============================================================================= Gate C: Unmarshal → Marshal → Unmarshal round-trip equivalence ============================================================================= runRoundTripGate asserts that a value unmarshaled from valid JSON, when re-marsha
(t *testing.T, data []byte)
| 227 | // Map key ordering in the marshaled output can differ from the input, so we |
| 228 | // compare VALUES (reflect.DeepEqual) rather than bytes. |
| 229 | func runRoundTripGate(t *testing.T, data []byte) { |
| 230 | t.Helper() |
| 231 | if !json.Valid(data) { |
| 232 | return |
| 233 | } |
| 234 | |
| 235 | // --- Variant 1: default interface{} (float64 numbers) --- |
| 236 | func() { |
| 237 | var v1 interface{} |
| 238 | if err := json.Unmarshal(data, &v1); err != nil { |
| 239 | // Valid JSON that fails to unmarshal into interface{} is the |
| 240 | // documented float64-range limitation (e.g. 1e999 → +Inf), |
| 241 | // classified by Gate B as a non-bug. Variant 2 (UseNumber) |
| 242 | // below still runs to cover the full-precision round-trip. |
| 243 | return |
| 244 | } |
| 245 | bytes2, err := json.Marshal(v1) |
| 246 | if err != nil { |
| 247 | t.Errorf("Gate C: Marshal failed for value from valid JSON: err=%v data=%s", |
| 248 | err, truncateForMsg(data)) |
| 249 | return |
| 250 | } |
| 251 | var v2 interface{} |
| 252 | if err := json.Unmarshal(bytes2, &v2); err != nil { |
| 253 | t.Errorf("Gate C: second Unmarshal failed for Marshal output: err=%v data=%s out=%s", |
| 254 | err, truncateForMsg(data), truncateForMsg(bytes2)) |
| 255 | return |
| 256 | } |
| 257 | if !reflect.DeepEqual(v1, v2) { |
| 258 | t.Errorf("Gate C: round-trip DeepEqual mismatch (ROUND-TRIP violation):\n"+ |
| 259 | " v1=%#v\n v2=%#v\n data=%s", |
| 260 | v1, v2, truncateForMsg(data)) |
| 261 | } |
| 262 | }() |
| 263 | |
| 264 | // --- Variant 2: json.Number (UseNumber) — full precision --- |
| 265 | func() { |
| 266 | dec1 := json.NewDecoder(bytes.NewReader(data)) |
| 267 | dec1.UseNumber() |
| 268 | var n1 interface{} |
| 269 | if err := dec1.Decode(&n1); err != nil { |
| 270 | return |
| 271 | } |
| 272 | bytes3, err := json.Marshal(n1) |
| 273 | if err != nil { |
| 274 | t.Errorf("Gate C: Marshal failed for UseNumber value: err=%v data=%s", |
| 275 | err, truncateForMsg(data)) |
| 276 | return |
| 277 | } |
| 278 | dec2 := json.NewDecoder(bytes.NewReader(bytes3)) |
| 279 | dec2.UseNumber() |
| 280 | var n2 interface{} |
| 281 | if err := dec2.Decode(&n2); err != nil { |
| 282 | t.Errorf("Gate C: second UseNumber decode failed: err=%v data=%s out=%s", |
| 283 | err, truncateForMsg(data), truncateForMsg(bytes3)) |
| 284 | return |
| 285 | } |
| 286 | if !reflect.DeepEqual(n1, n2) { |
no test coverage detected