fix: handle missing solutions correctly
Rather than creating an [[]] the parser now creates [] which isEmpty(). This makes the test suite check the next challenge for a solution. In addition, the logic for testing solutions was fixed.
This commit is contained in:
@ -87,7 +87,7 @@ const schema = Joi.object()
|
|||||||
crossDomain: Joi.bool()
|
crossDomain: Joi.bool()
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
solutions: Joi.array().items(Joi.array().items(fileJoi)),
|
solutions: Joi.array().items(Joi.array().items(fileJoi).min(1)),
|
||||||
superBlock: Joi.string().regex(slugRE),
|
superBlock: Joi.string().regex(slugRE),
|
||||||
superOrder: Joi.number(),
|
superOrder: Joi.number(),
|
||||||
suborder: Joi.number(),
|
suborder: Joi.number(),
|
||||||
|
@ -451,22 +451,26 @@ ${inspect(commentMap)}
|
|||||||
// This is expected to happen in the project based curriculum.
|
// This is expected to happen in the project based curriculum.
|
||||||
|
|
||||||
const nextChallenge = challenges[id + 1];
|
const nextChallenge = challenges[id + 1];
|
||||||
// TODO: can this be dried out, ideally by removing the redux
|
|
||||||
// handler?
|
|
||||||
if (nextChallenge) {
|
if (nextChallenge) {
|
||||||
const solutionFiles = cloneDeep(nextChallenge.challengeFiles);
|
const solutionFiles = cloneDeep(nextChallenge.challengeFiles);
|
||||||
solutionFiles.forEach(challengeFile => {
|
const solutionFilesWithEditableContents = solutionFiles.map(
|
||||||
challengeFile.editableContents = getLines(
|
file => ({
|
||||||
challengeFile.contents,
|
...file,
|
||||||
challenge.challengeFiles.find(
|
editableContents: getLines(
|
||||||
x => x.fileKey === challengeFile.fileKey
|
file.contents,
|
||||||
).editableRegionBoundaries
|
file.editableRegionBoundaries
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
solutions = [solutionFiles];
|
);
|
||||||
|
// Since there is only one seed, there can only be one solution,
|
||||||
|
// but the tests assume solutions is an array.
|
||||||
|
solutions = [solutionFilesWithEditableContents];
|
||||||
solutionFromNext = true;
|
solutionFromNext = true;
|
||||||
} else {
|
} else {
|
||||||
throw Error('solution omitted');
|
throw Error(
|
||||||
|
`solution omitted for ${challenge.superBlock} ${challenge.block} ${challenge.title}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,15 +523,11 @@ async function createTestRunner(
|
|||||||
solutionFromNext
|
solutionFromNext
|
||||||
) {
|
) {
|
||||||
const { required = [], template, removeComments } = challenge;
|
const { required = [], template, removeComments } = challenge;
|
||||||
// we should avoid modifying challenge, as it gets reused:
|
|
||||||
const challengeFiles = cloneDeep(challenge.challengeFiles);
|
const challengeFiles = replaceChallengeFilesContentsWithSolutions(
|
||||||
solutionFiles.forEach(solutionFile => {
|
challenge.challengeFiles,
|
||||||
const challengeFile = challengeFiles.find(
|
solutionFiles
|
||||||
x => x.fileKey === solutionFile.fileKey
|
);
|
||||||
);
|
|
||||||
challengeFile.contents = solutionFile.contents;
|
|
||||||
challengeFile.editableContents = solutionFile.editableContents;
|
|
||||||
});
|
|
||||||
|
|
||||||
const { build, sources, loadEnzyme } = await buildChallenge({
|
const { build, sources, loadEnzyme } = await buildChallenge({
|
||||||
challengeFiles,
|
challengeFiles,
|
||||||
@ -567,6 +567,25 @@ async function createTestRunner(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replaceChallengeFilesContentsWithSolutions(
|
||||||
|
challengeFiles,
|
||||||
|
solutionFiles
|
||||||
|
) {
|
||||||
|
return challengeFiles.map(file => {
|
||||||
|
const matchingSolutionFile = solutionFiles.find(
|
||||||
|
({ ext }) => ext === file.ext
|
||||||
|
);
|
||||||
|
if (!matchingSolutionFile) {
|
||||||
|
throw Error(`No matching solution file found`);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...file,
|
||||||
|
contents: matchingSolutionFile.contents,
|
||||||
|
editableContents: matchingSolutionFile.editableContents
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function getContextEvaluator(build, sources, code, loadEnzyme) {
|
async function getContextEvaluator(build, sources, code, loadEnzyme) {
|
||||||
await initializeTestRunner(build, sources, code, loadEnzyme);
|
await initializeTestRunner(build, sources, code, loadEnzyme);
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
const { isEmpty } = require('lodash');
|
||||||
const { root } = require('mdast-builder');
|
const { root } = require('mdast-builder');
|
||||||
const visitChildren = require('unist-util-visit-children');
|
const visitChildren = require('unist-util-visit-children');
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ function createPlugin() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
visitForContents(solutionTree);
|
visitForContents(solutionTree);
|
||||||
solutions.push(Object.values(solution));
|
if (!isEmpty(solution)) solutions.push(Object.values(solution));
|
||||||
});
|
});
|
||||||
|
|
||||||
file.data = {
|
file.data = {
|
||||||
|
Reference in New Issue
Block a user