reqproof:proptest ParseFloat Verifies: SYS-REQ-013 [property]
(t *testing.T)
| 813 | // reqproof:proptest ParseFloat |
| 814 | // Verifies: SYS-REQ-013 [property] |
| 815 | func TestOracleParseFloat(t *testing.T) { |
| 816 | r := oracleNewRNG(oracleSeed + 4) |
| 817 | const iterations = 10000 |
| 818 | for i := 0; i < iterations; i++ { |
| 819 | // Generate a random float64. |
| 820 | var val float64 |
| 821 | switch r.Intn(5) { |
| 822 | case 0: |
| 823 | val = r.Float64() |
| 824 | case 1: |
| 825 | val = -r.Float64() |
| 826 | case 2: |
| 827 | val = float64(oracleLargeInts[r.Intn(len(oracleLargeInts))]) |
| 828 | case 3: |
| 829 | val = r.NormFloat64() * 1e10 |
| 830 | default: |
| 831 | val = float64(r.Intn(1000)) |
| 832 | } |
| 833 | // Format using strconv to get the canonical shortest representation. |
| 834 | tok := strconv.FormatFloat(val, 'g', -1, 64) |
| 835 | |
| 836 | ref, refErr := strconv.ParseFloat(tok, 64) |
| 837 | got, err := ParseFloat([]byte(tok)) |
| 838 | |
| 839 | if refErr != nil { |
| 840 | t.Fatalf("strconv.ParseFloat rejected its own output %q: %v", tok, refErr) |
| 841 | } |
| 842 | if err != nil { |
| 843 | t.Fatalf("ParseFloat rejected valid float %q: %v", tok, err) |
| 844 | } |
| 845 | // Exact equality — FormatFloat→ParseFloat is a lossless round-trip |
| 846 | // for float64. If the two disagree, one of them is wrong. |
| 847 | if got != ref { |
| 848 | // Allow for ultra-small ULP differences only when very close |
| 849 | // (some parsers use a different decimal→float algorithm). |
| 850 | if !closeEnoughFloat(got, ref) { |
| 851 | t.Fatalf("ParseFloat divergence on %q: jsonparser=%g, strconv=%g", tok, got, ref) |
| 852 | } |
| 853 | } |
| 854 | } |
| 855 | |
| 856 | // Adversarial inputs via testing/quick on byte slices — exercises odd |
| 857 | // grammars the parser may legitimately accept or reject. |
| 858 | rf := func(b []byte) bool { |
| 859 | s := string(b) |
| 860 | ref, refErr := strconv.ParseFloat(s, 64) |
| 861 | got, err := ParseFloat([]byte(s)) |
| 862 | if refErr != nil { |
| 863 | return true // strconv grammar may be narrower; skip |
| 864 | } |
| 865 | if err != nil { |
| 866 | return false // parser rejected a value strconv accepted |
| 867 | } |
| 868 | return got == ref || closeEnoughFloat(got, ref) |
| 869 | } |
| 870 | if err := quick.Check(rf, &quick.Config{MaxCount: 5000}); err != nil { |
| 871 | t.Fatalf("ParseFloat diverges from strconv: %v", err) |
| 872 | } |
nothing calls this directly
no test coverage detected