locomotivecms-solid 0.2.2

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +10 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE +20 -0
  7. data/README.md +152 -0
  8. data/Rakefile +7 -0
  9. data/lib/locomotivecms-solid.rb +2 -0
  10. data/lib/solid.rb +48 -0
  11. data/lib/solid/arguments.rb +26 -0
  12. data/lib/solid/block.rb +13 -0
  13. data/lib/solid/conditional_block.rb +35 -0
  14. data/lib/solid/context_error.rb +2 -0
  15. data/lib/solid/default_security_rules.rb +24 -0
  16. data/lib/solid/element.rb +51 -0
  17. data/lib/solid/engine.rb +4 -0
  18. data/lib/solid/extensions.rb +17 -0
  19. data/lib/solid/iterable.rb +18 -0
  20. data/lib/solid/liquid_extensions.rb +87 -0
  21. data/lib/solid/liquid_extensions/assign_tag.rb +21 -0
  22. data/lib/solid/liquid_extensions/for_tag.rb +102 -0
  23. data/lib/solid/liquid_extensions/if_tag.rb +44 -0
  24. data/lib/solid/liquid_extensions/unless_tag.rb +13 -0
  25. data/lib/solid/liquid_extensions/variable.rb +34 -0
  26. data/lib/solid/method_whitelist.rb +56 -0
  27. data/lib/solid/model_drop.rb +119 -0
  28. data/lib/solid/parser.rb +108 -0
  29. data/lib/solid/parser/ripper.rb +220 -0
  30. data/lib/solid/parser/ruby_parser.rb +88 -0
  31. data/lib/solid/tag.rb +11 -0
  32. data/lib/solid/template.rb +24 -0
  33. data/lib/solid/version.rb +3 -0
  34. data/locomotivecms-solid.gemspec +26 -0
  35. data/spec/solid/arguments_spec.rb +314 -0
  36. data/spec/solid/block_spec.rb +39 -0
  37. data/spec/solid/conditional_block_spec.rb +39 -0
  38. data/spec/solid/default_security_rules_spec.rb +180 -0
  39. data/spec/solid/element_examples.rb +67 -0
  40. data/spec/solid/liquid_extensions/assign_tag_spec.rb +27 -0
  41. data/spec/solid/liquid_extensions/for_tag_spec.rb +48 -0
  42. data/spec/solid/liquid_extensions/if_tag_spec.rb +64 -0
  43. data/spec/solid/liquid_extensions/unless_tag_spec.rb +54 -0
  44. data/spec/solid/liquid_extensions/variable_spec.rb +25 -0
  45. data/spec/solid/model_drop_spec.rb +26 -0
  46. data/spec/solid/parser/ripper_spec.rb +14 -0
  47. data/spec/solid/parser/ruby_parser_spec.rb +7 -0
  48. data/spec/solid/tag_spec.rb +26 -0
  49. data/spec/solid/template_spec.rb +37 -0
  50. data/spec/spec_helper.rb +8 -0
  51. data/spec/support/class_highjacker_examples.rb +33 -0
  52. data/spec/support/method_whitelist_matchers.rb +17 -0
  53. data/spec/support/parser_examples.rb +261 -0
  54. data/spec/support/tag_highjacker_examples.rb +33 -0
  55. metadata +204 -0
