rspec-mocks icon indicating copy to clipboard operation
rspec-mocks copied to clipboard

Exclude stubbed classes from subclasses after teardown

Open GCorbel opened this issue 1 year ago • 15 comments

This fix https://github.com/rspec/rspec-mocks/issues/1568.

Stubbed classes are excluded from parent subclasses after each spec.

The original issue :

begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
  raise e
end

gemfile(true) do
  source "https://rubygems.org"

  gem "rspec", "3.12.0" # Activate the gem and version you are reporting the issue against.
  gem 'rspec-mocks', '3.12.6'
end

puts "Ruby version is: #{RUBY_VERSION}" # Ruby version is: 3.1.4

class Something; end

describe 'Test' do
  before(:each) do
    class A < Something; end
    stub_const('B', Class.new(Something))
  end

  it 'something' do
    puts Something.subclasses # => [B, A]
  end

  it 'something else' do
    puts Something.subclasses # => [B, B, A]
    # Only one occurence of B should be listed
  end
end

Now, Something.subclasses always return [B, A].

GCorbel avatar Feb 20 '24 22:02 GCorbel

I’m skeptical, however, to include it for everyone. There might be some performance impact, and since this can introduce flakiness due to the GC race condition and an exception is not reassuring.

I understand your worries. I would like to find a better solution but wasn't able.

Maybe we can use a config as excluded_stubbed_const_from_subclasses or enable it by default and do a config as thread_safe_garabage_collection ?

GCorbel avatar Feb 21 '24 15:02 GCorbel

The more I think, the more I'm in favor of a config flag. Maybe a warning message that say the flag have to be switched should be displayed when there is an error.

GCorbel avatar Feb 21 '24 15:02 GCorbel

I support your idea of opting in for this with a flag.

pirj avatar Feb 21 '24 15:02 pirj

We could conditionally require weakref if this option is on.

pirj avatar Feb 21 '24 15:02 pirj

Should we have the option on by default ?

GCorbel avatar Feb 21 '24 16:02 GCorbel

No. But we’re working in RSpec 4, and we can think about enabling it there unless performance considerations come up.

pirj avatar Feb 21 '24 17:02 pirj

I change to run specs only for Ruby 3.1 and ahead as in https://github.com/rails/rails/blob/v7.0.8/activesupport/lib/active_support/ruby_features.rb

GCorbel avatar Feb 29 '24 20:02 GCorbel

Sorry, my latest commit was completely broke. I fixed it.

GCorbel avatar Mar 04 '24 18:03 GCorbel

I fixed the code for Ruby <= 2.4

GCorbel avatar Mar 04 '24 21:03 GCorbel

The CI pass except for "ruby-head" which is not to my commit

GCorbel avatar Mar 05 '24 16:03 GCorbel

I fixed a flap on specs. Now the CI should pass.

GCorbel avatar Mar 06 '24 14:03 GCorbel

I finally succeeded to install Ruby 3.4-dev locally and confirm that the error on the CI is not related to the PR. It also fail on the main branch.

GCorbel avatar Mar 06 '24 17:03 GCorbel

Hello, I don't want to bother you but is it possible to have a quick review, at least on the global behavior? I'm waiting for this to be able to move forward on the project I'm working on.

GCorbel avatar Mar 25 '24 14:03 GCorbel

Please accept my apologies for the wait. The code is mostly good, thanks!

No problem, it's open source. You don't even have to reply.

GCorbel avatar Mar 26 '24 16:03 GCorbel

@JonRowe can you give a look at this request ?

GCorbel avatar May 14 '24 16:05 GCorbel

I'd like to apologise for leaving this hanging for so long, its been on my review list for ages but I just haven't been able to get around to it, I had a couple of concerns about weak ref and other such behaviour but following on from the discussion in #1568 I'm going to close this. Sorry to have wasted your time.

JonRowe avatar Sep 27 '24 10:09 JonRowe