lunarmodules / luassert

Assertion library for Lua
MIT License
202 stars 77 forks source link

assert.spy.was.called_with() should have variants just check equality. #129

Closed xpol closed 9 years ago

xpol commented 9 years ago

Lets see and example:

local Foo = {}
function Foo:add(Bar)
  Bar.callback(self)
  self.bar = Bar
end

local Bar = {}
function Bar.callback() end

describe('Foo', function()
  it(':add() calls Bar.callback()', function()
    local s = spy.on(Bar, 'callback')
    Foo:add(Bar) -- make a deep copy of Foo, before Foo.bar sets to Bar
    assert.spy(s).was.called(1) -- OK
    assert.spy(s).was.called_with(Foo) -- Failure, because Foo modified after callback...
  end)
end)
  1. The Foo:add() calls the spy and spy make a deep copy of Foo as FooCopy
  2. Then Foo:add() modifies Foo by add a Foo.bar = Bar
  3. The assert.spy(s).was.called_with(Foo) Failure because the Foo was not same as FooCopy.

So, I think it is needs that we have option in spy or called_with just keep a reference to its calling args and compare args by == (or something else).

DorianGray commented 9 years ago

It seems like there could be situations where someone wants both behaviors in a single spy. Would something like assert.spy(s).was.called_with(assert.reference(Foo)) be acceptable to force called_with to compare by reference instead of by value?

o-lim commented 9 years ago

This is solved by using the is_ref matcher. Just pass match.is_ref(foo) to called_with

describe('Foo', function()
  it(':add() calls Bar.callback()', function()
    local s = spy.on(Bar, 'callback')
    local match = require 'luassert.match`
    Foo:add(Bar) -- make a deep copy of Foo, before Foo.bar sets to Bar
    assert.spy(s).was.called(1) -- OK
    assert.spy(s).was.called_with(match.is_ref(Foo)) -- passes called_with compares against a reference to Foo
  end)
end)

See also issue #123, which the original issue referring to this behavior, and was resolved by PR #124, which introduced the is_ref matcher.

xpol commented 9 years ago

@o-lim Thank you very much!