Skip to content

fix: compare JSON values structurally in equality keywords - #132

Open
fitchmultz wants to merge 2 commits into
sagold:mainfrom
fitchmultz:fix/structural-enum-equality
Open

fitchmultz wants to merge 2 commits into
sagold:mainfrom
fitchmultz:fix/structural-enum-equality

Conversation

@fitchmultz

@fitchmultz fitchmultz commented Sep 21, 2026 •

Copy link
Copy Markdown

Summary

Use one small internal comparison utility for enum, const, and uniqueItems. It compares JSON arrays in order and JSON objects by their own members regardless of insertion order, treating names such as toString, valueOf, and constructor as data. The existing comparator remains responsible for non-JSON host values such as dates, regular expressions, and custom class instances. No dependency or public API changes.

enum currently compares serialized objects, so { a: 1, b: 2 } fails an enum containing { b: 2, a: 1 }. Directly reusing the existing comparator would introduce failures for ordinary JSON member names. The same comparator already makes const throw for {"toString":"label"} and {"valueOf":1}, and makes uniqueItems miss duplicate nested objects with an object-valued constructor member. The tests reproduce those defects before the change.

This follows the JSON instance equality contract in Core §4.2.2, used by enum and const and uniqueItems.

Verification

Final head fcdaf20b7060898948538715ddd584cac9b49817, based directly on current upstream main 65578c185fc324ebf8fcc8f6e654e85cbfab4da8. Rechecked September 21 with Node 24.21.0 and pnpm 10.34.5 using the frozen lockfile.

  • Focused native keyword tests: 13 passing / 9 failing before; 22 passing after. Final controls also exercise equal null-prototype maps and reject extra own members. Covers reordered and nested objects, changed values, missing/extra members, array order/length, primitive types, literal member names, unchanged inputs, and existing error data/pointers.
  • test:unit: 1,037 passing, 3 pending.
  • test:spec: 7,513 passing, 9 pending, with existing exclusions unchanged.
  • Native ESM, CommonJS, declaration, and browser IIFE builds complete; attw reports no problems. The same 22 focused controls pass against each built runtime entrypoint.
  • 22 additional before/after host-value controls for const and uniqueItems remain passing, including dates, regular expressions, boxed numbers, custom value objects, undefined-valued members, and NaN.
  • The preceding equality commit's source ESLint and TypeScript comparisons retained byte-identical baseline diagnostics: 3 ESLint errors, 4 source TypeScript errors, and 107 test TypeScript errors. That comparison predates the final null-prototype adjustment; no lint diagnostics were suppressed. Final-head unit/spec suites and ESM/CommonJS/declaration/IIFE builds were rerun, along with all 22 keyword controls and 22 host-value controls against each built runtime entrypoint.

Upstream CI for the final head requires maintainer approval (action_required). Local results above are not an upstream CI-success claim.

This is a focused equality correction, not a claim of complete JSON Schema conformance. Generated distributions are validated locally and excluded from this source-only change.

Treat null-prototype objects as plain member maps so literal names stay data instead of falling through to host-object comparison.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant