psyho / bogus

Fake library for Ruby
Other
359 stars 14 forks source link

Proc argument matcher matches all or nothing #37

Closed ml closed 10 years ago

ml commented 10 years ago

I am not able to use proc argument matcher to match just argument among a few:

mock(ESP::Mail).deliver("kiszonka", with { |message| message[:to] == "stefan@kiszonka.com" })

ESP::Mail.deliver "kiszonka", to: "stefan@kiszonka.com"

doesn't work and the matcher never gets called, while

mock(ESP::Mail).deliver(with { |template_name, message| 
 template_name == "kiszonka" && message[:to] == "stefan@kiszonka.com" })

ESP::Mail.deliver "kiszonka", to: "stefan@kiszonka.com"

works. Is it desired behavior and I'm just doing something wrong?

psyho commented 10 years ago

The with matcher is used to check all of the arguments together, that's why the second version works.

At the moment we don't have a single argument matcher with a proc, but it's very easy to add yourself, since the matchers are essentially just objects with overridden equality checks:

class Matches
  def initialize(&block)
    @block = block
  end

  def ==(argument)
    @block.call(argument)
  end
end

def matches(&block)
  Matches.new(&block)
end

and you will be able to use it like this:

mock(ESP::Mail).deliver("kiszonka", matches { |message| message[:to] == "stefan@kiszonka.com" })

We'll add something like this in the next version.