diff --git a/jsn.go b/jsn.go index cc42122..b7f3fa1 100644 --- a/jsn.go +++ b/jsn.go @@ -23,12 +23,14 @@ func (n N) MarshalJSON() ([]byte, error) { return []byte(n), nil } -// Unmarshal ... +// Unmarshal only 1 JSON entity from the input. +// Disallows unknown fields if the argument is a struct. func Unmarshal(b []byte, v any) error { return UnmarshalFrom(bytes.NewReader(b), v) } -// UnmarshalFrom ... +// UnmarshalFrom only 1 JSON entity from the input. +// Disallows unknown fields if the argument is a struct. func UnmarshalFrom(r io.Reader, v any) error { d := json.NewDecoder(r) d.DisallowUnknownFields() diff --git a/jsn_test.go b/jsn_test.go new file mode 100644 index 0000000..fef6bb9 --- /dev/null +++ b/jsn_test.go @@ -0,0 +1,61 @@ +package jsn + +import ( + "reflect" + "testing" +) + +func TestUnmarshal(t *testing.T) { + testCases := []struct { + input string + want any + errStr string + }{ + { + input: `"abc"`, + want: "abc", + }, + { + input: `123`, + want: float64(123), + }, + { + input: `{"abc": 123}`, + want: map[string]any{"abc": float64(123)}, + }, + { + input: `{"abc": 123} `, + want: map[string]any{"abc": float64(123)}, + }, + { + input: ` ["abc", 123] `, + want: []any{"abc", float64(123)}, + }, + { + input: `{"abc": 123}a`, + errStr: "body must contain only one JSON object", + }, + { + input: `{"abc`, + errStr: "unexpected EOF", + }, + } + + for _, tc := range testCases { + var val any + err := Unmarshal([]byte(tc.input), &val) + if err != nil { + if tc.errStr == "" { + t.Fatal(err) + } + if have := err.Error(); have != tc.errStr { + t.Fatalf("\nhave: %+v\nwant: %+v\n", have, tc.errStr) + } + continue + } + + if !reflect.DeepEqual(val, tc.want) { + t.Fatalf("\nhave: %+v\nwant: %+v\n", val, tc.want) + } + } +}