Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Conversation

nepalez
Copy link
Contributor

@nepalez nepalez commented Jan 16, 2016

With reference to #1055

Allows rspec matchers inherited from RSpec::Mocks::Matchers::* to be used
both in mocks and expectations:

  class ReceiveFoo < RSpec::Mocks::Matchers::Receive
    def initialize
      super :foo, nil
    end
  end

  describe "receiving foo" do
    it "works" do
      object = double

      allow(object).to receive_foo
      expect(object).to receive_foo

      object.foo
    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.

Suggestion: instead of doing a linear search over all the ancestors and implicitly using the matcher class name, what do you think of creating an explicit "tag" module that you can check instead? I'm thinking of something like this:

module RSpec
  module Mocks
    module Matchers
      # exists just so we can "tag" all rspec-mocks matchers to make detection of them easier.
      module Matcher; end

      # now include the module in each of our matcher classes...
      class HaveReceived
        include Matcher
      end

      class Receive
        include Matcher
      end

      class ReceiveMessages
        include Matcher
      end

      class ReceiveMessageChain
        include Matcher
      end

      # ...and then we can detect rspec-mocks matchers with a simple `===` check:
      def matcher_allowed?(matcher)
        RSpec::Mocks::Matchers::Matcher === matcher
      end
    end
  end
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Amazing technics :)

It seems offhand, that if we go this way, it can lead us to extraction of the "essential/mockable" part of the matcher to the module. For now this is just a speculation, I need time to play with the idea.

Copy link
Member

Choose a reason for hiding this comment

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

It seems offhand, that if we go this way, it can lead us to extraction of the "essential/mockable" part of the matcher to the module. For now this is just a speculation, I need time to play with the idea.

No. Delegation is more useful than inheritance in this fashion. We don't want to encourage more inheritance of our private APIs only support reasonable use cases like this. This module should only be used to improve the detection of inherited matchers from our own.

Copy link
Member

Choose a reason for hiding this comment

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

With reference to #1055

Allows rspec matchers inherited from `RSpec::Mocks::Matchers::*` to be used
both in mocks and expectations:

  class ReceiveFoo < RSpec::Mocks::Matchers::Receive
    def initialize
      super :foo, nil
    end
  end

  describe "receiving foo" do
    it "works" do
      object = double

      allow(object).to receive_foo
      expect(object).to receive_foo

      object.foo
    end
  end
JonRowe added a commit that referenced this pull request Jan 18, 2016
@JonRowe JonRowe merged commit c2937e0 into rspec:master Jan 18, 2016
@JonRowe
Copy link
Member

JonRowe commented Jan 18, 2016

Thanks! :)

JonRowe added a commit that referenced this pull request Jan 18, 2016
JonRowe added a commit that referenced this pull request Jan 18, 2016
Conflicts:
	Changelog.md
	lib/rspec/mocks.rb
yujinakayama pushed a commit to yujinakayama/rspec-monorepo that referenced this pull request Oct 6, 2021
Conflicts:
	Changelog.md
	lib/rspec/mocks.rb

---
This commit was imported from rspec/rspec-mocks@f0295bb.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants