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

516 lines, 283 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#### Mixing read --line with read -r
176
177$SH $REPO_ROOT/spec/testdata/ysh-read-0.sh
178
179## STDOUT:
180read -r
181REPLY=1
182REPLY=2
183
184read --raw-line
185_reply=1
186_reply=2
187
188Mixed
189REPLY=1
190REPLY=2
191_reply=3
192REPLY=4
193## END
194
195#### read --line --with-eol
196
197$SH $REPO_ROOT/spec/testdata/ysh-read-1.sh
198
199## STDOUT:
200reply=1
201reply=2
202reply=3
203myline=a
204myline=b
205## END
206
207#### read --raw-line --j8
208
209# TODO: is this similar to @() ? It reads j8 lines?
210#
211# But using a function is better?
212#
213# var x = fromJ8Line(_reply)
214# var x = fromJson(_reply) # this is https://jsonlines.org
215
216echo $'u\'foo\'' | read --raw-line --j8
217write -- "$_reply"
218
219## STDOUT:
220foo
221## END
222
223#### echo builtin should disallow typed args - literal
224shopt -s ysh:all
225#shopt -p simple_echo
226
227echo (42)
228## status: 2
229## STDOUT:
230## END
231
232#### echo builtin should disallow typed args - variable
233shopt -s ysh:all
234#shopt -p simple_echo
235
236var x = 43
237echo (x)
238## status: 2
239## STDOUT:
240## END
241
242#### read --all-lines
243seq 3 | read --all-lines :nums
244write --sep ' ' -- @nums
245## STDOUT:
2461 2 3
247## END
248
249#### read --all-lines --with-eol
250seq 3 | read --all-lines --with-eol :nums
251write --sep '' -- @nums
252## STDOUT:
2531
2542
2553
256## END
257
258#### Can simulate read --all-lines with a proc and value.Place
259
260$SH $REPO_ROOT/spec/testdata/ysh-read-2.sh
261
262## STDOUT:
263[
264 "1",
265 "2",
266 "3"
267]
268## END
269
270#### read --all
271echo foo | read --all
272echo "[$_reply]"
273
274echo bad > tmp.txt
275read --all (&x) < tmp.txt
276echo "[$x]"
277
278## STDOUT:
279[foo
280]
281[bad
282]
283## END
284
285#### read --all from directory is an error (EISDIR)
286mkdir -p ./dir
287read --all < ./dir
288echo status=$?
289## STDOUT:
290status=1
291## END
292
293#### read --num-bytes
294
295echo ' a b ' | read --num-bytes 4; echo "reply=[$_reply]"
296echo ' a b ' | read --num-bytes 5; echo "reply=[$_reply]"
297
298echo ' a b ' | read --num-bytes 4 (&x); echo "x=[$x]"
299echo ' a b ' | read --num-bytes 5 (&x); echo "x=[$x]"
300
301## STDOUT:
302reply=[ a ]
303reply=[ a b]
304x=[ a ]
305x=[ a b]
306## END
307
308#### read -0 is like read -r -d ''
309set -o errexit
310
311mkdir -p read0
312cd read0
313touch a\\b\\c\\d
314
315find . -type f -a -print0 | read -r -d '' name
316echo "[$name]"
317
318find . -type f -a -print0 | read -0
319echo "[$REPLY]"
320
321## STDOUT:
322[./a\b\c\d]
323[./a\b\c\d]
324## END
325
326#### simple_test_builtin
327
328test -n "foo"
329echo status=$?
330
331test -n "foo" -a -n "bar"
332echo status=$?
333
334[ -n foo ]
335echo status=$?
336
337shopt --set ysh:all
338shopt --unset errexit
339
340test -n "foo" -a -n "bar"
341echo status=$?
342
343[ -n foo ]
344echo status=$?
345
346test -z foo
347echo status=$?
348
349## STDOUT:
350status=0
351status=0
352status=0
353status=2
354status=2
355status=1
356## END
357
358#### long flags to test
359# no options necessary!
360
361test --dir /
362echo status=$?
363
364touch foo
365test --file foo
366echo status=$?
367
368test --exists /
369echo status=$?
370
371test --symlink foo
372echo status=$?
373
374test --typo foo
375echo status=$?
376
377## STDOUT:
378status=0
379status=0
380status=0
381status=1
382status=2
383## END
384
385
386#### push-registers
387shopt --set ysh:upgrade
388shopt --unset errexit
389
390status_code() {
391 return $1
392}
393
394[[ foo =~ (.*) ]]
395
396status_code 42
397push-registers {
398 status_code 43
399 echo status=$?
400
401 [[ bar =~ (.*) ]]
402 echo ${BASH_REMATCH[@]}
403}
404# WEIRD SEMANTIC TO REVISIT: push-registers is "SILENT" as far as exit code
405# This is for the headless shell, but hasn't been tested.
406# Better method: maybe we should provide a way of SETTING $?
407
408echo status=$?
409
410echo ${BASH_REMATCH[@]}
411## STDOUT:
412status=43
413bar bar
414status=42
415foo foo
416## END
417
418#### push-registers usage
419shopt --set parse_brace
420
421push-registers
422echo status=$?
423
424push-registers a b
425echo status=$?
426
427push-registers a b { # hm extra args are ignored
428 echo hi
429}
430echo status=$?
431
432## STDOUT:
433status=2
434status=2
435hi
436status=0
437## END
438
439#### fopen
440shopt --set parse_brace parse_proc
441
442proc p {
443 echo 'proc'
444}
445
446fopen >out.txt {
447 p
448 echo 'builtin'
449}
450
451cat out.txt
452
453echo ---
454
455fopen <out.txt {
456 tac
457}
458
459# Awkward bash syntax, but we'll live with it
460fopen {left}>left.txt {right}>right.txt {
461 echo 1 >& $left
462 echo 1 >& $right
463
464 echo 2 >& $left
465 echo 2 >& $right
466
467 echo 3 >& $left
468}
469
470echo ---
471comm -23 left.txt right.txt
472
473## STDOUT:
474proc
475builtin
476---
477builtin
478proc
479---
4803
481## END
482
483#### type(x)
484echo $[type(1234)]
485echo $[type('foo')]
486echo $[type(false)]
487echo $[type(1.234)]
488echo $[type([])]
489echo $[type({})]
490echo $[type(null)]
491
492shopt --set ysh:upgrade
493
494func f() {
495 return (42)
496}
497
498echo $[type(f)]
499echo $[type(len)]
500echo $[type('foo'->startsWith)]
501echo $[type('foo'=>join)] # Type error happens later
502echo $[type(1..3)]
503## STDOUT:
504Int
505Str
506Bool
507Float
508List
509Dict
510Null
511Func
512BuiltinFunc
513BoundFunc
514BoundFunc
515Range
516## END