Skip to content
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

stub_const does not restore Object.const_source_location after reset #1554

Open
tubaxenor opened this issue Sep 11, 2023 · 3 comments
Open

Comments

@tubaxenor
Copy link

tubaxenor commented Sep 11, 2023

Subject of the issue

When using stub_const, it does not reset Object.const_source_location after example finished.

Your environment

  • Ruby version: 2.7.5, 3.2.2
  • rspec-mocks version: 3.12.6

Steps to reproduce

File: spec/foo_spec.rb

class Foo; end

RSpec.describe Foo do
  it 'stubs and can be reset' do
    stub_const('Foo', Class.new)

    expect(Object.const_source_location('Foo').first).not_to include('foo_spec.rb')
    RSpec::Mocks.space.reset_all
    expect(Object.const_source_location('Foo').first).to include('foo_spec.rb')
  end
end

Expected behavior

Expect above test to pass.

Actual behavior

Foo
  stubs and can be reset (FAILED - 1)

Failures:

  1) Foo stubs and can be reset
     Failure/Error: expect(Object.const_source_location('Foo').first).to include('foo_spec.rb')
       expected "/Users/wei-fun.chang/workspace/rspec-mocks/lib/rspec/mocks/mutate_const.rb" to include "foo_spec.rb"
       ...
@pirj
Copy link
Member

pirj commented Sep 11, 2023

Would it reproduce if you’d put the class definition with the production code?

What is your use case?

@tubaxenor
Copy link
Author

tubaxenor commented Sep 11, 2023

Would it reproduce if you’d put the class definition with the production code?

I am not exactly sure the "production code" means here. Basically the const_set in reset will always set the source location to where it was called: https://github.com/rspec/rspec-mocks/blob/main/lib/rspec/mocks/mutate_const.rb#L229
Not an expert of C but I think it's defined here: https://github.com/ruby/ruby/blob/b1f0d009cbdf1990813c09165d372be29485f8ae/variable.c#L3482

What is your use case?

We have a code owner trace lib based on Object.const_source_location to map the code owner through the file path where the original class was defined. Recently there is a test flake caused by not able to pin down the owner because of source location changed to rspec-mock.

@JonRowe
Copy link
Member

JonRowe commented Sep 11, 2023

I'm not sure theres much we can do about that, given that the location of this is set by Ruby, we don't really have an alternate way to set constants that I know of, I would suggest you need to rework your tests to avoid using stub_const (or stub out const_source_location to remove the mock locations) sorry 😞

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

No branches or pull requests

3 participants