Skip to content

Commit ea368fa

Browse files
🧪 Add unit tests for dep-versions utility (#55)
* 🧪 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> * 🧪 Add unit tests for dep-versions utility and fix CI 🎯 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, spying on CWD, and dynamically cache-busting modules using query parameters. This also resolves the recent CI failure. Co-authored-by: sunnylqm <615282+sunnylqm@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: sunnylqm <615282+sunnylqm@users.noreply.github.com>
1 parent 3b9bdd5 commit ea368fa

1 file changed

Lines changed: 152 additions & 0 deletions

File tree

‎tests/dep-versions.test.ts‎

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

0 commit comments

Comments
 (0)