// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later package lowmemjson import ( "bytes" "io" "strings" "testing" "github.com/stretchr/testify/assert" ) func TestDecodeNumber(t *testing.T) { t.Parallel() r := strings.NewReader(`1{}`) var num int assert.NoError(t, NewDecoder(r).Decode(&num)) assert.Equal(t, 1, num) assert.Equal(t, 2, r.Len()) // check that it didn't read too far } func TestDecodeObject(t *testing.T) { t.Parallel() err := DecodeObject(strings.NewReader(`{"foo":9}`), func(r io.RuneScanner) error { return nil }, func(r io.RuneScanner) error { var n int return NewDecoder(r).Decode(&n) }) assert.ErrorContains(t, err, "did not consume entire") } func TestDecodeGrowing(t *testing.T) { t.Parallel() var buf bytes.Buffer dec := NewDecoder(&buf) var x any assert.ErrorIs(t, dec.Decode(&x), io.EOF) buf.WriteString("1\n") assert.NoError(t, dec.Decode(&x)) buf.WriteString("1\n") assert.NoError(t, dec.Decode(&x)) assert.ErrorIs(t, dec.Decode(&x), io.EOF) } type testAry []int func (a *testAry) DecodeJSON(r io.RuneScanner) error { return DecodeArray(r, func(r io.RuneScanner) error { var x int if err := NewDecoder(r).Decode(&x); err != nil { return err } *a = append(*a, x) return nil }) } type testObj map[string]int func (o *testObj) DecodeJSON(r io.RuneScanner) error { *o = make(testObj) var key string return DecodeObject(r, func(r io.RuneScanner) error { return NewDecoder(r).Decode(&key) }, func(r io.RuneScanner) error { var val int if err := NewDecoder(r).Decode(&val); err != nil { return err } (*o)[key] = val return nil }, ) } type testStr string func (s *testStr) DecodeJSON(r io.RuneScanner) error { var buf strings.Builder if err := DecodeString(r, &buf); err != nil { return err } *s = testStr(buf.String()) return nil } var ( _ Decodable = (*testAry)(nil) _ Decodable = (*testObj)(nil) _ Decodable = (*testStr)(nil) ) func TestDecodeTypeError(t *testing.T) { t.Parallel() type outType struct { First int Second testAry Third testObj Fourth testStr } var out outType err := NewDecoder(strings.NewReader(`{"First": 1.2, "Second": [3], "Third": {"a":4}, "Fourth": "foo\u000Abar"}`)).Decode(&out) assert.EqualError(t, err, `json: v["First"]: cannot decode JSON number 1.2 at input byte 9 into Go int: strconv.ParseInt: parsing "1.2": invalid syntax`) assert.Equal(t, outType{First: 0, Second: testAry{3}, Third: testObj{"a": 4}, Fourth: "foo\nbar"}, out) }