mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
4a61f4111f
commit
b864442717
@ -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"]
|
||||||
],
|
],
|
||||||
|
@ -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,8 +11,7 @@ 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,
|
||||||
color: {
|
color: {
|
||||||
@ -22,10 +21,9 @@ const setup = (propOverrides?: FieldConfig) => {
|
|||||||
mode: ThresholdsMode.Absolute,
|
mode: ThresholdsMode.Absolute,
|
||||||
steps: [{ value: -Infinity, color: '#7EB26D' }],
|
steps: [{ value: -Infinity, color: '#7EB26D' }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Object.assign(field, propOverrides);
|
|
||||||
|
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
showThresholdMarkers: true,
|
showThresholdMarkers: true,
|
||||||
showThresholdLabels: false,
|
showThresholdLabels: false,
|
||||||
field,
|
field,
|
||||||
@ -36,46 +34,10 @@ const setup = (propOverrides?: FieldConfig) => {
|
|||||||
numeric: 25,
|
numeric: 25,
|
||||||
},
|
},
|
||||||
theme: getTheme(),
|
theme: getTheme(),
|
||||||
};
|
|
||||||
|
|
||||||
const wrapper = shallow(<Gauge {...props} />);
|
|
||||||
const instance = wrapper.instance() as Gauge;
|
|
||||||
|
|
||||||
return {
|
|
||||||
instance,
|
|
||||||
wrapper,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Get thresholds formatted', () => {
|
describe('Gauge', () => {
|
||||||
it('should return first thresholds color for min and max', () => {
|
it('should render without blowing up', () => {
|
||||||
const { instance } = setup({
|
expect(() => render(<Gauge {...props} />)).not.toThrow();
|
||||||
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' },
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
55
packages/grafana-ui/src/components/Gauge/utils.test.ts
Normal file
55
packages/grafana-ui/src/components/Gauge/utils.test.ts
Normal 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' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
86
packages/grafana-ui/src/components/Gauge/utils.ts
Normal file
86
packages/grafana-ui/src/components/Gauge/utils.ts
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user