Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 1 addition & 127 deletions docs/labs/deserialization.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,137 +7,11 @@
<link rel="stylesheet" href="checker.css">
<script src="js-yaml.min.js"></script>
<script src="checker.js"></script>
<script src="deserialization.js"></script>
<link rel="license" href="https://creativecommons.org/licenses/by/4.0/">

<!-- See create_labs.md for how to create your own lab! -->

<!-- Sample expected answer -->
<script id="expected0" type="plain/text">
const data = JSON.parse(base64Decoded);
</script>
<!--
-->
<script id="expected1" type="plain/text">
if (data.username && typeof data.username == 'string' && data.username.length < 20) {
</script>

<!-- Full pattern of correct answer -->
<script id="correct0" type="plain/text">
\s* const data = JSON \. parse \( base64Decoded \) \; \s*
</script>
<script id="correct1" type="plain/text">
\s* if \( CONDALL \) \{ \s*
</script>

<script id="info" type="application/yaml">
---
# Allow condition subexpressions to be optionally surrounded by parentheses
# and allow the order to vary. This allows more real-world answers to be
# considered acceptable.
# Doing this is more easily done by buildigg up definitions,
# which is annoying to write but general.
definitions:
- term: COND0
value: |-
data \. username
- term: COND0
value: |-
(COND0|\( COND0 \))
- term: COND1
value: |-
typeof\s+data \. username == ('string'|"string"|`string`)
- term: COND1
value: |-
(COND1|\( COND1 \))
- term: COND2
value: |-
data \. username \. length < 20
- term: COND2
value: |-
(COND2|\( COND2 \))
# Only the first one is likely, but we may as well allow both possibilities.
# The first condition MUST be first because it checks if the value exists.
- term: CONDALL
value: |-
(COND0 && (COND1 && COND2|COND2 && COND1))
hints:
- absent: |
^ const data =
text: The first section should begin with `const data =`
- present: "json"
text: the JSON built-in global object is witten in uppercase.
- absent: |
JSON \. parse
text: Make a call to `JSON.parse` with the data retrieved, e.g.,
`JSON.parse(base64Decoded)` should be stored in `data`.
- present: |
\+
text: You should not have any concatenation (`+`) in the first section.
- absent: |
; $
text: JavaScript does not require semicolons at the end of a
statement, but since the other statements terminate with semicolons,
you should also terminate your statement with a semicolon to be consistent.
- absent: |-
^ if \(
index: 1
text: The second section should start with `if (` followed by a condition.
examples:
-
- const data = JSON.parse(base64Decoded);
- |
if data.username {
- absent: |
data \. username
index: 1
text: Check if the data object has a property called username. You can do this by referencing data.username.
- absent: \&\&
index: 1
text: To combine multiple conditions in JavaScript use &&. This operator means 'and', so both conditions must be true for the entire statement to pass.
- absent: typeof
index: 1
text: Use typeof to check the type of the operand's value.
You should have `typeof data.username == 'string'`
or similar.
- present: |
typeof data \. username == 'String'
index: 1
text: When using typeof, JavaScript expects "string" all lowercase.
- absent: length
index: 1
text: check if the length of the string is smaller than 20 characters.
Use the expression `data.username.length &lt; 20` to determine this.
- present: |-
^ if \(
absent: |-
^ if \( data \. username &&
index: 1
text: Begin the second section with `if ( data.username && ... `
because you must check if data is even present before you can check
various attributes of that data.
examples:
-
- "const data = JSON.parse(base64Decoded);"
- "if (typeof data.username == 'string' && data.username.length < 20 && data.username) {"
successes:
-
- const data = JSON.parse(base64Decoded);
- if (data.username && typeof data.username == 'string' && data.username.length < 20) {
-
- const data = JSON . parse ( base64Decoded ) ;
- if ( data . username && typeof data . username == 'string' && data . username.length < 20) {
-
- const data = JSON.parse(base64Decoded);
- if (data.username && (typeof data.username == 'string') && (data.username.length < 20)) {
-
- const data = JSON.parse(base64Decoded);
- if (data.username && typeof data.username == 'string' && (data.username.length < 20)) {
failures:
-
- const data = JSON.parse(base64Decoded);
- if (data.username && (typeof data.username == 'string')) && (data.username.length < 20)) {
# debug: true
</script>
</head>
<body>
<!-- For GitHub Pages formatting: -->
Expand Down
139 changes: 139 additions & 0 deletions docs/labs/deserialization.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
info =
{
definitions: [
{
term: "COND0",
value: String.raw`data \. username`
},
{
term: "COND0",
value: String.raw`(COND0|\( COND0 \))`
},
{
term: "COND1",
value: String.raw`typeof\s+data \. username == ('string'|"string"|${BACKQUOTE}string${BACKQUOTE})`
},
{
term: "COND1",
value: String.raw`(COND1|\( COND1 \))`
},
{
term: "COND2",
value: String.raw`data \. username \. length < 20`
},
{
term: "COND2",
value: String.raw`(COND2|\( COND2 \))`
},
{
term: "CONDALL",
value: "(COND0 && (COND1 && COND2|COND2 && COND1))"
}
],
hints: [
{
absent: "^ const data =\n",
text: "The first section should begin with `const data =`"
},
{
present: "json",
text: "the JSON built-in global object is witten in uppercase."
},
{
absent: String.raw`JSON \. parse
`,
text: "Make a call to `JSON.parse` with the data retrieved, e.g., `JSON.parse(base64Decoded)` should be stored in `data`."
},
{
present: String.raw`\+
`,
text: "You should not have any concatenation (`+`) in the first section."
},
{
absent: "; $\n",
text: "JavaScript does not require semicolons at the end of a statement, but since the other statements terminate with semicolons, you should also terminate your statement with a semicolon to be consistent."
},
{
absent: String.raw`^ if \(`,
index: 1,
text: "The second section should start with `if (` followed by a condition.",
examples: [
[
"const data = JSON.parse(base64Decoded);",
"if data.username {\n"
]
]
},
{
absent: String.raw`data \. username
`,
index: 1,
text: "Check if the data object has a property called username. You can do this by referencing data.username."
},
{
absent: String.raw`\&\&`,
index: 1,
text: "To combine multiple conditions in JavaScript use &&. This operator means 'and', so both conditions must be true for the entire statement to pass."
},
{
absent: "typeof",
index: 1,
text: "Use typeof to check the type of the operand's value. You should have `typeof data.username == 'string'` or similar."
},
{
present: String.raw`typeof data \. username == 'String'
`,
index: 1,
text: "When using typeof, JavaScript expects \"string\" all lowercase."
},
{
absent: "length",
index: 1,
text: "check if the length of the string is smaller than 20 characters. Use the expression `data.username.length &lt; 20` to determine this."
},
{
present: String.raw`^ if \(`,
absent: String.raw`^ if \( data \. username &&`,
index: 1,
text: "Begin the second section with `if ( data.username && ... ` because you must check if data is even present before you can check various attributes of that data.",
examples: [
[
"const data = JSON.parse(base64Decoded);",
"if (typeof data.username == 'string' && data.username.length < 20 && data.username) {"
]
]
}
],
expected: [
' const data = JSON.parse(base64Decoded);',
` if (data.username && typeof data.username == 'string' && data.username.length < 20) {`
],
correct: [
String.raw`\s* const data = JSON \. parse \( base64Decoded \) \; \s*`,
String.raw`\s* if \( CONDALL \) \{ \s*`
],
successes: [
[
"const data = JSON.parse(base64Decoded);",
"if (data.username && typeof data.username == 'string' && data.username.length < 20) {"
],
[
"const data = JSON . parse ( base64Decoded ) ;",
"if ( data . username && typeof data . username == 'string' && data . username.length < 20) {"
],
[
"const data = JSON.parse(base64Decoded);",
"if (data.username && (typeof data.username == 'string') && (data.username.length < 20)) {"
],
[
"const data = JSON.parse(base64Decoded);",
"if (data.username && typeof data.username == 'string' && (data.username.length < 20)) {"
]
],
failures: [
[
"const data = JSON.parse(base64Decoded);",
"if (data.username && (typeof data.username == 'string')) && (data.username.length < 20)) {"
]
]
}