jest
jest copied to clipboard
[Bug]: Arrays with extra properties aren't handled well
Version
28.1.2 - 29.3.1
Steps to reproduce
git clone https://github.com/benblank/jest-arrays-with-extra-properties.gitcd jest-arrays-with-extra-propertiesnpm installnpm test- Observe that all four tests failed.
Expected behavior
Arrays' extra properties should be considered when comparing them and displayed in failure messages when relevant.
Actual behavior
Arrays' extra properties are only compared by some matchers (e.g. toEqual does, but toMatchInlineSnapshot does not) and even those which correctly compare them don't display the differences in failure messages (instead just reporting that the received value "serializes to the same string").
Additional context
The current behavior is unhelpful both because it is inconsistent (e.g. between toEqual and toMatchInlineSnapshot) and because it doesn't give insight into the nature of the failures.
I haven't yet dug too deeply into this behavior, but it appears to be due to arrays' extra properties not being included during serialization (both prior to comparison in failure messages and for snapshots).
(Note: The failure messages in the example can be a bit difficult to decipher, as they are displaying comparisons of failure messages (so you get a failure message embedded in a failure message). There are explanatory comments in each test which hopefully describe the behaviors more clearly.)
Environment
System:
OS: Linux 5.10 Ubuntu 20.04.4 LTS (Focal Fossa)
CPU: (16) x64 Intel(R) Core(TM) i7-10700K CPU @ 3.80GHz
Binaries:
Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
npm: 8.13.2 - ~/.nvm/versions/node/v16.15.1/bin/npm
npmPackages:
jest: ^28.1.2 => 28.1.2
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
This issue persists in v28.1.3 (unsurprisingly) as well as v29.0.0-alpha.5 (though the inline snapshot also needs a minor tweak). The repro linked in the original post has been updated to use v29.0.0-alpha.5.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
The issue persists in v29.0.3. The repro linked in the original post has been updated.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
The issue persists in v29.1.2. The repro linked in the original post has been updated.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
The issue persists in v29.3.1. The repro linked in the original post has been updated.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
There has not been a release in the last 30 days; the repro is still up to date.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
Still no new release, so the repro is still up to date.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
The issue persists in v29.4.3. The repro linked in the original post has been updated.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
The issue persists in v29.5.0. The repro linked in the original post has been updated.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
There has not been a release in the last 30 days; the repro is still up to date.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
There has not been a release in the last 30 days; the repro is still up to date.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
There has not been a release in the last 30 days; the repro is still up to date.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
assert.equal() and assert.strictEqual() are failing with "Compared values have no visual difference" instead of "serializes to the same string".
JSON.stringify() does not show extra props just like toMatchInlineSnapshot().
I can only see the extra property being pick up by console.log(). It prints: [ 1, 2, 3, foo: 'bar' ].
Is this print out clear? Hm.. Looks unusual, but perhaps that’s the best way.
Other question: what to do with extra props on Map or Set?
For a Map with an extra prop, console prints {"foo":"bar"} omitting all the entries; structuredClone() omits extra props; same with console.log([...mapWithFooBar]).
I think the best solution is to avoid adding extra properties on iterable objects. It should be possible to make Jest respect them, but it does not mean that extra props will not cause problems elsewhere. I look just at few API and that already shows how unpredictable the behaviour can become.
Ultimately, I think inconsistency is the real enemy, here; I'll update the issue description to that effect.
Unexpected properties are perfectly "reasonable" in a monkey-patchable language like JS, but they're probably still a pretty universally bad practice, due to potential confusion when reading the code. The best solution for Jest may simply be to issue a warning when encountering them, but otherwise completely ignore them for comparison purposes. (Which would both resolve the inconsistency and alert the user to the fact that they're doing something Jest doesn't support.)
You make a good point with regards to Map and Set; there are other classes which should probably be considered, too (Date comes to mind). Basically, a known set of classes for which unexpected own, enumerable properties aren't considered when comparing, because they're fairly uncommon and would complicate an otherwise clean representation.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
The issue persists in v29.6.4. The repro linked in the original post has been updated.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
This issue was closed because it has been stalled for 30 days with no activity. Please open a new issue if the issue is still relevant, linking to this one.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.