-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
Proposal: assert.matchObject #50399
Comments
/cc @nodejs/assert. This doesn't seem like a bad idea to me. |
so the difference between this and |
yes.
Well, I guess so, but i'm more convinced that it should be the same as many other testing frameworks as a dedicated method. |
To me "assert to match object" is really not something I could understand without reading its docs, so I would prefer if we picked a different name. I think adding |
+1 on that. |
imo no. the current signature of deepEqual is A way to make this would would require a soft breaking change with a new signature of: deepEqual<T>(actual: unknown, expected: T, messageOrOption?: string | {
message?: string;
superset?: boolean;
}) |
@aduh95 I agree matchObject isn't a great name if it were to work with arrays (as does jest toMatchObject), but I also don't like adding an option to deepStrictEqual for the same reason as my previous comment. How about |
I think it would be fine to make the optional third argument an options object if not a string, as you suggested - and will ensure future compatibility for additional options. |
"superset" is a confusing name for this behavior; "allowExtraProperties", maybe? |
Just extending the function deepStrictEqual<T>(actual: unknown, expected: T, message?: string | Error): asserts actual is T;
function deepStrictEqual<T>(actual: unknown, expected: T, options?: { superset?: boolean }, message?: string | Error): asserts actual is T; I'm still not sure if an attribute would have a better DX: // attribute
assert.deepStrictEqual(
obj,
{
a: 1,
b: 2
},
{
superset: true
}
);
// custom method
assert.deepSupersetEqual(obj, {
a: 1,
b: 2
}); |
what is the downside of a new method? @aduh95 |
It's verbose, and another thing to learn, and having two methods that are identical except for one aspect is strange when it could be one method with an option. |
But wouldn't this behavior align with many other testing frameworks? |
Not all of them - iirc, in jasmine you’d use a special matcher wrapper around the object to indicate a partial match |
Either way tho, by and large there simply isn't a single cohesive ecosystem consensus around any part of testing. The downside of that is that node runs the risk of conflating patterns and confusing users; the upside is that node is free to make its own decisions. |
I agree, either way we should make a decision, right? What options are being considered? Should I make a poll? |
I don't want to build by committee. I rather have one person do the leg work and make a recommendation. People are then free to criticize and make another recommendation if they so please. |
I'd love to work on this feature, could anyone give me a heads up on where to start? Apparently I should start supporting the keyCheck function used in innerDeepEqual, to just compare properties of val2 in val1 and not in both sides |
That sounds right. It's called |
I have a working implementation and I'll open a PR for it soon (I need to finish updating the docs, add more tests and make sure the error message is not weird). The error message can't display a diff for now as the object tested for might highly deviate and we need a new implementation for the diff. How to expose it can still be discussed. I think it's easiest and most user friendly to have a separate API next to |
Looking at it without context, I still think the name |
Has anyone ever considered a DX like the following?
|
This way, if we also wanted a corresponding method to match array subsets, it would have to be called Given that we currently have
‘contains’ makes sense, but the naming should match existing JavaScript parlance, which, for reasons, went with To clarify, something like: import assert from "node:assert/strict"
assert.deepMatch({ a: 1, b: 2, c: 3 }, { b: 2 }) // pass
assert.deepMatch([1, 2, 3], [2]) // pass Then, for import assert from "node:assert/strict"
assert.includes ??= (a, b) => assert.equal(a.includes(b), true)
assert.includes("abc", "b") // pass
assert.includes([1, 2, 3], 2) // pass @arthurfiorette @targos @ljharb @MoLow @reconbot @synapse @simoneb What do you guys think? |
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
Fixes: nodejs#50399 Co-Authored-By: Cristian Barlutiu <[email protected]> PR-URL: nodejs#54630 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Moshe Atlow <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Chemi Atlow <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Jithil P Ponnan <[email protected]> Reviewed-By: Marco Ippolito <[email protected]>
Fixes: #50399 Co-Authored-By: Cristian Barlutiu <[email protected]> PR-URL: #54630 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Moshe Atlow <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Chemi Atlow <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Jithil P Ponnan <[email protected]> Reviewed-By: Marco Ippolito <[email protected]>
Fixes: #50399 Co-Authored-By: Cristian Barlutiu <[email protected]> PR-URL: #54630 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Moshe Atlow <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Chemi Atlow <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Jithil P Ponnan <[email protected]> Reviewed-By: Marco Ippolito <[email protected]>
Fixes: #50399 Co-Authored-By: Cristian Barlutiu <[email protected]> PR-URL: #54630 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Moshe Atlow <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Chemi Atlow <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Jithil P Ponnan <[email protected]> Reviewed-By: Marco Ippolito <[email protected]>
Fixes: #50399 Co-Authored-By: Cristian Barlutiu <[email protected]> PR-URL: #54630 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Moshe Atlow <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Chemi Atlow <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Jithil P Ponnan <[email protected]> Reviewed-By: Marco Ippolito <[email protected]>
What is the problem this feature will solve?
(I tried searching for related issues, but couldn't find one, sorry if this is a duplicated)
One thing I miss when using
node:test
andnode:assert
fromjest
related tests is theexpect(A).toMatchObject(B)
api. Within large production systems, a we usually have large objects with multiple deep properties, withassert.matchObject
we could test the same way asassert.deepStrictEqual
, but only specifyingexpected
properties we want to test out with a much nicer DX. Obviously aassert.notMatchObject
should also be present.Current behavior:
What is the feature you are proposing to solve the problem?
With
assert.matchObject
:It should ensure equality only for properties assigned to the second parameter.
myObjectToTest
could have 10000 other attributes or be literally the same as the second parameter, it would pass. Whenever a property declared inside the second object is not present in the first one, anAssertionError
should be thrown.Of course this is a small example that could be tested separately, but it is a perfect DX fit for large objects.
What alternatives have you considered?
I'm creating this feature request with a jest like API in mind, however any alternatives that also fixes this problem are welcome :) I'm also open to working on this, but first I need some kind of guidance :)
The text was updated successfully, but these errors were encountered: