rspec-rails 3.0.2 → 3.1.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +17 -0
- data/README.md +7 -7
- data/lib/generators/rspec.rb +10 -6
- data/lib/generators/rspec/controller/templates/controller_spec.rb +1 -1
- data/lib/generators/rspec/install/install_generator.rb +19 -2
- data/lib/generators/rspec/install/templates/spec/rails_helper.rb +13 -4
- data/lib/generators/rspec/integration/templates/request_spec.rb +1 -1
- data/lib/generators/rspec/job/job_generator.rb +12 -0
- data/lib/generators/rspec/job/templates/job_spec.rb.erb +7 -0
- data/lib/generators/rspec/model/model_generator.rb +18 -5
- data/lib/generators/rspec/scaffold/scaffold_generator.rb +107 -100
- data/lib/rspec-rails.rb +1 -1
- data/lib/rspec/rails.rb +1 -0
- data/lib/rspec/rails/adapters.rb +9 -7
- data/lib/rspec/rails/configuration.rb +2 -3
- data/lib/rspec/rails/example/controller_example_group.rb +172 -149
- data/lib/rspec/rails/example/feature_example_group.rb +25 -23
- data/lib/rspec/rails/example/helper_example_group.rb +27 -25
- data/lib/rspec/rails/example/mailer_example_group.rb +26 -22
- data/lib/rspec/rails/example/model_example_group.rb +8 -6
- data/lib/rspec/rails/example/request_example_group.rb +19 -17
- data/lib/rspec/rails/example/routing_example_group.rb +40 -38
- data/lib/rspec/rails/example/view_example_group.rb +140 -137
- data/lib/rspec/rails/extensions/active_record/proxy.rb +0 -1
- data/lib/rspec/rails/feature_check.rb +35 -0
- data/lib/rspec/rails/fixture_support.rb +1 -1
- data/lib/rspec/rails/matchers.rb +5 -2
- data/lib/rspec/rails/matchers/be_a_new.rb +68 -64
- data/lib/rspec/rails/matchers/be_new_record.rb +24 -20
- data/lib/rspec/rails/matchers/be_valid.rb +38 -34
- data/lib/rspec/rails/matchers/have_http_status.rb +340 -334
- data/lib/rspec/rails/matchers/have_rendered.rb +35 -32
- data/lib/rspec/rails/matchers/redirect_to.rb +30 -27
- data/lib/rspec/rails/matchers/routing_matchers.rb +103 -101
- data/lib/rspec/rails/version.rb +1 -1
- data/lib/rspec/rails/view_assigns.rb +1 -2
- data/lib/rspec/rails/view_rendering.rb +6 -8
- metadata +16 -13
- metadata.gz.sig +3 -2
data/lib/rspec-rails.rb
CHANGED
@@ -7,7 +7,7 @@ module RSpec
|
|
7
7
|
# Rails-3.0.1 requires config.app_generators instead of 3.0.0's config.generators
|
8
8
|
generators = config.respond_to?(:app_generators) ? config.app_generators : config.generators
|
9
9
|
generators.integration_tool :rspec
|
10
|
-
generators.test_framework
|
10
|
+
generators.test_framework :rspec
|
11
11
|
|
12
12
|
rake_tasks do
|
13
13
|
load "rspec/rails/tasks/rspec.rake"
|
data/lib/rspec/rails.rb
CHANGED
data/lib/rspec/rails/adapters.rb
CHANGED
@@ -89,13 +89,10 @@ module RSpec
|
|
89
89
|
|
90
90
|
# @private
|
91
91
|
module MinitestCounters
|
92
|
+
attr_writer :assertions
|
92
93
|
def assertions
|
93
94
|
@assertions ||= 0
|
94
95
|
end
|
95
|
-
|
96
|
-
def assertions=(assertions)
|
97
|
-
@assertions = assertions
|
98
|
-
end
|
99
96
|
end
|
100
97
|
|
101
98
|
# @private
|
@@ -124,7 +121,8 @@ module RSpec
|
|
124
121
|
end
|
125
122
|
end
|
126
123
|
|
127
|
-
def initialize
|
124
|
+
def initialize(*args)
|
125
|
+
super
|
128
126
|
@example = nil
|
129
127
|
end
|
130
128
|
|
@@ -143,8 +141,12 @@ module RSpec
|
|
143
141
|
# examples without exposing non-assertion methods in Test::Unit or
|
144
142
|
# Minitest.
|
145
143
|
def assertion_method_names
|
146
|
-
::RSpec::Rails::Assertions.
|
147
|
-
|
144
|
+
methods = ::RSpec::Rails::Assertions.
|
145
|
+
public_instance_methods.
|
146
|
+
select do |m|
|
147
|
+
m.to_s =~ /^(assert|flunk|refute)/
|
148
|
+
end
|
149
|
+
methods + [:build_message]
|
148
150
|
end
|
149
151
|
|
150
152
|
def define_assertion_delegators
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module RSpec
|
2
|
-
|
3
2
|
module Rails
|
4
3
|
# Fake class to document RSpec Rails configuration options. In practice,
|
5
4
|
# these are dynamically added to the normal RSpec configuration object.
|
@@ -39,7 +38,7 @@ module RSpec
|
|
39
38
|
# @private
|
40
39
|
def self.initialize_configuration(config)
|
41
40
|
config.backtrace_exclusion_patterns << /vendor\//
|
42
|
-
config.backtrace_exclusion_patterns << /
|
41
|
+
config.backtrace_exclusion_patterns << %r{ lib/rspec/rails }
|
43
42
|
|
44
43
|
config.include RSpec::Rails::ControllerExampleGroup, :type => :controller
|
45
44
|
config.include RSpec::Rails::HelperExampleGroup, :type => :helper
|
@@ -57,7 +56,7 @@ module RSpec
|
|
57
56
|
config.add_setting :infer_base_class_for_anonymous_controllers, :default => true
|
58
57
|
|
59
58
|
# fixture support
|
60
|
-
config.include
|
59
|
+
config.include RSpec::Rails::FixtureSupport
|
61
60
|
config.add_setting :use_transactional_fixtures, :alias_with => :use_transactional_examples
|
62
61
|
config.add_setting :use_instantiated_fixtures
|
63
62
|
config.add_setting :global_fixtures
|
@@ -1,179 +1,202 @@
|
|
1
|
-
module RSpec
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# Class-level DSL for controller specs.
|
14
|
-
module ClassMethods
|
15
|
-
# @private
|
16
|
-
def controller_class
|
17
|
-
described_class
|
18
|
-
end
|
1
|
+
module RSpec
|
2
|
+
module Rails
|
3
|
+
# Container module for controller spec functionality.
|
4
|
+
module ControllerExampleGroup
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include RSpec::Rails::RailsExampleGroup
|
7
|
+
include ActionController::TestCase::Behavior
|
8
|
+
include RSpec::Rails::ViewRendering
|
9
|
+
include RSpec::Rails::Matchers::RedirectTo
|
10
|
+
include RSpec::Rails::Matchers::RenderTemplate
|
11
|
+
include RSpec::Rails::Matchers::RoutingMatchers
|
12
|
+
include RSpec::Rails::AssertionDelegator.new(ActionDispatch::Assertions::RoutingAssertions)
|
19
13
|
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# @note Due to Ruby 1.8 scoping rules in anonymous subclasses, constants
|
26
|
-
# defined in `ApplicationController` must be fully qualified (e.g.
|
27
|
-
# `ApplicationController::AccessDenied`) in the block passed to the
|
28
|
-
# `controller` method. Any instance methods, filters, etc, that are
|
29
|
-
# defined in `ApplicationController`, however, are accessible from
|
30
|
-
# within the block.
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# describe ApplicationController do
|
34
|
-
# controller do
|
35
|
-
# def index
|
36
|
-
# raise ApplicationController::AccessDenied
|
37
|
-
# end
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# describe "handling AccessDenied exceptions" 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
|
-
# If you would like to spec a subclass of ApplicationController, call
|
49
|
-
# controller like so:
|
50
|
-
#
|
51
|
-
# controller(ApplicationControllerSubclass) do
|
52
|
-
# # ....
|
53
|
-
# end
|
54
|
-
def controller(base_class = nil, &body)
|
55
|
-
if RSpec.configuration.infer_base_class_for_anonymous_controllers?
|
56
|
-
base_class ||= controller_class
|
14
|
+
# Class-level DSL for controller specs.
|
15
|
+
module ClassMethods
|
16
|
+
# @private
|
17
|
+
def controller_class
|
18
|
+
described_class
|
57
19
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
20
|
+
|
21
|
+
# Supports a simple DSL for specifying behavior of ApplicationController.
|
22
|
+
# Creates an anonymous subclass of ApplicationController and evals the
|
23
|
+
# `body` in that context. Also sets up implicit routes for this
|
24
|
+
# controller, that are separate from those defined in "config/routes.rb".
|
25
|
+
#
|
26
|
+
# @note Due to Ruby 1.8 scoping rules in anonymous subclasses, constants
|
27
|
+
# defined in `ApplicationController` must be fully qualified (e.g.
|
28
|
+
# `ApplicationController::AccessDenied`) in the block passed to the
|
29
|
+
# `controller` method. Any instance methods, filters, etc, that are
|
30
|
+
# defined in `ApplicationController`, however, are accessible from
|
31
|
+
# within the block.
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# describe ApplicationController do
|
35
|
+
# controller do
|
36
|
+
# def index
|
37
|
+
# raise ApplicationController::AccessDenied
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# describe "handling AccessDenied exceptions" do
|
42
|
+
# it "redirects to the /401.html page" do
|
43
|
+
# get :index
|
44
|
+
# response.should redirect_to("/401.html")
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# If you would like to spec a subclass of ApplicationController, call
|
50
|
+
# controller like so:
|
51
|
+
#
|
52
|
+
# controller(ApplicationControllerSubclass) do
|
53
|
+
# # ....
|
54
|
+
# end
|
55
|
+
def controller(base_class = nil, &body)
|
56
|
+
if RSpec.configuration.infer_base_class_for_anonymous_controllers?
|
57
|
+
base_class ||= controller_class
|
58
|
+
end
|
59
|
+
base_class ||= defined?(ApplicationController) ? ApplicationController : ActionController::Base
|
60
|
+
|
61
|
+
new_controller_class = Class.new(base_class) do
|
62
|
+
def self.name
|
63
|
+
root_controller = defined?(ApplicationController) ? ApplicationController : ActionController::Base
|
64
|
+
if superclass == root_controller || superclass.abstract?
|
65
|
+
"AnonymousController"
|
66
|
+
else
|
67
|
+
superclass.to_s
|
68
|
+
end
|
67
69
|
end
|
68
70
|
end
|
69
|
-
|
70
|
-
|
71
|
-
(class << self; self; end).__send__(:define_method, :controller_class) { new_controller_class }
|
71
|
+
new_controller_class.class_exec(&body)
|
72
|
+
(class << self; self; end).__send__(:define_method, :controller_class) { new_controller_class }
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
74
|
+
before do
|
75
|
+
@orig_routes = routes
|
76
|
+
resource_name = if @controller.respond_to?(:controller_name)
|
77
|
+
@controller.controller_name.to_sym
|
78
|
+
else
|
79
|
+
:anonymous
|
80
|
+
end
|
81
|
+
resource_path = if @controller.respond_to?(:controller_path)
|
82
|
+
@controller.controller_path
|
83
|
+
else
|
84
|
+
resource_name.to_s
|
85
|
+
end
|
86
|
+
resource_module = resource_path.rpartition('/').first.presence
|
87
|
+
resource_as = 'anonymous_' + resource_path.tr('/', '_')
|
88
|
+
self.routes = ActionDispatch::Routing::RouteSet.new.tap do |r|
|
89
|
+
r.draw do
|
90
|
+
resources resource_name,
|
91
|
+
:as => resource_as,
|
92
|
+
:module => resource_module,
|
93
|
+
:path => resource_path
|
94
|
+
end
|
87
95
|
end
|
88
96
|
end
|
97
|
+
|
98
|
+
after do
|
99
|
+
self.routes = @orig_routes
|
100
|
+
@orig_routes = nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Specifies the routeset that will be used for the example group. This
|
105
|
+
# is most useful when testing Rails engines.
|
106
|
+
#
|
107
|
+
# @example
|
108
|
+
# describe MyEngine::PostsController do
|
109
|
+
# routes { MyEngine::Engine.routes }
|
110
|
+
#
|
111
|
+
# # ...
|
112
|
+
# end
|
113
|
+
def routes(&blk)
|
114
|
+
before do
|
115
|
+
self.routes = blk.call
|
116
|
+
end
|
89
117
|
end
|
118
|
+
end
|
119
|
+
|
120
|
+
attr_reader :controller, :routes
|
121
|
+
|
122
|
+
# @private
|
123
|
+
#
|
124
|
+
# RSpec Rails uses this to make Rails routes easily available to specs.
|
125
|
+
def routes=(routes)
|
126
|
+
@routes = routes
|
127
|
+
assertion_instance.instance_variable_set(:@routes, routes)
|
128
|
+
end
|
90
129
|
|
91
|
-
|
92
|
-
|
93
|
-
|
130
|
+
# @private
|
131
|
+
module BypassRescue
|
132
|
+
def rescue_with_handler(exception)
|
133
|
+
raise exception
|
94
134
|
end
|
95
135
|
end
|
96
136
|
|
97
|
-
#
|
98
|
-
#
|
137
|
+
# Extends the controller with a module that overrides
|
138
|
+
# `rescue_with_handler` to raise the exception passed to it. Use this to
|
139
|
+
# specify that an action _should_ raise an exception given appropriate
|
140
|
+
# conditions.
|
99
141
|
#
|
100
142
|
# @example
|
101
|
-
# describe
|
102
|
-
#
|
143
|
+
# describe ProfilesController do
|
144
|
+
# it "raises a 403 when a non-admin user tries to view another user's profile" do
|
145
|
+
# profile = create_profile
|
146
|
+
# login_as profile.user
|
103
147
|
#
|
104
|
-
#
|
148
|
+
# expect do
|
149
|
+
# bypass_rescue
|
150
|
+
# get :show, :id => profile.id + 1
|
151
|
+
# end.to raise_error(/403 Forbidden/)
|
152
|
+
# end
|
105
153
|
# end
|
106
|
-
def
|
107
|
-
|
108
|
-
|
154
|
+
def bypass_rescue
|
155
|
+
controller.extend(BypassRescue)
|
156
|
+
end
|
157
|
+
|
158
|
+
# If method is a named_route, delegates to the RouteSet associated with
|
159
|
+
# this controller.
|
160
|
+
def method_missing(method, *args, &block)
|
161
|
+
if route_available?(method)
|
162
|
+
controller.send(method, *args, &block)
|
163
|
+
else
|
164
|
+
super
|
109
165
|
end
|
110
166
|
end
|
111
|
-
end
|
112
167
|
|
113
|
-
|
168
|
+
included do
|
169
|
+
subject { controller }
|
114
170
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
def routes=(routes)
|
119
|
-
@routes = routes
|
120
|
-
assertion_instance.instance_variable_set(:@routes, routes)
|
121
|
-
end
|
171
|
+
before do
|
172
|
+
self.routes = ::Rails.application.routes
|
173
|
+
end
|
122
174
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
175
|
+
around do |ex|
|
176
|
+
previous_allow_forgery_protection_value = ActionController::Base.allow_forgery_protection
|
177
|
+
begin
|
178
|
+
ActionController::Base.allow_forgery_protection = false
|
179
|
+
ex.call
|
180
|
+
ensure
|
181
|
+
ActionController::Base.allow_forgery_protection = previous_allow_forgery_protection_value
|
182
|
+
end
|
183
|
+
end
|
127
184
|
end
|
128
|
-
end
|
129
185
|
|
130
|
-
|
131
|
-
# `rescue_with_handler` to raise the exception passed to it. Use this to
|
132
|
-
# specify that an action _should_ raise an exception given appropriate
|
133
|
-
# conditions.
|
134
|
-
#
|
135
|
-
# @example
|
136
|
-
# describe ProfilesController do
|
137
|
-
# it "raises a 403 when a non-admin user tries to view another user's profile" do
|
138
|
-
# profile = create_profile
|
139
|
-
# login_as profile.user
|
140
|
-
#
|
141
|
-
# expect do
|
142
|
-
# bypass_rescue
|
143
|
-
# get :show, :id => profile.id + 1
|
144
|
-
# end.to raise_error(/403 Forbidden/)
|
145
|
-
# end
|
146
|
-
# end
|
147
|
-
def bypass_rescue
|
148
|
-
controller.extend(BypassRescue)
|
149
|
-
end
|
186
|
+
private
|
150
187
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
if defined?(@routes) && @routes.named_routes.helpers.include?(method)
|
155
|
-
controller.send(method, *args, &block)
|
156
|
-
elsif defined?(@orig_routes) && @orig_routes && @orig_routes.named_routes.helpers.include?(method)
|
157
|
-
controller.send(method, *args, &block)
|
158
|
-
else
|
159
|
-
super
|
188
|
+
def route_available?(method)
|
189
|
+
(defined?(@routes) && route_defined?(routes, method)) ||
|
190
|
+
(defined?(@orig_routes) && route_defined?(@orig_routes, method))
|
160
191
|
end
|
161
|
-
end
|
162
192
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
before do
|
167
|
-
self.routes = ::Rails.application.routes
|
168
|
-
end
|
193
|
+
def route_defined?(routes, method)
|
194
|
+
return false if routes.nil?
|
169
195
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
ex.call
|
175
|
-
ensure
|
176
|
-
ActionController::Base.allow_forgery_protection = previous_allow_forgery_protection_value
|
196
|
+
if routes.named_routes.respond_to?(:route_defined?)
|
197
|
+
routes.named_routes.route_defined?(method)
|
198
|
+
else
|
199
|
+
routes.named_routes.helpers.include?(method)
|
177
200
|
end
|
178
201
|
end
|
179
202
|
end
|
@@ -1,32 +1,34 @@
|
|
1
|
-
module RSpec
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module RSpec
|
2
|
+
module Rails
|
3
|
+
# Container module for routing spec functionality.
|
4
|
+
module FeatureExampleGroup
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include RSpec::Rails::RailsExampleGroup
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
# Default host to be used in Rails route helpers if none is specified.
|
9
|
+
DEFAULT_HOST = "www.example.com"
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
included do
|
12
|
+
app = ::Rails.application
|
13
|
+
if app.respond_to?(:routes)
|
14
|
+
include app.routes.url_helpers if app.routes.respond_to?(:url_helpers)
|
15
|
+
include app.routes.mounted_helpers if app.routes.respond_to?(:mounted_helpers)
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
if respond_to?(:default_url_options)
|
18
|
+
default_url_options[:host] ||= ::RSpec::Rails::FeatureExampleGroup::DEFAULT_HOST
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
|
-
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
# Shim to check for presence of Capybara. Will delegate if present, raise
|
24
|
+
# if not. We assume here that in most cases `visit` will be the first
|
25
|
+
# Capybara method called in a spec.
|
26
|
+
def visit(*)
|
27
|
+
if defined?(super)
|
28
|
+
super
|
29
|
+
else
|
30
|
+
raise "Capybara not loaded, please add it to your Gemfile:\n\ngem \"capybara\""
|
31
|
+
end
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|