From cacc4eacd7df75a47df123d98217d46816a1bb8e Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Mon, 24 Jan 2022 19:42:27 +0100 Subject: [PATCH] fix: handle the sorting of transformed files (#44724) * fix: handle the sorting of transformed files We can't use the ext property, since that is transformed, but the history is maintained. * test: make solutions polyVinyls for sorting * refactor: inline prepareChallenge * refactor: make solutions polys in getChallenges * fix: convert each solution to a poly * fix: skip empty solutions * fix: get challenge file history in client * refactor: stop calling isPoly from the client * fix: remove debug console.log * refactor: remove unnecessary sorting step --- client/gatsby-node.js | 2 + .../src/templates/Challenges/classic/show.tsx | 1 + .../src/templates/Challenges/redux/index.js | 4 +- client/utils/gatsby/challenge-page-creator.js | 11 ++---- curriculum/getChallenges.js | 38 ++++++++++--------- curriculum/test/test-challenges.js | 5 +-- utils/sort-challengefiles.js | 18 ++++----- 7 files changed, 37 insertions(+), 42 deletions(-) diff --git a/client/gatsby-node.js b/client/gatsby-node.js index 2177a095b5..008208d441 100644 --- a/client/gatsby-node.js +++ b/client/gatsby-node.js @@ -95,10 +95,12 @@ exports.createPages = function createPages({ graphql, actions, reporter }) { contents head tail + history } solutions { contents ext + history } superBlock superOrder diff --git a/client/src/templates/Challenges/classic/show.tsx b/client/src/templates/Challenges/classic/show.tsx index a12d9995f2..e5ce1c4567 100644 --- a/client/src/templates/Challenges/classic/show.tsx +++ b/client/src/templates/Challenges/classic/show.tsx @@ -547,6 +547,7 @@ export const query = graphql` head tail editableRegionBoundaries + history } } } diff --git a/client/src/templates/Challenges/redux/index.js b/client/src/templates/Challenges/redux/index.js index 28218d68df..2338732bcf 100644 --- a/client/src/templates/Challenges/redux/index.js +++ b/client/src/templates/Challenges/redux/index.js @@ -2,7 +2,6 @@ import { isEmpty } from 'lodash-es'; import { createAction, handleActions } from 'redux-actions'; import { getLines } from '../../../../../utils/get-lines'; -import { createPoly } from '../../../../../utils/polyvinyl'; import { challengeTypes } from '../../../../utils/challenge-types'; import { completedChallengesSelector } from '../../../redux'; import { getTargetEditor } from '../utils/getTargetEditor'; @@ -58,12 +57,11 @@ export const sagas = [ ...createCurrentChallengeSaga(actionTypes) ]; -// TODO: can createPoly handle editable region, rather than separating it? export const createFiles = createAction( actionTypes.createFiles, challengeFiles => challengeFiles.map(challengeFile => ({ - ...createPoly(challengeFile), + ...challengeFile, seed: challengeFile.contents.slice(), editableContents: getLines( challengeFile.contents, diff --git a/client/utils/gatsby/challenge-page-creator.js b/client/utils/gatsby/challenge-page-creator.js index 463449980a..adcbd18811 100644 --- a/client/utils/gatsby/challenge-page-creator.js +++ b/client/utils/gatsby/challenge-page-creator.js @@ -1,5 +1,4 @@ const path = require('path'); -const { createPoly } = require('../../../utils/polyvinyl'); const { dasherize } = require('../../../utils/slugs'); const { sortChallengeFiles } = require('../../../utils/sort-challengefiles'); const { challengeTypes, viewTypes } = require('../challenge-types'); @@ -115,12 +114,10 @@ function getProjectPreviewConfig(challenge, allChallengeEdges) { const lastChallengeFiles = sortChallengeFiles( lastChallenge.challengeFiles ?? [] ); - const projectPreviewChallengeFiles = lastChallengeFiles.map((file, id) => - createPoly({ - ...file, - contents: solutionToLastChallenge[id]?.contents ?? file.contents - }) - ); + const projectPreviewChallengeFiles = lastChallengeFiles.map((file, id) => ({ + ...file, + contents: solutionToLastChallenge[id]?.contents ?? file.contents + })); return { showProjectPreview: diff --git a/curriculum/getChallenges.js b/curriculum/getChallenges.js index 1890d02d2d..d91b202b3b 100644 --- a/curriculum/getChallenges.js +++ b/curriculum/getChallenges.js @@ -337,27 +337,29 @@ ${getFullPath('english')} challenge.translationPending = lang !== 'english' && !isAuditedCert(lang, superBlock); challenge.usesMultifileEditor = !!usesMultifileEditor; + if (challenge.challengeFiles) { + // The client expects the challengeFiles to be an array of polyvinyls + challenge.challengeFiles = challengeFilesToPolys(challenge.challengeFiles); + } + if (challenge.solutions?.length) { + // The test runner needs the solutions to be arrays of polyvinyls so it + // can sort them correctly. + challenge.solutions = challenge.solutions.map(challengeFilesToPolys); + } - return prepareChallenge(challenge); + return challenge; } -// gets the challenge ready for sourcing into Gatsby -function prepareChallenge(challenge) { - if (challenge.challengeFiles) { - challenge.challengeFiles = challenge.challengeFiles.reduce( - (challengeFiles, challengeFile) => { - return [ - ...challengeFiles, - { - ...createPoly(challengeFile), - seed: challengeFile.contents.slice(0) - } - ]; - }, - [] - ); - } - return challenge; +function challengeFilesToPolys(files) { + return files.reduce((challengeFiles, challengeFile) => { + return [ + ...challengeFiles, + { + ...createPoly(challengeFile), + seed: challengeFile.contents.slice(0) + } + ]; + }, []); } async function hasEnglishSource(basePath, translationPath) { diff --git a/curriculum/test/test-challenges.js b/curriculum/test/test-challenges.js index b225bc01df..ad8b25ef38 100644 --- a/curriculum/test/test-challenges.js +++ b/curriculum/test/test-challenges.js @@ -43,7 +43,6 @@ const testEvaluator = const { getLines } = require('../../utils/get-lines'); const { isAuditedCert } = require('../../utils/is-audited'); -const { sortChallengeFiles } = require('../../utils/sort-challengefiles'); const { getChallengesForLang, getMetaForBlock, @@ -533,9 +532,7 @@ ${inspect(commentMap)} // TODO: the no-solution filtering is a little convoluted: const noSolution = new RegExp('// solution required'); - const solutionsAsArrays = solutions.map(sortChallengeFiles); - - const filteredSolutions = solutionsAsArrays.filter(solution => { + const filteredSolutions = solutions.filter(solution => { return !isEmpty( solution.filter( challengeFile => !noSolution.test(challengeFile.contents) diff --git a/utils/sort-challengefiles.js b/utils/sort-challengefiles.js index c20352f6b1..25d71c15f9 100644 --- a/utils/sort-challengefiles.js +++ b/utils/sort-challengefiles.js @@ -1,16 +1,14 @@ exports.sortChallengeFiles = function sortChallengeFiles(challengeFiles) { const xs = challengeFiles.slice(); - // TODO: refactor this to use an ext array ['html', 'js', 'css'] and loop over - // that. xs.sort((a, b) => { - if (a.ext === 'html') return -1; - if (b.ext === 'html') return 1; - if (a.ext === 'css') return -1; - if (b.ext === 'css') return 1; - if (a.ext === 'jsx') return -1; - if (b.ext === 'jsx') return 1; - if (a.ext === 'js') return -1; - if (b.ext === 'js') return 1; + if (a.history[0] === 'index.html') return -1; + if (b.history[0] === 'index.html') return 1; + if (a.history[0] === 'styles.css') return -1; + if (b.history[0] === 'styles.css') return 1; + if (a.history[0] === 'index.jsx') return -1; + if (b.history[0] === 'index.jsx') return 1; + if (a.history[0] === 'script.js') return -1; + if (b.history[0] === 'script.js') return 1; return 0; }); return xs;