remarkable_rails 3.1.8 → 3.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/CHANGELOG +91 -88
  2. data/LICENSE +20 -20
  3. data/README +80 -80
  4. data/lib/remarkable_rails/action_controller/base.rb +29 -29
  5. data/lib/remarkable_rails/action_controller/macro_stubs.rb +459 -457
  6. data/lib/remarkable_rails/action_controller/matchers/assign_to_matcher.rb +92 -92
  7. data/lib/remarkable_rails/action_controller/matchers/filter_params_matcher.rb +41 -41
  8. data/lib/remarkable_rails/action_controller/matchers/redirect_to_matcher.rb +119 -119
  9. data/lib/remarkable_rails/action_controller/matchers/render_template_matcher.rb +146 -146
  10. data/lib/remarkable_rails/action_controller/matchers/respond_with_matcher.rb +126 -126
  11. data/lib/remarkable_rails/action_controller/matchers/route_matcher.rb +135 -109
  12. data/lib/remarkable_rails/action_controller/matchers/set_cookies_matcher.rb +49 -49
  13. data/lib/remarkable_rails/action_controller/matchers/set_session_matcher.rb +106 -106
  14. data/lib/remarkable_rails/action_controller/matchers/set_the_flash_matcher.rb +54 -54
  15. data/lib/remarkable_rails/action_controller.rb +22 -22
  16. data/lib/remarkable_rails/action_view/base.rb +7 -7
  17. data/lib/remarkable_rails/action_view.rb +18 -18
  18. data/lib/remarkable_rails/active_orm.rb +19 -19
  19. data/lib/remarkable_rails.rb +30 -30
  20. data/locale/en.yml +110 -110
  21. data/spec/action_controller/assign_to_matcher_spec.rb +142 -142
  22. data/spec/action_controller/filter_params_matcher_spec.rb +64 -64
  23. data/spec/action_controller/macro_stubs_spec.rb +234 -208
  24. data/spec/action_controller/redirect_to_matcher_spec.rb +102 -102
  25. data/spec/action_controller/render_template_matcher_spec.rb +251 -251
  26. data/spec/action_controller/respond_with_matcher_spec.rb +223 -223
  27. data/spec/action_controller/route_matcher_spec.rb +96 -79
  28. data/spec/action_controller/set_cookies_matcher_spec.rb +149 -149
  29. data/spec/action_controller/set_session_matcher_spec.rb +141 -141
  30. data/spec/action_controller/set_the_flash_matcher_spec.rb +93 -93
  31. data/spec/application/application.rb +15 -15
  32. data/spec/application/tasks_controller.rb +34 -34
  33. data/spec/functional_builder.rb +88 -88
  34. data/spec/rcov.opts +2 -2
  35. data/spec/remarkable_rails_spec.rb +5 -5
  36. data/spec/spec.opts +4 -4
  37. data/spec/spec_helper.rb +42 -42
  38. metadata +7 -7
@@ -1,50 +1,50 @@
1
- module Remarkable
2
- module ActionController
3
-
4
- # Macro stubs makes stubs and expectations easier, more readable and DRY.
5
- #
6
- # == Example
7
- #
8
- # Let's jump off to an example:
9
- #
10
- # describe ProjectsController do
11
- # describe :get => :show, :id => 37 do
12
- # expects :find, :on => Project, :with => '37', :returns => proc { mock_project }
13
- #
14
- # should_assign_to :project, :with => proc { mock_project }
15
- # should_render_template 'show'
16
- #
17
- # describe Mime::XML do
18
- # should_assign_to :project
19
- # should_respond_with_content_type Mime::XML
20
- # end
21
- # end
22
- # end
23
- #
24
- # See how the spec is readable: a ProjectsController responding to get show
25
- # expects :find on Project which a mock project and then should assign to
26
- # project and render template 'show'.
27
- #
28
- # Each macro before asserting will check if an action was already performed and
29
- # if not, it runs the expectations and call the action.
30
- #
31
- # In other words, should assign to macro is basically doing:
32
- #
33
- # it 'should assign to project' do
34
- # Project.should_receive(:find).with('37').and_return(mock_project)
35
- # get :show, :id => '37'
36
- # assigns(:project).should == mock_project
37
- # end
38
- #
39
- # By default, all macros perform expectations. You can change
40
- # this behavior sending :with_stubs or :with_expectations as options:
41
- #
42
- # should_assign_to :project, :with_stubs => true
43
- # should_render_template 'show', :with_expectations => false
44
- #
45
- # This also works in the rspec way:
46
- #
47
- # it { should assign_to(:project).with_stubs }
1
+ module Remarkable
2
+ module ActionController
3
+
4
+ # Macro stubs makes stubs and expectations easier, more readable and DRY.
5
+ #
6
+ # == Example
7
+ #
8
+ # Let's jump off to an example:
9
+ #
10
+ # describe ProjectsController do
11
+ # describe :get => :show, :id => 37 do
12
+ # expects :find, :on => Project, :with => '37', :returns => proc { mock_project }
13
+ #
14
+ # should_assign_to :project, :with => proc { mock_project }
15
+ # should_render_template 'show'
16
+ #
17
+ # describe Mime::XML do
18
+ # should_assign_to :project
19
+ # should_respond_with_content_type Mime::XML
20
+ # end
21
+ # end
22
+ # end
23
+ #
24
+ # See how the spec is readable: a ProjectsController responding to get show
25
+ # expects :find on Project which a mock project and then should assign to
26
+ # project and render template 'show'.
27
+ #
28
+ # Each macro before asserting will check if an action was already performed and
29
+ # if not, it runs the expectations and call the action.
30
+ #
31
+ # In other words, should assign to macro is basically doing:
32
+ #
33
+ # it 'should assign to project' do
34
+ # Project.should_receive(:find).with('37').and_return(mock_project)
35
+ # get :show, :id => '37'
36
+ # assigns(:project).should == mock_project
37
+ # end
38
+ #
39
+ # By default, all macros perform expectations. You can change
40
+ # this behavior sending :with_stubs or :with_expectations as options:
41
+ #
42
+ # should_assign_to :project, :with_stubs => true
43
+ # should_render_template 'show', :with_expectations => false
44
+ #
45
+ # This also works in the rspec way:
46
+ #
47
+ # it { should assign_to(:project).with_stubs }
48
48
  # it { should render_template('show').with_expectations(false) }
