Repository navigation
[patch] Break natural-order ties ordinally so distinct strings never compare equal - #65
Conversation
…compare equal
NaturalStringComparer.Compare returned 0 when every chunk matched, so
strings that differ only in leading zeros or digit script ("file5" and
"file005", "v1" and "v01", "file٥" and "file5") compared equal. Sorted
collections then dropped one of them or threw on Add, and Array.Sort's
result depended on the input order.
The natural order stays the primary key; when it ties, the strings are
now ordered by string.CompareOrdinal, so Compare returns 0 only for
ordinally equal strings. The tests that asserted 0 for such pairs now
assert a nonzero, antisymmetric result.
Fixes #59
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013JBDCsjuRez5zdzBcBJ7Y7
|
CI is blocked by runner availability, not by this change. In run 37363660356, RoundTripStringJsonConverter#113 and #114 show the same 15-minute queue cancellation at the same time, so it looks like an org-wide Actions capacity or limit issue. Locally the full suite passes (25/25) on this branch. Nothing in the diff can change this. Once runners are available, CI needs to be re-run. Generated by Claude Code |
|



Fixes #59
What changed
NaturalStringComparer.Comparereturned0whenever every chunk matched. Strings that differ only in leading zeros or digit script therefore compared equal:file5/file005,v1/v01,file٥/file5. That broke theIComparer<T>contract in three ways:SortedSetsilently dropped entriesSortedDictionary.Addthrew on distinct keysArray.Sortoutput depended on input orderThe natural order is still the primary key. When it ties,
Comparenow falls back tostring.CompareOrdinal(x, y), so it returns 0 only for ordinally equal strings. Numerically equal strings stay next to each other:file5,file05andfile005all still sort afterfile4and beforefile6. The fallback allocates nothing, soCompare_AllocatesNothingstill holds. The<returns>doc now describes the tie-break.Tests
Six existing tests asserted
0for numerically equal but distinct strings. They now use anAssertTiedOnlyByOrdinalhelper, which asserts a nonzero result whose sign matchesCompareOrdinaland flips when the arguments are swapped.Compare_NonAsciiDigits_EqualValuesAreEqualis renamed..._EqualValuesAreTiedOrdinally.New tests, matching the issue's acceptance criteria:
Compare_NumericallyEqualStrings_AreNotEqual: over a set of values,Compare == 0exactly when the strings are ordinally equalCompare_NumericallyEqualStrings_StayBetweenTheirNeighbours: the tie-break only reorders strings within a tieSortedSet_KeepsStringsThatDifferOnlyInLeadingZeros:Count == 3SortedDictionary_AcceptsKeysThatDifferOnlyInLeadingZerosSort_IsTheSameForEveryInputOrder: every permutation of{a, b5, b05}gives the same outputWith the library change reverted, 9 tests fail: the updated ones and the new ones, except the neighbours guard. With the change, all 25 pass, and the library builds for all its target frameworks.
🤖 Generated with Claude Code
https://claude.ai/code/session_013JBDCsjuRez5zdzBcBJ7Y7
Generated by Claude Code