OILS / spec / append.test.sh View on Github | oils.pub

327 lines, 132 significant
1# spec/append.test.sh: Test +=
2
3## compare_shells: bash mksh zsh
4
5#### Append string to string
6s='abc'
7s+=d
8echo $s
9## stdout: abcd
10
11#### Append array to array
12a=(x y )
13a+=(t 'u v')
14argv.py "${a[@]}"
15## stdout: ['x', 'y', 't', 'u v']
16
17#### Append string to undefined variable
18
19s+=foo
20echo s=$s
21
22# bash and mksh agree that this does NOT respect set -u.
23# I think that's a mistake, but += is a legacy construct, so let's copy it.
24
25set -u
26
27t+=foo
28echo t=$t
29t+=foo
30echo t=$t
31## STDOUT:
32s=foo
33t=foo
34t=foofoo
35## END
36
37#### Append to array to undefined variable
38
39# I wonder if Oil should have accumulators:
40# auto y += %(c d) or something
41
42y+=(c d)
43argv.py "${y[@]}"
44## STDOUT:
45['c', 'd']
46## END
47
48#### error: s+=(my array)
49s='abc'
50s+=(d e f)
51argv.py "${s[@]}"
52## status: 0
53## STDOUT:
54['abc', 'd', 'e', 'f']
55## END
56
57#### error: myarray+=s
58
59# They treat this as implicit index 0. We disallow this on the LHS, so we will
60# also disallow it on the RHS.
61a=(x y )
62a+=z
63argv.py "${a[@]}"
64## status: 1
65## stdout-json: ""
66## OK bash/mksh status: 0
67## OK bash/mksh stdout: ['xz', 'y']
68## OK zsh status: 0
69## OK zsh stdout: ['x', 'y', 'z']
70
71#### typeset s+=(my array)
72typeset s='abc'
73echo $s
74
75typeset s+=(d e f)
76echo status=$?
77argv.py "${s[@]}"
78
79## status: 0
80## STDOUT:
81abc
82status=0
83['abc', 'd', 'e', 'f']
84## END
85## N-I mksh/zsh status: 1
86## N-I mksh/zsh stdout: abc
87## N-I mksh stderr: mksh: <stdin>[4]: syntax error: '(' unexpected
88## N-I zsh stderr: typeset: not valid in this context: s+
89
90#### error: typeset myarray+=s
91typeset a=(x y)
92argv.py "${a[@]}"
93typeset a+=s
94argv.py "${a[@]}"
95
96## status: 1
97## STDOUT:
98['x', 'y']
99## END
100## BUG bash status: 0
101## BUG bash STDOUT:
102['x', 'y']
103['xs', 'y']
104## END
105## N-I mksh STDOUT:
106## END
107
108#### error: append used like env prefix
109# This should be an error in other shells but it's not.
110A=a
111A+=a printenv.py A
112## status: 2
113## BUG bash/zsh status: 0
114## BUG bash/zsh stdout: aa
115## BUG mksh status: 0
116## BUG mksh stdout: a
117
118#### myarray[1]+=s - Append to element
119# They treat this as implicit index 0. We disallow this on the LHS, so we will
120# also disallow it on the RHS.
121a=(x y )
122a[1]+=z
123argv.py "${a[@]}"
124## status: 0
125## stdout: ['x', 'yz']
126## BUG zsh stdout: ['xz', 'y']
127
128#### myarray[-1]+=s - Append to last element
129# Works in bash, but not mksh. It seems like bash is doing the right thing.
130# a[-1] is allowed on the LHS. mksh doesn't have negative indexing?
131a=(1 '2 3')
132a[-1]+=' 4'
133argv.py "${a[@]}"
134## stdout: ['1', '2 3 4']
135## BUG mksh stdout: ['1', '2 3', ' 4']
136
137#### Try to append list to element
138# bash - runtime error: cannot assign list to array number
139# mksh - a[-1]+: is not an identifier
140# osh - parse error -- could be better!
141a=(1 '2 3')
142a[-1]+=(4 5)
143argv.py "${a[@]}"
144
145## stdout-json: ""
146## status: 2
147
148## OK bash status: 0
149## OK bash STDOUT:
150['1', '2 3']
151## END
152
153## OK zsh status: 0
154## OK zsh STDOUT:
155['1', '2 3', '4', '5']
156## END
157
158## N-I mksh status: 1
159
160#### Strings have value semantics, not reference semantics
161s1='abc'
162s2=$s1
163s1+='d'
164echo $s1 $s2
165## stdout: abcd abc
166
167#### typeset s+=
168
169typeset s+=foo
170echo s=$s
171
172# bash and mksh agree that this does NOT respect set -u.
173# I think that's a mistake, but += is a legacy construct, so let's copy it.
174
175set -u
176
177typeset t+=foo
178echo t=$t
179typeset t+=foo
180echo t=$t
181## STDOUT:
182s=foo
183t=foo
184t=foofoo
185## END
186## N-I zsh status: 1
187## N-I zsh stdout-json: ""
188
189#### typeset s${dyn}+=
190
191dyn=x
192
193typeset s${dyn}+=foo
194echo sx=$sx
195
196# bash and mksh agree that this does NOT respect set -u.
197# I think that's a mistake, but += is a legacy construct, so let's copy it.
198
199set -u
200
201typeset t${dyn}+=foo
202echo tx=$tx
203typeset t${dyn}+=foo
204echo tx=$tx
205## STDOUT:
206sx=foo
207tx=foo
208tx=foofoo
209## END
210## N-I zsh status: 1
211## N-I zsh stdout-json: ""
212
213#### export readonly +=
214
215export e+=foo
216echo e=$e
217
218readonly r+=bar
219echo r=$r
220
221set -u
222
223export e+=foo
224echo e=$e
225
226#readonly r+=foo
227#echo r=$e
228
229## STDOUT:
230e=foo
231r=bar
232e=foofoo
233## END
234## N-I zsh status: 1
235## N-I zsh stdout-json: ""
236
237#### local +=
238
239f() {
240 local s+=foo
241 echo s=$s
242
243 set -u
244 local s+=foo
245 echo s=$s
246}
247
248f
249## STDOUT:
250s=foo
251s=foofoo
252## END
253## N-I zsh status: 1
254## N-I zsh stdout-json: ""
255
256#### assign builtin appending array: declare d+=(d e)
257
258declare d+=(d e)
259echo "${d[@]}"
260declare d+=(c l)
261echo "${d[@]}"
262
263readonly r+=(r e)
264echo "${r[@]}"
265# can't do this again
266
267f() {
268 local l+=(l o)
269 echo "${l[@]}"
270
271 local l+=(c a)
272 echo "${l[@]}"
273}
274
275f
276
277## STDOUT:
278d e
279d e c l
280r e
281l o
282l o c a
283## END
284## N-I mksh status: 1
285## N-I mksh stdout-json: ""
286## N-I zsh status: 1
287## N-I zsh stdout-json: ""
288
289#### export+=array disallowed (strict_array)
290shopt -s strict_array
291
292export e+=(e x)
293echo "${e[@]}"
294
295## status: 1
296## STDOUT:
297## END
298## N-I bash status: 0
299## N-I bash STDOUT:
300e x
301## END
302
303
304#### Type mismatching of lhs+=rhs should not cause a crash
305case $SH in mksh|zsh) exit ;; esac
306s=
307a=()
308declare -A d=([lemon]=yellow)
309
310s+=(1)
311s+=([melon]=green)
312
313a+=lime
314a+=([1]=banana)
315
316d+=orange
317d+=(0)
318
319true
320
321## STDOUT:
322## END
323
324## OK osh status: 1
325
326## N-I mksh/zsh STDOUT:
327## END