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
439 #### push-registers
440 shopt --set ysh:upgrade
441 shopt --unset errexit
442
443 status_code() {
444 return $1
445 }
446
447 [[ foo =~ (.*) ]]
448
449 status_code 42
450 push-registers {
451 status_code 43
452 echo status=$?
453
454 [[ bar =~ (.*) ]]
455 echo ${BASH_REMATCH[@]}
456 }
457 # WEIRD SEMANTIC TO REVISIT: push-registers is "SILENT" as far as exit code
458 # This is for the headless shell, but hasn't been tested.
459 # Better method: maybe we should provide a way of SETTING $?
460
461 echo status=$?
462
463 echo ${BASH_REMATCH[@]}
464 ## STDOUT:
465 status=43
466 bar bar
467 status=42
468 foo foo
469 ## END
470
471 #### push-registers usage
472 shopt --set parse_brace
473
474 push-registers
475 echo status=$?
476
477 push-registers a b
478 echo status=$?
479
480 push-registers a b { # hm extra args are ignored
481 echo hi
482 }
483 echo status=$?
484
485 ## STDOUT:
486 status=2
487 status=2
488 hi
489 status=0
490 ## END
491
492 #### fopen
493 shopt --set parse_brace parse_proc
494
495 proc p {
496 echo 'proc'
497 }
498
499 fopen >out.txt {
500 p
501 echo 'builtin'
502 }
503
504 cat out.txt
505
506 echo ---
507
508 fopen <out.txt {
509 tac
510 }
511
512 # Awkward bash syntax, but we'll live with it
513 fopen {left}>left.txt {right}>right.txt {
514 echo 1 >& $left
515 echo 1 >& $right
516
517 echo 2 >& $left
518 echo 2 >& $right
519
520 echo 3 >& $left
521 }
522
523 echo ---
524 comm -23 left.txt right.txt
525
526 ## STDOUT:
527 proc
528 builtin
529 ---
530 builtin
531 proc
532 ---
533 3
534 ## END
535
536 #### type(x)
537 echo $[type(1234)]
538 echo $[type('foo')]
539 echo $[type(false)]
540 echo $[type(1.234)]
541 echo $[type([])]
542 echo $[type({})]
543 echo $[type(null)]
544
545 shopt --set ysh:upgrade
546
547 func f() {
548 return (42)
549 }
550
551 echo $[type(f)]
552 echo $[type(len)]
553 echo $[type('foo'=>startsWith)]
554 echo $[type('foo'=>join)] # Type error happens later
555 echo $[type(1..3)]
556 ## STDOUT:
557 Int
558 Str
559 Bool
560 Float
561 List
562 Dict
563 Null
564 Func
565 BuiltinFunc
566 BoundFunc
567 BoundFunc
568 Range
569 ## END
570
571 #### source ///osh/two.sh and $LIB_OSH
572
573 source ///osh/two.sh
574 echo status=$?
575
576 source $LIB_OSH/two.sh
577 echo status=$?
578
579 # errors
580 source ///
581 echo status=$?
582 source ///x
583 echo status=$?
584
585 ## STDOUT:
586 status=0
587 status=0
588 status=2
589 status=2
590 ## END