Skip to content

Commit 32ee36f

Browse files
chrfalchclaude
andcommitted
Trim the subpath-resolution test
Drop the helper functions and the long explanatory comment; the scan and the subprocess check (the part Jest's moduleNameMapper would otherwise defeat) collapse into two statements. 70 lines -> 43. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 08e62f9 commit 32ee36f

1 file changed

Lines changed: 22 additions & 53 deletions

File tree

packages/community-cli-plugin/src/commands/__tests__/reactNativeSubpathResolution-test.js

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,60 +15,29 @@ const path = require('node:path');
1515
const COMMANDS_DIR = path.join(__dirname, '..');
1616
const REPO_ROOT = path.resolve(__dirname, '../../../../..');
1717

18-
/**
19-
* The command wrappers reach into the `react-native` package with
20-
* `require.resolve('react-native/...')`. Those specifiers go through
21-
* react-native's `exports` map, which — unlike legacy CJS resolution — neither
22-
* appends extensions nor falls back to a directory's `index.js`. A specifier
23-
* missing either therefore throws, but only at runtime when the command is
24-
* invoked.
25-
*
26-
* Resolution must be checked in a real `node` process: Jest's `moduleNameMapper`
27-
* remaps `react-native` to the source tree and bypasses the `exports` map
28-
* entirely, so resolving in-band here would pass even when production fails.
29-
*/
30-
function collectReactNativeSpecifiers(): Array<{file: string, spec: string}> {
31-
const found = [];
32-
for (const name of fs.readdirSync(COMMANDS_DIR)) {
33-
if (!name.endsWith('.js')) {
34-
continue;
35-
}
36-
const filePath = path.join(COMMANDS_DIR, name);
37-
if (!fs.statSync(filePath).isFile()) {
38-
continue;
39-
}
40-
const source = fs.readFileSync(filePath, 'utf8');
41-
for (const match of source.matchAll(/'(react-native\/[^']+)'/g)) {
42-
found.push({file: name, spec: match[1]});
43-
}
44-
}
45-
return found;
46-
}
47-
48-
function resolvesInNode(spec: string): boolean {
49-
try {
50-
execFileSync(
51-
process.execPath,
52-
['-e', `require.resolve(${JSON.stringify(spec)})`],
53-
{cwd: REPO_ROOT, stdio: 'ignore'},
54-
);
55-
return true;
56-
} catch {
57-
return false;
58-
}
59-
}
60-
61-
describe('react-native subpath specifiers used by the command wrappers', () => {
62-
const specifiers = collectReactNativeSpecifiers();
18+
// The wrappers load scripts as `react-native/<subpath>`, resolved through
19+
// react-native's `exports` map: no extension guessing, no index.js fallback.
20+
// Must run in a real node process — Jest's moduleNameMapper bypasses `exports`
21+
// and would pass either way.
22+
const specifiers = fs
23+
.readdirSync(COMMANDS_DIR)
24+
.filter(name => name.endsWith('.js'))
25+
.flatMap(name =>
26+
[
27+
...fs
28+
.readFileSync(path.join(COMMANDS_DIR, name), 'utf8')
29+
.matchAll(/'(react-native\/[^']+)'/g),
30+
].map(match => ({file: name, spec: match[1]})),
31+
);
6332

64-
test('at least one specifier is covered by this test', () => {
65-
expect(specifiers.length).toBeGreaterThan(0);
66-
});
33+
test('found specifiers to check', () => {
34+
expect(specifiers.length).toBeGreaterThan(0);
35+
});
6736

68-
test.each(specifiers)(
69-
"$file resolves $spec through react-native's exports map",
70-
({spec}) => {
71-
expect(resolvesInNode(spec)).toBe(true);
72-
},
37+
test.each(specifiers)('$file resolves $spec', ({spec}) => {
38+
execFileSync(
39+
process.execPath,
40+
['-e', `require.resolve(${JSON.stringify(spec)})`],
41+
{cwd: REPO_ROOT, stdio: 'ignore'},
7342
);
7443
});

0 commit comments

Comments
 (0)