Replace test framework: jest -> vitest (#281)

* Replace test framework: jest -> vitest

* nit - remove deprecated npm scripts

* Add vitest config

* Add a few basic tests

* Update actions with vitest params

* Add correct expectations

* Remove jest config
This commit is contained in:
filtered
2024-11-07 09:27:32 +11:00
committed by GitHub
parent 93c26ac99e
commit 7e21b00cc7
17 changed files with 1179 additions and 4067 deletions

View File

@@ -25,6 +25,6 @@ jobs:
run: |
npm ci
npm run build
- name: Run jest tests
- name: Run vitest tests
run: |
npm test -- --verbose
npm test -- --reporter=verbose

View File

@@ -1,23 +0,0 @@
import type { JestConfigWithTsJest } from 'ts-jest'
const jestConfig: JestConfigWithTsJest = {
testMatch: ['**/test/**/*.test.ts'],
testEnvironment: 'jsdom',
moduleFileExtensions: ['js', 'jsx', 'json', 'ts'],
transform: {
'^.+\\.m?[tj]sx?$': [
'ts-jest',
{
tsconfig: './tsconfig.json',
}
]
},
clearMocks: true,
resetModules: true,
testTimeout: 10000,
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
}
export default jestConfig

4450
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -25,11 +25,7 @@
"preview": "vite preview",
"watch": "vite build --watch",
"release": "node scripts/release.js",
"test": "jest",
"deprecated-test:allVersions": "./utils/test.sh",
"deprecated-prettier": "npx prettier --write src/**/*.* css/**/*.*",
"deprecated-lint": "npx eslint src",
"deprecated-lint:fix": "npx eslint --fix src"
"test": "vitest"
},
"repository": {
"type": "git",
@@ -45,13 +41,12 @@
},
"homepage": "https://github.com/Comfy-Org/litegraph.js",
"devDependencies": {
"@types/jest": "^29.5.12",
"@types/node": "^22.1.0",
"jest-environment-jsdom": "^29.7.0",
"ts-jest": "^29.2.4",
"jsdom": "^25.0.1",
"ts-node": "^10.9.2",
"typescript": "^5.6.3",
"vite": "^5.3.4",
"vite-plugin-dts": "^4.3.0"
"vite-plugin-dts": "^4.3.0",
"vitest": "^2.1.4"
}
}

View File

@@ -1,45 +1,42 @@
import { LGraph, LGraphGroup, LGraphNode, LiteGraph } from "../src/litegraph"
import { LiteGraphGlobal } from "../src/LiteGraphGlobal"
import { describe } from "vitest"
import { LGraph, LiteGraph } from "@/litegraph"
import { lgTest } from "./lgTest"
function makeGraph() {
const LiteGraph = new LiteGraphGlobal()
LiteGraph.registerNodeType("TestNode", LGraphNode)
LiteGraph.registerNodeType("OtherNode", LGraphNode)
LiteGraph.registerNodeType("", LGraphNode)
return new LGraph()
}
describe("LGraph", () => {
it("can be instantiated", () => {
// @ts-ignore TODO: Remove once relative imports fix goes in.
describe.concurrent("LGraph", () => {
lgTest("can be instantiated", ({ expect }) => {
// @ts-expect-error Intentional - extra holds any / all consumer data that should be serialised
const graph = new LGraph({ extra: "TestGraph" })
expect(graph).toBeInstanceOf(LGraph)
expect(graph.extra).toBe("TestGraph")
expect(graph.extra).toBe("TestGraph")
})
lgTest("populates optional values", ({ expect, minimalSerialisableGraph }) => {
const dGraph = new LGraph(minimalSerialisableGraph)
expect(dGraph.links).toBeInstanceOf(Map)
expect(dGraph.nodes).toBeInstanceOf(Array)
expect(dGraph.groups).toBeInstanceOf(Array)
})
lgTest("matches previous snapshot", ({ expect, minimalSerialisableGraph, basicSerialisableGraph }) => {
const minLGraph = new LGraph(minimalSerialisableGraph)
expect(minLGraph).toMatchSnapshot("minLGraph")
const basicLGraph = new LGraph(basicSerialisableGraph)
expect(basicLGraph).toMatchSnapshot("basicLGraph")
})
})
describe("Legacy LGraph Compatibility Layer", () => {
it("can be extended via prototype", () => {
const graph = new LGraph()
describe.concurrent("Legacy LGraph Compatibility Layer", () => {
lgTest("can be extended via prototype", ({ expect, minimalGraph }) => {
// @ts-expect-error Should always be an error.
LGraph.prototype.newMethod = function () {
return "New method added via prototype"
}
// @ts-expect-error Should always be an error.
expect(graph.newMethod()).toBe("New method added via prototype")
expect(minimalGraph.newMethod()).toBe("New method added via prototype")
})
it("is correctly assigned to LiteGraph", () => {
lgTest("is correctly assigned to LiteGraph", ({ expect }) => {
expect(LiteGraph.LGraph).toBe(LGraph)
})
})
describe("LGraph Serialisation", () => {
it("should serialise", () => {
const graph = new LGraph()
graph.add(new LGraphNode("Test Node"))
graph.add(new LGraphGroup("Test Group"))
expect(graph.nodes.length).toBe(1)
expect(graph.groups.length).toBe(1)
})
})

10
test/LGraphGroup.test.ts Normal file
View File

@@ -0,0 +1,10 @@
import { describe, expect } from "vitest"
import { LGraphGroup } from "@/litegraph"
import { lgTest } from "./lgTest"
describe("LGraphGroup", () => {
lgTest("serializes to the existing format", () => {
const link = new LGraphGroup("title", 929)
expect(link.serialize()).toMatchSnapshot("Basic")
})
})

View File

@@ -1,9 +1,9 @@
import {
LGraphNode,
} from "../src/litegraph"
import { describe, expect } from "vitest"
import { LGraphNode } from "@/litegraph"
import { lgTest } from "./lgTest"
describe("LGraphNode", () => {
it("should serialize position/size correctly", () => {
lgTest("should serialize position/size correctly", () => {
const node = new LGraphNode("TestNode")
node.pos = [10, 10]
expect(node.pos).toEqual(new Float32Array([10, 10]))
@@ -13,4 +13,4 @@ describe("LGraphNode", () => {
expect(node.size).toEqual(new Float32Array([100, 100]))
expect(node.serialize().size).toEqual([100, 100])
})
})
})

15
test/LLink.test.ts Normal file
View File

@@ -0,0 +1,15 @@
import { describe, expect } from "vitest"
import { LLink } from "@/litegraph"
import { lgTest } from "./lgTest"
describe("LLink", () => {
lgTest("matches previous snapshot", () => {
const link = new LLink(1, "float", 4, 2, 5, 3)
expect(link.serialize()).toMatchSnapshot("Basic")
})
lgTest("serializes to the previous snapshot", () => {
const link = new LLink(1, "float", 4, 2, 5, 3)
expect(link.serialize()).toMatchSnapshot("Basic")
})
})

View File

@@ -0,0 +1,325 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`LGraph > matches previous snapshot > basicLGraph 1`] = `
LGraph {
"_groups": [
LGraphGroup {
"_bounding": Float32Array [
20,
20,
1,
3,
],
"_children": Set {},
"_nodes": [],
"_pos": Float32Array [
20,
20,
],
"_size": Float32Array [
1,
3,
],
"color": "#6029aa",
"flags": {},
"font": undefined,
"font_size": 14,
"graph": [Circular],
"id": 123,
"isPointInside": [Function],
"selected": undefined,
"setDirtyCanvas": [Function],
"title": "A group to test with",
},
],
"_input_nodes": undefined,
"_last_trigger_time": undefined,
"_links": Map {},
"_nodes": [
LGraphNode {
"_collapsed_width": undefined,
"_level": undefined,
"_pos": Float32Array [
10,
10,
],
"_posSize": Float32Array [
10,
10,
140,
60,
],
"_relative_id": undefined,
"_shape": undefined,
"_size": Float32Array [
140,
60,
],
"action_call": undefined,
"action_triggered": undefined,
"badgePosition": "top-left",
"badges": [],
"bgcolor": undefined,
"block_delete": undefined,
"boxcolor": undefined,
"clip_area": undefined,
"clonable": undefined,
"color": undefined,
"connections": [],
"console": undefined,
"exec_version": undefined,
"execute_triggered": undefined,
"flags": {},
"gotFocusAt": undefined,
"graph": [Circular],
"has_errors": true,
"horizontal": undefined,
"id": 1,
"ignore_remove": undefined,
"inputs": [],
"last_serialization": {
"id": 1,
},
"locked": undefined,
"lostFocusAt": undefined,
"mode": undefined,
"mouseOver": undefined,
"optional_inputs": undefined,
"optional_outputs": undefined,
"order": 0,
"outputs": [],
"properties": {},
"properties_info": [],
"redraw_on_mouse": undefined,
"removable": undefined,
"resizable": undefined,
"selected": undefined,
"serialize_widgets": undefined,
"showAdvanced": undefined,
"skip_subgraph_button": undefined,
"subgraph": undefined,
"title": undefined,
"type": null,
"widgets": undefined,
"widgets_start_y": undefined,
"widgets_up": undefined,
},
],
"_nodes_by_id": {
"1": LGraphNode {
"_collapsed_width": undefined,
"_level": undefined,
"_pos": Float32Array [
10,
10,
],
"_posSize": Float32Array [
10,
10,
140,
60,
],
"_relative_id": undefined,
"_shape": undefined,
"_size": Float32Array [
140,
60,
],
"action_call": undefined,
"action_triggered": undefined,
"badgePosition": "top-left",
"badges": [],
"bgcolor": undefined,
"block_delete": undefined,
"boxcolor": undefined,
"clip_area": undefined,
"clonable": undefined,
"color": undefined,
"connections": [],
"console": undefined,
"exec_version": undefined,
"execute_triggered": undefined,
"flags": {},
"gotFocusAt": undefined,
"graph": [Circular],
"has_errors": true,
"horizontal": undefined,
"id": 1,
"ignore_remove": undefined,
"inputs": [],
"last_serialization": {
"id": 1,
},
"locked": undefined,
"lostFocusAt": undefined,
"mode": undefined,
"mouseOver": undefined,
"optional_inputs": undefined,
"optional_outputs": undefined,
"order": 0,
"outputs": [],
"properties": {},
"properties_info": [],
"redraw_on_mouse": undefined,
"removable": undefined,
"resizable": undefined,
"selected": undefined,
"serialize_widgets": undefined,
"showAdvanced": undefined,
"skip_subgraph_button": undefined,
"subgraph": undefined,
"title": undefined,
"type": null,
"widgets": undefined,
"widgets_start_y": undefined,
"widgets_up": undefined,
},
},
"_nodes_executable": [],
"_nodes_in_order": [
LGraphNode {
"_collapsed_width": undefined,
"_level": undefined,
"_pos": Float32Array [
10,
10,
],
"_posSize": Float32Array [
10,
10,
140,
60,
],
"_relative_id": undefined,
"_shape": undefined,
"_size": Float32Array [
140,
60,
],
"action_call": undefined,
"action_triggered": undefined,
"badgePosition": "top-left",
"badges": [],
"bgcolor": undefined,
"block_delete": undefined,
"boxcolor": undefined,
"clip_area": undefined,
"clonable": undefined,
"color": undefined,
"connections": [],
"console": undefined,
"exec_version": undefined,
"execute_triggered": undefined,
"flags": {},
"gotFocusAt": undefined,
"graph": [Circular],
"has_errors": true,
"horizontal": undefined,
"id": 1,
"ignore_remove": undefined,
"inputs": [],
"last_serialization": {
"id": 1,
},
"locked": undefined,
"lostFocusAt": undefined,
"mode": undefined,
"mouseOver": undefined,
"optional_inputs": undefined,
"optional_outputs": undefined,
"order": 0,
"outputs": [],
"properties": {},
"properties_info": [],
"redraw_on_mouse": undefined,
"removable": undefined,
"resizable": undefined,
"selected": undefined,
"serialize_widgets": undefined,
"showAdvanced": undefined,
"skip_subgraph_button": undefined,
"subgraph": undefined,
"title": undefined,
"type": null,
"widgets": undefined,
"widgets_start_y": undefined,
"widgets_up": undefined,
},
],
"_subgraph_node": undefined,
"_version": 3,
"catch_errors": true,
"config": {},
"elapsed_time": 0.01,
"errors_in_execution": undefined,
"execution_time": undefined,
"execution_timer_id": undefined,
"extra": {},
"filter": undefined,
"fixedtime": 0,
"fixedtime_lapse": 0.01,
"globaltime": 0,
"inputs": {},
"iteration": 0,
"lastGroupId": 123,
"last_link_id": 0,
"last_node_id": 1,
"last_reroute_id": undefined,
"last_update_time": 0,
"links": Map {},
"list_of_graphcanvas": null,
"nodes_actioning": [],
"nodes_executedAction": [],
"nodes_executing": [],
"outputs": {},
"runningtime": 0,
"starttime": 0,
"status": 1,
"vars": {},
"version": 1,
}
`;
exports[`LGraph > matches previous snapshot > minLGraph 1`] = `
LGraph {
"_groups": [],
"_input_nodes": undefined,
"_last_trigger_time": undefined,
"_links": Map {},
"_nodes": [],
"_nodes_by_id": {},
"_nodes_executable": [],
"_nodes_in_order": [],
"_subgraph_node": undefined,
"_version": 0,
"catch_errors": true,
"config": {},
"elapsed_time": 0.01,
"errors_in_execution": undefined,
"execution_time": undefined,
"execution_timer_id": undefined,
"extra": {},
"filter": undefined,
"fixedtime": 0,
"fixedtime_lapse": 0.01,
"globaltime": 0,
"inputs": {},
"iteration": 0,
"lastGroupId": -1,
"last_link_id": 0,
"last_node_id": 0,
"last_reroute_id": undefined,
"last_update_time": 0,
"links": Map {},
"list_of_graphcanvas": null,
"nodes_actioning": [],
"nodes_executedAction": [],
"nodes_executing": [],
"outputs": {},
"runningtime": 0,
"starttime": 0,
"status": 1,
"vars": {},
"version": 1,
}
`;

View File

@@ -0,0 +1,17 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`LGraphGroup > serializes to the existing format > Basic 1`] = `
{
"bounding": [
10,
10,
140,
80,
],
"color": "#3f789e",
"flags": {},
"font_size": 24,
"id": 929,
"title": "title",
}
`;

View File

@@ -0,0 +1,23 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`LLink > matches previous snapshot > Basic 1`] = `
[
1,
4,
2,
5,
3,
"float",
]
`;
exports[`LLink > serializes to the previous snapshot > Basic 1`] = `
[
1,
4,
2,
5,
3,
"float",
]
`;

View File

@@ -0,0 +1,177 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Litegraph module > has the same structure > minLGraph 1`] = `
LiteGraphGlobal {
"ACTION": -1,
"ALWAYS": 0,
"ARROW_SHAPE": 5,
"AUTOHIDE_TITLE": 3,
"BOX_SHAPE": 1,
"CANVAS_GRID_SIZE": 10,
"CARD_SHAPE": 4,
"CENTER": 5,
"CIRCLE_SHAPE": 3,
"CONNECTING_LINK_COLOR": "#AFA",
"ContextMenu": [Function],
"CurveEditor": [Function],
"DEFAULT_GROUP_FONT": 24,
"DEFAULT_GROUP_FONT_SIZE": undefined,
"DEFAULT_POSITION": [
100,
100,
],
"DEFAULT_SHADOW_COLOR": "rgba(0,0,0,0.5)",
"DOWN": 2,
"DragAndScale": [Function],
"EVENT": -1,
"EVENT_LINK_COLOR": "#A86",
"GRID_SHAPE": 6,
"Globals": {},
"HIDDEN_LINK": -1,
"INPUT": 1,
"LEFT": 3,
"LGraph": [Function],
"LGraphCanvas": [Function],
"LGraphGroup": [Function],
"LGraphNode": [Function],
"LINEAR_LINK": 1,
"LINK_COLOR": "#9A9",
"LINK_RENDER_MODES": [
"Straight",
"Linear",
"Spline",
],
"LLink": [Function],
"LabelPosition": {
"Left": "left",
"Right": "right",
},
"MAX_NUMBER_OF_NODES": 10000,
"NEVER": 2,
"NODE_BOX_OUTLINE_COLOR": "#FFF",
"NODE_COLLAPSED_RADIUS": 10,
"NODE_COLLAPSED_WIDTH": 80,
"NODE_DEFAULT_BGCOLOR": "#353535",
"NODE_DEFAULT_BOXCOLOR": "#666",
"NODE_DEFAULT_COLOR": "#333",
"NODE_DEFAULT_SHAPE": "box",
"NODE_MIN_WIDTH": 50,
"NODE_MODES": [
"Always",
"On Event",
"Never",
"On Trigger",
],
"NODE_MODES_COLORS": [
"#666",
"#422",
"#333",
"#224",
"#626",
],
"NODE_SELECTED_TITLE_COLOR": "#FFF",
"NODE_SLOT_HEIGHT": 20,
"NODE_SUBTEXT_SIZE": 12,
"NODE_TEXT_COLOR": "#AAA",
"NODE_TEXT_HIGHLIGHT_COLOR": "#EEE",
"NODE_TEXT_SIZE": 14,
"NODE_TITLE_COLOR": "#999",
"NODE_TITLE_HEIGHT": 30,
"NODE_TITLE_TEXT_Y": 20,
"NODE_WIDGET_HEIGHT": 20,
"NODE_WIDTH": 140,
"NORMAL_TITLE": 0,
"NO_TITLE": 1,
"Nodes": {},
"ON_EVENT": 1,
"ON_TRIGGER": 3,
"OUTPUT": 2,
"RIGHT": 4,
"ROUND_SHAPE": 2,
"SPLINE_LINK": 2,
"STRAIGHT_LINK": 0,
"SlotDirection": {
"1": "Up",
"2": "Down",
"3": "Left",
"4": "Right",
"Down": 2,
"Left": 3,
"Right": 4,
"Up": 1,
},
"SlotShape": {
"1": "Box",
"3": "Circle",
"5": "Arrow",
"6": "Grid",
"7": "HollowCircle",
"Arrow": 5,
"Box": 1,
"Circle": 3,
"Grid": 6,
"HollowCircle": 7,
},
"SlotType": {
"-1": "Event",
"Array": "array",
"Event": -1,
},
"TRANSPARENT_TITLE": 2,
"UP": 1,
"VALID_SHAPES": [
"default",
"box",
"round",
"card",
],
"VERSION": 0.4,
"VERTICAL_LAYOUT": "vertical",
"WIDGET_BGCOLOR": "#222",
"WIDGET_OUTLINE_COLOR": "#666",
"WIDGET_SECONDARY_TEXT_COLOR": "#999",
"WIDGET_TEXT_COLOR": "#DDD",
"allow_multi_output_for_events": true,
"allow_scripts": false,
"alt_drag_do_clone_nodes": false,
"auto_load_slot_types": false,
"auto_sort_node_types": false,
"catch_exceptions": true,
"click_do_break_link_to": false,
"ctrl_alt_click_do_break_link": true,
"ctrl_shift_v_paste_connect_unselected_outputs": true,
"debug": false,
"dialog_close_on_mouse_leave": false,
"dialog_close_on_mouse_leave_delay": 500,
"distance": [Function],
"do_add_triggers_slots": false,
"getTime": [Function],
"highlight_selected_group": true,
"isInsideRectangle": [Function],
"middle_click_slot_add_default_node": false,
"node_box_coloured_by_mode": false,
"node_box_coloured_when_on": false,
"node_images_path": "",
"node_types_by_file_extension": {},
"overlapBounding": [Function],
"pointerevents_method": "pointer",
"proxy": null,
"registered_node_types": {},
"registered_slot_in_types": {},
"registered_slot_out_types": {},
"release_link_on_empty_shows_menu": false,
"search_filter_enabled": false,
"search_hide_on_mouse_leave": true,
"search_show_all_on_open": true,
"searchbox_extras": {},
"shift_click_do_break_link_from": false,
"slot_types_default_in": {},
"slot_types_default_out": {},
"slot_types_in": [],
"slot_types_out": [],
"snap_highlights_node": true,
"snaps_for_comfy": true,
"throw_errors": true,
"use_uuids": false,
}
`;

56
test/lgTest.ts Normal file
View File

@@ -0,0 +1,56 @@
import { test } from "vitest"
import type { ISerialisedGraph } from "../src/types/serialisation"
import { LGraph } from "@/LGraph"
const minimalSerialisableGraph: ISerialisedGraph = {
version: 1,
config: {},
last_node_id: 0,
last_link_id: 0,
nodes: [],
links: [],
groups: [],
}
const basicSerialisableGraph: ISerialisedGraph = {
version: 1,
config: {},
last_node_id: 0,
last_link_id: 0,
groups: [
{
id: 123,
bounding: [20, 20, 1, 3],
color: "#6029aa",
font_size: 14,
title: "A group to test with",
},
],
nodes: [
{
id: 1,
},
],
links: [],
}
interface LitegraphFixtures {
minimalGraph: LGraph
minimalSerialisableGraph: ISerialisedGraph
basicSerialisableGraph: ISerialisedGraph
}
export const lgTest = test.extend<LitegraphFixtures>({
minimalGraph: async ({}, use) => {
// Before each test function
const serialisable = structuredClone(minimalSerialisableGraph)
const lGraph = new LGraph(serialisable)
// use the fixture value
await use(lGraph)
// After each test function
},
basicSerialisableGraph: structuredClone(basicSerialisableGraph),
minimalSerialisableGraph: structuredClone(minimalSerialisableGraph),
})

21
test/litegraph.test.ts Normal file
View File

@@ -0,0 +1,21 @@
import { describe, expect } from "vitest"
import { clamp, LGraphCanvas, LiteGraph } from "@/litegraph"
import { LiteGraphGlobal } from "@/LiteGraphGlobal"
import { lgTest } from "./lgTest"
describe.concurrent("Litegraph module", () => {
lgTest("contains a global export", ({ expect }) => {
expect(LiteGraph).toBeInstanceOf(LiteGraphGlobal)
expect(LiteGraph.LGraphCanvas).toBe(LGraphCanvas)
})
lgTest("has the same structure", ({ expect }) => {
const lgGlobal = new LiteGraphGlobal()
expect(lgGlobal).toMatchSnapshot("minLGraph")
})
lgTest("clamps values", () => {
expect(clamp(-1.124, 13, 24)).toStrictEqual(13)
expect(clamp(Infinity, 18, 29)).toStrictEqual(29)
})
})

27
test/serialise.test.ts Normal file
View File

@@ -0,0 +1,27 @@
import { describe } from "vitest"
import { LGraph, LGraphGroup, LGraphNode } from "@/litegraph"
import { lgTest } from "./lgTest"
import type { ISerialisedGraph } from "@/types/serialisation"
describe.concurrent("LGraph Serialisation", () => {
lgTest("can (de)serialise node / group titles", ({ expect, minimalGraph }) => {
const nodeTitle = "Test Node"
const groupTitle = "Test Group"
minimalGraph.add(new LGraphNode(nodeTitle))
minimalGraph.add(new LGraphGroup(groupTitle))
expect(minimalGraph.nodes.length).toBe(1)
expect(minimalGraph.nodes[0].title).toEqual(nodeTitle)
expect(minimalGraph.groups.length).toBe(1)
expect(minimalGraph.groups[0].title).toEqual(groupTitle)
const serialised = JSON.stringify(minimalGraph.serialize())
const deserialised = JSON.parse(serialised) as ISerialisedGraph
const copied = new LGraph(deserialised)
expect(copied.nodes.length).toBe(1)
expect(copied.groups.length).toBe(1)
})
})

11
test/tsconfig.json Normal file
View File

@@ -0,0 +1,11 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
/* Test files should not be compiled */
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": ["**/*"]
}

View File

@@ -1,3 +1,4 @@
/// <reference types='vitest' />
import { defineConfig } from 'vite'
import path from 'path'
import dts from 'vite-plugin-dts'
@@ -27,8 +28,10 @@ export default defineConfig({
}),
],
resolve: {
alias: {
'@': '/src'
}
}
alias: { '@': '/src' },
},
test: {
alias: { '@': '../src' },
environment: 'jsdom',
},
})