Skip to content

Commit 735c768

Browse files
committed
test: add unit tests for updaters
- Added tests for DockerUpdater - Added tests for GoUpdater - Added tests for NodeUpdater - Added tests for PHPUpdater - Added tests for PythonUpdater - Added tests for RustUpdater
1 parent da44ec5 commit 735c768

7 files changed

Lines changed: 563 additions & 1 deletion

File tree

tests/services/updaterService.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, it, expect, vi, beforeEach } from 'vitest';
22
import { UpdaterService } from '../../src/services';
3-
import { Updater } from '../../src/interface';
3+
import { UpdaterInterface as Updater } from '../../src/interface';
44
import { PlatformDetectionError, VersionBumpError } from '../../src/errors';
55
import { UpdaterRegistry } from '../../src/registry/updaterRegistry';
66

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
2+
import { describe, it, expect, vi, beforeEach } from 'vitest';
3+
import { existsSync, readFileSync, writeFileSync } from 'fs';
4+
import { DockerUpdater } from '../../src/updaters/dockerUpdater';
5+
import { ReleaseType } from 'semver';
6+
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+
describe('DockerUpdater', () => {
21+
let dockerUpdater: DockerUpdater;
22+
23+
beforeEach(() => {
24+
vi.clearAllMocks();
25+
dockerUpdater = new DockerUpdater();
26+
});
27+
28+
describe('canHandle', () => {
29+
it('should return true if Dockerfile exists', () => {
30+
(existsSync as vi.Mock).mockReturnValue(true);
31+
expect(dockerUpdater.canHandle()).toBe(true);
32+
});
33+
34+
it('should return false if Dockerfile does not exist', () => {
35+
(existsSync as vi.Mock).mockReturnValue(false);
36+
expect(dockerUpdater.canHandle()).toBe(false);
37+
});
38+
});
39+
40+
describe('getCurrentVersion', () => {
41+
it('should return the version from Dockerfile', () => {
42+
(existsSync as vi.Mock).mockReturnValue(true);
43+
(readFileSync as vi.Mock).mockReturnValue('LABEL version="1.0.0"');
44+
dockerUpdater.canHandle();
45+
expect(dockerUpdater.getCurrentVersion()).toBe('1.0.0');
46+
});
47+
48+
it('should throw InvalidManifestError if version label is not found', () => {
49+
(existsSync as vi.Mock).mockReturnValue(true);
50+
(readFileSync as vi.Mock).mockReturnValue('LABEL other="value"');
51+
dockerUpdater.canHandle();
52+
expect(() => dockerUpdater.getCurrentVersion()).toThrow('Regex \'LABEL version="([^\"]+)\"\' did not find a match in Dockerfile');
53+
});
54+
});
55+
56+
describe('bumpVersion', () => {
57+
beforeEach(() => {
58+
(existsSync as vi.Mock).mockReturnValue(true);
59+
(readFileSync as vi.Mock).mockReturnValue('LABEL version="1.0.0"');
60+
dockerUpdater.canHandle();
61+
});
62+
63+
it.each(['major', 'minor', 'patch'])(
64+
'should bump the version for %s release',
65+
(releaseType) => {
66+
const newVersion = dockerUpdater.bumpVersion(releaseType as ReleaseType);
67+
expect(newVersion).not.toBe('1.0.0');
68+
expect(writeFileSync).toHaveBeenCalledWith(
69+
'Dockerfile',
70+
`LABEL version="${newVersion}"`,
71+
);
72+
},
73+
);
74+
75+
it('should throw an error if Dockerfile not found', () => {
76+
const updater = new DockerUpdater();
77+
expect(() => updater.bumpVersion('patch')).toThrow('Dockerfile not found');
78+
});
79+
});
80+
});

