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

676 lines, 379 significant
1## oils_failures_allowed: 3
2
3#### append onto BashArray a=(1 2)
4shopt -s parse_at
5a=(1 2)
6append '3 4' '5' (a)
7argv.py "${a[@]}"
8
9append -- 6 (a)
10argv.py "${a[@]}"
11
12## STDOUT:
13['1', '2', '3 4', '5']
14['1', '2', '3 4', '5', '6']
15## END
16
17#### append onto var a = :| 1 2 |
18shopt -s parse_at parse_proc
19var a = :| 1 2 |
20append '3 4' '5' (a)
21argv.py @a
22## STDOUT:
23['1', '2', '3 4', '5']
24## END
25
26#### append onto var a = ['1', '2']
27shopt -s parse_at parse_proc
28var a = ['1', '2']
29append '3 4' '5' (a)
30argv.py @a
31## STDOUT:
32['1', '2', '3 4', '5']
33## END
34
35#### append without typed arg
36append a b
37## status: 3
38
39#### append passed invalid type
40s=''
41append a b (s)
42echo status=$?
43## status: 3
44
45#### write --sep, --end, -n, varying flag syntax
46shopt -s ysh:all
47var a = %('a b' 'c d')
48write @a
49write .
50write -- @a
51write .
52
53write --sep '' --end '' @a; write
54write .
55
56write --sep '_' -- @a
57write --sep '_' --end $' END\n' -- @a
58
59# with =
60write --sep='_' --end=$' END\n' -- @a
61
62write -n x
63write -n y
64write
65
66## STDOUT:
67a b
68c d
69.
70a b
71c d
72.
73a bc d
74.
75a b_c d
76a b_c d END
77a b_c d END
78xy
79## END
80
81#### write --json
82shopt --set ysh:upgrade
83
84write --json u'\u{3bc}' x
85write --json b'\yfe\yff' y
86
87## STDOUT:
88"μ"
89"x"
90"��"
91"y"
92## END
93
94#### write --j8
95shopt --set ysh:upgrade
96
97write --j8 u'\u{3bc}' x
98write --j8 b'\yfe\yff' y
99
100## STDOUT:
101"μ"
102"x"
103b'\yfe\yff'
104"y"
105## END
106
107#### write -e not supported
108shopt -s ysh:all
109write -e foo
110write status=$?
111## stdout-json: ""
112## status: 2
113
114#### write syntax error
115shopt -s ysh:all
116write ---end foo
117write status=$?
118## stdout-json: ""
119## status: 2
120
121#### write --
122shopt -s ysh:all
123write --
124# This is annoying
125write -- --
126write done
127
128# this is a syntax error! Doh.
129write ---
130## status: 2
131## STDOUT:
132
133--
134done
135## END
136
137#### read flag usage
138read --lin
139echo status=$?
140
141read --line :var extra
142echo status=$?
143## STDOUT:
144status=2
145status=2
146## END
147
148#### read (&x) is usage error
149
150var x = null # allow no initialization
151echo hello | read (&x)
152echo status=$?
153
154## STDOUT:
155status=2
156## END
157
158#### read --raw-line
159
160echo hi | read --raw-line
161echo "reply=$_reply"
162echo len=$[len(_reply)]
163
164echo hi | read -r
165if test "$REPLY" = "$_reply"; then
166 echo pass
167fi
168
169## STDOUT:
170reply=hi
171len=2
172pass
173## END
174
175#### read --raw-line handles line without end, --with-eol
176
177write --end '' $'a\nb\n' | while read --raw-line; do
178 pp test_ (_reply)
179done
180
181echo
182
183write --end '' $'a\nb' | while read --raw-line; do
184 pp test_ (_reply)
185done
186
187echo
188
189write --end '' $'a\nb\n' | while read --raw-line --with-eol; do
190 pp test_ (_reply)
191done
192
193echo
194
195write --end '' $'a\nb' | while read --raw-line --with-eol; do
196 pp test_ (_reply)
197done
198
199
200## STDOUT:
201(Str) "a"
202(Str) "b"
203
204(Str) "a"
205(Str) "b"
206
207(Str) "a\n"
208(Str) "b\n"
209
210(Str) "a\n"
211(Str) "b"
212## END
213
214#### Mixing read --raw-line with read -r
215
216$SH $REPO_ROOT/spec/testdata/ysh-read-0.sh
217
218## STDOUT:
219read -r
220REPLY=1
221REPLY=2
222
223read --raw-line
224_reply=1
225_reply=2
226
227Mixed
228REPLY=1
229REPLY=2
230_reply=3
231REPLY=4
232## END
233
234#### read --raw-line --with-eol
235
236$SH $REPO_ROOT/spec/testdata/ysh-read-1.sh
237
238## STDOUT:
239reply=1
240reply=2
241reply=3
242myline=a
243myline=b
244## END
245
246#### read --raw-line --j8
247
248# TODO: is this similar to @() ? It reads j8 lines?
249#
250# But using a function is better?
251#
252# var x = fromJ8Line(_reply)
253# var x = fromJson(_reply) # this is https://jsonlines.org
254
255echo $'u\'foo\'' | read --raw-line --j8
256write -- "$_reply"
257
258## STDOUT:
259foo
260## END
261
262#### echo builtin should disallow typed args - literal
263shopt -s ysh:all
264#shopt -p simple_echo
265
266echo (42)
267## status: 2
268## STDOUT:
269## END
270
271#### echo builtin should disallow typed args - variable
272shopt -s ysh:all
273#shopt -p simple_echo
274
275var x = 43
276echo (x)
277## status: 2
278## STDOUT:
279## END
280
281#### read --all-lines
282seq 3 | read --all-lines :nums
283write --sep ' ' -- @nums
284## STDOUT:
2851 2 3
286## END
287
288#### read --all-lines --with-eol
289seq 3 | read --all-lines --with-eol :nums
290write --sep '' -- @nums
291## STDOUT:
2921
2932
2943
295## END
296
297#### Can simulate read --all-lines with a proc and value.Place
298
299$SH $REPO_ROOT/spec/testdata/ysh-read-2.sh
300
301## STDOUT:
302[
303 "1",
304 "2",
305 "3"
306]
307## END
308
309#### read --all
310echo foo | read --all
311echo "[$_reply]"
312
313echo bad > tmp.txt
314read --all (&x) < tmp.txt
315echo "[$x]"
316
317## STDOUT:
318[foo
319]
320[bad
321]
322## END
323
324#### read --all from directory is an error (EISDIR)
325mkdir -p ./dir
326read --all < ./dir
327echo status=$?
328## STDOUT:
329status=1
330## END
331
332#### read --num-bytes
333
334echo ' a b ' | read --num-bytes 4; echo "reply=[$_reply]"
335echo ' a b ' | read --num-bytes 5; echo "reply=[$_reply]"
336
337echo ' a b ' | read --num-bytes 4 (&x); echo "x=[$x]"
338echo ' a b ' | read --num-bytes 5 (&x); echo "x=[$x]"
339
340## STDOUT:
341reply=[ a ]
342reply=[ a b]
343x=[ a ]
344x=[ a b]
345## END
346
347#### read -0 is like read -r -d ''
348set -o errexit
349
350mkdir -p read0
351cd read0
352touch a\\b\\c\\d
353
354find . -type f -a -print0 | read -r -d '' name
355echo "[$name]"
356
357find . -type f -a -print0 | read -0
358echo "[$REPLY]"
359
360## STDOUT:
361[./a\b\c\d]
362[./a\b\c\d]
363## END
364
365#### read -0 myvar doesn't do anything with IFS
366
367touch 'foo bar '
368find -type f -print0 | read -0
369echo "[$REPLY]"
370
371find -type f -print0 | read -0 myvar
372echo "[$myvar]"
373
374## STDOUT:
375[./foo bar ]
376[./foo bar ]
377## END
378
379#### simple_test_builtin
380
381test -n "foo"
382echo status=$?
383
384test -n "foo" -a -n "bar"
385echo status=$?
386
387[ -n foo ]
388echo status=$?
389
390shopt --set ysh:all
391shopt --unset errexit
392
393test -n "foo" -a -n "bar"
394echo status=$?
395
396[ -n foo ]
397echo status=$?
398
399test -z foo
400echo status=$?
401
402## STDOUT:
403status=0
404status=0
405status=0
406status=2
407status=2
408status=1
409## END
410
411#### long flags to test
412# no options necessary!
413
414test --dir /
415echo status=$?
416
417touch foo
418test --file foo
419echo status=$?
420
421test --exists /
422echo status=$?
423
424test --symlink foo
425echo status=$?
426
427test --typo foo
428echo status=$?
429
430## STDOUT:
431status=0
432status=0
433status=0
434status=1
435status=2
436## END
437
438#### test --true; test --false
439shopt --set ysh:upgrade
440
441for expr in (true, false, '', 'other') {
442 pp test_ (expr)
443
444 try {
445 test --true $[expr]
446 }
447 echo true=$[_error.code]
448
449 try {
450 test --false $[expr]
451 }
452 echo false=$[_error.code]
453 echo
454}
455
456## STDOUT:
457(Bool) true
458true=0
459false=1
460
461(Bool) false
462true=1
463false=0
464
465(Str) ""
466true=1
467false=1
468
469(Str) "other"
470true=1
471false=1
472
473## END
474
475#### More test --true --false
476shopt --set ysh:upgrade
477
478var d = {}
479
480try {
481 test --true $[bool(d)]
482}
483echo dict=$[_error.code]
484
485setvar d.key = 'val'
486
487try {
488 test --true $[bool(d)]
489}
490echo dict=$[_error.code]
491
492echo
493
494if test --true $[bool(d)] && ! test -f / {
495 echo AndOr
496}
497
498## STDOUT:
499dict=1
500dict=0
501
502AndOr
503## END
504
505
506#### Make sure [[ is not affected by --true --false
507
508set +o errexit
509
510$SH +o ysh:all -c '[[ --true ]]; echo dbracket=$?'
511$SH +o ysh:all -c '[[ --false ]]; echo dbracket=$?'
512
513$SH +o ysh:all -c '[[ --true true ]]; echo dbracket=$?'
514echo "parse error $?"
515$SH +o ysh:all -c '[[ --false false ]]; echo dbracket=$?'
516echo "parse error $?"
517
518## STDOUT:
519dbracket=0
520dbracket=0
521parse error 2
522parse error 2
523## END
524
525#### push-registers
526shopt --set ysh:upgrade
527shopt --unset errexit
528
529status_code() {
530 return $1
531}
532
533[[ foo =~ (.*) ]]
534
535status_code 42
536push-registers {
537 status_code 43
538 echo status=$?
539
540 [[ bar =~ (.*) ]]
541 echo ${BASH_REMATCH[@]}
542}
543# WEIRD SEMANTIC TO REVISIT: push-registers is "SILENT" as far as exit code
544# This is for the headless shell, but hasn't been tested.
545# Better method: maybe we should provide a way of SETTING $?
546
547echo status=$?
548
549echo ${BASH_REMATCH[@]}
550## STDOUT:
551status=43
552bar bar
553status=42
554foo foo
555## END
556
557#### push-registers usage
558shopt --set parse_brace
559
560push-registers
561echo status=$?
562
563push-registers a b
564echo status=$?
565
566push-registers a b { # hm extra args are ignored
567 echo hi
568}
569echo status=$?
570
571## STDOUT:
572status=2
573status=2
574hi
575status=0
576## END
577
578#### redir
579shopt --set parse_brace parse_proc
580
581proc p {
582 echo 'proc'
583}
584
585redir >out.txt {
586 p
587 echo 'builtin'
588}
589
590cat out.txt
591
592echo ---
593
594redir <out.txt {
595 tac
596}
597
598# Awkward bash syntax, but we'll live with it
599redir {left}>left.txt {right}>right.txt {
600 echo 1 >& $left
601 echo 1 >& $right
602
603 echo 2 >& $left
604 echo 2 >& $right
605
606 echo 3 >& $left
607}
608
609echo ---
610comm -23 left.txt right.txt
611
612## STDOUT:
613proc
614builtin
615---
616builtin
617proc
618---
6193
620## END
621
622#### type(x)
623echo $[type(1234)]
624echo $[type('foo')]
625echo $[type(false)]
626echo $[type(1.234)]
627echo $[type([])]
628echo $[type({})]
629echo $[type(null)]
630
631shopt --set ysh:upgrade
632
633func f() {
634 return (42)
635}
636
637echo $[type(f)]
638echo $[type(len)]
639echo $[type('foo'=>startsWith)]
640echo $[type('foo'=>join)] # Type error happens later
641echo $[type(1..3)]
642## STDOUT:
643Int
644Str
645Bool
646Float
647List
648Dict
649Null
650Func
651BuiltinFunc
652BoundFunc
653BoundFunc
654Range
655## END
656
657#### source ///osh/two.sh and $LIB_OSH
658
659source ///osh/two.sh
660echo status=$?
661
662source $LIB_OSH/two.sh
663echo status=$?
664
665# errors
666source ///
667echo status=$?
668source ///x
669echo status=$?
670
671## STDOUT:
672status=0
673status=0
674status=1
675status=1
676## END