diff --git a/.travis.yml b/.travis.yml index 64e1c52..60d8fd7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,3 +5,4 @@ os: script: - shellcheck -s bash --exclude=SC2034,SC2154 <(awk '/```sh/{f=1;next}/```/{f=0}f' README.md) + - ./test.sh diff --git a/README.md b/README.md index fb0c73a..c8ccc04 100644 --- a/README.md +++ b/README.md @@ -102,8 +102,8 @@ scripts and not full blown utilities. ### Trim leading and trailing white-space from string. ```sh -trim() { - # Usage: trim " example string " +trim_string() { + # Usage: trim_string " example string " : "${1#"${1%%[![:space:]]*}"}" : "${_%"${_##*[![:space:]]}"}" printf '%s\n' "$_" @@ -114,7 +114,7 @@ trim() { ```sh # shellcheck disable=SC2086,SC2048 -trim() { +trim_all() { # Usage: trim " example string " set -f set -- $* @@ -226,10 +226,8 @@ reverse_array() { # Usage: reverse_array "array" # reverse_array 1 2 3 4 5 6 shopt -s extdebug - f()(printf '%s ' "${BASH_ARGV[@]}"); f "$@" + f()(printf '%s\n' "${BASH_ARGV[@]}"); f "$@" shopt -u extdebug - - printf '\n' } ``` @@ -547,7 +545,7 @@ _() { # Undocumented method. # Note: This is commented to make shellcheck play nice. - for i in {1..10};{ echo "$i";} + # for i in {1..10};{ echo "$i";} # Expansion. for i in {1..10}; do echo "$i"; done @@ -586,9 +584,10 @@ _() { f()(($1)) # Using tests, loops etc. - # Note: You can also use ‘while’, ‘until’, ‘case’, ‘(())’, ‘[[]]’. - f()if true; then echo "$1"; fi - f()for i in "$@"; do echo "$i"; done + # NOTE: You can also use ‘while’, ‘until’, ‘case’, ‘(())’, ‘[[]]’. + # NOTE: These are commented to make shellcheck play nice. + # f()if true; then echo "$1"; fi + # f()for i in "$@"; do echo "$i"; done } ``` diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..32a301f --- /dev/null +++ b/test.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +# +# Tests for the Pure Bash Bible. + +test_trim_string() { + result="$(trim_string " Hello, World ")" + assert_equals "$result" "Hello, World" +} + +test_trim_all() { + result="$(trim_all " Hello, World ")" + assert_equals "$result" "Hello, World" +} + +test_lower() { + result="$(lower "HeLlO")" + assert_equals "$result" "hello" +} + +test_upper() { + result="$(upper "HeLlO")" + assert_equals "$result" "HELLO" +} + +test_trim_quotes() { + result="$(trim_quotes "\"te'st' 'str'ing\"")" + assert_equals "$result" "test string" +} + +test_lstrip() { + result="$(lstrip "!:IHello" "!:I")" + assert_equals "$result" "Hello" +} + +test_rstrip() { + result="$(rstrip "Hello!:I" "!:I")" + assert_equals "$result" "Hello" +} + +test_reverse_array() { + IFS=$'\n' read -d "" -ra result < <(reverse_array 1 2 3 4 5) + assert_equals "${result[*]}" "5 4 3 2 1" +} + +test_remove_array_dups() { + IFS=$'\n' read -d "" -ra result < <(remove_array_dups 1 1 2 2 3 3 4 5) + assert_equals "${result[*]}" "1 2 3 4 5" +} + +test_cycle() { + # shellcheck disable=2034 + arr=(a b c d) + result="$(cycle; cycle; cycle)" + assert_equals "$result" "a b c " +} + +test_head() { + printf '%s\n%s\n\n\n' "hello" "world" > test_file + result="$(head 2 test_file)" + assert_equals "$result" $'hello\nworld' + rm test_file +} + +test_tail() { + printf '\n\n\n%s\n%s\n' "hello" "world" > test_file + result="$(tail 2 test_file)" + assert_equals "$result" $'hello\nworld' + rm test_file +} + +test_count() { + result="$(count ./{README.m,LICENSE.m,.travis.ym}*)" + assert_equals "$result" "3" +} + +test_dirname() { + result="$(dirname "/home/black/Pictures/Wallpapers/1.jpg")" + assert_equals "$result" "/home/black/Pictures/Wallpapers/" +} + +test_basename() { + result="$(basename "/home/black/Pictures/Wallpapers/1.jpg")" + assert_equals "$result" "1.jpg" +} + +test_hex_to_rgb() { + result="$(hex_to_rgb "#FFFFFF")" + assert_equals "$result" "255 255 255" +} + +test_rgb_to_hex() { + result="$(rgb_to_hex 0 0 0)" + assert_equals "$result" "#000000" +} + +test_date() { + result="$(date "%C")" + assert_equals "$result" "20" +} + +assert_equals() { + local status + ((tests+=1)) + + [[ "$1" == "$2" ]] && status="✔" + printf '%s\n' " ${status:-✖} | ${FUNCNAME[1]/test_}" + + if [[ "$1" == "$2" ]]; then + ((pass+=1)) + return 0 + else + :>/tmp/err + ((err+=1)) + return 1 + fi +} + +main() { + source <(awk '/```sh/{f=1;next}/```/{f=0}f' README.md) 2>/dev/null + + head="-> Running tests on the Pure Bash Bible.." + printf '\n%s\n%s\n' "$head" "${head//?/-}" + + test_trim_string + test_trim_all + test_lower + test_upper + test_trim_quotes + test_lstrip + test_rstrip + test_reverse_array + test_remove_array_dups + test_cycle + test_head + test_tail + test_count + test_dirname + test_basename + test_hex_to_rgb + test_rgb_to_hex + test_date + + comp="Completed $tests tests. ${pass:-0} passed, ${err:-0} errored." + printf '%s\n%s\n\n' "${comp//?/-}" "$comp" + + [[ -f /tmp/err ]] || exit 0 && { rm /tmp/err; exit 1; } +} + +main "$@"