49
49
  #
50
50
  # == Attention!
@@ -60,166 +60,166 @@ module Remarkable
60
60
  #
61
61
  # And it won't work. The right way to handle this is:
62
62
  #
63
- # expects :comment_ids=, :on => Post, :with => [[1,2,3]]
64
- #
65
- # == mock_models
66
- #
67
- # You don't have to play with proc all the time. You can call mock_models which
68
- # creates two class methods that simply returns a proc and a instance method that
63
+ # expects :comment_ids=, :on => Post, :with => [[1,2,3]]
64
+ #
65
+ # == mock_models
66
+ #
67
+ # You don't have to play with proc all the time. You can call mock_models which
68
+ # creates two class methods that simply returns a proc and a instance method that
69
69
  # do the actual mock.
70
70
  #
71
71
  # describe ProjectsController do
72
72
  # mock_models :project
73
73
  #
74
- # And it creates:
75
- #
76
- # def self.project_proc
77
- # proc { mock_project }
74
+ # And it creates:
75
+ #
76
+ # def self.project_proc
77
+ # proc { mock_project }
78
78
  # end
79
79
  #
80
80
  # # To be used on index actions
81
- # def self.projects_proc
82
- # proc { [mock_project] }
83
- # end
84
- #
85
- # def mock_project(stubs={})
86
- # @project ||= mock_model(Project, stubs)
87
- # end
88
- #
89
- # Then you can replace those lines:
90
- #
91
- # expects :find, :on => Project, :with => '37', :returns => proc { mock_project }
92
- # should_assign_to :project, :with => proc { mock_project }
93
- #
94
- # For:
95
- #
96
- # expects :find, :on => Project, :with => '37', :returns => project_proc
97
- # should_assign_to :project, :with => project_proc
98
- #
99
- # = Give me more!
100
- #
81
+ # def self.projects_proc
82
+ # proc { [mock_project] }
83
+ # end
84
+ #
85
+ # def mock_project(stubs={})
86
+ # @project ||= mock_model(Project, stubs)
87
+ # end
88
+ #
89
+ # Then you can replace those lines:
90
+ #
91
+ # expects :find, :on => Project, :with => '37', :returns => proc { mock_project }
92
+ # should_assign_to :project, :with => proc { mock_project }
93
+ #
94
+ # For:
95
+ #
96
+ # expects :find, :on => Project, :with => '37', :returns => project_proc
97
+ # should_assign_to :project, :with => project_proc
98
+ #
99
+ # = Give me more!
100
+ #
101
101
  # If you need to set the example group description, you can also call <tt>get</tt>,
