Skip to content

Commit a11dd35

Browse files
committed
test: add coverage for rspack version detection helpers
1 parent 81936bb commit a11dd35

1 file changed

Lines changed: 134 additions & 0 deletions

File tree

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import fs from 'node:fs';
2+
import os from 'node:os';
3+
import path from 'node:path';
4+
import type { Compiler as RspackCompiler } from '@rspack/core';
5+
import type { Compiler as WebpackCompiler } from 'webpack';
6+
import {
7+
getRspackMajorVersion,
8+
getRspackMajorVersionFromCompiler,
9+
getRspackVersion,
10+
isRspack2,
11+
} from '../rspackVersion.js';
12+
13+
/**
14+
* Creates a fake project directory containing `node_modules/@rspack/core`
15+
* with the given version. The fake package's entrypoint throws, so any
16+
* codepath that imports `@rspack/core` (instead of only resolving its
17+
* `package.json`) fails loudly.
18+
*/
19+
function createFixtureProject(root: string, version: string): string {
20+
const projectDir = fs.mkdtempSync(path.join(root, 'project-'));
21+
const packageDir = path.join(projectDir, 'node_modules', '@rspack', 'core');
22+
fs.mkdirSync(packageDir, { recursive: true });
23+
fs.writeFileSync(
24+
path.join(packageDir, 'package.json'),
25+
JSON.stringify({ name: '@rspack/core', version, main: 'index.js' })
26+
);
27+
fs.writeFileSync(
28+
path.join(packageDir, 'index.js'),
29+
'throw new Error("@rspack/core must not be imported by version detection");'
30+
);
31+
return projectDir;
32+
}
33+
34+
describe('rspackVersion helpers', () => {
35+
let tmpRoot: string;
36+
let rspack1Project: string;
37+
let rspack2Project: string;
38+
let brokenProject: string;
39+
40+
beforeAll(() => {
41+
tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'repack-rspack-version-'));
42+
rspack1Project = createFixtureProject(tmpRoot, '1.7.0');
43+
rspack2Project = createFixtureProject(tmpRoot, '2.3.4');
44+
// simulates an unusable @rspack/core install: package.json resolves but
45+
// cannot be loaded, which exercises the same `catch -> null` branch as a
46+
// missing install (jest's `require.resolve` treats `paths` as additional
47+
// lookup paths and falls back to the workspace install, so a truly absent
48+
// package cannot be simulated in-process here)
49+
brokenProject = createFixtureProject(tmpRoot, '0.0.0');
50+
fs.writeFileSync(
51+
path.join(
52+
brokenProject,
53+
'node_modules',
54+
'@rspack',
55+
'core',
56+
'package.json'
57+
),
58+
'not-json'
59+
);
60+
});
61+
62+
afterAll(() => {
63+
fs.rmSync(tmpRoot, { recursive: true, force: true });
64+
});
65+
66+
describe('getRspackVersion', () => {
67+
it('resolves the installed @rspack/core version by default', () => {
68+
const {
69+
version: installedVersion,
70+
} = require('@rspack/core/package.json');
71+
expect(getRspackVersion()).toBe(installedVersion);
72+
});
73+
74+
it('resolves @rspack/core from the given project context', () => {
75+
expect(getRspackVersion(rspack2Project)).toBe('2.3.4');
76+
expect(getRspackVersion(rspack1Project)).toBe('1.7.0');
77+
});
78+
79+
it('does not import @rspack/core while detecting the version', () => {
80+
// the fixture package's entrypoint throws on import, so a non-null
81+
// result proves only package.json was read
82+
expect(getRspackVersion(rspack2Project)).toBe('2.3.4');
83+
});
84+
85+
it('returns null when the version cannot be read', () => {
86+
expect(getRspackVersion(brokenProject)).toBeNull();
87+
});
88+
});
89+
90+
describe('getRspackMajorVersion', () => {
91+
it('parses the major version', () => {
92+
expect(getRspackMajorVersion(rspack1Project)).toBe(1);
93+
expect(getRspackMajorVersion(rspack2Project)).toBe(2);
94+
});
95+
96+
it('returns null when the version cannot be read', () => {
97+
expect(getRspackMajorVersion(brokenProject)).toBeNull();
98+
});
99+
});
100+
101+
describe('isRspack2', () => {
102+
it('detects Rspack 2 from the given project context', () => {
103+
expect(isRspack2(rspack2Project)).toBe(true);
104+
expect(isRspack2(rspack1Project)).toBe(false);
105+
});
106+
107+
it('returns false when the version cannot be read', () => {
108+
expect(isRspack2(brokenProject)).toBe(false);
109+
});
110+
});
111+
112+
describe('getRspackMajorVersionFromCompiler', () => {
113+
it('reads the major version from an rspack compiler', () => {
114+
// minimal mock: only `webpack.rspackVersion` is accessed
115+
const compiler = {
116+
webpack: { rspackVersion: '2.1.2' },
117+
} as unknown as RspackCompiler;
118+
expect(getRspackMajorVersionFromCompiler(compiler)).toBe(2);
119+
120+
const rspack1Compiler = {
121+
webpack: { rspackVersion: '1.7.12' },
122+
} as unknown as RspackCompiler;
123+
expect(getRspackMajorVersionFromCompiler(rspack1Compiler)).toBe(1);
124+
});
125+
126+
it('returns null for a webpack compiler', () => {
127+
// minimal mock: webpack compilers expose `version`, not `rspackVersion`
128+
const compiler = {
129+
webpack: { version: '5.99.0' },
130+
} as unknown as WebpackCompiler;
131+
expect(getRspackMajorVersionFromCompiler(compiler)).toBeNull();
132+
});
133+
});
134+
});

0 commit comments

Comments
 (0)