From 628885ae0f9be3c11515ad85e5711f427925d8aa Mon Sep 17 00:00:00 2001 From: implementer Date: Fri, 28 Aug 2026 21:33:52 +0000 Subject: [PATCH] test: lock in TypeScript 6.0.3 exact dependency (E00-S01-T09) --- tests/typescript-pin.test.mjs | 108 ++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 tests/typescript-pin.test.mjs diff --git a/tests/typescript-pin.test.mjs b/tests/typescript-pin.test.mjs new file mode 100644 index 0000000..4908c1b --- /dev/null +++ b/tests/typescript-pin.test.mjs @@ -0,0 +1,108 @@ +/** + * TypeScript exact-pin test — locks in the [E00-S01-T09] TypeScript 6.0.3 + * exact dependency for the workspace. + * + * Acceptance criteria covered (each test fails without the committed config): + * - "TypeScript 6.0.3 is pinned as an exact dependency" → the root + * `package.json` declares `devDependencies.typescript` as exactly + * `6.0.3` (a bare MAJOR.MINOR.PATCH — no `^`/`~`/`>=` range), and + * `pnpm-lock.yaml` resolves the root importer with specifier `6.0.3` / + * version `6.0.3` and contains exactly one resolved TypeScript entry + * (`typescript@6.0.3`) in its packages section. + * - "workspace packages resolve the exact TypeScript version" → running + * `pnpm exec tsc --version` inside every workspace package — the same + * binary the package `build`/`typecheck` scripts invoke — reports + * `Version 6.0.3`. + * + * Run: `node --test tests/typescript-pin.test.mjs` + * (node:test — built into Node >= 18; no dependencies, lockfile untouched.) + */ + +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { spawnSync } from 'node:child_process'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); + +const read = (relPath) => readFileSync(path.join(REPO_ROOT, relPath), 'utf8'); + +/** The exact TypeScript version this workspace is pinned to ([E00-S01-T09]). */ +const PINNED_TYPESCRIPT = '6.0.3'; + +/** Every workspace package that must resolve the pinned TypeScript version. */ +const WORKSPACE_PACKAGES = ['apps/server', 'packages/core', 'extensions/example']; + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +test('root package.json pins typescript as an exact dependency (6.0.3)', () => { + const manifest = JSON.parse(read('package.json')); + const spec = manifest.devDependencies?.typescript; + assert.equal( + spec, + PINNED_TYPESCRIPT, + `root package.json must pin devDependencies.typescript exactly as "${PINNED_TYPESCRIPT}" (got "${spec}")`, + ); + // The pin must be exact — a bare MAJOR.MINOR.PATCH, never a semver range + // (^, ~, >=, <, *, x-ranges) that could resolve to a different version. + assert.match( + spec, + /^\d+\.\d+\.\d+$/, + `"${spec}" is not an exact MAJOR.MINOR.PATCH version — pin typescript exactly, without a semver range`, + ); +}); + +test('pnpm-lock.yaml resolves the root typescript pin to exactly 6.0.3', () => { + const lockfile = read('pnpm-lock.yaml'); + + // Root importer: devDependencies.typescript must be specifier 6.0.3 with + // resolved version 6.0.3 (a range specifier like "^6.0.3" fails this). + const importersSection = lockfile.slice( + lockfile.indexOf('importers:'), + lockfile.indexOf('packages:'), + ); + assert.match( + importersSection, + /devDependencies:\s*\n\s+typescript:\s*\n\s+specifier: 6\.0\.3\s*\n\s+version: 6\.0\.3/, + 'pnpm-lock.yaml must resolve the root typescript devDependency to specifier "6.0.3" / version "6.0.3"', + ); + + // The packages section must contain exactly one resolved TypeScript entry, + // so no package can drift onto a different TypeScript version. + const packagesSection = lockfile.slice( + lockfile.indexOf('packages:'), + lockfile.indexOf('snapshots:'), + ); + const resolvedTypescriptEntries = [...packagesSection.matchAll(/^\s+(typescript@\S+):/gm)].map( + (m) => m[1], + ); + assert.deepEqual( + resolvedTypescriptEntries, + [`typescript@${PINNED_TYPESCRIPT}`], + `the lockfile must contain exactly one resolved TypeScript version (typescript@${PINNED_TYPESCRIPT}); got: ${resolvedTypescriptEntries.join(', ')}`, + ); +}); + +test('every workspace package resolves the exact TypeScript version (6.0.3)', () => { + for (const pkg of WORKSPACE_PACKAGES) { + const result = spawnSync('corepack', ['pnpm', 'exec', 'tsc', '--version'], { + cwd: path.join(REPO_ROOT, pkg), + encoding: 'utf8', + timeout: 120_000, + }); + assert.equal( + result.status, + 0, + `"corepack pnpm exec tsc --version" failed in ${pkg}: ${(result.stderr || result.stdout || '').trim()}`, + ); + assert.equal( + result.stdout.trim(), + `Version ${PINNED_TYPESCRIPT}`, + `${pkg} must resolve TypeScript ${PINNED_TYPESCRIPT} (got "${result.stdout.trim()}")`, + ); + } +});