jest: [Bug]: `structuredClone` fails on `toStrictEqual`
Version
29.4.0
Steps to reproduce
- Clone my repository at https://github.com/JamieMagee/jest-structuredclone-strictequal/blob/master/index.spec.js
npm install
npm test
Expected behavior
I expect to see objects cloned with structuredClone
to pass toStrictEqual
Actual behavior
The values do not pass toStrictEqual
(but do pass toEqual
).
jest › toStrictEqual › structured clone
expect(received).toStrictEqual(expected) // deep equality
Expected: {"value": "test"}
Received: serializes to the same string
6 | describe('toStrictEqual', () => {
7 | it('structured clone', () => {
> 8 | expect(structuredClone(value)).toStrictEqual(value);
| ^
9 | });
10 | it('JSON clone', () => {
11 | expect(JSON.parse(JSON.stringify(value))).toStrictEqual(value);
at Object.toStrictEqual (index.spec.js:8:44)
However JSON.parse(JSON.stringify())
does pass toStrictEqual
Additional context
The test output can be seen in this GitHub Actions run.
Environment
System:
OS: Linux 6.2 NixOS 23.05 (Stoat) 23.05 (Stoat)
CPU: (32) x64 AMD Ryzen 9 7950X 16-Core Processor
Binaries:
Node: 19.7.0 - /run/current-system/sw/bin/node
Yarn: 1.22.19 - /run/current-system/sw/bin/yarn
npm: 9.5.0 - /run/current-system/sw/bin/npm
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 7
- Comments: 44 (24 by maintainers)
This is still relevant.
I don’t think that’s correct. My reading is that it won’t recursively deep clone the prototype chain, which makes sense.
This can be seen by trying out these two lines in your browser or Node.js repl:
I think that this is Jest specific, because trying the same within the Jest runner results in another behaviour:
My guess is that this has something to do with worker threads/sandboxing/custom global environment, where maybe the global
Array
isn’t the same as theArray
constructor thatstructuredClone
uses. But I’m not familiar enough with the inner workings of Jest to say for sure…Not stale
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.
I suppose this is still a great feature to have.
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 is still open IMO.
pls no stale
@mrazauskas sorry for asking, but I am a bit confused as to the conclusion of this now. Is the suggestion for everyone to switch to jest-light-runner. Considering that Node assert also handles this.
@Grub4K Thanks. Good catch!
Seems like this is simply #2549. Using
jest-light-runner
solves the problem. Reference: https://github.com/jestjs/jest/issues/2549#issuecomment-1098071474With
jest-light-runner
I got:Would be interesting to try this out wider.
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.
Hi there ! I just stumbled upon the same issue, and I agree that, given
structuredClone
is now part of the standard library and more and more codebases, there should be an appropriate test for it.One particular sample that should pass IMO is the following:
This currently fails with
This is key to me because using the
JSON.parse(JSON.stringify(...))
technique does not accommodate nested dates objects (they are serialised to strings), wherestructuredClone
does. I don’t really get what Jest sees to differentiate the original and the clone in the date exemple above, aren’t the prototypes the same?Yeah, I agree it is subjective.
Would a new
toBeClone()
add too many similar APIs?Okay, it looks like this might be a limitation of
structuredClone
and we should usetoEqual
instead. From MDN (emphasis mine):Might be this is the explanation: