rspec-rails 3.0.2 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|