mjackson / expect

Write better assertions
MIT License
2.29k stars 117 forks source link

Support tmatch in toHaveBeenCalledWith #107

Open jraede opened 8 years ago

jraede commented 8 years ago

Is there a way to do something like this:

expect(mySpy).toHaveBeenCalledWith('foo', 'bar', anythingOfType(Function));

Seems like we would have to modify the isEqual test helper.

ljharb commented 8 years ago

How would "of type" be determined? instanceof is both unreliable and doesn't work cross-realm - this code is what's actually required to reliably determine that something is a function.

The only API i can think of that might work is one where the user decides for themselves - ie, anythingOfType would need to take a predicate function that received the value, and returned a boolean to indicate whether it passed. Thoughts?

jraede commented 8 years ago

Yeah I think allowing a predicate function would be the most pluggable. In order to have the isEqual know whether to run the function or compare its equality we could add something like matchingPredicate(myPredicate) or matcher(myPredicate) which would return some sort of object that isEqual could recognize and run the predicate function.

It would be pretty cool to implement something like I did in simplecheck or just add support for that library, so we could do things like

expect(mySpy).toHaveBeenCalledWith('foo', 'bar', simplecheckMatcher({
     someProp: String,
     someOtherProp: oneOf(1, 2),
}));
mjackson commented 8 years ago

@jraede We already use tmatch under the hood in in toMatch. Maybe we could use it here as well? Seems like it does the same thing as simplecheck.

ZephD commented 7 years ago

The ability to do partial object checks with toHaveBeenCalledWith would be fantastic, so +1. Something like:

const obj = { a: 'a', b: 'b' };
const spy = expect.createSpy();
spy(obj);
expect(spy).toHaveBeenCalledWith({ a: 'a' })