♻️(docs-app) Switch from Jest tests to Vitest
We have migrated the testing framework from Jest to Vitest for the Docs application. This change includes updates to test files, configuration files, and the addition of new setup files for Vitest.
This commit is contained in:
@@ -14,6 +14,7 @@ and this project adheres to
|
||||
|
||||
### Changed
|
||||
|
||||
- ♻️(docs-app) Switch from Jest tests to Vitest #1269
|
||||
- ⚡️(frontend) improve accessibility:
|
||||
- #1248
|
||||
- #1235
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
NEXT_PUBLIC_API_ORIGIN=http://test.jest
|
||||
NEXT_PUBLIC_PUBLISH_AS_MIT=false
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import type { Config } from 'jest';
|
||||
import nextJest from 'next/jest.js';
|
||||
|
||||
const createJestConfig = nextJest({
|
||||
dir: './',
|
||||
});
|
||||
|
||||
// Add any custom config to be passed to Jest
|
||||
const config: Config = {
|
||||
coverageProvider: 'v8',
|
||||
moduleNameMapper: {
|
||||
'^@/docs/(.*)$': '<rootDir>/src/features/docs/$1',
|
||||
'^@/(.*)$': '<rootDir>/src/$1',
|
||||
},
|
||||
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||
testEnvironment: 'jsdom',
|
||||
};
|
||||
|
||||
const jestConfig = async () => {
|
||||
const nextJestConfig = await createJestConfig(config)();
|
||||
return {
|
||||
...nextJestConfig,
|
||||
moduleNameMapper: {
|
||||
'\\.svg$': '<rootDir>/jest/mocks/svg.js',
|
||||
'^.+\\.svg\\?url$': `<rootDir>/jest/mocks/fileMock.js`,
|
||||
BlockNoteEditor: `<rootDir>/jest/mocks/ComponentMock.js`,
|
||||
'custom-blocks': `<rootDir>/jest/mocks/ComponentMock.js`,
|
||||
...nextJestConfig.moduleNameMapper,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default jestConfig;
|
||||
@@ -1,4 +0,0 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import * as dotenv from 'dotenv';
|
||||
|
||||
dotenv.config({ path: './.env.test' });
|
||||
@@ -1,5 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
export const ComponentMock = () => {
|
||||
return <div>My component mocked</div>;
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
module.exports = {
|
||||
src: '/img.jpg',
|
||||
height: 40,
|
||||
width: 40,
|
||||
blurDataURL: 'data:image/png;base64,imagedata',
|
||||
};
|
||||
|
||||
if (
|
||||
(typeof exports.default === 'function' ||
|
||||
(typeof exports.default === 'object' && exports.default !== null)) &&
|
||||
typeof exports.default.__esModule === 'undefined'
|
||||
) {
|
||||
Object.defineProperty(exports.default, '__esModule', { value: true });
|
||||
Object.assign(exports.default, exports);
|
||||
module.exports = exports.default;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
const nameMock = 'svg';
|
||||
export default nameMock;
|
||||
export const ReactComponent = 'svg';
|
||||
@@ -11,8 +11,8 @@
|
||||
"lint": "tsc --noEmit && next lint",
|
||||
"prettier": "prettier --write .",
|
||||
"stylelint": "stylelint \"**/*.css\"",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch"
|
||||
"test": "vitest",
|
||||
"test:watch": "vitest --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ag-media/react-pdf-table": "2.0.3",
|
||||
@@ -67,24 +67,25 @@
|
||||
"@testing-library/jest-dom": "6.6.4",
|
||||
"@testing-library/react": "16.3.0",
|
||||
"@testing-library/user-event": "14.6.1",
|
||||
"@types/jest": "30.0.0",
|
||||
"@types/lodash": "4.17.20",
|
||||
"@types/luxon": "3.7.1",
|
||||
"@types/node": "*",
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"@vitejs/plugin-react": "4.7.0",
|
||||
"cross-env": "10.0.0",
|
||||
"dotenv": "17.2.1",
|
||||
"eslint-config-impress": "*",
|
||||
"fetch-mock": "9.11.0",
|
||||
"jest": "30.0.5",
|
||||
"jest-environment-jsdom": "30.0.5",
|
||||
"jsdom": "26.1.0",
|
||||
"node-fetch": "2.7.0",
|
||||
"prettier": "3.6.2",
|
||||
"stylelint": "16.23.0",
|
||||
"stylelint-config-standard": "39.0.0",
|
||||
"stylelint-prettier": "5.0.3",
|
||||
"typescript": "*",
|
||||
"vite-tsconfig-paths": "5.1.4",
|
||||
"vitest": "3.2.4",
|
||||
"webpack": "5.101.0",
|
||||
"workbox-webpack-plugin": "7.1.0"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { APIError, isAPIError } from '@/api';
|
||||
|
||||
describe('APIError', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { baseApiUrl } from '@/api';
|
||||
|
||||
describe('config', () => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { fetchAPI } from '@/api';
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { useAPIInfiniteQuery } from '@/api';
|
||||
|
||||
@@ -21,8 +22,8 @@ const createWrapper = () => {
|
||||
|
||||
describe('helpers', () => {
|
||||
it('fetches and paginates correctly', async () => {
|
||||
const mockAPI = jest
|
||||
.fn<Promise<DummyResponse>, [{ page: number; query: string }]>()
|
||||
const mockAPI = vi
|
||||
.fn<(params: { page: number; query: string }) => Promise<DummyResponse>>()
|
||||
.mockResolvedValueOnce({
|
||||
results: [{ id: 1 }],
|
||||
next: 'url?page=2',
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { errorCauses, getCSRFToken } from '@/api';
|
||||
|
||||
describe('utils', () => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { Box } from '../Box';
|
||||
|
||||
@@ -1,42 +1,28 @@
|
||||
import { Crisp } from 'crisp-sdk-web';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { gotoLogout } from '../utils';
|
||||
|
||||
jest.mock('crisp-sdk-web', () => ({
|
||||
...jest.requireActual('crisp-sdk-web'),
|
||||
Crisp: {
|
||||
isCrispInjected: jest.fn().mockReturnValue(true),
|
||||
setTokenId: jest.fn(),
|
||||
user: {
|
||||
setEmail: jest.fn(),
|
||||
},
|
||||
session: {
|
||||
reset: jest.fn(),
|
||||
},
|
||||
},
|
||||
// Mock the Crisp service
|
||||
vi.mock('@/services/Crisp', () => ({
|
||||
terminateCrispSession: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('utils', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
vi.clearAllMocks();
|
||||
fetchMock.restore();
|
||||
});
|
||||
|
||||
it('checks support session is terminated when logout', () => {
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
it('checks support session is terminated when logout', async () => {
|
||||
const { terminateCrispSession } = await import('@/services/Crisp');
|
||||
|
||||
window.$crisp = true;
|
||||
const propertyDescriptors = Object.getOwnPropertyDescriptors(window);
|
||||
for (const key in propertyDescriptors) {
|
||||
propertyDescriptors[key].configurable = true;
|
||||
}
|
||||
const clonedWindow = Object.defineProperties({}, propertyDescriptors);
|
||||
|
||||
Object.defineProperty(clonedWindow, 'location', {
|
||||
// Mock window.location.replace
|
||||
const mockReplace = vi.fn();
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: {
|
||||
...window.location,
|
||||
replace: jest.fn(),
|
||||
replace: mockReplace,
|
||||
},
|
||||
writable: true,
|
||||
configurable: true,
|
||||
@@ -44,6 +30,9 @@ describe('utils', () => {
|
||||
|
||||
gotoLogout();
|
||||
|
||||
expect(Crisp.session.reset).toHaveBeenCalled();
|
||||
expect(terminateCrispSession).toHaveBeenCalled();
|
||||
expect(mockReplace).toHaveBeenCalledWith(
|
||||
'http://test.jest/api/v1.0/logout/',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { renderHook, waitFor } from '@testing-library/react';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { Fragment } from 'react';
|
||||
import { beforeEach, describe, expect, vi } from 'vitest';
|
||||
|
||||
import { AbstractAnalytic } from '@/libs';
|
||||
import { AppWrapper } from '@/tests/utils';
|
||||
|
||||
import { useAuth } from '../useAuth';
|
||||
|
||||
const trackEventMock = jest.fn();
|
||||
const trackEventMock = vi.fn();
|
||||
const flag = true;
|
||||
class TestAnalytic extends AbstractAnalytic {
|
||||
public constructor() {
|
||||
@@ -31,11 +32,11 @@ class TestAnalytic extends AbstractAnalytic {
|
||||
}
|
||||
}
|
||||
|
||||
jest.mock('next/router', () => ({
|
||||
...jest.requireActual('next/router'),
|
||||
vi.mock('next/router', async () => ({
|
||||
...(await vi.importActual('next/router')),
|
||||
useRouter: () => ({
|
||||
pathname: '/dashboard',
|
||||
replace: jest.fn(),
|
||||
replace: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -43,7 +44,7 @@ const dummyUser = { id: '123', email: 'test@example.com' };
|
||||
|
||||
describe('useAuth hook - trackEvent effect', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
vi.clearAllMocks();
|
||||
fetchMock.restore();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,36 +1,38 @@
|
||||
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { AppWrapper } from '@/tests/utils';
|
||||
|
||||
import { useSaveDoc } from '../useSaveDoc';
|
||||
|
||||
jest.mock('next/router', () => ({
|
||||
useRouter: jest.fn(),
|
||||
vi.mock('next/router', () => ({
|
||||
useRouter: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/docs/doc-versioning', () => ({
|
||||
vi.mock('@/docs/doc-versioning', () => ({
|
||||
KEY_LIST_DOC_VERSIONS: 'test-key-list-doc-versions',
|
||||
}));
|
||||
|
||||
jest.mock('@/docs/doc-management', () => ({
|
||||
useUpdateDoc: jest.requireActual('@/docs/doc-management/api/useUpdateDoc')
|
||||
.useUpdateDoc,
|
||||
vi.mock('@/docs/doc-management', async () => ({
|
||||
useUpdateDoc: (
|
||||
await vi.importActual('@/docs/doc-management/api/useUpdateDoc')
|
||||
).useUpdateDoc,
|
||||
}));
|
||||
|
||||
describe('useSaveDoc', () => {
|
||||
const mockRouterEvents = {
|
||||
on: jest.fn(),
|
||||
off: jest.fn(),
|
||||
on: vi.fn(),
|
||||
off: vi.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
vi.clearAllMocks();
|
||||
fetchMock.restore();
|
||||
|
||||
(useRouter as jest.Mock).mockReturnValue({
|
||||
(useRouter as Mock).mockReturnValue({
|
||||
events: mockRouterEvents,
|
||||
});
|
||||
});
|
||||
@@ -39,7 +41,7 @@ describe('useSaveDoc', () => {
|
||||
const yDoc = new Y.Doc();
|
||||
const docId = 'test-doc-id';
|
||||
|
||||
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
||||
const addEventListenerSpy = vi.spyOn(window, 'addEventListener');
|
||||
|
||||
renderHook(() => useSaveDoc(docId, yDoc, true, true), {
|
||||
wrapper: AppWrapper,
|
||||
@@ -60,8 +62,8 @@ describe('useSaveDoc', () => {
|
||||
addEventListenerSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should not save when canSave is false', async () => {
|
||||
jest.useFakeTimers();
|
||||
it('should not save when canSave is false', () => {
|
||||
vi.useFakeTimers();
|
||||
const yDoc = new Y.Doc();
|
||||
const docId = 'test-doc-id';
|
||||
|
||||
@@ -80,22 +82,19 @@ describe('useSaveDoc', () => {
|
||||
act(() => {
|
||||
// Trigger a local update
|
||||
yDoc.getMap('test').set('key', 'value');
|
||||
|
||||
// Advance timers to trigger the save interval
|
||||
vi.advanceTimersByTime(61000);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
// Now advance timers after state has updated
|
||||
jest.advanceTimersByTime(61000);
|
||||
});
|
||||
// Since canSave is false, no API call should be made
|
||||
expect(fetchMock.calls().length).toBe(0);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(fetchMock.calls().length).toBe(0);
|
||||
});
|
||||
|
||||
jest.useRealTimers();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('should save when there are local changes', async () => {
|
||||
jest.useFakeTimers();
|
||||
vi.useFakeTimers();
|
||||
const yDoc = new Y.Doc();
|
||||
const docId = 'test-doc-id';
|
||||
|
||||
@@ -117,21 +116,22 @@ describe('useSaveDoc', () => {
|
||||
});
|
||||
|
||||
act(() => {
|
||||
// Now advance timers after state has updated
|
||||
jest.advanceTimersByTime(61000);
|
||||
// Advance timers to trigger the save interval
|
||||
vi.advanceTimersByTime(61000);
|
||||
});
|
||||
|
||||
// Switch to real timers to allow the mutation promise to resolve
|
||||
vi.useRealTimers();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(fetchMock.lastCall()?.[0]).toBe(
|
||||
'http://test.jest/api/v1.0/documents/test-doc-id/',
|
||||
);
|
||||
});
|
||||
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should not save when there are no local changes', async () => {
|
||||
jest.useFakeTimers();
|
||||
it('should not save when there are no local changes', () => {
|
||||
vi.useFakeTimers();
|
||||
const yDoc = new Y.Doc();
|
||||
const docId = 'test-doc-id';
|
||||
|
||||
@@ -148,21 +148,20 @@ describe('useSaveDoc', () => {
|
||||
});
|
||||
|
||||
act(() => {
|
||||
// Now advance timers after state has updated
|
||||
jest.advanceTimersByTime(61000);
|
||||
// Advance timers without triggering any local updates
|
||||
vi.advanceTimersByTime(61000);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(fetchMock.calls().length).toBe(0);
|
||||
});
|
||||
// Since there are no local changes, no API call should be made
|
||||
expect(fetchMock.calls().length).toBe(0);
|
||||
|
||||
jest.useRealTimers();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('should cleanup event listeners on unmount', () => {
|
||||
const yDoc = new Y.Doc();
|
||||
const docId = 'test-doc-id';
|
||||
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
|
||||
const removeEventListenerSpy = vi.spyOn(window, 'removeEventListener');
|
||||
|
||||
const { unmount } = renderHook(() => useSaveDoc(docId, yDoc, true, true), {
|
||||
wrapper: AppWrapper,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { afterAll, afterEach, describe, expect, it, vi } from 'vitest';
|
||||
const originalEnv = process.env.NEXT_PUBLIC_PUBLISH_AS_MIT;
|
||||
|
||||
jest.mock('@/features/docs/doc-export/utils', () => ({
|
||||
vi.mock('@/features/docs/doc-export/utils', () => ({
|
||||
anything: true,
|
||||
}));
|
||||
jest.mock('@/features/docs/doc-export/components/ModalExport', () => ({
|
||||
vi.mock('@/features/docs/doc-export/components/ModalExport', () => ({
|
||||
ModalExport: () => <span>ModalExport</span>,
|
||||
}));
|
||||
|
||||
@@ -13,8 +14,8 @@ describe('useModuleExport', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
it('should return undefined when NEXT_PUBLIC_PUBLISH_AS_MIT is true', async () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React, { Fragment } from 'react';
|
||||
import { beforeEach, describe, expect, vi } from 'vitest';
|
||||
|
||||
import { AbstractAnalytic, Analytics } from '@/libs';
|
||||
import { AppWrapper } from '@/tests/utils';
|
||||
@@ -28,14 +29,10 @@ class TestAnalytic extends AbstractAnalytic {
|
||||
}
|
||||
}
|
||||
|
||||
jest.mock('@/features/docs/doc-export/', () => ({
|
||||
ModalExport: () => <span>ModalExport</span>,
|
||||
}));
|
||||
|
||||
jest.mock('next/router', () => ({
|
||||
...jest.requireActual('next/router'),
|
||||
vi.mock('next/router', async () => ({
|
||||
...(await vi.importActual('next/router')),
|
||||
useRouter: () => ({
|
||||
push: jest.fn(),
|
||||
push: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,34 +1,30 @@
|
||||
/**
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { RequestSerializer } from '../RequestSerializer';
|
||||
import { ApiPlugin } from '../plugins/ApiPlugin';
|
||||
|
||||
const mockedGet = jest.fn().mockResolvedValue({});
|
||||
const mockedGetAllKeys = jest.fn().mockResolvedValue([]);
|
||||
const mockedPut = jest.fn().mockResolvedValue({});
|
||||
const mockedDelete = jest.fn().mockResolvedValue({});
|
||||
const mockedClose = jest.fn().mockResolvedValue({});
|
||||
const mockedOpendDB = jest.fn().mockResolvedValue({
|
||||
const mockedGet = vi.fn().mockResolvedValue({});
|
||||
const mockedGetAllKeys = vi.fn().mockResolvedValue([]);
|
||||
const mockedPut = vi.fn().mockResolvedValue({});
|
||||
const mockedDelete = vi.fn().mockResolvedValue({});
|
||||
const mockedClose = vi.fn().mockResolvedValue({});
|
||||
const mockedOpendDB = vi.fn().mockResolvedValue({
|
||||
get: mockedGet,
|
||||
getAllKeys: mockedGetAllKeys,
|
||||
getAll: jest.fn().mockResolvedValue([]),
|
||||
getAll: vi.fn().mockResolvedValue([]),
|
||||
put: mockedPut,
|
||||
delete: mockedDelete,
|
||||
clear: jest.fn().mockResolvedValue({}),
|
||||
clear: vi.fn().mockResolvedValue({}),
|
||||
close: mockedClose,
|
||||
});
|
||||
|
||||
jest.mock('idb', () => ({
|
||||
...jest.requireActual('idb'),
|
||||
vi.mock('idb', async () => ({
|
||||
...(await vi.importActual('idb')),
|
||||
openDB: () => mockedOpendDB(),
|
||||
}));
|
||||
|
||||
describe('ApiPlugin', () => {
|
||||
afterEach(() => jest.clearAllMocks());
|
||||
afterEach(() => vi.clearAllMocks());
|
||||
|
||||
[
|
||||
{ type: 'item', table: 'doc-item' },
|
||||
@@ -36,7 +32,7 @@ describe('ApiPlugin', () => {
|
||||
{ type: 'update', table: 'doc-item' },
|
||||
].forEach(({ type, table }) => {
|
||||
it(`calls fetchDidSucceed with type ${type} and status 200`, async () => {
|
||||
const mockedSync = jest.fn().mockResolvedValue({});
|
||||
const mockedSync = vi.fn().mockResolvedValue({});
|
||||
const apiPlugin = new ApiPlugin({
|
||||
tableName: table as any,
|
||||
type: type as any,
|
||||
@@ -55,7 +51,7 @@ describe('ApiPlugin', () => {
|
||||
json: () => body,
|
||||
} as unknown as Request,
|
||||
} as any;
|
||||
const mockedClone = jest.fn().mockReturnValue(requestInit.request);
|
||||
const mockedClone = vi.fn().mockReturnValue(requestInit.request);
|
||||
await apiPlugin.requestWillFetch?.(requestInit);
|
||||
|
||||
const response = await apiPlugin.fetchDidSucceed?.({
|
||||
@@ -81,7 +77,7 @@ describe('ApiPlugin', () => {
|
||||
const apiPlugin = new ApiPlugin({
|
||||
tableName: table as any,
|
||||
type: type as any,
|
||||
syncManager: jest.fn() as any,
|
||||
syncManager: vi.fn() as any,
|
||||
});
|
||||
|
||||
const body = { lastName: 'Doe' };
|
||||
@@ -114,7 +110,7 @@ describe('ApiPlugin', () => {
|
||||
{ type: 'item', withClone: false },
|
||||
].forEach(({ type, withClone }) => {
|
||||
it(`calls requestWillFetch with type ${type}`, async () => {
|
||||
const mockedSync = jest.fn().mockResolvedValue({});
|
||||
const mockedSync = vi.fn().mockResolvedValue({});
|
||||
|
||||
const apiPlugin = new ApiPlugin({
|
||||
type: 'update',
|
||||
@@ -123,7 +119,7 @@ describe('ApiPlugin', () => {
|
||||
} as any,
|
||||
});
|
||||
|
||||
const mockedClone = jest.fn().mockResolvedValue({});
|
||||
const mockedClone = vi.fn().mockResolvedValue({});
|
||||
const requestInit = {
|
||||
request: {
|
||||
url: 'test-url',
|
||||
@@ -189,9 +185,9 @@ describe('ApiPlugin', () => {
|
||||
} as unknown as Request,
|
||||
} as any;
|
||||
|
||||
const mockedClone = jest.fn().mockReturnValue(requestInit.request);
|
||||
const mockedClone = vi.fn().mockReturnValue(requestInit.request);
|
||||
|
||||
const mockedSync = jest.fn().mockResolvedValue({});
|
||||
const mockedSync = vi.fn().mockResolvedValue({});
|
||||
const apiPlugin = new ApiPlugin({
|
||||
type: 'update',
|
||||
syncManager: {
|
||||
@@ -265,9 +261,9 @@ describe('ApiPlugin', () => {
|
||||
} as unknown as Request,
|
||||
} as any;
|
||||
|
||||
const mockedClone = jest.fn().mockReturnValue(requestInit.request);
|
||||
const mockedClone = vi.fn().mockReturnValue(requestInit.request);
|
||||
|
||||
const mockedSync = jest.fn().mockResolvedValue({});
|
||||
const mockedSync = vi.fn().mockResolvedValue({});
|
||||
const apiPlugin = new ApiPlugin({
|
||||
type: 'delete',
|
||||
syncManager: {
|
||||
@@ -334,7 +330,7 @@ describe('ApiPlugin', () => {
|
||||
Object.defineProperty(global, 'self', {
|
||||
value: {
|
||||
crypto: {
|
||||
randomUUID: jest.fn().mockReturnValue('444555'),
|
||||
randomUUID: vi.fn().mockReturnValue('444555'),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -351,9 +347,9 @@ describe('ApiPlugin', () => {
|
||||
} as unknown as Request,
|
||||
} as any;
|
||||
|
||||
const mockedClone = jest.fn().mockReturnValue(requestInit.request);
|
||||
const mockedClone = vi.fn().mockReturnValue(requestInit.request);
|
||||
|
||||
const mockedSync = jest.fn().mockResolvedValue({});
|
||||
const mockedSync = vi.fn().mockResolvedValue({});
|
||||
const apiPlugin = new ApiPlugin({
|
||||
type: 'create',
|
||||
syncManager: {
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
/**
|
||||
* @jest-environment node
|
||||
* @vitest-environment node
|
||||
*/
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
import { MESSAGE_TYPE } from '../conf';
|
||||
import { OfflinePlugin } from '../plugins/OfflinePlugin';
|
||||
|
||||
const mockServiceWorkerScope = {
|
||||
clients: {
|
||||
matchAll: jest.fn().mockResolvedValue([]),
|
||||
matchAll: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
} as unknown as ServiceWorkerGlobalScope;
|
||||
|
||||
@@ -19,11 +18,11 @@ const mockServiceWorkerScope = {
|
||||
} as unknown as ServiceWorkerGlobalScope;
|
||||
|
||||
describe('OfflinePlugin', () => {
|
||||
afterEach(() => jest.clearAllMocks());
|
||||
afterEach(() => vi.clearAllMocks());
|
||||
|
||||
it(`calls fetchDidSucceed`, async () => {
|
||||
const apiPlugin = new OfflinePlugin();
|
||||
const postMessageSpy = jest.spyOn(apiPlugin, 'postMessage');
|
||||
const postMessageSpy = vi.spyOn(apiPlugin, 'postMessage');
|
||||
|
||||
await apiPlugin.fetchDidSucceed?.({
|
||||
response: new Response(),
|
||||
@@ -34,7 +33,7 @@ describe('OfflinePlugin', () => {
|
||||
|
||||
it(`calls fetchDidFail`, async () => {
|
||||
const apiPlugin = new OfflinePlugin();
|
||||
const postMessageSpy = jest.spyOn(apiPlugin, 'postMessage');
|
||||
const postMessageSpy = vi.spyOn(apiPlugin, 'postMessage');
|
||||
|
||||
await apiPlugin.fetchDidFail?.({} as any);
|
||||
|
||||
@@ -43,12 +42,9 @@ describe('OfflinePlugin', () => {
|
||||
|
||||
it(`calls postMessage`, async () => {
|
||||
const apiPlugin = new OfflinePlugin();
|
||||
const mockClients = [
|
||||
{ postMessage: jest.fn() },
|
||||
{ postMessage: jest.fn() },
|
||||
];
|
||||
const mockClients = [{ postMessage: vi.fn() }, { postMessage: vi.fn() }];
|
||||
|
||||
mockServiceWorkerScope.clients.matchAll = jest
|
||||
mockServiceWorkerScope.clients.matchAll = vi
|
||||
.fn()
|
||||
.mockResolvedValue(mockClients);
|
||||
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
/**
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
import { SyncManager } from '../SyncManager';
|
||||
|
||||
const mockedSleep = jest.fn();
|
||||
jest.mock('@/utils/system', () => ({
|
||||
sleep: jest.fn().mockImplementation((ms) => mockedSleep(ms)),
|
||||
const mockedSleep = vi.fn();
|
||||
vi.mock('@/utils/system', () => ({
|
||||
sleep: vi.fn().mockImplementation((ms) => mockedSleep(ms)),
|
||||
}));
|
||||
|
||||
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
describe('SyncManager', () => {
|
||||
afterEach(() => jest.clearAllMocks());
|
||||
afterEach(() => vi.clearAllMocks());
|
||||
|
||||
it('checks SyncManager no sync to do', async () => {
|
||||
const toSync = jest.fn();
|
||||
const hasSyncToDo = jest.fn().mockResolvedValue(false);
|
||||
const toSync = vi.fn();
|
||||
const hasSyncToDo = vi.fn().mockResolvedValue(false);
|
||||
new SyncManager(toSync, hasSyncToDo);
|
||||
|
||||
await delay(100);
|
||||
@@ -28,8 +27,8 @@ describe('SyncManager', () => {
|
||||
});
|
||||
|
||||
it('checks SyncManager sync to do', async () => {
|
||||
const toSync = jest.fn();
|
||||
const hasSyncToDo = jest.fn().mockResolvedValue(true);
|
||||
const toSync = vi.fn();
|
||||
const hasSyncToDo = vi.fn().mockResolvedValue(true);
|
||||
new SyncManager(toSync, hasSyncToDo);
|
||||
|
||||
await delay(100);
|
||||
@@ -39,10 +38,10 @@ describe('SyncManager', () => {
|
||||
});
|
||||
|
||||
it('checks SyncManager sync to do trigger error', async () => {
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
const toSync = jest.fn().mockRejectedValue(new Error('error'));
|
||||
const hasSyncToDo = jest.fn().mockResolvedValue(true);
|
||||
const toSync = vi.fn().mockRejectedValue(new Error('error'));
|
||||
const hasSyncToDo = vi.fn().mockResolvedValue(true);
|
||||
new SyncManager(toSync, hasSyncToDo);
|
||||
|
||||
await delay(100);
|
||||
@@ -56,8 +55,8 @@ describe('SyncManager', () => {
|
||||
});
|
||||
|
||||
it('checks SyncManager multiple sync to do', async () => {
|
||||
const toSync = jest.fn().mockReturnValue(delay(200));
|
||||
const hasSyncToDo = jest.fn().mockResolvedValue(true);
|
||||
const toSync = vi.fn().mockReturnValue(delay(200));
|
||||
const hasSyncToDo = vi.fn().mockResolvedValue(true);
|
||||
const syncManager = new SyncManager(toSync, hasSyncToDo);
|
||||
|
||||
await syncManager.sync();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { MESSAGE_TYPE } from '../conf';
|
||||
import { useIsOffline, useOffline } from '../hooks/useOffline';
|
||||
|
||||
const mockAddEventListener = jest.fn();
|
||||
const mockRemoveEventListener = jest.fn();
|
||||
const mockAddEventListener = vi.fn();
|
||||
const mockRemoveEventListener = vi.fn();
|
||||
Object.defineProperty(navigator, 'serviceWorker', {
|
||||
value: {
|
||||
addEventListener: mockAddEventListener,
|
||||
@@ -16,7 +16,7 @@ Object.defineProperty(navigator, 'serviceWorker', {
|
||||
|
||||
describe('useOffline', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should set isOffline to true when receiving an offline message', () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render } from '@testing-library/react';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { useSWRegister } from '../hooks/useSWRegister';
|
||||
|
||||
@@ -12,9 +12,9 @@ const TestComponent = () => {
|
||||
describe('useSWRegister', () => {
|
||||
it('checks service-worker is register', () => {
|
||||
process.env.NEXT_PUBLIC_BUILD_ID = '123456';
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
const registerSpy = jest.fn();
|
||||
const registerSpy = vi.fn();
|
||||
registerSpy.mockImplementation(
|
||||
() =>
|
||||
new Promise((reject) => {
|
||||
@@ -22,11 +22,13 @@ describe('useSWRegister', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
const addEventListenerSpy = vi.fn();
|
||||
|
||||
Object.defineProperty(navigator, 'serviceWorker', {
|
||||
value: {
|
||||
register: registerSpy,
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
addEventListener: addEventListenerSpy,
|
||||
removeEventListener: vi.fn(),
|
||||
},
|
||||
writable: true,
|
||||
});
|
||||
@@ -34,7 +36,7 @@ describe('useSWRegister', () => {
|
||||
render(<TestComponent />);
|
||||
|
||||
expect(registerSpy).toHaveBeenCalledWith('/service-worker.js?v=123456');
|
||||
expect(navigator.serviceWorker.addEventListener).toHaveBeenCalledWith(
|
||||
expect(addEventListenerSpy).toHaveBeenCalledWith(
|
||||
'controllerchange',
|
||||
expect.any(Function),
|
||||
);
|
||||
@@ -44,7 +46,7 @@ describe('useSWRegister', () => {
|
||||
process.env.NEXT_PUBLIC_SW_DEACTIVATED = 'true';
|
||||
process.env.NEXT_PUBLIC_BUILD_ID = '123456';
|
||||
|
||||
const registerSpy = jest.fn();
|
||||
const registerSpy = vi.fn();
|
||||
registerSpy.mockImplementation(
|
||||
() =>
|
||||
new Promise((reject) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { isValidEmail } from '../string';
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { isSafeUrl } from '@/utils/url';
|
||||
|
||||
describe('isSafeUrl', () => {
|
||||
|
||||
25
src/frontend/apps/impress/vitest.config.ts
Normal file
25
src/frontend/apps/impress/vitest.config.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/// <reference types="vitest" />
|
||||
import react from '@vitejs/plugin-react';
|
||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths({
|
||||
root: '.',
|
||||
projects: ['./tsconfig.json'],
|
||||
}),
|
||||
],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
setupFiles: './vitest.setup.ts',
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
},
|
||||
},
|
||||
define: {
|
||||
'process.env.NODE_ENV': 'test',
|
||||
},
|
||||
});
|
||||
4
src/frontend/apps/impress/vitest.setup.ts
Normal file
4
src/frontend/apps/impress/vitest.setup.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
import * as dotenv from 'dotenv';
|
||||
|
||||
dotenv.config({ path: './.env.test', quiet: true });
|
||||
@@ -75,6 +75,27 @@
|
||||
json5 "^2.2.3"
|
||||
semver "^6.3.1"
|
||||
|
||||
"@babel/core@^7.28.0":
|
||||
version "7.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.3.tgz#aceddde69c5d1def69b839d09efa3e3ff59c97cb"
|
||||
integrity sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==
|
||||
dependencies:
|
||||
"@ampproject/remapping" "^2.2.0"
|
||||
"@babel/code-frame" "^7.27.1"
|
||||
"@babel/generator" "^7.28.3"
|
||||
"@babel/helper-compilation-targets" "^7.27.2"
|
||||
"@babel/helper-module-transforms" "^7.28.3"
|
||||
"@babel/helpers" "^7.28.3"
|
||||
"@babel/parser" "^7.28.3"
|
||||
"@babel/template" "^7.27.2"
|
||||
"@babel/traverse" "^7.28.3"
|
||||
"@babel/types" "^7.28.2"
|
||||
convert-source-map "^2.0.0"
|
||||
debug "^4.1.0"
|
||||
gensync "^1.0.0-beta.2"
|
||||
json5 "^2.2.3"
|
||||
semver "^6.3.1"
|
||||
|
||||
"@babel/generator@^7.27.5", "@babel/generator@^7.28.0":
|
||||
version "7.28.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.0.tgz#9cc2f7bd6eb054d77dc66c2664148a0c5118acd2"
|
||||
@@ -86,6 +107,17 @@
|
||||
"@jridgewell/trace-mapping" "^0.3.28"
|
||||
jsesc "^3.0.2"
|
||||
|
||||
"@babel/generator@^7.28.3":
|
||||
version "7.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e"
|
||||
integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.28.3"
|
||||
"@babel/types" "^7.28.2"
|
||||
"@jridgewell/gen-mapping" "^0.3.12"
|
||||
"@jridgewell/trace-mapping" "^0.3.28"
|
||||
jsesc "^3.0.2"
|
||||
|
||||
"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3":
|
||||
version "7.27.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5"
|
||||
@@ -167,6 +199,15 @@
|
||||
"@babel/helper-validator-identifier" "^7.27.1"
|
||||
"@babel/traverse" "^7.27.3"
|
||||
|
||||
"@babel/helper-module-transforms@^7.28.3":
|
||||
version "7.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6"
|
||||
integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.27.1"
|
||||
"@babel/helper-validator-identifier" "^7.27.1"
|
||||
"@babel/traverse" "^7.28.3"
|
||||
|
||||
"@babel/helper-optimise-call-expression@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200"
|
||||
@@ -237,6 +278,14 @@
|
||||
"@babel/template" "^7.27.2"
|
||||
"@babel/types" "^7.28.2"
|
||||
|
||||
"@babel/helpers@^7.28.3":
|
||||
version "7.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.3.tgz#b83156c0a2232c133d1b535dd5d3452119c7e441"
|
||||
integrity sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==
|
||||
dependencies:
|
||||
"@babel/template" "^7.27.2"
|
||||
"@babel/types" "^7.28.2"
|
||||
|
||||
"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.0":
|
||||
version "7.28.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e"
|
||||
@@ -244,6 +293,13 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.28.0"
|
||||
|
||||
"@babel/parser@^7.28.3":
|
||||
version "7.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.3.tgz#d2d25b814621bca5fe9d172bc93792547e7a2a71"
|
||||
integrity sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.28.2"
|
||||
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9"
|
||||
@@ -751,6 +807,20 @@
|
||||
dependencies:
|
||||
"@babel/plugin-transform-react-jsx" "^7.27.1"
|
||||
|
||||
"@babel/plugin-transform-react-jsx-self@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz#af678d8506acf52c577cac73ff7fe6615c85fc92"
|
||||
integrity sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
|
||||
"@babel/plugin-transform-react-jsx-source@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz#dcfe2c24094bb757bf73960374e7c55e434f19f0"
|
||||
integrity sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
|
||||
"@babel/plugin-transform-react-jsx@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz#1023bc94b78b0a2d68c82b5e96aed573bcfb9db0"
|
||||
@@ -1005,6 +1075,19 @@
|
||||
"@babel/types" "^7.28.0"
|
||||
debug "^4.3.1"
|
||||
|
||||
"@babel/traverse@^7.28.3":
|
||||
version "7.28.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.3.tgz#6911a10795d2cce43ec6a28cffc440cca2593434"
|
||||
integrity sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.27.1"
|
||||
"@babel/generator" "^7.28.3"
|
||||
"@babel/helper-globals" "^7.28.0"
|
||||
"@babel/parser" "^7.28.3"
|
||||
"@babel/template" "^7.27.2"
|
||||
"@babel/types" "^7.28.2"
|
||||
debug "^4.3.1"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.0", "@babel/types@^7.28.2", "@babel/types@^7.4.4":
|
||||
version "7.28.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.2.tgz#da9db0856a9a88e0a13b019881d7513588cf712b"
|
||||
@@ -1969,19 +2052,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz#0ededeae4d071f5c8ffe3678d15f3a1be09156be"
|
||||
integrity sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==
|
||||
|
||||
"@jest/environment-jsdom-abstract@30.0.5":
|
||||
version "30.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.0.5.tgz#7299cca59b3e84547ca3d1bbd4e7d36b4b44d426"
|
||||
integrity sha512-gpWwiVxZunkoglP8DCnT3As9x5O8H6gveAOpvaJd2ATAoSh7ZSSCWbr9LQtUMvr8WD3VjG9YnDhsmkCK5WN1rQ==
|
||||
dependencies:
|
||||
"@jest/environment" "30.0.5"
|
||||
"@jest/fake-timers" "30.0.5"
|
||||
"@jest/types" "30.0.5"
|
||||
"@types/jsdom" "^21.1.7"
|
||||
"@types/node" "*"
|
||||
jest-mock "30.0.5"
|
||||
jest-util "30.0.5"
|
||||
|
||||
"@jest/environment@30.0.5":
|
||||
version "30.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-30.0.5.tgz#eaaae0403c7d3f8414053c2224acc3011e1c3a1b"
|
||||
@@ -4300,6 +4370,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-3.0.0.tgz#96fdb89d25c62e7b6a5d08caf0ce5114370e3b8f"
|
||||
integrity sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==
|
||||
|
||||
"@rolldown/pluginutils@1.0.0-beta.27":
|
||||
version "1.0.0-beta.27"
|
||||
resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz#47d2bf4cef6d470b22f5831b420f8964e0bf755f"
|
||||
integrity sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==
|
||||
|
||||
"@rollup/plugin-babel@^5.2.0":
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
|
||||
@@ -5346,15 +5421,6 @@
|
||||
expect "^30.0.0"
|
||||
pretty-format "^30.0.0"
|
||||
|
||||
"@types/jsdom@^21.1.7":
|
||||
version "21.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-21.1.7.tgz#9edcb09e0b07ce876e7833922d3274149c898cfa"
|
||||
integrity sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
"@types/tough-cookie" "*"
|
||||
parse5 "^7.0.0"
|
||||
|
||||
"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9":
|
||||
version "7.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
||||
@@ -5577,11 +5643,6 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/tough-cookie@*":
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304"
|
||||
integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==
|
||||
|
||||
"@types/trusted-types@^2.0.2":
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
|
||||
@@ -5816,6 +5877,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777"
|
||||
integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==
|
||||
|
||||
"@vitejs/plugin-react@4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz#647af4e7bb75ad3add578e762ad984b90f4a24b9"
|
||||
integrity sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==
|
||||
dependencies:
|
||||
"@babel/core" "^7.28.0"
|
||||
"@babel/plugin-transform-react-jsx-self" "^7.27.1"
|
||||
"@babel/plugin-transform-react-jsx-source" "^7.27.1"
|
||||
"@rolldown/pluginutils" "1.0.0-beta.27"
|
||||
"@types/babel__core" "^7.20.5"
|
||||
react-refresh "^0.17.0"
|
||||
|
||||
"@vitest/expect@3.2.4":
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.2.4.tgz#8362124cd811a5ee11c5768207b9df53d34f2433"
|
||||
@@ -8734,6 +8807,11 @@ globjoin@^0.1.4:
|
||||
resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
|
||||
integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
|
||||
|
||||
globrex@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
||||
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
||||
|
||||
gopd@^1.0.1, gopd@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
|
||||
@@ -9788,17 +9866,6 @@ jest-each@30.0.5:
|
||||
jest-util "30.0.5"
|
||||
pretty-format "30.0.5"
|
||||
|
||||
jest-environment-jsdom@30.0.5:
|
||||
version "30.0.5"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-30.0.5.tgz#36351cc8a14fcd54945da0beb029af493d7d5764"
|
||||
integrity sha512-BmnDEoAH+jEjkPrvE9DTKS2r3jYSJWlN/r46h0/DBUxKrkgt2jAZ5Nj4wXLAcV1KWkRpcFqA5zri9SWzJZ1cCg==
|
||||
dependencies:
|
||||
"@jest/environment" "30.0.5"
|
||||
"@jest/environment-jsdom-abstract" "30.0.5"
|
||||
"@types/jsdom" "^21.1.7"
|
||||
"@types/node" "*"
|
||||
jsdom "^26.1.0"
|
||||
|
||||
jest-environment-node@30.0.5:
|
||||
version "30.0.5"
|
||||
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-30.0.5.tgz#6a98dd80e0384ead67ed05643381395f6cda93c9"
|
||||
@@ -10080,6 +10147,32 @@ js-yaml@^4.1.0:
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
jsdom@26.1.0:
|
||||
version "26.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-26.1.0.tgz#ab5f1c1cafc04bd878725490974ea5e8bf0c72b3"
|
||||
integrity sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==
|
||||
dependencies:
|
||||
cssstyle "^4.2.1"
|
||||
data-urls "^5.0.0"
|
||||
decimal.js "^10.5.0"
|
||||
html-encoding-sniffer "^4.0.0"
|
||||
http-proxy-agent "^7.0.2"
|
||||
https-proxy-agent "^7.0.6"
|
||||
is-potential-custom-element-name "^1.0.1"
|
||||
nwsapi "^2.2.16"
|
||||
parse5 "^7.2.1"
|
||||
rrweb-cssom "^0.8.0"
|
||||
saxes "^6.0.0"
|
||||
symbol-tree "^3.2.4"
|
||||
tough-cookie "^5.1.1"
|
||||
w3c-xmlserializer "^5.0.0"
|
||||
webidl-conversions "^7.0.0"
|
||||
whatwg-encoding "^3.1.1"
|
||||
whatwg-mimetype "^4.0.0"
|
||||
whatwg-url "^14.1.1"
|
||||
ws "^8.18.0"
|
||||
xml-name-validator "^5.0.0"
|
||||
|
||||
jsdom@^25.0.1:
|
||||
version "25.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-25.0.1.tgz#536ec685c288fc8a5773a65f82d8b44badcc73ef"
|
||||
@@ -10107,32 +10200,6 @@ jsdom@^25.0.1:
|
||||
ws "^8.18.0"
|
||||
xml-name-validator "^5.0.0"
|
||||
|
||||
jsdom@^26.1.0:
|
||||
version "26.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-26.1.0.tgz#ab5f1c1cafc04bd878725490974ea5e8bf0c72b3"
|
||||
integrity sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==
|
||||
dependencies:
|
||||
cssstyle "^4.2.1"
|
||||
data-urls "^5.0.0"
|
||||
decimal.js "^10.5.0"
|
||||
html-encoding-sniffer "^4.0.0"
|
||||
http-proxy-agent "^7.0.2"
|
||||
https-proxy-agent "^7.0.6"
|
||||
is-potential-custom-element-name "^1.0.1"
|
||||
nwsapi "^2.2.16"
|
||||
parse5 "^7.2.1"
|
||||
rrweb-cssom "^0.8.0"
|
||||
saxes "^6.0.0"
|
||||
symbol-tree "^3.2.4"
|
||||
tough-cookie "^5.1.1"
|
||||
w3c-xmlserializer "^5.0.0"
|
||||
webidl-conversions "^7.0.0"
|
||||
whatwg-encoding "^3.1.1"
|
||||
whatwg-mimetype "^4.0.0"
|
||||
whatwg-url "^14.1.1"
|
||||
ws "^8.18.0"
|
||||
xml-name-validator "^5.0.0"
|
||||
|
||||
jsesc@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
|
||||
@@ -12284,6 +12351,11 @@ react-number-format@^5.4.3:
|
||||
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.4.4.tgz#d31f0e260609431500c8d3f81bbd3ae1fb7cacad"
|
||||
integrity sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==
|
||||
|
||||
react-refresh@^0.17.0:
|
||||
version "0.17.0"
|
||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.17.0.tgz#b7e579c3657f23d04eccbe4ad2e58a8ed51e7e53"
|
||||
integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==
|
||||
|
||||
react-remove-scroll-bar@^2.3.7:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223"
|
||||
@@ -13952,6 +14024,11 @@ tsc-alias@1.8.16:
|
||||
normalize-path "^3.0.0"
|
||||
plimit-lit "^1.2.6"
|
||||
|
||||
tsconfck@^3.0.3:
|
||||
version "3.1.6"
|
||||
resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.6.tgz#da1f0b10d82237ac23422374b3fce1edb23c3ead"
|
||||
integrity sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==
|
||||
|
||||
tsconfig-paths@^3.15.0:
|
||||
version "3.15.0"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4"
|
||||
@@ -14468,6 +14545,15 @@ vite-node@3.2.4:
|
||||
pathe "^2.0.3"
|
||||
vite "^5.0.0 || ^6.0.0 || ^7.0.0-0"
|
||||
|
||||
vite-tsconfig-paths@5.1.4:
|
||||
version "5.1.4"
|
||||
resolved "https://registry.yarnpkg.com/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz#d9a71106a7ff2c1c840c6f1708042f76a9212ed4"
|
||||
integrity sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
globrex "^0.1.2"
|
||||
tsconfck "^3.0.3"
|
||||
|
||||
"vite@^5.0.0 || ^6.0.0 || ^7.0.0-0":
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.0.tgz#6fb13c74c13cfdd0e200ee61d6ea6e8fafc2e8b5"
|
||||
|
||||
Reference in New Issue
Block a user