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,185 @@
1
+ require 'resourceful/builder'
2
+
3
+ module Resourceful
4
+ # This module contains mixin modules
5
+ # used to implement the object serialization
6
+ # used for the Builder#publish method.
7
+ # They can also be used to get serialized representations of objects
8
+ # in other contexts.
9
+ #
10
+ # Serialization makes use of duck typing.
11
+ # Each class that can be serialized
12
+ # (just Array and ActiveRecord::Base by default)
13
+ # implements the +serialize+ and +to_serializable+ methods.
14
+ # These methods are implemented differently by the different classes,
15
+ # but the semantics of the implementations are consistent,
16
+ # so they can be used consistently.
17
+ #
18
+ # +to_serializable+ returns an object that can be directly serialized
19
+ # with a call to +to_xml+, +to_yaml+, or +to_json+.
20
+ # This object is either a hash or an array,
21
+ # and all the elements are either values, like strings and integers,
22
+ # or other serializable objects.
23
+ # This is useful for getting a model into a simple data structure format.
24
+ # The +attributes+ argument uses the same semantics
25
+ # as the <tt>:attributes</tt> option for Builder#publish.
26
+ # For example:
27
+ #
28
+ # c = Cake.new(:flavor => 'chocolate', :text => 'Happy birthday, Chris!')
29
+ # c.recipient = User.new(:name => 'Chris', :password => 'not very secure')
30
+ # c.to_serializable [
31
+ # :flavor, :text,
32
+ # :recipient => :name
33
+ # ]
34
+ #
35
+ # This would return the Ruby hash
36
+ #
37
+ # { :flavor => 'chocolate', :text => 'Happy birthday, Chris!',
38
+ # :user => {:name => 'Chris'} }
39
+ #
40
+ # +serialize+ takes a format (<tt>:xml</tt>, <tt>:yaml</tt>, or <tt>:json</tt> - see New Formats below)
41
+ # and a hash of options.
42
+ # The only option currently recognized is <tt>:attributes</tt>,
43
+ # which has the same semantics
44
+ # as the <tt>:attributes</tt> option for Builder#publish.
45
+ # +serialize+ returns a string containing the target
46
+ # serialized in the given format.
47
+ # For example:
48
+ #
49
+ # c = CandyBag.new(:title => 'jellybag')
50
+ # c.candies << Candy.new(:type => 'jellybean', :flavor => 'root beer')
51
+ # c.candies << Candy.new(:type => 'jellybean', :flavor => 'pear')
52
+ # c.candies << Candy.new(:type => 'licorice', :flavor => 'anisey')
53
+ # c.serialize :xml, :attributes => [:title, {:candies => [:type, :flavor]}]
54
+ #
55
+ # This would return a Ruby string containing
56
+ #
57
+ # <?xml version="1.0" encoding="UTF-8"?>
58
+ # <candy-bag>
59
+ # <title>jellybag</title>
60
+ # <candies>
61
+ # <candy>
62
+ # <type>jellybean</type>
63
+ # <flavor>root beer</flavor>
64
+ # </candy>
65
+ # <candy>
66
+ # <type>jellybean</type>
67
+ # <flavor>pear</flavor>
68
+ # </candy>
69
+ # <candy>
70
+ # <type>licorice</type>
71
+ # <flavor>anisey</flavor>
72
+ # </candy>
73
+ # </candies>
74
+ # </candy-bag>
75
+ #
76
+ module Serialize
77
+
78
+ # Takes an attributes option in the form passed to Builder#publish
79
+ # and returns a hash (or nil, if attributes is nil)
80
+ # containing the same data,
81
+ # but in a more consistent format.
82
+ # All keys are converted to symbols,
83
+ # and all lists are converted to hashes.
84
+ # For example:
85
+ #
86
+ # Resourceful::Serialize.normalize_attributes([:foo, :bar, {"baz" => ["boom"]}])
87
+ # #=> {"baz"=>["boom"], :foo=>nil, :bar=>nil}
88
+ #
89
+ def self.normalize_attributes(attributes) # :nodoc:
90
+ return nil if attributes.nil?
91
+ return {attributes.to_sym => nil} if String === attributes
92
+ return {attributes => nil} if !attributes.respond_to?(:inject)
93
+
94
+ attributes.inject({}) do |hash, attr|
95
+ if Array === attr
96
+ hash[attr[0]] = attr[1]
97
+ hash
98
+ else
99
+ hash.merge normalize_attributes(attr)
100
+ end
101
+ end
102
+ end
103
+
104
+ # This module contains the definitions of +serialize+ and +to_serializable+
105
+ # that are included in ActiveRecord::Base.
106
+ module Model
107
+ # :call-seq:
108
+ # serialize format, options = {}, :attributes => [ ... ]
109
+ #
110
+ # See the module documentation for Serialize for details.
111
+ def serialize(format, options)
112
+ raise "Must specify :attributes option" unless options[:attributes]
113
+ hash = self.to_serializable(options[:attributes])
114
+ root = self.class.to_s.underscore
115
+ if format == :xml
116
+ hash.send("to_#{format}", :root => root)
117
+ else
118
+ {root => hash}.send("to_#{format}")
119
+ end
120
+ end
121
+
122
+ # See the module documentation for Serialize for details.
123
+ def to_serializable(attributes)
124
+ raise "Must specify attributes for #{self.inspect}.to_serializable" if attributes.nil?
125
+
126
+ Serialize.normalize_attributes(attributes).inject({}) do |hash, (key, value)|
127
+ hash[key.to_s] = attr_hash_value(self.send(key), value)
128
+ hash
129
+ end
130
+ end
131
+
132
+ private
133
+
134
+ # Given an attribute value
135
+ # and a normalized (see above) attribute hash,
136
+ # returns the serializable form of that attribute.
137
+ def attr_hash_value(attr, sub_attributes)
138
+ if attr.respond_to?(:to_serializable)
139
+ attr.to_serializable(sub_attributes)
140
+ else
141
+ attr
142
+ end
143
+ end
144
+ end
145
+
146
+ # This module contains the definitions of +serialize+ and +to_serializable+
147
+ # that are included in ActiveRecord::Base.
148
+ module Array
149
+ # :call-seq:
150
+ # serialize format, options = {}, :attributes => [ ... ]
151
+ #
152
+ # See the module documentation for Serialize for details.
153
+ def serialize(format, options)
154
+ raise "Not all elements respond to to_serializable" unless all? { |e| e.respond_to? :to_serializable }
155
+ raise "Must specify :attributes option" unless options[:attributes]
156
+
157
+ serialized = map { |e| e.to_serializable(options[:attributes]) }
158
+ root = first.class.to_s.pluralize.underscore
159
+
160
+ if format == :xml
161
+ serialized.send("to_#{format}", :root => root)
162
+ else
163
+ {root => serialized}.send("to_#{format}")
164
+ end
165
+ end
166
+
167
+ # See the module documentation for Serialize for details.
168
+ def to_serializable(attributes)
169
+ if first.respond_to?(:to_serializable)
170
+ attributes = Serialize.normalize_attributes(attributes)
171
+ map { |e| e.to_serializable(attributes) }
172
+ else
173
+ self
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ if defined? ActiveModel
181
+ class ActiveModel::Base; include Resourceful::Serialize::Model; end
182
+ else
183
+ class ActiveRecord::Base; include Resourceful::Serialize::Model; end
184
+ end
185
+ class Array; include Resourceful::Serialize::Array; end
@@ -0,0 +1,474 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Resourceful::Default::Accessors, "#current_objects" do
4
+ include ControllerMocks
5
+ before :each do
6
+ mock_controller Resourceful::Default::Accessors
7
+ @objects = stub_list 5, 'object'
8
+ @model = stub
9
+ @controller.stubs(:current_model).returns(@model)
10
+ end
11
+
12
+ it "should look up all objects in the current model" do
13
+ @model.expects(:find).with(:all).returns(@objects)
14
+ @controller.current_objects.should == @objects
15
+ end
16
+
17
+ it "should cache the result, so subsequent calls won't run multiple queries" do
18
+ @model.expects(:find).once.returns(@objects)
19
+ @controller.current_objects
20
+ @controller.current_objects
21
+ end
22
+
23
+ it "shouldn't run a query if @current_objects is set" do
24
+ @controller.instance_variable_set('@current_objects', @objects)
25
+ @model.expects(:find).never
26
+ @controller.current_objects.should == @objects
27
+ end
28
+ end
29
+
30
+ describe Resourceful::Default::Accessors, "#load_objects" do
31
+ include ControllerMocks
32
+ before :each do
33
+ mock_controller Resourceful::Default::Accessors
34
+ @objects = stub_list 5, 'object'
35
+ @controller.stubs(:current_objects).returns(@objects)
36
+ @controller.stubs(:instance_variable_name).returns("posts")
37
+ end
38
+
39
+ it "should set the current instance variable to the object collection" do
40
+ @controller.load_objects
41
+ @controller.instance_variable_get('@posts').should == @objects
42
+ end
43
+ end
44
+
45
+ describe Resourceful::Default::Accessors, "#current_object on a plural controller" do
46
+ include ControllerMocks
47
+ before :each do
48
+ mock_controller Resourceful::Default::Accessors
49
+ @controller.stubs(:plural?).returns(true)
50
+ @controller.stubs(:params).returns(:id => "12")
51
+
52
+ @object = stub
53
+ @model = stub
54
+ @controller.stubs(:current_model).returns(@model)
55
+ end
56
+
57
+ it "should look up the object specified by the :id parameter in the current model" do
58
+ @model.expects(:find).with('12').returns(@object)
59
+ @controller.current_object.should == @object
60
+ end
61
+
62
+ it "should cache the result, so subsequent calls won't run multiple queries" do
63
+ @model.expects(:find).once.returns(@object)
64
+ @controller.current_object
65
+ @controller.current_object
66
+ end
67
+
68
+ it "shouldn't run a query if @current_object is set" do
69
+ @controller.instance_variable_set('@current_object', @object)
70
+ @model.expects(:find).never
71
+ @controller.current_object.should == @object
72
+ end
73
+ end
74
+
75
+ describe Resourceful::Default::Accessors, "#current_object on a singular controller" do
76
+ include ControllerMocks
77
+ before :each do
78
+ mock_controller Resourceful::Default::Accessors
79
+ @controller.stubs(:plural?).returns(false)
80
+ @controller.stubs(:controller_name).returns("posts")
81
+
82
+ @parent = stub('parent')
83
+ @controller.stubs(:parent_object).returns(@parent)
84
+ @controller.stubs(:parent?).returns(true)
85
+
86
+ @object = stub
87
+ end
88
+
89
+ it "should return the instance object from parent object" do
90
+ @parent.expects(:post).returns(@object)
91
+ @controller.current_object.should == @object
92
+ end
93
+ end
94
+
95
+ describe Resourceful::Default::Accessors, "#load_object" do
96
+ include ControllerMocks
97
+ before :each do
98
+ mock_controller Resourceful::Default::Accessors
99
+ @object = stub
100
+ @controller.stubs(:current_object).returns(@object)
101
+ @controller.stubs(:instance_variable_name).returns("posts")
102
+ end
103
+
104
+ it "should set the current singular instance variable to the current object" do
105
+ @controller.load_object
106
+ @controller.instance_variable_get('@post').should == @object
107
+ end
108
+ end
109
+
110
+ describe Resourceful::Default::Accessors, "#build_object with a #build-able model" do
111
+ include ControllerMocks
112
+ before :each do
113
+ mock_controller Resourceful::Default::Accessors
114
+ @params = {:name => "Bob", :password => "hideously insecure"}
115
+ @controller.stubs(:object_parameters).returns(@params)
116
+
117
+ @object = stub
118
+ @model = stub
119
+ @controller.stubs(:current_model).returns(@model)
120
+
121
+ @model.stubs(:build).returns(@object)
122
+ end
123
+
124
+ it "should return a new object built with current_model from the object parameters" do
125
+ @model.expects(:build).with(@params).returns(@object)
126
+ @controller.build_object.should == @object
127
+ end
128
+
129
+ it "should make current_object return the newly built object" do
130
+ @controller.build_object
131
+ @controller.current_object.should == @object
132
+ end
133
+ end
134
+
135
+ describe Resourceful::Default::Accessors, "#build_object with a non-#build-able model" do
136
+ include ControllerMocks
137
+ before :each do
138
+ mock_controller Resourceful::Default::Accessors
139
+ @params = {:name => "Bob", :password => "hideously insecure"}
140
+ @controller.stubs(:object_parameters).returns(@params)
141
+
142
+ @controller.stubs(:singular?).returns(false)
143
+ @controller.stubs(:parent?).returns(false)
144
+
145
+ @object = stub
146
+ @model = stub
147
+ @controller.stubs(:current_model).returns(@model)
148
+
149
+ @model.stubs(:new).returns(@object)
150
+ end
151
+
152
+ it "should return a new instance of the current_model built with the object parameters" do
153
+ @model.expects(:new).with(@params).returns(@object)
154
+ @controller.build_object.should == @object
155
+ end
156
+ end
157
+
158
+ describe Resourceful::Default::Accessors, "#current_model_name" do
159
+ include ControllerMocks
160
+ before :each do
161
+ mock_controller Resourceful::Default::Accessors
162
+ @controller.stubs(:controller_name).returns("funky_posts")
163
+ end
164
+
165
+ it "should return the controller's name, singularized and camel-cased" do
166
+ @controller.current_model_name.should == "FunkyPost"
167
+ end
168
+ end
169
+
170
+ describe Resourceful::Default::Accessors, "#namespaces" do
171
+ include ControllerMocks
172
+ before :each do
173
+ mock_controller Resourceful::Default::Accessors
174
+ @kontroller.stubs(:name).returns("FunkyStuff::Admin::Posts")
175
+ end
176
+
177
+ it "should return an array of underscored symbols representing the namespaces of the controller class" do
178
+ @controller.namespaces.should == [:funky_stuff, :admin]
179
+ end
180
+
181
+ it "should cache the result, so subsequent calls won't run multiple computations" do
182
+ @kontroller.expects(:name).once.returns("Posts")
183
+ @controller.namespaces
184
+ @controller.namespaces
185
+ end
186
+ end
187
+
188
+ describe Resourceful::Default::Accessors, "#instance_variable_name" do
189
+ include ControllerMocks
190
+ before :each do
191
+ mock_controller Resourceful::Default::Accessors
192
+ @controller.stubs(:controller_name).returns("posts")
193
+ end
194
+
195
+ it "should return controller_name" do
196
+ @controller.instance_variable_name == "posts"
197
+ end
198
+ end
199
+
200
+ describe Resourceful::Default::Accessors, "#current_model for a singular controller" do
201
+ include ControllerMocks
202
+ before :each do
203
+ mock_controller Resourceful::Default::Accessors
204
+ stub_const :Post
205
+ @controller.stubs(:singular?).returns(true)
206
+ @controller.stubs(:current_model_name).returns("Post")
207
+
208
+ @parent = stub('parent')
209
+ @controller.stubs(:parent_object).returns(@parent)
210
+ @controller.stubs(:parent?).returns(true)
211
+ end
212
+
213
+ it "should return the constant named by current_model_name" do
214
+ @controller.current_model.should == Post
215
+ end
216
+ end
217
+
218
+ describe Resourceful::Default::Accessors, "#current_model for a plural controller with no parent" do
219
+ include ControllerMocks
220
+ before :each do
221
+ mock_controller Resourceful::Default::Accessors
222
+ stub_const :Post
223
+ @controller.stubs(:singular?).returns(false)
224
+ @controller.stubs(:current_model_name).returns("Post")
225
+ @controller.stubs(:parent?).returns(false)
226
+ end
227
+
228
+ it "should return the constant named by current_model_name" do
229
+ @controller.current_model.should == Post
230
+ end
231
+ end
232
+
233
+ describe Resourceful::Default::Accessors, "#object_parameters" do
234
+ include ControllerMocks
235
+ before :each do
236
+ mock_controller Resourceful::Default::Accessors
237
+ @params = {"crazy_user" => {:name => "Hampton", :location => "Canada"}}
238
+ @controller.stubs(:params).returns(@params)
239
+ @controller.stubs(:current_model_name).returns("CrazyUser")
240
+ end
241
+
242
+ it "should return the element of the params hash with the name of the model" do
243
+ @controller.object_parameters.should == @params["crazy_user"]
244
+ end
245
+ end
246
+
247
+ describe Resourceful::Default::Accessors, " with two parent classes set on the controller class and one parent parameter supplied" do
248
+ include ControllerMocks
249
+ before :each do
250
+ mock_controller Resourceful::Default::Accessors
251
+ @parents = %w{post comment}
252
+ @models = @parents.map(&:camelize).map(&method(:stub_const))
253
+ @kontroller.parents = @parents
254
+ @controller.stubs(:singular?).returns(false)
255
+ @controller.stubs(:instance_variable_name).returns('lines')
256
+
257
+ @params = HashWithIndifferentAccess.new :post_id => 12
258
+ @controller.stubs(:params).returns(@params)
259
+
260
+ @post = stub('Post')
261
+ Post.stubs(:find).returns(@post)
262
+
263
+ @model = stub
264
+ end
265
+
266
+ it "should return true for #parent?" do
267
+ @controller.parent?.should be_true
268
+ end
269
+
270
+ it "should return the string names of all the parents for #parent_names" do
271
+ @controller.parent_names.should == @parents
272
+ end
273
+
274
+ it "should return the string name of the current parent for #parent_name" do
275
+ @controller.parent_name.should == 'post'
276
+ end
277
+
278
+ it "should return the model class for #parent_model" do
279
+ @controller.parent_model.should == Post
280
+ end
281
+
282
+ it "should return the parent object for #parent_object" do
283
+ Post.expects(:find).with(12).returns(@post)
284
+ @controller.parent_object.should == @post
285
+ end
286
+
287
+ it "should cache the value of #parent_object so multiple calls won't cause multiple queries" do
288
+ Post.expects(:find).returns(@post).once
289
+ @controller.parent_object
290
+ @controller.parent_object
291
+ end
292
+
293
+ it "should bind the parent object its proper instance variable" do
294
+ @controller.load_parent_object
295
+ @controller.instance_variable_get('@post').should == @post
296
+ end
297
+
298
+ it "should return the parent-scoped model for #current_model" do
299
+ @post.stubs(:lines).returns(@model)
300
+ @controller.current_model.should == @model
301
+ end
302
+
303
+ it "should return true for #ensure_parent_exists" do
304
+ @controller.expects(:render).never
305
+ @controller.ensure_parent_exists.should be_true
306
+ end
307
+ end
308
+
309
+ describe Resourceful::Default::Accessors, " with two parent classes set on the controller class but no parent parameter supplied" do
310
+ include ControllerMocks
311
+ before :each do
312
+ mock_controller Resourceful::Default::Accessors
313
+ @parents = %w{post comment}
314
+ @models = @parents.map(&:camelize).map(&method(:stub_const))
315
+ @kontroller.parents = @parents
316
+ @controller.stubs(:params).returns({})
317
+ @controller.stubs(:controller_name).returns('line')
318
+ stub_const('Line')
319
+ end
320
+
321
+ it "should return false for #parent?" do
322
+ @controller.parent?.should be_false
323
+ end
324
+
325
+ it "should return nil for #parent_name" do
326
+ @controller.parent_name.should be_nil
327
+ end
328
+
329
+ it "should return the unscoped model for #current_model" do
330
+ @controller.current_model.should == Line
331
+ end
332
+
333
+ it "should return false and render a 422 error for #ensure_parent_exists" do
334
+ @controller.expects(:render).with(has_entry(:status, 422))
335
+ @controller.ensure_parent_exists.should be_false
336
+ end
337
+ end
338
+
339
+ describe Resourceful::Default::Accessors, " with no parents" do
340
+ include ControllerMocks
341
+ before :each do
342
+ mock_controller Resourceful::Default::Accessors
343
+ @controller.stubs(:parents).returns([])
344
+ @controller.stubs(:current_model_name).returns('Line')
345
+ @controller.stubs(:params).returns({})
346
+ stub_const 'Line'
347
+ end
348
+
349
+ it "should return false for #parent?" do
350
+ @controller.parent?.should be_false
351
+ end
352
+
353
+ it "should return nil for #parent_name" do
354
+ @controller.parent_name.should be_nil
355
+ end
356
+
357
+ it "should return the unscoped model for #current_model" do
358
+ @controller.current_model.should == Line
359
+ end
360
+ end
361
+
362
+ describe Resourceful::Default::Accessors, " for a singular controller with a parent" do
363
+ include ControllerMocks
364
+ before :each do
365
+ mock_controller Resourceful::Default::Accessors
366
+ @controller.stubs(:singular?).returns(true)
367
+
368
+ @model = stub_model('Thing')
369
+ @model.send(:attr_accessor, :person_id)
370
+ @controller.stubs(:current_model).returns(@model)
371
+
372
+ @person = stub_model('Person')
373
+ @person.stubs(:id).returns 42
374
+ @controller.stubs(:parent_object).returns(@person)
375
+ @controller.stubs(:parent_name).returns('person')
376
+ @controller.stubs(:parent?).returns(true)
377
+
378
+ @controller.stubs(:object_parameters).returns :thinginess => 12, :bacon => true
379
+ end
380
+
381
+ it "should set assign the parent's id to a newly built object" do
382
+ thing = @controller.build_object
383
+ thing.thinginess.should == 12
384
+ thing.person_id.should == @person.id
385
+ end
386
+ end
387
+
388
+ describe Resourceful::Default::Accessors, "#save_succeeded!" do
389
+ include ControllerMocks
390
+ before :each do
391
+ mock_controller Resourceful::Default::Accessors
392
+ @controller.save_succeeded!
393
+ end
394
+
395
+ it "should make #save_succeeded? return true" do
396
+ @controller.save_succeeded?.should be_true
397
+ end
398
+ end
399
+
400
+ describe Resourceful::Default::Accessors, "#save_failed!" do
401
+ include ControllerMocks
402
+ before :each do
403
+ mock_controller Resourceful::Default::Accessors
404
+ @controller.save_failed!
405
+ end
406
+
407
+ it "should make #save_succeeded? return false" do
408
+ @controller.save_succeeded?.should be_false
409
+ end
410
+ end
411
+
412
+ describe Resourceful::Default::Accessors, " for a plural action" do
413
+ include ControllerMocks
414
+ before :each do
415
+ mock_controller Resourceful::Default::Accessors
416
+ @controller.stubs(:params).returns :action => "index"
417
+ end
418
+
419
+ it "should know it's a plural action" do
420
+ @controller.should be_a_plural_action
421
+ end
422
+
423
+ it "should know it's not a singular action" do
424
+ @controller.should_not be_a_singular_action
425
+ end
426
+ end
427
+
428
+ describe Resourceful::Default::Accessors, " for a singular action" do
429
+ include ControllerMocks
430
+ before :each do
431
+ mock_controller Resourceful::Default::Accessors
432
+ @controller.stubs(:params).returns :action => "show"
433
+ end
434
+
435
+ it "should know it's not a plural action" do
436
+ @controller.should_not be_a_plural_action
437
+ end
438
+
439
+ it "should know it's a singular action" do
440
+ @controller.should be_a_singular_action
441
+ end
442
+ end
443
+
444
+ describe Resourceful::Default::Accessors, " for a singular controller" do
445
+ include ControllerMocks
446
+ before :each do
447
+ mock_controller Resourceful::Default::Accessors
448
+ @controller.stubs(:instance_variable_name).returns "post"
449
+ end
450
+
451
+ it "should know it's not plural" do
452
+ @controller.should_not be_plural
453
+ end
454
+
455
+ it "should know it's singular" do
456
+ @controller.should be_singular
457
+ end
458
+ end
459
+
460
+ describe Resourceful::Default::Accessors, " for a plural controller" do
461
+ include ControllerMocks
462
+ before :each do
463
+ mock_controller Resourceful::Default::Accessors
464
+ @controller.stubs(:instance_variable_name).returns "posts"
465
+ end
466
+
467
+ it "should know it's plural" do
468
+ @controller.should be_plural
469
+ end
470
+
471
+ it "should know it's not singular" do
472
+ @controller.should_not be_singular
473
+ end
474
+ end