5
<title>Datatable Tests</title>
6
<link rel="stylesheet" type="text/css" href="../../../build/cssbase/base-min.css">
7
<script src="../../../build/yui/yui-debug.js"></script>
11
font-family: sans-serif;
19
border:1px solid #C9C675;
38
<body class="yui3-skin-sam">
39
<h1>Datatable Tests</h1>
41
<p>To test the performance of various datatables, look at the following sections in the code:
44
//large or small dataset.
47
//---------------------------------------------
48
// Special instructions
49
//---------------------------------------------
53
//ignore following tests (good to do if you are doing a large dataset)
54
testBaseDatatable: true,
55
testXYDatatable: true,
57
testYDatatable_FixedCol: true,
58
testYDatatable_AutoCol: true,
59
testXYDatatable_BigHeaders: false
64
Toggle <code>data</code> from <code>large</code> to <code>small</code> to get a different sized dataset. The <code>ignore</code> object determines which table to load. If testing performance, it is recommended that you only enable 1 table at a time.</p>
66
<p><input type="button" value="Run Tests" id="btnRun" disabled=true></p>
72
<h3>Base Datatable</h3>
75
<h3>Scrolling XY Datatable (Set columnwidths)</h3>
76
<P>A general XY scrolling datatable. Column widths are provided for all columns, table width and height is provided.</p>
77
<div id="scrolling-xy"></div>
79
<h3>Scrolling X Datatable (Auto Columns)</h3>
80
<p>A X-scrolling datatable. Column A and B have specified widths. The rest of the columns do not have any widths specified. Only a height of 200px is specified.</p>
81
<div id="scrolling-x"></div>
83
<h3>Scrolling Y Datatable</h3>
84
<p>A Y-scrolling datatable. Column widths are provided for all columns, table height is provided. Since all cols have specified width, you may see this table overflowing past its container div (the blue div in the background). </p>
85
<div id="scrolling-y"></div>
87
<h3>Scrolling Datatable with no ColumnWidth</h3>
88
<p>A Y-scrolling datatable, where only the first 2 columns have a specified width. Only the table height is provided.</p>
89
<div id="scrolling-colwidth"></div>
91
<h3>Scrolling Datatable with Big Headers</h3>
92
<p>A XY-scrolling datatable, where only the first 2 columns have a specified width. Table height and width is provided. The table headers are of larger width than the table contents</p>
93
<div id="scrolling-bigcols"></div>
96
<h3>Scrolling Datatable with no width or height set</h3>
97
<p>A scrolling datatable with no width or height values passed in will result in a base datatable being created with auto width and height.</p>
98
<div id="scrolling-noscroll"></div>
100
<script type="text/javascript">
106
filter: (window.location.search.match(/[?&]filter=([^&]+)/) || [])[1] || 'min',
108
useBrowserConsole: false
109
}).use("console", "test", "dump", "datatable", "profiler","node","json-parse", function(Y) {
113
var ASSERT = Y.Assert,
114
ARRAYASSERT = Y.ArrayAssert,
115
BTNRUN = Y.one("#btnRun"),
116
TestRunner = Y.Test.Runner;
117
BTNRUN.set("disabled", false);
118
TestRunner.subscribe(TestRunner.TEST_CASE_COMPLETE_EVENT, testCompleted);
119
Y.on("click", function(e){
121
BTNRUN.set("value", 'Running...');
122
BTNRUN.set("disabled", true);
126
function testCompleted() {
127
BTNRUN.set("value", 'Test Completed');
128
Y.log('Test Completed');
130
var myConsole = new Y.Console().render();
139
for (var i=0; i<500; i++) {
140
large[i] = {a: i+1, b:i+2, c:i+3, d: i+4, e: i+5, f: i+6, g:i+7};
144
var small = [{a:3, b:2, c:1, d:6, e:7, f:2, g:0}, {a:9, b:8, c:7, d:6, e:7, f:2, g:0}, {a:1, b:2, c:3, d:6, e:7, f:2, g:0},
145
{a:3, b:2, c:1, d:6, e:7, f:2, g:0}, {a:9, b:8, c:7, d:6, e:7, f:2, g:0}, {a:1, b:2, c:3, d:6, e:7, f:2, g:0},
146
{a:3, b:2, c:1, d:6, e:7, f:2, g:0}, {a:9, b:8, c:7, d:6, e:7, f:2, g:0}, {a:1, b:2, c:3, d:6, e:7, f:2, g:0},
147
{a:3, b:2, c:1, d:6, e:7, f:2, g:0}, {a:9, b:8, c:7, d:6, e:7, f:2, g:0}, {a:1, b:2, c:3, d:6, e:7, f:2, g:0}];
149
var testBasic = new Y.Test.Case({
152
{label:"Grandparent", children:[
154
{label:"Parent", children: [
160
cols: [{key:"a", field:"a", label:"AAA", sortable:true, className: ["oneClass", "anotherClass"], width:'75px'},{key:"b", abbr:"bbb", className:"myClass", width: '120px'},{key:"c", width:'75px'},{key:"d", width:'150px'},{key:"3", width:'75px'},{key:"f", width:'150px'},{key:"g", width:'75px'}],
162
cols2: [{key:"a", field:"a", label:"AAA", sortable:true, className: ["oneClass", "anotherClass"], width:'75px'},{key:"b", abbr:"bbb", className:"myClass", width:'75px'},{key:"c"},{key:"d"},{key:"e"},{key:"f"},{key:"g"}],
164
cols3: [{key:"a", field:"a", label:"Lorem Ipsum Dolor SIt Amet", sortable:true, className: ["oneClass", "anotherClass"], width:'5px'},{key:"b", abbr:"Lorem Ipsum Dolor SIt Amet", className:"myClass", width:'75px'},{key:"Lorem Ipsum Dolor SIt Amet"},{key:"Lorem Ipsum Dolor SIt Amet"},{key:"Lorem Ipsum Dolor SIt Amet"},{key:"Lorem Ipsum Dolor SIt Amet"},{key:"Lorem Ipsum Dolor SIt Amet"}],
167
//large or small dataset.
170
//---------------------------------------------
171
// Special instructions
172
//---------------------------------------------
176
//ignore following tests (good to do if you are doing a large dataset)
177
testBaseDatatable: true,
178
testXYDatatable: false,
179
testXDatatable: false,
180
testYDatatable_FixedCol: false,
181
testYDatatable_AutoCol: false,
182
testXYDatatable_BigHeaders: false,
183
testNoScrollDatatablekey: false
187
//---------------------------------------------
188
// Setup and tear down
189
//---------------------------------------------
191
setUp : function () {
194
//this.rs = new Y.Recordset({records:this.initialData});
196
//Some Ways to access recordset properties
197
//Y.log(rs.getRecordByIndex(0).getValue('a'));
198
//Y.log(rs.get('records').length);
201
tearDown : function () {
207
/////////////////////////////////////////////////////////////////////////////
211
/////////////////////////////////////////////////////////////////////////////
213
displayReport: function(data) {
215
var dl = Y.Node.create('<dl></dl>'),
216
results = Y.one('#results');
218
Y.each(data, function(v,k,o) {
219
var dt = Y.Node.create('<dt>'+k+'</dt>');
220
var dd = Y.Node.create('<dd>' + v.calls + ' call(s) at ' + v.avg + ' ms/call = <span>' + Math.round(v.avg*v.calls) + '</span> ms total</dd>');
225
results.appendChild(dl);
228
reportParser: function(report) {
229
return (report.calls > 0 && report.avg > 0.2);
233
/////////////////////////////////////////////////////////////////////////////
237
/////////////////////////////////////////////////////////////////////////////
241
testBaseDatatable: function() {
243
Y.Profiler.start('dtBase');
244
this.dt = new Y.DataTable.Base({columnset:this.cols, recordset:this.data, caption:"Base"});
245
Y.Profiler.registerObject('dt', this.dt);
247
Y.Profiler.stop('dtBase');
248
var msg = Y.Profiler.getAverage('dtBase') + 'ms taken to display';
249
var report = Y.Profiler.getFullReport(this.reportParser);
250
this.displayReport(report);
251
Y.Profiler.unregisterObject('dt');
253
Y.one(sel).appendChild('<p class="message">'+msg+'</p>');
256
testXYDatatable: function() {
257
var sel = '#scrolling-xy';
258
Y.Profiler.start('dtXY');
259
this.dt = new Y.DataTable.Base({columnset:this.cols, recordset:this.data, tdValueTemplate:"plug then render {value}", caption: "ScrollingDataTable"});
260
Y.Profiler.registerObject('dt', this.dt);
261
this.dt.plug(Y.Plugin.DataTableScroll, {width:"200px", height:"300px"});
263
Y.Profiler.stop('dtXY');
264
var msg = Y.Profiler.getAverage('dtXY') + 'ms taken to display';
266
var report = Y.Profiler.getFullReport(this.reportParser);
267
this.displayReport(report);
268
Y.Profiler.unregisterObject('dt');
270
Y.one(sel).appendChild('<p class="message">'+msg+'</p>');
274
testXDatatable: function() {
275
var sel = "#scrolling-x";
277
Y.Profiler.start('dtX');
278
this.dt = new Y.DataTable.Base({columnset:this.cols2, recordset:this.data, caption:"ScrollingDataTable"});
279
Y.Profiler.registerObject('dt', this.dt);
280
this.dt.plug(Y.Plugin.DataTableScroll, {width:"150px"});
283
Y.Profiler.stop('dtX');
285
var msg = Y.Profiler.getAverage('dtX') + 'ms taken to display';
286
var report = Y.Profiler.getFullReport(this.reportParser);
287
this.displayReport(report);
288
Y.Profiler.unregisterObject('dt');
290
Y.one(sel).appendChild('<p class="message">'+msg+'</p>');
294
testYDatatable_FixedCol: function() {
295
var sel = "#scrolling-y";
297
Y.Profiler.start('dtY1');
298
this.dt = new Y.DataTable.Base({columnset:this.cols, recordset:this.data, tdValueTemplate:"plug then render {value}", caption:"ScrollingDataTable"});
299
Y.Profiler.registerObject('dt', this.dt);
300
this.dt.plug(Y.Plugin.DataTableScroll, {height:"300px"});
304
Y.Profiler.stop('dtY1');
305
var msg = Y.Profiler.getAverage('dtY1') + 'ms taken to display';
308
var report = Y.Profiler.getFullReport(this.reportParser);
310
this.displayReport(report);
311
Y.Profiler.unregisterObject('dt');
314
Y.one(sel).appendChild('<p class="message">'+msg+'</p>');
317
testYDatatable_AutoCol: function() {
318
var sel = "#scrolling-colwidth";
320
Y.Profiler.start('dtY2');
321
this.dt = new Y.DataTable.Base({columnset:this.cols2, recordset:this.data, tdValueTemplate:"plug then render {value}", caption:"ScrollingDataTable"});
322
Y.Profiler.registerObject('dt', this.dt);
323
this.dt.plug(Y.Plugin.DataTableScroll, {height:"250px"});
325
Y.Profiler.stop('dtY2');
327
var msg = Y.Profiler.getAverage('dtY2') + 'ms taken to display';
328
var report = Y.Profiler.getFullReport(this.reportParser);
330
this.displayReport(report);
331
Y.Profiler.unregisterObject('dt');
333
Y.one(sel).appendChild('<p class="message">'+msg+'</p>');
336
testXYDatatable_BigHeaders: function() {
337
var sel = "#scrolling-bigcols";
339
Y.Profiler.start('dtHeaders');
340
this.dt = new Y.DataTable.Base({columnset:this.cols3, recordset:this.data, tdValueTemplate:"plug then render {value}", caption:"ScrollingDataTable"});
341
Y.Profiler.registerObject('dt', this.dt);
342
this.dt.plug(Y.Plugin.DataTableScroll, {height:"250px", width:"400px"});
344
Y.Profiler.stop('dtHeaders');
346
var msg = Y.Profiler.getAverage('dtHeaders') + 'ms taken to display';
347
var report = Y.Profiler.getFullReport(this.reportParser);
349
this.displayReport(report);
350
Y.Profiler.unregisterObject('dt');
352
Y.one(sel).appendChild('<p class="message">'+msg+'</p>');
355
testNoScrollDatatable: function() {
356
var sel = "#scrolling-noscroll";
358
Y.Profiler.start('dtNoScroll');
359
this.dt = new Y.DataTable.Base({columnset:this.cols3, recordset:this.data, tdValueTemplate:"plug then render {value}", caption:"ScrollingDataTable"});
360
Y.Profiler.registerObject('dt', this.dt);
361
this.dt.plug(Y.Plugin.DataTableScroll);
363
Y.Profiler.stop('dtNoScroll');
365
var msg = Y.Profiler.getAverage('dtNoScroll') + 'ms taken to display';
366
var report = Y.Profiler.getFullReport(this.reportParser);
368
this.displayReport(report);
369
Y.Profiler.unregisterObject('dt');
371
Y.one(sel).appendChild('<p class="message">'+msg+'</p>');
373
this.dt.scroll.set('width', '200px');
376
test_uniqueRecordset: function () {
378
var a = new Y.DataTable.Base(),
379
b = new Y.DataTable.Base(),
380
aRS = a.get('recordset'),
381
bRS = b.get('recordset');
383
Y.Assert.isTrue(aRS instanceof Y.Recordset);
384
Y.Assert.isTrue(bRS instanceof Y.Recordset);
385
Y.Assert.areNotSame(aRS, bRS);
388
"caption should not be added to the DOM unless set": function () {
389
var container = Y.one("#base"),
392
table = new Y.DataTable.Base({
393
columnset: this.cols,
394
recordset: this.data,
395
caption: "Caption set"
397
table.render(container);
399
caption = table.get('boundingBox').one('caption');
400
Y.Assert.isNotNull(caption);
401
Y.Assert.areSame("Caption set", caption.get('text'));
404
container.empty(true);
406
table = new Y.DataTable.Base({
407
columnset: this.cols,
410
table.render(container);
412
caption = table.get('boundingBox').one('caption');
413
Y.Assert.isNull(caption);
415
table.set('caption', 'Caption set');
416
caption = table.get('boundingBox').one('caption');
417
Y.Assert.isNotNull(caption);
418
Y.Assert.areSame('Caption set', caption.get('text'));
421
"test table.datasource.load() updates UI": function () {
422
var data = [ {a:1,b:1,c:1}, {a:2,b:2,c:2}, {a:3,b:3,c:3} ],
423
container = Y.one('#base'),
427
container.empty(true);
429
source = new Y.DataSource.Local({ source: data });
430
source.plug(Y.Plugin.DataSourceArraySchema, {
431
resultFields: ['a','b','c']
434
table = new Y.DataTable.Base({
435
columnset: [ { key: 'a', sortable: true }, 'b', 'c' ]
437
table.plug(Y.Plugin.DataTableDataSource, {
441
table.render(container);
443
Y.Assert.areSame(0, container.all('tbody tr').size());
445
table.datasource.load();
447
Y.Assert.areSame(3, container.all('tbody tr').size());
448
Y.Assert.areSame('1', container.one('tbody td').get('text'));
452
table.datasource.load();
454
Y.Assert.areSame(3, container.all('tbody tr').size());
455
Y.Assert.areSame('NEW', container.one('tbody td').get('text'));
458
"test Recordset does not lose plugins on load": function () {
459
var data = [ {a:1,b:1,c:1}, {a:2,b:2,c:2}, {a:3,b:3,c:3} ],
460
container = Y.one('#base'),
464
container.empty(true);
466
source = new Y.DataSource.Local({ source: data });
467
source.plug(Y.Plugin.DataSourceArraySchema, {
468
resultFields: ['a','b','c']
471
table = new Y.DataTable.Base({
472
columnset: [ { key: 'a', sortable: true }, 'b', 'c' ]
474
table.plug(Y.Plugin.DataTableDataSource, {
477
table.plug(Y.Plugin.DataTableSort);
479
table.render(container);
481
table.datasource.load();
483
recordset = table.get("recordset");
484
Y.Assert.isObject(recordset);
485
Y.Assert.isObject(recordset.sort);
488
"header rows should not have {placeholders}": function () {
490
var data = [ {a:1,b:1,c:1}, {a:2,b:2,c:2}, {a:3,b:3,c:3} ],
491
container = Y.one('#base'),
495
container.empty(true);
497
table = new Y.DataTable.Base({
499
columnset: [ 'a', 'b', 'c' ]
502
table.render(container);
504
html = table._theadNode.getContent();
505
Y.Assert.isNull(html.match(/\{\s*\w+\s*\}/));
508
"cells should default content from column.emptyCellValue": function () {
510
var data = [ {b:1,c:1,d:1},
514
container = Y.one('#base'),
518
container.empty(true);
520
table = new Y.DataTable.Base({
524
{ key: 'b', emptyCellValue: "(NO B)" },
525
{ key: 'c', formatter: "<em>C: {value}</em>",
526
emptyCellValue: "(NO C)" },
527
{ key: 'd', formatter: function (o) {
528
return o.value && (o.value + .5);
530
emptyCellValue: "(NO D)" }]
533
table.render(container);
535
Y.Assert.isNull(table._tbodyNode
536
.getContent().match(/\{\s*\w+\s*\}/));
538
Y.Assert.areSame('', table._tbodyNode.all('tr').item(0)
539
.all('.yui3-datatable-liner').item(0).getContent());
541
Y.Assert.areSame('(NO B)', table._tbodyNode.all('tr').item(1)
542
.all('.yui3-datatable-liner').item(1).getContent());
544
Y.Assert.areSame('<EM>C: (NO C)</EM>',
545
table._tbodyNode.all('tr').item(2)
546
.all('.yui3-datatable-liner').item(2).getContent()
547
.toUpperCase()); // <-- account for IE UC tags
549
Y.Assert.areSame('(NO D)', table._tbodyNode.all('tr').item(3)
550
.all('.yui3-datatable-liner').item(3).getContent());
554
"setting the recordset should update the UI": function () {
555
// Ticket #2529920 (comment 18)
556
// http://yuilibrary.com/projects/yui3/ticket/2529920#comment:18
557
var data = [ {a:1,b:1,c:1}, {a:2,b:2,c:2}, {a:3,b:3,c:3} ],
558
container = Y.one('#base'),
561
container.empty(true);
563
table = new Y.DataTable.Base({
565
columnset: [ 'a', 'b', 'c' ]
568
table.render(container);
570
cell = table._tbodyNode.one('.yui3-datatable-liner');
571
Y.Assert.areSame('1', cell.get('text'));
573
table.set('recordset', [
574
{ a: 10,b: 10,c: 10 },
575
{ a: 20,b: 20,c: 20 },
576
{ a: 30,b: 30,c: 30 }
579
cell = table._tbodyNode.one('.yui3-datatable-liner');
580
Y.Assert.areSame('10', cell.get('text'));
583
"formatters should not have access to o.td by default": function () {
586
table = new Y.DataTable.Base({
590
formatter: function (o) {
591
Y.Assert.isUndefined(o.td);
592
return o.value.toUpperCase();
596
{ key: 'c', formatter: "({value})" }
599
{ a: "a1", b: 53, c: "c1" },
600
{ a: "a2", b: 35, c: "c2" },
601
{ a: "a3", b: 42, c: "c3" }
605
Y.one('#base').empty();
607
table.render('#base');
609
cells = table._tbodyNode.one('tr').all('td');
610
Y.ArrayAssert.itemsAreSame(
611
['A1', '53', '(c1)'],
615
"createCell should populate o.td in formatters": function () {
616
var table, cells, i = 0;
618
table = new Y.DataTable.Base({
622
formatter: function (o) {
623
Y.Assert.isUndefined(o.td);
626
"<strong>???" + (++i) + "</strong>");
628
Y.Assert.isObject(o.td);
632
recordset: [{ a: "a1" }, { a: "a2" }, { a: "a3" }]
635
Y.one('#base').empty();
637
table.render('#base');
639
cells = table._tbodyNode.all('td');
641
Y.ArrayAssert.itemsAreSame(
642
['???1', '???2', '???3'],
647
var suite = new Y.Test.Suite("Datatable Test Suite");
648
suite.add(testBasic);
650
Y.Test.Runner.setName("Datatable Test Runner");
651
Y.Test.Runner.add(suite);