tests/updaters/goUpdater.test.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest';
2+
import { existsSync, readFileSync, writeFileSync } from 'fs';
3+
import { GoUpdater } from '../../src/updaters/goUpdater';
4+
import { ReleaseType } from 'semver';
5+
6+
vi.mock('fs', () => {
7+
const mockFs = {
8+
existsSync: vi.fn(),
9+
readFileSync: vi.fn(),
10+
writeFileSync: vi.fn(),
11+
};
12+
return {
13+
__esModule: true,
14+
default: mockFs,
15+
...mockFs,
16+
};
17+
});
18+
19+
describe('GoUpdater', () => {
20+
let goUpdater: GoUpdater;
21+
22+
beforeEach(() => {
23+
vi.clearAllMocks();
24+
goUpdater = new GoUpdater();
25+
});
26+
27+
describe('canHandle', () => {
28+
it('should return true if go.mod exists', () => {
29+
(existsSync as vi.Mock).mockReturnValue(true);
30+
expect(goUpdater.canHandle()).toBe(true);
31+
});
32+
33+
it('should return false if go.mod does not exist', () => {
34+
(existsSync as vi.Mock).mockReturnValue(false);
35+
expect(goUpdater.canHandle()).toBe(false);
36+
});
37+
});
38+
39+
describe('getCurrentVersion', () => {
40+
it('should return the version from go.mod', () => {
41+
(existsSync as vi.Mock).mockReturnValue(true);
42+
(readFileSync as vi.Mock).mockReturnValue('module github.com/user/repo\ngo 1.16\nmodule github.com/user/repo v1.2.3');
43+
goUpdater.canHandle();
44+
expect(goUpdater.getCurrentVersion()).toBe('1.2.3');
45+
});
46+
47+
it('should throw InvalidManifestError if version is not found', () => {
48+
(existsSync as vi.Mock).mockReturnValue(true);
49+
(readFileSync as vi.Mock).mockReturnValue('module github.com/user/repo');
50+
goUpdater.canHandle();
51+
expect(() => goUpdater.getCurrentVersion()).toThrow("Regex '^module\\s+[^\\s]+\\s+v?(\\d+\\.\\d+\\.\\d+)' did not find a match in go.mod");
52+
});
53+
});
54+
55+
describe('bumpVersion', () => {
56+
beforeEach(() => {
57+
(existsSync as vi.Mock).mockReturnValue(true);
58+
(readFileSync as vi.Mock).mockReturnValue(`module github.com/user/repo
59+
go 1.16
60+
61+
// This is a comment
62+
63+
require (
64+
github.com/some/dep v1.2.3
65+
)
66+
67+
// version v1.0.0
68+
69+
module github.com/user/repo v1.0.0`);
70+
goUpdater.canHandle();
71+
});
72+
73+
it.each(['major', 'minor', 'patch'])(
74+
'should bump the version for %s release',
75+
(releaseType) => {
76+
const newVersion = goUpdater.bumpVersion(releaseType as ReleaseType);
77+
expect(newVersion).not.toBe('1.0.0');
78+
expect(writeFileSync).toHaveBeenCalledWith(
79+
'go.mod',
80+
expect.stringContaining(`v${newVersion}`),
81+
);
82+
},
83+
);
84+
85+
it('should throw an error if go.mod not found', () => {
86+
const updater = new GoUpdater();
87+
expect(() => updater.bumpVersion('patch')).toThrow('go.mod not found');
88+
});
89+
});
90+
});

tests/updaters/nodeUpdater.test.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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+
nodeUpdater.canHandle(); // Ensure manifestPath is set
61+
(readFileSync as vi.Mock).mockReturnValueOnce(JSON.stringify({ version: '1.0.0' }));
62+
expect(nodeUpdater.getCurrentVersion()).toBe('1.0.0');
63+
expect(readFileSync).toHaveBeenCalledWith('package.json', 'utf8');
64+
});
65+
66+
it('should return null if package.json does not exist', () => {
67+
(existsSync as vi.Mock).mockReturnValue(false);
68+
expect(nodeUpdater.getCurrentVersion()).toBeNull();
69+
expect(readFileSync).not.toHaveBeenCalled();
70+
});
71+
});
72+
73+
describe('bumpVersion', () => {
74+
const mockPackageJson = { name: 'test-pkg', version: '1.0.0' };
75+
const newVersion = '1.0.1';
76+
77+
beforeEach(() => {
78+
(readFileSync as vi.Mock).mockReturnValue(JSON.stringify(mockPackageJson));
79+
(inc as vi.Mock).mockReturnValue(newVersion);
80+
});
81+
82+
it('should increment the version and write to package.json', () => {
83+
(existsSync as vi.Mock).mockReturnValue(true);
84+
nodeUpdater.canHandle();
85+
const result = nodeUpdater.bumpVersion('patch');
86+
87+
expect(inc).toHaveBeenCalledWith(mockPackageJson.version, 'patch');
88+
expect(writeFileSync).toHaveBeenCalledWith(
89+
'package.json',
90+
JSON.stringify({ ...mockPackageJson, version: newVersion }, null, 2),
91+
);
92+
expect(result).toBe(newVersion);
93+
});
94+
95+
it('should handle major release type', () => {
96+
(existsSync as vi.Mock).mockReturnValue(true);
97+
nodeUpdater.canHandle();
98+
const majorVersion = '2.0.0';
99+
(inc as vi.Mock).mockReturnValue(majorVersion);
100+
const result = nodeUpdater.bumpVersion('major');
101+
expect(inc).toHaveBeenCalledWith(mockPackageJson.version, 'major');
102+
expect(result).toBe(majorVersion);
103+
});
104+
105+
it('should handle minor release type', () => {
106+
(existsSync as vi.Mock).mockReturnValue(true);
107+
nodeUpdater.canHandle();
108+
const minorVersion = '1.1.0';
109+
(inc as vi.Mock).mockReturnValue(minorVersion);
110+
const result = nodeUpdater.bumpVersion('minor');
111+
expect(inc).toHaveBeenCalledWith(mockPackageJson.version, 'minor');
112+
expect(result).toBe(minorVersion);
113+
});
114+
});
115+
});

