rapid-core 0.1 → 0.2.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 (89) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile.lock +35 -2
  3. data/Rakefile +77 -48
  4. data/doc/server.txt +15 -0
  5. data/features/settings/double-nested/default.feature +2 -2
  6. data/features/settings/double-nested/validates/presence_of.feature +1 -1
  7. data/features/settings/nested/default.feature +1 -1
  8. data/features/settings/nested/validates/presence_of.feature +1 -1
  9. data/features/settings/not_found.feature +2 -2
  10. data/features/step_definitions/settings_steps.rb +7 -3
  11. data/features/step_definitions/template_steps.rb +3 -1
  12. data/lib/rapid/check.rb +30 -23
  13. data/lib/rapid/core.rb +12 -0
  14. data/lib/rapid/error.rb +1 -0
  15. data/lib/rapid/module.rb +10 -1
  16. data/lib/rapid/railtie.rb +6 -0
  17. data/lib/rapid/setting/base.rb +31 -8
  18. data/lib/rapid/setting/boolean_setting.rb +20 -1
  19. data/lib/rapid/setting/definer.rb +11 -47
  20. data/lib/rapid/setting/integer_setting.rb +7 -7
  21. data/lib/rapid/setting/module.rb +56 -0
  22. data/lib/rapid/setting/namespace/base.rb +35 -60
  23. data/lib/rapid/setting/namespace/instance.rb +195 -28
  24. data/lib/rapid/setting/string_setting.rb +7 -1
  25. data/lib/rapid/settings.rb +51 -65
  26. data/lib/rapid/skeleton/base.rb +39 -18
  27. data/lib/rapid/skeleton/helpers/directory.rb +5 -6
  28. data/lib/rapid/skeleton/helpers/files.rb +62 -0
  29. data/lib/rapid/skeleton/helpers/gem.rb +43 -32
  30. data/lib/rapid/skeleton/helpers/if_setting.rb +44 -0
  31. data/lib/rapid/skeleton/helpers/migration.rb +102 -32
  32. data/lib/rapid/skeleton/helpers/route.rb +8 -12
  33. data/lib/rapid/skeleton/helpers/script.rb +1 -2
  34. data/lib/rapid/skeleton/helpers/template.rb +23 -25
  35. data/lib/rapid/skeleton/helpers/view.rb +7 -7
  36. data/lib/rapid/spec/template.rb +1 -1
  37. data/lib/rapid/version.rb +1 -1
  38. data/lib/rapid/web/base.rb +35 -0
  39. data/lib/rapid/web/bootstrap.rb +98 -0
  40. data/lib/rapid/web/controller_helpers.rb +60 -0
  41. data/lib/rapid/web/navigator.rb +18 -0
  42. data/lib/rapid/web/select_helpers.rb +63 -0
  43. data/lib/rapid/web/settings_form_builder.rb +205 -0
  44. data/lib/rapid/web/static_helpers.rb +28 -0
  45. data/lib/rapid/web/tasks.rb +10 -0
  46. data/public/rapid/core/bootstrap-collapse.js +136 -0
  47. data/public/rapid/core/bootstrap-responsive.min.css +3 -0
  48. data/public/rapid/core/bootstrap.min.css +556 -0
  49. data/public/rapid/core/jquery-1.7.1.js +9253 -0
  50. data/public/rapid/core/prettify.css +30 -0
  51. data/public/rapid/core/prettify.js +28 -0
  52. data/rapid-core.gemspec +5 -0
  53. data/spec/rapid/check_spec.rb +11 -4
  54. data/spec/rapid/module_spec.rb +18 -0
  55. data/spec/rapid/setting/base_spec.rb +71 -0
  56. data/spec/rapid/setting/boolean_setting_spec.rb +95 -0
  57. data/spec/rapid/setting/definer_spec.rb +7 -13
  58. data/spec/rapid/setting/integer_setting_spec.rb +49 -0
  59. data/spec/rapid/setting/module_spec.rb +25 -0
  60. data/spec/rapid/setting/namespace/base_spec.rb +88 -54
  61. data/spec/rapid/setting/namespace/instance_spec.rb +308 -5
  62. data/spec/rapid/setting/string_setting_spec.rb +43 -0
  63. data/spec/rapid/settings_spec.rb +65 -17
  64. data/spec/rapid/skeleton/base_spec.rb +113 -7
  65. data/spec/rapid/skeleton/helpers/directory_spec.rb +8 -6
  66. data/spec/rapid/skeleton/helpers/files_spec.rb +93 -0
  67. data/spec/rapid/skeleton/helpers/gem_spec.rb +65 -36
  68. data/spec/rapid/skeleton/helpers/if_setting_spec.rb +110 -0
  69. data/spec/rapid/skeleton/helpers/migration_spec.rb +190 -1
  70. data/spec/rapid/skeleton/helpers/route_spec.rb +13 -12
  71. data/spec/rapid/skeleton/helpers/script_spec.rb +2 -1
  72. data/spec/rapid/skeleton/helpers/template_spec.rb +22 -35
  73. data/spec/rapid/spec/template_spec.rb +1 -1
  74. data/spec/rapid/web/base_spec.rb +33 -0
  75. data/spec/rapid/web/bootstrap_spec.rb +72 -0
  76. data/spec/rapid/web/controller_helpers_spec.rb +86 -0
  77. data/spec/rapid/web/navigator_spec.rb +17 -0
  78. data/spec/rapid/web/select_helpers_spec.rb +71 -0
  79. data/spec/rapid/web/settings_form_builder_spec.rb +255 -0
  80. data/spec/rapid/web/static_helpers_spec.rb +26 -0
  81. data/spec/spec_helper.rb +3 -0
  82. data/views/index.erb +11 -0
  83. data/views/layout.erb +9 -0
  84. metadata +107 -12
  85. data/lib/rapid.rb +0 -37
  86. data/lib/rapid/setting/class_hash.rb +0 -34
  87. data/lib/rapid/setting/instance_hash.rb +0 -132
  88. data/lib/rapid/setting/instance_root.rb +0 -107
  89. data/spec/rapid/setting/instance_root_spec.rb +0 -161
