@grafana/data#LoadingState TypeScript Examples

The following examples show how to use @grafana/data#LoadingState. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PanelChromeAngular.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
onPanelDataUpdate(data: PanelData) {
    let errorMessage: string | undefined;

    if (data.state === LoadingState.Error) {
      const { error } = data;
      if (error) {
        if (errorMessage !== error.message) {
          errorMessage = error.message;
        }
      }
    }

    this.setState({ data, errorMessage });
  }
Example #2
Source File: dropZone.test.tsx    From grafana-weathermap-panel with Apache License 2.0 5 votes vote down vote up
// import { PointClass } from 'Models/PointClass';
// import { RegionClass } from 'Models/RegionClass';
// import { OrientedLinkClass } from 'Models/OrientedLinkClass';

describe('waiting test', () => {
  let container: any, component: any;
  const additionalStep = { value: '1', label: '1' };
  let testProps = {};

  const mockFunctions = {
    onOptionsChange: (options: SimpleOptions, callback?: () => void) => {
      let testProps = {};
      act(() => {
        ReactDOM.render(
          <DropZone onOptionsChange={component} options={component} data={component} ref={(c) => (component = c)} {...testProps} />,
          container
        );
      });
    },
  };
  beforeEach(() => {
    const clonedDefaults = JSON.parse(JSON.stringify(defaults));
    clonedDefaults.listStep[1] = JSON.parse(JSON.stringify(additionalStep));
    clonedDefaults.promTargets = ['test'];
    container = document.createElement('div');
    document.body.appendChild(container);
    testProps = {
      options: clonedDefaults,
      onOptionsChange: mockFunctions.onOptionsChange,
      data: {
        state: LoadingState.Done,
        series: [
          {
            name: 'serieName',
            fields: [],
            length: 15,
          },
        ],
        timeRange: clonedDefaults.timeRange,
      },
    };

    act(() => {
      ReactDOM.render(
        <DropZone onOptionsChange={component} options={component} data={component} ref={(c) => (component = c)} {...testProps} />,
        container
      );
    });
  });

  describe('save', () => {
    test('region', (done) => {
      setTimeout(() => {
        //expect(result).toStrictEqual(expected);
        done();
      });
    });
  });
});
Example #3
Source File: runRequest.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
/*
 * This function should handle composing a PanelData from multiple responses
 */
