Skip to content

Commit f46cf10

Browse files
committed
update tests for main
1 parent 3a32a20 commit f46cf10

File tree

2 files changed

+90
-91
lines changed

2 files changed

+90
-91
lines changed

tests/main.test.js

Lines changed: 90 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,100 @@
11
import { describe, jest, test, beforeEach } from '@jest/globals';
2-
// import { mockConfig, mockCommander } from './mocks.js';
2+
import { mockConfig, easyMock, easyResolve } from './mocks.js';
33

44
// setup mocks
5-
// mockConfig();
6-
// const mockCommand = mockCommander();
7-
// jest.unstable_mockModule('src/cli/auth.js', () => ({ authCommand: jest.fn() }));
8-
// jest.unstable_mockModule('src/cli/exitOverride.js', () => ({
9-
// exitOverride: jest.fn(),
10-
// }));
11-
// jest.unstable_mockModule('src/cli/initialize.js', () => ({
12-
// initializeCommand: jest.fn(),
13-
// }));
14-
// jest.unstable_mockModule('src/cli/solve.js', () => ({ solveCommand: jest.fn() }));
15-
// jest.unstable_mockModule('src/cli/stats.js', () => ({ statsCommand: jest.fn() }));
16-
// jest.unstable_mockModule('src/cli/submit.js', () => ({ submitCommand: jest.fn() }));
17-
// jest.unstable_mockModule('src/errorHandler.js', () => ({ handleError: jest.fn() }));
18-
// jest.unstable_mockModule('src/festive.js', () => ({ printFestiveTitle: jest.fn() }));
5+
const easyMocks = [
6+
['src/commands/auth.js', ['authAction']],
7+
['src/commands/init.js', ['initAction']],
8+
['src/commands/solve.js', ['solveAction']],
9+
['src/commands/stats.js', ['statsAction']],
10+
['src/commands/submit.js', ['submitAction']],
11+
['src/errorHandler.js', ['handleError']],
12+
['src/festive.js', ['printFestiveTitle']],
13+
];
14+
easyMock(easyMocks);
15+
mockConfig();
16+
const mockCommander = (() => {
17+
class InvalidArgumentError extends Error {
18+
constructor(message) {
19+
super(message);
20+
this.name = 'InvalidArgumentError';
21+
}
22+
}
23+
const toReturn = {
24+
name: jest.fn().mockReturnThis(),
25+
description: jest.fn().mockReturnThis(),
26+
version: jest.fn().mockReturnThis(),
27+
addHelpText: jest.fn().mockReturnThis(),
28+
command: jest.fn().mockReturnThis(),
29+
hook: jest.fn().mockReturnThis(),
30+
action: jest.fn().mockReturnThis(),
31+
addArgument: jest.fn().mockReturnThis(),
32+
option: jest.fn().mockReturnThis(),
33+
parseAsync: jest.fn(),
34+
};
35+
jest.unstable_mockModule('commander', () => ({
36+
// eslint-disable-next-line func-names, object-shorthand
37+
Command: function () {
38+
return toReturn;
39+
},
40+
// eslint-disable-next-line func-names, object-shorthand
41+
Argument: function () {
42+
return {
43+
argParser: jest.fn().mockReturnThis(),
44+
};
45+
},
46+
InvalidArgumentError,
47+
}));
48+
return toReturn;
49+
})();
1950

20-
// const commands = [
21-
// { path: '../src/cli/auth.js', fnName: 'authCommand' },
22-
// { path: '../src/cli/initialize.js', fnName: 'initializeCommand' },
23-
// { path: '../src/cli/solve.js', fnName: 'solveCommand' },
24-
// { path: '../src/cli/submit.js', fnName: 'submitCommand' },
25-
// { path: '../src/cli/stats.js', fnName: 'statsCommand' },
26-
// ];
51+
// import after mocks set up
52+
const {
53+
authAction,
54+
initAction,
55+
solveAction,
56+
statsAction,
57+
submitAction,
58+
handleError,
59+
} = await easyResolve(easyMocks);
2760

