Gauge: convert tests to RTL (#49251)

* Move logic into utils file, add EXTREMELY basic RTL test

* initialise array with value
This commit is contained in:
Ashley Harrison 2022-05-20 10:51:11 +01:00 committed by GitHub
parent 4a61f4111f
commit b864442717
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 172 additions and 143 deletions

View File

@ -11,9 +11,6 @@ exports[`no enzyme tests`] = {
"packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx:3129955645": [ "packages/grafana-ui/src/components/Forms/Legacy/Input/Input.test.tsx:3129955645": [
[0, 19, 13, "RegExp match", "2409514259"] [0, 19, 13, "RegExp match", "2409514259"]
], ],
"packages/grafana-ui/src/components/Gauge/Gauge.test.tsx:2525939157": [
[0, 19, 13, "RegExp match", "2409514259"]
],
"packages/grafana-ui/src/components/Graph/Graph.test.tsx:1664091255": [ "packages/grafana-ui/src/components/Graph/Graph.test.tsx:1664091255": [
[0, 17, 13, "RegExp match", "2409514259"] [0, 17, 13, "RegExp match", "2409514259"]
], ],

View File

@ -1,4 +1,4 @@
import { shallow } from 'enzyme'; import { render } from '@testing-library/react';
import React from 'react'; import React from 'react';
import { ThresholdsMode, FieldConfig, FieldColorModeId } from '@grafana/data'; import { ThresholdsMode, FieldConfig, FieldColorModeId } from '@grafana/data';
@ -11,7 +11,6 @@ jest.mock('jquery', () => ({
plot: jest.fn(), plot: jest.fn(),
})); }));
const setup = (propOverrides?: FieldConfig) => {
const field: FieldConfig = { const field: FieldConfig = {
min: 0, min: 0,
max: 100, max: 100,
@ -23,7 +22,6 @@ const setup = (propOverrides?: FieldConfig) => {
steps: [{ value: -Infinity, color: '#7EB26D' }], steps: [{ value: -Infinity, color: '#7EB26D' }],
}, },
}; };
Object.assign(field, propOverrides);
const props: Props = { const props: Props = {
showThresholdMarkers: true, showThresholdMarkers: true,
@ -38,44 +36,8 @@ const setup = (propOverrides?: FieldConfig) => {
theme: getTheme(), theme: getTheme(),
}; };
const wrapper = shallow(<Gauge {...props} />); describe('Gauge', () => {
const instance = wrapper.instance() as Gauge; it('should render without blowing up', () => {
expect(() => render(<Gauge {...props} />)).not.toThrow();
return {
instance,
wrapper,
};
};
describe('Get thresholds formatted', () => {
it('should return first thresholds color for min and max', () => {
const { instance } = setup({
thresholds: { mode: ThresholdsMode.Absolute, steps: [{ value: -Infinity, color: '#7EB26D' }] },
});
expect(instance.getFormattedThresholds(2)).toEqual([
{ value: 0, color: '#7EB26D' },
{ value: 100, color: '#7EB26D' },
]);
});
it('should get the correct formatted values when thresholds are added', () => {
const { instance } = setup({
thresholds: {
mode: ThresholdsMode.Absolute,
steps: [
{ value: -Infinity, color: '#7EB26D' },
{ value: 50, color: '#EAB839' },
{ value: 75, color: '#6ED0E0' },
],
},
});
expect(instance.getFormattedThresholds(2)).toEqual([
{ value: 0, color: '#7EB26D' },
{ value: 50, color: '#7EB26D' },
{ value: 75, color: '#EAB839' },
{ value: 100, color: '#6ED0E0' },
]);
}); });
}); });

View File

