zeroshade commented on PR #1646:
URL: https://github.com/apache/iceberg-go/pull/1646#issuecomment-5219502081

   Follow-up on the one non-blocking point from my re-review, now with a 
verified snippet — approval above still stands, this is the only thing I'd like 
changed before merge.
   
   `TestMetadataUnmarshalDoesNotMutateInputAndRoundTripsAfterReuse` passes with 
the production fix in `UnmarshalJSON` reverted, so it currently protects 
nothing. The cause is the final assertion:
   
   ```go
   assert.JSONEq(t, string(encoded), string(reencoded))
   ```
   
   That compares `encoded` against a decode-then-re-encode of itself, which 
tests encoder idempotence rather than whether the reused decode preserved every 
field from `replacementData`.
   
   I initially wanted to suggest simply comparing `replacementData` against 
`encoded`, but I verified that and it does **not** work, for two reasons worth 
recording so this isn't re-attempted:
   
   1. A literal substitution doesn't compile — `reencoded` becomes unused 
(`declared and not used: reencoded`), so the round-trip block has to go with it.
   2. Even after removing it, the compare fails at `f258696` on exactly one 
key: `NestedField.Doc` is `json:"doc,omitempty"`, so the fixture's `"doc": ""` 
is omitted on encode. `version-log` was **not** a problem here — the fixture 
has it present, so `init()`'s nil-to-empty normalization never triggers.
   3. And once `doc` is normalized away, the compare passes *both* at the head 
and with the fix reverted — still vacuous. Fixing the tautology alone isn't 
enough to give the test teeth.
   
   What makes it non-vacuous is dropping `properties` from the replacement 
document: the fixed decoder clears the omitted state, the old one retains stale 
`{"prop":"value"}`. That's the assertion doing real work.
   
   Verified minimal form:
   
   ```go
   var replacement map[string]any
   require.NoError(t, json.Unmarshal([]byte(exampleViewJSON), &replacement))
   replacement["current-version-id"] = int64(2)
   replacement["versions"].([]any)[0].(map[string]any)["version-id"] = int64(2)
   replacement["versions"].([]any)[0].(map[string]any)["schema-id"] = 2
   replacement["schemas"].([]any)[0].(map[string]any)["schema-id"] = 2
   
delete(replacement["schemas"].([]any)[0].(map[string]any)["fields"].([]any)[0].(map[string]any),
 "doc")
   delete(replacement, "properties")
   replacementData, err := json.Marshal(replacement)
   require.NoError(t, err)
   require.NoError(t, json.Unmarshal(replacementData, &md))
   
   encoded, err := json.Marshal(&md)
   require.NoError(t, err)
   assert.JSONEq(t, string(replacementData), string(encoded))
   ```
   
   The trailing `roundTripped` / `reencoded` block is then deleted. Keep the 
existing input-mutation assertion at the top as-is.
   
   Confirmed empirically:
   
   - At `f258696`, targeted test: **passes**.
   - With pre-PR `UnmarshalJSON` restored: **fails**, and on the right thing — 
the only diff is a surviving `"properties": {"prop": "value"}` in the actual 
output.
   - `go test ./view/ -count=1` with the snippet in place: **green**.
   
   Two notes on the `delete` for `doc`: it's papering over an encode/decode 
asymmetry rather than testing anything, so if you'd rather avoid it, giving 
that fixture field a non-empty `doc` would remove the need for the line. Either 
is fine by me.
   
   Not worth blocking a correct production fix over — if you'd prefer to land 
this as-is and tighten the test in a follow-up, I'm happy with that too. The 
`.([]any)` / `.(map[string]any)` assertions stay unchecked either way, which 
remains ordinary test brittleness.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to