-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
test: add unit tests for scripts/compose.ts #5685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,104 @@ | ||||||||||||||||||||||||||||
| import { logger } from '../scripts/helpers/logger'; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| jest.mock('inquirer', () => ({ | ||||||||||||||||||||||||||||
| prompt: jest.fn() | ||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| jest.mock('fs', () => ({ | ||||||||||||||||||||||||||||
| writeFile: jest.fn() | ||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| jest.mock('dayjs', () => { | ||||||||||||||||||||||||||||
| const dayjsMock = jest.fn(() => ({ | ||||||||||||||||||||||||||||
| format: jest.fn(() => '2021-05-01T10:00:00+02:00') | ||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||
| return dayjsMock; | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Fix the padding lint errors in the Day.js mock. Add a blank line after the Proposed fix const dayjsMock = jest.fn(() => ({
format: jest.fn(() => '2021-05-01T10:00:00+02:00')
}));
+
return dayjsMock;📝 Committable suggestion
Suggested change
🧰 Tools🪛 ESLint[error] 12-14: Expected blank line after variable declarations. (newline-after-var) [error] 15-15: Expected blank line before this statement. (padding-line-between-statements) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| jest.mock('../scripts/helpers/logger', () => ({ | ||||||||||||||||||||||||||||
| logger: { | ||||||||||||||||||||||||||||
| info: jest.fn(), | ||||||||||||||||||||||||||||
| error: jest.fn() | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const flushPromises = () => new Promise((resolve) => setImmediate(resolve)); | ||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Use a block-bodied promise executor. The expression-bodied executor returns the Proposed fix-const flushPromises = () => new Promise((resolve) => setImmediate(resolve));
+const flushPromises = () =>
+ new Promise<void>((resolve) => {
+ setImmediate(resolve);
+ });📝 Committable suggestion
Suggested change
🧰 Tools🪛 ESLint[error] 25-25: Return values from promise executor functions cannot be read. (no-promise-executor-return) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| describe('compose script', () => { | ||||||||||||||||||||||||||||
| const defaultAnswers = { | ||||||||||||||||||||||||||||
| title: 'My First Blog Post!', | ||||||||||||||||||||||||||||
| excerpt: 'A test excerpt for the blog post.', | ||||||||||||||||||||||||||||
| tags: 'asyncapi, tutorial', | ||||||||||||||||||||||||||||
| type: 'Engineering', | ||||||||||||||||||||||||||||
| canonical: 'https://example.com' | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| let promptMock: jest.Mock; | ||||||||||||||||||||||||||||
| let writeFileMock: jest.Mock; | ||||||||||||||||||||||||||||
| let loggerInfoMock: jest.Mock; | ||||||||||||||||||||||||||||
| let loggerErrorMock: jest.Mock; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| beforeEach(() => { | ||||||||||||||||||||||||||||
| jest.resetModules(); | ||||||||||||||||||||||||||||
| jest.clearAllMocks(); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||||||||||||||||||||||||||||
| promptMock = require('inquirer').prompt; | ||||||||||||||||||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||||||||||||||||||||||||||||
| writeFileMock = require('fs').writeFile; | ||||||||||||||||||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||||||||||||||||||||||||||||
| loggerInfoMock = require('../scripts/helpers/logger').logger.info; | ||||||||||||||||||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||||||||||||||||||||||||||||
| loggerErrorMock = require('../scripts/helpers/logger').logger.error; | ||||||||||||||||||||||||||||
|
Comment on lines
+45
to
+52
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Fix the ESLint suppression for dynamic mock access. The directives suppress only Proposed fix- // eslint-disable-next-line `@typescript-eslint/no-var-requires`
+ // eslint-disable-next-line `@typescript-eslint/no-var-requires`, global-requireApply this change to each affected Also applies to: 59-60, 84-85, 96-97 🧰 Tools🪛 ESLint[error] 46-46: Unexpected require(). (global-require) [error] 48-48: Unexpected require(). (global-require) [error] 50-50: Unexpected require(). (global-require) [error] 52-52: Unexpected require(). (global-require) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| it('generates the blog post file with front matter for the happy path', async () => { | ||||||||||||||||||||||||||||
| promptMock.mockResolvedValue(defaultAnswers); | ||||||||||||||||||||||||||||
| writeFileMock.mockImplementation((_filePath, _content, _options, callback) => callback(null)); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||||||||||||||||||||||||||||
| require('../scripts/compose'); | ||||||||||||||||||||||||||||
| await flushPromises(); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| expect(writeFileMock).toHaveBeenCalledTimes(1); | ||||||||||||||||||||||||||||
| const [filePath, content, options] = writeFileMock.mock.calls[0]; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| expect(filePath).toBe('pages/blog/my-first-blog-post.md'); | ||||||||||||||||||||||||||||
| expect(options).toEqual({ flag: 'wx' }); | ||||||||||||||||||||||||||||
| expect(content).toContain('title: My First Blog Post!'); | ||||||||||||||||||||||||||||
| expect(content).toContain("tags: ['asyncapi','tutorial']"); | ||||||||||||||||||||||||||||
| expect(content).toContain('date: 2021-05-01T10:00:00+02:00'); | ||||||||||||||||||||||||||||
| expect(content).toContain('canonical: https://example.com'); | ||||||||||||||||||||||||||||
| expect(loggerInfoMock).toHaveBeenCalledWith('Blog post generated successfully at pages/blog/my-first-blog-post.md'); | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| it.each([ | ||||||||||||||||||||||||||||
| ['Hello World??', 'pages/blog/hello-world.md'], | ||||||||||||||||||||||||||||
| ['My-Second_Post (v2)', 'pages/blog/mysecondpost-v2.md'], | ||||||||||||||||||||||||||||
| ['', 'pages/blog/untitled.md'], | ||||||||||||||||||||||||||||
| ['!!!', 'pages/blog/untitled.md'] | ||||||||||||||||||||||||||||
| ])('slugifies the title "%s" into the file path "%s"', async (title, expectedPath) => { | ||||||||||||||||||||||||||||
| promptMock.mockResolvedValue({ ...defaultAnswers, title }); | ||||||||||||||||||||||||||||
| writeFileMock.mockImplementation((_filePath, _content, _options, callback) => callback(null)); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||||||||||||||||||||||||||||
| require('../scripts/compose'); | ||||||||||||||||||||||||||||
| await flushPromises(); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| expect(writeFileMock).toHaveBeenCalledTimes(1); | ||||||||||||||||||||||||||||
| expect(writeFileMock.mock.calls[0][0]).toBe(expectedPath); | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| it('logs an error when the file cannot be written', async () => { | ||||||||||||||||||||||||||||
| promptMock.mockResolvedValue(defaultAnswers); | ||||||||||||||||||||||||||||
| writeFileMock.mockImplementation((_filePath, _content, _options, callback) => callback(new Error('EEXIST'))); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
Comment on lines
+92
to
+95
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 12 'fs\.writeFile|throw err|logger\.error|\.catch' scripts/compose.ts
rg -n -C 6 'writeFileMock|callback\(new Error|flushPromises' tests/compose.test.tsRepository: asyncapi/website Length of output: 4485 🏁 Script executed: #!/bin/bash
set -euo pipefail
node - <<'JS'
function flushPromises() {
return new Promise((resolve) => setImmediate(resolve));
}
let caught = false;
const actualCallback = () => {
setTimeout(() => {
throw new Error('EEXIST');
}, 0);
};
Promise.resolve().then(() => {
actualCallback();
return flushPromises();
}).catch(() => {
caught = true;
});
flushPromises()
.then(() => {
const resolvedBeforeLaterCallback = !caught;
return flushPromises();
})
.then(() => {
console.log(JSON.stringify({ caughtWhenCallbackRunsLater: caught }));
});
JSRepository: asyncapi/website Length of output: 384 Make the write-error mock match
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||||||||||||||||||||||||||||
| require('../scripts/compose'); | ||||||||||||||||||||||||||||
| await flushPromises(); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| expect(loggerErrorMock).toHaveBeenCalled(); | ||||||||||||||||||||||||||||
| const errorArg = loggerErrorMock.mock.calls.find((call) => call[0] instanceof Error)?.[0] as Error; | ||||||||||||||||||||||||||||
| expect(errorArg.message).toBe('EEXIST'); | ||||||||||||||||||||||||||||
|
Comment on lines
+101
to
+102
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Add the blank line required after ESLint reports missing padding before the following assertion. Proposed fix const errorArg = loggerErrorMock.mock.calls.find((call) => call[0] instanceof Error)?.[0] as Error;
+
expect(errorArg.message).toBe('EEXIST');📝 Committable suggestion
Suggested change
🧰 Tools🪛 ESLint[error] 101-101: Expected blank line after variable declarations. (newline-after-var) [error] 102-102: Expected blank line before this statement. (padding-line-between-statements) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove the unused
loggerimport.The test accesses the mocked logger through the module lookup on Lines 50-52. The top-level import has no consumer and triggers the reported unused-import rules.
Proposed fix
-import { logger } from '../scripts/helpers/logger';📝 Committable suggestion
🧰 Tools
🪛 ESLint
[error] 1-1: 'logger' is defined but never used. Allowed unused vars must match /^_/u.
(no-unused-vars)
[error] 1-1: 'logger' is defined but never used.
(
@typescript-eslint/no-unused-vars)[error] 1-1: 'logger' is defined but never used.
(unused-imports/no-unused-imports)
🤖 Prompt for AI Agents
Source: Linters/SAST tools