refactor: files{} -> challengeFiles[], and key -> fileKey (#43023)
* fix(client): fix client * fix propType and add comment * revert user.json prettification * slight type refactor and payload correction Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> * update ChallengeFile type imports * add cypress test for code-storage * update test and storage epic * fix Shaun's tired brain's logic * refactor with suggestions Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> * update codeReset * increate cypress timeout because firefox is slow * remove unused import to make linter happy * use focus on editor Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> * use more specific seletor for cypress editor test * account for silly null challengeFiles Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@ -13,7 +13,7 @@ a container directive
|
||||
:::</p>
|
||||
</section>",
|
||||
"solutions": Array [
|
||||
Object {},
|
||||
Array [],
|
||||
],
|
||||
"tests": Array [],
|
||||
}
|
||||
@ -44,7 +44,7 @@ Object {
|
||||
</code></pre>",
|
||||
},
|
||||
"solutions": Array [
|
||||
Object {},
|
||||
Array [],
|
||||
],
|
||||
"tests": Array [],
|
||||
}
|
||||
@ -52,38 +52,33 @@ Object {
|
||||
|
||||
exports[`challenge parser should import md from other files 1`] = `
|
||||
Object {
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class=\\"language-html\\">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"files": Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
"challengeFiles": Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
const element = array[index];
|
||||
@ -91,20 +86,25 @@ for (let index = 0; index < array.length; index++) {
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "custom-name",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
],
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class=\\"language-html\\">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"instructions": "<section id=\\"instructions\\">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class=\\"language-html\\">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"solutions": Array [
|
||||
Object {},
|
||||
Array [],
|
||||
],
|
||||
"tests": Array [
|
||||
Object {
|
||||
@ -121,6 +121,43 @@ for (let index = 0; index < array.length; index++) {
|
||||
|
||||
exports[`challenge parser should not mix other YAML with the frontmatter 1`] = `
|
||||
Object {
|
||||
"challengeFiles": Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
],
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class=\\"language-html\\">code example
|
||||
@ -130,50 +167,13 @@ Object {
|
||||
anothersubkey: another value
|
||||
</code></pre>
|
||||
</section>",
|
||||
"files": Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "html",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
"instructions": "<section id=\\"instructions\\">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class=\\"language-html\\">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"solutions": Array [
|
||||
Object {},
|
||||
Array [],
|
||||
],
|
||||
"tests": Array [
|
||||
Object {
|
||||
@ -190,42 +190,8 @@ Object {
|
||||
|
||||
exports[`challenge parser should parse a more realistic md file 1`] = `
|
||||
Object {
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>When you add a lower rank heading element to the page, it's implied that you're starting a new subsection.</p>
|
||||
<p>After the last <code>h2</code> element of the second <code>section</code> element, add an <code>h3</code> element with the text <code>Things cats love:</code>.</p>
|
||||
<blockquote>
|
||||
<p>Some text in a blockquote</p>
|
||||
<p>
|
||||
Some text in a blockquote, with <code>code</code>
|
||||
</p>
|
||||
</blockquote>
|
||||
</section>",
|
||||
"files": Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [
|
||||
7,
|
||||
9,
|
||||
],
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
"challengeFiles": Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
@ -256,32 +222,14 @@ a {
|
||||
23,
|
||||
],
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "html-key",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"head": " // this runs before the user's code is evaluated.",
|
||||
"id": "final-key",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
"instructions": "<section id=\\"instructions\\">
|
||||
<p>Do something with the <code>code</code>.</p>
|
||||
<p>To test that adjacent tags are handled correctly:</p>
|
||||
<p>a bit of <code>code</code> <tag>with more after a space</tag> and another pair of <strong>elements</strong> <em>with a space</em></p>
|
||||
</section>",
|
||||
"solutions": Array [
|
||||
Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
@ -293,14 +241,46 @@ h1 {
|
||||
a {
|
||||
color: green;
|
||||
}",
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
"editableRegionBoundaries": Array [
|
||||
7,
|
||||
9,
|
||||
],
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": " // this runs before the user's code is evaluated.",
|
||||
"id": "final-key",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
],
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>When you add a lower rank heading element to the page, it's implied that you're starting a new subsection.</p>
|
||||
<p>After the last <code>h2</code> element of the second <code>section</code> element, add an <code>h3</code> element with the text <code>Things cats love:</code>.</p>
|
||||
<blockquote>
|
||||
<p>Some text in a blockquote</p>
|
||||
<p>
|
||||
Some text in a blockquote, with <code>code</code>
|
||||
</p>
|
||||
</blockquote>
|
||||
</section>",
|
||||
"instructions": "<section id=\\"instructions\\">
|
||||
<p>Do something with the <code>code</code>.</p>
|
||||
<p>To test that adjacent tags are handled correctly:</p>
|
||||
<p>a bit of <code>code</code> <tag>with more after a space</tag> and another pair of <strong>elements</strong> <em>with a space</em></p>
|
||||
</section>",
|
||||
"solutions": Array [
|
||||
Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
<h1>CatPhotoApp</h1>
|
||||
@ -327,22 +307,42 @@ a {
|
||||
</body>
|
||||
</html>",
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "html-key",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: green;
|
||||
}",
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';",
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "final-key",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
"tests": Array [
|
||||
Object {
|
||||
@ -385,89 +385,89 @@ assert(
|
||||
|
||||
exports[`challenge parser should parse a simple md file 1`] = `
|
||||
Object {
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class=\\"language-html\\">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"files": Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
"challengeFiles": Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
],
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class=\\"language-html\\">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"instructions": "<section id=\\"instructions\\">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class=\\"language-html\\">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"solutions": Array [
|
||||
Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}",
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "html-key",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}",
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';
|
||||
\`\`",
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
"tests": Array [
|
||||
Object {
|
||||
@ -491,54 +491,54 @@ if(let x of xs) {
|
||||
|
||||
exports[`challenge parser should parse frontmatter 1`] = `
|
||||
Object {
|
||||
"challengeType": 0,
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class=\\"language-html\\">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"files": Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
"challengeFiles": Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
],
|
||||
"challengeType": 0,
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>Paragraph 1</p>
|
||||
<pre><code class=\\"language-html\\">code example
|
||||
</code></pre>
|
||||
</section>",
|
||||
"forumTopicId": 18276,
|
||||
"id": "bd7123c8c441eddfaeb5bdef",
|
||||
"isHidden": false,
|
||||
"solutions": Array [
|
||||
Object {},
|
||||
Array [],
|
||||
],
|
||||
"tests": Array [
|
||||
Object {
|
||||
@ -557,6 +557,43 @@ Object {
|
||||
|
||||
exports[`challenge parser should parse gfm strikethrough and frontmatter 1`] = `
|
||||
Object {
|
||||
"challengeFiles": Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
],
|
||||
"description": "<section id=\\"description\\">
|
||||
<p>Paragraph 1 <del>Strikethrough text</del>. https://should.not.be.autolinked</p>
|
||||
<pre><code class=\\"language-html\\">code example
|
||||
@ -576,84 +613,47 @@ Object {
|
||||
</tbody>
|
||||
</table>
|
||||
</section>",
|
||||
"files": Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "html",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
"instructions": "<section id=\\"instructions\\">
|
||||
<p>Paragraph 0</p>
|
||||
<pre><code class=\\"language-html\\">code example 0
|
||||
</code></pre>
|
||||
</section>",
|
||||
"solutions": Array [
|
||||
Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}",
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "html-key",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}",
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';
|
||||
\`\`",
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
"tests": Array [
|
||||
Object {
|
||||
|
@ -2,42 +2,42 @@
|
||||
|
||||
exports[`add-seed plugin should have an output to match the snapshot 1`] = `
|
||||
Object {
|
||||
"files": Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
"challengeFiles": Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: green;
|
||||
}",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';",
|
||||
"editableRegionBoundaries": Array [],
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
@ -3,41 +3,41 @@
|
||||
exports[`add solution plugin should have an output to match the snapshot 1`] = `
|
||||
Object {
|
||||
"solutions": Array [
|
||||
Object {
|
||||
"indexcss": Object {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}",
|
||||
"ext": "css",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexcss",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexhtml": Object {
|
||||
Array [
|
||||
Object {
|
||||
"contents": "<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>",
|
||||
"ext": "html",
|
||||
"fileKey": "indexhtml",
|
||||
"head": "",
|
||||
"id": "html-key",
|
||||
"key": "indexhtml",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
"indexjs": Object {
|
||||
Object {
|
||||
"contents": "body {
|
||||
background: white;
|
||||
}",
|
||||
"ext": "css",
|
||||
"fileKey": "indexcss",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
Object {
|
||||
"contents": "var x = 'y';
|
||||
\`\`",
|
||||
"ext": "js",
|
||||
"fileKey": "indexjs",
|
||||
"head": "",
|
||||
"id": "",
|
||||
"key": "indexjs",
|
||||
"name": "index",
|
||||
"tail": "",
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
@ -7,8 +7,8 @@ const { getFileVisitor } = require('./utils/get-file-visitor');
|
||||
|
||||
const editableRegionMarker = '--fcc-editable-region--';
|
||||
|
||||
function findRegionMarkers(file) {
|
||||
const lines = file.contents.split('\n');
|
||||
function findRegionMarkers(challengeFile) {
|
||||
const lines = challengeFile.contents.split('\n');
|
||||
const editableLines = lines
|
||||
.map((line, id) => (line.trim() === editableRegionMarker ? id : -1))
|
||||
.filter(id => id >= 0);
|
||||
@ -55,26 +55,33 @@ function addSeeds() {
|
||||
visitForContents(contentsTree);
|
||||
visitForHead(headTree);
|
||||
visitForTail(tailTree);
|
||||
const seedVals = Object.values(seeds);
|
||||
file.data = {
|
||||
...file.data,
|
||||
files: seeds
|
||||
challengeFiles: seedVals
|
||||
};
|
||||
|
||||
// process region markers - remove them from content and add them to data
|
||||
Object.keys(seeds).forEach(key => {
|
||||
const fileData = seeds[key];
|
||||
const editRegionMarkers = findRegionMarkers(fileData);
|
||||
const challengeFiles = Object.values(seeds).map(data => {
|
||||
const seed = { ...data };
|
||||
const editRegionMarkers = findRegionMarkers(seed);
|
||||
if (editRegionMarkers) {
|
||||
fileData.contents = removeLines(fileData.contents, editRegionMarkers);
|
||||
seed.contents = removeLines(seed.contents, editRegionMarkers);
|
||||
|
||||
if (editRegionMarkers[1] <= editRegionMarkers[0]) {
|
||||
throw Error('Editable region must be non zero');
|
||||
}
|
||||
fileData.editableRegionBoundaries = editRegionMarkers;
|
||||
seed.editableRegionBoundaries = editRegionMarkers;
|
||||
} else {
|
||||
fileData.editableRegionBoundaries = [];
|
||||
seed.editableRegionBoundaries = [];
|
||||
}
|
||||
return seed;
|
||||
});
|
||||
|
||||
file.data = {
|
||||
...file.data,
|
||||
challengeFiles
|
||||
};
|
||||
}
|
||||
|
||||
return transformer;
|
||||
|
@ -1,4 +1,3 @@
|
||||
const { isObject } = require('lodash');
|
||||
const isArray = require('lodash/isArray');
|
||||
|
||||
const adjacentKeysAST = require('../__fixtures__/ast-adjacent-keys.json');
|
||||
@ -32,26 +31,26 @@ describe('add-seed plugin', () => {
|
||||
expect(typeof plugin).toEqual('function');
|
||||
});
|
||||
|
||||
it('adds a `files` property to `file.data`', () => {
|
||||
it('adds a `challengeFiles` property to `file.data`', () => {
|
||||
plugin(simpleAST, file);
|
||||
expect('files' in file.data).toBe(true);
|
||||
expect('challengeFiles' in file.data).toBe(true);
|
||||
});
|
||||
|
||||
it('ensures that the `files` property is an object', () => {
|
||||
it('ensures that the `challengeFiles` property is an array', () => {
|
||||
plugin(simpleAST, file);
|
||||
expect(isObject(file.data.files)).toBe(true);
|
||||
expect(isArray(file.data.challengeFiles)).toBe(true);
|
||||
});
|
||||
|
||||
it('adds test objects to the files array following a schema', () => {
|
||||
it('adds test objects to the challengeFiles array following a schema', () => {
|
||||
expect.assertions(17);
|
||||
plugin(simpleAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const testObject = files.indexjs;
|
||||
const testObject = challengeFiles.find(x => x.fileKey === 'indexjs');
|
||||
expect(Object.keys(testObject).length).toEqual(8);
|
||||
expect(testObject).toHaveProperty('key');
|
||||
expect(typeof testObject['key']).toBe('string');
|
||||
expect(testObject).toHaveProperty('fileKey');
|
||||
expect(typeof testObject['fileKey']).toBe('string');
|
||||
expect(testObject).toHaveProperty('ext');
|
||||
expect(typeof testObject['ext']).toBe('string');
|
||||
expect(testObject).toHaveProperty('name');
|
||||
@ -69,33 +68,32 @@ describe('add-seed plugin', () => {
|
||||
});
|
||||
|
||||
it('parses seeds without ids', () => {
|
||||
expect.assertions(6);
|
||||
expect.assertions(3);
|
||||
plugin(simpleAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const { indexjs, indexhtml, indexcss } = files;
|
||||
const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs');
|
||||
const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml');
|
||||
const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss');
|
||||
|
||||
expect(indexjs.contents).toBe(`var x = 'y';`);
|
||||
expect(indexjs.key).toBe(`indexjs`);
|
||||
expect(indexhtml.contents).toBe(`<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>`);
|
||||
expect(indexhtml.key).toBe(`indexhtml`);
|
||||
expect(indexcss.contents).toBe(`body {
|
||||
background: green;
|
||||
}`);
|
||||
expect(indexcss.key).toBe(`indexcss`);
|
||||
});
|
||||
|
||||
it('removes region markers from contents', () => {
|
||||
expect.assertions(2);
|
||||
plugin(withEditableAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const { indexcss } = files;
|
||||
const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss');
|
||||
|
||||
expect(indexcss.contents).not.toMatch('--fcc-editable-region--');
|
||||
expect(indexcss.editableRegionBoundaries).toEqual([1, 4]);
|
||||
@ -107,9 +105,11 @@ describe('add-seed plugin', () => {
|
||||
expect.assertions(3);
|
||||
plugin(withSeedKeysAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const { indexhtml, indexcss, indexjs } = files;
|
||||
const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs');
|
||||
const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml');
|
||||
const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss');
|
||||
|
||||
expect(indexhtml.id).toBe('');
|
||||
expect(indexcss.id).toBe('key-for-css');
|
||||
@ -138,9 +138,11 @@ describe('add-seed plugin', () => {
|
||||
expect.assertions(3);
|
||||
plugin(withBeforeAfterAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const { indexjs, indexhtml, indexcss } = files;
|
||||
const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs');
|
||||
const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml');
|
||||
const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss');
|
||||
|
||||
expect(indexjs.head).toBe('');
|
||||
expect(indexhtml.head).toBe(`<!-- comment -->`);
|
||||
@ -153,9 +155,11 @@ describe('add-seed plugin', () => {
|
||||
expect.assertions(3);
|
||||
plugin(withBeforeAfterAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const { indexjs, indexhtml, indexcss } = files;
|
||||
const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs');
|
||||
const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml');
|
||||
const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss');
|
||||
|
||||
expect(indexjs.tail).toBe(`function teardown(params) {
|
||||
// after
|
||||
@ -188,9 +192,11 @@ describe('add-seed plugin', () => {
|
||||
expect.assertions(6);
|
||||
plugin(emptyBeforeAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const { indexjs, indexhtml, indexcss } = files;
|
||||
const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs');
|
||||
const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml');
|
||||
const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss');
|
||||
|
||||
expect(indexjs.head).toBe('');
|
||||
expect(indexjs.tail).toBe('function teardown(params) {\n // after\n}');
|
||||
@ -204,9 +210,11 @@ describe('add-seed plugin', () => {
|
||||
expect.assertions(6);
|
||||
plugin(emptyAfterAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const { indexjs, indexhtml, indexcss } = files;
|
||||
const indexjs = challengeFiles.find(x => x.fileKey === 'indexjs');
|
||||
const indexhtml = challengeFiles.find(x => x.fileKey === 'indexhtml');
|
||||
const indexcss = challengeFiles.find(x => x.fileKey === 'indexcss');
|
||||
|
||||
expect(indexjs.head).toBe('');
|
||||
expect(indexjs.tail).toBe('');
|
||||
@ -234,9 +242,9 @@ describe('add-seed plugin', () => {
|
||||
expect.assertions(4);
|
||||
plugin(jsxSeedAST, file);
|
||||
const {
|
||||
data: { files }
|
||||
data: { challengeFiles }
|
||||
} = file;
|
||||
const { indexjsx } = files;
|
||||
const indexjsx = challengeFiles.find(x => x.fileKey === 'indexjsx');
|
||||
|
||||
expect(indexjsx.head).toBe(`function setup() {}`);
|
||||
expect(indexjsx.tail).toBe(`function teardown(params) {
|
||||
@ -248,7 +256,7 @@ describe('add-seed plugin', () => {
|
||||
const Button = () => {
|
||||
return <button> {/* another comment! */} text </button>;
|
||||
};`);
|
||||
expect(indexjsx.key).toBe(`indexjsx`);
|
||||
expect(indexjsx.fileKey).toBe(`indexjsx`);
|
||||
});
|
||||
|
||||
it('combines all the code of a specific language into a single file', () => {
|
||||
|
@ -30,7 +30,7 @@ function createPlugin() {
|
||||
);
|
||||
|
||||
visitForContents(solutionTree);
|
||||
solutions.push(solution);
|
||||
solutions.push(Object.values(solution));
|
||||
});
|
||||
|
||||
file.data = {
|
||||
|
@ -33,16 +33,18 @@ describe('add solution plugin', () => {
|
||||
expect(file.data.solutions.every(el => isObject(el))).toBe(true);
|
||||
});
|
||||
|
||||
it('adds solution objects to the files array following a schema', () => {
|
||||
it('adds solution objects to the challengeFiles array following a schema', () => {
|
||||
expect.assertions(15);
|
||||
plugin(mockAST, file);
|
||||
const {
|
||||
data: { solutions }
|
||||
} = file;
|
||||
const testObject = solutions[0].indexjs;
|
||||
const testObject = solutions[0].find(
|
||||
solution => solution.fileKey === 'indexjs'
|
||||
);
|
||||
expect(Object.keys(testObject).length).toEqual(7);
|
||||
expect(testObject).toHaveProperty('key');
|
||||
expect(typeof testObject['key']).toBe('string');
|
||||
expect(testObject).toHaveProperty('fileKey');
|
||||
expect(typeof testObject['fileKey']).toBe('string');
|
||||
expect(testObject).toHaveProperty('ext');
|
||||
expect(typeof testObject['ext']).toBe('string');
|
||||
expect(testObject).toHaveProperty('name');
|
||||
@ -64,16 +66,24 @@ describe('add solution plugin', () => {
|
||||
data: { solutions }
|
||||
} = file;
|
||||
expect(solutions.length).toBe(3);
|
||||
expect(solutions[0].indexjs.contents).toBe("var x = 'y';");
|
||||
expect(solutions[1].indexhtml.contents).toBe(`<html>
|
||||
expect(
|
||||
solutions[0].find(solution => solution.fileKey === 'indexjs').contents
|
||||
).toBe("var x = 'y';");
|
||||
expect(
|
||||
solutions[1].find(solution => solution.fileKey === 'indexhtml').contents
|
||||
).toBe(`<html>
|
||||
<body>
|
||||
solution number two
|
||||
</body>
|
||||
</html>`);
|
||||
expect(solutions[1].indexcss.contents).toBe(`body {
|
||||
expect(
|
||||
solutions[1].find(solution => solution.fileKey === 'indexcss').contents
|
||||
).toBe(`body {
|
||||
background: white;
|
||||
}`);
|
||||
expect(solutions[2].indexjs.contents).toBe("var x = 'y3';");
|
||||
expect(
|
||||
solutions[2].find(solution => solution.fileKey === 'indexjs').contents
|
||||
).toBe("var x = 'y3';");
|
||||
});
|
||||
|
||||
it('should reject solutions with editable region markers', () => {
|
||||
|
@ -12,7 +12,7 @@ const supportedLanguages = ['js', 'css', 'html', 'jsx', 'py'];
|
||||
|
||||
function defaultFile(lang, id) {
|
||||
return {
|
||||
key: `index${lang}`,
|
||||
fileKey: `index${lang}`,
|
||||
ext: lang,
|
||||
name: 'index',
|
||||
contents: '',
|
||||
@ -43,21 +43,21 @@ function codeToData(node, seeds, seedKey, validate) {
|
||||
Please use one of js, css, html, jsx or py
|
||||
`);
|
||||
|
||||
const key = `index${lang}`;
|
||||
const id = seeds[key] ? seeds[key].id : '';
|
||||
const fileKey = `index${lang}`;
|
||||
const id = seeds[fileKey] ? seeds[fileKey].id : '';
|
||||
// the contents will be missing if there is an id preceding this code
|
||||
// block.
|
||||
if (!seeds[key]) {
|
||||
seeds[key] = defaultFile(lang, id);
|
||||
if (!seeds[fileKey]) {
|
||||
seeds[fileKey] = defaultFile(lang, id);
|
||||
}
|
||||
if (isEmpty(node.value) && seedKey !== 'contents') {
|
||||
const section = keyToSection[seedKey];
|
||||
throw Error(`Empty code block in --${section}-- section`);
|
||||
}
|
||||
|
||||
seeds[key][seedKey] = isEmpty(seeds[key][seedKey])
|
||||
seeds[fileKey][seedKey] = isEmpty(seeds[fileKey][seedKey])
|
||||
? node.value
|
||||
: seeds[key][seedKey] + '\n' + node.value;
|
||||
: seeds[fileKey][seedKey] + '\n' + node.value;
|
||||
}
|
||||
|
||||
function idToData(node, index, parent, seeds) {
|
||||
@ -73,9 +73,9 @@ function idToData(node, index, parent, seeds) {
|
||||
}
|
||||
const codeNode = parent.children[index + 1];
|
||||
if (codeNode && is(codeNode, 'code')) {
|
||||
const key = `index${codeNode.lang}`;
|
||||
if (seeds[key]) throw Error('::id{#id}s must come before code blocks');
|
||||
seeds[key] = defaultFile(codeNode.lang, id);
|
||||
const fileKey = `index${codeNode.lang}`;
|
||||
if (seeds[fileKey]) throw Error('::id{#id}s must come before code blocks');
|
||||
seeds[fileKey] = defaultFile(codeNode.lang, id);
|
||||
} else {
|
||||
throw Error('::id{#id}s must come before code blocks');
|
||||
}
|
||||
|
Reference in New Issue
Block a user