Skip to content

Commit c66a174

Browse files
committed
test: add unit tests for NodeUpdater and updaterUtil
1 parent d015b30 commit c66a174

2 files changed

Lines changed: 240 additions & 0 deletions

File tree

tests/nodeUpdater.test.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest';
2+
3+
import { existsSync, readFileSync, writeFileSync } from 'fs';
4+
import { inc } from 'semver';
5+
6+
// Mock the fs module
7+
vi.mock('fs', () => {
8+
const mockFs = {
9+
existsSync: vi.fn(),
10+
readFileSync: vi.fn(),
11+
writeFileSync: vi.fn(),
12+
};
13+
return {
14+
__esModule: true,
15+
default: mockFs,
16+
...mockFs,
17+
};
18+
});
19+
20+
// Mock the semver module
21+
vi.mock('semver', () => {
22+
const mockInc = vi.fn();
23+
return {
24+
__esModule: true,
25+
default: {
26+
inc: mockInc,
27+
},
28+
inc: mockInc,
29+
};
30+
});
31+
32+
import { NodeUpdater } from '../src/updaters/nodeUpdater';
33+
34+
describe('NodeUpdater', () => {
35+
let nodeUpdater: NodeUpdater;
36+
37+
beforeEach(() => {
38+
nodeUpdater = new NodeUpdater();
39+
// Reset mocks before each test
40+
vi.clearAllMocks();
41+
});
42+
43+
describe('canHandle', () => {
44+
it('should return true if package.json exists', () => {
45+
(existsSync as vi.Mock).mockReturnValue(true);
46+
expect(nodeUpdater.canHandle()).toBe(true);
47+
expect(existsSync).toHaveBeenCalledWith('package.json');
48+
});
49+
50+
it('should return false if package.json does not exist', () => {
51+
(existsSync as vi.Mock).mockReturnValue(false);
52+
expect(nodeUpdater.canHandle()).toBe(false);
53+
expect(existsSync).toHaveBeenCalledWith('package.json');
54+
});
55+
});
56+
57+
describe('getCurrentVersion', () => {
58+
it('should return the version from package.json if it exists', () => {
59+
(existsSync as vi.Mock).mockReturnValue(true);
60+
(readFileSync as vi.Mock).mockReturnValueOnce(JSON.stringify({ version: '1.0.0' }));
61+
expect(nodeUpdater.getCurrentVersion()).toBe('1.0.0');
62+
expect(readFileSync).toHaveBeenCalledWith('package.json', 'utf8');
63+
});
64+
65+
it('should return null if package.json does not exist', () => {
66+
(existsSync as vi.Mock).mockReturnValue(false);
67+
expect(nodeUpdater.getCurrentVersion()).toBeNull();
68+
expect(readFileSync).not.toHaveBeenCalled();
69+
});
70+
});
71+
72+
describe('bumpVersion', () => {
73+
const mockPackageJson = { name: 'test-pkg', version: '1.0.0' };
74+
const newVersion = '1.0.1';
75+
76+
beforeEach(() => {
77+
(readFileSync as vi.Mock).mockReturnValue(JSON.stringify(mockPackageJson));
78+
(inc as vi.Mock).mockReturnValue(newVersion);
79+
});
80+
81+
it('should increment the version and write to package.json', () => {
82+
const result = nodeUpdater.bumpVersion('patch');
83+
84+
expect(inc).toHaveBeenCalledWith(mockPackageJson.version, 'patch');
85+
expect(writeFileSync).toHaveBeenCalledWith(
86+
'package.json',
87+
JSON.stringify({ ...mockPackageJson, version: newVersion }, null, 2),
88+
);
89+
expect(result).toBe(newVersion);
90+
});
91+
92+
it('should handle major release type', () => {
93+
const majorVersion = '2.0.0';
94+
(inc as vi.Mock).mockReturnValue(majorVersion);
95+
const result = nodeUpdater.bumpVersion('major');
96+
expect(inc).toHaveBeenCalledWith(mockPackageJson.version, 'major');
97+
expect(result).toBe(majorVersion);
98+
});
99+
100+
it('should handle minor release type', () => {
101+
const minorVersion = '1.1.0';
102+
(inc as vi.Mock).mockReturnValue(minorVersion);
103+
const result = nodeUpdater.bumpVersion('minor');
104+
expect(inc).toHaveBeenCalledWith(mockPackageJson.version, 'minor');
105+
expect(result).toBe(minorVersion);
106+
});
107+
});
108+
});

