Add some first integration tests

pull/256/head
Candid Dauth 2024-01-16 18:59:19 +01:00
rodzic 2e2a363802
commit fad68137a1
8 zmienionych plików z 769 dodań i 1 usunięć

Wyświetl plik

@ -0,0 +1,33 @@
{
"name": "facilmap-integration-tests",
"version": "3.4.0",
"private": true,
"type": "module",
"homepage": "https://github.com/FacilMap/facilmap",
"bugs": {
"url": "https://github.com/FacilMap/facilmap/issues"
},
"license": "AGPL-3.0",
"author": "Candid Dauth <cdauth@cdauth.eu>",
"repository": {
"type": "git",
"url": "https://github.com/FacilMap/facilmap.git"
},
"scripts": {
"integration-tests": "vitest run",
"check-types": "tsc -b --emitDeclarationOnly",
"lint": "eslint src/**/*.ts"
},
"dependencies": {
"facilmap-client": "workspace:^",
"facilmap-types": "workspace:^",
"facilmap-utils": "workspace:^",
"lodash-es": "^4.17.21",
"socket.io-client": "^4.7.2",
"vitest": "^1.1.1"
},
"devDependencies": {
"@types/lodash-es": "^4.17.12",
"typescript": "^5.3.3"
}
}

Wyświetl plik

