Skip to content

Conversation

benoittgt
Copy link
Member

This method has been moved in rails/rails@3cece0b
We do not include ActiveSupport::Testing::Assertion at the moment.

To avoid having to deal with complicated scenarios like Minitest errors. We redefine our own methods in rspec-rails.


I am really not sure about the approach.

Few questions:


As always feel free to push on this branch and amend my commit.

Fix: #2410

@benoittgt benoittgt marked this pull request as draft December 11, 2020 00:19
@benoittgt
Copy link
Member Author

Still in draft because for the CI but open for review.

Sorry I am very tired.

@JonRowe
Copy link
Member

JonRowe commented Dec 11, 2020

@benoittgt I would just include the new module from Rails, my reasoning is that their test helpers are built on their assertions, and by implementing them ourselves we will always lag behind. Take care of yourself!

@@ -71,6 +71,9 @@ def self.initialize_configuration(config) # rubocop:disable Metrics/MethodLength
config.add_setting :fixture_path
config.include RSpec::Rails::FixtureSupport, :use_fixtures

# Prevent test from failing on undefined method used in ActiveSupport testing helpers
config.include ActiveSupport::Testing::Assertions
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to check if this is defined? / Can we pull it into one of our existing modules?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was very curious about the CI.
I am pretty confident. This class exist since at least Rails 4.2 https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/testing/assertions.rb

I tried in RailsExampleGroup but it was not working, I still had the same error. I will keep digging.

Copy link
Member

Choose a reason for hiding this comment

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

Ok! I'll wait for your experiments to finish :)

Copy link
Member Author

Choose a reason for hiding this comment

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

I added a check on version. It's pretty basic but I think enough for our needs.

:foo
end
}.to_not raise_error
end
Copy link
Member

Choose a reason for hiding this comment

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

👍

@benoittgt benoittgt force-pushed the rails-6.1.0.rc2-assert-dev branch from 272b9fc to 181e33d Compare December 12, 2020 20:26
@benoittgt
Copy link
Member Author

The commit that probably impact us is https://github.com/rails/rails/pull/26293/files
But I don't understand because activesupport/lib/active_support/testing/assertions.rb is included in activesupport/lib/active_support/test_case.rb.

@benoittgt
Copy link
Member Author

Ok. It fails on 5.0.7.2.

Even with

--- a/lib/rspec/rails/configuration.rb
+++ b/lib/rspec/rails/configuration.rb
@@ -72,7 +72,9 @@ module RSpec
       config.include RSpec::Rails::FixtureSupport, :use_fixtures

       # Prevent test from failing on undefined method used in ActiveSupport testing helpers
-      config.include ActiveSupport::Testing::Assertions
+      if ::Rails::VERSION::STRING.to_f >= 6.1
+        config.include ActiveSupport::Testing::Assertions
+      end

I have a failure locally like the CI. How people can say it was working before? Maybe active_support/test_case is loaded into specific type of specs and we should validate our patch using example spec?

I am wondering if the best approach is to require ActiveSupport::Testing::Assertion into our different example like here

include ActionMailer::TestCase::Behavior

Copy link
Member

@pirj pirj left a comment

Choose a reason for hiding this comment

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

Way to go! 👍
Thanks

@benoittgt benoittgt force-pushed the rails-6.1.0.rc2-assert-dev branch 3 times, most recently from 3d0dc5e to 0e5d606 Compare December 16, 2020 22:47
@benoittgt benoittgt marked this pull request as ready for review December 16, 2020 23:07
# Prevent test from failing on undefined method used in ActiveSupport testing helpers
if ::Rails::VERSION::STRING.to_f >= 6.0
config.include ActiveSupport::Testing::Assertions
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 think this implementation needs to go in lib/rspec/rails/adapters.rb or lib/rspec/rails/example/rails_example_group.rb

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried this initially but was not able to make it work.

For lib/rspec/rails/example/rails_example_group.rb with:

--- a/lib/rspec/rails/example/rails_example_group.rb
+++ b/lib/rspec/rails/example/rails_example_group.rb
@@ -12,6 +12,11 @@ module RSpec
       include RSpec::Rails::MinitestLifecycleAdapter
       include RSpec::Rails::MinitestAssertionAdapter
       include RSpec::Rails::FixtureSupport
+
+      # Prevent test from failing on undefined method used in ActiveSupport testing helpers
+      if ::Rails::VERSION::STRING.to_f >= 6.0
+        include ActiveSupport::Testing::Assertions
+      end

From a Rails app that use rspec-rails with a test that call assert_nothing_raised, I get:

NameError:
  uninitialized constant ActiveSupport::Testing::Assertion

For lib/rspec/rails/adapters.rb this is pretty complicated inside. I tried to put in in multiple places but I am having error like from my Rails app:

NameError:
  uninitialized constant ActiveSupport::Testing

The other place were we properly load an active support testing class is in
https://github.com/rspec/rspec-rails/blob/rails-6-1-dev/lib/rspec/rails/fixture_file_upload_support.rb#L42
and then it is loaded in configuration

config.include RSpec::Rails::FixtureFileUploadSupport

