github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/json/buffer_test.gno (about) 1 package json 2 3 import ( 4 "testing" 5 ) 6 7 func TestBufferCurrent(t *testing.T) { 8 tests := []struct { 9 name string 10 buffer *buffer 11 expected byte 12 wantErr bool 13 }{ 14 { 15 name: "Valid current byte", 16 buffer: &buffer{ 17 data: []byte("test"), 18 length: 4, 19 index: 1, 20 }, 21 expected: 'e', 22 wantErr: false, 23 }, 24 { 25 name: "EOF", 26 buffer: &buffer{ 27 data: []byte("test"), 28 length: 4, 29 index: 4, 30 }, 31 expected: 0, 32 wantErr: true, 33 }, 34 } 35 36 for _, tt := range tests { 37 t.Run(tt.name, func(t *testing.T) { 38 got, err := tt.buffer.current() 39 if (err != nil) != tt.wantErr { 40 t.Errorf("buffer.current() error = %v, wantErr %v", err, tt.wantErr) 41 return 42 } 43 if got != tt.expected { 44 t.Errorf("buffer.current() = %v, want %v", got, tt.expected) 45 } 46 }) 47 } 48 } 49 50 func TestBufferStep(t *testing.T) { 51 tests := []struct { 52 name string 53 buffer *buffer 54 wantErr bool 55 }{ 56 { 57 name: "Valid step", 58 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 59 wantErr: false, 60 }, 61 { 62 name: "EOF error", 63 buffer: &buffer{data: []byte("test"), length: 4, index: 3}, 64 wantErr: true, 65 }, 66 } 67 68 for _, tt := range tests { 69 t.Run(tt.name, func(t *testing.T) { 70 err := tt.buffer.step() 71 if (err != nil) != tt.wantErr { 72 t.Errorf("buffer.step() error = %v, wantErr %v", err, tt.wantErr) 73 } 74 }) 75 } 76 } 77 78 func TestBufferNext(t *testing.T) { 79 tests := []struct { 80 name string 81 buffer *buffer 82 want byte 83 wantErr bool 84 }{ 85 { 86 name: "Valid next byte", 87 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 88 want: 'e', 89 wantErr: false, 90 }, 91 { 92 name: "EOF error", 93 buffer: &buffer{data: []byte("test"), length: 4, index: 3}, 94 want: 0, 95 wantErr: true, 96 }, 97 } 98 99 for _, tt := range tests { 100 t.Run(tt.name, func(t *testing.T) { 101 got, err := tt.buffer.next() 102 if (err != nil) != tt.wantErr { 103 t.Errorf("buffer.next() error = %v, wantErr %v", err, tt.wantErr) 104 return 105 } 106 if got != tt.want { 107 t.Errorf("buffer.next() = %v, want %v", got, tt.want) 108 } 109 }) 110 } 111 } 112 113 func TestBufferSlice(t *testing.T) { 114 tests := []struct { 115 name string 116 buffer *buffer 117 pos int 118 want []byte 119 wantErr bool 120 }{ 121 { 122 name: "Valid slice -- 0 characters", 123 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 124 pos: 0, 125 want: nil, 126 wantErr: false, 127 }, 128 { 129 name: "Valid slice -- 1 character", 130 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 131 pos: 1, 132 want: []byte("t"), 133 wantErr: false, 134 }, 135 { 136 name: "Valid slice -- 2 characters", 137 buffer: &buffer{data: []byte("test"), length: 4, index: 1}, 138 pos: 2, 139 want: []byte("es"), 140 wantErr: false, 141 }, 142 { 143 name: "Valid slice -- 3 characters", 144 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 145 pos: 3, 146 want: []byte("tes"), 147 wantErr: false, 148 }, 149 { 150 name: "Valid slice -- 4 characters", 151 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 152 pos: 4, 153 want: []byte("test"), 154 wantErr: false, 155 }, 156 { 157 name: "EOF error", 158 buffer: &buffer{data: []byte("test"), length: 4, index: 3}, 159 pos: 2, 160 want: nil, 161 wantErr: true, 162 }, 163 } 164 165 for _, tt := range tests { 166 t.Run(tt.name, func(t *testing.T) { 167 got, err := tt.buffer.slice(tt.pos) 168 if (err != nil) != tt.wantErr { 169 t.Errorf("buffer.slice() error = %v, wantErr %v", err, tt.wantErr) 170 return 171 } 172 if string(got) != string(tt.want) { 173 t.Errorf("buffer.slice() = %v, want %v", got, tt.want) 174 } 175 }) 176 } 177 } 178 179 func TestBufferMove(t *testing.T) { 180 tests := []struct { 181 name string 182 buffer *buffer 183 pos int 184 wantErr bool 185 wantIdx int 186 }{ 187 { 188 name: "Valid move", 189 buffer: &buffer{data: []byte("test"), length: 4, index: 1}, 190 pos: 2, 191 wantErr: false, 192 wantIdx: 3, 193 }, 194 { 195 name: "Move beyond length", 196 buffer: &buffer{data: []byte("test"), length: 4, index: 1}, 197 pos: 4, 198 wantErr: true, 199 wantIdx: 1, 200 }, 201 } 202 203 for _, tt := range tests { 204 t.Run(tt.name, func(t *testing.T) { 205 err := tt.buffer.move(tt.pos) 206 if (err != nil) != tt.wantErr { 207 t.Errorf("buffer.move() error = %v, wantErr %v", err, tt.wantErr) 208 } 209 if tt.buffer.index != tt.wantIdx { 210 t.Errorf("buffer.move() index = %v, want %v", tt.buffer.index, tt.wantIdx) 211 } 212 }) 213 } 214 } 215 216 func TestBufferSkip(t *testing.T) { 217 tests := []struct { 218 name string 219 buffer *buffer 220 b byte 221 wantErr bool 222 }{ 223 { 224 name: "Skip byte", 225 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 226 b: 'e', 227 wantErr: false, 228 }, 229 { 230 name: "Skip to EOF", 231 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 232 b: 'x', 233 wantErr: true, 234 }, 235 } 236 237 for _, tt := range tests { 238 t.Run(tt.name, func(t *testing.T) { 239 err := tt.buffer.skip(tt.b) 240 if (err != nil) != tt.wantErr { 241 t.Errorf("buffer.skip() error = %v, wantErr %v", err, tt.wantErr) 242 } 243 }) 244 } 245 } 246 247 func TestBufferSkipAny(t *testing.T) { 248 tests := []struct { 249 name string 250 buffer *buffer 251 s map[byte]bool 252 wantErr bool 253 }{ 254 { 255 name: "Skip any valid byte", 256 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 257 s: map[byte]bool{'e': true, 'o': true}, 258 wantErr: false, 259 }, 260 { 261 name: "Skip any to EOF", 262 buffer: &buffer{data: []byte("test"), length: 4, index: 0}, 263 s: map[byte]bool{'x': true, 'y': true}, 264 wantErr: true, 265 }, 266 } 267 268 for _, tt := range tests { 269 t.Run(tt.name, func(t *testing.T) { 270 err := tt.buffer.skipAny(tt.s) 271 if (err != nil) != tt.wantErr { 272 t.Errorf("buffer.skipAny() error = %v, wantErr %v", err, tt.wantErr) 273 } 274 }) 275 } 276 } 277 278 func TestSkipToNextSignificantToken(t *testing.T) { 279 tests := []struct { 280 name string 281 input []byte 282 expected int 283 }{ 284 {"No significant chars", []byte("abc"), 3}, 285 {"One significant char at start", []byte(".abc"), 0}, 286 {"Significant char in middle", []byte("ab.c"), 2}, 287 {"Multiple significant chars", []byte("a$.c"), 1}, 288 {"Significant char at end", []byte("abc$"), 3}, 289 {"Only significant chars", []byte("$."), 0}, 290 {"Empty string", []byte(""), 0}, 291 } 292 293 for _, tt := range tests { 294 t.Run(tt.name, func(t *testing.T) { 295 b := newBuffer(tt.input) 296 b.skipToNextSignificantToken() 297 if b.index != tt.expected { 298 t.Errorf("after skipToNextSignificantToken(), got index = %v, want %v", b.index, tt.expected) 299 } 300 }) 301 } 302 } 303 304 func mockBuffer(s string) *buffer { 305 return newBuffer([]byte(s)) 306 } 307 308 func TestSkipAndReturnIndex(t *testing.T) { 309 tests := []struct { 310 name string 311 input string 312 expected int 313 }{ 314 {"StartOfString", "", 0}, 315 {"MiddleOfString", "abcdef", 1}, 316 {"EndOfString", "abc", 1}, 317 } 318 319 for _, tt := range tests { 320 t.Run(tt.name, func(t *testing.T) { 321 buf := mockBuffer(tt.input) 322 got, err := buf.skipAndReturnIndex() 323 if err != nil && tt.input != "" { // Expect no error unless input is empty 324 t.Errorf("skipAndReturnIndex() error = %v", err) 325 } 326 if got != tt.expected { 327 t.Errorf("skipAndReturnIndex() = %v, want %v", got, tt.expected) 328 } 329 }) 330 } 331 } 332 333 func TestSkipUntil(t *testing.T) { 334 tests := []struct { 335 name string 336 input string 337 tokens map[byte]bool 338 expected int 339 }{ 340 {"SkipToToken", "abcdefg", map[byte]bool{'c': true}, 2}, 341 {"SkipToEnd", "abcdefg", map[byte]bool{'h': true}, 7}, 342 {"SkipNone", "abcdefg", map[byte]bool{'a': true}, 0}, 343 } 344 345 for _, tt := range tests { 346 t.Run(tt.name, func(t *testing.T) { 347 buf := mockBuffer(tt.input) 348 got, err := buf.skipUntil(tt.tokens) 349 if err != nil && got != len(tt.input) { // Expect error only if reached end without finding token 350 t.Errorf("skipUntil() error = %v", err) 351 } 352 if got != tt.expected { 353 t.Errorf("skipUntil() = %v, want %v", got, tt.expected) 354 } 355 }) 356 } 357 } 358 359 func TestSliceFromIndices(t *testing.T) { 360 tests := []struct { 361 name string 362 input string 363 start int 364 end int 365 expected string 366 }{ 367 {"FullString", "abcdefg", 0, 7, "abcdefg"}, 368 {"Substring", "abcdefg", 2, 5, "cde"}, 369 {"OutOfBounds", "abcdefg", 5, 10, "fg"}, 370 } 371 372 for _, tt := range tests { 373 t.Run(tt.name, func(t *testing.T) { 374 buf := mockBuffer(tt.input) 375 got := buf.sliceFromIndices(tt.start, tt.end) 376 if string(got) != tt.expected { 377 t.Errorf("sliceFromIndices() = %v, want %v", string(got), tt.expected) 378 } 379 }) 380 } 381 } 382 383 func TestBufferToken(t *testing.T) { 384 tests := []struct { 385 name string 386 path string 387 index int 388 isErr bool 389 }{ 390 { 391 name: "Simple valid path", 392 path: "@.length", 393 index: 8, 394 isErr: false, 395 }, 396 { 397 name: "Path with array expr", 398 path: "@['foo'].0.bar", 399 index: 14, 400 isErr: false, 401 }, 402 { 403 name: "Path with array expr and simple fomula", 404 path: "@['foo'].[(@.length - 1)].*", 405 index: 27, 406 isErr: false, 407 }, 408 { 409 name: "Path with filter expr", 410 path: "@['foo'].[?(@.bar == 1 & @.baz < @.length)].*", 411 index: 45, 412 isErr: false, 413 }, 414 { 415 name: "addition of foo and bar", 416 path: "@.foo+@.bar", 417 index: 11, 418 isErr: false, 419 }, 420 { 421 name: "logical AND of foo and bar", 422 path: "@.foo && @.bar", 423 index: 14, 424 isErr: false, 425 }, 426 { 427 name: "logical OR of foo and bar", 428 path: "@.foo || @.bar", 429 index: 14, 430 isErr: false, 431 }, 432 { 433 name: "accessing third element of foo", 434 path: "@.foo,3", 435 index: 7, 436 isErr: false, 437 }, 438 { 439 name: "accessing last element of array", 440 path: "@.length-1", 441 index: 10, 442 isErr: false, 443 }, 444 { 445 name: "number 1", 446 path: "1", 447 index: 1, 448 isErr: false, 449 }, 450 { 451 name: "float", 452 path: "3.1e4", 453 index: 5, 454 isErr: false, 455 }, 456 { 457 name: "float with minus", 458 path: "3.1e-4", 459 index: 6, 460 isErr: false, 461 }, 462 { 463 name: "float with plus", 464 path: "3.1e+4", 465 index: 6, 466 isErr: false, 467 }, 468 { 469 name: "negative number", 470 path: "-12345", 471 index: 6, 472 isErr: false, 473 }, 474 { 475 name: "negative float", 476 path: "-3.1e4", 477 index: 6, 478 isErr: false, 479 }, 480 { 481 name: "negative float with minus", 482 path: "-3.1e-4", 483 index: 7, 484 isErr: false, 485 }, 486 { 487 name: "negative float with plus", 488 path: "-3.1e+4", 489 index: 7, 490 isErr: false, 491 }, 492 { 493 name: "string number", 494 path: "'12345'", 495 index: 7, 496 isErr: false, 497 }, 498 { 499 name: "string with backslash", 500 path: "'foo \\'bar '", 501 index: 12, 502 isErr: false, 503 }, 504 { 505 name: "string with inner double quotes", 506 path: "'foo \"bar \"'", 507 index: 12, 508 isErr: false, 509 }, 510 { 511 name: "parenthesis 1", 512 path: "(@abc)", 513 index: 6, 514 isErr: false, 515 }, 516 { 517 name: "parenthesis 2", 518 path: "[()]", 519 index: 4, 520 isErr: false, 521 }, 522 { 523 name: "parenthesis mismatch", 524 path: "[(])", 525 index: 2, 526 isErr: true, 527 }, 528 { 529 name: "parenthesis mismatch 2", 530 path: "(", 531 index: 1, 532 isErr: true, 533 }, 534 { 535 name: "parenthesis mismatch 3", 536 path: "())]", 537 index: 2, 538 isErr: true, 539 }, 540 { 541 name: "bracket mismatch", 542 path: "[()", 543 index: 3, 544 isErr: true, 545 }, 546 { 547 name: "bracket mismatch 2", 548 path: "()]", 549 index: 2, 550 isErr: true, 551 }, 552 { 553 name: "path does not close bracket", 554 path: "@.foo[)", 555 index: 6, 556 isErr: false, 557 }, 558 } 559 560 for _, tt := range tests { 561 t.Run(tt.name, func(t *testing.T) { 562 buf := newBuffer([]byte(tt.path)) 563 564 err := buf.pathToken() 565 if tt.isErr { 566 if err == nil { 567 t.Errorf("Expected an error for path `%s`, but got none", tt.path) 568 } 569 } 570 571 if err == nil && tt.isErr { 572 t.Errorf("Expected an error for path `%s`, but got none", tt.path) 573 } 574 575 if buf.index != tt.index { 576 t.Errorf("Expected final index %d, got %d (token: `%s`) for path `%s`", tt.index, buf.index, string(buf.data[buf.index]), tt.path) 577 } 578 }) 579 } 580 } 581 582 func TestBufferFirst(t *testing.T) { 583 tests := []struct { 584 name string 585 data []byte 586 expected byte 587 }{ 588 { 589 name: "Valid first byte", 590 data: []byte("test"), 591 expected: 't', 592 }, 593 { 594 name: "Empty buffer", 595 data: []byte(""), 596 expected: 0, 597 }, 598 { 599 name: "Whitespace buffer", 600 data: []byte(" "), 601 expected: 0, 602 }, 603 { 604 name: "whitespace in middle", 605 data: []byte("hello world"), 606 expected: 'h', 607 }, 608 } 609 610 for _, tt := range tests { 611 t.Run(tt.name, func(t *testing.T) { 612 b := newBuffer(tt.data) 613 614 got, err := b.first() 615 if err != nil && tt.expected != 0 { 616 t.Errorf("Unexpected error: %v", err) 617 } 618 619 if got != tt.expected { 620 t.Errorf("Expected first byte to be %q, got %q", tt.expected, got) 621 } 622 }) 623 } 624 }