diff options
author | Manolo Carrasco <manolo@apache.org> | 2015-01-21 23:28:24 -0800 |
---|---|---|
committer | Sauli Tähkäpää <sauli@vaadin.com> | 2015-05-21 14:42:07 +0300 |
commit | 5759ee06e8fbdc2caeb912d614ec5a42834d009d (patch) | |
tree | caeef1516f932f5d96909054cf4b13e82d1c5a22 /vaadin-grid/test | |
download | vaadin-core-5759ee06e8fbdc2caeb912d614ec5a42834d009d.tar.gz vaadin-core-5759ee06e8fbdc2caeb912d614ec5a42834d009d.zip |
Release version 0.2-snapshot.
Diffstat (limited to 'vaadin-grid/test')
-rw-r--r-- | vaadin-grid/test/common.js | 86 | ||||
-rw-r--r-- | vaadin-grid/test/grid-binding-data.html | 185 | ||||
-rw-r--r-- | vaadin-grid/test/grid-editing-columns.html | 412 | ||||
-rw-r--r-- | vaadin-grid/test/grid-editor-handler.html | 202 | ||||
-rw-r--r-- | vaadin-grid/test/grid-properties.html | 86 | ||||
-rw-r--r-- | vaadin-grid/test/grid-redrawer.html | 201 | ||||
-rw-r--r-- | vaadin-grid/test/grid-rendering-light-dom.html | 130 | ||||
-rw-r--r-- | vaadin-grid/test/grid-scrolling-rows.html | 114 | ||||
-rw-r--r-- | vaadin-grid/test/grid-selecting-rows.html | 645 | ||||
-rw-r--r-- | vaadin-grid/test/grid-sorting-rows.html | 100 | ||||
-rw-r--r-- | vaadin-grid/test/grid-static-sections.html | 222 | ||||
-rw-r--r-- | vaadin-grid/test/index.html | 24 |
12 files changed, 2407 insertions, 0 deletions
diff --git a/vaadin-grid/test/common.js b/vaadin-grid/test/common.js new file mode 100644 index 0000000..4815d96 --- /dev/null +++ b/vaadin-grid/test/common.js @@ -0,0 +1,86 @@ +var grid, wrapper; + +describe.feature = function(description, suite) { + describe(description, function() { + before(function(done) { + initializeGrid(); + + waitUntil(function() { + return grid.then; + }, done, done); + }); + + after(function() { + return grid; //make sure everything is finished before moving on. + }); + + suite(); + }); +}; + +function gridContainsText(_grid, text) { + return Polymer.dom(_grid.root).querySelector(".v-grid-tablewrapper").parentElement.innerHTML.indexOf(text) > -1; +} + +function waitUntil(check, exec, onTimeout) { + var id = setInterval(function() { + if (check()) { + clearInterval(id); + clearTimeout(timeoutId); + exec(); + } + }, 100); + + var timeoutId = setTimeout(function() { + clearInterval(id); + assert.fail(); + onTimeout(); + }, 5000); +} + + +function initializeGrid() { + wrapper = document.getElementById("gridwrapper"); + wrapper.innerHTML = "<v-grid>" + + " <table>" + + " <col header-text='Name'>" + + " <col header-text='Value'>" + + " <tbody>" + + " <tr>" + + " <td>Grid</td>" + + " <td>10000</td>" + + " </tr>" + + " <tr>" + + " <td>VaadinX</td>" + + " <td>1000</td>" + + " </tr>" + + " </tbody>" + + " <tfoot>" + + " <tr>" + + " <td>Name</td>" + + " <td>Value</td>" + + " </tr>" + + " </tfoot>"+ + " </table>" + + " </v-grid>"; + grid = wrapper.querySelector("v-grid"); + + return grid; +}; + +var local = function() { + return Polymer.dom(grid.root); +}; +var light = function() { + return Polymer.dom(grid); +}; + +var qLocal = function(selector) { + return local().querySelector(selector); +}; +var qaLocal = function(selector) { + return local().querySelectorAll(selector); +}; +var qLight = function(selector) { + return light().querySelector(selector); +}; diff --git a/vaadin-grid/test/grid-binding-data.html b/vaadin-grid/test/grid-binding-data.html new file mode 100644 index 0000000..2d82b26 --- /dev/null +++ b/vaadin-grid/test/grid-binding-data.html @@ -0,0 +1,185 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + +<div id="gridwrapper"></div> + +<script> + describe.feature('binding data', function() { + + afterEach(function() { + return grid.then(function() { + + grid.selection.mode = 'single'; + grid.columns = [{name: 'Name', headerHtml: 'Name'}, {name: 'Value', headerHtml: 'Value'}]; + grid.data.source = [['Grid', '10000'], ['VaadinX', '1000']]; + + return grid; + }); + }); + + it('data: object type', function(done) { + grid.columns[0].name = "firstname"; + grid.columns[1].name = "lastname"; + grid.columns.push({ + name: 'salary', + headerHtml: "Salary" + }); + + var mydata = [{ + firstname: "John", + lastname: "Doe", + salary: 1234.56 + }, { + firstname: "Jane", + lastname: "Doe", + salary: 2345.67 + }, ]; + + grid.data.source = function(request) { + request.success(mydata.slice(request.index, request.index + + request.count), mydata.length); + }; + + + waitUntil(function() { + return gridContainsText(grid, "2345.67"); + }, function() { + var cells = qaLocal(".v-grid-body .v-grid-cell"); + assert.equal(cells[0].innerHTML, "John"); + assert.equal(cells[2].innerHTML, "1234.56"); + assert.equal(cells[3].innerHTML, "Jane"); + assert.equal(cells[4].innerHTML, "Doe"); + done(); + }, done); + + }); + + it('data: array type', function(done) { + grid.columns.push({ + headerHtml: "Salary" + }); + + mydata = [ + ["John", "Doe", 1234.56], + ["Jane", "Doe", 2345.67], + ]; + + grid.data.source = mydata; + + waitUntil(function() { + return gridContainsText(grid, "2345.67"); + }, function() { + var cells = qaLocal(".v-grid-body .v-grid-cell"); + assert.equal(cells[0].innerHTML, "John"); + assert.equal(cells[2].innerHTML, "1234.56"); + assert.equal(cells[3].innerHTML, "Jane"); + assert.equal(cells[4].innerHTML, "Doe"); + done(); + }, done); + + }); + + it('data: boolean type', function(done) { + grid.columns.splice(0, 1); + grid.selection.mode = "multi"; + + waitUntil(function() { + return qLocal("input[type='checkbox']"); + }, function() { + var mydata = [ + false, + true, + ]; + + grid.data.source = function(request) { + request.success(mydata.slice(request.index, request.index + + request.count), mydata.length); + }; + + waitUntil(function() { + return gridContainsText(grid, "false"); + }, function() { + var cells = qaLocal(".v-grid-body .v-grid-cell"); + assert.equal(cells[3].innerHTML, "true"); + done(); + }, done); + }, done); + + }); + + it('data: string type', function(done) { + grid.columns.splice(0, 1); + grid.selection.mode = "multi"; + + waitUntil(function() { + return qLocal("input[type='checkbox']"); + }, function() { + var mydata = [ + "Lorem", + "Ipsum", + ]; + + grid.data.source = function(request) { + request.success(mydata.slice(request.index, request.index + + request.count), mydata.length); + }; + + waitUntil(function() { + return gridContainsText(grid, "Lorem"); + }, function() { + var cells = qaLocal(".v-grid-body .v-grid-cell"); + assert.equal(cells[3].innerHTML, "Ipsum"); + done(); + }, done); + }, done); + + }); + + it('data: non-object types', function(done) { + var first = grid.columns[0]; + grid.columns.splice(0, 1); + grid.columns.push(first); + grid.columns.splice(1, 1); + grid._grid.setRows(5); + + + var mydata = [ + 1, 2, null, undefined, 1, "cellsready" + ]; + + grid.data.source = function(request) { + request.success(mydata.slice(request.index, request.index + + request.count), mydata.length); + }; + + waitUntil(function() { + return gridContainsText(grid, "cellsready"); + }, function() { + var cells = qaLocal(".v-grid-body .v-grid-cell"); + assert.equal(cells[0].innerHTML, "1"); + assert.equal(cells[1].innerHTML, "2"); + assert.equal(cells[2].innerHTML, ""); + assert.equal(cells[3].innerHTML, ""); + assert.equal(cells[4].innerHTML, "1"); + done(); + }, done); + + }); + }); +</script> + +</body> +</html> diff --git a/vaadin-grid/test/grid-editing-columns.html b/vaadin-grid/test/grid-editing-columns.html new file mode 100644 index 0000000..105aa3e --- /dev/null +++ b/vaadin-grid/test/grid-editing-columns.html @@ -0,0 +1,412 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + +<div id="gridwrapper"></div> + +<script> + describe.feature('editing columns', function() { + + function getFirstCell() { + return qLocal('.v-grid-body .v-grid-cell'); + } + + beforeEach(function() { + return grid.then(function() { + + grid.selection.mode = 'single'; + grid.frozenColumns = 0; + grid.columns = [{name: 'Name', headerContent: 'Name'}, {name: 'Value', headerContent: 'Value'}]; + grid.data.source = [['Grid', '10000'], ['VaadinX', '1000']]; + + return grid; + }); + }); + + it('add new column', function() { + grid.addColumn({ + name: "foo", + headerContent: "<b>Foo</b>", + sortable: true, + minWidth: 100, + maxWidth: 200, + width: 150, + flex: 1, + }); + + var c = grid.columns[grid.columns.length - 1]; + assert.equal(c.name, "foo"); + assert.equal(c.headerContent, "<b>Foo</b>"); + assert.equal(c.sortable, true); + assert.notOk(c.editable); + assert.equal(c.minWidth, 100); + assert.equal(c.maxWidth, 200); + assert.equal(c.width, 150); + assert.equal(c.flex, 1); + }); + + it('add new column before', function(done) { + + expect(grid.addColumn.bind(grid, { + name: "foo" + }, -1)).to.throw("Column not found."); + + expect(grid.addColumn.bind(grid, { + name: "foo" + }, 100)).to.throw("Column not found."); + + grid.addColumn({ + name: "foo", + headerContent: "foo" + }, 0); + grid.addColumn({ + name: "bar", + headerContent: "testHtml" + }, "foo"); + + waitUntil(function() { + return gridContainsText(grid, "testHtml"); + }, function() { + var headers = qaLocal(".v-grid-header .v-grid-row th"); + assert.equal(headers[0].innerHTML, "testHtml"); + assert.equal(headers[1].innerHTML, "foo"); + + expect(grid.addColumn.bind(grid, { + name: "baz" + }, "foobar")).to.throw("Column not found."); + done(); + }, done); + + }); + + it('edit new column', function(done) { + var c = { + name: "foo", + headerContent: "testHtml" + }; + grid.addColumn(c); + + waitUntil(function() { + return gridContainsText(grid, "testHtml"); + }, function() { + + var headers = qaLocal(".v-grid-header .v-grid-row th"); + assert.equal(headers[grid.columns.length - 1].innerHTML, "testHtml"); + + c.headerContent = "testHtml2"; + + waitUntil(function() { + return gridContainsText(grid, "testHtml2"); + }, function() { + assert.equal(headers[grid.columns.length - 1].innerHTML, "testHtml2"); + done(); + }, done); + + }, done); + + }); + + it('edit existing column', function(done) { + grid.columns[0].headerContent = "testHtml"; + waitUntil(function() { + return gridContainsText(grid, "testHtml"); + }, function() { + var headers = qaLocal(".v-grid-header .v-grid-row th"); + assert.equal(headers[0].innerHTML, "testHtml"); + done(); + }); + }); + + it('generated value', function(done) { + grid.addColumn({ + valueGenerator: function(dataItem) { + return "foo " + dataItem[0]; + } + }); + + waitUntil(function() { + return gridContainsText(grid, "foo Grid"); + }, done, done); + }); + + it('setting valueGenerator shouldnt fire select', function() { + var selectListener = sinon.spy(); + grid.addEventListener('select', selectListener); + + grid.selection.mode = "multi"; + grid.columns[0].valueGenerator = function() { return 1; }; + expect(selectListener.notCalled).to.be.true; + }); + + it('should not update the generated value', function(done) { + grid.columns[0].valueGenerator = function(dataItem) { + return Math.random(); + }; + + grid.then(function() { + var generatedValue = getFirstCell().innerText; + grid.selection.select(0); + expect(generatedValue).to.eql(getFirstCell().innerText); + done(); + }); + + }); + + it('renderer property', function(done) { + grid.columns[0].renderer = function(cell) { + cell.element.innerHTML = "<b>" + cell.data + "</b>"; + }; + + waitUntil(function() { + return gridContainsText(grid, "<b>Grid</b>"); + }, done, done); + }); + + it('renderer: cell values on change', function(done) { + var mydata = [ + ["John", "TestFoo"], + ["Jane", "TestBar"], + ]; + + grid.data.source = mydata; + + grid.columns[1].renderer = function(cell) { + cell.element.innerHTML = cell.data; + cell.element.cell = cell; + }; + + waitUntil(function() { + return gridContainsText(grid, "TestFoo"); + }, function() { + var cell = grid.querySelectorAll(".v-grid-body .v-grid-cell")[3].cell; + assert.equal(cell.row.index, 1); + assert.equal(cell.index, 1); + + mydata.splice(0, 1); + mydata[0].splice(0, 1); + grid.data.clearCache(); + + grid.columns.splice(0, 1); + waitUntil(function() { + return !gridContainsText(grid, "TestFoo"); + }, function() { + assert.equal(cell.row.index, 0); + assert.equal(cell.index, 0); + done(); + }, done); + }, done); + + }); + + it('initial property values', function() { + assert.equal(grid.columns[0].headerContent, "Name"); + }); + + describe('modifying columns array directly', function() { + it('should replace header content', function() { + expect(grid.querySelector('th').textContent).to.equal('Name'); + + grid.columns[0].headerContent = 'Foo'; + + return grid.then(function() { + expect(grid.querySelector('th').textContent).to.equal('Foo'); + }); + }); + + // fails because of replacing columns doesn't render row contents, + // see https://trello.com/c/8e27Tv3q/58-v-grid-bugs + it.skip('should render row contents', function() { + expect(grid.querySelectorAll('td').textContent).to.equal('Grid'); + + grid.columns = [{headerContent: 'Foo'}]; + + return grid.then(function() { + expect(grid.querySelectorAll('td').textContent).to.equal('Grid'); + }); + }); + }); + + it('modify columns array', function(done) { + var col = grid.columns[0]; + grid.columns.splice(1, 1); + + waitUntil(function() { + return !gridContainsText(grid, "Progress"); + }, function() { + grid.columns.push({ + headerContent: "testHtml" + }); + waitUntil(function() { + return gridContainsText(grid, "testHtml"); + }, done, done); + }, done); + }); + + it('remove column', function(done) { + grid.addColumn({ + name: "test", + headerContent: "test" + }); + grid.removeColumn(0); + + waitUntil(function() { + return !gridContainsText(grid, "Name") && gridContainsText(grid, "test"); + }, function() { + grid.removeColumn("test"); + waitUntil(function() { + return !gridContainsText(grid, "test"); + }, done, done); + }, done); + }); + + it('add new column to an empty grid', function(done) { + grid.columns = []; + + grid.columns.push({ + name: "foo", + headerContent: "fooheader" + }); + + grid.then(function() { + expect(gridContainsText(grid, 'fooheader')).to.be.true; + done(); + }); + }); + + it('frozen column', function(done) { + grid.frozenColumns = 1; + + waitUntil(function() { + return gridContainsText(grid, "v-grid-cell frozen"); + }, function() { + var headers = qaLocal(".v-grid-header .v-grid-row th"); + assert.isTrue(headers[0].classList.contains("frozen")); + done(); + }, done); + + }); + + it('frozen column declarative', function() { + grid.setAttribute("frozen-columns", "1"); + + return grid.then(function() { + expect(function(){grid.selection.mode = "multi";}).not.to.throw(); + }); + }); + + it('frozen column: unfreeze selection column', function() { + grid.selection.mode = "multi"; + assert.ok(qLocal(".frozen")); + + grid.frozenColumns = -1; + assert.notOk(qLocal(".frozen")); + }); + + it('should add a column to an empty grid with an index', function() { + grid.columns = []; + return grid.then(function() { + grid.addColumn({headerContent: "foo"}, 0); + return grid; + }).then(function() { + expect(qaLocal(".v-grid-header .v-grid-cell")).to.have.length(1); + return grid; + }); + }); + + it('should reference header cell after adding a new column', function() { + grid.addColumn({name: "foo"}); + grid.header.getCell(0, "foo").content = "foo"; + expect(grid.columns[2].headerContent).to.eql("foo"); + }); + + it('should support nested column names', function() { + grid.addColumn({ + name: "foo.bar.baz", + }); + grid.data.source = [{ + foo: { + bar: { + baz: "testing" + } + } + }]; + return grid.then(function() { + expect(gridContainsText(grid, "testing")).to.be.true; + }); + }); + + it('should not return values from name path', function() { + grid.addColumn({ + name: "foo.bar.baz", + }); + grid.data.source = [{ + foo: { + bar: "testing" + } + }]; + return grid.then(function() { + expect(gridContainsText(grid, "testing")).to.be.false; + }); + }); + + it('should allow undefined nested values', function() { + grid.addColumn({ + name: "foo.bar.baz", + }); + grid.data.source = [{ + foo: { + bar: undefined + } + }]; + return grid.then(function() { + expect(qaLocal(".v-grid-body .v-grid-cell")[2].innerHTML).to.be.empty; + }); + }); + + it('should have the right default value if flex attribute exists', function() { + qLight("table col").setAttribute("flex", ""); + return grid.then(function() { + expect(grid.columns[0].flex).to.eql(1); + expect(grid.columns[1].flex).to.eql(-1); + }); + }); + + it('should size columns with width property', function() { + grid.columns[0].width = 100; + return grid.then(function(){ + expect(qLocal(".v-grid-cell").offsetWidth).to.eql(100); + }); + }); + + it('should size columns with minWidth property', function() { + grid.columns[0].width = 100; + grid.columns[0].minWidth = 150; + return grid.then(function(){ + expect(qLocal(".v-grid-cell").offsetWidth).to.eql(150); + }); + }); + + it('should size columns with maxWidth property', function() { + grid.columns[0].maxWidth = 100; + return grid.then(function(){ + expect(qLocal(".v-grid-cell").offsetWidth).to.eql(100); + }); + }); + + }); +</script> + +</body> +</html> diff --git a/vaadin-grid/test/grid-editor-handler.html b/vaadin-grid/test/grid-editor-handler.html new file mode 100644 index 0000000..20c6e66 --- /dev/null +++ b/vaadin-grid/test/grid-editor-handler.html @@ -0,0 +1,202 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + +<div id="gridwrapper"></div> + +<script> + describe.feature('using editor handler', function() { + var editorHandler; + + beforeEach(function() { + grid.columns = [{name: 'Name'}, {name: 'Value'}]; + grid.editor.cancel(); + + editorHandler = { + getCellEditor: function(columnObject) { + var input = document.createElement("input"); + return input; + }, + bind: function(req) { + for (var i = 0; i < req.grid.columns.length; i++) { + var col = req.grid.columns[i]; + if (!col.readOnly) { + var el = req.getCellEditor(col); + el.value = req.dataItem[i]; + } + } + req.success(); + }, + save: function(req) { + var failingColumns = []; + for (var i = 0; i < req.grid.columns.length; i++) { + var col = req.grid.columns[i]; + var el = req.getCellEditor(col); + if (el.value == "fail") { + failingColumns.push(col); + } + } + if (failingColumns.length > 0) { + req.failure("Save failed", failingColumns); + } else { + req.success(); + } + } + }; + + grid.editor.handler = editorHandler; + + return grid; + }); + + it('editor: enabled', function() { + grid.columns[0].name = "name"; + grid.columns[1].name = "value"; + grid.editor.handler = editorHandler; + expect(grid.editor.editRow.bind(grid.editor, 0)).to.throw("editor is not enabled"); + grid.editor.enabled = true; + grid.editor.editRow(0); + + assert.isTrue(gridContainsText(grid, "v-grid-editor")); + }); + + it('editor: saveButtonText and cancelButtonText', function() { + grid.columns[0].name = "name"; + grid.columns[1].name = "value"; + grid.editor.handler = editorHandler; + grid.editor.enabled = true; + grid.editor.editRow(0); + grid.editor.saveButtonText = "saveButtonTextFoo"; + grid.editor.cancelButtonText = "cancelButtonTextFoo"; + + assert.isTrue(gridContainsText(grid, "saveButtonTextFoo")); + assert.isTrue(gridContainsText(grid, "cancelButtonTextFoo")); + }); + + it('editor: editrow', function() { + grid.columns[0].name = "name"; + grid.columns[1].name = "value"; + grid.editor.handler = editorHandler; + grid.editor.enabled = true; + + grid.editor.editRow(0); + assert.equal(qLocal(".v-grid-editor input").value, "Grid"); + grid.editor.cancel(); + assert.isFalse(gridContainsText(grid, "v-grid-editor")); + grid.editor.editRow(1); + assert.equal(qLocal(".v-grid-editor input").value, "VaadinX"); + grid.editor.save(); + assert.isFalse(gridContainsText(grid, "v-grid-editor")); + + expect(grid.editor.editRow.bind(grid.editor, 10)).to.throw("Row index"); + }); + + it('editor: failure', function() { + grid.columns[0].name = "name"; + grid.columns[1].name = "value"; + grid.editor.handler = editorHandler; + grid.editor.enabled = true; + + grid.editor.editRow(0); + var fields = qaLocal(".v-grid-editor input"); + fields[0].value = "fail"; + grid.editor.save(); + + assert.isTrue(gridContainsText(grid, "Save failed")); + var cells = qaLocal(".v-grid-editor-cells > div"); + assert.isTrue(cells[0].classList.contains("error")); + assert.isFalse(cells[1].classList.contains("error")); + + }); + + it('editor: return null cell editor', function() { + grid.columns[0].name = "name"; + grid.columns[1].name = "value"; + grid.editor.handler = { + getCellEditor: function(columnObject) { + return columnObject === grid.columns[0] ? null : undefined; + }, + bind: function(req) { + req.success(); + } + }; + grid.editor.enabled = true; + + grid.editor.editRow(0); + var cells = qaLocal(".v-grid-editor .v-grid-editor-cells > div"); + assert.lengthOf(cells, 2); + + var editors = qaLocal(".v-grid-editor .v-grid-editor-cells > div *"); + assert.lengthOf(editors, 0); + }); + + it('editor: element instance after save', function() { + grid.editor.enabled = true; + grid.editor.handler = editorHandler; + + var editor1, editor2; + editorHandler.save = function(req) { + if (!editor1) { + editor1 = req.getCellEditor(grid.columns[0]); + req.failure(); + } else { + editor2 = req.getCellEditor(grid.columns[0]); + req.success(); + } + }; + grid.editor.editRow(0); + + //Save fails + grid.editor.save(); + //Save succeeds + grid.editor.save(); + + assert.equal(editor1, editor2); + }); + + // fails because of replacing columns doesn't render row contents, + // see https://trello.com/c/8e27Tv3q/58-v-grid-bugs + it.skip('editor: default editor', function() { + grid.editor.enabled = true; + grid.editor.editRow(0); + + return grid.then(function() { + assert.equal("Grid", grid.querySelector('tbody tr td').textContent); + assert.equal("Grid", grid.querySelector('input').value); + + grid.querySelector('input').value = "Foo"; + grid.editor.save(); + }); + + }); + + it('editor: getCellEditor and read-only columns', function() { + grid.columns[0].readOnly = true; + + sinon.spy(editorHandler, "getCellEditor"); + + grid.editor.handler = editorHandler; + grid.editor.enabled = true; + grid.editor.editRow(0); + + assert.isTrue(editorHandler.getCellEditor.calledOnce); + + editorHandler.getCellEditor.restore(); + }); + }); +</script> + +</body> +</html> diff --git a/vaadin-grid/test/grid-properties.html b/vaadin-grid/test/grid-properties.html new file mode 100644 index 0000000..46743a4 --- /dev/null +++ b/vaadin-grid/test/grid-properties.html @@ -0,0 +1,86 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + +<div id="gridwrapper"></div> + +<script> + describe.feature('using properties', function() { + + it('rowClassGenerator', function() { + var gridEquals = true; + var elementEquals = true; + assert.notOk(grid.rowClassGenerator); + var rowClassGenerator = function(row) { + gridEquals = gridEquals && row.grid == grid; + elementEquals = elementEquals && row.element == qaLocal(".v-grid-body .v-grid-row")[row.index]; + return row.index + "_" + row.data[0]; + }; + + grid.rowClassGenerator = rowClassGenerator; + + assert.isTrue(elementEquals && gridEquals); + assert.isTrue(qLocal(".v-grid-body .v-grid-row").classList.contains("0_Grid")); + assert.equal(grid.rowClassGenerator, rowClassGenerator); + }); + + it('cellClassGenerator', function() { + var elementEquals = true; + + grid.columns[0].name = "name"; + grid.columns[1].name = "value"; + assert.notOk(grid.cellClassGenerator); + var cellClassGenerator = function(cell) { + var columnIndex = cell.columnName == "name" ? 0 : 1; + var cellElement = qaLocal(".v-grid-body .v-grid-row")[cell.row.index].querySelectorAll(".v-grid-cell")[columnIndex]; + elementEquals = elementEquals && cell.element == cellElement; + return cell.columnName; + }; + + grid.cellClassGenerator = cellClassGenerator; + + assert.isTrue(elementEquals); + assert.isTrue(qLocal(".v-grid-body .v-grid-row .v-grid-cell").classList.contains("name")); + assert.equal(grid.cellClassGenerator, cellClassGenerator); + }); + + it('should be enabled by default', function() { + expect(grid.disabled).to.be.false; + }); + + it('should disable', function() { + grid.disabled = true; + expect(grid.disabled).to.be.true; + }); + + it('should reflect disabled to attribute', function() { + grid.disabled = true; + expect(grid.hasAttribute("disabled")).to.be.true; + grid.disabled = false; + expect(grid.hasAttribute("disabled")).to.be.false; + }); + + it('should apply disabled attribute', function() { + grid.setAttribute("disabled", true); + expect(grid.disabled).to.be.true; + grid.removeAttribute("disabled"); + expect(grid.disabled).to.be.false; + }); + }); + +</script> + +</body> +</html> diff --git a/vaadin-grid/test/grid-redrawer.html b/vaadin-grid/test/grid-redrawer.html new file mode 100644 index 0000000..81c5f49 --- /dev/null +++ b/vaadin-grid/test/grid-redrawer.html @@ -0,0 +1,201 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + +<div id="gridwrapper"></div> + +<script> + describe.feature('redrawer', function() { + function width(e) { + return pxval(e, 'width'); + } + + function height(e) { + return pxval(e, 'height'); + } + + function pxval(e, prop) { + return parseInt(e.ownerDocument.defaultView.getComputedStyle(e).getPropertyValue(prop).replace('px', '')); + } + + describe('redraw', function() { + function assertHeightByRows(rows) { + var headersHeight = headers * thHeight; + var footersHeight = footers * tfHeight; + + h1 = headersHeight + footersHeight + rows * tdHeight; + // IE and FF add an aditional pixel to each row + h2 = h1 + rows + headers + footers; + + expect([h1, h2]).to.include(height(inner)); + } + + function assertSameDimensions() { + expect(width(grid)).to.equal(width(inner)); + expect(height(grid)).to.equal(height(inner)); + } + + var inner, + tbody, + headers, + footers, + tfHeight, + thHeight, + tdHeight + + beforeEach(function() { + inner = qaLocal("div.v-grid")[1]; + tbody = qLight('table tbody'); + + headers = qaLocal('thead tr').length; + footers = qaLocal('tfoot tr').length; + + tfHeight = height(qLocal('tfoot tr td')); + thHeight = height(qLocal('thead tr th')); + tdHeight = height(qLocal('tbody tr td')); + + grid.style.height = ""; + grid.style.width = ""; + grid.removeAttribute('rows'); + + // need to return thenable object for FF sake. + return grid; + }); + + // currently disabled because the grid.then call jams the test on IE. + it.skip('should draw correct dimensions and row heights by default', function() { + return grid.then(function() { + assertSameDimensions(); + assertHeightByRows(2); + }); + }); + + it('should redraw correctly after modifying body', function() { + tbody.innerHTML += tbody.innerHTML; + + return grid.then(function() { + assertSameDimensions(); + assertHeightByRows(4); + }); + }); + + describe('using limited row visibility', function() { + before(function() { + // Increase the number of rows + tbody.innerHTML += tbody.innerHTML; //4 + tbody.innerHTML += tbody.innerHTML; //8 + tbody.innerHTML += tbody.innerHTML; //16 + + return grid; + }); + + it('should redraw only visible rows', function() { + return grid.then(function() { + assertSameDimensions(); + + // grid has a limit of 10 data rows by default + assertHeightByRows(10); + }); + }); + + it('should redraw visible rows after limit is decreased', function() { + grid.rows = 3; + + return grid.then(function() { + assertSameDimensions(); + + assertHeightByRows(3); + }); + }); + + it('should redraw visible rows limit is removed', function() { + grid.rows = 0; + + return grid.then(function() { + assertSameDimensions(); + + assertHeightByRows(10); // default + }); + }); + }); + + it('should redraw with fixed dimensions', function() { + grid.style.width = '300px'; + grid.style.height = '100px'; + + return grid.then(function() { + return grid.then(function() { + assertSameDimensions(); + }); + }); + }); + + describe('grid with a fixed height (issue #8)', function() { + it('should keep the correct height after sorting', function() { + grid.columns[0].sortable = true; + grid.style.height = "500px"; + + var firstNonFrozenHeaderCell = qLocal.bind(this, ".v-grid-header .v-grid-cell:not(.frozen)"); + firstNonFrozenHeaderCell().click(); + + return grid.then(function() { + expect(qaLocal('.v-grid')[3].style.height).to.equal('100%'); + }); + }); + }); + + describe('using scaled dimensions', function() { + beforeEach(function() { + grid.style.position = 'absolute'; + grid.style.width = '100%'; + grid.style.height = '100%'; + + return grid; + }); + + it('should redraw with scaled dimensions', function() { + assertSameDimensions(); + }); + + it('should match dimensions with the surrounding div', function() { + expect(height(grid)).to.equal(document.body.clientHeight); + + // For some reason in IE sometimes there is a slight difference of 1 pixels + expect(Math.abs(document.body.clientWidth - width(grid))).to.be.at.most(1); + }) + + it('should allow different dimensions for v-grid and inner div', function() { + // We can have different height for v-grid and the inner grid. + // Also we can define more than 10 rows. + tbody.innerHTML += tbody.innerHTML; //4 + tbody.innerHTML += tbody.innerHTML; //8 + tbody.innerHTML += tbody.innerHTML; //16 + + grid.rows = 12; + grid.style.width = '50%'; + + return grid.then(function() { + expect(height(grid)).to.not.equal(height(inner)); + assert.equal(width(grid), width(inner)); + assertHeightByRows(12); + }); + }); + }); + }); + }); +</script> + +</body> +</html> diff --git a/vaadin-grid/test/grid-rendering-light-dom.html b/vaadin-grid/test/grid-rendering-light-dom.html new file mode 100644 index 0000000..0251cd7 --- /dev/null +++ b/vaadin-grid/test/grid-rendering-light-dom.html @@ -0,0 +1,130 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + +<div id="gridwrapper"></div> + +<script> + describe.feature('rendering light DOM', function() { + it('light dom table header gets rendered in the grid', function() { + var row = qLocal(".v-grid-header .v-grid-row"); + var cells = row.childNodes; + + assert.isTrue(cells[0].innerHTML == 'Name'); + assert.isTrue(cells[1].innerHTML == 'Value'); + }); + + it('light dom table body gets rendered in the grid', function() { + var row = qLocal(".v-grid-body .v-grid-row"); + var cells = row.childNodes; + + assert.isTrue(cells[0].innerHTML == 'Grid'); + assert.isTrue(cells[1].innerHTML == '10000'); + }); + + function removeGrid() { + if (grid) { + grid.style.visibility = "hidden"; + document.body.appendChild(grid); + grid = null; + } + } + + // makes grid.then in afterEach to never finish... + it.skip('DOM: headers & footers', function(done) { +// removeGrid(); + wrapper.innerHTML = "<v-grid><table>" + + "<thead hidden><tr class='red'><td colspan='2'></td></tr><tr class='pink'><th></th><th></th></tr></thead>" + + "<tfoot><tr class='foot1'><td colspan='2'></td></tr><tr class='foot2'><td></td><td></td></tr></tfoot>" + + "</table></v-grid>"; + grid = wrapper.querySelector("v-grid"); + + waitUntil(function() { + return qLocal(".v-grid-body"); + }, function() { + assert.equal(0, qaLocal("thead tr").length); + assert.equal(1, qaLocal("tfoot tr.foot1").length); + assert.equal(1, qaLocal("tfoot tr.foot2").length); + assert.equal(1, qaLocal("tfoot td[colspan='2']").length); + + qLight("thead").setAttribute('hidden', false) + waitUntil(function() { + return qaLocal("thead tr").length > 0; + }, function() { + assert.equal(1, qaLocal("thead tr.red").length); + assert.equal(1, qaLocal("thead tr.pink").length); + assert.equal(1, qaLocal("thead th[colspan='2']").length); + done(); + }, done); + + }, done); + }); + + it('DOM: mutation', function(done) { + waitUntil(function() { + return qLocal(".v-grid-body"); + }, function() { + var nrows = qaLocal("tbody tr").length; + var nheads = qaLocal("thead tr").length; + qLight("thead").innerHTML += qLight("table thead").innerHTML; + qLight("tbody").innerHTML += qLight("table tbody").innerHTML; + assert.equal("Name", qLocal("th").textContent); + qLight("th").textContent = "foo"; + waitUntil(function() { + return qLocal("tbody tr") && qaLocal("tbody tr").length == nrows * 2; + }, function() { + assert.equal(qaLocal("tbody tr").length, nrows * 2); + assert.equal(qaLocal("thead tr").length, nheads * 2); + assert.equal("foo", qLocal("th").textContent); + done(); + }, done); + }, done); + }); + + it('should have a sort-order', function(done) { + var ths = light().querySelectorAll("th"); + ths[0].setAttribute("sort-direction", "asc"); + ths[1].setAttribute("sort-direction", "desc"); + + grid.then(function(){ + var sortOrder = grid.sortOrder; + expect(grid.sortOrder[0]).to.eql({column: 0, direction: "asc"}); + expect(grid.sortOrder[1]).to.eql({column: 1, direction: "desc"}); + }).then(done); + }); + + it('should apply header-text from a th element', function(done) { + light().querySelector("th").setAttribute("header-text", "foo"); + + grid.then(function(){ + expect(grid.columns[0].headerHtml).to.eql("foo"); + }).then(done); + }); + + it('should apply header-text from a col element', function(done) { + var col = document.createElement("col"); + col.setAttribute("header-text", "foo"); + light().querySelector("table").prependChild(col); + + grid.then(function(){ + expect(grid.columns[0].headerHtml).to.eql("foo"); + }).then(done); + }); + + }); +</script> + +</body> +</html> diff --git a/vaadin-grid/test/grid-scrolling-rows.html b/vaadin-grid/test/grid-scrolling-rows.html new file mode 100644 index 0000000..a0ff781 --- /dev/null +++ b/vaadin-grid/test/grid-scrolling-rows.html @@ -0,0 +1,114 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + +<div id="gridwrapper"></div> + +<script> + describe.feature('scrolling rows', function() { + + var infiniteDataSource = function(req) { + var data = []; + for (var i = req.index; i < req.index + req.count; i++) { + data.push(["foo " + i, "bar " + i]); + } + req.success(data, this.size); + }; + + function firstColumnContents() { + var cells = qaLocal('td'); + + return _.chain(cells) + .filter(function(n) { + return _.indexOf(cells, n) % 2 == 0; + }) + .map(function(n) { + return n.textContent; + }) + .reduce(function(result, n) { + return result + ', ' + n; + }).value(); + } + + before(function() { + infiniteDataSource.size = 100; + grid.data.source = infiniteDataSource; + grid.rows = 5; + + return grid; + }); + + beforeEach(function() { + //reset position to an arbitrary row. + return grid.scrollToRow(24).then(function () { + // calling scrollToRow - scrollToRow - then seems to quite often + // run the callback in 'then' before the latter scrolling has finished. + // This is most likely caused by multiple timers being fired inside the Grid, + // and there's some gap between them - which makes grid.isWorkPending() to return + // 'false' too soon. + // Adding one 'then' in between the scrolling calls + // doesn't seem to remedy the situation. So let's add more. + return grid; + }); + }); + + it('should throw an error when scrolling to an invalid row', function() { + expect(grid.scrollToRow.bind(grid, -1)).to.throw("Row index"); + expect(grid.scrollToRow.bind(grid, 100)).to.throw("Row index"); + }); + + it('should scroll using scrollToRow', function() { + return grid.scrollToRow(50) + .then(function() { + expect(firstColumnContents()).to.contain('foo 50'); + }); + }); + + describe('scrolling with destination', function() { + it('should scroll to start', function() { + return grid.scrollToRow(50, 'start') + .then(function() { + expect(firstColumnContents()).to.contain('foo 50'); + expect(firstColumnContents()).to.contain('foo 54'); + }); + }); + + it('should scroll to end', function() { + return grid.scrollToRow(50, 'end') + .then(function() { + expect(firstColumnContents()).to.contain('foo 46'); + expect(firstColumnContents()).to.contain('foo 50'); + }); + }); + }); + + it('should scroll to end', function() { + return grid.scrollToEnd() + .then(function() { + expect(firstColumnContents()).to.contain('foo 99'); + }); + }); + + it('should scroll to start', function() { + return grid.scrollToStart() + .then(function() { + expect(firstColumnContents()).to.contain('foo 0'); + }); + }); + }); +</script> + +</body> +</html> diff --git a/vaadin-grid/test/grid-selecting-rows.html b/vaadin-grid/test/grid-selecting-rows.html new file mode 100644 index 0000000..0ac2eee --- /dev/null +++ b/vaadin-grid/test/grid-selecting-rows.html @@ -0,0 +1,645 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + + <div id="gridwrapper"></div> + + <script> + describe.feature('selecting rows', function() { + var selectListener; + + before(function() { + selectListener = sinon.spy(); + grid.addEventListener('select', selectListener); + }); + + function getSelectionModeAttr() { + return grid.getAttribute('selection-mode'); + }; + + function setSelectionModeAttr(mode) { + grid.setAttribute('selection-mode', mode); + + return grid; + }; + + afterEach(function() { + selectListener.reset(); + + return grid.then(function() { + // force selection clear + grid.selection.mode = 'disabled'; + grid.selection.mode = 'single'; + + return grid; + }); + }); + + describe('using attributes', function() { + describe('selection-mode', function() { + it('should set selectionMode to disabled', function() { + return setSelectionModeAttr('disabled').then(function() { + expect(grid.selection.mode).to.equal('disabled'); + }); + }); + + it('should set selectionMode to single', function() { + return setSelectionModeAttr('single').then(function() { + expect(grid.selection.mode).to.equal('single'); + }); + }); + + it('should set selectionMode to multi', function() { + return setSelectionModeAttr('multi').then(function() { + expect(grid.selection.mode).to.equal('multi'); + }); + }); + + it('should should remove selectionMode property', function() { + setSelectionModeAttr('disabled'); + grid.removeAttribute('selection-mode'); + + return grid.then(function() { + // 'single' is the default + expect(grid.selection.mode).to.equal('single'); + }); + }); + + // TODO: throws an error, but for some reason expect doesn't catch it. + it.skip('should fail setting the value to foobar', function() { + expect(function() { + setSelectionModeAttr('foobar'); + }).to.throw(Object); + }); + }); + }); + + describe('using properties', function() { + describe('selection.mode', function() { + var checkBoxQuery = "input[type='checkbox']"; + + it('should be single by default', function() { + expect(grid.selection.mode).to.equal('single'); + }); + + it('should be use default value when removing the value', function() { + grid.selection.mode = 'disabled'; + + grid.selection.mode = undefined; + + expect(grid.selection.mode).to.equal('single'); + }); + + it('should set selection-mode to disabled', function() { + grid.selection.mode = 'disabled'; + + return grid.then(function() { + expect(getSelectionModeAttr()).to.equal('disabled'); + expect(qLocal(checkBoxQuery)).to.be.undefined; + }); + }); + + it('should set selection-mode to single', function() { + grid.selection.mode = 'single'; + + return grid.then(function() { + expect(getSelectionModeAttr()).to.equal('single'); + expect(qLocal(checkBoxQuery)).to.be.undefined; + }); + }); + + it('should set selection-mode to multi', function() { + grid.selection.mode = 'multi'; + + return grid.then(function() { + expect(getSelectionModeAttr()).to.equal('multi'); + expect(qLocal(checkBoxQuery)).to.not.be.undefined; + }); + }); + + it('should fail setting the value to foobar', function() { + expect(function() { + grid.selection.mode = 'foobar'; + }).to.throw(Object); + }); + }); + + describe('selected', function() { + describe('with mode: single', function() { + beforeEach(function() { + grid.selection.mode = 'single'; + }); + + it('should clear the selection when changing mode to disabled', function() { + grid.selection.select(0); + + grid.selection.mode = 'disabled'; + + expect(grid.selection.selected()).to.be.empty; + }); + + it('should clear selection when changing mode to multi', function() { + grid.selection.select(0); + + grid.selection.mode = 'multi'; + + expect(grid.selection.selected()).to.be.empty; + }); + }); + + describe('with selectionMode: multi', function() { + beforeEach(function() { + grid.selection.mode = 'multi'; + }); + + it('should fire a \'select\' event', function() { + grid.selection.select(0); + + expect(selectListener.calledOnce).to.be.true; + }); + + it('should clear the selection when changing mode to disabled', function() { + grid.selection.select(0); + + grid.selection.mode = 'disabled'; + + expect(grid.selection.selected()).to.be.empty; + }); + + it('should clear selection when changing mode to single', function() { + grid.selection.select(0); + + grid.selection.mode = 'single'; + + expect(grid.selection.selected()).to.be.empty; + }); + + it('should remove multiple selections when changing mode to single', function() { + grid.selection.select(0); + grid.selection.select(1); + + grid.selection.mode = 'single'; + + expect(grid.selection.selected()).to.be.empty; + }); + }); + + describe('with selectionMode: disabled', function() { + beforeEach(function() { + grid.selection.mode = 'disabled'; + }); + + it('should not select any rows', function() { + grid.selection.select(0); + + expect(grid.selection.selected()).to.be.empty; + }); + }); + }); + }); + + describe('by clicking', function() { + function getFirstCell() { + return qLocal('.v-grid-body .v-grid-cell'); + } + + function clickFirstCell() { + getFirstCell().click(); + + return grid; + } + + before(function() { + // extra 'wait' added for IE11. + return grid; + }); + + it('should fire a \'select\' event', function() { + return clickFirstCell().then(function() { + expect(selectListener.calledOnce).to.be.true; + expect(selectListener.args[0][0]).to.have.property('type', 'select'); + }); + }); + + describe('with selection-mode: single', function() { + beforeEach(function() { + return setSelectionModeAttr('single'); + }); + + it('should select a row', function() { + return clickFirstCell().then(function() { + expect(grid.selection.selected()).to.eql([0]); + }); + }); + }); + + describe('with selection-mode: multi', function() { + beforeEach(function() { + return setSelectionModeAttr('multi'); + }); + + it('should only focus a clicked cell', function() { + return clickFirstCell().then(function() { + expect(grid.selection.selected()).to.be.empty; + expect(getFirstCell().getAttribute('class')).to.contain('focus'); + }); + }); + + // TODO: apparently clicking checkboxes isn't going to happen using JS... + it.skip('should select multiple rows', function() { + var inputs = qaLocal('input'); + inputs[0].checked = true; + inputs[1].click(); + + expect(getSelectedRowsAttr()).to.equal('0,1'); + }); + }); + + describe('with selection-mode: disabled', function() { + beforeEach(function() { + return setSelectionModeAttr('disabled'); + }); + + it('should not select a row', function() { + return clickFirstCell().then(function() { + expect(grid.selection.selected()).to.be.empty; + }); + }); + }); + }); + + describe('by using API', function() { + it('should fire a \'select\' event', function() { + grid.selection.select(0); + + expect(selectListener.calledOnce).to.be.true; + }); + + it('should not select invalid row', function() { + grid.selection.select('foo'); + + expect(grid.selection.selected()).to.be.empty; + }); + + it('should add \'row-selected\' class to the selected row', function() { + return grid.selection.select(1).then(function() { + expect(qaLocal('.v-grid-body .v-grid-row-selected')).to.have.length(1); + }); + }); + + describe('with selectionMode: single', function() { + beforeEach(function() { + grid.selection.mode = 'single'; + }); + + it('should select a row', function() { + grid.selection.select(1); + + expect(grid.selection.selected()).to.eql([1]); + }); + + it('should select another row', function() { + grid.selection.select(1); + grid.selection.select(0); + + expect(grid.selection.selected()).to.eql([0]); + }); + }); + + describe('with selectionMode: multi', function() { + beforeEach(function() { + grid.selection.mode = 'multi'; + }) + + it('should select multiple rows', function() { + grid.selection.select(0); + grid.selection.select(1); + + expect(grid.selection.selected()).to.eql([0,1]); + }); + }); + + describe('with selectionMode: disabled', function() { + beforeEach(function() { + grid.selection.mode = 'disabled'; + }); + + it('should not select a row', function() { + grid.selection.select(0); + + expect(grid.selection.selected()).to.be.empty; + }); + }); + }); + + describe('deselecting rows using API', function() { + it('should fire \'select\' event', function() { + grid.selection.select(0); + + grid.selection.deselect(0); + + expect(selectListener.calledTwice).to.be.true; + }); + + describe('with selectionMode: single', function() { + beforeEach(function() { + grid.selection.mode = 'single'; + }); + + it('should deselect a row', function() { + grid.selection.select(0); + + grid.selection.deselect(0); + + expect(grid.selectedRows).to.be.empty; + }); + + it('should not deselect other rows', function() { + grid.selection.select(0); + + grid.selection.deselect(1); + + expect(grid.selection.selected()).to.eql([0]); + }); + }); + + describe('with selectionMode: multi', function() { + beforeEach(function() { + grid.selection.mode = 'multi'; + }); + + it('should deselect a single row', function() { + grid.selection.select(0); + grid.selection.select(1); + + grid.selection.deselect(0); + + expect(grid.selection.selected()).to.eql([1]); + }); + }); + }); + + describe('selected indexes', function() { + + describe('in mode: single', function() { + beforeEach(function() { + grid.selection.mode = 'single'; + grid.selection.select(0); + }); + + it('should have a right size', function() { + expect(grid.selection.size).to.eql(1); + }); + + it('should have right deselections', function() { + expect(grid.selection.deselected()).to.be.empty; + }); + + it('should have right selections', function() { + expect(grid.selection.selected()).to.eql([0]); + }); + + it('should iterate right selections', function() { + var spy = sinon.spy(); + grid.selection.selected(spy); + expect(spy.calledOnce).to.be.true; + }); + + it('should return right mapped value', function() { + var mapper = function(index){ + return "foo " + index; + }; + expect(grid.selection.selected(mapper)).to.eql(["foo 0"]); + }); + + it('should return nothing with iterator', function() { + var iterator = function(i){ + // Itearate + }; + expect(grid.selection.selected(iterator)).to.be.empty; + }); + + it('clear should work right', function() { + grid.selection.clear(); + expect(grid.selection.selected()).to.be.empty; + }); + + it('selectAll should work right', function() { + grid.selection.selectAll(); + expect(grid.selection.selected()).to.be.empty; + }); + }); + + describe('in mode: multi', function() { + beforeEach(function() { + grid.data.source = function(req) { + var data = []; + for (var i = req.index; i < req.index + req.count; i++) { + data.push(["foo " + i, "bar " + i]); + } + req.success(data, 100); + }; + grid.selection.mode = 'multi'; + grid.selection.select(0); + grid.selection.select(1); + grid.selection.select(80); + grid.selection.select(81); + }); + + it('should have a right size', function() { + expect(grid.selection.size).to.eql(4); + }); + + it('should have right deselections', function() { + expect(grid.selection.deselected()).to.be.empty; + }); + + it('should have right selections', function() { + expect(grid.selection.selected()).to.eql([0,1,80,81]); + }); + + it('should iterate right selections', function() { + var spy = sinon.spy(); + grid.selection.selected(spy); + expect(spy.callCount).to.eql(4); + }); + + it('should return right mapped value', function() { + var mapper = function(index){ + return "foo " + index; + }; + expect(grid.selection.selected(mapper)).to.eql(["foo 0", "foo 1", "foo 80", "foo 81"]); + }); + + it('should return nothing with iterator', function() { + var iterator = function(i){ + // Itearate + }; + expect(grid.selection.selected(iterator)).to.be.empty; + }); + + it('should return tail', function() { + expect(grid.selection.selected(undefined, 3)).to.eql([81]); + }); + + it('should return head', function() { + expect(grid.selection.selected(undefined, undefined, 1)).to.eql([0, 1]); + }); + + it('should return range', function() { + expect(grid.selection.selected(undefined, 1, 2)).to.eql([1, 80]); + }); + + it('clear should work right', function() { + grid.selection.clear(); + expect(grid.selection.selected()).to.be.empty; + }); + + it('selectAll should work right', function() { + grid.selection.selectAll(); + expect(grid.selection.mode).to.eql("all"); + }); + + }); + + describe('in mode: all', function() { + beforeEach(function() { + grid.data.source = function(req) { + var data = []; + for (var i = req.index; i < req.index + req.count; i++) { + data.push(["foo " + i, "bar " + i]); + } + req.success(data, 100); + }; + grid.selection.mode = 'all'; + grid.selection.deselect(0); + grid.selection.deselect(1); + grid.selection.deselect(80); + grid.selection.deselect(81); + }); + + it('should have a right size', function() { + expect(grid.selection.size).to.eql(96); + }); + + it('should have right deselections', function() { + expect(grid.selection.deselected()).to.eql([0,1,80,81]); + }); + + it('should have right selections', function() { + expect(grid.selection.selected()).to.have.length(96); + }); + + it('should iterate right selections', function() { + var spy = sinon.spy(); + grid.selection.selected(spy); + expect(spy.callCount).to.eql(96); + }); + + it('should return right mapped value', function() { + var mapper = function(index){ + return "foo " + index; + }; + expect(grid.selection.selected(mapper)).to.contain("foo 2"); + expect(grid.selection.deselected(mapper)).to.eql(["foo 0", "foo 1", "foo 80", "foo 81"]); + }); + + it('should return nothing with iterator', function() { + var iterator = function(i){ + // Itearate + }; + expect(grid.selection.selected(iterator)).to.be.empty; + expect(grid.selection.deselected(iterator)).to.be.empty; + }); + + it('should return tail', function() { + expect(grid.selection.selected(undefined, 50)).to.have.length(46); + expect(grid.selection.deselected(undefined, 3)).to.eql([81]); + }); + + it('should return head', function() { + expect(grid.selection.selected(undefined, undefined, 30)).to.have.length(31); + expect(grid.selection.deselected(undefined, undefined, 1)).to.eql([0, 1]); + }); + + it('should not contain deselected values', function() { + expect(grid.selection.selected()).not.to.contain(0); + expect(grid.selection.selected()).not.to.contain(80); + }); + + it('should return range', function() { + expect(grid.selection.selected(undefined, 1, 2)).to.eql([3, 4]); + expect(grid.selection.deselected(undefined, 1, 2)).to.eql([1, 80]); + }); + + it('clear should work right', function() { + grid.selection.clear(); + expect(grid.selection.mode).to.eql("multi"); + }); + + it('selectAll should work right', function() { + grid.selection.selectAll(); + expect(grid.selection.deselected()).to.be.empty; + }); + + }); + + describe('in mode: disabled', function() { + beforeEach(function() { + grid.selection.mode = 'disabled'; + grid.selection.select(0); + }); + + it('should have a right size', function() { + expect(grid.selection.size).to.eql(0); + }); + + it('should have right deselections', function() { + expect(grid.selection.deselected()).to.eql([]); + }); + + it('should have right selections', function() { + expect(grid.selection.selected()).to.eql([]); + }); + + it('should iterate right selections', function() { + var spy = sinon.spy(); + grid.selection.selected(spy); + expect(spy.callCount).to.eql(0); + }); + + it('should return right mapped value', function() { + var mapper = function(index){ + return "foo " + index; + }; + expect(grid.selection.selected(mapper)).to.eql([]); + expect(grid.selection.deselected(mapper)).to.eql([]); + }); + + it('selectAll should work right', function() { + grid.selection.selectAll(); + expect(grid.selection.selected()).to.eql([]); + }); + + }); + + }); + + + }); + </script> +</body> + +</html> diff --git a/vaadin-grid/test/grid-sorting-rows.html b/vaadin-grid/test/grid-sorting-rows.html new file mode 100644 index 0000000..59acbbf --- /dev/null +++ b/vaadin-grid/test/grid-sorting-rows.html @@ -0,0 +1,100 @@ +<!DOCTYPE html> +<html> + +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> + +<body> + + <div id="gridwrapper"></div> + + <script> + describe.feature('sorting rows', function() { + + describe('using api', function() { + + function assignInvalidSortOrder() { + grid.data.sortOrder = [{ + column: 0, + direction: "ascending" // Should be asc or desc + }]; + } + + beforeEach(function() { + grid.columns[0].sortable = true; + grid.columns[1].sortable = true; + }); + + it('should set sortOrder property', function() { + grid.data.sortOrder = [{ + column: 0, + direction: "desc" + }]; + + expect(qLocal(".v-grid-header th").classList.contains("sort-desc")).to.be.true; + }); + + it('should clear sort order', function() { + grid.data.sortOrder = [{ + column: 0, + direction: "desc" + }]; + grid.data.sortOrder = []; + expect(grid.data.sortOrder).to.be.empty; + }); + + it('should preserve existing sort order on invalid value', function() { + grid.data.sortOrder = [{ + column: 0, + direction: "desc" + }]; + expect(assignInvalidSortOrder).to.throw("Invalid sort direction"); + expect(qLocal(".v-grid-header th").classList.contains("sort-desc")).to.be.true; + }); + + it('should be able to sort with multiple columns', function() { + grid.data.sortOrder = [{ + column: 0, + direction: "desc" + }, { + column: 1 + }]; + assert.lengthOf(grid.data.sortOrder, 2); + expect(qaLocal(".v-grid-header th")[0].classList.contains("sort-desc")).to.be.true; + expect(qaLocal(".v-grid-header th")[1].classList.contains("sort-asc")).to.be.true; + }); + + it('should reset selection', function() { + grid.selectedRows = [0]; + + grid.data.sortOrder = [{ + column: 0, + direction: "desc" + }]; + + expect(grid.selection.selected()).to.be.empty; + }); + + it('should ignore selection column from index', function() { + var firstNonFrozenHeaderCell = qLocal.bind(this, ".v-grid-header .v-grid-cell:not(.frozen)"); + + firstNonFrozenHeaderCell().click(); + expect(grid.data.sortOrder[0].column).to.eql(0); + + grid.selection.mode = "multi"; + firstNonFrozenHeaderCell().click(); + expect(grid.data.sortOrder[0].column).to.eql(0); + }); + + + }); + }); + </script> diff --git a/vaadin-grid/test/grid-static-sections.html b/vaadin-grid/test/grid-static-sections.html new file mode 100644 index 0000000..757e8d2 --- /dev/null +++ b/vaadin-grid/test/grid-static-sections.html @@ -0,0 +1,222 @@ +<!DOCTYPE html> +<html> +<head lang="en"> + <meta charset="UTF-8"> + <title></title> + <script src="../../webcomponentsjs/webcomponents-lite.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> + + <script src="common.js"></script> + + <link rel="import" href="../vaadin-grid.html"> +</head> +<body> + <div id="gridwrapper"></div> + + <script> + describe.feature('static sections', function() { + function removeHeaders() { + for(var i = grid.header.rowCount;i>0;i--) { + grid.header.removeRow(); + } + } + + function removeFooters() { + for(var i = grid.footer.rowCount;i>0;i--) { + grid.footer.removeRow(); + } + } + + beforeEach(function() { + removeHeaders(); + removeFooters(); + + grid.header.addRow(0, ['Name', 'Value']); + grid.footer.addRow(0, ['Name', 'Value']); + + grid.header.hidden = false; + grid.footer.hidden = false; + + return grid; + }); + + describe('header.defaultRow', function() { + it('should be 0 by default', function() { + expect(grid.header.defaultRow).to.equal(0); + }); + + it('should fail when set to a nonexisting row', function() { + expect(function() { + grid.header.defaultRow = 1; + }).to.throw('Row with index 1 does not exist'); + }); + + it('should set the defaultRow', function() { + grid.header.addRow(); + + // sorting indicator moves to the default row, so we'll + // use that to assert that default row has changed. + grid.columns[0].sortable = true; + grid.data.sortOrder = [{column: 0, direction: 'asc'}]; + + grid.header.defaultRow = 1; + + var cells = qaLocal('.v-grid-header .v-grid-cell'); + expect(cells[2].classList.toString()).to.contain('sort-asc'); + }); + + it('should have content in sync with column.headerContent', function() { + var column = grid.columns[0]; + var headerCell = grid.header.getCell(grid.header.defaultRow, 0); + + column.headerContent = "foo"; + expect(headerCell.content).to.eql("foo"); + + headerCell.content = "bar"; + expect(column.headerContent).to.eql("bar"); + }); + + }); + + ['header', 'footer'].forEach(function(section) { + describe(section, function() { + it('should be readonly', function() { + var originalValue = grid[section]; + + grid[section] = undefined; + + expect(grid[section]).to.equal(originalValue); + }); + + describe('getCell', function() { + it('should return correct cell using indeces', function() { + var cell = grid[section].getCell(0,0); + + expect(cell.content).to.equal('Name'); + }); + + it('should return correct cell using identifier', function() { + grid.columns[0].name = 'foo'; + + var cell = grid[section].getCell(0, 'foo'); + + expect(cell.content).to.equal('Name'); + }); + + it('should return correct cell from appended row', function() { + grid[section].addRow(1, [section + 'foo']); + + var cell = grid[section].getCell(1, 0); + + expect(cell.content).to.equal(section + 'foo'); + }); + }); + + describe('cell', function() { + describe('content', function() { + it('should set content', function() { + var cell = grid[section].getCell(0,0); + cell.content = 'foo'; + + expect(grid[section].getCell(0,0).content).to.equal('foo'); + }); + + it('should set html content', function() { + var cell = grid[section].getCell(0, 0); + + var input = document.createElement('input'); + cell.content = input; + + expect(qLocal('.v-grid-' + section + ' .v-grid-cell > input')).to.not.be.undefined; + }); + }); + + describe('hidden', function() { + it('should clear innerHTML', function() { + grid[section].hidden = true; + + expect(qLocal('.v-grid-' + section).innerHTML).to.be.empty; + }); + }); + + describe('colspan', function() { + it('should hide spanned cells', function() { + var cell = grid[section].getCell(0, 0); + + cell.colspan = 2; + + return grid.then(function() { + expect(qaLocal(".v-grid-" + section + " .v-grid-cell")[1].style.display).to.equal('none'); + }); + }); + }); + }); + + describe('addRow', function() { + it('should append new row', function() { + grid[section].addRow(); + + grid[section].getCell(1,0).content = 'foo'; + grid[section].getCell(1,1).content = 'bar'; + + var cells = qaLocal('.v-grid-' + section + ' .v-grid-cell'); + expect(cells[0].innerHTML).to.equal('Name'); + expect(cells[1].innerHTML).to.equal('Value'); + expect(cells[2].innerHTML).to.equal('foo'); + expect(cells[3].innerHTML).to.equal('bar'); + }); + + it('should insert new row to correct index', function() { + grid[section].addRow(0); + + grid[section].getCell(0,0).content = 'foo'; + grid[section].getCell(0,1).content = 'bar'; + + var cells = qaLocal('.v-grid-' + section + ' .v-grid-cell'); + expect(cells[0].innerHTML).to.equal('foo'); + expect(cells[1].innerHTML).to.equal('bar'); + expect(cells[2].innerHTML).to.equal('Name'); + expect(cells[3].innerHTML).to.equal('Value'); + }); + + it('should insert content to a new row', function() { + grid[section].addRow(0, ['foo', 'bar']); + + var cells = qaLocal(".v-grid-" + section + " .v-grid-cell"); + expect(cells[0].innerHTML).to.equal('foo'); + expect(cells[1].innerHTML).to.equal('bar'); + }); + }); + + describe('removeRow', function() { + it('should remove first row', function() { + grid[section].removeRow(); + + expect(qaLocal('.v-grid-' + section + ' .v-grid-cell')).to.be.empty; + }); + + it('should remove a specific row', function() { + grid[section].addRow(0, ['foo', 'bar']); + + grid[section].removeRow(1); + + expect(qaLocal('.v-grid-' + section + ' .v-grid-cell')).to.have.length(2); + }); + }); + + describe('setRowClassName', function() { + it('should set the classname of a specific row', function() { + grid[section].addRow(); + + grid[section].setRowClassName(1, 'second'); + + var rows = qaLocal(".v-grid-" + section + " .v-grid-row"); + expect(rows[1].classList.toString()).to.contain('second'); + }); + }); + }); + }); + }); + </script> +</body> +</html>
\ No newline at end of file diff --git a/vaadin-grid/test/index.html b/vaadin-grid/test/index.html new file mode 100644 index 0000000..e9bd2fc --- /dev/null +++ b/vaadin-grid/test/index.html @@ -0,0 +1,24 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8"> + <script src="../../webcomponentsjs/webcomponents.min.js"></script> + <script src="../../web-component-tester/browser.js"></script> +</head> +<body> +<script> +WCT.loadSuites([ + 'grid-binding-data.html', + 'grid-editing-columns.html', + 'grid-editor-handler.html', + 'grid-properties.html', + 'grid-redrawer.html', +// 'grid-rendering-light-dom.html', + 'grid-scrolling-rows.html', + 'grid-selecting-rows.html', + 'grid-static-sections.html', + 'grid-sorting-rows.html' +]); +</script> +</body> +</html> |