3
// A map of templates to their expected token output. Tokens are in the format:
4
// [type, value, startIndex, endIndex, subTokens].
7
'{{hi}}' : [ [ 'name', 'hi', 0, 6 ] ],
8
'{{hi.world}}' : [ [ 'name', 'hi.world', 0, 12 ] ],
9
'{{hi . world}}' : [ [ 'name', 'hi . world', 0, 14 ] ],
10
'{{ hi}}' : [ [ 'name', 'hi', 0, 7 ] ],
11
'{{hi }}' : [ [ 'name', 'hi', 0, 7 ] ],
12
'{{ hi }}' : [ [ 'name', 'hi', 0, 8 ] ],
13
'{{{hi}}}' : [ [ '&', 'hi', 0, 8 ] ],
14
'{{!hi}}' : [ [ '!', 'hi', 0, 7 ] ],
15
'{{! hi}}' : [ [ '!', 'hi', 0, 8 ] ],
16
'{{! hi }}' : [ [ '!', 'hi', 0, 9 ] ],
17
'{{ !hi}}' : [ [ '!', 'hi', 0, 8 ] ],
18
'{{ ! hi}}' : [ [ '!', 'hi', 0, 9 ] ],
19
'{{ ! hi }}' : [ [ '!', 'hi', 0, 10 ] ],
20
'a\n b' : [ [ 'text', 'a\n b', 0, 4 ] ],
21
'a{{hi}}' : [ [ 'text', 'a', 0, 1 ], [ 'name', 'hi', 1, 7 ] ],
22
'a {{hi}}' : [ [ 'text', 'a ', 0, 2 ], [ 'name', 'hi', 2, 8 ] ],
23
' a{{hi}}' : [ [ 'text', ' a', 0, 2 ], [ 'name', 'hi', 2, 8 ] ],
24
' a {{hi}}' : [ [ 'text', ' a ', 0, 3 ], [ 'name', 'hi', 3, 9 ] ],
25
'a{{hi}}b' : [ [ 'text', 'a', 0, 1 ], [ 'name', 'hi', 1, 7 ], [ 'text', 'b', 7, 8 ] ],
26
'a{{hi}} b' : [ [ 'text', 'a', 0, 1 ], [ 'name', 'hi', 1, 7 ], [ 'text', ' b', 7, 9 ] ],
27
'a{{hi}}b ' : [ [ 'text', 'a', 0, 1 ], [ 'name', 'hi', 1, 7 ], [ 'text', 'b ', 7, 9 ] ],
28
'a\n{{hi}} b \n' : [ [ 'text', 'a\n', 0, 2 ], [ 'name', 'hi', 2, 8 ], [ 'text', ' b \n', 8, 12 ] ],
29
'a\n {{hi}} \nb' : [ [ 'text', 'a\n ', 0, 3 ], [ 'name', 'hi', 3, 9 ], [ 'text', ' \nb', 9, 12 ] ],
30
'a\n {{!hi}} \nb' : [ [ 'text', 'a\n', 0, 2 ], [ '!', 'hi', 3, 10 ], [ 'text', 'b', 12, 13 ] ],
31
'a\n{{#a}}{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 2, 8, [], 8 ], [ 'text', 'b', 15, 16 ] ],
32
'a\n {{#a}}{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [], 9 ], [ 'text', 'b', 16, 17 ] ],
33
'a\n {{#a}}{{/a}} \nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [], 9 ], [ 'text', 'b', 17, 18 ] ],
34
'a\n{{#a}}\n{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 2, 8, [], 9 ], [ 'text', 'b', 16, 17 ] ],
35
'a\n {{#a}}\n{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [], 10 ], [ 'text', 'b', 17, 18 ] ],
36
'a\n {{#a}}\n{{/a}} \nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [], 10 ], [ 'text', 'b', 18, 19 ] ],
37
'a\n{{#a}}\n{{/a}}\n{{#b}}\n{{/b}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 2, 8, [], 9 ], [ '#', 'b', 16, 22, [], 23 ], [ 'text', 'b', 30, 31 ] ],
38
'a\n {{#a}}\n{{/a}}\n{{#b}}\n{{/b}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [], 10 ], [ '#', 'b', 17, 23, [], 24 ], [ 'text', 'b', 31, 32 ] ],
39
'a\n {{#a}}\n{{/a}}\n{{#b}}\n{{/b}} \nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [], 10 ], [ '#', 'b', 17, 23, [], 24 ], [ 'text', 'b', 32, 33 ] ],
40
'a\n{{#a}}\n{{#b}}\n{{/b}}\n{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 2, 8, [ [ '#', 'b', 9, 15, [], 16 ] ], 23 ], [ 'text', 'b', 30, 31 ] ],
41
'a\n {{#a}}\n{{#b}}\n{{/b}}\n{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [ [ '#', 'b', 10, 16, [], 17 ] ], 24 ], [ 'text', 'b', 31, 32 ] ],
42
'a\n {{#a}}\n{{#b}}\n{{/b}}\n{{/a}} \nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [ [ '#', 'b', 10, 16, [], 17 ] ], 24 ], [ 'text', 'b', 32, 33 ] ],
43
'{{>abc}}' : [ [ '>', 'abc', 0, 8 ] ],
44
'{{> abc }}' : [ [ '>', 'abc', 0, 10 ] ],
45
'{{ > abc }}' : [ [ '>', 'abc', 0, 11 ] ],
46
'{{=<% %>=}}' : [ [ '=', '<% %>', 0, 11 ] ],
47
'{{= <% %> =}}' : [ [ '=', '<% %>', 0, 13 ] ],
48
'{{=<% %>=}}<%={{ }}=%>' : [ [ '=', '<% %>', 0, 11 ], [ '=', '{{ }}', 11, 22 ] ],
49
'{{=<% %>=}}<%hi%>' : [ [ '=', '<% %>', 0, 11 ], [ 'name', 'hi', 11, 17 ] ],
50
'{{#a}}{{/a}}hi{{#b}}{{/b}}\n' : [ [ '#', 'a', 0, 6, [], 6 ], [ 'text', 'hi', 12, 14 ], [ '#', 'b', 14, 20, [], 20 ], [ 'text', '\n', 26, 27 ] ],
51
'{{a}}\n{{b}}\n\n{{#c}}\n{{/c}}\n' : [ [ 'name', 'a', 0, 5 ], [ 'text', '\n', 5, 6 ], [ 'name', 'b', 6, 11 ], [ 'text', '\n\n', 11, 13 ], [ '#', 'c', 13, 19, [], 20 ] ],
52
'{{#foo}}\n {{#a}}\n {{b}}\n {{/a}}\n{{/foo}}\n'
53
: [ [ '#', 'foo', 0, 8, [ [ '#', 'a', 11, 17, [ [ 'text', ' ', 18, 22 ], [ 'name', 'b', 22, 27 ], [ 'text', '\n', 27, 28 ] ], 30 ] ], 37 ] ]
56
describe('Mustache.parse', function () {
58
for (var template in expectations) {
59
(function (template, tokens) {
60
it('knows how to parse ' + JSON.stringify(template), function () {
61
assert.deepEqual(Mustache.parse(template), tokens);
63
})(template, expectations[template]);
66
describe('when there is an unclosed tag', function () {
67
it('throws an error', function () {
68
assert.throws(function () {
69
Mustache.parse('My name is {{name');
70
}, /unclosed tag at 17/i);
74
describe('when there is an unclosed section', function () {
75
it('throws an error', function () {
76
assert.throws(function () {
77
Mustache.parse('A list: {{#people}}{{name}}');
78
}, /unclosed section "people" at 27/i);
82
describe('when there is an unopened section', function () {
83
it('throws an error', function () {
84
assert.throws(function () {
85
Mustache.parse('The end of the list! {{/people}}');
86
}, /unopened section "people" at 21/i);
90
describe('when invalid tags are given as an argument', function () {
91
it('throws an error', function () {
92
assert.throws(function () {
93
Mustache.parse('A template <% name %>', [ '<%' ]);
98
describe('when the template contains invalid tags', function () {
99
it('throws an error', function () {
100
assert.throws(function () {
101
Mustache.parse('A template {{=<%=}}');
102
}, /invalid tags at 11/i);