make_resourceful 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/Rakefile +31 -0
  2. data/Readme.rdoc +229 -0
  3. data/VERSION +1 -0
  4. data/lib/make_resourceful.rb +11 -0
  5. data/lib/resourceful/base.rb +63 -0
  6. data/lib/resourceful/builder.rb +405 -0
  7. data/lib/resourceful/default/accessors.rb +418 -0
  8. data/lib/resourceful/default/actions.rb +101 -0
  9. data/lib/resourceful/default/callbacks.rb +51 -0
  10. data/lib/resourceful/default/responses.rb +118 -0
  11. data/lib/resourceful/default/urls.rb +136 -0
  12. data/lib/resourceful/generators/resourceful_scaffold/resourceful_scaffold_generator.rb +87 -0
  13. data/lib/resourceful/generators/resourceful_scaffold/templates/controller.rb +5 -0
  14. data/lib/resourceful/generators/resourceful_scaffold/templates/fixtures.yml +10 -0
  15. data/lib/resourceful/generators/resourceful_scaffold/templates/functional_test.rb +50 -0
  16. data/lib/resourceful/generators/resourceful_scaffold/templates/helper.rb +2 -0
  17. data/lib/resourceful/generators/resourceful_scaffold/templates/migration.rb +13 -0
  18. data/lib/resourceful/generators/resourceful_scaffold/templates/model.rb +2 -0
  19. data/lib/resourceful/generators/resourceful_scaffold/templates/unit_test.rb +7 -0
  20. data/lib/resourceful/generators/resourceful_scaffold/templates/view__form.haml +5 -0
  21. data/lib/resourceful/generators/resourceful_scaffold/templates/view_edit.haml +11 -0
  22. data/lib/resourceful/generators/resourceful_scaffold/templates/view_index.haml +5 -0
  23. data/lib/resourceful/generators/resourceful_scaffold/templates/view_new.haml +9 -0
  24. data/lib/resourceful/generators/resourceful_scaffold/templates/view_partial.haml +12 -0
  25. data/lib/resourceful/generators/resourceful_scaffold/templates/view_show.haml +14 -0
  26. data/lib/resourceful/maker.rb +92 -0
  27. data/lib/resourceful/response.rb +33 -0
  28. data/lib/resourceful/serialize.rb +185 -0
  29. data/spec/accessors_spec.rb +474 -0
  30. data/spec/actions_spec.rb +310 -0
  31. data/spec/base_spec.rb +12 -0
  32. data/spec/builder_spec.rb +332 -0
  33. data/spec/callbacks_spec.rb +71 -0
  34. data/spec/integration_spec.rb +394 -0
  35. data/spec/maker_spec.rb +91 -0
  36. data/spec/response_spec.rb +37 -0
  37. data/spec/responses_spec.rb +314 -0
  38. data/spec/serialize_spec.rb +133 -0
  39. data/spec/urls_spec.rb +282 -0
  40. metadata +97 -0
