blob: 0b54271afd7edc366f7e9a8709b6258309c4651c [file] [log] [blame]
/**
* 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);
});
});