tests/updaterUtil.test.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest';
2+
import { Updater } from '../src/interface';
3+
4+
// Define the mock updater instances
5+
const mockNodeUpdater: Updater = {
6+
platform: 'node',
7+
canHandle: vi.fn(),
8+
getCurrentVersion: vi.fn(),
9+
bumpVersion: vi.fn(),
10+
};
11+
12+
const mockPythonUpdater: Updater = {
13+
platform: 'python',
14+
canHandle: vi.fn(),
15+
getCurrentVersion: vi.fn(),
16+
bumpVersion: vi.fn(),
17+
};
18+
19+
const mockRustUpdater: Updater = {
20+
platform: 'rust',
21+
canHandle: vi.fn(),
22+
getCurrentVersion: vi.fn(),
23+
bumpVersion: vi.fn(),
24+
};
25+
26+
const mockGoUpdater: Updater = {
27+
platform: 'go',
28+
canHandle: vi.fn(),
29+
getCurrentVersion: vi.fn(),
30+
bumpVersion: vi.fn(),
31+
};
32+
33+
const mockDockerUpdater: Updater = {
34+
platform: 'docker',
35+
canHandle: vi.fn(),
36+
getCurrentVersion: vi.fn(),
37+
bumpVersion: vi.fn(),
38+
};
39+
40+
const mockPHPUpdater: Updater = {
41+
platform: 'php',
42+
canHandle: vi.fn(),
43+
getCurrentVersion: vi.fn(),
44+
bumpVersion: vi.fn(),
45+
};
46+
47+
// Mock the internal updaters array in updaterUtil.ts
48+
vi.doMock('../src/updaters', () => ({
49+
NodeUpdater: vi.fn(() => mockNodeUpdater),
50+
PythonUpdater: vi.fn(() => mockPythonUpdater),
51+
RustUpdater: vi.fn(() => mockRustUpdater),
52+
GoUpdater: vi.fn(() => mockGoUpdater),
53+
DockerUpdater: vi.fn(() => mockDockerUpdater),
54+
PHPUpdater: vi.fn(() => mockPHPUpdater),
55+
}));
56+
57+
// Import the module under test AFTER the mocks are defined
58+
// This import needs to be dynamic to ensure it's loaded after mocks are applied
59+
let detectPlatform: unknown;
60+
let updateVersion: unknown;
61+
62+
describe('updaterUtil', () => {
63+
beforeEach(async () => {
64+
vi.resetModules(); // Reset modules to ensure fresh imports after mocks
65+
// Dynamically import the module under test after mocks are set up
66+
const module = await import('../src/utils/updaterUtil');
67+
detectPlatform = module.detectPlatform;
68+
updateVersion = module.updateVersion;
69+
70+
vi.clearAllMocks();
71+
// Reset mock implementations for each test
72+
mockNodeUpdater.canHandle.mockReset();
73+
mockNodeUpdater.bumpVersion.mockReset();
74+
mockPythonUpdater.canHandle.mockReset();
75+
mockPythonUpdater.bumpVersion.mockReset();
76+
mockRustUpdater.canHandle.mockReset();
77+
mockRustUpdater.bumpVersion.mockReset();
78+
mockGoUpdater.canHandle.mockReset();
79+
mockGoUpdater.bumpVersion.mockReset();
80+
mockDockerUpdater.canHandle.mockReset();
81+
mockDockerUpdater.bumpVersion.mockReset();
82+
mockPHPUpdater.canHandle.mockReset();
83+
mockPHPUpdater.bumpVersion.mockReset();
84+
});
85+
86+
describe('detectPlatform', () => {
87+
it('should return the platform of the first updater that can handle', () => {
88+
mockNodeUpdater.canHandle.mockReturnValue(false);
89+
mockPythonUpdater.canHandle.mockReturnValue(true);
90+
mockRustUpdater.canHandle.mockReturnValue(false);
91+
mockGoUpdater.canHandle.mockReturnValue(false);
92+
mockDockerUpdater.canHandle.mockReturnValue(false);
93+
mockPHPUpdater.canHandle.mockReturnValue(false);
94+
95+
expect(detectPlatform()).toBe('python');
96+
expect(mockNodeUpdater.canHandle).toHaveBeenCalled();
97+
expect(mockPythonUpdater.canHandle).toHaveBeenCalled();
98+
});
99+
100+
it('should return "unknown" if no updater can handle', () => {
101+
mockNodeUpdater.canHandle.mockReturnValue(false);
102+
mockPythonUpdater.canHandle.mockReturnValue(false);
103+
mockRustUpdater.canHandle.mockReturnValue(false);
104+
mockGoUpdater.canHandle.mockReturnValue(false);
105+
mockDockerUpdater.canHandle.mockReturnValue(false);
106+
mockPHPUpdater.canHandle.mockReturnValue(false);
107+
108+
expect(detectPlatform()).toBe('unknown');
109+
expect(mockNodeUpdater.canHandle).toHaveBeenCalled();
110+
expect(mockPythonUpdater.canHandle).toHaveBeenCalled();
111+
});
112+
});
113+
114+
describe('updateVersion', () => {
115+
it('should call bumpVersion on the correct updater and return the new version', () => {
116+
const newVersion = '1.2.4';
117+
mockNodeUpdater.bumpVersion.mockReturnValue(newVersion);
118+
119+
const result = updateVersion('node', 'patch');
120+
121+
expect(result).toBe(newVersion);
122+
expect(mockNodeUpdater.bumpVersion).toHaveBeenCalledWith('patch');
123+
expect(mockPythonUpdater.bumpVersion).not.toHaveBeenCalled();
124+
});
125+
126+
it('should throw an error if no updater is found for the platform', () => {
127+
expect(() => updateVersion('nonexistent', 'patch')).toThrowError(
128+
'No updater found for platform: nonexistent',
129+
);
130+
});
131+
});
132+
});

0 commit comments

Comments
 (0)