| <!DOCTYPE html> |
| <!-- |
| Copyright 2016 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/base/utils.html"> |
| <link rel="import" href="/tracing/ui/base/deep_utils.html"> |
| <link rel="import" href="/tracing/value/histogram.html"> |
| <link rel="import" href="/tracing/value/ui/value_set_table.html"> |
| <link rel="import" href="/tracing/value/value_set.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tr.b.unittest.testSuite(function() { |
| var TEST_BOUNDARIES = tr.v.HistogramBinBoundaries.createLinear(0, 1e3, 20); |
| |
| function getTableRowAtPath(table, path) { |
| var row = table.tableRows[0]; |
| for (var index of path) |
| row = row.subRows[index]; |
| return row; |
| } |
| |
| // TODO(benjhayden): Test requestSelectionChange. |
| // TODO(benjhayden): Test search keyup. |
| // TODO(benjhayden): Test referenceDisplayLabel. |
| |
| test('implicitUndefinedValues', function() { |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| this.addHTMLOutput(table); |
| assert.strictEqual('block', getComputedStyle( |
| tr.b.findDeepElementMatchingPredicate( |
| table, e => e.textContent === 'zero values')).display); |
| assert.strictEqual('none', getComputedStyle( |
| tr.b.findDeepElementMatchingPredicate( |
| table, e => e.id === 'container')).display); |
| }); |
| |
| test('explicitUndefinedValues', function() { |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| table.values = undefined; |
| this.addHTMLOutput(table); |
| assert.strictEqual('block', getComputedStyle( |
| tr.b.findDeepElementMatchingPredicate( |
| table, e => e.textContent === 'zero values')).display); |
| assert.strictEqual('none', getComputedStyle( |
| tr.b.findDeepElementMatchingPredicate( |
| table, e => e.id === 'container')).display); |
| }); |
| |
| test('emptyValues', function() { |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| var values = new tr.v.ValueSet(); |
| table.values = values; |
| this.addHTMLOutput(table); |
| assert.strictEqual('block', getComputedStyle( |
| tr.b.findDeepElementMatchingPredicate( |
| table, e => e.textContent === 'zero values')).display); |
| assert.strictEqual('none', getComputedStyle( |
| tr.b.findDeepElementMatchingPredicate( |
| table, e => e.id === 'container')).display); |
| }); |
| |
| test('shortName', function() { |
| // One value has |name|='long name' and |shortName|='short name', |
| // another value has |name|='short name' to demonstrate the fundamental |
| // ambiguity that arises when Values can have multiple different "names". |
| |
| var now = new Date().getTime(); |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| var values = new tr.v.ValueSet(); |
| |
| var histA = new tr.v.Histogram('long name', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| histA.addSample(Math.random() * 1e3); |
| histA.shortName = 'short name'; |
| new tr.v.d.IterationInfo({ |
| label: 'iteration A', |
| benchmarkStartMs: now, |
| }).addToValue(histA); |
| values.addHistogram(histA); |
| |
| var histB = new tr.v.Histogram('short name', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| histB.addSample(Math.random() * 1e3); |
| new tr.v.d.IterationInfo({ |
| label: 'iteration B', |
| benchmarkStartMs: now, |
| }).addToValue(histB); |
| values.addHistogram(histB); |
| |
| table.values = values; |
| this.addHTMLOutput(table); |
| |
| assert.strictEqual('none', getComputedStyle( |
| tr.b.findDeepElementMatchingPredicate( |
| table, e => e.textContent === 'zero values')).display); |
| assert.strictEqual('block', getComputedStyle( |
| tr.b.findDeepElementMatchingPredicate( |
| table, e => e.id === 'container')).display); |
| assert.isDefined(tr.b.findDeepElementMatchingPredicate( |
| table, e => e.textContent === 'short name')); |
| assert.isUndefined(tr.b.findDeepElementMatchingPredicate( |
| table, e => e.textContent === 'long name')); |
| }); |
| |
| test('emptyAndMissing', function() { |
| var now = new Date().getTime(); |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| var values = new tr.v.ValueSet(); |
| |
| var histA = new tr.v.Histogram('histogram A', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| histA.addSample(Math.random() * 1e3); |
| new tr.v.d.IterationInfo({ |
| label: 'iteration A', |
| benchmarkStartMs: now, |
| }).addToValue(histA); |
| values.addHistogram(histA); |
| |
| var histB = new tr.v.Histogram('histogram B', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| histB.addSample(Math.random() * 1e3); |
| new tr.v.d.IterationInfo({ |
| label: 'iteration B', |
| benchmarkStartMs: now, |
| }).addToValue(histB); |
| values.addHistogram(histB); |
| |
| var histC = new tr.v.Histogram('histogram A', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| new tr.v.d.IterationInfo({ |
| label: 'iteration B', |
| benchmarkStartMs: now, |
| }).addToValue(histC); |
| values.addHistogram(histC); |
| |
| table.values = values; |
| this.addHTMLOutput(table); |
| |
| assert.isDefined(tr.b.findDeepElementMatchingPredicate( |
| table, e => e.textContent === '(empty)')); |
| assert.isDefined(tr.b.findDeepElementMatchingPredicate( |
| table, e => e.textContent === '(missing)')); |
| }); |
| |
| test('instantiate_1x1', function() { |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| var values = new tr.v.ValueSet(); |
| |
| var hist = new tr.v.Histogram('foo', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| hist.addSample(Math.random() * 1e3); |
| values.addHistogram(hist); |
| |
| table.values = values; |
| this.addHTMLOutput(table); |
| |
| var baseTable = tr.b.findDeepElementMatchingPredicate( |
| table, elem => elem.tagName === 'TR-UI-B-TABLE'); |
| assert.strictEqual(baseTable.tableRows.length, 1); |
| }); |
| |
| test('merge_unmergeable', function() { |
| var now = new Date().getTime(); |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| var values = new tr.v.ValueSet(); |
| |
| var histA = new tr.v.Histogram('histogram A', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| histA.addSample(Math.random() * 1e3); |
| new tr.v.d.IterationInfo({ |
| label: 'Value', |
| benchmarkStartMs: now, |
| storyDisplayName: 'story A' |
| }).addToValue(histA); |
| values.addHistogram(histA); |
| |
| var histB = new tr.v.Histogram('histogram B', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, |
| tr.v.HistogramBinBoundaries.createExponential(1e-3, 1e3, 20)); |
| for (var i = 0; i < 100; ++i) |
| histB.addSample(Math.random() * Math.random() * 1e3); |
| new tr.v.d.IterationInfo({ |
| label: 'Value', |
| benchmarkStartMs: now, |
| storyDisplayName: 'story A' |
| }).addToValue(histB); |
| values.addHistogram(histB); |
| |
| var histC = new tr.v.Histogram('histogram C', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, |
| tr.v.HistogramBinBoundaries.createExponential(1e-3, 1e3, 30)); |
| for (var i = 0; i < 100; ++i) |
| histC.addSample(Math.random() * Math.random() * 1e3); |
| new tr.v.d.IterationInfo({ |
| label: 'Value', |
| benchmarkStartMs: now, |
| storyDisplayName: 'story B' |
| }).addToValue(histC); |
| values.addHistogram(histC); |
| |
| table.values = values; |
| table.groupingKeys = [tr.v.ValueSet.GROUPINGS.STORY_NAME.key]; |
| this.addHTMLOutput(table); |
| |
| var baseTable = tr.b.findDeepElementMatchingPredicate( |
| table, elem => elem.tagName === 'TR-UI-B-TABLE'); |
| assert.strictEqual(baseTable.tableRows.length, 2); |
| }); |
| |
| test('instantiate_2x2', function() { |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| var values = new tr.v.ValueSet(); |
| |
| var numeric0a = new tr.v.Histogram('foo', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| numeric0a.addSample(Math.random() * 1e3); |
| values.addHistogram(numeric0a); |
| new tr.v.d.IterationInfo({ |
| label: 'iteration A', |
| benchmarkStartMs: new Date().getTime(), |
| }).addToValue(numeric0a); |
| |
| var numeric1a = new tr.v.Histogram('bar', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| numeric1a.addSample(Math.random() * 1e3); |
| values.addHistogram(numeric1a); |
| new tr.v.d.IterationInfo({ |
| label: 'iteration A', |
| benchmarkStartMs: new Date().getTime(), |
| }).addToValue(numeric1a); |
| |
| var numeric0b = new tr.v.Histogram('foo', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| numeric0b.addSample(Math.random() * 1e3); |
| values.addHistogram(numeric0b); |
| new tr.v.d.IterationInfo({ |
| label: 'iteration B', |
| benchmarkStartMs: new Date().getTime(), |
| }).addToValue(numeric0b); |
| |
| var numeric1b = new tr.v.Histogram('bar', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| numeric1b.addSample(Math.random() * 1e3); |
| values.addHistogram(numeric1b); |
| new tr.v.d.IterationInfo({ |
| label: 'iteration B', |
| benchmarkStartMs: new Date().getTime(), |
| }).addToValue(numeric1b); |
| |
| table.values = values; |
| this.addHTMLOutput(table); |
| |
| var baseTable = tr.b.findDeepElementMatchingPredicate( |
| table, elem => elem.tagName === 'TR-UI-B-TABLE'); |
| |
| assert.lengthOf(baseTable.tableColumns, 3); |
| assert.strictEqual('Name', baseTable.tableColumns[0].title); |
| assert.strictEqual('iteration A', baseTable.tableColumns[1].title); |
| assert.strictEqual('iteration B', baseTable.tableColumns[2].title); |
| }); |
| |
| test('instantiation_mergeNumerics', function() { |
| var table = document.createElement('tr-v-ui-value-set-table'); |
| var values = new tr.v.ValueSet(); |
| // Add 64 Histograms, all named 'foo', with different IterationInfos. |
| var benchmarkNames = ['bm A', 'bm B']; |
| var storyGroupingKeys0 = ['A', 'B']; |
| var storyGroupingKeys1 = ['C', 'D']; |
| var storyNames = ['story A', 'story B']; |
| var starts = [1439708400000, 1439794800000]; |
| var labels = ['label A', 'label B']; |
| |
| for (var benchmarkName of benchmarkNames) { |
| for (var storyGroupingKey0 of storyGroupingKeys0) { |
| for (var storyGroupingKey1 of storyGroupingKeys1) { |
| for (var storyName of storyNames) { |
| for (var startMs of starts) { |
| for (var storysetCounter = 0; storysetCounter < 2; |
| ++storysetCounter) { |
| for (var storyCounter = 0; storyCounter < 2; ++storyCounter) { |
| for (var label of labels) { |
| var numeric = new tr.v.Histogram('foo', |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, |
| TEST_BOUNDARIES); |
| for (var i = 0; i < 100; ++i) |
| numeric.addSample(Math.random() * 1e3); |
| |
| values.addHistogram(numeric); |
| |
| new tr.v.d.IterationInfo({ |
| storyGroupingKeys: { |
| storyGroupingKey0: storyGroupingKey0, |
| storyGroupingKey1: storyGroupingKey1 |
| }, |
| benchmarkName: benchmarkName, |
| storyDisplayName: storyName, |
| benchmarkStartMs: startMs, |
| storysetRepeatCounter: storysetCounter, |
| storyRepeatCounter: storyCounter, |
| label: label, |
| }).addToValue(numeric); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| table.values = values; |
| table.groupingKeys = [ |
| tr.v.ValueSet.GROUPINGS.HISTOGRAM_NAME.key, |
| tr.v.ValueSet.GROUPINGS.BENCHMARK_NAME.key, |
| 'storyGroupingKey_storyGroupingKey0', |
| 'storyGroupingKey_storyGroupingKey1', |
| tr.v.ValueSet.GROUPINGS.STORY_NAME.key, |
| tr.v.ValueSet.GROUPINGS.BENCHMARK_START.key, |
| tr.v.ValueSet.GROUPINGS.STORYSET_REPEAT.key, |
| tr.v.ValueSet.GROUPINGS.STORY_REPEAT.key, |
| ]; |
| this.addHTMLOutput(table); |
| var baseTable = tr.b.findDeepElementMatchingPredicate( |
| table, elem => elem.tagName === 'TR-UI-B-TABLE'); |
| |
| assert.lengthOf(baseTable.tableColumns, 3); |
| assert.strictEqual('Name', baseTable.tableColumns[0].title); |
| assert.strictEqual('label A', baseTable.tableColumns[1].title); |
| assert.strictEqual('label B', baseTable.tableColumns[2].title); |
| |
| assert.lengthOf(baseTable.tableRows, 1); |
| assert.strictEqual('foo', baseTable.tableRows[0].name); |
| assert.lengthOf(baseTable.tableRows[0].subRows, 2); |
| |
| // assertions only report their arguments, which is not enough information |
| // to diagnose problems with nested structures like tableRows -- the path to |
| // the particular row is needed. This code would be a bit simpler if each |
| // row were given a named variable, but the path to each subRow would still |
| // need to be tracked in order to provide for diagnosing. |
| var subRowPath = []; |
| var getSubRow = () => getTableRowAtPath(baseTable, subRowPath); |
| |
| for (var i = 0; i < benchmarkNames.length; ++i) { |
| subRowPath.push(i); |
| assert.lengthOf(getSubRow().subRows, 2, subRowPath); |
| assert.strictEqual(benchmarkNames[i], getSubRow().name, subRowPath); |
| |
| for (var s = 0; s < storyGroupingKeys0.length; ++s) { |
| subRowPath.push(s); |
| assert.lengthOf(getSubRow().subRows, 2, subRowPath); |
| assert.strictEqual('storyGroupingKey0: ' + storyGroupingKeys0[s], |
| getSubRow().name, subRowPath); |
| |
| for (var t = 0; t < storyGroupingKeys1.length; ++t) { |
| subRowPath.push(t); |
| assert.lengthOf(getSubRow().subRows, 2, subRowPath); |
| assert.strictEqual('storyGroupingKey1: ' + storyGroupingKeys1[t], |
| getSubRow().name, subRowPath); |
| |
| for (var j = 0; j < storyNames.length; ++j) { |
| subRowPath.push(j); |
| assert.lengthOf(getSubRow().subRows, 2, subRowPath); |
| assert.strictEqual(storyNames[j], getSubRow().name, subRowPath); |
| |
| for (var k = 0; k < starts.length; ++k) { |
| subRowPath.push(k); |
| assert.lengthOf(getSubRow().subRows, 2, subRowPath); |
| assert.strictEqual(tr.b.formatDate(new Date(starts[k])), |
| getSubRow().name, subRowPath); |
| |
| for (var l = 0; l < 2; ++l) { |
| subRowPath.push(l); |
| assert.lengthOf(getSubRow().subRows, 2, subRowPath); |
| assert.strictEqual('storyset repeat ' + l, getSubRow().name, |
| subRowPath); |
| |
| for (var m = 0; m < 2; ++m) { |
| subRowPath.push(m); |
| assert.lengthOf(getSubRow().subRows, 1, subRowPath); |
| assert.strictEqual('story repeat ' + m, getSubRow().name, |
| subRowPath); |
| |
| subRowPath.push(0); |
| assert.strictEqual('iteration', getSubRow().name, subRowPath); |
| subRowPath.pop(); |
| |
| subRowPath.pop(); |
| } |
| subRowPath.pop(); |
| } |
| subRowPath.pop(); |
| } |
| subRowPath.pop(); |
| } |
| subRowPath.pop(); |
| } |
| subRowPath.pop(); |
| } |
| subRowPath.pop(); |
| } |
| }); |
| }); |
| </script> |