From d663d553c55fbb5cdbe172d5c8780b777815de00 Mon Sep 17 00:00:00 2001 From: Matthew Kleiman Date: Tue, 18 Apr 2017 13:28:45 +0100 Subject: [PATCH] Allow column or row selection in the query tool. Fixes #2216 --- docs/en_US/images/query_output_data.png | Bin 62119 -> 52290 bytes ...opy_selected_query_results_feature_test.py | 76 ++++++ .../static/js/selection/column_selector.js | 92 +++++++ web/pgadmin/static/js/selection/copy_data.js | 52 ++++ .../static/js/selection/grid_selector.js | 79 ++++++ .../js/selection/range_boundary_navigator.js | 111 +++++++++ .../js/selection/range_selection_helper.js | 78 ++++++ .../static/js/selection/row_selector.js | 85 +++++++ .../datagrid/templates/datagrid/index.html | 2 +- .../tools/sqleditor/static/css/sqleditor.css | 15 +- .../templates/sqleditor/js/sqleditor.js | 61 +---- web/regression/README | 7 + .../feature_utils/base_feature_test.py | 1 + web/regression/feature_utils/pgadmin_page.py | 11 + .../selection/column_selector_spec.js | 235 ++++++++++++++++++ .../javascript/selection/copy_data_spec.js | 119 +++++++++ .../selection/grid_selector_spec.js | 126 ++++++++++ .../range_boundary_navigator_spec.js | 158 ++++++++++++ .../javascript/selection/row_selector_spec.js | 174 +++++++++++++ .../python_test_utils/test_utils.py | 3 + web/regression/requirements.txt | 1 + 21 files changed, 1427 insertions(+), 59 deletions(-) mode change 100755 => 100644 docs/en_US/images/query_output_data.png create mode 100644 web/pgadmin/feature_tests/copy_selected_query_results_feature_test.py create mode 100644 web/pgadmin/static/js/selection/column_selector.js create mode 100644 web/pgadmin/static/js/selection/copy_data.js create mode 100644 web/pgadmin/static/js/selection/grid_selector.js create mode 100644 web/pgadmin/static/js/selection/range_boundary_navigator.js create mode 100644 web/pgadmin/static/js/selection/range_selection_helper.js create mode 100644 web/pgadmin/static/js/selection/row_selector.js create mode 100644 web/regression/javascript/selection/column_selector_spec.js create mode 100644 web/regression/javascript/selection/copy_data_spec.js create mode 100644 web/regression/javascript/selection/grid_selector_spec.js create mode 100644 web/regression/javascript/selection/range_boundary_navigator_spec.js create mode 100644 web/regression/javascript/selection/row_selector_spec.js diff --git a/docs/en_US/images/query_output_data.png b/docs/en_US/images/query_output_data.png old mode 100755 new mode 100644 index e494523a1837a96940f6907674fa13d164c84874..a23815ec748d3e2ad415d4b0d531319bc9b644cb GIT binary patch literal 52290 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 VEgd~w!c*{1R#H)-NX+ob{{ec#z~le` literal 62119 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 R6h;YnPMviAk$T)O{om?@@nHY} diff --git a/web/pgadmin/feature_tests/copy_selected_query_results_feature_test.py b/web/pgadmin/feature_tests/copy_selected_query_results_feature_test.py new file mode 100644 index 000000000..223579eee --- /dev/null +++ b/web/pgadmin/feature_tests/copy_selected_query_results_feature_test.py @@ -0,0 +1,76 @@ +import pyperclip +import time + +from selenium.webdriver import ActionChains + +from regression.python_test_utils import test_utils +from regression.feature_utils.base_feature_test import BaseFeatureTest + + +class CopySelectedQueryResultsFeatureTest(BaseFeatureTest): + """ + Tests various ways to copy data from the query results grid. + """ + + + scenarios = [ + ("Test Copying Query Results", dict()) + ] + + def before(self): + connection = test_utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + test_utils.drop_database(connection, "acceptance_test_db") + test_utils.create_database(self.server, "acceptance_test_db") + test_utils.create_table(self.server, "acceptance_test_db", "test_table") + self.page.add_server(self.server) + + def runTest(self): + self.page.toggle_open_tree_item(self.server['name']) + self.page.toggle_open_tree_item('Databases') + self.page.toggle_open_tree_item('acceptance_test_db') + time.sleep(5) + self.page.find_by_partial_link_text("Tools").click() + self.page.find_by_partial_link_text("Query Tool").click() + self.page.click_tab('Query-1') + time.sleep(5) + ActionChains(self.page.driver).send_keys("SELECT * FROM test_table").perform() + self.page.driver.switch_to_frame(self.page.driver.find_element_by_tag_name("iframe")) + self.page.find_by_id("btn-flash").click() + + self._copies_rows() + self._copies_columns() + + def _copies_rows(self): + pyperclip.copy("old clipboard contents") + time.sleep(5) + self.page.find_by_xpath("//*[contains(@class, 'sr')]/*[1]/input[@type='checkbox']").click() + self.page.find_by_xpath("//*[@id='btn-copy-row']").click() + + self.assertEqual("'Some-Name','6'", + pyperclip.paste()) + + def _copies_columns(self): + pyperclip.copy("old clipboard contents") + + self.page.find_by_xpath("//*[@data-test='output-column-header' and contains(., 'some_column')]/input").click() + self.page.find_by_xpath("//*[@id='btn-copy-row']").click() + + self.assertEqual( + """'Some-Name' +'Some-Other-Name'""", + pyperclip.paste()) + + def after(self): + self.page.close_query_tool() + self.page.remove_server(self.server) + + connection = test_utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + test_utils.drop_database(connection, "acceptance_test_db") diff --git a/web/pgadmin/static/js/selection/column_selector.js b/web/pgadmin/static/js/selection/column_selector.js new file mode 100644 index 000000000..c89b3fa8d --- /dev/null +++ b/web/pgadmin/static/js/selection/column_selector.js @@ -0,0 +1,92 @@ +define(['jquery', 'sources/selection/range_selection_helper', 'slickgrid'], function ($, rangeSelectionHelper) { + var ColumnSelector = function () { + var init = function (grid) { + grid.onHeaderClick.subscribe(function (event, eventArgument) { + var column = eventArgument.column; + + if (column.selectable !== false) { + + if (!clickedCheckbox(event)) { + var $checkbox = $("[data-id='checkbox-" + column.id + "']"); + toggleCheckbox($checkbox); + } + + updateRanges(grid, column.id); + } + } + ); + grid.getSelectionModel().onSelectedRangesChanged + .subscribe(handleSelectedRangesChanged.bind(null, grid)); + }; + + var handleSelectedRangesChanged = function (grid, event, ranges) { + $('[data-cell-type="column-header-row"] input:checked') + .each(function (index, checkbox) { + var $checkbox = $(checkbox); + var columnIndex = grid.getColumnIndex($checkbox.data('column-id')); + var isStillSelected = rangeSelectionHelper.isRangeSelected(ranges, rangeSelectionHelper.rangeForColumn(grid, columnIndex)); + if (!isStillSelected) { + toggleCheckbox($checkbox); + } + }); + }; + + var updateRanges = function (grid, columnId) { + var selectionModel = grid.getSelectionModel(); + var ranges = selectionModel.getSelectedRanges(); + + var columnIndex = grid.getColumnIndex(columnId); + + var columnRange = rangeSelectionHelper.rangeForColumn(grid, columnIndex); + var newRanges; + if (rangeSelectionHelper.isRangeSelected(ranges, columnRange)) { + newRanges = rangeSelectionHelper.removeRange(ranges, columnRange); + } else { + if (rangeSelectionHelper.areAllRangesColumns(ranges, grid)) { + newRanges = rangeSelectionHelper.addRange(ranges, columnRange); + } else { + newRanges = [columnRange]; + } + } + selectionModel.setSelectedRanges(newRanges); + }; + + var clickedCheckbox = function (e) { + return e.target.type == "checkbox" + }; + + var toggleCheckbox = function (checkbox) { + if (checkbox.prop("checked")) { + checkbox.prop("checked", false) + } else { + checkbox.prop("checked", true) + } + }; + + var getColumnDefinitionsWithCheckboxes = function (columnDefinitions) { + return _.map(columnDefinitions, function (columnDefinition) { + if (columnDefinition.selectable !== false) { + var name = + "" + + " " + + " " + columnDefinition.name + "" + + ""; + return _.extend(columnDefinition, { + name: name + }); + } else { + return columnDefinition; + } + }); + }; + + $.extend(this, { + "init": init, + "getColumnDefinitionsWithCheckboxes": getColumnDefinitionsWithCheckboxes + }); + }; + return ColumnSelector; +}); diff --git a/web/pgadmin/static/js/selection/copy_data.js b/web/pgadmin/static/js/selection/copy_data.js new file mode 100644 index 000000000..018efeadb --- /dev/null +++ b/web/pgadmin/static/js/selection/copy_data.js @@ -0,0 +1,52 @@ +define([ + 'jquery', + 'underscore', + 'sources/selection/clipboard', + 'sources/selection/range_selection_helper', + 'sources/selection/range_boundary_navigator'], + function ($, _, clipboard, RangeSelectionHelper, rangeBoundaryNavigator) { + var copyData = function () { + var self = this; + + var grid = self.slickgrid; + var columnDefinitions = grid.getColumns(); + var selectedRanges = grid.getSelectionModel().getSelectedRanges(); + var data = grid.getData(); + var rows = grid.getSelectedRows(); + + + if (allTheRangesAreFullRows(selectedRanges, columnDefinitions)) { + self.copied_rows = rows.map(function (rowIndex) { + return data[rowIndex]; + }); + setPasteRowButtonEnablement(self.can_edit, true); + } else { + self.copied_rows = []; + setPasteRowButtonEnablement(self.can_edit, false); + } + + var csvText = rangeBoundaryNavigator.rangesToCsv(data, columnDefinitions, selectedRanges); + if (csvText) { + clipboard.copyTextToClipboard(csvText); + } + }; + + var setPasteRowButtonEnablement = function (canEditFlag, isEnabled) { + if (canEditFlag) { + $("#btn-paste-row").prop('disabled', !isEnabled); + } + }; + + var allTheRangesAreFullRows = function (ranges, columnDefinitions) { + var colRangeBounds = ranges.map(function (range) { + return [range.fromCell, range.toCell]; + }); + + if(RangeSelectionHelper.isFirstColumnData(columnDefinitions)) { + return _.isEqual(_.union.apply(null, colRangeBounds), [0, columnDefinitions.length - 1]); + } + return _.isEqual(_.union.apply(null, colRangeBounds), [1, columnDefinitions.length - 1]); + }; + + return copyData; +}); diff --git a/web/pgadmin/static/js/selection/grid_selector.js b/web/pgadmin/static/js/selection/grid_selector.js new file mode 100644 index 000000000..31aee69f1 --- /dev/null +++ b/web/pgadmin/static/js/selection/grid_selector.js @@ -0,0 +1,79 @@ +define(['jquery', 'sources/selection/column_selector', 'sources/selection/row_selector'], + function ($, ColumnSelector, RowSelector) { + var Slick = window.Slick; + + var GridSelector = function (columnDefinitions) { + var rowSelector = new RowSelector(columnDefinitions); + var columnSelector = new ColumnSelector(columnDefinitions); + + var init = function (grid) { + this.grid = grid; + grid.onHeaderClick.subscribe(function (event, eventArguments) { + if (eventArguments.column.selectAllOnClick) { + toggleSelectAll(grid); + } + }); + + grid.getSelectionModel().onSelectedRangesChanged + .subscribe(handleSelectedRangesChanged.bind(null, grid)); + grid.registerPlugin(rowSelector); + grid.registerPlugin(columnSelector); + }; + + var getColumnDefinitionsWithCheckboxes = function (columnDefinitions) { + columnDefinitions = columnSelector.getColumnDefinitionsWithCheckboxes(columnDefinitions); + columnDefinitions = rowSelector.getColumnDefinitionsWithCheckboxes(columnDefinitions); + + columnDefinitions[0].selectAllOnClick = true; + columnDefinitions[0].name = '' + columnDefinitions[0].name; + return columnDefinitions; + }; + + function handleSelectedRangesChanged(grid) { + $("[data-id='checkbox-select-all']").prop("checked", isEntireGridSelected(grid)); + } + + function isEntireGridSelected(grid) { + var selectionModel = grid.getSelectionModel(); + var selectedRanges = selectionModel.getSelectedRanges(); + return selectedRanges.length == 1 && isSameRange(selectedRanges[0], getRangeOfWholeGrid(grid)); + } + + function toggleSelectAll(grid) { + if (isEntireGridSelected(grid)) { + deselect(grid); + } else { + selectAll(grid) + } + } + + var isSameRange = function (range, otherRange) { + return range.fromCell == otherRange.fromCell && range.toCell == otherRange.toCell && + range.fromRow == otherRange.fromRow && range.toRow == otherRange.toRow; + }; + + function getRangeOfWholeGrid(grid) { + return new Slick.Range(0, 1, grid.getDataLength() - 1, grid.getColumns().length - 1); + } + + function deselect(grid) { + var selectionModel = grid.getSelectionModel(); + selectionModel.setSelectedRanges([]); + } + + function selectAll(grid) { + var range = getRangeOfWholeGrid(grid); + var selectionModel = grid.getSelectionModel(); + + selectionModel.setSelectedRanges([range]); + } + + $.extend(this, { + "init": init, + "getColumnDefinitionsWithCheckboxes": getColumnDefinitionsWithCheckboxes + }); + }; + + return GridSelector; + }); diff --git a/web/pgadmin/static/js/selection/range_boundary_navigator.js b/web/pgadmin/static/js/selection/range_boundary_navigator.js new file mode 100644 index 000000000..a268d245f --- /dev/null +++ b/web/pgadmin/static/js/selection/range_boundary_navigator.js @@ -0,0 +1,111 @@ +define(['sources/selection/range_selection_helper'], function (RangeSelectionHelper) { + return { + getUnion: function (allRanges) { + if (_.isEmpty(allRanges)) { + return []; + } + + allRanges.sort(firstElementNumberComparator); + var unionedRanges = [allRanges[0]]; + + allRanges.forEach(function (range) { + var maxBeginningOfRange = _.last(unionedRanges); + if (isStartInsideRange(range, maxBeginningOfRange)) { + if (!isEndInsideRange(range, maxBeginningOfRange)) { + maxBeginningOfRange[1] = range[1]; + } + } else { + unionedRanges.push(range); + } + }); + + return unionedRanges; + + function firstElementNumberComparator(a, b) { + return a[0] - b[0]; + } + + function isStartInsideRange(range, surroundingRange) { + return range[0] <= surroundingRange[1] + 1; + } + + function isEndInsideRange(range, surroundingRange) { + return range[1] <= surroundingRange[1]; + } + }, + + mapDimensionBoundaryUnion: function (unionedDimensionBoundaries, iteratee) { + var mapResult = []; + unionedDimensionBoundaries.forEach(function (subrange) { + for (var index = subrange[0]; index <= subrange[1]; index += 1) { + mapResult.push(iteratee(index)); + } + }); + return mapResult; + }, + + mapOver2DArray: function (rowRangeBounds, colRangeBounds, processCell, rowCollector) { + var unionedRowRanges = this.getUnion(rowRangeBounds); + var unionedColRanges = this.getUnion(colRangeBounds); + + return this.mapDimensionBoundaryUnion(unionedRowRanges, function (rowId) { + var rowData = this.mapDimensionBoundaryUnion(unionedColRanges, function (colId) { + return processCell(rowId, colId); + }); + return rowCollector(rowData); + }.bind(this)); + }, + + rangesToCsv: function (data, columnDefinitions, selectedRanges) { + var rowRangeBounds = selectedRanges.map(function (range) { + return [range.fromRow, range.toRow]; + }); + var colRangeBounds = selectedRanges.map(function (range) { + return [range.fromCell, range.toCell]; + }); + + if (!RangeSelectionHelper.isFirstColumnData(columnDefinitions)) { + colRangeBounds = this.removeFirstColumn(colRangeBounds); + } + + var csvRows = this.mapOver2DArray(rowRangeBounds, colRangeBounds, this.csvCell.bind(this, data, columnDefinitions), function (rowData) { + return rowData.join(','); + }); + return csvRows.join('\n'); + }, + + removeFirstColumn: function (colRangeBounds) { + var unionedColRanges = this.getUnion(colRangeBounds); + + var firstSubrangeStartsAt0 = function () { + return unionedColRanges[0][0] == 0; + }; + + function firstSubrangeIsJustFirstColumn() { + return unionedColRanges[0][1] == 0; + } + + if (firstSubrangeStartsAt0()) { + if (firstSubrangeIsJustFirstColumn()) { + unionedColRanges.shift(); + } else { + unionedColRanges[0][0] = 1; + } + } + return unionedColRanges; + }, + + csvCell: function (data, columnDefinitions, rowId, colId) { + var val = data[rowId][columnDefinitions[colId].pos]; + + if (val && _.isObject(val)) { + val = "'" + JSON.stringify(val) + "'"; + } else if (val && typeof val != "number" && typeof val != "boolean") { + val = "'" + val.toString() + "'"; + } else if (_.isNull(val) || _.isUndefined(val)) { + val = ''; + } + return val; + } + }; +}); \ No newline at end of file diff --git a/web/pgadmin/static/js/selection/range_selection_helper.js b/web/pgadmin/static/js/selection/range_selection_helper.js new file mode 100644 index 000000000..31ad3bf79 --- /dev/null +++ b/web/pgadmin/static/js/selection/range_selection_helper.js @@ -0,0 +1,78 @@ +define(['slickgrid'], function () { + var Slick = window.Slick; + + var isSameRange = function (range, otherRange) { + return range.fromCell == otherRange.fromCell && range.toCell == otherRange.toCell && + range.fromRow == otherRange.fromRow && range.toRow == otherRange.toRow; + }; + + var isRangeSelected = function (selectedRanges, range) { + return _.any(selectedRanges, function (selectedRange) { + return isSameRange(selectedRange, range) + }) + }; + + var removeRange = function (selectedRanges, range) { + return _.filter(selectedRanges, function (selectedRange) { + return !(isSameRange(selectedRange, range)) + }) + }; + + var addRange = function (ranges, range) { + ranges.push(range); + return ranges; + }; + + var areAllRangesRows = function (ranges, grid) { + return _.every(ranges, function (range) { + return range.fromRow == range.toRow && + range.fromCell == 1 && range.toCell == grid.getColumns().length - 1 + }) + }; + + var areAllRangesColumns = function (ranges, grid) { + return _.every(ranges, function (range) { + return range.fromCell == range.toCell && + range.fromRow == 0 && range.toRow == grid.getDataLength() - 1 + }) + }; + + var rangeForRow = function (grid, rowId) { + var columnDefinitions = grid.getColumns(); + if(isFirstColumnData(columnDefinitions)) { + return new Slick.Range(rowId, 0, rowId, grid.getColumns().length - 1); + } + return new Slick.Range(rowId, 1, rowId, grid.getColumns().length - 1); + }; + + function rangeForColumn(grid, columnIndex) { + return new Slick.Range(0, columnIndex, grid.getDataLength() - 1, columnIndex) + }; + + var getRangeOfWholeGrid = function (grid) { + return new Slick.Range(0, 1, grid.getDataLength() - 1, grid.getColumns().length - 1); + }; + + var isEntireGridSelected = function (grid) { + var selectionModel = grid.getSelectionModel(); + var selectedRanges = selectionModel.getSelectedRanges(); + return selectedRanges.length == 1 && isSameRange(selectedRanges[0], getRangeOfWholeGrid(grid)); + }; + + var isFirstColumnData = function (columnDefinitions) { + return !_.isUndefined(columnDefinitions[0].pos); + }; + + return { + addRange: addRange, + removeRange: removeRange, + isRangeSelected: isRangeSelected, + areAllRangesRows: areAllRangesRows, + areAllRangesColumns: areAllRangesColumns, + rangeForRow: rangeForRow, + rangeForColumn: rangeForColumn, + isEntireGridSelected: isEntireGridSelected, + getRangeOfWholeGrid: getRangeOfWholeGrid, + isFirstColumnData: isFirstColumnData + } +}); \ No newline at end of file diff --git a/web/pgadmin/static/js/selection/row_selector.js b/web/pgadmin/static/js/selection/row_selector.js new file mode 100644 index 000000000..76a8c1a7e --- /dev/null +++ b/web/pgadmin/static/js/selection/row_selector.js @@ -0,0 +1,85 @@ +define(['jquery', 'sources/selection/range_selection_helper', 'slickgrid'], function ($, rangeSelectionHelper) { + var RowSelector = function () { + var Slick = window.Slick; + + var gridEventBus = new Slick.EventHandler(); + + var init = function (grid) { + grid.getSelectionModel() + .onSelectedRangesChanged.subscribe(handleSelectedRangesChanged.bind(null, grid)); + gridEventBus + .subscribe(grid.onClick, handleClick.bind(null, grid)) + }; + + var handleClick = function (grid, event, args) { + if (grid.getColumns()[args.cell].id === 'row-header-column') { + if (event.target.type != "checkbox") { + var checkbox = $(event.target).find('input[type="checkbox"]'); + toggleCheckbox($(checkbox)); + } + updateRanges(grid, args.row); + } + } + + var handleSelectedRangesChanged = function (grid, event, ranges) { + $('[data-cell-type="row-header-checkbox"]:checked') + .each(function (index, checkbox) { + var $checkbox = $(checkbox); + var row = parseInt($checkbox.data('row')); + var isStillSelected = rangeSelectionHelper.isRangeSelected(ranges, + rangeSelectionHelper.rangeForRow(grid, row)); + if (!isStillSelected) { + toggleCheckbox($checkbox); + } + }); + } + + var updateRanges = function (grid, rowId) { + var selectionModel = grid.getSelectionModel(); + var ranges = selectionModel.getSelectedRanges(); + + var rowRange = rangeSelectionHelper.rangeForRow(grid, rowId); + + var newRanges; + if (rangeSelectionHelper.isRangeSelected(ranges, rowRange)) { + newRanges = rangeSelectionHelper.removeRange(ranges, rowRange); + } else { + if (rangeSelectionHelper.areAllRangesRows(ranges, grid)) { + newRanges = rangeSelectionHelper.addRange(ranges, rowRange); + } else { + newRanges = [rowRange]; + } + } + selectionModel.setSelectedRanges(newRanges); + } + + var toggleCheckbox = function (checkbox) { + if (checkbox.prop("checked")) { + checkbox.prop("checked", false) + } else { + checkbox.prop("checked", true) + } + }; + + var getColumnDefinitionsWithCheckboxes = function (columnDefinitions) { + columnDefinitions.unshift({ + id: 'row-header-column', + name: '', + selectable: false, + focusable: false, + formatter: function (rowIndex) { + return '' + } + }); + return columnDefinitions; + }; + + $.extend(this, { + "init": init, + "getColumnDefinitionsWithCheckboxes": getColumnDefinitionsWithCheckboxes + }); + }; + return RowSelector; +}); diff --git a/web/pgadmin/tools/datagrid/templates/datagrid/index.html b/web/pgadmin/tools/datagrid/templates/datagrid/index.html index 1d71b21e4..727eb777f 100644 --- a/web/pgadmin/tools/datagrid/templates/datagrid/index.html +++ b/web/pgadmin/tools/datagrid/templates/datagrid/index.html @@ -96,7 +96,7 @@