I am stuck to provide you another solution ATM. 😬

@benoittgt benoittgt mentioned this pull request Dec 19, 2020
3 tasks
@pirj pirj added this to the 4.1 milestone Dec 24, 2020
@doits
Copy link
Contributor

doits commented Jan 19, 2021

This is fixed in Rails 6.1.1. rails/rails#40780, nothing to do here 🎉

@benoittgt
Copy link
Member Author

benoittgt commented Jan 20, 2021

I can confirm that the regression is no longer visible in 6.1.1 but my spec here do not reflect that change, it is still failing.

I do not see a place where we handle this kind of regression check at a Rails level.

For the Rails level spec, we have feature spec, but they are also used for documentation. What we could do, could be to make the small app snippet as in #2423 ? Or last option, do not test for this regression that is more related to Rails itself. We never use assert_nothing_raise in our code base. WDYT @JonRowe and @pirj.

This method has been moved in rails/rails@3cece0b
We do not include ActiveSupport::Testing::Assertion.

Method was added back in rails/rails#40780, and
was released in Rails 6.1.1
@pirj pirj force-pushed the rails-6.1.0.rc2-assert-dev branch from 0e5d606 to 1f16b45 Compare January 20, 2021 21:55
@pirj pirj changed the base branch from rails-6.1.0.rc2-dev to rails-6-1-dev January 20, 2021 21:56
@pirj
Copy link
Member

pirj commented Jan 20, 2021

Removed the fix, only kept the regression test as per #2410 (comment).

Fails on 6.1.1, and 6.0 as well.

Snippets don't help much, there's still the same error.

rails/rails#40780 brought this method back to ActiveJob::TestHelper, and I struggle to understand how it can help us to get rid of the error. According to features/job_specs/job_spec.feature:

Job specs provide alternative assertions to those available in ActiveJob::TestHelper and help assert behaviour of the jobs themselves and that other entities correctly enqueue them.

Sorry for ruining the branch (I've also switched the target PR branch to rails-6-1-dev). Please feel free to push-force your local.

@pirj
Copy link
Member

pirj commented Jan 20, 2021

I'm not sure what is the real use case where assert_nothing_raised { ... } could be preferable over expect { ... }.not_to raise_error.
Is there a real use case?

@benoittgt
Copy link
Member Author

I am not sure the fix on Rails it the good solution because the initial move was rails/rails@3cece0b.

And for your last comment I have the same question. There is an interesting discussion on it here: minitest/minitest#809

@benoittgt
Copy link
Member Author

This should normally work, but it is not:

if __FILE__ =~ /^snippets/
  fail "Snippets are supposed to be run from their own directory to avoid side " \
       "effects as e.g. the root `Gemfile`, or `spec/spec_helpers.rb` to be " \
       "loaded by the root `.rspec`."
end

# We opt-out from using RubyGems, but `bundler/inline` requires it
require 'rubygems'

require "bundler/inline"

# We pass `false` to `gemfile` to skip the installation of gems,
# because it may install versions that would conflict with versions
# from the main `Gemfile.lock`.
gemfile(false) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Those Gemfiles carefully pick the right versions depending on
  # settings in the ENV, `.rails-version` and `maintenance-branch`.
  Dir.chdir('..') do
    # This Gemfile expects `maintenance-branch` file to be present
    # in the current directory.
    eval_gemfile 'Gemfile-rspec-dependencies'
    # This Gemfile expects `.rails-version` file
    eval_gemfile 'Gemfile-rails-dependencies'
  end

  gem "rspec-rails", path: "../"
end

# Run specs at exit
require "rspec/autorun"

# Initialization
require "active_job/railtie"

def skip_reason
  if Gem::Version.new(Rails.version) >= Gem::Version.new('6.1.1')
    false
  else
    "Skipping because Rails version is bellow 6.0 (Rails version: #{Rails.version})"
  end
end

# Rails project specs
RSpec.describe 'ActiveSupport::Testing::Assertions requirements', skip: skip_reason do
  it 'does not raise that "assert_nothing_raised" is undefined' do
    expect {
      assert_nothing_raised do
        :foo
      end
    }.to_not raise_error
  end
end

When we "puts caller" from where the new TestingAssertion has been added, we can see

/Users/bti/code/rails/activejob/lib/active_job/test_helper.rb:7:in `<module:ActiveJob>'
/Users/bti/code/rails/activejob/lib/active_job/test_helper.rb:5:in `<main>'
/Users/bti/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
/Users/bti/code/rails/activejob/lib/active_job/railtie.rb:35:in `block (2 levels) in <class:Railtie>'

@pirj
Copy link
Member

pirj commented Jan 26, 2021

I suggest we just close this and if questions arise, recommend including a module from Rails that provides this method. It would be an arguable situation for us to provide access to a method that is an extension of Minitest syntax.

@benoittgt
Copy link
Member Author

Thanks Phil for the followup. Yep I agree with you.

@benoittgt benoittgt closed this Jan 27, 2021
@benoittgt benoittgt deleted the rails-6.1.0.rc2-assert-dev branch January 27, 2021 20:27
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.

4 participants