From f3635f31358468b9abaaa57f1ab8b46f06a2c3dc Mon Sep 17 00:00:00 2001 From: wizardchen Date: Wed, 8 Apr 2026 16:35:02 +0800 Subject: [PATCH] test(types): add unit test for JSON unmarshalling and validation - Introduced a new test file for JSON handling to ensure that unmarshalling correctly copies input data. - Validated that the stored JSON remains intact after input mutation, and confirmed successful marshalling of the output. - This test enhances the reliability of JSON operations within the types package. --- internal/types/json.go | 4 +++- internal/types/json_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 internal/types/json_test.go diff --git a/internal/types/json.go b/internal/types/json.go index 98756520c..695728b9b 100644 --- a/internal/types/json.go +++ b/internal/types/json.go @@ -59,7 +59,9 @@ func (j *JSON) UnmarshalJSON(data []byte) error { if j == nil { return errors.New("JSON: UnmarshalJSON on nil pointer") } - *j = JSON(data) + copied := make([]byte, len(data)) + copy(copied, data) + *j = JSON(copied) return nil } diff --git a/internal/types/json_test.go b/internal/types/json_test.go new file mode 100644 index 000000000..5e4284c0f --- /dev/null +++ b/internal/types/json_test.go @@ -0,0 +1,37 @@ +package types + +import ( + "encoding/json" + "testing" +) + +func TestJSONUnmarshalCopiesInput(t *testing.T) { + type wrapper struct { + Value JSON `json:"value"` + } + + input := []byte(`{"value":{"generated_questions":[{"id":"q1","question":"今晚吃啥"}]}}`) + + var got wrapper + if err := json.Unmarshal(input, &got); err != nil { + t.Fatalf("unmarshal failed: %v", err) + } + + // Simulate decoder buffer reuse/caller mutation after UnmarshalJSON returns. + for i := range input { + input[i] = 'x' + } + + if !json.Valid(got.Value) { + t.Fatalf("stored JSON became invalid after input mutation: %q", string(got.Value)) + } + + marshaled, err := json.Marshal(got) + if err != nil { + t.Fatalf("marshal failed: %v", err) + } + + if len(marshaled) == 0 { + t.Fatal("expected marshaled output") + } +}