tests/updaters/phpUpdater.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
2+
import { describe, it, expect, vi, beforeEach } from 'vitest';
3+
import { existsSync, readFileSync, writeFileSync } from 'fs';
4+
import { PHPUpdater } from '../../src/updaters/phpUpdater';
5+
import { ReleaseType } from 'semver';
6+
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+
describe('PHPUpdater', () => {
21+
let phpUpdater: PHPUpdater;
22+
23+
beforeEach(() => {
24+
vi.clearAllMocks();
25+
phpUpdater = new PHPUpdater();
26+
});
27+
28+
describe('canHandle', () => {
29+
it.each(['composer.json', 'VERSION', 'version.php', 'config.php'])(
30+
'should return true if %s exists',
31+
(file) => {
32+
(existsSync as vi.Mock).mockImplementation((path) => path === file);
33+
expect(phpUpdater.canHandle()).toBe(true);
34+
},
35+
);
36+
37+
it('should return false if no manifest file exists', () => {
38+
(existsSync as vi.Mock).mockReturnValue(false);
39+
expect(phpUpdater.canHandle()).toBe(false);
40+
});
41+
});
42+
43+
describe('getCurrentVersion', () => {
44+
it('should get version from composer.json', () => {
45+
(existsSync as vi.Mock).mockReturnValue(true);
46+
(readFileSync as vi.Mock).mockReturnValue(JSON.stringify({ version: '1.0.0' }));
47+
phpUpdater.canHandle();
48+
expect(phpUpdater.getCurrentVersion()).toBe('1.0.0');
49+
});
50+
51+
it('should get version from VERSION file', () => {
52+
(existsSync as vi.Mock).mockImplementation((path) => path === 'VERSION');
53+
(readFileSync as vi.Mock).mockReturnValue('1.2.3');
54+
phpUpdater.canHandle();
55+
expect(phpUpdater.getCurrentVersion()).toBe('1.2.3');
56+
});
57+
});
58+
59+
describe('bumpVersion', () => {
60+
it.each(['major', 'minor', 'patch'])(
61+
'should bump composer.json version for %s release',
62+
(releaseType) => {
63+
(existsSync as vi.Mock).mockReturnValue(true);
64+
(readFileSync as vi.Mock).mockReturnValue(JSON.stringify({ version: '1.0.0' }));
65+
phpUpdater.canHandle();
66+
const newVersion = phpUpdater.bumpVersion(releaseType as ReleaseType);
67+
expect(newVersion).not.toBe('1.0.0');
68+
expect(writeFileSync).toHaveBeenCalledWith(
69+
'composer.json',
70+
JSON.stringify({ version: newVersion }, null, 2),
71+
);
72+
},
73+
);
74+
75+
it('should throw an error if manifest not found', () => {
76+
const updater = new PHPUpdater();
77+
expect(() => updater.bumpVersion('patch')).toThrow('PHP manifest file not found');
78+
});
79+
});
80+
});

0 commit comments

Comments
 (0)