buffer_test.gno
11.56 Kb ยท 593 lines
1package json
2
3import (
4 "testing"
5)
6
7func 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
50func 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
78func 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
113func 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
179func 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
216func 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
247func TestSkipToNextSignificantToken(t *testing.T) {
248 tests := []struct {
249 name string
250 input []byte
251 expected int
252 }{
253 {"No significant chars", []byte("abc"), 3},
254 {"One significant char at start", []byte(".abc"), 0},
255 {"Significant char in middle", []byte("ab.c"), 2},
256 {"Multiple significant chars", []byte("a$.c"), 1},
257 {"Significant char at end", []byte("abc$"), 3},
258 {"Only significant chars", []byte("$."), 0},
259 {"Empty string", []byte(""), 0},
260 }
261
262 for _, tt := range tests {
263 t.Run(tt.name, func(t *testing.T) {
264 b := newBuffer(tt.input)
265 b.skipToNextSignificantToken()
266 if b.index != tt.expected {
267 t.Errorf("after skipToNextSignificantToken(), got index = %v, want %v", b.index, tt.expected)
268 }
269 })
270 }
271}
272
273func mockBuffer(s string) *buffer {
274 return newBuffer([]byte(s))
275}
276
277func TestSkipAndReturnIndex(t *testing.T) {
278 tests := []struct {
279 name string
280 input string
281 expected int
282 }{
283 {"StartOfString", "", 0},
284 {"MiddleOfString", "abcdef", 1},
285 {"EndOfString", "abc", 1},
286 }
287
288 for _, tt := range tests {
289 t.Run(tt.name, func(t *testing.T) {
290 buf := mockBuffer(tt.input)
291 got, err := buf.skipAndReturnIndex()
292 if err != nil && tt.input != "" { // Expect no error unless input is empty
293 t.Errorf("skipAndReturnIndex() error = %v", err)
294 }
295 if got != tt.expected {
296 t.Errorf("skipAndReturnIndex() = %v, want %v", got, tt.expected)
297 }
298 })
299 }
300}
301
302func TestSkipUntil(t *testing.T) {
303 tests := []struct {
304 name string
305 input string
306 tokens map[byte]bool
307 expected int
308 }{
309 {"SkipToToken", "abcdefg", map[byte]bool{'c': true}, 2},
310 {"SkipToEnd", "abcdefg", map[byte]bool{'h': true}, 7},
311 {"SkipNone", "abcdefg", map[byte]bool{'a': true}, 0},
312 }
313
314 for _, tt := range tests {
315 t.Run(tt.name, func(t *testing.T) {
316 buf := mockBuffer(tt.input)
317 got, err := buf.skipUntil(tt.tokens)
318 if err != nil && got != len(tt.input) { // Expect error only if reached end without finding token
319 t.Errorf("skipUntil() error = %v", err)
320 }
321 if got != tt.expected {
322 t.Errorf("skipUntil() = %v, want %v", got, tt.expected)
323 }
324 })
325 }
326}
327
328func TestSliceFromIndices(t *testing.T) {
329 tests := []struct {
330 name string
331 input string
332 start int
333 end int
334 expected string
335 }{
336 {"FullString", "abcdefg", 0, 7, "abcdefg"},
337 {"Substring", "abcdefg", 2, 5, "cde"},
338 {"OutOfBounds", "abcdefg", 5, 10, "fg"},
339 }
340
341 for _, tt := range tests {
342 t.Run(tt.name, func(t *testing.T) {
343 buf := mockBuffer(tt.input)
344 got := buf.sliceFromIndices(tt.start, tt.end)
345 if string(got) != tt.expected {
346 t.Errorf("sliceFromIndices() = %v, want %v", string(got), tt.expected)
347 }
348 })
349 }
350}
351
352func TestBufferToken(t *testing.T) {
353 tests := []struct {
354 name string
355 path string
356 index int
357 isErr bool
358 }{
359 {
360 name: "Simple valid path",
361 path: "@.length",
362 index: 8,
363 isErr: false,
364 },
365 {
366 name: "Path with array expr",
367 path: "@['foo'].0.bar",
368 index: 14,
369 isErr: false,
370 },
371 {
372 name: "Path with array expr and simple fomula",
373 path: "@['foo'].[(@.length - 1)].*",
374 index: 27,
375 isErr: false,
376 },
377 {
378 name: "Path with filter expr",
379 path: "@['foo'].[?(@.bar == 1 & @.baz < @.length)].*",
380 index: 45,
381 isErr: false,
382 },
383 {
384 name: "addition of foo and bar",
385 path: "@.foo+@.bar",
386 index: 11,
387 isErr: false,
388 },
389 {
390 name: "logical AND of foo and bar",
391 path: "@.foo && @.bar",
392 index: 14,
393 isErr: false,
394 },
395 {
396 name: "logical OR of foo and bar",
397 path: "@.foo || @.bar",
398 index: 14,
399 isErr: false,
400 },
401 {
402 name: "accessing third element of foo",
403 path: "@.foo,3",
404 index: 7,
405 isErr: false,
406 },
407 {
408 name: "accessing last element of array",
409 path: "@.length-1",
410 index: 10,
411 isErr: false,
412 },
413 {
414 name: "number 1",
415 path: "1",
416 index: 1,
417 isErr: false,
418 },
419 {
420 name: "float",
421 path: "3.1e4",
422 index: 5,
423 isErr: false,
424 },
425 {
426 name: "float with minus",
427 path: "3.1e-4",
428 index: 6,
429 isErr: false,
430 },
431 {
432 name: "float with plus",
433 path: "3.1e+4",
434 index: 6,
435 isErr: false,
436 },
437 {
438 name: "negative number",
439 path: "-12345",
440 index: 6,
441 isErr: false,
442 },
443 {
444 name: "negative float",
445 path: "-3.1e4",
446 index: 6,
447 isErr: false,
448 },
449 {
450 name: "negative float with minus",
451 path: "-3.1e-4",
452 index: 7,
453 isErr: false,
454 },
455 {
456 name: "negative float with plus",
457 path: "-3.1e+4",
458 index: 7,
459 isErr: false,
460 },
461 {
462 name: "string number",
463 path: "'12345'",
464 index: 7,
465 isErr: false,
466 },
467 {
468 name: "string with backslash",
469 path: "'foo \\'bar '",
470 index: 12,
471 isErr: false,
472 },
473 {
474 name: "string with inner double quotes",
475 path: "'foo \"bar \"'",
476 index: 12,
477 isErr: false,
478 },
479 {
480 name: "parenthesis 1",
481 path: "(@abc)",
482 index: 6,
483 isErr: false,
484 },
485 {
486 name: "parenthesis 2",
487 path: "[()]",
488 index: 4,
489 isErr: false,
490 },
491 {
492 name: "parenthesis mismatch",
493 path: "[(])",
494 index: 2,
495 isErr: true,
496 },
497 {
498 name: "parenthesis mismatch 2",
499 path: "(",
500 index: 1,
501 isErr: true,
502 },
503 {
504 name: "parenthesis mismatch 3",
505 path: "())]",
506 index: 2,
507 isErr: true,
508 },
509 {
510 name: "bracket mismatch",
511 path: "[()",
512 index: 3,
513 isErr: true,
514 },
515 {
516 name: "bracket mismatch 2",
517 path: "()]",
518 index: 2,
519 isErr: true,
520 },
521 {
522 name: "path does not close bracket",
523 path: "@.foo[)",
524 index: 6,
525 isErr: false,
526 },
527 }
528
529 for _, tt := range tests {
530 t.Run(tt.name, func(t *testing.T) {
531 buf := newBuffer([]byte(tt.path))
532
533 err := buf.pathToken()
534 if tt.isErr {
535 if err == nil {
536 t.Errorf("Expected an error for path `%s`, but got none", tt.path)
537 }
538 }
539
540 if err == nil && tt.isErr {
541 t.Errorf("Expected an error for path `%s`, but got none", tt.path)
542 }
543
544 if buf.index != tt.index {
545 t.Errorf("Expected final index %d, got %d (token: `%s`) for path `%s`", tt.index, buf.index, string(buf.data[buf.index]), tt.path)
546 }
547 })
548 }
549}
550
551func TestBufferFirst(t *testing.T) {
552 tests := []struct {
553 name string
554 data []byte
555 expected byte
556 }{
557 {
558 name: "Valid first byte",
559 data: []byte("test"),
560 expected: 't',
561 },
562 {
563 name: "Empty buffer",
564 data: []byte(""),
565 expected: 0,
566 },
567 {
568 name: "Whitespace buffer",
569 data: []byte(" "),
570 expected: 0,
571 },
572 {
573 name: "whitespace in middle",
574 data: []byte("hello world"),
575 expected: 'h',
576 },
577 }
578
579 for _, tt := range tests {
580 t.Run(tt.name, func(t *testing.T) {
581 b := newBuffer(tt.data)
582
583 got, err := b.first()
584 if err != nil && tt.expected != 0 {
585 t.Errorf("Unexpected error: %v", err)
586 }
587
588 if got != tt.expected {
589 t.Errorf("Expected first byte to be %q, got %q", tt.expected, got)
590 }
591 })
592 }
593}