OILS / spec / ysh-json.test.sh View on Github | oilshell.org

1251 lines, 296 significant
1## oils_failures_allowed: 1
2## tags: dev-minimal
3
4#### usage errors
5
6json read zz
7echo status=$?
8
9json write
10
11## status: 3
12## STDOUT:
13status=2
14## END
15
16#### json write STRING
17shopt --set parse_proc
18
19json write ('foo')
20var s = 'foo'
21json write (s)
22## STDOUT:
23"foo"
24"foo"
25## END
26
27#### json write ARRAY
28json write (:|foo.cc foo.h|)
29json write (['foo.cc', 'foo.h'], space=0)
30## STDOUT:
31[
32 "foo.cc",
33 "foo.h"
34]
35["foo.cc","foo.h"]
36## END
37
38#### json write Dict
39json write ({k: 'v', k2: [4, 5]})
40
41json write ([{k: 'v', k2: 'v2'}, {}])
42
43## STDOUT:
44{
45 "k": "v",
46 "k2": [
47 4,
48 5
49 ]
50}
51[
52 {
53 "k": "v",
54 "k2": "v2"
55 },
56 {}
57]
58## END
59
60#### json write space=0, space=4
61shopt --set parse_proc
62
63var mydict = {name: "bob", age: 30}
64
65json write (mydict, space=0)
66json write (mydict, space=4)
67## STDOUT:
68{"name":"bob","age":30}
69{
70 "name": "bob",
71 "age": 30
72}
73## END
74
75#### json write in command sub
76shopt -s oil:all # for echo
77var mydict = {name: "bob", age: 30}
78json write (mydict)
79var x = $(json write (mydict))
80echo $x
81## STDOUT:
82{
83 "name": "bob",
84 "age": 30
85}
86{
87 "name": "bob",
88 "age": 30
89}
90## END
91
92#### json read passed invalid args
93
94# EOF
95json read
96echo status=$?
97
98json read 'z z'
99echo status=$?
100
101json read a b c
102echo status=$?
103
104## STDOUT:
105status=1
106status=2
107status=2
108## END
109
110#### json read uses $_reply var
111
112# space before true
113echo ' true' | json read
114json write (_reply)
115
116## STDOUT:
117true
118## END
119
120#### json read then json write
121
122# BUG with space before true
123echo '{"name": "bob", "age": 42, "ok": true}' | json read
124json write (_reply)
125
126echo '{"name": "bob", "age": 42, "ok":true}' | json read
127json write (_reply)
128
129echo '{"name": {}, "age": {}, "x":-1, "y": -0}' | json read
130json write (_reply)
131
132## STDOUT:
133{
134 "name": "bob",
135 "age": 42,
136 "ok": true
137}
138{
139 "name": "bob",
140 "age": 42,
141 "ok": true
142}
143{
144 "name": {},
145 "age": {},
146 "x": -1,
147 "y": 0
148}
149## END
150
151#### json read with redirect
152echo '{"age": 42}' > $TMP/foo.txt
153json read (&x) < $TMP/foo.txt
154pp cell_ x
155## STDOUT:
156x = (Cell exported:F readonly:F nameref:F val:(value.Dict d:[Dict age (value.Int i:42)]))
157## END
158
159#### json read at end of pipeline (relies on lastpipe)
160echo '{"age": 43}' | json read (&y)
161pp cell_ y
162## STDOUT:
163y = (Cell exported:F readonly:F nameref:F val:(value.Dict d:[Dict age (value.Int i:43)]))
164## END
165
166#### invalid JSON
167echo '{' | json read (&y)
168echo pipeline status = $?
169pp test_ (y)
170## status: 1
171## STDOUT:
172pipeline status = 1
173## END
174
175#### Extra data after valid JSON
176
177# Trailing space is OK
178echo '42 ' | json read
179echo num space $?
180
181echo '{} ' | json read
182echo obj space $?
183
184echo '42 # comment' | json8 read
185echo num comment $?
186
187echo '{} # comment ' | json8 read
188echo obj comment $?
189
190echo '42]' | json read
191echo num bracket $?
192
193echo '{}]' | json read
194echo obj bracket $?
195
196## STDOUT:
197num space 0
198obj space 0
199num comment 0
200obj comment 0
201num bracket 1
202obj bracket 1
203## END
204
205#### json write expression
206json write ([1,2,3], space=0)
207echo status=$?
208
209json write (5, 6) # to many args
210echo status=$?
211
212## status: 3
213## STDOUT:
214[1,2,3]
215status=0
216## END
217
218#### json write evaluation error
219
220#var block = ^(echo hi)
221#json write (block)
222#echo status=$?
223
224# undefined var
225json write (a)
226echo 'should have failed'
227
228## status: 1
229## STDOUT:
230## END
231
232#### json write of List in cycle
233
234var L = [1, 2, 3]
235setvar L[0] = L
236pp test_ (L)
237
238json write (L)
239echo status=$?
240
241## status: 0
242## STDOUT:
243(List) [[...],2,3]
244status=1
245## END
246
247#### json write of Dict in cycle
248
249var d = {}
250setvar d.k = d
251
252pp test_ (d)
253
254json write (d)
255echo status=$?
256
257## STDOUT:
258(Dict) {"k":{...}}
259status=1
260## END
261
262#### json write of List/Dict referenced twice (bug fix)
263
264var mylist = [1,2,3]
265var mydict = {foo: "bar"}
266
267var top = {k: mylist, k2: mylist, k3: mydict, k4: mydict}
268
269# BUG!
270json write (top, space=0)
271
272## STDOUT:
273{"k":[1,2,3],"k2":[1,2,3],"k3":{"foo":"bar"},"k4":{"foo":"bar"}}
274## END
275
276#### json read doesn't accept u'' or b'' strings
277
278json read <<EOF
279{"key": u'val'}
280EOF
281echo status=$?
282
283#pp test_ (_reply)
284
285json read <<EOF
286{"key": b'val'}
287EOF
288echo status=$?
289
290## STDOUT:
291status=1
292status=1
293## END
294
295#### json read doesn't accept comments, but json8 does
296
297json8 read <<EOF
298{ # comment
299 "key": # zz
300 b'val', # yy
301 "k2": "v2" #
302}
303EOF
304echo status=$?
305
306json8 write (_reply)
307
308json read <<EOF
309{"key": "val"} # comment
310EOF
311echo status=$?
312## STDOUT:
313status=0
314{
315 "key": "val",
316 "k2": "v2"
317}
318status=1
319## END
320
321
322#### json write emits Unicode replacement char for binary data \yff
323
324json write ([3, "foo", $'-\xff\xfe---\xfd=']) > tmp.txt
325
326# Round trip it for good measure
327json read < tmp.txt
328
329json write (_reply)
330
331## STDOUT:
332[
333 3,
334 "foo",
335 "-��---�="
336]
337## END
338
339#### json8 accepts j"" prefix, but json doesn't
340
341var msg = r'j"foo\nbar"'
342
343echo "$msg" | json read
344echo json=$?
345echo
346
347echo "$msg" | json8 read
348echo json8=$?
349pp test_ (_reply)
350echo
351
352var msg = r'j"\u0041"'
353echo "$msg" | json8 read
354echo json8=$?
355pp test_ (_reply)
356
357
358## STDOUT:
359json=1
360
361json8=0
362(Str) "foo\nbar"
363
364json8=0
365(Str) "A"
366## END
367
368#### j"" prefix not accepted in YSH (could be added later)
369
370shopt -s ysh:all
371
372# denied by YSH
373# echo j"\u{7f}"
374
375var s = j"\u{7f}"
376
377## status: 2
378## STDOUT:
379## END
380
381
382#### json8 write emits b'' strings for binary data \yff
383
384json8 write ([3, "foo", $'-\xff\xfe-\xfd='])
385
386## STDOUT:
387[
388 3,
389 "foo",
390 b'-\yff\yfe-\yfd='
391]
392## END
393
394
395#### json8 write bytes vs unicode string
396
397u=$'mu \u03bc \x01 \" \\ \b\f\n\r\t'
398u2=$'\x01\x1f' # this is a valid unicode string
399
400b=$'\xff' # this isn't valid unicode
401
402json8 write (u)
403json8 write (u2)
404
405json8 write (b)
406
407## STDOUT:
408"mu μ \u0001 \" \\ \b\f\n\r\t"
409"\u0001\u001f"
410b'\yff'
411## END
412
413#### JSON \/ escapes supported
414
415msg='"\/"'
416
417echo "$msg" | python3 -c 'import json, sys; print(json.load(sys.stdin))'
418
419echo "$msg" | json read
420echo reply=$_reply
421
422j8="b'\\/'"
423echo "$msg" | json read
424echo reply=$_reply
425
426
427## STDOUT:
428/
429reply=/
430reply=/
431## END
432
433#### JSON string can have unescaped ' and J8 string can have unescaped "
434
435json read <<EOF
436"'"
437EOF
438
439pp test_ (_reply)
440
441json8 read <<EOF
442u'"'
443EOF
444
445pp test_ (_reply)
446
447## STDOUT:
448(Str) "'"
449(Str) "\""
450## END
451
452
453#### J8 supports superfluous \" escapes, but JSON doesn't support \' escapes
454
455json8 read <<'EOF'
456b'\"'
457EOF
458echo reply=$_reply
459
460json8 read <<'EOF'
461b'\'\'\b\f\n\r\t\"\\'
462EOF
463pp test_ (_reply)
464
465# Suppress traceback
466python3 -c 'import json, sys; print(json.load(sys.stdin))' 2>/dev/null <<'EOF'
467"\'"
468EOF
469echo python3=$?
470
471json read <<'EOF'
472"\'"
473EOF
474echo json=$?
475
476## STDOUT:
477reply="
478(Str) "''\b\f\n\r\t\"\\"
479python3=1
480json=1
481## END
482
483#### Escaping uses \u0001 in "", but \u{1} in b''
484
485s1=$'\x01'
486s2=$'\x01\xff\x1f' # byte string
487
488json8 write (s1)
489json8 write (s2)
490
491## STDOUT:
492"\u0001"
493b'\u{1}\yff\u{1f}'
494## END
495
496
497#### json8 read
498
499echo '{ }' | json8 read
500pp test_ (_reply)
501
502echo '[ ]' | json8 read
503pp test_ (_reply)
504
505echo '[42]' | json8 read
506pp test_ (_reply)
507
508echo '[true, false]' | json8 read
509pp test_ (_reply)
510
511echo '{"k": "v"}' | json8 read
512pp test_ (_reply)
513
514echo '{"k": null}' | json8 read
515pp test_ (_reply)
516
517echo '{"k": 1, "k2": 2}' | json8 read
518pp test_ (_reply)
519
520echo "{u'k': {b'k2': null}}" | json8 read
521pp test_ (_reply)
522
523echo '{"k": {"k2": "v2"}, "k3": "backslash \\ \" \n line 2 \u03bc "}' | json8 read
524pp test_ (_reply)
525
526json8 read (&x) <<'EOF'
527{u'k': {u'k2': u'v2'}, u'k3': u'backslash \\ \" \n line 2 \u{3bc} '}
528EOF
529pp test_ (x)
530
531## STDOUT:
532(Dict) {}
533(List) []
534(List) [42]
535(List) [true,false]
536(Dict) {"k":"v"}
537(Dict) {"k":null}
538(Dict) {"k":1,"k2":2}
539(Dict) {"k":{"k2":null}}
540(Dict) {"k":{"k2":"v2"},"k3":"backslash \\ \" \n line 2 μ "}
541(Dict) {"k":{"k2":"v2"},"k3":"backslash \\ \" \n line 2 μ "}
542## END
543
544#### json8 round trip
545
546var obj = [42, 1.5, null, true, "hi", b'\yff\yfe\b\n""']
547
548json8 write (obj, space=0) > j
549
550cat j
551
552json8 read < j
553
554json8 write (_reply)
555
556## STDOUT:
557[42,1.5,null,true,"hi",b'\yff\yfe\b\n""']
558[
559 42,
560 1.5,
561 null,
562 true,
563 "hi",
564 b'\yff\yfe\b\n""'
565]
566## END
567
568#### json round trip (regression)
569
570var d = {
571 short: '-v', long: '--verbose', type: null, default: '', help: 'Enable verbose logging'
572}
573
574json write (d) | json read
575
576pp test_ (_reply)
577
578## STDOUT:
579(Dict) {"short":"-v","long":"--verbose","type":null,"default":"","help":"Enable verbose logging"}
580## END
581
582#### round trip: decode surrogate pair and encode
583
584var j = r'"\ud83e\udd26"'
585echo $j | json read (&c1)
586
587json write (c1)
588
589var j = r'"\uD83E\uDD26"'
590echo $j | json read (&c2)
591
592json write (c2)
593
594# Not a surrogate pair
595var j = r'"\u0001\u0002"'
596echo $j | json read (&c3)
597
598json write (c3)
599
600var j = r'"\u0100\u0101\u0102"'
601echo $j | json read (&c4)
602
603json write (c4)
604
605## STDOUT:
606"🤦"
607"🤦"
608"\u0001\u0002"
609"ĀāĂ"
610## END
611
612#### round trip: decode surrogate half and encode
613
614shopt -s ysh:upgrade
615
616for j in '"\ud83e"' '"\udd26"' {
617 var s = fromJson(j)
618 write -- "$j"
619 pp test_ (s)
620
621 write -n 'json '; json write (s)
622
623 write -n 'json8 '; json8 write (s)
624
625 echo
626}
627
628## STDOUT:
629"\ud83e"
630(Str) b'\yed\ya0\ybe'
631json "\ud83e"
632json8 b'\yed\ya0\ybe'
633
634"\udd26"
635(Str) b'\yed\yb4\ya6'
636json "\udd26"
637json8 b'\yed\yb4\ya6'
638
639## END
640
641#### toJson() toJson8()
642
643var obj = [42, 1.5, null, true, "hi", b'\yf0']
644
645echo $[toJson(obj)]
646echo $[toJson8(obj)]
647
648var obj2 = [3, 4]
649echo $[toJson(obj2, space=0)] # same as the default
650echo $[toJson8(obj2, space=0)]
651
652echo $[toJson(obj2, space=2)]
653echo $[toJson8(obj2, space=2)]
654
655# fully specify this behavior
656echo $[toJson(obj2, space=-2)]
657echo $[toJson8(obj2, space=-2)]
658
659## STDOUT:
660[42,1.5,null,true,"hi",""]
661[42,1.5,null,true,"hi",b'\yf0']
662[3,4]
663[3,4]
664[
665 3,
666 4
667]
668[
669 3,
670 4
671]
672[3,4]
673[3,4]
674## END
675
676#### fromJson() fromJson8()
677
678var m1 = '[42,1.5,null,true,"hi"]'
679
680# JSON8 message
681var m2 = '[42,1.5,null,true,"hi",' ++ "u''" ++ ']'
682
683pp test_ (fromJson8(m1))
684pp test_ (fromJson(m1))
685
686pp test_ (fromJson8(m2))
687pp test_ (fromJson(m2)) # fails
688
689## status: 4
690## STDOUT:
691(List) [42,1.5,null,true,"hi"]
692(List) [42,1.5,null,true,"hi"]
693(List) [42,1.5,null,true,"hi",""]
694## END
695
696#### User can handle errors - toJson() toJson8()
697shopt -s ysh:upgrade
698
699var obj = []
700call obj->append(obj)
701
702try {
703 echo $[toJson(obj)]
704}
705echo status=$_status
706echo "encode error $[_error.message]" | sed 's/0x[a-f0-9]\+/(object id)/'
707
708try { # use different style
709 echo $[toJson8( /d+/ )]
710}
711echo status=$_status
712echo "encode error $[_error.message]"
713
714# This makes the interpreter fail with a message
715echo $[toJson(obj)]
716
717## status: 4
718## STDOUT:
719status=4
720encode error Can't encode List (object id) in object cycle
721status=4
722encode error Can't serialize object of type Eggex
723## END
724
725#### User can handle errors - fromJson() fromJson8()
726shopt -s ysh:upgrade
727
728var message ='[42,1.5,null,true,"hi"'
729
730try {
731 var obj = fromJson(message)
732}
733echo status=$_status
734echo "decode error $[_error.message]" | egrep -o '.*Expected.*RBracket'
735
736try {
737 var obj = fromJson8(message)
738}
739echo status=$_status
740echo "decode error $[_error.message]" | egrep -o '.*Expected.*RBracket'
741
742try {
743 var obj = fromJson('[+]')
744}
745echo "positions $[_error.start_pos] - $[_error.end_pos]"
746
747# This makes the interpreter fail with a message
748var obj = fromJson(message)
749
750## status: 4
751## STDOUT:
752status=4
753decode error Expected Id.J8_RBracket
754status=4
755decode error Expected Id.J8_RBracket
756positions 1 - 2
757## END
758
759
760#### ASCII control chars can't appear literally in messages
761shopt -s ysh:upgrade
762
763var message=$'"\x01"'
764#echo $message | od -c
765
766try {
767 var obj = fromJson(message)
768}
769echo status=$_status
770echo "$[_error.message]" | egrep -o 'ASCII control chars'
771
772## STDOUT:
773status=4
774ASCII control chars
775## END
776
777
778#### \yff can't appear in u'' code strings (command)
779
780shopt -s ysh:upgrade
781
782echo -n b'\yfd' | od -A n -t x1
783echo -n u'\yfd' | od -A n -t x1
784
785## status: 2
786## STDOUT:
787 fd
788## END
789
790#### \yff can't appear in u'' code strings (expr)
791
792var x = b'\yfe'
793write -n -- $x | od -A n -t x1
794
795var x = u'\yfe'
796write -n -- $x | od -A n -t x1
797
798## status: 2
799## STDOUT:
800 fe
801## END
802
803#### \yff can't appear in u'' multiline code strings
804
805shopt -s ysh:upgrade
806
807echo -n b'''\yfc''' | od -A n -t x1
808echo -n u'''\yfd''' | od -A n -t x1
809
810## status: 2
811## STDOUT:
812 fc
813## END
814
815#### \yff can't appear in u'' data strings
816
817#shopt -s ysh:upgrade
818
819json8 read (&b) <<'EOF'
820b'\yfe'
821EOF
822pp test_ (b)
823
824json8 read (&u) <<'EOF'
825u'\yfe'
826EOF
827pp test_ (u) # undefined
828
829## status: 1
830## STDOUT:
831(Str) b'\yfe'
832## END
833
834#### \u{dc00} can't be in surrogate range in code (command)
835
836shopt -s ysh:upgrade
837
838echo -n u'\u{dc00}' | od -A n -t x1
839
840## status: 2
841## STDOUT:
842## END
843
844#### \u{dc00} can't be in surrogate range in code (expr)
845
846shopt -s ysh:upgrade
847
848var x = u'\u{dc00}'
849echo $x | od -A n -t x1
850
851## status: 2
852## STDOUT:
853## END
854
855#### \u{dc00} can't be in surrogate range in data
856
857json8 read <<'EOF'
858["long string", u'hello \u{d7ff}', "other"]
859EOF
860echo status=$?
861
862json8 read <<'EOF'
863["long string", u'hello \u{d800}', "other"]
864EOF
865echo status=$?
866
867json8 read <<'EOF'
868["long string", u'hello \u{dfff}', "other"]
869EOF
870echo status=$?
871
872json8 read <<'EOF'
873["long string", u'hello \u{e000}', "other"]
874EOF
875echo status=$?
876
877
878## STDOUT:
879status=0
880status=1
881status=1
882status=0
883## END
884
885
886#### Inf is encoded as null, like JavaScript
887
888# WRONG LOCATION! Gah
889#var x = fromJson(repeat('123', 20))
890
891shopt --set ysh:upgrade
892
893source $LIB_YSH/list.ysh
894
895# Create inf
896var big = repeat('12345678', 100) ++ '.0'
897#pp test_ (s)
898var inf = fromJson(big)
899var neg_inf = fromJson('-' ++ big)
900
901# Can be printed
902pp test_ (inf)
903pp test_ (neg_inf)
904echo --
905
906# Can't be serialized
907try {
908 json write (inf)
909}
910echo error=$[_error.code]
911
912try {
913 json write (neg_inf)
914}
915echo error=$[_error.code]
916
917echo --
918echo $[toJson(inf)]
919echo $[toJson(neg_inf)]
920
921## STDOUT:
922(Float) INFINITY
923(Float) -INFINITY
924--
925null
926error=0
927null
928error=0
929--
930null
931null
932## END
933
934#### NaN is encoded as null, like JavaScript
935
936pp test_ (NAN)
937
938json write (NAN)
939
940echo $[toJson(NAN)]
941
942## STDOUT:
943(Float) NAN
944null
945null
946## END
947
948
949#### Invalid UTF-8 in JSON is rejected
950
951echo $'"\xff"' | json read
952echo status=$?
953
954echo $'"\xff"' | json8 read
955echo status=$?
956
957echo $'\xff' | json read
958echo status=$?
959
960echo $'\xff' | json8 read
961echo status=$?
962
963## STDOUT:
964status=1
965status=1
966status=1
967status=1
968## END
969
970#### Invalid JSON in J8 is rejected
971
972json8 read <<EOF
973b'$(echo -e -n '\xff')'
974EOF
975echo status=$?
976
977json8 read <<EOF
978u'$(echo -e -n '\xff')'
979EOF
980echo status=$?
981
982## STDOUT:
983status=1
984status=1
985## END
986
987#### '' means the same thing as u''
988
989echo "''" | json8 read
990pp test_ (_reply)
991
992echo "'\u{3bc}'" | json8 read
993pp test_ (_reply)
994
995echo "'\yff'" | json8 read
996echo status=$?
997
998## STDOUT:
999(Str) ""
1000(Str) "μ"
1001status=1
1002## END
1003
1004#### decode integer larger than 2^32
1005
1006json=$(( 1 << 33 ))
1007echo $json
1008
1009echo $json | json read
1010pp test_ (_reply)
1011
1012## STDOUT:
10138589934592
1014(Int) 8589934592
1015## END
1016
1017#### decode integer larger than 2^64
1018
1019$SH <<'EOF'
1020json read <<< '123456789123456789123456789'
1021echo status=$?
1022pp test_ (_reply)
1023EOF
1024
1025$SH <<'EOF'
1026json read <<< '-123456789123456789123456789'
1027echo status=$?
1028pp test_ (_reply)
1029EOF
1030
1031echo ok
1032
1033## STDOUT:
1034status=1
1035status=1
1036ok
1037## END
1038
1039
1040#### round trip: read/write with ysh
1041
1042var file = "$REPO_ROOT/spec/testdata/bug.json"
1043#cat $file
1044cat $file | json read (&cfg)
1045json write (cfg) > ysh-json
1046
1047diff -u $file ysh-json
1048echo diff=$?
1049
1050## STDOUT:
1051diff=0
1052## END
1053
1054#### round trip: read/write with ysh, read/write with Python 3 (bug regression)
1055
1056var file = "$REPO_ROOT/spec/testdata/bug.json"
1057#cat $file
1058cat $file | json read (&cfg)
1059json write (cfg) > ysh-json
1060
1061cat ysh-json | python3 -c \
1062 'import json, sys; obj = json.load(sys.stdin); json.dump(obj, sys.stdout, indent=2); print()' \
1063 > py-json
1064
1065diff -u $file py-json
1066echo diff=$?
1067
1068## STDOUT:
1069diff=0
1070## END
1071
1072#### Encoding bytes that don't hit UTF8_REJECT immediately (bug fix)
1073
1074var x = $'\xce'
1075json8 write (x)
1076declare -p x
1077echo
1078
1079var y = $'\xbc'
1080json8 write (y)
1081declare -p y
1082echo
1083
1084var z = $'\xf0\x9f\xa4\xff'
1085json8 write (z)
1086declare -p z
1087
1088## STDOUT:
1089b'\yce'
1090declare -- x=$'\xce'
1091
1092b'\ybc'
1093declare -- y=$'\xbc'
1094
1095b'\yf0\y9f\ya4\yff'
1096declare -- z=$'\xf0\x9f\xa4\xff'
1097## END
1098
1099#### NIL8 token in JSON / JSON8
1100
1101echo "(" | json read
1102echo status=$?
1103
1104echo ")" | json8 read
1105echo status=$?
1106
1107## STDOUT:
1108status=1
1109status=1
1110## END
1111
1112#### Data after internal NUL (issue #2026)
1113
1114$SH <<'EOF'
1115pp test_ (fromJson(b'123\y00abc'))
1116EOF
1117echo status=$?
1118
1119$SH <<'EOF'
1120pp test_ (fromJson(b'123\y01abc'))
1121EOF
1122echo status=$?
1123
1124$SH <<'EOF'
1125shopt --set ysh:upgrade # b'' syntax
1126json read <<< b'123\y00abc'
1127EOF
1128echo status=$?
1129
1130$SH <<'EOF'
1131shopt --set ysh:upgrade # b'' syntax
1132json read <<< b'123\y01abc'
1133EOF
1134echo status=$?
1135
1136## STDOUT:
1137status=4
1138status=4
1139status=1
1140status=1
1141## END
1142
1143#### Float too big
1144
1145$SH <<'EOF'
1146json read <<< '123456789123456789123456789.12345e67890'
1147echo status=$?
1148pp test_ (_reply)
1149EOF
1150
1151$SH <<'EOF'
1152json read <<< '-123456789123456789123456789.12345e67890'
1153echo status=$?
1154pp test_ (_reply)
1155EOF
1156
1157## STDOUT:
1158status=0
1159(Float) INFINITY
1160status=0
1161(Float) -INFINITY
1162## END
1163
1164#### Many [[[ , but not too many
1165
1166shopt -s ysh:upgrade
1167
1168proc pairs(n) {
1169 var m = int(n) # TODO: 1 .. n should auto-convert?
1170
1171 for i in (1 ..< m) {
1172 write -n -- '['
1173 }
1174 for i in (1 ..< m) {
1175 write -n -- ']'
1176 }
1177}
1178
1179# This is all Python can handle; C++ can handle more
1180msg=$(pairs 50)
1181
1182#echo $msg
1183
1184echo "$msg" | json read
1185pp test_ (_reply)
1186echo len=$[len(_reply)]
1187
1188## STDOUT:
1189(List) [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
1190len=1
1191## END
1192
1193
1194#### Too many opening [[[ - blocking stack
1195
1196python2 -c 'print("[" * 10000)' | json read
1197pp test_ (_reply)
1198
1199python2 -c 'print("{" * 10000)' | json read
1200pp test_ (_reply)
1201
1202## STDOUT:
1203## END
1204
1205#### BashArray can be serialized
1206
1207declare -a empty_array
1208
1209declare -a array=(x y)
1210array[5]=z
1211
1212json write (empty_array)
1213json write (array)
1214
1215## STDOUT:
1216{
1217 "type": "BashArray",
1218 "data": {}
1219}
1220{
1221 "type": "BashArray",
1222 "data": {
1223 "0": "x",
1224 "1": "y",
1225 "5": "z"
1226 }
1227}
1228## END
1229
1230#### BashAssoc can be serialized
1231
1232declare -A empty_assoc
1233
1234declare -A assoc=([foo]=bar [42]=43)
1235
1236json write (empty_assoc)
1237json write (assoc)
1238
1239## STDOUT:
1240{
1241 "type": "BashAssoc",
1242 "data": {}
1243}
1244{
1245 "type": "BashAssoc",
1246 "data": {
1247 "foo": "bar",
1248 "42": "43"
1249 }
1250}
1251## END