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 }