@@ -0,0 +1,314 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe 'Resourceful::Default::Responses', " with a _flash parameter for :error" do
4
+ include ControllerMocks
5
+ before :each do
6
+ mock_controller Resourceful::Default::Responses
7
+ @flash = {}
8
+ @controller.stubs(:flash).returns(@flash)
9
+ @params = {:_flash => {:error => 'Oh no, an error!'}}
10
+ @controller.stubs(:params).returns(@params)
11
+ end
12
+
13
+ it "should set the flash for :error to the parameter's value when set_default_flash is called on :error" do
14
+ @controller.set_default_flash(:error, "Aw there's no error!")
15
+ @flash[:error].should == 'Oh no, an error!'
16
+ end
17
+
18
+ it "should set the flash for :message to the default value when set_default_flash is called on :message" do
19
+ @controller.set_default_flash(:message, "All jim dandy!")
20
+ @flash[:message].should == 'All jim dandy!'
21
+ end
22
+
23
+ it "shouldn't set the flash for :error when set_default_flash is called on :message" do
24
+ @controller.set_default_flash(:message, "All jim dandy!")
25
+ @flash[:error].should be_nil
26
+ end
27
+ end
28
+
29
+ describe 'Resourceful::Default::Responses', " with a _redirect parameter on :failure" do
30
+ include ControllerMocks
31
+ before :each do
32
+ mock_controller Resourceful::Default::Responses
33
+ @params = {:_redirect_on => {:failure => 'http://hamptoncatlin.com/'}}
34
+ @controller.stubs(:params).returns(@params)
35
+ end
36
+
37
+ it "should set the redirect for :failure to the parameter's value when set_default_redirect is called on :failure" do
38
+ @controller.expects(:redirect_to).with('http://hamptoncatlin.com/')
39
+ @controller.set_default_redirect(:back, :status => :failure)
40
+ end
41
+
42
+ it "should set the redirect for :success to the default value when set_default_redirect is called on :success" do
43
+ @controller.expects(:redirect_to).with(:back)
44
+ @controller.set_default_redirect(:back, :status => :success)
45
+ end
46
+
47
+ it "shouldn't set the redirect for :failure when set_default_redirect is called on :success" do
48
+ @controller.expects(:redirect_to).with(:back)
49
+ @controller.expects(:redirect_to).with('http://hamptoncatlin.com/').never
50
+ @controller.set_default_redirect(:back, :status => :success)
51
+ end
52
+
53
+ it "should set the default redirect for :success by default" do
54
+ @controller.expects(:redirect_to).with(:back)
55
+ @controller.set_default_redirect(:back)
56
+ end
57
+ end
58
+
59
+ describe 'Resourceful::Default::Responses', ' for show' do
60
+ include ControllerMocks
61
+ before :each do
62
+ mock_kontroller
63
+ create_builder
64
+ made_resourceful(Resourceful::Default::Responses)
65
+ @builder.apply
66
+ end
67
+
68
+ it "should have an empty HTML response" do
69
+ responses[:show].find { |f, p| f == :html }[1].call.should == nil
70
+ end
71
+
72
+ it "should have an empty JS response" do
73
+ responses[:show].find { |f, p| f == :js }[1].call.should == nil
74
+ end
75
+ end
76
+
77
+ describe 'Resourceful::Default::Responses', ' for index' do
78
+ include ControllerMocks
79
+ before :each do
80
+ mock_kontroller
81
+ create_builder
82
+ made_resourceful(Resourceful::Default::Responses)
83
+ @builder.apply
84
+ end
85
+
86
+ it "should have an empty HTML response" do
87
+ responses[:index].find { |f, p| f == :html }[1].call.should == nil
88
+ end
89
+
90
+ it "should have an empty JS response" do
91
+ responses[:index].find { |f, p| f == :js }[1].call.should == nil
92
+ end
93
+ end
94
+
95
+ describe 'Resourceful::Default::Responses', ' for edit' do
96
+ include ControllerMocks
97
+ before :each do
98
+ mock_kontroller
99
+ create_builder
100
+ made_resourceful(Resourceful::Default::Responses)
101
+ @builder.apply
102
+ end
103
+
104
+ it "should have an empty HTML response" do
105
+ responses[:edit].find { |f, p| f == :html }[1].call.should == nil
106
+ end
107
+
108
+ it "should have an empty JS response" do
109
+ responses[:edit].find { |f, p| f == :js }[1].call.should == nil
110
+ end
111
+ end
112
+
113
+ describe 'Resourceful::Default::Responses', ' for new' do
114
+ include ControllerMocks
115
+ before :each do
116
+ mock_kontroller
117
+ create_builder
118
+ made_resourceful(Resourceful::Default::Responses)
119
+ @builder.apply
120
+ end
121
+
122
+ it "should have an empty HTML response" do
123
+ responses[:new].find { |f, p| f == :html }[1].call.should == nil
124
+ end
125
+
126
+ it "should have an empty JS response" do
127
+ responses[:new].find { |f, p| f == :js }[1].call.should == nil
128
+ end
129
+ end
130
+
131
+ describe 'Resourceful::Default::Responses', ' for show_fails' do
132
+ include ControllerMocks
133
+ before :each do
134
+ mock_controller Resourceful::Default::Callbacks
135
+ create_builder
136
+ made_resourceful(Resourceful::Default::Responses)
137
+ @builder.apply
138
+ end
139
+
140
+ it "should give a 404 error for HTML" do
141
+ @controller.expects(:render).with(:text => "No item found", :status => 404)
142
+ @controller.scope(responses[:show_fails].find { |f, p| f == :html }[1]).call
143
+ end
144
+
145
+ it "should give a 404 error for JS" do
146
+ @controller.expects(:render).with(:text => "No item found", :status => 404)
147
+ @controller.scope(responses[:show_fails].find { |f, p| f == :js }[1]).call
148
+ end
149
+
150
+ it "should give a 404 error for XML" do
151
+ @controller.expects(:render).with(:text => "No item found", :status => 404)
152
+ @controller.scope(responses[:show_fails].find { |f, p| f == :xml }[1]).call
153
+ end
154
+ end
155
+
156
+ describe 'Resourceful::Default::Responses', ' for create' do
157
+ include ControllerMocks
158
+ before :each do
159
+ mock_controller Resourceful::Default::Callbacks
160
+ create_builder
161
+ made_resourceful(Resourceful::Default::Responses)
162
+ @builder.apply
163
+
164
+ [:set_default_flash, :set_default_redirect, :object_path].each(&@controller.method(:stubs))
165
+ end
166
+
167
+ it "should have an empty JS response" do
168
+ responses[:create].find { |f, p| f == :js }[1].call.should == nil
169
+ end
170
+
171
+ it "should flash a success message to :notice by default for HTML" do
172
+ @controller.expects(:set_default_flash).with(:notice, "Create successful!")
173
+ @controller.scope(responses[:create].find { |f, p| f == :html }[1]).call
174
+ end
175
+
176
+ it "should redirect to object_path by default for HTML" do
177
+ @controller.stubs(:object_path).returns("/posts/12")
178
+ @controller.expects(:set_default_redirect).with("/posts/12")
179
+ @controller.scope(responses[:create].find { |f, p| f == :html }[1]).call
180
+ end
181
+ end
182
+
183
+ describe 'Resourceful::Default::Responses', ' for create_fails' do
184
+ include ControllerMocks
185
+ before :each do
186
+ mock_controller Resourceful::Default::Callbacks
187
+ create_builder
188
+ made_resourceful(Resourceful::Default::Responses)
189
+ @builder.apply
190
+
191
+ [:set_default_flash, :render].each(&@controller.method(:stubs))
192
+ end
193
+
194
+ it "should have an empty JS response" do
195
+ responses[:create_fails].find { |f, p| f == :js }[1].call.should == nil
196
+ end
197
+
198
+ it "should flash a failure message to :error by default for HTML" do
199
+ @controller.expects(:set_default_flash).with(:error, "There was a problem!")
200
+ @controller.scope(responses[:create_fails].find { |f, p| f == :html }[1]).call
201
+ end
202
+
203
+ it "should render new with a 422 error for HTML" do
204
+ @controller.expects(:render).with(:action => :new, :status => 422)
205
+ @controller.scope(responses[:create_fails].find { |f, p| f == :html }[1]).call
206
+ end
207
+ end
208
+
209
+ describe 'Resourceful::Default::Responses', ' for update' do
210
+ include ControllerMocks
211
+ before :each do
212
+ mock_controller Resourceful::Default::Callbacks
213
+ create_builder
214
+ made_resourceful(Resourceful::Default::Responses)
215
+ @builder.apply
216
+
217
+ [:set_default_flash, :set_default_redirect, :object_path].each(&@controller.method(:stubs))
218
+ end
219
+
220
+ it "should have an empty JS response" do
221
+ responses[:update].find { |f, p| f == :js }[1].call.should == nil
222
+ end
223
+
224
+ it "should flash a success message to :notice by default for HTML" do
225
+ @controller.expects(:set_default_flash).with(:notice, "Save successful!")
226
+ @controller.scope(responses[:update].find { |f, p| f == :html }[1]).call
227
+ end
228
+
229
+ it "should redirect to object_path by default for HTML" do
230
+ @controller.stubs(:object_path).returns("/posts/12")
231
+ @controller.expects(:set_default_redirect).with("/posts/12")
232
+ @controller.scope(responses[:update].find { |f, p| f == :html }[1]).call
233
+ end
234
+ end
235
+
236
+ describe 'Resourceful::Default::Responses', ' for update_fails' do
237
+ include ControllerMocks
238
+ before :each do
239
+ mock_controller Resourceful::Default::Callbacks
240
+ create_builder
241
+ made_resourceful(Resourceful::Default::Responses)
242
+ @builder.apply
243
+
244
+ [:set_default_flash, :render].each(&@controller.method(:stubs))
245
+ end
246
+
247
+ it "should have an empty JS response" do
248
+ responses[:update_fails].find { |f, p| f == :js }[1].call.should == nil
249
+ end
250
+
251
+ it "should flash a failure message to :error by default for HTML" do
252
+ @controller.expects(:set_default_flash).with(:error, "There was a problem saving!")
253
+ @controller.scope(responses[:update_fails].find { |f, p| f == :html }[1]).call
254
+ end
255
+
256
+ it "should render edit with a 422 error for HTML" do
257
+ @controller.expects(:render).with(:action => :edit, :status => 422)
258
+ @controller.scope(responses[:update_fails].find { |f, p| f == :html }[1]).call
259
+ end
260
+ end
261
+
262
+
263
+ describe 'Resourceful::Default::Responses', ' for destroy' do
264
+ include ControllerMocks
265
+ before :each do
266
+ mock_controller Resourceful::Default::Callbacks
267
+ create_builder
268
+ made_resourceful(Resourceful::Default::Responses)
269
+ @builder.apply
270
+
271
+ [:set_default_flash, :set_default_redirect, :objects_path].each(&@controller.method(:stubs))
272
+ end
273
+
274
+ it "should have an empty JS response" do
275
+ responses[:destroy].find { |f, p| f == :js }[1].call.should == nil
276
+ end
277
+
278
+ it "should flash a success message to :notice by default for HTML" do
279
+ @controller.expects(:set_default_flash).with(:notice, "Record deleted!")
280
+ @controller.scope(responses[:destroy].find { |f, p| f == :html }[1]).call
281
+ end
282
+
283
+ it "should redirect to objects_path by default for HTML" do
284
+ @controller.stubs(:objects_path).returns("/posts")
285
+ @controller.expects(:set_default_redirect).with("/posts")
286
+ @controller.scope(responses[:destroy].find { |f, p| f == :html }[1]).call
287
+ end
288
+ end
289
+
290
+ describe 'Resourceful::Default::Responses', ' for destroy_fails' do
291
+ include ControllerMocks
292
+ before :each do
293
+ mock_controller Resourceful::Default::Callbacks
294
+ create_builder
295
+ made_resourceful(Resourceful::Default::Responses)
296
+ @builder.apply
297
+
298
+ [:set_default_flash, :set_default_redirect, :render].each(&@controller.method(:stubs))
299
+ end
300
+
301
+ it "should have an empty JS response" do
302
+ responses[:destroy_fails].find { |f, p| f == :js }[1].call.should == nil
303
+ end
304
+
305
+ it "should flash a failure message to :error by default for HTML" do
306
+ @controller.expects(:set_default_flash).with(:error, "There was a problem deleting!")
307
+ @controller.scope(responses[:destroy_fails].find { |f, p| f == :html }[1]).call
308
+ end
309
+
310
+ it "should redirect back on failure by default for HTML" do
311
+ @controller.expects(:set_default_redirect).with(:back, :status => :failure)
312
+ @controller.scope(responses[:destroy_fails].find { |f, p| f == :html }[1]).call
313
+ end
314
+ end
@@ -0,0 +1,133 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Resourceful::Serialize, ".normalize_attributes" do
4
+ it "should return nil if given nil" do
5
+ Resourceful::Serialize.normalize_attributes(nil).should be_nil
6
+ end
7
+
8
+ it "should return a basic hash if given a non-injectable attribute" do
9
+ Resourceful::Serialize.normalize_attributes(:foo).should == {:foo => nil}
10
+ Resourceful::Serialize.normalize_attributes(12).should == {12 => nil}
11
+ end
12
+
13
+ it "should return a basic hash with a symbol key if given a string attribute" do
14
+ Resourceful::Serialize.normalize_attributes("foo").should == {:foo => nil}
15
+ end
16
+
17
+ it "should preserve hashes" do
18
+ Resourceful::Serialize.normalize_attributes({:foo => nil, :bar => nil, :baz => nil}).should ==
19
+ {:foo => nil, :bar => nil, :baz => nil}
20
+ Resourceful::Serialize.normalize_attributes({:foo => 3, :bar => 1, :baz => 4}).should ==
21
+ {:foo => 3, :bar => 1, :baz => 4}
22
+ Resourceful::Serialize.normalize_attributes({:foo => 3, :bar => 1, :baz => [:foo, :bar]}).should ==
23
+ {:foo => 3, :bar => 1, :baz => [:foo, :bar]}
24
+ end
25
+
26
+ it "should merge injectable attributes into one big hash" do
27
+ Resourceful::Serialize.normalize_attributes([:foo, :bar, :baz]).should ==
28
+ {:foo => nil, :bar => nil, :baz => nil}
29
+ Resourceful::Serialize.normalize_attributes([:foo, :bar, {:baz => nil},
30
+ :boom, {:bop => nil, :blat => nil}]).should ==
31
+ {:foo => nil, :bar => nil, :baz => nil, :boom => nil, :bop => nil, :blat => nil}
32
+ Resourceful::Serialize.normalize_attributes([:foo, :bar, {:baz => 12},
33
+ :boom, {:bop => "foo", :blat => [:fee, :fi, :fo]}]).should ==
34
+ {:foo => nil, :bar => nil, :baz => 12, :boom => nil, :bop => "foo", :blat => [:fee, :fi, :fo]}
35
+ end
36
+ end
37
+
38
+ describe Array, " of non-serializable objects" do
39
+ before :each do
40
+ @array = [1, 2, 3, 4, "foo"]
41
+ end
42
+
43
+ it "should return itself for #to_serializable" do
44
+ @array.to_serializable(nil).should == @array
45
+ end
46
+
47
+ it "should raise an error for #serialize" do
48
+ lambda { @array.serialize(:yaml, :attributes => [:foo]) }.should raise_error("Not all elements respond to to_serializable")
49
+ end
50
+ end
51
+
52
+ describe Array, " of serializable objects" do
53
+ before :each do
54
+ @cat = stub_model("Cat")
55
+ @dog = stub_model("Dog")
56
+ @array = %w{brown yellow green}.zip(%w{rex rover fido}).
57
+ map { |c, d| @cat.new(:fur => c, :friend => @dog.new(:name => d)) }
58
+ end
59
+
60
+ it "should return an array of serializable hashes for #to_serializable" do
61
+ @array.to_serializable([:fur]).should == [{'fur' => 'brown'}, {'fur' => 'yellow'}, {'fur' => 'green'}]
62
+ end
63
+
64
+ it "should follow deep attributes for #to_serializable" do
65
+ @array.to_serializable([:fur, {:friend => :name}]).should ==
66
+ [{'fur' => 'brown', 'friend' => {'name' => 'rex'}},
67
+ {'fur' => 'yellow', 'friend' => {'name' => 'rover'}},
68
+ {'fur' => 'green', 'friend' => {'name' => 'fido'}}]
69
+ end
70
+
71
+ it "should raise an error if #serialize is called without the :attributes option" do
72
+ lambda { @array.serialize(:yaml, {}) }.should raise_error("Must specify :attributes option")
73
+ end
74
+
75
+ it "should serialize to a hash with a pluralized root for #serialize" do
76
+ YAML.load(@array.serialize(:yaml, :attributes => [:fur, {:friend => :name}])).should ==
77
+ {"cats" => [{'fur' => 'brown', 'friend' => {'name' => 'rex'}},
78
+ {'fur' => 'yellow', 'friend' => {'name' => 'rover'}},
79
+ {'fur' => 'green', 'friend' => {'name' => 'fido'}}]}
80
+ end
81
+
82
+ it "should serialize to an XML document with a pluralized root for #serialize(:xml, ...)" do
83
+ doc = REXML::Document.new(@array.serialize(:xml, :attributes => [:fur, {:friend => :name}]),
84
+ :ignore_whitespace_nodes => :all)
85
+ doc.root.name.should == "cats"
86
+ cats = doc.get_elements('/cats/cat')
87
+ cats.size.should == 3
88
+ cats.zip(%w{brown yellow green}, %w{rex rover fido}) do |cat, fur, dog|
89
+ cat.children.find { |e| e.name == "fur" }.text.should == fur
90
+ cat.children.find { |e| e.name == "friend" }.children[0].text.should == dog
91
+ end
92
+ end
93
+ end
94
+
95
+ describe ActiveRecord::Base, " with a few attributes and an association" do
96
+ before :each do
97
+ @person = stub_model("Person")
98
+ @party_hat = stub_model("PartyHat")
99
+ @model = @person.new(:name => "joe", :eye_color => "blue", :hairs => 567,
100
+ :party_hat => @party_hat.new(:color => 'blue', :size => 12, :pattern => 'stripey'))
101
+ end
102
+
103
+ it "should raise an error if #to_serializable is called without attributes" do
104
+ lambda { @model.to_serializable(nil) }.should raise_error("Must specify attributes for #<Person>.to_serializable")
105
+ end
106
+
107
+ it "should return an attributes hash for #to_serializable" do
108
+ @model.to_serializable([:name, :hairs, {:party_hat => [:color, :size]}]).should ==
109
+ {'name' => 'joe', 'hairs' => 567, 'party_hat' => {
110
+ 'color' => 'blue', 'size' => 12
111
+ }}
112
+ end
113
+
114
+ it "should raise an error if #serialize is called without the :attributes option" do
115
+ lambda { @model.serialize(:yaml, {}) }.should raise_error("Must specify :attributes option")
116
+ end
117
+
118
+ it "should serialize to a hash for #serialize" do
119
+ YAML.load(@model.serialize(:yaml, :attributes => [:hairs, :eye_color, {:party_hat => :size}])).should ==
120
+ {"person" => {'hairs' => 567, 'eye_color' => 'blue', 'party_hat' => {'size' => 12}}}
121
+ end
122
+
123
+ it "should serialize to an XML document for #serialize(:xml, ...)" do
124
+ doc = REXML::Document.new(@model.serialize(:xml, :attributes => [:name, :eye_color, {:party_hat => :pattern}]),
125
+ :ignore_whitespace_nodes => :all)
126
+ doc.root.name.should == "person"
127
+ doc.root.children.find { |e| e.name == "name" }.text.should == "joe"
128
+ doc.root.children.find { |e| e.name == "eye-color" }.text.should == "blue"
129
+
130
+ hat = doc.root.children.find { |e| e.name == "party-hat" }
131
+ hat.children.find { |e| e.name == "pattern" }.text.should == "stripey"
132
+ end
133
+ end