rapid-core 0.1

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 (132) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +11 -0
  4. data/Gemfile.lock +53 -0
  5. data/Rakefile +61 -0
  6. data/cucumber.yml +3 -0
  7. data/doc/plan.txt +89 -0
  8. data/doc/scaffold/controller.rb +83 -0
  9. data/doc/scaffold/helper.rb +2 -0
  10. data/doc/scaffold/model.rb +5 -0
  11. data/doc/scaffold/rapid_scaffold.rb +5 -0
  12. data/doc/scaffold/views/_form.html.erb +25 -0
  13. data/doc/scaffold/views/edit.html.erb +6 -0
  14. data/doc/scaffold/views/index.html.erb +25 -0
  15. data/doc/scaffold/views/new.html.erb +5 -0
  16. data/doc/scaffold/views/show.html.erb +15 -0
  17. data/features/settings/boolean/default.feature +36 -0
  18. data/features/settings/double-nested/default.feature +50 -0
  19. data/features/settings/double-nested/if.feature +41 -0
  20. data/features/settings/double-nested/unless.feature +39 -0
  21. data/features/settings/double-nested/validates/exclusion_of.feature +30 -0
  22. data/features/settings/double-nested/validates/format_of.feature +30 -0
  23. data/features/settings/double-nested/validates/inclusion_of.feature +30 -0
  24. data/features/settings/double-nested/validates/length_of.feature +30 -0
  25. data/features/settings/double-nested/validates/presence_of.feature +37 -0
  26. data/features/settings/double-nested/validates/size_of.feature +30 -0
  27. data/features/settings/integer/default.feature +49 -0
  28. data/features/settings/nested/default.feature +50 -0
  29. data/features/settings/nested/if.feature +53 -0
  30. data/features/settings/nested/unless.feature +32 -0
  31. data/features/settings/nested/validates/exclusion_of.feature +30 -0
  32. data/features/settings/nested/validates/format_of.feature +30 -0
  33. data/features/settings/nested/validates/inclusion_of.feature +30 -0
  34. data/features/settings/nested/validates/length_of.feature +30 -0
  35. data/features/settings/nested/validates/presence_of.feature +37 -0
  36. data/features/settings/nested/validates/size_of.feature +30 -0
  37. data/features/settings/not_found.feature +33 -0
  38. data/features/settings/string/default.feature +36 -0
  39. data/features/settings/string/validates/exclusion_of.feature +30 -0
  40. data/features/settings/string/validates/format_of.feature +30 -0
  41. data/features/settings/string/validates/inclusion_of.feature +30 -0
  42. data/features/settings/string/validates/length_of.feature +30 -0
  43. data/features/settings/string/validates/presence_of.feature +37 -0
  44. data/features/settings/string/validates/size_of.feature +30 -0
  45. data/features/step_definitions/settings_steps.rb +92 -0
  46. data/features/step_definitions/skeleton_steps.rb +68 -0
  47. data/features/step_definitions/template_steps.rb +39 -0
  48. data/features/support/env.rb +6 -0
  49. data/features/templates/comment_if.feature +55 -0
  50. data/features/templates/comment_unless.feature +56 -0
  51. data/features/templates/for/for.feature +51 -0
  52. data/features/templates/if/else.feature +60 -0
  53. data/features/templates/if/elsif.feature +82 -0
  54. data/features/templates/if/if.feature +55 -0
  55. data/features/templates/namespaces/exist.feature +54 -0
  56. data/features/templates/static.feature +37 -0
  57. data/features/templates/variables.feature +61 -0
  58. data/lib/rapid/check.rb +162 -0
  59. data/lib/rapid/core.rb +37 -0
  60. data/lib/rapid/error.rb +84 -0
  61. data/lib/rapid/module.rb +35 -0
  62. data/lib/rapid/railtie.rb +18 -0
  63. data/lib/rapid/setting/base.rb +35 -0
  64. data/lib/rapid/setting/boolean_setting.rb +17 -0
  65. data/lib/rapid/setting/class_hash.rb +34 -0
  66. data/lib/rapid/setting/comments.rb +25 -0
  67. data/lib/rapid/setting/definer.rb +151 -0
  68. data/lib/rapid/setting/instance_hash.rb +132 -0
  69. data/lib/rapid/setting/instance_root.rb +107 -0
  70. data/lib/rapid/setting/integer_setting.rb +24 -0
  71. data/lib/rapid/setting/namespace/base.rb +113 -0
  72. data/lib/rapid/setting/namespace/instance.rb +84 -0
  73. data/lib/rapid/setting/nested_validations.rb +86 -0
  74. data/lib/rapid/setting/string_setting.rb +13 -0
  75. data/lib/rapid/settings.rb +129 -0
  76. data/lib/rapid/skeleton/base.rb +164 -0
  77. data/lib/rapid/skeleton/helpers/directory.rb +53 -0
  78. data/lib/rapid/skeleton/helpers/gem.rb +133 -0
  79. data/lib/rapid/skeleton/helpers/migration.rb +46 -0
  80. data/lib/rapid/skeleton/helpers/route.rb +115 -0
  81. data/lib/rapid/skeleton/helpers/script.rb +33 -0
  82. data/lib/rapid/skeleton/helpers/template.rb +73 -0
  83. data/lib/rapid/skeleton/helpers/view.rb +35 -0
  84. data/lib/rapid/spec/template.rb +104 -0
  85. data/lib/rapid/spec.rb +1 -0
  86. data/lib/rapid/tasks.rb +29 -0
  87. data/lib/rapid/template/base.rb +49 -0
  88. data/lib/rapid/template/node/base.rb +43 -0
  89. data/lib/rapid/template/node/comment_node.rb +42 -0
  90. data/lib/rapid/template/node/if_node.rb +109 -0
  91. data/lib/rapid/template/node/root.rb +51 -0
  92. data/lib/rapid/template/node/static.rb +29 -0
  93. data/lib/rapid/template/node/variable.rb +86 -0
  94. data/lib/rapid/template/parser.rb +167 -0
  95. data/lib/rapid/template/pulling/base.rb +91 -0
  96. data/lib/rapid/template/pulling/explicit.rb +92 -0
  97. data/lib/rapid/template/pulling/forgiving.rb +58 -0
  98. data/lib/rapid/version.rb +3 -0
  99. data/lib/rapid.rb +37 -0
  100. data/rapid-core.gemspec +26 -0
  101. data/spec/rapid/check_spec.rb +119 -0
  102. data/spec/rapid/error_spec.rb +14 -0
  103. data/spec/rapid/module_spec.rb +28 -0
  104. data/spec/rapid/setting/base_spec.rb +17 -0
  105. data/spec/rapid/setting/definer_spec.rb +318 -0
  106. data/spec/rapid/setting/instance_root_spec.rb +161 -0
  107. data/spec/rapid/setting/namespace/base_spec.rb +93 -0
  108. data/spec/rapid/setting/namespace/instance_spec.rb +12 -0
  109. data/spec/rapid/setting/nested_validations_spec.rb +72 -0
  110. data/spec/rapid/settings_spec.rb +51 -0
  111. data/spec/rapid/skeleton/base_spec.rb +224 -0
  112. data/spec/rapid/skeleton/helpers/directory_spec.rb +104 -0
  113. data/spec/rapid/skeleton/helpers/gem_spec.rb +180 -0
  114. data/spec/rapid/skeleton/helpers/migration_spec.rb +23 -0
  115. data/spec/rapid/skeleton/helpers/route_spec.rb +120 -0
  116. data/spec/rapid/skeleton/helpers/script_spec.rb +57 -0
  117. data/spec/rapid/skeleton/helpers/template_spec.rb +142 -0
  118. data/spec/rapid/skeleton/helpers/view_spec.rb +54 -0
  119. data/spec/rapid/spec/template_spec.rb +168 -0
  120. data/spec/rapid/template/base_spec.rb +290 -0
  121. data/spec/rapid/template/node/base_spec.rb +9 -0
  122. data/spec/rapid/template/node/comment_node_spec.rb +46 -0
  123. data/spec/rapid/template/node/if_node_spec.rb +28 -0
  124. data/spec/rapid/template/node/root_spec.rb +9 -0
  125. data/spec/rapid/template/node/static_spec.rb +17 -0
  126. data/spec/rapid/template/node/variable_spec.rb +87 -0
  127. data/spec/rapid/template/parser_spec.rb +187 -0
  128. data/spec/rapid/template/pulling/base_spec.rb +81 -0
  129. data/spec/rapid/template/pulling/explicit_spec.rb +33 -0
  130. data/spec/rapid/template/pulling/forgiving_spec.rb +132 -0
  131. data/spec/spec_helper.rb +10 -0
  132. metadata +325 -0