@ -0,0 +1,384 @@
import { expect, test, vi } from "vitest";
import { createTemporaryPad, emit, generateTestPadId, getFacilMapUrl, getTemporaryPadData, openClient, openSocket } from "./utils";
import { Writable, type PadData, SocketVersion, CRU, type FindPadsResult, type PagedResults } from "facilmap-types";
import { pick } from "lodash-es";
import Client from "facilmap-client";
test("Create pad (using default values)", async () => {
const client = await openClient();
const onPadData = vi.fn();
client.on("padData", onPadData);
await createTemporaryPad(client, {}, async (createPadData, padData) => {
const expectedPadData: PadData & { writable: Writable } = {
...createPadData,
name: "",
searchEngines: false,
description: "",
clusterMarkers: false,
legend1: "",
legend2: "",
defaultViewId: null,
defaultView: null,
writable: Writable.ADMIN
};
expect(client.padId).toBe(createPadData.adminId);
expect(client.readonly).toBe(false);
expect(client.writable).toBe(Writable.ADMIN);
expect(client.serverError).toBe(undefined);
expect(padData).toEqual(expectedPadData);
expect(client.padData).toEqual(expectedPadData);
expect(onPadData).toBeCalledTimes(1);
expect(onPadData).toHaveBeenCalledWith(expectedPadData);
expect(await client.getPad({ padId: createPadData.id })).toEqual(pick(expectedPadData, ["id", "name", "description"]));
});
});
test("Create pad (using custom values)", async () => {
const client = await openClient();
const onPadData = vi.fn();
client.on("padData", onPadData);
await createTemporaryPad(client, {
name: "Test pad",
searchEngines: true,
description: "Test description",
clusterMarkers: true,
legend1: "Legend 1",
legend2: "Legend 1",
defaultViewId: null
}, async (createPadData, padData) => {
const expectedPadData: PadData & { writable: Writable } = {
...createPadData,
defaultView: null,
writable: Writable.ADMIN
};
expect(client.padId).toBe(createPadData.adminId);
expect(client.readonly).toBe(false);
expect(client.writable).toBe(Writable.ADMIN);
expect(client.serverError).toBe(undefined);
expect(padData).toEqual(expectedPadData);
expect(client.padData).toEqual(expectedPadData);
expect(onPadData).toBeCalledTimes(1);
expect(onPadData).toHaveBeenCalledWith(expectedPadData);
expect(await client.getPad({ padId: createPadData.id })).toEqual(pick(expectedPadData, ["id", "name", "description"]));
});
});
test("Create pad (ID already taken)", async () => {
const client1 = await openClient();
const client2 = await openClient();
await createTemporaryPad(client1, {}, async (createPadData1) => {
await expect(async () => {
await createTemporaryPad(client2, {
id: createPadData1.id
})
}).rejects.toThrowError("already taken");
await expect(async () => {
await createTemporaryPad(client2, {
writeId: createPadData1.id
})
}).rejects.toThrowError("already taken");
await expect(async () => {
await createTemporaryPad(client2, {
adminId: createPadData1.id
})
}).rejects.toThrowError("already taken");
});
});
test("Create pad (duplicate IDs)", async () => {
const client = await openClient();
const newId = generateTestPadId();
await expect(async () => {
await createTemporaryPad(client, {
id: newId,
writeId: newId
});
}).rejects.toThrowError("have to be different");
await expect(async () => {
await createTemporaryPad(client, {
id: newId,
adminId: newId
});
}).rejects.toThrowError("have to be different");
await expect(async () => {
await createTemporaryPad(client, {
writeId: newId,
adminId: newId
});
}).rejects.toThrowError("have to be different");
});
test("Edit pad", async () => {
const client = await openClient();
const onPadData = vi.fn();
client.on("padData", onPadData);
await createTemporaryPad(client, {}, async (createPadData, padData) => {
const update = {
name: "Test pad",
searchEngines: true,
description: "Test description",
clusterMarkers: true,
legend1: "Legend 1",
legend2: "Legend 1"
} satisfies PadData<CRU.UPDATE>;
const updatedPadData = await client.editPad(update);
const expectedPadData: PadData & { writable: Writable } = {
...createPadData,
...update,
defaultViewId: null,
defaultView: null,
writable: Writable.ADMIN
};
expect(updatedPadData).toEqual(expectedPadData);
expect(client.padData).toEqual(expectedPadData);
expect(onPadData).toHaveBeenLastCalledWith(expectedPadData);
expect(await client.getPad({ padId: createPadData.id })).toEqual(pick(expectedPadData, ["id", "name", "description"]));
});
});
test("Rename pad", async () => {
const client = await openClient();
const onPadData = vi.fn();
client.on("padData", onPadData);
await createTemporaryPad(client, {}, async (createPadData, padData) => {
const update = {
id: generateTestPadId(),
writeId: generateTestPadId(),
adminId: generateTestPadId()
} satisfies PadData<CRU.UPDATE>;
const updatedPadData = await client.editPad(update);
const expectedPadData: PadData & { writable: Writable } = {
...padData,
...update
};
expect(updatedPadData).toEqual(expectedPadData);
expect(client.padData).toEqual(expectedPadData);
expect(onPadData).toHaveBeenLastCalledWith(expectedPadData);
expect(await client.getPad({ padId: createPadData.id })).toBeNull();
expect(await client.getPad({ padId: createPadData.writeId })).toBeNull();
expect(await client.getPad({ padId: createPadData.adminId })).toBeNull();
expect(await client.getPad({ padId: update.id })).toEqual(pick(expectedPadData, ["id", "name", "description"]));
expect(await client.getPad({ padId: update.writeId })).toEqual(pick(expectedPadData, ["id", "name", "description"]));
expect(await client.getPad({ padId: update.adminId })).toEqual(pick(expectedPadData, ["id", "name", "description"]));
});
});
test("Rename pad (ID already taken)", async () => {
const client1 = await openClient();
const client2 = await openClient();
await createTemporaryPad(client1, {}, async (createPadData1) => {
await createTemporaryPad(client2, {}, async (createPadData2) => {
await expect(async () => {
await client2.editPad({
id: createPadData1.id
});
}).rejects.toThrowError("already taken");
await expect(async () => {
await client2.editPad({
writeId: createPadData1.id
});
}).rejects.toThrowError("already taken");
await expect(async () => {
await client2.editPad({
adminId: createPadData1.id
});
}).rejects.toThrowError("already taken");
});
});
});
test("Rename pad (duplicate IDs)", async () => {
const client = await openClient();
await createTemporaryPad(client, {}, async () => {
const newId = generateTestPadId();
await expect(async () => {
await client.editPad({
id: newId,
writeId: newId
});
}).rejects.toThrowError("cannot be the same");
await expect(async () => {
await client.editPad({
id: newId,
adminId: newId
});
}).rejects.toThrowError("cannot be the same");
await expect(async () => {
await client.editPad({
writeId: newId,
adminId: newId
});
}).rejects.toThrowError("cannot be the same");
});
});
test("Delete pad", async () => {
const client = await openClient();
const padData = getTemporaryPadData({});
await createTemporaryPad(client, padData, async () => {
expect(client.deleted).toBe(false);
const result = await client.getPad({ padId: padData.id });
expect(result).toBeTruthy();
});
expect(client.deleted).toBe(true);
const result = await client.getPad({ padId: padData.id });
expect(result).toBeNull();
});
test("Open existing pad", async () => {
const client1 = await openClient();
await createTemporaryPad(client1, {}, async (createPadData, padData) => {
const client2 = await openClient(createPadData.id);
expect(client2.padData).toEqual({ ...padData, writeId: undefined, adminId: undefined, writable: Writable.READ });
const client3 = await openClient(createPadData.writeId);
expect(client3.padData).toEqual({ ...padData, adminId: undefined, writable: Writable.WRITE });
const client4 = await openClient(createPadData.adminId);
expect(client4.padData).toEqual({ ...padData, writable: Writable.ADMIN });
const client5 = await openClient();
const onPadData5 = vi.fn();
client5.on("padData", onPadData5);
const result5 = await client5.setPadId(createPadData.id);
expect(result5.padData![0]).toEqual({ ...padData, writeId: undefined, adminId: undefined, writable: Writable.READ });
expect(onPadData5).toBeCalledTimes(1);
expect(onPadData5).toBeCalledWith({ ...padData, writeId: undefined, adminId: undefined, writable: Writable.READ });
expect(client5.padData).toEqual({ ...padData, writeId: undefined, adminId: undefined, writable: Writable.READ });
const client6 = await openClient();
const onPadData6 = vi.fn();
client6.on("padData", onPadData6);
const result6 = await client6.setPadId(createPadData.writeId);
expect(result6.padData![0]).toEqual({ ...padData, adminId: undefined, writable: Writable.WRITE });
expect(onPadData6).toBeCalledTimes(1);
expect(onPadData6).toBeCalledWith({ ...padData, adminId: undefined, writable: Writable.WRITE });
expect(client6.padData).toEqual({ ...padData, adminId: undefined, writable: Writable.WRITE });
const client7 = await openClient();
const onPadData7 = vi.fn();
client7.on("padData", onPadData7);
const result7 = await client7.setPadId(createPadData.adminId);
expect(result7.padData![0]).toEqual({ ...padData, writable: Writable.ADMIN });
expect(onPadData7).toBeCalledTimes(1);
expect(onPadData7).toBeCalledWith({ ...padData, writable: Writable.ADMIN });
expect(client7.padData).toEqual({ ...padData, writable: Writable.ADMIN });
});
});
test("Open non-existing pad", async () => {
const id = generateTestPadId();
const client1 = new Client(getFacilMapUrl(), id, { reconnection: false });
await expect(new Promise<any>((resolve, reject) => {
client1.on("padData", resolve);
client1.on("serverError", reject);
client1.on("connect_error", reject);
})).rejects.toThrowError("does not exist");
expect(client1.serverError?.message).toMatch("does not exist");
const client2 = await openClient();
await expect(async () => {
await client2.setPadId(id);
}).rejects.toThrowError("does not exist");
expect(client2.serverError?.message).toMatch("does not exist");
});
test("Find pads", async () => {
const uniqueId = generateTestPadId();
const client = await openClient();
await createTemporaryPad(client, {
name: `Test ${uniqueId} pad`,
searchEngines: true
}, async (createPadData) => {
const expectedFound: PagedResults<FindPadsResult> = {
results: [{ id: createPadData.id, name: `Test ${uniqueId} pad`, description: "" }],
totalLength: 1
};
const expectedNotFound: PagedResults<FindPadsResult> = {
results: [],
totalLength: 0
};
expect(await client.findPads({ query: `Test ${uniqueId} pad` })).toEqual(expectedFound);
expect(await client.findPads({ query: `test ${uniqueId} pad` })).toEqual(expectedFound);
expect(await client.findPads({ query: `Te?t ${uniqueId} pad` })).toEqual(expectedFound);
expect(await client.findPads({ query: `Te* ${uniqueId} pad` })).toEqual(expectedFound);
expect(await client.findPads({ query: uniqueId })).toEqual(expectedFound);
expect(await client.findPads({ query: `Te ${uniqueId} pad` })).toEqual(expectedNotFound);
expect(await client.findPads({ query: `Te? ${uniqueId} pad` })).toEqual(expectedNotFound);
expect(await client.findPads({ query: `Te% ${uniqueId} pad` })).toEqual(expectedNotFound);
await client.editPad({ searchEngines: false });
expect(await client.findPads({ query: `Test ${uniqueId} pad` })).toEqual(expectedNotFound);
});
});
test("Socket v1 pad name", async () => {
const socket = await openSocket(SocketVersion.V1);
const onPadData = vi.fn();
socket.on("padData", onPadData);
try {
const padData = getTemporaryPadData({});
const result = await emit(socket, "createPad", padData);
expect(result.padData![0].name).toBe("Unnamed map");
const result2 = await emit(socket, "editPad", { name: "New name" });
expect(result2.name).toBe("New name");
expect(onPadData).toBeCalledTimes(1);
expect(onPadData.mock.calls[0][0].name).toBe("New name");
const result3 = await emit(socket, "editPad", { name: "" });
expect(result3.name).toBe("Unnamed map");
expect(onPadData).toBeCalledTimes(2);
expect(onPadData.mock.calls[1][0].name).toBe("Unnamed map");
} finally {
await emit(socket, "deletePad", undefined);
}
});