@@ -2,11 +2,314 @@ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
2
 
3
3
  describe Rapid::Setting::Namespace::Instance do
4
4
 
5
- it "should alias root as _root by default" do
6
- obj = mock(:default_empty => true, :scalars => [])
7
- @instance = Rapid::Setting::Namespace::Instance.new "hi", obj
8
- @instance.root.should == "hi"
9
- @instance._root.should == "hi"
5
+ def root_instance value = {}
6
+ @namespace = Rapid::Setting::Namespace::Base.new(nil)
7
+ @parent = nil
8
+ @instance = Rapid::Setting::Namespace::Instance.new @namespace, @parent, value
9
+ end
10
+
11
+ def child_instance name, value = {}
12
+ @namespace = Rapid::Setting::Namespace::Base.new(nil)
13
+ @child = Rapid::Setting::StringSetting.new(name, :namespace => @namespace)
14
+
15
+ @parent = nil
16
+
17
+ @instance = Rapid::Setting::Namespace::Instance.new @namespace, @parent, value
18
+ end
19
+
20
+ def grandchild_instance name1, name2, value = {}
21
+ @namespace = Rapid::Setting::Namespace::Base.new(nil)
22
+ @child = Rapid::Setting::Namespace::Base.new(name1, :namespace => @namespace)
23
+ @grandchild = Rapid::Setting::StringSetting.new(name2, :namespace => @child)
24
+
25
+ @parent = nil
26
+
27
+ @instance = Rapid::Setting::Namespace::Instance.new @namespace, @parent, value
28
+ end
29
+
30
+ it "should know on? and empty" do
31
+ @instance = root_instance
32
+
33
+ @instance.on?.should be_true
34
+ @instance.on.should be_true
35
+ @instance.empty?.should be_true
36
+ end
37
+
38
+ it "should accept on=" do
39
+ @instance = root_instance
40
+
41
+ @instance.on?.should == true
42
+ @instance.on = nil
43
+ @instance.on?.should == false
44
+ end
45
+
46
+ it "should turn on when a child setting is set" do
47
+ @instance = grandchild_instance 'foo', 'bar'
48
+ @instance['foo'].on?.should == false
49
+
50
+ @instance['foo.bar'] = 'hi'
51
+
52
+ @instance['foo'].on?.should == true
53
+ end
54
+
55
+ it "should expose namespaces and scalars" do
56
+ @instance = child_instance 'foo'
57
+ @instance['foo'] = "hi"
58
+
59
+ @instance.namespaces.should == []
60
+ @instance.scalars.should == ["hi"]
61
+ end
62
+
63
+ it "should know its parent" do
64
+ @instance = child_instance 'foo'
65
+ @instance.send(:_parent).should == nil
66
+ end
67
+
68
+ describe "[]" do
69
+
70
+ it "should not find child if the setting does not exist" do
71
+ @instance = root_instance 'foo' => 'bar'
72
+ @instance['foo'].should == nil
73
+ end
74
+
75
+ it "should try a manually implemented method if the setting does not exist" do
76
+ @instance = root_instance 'freeze' => 'hi'
77
+ @instance.freeze.should == @instance
78
+ @instance['freeze'].should == @instance
79
+ end
80
+
81
+ it "should not find the grandchild if the setting does not exist" do
82
+ @instance = root_instance 'foo' => {'bar' => 'nuts'}
83
+ @instance['foo.bar'].should == nil
84
+ end
85
+
86
+ it "should get the setting when it exists even if there's an implemented method" do
87
+ @instance = child_instance 'freeze', 'freeze' => 'hi'
88
+ @instance['freeze'].should == 'hi'
89
+ end
90
+
91
+ it "should find child" do
92
+ @instance = child_instance 'foo', 'foo' => 'bar'
93
+ @instance['foo'].should == 'bar'
94
+ end
95
+
96
+ it "should find the grandchild if the settings exist" do
97
+ @instance = grandchild_instance 'foo', 'bar', 'foo' => {'bar' => 'nuts'}
98
+ @instance['foo.bar'].should == 'nuts'
99
+ end
100
+
101
+ it "should not find a value that's not there" do
102
+ @instance = root_instance
103
+ @instance['foo.bar'].should == nil
104
+ @instance['foo'].should == nil
105
+ end
106
+
107
+ end
108
+
109
+ describe "[]=" do
110
+
111
+ describe "child settings" do
112
+
113
+ it "should set the setting" do
114
+ @instance = child_instance 'foo'
115
+ @instance['foo'].should == nil
116
+ @instance['foo'] = 'bar'
117
+ @instance['foo'].should == 'bar'
118
+ end
119
+
120
+ it "should remember an assignment error when the setting does not exist" do
121
+ @instance = root_instance
122
+ @instance['foo'] = 'bar'
123
+ @instance.valid?.should be_false
124
+ @instance.errors['foo'].should == ["can't be found"]
125
+ end
126
+
127
+ it "should try a manually implemented method if the setting does not exist" do
128
+ @instance = root_instance
129
+ @instance['taguri'] = "5"
130
+ @instance.taguri.should == "5"
131
+ end
132
+
133
+ it "should not try the manually implemented method if the setting exists" do
134
+ @instance = child_instance 'taguri'
135
+ @instance.should_not_receive(:taguri=)
136
+
137
+ @instance['taguri'] = 'bar'
138
+ @instance['taguri'].should == 'bar'
139
+ end
140
+
141
+ it "should accept values for a child namespace" do
142
+ @instance = grandchild_instance 'foo', 'bar'
143
+ @instance['foo'] = {'bar' => 'hi'}
144
+ @instance['foo.bar'].should == 'hi'
145
+ end
146
+
147
+ end
148
+
149
+ describe "child namespaces" do
150
+
151
+ it "should set a child namespace" do
152
+ @instance = grandchild_instance 'foo', 'bar'
153
+ @instance['foo.bar'] = 'nuts'
154
+ @instance.valid?.should == true
155
+ @instance.errors['foo.bar'].should == []
156
+ end
157
+
158
+ it "should recognize a bad value for a child namespace" do
159
+ @instance = child_instance 'foo'
160
+ @instance['foo.bar'] = 'nuts'
161
+ @instance.valid?.should == false
162
+ @instance.errors['foo.bar'].should == ["doesn't allow values of that type"]
163
+ end
164
+
165
+ it "should recognize an non-existing child namespace" do
166
+ @instance = root_instance
167
+ @instance['foo.bar'] = 'hi'
168
+ @instance.valid?.should == false
169
+ @instance.errors['foo.bar'].should == ["can't be found"]
170
+ end
171
+
172
+ it "should reload a child namespace without overriding existing values" do
173
+ @namespace = Rapid::Setting::Namespace::Base.new(nil)
174
+ @child = Rapid::Setting::Namespace::Base.new('foo', :namespace => @namespace)
175
+ @grandchild = Rapid::Setting::Namespace::Base.new('bar', :namespace => @child)
176
+ @string = Rapid::Setting::StringSetting.new('nuts', :namespace => @grandchild)
177
+ @string = Rapid::Setting::StringSetting.new('squirrel', :namespace => @grandchild)
178
+
179
+ @parent = nil
180
+
181
+ @instance = Rapid::Setting::Namespace::Instance.new @namespace, @parent, {}
182
+
183
+ @instance['foo.bar.nuts'].should == nil
184
+ @instance['foo.bar.squirrel'].should == nil
185
+
186
+ @instance['foo.bar.nuts'] = 'hi'
187
+ @instance['foo.bar.squirrel'] = 'Alvin'
188
+
189
+ @instance['foo.bar.nuts'].should == 'hi'
190
+ @instance['foo.bar.squirrel'].should == 'Alvin'
191
+
192
+ @instance['foo'] = {'bar' => {'nuts' => 'hey'}}
193
+
194
+ @instance['foo.bar.nuts'].should == 'hey'
195
+ @instance['foo.bar.squirrel'].should == 'Alvin'
196
+ end
197
+
198
+ end
199
+
200
+ end
201
+
202
+ describe "values" do
203
+
204
+ before do
205
+ @namespace = Rapid::Setting::Namespace::Base.new(nil)
206
+ @parent = nil
207
+ end
208
+
209
+ def load value
210
+ @instance = Rapid::Setting::Namespace::Instance.new @namespace, @parent, value
211
+ end
212
+
213
+ it "should accept false" do
214
+ load false
215
+
216
+ @instance.on?.should == false
217
+ @instance.empty?.should == true
218
+ end
219
+
220
+ it "should accept nil" do
221
+ load nil
222
+
223
+ @instance.on?.should == false
224
+ @instance.empty?.should == true
225
+ end
226
+
227
+ it "should accept true" do
228
+ load true
229
+
230
+ @instance.on?.should == true
231
+ @instance.empty?.should == true
232
+ end
233
+
234
+ it "should accept {}" do
235
+ load({})
236
+
237
+ @instance.on?.should == true
238
+ @instance.empty?.should == true
239
+ end
240
+
241
+ it "should accept {...}" do
242
+ load :foo => 'hi'
243
+
244
+ @instance.on?.should == true
245
+ @instance.empty?.should == false
246
+ end
247
+
248
+ it "should not accept integers" do
249
+ lambda { load(3) }.should raise_error(Rapid::InvalidSettingError)
250
+ end
251
+
252
+ it "should not accept []" do
253
+ lambda { load([]) }.should raise_error(Rapid::InvalidSettingError)
254
+ end
255
+
256
+ end
257
+
258
+ describe "defaults" do
259
+
260
+ def child_instance name, value = {}
261
+ @namespace = Rapid::Setting::Namespace::Base.new(nil)
262
+ @child = Rapid::Setting::StringSetting.new(name, :namespace => @namespace, :default => 'hi')
263
+
264
+ @parent = nil
265
+
266
+ @instance = Rapid::Setting::Namespace::Instance.new @namespace, @parent, value
267
+ end
268
+
269
+ it "should use setting defaults" do
270
+ @instance = child_instance 'foo'
271
+ @instance['foo'].should == 'hi'
272
+ end
273
+
274
+ end
275
+
276
+ describe "to_hash" do
277
+
278
+ it "should drop blank namespaces" do
279
+ @instance = grandchild_instance 'foo', 'bar'
280
+ @instance.to_hash.should == {}
281
+
282
+ @instance = grandchild_instance 'foo', 'bar', 'foo' => {}
283
+ @instance.to_hash.should == {}
284
+ end
285
+
286
+ it "should not drop namespaces with values" do
287
+ @instance = grandchild_instance 'foo', 'bar', 'foo' => {'bar' => 'hi'}
288
+ @instance.to_hash.should == {'foo' => {'bar' => 'hi'}}
289
+ end
290
+
291
+ end
292
+
293
+ describe "set?" do
294
+
295
+ it "should be true when child setting is set" do
296
+ @instance = child_instance 'foo'
297
+
298
+ @instance.set?('foo').should == false
299
+ @instance['foo'] = 'hi'
300
+ @instance.set?('foo').should == true
301
+ end
302
+
303
+ it "should be true when grandchild setting is set" do
304
+ @instance = grandchild_instance 'foo', 'bar'
305
+
306
+ @instance.set?('foo.bar').should == false
307
+ @instance.set?('foo').should == false
308
+ @instance['foo.bar'] = 'hi'
309
+ @instance.set?('foo.bar').should == true
310
+ @instance.set?('foo').should == true
311
+ end
312
+
10
313
  end
