summaryrefslogtreecommitdiffstats
path: root/spec/basic.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/basic.js')
-rw-r--r--spec/basic.js162
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: "&\"'`\\<>"}, '&amp;&quot;&#x27;&#x60;\\&lt;&gt;',
+ "by default expressions should be escaped");
+
+ shouldCompileTo("{{awesome}}", {awesome: "Escaped, <b> looks like: &lt;b&gt;"}, 'Escaped, &lt;b&gt; looks like: &amp;lt;b&amp;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);
+ });
+});