Wyświetl plik

@ -0,0 +1,84 @@
import { io, Socket } from "socket.io-client";
import Client from "facilmap-client";
import { type CRU, type PadData, SocketVersion, type SocketClientToServerEvents, type SocketServerToClientEvents, Writable } from "facilmap-types";
import { generateRandomPadId } from "facilmap-utils";
export function getFacilMapUrl(): string {
if (!process.env.FACILMAP_URL) {
throw new Error("Please specify the FacilMap server URL as FACILMAP_URL.");
}
return process.env.FACILMAP_URL;
}
export async function openSocket<V extends SocketVersion>(version: V): Promise<Socket<SocketServerToClientEvents<V>, SocketClientToServerEvents<V>>> {
const serverUrl = new URL(getFacilMapUrl());
const socket = io(`${serverUrl.origin}${version !== SocketVersion.V1 ? `/${SocketVersion}` : ""}`, {
forceNew: true,
path: serverUrl.pathname.replace(/\/$/, "") + "/socket.io"
});
await new Promise<void>((resolve, reject) => {
socket.on("connect", resolve);
socket.on("connect_error", reject);
});
return socket;
}
export async function openClient(id?: string): Promise<Client> {
const client = new Client(getFacilMapUrl(), id, { reconnection: false });
await new Promise<void>((resolve, reject) => {
if (id != null) {
client.on("padData", () => {
resolve();
});
} else {
client.on("connect", resolve);
}
client.on("serverError", reject);
client.on("connect_error", reject);
});
return client;
}
export function generateTestPadId(): string {
return `integration-test-${generateRandomPadId()}`;
}
export function getTemporaryPadData<D extends Partial<PadData<CRU.CREATE>>>(data: D): D & Pick<PadData<CRU.CREATE>, "id" | "writeId" | "adminId"> {
return {
id: generateTestPadId(),
writeId: generateTestPadId(),
adminId: generateTestPadId(),
...data
};
}
export async function createTemporaryPad<D extends Partial<PadData<CRU.CREATE>>>(client: Client, data: D, callback?: (createPadData: ReturnType<typeof getTemporaryPadData<D>>, padData: PadData & { writable: Writable }) => Promise<void>): Promise<void> {
const createPadData = getTemporaryPadData(data);
const result = await client.createPad(createPadData);
try {
await callback?.(createPadData, result.padData![0]);
} finally {
await client.deletePad();
}
}
export async function promiseCallback<T>(callback: (callback: T extends void ? (err: Error | null) => void : (err: Error | null, data: T) => void) => void): Promise<T> {
return await new Promise<T>((resolve, reject) => {
callback(((err: Error | null, data: T) => {
if (err) {
reject(err);
} else {
resolve(data);
}
}) as any);
});
}
type EventArgs<Args extends any[]> = Args extends [...infer Others, (...args: any[]) => any] ? Others : Args;
type EventResult<Args extends any[]> = Args extends [...any[], (err: Error | null, data: infer Result) => any] ? Result : void;
export async function emit<EmitEvents extends Record<string, any>, Ev extends keyof EmitEvents>(socket: Socket<any, EmitEvents>, ev: Ev, ...args: EventArgs<Parameters<EmitEvents[Ev]>>): Promise<EventResult<Parameters<EmitEvents[Ev]>>> {
return await promiseCallback((callback) => {
// @ts-ignore
socket.emit(ev, ...args, callback);
});
}

