blob: c24e0f4da7d65cf2454f7cacf8c36ed35a804818 [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/tracing/ui/base/deep_utils.html">
<link rel="import" href="/tracing/ui/base/table.html">
<script>
'use strict';
tr.b.unittest.testSuite(function() {
var THIS_DOC = document.currentScript.ownerDocument;
var SelectionMode = tr.ui.b.TableFormat.SelectionMode;
var HighlightStyle = tr.ui.b.TableFormat.HighlightStyle;
var ColumnAlignment = tr.ui.b.TableFormat.ColumnAlignment;
function isSelected(element) {
if (!element.hasAttribute('selected'))
return false;
return element.getAttribute('selected') === 'true';
}
function simulateDoubleClick(element) {
// See https://developer.mozilla.org/en/docs/Web/API/MouseEvent#Example.
var event = new MouseEvent('dblclick', {
bubbles: true,
cancelable: true,
view: window
});
return element.dispatchEvent(event);
}
test('instantiateEmptyTable_withoutEmptyValue', function() {
var columns = [
{
title: 'First Column',
value: function(row) { return row.firstData; },
width: '300px'
},
{
title: 'Second Column',
value: function(row) { return row.secondData; }
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = [];
table.rebuild();
this.addHTMLOutput(table);
// Check that the width of the first column was set correctly (despite no
// body rows).
var firstColumnHeader = table.$.head.children[0].children[0];
assert.closeTo(firstColumnHeader.offsetWidth, 300, 20);
// Check that the first column has a non-empty header.
var firstColumnTitle = tr.b.findDeepElementMatchingPredicate(
firstColumnHeader, function(element) {
return Polymer.dom(element).textContent === 'First Column';
});
assert.isDefined(firstColumnTitle);
// Check that empty value was not appended.
assert.lengthOf(table.$.body.children, 0);
});
test('instantiateEmptyTable_withEmptyValue', function() {
var columns = [
{
title: 'First Column',
value: function(row) { return row.firstData; },
width: '300px'
},
{
title: 'Second Column',
value: function(row) { return row.secondData; }
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = [];
table.emptyValue = 'This table is left intentionally empty';
table.rebuild();
this.addHTMLOutput(table);
// Check that the width of the first column was set correctly (despite no
// body rows).
var firstColumnHeader = table.$.head.children[0].children[0];
assert.closeTo(firstColumnHeader.offsetWidth, 300, 20);
// Check that empty value was appended.
assert.lengthOf(table.$.body.children, 1);
});
test('instantiateNestedTableNoNests', function() {
var columns = [
{
title: 'First Column',
value: function(row) { return row.firstData; },
width: '200px'
},
{
title: 'Second Column',
value: function(row) { return row.secondData; }
}
];
var rows = [
{
firstData: 'A1',
secondData: 'A2'
},
{
firstData: 'B1',
secondData: 'B2'
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.emptyValue = 'THIS SHOULD NOT BE VISIBLE!!!';
table.rebuild();
this.addHTMLOutput(table);
// Check that empty value was not appended.
assert.lengthOf(table.$.body.children, 2);
});
test('sequentialRebuildsBehaveSanely', function() {
var columns = [
{
title: 'First Column',
value: function(row) { return row.firstData; },
width: '200px'
},
{
title: 'Second Column',
value: function(row) { return row.secondData; }
}
];
var rows = [
{
firstData: 'A1',
secondData: 'A2'
},
{
firstData: 'B1',
secondData: 'B2'
}
];
var footerRows = [
{
firstData: 'A1',
secondData: 'A2'
},
{
firstData: 'B1',
secondData: 'B2'
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.footerRows = footerRows;
table.rebuild();
table.rebuild();
assert.equal(table.$.body.children.length, 2);
assert.equal(table.$.foot.children.length, 2);
this.addHTMLOutput(table);
});
test('instantiateNestedTableWithNests', function() {
var columns = [
{
title: 'First Column',
value: function(row) { return row.firstData; },
width: '250px'
},
{
title: 'Second Column',
value: function(row) { return row.secondData; },
width: '50%'
}
];
var rows = [
{
firstData: 'A1',
secondData: 'A2',
subRows: [
{
firstData: 'Sub1 A1',
secondData: 'Sub1 A2'
},
{
firstData: 'Sub2 A1',
secondData: 'Sub2 A2',
subRows: [
{
firstData: 'SubSub1 A1',
secondData: 'SubSub1 A2'
},
{
firstData: 'SubSub2 A1',
secondData: 'SubSub2 A2'
}
]
},
{
firstData: 'Sub3 A1',
secondData: 'Sub3 A2'
}
]
},
{
firstData: 'B1',
secondData: 'B2'
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
});
test('instantiateSortingCallbacksWithNests', function() {
var table = document.createElement('tr-ui-b-table');
var columns = [
{
title: 'First Column',
value: function(row) { return row.firstData; },
width: '50%'
},
{
title: 'Second Column',
value: function(row) { return row.secondData; },
width: '250px',
cmp: function(rowA, rowB) {
return rowA.secondData.toString().localeCompare(
rowB.secondData.toString());
},
showExpandButtons: true
}
];
var rows = [
{
firstData: 'A1',
secondData: 'A2',
subRows: [
{
firstData: 'Sub1 A1',
secondData: 'Sub1 A2'
},
{
firstData: 'Sub2 A1',
secondData: 'Sub2 A2',
subRows: [
{
firstData: 'SubSub1 A1',
secondData: 'SubSub1 A2'
},
{
firstData: 'SubSub2 A1',
secondData: 'SubSub2 A2'
}
]
},
{
firstData: 'Sub3 A1',
secondData: 'Sub3 A2'
}
]
},
{
firstData: 'B1',
secondData: 'B2'
}
];
var footerRows = [
{
firstData: 'F1',
secondData: 'F2',
subRows: [
{
firstData: 'Sub1F1',
secondData: 'Sub1F2'
},
{
firstData: 'Sub2F1',
secondData: 'Sub2F2',
subRows: [
{
firstData: 'SubSub1F1',
secondData: 'SubSub1F2'
},
{
firstData: 'SubSub2F1',
secondData: 'SubSub2F2'
}
]
},
{
firstData: 'Sub3F1',
secondData: 'Sub3F2'
}
]
},
{
firstData: 'F\'1',
secondData: 'F\'2'
}
];
table.tableColumns = columns;
table.tableRows = rows;
table.footerRows = footerRows;
table.rebuild();
this.addHTMLOutput(table);
var button = THIS_DOC.createElement('button');
Polymer.dom(button).textContent = 'Sort By Col 0';
button.addEventListener('click', function() {
table.sortDescending = !table.sortDescending;
table.sortColumnIndex = 0;
});
table.rebuild();
this.addHTMLOutput(button);
});
test('instantiateNestedTableAlreadyExpanded', function() {
var columns = [
{
title: 'a',
value: function(row) { return row.a; },
width: '150px'
},
{
title: 'a',
value: function(row) { return row.b; },
width: '50%'
}
];
var rows = [
{
a: 'aToplevel',
b: 'bToplevel',
isExpanded: true,
subRows: [
{
a: 'a1',
b: 'b1'
}
]
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
var a1El = tr.b.findDeepElementMatchingPredicate(table, function(element) {
return Polymer.dom(element).textContent == 'a1';
});
assert.isDefined(a1El);
var bToplevelEl = tr.b.findDeepElementMatchingPredicate(
table,
function(element) {
return Polymer.dom(element).textContent == 'bToplevel';
});
assert.isDefined(bToplevelEl);
var expandButton = Polymer.dom(bToplevelEl.parentElement)
.querySelector('expand-button');
assert.isTrue(Polymer.dom(expandButton).classList.contains(
'button-expanded'));
});
test('subRowsThatAreRetrievedOnDemand', function() {
var columns = [
{
title: 'a',
value: function(row) { return row.a; },
width: '150px'
}
];
var rows = [
{
a: 'row1',
subRows: [
{
b: 'row1.1',
get subRows() {
throw new Error('Shold not be called');
}
}
]
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
});
test('instantiateTableWithHiddenHeader', function() {
var columns = [
{
title: 'a',
value: function(row) { return row.a; },
width: '150px'
},
{
title: 'a',
value: function(row) { return row.b; },
width: '50%'
}
];
var rows = [
{
a: 'aToplevel',
b: 'bToplevel'
}
];
var table = document.createElement('tr-ui-b-table');
table.showHeader = false;
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
var tHead = table.$.head;
assert.equal(table.$.head.children.length, 0);
assert.equal(0, tHead.getBoundingClientRect().height);
table.showHeader = true;
table.rebuild();
table.showHeader = false;
table.rebuild();
assert.equal(table.$.head.children.length, 0);
});
test('sortColumnsNotPossibleOnPercentSizedColumns', function() {
var columns = [
{
title: 'Title',
value: function(row) { return row.a; },
width: '150px'
},
{
title: 'Value',
value: function(row) { return row.b; },
width: '100%',
showExpandButtons: true
}
];
var table1 = document.createElement('tr-ui-b-table');
table1.showHeader = true;
assert.throws(function() {
table1.tableColumns = columns;
});
});
test('twoTablesFirstColumnMatching', function() {
var columns = [
{
title: 'Title',
value: function(row) { return row.a; },
width: '150px'
},
{
title: 'Value',
value: function(row) { return row.b; },
width: '100%'
}
];
var table1 = document.createElement('tr-ui-b-table');
table1.showHeader = true;
table1.tableColumns = columns;
table1.tableRows = [
{
a: 'first',
b: 'row'
}
];
table1.rebuild();
this.addHTMLOutput(table1);
var table2 = document.createElement('tr-ui-b-table');
table2.showHeader = false;
table2.tableColumns = columns;
table2.tableRows = [
{
a: 'second',
b: 'row'
}
];
table2.rebuild();
this.addHTMLOutput(table2);
var h1FirstCol = table1.$.head.children[0].children[0];
var h2FirstCol = table2.$.body.children[0].children[0];
assert.equal(h1FirstCol.getBoundingClientRect().width,
h2FirstCol.getBoundingClientRect().width);
});
test('programmaticSorting', function() {
var table = document.createElement('tr-ui-b-table');
var columns = [
{
title: 'Column',
value: function(row) { return row.value; },
cmp: function(rowA, rowB) {
return rowA.value.toString().localeCompare(
rowB.value.toString());
}
}
];
var rows = [
{
value: 'A1',
subRows: [
{
value: 'A1.1'
},
{
value: 'A1.2',
subRows: [
{
value: 'A1.2.1'
},
{
value: 'A1.2.2'
}
]
},
{
value: 'A1.3'
}
]
},
{
value: 'A2'
}
];
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
table.sortDescending = true;
table.sortColumnIndex = 0;
table.rebuild();
var r0 = table.$.body.children[0];
assert.equal(r0.rowInfo.userRow, rows[1]);
var r1 = table.$.body.children[1];
assert.equal(r1.rowInfo.userRow, rows[0]);
});
test('sortDispatchesEvent', function() {
var table = document.createElement('tr-ui-b-table');
var columns = [
{
title: 'Column 0',
value: function(row) { return row.value0; },
cmp: function(rowA, rowB) { return rowA.value0 - rowB.value0; }
},
{
title: 'Column 1',
value: function(row) { return row.value1; },
cmp: function(rowA, rowB) { return rowA.value1 - rowB.value1; }
}
];
var sortColumnIndex = undefined;
var sortDescending = undefined;
var numListenerCalls = 0;
table.tableColumns = columns;
table.addEventListener('sort-column-changed', function(e) {
sortColumnIndex = e.sortColumnIndex;
sortDescending = e.sortDescending;
numListenerCalls++;
});
table.rebuild();
table.sortColumnIndex = 0;
assert.equal(sortColumnIndex, 0);
assert.equal(numListenerCalls, 1);
table.sortDescending = true;
assert.equal(sortColumnIndex, 0);
assert.isTrue(sortDescending);
assert.equal(numListenerCalls, 2);
table.sortColumnIndex = 1;
table.sortDescending = false;
assert.equal(sortColumnIndex, 1);
assert.isFalse(sortDescending);
assert.equal(numListenerCalls, 4);
table.sortColumnIndex = undefined;
assert.equal(sortColumnIndex, undefined);
assert.equal(numListenerCalls, 5);
});
test('sortingAfterExpand', function() {
var table = document.createElement('tr-ui-b-table');
var columns = [
{
title: 'Column',
value: function(row) { return row.value; },
cmp: function(rowA, rowB) {
return rowA.value.toString().localeCompare(
rowB.value.toString());
}
}
];
var rows = [
{
value: 'A1',
isExpanded: true,
subRows: [
{
value: 'A1.1'
},
{
value: 'A1.2',
subRows: [
{
value: 'A1.2.1'
},
{
value: 'A1.2.2'
}
]
},
{
value: 'A1.3'
}
]
},
{
value: 'A2'
}
];
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
table.sortDescending = true;
table.sortColumnIndex = 0;
table.rebuild();
var r0 = table.$.body.children[0];
assert.equal(r0.rowInfo.userRow, rows[1]);
var r1 = table.$.body.children[1];
assert.equal(r1.rowInfo.userRow, rows[0]);
var r2 = table.$.body.children[2];
assert.equal(r2.rowInfo.userRow, rows[0].subRows[2]);
assert.isFalse(r0.hasAttribute('tabIndex'));
});
function createSimpleOneColumnNestedTable() {
var table = document.createElement('tr-ui-b-table');
var columns = [
{
title: 'Column',
value: function(row) { return row.value; },
cmp: function(rowA, rowB) {
return rowA.value.toString().localeCompare(
rowB.value.toString());
}
}
];
var rows = [
{
value: 'A1',
subRows: [
{
value: 'A1.1'
},
{
value: 'A1.2',
subRows: [
{
value: 'A1.2.1'
},
{
value: 'A1.2.2'
}
]
},
{
value: 'A1.3'
}
]
},
{
value: 'A2'
}
];
table.tableColumns = columns;
table.tableRows = rows;
return table;
}
test('expandAfterRebuild', function() {
var table = createSimpleOneColumnNestedTable();
table.rebuild();
var rows = table.tableRows;
this.addHTMLOutput(table);
table.rebuild();
assert.isFalse(table.getExpandedForTableRow(rows[0]));
table.setExpandedForTableRow(rows[0], true);
assert.isTrue(table.getExpandedForTableRow(rows[0]));
var r1 = table.$.body.children[1];
assert.equal(r1.rowInfo.userRow, rows[0].subRows[0]);
});
test('tableSelection', function() {
var table = createSimpleOneColumnNestedTable();
var rows = table.tableRows;
table.selectionMode = SelectionMode.ROW;
table.selectedTableRow = rows[0];
table.setExpandedForTableRow(rows[0], true);
table.selectedTableRow = rows[0].subRows[1];
assert.equal(table.selectedTableRow, rows[0].subRows[1]);
table.setExpandedForTableRow(rows[0], false);
assert.equal(table.selectedTableRow, rows[0]);
table.selectionMode = SelectionMode.NONE;
assert.equal(table.selectedTableRow, undefined);
table.selectionMode = SelectionMode.ROW;
table.setExpandedForTableRow(rows[0].subRows[1], true);
this.addHTMLOutput(table);
var r0 = table.$.body.children[0];
assert.isTrue(r0.hasAttribute('tabIndex'));
});
test('keyMovement', function() {
var table = createSimpleOneColumnNestedTable();
table.selectionMode = SelectionMode.ROW;
this.addHTMLOutput(table);
var rows = table.tableRows;
table.selectedTableRow = rows[0];
table.performKeyCommand_('ARROW_DOWN');
assert.equal(table.selectedTableRow, rows[1]);
table.performKeyCommand_('ARROW_UP');
assert.equal(table.selectedTableRow, rows[0]);
// Enter on collapsed row should expand.
table.selectedTableRow = rows[0];
table.performKeyCommand_('SPACE');
assert.equal(table.selectedTableRow, rows[0]);
assert.isTrue(table.getExpandedForTableRow(rows[0]));
table.performKeyCommand_('SPACE');
assert.isFalse(table.getExpandedForTableRow(rows[0]));
// Arrow right on collapsed row should expand.
table.selectedTableRow = rows[0];
table.performKeyCommand_('ARROW_RIGHT');
assert.equal(table.selectedTableRow, rows[0].subRows[0]);
assert.isTrue(table.getExpandedForTableRow(rows[0]));
table.performKeyCommand_('ARROW_DOWN');
assert.equal(table.selectedTableRow, rows[0].subRows[1]);
// Arrow left on collapsed item should select parent.
table.performKeyCommand_('ARROW_LEFT');
assert.equal(table.selectedTableRow, rows[0]);
assert.isTrue(table.getExpandedForTableRow(rows[0]));
// Arrow left on parent should collapse its children.
table.performKeyCommand_('ARROW_LEFT');
assert.isFalse(table.getExpandedForTableRow(rows[0]));
// Arrow right on expanded row should select first child.
table.selectedTableRow = rows[0];
table.setExpandedForTableRow(rows[0], true);
table.performKeyCommand_('ARROW_RIGHT');
assert.equal(table.selectedTableRow, rows[0].subRows[0]);
// Arrow right on a non-expandable row should do nothing.
table.selectedTableRow = rows[1];
assert.equal(table.selectedTableRow, rows[1]);
table.performKeyCommand_('ARROW_RIGHT');
assert.equal(table.selectedTableRow, rows[1]);
assert.isFalse(table.getExpandedForTableRow(rows[1]));
});
test('RightArrowKeyWhenTableSorted', function() {
var table = createSimpleOneColumnNestedTable();
table.selectionMode = SelectionMode.ROW;
this.addHTMLOutput(table);
table.sortDescending = true;
table.sortColumnIndex = 0;
table.rebuild();
var rows = table.tableRows;
// Arrow right should select the first child showing up on the viewer,
// rather than first child in sub rows since sorted.
table.selectedTableRow = rows[0];
table.performKeyCommand_('ARROW_RIGHT');
assert.equal(table.selectedTableRow, rows[0].subRows[2]);
});
test('reduceNumberOfColumnsAfterRebuild', function() {
// Create a table with two columns.
var table = document.createElement('tr-ui-b-table');
table.tableColumns = [
{
title: 'First Column',
value: function(row) { return row.firstData; },
width: '100px'
},
{
title: 'Second Column',
value: function(row) { return row.secondData; },
width: '100px'
}
];
// Build the table.
table.rebuild();
// Check that reducing the number of columns doesn't throw an exception.
table.tableColumns = [
{
title: 'First Column',
value: function(row) { return row.firstData; },
width: '200px'
}
];
});
test('rowHighlightDark', function() {
var columns = [
{
title: 'Title',
value: function(row) { return row.a; },
width: '150px',
supportsCellSelection: false
},
{
title: 'Col1',
value: function(row) { return row.b; },
width: '33%'
},
{
title: 'Col2',
value: function(row) { return row.b * 2; },
width: '33%'
},
{
title: 'Col3',
value: function(row) { return row.b * 3; },
width: '33%'
}
];
var table = document.createElement('tr-ui-b-table');
table.showHeader = true;
table.rowHighlightStyle = HighlightStyle.DARK;
table.tableColumns = columns;
table.tableRows = [
{
a: 'first',
b: '1'
},
{
a: 'second',
b: '2'
}
];
table.rebuild();
this.addHTMLOutput(table);
});
test('cellHighlightLight', function() {
var columns = [
{
title: 'Title',
value: function(row) { return row.a; },
width: '150px',
supportsCellSelection: false
},
{
title: 'Col1',
value: function(row) { return row.b; },
width: '33%'
},
{
title: 'Col2',
value: function(row) { return row.b * 2; },
width: '33%'
},
{
title: 'Col3',
value: function(row) { return row.b * 3; },
width: '33%'
}
];
var table = document.createElement('tr-ui-b-table');
table.showHeader = true;
table.cellHighlightStyle = HighlightStyle.LIGHT;
table.tableColumns = columns;
table.tableRows = [
{
a: 'first',
b: '1'
},
{
a: 'second',
b: '2'
}
];
table.rebuild();
this.addHTMLOutput(table);
});
test('cellSelectionBasic', function() {
var columns = [
{
title: 'Title',
value: function(row) { return row.a; },
width: '150px',
supportsCellSelection: false
},
{
title: 'Col1',
value: function(row) { return row.b; },
width: '33%'
},
{
title: 'Col2',
value: function(row) { return row.b * 2; },
width: '33%'
},
{
title: 'Col3',
value: function(row) { return row.b * 3; },
width: '33%'
}
];
var table = document.createElement('tr-ui-b-table');
table.showHeader = true;
table.selectionMode = SelectionMode.CELL;
table.rowHighlightStyle = HighlightStyle.NONE;
table.tableColumns = columns;
table.tableRows = [
{
a: 'first',
b: '1'
},
{
a: 'second',
b: '2'
}
];
table.rebuild();
this.addHTMLOutput(table);
table.selectedTableRow = table.tableRows[0];
assert.equal(table.selectedColumnIndex, 1);
var selectedCell = table.selectedCell;
assert.strictEqual(selectedCell.row, table.tableRows[0]);
assert.strictEqual(selectedCell.column, columns[1]);
assert.strictEqual(selectedCell.value, '1');
table.performKeyCommand_('ARROW_DOWN');
table.performKeyCommand_('ARROW_RIGHT');
table.performKeyCommand_('ARROW_RIGHT');
table.performKeyCommand_('ARROW_LEFT');
assert.equal(table.selectedTableRow, table.tableRows[1]);
assert.equal(table.selectedColumnIndex, 2);
selectedCell = table.selectedCell;
assert.strictEqual(selectedCell.row, table.tableRows[1]);
assert.strictEqual(selectedCell.column, columns[2]);
assert.strictEqual(selectedCell.value, 4);
table.selectedTableRow = undefined;
assert.isUndefined(table.selectedTableRow);
assert.isUndefined(table.selectedColumnIndex);
assert.isUndefined(table.selectedColumnIndex);
assert.isUndefined(table.selectedCell);
});
test('cellSelectionNested', function() {
var columns = [
{
title: 'Title',
value: function(row) { return row.a; },
width: '150px',
supportsCellSelection: false
},
{
title: 'Value',
value: function(row) { return row.b; },
width: '150px'
}
];
var rows = [
{
a: 'parent',
b: '1',
subRows: [
{
a: 'child',
b: '2'
}
]
}
];
var table = document.createElement('tr-ui-b-table');
table.showHeader = true;
table.selectionMode = SelectionMode.CELL;
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
// Expand the parent row.
table.setExpandedForTableRow(rows[0], true);
// Select the second cell in the child row.
table.selectedTableRow = rows[0].subRows[0];
assert.isFalse(isSelected(table.$.body.children[0]));
assert.isFalse(isSelected(table.$.body.children[0].children[1]));
assert.isTrue(isSelected(table.$.body.children[1]));
assert.isTrue(isSelected(table.$.body.children[1].children[1]));
// Fold the parent row. The second cell in the parent row should be
// automatically selected.
table.setExpandedForTableRow(rows[0], false);
assert.isTrue(isSelected(table.$.body.children[0]));
assert.isTrue(isSelected(table.$.body.children[0].children[1]));
// Expand the parent row again. Only the second cell of the parent row
// should still be selected.
table.setExpandedForTableRow(rows[0], true);
assert.isTrue(isSelected(table.$.body.children[0]));
assert.isTrue(isSelected(table.$.body.children[0].children[1]));
assert.isFalse(isSelected(table.$.body.children[1]));
assert.isFalse(isSelected(table.$.body.children[1].children[1]));
});
test('resolvedHighlightStyle', function() {
var table = document.createElement('tr-ui-b-table');
// Undefined selection mode.
assert.strictEqual(table.resolvedRowHighlightStyle, HighlightStyle.NONE);
assert.strictEqual(table.resolvedCellHighlightStyle, HighlightStyle.NONE);
// Row selection mode.
table.selectionMode = SelectionMode.ROW;
assert.strictEqual(table.resolvedRowHighlightStyle, HighlightStyle.DARK);
assert.strictEqual(table.resolvedCellHighlightStyle, HighlightStyle.NONE);
// Cell selection mode.
table.selectionMode = SelectionMode.CELL;
assert.strictEqual(table.resolvedRowHighlightStyle, HighlightStyle.LIGHT);
assert.strictEqual(table.resolvedCellHighlightStyle, HighlightStyle.DARK);
// Explicit row highlight style.
table.rowHighlightStyle = HighlightStyle.NONE;
assert.strictEqual(table.resolvedRowHighlightStyle, HighlightStyle.NONE);
assert.strictEqual(table.resolvedCellHighlightStyle, HighlightStyle.DARK);
// Explicit row and cell highlight styles.
table.cellHighlightStyle = HighlightStyle.LIGHT;
assert.strictEqual(table.resolvedRowHighlightStyle, HighlightStyle.NONE);
assert.strictEqual(table.resolvedCellHighlightStyle, HighlightStyle.LIGHT);
// Back to default highlight styles.
table.cellHighlightStyle = HighlightStyle.DEFAULT;
table.rowHighlightStyle = HighlightStyle.DEFAULT;
assert.strictEqual(table.resolvedRowHighlightStyle, HighlightStyle.LIGHT);
assert.strictEqual(table.resolvedCellHighlightStyle, HighlightStyle.DARK);
});
test('headersWithHtmlElements', function() {
var firstColumnTitle = document.createTextNode('First Column');
var secondColumnTitle = document.createElement('span');
secondColumnTitle.innerText = 'Second Column';
secondColumnTitle.style.color = 'blue';
var columns = [
{
title: firstColumnTitle,
value: function(row) { return row.firstData; },
width: '200px'
},
{
title: secondColumnTitle,
value: function(row) { return row.secondData; }
}
];
var rows = [
{
firstData: 'A1',
secondData: 'A2'
},
{
firstData: 'B1',
secondData: 'B2'
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
var firstColumnHeader = table.$.head.children[0].children[0].children[0];
var secondColumnHeader = table.$.head.children[0].children[1].children[0];
assert.equal(Polymer.dom(firstColumnHeader.cellTitle).textContent,
'First Column');
assert.equal(Polymer.dom(secondColumnHeader.cellTitle).textContent,
'Second Column');
});
test('align', function() {
var columns = [
{
title: 'a',
align: ColumnAlignment.RIGHT,
value: function(row) {
return row.a;
}
}
];
var rows = [{a: 1}, {a: 'long-row-so-that-alignment-would-be-visible'}];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
assert.strictEqual(
table.$.body.children[0].children[0].style.textAlign, 'right');
});
test('subRowsPropertyName', function() {
var columns = [
{
title: 'a',
value: function(row) {
return row.a;
}
}
];
var rows = [
{
a: 1,
isExpanded: true,
children: [
{a: 2}
]
}
];
var table = document.createElement('tr-ui-b-table');
table.subRowsPropertyName = 'children';
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
assert.equal(
2, Polymer.dom(table.$.body.children[1].children[0]).textContent);
});
test('shouldNotRenderUndefined', function() {
var columns = [
{
title: 'Column',
value: function(row) { return row.firstData; }
}
];
var rows = [
{
firstData: undefined,
secondData: 'A2'
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
// check that we don't have 'undefined' anywhere
assert.isTrue(Polymer.dom(table.$.body).innerHTML.indexOf('undefined') < 0);
});
test('customizeTableRowCallback', function() {
var columns = [
{
title: 'Column',
value: function(row) { return row.data; }
}
];
var rows = [
{
data: 'data'
}
];
var table = document.createElement('tr-ui-b-table');
var callbackCalled = false;
table.tableColumns = columns;
table.tableRows = rows;
table.customizeTableRowCallback = function(userRow, trElement) {
callbackCalled = (userRow === rows[0]);
};
table.rebuild();
assert.isTrue(callbackCalled);
this.addHTMLOutput(table);
// The callback can also be set after the table is first built.
table.customizeTableRowCallback = function(userRow, trElement) {
callbackCalled = (userRow === rows[0]);
};
// Setting the customize callback should set the body dirty.
assert.isTrue(table.bodyDirty_);
callbackCalled = false;
// Don't bother waiting for the timeout.
table.rebuild();
assert.isTrue(callbackCalled);
});
test('selectionEdgeCases', function() {
var table = document.createElement('tr-ui-b-table');
table.tableColumns = [
{
title: 'Column',
value: function(row) { return row.data; },
supportsCellSelection: false
}
];
table.tableRows = [{ data: 'body row' }];
table.footerRows = [{ data: 'footer row' }];
table.selectionMode = SelectionMode.ROW;
this.addHTMLOutput(table);
// Clicking on the body row should *not* throw an exception (despite the
// column not supporting cell selection).
table.$.body.children[0].children[0].click();
// Clicking on the footer row should *not* throw an exception (despite
// footer rows not being selectable in general).
table.$.foot.children[0].children[0].click();
});
test('defaultExpansionStateCallback', function() {
var columns = [
{
title: 'Name',
value: function(row) { return row.name; }
},
{
title: 'Value',
value: function(row) { return row.value; }
}
];
var rows = [
{
name: 'A',
value: 10,
subRows: [
{
name: 'B',
value: 8,
subRows: [
{
name: 'C',
value: 4
},
{
name: 'D',
value: 4
}
]
},
{
name: 'E',
value: 2,
subRows: [
{
name: 'F',
value: 1
},
{
name: 'G',
value: 1
}
]
}
]
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
var cRow = tr.b.findDeepElementMatchingPredicate(
table, function(element) {
return Polymer.dom(element).textContent === 'C';
});
assert.equal(cRow, undefined);
var callbackCalled = false;
table.defaultExpansionStateCallback = function(row, parentRow) {
callbackCalled = true;
if (parentRow === undefined)
return true;
if (row.value >= (parentRow.value * 0.8))
return true;
return false;
};
// Setting the callback should set the body dirty.
assert.isTrue(table.bodyDirty_);
assert.isFalse(callbackCalled);
table.rebuild();
assert.isTrue(callbackCalled);
cRow = tr.b.findDeepElementMatchingPredicate(table, function(element) {
return Polymer.dom(element).textContent === 'C';
});
assert.isDefined(cRow);
});
test('sortExpanded', function() {
var columns = [
{
title: 'Name',
value: function(row) { return row.name; }
},
{
title: 'Value',
value: function(row) { return row.value; },
cmp: function(x, y) { return x.value - y.value; }
}
];
var rows = [
{
name: 'A',
value: 10,
subRows: [
{
name: 'B',
value: 8
},
{
name: 'C',
value: 4
},
]
}
];
var table = document.createElement('tr-ui-b-table');
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
function isB(row) {
return row.textContent === 'B';
}
// Check that 'A' row is not expanded.
assert.isUndefined(tr.b.findDeepElementMatchingPredicate(table, isB));
// Expand 'A' row.
table.setExpandedForTableRow(rows[0], true);
// Check that 'A' is expanded.
assert.isDefined(tr.b.findDeepElementMatchingPredicate(table, isB));
// Sort by value.
table.sortColumnIndex = 1;
// Rebuild the table synchronously instead of waiting for scheduleRebuild_'s
// setTimeout(0).
table.rebuild();
// Check that 'A' is still expanded.
assert.isDefined(tr.b.findDeepElementMatchingPredicate(table, isB));
});
test('userCanModifySortOrder', function() {
var table = document.createElement('tr-ui-b-table');
table.tableColumns = [
{
title: 'Name',
value: row => row.name
},
{
title: 'colA',
value: row => row.a,
cmp: (rowA, rowB) => rowA.a - rowB.a
},
{
title: 'colB',
value: row => row.b,
cmp: (rowA, rowB) => rowA.b - rowB.b
}
];
table.tableRows = [
{name: 'A', a: 42, b: 0},
{name: 'B', a: 89, b: 100},
{name: 'C', a: 65, b: -273.15}
];
table.userCanModifySortOrder = false;
table.sortColumnIndex = 2;
table.sortDescending = true;
table.rebuild();
this.addHTMLOutput(table);
var toggleButton = document.createElement('button');
Polymer.dom(toggleButton).textContent =
'Toggle table.userCanModifySortOrder';
toggleButton.addEventListener('click', function() {
table.userCanModifySortOrder = !table.userCanModifySortOrder;
});
this.addHTMLOutput(toggleButton);
var unsetButton = document.createElement('button');
Polymer.dom(unsetButton).textContent = 'Unset sort order';
unsetButton.addEventListener('click', function() {
table.sortColumnIndex = undefined;
});
this.addHTMLOutput(unsetButton);
});
test('columnSelection', function() {
var table = document.createElement('tr-ui-b-table');
table.tableColumns = [
{
title: 'Name',
value: (row) => row.name
},
{
title: 'colA',
selectable: true,
value: (row) => row.a,
cmp: (rowA, rowB) => rowA.a - rowB.a
},
{
title: 'colB',
selectable: true,
value: (row) => row.b,
cmp: (rowA, rowB) => rowA.b - rowB.b
}
];
table.tableRows = [
{name: 'foo', a: 42, b: -42},
{name: 'bar', a: 57, b: 133}
];
table.rebuild();
table.selectionMode = SelectionMode.CELL;
this.addHTMLOutput(table);
table.selectedTableColumnIndex = 1;
var cols = tr.b.findDeepElementMatchingPredicate(table,
e => e.tagName === 'COLGROUP').children;
assert.isNull(cols[0].getAttribute('selected'));
assert.strictEqual(cols[1].getAttribute('selected'), 'true');
assert.isNull(cols[2].getAttribute('selected'));
assert.strictEqual(1, table.selectedTableColumnIndex);
table.selectedTableColumnIndex = undefined;
cols = tr.b.findDeepElementMatchingPredicate(table,
e => e.tagName === 'COLGROUP').children;
assert.isNull(cols[0].getAttribute('selected'));
assert.isNull(cols[1].getAttribute('selected'));
assert.isNull(cols[2].getAttribute('selected'));
assert.isUndefined(table.selectedTableColumnIndex);
table.selectedTableColumnIndex = 2;
cols = tr.b.findDeepElementMatchingPredicate(table,
e => e.tagName === 'COLGROUP').children;
assert.isNull(cols[0].getAttribute('selected'));
assert.isNull(cols[1].getAttribute('selected'));
assert.strictEqual(cols[2].getAttribute('selected'), 'true');
assert.strictEqual(2, table.selectedTableColumnIndex);
});
test('stepInto', function() {
var columns = [
{
title: 'Title',
value: function(row) { return row.a; },
width: '150px',
supportsCellSelection: false
},
{
title: 'Col1',
value: function(row) { return row.b; },
width: '33%'
},
{
title: 'Col2',
value: function(row) { return row.b * 2; },
width: '33%'
},
{
title: 'Col3',
value: function(row) { return row.b * 3; },
width: '33%'
}
];
var rows = [
{
a: 'first',
b: '1'
},
{
a: 'second',
b: '2'
}
];
var table = document.createElement('tr-ui-b-table');
var firedStepIntoEvents = [];
table.addEventListener('step-into', e => firedStepIntoEvents.push(e));
table.cellHighlightStyle = HighlightStyle.DARK;
table.tableColumns = columns;
table.tableRows = rows;
table.rebuild();
this.addHTMLOutput(table);
assert.lengthOf(firedStepIntoEvents, 0);
// Double click.
simulateDoubleClick(table.$.body.children[0].children[1]);
assert.lengthOf(firedStepIntoEvents, 1);
assert.strictEqual(firedStepIntoEvents[0].tableRow, rows[0]);
assert.strictEqual(firedStepIntoEvents[0].tableColumn, columns[1]);
assert.strictEqual(firedStepIntoEvents[0].columnIndex, 1);
simulateDoubleClick(table.$.body.children[1].children[3]);
assert.lengthOf(firedStepIntoEvents, 2);
assert.strictEqual(firedStepIntoEvents[1].tableRow, rows[1]);
assert.strictEqual(firedStepIntoEvents[1].tableColumn, columns[3]);
assert.strictEqual(firedStepIntoEvents[1].columnIndex, 3);
// Shift+Enter in cell selection mode.
table.selectionMode = SelectionMode.CELL;
table.selectedTableRow = rows[0];
table.selectedColumnIndex = 2;
table.performKeyCommand_('ENTER');
assert.lengthOf(firedStepIntoEvents, 3);
assert.strictEqual(firedStepIntoEvents[2].tableRow, rows[0]);
assert.strictEqual(firedStepIntoEvents[2].tableColumn, columns[2]);
assert.strictEqual(firedStepIntoEvents[2].columnIndex, 2);
// Shift+Enter in row selection mode.
table.selectionMode = SelectionMode.ROW;
table.selectedTableRow = rows[1];
table.performKeyCommand_('ENTER');
assert.lengthOf(firedStepIntoEvents, 4);
assert.strictEqual(firedStepIntoEvents[3].tableRow, rows[1]);
assert.isUndefined(firedStepIntoEvents[3].tableColumn);
assert.isUndefined(firedStepIntoEvents[3].columnIndex);
});
});
</script>