export function processResponsePacket(packet: DataQueryResponse, state: RunningQueryState): RunningQueryState {
  const request = state.panelData.request;
  const packets: MapOfResponsePackets = {
    ...state.packets,
  };

  packets[packet.key || 'A'] = packet;

  let loadingState = packet.state || LoadingState.Done;
  let error: DataQueryError | undefined = undefined;

  // Update the time range
  const range = { ...request.range };
  const timeRange = isString(range.raw.from)
    ? {
        from: dateMath.parse(range.raw.from, false),
        to: dateMath.parse(range.raw.to, true),
        raw: range.raw,
      }
    : range;

  const combinedData = flatten(
    lodashMap(packets, (packet: DataQueryResponse) => {
      if (packet.error) {
        loadingState = LoadingState.Error;
        error = packet.error;
      }
      return packet.data;
    })
  );

  const panelData = {
    state: loadingState,
    series: combinedData,
    error,
    request,
    timeRange,
  };

  return { packets, panelData };
}
Example #4
Source File: addCoordinate.test.tsx    From grafana-weathermap-panel with Apache License 2.0 4 votes vote down vote up
// /*
//  * testing the AddCoordinate component features
//  * - add coordinates
//  * - edit coordinates parameters
//  */
describe('AddCoordinate tests', () => {
  let container: any, component: any, coordinates: any;
  const additionalStep = { value: '1', label: '1' };
  /*
   * Mock "onOptionChange" by re-rendering the component with the new options
   */
  let mockFunctions = {
    onOptionsChange: (options: SimpleOptions, callback?: () => void) => {
      let testProps = {};
      act(() => {
        ReactDOM.render(
          <AddCoordinate
            data={component}
            options={component}
            onOptionsChange={component}
            isLink={component}
            isPoint={component}
            isRegion={component}
            ref={(c) => (component = c)}
            {...testProps}
          />,
          container
        );
      });
    },
  };
  let testProps = {};
  beforeEach(() => {
    // testTextObjectClass = new TextObject('legend', true, 'value', 'unit', 'colbr', 'coltxtr', 'ctyletxtr', 'colbackbu');
    // parametrageMetric = new ParametrageMetrique('', '', '');
    coordinates = [
      // new CoordinateSpaceExtendClass(
      //   0,
      //   '-10',
      //   '10',
      //   '-20',
      //   '20',
      //   'test-label',
      //   'test.png',
      //   'test-interface',
      //   testTextObjectClass,
      //   parametrageMetric,
      //   'key0',
      //   'valkey0'
      // ),
      // new CoordinateSpaceExtendClass(
      //   1,
      //   '-10',
      //   '10',
      //   '-20',
      //   '20',
      //   'test-label',
      //   'test.png',
      //   'test-interface',
      //   testTextObjectClass,
      //   parametrageMetric,
      //   'key1',
      //   'valkey1'
      // ),
    ];

    let clonedDefaults = JSON.parse(JSON.stringify(defaults));
    clonedDefaults.listStep[1] = JSON.parse(JSON.stringify(additionalStep));
    container = document.createElement('div');
    console.log('container: ', container);
    document.body.appendChild(container);
    testProps = {
      options: clonedDefaults,
      onOptionsChange: mockFunctions.onOptionsChange,
      data: {
        state: LoadingState.Done,
        series: [
          {
            name: 'serieName',
            fields: [],
            length: 15,
          },
        ],
        timeRange: clonedDefaults.timeRange,
      },
    };
    act(() => {
      ReactDOM.render(
        <AddCoordinate
          data={component}
          options={component}
          onOptionsChange={component}
          isLink={component}
          isPoint={component}
          isRegion={component}
          ref={(c) => (component = c)}
          {...testProps}
        />,
        container
      );
    });
  });

  afterEach(() => {
    console.log('container: ', container);

    document.body.removeChild(container);
    container = null;
    component = null;
    coordinates = [];
    jest.clearAllMocks();
  });

  test('search new id', () => {
    expect(component.searchNewId(coordinates)).toBe(0);
  });
});
Example #5
Source File: datasource.test.ts    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
describe('PrometheusDatasource', () => {
  let ds: PrometheusDatasource;
  const instanceSettings = ({
    url: 'proxied',
    directUrl: 'direct',
    user: 'test',
    password: 'mupp',
    jsonData: {} as any,
  } as unknown) as DataSourceInstanceSettings<PromOptions>;

  beforeEach(() => {
    ds = new PrometheusDatasource(instanceSettings);
  });

  describe('Query', () => {
    it('returns empty array when no queries', done => {
      expect.assertions(2);

      ds.query(createDataRequest([])).subscribe({
        next(next) {
          expect(next.data).toEqual([]);
          expect(next.state).toBe(LoadingState.Done);
        },
        complete() {
          done();
        },
      });
    });

    it('performs time series queries', done => {
      expect.assertions(2);

      ds.query(createDataRequest([{}])).subscribe({
        next(next) {
          expect(next.data.length).not.toBe(0);
          expect(next.state).toBe(LoadingState.Done);
        },
        complete() {
          done();
        },
      });
    });

    it('with 2 queries and used from Explore, sends results as they arrive', done => {
      expect.assertions(4);

      const responseStatus = [LoadingState.Loading, LoadingState.Done];
      ds.query(createDataRequest([{}, {}], { app: CoreApp.Explore })).subscribe({
        next(next) {
          expect(next.data.length).not.toBe(0);
          expect(next.state).toBe(responseStatus.shift());
        },
        complete() {
          done();
        },
      });
    });

    it('with 2 queries and used from Panel, waits for all to finish until sending Done status', done => {
      expect.assertions(2);
      ds.query(createDataRequest([{}, {}], { app: CoreApp.Dashboard })).subscribe({
        next(next) {
          expect(next.data.length).not.toBe(0);
          expect(next.state).toBe(LoadingState.Done);
        },
        complete() {
          done();
        },
      });
    });
  });

  describe('Datasource metadata requests', () => {
    it('should perform a GET request with the default config', () => {
      ds.metadataRequest('/foo');
      expect(datasourceRequestMock.mock.calls.length).toBe(1);
      expect(datasourceRequestMock.mock.calls[0][0].method).toBe('GET');
    });

    it('should still perform a GET request with the DS HTTP method set to POST', () => {
      const postSettings = _.cloneDeep(instanceSettings);
      postSettings.jsonData.httpMethod = 'POST';
      const promDs = new PrometheusDatasource(postSettings);
      promDs.metadataRequest('/foo');
      expect(datasourceRequestMock.mock.calls.length).toBe(1);
      expect(datasourceRequestMock.mock.calls[0][0].method).toBe('GET');
    });
  });

  describe('When using adhoc filters', () => {
    const DEFAULT_QUERY_EXPRESSION = 'metric{job="foo"} - metric';
    const target = { expr: DEFAULT_QUERY_EXPRESSION };
    const originalAdhocFiltersMock = getAdhocFiltersMock();

    afterAll(() => {
      getAdhocFiltersMock.mockReturnValue(originalAdhocFiltersMock);
    });

    it('should not modify expression with no filters', () => {
      const result = ds.createQuery(target as any, { interval: '15s' } as any, 0, 0);
      expect(result).toMatchObject({ expr: DEFAULT_QUERY_EXPRESSION });
    });

    it('should add filters to expression', () => {
      getAdhocFiltersMock.mockReturnValue([
        {
          key: 'k1',
          operator: '=',
          value: 'v1',
        },
        {
          key: 'k2',
          operator: '!=',
          value: 'v2',
        },
      ]);
      const result = ds.createQuery(target as any, { interval: '15s' } as any, 0, 0);
      expect(result).toMatchObject({ expr: 'metric{job="foo",k1="v1",k2!="v2"} - metric{k1="v1",k2!="v2"}' });
    });

    it('should add escaping if needed to regex filter expressions', () => {
      getAdhocFiltersMock.mockReturnValue([
        {
          key: 'k1',
          operator: '=~',
          value: 'v.*',
        },
        {
          key: 'k2',
          operator: '=~',
          value: `v'.*`,
        },
      ]);
      const result = ds.createQuery(target as any, { interval: '15s' } as any, 0, 0);
      expect(result).toMatchObject({
        expr: `metric{job="foo",k1=~"v.*",k2=~"v\\\\'.*"} - metric{k1=~"v.*",k2=~"v\\\\'.*"}`,
      });
    });
  });

  describe('When performing performSuggestQuery', () => {
    it('should cache response', async () => {
      datasourceRequestMock.mockImplementation(() =>
        Promise.resolve({
          status: 'success',
          data: { data: ['value1', 'value2', 'value3'] },
        })
      );

      let results = await ds.performSuggestQuery('value', true);

      expect(results).toHaveLength(3);

      datasourceRequestMock.mockImplementation(jest.fn());
      results = await ds.performSuggestQuery('value', true);

      expect(results).toHaveLength(3);
    });
  });

  describe('When converting prometheus histogram to heatmap format', () => {
    let query: any;
    beforeEach(() => {
      query = {
        range: { from: dateTime(1443454528000), to: dateTime(1443454528000) },
        targets: [{ expr: 'test{job="testjob"}', format: 'heatmap', legendFormat: '{{le}}' }],
        interval: '1s',
      };
    });

    it('should convert cumullative histogram to ordinary', () => {
      const resultMock = [
        {
          metric: { __name__: 'metric', job: 'testjob', le: '10' },
          values: [
            [1443454528.0, '10'],
            [1443454528.0, '10'],
          ],
        },
        {
          metric: { __name__: 'metric', job: 'testjob', le: '20' },
          values: [
            [1443454528.0, '20'],
            [1443454528.0, '10'],
          ],
        },
        {
          metric: { __name__: 'metric', job: 'testjob', le: '30' },
          values: [
            [1443454528.0, '25'],
            [1443454528.0, '10'],
          ],
        },
      ];
      const responseMock = { data: { data: { result: resultMock } } };

      const expected = [
        {
          target: '10',
          datapoints: [
            [10, 1443454528000],
            [10, 1443454528000],
          ],
        },
        {
          target: '20',
          datapoints: [
            [10, 1443454528000],
            [0, 1443454528000],
          ],
        },
        {
          target: '30',
          datapoints: [
            [5, 1443454528000],
            [0, 1443454528000],
          ],
        },
      ];

      ds.performTimeSeriesQuery = jest.fn().mockReturnValue([responseMock]);
      ds.query(query).subscribe((result: any) => {
        const results = result.data;
        return expect(results).toMatchObject(expected);
      });
    });

    it('should sort series by label value', () => {
      const resultMock = [
        {
          metric: { __name__: 'metric', job: 'testjob', le: '2' },
          values: [
            [1443454528.0, '10'],
            [1443454528.0, '10'],
          ],
        },
        {
          metric: { __name__: 'metric', job: 'testjob', le: '4' },
          values: [
            [1443454528.0, '20'],
            [1443454528.0, '10'],
          ],
        },
        {
          metric: { __name__: 'metric', job: 'testjob', le: '+Inf' },
          values: [
            [1443454528.0, '25'],
            [1443454528.0, '10'],
          ],
        },
        {
          metric: { __name__: 'metric', job: 'testjob', le: '1' },
          values: [
            [1443454528.0, '25'],
            [1443454528.0, '10'],
          ],
        },
      ];
      const responseMock = { data: { data: { result: resultMock } } };

      const expected = ['1', '2', '4', '+Inf'];

      ds.performTimeSeriesQuery = jest.fn().mockReturnValue([responseMock]);
      ds.query(query).subscribe((result: any) => {
        const seriesLabels = _.map(result.data, 'target');
        return expect(seriesLabels).toEqual(expected);
      });
    });
  });

  describe('alignRange', () => {
    it('does not modify already aligned intervals with perfect step', () => {
      const range = alignRange(0, 3, 3, 0);
      expect(range.start).toEqual(0);
      expect(range.end).toEqual(3);
    });

    it('does modify end-aligned intervals to reflect number of steps possible', () => {
      const range = alignRange(1, 6, 3, 0);
      expect(range.start).toEqual(0);
      expect(range.end).toEqual(6);
    });

    it('does align intervals that are a multiple of steps', () => {
      const range = alignRange(1, 4, 3, 0);
      expect(range.start).toEqual(0);
      expect(range.end).toEqual(3);
    });

    it('does align intervals that are not a multiple of steps', () => {
      const range = alignRange(1, 5, 3, 0);
      expect(range.start).toEqual(0);
      expect(range.end).toEqual(3);
    });

    it('does align intervals with local midnight -UTC offset', () => {
      //week range, location 4+ hours UTC offset, 24h step time
      const range = alignRange(4 * 60 * 60, (7 * 24 + 4) * 60 * 60, 24 * 60 * 60, -4 * 60 * 60); //04:00 UTC, 7 day range
      expect(range.start).toEqual(4 * 60 * 60);
      expect(range.end).toEqual((7 * 24 + 4) * 60 * 60);
    });

    it('does align intervals with local midnight +UTC offset', () => {
      //week range, location 4- hours UTC offset, 24h step time
      const range = alignRange(20 * 60 * 60, (8 * 24 - 4) * 60 * 60, 24 * 60 * 60, 4 * 60 * 60); //20:00 UTC on day1, 7 days later is 20:00 on day8
      expect(range.start).toEqual(20 * 60 * 60);
      expect(range.end).toEqual((8 * 24 - 4) * 60 * 60);
    });
  });

  describe('extractRuleMappingFromGroups()', () => {
    it('returns empty mapping for no rule groups', () => {
      expect(extractRuleMappingFromGroups([])).toEqual({});
    });

    it('returns a mapping for recording rules only', () => {
      const groups = [
        {
          rules: [
            {
              name: 'HighRequestLatency',
              query: 'job:request_latency_seconds:mean5m{job="myjob"} > 0.5',
              type: 'alerting',
            },
            {
              name: 'job:http_inprogress_requests:sum',
              query: 'sum(http_inprogress_requests) by (job)',
              type: 'recording',
            },
          ],
          file: '/rules.yaml',
          interval: 60,
          name: 'example',
        },
      ];
      const mapping = extractRuleMappingFromGroups(groups);
      expect(mapping).toEqual({ 'job:http_inprogress_requests:sum': 'sum(http_inprogress_requests) by (job)' });
    });
  });

  describe('Prometheus regular escaping', () => {
    it('should not escape non-string', () => {
      expect(prometheusRegularEscape(12)).toEqual(12);
    });

    it('should not escape simple string', () => {
      expect(prometheusRegularEscape('cryptodepression')).toEqual('cryptodepression');
    });

    it("should escape '", () => {
      expect(prometheusRegularEscape("looking'glass")).toEqual("looking\\\\'glass");
    });

    it('should escape multiple characters', () => {
      expect(prometheusRegularEscape("'looking'glass'")).toEqual("\\\\'looking\\\\'glass\\\\'");
    });
  });

  describe('Prometheus regexes escaping', () => {
    it('should not escape simple string', () => {
      expect(prometheusSpecialRegexEscape('cryptodepression')).toEqual('cryptodepression');
    });

    it('should escape $^*+?.()|\\', () => {
      expect(prometheusSpecialRegexEscape("looking'glass")).toEqual("looking\\\\'glass");
      expect(prometheusSpecialRegexEscape('looking{glass')).toEqual('looking\\\\{glass');
      expect(prometheusSpecialRegexEscape('looking}glass')).toEqual('looking\\\\}glass');
      expect(prometheusSpecialRegexEscape('looking[glass')).toEqual('looking\\\\[glass');
      expect(prometheusSpecialRegexEscape('looking]glass')).toEqual('looking\\\\]glass');
      expect(prometheusSpecialRegexEscape('looking$glass')).toEqual('looking\\\\$glass');
      expect(prometheusSpecialRegexEscape('looking^glass')).toEqual('looking\\\\^glass');
      expect(prometheusSpecialRegexEscape('looking*glass')).toEqual('looking\\\\*glass');
      expect(prometheusSpecialRegexEscape('looking+glass')).toEqual('looking\\\\+glass');
      expect(prometheusSpecialRegexEscape('looking?glass')).toEqual('looking\\\\?glass');
      expect(prometheusSpecialRegexEscape('looking.glass')).toEqual('looking\\\\.glass');
      expect(prometheusSpecialRegexEscape('looking(glass')).toEqual('looking\\\\(glass');
      expect(prometheusSpecialRegexEscape('looking)glass')).toEqual('looking\\\\)glass');
      expect(prometheusSpecialRegexEscape('looking\\glass')).toEqual('looking\\\\\\\\glass');
      expect(prometheusSpecialRegexEscape('looking|glass')).toEqual('looking\\\\|glass');
    });

    it('should escape multiple special characters', () => {
      expect(prometheusSpecialRegexEscape('+looking$glass?')).toEqual('\\\\+looking\\\\$glass\\\\?');
    });
  });

  describe('When interpolating variables', () => {
    let customVariable: CustomVariable;
    beforeEach(() => {
      customVariable = new CustomVariable({}, {} as any);
    });

    describe('and value is a string', () => {
      it('should only escape single quotes', () => {
        expect(ds.interpolateQueryExpr("abc'$^*{}[]+?.()|", customVariable)).toEqual("abc\\\\'$^*{}[]+?.()|");
      });
    });

    describe('and value is a number', () => {
      it('should return a number', () => {
        expect(ds.interpolateQueryExpr(1000 as any, customVariable)).toEqual(1000);
      });
    });

    describe('and variable allows multi-value', () => {
      beforeEach(() => {
        customVariable.multi = true;
      });

      it('should regex escape values if the value is a string', () => {
        expect(ds.interpolateQueryExpr('looking*glass', customVariable)).toEqual('looking\\\\*glass');
      });

      it('should return pipe separated values if the value is an array of strings', () => {
        expect(ds.interpolateQueryExpr(['a|bc', 'de|f'], customVariable)).toEqual('a\\\\|bc|de\\\\|f');
      });
    });

    describe('and variable allows all', () => {
      beforeEach(() => {
        customVariable.includeAll = true;
      });

      it('should regex escape values if the array is a string', () => {
        expect(ds.interpolateQueryExpr('looking*glass', customVariable)).toEqual('looking\\\\*glass');
      });

      it('should return pipe separated values if the value is an array of strings', () => {
        expect(ds.interpolateQueryExpr(['a|bc', 'de|f'], customVariable)).toEqual('a\\\\|bc|de\\\\|f');
      });
    });
  });

  describe('metricFindQuery', () => {
    beforeEach(() => {
      const query = 'query_result(topk(5,rate(http_request_duration_microseconds_count[$__interval])))';
      replaceMock.mockImplementation(jest.fn);
      ds.metricFindQuery(query);
    });

    afterAll(() => {
      replaceMock.mockImplementation((a: string) => a);
    });

    it('should call templateSrv.replace with scopedVars', () => {
      expect(replaceMock.mock.calls[0][1]).toBeDefined();
    });

    it('should have the correct range and range_ms', () => {
      const range = replaceMock.mock.calls[0][1].__range;
      const rangeMs = replaceMock.mock.calls[0][1].__range_ms;
      const rangeS = replaceMock.mock.calls[0][1].__range_s;
      expect(range).toEqual({ text: '21s', value: '21s' });
      expect(rangeMs).toEqual({ text: 21031, value: 21031 });
      expect(rangeS).toEqual({ text: 21, value: 21 });
    });

    it('should pass the default interval value', () => {
      const interval = replaceMock.mock.calls[0][1].__interval;
      const intervalMs = replaceMock.mock.calls[0][1].__interval_ms;
      expect(interval).toEqual({ text: '15s', value: '15s' });
      expect(intervalMs).toEqual({ text: 15000, value: 15000 });
    });
  });
});
Example #6
Source File: textObjects.test.tsx    From grafana-weathermap-panel with Apache License 2.0 4 votes vote down vote up
/*
 * testing the TextObjects component features
 * - edit parameters
 */
