rspec-rails 2.99.0 → 3.0.0.beta1

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 (128) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +40 -68
  5. data/License.txt +1 -0
  6. data/README.md +6 -4
  7. data/features/Generators.md +24 -0
  8. data/features/GettingStarted.md +84 -0
  9. data/features/README.md +56 -0
  10. data/features/RailsVersions.md +4 -0
  11. data/features/Transactions.md +84 -0
  12. data/features/Upgrade.md +121 -0
  13. data/features/controller_specs/Cookies.md +57 -0
  14. data/features/controller_specs/README.md +45 -0
  15. data/features/controller_specs/anonymous_controller.feature +378 -0
  16. data/features/controller_specs/bypass_rescue.feature +75 -0
  17. data/features/controller_specs/controller_spec.feature +58 -0
  18. data/features/controller_specs/engine_routes.feature +51 -0
  19. data/features/controller_specs/isolation_from_views.feature +87 -0
  20. data/features/controller_specs/render_views.feature +114 -0
  21. data/features/directory_structure.feature +71 -0
  22. data/features/feature_specs/feature_spec.feature +35 -0
  23. data/features/helper_specs/helper_spec.feature +122 -0
  24. data/features/mailer_specs/url_helpers.feature +38 -0
  25. data/features/matchers/README.md +18 -0
  26. data/features/matchers/new_record_matcher.feature +41 -0
  27. data/features/matchers/redirect_to_matcher.feature +40 -0
  28. data/features/matchers/relation_match_array.feature +27 -0
  29. data/features/matchers/render_template_matcher.feature +49 -0
  30. data/features/mocks/mock_model.feature +147 -0
  31. data/features/mocks/stub_model.feature +58 -0
  32. data/features/model_specs/README.md +21 -0
  33. data/features/model_specs/errors_on.feature +51 -0
  34. data/features/model_specs/records.feature +27 -0
  35. data/features/model_specs/transactional_examples.feature +109 -0
  36. data/features/request_specs/request_spec.feature +49 -0
  37. data/features/routing_specs/README.md +16 -0
  38. data/features/routing_specs/be_routable_matcher.feature +80 -0
  39. data/features/routing_specs/engine_routes.feature +38 -0
  40. data/features/routing_specs/named_routes.feature +18 -0
  41. data/features/routing_specs/route_to_matcher.feature +90 -0
  42. data/features/step_definitions/additional_cli_steps.rb +4 -0
  43. data/features/step_definitions/model_steps.rb +3 -0
  44. data/features/support/capybara.rb +7 -0
  45. data/features/support/env.rb +53 -0
  46. data/features/support/rails_versions.rb +4 -0
  47. data/features/support/rubinius.rb +6 -0
  48. data/features/view_specs/inferred_controller_path.feature +45 -0
  49. data/features/view_specs/stub_template.feature +51 -0
  50. data/features/view_specs/view_spec.feature +206 -0
  51. data/lib/generators/rspec/controller/templates/controller_spec.rb +1 -1
  52. data/lib/generators/rspec/install/templates/spec/spec_helper.rb.tt +2 -21
  53. data/lib/generators/rspec/integration/integration_generator.rb +2 -3
  54. data/lib/generators/rspec/integration/templates/request_spec.rb +1 -1
  55. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +4 -4
  56. data/lib/generators/rspec/scaffold/scaffold_generator.rb +2 -3
  57. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +16 -16
  58. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +2 -2
  59. data/lib/generators/rspec/scaffold/templates/index_spec.rb +1 -1
  60. data/lib/generators/rspec/scaffold/templates/new_spec.rb +2 -2
  61. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +7 -7
  62. data/lib/generators/rspec/scaffold/templates/show_spec.rb +2 -2
  63. data/lib/rspec/rails.rb +0 -5
  64. data/lib/rspec/rails/adapters.rb +5 -12
  65. data/lib/rspec/rails/example.rb +55 -24
  66. data/lib/rspec/rails/example/controller_example_group.rb +7 -31
  67. data/lib/rspec/rails/example/view_example_group.rb +0 -3
  68. data/lib/rspec/rails/matchers.rb +1 -2
  69. data/lib/rspec/rails/matchers/be_a_new.rb +1 -1
  70. data/lib/rspec/rails/matchers/be_new_record.rb +1 -1
  71. data/lib/rspec/rails/matchers/be_valid.rb +1 -1
  72. data/lib/rspec/rails/matchers/have_rendered.rb +1 -1
  73. data/lib/rspec/rails/matchers/redirect_to.rb +1 -1
  74. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  75. data/lib/rspec/rails/matchers/routing_matchers.rb +6 -10
  76. data/lib/rspec/rails/mocks.rb +5 -41
  77. data/lib/rspec/rails/tasks/rspec.rake +5 -12
  78. data/lib/rspec/rails/vendor/capybara.rb +4 -35
  79. data/lib/rspec/rails/version.rb +1 -1
  80. data/spec/generators/rspec/controller/controller_generator_spec.rb +97 -0
  81. data/spec/generators/rspec/helper/helper_generator_spec.rb +30 -0
  82. data/spec/generators/rspec/install/install_generator_spec.rb +30 -0
  83. data/spec/generators/rspec/integration/integration_generator_spec.rb +44 -0
  84. data/spec/generators/rspec/mailer/mailer_generator_spec.rb +48 -0
  85. data/spec/generators/rspec/model/model_generator_spec.rb +52 -0
  86. data/spec/generators/rspec/observer/observer_generator_spec.rb +21 -0
  87. data/spec/generators/rspec/scaffold/scaffold_generator_spec.rb +138 -0
  88. data/spec/generators/rspec/view/view_generator_spec.rb +41 -0
  89. data/spec/rspec/rails/assertion_adapter_spec.rb +28 -0
  90. data/spec/rspec/rails/assertion_delegator_spec.rb +43 -0
  91. data/spec/rspec/rails/configuration_spec.rb +26 -0
  92. data/spec/rspec/rails/deprecations_spec.rb +18 -0
  93. data/spec/rspec/rails/example/controller_example_group_spec.rb +100 -0
  94. data/spec/rspec/rails/example/feature_example_group_spec.rb +56 -0
  95. data/spec/rspec/rails/example/helper_example_group_spec.rb +66 -0
  96. data/spec/rspec/rails/example/mailer_example_group_spec.rb +21 -0
  97. data/spec/rspec/rails/example/model_example_group_spec.rb +15 -0
  98. data/spec/rspec/rails/example/request_example_group_spec.rb +17 -0
  99. data/spec/rspec/rails/example/routing_example_group_spec.rb +32 -0
  100. data/spec/rspec/rails/example/view_example_group_spec.rb +220 -0
  101. data/spec/rspec/rails/extensions/active_model/errors_on_spec.rb +23 -0
  102. data/spec/rspec/rails/extensions/active_record/base_spec.rb +42 -0
  103. data/spec/rspec/rails/fixture_support_spec.rb +17 -0
  104. data/spec/rspec/rails/matchers/be_a_new_spec.rb +142 -0
  105. data/spec/rspec/rails/matchers/be_new_record_spec.rb +33 -0
  106. data/spec/rspec/rails/matchers/be_routable_spec.rb +41 -0
  107. data/spec/rspec/rails/matchers/be_valid_spec.rb +44 -0
  108. data/spec/rspec/rails/matchers/has_spec.rb +29 -0
  109. data/spec/rspec/rails/matchers/have_rendered_spec.rb +93 -0
  110. data/spec/rspec/rails/matchers/redirect_to_spec.rb +80 -0
  111. data/spec/rspec/rails/matchers/relation_match_array_spec.rb +31 -0
  112. data/spec/rspec/rails/matchers/route_to_spec.rb +151 -0
  113. data/spec/rspec/rails/minitest_lifecycle_adapter_spec.rb +22 -0
  114. data/spec/rspec/rails/mocks/mock_model_spec.rb +378 -0
  115. data/spec/rspec/rails/mocks/stub_model_spec.rb +154 -0
  116. data/spec/rspec/rails/setup_and_teardown_adapter_spec.rb +32 -0
  117. data/spec/rspec/rails/view_rendering_spec.rb +111 -0
  118. data/spec/spec_helper.rb +35 -0
  119. data/spec/support/ar_classes.rb +42 -0
  120. data/spec/support/helpers.rb +20 -0
  121. data/spec/support/matchers.rb +9 -0
  122. data/spec/support/null_object.rb +6 -0
  123. metadata +229 -42
  124. metadata.gz.sig +0 -0
  125. data/lib/autotest/rails_rspec2.rb +0 -91
  126. data/lib/rspec/rails/infer_type_configuration.rb +0 -26
  127. data/lib/rspec/rails/matchers/have_extension.rb +0 -36
  128. data/lib/rspec/rails/module_inclusion.rb +0 -19
@@ -0,0 +1,56 @@
1
+ rspec-rails extends Rails' built-in testing framework to support rspec examples
2
+ for requests, controllers, models, views, helpers, mailers and routing.
3
+
4
+ ## Rails-3
5
+
6
+ rspec-rails-2 supports rails-3.0.0 and later. For earlier versions of Rails,
7
+ you need [rspec-rails-1.3](http://rspec.info).
8
+
9
+ ## Install
10
+
11
+ gem install rspec-rails
12
+
13
+ This installs the following gems:
14
+
15
+ rspec
16
+ rspec-core
17
+ rspec-expectations
18
+ rspec-mocks
19
+ rspec-rails
20
+
21
+ ## Configure
22
+
23
+ Add rspec-rails to the :test and :development groups in the Gemfile:
24
+
25
+ group :test, :development do
26
+ gem "rspec-rails", "~> 2.4"
27
+ end
28
+
29
+ It needs to be in the :development group to expose generators and rake tasks
30
+ without having to type RAILS_ENV=test.
31
+
32
+ Now you can run:
33
+
34
+ script/rails generate rspec:install
35
+
36
+ This adds the spec directory and some skeleton files, including a .rspec
37
+ file.
38
+
39
+ ## Webrat and Capybara
40
+
41
+ You can choose between webrat or capybara for simulating a browser, automating
42
+ a browser, or setting expectations using the matchers they supply. Just add
43
+ your preference to the Gemfile:
44
+
45
+ gem "webrat"
46
+ gem "capybara"
47
+
48
+ ## Issues
49
+
50
+ The documentation for rspec-rails is a work in progress. We'll be adding
51
+ Cucumber features over time, and clarifying existing ones. If you have
52
+ specific features you'd like to see added, find the existing documentation
53
+ incomplete or confusing, or, better yet, wish to write a missing Cucumber
54
+ feature yourself, please [submit an
55
+ issue](http://github.com/rspec/rspec-rails/issues) or a [pull
56
+ request](http://github.com/rspec/rspec-rails).
@@ -0,0 +1,4 @@
1
+ rails version | rspec-rails version
2
+ 2.3 | 1.3.4
3
+ 3.0 | >= 2.0
4
+ 3.1 | >= 2.6
@@ -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
+ expect(@widget).to do_something
40
+ end
41
+
42
+ it "does something else" do
43
+ expect(@widget).to 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,121 @@
1
+ # Upgrading from rspec-rails-1.x to rspec-rails-2.
2
+
3
+ This is a work in progress. Please submit errata, missing steps, or patches to
4
+ the [rspec-rails issue tracker](https://github.com/rspec/rspec-rails/issues).
5
+
6
+ ## Rake tasks
7
+
8
+ Delete lib/tasks/rspec.rake, if present. Rake tasks now live in the rspec-rails
9
+ gem.
10
+
11
+ ## `spec_helper.rb`
12
+
13
+ There were a few changes to the generated `spec/spec_helper.rb` file. We
14
+ recommend the following:
15
+
16
+ 1. set aside a copy of your existing `spec/spec_helper.rb` file.
17
+ 2. run `rails generate rspec:install`
18
+ 3. copy any customizations from your old spec_helper to the new one
19
+
20
+ If you prefer to make the changes manually in the existing spec_helper, here
21
+ is what you need to change:
22
+
23
+ # rspec-1
24
+ require 'spec/autorun'
25
+
26
+ Spec::Runner.configure do |config|
27
+ ...
28
+ end
29
+
30
+ # rspec-2
31
+ require 'rspec/rails'
32
+
33
+ RSpec.configure do |config|
34
+ ...
35
+ end
36
+
37
+ ## Controller specs
38
+
39
+ ### isolation from view templates
40
+
41
+ By default, controller specs do _not_ render view templates. This keeps
42
+ controller specs isolated from the content of views and their requirements.
43
+
44
+ NOTE that the template must exist, but it will not be rendered. This is
45
+ different from rspec-rails-1.x, in which the template didn't need to exist, but
46
+ ActionController makes a number of new decisions in Rails 3 based on the
47
+ existence of the template. To keep the RSpec code free of monkey patches, and
48
+ to keep the rspec user experience simpler, we decided that this would be a fair
49
+ trade-off.
50
+
51
+ ### `response.should render_template`
52
+
53
+ This needs to move from before the action to after. For example:
54
+
55
+ # rspec-rails-1
56
+ controller.should render_template("edit")
57
+ get :edit, :id => "37"
58
+
59
+ # rspec-rails-2
60
+ get :edit, :id => "37"
61
+ response.should render_template("edit")
62
+
63
+ # rspec-rails-2 with expect syntax
64
+ get :edit, :id => "37"
65
+ expect(response).to render_template("edit")
66
+
67
+ rspec-1 had to monkey patch Rails to get render_template to work before the
68
+ action, and this broke a couple of times with Rails releases (requiring urgent
69
+ fix releases in RSpec). Part of the philosophy of rspec-rails-2 is to rely on
70
+ public APIs in Rails as much as possible. In this case, `render_template`
71
+ delegates directly to Rails' `assert_template`, which only works after the
72
+ action.
73
+
74
+ ## View specs
75
+
76
+ ### `view.should render_template`
77
+
78
+ Rails changed the way it renders partials, so to set an expectation that a
79
+ partial gets rendered, you need
80
+
81
+ render
82
+ view.should render_template(:partial => "widget/_row")
83
+
84
+ ### stub_template
85
+
86
+ Introduced in rspec-rails-2.2, simulates the presence of view templates on the
87
+ file system. This supports isolation from partials rendered by the vew template
88
+ that is the subject of a view example:
89
+
90
+ stub_template "widgets/_widget.html.erb" => "This Content"
91
+
92
+ ### No more `have_tag` or `have_text`
93
+
94
+ Before Webrat came along, rspec-rails had its own `have_tag` and `have_text`
95
+ matchers that wrapped Rails' `assert_select`. Webrat included replacements for
96
+ these methods, as well as new matchers (`have_selector` and `have_xpath`), all
97
+ of which rely on Nokogiri to do its work, and are far less brittle than RSpec's
98
+ `have_tag`.
99
+
100
+ Capybara has similar matchers, which will soon be available view specs (they
101
+ are already available in controller specs with `render_views`).
102
+
103
+ Given the brittleness of RSpec's `have_tag` and `have_text` matchers and the
104
+ presence of new Webrat and Capybara matchers that do a better job, `have_tag`
105
+ and `have_text` were not included in rspec-rails-2.
106
+
107
+ ## Mocks, stubs, doubles
108
+
109
+ ### as_new_record
110
+
111
+ Earlier versions of the view generators generated stub_model with `:new_record?
112
+ => true`. That is no longer recognized in rspec-rails-2, so you need to change
113
+ this:
114
+
115
+ stub_model(Widget, :new_record? => true)
116
+
117
+ to this:
118
+
119
+ stub_model(Widget).as_new_record
120
+
121
+ Generators in 2.0.0 final release will do the latter.
@@ -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
+ expect(response.cookies['foo']).to 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
+
@@ -0,0 +1,45 @@
1
+ Controller specs live in `spec/controllers` or any example group with
2
+ `:type => :controller`.
3
+
4
+ A controller spec is an RSpec wrapper for a Rails functional test
5
+ ([ActionController::TestCase::Behavior](https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/test_case.rb)).
6
+ It allows you to simulate a single http request in each example, and then
7
+ specify expected outcomes such as:
8
+
9
+ * rendered templates
10
+ * redirects
11
+ * instance variables assigned in the controller to be shared with the view
12
+ * cookies sent back with the response
13
+
14
+ To specify outcomes, you can use:
15
+
16
+ * standard rspec matchers (`expect(response.status).to eq(200)`)
17
+ * standard test/unit assertions (`assert_equal 200, response.status`)
18
+ * rails assertions (`assert_response 200`)
19
+ * rails-specific matchers:
20
+ * `expect(response).to render_template(wraps assert_template)`
21
+ * `expect(response).to redirect_to(wraps assert_redirected_to)`
22
+ * `expect(assigns(:widget)).to be_a_new(Widget)`
23
+
24
+ ## Examples
25
+
26
+ describe TeamsController do
27
+ describe "GET index" do
28
+ it "assigns @teams" do
29
+ team = Team.create
30
+ get :index
31
+ expect(assigns(:teams)).to eq([team])
32
+ end
33
+
34
+ it "renders the index template" do
35
+ get :index
36
+ expect(response).to render_template("index")
37
+ end
38
+ end
39
+ end
40
+
41
+ ## Views
42
+
43
+ * by default, views are not rendered. See
44
+ [views are stubbed by default](controller-specs/views-are-stubbed-by-default) and
45
+ [render_views](controller-specs/render-views) for details.
@@ -0,0 +1,378 @@
1
+ Feature: anonymous controller
2
+
3
+ Use the `controller` method to define an anonymous controller derived from
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`
21
+
22
+ Scenario: specify error handling in ApplicationController
23
+ Given a file named "spec/controllers/application_controller_spec.rb" with:
24
+ """ruby
25
+ require "spec_helper"
26
+
27
+ class ApplicationController < ActionController::Base
28
+ class AccessDenied < StandardError; end
29
+
30
+ rescue_from AccessDenied, :with => :access_denied
31
+
32
+ private
33
+
34
+ def access_denied
35
+ redirect_to "/401.html"
36
+ end
37
+ end
38
+
39
+ describe ApplicationController do
40
+ controller do
41
+ def index
42
+ raise ApplicationController::AccessDenied
43
+ end
44
+ end
45
+
46
+ describe "handling AccessDenied exceptions" do
47
+ it "redirects to the /401.html page" do
48
+ get :index
49
+ expect(response).to redirect_to("/401.html")
50
+ end
51
+ end
52
+ end
53
+ """
54
+ When I run `rspec spec`
55
+ Then the examples should all pass
56
+
57
+ Scenario: specify error handling in subclass of ApplicationController
58
+ Given a file named "spec/controllers/application_controller_subclass_spec.rb" with:
59
+ """ruby
60
+ require "spec_helper"
61
+
62
+ class ApplicationController < ActionController::Base
63
+ class AccessDenied < StandardError; end
64
+ end
65
+
66
+ class ApplicationControllerSubclass < ApplicationController
67
+
68
+ rescue_from ApplicationController::AccessDenied, :with => :access_denied
69
+
70
+ private
71
+
72
+ def access_denied
73
+ redirect_to "/401.html"
74
+ end
75
+ end
76
+
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
+ expect(response).to redirect_to("/401.html")
88
+ end
89
+ end
90
+ end
91
+ """
92
+ When I run `rspec spec`
93
+ Then the examples should all pass
94
+
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
+ """ruby
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
+ expect(controller).to be_a_kind_of(ApplicationControllerSubclass)
117
+ end
118
+ end
119
+ """
120
+ When I run `rspec spec`
121
+ Then the examples should all pass
122
+
123
+ Scenario: invoke around filter in base class
124
+ Given a file named "spec/controllers/application_controller_around_filter_spec.rb" with:
125
+ """ruby
126
+ require "spec_helper"
127
+
128
+ class ApplicationController < ActionController::Base
129
+ around_filter :an_around_filter
130
+
131
+ def an_around_filter
132
+ @callback_invoked = true
133
+ yield
134
+ end
135
+ end
136
+
137
+ describe ApplicationController do
138
+ controller do
139
+ def index
140
+ render :nothing => true
141
+ end
142
+ end
143
+
144
+ it "invokes the callback" do
145
+ get :index
146
+
147
+ expect(assigns[:callback_invoked]).to be_truthy
148
+ end
149
+ end
150
+ """
151
+ When I run `rspec spec`
152
+ Then the examples should all pass
153
+
154
+ Scenario: anonymous controllers only create resource routes
155
+ Given a file named "spec/controllers/application_controller_spec.rb" with:
156
+ """ruby
157
+ require "spec_helper"
158
+
159
+ describe ApplicationController do
160
+ controller do
161
+ def index
162
+ render :text => "index called"
163
+ end
164
+
165
+ def create
166
+ render :text => "create called"
167
+ end
168
+
169
+ def new
170
+ render :text => "new called"
171
+ end
172
+
173
+ def show
174
+ render :text => "show called"
175
+ end
176
+
177
+ def edit
178
+ render :text => "edit called"
179
+ end
180
+
181
+ def update
182
+ render :text => "update called"
183
+ end
184
+
185
+ def destroy
186
+ render :text => "destroy called"
187
+ end
188
+
189
+ def willerror
190
+ render :text => "will not render"
191
+ end
192
+ end
193
+
194
+ describe "#index" do
195
+ it "responds to GET" do
196
+ get :index
197
+ expect(response.body).to eq "index called"
198
+ end
199
+
200
+ it "also responds to POST" do
201
+ post :index
202
+ expect(response.body).to eq "index called"
203
+ end
204
+
205
+ it "also responds to PUT" do
206
+ put :index
207
+ expect(response.body).to eq "index called"
208
+ end
209
+
210
+ it "also responds to DELETE" do
211
+ delete :index
212
+ expect(response.body).to eq "index called"
213
+ end
214
+ end
215
+
216
+ describe "#create" do
217
+ it "responds to POST" do
218
+ post :create
219
+ expect(response.body).to eq "create called"
220
+ end
221
+
222
+ # And the rest...
223
+ %w{get post put delete}.each do |calltype|
224
+ it "responds to #{calltype}" do
225
+ send(calltype, :create)
226
+ expect(response.body).to eq "create called"
227
+ end
228
+ end
229
+ end
230
+
231
+ describe "#new" do
232
+ it "responds to GET" do
233
+ get :new
234
+ expect(response.body).to eq "new called"
235
+ end
236
+
237
+ # And the rest...
238
+ %w{get post put delete}.each do |calltype|
239
+ it "responds to #{calltype}" do
240
+ send(calltype, :new)
241
+ expect(response.body).to eq "new called"
242
+ end
243
+ end
244
+ end
245
+
246
+ describe "#edit" do
247
+ it "responds to GET" do
248
+ get :edit, :id => "anyid"
249
+ expect(response.body).to eq "edit called"
250
+ end
251
+
252
+ it "requires the :id parameter" do
253
+ expect { get :edit }.to raise_error(ActionController::RoutingError)
254
+ end
255
+
256
+ # And the rest...
257
+ %w{get post put delete}.each do |calltype|
258
+ it "responds to #{calltype}" do
259
+ send(calltype, :edit, {:id => "anyid"})
260
+ expect(response.body).to eq "edit called"
261
+ end
262
+ end
263
+ end
264
+
265
+ describe "#show" do
266
+ it "responds to GET" do
267
+ get :show, :id => "anyid"
268
+ expect(response.body).to eq "show called"
269
+ end
270
+
271
+ it "requires the :id parameter" do
272
+ expect { get :show }.to raise_error(ActionController::RoutingError)
273
+ end
274
+
275
+ # And the rest...
276
+ %w{get post put delete}.each do |calltype|
277
+ it "responds to #{calltype}" do
278
+ send(calltype, :show, {:id => "anyid"})
279
+ expect(response.body).to eq "show called"
280
+ end
281
+ end
282
+ end
283
+
284
+ describe "#update" do
285
+ it "responds to PUT" do
286
+ put :update, :id => "anyid"
287
+ expect(response.body).to eq "update called"
288
+ end
289
+
290
+ it "requires the :id parameter" do
291
+ expect { put :update }.to raise_error(ActionController::RoutingError)
292
+ end
293
+
294
+ # And the rest...
295
+ %w{get post put delete}.each do |calltype|
296
+ it "responds to #{calltype}" do
297
+ send(calltype, :update, {:id => "anyid"})
298
+ expect(response.body).to eq "update called"
299
+ end
300
+ end
301
+ end
302
+
303
+ describe "#destroy" do
304
+ it "responds to DELETE" do
305
+ delete :destroy, :id => "anyid"
306
+ expect(response.body).to eq "destroy called"
307
+ end
308
+
309
+ it "requires the :id parameter" do
310
+ expect { delete :destroy }.to raise_error(ActionController::RoutingError)
311
+ end
312
+
313
+ # And the rest...
314
+ %w{get post put delete}.each do |calltype|
315
+ it "responds to #{calltype}" do
316
+ send(calltype, :destroy, {:id => "anyid"})
317
+ expect(response.body).to eq "destroy called"
318
+ end
319
+ end
320
+ end
321
+
322
+ describe "#willerror" do
323
+ it "cannot be called" do
324
+ expect { get :willerror }.to raise_error(ActionController::RoutingError)
325
+ end
326
+ end
327
+ end
328
+ """
329
+ When I run `rspec spec`
330
+ Then the examples should all pass
331
+
332
+ Scenario: draw custom routes for anonymous controllers
333
+ Given a file named "spec/controllers/application_controller_spec.rb" with:
334
+ """ruby
335
+ require "spec_helper"
336
+
337
+ describe ApplicationController do
338
+ controller do
339
+ def custom
340
+ render :text => "custom called"
341
+ end
342
+ end
343
+
344
+ specify "a custom action can be requested if routes are drawn manually" do
345
+ routes.draw { get "custom" => "anonymous#custom" }
346
+
347
+ get :custom
348
+ expect(response.body).to eq "custom called"
349
+ end
350
+ end
351
+ """
352
+ When I run `rspec spec`
353
+ Then the examples should all pass
354
+
355
+ Scenario: refer to application routes in the controller under test
356
+ Given a file named "spec/controllers/application_controller_spec.rb" with:
357
+ """ruby
358
+ require "spec_helper"
359
+
360
+ Rails.application.routes.draw do
361
+ match "/login" => "sessions#new", :as => "login", :via => "get"
362
+ end
363
+
364
+ describe ApplicationController do
365
+ controller do
366
+ def index
367
+ redirect_to login_url
368
+ end
369
+ end
370
+
371
+ it "redirects to the login page" do
372
+ get :index
373
+ expect(response).to redirect_to("/login")
374
+ end
375
+ end
376
+ """
377
+ When I run `rspec spec`
378
+ Then the examples should all pass