@@ -0,0 +1,290 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Rapid::Template::Base do
4
+
5
+ describe "pull" do
6
+
7
+ def pull erb, content
8
+ @template = Rapid::Template::Base.new(erb)
9
+ @result = @template.pull content
10
+ end
11
+
12
+ describe "static" do
13
+
14
+ it "should not pull anything from a line without ERB" do
15
+ pull %(hi hey), %(hi hey)
16
+ @result.should == {}
17
+ end
18
+
19
+ it "should pull multiple line static content" do
20
+ pull "--color\n--format documentation\n\n", "--color\n--format documentation\n\n"
21
+ @result.should == {}
22
+ end
23
+
24
+ it "should error when trailing text is not matched" do
25
+ lambda { pull %(bar hi), "bar hi more text" }.should raise_error(Rapid::NotMatchingTemplateError)
26
+ end
27
+
28
+ it "should match even when spacing isn't perfect in the project content" do
29
+ pull %(hi hey), "\nhi hey"
30
+ @result.should == {}
31
+ end
32
+
33
+ it "should match even when spacing isn't perfect in the ERB" do
34
+ pull %(\nhi hey), "hi hey"
35
+ @result.should == {}
36
+ end
37
+
38
+ it "should pull regardless of the ending newline" do
39
+ pull "hi hey\n", "hi hey\n"
40
+ @result.should == {}
41
+ end
42
+
43
+ # it "should pull regardless of too many ending newlines" do
44
+ # pull "hi hey\n\n", "hi hey"
45
+ # @result.should == {}
46
+ #
47
+ # pull "hi hey", "hi hey\n\n"
48
+ # @result.should == {}
49
+ # end
50
+
51
+ end
52
+
53
+ describe "variables" do
54
+
55
+ it "should pull a variable out when it's the entire line" do
56
+ pull %(<%= name %>), %(Dan)
57
+ @result.should == {"name" => "Dan"}
58
+ end
59
+
60
+ it "should pull a variable out when it's the entire file" do
61
+ pull "<%= name %>", "foo\nbar\nbaz\n"
62
+ @result.should == {"name" => "foo\nbar\nbaz\n"}
63
+ end
64
+
65
+ it "should pull blank" do
66
+ pull %(class Foo\n <%= foo %>\nend), "class Foo\n \nend"
67
+ @result.should == {'foo' => ''}
68
+ end
69
+
70
+ it "should pull the same variable out of the same code" do
71
+ pull %(role :app, "<%= deploy.production.domain %>"\nrole :db, "<%= deploy.production.domain %>", :primary=> true),
72
+ %(role :app, "foo"\nrole :db, "foo", :primary=> true)
73
+
74
+ @result.should == {'deploy.production.domain' => 'foo'}
75
+ end
76
+
77
+ it "should pull a variable out of an internal if var?" do
78
+ pull %(<% if foo? %>a <%= foo %> c<% end %>), "a b c"
79
+ @result.should == {"foo" => "b"}
80
+ end
81
+
82
+ it "should pull a variable out of an internal if var" do
83
+ pull %(<% if foo %>a <%= foo %> c<% end %>), "a b c"
84
+ @result.should == {"foo" => "b"}
85
+ end
86
+
87
+ it "should pull a variable from a single line" do
88
+ pull %(hi <%= name %> hey), %(hi Dan hey)
89
+ @result.should == {"name" => "Dan"}
90
+ end
91
+
92
+ it "should not be confused by less-than after a variable" do
93
+ pull %(class <%= name %> < Base), %(class Foo < Base)
94
+ @result.should == {"name" => "Foo"}
95
+ end
96
+
97
+ it "should pull two variables from the same line" do
98
+ pull %(hi <%= name %> hey <%= version %>), %(hi Dan hey 1.0)
99
+ @result.should == {"name" => "Dan", "version" => "1.0"}
100
+ end
101
+
102
+ it "should error when two ERB variables are close to one another" do
103
+ lambda { pull %(hi <%= name %><%= version %>), %(hi Dan1.0) }.should raise_error(Rapid::InvalidTemplateError)
104
+ end
105
+
106
+ it "should error when there is no variable given" do
107
+ lambda { pull %(hi <%= %> hey), "hi hey" }.should raise_error(Rapid::InvalidTemplateError)
108
+ end
109
+
110
+ it "should error when the content doesn't match the template" do
111
+ lambda { pull %(hi), %(hey) }.should raise_error(Rapid::NotMatchingTemplateError)
112
+ lambda { pull %(<%= name %> foo), %(Dan bar) }.should raise_error(Rapid::NotMatchingTemplateError)
113
+ lambda { pull %(foo <%= name %>), %(bar Dan) }.should raise_error(Rapid::NotMatchingTemplateError)
114
+ lambda { pull %(foo <%= name %> bar <%= version %> baz), %(X Dan bar 1.0 baz) }.should raise_error(Rapid::NotMatchingTemplateError)
115
+ lambda { pull %(foo <%= name %> bar <%= version %> baz), %(foo Dan X 1.0 baz) }.should raise_error(Rapid::NotMatchingTemplateError)
116
+ lambda { pull %(foo <%= name %> bar <%= version %> baz), %(foo Dan bar 1.0 X) }.should raise_error(Rapid::NotMatchingTemplateError)
117
+ lambda { pull %(foo <%= name %> bar <%= version %> baz), %(foo) }.should raise_error(Rapid::NotMatchingTemplateError)
118
+ end
119
+
120
+ end
121
+
122
+ describe "if statements" do
123
+
124
+ it "should pull true" do
125
+ pull %(<% if foo %>bar<% end %> hi), "bar hi"
126
+ @result.should == {"foo" => true}
127
+
128
+ pull %(<% if foo? %>bar<% end %> hi), "bar hi"
129
+ @result.should == {"foo" => true}
130
+
131
+ pull %(<% if foo == true %>bar<% end %> hi), "bar hi"
132
+ @result.should == {"foo" => true}
133
+ end
134
+
135
+ it "should pull false" do
136
+ pull %(<% if foo %>bar<% end %> hi), " hi"
137
+ @result.should == {"foo" => false}
138
+
139
+ pull %(<% if foo == false %>bar<% end %> hi), "bar hi"
140
+ @result.should == {"foo" => false}
141
+ end
142
+
143
+ it "should pull double quoted strings" do
144
+ pull %(<% if foo == "hi" %>bar<% end %> hi), "bar hi"
145
+ @result.should == {"foo" => "hi"}
146
+ end
147
+
148
+ it "should pull single quoted strings" do
149
+ pull %(<% if foo == 'hi' %>bar<% end %> hi), "bar hi"
150
+ @result.should == {"foo" => "hi"}
151
+ end
152
+
153
+ it "should pull integers" do
154
+ pull %(<% if foo == 1 %>bar<% end %> hi), "bar hi"
155
+ @result.should == {"foo" => 1}
156
+ end
157
+
158
+ it "should pull floats" do
159
+ pull %(<% if foo.bar == 1.2 %>bar<% end %> hi), "bar hi"
160
+ @result.should == {"foo.bar" => 1.2}
161
+ end
162
+
163
+ it "should not pull regex" do
164
+ lambda { pull %(<% if foo == /aa/ %>bar<% end %> hi), "bar hi" }.should raise_error(Rapid::InvalidTemplateError)
165
+ end
166
+
167
+ end
168
+
169
+ describe "if-else statements" do
170
+
171
+ it "should pull if" do
172
+ pull %(<% if foo %>bar<% else %>baz<% end %> hi), "bar hi"
173
+ @result.should == {"foo" => true}
174
+ end
175
+
176
+ it "should pull else" do
177
+ pull %(<% if foo %>bar<% else %>baz<% end %> hi), "baz hi"
178
+ @result.should == {"foo" => false}
179
+ end
180
+
181
+ end
182
+
183
+ describe "if-elsif-else statements" do
184
+
185
+ it "should pull if" do
186
+ pull %(<% if foo == 1 %>foo<% elsif foo == 2 %>bar<% else %>baz<% end %> hi), "foo hi"
187
+ @result.should == {"foo" => 1}
188
+ end
189
+
190
+ it "should pull elsif" do
191
+ pull %(<% if foo == 1 %>foo<% elsif foo == 2 %>bar<% else %>baz<% end %> hi), "bar hi"
192
+ @result.should == {"foo" => 2}
193
+ end
194
+
195
+ it "should pull else" do
196
+ pull %(<% if foo == 1 %>foo<% elsif foo == 2 %>bar<% else %>baz<% end %> hi), "baz hi"
197
+ @result.should == {}
198
+ end
199
+
200
+ # it "should ignore whitespace" do
201
+ # pull %(<% if foo == 1 %>\n\nfoo\t\t<% elsif foo == 2 %>\t\tbar\n\n<% else %>\n\tbaz <% end %> hi\n\n), " baz\n hi \t"
202
+ # @result.should == {}
203
+ # end
204
+
205
+ end
206
+
207
+ describe "nested if statements" do
208
+
209
+ it "should pull nested if statements" do
210
+ pull %(<% if foo %>foo <% if bar == 2 %>bar<% end %><% end %>), "foo bar"
211
+ @result.should == {"foo" => true, "bar" => 2}
212
+ end
213
+
214
+ it "should handle content after the nested if statement" do
215
+ pull %(<% if development.domain? %>{:host => "<%= development.domain %>"<% if development.port? %>, :port => <%= development.port %><% end %>}<% end %>),
216
+ %({:host => "www.example.com", :port => 8080})
217
+
218
+ @result.should == {'development.domain' => 'www.example.com', 'development.port' => '8080'}
219
+ end
220
+
221
+ end
222
+
223
+ describe "yield" do
224
+
225
+ it "should pull around a yield" do
226
+ pull %(class <%= class_name %>\n <%= yield %>\nend), "class Foo\n def baz\n end\n\nend"
227
+ @result.should == {"yield" => "def baz\n end\n", "class_name" => "Foo" }
228
+ end
229
+
230
+ end
231
+
232
+ describe "comment_unless" do
233
+
234
+ it "should pull when false" do
235
+ pull %(foo <%= comment_unless foo %>bar), "foo # bar"
236
+ @result.should == {"foo" => false}
237
+ end
238
+
239
+ it "should pull when true" do
240
+ pull %(foo <%= comment_unless foo %>bar), "foo bar"
241
+ @result.should == {"foo" => true}
242
+ end
243
+
244
+ end
245
+
246
+ describe "comment_if" do
247
+
248
+ it "should pull when false" do
249
+ pull %(foo <%= comment_if foo %>bar), "foo bar"
250
+ @result.should == {"foo" => false}
251
+ end
252
+
253
+ it "should pull when true" do
254
+ pull %(foo <%= comment_if foo %>bar), "foo # bar"
255
+ @result.should == {"foo" => true}
256
+ end
257
+
258
+ end
259
+
260
+ end
261
+
262
+ describe "push" do
263
+
264
+ def push skeleton, content
265
+ @template = Rapid::Template::Base.new content
266
+ @template.push skeleton
267
+ end
268
+
269
+ before do
270
+ @settings = mock('settings', :get_binding => nil)
271
+ end
272
+
273
+ it "should push a template with no logic" do
274
+ @skeleton = Rapid::Skeleton::Base.new @settings
275
+ push(@skeleton, %(foobar)).should == "foobar"
276
+ end
277
+
278
+ it "should catch NameError inside the template and re-raise under the Rapid namespace" do
279
+ @skeleton = Rapid::Skeleton::Base.new @settings
280
+ lambda { push(@skeleton, %(<%= foo %>)) }.should raise_error(Rapid::TemplateRenderError)
281
+ end
282
+
283
+ it "should catch SyntaxEror inside the template and re-raise under the Rapid namespace" do
284
+ @skeleton = Rapid::Skeleton::Base.new @settings
285
+ lambda { push(@skeleton, %(<% if true %>foo)) }.should raise_error(Rapid::TemplateRenderError)
286
+ end
287
+
288
+ end
289
+
290
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe Rapid::Template::Node::Base do
4
+
5
+ it "should not implement pull" do
6
+ lambda { Rapid::Template::Node::Base.new.pull(nil) }.should raise_error(NotImplementedError)
7
+ end
8
+
9
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe Rapid::Template::Node::CommentNode do
4
+
5
+ it "should implement inspect" do
6
+ Rapid::Template::Node::CommentNode.new(true, "foo").inspect.class.should == String
7
+ end
8
+
9
+ it "should automatically remove the ?" do
10
+ Rapid::Template::Node::CommentNode.new(true, "foo?").variable.should == "foo"
11
+ end
12
+
13
+ it "should implement ==" do
14
+ Rapid::Template::Node::CommentNode.new(true, "foo").should == Rapid::Template::Node::CommentNode.new(true, "foo")
15
+
16
+ Rapid::Template::Node::CommentNode.new(true, "foo").should_not == Rapid::Template::Node::CommentNode.new(false, "foo")
17
+
18
+ end
19
+
20
+ describe "pull" do
21
+
22
+ before do
23
+ @node = Rapid::Template::Node::CommentNode.new(true, "foo")
24
+ end
25
+
26
+ it "should move the result and set the variable when comment is present" do
27
+ @result = Rapid::Template::Pulling::Explicit.new("# something")
28
+
29
+ @node.pull @result
30
+
31
+ @result.content.should == "something"
32
+ @result["foo"].should == true
33
+ end
34
+
35
+ it "should not move the result over and set the variable when comment is not present" do
36
+ @result = Rapid::Template::Pulling::Explicit.new("something")
37
+
38
+ @node.pull @result
39
+
40
+ @result.content.should == "something"
41
+ @result["foo"].should == false
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe Rapid::Template::Node::IfNode do
4
+
5
+ it "should implement inspect" do
6
+ Rapid::Template::Node::IfNode.new("foo", nil).inspect.class.should == String
7
+ end
8
+
9
+ it "should not accept random arguments as nodes" do
10
+ lambda { Rapid::Template::Node::IfNode.new("foo", 3) }.should raise_error(ArgumentError)
11
+ end
12
+
13
+ it "should require content from the then node" do
14
+ lambda { Rapid::Template::Node::IfNode.new("foo", nil).pull(nil) }.should raise_error(Rapid::InvalidTemplateError)
15
+ end
16
+
17
+ it "should delegate next_to to its parent" do
18
+ @parent = mock("parent")
19
+
20
+ @if = Rapid::Template::Node::IfNode.new("foo", nil)
21
+ @if.send :parent=, @parent
22
+
23
+ @parent.should_receive(:next_to).with(@if).and_return(3)
24
+
25
+ @if.next_to(mock("child")).should == 3
26
+ end
27
+
28
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe Rapid::Template::Node::Root do
4
+
5
+ it "should implement inspect" do
6
+ Rapid::Template::Node::Root.new([]).inspect.class.should == String
7
+ end
8
+
9
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe Rapid::Template::Node::Static do
4
+
5
+ it "should implement inspect" do
6
+ Rapid::Template::Node::Static.new("foo").inspect.class.should == String
7
+ end
8
+
9
+ it "should delegate pull to result.match!" do
10
+ @result = mock 'result'
11
+ @result.should_receive(:match!).with("foo")
12
+
13
+ @node = Rapid::Template::Node::Static.new("foo")
14
+ @node.pull @result
15
+ end
16
+
17
+ end
@@ -0,0 +1,87 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ describe Rapid::Template::Node::Variable do
4
+
5
+ it "should implement inspect" do
6
+ Rapid::Template::Node::Variable.new("foo").inspect.class.should == String
7
+ end
8
+
9
+ describe "pull" do
10
+
11
+ before do
12
+ @next_text = " abcdefghijklmnopqrstuvwxyz0123456789"
13
+ @node = Rapid::Template::Node::Variable.new("foo")
14
+ @next = Rapid::Template::Node::Static.new(@next_text)
15
+
16
+ @node.stub!(:next_node).and_return(@next)
17
+ end
18
+
19
+ it "should succeed" do
20
+ @result = Rapid::Template::Pulling::Explicit.new("3 abcdefghijklmnopqrstuvwxyz0123456789")
21
+ @node.pull @result
22
+
23
+ @result["foo"].should == "3"
24
+ @result.previous_content.should == "3"
25
+ @result.content.should == " abcdefghijklmnopqrstuvwxyz0123456789"
26
+ end
27
+
28
+ it "should work even when the last piece is nil" do
29
+ @node = Rapid::Template::Node::Variable.new("foo")
30
+ @node.should_receive(:next_node).and_return(nil)
31
+
32
+ @result = Rapid::Template::Pulling::Explicit.new("3")
33
+ @node.pull @result
34
+
35
+ @result["foo"].should == "3"
36
+ @result.previous_content.should == "3"
37
+ @result.content.should == ""
38
+ end
39
+
40
+ it "should just fail if the content after the variable doesn't match at all" do
41
+ @result = Rapid::Template::Pulling::Explicit.new("foo baz")
42
+
43
+ begin
44
+ @node.pull @result
45
+ raise "it should fail"
46
+
47
+ rescue Rapid::NotMatchingTemplateError => e
48
+ e.result.should == {}
49
+ e.expected_content.should == ' abcdefghijklmnopqrstuvwxyz0123456789'
50
+ e.content.should == 'foo baz'
51
+ e.previous_content.should == ''
52
+ end
53
+ end
54
+
55
+ it "should match a blank variable and some text even when it fails" do
56
+ @result = Rapid::Template::Pulling::Explicit.new(" abcdefghijklmnopqrstuvwxyz0123")
57
+
58
+ begin
59
+ @node.pull @result
60
+ raise "it should fail"
61
+
62
+ rescue Rapid::NotMatchingTemplateError => e
63
+ e.result.should == {"foo" => ""}
64
+ e.content.should == ''
65
+ e.previous_content.should == ' abcdefghijklmnopqrstuvwxyz0123'
66
+ e.expected_content.should == '456789'
67
+ end
68
+ end
69
+
70
+ it "should some of the content after the variable" do
71
+ @result = Rapid::Template::Pulling::Explicit.new("foo abcdefghijklmnopqrstuvwxyz0123")
72
+
73
+ begin
74
+ @node.pull @result
75
+ raise "it should fail"
76
+
77
+ rescue Rapid::NotMatchingTemplateError => e
78
+ e.result.should == {"foo" => "foo"}
79
+ e.expected_content.should == '456789'
80
+ e.content.should == ''
81
+ e.previous_content.should == 'foo abcdefghijklmnopqrstuvwxyz0123'
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,187 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Rapid::Template::Parser do
4
+
5
+ def compile str
6
+ Rapid::Template::Parser.new(str).parse
7
+ end
8
+
9
+ def root_node *nodes
10
+ Rapid::Template::Node::Root.new(nodes)
11
+ end
12
+
13
+ def static_node str
14
+ Rapid::Template::Node::Static.new(str)
15
+ end
16
+
17
+ def variable_node variable_name
18
+ Rapid::Template::Node::Variable.new(variable_name)
19
+ end
20
+
21
+ def if_node *args
22
+ Rapid::Template::Node::IfNode.new(*args)
23
+ end
24
+
25
+ it "should compile a static string" do
26
+ compile("hey Dan hi").should == root_node(static_node("hey Dan hi"))
27
+ end
28
+
29
+ it "should recognize comments" do
30
+ compile("<%# some comment %>").should == root_node
31
+ compile("hi<%# some comment %>").should == root_node(static_node("hi"))
32
+ compile("<%# some comment%>hey").should == root_node(static_node("hey"))
33
+ compile("hi<%# some comment %>hey").should == root_node(static_node("hihey"))
34
+ end
35
+
36
+ it "should compile a variable assignment within a string" do
37
+ compile("<%= name %>").should == root_node(variable_node("name"))
38
+ compile("hey <%= name %> hi").should == root_node(static_node("hey "), variable_node("name"), static_node(" hi"))
39
+ compile("hey <%= name %>").should == root_node(static_node("hey "), variable_node("name"))
40
+ end
41
+
42
+ it "should compile an if statement" do
43
+ compile("hey <% if true %>Dan<% end %>").should == root_node(static_node("hey "), if_node("true", static_node("Dan")))
44
+ end
45
+
46
+ it "should raise an error for unhandled indicators" do
47
+ lambda { compile("<%== foo %>") }.should raise_error(Rapid::UnknownMethodTemplateError)
48
+ end
49
+
50
+ it "should raise an error when an unknown method is called" do
51
+ lambda { compile("<% foo do %>hey<% end %>") }.should raise_error(Rapid::UnknownMethodTemplateError)
52
+ end
53
+
54
+ it "should compile an if-else statement" do
55
+ compile("<% if true %>Dan<% else %>Rob<% end %>").should ==
56
+ root_node(if_node("true", static_node("Dan"), static_node("Rob")))
57
+
58
+ compile("hey <% if true %>Dan<% else %>Rob<% end %>").should ==
59
+ root_node(static_node("hey "), if_node("true", static_node("Dan"), static_node("Rob")))
60
+
61
+ compile("<% if true %>Dan<% else %>Rob<% end %> hi").should ==
62
+ root_node(if_node("true", static_node("Dan"), static_node("Rob")), static_node(" hi"))
63
+
64
+ compile(%(<% if true %>a<% else %>b<% end %>c<%= foo %>)).should ==
65
+ root_node(if_node("true", static_node("a"), static_node("b")), static_node("c"), variable_node("foo"))
66
+ end
67
+
68
+ it "should compile an if-elsif-else statement" do
69
+ compile("hey <% if true %>Dan<% elsif a %>Jim<% else %>Rob<% end %>").should ==
70
+ root_node(static_node("hey "), if_node("true", static_node("Dan"), if_node("a", static_node("Jim"), static_node("Rob"))))
71
+
72
+ compile(%(<% if true %>a<% elsif false %>b<% else %>c<% end %>d<%= foo %>)).should ==
73
+ root_node(if_node("true", static_node("a"), if_node("false", static_node("b"), static_node("c"))), static_node("d"), variable_node("foo"))
74
+ end
75
+
76
+ describe "not removing whitespace" do
77
+
78
+ it "should not lose newlines after one-line if-statement" do
79
+ compile(%(a <% if true %> b <% end %> c )).should ==
80
+ root_node(static_node("a "), if_node("true", static_node(" b ")), static_node(" c "))
81
+ end
82
+
83
+ it "should not lose newlines after one-line if-statement" do
84
+ compile(%(a\n<% if true %>b<% end %>c)).should ==
85
+ root_node(static_node("a\n"), if_node("true", static_node("b")), static_node("c"))
86
+ end
87
+
88
+ it "should not lose newlines after one-line if-statement" do
89
+ compile(%(a<% if true %>\nb<% end %>c)).should ==
90
+ root_node(static_node("a"), if_node("true", static_node("\nb")), static_node("c"))
91
+ end
92
+
93
+ it "should not lose newlines after one-line if-statement" do
94
+ compile(%(a<% if true %>b\n<% end %>c)).should ==
95
+ root_node(static_node("a"), if_node("true", static_node("b\n")), static_node("c"))
96
+ end
97
+
98
+ it "should not lose newlines after one-line if-statement" do
99
+ compile(%(a<% if true %>b<% end %>\nc)).should ==
100
+ root_node(static_node("a"), if_node("true", static_node("b")), static_node("\nc"))
101
+ end
102
+
103
+ it "should not lose newlines after one-line if-statement" do
104
+ compile(%(a<% if true %>b<% end %>c\n)).should ==
105
+ root_node(static_node("a"), if_node("true", static_node("b")), static_node("c\n"))
106
+ end
107
+
108
+ it "should not lose newlines after one-line if-statement" do
109
+ compile(%(a<% if true %>\nb\n<% end %>c)).should ==
110
+ root_node(static_node("a"), if_node("true", static_node("\nb\n")), static_node("c"))
111
+ end
112
+
113
+ it "should not remove whitespace inside the block" do
114
+ compile(%(a<% if true %>\n b \n<% end %>c)).should ==
115
+ root_node(static_node("a"), if_node("true", static_node("\n b \n")), static_node("c"))
116
+ end
117
+
118
+ it "should not remove trailing spaces after the block" do
119
+ compile(%(a\n<% if true %> \nb\n<% end %> \nc)).should ==
120
+ root_node(static_node("a\n"), if_node("true", static_node("b\n")), static_node("c"))
121
+ end
122
+
123
+ it "should not remove whitespace when there's content after the newline" do
124
+ compile(%(\n foo <% if true %>\nbar\n <% end %>\n)).should ==
125
+ root_node(static_node("\n foo "), if_node("true", static_node("\nbar\n")))
126
+ end
127
+
128
+ end
129
+
130
+ describe "removing whitespace" do
131
+
132
+ it "should remove whitespace if statement is on its own line" do
133
+ compile(%(a\n<% if true %>\nb\n<% end %>\nc)).should ==
134
+ root_node(static_node("a\n"), if_node("true", static_node("b\n")), static_node("c"))
135
+ end
136
+
137
+ it "should remove prepended spaces on the empty line too" do
138
+ compile(%(a\n <% if true %>\nb\n <% end %>\nc)).should ==
139
+ root_node(static_node("a\n"), if_node("true", static_node("b\n")), static_node("c"))
140
+ end
141
+
142
+ it "should remove prepended tabs on the empty line too" do
143
+ compile(%(a\n\t\t<% if true %>\nb\n\t\t<% end %>\nc)).should ==
144
+ root_node(static_node("a\n"), if_node("true", static_node("b\n")), static_node("c"))
145
+ end
146
+
147
+ it "should not remove trailing tabs on the empty line too" do
148
+ compile(%(a\n<% if true %>\t\t\nb\n<% end %>\t\t\nc)).should ==
149
+ root_node(static_node("a\n"), if_node("true", static_node("b\n")), static_node("c"))
150
+ end
151
+
152
+ it "should know '-%>' but not do anything different" do
153
+ compile(%(a\n<%- if true -%>\nb\n<%- end -%>\nc)).should ==
154
+ root_node(static_node("a\n"), if_node("true", static_node("b\n")), static_node("c"))
155
+ end
156
+
157
+ it "should remove newline when block is the first thing in the file" do
158
+ compile(%( <% if true %>\nbar<% end %>c)).should ==
159
+ root_node(if_node("true", static_node("bar")), static_node("c"))
160
+ end
161
+
162
+ it "should maintain correct whitespace with two if statements side-by-side" do
163
+ compile(%(a\n<% if true %>\n b\n<% end %>\n<% if true %>\n c\n<% end %>\nd\n)).should ==
164
+ root_node(static_node("a\n"), if_node("true", static_node(" b\n")), if_node("true", static_node(" c\n")), static_node("d\n"))
165
+ end
166
+
167
+ end
168
+
169
+ describe "<%%" do
170
+
171
+ it "should work when it's alone" do
172
+ compile("<%% foo %>").should == root_node(static_node("<% foo %>"))
173
+ end
174
+
175
+ it "should work surrounded by other static text" do
176
+ # this could be done better, but oh well
177
+ compile("a<%% foo %>b").should == root_node(static_node("a<% foo %>b"))
178
+ end
179
+
180
+ it "should work with new lines inside it" do
181
+ compile(%(<%%\n code\n %>\n a)).should ==
182
+ root_node(static_node("<%\n code\n %>\n a"))
183
+ end
184
+
185
+ end
186
+
187
+ end