-
Notifications
You must be signed in to change notification settings - Fork 0
/
jsqt_test.go
1778 lines (1659 loc) · 69.4 KB
/
jsqt_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package jsqt
import (
"fmt"
"reflect"
"strings"
"testing"
)
func TestGet(t *testing.T) {
tt := []struct {
give string
when string
then string
}{
// (iterate -c)
{give: `{"a":3,"b":[{"a":4,"b":[{"a":5,"b":[{"a":6}]},{"a":7,"b":[{"a":8}]}]}]}`, when: `(iterate -c (== "a" (key)))`, then: `[3,4,5,6,7,8]`},
{give: `{"a":3,"b":[{"a":4,"b":[{"a":5,"b":[{"a":6}]},{"a":7,"b":[{"a":8}]}]}, {"a":9}]}`, when: `(iterate -c -d 3 (== "a" (key)))`, then: `[3,4,9]`},
// (partition)
{give: `[{"a":2},{"a":1},{"a":3}]`, when: `(partition (> 2 a))`, then: `[[{"a":3}],[{"a":2},{"a":1}]]`},
{give: `[1,2,3,4]`, when: `(partition (> 4))`, then: `[[],[1,2,3,4]]`},
{give: `[1,2,3,4]`, when: `(partition (> 3))`, then: `[[4],[1,2,3]]`},
{give: `[1,2,3,4]`, when: `(partition (> 2))`, then: `[[3,4],[1,2]]`},
{give: `[1,2,3,4]`, when: `(partition (> 1))`, then: `[[2,3,4],[1]]`},
{give: `[1,2,3,4]`, when: `(partition (> 0))`, then: `[[1,2,3,4],[]]`},
// (chunk)
{give: `[1,2,3,4]`, when: `(chunk 4)`, then: `[[1,2,3,4]]`},
{give: `[1,2,3,4]`, when: `(chunk 3)`, then: `[[1,2,3],[4]]`},
{give: `[1,2,3,4]`, when: `(chunk 2)`, then: `[[1,2],[3,4]]`},
{give: `[1,2,3,4]`, when: `(chunk 1)`, then: `[[1],[2],[3],[4]]`},
{give: `[1,2,3]`, when: `(chunk 11)`, then: `[[1,2,3]]`},
{give: `[1,2,3]`, when: `(chunk 4)`, then: `[[1,2,3]]`},
{give: `[1,2,3]`, when: `(chunk 3)`, then: `[[1,2,3]]`},
{give: `[1,2,3]`, when: `(chunk 2)`, then: `[[1,2],[3]]`},
{give: `[1,2,3]`, when: `(chunk 1)`, then: `[[1],[2],[3]]`},
{give: `[1,2,3]`, when: `(chunk 0)`, then: `[[1],[2],[3]]`},
// (min) (max)
{give: `[{"a":2},{"a":1},{"a":3}]`, when: `(max a)`, then: `3`},
{give: `[{"a":2},{"a":1},{"a":3}]`, when: `(min a)`, then: `1`},
{give: `[2,1,3]`, when: `(min)`, then: `1`},
{give: `[2,1,3]`, when: `(max)`, then: `3`},
{give: `[2]`, when: `(max)`, then: `2`},
{give: `[2]`, when: `(min)`, then: `2`},
// (valid)
{give: ``, when: `(valid)`, then: ``},
{give: `{"a":[3,{"a":}]}`, when: `(valid a)`, then: ``},
{give: `{"a":[3,{"a":4}]}`, when: `(valid a)`, then: `[3,{"a":4}]`},
{give: `{ "a" : [ { "b" : "c" } , null , false , true , { } , [ 3 , 1.2 ] ] }`, when: `(valid)`, then: `{ "a" : [ { "b" : "c" } , null , false , true , { } , [ 3 , 1.2 ] ] }`},
{give: `x`, when: `(valid)`, then: ``},
{give: `"a"`, when: `(valid)`, then: `"a"`},
{give: `""`, when: `(valid)`, then: `""`},
{give: `3`, when: `(valid)`, then: `3`},
{give: `true`, when: `(valid)`, then: `true`},
{give: `false`, when: `(valid)`, then: `false`},
{give: `null`, when: `(valid)`, then: `null`},
{give: `{"a":[{"b":"c"},null,false,true,{},[3,1.2,01]]}`, when: `(valid)`, then: ``},
{give: `{"a":[{"b":"c"},null,false,true,{},[3,1.2,x]]}`, when: `(valid)`, then: ``},
{give: `{"a":[{"b":"c"},null,false,true,{},[3,1.2,null]]}`, when: `(valid)`, then: `{"a":[{"b":"c"},null,false,true,{},[3,1.2,null]]}`},
{give: `{"a":[{"b":"c"},null,false,true,{},[]]}`, when: `(valid)`, then: `{"a":[{"b":"c"},null,false,true,{},[]]}`},
{give: `{"a":[{},[]]}`, when: `(valid)`, then: `{"a":[{},[]]}`},
{give: `{"a":[,""]}`, when: `(valid)`, then: ``},
{give: `{"a":["",""]}`, when: `(valid)`, then: `{"a":["",""]}`},
{give: `["a":""]`, when: `(valid)`, then: ``},
{give: `["" ""]`, when: `(valid)`, then: ``},
{give: `["",""]`, when: `(valid)`, then: `["",""]`},
{give: `[,""]`, when: `(valid)`, then: ``},
{give: `[3,4}`, when: `(valid)`, then: ``},
{give: `[3,,3]`, when: `(valid)`, then: ``},
{give: `[3,]`, when: `(valid)`, then: ``},
{give: `[""]`, when: `(valid)`, then: `[""]`},
{give: `[,]`, when: `(valid)`, then: ``},
{give: `]`, when: `(valid)`, then: ``},
{give: `[`, when: `(valid)`, then: ``},
{give: `[]`, when: `(valid)`, then: `[]`},
{give: `"a":""}`, when: `(valid)`, then: ``},
{give: `{"a",""}`, when: `(valid)`, then: ``},
{give: `{,"a"}`, when: `(valid)`, then: ``},
{give: `{,"a":""}`, when: `(valid)`, then: ``},
{give: `{"a":"",}`, when: `(valid)`, then: ``},
{give: `{"a":}`, when: `(valid)`, then: ``},
{give: `{"a":"}`, when: `(valid)`, then: ``},
{give: `{"a"""}`, when: `(valid)`, then: ``},
{give: `{"a":""`, when: `(valid)`, then: ``},
{give: `{"a":"b":""}`, when: `(valid)`, then: ``},
{give: `{"a":{"b":""}`, when: `(valid)`, then: ``},
{give: `{"a":{"b":"",}}`, when: `(valid)`, then: ``},
{give: `{,}`, when: `(valid)`, then: ``},
{give: `{"a":{"b":"","c":""}}`, when: `(valid)`, then: `{"a":{"b":"","c":""}}`},
{give: `{"a":{"b":""}}`, when: `(valid)`, then: `{"a":{"b":""}}`},
{give: `{"a":"",,"b":""}`, when: `(valid)`, then: ``},
{give: `{"a":"","b":""}`, when: `(valid)`, then: `{"a":"","b":""}`},
{give: `{"a":""}`, when: `(valid)`, then: `{"a":""}`},
{give: `{`, when: `(valid)`, then: ``},
{give: `}`, when: `(valid)`, then: ``},
{give: `{}`, when: `(valid)`, then: `{}`},
// (reduce)
{give: `{"a":3,"b":4,"c":5}`, when: `(reduce 2 (expr (this) + (val)))`, then: `14`},
{give: `[3,4,5]`, when: `(reduce 2 (expr (this) + (val)))`, then: `14`},
// (transpose)
{give: `3`, when: `(transpose)`, then: `3`},
{give: `[{"a":3,"b":5},{"a":4,"b":6,"c":7}]`, when: `(transpose)`, then: `{"a":[3,4],"b":[5,6]}`},
{give: `[{"a":3,"b":5,"c":7},{"a":4,"b":6}]`, when: `(transpose)`, then: `{"a":[3,4],"b":[5,6],"c":[7]}`},
{give: `[{"a":3,"b":5},{"a":4,"b":6}]`, when: `(transpose)`, then: `{"a":[3,4],"b":[5,6]}`},
{give: `{"a":[3,4,5],"b":[6,7]}`, when: `(transpose)`, then: `[{"a":3,"b":6},{"a":4,"b":7},{"a":5}]`},
{give: `{"a":[3,4],"b":[5,6,7,8]}`, when: `(transpose)`, then: `[{"a":3,"b":5},{"a":4,"b":6},{"b":7},{"b":8}]`},
{give: `{"a":[3,4],"b":[5,6],"c":[7]}`, when: `(transpose)`, then: `[{"a":3,"b":5,"c":7},{"a":4,"b":6}]`},
{give: `{"a":[3,4],"b":[5,6],"c":7}`, when: `(transpose)`, then: `[{"a":3,"b":5},{"a":4,"b":6}]`},
{give: `{"a":[3,4],"b":[5,6]}`, when: `(transpose)`, then: `[{"a":3,"b":5},{"a":4,"b":6}]`},
// (unwind)
{give: `{"a":3}`, when: `(unwind b)`, then: `[]`},
{give: `{"a":3,"b":null}`, when: `(unwind b)`, then: `[]`},
{give: `{"a":3,"b":[]}`, when: `(unwind b)`, then: `[]`},
{give: `{"a":3,"b":4}`, when: `(unwind b)`, then: `[]`},
{give: `[{"a":3,"b":[4,5]},{"a":6,"b":[7,8]}]`, when: `(unwind b)`, then: `[{"a":3,"b":4},{"a":3,"b":5},{"a":6,"b":7},{"a":6,"b":8}]`},
{give: `{"a":3,"b":[4,5]}`, when: `(unwind b -r x)`, then: `[{"a":3,"x":4},{"a":3,"x":5}]`},
{give: `{"a":3,"b":[4,5]}`, when: `(unwind b)`, then: `[{"a":3,"b":4},{"a":3,"b":5}]`},
// (expr)
{give: ``, when: `(expr 1 + 2 ? 3)`, then: `3`},
{give: ``, when: `(expr -4 * -5 + -(raw 1) - -2 + -3)`, then: `18`},
{give: `{"a":3}`, when: `(expr 4 * (expr 5 + (get a)))`, then: `32`},
{give: `{"a":3}`, when: `(expr 4 * 5 + (get a))`, then: `23`},
{give: ``, when: `(expr 1 + 1 / 2)`, then: `1.5`},
{give: ``, when: `(expr 1 + 1 % 2)`, then: `2`},
{give: ``, when: `(expr 1 % 2)`, then: `1`},
{give: ``, when: `(expr (raw 2) * 3 + 4 * 3 + 4 - 5)`, then: `17`},
{give: ``, when: `(expr 2 * 3 + 4 * 3 + 4 - 5)`, then: `17`},
{give: ``, when: `(expr 2 + 3 * 4 + 3 * 4 - 5)`, then: `21`},
{give: ``, when: `(expr 3 * (expr 4 * 2 - 5 + (expr 2 + 3) * 4 * 2 - 5) + 2)`, then: `116`},
{give: ``, when: `(expr 3 * 4 * 2 - 5 + (expr 2 + 3) * 4 * 2 - 5 + 2)`, then: `56`},
{give: ``, when: `(expr 3 * 4 * 2 - 5 + 2 + 3 * 4 * 2 - 5 + 2)`, then: `42`},
{give: ``, when: `(expr 3 * 4 - 5 + 2)`, then: `9`},
{give: ``, when: `(expr 3 * 4 * 2 - 5 + 2)`, then: `21`},
{give: ``, when: `(expr 2 + 3 * 4 - 5 + 2 + 3 * 4 - 5)`, then: `18`},
{give: ``, when: `(expr 2.1 + 2.5)`, then: `4.6`},
{give: ``, when: `(expr 2 - 5)`, then: `-3`},
{give: ``, when: `(expr 2 - -2)`, then: `4`},
{give: ``, when: `(expr 2 - 2)`, then: `0`},
{give: ``, when: `(expr 3 * 4)`, then: `12`},
{give: ``, when: `(expr 3 + 4)`, then: `7`},
{give: ``, when: `(expr 3)`, then: `3`},
// (at)
{give: `[3,4]`, when: `(at (raw 1))`, then: `4`},
{give: `[3,4]`, when: `(at 0)`, then: `3`},
// (group)
{give: `[{"a":"3"},{"a":"3"},{"a":"4"}]`, when: `(group a (val) -a x y)`, then: `[{"x":"3","y":[{"a":"3"},{"a":"3"}]},{"x":"4","y":[{"a":"4"}]}]`},
{give: `[{"a":3},{"a":3},{"a":4}]`, when: `(group a (val) -a x y)`, then: `[{"x":3,"y":[{"a":3},{"a":3}]},{"x":4,"y":[{"a":4}]}]`},
{give: `[{"a":3},{"a":3},{"a":4}]`, when: `(group a (val) -a)`, then: `[{"key":3,"values":[{"a":3},{"a":3}]},{"key":4,"values":[{"a":4}]}]`},
{give: `[{"a":3},{"a":3},{"a":4}]`, when: `(group a (val) -a)`, then: `[{"key":3,"values":[{"a":3},{"a":3}]},{"key":4,"values":[{"a":4}]}]`},
{give: `[{"a":3},{"a":3},{"a":4}]`, when: `(group a (val))`, then: `{"3":[{"a":3},{"a":3}],"4":[{"a":4}]}`},
{give: `[3,4,3,4,5]`, when: `(group (val) (key))`, then: `{"3":[0,2],"4":[1,3],"5":[4]}`},
// (unique)
{give: `[{"a":3},{"a":3},{"a":4}]`, when: `(unique a)`, then: `[3,4]`},
{give: `[3,4,3,4,5]`, when: `(unique)`, then: `[3,4,5]`},
// (in)
{give: `[3,4,5,6,7]`, when: `(collect (not (in [4,6])))`, then: `[3,5,7]`},
{give: `[3,4,5,6,7]`, when: `(collect (in [4,6]))`, then: `[4,6]`},
// (slice)
{give: `3`, when: `(slice 0)`, then: `3`},
{give: `[3,4,5,6,7,8]`, when: `(slice 2 -1)`, then: `[5,6,7]`},
{give: `[3,4,5,6,7,8]`, when: `(slice -2)`, then: `[7,8]`},
{give: `[3,4,5,6,7,8]`, when: `(slice 2 4)`, then: `[5,6]`},
{give: `[3,4,5,6,7,8]`, when: `(slice 0 3)`, then: `[3,4,5]`},
{give: `[3,4,5,6,7,8]`, when: `(slice 0 0)`, then: `[3,4,5,6,7,8]`},
{give: `[3,4,5,6,7,8]`, when: `(slice 6)`, then: `[]`},
{give: `[3,4,5,6,7,8]`, when: `(slice 3)`, then: `[6,7,8]`},
{give: `[3,4,5,6,7,8]`, when: `(slice 1)`, then: `[4,5,6,7,8]`},
{give: `[3,4,5,6,7,8]`, when: `(slice 0)`, then: `[3,4,5,6,7,8]`},
// (match)
{give: `{"a":3,"aab":4,"aac":5,"bac":6}`, when: `(match -kk x)`, then: ``},
{give: `{"a":3,"aab":4,"aac":5,"bac":6}`, when: `(match -kk a)`, then: `"a"`},
{give: `{"a":3,"aab":4,"aac":5,"bac":6}`, when: `(match -kk -s ab)`, then: `"aab"`},
{give: `{"a":3,"aab":4,"aac":5,"bac":6}`, when: `(match -kk -p aa)`, then: `"aab"`},
{give: `{"a":3,"aab":4,"aac":5,"bac":6}`, when: `(match -kk -r ^aa)`, then: `"aab"`},
{give: `{"a":3,"b":4}`, when: `(match -k b)`, then: `4`},
{give: `{"a":3,"aab":4,"aac":5,"bac":6}`, when: `(match -k -r ^aa)`, then: `4`},
{give: `{"a":3,"aab":4,"aac":5,"bac":6}`, when: `(match -k -s ac)`, then: `5`},
{give: `{"a":3,"aab":4,"aac":5,"bac":6}`, when: `(match -k -p aa)`, then: `4`},
{give: `[{"a":3},{"a":4},{"a":5}]`, when: `(get * (match -v (match -k -r ^a) -r [35]))`, then: `[{"a":3},{"a":5}]`},
{give: `[{"a":3},{"a":4},{"a":5}]`, when: `(get * (match -v a -r [35]))`, then: `[{"a":3},{"a":5}]`},
{give: `{"a_b":3,"a_c":4,"b_c":5}`, when: `(iterate (match -s _c) (this))`, then: `{"a_c":4,"b_c":5}`},
{give: `{"a_b":3,"a_c":4,"b_c":5}`, when: `(iterate (match -p a_) (this))`, then: `{"a_b":3,"a_c":4}`},
{give: `{"a_b":3,"a_c":4,"b_c":5}`, when: `(iterate (match -r ^a_) (this))`, then: `{"a_b":3,"a_c":4}`},
{give: `{"a_b":3,"a_c":4,"b_c":5}`, when: `(iterate (match a_c) (this))`, then: `{"a_c":4}`},
// (set)
{give: `[{"a":[3]}]`, when: `(set * a (nothing) 7)`, then: `[{"a":[3]}]`}, // Should not crash.
{give: `[{"a":3,"b":[{"c":4,"d":5}]},{"a":6,"b":[{"c":7,"d":8}]}]`, when: `(set * -m (pick b) b * -m (upsert x 0) c 9)`, then: `[{"b":[{"x":0,"c":9,"d":5}]},{"b":[{"x":0,"c":9,"d":8}]}]`},
{give: `[{"a":{"b":3,"c":4,"d":{"e":5}}},{"a":{"b":6,"c":7,"d":{"e":8}}}]`, when: `(set * a -m (pick c d) d e 9)`, then: `[{"a":{"c":4,"d":{"e":9}}},{"a":{"c":7,"d":{"e":9}}}]`},
{give: `[{"a":[{"a":3},{"a":4}]},{"a":[{"a":5}]}]`, when: `(set * a -r y * a -r x (this))`, then: `[{"y":[{"x":3},{"x":4}]},{"y":[{"x":5}]}]`},
{give: `[{"a":[{"a":3},{"a":4}]},{"a":[{"a":5}]}]`, when: `(set * a -r y * a (this))`, then: `[{"y":[{"a":3},{"a":4}]},{"y":[{"a":5}]}]`},
{give: `[{"a":[{"a":3},{"a":4}]},{"a":[{"a":5}]}]`, when: `(set * a * a -r x (this))`, then: `[{"a":[{"x":3},{"x":4}]},{"a":[{"x":5}]}]`},
{give: `[{"a":3},{"a":3}]`, when: `(set * a -r x (this))`, then: `[{"x":3},{"x":3}]`},
{give: `{"a":3,"b":4}`, when: `(set c -r x (this))`, then: `{"a":3,"b":4}`},
{give: `{"a":3,"b":4}`, when: `(set b -r x (this))`, then: `{"a":3,"x":4}`},
{give: `{"a":3,"b":4}`, when: `(set a -r x (this))`, then: `{"x":3,"b":4}`},
{give: `3`, when: `(set a 7)`, then: `3`},
{give: `{"a":{"b":3}}`, when: `(set -i a a 0 a 3)`, then: `{"a":{"b":3,"a":[{"a":3}]}}`},
{give: `{}`, when: `(set -i 0 a 0 a 3)`, then: `[{"a":[{"a":3}]}]`},
{give: `{}`, when: `(set -i 0 a 0 0 3)`, then: `[{"a":[[3]]}]`},
{give: `{}`, when: `(set -i 0 a 0 3)`, then: `[{"a":[3]}]`},
{give: `{}`, when: `(set -i 0 0 a 3)`, then: `[[{"a":3}]]`},
{give: `{}`, when: `(set -i 0 0 0 3)`, then: `[[[3]]]`},
{give: `{}`, when: `(set -i 0 0 3)`, then: `[[3]]`},
{give: `{}`, when: `(set -i 0 3)`, then: `[3]`},
{give: `{}`, when: `(set -i 0)`, then: `0`},
{give: `{}`, when: `(set -i "0" 3)`, then: `{"0":3}`},
{give: `{}`, when: `(set -i a 0 b 0 3)`, then: `{"a":[{"b":[3]}]}`},
{give: `{}`, when: `(set -i a 1 b 3)`, then: `{"a":[{"b":3}]}`},
{give: `{}`, when: `(set -i a 0 b 3)`, then: `{"a":[{"b":3}]}`},
{give: `{"1":[{"1":[{"1":3},{"1":4}]},{"1":[{"1":5},{"1":6}]}]}`, when: `(set 1 1 1 1 1 7)`, then: `{"1":[{"1":[{"1":3},{"1":4}]},{"1":[{"1":5},{"1":7}]}]}`},
{give: `{"1":[{"1":[{"1":3},{"1":4}]},{"1":[{"1":5},{"1":6}]}]}`, when: `(set 1 * 1 * 1 7)`, then: `{"1":[{"1":[{"1":7},{"1":7}]},{"1":[{"1":7},{"1":7}]}]}`},
{give: `{"*":[{"*":[{"*":3},{"*":4}]},{"*":[{"*":5},{"*":6}]}]}`, when: `(set * * * * * 7)`, then: `{"*":[{"*":[{"*":7},{"*":7}]},{"*":[{"*":7},{"*":7}]}]}`},
{give: `{"a":[{"1":[{"c":3},{"c":4}]},{"1":[{"c":5},{"c":6}]}]}`, when: `(set a * 1 * c 7)`, then: `{"a":[{"1":[{"c":7},{"c":7}]},{"1":[{"c":7},{"c":7}]}]}`},
{give: `{"a":[{"*":[{"c":3},{"c":4}]},{"*":[{"c":5},{"c":6}]}]}`, when: `(set a * * * c 7)`, then: `{"a":[{"*":[{"c":7},{"c":7}]},{"*":[{"c":7},{"c":7}]}]}`},
{give: `{"a":[{"b":[{"c":3},{"c":4}]},{"b":[{"c":5},{"c":6}]}]}`, when: `(set a * b * c 7)`, then: `{"a":[{"b":[{"c":7},{"c":7}]},{"b":[{"c":7},{"c":7}]}]}`},
{give: `[[3],[4,5]]`, when: `(set -i 0 1 x 7)`, then: `[[3,{"x":7}],[4,5]]`},
{give: `{"a":[{"b":[{"c":3},{"c":4}]},{"b":[{"c":5},{"c":6}]}]}`, when: `(set -i a * b 100 {})`, then: `{"a":[{"b":[{"c":3},{"c":4},{}]},{"b":[{"c":5},{"c":6},{}]}]}`},
{give: `{"a":[{"b":[{"c":3},{"c":4}]},{"b":[{"c":5},{"c":6}]}]}`, when: `(set -i a * b 7)`, then: `{"a":[{"b":7},{"b":7}]}`},
{give: `{"a":[{"b":[{"c":3},{"c":4}]},{"b":[{"c":5},{"c":6}]}]}`, when: `(set -i a * b * 7)`, then: `{"a":[{"b":[7,7]},{"b":[7,7]}]}`},
{give: `{"a":[{"b":3},{"c":4}]}`, when: `(set -i a * x c (raw 7))`, then: `{"a":[{"b":3,"x":{"c":7}},{"c":4,"x":{"c":7}}]}`},
{give: `{"a":{"b":3,"c":4}}`, when: `(set -i a x c (raw 7))`, then: `{"a":{"b":3,"c":4,"x":{"c":7}}}`},
{give: `[3]`, when: `(set -i 1 (raw 7))`, then: `[3,7]`},
{give: `{}`, when: `(set -i x 5)`, then: `{"x":5}`},
{give: `[{"a":[3,4]},{"a":[3,4]},{"b":[3,4]}]`, when: `(set * a 1 (raw 7))`, then: `[{"a":[3,7]},{"a":[3,7]},{"b":[3,4]}]`},
{give: `{"a":[{"b":3,"a":[{"b":4},{"b":5}]},{"b":6}]}`, when: `(set a 0 a * b (raw 7))`, then: `{"a":[{"b":3,"a":[{"b":7},{"b":7}]},{"b":6}]}`},
{give: `{"a":[{"b":3,"a":[{"b":4},{"b":5}]},{"b":6}]}`, when: `(set a 0 a 1 b (raw 7))`, then: `{"a":[{"b":3,"a":[{"b":4},{"b":7}]},{"b":6}]}`},
{give: `{"a":[{"b":3,"a":[{"b":4},{"b":5}]},{"b":6}]}`, when: `(set a 0 a 0 b (raw 7))`, then: `{"a":[{"b":3,"a":[{"b":7},{"b":5}]},{"b":6}]}`},
{give: `{"e":3,"a":{"b":{"c":[{"d":4},{"d":5}],"f":6},"f":8},"f":9}`, when: `(set a b c * d (raw 7))`, then: `{"e":3,"a":{"b":{"c":[{"d":7},{"d":7}],"f":6},"f":8},"f":9}`},
{give: `[{"a":3},{"a":4},{"b":5}]`, when: `(set * a (raw 7))`, then: `[{"a":7},{"a":7},{"b":5}]`},
{give: `{"a":[{"b":3},{"b":4}],"b":5}`, when: `(set a 1 b (raw 7))`, then: `{"a":[{"b":3},{"b":7}],"b":5}`},
{give: `{"a":[{"b":3},{"b":4}],"b":5}`, when: `(set a 0 b (raw 7))`, then: `{"a":[{"b":7},{"b":4}],"b":5}`},
{give: `{"a":{"0":[3,4]}}`, when: `(set a 0 1 (raw 7))`, then: `{"a":{"0":[3,7]}}`},
{give: `{"a":{"b":[3,4]}}`, when: `(set a b 1 (raw 7))`, then: `{"a":{"b":[3,7]}}`},
{give: `[[3],[4,5],[[8]]]`, when: `(set * 0 (nothing))`, then: `[[],[5],[]]`},
{give: `[[3],[4,5],[[8]]]`, when: `(set 0 (nothing))`, then: `[[4,5],[[8]]]`},
{give: `[[3],[4,5]]`, when: `(set 1 (nothing))`, then: `[[3]]`},
{give: `[[3],[4,5]]`, when: `(set 0 (nothing))`, then: `[[4,5]]`},
{give: `[[3],[4,5]]`, when: `(set 0 (raw 7))`, then: `[7,[4,5]]`},
{give: `[[3],[4,5]]`, when: `(set 1 (raw 7))`, then: `[[3],7]`},
{give: `[[3],[4,5]]`, when: `(set 1 1 (raw 7))`, then: `[[3],[4,7]]`},
{give: `[[3],[4,5]]`, when: `(set 1 0 (raw 7))`, then: `[[3],[7,5]]`},
{give: `[[3],[4,5]]`, when: `(set 0 0 (raw 7))`, then: `[[7],[4,5]]`},
{give: `[3,4,5]`, when: `(set 3 (nothing))`, then: `[3,4,5]`},
{give: `[3,4,5]`, when: `(set 2 (nothing))`, then: `[3,4]`},
{give: `[3,4,5]`, when: `(set 1 (nothing))`, then: `[3,5]`},
{give: `[3,4,5]`, when: `(set 0 (nothing))`, then: `[4,5]`},
{give: `[3,4,5]`, when: `(set 3 (raw 7))`, then: `[3,4,5]`},
{give: `[3,4,5]`, when: `(set 2 (raw 7))`, then: `[3,4,7]`},
{give: `[3,4,5]`, when: `(set 1 (raw 7))`, then: `[3,7,5]`},
{give: `[3,4,5]`, when: `(set 0 (raw 7))`, then: `[7,4,5]`},
{give: `{"0":3}`, when: `(set 0 (raw 7))`, then: `{"0":7}`},
{give: `[[[3]]]`, when: `(set 0 (raw 7))`, then: `[7]`},
{give: `[[3]]`, when: `(set 0 (raw 7))`, then: `[7]`},
{give: `[3]`, when: `(set 0 (raw 7))`, then: `[7]`},
{give: `{"a":{"b":"c"},"d":3}`, when: `(set a (nothing))`, then: `{"d":3}`},
{give: `{"a":3,"b":{"c":4,"d":5,"e":{}},"f":6}`, when: `(set b e (nothing))`, then: `{"a":3,"b":{"c":4,"d":5},"f":6}`},
{give: `{"a":{"b":"c"},"d":3}`, when: `(set d (raw 7))`, then: `{"a":{"b":"c"},"d":7}`},
{give: `{"a":{"b":"bb","c":"cc"}}`, when: `(set a c (raw 7))`, then: `{"a":{"b":"bb","c":7}}`},
{give: `{"a":3,"b":{"c":4,"d":5},"e":6}`, when: `(set b d (raw 7))`, then: `{"a":3,"b":{"c":4,"d":7},"e":6}`},
{give: `{"a":3,"b":4}`, when: `(set a (nothing))`, then: `{"b":4}`},
{give: `{"a":3,"b":4}`, when: `(set b (nothing))`, then: `{"a":3}`},
{give: `{"a":3,"b":4}`, when: `(set b (raw 7))`, then: `{"a":3,"b":7}`},
{give: `{"a":3,"b":4}`, when: `(set a (raw 7))`, then: `{"a":7,"b":4}`},
{give: `{"a":3,"b":4}`, when: `(set a 7)`, then: `{"a":7,"b":4}`},
// (key) (val)
{give: `[[3,4]]`, when: `(get * (arr (key) (val) (obj -i (key) (val)) (key) (val))) (flatten)`, then: `[0,[3,4],{"0":3,"1":4},0,[3,4]]`},
{give: `[3,4]`, when: `(collect (arr (key) (val)))`, then: `[[0,3],[1,4]]`},
{give: `{"a":3,"c":4}`, when: `(iterate (concat (key) (val)) (arr (key) (val)))`, then: `{"a3":["a",3],"c4":["c",4]}`},
{give: `{"a":3,"c":4}`, when: `(iterate -r (key) (arr (key) (val)))`, then: `[null,{"a":["a",3],"c":["c",4]}]`},
{give: `{"a":3}`, when: `(iterate -k (key))`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(iterate -v (val))`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(iterate -kv (concat (key) (val)))`, then: `{"aa":"33"}`},
// (save) (load)
{give: `{"a":3,"b":4}`, when: `(save -k a b c -v (raw 7)) (obj x (load a) y (load b) z (load c)`, then: `{"x":3,"y":4,"z":7}`},
{give: `{"a":3}`, when: `(save (get a)) (arr (load))`, then: `[3]`},
{give: `{"a":3}`, when: `(save a) (arr (load))`, then: `[3]`},
{give: `{"a":3}`, when: `a (save) (arr (load))`, then: `[3]`},
// (iterate)
{give: `3`, when: `(iterate -r (key) (stringify))`, then: `"3"`},
{give: `{"a":{"b":{"c":3}}}`, when: `(iterate -d 3 (upper) (val))`, then: `{"A":{"B":{"C":3}}}`},
{give: `{"a":{"b":{"c":3}}}`, when: `(iterate -d 2 (upper) (val))`, then: `{"A":{"B":{"c":3}}}`},
{give: `{"a":{"b":{"c":3}}}`, when: `(iterate -d 1 (upper) (val))`, then: `{"A":{"b":{"c":3}}}`},
{give: `{"a":3,"b":{},"c":{"d":4,"e":[]},"f":{"g":[]},"h":[5,[6],{}]}`, when: `(iterate (upper) (not (is-empty)))`, then: `{"A":3,"C":{"D":4},"H":[5,[6]]}`},
{give: `{"a":{"a":3,"b":4,"c":5},"b":{"a":6,"b":7,"c":8},"c":9}`, when: `(iterate (!= "c") (this))`, then: `{"a":{"a":3,"b":4},"b":{"a":6,"b":7}}`},
{give: `{"a":{"a":3,"b":4,"c":5},"b":{"a":6,"b":7,"c":8},"c":9}`, when: `(iterate (this) (pluck c))`, then: `{"a":{"a":3,"b":4},"b":{"a":6,"b":7},"c":9}`},
{give: `{"a":{"a":3,"b":4,"c":{"a":5,"c":6}},"b":{"a":6,"b":7,"c":8},"c":9}`, when: `(iterate -r (this) (pluck c))`, then: `{"a":{"a":3,"b":4},"b":{"a":6,"b":7}}`},
{give: `{"a":{"a":3,"b":4,"c":5},"b":{"a":6,"b":7,"c":8},"c":9}`, when: `(iterate -r (this) (pluck c))`, then: `{"a":{"a":3,"b":4},"b":{"a":6,"b":7}}`},
{give: `{"a":3}`, when: `(iterate (raw "a b") (this))`, then: `{"a b":3}`},
{give: `{"a":3}`, when: `(iterate (if (== "a") (nothing)) (this))`, then: `{}`},
{give: `[4,5]`, when: `(iterate (this) (if (is-num) (nothing)))`, then: `[]`},
// Test empty context input for many functions.
{give: `["3 4","5 6","7 8"]`, when: `(collect (!= "5 6") (replace " " "_"))`, then: `["3_4","7_8"]`},
{give: `[[3,4],[5,6],[7,8]]`, when: `(collect (!= 6 1) (reverse))`, then: `[[4,3],[8,7]]`},
{give: `[[3,4],[5,6],[7,8]]`, when: `(collect (!= 6 1) (sort desc))`, then: `[[4,3],[8,7]]`},
// (def)
{give: `{"a":3,"b":4}`, when: `(def b (a)) (def a (stringify)) (arr (get a (a)) (get b (b)))`, then: `["3","4"]`},
{give: `{"a":3,"b":4}`, when: `(def a (stringify)) (def b (a)) (arr (get a (a)) (get b (b)))`, then: `["3","4"]`},
{give: `{"a":3,"b":4}`, when: `(def a (get a)) (def b (load)) (save (raw 5)) (arr (a) (b))`, then: `[3,5]`},
{give: `{"a":3,"b":4}`, when: `(def a (get a)) (def b (get b)) (arr (a) (b))`, then: `[3,4]`},
// (upsert)
{give: `3`, when: `(upsert b 5)`, then: `3`},
{give: `{"a":3}`, when: `(upsert (nothing) a)`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(upsert x (nothing))`, then: `{"a":3}`},
{give: `{"a":3,"b":4,"c":5}`, when: `(upsert x 5 y (get a) b 7 a (nothing))`, then: `{"x":5,"y":3,"b":7,"c":5}`},
{give: `{"a":3,"b":4}`, when: `(upsert b 5)`, then: `{"b":5,"a":3}`},
// (pluck)
{give: `{"a":3,"b":4,"c":5}`, when: `(pluck b c)`, then: `{"a":3}`},
// (pick)
{give: `{"a":3,"b":4,"c":5}`, when: `(pick b -r x -m (concat (raw "b") (this)) c)`, then: `{"x":"b4","c":5}`},
{give: `{"a":3,"b":4,"c":5}`, when: `(pick b -r x c)`, then: `{"x":4,"c":5}`},
{give: `{"a":{"b":3,"c":4,"d":{"e":3,"f":4}},"c":5}`, when: `(pick a -m (pick b d -m (pick f)))`, then: `{"a":{"b":3,"d":{"f":4}}}`},
{give: `{"a":{"b":3,"c":4},"b":{"d":3,"e":4},"c":5}`, when: `(pick a -m (pick c) c -m (nothing))`, then: `{"a":{"c":4}}`},
{give: `{"a":{"b":3,"c":4},"b":{"d":3,"e":4},"c":5}`, when: `(pick a -m (pick c) b -m (pick d))`, then: `{"a":{"c":4},"b":{"d":3}}`},
{give: `{"a":3,"b":4,"c":5}`, when: `(pick b c)`, then: `{"b":4,"c":5}`},
{give: `3`, when: `(pick)`, then: `3`},
// (this)
{give: `[3,4]`, when: `(collect (obj x (this)))`, then: `[{"x":3},{"x":4}]`},
// (split)
{give: `{"a":"one,two"}`, when: `(split ";" a)`, then: `["one,two"]`},
{give: `"one,two,three"`, when: `(split ";")`, then: `["one,two,three"]`},
{give: `"one,\"two three\""`, when: `(split ",")`, then: `["one","\"two three\""]`},
{give: `"one,two,three"`, when: `(split ",")`, then: `["one","two","three"]`},
// (join)
{give: `{"x":["a","b","c"]}`, when: `(join "_" x)`, then: `"a_b_c"`},
{give: `["a","b","c"]`, when: `(join "_")`, then: `"a_b_c"`},
// (reverse)
{give: `[{"a":3},{"b":4}]`, when: `(reverse)`, then: `[{"b":4},{"a":3}]`},
{give: `[3,4,5,6,2,7]`, when: `(reverse)`, then: `[7,2,6,5,4,3]`},
// (sort)
{give: `[1, 10, 2]`, when: `(sort)`, then: `[1,2,10]`},
{give: `[1, 10, 2]`, when: `(sort desc)`, then: `[10,2,1]`},
{give: `{"c":1,"b":10,"a":2}`, when: `(sort)`, then: `{"a":2,"b":10,"c":1}`},
{give: `{"a":1,"b":10,"c":2}`, when: `(sort desc)`, then: `{"c":2,"b":10,"a":1}`},
{give: `[{"a":1},{"a":10},{"a":2}]`, when: `(sort desc a)`, then: `[{"a":10},{"a":2},{"a":1}]`},
{give: `[{"a":1},{"a":10},{"a":2}]`, when: `(sort a)`, then: `[{"a":1},{"a":2},{"a":10}]`},
// (either) should skip its arguments.
{give: `{"a":"","b":"B","c":""}`, when: `(get (either a b c) (lower))`, then: `"b"`},
// (either)
{give: `{"b":"B"}`, when: `(either a b c)`, then: `"B"`},
{give: `{"a":"","b":"","c":""}`, when: `(either a b c)`, then: `""`},
{give: `{"a":"A","b":"","c":"C"}`, when: `(either a b c)`, then: `"A"`},
{give: `{"a":"A","b":"B","c":""}`, when: `(either a b c)`, then: `"A"`},
{give: `{"a":"A","b":"","c":""}`, when: `(either a b c)`, then: `"A"`},
{give: `{"a":"","b":"","c":"C"}`, when: `(either a b c)`, then: `"C"`},
{give: `{"a":"","b":"B","c":""}`, when: `(either a b c)`, then: `"B"`},
{give: `{"a":"","b":"B","c":"C"}`, when: `(either a b c)`, then: `"B"`},
{give: `{"a":"A","b":"B","c":"C"}`, when: `(either a b c)`, then: `"A"`},
{give: `{"a":"","b":""}`, when: `(either a b)`, then: `""`},
{give: `{"a":"","b":"B"}`, when: `(either a b)`, then: `"B"`},
{give: `{"a":"A","b":""}`, when: `(either a b)`, then: `"A"`},
{give: `{"a":"A","b":"B"}`, when: `(either a b)`, then: `"A"`},
// (concat)
{give: `{"a":"x","b":3,"c":true,"d":null,"e":{},"f":[],"g":{"h": 4},"i":false}`, when: `(concat a b c d e f g i)`, then: `"x3truenullfalse"`},
{give: `{ "a": "hello" }`, when: `(concat a (raw " \"world\""))`, then: `"hello \"world\""`},
{give: `{ "a": "hello", "b": "world" }`, when: `(concat a (raw " ") b)`, then: `"hello world"`},
//(replace)
{give: `"a b"`, when: `(replace " " ")`, then: `"a"b"`}, // Invalid second param. This tests a crash protection.
{give: `"a b"`, when: `(replace " " "_")`, then: `"a_b"`},
// (upper)
{give: `"a"`, when: `(upper)`, then: `"A"`},
// (lower)
{give: `"A"`, when: `(lower)`, then: `"a"`},
// (stringify)
{give: `3`, when: `(stringify)`, then: `"3"`},
{give: `-3`, when: `(stringify)`, then: `"-3"`},
{give: `[]`, when: `(stringify)`, then: `"[]"`},
{give: `{}`, when: `(stringify)`, then: `"{}"`},
{give: `""`, when: `(stringify)`, then: `"\"\""`},
{give: `{"a":[{"b":3},4,"5"]}`, when: `(stringify)`, then: `"{\"a\":[{\"b\":3},4,\"5\"]}"`},
// (jsonify)
{give: `"{\"a\":[{\"b\":3},4,\"5\"]}"`, when: `(jsonify)`, then: `{"a":[{"b":3},4,"5"]}`},
{give: `"3"`, when: `(jsonify)`, then: `3`},
{give: `"{}"`, when: `(jsonify)`, then: `{}`},
// (bool)
{give: `{"a":3}`, when: `(bool b)`, then: `false`},
{give: `{"a":3}`, when: `(bool a)`, then: `true`},
{give: `3`, when: `(is-num) (bool)`, then: `true`},
{give: `{}`, when: `(is-num) (bool)`, then: `false`},
// (arr -t)
{give: `[{"a":3,"b":true},{"a":3,"b":3}]`, when: `(arr -t (and (is-num a) (is-bool b)))`, then: ``},
{give: `[{"a":3,"b":true},{"a":3,"b":true}]`, when: `(arr -t (and (is-num a) (is-bool b)))`, then: `[{"a":3,"b":true},{"a":3,"b":true}]`},
{give: `[3,4,3]`, when: `(arr -t (or (== 3) (== 5)))`, then: ``},
{give: `[3,4,3]`, when: `(arr -t (or (== 3) (== 4)))`, then: `[3,4,3]`},
{give: `[3,4,""]`, when: `(arr -t (or (is-num)))`, then: ``},
{give: `[3,4,5]`, when: `(arr -t (or (is-num)))`, then: `[3,4,5]`},
{give: `[3,4,5]`, when: `(arr -t (and (is-num) (is-num)))`, then: `[3,4,5]`},
{give: `[3,4,5]`, when: `(arr -t (and (is-num) (> 8)))`, then: ``},
{give: `[3,4,5]`, when: `(arr -t (and (is-num) (< 8)))`, then: `[3,4,5]`},
{give: `[3,4,""]`, when: `(arr -t (and (is-num)))`, then: ``},
{give: `[3,4,5]`, when: `(arr -t (and (is-num)))`, then: `[3,4,5]`},
// (or) (and) (not)
{give: `{"a":3,"b":4}`, when: `(not a)`, then: ``},
{give: `{"a":3,"b":4}`, when: `(and a b)`, then: `{"a":3,"b":4}`},
{give: `{"a":3,"b":4}`, when: `(and a x)`, then: ``},
{give: `{"a":3,"b":4}`, when: `(or x y b)`, then: `{"a":3,"b":4}`},
{give: `{"a":3,"b":4}`, when: `(or a x)`, then: `{"a":3,"b":4}`},
{give: `[3,"",4,"5"]`, when: `(collect (not (is-str)))`, then: `[3,4]`},
{give: `[{"a":3},{"a":4},{"a":5},{"a":6}]`, when: `(collect (or (< 4 a) (> 5 a)) a)`, then: `[3,6]`},
{give: `[{"a":3},{"a":4},{"a":5},{"a":6}]`, when: `(collect (and (>= 4 a) (<= 5 a)) a)`, then: `[4,5]`},
// (objectify)
{give: `[[1,3],[2,4]]`, when: `(objectify)`, then: `{"1":3,"2":4}`},
{give: `[["a",3],["b",4]]`, when: `(objectify)`, then: `{"a":3,"b":4}`},
// (entries)
{give: `{"a":3,"b":4}`, when: `(entries) (collect (flatten))`, then: `["a",3,"b",4]`},
{give: `{"a":3,"b":4}`, when: `(entries)`, then: `[["a",3],["b",4]]`},
//(values)
{give: `{"a":3,"b":4}`, when: `(values)`, then: `[3,4]`},
// (key)
{give: `{"a":3,"b":4}`, when: `(keys)`, then: `["a","b"]`},
// (if)
{give: `[3,4,5,6]`, when: `(iterate (key) (if (== 4) 7 (== 5) 8 (raw 9)))`, then: `[9,7,8,9]`},
{give: `[3,4,5,6]`, when: `(iterate (key) (if (== 4) 7 (== 5) 8))`, then: `[3,7,8,6]`},
{give: `[33,44]`, when: `(if -n (is-arr) "array" (raw "skip array"))`, then: `"skip array"`},
{give: `[33,44]`, when: `(if (not (is-arr)) "array" (raw "skip array"))`, then: `"skip array"`},
{give: `[33,44]`, when: `(if (is-arr) "array" (raw "not array"))`, then: `"array"`},
{give: `[33,44]`, when: `(if (is-arr) 4)`, then: `4`}, // Can omit Else.
{give: `{"b":3}`, when: `(if (is-num) 4)`, then: `{"b":3}`}, // Can omit Else.
{give: `{"a":""}`, when: `(get a (if (is-str) {} (raw 3)))`, then: `{}`}, // Then.
{give: `{"a":{"b":3}}`, when: `(get a (if (is-str) {} (this)))`, then: `{"b":3}`}, // Else.
{give: `3`, when: `(if (is-num) (obj b (this)) (raw 3))`, then: `{"b":3}`}, // Then.
{give: `3`, when: `(if (is-str) 4 (nothing))`, then: ``}, // Else.
// (is-void)
{give: `{"a":[]}`, when: `(is-void a)`, then: `{"a":[]}`},
{give: `{"a":[3]}`, when: `(is-void a)`, then: ``},
{give: `{}`, when: `(is-void)`, then: `{}`},
{give: `[]`, when: `(is-void)`, then: `[]`},
{give: `""`, when: `(is-void)`, then: ``},
// (is-blank)
{give: `{"a":null}`, when: `(is-blank a)`, then: `{"a":null}`},
{give: `{"a":3}`, when: `(is-blank a)`, then: ``},
{give: `{}`, when: `(is-blank)`, then: `{}`},
{give: `[]`, when: `(is-blank)`, then: `[]`},
{give: `null`, when: `(is-blank)`, then: `null`},
{give: `""`, when: `(is-blank)`, then: ``},
// (is-nully)
{give: `{"a":""}`, when: `(is-nully a)`, then: `{"a":""}`},
{give: `{"a":3}`, when: `(is-nully a)`, then: ``},
{give: `{}`, when: `(is-nully)`, then: `{}`},
{give: `[]`, when: `(is-nully)`, then: `[]`},
{give: `null`, when: `(is-nully)`, then: `null`},
{give: `""`, when: `(is-nully)`, then: `""`},
{give: `3`, when: `(is-nully)`, then: ``},
// (is-some)
{give: `{"a":0}`, when: `(is-some a)`, then: `{"a":0}`},
{give: `{"a":null}`, when: `(is-some a)`, then: ``},
{give: `3`, when: `(is-some)`, then: `3`},
{give: `""`, when: `(is-some)`, then: `""`},
{give: `null`, when: `(is-some)`, then: ``},
// (nothing) - Undocumented.
{give: `3`, when: `(nothing)`, then: ``},
// (exists)
{give: `{"a":3}`, when: `(exists a)`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(exists b)`, then: ``},
{give: `3`, when: `(exists)`, then: `3`},
{give: ``, when: `(exists)`, then: ``},
// (truthy)
{give: `{"a":1}`, when: `(truthy a)`, then: `{"a":1}`},
{give: `{"a":0}`, when: `(truthy a)`, then: ``},
{give: `{}`, when: `(truthy)`, then: ``},
{give: `[]`, when: `(truthy)`, then: ``},
{give: `0`, when: `(truthy)`, then: ``},
{give: `""`, when: `(truthy)`, then: ``},
{give: `null`, when: `(truthy)`, then: ``},
{give: `[0]`, when: `(truthy)`, then: `[0]`},
{give: `3`, when: `(truthy)`, then: `3`},
{give: `{"a":3}`, when: `(truthy)`, then: `{"a":3}`},
{give: `true`, when: `(truthy)`, then: `true`},
// (falsy)
{give: `{"a":0}`, when: `(falsy a)`, then: `{"a":0}`},
{give: `{"a":1}`, when: `(falsy a)`, then: ``},
{give: `{}`, when: `(falsy)`, then: `{}`},
{give: `[]`, when: `(falsy)`, then: `[]`},
{give: `0`, when: `(falsy)`, then: `0`},
{give: `""`, when: `(falsy)`, then: `""`},
{give: `false`, when: `(falsy)`, then: `false`},
{give: `[0]`, when: `(falsy)`, then: ``},
{give: `3`, when: `(falsy)`, then: ``},
{give: `null`, when: `(falsy)`, then: `null`},
// (is-empty-obj)
{give: `{"a":{}}`, when: `(is-empty-obj a)`, then: `{"a":{}}`},
{give: `{"a":{"b":3}}`, when: `(is-empty-obj a)`, then: ``},
{give: `{}`, when: `(is-empty-obj)`, then: `{}`},
{give: `{"a":3}`, when: `(is-empty-obj)`, then: ``},
{give: `[]`, when: `(is-empty-obj)`, then: ``},
// (is-empty-arr)
{give: `{"a":[]}`, when: `(is-empty-arr a)`, then: `{"a":[]}`},
{give: `{"a":[3]}`, when: `(is-empty-arr a)`, then: ``},
{give: `{}`, when: `(is-empty-arr)`, then: ``},
{give: `[0]`, when: `(is-empty-arr)`, then: ``},
{give: `[]`, when: `(is-empty-arr)`, then: `[]`},
// (is-empty-str)
{give: `{"a":""}`, when: `(is-empty-str a)`, then: `{"a":""}`},
{give: `{"a":"3"}`, when: `(is-empty-str a)`, then: ``},
{give: `3`, when: `(is-empty-str)`, then: ``},
{give: `""`, when: `(is-empty-str)`, then: `""`},
// (is-empty)
{give: `{"a":""}`, when: `(is-empty a)`, then: `{"a":""}`},
{give: `{"a":"3"}`, when: `(is-empty a)`, then: ``},
{give: `3`, when: `(is-empty)`, then: ``},
{give: `{}`, when: `(is-empty)`, then: `{}`},
{give: `[]`, when: `(is-empty)`, then: `[]`},
{give: `""`, when: `(is-empty)`, then: `""`},
// (is-null)
{give: `{"a":null}`, when: `(is-null a)`, then: `{"a":null}`},
{give: `{"a":3}`, when: `(is-null a)`, then: ``},
{give: `3`, when: `(is-null)`, then: ``},
{give: `null`, when: `(is-null)`, then: `null`},
// (is-bool)
{give: `{"a":false}`, when: `(is-bool a)`, then: `{"a":false}`},
{give: `{"a":true}`, when: `(is-bool a)`, then: `{"a":true}`},
{give: `{"a":3}`, when: `(is-bool a)`, then: ``},
{give: `3`, when: `(is-bool)`, then: ``},
{give: `true`, when: `(is-bool)`, then: `true`},
{give: `false`, when: `(is-bool)`, then: `false`},
// (is-str)
{give: `{"a":"3"}`, when: `(is-str a)`, then: `{"a":"3"}`},
{give: `{"a":3}`, when: `(is-str a)`, then: ``},
{give: `3`, when: `(is-str)`, then: ``},
{give: `"3"`, when: `(is-str)`, then: `"3"`},
// (is-arr)
{give: `{"a":[3]}`, when: `(is-arr a)`, then: `{"a":[3]}`},
{give: `{"a":3}`, when: `(is-arr a)`, then: ``},
{give: `3`, when: `(is-arr)`, then: ``},
{give: `[]`, when: `(is-arr)`, then: `[]`},
// (is-obj)
{give: `{"a":{"b":3}}`, when: `(is-obj a)`, then: `{"a":{"b":3}}`},
{give: `{"a":3}`, when: `(is-obj a)`, then: ``},
{give: `3`, when: `(is-obj)`, then: ``},
{give: `{}`, when: `(is-obj)`, then: `{}`},
// (is-num)
{give: `{"a":3}`, when: `(is-num a)`, then: `{"a":3}`},
{give: `{"a":"3"}`, when: `(is-num a)`, then: ``},
{give: `"3"`, when: `(is-num)`, then: ``},
{give: `3`, when: `(is-num)`, then: `3`},
// (ugly) (pretty)
{give: `[ { "a" : 3 , "b" : [ 4 , { "c" : 5, "d": "e f" } ], "c": [ ], "d": { } } ]`, when: `(pretty)`, then: "[\n {\n \"a\": 3,\n \"b\": [\n 4,\n {\n \"c\": 5,\n \"d\": \"e f\"\n }\n ],\n \"c\": [],\n \"d\": {}\n }\n]"},
{give: `[ { "a" : 3 , "b" : [ 4 , { "c" : 5, "d": "e f" } ], "c": [ ], "d": { } } ]`, when: `(ugly)`, then: `[{"a":3,"b":[4,{"c":5,"d":"e f"}],"c":[],"d":{}}]`},
// (==)
{give: `{"a":"3"}`, when: `(== 0 a)`, then: ``},
{give: `{"a":3}`, when: `(== 2 a)`, then: ``},
{give: `{"a":3}`, when: `(== 3 a)`, then: `{"a":3}`},
{give: `3`, when: `(== 2 (this))`, then: ``},
{give: `3`, when: `(== 3 (this))`, then: `3`},
{give: `3`, when: `(== 2)`, then: ``},
{give: `3`, when: `(== 3)`, then: `3`},
// (!=)
{give: `{"a":"3"}`, when: `(!= 0 a)`, then: `{"a":"3"}`},
{give: `{"a":3}`, when: `(!= 2 a)`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(!= 3 a)`, then: ``},
{give: `3`, when: `(!= 3 (this))`, then: ``},
{give: `3`, when: `(!= 2 (this))`, then: `3`},
{give: `3`, when: `(!= 3)`, then: ``},
{give: `3`, when: `(!= 2)`, then: `3`},
// (>=)
{give: `{"a":"3"}`, when: `(>= 0 a)`, then: ``},
{give: `"bear"`, when: `(>= "ant")`, then: `"bear"`},
{give: `"ant"`, when: `(>= "bear")`, then: ``},
{give: `{"a":3}`, when: `(>= 2 a)`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(>= 3 a)`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(>= 4 a)`, then: ``},
{give: `3`, when: `(>= 2 (this))`, then: `3`},
{give: `3`, when: `(>= 3 (this))`, then: `3`},
{give: `3`, when: `(>= 4 (this))`, then: ``},
{give: `3`, when: `(>= 2)`, then: `3`},
{give: `3`, when: `(>= 3)`, then: `3`},
{give: `3`, when: `(>= 4)`, then: ``},
// (<=)
{give: `{"a":"3"}`, when: `(<= 0 a)`, then: `{"a":"3"}`},
{give: `"bear"`, when: `(<= "ant")`, then: ``},
{give: `"ant"`, when: `(<= "bear")`, then: `"ant"`},
{give: `{"a":3}`, when: `(<= 2 a)`, then: ``},
{give: `{"a":3}`, when: `(<= 3 a)`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(<= 4 a)`, then: `{"a":3}`},
{give: `3`, when: `(<= 2 (this))`, then: ``},
{give: `3`, when: `(<= 3 (this))`, then: `3`},
{give: `3`, when: `(<= 4 (this))`, then: `3`},
{give: `3`, when: `(<= 2)`, then: ``},
{give: `3`, when: `(<= 3)`, then: `3`},
{give: `3`, when: `(<= 4)`, then: `3`},
// (>)
{give: `{"a":"3"}`, when: `(> 0 a)`, then: ``},
{give: `{"a":3}`, when: `(> 2 a)`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(> 3 a)`, then: ``},
{give: `3`, when: `(> 2 (this))`, then: `3`},
{give: `3`, when: `(> 3 (this))`, then: ``},
{give: `3`, when: `(> 2)`, then: `3`},
{give: `3`, when: `(> 3)`, then: ``},
// (<)
{give: `{"a":"3"}`, when: `(< 0 a)`, then: `{"a":"3"}`},
{give: `{"a":3}`, when: `(< 4 a)`, then: `{"a":3}`},
{give: `{"a":3}`, when: `(< 3 a)`, then: ``},
{give: `3`, when: `(< 4 (this))`, then: `3`},
{give: `3`, when: `(< 3 (this))`, then: ``},
{give: `3`, when: `(< 4)`, then: `3`},
{give: `3`, when: `(< 3)`, then: ``},
// (comparison)
{give: `[{"a":3,"b":6},{"a":4,"b":7},{"a":5,"b":8}]`, when: `(collect (== 7 b) a)`, then: `[4]`},
{give: `[{"a":3,"b":6},{"a":4,"b":7},{"a":5,"b":8}]`, when: `(collect (!= 7 b) a)`, then: `[3,5]`},
{give: `[{"a":3,"b":6},{"a":4,"b":7},{"a":5,"b":8}]`, when: `(collect (>= 7 b) a)`, then: `[4,5]`},
{give: `[{"a":3,"b":6},{"a":4,"b":7},{"a":5,"b":8}]`, when: `(collect (<= 7 b) a)`, then: `[3,4]`},
{give: `[{"a":3,"b":6},{"a":4,"b":7},{"a":5,"b":8}]`, when: `(collect (> 7 b) a)`, then: `[5]`},
{give: `[{"a":3,"b":11},{"a":4,"b":100},{"a":5,"b":8}]`, when: `(collect (< 77 b) a)`, then: `[3,5]`},
// (iterate -kv)
{give: "{ \"a\"\t:\t3\t}", when: `(iterate -kv (this))`, then: `{"a":3}`},
{give: `{ "a" : 3, "b": [ 3 , { "c": "d" } ] }`, when: `(iterate -kv (upper))`, then: `{"A":3,"B":[3,{"C":"D"}]}`},
{give: `{ "a": "b" }`, when: `(iterate -kv (upper))`, then: `{"A":"B"}`},
{give: `3`, when: `(iterate -kv (stringify))`, then: `"3"`},
{give: `3`, when: `(iterate -kv (this))`, then: `3`},
// (iterate -v)
{give: "{ \"a\"\t:\t3\t}", when: `(iterate -v (this))`, then: `{"a":3}`},
{give: `{ "a" : 3, "b": [ 3 , { "a" : 3 } ] }`, when: `(iterate -v (if (== 3) (raw 4) (this))))`, then: `{"a":4,"b":[4,{"a":4}]}`},
{give: `{ "a": 3 }`, when: `(iterate -v (if (== 3) (raw 4) (this)))`, then: `{"a":4}`},
{give: `3`, when: `(iterate -v (stringify))`, then: `"3"`},
{give: `3`, when: `(iterate -v (this))`, then: `3`},
// (iterate -k)
{give: "{ \"a\"\t:\t3\t}", when: `(iterate -k (this))`, then: `{"a":3}`},
{give: `{ "a" : 3 , "b" : [ 3, { "a": 3 } ] }`, when: `(iterate -k (if (== "a") (raw "x") (this))))`, then: `{"x":3,"b":[3,{"x":3}]}`},
{give: `{ "a" : 3 }`, when: `(iterate -k (if (== "a") (raw "x") (this)))`, then: `{"x":3}`},
{give: `3`, when: `(iterate -k (stringify))`, then: `3`},
{give: `3`, when: `(iterate -k (this))`, then: `3`},
// (iterate -f)
{give: "{ \"a\"\t:\t3\t}", when: `(iterate -f (key) (val))`, then: `{"a":3}`},
{give: "{ \"a\"\t:\t3\t}", when: `(iterate -f (this) (this))`, then: `{"a":3}`},
{give: `{ "a" : 3 , "b" : [ { "c" : 4 } , { "c" : 5 } ] , "d" : [ 6 , true ] }`, when: `(iterate -f (key) (if (is-num) (stringify) (val)))`, then: `{"a":"3","b":[{"c":"4"},{"c":"5"}],"d":["6",true]}`},
{give: `{ "a" : 3 , "b" : [ { "c" : 4 } , { "c" : 5 } ] , "d" : [ 6 , true ] }`, when: `(iterate -f (this) (if (is-num) (stringify) (this)))`, then: `{"a":"3","b":[{"c":"4"},{"c":"5"}],"d":["6",true]}`},
{give: `{ "a" : 3, "b" : 4}`, when: `(iterate -f (this) (if (is-num) (stringify) (this)))`, then: `{"a":"3","b":"4"}`},
{give: `[3,4]`, when: `(iterate -f (key) (if (is-num) (stringify) (val)))`, then: `["3","4"]`},
{give: `[3,4]`, when: `(iterate -f (this) (if (is-num) (stringify) (this)))`, then: `["3","4"]`},
{give: `["30"]`, when: `(iterate -f (this) (jsonify))`, then: `[30]`},
{give: `3`, when: `(iterate -f (this) (stringify))`, then: `"3"`},
{give: `3`, when: `(iterate -f (key) (val))`, then: `3`},
{give: `3`, when: `(iterate -f (this) (this))`, then: `3`},
// (default)
{give: `[{"b":3},{"c":4},{"b":5}]`, when: `(collect b (default 0))`, then: `[3,0,5]`},
// (size)
{give: `{"a":3,"b":4}`, when: `(size)`, then: `2`},
{give: `"abc"`, when: `(size)`, then: `3`},
{give: `[3,4]`, when: `(size)`, then: `2`},
// (merge)
{give: `[{"a":3},{"b":4}]`, when: `(merge)`, then: `{"a":3,"b":4}`},
// (flatten)
{give: `{"a":{}}`, when: `(flatten -k a)`, then: `{}`},
{give: `{"a":null}`, when: `(flatten -k a)`, then: `{"a":null}`},
{give: `[{"a":{"b":3}},{"a":{"b":4,"c":{"d":5}}}]`, when: `(flatten -k a)`, then: `[{"b":3},{"b":4,"c":{"d":5}}]`},
{give: `{"a":{"d":3,"e":4},"b":{"f":5},"c":{"g":6}}`, when: `(flatten -k a b)`, then: `{"d":3,"e":4,"f":5,"c":{"g":6}}`},
{give: `{"a":{},"c":{"d":{}},"f":5,"b":{"g":{"h":3,"i":{"l":7}},"j":5}}`, when: `(flatten)`, then: `{"f":5,"h":3,"l":7,"j":5}`},
{give: `{"a":[{"c":{"d":3,"e":{"k":6}},"f":5}],"b":{"g":{"h":3,"i":{"l":7}},"j":5}}`, when: `(flatten 0)`, then: `{"a":[{"c":{"d":3,"e":{"k":6}},"f":5}],"h":3,"l":7,"j":5}`},
{give: `{"a":{"c":{"d":3,"e":{"k":6}},"f":5},"b":{"g":{"h":3,"i":{"l":7}},"j":5}}`, when: `(flatten 3)`, then: `{"d":3,"k":6,"f":5,"h":3,"l":7,"j":5}`},
{give: `{"a":{"c":{"d":3,"e":{"k":6}},"f":5},"b":{"g":{"h":3,"i":{"l":7}},"j":5}}`, when: `(flatten 2)`, then: `{"d":3,"e":{"k":6},"f":5,"h":3,"i":{"l":7},"j":5}`},
{give: `{"a":{"c":{"d":3,"e":{"k":6}},"f":5},"b":{"g":{"h":3,"i":{"l":7}},"j":5}}`, when: `(flatten 1)`, then: `{"c":{"d":3,"e":{"k":6}},"f":5,"g":{"h":3,"i":{"l":7}},"j":5}`},
{give: `{"a":{"c":{"d":3,"e":{"k":6}},"f":5},"b":{"g":{"h":3,"i":{"l":7}},"j":5}}`, when: `(flatten 0)`, then: `{"d":3,"k":6,"f":5,"h":3,"l":7,"j":5}`},
{give: `{"a":{"c":{"d":3,"e":{"k":6}},"f":5},"b":{"g":{"h":3,"i":{"l":7}},"j":5}}`, when: `(flatten)`, then: `{"d":3,"k":6,"f":5,"h":3,"l":7,"j":5}`},
{give: `[ 3 , [ 4 , [ [ 5 ] ] ] , [ [ { "a" : [ [ 7 ] ] } ] ] , { "a" : [ [ 8 ] ] } ]`, when: `(flatten 0)`, then: `[3,4,5,{ "a" : [ [ 7 ] ] },{ "a" : [ [ 8 ] ] }]`},
{give: `[[],3,[4,[5]],[[[]],7],8,[]]`, when: `(flatten 0)`, then: `[3,4,5,7,8]`},
{give: `[3,[4,[5]],[[[6]],7],8]`, when: `(flatten 3)`, then: `[3,4,5,6,7,8]`},
{give: `[3,[4,[5]],[[[6]],7],8]`, when: `(flatten 2)`, then: `[3,4,5,[6],7,8]`},
{give: `[3,[4,[5]],[[[6]],7],8]`, when: `(flatten 1)`, then: `[3,4,[5],[[6]],7,8]`},
{give: `[3,[4,[5]],[[[6]],7],8]`, when: `(flatten 0)`, then: `[3,4,5,6,7,8]`},
{give: `[3,4]`, when: `(flatten 0)`, then: `[3,4]`},
{give: `[[3]]`, when: `(flatten)`, then: `[3]`},
{give: `[3]`, when: `(flatten)`, then: `3`},
{give: `3`, when: `(flatten)`, then: `3`},
// (first) (last)
{give: `{"a":[]}`, when: `a (last)`, then: ``},
{give: `{"a":[]}`, when: `(first a)`, then: ``},
{give: `{"a":[3,4,5]}`, when: `a (last)`, then: `5`},
{give: `{"a":[3,4,5]}`, when: `a (first)`, then: `3`},
{give: `[]`, when: `(last)`, then: ``},
{give: `[]`, when: `(first)`, then: ``},
{give: `{"a":[{"b":{"c":3}},{"b":{}}]}`, when: `a (last (== 3 (get b c)) b c)`, then: `3`},
{give: `{"a":[{"b":{"c":3}},{"b":{}}]}`, when: `a (first (== 3 (get b c)) b c)`, then: `3`},
{give: `{"a":[{"b":3},{"b":4}]}`, when: `a (last) b`, then: `4`},
{give: `{"a":[{"b":3},{"b":4}]}`, when: `a (first) b`, then: `3`},
{give: `[{"a":3,"b":1},{"a":4,"b":2},{"a":4,"b":3},{"a":5,"b":4}]`, when: `(last (== 4 a) b)`, then: `3`},
{give: `[{"a":3,"b":1},{"a":4,"b":2},{"a":4,"b":3},{"a":5,"b":4}]`, when: `(first (== 4 a) b)`, then: `2`},
{give: `[{"a":3,"b":1},{"a":4,"b":2},{"a":4,"b":3},{"a":5,"b":4}]`, when: `(last (== 4 a))`, then: `{"a":4,"b":3}`},
{give: `[{"a":3,"b":1},{"a":4,"b":2},{"a":4,"b":3},{"a":5,"b":4}]`, when: `(first (== 4 a))`, then: `{"a":4,"b":2}`},
{give: `[{"a":3,"b":1},{"a":4,"b":2},{"a":4,"b":3},{"a":5,"b":4}]`, when: `(last a)`, then: `5`},
{give: `[{"a":3,"b":1},{"a":4,"b":2},{"a":4,"b":3},{"a":5,"b":4}]`, when: `(first a)`, then: `3`},
{give: `[{"a":3,"b":1},{"a":4,"b":2},{"a":4,"b":3},{"a":5,"b":4}]`, when: `(last)`, then: `{"a":5,"b":4}`},
{give: `[{"a":3,"b":1},{"a":4,"b":2},{"a":4,"b":3},{"a":5,"b":4}]`, when: `(first)`, then: `{"a":3,"b":1}`},
// (arr)
{give: `{"a":3,"b":4}`, when: `(arr a b a (raw "hi"))`, then: `[3,4,3,"hi"]`},
{give: `{"a":3,"b":4}`, when: `(arr a b c)`, then: `[3,4]`},
{give: `{"a":3,"b":4}`, when: `(arr a b a)`, then: `[3,4,3]`},
{give: `{"a":3,"b":4}`, when: `(arr (get a) (get b) (get a))`, then: `[3,4,3]`},
{give: ``, when: `(arr)`, then: `[]`},
// (obj)
{give: `{"a":3,"b":4}`, when: `(obj -i (concat (raw "key_") (key)) (this))`, then: `{"key_a":3,"key_b":4}`},
{give: `{"a":3,"b":4}`, when: `(obj -i (concat (raw "key_") (key)) (val))`, then: `{"key_a":3,"key_b":4}`},
{give: `[{"a":3,"b":30},{"a":4,"b":40}]`, when: `(obj -i (get a) (val))`, then: `{"3":{"a":3,"b":30},"4":{"a":4,"b":40}}`},
{give: `{"a":3}`, when: `(obj (raw 4) a)`, then: `{"4":3}`},
{give: `{"a":3}`, when: `(obj "4" a)`, then: `{"4":3}`},
{give: `{"a":3}`, when: `(obj 4 a)`, then: `{"4":3}`},
{give: `{"a":3}`, when: `(obj (nothing) a)`, then: `{}`},
{give: `{"a":3}`, when: `(obj x (nothing))`, then: `{}`},
{give: `{"a":"aaa","b":"bbb"}`, when: `(obj (get a) (get b))`, then: `{"aaa":"bbb"}`},
{give: `{"a":3,"b":4}`, when: `(obj "a b" a y b)`, then: `{"a b":3,"y":4}`},
{give: `{"a":3,"b":4}`, when: `(obj "a b" (get a) y (get b))`, then: `{"a b":3,"y":4}`},
{give: `{"a":3,"b":4}`, when: `(obj x (get a) y (get b))`, then: `{"x":3,"y":4}`},
{give: `{"a":{"b":{"c":3}}}`, when: `(get a b (obj x c))`, then: `{"x":3}`},
// (get *)
{give: `[{"a":[{"a":3},{"a":4}]},{"a":[{"a":5},{"a":6}]}]`, when: `(get * a (get * a) (flatten))`, then: `[3,4,5,6]`},
{give: `[{"1":[{"1":3},{"1":4}]},{"1":[{"1":5},{"1":6}]}]`, when: `(get 1 1 1 1)`, then: `6`},
{give: `[{"1":[{"1":3},{"1":4}]},{"1":[{"1":5},{"1":6}]}]`, when: `(get * 1 * 1)`, then: `[[3,4],[5,6]]`},
{give: `[{"*":[{"*":3},{"*":4}]},{"*":[{"*":5},{"*":6}]}]`, when: `(get * "*" * "*")`, then: `[[3,4],[5,6]]`},
{give: `[{"a":[{"a":3},{"a":4}]},{"a":[{"a":5},{"a":6}]}]`, when: `(get * a * a)`, then: `[[3,4],[5,6]]`},
{
give: `{"a":{"b":{"c":[{"d":"one","e":{"f":[{"g":{"h":{"i":{"j":[{"k":{"l":3}},{"k":{"l":4}}]}}}}]}},{"d":"two","e":{"f":[{"g":{"h":{"i":{"j":[{"k":{"l":5}}]}}}}]}}]}}}`,
when: `(get a b c * (obj x d e (get e f * g h i j (get * k l) (flatten)))))`,
then: `[{"x":"one","e":[3,4]},{"x":"two","e":[5]}]`,
},
{give: `[3,4,5]`, when: `(get *)`, then: `[3,4,5]`},
{give: `[{"a":3}]`, when: `(get * a)`, then: `[3]`},
{give: ``, when: `(get *)`, then: `[]`},
{give: `3`, when: `(get *)`, then: `[]`},
{give: `[]`, when: `(get * a)`, then: `[]`},
{give: `[]`, when: `(get *)`, then: `[]`},
{give: `[{"b":{"c":3}},{"b":{}}]`, when: `(get * b c)`, then: `[3]`},
{give: `[{"a":3},{"b":4},{"a":5}]`, when: `(get * a)`, then: `[3,5]`},
// (get) order should not matter.
{give: `{"a":3,"b":4]}`, when: `(obj x b y a z a w b)`, then: `{"x":4,"y":3,"z":3,"w":4}`},
// (get)
{give: `{"a":[{"b":3},{"c":4}]}`, when: `(get a 1 c)`, then: `4`},
{give: `{"a":[{"b":3},{"c":4}]}`, when: `(get a 0 b)`, then: `3`},
{give: `[{"a":3},{"a":4}]`, when: `(get 0 a)`, then: `3`},
{give: `[2,3,4]`, when: `(get 3)`, then: ``},
{give: `[2,3,4]`, when: `(get 2)`, then: `4`},
{give: `[2,3,4]`, when: `(get 1)`, then: `3`},
{give: `[2,3,4]`, when: `(get 0)`, then: `2`},
{give: `{"aa":{"bb":{"cc":3}}}`, when: `(get aa bb cc)`, then: `3`},
{give: `{"a b":{"c d":3}}`, when: `(get "a b" "c d")`, then: `3`},
{give: `{"a b":3}`, when: `(get "a b")`, then: `3`},
{give: `{"a":{"b":3}}`, when: `(get a b)`, then: `3`},
{give: `{"a":3}`, when: `(get a)`, then: `3`},
// (root)
{give: `3`, when: `(root)`, then: `3`},
{give: ``, when: `(root)`, then: ``},
// (raw)
{give: ``, when: `(raw [ 3, 4 ])`, then: `[ 3, 4 ]`},
{give: ``, when: `(raw { "a b": "c d" })`, then: `{ "a b": "c d" }`},
{give: ``, when: `(raw {})`, then: `{}`},
{give: ``, when: `(raw [])`, then: `[]`},
{give: ``, when: `(raw null)`, then: `null`},
{give: ``, when: `(raw true)`, then: `true`},
{give: ``, when: `(raw false)`, then: `false`},
{give: ``, when: `(raw 3e2)`, then: `3e2`},
{give: ``, when: `(raw 3)`, then: `3`},
{give: ``, when: `(raw "a b")`, then: `"a b"`},
{give: ``, when: `(raw "a")`, then: `"a"`},
{give: ``, when: `(raw -3)`, then: `-3`},
{give: ``, when: `(raw 1.2)`, then: `1.2`},
}
for _, tc := range tt {
r := Get(tc.give, tc.when)
assertEqual(t, tc.then, r.String(), tc)
}
}
func Test_Invalid_Query(t *testing.T) {
tt := []struct {
give string
when string
then string
}{
{give: `[3,4]`, when: `(collect (this)`, then: `[3,4]`},
}
for _, tc := range tt {
r := Get(tc.give, tc.when)
assertEqual(t, tc.then, r.String(), tc)
}
}
func TestGetWith(t *testing.T) {
tt := []struct {
give string
when string
args []any
then string
}{
{
give: ``,
when: `(obj a (arg 0) b (arg 1) c (arg 2) d (arg 3) e (arg 4))`,
args: []any{"Hello \"World\"", 4, float32(1.2), float64(1.5), []any{3, "4"}},
then: `{"a":"Hello \"World\"","b":4,"c":1.2,"d":1.5,"e":[3,"4"]}`,
},
{
give: `3`,
when: `(obj a (arg 0))`,
args: []any{func(j Json) Json { return j.Stringify() }},
then: `{"a":"3"}`,
},
}
for _, tc := range tt {
r := GetWith(tc.give, tc.when, tc.args)
assertEqual(t, tc.then, r.String(), tc)
}
}
func BenchmarkGetWith(b *testing.B) {
a := []any{3}
for i := 0; i < b.N; i++ {
_ = GetWith("", "(arg 0)", a)
}
}
func TestValid(t *testing.T) {
tt := []struct {
give string
then bool
}{
{give: `{"a":3}`, then: true},
{give: `{"a":3,}`, then: false},
}
for _, tc := range tt {
ok := Valid(tc.give)
assertEqual(t, tc.then, ok, tc)
}
}
func BenchmarkValid(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Valid(TestData1)
}
}
func TestJsonWS(t *testing.T) {
tt := []struct {
give string
when string
then string
}{
{give: ` {"a":3,"b":4}`, when: `(pick b)`, then: `{"b":4}`},
{give: ` { "a" : 3, "b" : [ { "c" : 4 } ] }`, when: `(get b 0 c)`, then: `4`},
{give: `[3,4 ]`, when: `(get 1)`, then: `4`},
{give: `[3, 4]`, when: `(get 1)`, then: `4`},
{give: `[3 ,4]`, when: `(get 1)`, then: `4`},
{give: `[ 3,4]`, when: `(get 1)`, then: `4`},
{give: `{"a":3, "b":4}`, when: `(get b)`, then: `4`},
{give: `{"a":3 ,"b":4}`, when: `(get a)`, then: `3`},
{give: `{"a": 3}`, when: `(get a)`, then: `3`},
{give: `{"a" :3}`, when: `(get a)`, then: `3`},
{give: `{ "a":3}`, when: `(get a)`, then: `3`},
}
for _, tc := range tt {
r := Get(tc.give, tc.when)
assertEqual(t, tc.then, r.String(), tc)
}
}
func TestJsonBytes(t *testing.T) {
tt := []struct {
give string
then []byte
}{
{give: `[3,4]`, then: []byte{'[', '3', ',', '4', ']'}},
}
for _, tc := range tt {
r := Get(tc.give, `(this)`).Bytes()
assertEqual(t, tc.then, r, tc)
}
}
func TestJsonGet(t *testing.T) {
tt := []struct {
give string
when string
then string
}{
{give: `{"a":2,"b":3}`, when: `a`, then: `2`},
{give: `{"a":2,"b":3}`, when: `b`, then: `3`},
{give: `{"a":2,"b":3}`, when: `c`, then: ``},
{give: `{"a":[2,3]}`, when: `a`, then: `[2,3]`},
{give: `[2,3]`, when: `0`, then: `2`},
{give: `[2,3]`, when: `1`, then: `3`},
{give: `[2,3]`, when: `2`, then: ``},
{give: `{"a":{"b":2}}`, when: `a`, then: `{"b":2}`},
}
for _, tc := range tt {
j := JSON(tc.give)
r := j.Get(tc.when)
assertEqual(t, tc.then, r.String(), tc)
}
}
func BenchmarkJson_Get(b *testing.B) {
j := JSON(TestData1)
for i := 0; i < b.N; i++ {
_ = j.Get("age")
}
}
func TestJsonGet_Order(t *testing.T) {
j := JSON(`{"a":3,"b":4}`)
assertEqual(t, "4", j.Get("b").String())
assertEqual(t, "3", j.Get("a").String())
j = JSON(`[3,4]`)
assertEqual(t, "4", j.Get("1").String())
assertEqual(t, "3", j.Get("0").String())
}
func TestJsonForEachKeyVal(t *testing.T) {
tt := []struct {
give string
then []string
}{
{give: `{}`, then: nil},
{give: `{"a":2}`, then: []string{"a", "2"}},
{give: `{"a":2,"b":3}`, then: []string{"a", "2", "b", "3"}},
{give: `{"a":{"b":2}}`, then: []string{"a", `{"b":2}`}},
{give: `{"a":[2]}`, then: []string{"a", "[2]"}},
}
for _, tc := range tt {
var r []string
j := JSON(tc.give)
j.ForEachKeyVal(func(k, v Json) bool {
r = append(r, k.Str(), v.String())
return false
})
assertEqual(t, tc.then, r, tc.give)
}
}
func TestJsonForEach(t *testing.T) {
tt := []struct {
give string
then []string
}{
{give: "[]", then: nil},
{give: "[10]", then: []string{"0", "10"}},
{give: "[10,20]", then: []string{"0", "10", "1", "20"}},
{give: "[10,20,30]", then: []string{"0", "10", "1", "20", "2", "30"}},
{give: "[{},{},[10]]", then: []string{"0", "{}", "1", "{}", "2", "[10]"}},
}
for _, tc := range tt {
var r []string
j := JSON(tc.give)
j.ForEach(func(i, v Json) bool {
r = append(r, i.String(), v.String())
return false
})
assertEqual(t, tc.then, r, tc.give)
}
}
func TestJsonStr(t *testing.T) {
tt := []struct {
give string
then string
}{
{give: ``, then: ``},
{give: `""`, then: ``},
{give: `"a"`, then: `a`},
{give: `"\"a\""`, then: `"a"`},
}
for _, tc := range tt {
j := JSON(tc.give)
assertEqual(t, tc.then, j.Str(), tc.give)
}
}
func TestJsonInt(t *testing.T) {
tt := []struct {
give string
then int
}{
{give: ``, then: 0},
{give: `0`, then: 0},
{give: `1`, then: 1},
{give: `-2`, then: -2},
{give: `100`, then: 100},
}
for _, tc := range tt {
j := JSON(tc.give)
assertEqual(t, tc.then, j.Int(), tc.give)
}
}
func TestJsonInt64(t *testing.T) {
tt := []struct {
give string
then int64
}{
{give: ``, then: 0},
{give: `0`, then: 0},
{give: `1`, then: 1},
{give: `-2`, then: -2},
{give: `100`, then: 100},
}
for _, tc := range tt {
j := JSON(tc.give)