rspec-rails 2.6.1 → 2.7.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. data/README.md +5 -5
  2. data/features/Transactions.md +84 -0
  3. data/features/controller_specs/Cookies.md +57 -0
  4. data/features/controller_specs/anonymous_controller.feature +104 -61
  5. data/features/controller_specs/bypass_rescue.feature +75 -0
  6. data/features/matchers/relation_match_array.feature +20 -0
  7. data/features/mocks/mock_model.feature +6 -6
  8. data/features/support/env.rb +2 -2
  9. data/features/view_specs/view_spec.feature +2 -8
  10. data/lib/autotest/rails_rspec2.rb +1 -1
  11. data/lib/generators/rspec/controller/templates/controller_spec.rb +1 -1
  12. data/lib/generators/rspec/install/templates/spec/spec_helper.rb +6 -0
  13. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +6 -6
  14. data/lib/generators/rspec/view/templates/view_spec.rb +1 -1
  15. data/lib/rspec/rails/example/controller_example_group.rb +19 -1
  16. data/lib/rspec/rails/fixture_support.rb +11 -0
  17. data/lib/rspec/rails/matchers.rb +1 -0
  18. data/lib/rspec/rails/matchers/relation_match_array.rb +3 -0
  19. data/lib/rspec/rails/matchers/routing_matchers.rb +16 -14
  20. data/lib/rspec/rails/mocks.rb +12 -7
  21. data/lib/rspec/rails/version.rb +1 -1
  22. data/spec/generators/rspec/controller/controller_generator_spec.rb +86 -0
  23. data/spec/generators/rspec/helper/helper_generator_spec.rb +30 -0
  24. data/spec/generators/rspec/install/install_generator_spec.rb +18 -0
  25. data/spec/generators/rspec/integration/integration_generator_spec.rb +44 -0
  26. data/spec/generators/rspec/mailer/mailer_generator_spec.rb +48 -0
  27. data/spec/generators/rspec/model/model_generator_spec.rb +52 -0
  28. data/spec/generators/rspec/observer/observer_generator_spec.rb +21 -0
  29. data/spec/generators/rspec/scaffold/scaffold_generator_spec.rb +113 -0
  30. data/spec/generators/rspec/view/view_generator_spec.rb +41 -0
  31. data/spec/rspec/rails/example/controller_example_group_spec.rb +39 -3
  32. data/spec/rspec/rails/matchers/relation_match_array_spec.rb +19 -0
  33. data/spec/rspec/rails/matchers/route_to_spec.rb +25 -3
  34. data/spec/rspec/rails/mocks/mock_model_spec.rb +62 -2
  35. data/spec/rspec/rails/mocks/stub_model_spec.rb +0 -1
  36. data/spec/spec_helper.rb +2 -1
  37. data/spec/{rspec/rails/mocks → support}/ar_classes.rb +5 -2
  38. metadata +102 -99
  39. data/.document +0 -5
  40. data/.gitignore +0 -14
  41. data/.rspec +0 -1
  42. data/.travis.yml +0 -11
  43. data/History.md +0 -1
  44. data/License.txt +0 -23
  45. data/README_DEV.md +0 -43
  46. data/Rakefile +0 -152
  47. data/Thorfile +0 -45
  48. data/Upgrade.md +0 -1
  49. data/cucumber.yml +0 -3
  50. data/features/.nav +0 -35
  51. data/features/Changelog.md +0 -162
  52. data/gemfiles/.bundle/config +0 -2
  53. data/gemfiles/base.rb +0 -60
  54. data/gemfiles/rails-3-0-stable +0 -6
  55. data/gemfiles/rails-3.0.0 +0 -5
  56. data/gemfiles/rails-3.0.1 +0 -5
  57. data/gemfiles/rails-3.0.2 +0 -5
  58. data/gemfiles/rails-3.0.3 +0 -5
  59. data/gemfiles/rails-3.0.4 +0 -5
  60. data/gemfiles/rails-3.0.5 +0 -5
  61. data/gemfiles/rails-3.0.6 +0 -5
  62. data/gemfiles/rails-3.0.7 +0 -5
  63. data/gemfiles/rails-3.1.0.rc1 +0 -5
  64. data/gemfiles/rails-master +0 -5
  65. data/rspec-rails.gemspec +0 -34
  66. data/templates/generate_stuff.rb +0 -21
  67. data/templates/run_specs.rb +0 -9
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  rspec-2 for rails-3 with lightweight extensions to each
4
4
 
