Skip to content

Compare JSON numbers without rounding away differences - #1969

Open
x0Lazarus wants to merge 1 commit into
stretchr:masterfrom
x0Lazarus:fix/compare-json-numbers-exactly
Open

x0Lazarus wants to merge 1 commit into
stretchr:masterfrom
x0Lazarus:fix/compare-json-numbers-exactly

Conversation

@x0Lazarus

Copy link
Copy Markdown

Summary

Make JSONEq reject different numbers that round to the same float64 value.

Changes

When the existing comparison would pass, compare the original JSON numbers before accepting the result. Normalize decimal and exponent spellings so values such as 1, 1.0, and 1e0 still compare equal. This also distinguishes very small nonzero numbers from zero.

The existing input validation and diagnostics remain in place. Identical input strings keep their fast path; other apparently equal inputs need an additional decode to avoid losing numeric information.

Tests cover large integers, decimal rounding, underflow, nested values, equivalent number spellings, and invalid inputs. On Windows, the full suite passes with Go 1.17.13. The assert, require, and mock tests, plus go vet ./... and go build ./..., pass with Go 1.17.13 and 1.27.1. With Go 1.27.1, the full suite still hits the existing TestFailfastSuiteFailFastOn failure because its subprocess needs the unavailable race/CGO support; the same failure occurs at the base revision.

Motivation

JSONEq currently accepts {"id":9007199254740992} and {"id":9007199254740993} as equal. Both numbers become the same float64 during decoding, so a test can pass even when an ID has changed. The comparison now keeps enough information to catch that difference without treating equivalent numeric spellings as different values.

Related issues

Related to the numeric-value comparison discussed in #360; equivalent spellings remain equal.

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