Skip to content

Commit 8538868

Browse files
authored
Merge pull request sstephenson#8 from bats-core/mbland-optimized
Fix macOS/Bash 3.2 breakage; eliminate subshells from exec-test, preprocess
2 parents 55bf719 + ebb192e commit 8538868

9 files changed

+156
-87
lines changed

libexec/bats

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,35 +26,58 @@ help() {
2626
echo
2727
}
2828

29+
BATS_READLINK=
30+
2931
resolve_link() {
30-
$(type -p greadlink readlink | head -1) "$1"
32+
if [[ -z "$BATS_READLINK" ]]; then
33+
if command -v 'greadlink' >/dev/null; then
34+
BATS_READLINK='greadlink'
35+
elif command -v 'readlink' >/dev/null; then
36+
BATS_READLINK='readlink'
37+
else
38+
BATS_READLINK='true'
39+
fi
40+
fi
41+
"$BATS_READLINK" "$1" || return 0
3142
}
3243

3344
abs_dirname() {
34-
local cwd="$(pwd)"
45+
local cwd="$PWD"
3546
local path="$1"
3647

3748
while [ -n "$path" ]; do
3849
cd "${path%/*}"
3950
local name="${path##*/}"
40-
path="$(resolve_link "$name" || true)"
51+
path="$(resolve_link "$name")"
4152
done
4253

43-
pwd
54+
printf -v "$2" -- '%s' "$PWD"
4455
cd "$cwd"
4556
}
4657

4758
expand_path() {
48-
{ cd "$(dirname "$1")" 2>/dev/null
49-
local dirname="$PWD"
59+
local path="${1%/}"
60+
local dirname="${path%/*}"
61+
62+
if [[ "$dirname" == "$path" ]]; then
63+
dirname="$PWD"
64+
elif cd "$dirname" 2>/dev/null; then
65+
dirname="$PWD"
5066
cd "$OLDPWD"
51-
echo "$dirname/$(basename "$1")"
52-
} || echo "$1"
67+
else
68+
printf '%s' "$path"
69+
return
70+
fi
71+
printf -v "$2" '%s/%s' "$dirname" "${path##*/}"
5372
}
5473

55-
BATS_LIBEXEC="$(abs_dirname "$0")"
56-
export BATS_PREFIX="$(abs_dirname "$BATS_LIBEXEC")"
57-
export BATS_CWD="$(abs_dirname .)"
74+
abs_dirname "$0" 'BATS_LIBEXEC'
75+
abs_dirname "$BATS_LIBEXEC" 'BATS_PREFIX'
76+
abs_dirname '.' 'BATS_CWD'
77+
78+
export BATS_PREFIX
79+
export BATS_CWD
80+
export BATS_TEST_PATTERN='^ *@test +(.+) +\{ *(.*)$'
5881
export PATH="$BATS_LIBEXEC:$PATH"
5982

6083
options=()
@@ -113,14 +136,16 @@ fi
113136

