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

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