From 28411a2cece75d086b7c994ddf7ea7daf8a507e8 Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Fri, 12 Sep 2025 18:50:02 +0200 Subject: [PATCH] refactor: migrate challenge parser tests to vitest (#62186) --- jest.config.js | 1 + package.json | 1 + pnpm-lock.yaml | 5 +- tools/challenge-parser/package.json | 5 +- .../index.acceptance.test.js.snap | 20 +- .../parser/index.acceptance.test.js | 28 +- .../add-frontmatter.test.js.snap | 4 +- .../__snapshots__/add-hooks.test.js.snap | 4 +- .../__snapshots__/add-quizzes.test.js.snap | 4 +- .../__snapshots__/add-seed.test.js.snap | 4 +- .../__snapshots__/add-solution.test.js.snap | 4 +- .../__snapshots__/add-tests.test.js.snap | 4 +- .../__snapshots__/add-text.test.js.snap | 4 +- .../add-video-question.test.js.snap | 4 +- .../replace-imports.test.js.snap | 4 +- .../plugins/add-fill-in-the-blank.test.js | 5 +- .../parser/plugins/add-frontmatter.test.js | 7 +- .../parser/plugins/add-hooks.test.js | 5 +- .../parser/plugins/add-quizzes.test.js | 5 +- .../parser/plugins/add-seed.test.js | 7 +- .../parser/plugins/add-solution.test.js | 7 +- .../parser/plugins/add-tests.test.js | 5 +- .../parser/plugins/add-text.test.js | 5 +- .../parser/plugins/add-video-question.test.js | 5 +- .../parser/plugins/replace-imports.test.js | 284 ++++++++---------- .../parser/plugins/restore-directives.test.js | 11 +- .../__snapshots__/get-section.test.js.snap | 6 +- .../plugins/utils/before-heading.test.js | 7 +- .../parser/plugins/utils/find-all.test.js | 4 +- .../plugins/utils/get-file-visitor.test.js | 33 -- .../parser/plugins/utils/get-id.test.js | 6 +- .../utils/get-paragraph-content.test.js | 6 +- .../parser/plugins/utils/get-section.test.js | 11 +- .../plugins/utils/mdast-to-html.test.js | 5 +- .../parser/plugins/validate-sections.test.js | 12 +- .../translation-parser/index.test.js | 13 +- 36 files changed, 257 insertions(+), 288 deletions(-) delete mode 100644 tools/challenge-parser/parser/plugins/utils/get-file-visitor.test.js diff --git a/jest.config.js b/jest.config.js index 7496579148f..e2d111fa59e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,6 +4,7 @@ module.exports = { 'api/', 'e2e/', 'tools/challenge-helper-scripts/', + 'tools/challenge-parser/', 'tools/scripts/build/', 'curriculum' ], diff --git a/package.json b/package.json index fcbd946e2fc..5e07713c171 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "test:api": "cd api && pnpm test", "test:tools:challenge-helper-scripts": "cd ./tools/challenge-helper-scripts && pnpm test run", "test:tools:scripts-build": "cd ./tools/scripts/build && pnpm test run", + "test:tools:challenge-parser": "cd ./tools/challenge-parser && pnpm test run", "test:curriculum:content": "cd ./curriculum && pnpm test", "test:curriculum:tooling": "cd ./curriculum && pnpm vitest run", "test-curriculum-full-output": "cd ./curriculum && pnpm run test:full-output", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a339b059cc..a7718e8ba41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -959,6 +959,9 @@ importers: unist-util-select: specifier: 3.0.4 version: 3.0.4 + vitest: + specifier: ^3.2.4 + version: 3.2.4(@types/node@20.12.8)(@vitest/ui@3.2.4)(jsdom@26.1.0)(msw@2.8.7(@types/node@20.12.8)(typescript@5.8.2))(terser@5.28.1)(tsx@4.19.1)(yaml@2.8.0) tools/client-plugins/browser-scripts: dependencies: @@ -20408,7 +20411,7 @@ snapshots: sirv: 3.0.1 tinyglobby: 0.2.14 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@20.12.8)(@vitest/ui@3.2.4)(jsdom@16.7.0)(msw@2.8.7(@types/node@20.12.8)(typescript@5.8.2))(terser@5.28.1)(tsx@4.19.1)(yaml@2.8.0) + vitest: 3.2.4(@types/node@20.12.8)(@vitest/ui@3.2.4)(jsdom@26.1.0)(msw@2.8.7(@types/node@20.12.8)(typescript@5.8.2))(terser@5.28.1)(tsx@4.19.1)(yaml@2.8.0) '@vitest/utils@3.2.4': dependencies: diff --git a/tools/challenge-parser/package.json b/tools/challenge-parser/package.json index 7457803bacd..b82af7e47c2 100644 --- a/tools/challenge-parser/package.json +++ b/tools/challenge-parser/package.json @@ -19,7 +19,7 @@ "author": "freeCodeCamp ", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "vitest" }, "dependencies": { "hast-util-to-html": "7.1.3", @@ -54,6 +54,7 @@ "unist-util-visit-children": "1.1.4" }, "devDependencies": { - "unist-util-select": "3.0.4" + "unist-util-select": "3.0.4", + "vitest": "^3.2.4" } } diff --git a/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap b/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap index e92140bcbcc..e026456b949 100644 --- a/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap +++ b/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`challenge parser it should not parse directives we do not use 1`] = ` +exports[`challenge parser > it should not parse directives we do not use 1`] = ` { "assignments": [], "description": "
@@ -18,7 +18,7 @@ a container directive } `; -exports[`challenge parser it should parse md with a scene 1`] = ` +exports[`challenge parser > it should parse md with a scene 1`] = ` { "assignments": [], "description": "
@@ -72,7 +72,7 @@ exports[`challenge parser it should parse md with a scene 1`] = ` } `; -exports[`challenge parser it should parse video questions 1`] = ` +exports[`challenge parser > it should parse video questions 1`] = ` { "assignments": [], "description": "
@@ -113,7 +113,7 @@ exports[`challenge parser it should parse video questions 1`] = ` } `; -exports[`challenge parser should import md from other files 1`] = ` +exports[`challenge parser > should import md from other files 1`] = ` { "assignments": [], "challengeFiles": [ @@ -178,7 +178,7 @@ for (let index = 0; index < array.length; index++) { } `; -exports[`challenge parser should not mix other YAML with the frontmatter 1`] = ` +exports[`challenge parser > should not mix other YAML with the frontmatter 1`] = ` { "assignments": [], "challengeFiles": [ @@ -243,7 +243,7 @@ exports[`challenge parser should not mix other YAML with the frontmatter 1`] = ` } `; -exports[`challenge parser should parse a more realistic md file 1`] = ` +exports[`challenge parser > should parse a more realistic md file 1`] = ` { "assignments": [], "challengeFiles": [ @@ -433,7 +433,7 @@ assert( } `; -exports[`challenge parser should parse a simple md file 1`] = ` +exports[`challenge parser > should parse a simple md file 1`] = ` { "assignments": [], "challengeFiles": [ @@ -534,7 +534,7 @@ if(let x of xs) { } `; -exports[`challenge parser should parse frontmatter 1`] = ` +exports[`challenge parser > should parse frontmatter 1`] = ` { "assignments": [], "challengeFiles": [ @@ -596,7 +596,7 @@ exports[`challenge parser should parse frontmatter 1`] = ` } `; -exports[`challenge parser should parse gfm strikethrough and frontmatter 1`] = ` +exports[`challenge parser > should parse gfm strikethrough and frontmatter 1`] = ` { "assignments": [], "challengeFiles": [ diff --git a/tools/challenge-parser/parser/index.acceptance.test.js b/tools/challenge-parser/parser/index.acceptance.test.js index 5842a155330..4d0a5d0ad05 100644 --- a/tools/challenge-parser/parser/index.acceptance.test.js +++ b/tools/challenge-parser/parser/index.acceptance.test.js @@ -1,68 +1,66 @@ -const path = require('path'); +import { resolve } from 'path'; -const { parseMD } = require('.'); +import { describe, it, expect } from 'vitest'; + +import { parseMD } from '.'; describe('challenge parser', () => { it('should parse a simple md file', async () => { - const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/simple.md') - ); + const parsed = await parseMD(resolve(__dirname, '__fixtures__/simple.md')); expect(parsed).toMatchSnapshot(); }); it('should parse a more realistic md file', async () => { const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/realistic.md') + resolve(__dirname, '__fixtures__/realistic.md') ); expect(parsed).toMatchSnapshot(); }); it('should import md from other files', async () => { const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/with-imports.md') + resolve(__dirname, '__fixtures__/with-imports.md') ); expect(parsed).toMatchSnapshot(); }); it('should parse frontmatter', async () => { const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/with-frontmatter.md') + resolve(__dirname, '__fixtures__/with-frontmatter.md') ); expect(parsed).toMatchSnapshot(); }); it('should parse gfm strikethrough and frontmatter', async () => { const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/with-gfm.md') + resolve(__dirname, '__fixtures__/with-gfm.md') ); expect(parsed).toMatchSnapshot(); }); it('should not mix other YAML with the frontmatter', async () => { const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/with-yaml.md') + resolve(__dirname, '__fixtures__/with-yaml.md') ); expect(parsed).toMatchSnapshot(); }); it('it should parse video questions', async () => { const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/with-video-question.md') + resolve(__dirname, '__fixtures__/with-video-question.md') ); expect(parsed).toMatchSnapshot(); }); it('it should not parse directives we do not use', async () => { const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/with-directives.md') + resolve(__dirname, '__fixtures__/with-directives.md') ); expect(parsed).toMatchSnapshot(); }); it('it should parse md with a scene', async () => { - const parsed = await parseMD( - path.resolve(__dirname, '__fixtures__/scene.md') - ); + const parsed = await parseMD(resolve(__dirname, '__fixtures__/scene.md')); expect(parsed).toMatchSnapshot(); }); }); diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/add-frontmatter.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/add-frontmatter.test.js.snap index 29c5bb6203d..ab1d3c18c65 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/add-frontmatter.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/add-frontmatter.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`process-frontmatter plugin should have an output to match the snapshot 1`] = ` +exports[`process-frontmatter plugin > should have an output to match the snapshot 1`] = ` { "challengeType": 0, "forumTopicId": 18276, diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/add-hooks.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/add-hooks.test.js.snap index a3d75039298..99812c202c4 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/add-hooks.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/add-hooks.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`add-before-hook plugin should have an output to match the snapshot 1`] = ` +exports[`add-before-hook plugin > should have an output to match the snapshot 1`] = ` { "hooks": { "beforeAll": "// before all code diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/add-quizzes.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/add-quizzes.test.js.snap index 244566db514..d996e413ba3 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/add-quizzes.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/add-quizzes.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`add-quizzes plugin should match the quizzes snapshot 1`] = ` +exports[`add-quizzes plugin > should match the quizzes snapshot 1`] = ` { "quizzes": [ { diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/add-seed.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/add-seed.test.js.snap index c0b8705c3cd..78738ba3f45 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/add-seed.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/add-seed.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`add-seed plugin should have an output to match the snapshot 1`] = ` +exports[`add-seed plugin > should have an output to match the snapshot 1`] = ` { "challengeFiles": [ { diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/add-solution.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/add-solution.test.js.snap index 0da4a27fd24..bc7c066cf02 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/add-solution.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/add-solution.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`add solution plugin should have an output to match the snapshot 1`] = ` +exports[`add solution plugin > should have an output to match the snapshot 1`] = ` { "solutions": [ [ diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/add-tests.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/add-tests.test.js.snap index aef10341e47..fd3c65ba12f 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/add-tests.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/add-tests.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`add-tests plugin should have an output to match the snapshot 1`] = ` +exports[`add-tests plugin > should have an output to match the snapshot 1`] = ` { "tests": [ { diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/add-text.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/add-text.test.js.snap index 7c90c4f0cb4..c75f0639587 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/add-text.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/add-text.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`add-text should have an output to match the snapshot 1`] = ` +exports[`add-text > should have an output to match the snapshot 1`] = ` { "description": "

Paragraph 1

diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/add-video-question.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/add-video-question.test.js.snap index 1fef22f040c..865b7d6ffd5 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/add-video-question.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/add-video-question.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`add-video-question plugin should match the video snapshot 1`] = ` +exports[`add-video-question plugin > should match the video snapshot 1`] = ` { "questions": [ { diff --git a/tools/challenge-parser/parser/plugins/__snapshots__/replace-imports.test.js.snap b/tools/challenge-parser/parser/plugins/__snapshots__/replace-imports.test.js.snap index 59fd5610527..e699c449f31 100644 --- a/tools/challenge-parser/parser/plugins/__snapshots__/replace-imports.test.js.snap +++ b/tools/challenge-parser/parser/plugins/__snapshots__/replace-imports.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`replace-imports should have an output to match the snapshot 1`] = ` +exports[`replace-imports > should have an output to match the snapshot 1`] = ` { "children": [ { diff --git a/tools/challenge-parser/parser/plugins/add-fill-in-the-blank.test.js b/tools/challenge-parser/parser/plugins/add-fill-in-the-blank.test.js index ed0cf83af02..9b1cc8b921d 100644 --- a/tools/challenge-parser/parser/plugins/add-fill-in-the-blank.test.js +++ b/tools/challenge-parser/parser/plugins/add-fill-in-the-blank.test.js @@ -1,5 +1,6 @@ -const parseFixture = require('../__fixtures__/parse-fixture'); -const addFillInTheBlankQuestion = require('./add-fill-in-the-blank'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import parseFixture from '../__fixtures__/parse-fixture'; +import addFillInTheBlankQuestion from './add-fill-in-the-blank'; describe('fill-in-the-blanks plugin', () => { let mockFillInTheBlankAST, diff --git a/tools/challenge-parser/parser/plugins/add-frontmatter.test.js b/tools/challenge-parser/parser/plugins/add-frontmatter.test.js index 15d01c60120..57b9bb352f3 100644 --- a/tools/challenge-parser/parser/plugins/add-frontmatter.test.js +++ b/tools/challenge-parser/parser/plugins/add-frontmatter.test.js @@ -1,7 +1,8 @@ -const { isObject } = require('lodash'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import { isObject } from 'lodash'; -const parse = require('../__fixtures__/parse-fixture'); -const processFrontmatter = require('./add-frontmatter'); +import parse from '../__fixtures__/parse-fixture'; +import processFrontmatter from './add-frontmatter'; describe('process-frontmatter plugin', () => { let mockAST; diff --git a/tools/challenge-parser/parser/plugins/add-hooks.test.js b/tools/challenge-parser/parser/plugins/add-hooks.test.js index d856f46a643..e424a1a9d82 100644 --- a/tools/challenge-parser/parser/plugins/add-hooks.test.js +++ b/tools/challenge-parser/parser/plugins/add-hooks.test.js @@ -1,6 +1,7 @@ -const parseFixture = require('../__fixtures__/parse-fixture'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import parseFixture from '../__fixtures__/parse-fixture'; -const addBeforeHook = require('./add-hooks'); +import addBeforeHook from './add-hooks'; describe('add-before-hook plugin', () => { let withBeforeHookAST, diff --git a/tools/challenge-parser/parser/plugins/add-quizzes.test.js b/tools/challenge-parser/parser/plugins/add-quizzes.test.js index 2eedce30d28..bb065e737d3 100644 --- a/tools/challenge-parser/parser/plugins/add-quizzes.test.js +++ b/tools/challenge-parser/parser/plugins/add-quizzes.test.js @@ -1,5 +1,6 @@ -const parseFixture = require('./../__fixtures__/parse-fixture'); -const addQuizzes = require('./add-quizzes'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import parseFixture from './../__fixtures__/parse-fixture'; +import addQuizzes from './add-quizzes'; describe('add-quizzes plugin', () => { let mockQuizzesAST; diff --git a/tools/challenge-parser/parser/plugins/add-seed.test.js b/tools/challenge-parser/parser/plugins/add-seed.test.js index cc7c0486678..69fccc669ba 100644 --- a/tools/challenge-parser/parser/plugins/add-seed.test.js +++ b/tools/challenge-parser/parser/plugins/add-seed.test.js @@ -1,7 +1,8 @@ -const isArray = require('lodash/isArray'); -const parseFixture = require('../__fixtures__/parse-fixture'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import isArray from 'lodash/isArray'; +import parseFixture from '../__fixtures__/parse-fixture'; -const addSeed = require('./add-seed'); +import addSeed from './add-seed'; describe('add-seed plugin', () => { let adjacentKeysAST, diff --git a/tools/challenge-parser/parser/plugins/add-solution.test.js b/tools/challenge-parser/parser/plugins/add-solution.test.js index ff92e13f40a..0739bd2ef06 100644 --- a/tools/challenge-parser/parser/plugins/add-solution.test.js +++ b/tools/challenge-parser/parser/plugins/add-solution.test.js @@ -1,6 +1,7 @@ -const { isObject } = require('lodash'); -const parseFixture = require('../__fixtures__/parse-fixture'); -const addSolution = require('./add-solution'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import { isObject } from 'lodash'; +import parseFixture from '../__fixtures__/parse-fixture'; +import addSolution from './add-solution'; describe('add solution plugin', () => { let mockAST, multiSolnsAST, editableSolutionAST; diff --git a/tools/challenge-parser/parser/plugins/add-tests.test.js b/tools/challenge-parser/parser/plugins/add-tests.test.js index 7aeccb4de9c..2f7c614e3b5 100644 --- a/tools/challenge-parser/parser/plugins/add-tests.test.js +++ b/tools/challenge-parser/parser/plugins/add-tests.test.js @@ -1,5 +1,6 @@ -const parseFixture = require('../__fixtures__/parse-fixture'); -const addTests = require('./add-tests'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import parseFixture from '../__fixtures__/parse-fixture'; +import addTests from './add-tests'; describe('add-tests plugin', () => { let brokenHintsAST, simpleAST, missingTestStringAST; diff --git a/tools/challenge-parser/parser/plugins/add-text.test.js b/tools/challenge-parser/parser/plugins/add-text.test.js index 804c2309859..d7f1f5bbbf3 100644 --- a/tools/challenge-parser/parser/plugins/add-text.test.js +++ b/tools/challenge-parser/parser/plugins/add-text.test.js @@ -1,5 +1,6 @@ -const parseFixture = require('../__fixtures__/parse-fixture'); -const addText = require('./add-text'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import parseFixture from '../__fixtures__/parse-fixture'; +import addText from './add-text'; describe('add-text', () => { let realisticAST, mockAST, withSubSectionAST; diff --git a/tools/challenge-parser/parser/plugins/add-video-question.test.js b/tools/challenge-parser/parser/plugins/add-video-question.test.js index 9d893ed2204..a08fd6a9a77 100644 --- a/tools/challenge-parser/parser/plugins/add-video-question.test.js +++ b/tools/challenge-parser/parser/plugins/add-video-question.test.js @@ -1,5 +1,6 @@ -const parseFixture = require('../__fixtures__/parse-fixture'); -const addVideoQuestion = require('./add-video-question'); +import { describe, beforeAll, beforeEach, it, expect } from 'vitest'; +import parseFixture from '../__fixtures__/parse-fixture'; +import addVideoQuestion from './add-video-question'; describe('add-video-question plugin', () => { let simpleAST, videoAST, multipleQuestionAST, videoOutOfOrderAST; diff --git a/tools/challenge-parser/parser/plugins/replace-imports.test.js b/tools/challenge-parser/parser/plugins/replace-imports.test.js index c00ef586edc..55d4ec392eb 100644 --- a/tools/challenge-parser/parser/plugins/replace-imports.test.js +++ b/tools/challenge-parser/parser/plugins/replace-imports.test.js @@ -1,10 +1,11 @@ -const path = require('path'); -const cloneDeep = require('lodash/cloneDeep'); -const toVfile = require('to-vfile'); -const selectAll = require('unist-util-select').selectAll; -const parseFixture = require('../__fixtures__/parse-fixture'); +import { resolve } from 'path'; +import { describe, beforeAll, beforeEach, it, expect, vi } from 'vitest'; +import cloneDeep from 'lodash/cloneDeep'; +import toVfile from 'to-vfile'; +import { selectAll } from 'unist-util-select'; +import parseFixture from '../__fixtures__/parse-fixture'; -const addImports = require('./replace-imports'); +import addImports from './replace-imports'; describe('replace-imports', () => { let importsAST, @@ -36,10 +37,10 @@ describe('replace-imports', () => { simpleAST = cloneDeep(originalSimpleAST); markerAST = cloneDeep(originalMarkerAST); correctFile = toVfile( - path.resolve(__dirname, '../__fixtures__/with-imports.md') + resolve(__dirname, '../__fixtures__/with-imports.md') ); incorrectFile = toVfile( - path.resolve(__dirname, '../__fixtures__/incorrect-path/with-imports.md') + resolve(__dirname, '../__fixtures__/incorrect-path/with-imports.md') ); }); @@ -50,70 +51,66 @@ describe('replace-imports', () => { expect(typeof plugin).toEqual('function'); }); - it('should fail when the imported file is null', done => { + it('should fail when the imported file is null', () => { const plugin = addImports(); - const next = err => { - if (err) { - done(); - } else { - done('An error should have been thrown by addImports'); - } - }; - plugin(importsAST, null, next); + const nextSpy = vi.fn(); + + plugin(importsAST, null, nextSpy); + expect(nextSpy).toHaveBeenCalledWith( + 'replace-imports must be passed a file' + ); }); - it('should proceed when the imported file exists', done => { - const plugin = addImports(); - plugin(importsAST, correctFile, done); - }); - - it('should fail when the imported file cannot be found', done => { - expect.assertions(1); - console.error = jest.fn(); + it('should proceed when the imported file exists', async () => { const plugin = addImports(); - // we have to rely on the next callback, because that is how you get error - // messages out of transformers - const next = err => { - if (err) { - expect(console.error).toHaveBeenCalledTimes(2); - done(); - } else { - done('An error should have been thrown by addImports'); - } - }; - plugin(importsAST, incorrectFile, next); + await new Promise(resolve => { + plugin(importsAST, correctFile, resolve); + }); }); - it('should modify the tree when there are imports', done => { + it('should fail when the imported file cannot be found', async () => { + expect.assertions(2); + console.error = vi.fn(); + const plugin = addImports(); + + await expect( + new Promise((resolve, reject) => { + plugin(importsAST, incorrectFile, err => { + if (err) { + expect(console.error).toHaveBeenCalledTimes(2); + resolve(); + } else { + reject('An error should have been thrown by addImports'); + } + }); + }) + ).resolves.toBeUndefined(); + }); + + it('should modify the tree when there are imports', async () => { expect.assertions(1); const plugin = addImports(); - const next = err => { - if (err) { - done(err); - } else { - expect(importsAST).not.toEqual(originalImportsAST); - done(); - } - }; - plugin(importsAST, correctFile, next); + + await new Promise(resolve => { + plugin(importsAST, correctFile, resolve); + }); + + expect(importsAST).not.toEqual(originalImportsAST); }); - it('should NOT modify the tree when there are NO imports', done => { + it('should NOT modify the tree when there are NO imports', async () => { expect.assertions(1); const plugin = addImports(); - const next = err => { - if (err) { - done(err); - } else { - expect(simpleAST).toEqual(originalSimpleAST); - done(); - } - }; - plugin(simpleAST, correctFile, next); + + await new Promise(resolve => { + plugin(simpleAST, correctFile, resolve); + }); + + expect(simpleAST).toEqual(originalSimpleAST); }); - it('should remove all import statements', done => { + it('should remove all import statements', async () => { expect.assertions(2); const selector = 'leafDirective[name=import]'; const plugin = addImports(); @@ -121,19 +118,15 @@ describe('replace-imports', () => { expect(importNodes.length).toBe(1); - const next = err => { - if (err) { - done(err); - } else { - const importNodes = selectAll(selector, importsAST); - expect(importNodes.length).toBe(0); - done(); - } - }; - plugin(importsAST, correctFile, next); + await new Promise(resolve => { + plugin(importsAST, correctFile, resolve); + }); + + const importNodesAfter = selectAll(selector, importsAST); + expect(importNodesAfter.length).toBe(0); }); - it('should not remove an ::import without the required attributes', done => { + it('should not remove an ::import without the required attributes', async () => { expect.assertions(2); const selector = 'leafDirective[name=import]'; const plugin = addImports(); @@ -141,19 +134,15 @@ describe('replace-imports', () => { expect(importNodes.length).toBe(3); - const next = err => { - if (err) { - done(err); - } else { - const importNodes = selectAll(selector, importsExtraAST); - expect(importNodes.length).toBe(1); - done(); - } - }; - plugin(importsExtraAST, correctFile, next); + await new Promise(resolve => { + plugin(importsExtraAST, correctFile, resolve); + }); + + const importNodesAfter = selectAll(selector, importsExtraAST); + expect(importNodesAfter.length).toBe(1); }); - it('should remove all matching ::use statements', done => { + it('should remove all matching ::use statements', async () => { expect.assertions(2); const selector = 'leafDirective[name=use]'; const plugin = addImports(); @@ -162,108 +151,97 @@ describe('replace-imports', () => { // one matching component and two other jsx nodes expect(components.length).toBe(1); - const next = err => { - if (err) { - done(err); - } else { - const components = selectAll(selector, importsAST); - expect(components.length).toBe(0); - done(); - } - }; - plugin(importsAST, correctFile, next); + await new Promise(resolve => { + plugin(importsAST, correctFile, resolve); + }); + + const componentsAfter = selectAll(selector, importsAST); + expect(componentsAfter.length).toBe(0); }); - it('should replace the ::use statement with the imported content', done => { + it('should replace the ::use statement with the imported content', async () => { // checks the contents of script.md are there after the import step expect.assertions(2); const plugin = addImports(); - const next = err => { - if (err) { - done(err); - } else { - const jsNodes = selectAll('code[lang=js]', importsAST); - expect(jsNodes.length).toBe(4); + await new Promise(resolve => { + plugin(importsAST, correctFile, resolve); + }); - const codeValues = jsNodes.map(({ value }) => value); - expect(codeValues).toEqual( - expect.arrayContaining([ - `for (let index = 0; index < array.length; index++) { + const jsNodes = selectAll('code[lang=js]', importsAST); + expect(jsNodes.length).toBe(4); + + const codeValues = jsNodes.map(({ value }) => value); + expect(codeValues).toEqual( + expect.arrayContaining([ + `for (let index = 0; index < array.length; index++) { const element = array[index]; // imported from script.md }` - ]) - ); - done(); - } - }; - plugin(importsAST, correctFile, next); + ]) + ); }); - it('should handle multiple import statements', done => { + it('should handle multiple import statements', async () => { // checks the contents of script.md are there after the import step expect.assertions(4); const plugin = addImports(); - const next = err => { - if (err) { - done(err); - } else { - const jsNodes = selectAll('code[lang=js]', importsTwoAST); - expect(jsNodes.length).toBe(4); + await new Promise(resolve => { + plugin(importsTwoAST, correctFile, resolve); + }); - const codeValues = jsNodes.map(({ value }) => value); - expect(codeValues).toEqual( - expect.arrayContaining([ - `for (let index = 0; index < array.length; index++) { + const jsNodes = selectAll('code[lang=js]', importsTwoAST); + expect(jsNodes.length).toBe(4); + + const codeValues = jsNodes.map(({ value }) => value); + expect(codeValues).toEqual( + expect.arrayContaining([ + `for (let index = 0; index < array.length; index++) { const element = array[index]; // imported from script.md }` - ]) - ); - const cssNodes = selectAll('code[lang=css]', importsTwoAST); - expect(cssNodes.length).toBe(2); + ]) + ); + const cssNodes = selectAll('code[lang=css]', importsTwoAST); + expect(cssNodes.length).toBe(2); - const cssValues = cssNodes.map(({ value }) => value); - expect(cssValues).toEqual( - expect.arrayContaining([ - `div { + const cssValues = cssNodes.map(({ value }) => value); + expect(cssValues).toEqual( + expect.arrayContaining([ + `div { background: red }` - ]) - ); - done(); - } - }; - plugin(importsTwoAST, correctFile, next); + ]) + ); }); - it('should reject imported files with editable region markers', done => { - expect.assertions(1); - console.error = jest.fn(); + it('should reject imported files with editable region markers', async () => { + expect.assertions(2); // One inside the callback and one for the outer expect + console.error = vi.fn(); const plugin = addImports(); - const next = err => { - if (err) { - expect(console.error).toHaveBeenCalledTimes(2); - done(); - } else { - done('An error should have been thrown by addImports'); - } - }; - plugin(markerAST, correctFile, next); + + await expect( + new Promise((resolve, reject) => { + plugin(markerAST, correctFile, err => { + if (err) { + expect(console.error).toHaveBeenCalledTimes(2); + } else { + reject('An error should have been thrown by addImports'); + } + resolve(); + }); + }) + ).resolves.toBeUndefined(); }); - it('should have an output to match the snapshot', done => { + it('should have an output to match the snapshot', async () => { const plugin = addImports(); - const next = err => { - if (err) { - done(err); - } else { - expect(importsAST).toMatchSnapshot(); - done(); - } - }; - plugin(importsAST, correctFile, next); + + await new Promise(resolve => { + plugin(importsAST, correctFile, resolve); + }); + + expect(importsAST).toMatchSnapshot(); }); }); diff --git a/tools/challenge-parser/parser/plugins/restore-directives.test.js b/tools/challenge-parser/parser/plugins/restore-directives.test.js index 1ca664c33eb..4fc332b58d3 100644 --- a/tools/challenge-parser/parser/plugins/restore-directives.test.js +++ b/tools/challenge-parser/parser/plugins/restore-directives.test.js @@ -1,9 +1,10 @@ -const cloneDeep = require('lodash/cloneDeep'); -const find = require('unist-util-find'); -const { selectAll } = require('unist-util-select'); +import { describe, beforeEach, beforeAll, it, expect } from 'vitest'; +import cloneDeep from 'lodash/cloneDeep'; +import find from 'unist-util-find'; +import { selectAll } from 'unist-util-select'; -const parseFixture = require('../__fixtures__/parse-fixture'); -const restoreDirectives = require('./restore-directives'); +import parseFixture from '../__fixtures__/parse-fixture'; +import restoreDirectives from './restore-directives'; describe('restore-directives', () => { let directivesAST, directivesOriginalAST; diff --git a/tools/challenge-parser/parser/plugins/utils/__snapshots__/get-section.test.js.snap b/tools/challenge-parser/parser/plugins/utils/__snapshots__/get-section.test.js.snap index e6519540cc4..120ff36d9ca 100644 --- a/tools/challenge-parser/parser/plugins/utils/__snapshots__/get-section.test.js.snap +++ b/tools/challenge-parser/parser/plugins/utils/__snapshots__/get-section.test.js.snap @@ -1,6 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`getSection should match the hints snapshot 1`] = ` +exports[`getSection > should match the hints snapshot 1`] = ` [ { "children": [ @@ -338,7 +338,7 @@ if(let x of xs) { ] `; -exports[`getSection should match the instructions snapshot 1`] = ` +exports[`getSection > should match the instructions snapshot 1`] = ` [ { "children": [ diff --git a/tools/challenge-parser/parser/plugins/utils/before-heading.test.js b/tools/challenge-parser/parser/plugins/utils/before-heading.test.js index 9441b0d1cdb..e9d5d5bbcc4 100644 --- a/tools/challenge-parser/parser/plugins/utils/before-heading.test.js +++ b/tools/challenge-parser/parser/plugins/utils/before-heading.test.js @@ -1,7 +1,8 @@ -const isArray = require('lodash/isArray'); +import isArray from 'lodash/isArray'; +import { describe, beforeAll, it, expect } from 'vitest'; -const parseFixture = require('../../__fixtures__/parse-fixture'); -const getAllBefore = require('./before-heading'); +import parseFixture from '../../__fixtures__/parse-fixture'; +import getAllBefore from './before-heading'; describe('before-headings', () => { let simpleAst; diff --git a/tools/challenge-parser/parser/plugins/utils/find-all.test.js b/tools/challenge-parser/parser/plugins/utils/find-all.test.js index 5da67f96404..82a772ce392 100644 --- a/tools/challenge-parser/parser/plugins/utils/find-all.test.js +++ b/tools/challenge-parser/parser/plugins/utils/find-all.test.js @@ -1,4 +1,6 @@ -const { findAll } = require('./find-all'); +import { describe, it, expect } from 'vitest'; + +import { findAll } from './find-all'; const testTree = { type: 'root', diff --git a/tools/challenge-parser/parser/plugins/utils/get-file-visitor.test.js b/tools/challenge-parser/parser/plugins/utils/get-file-visitor.test.js deleted file mode 100644 index 75006629ce2..00000000000 --- a/tools/challenge-parser/parser/plugins/utils/get-file-visitor.test.js +++ /dev/null @@ -1,33 +0,0 @@ -describe('get-file-visitor', () => { - it('should join code with newlines', () => { - /* i.e. if you've got two js code blocks it should do this - - ```js - one - ``` - - ```js - two - ``` - - become - - ```js - one - two - ``` - - not - - ```js - onetwo - ``` - or - ```js - - one - two - ``` - */ - }); -}); diff --git a/tools/challenge-parser/parser/plugins/utils/get-id.test.js b/tools/challenge-parser/parser/plugins/utils/get-id.test.js index 15d52e21161..485b959b082 100644 --- a/tools/challenge-parser/parser/plugins/utils/get-id.test.js +++ b/tools/challenge-parser/parser/plugins/utils/get-id.test.js @@ -1,5 +1,7 @@ -const parseFixture = require('../../__fixtures__/parse-fixture'); -const getId = require('./get-id'); +import { describe, beforeAll, it, expect } from 'vitest'; + +import parseFixture from '../../__fixtures__/parse-fixture'; +import getId from './get-id'; describe('get-id', () => { let idNode, imageNode, multipleChildrenNode; diff --git a/tools/challenge-parser/parser/plugins/utils/get-paragraph-content.test.js b/tools/challenge-parser/parser/plugins/utils/get-paragraph-content.test.js index 059c43fe64e..367655caa0a 100644 --- a/tools/challenge-parser/parser/plugins/utils/get-paragraph-content.test.js +++ b/tools/challenge-parser/parser/plugins/utils/get-paragraph-content.test.js @@ -1,5 +1,7 @@ -const parseFixture = require('../../__fixtures__/parse-fixture'); -const { getParagraphContent } = require('./get-paragraph-content'); +import { describe, beforeAll, it, expect } from 'vitest'; + +import parseFixture from '../../__fixtures__/parse-fixture'; +import { getParagraphContent } from './get-paragraph-content'; describe('getParagraphContent', () => { let simpleAST; diff --git a/tools/challenge-parser/parser/plugins/utils/get-section.test.js b/tools/challenge-parser/parser/plugins/utils/get-section.test.js index 40984203ba8..b4b2b286254 100644 --- a/tools/challenge-parser/parser/plugins/utils/get-section.test.js +++ b/tools/challenge-parser/parser/plugins/utils/get-section.test.js @@ -1,9 +1,10 @@ -const isArray = require('lodash/isArray'); -const { root } = require('mdast-builder'); -const find = require('unist-util-find'); +import { describe, beforeAll, it, expect } from 'vitest'; +import isArray from 'lodash/isArray'; +import { root } from 'mdast-builder'; +import find from 'unist-util-find'; -const parseFixture = require('../../__fixtures__/parse-fixture'); -const { getSection } = require('./get-section'); +import parseFixture from '../../__fixtures__/parse-fixture'; +import { getSection } from './get-section'; describe('getSection', () => { let simpleAst, extraHeadingAst; diff --git a/tools/challenge-parser/parser/plugins/utils/mdast-to-html.test.js b/tools/challenge-parser/parser/plugins/utils/mdast-to-html.test.js index f7c19670ff7..4bc9a47673b 100644 --- a/tools/challenge-parser/parser/plugins/utils/mdast-to-html.test.js +++ b/tools/challenge-parser/parser/plugins/utils/mdast-to-html.test.js @@ -1,5 +1,6 @@ -const parseFixture = require('../../__fixtures__/parse-fixture'); -const mdastToHTML = require('./mdast-to-html'); +import { describe, beforeAll, it, expect } from 'vitest'; +import parseFixture from '../../__fixtures__/parse-fixture'; +import mdastToHTML from './mdast-to-html'; describe('mdast-to-html', () => { let mdastMixedNodes, singleNode, inlineHTMLNodes; diff --git a/tools/challenge-parser/parser/plugins/validate-sections.test.js b/tools/challenge-parser/parser/plugins/validate-sections.test.js index bc750848ce2..cf7101ff1a9 100644 --- a/tools/challenge-parser/parser/plugins/validate-sections.test.js +++ b/tools/challenge-parser/parser/plugins/validate-sections.test.js @@ -1,8 +1,10 @@ -const unified = require('unified'); -const remark = require('remark-parse'); -const frontmatter = require('remark-frontmatter'); -const addFrontmatter = require('./add-frontmatter'); -const validateSections = require('./validate-sections'); +import { describe, it, expect } from 'vitest'; +import unified from 'unified'; +import remark from 'remark-parse'; +import frontmatter from 'remark-frontmatter'; + +import addFrontmatter from './add-frontmatter'; +import validateSections from './validate-sections'; const processor = unified() .use(remark) diff --git a/tools/challenge-parser/translation-parser/index.test.js b/tools/challenge-parser/translation-parser/index.test.js index 2dba75a3521..f27ba80a103 100644 --- a/tools/challenge-parser/translation-parser/index.test.js +++ b/tools/challenge-parser/translation-parser/index.test.js @@ -1,18 +1,17 @@ -const { - ENGLISH_CHALLENGE_NO_FILES -} = require('./__fixtures__/challenge-objects'); -const { SIMPLE_TRANSLATION } = require('./__mocks__/mock-comments'); -const { +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; +import { ENGLISH_CHALLENGE_NO_FILES } from './__fixtures__/challenge-objects'; +import { SIMPLE_TRANSLATION } from './__mocks__/mock-comments'; +import { translateComments, translateCommentsInChallenge, translateGeneric -} = require('.'); +} from '.'; let logSpy; describe('translation parser', () => { beforeEach(() => { - logSpy = jest.spyOn(console, 'warn').mockImplementation(); + logSpy = vi.spyOn(console, 'warn').mockImplementation(); }); afterEach(() => { logSpy.mockRestore();