mirror of https://github.com/buster-so/buster.git
add some tests around formatting dates
This commit is contained in:
parent
38a880bc3e
commit
d1ea8968f9
|
@ -1,13 +1,9 @@
|
||||||
import {
|
import { type ColumnLabelFormat, DEFAULT_COLUMN_SETTINGS } from '@buster/server-shared/metrics';
|
||||||
type ColumnLabelFormat,
|
|
||||||
DEFAULT_COLUMN_LABEL_FORMAT,
|
|
||||||
DEFAULT_COLUMN_SETTINGS,
|
|
||||||
} from '@buster/server-shared/metrics';
|
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import type { BusterChartProps } from '../../../BusterChart.types';
|
import type { BusterChartProps } from '../../../BusterChart.types';
|
||||||
import type { DatasetOption } from '../../../chartHooks';
|
import type { DatasetOption } from '../../../chartHooks';
|
||||||
import type { DatasetOptionsWithTicks } from '../../../chartHooks/useDatasetOptions/interfaces';
|
import type { DatasetOptionsWithTicks } from '../../../chartHooks/useDatasetOptions/interfaces';
|
||||||
import { barSeriesBuilder } from './barSeriesBuilder';
|
import { barSeriesBuilder, barSeriesBuilder_labels } from './barSeriesBuilder';
|
||||||
import type { SeriesBuilderProps } from './interfaces';
|
import type { SeriesBuilderProps } from './interfaces';
|
||||||
|
|
||||||
describe('barSeriesBuilder', () => {
|
describe('barSeriesBuilder', () => {
|
||||||
|
@ -313,3 +309,210 @@ describe('percentage mode logic', () => {
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('barSeriesBuilder_labels - dateTicks', () => {
|
||||||
|
it('should return date ticks when columnLabelFormat has date style and single xAxis', () => {
|
||||||
|
// Arrange
|
||||||
|
const mockDatasetOptions: DatasetOptionsWithTicks = {
|
||||||
|
datasets: [],
|
||||||
|
ticks: [['2024-01-01'], ['2024-02-01'], ['2024-03-01']],
|
||||||
|
ticksKey: [{ key: 'date', value: '' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const columnLabelFormats = {
|
||||||
|
date: {
|
||||||
|
columnType: 'date',
|
||||||
|
style: 'date',
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
multiplier: 1,
|
||||||
|
prefix: '',
|
||||||
|
suffix: '',
|
||||||
|
replaceMissingDataWith: 0,
|
||||||
|
makeLabelHumanReadable: true,
|
||||||
|
} as ColumnLabelFormat,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = barSeriesBuilder_labels({
|
||||||
|
datasetOptions: mockDatasetOptions,
|
||||||
|
columnLabelFormats,
|
||||||
|
xAxisKeys: ['date'],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toHaveLength(3);
|
||||||
|
expect(result[0]).toBeInstanceOf(Date);
|
||||||
|
expect(result[1]).toBeInstanceOf(Date);
|
||||||
|
expect(result[2]).toBeInstanceOf(Date);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return quarter ticks when columnLabelFormat has quarter convertNumberTo and single xAxis', () => {
|
||||||
|
// Arrange
|
||||||
|
const mockDatasetOptions: DatasetOptionsWithTicks = {
|
||||||
|
datasets: [],
|
||||||
|
ticks: [[1], [2], [3], [4]],
|
||||||
|
ticksKey: [{ key: 'quarter', value: '' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const columnLabelFormats = {
|
||||||
|
quarter: {
|
||||||
|
columnType: 'number',
|
||||||
|
style: 'date',
|
||||||
|
convertNumberTo: 'quarter',
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
multiplier: 1,
|
||||||
|
prefix: '',
|
||||||
|
suffix: '',
|
||||||
|
replaceMissingDataWith: 0,
|
||||||
|
makeLabelHumanReadable: true,
|
||||||
|
} as ColumnLabelFormat,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = barSeriesBuilder_labels({
|
||||||
|
datasetOptions: mockDatasetOptions,
|
||||||
|
columnLabelFormats,
|
||||||
|
xAxisKeys: ['quarter'],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toHaveLength(4);
|
||||||
|
expect(result[0]).toBe('Q1');
|
||||||
|
expect(result[1]).toBe('Q2');
|
||||||
|
expect(result[2]).toBe('Q3');
|
||||||
|
expect(result[3]).toBe('Q4');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return quarter ticks with double xAxis when one is quarter and one is number', () => {
|
||||||
|
// Arrange
|
||||||
|
const mockDatasetOptions: DatasetOptionsWithTicks = {
|
||||||
|
datasets: [],
|
||||||
|
ticks: [
|
||||||
|
[1, 2023],
|
||||||
|
[2, 2023],
|
||||||
|
[3, 2023],
|
||||||
|
],
|
||||||
|
ticksKey: [
|
||||||
|
{ key: 'quarter', value: '' },
|
||||||
|
{ key: 'year', value: '' },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const columnLabelFormats = {
|
||||||
|
quarter: {
|
||||||
|
columnType: 'number',
|
||||||
|
style: 'date',
|
||||||
|
convertNumberTo: 'quarter',
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
multiplier: 1,
|
||||||
|
prefix: '',
|
||||||
|
suffix: '',
|
||||||
|
replaceMissingDataWith: 0,
|
||||||
|
makeLabelHumanReadable: true,
|
||||||
|
} as ColumnLabelFormat,
|
||||||
|
year: {
|
||||||
|
columnType: 'number',
|
||||||
|
style: 'number',
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
multiplier: 1,
|
||||||
|
prefix: '',
|
||||||
|
suffix: '',
|
||||||
|
numberSeparatorStyle: null,
|
||||||
|
replaceMissingDataWith: 0,
|
||||||
|
makeLabelHumanReadable: true,
|
||||||
|
} as ColumnLabelFormat,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = barSeriesBuilder_labels({
|
||||||
|
datasetOptions: mockDatasetOptions,
|
||||||
|
columnLabelFormats,
|
||||||
|
xAxisKeys: ['quarter', 'year'],
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('result', result[0]);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toHaveLength(3);
|
||||||
|
expect(result[0]).toContain('Q1');
|
||||||
|
expect(result[0]).toContain('2023');
|
||||||
|
expect(result[1]).toContain('Q2');
|
||||||
|
expect(result[2]).toContain('Q3');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null dateTicks when columnLabelFormat does not have date style', () => {
|
||||||
|
// Arrange
|
||||||
|
const mockDatasetOptions: DatasetOptionsWithTicks = {
|
||||||
|
datasets: [],
|
||||||
|
ticks: [['Product A'], ['Product B'], ['Product C']],
|
||||||
|
ticksKey: [{ key: 'product', value: '' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const columnLabelFormats = {
|
||||||
|
product: {
|
||||||
|
columnType: 'string',
|
||||||
|
style: 'string',
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
multiplier: 1,
|
||||||
|
prefix: '',
|
||||||
|
suffix: '',
|
||||||
|
replaceMissingDataWith: 0,
|
||||||
|
makeLabelHumanReadable: true,
|
||||||
|
} as unknown as ColumnLabelFormat,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = barSeriesBuilder_labels({
|
||||||
|
datasetOptions: mockDatasetOptions,
|
||||||
|
columnLabelFormats,
|
||||||
|
xAxisKeys: ['product'],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toHaveLength(3);
|
||||||
|
expect(result[0]).toBe('Product A');
|
||||||
|
expect(result[1]).toBe('Product B');
|
||||||
|
expect(result[2]).toBe('Product C');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return date ticks when columnType is number but style is date', () => {
|
||||||
|
// Arrange
|
||||||
|
const mockDatasetOptions: DatasetOptionsWithTicks = {
|
||||||
|
datasets: [],
|
||||||
|
ticks: [['2024-01-15'], ['2024-01-16'], ['2024-01-17']],
|
||||||
|
ticksKey: [{ key: 'timestamp', value: '' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const columnLabelFormats = {
|
||||||
|
timestamp: {
|
||||||
|
columnType: 'number',
|
||||||
|
style: 'date',
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
multiplier: 1,
|
||||||
|
prefix: '',
|
||||||
|
suffix: '',
|
||||||
|
replaceMissingDataWith: 0,
|
||||||
|
makeLabelHumanReadable: true,
|
||||||
|
} as ColumnLabelFormat,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = barSeriesBuilder_labels({
|
||||||
|
datasetOptions: mockDatasetOptions,
|
||||||
|
columnLabelFormats,
|
||||||
|
xAxisKeys: ['timestamp'],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toHaveLength(3);
|
||||||
|
expect(result[0]).toBeInstanceOf(Date);
|
||||||
|
expect(result[1]).toBeInstanceOf(Date);
|
||||||
|
expect(result[2]).toBeInstanceOf(Date);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -360,6 +360,12 @@ export const barSeriesBuilder_labels = ({
|
||||||
return dateTicks;
|
return dateTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const containsADateStyle = datasetOptions.ticksKey.some((tick) => {
|
||||||
|
const selectedColumnLabelFormat = columnLabelFormats[tick.key];
|
||||||
|
return selectedColumnLabelFormat?.style === 'date';
|
||||||
|
});
|
||||||
|
const selectedJoinCharacter = containsADateStyle ? JOIN_CHARACTER_DATE : JOIN_CHARACTER;
|
||||||
|
|
||||||
const labels = datasetOptions.ticks.flatMap((item) => {
|
const labels = datasetOptions.ticks.flatMap((item) => {
|
||||||
return item
|
return item
|
||||||
.map<string>((item, index) => {
|
.map<string>((item, index) => {
|
||||||
|
@ -367,7 +373,7 @@ export const barSeriesBuilder_labels = ({
|
||||||
const columnLabelFormat = columnLabelFormats[key];
|
const columnLabelFormat = columnLabelFormats[key];
|
||||||
return formatLabel(item, columnLabelFormat);
|
return formatLabel(item, columnLabelFormat);
|
||||||
})
|
})
|
||||||
.join(JOIN_CHARACTER);
|
.join(selectedJoinCharacter);
|
||||||
});
|
});
|
||||||
|
|
||||||
return labels;
|
return labels;
|
||||||
|
|
|
@ -45,6 +45,7 @@ export const createTickDates = (
|
||||||
}
|
}
|
||||||
|
|
||||||
const isDoubleXAxis = xAxisKeys.length === 2;
|
const isDoubleXAxis = xAxisKeys.length === 2;
|
||||||
|
console.log('isDoubleXAxis', isDoubleXAxis);
|
||||||
if (isDoubleXAxis) {
|
if (isDoubleXAxis) {
|
||||||
const oneIsAQuarter = xColumnLabelFormats.findIndex(
|
const oneIsAQuarter = xColumnLabelFormats.findIndex(
|
||||||
(format) => format.convertNumberTo === 'quarter' && format.columnType === 'number'
|
(format) => format.convertNumberTo === 'quarter' && format.columnType === 'number'
|
||||||
|
@ -52,6 +53,8 @@ export const createTickDates = (
|
||||||
const oneIsANumber = xColumnLabelFormats.findIndex(
|
const oneIsANumber = xColumnLabelFormats.findIndex(
|
||||||
(format) => format.columnType === 'number' && format.style === 'number'
|
(format) => format.columnType === 'number' && format.style === 'number'
|
||||||
);
|
);
|
||||||
|
console.log('oneIsAQuarter', oneIsAQuarter);
|
||||||
|
console.log('oneIsANumber', oneIsANumber);
|
||||||
if (oneIsAQuarter !== -1 && oneIsANumber !== -1) {
|
if (oneIsAQuarter !== -1 && oneIsANumber !== -1) {
|
||||||
return createQuarterTickDates(ticks, xColumnLabelFormats, oneIsAQuarter);
|
return createQuarterTickDates(ticks, xColumnLabelFormats, oneIsAQuarter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,6 +330,7 @@ describe('lineSeriesBuilder', () => {
|
||||||
const labels = lineSeriesBuilder_labels(props);
|
const labels = lineSeriesBuilder_labels(props);
|
||||||
|
|
||||||
expect(labels).toHaveLength(3);
|
expect(labels).toHaveLength(3);
|
||||||
|
console.log('labels', labels[0]);
|
||||||
expect(labels[0]).toBe('formatted-2023-01-01 formatted-A');
|
expect(labels[0]).toBe('formatted-2023-01-01 formatted-A');
|
||||||
expect(labels[1]).toBe('formatted-2023-01-02 formatted-B');
|
expect(labels[1]).toBe('formatted-2023-01-02 formatted-B');
|
||||||
expect(labels[2]).toBe('formatted-2023-01-03 formatted-A');
|
expect(labels[2]).toBe('formatted-2023-01-03 formatted-A');
|
||||||
|
|
Loading…
Reference in New Issue