diff options
author | kpdecker <kpdecker@gmail.com> | 2013-06-01 23:45:43 -0500 |
---|---|---|
committer | kpdecker <kpdecker@gmail.com> | 2013-06-01 23:45:43 -0500 |
commit | adda0569e0ec3fc363af9efbb23f5304c6d80fe2 (patch) | |
tree | 9952d7aed77f8710a53731bb98340d5468c9e931 /spec/basic.js | |
parent | d13ae310d36a27fcbc333570f9b7ae9c7e641392 (diff) | |
download | handlebars.js-adda0569e0ec3fc363af9efbb23f5304c6d80fe2.zip handlebars.js-adda0569e0ec3fc363af9efbb23f5304c6d80fe2.tar.gz handlebars.js-adda0569e0ec3fc363af9efbb23f5304c6d80fe2.tar.bz2 |
Refactor qunit unit tests
Allows for testing node, browser, and precompiled modes in the node
tests. Also reorganizes the qunit spec file to provide better
organization.
Diffstat (limited to 'spec/basic.js')
-rw-r--r-- | spec/basic.js | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/spec/basic.js b/spec/basic.js new file mode 100644 index 0000000..a46636c --- /dev/null +++ b/spec/basic.js @@ -0,0 +1,162 @@ +describe("basic context", function() { + it("most basic", function() { + shouldCompileTo("{{foo}}", { foo: "foo" }, "foo"); + }); + + it("escaping", function() { + shouldCompileTo("\\{{foo}}", { foo: "food" }, "{{foo}}"); + shouldCompileTo("\\\\{{foo}}", { foo: "food" }, "\\food"); + shouldCompileTo("\\\\ {{foo}}", { foo: "food" }, "\\\\ food"); + }); + + it("compiling with a basic context", function() { + shouldCompileTo("Goodbye\n{{cruel}}\n{{world}}!", {cruel: "cruel", world: "world"}, "Goodbye\ncruel\nworld!", + "It works if all the required keys are provided"); + }); + + it("comments", function() { + shouldCompileTo("{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!", + {cruel: "cruel", world: "world"}, "Goodbye\ncruel\nworld!", + "comments are ignored"); + }); + + it("boolean", function() { + var string = "{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!"; + shouldCompileTo(string, {goodbye: true, world: "world"}, "GOODBYE cruel world!", + "booleans show the contents when true"); + + shouldCompileTo(string, {goodbye: false, world: "world"}, "cruel world!", + "booleans do not show the contents when false"); + }); + + it("zeros", function() { + shouldCompileTo("num1: {{num1}}, num2: {{num2}}", {num1: 42, num2: 0}, + "num1: 42, num2: 0"); + shouldCompileTo("num: {{.}}", 0, "num: 0"); + shouldCompileTo("num: {{num1/num2}}", {num1: {num2: 0}}, "num: 0"); + }); + + it("newlines", function() { + shouldCompileTo("Alan's\nTest", {}, "Alan's\nTest"); + shouldCompileTo("Alan's\rTest", {}, "Alan's\rTest"); + }); + + it("escaping text", function() { + shouldCompileTo("Awesome's", {}, "Awesome's", "text is escaped so that it doesn't get caught on single quotes"); + shouldCompileTo("Awesome\\", {}, "Awesome\\", "text is escaped so that the closing quote can't be ignored"); + shouldCompileTo("Awesome\\\\ foo", {}, "Awesome\\\\ foo", "text is escaped so that it doesn't mess up backslashes"); + shouldCompileTo("Awesome {{foo}}", {foo: '\\'}, "Awesome \\", "text is escaped so that it doesn't mess up backslashes"); + shouldCompileTo(' " " ', {}, ' " " ', "double quotes never produce invalid javascript"); + }); + + it("escaping expressions", function() { + shouldCompileTo("{{{awesome}}}", {awesome: "&\"\\<>"}, '&\"\\<>', + "expressions with 3 handlebars aren't escaped"); + + shouldCompileTo("{{&awesome}}", {awesome: "&\"\\<>"}, '&\"\\<>', + "expressions with {{& handlebars aren't escaped"); + + shouldCompileTo("{{awesome}}", {awesome: "&\"'`\\<>"}, '&"'`\\<>', + "by default expressions should be escaped"); + + shouldCompileTo("{{awesome}}", {awesome: "Escaped, <b> looks like: <b>"}, 'Escaped, <b> looks like: &lt;b&gt;', + "escaping should properly handle amperstands"); + }); + + it("functions returning safestrings shouldn't be escaped", function() { + var hash = {awesome: function() { return new Handlebars.SafeString("&\"\\<>"); }}; + shouldCompileTo("{{awesome}}", hash, '&\"\\<>', + "functions returning safestrings aren't escaped"); + }); + + it("functions", function() { + shouldCompileTo("{{awesome}}", {awesome: function() { return "Awesome"; }}, "Awesome", + "functions are called and render their output"); + shouldCompileTo("{{awesome}}", {awesome: function() { return this.more; }, more: "More awesome"}, "More awesome", + "functions are bound to the context"); + }); + + it("functions with context argument", function() { + shouldCompileTo("{{awesome frank}}", + {awesome: function(context) { return context; }, + frank: "Frank"}, + "Frank", "functions are called with context arguments"); + }); + + + it("paths with hyphens", function() { + shouldCompileTo("{{foo-bar}}", {"foo-bar": "baz"}, "baz", "Paths can contain hyphens (-)"); + shouldCompileTo("{{foo.foo-bar}}", {foo: {"foo-bar": "baz"}}, "baz", "Paths can contain hyphens (-)"); + shouldCompileTo("{{foo/foo-bar}}", {foo: {"foo-bar": "baz"}}, "baz", "Paths can contain hyphens (-)"); + }); + + it("nested paths", function() { + shouldCompileTo("Goodbye {{alan/expression}} world!", {alan: {expression: "beautiful"}}, + "Goodbye beautiful world!", "Nested paths access nested objects"); + }); + + it("nested paths with empty string value", function() { + shouldCompileTo("Goodbye {{alan/expression}} world!", {alan: {expression: ""}}, + "Goodbye world!", "Nested paths access nested objects with empty string"); + }); + + it("literal paths", function() { + shouldCompileTo("Goodbye {{[@alan]/expression}} world!", {"@alan": {expression: "beautiful"}}, + "Goodbye beautiful world!", "Literal paths can be used"); + shouldCompileTo("Goodbye {{[foo bar]/expression}} world!", {"foo bar": {expression: "beautiful"}}, + "Goodbye beautiful world!", "Literal paths can be used"); + }); + + it('literal references', function() { + shouldCompileTo("Goodbye {{[foo bar]}} world!", {"foo bar": "beautiful"}, + "Goodbye beautiful world!", "Literal paths can be used"); + }); + + it("that current context path ({{.}}) doesn't hit helpers", function() { + shouldCompileTo("test: {{.}}", [null, {helper: "awesome"}], "test: "); + }); + + it("complex but empty paths", function() { + shouldCompileTo("{{person/name}}", {person: {name: null}}, ""); + shouldCompileTo("{{person/name}}", {person: {}}, ""); + }); + + it("this keyword in paths", function() { + var string = "{{#goodbyes}}{{this}}{{/goodbyes}}"; + var hash = {goodbyes: ["goodbye", "Goodbye", "GOODBYE"]}; + shouldCompileTo(string, hash, "goodbyeGoodbyeGOODBYE", + "This keyword in paths evaluates to current context"); + + string = "{{#hellos}}{{this/text}}{{/hellos}}"; + hash = {hellos: [{text: "hello"}, {text: "Hello"}, {text: "HELLO"}]}; + shouldCompileTo(string, hash, "helloHelloHELLO", "This keyword evaluates in more complex paths"); + }); + + it("this keyword nested inside path", function() { + var string = "{{#hellos}}{{text/this/foo}}{{/hellos}}"; + (function() { + CompilerContext.compile(string); + }).should.throw(Error); + }); + + it("this keyword in helpers", function() { + var helpers = {foo: function(value) { + return 'bar ' + value; + }}; + var string = "{{#goodbyes}}{{foo this}}{{/goodbyes}}"; + var hash = {goodbyes: ["goodbye", "Goodbye", "GOODBYE"]}; + shouldCompileTo(string, [hash, helpers], "bar goodbyebar Goodbyebar GOODBYE", + "This keyword in paths evaluates to current context"); + + string = "{{#hellos}}{{foo this/text}}{{/hellos}}"; + hash = {hellos: [{text: "hello"}, {text: "Hello"}, {text: "HELLO"}]}; + shouldCompileTo(string, [hash, helpers], "bar hellobar Hellobar HELLO", "This keyword evaluates in more complex paths"); + }); + + it("this keyword nested inside helpers param", function() { + var string = "{{#hellos}}{{foo text/this/foo}}{{/hellos}}"; + (function() { + CompilerContext.compile(string); + }).should.throw(Error); + }); +}); |