114137
filenames=()
115138
for filename in "${arguments[@]}"; do
139+
expand_path "$filename" 'filename'
140+
116141
if [ -d "$filename" ]; then
117142
shopt -s nullglob
118-
for suite_filename in "$(expand_path "$filename")"/*.bats; do
143+
for suite_filename in "$filename"/*.bats; do
119144
filenames["${#filenames[@]}"]="$suite_filename"
120145
done
121146
shopt -u nullglob
122147
else
123-
filenames["${#filenames[@]}"]="$(expand_path "$filename")"
148+
filenames["${#filenames[@]}"]="$filename"
124149
fi
125150
done
126151

@@ -130,13 +155,11 @@ else
130155
command="bats-exec-suite"
131156
fi
132157

133-
if [ -n "$pretty" ]; then
158+
set -o pipefail execfail
159+
if [ -z "$pretty" ]; then
160+
exec "$command" $count_flag "${filenames[@]}"
161+
else
134162
extended_syntax_flag="-x"
135163
formatter="bats-format-tap-stream"
136-
else
137-
extended_syntax_flag=""
138-
formatter="cat"
164+
exec "$command" $count_flag $extended_syntax_flag "${filenames[@]}" | "$formatter"
139165
fi
140-
141-
set -o pipefail execfail
142-
exec "$command" $count_flag $extended_syntax_flag "${filenames[@]}" | "$formatter"

libexec/bats-exec-suite

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ trap "kill 0; exit 1" int
1717

1818
count=0
1919
for filename in "$@"; do
20-
let count+="$(bats-exec-test -c "$filename")"
20+
while IFS= read -r line; do
21+
if [[ "$line" =~ $BATS_TEST_PATTERN ]]; then
22+
let count+=1
23+
fi
24+
done <"$filename"
2125
done
2226

2327
if [ -n "$count_only_flag" ]; then

libexec/bats-exec-test

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ else
2626
shift
2727
fi
2828

29-
BATS_TEST_DIRNAME="$(dirname "$BATS_TEST_FILENAME")"
29+
BATS_TEST_DIRNAME="${BATS_TEST_FILENAME%/*}"
3030
BATS_TEST_NAMES=()
3131

3232
load() {
@@ -39,10 +39,10 @@ load() {
3939
filename="$BATS_TEST_DIRNAME/${name}.bash"
4040
fi
4141

42-
[ -f "$filename" ] || {
42+
if [[ ! -f "$filename" ]]; then
4343
echo "bats: $filename does not exist" >&2
4444
exit 1
45-
}
45+
fi
4646

4747
source "${filename}"
4848
}
@@ -101,39 +101,42 @@ bats_capture_stack_trace() {
101101
local teardown_pattern=" teardown $BATS_TEST_SOURCE"
102102

103103
local frame
104-
local index=1
104+
local i
105105

106-
while frame="$(caller "$index")"; do
106+
for ((i=2; i != ${#FUNCNAME[@]}; ++i)); do
107+
frame="${BASH_LINENO[$((i-1))]} ${FUNCNAME[$i]} ${BASH_SOURCE[$i]}"
107108
BATS_CURRENT_STACK_TRACE["${#BATS_CURRENT_STACK_TRACE[@]}"]="$frame"
108109
if [[ "$frame" = *"$test_pattern" || \
109110
"$frame" = *"$setup_pattern" || \
110111
"$frame" = *"$teardown_pattern" ]]; then
111112
break
112-
else
113-
let index+=1
114113
fi
115114
done
116115

117-
BATS_SOURCE="$(bats_frame_filename "${BATS_CURRENT_STACK_TRACE[0]}")"
118-
BATS_LINENO="$(bats_frame_lineno "${BATS_CURRENT_STACK_TRACE[0]}")"
116+
bats_frame_filename "${BATS_CURRENT_STACK_TRACE[0]}" 'BATS_SOURCE'
117+
bats_frame_lineno "${BATS_CURRENT_STACK_TRACE[0]}" 'BATS_LINENO'
119118
}
120119

121120
bats_print_stack_trace() {
122121
local frame
123122
local index=1
124123
local count="${#@}"
124+
local filename
125+
local lineno
125126

126127
for frame in "$@"; do
127-
local filename="$(bats_trim_filename "$(bats_frame_filename "$frame")")"
128-
local lineno="$(bats_frame_lineno "$frame")"
128+
bats_frame_filename "$frame" 'filename'
129+
bats_trim_filename "$filename" 'filename'
130+
bats_frame_lineno "$frame" 'lineno'
129131

130132
if [ $index -eq 1 ]; then
131133
echo -n "# ("
132134
else
133135
echo -n "# "
134136
fi
135137

136-
local fn="$(bats_frame_function "$frame")"
138+
local fn
139+
bats_frame_function "$frame" 'fn'
137140
if [ "$fn" != "$BATS_TEST_NAME" ]; then
138141
echo -n "from function \`$fn' "
139142
fi
@@ -151,12 +154,16 @@ bats_print_stack_trace() {
151154
bats_print_failed_command() {
152155
local frame="$1"
153156
local status="$2"
154-
local filename="$(bats_frame_filename "$frame")"
155-
local lineno="$(bats_frame_lineno "$frame")"
157+
local filename
158+
local lineno
159+
local failed_line
160+
local failed_command
156161

157-
local failed_line="$(bats_extract_line "$filename" "$lineno")"
158-
local failed_command="$(bats_strip_string "$failed_line")"
159-
echo -n "# \`${failed_command}' "
162+
bats_frame_filename "$frame" 'filename'
163+
bats_frame_lineno "$frame" 'lineno'
164+
bats_extract_line "$filename" "$lineno" 'failed_line'
165+
bats_strip_string "$failed_line" 'failed_command'
166+
printf '%s' "# \`${failed_command}' "
160167

161168
if [ $status -eq 1 ]; then
162169
echo "failed"
@@ -166,49 +173,46 @@ bats_print_failed_command() {
166173
}
167174

168175
bats_frame_lineno() {
169-
local frame="$1"
170-
local lineno="${frame%% *}"
171-
echo "$lineno"
176+
printf -v "$2" '%s' "${1%% *}"
172177
}
173178

174179
bats_frame_function() {
175-
local frame="$1"
176-
local rest="${frame#* }"
177-
local fn="${rest%% *}"
178-
echo "$fn"
180+
local __bff_function="${1#* }"
181+
printf -v "$2" '%s' "${__bff_function%% *}"
179182
}
180183

181184
bats_frame_filename() {
182-
local frame="$1"
183-
local rest="${frame#* }"
184-
local filename="${rest#* }"
185+
local __bff_filename="${1#* }"
186+
__bff_filename="${__bff_filename#* }"
185187

186-
if [ "$filename" = "$BATS_TEST_SOURCE" ]; then
187-
echo "$BATS_TEST_FILENAME"
188-
else
189-
echo "$filename"
188+
if [ "$__bff_filename" = "$BATS_TEST_SOURCE" ]; then
189+
__bff_filename="$BATS_TEST_FILENAME"
190190
fi
191+
printf -v "$2" '%s' "$__bff_filename"
191192
}
192193

193194
bats_extract_line() {
194-
local filename="$1"
195-
local lineno="$2"
196-
sed -n "${lineno}p" "$filename"
195+
local __bats_extract_line_line
196+
local __bats_extract_line_index='0'
197+
198+
while IFS= read -r __bats_extract_line_line; do
199+
if [[ "$((++__bats_extract_line_index))" -eq "$2" ]]; then
200+
printf -v "$3" '%s' "${__bats_extract_line_line%$'\r'}"
201+
break
202+
fi
203+
done <"$1"
197204
}
198205

199206
bats_strip_string() {
200-
local string="$1"
201-
printf "%s" "$string" | sed -e "s/^[ "$'\t'"]*//" -e "s/[ "$'\t'"]*$//"
207+
[[ "$1" =~ ^[[:space:]]*(.*)[[:space:]]*$ ]]
208+
printf -v "$2" '%s' "${BASH_REMATCH[1]}"
202209
}
203210

