Skip to content

Commit 3a678c5

Browse files
committed
test(cli): import the commands under the planted prerelease manifest at collection time
Claude-Session: https://claude.ai/code/session_01CxBKycaiUpA1yGx1XyoGqX Co-authored-by: Claude <noreply@anthropic.com>
1 parent 95c59d7 commit 3a678c5

1 file changed

Lines changed: 28 additions & 28 deletions

File tree

‎packages/cli/test/scaffold-exact-objectstack-pin.test.ts‎

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
* and no other test sees until it lands: a `cut-rc` pass in pre mode makes
1313
* the CLI `X.Y.Z-rc.N`, and that whole string — prerelease tail included — is
1414
* the pin. The CLI reads its version from its own `package.json` once and
15-
* caches it, so the module graph is re-imported under a planted manifest read.
15+
* caches it, so this file first imports the commands under a planted manifest read.
1616
* The in-repo placement is the control: it keeps `workspace:*`.
1717
*/
1818

19-
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
19+
import { describe, it, expect, vi } from 'vitest';
2020
import fs from 'fs';
2121
import path from 'path';
2222
import { fileURLToPath } from 'url';
@@ -25,12 +25,6 @@ const HERE = path.dirname(fileURLToPath(import.meta.url));
2525
const CLI_MANIFEST = path.resolve(HERE, '..', 'package.json');
2626
const PRERELEASE = '18.1.0-rc.2';
2727

28-
type InitModule = typeof import('../src/commands/init.js');
29-
type CreateModule = typeof import('../src/commands/create.js');
30-
31-
let init: InitModule;
32-
let create: CreateModule;
33-
3428
/** Every `@objectstack/*` entry of a manifest, both dependency sections. */
3529
function objectstackDeps(pkg: {
3630
dependencies?: Record<string, string>;
@@ -41,28 +35,34 @@ function objectstackDeps(pkg: {
4135
);
4236
}
4337

44-
beforeAll(async () => {
45-
const realRead = fs.readFileSync;
46-
const spy = vi.spyOn(fs, 'readFileSync').mockImplementation(((file: unknown, ...rest: unknown[]) =>
47-
typeof file === 'string' && path.resolve(file) === CLI_MANIFEST
48-
? JSON.stringify({ name: '@objectstack/cli', version: PRERELEASE })
49-
: (realRead as (...args: unknown[]) => unknown)(file, ...rest)) as typeof fs.readFileSync);
50-
try {
51-
vi.resetModules();
52-
init = await import('../src/commands/init.js');
53-
create = await import('../src/commands/create.js');
54-
// Read while the planted manifest is in place; the value is cached after.
55-
expect(init.getCliVersion()).toBe(PRERELEASE);
56-
} finally {
57-
spy.mockRestore();
58-
}
59-
});
60-
61-
afterAll(() => {
62-
vi.resetModules();
63-
});
38+
// The first import of the command modules happens HERE, under the planted
39+
// manifest read, at collection time: each test file gets its own module
40+
// registry, so no reset is needed, and module evaluation is not charged to a
41+
// hook's timeout.
42+
const realRead = fs.readFileSync;
43+
const spy = vi.spyOn(fs, 'readFileSync').mockImplementation(((file: unknown, ...rest: unknown[]) =>
44+
typeof file === 'string' && path.resolve(file) === CLI_MANIFEST
45+
? JSON.stringify({ name: '@objectstack/cli', version: PRERELEASE })
46+
: (realRead as (...args: unknown[]) => unknown)(file, ...rest)) as typeof fs.readFileSync);
47+
let init: typeof import('../src/commands/init.js');
48+
let create: typeof import('../src/commands/create.js');
49+
let plantedVersion: string;
50+
try {
51+
init = await import('../src/commands/init.js');
52+
create = await import('../src/commands/create.js');
53+
// Read while the planted manifest is in place; the value is cached after.
54+
plantedVersion = init.getCliVersion();
55+
} finally {
56+
spy.mockRestore();
57+
}
6458

6559
describe('a prerelease CLI pins scaffolded @objectstack/* deps exactly', () => {
60+
// Harness guard: without it, a manifest read that escaped the spy would
61+
// measure the checkout's own release version and prove nothing about tails.
62+
it('reads the planted prerelease as the CLI version', () => {
63+
expect(plantedVersion).toBe(PRERELEASE);
64+
});
65+
6666
it('os init: every template, every @objectstack/* dep', () => {
6767
const keys = Object.keys(init.TEMPLATES);
6868
expect(keys.length).toBeGreaterThan(0);

0 commit comments

Comments
 (0)