Skip to content

Commit ad87696

Browse files
🧪 Add unit tests for dep-versions utility
🎯 What: Add unit tests to cover the functionality of the `depVersions` module which dynamically computes and resolves the version of dependencies based on the `package.json` file in the current working directory. 📊 Coverage: Added scenarios for handling a missing `package.json`, a `package.json` with no dependencies, successful versions resolutions with alphabetical sorting, skipping of non-resolvable modules without crashing, and deduplication of packages appearing in both `dependencies` and `devDependencies`. ✨ Result: `src/utils/dep-versions.ts` is now covered effectively by using temporary isolated filesystem setups and bypassing module caching, improving overall reliability. Co-authored-by: sunnylqm <615282+sunnylqm@users.noreply.github.com>
1 parent 94778d8 commit ad87696

1 file changed

Lines changed: 140 additions & 0 deletions

File tree

‎tests/dep-versions.test.ts‎

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
2+
import * as fs from 'fs';
3+
import * as os from 'os';
4+
import * as path from 'path';
5+
6+
describe('depVersions utility', () => {
7+
const originalCwd = process.cwd();
8+
let testDir: string;
9+
let testCount = 0;
10+
11+
beforeEach(() => {
12+
testCount++;
13+
testDir = path.join(os.tmpdir(), `temp-test-dep-versions-${Date.now()}-${testCount}`);
14+
fs.mkdirSync(testDir, { recursive: true });
15+
process.chdir(testDir);
16+
});
17+
18+
afterEach(() => {
19+
process.chdir(originalCwd);
20+
fs.rmSync(testDir, { recursive: true, force: true });
21+
});
22+
23+
const loadDepVersions = async () => {
24+
// Bust the module cache by appending a query string
25+
// Since the process.cwd() has changed, we need the absolute path to the module
26+
const modulePath = path.join(originalCwd, 'src', 'utils', 'dep-versions.ts');
27+
const module = await import(`${modulePath}?t=${Date.now()}_${testCount}`);
28+
return module.depVersions;
29+
};
30+
31+
test('should return an empty object if no package.json is found', async () => {
32+
// testDir has no package.json
33+
const deps = await loadDepVersions();
34+
expect(deps).toEqual({});
35+
});
36+
37+
test('should return an empty object if package.json has no dependencies or devDependencies', async () => {
38+
fs.writeFileSync(
39+
path.join(testDir, 'package.json'),
40+
JSON.stringify({ name: 'test-app' }),
41+
);
42+
43+
const deps = await loadDepVersions();
44+
expect(deps).toEqual({});
45+
});
46+
47+
test('should resolve versions for dependencies and devDependencies and sort keys', async () => {
48+
fs.writeFileSync(
49+
path.join(testDir, 'package.json'),
50+
JSON.stringify({
51+
dependencies: {
52+
zeta: '^1.0.0',
53+
alpha: '^2.0.0',
54+
},
55+
devDependencies: {
56+
beta: '^3.0.0',
57+
},
58+
}),
59+
);
60+
61+
const depsToCreate = [
62+
{ name: 'zeta', version: '1.0.5' },
63+
{ name: 'alpha', version: '2.1.0' },
64+
{ name: 'beta', version: '3.0.1' },
65+
];
66+
67+
for (const dep of depsToCreate) {
68+
const depDir = path.join(testDir, 'node_modules', dep.name);
69+
fs.mkdirSync(depDir, { recursive: true });
70+
fs.writeFileSync(
71+
path.join(depDir, 'package.json'),
72+
JSON.stringify({ version: dep.version }),
73+
);
74+
}
75+
76+
const deps = await loadDepVersions();
77+
78+
// Check that versions are resolved
79+
expect(deps).toEqual({
80+
alpha: '2.1.0',
81+
beta: '3.0.1',
82+
zeta: '1.0.5',
83+
});
84+
85+
// Check that keys are sorted alphabetically
86+
const keys = Object.keys(deps);
87+
expect(keys).toEqual(['alpha', 'beta', 'zeta']);
88+
});
89+
90+
test('should skip dependencies that cannot be resolved without throwing an error', async () => {
91+
fs.writeFileSync(
92+
path.join(testDir, 'package.json'),
93+
JSON.stringify({
94+
dependencies: {
95+
exists: '^1.0.0',
96+
missing: '^2.0.0',
97+
},
98+
}),
99+
);
100+
101+
// Only create 'exists'
102+
const existsDir = path.join(testDir, 'node_modules', 'exists');
103+
fs.mkdirSync(existsDir, { recursive: true });
104+
fs.writeFileSync(
105+
path.join(existsDir, 'package.json'),
106+
JSON.stringify({ version: '1.0.0' }),
107+
);
108+
109+
const deps = await loadDepVersions();
110+
expect(deps).toEqual({
111+
exists: '1.0.0',
112+
});
113+
});
114+
115+
test('should deduplicate dependencies appearing in both dependencies and devDependencies', async () => {
116+
fs.writeFileSync(
117+
path.join(testDir, 'package.json'),
118+
JSON.stringify({
119+
dependencies: {
120+
shared: '^1.0.0',
121+
},
122+
devDependencies: {
123+
shared: '^1.0.0',
124+
},
125+
}),
126+
);
127+
128+
const sharedDir = path.join(testDir, 'node_modules', 'shared');
129+
fs.mkdirSync(sharedDir, { recursive: true });
130+
fs.writeFileSync(
131+
path.join(sharedDir, 'package.json'),
132+
JSON.stringify({ version: '1.0.2' }),
133+
);
134+
135+
const deps = await loadDepVersions();
136+
expect(deps).toEqual({
137+
shared: '1.0.2',
138+
});
139+
});
140+
});

0 commit comments

Comments
 (0)