102
- # <tt>post</tt>, <tt>put</tt> and <tt>delete</tt> methods:
103
- #
104
- # describe 'my description' do
105
- # get :show, :id => 37
106
- #
107
- # Things start to get even better when we start to talk about nested resources.
108
- # After our ProjectsController is created, we want to create a TasksController:
109
- #
110
- # describe TasksController do
111
- # params :project_id => '42' #=> define params for all requests
112
- #
113
- # # Those two expectations get inherited in all describe groups below
114
- # expects :find_by_title, :on => Project, :with => '42', :returns => project_proc
115
- # expects :tasks, :and_return => Task
116
- #
117
- # describe :get => :show, :id => '37' do
118
- # expects :find, :with => '37', :and_return => task_proc
119
- #
120
- # should_assign_to :project, :task
121
- # should_render_template 'show'
122
- # end
123
- # end
124
- #
125
- # As you noticed, you can define parameters that will be available to all requests,
126
- # using the method <tt>params</tt>.
127
- #
102
+ # <tt>post</tt>, <tt>put</tt> and <tt>delete</tt> methods:
103
+ #
104
+ # describe 'my description' do
105
+ # get :show, :id => 37
106
+ #
107
+ # Things start to get even better when we start to talk about nested resources.
108
+ # After our ProjectsController is created, we want to create a TasksController:
109
+ #
110
+ # describe TasksController do
111
+ # params :project_id => '42' #=> define params for all requests
112
+ #
113
+ # # Those two expectations get inherited in all describe groups below
114
+ # expects :find_by_title, :on => Project, :with => '42', :returns => project_proc
115
+ # expects :tasks, :and_return => Task
116
+ #
117
+ # describe :get => :show, :id => '37' do
118
+ # expects :find, :with => '37', :and_return => task_proc
119
+ #
120
+ # should_assign_to :project, :task
121
+ # should_render_template 'show'
122
+ # end
123
+ # end
124
+ #
125
+ # As you noticed, you can define parameters that will be available to all requests,
126
+ # using the method <tt>params</tt>.
127
+ #
128
128
  # Finally if you need to write a spec by hand, you can invoke the action and
129
- # expectations with run_action!, run_expectations! and run_stubs!. Examples:
130
- #
131
- # describe :get => :new do
132
- # expects :new, :on => Project, :returns => project_proc
133
- #
134
- # it "should do something different" do
135
- # run_action!
136
- # # do you assertions here
137
- # end
138
- # end
139
- #
140
- # = Performance!
141
- #
129
+ # expectations with run_action!, run_expectations! and run_stubs!. Examples:
130
+ #
131
+ # describe :get => :new do
132
+ # expects :new, :on => Project, :returns => project_proc
133
+ #
134
+ # it "should do something different" do
135
+ # run_action!
136
+ # # do you assertions here
137
+ # end
138
+ # end
139
+ #
140
+ # = Performance!
141
+ #
142
142
  # Remarkable comes with a new way to speed up your tests. It performs the
143
- # action inside a before(:all), so you can do:
144
- #
145
- # describe "responding to GET show" do
146
- # get! :show, :id => 37
147
- #
148
- # should_assign_to :task
149
- # should_render_template :show
150
- # end
151
- #
152
- # Or in the compact way:
153
- #
154
- # describe :get! => :show, :id => 37
155
- #
143
+ # action inside a before(:all), so you can do:
144
+ #
145
+ # describe "responding to GET show" do
146
+ # get! :show, :id => 37
147
+ #
148
+ # should_assign_to :task
149
+ # should_render_template :show
150
+ # end
151
+ #
152
+ # Or in the compact way:
153
+ #
154
+ # describe :get! => :show, :id => 37
155
+ #
156
156
  # The action will be performed just once before running the macros. If any
157
157
  # error happens while performing the action, rspec will output an error
158
- # but ALL the examples inside the example group (describe) won't be run.
159
- #
158
+ # but ALL the examples inside the example group (describe) won't be run.
159
+ #
160
160
  # By now, the bang methods works only when integrate_views is true and this
161
- # is when you must see a bigger performance gain.
162
- #
161
+ # is when you must see a bigger performance gain.
162
+ #
163
163
  # This feature comes with some rspec and rspec rails tweakings. So if you want
164
164
  # to do something before the action is performed (stubs something or log
165
- # someone in session), you have to do it giving a block to the action method:
166
- #
167
- # get! :show, :id => 37 do
168
- # login_as(mock_user)
169
- # end
170
- #
171
- # You can still use the compact way and give the block:
172
- #
173
- # describe :get => :show, :id => 37 do
174
- # get! do
175
- # login_as(mock_user)
176
- # end
177
- # end
178
- #
179
- module MacroStubs
180
- HTTP_VERBS_METHODS = [:get, :get!, :post, :post!, :put, :put!, :delete, :delete!]
181
-
182
- def self.included(base) #:nodoc:
183
- base.extend ClassMethods
184
- base.class_inheritable_reader :expects_chain, :default_action, :default_mime,
165
+ # someone in session), you have to do it giving a block to the action method:
166
+ #
167
+ # get! :show, :id => 37 do
168
+ # login_as(mock_user)
169
+ # end
170
+ #
171
+ # You can still use the compact way and give the block:
172
+ #
173
+ # describe :get => :show, :id => 37 do
174
+ # get! do
175
+ # login_as(mock_user)
176
+ # end
177
+ # end
178
+ #
179
+ module MacroStubs
180
+ HTTP_VERBS_METHODS = [:get, :get!, :post, :post!, :put, :put!, :delete, :delete!]
181
+
182
+ def self.included(base) #:nodoc:
183
+ base.extend ClassMethods
184
+ base.class_inheritable_reader :expects_chain, :default_action, :default_mime,
185
185
  :default_verb, :default_params, :default_xhr,
186
- :before_all_block
187
- end
188
-
189
- module ClassMethods
190
-
191
- # Creates a chain that will be evaluated as stub or expectation. The
186
+ :before_all_block
187
+ end
188
+
189
+ module ClassMethods
190
+
191
+ # Creates a chain that will be evaluated as stub or expectation. The
192
192
  # first parameter is the method expected. You can also specify multiple
193
193
  # methods to stub and give a block to calculate the returned value. See
194
194
  # examples below.
195
- #
196
- # == Options
197
- #
198
- # * <tt>:on</tt> - Tell which object will receive the expected method.
199
- # This option is always required.
200
- #
201
- # * <tt>:with</tt> - Tell each parameters will be sent with the expected
202
- # method. This option is used only in expectations and is optional.
203
- #
204
- # * <tt>:returns</tt> - Tell what the expectations should return. Not
205
- # required.
206
- #
207
- # * <tt>:times</tt> - The number of times the object will receive the
195
+ #
196
+ # == Options
197
+ #
198
+ # * <tt>:on</tt> - Tell which object will receive the expected method.
199
+ # This option is always required.
200
+ #
201
+ # * <tt>:with</tt> - Tell each parameters will be sent with the expected
202
+ # method. This option is used only in expectations and is optional.
203
+ #
204
+ # * <tt>:returns</tt> - Tell what the expectations should return. Not
205
+ # required.
206
+ #
207
+ # * <tt>:times</tt> - The number of times the object will receive the
208
208
  # method. Used only in expectations and when not given, defaults to 1.
209
209
  #
210
210
  # * <tt>:ordered</tt> - When true specifies that expectations should
211
- # be received in order.
212
- #
213
- # == Example
214
- #
211
+ # be received in order.
212
+ #
213
+ # == Example
214
+ #
215
215
  # expects :new, :on => Project, :returns => :project_proc, :times => 2
216
216
  #
217
217
  # expects :new, :find, :on => Project, :returns => :project_proc
218
218
  #
219
219
  # expects :human_attribute_name, :on => Project, :with => :title do |attr|
220
220
  # attr.to_s.humanize
221
- # end
222
- #
221
+ # end
222
+ #
223
223
  def expects(*args, &block)
224
224
  options = args.extract_options!
225
225
  options.assert_valid_keys(:on, :with, :returns, :times, :ordered)
@@ -227,34 +227,34 @@ module Remarkable
227
227
  args.each do |arg|
228
228
  write_inheritable_array(:expects_chain, [ [ arg, options, block] ])
229
229
  end
230
- end
231
-
232
- # The mime type of the request. The value given will be called transformed
233
- # into a string and set in the @request.env['HTTP_ACCEPT'] variable.
234
- #
235
- # == Examples
236
- #
237
- # mime Mime::XML
238
- # mime 'application/xml+rss'
239
- #
240
- def mime(mime)
241
- write_inheritable_attribute(:default_mime, mime.to_s)
242
- end
243
-
244
- # The params used for the request. Calls are always nested:
245
- #
246
- # == Examples
247
- #
248
- # describe TasksController do
249
- # params :project_id => 42
250
- #
251
- # describe :get => :show, :id => 37 do
252
- # # will request with params {:id => 37, :project_id => 42}
253
- # end
254
- # end
255
- #
256
- def params(params)
257
- write_inheritable_hash(:default_params, params)
230
+ end
231
+
232
+ # The mime type of the request. The value given will be called transformed
233
+ # into a string and set in the @request.env['HTTP_ACCEPT'] variable.
234
+ #
235
+ # == Examples
236
+ #
237
+ # mime Mime::XML
238
+ # mime 'application/xml+rss'
239
+ #
240
+ def mime(mime)
241
+ write_inheritable_attribute(:default_mime, mime.to_s)
242
+ end
243
+
244
+ # The params used for the request. Calls are always nested:
245
+ #
246
+ # == Examples
247
+ #
248
+ # describe TasksController do
249
+ # params :project_id => 42
250
+ #
251
+ # describe :get => :show, :id => 37 do
252
+ # # will request with params {:id => 37, :project_id => 42}
253
+ # end
254
+ # end
255
+ #
256
+ def params(params)
257
+ write_inheritable_hash(:default_params, params)
258
258
  end
259
259
 
260
260
  # Sets the request to perform a XmlHttpRequest.
@@ -267,183 +267,183 @@ module Remarkable
267
267
  #
268
268
  def xhr!(bool=true)
269
269
  write_inheritable_attribute(:default_xhr, bool)
270
- end
271
-
272
- [:get, :post, :put, :delete].each do |verb|
273
- module_eval <<-VERB, __FILE__, __LINE__
274
- # Declares that we want to do a #{verb} request in the given action
275
- # and with the given params.
276
- #
277
- # == Examples
278
- #
279
- # #{verb} :action, :id => 42
280
- #
281
- def #{verb}(action, params={})
282
- params(params)
283
- write_inheritable_attribute(:default_verb, #{verb.inspect})
284
- write_inheritable_attribute(:default_action, action)
285
- end
286
- VERB
287
- end
288
-
289
- [:get!, :post!, :put!, :delete!].each do |verb|
290
- module_eval <<-VERB, __FILE__, __LINE__
291
- # Declares that we want to do a #{verb} request in the given action
292
- # and with the given params, but the action is performed just once
293
- # in the describe group. In other words, it's performed in a
294
- # before(:all) filter.
295
- #
296
- # == Examples
297
- #
298
- # #{verb} :action, :id => 42
299
- #
300
- def #{verb}(action=nil, params={}, &block)
301
- #{verb.to_s.chop}(action, params) if action
302
- write_inheritable_array(:before_all_block, [block]) if block
303
- run_callbacks_once!
304
- end
305
- VERB
306
- end
307
-
308
- # Undefine the method run_callbacks so rspec won't run them in the
309
- # before and after :each cycle. Then we redefine it as run_callbacks_once,
310
- # which will be used as an before(:all) and after(:all) filter.
311
- #
312
- def run_callbacks_once!(&block) #:nodoc:
313
- unless instance_methods.any?{|m| m.to_s == 'run_callbacks_once' }
314
- alias_method :run_callbacks_once, :run_callbacks
315
- class_eval "def run_callbacks(*args); end"
316
-
317
- before(:all) do
318
- setup_mocks_for_rspec
319
- run_callbacks_once :setup
320
-
321
- before_all_block.each do |block|
322
- instance_eval(&block)
323
- end if before_all_block
324
-
325
- run_action!
326
- verify_mocks_for_rspec
327
- teardown_mocks_for_rspec
328
- end
329
-
330
- after(:all) do
331
- run_callbacks_once :teardown
332
- end
333
- end
334
- end
335
-
336
- # Overwrites describe to provide quick action description with I18n.
337
- #
338
- # You can now do:
339
- #
340
- # describe :get => :show, :id => 37
341
- #
342
- # Which is the same as:
343
- #
344
- # describe 'responding to #GET show' do
345
- # get :show, :id => 37
346
- #
347
- # And do this:
348
- #
349
- # describe Mime::XML
350
- #
351
- # Which is the same as:
352
- #
353
- # describe 'with xml' do
354
- # mime Mime::XML
355
- #
356
- # The string can be localized using I18n. An example yml file is:
357
- #
358
- # locale:
359
- # remarkable:
360
- # action_controller:
361
- # responding: "responding to #{{verb}} {{action}}"
362
- # mime_type: "with {{format}} ({{content_type}})"
363
- #
364
- # And load the locale file with:
365
- #
366
- # Remarkable.add_locale locale_path
367
- #
368
- def describe(*args, &block)
369
- options = args.first.is_a?(Hash) ? args.first : {}
370
- verb = (options.keys & HTTP_VERBS_METHODS).first
371
-
372
- if verb
373
- action = options.delete(verb)
374
- verb = verb.to_s
375
-
376
- description = Remarkable.t 'remarkable.action_controller.responding',
377
- :default => "responding to \#{{verb}} {{action}}",
378
- :verb => verb.sub('!', '').upcase, :action => action
379
-
380
- send_args = [ verb, action, options ]
381
- elsif args.first.is_a?(Mime::Type)
382
- mime = args.first
383
-
384
- description = Remarkable.t 'remarkable.action_controller.mime_type',
385
- :default => "with #{mime.to_sym}",
386
- :format => mime.to_sym, :content_type => mime.to_s
387
-
388
- send_args = [ :mime, mime ]
389
- else # return if no special type was found
390
- return super(*args, &block)
391
- end
392
-
393
- args.shift
394
- args.unshift(description)
395
-
396
- # Creates an example group, send the method and eval the given block.
397
- #
398
- example_group = super(*args) do
399
- send(*send_args)
400
- instance_eval(&block)
401
- end
402
- end
403
-
404
- # Creates mock methods automatically.
405
- #
270
+ end
271
+
272
+ [:get, :post, :put, :delete].each do |verb|
273
+ module_eval <<-VERB, __FILE__, __LINE__
274
+ # Declares that we want to do a #{verb} request in the given action
275
+ # and with the given params.
276
+ #
277
+ # == Examples
278
+ #
279
+ # #{verb} :action, :id => 42
280
+ #
281
+ def #{verb}(action, params={})
282
+ params(params)
283
+ write_inheritable_attribute(:default_verb, #{verb.inspect})
284
+ write_inheritable_attribute(:default_action, action)
285
+ end
286
+ VERB
287
+ end
288
+
289
+ [:get!, :post!, :put!, :delete!].each do |verb|
290
+ module_eval <<-VERB, __FILE__, __LINE__
291
+ # Declares that we want to do a #{verb} request in the given action
292
+ # and with the given params, but the action is performed just once
293
+ # in the describe group. In other words, it's performed in a
294
+ # before(:all) filter.
295
+ #
296
+ # == Examples
297
+ #
298
+ # #{verb} :action, :id => 42
299
+ #
300
+ def #{verb}(action=nil, params={}, &block)
301
+ #{verb.to_s.chop}(action, params) if action
302
+ write_inheritable_array(:before_all_block, [block]) if block
303
+ run_callbacks_once!
304
+ end
305
+ VERB
306
+ end
307
+
308
+ # Undefine the method run_callbacks so rspec won't run them in the
309
+ # before and after :each cycle. Then we redefine it as run_callbacks_once,
310
+ # which will be used as an before(:all) and after(:all) filter.
311
+ #
312
+ def run_callbacks_once!(&block) #:nodoc:
313
+ unless instance_methods.any?{|m| m.to_s == 'run_callbacks_once' }
314
+ alias_method :run_callbacks_once, :run_callbacks
315
+ class_eval "def run_callbacks(*args); end"
316
+
317
+ before(:all) do
318
+ setup_mocks_for_rspec
319
+ run_callbacks_once :setup
320
+
321
+ before_all_block.each do |block|
322
+ instance_eval(&block)
323
+ end if before_all_block
324
+
325
+ run_action!
326
+ verify_mocks_for_rspec
327
+ teardown_mocks_for_rspec
328
+ end
329
+
330
+ after(:all) do
331
+ run_callbacks_once :teardown
332
+ end
333
+ end
334
+ end
335
+
336
+ # Overwrites describe to provide quick action description with I18n.
337
+ #
338
+ # You can now do:
339
+ #
340
+ # describe :get => :show, :id => 37
341
+ #
342
+ # Which is the same as:
343
+ #
344
+ # describe 'responding to #GET show' do
345
+ # get :show, :id => 37
346
+ #
347
+ # And do this:
348
+ #
349
+ # describe Mime::XML
350
+ #
351
+ # Which is the same as:
352
+ #
353
+ # describe 'with xml' do
354
+ # mime Mime::XML
355
+ #
356
+ # The string can be localized using I18n. An example yml file is:
357
+ #
358
+ # locale:
359
+ # remarkable:
360
+ # action_controller:
361
+ # responding: "responding to #{{verb}} {{action}}"
362
+ # mime_type: "with {{format}} ({{content_type}})"
363
+ #
364
+ # And load the locale file with:
365
+ #
366
+ # Remarkable.add_locale locale_path
367
+ #
368
+ def describe(*args, &block)
369
+ options = args.first.is_a?(Hash) ? args.first : {}
370
+ verb = (options.keys & HTTP_VERBS_METHODS).first
371
+
372
+ if verb
373
+ action = options.delete(verb)
374
+ verb = verb.to_s
375
+
376
+ description = Remarkable.t 'remarkable.action_controller.responding',
377
+ :default => "responding to \#{{verb}} {{action}}",
378
+ :verb => verb.sub('!', '').upcase, :action => action
379
+
380
+ send_args = [ verb, action, options ]
381
+ elsif args.first.is_a?(Mime::Type)
382
+ mime = args.first
383
+
384
+ description = Remarkable.t 'remarkable.action_controller.mime_type',
385
+ :default => "with #{mime.to_sym}",
386
+ :format => mime.to_sym, :content_type => mime.to_s
387
+
388
+ send_args = [ :mime, mime ]
389
+ else # return if no special type was found
390
+ return super(*args, &block)
391
+ end
392
+
393
+ args.shift
394
+ args.unshift(description)
395
+
396
+ # Creates an example group, send the method and eval the given block.
397
+ #
398
+ example_group = super(*args) do
399
+ send(*send_args)
400
+ instance_eval(&block)
401
+ end
402
+ end
403
+
404
+ # Creates mock methods automatically.
405
+ #
406
406
  # == Options
407
407
  #
408
408
  # * <tt>:as</tt> - Used to set the model . For example, if you have
409
409
  # Admin::Task model, you have to tell the name of the class to be
410
410
  # mocked:
411
411
  #
412
- # mock_models :admin_task, :as => "Admin::Task"
413
- #
414
- # * <tt>:class_method</tt> - When set to false, does not create the
415
- # class method which returns a proc.
416
- #
417
- # == Examples
418
- #
419
- # Doing this:
420
- #
421
- # describe ProjectsController do
422
- # mock_models :project
423
- # end
424
- #
425
- # Will create one instance and two class mock methods for you:
426
- #
427
- # def self.project_proc
428
- # proc { mock_project }
412
+ # mock_models :admin_task, :as => "Admin::Task"
413
+ #
414
+ # * <tt>:class_method</tt> - When set to false, does not create the
415
+ # class method which returns a proc.
416
+ #
417
+ # == Examples
418
+ #
419
+ # Doing this:
420
+ #
421
+ # describe ProjectsController do
422
+ # mock_models :project
423
+ # end
424
+ #
425
+ # Will create one instance and two class mock methods for you:
426
+ #
427
+ # def self.project_proc
428
+ # proc { mock_project }
429
429
  # end
430
430
  #
431
431
  # # To be used on index actions
432
- # def self.projects_procs
433
- # proc { [ mock_project ] }
434
- # end
435
- #
436
- # def mock_project(stubs={})
437
- # @project ||= mock_model(Project, stubs)
432
+ # def self.projects_procs
433
+ # proc { [ mock_project ] }
438
434
  # end
439
- #
440
- # If you want to create just the instance method, you can give
441
- # :class_method => false as option.
442
- #
443
- def mock_models(*models)
444
- options = models.extract_options!
445
- options = { :class_method => true }.merge(options)
446
-
435
+ #
436
+ # def mock_project(stubs={})
437
+ # @project ||= mock_model(Project, stubs)
438
+ # end
439
+ #
440
+ # If you want to create just the instance method, you can give
441
+ # :class_method => false as option.
442
+ #
443
+ def mock_models(*models)
444
+ options = models.extract_options!
445
+ options = { :class_method => true }.merge(options)
446
+
447
447
  models.each do |model|
448
448
  model = model.to_s
449
449
  klass = options[:as] || model.classify
@@ -457,36 +457,36 @@ module Remarkable
457
457
  alias :mock_#{model.pluralize} :#{model.pluralize}_proc
458
458
  METHOD
459
459
  end
460
-
461
- self.class_eval <<-METHOD
462
- def mock_#{model}(stubs={})
463
- @#{model} ||= mock_model(#{klass}, stubs)
464
- end
465
- METHOD
466
- end
460
+
461
+ self.class_eval <<-METHOD
462
+ def mock_#{model}(stubs={})
463
+ @#{model} ||= mock_model(#{klass}, stubs)
464
+ end
465
+ METHOD
466
+ end
467
467
  end
468
- alias :mock_model :mock_models
469
-
470
- end
471
-
472
- protected
473
-
474
- # Evaluates the expectation chain as stub or expectations.
475
- #
476
- def evaluate_expectation_chain(use_expectations=true) #:nodoc:
477
- return if self.expects_chain.nil?
478
-
468
+ alias :mock_model :mock_models
469
+
470
+ end
471
+
472
+ protected
473
+
474
+ # Evaluates the expectation chain as stub or expectations.
475
+ #
476
+ def evaluate_expectation_chain(use_expectations=true) #:nodoc:
477
+ return if self.expects_chain.nil?
478
+
479
479
  self.expects_chain.each do |method, options, block|
480
- object = evaluate_value(options[:on])
481
- raise ScriptError, "You have to give me :on as an option when calling :expects." if object.nil?
482
-
483
- if use_expectations
480
+ object = evaluate_value(options[:on])
481
+ raise ScriptError, "You have to give me :on as an option when calling :expects." if object.nil?
482
+
483
+ if use_expectations
484
484
  chain = object.should_receive(method)
485
485
 
486
486
  if options.key?(:with)
487
487
  with = evaluate_value(options[:with])
488
488
 
489
- chain = if with.is_a?(Array)
489
+ chain = if with.is_a?(Array)
490
490
  chain.with(*with)
491
491
  else
492
492
  chain.with(with)
@@ -497,74 +497,76 @@ module Remarkable
497
497
  chain = chain.exactly(times).times
498
498
 
499
499
  chain = chain.ordered if options[:ordered]
500
- else
501
- chain = object.stub!(method)
500
+ else
501
+ chain = object.stub!(method)
502
502
  end
503
503
 
504
- chain = if block
504
+ chain = if block
505
505
  chain.and_return(&block)
506
506
  else
507
507
  return_value = evaluate_value(options[:returns])
508
508
  chain.and_return(return_value)
509
- end
510
- end
511
- end
512
-
513
- # Instance method run_stubs! if someone wants to declare additional
514
- # tests and call the stubs inside of it.
515
- #
516
- def run_stubs!
517
- evaluate_expectation_chain(false)
518
- end
519
-
520
- # Instance method run_expectations! if someone wants to declare
521
- # additional tests and call the stubs inside of it.
522
- #
523
- def run_expectations!
524
- evaluate_expectation_chain(true)
525
- end
526
-
527
- # Run the action declared in the describe group, but before runs also
528
- # the expectations. If an action was already performed, it doesn't run
529
- # anything at all and returns false.
530
- #
531
- # The first parameter is if you want to run expectations or stubs. You
532
- # can also supply the verb (get, post, put or delete), which action to
509
+ end
510
+ end
511
+ end
512
+
513
+ # Instance method run_stubs! if someone wants to declare additional
514
+ # tests and call the stubs inside of it.
515
+ #
516
+ def run_stubs!
517
+ evaluate_expectation_chain(false)
518
+ end
519
+
520
+ # Instance method run_expectations! if someone wants to declare
521
+ # additional tests and call the stubs inside of it.
522
+ #
523
+ def run_expectations!
524
+ evaluate_expectation_chain(true)
525
+ end
526
+
527
+ # Run the action declared in the describe group, but before runs also
528
+ # the expectations. If an action was already performed, it doesn't run
529
+ # anything at all and returns false.
530
+ #
531
+ # The first parameter is if you want to run expectations or stubs. You
532
+ # can also supply the verb (get, post, put or delete), which action to
533
533
  # call, parameters, the mime type and if a xhr should be performed. If
534
534
  # any of those parameters are supplied, they override the current
535
- # definition.
536
- #
537
- def run_action!(use_expectations=true, verb=nil, action=nil, params=nil, mime=nil, xhr=nil)
538
- return false if controller.send(:performed?)
539
-
540
- evaluate_expectation_chain(use_expectations)
541
-
542
- mime ||= default_mime
543
- verb ||= default_verb
544
- action ||= default_action
535
+ # definition.
536
+ #
537
+ def run_action!(use_expectations=true, verb=nil, action=nil, params=nil, mime=nil, xhr=nil)
538
+ return false if controller.send(:performed?)
539
+
540
+ evaluate_expectation_chain(use_expectations)
541
+
542
+ mime ||= default_mime
543
+ verb ||= default_verb
544
+ action ||= default_action
545
545
  params ||= default_params
546
- xhr ||= default_xhr
547
-
548
- raise ScriptError, "No action was performed or declared." unless verb && action
549
-
546
+ xhr ||= default_xhr
547
+
548
+ raise ScriptError, "No action was performed or declared." unless verb && action
549
+
550
550
  request.env["HTTP_ACCEPT"] ||= mime.to_s if mime
551
- request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' if xhr
552
- send(verb, action, params)
553
- end
554
-
555
- # Evaluate a given value.
556
- #
557
- # This allows procs to be given to the expectation chain and they will
558
- # be evaluated in the instance binding.
559
- #
560
- def evaluate_value(duck) #:nodoc:
561
- if duck.is_a?(Proc)
562
- self.instance_eval(&duck)
563
- else
564
- duck
565
- end
566
- end
567
-
568
- end
569
- end
570
- end
551
+ request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' if xhr
552
+ send(verb, action, params)
553
+ end
554
+
555
+ # Evaluate a given value.
556
+ #
557
+ # This allows procs to be given to the expectation chain and they will
558
+ # be evaluated in the instance binding.
559
+ #
560
+ def evaluate_value(duck) #:nodoc:
561
+ if duck.is_a?(Proc)
562
+ self.instance_eval(&duck)
563
+ elsif duck.is_a?(Array)
564
+ duck.map{|child_duck| evaluate_value(child_duck) }
565
+ else
566
+ duck
567
+ end
568
+ end
569
+
570
+ end
571
+ end
572
+ end