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

     1  package jzon
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestIterator_readObjectFieldAsSlice(t *testing.T) {
    12  	t.Run("stream reading", func(t *testing.T) {
    13  		withIterator("", func(it *Iterator) {
    14  			for step := 1; step < 8; step++ {
    15  				it.Reset(&stepByteReader{
    16  					b:    `{"a":1}`,
    17  					step: step, // consume the entire field A
    18  				})
    19  				var s struct {
    20  					A int `json:"a"`
    21  				}
    22  				err := it.ReadVal(&s)
    23  				require.NoError(t, err)
    24  				require.Equal(t, 1, s.A)
    25  			}
    26  		})
    27  	})
    28  }
    29  
    30  func TestIterator_Object_ReadObjectBegin(t *testing.T) {
    31  	t.Run("eof", func(t *testing.T) {
    32  		withIterator("", func(it *Iterator) {
    33  			_, _, err := it.ReadObjectBegin()
    34  			require.Equal(t, io.EOF, err)
    35  		})
    36  	})
    37  	t.Run("invalid first byte", func(t *testing.T) {
    38  		withIterator(`"`, func(it *Iterator) {
    39  			_, _, err := it.ReadObjectBegin()
    40  			require.IsType(t, UnexpectedByteError{}, err)
    41  		})
    42  	})
    43  	t.Run("eof after first byte", func(t *testing.T) {
    44  		withIterator("{", func(it *Iterator) {
    45  			_, _, err := it.ReadObjectBegin()
    46  			require.Equal(t, io.EOF, err)
    47  		})
    48  	})
    49  	t.Run("empty object", func(t *testing.T) {
    50  		withIterator(" { } ", func(it *Iterator) {
    51  			more, _, err := it.ReadObjectBegin()
    52  			require.NoError(t, err)
    53  			require.False(t, more)
    54  		})
    55  	})
    56  	t.Run("invalid", func(t *testing.T) {
    57  		withIterator(` { "" `, func(it *Iterator) {
    58  			_, _, err := it.ReadObjectBegin()
    59  			require.Equal(t, io.EOF, err)
    60  		})
    61  	})
    62  	t.Run("invalid colon", func(t *testing.T) {
    63  		withIterator(` { "" a `, func(it *Iterator) {
    64  			_, _, err := it.ReadObjectBegin()
    65  			require.IsType(t, UnexpectedByteError{}, err)
    66  		})
    67  	})
    68  	t.Run("valid", func(t *testing.T) {
    69  		withIterator(` { "" : `, func(it *Iterator) {
    70  			more, field, err := it.ReadObjectBegin()
    71  			require.NoError(t, err)
    72  			require.True(t, more)
    73  			require.Equal(t, "", field)
    74  		})
    75  	})
    76  	t.Run("invalid second token", func(t *testing.T) {
    77  		withIterator(` { 1 `, func(it *Iterator) {
    78  			_, _, err := it.ReadObjectBegin()
    79  			require.IsType(t, UnexpectedByteError{}, err)
    80  		})
    81  	})
    82  }
    83  
    84  func TestIterator_Object_ReadObjectMore(t *testing.T) {
    85  	f := func(t *testing.T, s string, cb func(it *Iterator)) {
    86  		s = ` { "k" : 2 ` + s
    87  		withIterator(s, func(it *Iterator) {
    88  			more, field, err := it.ReadObjectBegin()
    89  			require.NoError(t, err)
    90  			require.True(t, more)
    91  			require.Equal(t, "k", field)
    92  
    93  			i, err := it.ReadInt()
    94  			require.NoError(t, err)
    95  			require.Equal(t, 2, i)
    96  			cb(it)
    97  		})
    98  	}
    99  	t.Run("eof", func(t *testing.T) {
   100  		f(t, "", func(it *Iterator) {
   101  			_, _, err := it.ReadObjectMore()
   102  			require.Equal(t, io.EOF, err)
   103  		})
   104  	})
   105  	t.Run("valid ending", func(t *testing.T) {
   106  		f(t, "}", func(it *Iterator) {
   107  			more, _, err := it.ReadObjectMore()
   108  			require.NoError(t, err)
   109  			require.False(t, more)
   110  		})
   111  	})
   112  	t.Run("eof after comma", func(t *testing.T) {
   113  		f(t, `, `, func(it *Iterator) {
   114  			_, _, err := it.ReadObjectMore()
   115  			require.Equal(t, io.EOF, err)
   116  		})
   117  	})
   118  	t.Run("invalid byte after comma", func(t *testing.T) {
   119  		f(t, `, a`, func(it *Iterator) {
   120  			_, _, err := it.ReadObjectMore()
   121  			require.IsType(t, UnexpectedByteError{}, err)
   122  		})
   123  	})
   124  	t.Run("valid", func(t *testing.T) {
   125  		f(t, `, "k2" : `, func(it *Iterator) {
   126  			more, field, err := it.ReadObjectMore()
   127  			require.NoError(t, err)
   128  			require.True(t, more)
   129  			require.Equal(t, "k2", field)
   130  		})
   131  	})
   132  	t.Run("invalid byte", func(t *testing.T) {
   133  		f(t, ` a`, func(it *Iterator) {
   134  			_, _, err := it.ReadObjectMore()
   135  			require.IsType(t, UnexpectedByteError{}, err)
   136  		})
   137  	})
   138  	t.Run("eof after quote", func(t *testing.T) {
   139  		f(t, `, "`, func(it *Iterator) {
   140  			_, _, err := it.ReadObjectMore()
   141  			require.Equal(t, io.EOF, err)
   142  		})
   143  	})
   144  }
   145  
   146  func TestIterator_Object_ReadObject_Example(t *testing.T) {
   147  	must := require.New(t)
   148  
   149  	withIterator(` { "key" : "value" , "key2" : 1 } `,
   150  		func(it *Iterator) {
   151  			more, field, err := it.ReadObjectBegin()
   152  			must.NoError(err)
   153  			must.True(more)
   154  			must.Equal("key", field)
   155  
   156  			s, err := it.ReadString()
   157  			must.NoError(err)
   158  			must.Equal("value", s)
   159  
   160  			more, field, err = it.ReadObjectMore()
   161  			must.NoError(err)
   162  			must.True(more)
   163  			must.Equal("key2", field)
   164  
   165  			i, err := it.ReadInt()
   166  			must.NoError(err)
   167  			must.Equal(1, i)
   168  
   169  			more, _, err = it.ReadObjectMore()
   170  			must.NoError(err)
   171  			must.False(more)
   172  
   173  			_, err = it.NextValueType()
   174  			must.Equal(io.EOF, err)
   175  		})
   176  }
   177  
   178  func TestIterator_Object_ReadObjectCB(t *testing.T) {
   179  	t.Run("eof", func(t *testing.T) {
   180  		withIterator("", func(it *Iterator) {
   181  			err := it.ReadObjectCB(nil)
   182  			require.Equal(t, io.EOF, err)
   183  		})
   184  	})
   185  	t.Run("invalid first byte", func(t *testing.T) {
   186  		withIterator(" a", func(it *Iterator) {
   187  			err := it.ReadObjectCB(nil)
   188  			require.IsType(t, UnexpectedByteError{}, err)
   189  		})
   190  	})
   191  	t.Run("eof after first byte", func(t *testing.T) {
   192  		withIterator(" { ", func(it *Iterator) {
   193  			err := it.ReadObjectCB(nil)
   194  			require.Equal(t, io.EOF, err)
   195  		})
   196  	})
   197  	t.Run("empty object", func(t *testing.T) {
   198  		withIterator(" { } ", func(it *Iterator) {
   199  			err := it.ReadObjectCB(nil)
   200  			require.NoError(t, err)
   201  		})
   202  	})
   203  	t.Run("invalid field", func(t *testing.T) {
   204  		withIterator(` { a`, func(it *Iterator) {
   205  			err := it.ReadObjectCB(nil)
   206  			require.IsType(t, UnexpectedByteError{}, err)
   207  		})
   208  	})
   209  	t.Run("invalid field 2", func(t *testing.T) {
   210  		withIterator(` { " `, func(it *Iterator) {
   211  			err := it.ReadObjectCB(nil)
   212  			require.Equal(t, io.EOF, err)
   213  		})
   214  	})
   215  	t.Run("error during callback", func(t *testing.T) {
   216  		withIterator(` { " " : `, func(it *Iterator) {
   217  			e := errors.New("test")
   218  			err := it.ReadObjectCB(func(it *Iterator, field string) error {
   219  				return e
   220  			})
   221  			require.Equal(t, e, err)
   222  		})
   223  	})
   224  	t.Run("eof after first item", func(t *testing.T) {
   225  		withIterator(` { " " : 1`, func(it *Iterator) {
   226  			err := it.ReadObjectCB(func(it *Iterator, field string) error {
   227  				i, err := it.ReadInt()
   228  				require.NoError(t, err)
   229  				require.Equal(t, 1, i)
   230  				return nil
   231  			})
   232  			require.Equal(t, io.EOF, err)
   233  		})
   234  	})
   235  	t.Run("end after first item", func(t *testing.T) {
   236  		withIterator(` { " " : 1 } `, func(it *Iterator) {
   237  			err := it.ReadObjectCB(func(it *Iterator, field string) error {
   238  				i, err := it.ReadInt()
   239  				require.NoError(t, err)
   240  				require.Equal(t, 1, i)
   241  				return nil
   242  			})
   243  			require.NoError(t, err)
   244  
   245  			_, err = it.NextValueType()
   246  			require.Equal(t, io.EOF, err)
   247  		})
   248  	})
   249  	t.Run("eof after comma", func(t *testing.T) {
   250  		withIterator(` { " " : 1 , `, func(it *Iterator) {
   251  			err := it.ReadObjectCB(func(it *Iterator, field string) error {
   252  				i, err := it.ReadInt()
   253  				require.NoError(t, err)
   254  				require.Equal(t, 1, i)
   255  				return nil
   256  			})
   257  			require.Equal(t, io.EOF, err)
   258  		})
   259  	})
   260  	t.Run("invalid byte after comma", func(t *testing.T) {
   261  		withIterator(` { " " : 1 , a `, func(it *Iterator) {
   262  			err := it.ReadObjectCB(func(it *Iterator, field string) error {
   263  				i, err := it.ReadInt()
   264  				require.NoError(t, err)
   265  				require.Equal(t, 1, i)
   266  				return nil
   267  			})
   268  			require.IsType(t, UnexpectedByteError{}, err)
   269  		})
   270  	})
   271  	t.Run("eof after second field", func(t *testing.T) {
   272  		withIterator(` { " " : 1 , " `, func(it *Iterator) {
   273  			err := it.ReadObjectCB(func(it *Iterator, field string) error {
   274  				i, err := it.ReadInt()
   275  				require.NoError(t, err)
   276  				require.Equal(t, 1, i)
   277  				return nil
   278  			})
   279  			require.Equal(t, io.EOF, err)
   280  		})
   281  	})
   282  	t.Run("invalid comma", func(t *testing.T) {
   283  		withIterator(` { " " : 1 a " `, func(it *Iterator) {
   284  			err := it.ReadObjectCB(func(it *Iterator, field string) error {
   285  				i, err := it.ReadInt()
   286  				require.NoError(t, err)
   287  				require.Equal(t, 1, i)
   288  				return nil
   289  			})
   290  			require.IsType(t, UnexpectedByteError{}, err)
   291  		})
   292  	})
   293  }
   294  
   295  func TestIterator_Object_ReadObjectCB_Example(t *testing.T) {
   296  	must := require.New(t)
   297  
   298  	withIterator(` { "key" : "value" , "key2" : "value2" } `,
   299  		func(it *Iterator) {
   300  			m := map[string]string{}
   301  
   302  			err := it.ReadObjectCB(func(it *Iterator, field string) (err error) {
   303  				value, err := it.ReadString()
   304  				if err == nil {
   305  					m[field] = value
   306  				}
   307  				return
   308  			})
   309  			must.NoError(err)
   310  			must.Len(m, 2)
   311  			must.Equal("value", m["key"])
   312  			must.Equal("value2", m["key2"])
   313  
   314  			_, err = it.NextValueType()
   315  			must.Equal(io.EOF, err)
   316  		})
   317  }
   318  
   319  func TestIterator_Object_skipObjectField(t *testing.T) {
   320  	must := require.New(t)
   321  
   322  	withIterator(` key" : `, func(it *Iterator) {
   323  		err := it.skipObjectField()
   324  		must.NoError(err)
   325  	})
   326  	withIterator(` key `, func(it *Iterator) {
   327  		err := it.skipObjectField()
   328  		must.Equal(io.EOF, err)
   329  	})
   330  	withIterator(` key" { `, func(it *Iterator) {
   331  		err := it.skipObjectField()
   332  		must.IsType(UnexpectedByteError{}, err)
   333  	})
   334  }