From f613a1e5fda1e79e860c9b0792c3339664b9a27c Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Fri, 3 Dec 2021 21:32:29 +0100 Subject: [PATCH] fix: index.css/js to styles/script (#44356) * fix: replace index with script/styles as needed * fix: remove redundant fileKey It's overwritten by createPoly, so the parser does not need to create it * fix: curriculum test suite * Update client/src/templates/Challenges/classic/MultifileEditor.js Co-authored-by: Shaun Hamilton Co-authored-by: Shaun Hamilton --- client/src/redux/prop-types.ts | 2 +- .../Challenges/classic/MultifileEditor.js | 11 ++- .../Challenges/rechallenge/transformers.js | 4 +- .../src/templates/Challenges/utils/build.js | 11 +-- curriculum/test/test-challenges.js | 6 +- .../index.acceptance.test.js.snap | 63 ++++---------- .../__snapshots__/add-seed.test.js.snap | 7 +- .../__snapshots__/add-solution.test.js.snap | 7 +- .../parser/plugins/add-seed.js | 1 - .../parser/plugins/add-seed.test.js | 87 +++++++++---------- .../parser/plugins/add-solution.test.js | 32 +++---- .../parser/plugins/utils/get-file-visitor.js | 23 +++-- utils/__fixtures__/challenges.js | 16 ++-- utils/sort-challengefiles.test.js | 2 +- 14 files changed, 115 insertions(+), 157 deletions(-) diff --git a/client/src/redux/prop-types.ts b/client/src/redux/prop-types.ts index e6a46dfb7d..1bc7bfb999 100644 --- a/client/src/redux/prop-types.ts +++ b/client/src/redux/prop-types.ts @@ -297,7 +297,7 @@ export type CompletedChallenge = { }; export type Ext = 'js' | 'html' | 'css' | 'jsx'; -export type FileKey = 'indexjs' | 'indexhtml' | 'indexcss'; +export type FileKey = 'scriptjs' | 'indexhtml' | 'stylescss'; export type ChallengeMeta = { block: string; diff --git a/client/src/templates/Challenges/classic/MultifileEditor.js b/client/src/templates/Challenges/classic/MultifileEditor.js index 77a542758d..96f426d6f6 100644 --- a/client/src/templates/Challenges/classic/MultifileEditor.js +++ b/client/src/templates/Challenges/classic/MultifileEditor.js @@ -40,14 +40,13 @@ const propTypes = { saveEditorContent: PropTypes.func.isRequired, setEditorFocusability: PropTypes.func, theme: PropTypes.string, - // TODO: is this used? title: PropTypes.string, updateFile: PropTypes.func.isRequired, usesMultifileEditor: PropTypes.bool, visibleEditors: PropTypes.shape({ - indexjs: PropTypes.bool, + scriptjs: PropTypes.bool, indexjsx: PropTypes.bool, - indexcss: PropTypes.bool, + stylescss: PropTypes.bool, indexhtml: PropTypes.bool }) }; @@ -83,7 +82,7 @@ const MultifileEditor = props => { theme, resizeProps, title, - visibleEditors: { indexcss, indexhtml, indexjs, indexjsx }, + visibleEditors: { stylescss, indexhtml, scriptjs, indexjsx }, usesMultifileEditor } = props; const editorTheme = theme === 'night' ? 'vs-dark-custom' : 'vs-custom'; @@ -105,8 +104,8 @@ const MultifileEditor = props => { if (indexjsx) editorKeys.push('indexjsx'); if (indexhtml) editorKeys.push('indexhtml'); - if (indexcss) editorKeys.push('indexcss'); - if (indexjs) editorKeys.push('indexjs'); + if (stylescss) editorKeys.push('stylescss'); + if (scriptjs) editorKeys.push('scriptjs'); const editorAndSplitterKeys = editorKeys.reduce((acc, key) => { if (acc.length === 0) { diff --git a/client/src/templates/Challenges/rechallenge/transformers.js b/client/src/templates/Challenges/rechallenge/transformers.js index ba1a5d2cdb..eb25b6e6ae 100644 --- a/client/src/templates/Challenges/rechallenge/transformers.js +++ b/client/src/templates/Challenges/rechallenge/transformers.js @@ -227,11 +227,11 @@ const transformIncludes = async function (fileP) { div.querySelector('script[src="./script.js"]'); const importedFiles = []; if (link) { - importedFiles.push('index.css'); + importedFiles.push('styles.css'); link.remove(); } if (script) { - importedFiles.push('index.js'); + importedFiles.push('script.js'); script.remove(); } diff --git a/client/src/templates/Challenges/utils/build.js b/client/src/templates/Challenges/utils/build.js index 08ef7aa3f0..fbc9a318c2 100644 --- a/client/src/templates/Challenges/utils/build.js +++ b/client/src/templates/Challenges/utils/build.js @@ -51,17 +51,10 @@ const composeFunctions = (...fns) => fns.map(applyFunction).reduce((f, g) => x => f(x).then(g)); function buildSourceMap(challengeFiles) { - // TODO: concatenating the source/contents is a quick hack for multi-file - // editing. It is used because all the files (js, html and css) end up with - // the same name 'index'. This made the last file the only file to appear in - // sources. - // A better solution is to store and handle them separately. Perhaps never - // setting the name to 'index'. Use 'contents' instead? - // TODO: is file.source ever defined? + // TODO: rename sources.index to sources.contents. const source = challengeFiles.reduce( (sources, challengeFile) => { - sources[challengeFile.name] += - challengeFile.source || challengeFile.contents; + sources.index += challengeFile.source || challengeFile.contents; sources.editableContents += challengeFile.editableContents || ''; return sources; }, diff --git a/curriculum/test/test-challenges.js b/curriculum/test/test-challenges.js index 283f187529..03815e5812 100644 --- a/curriculum/test/test-challenges.js +++ b/curriculum/test/test-challenges.js @@ -459,7 +459,9 @@ ${inspect(commentMap)} challengeFile.editableContents = getLines( challengeFile.contents, challenge.challengeFiles.find( - x => x.fileKey === challengeFile.fileKey + x => + x.ext === challengeFile.ext && + x.name === challengeFile.name ).editableRegionBoundaries ); }); @@ -523,7 +525,7 @@ async function createTestRunner( const challengeFiles = cloneDeep(challenge.challengeFiles); solutionFiles.forEach(solutionFile => { const challengeFile = challengeFiles.find( - x => x.fileKey === solutionFile.fileKey + x => x.ext === solutionFile.ext && x.name === solutionFile.name ); challengeFile.contents = solutionFile.contents; challengeFile.editableContents = solutionFile.editableContents; 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 292a0ec53a..40a3996a3d 100644 --- a/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap +++ b/tools/challenge-parser/parser/__snapshots__/index.acceptance.test.js.snap @@ -60,7 +60,6 @@ Object { ", "editableRegionBoundaries": Array [], "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "", "name": "index", @@ -72,10 +71,9 @@ Object { }", "editableRegionBoundaries": Array [], "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { @@ -86,10 +84,9 @@ for (let index = 0; index < array.length; index++) { }", "editableRegionBoundaries": Array [], "ext": "js", - "fileKey": "indexjs", "head": "", "id": "custom-name", - "name": "index", + "name": "script", "tail": "", }, ], @@ -129,7 +126,6 @@ Object { ", "editableRegionBoundaries": Array [], "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "", "name": "index", @@ -141,20 +137,18 @@ Object { }", "editableRegionBoundaries": Array [], "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y';", "editableRegionBoundaries": Array [], "ext": "js", - "fileKey": "indexjs", "head": "", "id": "", - "name": "index", + "name": "script", "tail": "", }, ], @@ -222,7 +216,6 @@ Object { 23, ], "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "html-key", "name": "index", @@ -246,20 +239,18 @@ a { 9, ], "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y';", "editableRegionBoundaries": Array [], "ext": "js", - "fileKey": "indexjs", "head": " // this runs before the user's code is evaluated.", "id": "final-key", - "name": "index", + "name": "script", "tail": "", }, ], @@ -307,7 +298,6 @@ a { ", "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "html-key", "name": "index", @@ -327,19 +317,17 @@ a { color: green; }", "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y';", "ext": "js", - "fileKey": "indexjs", "head": "", "id": "final-key", - "name": "index", + "name": "script", "tail": "", }, ], @@ -393,7 +381,6 @@ Object { ", "editableRegionBoundaries": Array [], "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "", "name": "index", @@ -405,20 +392,18 @@ Object { }", "editableRegionBoundaries": Array [], "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y';", "editableRegionBoundaries": Array [], "ext": "js", - "fileKey": "indexjs", "head": "", "id": "", - "name": "index", + "name": "script", "tail": "", }, ], @@ -440,7 +425,6 @@ Object { ", "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "html-key", "name": "index", @@ -451,20 +435,18 @@ Object { background: white; }", "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y'; \`\`", "ext": "js", - "fileKey": "indexjs", "head": "", "id": "", - "name": "index", + "name": "script", "tail": "", }, ], @@ -499,7 +481,6 @@ Object { ", "editableRegionBoundaries": Array [], "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "", "name": "index", @@ -511,20 +492,18 @@ Object { }", "editableRegionBoundaries": Array [], "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y';", "editableRegionBoundaries": Array [], "ext": "js", - "fileKey": "indexjs", "head": "", "id": "", - "name": "index", + "name": "script", "tail": "", }, ], @@ -565,7 +544,6 @@ Object { ", "editableRegionBoundaries": Array [], "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "", "name": "index", @@ -577,20 +555,18 @@ Object { }", "editableRegionBoundaries": Array [], "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y';", "editableRegionBoundaries": Array [], "ext": "js", - "fileKey": "indexjs", "head": "", "id": "", - "name": "index", + "name": "script", "tail": "", }, ], @@ -626,7 +602,6 @@ Object { ", "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "html-key", "name": "index", @@ -637,20 +612,18 @@ Object { background: white; }", "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y'; \`\`", "ext": "js", - "fileKey": "indexjs", "head": "", "id": "", - "name": "index", + "name": "script", "tail": "", }, ], 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 c62776dd8e..e406f31a81 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 @@ -10,7 +10,6 @@ Object { ", "editableRegionBoundaries": Array [], "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "", "name": "index", @@ -22,20 +21,18 @@ Object { }", "editableRegionBoundaries": Array [], "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y';", "editableRegionBoundaries": Array [], "ext": "js", - "fileKey": "indexjs", "head": "", "id": "", - "name": "index", + "name": "script", "tail": "", }, ], 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 7df32888d3..1887744ea1 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 @@ -10,7 +10,6 @@ Object { ", "ext": "html", - "fileKey": "indexhtml", "head": "", "id": "html-key", "name": "index", @@ -21,20 +20,18 @@ Object { background: white; }", "ext": "css", - "fileKey": "indexcss", "head": "", "id": "", - "name": "index", + "name": "styles", "tail": "", }, Object { "contents": "var x = 'y'; \`\`", "ext": "js", - "fileKey": "indexjs", "head": "", "id": "", - "name": "index", + "name": "script", "tail": "", }, ], diff --git a/tools/challenge-parser/parser/plugins/add-seed.js b/tools/challenge-parser/parser/plugins/add-seed.js index da016291d9..564ebb5c07 100644 --- a/tools/challenge-parser/parser/plugins/add-seed.js +++ b/tools/challenge-parser/parser/plugins/add-seed.js @@ -2,7 +2,6 @@ const { isEmpty } = require('lodash'); const { root } = require('mdast-builder'); const visitChildren = require('unist-util-visit-children'); const getAllBetween = require('./utils/between-headings'); -// const visit = require('unist-util-visit'); const { getFileVisitor } = require('./utils/get-file-visitor'); const editableRegionMarker = '--fcc-editable-region--'; diff --git a/tools/challenge-parser/parser/plugins/add-seed.test.js b/tools/challenge-parser/parser/plugins/add-seed.test.js index 7c91a69479..d4051cb39e 100644 --- a/tools/challenge-parser/parser/plugins/add-seed.test.js +++ b/tools/challenge-parser/parser/plugins/add-seed.test.js @@ -42,15 +42,13 @@ describe('add-seed plugin', () => { }); it('adds test objects to the challengeFiles array following a schema', () => { - expect.assertions(17); + expect.assertions(15); plugin(simpleAST, file); const { data: { challengeFiles } } = file; - const testObject = challengeFiles.find(x => x.fileKey === 'indexjs'); - expect(Object.keys(testObject).length).toEqual(8); - expect(testObject).toHaveProperty('fileKey'); - expect(typeof testObject['fileKey']).toBe('string'); + const testObject = challengeFiles.find(x => x.ext === 'js'); + expect(Object.keys(testObject).length).toEqual(7); expect(testObject).toHaveProperty('ext'); expect(typeof testObject['ext']).toBe('string'); expect(testObject).toHaveProperty('name'); @@ -73,16 +71,16 @@ describe('add-seed plugin', () => { const { data: { challengeFiles } } = file; - const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs'); - const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml'); - const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss'); + const scriptjs = challengeFiles.find(x => x.ext === 'js'); + const indexhtml = challengeFiles.find(x => x.ext === 'html'); + const stylescss = challengeFiles.find(x => x.ext === 'css'); - expect(indexjs.contents).toBe(`var x = 'y';`); + expect(scriptjs.contents).toBe(`var x = 'y';`); expect(indexhtml.contents).toBe(` `); - expect(indexcss.contents).toBe(`body { + expect(stylescss.contents).toBe(`body { background: green; }`); }); @@ -93,10 +91,10 @@ describe('add-seed plugin', () => { const { data: { challengeFiles } } = file; - const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss'); + const stylescss = challengeFiles.find(x => x.ext === 'css'); - expect(indexcss.contents).not.toMatch('--fcc-editable-region--'); - expect(indexcss.editableRegionBoundaries).toEqual([1, 4]); + expect(stylescss.contents).not.toMatch('--fcc-editable-region--'); + expect(stylescss.editableRegionBoundaries).toEqual([1, 4]); }); // TODO: can we reuse 'name'? It's always 'index', I think, which suggests @@ -107,13 +105,13 @@ describe('add-seed plugin', () => { const { data: { challengeFiles } } = file; - const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs'); - const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml'); - const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss'); + const scriptjs = challengeFiles.find(x => x.ext === 'js'); + const indexhtml = challengeFiles.find(x => x.ext === 'html'); + const stylescss = challengeFiles.find(x => x.ext === 'css'); expect(indexhtml.id).toBe(''); - expect(indexcss.id).toBe('key-for-css'); - expect(indexjs.id).toBe('key-for-js'); + expect(stylescss.id).toBe('key-for-css'); + expect(scriptjs.id).toBe('key-for-js'); }); it('throws if an id is anywhere except directly before a code node', () => { @@ -140,13 +138,13 @@ describe('add-seed plugin', () => { const { data: { challengeFiles } } = file; - const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs'); - const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml'); - const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss'); + const scriptjs = challengeFiles.find(x => x.ext === 'js'); + const indexhtml = challengeFiles.find(x => x.ext === 'html'); + const stylescss = challengeFiles.find(x => x.ext === 'css'); - expect(indexjs.head).toBe(''); + expect(scriptjs.head).toBe(''); expect(indexhtml.head).toBe(``); - expect(indexcss.head).toBe(`body { + expect(stylescss.head).toBe(`body { etc: '' }`); }); @@ -157,15 +155,15 @@ describe('add-seed plugin', () => { const { data: { challengeFiles } } = file; - const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs'); - const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml'); - const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss'); + const scriptjs = challengeFiles.find(x => x.ext === 'js'); + const indexhtml = challengeFiles.find(x => x.ext === 'html'); + const stylescss = challengeFiles.find(x => x.ext === 'css'); - expect(indexjs.tail).toBe(`function teardown(params) { + expect(scriptjs.tail).toBe(`function teardown(params) { // after }`); expect(indexhtml.tail).toBe(''); - expect(indexcss.tail).toBe(`body { + expect(stylescss.tail).toBe(`body { background: blue; }`); }); @@ -194,16 +192,16 @@ describe('add-seed plugin', () => { const { data: { challengeFiles } } = file; - const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs'); - const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml'); - const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss'); + const scriptjs = challengeFiles.find(x => x.ext === 'js'); + const indexhtml = challengeFiles.find(x => x.ext === 'html'); + const stylescss = challengeFiles.find(x => x.ext === 'css'); - expect(indexjs.head).toBe(''); - expect(indexjs.tail).toBe('function teardown(params) {\n // after\n}'); + expect(scriptjs.head).toBe(''); + expect(scriptjs.tail).toBe('function teardown(params) {\n // after\n}'); expect(indexhtml.head).toBe(''); expect(indexhtml.tail).toBe(''); - expect(indexcss.head).toBe(''); - expect(indexcss.tail).toBe('body {\n background: blue;\n}'); + expect(stylescss.head).toBe(''); + expect(stylescss.tail).toBe('body {\n background: blue;\n}'); }); it('quietly ignores empty after sections', () => { @@ -212,16 +210,16 @@ describe('add-seed plugin', () => { const { data: { challengeFiles } } = file; - const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs'); - const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml'); - const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss'); + const scriptjs = challengeFiles.find(x => x.ext === 'js'); + const indexhtml = challengeFiles.find(x => x.ext === 'html'); + const stylescss = challengeFiles.find(x => x.ext === 'css'); - expect(indexjs.head).toBe(''); - expect(indexjs.tail).toBe(''); + expect(scriptjs.head).toBe(''); + expect(scriptjs.tail).toBe(''); expect(indexhtml.head).toBe(''); expect(indexhtml.tail).toBe(''); - expect(indexcss.head).toBe("body {\n etc: ''\n}"); - expect(indexcss.tail).toBe(''); + expect(stylescss.head).toBe("body {\n etc: ''\n}"); + expect(stylescss.tail).toBe(''); }); it('throws an error (with line number) if 2 markers appear on 1 line', () => { @@ -239,12 +237,12 @@ describe('add-seed plugin', () => { }); it('handles jsx', () => { - expect.assertions(4); + expect.assertions(3); plugin(jsxSeedAST, file); const { data: { challengeFiles } } = file; - const indexjsx = challengeFiles.find(x => x.fileKey === 'indexjsx'); + const indexjsx = challengeFiles.find(x => x.ext === 'jsx'); expect(indexjsx.head).toBe(`function setup() {}`); expect(indexjsx.tail).toBe(`function teardown(params) { @@ -256,7 +254,6 @@ describe('add-seed plugin', () => { const Button = () => { return ; };`); - expect(indexjsx.fileKey).toBe(`indexjsx`); }); it('combines all the code of a specific language into a single file', () => { diff --git a/tools/challenge-parser/parser/plugins/add-solution.test.js b/tools/challenge-parser/parser/plugins/add-solution.test.js index 522deb2386..ced1c59860 100644 --- a/tools/challenge-parser/parser/plugins/add-solution.test.js +++ b/tools/challenge-parser/parser/plugins/add-solution.test.js @@ -34,17 +34,13 @@ describe('add solution plugin', () => { }); it('adds solution objects to the challengeFiles array following a schema', () => { - expect.assertions(15); + expect.assertions(13); plugin(mockAST, file); const { data: { solutions } } = file; - const testObject = solutions[0].find( - solution => solution.fileKey === 'indexjs' - ); - expect(Object.keys(testObject).length).toEqual(7); - expect(testObject).toHaveProperty('fileKey'); - expect(typeof testObject['fileKey']).toBe('string'); + const testObject = solutions[0].find(solution => solution.ext === 'js'); + expect(Object.keys(testObject).length).toEqual(6); expect(testObject).toHaveProperty('ext'); expect(typeof testObject['ext']).toBe('string'); expect(testObject).toHaveProperty('name'); @@ -66,24 +62,22 @@ describe('add solution plugin', () => { data: { solutions } } = file; expect(solutions.length).toBe(3); - expect( - solutions[0].find(solution => solution.fileKey === 'indexjs').contents - ).toBe("var x = 'y';"); - expect( - solutions[1].find(solution => solution.fileKey === 'indexhtml').contents - ).toBe(` + expect(solutions[0].find(solution => solution.ext === 'js').contents).toBe( + "var x = 'y';" + ); + expect(solutions[1].find(solution => solution.ext === 'html').contents) + .toBe(` solution number two `); - expect( - solutions[1].find(solution => solution.fileKey === 'indexcss').contents - ).toBe(`body { + expect(solutions[1].find(solution => solution.ext === 'css').contents) + .toBe(`body { background: white; }`); - expect( - solutions[2].find(solution => solution.fileKey === 'indexjs').contents - ).toBe("var x = 'y3';"); + expect(solutions[2].find(solution => solution.ext === 'js').contents).toBe( + "var x = 'y3';" + ); }); it('should reject solutions with editable region markers', () => { diff --git a/tools/challenge-parser/parser/plugins/utils/get-file-visitor.js b/tools/challenge-parser/parser/plugins/utils/get-file-visitor.js index 920d41d15c..1ea029e7ac 100644 --- a/tools/challenge-parser/parser/plugins/utils/get-file-visitor.js +++ b/tools/challenge-parser/parser/plugins/utils/get-file-visitor.js @@ -12,9 +12,8 @@ const supportedLanguages = ['js', 'css', 'html', 'jsx', 'py']; function defaultFile(lang, id) { return { - fileKey: `index${lang}`, ext: lang, - name: 'index', + name: getFilenames(lang), contents: '', head: '', tail: '', @@ -22,6 +21,14 @@ function defaultFile(lang, id) { }; } +function getFilenames(lang) { + const langToFilename = { + js: 'script', + css: 'styles' + }; + return langToFilename[lang] ?? 'index'; +} + function getFileVisitor(seeds, seedKey, validate) { return (node, index, parent) => { if (is(node, 'root')) return; @@ -43,21 +50,21 @@ function codeToData(node, seeds, seedKey, validate) { Please use one of js, css, html, jsx or py `); - const fileKey = `index${lang}`; - const id = seeds[fileKey] ? seeds[fileKey].id : ''; + const fileId = `index${lang}`; + const id = seeds[fileId] ? seeds[fileId].id : ''; // the contents will be missing if there is an id preceding this code // block. - if (!seeds[fileKey]) { - seeds[fileKey] = defaultFile(lang, id); + if (!seeds[fileId]) { + seeds[fileId] = defaultFile(lang, id); } if (isEmpty(node.value) && seedKey !== 'contents') { const section = keyToSection[seedKey]; throw Error(`Empty code block in --${section}-- section`); } - seeds[fileKey][seedKey] = isEmpty(seeds[fileKey][seedKey]) + seeds[fileId][seedKey] = isEmpty(seeds[fileId][seedKey]) ? node.value - : seeds[fileKey][seedKey] + '\n' + node.value; + : seeds[fileId][seedKey] + '\n' + node.value; } function idToData(node, index, parent, seeds) { diff --git a/utils/__fixtures__/challenges.js b/utils/__fixtures__/challenges.js index e4dab4e37a..5d9c0e75b6 100644 --- a/utils/__fixtures__/challenges.js +++ b/utils/__fixtures__/challenges.js @@ -4,10 +4,10 @@ exports.challengeFiles = [ error: null, ext: 'css', head: '', - history: ['index.css'], - fileKey: 'indexcss', - name: 'index', - path: 'index.css', + history: ['styles.css'], + fileKey: 'stylescss', + name: 'styles', + path: 'styles.css', seed: 'some css', tail: '' }, @@ -28,10 +28,10 @@ exports.challengeFiles = [ error: null, ext: 'js', head: '', - history: ['index.js'], - fileKey: 'indexjs', - name: 'index', - path: 'index.js', + history: ['script.js'], + fileKey: 'scriptjs', + name: 'script', + path: 'script.js', seed: 'some js', tail: '' }, diff --git a/utils/sort-challengefiles.test.js b/utils/sort-challengefiles.test.js index 94d9b8ad03..9c717ff739 100644 --- a/utils/sort-challengefiles.test.js +++ b/utils/sort-challengefiles.test.js @@ -17,7 +17,7 @@ describe('sort-files', () => { it('should sort the objects into html, css, jsx, js order', () => { const sorted = sortChallengeFiles(challengeFiles); const sortedKeys = sorted.map(({ fileKey }) => fileKey); - const expected = ['indexhtml', 'indexcss', 'indexjsx', 'indexjs']; + const expected = ['indexhtml', 'stylescss', 'indexjsx', 'scriptjs']; expect(sortedKeys).toStrictEqual(expected); }); });