blob: 0c2ab37b74918004f6a37c3839d5b579e3143e2c [file] [log] [blame]
Chris Craikb122baf2015-03-05 13:58:42 -08001<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/base/deep_utils.html">
9<link rel="import" href="/core/analysis/table_builder.html">
10
11<script>
12'use strict';
13
14tv.b.unittest.testSuite(function() {
15 var THIS_DOC = document._currentScript.ownerDocument;
16
Chris Craik44c28202015-05-12 17:25:16 -070017 test('instantiateEmptyTable_withoutEmptyValue', function() {
18 var columns = [
19 {
20 title: 'First Column',
21 value: function(row) { return row.firstData; },
22 width: '300px'
23 },
24 {
25 title: 'Second Column',
26 value: function(row) { return row.secondData; }
27 }
28 ];
29
30 var table = document.createElement('tracing-analysis-nested-table');
31 table.tableColumns = columns;
32 table.tableRows = [];
33 table.rebuild();
34
35 this.addHTMLOutput(table);
36
37 // Check that the width of the first column was set correctly (despite no
38 // body rows).
39 var firstColumnHeader = table.$.head.children[0].children[0];
40 assert.closeTo(firstColumnHeader.offsetWidth, 300, 20);
41
42 // Check that empty value was not appended.
43 assert.lengthOf(table.$.body.children, 0);
44 });
45
46 test('instantiateEmptyTable_withEmptyValue', function() {
47 var columns = [
48 {
49 title: 'First Column',
50 value: function(row) { return row.firstData; },
51 width: '300px'
52 },
53 {
54 title: 'Second Column',
55 value: function(row) { return row.secondData; }
56 }
57 ];
58
59 var table = document.createElement('tracing-analysis-nested-table');
60 table.tableColumns = columns;
61 table.tableRows = [];
62 table.emptyValue = 'This table is left intentionally empty';
63 table.rebuild();
64
65 this.addHTMLOutput(table);
66
67 // Check that the width of the first column was set correctly (despite no
68 // body rows).
69 var firstColumnHeader = table.$.head.children[0].children[0];
70 assert.closeTo(firstColumnHeader.offsetWidth, 300, 20);
71
72 // Check that empty value was appended.
73 assert.lengthOf(table.$.body.children, 1);
74 });
75
Chris Craikb122baf2015-03-05 13:58:42 -080076 test('instantiateNestedTableNoNests', function() {
77 var columns = [
78 {
79 title: 'First Column',
80 value: function(row) { return row.firstData; },
81 width: '200px'
82 },
83 {
84 title: 'Second Column',
85 value: function(row) { return row.secondData; }
86 }
87 ];
88
89 var rows = [
90 {
91 firstData: 'A1',
92 secondData: 'A2'
93 },
94 {
95 firstData: 'B1',
96 secondData: 'B2'
97 }
98 ];
99
100 var table = document.createElement('tracing-analysis-nested-table');
101 table.tableColumns = columns;
102 table.tableRows = rows;
Chris Craik44c28202015-05-12 17:25:16 -0700103 table.emptyValue = 'THIS SHOULD NOT BE VISIBLE!!!';
Chris Craikb122baf2015-03-05 13:58:42 -0800104 table.rebuild();
105
106 this.addHTMLOutput(table);
Chris Craik44c28202015-05-12 17:25:16 -0700107
108 // Check that empty value was not appended.
109 assert.lengthOf(table.$.body.children, 2);
Chris Craikb122baf2015-03-05 13:58:42 -0800110 });
111
Chris Craik19832152015-04-16 15:43:38 -0700112 test('sequentialRebuildsBehaveSanely', function() {
113 var columns = [
114 {
115 title: 'First Column',
116 value: function(row) { return row.firstData; },
117 width: '200px'
118 },
119 {
120 title: 'Second Column',
121 value: function(row) { return row.secondData; }
122 }
123 ];
124
125 var rows = [
126 {
127 firstData: 'A1',
128 secondData: 'A2'
129 },
130 {
131 firstData: 'B1',
132 secondData: 'B2'
133 }
134 ];
135 var footerRows = [
136 {
137 firstData: 'A1',
138 secondData: 'A2'
139 },
140 {
141 firstData: 'B1',
142 secondData: 'B2'
143 }
144 ];
145
146 var table = document.createElement('tracing-analysis-nested-table');
147 table.tableColumns = columns;
148 table.tableRows = rows;
149 table.footerRows = footerRows;
150 table.rebuild();
151 table.rebuild();
152 assert.equal(table.$.body.children.length, 2);
153 assert.equal(table.$.foot.children.length, 2);
154
155 this.addHTMLOutput(table);
156 });
157
Chris Craikb122baf2015-03-05 13:58:42 -0800158 test('instantiateNestedTableWithNests', function() {
159 var columns = [
160 {
161 title: 'First Column',
162 value: function(row) { return row.firstData; },
163 width: '250px'
164 },
165 {
166 title: 'Second Column',
167 value: function(row) { return row.secondData; },
168 width: '50%'
169 }
170 ];
171
172 var rows = [
173 {
174 firstData: 'A1',
175 secondData: 'A2',
176 subRows: [
177 {
178 firstData: 'Sub1 A1',
179 secondData: 'Sub1 A2'
180 },
181 {
182 firstData: 'Sub2 A1',
183 secondData: 'Sub2 A2',
184 subRows: [
185 {
186 firstData: 'SubSub1 A1',
187 secondData: 'SubSub1 A2'
188 },
189 {
190 firstData: 'SubSub2 A1',
191 secondData: 'SubSub2 A2'
192 }
193 ]
194 },
195 {
196 firstData: 'Sub3 A1',
197 secondData: 'Sub3 A2'
198 }
199 ]
200 },
201 {
202 firstData: 'B1',
203 secondData: 'B2'
204 }
205 ];
206
207 var table = document.createElement('tracing-analysis-nested-table');
208 table.tableColumns = columns;
209 table.tableRows = rows;
210 table.rebuild();
211
212 this.addHTMLOutput(table);
213 });
214
215 test('instantiateSortingCallbacksWithNests', function() {
216 var table = document.createElement('tracing-analysis-nested-table');
217
218 var columns = [
219 {
220 title: 'First Column',
221 value: function(row) { return row.firstData; },
222 width: '50%'
223 },
224 {
225 title: 'Second Column',
226 value: function(row) { return row.secondData; },
227 width: '250px',
228 cmp: function(rowA, rowB) {
229 return rowA.secondData.toString().localeCompare(
230 rowB.secondData.toString());
231 },
232 showExpandButtons: true
233 }
234 ];
235
236 var rows = [
237 {
238 firstData: 'A1',
239 secondData: 'A2',
240 subRows: [
241 {
242 firstData: 'Sub1 A1',
243 secondData: 'Sub1 A2'
244 },
245 {
246 firstData: 'Sub2 A1',
247 secondData: 'Sub2 A2',
248 subRows: [
249 {
250 firstData: 'SubSub1 A1',
251 secondData: 'SubSub1 A2'
252 },
253 {
254 firstData: 'SubSub2 A1',
255 secondData: 'SubSub2 A2'
256 }
257 ]
258 },
259 {
260 firstData: 'Sub3 A1',
261 secondData: 'Sub3 A2'
262 }
263 ]
264 },
265 {
266 firstData: 'B1',
267 secondData: 'B2'
268 }
269 ];
270
271 var footerRows = [
272 {
273 firstData: 'F1',
274 secondData: 'F2',
275 subRows: [
276 {
277 firstData: 'Sub1F1',
278 secondData: 'Sub1F2'
279 },
280 {
281 firstData: 'Sub2F1',
282 secondData: 'Sub2F2',
283 subRows: [
284 {
285 firstData: 'SubSub1F1',
286 secondData: 'SubSub1F2'
287 },
288 {
289 firstData: 'SubSub2F1',
290 secondData: 'SubSub2F2'
291 }
292 ]
293 },
294 {
295 firstData: 'Sub3F1',
296 secondData: 'Sub3F2'
297 }
298 ]
299 },
300 {
301 firstData: 'F\'1',
302 secondData: 'F\'2'
303 }
304
305 ];
306
307 table.tableColumns = columns;
308 table.tableRows = rows;
309 table.footerRows = footerRows;
310 table.rebuild();
311
312 this.addHTMLOutput(table);
313
314 var button = THIS_DOC.createElement('button');
315 button.textContent = 'Sort By Col 0';
316 button.addEventListener('click', function() {
317 table.sortDescending = !table.sortDescending;
318 table.sortColumnIndex = 0;
319 });
320 table.rebuild();
321
322 this.addHTMLOutput(button);
323 });
324
325
326 test('instantiateNestedTableAlreadyExpanded', function() {
327 var columns = [
328 {
329 title: 'a',
330 value: function(row) { return row.a; },
331 width: '150px'
332 },
333 {
334 title: 'a',
335 value: function(row) { return row.b; },
336 width: '50%'
337 }
338 ];
339
340 var rows = [
341 {
342 a: 'aToplevel',
343 b: 'bToplevel',
344 isExpanded: true,
345 subRows: [
346 {
347 a: 'a1',
348 b: 'b1'
349 }
350 ]
351 }
352 ];
353
354 var table = document.createElement('tracing-analysis-nested-table');
355 table.tableColumns = columns;
356 table.tableRows = rows;
357 table.rebuild();
358 this.addHTMLOutput(table);
359
360 var a1El = tv.b.findDeepElementMatchingPredicate(table, function(element) {
361 return element.textContent == 'a1';
362 });
363 assert.isDefined(a1El);
364
365 var bToplevelEl = tv.b.findDeepElementMatchingPredicate(
366 table,
367 function(element) {
368 return element.textContent == 'bToplevel';
369 });
370 assert.isDefined(bToplevelEl);
371 var expandButton = bToplevelEl.parentElement.querySelector('expand-button');
372 assert.isTrue(expandButton.classList.contains('button-expanded'));
373 });
374
375
Chris Craikbeca7ae2015-04-07 13:29:55 -0700376 test('subRowsThatAreRetrievedOnDemand', function() {
377 var columns = [
378 {
379 title: 'a',
380 value: function(row) { return row.a; },
381 width: '150px'
382 }
383 ];
384
385 var rows = [
386 {
387 a: 'row1',
388 subRows: [
389 {
390 b: 'row1.1',
391 get subRows() {
392 throw new Error('Shold not be called');
393 }
394 }
395 ]
396 }
397 ];
398
399 var table = document.createElement('tracing-analysis-nested-table');
400 table.tableColumns = columns;
401 table.tableRows = rows;
402 table.rebuild();
403 this.addHTMLOutput(table);
404 });
405
406
Chris Craikb122baf2015-03-05 13:58:42 -0800407 test('instantiateTableWithHiddenHeader', function() {
408 var columns = [
409 {
410 title: 'a',
411 value: function(row) { return row.a; },
412 width: '150px'
413 },
414 {
415 title: 'a',
416 value: function(row) { return row.b; },
417 width: '50%'
418 }
419 ];
420
421 var rows = [
422 {
423 a: 'aToplevel',
424 b: 'bToplevel'
425 }
426 ];
427
428 var table = document.createElement('tracing-analysis-nested-table');
429 table.showHeader = false;
430 table.tableColumns = columns;
431 table.tableRows = rows;
432 table.rebuild();
433 this.addHTMLOutput(table);
434
435 var tHead = table.$.head;
436 assert.equal(table.$.head.children.length, 0);
437 assert.equal(0, tHead.getBoundingClientRect().height);
438
439 table.showHeader = true;
440 table.rebuild();
441 table.showHeader = false;
442 table.rebuild();
443 assert.equal(table.$.head.children.length, 0);
444 });
445
446
447 test('sortColumnsNotPossibleOnPercentSizedColumns', function() {
448 var columns = [
449 {
450 title: 'Title',
451 value: function(row) { return row.a; },
452 width: '150px'
453 },
454 {
455 title: 'Value',
456 value: function(row) { return row.b; },
457 width: '100%',
458 showExpandButtons: true
459 }
460 ];
461
462 var table1 = document.createElement('tracing-analysis-nested-table');
463 table1.showHeader = true;
464
465 assert.throws(function() {
466 table1.tableColumns = columns;
467 });
468 });
469
470 test('twoTablesFirstColumnMatching', function() {
471 var columns = [
472 {
473 title: 'Title',
474 value: function(row) { return row.a; },
475 width: '150px'
476 },
477 {
478 title: 'Value',
479 value: function(row) { return row.b; },
480 width: '100%'
481 }
482 ];
483
484 var table1 = document.createElement('tracing-analysis-nested-table');
485 table1.showHeader = true;
486 table1.tableColumns = columns;
487 table1.tableRows = [
488 {
489 a: 'first',
490 b: 'row'
491 }
492 ];
493 table1.rebuild();
494 this.addHTMLOutput(table1);
495
496 var table2 = document.createElement('tracing-analysis-nested-table');
497 table2.showHeader = false;
498 table2.tableColumns = columns;
499 table2.tableRows = [
500 {
501 a: 'second',
502 b: 'row'
503 }
504 ];
505 table2.rebuild();
506 this.addHTMLOutput(table2);
507
508 var h1FirstCol = table1.$.head.children[0].children[0];
509 var h2FirstCol = table2.$.body.children[0].children[0];
510 assert.equal(h1FirstCol.getBoundingClientRect().width,
511 h2FirstCol.getBoundingClientRect().width);
512 });
Chris Craikbeca7ae2015-04-07 13:29:55 -0700513
514 test('programmaticSorting', function() {
515 var table = document.createElement('tracing-analysis-nested-table');
516
517 var columns = [
518 {
519 title: 'Column',
520 value: function(row) { return row.value; },
521 cmp: function(rowA, rowB) {
522 return rowA.value.toString().localeCompare(
523 rowB.value.toString());
524 }
525 }
526 ];
527
528 var rows = [
529 {
530 value: 'A1',
531 subRows: [
532 {
533 value: 'A1.1'
534 },
535 {
536 value: 'A1.2',
537 subRows: [
538 {
539 value: 'A1.2.1'
540 },
541 {
542 value: 'A1.2.2'
543 }
544 ]
545 },
546 {
547 value: 'A1.3'
548 }
549 ]
550 },
551 {
552 value: 'A2'
553 }
554 ];
555
556 table.tableColumns = columns;
557 table.tableRows = rows;
558 table.rebuild();
559
560 this.addHTMLOutput(table);
561
562 table.sortDescending = true;
563 table.sortColumnIndex = 0;
564 table.rebuild();
565 var r0 = table.$.body.children[0];
566 assert.equal(r0.rowInfo.userRow, rows[1]);
567
568 var r1 = table.$.body.children[1];
569 assert.equal(r1.rowInfo.userRow, rows[0]);
570 });
571
572 test('sortingAfterExpand', function() {
573 var table = document.createElement('tracing-analysis-nested-table');
574
575 var columns = [
576 {
577 title: 'Column',
578 value: function(row) { return row.value; },
579 cmp: function(rowA, rowB) {
580 return rowA.value.toString().localeCompare(
581 rowB.value.toString());
582 }
583 }
584 ];
585
586 var rows = [
587 {
588 value: 'A1',
589 isExpanded: true,
590 subRows: [
591 {
592 value: 'A1.1'
593 },
594 {
595 value: 'A1.2',
596 subRows: [
597 {
598 value: 'A1.2.1'
599 },
600 {
601 value: 'A1.2.2'
602 }
603 ]
604 },
605 {
606 value: 'A1.3'
607 }
608 ]
609 },
610 {
611 value: 'A2'
612 }
613 ];
614
615 table.tableColumns = columns;
616 table.tableRows = rows;
617 table.rebuild();
618
619 this.addHTMLOutput(table);
620
621 table.sortDescending = true;
622 table.sortColumnIndex = 0;
623 table.rebuild();
624 var r0 = table.$.body.children[0];
625 assert.equal(r0.rowInfo.userRow, rows[1]);
626
627 var r1 = table.$.body.children[1];
628 assert.equal(r1.rowInfo.userRow, rows[0]);
629
630 var r2 = table.$.body.children[2];
631 assert.equal(r2.rowInfo.userRow, rows[0].subRows[2]);
632
633 assert.isFalse(r0.hasAttribute('tabIndex'));
634 });
635
636 function createSimpleOneColumnNestedTable() {
637 var table = document.createElement('tracing-analysis-nested-table');
638
639 var columns = [
640 {
641 title: 'Column',
642 value: function(row) { return row.value; },
643 cmp: function(rowA, rowB) {
644 return rowA.value.toString().localeCompare(
645 rowB.value.toString());
646 }
647 }
648 ];
649
650 var rows = [
651 {
652 value: 'A1',
653 subRows: [
654 {
655 value: 'A1.1'
656 },
657 {
658 value: 'A1.2',
659 subRows: [
660 {
661 value: 'A1.2.1'
662 },
663 {
664 value: 'A1.2.2'
665 }
666 ]
667 },
668 {
669 value: 'A1.3'
670 }
671 ]
672 },
673 {
674 value: 'A2'
675 }
676 ];
677
678 table.tableColumns = columns;
679 table.tableRows = rows;
680 return table;
681 }
682
683 test('expandAfterRebuild', function() {
684 var table = createSimpleOneColumnNestedTable();
685 table.rebuild();
686 var rows = table.tableRows;
687
688 this.addHTMLOutput(table);
689
690 table.rebuild();
691 assert.isFalse(table.getExpandedForTableRow(rows[0]));
692 table.setExpandedForTableRow(rows[0], true);
693 assert.isTrue(table.getExpandedForTableRow(rows[0]));
694
695 var r1 = table.$.body.children[1];
696 assert.equal(r1.rowInfo.userRow, rows[0].subRows[0]);
697 });
698
699 test('tableSelection', function() {
700 var table = createSimpleOneColumnNestedTable();
701 var rows = table.tableRows;
702
703 table.supportsSelection = true;
704 table.selectedTableRow = rows[0];
705
706 table.setExpandedForTableRow(rows[0], true);
707 table.selectedTableRow = rows[0].subRows[1];
708 assert.equal(table.selectedTableRow, rows[0].subRows[1]);
709
710 table.setExpandedForTableRow(rows[0], false);
711 assert.equal(table.selectedTableRow, rows[0]);
712
713 table.supportsSelection = false;
714 assert.equal(table.selectedTableRow, undefined);
715
716 table.supportsSelection = true;
717 table.setExpandedForTableRow(rows[0].subRows[1], true);
718 this.addHTMLOutput(table);
719
720 var r0 = table.$.body.children[0];
721 assert.isTrue(r0.hasAttribute('tabIndex'));
722 });
723
724
725 test('keyMovement', function() {
726 var table = createSimpleOneColumnNestedTable();
727 table.supportsSelection = true;
728 this.addHTMLOutput(table);
729
730 var rows = table.tableRows;
731 table.selectedTableRow = rows[0];
732
733 table.performKeyCommand_('ARROW_DOWN');
734 assert.equal(table.selectedTableRow, rows[1]);
735
736 table.performKeyCommand_('ARROW_UP');
737 assert.equal(table.selectedTableRow, rows[0]);
738
739 // Arrow right on collapsed row should expand.
740 table.selectedTableRow = rows[0];
741 table.performKeyCommand_('ARROW_RIGHT');
742 assert.equal(table.selectedTableRow, rows[0].subRows[0]);
743 assert.isTrue(table.getExpandedForTableRow(rows[0]));
744
745 table.performKeyCommand_('ARROW_DOWN');
746 assert.equal(table.selectedTableRow, rows[0].subRows[1]);
747
748 // ARrow left on collapsed item should select parent.
749 table.performKeyCommand_('ARROW_LEFT');
750 assert.equal(table.selectedTableRow, rows[0]);
751 assert.isTrue(table.getExpandedForTableRow(rows[0]));
752
753 // Arrow right on expanded row should select first child.
754 table.selectedTableRow = rows[0];
755 table.setExpandedForTableRow(rows[0], true);
756 table.performKeyCommand_('ARROW_RIGHT');
757 assert.equal(table.selectedTableRow, rows[0].subRows[0]);
758
759 // Arrow right on a non-expandable row should do nothing.
760 table.selectedTableRow = rows[1];
761 assert.equal(table.selectedTableRow, rows[1]);
762 table.performKeyCommand_('ARROW_RIGHT');
763 assert.equal(table.selectedTableRow, rows[1]);
764 assert.isFalse(table.getExpandedForTableRow(rows[1]));
765 });
Chris Craik44c28202015-05-12 17:25:16 -0700766
767 test('reduceNumberOfColumnsAfterRebuild', function() {
768 // Create a table with two columns.
769 var table = document.createElement('tracing-analysis-nested-table');
770 table.tableColumns = [
771 {
772 title: 'First Column',
773 value: function(row) { return row.firstData; },
774 width: '100px'
775 },
776 {
777 title: 'Second Column',
778 value: function(row) { return row.secondData; },
779 width: '100px'
780 }
781 ];
782
783 // Build the table.
784 table.rebuild();
785
786 // Check that reducing the number of columns doesn't throw an exception.
787 table.tableColumns = [
788 {
789 title: 'First Column',
790 value: function(row) { return row.firstData; },
791 width: '200px'
792 }
793 ];
794 });
795
796 test('cellSelectionBasic', function() {
797 var columns = [
798 {
799 title: 'Title',
800 value: function(row) { return row.a; },
801 width: '150px',
802 supportsCellSelection: false
803 },
804 {
805 title: 'Col1',
806 value: function(row) { return row.b; },
807 width: '33%'
808 },
809 {
810 title: 'Col2',
811 value: function(row) { return row.b * 2; },
812 width: '33%'
813 },
814 {
815 title: 'Col3',
816 value: function(row) { return row.b * 3; },
817 width: '33%'
818 }
819 ];
820
821 var table = document.createElement('tracing-analysis-nested-table');
822 table.showHeader = true;
823 table.supportsSelection = true;
824 table.cellSelectionMode = true;
825 table.tableColumns = columns;
826 table.tableRows = [
827 {
828 a: 'first',
829 b: '1'
830 },
831 {
832 a: 'second',
833 b: '2'
834 }
835 ];
836 table.rebuild();
837 this.addHTMLOutput(table);
838
839 table.selectedTableRow = table.tableRows[0];
840 assert.equal(table.selectedColumnIndex, 1);
841
842 table.performKeyCommand_('ARROW_DOWN');
843 table.performKeyCommand_('ARROW_RIGHT');
844 table.performKeyCommand_('ARROW_RIGHT');
845 table.performKeyCommand_('ARROW_LEFT');
846 assert.equal(table.selectedTableRow, table.tableRows[1]);
847 assert.equal(table.selectedColumnIndex, 2);
848 });
849
850 test('headersWithHtmlElements', function() {
851 var firstColumnTitle = document.createTextNode('First Column');
852 var secondColumnTitle = document.createElement('span');
853 secondColumnTitle.innerText = 'Second Column';
854 secondColumnTitle.style.color = 'blue';
855
856 var columns = [
857 {
858 title: firstColumnTitle,
859 value: function(row) { return row.firstData; },
860 width: '200px'
861 },
862 {
863 title: secondColumnTitle,
864 value: function(row) { return row.secondData; }
865 }
866 ];
867
868 var rows = [
869 {
870 firstData: 'A1',
871 secondData: 'A2'
872 },
873 {
874 firstData: 'B1',
875 secondData: 'B2'
876 }
877 ];
878
879 var table = document.createElement('tracing-analysis-nested-table');
880 table.tableColumns = columns;
881 table.tableRows = rows;
882 table.rebuild();
883
884 this.addHTMLOutput(table);
885
886 var firstColumnHeader = table.$.head.children[0].children[0].children[0];
887 var secondColumnHeader = table.$.head.children[0].children[1].children[0];
888 assert.equal(firstColumnHeader.cellTitle.textContent, 'First Column');
889 assert.equal(secondColumnHeader.cellTitle.textContent, 'Second Column');
890 });
Chris Craikb122baf2015-03-05 13:58:42 -0800891});
892</script>