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