--------------------------------------------------------------------------- Property 4: ParseInt / ParseFloat / ParseBoolean agree with strconv. --------------------------------------------------------------------------- genIntToken generates random decimal integer strings (including boundary values
(t *testing.T)
| 761 | // reqproof:proptest ParseInt |
| 762 | // Verifies: SYS-REQ-015 [property] |
| 763 | func TestOracleParseInt(t *testing.T) { |
| 764 | r := oracleNewRNG(oracleSeed + 3) |
| 765 | const iterations = 10000 |
| 766 | for i := 0; i < iterations; i++ { |
| 767 | // Generate a random int64 (with bias toward boundary values). |
| 768 | var val int64 |
| 769 | switch r.Intn(4) { |
| 770 | case 0: |
| 771 | val = oracleLargeInts[r.Intn(len(oracleLargeInts))] |
| 772 | case 1: |
| 773 | val = r.Int63() |
| 774 | case 2: |
| 775 | val = -r.Int63() |
| 776 | default: |
| 777 | val = int64(r.Intn(200)) - 100 |
| 778 | } |
| 779 | // Format as decimal, optionally with a leading sign. |
| 780 | tok := strconv.FormatInt(val, 10) |
| 781 | |
| 782 | ref, refErr := strconv.ParseInt(tok, 10, 64) |
| 783 | got, err := ParseInt([]byte(tok)) |
| 784 | |
| 785 | // The token was produced by strconv.FormatInt, so strconv MUST accept. |
| 786 | if refErr != nil { |
| 787 | t.Fatalf("strconv.ParseInt rejected its own output %q: %v", tok, refErr) |
| 788 | } |
| 789 | if err != nil { |
| 790 | t.Fatalf("ParseInt rejected valid int %q: %v", tok, err) |
| 791 | } |
| 792 | if got != ref { |
| 793 | t.Fatalf("ParseInt divergence on %q: jsonparser=%d, strconv=%d", tok, got, ref) |
| 794 | } |
| 795 | } |
| 796 | |
| 797 | // Adversarial inputs: assert agreement on the common-acceptance domain. |
| 798 | // When both accept, values MUST match (this is the property that catches |
| 799 | // silent arithmetic bugs). When one rejects, the other may also reject — |
| 800 | // divergence of acceptance is allowed (D1 in file header: jsonparser |
| 801 | // follows strict JSON grammar, strconv accepts Go-idiomatic extensions). |
| 802 | adversarial := []string{ |
| 803 | "", " ", " 123 ", "+42", "-0", "00", "0x10", "1e5", |
| 804 | "123abc", "99999999999999999999999999", "-99999999999999999999999999", |
| 805 | "12.34", "1_000", "0b11", "0o17", "\t\n", " -1 ", |
| 806 | "9223372036854775808", // max int64 + 1 (overflow) |
| 807 | "-9223372036854775809", // min int64 - 1 (underflow) |
| 808 | } |
| 809 | for _, tok := range adversarial { |
| 810 | ref, refErr := strconv.ParseInt(tok, 10, 64) |
| 811 | got, err := ParseInt([]byte(tok)) |
| 812 | // If both accept, values must match. |
| 813 | if refErr == nil && err == nil && got != ref { |
| 814 | t.Fatalf("ParseInt divergence on adversarial %q: jsonparser=%d, strconv=%d", tok, got, ref) |
| 815 | } |
| 816 | } |
| 817 | } |
| 818 | |
| 819 | // reqproof:proptest ParseFloat |
| 820 | // Verifies: SYS-REQ-013 [property] |
nothing calls this directly
no test coverage detected