github.com/hernad/nomad@v1.6.112/ui/tests/unit/components/stats-time-series-test.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 import { module, test } from 'qunit'; 7 import { setupTest } from 'ember-qunit'; 8 import moment from 'moment'; 9 import d3Format from 'd3-format'; 10 import d3TimeFormat from 'd3-time-format'; 11 import setupGlimmerComponentFactory from 'nomad-ui/tests/helpers/glimmer-factory'; 12 13 module('Unit | Component | stats-time-series', function (hooks) { 14 setupTest(hooks); 15 setupGlimmerComponentFactory(hooks, 'stats-time-series'); 16 17 const ts = (offset, resolution = 'm') => 18 moment().subtract(offset, resolution).toDate(); 19 20 const wideData = [ 21 { timestamp: ts(20), percent: 0.5 }, 22 { timestamp: ts(18), percent: 0.5 }, 23 { timestamp: ts(16), percent: 0.4 }, 24 { timestamp: ts(14), percent: 0.3 }, 25 { timestamp: ts(12), percent: 0.9 }, 26 { timestamp: ts(10), percent: 0.3 }, 27 { timestamp: ts(8), percent: 0.3 }, 28 { timestamp: ts(6), percent: 0.4 }, 29 { timestamp: ts(4), percent: 0.5 }, 30 { timestamp: ts(2), percent: 0.6 }, 31 { timestamp: ts(0), percent: 0.6 }, 32 ]; 33 34 const narrowData = [ 35 { timestamp: ts(20, 's'), percent: 0.5 }, 36 { timestamp: ts(18, 's'), percent: 0.5 }, 37 { timestamp: ts(16, 's'), percent: 0.4 }, 38 { timestamp: ts(14, 's'), percent: 0.3 }, 39 { timestamp: ts(12, 's'), percent: 0.9 }, 40 { timestamp: ts(10, 's'), percent: 0.3 }, 41 ]; 42 43 const unboundedData = [ 44 { timestamp: ts(20, 's'), percent: -0.5 }, 45 { timestamp: ts(18, 's'), percent: 1.5 }, 46 ]; 47 48 const nullData = [ 49 { timestamp: ts(20, 's'), percent: null }, 50 { timestamp: ts(18, 's'), percent: null }, 51 ]; 52 53 test('xFormat is time-formatted for hours, minutes, and seconds', function (assert) { 54 assert.expect(11); 55 56 const chart = this.createComponent({ data: wideData }); 57 58 wideData.forEach((datum) => { 59 assert.equal( 60 chart.xFormat(datum.timestamp), 61 d3TimeFormat.timeFormat('%H:%M:%S')(datum.timestamp) 62 ); 63 }); 64 }); 65 66 test('yFormat is percent-formatted', function (assert) { 67 assert.expect(11); 68 69 const chart = this.createComponent({ data: wideData }); 70 71 wideData.forEach((datum) => { 72 assert.equal( 73 chart.yFormat(datum.percent), 74 d3Format.format('.1~%')(datum.percent) 75 ); 76 }); 77 }); 78 79 test('x scale domain is at least five minutes', function (assert) { 80 const chart = this.createComponent({ data: narrowData }); 81 82 assert.equal( 83 +chart.xScale(narrowData, 0).domain()[0], 84 +moment(Math.max(...narrowData.mapBy('timestamp'))) 85 .subtract(5, 'm') 86 .toDate(), 87 'The lower bound of the xScale is 5 minutes ago' 88 ); 89 }); 90 91 test('x scale domain is greater than five minutes when the domain of the data is larger than five minutes', function (assert) { 92 const chart = this.createComponent({ data: wideData }); 93 94 assert.equal( 95 +chart.xScale(wideData, 0).domain()[0], 96 Math.min(...wideData.mapBy('timestamp')), 97 'The lower bound of the xScale is the oldest timestamp in the dataset' 98 ); 99 }); 100 101 test('y scale domain is typically 0 to 1 (0 to 100%)', function (assert) { 102 const chart = this.createComponent({ data: wideData }); 103 104 assert.deepEqual( 105 [ 106 Math.min(...wideData.mapBy('percent')), 107 Math.max(...wideData.mapBy('percent')), 108 ], 109 [0.3, 0.9], 110 'The bounds of the value prop of the dataset is narrower than 0 - 1' 111 ); 112 113 assert.deepEqual( 114 chart.yScale(wideData, 0).domain(), 115 [0, 1], 116 'The bounds of the yScale are still 0 and 1' 117 ); 118 }); 119 120 test('the extent of the y domain overrides the default 0 to 1 domain when there are values beyond these bounds', function (assert) { 121 const chart = this.createComponent({ data: unboundedData }); 122 123 assert.deepEqual( 124 chart.yScale(unboundedData, 0).domain(), 125 [-0.5, 1.5], 126 'The bounds of the yScale match the bounds of the unbounded data' 127 ); 128 129 chart.args.data = [unboundedData[0]]; 130 131 assert.deepEqual( 132 chart.yScale(chart.args.data, 0).domain(), 133 [-0.5, 1], 134 'The upper bound is still the default 1, but the lower bound is overridden due to the unbounded low value' 135 ); 136 137 chart.args.data = [unboundedData[1]]; 138 139 assert.deepEqual( 140 chart.yScale(chart.args.data, 0).domain(), 141 [0, 1.5], 142 'The lower bound is still the default 0, but the upper bound is overridden due to the unbounded high value' 143 ); 144 }); 145 146 test('when there are only empty frames in the data array, the default y domain is used', function (assert) { 147 const chart = this.createComponent({ data: nullData }); 148 149 assert.deepEqual( 150 chart.yScale(nullData, 0).domain(), 151 [0, 1], 152 'The bounds are 0 and 1' 153 ); 154 }); 155 });