github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/decoder_test.go (about)

     1  package jzon
     2  
     3  import (
     4  	"encoding/json"
     5  	"io"
     6  	"io/ioutil"
     7  	"strings"
     8  	"testing"
     9  	"testing/iotest"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  type decFace interface {
    15  	UseNumber()
    16  
    17  	DisallowUnknownFields()
    18  
    19  	Decode(interface{}) error
    20  
    21  	Buffered() io.Reader
    22  
    23  	// This is incompatible
    24  	// Token() (json.Token, error)
    25  
    26  	More() bool
    27  }
    28  
    29  type inputOffset interface {
    30  	// Not available for go<1.13
    31  	InputOffset() int64
    32  }
    33  
    34  var _ decFace = &json.Decoder{}
    35  var _ decFace = &Decoder{}
    36  
    37  func TestDecoder(t *testing.T) {
    38  	t.Run("consecutive", func(t *testing.T) {
    39  		t.Run("success", func(t *testing.T) {
    40  			must := require.New(t)
    41  
    42  			newReader := func() io.Reader {
    43  				s := ` {} {} `
    44  				return iotest.OneByteReader(strings.NewReader(s))
    45  			}
    46  
    47  			check := func(dec decFace, length int, expMore bool, leftOffset, rightOffset int64) {
    48  				buffered := dec.Buffered()
    49  				if buffered == nil {
    50  					return
    51  				}
    52  				b, err := ioutil.ReadAll(buffered)
    53  				must.NoError(err)
    54  				if length > 0 {
    55  					t.Logf("%T: %q", dec, b)
    56  				}
    57  				must.True(length >= len(b))
    58  
    59  				ofI, ofIok := dec.(inputOffset)
    60  				if ofIok {
    61  					offset := ofI.InputOffset()
    62  					// t.Logf("%T %d", dec, offset)
    63  					must.True(leftOffset <= offset, "%T %d > %d", dec, leftOffset, offset)
    64  					must.True(rightOffset >= offset, "%T %d < %d", dec, rightOffset, offset)
    65  				}
    66  
    67  				more := dec.More()
    68  				must.Equal(expMore, more, "%T", dec)
    69  
    70  				if ofIok {
    71  					offset := ofI.InputOffset()
    72  					// t.Logf("%T %d", dec, offset)
    73  					must.True(leftOffset <= offset, "%T %d > %d", dec, leftOffset, offset)
    74  					must.True(rightOffset >= offset, "%T %d < %d", dec, rightOffset, offset)
    75  				}
    76  			}
    77  
    78  			f := func(dec decFace) {
    79  				var i, i2, i3 interface{}
    80  
    81  				check(dec, 0, true, 0, 1)
    82  
    83  				err := dec.Decode(&i)
    84  				must.NoError(err, "%T", dec)
    85  				check(dec, 0, true, 3, 4)
    86  
    87  				err2 := dec.Decode(&i2)
    88  				must.NoError(err2, "%T", dec)
    89  				check(dec, 0, false, 6, 7)
    90  
    91  				err3 := dec.Decode(&i3)
    92  				must.Equal(io.EOF, err3, "%T", dec)
    93  				check(dec, 1, false, 6, 7)
    94  			}
    95  			f(json.NewDecoder(newReader()))
    96  			dec := NewDecoder(newReader())
    97  			defer dec.Release()
    98  			f(dec)
    99  		})
   100  		t.Run("failure at start", func(t *testing.T) {
   101  			must := require.New(t)
   102  
   103  			newReader := func() io.Reader {
   104  				s := ` } {} `
   105  				return iotest.OneByteReader(strings.NewReader(s))
   106  			}
   107  			f := func(dec decFace) {
   108  				var i, i2 interface{}
   109  
   110  				err := dec.Decode(&i)
   111  				t.Logf("%T %v", dec, err)
   112  				must.Error(err)
   113  
   114  				err2 := dec.Decode(&i2)
   115  				t.Logf("%T %v", dec, err2)
   116  				must.Equal(err2, err)
   117  			}
   118  			f(json.NewDecoder(newReader()))
   119  			dec := NewDecoder(newReader())
   120  			defer dec.Release()
   121  			f(dec)
   122  		})
   123  		t.Run("failure at middle", func(t *testing.T) {
   124  			must := require.New(t)
   125  
   126  			newReader := func() io.Reader {
   127  				s := ` {} } `
   128  				return iotest.OneByteReader(strings.NewReader(s))
   129  			}
   130  			f := func(dec decFace) {
   131  				var i, i2 interface{}
   132  
   133  				err := dec.Decode(&i)
   134  				must.NoError(err)
   135  
   136  				err2 := dec.Decode(&i2)
   137  				t.Logf("%T %v", dec, err2)
   138  				must.Error(err2)
   139  			}
   140  			f(json.NewDecoder(newReader()))
   141  			dec := NewDecoder(newReader())
   142  			defer dec.Release()
   143  			f(dec)
   144  		})
   145  	})
   146  }
   147  
   148  func TestDecoder_UseNumber(t *testing.T) {
   149  	must := require.New(t)
   150  	s := "123.456"
   151  	newReader := func() io.Reader {
   152  		return strings.NewReader(s)
   153  	}
   154  	f := func(dec decFace) {
   155  		dec.UseNumber()
   156  		var i interface{}
   157  		err := dec.Decode(&i)
   158  		must.NoError(err)
   159  		must.Equal(json.Number(s), i)
   160  	}
   161  	f(json.NewDecoder(newReader()))
   162  	dec := NewDecoder(newReader())
   163  	defer dec.Release()
   164  	f(dec)
   165  }
   166  
   167  func TestDecoder_DisallowUnknownFields(t *testing.T) {
   168  	must := require.New(t)
   169  	s := `{"k":"v"}`
   170  	newReader := func() io.Reader {
   171  		return strings.NewReader(s)
   172  	}
   173  	f := func(dec decFace) {
   174  		dec.DisallowUnknownFields()
   175  		var i struct{}
   176  		err := dec.Decode(&i)
   177  		t.Log(err)
   178  		must.Error(err)
   179  	}
   180  	f(json.NewDecoder(newReader()))
   181  	dec := NewDecoder(newReader())
   182  	defer dec.Release()
   183  	f(dec)
   184  }