-
Notifications
You must be signed in to change notification settings - Fork 31.2k
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.any
for assert.deepEqual
to match on types instead of values
#55319
Comments
IIRC custom assertions have been discussed before, and people are, for the most part, +1 on them, however the specific details of how they'll work haven't yet been discussed. For your specific case, comparing the |
Do not get this fully. How is this meant? |
I meant that for your specific case,
|
I think it's a good idea to add such functionality. The details would have to be clarified and they might be a bit more tricky but it's something I also wanted for a while already. @redyetidev I don't think this is a good alternative as it would require multiple different assertions instead of one. |
@nodejs/assert |
👍 on this. I agree, |
I'm definitely in favor of this, and I'm excited to see where it could go. Hypothetically, the following could be a possible (though very rough) starting point:
(With the same alternative syntax) |
@redyetidev Yeah, sounds great. But definitely make sure this can be used in an (nested) object, like in your second example. This is the whole point about it. To make tests on dynamically changing objects easier. |
import { strict as assert, AssertionError } from 'node:assert';
assert.define = (cb) => {
const customAssertion = (...args) => {
try {
if (!cb(...args)) {
// Some logic would go here to show *where* the assertion failed,
// similarly to assert(false) showing the failed assertion
throw new AssertionError({
message: `${args[0]} failed a custom assertion with ${args[1]}`,
actual: args[0],
expected: args[1],
operator: cb,
stackStartFn: customAssertion,
});
}
} catch (e) {
if (e instanceof AssertionError) {
// Some logic would go here to show *where* the assertion failed,
// similarly to assert(false) showing the failed assertion
throw e;
}
throw e;
}
};
return customAssertion;
};
const assertGte = assert.define((a, b) => {
if (a < b) {
throw new AssertionError({
message: `${a} is not greater than or equal to ${b}`,
actual: a,
expected: b,
operator: '>=',
});
}
return true;
});
assertGte(5, 10); For |
The problematic part is how to implement this in the existing code. It is used in The visualized error is also problematic. Throwing an error inside of the assertion method would be fine. Otherwise it's tricky. |
A possibility would be to use a WeakSet for detecting the methods being created by assert. The existence check would also not be that costly. |
The challenge with any special sentinel values that can be stored in a nested object is that those very values might be present in the |
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the
never-stale
|
What is the problem this feature will solve?
Given for example a
Date.now
in a nested object I would like be able to rundeepEqual
on the object.Such situation often happens if you are testing responses from APIs or something similar.
This obviously will throw an AssertionError:
What is the feature you are proposing to solve the problem?
One option would be to introduce an asymmetric matcher
assert.any
that could dynamically check on the given type in the expected object.Checking the type is often enough in such situation.
This would pass:
Another option would be to let you define custom asymmetric matchers:
What alternatives have you considered?
I tried to use another assertion library which are capable of doing this: Vitest, unexpected.js, Jest
But this gives mangled output and I am not satisfied to bring in such big libraries for the sake of only doing asymmetric matching. Also I explain my tests in a documentation for other developers and I would like to use the Node built-in tools for simplicity.
The text was updated successfully, but these errors were encountered: