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.
- checksums.yaml +8 -8
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +40 -68
- data/License.txt +1 -0
- data/README.md +6 -4
- data/features/Generators.md +24 -0
- data/features/GettingStarted.md +84 -0
- data/features/README.md +56 -0
- data/features/RailsVersions.md +4 -0
- data/features/Transactions.md +84 -0
- data/features/Upgrade.md +121 -0
- data/features/controller_specs/Cookies.md +57 -0
- data/features/controller_specs/README.md +45 -0
- data/features/controller_specs/anonymous_controller.feature +378 -0
- data/features/controller_specs/bypass_rescue.feature +75 -0
- data/features/controller_specs/controller_spec.feature +58 -0
- data/features/controller_specs/engine_routes.feature +51 -0
- data/features/controller_specs/isolation_from_views.feature +87 -0
- data/features/controller_specs/render_views.feature +114 -0
- data/features/directory_structure.feature +71 -0
- data/features/feature_specs/feature_spec.feature +35 -0
- data/features/helper_specs/helper_spec.feature +122 -0
- data/features/mailer_specs/url_helpers.feature +38 -0
- data/features/matchers/README.md +18 -0
- data/features/matchers/new_record_matcher.feature +41 -0
- data/features/matchers/redirect_to_matcher.feature +40 -0
- data/features/matchers/relation_match_array.feature +27 -0
- data/features/matchers/render_template_matcher.feature +49 -0
- data/features/mocks/mock_model.feature +147 -0
- data/features/mocks/stub_model.feature +58 -0
- data/features/model_specs/README.md +21 -0
- data/features/model_specs/errors_on.feature +51 -0
- data/features/model_specs/records.feature +27 -0
- data/features/model_specs/transactional_examples.feature +109 -0
- data/features/request_specs/request_spec.feature +49 -0
- data/features/routing_specs/README.md +16 -0
- data/features/routing_specs/be_routable_matcher.feature +80 -0
- data/features/routing_specs/engine_routes.feature +38 -0
- data/features/routing_specs/named_routes.feature +18 -0
- data/features/routing_specs/route_to_matcher.feature +90 -0
- data/features/step_definitions/additional_cli_steps.rb +4 -0
- data/features/step_definitions/model_steps.rb +3 -0
- data/features/support/capybara.rb +7 -0
- data/features/support/env.rb +53 -0
- data/features/support/rails_versions.rb +4 -0
- data/features/support/rubinius.rb +6 -0
- data/features/view_specs/inferred_controller_path.feature +45 -0
- data/features/view_specs/stub_template.feature +51 -0
- data/features/view_specs/view_spec.feature +206 -0
- data/lib/generators/rspec/controller/templates/controller_spec.rb +1 -1
- data/lib/generators/rspec/install/templates/spec/spec_helper.rb.tt +2 -21
- data/lib/generators/rspec/integration/integration_generator.rb +2 -3
- data/lib/generators/rspec/integration/templates/request_spec.rb +1 -1
- data/lib/generators/rspec/mailer/templates/mailer_spec.rb +4 -4
- data/lib/generators/rspec/scaffold/scaffold_generator.rb +2 -3
- data/lib/generators/rspec/scaffold/templates/controller_spec.rb +16 -16
- data/lib/generators/rspec/scaffold/templates/edit_spec.rb +2 -2
- data/lib/generators/rspec/scaffold/templates/index_spec.rb +1 -1
- data/lib/generators/rspec/scaffold/templates/new_spec.rb +2 -2
- data/lib/generators/rspec/scaffold/templates/routing_spec.rb +7 -7
- data/lib/generators/rspec/scaffold/templates/show_spec.rb +2 -2
- data/lib/rspec/rails.rb +0 -5
- data/lib/rspec/rails/adapters.rb +5 -12
- data/lib/rspec/rails/example.rb +55 -24
- data/lib/rspec/rails/example/controller_example_group.rb +7 -31
- data/lib/rspec/rails/example/view_example_group.rb +0 -3
- data/lib/rspec/rails/matchers.rb +1 -2
- data/lib/rspec/rails/matchers/be_a_new.rb +1 -1
- data/lib/rspec/rails/matchers/be_new_record.rb +1 -1
- data/lib/rspec/rails/matchers/be_valid.rb +1 -1
- data/lib/rspec/rails/matchers/have_rendered.rb +1 -1
- data/lib/rspec/rails/matchers/redirect_to.rb +1 -1
- data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
- data/lib/rspec/rails/matchers/routing_matchers.rb +6 -10
- data/lib/rspec/rails/mocks.rb +5 -41
- data/lib/rspec/rails/tasks/rspec.rake +5 -12
- data/lib/rspec/rails/vendor/capybara.rb +4 -35
- data/lib/rspec/rails/version.rb +1 -1
- data/spec/generators/rspec/controller/controller_generator_spec.rb +97 -0
- data/spec/generators/rspec/helper/helper_generator_spec.rb +30 -0
- data/spec/generators/rspec/install/install_generator_spec.rb +30 -0
- data/spec/generators/rspec/integration/integration_generator_spec.rb +44 -0
- data/spec/generators/rspec/mailer/mailer_generator_spec.rb +48 -0
- data/spec/generators/rspec/model/model_generator_spec.rb +52 -0
- data/spec/generators/rspec/observer/observer_generator_spec.rb +21 -0
- data/spec/generators/rspec/scaffold/scaffold_generator_spec.rb +138 -0
- data/spec/generators/rspec/view/view_generator_spec.rb +41 -0
- data/spec/rspec/rails/assertion_adapter_spec.rb +28 -0
- data/spec/rspec/rails/assertion_delegator_spec.rb +43 -0
- data/spec/rspec/rails/configuration_spec.rb +26 -0
- data/spec/rspec/rails/deprecations_spec.rb +18 -0
- data/spec/rspec/rails/example/controller_example_group_spec.rb +100 -0
- data/spec/rspec/rails/example/feature_example_group_spec.rb +56 -0
- data/spec/rspec/rails/example/helper_example_group_spec.rb +66 -0
- data/spec/rspec/rails/example/mailer_example_group_spec.rb +21 -0
- data/spec/rspec/rails/example/model_example_group_spec.rb +15 -0
- data/spec/rspec/rails/example/request_example_group_spec.rb +17 -0
- data/spec/rspec/rails/example/routing_example_group_spec.rb +32 -0
- data/spec/rspec/rails/example/view_example_group_spec.rb +220 -0
- data/spec/rspec/rails/extensions/active_model/errors_on_spec.rb +23 -0
- data/spec/rspec/rails/extensions/active_record/base_spec.rb +42 -0
- data/spec/rspec/rails/fixture_support_spec.rb +17 -0
- data/spec/rspec/rails/matchers/be_a_new_spec.rb +142 -0
- data/spec/rspec/rails/matchers/be_new_record_spec.rb +33 -0
- data/spec/rspec/rails/matchers/be_routable_spec.rb +41 -0
- data/spec/rspec/rails/matchers/be_valid_spec.rb +44 -0
- data/spec/rspec/rails/matchers/has_spec.rb +29 -0
- data/spec/rspec/rails/matchers/have_rendered_spec.rb +93 -0
- data/spec/rspec/rails/matchers/redirect_to_spec.rb +80 -0
- data/spec/rspec/rails/matchers/relation_match_array_spec.rb +31 -0
- data/spec/rspec/rails/matchers/route_to_spec.rb +151 -0
- data/spec/rspec/rails/minitest_lifecycle_adapter_spec.rb +22 -0
- data/spec/rspec/rails/mocks/mock_model_spec.rb +378 -0
- data/spec/rspec/rails/mocks/stub_model_spec.rb +154 -0
- data/spec/rspec/rails/setup_and_teardown_adapter_spec.rb +32 -0
- data/spec/rspec/rails/view_rendering_spec.rb +111 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/support/ar_classes.rb +42 -0
- data/spec/support/helpers.rb +20 -0
- data/spec/support/matchers.rb +9 -0
- data/spec/support/null_object.rb +6 -0
- metadata +229 -42
- metadata.gz.sig +0 -0
- data/lib/autotest/rails_rspec2.rb +0 -91
- data/lib/rspec/rails/infer_type_configuration.rb +0 -26
- data/lib/rspec/rails/matchers/have_extension.rb +0 -36
- data/lib/rspec/rails/module_inclusion.rb +0 -19
data/features/README.md
ADDED
@@ -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,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.
|
data/features/Upgrade.md
ADDED
@@ -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
|