Skip to content

Commit fef96ff

Browse files
committed
Merge pull request #1492 from rspec/rails-5-support-patches
Rails 5 support patches
2 parents b1dff7f + 275905d commit fef96ff

File tree

14 files changed

+122
-28
lines changed

14 files changed

+122
-28
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ matrix:
5656
# Rails 5.x only supports 2.2
5757
- rvm: 2.2.2
5858
env: RAILS_VERSION=master
59+
- rvm: 2.2.2
60+
env: RAILS_VERSION=5.0.0.beta1
5961
exclude:
6062
# 3.0.x is not supported on MRI 2.0+
6163
- rvm: 2.0.0

Gemfile-rails-dependencies

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ when /master/
66
gem "journey", :git => "git://github.com/rails/journey.git"
77
gem "activerecord-deprecated_finders", :git => "git://github.com/rails/activerecord-deprecated_finders.git"
88
gem "rails-observers", :git => "git://github.com/rails/rails-observers"
9+
gem "web-console", :git => "git://github.com/rails/web-console", :group => :development
910
gem 'sass-rails', :git => "git://github.com/rails/sass-rails.git"
1011
gem 'coffee-rails', :git => "git://github.com/rails/coffee-rails.git"
1112
gem 'rack', :git => 'git://github.com/rack/rack.git'

Rakefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,16 @@ RSpec::Core::RakeTask.new(:spec) do |t|
1717
t.rspec_opts = %w[--color]
1818
end
1919

20-
Cucumber::Rake::Task.new(:cucumber)
20+
Cucumber::Rake::Task.new(:cucumber) do |t|
21+
version = ENV.fetch("RAILS_VERSION", "~> 4.2.0")
22+
cucumber_flag = "--tags ~@rails_post_5"
23+
p version
24+
if /(^| )5(\.|-)0/ === version || version == "master"
25+
cucumber_flag = "--tags ~@rails_pre_5"
26+
end
27+
28+
t.cucumber_opts = cucumber_flag
29+
end
2130

2231
namespace :generate do
2332
desc "generate a fresh app with rspec installed"

example_app_generator/generate_app.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
# Remove the existing rails version so we can properly use master or other
1515
# edge branches
1616
gsub_file 'Gemfile', /^.*\bgem 'rails.*$/, ''
17+
gsub_file "Gemfile", /.*web-console.*/, ''
18+
19+
if Rails::VERSION::STRING >= '5.0.0'
20+
append_to_file('Gemfile', "gem 'rails-controller-testing', :git => 'https://github.com/rails/rails-controller-testing'")
21+
end
1722

1823
# Use our version of RSpec and Rails
1924
append_to_file 'Gemfile', <<-EOT.gsub(/^ +\|/, '')

features/controller_specs/render_views.feature

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Feature: render_views
1212
render_views
1313
1414
describe "GET index" do
15-
it "says 'Listing widgets'" do
15+
it "has a widgets related heading" do
1616
get :index
17-
expect(response.body).to match /Listing widgets/im
17+
expect(response.body).to match /<h1>.*widgets/im
1818
end
1919
end
2020
end
@@ -34,7 +34,7 @@ Feature: render_views
3434
describe "GET index" do
3535
it "renders the actual template" do
3636
get :index
37-
expect(response.body).to match /Listing widgets/im
37+
expect(response.body).to match /<h1>.*widgets/im
3838
end
3939
end
4040
@@ -65,7 +65,7 @@ Feature: render_views
6565
describe "GET index" do
6666
it "renders the actual template" do
6767
get :index
68-
expect(response.body).to match /Listing widgets/im
68+
expect(response.body).to match /<h1>.*widgets/im
6969
end
7070
end
7171
end
@@ -105,7 +105,7 @@ Feature: render_views
105105
describe "GET index" do
106106
it "renders the index template" do
107107
get :index
108-
expect(response.body).to match /Listing widgets/im
108+
expect(response.body).to match /<h1>.*widgets/im
109109
end
110110
end
111111
end

features/mailer_specs/url_helpers.feature

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,46 @@ Feature: URL helpers in mailer examples
33
Mailer specs are marked by `:type => :mailer` or if you have set
44
`config.infer_spec_type_from_file_location!` by placing them in `spec/mailer`.
55

