Repository navigation
Conversation
✅ Deploy Preview for jestjs ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
snmsoodan
force-pushed
the
fix/15073-serializable-properties
branch
from
September 23, 2026 18:48
0a4378a to
b9f2b1a
Compare
babel-jest
babel-plugin-jest-hoist
babel-preset-jest
create-jest
@jest/diff-sequences
expect
@jest/expect-utils
jest
jest-changed-files
jest-circus
jest-cli
jest-config
@jest/console
@jest/core
@jest/create-cache-key-function
jest-diff
jest-docblock
jest-each
@jest/environment
jest-environment-jsdom
@jest/environment-jsdom-abstract
jest-environment-node
@jest/expect
@jest/fake-timers
@jest/get-type
@jest/globals
jest-haste-map
jest-jasmine2
jest-leak-detector
jest-matcher-utils
jest-message-util
jest-mock
@jest/pattern
jest-phabricator
jest-regex-util
@jest/reporters
jest-resolve
jest-resolve-dependencies
jest-runner
jest-runtime
@jest/schemas
jest-snapshot
@jest/snapshot-utils
@jest/source-map
@jest/test-result
@jest/test-sequencer
@jest/transform
@jest/types
jest-util
jest-validate
jest-watcher
jest-worker
pretty-format
commit: |
`SERIALIZABLE_PROPERTIES` lets an object declare which of its properties are serializable, but it was only honoured while printing. Equality compared every own enumerable property instead, so a class could not exclude its internal fields from `toEqual`/`toStrictEqual`. `equals` now looks the symbol up with `Symbol.for`, which keeps `@jest/expect-utils` free of a dependency on `jest-matcher-utils`, and only compares the declared properties of plain objects and class instances. Arrays, typed arrays, `Map`s, `Set`s, `Date`s, `RegExp`s, `Error`s, promises and DOM nodes keep their own comparison semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7ee9c5ce-96b9-4d2b-a163-a6e5a4a4eb38
snmsoodan
force-pushed
the
fix/15073-serializable-properties
branch
from
September 23, 2026 19:03
b9f2b1a to
44c3c57
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SERIALIZABLE_PROPERTIEScurrently only reaches one half of the story:jest-matcher-utilsconsults it when printing a diff, but the equality matchers ignore it, so an object that declares which of its properties are serializable still failstoEqualon the properties it told Jest not to care about:On
mainthe diff printer filterslabelout whileeq()still walks it, so the matcher reports a difference on a property it deliberately hides from the printed diff. This aligns the two, as discussed in the issue:What the change does
eq()'skeys()helper now skips own enumerable string and symbol keys that the object declared as not serializable, mirroringgetSerializableProperties()fromjest-matcher-utils/src/deepCyclicCopyReplaceable.ts(looked up viaSymbol.for('@jest/serializableProperties'), so@jest/expect-utilskeeps no dependency onjest-matcher-utils). The declaration is inherited, so setting it on a class prototype covers every instance, exactly like the printing path.The behaviour stays opt-in: an object that declares nothing is compared exactly as before.
@Fryuni's objection
In the issue, @Fryuni argued that equality is about runtime values rather than serialized representations, with
Array(2)vs[undefined, undefined]as the counterexample. That concern is the reason for the explicit exclusion list inisBuiltInObject(): arrays, typed arrays,ArrayBuffer,Date,Error,Map,Promise,RegExp,SetandWeakMap/WeakSetnever consult the declaration, because they already have their own comparison semantics (iterableEquality, item-wise comparison,message, and so on). The sparse-array example therefore behaves exactly as it does onmain, and so do asymmetric matchers. A user has to opt in on a class of their own.One visible consequence, which follows directly from aligning with the printer and is documented in
docs/ExpectAPI.md: for an instance that declares a subset,toEqual(instance, plainObjectWithTheSameKeys)is nowtruewhiletoStrictEqualstaysfalse, since the latter still compares prototypes.Fixes #15073
Tests
packages/expect-utils/src/__tests__/jasmineUtils.test.tscovers string keys, symbol keys, nested objects/arrays/Maps, inherited declarations, empty declarations, a throwing getter and the excluded built-ins, plus no-regression cases (a class that declares nothing, an object that declaresundefined, built-ins that carry the symbol).packages/expect/src/__tests__/serializableProperties.test.tscoverstoEqual,toStrictEqual,toHaveBeenCalledWithand the asymmetric matcher path end to end.Locally (with the new tests in place and
packages/expect-utils packages/expect packages/jest-matcher-utils packages/jest-snapshot packages/jest-circus):main: 51 suites, 1519 passed, 0 failedyarn build:ts,yarn typecheck:tests,yarn eslintandyarn prettier --checkare clean.