refactor(multi) move preparation into curriculum

This commit is contained in:
Oliver Eyton-Williams
2020-06-08 15:01:48 +02:00
committed by Mrugesh Mohapatra
parent 88de5bc602
commit 754a33970e
3 changed files with 53 additions and 43 deletions

View File

@ -5,18 +5,13 @@ const {
createChallenge,
getChallengesDirForLang
} = require('../../curriculum/getChallenges');
const { dasherize, nameify } = require('../../utils/slugs');
const { locale } = require('../config/env.json');
const { blockNameify } = require('../../utils/block-nameify');
const arrToString = arr =>
Array.isArray(arr) ? arr.join('\n') : _.toString(arr);
exports.localeChallengesRootDir = getChallengesDirForLang(locale);
exports.replaceChallengeNode = locale => {
return async function replaceChallengeNode(fullFilePath) {
return prepareChallenge(await createChallenge(fullFilePath, null, locale));
return await createChallenge(fullFilePath, null, locale);
};
};
@ -32,29 +27,7 @@ exports.buildChallenges = async function buildChallenges() {
const builtChallenges = blocks
.filter(block => !block.isPrivate)
.map(({ challenges }) => challenges.map(prepareChallenge))
.map(({ challenges }) => challenges)
.reduce((accu, current) => accu.concat(current), []);
return builtChallenges;
};
function prepareChallenge(challenge) {
challenge.name = nameify(challenge.title);
if (challenge.files) {
challenge.files = _.reduce(
challenge.files,
(map, file) => {
map[file.key] = {
...file,
head: arrToString(file.head),
contents: arrToString(file.contents),
tail: arrToString(file.tail)
};
return map;
},
{}
);
}
challenge.block = dasherize(challenge.block);
challenge.superBlock = blockNameify(challenge.superBlock);
return challenge;
}

View File

@ -1,5 +1,5 @@
const path = require('path');
const { findIndex } = require('lodash');
const { findIndex, reduce, toString } = require('lodash');
const readDirP = require('readdirp-walk');
const { parseMarkdown } = require('../tools/challenge-md-parser');
const fs = require('fs');
@ -11,8 +11,10 @@ const {
/* eslint-enable max-len*/
const { COMMENT_TRANSLATIONS } = require('./comment-dictionary');
const { dasherize } = require('../utils/slugs');
const { isAuditedCert } = require('../utils/is-audited');
const { dasherize, nameify } = require('../utils/slugs');
const { createPoly } = require('../utils/polyvinyl');
const { blockNameify } = require('../utils/block-nameify');
const challengesDir = path.resolve(__dirname, './challenges');
const metaDir = path.resolve(challengesDir, '_meta');
@ -180,6 +182,43 @@ Trying to parse ${fullPath}`);
challenge.template = template;
challenge.time = time;
return prepareChallenge(challenge);
}
// gets the challenge ready for sourcing into Gatsby
function prepareChallenge(challenge) {
challenge.name = nameify(challenge.title);
if (challenge.files) {
challenge.files = reduce(
challenge.files,
(map, file) => {
map[file.key] = {
...file,
head: arrToString(file.head),
contents: arrToString(file.contents),
tail: arrToString(file.tail)
};
return map;
},
{}
);
// TODO: This should be something that can be folded into the above reduce
challenge.files = Object.keys(challenge.files)
.filter(key => challenge.files[key])
.map(key => challenge.files[key])
.reduce(
(files, file) => ({
...files,
[file.key]: {
...createPoly(file),
seed: file.contents.slice(0)
}
}),
{}
);
}
challenge.block = dasherize(challenge.block);
challenge.superBlock = blockNameify(challenge.superBlock);
return challenge;
}
@ -255,3 +294,7 @@ function getBlockNameFromFullPath(fullFilePath) {
const [, block] = fullFilePath.split(path.sep).reverse();
return block;
}
function arrToString(arr) {
return Array.isArray(arr) ? arr.join('\n') : toString(arr);
}

View File

@ -42,6 +42,7 @@ const {
} = require('../../client/utils/challengeTypes');
const { dasherize } = require('../../utils/slugs');
const { sortFiles } = require('../../utils/sort-files');
const { testedLang } = require('../utils');
@ -50,7 +51,6 @@ const {
buildJSChallenge
} = require('../../client/src/templates/Challenges/utils/build');
const { createPoly } = require('../../utils/polyvinyl');
const { sortChallenges } = require('./utils/sort-challenges');
const testEvaluator = require('../../client/config/test-evaluator').filename;
@ -319,7 +319,6 @@ function populateTestsForLang({ lang, challenges, meta }) {
});
});
let { files = [] } = challenge;
if (challengeType === challengeTypes.backend) {
it('Check tests is not implemented.');
return;
@ -334,7 +333,6 @@ function populateTestsForLang({ lang, challenges, meta }) {
// TODO: create more sophisticated validation now we allow for more
// than one seed/solution file.
files = files.map(createPoly);
it('Test suite must fail on the initial contents', async function() {
this.timeout(5000 * tests.length + 1000);
// suppress errors in the console.
@ -344,7 +342,7 @@ function populateTestsForLang({ lang, challenges, meta }) {
let testRunner;
try {
testRunner = await createTestRunner(
{ ...challenge, files },
challenge,
'',
buildChallenge
);
@ -390,7 +388,7 @@ function populateTestsForLang({ lang, challenges, meta }) {
it(`Solution ${index + 1} must pass the tests`, async function() {
this.timeout(5000 * tests.length + 1000);
const testRunner = await createTestRunner(
{ ...challenge, files },
challenge,
solution,
buildChallenge
);
@ -418,14 +416,10 @@ async function createTestRunner(
solution,
buildChallenge
) {
// TODO: solutions will need to be multi-file, too, with a fallback when there
// is only one file.
// we cannot simply use the solution instead of files, because the are not
// just the seed(s), they contain the head and tail code. The best approach
// is probably to separate out the head and tail from the files. Then the
// files can be entirely replaced by the solution.
// fallback for single solution
const sortedFiles = sortFiles(files);
if (solution) {
files[0].contents = solution;
files[sortedFiles[0].key].contents = solution;
}
const { build, sources, loadEnzyme } = await buildChallenge({