@ -8,17 +8,14 @@ import {
ThresholdsMode, ThresholdsMode,
GAUGE_DEFAULT_MAXIMUM, GAUGE_DEFAULT_MAXIMUM,
GAUGE_DEFAULT_MINIMUM, GAUGE_DEFAULT_MINIMUM,
getActiveThreshold,
Threshold,
getColorForTheme,
FieldColorModeId,
FALLBACK_COLOR,
TextDisplayOptions, TextDisplayOptions,
} from '@grafana/data'; } from '@grafana/data';
import { Themeable } from '../../types'; import { Themeable } from '../../types';
import { calculateFontSize } from '../../utils/measureText'; import { calculateFontSize } from '../../utils/measureText';
import { calculateGaugeAutoProps, DEFAULT_THRESHOLDS, getFormattedThresholds } from './utils';
export interface Props extends Themeable { export interface Props extends Themeable {
height: number; height: number;
field: FieldConfig; field: FieldConfig;
@ -40,13 +37,7 @@ export class Gauge extends PureComponent<Props> {
field: { field: {
min: 0, min: 0,
max: 100, max: 100,
thresholds: { thresholds: DEFAULT_THRESHOLDS,
mode: ThresholdsMode.Absolute,
steps: [
{ value: -Infinity, color: 'green' },
{ value: 80, color: 'red' },
],
},
}, },
}; };
@ -58,48 +49,6 @@ export class Gauge extends PureComponent<Props> {
this.draw(); this.draw();
} }
getFormattedThresholds(decimals: number): Threshold[] {
const { field, theme, value } = this.props;
if (field.color?.mode !== FieldColorModeId.Thresholds) {
return [{ value: field.min ?? GAUGE_DEFAULT_MINIMUM, color: value.color ?? FALLBACK_COLOR }];
}
const thresholds = field.thresholds ?? Gauge.defaultProps.field?.thresholds!;
const isPercent = thresholds.mode === ThresholdsMode.Percentage;
const steps = thresholds.steps;
let min = field.min ?? GAUGE_DEFAULT_MINIMUM;
let max = field.max ?? GAUGE_DEFAULT_MAXIMUM;
if (isPercent) {
min = 0;
max = 100;
}
const first = getActiveThreshold(min, steps);
const last = getActiveThreshold(max, steps);
const formatted: Threshold[] = [];
formatted.push({ value: +min.toFixed(decimals), color: getColorForTheme(first.color, theme) });
let skip = true;
for (let i = 0; i < steps.length; i++) {
const step = steps[i];
if (skip) {
if (first === step) {
skip = false;
}
continue;
}
const prev = steps[i - 1];
formatted.push({ value: step.value, color: getColorForTheme(prev!.color, theme) });
if (step === last) {
break;
}
}
formatted.push({ value: +max.toFixed(decimals), color: getColorForTheme(last.color, theme) });
return formatted;
}
draw() { draw() {
const { field, showThresholdLabels, showThresholdMarkers, width, height, theme, value } = this.props; const { field, showThresholdLabels, showThresholdMarkers, width, height, theme, value } = this.props;
@ -157,7 +106,7 @@ export class Gauge extends PureComponent<Props> {
layout: { margin: 0, thresholdWidth: 0, vMargin: 0 }, layout: { margin: 0, thresholdWidth: 0, vMargin: 0 },
cell: { border: { width: 0 } }, cell: { border: { width: 0 } },
threshold: { threshold: {
values: this.getFormattedThresholds(decimals), values: getFormattedThresholds(decimals, field, value, theme),
label: { label: {
show: showThresholdLabels, show: showThresholdLabels,
margin: thresholdMarkersWidth + 1, margin: thresholdMarkersWidth + 1,
@ -240,23 +189,3 @@ export class Gauge extends PureComponent<Props> {
); );
} }
} }
interface GaugeAutoProps {
titleFontSize: number;
gaugeHeight: number;
showLabel: boolean;
}
function calculateGaugeAutoProps(width: number, height: number, title: string | undefined): GaugeAutoProps {
const showLabel = title !== null && title !== undefined;
const titleFontSize = Math.min((width * 0.15) / 1.5, 20); // 20% of height * line-height, max 40px
const titleHeight = titleFontSize * 1.5;
const availableHeight = showLabel ? height - titleHeight : height;
const gaugeHeight = Math.min(availableHeight, width);
return {
showLabel,
gaugeHeight,
titleFontSize,
};
}

View File

@ -0,0 +1,55 @@
import { FieldColorModeId, FieldConfig, ThresholdsMode } from '@grafana/data';
import { getTheme } from '../../themes';
import { getFormattedThresholds } from './utils';
describe('getFormattedThresholds', () => {
const value = {
text: '25',
numeric: 25,
};
const theme = getTheme();
let field: FieldConfig;
beforeEach(() => {
field = {
min: 0,
max: 100,
color: {
mode: FieldColorModeId.Thresholds,
},
thresholds: {
mode: ThresholdsMode.Absolute,
steps: [{ value: -Infinity, color: '#7EB26D' }],
},
};
});
it('should return first thresholds color for min and max', () => {
field.thresholds = { mode: ThresholdsMode.Absolute, steps: [{ value: -Infinity, color: '#7EB26D' }] };
expect(getFormattedThresholds(2, field, value, theme)).toEqual([
{ value: 0, color: '#7EB26D' },
{ value: 100, color: '#7EB26D' },
]);
});
it('should get the correct formatted values when thresholds are added', () => {
field.thresholds = {
mode: ThresholdsMode.Absolute,
steps: [
{ value: -Infinity, color: '#7EB26D' },
{ value: 50, color: '#EAB839' },
{ value: 75, color: '#6ED0E0' },
],
};
expect(getFormattedThresholds(2, field, value, theme)).toEqual([
{ value: 0, color: '#7EB26D' },
{ value: 50, color: '#7EB26D' },
{ value: 75, color: '#EAB839' },
{ value: 100, color: '#6ED0E0' },
]);
});
});

View File

@ -0,0 +1,86 @@
import {
DisplayValue,
FALLBACK_COLOR,
FieldColorModeId,
FieldConfig,
GAUGE_DEFAULT_MAXIMUM,
GAUGE_DEFAULT_MINIMUM,
getActiveThreshold,
getColorForTheme,
GrafanaTheme,
Threshold,
ThresholdsConfig,
ThresholdsMode,
} from '@grafana/data';
interface GaugeAutoProps {
titleFontSize: number;
gaugeHeight: number;
showLabel: boolean;
}
export const DEFAULT_THRESHOLDS: ThresholdsConfig = {
mode: ThresholdsMode.Absolute,
steps: [
{ value: -Infinity, color: 'green' },
{ value: 80, color: 'red' },
],
};
export function calculateGaugeAutoProps(width: number, height: number, title: string | undefined): GaugeAutoProps {
const showLabel = title !== null && title !== undefined;
const titleFontSize = Math.min((width * 0.15) / 1.5, 20); // 20% of height * line-height, max 40px
const titleHeight = titleFontSize * 1.5;
const availableHeight = showLabel ? height - titleHeight : height;
const gaugeHeight = Math.min(availableHeight, width);
return {
showLabel,
gaugeHeight,
titleFontSize,
};
}
export function getFormattedThresholds(
decimals: number,
field: FieldConfig,
value: DisplayValue,
theme: GrafanaTheme
): Threshold[] {
if (field.color?.mode !== FieldColorModeId.Thresholds) {
return [{ value: field.min ?? GAUGE_DEFAULT_MINIMUM, color: value.color ?? FALLBACK_COLOR }];
}
const thresholds = field.thresholds ?? DEFAULT_THRESHOLDS;
const isPercent = thresholds.mode === ThresholdsMode.Percentage;
const steps = thresholds.steps;
let min = field.min ?? GAUGE_DEFAULT_MINIMUM;
let max = field.max ?? GAUGE_DEFAULT_MAXIMUM;
if (isPercent) {
min = 0;
max = 100;
}
const first = getActiveThreshold(min, steps);
const last = getActiveThreshold(max, steps);
const formatted: Threshold[] = [{ value: +min.toFixed(decimals), color: getColorForTheme(first.color, theme) }];
let skip = true;
for (let i = 0; i < steps.length; i++) {
const step = steps[i];
if (skip) {
if (first === step) {
skip = false;
}
continue;
}
const prev = steps[i - 1];
formatted.push({ value: step.value, color: getColorForTheme(prev!.color, theme) });
if (step === last) {
break;
}
}
formatted.push({ value: +max.toFixed(decimals), color: getColorForTheme(last.color, theme) });
return formatted;
}