11
314
 
12
315
  end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Rapid::Setting::StringSetting do
4
+
5
+ describe "load" do
6
+
7
+ before do
8
+ @setting = Rapid::Setting::StringSetting.new("foo")
9
+ end
10
+
11
+ it "should know nil is nil" do
12
+ @setting.load(nil).should == nil
13
+ end
14
+
15
+ it "should know false as nil" do
16
+ @setting.load(false).should == nil
17
+ end
18
+
19
+ it "should know strings" do
20
+ @setting.load("hi").should == "hi"
21
+ @setting.load("false").should == "false"
22
+ @setting.load(true).should == "true"
23
+ end
24
+
25
+ it "should know integers" do
26
+ @setting.load(3).should == "3"
27
+ end
28
+
29
+ it "should know floats" do
30
+ @setting.load(3.5).should == "3.5"
31
+ end
32
+
33
+ it "should not know arrays" do
34
+ lambda { @setting.load([]) }.should raise_error(Rapid::InvalidSettingError)
35
+ end
36
+
37
+ it "should not know hashes" do
38
+ lambda { @setting.load({}) }.should raise_error(Rapid::InvalidSettingError)
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -8,6 +8,7 @@ describe Rapid::Settings do
8
8
  include Rapid::Settings
9
9
 
10
10
  setting.string 'foo'
