diff --git a/src/utils/parse.ts b/src/utils/parse.ts index 970ab99..36fc5d3 100644 --- a/src/utils/parse.ts +++ b/src/utils/parse.ts @@ -41,15 +41,13 @@ export function parseMdContent(md: string): TutorialFrame | never { const summaryMatch = parts .shift() .match(/^#\s(?.*)[\n\r]+(?[^]*)/); - if (!summaryMatch.groups.tutorialTitle) { - throw new Error("Missing tutorial title"); + if (summaryMatch.groups.tutorialTitle) { + mdContent.summary.title = summaryMatch.groups.tutorialTitle.trim(); } - mdContent.summary.title = summaryMatch.groups.tutorialTitle.trim(); - if (!summaryMatch.groups.tutorialDescription) { - throw new Error("Missing tutorial summary description"); + if (summaryMatch.groups.tutorialDescription) { + mdContent.summary.description = summaryMatch.groups.tutorialDescription.trim(); } - mdContent.summary.description = summaryMatch.groups.tutorialDescription.trim(); // Identify each part of the content parts.forEach((section: string) => { @@ -67,10 +65,10 @@ export function parseMdContent(md: string): TutorialFrame | never { // @ts-ignore mdContent.levels[levelId] = { id: levelId, - title: levelTitle, + title: levelTitle.trim(), summary: levelSummary ? levelSummary.trim() - : _.truncate(levelContent, { length: 80, omission: "..." }), + : _.truncate(levelContent.trim(), { length: 80, omission: "..." }), content: levelContent.trim(), }; } else { diff --git a/tests/parse.test.ts b/tests/parse.test.ts index bd290d6..1c63017 100644 --- a/tests/parse.test.ts +++ b/tests/parse.test.ts @@ -386,6 +386,10 @@ The first step filter: "someFilter", subtasks: true, }, + solution: { + commands: ["npm install"], + files: ["someFile.js"], + }, }, ], }, @@ -396,6 +400,7 @@ The first step config, commits: { L1S1Q: ["abcdefg1", "123456789"], + L1S1A: ["1gfedcba", "987654321"], }, }); const expected = { @@ -419,6 +424,11 @@ The first step filter: "someFilter", subtasks: true, }, + solution: { + commits: ["1gfedcba", "987654321"], + commands: ["npm install"], + files: ["someFile.js"], + }, }, ], }, @@ -427,6 +437,178 @@ The first step expect(result.levels[0].steps[0]).toEqual(expected.levels[0].steps[0]); }); + it("should load the full config for a step", () => { + const md = `# Title + +Description. + +## L1 Title 1 + +First level content. + +### L1S1 + +The first step + +### L1S2 + +The second step + +## L2 Title 2 + +Second level content. + +### L2S1 + +The third step +`; + const config = { + levels: [ + { + id: "L1", + steps: [ + { + id: "L1S1", + setup: { + commands: ["npm install"], + files: ["someFile.js"], + watchers: ["someFile.js"], + filter: "someFilter", + subtasks: true, + }, + solution: { + commands: ["npm install"], + files: ["someFile.js"], + }, + }, + { + id: "L1S2", + setup: { + commands: ["npm install"], + files: ["someFile.js"], + watchers: ["someFile.js"], + filter: "someFilter", + subtasks: true, + }, + solution: { + commands: ["npm install"], + files: ["someFile.js"], + }, + }, + ], + }, + { + id: "L2", + summary: "Second level content.", + content: "First level content.", + steps: [ + { + id: "L2S1", + setup: { + commands: ["npm install"], + files: ["someFile.js"], + watchers: ["someFile.js"], + filter: "someFilter", + subtasks: true, + }, + solution: { + commands: ["npm install"], + files: ["someFile.js"], + }, + }, + ], + }, + ], + }; + const result = parse({ + text: md, + config, + commits: { + L1S1Q: ["abcdefg1", "123456789"], + L1S1A: ["1gfedcba", "987654321"], + L1S2Q: ["2abcdefg"], + L1S2A: ["3abcdefg"], + L2S1Q: ["4abcdefg"], + L2S1A: ["5abcdefg"], + }, + }); + const expected = { + summary: { + description: "Description.", + }, + levels: [ + { + id: "L1", + title: "Title 1", + summary: "First level content.", + content: "First level content.", + steps: [ + { + id: "L1S1", + content: "The first step", + setup: { + commits: ["abcdefg1", "123456789"], + commands: ["npm install"], + files: ["someFile.js"], + watchers: ["someFile.js"], + filter: "someFilter", + subtasks: true, + }, + solution: { + commits: ["1gfedcba", "987654321"], + commands: ["npm install"], + files: ["someFile.js"], + }, + }, + { + id: "L1S2", + content: "The second step", + setup: { + commits: ["2abcdefg"], + commands: ["npm install"], + files: ["someFile.js"], + watchers: ["someFile.js"], + filter: "someFilter", + subtasks: true, + }, + solution: { + commits: ["3abcdefg"], + commands: ["npm install"], + files: ["someFile.js"], + }, + }, + ], + }, + { + id: "L2", + title: "Title 2", + summary: "Second level content.", + content: "Second level content.", + steps: [ + { + id: "L2S1", + content: "The third step", + setup: { + commits: ["4abcdefg"], + commands: ["npm install"], + files: ["someFile.js"], + watchers: ["someFile.js"], + filter: "someFilter", + subtasks: true, + }, + solution: { + commits: ["5abcdefg"], + commands: ["npm install"], + files: ["someFile.js"], + }, + }, + ], + }, + ], + }; + expect(result.levels).toEqual(expected.levels); + }); + // config it("should parse the tutorial config", () => { const md = `# Title