refactor: remove jest and lint vitest (#62330)

This commit is contained in:
Oliver Eyton-Williams
2025-09-24 09:27:03 +02:00
committed by GitHub
parent d96d528e8c
commit 51eba06a7d
25 changed files with 253 additions and 1813 deletions

View File

@@ -97,7 +97,7 @@ describe('Exam Environment mocked Math.random', () => {
describe('generateExam()', () => { describe('generateExam()', () => {
it('should generate a randomized exam without throwing', () => { it('should generate a randomized exam without throwing', () => {
const _randomizedExam = generateExam(exam); expect(() => generateExam(exam)).not.toThrow();
}); });
it('should generate an exam matching with the correct number of question sets', () => { it('should generate an exam matching with the correct number of question sets', () => {
@@ -199,7 +199,9 @@ describe('Exam Environment mocked Math.random', () => {
describe('validateAttempt()', () => { describe('validateAttempt()', () => {
it('should validate a correct attempt', () => { it('should validate a correct attempt', () => {
validateAttempt(generatedExam, examAttempt.questionSets); expect(() =>
validateAttempt(generatedExam, examAttempt.questionSets)
).not.toThrow();
}); });
it('should invalidate an incorrect attempt', () => { it('should invalidate an incorrect attempt', () => {
@@ -422,6 +424,7 @@ describe('Exam Environment Schema', () => {
await fastifyTestInstance.prisma.examEnvironmentExam.deleteMany({}); await fastifyTestInstance.prisma.examEnvironmentExam.deleteMany({});
}); });
// eslint-disable-next-line vitest/expect-expect
it("If this test fails and you've deliberately altered the schema, then increment the `version` field by 1", async () => { it("If this test fails and you've deliberately altered the schema, then increment the `version` field by 1", async () => {
const configQuestionSets = [ const configQuestionSets = [
{ {
@@ -490,6 +493,7 @@ describe('Exam Environment Schema', () => {
{} {}
); );
}); });
// eslint-disable-next-line vitest/expect-expect
it("If this test fails and you've deliberately altered the schema, then increment the `version` field by 1", async () => { it("If this test fails and you've deliberately altered the schema, then increment the `version` field by 1", async () => {
await fastifyTestInstance.prisma.examEnvironmentGeneratedExam.create({ await fastifyTestInstance.prisma.examEnvironmentGeneratedExam.create({
data: { data: {
@@ -508,6 +512,7 @@ describe('Exam Environment Schema', () => {
{} {}
); );
}); });
// eslint-disable-next-line vitest/expect-expect
it("If this test fails and you've deliberately altered the schema, then increment the `version` field by 1", async () => { it("If this test fails and you've deliberately altered the schema, then increment the `version` field by 1", async () => {
await fastifyTestInstance.prisma.examEnvironmentExamAttempt.create({ await fastifyTestInstance.prisma.examEnvironmentExamAttempt.create({
data: { data: {

View File

@@ -138,7 +138,7 @@ describe('errorHandling', () => {
expect(res.statusCode).toEqual(400); expect(res.statusCode).toEqual(400);
}); });
test('should return the error message if the status is not 500 ', async () => { test('should return the error message if the status is not 500', async () => {
const res = await fastify.inject({ const res = await fastify.inject({
method: 'GET', method: 'GET',
url: '/test-bad-request' url: '/test-bad-request'

View File

@@ -670,18 +670,16 @@ Happy coding!
const response = await superPut('/update-my-username').send({ const response = await superPut('/update-my-username').send({
username: 'TwaHa1' username: 'TwaHa1'
}); });
expect(response.body).toStrictEqual({
message: 'flash.username-updated',
type: 'success',
variables: { username: 'TwaHa1' }
});
const user = await fastifyTestInstance.prisma.user.findFirst({ const user = await fastifyTestInstance.prisma.user.findFirst({
where: { email: 'foo@bar.com' } where: { email: 'foo@bar.com' }
}); });
expect(user?.username).toEqual('twaha1'); expect(user?.username).toEqual('twaha1');
expect(response.body).toStrictEqual({
message: 'flash.username-updated',
type: 'success',
variables: { username: 'TwaHa1' }
});
expect(response.statusCode).toEqual(200); expect(response.statusCode).toEqual(200);
}); });
@@ -725,20 +723,6 @@ Happy coding!
expect(existingUser.statusCode).toEqual(400); expect(existingUser.statusCode).toEqual(400);
}); });
test('PUT returns 200 status code with "success" message', async () => {
await superPut('/update-my-username').send({ username: 'twaha3' });
const response = await superPut('/update-my-username').send({
username: 'TWaha3'
});
expect(response.body).toStrictEqual({
message: 'flash.username-updated',
type: 'success',
variables: { username: 'TWaha3' }
});
expect(response.statusCode).toEqual(200);
});
test('PUT /update-my-username returns 400 status code when username is too long', async () => { test('PUT /update-my-username returns 400 status code when username is too long', async () => {
const username = 'a'.repeat(1001); const username = 'a'.repeat(1001);
const response = await superPut('/update-my-username').send({ const response = await superPut('/update-my-username').send({
@@ -899,7 +883,7 @@ Happy coding!
expect(response.statusCode).toEqual(200); expect(response.statusCode).toEqual(200);
}); });
test('PUT with empty strings clears the values in about settings ', async () => { test('PUT with empty strings clears the values in about settings', async () => {
const initialResponse = await superPut('/update-my-about').send({ const initialResponse = await superPut('/update-my-about').send({
about: 'Teacher at freeCodeCamp', about: 'Teacher at freeCodeCamp',
name: 'Quincy Larson', name: 'Quincy Larson',

View File

@@ -205,8 +205,6 @@ export function setupServer(): void {
If you are seeing this error, the root cause is likely an error thrown in the beforeAll hook.`); If you are seeing this error, the root cause is likely an error thrown in the beforeAll hook.`);
await fastifyTestInstance.prisma.$runCommandRaw({ dropDatabase: 1 }); await fastifyTestInstance.prisma.$runCommandRaw({ dropDatabase: 1 });
// Due to a prisma bug, this is not enough, we need to --force-exit jest:
// https://github.com/prisma/prisma/issues/18146
await fastifyTestInstance.close(); await fastifyTestInstance.close();
}); });
} }

View File

@@ -139,7 +139,6 @@
"@total-typescript/ts-reset": "^0.5.0", "@total-typescript/ts-reset": "^0.5.0",
"@types/canvas-confetti": "^1.6.0", "@types/canvas-confetti": "^1.6.0",
"@types/gatsbyjs__reach-router": "1.3.0", "@types/gatsbyjs__reach-router": "1.3.0",
"@types/jest": "29.5.12",
"@types/js-yaml": "4.0.5", "@types/js-yaml": "4.0.5",
"@types/loadable__component": "5.13.8", "@types/loadable__component": "5.13.8",
"@types/lodash-es": "^4.17.6", "@types/lodash-es": "^4.17.6",
@@ -166,7 +165,6 @@
"dotenv": "16.4.5", "dotenv": "16.4.5",
"gatsby-plugin-webpack-bundle-analyser-v2": "1.1.32", "gatsby-plugin-webpack-bundle-analyser-v2": "1.1.32",
"i18next-fs-backend": "2.6.0", "i18next-fs-backend": "2.6.0",
"jest-json-schema-extended": "1.0.1",
"joi": "17.12.2", "joi": "17.12.2",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"monaco-editor-webpack-plugin": "7.0.1", "monaco-editor-webpack-plugin": "7.0.1",

View File

@@ -24,7 +24,7 @@ describe('<Intro />', () => {
it('has no blockquotes when loggedOut', () => { it('has no blockquotes when loggedOut', () => {
renderWithRedux(<Intro {...loggedOutProps} />); renderWithRedux(<Intro {...loggedOutProps} />);
expect(screen.queryByTestId('quote-block')).not.toBeInTheDocument(); expect(screen.queryByTestId('quote-block')).not.toBeInTheDocument();
expect(screen.getByRole('heading', { level: 1 })); expect(screen.getByRole('heading', { level: 1 })).toBeInTheDocument();
}); });
it('has a blockquote when loggedIn', () => { it('has a blockquote when loggedIn', () => {

View File

@@ -33,18 +33,13 @@ describe('createLanguageRedirect for clientLocale === english', () => {
{ lang: 'chinese-traditional', url: chineseTraditionalPageURL }, { lang: 'chinese-traditional', url: chineseTraditionalPageURL },
{ lang: 'dothraki', url: dothrakiPageURL } { lang: 'dothraki', url: dothrakiPageURL }
].forEach(({ lang, url }) => { ].forEach(({ lang, url }) => {
it( it(`should redirect to ${lang} version of page`, () => {
lang === 'english'
? `should redirect to same version of page for lang == english`
: `should redirect to ${lang} version of page`,
() => {
const receivedPageURL = createLanguageRedirect({ const receivedPageURL = createLanguageRedirect({
...envVars, ...envVars,
lang lang
}); });
expect(receivedPageURL).toBe(url); expect(receivedPageURL).toBe(url);
} });
);
}); });
}); });
@@ -70,18 +65,13 @@ describe('createLanguageRedirect for clientLocale === english', () => {
{ lang: 'chinese-traditional', url: chineseTraditionalPageURL }, { lang: 'chinese-traditional', url: chineseTraditionalPageURL },
{ lang: 'dothraki', url: dothrakiPageURL } { lang: 'dothraki', url: dothrakiPageURL }
].forEach(({ lang, url }) => { ].forEach(({ lang, url }) => {
it( it(`should redirect to ${lang} version of page`, () => {
lang === 'english'
? `should redirect to same version of page for lang == english`
: `should redirect to ${lang} version of page`,
() => {
const receivedPageURL = createLanguageRedirect({ const receivedPageURL = createLanguageRedirect({
...envVars, ...envVars,
lang lang
}); });
expect(receivedPageURL).toBe(url); expect(receivedPageURL).toBe(url);
} });
);
}); });
}); });
}); });
@@ -117,18 +107,13 @@ describe('createLanguageRedirect for clientLocale === chinese', () => {
{ lang: 'chinese-traditional', url: chineseTraditionalPageURL }, { lang: 'chinese-traditional', url: chineseTraditionalPageURL },
{ lang: 'dothraki', url: dothrakiPageURL } { lang: 'dothraki', url: dothrakiPageURL }
].forEach(({ lang, url }) => { ].forEach(({ lang, url }) => {
it( it(`should redirect to ${lang} version of page`, () => {
lang === 'chinese'
? `should redirect to same version of page for lang == chinese`
: `should redirect to ${lang} version of page`,
() => {
const receivedPageURL = createLanguageRedirect({ const receivedPageURL = createLanguageRedirect({
...envVars, ...envVars,
lang lang
}); });
expect(receivedPageURL).toBe(url); expect(receivedPageURL).toBe(url);
} });
);
}); });
}); });
@@ -154,18 +139,13 @@ describe('createLanguageRedirect for clientLocale === chinese', () => {
{ lang: 'chinese-traditional', url: chineseTraditionalPageURL }, { lang: 'chinese-traditional', url: chineseTraditionalPageURL },
{ lang: 'dothraki', url: dothrakiPageURL } { lang: 'dothraki', url: dothrakiPageURL }
].forEach(({ lang, url }) => { ].forEach(({ lang, url }) => {
it( it(`should redirect to ${lang} version of page`, () => {
lang === 'chinese'
? `should redirect to same version of page for lang == chinese`
: `should redirect to ${lang} version of page`,
() => {
const receivedPageURL = createLanguageRedirect({ const receivedPageURL = createLanguageRedirect({
...envVars, ...envVars,
lang lang
}); });
expect(receivedPageURL).toBe(url); expect(receivedPageURL).toBe(url);
} });
);
}); });
}); });
}); });

View File

@@ -1,3 +1,6 @@
// All tests use expectSaga which the eslint-plugin-vitest plugin does not
// recognize
/* eslint-disable vitest/expect-expect */
// @vitest-environment jsdom // @vitest-environment jsdom
import { expectSaga } from 'redux-saga-test-plan'; import { expectSaga } from 'redux-saga-test-plan';
import { describe, it, vi } from 'vitest'; import { describe, it, vi } from 'vitest';

View File

@@ -1,3 +1,6 @@
// All tests use expectSaga which the eslint-plugin-vitest plugin does not
// recognize
/* eslint-disable vitest/expect-expect */
import { expectSaga } from 'redux-saga-test-plan'; import { expectSaga } from 'redux-saga-test-plan';
import { describe, it, vi } from 'vitest'; import { describe, it, vi } from 'vitest';

View File

@@ -36,8 +36,7 @@
"update-challenge-order": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/update-challenge-order", "update-challenge-order": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/update-challenge-order",
"update-step-titles": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/update-step-titles", "update-step-titles": "CALLING_DIR=$INIT_CWD tsx --tsconfig ../tsconfig.json ../tools/challenge-helper-scripts/update-step-titles",
"test-gen": "node ./test/utils/generate-block-tests.mjs", "test-gen": "node ./test/utils/generate-block-tests.mjs",
"test": "NODE_OPTIONS='--max-old-space-size=7168' pnpm -s test-gen && vitest -c test/vitest.config.mjs", "test": "NODE_OPTIONS='--max-old-space-size=7168' pnpm -s test-gen && vitest -c test/vitest.config.mjs"
"test:full-output": "NODE_OPTIONS='--max-old-space-size=7168' pnpm -s test-gen && FULL_OUTPUT=true vitest -c test/vitest.config.mjs --reporter=default"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.23.7", "@babel/core": "7.23.7",

View File

@@ -11,7 +11,7 @@ import jsxAllyPlugin from 'eslint-plugin-jsx-a11y';
import prettierConfig from 'eslint-config-prettier'; import prettierConfig from 'eslint-config-prettier';
import reactPlugin from 'eslint-plugin-react'; import reactPlugin from 'eslint-plugin-react';
import testingLibraryPlugin from 'eslint-plugin-testing-library'; import testingLibraryPlugin from 'eslint-plugin-testing-library';
import jestDomPlugin from 'eslint-plugin-jest-dom'; import vitest from '@vitest/eslint-plugin';
import tsParser from '@typescript-eslint/parser'; import tsParser from '@typescript-eslint/parser';
import tseslint from 'typescript-eslint'; import tseslint from 'typescript-eslint';
import jsdoc from 'eslint-plugin-jsdoc'; import jsdoc from 'eslint-plugin-jsdoc';
@@ -62,7 +62,6 @@ export default tseslint.config(
...globals.browser, ...globals.browser,
...globals.mocha, ...globals.mocha,
...globals.node, ...globals.node,
...globals.jest,
Promise: true, Promise: true,
window: true, window: true,
$: true, $: true,
@@ -167,10 +166,12 @@ export default tseslint.config(
{ {
files: ['client/**/*.test.[jt]s?(x)'], files: ['client/**/*.test.[jt]s?(x)'],
extends: [ extends: [testingLibraryPlugin.configs['flat/react']]
testingLibraryPlugin.configs['flat/react'], },
jestDomPlugin.configs['flat/recommended'] {
] files: ['**/*.test.[jt]s?(x)'],
plugins: { vitest },
extends: [vitest.configs.recommended]
}, },
{ {
files: ['e2e/*.ts'], files: ['e2e/*.ts'],

View File

@@ -1,32 +0,0 @@
module.exports = {
testPathIgnorePatterns: [
'/node_modules/',
'api/',
'e2e/',
'tools/challenge-helper-scripts/',
'tools/challenge-parser/',
'tools/scripts/build/',
'tools/scripts/lint/',
'shared',
'curriculum',
'client',
'shared/'
],
moduleNameMapper: {
// CSS Modules - match files that end with 'module.css'
'\\.module\\.css$': 'identity-obj-proxy',
'^lodash-es$': 'lodash'
},
globals: {
__PATH_PREFIX__: ''
},
verbose: true,
transform: {
'^.+\\.[jt]sx?$': '<rootDir>/jest.transform.js'
},
roots: ['.', './client'],
transformIgnorePatterns: ['node_modules/.pnpm/(?!(nanoid|uuid)@)'],
setupFilesAfterEnv: ['./jest.setup.js'],
testEnvironment: 'jsdom',
watchPathIgnorePatterns: ['<rootDir>/__fixtures__.*']
};

View File

@@ -1 +0,0 @@
import '@testing-library/jest-dom';

View File

@@ -1,18 +0,0 @@
const babelOptions = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 18
}
}
],
'@babel/react',
'@babel/preset-typescript'
]
};
// TODO: is there a way to do this without a separate transform? i.e. can we
// just use the existing config?
module.exports = require('babel-jest').default.createTransformer(babelOptions);

View File

@@ -79,9 +79,6 @@
"test:curriculum:tooling": "cd ./curriculum && pnpm vitest run", "test:curriculum:tooling": "cd ./curriculum && pnpm vitest run",
"test:shared": "cd ./shared && pnpm vitest run", "test:shared": "cd ./shared && pnpm vitest run",
"test:client": "cd ./client && pnpm test run", "test:client": "cd ./client && pnpm test run",
"test-curriculum-full-output": "cd ./curriculum && pnpm run test:full-output run",
"test-config": "jest config",
"test-utils": "jest utils",
"prepare": "husky", "prepare": "husky",
"playwright:run": "playwright test", "playwright:run": "playwright test",
"playwright:watch": "playwright test --ui-port=0" "playwright:watch": "playwright test --ui-port=0"
@@ -98,20 +95,18 @@
"@playwright/test": "^1.47.1", "@playwright/test": "^1.47.1",
"@testing-library/dom": "10.4.0", "@testing-library/dom": "10.4.0",
"@testing-library/jest-dom": "6.6.3", "@testing-library/jest-dom": "6.6.3",
"@types/jest": "29.5.12",
"@types/lodash": "4.14.202", "@types/lodash": "4.14.202",
"@types/node": "20.12.8", "@types/node": "20.12.8",
"@types/testing-library__jest-dom": "^5.14.5", "@types/testing-library__jest-dom": "^5.14.5",
"@typescript-eslint/eslint-plugin": "8.24.0", "@typescript-eslint/eslint-plugin": "8.24.0",
"@typescript-eslint/parser": "8.23.0", "@typescript-eslint/parser": "8.23.0",
"babel-jest": "29.7.0", "@vitest/eslint-plugin": "^1.3.12",
"debug": "4.3.4", "debug": "4.3.4",
"eslint": "9.19.0", "eslint": "9.19.0",
"eslint-config-prettier": "10.0.1", "eslint-config-prettier": "10.0.1",
"eslint-import-resolver-typescript": "^3.5.5", "eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-filenames-simple": "0.9.0", "eslint-plugin-filenames-simple": "0.9.0",
"eslint-plugin-import": "2.31.0", "eslint-plugin-import": "2.31.0",
"eslint-plugin-jest-dom": "5.5.0",
"eslint-plugin-jsdoc": "48.2.1", "eslint-plugin-jsdoc": "48.2.1",
"eslint-plugin-jsx-a11y": "6.10.2", "eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-no-only-tests": "3.1.0", "eslint-plugin-no-only-tests": "3.1.0",
@@ -121,8 +116,6 @@
"globals": "^15.14.0", "globals": "^15.14.0",
"husky": "9.0.11", "husky": "9.0.11",
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"js-yaml": "3.14.1", "js-yaml": "3.14.1",
"lint-staged": "^13.1.0", "lint-staged": "^13.1.0",
"lodash": "4.17.21", "lodash": "4.17.21",

1558
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -18,5 +18,4 @@ packages:
packageExtensions: packageExtensions:
'@testing-library/jest-dom': '@testing-library/jest-dom':
peerDependencies: peerDependencies:
jest: '*'
vitest: '*' vitest: '*'

View File

@@ -4,10 +4,7 @@ import { join } from 'path';
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { getFileName } from './get-file-name'; import { getFileName } from './get-file-name';
const basePath = join( const basePath = join(process.cwd(), '__fixtures__');
process.cwd(),
'__fixtures__' + process.env.JEST_WORKER_ID
);
const commonPath = join(basePath, 'curriculum', 'challenges'); const commonPath = join(basePath, 'curriculum', 'challenges');
const block = 'project-get-file-name'; const block = 'project-get-file-name';

View File

@@ -1,118 +1,5 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`challenge parser > it should not parse directives we do not use 1`] = `
{
"assignments": [],
"description": "<section id="description">
<p>:root appears, :import appears</p>
<p>the next paragraph should appear</p>
::import
<p>even though it's an import directive, but if we use the full syntax <code>::directive-name{attr="name" attr2="a/path"}</code></p>
<p>it goes.</p>
<p>::: name [inline-content] {key=val}
a container directive
:::</p>
</section>",
"solutions": [],
"tests": [],
}
`;
exports[`challenge parser > it should parse md with a scene 1`] = `
{
"assignments": [],
"description": "<section id="description">
<p>This challenge has a scene.</p>
</section>",
"scene": {
"commands": [
{
"character": "Maria",
"opacity": 1,
"startTime": 0,
},
{
"character": "Maria",
"dialogue": {
"align": "center",
"text": "I'm Maria, the team lead.",
},
"finishTime": 2.4,
"startTime": 0.7,
},
{
"character": "Maria",
"opacity": 0,
"startTime": 3.4,
},
],
"setup": {
"audio": {
"filename": "1.1-1.mp3",
"finishTimestamp": 4,
"startTime": 1,
"startTimestamp": 2.6,
},
"background": "company2-center.png",
"characters": [
{
"character": "Maria",
"opacity": 0,
"position": {
"x": 50,
"y": 0,
"z": 1.5,
},
},
],
},
},
"solutions": [],
"tests": [],
}
`;
exports[`challenge parser > it should parse video questions 1`] = `
{
"assignments": [],
"description": "<section id="description">
<p>Paragraph 1</p>
<pre><code class="language-html">code example
</code></pre>
</section>",
"instructions": "<section id="instructions">
<p>Paragraph 0</p>
<pre><code class="language-html">code example 0
</code></pre>
</section>",
"questions": [
{
"answers": [
{
"answer": "<p>Some inline <code>code</code></p>",
"feedback": "<p>That is not correct.</p>",
},
{
"answer": "<p>Some <em>italics</em></p>
<p>A second answer paragraph.</p>",
"feedback": null,
},
{
"answer": "<p><code> code in </code> code tags</p>",
"feedback": null,
},
],
"solution": 3,
"text": "<p>Question line 1</p>
<pre><code class="language-js"> var x = 'y';
</code></pre>",
},
],
"solutions": [],
"tests": [],
}
`;
exports[`challenge parser > should import md from other files 1`] = ` exports[`challenge parser > should import md from other files 1`] = `
{ {
"assignments": [], "assignments": [],
@@ -243,6 +130,24 @@ exports[`challenge parser > should not mix other YAML with the frontmatter 1`] =
} }
`; `;
exports[`challenge parser > should not parse directives we do not use 1`] = `
{
"assignments": [],
"description": "<section id="description">
<p>:root appears, :import appears</p>
<p>the next paragraph should appear</p>
::import
<p>even though it's an import directive, but if we use the full syntax <code>::directive-name{attr="name" attr2="a/path"}</code></p>
<p>it goes.</p>
<p>::: name [inline-content] {key=val}
a container directive
:::</p>
</section>",
"solutions": [],
"tests": [],
}
`;
exports[`challenge parser > should parse a more realistic md file 1`] = ` exports[`challenge parser > should parse a more realistic md file 1`] = `
{ {
"assignments": [], "assignments": [],
@@ -710,3 +615,98 @@ if(let x of xs) {
], ],
} }
`; `;
exports[`challenge parser > should parse md with a scene 1`] = `
{
"assignments": [],
"description": "<section id="description">
<p>This challenge has a scene.</p>
</section>",
"scene": {
"commands": [
{
"character": "Maria",
"opacity": 1,
"startTime": 0,
},
{
"character": "Maria",
"dialogue": {
"align": "center",
"text": "I'm Maria, the team lead.",
},
"finishTime": 2.4,
"startTime": 0.7,
},
{
"character": "Maria",
"opacity": 0,
"startTime": 3.4,
},
],
"setup": {
"audio": {
"filename": "1.1-1.mp3",
"finishTimestamp": 4,
"startTime": 1,
"startTimestamp": 2.6,
},
"background": "company2-center.png",
"characters": [
{
"character": "Maria",
"opacity": 0,
"position": {
"x": 50,
"y": 0,
"z": 1.5,
},
},
],
},
},
"solutions": [],
"tests": [],
}
`;
exports[`challenge parser > should parse video questions 1`] = `
{
"assignments": [],
"description": "<section id="description">
<p>Paragraph 1</p>
<pre><code class="language-html">code example
</code></pre>
</section>",
"instructions": "<section id="instructions">
<p>Paragraph 0</p>
<pre><code class="language-html">code example 0
</code></pre>
</section>",
"questions": [
{
"answers": [
{
"answer": "<p>Some inline <code>code</code></p>",
"feedback": "<p>That is not correct.</p>",
},
{
"answer": "<p>Some <em>italics</em></p>
<p>A second answer paragraph.</p>",
"feedback": null,
},
{
"answer": "<p><code> code in </code> code tags</p>",
"feedback": null,
},
],
"solution": 3,
"text": "<p>Question line 1</p>
<pre><code class="language-js"> var x = 'y';
</code></pre>",
},
],
"solutions": [],
"tests": [],
}
`;

View File

@@ -45,21 +45,21 @@ describe('challenge parser', () => {
expect(parsed).toMatchSnapshot(); expect(parsed).toMatchSnapshot();
}); });
it('it should parse video questions', async () => { it('should parse video questions', async () => {
const parsed = await parseMD( const parsed = await parseMD(
resolve(__dirname, '__fixtures__/with-video-question.md') resolve(__dirname, '__fixtures__/with-video-question.md')
); );
expect(parsed).toMatchSnapshot(); expect(parsed).toMatchSnapshot();
}); });
it('it should not parse directives we do not use', async () => { it('should not parse directives we do not use', async () => {
const parsed = await parseMD( const parsed = await parseMD(
resolve(__dirname, '__fixtures__/with-directives.md') resolve(__dirname, '__fixtures__/with-directives.md')
); );
expect(parsed).toMatchSnapshot(); expect(parsed).toMatchSnapshot();
}); });
it('it should parse md with a scene', async () => { it('should parse md with a scene', async () => {
const parsed = await parseMD(resolve(__dirname, '__fixtures__/scene.md')); const parsed = await parseMD(resolve(__dirname, '__fixtures__/scene.md'));
expect(parsed).toMatchSnapshot(); expect(parsed).toMatchSnapshot();
}); });

View File

@@ -272,29 +272,6 @@ const Button = () => {
};`); };`);
}); });
/* Revisit this once we've decided what to do about multifile imports. I
think the best approach is likely to be use the following format for .files
it('combines all the code of a specific language into a single file', () => {
{ css: [css files],
html: [html files],
...
}
or
{ css: {css files},
html: {html files},
...
}
depending on what's easier to work with in graphQL
});
*/
it('should throw an error if a seed has no contents', () => { it('should throw an error if a seed has no contents', () => {
expect.assertions(1); expect.assertions(1);
expect(() => plugin(withEmptyContentsAST, file)).toThrow( expect(() => plugin(withEmptyContentsAST, file)).toThrow(

View File

@@ -64,9 +64,11 @@ describe('replace-imports', () => {
it('should proceed when the imported file exists', async () => { it('should proceed when the imported file exists', async () => {
const plugin = addImports(); const plugin = addImports();
await new Promise(resolve => { await expect(
new Promise(resolve => {
plugin(importsAST, correctFile, resolve); plugin(importsAST, correctFile, resolve);
}); })
).resolves.toBeUndefined();
}); });
it('should fail when the imported file cannot be found', async () => { it('should fail when the imported file cannot be found', async () => {

View File

@@ -44,9 +44,9 @@ describe('external curriculum data build', () => {
}); });
test('there should be an endpoint to request submit types from', () => { test('there should be an endpoint to request submit types from', () => {
fs.existsSync( expect(
`${clientStaticPath}/curriculum-data/${VERSION}/submit-types.json` fs.existsSync(`${clientStaticPath}/curriculum-data/submit-types.json`)
); ).toBeTruthy();
}); });
test('the available-superblocks file should have the correct structure', async () => { test('the available-superblocks file should have the correct structure', async () => {
@@ -60,12 +60,8 @@ describe('external curriculum data build', () => {
const result = validateAvailableSuperBlocks(availableSuperblocks); const result = validateAvailableSuperBlocks(availableSuperblocks);
if (result.error) { expect(result.error?.details).toBeUndefined();
throw Error( expect(result.error).toBeFalsy();
`file: available-superblocks.json
${result.error.message}`
);
}
}); });
test('the super block files generated should have the correct schema', async () => { test('the super block files generated should have the correct schema', async () => {
@@ -93,10 +89,8 @@ ${result.error.message}`
const result = validateSuperBlock(JSON.parse(fileContent)); const result = validateSuperBlock(JSON.parse(fileContent));
if (result.error) { expect(result.error?.details).toBeUndefined();
throw Error(`file: ${fileInArray} expect(result.error).toBeFalsy();
${result.error.message}`);
}
}); });
}); });

View File

@@ -82,12 +82,8 @@ describe('external curriculum data build', () => {
expect.arrayContaining(filteredSuperBlockStages) expect.arrayContaining(filteredSuperBlockStages)
); );
if (result.error) { expect(result.error?.details).toBeUndefined();
throw Error( expect(result.error).toBeFalsy();
`file: available-superblocks.json
${result.error.message}`
);
}
}); });
test('the super block files generated should have the correct schema', async () => { test('the super block files generated should have the correct schema', async () => {
@@ -118,10 +114,8 @@ ${result.error.message}`
const result = validateSuperBlock(JSON.parse(fileContent)); const result = validateSuperBlock(JSON.parse(fileContent));
if (result.error) { expect(result.error?.details).toBeUndefined();
throw Error(`file: ${fileInArray} expect(result.error).toBeFalsy();
${result.error.message}`);
}
}); });
}); });

View File

@@ -14,6 +14,6 @@
"noEmit": true, "noEmit": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"skipLibCheck": true, "skipLibCheck": true,
"types": ["node", "jest"] "types": ["node"]
} }
} }