5
- [![build status](http://travis-ci.org/rspec/rspec-rails.png)](http://travis-ci.org/rspec/rspec-rails)
5
+ [![build status](https://secure.travis-ci.org/rspec/rspec-rails.png)](http://travis-ci.org/rspec/rspec-rails)
6
6
 
7
7
  NOTE: rspec-2 does _not_ support rails-2. Use rspec-rails-1.3.x for rails-2.
8
8
 
@@ -36,18 +36,18 @@ This installs the following gems:
36
36
  Add `rspec-rails` to the `:test` and `:development` groups in the Gemfile:
37
37
 
38
38
  group :test, :development do
39
- gem "rspec-rails", "~> 2.4"
39
+ gem "rspec-rails", "~> 2.6"
40
40
  end
41
41
 
42
42
  It needs to be in the `:development` group to expose generators and rake
43
43
  tasks without having to type `RAILS_ENV=test`.
44
44
 
45
- Now you can run:
45
+ Now you can run:
46
46
 
47
- script/rails generate rspec:install
47
+ rails g rspec:install
48
48
 
49
49
  This adds the spec directory and some skeleton files, including
50
- the "rake spec" task.
50
+ the "rake spec" task.
51
51
 
52
52
  ### Generators
53
53
 
@@ -0,0 +1,84 @@
1
+ When you run `rails generate rspec:install`, the `spec/spec_helper.rb` file
2
+ includes the following configuration:
3
+
4
+ RSpec.configure do |config|
5
+ config.use_transactional_fixtures = true
6
+ end
7
+
8
+ The name of this setting is a bit misleading. What it really means in Rails
9
+ is "run every test method within a transaction." In the context of rspec-rails,
10
+ it means "run every example within a transaction."
11
+
12
+ The idea is to start each example with a clean database, create whatever data
13
+ is necessary for that example, and then remove that data by simply rolling back
14
+ the transaction at the end of the example.
15
+
16
+ ### Disabling transactions
17
+
18
+ If you prefer to manage the data yourself, or using another tool like
19
+ [database_cleaner](https://github.com/bmabey/database_cleaner) to do it for you,
20
+ simply tell RSpec to tell Rails not to manage transactions:
21
+
22
+ RSpec.configure do |config|
23
+ config.use_transactional_fixtures = false
24
+ end
25
+
26
+ ### Data created in `before(:each)` are rolled back
27
+
28
+ Any data you create in a `before(:each)` hook will be rolled back at the end of
29
+ the example. This is a good thing because it means that each example is
30
+ isolated from state that would otherwise be left around by the examples that
31
+ already ran. For example:
32
+
33
+ describe Widget do
34
+ before(:each) do
35
+ @widget = Widget.create
36
+ end
37
+
38
+ it "does something" do
39
+ @widget.should do_something
40
+ end
41
+
42
+ it "does something else" do
43
+ @widget.should do_something_else
44
+ end
45
+ end
46
+
47
+ The `@widget` is recreated in each of the two examples above, so each example
48
+ has a different object, _and_ the underlying data is rolled back so the data
49
+ backing the `@widget` in each example is new.
50
+
51
+ ### Data created in `before(:all)` are _not_ rolled back
52
+
53
+ `before(:all)` hooks are invoked before the transaction is opened. You can use
54
+ this to speed things up by creating data once before any example in a group is
55
+ run, however, this introduces a number of complications and you should only do
56
+ this if you have a firm grasp of the implications. Here are a couple of
57
+ guidelines:
58
+
59
+ 1. Be sure to clean up any data in an `after(:all)` hook:
60
+
61
+ before(:all) do
62
+ @widget = Widget.create!
63
+ end
64
+
65
+ after(:all) do
66
+ @widget.destroy
67
+ end
68
+
69
+ If you don't do that, you'll leave data lying around that will eventually
70
+ interfere with other examples.
71
+
72
+ 2. Reload the object in a `before(:each)` hook.
73
+
74
+ before(:all) do
75
+ @widget = Widget.create!
76
+ end
77
+
78
+ before(:each) do
79
+ @widget.reload
80
+ end
81
+
82
+ Even though database updates in each example will be rolled back, the
83
+ object won't _know_ about those rollbacks so the object and its backing
84
+ data can easily get out of sync.
@@ -0,0 +1,57 @@
1
+ Controller specs wrap Rails controller tests, which expose a few different ways
2
+ to access cookies:
3
+
4
+ @request.cookies['key']
5
+ @response.cookies['key']
6
+ cookies['key']
7
+
8
+ rails-3.0.x and 3.1 handle these slightly differently, so to avoid confusion, we recommend
9
+ the following guidelines:
10
+
11
+ ### Recommended guidelines for rails-3.0.0 to 3.1.0
12
+
13
+ * Access cookies through the `request` and `response` objects in the spec.
14
+ * Use `request.cookies` before the action to set up state.
15
+ * Use `response.cookies` after the action to specify outcomes.
16
+ * Use the `cookies` object in the controller action.
17
+ * Use String keys.
18
+
19
+ <pre>
20
+ # spec
21
+ request.cookies['foo'] = 'bar'
22
+ get :some_action
23
+ response.cookies['foo'].should eq('modified bar')
24
+
25
+ # controller
26
+ def some_action
27
+ cookies['foo'] = "modified #{cookies['foo']}"
28
+ end
29
+ </pre>
30
+
31
+ #### Why use Strings instead of Symbols?
32
+
33
+ The `cookies` objects in the spec come from Rack, and do not support
34
+ indifferent access (i.e. `:foo` and `"foo"` are different keys). The `cookies`
35
+ object in the controller _does_ support indifferent access, which is a bit
36
+ confusing.
37
+
38
+ This changed in rails-3.1, so you _can_ use symbol keys, but we recommend
39
+ sticking with string keys for consistency.
40
+
41
+ #### Why not use the `cookies` method?
42
+
43
+ The `cookies` method combines the `request` and `response` cookies. This can
44
+ lead to confusion when setting cookies in the example in order to set up state
45
+ for the controller action.
46
+
47
+ # does not work in rails 3.0.0 > 3.1.0
48
+ cookies['foo'] = 'bar' # this is not visible in the controller
49
+ get :some_action
50
+
51
+ ### Future versions of Rails
52
+
53
+ There is code in the master branch in rails that makes cookie access more
54
+ consistent so you can use the same `cookies` object before and after the action,
55
+ and you can use String or Symbol keys. We'll update these docs accordingly when
56
+ that is released.
57
+
@@ -1,109 +1,152 @@
1
1
  Feature: anonymous controller
2
2
 
3
3
  Use the `controller` method to define an anonymous controller derived from
4
- ApplicationController, or any other base controller. This is useful for
5
- specifying behavior like global error handling.
4
+ `ApplicationController`. This is useful for specifying behavior like global
5
+ error handling.
6
+
7
+ To specify a different base class, you can pass the class explicitly to the
8
+ controller method:
9
+
10
+ controller(BaseController)
11
+
12
+ You can also configure RSpec to use the described class:
13
+
14
+ RSpec.configure do |c|
15
+ c.infer_base_class_for_anonymous_controllers = true
16
+ end
17
+
18
+ describe BaseController do
19
+ controller { ... }
20
+ # ^^ creates an anonymous subclass of `BaseController`
6
21
 
7
22
  Scenario: specify error handling in ApplicationController
8
23
  Given a file named "spec/controllers/application_controller_spec.rb" with:
9
- """
10
- require "spec_helper"
24
+ """
25
+ require "spec_helper"
11
26
 
12
- class ApplicationController < ActionController::Base
13
- class AccessDenied < StandardError; end
27
+ class ApplicationController < ActionController::Base
28
+ class AccessDenied < StandardError; end
14
29
 
15
- rescue_from AccessDenied, :with => :access_denied
30
+ rescue_from AccessDenied, :with => :access_denied
16
31
 
17
- private
32
+ private
18
33
 
19
- def access_denied
20
- redirect_to "/401.html"
34
+ def access_denied
35
+ redirect_to "/401.html"
36
+ end
21
37
  end
22
- end
23
38
 
24
- describe ApplicationController do
25
- controller do
26
- def index
27
- raise ApplicationController::AccessDenied
39
+ describe ApplicationController do
40
+ controller do
41
+ def index
42
+ raise ApplicationController::AccessDenied
43
+ end
28
44
  end
29
- end
30
45
 
31
- describe "handling AccessDenied exceptions" do
32
- it "redirects to the /401.html page" do
33
- get :index
34
- response.should redirect_to("/401.html")
46
+ describe "handling AccessDenied exceptions" do
47
+ it "redirects to the /401.html page" do
48
+ get :index
49
+ response.should redirect_to("/401.html")
50
+ end
35
51
  end
36
52
  end
37
- end
38
- """
53
+ """
39
54
  When I run `rspec spec`
40
55
  Then the examples should all pass
41
56
 
42
57
  Scenario: specify error handling in subclass of ApplicationController
43
58
  Given a file named "spec/controllers/application_controller_subclass_spec.rb" with:
44
- """
45
- require "spec_helper"
59
+ """
60
+ require "spec_helper"
46
61
 
47
- class ApplicationController < ActionController::Base
48
- class AccessDenied < StandardError; end
49
- end
62
+ class ApplicationController < ActionController::Base
63
+ class AccessDenied < StandardError; end
64
+ end
50
65
 
51
- class ApplicationControllerSubclass < ApplicationController
66
+ class ApplicationControllerSubclass < ApplicationController
52
67
 
53
- rescue_from ApplicationController::AccessDenied, :with => :access_denied
68
+ rescue_from ApplicationController::AccessDenied, :with => :access_denied
54
69
 
55
70
  private
56
71
 
57
- def access_denied
58
- redirect_to "/401.html"
72
+ def access_denied
73
+ redirect_to "/401.html"
74
+ end
59
75
  end
60
- end
61
76
 
62
- describe ApplicationControllerSubclass do
63
- controller(ApplicationControllerSubclass) do
64
- def index
65
- raise ApplicationController::AccessDenied
77
+ describe ApplicationControllerSubclass do
78
+ controller(ApplicationControllerSubclass) do
79
+ def index
80
+ raise ApplicationController::AccessDenied
81
+ end
82
+ end
83
+
84
+ describe "handling AccessDenied exceptions" do
85
+ it "redirects to the /401.html page" do
86
+ get :index
87
+ response.should redirect_to("/401.html")
88
+ end
66
89
  end
67
90
  end
91
+ """
92
+ When I run `rspec spec`
93
+ Then the examples should all pass
68
94
 
69
- describe "handling AccessDenied exceptions" do
70
- it "redirects to the /401.html page" do
71
- get :index
72
- response.should redirect_to("/401.html")
95
+ Scenario: infer base class from the described class
96
+ Given a file named "spec/controllers/base_class_can_be_inferred_spec.rb" with:
97
+ """
98
+ require "spec_helper"
99
+
100
+ RSpec.configure do |c|
101
+ c.infer_base_class_for_anonymous_controllers = true
102
+ end
103
+
104
+ class ApplicationController < ActionController::Base; end
105
+
106
+ class ApplicationControllerSubclass < ApplicationController; end
107
+
108
+ describe ApplicationControllerSubclass do
109
+ controller do
110
+ def index
111
+ render :text => "Hello World"
112
+ end
113
+ end
114
+
115
+ it "creates an anonymous controller derived from ApplicationControllerSubclass" do
116
+ controller.should be_a_kind_of(ApplicationControllerSubclass)
73
117
  end
74
118
  end
75
- end
76
- """
119
+ """
77
120
  When I run `rspec spec`
78
121
  Then the examples should all pass
79
122
 
80
- Scenario: regression with ApplicationController around_filters
123
+ Scenario: invoke around filter in base class
81
124
  Given a file named "spec/controllers/application_controller_around_filter_spec.rb" with:
82
- """
83
- require "spec_helper"
125
+ """
126
+ require "spec_helper"
84
127
 
85
- class ApplicationController < ActionController::Base
86
- around_filter :some_around_filter
128
+ class ApplicationController < ActionController::Base
129
+ around_filter :an_around_filter
87
130
 
88
- def some_around_filter
89
- @callback_invoked = true
90
- yield
131
+ def an_around_filter
132
+ @callback_invoked = true
133
+ yield
134
+ end
91
135
  end
92
- end
93
136
 
94
- describe ApplicationController do
95
- controller do
96
- def index
97
- render :nothing => true
137
+ describe ApplicationController do
138
+ controller do
139
+ def index
140
+ render :nothing => true
141
+ end
98
142
  end
99
- end
100
143
 
101
- it "invokes the callback" do
102
- get :index
144
+ it "invokes the callback" do
145
+ get :index
103
146
 
104
- assigns[:callback_invoked].should be_true
147
+ assigns[:callback_invoked].should be_true
148
+ end
105
149
  end
106
- end
107
- """
150
+ """
108
151
  When I run `rspec spec`
109
152
  Then the examples should all pass
@@ -0,0 +1,75 @@
1
+ Feature: bypass rescue
2
+
3
+ Use `bypass_rescue` to bypass both Rails' default handling of errors in
4
+ controller actions, and any custom handling declared with a `rescue_from`
5
+ statement.
6
+
7
+ This lets you specify details of the exception being raised, regardless of
8
+ how it might be handled upstream.
9
+
10
+ Background:
11
+ Given a file named "spec/controllers/gadgets_controller_spec_context.rb" with:
12
+ """
13
+ class AccessDenied < StandardError; end
14
+
15
+ class ApplicationController < ActionController::Base
16
+ rescue_from AccessDenied, :with => :access_denied
17
+
18
+ private
19
+
20
+ def access_denied
21
+ redirect_to "/401.html"
22
+ end
23
+ end
24
+ """
25
+
26
+ Scenario: standard exception handling using `rescue_from`
27
+ Given a file named "spec/controllers/gadgets_controller_spec.rb" with:
28
+ """
29
+ require "spec_helper"
30
+
31
+ require 'controllers/gadgets_controller_spec_context'
32
+
33
+ describe GadgetsController do
34
+ before do
35
+ def controller.index
36
+ raise AccessDenied
37
+ end
38
+ end
39
+
40
+ describe "index" do
41
+ it "redirects to the /401.html page" do
42
+ get :index
43
+ response.should redirect_to("/401.html")
44
+ end
45
+ end
46
+ end
47
+ """
48
+ When I run `rspec spec/controllers/gadgets_controller_spec.rb`
49
+ Then the examples should all pass
50
+
51
+ Scenario: bypass `rescue_from` handling with `bypass_rescue`
52
+ Given a file named "spec/controllers/gadgets_controller_spec.rb" with:
53
+ """
54
+ require "spec_helper"
55
+
56
+ require 'controllers/gadgets_controller_spec_context'
57
+
58
+ describe GadgetsController do
59
+ before do
60
+ def controller.index
61
+ raise AccessDenied
62
+ end
63
+ end
64
+
65
+ describe "index" do
66
+ it "raises AccessDenied" do
67
+ bypass_rescue
68
+ expect { get :index }.to raise_error(AccessDenied)
69
+ end
70
+ end
71
+ end
72
+ """
73
+ When I run `rspec spec/controllers/gadgets_controller_spec.rb`
74
+ Then the examples should all pass
75
+