Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(grafana): migrate jest #435

Merged
merged 1 commit into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .config/jest-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-jest-config
*/

import '@testing-library/jest-dom';

// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
Object.defineProperty(global, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});

HTMLCanvasElement.prototype.getContext = () => {};
43 changes: 43 additions & 0 deletions .config/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-jest-config
*/

const path = require('path');
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils');

module.exports = {
moduleNameMapper: {
'\\.(css|scss|sass)$': 'identity-obj-proxy',
'react-inlinesvg': path.resolve(__dirname, 'jest', 'mocks', 'react-inlinesvg.tsx'),
},
modulePaths: ['<rootDir>/src'],
setupFilesAfterEnv: ['<rootDir>/jest-setup.js'],
testEnvironment: 'jest-environment-jsdom',
testMatch: [
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
'<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}',
'<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}',
],
transform: {
'^.+\\.(t|j)sx?$': [
'@swc/jest',
{
sourceMaps: 'inline',
jsc: {
parser: {
syntax: 'typescript',
tsx: true,
decorators: false,
dynamicImport: true,
},
},
},
],
},
// Jest will throw `Cannot use import statement outside module` if it tries to load an
// ES module without it being transformed first. ./config/README.md#esm-errors-with-jest
transformIgnorePatterns: [nodeModulesToTransform(grafanaESModules)],
};
25 changes: 25 additions & 0 deletions .config/jest/mocks/react-inlinesvg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Due to the grafana/ui Icon component making fetch requests to
// `/public/img/icon/<icon_name>.svg` we need to mock react-inlinesvg to prevent
// the failed fetch requests from displaying errors in console.

import React from 'react';

type Callback = (...args: any[]) => void;

export interface StorageItem {
content: string;
queue: Callback[];
status: string;
}

export const cacheStore: { [key: string]: StorageItem } = Object.create(null);

const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/;

const InlineSVG = ({ src }: { src: string }) => {
// testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`)
const testId = src.replace(SVG_FILE_NAME_REGEX, '$2');
return <svg xmlns="http://www.w3.org/2000/svg" data-testid={testId} viewBox="0 0 24 24" />;
};

export default InlineSVG;
29 changes: 29 additions & 0 deletions .config/jest/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in .config/README.md
*/

/*
* This utility function is useful in combination with jest `transformIgnorePatterns` config
* to transform specific packages (e.g.ES modules) in a projects node_modules folder.
*/
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!(${moduleNames.join('|')})\/)`;

// Array of known nested grafana package dependencies that only bundle an ESM version
const grafanaESModules = [
'.pnpm', // Support using pnpm symlinked packages
'd3',
'd3-color',
'd3-force',
'd3-interpolate',
'd3-scale-chromatic',
'ol',
'react-colorful',
'uuid',
];

module.exports = {
nodeModulesToTransform,
grafanaESModules
}
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ jobs:
- name: Check types
run: yarn run typecheck

- name: Unit tests
run: yarn run test:ci

- name: Build and test frontend
run: yarn build

Expand Down
2 changes: 2 additions & 0 deletions jest-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Jest setup provided by Grafana scaffolding
import './.config/jest-setup';
14 changes: 7 additions & 7 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// This file is needed because it is used by vscode and other tools that
// call `jest` directly. However, unless you are doing anything special
// do not edit this file
// force timezone to UTC to allow tests to work regardless of local timezone
// generally used by snapshots, but can affect specific tests
process.env.TZ = 'UTC';

const standard = require('@grafana/toolkit/src/config/jest.plugin.config');

// This process will use the same config that `yarn test` is using
module.exports = standard.jestConfig();
module.exports = {
// Jest configuration provided by Grafana scaffolding
...require('./.config/jest.config'),
};
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"prettier:write": "yarn run prettier:check --write",
"release:minor": "npm version minor && yarn run build-sign-release",
"release:patch": "npm version patch && yarn run build-sign-release",
"test": "jest --watch --onlyChanged",
"test:ci": "jest --passWithNoTests --maxWorkers 4",
"typecheck": "tsc --noEmit"
},
"repository": {
Expand All @@ -33,8 +35,10 @@
"@grafana/tsconfig": "^1.2.0-rc1",
"@swc/core": "^1.3.65",
"@swc/helpers": "^0.5.1",
"@swc/jest": "^0.2.26",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@types/jest": "^29.5.0",
"@types/lodash": "^4.14.195",
"@types/node": "^18.15.11",
"@types/react-virtualized-auto-sizer": "^1.0.0",
Expand All @@ -48,6 +52,9 @@
"eslint-webpack-plugin": "^4.0.1",
"fork-ts-checker-webpack-plugin": "^8.0.0",
"glob": "^10.2.7",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"prettier": "^2.8.7",
"replace-in-file-webpack-plugin": "^1.0.6",
"sass": "1.63.2",
Expand Down
Loading