mvz-ruby-handlebars 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +115 -0
- data/Rakefile +9 -0
- data/lib/ruby-handlebars.rb +85 -0
- data/lib/ruby-handlebars/context.rb +55 -0
- data/lib/ruby-handlebars/helper.rb +41 -0
- data/lib/ruby-handlebars/parser.rb +70 -0
- data/lib/ruby-handlebars/template.rb +20 -0
- data/lib/ruby-handlebars/tree.rb +101 -0
- data/lib/ruby-handlebars/version.rb +3 -0
- data/spec/handlebars_spec.rb +327 -0
- data/spec/parser_spec.rb +317 -0
- data/spec/spec_helper.rb +0 -0
- data/spec/tree_spec.rb +14 -0
- metadata +175 -0
@@ -0,0 +1,327 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative '../lib/ruby-handlebars'
|
3
|
+
|
4
|
+
describe Handlebars::Handlebars do
|
5
|
+
let(:hbs) {Handlebars::Handlebars.new}
|
6
|
+
|
7
|
+
def evaluate(template, args = {})
|
8
|
+
hbs.compile(template).call(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'evaluating' do
|
12
|
+
it 'a dummy template' do
|
13
|
+
expect(evaluate('My simple template')).to eq('My simple template')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'a simple replacement' do
|
17
|
+
expect(evaluate('Hello {{name}}', {name: 'world'})).to eq('Hello world')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'allows values specified by methods' do
|
21
|
+
expect(evaluate('Hello {{name}}', double(name: 'world'))).to eq('Hello world')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'prefers hash value over method value' do
|
25
|
+
expect(evaluate('Hello {{name}}', double(name: 'world', '[]': 'dog', has_key?: true))).to eq('Hello dog')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'handles object that implement #[] but not #has_key?' do
|
29
|
+
expect(evaluate('Hello {{name}}', double(name: 'world', '[]': 'dog'))).to eq('Hello world')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'a replacement with a path' do
|
33
|
+
expect(evaluate('My simple template: {{person.name}}', {person: {name: 'Another name'}})).to eq('My simple template: Another name')
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'partials' do
|
37
|
+
it 'simple' do
|
38
|
+
hbs.register_partial('plic', "Plic")
|
39
|
+
expect(evaluate("Hello {{> plic}}")).to eq("Hello Plic")
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'using context' do
|
43
|
+
hbs.register_partial('brackets', "[{{name}}]")
|
44
|
+
expect(evaluate("Hello {{> brackets}}", {name: 'world'})).to eq("Hello [world]")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'helpers' do
|
49
|
+
it 'without any argument' do
|
50
|
+
hbs.register_helper('rainbow') {|context| "-"}
|
51
|
+
expect(evaluate("{{rainbow}}")).to eq("-")
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'with a single argument' do
|
55
|
+
hbs.register_helper('noah') {|context, value| value.gsub(/a/, '')}
|
56
|
+
|
57
|
+
expect(evaluate("{{noah country}}", {country: 'Canada'})).to eq("Cnd")
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'with multiple arguments, including strings' do
|
61
|
+
hbs.register_helper('add') {|context, left, op, right| "#{left} #{op} #{right}"}
|
62
|
+
|
63
|
+
expect(evaluate("{{add left '&' right}}", {left: 'Law', right: 'Order'})).to eq("Law & Order")
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'with an empty string argument' do
|
67
|
+
hbs.register_helper('noah') {|context, value| value.to_s.gsub(/a/, '')}
|
68
|
+
|
69
|
+
expect(evaluate("hey{{noah ''}}there", {})).to eq("heythere")
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'block' do
|
73
|
+
hbs.register_helper('comment') do |context, commenter, block|
|
74
|
+
block.fn(context).split("\n").map do |line|
|
75
|
+
"#{commenter} #{line}"
|
76
|
+
end.join("\n")
|
77
|
+
|
78
|
+
expect(evaluate([
|
79
|
+
"{{comment '//'}}",
|
80
|
+
"Author: {{author.name}}, {{author.company}}",
|
81
|
+
"Date: {{commit_date}}",
|
82
|
+
"{{/comment}}"
|
83
|
+
].join("\n"), {author: {name: 'Vincent', company: 'Hiptest'}, commit_date: 'today'})).to eq([
|
84
|
+
"// Author: Vincent, Hiptest",
|
85
|
+
"// Date: today"
|
86
|
+
].join("\n"))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'block without arguments' do
|
91
|
+
template = [
|
92
|
+
"<tr>{{#indent}}",
|
93
|
+
"{{#each items}}<td>{{{ this }}}</td>",
|
94
|
+
"{{/each}}",
|
95
|
+
"{{/indent}}",
|
96
|
+
"</tr>"
|
97
|
+
].join("\n")
|
98
|
+
|
99
|
+
hbs.register_helper('indent') do |context, block|
|
100
|
+
block.fn(context).split("\n").map do |line|
|
101
|
+
" #{line}"
|
102
|
+
end.join("\n")
|
103
|
+
end
|
104
|
+
|
105
|
+
expect(evaluate(template, {items: ['a', 'b', 'c']})).to eq([
|
106
|
+
"<tr> ",
|
107
|
+
" <td>a</td>",
|
108
|
+
" <td>b</td>",
|
109
|
+
" <td>c</td>",
|
110
|
+
"</tr>"
|
111
|
+
].join("\n"))
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'block parameters can be paths' do
|
115
|
+
data = {company: {people: ['a', 'b', 'c']}}
|
116
|
+
expect(evaluate("{{#each company.people}}{{{this}}}{{/each}}", data)).to eq('abc')
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'default helpers' do
|
121
|
+
context 'if' do
|
122
|
+
it 'without else' do
|
123
|
+
template = [
|
124
|
+
"{{#if condition}}",
|
125
|
+
" Show something",
|
126
|
+
"{{/if}}"
|
127
|
+
].join("\n")
|
128
|
+
expect(evaluate(template, {condition: true})).to eq("\n Show something\n")
|
129
|
+
expect(evaluate(template, {condition: false})).to eq("")
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'with an else' do
|
133
|
+
template = [
|
134
|
+
"{{#if condition}}",
|
135
|
+
" Show something",
|
136
|
+
"{{ else }}",
|
137
|
+
" Do not show something",
|
138
|
+
"{{/if}}"
|
139
|
+
].join("\n")
|
140
|
+
expect(evaluate(template, {condition: true})).to eq("\n Show something\n")
|
141
|
+
expect(evaluate(template, {condition: false})).to eq("\n Do not show something\n")
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'imbricated ifs' do
|
145
|
+
template = [
|
146
|
+
"{{#if first_condition}}",
|
147
|
+
" {{#if second_condition}}",
|
148
|
+
" Case 1",
|
149
|
+
" {{else}}",
|
150
|
+
" Case 2",
|
151
|
+
" {{/if}}",
|
152
|
+
"{{else}}",
|
153
|
+
" {{#if second_condition}}",
|
154
|
+
" Case 3",
|
155
|
+
" {{else}}",
|
156
|
+
" Case 4",
|
157
|
+
" {{/if}}",
|
158
|
+
"{{/if}}"
|
159
|
+
].join("\n")
|
160
|
+
|
161
|
+
expect(evaluate(template, {first_condition: true, second_condition: true}).strip).to eq("Case 1")
|
162
|
+
expect(evaluate(template, {first_condition: true, second_condition: false}).strip).to eq("Case 2")
|
163
|
+
expect(evaluate(template, {first_condition: false, second_condition: true}).strip).to eq("Case 3")
|
164
|
+
expect(evaluate(template, {first_condition: false, second_condition: false}).strip).to eq("Case 4")
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'each' do
|
169
|
+
let(:ducks) {[{name: 'Huey'}, {name: 'Dewey'}, {name: 'Louis'}]}
|
170
|
+
|
171
|
+
it 'simple case' do
|
172
|
+
template = [
|
173
|
+
"<ul>",
|
174
|
+
"{{#each items}} <li>{{this.name}}</li>",
|
175
|
+
"{{/each}}</ul>"
|
176
|
+
].join("\n")
|
177
|
+
|
178
|
+
data = {items: ducks}
|
179
|
+
expect(evaluate(template, data)).to eq([
|
180
|
+
"<ul>",
|
181
|
+
" <li>Huey</li>",
|
182
|
+
" <li>Dewey</li>",
|
183
|
+
" <li>Louis</li>",
|
184
|
+
"</ul>"
|
185
|
+
].join("\n"))
|
186
|
+
|
187
|
+
data = {items: []}
|
188
|
+
expect(evaluate(template, data)).to eq([
|
189
|
+
"<ul>",
|
190
|
+
"</ul>"
|
191
|
+
].join("\n"))
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'considers not found items as an empty list and does not raise an error' do
|
195
|
+
template = [
|
196
|
+
"<ul>",
|
197
|
+
"{{#each stuff}} <li>{{this.name}}</li>",
|
198
|
+
"{{/each}}</ul>"
|
199
|
+
].join("\n")
|
200
|
+
|
201
|
+
expect(evaluate(template, {})).to eq([
|
202
|
+
"<ul>",
|
203
|
+
"</ul>"
|
204
|
+
].join("\n"))
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'considers not found items as an empty list and uses else block if provided' do
|
208
|
+
template = [
|
209
|
+
"<ul>",
|
210
|
+
"{{#each stuff}} <li>{{this.name}}</li>",
|
211
|
+
"{{else}} <li>No stuff found....</li>",
|
212
|
+
"{{/each}}</ul>"
|
213
|
+
].join("\n")
|
214
|
+
|
215
|
+
expect(evaluate(template, {})).to eq([
|
216
|
+
"<ul>",
|
217
|
+
" <li>No stuff found....</li>",
|
218
|
+
"</ul>"
|
219
|
+
].join("\n"))
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'works with non-hash data' do
|
223
|
+
template = [
|
224
|
+
"<ul>",
|
225
|
+
"{{#each items}} <li>{{this.name}}</li>",
|
226
|
+
"{{/each}}</ul>"
|
227
|
+
].join("\n")
|
228
|
+
|
229
|
+
data = double(items: ducks)
|
230
|
+
expect(evaluate(template, data)).to eq([
|
231
|
+
"<ul>",
|
232
|
+
" <li>Huey</li>",
|
233
|
+
" <li>Dewey</li>",
|
234
|
+
" <li>Louis</li>",
|
235
|
+
"</ul>"
|
236
|
+
].join("\n"))
|
237
|
+
|
238
|
+
data = {items: []}
|
239
|
+
expect(evaluate(template, data)).to eq([
|
240
|
+
"<ul>",
|
241
|
+
"</ul>"
|
242
|
+
].join("\n"))
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'using an else statement' do
|
246
|
+
template = [
|
247
|
+
"<ul>",
|
248
|
+
"{{#each items}} <li>{{this.name}}</li>",
|
249
|
+
"{{else}} <li>No ducks to display</li>",
|
250
|
+
"{{/each}}</ul>"
|
251
|
+
].join("\n")
|
252
|
+
|
253
|
+
data = {items: ducks}
|
254
|
+
expect(evaluate(template, data)).to eq([
|
255
|
+
"<ul>",
|
256
|
+
" <li>Huey</li>",
|
257
|
+
" <li>Dewey</li>",
|
258
|
+
" <li>Louis</li>",
|
259
|
+
"</ul>"
|
260
|
+
].join("\n"))
|
261
|
+
|
262
|
+
data = {items: []}
|
263
|
+
expect(evaluate(template, data)).to eq([
|
264
|
+
"<ul>",
|
265
|
+
" <li>No ducks to display</li>",
|
266
|
+
"</ul>"
|
267
|
+
].join("\n"))
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'imbricated' do
|
271
|
+
data = {people: [
|
272
|
+
{
|
273
|
+
name: 'Huey',
|
274
|
+
email: 'huey@junior-woodchucks.example.com',
|
275
|
+
phones: ['1234', '5678'],
|
276
|
+
},
|
277
|
+
{
|
278
|
+
name: 'Dewey',
|
279
|
+
email: 'dewey@junior-woodchucks.example.com',
|
280
|
+
phones: ['4321'],
|
281
|
+
}
|
282
|
+
]}
|
283
|
+
|
284
|
+
template = [
|
285
|
+
"People:",
|
286
|
+
"<ul>",
|
287
|
+
" {{#each people}}",
|
288
|
+
" <li>",
|
289
|
+
" <ul>",
|
290
|
+
" <li>Name: {{this.name}}</li>",
|
291
|
+
" <li>Phones: {{#each this.phones}} {{this}} {{/each}}</li>",
|
292
|
+
" <li>email: {{this.email}}</li>",
|
293
|
+
" </ul>",
|
294
|
+
" </li>",
|
295
|
+
" {{else}}",
|
296
|
+
" <li>No one to display</li>",
|
297
|
+
" {{/each}}",
|
298
|
+
"</ul>"
|
299
|
+
].join("\n")
|
300
|
+
|
301
|
+
expect(evaluate(template, data)).to eq([
|
302
|
+
"People:",
|
303
|
+
"<ul>",
|
304
|
+
" ",
|
305
|
+
" <li>",
|
306
|
+
" <ul>",
|
307
|
+
" <li>Name: Huey</li>",
|
308
|
+
" <li>Phones: 1234 5678 </li>",
|
309
|
+
" <li>email: huey@junior-woodchucks.example.com</li>",
|
310
|
+
" </ul>",
|
311
|
+
" </li>",
|
312
|
+
" ",
|
313
|
+
" <li>",
|
314
|
+
" <ul>",
|
315
|
+
" <li>Name: Dewey</li>",
|
316
|
+
" <li>Phones: 4321 </li>",
|
317
|
+
" <li>email: dewey@junior-woodchucks.example.com</li>",
|
318
|
+
" </ul>",
|
319
|
+
" </li>",
|
320
|
+
" ",
|
321
|
+
"</ul>"
|
322
|
+
].join("\n"))
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,317 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative '../lib/ruby-handlebars/parser'
|
3
|
+
|
4
|
+
describe Handlebars::Parser do
|
5
|
+
let(:parser) {Handlebars::Parser.new}
|
6
|
+
|
7
|
+
context 'recognizes' do
|
8
|
+
it 'simple templates' do
|
9
|
+
expect(parser.parse('Ho hi !')).to eq({
|
10
|
+
block_items: [
|
11
|
+
{template_content: 'Ho hi !'}
|
12
|
+
]
|
13
|
+
})
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'simple replacements' do
|
17
|
+
expect(parser.parse('{{plic}}')).to eq({
|
18
|
+
block_items: [
|
19
|
+
{helper_name: 'plic'}
|
20
|
+
]
|
21
|
+
})
|
22
|
+
expect(parser.parse('{{ plic}}')).to eq({
|
23
|
+
block_items: [
|
24
|
+
{helper_name: 'plic'}
|
25
|
+
]
|
26
|
+
})
|
27
|
+
expect(parser.parse('{{plic }}')).to eq({
|
28
|
+
block_items: [
|
29
|
+
{helper_name: 'plic'}
|
30
|
+
]
|
31
|
+
})
|
32
|
+
expect(parser.parse('{{ plic }}')).to eq({
|
33
|
+
block_items: [
|
34
|
+
{helper_name: 'plic'}
|
35
|
+
]
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'safe strings' do
|
40
|
+
expect(parser.parse('{{{plic}}}')).to eq({
|
41
|
+
block_items: [
|
42
|
+
{helper_name: 'plic'}
|
43
|
+
]
|
44
|
+
})
|
45
|
+
|
46
|
+
expect(parser.parse('{{{ plic}}}')).to eq({
|
47
|
+
block_items: [
|
48
|
+
{helper_name: 'plic'}
|
49
|
+
]
|
50
|
+
})
|
51
|
+
|
52
|
+
expect(parser.parse('{{{plic }}}')).to eq({
|
53
|
+
block_items: [
|
54
|
+
{helper_name: 'plic'}
|
55
|
+
]
|
56
|
+
})
|
57
|
+
|
58
|
+
expect(parser.parse('{{{ plic }}}')).to eq({
|
59
|
+
block_items: [
|
60
|
+
{helper_name: 'plic'}
|
61
|
+
]
|
62
|
+
})
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'helpers' do
|
67
|
+
it 'simple' do
|
68
|
+
expect(parser.parse('{{ capitalize plic }}')).to eq({
|
69
|
+
block_items: [
|
70
|
+
{
|
71
|
+
helper_name: 'capitalize',
|
72
|
+
parameters: {parameter_name: 'plic'}
|
73
|
+
}
|
74
|
+
]
|
75
|
+
})
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'with single-quoted string parameter' do
|
79
|
+
expect(parser.parse("{{ capitalize 'hi'}}")).to eq({
|
80
|
+
block_items: [
|
81
|
+
{
|
82
|
+
helper_name: 'capitalize',
|
83
|
+
parameters: {parameter_name: {str_content: 'hi'}},
|
84
|
+
}
|
85
|
+
]
|
86
|
+
})
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'with single-quoted empty string parameter' do
|
90
|
+
expect(parser.parse("{{ capitalize ''}}")).to eq({
|
91
|
+
block_items: [
|
92
|
+
{
|
93
|
+
helper_name: 'capitalize',
|
94
|
+
parameters: {parameter_name: {str_content: ''}},
|
95
|
+
}
|
96
|
+
]
|
97
|
+
})
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'with double-quoted string parameter' do
|
101
|
+
expect(parser.parse('{{ capitalize "hi"}}')).to eq({
|
102
|
+
block_items: [
|
103
|
+
{
|
104
|
+
helper_name: 'capitalize',
|
105
|
+
parameters: {parameter_name: {str_content: 'hi'}},
|
106
|
+
}
|
107
|
+
]
|
108
|
+
})
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'with double-quoted empty string parameter' do
|
112
|
+
expect(parser.parse('{{ capitalize ""}}')).to eq({
|
113
|
+
block_items: [
|
114
|
+
{
|
115
|
+
helper_name: 'capitalize',
|
116
|
+
parameters: {parameter_name: {str_content: ''}},
|
117
|
+
}
|
118
|
+
]
|
119
|
+
})
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'with multiple parameters' do
|
123
|
+
expect(parser.parse('{{ concat plic ploc plouf }}')).to eq({
|
124
|
+
block_items: [
|
125
|
+
{
|
126
|
+
helper_name: 'concat',
|
127
|
+
parameters: [
|
128
|
+
{parameter_name: 'plic'},
|
129
|
+
{parameter_name: 'ploc'},
|
130
|
+
{parameter_name: 'plouf'}
|
131
|
+
]
|
132
|
+
}
|
133
|
+
]
|
134
|
+
})
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'block' do
|
138
|
+
expect(parser.parse('{{#capitalize}}plic{{/capitalize}}')).to eq({
|
139
|
+
block_items: [
|
140
|
+
{
|
141
|
+
helper_name: 'capitalize',
|
142
|
+
block_items: [
|
143
|
+
{template_content: 'plic'}
|
144
|
+
]
|
145
|
+
}
|
146
|
+
]
|
147
|
+
})
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'block with parameters' do
|
151
|
+
expect(parser.parse('{{#comment "#"}}plic{{/comment}}')).to eq({
|
152
|
+
block_items: [
|
153
|
+
{
|
154
|
+
helper_name: 'comment',
|
155
|
+
parameters: {parameter_name: {str_content: '#'}},
|
156
|
+
block_items: [
|
157
|
+
{template_content: 'plic'}
|
158
|
+
]
|
159
|
+
}
|
160
|
+
]
|
161
|
+
})
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'imbricated blocks' do
|
165
|
+
expect(parser.parse('{{#comment "#"}}plic {{#capitalize}}ploc{{/capitalize}} plouc{{/comment}}')).to eq({
|
166
|
+
block_items: [
|
167
|
+
{
|
168
|
+
helper_name: 'comment',
|
169
|
+
parameters: {parameter_name: {str_content: '#'}},
|
170
|
+
block_items: [
|
171
|
+
{template_content: 'plic '},
|
172
|
+
{
|
173
|
+
helper_name: 'capitalize',
|
174
|
+
block_items: [{template_content: 'ploc'}]
|
175
|
+
},
|
176
|
+
{template_content: ' plouc'},
|
177
|
+
]
|
178
|
+
}
|
179
|
+
]
|
180
|
+
})
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'if block' do
|
185
|
+
it 'simple' do
|
186
|
+
expect(parser.parse('{{#if something}}show something else{{/if}}')).to eq({
|
187
|
+
block_items: [
|
188
|
+
{
|
189
|
+
helper_name: 'if',
|
190
|
+
parameters: {parameter_name: 'something'},
|
191
|
+
block_items: [
|
192
|
+
{template_content: 'show something else'}
|
193
|
+
]
|
194
|
+
}
|
195
|
+
]
|
196
|
+
})
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'with an else statement' do
|
200
|
+
expect(parser.parse('{{#if something}}Ok{{else}}not ok{{/if}}')).to eq({
|
201
|
+
block_items: [
|
202
|
+
{
|
203
|
+
helper_name: 'if',
|
204
|
+
parameters: {parameter_name: 'something'},
|
205
|
+
block_items: [
|
206
|
+
{template_content: 'Ok'},
|
207
|
+
{helper_name: 'else'},
|
208
|
+
{template_content: 'not ok'}
|
209
|
+
]
|
210
|
+
}
|
211
|
+
]
|
212
|
+
})
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'imbricated' do
|
216
|
+
expect(parser.parse('{{#if something}}{{#if another_thing}}Plic{{/if}}ploc{{/if}}')).to eq({
|
217
|
+
block_items: [
|
218
|
+
{
|
219
|
+
helper_name: 'if',
|
220
|
+
parameters: {parameter_name: 'something'},
|
221
|
+
block_items: [
|
222
|
+
{
|
223
|
+
helper_name: 'if',
|
224
|
+
parameters: {parameter_name: 'another_thing'},
|
225
|
+
block_items: [
|
226
|
+
{template_content: 'Plic'}
|
227
|
+
]
|
228
|
+
},
|
229
|
+
{template_content: 'ploc'}
|
230
|
+
]
|
231
|
+
}
|
232
|
+
]
|
233
|
+
})
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context 'each block' do
|
238
|
+
it 'simple' do
|
239
|
+
expect(parser.parse('{{#each people}} {{this.name}} {{/each}}')).to eq({
|
240
|
+
block_items: [
|
241
|
+
{
|
242
|
+
helper_name: 'each',
|
243
|
+
parameters: {parameter_name: 'people'},
|
244
|
+
block_items: [
|
245
|
+
{template_content: ' '},
|
246
|
+
{helper_name: 'this.name'},
|
247
|
+
{template_content: ' '}
|
248
|
+
]
|
249
|
+
}
|
250
|
+
]
|
251
|
+
})
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'imbricated' do
|
255
|
+
expect(parser.parse('{{#each people}} {{this.name}} <ul> {{#each this.contact}} <li>{{this}}</li> {{/each}}</ul>{{/each}}')).to eq({
|
256
|
+
block_items: [
|
257
|
+
{
|
258
|
+
helper_name: 'each',
|
259
|
+
parameters: {parameter_name: 'people'},
|
260
|
+
block_items: [
|
261
|
+
{template_content: ' '},
|
262
|
+
{helper_name: 'this.name'},
|
263
|
+
{template_content: ' <ul> '},
|
264
|
+
{
|
265
|
+
helper_name: 'each',
|
266
|
+
parameters: {parameter_name: 'this.contact'},
|
267
|
+
block_items: [
|
268
|
+
{template_content: ' <li>'},
|
269
|
+
{helper_name: 'this'},
|
270
|
+
{template_content: '</li> '}
|
271
|
+
]
|
272
|
+
},
|
273
|
+
{template_content: '</ul>'}
|
274
|
+
]
|
275
|
+
}
|
276
|
+
]
|
277
|
+
})
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
context 'templates with single curlies' do
|
282
|
+
it 'works with loose curlies' do
|
283
|
+
expect(parser.parse('} Hi { hey } {')).to eq({
|
284
|
+
block_items: [
|
285
|
+
{template_content: '} Hi { hey } {'}
|
286
|
+
]
|
287
|
+
})
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'works with groups of curlies' do
|
291
|
+
expect(parser.parse('{ Hi }{ hey }')).to eq({
|
292
|
+
block_items: [
|
293
|
+
{template_content: '{ Hi }{ hey }'}
|
294
|
+
]
|
295
|
+
})
|
296
|
+
end
|
297
|
+
|
298
|
+
it 'works with closing curly before value' do
|
299
|
+
expect(parser.parse('Hi }{{ hey }}')).to eq({
|
300
|
+
block_items: [
|
301
|
+
{template_content: 'Hi }'},
|
302
|
+
{helper_name: 'hey'}
|
303
|
+
]
|
304
|
+
})
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'works with closing curly before value at the start' do
|
308
|
+
expect(parser.parse('}{{ hey }}')).to eq({
|
309
|
+
block_items: [
|
310
|
+
{template_content: '}'},
|
311
|
+
{helper_name: 'hey'}
|
312
|
+
]
|
313
|
+
})
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|