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