- "); + grid = new Slick.Grid("#grid", data, columns, {}); + grid.setSelectionModel(new Slick.RowSelectionModel({selectActiveRow: false})); + sqlEditor = {slickgrid: grid}; + }); + + afterEach(function() { + $("body").remove('#grid'); + $("body").remove('#btn-paste-row'); + }); + + describe("when rows are selected", function () { + beforeEach(function () { + grid.getSelectionModel().setSelectedRanges([ + RangeSelectionHelper.rangeForRow(grid, 0), + RangeSelectionHelper.rangeForRow(grid, 2)] + ); + }); + + it("copies them", function () { + spyOn(clipboard, 'copyTextToClipboard'); + + copyData.apply(sqlEditor); + + expect(sqlEditor.copied_rows.length).toBe(2); + + expect(clipboard.copyTextToClipboard).toHaveBeenCalled(); + expect(clipboard.copyTextToClipboard.calls.mostRecent().args[0]).toContain("1,'leopord','12'"); + expect(clipboard.copyTextToClipboard.calls.mostRecent().args[0]).toContain("3,'puma','9'"); + }); + + describe("when the user can edit the grid", function () { + it("enables the paste row button", function () { + copyData.apply(_.extend({can_edit: true}, sqlEditor)); + + expect($("#btn-paste-row").prop('disabled')).toBe(false); + }); + }); + }); + + describe("when a column is selected", function () { + beforeEach(function () { + var firstColumn = new Slick.Range(0, 0, 2, 0); + grid.getSelectionModel().setSelectedRanges([firstColumn]) + }); + + it("copies text to the clipboard", function () { + spyOn(clipboard, 'copyTextToClipboard'); + + copyData.apply(sqlEditor); + + expect(clipboard.copyTextToClipboard).toHaveBeenCalled(); + + var copyArg = clipboard.copyTextToClipboard.calls.mostRecent().args[0]; + var rowStrings = copyArg.split('\n'); + expect(rowStrings[0]).toBe("1"); + expect(rowStrings[1]).toBe("2"); + expect(rowStrings[2]).toBe("3"); + }); + + it("sets copied_rows to empty", function () { + copyData.apply(sqlEditor); + + expect(sqlEditor.copied_rows.length).toBe(0); + }); + + describe("when the user can edit the grid", function () { + it("disables the paste row button", function () { + copyData.apply(_.extend({can_edit: true}, sqlEditor)); + + expect($("#btn-paste-row").prop('disabled')).toBe(true); + }); + }); + }); + }); + }); diff --git a/web/regression/javascript/selection/grid_selector_spec.js b/web/regression/javascript/selection/grid_selector_spec.js new file mode 100644 index 000000000..a74a66f93 --- /dev/null +++ b/web/regression/javascript/selection/grid_selector_spec.js @@ -0,0 +1,126 @@ +define(["jquery", + "underscore", + "slickgrid/slick.grid", + "slickgrid/slick.rowselectionmodel", + "sources/selection/grid_selector" + ], + function ($, _, SlickGrid, RowSelectionModel, GridSelector) { + describe("GridSelector", function () { + var container, data, columns, gridSelector, rowSelectionModel; + + beforeEach(function () { + container = $("
"); + container.height(9999); + columns = [{ + id: '1', + name: 'some-column-name', + }, { + id: '2', + name: 'second column', + }]; + + gridSelector = new GridSelector(); + columns = gridSelector.getColumnDefinitionsWithCheckboxes(columns); + + data = []; + for (var i = 0; i < 10; i++) { + data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i}); + } + var grid = new SlickGrid(container, data, columns); + + rowSelectionModel = new RowSelectionModel(); + grid.setSelectionModel(rowSelectionModel); + + grid.registerPlugin(gridSelector); + grid.invalidate(); + + $("body").append(container); + }); + + afterEach(function () { + $("body").find(container).remove(); + }); + + it("renders an additional column on the left for selecting rows", function () { + expect(columns.length).toBe(3); + + var leftmostColumn = columns[0]; + expect(leftmostColumn.id).toBe('row-header-column'); + }); + + it("renders checkboxes for selecting columns", function () { + expect(container.find('[data-test="output-column-header"] input').length).toBe(2) + }); + + it("renders a checkbox for selecting all the cells", function () { + expect(container.find("[title='Select/Deselect All']").length).toBe(1); + }); + + describe("when the cell for the select/deselect all is clicked", function () { + it("selects the whole grid", function () { + container.find("[title='Select/Deselect All']").parent().click(); + + var selectedRanges = rowSelectionModel.getSelectedRanges(); + expect(selectedRanges.length).toBe(1); + var selectedRange = selectedRanges[0]; + expect(selectedRange.fromCell).toBe(1); + expect(selectedRange.toCell).toBe(2); + expect(selectedRange.fromRow).toBe(0); + expect(selectedRange.toRow).toBe(9); + }); + + it("checks the checkbox", function () { + container.find("[title='Select/Deselect All']").parent().click(); + + expect($(container.find("[data-id='checkbox-select-all']")).is(':checked')).toBeTruthy(); + }) + }); + + describe("when the main checkbox in the corner gets selected", function () { + it("unchecks all the columns", function () { + container.find("[title='Select/Deselect All']").click(); + + expect($(container.find('.slick-header-columns input')[1]).is(':checked')).toBeFalsy(); + expect($(container.find('.slick-header-columns input')[2]).is(':checked')).toBeFalsy(); + }); + + it("selects all the cells", function () { + container.find("[title='Select/Deselect All']").click(); + + var selectedRanges = rowSelectionModel.getSelectedRanges(); + expect(selectedRanges.length).toBe(1); + var selectedRange = selectedRanges[0]; + expect(selectedRange.fromCell).toBe(1); + expect(selectedRange.toCell).toBe(2); + expect(selectedRange.fromRow).toBe(0); + expect(selectedRange.toRow).toBe(9); + }); + + describe("when the main checkbox in the corner gets deselected", function () { + beforeEach(function () { + container.find("[title='Select/Deselect All']").click(); + }); + + it("deselects all the cells", function () { + container.find("[title='Select/Deselect All']").click(); + + var selectedRanges = rowSelectionModel.getSelectedRanges(); + expect(selectedRanges.length).toBe(0); + }); + }); + + describe("and then the underlying selection changes", function () { + beforeEach(function () { + container.find("[title='Select/Deselect All']").click(); + }); + + it("unchecks the main checkbox", function () { + var ranges = [new Slick.Range(0, 0, 0, 1)]; + rowSelectionModel.setSelectedRanges(ranges); + + expect($(container.find("[title='Select/Deselect All']")).is(':checked')).toBeFalsy(); + }); + }); + }); + }); + }); diff --git a/web/regression/javascript/selection/range_boundary_navigator_spec.js b/web/regression/javascript/selection/range_boundary_navigator_spec.js new file mode 100644 index 000000000..8376d0a78 --- /dev/null +++ b/web/regression/javascript/selection/range_boundary_navigator_spec.js @@ -0,0 +1,158 @@ +define(['sources/selection/range_boundary_navigator'], function (rangeBoundaryNavigator) { + + describe("#getUnion", function () { + describe("when the ranges completely overlap", function () { + it("returns a list with that range", function () { + var ranges = [[1, 4], [1, 4], [1, 4]]; + + var union = rangeBoundaryNavigator.getUnion(ranges); + + expect(union).toEqual([[1, 4]]); + }); + }); + + describe("when the ranges all overlap partially or touch", function () { + it("returns one long range", function () { + var rangeBounds = [[3, 6], [1, 4], [7, 14]]; + + var union = rangeBoundaryNavigator.getUnion(rangeBounds); + + expect(union).toEqual([[1, 14]]); + }); + + it("returns them in order from lowest to highest", function () { + var rangeBounds = [[3, 6], [2, 3], [10, 12]]; + + var union = rangeBoundaryNavigator.getUnion(rangeBounds); + + expect(union).toEqual([[2, 6], [10, 12]]); + }); + + describe("when one range completely overlaps another", function() { + + it("returns them in order from lowest to highest", function () { + var rangeBounds = [[9, 14], [2, 3], [11, 13]]; + + var union = rangeBoundaryNavigator.getUnion(rangeBounds); + + expect(union).toEqual([[2, 3], [9, 14]]); + }); + }); + + describe("when one range is a subset of another", function () { + it("returns the larger range", function () { + var rangeBounds = [[2, 6], [1, 14], [8, 10]]; + + var union = rangeBoundaryNavigator.getUnion(rangeBounds); + + expect(union).toEqual([[1, 14]]); + }) + }) + }); + + describe("when the ranges do not touch", function () { + it("returns them in order from lowest to highest", function () { + var rangeBounds = [[3, 6], [1, 1], [8, 10]]; + + var union = rangeBoundaryNavigator.getUnion(rangeBounds); + + expect(union).toEqual([[1, 1], [3, 6], [8, 10]]); + }); + }); + }); + + + describe("#mapDimensionBoundaryUnion", function () { + it("returns a list of the results of the callback", function () { + var rangeBounds = [[0, 1], [3, 3]]; + var callback = function () { + return 'hello'; + }; + var result = rangeBoundaryNavigator.mapDimensionBoundaryUnion(rangeBounds, callback); + expect(result).toEqual(['hello', 'hello', 'hello']); + }); + + it("calls the callback with each index in the dimension", function () { + var rangeBounds = [[0, 1], [3, 3]]; + var callback = jasmine.createSpy('callbackSpy'); + rangeBoundaryNavigator.mapDimensionBoundaryUnion(rangeBounds, callback); + expect(callback.calls.allArgs()).toEqual([[0], [1], [3]]); + }); + }); + + describe("#mapOver2DArray", function () { + var data, rowCollector, processCell; + beforeEach(function () { + data = [[0, 1, 2, 3], [2, 2, 2, 2], [4, 5, 6, 7]]; + processCell = function (rowIndex, columnIndex) { + return data[rowIndex][columnIndex]; + }; + rowCollector = function (rowData) { + return JSON.stringify(rowData); + }; + }); + + it("calls the callback for each item in the ranges", function () { + var rowRanges = [[0, 0], [2, 2]]; + var colRanges = [[0, 3]]; + + var selectionResult = rangeBoundaryNavigator.mapOver2DArray(rowRanges, colRanges, processCell, rowCollector); + + expect(selectionResult).toEqual(["[0,1,2,3]", "[4,5,6,7]"]); + }); + + describe("when the ranges are out of order/duplicated", function () { + var rowRanges, colRanges; + beforeEach(function () { + rowRanges = [[2, 2], [2, 2], [0, 0]]; + colRanges = [[0, 3]]; + }); + + it("uses the union of the ranges", function () { + spyOn(rangeBoundaryNavigator, "getUnion").and.callThrough(); + + var selectionResult = rangeBoundaryNavigator.mapOver2DArray(rowRanges, colRanges, processCell, rowCollector); + + expect(rangeBoundaryNavigator.getUnion).toHaveBeenCalledWith(rowRanges); + expect(rangeBoundaryNavigator.getUnion).toHaveBeenCalledWith(colRanges); + expect(selectionResult).toEqual(["[0,1,2,3]", "[4,5,6,7]"]); + }); + }); + }); + + describe("#rangesToCsv", function () { + var data, columnDefinitions, ranges; + beforeEach(function () { + data = [[1, "leopard", "12"], + [2, "lion", "13"], + [3, "cougar", "9"], + [4, "tiger", "10"]]; + columnDefinitions = [{name: 'id', pos: 0}, {name: 'animal', pos: 1}, {name: 'size', pos: 2}]; + ranges = [new Slick.Range(0, 0, 0, 2), new Slick.Range(3, 0, 3, 2)]; + }); + + it("returns csv for the provided ranges", function () { + + var csvResult = rangeBoundaryNavigator.rangesToCsv(data, columnDefinitions, ranges); + + expect(csvResult).toEqual("1,'leopard','12'\n4,'tiger','10'"); + }); + + describe("when there is an extra column with checkboxes", function () { + beforeEach(function () { + columnDefinitions = [{name: 'not-a-data-column'}, {name: 'id', pos: 0}, {name: 'animal', pos: 1}, { + name: 'size', + pos: 2 + }]; + ranges = [new Slick.Range(0, 0, 0, 3), new Slick.Range(3, 0, 3, 3)]; + + }); + + it("returns csv for the columns with data", function () { + var csvResult = rangeBoundaryNavigator.rangesToCsv(data, columnDefinitions, ranges); + + expect(csvResult).toEqual("1,'leopard','12'\n4,'tiger','10'"); + }); + }); + }); +}); \ No newline at end of file diff --git a/web/regression/javascript/selection/row_selector_spec.js b/web/regression/javascript/selection/row_selector_spec.js new file mode 100644 index 000000000..10697e6a1 --- /dev/null +++ b/web/regression/javascript/selection/row_selector_spec.js @@ -0,0 +1,174 @@ +define( + ["jquery", + "underscore", + "slickgrid/slick.grid", + "sources/selection/row_selector", + "slickgrid/slick.rowselectionmodel", + "slickgrid", + ], + function ($, _, SlickGrid, RowSelector, RowSelectionModel, Slick) { + describe("RowSelector", function () { + var container, data, columnDefinitions, grid, rowSelectionModel; + + beforeEach(function () { + container = $("
"); + container.height(9999); + + columnDefinitions = [{ + id: '1', + name: 'some-column-name', + selectable: true + }, { + id: '2', + name: 'second column', + selectable: true + }]; + + var rowSelector = new RowSelector(); + data = []; + for (var i = 0; i < 10; i++) { + data.push(['some-value-' + i, 'second value ' + i]); + } + columnDefinitions = rowSelector.getColumnDefinitionsWithCheckboxes(columnDefinitions); + grid = new SlickGrid(container, data, columnDefinitions); + + rowSelectionModel = new RowSelectionModel(); + grid.setSelectionModel(rowSelectionModel); + grid.registerPlugin(rowSelector); + grid.invalidate(); + + $("body").append(container); + }); + + afterEach(function () { + $("body").find(container).remove(); + }); + + it("renders an additional column on the left", function () { + expect(columnDefinitions.length).toBe(3); + + var leftmostColumn = columnDefinitions[0]; + expect(leftmostColumn.id).toBe('row-header-column'); + expect(leftmostColumn.name).toBe(''); + expect(leftmostColumn.selectable).toBe(false); + }); + + it("renders a checkbox the leftmost column", function () { + expect(container.find('.sr').length).toBe(11); + expect(container.find('.sr .sc:first-child input[type="checkbox"]').length).toBe(10); + }); + + it("preserves the other attributes of column definitions", function () { + expect(columnDefinitions[1].id).toBe('1'); + expect(columnDefinitions[1].selectable).toBe(true); + }); + + describe("selecting rows", function () { + describe("when the user clicks a row header checkbox", function () { + it("selects the row", function () { + container.find('.sr .sc:first-child input[type="checkbox"]')[0].click(); + + var selectedRanges = rowSelectionModel.getSelectedRanges(); + expectOnlyTheFirstRowToBeSelected(selectedRanges); + }); + + it("checks the checkbox", function () { + container.find('.sr .sc:first-child input[type="checkbox"]')[5].click(); + + expect($(container.find('.sr .sc:first-child input[type="checkbox"]')[5]) + .is(':checked')).toBeTruthy(); + }); + }); + + describe("when the user clicks a row header", function () { + it("selects the row", function () { + container.find('.sr .sc:first-child')[0].click(); + + var selectedRanges = rowSelectionModel.getSelectedRanges(); + expectOnlyTheFirstRowToBeSelected(selectedRanges); + }); + + it("checks the checkbox", function () { + container.find('.sr .sc:first-child')[7].click(); + + expect($(container.find('.sr .sc:first-child input[type="checkbox"]')[7]) + .is(':checked')).toBeTruthy(); + }); + }); + + describe("when the user clicks multiple row headers", function () { + it("selects another row", function () { + container.find('.sr .sc:first-child')[4].click(); + container.find('.sr .sc:first-child')[0].click(); + + var selectedRanges = rowSelectionModel.getSelectedRanges(); + expect(selectedRanges.length).toEqual(2); + + var row1 = selectedRanges[0]; + expect(row1.fromRow).toBe(4); + expect(row1.toRow).toBe(4); + + var row2 = selectedRanges[1]; + expect(row2.fromRow).toBe(0); + expect(row2.toRow).toBe(0); + }); + }); + + describe("when a column was already selected", function () { + beforeEach(function () { + var selectedRanges = [new Slick.Range(0, 0, 0, 1)]; + rowSelectionModel.setSelectedRanges(selectedRanges); + }); + + it("deselects the column", function () { + container.find('.sr .sc:first-child')[0].click(); + var selectedRanges = rowSelectionModel.getSelectedRanges(); + + expectOnlyTheFirstRowToBeSelected(selectedRanges); + }) + }); + + describe("when the row is deselected through setSelectedRanges", function () { + beforeEach(function () { + container.find('.sr .sc:first-child')[4].click(); + }); + + it("should uncheck the checkbox", function () { + rowSelectionModel.setSelectedRanges([]); + + expect($(container.find('.sr .sc:first-child input[type="checkbox"]')[4]) + .is(':checked')).toBeFalsy(); + }); + }); + + describe("click a second time", function () { + beforeEach(function () { + container.find('.sr .sc:first-child')[1].click(); + }); + + it("unchecks checkbox", function () { + container.find('.sr .sc:first-child')[1].click(); + expect($(container.find('.sr .sc:first-child input[type="checkbox"]')[1]) + .is(':checked')).toBeFalsy(); + }); + + it("unselects the row", function () { + container.find('.sr .sc:first-child')[1].click(); + var selectedRanges = rowSelectionModel.getSelectedRanges(); + + expect(selectedRanges.length).toEqual(0); + }) + }); + }); + }); + + function expectOnlyTheFirstRowToBeSelected(selectedRanges) { + var row = selectedRanges[0]; + + expect(selectedRanges.length).toEqual(1); + expect(row.fromCell).toBe(1); + expect(row.toCell).toBe(2); + expect(row.fromRow).toBe(0); + expect(row.toRow).toBe(0); + } + }); \ No newline at end of file diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py index f3a6ce8ce..2b7c6954e 100644 --- a/web/regression/python_test_utils/test_utils.py +++ b/web/regression/python_test_utils/test_utils.py @@ -163,6 +163,9 @@ def create_table(server, db_name, table_name): table_name) pg_cursor.execute( '''INSERT INTO "%s" VALUES ('Some-Name', 6)''' % table_name) + pg_cursor.execute( + '''INSERT INTO "%s" VALUES ('Some-Other-Name', 22)''' % table_name) + connection.set_isolation_level(old_isolation_level) connection.commit() diff --git a/web/regression/requirements.txt b/web/regression/requirements.txt index f644c12a6..693ea1771 100644 --- a/web/regression/requirements.txt +++ b/web/regression/requirements.txt @@ -1,4 +1,5 @@ chromedriver_installer==0.0.6 +pyperclip~=1.5.27 selenium==3.3.1 testscenarios==0.5.0 testtools==2.0.0