@@ -0,0 +1,17 @@
1
+ RSpec::Matchers.define :safely_respond_to do |method_name|
2
+ match do |object|
3
+ Solid::MethodWhitelist.safely_respond_to?(object, method_name)
4
+ end
5
+ end
6
+
7
+ def it_should_safely_respond_to(*methods)
8
+ methods.each do |method|
9
+ it { should safely_respond_to method }
10
+ end
11
+ end
12
+
13
+ def it_should_not_safely_respond_to(*methods)
14
+ methods.each do |method|
15
+ it { should_not safely_respond_to method }
16
+ end
17
+ end
@@ -0,0 +1,261 @@
1
+ RSpec::Matchers.define :evaluate_to do |value|
2
+
3
+ match do |expression|
4
+ expression.evaluate(context).should be == value
5
+ end
6
+
7
+ end
8
+
9
+ shared_examples 'a solid parser' do
10
+
11
+ let(:parser) { described_class }
12
+
13
+ let(:context) { {} }
14
+
15
+ context 'literals parsing' do
16
+
17
+ it 'is able to parse an Integer' do
18
+ exp = parser.parse('42')
19
+ exp.should be_a Solid::Parser::Literal
20
+ exp.should evaluate_to 42
21
+ end
22
+
23
+ it 'is able to parse a Float' do
24
+ exp = parser.parse('4.2')
25
+ exp.should be_a Solid::Parser::Literal
26
+ exp.should evaluate_to 4.2
27
+ end
28
+
29
+ it 'is able to parse a String' do
30
+ exp = parser.parse('"foo"')
31
+ exp.should be_a Solid::Parser::Literal
32
+ exp.should evaluate_to 'foo'
33
+ end
34
+
35
+ it 'is able to parse a single quoted String' do
36
+ exp = parser.parse("'foo'")
37
+ exp.should be_a Solid::Parser::Literal
38
+ exp.should evaluate_to 'foo'
39
+ end
40
+
41
+ it 'is able to parse an Array' do
42
+ exp = parser.parse('[1, 2, 3]')
43
+ exp.should be_a Solid::Parser::LiteralArray
44
+ exp.should evaluate_to [1, 2, 3]
45
+ end
46
+
47
+ it 'is able to parse an empty Array' do
48
+ exp = parser.parse('[]')
49
+ exp.should be_a Solid::Parser::LiteralArray
50
+ exp.should evaluate_to []
51
+ end
52
+
53
+ it 'is able to parse a inclusive Range' do
54
+ exp = parser.parse('1..10')
55
+ exp.should be_a Solid::Parser::LiteralRange
56
+ exp.should evaluate_to 1..10
57
+ end
58
+
59
+ it 'is able to parse a exclusive Range' do
60
+ exp = parser.parse('1...10')
61
+ exp.should be_a Solid::Parser::LiteralRange
62
+ exp.should evaluate_to 1...10
63
+ end
64
+
65
+ it 'is able to parse a inclusive Range of Float' do
66
+ exp = parser.parse('1.0..10.0')
67
+ exp.should be_a Solid::Parser::LiteralRange
68
+ exp.should evaluate_to 1.0..10.0
69
+ end
70
+
71
+ it 'is able to parse a exclusive Range of Float' do
72
+ exp = parser.parse('1.0...10.0')
73
+ exp.should be_a Solid::Parser::LiteralRange
74
+ exp.should evaluate_to 1.0...10.0
75
+ end
76
+
77
+ it 'is able to parse a Hash' do
78
+ exp = parser.parse('{1 => 2, 3 => 4}')
79
+ exp.should be_a Solid::Parser::LiteralHash
80
+ exp.should evaluate_to({1 => 2, 3 => 4})
81
+ end
82
+
83
+ it 'is able to parse an empty Hash' do
84
+ exp = parser.parse('{}')
85
+ exp.should be_a Solid::Parser::LiteralHash
86
+ exp.should evaluate_to({})
87
+ end
88
+
89
+ it 'is able to parse a simple Regex' do
90
+ exp = parser.parse('/foo/')
91
+ exp.should be_a Solid::Parser::Literal
92
+ exp.should evaluate_to(/foo/)
93
+ end
94
+
95
+ it 'is able to parse a flagged Regex' do
96
+ exp = parser.parse('/foo/x')
97
+ exp.should be_a Solid::Parser::Literal
98
+ exp.should evaluate_to(/foo/x)
99
+ end
100
+
101
+ it 'is able to parse a true Boolean' do
102
+ exp = parser.parse('true')
103
+ exp.should be_a Solid::Parser::Literal
104
+ exp.should evaluate_to(true)
105
+ end
106
+
107
+ it 'is able to parse a false Boolean' do
108
+ exp = parser.parse('false')
109
+ exp.should be_a Solid::Parser::Literal
110
+ exp.should evaluate_to(false)
111
+ end
112
+
113
+ it 'is able to parse a nil' do
114
+ exp = parser.parse('nil')
115
+ exp.should be_a Solid::Parser::Literal
116
+ exp.should evaluate_to(nil)
117
+ end
118
+
119
+ end
120
+
121
+ context 'constants and variable reference' do
122
+
123
+ let(:context) { {'TRUTH' => 42, 'somevar' => 'foo'} }
124
+
125
+ it 'is able to reference a simple constant' do
126
+ exp = parser.parse('TRUTH')
127
+ exp.should be_a Solid::Parser::ContextVariable
128
+ exp.should evaluate_to(42)
129
+ end
130
+
131
+ it 'is able to reference a simple variable' do
132
+ exp = parser.parse('somevar')
133
+ exp.should be_a Solid::Parser::ContextVariable
134
+ exp.should evaluate_to('foo')
135
+ end
136
+
137
+ end
138
+
139
+ context 'methods calling' do
140
+
141
+ class Dummy
142
+
143
+ def echo(exp)
144
+ exp
145
+ end
146
+
147
+ def [](key)
148
+ key
149
+ end
150
+
151
+ def to_liquid
152
+ self
153
+ end
154
+
155
+ end
156
+
157
+ let(:context) { {'somevar' => 'foo', 'dummy' => Dummy.new, 'truth' => 42} }
158
+
159
+ it 'is able to call simple methods without arguments' do
160
+ exp = parser.parse('somevar.length')
161
+ exp.should be_a Solid::Parser::MethodCall
162
+ exp.should evaluate_to(3)
163
+ end
164
+
165
+ it 'is able to call a method on a literal' do
166
+ exp = parser.parse('"foo".length')
167
+ exp.should be_a Solid::Parser::MethodCall
168
+ exp.should evaluate_to(3)
169
+ end
170
+
171
+ it 'is able to call a simple method ending with a "?"' do
172
+ exp = parser.parse('somevar.nil?')
173
+ exp.should be_a Solid::Parser::MethodCall
174
+ exp.should evaluate_to(false)
175
+ end
176
+
177
+ it 'is able to call a simple method ending with a "!"' do
178
+ exp = parser.parse('somevar.strip!')
179
+ exp.should be_a Solid::Parser::MethodCall
180
+ exp.should evaluate_to(nil)
181
+ end
182
+
183
+ it 'is able to call a method on nil' do
184
+ exp = parser.parse('nil.nil?')
185
+ exp.should be_a Solid::Parser::MethodCall
186
+ exp.should evaluate_to(true)
187
+ end
188
+
189
+ it 'is able to call a method with arguments' do
190
+ exp = parser.parse('somevar.gsub("f", "b")')
191
+ exp.should be_a Solid::Parser::MethodCall
192
+ exp.should evaluate_to('boo')
193
+ end
194
+
195
+ it 'is able to call a method with unenclosed terminating hash' do
196
+ exp = parser.parse('dummy.echo("foo" => "bar")')
197
+ exp.should be_a Solid::Parser::MethodCall
198
+ exp.should evaluate_to({"foo" => "bar"})
199
+ end
200
+
201
+ it 'is able to call "binary operator" methods' do
202
+ exp = parser.parse('1 + 1')
203
+ exp.should be_a Solid::Parser::MethodCall
204
+ exp.should evaluate_to(2)
205
+ end
206
+
207
+ it 'is able to call `-` "unary operator" methods' do
208
+ exp = parser.parse('-truth')
209
+ exp.should be_a Solid::Parser::MethodCall
210
+ exp.should evaluate_to(-42)
211
+ end
212
+
213
+ it 'is able to call `+` "unary operator" methods' do
214
+ exp = parser.parse('+truth')
215
+ exp.should be_a Solid::Parser::MethodCall
216
+ exp.should evaluate_to(42)
217
+ end
218
+
219
+ it 'is able to call `~` "unary operator" methods' do
220
+ exp = parser.parse('~truth')
221
+ exp.should be_a Solid::Parser::MethodCall
222
+ exp.should evaluate_to(-43)
223
+ end
224
+
225
+ end
226
+
227
+ context 'boolean operators' do
228
+
229
+ it 'is able to evaluate && expressions' do
230
+ exp = parser.parse('true && true')
231
+ exp.should be_a Solid::Parser::MethodCall
232
+ exp.should evaluate_to(true)
233
+ end
234
+
235
+ it 'is able to evaluate || expressions' do
236
+ exp = parser.parse('true || false')
237
+ exp.should be_a Solid::Parser::MethodCall
238
+ exp.should evaluate_to(true)
239
+ end
240
+
241
+ it 'is able to evaluate `and` expressions' do
242
+ exp = parser.parse('true or true')
243
+ exp.should be_a Solid::Parser::MethodCall
244
+ exp.should evaluate_to(true)
245
+ end
246
+
247
+ it 'is able to evaluate `or` expressions' do
248
+ exp = parser.parse('true or false')
249
+ exp.should be_a Solid::Parser::MethodCall
250
+ exp.should evaluate_to(true)
251
+ end
252
+
253
+ it 'is able to evaluate `!` expressions' do
254
+ exp = parser.parse('!false')
255
+ exp.should be_a Solid::Parser::MethodCall
256
+ exp.should evaluate_to(true)
257
+ end
258
+
259
+ end
260
+
261
+ end
@@ -0,0 +1,33 @@
1
+ shared_examples "a tag highjacker" do
2
+
3
+ context 'tag highjacking' do
4
+
5
+ let(:highjacked_tag_name) { described_class.tag_name.to_s }
6
+
7
+ def highjacked_tag
8
+ Liquid::Template.tags[highjacked_tag_name]
9
+ end
10
+
11
+ after :each do
12
+ described_class.unload!
13
+ end
14
+
15
+ let!(:original_tag_id) { highjacked_tag.object_id }
16
+
17
+ it 'should be able to replace original tag class' do
18
+ expect{
19
+ described_class.load!
20
+ }.to change{ highjacked_tag.object_id }.from(original_tag_id).to(described_class.object_id)
21
+ end
22
+
23
+ it 'should be able to restore original tag class' do
24
+ described_class.load!
25
+ expect{
26
+ described_class.unload!
27
+ }.to change{ highjacked_tag.object_id }.from(described_class.object_id).to(original_tag_id)
28
+ end
29
+
30
+ end
31
+
32
+
33
+ end
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: locomotivecms-solid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Jean Boussier
8
+ - Yannick François
9
+ - Didier Lafforgue
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-09-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: i18n
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: ruby_parser
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: '3.2'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: '3.2'
71
+ - !ruby/object:Gem::Dependency
72
+ name: activesupport
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '3'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ~>
83
+ - !ruby/object:Gem::Version
84
+ version: '3'
85
+ - !ruby/object:Gem::Dependency
86
+ name: locomotivecms-liquid
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ version: 2.6.0
92
+ type: :runtime
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: 2.6.0
99
+ description: The Solid gem from the TigerLily team but modified to work with LocomotiveCMS
100
+ email:
101
+ - jean.boussier@tigerlilyapps.com
102
+ - yannick@tigerlilyapps.com
103
+ - didier.lafforgue@gmail.com
104
+ executables: []
105
+ extensions: []
106
+ extra_rdoc_files: []
107
+ files:
108
+ - .gitignore
109
+ - .rspec
110
+ - .travis.yml
111
+ - Gemfile
112
+ - LICENSE
113
+ - README.md
114
+ - Rakefile
115
+ - lib/locomotivecms-solid.rb
116
+ - lib/solid.rb
117
+ - lib/solid/arguments.rb
118
+ - lib/solid/block.rb
119
+ - lib/solid/conditional_block.rb
120
+ - lib/solid/context_error.rb
121
+ - lib/solid/default_security_rules.rb
122
+ - lib/solid/element.rb
123
+ - lib/solid/engine.rb
124
+ - lib/solid/extensions.rb
125
+ - lib/solid/iterable.rb
126
+ - lib/solid/liquid_extensions.rb
127
+ - lib/solid/liquid_extensions/assign_tag.rb
128
+ - lib/solid/liquid_extensions/for_tag.rb
129
+ - lib/solid/liquid_extensions/if_tag.rb
130
+ - lib/solid/liquid_extensions/unless_tag.rb
131
+ - lib/solid/liquid_extensions/variable.rb
132
+ - lib/solid/method_whitelist.rb
133
+ - lib/solid/model_drop.rb
134
+ - lib/solid/parser.rb
135
+ - lib/solid/parser/ripper.rb
136
+ - lib/solid/parser/ruby_parser.rb
137
+ - lib/solid/tag.rb
138
+ - lib/solid/template.rb
139
+ - lib/solid/version.rb
140
+ - locomotivecms-solid.gemspec
141
+ - spec/solid/arguments_spec.rb
142
+ - spec/solid/block_spec.rb
143
+ - spec/solid/conditional_block_spec.rb
144
+ - spec/solid/default_security_rules_spec.rb
145
+ - spec/solid/element_examples.rb
146
+ - spec/solid/liquid_extensions/assign_tag_spec.rb
147
+ - spec/solid/liquid_extensions/for_tag_spec.rb
148
+ - spec/solid/liquid_extensions/if_tag_spec.rb
149
+ - spec/solid/liquid_extensions/unless_tag_spec.rb
150
+ - spec/solid/liquid_extensions/variable_spec.rb
151
+ - spec/solid/model_drop_spec.rb
152
+ - spec/solid/parser/ripper_spec.rb
153
+ - spec/solid/parser/ruby_parser_spec.rb
154
+ - spec/solid/tag_spec.rb
155
+ - spec/solid/template_spec.rb
156
+ - spec/spec_helper.rb
157
+ - spec/support/class_highjacker_examples.rb
158
+ - spec/support/method_whitelist_matchers.rb
159
+ - spec/support/parser_examples.rb
160
+ - spec/support/tag_highjacker_examples.rb
161
+ homepage: ''
162
+ licenses: []
163
+ metadata: {}
164
+ post_install_message:
165
+ rdoc_options: []
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - '>='
176
+ - !ruby/object:Gem::Version
177
+ version: '0'
178
+ requirements: []
179
+ rubyforge_project:
180
+ rubygems_version: 2.0.7
181
+ signing_key:
182
+ specification_version: 4
183
+ summary: Helpers for easily creating custom Liquid tags and block
184
+ test_files:
185
+ - spec/solid/arguments_spec.rb
186
+ - spec/solid/block_spec.rb
187
+ - spec/solid/conditional_block_spec.rb
188
+ - spec/solid/default_security_rules_spec.rb
189
+ - spec/solid/element_examples.rb
190
+ - spec/solid/liquid_extensions/assign_tag_spec.rb
191
+ - spec/solid/liquid_extensions/for_tag_spec.rb
192
+ - spec/solid/liquid_extensions/if_tag_spec.rb
193
+ - spec/solid/liquid_extensions/unless_tag_spec.rb
194
+ - spec/solid/liquid_extensions/variable_spec.rb
195
+ - spec/solid/model_drop_spec.rb
196
+ - spec/solid/parser/ripper_spec.rb
197
+ - spec/solid/parser/ruby_parser_spec.rb
198
+ - spec/solid/tag_spec.rb
199
+ - spec/solid/template_spec.rb
200
+ - spec/spec_helper.rb
201
+ - spec/support/class_highjacker_examples.rb
202
+ - spec/support/method_whitelist_matchers.rb
203
+ - spec/support/parser_examples.rb
204
+ - spec/support/tag_highjacker_examples.rb