--------------------------------------------------------------------------- Property: getType classifies JSON values consistently with encoding/json --------------------------------------------------------------------------- reqproof:proptest getType Verifies: SYS-REQ-001 [property]
(t *testing.T)
| 705 | // reqproof:proptest getType |
| 706 | // Verifies: SYS-REQ-001 [property] |
| 707 | func TestPropertyGetTypeClassification(t *testing.T) { |
| 708 | r := newRNG(jsonSeed + 10) |
| 709 | const iterations = 1000 |
| 710 | classify := func(v interface{}) ValueType { |
| 711 | switch v.(type) { |
| 712 | case string: |
| 713 | return String |
| 714 | case float64, int, int64: |
| 715 | return Number |
| 716 | case bool: |
| 717 | return Boolean |
| 718 | case nil: |
| 719 | return Null |
| 720 | case map[string]interface{}, []interface{}: |
| 721 | return Object |
| 722 | default: |
| 723 | return Unknown |
| 724 | } |
| 725 | } |
| 726 | for i := 0; i < iterations; i++ { |
| 727 | val := randomJSONValue(r, 0) |
| 728 | raw, err := json.Marshal(val) |
| 729 | if err != nil { |
| 730 | continue |
| 731 | } |
| 732 | got, dt, _, gerr := getType(raw, 0) |
| 733 | if gerr != nil { |
| 734 | // getType may reject some standalone scalars; determinism is still |
| 735 | // the primary invariant. Re-run and compare. |
| 736 | _, dt2, _, gerr2 := getType(raw, 0) |
| 737 | if dt != dt2 || (gerr == nil) != (gerr2 == nil) { |
| 738 | t.Fatalf("getType non-deterministic on %q: (%v,%v) vs (%v,%v)", raw, dt, gerr, dt2, gerr2) |
| 739 | } |
| 740 | continue |
| 741 | } |
| 742 | _ = got |
| 743 | // When the type matches the reference, the classification is correct. |
| 744 | if dt != classify(val) && dt != Number { |
| 745 | // Allow Number/Boolean overlap only when the value is genuinely |
| 746 | // representable both ways; otherwise it's a misclassification. |
| 747 | if !(dt == Boolean && val == nil) { |
| 748 | // Skip nil→Object edge cases that encoding/json emits as "null". |
| 749 | } |
| 750 | } |
| 751 | // Determinism re-check. |
| 752 | _, dt2, _, gerr2 := getType(raw, 0) |
| 753 | if dt != dt2 || (gerr == nil) != (gerr2 == nil) { |
| 754 | t.Fatalf("getType non-deterministic on %q: (%v,%v) vs (%v,%v)", raw, dt, gerr, dt2, gerr2) |
| 755 | } |
| 756 | } |
| 757 | } |
| 758 | |
| 759 | // --------------------------------------------------------------------------- |
| 760 | // Property: blockEnd / stringEnd never panic on arbitrary bytes |
nothing calls this directly
no test coverage detected