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
This commit is contained in:
Oliver Eyton-Williams
2022-01-24 19:42:27 +01:00
committed by GitHub
parent b1fb6adc39
commit cacc4eacd7
7 changed files with 37 additions and 42 deletions

View File

@ -95,10 +95,12 @@ exports.createPages = function createPages({ graphql, actions, reporter }) {
contents contents
head head
tail tail
history
} }
solutions { solutions {
contents contents
ext ext
history
} }
superBlock superBlock
superOrder superOrder

View File

@ -547,6 +547,7 @@ export const query = graphql`
head head
tail tail
editableRegionBoundaries editableRegionBoundaries
history
} }
} }
} }

View File

@ -2,7 +2,6 @@ import { isEmpty } from 'lodash-es';
import { createAction, handleActions } from 'redux-actions'; import { createAction, handleActions } from 'redux-actions';
import { getLines } from '../../../../../utils/get-lines'; import { getLines } from '../../../../../utils/get-lines';
import { createPoly } from '../../../../../utils/polyvinyl';
import { challengeTypes } from '../../../../utils/challenge-types'; import { challengeTypes } from '../../../../utils/challenge-types';
import { completedChallengesSelector } from '../../../redux'; import { completedChallengesSelector } from '../../../redux';
import { getTargetEditor } from '../utils/getTargetEditor'; import { getTargetEditor } from '../utils/getTargetEditor';
@ -58,12 +57,11 @@ export const sagas = [
...createCurrentChallengeSaga(actionTypes) ...createCurrentChallengeSaga(actionTypes)
]; ];
// TODO: can createPoly handle editable region, rather than separating it?
export const createFiles = createAction( export const createFiles = createAction(
actionTypes.createFiles, actionTypes.createFiles,
challengeFiles => challengeFiles =>
challengeFiles.map(challengeFile => ({ challengeFiles.map(challengeFile => ({
...createPoly(challengeFile), ...challengeFile,
seed: challengeFile.contents.slice(), seed: challengeFile.contents.slice(),
editableContents: getLines( editableContents: getLines(
challengeFile.contents, challengeFile.contents,

View File

@ -1,5 +1,4 @@
const path = require('path'); const path = require('path');
const { createPoly } = require('../../../utils/polyvinyl');
const { dasherize } = require('../../../utils/slugs'); const { dasherize } = require('../../../utils/slugs');
const { sortChallengeFiles } = require('../../../utils/sort-challengefiles'); const { sortChallengeFiles } = require('../../../utils/sort-challengefiles');
const { challengeTypes, viewTypes } = require('../challenge-types'); const { challengeTypes, viewTypes } = require('../challenge-types');
@ -115,12 +114,10 @@ function getProjectPreviewConfig(challenge, allChallengeEdges) {
const lastChallengeFiles = sortChallengeFiles( const lastChallengeFiles = sortChallengeFiles(
lastChallenge.challengeFiles ?? [] lastChallenge.challengeFiles ?? []
); );
const projectPreviewChallengeFiles = lastChallengeFiles.map((file, id) => const projectPreviewChallengeFiles = lastChallengeFiles.map((file, id) => ({
createPoly({ ...file,
...file, contents: solutionToLastChallenge[id]?.contents ?? file.contents
contents: solutionToLastChallenge[id]?.contents ?? file.contents }));
})
);
return { return {
showProjectPreview: showProjectPreview:

View File

@ -337,27 +337,29 @@ ${getFullPath('english')}
challenge.translationPending = challenge.translationPending =
lang !== 'english' && !isAuditedCert(lang, superBlock); lang !== 'english' && !isAuditedCert(lang, superBlock);
challenge.usesMultifileEditor = !!usesMultifileEditor; 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 challengeFilesToPolys(files) {
function prepareChallenge(challenge) { return files.reduce((challengeFiles, challengeFile) => {
if (challenge.challengeFiles) { return [
challenge.challengeFiles = challenge.challengeFiles.reduce( ...challengeFiles,
(challengeFiles, challengeFile) => { {
return [ ...createPoly(challengeFile),
...challengeFiles, seed: challengeFile.contents.slice(0)
{ }
...createPoly(challengeFile), ];
seed: challengeFile.contents.slice(0) }, []);
}
];
},
[]
);
}
return challenge;
} }
async function hasEnglishSource(basePath, translationPath) { async function hasEnglishSource(basePath, translationPath) {

View File

@ -43,7 +43,6 @@ const testEvaluator =
const { getLines } = require('../../utils/get-lines'); const { getLines } = require('../../utils/get-lines');
const { isAuditedCert } = require('../../utils/is-audited'); const { isAuditedCert } = require('../../utils/is-audited');
const { sortChallengeFiles } = require('../../utils/sort-challengefiles');
const { const {
getChallengesForLang, getChallengesForLang,
getMetaForBlock, getMetaForBlock,
@ -533,9 +532,7 @@ ${inspect(commentMap)}
// TODO: the no-solution filtering is a little convoluted: // TODO: the no-solution filtering is a little convoluted:
const noSolution = new RegExp('// solution required'); const noSolution = new RegExp('// solution required');
const solutionsAsArrays = solutions.map(sortChallengeFiles); const filteredSolutions = solutions.filter(solution => {
const filteredSolutions = solutionsAsArrays.filter(solution => {
return !isEmpty( return !isEmpty(
solution.filter( solution.filter(
challengeFile => !noSolution.test(challengeFile.contents) challengeFile => !noSolution.test(challengeFile.contents)

View File

@ -1,16 +1,14 @@
exports.sortChallengeFiles = function sortChallengeFiles(challengeFiles) { exports.sortChallengeFiles = function sortChallengeFiles(challengeFiles) {
const xs = challengeFiles.slice(); const xs = challengeFiles.slice();
// TODO: refactor this to use an ext array ['html', 'js', 'css'] and loop over
// that.
xs.sort((a, b) => { xs.sort((a, b) => {
if (a.ext === 'html') return -1; if (a.history[0] === 'index.html') return -1;
if (b.ext === 'html') return 1; if (b.history[0] === 'index.html') return 1;
if (a.ext === 'css') return -1; if (a.history[0] === 'styles.css') return -1;
if (b.ext === 'css') return 1; if (b.history[0] === 'styles.css') return 1;
if (a.ext === 'jsx') return -1; if (a.history[0] === 'index.jsx') return -1;
if (b.ext === 'jsx') return 1; if (b.history[0] === 'index.jsx') return 1;
if (a.ext === 'js') return -1; if (a.history[0] === 'script.js') return -1;
if (b.ext === 'js') return 1; if (b.history[0] === 'script.js') return 1;
return 0; return 0;
}); });
return xs; return xs;