-
-
Notifications
You must be signed in to change notification settings - Fork 306
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
Support for comparing ES2015 Maps and Sets #342
Comments
I think these things could indeed be useful, but the goal of tape is generally to mirror the small API of In the meantime, something like this should work just fine: var test = require('tape');
var isEqual = require('is-equal');
test('something', function (t) {
t.ok(isEqual(a, b), 'a and b are equal');
t.end();
}); |
Unfortunately, you are correct about the current official position of the project. However, as a potential ray of hope: My view on But yeah, there's no guarantees on any of that stuff and a change in the situation may take a while. On the upside, the Node.js Core Technical Committee is scheduled to discuss this issue at this week's meeting. See nodejs/CTC#63 for info if interested. |
@Trott Thanks; good to know. It’ll be slow but interesting for the whole Node ecosystem to see what ends up happening. @ljharb In lieu of a change, it may be most efficient to put a note in the readme and whatever other documentation, saying that the intent of the tape API is to mirror node's assert, and that users should generally use other libraries such as is-equal or write their own comparator functions if they wish to compare items deeply. It would be usefully clarifying and might save the time of new users. |
@js-choi thanks, that's a great idea. PRs are appreciated, especially for docs improvements. |
At the last CTC meeting, it was agreed that the Locked API status for Based on the conversation, I believe we would now accept a PR to (for example) fix The API is still Locked, which means no new features. But adjusting the API to work with Maps, Sets, Symbols, etc. should be allowable. (There's a chance people will argue that such changes should only be released in a major version, which goes out every six months. We'll see.) Hope this helps. |
@Trott awesome - if you could link me to that PR, i'd be very interested in ensuring it behaves properly. |
@ljharb Found the PR. It's from 1.5 years ago and is closed. nodejs/node#2315 I'll update my comment above to strike out the part where I say that I think there's already a PR open for it. |
@ljharb Other open PRs on |
Once this is merged into core I will release a new major version of deep-equal based on the new algorithm that tape can be updated to support. |
assert.deepEqual and assert.deepStrictEqual currently return true for any pair of Maps and Sets regardless of content. This patch adds support in deepEqual and deepStrictEqual to verify the contents of Maps and Sets. Unfortunately because there's no way to pairwise fetch set values or map values which are equivalent but not reference-equal, this change currently only supports reference equality checking in set values and map key values. Equivalence checking could be done, but it would be an O(n^2) operation, and worse, it would get slower exponentially if maps and sets were nested. Note that this change breaks compatibility with previous versions of deepEqual and deepStrictEqual if consumers were depending on all maps and sets to be seen as equivalent. The old behaviour was never documented, but nevertheless there are certainly some tests out there which depend on it. Support has stalled because the assert API was frozen, but was recently unfrozen in CTC#63 Fixes: nodejs#2309 Refs: tape-testing/tape#342 Refs: nodejs#2315 Refs: nodejs/CTC#63
assert.deepEqual and assert.deepStrictEqual currently return true for any pair of Maps and Sets regardless of content. This patch adds support in deepEqual and deepStrictEqual to verify the contents of Maps and Sets. Deeo equivalence checking is currently an O(n^2) operation, and worse, it gets slower exponentially if maps and sets were nested. Note that this change breaks compatibility with previous versions of deepEqual and deepStrictEqual if consumers were depending on all maps and sets to be seen as equivalent. The old behaviour was never documented, but nevertheless there are certainly some tests out there which depend on it. Support has stalled because the assert API was frozen, but was recently unfrozen in CTC#63. --- Later squashed in: This change updates the checks for deep equality checking on Map and Set to check all set values / all map keys to see if any of them match the expected result. This change is much slower, but based on the conversation in the pull request its probably the right approach. Fixes: #2309 Refs: tape-testing/tape#342 Refs: #2315 Refs: nodejs/CTC#63 PR-URL: #12142 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
As listed in inspect-js/node-deep-equal#54, it looks like support was added to Node.js in v8. Is there an ETA for this change coming to tape? |
+1 to this |
Borrow solution from node-tap? tapjs/tapjs#372 |
@lfurzewaddock that doesn't match node's assert module, and is both not robust and has a bug. |
Thanks @ljharb, I can confirm |
This should be resolved in the v5.0.0-next.0 prerelease of tape, via deep-equal v2. |
As noted in inspect-js/node-deep-equal#28, Node’s
deepEqual
algorithm does not support comparing ES2015/ES6Map
s andSet
s, and, as noted in nodejs/node#2309 and nodejs/node#2315, there is no intent by Node’s staff to support them. According to @domenic and @Trott, the Node standardassert
module is intended for only testing Node itself, and assertions in user land should be addressed by user-land assertion libraries. For this same reason (mjackson/expect#47), along with circular references (mjackson/expect#50), the expect library has switched from node-deep-equal to is-equal (mjackson/expect@32e2169).Given all this, it would make sense for Tape to add another recursive comparison function – alternative to
t.deepEqual
,t.deepLooseEqual
, etc. – that would supportMap
s andSet
s. This function too might use is-equal, which also supports comparingDate
s andRegExp
s, and which might be called something liket.jsEquiv
, since it would test whether two objects represent the same JavaScript-standard-library data.Alternatively, it may be simpler and more generally useful to support
Map
s andSet
s by simply comparing their iterators’ items. Shallow and deep versions might be calledt.iterEquiv
andt.deepIterEquiv
(alternative names includet.itemsEqual
,t.iterEqual
, and so on). For instance,t.deepIterEquiv(new Map([ [ 3, 2 ], [ 5, 4 ] ]), [ [ 3, 2 ], [ 5, 4 ] ]
would test as true, because the map and the array’s iterators both yield the same entries in the same order, and their entries’ iterators also yield the same integers in the same order.In this case,
t.iterEquiv
andt.deepIterEquiv
might also allow additional optional arguments that let the user customize what predicates are used to compare items.t.iterEquiv
would take one optional predicate, for comparing items shallowly.t.deepIterEquiv
would take two optional predicates: one for comparing leaf-node items and the other for comparing branch-node items without regard to the branches’ children.These two options for comparing
Map
s andSet
s –t.jsEquiv
versust.iterEquiv
/t.deepIterEquiv
– are not mutually exclusive, of course. Both are useful, and neither should also be difficult to implement; I might be open to doing the work myself. The question here is more about whether @substack thinks either or both of them would fit with his vision for Tape.The text was updated successfully, but these errors were encountered: