rspec-rails 2.8.0.rc1 → 2.8.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/License.txt +22 -0
  2. data/README.md +253 -119
  3. data/features/README.md +0 -2
  4. data/features/Upgrade.md +1 -1
  5. data/lib/generators/rspec/install/templates/spec/spec_helper.rb +1 -1
  6. data/lib/generators/rspec/integration/integration_generator.rb +1 -0
  7. data/lib/generators/rspec/scaffold/scaffold_generator.rb +1 -0
  8. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +23 -16
  9. data/lib/rspec/rails/adapters.rb +25 -13
  10. data/lib/rspec/rails/example/controller_example_group.rb +65 -122
  11. data/lib/rspec/rails/example/helper_example_group.rb +11 -36
  12. data/lib/rspec/rails/example/mailer_example_group.rb +1 -1
  13. data/lib/rspec/rails/example/rails_example_group.rb +5 -0
  14. data/lib/rspec/rails/example/request_example_group.rb +4 -19
  15. data/lib/rspec/rails/example/routing_example_group.rb +8 -10
  16. data/lib/rspec/rails/example/view_example_group.rb +21 -35
  17. data/lib/rspec/rails/extensions/active_record/base.rb +15 -12
  18. data/lib/rspec/rails/fixture_support.rb +1 -1
  19. data/lib/rspec/rails/matchers/be_a_new.rb +63 -30
  20. data/lib/rspec/rails/matchers/be_new_record.rb +18 -3
  21. data/lib/rspec/rails/matchers/have_extension.rb +26 -14
  22. data/lib/rspec/rails/matchers/redirect_to.rb +26 -7
  23. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  24. data/lib/rspec/rails/matchers/render_template.rb +27 -8
  25. data/lib/rspec/rails/matchers/routing_matchers.rb +72 -24
  26. data/lib/rspec/rails/mocks.rb +42 -34
  27. data/lib/rspec/rails/module_inclusion.rb +2 -1
  28. data/lib/rspec/rails/version.rb +1 -1
  29. data/lib/rspec/rails/view_assigns.rb +31 -34
  30. data/lib/rspec/rails/view_rendering.rb +10 -6
  31. data/spec/rspec/rails/example/controller_example_group_spec.rb +2 -2
  32. data/spec/rspec/rails/example/helper_example_group_spec.rb +5 -5
  33. data/spec/rspec/rails/example/view_example_group_spec.rb +5 -5
  34. data/spec/rspec/rails/matchers/be_a_new_spec.rb +2 -0
  35. data/spec/rspec/rails/matchers/be_new_record_spec.rb +2 -0
  36. data/spec/rspec/rails/matchers/render_template_spec.rb +3 -5
  37. data/spec/rspec/rails/mocks/mock_model_spec.rb +28 -0
  38. metadata +22 -19
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2006 David Chelimsky, The RSpec Development Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -2,34 +2,42 @@
2
2
 
3
3
  rspec-2 for rails-3 with lightweight extensions to each
4
4
 
