test: tighten fusion-era assertions + PathSummary fusion correctness suite#964
Merged
JohannesLichtenberger merged 1 commit intomainfrom Apr 30, 2026
Merged
Conversation
…ess suite
Several tests were relaxed during the iter#28-32 fusion rollout to accept
either the legacy OBJECT_KEY shape or the post-fusion OBJECT_NAMED_*
shape. With fusion default ON the legacy branch is unreachable, which
makes those OR/role-predicate assertions silently weaker than they look.
Tighten assertions to the exact fused kind dictated by each test's JSON
shape:
- JsonNodeTrxCopyTest: 4 assertion sites switched from
`assertTrue(kind.playsObjectKeyRole())` to `assertEquals(kind, OBJECT_NAMED_*)`
per primitive value type. Drop the unreachable legacy `if/else`
descent branches.
- FlyweightCursorTest: same tightening at 5 assertion sites; descendant-
count assertion changed from `count >= 3` (which accepted both 3-fused
and 5-legacy) to `assertEquals(3, count)`.
- LdjsonShredderTest: 2 sites tightened to OBJECT_NAMED_STRING + value
assertion.
Also add PathSummaryFusionTest pinning the path-summary contract under
fusion:
1. Fused OBJECT_NAMED_{STRING,NUMBER,BOOLEAN,NULL} primitive leaves
register under canonical OBJECT_NAMED_OBJECT pathKind, refcount=1
per field.
2. Duplicate field names across sibling objects increment references to
the shared path entry (refs=2 for two siblings, both fused).
3. Removing one of two fused-field instances decrements references to 1.
4. Removing the last fused field collapses the path-summary entry
entirely (no orphaned refs=0 entry).
5. Phase-2 structural fusion of OBJECT_NAMED_ARRAY mirrors at both the
field-name level (OBJECT_NAMED_OBJECT pathKind) and the underlying
array level (ARRAY pathKind).
6. setObjectKeyName migrates references from old → new path entry; old
entry is removed.
All 6 PathSummary scenarios + 52 tightened-class tests pass.
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
During the iter#28→32 fusion rollout (PRs landing the
OBJECT_NAMED_*family) several existing tests were relaxed to accept either the legacyOBJECT_KEYshape or the post-fusionOBJECT_NAMED_*shape. Now that fusion is default ON, the legacy branch is unreachable — those OR/role-predicate assertions are silently weaker than they look. Per the project rule "do not relax tests," tighten them back to the exact fused kind dictated by each test's JSON shape.Also add a new
PathSummaryFusionTestbecause the user asked specifically: make sure that with fused nodes, the PathSummary is still valid.Tightenings (3 files)
JsonNodeTrxCopyTest.java4 assertion sites switched from
assertTrue(kind.playsObjectKeyRole(), …)(accepts any of the 6 fused kinds) toassertEquals(NodeKind.OBJECT_NAMED_<TYPE>, kind)per JSON value type. Removed the unreachable legacyif/elsedescent branches whose else-arm walks an extraOBJECT_STRING_VALUE/etc. child that fusion no longer emits.FlyweightCursorTest.javaOBJECT_NAMED_STRINGfor string-valued fields,OBJECT_NAMED_NUMBERfor numeric).assertTrue(count >= 3, …)(accepts both the 3-fused and 5-legacy answer); nowassertEquals(3, count, …).LdjsonShredderTest.java2 sites at
testTreeStructuretightened toOBJECT_NAMED_STRINGand now also assert the inline value (\"v\"/\"v2\") — a legitimate strengthening since the fused leaf carries the value directly.New:
PathSummaryFusionTest(6 tests, all passing)Pins down the contracts in
PathSummaryWriter:fusedPrimitiveLeaves_registerCanonicalOBJECT_NAMED_OBJECT_pathKind—{s,n,b,z}of all four primitive flavours each produces one level-1 entry under the canonicalOBJECT_NAMED_OBJECTpathKind withreferences=1.duplicateFieldName_acrossSiblingObjects_increments_references—[{name:\"a\"},{name:\"b\"}]collapses into one path entry withreferences=2.removingFusedField_decrements_pathSummaryReferences— removing one of two fusedOBJECT_NAMED_NUMBERrecords drops refs from 2 → 1.removingLastFusedField_collapses_pathSummaryEntry— removing the sole instance of a field eliminates the entry entirely (no orphan refs=0 entry).fusedStructural_OBJECT_NAMED_ARRAY_registers_pathSummaryEntries_onBothLevels— Phase 2 structural fusion of{items:[1,2,3]}mirrors at both the field-name level (OBJECT_NAMED_OBJECTpathKind foritems) AND the underlying array level (ARRAYpathKind for elements).renamingFusedField_migrates_pathSummaryReferences—setObjectKeyName(\"oldName\" → \"newName\")migrates the reference; old entry gone, new entry refs=1, registered under the canonical pathKind.Test plan
./gradlew :sirix-core:test --tests \"io.sirix.access.node.json.JsonNodeTrxCopyTest\"— 14 tests, 0 failures../gradlew :sirix-core:test --tests \"io.sirix.access.trx.node.FlyweightCursorTest\"— 15 tests, 0 failures../gradlew :sirix-core:test --tests \"io.sirix.service.json.shredder.LdjsonShredderTest\"— 23 tests, 0 failures../gradlew :sirix-core:test --tests \"io.sirix.access.node.json.PathSummaryFusionTest\"— 6 tests, 0 failures.Notes
HOTSplitIntegrationTest,HOTVersioningIntegrationTest,JsonStructuralFuzzTest,HOTHeightOptimalTest,HOTIndexManyRevisionsTest, etc.) useplaysObjectKeyRole()as dispatch (if (kind.playsObjectKeyRole()) { … }), not as an assertion. Those are legitimate flow-control predicates, not relaxations — left alone.ProductionReadinessTestusesplaysObjectKeyRole()inside walker dispatch and one comment says "accept either kind via NodeKind#playsObjectKeyRole()." That comment is stale (fusion default ON), but the predicate is still a dispatch usage, not a weakened assertion. Left alone.