refactor(multi) move preparation into curriculum
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
88de5bc602
commit
754a33970e
@ -5,18 +5,13 @@ const {
|
|||||||
createChallenge,
|
createChallenge,
|
||||||
getChallengesDirForLang
|
getChallengesDirForLang
|
||||||
} = require('../../curriculum/getChallenges');
|
} = require('../../curriculum/getChallenges');
|
||||||
const { dasherize, nameify } = require('../../utils/slugs');
|
|
||||||
const { locale } = require('../config/env.json');
|
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.localeChallengesRootDir = getChallengesDirForLang(locale);
|
||||||
|
|
||||||
exports.replaceChallengeNode = locale => {
|
exports.replaceChallengeNode = locale => {
|
||||||
return async function replaceChallengeNode(fullFilePath) {
|
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
|
const builtChallenges = blocks
|
||||||
.filter(block => !block.isPrivate)
|
.filter(block => !block.isPrivate)
|
||||||
.map(({ challenges }) => challenges.map(prepareChallenge))
|
.map(({ challenges }) => challenges)
|
||||||
.reduce((accu, current) => accu.concat(current), []);
|
.reduce((accu, current) => accu.concat(current), []);
|
||||||
return builtChallenges;
|
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;
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { findIndex } = require('lodash');
|
const { findIndex, reduce, toString } = require('lodash');
|
||||||
const readDirP = require('readdirp-walk');
|
const readDirP = require('readdirp-walk');
|
||||||
const { parseMarkdown } = require('../tools/challenge-md-parser');
|
const { parseMarkdown } = require('../tools/challenge-md-parser');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@ -11,8 +11,10 @@ const {
|
|||||||
/* eslint-enable max-len*/
|
/* eslint-enable max-len*/
|
||||||
const { COMMENT_TRANSLATIONS } = require('./comment-dictionary');
|
const { COMMENT_TRANSLATIONS } = require('./comment-dictionary');
|
||||||
|
|
||||||
const { dasherize } = require('../utils/slugs');
|
|
||||||
const { isAuditedCert } = require('../utils/is-audited');
|
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 challengesDir = path.resolve(__dirname, './challenges');
|
||||||
const metaDir = path.resolve(challengesDir, '_meta');
|
const metaDir = path.resolve(challengesDir, '_meta');
|
||||||
@ -180,6 +182,43 @@ Trying to parse ${fullPath}`);
|
|||||||
challenge.template = template;
|
challenge.template = template;
|
||||||
challenge.time = time;
|
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;
|
return challenge;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,3 +294,7 @@ function getBlockNameFromFullPath(fullFilePath) {
|
|||||||
const [, block] = fullFilePath.split(path.sep).reverse();
|
const [, block] = fullFilePath.split(path.sep).reverse();
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function arrToString(arr) {
|
||||||
|
return Array.isArray(arr) ? arr.join('\n') : toString(arr);
|
||||||
|
}
|
||||||
|
@ -42,6 +42,7 @@ const {
|
|||||||
} = require('../../client/utils/challengeTypes');
|
} = require('../../client/utils/challengeTypes');
|
||||||
|
|
||||||
const { dasherize } = require('../../utils/slugs');
|
const { dasherize } = require('../../utils/slugs');
|
||||||
|
const { sortFiles } = require('../../utils/sort-files');
|
||||||
|
|
||||||
const { testedLang } = require('../utils');
|
const { testedLang } = require('../utils');
|
||||||
|
|
||||||
@ -50,7 +51,6 @@ const {
|
|||||||
buildJSChallenge
|
buildJSChallenge
|
||||||
} = require('../../client/src/templates/Challenges/utils/build');
|
} = require('../../client/src/templates/Challenges/utils/build');
|
||||||
|
|
||||||
const { createPoly } = require('../../utils/polyvinyl');
|
|
||||||
const { sortChallenges } = require('./utils/sort-challenges');
|
const { sortChallenges } = require('./utils/sort-challenges');
|
||||||
|
|
||||||
const testEvaluator = require('../../client/config/test-evaluator').filename;
|
const testEvaluator = require('../../client/config/test-evaluator').filename;
|
||||||
@ -319,7 +319,6 @@ function populateTestsForLang({ lang, challenges, meta }) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let { files = [] } = challenge;
|
|
||||||
if (challengeType === challengeTypes.backend) {
|
if (challengeType === challengeTypes.backend) {
|
||||||
it('Check tests is not implemented.');
|
it('Check tests is not implemented.');
|
||||||
return;
|
return;
|
||||||
@ -334,7 +333,6 @@ function populateTestsForLang({ lang, challenges, meta }) {
|
|||||||
// TODO: create more sophisticated validation now we allow for more
|
// TODO: create more sophisticated validation now we allow for more
|
||||||
// than one seed/solution file.
|
// than one seed/solution file.
|
||||||
|
|
||||||
files = files.map(createPoly);
|
|
||||||
it('Test suite must fail on the initial contents', async function() {
|
it('Test suite must fail on the initial contents', async function() {
|
||||||
this.timeout(5000 * tests.length + 1000);
|
this.timeout(5000 * tests.length + 1000);
|
||||||
// suppress errors in the console.
|
// suppress errors in the console.
|
||||||
@ -344,7 +342,7 @@ function populateTestsForLang({ lang, challenges, meta }) {
|
|||||||
let testRunner;
|
let testRunner;
|
||||||
try {
|
try {
|
||||||
testRunner = await createTestRunner(
|
testRunner = await createTestRunner(
|
||||||
{ ...challenge, files },
|
challenge,
|
||||||
'',
|
'',
|
||||||
buildChallenge
|
buildChallenge
|
||||||
);
|
);
|
||||||
@ -390,7 +388,7 @@ function populateTestsForLang({ lang, challenges, meta }) {
|
|||||||
it(`Solution ${index + 1} must pass the tests`, async function() {
|
it(`Solution ${index + 1} must pass the tests`, async function() {
|
||||||
this.timeout(5000 * tests.length + 1000);
|
this.timeout(5000 * tests.length + 1000);
|
||||||
const testRunner = await createTestRunner(
|
const testRunner = await createTestRunner(
|
||||||
{ ...challenge, files },
|
challenge,
|
||||||
solution,
|
solution,
|
||||||
buildChallenge
|
buildChallenge
|
||||||
);
|
);
|
||||||
@ -418,14 +416,10 @@ async function createTestRunner(
|
|||||||
solution,
|
solution,
|
||||||
buildChallenge
|
buildChallenge
|
||||||
) {
|
) {
|
||||||
// TODO: solutions will need to be multi-file, too, with a fallback when there
|
// fallback for single solution
|
||||||
// is only one file.
|
const sortedFiles = sortFiles(files);
|
||||||
// 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.
|
|
||||||
if (solution) {
|
if (solution) {
|
||||||
files[0].contents = solution;
|
files[sortedFiles[0].key].contents = solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { build, sources, loadEnzyme } = await buildChallenge({
|
const { build, sources, loadEnzyme } = await buildChallenge({
|
||||||
|
Reference in New Issue
Block a user