describe('TextObjects tests', () => {
  let container: any, component: any, testTextObject: TextObject;
  const additionalStep = { value: '1', label: '1' };
  let linkclass: LinkURLClass = new LinkURLClass('unlien', 'uneautrelien', 'encoreunlien');
  let lowerlimitclass: LowerLimitClass = new LowerLimitClass(1, '-10', '30', 'red', 'blue', '10px');
  testTextObject = new TextObject(
    '',
    false,
    '',
    '',
    { bold: false, italic: false, underline: false },
    false,
    {
      legendElement: '',
      numericFormatElement: '',
      unit: '',
      displayObjectInTooltip: false,
      // 'displayObjectPermanently': false,
      addColorTextElement: false,
      colorTextElement: 'white',
      addColorBackElement: false,
      colorBackElement: 'black',
    },
    {
      legendElement: '',
      numericFormatElement: '',
      unit: '',
      displayObjectInTooltip: false,
      // 'displayObjectPermanently': false,
      addColorTextElement: false,
      colorTextElement: 'white',
      addColorBackElement: false,
      colorBackElement: 'black',
    }
  );
  let metric: Metric = {
    key: 'key',
    unit: 'm',
    format: 'qw',
    keyValue: 'code',
    refId: 'A',
    expr: '',
    returnQuery: [],
    manageValue: 'avg',
  };
  let testProps = { options: {}, data: {}, onOptionsChange: {}, callBackToParent: {}, coordinateSpace: {} };
  let coordinateSpaceTest: CoordinateSpaceClass = new CoordinateSpaceClass(
    1,
    linkclass,
    '',
    [lowerlimitclass],
    'test',
    testTextObject,
    metric,
    [],
    false,
    false,
    false,
    {
      labelAPositionX: '',
      labelAPositionY: '',
      labelBPositionX: '',
      labelBPositionY: '',
      tooltipPositionA: { label: 'Left', value: 'Left' },
      tooltipPositionB: { label: 'Left', value: 'Left' },
    }
  );
  /*
   * Mock "onOptionChange" by re-rendering the component with the new options
   */
  let mockFunctions = {
    onOptionsChange: (options: SimpleOptions, callback?: () => void) => {
      testProps.options = options;
      act(() => {
        ReactDOM.render(<TextObjects ref={(c) => (component = c)} {...testProps} />, container);
      });
    },
    callBackToParent: (followLink: string, hoveringTooltipLink: string, hoveringTooltipText: string, textObj: TextObject) => {
      coordinateSpaceTest.linkURL.followLink = followLink ? followLink : coordinateSpaceTest.linkURL.followLink;
      coordinateSpaceTest.linkURL.hoveringTooltipLink = hoveringTooltipLink ? hoveringTooltipLink : coordinateSpaceTest.linkURL.hoveringTooltipLink;
      coordinateSpaceTest.linkURL.hoveringTooltipText = hoveringTooltipText ? hoveringTooltipText : coordinateSpaceTest.linkURL.hoveringTooltipText;
      coordinateSpaceTest.linkURL.hoveringTooltipText = hoveringTooltipText ? hoveringTooltipText : coordinateSpaceTest.linkURL.hoveringTooltipText;
      act(() => {
        ReactDOM.render(<TextObjects ref={(c) => (component = c)} {...testProps} />, container);
      });
    },
  };
  beforeEach(() => {
    let clonedDefaults = JSON.parse(JSON.stringify(defaults));
    testTextObject = new TextObject(
      '',
      false,
      '',
      '',
      { bold: false, italic: false, underline: false },
      false,
      {
        legendElement: '',
        numericFormatElement: '',
        unit: '',
        displayObjectInTooltip: false,
        // 'displayObjectPermanently': false,
        addColorTextElement: false,
        colorTextElement: 'white',
        addColorBackElement: false,
        colorBackElement: 'black',
      },
      {
        legendElement: '',
        numericFormatElement: '',
        unit: '',
        displayObjectInTooltip: false,
        // 'displayObjectPermanently': false,
        addColorTextElement: false,
        colorTextElement: 'white',
        addColorBackElement: false,
        colorBackElement: 'black',
      }
    );
    clonedDefaults.listStep[1] = JSON.parse(JSON.stringify(additionalStep));
    clonedDefaults.promTargets = ['test'];
    container = document.createElement('div');
    document.body.appendChild(container);
    testProps = {
      options: clonedDefaults,
      coordinateSpace: coordinateSpaceTest,
      onOptionsChange: mockFunctions.onOptionsChange,
      callBackToParent: mockFunctions.callBackToParent,
      data: {
        state: LoadingState.Done,
        series: [
          {
            name: 'serieName',
            fields: [],
            length: 15,
          },
        ],
        timeRange: clonedDefaults.timeRange,
      },
    };

    act(() => {
      ReactDOM.render(<TextObjects ref={(c) => (component = c)} {...testProps} />, container);
    });
  });

  afterEach(() => {
    document.body.removeChild(container);
    container = null;
    component = null;
    jest.clearAllMocks();
  });
  describe('testBasicOnChangeOption', () => {
    test('onChangeValeur', (done) => {
      component.onChangeValeur('testText');
      setTimeout(() => {
        expect(component.state.textObject.value).toBe('testText');
        done();
      });
    });
    test('onChangeBackColor', (done) => {
      component.onChangeBackColor(2, 'testText');
      setTimeout(() => {
        expect(component.state.textObject.colorBack).toBe('testText');
        done();
      });
    });
    test('onChangeColorText', (done) => {
      component.onChangeColorText(2, 'testText');
      setTimeout(() => {
        expect(component.state.textObject.colorText).toBe('testText');
        done();
      });
    });
    test('onChangeColorTextElement', (done) => {
      component.onChangeColorTextElement(2, 'testText');
      setTimeout(() => {
        expect(component.state.textObject.generateAuxiliaryElement.colorTextElement).toBe('testText');
        done();
      });
    });
    test('onChangeColorBackElement', (done) => {
      component.onChangeColorBackElement(2, 'testText');
      setTimeout(() => {
        expect(component.state.textObject.generateAuxiliaryElement.colorBackElement).toBe('testText');
        done();
      });
    });
    test('onChangeValueGenerateObjectTextColorTextElement', (done) => {
      component.onChangeValueGenerateObjectTextColorTextElement(2, 'testText');
      setTimeout(() => {
        expect(component.state.textObject.valueGenerateObjectText.colorTextElement).toBe('testText');
        done();
      });
    });
    test('onChangeValueGenerateObjectTextColorBackElement', (done) => {
      component.onChangeValueGenerateObjectTextColorBackElement(2, 'testText');
      setTimeout(() => {
        expect(component.state.textObject.valueGenerateObjectText.colorBackElement).toBe('testText');
        done();
      });
    });
    test('saveData', (done) => {
      component.saveData({ bold: 'false', italic: 'false', underline: 'true' });
      setTimeout(() => {
        expect(component.state.textObject.style.bold).toStrictEqual('false');
        expect(component.state.textObject.style.italic).toStrictEqual('false');
        expect(component.state.textObject.style.underline).toStrictEqual('true');
        done();
      });
    });
  });
  describe('testEventOnChangeOption', () => {
    let target = {
      value: '200',
    } as HTMLInputElement;
    let event = {
      currentTarget: target,
    };
    test('onChangeLegendElement', (done) => {
      component.onChangeLegendElement(event);
      setTimeout(() => {
        expect(component.state.textObject.generateAuxiliaryElement.legendElement).toBe('200');
        done();
      });
    });
    test('onChangeunit', (done) => {
      component.onChangeunit(event);
      setTimeout(() => {
        expect(component.state.textObject.generateAuxiliaryElement.unit).toBe('200');
        done();
      });
    });
    test('onChangeFormatageNumeriqueTextObject', (done) => {
      component.onChangeFormatageNumeriqueTextObject(event);
      setTimeout(() => {
        expect(component.state.textObject.generateAuxiliaryElement.numericFormatElement).toBe('200');
        done();
      });
    });
    test('onChangeValueGenerateObjectTextLegendElement', (done) => {
      component.onChangeValueGenerateObjectTextLegendElement(event);
      setTimeout(() => {
        expect(component.state.textObject.valueGenerateObjectText.legendElement).toBe('200');
        done();
      });
    });
    test('onChangeValueGenerateObjectTextunit', (done) => {
      component.onChangeValueGenerateObjectTextunit(event);
      setTimeout(() => {
        expect(component.state.textObject.valueGenerateObjectText.unit).toBe('200');
        done();
      });
    });
    test('onChangeValueGenerateObjectTextFormatageNumeriqueTextObject', (done) => {
      component.onChangeValueGenerateObjectTextFormatageNumeriqueTextObject(event);
      setTimeout(() => {
        expect(component.state.textObject.valueGenerateObjectText.numericFormatElement).toBe('200');
        done();
      });
    });
  });
  describe('testonSwitch', () => {
    // let target = {
    //   value: '200',
    // } as HTMLInputElement;
    // let event = {
    //   currentTarget: target,
    // };
    let save: any = testTextObject.generateObjectText;
    test('onSwitchGenerateObjectText', (done) => {
      component.onSwitchGenerateObjectText();
      setTimeout(() => {
        expect(component.state.textObject.generateObjectText).toBe(!save.generateObjectText);
        done();
      });
    });
    save = testTextObject.generateAuxiliaryElement.displayObjectInTooltip;
    test('onSwitchdisplayObjectInTooltip', (done) => {
      component.onSwitchdisplayObjectInTooltip();
      setTimeout(() => {
        expect(component.state.textObject.generateAuxiliaryElement.displayObjectInTooltip).toBe(!save);
        done();
      });
    });
    save = testTextObject.generateAuxiliaryElement.addColorTextElement;
    test('onSwitchAddColorTextElement', (done) => {
      component.onSwitchAddColorTextElement();
      setTimeout(() => {
        expect(component.state.textObject.generateAuxiliaryElement.addColorTextElement).toBe(!save);
        done();
      });
    });
    save = testTextObject.generateAuxiliaryElement.addColorTextElement;
    test('onSwitchAddColorBackElement', (done) => {
      component.onSwitchAddColorBackElement();
      setTimeout(() => {
        expect(component.state.textObject.generateAuxiliaryElement.addColorBackElement).toBe(!save);
        done();
      });
    });
    save = testTextObject.generateAuxiliaryElement.addColorTextElement;
    test('onSwitchisTextTooltip', (done) => {
      component.onSwitchisTextTooltip();
      setTimeout(() => {
        expect(component.state.textObject.isTextTooltip).toBe(!save);
        done();
      });
    });
    save = testTextObject.valueGenerateObjectText.displayObjectInTooltip;
    test('onSwitchValueGenerateObjectTextdisplayObjectInTooltip', (done) => {
      component.onSwitchValueGenerateObjectTextdisplayObjectInTooltip();
      setTimeout(() => {
        expect(component.state.textObject.valueGenerateObjectText.displayObjectInTooltip).toBe(!save);
        done();
      });
    });
    save = testTextObject.valueGenerateObjectText.addColorTextElement;
    test('onSwitchValueGenerateObjectTextAddColorTextElement', (done) => {
      component.onSwitchValueGenerateObjectTextAddColorTextElement();
      setTimeout(() => {
        expect(component.state.textObject.valueGenerateObjectText.addColorTextElement).toBe(!save);
        done();
      });
    });
    save = testTextObject.valueGenerateObjectText.addColorBackElement;
    test('onSwitchValueGenerateObjectTextAddColorBackElement', (done) => {
      component.onSwitchValueGenerateObjectTextAddColorBackElement();
      setTimeout(() => {
        expect(component.state.textObject.valueGenerateObjectText.addColorBackElement).toBe(!save);
        done();
      });
    });
  });
  // test('Have to fill the returnQuery', done => {
  //   reqUpdateMetrics(propsAB);
  //   setTimeout(() => {
  //     expect(propsAB.options.regionCoordinateSpace[0].mainMetric.returnQuery).toStrictEqual(result);
  //     expect(propsAB.options.regionCoordinateSpace[0].metrics[0].returnQuery).toEqual(result);
  //     expect(propsAB.options.regionCoordinateSpace[0].metrics[1].returnQuery).toEqual(result);
  //     expect(propsAB.options.arrayPoints[0].mainMetric.returnQuery).toStrictEqual(result);
  //     expect(propsAB.options.arrayPoints[0].metrics[0].returnQuery).toEqual(result);
  //     expect(propsAB.options.arrayPoints[0].metrics[1].returnQuery).toEqual(result);
  //     expect(propsAB.options.arrayOrientedLinks[0].mainMetric.returnQuery).toStrictEqual(result);
  //     expect(propsAB.options.arrayOrientedLinks[0].metrics[0].returnQuery).toEqual(result);
  //     expect(propsAB.options.arrayOrientedLinks[0].metrics[1].returnQuery).toEqual(result);
  //     done();
  //   });
  // });
});
Example #7
Source File: runRequest.test.ts    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
describe('runRequest', () => {
  runRequestScenario('with no queries', ctx => {
    ctx.setup(() => {
      ctx.request.targets = [];
      ctx.start();
    });

    it('should emit empty result with loading state done', () => {
      expect(ctx.wasStarted).toBe(false);
      expect(ctx.results[0].state).toBe(LoadingState.Done);
    });
  });

  runRequestScenario('After first response', ctx => {
    ctx.setup(() => {
      ctx.start();
      ctx.emitPacket({
        data: [{ name: 'Data' } as DataFrame],
      });
    });

    it('should emit single result with loading state done', () => {
      expect(ctx.wasStarted).toBe(true);
      expect(ctx.results.length).toBe(1);
    });
  });

  runRequestScenario('After tree responses, 2 with different keys', ctx => {
    ctx.setup(() => {
      ctx.start();
      ctx.emitPacket({
        data: [{ name: 'DataA-1' } as DataFrame],
        key: 'A',
      });
      ctx.emitPacket({
        data: [{ name: 'DataA-2' } as DataFrame],
        key: 'A',
      });
      ctx.emitPacket({
        data: [{ name: 'DataB-1' } as DataFrame],
        key: 'B',
      });
    });

    it('should emit 3 seperate results', () => {
      expect(ctx.results.length).toBe(3);
    });

    it('should combine results and return latest data for key A', () => {
      expect(ctx.results[2].series).toEqual([{ name: 'DataA-2' }, { name: 'DataB-1' }]);
    });

    it('should have loading state Done', () => {
      expect(ctx.results[2].state).toEqual(LoadingState.Done);
    });
  });

  runRequestScenario('After response with state Streaming', ctx => {
    ctx.setup(() => {
      ctx.start();
      ctx.emitPacket({
        data: [{ name: 'DataA-1' } as DataFrame],
        key: 'A',
      });
      ctx.emitPacket({
        data: [{ name: 'DataA-2' } as DataFrame],
        key: 'A',
        state: LoadingState.Streaming,
      });
    });

    it('should have loading state Streaming', () => {
      expect(ctx.results[1].state).toEqual(LoadingState.Streaming);
    });
  });

  runRequestScenario('If no response after 250ms', ctx => {
    ctx.setup(async () => {
      ctx.start();
      await sleep(250);
    });

    it('should emit 1 result with loading state', () => {
      expect(ctx.results.length).toBe(1);
      expect(ctx.results[0].state).toBe(LoadingState.Loading);
    });
  });

  runRequestScenario('on thrown error', ctx => {
    ctx.setup(() => {
      ctx.error = new Error('Ohh no');
      ctx.start();
    });

    it('should emit 1 error result', () => {
      expect(ctx.results[0].error.message).toBe('Ohh no');
      expect(ctx.results[0].state).toBe(LoadingState.Error);
    });
  });

  runRequestScenario('If time range is relative', ctx => {
    ctx.setup(async () => {
      // any changes to ctx.request.range will throw and state would become LoadingState.Error
      deepFreeze(ctx.request.range);
      ctx.start();

      // wait a bit
      await sleep(20);

      ctx.emitPacket({ data: [{ name: 'DataB-1' } as DataFrame] });
    });

    it('should add the correct timeRange property and the request range should not be mutated', () => {
      expect(ctx.results[0].timeRange.to.valueOf()).toBeDefined();
      expect(ctx.results[0].timeRange.to.valueOf()).not.toBe(ctx.toStartTime.valueOf());
      expect(ctx.results[0].timeRange.to.valueOf()).not.toBe(ctx.results[0].request.range.to.valueOf());

      expectThatRangeHasNotMutated(ctx);
    });
  });

  runRequestScenario('If time range is not relative', ctx => {
    ctx.setup(async () => {
      ctx.request.range.raw.from = ctx.fromStartTime;
      ctx.request.range.raw.to = ctx.toStartTime;
      // any changes to ctx.request.range will throw and state would become LoadingState.Error
      deepFreeze(ctx.request.range);
      ctx.start();

      // wait a bit
      await sleep(20);

      ctx.emitPacket({ data: [{ name: 'DataB-1' } as DataFrame] });
    });

    it('should add the correct timeRange property and the request range should not be mutated', () => {
      expect(ctx.results[0].timeRange).toBeDefined();
      expect(ctx.results[0].timeRange.to.valueOf()).toBe(ctx.toStartTime.valueOf());
      expect(ctx.results[0].timeRange.to.valueOf()).toBe(ctx.results[0].request.range.to.valueOf());

      expectThatRangeHasNotMutated(ctx);
    });
  });
});