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

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