lunarmodules / luassert

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

Add `self` modifier to spies #167

Closed 13k closed 2 years ago

13k commented 4 years ago

This PR adds a self modifier that works only with spy.on() spies (spies that have a target table) and the called_with assertion, since for the other assertions it doesn't make much sense [1].

It's essentially syntax sugar for called_with(match.is_ref(table), args...).

The goal is to be a cleaner "fix" for #162, making the suite code more readable:

spy.on(t, "fn")

t:fn(1, 2)

-- with `self` modifier
assert.spy(t.fn).was.self.called_with(1, 2)
-- without `self` modifier
assert.spy(t.fn).was.called_with(match.is_ref(t), 1, 2)

Under the hood, the modifier simply adds a flag to the state, if applicable. It throws an error if the flag is already set, like the array modifier does. It also throws an error if the spy doesn't have a target table (like pure callbacks created with spy.new).

Assertions then check for the flag. If it's set, called_with will inject a match.is_ref() check against the target table as the first argument. The other assertions will throw an error [2].

[1] It makes sense for the called(1) special case, where self.called() could be an alias to self.called_with(). I didn't change called() with this special case because failure messages would be somewhat confusing.

[2] This behavior is debatable. Should it throw an error or silently ignore the self modifier?