2861
describe('main', () => {
29-
test.todo('fix main tests after refactor');
30-
// beforeEach(() => {
31-
// jest.resetModules();
32-
// jest.clearAllMocks();
33-
// });
62+
beforeEach(() => {
63+
jest.clearAllMocks();
64+
});
3465

35-
// test.each(commands)('adds "$fnName" command', async ({ path, fnName }) => {
36-
// const module = await import(path);
37-
// await import('../src/main.js');
38-
// const calls = mockCommand.addCommand.mock.calls.flat();
39-
// expect(calls).toContain(module[fnName]);
40-
// });
66+
test.each([
67+
['auth', authAction],
68+
['init', initAction],
69+
['solve', solveAction],
70+
['submit', submitAction],
71+
['stats', statsAction],
72+
])('adds command %s', async (name, action) =>
73+
jest.isolateModulesAsync(async () => {
74+
await import('../src/main.js');
75+
const commandIndex = mockCommander.command.mock.calls
76+
.flat()
77+
.indexOf(name);
78+
const actionIndex = mockCommander.action.mock.calls
79+
.flat()
80+
.indexOf(action);
81+
expect(commandIndex).not.toBe(-1);
82+
expect(actionIndex).not.toBe(-1);
83+
expect(commandIndex).toBe(actionIndex);
84+
})
85+
);
4186

42-
// test('loads correct number of commands', async () => {
43-
// // test is brittle on purpose, ensures if a new command is added in main
44-
// // that this test suite must be updated with the new command too.
45-
// await import('../src/main.js');
46-
// expect(mockCommand.addCommand).toHaveBeenCalledTimes(commands.length);
47-
// });
87+
test('invokes the CLI', async () =>
88+
jest.isolateModulesAsync(async () => {
89+
await import('../src/main.js');
90+
expect(mockCommander.parseAsync).toHaveBeenCalledTimes(1);
91+
}));
4892

49-
// test('invokes the CLI', async () => {
50-
// await import('../src/main.js');
51-
// expect(mockCommand.parseAsync).toHaveBeenCalledTimes(1);
52-
// });
53-
54-
// test('handles error if CLI throws', async () => {
55-
// const { handleError } = await import('../src/errorHandler.js');
56-
// const error = new RangeError('WRONG');
57-
// mockCommand.parseAsync.mockImplementationOnce(async () => {
58-
// throw error;
59-
// });
60-
// await import('../src/main.js');
61-
// expect(handleError).toHaveBeenCalledTimes(1);
62-
// expect(handleError).toHaveBeenCalledWith(error);
63-
// });
93+
test('invokes errorHandler on exception', async () =>
94+
jest.isolateModulesAsync(async () => {
95+
const error = new Error('BAD');
96+
mockCommander.parseAsync.mockRejectedValue(error);
97+
await import('../src/main.js');
98+
expect(handleError).toHaveBeenCalledWith(error);
99+
}));
64100
});

tests/mocks.js

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,43 +33,6 @@ export const mockConfig = () => {
3333
return toReturn;
3434
};
3535

36-
/**
37-
* Mocks the Commander module and all of the commonly used functions.
38-
*/
39-
export const mockCommander = () => {
40-
class InvalidArgumentError extends Error {
41-
constructor(message) {
42-
super(message);
43-
this.name = 'InvalidArgumentError';
44-
}
45-
}
46-
const toReturn = {
47-
name: jest.fn().mockReturnThis(),
48-
description: jest.fn().mockReturnThis(),
49-
version: jest.fn().mockReturnThis(),
50-
addHelpText: jest.fn().mockReturnThis(),
51-
addCommand: jest.fn().mockReturnThis(),
52-
exitOverride: jest.fn().mockReturnThis(),
53-
hook: jest.fn().mockReturnThis(),
54-
action: jest.fn().mockReturnThis(),
55-
parseAsync: jest.fn(),
56-
};
57-
jest.unstable_mockModule('commander', () => ({
58-
// eslint-disable-next-line func-names, object-shorthand
59-
Command: function () {
60-
return toReturn;
61-
},
62-
// eslint-disable-next-line func-names, object-shorthand
63-
Argument: function () {
64-
return {
65-
argParser: jest.fn().mockReturnThis(),
66-
};
67-
},
68-
InvalidArgumentError,
69-
}));
70-
return toReturn;
71-
};
72-
7336
/**
7437
* Sets up mocks for all of the modules
7538
*/

0 commit comments

Comments
 (0)