lunarmodules / luassert

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

spy `was_called_with` fails when `self` is touched #162

Closed rubensayshi closed 5 years ago

rubensayshi commented 5 years ago

I'm a bit new to lua and I'm certain that this probably makes (slightly more) sense to people who do understand the inner workings of lua and luasert, but what I'm running into is inconvenient at best...

when I try to use assert.spy().was_called_with for a method that's bound with :, I need to add the object to the obj to was_called_with as first argument, which makes sense.
but what doesn't make sense is that if the object has been modified between the call and the assert then it fails.

I suspect you have some way to snapshot the arguments being passed in and for a table that means it will think it's a different table being passed in.

this looks like a bug to me, but maybe there's a better way of doing this assertion that doesn't fail, in that case maybe just updating the docs to explain people that would be good enough ;-)

        describe("spies", function()
            it("replaces an original function", function()
                local t = {
                    defaultmsg = "hiii",
                    somerandomproperty = true,
                }

                function t:greet(msg) if msg then print(msg) else print(self.defaultmsg) end end

                local s = spy.on(t, "greet")

                t:greet("Hey!") -- prints 'Hey!'
                assert.spy(t.greet).was_called_with(t, "Hey!")

                t:greet("Hey!") -- prints 'Hey!'

                -- when touching t the next assert fails
                t.somerandomproperty = false
                assert.spy(t.greet).was_called_with(t, "Hey!")
            end)
        end)

it also similarly fails if the mutation it done by the method called, which was ofc my original problem, the above was trying to isolate the problem;

        describe("spies", function()
            it("replaces an original function", function()
                local t = {
                    cnt = 0,
                }

                function t:greet(msg)
                    self.cnt = self.cnt + 1
                    print(msg)
                end

                local s = spy.on(t, "greet")

                t:greet("Hey!") -- prints 'Hey!'
                -- this assert will fail because `t` was touched 
                assert.spy(s).was_called_with(t, "Hey!")
            end)
        end)

PS. <3 busted, a light in the dark when learning lua