mvz-ruby-handlebars 0.0.11 → 0.0.12
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 +4 -4
- data/CHANGELOG.md +88 -8
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/Rakefile +4 -4
- data/lib/ruby-handlebars/context.rb +1 -1
- data/lib/ruby-handlebars/escapers/html_escaper.rb +1 -1
- data/lib/ruby-handlebars/helper.rb +1 -1
- data/lib/ruby-handlebars/helpers/each_helper.rb +3 -3
- data/lib/ruby-handlebars/helpers/helper_missing_helper.rb +2 -2
- data/lib/ruby-handlebars/helpers/if_helper.rb +2 -2
- data/lib/ruby-handlebars/helpers/register_default_helpers.rb +5 -5
- data/lib/ruby-handlebars/helpers/unless_helper.rb +2 -2
- data/lib/ruby-handlebars/helpers/with_helper.rb +2 -2
- data/lib/ruby-handlebars/parser.rb +19 -21
- data/lib/ruby-handlebars/template.rb +1 -1
- data/lib/ruby-handlebars/tree.rb +3 -3
- data/lib/ruby-handlebars/version.rb +1 -1
- data/lib/ruby-handlebars.rb +8 -8
- data/spec/handlebars_spec.rb +102 -102
- data/spec/parser_spec.rb +163 -155
- data/spec/ruby-handlebars/context_spec.rb +64 -64
- data/spec/ruby-handlebars/helpers/each_helper_spec.rb +41 -41
- data/spec/ruby-handlebars/helpers/helper_missing_helper_spec.rb +14 -14
- data/spec/ruby-handlebars/helpers/if_helper_spec.rb +16 -16
- data/spec/ruby-handlebars/helpers/register_default_helpers_spec.rb +10 -10
- data/spec/ruby-handlebars/helpers/unless_helper_spec.rb +14 -14
- data/spec/ruby-handlebars/helpers/with_helper_spec.rb +6 -6
- data/spec/spec_helper.rb +1 -1
- data/spec/tree_spec.rb +3 -3
- metadata +18 -4
data/spec/handlebars_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
1
|
+
require_relative "spec_helper"
|
2
|
+
require_relative "../lib/ruby-handlebars"
|
3
|
+
require_relative "../lib/ruby-handlebars/escapers/dummy_escaper"
|
4
4
|
|
5
5
|
|
6
6
|
describe Handlebars::Handlebars do
|
@@ -10,140 +10,140 @@ describe Handlebars::Handlebars do
|
|
10
10
|
hbs.compile(template).call(args)
|
11
11
|
end
|
12
12
|
|
13
|
-
context
|
14
|
-
it
|
15
|
-
expect(evaluate(
|
13
|
+
context "evaluating" do
|
14
|
+
it "a dummy template" do
|
15
|
+
expect(evaluate("My simple template")).to eq("My simple template")
|
16
16
|
end
|
17
17
|
|
18
|
-
it
|
19
|
-
expect(evaluate(
|
18
|
+
it "a simple replacement" do
|
19
|
+
expect(evaluate("Hello {{name}}", {name: "world"})).to eq("Hello world")
|
20
20
|
end
|
21
21
|
|
22
|
-
it
|
23
|
-
expect(evaluate(
|
22
|
+
it "a double braces replacement with unsafe characters" do
|
23
|
+
expect(evaluate("Hello {{name}}", {name: '<"\'>&'})).to eq("Hello <"'>&")
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
27
|
-
expect(evaluate(
|
26
|
+
it "a double braces replacement with nil" do
|
27
|
+
expect(evaluate("Hello {{name}}", {name: nil})).to eq("Hello ")
|
28
28
|
end
|
29
29
|
|
30
|
-
it
|
31
|
-
expect(evaluate(
|
30
|
+
it "a triple braces replacement with unsafe characters" do
|
31
|
+
expect(evaluate("Hello {{{name}}}", {name: '<"\'>&'})).to eq('Hello <"\'>&')
|
32
32
|
end
|
33
33
|
|
34
|
-
it
|
35
|
-
expect(evaluate(
|
34
|
+
it "allows values specified by methods" do
|
35
|
+
expect(evaluate("Hello {{name}}", double(name: "world"))).to eq("Hello world")
|
36
36
|
end
|
37
37
|
|
38
|
-
it
|
39
|
-
expect(evaluate(
|
38
|
+
it "prefers hash value over method value" do
|
39
|
+
expect(evaluate("Hello {{name}}", double(name: "world", '[]': "dog", has_key?: true))).to eq("Hello dog")
|
40
40
|
end
|
41
41
|
|
42
|
-
it
|
43
|
-
expect(evaluate(
|
42
|
+
it "handles object that implement #[] but not #has_key?" do
|
43
|
+
expect(evaluate("Hello {{name}}", double(name: "world", '[]': "dog"))).to eq("Hello world")
|
44
44
|
end
|
45
45
|
|
46
|
-
it
|
47
|
-
expect(evaluate(
|
46
|
+
it "a replacement with a path" do
|
47
|
+
expect(evaluate("My simple template: {{person.name}}", {person: {name: "Another name"}})).to eq("My simple template: Another name")
|
48
48
|
end
|
49
49
|
|
50
|
-
it
|
51
|
-
expect(evaluate(
|
50
|
+
it "prefers a replacement even if its name matches a helper" do
|
51
|
+
expect(evaluate("Hello {{each}}", {each: "world"})).to eq("Hello world")
|
52
52
|
end
|
53
53
|
|
54
|
-
it
|
55
|
-
expect(evaluate(
|
54
|
+
it "handles a parameter with a dash" do
|
55
|
+
expect(evaluate("Hello {{first-name}}", double("first-name": "world"))).to eq("Hello world")
|
56
56
|
end
|
57
57
|
|
58
|
-
context
|
59
|
-
it
|
60
|
-
hbs.register_partial(
|
58
|
+
context "partials" do
|
59
|
+
it "simple" do
|
60
|
+
hbs.register_partial("plic", "Plic")
|
61
61
|
expect(evaluate("Hello {{> plic}}")).to eq("Hello Plic")
|
62
62
|
end
|
63
63
|
|
64
|
-
it
|
65
|
-
hbs.register_partial(
|
64
|
+
it "using a name with a slash" do
|
65
|
+
hbs.register_partial("parent/plic", "Plic")
|
66
66
|
expect(evaluate("Hello {{> parent/plic}}")).to eq("Hello Plic")
|
67
67
|
end
|
68
68
|
|
69
|
-
it
|
70
|
-
hbs.register_partial(
|
69
|
+
it "using a name that begins with a slash" do
|
70
|
+
hbs.register_partial("/parent/plic", "Plic")
|
71
71
|
expect(evaluate("Hello {{> /parent/plic}}")).to eq("Hello Plic")
|
72
72
|
end
|
73
73
|
|
74
|
-
it
|
75
|
-
hbs.register_partial(
|
76
|
-
expect(evaluate("Hello {{> brackets}}", {name:
|
74
|
+
it "using context" do
|
75
|
+
hbs.register_partial("brackets", "[{{name}}]")
|
76
|
+
expect(evaluate("Hello {{> brackets}}", {name: "world"})).to eq("Hello [world]")
|
77
77
|
end
|
78
78
|
|
79
|
-
it
|
80
|
-
hbs.register_partial(
|
79
|
+
it "with a string argument" do
|
80
|
+
hbs.register_partial("with_args", "[{{name}}]")
|
81
81
|
expect(evaluate("Hello {{> with_args name='jon'}}")).to eq("Hello [jon]")
|
82
82
|
end
|
83
83
|
|
84
|
-
it
|
85
|
-
hbs.register_partial(
|
84
|
+
it "with string arguments" do
|
85
|
+
hbs.register_partial("with_args", "[{{fname}} {{lname}}]")
|
86
86
|
expect(evaluate("Hello {{> with_args fname='jon' lname='doe'}}")).to eq("Hello [jon doe]")
|
87
87
|
end
|
88
88
|
|
89
|
-
it
|
90
|
-
hbs.register_partial(
|
91
|
-
expect(evaluate("Hello {{> with_args fname='jon' lname=last_name}}", {last_name:
|
89
|
+
it "with variables in arguments" do
|
90
|
+
hbs.register_partial("with_args", "[{{fname}} {{lname}}]")
|
91
|
+
expect(evaluate("Hello {{> with_args fname='jon' lname=last_name}}", {last_name: "doe"})).to eq("Hello [jon doe]")
|
92
92
|
end
|
93
93
|
|
94
|
-
it
|
95
|
-
hbs.register_helper(
|
96
|
-
hbs.register_partial(
|
94
|
+
it "with a helper as an argument" do
|
95
|
+
hbs.register_helper("wrap_parens") {|context, value| "(#{value})"}
|
96
|
+
hbs.register_partial("with_args", "[{{fname}} {{lname}}]")
|
97
97
|
expect(evaluate("Hello {{> with_args fname='jon' lname=(wrap_parens 'doe')}}")).to eq("Hello [jon (doe)]")
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
context
|
102
|
-
it
|
103
|
-
hbs.register_helper(
|
101
|
+
context "helpers" do
|
102
|
+
it "without any argument" do
|
103
|
+
hbs.register_helper("rainbow") {|context| "-"}
|
104
104
|
expect(evaluate("{{rainbow}}")).to eq("-")
|
105
105
|
end
|
106
106
|
|
107
|
-
it
|
108
|
-
hbs.register_helper(
|
107
|
+
it "with a single argument" do
|
108
|
+
hbs.register_helper("noah") {|context, value| value.gsub(/a/, "")}
|
109
109
|
|
110
|
-
expect(evaluate("{{noah country}}", {country:
|
110
|
+
expect(evaluate("{{noah country}}", {country: "Canada"})).to eq("Cnd")
|
111
111
|
end
|
112
112
|
|
113
|
-
it
|
114
|
-
hbs.register_helper(
|
113
|
+
it "with multiple arguments, including strings" do
|
114
|
+
hbs.register_helper("add") {|context, left, op, right| "#{left} #{op} #{right}"}
|
115
115
|
|
116
|
-
expect(evaluate("{{add left '&' right}}", {left:
|
117
|
-
expect(evaluate("{{{add left '&' right}}}", {left:
|
116
|
+
expect(evaluate("{{add left '&' right}}", {left: "Law", right: "Order"})).to eq("Law & Order")
|
117
|
+
expect(evaluate("{{{add left '&' right}}}", {left: "Law", right: "Order"})).to eq("Law & Order")
|
118
118
|
end
|
119
119
|
|
120
|
-
it
|
121
|
-
hbs.register_helper(
|
120
|
+
it "with optional arguments not specified" do
|
121
|
+
hbs.register_helper("rainbow") {|context, *opts| "-"}
|
122
122
|
expect(evaluate("{{rainbow}}")).to eq("-")
|
123
123
|
end
|
124
124
|
|
125
|
-
it
|
126
|
-
hbs.register_helper(
|
125
|
+
it "with an empty string argument" do
|
126
|
+
hbs.register_helper("noah") {|context, value| value.to_s.gsub(/a/, "")}
|
127
127
|
|
128
128
|
expect(evaluate("hey{{noah ''}}there", {})).to eq("heythere")
|
129
129
|
end
|
130
130
|
|
131
|
-
it
|
132
|
-
hbs.register_helper(
|
133
|
-
hbs.register_helper(
|
131
|
+
it "with helpers as arguments" do
|
132
|
+
hbs.register_helper("wrap_parens") {|context, value| "(#{value})"}
|
133
|
+
hbs.register_helper("wrap_dashes") {|context, value| "-#{value}-"}
|
134
134
|
|
135
135
|
expect(evaluate('{{wrap_dashes (wrap_parens "hello")}}', {})).to eq("-(hello)-")
|
136
|
-
expect(evaluate(
|
136
|
+
expect(evaluate("{{wrap_dashes (wrap_parens world)}}", {world: "world"})).to eq("-(world)-")
|
137
137
|
end
|
138
138
|
|
139
|
-
it
|
140
|
-
hbs.register_helper(
|
139
|
+
it "with an empty string argument" do
|
140
|
+
hbs.register_helper("noah") {|context, value| value.to_s.gsub(/a/, "")}
|
141
141
|
|
142
142
|
expect(evaluate("hey{{noah ''}}there", {})).to eq("heythere")
|
143
143
|
end
|
144
144
|
|
145
|
-
it
|
146
|
-
hbs.register_helper(
|
145
|
+
it "block" do
|
146
|
+
hbs.register_helper("comment") do |context, commenter, block|
|
147
147
|
block.fn(context).split("\n").map do |line|
|
148
148
|
"#{commenter} #{line}"
|
149
149
|
end.join("\n")
|
@@ -153,14 +153,14 @@ describe Handlebars::Handlebars do
|
|
153
153
|
"Author: {{author.name}}, {{author.company}}",
|
154
154
|
"Date: {{commit_date}}",
|
155
155
|
"{{/comment}}"
|
156
|
-
].join("\n"), {author: {name:
|
156
|
+
].join("\n"), {author: {name: "Vincent", company: "Hiptest"}, commit_date: "today"})).to eq([
|
157
157
|
"// Author: Vincent, Hiptest",
|
158
158
|
"// Date: today"
|
159
159
|
].join("\n"))
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
163
|
-
it
|
163
|
+
it "block without arguments" do
|
164
164
|
template = [
|
165
165
|
"<tr>{{#indent}}",
|
166
166
|
"{{#each items}}<td>{{{ this }}}</td>",
|
@@ -169,13 +169,13 @@ describe Handlebars::Handlebars do
|
|
169
169
|
"</tr>"
|
170
170
|
].join("\n")
|
171
171
|
|
172
|
-
hbs.register_helper(
|
172
|
+
hbs.register_helper("indent") do |context, block|
|
173
173
|
block.fn(context).split("\n").map do |line|
|
174
174
|
" #{line}"
|
175
175
|
end.join("\n")
|
176
176
|
end
|
177
177
|
|
178
|
-
expect(evaluate(template, {items: [
|
178
|
+
expect(evaluate(template, {items: ["a", "b", "c"]})).to eq([
|
179
179
|
"<tr> ",
|
180
180
|
" <td>a</td>",
|
181
181
|
" <td>b</td>",
|
@@ -184,33 +184,33 @@ describe Handlebars::Handlebars do
|
|
184
184
|
].join("\n"))
|
185
185
|
end
|
186
186
|
|
187
|
-
it
|
188
|
-
data = {company: {people: [
|
189
|
-
expect(evaluate("{{#each company.people}}{{{this}}}{{/each}}", data)).to eq(
|
187
|
+
it "block parameters can be paths" do
|
188
|
+
data = {company: {people: ["a", "b", "c"]}}
|
189
|
+
expect(evaluate("{{#each company.people}}{{{this}}}{{/each}}", data)).to eq("abc")
|
190
190
|
end
|
191
191
|
|
192
|
-
it
|
193
|
-
expect { evaluate(
|
192
|
+
it "a else keyword out of a helper will raise an error" do
|
193
|
+
expect { evaluate("My {{ else }} template") }.to raise_exception(Parslet::ParseFailed)
|
194
194
|
end
|
195
195
|
|
196
196
|
it '"else" can be part of a path' do
|
197
|
-
expect(evaluate(
|
197
|
+
expect(evaluate("My {{ something.else }} template", { something: { else: "awesome" }})).to eq("My awesome template")
|
198
198
|
end
|
199
199
|
end
|
200
200
|
|
201
|
-
context
|
202
|
-
it
|
203
|
-
hbs.register_as_helper(
|
201
|
+
context "as_helpers" do
|
202
|
+
it "can be used to have names parameters inside the block" do
|
203
|
+
hbs.register_as_helper("test_with") do |context, value, name, block|
|
204
204
|
context.with_temporary_context(name => value) do
|
205
205
|
block.fn(context)
|
206
206
|
end
|
207
207
|
end
|
208
208
|
|
209
|
-
expect(evaluate("{{#test_with name as |duck|}}Duck name is: {{duck}}{{/test_with}}", {name: "Dewey"})).to eq(
|
209
|
+
expect(evaluate("{{#test_with name as |duck|}}Duck name is: {{duck}}{{/test_with}}", {name: "Dewey"})).to eq("Duck name is: Dewey")
|
210
210
|
end
|
211
211
|
|
212
212
|
it 'can have multiple "as" parameters' do
|
213
|
-
hbs.register_as_helper(
|
213
|
+
hbs.register_as_helper("test_with") do |context, value1, value2, name1, name2, block|
|
214
214
|
mapping = {}
|
215
215
|
mapping[name1] = value1
|
216
216
|
mapping[name2] = value2
|
@@ -220,47 +220,47 @@ describe Handlebars::Handlebars do
|
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
|
-
expect(evaluate("{{#test_with name1 name2 as |duck1 duck2|}}Duck names are {{duck1}} and {{duck2}}{{/test_with}}", {name1: "Huey", name2: "Dewey"})).to eq(
|
223
|
+
expect(evaluate("{{#test_with name1 name2 as |duck1 duck2|}}Duck names are {{duck1}} and {{duck2}}{{/test_with}}", {name1: "Huey", name2: "Dewey"})).to eq("Duck names are Huey and Dewey")
|
224
224
|
end
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
228
|
-
context
|
228
|
+
context "escaping characters" do
|
229
229
|
let(:escaper) { nil }
|
230
230
|
let(:name) { '<"\'>&' }
|
231
|
-
let(:replacement_escaped) { evaluate(
|
231
|
+
let(:replacement_escaped) { evaluate("Hello {{ name }}", {name: name}) }
|
232
232
|
let(:helper_replacement_escaped) {
|
233
|
-
hbs.register_helper(
|
234
|
-
evaluate(
|
233
|
+
hbs.register_helper("wrap_parens") {|context, value| "(#{value})"}
|
234
|
+
evaluate("Hello {{wrap_parens name}}", {name: name})
|
235
235
|
}
|
236
236
|
|
237
237
|
before do
|
238
238
|
hbs.set_escaper(escaper)
|
239
239
|
end
|
240
240
|
|
241
|
-
context
|
242
|
-
it
|
243
|
-
expect(replacement_escaped).to eq(
|
241
|
+
context "default escaper" do
|
242
|
+
it "escapes HTML characters in simple replacements" do
|
243
|
+
expect(replacement_escaped).to eq("Hello <"'>&")
|
244
244
|
end
|
245
245
|
|
246
|
-
it
|
247
|
-
expect(helper_replacement_escaped).to eq(
|
246
|
+
it "escapes HTML characters in helpers" do
|
247
|
+
expect(helper_replacement_escaped).to eq("Hello (<"'>&)")
|
248
248
|
end
|
249
249
|
end
|
250
250
|
|
251
|
-
context
|
251
|
+
context "DummyEscaper" do
|
252
252
|
let(:escaper) { Handlebars::Escapers::DummyEscaper }
|
253
253
|
|
254
|
-
it
|
254
|
+
it "escapes nothing" do
|
255
255
|
expect(replacement_escaped).to eq('Hello <"\'>&')
|
256
256
|
end
|
257
257
|
|
258
|
-
it
|
258
|
+
it "escapes nothing in helpers" do
|
259
259
|
expect(helper_replacement_escaped).to eq('Hello (<"\'>&)')
|
260
260
|
end
|
261
261
|
end
|
262
262
|
|
263
|
-
context
|
263
|
+
context "custom escaper" do
|
264
264
|
class VowelEscaper
|
265
265
|
def self.escape(value)
|
266
266
|
value.gsub(/([aeiuo])/, '-\1')
|
@@ -268,14 +268,14 @@ describe Handlebars::Handlebars do
|
|
268
268
|
end
|
269
269
|
|
270
270
|
let(:escaper) { VowelEscaper }
|
271
|
-
let(:name) {
|
271
|
+
let(:name) { "Her Serene Highness" }
|
272
272
|
|
273
|
-
it
|
274
|
-
expect(replacement_escaped).to eq(
|
273
|
+
it "applies the escaping" do
|
274
|
+
expect(replacement_escaped).to eq("Hello H-er S-er-en-e H-ighn-ess")
|
275
275
|
end
|
276
276
|
|
277
|
-
it
|
278
|
-
expect(helper_replacement_escaped).to eq(
|
277
|
+
it "applies the escaping in helpers" do
|
278
|
+
expect(helper_replacement_escaped).to eq("Hello (H-er S-er-en-e H-ighn-ess)")
|
279
279
|
end
|
280
280
|
end
|
281
281
|
end
|