Merge pull request #2144 from hereje/refactor/replace-jest-with-vitest

refactor: replace jest with vitest
This commit is contained in:
David Baker
2024-02-16 10:34:00 +00:00
committed by GitHub
14 changed files with 482 additions and 1589 deletions

View File

@@ -1,11 +1,11 @@
name: Run jest tests name: Run unit tests
on: on:
pull_request: {} pull_request: {}
push: push:
branches: [livekit, full-mesh] branches: [livekit, full-mesh]
jobs: jobs:
jest: vitest:
name: Run jest tests name: Run vitest tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
@@ -16,7 +16,7 @@ jobs:
cache: "yarn" cache: "yarn"
- name: Install dependencies - name: Install dependencies
run: "yarn install" run: "yarn install"
- name: Jest - name: Vitest
run: "yarn run test" run: "yarn run test"
- name: Upload to codecov - name: Upload to codecov
uses: codecov/codecov-action@v4 uses: codecov/codecov-action@v4

View File

@@ -13,7 +13,8 @@
"lint:types": "tsc", "lint:types": "tsc",
"i18n": "node_modules/i18next-parser/bin/cli.js", "i18n": "node_modules/i18next-parser/bin/cli.js",
"i18n:check": "node_modules/i18next-parser/bin/cli.js --fail-on-warnings --fail-on-update", "i18n:check": "node_modules/i18next-parser/bin/cli.js --fail-on-warnings --fail-on-update",
"test": "jest", "test": "vitest",
"test:coverage": "vitest run --coverage",
"backend": "docker-compose -f backend-docker-compose.yml up" "backend": "docker-compose -f backend-docker-compose.yml up"
}, },
"dependencies": { "dependencies": {
@@ -88,14 +89,12 @@
"@react-spring/rafz": "^9.7.3", "@react-spring/rafz": "^9.7.3",
"@react-types/dialog": "^3.5.5", "@react-types/dialog": "^3.5.5",
"@sentry/vite-plugin": "^2.0.0", "@sentry/vite-plugin": "^2.0.0",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^14.0.0", "@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.5.1", "@testing-library/user-event": "^14.5.1",
"@types/content-type": "^1.1.5", "@types/content-type": "^1.1.5",
"@types/dom-screen-wake-lock": "^1.0.1", "@types/dom-screen-wake-lock": "^1.0.1",
"@types/dompurify": "^3.0.2", "@types/dompurify": "^3.0.2",
"@types/grecaptcha": "^3.0.4", "@types/grecaptcha": "^3.0.4",
"@types/jest": "^29.5.5",
"@types/node": "^20.0.0", "@types/node": "^20.0.0",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"@types/request": "^2.48.8", "@types/request": "^2.48.8",
@@ -116,37 +115,14 @@
"eslint-plugin-react-hooks": "^4.5.0", "eslint-plugin-react-hooks": "^4.5.0",
"eslint-plugin-unicorn": "^51.0.0", "eslint-plugin-unicorn": "^51.0.0",
"i18next-parser": "^8.0.0", "i18next-parser": "^8.0.0",
"identity-obj-proxy": "^3.0.0", "jsdom": "^24.0.0",
"jest": "^29.2.2",
"jest-environment-jsdom": "^29.3.1",
"jest-mock": "^29.5.0",
"prettier": "^3.0.0", "prettier": "^3.0.0",
"sass": "^1.42.1", "sass": "^1.42.1",
"typescript": "^5.1.6", "typescript": "^5.1.6",
"typescript-eslint-language-service": "^5.0.5", "typescript-eslint-language-service": "^5.0.5",
"vite": "^5.0.0", "vite": "^5.0.0",
"vite-plugin-html-template": "^1.1.0", "vite-plugin-html-template": "^1.1.0",
"vite-plugin-svgr": "^4.0.0" "vite-plugin-svgr": "^4.0.0",
}, "vitest": "^1.2.2"
"jest": {
"testEnvironment": "./test/environment.ts",
"testMatch": [
"<rootDir>/test/**/*-test.[jt]s?(x)"
],
"transformIgnorePatterns": [
"/node_modules/(?!d3)+$",
"/node_modules/(?!internmap)+$"
],
"moduleNameMapper": {
"\\.css$": "identity-obj-proxy",
"\\.svg\\?react$": "<rootDir>/test/mocks/svgr.ts",
"^\\./IndexedDBWorker\\?worker$": "<rootDir>/test/mocks/workerMock.ts",
"^\\./olm$": "<rootDir>/test/mocks/olmMock.ts"
},
"collectCoverage": true,
"coverageReporters": [
"text",
"cobertura"
]
} }
} }

View File

@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { vi } from "vitest";
import { screen, render } from "@testing-library/react"; import { screen, render } from "@testing-library/react";
import { Toast } from "../src/Toast"; import { Toast } from "../src/Toast";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
@@ -35,7 +36,7 @@ test("Toast renders", () => {
}); });
test("Toast dismisses when clicked", async () => { test("Toast dismisses when clicked", async () => {
const onDismiss = jest.fn(); const onDismiss = vi.fn();
render( render(
<Toast open={true} onDismiss={onDismiss}> <Toast open={true} onDismiss={onDismiss}>
Hello world! Hello world!
@@ -47,13 +48,13 @@ test("Toast dismisses when clicked", async () => {
test("Toast dismisses itself after the specified timeout", async () => { test("Toast dismisses itself after the specified timeout", async () => {
withFakeTimers(() => { withFakeTimers(() => {
const onDismiss = jest.fn(); const onDismiss = vi.fn();
render( render(
<Toast open={true} onDismiss={onDismiss} autoDismiss={2000}> <Toast open={true} onDismiss={onDismiss} autoDismiss={2000}>
Hello world! Hello world!
</Toast>, </Toast>,
); );
jest.advanceTimersByTime(2000); vi.advanceTimersByTime(2000);
expect(onDismiss).toHaveBeenCalled(); expect(onDismiss).toHaveBeenCalled();
}); });
}); });

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { mocked } from "jest-mock"; import { vi } from "vitest";
import { getRoomIdentifierFromUrl } from "../src/UrlParams"; import { getRoomIdentifierFromUrl } from "../src/UrlParams";
import { Config } from "../src/config/Config"; import { Config } from "../src/config/Config";
@@ -24,11 +24,11 @@ const ROOM_ID = "!d45f138fsd";
const ORIGIN = "https://call.element.io"; const ORIGIN = "https://call.element.io";
const HOMESERVER = "call.ems.host"; const HOMESERVER = "call.ems.host";
jest.mock("../src/config/Config"); vi.mock("../src/config/Config");
describe("UrlParams", () => { describe("UrlParams", () => {
beforeAll(() => { beforeAll(() => {
mocked(Config.defaultServerName).mockReturnValue("call.ems.host"); vi.mocked(Config.defaultServerName).mockReturnValue("call.ems.host");
}); });
describe("handles URL with /room/", () => { describe("handles URL with /room/", () => {

View File

@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Toast renders 1`] = ` exports[`Toast renders 1`] = `
<button <button

View File

@@ -1,18 +0,0 @@
import { TextEncoder } from "util";
import JSDOMEnvironment_, {
TestEnvironment as TestEnvironment_,
} from "jest-environment-jsdom";
import { JestEnvironmentConfig, EnvironmentContext } from "@jest/environment";
// This is a patched version of jsdom that adds TextEncoder, as a workaround for
// https://github.com/jsdom/jsdom/issues/2524
// Once that issue is resolved, this custom environment file can be deleted
export default class JSDOMEnvironment extends JSDOMEnvironment_ {
constructor(config: JestEnvironmentConfig, context: EnvironmentContext) {
super(config, context);
this.global.TextEncoder ??= TextEncoder;
}
}
export const TestEnvironment =
TestEnvironment_ === JSDOMEnvironment_ ? JSDOMEnvironment : TestEnvironment_;

View File

@@ -1 +0,0 @@
module.exports = { loadOlm: jest.fn(async () => {}) };

View File

@@ -1,3 +0,0 @@
// Mock file for SVG imports
const ReactComponent = "svg";
export default ReactComponent;

View File

@@ -1 +0,0 @@
module.exports = jest.fn();

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { Mocked, mocked } from "jest-mock"; import { vi, Mocked } from "vitest";
import { RoomState } from "matrix-js-sdk/src/models/room-state"; import { RoomState } from "matrix-js-sdk/src/models/room-state";
import { PosthogAnalytics } from "../../src/analytics/PosthogAnalytics"; import { PosthogAnalytics } from "../../src/analytics/PosthogAnalytics";
import { checkForParallelCalls } from "../../src/room/checkForParallelCalls"; import { checkForParallelCalls } from "../../src/room/checkForParallelCalls";
@@ -23,10 +23,10 @@ import { withFakeTimers } from "../utils";
const withMockedPosthog = ( const withMockedPosthog = (
continuation: (posthog: Mocked<PosthogAnalytics>) => void, continuation: (posthog: Mocked<PosthogAnalytics>) => void,
) => { ) => {
const posthog = mocked({ const posthog = vi.mocked({
trackEvent: jest.fn(), trackEvent: vi.fn(),
} as unknown as PosthogAnalytics); } as unknown as PosthogAnalytics);
const instanceSpy = jest const instanceSpy = vi
.spyOn(PosthogAnalytics, "instance", "get") .spyOn(PosthogAnalytics, "instance", "get")
.mockReturnValue(posthog); .mockReturnValue(posthog);
try { try {

View File

@@ -13,12 +13,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { vi } from "vitest";
export function withFakeTimers(continuation: () => void): void { export function withFakeTimers(continuation: () => void): void {
jest.useFakeTimers(); vi.useFakeTimers();
try { try {
continuation(); continuation();
} finally { } finally {
jest.useRealTimers(); vi.useRealTimers();
} }
} }

View File

@@ -12,9 +12,23 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"esModuleInterop": true, "esModuleInterop": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"moduleResolution": "node", "moduleResolution": "bundler",
"declaration": true, "declaration": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"paths": {
// These imports within @livekit/components-core and
// @livekit/components-react are broken under the "bundler" module
// resolution mode, so we need to resolve them manually
"livekit-client/dist/src/room/Room": [
"./node_modules/livekit-client/dist/src/room/Room.d.ts"
],
"livekit-client/dist/src/room/participant/Participant": [
"./node_modules/livekit-client/dist/src/room/participant/Participant.d.ts"
],
"livekit-client/dist/src/proto/livekit_models_pb": [
"./node_modules/livekit-client/dist/src/proto/livekit_models_pb.d.ts"
]
},
// TODO: Enable the following options later. // TODO: Enable the following options later.
// "forceConsistentCasingInFileNames": true, // "forceConsistentCasingInFileNames": true,
@@ -29,6 +43,7 @@
}, },
"include": [ "include": [
"./node_modules/matrix-js-sdk/src/@types/*.d.ts", "./node_modules/matrix-js-sdk/src/@types/*.d.ts",
"./node_modules/vitest/globals.d.ts",
"./src/**/*.ts", "./src/**/*.ts",
"./src/**/*.tsx", "./src/**/*.tsx",
"./test/**/*.ts", "./test/**/*.ts",

24
vitest.config.js Normal file
View File

@@ -0,0 +1,24 @@
import { defineConfig, mergeConfig } from "vitest/config";
import viteConfig from "./vite.config";
export default defineConfig((configEnv) =>
mergeConfig(
viteConfig(configEnv),
defineConfig({
test: {
globals: true,
environment: "jsdom",
css: {
modules: {
classNameStrategy: "non-scoped",
},
},
include: ["test/**/*-test.[jt]s?(x)"],
coverage: {
reporter: ["text", "html"],
exclude: ["node_modules/"],
},
},
}),
),
);

1937
yarn.lock

File diff suppressed because it is too large Load Diff