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

364 lines, 149 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 invoked without any arguments is an error
281shopt --set ysh:upgrade
282
283use $REPO_ROOT/spec/testdata/module2/util.ysh
284
285util
286
287## status: 2
288## STDOUT:
289caller_no_leak = null
290## END
291
292#### module invoked with nonexistent name is error
293shopt --set ysh:upgrade
294
295use $REPO_ROOT/spec/testdata/module2/util.ysh
296
297util zzz
298
299## status: 2
300## STDOUT:
301caller_no_leak = null
302## END
303
304#### circular import is an error?
305
306echo hi
307
308## STDOUT:
309## END
310
311#### Module with parse error
312
313shopt --set ysh:upgrade
314
315use $REPO_ROOT/spec/testdata/module2/parse-error.ysh
316
317echo 'should not get here'
318
319## status: 2
320## STDOUT:
321## END
322
323#### Module with runtime error
324
325shopt --set ysh:upgrade
326
327use $REPO_ROOT/spec/testdata/module2/runtime-error.ysh
328
329echo 'should not get here'
330
331## status: 1
332## STDOUT:
333runtime-error before
334## END
335
336#### user can inspect __modules__ cache
337
338echo 'TODO: Dict view of realpath() string -> Obj instance'
339
340## STDOUT:
341## END
342
343#### use foo.ysh --names a b
344
345echo TODO
346
347## STDOUT:
348## END
349
350
351#### use foo.ysh --all-provided
352
353echo TODO
354
355## STDOUT:
356## END
357
358
359#### use foo.ysh --all-for-testing
360
361echo TODO
362
363## STDOUT:
364## END