mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-11-14 16:52:09 +08:00
test: move the test workspace to Vitest 4 and align the Vite toolchain
The repo ran two Vite stacks. ui/ builds the viewer with Vite 7 and
vite-plugin-svelte 6, while Vitest 2 at the root kept Vite 5.4 and plugin 4 with
their own esbuild, whose dev tree carried the critical audit findings. The move
leaves one stack.
Tests now run as test.projects in vitest.config.mts, so vitest.workspace.mts goes
away: engine extends the base (env, global setup, home sandbox), ui stands alone
with the Svelte plugin, jsdom and the browser conditions. The WASM flags move to
test.execArgv, because Vitest 4 ignores poolOptions.forks.execArgv with a
deprecation line and the #1779 worker death comes back. git-index-currency injects
its failures through the mocks' own vi.fn: under Vitest 4 a spy on a mocked module
is that vi.fn, so the captured real function recursed into itself, and
restoreAllMocks no longer resets one, so the injection leaked into later tests.
devEngines sets Node 22.12 as the floor for working in the repo, which is what
Vite 7 asks for; engines, what users run, is unchanged.
Changes on top of the contributor's commits:
- The lockfile is regenerated from main's, not taken from the PR: the PR's would
have put devalue, postcss and ignore back below the fixes in issues 3044 and
3050, and restored the @types/better-sqlite3 that 3044 dropped. ui's packages
hoist to the root at the versions it already built with, and rollup stays.
- testTimeout and hookTimeout rise to 30 s and 60 s. Since Vitest 3 a synchronous
test or hook that outlasts its limit fails; under Vitest 2 the timer could not
fire until the body returned, so a body blocked in spawnSync never timed out. A
6 s synchronous test passes on 2.1.9 and fails on 4.1.11, and an 11 s hook does
the same and skips its tests. The first full run lost frontload-hook to this,
the contributor's lost two bundle-launcher listings, and 31 tests passed 4 s on
a quiet machine, so on a loaded one they would all flake.
- A new test reads the WASM flags from the worker's own command line, since the
config can stop reaching workers with no failure, and a Vitest 5 move could
repeat that.
- CONTRIBUTING and AGENTS state the new floor and the projects setup; two test
files name TestProject, which replaced the removed GlobalSetupContext type.
- Left out as out of scope: a trailing blank line in ui/src/lib/trail-codec.ts.
Validated on Windows, Node 22.22, npm 10.9:
- what ships is unchanged: npm ci --omit=dev, the bundle's step, gives 193 files
byte-identical to main's; npm run build:lib gives 171 byte-identical files;
dist/viewer matches main's once Svelte's scope hashes, which come from the
checkout path, are masked (main built in two folders differs the same way).
- every test is kept: at cd04b21a vitest list finds 9,719 tests on main (9,701
engine, 18 ui) and those plus the new guard here, each in the same project, none
twice.
- npm's own checks across Node versions: from 22.12 up, devEngines passes and no
package warns EBADENGINE, the same as main; below it npm ci and npm run stop with
EBADDEVENGINES. Node 20 could not run from source already, and Vite 7 rejects
22.5 to 22.11. npm ci logs the one deprecation main logs. release.yml's lock sync
changes only the version fields.
- dev tree audit: main 10 findings with 2 critical, here 7 with none critical;
production stays at 0.
- red to green: main's git-index-currency fails 7 of 13 under Vitest 4; putting
the flags back under poolOptions turns the guard red.
Original PR #1667 by @danusha2345.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Colby Mchenry
co-authored by
Claude Opus 5.5
parent
274b43c44b
commit
b1e6c9767d
@@ -47,15 +47,14 @@ leaves behind, and asserts the seam: nothing outside `lib/adapter.js` may reach
|
||||
package is **prepared, not published** — `ui/package.json` carries `"private": true` deliberately,
|
||||
and `scripts/pack-npm.sh` only packs a tarball when `CODEGRAPH_PACK_UI=1`.
|
||||
|
||||
Tests run as **two vitest projects** (`vitest.workspace.mts`): `engine` (node) and `ui` (jsdom, the
|
||||
Tests run as **two Vitest projects** (`test.projects` in `vitest.config.mts`): `engine` (node) and `ui` (jsdom, the
|
||||
Svelte plugin, `resolve.conditions: ['browser']`) for the single `__tests__/ui-package.test.ts`.
|
||||
`npm test` still runs both. The split is not cosmetic — `browser` is a package-resolution
|
||||
condition, and applied globally it hands the engine's suites the browser builds of
|
||||
`web-tree-sitter` and friends. The root config (`vitest.config.mts`, `.mts` because the plugin is
|
||||
ESM-only and the repo is CJS) is the shared base; note that a workspace project **concatenates**
|
||||
the base's `include` with its own, which is why the `ui` project does not `extends` it.
|
||||
ESM-only and the repo is CJS) is the shared base; note that a project with `extends: true` **concatenates** the base's `include` with its own, which is why the `ui` project sets `extends: false`.
|
||||
|
||||
Node engines: `>=20.0.0 <25.0.0`. There is a hard exit on Node 25.x and below 20 (see `src/bin/node-version-check.ts`).
|
||||
Node engines: `>=20.0.0 <25.0.0`. There is a hard exit on Node 25.x and below 20 (see `src/bin/node-version-check.ts`). That range is what users run. Working in this repo needs Node 22.12 or newer: `devEngines` makes `npm ci` and `npm run` stop on anything older, for Vite 7 and Vitest 4.
|
||||
|
||||
## Architecture
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
- `codegraph serve --mcp --no-telemetry` turns telemetry off for one MCP server entry, so a shared MCP config can opt out without an environment variable; a background daemon that's already running for the project keeps its own setting until it exits. Thanks @danusha2345. (#1908)
|
||||
- `codegraph implementations <name>` lists the types that implement or extend a trait, interface or class, with each one's file and line, how it's tied to the type, and whether it's test code, a Rust mock in a `#[cfg(test)]` module included; `--depth` follows subclasses of subclasses. Thanks @danusha2345. (#2833)
|
||||
- Set `CODEGRAPH_SYNTH_MIN_INTERVAL_MS` to limit how often live syncs rebuild the callback and event links across the whole project, which on a large TypeScript or Vue repo otherwise happens on almost every edit; a rebuild that's put off runs when the interval is up even if no edit follows, and until then those links can be that far behind your code. A full `codegraph index` is never held. Thanks @danusha2345. (#2911)
|
||||
- For contributors, the test suite now runs on Vitest 4 and working in this repository needs Node 22.12 or newer; installing and using CodeGraph doesn't change. Thanks @danusha2345.
|
||||
- New `codegraph cycles` command lists the groups of files that import each other in a circle, as text or `--json`, and exits 1 when it finds any, so it works as a pre-commit or CI check (#888). Thanks @jiangyq9 and @goutham80808.
|
||||
- `codegraph init --local-only` keeps `.codegraph/` out of git entirely, so nothing of CodeGraph's shows in `git status`, and it works on a project that's already set up, leaving a `.codegraph/.gitignore` you've edited or committed alone (#910). Thanks @jadchene, @jiangyq9, @Wood-Q and @walterf3.
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ Thanks for helping out. Small, focused changes are the easiest to review and lan
|
||||
|
||||
## Build from source
|
||||
|
||||
You need Git, npm, and Node.js 22.5 or later, below 25. Running from source uses Node's built-in `node:sqlite`; the published installers bundle their own Node, so this only matters here.
|
||||
You need Git, npm, and Node.js 22.12 or later, below 25. `npm ci` stops on anything older, because the build and test tools need it and running from source uses Node's built-in `node:sqlite`; the published installers bundle their own Node, so this only matters here.
|
||||
|
||||
```bash
|
||||
# Fork the repository on GitHub, then:
|
||||
|
||||
@@ -13,8 +13,28 @@ vi.mock('child_process', async importOriginal => {
|
||||
});
|
||||
vi.mock('fs', async importOriginal => {
|
||||
const actual = await importOriginal<typeof import('fs')>();
|
||||
return { ...actual, readFileSync: vi.fn(actual.readFileSync) };
|
||||
// openSync too: a bounded source reader opens a descriptor instead of
|
||||
// calling readFileSync, and the injected read failure must reach either.
|
||||
return { ...actual, readFileSync: vi.fn(actual.readFileSync), openSync: vi.fn(actual.openSync) };
|
||||
});
|
||||
// The real entry points, for the injecting implementations to fall through to
|
||||
// and for afterEach to reinstate. Under Vitest 4 `vi.spyOn` on a mocked
|
||||
// module's export returns the same `vi.fn`, so reading `cp.execFileSync` inside
|
||||
// a test and calling it from the injected implementation recurses into itself,
|
||||
// and `vi.restoreAllMocks()` no longer resets a `vi.fn`'s implementation.
|
||||
const actualCp = await vi.importActual<typeof import('child_process')>('child_process');
|
||||
const actualFs = await vi.importActual<typeof import('fs')>('fs');
|
||||
const injectExecFileSync = (impl: (real: typeof cp.execFileSync, ...args: any[]) => unknown) =>
|
||||
vi.mocked(cp.execFileSync).mockImplementation(((...args: any[]) => impl(actualCp.execFileSync, ...args)) as typeof cp.execFileSync);
|
||||
const injectReadFileSync = (impl: (real: typeof fs.readFileSync, ...args: any[]) => unknown) =>
|
||||
vi.mocked(fs.readFileSync).mockImplementation(((...args: any[]) => impl(actualFs.readFileSync, ...args)) as typeof fs.readFileSync);
|
||||
const injectOpenSync = (impl: (real: typeof fs.openSync, ...args: any[]) => unknown) =>
|
||||
vi.mocked(fs.openSync).mockImplementation(((...args: any[]) => impl(actualFs.openSync, ...args)) as typeof fs.openSync);
|
||||
const reinstateIo = () => {
|
||||
vi.mocked(cp.execFileSync).mockImplementation(actualCp.execFileSync as typeof cp.execFileSync);
|
||||
vi.mocked(fs.readFileSync).mockImplementation(actualFs.readFileSync as typeof fs.readFileSync);
|
||||
vi.mocked(fs.openSync).mockImplementation(actualFs.openSync as typeof fs.openSync);
|
||||
};
|
||||
|
||||
describe('git index currency across commits and restores (#1829)', () => {
|
||||
let root: string;
|
||||
@@ -34,7 +54,7 @@ describe('git index currency across commits and restores (#1829)', () => {
|
||||
cg = CodeGraph.initSync(root);
|
||||
expect((await cg.indexAll()).success).toBe(true);
|
||||
});
|
||||
afterEach(() => { vi.restoreAllMocks(); cg?.close(); fs.rmSync(root, { recursive: true, force: true }); });
|
||||
afterEach(() => { reinstateIo(); vi.restoreAllMocks(); cg?.close(); fs.rmSync(root, { recursive: true, force: true }); });
|
||||
|
||||
it.each(['index', 'sync', 'scoped'] as const)('sees a restored indexed dirty edit after %s', async mode => {
|
||||
write('source.ts', 'dirtyVersion');
|
||||
@@ -80,12 +100,11 @@ describe('git index currency across commits and restores (#1829)', () => {
|
||||
|
||||
it('falls back when git diff fails instead of claiming a clean index', () => {
|
||||
write('new.ts', 'newSymbol'); commit();
|
||||
const real = cp.execFileSync;
|
||||
let injected = 0;
|
||||
vi.spyOn(cp, 'execFileSync').mockImplementation(((file: string, args: string[], options: any) => {
|
||||
injectExecFileSync((real, file: string, args: string[], options: any) => {
|
||||
if (file === 'git' && args[0] === 'diff') { injected++; throw new Error('Injected git diff timeout'); }
|
||||
return real(file, args, options);
|
||||
}) as typeof cp.execFileSync);
|
||||
});
|
||||
expect(cg.getChangedFiles().added).toEqual(['new.ts']);
|
||||
expect(injected).toBeGreaterThan(0);
|
||||
});
|
||||
@@ -135,19 +154,17 @@ describe('git index currency across commits and restores (#1829)', () => {
|
||||
// Sync reads a source file through a bounded reader that opens a
|
||||
// descriptor (#1910), so the failure is injected at openSync as well as
|
||||
// readFileSync: it must reach whichever one the read goes through.
|
||||
const realRead = fs.readFileSync;
|
||||
const realOpen = fs.openSync;
|
||||
let injected = 0;
|
||||
const failNewTs = (real: (...args: any[]) => unknown) => (file: any, ...args: any[]) => {
|
||||
const failNewTs = (real: (...args: any[]) => unknown, file: any, ...args: any[]) => {
|
||||
if (String(file) === path.join(root, 'new.ts')) { injected++; throw new Error('Injected transient read error'); }
|
||||
return real(file, ...args);
|
||||
};
|
||||
vi.spyOn(fs, 'readFileSync').mockImplementation(failNewTs(realRead as any) as typeof fs.readFileSync);
|
||||
vi.spyOn(fs, 'openSync').mockImplementation(failNewTs(realOpen as any) as typeof fs.openSync);
|
||||
injectReadFileSync(failNewTs);
|
||||
injectOpenSync(failNewTs);
|
||||
await cg.sync();
|
||||
expect(injected).toBeGreaterThan(0);
|
||||
expect(symbols('newSymbol')).not.toContain('newSymbol');
|
||||
vi.restoreAllMocks();
|
||||
reinstateIo();
|
||||
expect(cg.getChangedFiles().added).toEqual(['new.ts']);
|
||||
await cg.sync(); clean();
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import type { GlobalSetupContext } from 'vitest/node';
|
||||
import type { TestProject } from 'vitest/node';
|
||||
|
||||
declare module 'vitest' {
|
||||
export interface ProvidedContext {
|
||||
@@ -20,7 +20,7 @@ declare module 'vitest' {
|
||||
}
|
||||
}
|
||||
|
||||
export default function setup({ provide }: GlobalSetupContext): () => void {
|
||||
export default function setup({ provide }: TestProject): () => void {
|
||||
const registry = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-test-homes-'));
|
||||
provide('homeSandboxRegistry', registry);
|
||||
return () => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* home, Claude profile, daemon registry or git identity.
|
||||
*/
|
||||
import { describe, it, expect, inject } from 'vitest';
|
||||
import type { GlobalSetupContext } from 'vitest/node';
|
||||
import type { TestProject } from 'vitest/node';
|
||||
import { execFileSync } from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
@@ -77,7 +77,7 @@ describe('test home sandbox', () => {
|
||||
let registry = '';
|
||||
const teardown = setupHomeSandboxRun({
|
||||
provide(_key: string, value: string) { registry = value; },
|
||||
} as unknown as GlobalSetupContext);
|
||||
} as unknown as TestProject);
|
||||
const homes = ['skipped', 'held'].map((label) => {
|
||||
const home = fs.mkdtempSync(path.join(os.tmpdir(), `codegraph-test-home-${label}-`));
|
||||
fs.writeFileSync(path.join(home, '.gitconfig'), '');
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* The test workers run with the WASM runtime flags.
|
||||
*
|
||||
* Without them a pool worker compiles the tree-sitter grammars on V8's
|
||||
* optimizing tier, and once enough parses have warmed a grammar up the worker
|
||||
* dies with `Fatal process out of memory: Zone`, which vitest reports only as
|
||||
* "Worker exited unexpectedly", with the rest of the file unrun (#1779).
|
||||
*
|
||||
* The flags reach the workers through a vitest option, and vitest ignores an
|
||||
* option it no longer reads without a word: `poolOptions.forks.execArgv` went
|
||||
* that way in the move to Vitest 4. So this reads the worker's own command
|
||||
* line instead of trusting the config.
|
||||
*/
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { WASM_RUNTIME_FLAGS } from '../src/extraction/wasm-runtime-flags';
|
||||
|
||||
describe('test pool workers', () => {
|
||||
it('run with the WASM runtime flags', () => {
|
||||
for (const flag of WASM_RUNTIME_FLAGS) expect(process.execArgv).toContain(flag);
|
||||
});
|
||||
});
|
||||
Generated
+319
-884
File diff suppressed because it is too large
Load Diff
+9
-2
@@ -19,6 +19,13 @@
|
||||
"workspaces": [
|
||||
"ui"
|
||||
],
|
||||
"devEngines": {
|
||||
"runtime": {
|
||||
"name": "node",
|
||||
"version": ">=22.12.0",
|
||||
"onFail": "error"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc && npm run copy-assets && npm run build:ui && node -e \"require('fs').chmodSync('dist/bin/codegraph.js', 0o755)\"",
|
||||
"build:ui": "cd ui && npm run build && cd .. && node scripts/check-ui-build.mjs",
|
||||
@@ -54,12 +61,12 @@
|
||||
"web-tree-sitter": "^0.25.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
||||
"@types/node": "^20.19.30",
|
||||
"@types/picomatch": "^4.0.2",
|
||||
"jsdom": "^25.0.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vitest": "^2.1.9"
|
||||
"vitest": "^4.1.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0 <25.0.0"
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
"directory": "ui"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md"
|
||||
|
||||
+49
-10
@@ -1,11 +1,10 @@
|
||||
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import { WASM_RUNTIME_FLAGS } from './src/extraction/wasm-runtime-flags';
|
||||
|
||||
/**
|
||||
* The SHARED base. `vitest.workspace.mts` extends it twice — once for the
|
||||
* engine's node-environment suites and once for the viewer package's jsdom
|
||||
* one — so the environment, the plugins and the module-resolution conditions
|
||||
* a browser test needs cannot leak into the other 200-odd suites.
|
||||
* One process, two Vitest projects. The engine stays in Node; the UI package
|
||||
* test alone gets Svelte compilation, jsdom and browser resolution conditions.
|
||||
*/
|
||||
export default defineConfig({
|
||||
test: {
|
||||
@@ -18,6 +17,15 @@ export default defineConfig({
|
||||
// A throwaway home dir (and git global config) per test file, so nothing
|
||||
// the suite runs can write to the developer's real one (#2275).
|
||||
setupFiles: ['./__tests__/setup-home-sandbox.ts'],
|
||||
/**
|
||||
* Since Vitest 3 a synchronous test or hook fails when it outlasts its
|
||||
* timeout. Under Vitest 2 the timer could not fire until the body had
|
||||
* returned, so a body blocked in `spawnSync` never timed out at all. Hundreds
|
||||
* of tests here block on the built CLI, and on a loaded machine the 5 s and
|
||||
* 10 s defaults would turn them into flakes.
|
||||
*/
|
||||
testTimeout: 30_000,
|
||||
hookTimeout: 60_000,
|
||||
/**
|
||||
* Several MCP integration tests (mcp-daemon, mcp-initialize, mcp-ppid-watchdog,
|
||||
* mcp-roots) spawn `dist/bin/codegraph.js serve --mcp` with `process.execPath`
|
||||
@@ -49,16 +57,47 @@ export default defineConfig({
|
||||
* parses have warmed a grammar function up, its background tier-up job
|
||||
* exhausts a compiler Zone and aborts the worker — `Fatal process out of
|
||||
* memory: Zone`, surfaced by vitest only as "Worker exited unexpectedly"
|
||||
* with the rest of the file's tests silently unrun (#1779; the product-side
|
||||
* story is in wasm-runtime-flags.ts, #293/#298). On Node 24 with a
|
||||
* 660-test extraction suite this reproduced on every run at the same test.
|
||||
* V8 flags are process-global, so the parse worker threads a test spawns
|
||||
* are covered too.
|
||||
* with the rest of the file's tests silently unrun (#1779, #1883; the
|
||||
* product-side story is in wasm-runtime-flags.ts, #293/#298). V8 flags are
|
||||
* process-global, so the parse worker threads a test spawns are covered
|
||||
* too. Vitest 4 reads `test.execArgv`; the 2.x `poolOptions.forks.execArgv`
|
||||
* is silently ignored here. The engine project inherits it via `extends`.
|
||||
*/
|
||||
poolOptions: { forks: { execArgv: [...WASM_RUNTIME_FLAGS] } },
|
||||
execArgv: [...WASM_RUNTIME_FLAGS],
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
reporter: ['text', 'json', 'html'],
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
extends: true,
|
||||
test: {
|
||||
name: 'engine',
|
||||
include: ['__tests__/**/*.test.ts'],
|
||||
exclude: ['**/node_modules/**', '**/dist/**', '__tests__/ui-package.test.ts'],
|
||||
},
|
||||
},
|
||||
{
|
||||
// Browser package resolution must not leak into the engine project:
|
||||
// web-tree-sitter and other dual packages would resolve differently.
|
||||
// And no `extends`: a project that extends takes the base's `include`
|
||||
// too, so every engine suite would run a second time inside jsdom.
|
||||
extends: false,
|
||||
plugins: [svelte({ configFile: 'ui/svelte.config.js' })],
|
||||
resolve: { conditions: ['browser'] },
|
||||
test: {
|
||||
name: 'ui',
|
||||
globals: true,
|
||||
include: ['__tests__/ui-package.test.ts'],
|
||||
environment: 'jsdom',
|
||||
server: {
|
||||
deps: {
|
||||
// @xyflow/svelte ships source .svelte files that Node cannot load.
|
||||
inline: [/@xyflow\/svelte/],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import { svelte, vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
import { defineWorkspace } from 'vitest/config';
|
||||
|
||||
/**
|
||||
* Two projects, one command (`npm test` still runs everything).
|
||||
*
|
||||
* The split exists because of exactly one suite. `ui-package.test.ts` mounts
|
||||
* `@colbymchenry/codegraph-ui`'s components against a mock adapter (task
|
||||
* CG-61), and to do that it needs three things the engine's suites must never
|
||||
* see:
|
||||
*
|
||||
* - the **Svelte plugin**, to compile `.svelte` and `.svelte.ts` modules;
|
||||
* - **jsdom**, because a component without a document is not a render;
|
||||
* - `resolve.conditions: ['browser']`, so `svelte` resolves to its client
|
||||
* build rather than its server one (`mount()` throws on the server).
|
||||
*
|
||||
* That last one is why this is a workspace rather than one config with a
|
||||
* couple of extra fields. `browser` is a package-resolution condition, not a
|
||||
* test setting: applied globally it would also hand the engine's suites the
|
||||
* browser builds of `web-tree-sitter` and friends, and the failures that
|
||||
* causes look nothing like their cause.
|
||||
*
|
||||
* The engine project `extends` the shared base, so the env vars, Node guard and
|
||||
* home-dir sandbox in `vitest.config.mts` still apply to every engine test. The
|
||||
* ui project does not — see the note on it.
|
||||
*/
|
||||
export default defineWorkspace([
|
||||
{
|
||||
extends: './vitest.config.mts',
|
||||
test: {
|
||||
name: 'engine',
|
||||
include: ['__tests__/**/*.test.ts'],
|
||||
exclude: ['**/node_modules/**', '**/dist/**', '__tests__/ui-package.test.ts'],
|
||||
},
|
||||
},
|
||||
{
|
||||
// Deliberately NOT `extends`: a workspace project CONCATENATES the base's
|
||||
// `include` with its own, so extending here would run all 200-odd engine
|
||||
// suites a second time inside jsdom (and two of them fail there, for
|
||||
// reasons that have nothing to do with anything). This project stands
|
||||
// alone, and it needs none of the base's spawn-related env anyway.
|
||||
plugins: [
|
||||
// The same preprocessor `ui/svelte.config.js` builds with, so the test
|
||||
// compiles what the package ships.
|
||||
svelte({ preprocess: vitePreprocess() }),
|
||||
],
|
||||
resolve: { conditions: ['browser'] },
|
||||
test: {
|
||||
name: 'ui',
|
||||
globals: true,
|
||||
include: ['__tests__/ui-package.test.ts'],
|
||||
environment: 'jsdom',
|
||||
server: {
|
||||
deps: {
|
||||
// `@xyflow/svelte` ships uncompiled `.svelte` files, so it has to go
|
||||
// through the plugin above rather than be externalised to Node,
|
||||
// which has no idea what a `.svelte` file is.
|
||||
inline: [/@xyflow\/svelte/],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
Reference in New Issue
Block a user