| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- import {
- DatasourceType,
- supersetTheme,
- TimeGranularity,
- VizType,
- } from '@superset-ui/core';
- import transformProps from '../../src/BigNumber/BigNumberWithTrendline/transformProps';
- import {
- BigNumberDatum,
- BigNumberWithTrendlineChartProps,
- BigNumberWithTrendlineFormData,
- } from '../../src/BigNumber/types';
- const formData = {
- metric: 'value',
- colorPicker: {
- r: 0,
- g: 122,
- b: 135,
- a: 1,
- },
- compareLag: 1,
- timeGrainSqla: TimeGranularity.QUARTER,
- granularitySqla: 'ds',
- compareSuffix: 'over last quarter',
- viz_type: VizType.BigNumber,
- yAxisFormat: '.3s',
- datasource: 'test_datasource',
- };
- const rawFormData: BigNumberWithTrendlineFormData = {
- colorPicker: { b: 0, g: 0, r: 0 },
- datasource: '1__table',
- metric: 'value',
- color_picker: {
- r: 0,
- g: 122,
- b: 135,
- a: 1,
- },
- compare_lag: 1,
- time_grain_sqla: TimeGranularity.QUARTER,
- granularity_sqla: 'ds',
- compare_suffix: 'over last quarter',
- viz_type: VizType.BigNumber,
- y_axis_format: '.3s',
- };
- function generateProps(
- data: BigNumberDatum[],
- extraFormData = {},
- extraQueryData: any = {},
- ): BigNumberWithTrendlineChartProps {
- return {
- width: 200,
- height: 500,
- annotationData: {},
- datasource: {
- id: 0,
- name: '',
- type: DatasourceType.Table,
- columns: [],
- metrics: [],
- columnFormats: {},
- verboseMap: {},
- },
- rawDatasource: {},
- rawFormData,
- hooks: {},
- initialValues: {},
- formData: {
- ...formData,
- ...extraFormData,
- },
- queriesData: [
- {
- data,
- ...extraQueryData,
- },
- ],
- ownState: {},
- filterState: {},
- behaviors: [],
- theme: supersetTheme,
- };
- }
- describe('BigNumberWithTrendline', () => {
- const props = generateProps(
- [
- {
- __timestamp: 0,
- value: 1.2345,
- },
- {
- __timestamp: 100,
- value: null,
- },
- ],
- { showTrendLine: true },
- );
- describe('transformProps()', () => {
- it('should fallback and format time', () => {
- const transformed = transformProps(props);
- // the first item is the last item sorted by __timestamp
- const lastDatum = transformed.trendLineData?.pop();
- // should use last available value
- expect(lastDatum?.[0]).toStrictEqual(100);
- expect(lastDatum?.[1]).toBeNull();
- // should get the last non-null value
- expect(transformed.bigNumber).toStrictEqual(1.2345);
- // bigNumberFallback is only set when bigNumber is null after aggregation
- expect(transformed.bigNumberFallback).toBeNull();
- // should successfully formatTime by granularity
- // @ts-ignore
- expect(transformed.formatTime(new Date('2020-01-01'))).toStrictEqual(
- '2020-01-01 00:00:00',
- );
- });
- it('should respect datasource d3 format', () => {
- const propsWithDatasource = {
- ...props,
- datasource: {
- ...props.datasource,
- metrics: [
- {
- label: 'value',
- metric_name: 'value',
- d3format: '.2f',
- uuid: '1',
- },
- ],
- },
- };
- const transformed = transformProps(propsWithDatasource);
- // @ts-ignore
- expect(transformed.headerFormatter(transformed.bigNumber)).toStrictEqual(
- '1.23',
- );
- });
- it('should format with datasource currency', () => {
- const propsWithDatasource = {
- ...props,
- datasource: {
- ...props.datasource,
- currencyFormats: {
- value: { symbol: 'USD', symbolPosition: 'prefix' },
- },
- metrics: [
- {
- label: 'value',
- metric_name: 'value',
- d3format: '.2f',
- currency: { symbol: 'USD', symbolPosition: 'prefix' },
- uuid: '1',
- },
- ],
- },
- };
- const transformed = transformProps(propsWithDatasource);
- // @ts-ignore
- expect(transformed.headerFormatter(transformed.bigNumber)).toStrictEqual(
- '$ 1.23',
- );
- });
- });
- });
- describe('BigNumberWithTrendline - Aggregation Tests', () => {
- const baseProps = {
- width: 800,
- height: 600,
- formData: {
- colorPicker: { r: 0, g: 0, b: 0, a: 1 },
- metric: 'metric',
- aggregation: 'LAST_VALUE',
- },
- queriesData: [
- {
- data: [
- { __timestamp: 1607558400000, metric: 10 },
- { __timestamp: 1607558500000, metric: 30 },
- { __timestamp: 1607558600000, metric: 50 },
- { __timestamp: 1607558700000, metric: 60 },
- ],
- colnames: ['__timestamp', 'metric'],
- coltypes: ['TIMESTAMP', 'BIGINT'],
- },
- ],
- hooks: {},
- filterState: {},
- datasource: {
- columnFormats: {},
- currencyFormats: {},
- },
- rawDatasource: {},
- rawFormData: {},
- theme: {
- colors: {
- grayscale: {
- light5: '#fafafa',
- },
- },
- },
- } as unknown as BigNumberWithTrendlineChartProps;
- const propsWithEvenData = {
- ...baseProps,
- queriesData: [
- {
- data: [
- { __timestamp: 1607558400000, metric: 10 },
- { __timestamp: 1607558500000, metric: 20 },
- { __timestamp: 1607558600000, metric: 30 },
- { __timestamp: 1607558700000, metric: 40 },
- ],
- colnames: ['__timestamp', 'metric'],
- coltypes: ['TIMESTAMP', 'BIGINT'],
- },
- ],
- } as unknown as BigNumberWithTrendlineChartProps;
- it('should correctly calculate SUM', () => {
- const props = {
- ...baseProps,
- formData: { ...baseProps.formData, aggregation: 'sum' },
- queriesData: [
- baseProps.queriesData[0],
- {
- data: [{ metric: 150 }],
- colnames: ['metric'],
- coltypes: ['BIGINT'],
- },
- ],
- } as unknown as BigNumberWithTrendlineChartProps;
- const transformed = transformProps(props);
- expect(transformed.bigNumber).toStrictEqual(150);
- });
- it('should correctly calculate AVG', () => {
- const props = {
- ...baseProps,
- formData: { ...baseProps.formData, aggregation: 'mean' },
- queriesData: [
- baseProps.queriesData[0],
- {
- data: [{ metric: 37.5 }],
- colnames: ['metric'],
- coltypes: ['BIGINT'],
- },
- ],
- } as unknown as BigNumberWithTrendlineChartProps;
- const transformed = transformProps(props);
- expect(transformed.bigNumber).toStrictEqual(37.5);
- });
- it('should correctly calculate MIN', () => {
- const props = {
- ...baseProps,
- formData: { ...baseProps.formData, aggregation: 'min' },
- queriesData: [
- baseProps.queriesData[0],
- {
- data: [{ metric: 10 }],
- colnames: ['metric'],
- coltypes: ['BIGINT'],
- },
- ],
- } as unknown as BigNumberWithTrendlineChartProps;
- const transformed = transformProps(props);
- expect(transformed.bigNumber).toStrictEqual(10);
- });
- it('should correctly calculate MAX', () => {
- const props = {
- ...baseProps,
- formData: { ...baseProps.formData, aggregation: 'max' },
- queriesData: [
- baseProps.queriesData[0],
- {
- data: [{ metric: 60 }],
- colnames: ['metric'],
- coltypes: ['BIGINT'],
- },
- ],
- } as unknown as BigNumberWithTrendlineChartProps;
- const transformed = transformProps(props);
- expect(transformed.bigNumber).toStrictEqual(60);
- });
- it('should correctly calculate MEDIAN (odd count)', () => {
- const oddCountProps = {
- ...baseProps,
- queriesData: [
- {
- data: [
- { __timestamp: 1607558300000, metric: 10 },
- { __timestamp: 1607558400000, metric: 20 },
- { __timestamp: 1607558500000, metric: 30 },
- { __timestamp: 1607558600000, metric: 40 },
- { __timestamp: 1607558700000, metric: 50 },
- ],
- colnames: ['__timestamp', 'metric'],
- coltypes: ['TIMESTAMP', 'BIGINT'],
- },
- ],
- } as unknown as BigNumberWithTrendlineChartProps;
- const props = {
- ...oddCountProps,
- formData: { ...oddCountProps.formData, aggregation: 'median' },
- queriesData: [
- oddCountProps.queriesData[0],
- {
- data: [{ metric: 30 }],
- colnames: ['metric'],
- coltypes: ['BIGINT'],
- },
- ],
- } as unknown as BigNumberWithTrendlineChartProps;
- const transformed = transformProps(props);
- expect(transformed.bigNumber).toStrictEqual(30);
- });
- it('should correctly calculate MEDIAN (even count)', () => {
- const props = {
- ...propsWithEvenData,
- formData: { ...propsWithEvenData.formData, aggregation: 'median' },
- queriesData: [
- propsWithEvenData.queriesData[0],
- {
- data: [{ metric: 25 }],
- colnames: ['metric'],
- coltypes: ['BIGINT'],
- },
- ],
- } as unknown as BigNumberWithTrendlineChartProps;
- const transformed = transformProps(props);
- expect(transformed.bigNumber).toStrictEqual(25);
- });
- it('should return the LAST_VALUE correctly', () => {
- const transformed = transformProps(baseProps);
- expect(transformed.bigNumber).toStrictEqual(10);
- });
- });
|