Skip to content

Commit 243afe5

Browse files
committed
fix: Now error when set-string'ing a non-string value
This also fixes other bugs with 'traverse-set'
1 parent d9aea7c commit 243afe5

File tree

4 files changed

+291
-63
lines changed

4 files changed

+291
-63
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,9 @@ bpm install
5959
- add tests for array in array (like object in object)
6060
- ensure error (for set primarily) if the virtual object references a variable that does not exist
6161
- "queried for X, but found existing object": print object in error (same with indexed arrays)
62-
- zerocopy for get and set
6362
- -p flag?
63+
- support `--pass-by-value`
64+
- check for circular references
65+
- unset all function
66+
- --reply-with-ref --reply-with-value
67+
- meta: 'unset REPLY' potential conflict with set -u

pkg/lib/traverse-set.sh

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ bash_object.traverse-set() {
127127

128128
bash_object.trace_loop
129129

130+
local is_index_of_array='no'
131+
if [ "${key::1}" = $'\x1C' ]; then
132+
key="${key#?}"
133+
is_index_of_array='yes'
134+
fi
135+
130136
# If 'key' is not a member of object or index of array, error
131137
if [ -z "${current_object["$key"]+x}" ]; then
132138
# If we are before the last element in the query, then error
@@ -230,20 +236,49 @@ bash_object.traverse-set() {
230236
# TODO: test these internal invalid errors (error when type=array references object, etc.)?
231237
:
232238
elif ((i+1 == ${#REPLIES[@]})); then
233-
case "$vmd_dtype" in
234-
object)
235-
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Was going to set-string, but found existing object'
236-
return
237-
;;
238-
array)
239-
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Was going to set-string, but found existing array'
240-
return
241-
;;
242-
*)
243-
bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "Unexpected vmd_dtype '$vmd_dtype'"
239+
if [ "$final_value_type" = object ]; then
240+
case "$vmd_dtype" in
241+
object) :;;
242+
array)
243+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' "Assigning an $final_value_type, but found existing $vmd_dtype"
244+
return
245+
;;
246+
*)
247+
bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "Unexpected vmd_dtype '$vmd_dtype'"
248+
return
249+
;;
250+
esac
251+
elif [ "$final_value_type" = array ]; then
252+
case "$vmd_dtype" in
253+
object)
254+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' "Assigning an $final_value_type, but found existing $vmd_dtype"
255+
return
256+
;;
257+
array) :;;
258+
*)
259+
bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "Unexpected vmd_dtype '$vmd_dtype'"
260+
return
261+
;;
262+
esac
263+
elif [ "$final_value_type" = string ]; then
264+
case "$vmd_dtype" in
265+
object)
266+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' "Assigning an $final_value_type, but found existing $vmd_dtype"
267+
return
268+
;;
269+
array)
270+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' "Assigning an $final_value_type, but found existing $vmd_dtype"
271+
return
272+
;;
273+
*)
274+
bash_object.util.die 'ERROR_INTERNAL_INVALID_VOBJ' "Unexpected vmd_dtype '$vmd_dtype'"
275+
return
276+
;;
277+
esac
278+
else
279+
bash_object.util.die 'ERROR_INTERNAL_INVALID_PARAM' "Unexpected final_value_type '$final_value_type'"
244280
return
245-
;;
246-
esac
281+
fi
247282
fi
248283
# Otherwise, 'key_value' is a string
249284
else
@@ -255,11 +290,20 @@ bash_object.traverse-set() {
255290
# TODO error message
256291
bash_object.util.die 'ERROR_VALUE_NOT_FOUND' "Encountered string using accessor '$key', but expected to find either an object or array, in accordance with the filter"
257292
return
258-
:
259293
elif ((i+1 == ${#REPLIES[@]})); then
260-
# TODO: ensure correct type
261-
local -n string_to_copy_from="$final_value"
262-
current_object["$key"]="$string_to_copy_from"
294+
if [ "$final_value_type" = object ]; then
295+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Assigning an object, but found existing string'
296+
return
297+
elif [ "$final_value_type" = array ]; then
298+
bash_object.util.die 'ERROR_VALUE_INCORRECT_TYPE' 'Assigning an array, but found existing string'
299+
return
300+
elif [ "$final_value_type" = string ]; then
301+
local -n string_to_copy_from="$final_value"
302+
current_object["$key"]="$string_to_copy_from"
303+
else
304+
bash_object.util.die 'ERROR_INTERNAL_INVALID_PARAM' "Unexpected final_value_type '$final_value_type'"
305+
return
306+
fi
263307
fi
264308
fi
265309
fi

tests/set-errors-invalid-vobj-type.bats

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,228 @@
55
# it is the wrong type
66

77
load './util/init.sh'
8+
9+
# set-object
10+
@test "Error on set-object'ing array" {
11+
declare -a SUB_ARRAY=(omicron pi rho)
12+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
13+
declare -A obj=([upsilon]=phi)
14+
15+
run bash_object.traverse-set --pass-by-ref object OBJECT '.my_key' obj
16+
17+
assert_failure
18+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
19+
assert_line -p 'Assigning an object, but found existing array'
20+
}
21+
22+
@test "Error on set-object'ing array inside object" {
23+
declare -a SUB_SUB_ARRAY=(omicron pi rho)
24+
declare -A SUB_OBJECT=([nested]=$'\x1C\x1Dtype=array;&SUB_SUB_ARRAY')
25+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_OBJECT')
26+
declare -A obj=([upsilon]=phi)
27+
28+
run bash_object.traverse-set --pass-by-ref object OBJECT '.my_key.nested' obj
29+
30+
assert_failure
31+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
32+
assert_line -p 'Assigning an object, but found existing array'
33+
}
34+
35+
@test "Error on set-object'ing array in array" {
36+
declare -a SUB_SUB_ARRAY=(rho sigma tau)
37+
declare -a SUB_ARRAY=(omicron pi $'\x1C\x1Dtype=array;&SUB_SUB_ARRAY')
38+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
39+
declare -A obj=([upsilon]=phi)
40+
41+
run bash_object.traverse-set --pass-by-ref object OBJECT '.["my_key"].[2]' obj
42+
43+
assert_failure
44+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
45+
assert_line -p 'Assigning an object, but found existing array'
46+
}
47+
48+
@test "Error on set-object'ing string" {
49+
declare -A OBJECT=([my_key]='string_value2')
50+
declare -A obj=([upsilon]=phi)
51+
52+
run bash_object.traverse-set --pass-by-ref object OBJECT '.my_key' obj
53+
54+
assert_failure
55+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
56+
assert_line -p 'Assigning an object, but found existing string'
57+
}
58+
59+
@test "Error on set-object'ing string inside object" {
60+
declare -A SUB_OBJECT=([nested]='string_value')
61+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
62+
declare -A obj=([upsilon]=phi)
63+
64+
run bash_object.traverse-set --pass-by-ref object OBJECT '.my_key.nested' obj
65+
66+
assert_failure
67+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
68+
assert_line -p 'Assigning an object, but found existing string'
69+
}
70+
71+
@test "Error on set-object'ing string in array" {
72+
declare -a SUB_ARRAY=(omicron pi rho)
73+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
74+
declare -A obj=([upsilon]=phi)
75+
76+
run bash_object.traverse-set --pass-by-ref object OBJECT '.["my_key"].[2]' obj
77+
78+
assert_failure
79+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
80+
assert_line -p 'Assigning an object, but found existing string'
81+
}
82+
83+
# set-array
84+
@test "Error on set-array'ing object" {
85+
declare -A SUB_SUB_OBJECT=([phi]=chi)
86+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
87+
declare -a arr=(upsilon phi chi psi)
88+
89+
run bash_object.traverse-set --pass-by-ref array OBJECT '.my_key' arr
90+
91+
assert_failure
92+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
93+
assert_line -p 'Assigning an array, but found existing object'
94+
}
95+
96+
@test "Error on set-array'ing object inside object" {
97+
declare -A SUB_SUB_OBJECT=([phi]=chi)
98+
declare -A SUB_OBJECT=([nested]=$'\x1C\x1Dtype=object;&SUB_SUB_OBJECT')
99+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
100+
declare -a arr=(upsilon phi chi psi)
101+
102+
run bash_object.traverse-set --pass-by-ref array OBJECT '.my_key.nested' arr
103+
104+
assert_failure
105+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
106+
assert_line -p 'Assigning an array, but found existing object'
107+
}
108+
109+
@test "Error on set-array'ing object in array" {
110+
declare -A SUB_SUB_OBJECT=([phi]=chi)
111+
declare -a SUB_ARRAY=(omicron pi $'\x1C\x1Dtype=object;&SUB_SUB_OBJECT')
112+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
113+
declare -a arr=(upsilon phi chi psi)
114+
115+
run bash_object.traverse-set --pass-by-ref array OBJECT '.["my_key"].[2]' arr
116+
117+
assert_failure
118+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
119+
assert_line -p 'Assigning an array, but found existing object'
120+
}
121+
122+
@test "Error on set-array'ing string" {
123+
declare -A OBJECT=([my_key]='string_value2')
124+
declare -a arr=(upsilon phi chi psi)
125+
126+
run bash_object.traverse-set --pass-by-ref array OBJECT '.my_key' arr
127+
128+
assert_failure
129+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
130+
assert_line -p 'Assigning an array, but found existing string'
131+
}
132+
133+
@test "Error on set-array'ing string inside object" {
134+
declare -A SUB_OBJECT=([nested]='string_value')
135+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
136+
declare -a arr=(upsilon phi chi psi)
137+
138+
run bash_object.traverse-set --pass-by-ref array OBJECT '.my_key.nested' arr
139+
140+
assert_failure
141+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
142+
assert_line -p 'Assigning an array, but found existing string'
143+
}
144+
145+
@test "Error on set-array'ing string in array" {
146+
declare -a SUB_ARRAY=(omicron pi 'string value')
147+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
148+
declare -a arr=(upsilon phi chi psi)
149+
150+
run bash_object.traverse-set --pass-by-ref array OBJECT '.["my_key"].[2]' arr
151+
152+
assert_failure
153+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
154+
assert_line -p 'Assigning an array, but found existing string'
155+
}
156+
157+
# set-string
158+
@test "Error on set-string'ing array" {
159+
declare -a SUB_ARRAY=(omicron pi rho)
160+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
161+
str='psi-omega'
162+
163+
run bash_object.traverse-set --pass-by-ref string OBJECT '.my_key' str
164+
165+
assert_failure
166+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
167+
assert_line -p 'Assigning an string, but found existing array'
168+
}
169+
170+
@test "Error on set-string'ing array inside object" {
171+
declare -a SUB_SUB_ARRAY=(omicron pi rho)
172+
declare -A SUB_OBJECT=([nested]=$'\x1C\x1Dtype=array;&SUB_SUB_ARRAY')
173+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_OBJECT')
174+
str='psi-omega'
175+
176+
run bash_object.traverse-set --pass-by-ref string OBJECT '.my_key.nested' str
177+
178+
assert_failure
179+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
180+
assert_line -p 'Assigning an string, but found existing array'
181+
}
182+
183+
@test "Error on set-string'ing array in array" {
184+
declare -a SUB_SUB_ARRAY=(rho sigma tau)
185+
declare -a SUB_ARRAY=(omicron pi $'\x1C\x1Dtype=array;&SUB_SUB_ARRAY')
186+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
187+
str='psi-omega'
188+
189+
run bash_object.traverse-set --pass-by-ref string OBJECT '.["my_key"].[2]' str
190+
191+
assert_failure
192+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
193+
assert_line -p 'Assigning an string, but found existing array'
194+
}
195+
196+
@test "Error on set-string'ing object" {
197+
declare -A SUB_SUB_OBJECT=([phi]=chi)
198+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
199+
str='psi-omega'
200+
201+
run bash_object.traverse-set --pass-by-ref string OBJECT '.my_key' str
202+
203+
assert_failure
204+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
205+
assert_line -p 'Assigning an string, but found existing object'
206+
}
207+
208+
@test "Error on set-string'ing object inside object" {
209+
declare -A SUB_SUB_OBJECT=([phi]=chi)
210+
declare -A SUB_OBJECT=([nested]=$'\x1C\x1Dtype=object;&SUB_SUB_OBJECT')
211+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
212+
str='psi-omega'
213+
214+
run bash_object.traverse-set --pass-by-ref string OBJECT '.my_key.nested' str
215+
216+
assert_failure
217+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
218+
assert_line -p 'Assigning an string, but found existing object'
219+
}
220+
221+
@test "Error on set-string'ing object in array" {
222+
declare -A SUB_SUB_OBJECT=([phi]=chi)
223+
declare -a SUB_ARRAY=(omicron pi $'\x1C\x1Dtype=object;&SUB_SUB_OBJECT')
224+
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
225+
str='psi-omega'
226+
227+
run bash_object.traverse-set --pass-by-ref string OBJECT '.["my_key"].[2]' str
228+
229+
assert_failure
230+
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
231+
assert_line -p 'Assigning an string, but found existing object'
232+
}

tests/set-string.bats

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,6 @@
22

33
load './util/init.sh'
44

5-
@test "Error on set-string'ing object" {
6-
declare -A SUB_OBJECT=([nested]=woof)
7-
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
8-
9-
run bash_object.traverse-set --pass-by-ref string 'OBJECT' '.my_key' 'my_value'
10-
11-
assert_failure
12-
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
13-
assert_output -p "to set-string, but found existing object"
14-
}
15-
16-
@test "Error on set-string'ing object in object" {
17-
declare -A SUB_OBJECT=([nested]=woof)
18-
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
19-
20-
run bash_object.traverse-set --pass-by-ref string 'OBJECT' '.my_key' 'my_value'
21-
22-
assert_failure
23-
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
24-
assert_output -p "to set-string, but found existing object"
25-
}
26-
27-
@test "Error on set-string'ing array" {
28-
declare -A SUB_ARRAY=(omicron pi rho)
29-
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=array;&SUB_ARRAY')
30-
31-
run bash_object.traverse-set --pass-by-ref string 'OBJECT' '.my_key' 'my_value'
32-
33-
assert_failure
34-
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
35-
assert_output -p "to set-string, but found existing array"
36-
}
37-
38-
@test "Error on set-string'ing array in object" {
39-
declare -A SUB_SUB_ARRAY=(omicron pi rho)
40-
declare -A SUB_OBJECT=([nested]=$'\x1C\x1Dtype=array;&SUB_SUB_ARRAY')
41-
declare -A OBJECT=([my_key]=$'\x1C\x1Dtype=object;&SUB_OBJECT')
42-
43-
run bash_object.traverse-set --pass-by-ref string 'OBJECT' '.my_key.nested' 'my_value'
44-
45-
assert_failure
46-
assert_line -p "ERROR_VALUE_INCORRECT_TYPE"
47-
assert_output -p "to set-string, but found existing array"
48-
}
49-
505
@test "Correctly sets string at root" {
516
declare -A OBJECT=()
527
str='my_value'

0 commit comments

Comments
 (0)