UNPKG

ractive

Version:

Next-generation DOM manipulation

1,230 lines (1,208 loc) 33.2 kB
// MUSTACHE SPEC COMPLIANCE TESTS // ============================== // // These are included to aid development; Ractive will never be able to pass // every test in the suite because it's doing something fundamentally different // to other mustache implementations. // // Unpassable tests are marked as such. // // Some tests technically fail in IE8. This is because IE8 is shit. The library // works fine, but IE8 gets all confused about whitespace when doing innerHTML. // For the sake of sanity, these tests are also marked. define([ 'ractive' ], function ( Ractive ) { return function () { var fixture, testModules, runTest, runModule, i, isOldIe; fixture = document.getElementById( 'qunit-fixture' ); testModules = [ { name: 'Comments', 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 {{! 3 4 }}\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." } ] }, { name: 'Delimiters', 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.", oldIe: true }, { 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.", oldIe: true }, { name: "Partial Inheritence", data: { value: "yes" }, expected: "[ .yes. ]\n[ .yes. ]\n", template: "[ {{>include}} ]\n{{= | | =}}\n[ |>include| ]\n", desc: "Delimiters set in a parent template should not affect a partial.", partials: { include: ".{{value}}." }, oldIe: true }, { name: "Post-Partial Behavior", data: { value: "yes" }, expected: "[ .yes. .yes. ]\n[ .yes. .|value|. ]\n", template: "[ {{>include}} ]\n[ .{{value}}. .|value|. ]\n", desc: "Delimiters set in a partial should not affect the parent template.", partials: { // Note: the original test looked like this: // include: ".{{value}}. {{= | | =}} .|value|." // This breaks in Ractive because the | is assumed to be part of the // expression include: ".{{value}}. {{= <% %> =}} .<%value%>." }, oldIe: true }, { 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: "Standalone Line Endings", data: {}, expected: "|\r\n|", template: "|\r\n{{= @ @ =}}\r\n|", desc: "\"\\r\\n\" should be considered a newline for standalone tags." }, { name: "Standalone Without Previous Line", data: {}, expected: "=", template: " {{=@ @=}}\n=", desc: "Standalone tags should not require a newline to precede them." }, { name: "Standalone Without Newline", data: {}, expected: "=\n", template: "=\n {{=@ @=}}", desc: "Standalone tags should not require a newline to follow them." }, { name: "Pair with Padding", data: {}, expected: "||", template: "|{{= @ @ =}}|", desc: "Superfluous in-tag whitespace should be ignored." } ] }, { name: 'Interpolation', 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: &amp; &quot; &lt; &gt;\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: "Basic Context Miss Interpolation", data: {}, expected: "I () be seen!", template: "I ({{cannot}}) be seen!", desc: "Failed context lookups should default to empty strings." }, { name: "Triple Mustache Context Miss Interpolation", data: {}, expected: "I () be seen!", template: "I ({{{cannot}}}) be seen!", desc: "Failed context lookups should default to empty strings." }, { name: "Ampersand Context Miss Interpolation", data: {}, expected: "I () be seen!", template: "I ({{&cannot}}) be seen!", desc: "Failed context lookups should default to empty strings." }, { name: "Dotted Names - Basic Interpolation", data: { person: { name: "Joe" } }, expected: "\"Joe\" == \"Joe\"", template: "\"{{person.name}}\" == \"{{#person}}{{name}}{{/person}}\"", desc: "Dotted names should be considered a form of shorthand for sections." }, { name: "Dotted Names - Triple Mustache Interpolation", data: { person: { name: "Joe" } }, expected: "\"Joe\" == \"Joe\"", template: "\"{{{person.name}}}\" == \"{{#person}}{{{name}}}{{/person}}\"", desc: "Dotted names should be considered a form of shorthand for sections." }, { name: "Dotted Names - Ampersand Interpolation", data: { person: { name: "Joe" } }, expected: "\"Joe\" == \"Joe\"", template: "\"{{&person.name}}\" == \"{{#person}}{{&name}}{{/person}}\"", desc: "Dotted names should be considered a form of shorthand for sections." }, { name: "Dotted Names - Arbitrary Depth", data: { a: { b: { c: { d: { e: { name: "Phil" } } } } } }, expected: "\"Phil\" == \"Phil\"", template: "\"{{a.b.c.d.e.name}}\" == \"Phil\"", desc: "Dotted names should be functional to any level of nesting." }, { name: "Dotted Names - Broken Chains", data: { a: {} }, expected: "\"\" == \"\"", template: "\"{{a.b.c}}\" == \"\"", desc: "Any falsey value prior to the last part of the name should yield ''." }, { name: "Dotted Names - Broken Chain Resolution", data: { a: { b: {} }, c: { name: "Jim" } }, expected: "\"\" == \"\"", template: "\"{{a.b.c.name}}\" == \"\"", desc: "Each part of a dotted name should resolve only against its parent." }, { name: "Dotted Names - Initial Resolution", data: { a: { b: { c: { d: { e: { name: "Phil" } } } } }, b: { c: { d: { e: { name: "Wrong" } } } } }, expected: "\"Phil\" == \"Phil\"", template: "\"{{#a}}{{b.c.d.e.name}}{{/a}}\" == \"Phil\"", desc: "The first part of a dotted name should resolve as any other name." }, { 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." } ] }, { name: 'Inverted', 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.", oldIe: true }, { 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.", oldIe: true }, { 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.", oldIe: true }, { 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.", unpassable: true }, { 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.", oldIe: true }, { 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.", oldIe: true }, { name: "Padding", data: { boolean: false }, expected: "|=|", template: "|{{^ boolean }}={{/ boolean }}|", desc: "Superfluous in-tag whitespace should be ignored." } ] }, { name: 'Partials', tests: [ { name: "Basic Behavior", data: {}, expected: "\"from partial\"", template: "\"{{>text}}\"", desc: "The greater-than operator should expand to the named partial.", partials: { text: "from partial" } }, { name: "Failed Lookup", data: {}, expected: "\"\"", template: "\"{{>text}}\"", desc: "The empty string should be used when the named partial is not found.", partials: {} }, { name: "Context", data: { text: "content" }, expected: "\"*content*\"", template: "\"{{>partial}}\"", desc: "The greater-than operator should operate within the current context.", partials: { partial: "*{{text}}*" } }, { name: "Recursion", data: { content: "X", nodes: [ { content: "Y", nodes: [] } ] }, expected: "X(Y())", template: "{{>node}}", desc: "The greater-than operator should properly recurse.", partials: { node: "{{content}}({{#nodes}}{{>node}}{{/nodes}})" } }, { name: "Surrounding Whitespace", data: {}, expected: "| \t|\t |", template: "| {{>partial}} |", desc: "The greater-than operator should not alter surrounding whitespace.", partials: { partial: "\t|\t" } }, { name: "Inline Indentation", data: { data: "|" }, expected: " | >\n>\n", template: " {{data}} {{> partial}}\n", desc: "Whitespace should be left untouched.", partials: { partial: ">\n>" } }, { name: "Standalone Line Endings", data: {}, expected: "|\r\n>|", template: "|\r\n{{>partial}}\r\n|", desc: "\"\\r\\n\" should be considered a newline for standalone tags.", partials: { partial: ">" }, oldIe: true, unpassable: true }, { name: "Standalone Without Previous Line", data: {}, expected: " >\n >>", template: " {{>partial}}\n>", desc: "Standalone tags should not require a newline to precede them.", partials: { partial: ">\n>" }, unpassable: true }, { name: "Standalone Without Newline", data: {}, expected: ">\n >\n >", template: ">\n {{>partial}}", desc: "Standalone tags should not require a newline to follow them.", partials: { partial: ">\n>" }, unpassable: true }, { name: "Standalone Indentation", data: { content: "<\n->" }, expected: "\\\n |\n <\n->\n |\n/\n", template: "\\\n {{>partial}}\n/\n", desc: "Each line of the partial should be indented before rendering.", partials: { partial: "|\n{{{content}}}\n|\n" }, unpassable: true }, { name: "Padding Whitespace", data: { boolean: true }, expected: "|[]|", template: "|{{> partial }}|", desc: "Superfluous in-tag whitespace should be ignored.", partials: { partial: "[]" } } ] }, { name: 'Sections', 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.", oldIe: true }, { 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.", oldIe: true }, { 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.1)(2.2)(3.3)(4.4)(5.5)\"", 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.", oldIe: true }, { 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.", oldIe: true }, { 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.", unpassable: true }, { 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.", oldIe: true }, { 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.", oldIe: true }, { name: "Padding", data: { boolean: true }, expected: "|=|", template: "|{{# boolean }}={{/ boolean }}|", desc: "Superfluous in-tag whitespace should be ignored." } ] } ]; isOldIe = /MSIE [6-8]/.test( navigator.userAgent ); runTest = function ( theTest ) { test( theTest.name, function ( t ) { var ractive; ractive = new Ractive({ el: fixture, template: theTest.template, data: theTest.data, partials: theTest.partials, preserveWhitespace: true }); t.htmlEqual( fixture.innerHTML, theTest.expected, theTest.desc + '\n' + theTest.template + '\n' ); }); }; runModule = function ( theModule ) { var i, theTest; module( 'Mustache compliance (' + theModule.name + ')' ); for ( i=0; i<theModule.tests.length; i+=1 ) { theTest = theModule.tests[i]; if ( !theTest.unpassable && ( !isOldIe || !theTest.oldIe ) ) { runTest( theModule.tests[i] ); } } }; for ( i=0; i<testModules.length; i+=1 ) { runModule( testModules[i] ); } }; });