Bash · 5236 bytes Raw Blame History
1 #!/bin/sh
2 TEST_PREFIX="[int-expansion]"
3 SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
4 SHELL_BIN="${SHELL_BIN:?ERROR: SHELL_BIN must be set}"
5 export SHELL_BIN
6 . "$SCRIPT_DIR/../test_harness.sh"
7
8 # Integration tests: builtins with parameter, arithmetic, and command substitution
9
10 section "1. parameter expansion with builtins"
11 compare_output "default value" 'X=hello; echo ${X:-default}'
12 compare_output "unset default" 'echo ${UNSET_VAR_XYZ:-fallback}'
13 compare_output "alternate value set" 'X=hello; echo ${X:+alternate}'
14 compare_output "alternate value unset" 'echo ${UNSET_VAR_XYZ:+alternate}'
15 compare_output "prefix strip" 'X=hello; echo ${X#h}'
16 compare_output "prefix strip greedy" 'X=hello; echo ${X##*l}'
17 compare_output "suffix strip" 'X=hello; echo ${X%o}'
18 compare_output "suffix strip greedy" 'X=hello; echo ${X%%l*}'
19 compare_output "substitution" 'X=hello_world; echo ${X/world/earth}'
20 compare_output "substitution global" 'X=ababa; echo ${X//a/x}'
21 compare_output "string length" 'X=hello; echo ${#X}'
22 compare_output "assign default" 'unset ADEF; echo ${ADEF:=assigned}; echo $ADEF'
23 compare_output "substring" 'X=hello; echo ${X:1:3}'
24 compare_output "uppercase" 'X=hello; echo ${X^^}'
25 compare_output "lowercase" 'X=HELLO; echo ${X,,}'
26 compare_output "first char upper" 'X=hello; echo ${X^}'
27 compare_output "first char lower" 'X=HELLO; echo ${X,}'
28
29 section "2. array expansion with builtins"
30 compare_output "all elements" 'arr=(a b c); echo ${arr[@]}'
31 compare_output "element count" 'arr=(a b c); echo ${#arr[@]}'
32 compare_output "index access" 'arr=(a b c); echo ${arr[1]}'
33 compare_output "first element" 'arr=(a b c); echo ${arr[0]}'
34 compare_output "last element" 'arr=(a b c); echo ${arr[-1]}'
35 compare_output "array slice" 'arr=(a b c d e); echo ${arr[@]:1:3}'
36 compare_output "iterate array" 'arr=(a b c); for x in "${arr[@]}"; do echo $x; done'
37 compare_output "array length of element" 'arr=(hello world); echo ${#arr[0]}'
38 compare_output "assoc array access" 'declare -A map; map[key]=value; echo ${map[key]}'
39 compare_output "assoc array keys" 'declare -A m; m[a]=1; m[b]=2; echo ${!m[@]} | tr " " "\n" | sort | tr "\n" " "; echo'
40 compare_output "array append" 'arr=(a b); arr+=(c); echo ${arr[@]}'
41 compare_output "array unset element" 'arr=(a b c); unset arr[1]; echo ${arr[@]}'
42
43 section "3. arithmetic expansion"
44 compare_output "basic add" 'echo $((3 + 4))'
45 compare_output "variable in arithmetic" 'X=5; echo $((X * 2))'
46 compare_output "exponent" 'echo $((2 ** 10))'
47 compare_output "grouping" 'echo $(( (3 + 4) * 2 ))'
48 compare_output "modulo" 'echo $((17 % 5))'
49 compare_output "division" 'echo $((10 / 3))'
50 compare_output "comparison in arithmetic" 'echo $((5 > 3))'
51 compare_output "ternary" 'X=5; echo $(( X > 3 ? 1 : 0 ))'
52 compare_output "increment" 'X=5; echo $((++X)); echo $X'
53 compare_output "decrement" 'X=5; echo $((--X)); echo $X'
54 compare_output "compound assignment" 'X=10; echo $((X += 5)); echo $X'
55 compare_output "bitwise and" 'echo $((12 & 10))'
56 compare_output "bitwise or" 'echo $((12 | 10))'
57 compare_output "left shift" 'echo $((1 << 4))'
58
59 section "4. command substitution"
60 compare_output "basic cmd sub" 'echo "$(echo hello)"'
61 compare_output "nested cmd sub" 'echo "$(echo $(echo nested))"'
62 compare_output "cd in cmd sub" 'X=$(cd /tmp && pwd); echo $X'
63 compare_output "exit status from cmd sub" 'X=$(true); echo $?'
64 compare_output "false status from cmd sub" 'X=$(false); echo $?'
65 compare_output "backtick form" 'echo `echo backtick`'
66 compare_output "cmd sub preserves newlines in var" 'X=$(printf "a\nb"); echo "$X"'
67 compare_output "cmd sub strips trailing newline" 'X=$(echo hello); echo $X'
68 compare_output "cmd sub in arithmetic" 'echo $(( $(echo 3) + $(echo 4) ))'
69 compare_output "nested cmd sub with processing" 'echo $(echo $(echo hello) | tr a-z A-Z)'
70
71 section "5. tilde expansion"
72 compare_output "tilde expands to HOME" 'echo ~ | grep -q / && echo yes'
73 compare_output "tilde with path" 'echo ~/subdir | grep -q / && echo yes'
74 compare_output "cd with tilde" 'cd ~ && echo $? || echo failed'
75
76 section "6. word splitting and IFS"
77 compare_output "IFS colon split" 'IFS=:; read A B C <<< "one:two:three"; echo "$A $B $C"'
78 compare_output "custom IFS in for" 'IFS=,; for x in $(echo "a,b,c"); do echo $x; done'
79 compare_output "word splitting with set" 'X="a b c"; set -- $X; echo $#'
80 compare_output "IFS default splitting" 'X="a b c"; set -- $X; echo $1 $2 $3'
81 compare_output "IFS empty no splitting" 'IFS=""; X="a b c"; set -- $X; echo $#'
82
83 section "7. brace expansion"
84 compare_output "comma brace" 'echo {a,b,c}'
85 compare_output "range brace" 'echo {1..5}'
86 compare_output "range with step" 'echo {1..10..2}'
87 compare_output "brace with prefix" 'echo file.{txt,md,sh}'
88 compare_output "nested brace" 'echo {a,b}{1,2}'
89
90 section "8. quoting interaction"
91 compare_output "double quotes preserve" 'X="hello world"; echo "$X"'
92 compare_output "single quotes literal" 'X="hello world"; echo '"'"'$X'"'"''
93 compare_output "nested quoting in cmd sub" 'echo "$(echo "nested quotes")"'
94 compare_output "escaped dollar" 'echo \$HOME'
95 compare_output "escaped backtick" 'echo \`echo hi\`'
96 compare_output "mixed quoting" "echo 'single' \"double\" plain"
97 compare_output "quote in variable" 'X="it'"'"'s"; echo "$X"'
98
99 print_summary