Skip to content

Commit 21812bd

Browse files
committed
test: make the bin-only doctor fixture actually bin-only
The workspace fixture builder wrote an index.js for every package, so the bin-only case had no main and no exports but did have an entry file to fall back to. require.resolve('<dep>') therefore succeeded and the case stopped pinning the resolve ORDER it exists to pin: swapping the two attempts left it green. Write an entry file only for a manifest that declares main or exports. Verified by the swap: entry-first ordering now reds the bin-only case.
1 parent c9730b2 commit 21812bd

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

test/cli/doctor.test.mjs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,23 +231,30 @@ test('version check PASSES when installed satisfies the declared range', async (
231231
// openly contradicted each other before this).
232232
//
233233
// COUNTERFACTUAL: restore the `join(appDir, 'node_modules', dep, 'package.json')`
234-
// read and the three fixtures below all red with "N @webjsdev/* dependency not
234+
// read and all six fixtures below red with "N @webjsdev/* dependency not
235235
// installed", which is the measured before-state on examples/blog and website.
236236
// ---------------------------------------------------------------------------
237237

238238
/**
239239
* A workspace-shaped tree: deps installed ONLY in the root node_modules, plus an
240240
* app subdirectory with its own package.json and no node_modules of its own.
241241
* Returns the app dir.
242+
*
243+
* An entry file is written ONLY for a manifest that declares `main` or
244+
* `exports`, so a bin-only manifest models a real bin-only package. Writing one
245+
* unconditionally would be the difference between a fixture and a prop: CJS
246+
* resolution falls back to `index.js`, so `require.resolve('<dep>')` would
247+
* succeed for a package with no main entry and the bin-only case would stop
248+
* pinning the resolve ORDER it exists to pin.
242249
*/
243250
function workspaceFixture(installs, ranges) {
244251
const root = tmpDir();
245252
write(root, 'package.json', JSON.stringify({ name: 'root', workspaces: ['apps/*'] }));
246253
for (const [name, manifest] of Object.entries(installs)) {
247254
write(root, `node_modules/${name}/package.json`, JSON.stringify(manifest));
248-
// Every fixture package carries a real entry file, so the exports-map
249-
// fallback has something to resolve.
250-
write(root, `node_modules/${name}/index.js`, 'export const x = 1;\n');
255+
if (manifest.main || manifest.exports) {
256+
write(root, `node_modules/${name}/index.js`, 'export const x = 1;\n');
257+
}
251258
}
252259
write(root, 'apps/web/package.json', JSON.stringify({ name: 'web', dependencies: ranges }));
253260
return join(root, 'apps/web');
@@ -269,8 +276,9 @@ test('version check PASSES for a workspace app whose deps hoist to the root node
269276

270277
test('version check resolves a BIN-ONLY package (no main, no exports), like @webjsdev/cli', async () => {
271278
// require.resolve('<dep>') throws MODULE_NOT_FOUND for a package with no main
272-
// entry, which is why the direct `<dep>/package.json` resolve is attempted
273-
// FIRST rather than as a fallback.
279+
// entry and no index.js to fall back to, which is why the direct
280+
// `<dep>/package.json` resolve is attempted FIRST rather than as a fallback.
281+
// Reorder the two attempts in readInstalledVersion and this case reds.
274282
const appDir = workspaceFixture(
275283
{ '@webjsdev/cli': { name: '@webjsdev/cli', version: '0.10.52', bin: { webjs: 'bin/webjs.js' } } },
276284
{ '@webjsdev/cli': '^0.10.0' }

0 commit comments

Comments
 (0)