--------------------------------------------------------------------------- Property: token-boundary helpers are deterministic and never panic --------------------------------------------------------------------------- reqproof:proptest findTokenStart, nextToken, lastToken, tokenStart, tokenEnd Ver
(t *testing.T)
| 636 | // reqproof:proptest findTokenStart, nextToken, lastToken, tokenStart, tokenEnd |
| 637 | // Verifies: SYS-REQ-035 [property] |
| 638 | func TestPropertyTokenHelpersNoCrash(t *testing.T) { |
| 639 | r := newRNG(jsonSeed + 9) |
| 640 | const iterations = 3000 |
| 641 | cases := make([][]byte, 0, iterations) |
| 642 | for i := 0; i < iterations; i++ { |
| 643 | cases = append(cases, randomBytes(r, 64)) |
| 644 | } |
| 645 | // Add curated edge cases. |
| 646 | cases = append(cases, |
| 647 | nil, []byte{}, []byte(" "), []byte(" \t\n "), |
| 648 | []byte("a"), []byte("\""), []byte("{}"), []byte("[]"), |
| 649 | bytes.Repeat([]byte{0x80}, 128), |
| 650 | bytes.Repeat([]byte(" "), 256), |
| 651 | ) |
| 652 | for i, raw := range cases { |
| 653 | // findTokenStart over all byte values. |
| 654 | for tok := 0; tok < 256; tok++ { |
| 655 | if !recoverNoPanic(func() { _ = findTokenStart(raw, byte(tok)) }) { |
| 656 | t.Fatalf("findTokenStart panicked on case %d tok=%d input=%q", i, tok, raw) |
| 657 | } |
| 658 | } |
| 659 | // nextToken / lastToken / tokenStart / tokenEnd: determinism. |
| 660 | nA := nextToken(raw) |
| 661 | nB := nextToken(raw) |
| 662 | if nA != nB { |
| 663 | t.Fatalf("nextToken non-deterministic on %q: %d vs %d", raw, nA, nB) |
| 664 | } |
| 665 | lA := lastToken(raw) |
| 666 | lB := lastToken(raw) |
| 667 | if lA != lB { |
| 668 | t.Fatalf("lastToken non-deterministic on %q: %d vs %d", raw, lA, lB) |
| 669 | } |
| 670 | if !recoverNoPanic(func() { _ = tokenStart(raw) }) { |
| 671 | t.Fatalf("tokenStart panicked on %q", raw) |
| 672 | } |
| 673 | tsA := tokenStart(raw) |
| 674 | tsB := tokenStart(raw) |
| 675 | if tsA != tsB { |
| 676 | t.Fatalf("tokenStart non-deterministic on %q: %d vs %d", raw, tsA, tsB) |
| 677 | } |
| 678 | teA := tokenEnd(raw) |
| 679 | teB := tokenEnd(raw) |
| 680 | if teA != teB { |
| 681 | t.Fatalf("tokenEnd non-deterministic on %q: %d vs %d", raw, teA, teB) |
| 682 | } |
| 683 | // Bounds: when the helper returns a valid index it must be in [0,len]. |
| 684 | // (tokenEnd/lastToken may legitimately return len(data) to signal |
| 685 | // "scanned past the end"; allow that as a sentinel value.) |
| 686 | if nA != -1 && (nA < 0 || nA > len(raw)) { |
| 687 | t.Fatalf("nextToken out-of-range %d on %q (len=%d)", nA, raw, len(raw)) |
| 688 | } |
| 689 | if lA != -1 && (lA < 0 || lA > len(raw)) { |
| 690 | t.Fatalf("lastToken out-of-range %d on %q (len=%d)", lA, raw, len(raw)) |
| 691 | } |
| 692 | if tsA != -1 && (tsA < 0 || tsA > len(raw)) { |
| 693 | t.Fatalf("tokenStart out-of-range %d on %q (len=%d)", tsA, raw, len(raw)) |
| 694 | } |
| 695 | if teA != -1 && (teA < 0 || teA > len(raw)) { |
nothing calls this directly
no test coverage detected