| <!DOCTYPE html> |
| <!-- |
| Copyright 2015 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/math/range.html"> |
| <link rel="import" href="/tracing/base/raf.html"> |
| <link rel="import" href="/tracing/base/time_display_modes.html"> |
| <link rel="import" href="/tracing/base/unit.html"> |
| <link rel="import" href="/tracing/base/unit_scale.html"> |
| <link rel="import" href="/tracing/value/histogram.html"> |
| <link rel="import" href="/tracing/value/ui/scalar_context_controller.html"> |
| <link rel="import" href="/tracing/value/ui/scalar_span.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tr.b.unittest.testSuite(function() { |
| let Scalar = tr.b.Scalar; |
| let Unit = tr.b.Unit; |
| const THIS_DOC = document.currentScript.ownerDocument; |
| |
| const EXAMPLE_MEMORY_FORMATTING_CONTEXT = { |
| unitPrefix: tr.b.UnitPrefixScale.BINARY.KIBI, |
| }; |
| const EXAMPLE_MEMORY_NUMERIC = new Scalar( |
| Unit.byName.sizeInBytesDelta_smallerIsBetter, 256 * 1024 * 1024); |
| |
| function checkSignificance(span, expectedSignificance) { |
| assert.strictEqual(span.$.insignificant.style.display, |
| expectedSignificance === 'insignificant' ? 'inline' : ''); |
| assert.strictEqual(span.$.significantly_better.style.display, |
| expectedSignificance === 'significantly_better' ? 'inline' : ''); |
| assert.strictEqual(span.$.significantly_worse.style.display, |
| expectedSignificance === 'significantly_worse' ? 'inline' : ''); |
| } |
| |
| function checkScalarSpan(test, value, unit, expectedContent, opt_options) { |
| let options = opt_options || {}; |
| let span = tr.v.ui.createScalarSpan(new tr.b.Scalar(unit, value), |
| {significance: options.significance}); |
| |
| test.addHTMLOutput(span); |
| assert.strictEqual( |
| Polymer.dom(span.$.content).textContent, expectedContent); |
| assert.strictEqual(window.getComputedStyle(span.$.content).color, |
| options.expectedColor || 'rgb(0, 0, 0)'); |
| |
| if (options.expectedTitle) { |
| assert.strictEqual(span.$.content.title, options.expectedTitle); |
| } |
| |
| if (options.significance !== undefined) { |
| checkSignificance(span, options.expectedEmoji); |
| if (options.expectedTitle) { |
| assert.strictEqual(span.$.significance.title, options.expectedTitle); |
| } |
| } |
| } |
| |
| test('instantiate_significance', function() { |
| let countD = Unit.byName.count.correspondingDeltaUnit; |
| let countSIBD = Unit.byName.count_smallerIsBetter.correspondingDeltaUnit; |
| let countBIBD = Unit.byName.count_biggerIsBetter.correspondingDeltaUnit; |
| |
| let zero = String.fromCharCode(177) + '0'; |
| |
| checkScalarSpan(this, 0, countSIBD, zero, { |
| significance: tr.b.math.Statistics.Significance.DONT_CARE, |
| expectedTitle: 'no change', |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, 0, countSIBD, zero, { |
| expectedEmoji: 'insignificant', |
| significance: tr.b.math.Statistics.Significance.INSIGNIFICANT, |
| expectedEmojiColor: 'rgb(0, 0, 0)', |
| expectedTitle: 'no change' |
| }); |
| |
| assert.throws(() => checkScalarSpan(this, 0, countSIBD, zero, |
| {significance: tr.b.math.Statistics.Significance.SIGNIFICANT})); |
| |
| checkScalarSpan(this, 0, countBIBD, zero, { |
| significance: tr.b.math.Statistics.Significance.DONT_CARE, |
| expectedTitle: 'no change', |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, 0, countBIBD, zero, { |
| expectedEmoji: 'insignificant', |
| significance: tr.b.math.Statistics.Significance.INSIGNIFICANT, |
| expectedEmojiColor: 'rgb(0, 0, 0)', |
| expectedTitle: 'no change' |
| }); |
| |
| assert.throws(() => checkScalarSpan(this, 0, countSIBD, zero, |
| {significance: tr.b.math.Statistics.Significance.SIGNIFICANT})); |
| |
| checkScalarSpan(this, 1, countSIBD, '+1', { |
| significance: tr.b.math.Statistics.Significance.DONT_CARE, |
| expectedColor: 'rgb(255, 0, 0)', |
| expectedTitle: 'regression', |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, 1, countSIBD, '+1', { |
| significance: tr.b.math.Statistics.Significance.INSIGNIFICANT, |
| expectedColor: 'rgb(255, 0, 0)', |
| expectedEmoji: 'insignificant', |
| expectedEmojiColor: 'rgb(0, 0, 0)', |
| expectedTitle: 'insignificant regression' |
| }); |
| |
| checkScalarSpan(this, 1, countSIBD, '+1', { |
| significance: tr.b.math.Statistics.Significance.SIGNIFICANT, |
| expectedColor: 'rgb(255, 0, 0)', |
| expectedEmoji: 'significantly_worse', |
| expectedEmojiColor: 'rgb(255, 0, 0)', |
| expectedTitle: 'significant regression' |
| }); |
| |
| checkScalarSpan(this, 1, countBIBD, '+1', { |
| significance: tr.b.math.Statistics.Significance.DONT_CARE, |
| expectedColor: 'rgb(0, 128, 0)', |
| expectedTitle: 'improvement', |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, 1, countBIBD, '+1', { |
| significance: tr.b.math.Statistics.Significance.INSIGNIFICANT, |
| expectedColor: 'rgb(0, 128, 0)', |
| expectedEmoji: 'insignificant', |
| expectedEmojiColor: 'rgb(0, 0, 0)', |
| expectedTitle: 'insignificant improvement' |
| }); |
| |
| checkScalarSpan(this, 1, countBIBD, '+1', { |
| significance: tr.b.math.Statistics.Significance.SIGNIFICANT, |
| expectedColor: 'rgb(0, 128, 0)', |
| expectedEmoji: 'significantly_better', |
| expectedEmojiColor: 'rgb(0, 128, 0)', |
| expectedTitle: 'significant improvement' |
| }); |
| |
| checkScalarSpan(this, -1, countSIBD, '-1', { |
| significance: tr.b.math.Statistics.Significance.DONT_CARE, |
| expectedColor: 'rgb(0, 128, 0)', |
| expectedEmoji: '', |
| expectedEmojiColor: '', |
| expectedTitle: 'improvement' |
| }); |
| |
| checkScalarSpan(this, -1, countSIBD, '-1', { |
| significance: tr.b.math.Statistics.Significance.INSIGNIFICANT, |
| expectedColor: 'rgb(0, 128, 0)', |
| expectedEmoji: 'insignificant', |
| expectedEmojiColor: 'rgb(0, 0, 0)', |
| expectedTitle: 'insignificant improvement' |
| }); |
| |
| checkScalarSpan(this, -1, countSIBD, '-1', { |
| significance: tr.b.math.Statistics.Significance.SIGNIFICANT, |
| expectedColor: 'rgb(0, 128, 0)', |
| expectedEmoji: 'significantly_better', |
| expectedEmojiColor: 'rgb(0, 128, 0)', |
| expectedTitle: 'significant improvement' |
| }); |
| |
| checkScalarSpan(this, -1, countBIBD, '-1', { |
| expectedColor: 'rgb(255, 0, 0)', |
| significance: tr.b.math.Statistics.Significance.DONT_CARE, |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, -1, countBIBD, '-1', { |
| significance: tr.b.math.Statistics.Significance.INSIGNIFICANT, |
| expectedColor: 'rgb(255, 0, 0)', |
| expectedEmoji: 'insignificant', |
| expectedEmojiColor: 'rgb(0, 0, 0)', |
| expectedTitle: 'insignificant regression' |
| }); |
| |
| checkScalarSpan(this, -1, countBIBD, '-1', { |
| significance: tr.b.math.Statistics.Significance.SIGNIFICANT, |
| expectedColor: 'rgb(255, 0, 0)', |
| expectedEmoji: 'significantly_worse', |
| expectedEmojiColor: 'rgb(255, 0, 0)', |
| expectedTitle: 'significant regression' |
| }); |
| |
| checkScalarSpan(this, 1, countD, '+1', { |
| expectedColor: 'rgb(0, 0, 0)', |
| significance: tr.b.math.Statistics.Significance.DONT_CARE, |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, 1, countD, '+1', { |
| expectedColor: 'rgb(0, 0, 0)', |
| significance: tr.b.math.Statistics.Significance.INSIGNIFICANT, |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, 1, countD, '+1', { |
| expectedColor: 'rgb(0, 0, 0)', |
| significance: tr.b.math.Statistics.Significance.SIGNIFICANT, |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, -1, countD, '-1', { |
| expectedColor: 'rgb(0, 0, 0)', |
| significance: tr.b.math.Statistics.Significance.DONT_CARE, |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, -1, countD, '-1', { |
| expectedColor: 'rgb(0, 0, 0)', |
| significance: tr.b.math.Statistics.Significance.INSIGNIFICANT, |
| expectedEmoji: '' |
| }); |
| |
| checkScalarSpan(this, -1, countD, '-1', { |
| expectedColor: 'rgb(0, 0, 0)', |
| significance: tr.b.math.Statistics.Significance.SIGNIFICANT, |
| expectedEmoji: '' |
| }); |
| }); |
| |
| test('instantiate', function() { |
| checkScalarSpan(this, 123.456789, Unit.byName.timeDurationInMs, |
| '123.457 ms'); |
| checkScalarSpan(this, 0, Unit.byName.normalizedPercentage, '0.000%'); |
| checkScalarSpan(this, 1, Unit.byName.normalizedPercentage, '100.000%'); |
| checkScalarSpan(this, -2560, Unit.byName.sizeInBytes, '-2.5 KiB'); |
| }); |
| |
| test('instantiate_smallerIsBetter', function() { |
| checkScalarSpan(this, 45097156608, Unit.byName.sizeInBytes_smallerIsBetter, |
| '42.0 GiB'); |
| checkScalarSpan(this, 0, Unit.byName.energyInJoules_smallerIsBetter, |
| '0.000 J'); |
| checkScalarSpan(this, -0.25, Unit.byName.unitlessNumber_smallerIsBetter, |
| '-0.250'); |
| }); |
| |
| test('instantiate_biggerIsBetter', function() { |
| checkScalarSpan(this, 0.07, Unit.byName.powerInWatts_smallerIsBetter, |
| '0.070 W'); |
| checkScalarSpan(this, 0, Unit.byName.timeStampInMs_biggerIsBetter, |
| '0.000 ms'); |
| checkScalarSpan(this, -0.00003, |
| Unit.byName.normalizedPercentage_biggerIsBetter, '-0.003%'); |
| }); |
| |
| test('instantiate_delta', function() { |
| checkScalarSpan(this, 123.456789, Unit.byName.timeDurationInMsDelta, |
| '+123.457 ms'); |
| checkScalarSpan(this, 0, Unit.byName.normalizedPercentageDelta, |
| '\u00B10.000%'); |
| checkScalarSpan(this, -2560, Unit.byName.sizeInBytesDelta, |
| '-2.5 KiB'); |
| }); |
| |
| test('instantiate_delta_smallerIsBetter', function() { |
| checkScalarSpan(this, 45097156608, |
| Unit.byName.sizeInBytesDelta_smallerIsBetter, '+42.0 GiB', |
| {expectedColor: 'rgb(255, 0, 0)'}); |
| checkScalarSpan(this, 0, Unit.byName.energyInJoulesDelta_smallerIsBetter, |
| '\u00B10.000 J'); |
| checkScalarSpan(this, -0.25, |
| Unit.byName.unitlessNumberDelta_smallerIsBetter, '-0.250', |
| {expectedColor: 'rgb(0, 128, 0)'}); |
| }); |
| |
| test('instantiate_delta_biggerIsBetter', function() { |
| checkScalarSpan(this, 0.07, Unit.byName.powerInWattsDelta_biggerIsBetter, |
| '+0.070 W', {expectedColor: 'rgb(0, 128, 0)'}); |
| checkScalarSpan(this, 0, Unit.byName.timeStampInMsDelta_biggerIsBetter, |
| '\u00B10.000 ms'); |
| checkScalarSpan(this, -0.00003, |
| Unit.byName.normalizedPercentageDelta_biggerIsBetter, '-0.003%', |
| {expectedColor: 'rgb(255, 0, 0)'}); |
| }); |
| |
| test('createScalarSpan', function() { |
| // No config. |
| let span = tr.v.ui.createScalarSpan( |
| new Scalar(Unit.byName.powerInWatts, 3.14)); |
| assert.strictEqual(Polymer.dom(span.$.content).textContent, '3.140 W'); |
| assert.strictEqual(span.ownerDocument, document); |
| assert.strictEqual(span.tagName, 'TR-V-UI-SCALAR-SPAN'); |
| assert.strictEqual(span.value, 3.14); |
| assert.strictEqual(span.unit, Unit.byName.powerInWatts); |
| assert.isUndefined(span.context); |
| assert.isUndefined(span.customContextRange); |
| assert.isUndefined(span.warning); |
| assert.isFalse(span.leftAlign); |
| this.addHTMLOutput(span); |
| |
| // Inline. |
| let div = document.createElement('div'); |
| this.addHTMLOutput(div); |
| let inlineSpan = tr.v.ui.createScalarSpan( |
| new Scalar(Unit.byName.powerInWatts, 3.14), |
| {inline: true}); |
| assert.strictEqual(Polymer.dom(inlineSpan.$.content).textContent, |
| '3.140 W'); |
| assert.strictEqual(inlineSpan.ownerDocument, document); |
| assert.strictEqual(inlineSpan.tagName, 'TR-V-UI-SCALAR-SPAN'); |
| assert.strictEqual(inlineSpan.value, 3.14); |
| assert.strictEqual(inlineSpan.unit, Unit.byName.powerInWatts); |
| assert.isUndefined(inlineSpan.context); |
| assert.isUndefined(inlineSpan.customContextRange); |
| assert.isUndefined(inlineSpan.warning); |
| assert.isFalse(inlineSpan.leftAlign); |
| div.appendChild(document.createTextNode('prefix ')); |
| div.appendChild(inlineSpan); |
| div.appendChild(document.createTextNode(' suffix')); |
| assert.isBelow(inlineSpan.getBoundingClientRect().width, |
| span.getBoundingClientRect().width); |
| |
| // Custom owner document and right align. |
| span = tr.v.ui.createScalarSpan( |
| new Scalar(Unit.byName.energyInJoules, 2.72), |
| { ownerDocument: THIS_DOC, leftAlign: true}); |
| assert.strictEqual(Polymer.dom(span.$.content).textContent, '2.720 J'); |
| assert.strictEqual(span.ownerDocument, THIS_DOC); |
| assert.strictEqual(span.tagName, 'TR-V-UI-SCALAR-SPAN'); |
| assert.strictEqual(span.value, 2.72); |
| assert.strictEqual(span.unit, Unit.byName.energyInJoules); |
| assert.isUndefined(span.context); |
| assert.isUndefined(span.customContextRange); |
| assert.isUndefined(span.warning); |
| assert.isTrue(span.leftAlign); |
| this.addHTMLOutput(span); |
| |
| // Unit and sparkline set via config. |
| span = tr.v.ui.createScalarSpan(1.62, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: tr.b.math.Range.fromExplicitRange(0, 3.24) |
| }); |
| assert.strictEqual(Polymer.dom(span.$.content).textContent, '1.620 ms'); |
| assert.strictEqual(span.ownerDocument, document); |
| assert.strictEqual(span.tagName, 'TR-V-UI-SCALAR-SPAN'); |
| assert.strictEqual(span.value, 1.62); |
| assert.strictEqual(span.unit, Unit.byName.timeStampInMs); |
| assert.isUndefined(span.context); |
| assert.isTrue(tr.b.math.Range.fromExplicitRange(0, 3.24).equals( |
| span.customContextRange)); |
| assert.isUndefined(span.warning); |
| assert.isFalse(span.leftAlign); |
| this.addHTMLOutput(span); |
| |
| // Custom context. |
| span = tr.v.ui.createScalarSpan( |
| new Scalar(Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| 256 * 1024 * 1024), { context: { |
| unitPrefix: tr.b.UnitPrefixScale.BINARY.KIBI, |
| minimumFractionDigits: 2 |
| } }); |
| assert.strictEqual( |
| Polymer.dom(span.$.content).textContent, '+262,144.00 KiB'); |
| assert.strictEqual(span.ownerDocument, document); |
| assert.strictEqual(span.tagName, 'TR-V-UI-SCALAR-SPAN'); |
| assert.strictEqual(span.value, 256 * 1024 * 1024); |
| assert.strictEqual(span.unit, Unit.byName.sizeInBytesDelta_smallerIsBetter); |
| assert.deepEqual(span.context, { |
| unitPrefix: tr.b.UnitPrefixScale.BINARY.KIBI, |
| minimumFractionDigits: 2 |
| }); |
| assert.isUndefined(span.customContextRange); |
| assert.isUndefined(span.warning); |
| assert.isFalse(span.leftAlign); |
| this.addHTMLOutput(span); |
| }); |
| |
| test('instantiate_withWarning', function() { |
| let span = document.createElement('tr-v-ui-scalar-span'); |
| span.value = 400000000; |
| span.unit = Unit.byName.sizeInBytes; |
| span.warning = 'There is a problem with this size'; |
| this.addHTMLOutput(span); |
| }); |
| |
| test('instantiate_withCustomContextRange', function() { |
| let span = document.createElement('tr-v-ui-scalar-span'); |
| span.value = new Scalar(Unit.byName.unitlessNumber, 0.99); |
| span.customContextRange = tr.b.math.Range.fromExplicitRange(0, 3); |
| this.addHTMLOutput(span); |
| }); |
| |
| test('instantiate_withRightAlign', function() { |
| let span = document.createElement('tr-v-ui-scalar-span'); |
| span.value = new Scalar(Unit.byName.timeStampInMs, 5.777); |
| span.leftAlign = true; |
| this.addHTMLOutput(span); |
| }); |
| |
| test('instantiate_withContext', function() { |
| let span = document.createElement('tr-v-ui-scalar-span'); |
| span.value = new Scalar( |
| Unit.byName.unitlessNumberDelta_smallerIsBetter, 42); |
| span.context = { maximumFractionDigits: 2 }; |
| assert.strictEqual(Polymer.dom(span.$.content).textContent, '+42.00'); |
| this.addHTMLOutput(span); |
| }); |
| |
| test('deltaAndNonDeltaHaveSimilarHeights', function() { |
| let spanA = document.createElement('tr-v-ui-scalar-span'); |
| spanA.setValueAndUnit(400, Unit.byName.timeDurationInMs); |
| checkSignificance(spanA, ''); |
| |
| let spanB = document.createElement('tr-v-ui-scalar-span'); |
| spanB.setValueAndUnit(400, Unit.byName.timeDurationInMsDelta); |
| checkSignificance(spanB, ''); |
| |
| let spanC = document.createElement('tr-v-ui-scalar-span'); |
| spanC.setValueAndUnit( |
| 400, Unit.byName.timeDurationInMsDelta_smallerIsBetter); |
| spanC.significance = tr.b.math.Statistics.Significance.SIGNIFICANT; |
| checkSignificance(spanC, 'significantly_worse'); |
| |
| let spanD = document.createElement('tr-v-ui-scalar-span'); |
| spanD.setValueAndUnit( |
| 400, Unit.byName.timeDurationInMsDelta_biggerIsBetter); |
| spanD.significance = tr.b.math.Statistics.Significance.SIGNIFICANT; |
| checkSignificance(spanD, 'significantly_better'); |
| |
| let spanE = document.createElement('tr-v-ui-scalar-span'); |
| spanE.setValueAndUnit( |
| 400, Unit.byName.timeDurationInMsDelta_smallerIsBetter); |
| spanE.significance = tr.b.math.Statistics.Significance.INSIGNIFICANT; |
| checkSignificance(spanE, 'insignificant'); |
| |
| let overall = document.createElement('div'); |
| overall.style.display = 'flex'; |
| // These spans must be on separate lines so that Chrome has the option of |
| // making their heights different. The point of the test is that Chrome |
| // shouldn't have to make their heights different even when it could. |
| overall.style.flexDirection = 'column'; |
| Polymer.dom(overall).appendChild(spanA); |
| Polymer.dom(overall).appendChild(spanB); |
| Polymer.dom(overall).appendChild(spanC); |
| Polymer.dom(overall).appendChild(spanD); |
| Polymer.dom(overall).appendChild(spanE); |
| this.addHTMLOutput(overall); |
| |
| let expectedHeight = spanA.getBoundingClientRect().height; |
| assert.strictEqual(expectedHeight, spanB.getBoundingClientRect().height); |
| assert.strictEqual(expectedHeight, spanC.getBoundingClientRect().height); |
| assert.strictEqual(expectedHeight, spanD.getBoundingClientRect().height); |
| assert.strictEqual(expectedHeight, spanE.getBoundingClientRect().height); |
| }); |
| |
| test('warningAndNonWarningHaveSimilarHeights', function() { |
| let spanA = document.createElement('tr-v-ui-scalar-span'); |
| spanA.setValueAndUnit(400, Unit.byName.timeDurationInMs); |
| |
| let spanB = document.createElement('tr-v-ui-scalar-span'); |
| spanB.setValueAndUnit(400, Unit.byName.timeDurationInMs); |
| spanB.warning = 'There is a problem with this time'; |
| |
| let overall = document.createElement('div'); |
| overall.style.display = 'flex'; |
| // These spans must be on separate lines so that Chrome has the option of |
| // making their heights different. The point of the test is that Chrome |
| // shouldn't have to make their heights different even when it could. |
| overall.style.flexDirection = 'column'; |
| Polymer.dom(overall).appendChild(spanA); |
| Polymer.dom(overall).appendChild(spanB); |
| this.addHTMLOutput(overall); |
| |
| let rectA = spanA.getBoundingClientRect(); |
| let rectB = spanB.getBoundingClientRect(); |
| assert.strictEqual(rectA.height, rectB.height); |
| }); |
| |
| test('respectCurrentDisplayUnit', function() { |
| try { |
| Unit.currentTimeDisplayMode = tr.b.TimeDisplayModes.ns; |
| |
| let span = document.createElement('tr-v-ui-scalar-span'); |
| span.setValueAndUnit(73, Unit.byName.timeStampInMs); |
| this.addHTMLOutput(span); |
| |
| assert.isTrue(Polymer.dom(span.$.content).textContent.indexOf('ns') > 0); |
| Unit.currentTimeDisplayMode = tr.b.TimeDisplayModes.ms; |
| assert.isTrue(Polymer.dom(span.$.content).textContent.indexOf('ms') > 0); |
| } finally { |
| Unit.reset(); |
| } |
| }); |
| |
| function checkSparkline(span, expectation) { |
| tr.b.forceAllPendingTasksToRunForTest(); |
| let sparklineEl = span.$.sparkline; |
| let computedStyle = getComputedStyle(sparklineEl); |
| |
| let expectedDisplay = expectation.display || 'block'; |
| assert.strictEqual(computedStyle.display, expectedDisplay); |
| if (expectedDisplay === 'none') { |
| // Test expectation sanity check. |
| assert.notProperty(expectation, 'left'); |
| assert.notProperty(expectation, 'width'); |
| assert.notProperty(expectation, 'classList'); |
| return; |
| } |
| |
| assert.closeTo(parseFloat(computedStyle.left), expectation.left, 0.1); |
| assert.closeTo(parseFloat(computedStyle.width), expectation.width, 0.1); |
| assert.sameMembers(tr.b.asArray(sparklineEl.classList), |
| expectation.classList || []); |
| } |
| |
| test('customContextRange', function() { |
| let div = document.createElement('div'); |
| div.style.width = '101px'; // One extra pixel for sparkline border. |
| this.addHTMLOutput(div); |
| |
| // No custom context range. |
| let span1 = tr.v.ui.createScalarSpan(0, { |
| unit: Unit.byName.timeStampInMs |
| }); |
| Polymer.dom(div).appendChild(span1); |
| checkSparkline(span1, {display: 'none'}); |
| let span2 = tr.v.ui.createScalarSpan(0, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: undefined |
| }); |
| Polymer.dom(div).appendChild(span2); |
| checkSparkline(span2, {display: 'none'}); |
| let span3 = tr.v.ui.createScalarSpan(0, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: new tr.b.math.Range() // Empty range. |
| }); |
| Polymer.dom(div).appendChild(span3); |
| checkSparkline(span3, {display: 'none'}); |
| |
| let range = tr.b.math.Range.fromExplicitRange(-15, 15); |
| |
| // Values inside custom context range. |
| let span4 = tr.v.ui.createScalarSpan(-15, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span4); |
| checkSparkline(span4, {left: 0, width: 51}); |
| let span5 = tr.v.ui.createScalarSpan(-14, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span5); |
| checkSparkline(span5, {left: 3.33, width: 47.67}); |
| let span6 = tr.v.ui.createScalarSpan(-10, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span6); |
| checkSparkline(span6, {left: 16.67, width: 34.33}); |
| let span7 = tr.v.ui.createScalarSpan(0, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span7); |
| checkSparkline(span7, {left: 50, width: 1}); |
| let span8 = tr.v.ui.createScalarSpan(10, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span8); |
| checkSparkline(span8, {left: 50, width: 34.33, classList: ['positive']}); |
| let span9 = tr.v.ui.createScalarSpan(14, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span9); |
| checkSparkline(span9, {left: 50, width: 47.67, classList: ['positive']}); |
| let span10 = tr.v.ui.createScalarSpan(15, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span10); |
| checkSparkline(span10, {left: 50, width: 51, classList: ['positive']}); |
| |
| // Values outside custom context range. |
| let span11 = tr.v.ui.createScalarSpan(-20, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span11); |
| checkSparkline(span11, {left: 0, width: 51}); |
| let span12 = tr.v.ui.createScalarSpan(20, { |
| unit: Unit.byName.timeStampInMs, |
| customContextRange: range |
| }); |
| Polymer.dom(div).appendChild(span12); |
| checkSparkline(span12, {left: 50, width: 51, classList: ['positive']}); |
| }); |
| |
| test('emptyNumeric', function() { |
| assert.strictEqual(tr.v.ui.createScalarSpan(), ''); |
| }); |
| |
| test('contextControllerChanges', function() { |
| let div = document.createElement('div'); |
| div.style.width = '101px'; // One extra pixel for sparkline border. |
| this.addHTMLOutput(div); |
| |
| div.appendChild( |
| document.createElement('tr-v-ui-scalar-context-controller')); |
| |
| let s1 = tr.v.ui.createScalarSpan(10, { |
| unit: Unit.byName.powerInWatts |
| }); |
| Polymer.dom(div).appendChild(s1); |
| checkSparkline(s1, {display: 'none'}); |
| |
| let s2 = tr.v.ui.createScalarSpan(20, { |
| unit: Unit.byName.powerInWatts, |
| contextGroup: 'A' |
| }); |
| Polymer.dom(div).appendChild(s2); |
| checkSparkline(s1, {display: 'none'}); |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| |
| let s3 = tr.v.ui.createScalarSpan(30, { |
| unit: Unit.byName.powerInWatts, |
| contextGroup: 'A' |
| }); |
| Polymer.dom(div).appendChild(s3); |
| checkSparkline(s1, {display: 'none'}); |
| checkSparkline(s2, {left: 0, width: 67.67, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| |
| let s4 = tr.v.ui.createScalarSpan(40, { |
| unit: Unit.byName.powerInWatts, |
| contextGroup: 'B' |
| }); |
| Polymer.dom(div).appendChild(s4); |
| checkSparkline(s1, {display: 'none'}); |
| checkSparkline(s2, {left: 0, width: 67.67, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s4, {left: 0, width: 101, classList: ['positive']}); |
| |
| s3.contextGroup = 'B'; |
| checkSparkline(s1, {display: 'none'}); |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 76, classList: ['positive']}); |
| checkSparkline(s4, {left: 0, width: 101, classList: ['positive']}); |
| |
| s1.setAttribute('context-group', 'A'); |
| checkSparkline(s1, {left: 0, width: 51, classList: ['positive']}); |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 76, classList: ['positive']}); |
| checkSparkline(s4, {left: 0, width: 101, classList: ['positive']}); |
| |
| s1.value = 50; |
| checkSparkline(s1, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s2, {left: 0, width: 41, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 76, classList: ['positive']}); |
| checkSparkline(s4, {left: 0, width: 101, classList: ['positive']}); |
| |
| s1.customContextRange = tr.b.math.Range.fromExplicitRange(0, 150); |
| checkSparkline(s1, {left: 0, width: 34.33, classList: ['positive']}); |
| checkSparkline(s2, {left: 0, width: 41, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 76, classList: ['positive']}); |
| checkSparkline(s4, {left: 0, width: 101, classList: ['positive']}); |
| |
| s4.contextGroup = null; |
| checkSparkline(s1, {left: 0, width: 34.33, classList: ['positive']}); |
| checkSparkline(s2, {left: 0, width: 41, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s4, {display: 'none'}); |
| |
| s1.customContextRange = undefined; |
| checkSparkline(s1, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s2, {left: 0, width: 41, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s4, {display: 'none'}); |
| |
| s4.value = 0; |
| checkSparkline(s1, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s2, {left: 0, width: 41, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s4, {display: 'none'}); |
| |
| div.removeChild(s1); |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s4, {display: 'none'}); |
| |
| s1.contextGroup = 'B'; |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s4, {display: 'none'}); |
| |
| div.appendChild(s1); |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 61, classList: ['positive']}); |
| checkSparkline(s4, {display: 'none'}); |
| checkSparkline(s1, {left: 0, width: 101, classList: ['positive']}); |
| |
| s1.removeAttribute('context-group'); |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s4, {display: 'none'}); |
| checkSparkline(s1, {display: 'none'}); |
| |
| s1.customContextRange = tr.b.math.Range.fromExplicitRange(0, 100); |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s3, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s4, {display: 'none'}); |
| checkSparkline(s1, {left: 0, width: 51, classList: ['positive']}); |
| |
| s3.value = 0; |
| checkSparkline(s2, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(s3, {display: 'none'}); |
| checkSparkline(s4, {display: 'none'}); |
| checkSparkline(s1, {left: 0, width: 51, classList: ['positive']}); |
| }); |
| |
| test('deltaSparkline_noImprovementDirection', function() { |
| let div = document.createElement('div'); |
| div.style.width = '101px'; // One extra pixel for sparkline border. |
| this.addHTMLOutput(div); |
| div.appendChild( |
| document.createElement('tr-v-ui-scalar-context-controller')); |
| |
| let span1 = tr.v.ui.createScalarSpan(20971520, { |
| unit: Unit.byName.sizeInBytesDelta, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span1); |
| let span2 = tr.v.ui.createScalarSpan(15728640, { |
| unit: Unit.byName.sizeInBytesDelta, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span2); |
| let span3 = tr.v.ui.createScalarSpan(12582912, { |
| unit: Unit.byName.sizeInBytesDelta, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span3); |
| let span4 = tr.v.ui.createScalarSpan(11534336, { |
| unit: Unit.byName.sizeInBytesDelta, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span4); |
| let span5 = tr.v.ui.createScalarSpan(10485760, { |
| unit: Unit.byName.sizeInBytesDelta, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span5); |
| let span6 = tr.v.ui.createScalarSpan(9437184, { |
| unit: Unit.byName.sizeInBytesDelta, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span6); |
| let span7 = tr.v.ui.createScalarSpan(8388608, { |
| unit: Unit.byName.sizeInBytesDelta, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span7); |
| let span8 = tr.v.ui.createScalarSpan(5242880, { |
| unit: Unit.byName.sizeInBytesDelta, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span8); |
| |
| // We must check the sparklines *after* all spans are appended because new |
| // values can change the context range. |
| checkSparkline(span1, {left: 0, width: 101, classList: ['positive']}); |
| checkSparkline(span2, {left: 0, width: 76, classList: ['positive']}); |
| checkSparkline(span3, {left: 0, width: 61, classList: ['positive']}); |
| checkSparkline(span4, {left: 0, width: 56, classList: ['positive']}); |
| checkSparkline(span5, {left: 0, width: 51, classList: ['positive']}); |
| checkSparkline(span6, {left: 0, width: 46, classList: ['positive']}); |
| checkSparkline(span7, {left: 0, width: 41, classList: ['positive']}); |
| checkSparkline(span8, {left: 0, width: 26, classList: ['positive']}); |
| }); |
| |
| test('deltaSparkline_smallerIsBetter', function() { |
| let div = document.createElement('div'); |
| div.style.width = '101px'; // One extra pixel for sparkline border. |
| this.addHTMLOutput(div); |
| div.appendChild( |
| document.createElement('tr-v-ui-scalar-context-controller')); |
| |
| let span1 = tr.v.ui.createScalarSpan(5242880, { |
| unit: Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span1); |
| let span2 = tr.v.ui.createScalarSpan(0, { |
| unit: Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span2); |
| let span3 = tr.v.ui.createScalarSpan(-3145728, { |
| unit: Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span3); |
| let span4 = tr.v.ui.createScalarSpan(-4194304, { |
| unit: Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span4); |
| let span5 = tr.v.ui.createScalarSpan(-5242880, { |
| unit: Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span5); |
| let span6 = tr.v.ui.createScalarSpan(-6291456, { |
| unit: Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span6); |
| let span7 = tr.v.ui.createScalarSpan(-7340032, { |
| unit: Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span7); |
| let span8 = tr.v.ui.createScalarSpan(-15728640, { |
| unit: Unit.byName.sizeInBytesDelta_smallerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span8); |
| |
| // We must check the sparklines *after* all spans are appended because new |
| // values can change the context range. |
| checkSparkline(span1, |
| {left: 75, width: 26, classList: ['positive', 'worse']}); |
| checkSparkline(span2, {left: 75, width: 1, classList: ['same']}); |
| checkSparkline(span3, {left: 60, width: 16, classList: ['better']}); |
| checkSparkline(span4, {left: 55, width: 21, classList: ['better']}); |
| checkSparkline(span5, {left: 50, width: 26, classList: ['better']}); |
| checkSparkline(span6, {left: 45, width: 31, classList: ['better']}); |
| checkSparkline(span7, {left: 40, width: 36, classList: ['better']}); |
| checkSparkline(span8, {left: 0, width: 76, classList: ['better']}); |
| }); |
| |
| test('deltaSparkline_biggerIsBetter', function() { |
| let div = document.createElement('div'); |
| div.style.width = '101px'; // One extra pixel for sparkline border. |
| this.addHTMLOutput(div); |
| div.appendChild( |
| document.createElement('tr-v-ui-scalar-context-controller')); |
| |
| let span1 = tr.v.ui.createScalarSpan(0, { |
| unit: Unit.byName.sizeInBytesDelta_biggerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span1); |
| let span2 = tr.v.ui.createScalarSpan(-5242880, { |
| unit: Unit.byName.sizeInBytesDelta_biggerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span2); |
| let span3 = tr.v.ui.createScalarSpan(-8388608, { |
| unit: Unit.byName.sizeInBytesDelta_biggerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span3); |
| let span4 = tr.v.ui.createScalarSpan(-9437184, { |
| unit: Unit.byName.sizeInBytesDelta_biggerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span4); |
| let span5 = tr.v.ui.createScalarSpan(-10485760, { |
| unit: Unit.byName.sizeInBytesDelta_biggerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span5); |
| let span6 = tr.v.ui.createScalarSpan(-11534336, { |
| unit: Unit.byName.sizeInBytesDelta_biggerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span6); |
| let span7 = tr.v.ui.createScalarSpan(-12582912, { |
| unit: Unit.byName.sizeInBytesDelta_biggerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span7); |
| let span8 = tr.v.ui.createScalarSpan(-20971520, { |
| unit: Unit.byName.sizeInBytesDelta_biggerIsBetter, |
| contextGroup: 'test' |
| }); |
| Polymer.dom(div).appendChild(span8); |
| |
| // We must check the sparklines *after* all spans are appended because new |
| // values can change the context range. |
| checkSparkline(span1, {left: 100, width: 1, classList: ['same']}); |
| checkSparkline(span2, {left: 75, width: 26, classList: ['worse']}); |
| checkSparkline(span3, {left: 60, width: 41, classList: ['worse']}); |
| checkSparkline(span4, {left: 55, width: 46, classList: ['worse']}); |
| checkSparkline(span5, {left: 50, width: 51, classList: ['worse']}); |
| checkSparkline(span6, {left: 45, width: 56, classList: ['worse']}); |
| checkSparkline(span7, {left: 40, width: 61, classList: ['worse']}); |
| checkSparkline(span8, {left: 0, width: 101, classList: ['worse']}); |
| }); |
| |
| test('classListChanges', function() { |
| let div = document.createElement('div'); |
| div.style.width = '200px'; |
| this.addHTMLOutput(div); |
| |
| let span = tr.v.ui.createScalarSpan(10, { |
| unit: Unit.byName.energyInJoulesDelta_smallerIsBetter, |
| significance: tr.b.math.Statistics.Significance.SIGNIFICANT, |
| customContextRange: tr.b.math.Range.fromExplicitRange(-20, 20) |
| }); |
| Polymer.dom(div).appendChild(span); |
| |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), ['worse']); |
| checkSignificance(span, 'significantly_worse'); |
| |
| span.significance = tr.b.math.Statistics.Significance.DONT_CARE; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), |
| ['positive', 'worse']); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), ['worse']); |
| checkSignificance(span, ''); |
| |
| span.value = -5; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), ['better']); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), ['better']); |
| checkSignificance(span, ''); |
| |
| span.unit = Unit.byName.energyInJoules; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), []); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), []); |
| checkSignificance(span, ''); |
| |
| span.value = 20; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), ['positive']); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), []); |
| checkSignificance(span, ''); |
| |
| span.unit = Unit.byName.energyInJoulesDelta_biggerIsBetter; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), |
| ['positive', 'better']); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), ['better']); |
| checkSignificance(span, ''); |
| |
| span.significance = tr.b.math.Statistics.Significance.INSIGNIFICANT; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), |
| ['positive', 'better']); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), ['better']); |
| checkSignificance(span, 'insignificant'); |
| |
| span.unit = Unit.byName.energyInJoulesDelta_smallerIsBetter; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), |
| ['positive', 'worse']); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), ['worse']); |
| checkSignificance(span, 'insignificant'); |
| |
| span.unit = Unit.byName.energyInJoulesDelta; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), ['positive']); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), []); |
| checkSignificance(span, ''); |
| |
| span.value = 0; |
| assert.sameMembers(tr.b.asArray(span.$.sparkline.classList), []); |
| assert.sameMembers(tr.b.asArray(span.$.content.classList), []); |
| checkSignificance(span, ''); |
| }); |
| |
| test('sparkline_uncentered', function() { |
| let div = document.createElement('div'); |
| this.addHTMLOutput(div); |
| div.appendChild( |
| document.createElement('tr-v-ui-scalar-context-controller')); |
| |
| Polymer.dom(div).appendChild(tr.v.ui.createScalarSpan(-1, { |
| unit: Unit.byName.powerInWattsDelta, |
| contextGroup: 'test' |
| })); |
| Polymer.dom(div).appendChild(tr.v.ui.createScalarSpan(100, { |
| unit: Unit.byName.powerInWattsDelta, |
| contextGroup: 'test' |
| })); |
| Polymer.dom(div).appendChild(tr.v.ui.createScalarSpan(80, { |
| unit: Unit.byName.powerInWattsDelta, |
| contextGroup: 'test' |
| })); |
| Polymer.dom(div).appendChild(tr.v.ui.createScalarSpan(60, { |
| unit: Unit.byName.powerInWattsDelta, |
| contextGroup: 'test' |
| })); |
| }); |
| |
| test('sparkline_centered', function() { |
| let div = document.createElement('div'); |
| this.addHTMLOutput(div); |
| div.appendChild( |
| document.createElement('tr-v-ui-scalar-context-controller')); |
| |
| Polymer.dom(div).appendChild(tr.v.ui.createScalarSpan(-1, { |
| unit: Unit.byName.powerInWattsDelta, |
| customContextRange: tr.b.math.Range.fromExplicitRange(-100, 100) |
| })); |
| Polymer.dom(div).appendChild(tr.v.ui.createScalarSpan(100, { |
| unit: Unit.byName.powerInWattsDelta, |
| customContextRange: tr.b.math.Range.fromExplicitRange(-100, 100) |
| })); |
| Polymer.dom(div).appendChild(tr.v.ui.createScalarSpan(80, { |
| unit: Unit.byName.powerInWattsDelta, |
| customContextRange: tr.b.math.Range.fromExplicitRange(-100, 100) |
| })); |
| Polymer.dom(div).appendChild(tr.v.ui.createScalarSpan(60, { |
| unit: Unit.byName.powerInWattsDelta, |
| customContextRange: tr.b.math.Range.fromExplicitRange(-100, 100) |
| })); |
| }); |
| |
| timedPerfTest('memory_scalar_spans', function() { |
| tr.v.ui.createScalarSpan(EXAMPLE_MEMORY_NUMERIC, { |
| context: EXAMPLE_MEMORY_FORMATTING_CONTEXT, |
| inline: true, |
| }); |
| }, { |
| iterations: 1000, |
| }); |
| }); |
| </script> |