avajs/ava

Alternative assertion for unordered deep comparisons

開放

#3,020 建立於 2022年5月8日

 (11 則留言) (0 個反應) (0 位負責人)JavaScript (1,408 個分叉)batch import
enhancementhelp wantedscope:assertions

倉庫指標

星標
 (20,600 顆星)
PR 合併指標
 (PR 指標待抓取)

描述

deepEqual take insertation order in account for Sets and Maps but not for Objects. Therefore t.deepEqual(new Set([1,2]), new Set([2,1]) will fail while t.deepEqual({a:1, b:2}, {b:2, a:1}) succeed. Container classes should obey the same rules, same assertations should work the same for all containers.

I understand object iteration order is undefined (arbitrary) according to MDN, while Sets and Maps are OrderedSets and OrderedMaps in javascript. Probably this is the basis of the current implementation, but please be aware that order of Object.getOwnPropertyNames, Object.getOwnPropertySymbols and Reflect.ownKeys return values are defined in ES6 therefore elements of objects are pretty much ordered.

The current assertation rules are unfortunately inconsistent for containers, and there is no (easy) way to test (unordered) Sets and Maps.

Sets are usually used as mathematical sets, where ordering shouldn't matter. Also Maps are used as generic containers, trees, caches where failing on order difference is more like a bug than a feature. To be honest there are very few, rare edge-cases where one would like to test for Map/Set ordering (eliminating duplicates from arrays is the only one came into my mind). If one would need ordering, insertion order is almost certainly won't suffice and some more advanced structure like red-black tree or alike will be implemented instead anyway).

Ideal solution would be if ES would have both Sets and OrderedSets, but unfortunately this is not the case. Changing deepEqual implementation certainly would break some existing test cases, which is very unfortunate. Therefore probably the only viable way is to add a new assertation rule for unordered cases and document the fact Object are not considered ordered collections.

貢獻者指南