109 lines
4.4 KiB
JavaScript
109 lines
4.4 KiB
JavaScript
/**
|
|
* 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()}")`,
|
|
);
|
|
}
|
|
});
|