diff options
Diffstat (limited to 'devtools/client/shared/test/browser_tableWidget_basic.js')
-rw-r--r-- | devtools/client/shared/test/browser_tableWidget_basic.js | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/devtools/client/shared/test/browser_tableWidget_basic.js b/devtools/client/shared/test/browser_tableWidget_basic.js new file mode 100644 index 000000000..684ca99bb --- /dev/null +++ b/devtools/client/shared/test/browser_tableWidget_basic.js @@ -0,0 +1,390 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that the table widget api works fine + +"use strict"; + +const TEST_URI = "data:text/xml;charset=UTF-8,<?xml version='1.0'?>" + + "<?xml-stylesheet href='chrome://global/skin/global.css'?>" + + + // Uncomment these lines to help with visual debugging. When uncommented they + // dump a couple of thousand errors in the log (bug 1258285) + // "<?xml-stylesheet href='chrome://devtools/skin/light-theme.css'?>" + + // "<?xml-stylesheet href='chrome://devtools/skin/widgets.css'?>" + + + "<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" + + " title='Table Widget' width='600' height='500'>" + + "<box flex='1' class='theme-light'/></window>"; + +const {TableWidget} = require("devtools/client/shared/widgets/TableWidget"); + +add_task(function* () { + yield addTab("about:blank"); + let [host, , doc] = yield createHost("bottom", TEST_URI); + + let table = new TableWidget(doc.querySelector("box"), { + initialColumns: { + col1: "Column 1", + col2: "Column 2", + col3: "Column 3", + col4: "Column 4" + }, + uniqueId: "col1", + emptyText: "This is dummy empty text", + highlightUpdated: true, + removableColumns: true, + firstColumn: "col4" + }); + + startTests(doc, table); + endTests(doc, host, table); +}); + +function startTests(doc, table) { + populateTable(doc, table); + + testTreeItemInsertedCorrectly(doc, table); + testAPI(doc, table); +} + +function endTests(doc, host, table) { + table.destroy(); + host.destroy(); + gBrowser.removeCurrentTab(); + table = null; + finish(); +} + +function populateTable(doc, table) { + table.push({ + col1: "id1", + col2: "value10", + col3: "value20", + col4: "value30" + }); + table.push({ + col1: "id2", + col2: "value14", + col3: "value29", + col4: "value32" + }); + table.push({ + col1: "id3", + col2: "value17", + col3: "value21", + col4: "value31", + extraData: "foobar", + extraData2: 42 + }); + table.push({ + col1: "id4", + col2: "value12", + col3: "value26", + col4: "value33" + }); + table.push({ + col1: "id5", + col2: "value19", + col3: "value26", + col4: "value37" + }); + table.push({ + col1: "id6", + col2: "value15", + col3: "value25", + col4: "value37" + }); + table.push({ + col1: "id7", + col2: "value18", + col3: "value21", + col4: "value36", + somethingExtra: "Hello World!" + }); + table.push({ + col1: "id8", + col2: "value11", + col3: "value27", + col4: "value34" + }); + + let span = doc.createElement("span"); + span.textContent = "domnode"; + + table.push({ + col1: "id9", + col2: "value11", + col3: "value23", + col4: span + }); +} + +/** + * Test if the nodes are inserted correctly in the table. + */ +function testTreeItemInsertedCorrectly(doc, table) { + // double because of splitters + is(table.tbody.children.length, 4 * 2, "4 columns exist"); + + // Test firstColumn option and check if the nodes are inserted correctly + is(table.tbody.children[0].firstChild.children.length, 9 + 1, + "Correct rows in column 4"); + is(table.tbody.children[0].firstChild.firstChild.value, "Column 4", + "Correct column header value"); + + for (let i = 1; i < 4; i++) { + is(table.tbody.children[i * 2].firstChild.children.length, 9 + 1, + `Correct rows in column ${i}`); + is(table.tbody.children[i * 2].firstChild.firstChild.value, `Column ${i}`, + "Correct column header value"); + } + for (let i = 1; i < 10; i++) { + is(table.tbody.children[2].firstChild.children[i].value, `id${i}`, + `Correct value in row ${i}`); + } + + // Remove firstColumn option and reset the table + table.clear(); + table.firstColumn = ""; + table.setColumns({ + col1: "Column 1", + col2: "Column 2", + col3: "Column 3", + col4: "Column 4" + }); + populateTable(doc, table); + + // Check if the nodes are inserted correctly without firstColumn option + for (let i = 0; i < 4; i++) { + is(table.tbody.children[i * 2].firstChild.children.length, 9 + 1, + `Correct rows in column ${i}`); + is(table.tbody.children[i * 2].firstChild.firstChild.value, + `Column ${i + 1}`, + "Correct column header value"); + } + + for (let i = 1; i < 10; i++) { + is(table.tbody.firstChild.firstChild.children[i].value, `id${i}`, + `Correct value in row ${i}`); + } +} + +/** + * Tests if the API exposed by TableWidget works properly + */ +function testAPI(doc, table) { + info("Testing TableWidget API"); + // Check if selectRow and selectedRow setter works as expected + // Nothing should be selected beforehand + ok(!doc.querySelector(".theme-selected"), "Nothing is selected"); + table.selectRow("id4"); + let node = doc.querySelector(".theme-selected"); + ok(!!node, "Somthing got selected"); + is(node.getAttribute("data-id"), "id4", "Correct node selected"); + + table.selectRow("id7"); + let node2 = doc.querySelector(".theme-selected"); + ok(!!node2, "Somthing is still selected"); + isnot(node, node2, "Newly selected node is different from previous"); + is(node2.getAttribute("data-id"), "id7", "Correct node selected"); + + // test if selectedIRow getter works + is(table.selectedRow.col1, "id7", "Correct result of selectedRow getter"); + + // test if isSelected works + ok(table.isSelected("id7"), "isSelected with column id works"); + ok(table.isSelected({ + col1: "id7", + col2: "value18", + col3: "value21", + col4: "value36", + somethingExtra: "Hello World!" + }), "isSelected with json works"); + + table.selectedRow = "id4"; + let node3 = doc.querySelector(".theme-selected"); + ok(!!node3, "Somthing is still selected"); + isnot(node2, node3, "Newly selected node is different from previous"); + is(node3, node, "First and third selected nodes should be same"); + is(node3.getAttribute("data-id"), "id4", "Correct node selected"); + + // test if selectedRow getter works + is(table.selectedRow.col1, "id4", "Correct result of selectedRow getter"); + + // test if clear selection works + table.clearSelection(); + ok(!doc.querySelector(".theme-selected"), + "Nothing selected after clear selection call"); + + // test if selectNextRow and selectPreviousRow work + table.selectedRow = "id7"; + ok(table.isSelected("id7"), "Correct row selected"); + table.selectNextRow(); + ok(table.isSelected("id8"), "Correct row selected after selectNextRow call"); + + table.selectNextRow(); + ok(table.isSelected("id9"), "Correct row selected after selectNextRow call"); + + table.selectNextRow(); + ok(table.isSelected("id1"), + "Properly cycled to first row after selectNextRow call on last row"); + + table.selectNextRow(); + ok(table.isSelected("id2"), "Correct row selected after selectNextRow call"); + + table.selectPreviousRow(); + ok(table.isSelected("id1"), + "Correct row selected after selectPreviousRow call"); + + table.selectPreviousRow(); + ok(table.isSelected("id9"), + "Properly cycled to last row after selectPreviousRow call on first row"); + + // test if remove works + ok(doc.querySelector("[data-id='id4']"), "id4 row exists before removal"); + table.remove("id4"); + ok(!doc.querySelector("[data-id='id4']"), + "id4 row does not exist after removal through id"); + + ok(doc.querySelector("[data-id='id6']"), "id6 row exists before removal"); + table.remove({ + col1: "id6", + col2: "value15", + col3: "value25", + col4: "value37" + }); + ok(!doc.querySelector("[data-id='id6']"), + "id6 row does not exist after removal through json"); + + table.push({ + col1: "id4", + col2: "value12", + col3: "value26", + col4: "value33" + }); + table.push({ + col1: "id6", + col2: "value15", + col3: "value25", + col4: "value37" + }); + + // test if selectedIndex getter setter works + table.selectedIndex = 2; + ok(table.isSelected("id3"), "Correct row selected by selectedIndex setter"); + + table.selectedIndex = 4; + ok(table.isSelected("id5"), "Correct row selected by selectedIndex setter"); + + table.selectRow("id8"); + is(table.selectedIndex, 7, "Correct value of selectedIndex getter"); + + // testing if clear works + table.clear(); + // double because splitters + is(table.tbody.children.length, 4 * 2, + "4 columns exist even after clear"); + for (let i = 0; i < 4; i++) { + is(table.tbody.children[i * 2].firstChild.children.length, 1, + `Only header in the column ${i} after clear call`); + is(table.tbody.children[i * 2].firstChild.firstChild.value, + `Column ${i + 1}`, + "Correct column header value"); + } + + // testing if setColumns work + table.setColumns({ + col1: "Foobar", + col2: "Testing" + }); + + // double because splitters + is(table.tbody.children.length, 2 * 2, + "2 columns exist after setColumn call"); + is(table.tbody.children[0].firstChild.firstChild.value, "Foobar", + "Correct column header value for first column"); + is(table.tbody.children[2].firstChild.firstChild.value, "Testing", + "Correct column header value for second column"); + + table.setColumns({ + col1: "Column 1", + col2: "Column 2", + col3: "Column 3", + col4: "Column 4" + }); + // double because splitters + is(table.tbody.children.length, 4 * 2, + "4 columns exist after second setColumn call"); + + populateTable(doc, table); + + // testing if update works + is(doc.querySelectorAll("[data-id='id4']")[1].value, "value12", + "Correct value before update"); + table.update({ + col1: "id4", + col2: "UPDATED", + col3: "value26", + col4: "value33" + }); + is(doc.querySelectorAll("[data-id='id4']")[1].value, "UPDATED", + "Correct value after update"); + + // testing if sorting works by calling it once on an already sorted column + // should sort descending + table.sortBy("col1"); + for (let i = 1; i < 10; i++) { + is(table.tbody.firstChild.firstChild.children[i].value, `id${10 - i}`, + `Correct value in row ${i} after descending sort by on col1`); + } + // Calling it on an unsorted column should sort by it in ascending manner + table.sortBy("col2"); + let cell = table.tbody.children[2].firstChild.children[2]; + checkAscendingOrder(cell); + + // Calling it again should sort by it in descending manner + table.sortBy("col2"); + cell = table.tbody.children[2].firstChild.lastChild.previousSibling; + checkDescendingOrder(cell); + + // Calling it again should sort by it in ascending manner + table.sortBy("col2"); + cell = table.tbody.children[2].firstChild.children[2]; + checkAscendingOrder(cell); + + table.clear(); + populateTable(doc, table); + + // testing if sorting works should sort by ascending manner + table.sortBy("col4"); + cell = table.tbody.children[6].firstChild.children[1]; + is(cell.textContent, "domnode", "DOMNode sorted correctly"); + checkAscendingOrder(cell.nextSibling); + + // Calling it again should sort it in descending order + table.sortBy("col4"); + cell = table.tbody.children[6].firstChild.children[9]; + is(cell.textContent, "domnode", "DOMNode sorted correctly"); + checkDescendingOrder(cell.previousSibling); +} + +function checkAscendingOrder(cell) { + while (cell) { + let currentCell = cell.value || cell.textContent; + let prevCell = cell.previousSibling.value || + cell.previousSibling.textContent; + ok(currentCell >= prevCell, "Sorting is in ascending order"); + cell = cell.nextSibling; + } +} + +function checkDescendingOrder(cell) { + while (cell != cell.parentNode.firstChild) { + let currentCell = cell.value || cell.textContent; + let nextCell = cell.nextSibling.value || cell.nextSibling.textContent; + ok(currentCell >= nextCell, "Sorting is in descending order"); + cell = cell.previousSibling; + } +} |