6+
@rails_post_5
7+
Scenario: using URL helpers with default options
8+
Given a file named "config/initializers/mailer_defaults.rb" with:
9+
"""ruby
10+
Rails.configuration.action_mailer.default_url_options = { :host => 'example.com' }
11+
"""
12+
And a file named "spec/mailers/notifications_spec.rb" with:
13+
"""ruby
14+
require 'rails_helper'
15+
16+
RSpec.describe NotificationsMailer, :type => :mailer do
17+
it 'should have access to URL helpers' do
18+
expect { gadgets_url }.not_to raise_error
19+
end
20+
end
21+
"""
22+
When I run `rspec spec`
23+
Then the examples should all pass
24+
25+
@rails_post_5
26+
Scenario: using URL helpers without default options
27+
Given a file named "config/initializers/mailer_defaults.rb" with:
28+
"""ruby
29+
# no default options
30+
"""
31+
And a file named "spec/mailers/notifications_spec.rb" with:
32+
"""ruby
33+
require 'rails_helper'
34+
35+
RSpec.describe NotificationsMailer, :type => :mailer do
36+
it 'should have access to URL helpers' do
37+
expect { gadgets_url :host => 'example.com' }.not_to raise_error
38+
expect { gadgets_url }.to raise_error
39+
end
40+
end
41+
"""
42+
When I run `rspec spec`
43+
Then the examples should all pass
44+
45+
@rails_pre_5
646
Scenario: using URL helpers with default options
747
Given a file named "config/initializers/mailer_defaults.rb" with:
848
"""ruby
@@ -21,6 +61,7 @@ Feature: URL helpers in mailer examples
2161
When I run `rspec spec`
2262
Then the examples should all pass
2363

64+
@rails_pre_5
2465
Scenario: using URL helpers without default options
2566
Given a file named "config/initializers/mailer_defaults.rb" with:
2667
"""ruby

lib/generators/rspec/mailer/templates/mailer_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
require "rails_helper"
22

33
<% module_namespacing do -%>
4-
RSpec.describe <%= class_name %>, <%= type_metatag(:mailer) %> do
4+
RSpec.describe <%= class_name %><%= Rails.version.to_f >= 5.0 ? "Mailer" : "" %>, <%= type_metatag(:mailer) %> do
55
<% for action in actions -%>
66
describe "<%= action %>" do
7-
let(:mail) { <%= class_name %>.<%= action %> }
7+
let(:mail) { <%= class_name %><%= Rails.version.to_f >= 5.0 ? "Mailer" : "" %>.<%= action %> }
88
99
it "renders the headers" do
1010
expect(mail.subject).to eq(<%= action.to_s.humanize.inspect %>)

lib/rspec/rails/configuration.rb

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ class Configuration
3636
:feature => %w[spec features]
3737
}
3838

39+
# Sets up the different example group modules for the different spec types
40+
#
41+
# @api private
42+
def self.add_test_type_configurations(config)
43+
config.include RSpec::Rails::ControllerExampleGroup, :type => :controller
44+
config.include RSpec::Rails::HelperExampleGroup, :type => :helper
45+
config.include RSpec::Rails::ModelExampleGroup, :type => :model
46+
config.include RSpec::Rails::RequestExampleGroup, :type => :request
47+
config.include RSpec::Rails::RoutingExampleGroup, :type => :routing
48+
config.include RSpec::Rails::ViewExampleGroup, :type => :view
49+
config.include RSpec::Rails::FeatureExampleGroup, :type => :feature
50+
end
51+
3952
# @private
4053
def self.initialize_configuration(config)
4154
config.backtrace_exclusion_patterns << /vendor\//
@@ -98,13 +111,15 @@ def filter_rails_from_backtrace!
98111
end
99112
end
100113

101-
config.include RSpec::Rails::ControllerExampleGroup, :type => :controller
102-
config.include RSpec::Rails::HelperExampleGroup, :type => :helper
103-
config.include RSpec::Rails::ModelExampleGroup, :type => :model
104-
config.include RSpec::Rails::RequestExampleGroup, :type => :request
105-
config.include RSpec::Rails::RoutingExampleGroup, :type => :routing
106-
config.include RSpec::Rails::ViewExampleGroup, :type => :view
107-
config.include RSpec::Rails::FeatureExampleGroup, :type => :feature
114+
add_test_type_configurations(config)
115+
116+
if defined?(::Rails::Controller::Testing)
117+
[:controller, :view, :request].each do |type|
118+
config.include ::Rails::Controller::Testing::TestProcess, :type => type
119+
config.include ::Rails::Controller::Testing::TemplateAssertions, :type => type
120+
config.include ::Rails::Controller::Testing::Integration, :type => type
121+
end
122+
end
108123

109124
if defined?(ActionMailer)
110125
config.include RSpec::Rails::MailerExampleGroup, :type => :mailer

lib/rspec/rails/example/view_example_group.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,14 @@ def _include_controller_helpers
159159
end
160160

161161
controller.controller_path = _controller_path
162-
controller.request.path_parameters[:controller] = _controller_path
163-
controller.request.path_parameters[:action] = _inferred_action unless _inferred_action =~ /^_/
162+
163+
path_params_to_merge = {}
164+
path_params_to_merge[:controller] = _controller_path
165+
path_params_to_merge[:action] = _inferred_action unless _inferred_action =~ /^_/
166+
167+
path_params = controller.request.path_parameters
168+
169+
controller.request.path_parameters = path_params.reverse_merge(path_params_to_merge)
164170
controller.request.path = ViewPathBuilder.new(::Rails.application.routes).path_for(controller.request.path_parameters)
165171
ViewSpecMethods.add_to(::ActionView::TestCase::TestController)
166172
end