5
- NOTE: Use rspec-rails-1.3.x for rails-2.
5
+ Note: Use [rspec-rails-1.3](http://github.com/dchelimsky/rspec-rails) for rails-2.
6
6
 
7
7
  ## Install
8
8
 
9
- gem install rspec-rails
9
+ ```
10
+ gem install rspec-rails
11
+ ```
10
12
 
11
13
  This installs the following gems:
12
14
 
13
- rspec
14
- rspec-core
15
- rspec-expectations
16
- rspec-mocks
17
- rspec-rails
15
+ ```
16
+ rspec
17
+ rspec-core
18
+ rspec-expectations
19
+ rspec-mocks
20
+ rspec-rails
21
+ ```
18
22
 
19
23
  ## Configure
20
24
 
21
25
  Add `rspec-rails` to the `:test` and `:development` groups in the Gemfile:
22
26
 
23
- group :test, :development do
24
- gem "rspec-rails", "~> 2.6"
25
- end
27
+ ```ruby
28
+ group :test, :development do
29
+ gem "rspec-rails", "~> 2.6"
30
+ end
31
+ ```
26
32
 
27
33
  It needs to be in the `:development` group to expose generators and rake
28
34
  tasks without having to type `RAILS_ENV=test`.
29
35
 
30
36
  Now you can run:
31
37
 
32
- rails generate rspec:install
38
+ ```
39
+ rails generate rspec:install
40
+ ```
33
41
 
34
42
  This adds the spec directory and some skeleton files, including
35
43
  the "rake spec" task.
@@ -43,20 +51,7 @@ controllers, etc, RSpec specs are generated instead of Test::Unit tests.
43
51
 
44
52
  Please note that the generators are there to help you get started, but they are
45
53
  no substitute for writing your own examples, and they are only guaranteed to
46
- work out of the box for the default scenario (`ActiveRecord` + `Webrat`).
47
-
48
- ### Autotest
49
-
50
- The `rspec:install` generator creates an `.rspec` file, which tells Autotest
51
- that you're using RSpec and Rails. You'll also need to add the ZenTest gem to
52
- your Gemfile:
53
-
54
- gem "ZenTest"
55
-
56
- At this point, if all of the gems in your Gemfile are installed in system
57
- gems, you can just type `autotest`. If, however, Bundler is managing any gems
58
- for you directly (i.e. you've got `:git` or `:path` attributes in the `Gemfile`),
59
- you'll need to run `bundle exec autotest`.
54
+ work out of the box for the default scenario (`ActiveRecord` & `Webrat`).
60
55
 
61
56
  ### Webrat and Capybara
62
57
 
@@ -64,8 +59,10 @@ You can choose between webrat or capybara for simulating a browser, automating
64
59
  a browser, or setting expectations using the matchers they supply. Just add
65
60
  your preference to the Gemfile:
66
61
 
67
- gem "webrat"
68
- gem "capybara"
62
+ ```ruby
63
+ gem "webrat"
64
+ gem "capybara"
65
+ ```
69
66
 
70
67
  ## Living on edge
71
68
 
@@ -73,11 +70,13 @@ Bundler makes it a snap to use the latest code for any gem your app depends on.
73
70
  rspec-rails, you'll need to point bundler to the git repositories for `rspec-rails`
74
71
  and the other rspec related gems it depends on:
75
72
 
76
- gem "rspec-rails", :git => "git://github.com/rspec/rspec-rails.git"
77
- gem "rspec", :git => "git://github.com/rspec/rspec.git"
78
- gem "rspec-core", :git => "git://github.com/rspec/rspec-core.git"
79
- gem "rspec-expectations", :git => "git://github.com/rspec/rspec-expectations.git"
80
- gem "rspec-mocks", :git => "git://github.com/rspec/rspec-mocks.git"
73
+ ```ruby
74
+ gem "rspec-rails", :git => "git://github.com/rspec/rspec-rails.git"
75
+ gem "rspec", :git => "git://github.com/rspec/rspec.git"
76
+ gem "rspec-core", :git => "git://github.com/rspec/rspec-core.git"
77
+ gem "rspec-expectations", :git => "git://github.com/rspec/rspec-expectations.git"
78
+ gem "rspec-mocks", :git => "git://github.com/rspec/rspec-mocks.git"
79
+ ```
81
80
 
82
81
  Run `bundle install` and you'll have whatever is in git right now. Any time you
83
82
  want to update to a newer head, just run `bundle update`.
@@ -103,14 +102,16 @@ See http://github.com/rspec/rspec-rails/issues
103
102
 
104
103
  Request specs live in spec/requests.
105
104
 
106
- describe "widgets resource" do
107
- describe "GET index" do
108
- it "contains the widgets header" do
109
- get "/widgets/index"
110
- response.should have_selector("h1", :content => "Widgets")
111
- end
112
- end
105
+ ```ruby
106
+ describe "widgets resource" do
107
+ describe "GET index" do
108
+ it "contains the widgets header" do
109
+ get "/widgets/index"
110
+ response.should have_selector("h1", :content => "Widgets")
113
111
  end
112
+ end
113
+ end
114
+ ```
114
115
 
115
116
  Request specs mix in behavior from Rails' integration tests. See the
116
117
  docs for ActionDispatch::Integration::Runner for more information.
@@ -118,25 +119,91 @@ docs for ActionDispatch::Integration::Runner for more information.
118
119
  # Controller Specs
119
120
 
120
121
  Controller specs live in spec/controllers, and mix in
121
- ActionController::TestCase::Behavior. See the documentation
122
- for ActionController::TestCase to see what facilities are
123
- available from Rails.
122
+ ActionController::TestCase::Behavior, which is the basis for Rails' functional
123
+ tests.
124
124
 
125
- You can use RSpec expectations/matchers or Test::Unit assertions.
125
+ ## with fixtures
126
+
127
+ ```ruby
128
+ describe WidgetsController do
129
+ describe "GET index" do
130
+ fixtures :widgets
131
+
132
+ it "assigns all widgets to @widgets" do
133
+ get :index
134
+ assigns(:widgets).should eq(Widget.all)
135
+ end
136
+ end
137
+ end
138
+ ```
139
+
140
+ ## with a factory
141
+
142
+ ```ruby
143
+ describe WidgetsController do
144
+ describe "GET index" do
145
+ it "assigns all widgets to @widgets" do
146
+ widget = Factory(:widget)
147
+ get :index
148
+ assigns(:widgets).should eq([widget])
149
+ end
150
+ end
151
+ end
152
+ ```
153
+
154
+ ## with stubs
155
+
156
+ ```ruby
157
+ describe WidgetsController do
158
+ describe "GET index" do
159
+ it "assigns all widgets to @widgets" do
160
+ widget = stub_model(Widget)
161
+ Widget.stub(:all) { [widget] }
162
+ get :index
163
+ assigns(:widgets).should eq([widget])
164
+ end
165
+ end
166
+ end
167
+ ```
168
+
169
+ ## matchers
170
+
171
+ In addition to the stock matchers from rspec-expectations, controller
172
+ specs add these matchers, which delegate to rails' assertions:
173
+
174
+ ```ruby
175
+ response.should render_template(*args)
176
+ # => delegates to assert_template(*args)
177
+
178
+ response.should redirect_to(destination)
179
+ # => delegates to assert_redirected_to(destination)
180
+ ```
181
+
182
+ ## isolation from views
183
+
184
+ RSpec's preferred approach to spec'ing controller behaviour is to isolate
185
+ the controller from its collaborators. By default, therefore, controller
186
+ example groups do not render the views in your app. Due to the way Rails
187
+ searches for view templates, the template still needs to exist, but it
188
+ won't actually be loaded.
189
+
190
+ NOTE that this is different from rspec-rails-1 with rails-2, which did not
191
+ require the presence of the file at all. Due to changes in rails-3, this
192
+ was no longer feasible in rspec-rails-2.
126
193
 
127
194
  ## `render_views`
128
- By default, controller specs do not render views. This supports specifying
129
- controllers without concern for whether the views they render work correctly
130
- (NOTE: the template must exist, unlike rspec-rails-1. See Upgrade.md for more
131
- information about this). If you prefer to render the views (a la Rails'
132
- functional tests), you can use the `render_views` declaration in each example
133
- group:
134
195
 
135
- describe SomeController do
136
- render_views
137
- ...
196
+ If you prefer a more integrated approach, similar to that of Rails'
197
+ functional tests, you can tell controller groups to render the views in the
198
+ app with the `render_views` declaration:
138
199
 
139
- ### * Upgrade note
200
+ ```ruby
201
+ describe WidgetsController do
202
+ render_views
203
+ # ...
204
+ ```
205
+
206
+ ### Upgrade note
140
207
 
141
208
  `render_views` replaces `integrate_views` from rspec-rails-1.3
142
209
 
@@ -145,36 +212,42 @@ group:
145
212
  Use `assigns(key)` to express expectations about instance variables that a controller
146
213
  assigns to the view in the course of an action:
147
214
 
148
- get :index
149
- assigns(:widgets).should eq(expected_value)
215
+ ```ruby
216
+ get :index
217
+ assigns(:widgets).should eq(expected_value)
218
+ ```
150
219
 
151
220
  # View specs
152
221
 
153
222
  View specs live in spec/views, and mix in ActionView::TestCase::Behavior.
154
223
 
155
- describe "events/index.html.erb" do
156
- it "renders _event partial for each event" do
157
- assign(:events, [stub_model(Event), stub_model(Event)])
158
- render
159
- view.should render_template(:partial => "_event", :count => 2)
160
- end
161
- end
162
-
163
- describe "events/show.html.erb" do
164
- it "displays the event location" do
165
- assign(:event, stub_model(Event,
166
- :location => "Chicago"
167
- )
168
- render
169
- rendered.should contain("Chicago")
170
- end
171
- end
224
+ ```ruby
225
+ describe "events/index.html.erb" do
226
+ it "renders _event partial for each event" do
227
+ assign(:events, [stub_model(Event), stub_model(Event)])
228
+ render
229
+ view.should render_template(:partial => "_event", :count => 2)
230
+ end
231
+ end
232
+
233
+ describe "events/show.html.erb" do
234
+ it "displays the event location" do
235
+ assign(:event, stub_model(Event,
236
+ :location => "Chicago"
237
+ ))
238
+ render
239
+ rendered.should contain("Chicago")
240
+ end
241
+ end
242
+ ```
172
243
 
173
244
  View specs infer the controller name and path from the path to the view
174
245
  template. e.g. if the template is "events/index.html.erb" then:
175
246
 
176
- controller.controller_path == "events"
177
- controller.request.path_parameters[:controller] == "events"
247
+ ```ruby
248
+ controller.controller_path == "events"
249
+ controller.request.path_parameters[:controller] == "events"
250
+ ```
178
251
 
179
252
  This means that most of the time you don't need to set these values. When
180
253
  spec'ing a partial that is included across different controllers, you _may_
@@ -183,14 +256,18 @@ need to override these values before rendering the view.
183
256
  To provide a layout for the render, you'll need to specify _both_ the template
184
257
  and the layout explicitly. For example:
185
258
 
186
- render :template => "events/show", :layout => "layouts/application"
259
+ ```ruby
260
+ render :template => "events/show", :layout => "layouts/application"
261
+ ```
187
262
 
188
263
  ## `assign(key, val)`
189
264
 
190
265
  Use this to assign values to instance variables in the view:
191
266
 
192
- assign(:widget, stub_model(Widget))
193
- render
267
+ ```ruby
268
+ assign(:widget, stub_model(Widget))
269
+ render
270
+ ```
194
271
 
195
272
  The code above assigns `stub_model(Widget)` to the `@widget` variable in the view, and then
196
273
  renders the view.
@@ -200,47 +277,92 @@ instance variables you set will be transparently propagated into your views
200
277
  (similar to how instance variables you set in controller actions are made
201
278
  available in views). For example:
202
279
 
203
- @widget = stub_model(Widget)
204
- render # @widget is available inside the view
280
+ ```ruby
281
+ @widget = stub_model(Widget)
282
+ render # @widget is available inside the view
283
+ ```
205
284
 
206
285
  RSpec doesn't officially support this pattern, which only works as a
207
286
  side-effect of the inclusion of `ActionView::TestCase`. Be aware that it may be
208
287
  made unavailable in the future.
209
288
 
210
- ### * Upgrade note
289
+ ### Upgrade note
211
290
 
212
- `assign(key, value)` replaces `assigns[key] = value` from rspec-rails-1.3
291
+ ```ruby
292
+ # rspec-rails-1.x
293
+ assigns[key] = value
294
+
295
+ # rspec-rails-2.x
296
+ assign(key, value)
297
+ ```
213
298
 
214
299
  ## `rendered`
215
300
 
216
301
  This represents the rendered view.
217
302
 
218
- render
219
- rendered.should =~ /Some text expected to appear on the page/
303
+ ```ruby
304
+ render
305
+ rendered.should =~ /Some text expected to appear on the page/
306
+ ```
307
+
308
+ ### Upgrade note
309
+
310
+ ```ruby
311
+ # rspec-rails-1.x
312
+ render
313
+ response.should xxx
314
+
315
+ # rspec-rails-2.x
316
+ render
317
+ rendered.should xxx
318
+ ```
220
319
 
221
- ### * Upgrade note
320
+ # Model specs
222
321
 
223
- `rendered` replaces `response` from rspec-rails-1.3
322
+ Model specs live in spec/models.
323
+
324
+ ```ruby
325
+ describe Articles do
326
+ describe ".recent" do
327
+ it "includes articles published less than one week ago" do
328
+ article = Article.create!(:published_at => Date.today - 1.week + 1.second)
329
+ Article.recent.should eq([article])
330
+ end
331
+
332
+ it "excludes articles published at midnight one week ago" do
333
+ article = Article.create!(:published_at => Date.today - 1.week)
334
+ Article.recent.should be_empty
335
+ end
336
+
337
+ it "excludes articles published more than one week ago" do
338
+ article = Article.create!(:published_at => Date.today - 1.week - 1.second)
339
+ Article.recent.should be_empty
340
+ end
341
+ end
342
+ end
343
+ ```
224
344
 
225
345
  # Routing specs
226
346
 
227
347
  Routing specs live in spec/routing.
228
348
 
229
- describe "routing to profiles" do
230
- it "routes /profile/:username to profile#show for username" do
231
- { :get => "/profiles/jsmith" }.should route_to(
232
- :controller => "profiles",
233
- :action => "show",
234
- :username => "jsmith"
235
- )
236
- end
237
-
238
- it "does not expose a list of profiles" do
239
- { :get => "/profiles" }.should_not be_routable
240
- end
241
- end
349
+ ```ruby
350
+ describe "routing to profiles" do
351
+ it "routes /profile/:username to profile#show for username" do
352
+ { :get => "/profiles/jsmith" }.should route_to(
353
+ :controller => "profiles",
354
+ :action => "show",
355
+ :username => "jsmith"
356
+ )
357
+ end
242
358
 
243
- ### * Upgrade note
359
+ it "does not expose a list of profiles" do
360
+ { :get => "/profiles" }.should_not be_routable
361
+ end
362
+ end
363
+ ```
364
+
365
+ ### Upgrade note
244
366
 
245
367
  `route_for` from rspec-rails-1.x is gone. Use `route_to` and `be_routable` instead.
246
368
 
@@ -248,16 +370,21 @@ Routing specs live in spec/routing.
248
370
 
249
371
  Helper specs live in spec/helpers, and mix in ActionView::TestCase::Behavior.
250
372
 
251
- describe EventsHelper do
252
- describe "#link_to_event" do
253
- it "displays the title, and formatted date" do
254
- event = Event.new("Ruby Kaigi", Date.new(2010, 8, 27))
255
- # helper is an instance of ActionView::Base configured with the
256
- # EventsHelper and all of Rails' built-in helpers
257
- helper.link_to_event.should =~ /Ruby Kaigi, 27 Aug, 2010/
258
- end
259
- end
373
+ Provides a `helper` object which mixes in the helper module being spec'd, along
374
+ with `ApplicationHelper` (if present).
375
+
376
+ ```ruby
377
+ describe EventsHelper do
378
+ describe "#link_to_event" do
379
+ it "displays the title, and formatted date" do
380
+ event = Event.new("Ruby Kaigi", Date.new(2010, 8, 27))
381
+ # helper is an instance of ActionView::Base configured with the
382
+ # EventsHelper and all of Rails' built-in helpers
383
+ helper.link_to_event.should =~ /Ruby Kaigi, 27 Aug, 2010/
260
384
  end
385
+ end
386
+ end
387
+ ```
261
388
 
262
389
  # Matchers
263
390
 
@@ -268,9 +395,10 @@ of them simply delegate to Rails' assertions.
268
395
  * Available in all specs.
269
396
  * Primarily intended for controller specs
270
397
 
271
- <pre>
398
+ ```ruby
272
399
  object.should be_a_new(Widget)
273
- </pre>
400
+ ```
401
+
274
402
 
275
403
  Passes if the object is a `Widget` and returns true for `new_record?`
276
404
 
@@ -280,41 +408,47 @@ Passes if the object is a `Widget` and returns true for `new_record?`
280
408
 
281
409
  In request and controller specs, apply to the response object:
282
410
 
283
- response.should render_template("new")
411
+ ```ruby
412
+ response.should render_template("new")
413
+ ```
284
414
 
285
415
  In view specs, apply to the view object:
286
416
 
287
- view.should render_template(:partial => "_form", :locals => { :widget => widget } )
417
+ ```ruby
418
+ view.should render_template(:partial => "_form", :locals => { :widget => widget } )
419
+ ```
288
420
 
289
421
  ## `redirect_to`
290
422
  * Delegates to assert_redirect
291
423
  * Available in request and controller specs.
292
424
 
293
- <pre>
425
+ ```ruby
294
426
  response.should redirect_to(widgets_path)
295
- </pre>
427
+ ```
296
428
 
297
429
  ## `route_to`
298
430
 
299
431
  * Delegates to Rails' assert_routing.
300
432
  * Available in routing and controller specs.
301
433
 
302
- <pre>
434
+ ```ruby
303
435
  { :get => "/widgets" }.should route_to(:controller => "widgets", :action => "index")
304
- </pre>
436
+ ```
305
437
 
306
438
  ## `be_routable`
307
439
 
308
440
  Passes if the path is recognized by Rails' routing. This is primarily intended
309
441
  to be used with `should_not` to specify routes that should not be routable.
310
442
 
311
- { :get => "/widgets/1/edit" }.should_not be_routable
443
+ ```ruby
444
+ { :get => "/widgets/1/edit" }.should_not be_routable
445
+ ```
312
446
 
313
- ## Contribute
447
+ # Contribute
314
448
 
315
449
  See [http://github.com/rspec/rspec-dev](http://github.com/rspec/rspec-dev)
316
450
 
317
- ## Also see
451
+ # Also see
318
452
 
319
453
  * [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
320
454
  * [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core)