Skip to content

Commit

Permalink
Merge pull request #1470 from eregon/better-check-for-Class-new
Browse files Browse the repository at this point in the history
Use a better and more reliable check for whether a method is the same as Class#new
  • Loading branch information
JonRowe committed Apr 22, 2022
2 parents 1611752 + c0c2e44 commit e994d52
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
16 changes: 14 additions & 2 deletions lib/rspec/mocks/method_reference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,23 @@ class ClassNewMethodReference < ObjectMethodReference
def self.applies_to?(method_name)
return false unless method_name == :new
klass = yield
return false unless klass.respond_to?(:new, true)
return false unless ::Class === klass && klass.respond_to?(:new, true)

# We only want to apply our special logic to normal `new` methods.
# Methods that the user has monkeyed with should be left as-is.
::RSpec::Support.method_handle_for(klass, :new).owner == ::Class
uses_class_new?(klass)
end

if RUBY_VERSION.to_i >= 3
CLASS_NEW = ::Class.singleton_class.instance_method(:new)

def self.uses_class_new?(klass)
::RSpec::Support.method_handle_for(klass, :new) == CLASS_NEW.bind(klass)
end
else # Ruby 2's Method#== is too strict
def self.uses_class_new?(klass)
::RSpec::Support.method_handle_for(klass, :new).owner == ::Class
end
end

def with_signature
Expand Down
14 changes: 14 additions & 0 deletions spec/rspec/mocks/partial_double_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,20 @@ class << self
end
end

context "on a class with a twice-aliased `new`" do
it 'uses the method signature from `#initialize` for arg verification', :if => (RUBY_VERSION.to_i >= 3) do
subclass = Class.new(klass) do
class << self
alias_method :_new, :new
alias_method :new, :_new
end
end

prevents(/arguments/) { allow(subclass).to receive(:new).with(1) }
allow(subclass).to receive(:new).with(1, 2)
end
end

context 'on a class that has redefined `self.method`' do
it 'allows the stubbing of :new' do
subclass = Class.new(klass) do
Expand Down

0 comments on commit e994d52

Please sign in to comment.