mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-11 22:50:06 +00:00
chore: Remove remaining Jest references (no-changelog) (#33412)
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
cubic-dev-ai[bot]
parent
29e0e32e3b
commit
8bb6489918
@@ -29,8 +29,7 @@ on:
|
||||
description: |
|
||||
Newline-separated list of CHANGED_FILES from ci-filter. Passed to
|
||||
per-package `janitor scope` invocations so test runners can filter
|
||||
to actually-changed source files via jest --findRelatedTests or
|
||||
vitest related.
|
||||
to actually-changed source files via vitest related.
|
||||
required: false
|
||||
default: ''
|
||||
type: string
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Mock } from 'vitest';
|
||||
|
||||
// Mock @daytona/sdk so we can drive sandbox creation, token refresh, and
|
||||
// sandbox refetch behavior from Jest without touching the network.
|
||||
// sandbox refetch behavior from Vitest without touching the network.
|
||||
|
||||
interface MockSandbox {
|
||||
id: string;
|
||||
|
||||
+1
-1
@@ -185,7 +185,7 @@ describe('Discovery Subgraph - Integration Tests', () => {
|
||||
vi.setConfig({ testTimeout: 1800000 }); // 30 minutes
|
||||
|
||||
beforeAll(async () => {
|
||||
// Override console.log to use process.stdout directly, bypassing Jest's
|
||||
// Override console.log to use process.stdout directly, bypassing Vitest's
|
||||
// verbose wrapper that adds stack traces to every log line
|
||||
vi.spyOn(console, 'log').mockImplementation((...args: unknown[]) => {
|
||||
process.stdout.write(args.map(String).join(' ') + '\n');
|
||||
|
||||
@@ -106,10 +106,9 @@ function respondWith(routes: Route[]) {
|
||||
type AnyFn = (...args: any[]) => any;
|
||||
|
||||
/**
|
||||
* Test-framework mock factory — pass `jest.fn` or `vi.fn`. Injected so this
|
||||
* helper stays framework-neutral: `@n8n/backend-network` runs on vitest while
|
||||
* consumers such as `packages/cli` run on jest, and `expect(fn).toHaveBeenCalled…`
|
||||
* assertions need a real mock from the consumer's own framework.
|
||||
* Test-framework mock factory — pass `vi.fn`. Injected so this helper stays
|
||||
* framework-neutral and `expect(fn).toHaveBeenCalled…` assertions get a real
|
||||
* mock from the consumer's own test framework.
|
||||
*/
|
||||
export type MockFnFactory = <T extends AnyFn>(
|
||||
impl: T,
|
||||
@@ -121,7 +120,7 @@ export type MockFnFactory = <T extends AnyFn>(
|
||||
* `headers` merged), so assertions see exactly what the real client would send.
|
||||
*
|
||||
* @param routes responses to serve, matched and consumed in order.
|
||||
* @param fn the consumer's mock factory (`jest.fn` / `vi.fn`).
|
||||
* @param fn the consumer's mock factory (`vi.fn`).
|
||||
*/
|
||||
export function createFakeOutboundHttp(routes: Route[], fn: MockFnFactory) {
|
||||
const stub = respondWith(routes);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"lint": "eslint . --quiet",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"watch": "tsc -p tsconfig.build.json --watch",
|
||||
"test": "echo \"WARNING: no test specified\" && exit 0",
|
||||
"test": "node -e \"process.exit(0)\"",
|
||||
"test:dev": "echo \"WARNING: no test specified\" && exit 0"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"lint": "eslint . --quiet",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"start": "./bin/n8n-benchmark",
|
||||
"test": "echo \"WARNING: no test specified\" && exit 0",
|
||||
"test": "node -e \"process.exit(0)\"",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"benchmark": "zx scripts/run.mjs",
|
||||
"benchmark-in-cloud": "pnpm benchmark --env cloud",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"lint": "eslint . --quiet",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"watch": "tsc -p tsconfig.build.json --watch",
|
||||
"test": "jest --passWithNoTests"
|
||||
"test": "node -e \"process.exit(0)\""
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"module": "src/index.ts",
|
||||
|
||||
@@ -16,8 +16,8 @@ import { configDefaults } from 'vitest/config';
|
||||
* only `tsc` with cross-file type information collapses the union to `String`. Vite's
|
||||
* oxc transform — and SWC — emit `Object` instead, which TypeORM rejects at
|
||||
* `DataSource.initialize()`. Single-file `transpileModule` also emits `Object` because
|
||||
* it can't resolve the imported alias. A full Program is required, which mirrors the
|
||||
* old jest config that set `isolatedModules: false` for exactly this reason.
|
||||
* it can't resolve the imported alias. A full Program is required — the same
|
||||
* reason a non-isolated-modules TypeScript compile is needed here.
|
||||
*
|
||||
* Scoping to `src/entities/**` keeps the cost contained: only the ~50 entity files pay
|
||||
* the tsc price (and the Program is rooted there), while DI `@Service` constructor
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"lint": "eslint . --quiet",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"watch": "tsc -p tsconfig.build.json --watch",
|
||||
"test": "echo \"WARNING: no test specified\" && exit 0",
|
||||
"test": "node -e \"process.exit(0)\"",
|
||||
"test:dev": "echo \"WARNING: no test specified\" && exit 0"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
|
||||
@@ -5,7 +5,7 @@ export const NoErrorInstanceInToThrowRule = ESLintUtils.RuleCreator.withoutDocs(
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description:
|
||||
'Disallow passing error instances to `.toThrow()` and `.toThrowError`. Jest compares by reference, not message, making assertions flaky. Pass the error class and message string separately instead.',
|
||||
'Disallow passing error instances to `.toThrow()` and `.toThrowError`. Passing an instance makes the assertion ambiguous and flaky. Pass the error class and message string separately instead.',
|
||||
},
|
||||
messages: {
|
||||
noErrorInstance:
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ n8n community nodes are distributed as pre-built npm packages. Unlike regular np
|
||||
"name": "n8n-nodes-example",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "jest"
|
||||
"test": "vitest run"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"build:unchecked": "pnpm run build",
|
||||
"create-json-schema": "tsx scripts/create-json-schema.ts",
|
||||
"preview": "vite preview",
|
||||
"test": "node -e \"process.exit(0);\""
|
||||
"test": "node -e \"process.exit(0)\""
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "catalog:frontend",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* This entry point intentionally avoids importing anything from `../agent`
|
||||
* or other native agent-tainted modules so it remains safe to consume from
|
||||
* Jest CJS test environments.
|
||||
* downstream test environments.
|
||||
*/
|
||||
|
||||
export {
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import * as path from 'node:path';
|
||||
* 2. NODE_PATH must not be clobbered by load-nodes-and-credentials.ts
|
||||
* 3. Module._initPaths() must be called to pick up NODE_PATH at runtime
|
||||
*
|
||||
* Tests use child processes because Jest intercepts require() with its own
|
||||
* Tests use child processes because Vitest intercepts require() with its own
|
||||
* resolver which doesn't respect NODE_PATH changes.
|
||||
*
|
||||
* IMPORTANT: Scripts are placed in a separate directory from the installed
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
* only auto-excludes the test files it runs, so type decls, mocks and test
|
||||
* helpers otherwise land in the denominator at 0%. Spread these onto
|
||||
* `coverageConfigDefaults.exclude` in each config.
|
||||
*
|
||||
* Mirrors the jest equivalent at the repo root (jest.coverage-excludes.js) —
|
||||
* same intent, plain globs here vs `!`-negated globs there. Keep them in sync.
|
||||
*/
|
||||
export const coverageExcludes = [
|
||||
'**/*.spec.ts',
|
||||
|
||||
@@ -17,10 +17,10 @@ import { generateNodeDefinitions } from '../generate-types/generate-node-defs-cl
|
||||
// Use a worker-specific directory to prevent race conditions when multiple test
|
||||
// workers run schema-using tests in parallel (they would otherwise concurrently
|
||||
// delete and regenerate schemas into the same shared temp directory).
|
||||
// Vitest exposes the per-worker id as VITEST_POOL_ID; Jest used JEST_WORKER_ID.
|
||||
// Vitest exposes the per-worker id as VITEST_POOL_ID.
|
||||
// Without this, every parallel worker collapses onto the same `-0` directory and
|
||||
// one worker's rmSync wipes schemas another worker just generated.
|
||||
const WORKER_ID = process.env.VITEST_POOL_ID ?? process.env.JEST_WORKER_ID ?? '0';
|
||||
const WORKER_ID = process.env.VITEST_POOL_ID ?? '0';
|
||||
const SCHEMA_TEST_DIR = path.join(os.tmpdir(), `n8n-schema-tests-${WORKER_ID}`);
|
||||
const STAMP_FILE = path.join(SCHEMA_TEST_DIR, '.generator-hash');
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ describe('enqueueExecution', () => {
|
||||
const error = new Error('stop for test purposes');
|
||||
|
||||
// mock a rejection to stop execution flow before we create the PCancelable promise,
|
||||
// so that Jest does not move on to tear down the suite until the PCancelable settles
|
||||
// so that Vitest does not move on to tear down the suite until the PCancelable settles
|
||||
addJob.mockRejectedValueOnce(error);
|
||||
|
||||
// @ts-expect-error Private method
|
||||
|
||||
@@ -262,7 +262,7 @@ describe('TaskBroker', () => {
|
||||
validUntil: createValidUntil(1000),
|
||||
};
|
||||
|
||||
vi.spyOn(taskBroker, 'acceptOffer').mockResolvedValue(); // allow Jest to exit cleanly
|
||||
vi.spyOn(taskBroker, 'acceptOffer').mockResolvedValue(); // allow Vitest to exit cleanly
|
||||
|
||||
taskBroker.taskOffered(offer);
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ function expectWorkflowsMatch(
|
||||
const oldSorted = [...oldWorkflows].sort((a, b) => a.id.localeCompare(b.id));
|
||||
const newSorted = [...newWorkflows].sort((a, b) => a.id.localeCompare(b.id));
|
||||
|
||||
// Jest's toEqual does deep recursive comparison of all fields
|
||||
// Vitest's toEqual does deep recursive comparison of all fields
|
||||
expect(newSorted).toEqual(oldSorted);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ export interface SetupProps {
|
||||
enabledFeatures?: BooleanLicenseFeature[];
|
||||
quotas?: Partial<{ [K in NumericLicenseFeature]: number }>;
|
||||
modules?: ModuleName[];
|
||||
/** Override the default Jest timeout (ms) for the shared `beforeAll` setup hook. */
|
||||
/** Override the default test timeout (ms) for the shared `beforeAll` setup hook. */
|
||||
setupTimeout?: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -379,7 +379,7 @@ export const setupTestServer = ({
|
||||
// Close the HTTP server first so any in-flight requests can't reach the
|
||||
// DI container after testDb.terminate() resets it. Await the close so
|
||||
// pending handlers drain before the next file's beforeAll runs in
|
||||
// persistent Jest workers — otherwise stale handlers call
|
||||
// persistent Vitest workers — otherwise stale handlers call
|
||||
// Container.get(Logger), construct a fresh Logger, and trip Vitest's
|
||||
// "environment torn down" guard when winston is imported.
|
||||
// Skip when the server never started listening (some suites bail in
|
||||
|
||||
+10
-20
@@ -66,36 +66,26 @@ if (!pkgRoot) {
|
||||
|
||||
const fileRelToPkg = relative(pkgRoot, absFile);
|
||||
|
||||
function detectRunner(pkgRootDir) {
|
||||
function detectVitest(pkgRootDir) {
|
||||
const pkg = JSON.parse(readFileSync(resolve(pkgRootDir, 'package.json'), 'utf8'));
|
||||
const deps = { ...pkg.devDependencies, ...pkg.dependencies };
|
||||
if (deps.vitest) return 'vitest';
|
||||
if (deps.jest) return 'jest';
|
||||
if (deps.vitest) return true;
|
||||
|
||||
const testScript = pkg.scripts?.test ?? '';
|
||||
if (/\bvitest\b/.test(testScript)) return 'vitest';
|
||||
if (/\bjest\b/.test(testScript)) return 'jest';
|
||||
if (/\bvitest\b/.test(pkg.scripts?.test ?? '')) return true;
|
||||
|
||||
if (existsSync(resolve(pkgRootDir, 'jest.config.js')) ||
|
||||
existsSync(resolve(pkgRootDir, 'jest.config.ts')) ||
|
||||
existsSync(resolve(pkgRootDir, 'jest.config.mjs'))) return 'jest';
|
||||
if (existsSync(resolve(pkgRootDir, 'vitest.config.ts')) ||
|
||||
return (
|
||||
existsSync(resolve(pkgRootDir, 'vitest.config.ts')) ||
|
||||
existsSync(resolve(pkgRootDir, 'vitest.config.js')) ||
|
||||
existsSync(resolve(pkgRootDir, 'vitest.config.mjs'))) return 'vitest';
|
||||
|
||||
return null;
|
||||
existsSync(resolve(pkgRootDir, 'vitest.config.mjs'))
|
||||
);
|
||||
}
|
||||
|
||||
const runner = detectRunner(pkgRoot);
|
||||
if (!runner) {
|
||||
console.error(`Could not detect vitest or jest in ${pkgRoot}/package.json`);
|
||||
if (!detectVitest(pkgRoot)) {
|
||||
console.error(`Could not detect vitest in ${pkgRoot}/package.json`);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const runnerArgs =
|
||||
runner === 'vitest'
|
||||
? ['vitest', 'run', fileRelToPkg, '--reporter=dot']
|
||||
: ['jest', fileRelToPkg, '--colors=false'];
|
||||
const runnerArgs = ['vitest', 'run', fileRelToPkg, '--reporter=dot'];
|
||||
|
||||
let passed = 0;
|
||||
let firstFailureLogged = false;
|
||||
|
||||
@@ -65,10 +65,6 @@ describe('findPackageForSourceFile', () => {
|
||||
});
|
||||
|
||||
it('returns undefined for unowned paths', () => {
|
||||
assert.equal(
|
||||
findPackageForSourceFile('packages/@n8n/expression-runtime/src/foo.ts', ELIGIBLE),
|
||||
undefined,
|
||||
);
|
||||
assert.equal(findPackageForSourceFile('README.md', ELIGIBLE), undefined);
|
||||
});
|
||||
});
|
||||
@@ -88,7 +84,7 @@ describe('buildMatrixRowForFile (on-demand re-score path)', () => {
|
||||
|
||||
it('throws for files outside ELIGIBLE_PACKAGES', () => {
|
||||
assert.throws(
|
||||
() => buildMatrixRowForFile('packages/cli/src/server.ts', ELIGIBLE),
|
||||
() => buildMatrixRowForFile('packages/nodes-base/utils/binary.ts', ELIGIBLE),
|
||||
/No mutation-tracked package owns/,
|
||||
);
|
||||
});
|
||||
@@ -332,8 +328,8 @@ describe('buildMatrixFromPicked (global picker → matrix shape)', () => {
|
||||
// builder dies rather than spawning a mutate job we can't service.
|
||||
const picked = [
|
||||
{
|
||||
source_file_path: 'packages/@n8n/expression-runtime/src/foo.ts',
|
||||
package: '@n8n/expression-runtime',
|
||||
source_file_path: 'packages/nodes-base/utils/binary.ts',
|
||||
package: 'n8n-nodes-base',
|
||||
prior_status: 'new',
|
||||
effective_status: 'new',
|
||||
value: 1,
|
||||
|
||||
@@ -118,14 +118,14 @@ const NON_SOURCE_DIRS = new Set(['__tests__', '__mocks__', 'fixtures']);
|
||||
|
||||
// The vitest-eligible mutation-tracked packages. Single source of truth for
|
||||
// global mode: the picker walks every entry here unless overridden via
|
||||
// --block. Adding a package = one-line append here AND in
|
||||
// .github/workflows/mutation-health-nightly.yml `setup` job. Jest packages
|
||||
// and the isolated-vm engine (@n8n/expression-runtime, blocked on DEVP-257)
|
||||
// are intentionally absent.
|
||||
// --block. The nightly workflow's `setup` job builds its matrix from this
|
||||
// export (DEVP-497), so adding a package = one-line append here, nothing else.
|
||||
export const ELIGIBLE_PACKAGES = [
|
||||
{ name: 'n8n-workflow', dir: 'packages/workflow' },
|
||||
{ name: '@n8n/crdt', dir: 'packages/@n8n/crdt' },
|
||||
{ name: '@n8n/decorators', dir: 'packages/@n8n/decorators' },
|
||||
{ name: '@n8n/expression-runtime', dir: 'packages/@n8n/expression-runtime' },
|
||||
{ name: 'n8n', dir: 'packages/cli' },
|
||||
];
|
||||
|
||||
export function isEligible(pkgName) {
|
||||
|
||||
@@ -108,10 +108,7 @@ describe('isEligible (vitest allowlist unit test)', () => {
|
||||
});
|
||||
|
||||
it('rejects packages outside the allowlist', () => {
|
||||
// expression-runtime is intentionally blocked on DEVP-257
|
||||
assert.equal(isEligible('@n8n/expression-runtime'), false);
|
||||
// jest packages aren't onboarded yet
|
||||
assert.equal(isEligible('@n8n/cli'), false);
|
||||
assert.equal(isEligible('@n8n/foo'), false);
|
||||
assert.equal(isEligible(''), false);
|
||||
assert.equal(isEligible(undefined), false);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user