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  });