github.com/aminovpavel/nomad@v0.11.8/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 7 module('Unit | Component | stats-time-series', function(hooks) { 8 setupTest(hooks); 9 10 const ts = (offset, resolution = 'm') => 11 moment() 12 .subtract(offset, resolution) 13 .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 const chart = this.owner.factoryFor('component:stats-time-series').create(); 50 51 chart.set('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 const chart = this.owner.factoryFor('component:stats-time-series').create(); 63 64 chart.set('data', wideData); 65 66 wideData.forEach(datum => { 67 assert.equal(chart.yFormat()(datum.percent), d3Format.format('.1~%')(datum.percent)); 68 }); 69 }); 70 71 test('x scale domain is at least five minutes', function(assert) { 72 const chart = this.owner.factoryFor('component:stats-time-series').create(); 73 74 chart.set('data', narrowData); 75 76 assert.equal( 77 +chart.get('xScale').domain()[0], 78 +moment(Math.max(...narrowData.mapBy('timestamp'))) 79 .subtract(5, 'm') 80 .toDate(), 81 'The lower bound of the xScale is 5 minutes ago' 82 ); 83 }); 84 85 test('x scale domain is greater than five minutes when the domain of the data is larger than five minutes', function(assert) { 86 const chart = this.owner.factoryFor('component:stats-time-series').create(); 87 88 chart.set('data', wideData); 89 90 assert.equal( 91 +chart.get('xScale').domain()[0], 92 Math.min(...wideData.mapBy('timestamp')), 93 'The lower bound of the xScale is the oldest timestamp in the dataset' 94 ); 95 }); 96 97 test('y scale domain is typically 0 to 1 (0 to 100%)', function(assert) { 98 const chart = this.owner.factoryFor('component:stats-time-series').create(); 99 100 chart.set('data', wideData); 101 102 assert.deepEqual( 103 [Math.min(...wideData.mapBy('percent')), Math.max(...wideData.mapBy('percent'))], 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.get('yScale').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.owner.factoryFor('component:stats-time-series').create(); 117 118 chart.set('data', unboundedData); 119 120 assert.deepEqual( 121 chart.get('yScale').domain(), 122 [-0.5, 1.5], 123 'The bounds of the yScale match the bounds of the unbounded data' 124 ); 125 126 chart.set('data', [unboundedData[0]]); 127 128 assert.deepEqual( 129 chart.get('yScale').domain(), 130 [-0.5, 1], 131 'The upper bound is still the default 1, but the lower bound is overridden due to the unbounded low value' 132 ); 133 134 chart.set('data', [unboundedData[1]]); 135 136 assert.deepEqual( 137 chart.get('yScale').domain(), 138 [0, 1.5], 139 'The lower bound is still the default 0, but the upper bound is overridden due to the unbounded high value' 140 ); 141 }); 142 143 test('when there are only empty frames in the data array, the default y domain is used', function(assert) { 144 const chart = this.owner.factoryFor('component:stats-time-series').create(); 145 146 chart.set('data', nullData); 147 148 assert.deepEqual(chart.get('yScale').domain(), [0, 1], 'The bounds are 0 and 1'); 149 }); 150 });