94 lines
3.7 KiB
JavaScript
94 lines
3.7 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { readFile } from 'node:fs/promises';
|
|
import test from 'node:test';
|
|
|
|
const root = new URL('../', import.meta.url);
|
|
const readJson = async (path) => JSON.parse(await readFile(new URL(path, root), 'utf8'));
|
|
|
|
const workspacePackages = ['apps/api', 'apps/web', 'packages/contracts'];
|
|
|
|
test('Phase 1 workspace pins pnpm and preserves the legacy service gates', async () => {
|
|
const packageJson = await readJson('package.json');
|
|
|
|
assert.equal(packageJson.packageManager, 'pnpm@11.13.0');
|
|
for (const script of ['lint', 'format:check', 'typecheck', 'test:unit', 'test:contract']) {
|
|
assert.equal(typeof packageJson.scripts[script], 'string', `missing ${script} script`);
|
|
}
|
|
assert.equal(packageJson.scripts.start, 'node server/index.js');
|
|
assert.equal(packageJson.scripts.dev, 'node --watch server/index.js');
|
|
assert.match(
|
|
packageJson.scripts.test,
|
|
/node --test/,
|
|
'root test must retain the legacy node:test gate',
|
|
);
|
|
assert.match(packageJson.scripts.test, /test\/\*\.test\.js/);
|
|
assert.match(packageJson.scripts.test, /packages\/operation-registry\/test\/\*\.test\.ts/);
|
|
assert.match(packageJson.scripts.test, /packages\/test-fixtures\/test\/\*\.test\.ts/);
|
|
assert.doesNotMatch(
|
|
packageJson.scripts.test,
|
|
/^node --test$/,
|
|
'root test must not auto-discover Vitest-only files',
|
|
);
|
|
assert.match(packageJson.scripts.lint, /apps/);
|
|
assert.match(packageJson.scripts.lint, /packages\/contracts/);
|
|
assert.match(packageJson.scripts.lint, /eslint\.config\.js/);
|
|
assert.doesNotMatch(
|
|
packageJson.scripts.lint,
|
|
/eslint\s+\./,
|
|
'Phase 1 lint must not claim unmigrated legacy code',
|
|
);
|
|
assert.doesNotMatch(packageJson.scripts.lint, /echo|true/, 'lint must execute a real checker');
|
|
assert.match(packageJson.scripts['format:check'], /prettier --check/);
|
|
assert.match(
|
|
packageJson.scripts.typecheck,
|
|
/^corepack pnpm /,
|
|
'typecheck must work when pnpm is provided only by Corepack',
|
|
);
|
|
});
|
|
|
|
test('Phase 1 workspace and strict shared TypeScript policy are explicit', async () => {
|
|
const workspace = await readFile(new URL('pnpm-workspace.yaml', root), 'utf8');
|
|
assert.match(workspace, /^packages:\s*$/m);
|
|
assert.match(workspace, /- ['"]apps\/\*['"]/);
|
|
assert.match(workspace, /- ['"]packages\/\*['"]/);
|
|
|
|
const tsconfig = await readJson('tsconfig.base.json');
|
|
const required = {
|
|
strict: true,
|
|
noUncheckedIndexedAccess: true,
|
|
exactOptionalPropertyTypes: true,
|
|
useUnknownInCatchVariables: true,
|
|
noImplicitOverride: true,
|
|
};
|
|
for (const [option, value] of Object.entries(required)) {
|
|
assert.equal(tsconfig.compilerOptions[option], value, `${option} must be enabled`);
|
|
}
|
|
});
|
|
|
|
test('initial application and contract packages compile from isolated source entries', async () => {
|
|
for (const directory of workspacePackages) {
|
|
const manifest = await readJson(`${directory}/package.json`);
|
|
const tsconfig = await readJson(`${directory}/tsconfig.json`);
|
|
await readFile(new URL(`${directory}/src/index.ts`, root), 'utf8');
|
|
|
|
const serialized = JSON.stringify({ manifest, tsconfig });
|
|
assert.doesNotMatch(
|
|
serialized,
|
|
/(?:^|[/.])server(?:[/.]|$)/,
|
|
`${directory} must not depend on legacy server`,
|
|
);
|
|
assert.doesNotMatch(
|
|
serialized,
|
|
/(?:^|[/.])public(?:[/.]|$)/,
|
|
`${directory} must not depend on legacy public assets`,
|
|
);
|
|
assert.equal(tsconfig.extends, '../../tsconfig.base.json');
|
|
}
|
|
});
|
|
|
|
test('runtime dependencies stay pinned to the versions already present before workspace migration', async () => {
|
|
const packageJson = await readJson('package.json');
|
|
assert.equal(packageJson.dependencies.fastify, '5.10.0');
|
|
assert.equal(packageJson.dependencies['@fastify/static'], '9.1.3');
|
|
});
|