Skip to content

Normalize JSON in one module - #1

Draft
myabc wants to merge 2 commits into
mainfrom
feature/deepen-matcher-chain
Draft

myabc wants to merge 2 commits into
mainfrom
feature/deepen-matcher-chain

Conversation

@myabc

@myabc myabc commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

🤖 Normalization was spread over Helpers, Exclusion and BeJsonEql, and the key sort that makes equivalence work was hidden inside Exclusion#exclude_keys. As a result "normalized JSON" meant two different things: normalize_json kept source key order while be_json_eql compared sorted keys, and include_json compared Ruby values rather than normalized JSON.

What changes

  • New internal JsonSpec::Normalization.normalize(ruby, excluded_keys: []) owns dropping excluded keys, sorting keys and generating text.
  • normalize_json, generate_normalized_json, be_json_eql and include_json all go through it, so they agree on what "equivalent" means.
  • JsonSpec::Exclusion shrinks to the per-matcher set of excluded keys.
  • Adds CONTEXT.md, a short domain glossary defining "normalized JSON" and "excluded keys".

Behaviour changes

All are listed in CHANGELOG.md under 2.0.0 unless noted.

  • normalize_json and generate_normalized_json now sort object keys. They still exclude nothing.
  • include_json compares normalized JSON element by element, like be_json_eql. An integer no longer matches an equal float ([10.0] does not include 10), and a non-string expected value against a JSON string fails instead of raising TypeError.
  • JsonSpec::Exclusion.exclude_keys and exclude_key? are removed, and the module no longer extends itself. It was never documented.
  • Not in the changelog: normalization generates with allow_nan: true, because JSON.parse reads numbers too large for a float (1e400) as Infinity. Without it include_json would raise on any document containing such a number. This also means be_json_eql and normalize_json no longer raise JSON::GeneratorError on such input, and normalize_json("1e400") returns Infinity, which is not valid JSON. Open question for review: keep this, or narrow it to include_json only.

Testing

  • bundle exec rake passes locally on Ruby 4.0.2: 129 examples, 53 scenarios.
  • New spec/json_spec/normalization_spec.rb tests the module at its interface. New specs cover key sorting in the helpers, the include_json equality changes, overflowing numbers, and requiring only json_spec/helpers.
  • A Codex adversarial review found two regressions (direct require "json_spec/helpers" raising NameError, and the overflowing-number crash); both are fixed with regression specs. The review was not re-run after the fixes.

myabc added 2 commits October 2, 2026 20:54
Defines normalized JSON and excluded keys so the code and future
design discussions share one meaning for each term.
Normalization was spread over Helpers, Exclusion and BeJsonEql, and
the key sort that makes equivalence work hid inside
Exclusion#exclude_keys. As a result normalize_json kept source key
order while be_json_eql compared sorted keys, and include_json
compared Ruby values instead of normalized JSON.

JsonSpec::Normalization now owns dropping excluded keys, sorting
keys and generating text. The normalize helpers and both matchers
go through it, so they agree on what equivalent means. Exclusion
shrinks to the per-matcher key set.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant