git.lukeshu.com/go/lowmemjson@v0.3.9-0.20230723050957-72f6d13f6fb2/decode_test.go (about)

     1  // Copyright (C) 2022-2023  Luke Shumaker <lukeshu@lukeshu.com>
     2  //
     3  // SPDX-License-Identifier: GPL-2.0-or-later
     4  
     5  package lowmemjson
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestDecodeNumber(t *testing.T) {
    17  	t.Parallel()
    18  	r := strings.NewReader(`1{}`)
    19  
    20  	var num int
    21  	assert.NoError(t, NewDecoder(r).Decode(&num))
    22  	assert.Equal(t, 1, num)
    23  	assert.Equal(t, 2, r.Len()) // check that it didn't read too far
    24  }
    25  
    26  func TestDecodeObject(t *testing.T) {
    27  	t.Parallel()
    28  	err := DecodeObject(strings.NewReader(`{"foo":9}`),
    29  		func(r io.RuneScanner) error {
    30  			return nil
    31  		},
    32  		func(r io.RuneScanner) error {
    33  			var n int
    34  			return NewDecoder(r).Decode(&n)
    35  		})
    36  	assert.ErrorContains(t, err, "did not consume entire")
    37  }
    38  
    39  func TestDecodeGrowing(t *testing.T) {
    40  	t.Parallel()
    41  	var buf bytes.Buffer
    42  	dec := NewDecoder(&buf)
    43  	var x any
    44  	assert.ErrorIs(t, dec.Decode(&x), io.EOF)
    45  	buf.WriteString("1\n")
    46  	assert.NoError(t, dec.Decode(&x))
    47  	buf.WriteString("1\n")
    48  	assert.NoError(t, dec.Decode(&x))
    49  	assert.ErrorIs(t, dec.Decode(&x), io.EOF)
    50  }
    51  
    52  type testAry []int
    53  
    54  func (a *testAry) DecodeJSON(r io.RuneScanner) error {
    55  	return DecodeArray(r, func(r io.RuneScanner) error {
    56  		var x int
    57  		if err := NewDecoder(r).Decode(&x); err != nil {
    58  			return err
    59  		}
    60  		*a = append(*a, x)
    61  		return nil
    62  	})
    63  }
    64  
    65  type testObj map[string]int
    66  
    67  func (o *testObj) DecodeJSON(r io.RuneScanner) error {
    68  	*o = make(testObj)
    69  	var key string
    70  	return DecodeObject(r,
    71  		func(r io.RuneScanner) error {
    72  			return NewDecoder(r).Decode(&key)
    73  		},
    74  		func(r io.RuneScanner) error {
    75  			var val int
    76  			if err := NewDecoder(r).Decode(&val); err != nil {
    77  				return err
    78  			}
    79  			(*o)[key] = val
    80  			return nil
    81  		},
    82  	)
    83  }
    84  
    85  type testStr string
    86  
    87  func (s *testStr) DecodeJSON(r io.RuneScanner) error {
    88  	var buf strings.Builder
    89  	if err := DecodeString(r, &buf); err != nil {
    90  		return err
    91  	}
    92  	*s = testStr(buf.String())
    93  	return nil
    94  }
    95  
    96  var (
    97  	_ Decodable = (*testAry)(nil)
    98  	_ Decodable = (*testObj)(nil)
    99  	_ Decodable = (*testStr)(nil)
   100  )
   101  
   102  func TestDecodeTypeError(t *testing.T) {
   103  	t.Parallel()
   104  	type outType struct {
   105  		First  int
   106  		Second testAry
   107  		Third  testObj
   108  		Fourth testStr
   109  	}
   110  	var out outType
   111  	err := NewDecoder(strings.NewReader(`{"First": 1.2, "Second": [3], "Third": {"a":4}, "Fourth": "foo\u000Abar"}`)).Decode(&out)
   112  	assert.EqualError(t, err,
   113  		`json: v["First"]: cannot decode JSON number 1.2 at input byte 9 into Go int: strconv.ParseInt: parsing "1.2": invalid syntax`)
   114  	assert.Equal(t, outType{First: 0, Second: testAry{3}, Third: testObj{"a": 4}, Fourth: "foo\nbar"}, out)
   115  }