summaryrefslogtreecommitdiffstats
path: root/spec/blocks.js
blob: a13cce2a4d761e7be6bed79bf9431e1d4ae25ca8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*global CompilerContext, shouldCompileTo, shouldThrow */
describe('blocks', function() {
  it("array", function() {
    var string   = "{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!";
    var hash     = {goodbyes: [{text: "goodbye"}, {text: "Goodbye"}, {text: "GOODBYE"}], world: "world"};
    shouldCompileTo(string, hash, "goodbye! Goodbye! GOODBYE! cruel world!",
                    "Arrays iterate over the contents when not empty");

    shouldCompileTo(string, {goodbyes: [], world: "world"}, "cruel world!",
                    "Arrays ignore the contents when empty");

  });

  it("array with @index", function() {
    var string = "{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!";
    var hash   = {goodbyes: [{text: "goodbye"}, {text: "Goodbye"}, {text: "GOODBYE"}], world: "world"};

    var template = CompilerContext.compile(string);
    var result = template(hash);

    equal(result, "0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!", "The @index variable is used");
  });
  
  it("empty block", function() {
    var string   = "{{#goodbyes}}{{/goodbyes}}cruel {{world}}!";
    var hash     = {goodbyes: [{text: "goodbye"}, {text: "Goodbye"}, {text: "GOODBYE"}], world: "world"};
    shouldCompileTo(string, hash, "cruel world!",
                    "Arrays iterate over the contents when not empty");

    shouldCompileTo(string, {goodbyes: [], world: "world"}, "cruel world!",
                    "Arrays ignore the contents when empty");
  });

  it("block with complex lookup", function() {
    var string = "{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}";
    var hash     = {name: "Alan", goodbyes: [{text: "goodbye"}, {text: "Goodbye"}, {text: "GOODBYE"}]};

    shouldCompileTo(string, hash, "goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! ",
                    "Templates can access variables in contexts up the stack with relative path syntax");
  });

  it("block with complex lookup using nested context", function() {
    var string = "{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}";

    shouldThrow(function() {
      CompilerContext.compile(string);
    }, Error);
  });

  it("block with deep nested complex lookup", function() {
    var string = "{{#outer}}Goodbye {{#inner}}cruel {{../../omg}}{{/inner}}{{/outer}}";
    var hash = {omg: "OMG!", outer: [{ inner: [{ text: "goodbye" }] }] };

    shouldCompileTo(string, hash, "Goodbye cruel OMG!");
  });

  describe('inverted sections', function() {
    it("inverted sections with unset value", function() {
      var string = "{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}";
      var hash = {};
      shouldCompileTo(string, hash, "Right On!", "Inverted section rendered when value isn't set.");
    });

    it("inverted section with false value", function() {
      var string = "{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}";
      var hash = {goodbyes: false};
      shouldCompileTo(string, hash, "Right On!", "Inverted section rendered when value is false.");
    });

    it("inverted section with empty set", function() {
      var string = "{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}";
      var hash = {goodbyes: []};
      shouldCompileTo(string, hash, "Right On!", "Inverted section rendered when value is empty set.");
    });

    it("block inverted sections", function() {
      shouldCompileTo("{{#people}}{{name}}{{^}}{{none}}{{/people}}", {none: "No people"},
        "No people");
    });

    it("block inverted sections with empty arrays", function() {
      shouldCompileTo("{{#people}}{{name}}{{^}}{{none}}{{/people}}", {none: "No people", people: []},
        "No people");
    });
  });

  describe('standalone sections', function() {
    it('block standalone else sections', function() {
      shouldCompileTo('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n', {none: 'No people'},
        'No people\n');
      shouldCompileTo('{{#none}}\n{{.}}\n{{^}}\n{{none}}\n{{/none}}\n', {none: 'No people'},
        'No people\n');
      shouldCompileTo('\n{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n', {none: 'No people'},
        'No people\n');
    });
  });

  describe('compat mode', function() {
    it("block with deep recursive lookup lookup", function() {
      var string = "{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}";
      var hash = {omg: "OMG!", outer: [{ inner: [{ text: "goodbye" }] }] };

      shouldCompileTo(string, [hash, undefined, undefined, true], "Goodbye cruel OMG!");
    });
    it("block with deep recursive pathed lookup", function() {
      var string = "{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}";
      var hash = {omg: {yes: "OMG!"}, outer: [{ inner: [{ yes: 'no', text: "goodbye" }] }] };

      shouldCompileTo(string, [hash, undefined, undefined, true], "Goodbye cruel OMG!");
    });
    it("block with missed recursive lookup", function() {
      var string = "{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}";
      var hash = {omg: {no: "OMG!"}, outer: [{ inner: [{ yes: 'no', text: "goodbye" }] }] };

      shouldCompileTo(string, [hash, undefined, undefined, true], "Goodbye cruel ");
    });
  });
});