| #!/usr/bin/env bash |
| set -e |
| |
| bats_encode_test_name() { |
| local name="$1" |
| local result='test_' |
| local hex_code |
| |
| if [[ ! "$name" =~ [^[:alnum:]\ _-] ]]; then |
| name="${name//_/-5f}" |
| name="${name//-/-2d}" |
| name="${name// /_}" |
| result+="$name" |
| else |
| local length="${#name}" |
| local char i |
| |
| for ((i = 0; i < length; i++)); do |
| char="${name:$i:1}" |
| if [[ "$char" == ' ' ]]; then |
| result+='_' |
| elif [[ "$char" =~ [[:alnum:]] ]]; then |
| result+="$char" |
| else |
| printf -v 'hex_code' -- '-%02x' \'"$char" |
| result+="$hex_code" |
| fi |
| done |
| fi |
| |
| printf -v "$2" '%s' "$result" |
| } |
| |
| BATS_TEST_PATTERN="^[[:blank:]]*@test[[:blank:]]+(.*[^[:blank:]])[[:blank:]]+\{(.*)\$" |
| BATS_TEST_PATTERN_COMMENT="[[:blank:]]*([^[:blank:]()]+)[[:blank:]]*\(?\)?[[:blank:]]+\{[[:blank:]]+#[[:blank:]]*@test[[:blank:]]*\$" |
| BATS_COMMENT_COMMAND_PATTERN="^[[:blank:]]*#[[:blank:]]*bats[[:blank:]]+(.*)$" |
| BATS_VALID_TAG_PATTERN="[-_:[:alnum:]]+" |
| BATS_VALID_TAGS_PATTERN="^ *($BATS_VALID_TAG_PATTERN)?( *, *$BATS_VALID_TAG_PATTERN)* *$" |
| |
| # shellcheck source=lib/bats-core/common.bash |
| source "$BATS_ROOT/lib/bats-core/common.bash" |
| |
| extract_tags() { # <tag_type/return_var> <tags-string> |
| local -r tag_type=$1 tags_string=$2 |
| local -a tags=() |
| |
| if [[ $tags_string =~ $BATS_VALID_TAGS_PATTERN ]]; then |
| IFS=, read -ra tags <<<"$tags_string" |
| local -ri length=${#tags[@]} |
| for ((i = 0; i < length; ++i)); do |
| local element="tags[$i]" |
| bats_trim "$element" "${!element}" 2>/dev/null # printf on bash 3 will complain but work anyways |
| if [[ -z "${!element}" && -n "${CHECK_BATS_COMMENT_COMMANDS:-}" ]]; then |
| printf "%s:%d: Error: Invalid %s: '%s'. " "$test_file" "$line_number" "$tag_type" "$tags_string" |
| printf "Tags must not be empty. Please remove redundant commas!\n" |
| exit_code=1 |
| fi |
| done |
| elif [[ -n "${CHECK_BATS_COMMENT_COMMANDS:-}" ]]; then |
| printf "%s:%d: Error: Invalid %s: '%s'. " "$test_file" "$line_number" "$tag_type" "$tags_string" |
| printf "Valid tags must match %s and be separated with comma (and optional spaces)\n" "$BATS_VALID_TAG_PATTERN" |
| exit_code=1 |
| fi >&2 |
| if ((${#tags[@]} > 0)); then |
| eval "$tag_type=(\"\${tags[@]}\")" |
| else |
| eval "$tag_type=()" |
| fi |
| } |
| |
| test_file="$1" |
| tests=() |
| test_tags=() |
| # shellcheck disable=SC2034 # used in `bats_sort tags`/`extract_tags`` |
| file_tags=() |
| line_number=0 |
| exit_code=0 |
| { |
| while IFS= read -r line; do |
| ((++line_number)) |
| line="${line//$'\r'/}" |
| if [[ "$line" =~ $BATS_TEST_PATTERN ]] || [[ "$line" =~ $BATS_TEST_PATTERN_COMMENT ]]; then |
| name="${BASH_REMATCH[1]#[\'\"]}" |
| name="${name%[\'\"]}" |
| body="${BASH_REMATCH[2]:-}" |
| bats_encode_test_name "$name" 'encoded_name' |
| printf '%s() { bats_test_begin "%s"; %s\n' "${encoded_name:?}" "$name" "$body" || : |
| |
| bats_append_arrays_as_args \ |
| test_tags file_tags \ |
| -- bats_sort tags |
| if [[ -z "$BATS_TEST_FILTER" || "$name" =~ $BATS_TEST_FILTER ]]; then |
| IFS=, |
| tests+=("--tags '${tags[*]-}' $encoded_name") |
| fi |
| # shellcheck disable=SC2034 # used in `bats_sort tags`/`extract_tags` |
| test_tags=() # reset test tags for next test |
| else |
| if [[ "$line" =~ $BATS_COMMENT_COMMAND_PATTERN ]]; then |
| command=${BASH_REMATCH[1]} |
| case $command in |
| 'test_tags='*) |
| extract_tags test_tags "${command#test_tags=}" |
| ;; |
| 'file_tags='*) |
| extract_tags file_tags "${command#file_tags=}" |
| ;; |
| esac |
| fi |
| printf '%s\n' "$line" |
| fi |
| done |
| } <<<"$(<"$test_file")"$'\n' |
| |
| for test_name in "${tests[@]}"; do |
| printf 'bats_test_function %s\n' "$test_name" |
| done |
| |
| exit $exit_code |