From 731d813b53de09332dae169b703e9b24835cdb0f Mon Sep 17 00:00:00 2001 From: Sergey Dolganov Date: Thu, 9 Jan 2020 17:17:42 +0300 Subject: [PATCH 1/2] Add failing spec for #1652 --- .../example/controller_example_group_spec.rb | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/spec/rspec/rails/example/controller_example_group_spec.rb b/spec/rspec/rails/example/controller_example_group_spec.rb index 6d982b51d3..7452f5823f 100644 --- a/spec/rspec/rails/example/controller_example_group_spec.rb +++ b/spec/rspec/rails/example/controller_example_group_spec.rb @@ -90,6 +90,35 @@ def my_helper example.foos_url end + + context "when controller is not a stub" do + let(:custom_contoller) do + stub_const( + "CustomController", + Class.new(ActionController::Base) do + def index + render plain: "ok" + end + end + ) + end + + let(:group) { group_for custom_contoller } + let(:controller) { custom_contoller } + + it "properly delegates routing assertions" do + with_isolated_stderr do + example.with_routing do |map| + map.draw do + get "custom" => "custom#index" + end + + expect { example.get :index }.not_to raise_error + end + end + end + end + end describe "#bypass_rescue" do From afebe67c983d5cae289a84e4ddfdf547c6b2e95f Mon Sep 17 00:00:00 2001 From: Sergey Dolganov Date: Fri, 20 Jan 2017 17:42:34 +0500 Subject: [PATCH 2/2] Fix `with_routing` not working with `get :index` As guys previously mentioned in the thread the problem is that `#get` is called on other context then `#with_routing`. It is caused by https://github.com/rspec/rspec-rails/blob/master/lib/rspec/rails/example/controller_example_group.rb#L5. ActionDispatch::Assertions::RoutingAssertions is adding #with_routing to an assertion_instance, and ActionController::TestCase::Behavior is adding #get to ControllerExampleGroup. So I decided to add an ControllerAssertionDelegator which will include both of them. Actually AssertionDelegator missed some methods, so I featured them in that delegator. Closes #1652 --- lib/rspec/rails/adapters.rb | 42 +++++++++++++++++++ .../rails/example/controller_example_group.rb | 6 +-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/lib/rspec/rails/adapters.rb b/lib/rspec/rails/adapters.rb index ba8cc394e4..0a6891bc07 100644 --- a/lib/rspec/rails/adapters.rb +++ b/lib/rspec/rails/adapters.rb @@ -60,6 +60,48 @@ def assertion_instance end end + # @private + class ControllerAssertionDelegator < AssertionDelegator + module Setup + extend ActiveSupport::Concern + + included { init_setup } + + module ClassMethods + attr_reader :setup_methods, :setup_blocks + attr_accessor :controller_class + + def init_setup + @setup_methods ||= [] + @setup_blocks ||= [] + end + + def setup(*methods, &block) + @setup_methods += methods + @setup_blocks << block if block + end + end + + def initialize(*) + super + self.class.controller_class = described_class + run_setup + end + + def run_setup + self.class.setup_methods.each { |m| send(m) } + self.class.setup_blocks.each { |b| b.call } + end + end + + def initialize(*args) + args << Setup + args << ActionDispatch::Assertions::RoutingAssertions + args << ActionController::TestCase::Behavior + super(*args) + end + end + # Adapts example groups for `Minitest::Test::LifecycleHooks` # # @private diff --git a/lib/rspec/rails/example/controller_example_group.rb b/lib/rspec/rails/example/controller_example_group.rb index 3150f3d469..d3ced02605 100644 --- a/lib/rspec/rails/example/controller_example_group.rb +++ b/lib/rspec/rails/example/controller_example_group.rb @@ -1,9 +1,7 @@ module RSpec module Rails # @private - ControllerAssertionDelegator = RSpec::Rails::AssertionDelegator.new( - ActionDispatch::Assertions::RoutingAssertions - ) + ControllerAssertionDelegatorInstance = RSpec::Rails::ControllerAssertionDelegator.new # @api public # Container module for controller spec functionality. @@ -15,7 +13,7 @@ module ControllerExampleGroup include RSpec::Rails::Matchers::RedirectTo include RSpec::Rails::Matchers::RenderTemplate include RSpec::Rails::Matchers::RoutingMatchers - include ControllerAssertionDelegator + include ControllerAssertionDelegatorInstance # Class-level DSL for controller specs. module ClassMethods