204211
bats_trim_filename() {
205-
local filename="$1"
206-
local length="${#BATS_CWD}"
207-
208-
if [ "${filename:0:length+1}" = "${BATS_CWD}/" ]; then
209-
echo "${filename:length+1}"
212+
if [[ "$1" =~ ^${BATS_CWD}/ ]]; then
213+
printf -v "$2" '%s' "${1#$BATS_CWD/}"
210214
else
211-
echo "$filename"
215+
printf -v "$2" '%s' "$1"
212216
fi
213217
}
214218

@@ -289,7 +293,7 @@ bats_perform_tests() {
289293

290294
bats_perform_test() {
291295
BATS_TEST_NAME="$1"
292-
if [ "$(type -t "$BATS_TEST_NAME" || true)" = "function" ]; then
296+
if declare -F "$BATS_TEST_NAME" >/dev/null; then
293297
BATS_TEST_NUMBER="$2"
294298
if [ -z "$BATS_TEST_NUMBER" ]; then
295299
echo "1..1"
@@ -322,7 +326,7 @@ BATS_OUT="${BATS_TMPNAME}.out"
322326

323327
bats_preprocess_source() {
324328
BATS_TEST_SOURCE="${BATS_TMPNAME}.src"
325-
{ tr -d '\r' < "$BATS_TEST_FILENAME"; echo; } | bats-preprocess > "$BATS_TEST_SOURCE"
329+
. bats-preprocess <<< "$(< "$BATS_TEST_FILENAME")"$'\n' > "$BATS_TEST_SOURCE"
326330
trap "bats_cleanup_preprocessed_source" err exit
327331
trap "bats_cleanup_preprocessed_source; exit 1" int
328332
}

libexec/bats-format-tap-stream

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,15 @@ log() {
6565
}
6666

6767
summary() {
68-
printf "\n%d test%s" "$count" "$(plural "$count")"
68+
printf "\n%d test" "$count"
69+
if [[ "$count" -ne '1' ]]; then
70+
printf 's'
71+
fi
6972

70-
printf ", %d failure%s" "$failures" "$(plural "$failures")"
73+
printf ", %d failure" "$failures"
74+
if [[ "$failures" -ne '1' ]]; then
75+
printf 's'
76+
fi
7177

7278
if [ "$skipped" -gt 0 ]; then
7379
printf ", %d skipped" "$skipped"
@@ -79,7 +85,9 @@ summary() {
7985
printf_with_truncation() {
8086
local width="$1"
8187
shift
82-
local string="$(printf "$@")"
88+
local string
89+
90+
printf -v 'string' -- "$@"
8391

8492
if [ "${#string}" -gt "$width" ]; then
8593
printf "%s..." "${string:0:$(( $width - 4 ))}"
@@ -105,18 +113,18 @@ advance() {
105113

106114
set_color() {
107115
local color="$1"
108-
local weight="$2"
109-
printf "\x1B[%d;%dm" $(( 30 + $color )) "$( [ "$weight" = "bold" ] && echo 1 || echo 22 )"
116+
local weight='22'
117+
118+
if [[ "$2" == 'bold' ]]; then
119+
weight='1'
120+
fi
121+
printf "\x1B[%d;%dm" $(( 30 + $color )) "$weight"
110122
}
111123

112124
clear_color() {
113125
printf "\x1B[0m"
114126
}
115127

116-
plural() {
117-
[ "$1" -eq 1 ] || echo "s"
118-
}
119-
120128
_buffer=""
121129

122130
buffer() {

0 commit comments

Comments
 (0)