curlybars 1.3.1 → 1.7.0
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/lib/curlybars.rb +8 -1
- data/lib/curlybars/configuration.rb +1 -9
- data/lib/curlybars/error/base.rb +2 -0
- data/lib/curlybars/generic.rb +36 -0
- data/lib/curlybars/lexer.rb +3 -0
- data/lib/curlybars/method_whitelist.rb +25 -3
- data/lib/curlybars/node/block_helper_else.rb +1 -0
- data/lib/curlybars/node/each_else.rb +6 -2
- data/lib/curlybars/node/if_else.rb +1 -1
- data/lib/curlybars/node/path.rb +58 -11
- data/lib/curlybars/node/sub_expression.rb +108 -0
- data/lib/curlybars/node/unless_else.rb +1 -1
- data/lib/curlybars/node/with_else.rb +6 -2
- data/lib/curlybars/parser.rb +39 -0
- data/lib/curlybars/processor/tilde.rb +3 -0
- data/lib/curlybars/rendering_support.rb +9 -1
- data/lib/curlybars/template_handler.rb +18 -6
- data/lib/curlybars/version.rb +1 -1
- data/lib/curlybars/visitor.rb +6 -0
- data/spec/acceptance/application_layout_spec.rb +2 -2
- data/spec/acceptance/collection_blocks_spec.rb +1 -1
- data/spec/acceptance/global_helper_spec.rb +1 -1
- data/spec/curlybars/lexer_spec.rb +25 -2
- data/spec/curlybars/method_whitelist_spec.rb +8 -4
- data/spec/curlybars/rendering_support_spec.rb +4 -9
- data/spec/curlybars/template_handler_spec.rb +33 -30
- data/spec/integration/cache_spec.rb +20 -18
- data/spec/integration/node/block_helper_else_spec.rb +0 -2
- data/spec/integration/node/each_else_spec.rb +208 -4
- data/spec/integration/node/each_spec.rb +0 -2
- data/spec/integration/node/helper_spec.rb +12 -2
- data/spec/integration/node/if_else_spec.rb +0 -2
- data/spec/integration/node/if_spec.rb +2 -4
- data/spec/integration/node/output_spec.rb +0 -2
- data/spec/integration/node/partial_spec.rb +0 -2
- data/spec/integration/node/path_spec.rb +0 -2
- data/spec/integration/node/root_spec.rb +0 -2
- data/spec/integration/node/sub_expression_spec.rb +426 -0
- data/spec/integration/node/template_spec.rb +0 -2
- data/spec/integration/node/unless_else_spec.rb +2 -4
- data/spec/integration/node/unless_spec.rb +0 -2
- data/spec/integration/node/with_spec.rb +66 -4
- data/spec/integration/processor/tilde_spec.rb +1 -1
- data/spec/integration/processors_spec.rb +4 -5
- data/spec/integration/visitor_spec.rb +13 -5
- metadata +49 -15
@@ -82,8 +82,6 @@ describe "{{#unless}}...{{else}}...{{/unless}}" do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
describe "#validate" do
|
85
|
-
let(:presenter_class) { double(:presenter_class) }
|
86
|
-
|
87
85
|
it "validates with errors the condition" do
|
88
86
|
dependency_tree = {}
|
89
87
|
|
@@ -96,7 +94,7 @@ describe "{{#unless}}...{{else}}...{{/unless}}" do
|
|
96
94
|
expect(errors).not_to be_empty
|
97
95
|
end
|
98
96
|
|
99
|
-
it "validates
|
97
|
+
it "validates without errors when using a helper in the condition" do
|
100
98
|
dependency_tree = { helper: :helper }
|
101
99
|
|
102
100
|
source = <<-HBS
|
@@ -105,7 +103,7 @@ describe "{{#unless}}...{{else}}...{{/unless}}" do
|
|
105
103
|
|
106
104
|
errors = Curlybars.validate(dependency_tree, source)
|
107
105
|
|
108
|
-
expect(errors).
|
106
|
+
expect(errors).to be_empty
|
109
107
|
end
|
110
108
|
|
111
109
|
it "validates with errors the nested unless_template" do
|
@@ -1,5 +1,5 @@
|
|
1
1
|
describe "{{#with presenter}}...{{/with}}" do
|
2
|
-
let(:global_helpers_providers) { [] }
|
2
|
+
let(:global_helpers_providers) { [IntegrationTest::GlobalHelperProvider.new] }
|
3
3
|
|
4
4
|
describe "#compile" do
|
5
5
|
let(:post) { double("post") }
|
@@ -31,6 +31,18 @@ describe "{{#with presenter}}...{{/with}}" do
|
|
31
31
|
HTML
|
32
32
|
end
|
33
33
|
|
34
|
+
it "allows subexpressions" do
|
35
|
+
template = Curlybars.compile(<<-HBS)
|
36
|
+
{{#with (translate user "sk-SK")}}
|
37
|
+
{{avatar.url}}
|
38
|
+
{{/with}}
|
39
|
+
HBS
|
40
|
+
|
41
|
+
expect(eval(template)).to resemble(<<-HTML)
|
42
|
+
http://example.com/foo.png?locale=sk-SK
|
43
|
+
HTML
|
44
|
+
end
|
45
|
+
|
34
46
|
it "allows empty with_template" do
|
35
47
|
template = Curlybars.compile(<<-HBS)
|
36
48
|
{{#with user}}{{/with}}
|
@@ -39,7 +51,7 @@ describe "{{#with presenter}}...{{/with}}" do
|
|
39
51
|
expect(eval(template)).to resemble("")
|
40
52
|
end
|
41
53
|
|
42
|
-
it "renders the else
|
54
|
+
it "renders the else template if the context is nil" do
|
43
55
|
template = Curlybars.compile(<<-HBS)
|
44
56
|
{{#with return_nil}}
|
45
57
|
text
|
@@ -75,8 +87,6 @@ describe "{{#with presenter}}...{{/with}}" do
|
|
75
87
|
end
|
76
88
|
|
77
89
|
describe "#validate" do
|
78
|
-
let(:presenter_class) { double(:presenter_class) }
|
79
|
-
|
80
90
|
it "without errors" do
|
81
91
|
dependency_tree = { a_presenter: {} }
|
82
92
|
|
@@ -89,6 +99,34 @@ describe "{{#with presenter}}...{{/with}}" do
|
|
89
99
|
expect(errors).to be_empty
|
90
100
|
end
|
91
101
|
|
102
|
+
it "without errors when a presenter helper is used" do
|
103
|
+
dependency_tree = { translate_article: [:helper, { title: nil }] }
|
104
|
+
|
105
|
+
source = <<-HBS
|
106
|
+
{{#with (translate_article 12345 "en-US")}}
|
107
|
+
{{title}}
|
108
|
+
{{/with}}
|
109
|
+
HBS
|
110
|
+
|
111
|
+
errors = Curlybars.validate(dependency_tree, source)
|
112
|
+
|
113
|
+
expect(errors).to be_empty
|
114
|
+
end
|
115
|
+
|
116
|
+
it "without errors when a generic presenter helper is used" do
|
117
|
+
dependency_tree = { article: { title: nil }, translate: [:helper, {}] }
|
118
|
+
|
119
|
+
source = <<-HBS
|
120
|
+
{{#with (translate article "en-US")}}
|
121
|
+
{{title}}
|
122
|
+
{{/with}}
|
123
|
+
HBS
|
124
|
+
|
125
|
+
errors = Curlybars.validate(dependency_tree, source)
|
126
|
+
|
127
|
+
expect(errors).to be_empty
|
128
|
+
end
|
129
|
+
|
92
130
|
it "with errors due to a leaf" do
|
93
131
|
dependency_tree = { not_a_presenter: nil }
|
94
132
|
|
@@ -112,5 +150,29 @@ describe "{{#with presenter}}...{{/with}}" do
|
|
112
150
|
|
113
151
|
expect(errors).not_to be_empty
|
114
152
|
end
|
153
|
+
|
154
|
+
it "with errors due collection helpers" do
|
155
|
+
dependency_tree = { reverse_articles: [:helper, [{ title: nil }]] }
|
156
|
+
|
157
|
+
source = <<-HBS
|
158
|
+
{{#with (reverse_articles)}}{{/with}}
|
159
|
+
HBS
|
160
|
+
|
161
|
+
errors = Curlybars.validate(dependency_tree, source)
|
162
|
+
|
163
|
+
expect(errors).not_to be_empty
|
164
|
+
end
|
165
|
+
|
166
|
+
it "with errors due generic collection helpers" do
|
167
|
+
dependency_tree = { articles: [{ title: nil }], slice: [:helper, [{}]] }
|
168
|
+
|
169
|
+
source = <<-HBS
|
170
|
+
{{#with (slice articles 0 4)}}{{/with}}
|
171
|
+
HBS
|
172
|
+
|
173
|
+
errors = Curlybars.validate(dependency_tree, source)
|
174
|
+
|
175
|
+
expect(errors).not_to be_empty
|
176
|
+
end
|
115
177
|
end
|
116
178
|
end
|
@@ -30,7 +30,7 @@ describe "tilde operator" do
|
|
30
30
|
it "runs even when 'run_processors' flag is set to false" do
|
31
31
|
allow(Curlybars::Processor::Tilde).to receive(:process!)
|
32
32
|
|
33
|
-
Curlybars.validate(presenter, "source", run_processors: false)
|
33
|
+
Curlybars.validate(presenter.dependency_tree, "source", run_processors: false)
|
34
34
|
|
35
35
|
expect(Curlybars::Processor::Tilde).to have_received(:process!)
|
36
36
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
describe "processors" do
|
2
2
|
let(:presenter) { double(:presenter, dependency_tree: { curlybars: nil }) }
|
3
|
-
let(:global_helpers_providers) { [] }
|
4
3
|
let(:processor) { double(:processor) }
|
5
4
|
|
6
5
|
before do
|
@@ -10,19 +9,19 @@ describe "processors" do
|
|
10
9
|
|
11
10
|
describe "validation" do
|
12
11
|
it "are run by default" do
|
13
|
-
Curlybars.validate(presenter, "source")
|
12
|
+
Curlybars.validate(presenter.dependency_tree, "source")
|
14
13
|
|
15
14
|
expect(processor).to have_received(:process!)
|
16
15
|
end
|
17
16
|
|
18
|
-
it "are
|
19
|
-
Curlybars.validate(presenter, "source", run_processors: true)
|
17
|
+
it "are run when run_processors is true" do
|
18
|
+
Curlybars.validate(presenter.dependency_tree, "source", run_processors: true)
|
20
19
|
|
21
20
|
expect(processor).to have_received(:process!)
|
22
21
|
end
|
23
22
|
|
24
23
|
it "are not run when run_processors is false" do
|
25
|
-
Curlybars.validate(presenter, "source", run_processors: false)
|
24
|
+
Curlybars.validate(presenter.dependency_tree, "source", run_processors: false)
|
26
25
|
|
27
26
|
expect(processor).not_to have_received(:process!)
|
28
27
|
end
|
@@ -4,6 +4,8 @@ describe "visitor" do
|
|
4
4
|
{{#print_args_and_options 'first' 'second' key='value'}}
|
5
5
|
{{/print_args_and_options}}
|
6
6
|
|
7
|
+
{{calc (calc 1 "+" 2) "*" 3}}
|
8
|
+
|
7
9
|
{{#render_inverse}}
|
8
10
|
fn
|
9
11
|
{{else}}
|
@@ -53,7 +55,7 @@ describe "visitor" do
|
|
53
55
|
it "visits BlockHelperElse nodes" do
|
54
56
|
visitor = counting_visitor_for(Curlybars::Node::BlockHelperElse)
|
55
57
|
output = Curlybars.visit(visitor, source)
|
56
|
-
expect(output).to eq(
|
58
|
+
expect(output).to eq(5)
|
57
59
|
end
|
58
60
|
|
59
61
|
it "visits EachElse nodes" do
|
@@ -71,13 +73,13 @@ describe "visitor" do
|
|
71
73
|
it "visits Item nodes" do
|
72
74
|
visitor = counting_visitor_for(Curlybars::Node::Item)
|
73
75
|
output = Curlybars.visit(visitor, source)
|
74
|
-
expect(output).to eq(
|
76
|
+
expect(output).to eq(44)
|
75
77
|
end
|
76
78
|
|
77
79
|
it "visits Literal nodes" do
|
78
80
|
visitor = counting_visitor_for(Curlybars::Node::Literal)
|
79
81
|
output = Curlybars.visit(visitor, source)
|
80
|
-
expect(output).to eq(
|
82
|
+
expect(output).to eq(8)
|
81
83
|
end
|
82
84
|
|
83
85
|
it "visits Option nodes" do
|
@@ -95,7 +97,7 @@ describe "visitor" do
|
|
95
97
|
it "visits Path nodes" do
|
96
98
|
visitor = counting_visitor_for(Curlybars::Node::Path)
|
97
99
|
output = Curlybars.visit(visitor, source)
|
98
|
-
expect(output).to eq(
|
100
|
+
expect(output).to eq(15)
|
99
101
|
end
|
100
102
|
|
101
103
|
it "visits Root nodes" do
|
@@ -104,6 +106,12 @@ describe "visitor" do
|
|
104
106
|
expect(output).to eq(1)
|
105
107
|
end
|
106
108
|
|
109
|
+
it "visits SubExpression nodes" do
|
110
|
+
visitor = counting_visitor_for(Curlybars::Node::SubExpression)
|
111
|
+
output = Curlybars.visit(visitor, source)
|
112
|
+
expect(output).to eq(1)
|
113
|
+
end
|
114
|
+
|
107
115
|
it "visits Template nodes" do
|
108
116
|
visitor = counting_visitor_for(Curlybars::Node::Template)
|
109
117
|
output = Curlybars.visit(visitor, source)
|
@@ -113,7 +121,7 @@ describe "visitor" do
|
|
113
121
|
it "visits Text nodes" do
|
114
122
|
visitor = counting_visitor_for(Curlybars::Node::Text)
|
115
123
|
output = Curlybars.visit(visitor, source)
|
116
|
-
expect(output).to eq(
|
124
|
+
expect(output).to eq(29)
|
117
125
|
end
|
118
126
|
|
119
127
|
it "visits UnlessElse nodes" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: curlybars
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Libo Cannici
|
@@ -10,10 +10,12 @@ authors:
|
|
10
10
|
- Mauro Codella
|
11
11
|
- Luís Almeida
|
12
12
|
- Andreas Garnæs
|
13
|
+
- Augusto Silva
|
14
|
+
- Attila Večerek
|
13
15
|
autorequire:
|
14
16
|
bindir: bin
|
15
17
|
cert_chain: []
|
16
|
-
date:
|
18
|
+
date: 2021-02-17 00:00:00.000000000 Z
|
17
19
|
dependencies:
|
18
20
|
- !ruby/object:Gem::Dependency
|
19
21
|
name: actionpack
|
@@ -24,7 +26,7 @@ dependencies:
|
|
24
26
|
version: '4.2'
|
25
27
|
- - "<"
|
26
28
|
- !ruby/object:Gem::Version
|
27
|
-
version: '6.
|
29
|
+
version: '6.2'
|
28
30
|
type: :runtime
|
29
31
|
prerelease: false
|
30
32
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -34,7 +36,7 @@ dependencies:
|
|
34
36
|
version: '4.2'
|
35
37
|
- - "<"
|
36
38
|
- !ruby/object:Gem::Version
|
37
|
-
version: '6.
|
39
|
+
version: '6.2'
|
38
40
|
- !ruby/object:Gem::Dependency
|
39
41
|
name: activesupport
|
40
42
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,7 +46,7 @@ dependencies:
|
|
44
46
|
version: '4.2'
|
45
47
|
- - "<"
|
46
48
|
- !ruby/object:Gem::Version
|
47
|
-
version: '6.
|
49
|
+
version: '6.2'
|
48
50
|
type: :runtime
|
49
51
|
prerelease: false
|
50
52
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -54,7 +56,7 @@ dependencies:
|
|
54
56
|
version: '4.2'
|
55
57
|
- - "<"
|
56
58
|
- !ruby/object:Gem::Version
|
57
|
-
version: '6.
|
59
|
+
version: '6.2'
|
58
60
|
- !ruby/object:Gem::Dependency
|
59
61
|
name: ffi
|
60
62
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,7 +122,7 @@ dependencies:
|
|
120
122
|
version: '4.2'
|
121
123
|
- - "<"
|
122
124
|
- !ruby/object:Gem::Version
|
123
|
-
version: '6.
|
125
|
+
version: '6.2'
|
124
126
|
type: :development
|
125
127
|
prerelease: false
|
126
128
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -130,7 +132,7 @@ dependencies:
|
|
130
132
|
version: '4.2'
|
131
133
|
- - "<"
|
132
134
|
- !ruby/object:Gem::Version
|
133
|
-
version: '6.
|
135
|
+
version: '6.2'
|
134
136
|
- !ruby/object:Gem::Dependency
|
135
137
|
name: rake
|
136
138
|
requirement: !ruby/object:Gem::Requirement
|
@@ -165,32 +167,60 @@ dependencies:
|
|
165
167
|
requirements:
|
166
168
|
- - "~>"
|
167
169
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
170
|
+
version: 1.6.0
|
169
171
|
type: :development
|
170
172
|
prerelease: false
|
171
173
|
version_requirements: !ruby/object:Gem::Requirement
|
172
174
|
requirements:
|
173
175
|
- - "~>"
|
174
176
|
- !ruby/object:Gem::Version
|
175
|
-
version:
|
177
|
+
version: 1.6.0
|
178
|
+
- !ruby/object:Gem::Dependency
|
179
|
+
name: rubocop-performance
|
180
|
+
requirement: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - "~>"
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: 1.9.0
|
185
|
+
type: :development
|
186
|
+
prerelease: false
|
187
|
+
version_requirements: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - "~>"
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: 1.9.0
|
192
|
+
- !ruby/object:Gem::Dependency
|
193
|
+
name: rubocop-rake
|
194
|
+
requirement: !ruby/object:Gem::Requirement
|
195
|
+
requirements:
|
196
|
+
- - "~>"
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
version: 0.5.0
|
199
|
+
type: :development
|
200
|
+
prerelease: false
|
201
|
+
version_requirements: !ruby/object:Gem::Requirement
|
202
|
+
requirements:
|
203
|
+
- - "~>"
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: 0.5.0
|
176
206
|
- !ruby/object:Gem::Dependency
|
177
207
|
name: rubocop-rspec
|
178
208
|
requirement: !ruby/object:Gem::Requirement
|
179
209
|
requirements:
|
180
210
|
- - "~>"
|
181
211
|
- !ruby/object:Gem::Version
|
182
|
-
version: 1.
|
212
|
+
version: 2.1.0
|
183
213
|
type: :development
|
184
214
|
prerelease: false
|
185
215
|
version_requirements: !ruby/object:Gem::Requirement
|
186
216
|
requirements:
|
187
217
|
- - "~>"
|
188
218
|
- !ruby/object:Gem::Version
|
189
|
-
version: 1.
|
219
|
+
version: 2.1.0
|
190
220
|
description: |-
|
191
221
|
A view layer for your Rails apps that separates structure and logic, using Handlebars templates.
|
192
222
|
Strongly inspired by Curly Template gem by Daniel Schierbeck.
|
193
|
-
email:
|
223
|
+
email: vikings@zendesk.com
|
194
224
|
executables: []
|
195
225
|
extensions: []
|
196
226
|
extra_rdoc_files: []
|
@@ -205,6 +235,7 @@ files:
|
|
205
235
|
- lib/curlybars/error/presenter/not_found.rb
|
206
236
|
- lib/curlybars/error/render.rb
|
207
237
|
- lib/curlybars/error/validate.rb
|
238
|
+
- lib/curlybars/generic.rb
|
208
239
|
- lib/curlybars/lexer.rb
|
209
240
|
- lib/curlybars/method_whitelist.rb
|
210
241
|
- lib/curlybars/node/block_helper_else.rb
|
@@ -219,6 +250,7 @@ files:
|
|
219
250
|
- lib/curlybars/node/path.rb
|
220
251
|
- lib/curlybars/node/root.rb
|
221
252
|
- lib/curlybars/node/string.rb
|
253
|
+
- lib/curlybars/node/sub_expression.rb
|
222
254
|
- lib/curlybars/node/template.rb
|
223
255
|
- lib/curlybars/node/text.rb
|
224
256
|
- lib/curlybars/node/unless_else.rb
|
@@ -265,6 +297,7 @@ files:
|
|
265
297
|
- spec/integration/node/partial_spec.rb
|
266
298
|
- spec/integration/node/path_spec.rb
|
267
299
|
- spec/integration/node/root_spec.rb
|
300
|
+
- spec/integration/node/sub_expression_spec.rb
|
268
301
|
- spec/integration/node/template_spec.rb
|
269
302
|
- spec/integration/node/unless_else_spec.rb
|
270
303
|
- spec/integration/node/unless_spec.rb
|
@@ -285,14 +318,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
285
318
|
requirements:
|
286
319
|
- - ">="
|
287
320
|
- !ruby/object:Gem::Version
|
288
|
-
version: '
|
321
|
+
version: '2.4'
|
289
322
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
290
323
|
requirements:
|
291
324
|
- - ">="
|
292
325
|
- !ruby/object:Gem::Version
|
293
326
|
version: '0'
|
294
327
|
requirements: []
|
295
|
-
rubygems_version: 3.
|
328
|
+
rubygems_version: 3.1.4
|
296
329
|
signing_key:
|
297
330
|
specification_version: 4
|
298
331
|
summary: Create your views using Handlebars templates!
|
@@ -318,6 +351,7 @@ test_files:
|
|
318
351
|
- spec/integration/node/unless_else_spec.rb
|
319
352
|
- spec/integration/node/output_spec.rb
|
320
353
|
- spec/integration/node/if_spec.rb
|
354
|
+
- spec/integration/node/sub_expression_spec.rb
|
321
355
|
- spec/integration/node/unless_spec.rb
|
322
356
|
- spec/integration/node/with_spec.rb
|
323
357
|
- spec/integration/node/partial_spec.rb
|