11
+ attr_accessor :nuts
11
12
  end
12
13
  end
13
14
 
@@ -18,34 +19,81 @@ describe Rapid::Settings do
18
19
  Object.send(:remove_const, :MyClass) rescue nil
19
20
  end
20
21
 
21
- describe "extract_nested_namespace" do
22
+ it "should expose the setting's bindings by default" do
23
+ @instance.get_binding.should_not be_nil
24
+ end
25
+
26
+ describe "class settings" do
22
27
 
23
- it "should return the namespace and rest" do
24
- Rapid::Settings.extract_nested_namespace("foo.bar").should == ["foo", "bar"]
28
+ it "should expose the class settings" do
29
+ MyClass.settings['foo'].class.should == Rapid::Setting::StringSetting
25
30
  end
26
31
 
27
- it "should return nil and original when not namespaced" do
28
- Rapid::Settings.extract_nested_namespace("foo").should == [nil, "foo"]
32
+ end
33
+
34
+ describe "array-like properties" do
35
+
36
+ it "should work with settings" do
37
+ @instance['foo'] = 'hi'
38
+ @instance['foo'].should == 'hi'
39
+ @instance.foo.should == 'hi'
29
40
  end
30
41
 
31
- it "should handle nil" do
32
- Rapid::Settings.extract_nested_namespace(nil).should == [nil, nil]
42
+ it "should handle accessors" do
43
+ @instance['nuts'] = 5
44
+ @instance['nuts'].should == 5
33
45
  end
