curlybars 0.9.13
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/lib/curlybars.rb +108 -0
- data/lib/curlybars/configuration.rb +41 -0
- data/lib/curlybars/dependency_tracker.rb +8 -0
- data/lib/curlybars/error/base.rb +18 -0
- data/lib/curlybars/error/compile.rb +11 -0
- data/lib/curlybars/error/lex.rb +22 -0
- data/lib/curlybars/error/parse.rb +41 -0
- data/lib/curlybars/error/presenter/not_found.rb +23 -0
- data/lib/curlybars/error/render.rb +11 -0
- data/lib/curlybars/error/validate.rb +18 -0
- data/lib/curlybars/lexer.rb +60 -0
- data/lib/curlybars/method_whitelist.rb +69 -0
- data/lib/curlybars/node/block_helper_else.rb +108 -0
- data/lib/curlybars/node/boolean.rb +24 -0
- data/lib/curlybars/node/each_else.rb +69 -0
- data/lib/curlybars/node/if_else.rb +33 -0
- data/lib/curlybars/node/item.rb +31 -0
- data/lib/curlybars/node/literal.rb +28 -0
- data/lib/curlybars/node/option.rb +25 -0
- data/lib/curlybars/node/output.rb +24 -0
- data/lib/curlybars/node/partial.rb +24 -0
- data/lib/curlybars/node/path.rb +137 -0
- data/lib/curlybars/node/root.rb +29 -0
- data/lib/curlybars/node/string.rb +24 -0
- data/lib/curlybars/node/template.rb +32 -0
- data/lib/curlybars/node/text.rb +24 -0
- data/lib/curlybars/node/unless_else.rb +33 -0
- data/lib/curlybars/node/variable.rb +34 -0
- data/lib/curlybars/node/with_else.rb +54 -0
- data/lib/curlybars/parser.rb +183 -0
- data/lib/curlybars/position.rb +7 -0
- data/lib/curlybars/presenter.rb +288 -0
- data/lib/curlybars/processor/tilde.rb +31 -0
- data/lib/curlybars/processor/token_factory.rb +9 -0
- data/lib/curlybars/railtie.rb +18 -0
- data/lib/curlybars/rendering_support.rb +222 -0
- data/lib/curlybars/safe_buffer.rb +11 -0
- data/lib/curlybars/template_handler.rb +93 -0
- data/lib/curlybars/version.rb +3 -0
- data/spec/acceptance/application_layout_spec.rb +60 -0
- data/spec/acceptance/collection_blocks_spec.rb +28 -0
- data/spec/acceptance/global_helper_spec.rb +25 -0
- data/spec/curlybars/configuration_spec.rb +57 -0
- data/spec/curlybars/error/base_spec.rb +41 -0
- data/spec/curlybars/error/compile_spec.rb +19 -0
- data/spec/curlybars/error/lex_spec.rb +25 -0
- data/spec/curlybars/error/parse_spec.rb +74 -0
- data/spec/curlybars/error/render_spec.rb +19 -0
- data/spec/curlybars/error/validate_spec.rb +19 -0
- data/spec/curlybars/lexer_spec.rb +466 -0
- data/spec/curlybars/method_whitelist_spec.rb +168 -0
- data/spec/curlybars/processor/tilde_spec.rb +60 -0
- data/spec/curlybars/rendering_support_spec.rb +426 -0
- data/spec/curlybars/safe_buffer_spec.rb +46 -0
- data/spec/curlybars/template_handler_spec.rb +222 -0
- data/spec/integration/cache_spec.rb +124 -0
- data/spec/integration/comment_spec.rb +60 -0
- data/spec/integration/exception_spec.rb +31 -0
- data/spec/integration/node/block_helper_else_spec.rb +422 -0
- data/spec/integration/node/each_else_spec.rb +204 -0
- data/spec/integration/node/each_spec.rb +291 -0
- data/spec/integration/node/escape_spec.rb +27 -0
- data/spec/integration/node/helper_spec.rb +176 -0
- data/spec/integration/node/if_else_spec.rb +129 -0
- data/spec/integration/node/if_spec.rb +143 -0
- data/spec/integration/node/output_spec.rb +68 -0
- data/spec/integration/node/partial_spec.rb +66 -0
- data/spec/integration/node/path_spec.rb +286 -0
- data/spec/integration/node/root_spec.rb +15 -0
- data/spec/integration/node/template_spec.rb +86 -0
- data/spec/integration/node/unless_else_spec.rb +129 -0
- data/spec/integration/node/unless_spec.rb +130 -0
- data/spec/integration/node/with_spec.rb +116 -0
- data/spec/integration/processor/tilde_spec.rb +38 -0
- data/spec/integration/processors_spec.rb +30 -0
- metadata +358 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
describe '{{value}}' do
|
2
|
+
let(:global_helpers_providers) { [] }
|
3
|
+
|
4
|
+
describe "#compile" do
|
5
|
+
let(:post) { double("post") }
|
6
|
+
let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
|
7
|
+
|
8
|
+
it "prints out a string" do
|
9
|
+
template = Curlybars.compile(<<-HBS)
|
10
|
+
{{'hello world!'}}
|
11
|
+
HBS
|
12
|
+
|
13
|
+
expect(eval(template)).to resemble('hello world!')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "prints out a boolean" do
|
17
|
+
template = Curlybars.compile(<<-HBS)
|
18
|
+
{{true}}
|
19
|
+
HBS
|
20
|
+
|
21
|
+
expect(eval(template)).to resemble('true')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "prints out an integer" do
|
25
|
+
template = Curlybars.compile(<<-HBS)
|
26
|
+
{{7}}
|
27
|
+
HBS
|
28
|
+
|
29
|
+
expect(eval(template)).to resemble('7')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "prints out a variable" do
|
33
|
+
template = Curlybars.compile(<<-HBS)
|
34
|
+
{{#each two_elements}}
|
35
|
+
Index: {{@index}}
|
36
|
+
First: {{@first}}
|
37
|
+
Last: {{@last}}
|
38
|
+
{{/each}}
|
39
|
+
HBS
|
40
|
+
|
41
|
+
expect(eval(template)).to resemble(<<-HTML)
|
42
|
+
Index: 0
|
43
|
+
First: true
|
44
|
+
Last: false
|
45
|
+
|
46
|
+
Index: 1
|
47
|
+
First: false
|
48
|
+
Last: true
|
49
|
+
HTML
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#validate" do
|
54
|
+
let(:presenter_class) { double(:presenter_class) }
|
55
|
+
|
56
|
+
it "validates the path with errors" do
|
57
|
+
dependency_tree = {}
|
58
|
+
|
59
|
+
source = <<-HBS
|
60
|
+
{{unallowed_path}}
|
61
|
+
HBS
|
62
|
+
|
63
|
+
errors = Curlybars.validate(dependency_tree, source)
|
64
|
+
|
65
|
+
expect(errors).not_to be_empty
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
describe "{{> partial}}" do
|
2
|
+
let(:global_helpers_providers) { [] }
|
3
|
+
|
4
|
+
describe "#compile" do
|
5
|
+
let(:post) { double("post") }
|
6
|
+
let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
|
7
|
+
|
8
|
+
it "evaluates the methods chain call" do
|
9
|
+
template = Curlybars.compile(<<-HBS)
|
10
|
+
{{> partial}}
|
11
|
+
HBS
|
12
|
+
|
13
|
+
expect(eval(template)).to resemble(<<-HTML)
|
14
|
+
partial
|
15
|
+
HTML
|
16
|
+
end
|
17
|
+
|
18
|
+
it "renders nothing when the partial returns `nil`" do
|
19
|
+
template = Curlybars.compile(<<-HBS)
|
20
|
+
{{> return_nil}}
|
21
|
+
HBS
|
22
|
+
|
23
|
+
expect(eval(template)).to resemble("")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#validate" do
|
28
|
+
let(:presenter_class) { double(:presenter_class) }
|
29
|
+
|
30
|
+
it "validates the path with errors" do
|
31
|
+
dependency_tree = {}
|
32
|
+
|
33
|
+
source = <<-HBS
|
34
|
+
{{> unallowed_partial}}
|
35
|
+
HBS
|
36
|
+
|
37
|
+
errors = Curlybars.validate(dependency_tree, source)
|
38
|
+
|
39
|
+
expect(errors).not_to be_empty
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises when using a helper as a partial" do
|
43
|
+
dependency_tree = { helper: nil }
|
44
|
+
|
45
|
+
source = <<-HBS
|
46
|
+
{{> helper}}
|
47
|
+
HBS
|
48
|
+
|
49
|
+
errors = Curlybars.validate(dependency_tree, source)
|
50
|
+
|
51
|
+
expect(errors).not_to be_empty
|
52
|
+
end
|
53
|
+
|
54
|
+
it "does not raise with a valid partial" do
|
55
|
+
dependency_tree = { partial: :partial }
|
56
|
+
|
57
|
+
source = <<-HBS
|
58
|
+
{{> partial}}
|
59
|
+
HBS
|
60
|
+
|
61
|
+
errors = Curlybars.validate(dependency_tree, source)
|
62
|
+
|
63
|
+
expect(errors).to be_empty
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
describe "{{path}}" do
|
2
|
+
let(:global_helpers_providers) { [] }
|
3
|
+
|
4
|
+
describe "#compile" do
|
5
|
+
let(:post) { double("post") }
|
6
|
+
let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
|
7
|
+
|
8
|
+
it "evaluates the methods chain call" do
|
9
|
+
template = Curlybars.compile(<<-HBS)
|
10
|
+
{{user.avatar.url}}
|
11
|
+
HBS
|
12
|
+
|
13
|
+
expect(eval(template)).to resemble(<<-HTML)
|
14
|
+
http://example.com/foo.png
|
15
|
+
HTML
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is tolerant to paths that return `nil`" do
|
19
|
+
template = Curlybars.compile(<<-HBS)
|
20
|
+
{{return_nil.property}}
|
21
|
+
HBS
|
22
|
+
|
23
|
+
expect(eval(template)).to resemble("")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "{{../path}} is evaluated on the second to last context in the stack" do
|
27
|
+
template = Curlybars.compile(<<-HBS)
|
28
|
+
{{#with user.avatar}}
|
29
|
+
{{../context}}
|
30
|
+
{{/with}}
|
31
|
+
HBS
|
32
|
+
|
33
|
+
expect(eval(template)).to resemble(<<-HTML)
|
34
|
+
root_context
|
35
|
+
HTML
|
36
|
+
end
|
37
|
+
|
38
|
+
it "{{-a-path-}} is a valid path" do
|
39
|
+
template = Curlybars.compile(<<-HBS)
|
40
|
+
{{-a-path-}}
|
41
|
+
HBS
|
42
|
+
|
43
|
+
expect(eval(template)).to resemble(<<-HTML)
|
44
|
+
a path, whose name contains underscores
|
45
|
+
HTML
|
46
|
+
end
|
47
|
+
|
48
|
+
it "{{../../path}} is evaluated on the third to last context in the stack" do
|
49
|
+
template = Curlybars.compile(<<-HBS)
|
50
|
+
{{#with user}}
|
51
|
+
{{#with avatar}}
|
52
|
+
{{../../context}}
|
53
|
+
{{/with}}
|
54
|
+
{{/with}}
|
55
|
+
HBS
|
56
|
+
|
57
|
+
expect(eval(template)).to resemble(<<-HTML)
|
58
|
+
root_context
|
59
|
+
HTML
|
60
|
+
end
|
61
|
+
|
62
|
+
it "{{../path}} uses the right context, even when using the same name" do
|
63
|
+
template = Curlybars.compile(<<-HBS)
|
64
|
+
{{#with user}}
|
65
|
+
{{#with avatar}}
|
66
|
+
{{../context}}
|
67
|
+
{{/with}}
|
68
|
+
{{../context}}
|
69
|
+
{{/with}}
|
70
|
+
HBS
|
71
|
+
|
72
|
+
expect(eval(template)).to resemble(<<-HTML)
|
73
|
+
user_context
|
74
|
+
root_context
|
75
|
+
HTML
|
76
|
+
end
|
77
|
+
|
78
|
+
it "a path with more `../` than the stack size will resolve to empty string" do
|
79
|
+
template = Curlybars.compile(<<-HBS)
|
80
|
+
{{context}}
|
81
|
+
{{../context}}
|
82
|
+
{{../../context}}
|
83
|
+
HBS
|
84
|
+
|
85
|
+
expect(eval(template)).to resemble(<<-HTML)
|
86
|
+
root_context
|
87
|
+
HTML
|
88
|
+
end
|
89
|
+
|
90
|
+
it "understands `this` as the current presenter" do
|
91
|
+
template = Curlybars.compile(<<-HBS)
|
92
|
+
{{user.avatar.url}}
|
93
|
+
{{#with this}}
|
94
|
+
{{user.avatar.url}}
|
95
|
+
{{/with}}
|
96
|
+
HBS
|
97
|
+
|
98
|
+
expect(eval(template)).to resemble(<<-HTML)
|
99
|
+
http://example.com/foo.png
|
100
|
+
http://example.com/foo.png
|
101
|
+
HTML
|
102
|
+
end
|
103
|
+
|
104
|
+
it "understands `length` as allowed method on a collection" do
|
105
|
+
template = Curlybars.compile(<<-HBS)
|
106
|
+
{{array_of_users.length}}
|
107
|
+
HBS
|
108
|
+
|
109
|
+
expect(eval(template)).to resemble(<<-HTML)
|
110
|
+
1
|
111
|
+
HTML
|
112
|
+
end
|
113
|
+
|
114
|
+
it "raises when trying to call methods not implemented on context" do
|
115
|
+
template = Curlybars.compile(<<-HBS)
|
116
|
+
{{not_in_whitelist}}
|
117
|
+
HBS
|
118
|
+
|
119
|
+
expect do
|
120
|
+
eval(eval(template))
|
121
|
+
end.to raise_error(Curlybars::Error::Render)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#validate" do
|
126
|
+
let(:presenter_class) { double(:presenter_class) }
|
127
|
+
|
128
|
+
it "without errors" do
|
129
|
+
dependency_tree = { sub_context: {}, outer_field: nil }
|
130
|
+
|
131
|
+
source = <<-HBS
|
132
|
+
{{#with sub_context}}
|
133
|
+
{{../outer_field}}
|
134
|
+
{{/with}}
|
135
|
+
HBS
|
136
|
+
|
137
|
+
errors = Curlybars.validate(dependency_tree, source)
|
138
|
+
|
139
|
+
expect(errors).to be_empty
|
140
|
+
end
|
141
|
+
|
142
|
+
it "without errors when it goes out of context" do
|
143
|
+
dependency_tree = {}
|
144
|
+
|
145
|
+
source = <<-HBS
|
146
|
+
{{../outer_field}}
|
147
|
+
HBS
|
148
|
+
|
149
|
+
errors = Curlybars.validate(dependency_tree, source)
|
150
|
+
|
151
|
+
expect(errors).to be_empty
|
152
|
+
end
|
153
|
+
|
154
|
+
it "without errors using `this`" do
|
155
|
+
dependency_tree = { field: nil }
|
156
|
+
|
157
|
+
source = <<-HBS
|
158
|
+
{{#with this}}
|
159
|
+
{{field}}
|
160
|
+
{{/with}}
|
161
|
+
HBS
|
162
|
+
|
163
|
+
errors = Curlybars.validate(dependency_tree, source)
|
164
|
+
|
165
|
+
expect(errors).to be_empty
|
166
|
+
end
|
167
|
+
|
168
|
+
it "without errors using `length` on a collection of presenters" do
|
169
|
+
dependency_tree = { collection_of_presenters: [{}] }
|
170
|
+
|
171
|
+
source = <<-HBS
|
172
|
+
{{collection_of_presenters.length}}
|
173
|
+
HBS
|
174
|
+
|
175
|
+
errors = Curlybars.validate(dependency_tree, source)
|
176
|
+
|
177
|
+
expect(errors).to be_empty
|
178
|
+
end
|
179
|
+
|
180
|
+
it "with errors using `length` on anything else than a collection" do
|
181
|
+
dependency_tree = { presenter: {} }
|
182
|
+
|
183
|
+
source = <<-HBS
|
184
|
+
{{presenter.length}}
|
185
|
+
HBS
|
186
|
+
|
187
|
+
errors = Curlybars.validate(dependency_tree, source)
|
188
|
+
|
189
|
+
expect(errors).not_to be_empty
|
190
|
+
end
|
191
|
+
|
192
|
+
it "with errors when adding another step after `length`" do
|
193
|
+
dependency_tree = { presenter: {} }
|
194
|
+
|
195
|
+
source = <<-HBS
|
196
|
+
{{presenter.length.anything}}
|
197
|
+
HBS
|
198
|
+
|
199
|
+
errors = Curlybars.validate(dependency_tree, source)
|
200
|
+
|
201
|
+
expect(errors).not_to be_empty
|
202
|
+
end
|
203
|
+
|
204
|
+
it "to refer an outer scope using `this`" do
|
205
|
+
dependency_tree = { field: nil, sub_presenter: {} }
|
206
|
+
|
207
|
+
source = <<-HBS
|
208
|
+
{{#with sub_presenter}}
|
209
|
+
{{#with ../this}}
|
210
|
+
{{field}}
|
211
|
+
{{/with}}
|
212
|
+
{{/with}}
|
213
|
+
HBS
|
214
|
+
|
215
|
+
errors = Curlybars.validate(dependency_tree, source)
|
216
|
+
|
217
|
+
expect(errors).to be_empty
|
218
|
+
end
|
219
|
+
|
220
|
+
describe "with errors" do
|
221
|
+
it "raises with errors" do
|
222
|
+
dependency_tree = {}
|
223
|
+
errors = Curlybars.validate(dependency_tree, "{{unallowed_path}}")
|
224
|
+
|
225
|
+
expect(errors).not_to be_empty
|
226
|
+
end
|
227
|
+
|
228
|
+
it "raises with metadata" do
|
229
|
+
dependency_tree = {}
|
230
|
+
errors = Curlybars.validate(dependency_tree, "{{unallowed_path}}")
|
231
|
+
|
232
|
+
expect(errors.first.metadata).to eq(path: "unallowed_path", step: :unallowed_path)
|
233
|
+
end
|
234
|
+
|
235
|
+
it "raises with length 0 when the error has no length" do
|
236
|
+
dependency_tree = {}
|
237
|
+
errors = Curlybars.validate(dependency_tree, "{{ok}")
|
238
|
+
|
239
|
+
expect(errors.first.position).to eq(Curlybars::Position.new(nil, 1, 4, 0))
|
240
|
+
end
|
241
|
+
|
242
|
+
describe "raises correct error message" do
|
243
|
+
let(:dependency_tree) { { ok: nil } }
|
244
|
+
|
245
|
+
it "when path contains several parts" do
|
246
|
+
source = "{{ok.unallowed.ok}}"
|
247
|
+
errors = Curlybars.validate(dependency_tree, source)
|
248
|
+
|
249
|
+
expect(errors.first.message).to eq("not possible to access `unallowed` in `ok.unallowed.ok`")
|
250
|
+
end
|
251
|
+
|
252
|
+
it "when path contains one part" do
|
253
|
+
source = "{{unallowed}}"
|
254
|
+
errors = Curlybars.validate(dependency_tree, source)
|
255
|
+
|
256
|
+
expect(errors.first.message).to eq("'unallowed' does not exist")
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "raises exact location of unallowed steps" do
|
261
|
+
let(:dependency_tree) { { ok: { allowed: { ok: nil } } } }
|
262
|
+
|
263
|
+
it "when in a compacted form" do
|
264
|
+
source = "{{ok.unallowed.ok}}"
|
265
|
+
errors = Curlybars.validate(dependency_tree, source)
|
266
|
+
|
267
|
+
expect(errors.first.position).to eq(Curlybars::Position.new(nil, 1, 5, 12))
|
268
|
+
end
|
269
|
+
|
270
|
+
it "with `this` keyword" do
|
271
|
+
source = "{{ok.this.unallowed.ok}}"
|
272
|
+
errors = Curlybars.validate(dependency_tree, source)
|
273
|
+
|
274
|
+
expect(errors.first.position).to eq(Curlybars::Position.new(nil, 1, 10, 12))
|
275
|
+
end
|
276
|
+
|
277
|
+
it "with some spacing" do
|
278
|
+
source = " {{ ok.unallowed.ok }} "
|
279
|
+
errors = Curlybars.validate(dependency_tree, source)
|
280
|
+
|
281
|
+
expect(errors.first.position).to eq(Curlybars::Position.new(nil, 1, 9, 12))
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
describe "root" do
|
2
|
+
describe "#validate" do
|
3
|
+
let(:presenter_class) { double(:presenter_class) }
|
4
|
+
|
5
|
+
it "without errors if template is empty" do
|
6
|
+
dependency_tree = {}
|
7
|
+
|
8
|
+
source = ""
|
9
|
+
|
10
|
+
errors = Curlybars.validate(dependency_tree, source)
|
11
|
+
|
12
|
+
expect(errors).to be_empty
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
describe "template" do
|
2
|
+
let(:global_helpers_providers) { [] }
|
3
|
+
|
4
|
+
describe "#compile" do
|
5
|
+
let(:post) { double("post") }
|
6
|
+
let(:presenter) { IntegrationTest::Presenter.new(double("view_context"), post: post) }
|
7
|
+
|
8
|
+
it "raises an exception when contexts stack is too deep (>= 10)" do
|
9
|
+
template = Curlybars.compile(hbs_with_depth(10))
|
10
|
+
|
11
|
+
expect do
|
12
|
+
eval(template)
|
13
|
+
end.to raise_error(Curlybars::Error::Render)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises an exception when contexts stack is not too deep (< 10)" do
|
17
|
+
template = Curlybars.compile(hbs_with_depth(9))
|
18
|
+
|
19
|
+
expect do
|
20
|
+
eval(template)
|
21
|
+
end.not_to raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can be empty" do
|
25
|
+
template = Curlybars.compile('')
|
26
|
+
|
27
|
+
expect(eval(template)).to resemble("")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can contain a single curly" do
|
31
|
+
template = Curlybars.compile('{')
|
32
|
+
|
33
|
+
expect(eval(template)).to resemble(<<-HTML)
|
34
|
+
{
|
35
|
+
HTML
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can contain a single backslash" do
|
39
|
+
template = Curlybars.compile('\\')
|
40
|
+
|
41
|
+
expect(eval(template)).to resemble(<<-HTML)
|
42
|
+
\\
|
43
|
+
HTML
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def hbs_with_depth(depth)
|
49
|
+
hbs = "%s"
|
50
|
+
depth.times { hbs %= "{{#with this}}%s{{/with}}" }
|
51
|
+
hbs %= ''
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#validate" do
|
56
|
+
let(:presenter_class) { double(:presenter_class) }
|
57
|
+
|
58
|
+
it "without errors" do
|
59
|
+
dependency_tree = { presenter: { field: nil } }
|
60
|
+
|
61
|
+
source = <<-HBS
|
62
|
+
{{#with presenter}}
|
63
|
+
{{field}}
|
64
|
+
{{/with}}
|
65
|
+
HBS
|
66
|
+
|
67
|
+
errors = Curlybars.validate(dependency_tree, source)
|
68
|
+
|
69
|
+
expect(errors).to be_empty
|
70
|
+
end
|
71
|
+
|
72
|
+
it "with errors" do
|
73
|
+
dependency_tree = { presenter: { field: nil } }
|
74
|
+
|
75
|
+
source = <<-HBS
|
76
|
+
{{#with presenter}}
|
77
|
+
{{unallowed}}
|
78
|
+
{{/with}}
|
79
|
+
HBS
|
80
|
+
|
81
|
+
errors = Curlybars.validate(dependency_tree, source)
|
82
|
+
|
83
|
+
expect(errors).not_to be_empty
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|