Skip to content

Commit

Permalink
refactor(Common): Refactors the new parseTracks function as per code …
Browse files Browse the repository at this point in the history
…review. It maintains backwards compatibility with current workflows
  • Loading branch information
mfdebian committed Nov 20, 2023
1 parent 47613da commit 8553da5
Show file tree
Hide file tree
Showing 20 changed files with 45 additions and 99 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,11 @@ curriculum-parser project projects/01-cipher/ \
--version 5.5.0 \
--lo=./learning-objectives
```

## Known tracks

This project contains an array in [`lib/common.js`](./lib/common.js) called
`knownTracks` which contains the list of tracks that are known by the parser.

If a new track was ever going to be added to the curriculum, it would need to be
added to this array or else it'd throw the corresponding _Invalid track_ error.
15 changes: 0 additions & 15 deletions lib/__tests__/__fixtures__/01-a-project-without-tracks/README.md

This file was deleted.

15 changes: 0 additions & 15 deletions lib/__tests__/__fixtures__/01-a-project-without-tracks/project.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
---
track: web-dev
env: cjs
---

Expand Down
11 changes: 0 additions & 11 deletions lib/__tests__/__fixtures__/topic-without-tracks/README.md

This file was deleted.

2 changes: 1 addition & 1 deletion lib/__tests__/challenge.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('parseChallenge', () => {
});

it('throws when no tracks', () => {
const dir = resolveFixturePath('challenge-without-tracks');
const dir = resolveFixturePath('challenge-without-track-nor-tracks');
return expect(parseChallenge(dir, {}, {}))
.rejects.toThrow('No tracks found. Expected at least one');
});
Expand Down
14 changes: 7 additions & 7 deletions lib/__tests__/common.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
getTitle,
parseDirname,
splitMetaAndContent,
validateTracks,
parseTracks,
} from '../common.js';

vi.mock('sharp');
Expand Down Expand Up @@ -41,24 +41,24 @@ describe('splitMetaAndContent', () => {
});
});

describe('validateTracks', () => {
describe('parseTracks', () => {
it('should reject if tracks is not an array', () => {
[null, undefined, 420, 'foo', {}].forEach((variable) => {
expect(() => validateTracks(variable))
expect(() => parseTracks({ tracks: variable }))
.toThrow('No tracks found. Expected at least one.');
});
});

it('should reject if tracks array is empty', () => {
const emptyTracks = [];
expect(() => validateTracks(emptyTracks))
const emptyTracks = { tracks: [] };
expect(() => parseTracks(emptyTracks))
.toThrow('No tracks found. Expected at least one.');
});

it('should reject if tracks contains unknown track', () => {
const badTracks = ['web-dev', 'ux', 'data', 'foo'];
expect(() => validateTracks(badTracks))
.toThrow('Found unknown track "foo". Expected "web-dev", "ux" or "data".');
expect(() => parseTracks({ tracks: badTracks }))
.toThrow('Invalid track "foo". Expected "web-dev", "ux" or "data".');
});
});

Expand Down
16 changes: 2 additions & 14 deletions lib/__tests__/project.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,11 @@ describe('parseProject', () => {
});
});

it('when unknown track', () => {
const p = resolveFixturePath('01-a-project-without-track');
it('when project doesnt contain track nor tracks', () => {
const p = resolveFixturePath('01-a-project-without-track-nor-tracks');
return parseProject(p, {
repo: 'Laboratoria/bootcamp',
version: '1.0.0',
}, pkg)
.catch((err) => {
expect(err.message)
.toBe('Invalid track "undefined". Expected "web-dev", "ux" or "data".');
});
});

it('when project doesnt contain tracks', () => {
const p = resolveFixturePath('01-a-project-without-tracks');
return parseProject(p, {
repo: 'Laboratoria/curriculum',
version: '1.0.0',
}, pkg)
.catch((err) => {
expect(err.message)
Expand Down
16 changes: 2 additions & 14 deletions lib/__tests__/topic.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,12 @@ describe('parseTopic', () => {
});
});

it('when README.md doesnt contain track', () => {
const p = resolveFixturePath('topic-without-track');
it('when README.md doesnt contain track nor tracks', () => {
const p = resolveFixturePath('topic-without-track-nor-tracks');
expect.assertions(1);
return parseTopic(p, {
repo: 'Laboratoria/bootcamp',
version: '1.0.0',
})
.catch((err) => {
expect(err.message).toBe('Invalid track "undefined". Expected "web-dev", "ux" or "data".');
});
});

it('when README.md doesnt contain tracks', () => {
const p = resolveFixturePath('topic-without-tracks');
expect.assertions(1);
return parseTopic(p, {
repo: 'Laboratoria/curriculum',
version: '1.0.0',
})
.catch((err) => {
expect(err.message).toBe('No tracks found. Expected at least one.');
Expand Down
6 changes: 2 additions & 4 deletions lib/challenge.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
parseDirname,
parseReadmes,
parser,
validateTracks,
parseTracks,
} from './common.js';

const knownEnvs = ['cjs', 'dom', 'form'];
Expand Down Expand Up @@ -221,9 +221,7 @@ export const parseChallenge = async (dir, opts, pkg) => {
// TODO: Validate files (boilerplate, tests and solution)
const files = flattenTree(await dirToTree(dir));

const { track, tracks } = meta;

validateTracks(tracks);
const { track, tracks } = parseTracks(meta);

return {
slug,
Expand Down
20 changes: 17 additions & 3 deletions lib/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const parser = unified()
.use(remarkRehype)
.use(rehypeStringify);

const knownTracks = ['web-dev', 'ux', 'data'];

export const parseDirname = (dir) => {
const basename = path.basename(dir);

Expand Down Expand Up @@ -257,16 +259,28 @@ export const parseReadmes = async (dir, langs, type, fn) => {
};
};

export const validateTracks = (tracks) => {
export const parseTracks = (meta) => {
let { track, tracks } = meta;

if (track && !tracks) {
tracks = [track];
}

if (!track && tracks?.length) {
[track] = tracks;
}

if (!Array.isArray(tracks) || !tracks.length) {
throw new Error('No tracks found. Expected at least one.');
}

tracks.forEach((track) => {
if (!['web-dev', 'ux', 'data'].includes(track)) {
throw new Error(`Found unknown track "${track}". Expected "web-dev", "ux" or "data".`);
if (!knownTracks.includes(track)) {
throw new Error(`Invalid track "${track}". Expected "web-dev", "ux" or "data".`);
}
});

return { track, tracks };
};

export const comparePrefixedDirs = (a, b) => (
Expand Down
10 changes: 3 additions & 7 deletions lib/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
parseReadmes,
getTitle,
parser,
validateTracks,
parseTracks,
} from './common.js';

const getSummary = (rootNode) => {
Expand Down Expand Up @@ -155,13 +155,9 @@ export const parseProject = async (dir, opts, pkg) => {
}),
);

const { track, tracks, cover, thumb } = meta;
const { cover, thumb } = meta;

if (!['web-dev', 'ux', 'data'].includes(track)) {
throw new Error(`Invalid track "${track}". Expected "web-dev", "ux" or "data".`);
}

validateTracks(tracks);
const { track, tracks } = parseTracks(meta);

const learningObjectives = await transformLearningObjectives(dir, opts, meta);

Expand Down
10 changes: 3 additions & 7 deletions lib/topic.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
parseDirname,
parseReadmes,
parser,
validateTracks,
parseTracks,
} from './common.js';
import { parsePart } from './part.js';

Expand Down Expand Up @@ -167,13 +167,9 @@ export const parseTopic = async (dir, opts, pkg) => {
}),
);

const { track, tracks, cover, thumb } = meta;
const { cover, thumb } = meta;

if (!['web-dev', 'ux', 'data'].includes(track)) {
throw new Error(`Invalid track "${track}". Expected "web-dev", "ux" or "data".`);
}

validateTracks(tracks);
const { track, tracks } = parseTracks(meta);

const units = await parseUnits(dir, langs, parsedLocales);
const { errors: duplicateSlugErrors } = units.reduce(
Expand Down

0 comments on commit 8553da5

Please sign in to comment.