refactor: drop superorder from metas (#44422)

* refactor: create superOrder from superblock

* chore: drop superOrders from meta

* fix: return null for 'certifications'

* fix: only set superOrder if it is needed

* fix(tests): remove filter from order tests

* test: use getSuperOrder, since superOrder has gone

* test: ignore certificates

* fix: getSuperOrder throw for 'certifications'

* test: remove certificate special case

It wasn't necessary, anyway (it had never been working because I put
certificate not certification)

Co-authored-by: Nicholas Carrigan <nhcarrigan@gmail.com>
This commit is contained in:
Oliver Eyton-Williams
2021-12-14 17:16:23 +01:00
committed by GitHub
parent d4f490419f
commit 1642c631de
74 changed files with 81 additions and 84 deletions

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "quality-assurance",
"superOrder": 6,
"challengeOrder": [
[
"5895f700f9fc0f352b528e63",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "coding-interview-prep",
"superOrder": 11,
"challengeOrder": [
[
"a3f503de51cf954ede28891d",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"587d774c367417b2b2512a9c",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"587d7791367417b2b2512ab3",

View File

@ -5,7 +5,6 @@
"order": 3,
"time": "150 hours",
"superBlock": "back-end-development-and-apis",
"superOrder": 5,
"challengeOrder": [
[
"bd7158d8c443edefaeb5bdef",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"56533eb9ac21ba0edf2244b3",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"bad87fee1348bd9aedf08803",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"587d7b7e367417b2b2512b20",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"bd7123c8c441eddfaeb5bdef",

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"isBeta": true,
"challengeOrder": [
[

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"bd7123c9c441eddfaeb4bdef",

View File

@ -5,7 +5,6 @@
"order": 1,
"time": "5 hours",
"superBlock": "back-end-development-and-apis",
"superOrder": 5,
"challengeOrder": [
[
"587d7fb0367417b2b2512bed",

View File

@ -11,7 +11,6 @@
}
],
"superBlock": "front-end-development-libraries",
"superOrder": 2,
"challengeOrder": [
[
"bad87fee1348bd9acde08712",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"587d78ab367417b2b2512af0",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"5a858944d96184f06fd60d61",

View File

@ -12,7 +12,6 @@
}
],
"superBlock": "data-visualization",
"superOrder": 3,
"challengeOrder": [
[
"5d8a4cfbe6b6180ed9a1c9de",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "data-analysis-with-python",
"superOrder": 8,
"challengeOrder": [
[
"5e9a093a74c4063ca6f7c14c",

View File

@ -5,7 +5,6 @@
"order": 2,
"time": "150 hours",
"superBlock": "data-analysis-with-python",
"superOrder": 8,
"challengeOrder": [
[
"5e46f7e5ac417301a38fb928",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "coding-interview-prep",
"superOrder": 11,
"challengeOrder": [
[
"587d8253367417b2b2512c6a",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "data-visualization",
"superOrder": 3,
"challengeOrder": [
[
"bd7168d8c242eddfaeb5bd13",

View File

@ -11,7 +11,6 @@
}
],
"superBlock": "data-visualization",
"superOrder": 3,
"challengeOrder": [
["587d7fa6367417b2b2512bc2", "Add Document Elements with D3"],
["587d7fa6367417b2b2512bc3", "Select a Group of Elements with D3"],

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"587d7b83367417b2b2512b33",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"587d7b87367417b2b2512b40",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "front-end-development-libraries",
"superOrder": 2,
"challengeOrder": [
[
"bd7158d8c442eddfaeb5bd13",

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"isBeta": true,
"challengeOrder": [
[

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"587d7b8d367417b2b2512b5b",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "machine-learning-with-python",
"superOrder": 10,
"challengeOrder": [
[
"5e9a0e9ef99a403d019610ca",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "information-security",
"superOrder": 9,
"challengeOrder": [
[
"587d824a367417b2b2512c44",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "information-security",
"superOrder": 9,
"challengeOrder": [
[
"587d8247367417b2b2512c36",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"a3566b1109230028080c9345",

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"5ddb965c65d27e1512d44d9a",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"aaa48de84e1ecc7c742e1124",

View File

@ -11,7 +11,6 @@
}
],
"superBlock": "front-end-development-libraries",
"superOrder": 2,
"challengeOrder": [
[
"bad87fee1348bd9acdd08826",

View File

@ -11,7 +11,6 @@
}
],
"superBlock": "data-visualization",
"superOrder": 3,
"challengeOrder": [
[
"587d7fad367417b2b2512be1",

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 1,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"5d822fd413a79914d39e98c9",

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 1,
"isBeta": true,
"challengeOrder": [
[

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "relational-databases",
"superOrder": 4,
"challengeOrder": [
[
"5ea8adfab628f68d805bfc5e",

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -8,7 +8,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"isBeta": true,
"challengeOrder": [
[

View File

@ -5,7 +5,6 @@
"order": 2,
"time": "150 hours",
"superBlock": "machine-learning-with-python",
"superOrder": 10,
"challengeOrder": [
[
"5e46f8d6ac417301a38fb92d",

View File

@ -5,7 +5,6 @@
"order": 0,
"time": "5 hours",
"superBlock": "back-end-development-and-apis",
"superOrder": 5,
"challengeOrder": [
[
"587d7fb3367417b2b2512bfb",

View File

@ -5,7 +5,6 @@
"order": 2,
"time": "5 hours",
"superBlock": "back-end-development-and-apis",
"superOrder": 5,
"challengeOrder": [
[
"587d7fb6367417b2b2512c06",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "data-analysis-with-python",
"superOrder": 8,
"challengeOrder": [
[
"5e9a0a8e09c5df3cc3600ed2",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"587d7dac367417b2b2512b73",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "coding-interview-prep",
"superOrder": 11,
"challengeOrder": [
[
"5900f36e1000cf542c50fe80",

View File

@ -5,7 +5,6 @@
"order": 0,
"time": "15 hours",
"superBlock": "scientific-computing-with-python",
"superOrder": 7,
"challengeOrder": [
[
"5e6a54a558d3af90110a60a0",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "information-security",
"superOrder": 9,
"challengeOrder": [
[
"5ea9997bbec2e9bc47e94dae",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "quality-assurance",
"superOrder": 6,
"challengeOrder": [
[
"587d824a367417b2b2512c46",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "quality-assurance",
"superOrder": 6,
"challengeOrder": [
[
"587d8249367417b2b2512c41",

View File

@ -20,7 +20,6 @@
}
],
"superBlock": "front-end-development-libraries",
"superOrder": 2,
"challengeOrder": [
[
"5a24c314108439a4d4036141",

View File

@ -14,7 +14,6 @@
}
],
"superBlock": "front-end-development-libraries",
"superOrder": 2,
"challengeOrder": [
[
"587d7dbc367417b2b2512bb1",

View File

@ -14,7 +14,6 @@
}
],
"superBlock": "front-end-development-libraries",
"superOrder": 2,
"challengeOrder": [
[
"5a24c314108439a4d403614b",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 1,
"challengeOrder": [
[
"587d7db3367417b2b2512b8e",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"587d78b0367417b2b2512b08",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 0,
"challengeOrder": [
[
"bd7158d8c442eddfaeb5bd18",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "coding-interview-prep",
"superOrder": 11,
"challengeOrder": [
[
"594810f028c0303b75339acb",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "front-end-development-libraries",
"superOrder": 2,
"challengeOrder": [
[
"587d7dbd367417b2b2512bb4",

View File

@ -5,7 +5,6 @@
"order": 1,
"time": "150 hours",
"superBlock": "scientific-computing-with-python",
"superOrder": 7,
"challengeOrder": [
[
"5e44412c903586ffb414c94c",

View File

@ -7,7 +7,6 @@
"template": "",
"required": [],
"superBlock": "coding-interview-prep",
"superOrder": 11,
"challengeOrder": [
[
"bd7158d8c442eddfaeb5bd10",

View File

@ -5,7 +5,6 @@
"order": 0,
"time": "15 hours",
"superBlock": "machine-learning-with-python",
"superOrder": 10,
"challengeOrder": [
[
"5e8f2f13c4cdbe86b5c72d87",

View File

@ -4,6 +4,7 @@ const util = require('util');
const yaml = require('js-yaml');
const { findIndex } = require('lodash');
const readDirP = require('readdirp');
const { getSuperOrder } = require('./utils');
const { helpCategoryMap } = require('../client/utils/challenge-types');
const { showUpcomingChanges } = require('../config/env.json');
const { curriculum: curriculumLangs } =
@ -296,7 +297,6 @@ ${getFullPath('english')}
const {
name: blockName,
order,
superOrder,
isPrivate,
required = [],
template,
@ -305,7 +305,8 @@ ${getFullPath('english')}
} = meta;
challenge.block = dasherize(blockName);
challenge.order = order;
challenge.superOrder = superOrder;
const superOrder = getSuperOrder(superBlock);
if (superOrder !== null) challenge.superOrder = superOrder;
challenge.superBlock = superBlock;
challenge.challengeOrder = challengeOrder;
challenge.isPrivate = challenge.isPrivate || isPrivate;

View File

@ -50,7 +50,7 @@ const {
getTranslatableComments
} = require('../getChallenges');
const { challengeSchemaValidator } = require('../schema/challengeSchema');
const { testedLang } = require('../utils');
const { testedLang, getSuperOrder } = require('../utils');
const ChallengeTitles = require('./utils/challengeTitles');
const MongoIds = require('./utils/mongoIds');
const createPseudoWorker = require('./utils/pseudo-worker');
@ -268,22 +268,16 @@ function populateTestsForLang({ lang, challenges, meta }) {
]);
superBlocks.forEach(superBlock => {
const filteredMeta = Object.values(meta)
/**
* Exclude any meta which doesn't have a superOrder, as these shouldn't
* appear on the learn map and thus don't need to be validated.
*/
.filter(
el =>
el.superBlock === superBlock && typeof el.superOrder !== 'undefined'
)
.filter(el => el.superBlock === superBlock)
.sort((a, b) => a.order - b.order);
if (!filteredMeta.length) {
return;
}
it(`${superBlock} should have the same order in every meta`, function () {
const firstOrder = filteredMeta[0].superOrder;
const firstOrder = getSuperOrder(filteredMeta[0].superBlock);
assert.isNumber(firstOrder);
assert.isTrue(
filteredMeta.every(el => el.superOrder === firstOrder),
filteredMeta.every(el => getSuperOrder(el.superBlock) === firstOrder),
'The superOrder properties are mismatched.'
);
});

View File

@ -16,3 +16,32 @@ exports.testedLang = function testedLang() {
throw Error('LOCALE must be set for testing');
}
};
// TODO: migrate to TS and use the SuperBlocks enum from
// config/certification-settings.ts
const superBlockToOrder = {
'responsive-web-design': 0,
'javascript-algorithms-and-data-structures': 1,
'front-end-development-libraries': 2,
'data-visualization': 3,
'relational-databases': 4,
'back-end-development-and-apis': 5,
'quality-assurance': 6,
'scientific-computing-with-python': 7,
'data-analysis-with-python': 8,
'information-security': 9,
'machine-learning-with-python': 10,
'coding-interview-prep': 11
};
function getSuperOrder(superblock, { isLegacy } = { isLegacy: false }) {
if (typeof superblock !== 'string')
throw Error('superblock must be a string');
const order = superBlockToOrder[superblock];
if (typeof order === 'undefined')
throw Error(`${superblock} is not a valid superblock`);
return isLegacy ? order + 12 : order;
}
exports.getSuperOrder = getSuperOrder;

43
curriculum/utils.test.js Normal file
View File

@ -0,0 +1,43 @@
import { getSuperOrder } from './utils';
describe('getSuperOrder', () => {
it('returns a number for valid superblocks', () => {
expect.assertions(1);
expect(typeof getSuperOrder('responsive-web-design')).toBe('number');
});
it('throws for unknown superblocks', () => {
expect.assertions(4);
expect(() => getSuperOrder()).toThrow();
expect(() => getSuperOrder(null)).toThrow();
expect(() => getSuperOrder('')).toThrow();
expect(() => getSuperOrder('respansive-wib-desoin')).toThrow();
});
it('throws for "certifications"', () => {
expect.assertions(2);
expect(() => getSuperOrder('certifications')).toThrow();
expect(() => getSuperOrder('certifications', { isLegacy: true })).toThrow();
});
it('returns unique numbers for all current superblocks', () => {
expect.assertions(12);
expect(getSuperOrder('responsive-web-design')).toBe(0);
expect(getSuperOrder('javascript-algorithms-and-data-structures')).toBe(1);
expect(getSuperOrder('front-end-development-libraries')).toBe(2);
expect(getSuperOrder('data-visualization')).toBe(3);
expect(getSuperOrder('relational-databases')).toBe(4);
expect(getSuperOrder('back-end-development-and-apis')).toBe(5);
expect(getSuperOrder('quality-assurance')).toBe(6);
expect(getSuperOrder('scientific-computing-with-python')).toBe(7);
expect(getSuperOrder('data-analysis-with-python')).toBe(8);
expect(getSuperOrder('information-security')).toBe(9);
expect(getSuperOrder('machine-learning-with-python')).toBe(10);
expect(getSuperOrder('coding-interview-prep')).toBe(11);
});
it('returns unique numbers for all legacy superblocks', () => {
expect.assertions(1);
expect(getSuperOrder('responsive-web-design', { isLegacy: true })).toBe(12);
});
});