Wyświetl plik

@ -0,0 +1,81 @@
import { expect, test, vi } from "vitest";
import { createTemporaryPad, openClient } from "./utils";
import { type CRU, type View } from "facilmap-types";
test("Database views", async () => {
const client = await openClient();
const onView = vi.fn();
client.on("view", onView);
const onPadData = vi.fn();
client.on("padData", onPadData);
await createTemporaryPad(client, {}, async (padData) => {
// Create View 1
const view1 = {
name: "Test view 1",
left: -10,
right: 10,
top: -20,
bottom: 20,
baseLayer: "Mpnk",
layers: []
} satisfies View<CRU.CREATE>;
const view1Result = await client.addView(view1);
const expectedView1: View = {
...view1,
filter: null,
id: view1Result.id,
padId: padData.id
};
expect(view1Result).toEqual(expectedView1);
expect(onView).toBeCalledTimes(1);
expect(onView).toHaveBeenNthCalledWith(1, expectedView1);
expect(client.views).toEqual({
[expectedView1.id]: expectedView1
});
// Create view 2
const view2 = {
name: "Test view 2",
left: -30,
right: 30,
top: -40,
bottom: 40,
baseLayer: "ToPl",
layers: ["grid"],
filter: "name == \"\""
} satisfies View<CRU.CREATE>;
const view2Result = await client.addView(view2);
const expectedView2: View = {
...view2,
id: view2Result.id,
padId: padData.id
};
expect(view2Result).toEqual(expectedView2);
expect(onView).toBeCalledTimes(2);
expect(onView).toHaveBeenNthCalledWith(2, expectedView2);
expect(client.views).toEqual({
[expectedView1.id]: expectedView1,
[expectedView2.id]: expectedView2
});
// Set view 2 as default view
const padResult = await client.editPad({
defaultViewId: expectedView2.id
});
expect(padResult.defaultView).toEqual(expectedView2);
expect(onPadData.mock.lastCall[0].defaultView).toEqual(expectedView2);
});
});

