-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
assert: add new callTracker.callsWith function #43133
assert: add new callTracker.callsWith function #43133
Conversation
406b2a0
to
8290594
Compare
cca51af
to
afcbd38
Compare
this also adds the replaceme tag on the docs
afcbd38
to
4d56b1c
Compare
is it ready to go? |
cc: @nodejs/assert |
@@ -322,6 +322,88 @@ function func() {} | |||
const callsfunc = tracker.calls(func); | |||
``` | |||
|
|||
### `tracker.callsWith([fn],withArgs[, exact])` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### `tracker.callsWith([fn],withArgs[, exact])` | |
### `tracker.callsWith([fn], withArgs[, exact])` |
it is very strange to have an optional argument before a required one. can that be reevaluated?
The wrapper function is expected to be called exactly `exact` times and | ||
to be called exactly with `withArgs` arguments. | ||
|
||
The `withArgs` will compare whether the function arguments are deep-strict equal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The `withArgs` will compare whether the function arguments are deep-strict equal | |
The `withArgs` will compare whether the function arguments are deep-strict equal. |
[`tracker.verify()`][] is called, then [`tracker.verify()`][] will throw an | ||
error. | ||
|
||
```mjs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
```mjs | |
```js |
i don't think mjs is a syntax highlighting mode, this is just JS
if (context.actual === context.exact) { | ||
|
||
// Only spy args if requested | ||
if (context.expectedArgs.length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this checking if it's truthy, or if it's > 1? a user doesn't have to pass in a number, does it?
details: ArrayPrototypePush([], { | ||
message, | ||
operator: 'callsWith', | ||
stack: genericNodeError() | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
details: ArrayPrototypePush([], { | |
message, | |
operator: 'callsWith', | |
stack: genericNodeError() | |
}) | |
details: [{ | |
message, | |
operator: 'callsWith', | |
stack: genericNodeError() | |
}] |
I don't know if this is a good idea.
|
Just a thing, I didn't like either the design of this API so I opened this Issue to make it extendable. I got a green signal to go forward on this implementation so I believe I'd mark this PR as draft until I finish the new design in the next few weeks. Well, I agree this can be done on the userland however I was wondering to implement something like Sinon Spies does to avoid verbosity and replicated code. This example you pointed out I believe is something expected. Even using only {
function testBuffer(buffer) {
buffer.slice(0, 10);
}
const ct = new assert.CallTracker();
const fn = ct.calls(testBuffer);
// This throws from within testBuffer:
fn(null);
// This is never reached, so callsWith() never produces a visible error:
ct.verify();
} About those questions: What if I want to additionally verify the value of this? What if I want to ignore a specific argument?
What if I only want to check the typeof of an argument?
What if I want reference equality (instead of deep equality) for a specific argument?
|
I'm rolling back this PR to Draft as the #43341 will change the function's signature. As soon as it's landed I'll came back here |
Sinon Spies are a good example of a userland implementation. That being said, Sinon's
Yes, but My understanding is that the entire purpose of
Sinon has
If every additional feature will require additional options, the complexity of this API will explode rapidly.
I don't understand; I think |
@ErickWendel it's totally up to you, but you may want to take a look at cjihrig@e484301. It's proof of concept work for adding mocking to Node's test runner. It probably overlaps with this a bit. |
Uh I liked it! I'm in vacation right now. As soon as I'm back I'll take a look at it |
@ErickWendel I think a much more powerful API can be an API exposing an array of calls and their params, this way you can decide what assersions to perform on the arguments, I thought of something like this const tracked = callTracker.track(() => {});
assert.strictEqual(tracked.calls.length, 0);
tracked('bar');
assert.strictEqual(tracked.calls.length, 1);
assert.strictEqual(tracked.calls[0], { arguments: ['bar'] }); WDYT? |
wooww I loved the idea. I think Sinon does the same thing right? |
Cool I implemented some POC MoLow@ecd3ff7 |
closing this PR as it has another one in progress with the PoC MoLow@ecd3ff7 |
@ErickWendel can you link to the other PR? |
just linked your PoC and realized it's not a PR, is it? |
Ah, I did not want to open a PR before you told me you are ok with it. I will rebase my branch and open a PR |
oh perfect! Sorry for the mess 😂 |
This PR adds a new
callTracker.callsWith
function and its docs