OILS / spec / ysh-bugs.test.sh View on Github | oils.pub

400 lines, 190 significant
1## our_shell: ysh
2## oils_failures_allowed: 6
3
4#### fastlex: NUL byte inside shebang line
5
6# Hm this test doesn't really tickle the bug
7
8echo b'#! /usr/bin/env \y00 sh \necho hi' > tmp.ysh
9env OILS_HIJACK_SHEBANG=1 $[ENV.SH] tmp.ysh
10
11## STDOUT:
12hi
13## END
14
15#### Tea keywords don't interfere with YSH expressions
16
17var d = {data: 'foo'}
18
19echo $[d.data]
20
21var e = {enum: 1, class: 2, import: 3, const: 4, var: 5, set: 6}
22echo $[len(e)]
23
24## STDOUT:
25foo
266
27## END
28
29#### Catch AttributeError
30
31var s = 'foo'
32echo s=$s
33var t = s.bad()
34echo 'should not get here'
35
36## status: 3
37## STDOUT:
38s=foo
39## END
40
41
42#### Command sub paren parsing bug (#1387)
43
44write $(if (true) { write true })
45
46const a = $(write $[len('foo')])
47echo $a
48
49const b = $(write $[5 ** 3])
50echo $b
51
52const c = $(
53 write $[6 + 7]
54)
55echo $c
56
57## STDOUT:
58true
593
60125
6113
62## END
63
64
65#### More Command sub paren parsing
66
67write $( var mylist = ['for']; for x in (mylist) { echo $x } )
68
69write $( echo while; while (false) { write hi } )
70
71write $( if (true) { write 'if' } )
72
73write $( if (false) { write 'if' } elif (true) { write 'elif' } )
74
75## STDOUT:
76for
77while
78if
79elif
80## END
81
82#### don't execute empty command
83
84shopt --set ysh:all
85
86set -x
87
88try {
89 type -a ''
90}
91echo "type -a returned $_status"
92
93$(true)
94echo nope
95
96## status: 127
97## STDOUT:
98type -a returned 1
99## END
100
101
102#### Do && || with YSH constructs make sense/
103
104# I guess there's nothing wrong with this?
105#
106# But I generally feel && || are only for
107#
108# test --file x && test --file y
109
110var x = []
111true && call x->append(42)
112false && call x->append(43)
113pp test_ (x)
114
115func amp() {
116 true && return (42)
117}
118
119func pipe() {
120 false || return (42)
121}
122
123pp test_ (amp())
124pp test_ (pipe())
125
126## STDOUT:
127## END
128
129
130#### shvar then replace - bug #1986 context manager crash
131
132shvar FOO=bar {
133 for x in (1 ..< 500) {
134 var Q = "hello"
135 setvar Q = Q=>replace("hello","world")
136 }
137}
138#echo $Q
139echo hi
140
141## STDOUT:
142hi
143## END
144
145
146#### Parsing crash - bug #2003
147
148set +o errexit
149
150$[ENV.SH] -c 'proc y (;x) { return = x }'
151echo status=$?
152
153$[ENV.SH] -c 'func y (;x) { return = x }'
154echo status=$?
155
156## STDOUT:
157status=2
158status=2
159## END
160
161
162#### proc with IFS= read -r line - dynamic scope - issue #2012
163
164# 2024-10 - FIXED by the new Env Obj! Because in YSH, 'line' is NOT created in
165# TEMP stack frame - we use the ENCLOSED frame, and it fixes it.
166
167proc p {
168 read -r line
169 write $line
170}
171
172proc p-ifs {
173 IFS= read -r line
174 write $line
175}
176
177#set -x
178
179echo zz | p
180
181echo yy | p-ifs
182
183## STDOUT:
184zz
185yy
186## END
187
188#### func call inside proc call - error message attribution
189
190try 2> foo {
191 $[ENV.SH] -c '
192func ident(x) {
193 return (x)
194}
195
196proc p (; x) {
197 echo $x
198}
199
200# BUG: it points to ( in ident(
201# should point to ( in eval (
202
203eval (ident([1,2,3]))
204'
205}
206
207cat foo
208
209## STDOUT:
210## END
211
212
213#### Crash in parsing case on EOF condition - issue #2037
214
215var WEIGHT = ${1:-}
216case (WEIGHT) {
217 "-" { echo "got nothing" }
218 (else) { echo $WEIGHT
219}
220
221## status: 2
222## STDOUT:
223## END
224
225#### Crash due to incorrect of context manager rooting - issue #1986
226
227proc p {
228 var s = "hi"
229 for q in (1..<50) {
230 shvar Q="whatever" {
231 setvar s = "." ++ s
232 }
233 }
234}
235
236for i in (1..<10) {
237 p
238}
239
240if false {
241 echo 'testing for longer'
242 for i in (1 ..< 1000) {
243 p
244 }
245}
246
247## STDOUT:
248## END
249
250
251#### crash due to arbitrary PNode limit - issue #2078
252
253#!/usr/bin/env ysh
254var DelegatedCompName = {
255 "llvm" : "x_project",
256 "rocprofiler_register" : "x_rocprofiler_register",
257 "roct_thunk_interface" : "x_roct",
258 "rocr_runtime" : "x_rocr",
259 "openmp" : "x_openmp",
260 "offload" : "x_offload",
261 "aomp_extras" : "x_extras",
262 "comgr" : "x_comgr",
263 "rocminfo" : "x_rocminfo",
264 "rocsmilib" : "x_rocm_smi_lib",
265 "amdsmi" : "x_amdsmi",
266 "flang_legacy" : "x_flang_legacy",
267 "pgmath" : "x_pgmath",
268 "flang" : "x_flang",
269 "flang_runtime" : "x_flang_runtime",
270 "hipcc" : "x_hipcc",
271 "hipamd" : "x_hipamd",
272 "rocm_dbgapi" : "x_rocdbgapi",
273 "rocgdb" : "x_rocgdb",
274 "roctracer" : "x_roctracer",
275 "rocprofiler" : "x_rocprofiler"
276}
277
278echo $[len(DelegatedCompName)]
279
280## STDOUT:
28121
282## END
283
284#### bad assertion when pretty printing
285
286pp value (__builtins__) > /dev/null
287echo status=$?
288
289## STDOUT:
290status=0
291## END
292
293#### Another "stealing stdin" issue with spec tests
294
295proc where2(; pred) {
296 for line in (io.stdin) {
297 pp test_ (line)
298 }
299}
300
301seq 5 | where2 [_line ~== 2 or _line ~== 4]
302
303#{ echo 1; echo 2; } | where2 [_line ~== 2 or _line ~== 4]
304
305# empty lines here get put on stdin
306
307## STDOUT:
308(Str) "1"
309(Str) "2"
310(Str) "3"
311(Str) "4"
312(Str) "5"
313## END
314
315#### Nested io.stdin
316
317proc bug {
318 echo '''
319 proc inner {
320 printf 'a\nb\n' | for x in (io.stdin) {
321 echo x=$x
322 }
323 }
324
325 printf 'x\ny\n' | for _ in (io.stdin) {
326 inner
327 }
328 '''
329}
330
331# Changes with invocation style
332
333$[ENV.SH] <(bug)
334echo ---
335$[ENV.SH] -c $(bug)
336echo ---
337bug | $[ENV.SH]
338
339## STDOUT:
340x=a
341x=b
342x=a
343x=b
344---
345x=a
346x=b
347x=a
348x=b
349---
350x=a
351x=b
352x=a
353x=b
354## END
355
356#### Iterating over io.stdin multiple times (#2356)
357
358echo u'a\nb' | for i, line in (io.stdin) { echo $i: $line; break }
359echo u'c\nd' | for i, line in (io.stdin) { echo $i: $line }
360
361## STDOUT:
3620: a
3630: c
3641: d
365## END
366
367#### Long boolean flags can't have attached values
368
369# This currently works, but I think --json and --j8 are enough?
370
371write --json=0 hi
372write --json=F hi
373write --json=False hi
374write --json=false hi
375echo
376
377write --json=1 hi
378write --json=T hi
379write --json=True hi
380write --json=true hi
381
382# typo bug
383write --json=Talse hi
384
385## status: 1
386## STDOUT:
387## END
388
389#### Bug: rooting of pgen2::PNode
390
391# manifests with _bin/cxx-asan+gcalways/ysh, after turning on VALIDATE_ROOTS
392
393var x = 42
394echo $x
395
396#var y = 'foo-' ++ $(var y = 42; echo $y)
397
398## STDOUT:
39942
400## END