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

435 lines, 183 significant
1## oils_failures_allowed: 5
2
3#### source-guard is an old way of preventing redefinition - could remove it
4shopt --set ysh:upgrade
5
6source-guard 'main' || return 0
7source $REPO_ROOT/spec/testdata/module/common.ysh
8source $REPO_ROOT/spec/testdata/module/module1.ysh
9## STDOUT:
10common
11module1
12## END
13
14#### is-main
15
16# This sources lib.ysh
17$SH $REPO_ROOT/spec/testdata/module/main.ysh
18
19# Run it directly
20$SH $REPO_ROOT/spec/testdata/module/lib.ysh
21
22## STDOUT:
23lib.ysh is not the main module
24hi from main.ysh
25hi from lib.ysh
26## END
27
28#### is-main with -c and stdin
29
30$SH -c 'echo -c; is-main; echo status=$?'
31
32echo 'echo stdin; is-main; echo status=$?' | $SH
33
34## STDOUT:
35-c
36status=0
37stdin
38status=0
39## END
40
41#### use builtin usage
42
43use
44echo no-arg=$?
45
46use foo
47echo one-arg=$?
48
49use --extern foo
50echo extern=$?
51
52use --bad-flag
53echo bad-flag=$?
54
55use too many
56echo too-many=$?
57
58use ///no-builtin
59echo no-builtin=$?
60
61
62## STDOUT:
63no-arg=2
64one-arg=1
65extern=0
66bad-flag=2
67too-many=2
68no-builtin=1
69## END
70
71
72#### use --extern is a no-op, for static analysis
73
74use --extern grep sed awk
75echo status=$?
76
77use --extern zzz
78echo status=$?
79
80## STDOUT:
81status=0
82status=0
83## END
84
85#### use foo.ysh creates a value.Obj, and it's cached on later invocations
86
87shopt --set ysh:upgrade
88
89var caller_no_leak = 42
90
91use $REPO_ROOT/spec/testdata/module2/util.ysh
92
93# This is a value.Obj
94pp test_ (['util', util])
95var id1 = id(util)
96
97var saved_util = util
98
99use $REPO_ROOT/spec/testdata/module2/util.ysh
100pp test_ (['repeated', util])
101var id2 = id(util)
102
103# Create a symlink to test normalization
104
105ln -s $REPO_ROOT/spec/testdata/module2/util.ysh symlink.ysh
106
107use symlink.ysh
108pp test_ (['symlink', symlink])
109var id3 = id(symlink)
110
111#pp test_ ([id1, id2, id3])
112
113# Make sure they are all the same object
114assert [id1 === id2]
115assert [id2 === id3]
116
117# Doesn't leak from util.ysh
118echo "setvar_noleak $[getVar('setvar_noleak')]"
119echo "setglobal_noleak $[getVar('setglobal_noleak')]"
120
121## STDOUT:
122caller_no_leak = null
123(List) ["util",{"MY_INTEGER":42,"log":<Proc>,"die":<Proc>,"setvar_noleak":"util.ysh","setglobal_noleak":"util.ysh","invokableObj":{"x":3,"y":4} ==> {"__invoke__":<Proc>}} ==> {"__invoke__":<BuiltinProc>}]
124(List) ["repeated",{"MY_INTEGER":42,"log":<Proc>,"die":<Proc>,"setvar_noleak":"util.ysh","setglobal_noleak":"util.ysh","invokableObj":{"x":3,"y":4} ==> {"__invoke__":<Proc>}} ==> {"__invoke__":<BuiltinProc>}]
125(List) ["symlink",{"MY_INTEGER":42,"log":<Proc>,"die":<Proc>,"setvar_noleak":"util.ysh","setglobal_noleak":"util.ysh","invokableObj":{"x":3,"y":4} ==> {"__invoke__":<Proc>}} ==> {"__invoke__":<BuiltinProc>}]
126setvar_noleak null
127setglobal_noleak null
128## END
129
130#### procs in a module can call setglobal on globals in that module
131shopt --set ysh:upgrade
132
133use $REPO_ROOT/spec/testdata/module2/globals.ysh
134
135# get() should work on Obj too. Possibly we should get rid of the default
136var myproc = get(propView(globals), 'mutate-g1', null)
137call setVar('mutate-g1', myproc)
138
139# you can mutate it internally, but the mutation isn't VISIBLE. GAH!
140# I wonder if you make Cell a value? or something
141mutate-g1
142echo
143
144# PROBLEM: This is a value.Obj COPY, not the fucking original!!!
145# immutable objects??
146
147#pp test_ ([id(globals.d), globals.d])
148
149call globals.mutateG2()
150echo
151
152#= propView(globals)
153
154# these are not provided
155echo "globals.g1 = $[get(globals, 'g1', null)]"
156echo "globals.g2 = $[get(globals, 'g2', null)]"
157echo
158
159#pp frame_vars_
160# Shouldn't appear here
161echo "importer g1 = $[getVar('g1')]"
162echo "importer g2 = $[getVar('g2')]"
163
164## STDOUT:
165g1 = g1
166g1 = proc mutated
167
168g2 = g2
169g2 = func mutated
170
171globals.g1 = null
172globals.g2 = null
173
174importer g1 = null
175importer g2 = null
176## END
177
178#### no provided names
179shopt --set ysh:upgrade
180
181use $REPO_ROOT/spec/testdata/module2/no-provide.ysh
182
183## status: 1
184## STDOUT:
185## END
186
187#### bad provide type
188shopt --set ysh:upgrade
189
190use $REPO_ROOT/spec/testdata/module2/bad-provide-type.ysh
191
192echo 'should not get here'
193
194## status: 1
195## STDOUT:
196## END
197
198#### invalid provide entries
199shopt --set ysh:upgrade
200
201use $REPO_ROOT/spec/testdata/module2/bad-provide.ysh
202
203echo 'should not get here'
204
205## status: 1
206## STDOUT:
207## END
208
209#### use foo.ysh creates a value.Obj with __invoke__
210shopt --set ysh:upgrade
211
212use $REPO_ROOT/spec/testdata/module2/util.ysh
213
214# This is a value.Obj
215#pp test_ (util)
216
217util log 'hello'
218util die 'hello there'
219
220## STDOUT:
221caller_no_leak = null
222log hello
223die hello there
224## END
225
226#### module itself is invokable Obj, which can contain invokable obj!
227shopt --set ysh:upgrade
228
229use $REPO_ROOT/spec/testdata/module2/util.ysh
230
231util invokableObj (1)
232
233# Usage error
234#util invokableObj
235
236## STDOUT:
237caller_no_leak = null
238sum = 8
239## END
240
241#### argument binding test
242shopt --set ysh:upgrade
243
244use $REPO_ROOT/spec/testdata/module2/util2.ysh
245
246util2 echo-args w1 w2 w3 w4 (3, 4, 5, 6, n1=7, n2=8, n3=9) {
247 echo hi
248}
249
250echo ---
251
252util2 echo-args w1 w2 (3, 4, n3=9) {
253 echo hi
254}
255
256## STDOUT:
257(List) ["w1","w2"]
258(List) ["w3","w4"]
259
260(List) [3,4]
261(List) [5,6]
262
263(List) [7,8]
264(Dict) {"n3":9}
265
266<Block>
267---
268(List) ["w1","w2"]
269(List) []
270
271(List) [3,4]
272(List) []
273
274(List) [42,43]
275(Dict) {"n3":9}
276
277<Block>
278## END
279
280#### module-with-hyphens
281shopt --set ysh:upgrade
282
283use $REPO_ROOT/spec/testdata/module2/for-xtrace.ysh
284
285for-xtrace increment
286
287var mod = getVar('for-xtrace')
288pp test_ (mod.counter)
289
290## STDOUT:
291[for-xtrace]
292counter = 5
293counter = 6
294(Int) 6
295## END
296
297
298#### modules can access __builtins__ directly
299shopt --set ysh:upgrade
300
301use $REPO_ROOT/spec/testdata/module2/builtins.ysh
302
303var mylen = builtins.mylen
304
305pp test_ (mylen([3,4,5]))
306
307## STDOUT:
308(Int) 3
309## END
310
311#### use may only be used a TOP level, not within proc
312shopt --set ysh:upgrade
313
314proc use-it {
315 use $REPO_ROOT/spec/testdata/module2/builtins.ysh
316}
317
318use-it
319
320## status: 2
321## STDOUT:
322## END
323
324#### Mutable variables are frozen - beware!
325
326shopt --set ysh:upgrade
327
328use $REPO_ROOT/spec/testdata/module2/for-xtrace.ysh
329
330for-xtrace increment
331
332var mod = getVar('for-xtrace')
333pp test_ (mod.counter)
334
335for-xtrace increment
336
337pp test_ (mod.counter)
338
339for-xtrace increment
340
341## STDOUT:
342[for-xtrace]
343counter = 5
344counter = 6
345(Int) 6
346counter = 7
347(Int) 6
348counter = 8
349## END
350
351#### module invoked without any arguments is an error
352shopt --set ysh:upgrade
353
354use $REPO_ROOT/spec/testdata/module2/util.ysh
355
356util
357
358## status: 2
359## STDOUT:
360caller_no_leak = null
361## END
362
363#### module invoked with nonexistent name is error
364shopt --set ysh:upgrade
365
366use $REPO_ROOT/spec/testdata/module2/util.ysh
367
368util zzz
369
370## status: 2
371## STDOUT:
372caller_no_leak = null
373## END
374
375#### circular import is an error?
376
377echo hi
378
379## STDOUT:
380## END
381
382#### Module with parse error
383
384shopt --set ysh:upgrade
385
386use $REPO_ROOT/spec/testdata/module2/parse-error.ysh
387
388echo 'should not get here'
389
390## status: 2
391## STDOUT:
392## END
393
394#### Module with runtime error
395
396shopt --set ysh:upgrade
397
398use $REPO_ROOT/spec/testdata/module2/runtime-error.ysh
399
400echo 'should not get here'
401
402## status: 1
403## STDOUT:
404runtime-error before
405## END
406
407#### user can inspect __modules__ cache
408
409echo 'TODO: Dict view of realpath() string -> Obj instance'
410
411## STDOUT:
412## END
413
414#### use foo.ysh --names a b
415
416echo TODO
417
418## STDOUT:
419## END
420
421
422#### use foo.ysh --all-provided
423
424echo TODO
425
426## STDOUT:
427## END
428
429
430#### use foo.ysh --all-for-testing
431
432echo TODO
433
434## STDOUT:
435## END