34
46
 
35
- it "should handle a symbol" do
36
- Rapid::Settings.extract_nested_namespace(:foo).should == [nil, 'foo']
47
+ it "should not break when accessing unknown settings" do
48
+ @instance['boo.foo'].should == nil
49
+ end
50
+
51
+ it "should not be valid after assigning an invalid setting" do
52
+ @instance.valid?.should be_true
53
+
54
+ @instance['bar'] = 4
55
+
56
+ @instance['bar'].should == nil
57
+ @instance.valid?.should be_false
58
+ @instance.errors['bar'].should == ["can't be found"]
59
+ end
60
+
61
+ it "should not be valid after assigning an invalid child setting" do
62
+ @instance.valid?.should be_true
63
+
64
+ @instance['nuts.squirrel'] = 'hi'
65
+
66
+ @instance.valid?.should be_false
67
+ @instance.errors['nuts.squirrel'].should == ["can't be found"]
68
+ end
69
+
70
+ it "should not be valid after assigning an invalid value to an existing setting" do
71
+ @instance['foo.bar'] = 4
72
+ @instance.valid?.should be_false
73
+ @instance.errors['foo.bar'].should == ["doesn't allow values of that type"]
37
74
  end
38
75
 
39
76
  end
40
77
 
41
- it "should expose the setting's bindings by default" do
42
- @instance.get_binding.should_not be_nil
43
- end
44
-
45
- it "should provide array-like access" do
46
- @instance['foo'] = 'hi'
47
- @instance['foo'].should == 'hi'
48
- @instance.foo.should == 'hi'
78
+ describe "nested validations" do
79
+
80
+ before do
81
+ @definer = MyClass.send(:setting)
82
+ end
83
+
84
+ it "should validate presence if a child setting is present" do
85
+ @definer.integer "app.emails.smtp.port"
86
+ @definer.string "app.name"
87
+
88
+ MyClass.validates_presence_of "app.emails.smtp.port", :if => '_root.app.name'
89
+
90
+ MyClass.new.valid?.should == true
91
+ @instance = MyClass.new
92
+ @instance.settings = {'app.name' => 'hi'}
93
+ @instance.valid?.should == false
94
+ @instance.errors['app.emails.smtp.port'].should == ["can't be blank"]
95
+ end
96
+
49
97
  end
50
98
 
51
99
  end