Skip to content

let request specs use integration test services #1560

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 9, 2016

Conversation

bronson
Copy link
Contributor

@bronson bronson commented Feb 25, 2016

Rails integration tests have some services like assert_select.
This pull request makes them available in request specs.

This is already the case for controller specs: https://github.com/rspec/rspec-rails/blob/4a2a078632990/lib/rspec/rails/example/controller_example_group.rb#L13

This came up while converting controller specs to request specs as suggested by the Rails 5 release notes. (I have an API-only app so capybara is out)

This will be a no-op until Rails merges rails/rails#23880

@bronson
Copy link
Contributor Author

bronson commented Feb 25, 2016

Lint fail: (and technically I agree)

lib/rspec/rails/example/request_example_group.rb:8:7: C: Avoid using rescue in its modifier form.
      include ActionDispatch::IntegrationTest::Behavior rescue NameError
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Fixed, and includes a helpful comment.

@bronson bronson force-pushed the patch-1 branch 3 times, most recently from 87d6bc4 to 5d462b7 Compare February 25, 2016 22:57
[:assert_select, :url_for, :url_options].each do |name|
define_method(name) { |*args| raise "you must upgrade Rails to call #{name}" }
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we need this, we already get the NoMethodError for free after all ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree. This is my way around Rubocop's "do not suppress exceptions error". Turns out, after writing it, I actually like it. Yay for helpful error messages.

I originally wrote this PR as a one-liner:

include ActionDispatch::IntegrationTest::Behavior rescue NameError

but Rubocop didn't like that.

So I did a block:

     begin
        include ActionDispatch::IntegrationTest::Behavior
      rescue NameError
        # if AD::IT::Behavior doesn't exist, that just means that Rails is old
        # and integration test helpers (like assert_select) aren't available.
      end

And it didn't like that either. So I went all the way to this.

Happy to throw a # rubocop:disable Lint/HandleExceptions and got back to the one-liner if you'd prefer. But I kinda vote for the error messages.

@bronson bronson force-pushed the patch-1 branch 2 times, most recently from 322a684 to 53571a4 Compare February 26, 2016 03:10
@bronson
Copy link
Contributor Author

bronson commented Mar 7, 2016

The Rails side is merged.

@JonRowe shall I delete IntegrationHelperWarnings and put in # rubocop:disable Lint/HandleExceptions instead? (otherwise Rubocop complains about the empty rescue)

Like we discussed, I'm partial to the helpful error message, but I'd like to do whatever you think is best.

@filialpails
Copy link

Regarding the modifier form of rescue,

include ActionDispatch::IntegrationTest::Behavior rescue NameError

isn't equivalent to

begin
  include ActionDispatch::IntegrationTest::Behavior
rescue NameError
end

but to

begin
  include ActionDispatch::IntegrationTest::Behavior
rescue
  NameError
end

You can't rescue a particular class of exceptions with the modifier form. It always rescues StandardError and its descendants.

@bronson
Copy link
Contributor Author

bronson commented Mar 8, 2016

That's true. Block form would be best here.

The question is, what should go in that block? The fake module, or a comment to placate the linter?

@JonRowe
Copy link
Member

JonRowe commented Mar 9, 2016

# rubocop:disable Lint/HandleExceptions is fine if a comment in the rescue block doesn't do that for you.

@bronson bronson force-pushed the patch-1 branch 3 times, most recently from 0e926be to 6107b53 Compare March 9, 2016 01:32
@bronson
Copy link
Contributor Author

bronson commented Mar 9, 2016

Rebased and ready. The Travis breakage is identical to master so this branch should be fine.

This allows request specs to call assert_select, url_for, etc.
@bronson
Copy link
Contributor Author

bronson commented Mar 9, 2016

Arg, updated the comment:

- # rails is too old to provide request helpers
+ # rails is too old to provide integration test helpers

Everything else is unchanged, still ready to merge.

JonRowe added a commit that referenced this pull request Mar 9, 2016
let request specs use integration test services
@JonRowe JonRowe merged commit 73890bc into rspec:master Mar 9, 2016
@JonRowe
Copy link
Member

JonRowe commented Mar 9, 2016

Thanks

@bronson
Copy link
Contributor Author

bronson commented Mar 11, 2016

just for posterity, this is the patch that displayed a helpful error:

diff --git a/lib/rspec/rails/example/request_example_group.rb b/lib/rspec/rails/example/request_example_group.rb
index d308bce..f53bcef 100644
--- a/lib/rspec/rails/example/request_example_group.rb
+++ b/lib/rspec/rails/example/request_example_group.rb
@@ -1,5 +1,14 @@
 module RSpec
   module Rails
+    # Raises an error if the user tries to call integration test helpers.
+    # If the helpers are available then this module will be ignored.
+    module IntegrationHelperWarnings
+      extend ActiveSupport::Concern
+      [:assert_select, :url_for, :url_options].each do |name|
+        define_method(name) { |*| raise "you must upgrade Rails to call #{name}" }
+      end
+    end
+
     # @api public
     # Container class for request spec functionality.
     module RequestExampleGroup
@@ -11,6 +20,12 @@ module RSpec
       include RSpec::Rails::Matchers::RenderTemplate
       include ActionController::TemplateAssertions

+      begin
+        include ActionDispatch::IntegrationTest::Behavior
+      rescue NameError
+        include IntegrationHelperWarnings
+      end
+
       # Delegates to `Rails.application`.
       def app
         ::Rails.application

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants