Files
sausage/userland/brush/source/brush-shell/tests/cases/compat/arrays.yaml
T
2026-11-11 22:04:16 +00:00

501 lines
12 KiB
YAML

name: "Arrays"
incompatible_configs: ["sh"]
common_test_files:
- path: "helpers.sh"
contents: |
stable_print_assoc_array() {
# TODO(nameref): enable use of nameref when implemented; for now
# we assume the name of the array is assoc_array
# local -n assoc_array=$1
local key
for key in $(printf "%s\n" "${!assoc_array[@]}" | sort -n); do
echo "\"${key}\" => ${assoc_array[${key}]}"
done
}
cases:
- name: "Basic indexed array definition and access"
stdin: |
var=(a b c)
echo "var: $var"
echo "var: ${var}"
echo "var[0]: ${var[0]}"
echo "var[1]: ${var[1]}"
echo "var[2]: ${var[2]}"
echo "var[3]: ${var[3]}"
echo "var[4]: ${var[4]}"
echo "var[*]: ${var[*]}"
declare -p var
- name: "Negative indexed array access"
stdin: |
var=(a b c)
echo "var[-1]: ${var[-1]}"
echo "var[-2]: ${var[-2]}"
echo "var[-3]: ${var[-3]}"
- name: "Too large negative indexed array access"
ignore_stderr: true
stdin: |
var=(a b c)
echo "var[-4]: ${var[-4]}"
- name: "Negative indexed array access (set)"
stdin: |
var=(a b c d e f g)
var[-1]=x
var[-3]=z
echo "var[*]: ${var[*]}"
declare -p var
- name: "Too large negative indexed array access (set)"
ignore_stderr: true
stdin: |
var=(a b c)
var[-4]=x
echo "var[*]: ${var[*]}"
declare -p var
- name: "Define array with expansion"
stdin: |
body='a b'
var=($body)
declare -p var
declare -a var2=($body)
declare -p var2
- name: "Arrays with empty values"
stdin: |
var1=(a "" c)
declare -p var1
var2=(a "$nonexistent" c)
declare -p var2
var3=("" "" "")
declare -p var3
- name: "Basic associative array definition and access"
stdin: |
declare -A var=([0]=99 [a]=3 [b]=4 [c]=5)
echo "var: $var"
echo "var: ${var}"
echo "var[0]: ${var[0]}"
echo "var[a]: ${var[a]}"
echo "var[b]: ${var[b]}"
echo "var[c]: ${var[c]}"
echo "var[d]: ${var[d]}"
key="a"
echo "var[key]: ${var[${key}]}"
- name: "Array updating via index"
stdin: |
var=(a b c)
var[1]="d"
echo "var[*]: ${var[*]}"
declare -p var
- name: "Array index assignment"
stdin: |
x=(3 2 1)
y[${x[0]}]=10
y[x[1]]=11
declare -p y
- name: "Arithmetic index assignment on declared-but-unset variable"
stdin: |
declare a
i=1
a[i]=help
declare -p a
- name: "Arithmetic index assignment on local declared-but-unset variable"
stdin: |
f() {
local a
i=1
a[i]=help
declare -p a
}
f
- name: "Arithmetic index assignment on scalar variable"
stdin: |
a=foo
i=1
a[i]=help
declare -p a
- name: "Arithmetic index assignment on undeclared variable"
stdin: |
i=1
a[i]=help
declare -p a
- name: "Replacing array with string"
stdin: |
var=(a b c)
var="x"
echo "var[*]: ${var[*]}"
declare -p var
- name: "Array replacing"
stdin: |
var=(a b c)
var=(d e f)
echo "var[*]: ${var[*]}"
declare -p var
- name: "Appending array to indexed array"
stdin: |
var=(a b c)
var+=(e f g)
echo "var[*]: ${var[*]}"
declare -p var
var+=("" "" "")
declare -p var
var+=(h "i" "$nonexistent" j)
var+=(j k l)
declare -p var
- name: "Appending array to declared-but-unset indexed array"
stdin: |
declare -a var
var+=(e f g)
echo "var[*]: ${var[*]}"
declare -p var
- name: "Appending item to indexed array"
stdin: |
var=(a b c)
var+=d
echo "var[*]: ${var[*]}"
declare -p var
- name: "Appending item to element of indexed array"
stdin: |
declare -a var=(1 2 3)
var[1]+=2
echo "var[*]: ${var[*]}"
declare -p var
- name: "Appending item to element of int indexed array"
stdin: |
declare -ai var=(1 2 3)
var[1]+=2
echo "var[*]: ${var[*]}"
declare -p var
- name: "Appending items to int indexed array"
stdin: |
declare -ai var=(1 2 3)
var+=(4 value 6)
declare -p var
- name: "Appending array to associative array"
stdin: |
source helpers.sh
declare -A assoc_array=([a]=1 [b]=2 [c]=3)
assoc_array+=([d]=4 [e]=5 [f]=6)
stable_print_assoc_array assoc_array
- name: "Appending array to declared-but-unset associative array"
stdin: |
source helpers.sh
declare -A assoc_array
assoc_array+=([d]=4 [e]=5 [f]=6)
stable_print_assoc_array assoc_array
- name: "Appending item to associative array"
stdin: |
source helpers.sh
declare -A assoc_array=([a]=1 [b]=2 [c]=3)
assoc_array+=d
stable_print_assoc_array assoc_array
- name: "Appending item to element of associative array"
stdin: |
source helpers.sh
declare -A assoc_array=([a]=1 [b]=2 [c]=3)
assoc_array[b]+=2
stable_print_assoc_array assoc_array
- name: "Appending item to element of int associative array"
stdin: |
source helpers.sh
declare -Ai assoc_array=([a]=1 [b]=2 [c]=3)
assoc_array[b]+=2
stable_print_assoc_array assoc_array
- name: "Appending items to int associative array"
stdin: |
source helpers.sh
declare -Ai assoc_array=([a]=1 [b]=2 [c]=3)
assoc_array+=([d]=4 [e]=value [f]=6)
stable_print_assoc_array assoc_array
- name: "Appending array to item"
stdin: |
var=x
var+=(a b c)
echo "var[*]: ${var[*]}"
declare -p var
- name: "Fill associative array"
stdin: |
declare -Ag myarray
myfunc() {
local myarg=$1 element
shift
for element in "$@"; do
echo "Setting: myarray[$element]=$myarg"
myarray[$element]="${myarg}${element}"
done
}
myfunc 'first' bunzip2 bzcat pbunzip2 pbzcat lbunzip2 lbzcat
- name: "Declare via array index"
stdin: |
declare -A assoc_array["key"]="value"
declare -p assoc_array
declare -a indexed_array[5]="value"
declare -p indexed_array
declare implicit_array[5]="value"
declare -p implicit_array
declare -A no_value_assoc_array["key"]
declare -p no_value_assoc_array
declare no_value_indexed_array[33]
declare -p no_value_indexed_array
- name: "Create array via index update"
stdin: |
i=0
my_array[i++]="c"
echo "0: i=$i array=${my_array[@]}"
my_array[i++]="b"
echo "1: i=$i array=${my_array[@]}"
my_array[i++]="a"
echo "2: i=$i array=${my_array[@]}"
- name: "Expansion of array body"
stdin: |
elements="a b c"
array1=(${elements})
declare -p array1
array2=("${elements}")
declare -p array2
- name: "Copy array"
stdin: |
src=(a b c)
dest1=("${src[*]}")
declare -p dest1
dest2=(${src[*]})
declare -p dest2
dest3=("${src[@]}")
declare -p dest3
dest4=(${src[@]})
declare -p dest4
- name: "Multi-line definition of array"
stdin: |
array=(
a
b
c
)
declare -p array
- name: "Dump values from non-existent array"
stdin: |
for key in ${NONEXISTENT[@]}; do
echo "@-Key: ${key}"
done
for key in "${NONEXISTENT[@]}"; do
echo "@-Quoted Key: ${key}"
done
for key in ${NONEXISTENT[*]}; do
echo "*-Key: ${key}"
done
for key in "${NONEXISTENT[*]}"; do
echo "*-Quoted Key: ${key}"
done
- name: "Use non-existent var in indexed array index"
stdin: |
declare -a myarray=(10)
echo "Value: ${myarray[$non_existent_var]}"
- name: "Use non-existent var in associative array index"
ignore_stderr: true
stdin: |
declare -A myarray=([0]="default" ["a"]="other")
echo "Value: ${myarray[$non_existent_var]}"
- name: "Nested array reference"
stdin: |
x=(2 3 4)
echo ${x[${x[0]}]}
- name: "Append array-resulting expansion to array"
stdin: |
declare -a otherarray=("a" "b" "c")
declare -a ourarray=()
ourarray+=("${otherarray[@]/a/x}")
declare -p otherarray
declare -p ourarray
- name: "Array declaration in a function"
stdin: |
outer() {
inner=()
if test true; then
echo true
else
echo false
fi
}
outer
- name: "Array element expansion with non-standard IFS"
stdin: |
IFS='|'
declare -a myarray=(abc 1 f)
echo "\"\${myarray[@]}\": ${myarray[@]}"
echo "\"\${myarray[*]}\": ${myarray[*]}"
echo "\${myarray[@]}:" ${myarray[@]}
echo "\${myarray[*]}:" ${myarray[*]}
#
# Field splitting applies to what an expansion produced, not to the literal text around it. A
# compound value's elements are separated by the parser on whitespace; an IFS character sitting
# in literal text is just a character.
#
- name: "Literal text in a compound value is not field-split"
stdin: |
IFS=,
arr=(a,b)
declare -p arr
- name: "A compound value field-splits an expansion but not the literal beside it"
stdin: |
IFS=,
v="p,q"
arr=(a,b $v keep,me)
declare -p arr
- name: "Empty array with newline"
stdin: |
declare -a myarray=(
)
- name: "Parenthesized arithmetic in array index assignment"
known_failure: true # TODO(tokenizer): #1211: '(' inside an assignment's subscript is tokenized as an operator
stdin: |
c[(1)]=x
declare -p c
i=1
d[(i+1)*2]=y
declare -p d
- name: "Compound assignment appends to an element with [key]+="
known_failure: true # TODO(parser): an element's += isn't parsed, so the word is taken as a value
stdin: |
a=(x y)
a+=([0]+=z)
declare -p a
declare -A m=([k]=v)
m+=([k]+=w [j]+=u)
declare -p m
declare -a d=(p q)
declare -a d+=([1]+=r)
declare -p d
- name: "Compound assignment evaluates an indexed array's subscripts"
known_failure: true # TODO(arrays): an element's subscript isn't evaluated as arithmetic
stdin: |
a=([1+1]=x)
declare -p a
i=1
declare -a b=([i+1]=y [i*5]=z)
declare -p b
#
# Ordering between value expansion and subscript evaluation. A shell expands an
# assignment's words before it evaluates any arithmetic subscript, so side effects
# in a subscript are not visible to the value being assigned.
#
- name: "Index arithmetic is evaluated after the value is expanded"
stdin: |
i=0
a[i++]=$i
declare -p a
echo "i=$i"
- name: "Append with an arithmetic subscript"
stdin: |
i=0
a[i++]=$i
a[i++]+=$i
declare -p a
echo "i=$i"
- name: "Associative subscripts are not arithmetically evaluated"
stdin: |
i=0
declare -A m
m[i++]=$i
declare -p m
echo "i=$i"
- name: "Associative subscript is expanded once in a plain assignment"
stdin: |
declare -A m
k='$(echo expanded-twice)'
m[$k]=v
declare -p m
#
# An empty subscript in a parameter reference is rejected while the word is parsed, before any
# array is consulted.
#
- name: "An empty subscript is a bad substitution"
known_failure: true # TODO: the word parser accepts an empty subscript and treats it as element 0
ignore_stderr: true
stdin: |
zz_a=(1 2 3)
echo "[${zz_a[]}]"
echo "status: $?"
- name: "Negative index into sparse indexed array"
stdin: |
b=(a b c d)
b[5]=q
echo "<${b[-2]}> <${b[-1]}>"
b[-2]=Z
b[-1]+=r
declare -p b
unset 'b[-3]'
declare -p b