mirror of
https://github.com/grafana/grafana.git
synced 2025-09-18 14:33:12 +08:00
Chore: Upgrade typescript and related packages (#27316)
* Chore: Upgrade typescript and related packages Closes #27115 * Apply suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * fixes some tests * Fix failing tests * Apply suggestions from code review Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
13
package.json
13
package.json
@ -119,8 +119,9 @@
|
|||||||
"@types/testing-library__jest-dom": "^5.9.2",
|
"@types/testing-library__jest-dom": "^5.9.2",
|
||||||
"@types/testing-library__react-hooks": "^3.2.0",
|
"@types/testing-library__react-hooks": "^3.2.0",
|
||||||
"@types/tinycolor2": "1.4.2",
|
"@types/tinycolor2": "1.4.2",
|
||||||
"@typescript-eslint/eslint-plugin": "3.6.0",
|
"@typescript-eslint/eslint-plugin": "4.0.1",
|
||||||
"@typescript-eslint/parser": "3.6.0",
|
"@typescript-eslint/parser": "4.0.1",
|
||||||
|
"angular-mocks": "1.6.6",
|
||||||
"autoprefixer": "9.7.4",
|
"autoprefixer": "9.7.4",
|
||||||
"axios": "0.19.2",
|
"axios": "0.19.2",
|
||||||
"babel-core": "7.0.0-bridge.0",
|
"babel-core": "7.0.0-bridge.0",
|
||||||
@ -162,7 +163,7 @@
|
|||||||
"html-webpack-harddisk-plugin": "1.0.1",
|
"html-webpack-harddisk-plugin": "1.0.1",
|
||||||
"html-webpack-plugin": "3.2.0",
|
"html-webpack-plugin": "3.2.0",
|
||||||
"husky": "4.2.1",
|
"husky": "4.2.1",
|
||||||
"jest": "26.0.0",
|
"jest": "26.4.2",
|
||||||
"jest-canvas-mock": "2.2.0",
|
"jest-canvas-mock": "2.2.0",
|
||||||
"jest-date-mock": "1.0.8",
|
"jest-date-mock": "1.0.8",
|
||||||
"lerna": "^3.20.2",
|
"lerna": "^3.20.2",
|
||||||
@ -192,10 +193,10 @@
|
|||||||
"sinon": "8.1.1",
|
"sinon": "8.1.1",
|
||||||
"style-loader": "1.1.3",
|
"style-loader": "1.1.3",
|
||||||
"terser-webpack-plugin": "2.3.5",
|
"terser-webpack-plugin": "2.3.5",
|
||||||
"ts-jest": "26.1.0",
|
"ts-jest": "26.3.0",
|
||||||
"ts-node": "8.8.1",
|
"ts-node": "8.8.1",
|
||||||
"tslib": "1.10.0",
|
"tslib": "2.0.1",
|
||||||
"typescript": "3.9.3",
|
"typescript": "4.0.2",
|
||||||
"webpack": "4.41.5",
|
"webpack": "4.41.5",
|
||||||
"webpack-bundle-analyzer": "3.6.0",
|
"webpack-bundle-analyzer": "3.6.0",
|
||||||
"webpack-cleanup-plugin": "0.5.1",
|
"webpack-cleanup-plugin": "0.5.1",
|
||||||
|
@ -49,6 +49,6 @@
|
|||||||
"rollup-plugin-typescript2": "0.26.0",
|
"rollup-plugin-typescript2": "0.26.0",
|
||||||
"rollup-plugin-visualizer": "3.3.1",
|
"rollup-plugin-visualizer": "3.3.1",
|
||||||
"sinon": "8.1.1",
|
"sinon": "8.1.1",
|
||||||
"typescript": "3.9.3"
|
"typescript": "4.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
"@grafana/tsconfig": "^1.0.0-rc1",
|
"@grafana/tsconfig": "^1.0.0-rc1",
|
||||||
"commander": "5.0.0",
|
"commander": "5.0.0",
|
||||||
"execa": "4.0.0",
|
"execa": "4.0.0",
|
||||||
"typescript": "3.9.3",
|
"typescript": "4.0.2",
|
||||||
"yaml": "^1.8.3"
|
"yaml": "^1.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
"execa": "4.0.0",
|
"execa": "4.0.0",
|
||||||
"resolve-as-bin": "2.1.0",
|
"resolve-as-bin": "2.1.0",
|
||||||
"ts-loader": "6.2.1",
|
"ts-loader": "6.2.1",
|
||||||
"typescript": "3.9.3",
|
"typescript": "4.0.2",
|
||||||
"yaml": "^1.8.3"
|
"yaml": "^1.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
"rollup-plugin-terser": "5.3.0",
|
"rollup-plugin-terser": "5.3.0",
|
||||||
"rollup-plugin-typescript2": "0.26.0",
|
"rollup-plugin-typescript2": "0.26.0",
|
||||||
"rollup-plugin-visualizer": "3.3.1",
|
"rollup-plugin-visualizer": "3.3.1",
|
||||||
"typescript": "3.9.3"
|
"typescript": "4.0.2"
|
||||||
},
|
},
|
||||||
"types": "src/index.ts"
|
"types": "src/index.ts"
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@
|
|||||||
"@types/semver": "^6.0.0",
|
"@types/semver": "^6.0.0",
|
||||||
"@types/tmp": "^0.1.0",
|
"@types/tmp": "^0.1.0",
|
||||||
"@types/webpack": "4.41.7",
|
"@types/webpack": "4.41.7",
|
||||||
"@typescript-eslint/eslint-plugin": "3.6.0",
|
"@typescript-eslint/eslint-plugin": "4.0.1",
|
||||||
"@typescript-eslint/parser": "3.6.0",
|
"@typescript-eslint/parser": "4.0.1",
|
||||||
"axios": "0.19.2",
|
"axios": "0.19.2",
|
||||||
"babel-jest": "24.8.0",
|
"babel-jest": "24.8.0",
|
||||||
"babel-loader": "8.1.0",
|
"babel-loader": "8.1.0",
|
||||||
@ -102,11 +102,11 @@
|
|||||||
"simple-git": "^1.132.0",
|
"simple-git": "^1.132.0",
|
||||||
"style-loader": "^0.23.1",
|
"style-loader": "^0.23.1",
|
||||||
"terser-webpack-plugin": "^2.3.4",
|
"terser-webpack-plugin": "^2.3.4",
|
||||||
"ts-jest": "24.1.0",
|
"ts-jest": "26.3.0",
|
||||||
"ts-loader": "6.2.1",
|
"ts-loader": "6.2.1",
|
||||||
"ts-node": "8.8.1",
|
"ts-node": "8.8.1",
|
||||||
"tslib": "1.10.0",
|
"tslib": "2.0.1",
|
||||||
"typescript": "3.9.3",
|
"typescript": "4.0.2",
|
||||||
"url-loader": "^2.0.1",
|
"url-loader": "^2.0.1",
|
||||||
"webpack": "4.41.5"
|
"webpack": "4.41.5"
|
||||||
},
|
},
|
||||||
|
@ -107,7 +107,7 @@
|
|||||||
"rollup-plugin-visualizer": "3.3.1",
|
"rollup-plugin-visualizer": "3.3.1",
|
||||||
"storybook-dark-mode": "0.6.1",
|
"storybook-dark-mode": "0.6.1",
|
||||||
"ts-loader": "6.2.1",
|
"ts-loader": "6.2.1",
|
||||||
"typescript": "3.9.3"
|
"typescript": "4.0.2"
|
||||||
},
|
},
|
||||||
"types": "src/index.ts"
|
"types": "src/index.ts"
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ export const ContextMenu: React.FC<ContextMenuProps> = React.memo(({ x, y, onClo
|
|||||||
renderItem={(item, index) => {
|
renderItem={(item, index) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ContextMenuGroup group={item} onClick={onClose} />
|
<ContextMenuGroupComponent group={item} onClick={onClose} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@ -207,7 +207,7 @@ interface ContextMenuItemProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ContextMenuItem: React.FC<ContextMenuItemProps> = React.memo(
|
const ContextMenuItemComponent: React.FC<ContextMenuItemProps> = React.memo(
|
||||||
({ url, icon, label, target, onClick, className }) => {
|
({ url, icon, label, target, onClick, className }) => {
|
||||||
const theme = useContext(ThemeContext);
|
const theme = useContext(ThemeContext);
|
||||||
const styles = getContextMenuStyles(theme);
|
const styles = getContextMenuStyles(theme);
|
||||||
@ -235,7 +235,7 @@ interface ContextMenuGroupProps {
|
|||||||
onClick?: () => void; // Used with 'onClose'
|
onClick?: () => void; // Used with 'onClose'
|
||||||
}
|
}
|
||||||
|
|
||||||
const ContextMenuGroup: React.FC<ContextMenuGroupProps> = ({ group, onClick }) => {
|
const ContextMenuGroupComponent: React.FC<ContextMenuGroupProps> = ({ group, onClick }) => {
|
||||||
const theme = useContext(ThemeContext);
|
const theme = useContext(ThemeContext);
|
||||||
const styles = getContextMenuStyles(theme);
|
const styles = getContextMenuStyles(theme);
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ const ContextMenuGroup: React.FC<ContextMenuGroupProps> = ({ group, onClick }) =
|
|||||||
items={group.items || []}
|
items={group.items || []}
|
||||||
renderItem={item => {
|
renderItem={item => {
|
||||||
return (
|
return (
|
||||||
<ContextMenuItem
|
<ContextMenuItemComponent
|
||||||
url={item.url}
|
url={item.url}
|
||||||
label={item.label}
|
label={item.label}
|
||||||
target={item.target}
|
target={item.target}
|
||||||
|
@ -5,13 +5,13 @@ import { stylesFactory, useTheme } from '../../themes';
|
|||||||
import { Badge, BadgeProps } from '../Badge/Badge';
|
import { Badge, BadgeProps } from '../Badge/Badge';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
|
|
||||||
interface FeatureInfoBox extends Omit<InfoBoxProps, 'branded' | 'title' | 'urlTitle'> {
|
interface FeatureInfoBoxProps extends Omit<InfoBoxProps, 'branded' | 'title' | 'urlTitle'> {
|
||||||
title: string;
|
title: string;
|
||||||
featureState?: FeatureState;
|
featureState?: FeatureState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FeatureInfoBox = React.memo(
|
export const FeatureInfoBox = React.memo(
|
||||||
React.forwardRef<HTMLDivElement, FeatureInfoBox>(({ title, featureState, ...otherProps }, ref) => {
|
React.forwardRef<HTMLDivElement, FeatureInfoBoxProps>(({ title, featureState, ...otherProps }, ref) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const styles = getFeatureInfoBoxStyles(theme);
|
const styles = getFeatureInfoBoxStyles(theme);
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"enzyme": "^3.8.0",
|
"enzyme": "^3.8.0",
|
||||||
"enzyme-adapter-react-16": "^1.2.0",
|
"enzyme-adapter-react-16": "^1.2.0",
|
||||||
"typescript": "3.9.3"
|
"typescript": "4.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@grafana/data": "7.3.0-pre.0",
|
"@grafana/data": "7.3.0-pre.0",
|
||||||
|
@ -8,13 +8,13 @@ import appEvents from 'app/core/app_events';
|
|||||||
import { AppEvents } from '@grafana/data';
|
import { AppEvents } from '@grafana/data';
|
||||||
|
|
||||||
interface SignupDTO {
|
interface SignupDTO {
|
||||||
name: string;
|
name?: string;
|
||||||
email: string;
|
email: string;
|
||||||
username: string;
|
username: string;
|
||||||
orgName?: string;
|
orgName?: string;
|
||||||
password: string;
|
password: string;
|
||||||
code: string;
|
code: string;
|
||||||
confirm: string;
|
confirm?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ConnectedProps {
|
interface ConnectedProps {
|
||||||
|
@ -28,6 +28,7 @@ function mockLocationHref(href: string) {
|
|||||||
search = href.substring(searchPos);
|
search = href.substring(searchPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
delete window.location;
|
delete window.location;
|
||||||
(window as any).location = {
|
(window as any).location = {
|
||||||
...location,
|
...location,
|
||||||
|
@ -80,7 +80,7 @@ export class DashboardModel {
|
|||||||
// ------------------
|
// ------------------
|
||||||
|
|
||||||
// repeat process cycles
|
// repeat process cycles
|
||||||
iteration: number;
|
iteration?: number;
|
||||||
meta: DashboardMeta;
|
meta: DashboardMeta;
|
||||||
events: Emitter;
|
events: Emitter;
|
||||||
|
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
const applyFieldOverridesMock = jest.fn();
|
||||||
|
|
||||||
|
jest.mock('@grafana/data', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
...(jest.requireActual('@grafana/data') as any),
|
||||||
|
applyFieldOverrides: applyFieldOverridesMock,
|
||||||
|
}));
|
||||||
|
|
||||||
import { PanelQueryRunner } from './PanelQueryRunner';
|
import { PanelQueryRunner } from './PanelQueryRunner';
|
||||||
// Importing this way to be able to spy on grafana/data
|
// Importing this way to be able to spy on grafana/data
|
||||||
import * as grafanaData from '@grafana/data';
|
import * as grafanaData from '@grafana/data';
|
||||||
@ -131,6 +139,10 @@ function describeQueryRunnerScenario(description: string, scenarioFn: ScenarioFn
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('PanelQueryRunner', () => {
|
describe('PanelQueryRunner', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
describeQueryRunnerScenario('simple scenario', ctx => {
|
describeQueryRunnerScenario('simple scenario', ctx => {
|
||||||
it('should set requestId on request', async () => {
|
it('should set requestId on request', async () => {
|
||||||
expect(ctx.queryCalledWith?.requestId).toBe('Q100');
|
expect(ctx.queryCalledWith?.requestId).toBe('Q100');
|
||||||
@ -211,14 +223,12 @@ describe('PanelQueryRunner', () => {
|
|||||||
'field overrides',
|
'field overrides',
|
||||||
ctx => {
|
ctx => {
|
||||||
it('should apply when field override options are set', async () => {
|
it('should apply when field override options are set', async () => {
|
||||||
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
|
||||||
|
|
||||||
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
|
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
|
||||||
next: (data: PanelData) => {
|
next: (data: PanelData) => {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(spy).toBeCalled();
|
expect(applyFieldOverridesMock).toBeCalled();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -277,15 +287,13 @@ describe('PanelQueryRunner', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not apply field config when applyFieldConfig option is false', async () => {
|
it('should not apply field config when applyFieldConfig option is false', async () => {
|
||||||
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
|
||||||
spy.mockClear();
|
|
||||||
ctx.runner.getData({ withFieldConfig: false, withTransforms: true }).subscribe({
|
ctx.runner.getData({ withFieldConfig: false, withTransforms: true }).subscribe({
|
||||||
next: (data: PanelData) => {
|
next: (data: PanelData) => {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(spy).not.toBeCalled();
|
expect(applyFieldOverridesMock).not.toBeCalled();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -322,15 +330,13 @@ describe('PanelQueryRunner', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not apply field config when applyFieldConfig option is false', async () => {
|
it('should not apply field config when applyFieldConfig option is false', async () => {
|
||||||
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
|
||||||
spy.mockClear();
|
|
||||||
ctx.runner.getData({ withFieldConfig: false, withTransforms: true }).subscribe({
|
ctx.runner.getData({ withFieldConfig: false, withTransforms: true }).subscribe({
|
||||||
next: (data: PanelData) => {
|
next: (data: PanelData) => {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(spy).not.toBeCalled();
|
expect(applyFieldOverridesMock).not.toBeCalled();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ const mockWindowLocation = (): [jest.MockInstance<any, any>, () => void] => {
|
|||||||
|
|
||||||
// JSDom defines window in a way that you cannot tamper with location so this seems to be the only way to change it.
|
// JSDom defines window in a way that you cannot tamper with location so this seems to be the only way to change it.
|
||||||
// https://github.com/facebook/jest/issues/5124#issuecomment-446659510
|
// https://github.com/facebook/jest/issues/5124#issuecomment-446659510
|
||||||
|
//@ts-ignore
|
||||||
delete window.location;
|
delete window.location;
|
||||||
window.location = {} as any;
|
window.location = {} as any;
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ export const initQueryVariableEditor = (identifier: VariableIdentifier): ThunkRe
|
|||||||
if (!variable.datasource) {
|
if (!variable.datasource) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch(changeQueryVariableDataSource(toVariableIdentifier(variable), variable.datasource));
|
await dispatch(changeQueryVariableDataSource(toVariableIdentifier(variable), variable.datasource));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const changeQueryVariableDataSource = (
|
export const changeQueryVariableDataSource = (
|
||||||
|
@ -35,7 +35,9 @@ export function toVariablePayload<T extends any = undefined>(
|
|||||||
identifier: VariableIdentifier,
|
identifier: VariableIdentifier,
|
||||||
data?: T
|
data?: T
|
||||||
): VariablePayload<T>;
|
): VariablePayload<T>;
|
||||||
|
// eslint-disable-next-line
|
||||||
export function toVariablePayload<T extends any = undefined>(model: VariableModel, data?: T): VariablePayload<T>;
|
export function toVariablePayload<T extends any = undefined>(model: VariableModel, data?: T): VariablePayload<T>;
|
||||||
|
// eslint-disable-next-line
|
||||||
export function toVariablePayload<T extends any = undefined>(
|
export function toVariablePayload<T extends any = undefined>(
|
||||||
obj: VariableIdentifier | VariableModel,
|
obj: VariableIdentifier | VariableModel,
|
||||||
data?: T
|
data?: T
|
||||||
|
@ -20,7 +20,9 @@ describe('ConfigEditor', () => {
|
|||||||
|
|
||||||
it('should set defaults', () => {
|
it('should set defaults', () => {
|
||||||
const options = createDefaultConfigOptions();
|
const options = createDefaultConfigOptions();
|
||||||
|
//@ts-ignore
|
||||||
delete options.jsonData.esVersion;
|
delete options.jsonData.esVersion;
|
||||||
|
//@ts-ignore
|
||||||
delete options.jsonData.timeField;
|
delete options.jsonData.timeField;
|
||||||
delete options.jsonData.maxConcurrentShardRequests;
|
delete options.jsonData.maxConcurrentShardRequests;
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ export default class AppInsightsDatasource extends DataSourceWithBackend<AzureMo
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyTemplateVariables(target: AzureMonitorQuery, scopedVars: ScopedVars): Record<string, any> {
|
applyTemplateVariables(target: AzureMonitorQuery, scopedVars: ScopedVars): Record<string, any> {
|
||||||
const item = target.appInsights;
|
const item = target.appInsights!;
|
||||||
|
|
||||||
const old: any = item;
|
const old: any = item;
|
||||||
// fix for timeGrainUnit which is a deprecated/removed field name
|
// fix for timeGrainUnit which is a deprecated/removed field name
|
||||||
|
@ -16,7 +16,7 @@ export interface AzureMonitorQuery extends DataQuery {
|
|||||||
|
|
||||||
azureMonitor: AzureMetricQuery;
|
azureMonitor: AzureMetricQuery;
|
||||||
azureLogAnalytics: AzureLogsQuery;
|
azureLogAnalytics: AzureLogsQuery;
|
||||||
appInsights: ApplicationInsightsQuery;
|
appInsights?: ApplicationInsightsQuery;
|
||||||
insightsAnalytics: InsightsAnalyticsQuery;
|
insightsAnalytics: InsightsAnalyticsQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ export interface AzureMetricQuery {
|
|||||||
metricDefinition: string;
|
metricDefinition: string;
|
||||||
metricNamespace: string;
|
metricNamespace: string;
|
||||||
metricName: string;
|
metricName: string;
|
||||||
timeGrainUnit: string;
|
timeGrainUnit?: string;
|
||||||
timeGrain: string;
|
timeGrain: string;
|
||||||
allowedTimeGrainsMs: number[];
|
allowedTimeGrainsMs: number[];
|
||||||
aggregation: string;
|
aggregation: string;
|
||||||
|
@ -46,7 +46,7 @@ export class ConfigEditor extends PureComponent<Props> {
|
|||||||
onVersionChanged = (selected: SelectableValue<InfluxVersion>) => {
|
onVersionChanged = (selected: SelectableValue<InfluxVersion>) => {
|
||||||
const { options, onOptionsChange } = this.props;
|
const { options, onOptionsChange } = this.props;
|
||||||
|
|
||||||
const copy = {
|
const copy: any = {
|
||||||
...options,
|
...options,
|
||||||
jsonData: {
|
jsonData: {
|
||||||
...options.jsonData,
|
...options.jsonData,
|
||||||
|
@ -64,7 +64,7 @@ describe('InfluxLogsQueryField', () => {
|
|||||||
const wrapper = getInfluxLogsQueryField();
|
const wrapper = getInfluxLogsQueryField();
|
||||||
// Looks strange but we do async stuff in didMount and this will push the stack at the end of eval loop, effectively
|
// Looks strange but we do async stuff in didMount and this will push the stack at the end of eval loop, effectively
|
||||||
// waiting for the didMount to finish.
|
// waiting for the didMount to finish.
|
||||||
await Promise.resolve();
|
await new Promise(resolve => setImmediate(resolve));
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
const cascader = wrapper.find(ButtonCascader);
|
const cascader = wrapper.find(ButtonCascader);
|
||||||
expect(cascader.prop('options')).toEqual([
|
expect(cascader.prop('options')).toEqual([
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { mount } from 'enzyme';
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import RCCascader from 'rc-cascader';
|
import RCCascader from 'rc-cascader';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PromQlLanguageProvider, { DEFAULT_LOOKUP_METRICS_THRESHOLD } from '../language_provider';
|
import PromQlLanguageProvider, { DEFAULT_LOOKUP_METRICS_THRESHOLD } from '../language_provider';
|
||||||
import PromQueryField, { groupMetricsByPrefix, RECORDING_RULES_GROUP } from './PromQueryField';
|
import PromQueryField, { groupMetricsByPrefix, RECORDING_RULES_GROUP } from './PromQueryField';
|
||||||
import { ButtonCascader } from '@grafana/ui';
|
|
||||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||||
import { PromOptions } from '../types';
|
import { PromOptions } from '../types';
|
||||||
|
import { fireEvent, render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
describe('PromQueryField', () => {
|
describe('PromQueryField', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
@ -21,7 +20,7 @@ describe('PromQueryField', () => {
|
|||||||
},
|
},
|
||||||
} as unknown) as DataSourceInstanceSettings<PromOptions>;
|
} as unknown) as DataSourceInstanceSettings<PromOptions>;
|
||||||
|
|
||||||
const queryField = mount(
|
const queryField = render(
|
||||||
<PromQueryField
|
<PromQueryField
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
datasource={datasource}
|
datasource={datasource}
|
||||||
@ -32,11 +31,11 @@ describe('PromQueryField', () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(queryField.find(ButtonCascader).length).toBe(1);
|
expect(queryField.getAllByRole('button')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a disabled metrics chooser if lookups are disabled in datasource settings', () => {
|
it('renders a disabled metrics chooser if lookups are disabled in datasource settings', () => {
|
||||||
const queryField = mount(
|
const queryField = render(
|
||||||
<PromQueryField
|
<PromQueryField
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
datasource={{ lookupsDisabled: true }}
|
datasource={{ lookupsDisabled: true }}
|
||||||
@ -47,12 +46,8 @@ describe('PromQueryField', () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
const bcButton = queryField.getByRole('button');
|
||||||
queryField
|
expect(bcButton).toBeDisabled();
|
||||||
.find(ButtonCascader)
|
|
||||||
.find('button')
|
|
||||||
.props().disabled
|
|
||||||
).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('refreshes metrics when the data source changes', async () => {
|
it('refreshes metrics when the data source changes', async () => {
|
||||||
@ -68,7 +63,7 @@ describe('PromQueryField', () => {
|
|||||||
},
|
},
|
||||||
} as unknown) as PromQlLanguageProvider;
|
} as unknown) as PromQlLanguageProvider;
|
||||||
|
|
||||||
const queryField = mount(
|
const queryField = render(
|
||||||
<PromQueryField
|
<PromQueryField
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
datasource={{
|
datasource={{
|
||||||
@ -80,29 +75,36 @@ describe('PromQueryField', () => {
|
|||||||
history={[]}
|
history={[]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
await Promise.resolve();
|
|
||||||
|
|
||||||
const cascader = queryField.find<RCCascader>(RCCascader);
|
let cascader = await queryField.findByRole('button');
|
||||||
cascader.simulate('click');
|
fireEvent.keyDown(cascader, { keyCode: 40 });
|
||||||
const cascaderNode: HTMLElement = cascader.instance().getPopupDOMNode();
|
let listNodes = screen.getAllByRole('menuitem');
|
||||||
|
for (const node of listNodes) {
|
||||||
for (const item of Array.from(cascaderNode.getElementsByTagName('li'))) {
|
expect(metrics).toContain(node.innerHTML);
|
||||||
expect(metrics.includes(item.innerHTML)).toBe(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const changedMetrics = ['baz', 'moo'];
|
const changedMetrics = ['baz', 'moo'];
|
||||||
queryField.setProps({
|
queryField.rerender(
|
||||||
datasource: {
|
<PromQueryField
|
||||||
languageProvider: {
|
datasource={{
|
||||||
...languageProvider,
|
//@ts-ignore
|
||||||
metrics: changedMetrics,
|
languageProvider: {
|
||||||
},
|
...languageProvider,
|
||||||
},
|
metrics: changedMetrics,
|
||||||
});
|
},
|
||||||
await Promise.resolve();
|
}}
|
||||||
|
query={{ expr: '', refId: '' }}
|
||||||
|
onRunQuery={() => {}}
|
||||||
|
onChange={() => {}}
|
||||||
|
history={[]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
for (const item of Array.from(cascaderNode.getElementsByTagName('li'))) {
|
cascader = await queryField.findByRole('button');
|
||||||
expect(changedMetrics.includes(item.innerHTML)).toBe(true);
|
fireEvent.keyDown(cascader, { keyCode: 40 });
|
||||||
|
listNodes = screen.getAllByRole('menuitem');
|
||||||
|
for (const node of listNodes) {
|
||||||
|
expect(changedMetrics).toContain(node.innerHTML);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user