Wyświetl plik

@ -0,0 +1,22 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"outDir": "./out",
"composite": true,
"paths": {
"facilmap-types": ["../types/src/index.ts"],
"facilmap-utils": ["../utils/src/index.ts"],
"facilmap-client": ["../client/src/client.ts"],
}
},
"references": [
{ "path": "../types/tsconfig.json" },
{ "path": "../utils/tsconfig.json" },
{ "path": "../client/tsconfig.json" }
],
"include": [
"src/**/*",
"vite.config.ts",
"server.ts"
]
}

Wyświetl plik

@ -0,0 +1,29 @@
import { defineConfig } from "vite";
import dtsPlugin from "vite-plugin-dts";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [
dtsPlugin({ rollupTypes: true }),
tsconfigPaths({ loose: true })
],
build: {
sourcemap: false,
minify: false,
target: "esnext",
lib: {
entry: './src/server.ts',
name: 'facilmap-server',
fileName: () => 'facilmap-server.mjs',
formats: ['es']
},
rollupOptions: {
external: (id) => (
!id.startsWith("./")
&& !id.startsWith("../")
&& /* resolved internal modules */ !id.startsWith("/")
&& !["facilmap-types", "facilmap-utils"].includes(id)
)
}
}
});

Wyświetl plik

@ -8,7 +8,8 @@
"utils",
"leaflet",
"frontend",
"server"
"server",
"integration-tests"
],
"scripts": {
"lint": "eslint --ext .js,.mjs,.cjs,.ts,.mts,.cts,.vue ./",

134
yarn.lock
Wyświetl plik

@ -1384,6 +1384,17 @@ __metadata:
languageName: node
linkType: hard
"@vitest/expect@npm:1.1.1":
version: 1.1.1
resolution: "@vitest/expect@npm:1.1.1"
dependencies:
"@vitest/spy": 1.1.1
"@vitest/utils": 1.1.1
chai: ^4.3.10
checksum: 5037c30a76becf7ba5f93b16c95d64cadf21e87b72d473a1595f4c201df6a0d60cb8d4a98a3446504c7314d94e1c7646d4d232b563345eb8446f67512b5a501a
languageName: node
linkType: hard
"@vitest/runner@npm:1.1.0":
version: 1.1.0
resolution: "@vitest/runner@npm:1.1.0"
@ -1395,6 +1406,17 @@ __metadata:
languageName: node
linkType: hard
"@vitest/runner@npm:1.1.1":
version: 1.1.1
resolution: "@vitest/runner@npm:1.1.1"
dependencies:
"@vitest/utils": 1.1.1
p-limit: ^5.0.0
pathe: ^1.1.1
checksum: 1d955ca9c190ae01f7bf6f83ce970e310ac2c106a7efd86aa5d658d6ceba9a7411843f44dd3d3dc13953aaf3f9eadf6f8729fc2384116b60b80613a74847241a
languageName: node
linkType: hard
"@vitest/snapshot@npm:1.1.0":
version: 1.1.0
resolution: "@vitest/snapshot@npm:1.1.0"
@ -1406,6 +1428,17 @@ __metadata:
languageName: node
linkType: hard
"@vitest/snapshot@npm:1.1.1":
version: 1.1.1
resolution: "@vitest/snapshot@npm:1.1.1"
dependencies:
magic-string: ^0.30.5
pathe: ^1.1.1
pretty-format: ^29.7.0
checksum: 35664d8ee7468e662ea185e8cd4479e157b645fed12fcb897427fcc213745b1eafa717713dc8f8b8d557611cbbdcb3b47c075afdaaca28ed5f790539d69b392e
languageName: node
linkType: hard
"@vitest/spy@npm:1.1.0":
version: 1.1.0
resolution: "@vitest/spy@npm:1.1.0"
@ -1415,6 +1448,15 @@ __metadata:
languageName: node
linkType: hard
"@vitest/spy@npm:1.1.1":
version: 1.1.1
resolution: "@vitest/spy@npm:1.1.1"
dependencies:
tinyspy: ^2.2.0
checksum: 8067b127dc7521a02315cb537726299d86cc74f95512edcee8adc45abd0e0c7dd69afd20f3de6c0976d3cd67ddd173302bb9a1e7df654f022a634fd50c7a6560
languageName: node
linkType: hard
"@vitest/utils@npm:1.1.0":
version: 1.1.0
resolution: "@vitest/utils@npm:1.1.0"
@ -1426,6 +1468,17 @@ __metadata:
languageName: node
linkType: hard
"@vitest/utils@npm:1.1.1":
version: 1.1.1
resolution: "@vitest/utils@npm:1.1.1"
dependencies:
diff-sequences: ^29.6.3
loupe: ^2.3.7
pretty-format: ^29.7.0
checksum: fb552502757a3fa5405221c143e368c3d320162edd6385ffc23568d846c023fb2c861ed0b22edf6cabbe8ac16422012f5a5993de8abd6b50b1165101a52801a7
languageName: node
linkType: hard
"@volar/language-core@npm:1.11.1, @volar/language-core@npm:~1.11.1":
version: 1.11.1
resolution: "@volar/language-core@npm:1.11.1"
@ -3434,6 +3487,21 @@ __metadata:
languageName: unknown
linkType: soft
"facilmap-integration-tests@workspace:integration-tests":
version: 0.0.0-use.local
resolution: "facilmap-integration-tests@workspace:integration-tests"
dependencies:
"@types/lodash-es": ^4.17.12
facilmap-client: "workspace:^"
facilmap-types: "workspace:^"
facilmap-utils: "workspace:^"
lodash-es: ^4.17.21
socket.io-client: ^4.7.2
typescript: ^5.3.3
vitest: ^1.1.1
languageName: unknown
linkType: soft
"facilmap-leaflet@workspace:^, facilmap-leaflet@workspace:leaflet":
version: 0.0.0-use.local
resolution: "facilmap-leaflet@workspace:leaflet"
@ -7628,6 +7696,21 @@ __metadata:
languageName: node
linkType: hard
"vite-node@npm:1.1.1":
version: 1.1.1
resolution: "vite-node@npm:1.1.1"
dependencies:
cac: ^6.7.14
debug: ^4.3.4
pathe: ^1.1.1
picocolors: ^1.0.0
vite: ^5.0.0
bin:
vite-node: vite-node.mjs
checksum: 0d036e8d9ec0ab604603b1ddc89e1a50d516ab87829e9f06e0f972e802199d0fda94fd85a59be17e0a63c18671dcb4fb5b473245f9c1fda6455356ed37195cf0
languageName: node
linkType: hard
"vite-plugin-css-injected-by-js@npm:^3.3.1":
version: 3.3.1
resolution: "vite-plugin-css-injected-by-js@npm:3.3.1"
@ -7764,6 +7847,57 @@ __metadata:
languageName: node
linkType: hard
"vitest@npm:^1.1.1":
version: 1.1.1
resolution: "vitest@npm:1.1.1"
dependencies:
"@vitest/expect": 1.1.1
"@vitest/runner": 1.1.1
"@vitest/snapshot": 1.1.1
"@vitest/spy": 1.1.1
"@vitest/utils": 1.1.1
acorn-walk: ^8.3.0
cac: ^6.7.14
chai: ^4.3.10
debug: ^4.3.4
execa: ^8.0.1
local-pkg: ^0.5.0
magic-string: ^0.30.5
pathe: ^1.1.1
picocolors: ^1.0.0
std-env: ^3.5.0
strip-literal: ^1.3.0
tinybench: ^2.5.1
tinypool: ^0.8.1
vite: ^5.0.0
vite-node: 1.1.1
why-is-node-running: ^2.2.2
peerDependencies:
"@edge-runtime/vm": "*"
"@types/node": ^18.0.0 || >=20.0.0
"@vitest/browser": ^1.0.0
"@vitest/ui": ^1.0.0
happy-dom: "*"
jsdom: "*"
peerDependenciesMeta:
"@edge-runtime/vm":
optional: true
"@types/node":
optional: true
"@vitest/browser":
optional: true
"@vitest/ui":
optional: true
happy-dom:
optional: true
jsdom:
optional: true
bin:
vitest: vitest.mjs
checksum: f0c827ae4ea230d7f9d9ff9227be0ee851add7fdfee2ee2c03fee49a75ddd14aacf8652fccd01d340075e2b9ef25153084d1bb21b47024864dbfb90cbaec46b4
languageName: node
linkType: hard
"vue-eslint-parser@npm:^9.3.1":
version: 9.3.2
resolution: "vue-eslint-parser@npm:9.3.2"