lib/rspec/rails/matchers/have_http_status.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ def as_test_response(obj)
4343
# Capybara or catch `NameError`s for the undefined constants
4444
obj = ActionDispatch::Response.new.tap do |resp|
4545
resp.status = obj.status_code
46-
resp.headers = obj.response_headers
46+
resp.headers.clear
47+
resp.headers.merge!(obj.response_headers)
4748
resp.body = obj.body
49+
resp.request = ActionDispatch::Request.new({})
4850
end
4951
::ActionDispatch::TestResponse.from_response(obj)
5052
else
@@ -84,7 +86,7 @@ def initialize(code)
8486
# @return [Boolean] `true` if the numeric code matched the `response` code
8587
def matches?(response)
8688
test_response = as_test_response(response)
87-
@actual = test_response.response_code
89+
@actual = test_response.response_code.to_i
8890
expected == @actual
8991
rescue TypeError => _ignored
9092
@invalid_response = response

spec/generators/rspec/mailer/mailer_generator_spec.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
end
1414
it { is_expected.to exist }
1515
it { is_expected.to contain(/require "rails_helper"/) }
16-
it { is_expected.to contain(/^RSpec.describe Posts, #{type_metatag(:mailer)}/) }
16+
if Rails.version.to_f >= 5.0
17+
# Rails 5 automatically appends Mailer to the provided constant so we do too
18+
it { is_expected.to contain(/^RSpec.describe PostsMailer, #{type_metatag(:mailer)}/) }
19+
else
20+
it { is_expected.to contain(/^RSpec.describe Posts, #{type_metatag(:mailer)}/) }
21+
end
1722
it { is_expected.to contain(/describe "index" do/) }
1823
it { is_expected.to contain(/describe "show" do/) }
1924
end

spec/rspec/rails/example/mailer_example_group_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module RSpec::Rails
55
module ::Rails; end
66
before do
77
allow(Rails).to receive_message_chain(:application, :routes, :url_helpers).and_return(Rails)
8+
allow(Rails.application).to receive(:config).and_return(double("Rails.application.config").as_null_object)
89
allow(Rails).to receive_message_chain(:configuration, :action_mailer, :default_url_options).and_return({})
910
end
1011

spec/rspec/rails/matchers/have_http_status_spec.rb

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,27 @@
44
include RSpec::Rails::Matchers
55

66
def create_response(opts = {})
7-
ActionDispatch::TestResponse.new(opts.fetch(:status))
7+
ActionDispatch::TestResponse.new(opts.fetch(:status)).tap {|x|
8+
x.request = ActionDispatch::Request.new({})
9+
}
810
end
911

1012
shared_examples_for "supports different response instances" do
1113
context "given an ActionDispatch::Response" do
1214
it "returns true for a response with the same code" do
13-
response = ::ActionDispatch::Response.new(code)
15+
response = ::ActionDispatch::Response.new(code).tap {|x|
16+
x.request = ActionDispatch::Request.new({})
17+
}
1418

1519
expect( matcher.matches?(response) ).to be(true)
1620
end
1721
end
1822

1923
context "given an ActionDispatch::TestResponse" do
2024
it "returns true for a response with the same code" do
21-
response = ::ActionDispatch::TestResponse.new(code)
25+
response = ::ActionDispatch::TestResponse.new(code).tap {|x|
26+
x.request = ActionDispatch::Request.new({})
27+
}
2228

2329
expect( matcher.matches?(response) ).to be(true)
2430
end
@@ -382,12 +388,12 @@ def create_response(opts = {})
382388
it_behaves_like "supports different response instances" do
383389
subject(:matcher) { have_redirect_status }
384390

385-
let(:code) { 333 }
391+
let(:code) { 308 }
386392
end
387393

388394
describe "matching a response" do
389395
it "returns true for a response with a 3xx status code" do
390-
any_3xx_code = 333
396+
any_3xx_code = 308
391397
response = create_response(:status => any_3xx_code)
392398

393399
expect( have_redirect_status.matches?(response) ).to be(true)
@@ -416,12 +422,12 @@ def create_response(opts = {})
416422
end
417423

418424
it "has a negated failure message reporting the expected and actual status codes" do
419-
any_3xx_code = 333
425+
any_3xx_code = 308
420426
response = create_response(:status => any_3xx_code)
421427

422428
expect{ have_redirect_status.matches? response }.
423429
to change(have_redirect_status, :failure_message_when_negated).
424-
to(/not to have a redirect status code \(3xx\) but it was 333/)
430+
to(/not to have a redirect status code \(3xx\) but it was 308/)
425431
end
426432
end
427433

@@ -430,5 +436,4 @@ def create_response(opts = {})
430436
expect{ have_http_status(nil) }.to raise_error ArgumentError
431437
end
432438
end
433-
434439
end

spec/support/ar_classes.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ def self.extended(host)
1313
nonexistent_model_id integer
1414
)
1515
eosql
16+
17+
host.reset_column_information
1618
end
1719
end
1820

0 commit comments

Comments
 (0)