Search code examples
bashtestingbats-core

How to test formatting in Bash 5 with Bats Core?


Trying to get into Shell testing with Bash (5.1.16), using Bats Core. I ran into an issue while trying to test formatting, and already spent 2 hours on it. 🤯

In this test I want to make sure that the text is formatted red.

@test "Message with title only, format 'list', style 'error'" {
  run message \
    --title="Message Title" \
    --format="list" \
    --style="error"

  # echo "${lines[@]}" > foobar.sh

  assert_line --index 0 -p '[31m      [✖] Message Title (B[m'
}

If I dump the Bats Core result lines to a file with echo "${lines[@]}" > foobar.sh I get:

[31m      [✖] Message Title (B[m

StackOverflow does not show the escapes. Here is how it is in IntelliJ

2

I don't understand why this does not work, while the following in other tests work.

  [[ "${output}" == "[30mHello World.(B[m How are you?" ]] # also with ESC in IntelliJ

Edit: I assume the underlying code to work, because the output is correct. However, here the underlying code for message() from sourced file 1:


# arguments and stuff here
if is_false "${no_icons:-}" && is_present "${icon:-}"; then
  output_string="      [${icon}] "
  unset spaces
fi

output_string="$output_string${spaces:-}${title:-}\n"

text_red "${output_string:-}"

if is_blank "${message:-}"; then
  return
fi

echo "$message" | while read -r line; do

  # Indirect color function call     # Trim whitespaces from line beginning
  text_red "      $(echo -e "${line}" | sed -e 's/^[[:space:]]*//')\n"

done

Here the coloring functions from sourced file 2:

  function _print_foreground_color() {
    printf "%b" "$(tput setaf "${2:-}" 2>/dev/null)" "${1:-}" "$(tput sgr0 2>/dev/null)"
  }

  function text_red() {
    _print_foreground_color "${1:-}" 1
  }

My questions:

  1. What am I doing wrong?
  2. What is the best way to, with Bats Core, test formatting?

Any help would be much appreciated!


Solution

  • You can use printf "%q" to get the value you want to test :

    #!/usr/bin/env bash
       
    function _print_foreground_color() {
        printf "%b" "$(tput setaf "${2:-}" 2>/dev/null)" "${1:-}" "$(tput sgr0 2>/dev/null)"
    } 
    
    function text_red() {
        _print_foreground_color "${1:-}" 1
    } 
    
    text_red alert; echo
    # Output :
    # alert in red
    
    printf "%q\n" "$(text_red alert)"
    # Output :
    # $'\E[31malert\E(B\E[m'
    
    if test "$(text_red alert)" = $'\E[31malert\E(B\E[m'; then
        echo "Compared successfully"
    fi
    # Output :
    # Compared successfully