Files
multi-simadmin/test/phase-one-workspace.test.js
T

99 lines
3.9 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['test:contract'],
/openapi-validator\.test\.ts/,
'contract gate must include independent OpenAPI mutation tests',
);
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');
});