diff --git a/tests/unit/data/benchmark.json b/tests/unit/data/benchmark.json index 5e0677bc..2efeaa21 100644 --- a/tests/unit/data/benchmark.json +++ b/tests/unit/data/benchmark.json @@ -79,12 +79,7 @@ "default_branch": "master", "open_issues_count": 0, "is_template": true, - "topics": [ - "octocat", - "atom", - "electron", - "api" - ], + "topics": ["octocat", "atom", "electron", "api"], "has_issues": true, "has_projects": true, "has_wiki": true, @@ -96,11 +91,7 @@ "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", - "permissions": { - "admin": false, - "push": false, - "pull": true - }, + "permissions": { "admin": false, "push": false, "pull": true }, "template_repository": "octocat/template", "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "delete_branch_on_merge": true, diff --git a/tests/unit/data/mustache_comments.json b/tests/unit/data/mustache_comments.json index eb2fc158..6cd078f7 100644 --- a/tests/unit/data/mustache_comments.json +++ b/tests/unit/data/mustache_comments.json @@ -1,83 +1,83 @@ { - "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", - "overview": "Comment tags represent content that should never appear in the resulting\noutput.\n\nThe tag's content may contain any substring (including newlines) EXCEPT the\nclosing delimiter.\n\nComment tags SHOULD be treated as standalone when appropriate.\n", - "tests": [ - { - "name": "Inline", - "data": {}, - "expected": "1234567890", - "template": "12345{{! Comment Block! }}67890", - "desc": "Comment blocks should be removed from the template." - }, - { - "name": "Multiline", - "data": {}, - "expected": "1234567890\n", - "template": "12345{{!\n This is a\n multi-line comment...\n}}67890\n", - "desc": "Multiline comments should be permitted." - }, - { - "name": "Standalone", - "data": {}, - "expected": "Begin.\nEnd.\n", - "template": "Begin.\n{{! Comment Block! }}\nEnd.\n", - "desc": "All standalone comment lines should be removed." - }, - { - "name": "Indented Standalone", - "data": {}, - "expected": "Begin.\nEnd.\n", - "template": "Begin.\n {{! Indented Comment Block! }}\nEnd.\n", - "desc": "All standalone comment lines should be removed." - }, - { - "name": "Standalone Line Endings", - "data": {}, - "expected": "|\r\n|", - "template": "|\r\n{{! Standalone Comment }}\r\n|", - "desc": "\"\\r\\n\" should be considered a newline for standalone tags." - }, - { - "name": "Standalone Without Previous Line", - "data": {}, - "expected": "!", - "template": " {{! I'm Still Standalone }}\n!", - "desc": "Standalone tags should not require a newline to precede them." - }, - { - "name": "Standalone Without Newline", - "data": {}, - "expected": "!\n", - "template": "!\n {{! I'm Still Standalone }}", - "desc": "Standalone tags should not require a newline to follow them." - }, - { - "name": "Multiline Standalone", - "data": {}, - "expected": "Begin.\nEnd.\n", - "template": "Begin.\n{{!\nSomething's going on here...\n}}\nEnd.\n", - "desc": "All standalone comment lines should be removed." - }, - { - "name": "Indented Multiline Standalone", - "data": {}, - "expected": "Begin.\nEnd.\n", - "template": "Begin.\n {{!\n Something's going on here...\n }}\nEnd.\n", - "desc": "All standalone comment lines should be removed." - }, - { - "name": "Indented Inline", - "data": {}, - "expected": " 12 \n", - "template": " 12 {{! 34 }}\n", - "desc": "Inline comments should not strip whitespace" - }, - { - "name": "Surrounding Whitespace", - "data": {}, - "expected": "12345 67890", - "template": "12345 {{! Comment Block! }} 67890", - "desc": "Comment removal should preserve surrounding whitespace." - } - ] + "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", + "overview": "Comment tags represent content that should never appear in the resulting\noutput.\n\nThe tag's content may contain any substring (including newlines) EXCEPT the\nclosing delimiter.\n\nComment tags SHOULD be treated as standalone when appropriate.\n", + "tests": [ + { + "name": "Inline", + "data": {}, + "expected": "1234567890", + "template": "12345{{! Comment Block! }}67890", + "desc": "Comment blocks should be removed from the template." + }, + { + "name": "Multiline", + "data": {}, + "expected": "1234567890\n", + "template": "12345{{!\n This is a\n multi-line comment...\n}}67890\n", + "desc": "Multiline comments should be permitted." + }, + { + "name": "Standalone", + "data": {}, + "expected": "Begin.\nEnd.\n", + "template": "Begin.\n{{! Comment Block! }}\nEnd.\n", + "desc": "All standalone comment lines should be removed." + }, + { + "name": "Indented Standalone", + "data": {}, + "expected": "Begin.\nEnd.\n", + "template": "Begin.\n {{! Indented Comment Block! }}\nEnd.\n", + "desc": "All standalone comment lines should be removed." + }, + { + "name": "Standalone Line Endings", + "data": {}, + "expected": "|\r\n|", + "template": "|\r\n{{! Standalone Comment }}\r\n|", + "desc": "\"\\r\\n\" should be considered a newline for standalone tags." + }, + { + "name": "Standalone Without Previous Line", + "data": {}, + "expected": "!", + "template": " {{! I'm Still Standalone }}\n!", + "desc": "Standalone tags should not require a newline to precede them." + }, + { + "name": "Standalone Without Newline", + "data": {}, + "expected": "!\n", + "template": "!\n {{! I'm Still Standalone }}", + "desc": "Standalone tags should not require a newline to follow them." + }, + { + "name": "Multiline Standalone", + "data": {}, + "expected": "Begin.\nEnd.\n", + "template": "Begin.\n{{!\nSomething's going on here...\n}}\nEnd.\n", + "desc": "All standalone comment lines should be removed." + }, + { + "name": "Indented Multiline Standalone", + "data": {}, + "expected": "Begin.\nEnd.\n", + "template": "Begin.\n {{!\n Something's going on here...\n }}\nEnd.\n", + "desc": "All standalone comment lines should be removed." + }, + { + "name": "Indented Inline", + "data": {}, + "expected": " 12 \n", + "template": " 12 {{! 34 }}\n", + "desc": "Inline comments should not strip whitespace" + }, + { + "name": "Surrounding Whitespace", + "data": {}, + "expected": "12345 67890", + "template": "12345 {{! Comment Block! }} 67890", + "desc": "Comment removal should preserve surrounding whitespace." + } + ] } diff --git a/tests/unit/data/mustache_delimiters.json b/tests/unit/data/mustache_delimiters.json index de1c22ba..803f1795 100644 --- a/tests/unit/data/mustache_delimiters.json +++ b/tests/unit/data/mustache_delimiters.json @@ -1,77 +1,67 @@ { - "tests": [ - { - "name": "Pair Behavior", - "data": { - "text": "Hey!" - }, - "expected": "(Hey!)", - "template": "{{=<% %>=}}(<%text%>)", - "desc": "The equals sign (used on both sides) should permit delimiter changes." - }, - { - "name": "Special Characters", - "data": { - "text": "It worked!" - }, - "expected": "(It worked!)", - "template": "({{=[ ]=}}[text])", - "desc": "Characters with special meaning regexen should be valid delimiters." - }, - { - "name": "Sections", - "data": { - "section": true, - "data": "I got interpolated." - }, - "expected": "[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n", - "template": "[\n{{#section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|#section|\n {{data}}\n |data|\n|/section|\n]\n", - "desc": "Delimiters set outside sections should persist." - }, - { - "name": "Inverted Sections", - "data": { - "section": false, - "data": "I got interpolated." - }, - "expected": "[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n", - "template": "[\n{{^section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|^section|\n {{data}}\n |data|\n|/section|\n]\n", - "desc": "Delimiters set outside inverted sections should persist." - }, - { - "name": "Surrounding Whitespace", - "data": {}, - "expected": "| |", - "template": "| {{=@ @=}} |", - "desc": "Surrounding whitespace should be left untouched." - }, - { - "name": "Outlying Whitespace (Inline)", - "data": {}, - "expected": " | \n", - "template": " | {{=@ @=}}\n", - "desc": "Whitespace should be left untouched." - }, - { - "name": "Standalone Tag", - "data": {}, - "expected": "Begin.\nEnd.\n", - "template": "Begin.\n{{=@ @=}}\nEnd.\n", - "desc": "Standalone lines should be removed from the template." - }, - { - "name": "Indented Standalone Tag", - "data": {}, - "expected": "Begin.\nEnd.\n", - "template": "Begin.\n {{=@ @=}}\nEnd.\n", - "desc": "Indented standalone lines should be removed from the template." - }, - { - "name": "Pair with Padding", - "data": {}, - "expected": "||", - "template": "|{{= @ @ =}}|", - "desc": "Superfluous in-tag whitespace should be ignored." - } - ] + "tests": [ + { + "name": "Pair Behavior", + "data": { "text": "Hey!" }, + "expected": "(Hey!)", + "template": "{{=<% %>=}}(<%text%>)", + "desc": "The equals sign (used on both sides) should permit delimiter changes." + }, + { + "name": "Special Characters", + "data": { "text": "It worked!" }, + "expected": "(It worked!)", + "template": "({{=[ ]=}}[text])", + "desc": "Characters with special meaning regexen should be valid delimiters." + }, + { + "name": "Sections", + "data": { "section": true, "data": "I got interpolated." }, + "expected": "[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n", + "template": "[\n{{#section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|#section|\n {{data}}\n |data|\n|/section|\n]\n", + "desc": "Delimiters set outside sections should persist." + }, + { + "name": "Inverted Sections", + "data": { "section": false, "data": "I got interpolated." }, + "expected": "[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n", + "template": "[\n{{^section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|^section|\n {{data}}\n |data|\n|/section|\n]\n", + "desc": "Delimiters set outside inverted sections should persist." + }, + { + "name": "Surrounding Whitespace", + "data": {}, + "expected": "| |", + "template": "| {{=@ @=}} |", + "desc": "Surrounding whitespace should be left untouched." + }, + { + "name": "Outlying Whitespace (Inline)", + "data": {}, + "expected": " | \n", + "template": " | {{=@ @=}}\n", + "desc": "Whitespace should be left untouched." + }, + { + "name": "Standalone Tag", + "data": {}, + "expected": "Begin.\nEnd.\n", + "template": "Begin.\n{{=@ @=}}\nEnd.\n", + "desc": "Standalone lines should be removed from the template." + }, + { + "name": "Indented Standalone Tag", + "data": {}, + "expected": "Begin.\nEnd.\n", + "template": "Begin.\n {{=@ @=}}\nEnd.\n", + "desc": "Indented standalone lines should be removed from the template." + }, + { + "name": "Pair with Padding", + "data": {}, + "expected": "||", + "template": "|{{= @ @ =}}|", + "desc": "Superfluous in-tag whitespace should be ignored." + } + ] } diff --git a/tests/unit/data/mustache_extra.json b/tests/unit/data/mustache_extra.json index a69973b9..ac77a5a6 100644 --- a/tests/unit/data/mustache_extra.json +++ b/tests/unit/data/mustache_extra.json @@ -1,66 +1,66 @@ { - "tests": [ - { - "name": "Demo", - "data": { - "header": "Colors", - "items": [ - {"name": "red", "first": true, "url": "#Red"}, - {"name": "green", "link": true, "url": "#Green"}, - {"name": "blue", "link": true, "url": "#Blue"} - ], - "empty": false - }, - "expected": "

Colors

\n\n
  • red
  • \n
  • green
  • \n
  • blue
  • \n\n", - "template": "

    {{header}}

    \n{{#bug}}\n{{/bug}}\n\n{{#items}}\n {{#first}}\n
  • {{name}}
  • \n {{/first}}\n {{#link}}\n
  • {{name}}
  • \n {{/link}}\n{{/items}}\n\n{{#empty}}\n

    The list is empty.

    \n{{/empty}}\n" - }, - { - "name": "Ted's Abusive Test 1", - "data": { "x": 123 }, - "template": "{{x}}", - "expected": "123" - }, - { - "name": "Ted's Abusive Test 2", - "data": { "x": 123, "y": 456 }, - "template": "{{x}} {{y}}", - "expected": "123 456" - }, - { - "name": "Ted's Abusive Test 3", - "data": [ null ], - "template": "{{null}}", - "expected": "" - }, - { - "name": "Ted's Abusive Test 4", - "data": { "x": 123, "y": 456 }, - "template": "{{}}", - "expected": "{{}}" - }, - { - "name": "Ted's Abusive Test 5", - "data": { "boolean": true}, - "template": "{{#boolean}}IT IS TRUE{{/boolean}}", - "expected": "IT IS TRUE" - }, - { - "name": "Ted's Abusive Test 6", - "data": { "boolean": false}, - "template": "{{^boolean}}IT IS FALSE{{/boolean}}", - "expected": "IT IS FALSE" - }, - { - "name": "Ted's Abusive Test 7", - "data": { "list": - [ - { "k": 789, "v": 0 }, - { "k": null, "v": true }, - { "k": -1, "v": -2 } - ] - }, - "template": "{{#list}}{{k}}={{v}}, {{/list}}", - "expected": "789=0, =true, -1=-2, " - } - ] + "tests": [ + { + "name": "Demo", + "data": { + "header": "Colors", + "items": [ + { "name": "red", "first": true, "url": "#Red" }, + { "name": "green", "link": true, "url": "#Green" }, + { "name": "blue", "link": true, "url": "#Blue" } + ], + "empty": false + }, + "expected": "

    Colors

    \n\n
  • red
  • \n
  • green
  • \n
  • blue
  • \n\n", + "template": "

    {{header}}

    \n{{#bug}}\n{{/bug}}\n\n{{#items}}\n {{#first}}\n
  • {{name}}
  • \n {{/first}}\n {{#link}}\n
  • {{name}}
  • \n {{/link}}\n{{/items}}\n\n{{#empty}}\n

    The list is empty.

    \n{{/empty}}\n" + }, + { + "name": "Ted's Abusive Test 1", + "data": { "x": 123 }, + "template": "{{x}}", + "expected": "123" + }, + { + "name": "Ted's Abusive Test 2", + "data": { "x": 123, "y": 456 }, + "template": "{{x}} {{y}}", + "expected": "123 456" + }, + { + "name": "Ted's Abusive Test 3", + "data": [null], + "template": "{{null}}", + "expected": "" + }, + { + "name": "Ted's Abusive Test 4", + "data": { "x": 123, "y": 456 }, + "template": "{{}}", + "expected": "{{}}" + }, + { + "name": "Ted's Abusive Test 5", + "data": { "boolean": true }, + "template": "{{#boolean}}IT IS TRUE{{/boolean}}", + "expected": "IT IS TRUE" + }, + { + "name": "Ted's Abusive Test 6", + "data": { "boolean": false }, + "template": "{{^boolean}}IT IS FALSE{{/boolean}}", + "expected": "IT IS FALSE" + }, + { + "name": "Ted's Abusive Test 7", + "data": { + "list": [ + { "k": 789, "v": 0 }, + { "k": null, "v": true }, + { "k": -1, "v": -2 } + ] + }, + "template": "{{#list}}{{k}}={{v}}, {{/list}}", + "expected": "789=0, =true, -1=-2, " + } + ] } diff --git a/tests/unit/data/mustache_interpolation.json b/tests/unit/data/mustache_interpolation.json index 0b2c03aa..a1fd4ec1 100644 --- a/tests/unit/data/mustache_interpolation.json +++ b/tests/unit/data/mustache_interpolation.json @@ -1,182 +1,144 @@ { - "tests": [ - { - "name": "No Interpolation", - "data": {}, - "expected": "Hello from {Mustache}!\n", - "template": "Hello from {Mustache}!\n", - "desc": "Mustache-free templates should render as-is." - }, - { - "name": "Basic Interpolation", - "data": { - "subject": "world" - }, - "expected": "Hello, world!\n", - "template": "Hello, {{subject}}!\n", - "desc": "Unadorned tags should interpolate content into the template." - }, - { - "name": "HTML Escaping", - "data": { - "forbidden": "& \" < >" - }, - "expected": "These characters should be HTML escaped: & " < >\n", - "template": "These characters should be HTML escaped: {{forbidden}}\n", - "desc": "Basic interpolation should be HTML escaped." - }, - { - "name": "Triple Mustache", - "data": { - "forbidden": "& \" < >" - }, - "expected": "These characters should not be HTML escaped: & \" < >\n", - "template": "These characters should not be HTML escaped: {{{forbidden}}}\n", - "desc": "Triple mustaches should interpolate without HTML escaping." - }, - { - "name": "Ampersand", - "data": { - "forbidden": "& \" < >" - }, - "expected": "These characters should not be HTML escaped: & \" < >\n", - "template": "These characters should not be HTML escaped: {{&forbidden}}\n", - "desc": "Ampersand should interpolate without HTML escaping." - }, - { - "name": "Basic Integer Interpolation", - "data": { - "mph": 85 - }, - "expected": "\"85 miles an hour!\"", - "template": "\"{{mph}} miles an hour!\"", - "desc": "Integers should interpolate seamlessly." - }, - { - "name": "Triple Mustache Integer Interpolation", - "data": { - "mph": 85 - }, - "expected": "\"85 miles an hour!\"", - "template": "\"{{{mph}}} miles an hour!\"", - "desc": "Integers should interpolate seamlessly." - }, - { - "name": "Ampersand Integer Interpolation", - "data": { - "mph": 85 - }, - "expected": "\"85 miles an hour!\"", - "template": "\"{{&mph}} miles an hour!\"", - "desc": "Integers should interpolate seamlessly." - }, - { - "name": "Basic Decimal Interpolation", - "data": { - "power": 1.21 - }, - "expected": "\"1.21 jiggawatts!\"", - "template": "\"{{power}} jiggawatts!\"", - "desc": "Decimals should interpolate seamlessly with proper significance." - }, - { - "name": "Triple Mustache Decimal Interpolation", - "data": { - "power": 1.21 - }, - "expected": "\"1.21 jiggawatts!\"", - "template": "\"{{{power}}} jiggawatts!\"", - "desc": "Decimals should interpolate seamlessly with proper significance." - }, - { - "name": "Ampersand Decimal Interpolation", - "data": { - "power": 1.21 - }, - "expected": "\"1.21 jiggawatts!\"", - "template": "\"{{&power}} jiggawatts!\"", - "desc": "Decimals should interpolate seamlessly with proper significance." - }, - { - "name": "Interpolation - Surrounding Whitespace", - "data": { - "string": "---" - }, - "expected": "| --- |", - "template": "| {{string}} |", - "desc": "Interpolation should not alter surrounding whitespace." - }, - { - "name": "Triple Mustache - Surrounding Whitespace", - "data": { - "string": "---" - }, - "expected": "| --- |", - "template": "| {{{string}}} |", - "desc": "Interpolation should not alter surrounding whitespace." - }, - { - "name": "Ampersand - Surrounding Whitespace", - "data": { - "string": "---" - }, - "expected": "| --- |", - "template": "| {{&string}} |", - "desc": "Interpolation should not alter surrounding whitespace." - }, - { - "name": "Interpolation - Standalone", - "data": { - "string": "---" - }, - "expected": " ---\n", - "template": " {{string}}\n", - "desc": "Standalone interpolation should not alter surrounding whitespace." - }, - { - "name": "Triple Mustache - Standalone", - "data": { - "string": "---" - }, - "expected": " ---\n", - "template": " {{{string}}}\n", - "desc": "Standalone interpolation should not alter surrounding whitespace." - }, - { - "name": "Ampersand - Standalone", - "data": { - "string": "---" - }, - "expected": " ---\n", - "template": " {{&string}}\n", - "desc": "Standalone interpolation should not alter surrounding whitespace." - }, - { - "name": "Interpolation With Padding", - "data": { - "string": "---" - }, - "expected": "|---|", - "template": "|{{ string }}|", - "desc": "Superfluous in-tag whitespace should be ignored." - }, - { - "name": "Triple Mustache With Padding", - "data": { - "string": "---" - }, - "expected": "|---|", - "template": "|{{{ string }}}|", - "desc": "Superfluous in-tag whitespace should be ignored." - }, - { - "name": "Ampersand With Padding", - "data": { - "string": "---" - }, - "expected": "|---|", - "template": "|{{& string }}|", - "desc": "Superfluous in-tag whitespace should be ignored." - } - ] + "tests": [ + { + "name": "No Interpolation", + "data": {}, + "expected": "Hello from {Mustache}!\n", + "template": "Hello from {Mustache}!\n", + "desc": "Mustache-free templates should render as-is." + }, + { + "name": "Basic Interpolation", + "data": { "subject": "world" }, + "expected": "Hello, world!\n", + "template": "Hello, {{subject}}!\n", + "desc": "Unadorned tags should interpolate content into the template." + }, + { + "name": "HTML Escaping", + "data": { "forbidden": "& \" < >" }, + "expected": "These characters should be HTML escaped: & " < >\n", + "template": "These characters should be HTML escaped: {{forbidden}}\n", + "desc": "Basic interpolation should be HTML escaped." + }, + { + "name": "Triple Mustache", + "data": { "forbidden": "& \" < >" }, + "expected": "These characters should not be HTML escaped: & \" < >\n", + "template": "These characters should not be HTML escaped: {{{forbidden}}}\n", + "desc": "Triple mustaches should interpolate without HTML escaping." + }, + { + "name": "Ampersand", + "data": { "forbidden": "& \" < >" }, + "expected": "These characters should not be HTML escaped: & \" < >\n", + "template": "These characters should not be HTML escaped: {{&forbidden}}\n", + "desc": "Ampersand should interpolate without HTML escaping." + }, + { + "name": "Basic Integer Interpolation", + "data": { "mph": 85 }, + "expected": "\"85 miles an hour!\"", + "template": "\"{{mph}} miles an hour!\"", + "desc": "Integers should interpolate seamlessly." + }, + { + "name": "Triple Mustache Integer Interpolation", + "data": { "mph": 85 }, + "expected": "\"85 miles an hour!\"", + "template": "\"{{{mph}}} miles an hour!\"", + "desc": "Integers should interpolate seamlessly." + }, + { + "name": "Ampersand Integer Interpolation", + "data": { "mph": 85 }, + "expected": "\"85 miles an hour!\"", + "template": "\"{{&mph}} miles an hour!\"", + "desc": "Integers should interpolate seamlessly." + }, + { + "name": "Basic Decimal Interpolation", + "data": { "power": 1.21 }, + "expected": "\"1.21 jiggawatts!\"", + "template": "\"{{power}} jiggawatts!\"", + "desc": "Decimals should interpolate seamlessly with proper significance." + }, + { + "name": "Triple Mustache Decimal Interpolation", + "data": { "power": 1.21 }, + "expected": "\"1.21 jiggawatts!\"", + "template": "\"{{{power}}} jiggawatts!\"", + "desc": "Decimals should interpolate seamlessly with proper significance." + }, + { + "name": "Ampersand Decimal Interpolation", + "data": { "power": 1.21 }, + "expected": "\"1.21 jiggawatts!\"", + "template": "\"{{&power}} jiggawatts!\"", + "desc": "Decimals should interpolate seamlessly with proper significance." + }, + { + "name": "Interpolation - Surrounding Whitespace", + "data": { "string": "---" }, + "expected": "| --- |", + "template": "| {{string}} |", + "desc": "Interpolation should not alter surrounding whitespace." + }, + { + "name": "Triple Mustache - Surrounding Whitespace", + "data": { "string": "---" }, + "expected": "| --- |", + "template": "| {{{string}}} |", + "desc": "Interpolation should not alter surrounding whitespace." + }, + { + "name": "Ampersand - Surrounding Whitespace", + "data": { "string": "---" }, + "expected": "| --- |", + "template": "| {{&string}} |", + "desc": "Interpolation should not alter surrounding whitespace." + }, + { + "name": "Interpolation - Standalone", + "data": { "string": "---" }, + "expected": " ---\n", + "template": " {{string}}\n", + "desc": "Standalone interpolation should not alter surrounding whitespace." + }, + { + "name": "Triple Mustache - Standalone", + "data": { "string": "---" }, + "expected": " ---\n", + "template": " {{{string}}}\n", + "desc": "Standalone interpolation should not alter surrounding whitespace." + }, + { + "name": "Ampersand - Standalone", + "data": { "string": "---" }, + "expected": " ---\n", + "template": " {{&string}}\n", + "desc": "Standalone interpolation should not alter surrounding whitespace." + }, + { + "name": "Interpolation With Padding", + "data": { "string": "---" }, + "expected": "|---|", + "template": "|{{ string }}|", + "desc": "Superfluous in-tag whitespace should be ignored." + }, + { + "name": "Triple Mustache With Padding", + "data": { "string": "---" }, + "expected": "|---|", + "template": "|{{{ string }}}|", + "desc": "Superfluous in-tag whitespace should be ignored." + }, + { + "name": "Ampersand With Padding", + "data": { "string": "---" }, + "expected": "|---|", + "template": "|{{& string }}|", + "desc": "Superfluous in-tag whitespace should be ignored." + } + ] } diff --git a/tests/unit/data/mustache_inverted.json b/tests/unit/data/mustache_inverted.json index aae4cc3f..9a7ddac3 100644 --- a/tests/unit/data/mustache_inverted.json +++ b/tests/unit/data/mustache_inverted.json @@ -1,214 +1,153 @@ { - "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", - "overview": "Inverted Section tags and End Section tags are used in combination to wrap a\nsection of the template.\n\nThese tags' content MUST be a non-whitespace character sequence NOT\ncontaining the current closing delimiter; each Inverted Section tag MUST be\nfollowed by an End Section tag with the same content within the same\nsection.\n\nThis tag's content names the data to replace the tag. Name resolution is as\nfollows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object and the method with the given name has an\n arity of 1, the method SHOULD be called with a String containing the\n unprocessed contents of the sections; the data is the value returned.\n 5) Otherwise, the data is the value returned by calling the method with\n the given name.\n 6) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nIf the data is not of a list type, it is coerced into a list as follows: if\nthe data is truthy (e.g. `!!data == true`), use a single-element list\ncontaining the data, otherwise use an empty list.\n\nThis section MUST NOT be rendered unless the data list is empty.\n\nInverted Section and End Section tags SHOULD be treated as standalone when\nappropriate.\n", - "tests": [ - { - "name": "Falsey", - "data": { - "boolean": false - }, - "expected": "\"This should be rendered.\"", - "template": "\"{{^boolean}}This should be rendered.{{/boolean}}\"", - "desc": "Falsey sections should have their contents rendered." - }, - { - "name": "Truthy", - "data": { - "boolean": true - }, - "expected": "\"\"", - "template": "\"{{^boolean}}This should not be rendered.{{/boolean}}\"", - "desc": "Truthy sections should have their contents omitted." - }, - { - "name": "Context", - "data": { - "context": { - "name": "Joe" - } - }, - "expected": "\"\"", - "template": "\"{{^context}}Hi {{name}}.{{/context}}\"", - "desc": "Objects and hashes should behave like truthy values." - }, - { - "name": "List", - "data": { - "list": [ - { - "n": 1 - }, - { - "n": 2 - }, - { - "n": 3 - } - ] - }, - "expected": "\"\"", - "template": "\"{{^list}}{{n}}{{/list}}\"", - "desc": "Lists should behave like truthy values." - }, - { - "name": "Empty List", - "data": { - "list": [] - }, - "expected": "\"Yay lists!\"", - "template": "\"{{^list}}Yay lists!{{/list}}\"", - "desc": "Empty lists should behave like falsey values." - }, - { - "name": "Doubled", - "data": { - "two": "second", - "bool": false - }, - "expected": "* first\n* second\n* third\n", - "template": "{{^bool}}\n* first\n{{/bool}}\n* {{two}}\n{{^bool}}\n* third\n{{/bool}}\n", - "desc": "Multiple inverted sections per template should be permitted." - }, - { - "name": "Nested (Falsey)", - "data": { - "bool": false - }, - "expected": "| A B C D E |", - "template": "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", - "desc": "Nested falsey sections should have their contents rendered." - }, - { - "name": "Nested (Truthy)", - "data": { - "bool": true - }, - "expected": "| A E |", - "template": "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", - "desc": "Nested truthy sections should be omitted." - }, - { - "name": "Context Misses", - "data": {}, - "expected": "[Cannot find key 'missing'!]", - "template": "[{{^missing}}Cannot find key 'missing'!{{/missing}}]", - "desc": "Failed context lookups should be considered falsey." - }, - { - "name": "Dotted Names - Truthy", - "data": { - "a": { - "b": { - "c": true - } - } - }, - "expected": "\"\" == \"\"", - "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"\"", - "desc": "Dotted names should be valid for Inverted Section tags." - }, - { - "name": "Dotted Names - Falsey", - "data": { - "a": { - "b": { - "c": false - } - } - }, - "expected": "\"Not Here\" == \"Not Here\"", - "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\"", - "desc": "Dotted names should be valid for Inverted Section tags." - }, - { - "name": "Dotted Names - Broken Chains", - "data": { - "a": {} - }, - "expected": "\"Not Here\" == \"Not Here\"", - "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\"", - "desc": "Dotted names that cannot be resolved should be considered falsey." - }, - { - "name": "Surrounding Whitespace", - "data": { - "boolean": false - }, - "expected": " | \t|\t | \n", - "template": " | {{^boolean}}\t|\t{{/boolean}} | \n", - "desc": "Inverted sections should not alter surrounding whitespace." - }, - { - "name": "Internal Whitespace", - "data": { - "boolean": false - }, - "expected": " | \n | \n", - "template": " | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", - "desc": "Inverted should not alter internal whitespace." - }, - { - "name": "Indented Inline Sections", - "data": { - "boolean": false - }, - "expected": " NO\n WAY\n", - "template": " {{^boolean}}NO{{/boolean}}\n {{^boolean}}WAY{{/boolean}}\n", - "desc": "Single-line sections should not alter surrounding whitespace." - }, - { - "name": "Standalone Lines", - "data": { - "boolean": false - }, - "expected": "| This Is\n|\n| A Line\n", - "template": "| This Is\n{{^boolean}}\n|\n{{/boolean}}\n| A Line\n", - "desc": "Standalone lines should be removed from the template." - }, - { - "name": "Standalone Indented Lines", - "data": { - "boolean": false - }, - "expected": "| This Is\n|\n| A Line\n", - "template": "| This Is\n {{^boolean}}\n|\n {{/boolean}}\n| A Line\n", - "desc": "Standalone indented lines should be removed from the template." - }, - { - "name": "Standalone Line Endings", - "data": { - "boolean": false - }, - "expected": "|\r\n|", - "template": "|\r\n{{^boolean}}\r\n{{/boolean}}\r\n|", - "desc": "\"\\r\\n\" should be considered a newline for standalone tags." - }, - { - "name": "Standalone Without Previous Line", - "data": { - "boolean": false - }, - "expected": "^\n/", - "template": " {{^boolean}}\n^{{/boolean}}\n/", - "desc": "Standalone tags should not require a newline to precede them." - }, - { - "name": "Standalone Without Newline", - "data": { - "boolean": false - }, - "expected": "^\n/\n", - "template": "^{{^boolean}}\n/\n {{/boolean}}", - "desc": "Standalone tags should not require a newline to follow them." - }, - { - "name": "Padding", - "data": { - "boolean": false - }, - "expected": "|=|", - "template": "|{{^ boolean }}={{/ boolean }}|", - "desc": "Superfluous in-tag whitespace should be ignored." - } - ] + "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", + "overview": "Inverted Section tags and End Section tags are used in combination to wrap a\nsection of the template.\n\nThese tags' content MUST be a non-whitespace character sequence NOT\ncontaining the current closing delimiter; each Inverted Section tag MUST be\nfollowed by an End Section tag with the same content within the same\nsection.\n\nThis tag's content names the data to replace the tag. Name resolution is as\nfollows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object and the method with the given name has an\n arity of 1, the method SHOULD be called with a String containing the\n unprocessed contents of the sections; the data is the value returned.\n 5) Otherwise, the data is the value returned by calling the method with\n the given name.\n 6) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nIf the data is not of a list type, it is coerced into a list as follows: if\nthe data is truthy (e.g. `!!data == true`), use a single-element list\ncontaining the data, otherwise use an empty list.\n\nThis section MUST NOT be rendered unless the data list is empty.\n\nInverted Section and End Section tags SHOULD be treated as standalone when\nappropriate.\n", + "tests": [ + { + "name": "Falsey", + "data": { "boolean": false }, + "expected": "\"This should be rendered.\"", + "template": "\"{{^boolean}}This should be rendered.{{/boolean}}\"", + "desc": "Falsey sections should have their contents rendered." + }, + { + "name": "Truthy", + "data": { "boolean": true }, + "expected": "\"\"", + "template": "\"{{^boolean}}This should not be rendered.{{/boolean}}\"", + "desc": "Truthy sections should have their contents omitted." + }, + { + "name": "Context", + "data": { "context": { "name": "Joe" } }, + "expected": "\"\"", + "template": "\"{{^context}}Hi {{name}}.{{/context}}\"", + "desc": "Objects and hashes should behave like truthy values." + }, + { + "name": "List", + "data": { "list": [{ "n": 1 }, { "n": 2 }, { "n": 3 }] }, + "expected": "\"\"", + "template": "\"{{^list}}{{n}}{{/list}}\"", + "desc": "Lists should behave like truthy values." + }, + { + "name": "Empty List", + "data": { "list": [] }, + "expected": "\"Yay lists!\"", + "template": "\"{{^list}}Yay lists!{{/list}}\"", + "desc": "Empty lists should behave like falsey values." + }, + { + "name": "Doubled", + "data": { "two": "second", "bool": false }, + "expected": "* first\n* second\n* third\n", + "template": "{{^bool}}\n* first\n{{/bool}}\n* {{two}}\n{{^bool}}\n* third\n{{/bool}}\n", + "desc": "Multiple inverted sections per template should be permitted." + }, + { + "name": "Nested (Falsey)", + "data": { "bool": false }, + "expected": "| A B C D E |", + "template": "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", + "desc": "Nested falsey sections should have their contents rendered." + }, + { + "name": "Nested (Truthy)", + "data": { "bool": true }, + "expected": "| A E |", + "template": "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", + "desc": "Nested truthy sections should be omitted." + }, + { + "name": "Context Misses", + "data": {}, + "expected": "[Cannot find key 'missing'!]", + "template": "[{{^missing}}Cannot find key 'missing'!{{/missing}}]", + "desc": "Failed context lookups should be considered falsey." + }, + { + "name": "Dotted Names - Truthy", + "data": { "a": { "b": { "c": true } } }, + "expected": "\"\" == \"\"", + "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"\"", + "desc": "Dotted names should be valid for Inverted Section tags." + }, + { + "name": "Dotted Names - Falsey", + "data": { "a": { "b": { "c": false } } }, + "expected": "\"Not Here\" == \"Not Here\"", + "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\"", + "desc": "Dotted names should be valid for Inverted Section tags." + }, + { + "name": "Dotted Names - Broken Chains", + "data": { "a": {} }, + "expected": "\"Not Here\" == \"Not Here\"", + "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\"", + "desc": "Dotted names that cannot be resolved should be considered falsey." + }, + { + "name": "Surrounding Whitespace", + "data": { "boolean": false }, + "expected": " | \t|\t | \n", + "template": " | {{^boolean}}\t|\t{{/boolean}} | \n", + "desc": "Inverted sections should not alter surrounding whitespace." + }, + { + "name": "Internal Whitespace", + "data": { "boolean": false }, + "expected": " | \n | \n", + "template": " | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", + "desc": "Inverted should not alter internal whitespace." + }, + { + "name": "Indented Inline Sections", + "data": { "boolean": false }, + "expected": " NO\n WAY\n", + "template": " {{^boolean}}NO{{/boolean}}\n {{^boolean}}WAY{{/boolean}}\n", + "desc": "Single-line sections should not alter surrounding whitespace." + }, + { + "name": "Standalone Lines", + "data": { "boolean": false }, + "expected": "| This Is\n|\n| A Line\n", + "template": "| This Is\n{{^boolean}}\n|\n{{/boolean}}\n| A Line\n", + "desc": "Standalone lines should be removed from the template." + }, + { + "name": "Standalone Indented Lines", + "data": { "boolean": false }, + "expected": "| This Is\n|\n| A Line\n", + "template": "| This Is\n {{^boolean}}\n|\n {{/boolean}}\n| A Line\n", + "desc": "Standalone indented lines should be removed from the template." + }, + { + "name": "Standalone Line Endings", + "data": { "boolean": false }, + "expected": "|\r\n|", + "template": "|\r\n{{^boolean}}\r\n{{/boolean}}\r\n|", + "desc": "\"\\r\\n\" should be considered a newline for standalone tags." + }, + { + "name": "Standalone Without Previous Line", + "data": { "boolean": false }, + "expected": "^\n/", + "template": " {{^boolean}}\n^{{/boolean}}\n/", + "desc": "Standalone tags should not require a newline to precede them." + }, + { + "name": "Standalone Without Newline", + "data": { "boolean": false }, + "expected": "^\n/\n", + "template": "^{{^boolean}}\n/\n {{/boolean}}", + "desc": "Standalone tags should not require a newline to follow them." + }, + { + "name": "Padding", + "data": { "boolean": false }, + "expected": "|=|", + "template": "|{{^ boolean }}={{/ boolean }}|", + "desc": "Superfluous in-tag whitespace should be ignored." + } + ] } diff --git a/tests/unit/data/mustache_sections.json b/tests/unit/data/mustache_sections.json index 56279257..53936eda 100644 --- a/tests/unit/data/mustache_sections.json +++ b/tests/unit/data/mustache_sections.json @@ -1,282 +1,187 @@ { - "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", - "overview": "Section tags and End Section tags are used in combination to wrap a section\nof the template for iteration\n\nThese tags' content MUST be a non-whitespace character sequence NOT\ncontaining the current closing delimiter; each Section tag MUST be followed\nby an End Section tag with the same content within the same section.\n\nThis tag's content names the data to replace the tag. Name resolution is as\nfollows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object and the method with the given name has an\n arity of 1, the method SHOULD be called with a String containing the\n unprocessed contents of the sections; the data is the value returned.\n 5) Otherwise, the data is the value returned by calling the method with\n the given name.\n 6) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nIf the data is not of a list type, it is coerced into a list as follows: if\nthe data is truthy (e.g. `!!data == true`), use a single-element list\ncontaining the data, otherwise use an empty list.\n\nFor each element in the data list, the element MUST be pushed onto the\ncontext stack, the section MUST be rendered, and the element MUST be popped\noff the context stack.\n\nSection and End Section tags SHOULD be treated as standalone when\nappropriate.\n", - "tests": [ - { - "name": "Truthy", - "data": { - "boolean": true - }, - "expected": "\"This should be rendered.\"", - "template": "\"{{#boolean}}This should be rendered.{{/boolean}}\"", - "desc": "Truthy sections should have their contents rendered." - }, - { - "name": "Falsey", - "data": { - "boolean": false - }, - "expected": "\"\"", - "template": "\"{{#boolean}}This should not be rendered.{{/boolean}}\"", - "desc": "Falsey sections should have their contents omitted." - }, - { - "name": "Context", - "data": { - "context": { - "name": "Joe" - } - }, - "expected": "\"Hi Joe.\"", - "template": "\"{{#context}}Hi {{name}}.{{/context}}\"", - "desc": "Objects and hashes should be pushed onto the context stack." - }, - { - "name": "Deeply Nested Contexts", - "data": { - "a": { - "one": 1 - }, - "b": { - "two": 2 - }, - "c": { - "three": 3 - }, - "d": { - "four": 4 - }, - "e": { - "five": 5 - } - }, - "expected": "1\n121\n12321\n1234321\n123454321\n1234321\n12321\n121\n1\n", - "template": "{{#a}}\n{{one}}\n{{#b}}\n{{one}}{{two}}{{one}}\n{{#c}}\n{{one}}{{two}}{{three}}{{two}}{{one}}\n{{#d}}\n{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}\n{{#e}}\n{{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}\n{{/e}}\n{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}\n{{/d}}\n{{one}}{{two}}{{three}}{{two}}{{one}}\n{{/c}}\n{{one}}{{two}}{{one}}\n{{/b}}\n{{one}}\n{{/a}}\n", - "desc": "All elements on the context stack should be accessible." - }, - { - "name": "List", - "data": { - "list": [ - { - "item": 1 - }, - { - "item": 2 - }, - { - "item": 3 - } - ] - }, - "expected": "\"123\"", - "template": "\"{{#list}}{{item}}{{/list}}\"", - "desc": "Lists should be iterated; list items should visit the context stack." - }, - { - "name": "Empty List", - "data": { - "list": [] - }, - "expected": "\"\"", - "template": "\"{{#list}}Yay lists!{{/list}}\"", - "desc": "Empty lists should behave like falsey values." - }, - { - "name": "Doubled", - "data": { - "two": "second", - "bool": true - }, - "expected": "* first\n* second\n* third\n", - "template": "{{#bool}}\n* first\n{{/bool}}\n* {{two}}\n{{#bool}}\n* third\n{{/bool}}\n", - "desc": "Multiple sections per template should be permitted." - }, - { - "name": "Nested (Truthy)", - "data": { - "bool": true - }, - "expected": "| A B C D E |", - "template": "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", - "desc": "Nested truthy sections should have their contents rendered." - }, - { - "name": "Nested (Falsey)", - "data": { - "bool": false - }, - "expected": "| A E |", - "template": "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", - "desc": "Nested falsey sections should be omitted." - }, - { - "name": "Context Misses", - "data": {}, - "expected": "[]", - "template": "[{{#missing}}Found key 'missing'!{{/missing}}]", - "desc": "Failed context lookups should be considered falsey." - }, - { - "name": "Implicit Iterator - String", - "data": { - "list": [ - "a", - "b", - "c", - "d", - "e" - ] - }, - "expected": "\"(a)(b)(c)(d)(e)\"", - "template": "\"{{#list}}({{.}}){{/list}}\"", - "desc": "Implicit iterators should directly interpolate strings." - }, - { - "name": "Implicit Iterator - Integer", - "data": { - "list": [ - 1, - 2, - 3, - 4, - 5 - ] - }, - "expected": "\"(1)(2)(3)(4)(5)\"", - "template": "\"{{#list}}({{.}}){{/list}}\"", - "desc": "Implicit iterators should cast integers to strings and interpolate." - }, - { - "name": "Implicit Iterator - Decimal", - "data": { - "list": [ - 1.1, - 2.2, - 3.3, - 4.4, - 5.5 - ] - }, - "expected": "\"(1.10)(2.20)(3.30)(4.40)(5.50)\"", - "template": "\"{{#list}}({{.}}){{/list}}\"", - "desc": "Implicit iterators should cast decimals to strings and interpolate." - }, - { - "name": "Dotted Names - Truthy", - "data": { - "a": { - "b": { - "c": true - } - } - }, - "expected": "\"Here\" == \"Here\"", - "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"Here\"", - "desc": "Dotted names should be valid for Section tags." - }, - { - "name": "Dotted Names - Falsey", - "data": { - "a": { - "b": { - "c": false - } - } - }, - "expected": "\"\" == \"\"", - "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"\"", - "desc": "Dotted names should be valid for Section tags." - }, - { - "name": "Dotted Names - Broken Chains", - "data": { - "a": {} - }, - "expected": "\"\" == \"\"", - "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"\"", - "desc": "Dotted names that cannot be resolved should be considered falsey." - }, - { - "name": "Surrounding Whitespace", - "data": { - "boolean": true - }, - "expected": " | \t|\t | \n", - "template": " | {{#boolean}}\t|\t{{/boolean}} | \n", - "desc": "Sections should not alter surrounding whitespace." - }, - { - "name": "Internal Whitespace", - "data": { - "boolean": true - }, - "expected": " | \n | \n", - "template": " | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", - "desc": "Sections should not alter internal whitespace." - }, - { - "name": "Indented Inline Sections", - "data": { - "boolean": true - }, - "expected": " YES\n GOOD\n", - "template": " {{#boolean}}YES{{/boolean}}\n {{#boolean}}GOOD{{/boolean}}\n", - "desc": "Single-line sections should not alter surrounding whitespace." - }, - { - "name": "Standalone Lines", - "data": { - "boolean": true - }, - "expected": "| This Is\n|\n| A Line\n", - "template": "| This Is\n{{#boolean}}\n|\n{{/boolean}}\n| A Line\n", - "desc": "Standalone lines should be removed from the template." - }, - { - "name": "Indented Standalone Lines", - "data": { - "boolean": true - }, - "expected": "| This Is\n|\n| A Line\n", - "template": "| This Is\n {{#boolean}}\n|\n {{/boolean}}\n| A Line\n", - "desc": "Indented standalone lines should be removed from the template." - }, - { - "name": "Standalone Line Endings", - "data": { - "boolean": true - }, - "expected": "|\r\n|", - "template": "|\r\n{{#boolean}}\r\n{{/boolean}}\r\n|", - "desc": "\"\\r\\n\" should be considered a newline for standalone tags." - }, - { - "name": "Standalone Without Previous Line", - "data": { - "boolean": true - }, - "expected": "#\n/", - "template": " {{#boolean}}\n#{{/boolean}}\n/", - "desc": "Standalone tags should not require a newline to precede them." - }, - { - "name": "Standalone Without Newline", - "data": { - "boolean": true - }, - "expected": "#\n/\n", - "template": "#{{#boolean}}\n/\n {{/boolean}}", - "desc": "Standalone tags should not require a newline to follow them." - }, - { - "name": "Padding", - "data": { - "boolean": true - }, - "expected": "|=|", - "template": "|{{# boolean }}={{/ boolean }}|", - "desc": "Superfluous in-tag whitespace should be ignored." - } - ] + "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", + "overview": "Section tags and End Section tags are used in combination to wrap a section\nof the template for iteration\n\nThese tags' content MUST be a non-whitespace character sequence NOT\ncontaining the current closing delimiter; each Section tag MUST be followed\nby an End Section tag with the same content within the same section.\n\nThis tag's content names the data to replace the tag. Name resolution is as\nfollows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object and the method with the given name has an\n arity of 1, the method SHOULD be called with a String containing the\n unprocessed contents of the sections; the data is the value returned.\n 5) Otherwise, the data is the value returned by calling the method with\n the given name.\n 6) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nIf the data is not of a list type, it is coerced into a list as follows: if\nthe data is truthy (e.g. `!!data == true`), use a single-element list\ncontaining the data, otherwise use an empty list.\n\nFor each element in the data list, the element MUST be pushed onto the\ncontext stack, the section MUST be rendered, and the element MUST be popped\noff the context stack.\n\nSection and End Section tags SHOULD be treated as standalone when\nappropriate.\n", + "tests": [ + { + "name": "Truthy", + "data": { "boolean": true }, + "expected": "\"This should be rendered.\"", + "template": "\"{{#boolean}}This should be rendered.{{/boolean}}\"", + "desc": "Truthy sections should have their contents rendered." + }, + { + "name": "Falsey", + "data": { "boolean": false }, + "expected": "\"\"", + "template": "\"{{#boolean}}This should not be rendered.{{/boolean}}\"", + "desc": "Falsey sections should have their contents omitted." + }, + { + "name": "Context", + "data": { "context": { "name": "Joe" } }, + "expected": "\"Hi Joe.\"", + "template": "\"{{#context}}Hi {{name}}.{{/context}}\"", + "desc": "Objects and hashes should be pushed onto the context stack." + }, + { + "name": "Deeply Nested Contexts", + "data": { + "a": { "one": 1 }, + "b": { "two": 2 }, + "c": { "three": 3 }, + "d": { "four": 4 }, + "e": { "five": 5 } + }, + "expected": "1\n121\n12321\n1234321\n123454321\n1234321\n12321\n121\n1\n", + "template": "{{#a}}\n{{one}}\n{{#b}}\n{{one}}{{two}}{{one}}\n{{#c}}\n{{one}}{{two}}{{three}}{{two}}{{one}}\n{{#d}}\n{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}\n{{#e}}\n{{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}\n{{/e}}\n{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}\n{{/d}}\n{{one}}{{two}}{{three}}{{two}}{{one}}\n{{/c}}\n{{one}}{{two}}{{one}}\n{{/b}}\n{{one}}\n{{/a}}\n", + "desc": "All elements on the context stack should be accessible." + }, + { + "name": "List", + "data": { "list": [{ "item": 1 }, { "item": 2 }, { "item": 3 }] }, + "expected": "\"123\"", + "template": "\"{{#list}}{{item}}{{/list}}\"", + "desc": "Lists should be iterated; list items should visit the context stack." + }, + { + "name": "Empty List", + "data": { "list": [] }, + "expected": "\"\"", + "template": "\"{{#list}}Yay lists!{{/list}}\"", + "desc": "Empty lists should behave like falsey values." + }, + { + "name": "Doubled", + "data": { "two": "second", "bool": true }, + "expected": "* first\n* second\n* third\n", + "template": "{{#bool}}\n* first\n{{/bool}}\n* {{two}}\n{{#bool}}\n* third\n{{/bool}}\n", + "desc": "Multiple sections per template should be permitted." + }, + { + "name": "Nested (Truthy)", + "data": { "bool": true }, + "expected": "| A B C D E |", + "template": "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", + "desc": "Nested truthy sections should have their contents rendered." + }, + { + "name": "Nested (Falsey)", + "data": { "bool": false }, + "expected": "| A E |", + "template": "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", + "desc": "Nested falsey sections should be omitted." + }, + { + "name": "Context Misses", + "data": {}, + "expected": "[]", + "template": "[{{#missing}}Found key 'missing'!{{/missing}}]", + "desc": "Failed context lookups should be considered falsey." + }, + { + "name": "Implicit Iterator - String", + "data": { "list": ["a", "b", "c", "d", "e"] }, + "expected": "\"(a)(b)(c)(d)(e)\"", + "template": "\"{{#list}}({{.}}){{/list}}\"", + "desc": "Implicit iterators should directly interpolate strings." + }, + { + "name": "Implicit Iterator - Integer", + "data": { "list": [1, 2, 3, 4, 5] }, + "expected": "\"(1)(2)(3)(4)(5)\"", + "template": "\"{{#list}}({{.}}){{/list}}\"", + "desc": "Implicit iterators should cast integers to strings and interpolate." + }, + { + "name": "Implicit Iterator - Decimal", + "data": { "list": [1.1, 2.2, 3.3, 4.4, 5.5] }, + "expected": "\"(1.10)(2.20)(3.30)(4.40)(5.50)\"", + "template": "\"{{#list}}({{.}}){{/list}}\"", + "desc": "Implicit iterators should cast decimals to strings and interpolate." + }, + { + "name": "Dotted Names - Truthy", + "data": { "a": { "b": { "c": true } } }, + "expected": "\"Here\" == \"Here\"", + "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"Here\"", + "desc": "Dotted names should be valid for Section tags." + }, + { + "name": "Dotted Names - Falsey", + "data": { "a": { "b": { "c": false } } }, + "expected": "\"\" == \"\"", + "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"\"", + "desc": "Dotted names should be valid for Section tags." + }, + { + "name": "Dotted Names - Broken Chains", + "data": { "a": {} }, + "expected": "\"\" == \"\"", + "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"\"", + "desc": "Dotted names that cannot be resolved should be considered falsey." + }, + { + "name": "Surrounding Whitespace", + "data": { "boolean": true }, + "expected": " | \t|\t | \n", + "template": " | {{#boolean}}\t|\t{{/boolean}} | \n", + "desc": "Sections should not alter surrounding whitespace." + }, + { + "name": "Internal Whitespace", + "data": { "boolean": true }, + "expected": " | \n | \n", + "template": " | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", + "desc": "Sections should not alter internal whitespace." + }, + { + "name": "Indented Inline Sections", + "data": { "boolean": true }, + "expected": " YES\n GOOD\n", + "template": " {{#boolean}}YES{{/boolean}}\n {{#boolean}}GOOD{{/boolean}}\n", + "desc": "Single-line sections should not alter surrounding whitespace." + }, + { + "name": "Standalone Lines", + "data": { "boolean": true }, + "expected": "| This Is\n|\n| A Line\n", + "template": "| This Is\n{{#boolean}}\n|\n{{/boolean}}\n| A Line\n", + "desc": "Standalone lines should be removed from the template." + }, + { + "name": "Indented Standalone Lines", + "data": { "boolean": true }, + "expected": "| This Is\n|\n| A Line\n", + "template": "| This Is\n {{#boolean}}\n|\n {{/boolean}}\n| A Line\n", + "desc": "Indented standalone lines should be removed from the template." + }, + { + "name": "Standalone Line Endings", + "data": { "boolean": true }, + "expected": "|\r\n|", + "template": "|\r\n{{#boolean}}\r\n{{/boolean}}\r\n|", + "desc": "\"\\r\\n\" should be considered a newline for standalone tags." + }, + { + "name": "Standalone Without Previous Line", + "data": { "boolean": true }, + "expected": "#\n/", + "template": " {{#boolean}}\n#{{/boolean}}\n/", + "desc": "Standalone tags should not require a newline to precede them." + }, + { + "name": "Standalone Without Newline", + "data": { "boolean": true }, + "expected": "#\n/\n", + "template": "#{{#boolean}}\n/\n {{/boolean}}", + "desc": "Standalone tags should not require a newline to follow them." + }, + { + "name": "Padding", + "data": { "boolean": true }, + "expected": "|=|", + "template": "|{{# boolean }}={{/ boolean }}|", + "desc": "Superfluous in-tag whitespace should be ignored." + } + ] } diff --git a/tests/unit/data/sample.json b/tests/unit/data/sample.json index e7b8e861..e2411954 100644 --- a/tests/unit/data/sample.json +++ b/tests/unit/data/sample.json @@ -1,10 +1,11 @@ { - "primitive1": "value1", - "array0": [], - "array1": [ "value2", "value3" ], - "obj0": {}, - "obj1": { "primitive2": "value4", - "array2": [ "value5" ], - "obj2": { "array3": [], - "primitive3": "value6" } } + "primitive1": "value1", + "array0": [], + "array1": ["value2", "value3"], + "obj0": {}, + "obj1": { + "primitive2": "value4", + "array2": ["value5"], + "obj2": { "array3": [], "primitive3": "value6" } + } }