FuzzSequence runs multi-operation sequences against a single JSON document. Verifies: SYS-REQ-035 (no-panic on sequences of operations). reqproof:proptest parser.Set, parser.Delete, parser.Get
(f *testing.F)
| 533 | // Verifies: SYS-REQ-035 (no-panic on sequences of operations). |
| 534 | // reqproof:proptest parser.Set, parser.Delete, parser.Get |
| 535 | func FuzzSequence(f *testing.F) { |
| 536 | // Seed with valid JSON + valid-shape paths so the sequences have a |
| 537 | // well-defined starting state. |
| 538 | f.Add([]byte(`{"a":1,"b":2}`), []byte("a")) |
| 539 | f.Add([]byte(`{"a":1,"b":2}`), []byte("b")) |
| 540 | f.Add([]byte(`{"x":{"y":1}}`), []byte("x/y")) |
| 541 | f.Add([]byte(`[1,2,3]`), []byte("[0]")) |
| 542 | f.Add([]byte(`{"a":[1,2,3]}`), []byte("a/[1]")) |
| 543 | f.Add([]byte(`{}`), []byte("newkey")) |
| 544 | f.Add([]byte(`{"a":1}`), []byte("a")) |
| 545 | |
| 546 | f.Fuzz(func(t *testing.T, data []byte, pathBytes []byte) { |
| 547 | // Only sequence-test VALID JSON — invalid input has no defined |
| 548 | // post-condition invariant. |
| 549 | if !json.Valid(data) { |
| 550 | return |
| 551 | } |
| 552 | path := splitPathComponents(pathBytes) |
| 553 | // Restrict to paths whose shape matches the data (the documented-open |
| 554 | // D6/D9/D10 divergences are out of scope for sequence invariants). |
| 555 | if !pathShapeMatchesData(data, path) { |
| 556 | return |
| 557 | } |
| 558 | // Refuse the empty-key hazard (SYS-REQ-111 class). |
| 559 | for _, c := range path { |
| 560 | if c == "" { |
| 561 | return |
| 562 | } |
| 563 | } |
| 564 | |
| 565 | r := newRandFromSeed(data, pathBytes) |
| 566 | setVal := []byte(`42`) |
| 567 | setVal2 := []byte(`99`) |
| 568 | |
| 569 | // Pick one of the five sequence shapes at random. |
| 570 | switch r.Intn(5) { |
| 571 | case 0: |
| 572 | // S1: Set → Get round-trip (deeper than single-op gate). |
| 573 | // |
| 574 | // NOTE: Set at an out-of-range array index appends to the array |
| 575 | // (SYS-REQ-110). Get at the same index then returns not-found |
| 576 | // because the array doesn't have that many elements. This is |
| 577 | // documented behavior; a Get error here is tolerated (matching |
| 578 | // the existing round-trip gate in json_fuzz_test.go). |
| 579 | out, ok := applySequenceStep(t, data, "set", path, setVal) |
| 580 | if !ok { |
| 581 | return |
| 582 | } |
| 583 | assertAfterStep(t, "S1.Set", out, path, func(t *testing.T, state []byte) { |
| 584 | got, _, _, gErr := Get(state, path...) |
| 585 | if gErr != nil { |
| 586 | return // tolerated: OOB index after append-style Set. |
| 587 | } |
| 588 | // Allow numeric-equivalent representations. |
| 589 | if bytes.Equal(got, setVal) { |
| 590 | return |
| 591 | } |
| 592 | if gf, e1 := strconvParseFloat(got); e1 == nil { |
nothing calls this directly
no test coverage detected