From 5a90f492ab36e47b8bfb7d2514d56d0221db63be Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 13:55:54 +0530 Subject: [PATCH 01/32] initial setup --- scripts/markdown/check-markdown.js | 2 + tests/markdown/check-markdown.test.js | 270 ++++++++++++++++++++++++++ 2 files changed, 272 insertions(+) create mode 100644 tests/markdown/check-markdown.test.js diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 8979f7e0b4ab..0ff2f15eb255 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -144,3 +144,5 @@ const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); checkMarkdownFiles(docsFolderPath, validateDocs); checkMarkdownFiles(blogsFolderPath, validateBlogs); + +module.exports = { isValidURL, validateBlogs, validateDocs, checkMarkdownFiles,} diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js new file mode 100644 index 000000000000..9c5e924935dd --- /dev/null +++ b/tests/markdown/check-markdown.test.js @@ -0,0 +1,270 @@ +const fs = require('fs'); +const path = require('path'); +const os = require('os'); +const { + isValidURL, + validateBlogs, + validateDocs, + checkMarkdownFiles +} = require('../../scripts/markdown/check-markdown'); + +describe('Frontmatter Validator', () => { + let tempDir; + let mockConsoleError; + + beforeEach(done => { + mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); + fs.mkdtemp(path.join(os.tmpdir(), 'frontmatter-test-'), (err, directory) => { + if (err) throw err; + tempDir = directory; + done(); + }); + }); + + afterEach(done => { + mockConsoleError.mockRestore(); + fs.rm(tempDir, { recursive: true, force: true }, err => { + if (err) throw err; + done(); + }); + }); + + it('should return true for valid URLs', () => { + expect(isValidURL('https://example.com')).toBe(true); + expect(isValidURL('http://localhost:3000')).toBe(true); + expect(isValidURL('https://sub.domain.com/path?query=value')).toBe(true); + }); + + it('should return false for invalid URLs', () => { + expect(isValidURL('not-a-url')).toBe(false); + expect(isValidURL('http://')).toBe(false); + expect(isValidURL('')).toBe(false); + }); + + it('should return null for valid blog frontmatter', () => { + const validFrontmatter = { + title: 'Test Blog', + date: '2024-01-01', + type: 'blog', + tags: ['test', 'validation'], + cover: 'cover.jpg', + authors: [ + { + name: 'John Doe', + link: 'https://example.com', + photo: 'john.jpg' + } + ] + }; + + expect(validateBlogs(validFrontmatter)).toBeNull(); + }); + + it('should return errors for missing required attributes', () => { + const invalidFrontmatter = { + title: 'Test Blog' + }; + + const errors = validateBlogs(invalidFrontmatter); + expect(errors).toContain('date is missing'); + expect(errors).toContain('type is missing'); + expect(errors).toContain('tags is missing'); + expect(errors).toContain('cover is missing'); + expect(errors).toContain('authors is missing'); + }); + + it('should validate date format', () => { + const frontmatter = { + title: 'Test Blog', + date: 'invalid-date', + type: 'blog', + tags: ['test'], + cover: 'cover.jpg', + authors: [{ name: 'John', photo: 'photo.jpg' }] + }; + + const errors = validateBlogs(frontmatter); + expect(errors).toContain('Invalid date format: invalid-date'); + }); + + it('should validate authors array format', () => { + const frontmatter = { + title: 'Test Blog', + date: '2024-01-01', + type: 'blog', + tags: ['test'], + cover: 'cover.jpg', + authors: [ + { name: 'John' }, + { photo: 'jane.jpg' }, + { name: 'Bob', photo: 'bob.jpg', link: 'not-a-url' } + ] + }; + + const errors = validateBlogs(frontmatter); + expect(errors).toContain('Author at index 0 is missing a photo'); + expect(errors).toContain('Author at index 1 is missing a name'); + expect(errors).toContain('Invalid URL for author at index 2: not-a-url'); + }); + + it('should return null for valid docs frontmatter', () => { + const validFrontmatter = { + title: 'Test Doc', + weight: 1 + }; + + expect(validateDocs(validFrontmatter)).toBeNull(); + }); + + it('should return errors for invalid docs frontmatter', () => { + const invalidFrontmatter = { + title: 123, + weight: 'not-a-number' + }; + + const errors = validateDocs(invalidFrontmatter); + expect(errors).toContain('Title is missing or not a string'); + expect(errors).toContain('Weight is missing or not a number'); + }); + + it('should validate markdown files in directory', done => { + const validBlogContent = `--- +title: Valid Blog +date: 2024-01-01 +type: blog +tags: ['test'] +cover: cover.jpg +authors: + - name: John Doe + photo: john.jpg +--- +Content here +`; + + const invalidBlogContent = `--- +title: Invalid Blog +--- +Content here +`; + fs.writeFile(path.join(tempDir, 'valid.md'), validBlogContent, err => { + if (err) throw err; + + fs.writeFile(path.join(tempDir, 'invalid.md'), invalidBlogContent, err => { + if (err) throw err; + + fs.mkdir(path.join(tempDir, 'subdir'), err => { + if (err) throw err; + + fs.writeFile(path.join(tempDir, 'subdir', 'nested.md'), validBlogContent, err => { + if (err) throw err; + + const mockConsole = jest.spyOn(console, 'log').mockImplementation(); + const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); + + checkMarkdownFiles(tempDir, validateBlogs); + + setTimeout(() => { + expect(mockConsole).toHaveBeenCalledWith( + expect.stringContaining('Errors in file invalid.md:') + ); + + mockConsole.mockRestore(); + mockProcessExit.mockRestore(); + done(); + }, 1000); + }); + }); + }); + }); + }); + + it('should skip specified directories', done => { + fs.mkdir(path.join(tempDir, 'reference', 'specification'), { recursive: true }, err => { + if (err) throw err; + + const invalidContent = `--- +title: Invalid Content +---`; + + fs.writeFile(path.join(tempDir, 'reference', 'specification', 'skip.md'), invalidContent, err => { + if (err) throw err; + + const mockConsole = jest.spyOn(console, 'log').mockImplementation(); + + checkMarkdownFiles(tempDir, validateBlogs); + + setTimeout(() => { + expect(mockConsole).not.toHaveBeenCalled(); + + mockConsole.mockRestore(); + done(); + }, 1000); + }); + }); + }); + + it('should push multiple validation errors for invalid blog frontmatter', () => { + const invalidFrontmatter = { + title: 123, + date: 'invalid-date', + type: 'blog', + tags: 'not-an-array', + cover: ['not-a-string'], + authors: { + name: 'John Doe' + } + }; + + const errors = validateBlogs(invalidFrontmatter); + + expect(errors).toContain('Invalid date format: invalid-date'); + expect(errors).toContain('Tags should be an array'); + expect(errors).toContain('Cover must be a string'); + expect(errors).toContain('Authors should be an array'); + expect(errors.length).toBeGreaterThan(3); + }); + + + it('should handle filesystem errors when reading directory and file stats', done => { + const testFilePath = path.join(tempDir, 'test.md'); + fs.writeFileSync(testFilePath, '---\ntitle: Test\n---\nContent'); + + const originalReaddir = fs.readdir; + const mockReaddir = jest.spyOn(fs, 'readdir').mockImplementation((path, callback) => { + if (path.includes('error')) { + callback(new Error('Failed to read directory')); + } else { + originalReaddir(path, callback); + } + }); + + const originalStat = fs.stat; + const mockStat = jest.spyOn(fs, 'stat').mockImplementation((path, callback) => { + if (path.includes('test.md')) { + callback(new Error('Failed to read file stats')); + } else { + originalStat(path, callback); + } + }); + + checkMarkdownFiles(path.join(tempDir, 'error'), validateBlogs); + + checkMarkdownFiles(tempDir, validateBlogs); + + setTimeout(() => { + expect(mockConsoleError).toHaveBeenCalledWith( + 'Error reading directory:', + expect.any(Error) + ); + + expect(mockConsoleError).toHaveBeenCalledWith( + 'Error reading file stats:', + expect.any(Error) + ); + + mockReaddir.mockRestore(); + mockStat.mockRestore(); + done(); + }, 100); + }); +}); From 5373c9f16bdb1e4ff79053ed46773cb0bd49d4ed Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 14:04:23 +0530 Subject: [PATCH 02/32] tests updated --- scripts/markdown/check-markdown.js | 2 +- tests/markdown/check-markdown.test.js | 93 --------------------------- 2 files changed, 1 insertion(+), 94 deletions(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 0ff2f15eb255..7c0767b3824c 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -145,4 +145,4 @@ const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); checkMarkdownFiles(docsFolderPath, validateDocs); checkMarkdownFiles(blogsFolderPath, validateBlogs); -module.exports = { isValidURL, validateBlogs, validateDocs, checkMarkdownFiles,} +module.exports = { validateBlogs, validateDocs, checkMarkdownFiles,} diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 9c5e924935dd..e41e53b35573 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -2,7 +2,6 @@ const fs = require('fs'); const path = require('path'); const os = require('os'); const { - isValidURL, validateBlogs, validateDocs, checkMarkdownFiles @@ -29,64 +28,6 @@ describe('Frontmatter Validator', () => { }); }); - it('should return true for valid URLs', () => { - expect(isValidURL('https://example.com')).toBe(true); - expect(isValidURL('http://localhost:3000')).toBe(true); - expect(isValidURL('https://sub.domain.com/path?query=value')).toBe(true); - }); - - it('should return false for invalid URLs', () => { - expect(isValidURL('not-a-url')).toBe(false); - expect(isValidURL('http://')).toBe(false); - expect(isValidURL('')).toBe(false); - }); - - it('should return null for valid blog frontmatter', () => { - const validFrontmatter = { - title: 'Test Blog', - date: '2024-01-01', - type: 'blog', - tags: ['test', 'validation'], - cover: 'cover.jpg', - authors: [ - { - name: 'John Doe', - link: 'https://example.com', - photo: 'john.jpg' - } - ] - }; - - expect(validateBlogs(validFrontmatter)).toBeNull(); - }); - - it('should return errors for missing required attributes', () => { - const invalidFrontmatter = { - title: 'Test Blog' - }; - - const errors = validateBlogs(invalidFrontmatter); - expect(errors).toContain('date is missing'); - expect(errors).toContain('type is missing'); - expect(errors).toContain('tags is missing'); - expect(errors).toContain('cover is missing'); - expect(errors).toContain('authors is missing'); - }); - - it('should validate date format', () => { - const frontmatter = { - title: 'Test Blog', - date: 'invalid-date', - type: 'blog', - tags: ['test'], - cover: 'cover.jpg', - authors: [{ name: 'John', photo: 'photo.jpg' }] - }; - - const errors = validateBlogs(frontmatter); - expect(errors).toContain('Invalid date format: invalid-date'); - }); - it('should validate authors array format', () => { const frontmatter = { title: 'Test Blog', @@ -107,15 +48,6 @@ describe('Frontmatter Validator', () => { expect(errors).toContain('Invalid URL for author at index 2: not-a-url'); }); - it('should return null for valid docs frontmatter', () => { - const validFrontmatter = { - title: 'Test Doc', - weight: 1 - }; - - expect(validateDocs(validFrontmatter)).toBeNull(); - }); - it('should return errors for invalid docs frontmatter', () => { const invalidFrontmatter = { title: 123, @@ -178,31 +110,6 @@ Content here }); }); - it('should skip specified directories', done => { - fs.mkdir(path.join(tempDir, 'reference', 'specification'), { recursive: true }, err => { - if (err) throw err; - - const invalidContent = `--- -title: Invalid Content ----`; - - fs.writeFile(path.join(tempDir, 'reference', 'specification', 'skip.md'), invalidContent, err => { - if (err) throw err; - - const mockConsole = jest.spyOn(console, 'log').mockImplementation(); - - checkMarkdownFiles(tempDir, validateBlogs); - - setTimeout(() => { - expect(mockConsole).not.toHaveBeenCalled(); - - mockConsole.mockRestore(); - done(); - }, 1000); - }); - }); - }); - it('should push multiple validation errors for invalid blog frontmatter', () => { const invalidFrontmatter = { title: 123, From a30cef350f99ee5c9ff98cb727644449d07c61b2 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 14:06:55 +0530 Subject: [PATCH 03/32] test updated again --- tests/markdown/check-markdown.test.js | 160 ++++++++------------------ 1 file changed, 46 insertions(+), 114 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index e41e53b35573..385ea30664ef 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -22,156 +22,88 @@ describe('Frontmatter Validator', () => { afterEach(done => { mockConsoleError.mockRestore(); - fs.rm(tempDir, { recursive: true, force: true }, err => { - if (err) throw err; - done(); - }); + fs.rm(tempDir, { recursive: true, force: true }, done); }); - it('should validate authors array format', () => { + it('validates authors array and returns specific errors', () => { const frontmatter = { title: 'Test Blog', date: '2024-01-01', type: 'blog', tags: ['test'], cover: 'cover.jpg', - authors: [ - { name: 'John' }, - { photo: 'jane.jpg' }, - { name: 'Bob', photo: 'bob.jpg', link: 'not-a-url' } - ] + authors: [{ name: 'John' }, { photo: 'jane.jpg' }, { name: 'Bob', photo: 'bob.jpg', link: 'not-a-url' }] }; const errors = validateBlogs(frontmatter); - expect(errors).toContain('Author at index 0 is missing a photo'); - expect(errors).toContain('Author at index 1 is missing a name'); - expect(errors).toContain('Invalid URL for author at index 2: not-a-url'); + expect(errors).toEqual(expect.arrayContaining([ + 'Author at index 0 is missing a photo', + 'Author at index 1 is missing a name', + 'Invalid URL for author at index 2: not-a-url' + ])); }); - it('should return errors for invalid docs frontmatter', () => { - const invalidFrontmatter = { - title: 123, - weight: 'not-a-number' - }; - - const errors = validateDocs(invalidFrontmatter); - expect(errors).toContain('Title is missing or not a string'); - expect(errors).toContain('Weight is missing or not a number'); + it('validates docs frontmatter for required fields', () => { + const frontmatter = { title: 123, weight: 'not-a-number' }; + const errors = validateDocs(frontmatter); + expect(errors).toEqual(expect.arrayContaining([ + 'Title is missing or not a string', + 'Weight is missing or not a number' + ])); }); - it('should validate markdown files in directory', done => { - const validBlogContent = `--- -title: Valid Blog -date: 2024-01-01 -type: blog -tags: ['test'] -cover: cover.jpg -authors: - - name: John Doe - photo: john.jpg ---- -Content here -`; - - const invalidBlogContent = `--- -title: Invalid Blog ---- -Content here -`; - fs.writeFile(path.join(tempDir, 'valid.md'), validBlogContent, err => { - if (err) throw err; + it('checks for errors in markdown files in a directory', done => { + fs.writeFileSync(path.join(tempDir, 'invalid.md'), `---\ntitle: Invalid Blog\n---`); + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); - fs.writeFile(path.join(tempDir, 'invalid.md'), invalidBlogContent, err => { - if (err) throw err; - - fs.mkdir(path.join(tempDir, 'subdir'), err => { - if (err) throw err; - - fs.writeFile(path.join(tempDir, 'subdir', 'nested.md'), validBlogContent, err => { - if (err) throw err; - - const mockConsole = jest.spyOn(console, 'log').mockImplementation(); - const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); - - checkMarkdownFiles(tempDir, validateBlogs); - - setTimeout(() => { - expect(mockConsole).toHaveBeenCalledWith( - expect.stringContaining('Errors in file invalid.md:') - ); + checkMarkdownFiles(tempDir, validateBlogs); - mockConsole.mockRestore(); - mockProcessExit.mockRestore(); - done(); - }, 1000); - }); - }); - }); - }); + setTimeout(() => { + expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Errors in file invalid.md:')); + mockConsoleLog.mockRestore(); + done(); + }, 100); }); - it('should push multiple validation errors for invalid blog frontmatter', () => { - const invalidFrontmatter = { + it('returns multiple validation errors for invalid blog frontmatter', () => { + const frontmatter = { title: 123, date: 'invalid-date', type: 'blog', tags: 'not-an-array', cover: ['not-a-string'], - authors: { - name: 'John Doe' - } + authors: { name: 'John Doe' } }; + const errors = validateBlogs(frontmatter); - const errors = validateBlogs(invalidFrontmatter); - - expect(errors).toContain('Invalid date format: invalid-date'); - expect(errors).toContain('Tags should be an array'); - expect(errors).toContain('Cover must be a string'); - expect(errors).toContain('Authors should be an array'); expect(errors.length).toBeGreaterThan(3); }); + it('handles filesystem errors gracefully', done => { + fs.writeFileSync(path.join(tempDir, 'test.md'), '---\ntitle: Test\n---\nContent'); + jest.spyOn(fs, 'stat').mockImplementation((path, callback) => callback(new Error('File stat error'))); - it('should handle filesystem errors when reading directory and file stats', done => { - const testFilePath = path.join(tempDir, 'test.md'); - fs.writeFileSync(testFilePath, '---\ntitle: Test\n---\nContent'); + checkMarkdownFiles(tempDir, validateBlogs); - const originalReaddir = fs.readdir; - const mockReaddir = jest.spyOn(fs, 'readdir').mockImplementation((path, callback) => { - if (path.includes('error')) { - callback(new Error('Failed to read directory')); - } else { - originalReaddir(path, callback); - } - }); + setTimeout(() => { + expect(mockConsoleError).toHaveBeenCalledWith('Error reading file stats:', expect.any(Error)); + fs.stat.mockRestore(); + done(); + }, 100); + }); - const originalStat = fs.stat; - const mockStat = jest.spyOn(fs, 'stat').mockImplementation((path, callback) => { - if (path.includes('test.md')) { - callback(new Error('Failed to read file stats')); - } else { - originalStat(path, callback); - } + it('handles errors when reading a directory', done => { + jest.spyOn(fs, 'readdir').mockImplementation((_, callback) => { + callback(new Error('Directory read error')); }); - - checkMarkdownFiles(path.join(tempDir, 'error'), validateBlogs); - + checkMarkdownFiles(tempDir, validateBlogs); - + setTimeout(() => { - expect(mockConsoleError).toHaveBeenCalledWith( - 'Error reading directory:', - expect.any(Error) - ); - - expect(mockConsoleError).toHaveBeenCalledWith( - 'Error reading file stats:', - expect.any(Error) - ); - - mockReaddir.mockRestore(); - mockStat.mockRestore(); + expect(mockConsoleError).toHaveBeenCalledWith('Error reading directory:', expect.any(Error)); + fs.readdir.mockRestore(); done(); }, 100); }); + }); From a9da2400f2109972087f93c047df01469daa6c42 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 9 Nov 2024 15:16:03 +0530 Subject: [PATCH 04/32] fwqfwef --- tests/markdown/check-markdown.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 385ea30664ef..b7a907fdf97e 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -13,7 +13,7 @@ describe('Frontmatter Validator', () => { beforeEach(done => { mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); - fs.mkdtemp(path.join(os.tmpdir(), 'frontmatter-test-'), (err, directory) => { + fs.mkdtemp(path.join(os.tmpdir(), 'test-config'), (err, directory) => { if (err) throw err; tempDir = directory; done(); @@ -75,6 +75,7 @@ describe('Frontmatter Validator', () => { authors: { name: 'John Doe' } }; const errors = validateBlogs(frontmatter); + console.log(errors) expect(errors.length).toBeGreaterThan(3); }); From 86201ed63bd60bbe54d261340c706efff5dcdc6e Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 10 Nov 2024 23:16:47 +0530 Subject: [PATCH 05/32] use async await --- scripts/markdown/check-markdown.js | 57 ++++++++++++--------------- tests/markdown/check-markdown.test.js | 27 ------------- 2 files changed, 25 insertions(+), 59 deletions(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 7c0767b3824c..2795edc7f72b 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -1,4 +1,4 @@ -const fs = require('fs'); +const fs = require('fs').promises; const matter = require('gray-matter'); const path = require('path'); @@ -98,45 +98,38 @@ function validateDocs(frontmatter) { * @param {Function} validateFunction - The function used to validate the frontmatter. * @param {string} [relativePath=''] - The relative path of the folder for logging purposes. */ -function checkMarkdownFiles(folderPath, validateFunction, relativePath = '') { - fs.readdir(folderPath, (err, files) => { - if (err) { - console.error('Error reading directory:', err); - return; - } - - files.forEach(file => { +async function checkMarkdownFiles(folderPath, validateFunction, relativePath = '') { + try { + const files = await fs.readdir(folderPath); + for (const file of files) { const filePath = path.join(folderPath, file); const relativeFilePath = path.join(relativePath, file); // Skip the folder 'docs/reference/specification' if (relativeFilePath.includes('reference/specification')) { - return; + continue; } - fs.stat(filePath, (err, stats) => { - if (err) { - console.error('Error reading file stats:', err); - return; - } + const stats = await fs.stat(filePath); + + // Recurse if directory, otherwise validate markdown file + if (stats.isDirectory()) { + await checkMarkdownFiles(filePath, validateFunction, relativeFilePath); + } else if (path.extname(file) === '.md') { + const fileContent = await fs.readFile(filePath, 'utf-8'); + const { data: frontmatter } = matter(fileContent); - // Recurse if directory, otherwise validate markdown file - if (stats.isDirectory()) { - checkMarkdownFiles(filePath, validateFunction, relativeFilePath); - } else if (path.extname(file) === '.md') { - const fileContent = fs.readFileSync(filePath, 'utf-8'); - const { data: frontmatter } = matter(fileContent); - - const errors = validateFunction(frontmatter); - if (errors) { - console.log(`Errors in file ${relativeFilePath}:`); - errors.forEach(error => console.log(` - ${error}`)); - process.exitCode = 1; - } + const errors = validateFunction(frontmatter); + if (errors) { + console.log(`Errors in file ${relativeFilePath}:`); + errors.forEach(error => console.log(` - ${error}`)); + process.exitCode = 1; } - }); - }); - }); + } + } + } catch (err) { + console.error('Error processing files:', err); + } } const docsFolderPath = path.resolve(__dirname, '../../markdown/docs'); @@ -145,4 +138,4 @@ const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); checkMarkdownFiles(docsFolderPath, validateDocs); checkMarkdownFiles(blogsFolderPath, validateBlogs); -module.exports = { validateBlogs, validateDocs, checkMarkdownFiles,} +module.exports = { validateBlogs, validateDocs, checkMarkdownFiles } diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index b7a907fdf97e..861749637996 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -79,32 +79,5 @@ describe('Frontmatter Validator', () => { expect(errors.length).toBeGreaterThan(3); }); - - it('handles filesystem errors gracefully', done => { - fs.writeFileSync(path.join(tempDir, 'test.md'), '---\ntitle: Test\n---\nContent'); - jest.spyOn(fs, 'stat').mockImplementation((path, callback) => callback(new Error('File stat error'))); - - checkMarkdownFiles(tempDir, validateBlogs); - - setTimeout(() => { - expect(mockConsoleError).toHaveBeenCalledWith('Error reading file stats:', expect.any(Error)); - fs.stat.mockRestore(); - done(); - }, 100); - }); - - it('handles errors when reading a directory', done => { - jest.spyOn(fs, 'readdir').mockImplementation((_, callback) => { - callback(new Error('Directory read error')); - }); - - checkMarkdownFiles(tempDir, validateBlogs); - - setTimeout(() => { - expect(mockConsoleError).toHaveBeenCalledWith('Error reading directory:', expect.any(Error)); - fs.readdir.mockRestore(); - done(); - }, 100); - }); }); From 7c44f4a188e93b8cceb930b753248036a19abfff Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 10 Nov 2024 23:32:25 +0530 Subject: [PATCH 06/32] tests updated --- tests/markdown/check-markdown.test.js | 44 ++++++++++++++------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 861749637996..561ce80d144f 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -1,4 +1,4 @@ -const fs = require('fs'); +const fs = require('fs').promises; const path = require('path'); const os = require('os'); const { @@ -11,21 +11,17 @@ describe('Frontmatter Validator', () => { let tempDir; let mockConsoleError; - beforeEach(done => { + beforeEach(async () => { mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); - fs.mkdtemp(path.join(os.tmpdir(), 'test-config'), (err, directory) => { - if (err) throw err; - tempDir = directory; - done(); - }); + tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-config')); }); - afterEach(done => { + afterEach(async () => { mockConsoleError.mockRestore(); - fs.rm(tempDir, { recursive: true, force: true }, done); + await fs.rm(tempDir, { recursive: true, force: true }); }); - it('validates authors array and returns specific errors', () => { + it('validates authors array and returns specific errors', async () => { const frontmatter = { title: 'Test Blog', date: '2024-01-01', @@ -43,7 +39,7 @@ describe('Frontmatter Validator', () => { ])); }); - it('validates docs frontmatter for required fields', () => { + it('validates docs frontmatter for required fields', async () => { const frontmatter = { title: 123, weight: 'not-a-number' }; const errors = validateDocs(frontmatter); expect(errors).toEqual(expect.arrayContaining([ @@ -52,20 +48,17 @@ describe('Frontmatter Validator', () => { ])); }); - it('checks for errors in markdown files in a directory', done => { - fs.writeFileSync(path.join(tempDir, 'invalid.md'), `---\ntitle: Invalid Blog\n---`); + it('checks for errors in markdown files in a directory', async () => { + await fs.writeFile(path.join(tempDir, 'invalid.md'), `---\ntitle: Invalid Blog\n---`); const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); - checkMarkdownFiles(tempDir, validateBlogs); + await checkMarkdownFiles(tempDir, validateBlogs); - setTimeout(() => { - expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Errors in file invalid.md:')); - mockConsoleLog.mockRestore(); - done(); - }, 100); + expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Errors in file invalid.md:')); + mockConsoleLog.mockRestore(); }); - it('returns multiple validation errors for invalid blog frontmatter', () => { + it('returns multiple validation errors for invalid blog frontmatter', async () => { const frontmatter = { title: 123, date: 'invalid-date', @@ -75,9 +68,18 @@ describe('Frontmatter Validator', () => { authors: { name: 'John Doe' } }; const errors = validateBlogs(frontmatter); - console.log(errors) expect(errors.length).toBeGreaterThan(3); }); + + it('logs error to console when an error occurs in checkMarkdownFiles', async () => { + const invalidFolderPath = path.join(tempDir, 'non-existent-folder'); + const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); + + await checkMarkdownFiles(invalidFolderPath, validateBlogs); + + expect(mockConsoleError.mock.calls[0][0]).toContain('Error processing files:'); + mockConsoleError.mockRestore(); + }); }); From c98ecdd56315504130def85e7a0d8b47bde4fa8d Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 10 Nov 2024 23:37:09 +0530 Subject: [PATCH 07/32] wqegeg --- tests/markdown/check-markdown.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 561ce80d144f..ee6d77647bb7 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -81,5 +81,4 @@ describe('Frontmatter Validator', () => { expect(mockConsoleError.mock.calls[0][0]).toContain('Error processing files:'); mockConsoleError.mockRestore(); }); - }); From 6e34205cce7d204b638282564648f2c9d2281373 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sun, 10 Nov 2024 23:42:26 +0530 Subject: [PATCH 08/32] test updated --- tests/markdown/check-markdown.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index ee6d77647bb7..05c311a489ad 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -80,5 +80,6 @@ describe('Frontmatter Validator', () => { expect(mockConsoleError.mock.calls[0][0]).toContain('Error processing files:'); mockConsoleError.mockRestore(); - }); + }); + }); From 333e0b2a14b25ed33bdf8c0498a92edaa51da91d Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 11 Nov 2024 11:44:02 +0530 Subject: [PATCH 09/32] feg --- tests/markdown/check-markdown.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 05c311a489ad..795b938c325b 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -80,6 +80,5 @@ describe('Frontmatter Validator', () => { expect(mockConsoleError.mock.calls[0][0]).toContain('Error processing files:'); mockConsoleError.mockRestore(); - }); - + }); }); From 8849351044e80127ba7c9507801741cbd5f019ae Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Mon, 11 Nov 2024 11:53:21 +0530 Subject: [PATCH 10/32] Fixed variable shadowing --- tests/markdown/check-markdown.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 795b938c325b..6675ca3a14f1 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -74,11 +74,9 @@ describe('Frontmatter Validator', () => { it('logs error to console when an error occurs in checkMarkdownFiles', async () => { const invalidFolderPath = path.join(tempDir, 'non-existent-folder'); - const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); await checkMarkdownFiles(invalidFolderPath, validateBlogs); expect(mockConsoleError.mock.calls[0][0]).toContain('Error processing files:'); - mockConsoleError.mockRestore(); }); }); From fada5ab15c83b1425d28bfc935404a29ed5ca87c Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Wed, 13 Nov 2024 17:28:27 +0530 Subject: [PATCH 11/32] added tests for continue --- tests/markdown/check-markdown.test.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 6675ca3a14f1..210d15dd25d3 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -78,5 +78,19 @@ describe('Frontmatter Validator', () => { await checkMarkdownFiles(invalidFolderPath, validateBlogs); expect(mockConsoleError.mock.calls[0][0]).toContain('Error processing files:'); - }); + }); + + it('skips the "reference/specification" folder during validation', async () => { + const referenceSpecDir = path.join(tempDir, 'reference', 'specification'); + await fs.mkdir(referenceSpecDir, { recursive: true }); + await fs.writeFile(path.join(referenceSpecDir, 'skipped.md'), `---\ntitle: Skipped File\n---`); + + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + + await checkMarkdownFiles(tempDir, validateDocs); + + expect(mockConsoleLog).not.toHaveBeenCalledWith(expect.stringContaining('Errors in file reference/specification/skipped.md')); + mockConsoleLog.mockRestore(); + }); + }); From 68cd3ee3012281353bb876306ff0fb461995460d Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 14 Nov 2024 17:16:56 +0530 Subject: [PATCH 12/32] workflow re-run --- tests/markdown/check-markdown.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 210d15dd25d3..dd2b533c3ab4 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -92,5 +92,4 @@ describe('Frontmatter Validator', () => { expect(mockConsoleLog).not.toHaveBeenCalledWith(expect.stringContaining('Errors in file reference/specification/skipped.md')); mockConsoleLog.mockRestore(); }); - }); From 998af5a373ef41c6ce5c581c90e760345fac2f56 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 14 Nov 2024 17:26:29 +0530 Subject: [PATCH 13/32] workflow update --- .github/workflows/if-nodejs-pr-testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/if-nodejs-pr-testing.yml b/.github/workflows/if-nodejs-pr-testing.yml index d5489e7ab8f2..d96efbd1d60a 100644 --- a/.github/workflows/if-nodejs-pr-testing.yml +++ b/.github/workflows/if-nodejs-pr-testing.yml @@ -117,7 +117,7 @@ jobs: - if: steps.packagejson.outputs.exists == 'true' name: Upload Coverage to Codecov - uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 + uses: codecov/codecov-action@v4 with: fail_ci_if_error: true files: ./coverage/lcov.info From f5c8964f3ac70c35082402a9805214453eb99aff Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 14 Nov 2024 17:46:05 +0530 Subject: [PATCH 14/32] ff --- .github/workflows/if-nodejs-pr-testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/if-nodejs-pr-testing.yml b/.github/workflows/if-nodejs-pr-testing.yml index d96efbd1d60a..d5489e7ab8f2 100644 --- a/.github/workflows/if-nodejs-pr-testing.yml +++ b/.github/workflows/if-nodejs-pr-testing.yml @@ -117,7 +117,7 @@ jobs: - if: steps.packagejson.outputs.exists == 'true' name: Upload Coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 with: fail_ci_if_error: true files: ./coverage/lcov.info From a93b45d0feebecf5cf16d24c5b4d2c81c69fcd53 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 23 Nov 2024 09:49:13 +0530 Subject: [PATCH 15/32] suggetion applied --- scripts/markdown/check-markdown.js | 44 ++++++++++++++++----------- tests/markdown/check-markdown.test.js | 12 ++++++-- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 2795edc7f72b..c1ebb935c241 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -101,34 +101,42 @@ function validateDocs(frontmatter) { async function checkMarkdownFiles(folderPath, validateFunction, relativePath = '') { try { const files = await fs.readdir(folderPath); - for (const file of files) { + const filePromises = files.map(async (file) => { const filePath = path.join(folderPath, file); const relativeFilePath = path.join(relativePath, file); // Skip the folder 'docs/reference/specification' if (relativeFilePath.includes('reference/specification')) { - continue; + return; } - const stats = await fs.stat(filePath); - - // Recurse if directory, otherwise validate markdown file - if (stats.isDirectory()) { - await checkMarkdownFiles(filePath, validateFunction, relativeFilePath); - } else if (path.extname(file) === '.md') { - const fileContent = await fs.readFile(filePath, 'utf-8'); - const { data: frontmatter } = matter(fileContent); - - const errors = validateFunction(frontmatter); - if (errors) { - console.log(`Errors in file ${relativeFilePath}:`); - errors.forEach(error => console.log(` - ${error}`)); - process.exitCode = 1; + try { + const stats = await fs.stat(filePath); + + // Recurse if directory, otherwise validate markdown file + if (stats.isDirectory()) { + await checkMarkdownFiles(filePath, validateFunction, relativeFilePath); + } else if (path.extname(file) === '.md') { + const fileContent = await fs.readFile(filePath, 'utf-8'); + const { data: frontmatter } = matter(fileContent); + + const errors = validateFunction(frontmatter); + if (errors) { + console.log(`Errors in file ${relativeFilePath}:`); + errors.forEach(error => console.log(` - ${error}`)); + process.exitCode = 1; + } } + } catch (err) { + console.error(`Error processing file ${relativeFilePath}:`, err); + throw err; } - } + }); + + await Promise.all(filePromises); } catch (err) { - console.error('Error processing files:', err); + console.error(`Error in directory ${folderPath}:`, err); + throw err; } } diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index dd2b533c3ab4..e68f136c19d5 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -74,11 +74,17 @@ describe('Frontmatter Validator', () => { it('logs error to console when an error occurs in checkMarkdownFiles', async () => { const invalidFolderPath = path.join(tempDir, 'non-existent-folder'); + const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); - await checkMarkdownFiles(invalidFolderPath, validateBlogs); + try { + await checkMarkdownFiles(invalidFolderPath, validateBlogs); + } catch (error) { + expect(error.code).toBe('ENOENT'); + } - expect(mockConsoleError.mock.calls[0][0]).toContain('Error processing files:'); - }); + expect(mockConsoleError.mock.calls[0][0]).toContain('Error in directory'); + mockConsoleError.mockRestore(); + }); it('skips the "reference/specification" folder during validation', async () => { const referenceSpecDir = path.join(tempDir, 'reference', 'specification'); From 2732f0ff78bf77a704a8660c5bf9e79eea95c437 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 23 Nov 2024 09:51:46 +0530 Subject: [PATCH 16/32] suggetion applied --- tests/markdown/check-markdown.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index e68f136c19d5..ac44861e2817 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -74,7 +74,7 @@ describe('Frontmatter Validator', () => { it('logs error to console when an error occurs in checkMarkdownFiles', async () => { const invalidFolderPath = path.join(tempDir, 'non-existent-folder'); - const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); + // const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); try { await checkMarkdownFiles(invalidFolderPath, validateBlogs); From 4fcdea805f22647e0c6b9b262c82bc4f0d20c73a Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 23 Nov 2024 09:52:40 +0530 Subject: [PATCH 17/32] suggetion applied 2 --- tests/markdown/check-markdown.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index ac44861e2817..2d2cbbd46a93 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -74,7 +74,6 @@ describe('Frontmatter Validator', () => { it('logs error to console when an error occurs in checkMarkdownFiles', async () => { const invalidFolderPath = path.join(tempDir, 'non-existent-folder'); - // const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); try { await checkMarkdownFiles(invalidFolderPath, validateBlogs); @@ -83,7 +82,6 @@ describe('Frontmatter Validator', () => { } expect(mockConsoleError.mock.calls[0][0]).toContain('Error in directory'); - mockConsoleError.mockRestore(); }); it('skips the "reference/specification" folder during validation', async () => { From e1a16c117285d610fae3d6132b3ac02c09377cfa Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Sat, 23 Nov 2024 09:59:47 +0530 Subject: [PATCH 18/32] test added for err --- tests/markdown/check-markdown.test.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 2d2cbbd46a93..b8bf563a544c 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -96,4 +96,24 @@ describe('Frontmatter Validator', () => { expect(mockConsoleLog).not.toHaveBeenCalledWith(expect.stringContaining('Errors in file reference/specification/skipped.md')); mockConsoleLog.mockRestore(); }); + + it('logs and rethrows error when an exception occurs while processing a file', async () => { + const filePath = path.join(tempDir, 'invalid.md'); + await fs.writeFile(filePath, `---\ntitle: Valid Title\n---`); + + const mockReadFile = jest.spyOn(fs, 'readFile').mockRejectedValue(new Error('Test readFile error')); + + try { + await checkMarkdownFiles(tempDir, validateBlogs); + } catch (err) { + expect(mockConsoleError).toHaveBeenCalledWith( + expect.stringContaining(`Error processing file invalid.md:`), + expect.any(Error) + ); + expect(err.message).toBe('Test readFile error'); + } + + mockReadFile.mockRestore(); + }); + }); From 0fbdc06a876782a6adb664a8c4962bb958cdaafe Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 28 Nov 2024 22:05:43 +0530 Subject: [PATCH 19/32] main function added --- scripts/markdown/check-markdown.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index c1ebb935c241..d36f43d024ec 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -143,7 +143,18 @@ async function checkMarkdownFiles(folderPath, validateFunction, relativePath = ' const docsFolderPath = path.resolve(__dirname, '../../markdown/docs'); const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); -checkMarkdownFiles(docsFolderPath, validateDocs); -checkMarkdownFiles(blogsFolderPath, validateBlogs); +async function main() { + try { + await Promise.all([ + checkMarkdownFiles(docsFolderPath, validateDocs), + checkMarkdownFiles(blogsFolderPath, validateBlogs) + ]); + } catch (error) { + console.error('Failed to validate markdown files:', error); + process.exit(1); + } +} + +main(); module.exports = { validateBlogs, validateDocs, checkMarkdownFiles } From 02e221b624b1daf38ceecbf1a9a6ed2491251013 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 28 Nov 2024 22:29:11 +0530 Subject: [PATCH 20/32] added test for main function --- scripts/markdown/check-markdown.js | 2 +- tests/markdown/check-markdown.test.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index d36f43d024ec..45df04962eff 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -157,4 +157,4 @@ async function main() { main(); -module.exports = { validateBlogs, validateDocs, checkMarkdownFiles } +module.exports = { validateBlogs, validateDocs, checkMarkdownFiles, main } diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index b8bf563a544c..d59c92987f40 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -2,6 +2,7 @@ const fs = require('fs').promises; const path = require('path'); const os = require('os'); const { + main, validateBlogs, validateDocs, checkMarkdownFiles @@ -116,4 +117,19 @@ describe('Frontmatter Validator', () => { mockReadFile.mockRestore(); }); + it('should handle main function errors', async () => { + const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {}); + jest.spyOn(fs, 'readdir').mockRejectedValue(new Error('Test error')); + + await main(); + + expect(mockConsoleError).toHaveBeenCalledWith( + 'Failed to validate markdown files:', + expect.any(Error) + ); + expect(mockExit).toHaveBeenCalledWith(1); + + mockExit.mockRestore(); + }); + }); From b17b83e3e652ccbd729977249fe1a6bbfecd19d9 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 28 Nov 2024 22:31:04 +0530 Subject: [PATCH 21/32] tests updated --- tests/markdown/check-markdown.test.js | 35 ++++++++++++--------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index d59c92987f40..39bc88a93023 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -75,25 +75,22 @@ describe('Frontmatter Validator', () => { it('logs error to console when an error occurs in checkMarkdownFiles', async () => { const invalidFolderPath = path.join(tempDir, 'non-existent-folder'); - - try { - await checkMarkdownFiles(invalidFolderPath, validateBlogs); - } catch (error) { - expect(error.code).toBe('ENOENT'); - } - + + await expect(checkMarkdownFiles(invalidFolderPath, validateBlogs)) + .rejects.toThrow('ENOENT'); + expect(mockConsoleError.mock.calls[0][0]).toContain('Error in directory'); - }); + }); it('skips the "reference/specification" folder during validation', async () => { const referenceSpecDir = path.join(tempDir, 'reference', 'specification'); await fs.mkdir(referenceSpecDir, { recursive: true }); await fs.writeFile(path.join(referenceSpecDir, 'skipped.md'), `---\ntitle: Skipped File\n---`); - + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); - + await checkMarkdownFiles(tempDir, validateDocs); - + expect(mockConsoleLog).not.toHaveBeenCalledWith(expect.stringContaining('Errors in file reference/specification/skipped.md')); mockConsoleLog.mockRestore(); }); @@ -101,9 +98,9 @@ describe('Frontmatter Validator', () => { it('logs and rethrows error when an exception occurs while processing a file', async () => { const filePath = path.join(tempDir, 'invalid.md'); await fs.writeFile(filePath, `---\ntitle: Valid Title\n---`); - + const mockReadFile = jest.spyOn(fs, 'readFile').mockRejectedValue(new Error('Test readFile error')); - + try { await checkMarkdownFiles(tempDir, validateBlogs); } catch (err) { @@ -113,22 +110,22 @@ describe('Frontmatter Validator', () => { ); expect(err.message).toBe('Test readFile error'); } - + mockReadFile.mockRestore(); }); it('should handle main function errors', async () => { - const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {}); + const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => { }); jest.spyOn(fs, 'readdir').mockRejectedValue(new Error('Test error')); - + await main(); - + expect(mockConsoleError).toHaveBeenCalledWith( - 'Failed to validate markdown files:', + 'Failed to validate markdown files:', expect.any(Error) ); expect(mockExit).toHaveBeenCalledWith(1); - + mockExit.mockRestore(); }); From 35d2e843b10d411d2445adbd391dc45d64cbabe7 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 28 Nov 2024 22:34:36 +0530 Subject: [PATCH 22/32] jgk --- tests/markdown/check-markdown.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 39bc88a93023..8cc674f134a5 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -128,5 +128,4 @@ describe('Frontmatter Validator', () => { mockExit.mockRestore(); }); - }); From 7921604e27859c6fe929c8ab66d343680a8beefb Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Thu, 28 Nov 2024 23:44:14 +0530 Subject: [PATCH 23/32] test updated --- tests/markdown/check-markdown.test.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 8cc674f134a5..866c10ca6f90 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -70,7 +70,11 @@ describe('Frontmatter Validator', () => { }; const errors = validateBlogs(frontmatter); - expect(errors.length).toBeGreaterThan(3); + expect(errors).toEqual([ + "Invalid date format: invalid-date", + "Tags should be an array", + "Cover must be a string", + "Authors should be an array"]); }); it('logs error to console when an error occurs in checkMarkdownFiles', async () => { @@ -127,5 +131,6 @@ describe('Frontmatter Validator', () => { expect(mockExit).toHaveBeenCalledWith(1); mockExit.mockRestore(); - }); + }); + }); From dff6ccc29b5f5e5a989aa5a4280381b312fa1e63 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 11:32:57 +0530 Subject: [PATCH 24/32] main function test added --- tests/markdown/check-markdown.test.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 866c10ca6f90..a56ed97247eb 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -131,6 +131,10 @@ describe('Frontmatter Validator', () => { expect(mockExit).toHaveBeenCalledWith(1); mockExit.mockRestore(); - }); - + }); + + it('should execute main without errors', async () => { + await expect(main()).resolves.not.toThrow(); + }); + }); From 53c86fdd1a4832b0b7fb3f15c224df47e801caef Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 11:47:54 +0530 Subject: [PATCH 25/32] test updated --- tests/markdown/check-markdown.test.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index a56ed97247eb..651a8b22e23c 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -131,10 +131,5 @@ describe('Frontmatter Validator', () => { expect(mockExit).toHaveBeenCalledWith(1); mockExit.mockRestore(); - }); - - it('should execute main without errors', async () => { - await expect(main()).resolves.not.toThrow(); - }); - + }); }); From 92cc88546110f84246bdfa7ac17021b2ac3d2178 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 11:56:30 +0530 Subject: [PATCH 26/32] test updates --- tests/markdown/check-markdown.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 651a8b22e23c..0cbdf5f323ef 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -131,5 +131,5 @@ describe('Frontmatter Validator', () => { expect(mockExit).toHaveBeenCalledWith(1); mockExit.mockRestore(); - }); + }); }); From c0afa97362a6d9cc5f901588fb94081b52727d40 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 22:14:14 +0530 Subject: [PATCH 27/32] script updated --- scripts/markdown/check-markdown.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 45df04962eff..0067f7ae4dda 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -143,11 +143,11 @@ async function checkMarkdownFiles(folderPath, validateFunction, relativePath = ' const docsFolderPath = path.resolve(__dirname, '../../markdown/docs'); const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); -async function main() { +async function main(docsPath = docsFolderPath, blogsPath = blogsFolderPath) { try { await Promise.all([ - checkMarkdownFiles(docsFolderPath, validateDocs), - checkMarkdownFiles(blogsFolderPath, validateBlogs) + checkMarkdownFiles(docsPath, validateDocs), + checkMarkdownFiles(blogsPath, validateBlogs) ]); } catch (error) { console.error('Failed to validate markdown files:', error); @@ -155,6 +155,6 @@ async function main() { } } -main(); +main(docsFolderPath,blogsFolderPath); module.exports = { validateBlogs, validateDocs, checkMarkdownFiles, main } From 10c1ba558e5c483ece4112499aaa6920724c0c52 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 22:39:20 +0530 Subject: [PATCH 28/32] add tests for main function --- scripts/markdown/check-markdown.js | 7 +++---- tests/markdown/check-markdown.test.js | 14 +++++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 0067f7ae4dda..0563a5e37add 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -143,15 +143,14 @@ async function checkMarkdownFiles(folderPath, validateFunction, relativePath = ' const docsFolderPath = path.resolve(__dirname, '../../markdown/docs'); const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); -async function main(docsPath = docsFolderPath, blogsPath = blogsFolderPath) { +async function main(docsFolderPath, blogsFolderPath) { try { await Promise.all([ - checkMarkdownFiles(docsPath, validateDocs), - checkMarkdownFiles(blogsPath, validateBlogs) + checkMarkdownFiles(docsFolderPath, validateDocs), + checkMarkdownFiles(blogsFolderPath, validateBlogs) ]); } catch (error) { console.error('Failed to validate markdown files:', error); - process.exit(1); } } diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 0cbdf5f323ef..3f4d04941a6d 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -119,7 +119,6 @@ describe('Frontmatter Validator', () => { }); it('should handle main function errors', async () => { - const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => { }); jest.spyOn(fs, 'readdir').mockRejectedValue(new Error('Test error')); await main(); @@ -128,8 +127,17 @@ describe('Frontmatter Validator', () => { 'Failed to validate markdown files:', expect.any(Error) ); - expect(mockExit).toHaveBeenCalledWith(1); + }); + + it('should handle successful main function execution', async () => { + + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + + await main(); + + expect(mockConsoleLog).not.toHaveBeenCalledWith(); - mockExit.mockRestore(); + mockConsoleLog.mockRestore(); }); + }); From 2fa09e628e56cac7fc556b7c28f02324144a281e Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 22:41:54 +0530 Subject: [PATCH 29/32] test updated --- tests/markdown/check-markdown.test.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 3f4d04941a6d..f56bbebf4f9f 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -130,14 +130,10 @@ describe('Frontmatter Validator', () => { }); it('should handle successful main function execution', async () => { - - const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); await main(); - expect(mockConsoleLog).not.toHaveBeenCalledWith(); - - mockConsoleLog.mockRestore(); + expect(mockConsoleError).not.toHaveBeenCalledWith() }); }); From aa0e2412ff8292127cd01ee373b142caa54bcf13 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 22:48:43 +0530 Subject: [PATCH 30/32] status code upudated --- scripts/markdown/check-markdown.js | 1 + tests/markdown/check-markdown.test.js | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 0563a5e37add..0cda8fe0e958 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -151,6 +151,7 @@ async function main(docsFolderPath, blogsFolderPath) { ]); } catch (error) { console.error('Failed to validate markdown files:', error); + process.exit(1); } } diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index f56bbebf4f9f..9130b3ceac59 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -11,14 +11,17 @@ const { describe('Frontmatter Validator', () => { let tempDir; let mockConsoleError; + let mockProcessExit; beforeEach(async () => { mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); + mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-config')); }); afterEach(async () => { mockConsoleError.mockRestore(); + mockProcessExit.mockRestore(); await fs.rm(tempDir, { recursive: true, force: true }); }); @@ -118,11 +121,13 @@ describe('Frontmatter Validator', () => { mockReadFile.mockRestore(); }); - it('should handle main function errors', async () => { + it('should handle main function errors and exit with status 1', async () => { jest.spyOn(fs, 'readdir').mockRejectedValue(new Error('Test error')); await main(); + expect(mockProcessExit).toHaveBeenCalledWith(1); + expect(mockConsoleError).toHaveBeenCalledWith( 'Failed to validate markdown files:', expect.any(Error) @@ -130,10 +135,10 @@ describe('Frontmatter Validator', () => { }); it('should handle successful main function execution', async () => { - + await main(); - + expect(mockConsoleError).not.toHaveBeenCalledWith() }); - + }); From 746dc8809c0b1ce7b890898e2b2bced81b1c3d86 Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 22:51:13 +0530 Subject: [PATCH 31/32] test updated --- tests/markdown/check-markdown.test.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js index 9130b3ceac59..51d1b3d1b34f 100644 --- a/tests/markdown/check-markdown.test.js +++ b/tests/markdown/check-markdown.test.js @@ -102,21 +102,17 @@ describe('Frontmatter Validator', () => { mockConsoleLog.mockRestore(); }); - it('logs and rethrows error when an exception occurs while processing a file', async () => { + it('logs and rejects when an exception occurs while processing a file', async () => { const filePath = path.join(tempDir, 'invalid.md'); await fs.writeFile(filePath, `---\ntitle: Valid Title\n---`); const mockReadFile = jest.spyOn(fs, 'readFile').mockRejectedValue(new Error('Test readFile error')); - try { - await checkMarkdownFiles(tempDir, validateBlogs); - } catch (err) { - expect(mockConsoleError).toHaveBeenCalledWith( - expect.stringContaining(`Error processing file invalid.md:`), - expect.any(Error) - ); - expect(err.message).toBe('Test readFile error'); - } + await expect(checkMarkdownFiles(tempDir, validateBlogs)).rejects.toThrow('Test readFile error'); + expect(mockConsoleError).toHaveBeenCalledWith( + expect.stringContaining(`Error processing file invalid.md:`), + expect.any(Error) + ); mockReadFile.mockRestore(); }); From 29cd78ce2ac0a1cb6115be6156e320630b9325cf Mon Sep 17 00:00:00 2001 From: Vishvamsinh Vaghela Date: Fri, 29 Nov 2024 23:07:24 +0530 Subject: [PATCH 32/32] script updated --- scripts/markdown/check-markdown.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 0cda8fe0e958..45df04962eff 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -143,7 +143,7 @@ async function checkMarkdownFiles(folderPath, validateFunction, relativePath = ' const docsFolderPath = path.resolve(__dirname, '../../markdown/docs'); const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); -async function main(docsFolderPath, blogsFolderPath) { +async function main() { try { await Promise.all([ checkMarkdownFiles(docsFolderPath, validateDocs), @@ -155,6 +155,6 @@ async function main(docsFolderPath, blogsFolderPath) { } } -main(docsFolderPath,blogsFolderPath); +main(); module.exports = { validateBlogs, validateDocs, checkMarkdownFiles, main }