diff --git a/tests/color.class.sh b/tests/color.class.sh new file mode 100644 index 0000000000000000000000000000000000000000..362078205343127eac90576b64e96e9aca4cd3e9 --- /dev/null +++ b/tests/color.class.sh @@ -0,0 +1,601 @@ +#!/bin/bash +# ====================================================================== +# +# COLORS +# +# a few shell functions for colored output +# +# ---------------------------------------------------------------------- +# License: GPL 3.0 +# Source: <https://github.com/axelhahn/bash_colorfunctions> +# Docs: <https://www.axel-hahn.de/docs/bash_colorfunctions/> +# ---------------------------------------------------------------------- +# 2023-08-09 ahahn 0.1 initial lines +# 2023-08-09 ahahn 0.2 hide output of regex test with grep +# 2023-08-13 ahahn 0.3 introduce of color presets with foreground and background +# 2023-08-13 ahahn 0.4 list presets, debug, count of colors +# 2023-08-13 ahahn 0.5 support of RGB hex code +# 2023-08-14 ahahn 0.6 fix setting fg and bg as RGB hex code +# 2023-08-14 ahahn 0.7 remove color.ansi; respect NO_COLOR=1 +# 2023-08-16 ahahn 0.8 add function color.preset +# ====================================================================== + +_VERSION=0.8 +typeset -i COLOR_DEBUG; COLOR_DEBUG=0 + +# ---------------------------------------------------------------------- +# CONSTANTS +# ---------------------------------------------------------------------- + +declare -A BGCOLOR_CODE +declare -A COLOR_CODE + +# background colors +BGCOLOR_CODE[black]="40" +BGCOLOR_CODE[red]="41" +BGCOLOR_CODE[green]="42" +BGCOLOR_CODE[brown]="43" +BGCOLOR_CODE[blue]="44" +BGCOLOR_CODE[purple]="45" +BGCOLOR_CODE[cyan]="46" +BGCOLOR_CODE[lightgray]="47" +BGCOLOR_CODE[darkgray]="1;40" +BGCOLOR_CODE[lightred]="1;41" +BGCOLOR_CODE[lightgreen]="1;42" +BGCOLOR_CODE[yellow]="1;43" +BGCOLOR_CODE[lightblue]="1;44" +BGCOLOR_CODE[lightpurple]="1;45" +BGCOLOR_CODE[lightcyan]="1;46" +BGCOLOR_CODE[white]="1;47" + +# foreground colors +COLOR_CODE[black]="30" +COLOR_CODE[red]="31" +COLOR_CODE[green]="32" +COLOR_CODE[brown]="33" +COLOR_CODE[blue]="34" +COLOR_CODE[purple]="35" +COLOR_CODE[cyan]="36" +COLOR_CODE[lightgray]="37" +COLOR_CODE[darkgray]="1;30" +COLOR_CODE[lightred]="1;31" +COLOR_CODE[lightgreen]="1;32" +COLOR_CODE[yellow]="1;33" +COLOR_CODE[lightblue]="1;34" +COLOR_CODE[lightpurple]="1;35" +COLOR_CODE[lightcyan]="1;36" +COLOR_CODE[white]="1;37" + +# custom presets as array of foreground and background color +# +# +--- the label is part of the variable +# | +# v +# COLOR_PRESET_error=("white" "red") +# COLOR_PRESET_ok=("white" "green") + +# ---------------------------------------------------------------------- +# PRIVATE FUNCTIONS +# ---------------------------------------------------------------------- + +# write debug output - if debugging is enabled +# Its output is written to STDERR +# param string text to show +function color.__wd(){ + test "$COLOR_DEBUG" = "1" && >&2 echo "DEBUG: $*" +} + +# test, if given value is a known color name +# param string colorname to test +function color.__iscolorname(){ + test -n "${COLOR_CODE[$1]}" && return 0 + return 1 +} + +# test, if given value is a value 0..7 +# param string color to test +function color.__iscolorcode(){ + test "$1" = "0" && return 0 + test "$1" = "1" && return 0 + test "$1" = "2" && return 0 + test "$1" = "3" && return 0 + test "$1" = "4" && return 0 + test "$1" = "5" && return 0 + test "$1" = "6" && return 0 + test "$1" = "7" && return 0 + return 1 +} + +# test, if given value is an ansi code +# param string color to test +function color.__iscolorvalue(){ + if grep -E "^([01];|)[34][0-7]$" >/dev/null <<< "$1" ; then + return 0 + fi + return 1 +} + +# test, if given value is an rgb hexcode eg. #80a0f0 +# param string color to test +function color.__isrgbhex(){ + if grep -iE "^#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$" >/dev/null <<< "$1" ; then + return 0 + fi + return 1 +} + +# convert rgb hex code eg. #80a0f0 to 3 decimal values +# output us a string with space separated values for red, green, blue +# param string color as "#RRGGBB" to convert +function color.__getrgb(){ + local _r + local _g + local _b + if color.__isrgbhex "$1"; then + _r=$( cut -c 2,3 <<< "$1" ) + _g=$( cut -c 4,5 <<< "$1" ) + _b=$( cut -c 6,7 <<< "$1" ) + echo "$((16#$_r)) $((16#$_g)) $((16#$_b))" + fi +} + +# test, if given value is a color that can be one of +# - colorname +# - value 0..7 +# - ansi code +# param string color to test +function color.__isacolor(){ + if color.__iscolorname "$1"; then return 0; fi + if color.__iscolorcode "$1"; then return 0; fi + if color.__iscolorvalue "$1"; then return 0; fi + if color.__isrgbhex "$1"; then return 0; fi + color.__wd "$FUNCNAME is acolor: $1 --> No" + return 1 +} + +# test, if given value is an existing preset +# param string color to test +function color.__isapreset(){ + local _colorset + eval "_colorset=\$COLOR_PRESET_${1}" + test -n "$_colorset" && return 0 + return 1 +} + +# respect NO_COLOR=1 +# return 1 if colors are allowed to be used. +function color.__usecolor(){ + test "$NO_COLOR" = "1" && return 1 + return 0 +} + +# set foreground or background +# param string color as +# - basic color 0..7 OR +# - color name eg. "black" OR +# - a valid color value eg. "1;30" OR +# - a hex code eg. "#10404f" +# param integer what to set; '3' for for foreground or '4' for background colors +function color.__fgorbg(){ + local _color="$1" + local _prefix="$2" + color.__wd "$FUNCNAME $1 $2" + if color.__iscolorname "${_color}"; then + color.__wd "yep, ${_color} is a color name." + test "$_prefix" = "3" && color.set "${COLOR_CODE[${_color}]}" + test "$_prefix" = "4" && color.set "${BGCOLOR_CODE[${_color}]}" + else + if color.__iscolorcode "${_color}"; then + color.__wd "yep, ${_color} is a color code." + else + if color.__iscolorvalue "${_color}"; then + color.__wd "yep, ${_color} is a color value." + color.set "${_color}" + else + if color.__isrgbhex "${_color}"; then + local _r + local _g + local _b + read -r _r _g _b <<< $( color.__getrgb "${_color}" ) + color.set "${_prefix}8;2;$_r;$_g;$_b" + else + >&2 echo "ERROR: color '${_color}' is not a name nor a value between 0..7 nor a valid color value nor RGB." + fi + fi + fi + fi +} + +# ---------------------------------------------------------------------- +# FUNCTIONS :: helpers +# ---------------------------------------------------------------------- + +# get count of colors in the current terminal +function color.count(){ + tput colors +} + +# enable debug flag +function color.debugon(){ + COLOR_DEBUG=1 + color.__wd "$FUNCNAME - debugging is enabled now" +} + +# disable debug flag +function color.debugoff(){ + color.__wd "$FUNCNAME - disabling debugging now" + COLOR_DEBUG=0 +} + +# show debugging status +function color.debugstatus(){ + echo -n "INFO: color.debug - debugging is " + if [ $COLOR_DEBUG -eq 0 ]; then + echo "DISABLED" + else + echo "ENABLED" + fi +} + +# show help +function color.help(){ + local _self; _self='[path]/color.class.sh' + color.reset + local _debug=$COLOR_DEBUG + COLOR_DEBUG=0 + + echo "_______________________________________________________________________________" + echo + color.echo "red" " ### ### # ### ####" + color.echo "yellow" " # # # # # # # #" + color.echo "white" " # # # # # # ####" + color.echo "yellow" " # # # # # # # #" + color.echo "red" " ### ### ##### ### # #" + echo "_________________________________________________________________________/ v$_VERSION" + echo + + sed "s#^ ##g" << EOH + HELP: + 'color' is a class like component to simplify the handling of ansi colors and keeps + the color settings readable. A set NO_COLOR=1 will be respected. + + Author: Axel Hahn + License: GNU GPL 3.0 + Source: <https://github.com/axelhahn/bash_colorfunctions> + Docs: <https://www.axel-hahn.de/docs/bash_colorfunctions/> + + + FUNCTIONS: + + ---------- Information: + + color.help this help + color.list show a table with valid color names + color.presets show a table with defined custom presets + + color.count get count of colors in the current terminal + + color.debugon enable debugging + color.debugoff disable debugging + color.debugstatus show debugstatus + + ---------- Colored output: + + color.bg COLOR (COLOR2) + set a background color; a 2nd parameter is optional to set + a foreground color too + color.fg COLOR (COLOR2) + set a foreground color; a 2nd parameter is optional to set + a background color too + color.preset PRESET + Apply the color set of foreground and background of a given + preset name. + color.echo COLOR|PRESET (COLOR2) TEXT + write a colored text with carriage return and reset colors + The 1st param must be a COLOR(code/ name) for the + foreground or a label of a preset. + The 2nd CAN be a color for the background, but can be + skipped. + Everything behind is text for the output. + color.print COLOR|PRESET (COLOR2) TEXT + see color.echo - the same but without carriage return. + color.reset reset colors + color.set RAWCOLOR (RAWCOLOR2 (... RAWCOLOR_N)) + set ansi colors; it can handle multiple color values + + + ---------- Other: + + color.blink start blinking text + color.bold start bold text + color.invert start inverted text + color.underline start underline text + + VALUES: + COLOR a color; it can be... + - a color keyword, eg black, blue, red, ... for all + known values run 'color.list' + - a value 0..7 to set basic colors 30..37 (or 40..47) + - an ansi color value eg. "30" or "1;42" + - RGB hexcode with '#' as prefix followed by 2 digit + hexcode for red, green and blue eg. "#10404f" + (like css rgb color codes) + PRESET Name of a custom preset; see DEFINE PRESETS below. + RAWCOLOR an ansi color value eg. "30" (black foreground) or + "1;42" (lightgreen background) + + + DEFINE PRESETS: + A shortcut for a combination of foreground + background color. The label + is part of a bash variable with the prefix 'COLOR_PRESET_'. + The value is a bash array with 2 colors for foreground and background. + See the value description for COLOR above. + + SYNTAX: + COLOR_PRESET_<LABEL>=(<FOREGROUND> <BACKGROUND>) + + To see all defined presets use 'color.presets' + + + EXAMPLES: + First you need to source the file $_self. + . $_self + + (1) + Show output of the command 'ls -l' in blue + color.fg "blue" + ls -l + color.reset + + (2) + show a red error message + color.echo "red" "ERROR: Something went wrong." + + (3) + Use a custom preset: + COLOR_PRESET_error=("white" "red") + color.echo "error" "ERROR: Something went wrong." + + This defines a preset named "error". "white" is a colorname + for the foreground color, "red" ist the background. + +EOH + + if [ -n "$NO_COLOR" ]; then + echo -n "INFO: NO_COLOR=$NO_COLOR was set. The coloring functionality is " + if ! color.__usecolor; then + echo "DISBALED." + else + echo "ENABLED (must be 1 to disable)." + fi + echo + else + echo "INFO: NO_COLOR will be respected - but it is not set." + fi + + COLOR_DEBUG=$_debug +} + +# a little helper: show colors and the color codes +function color.list(){ + color.reset + local _debug=$COLOR_DEBUG + COLOR_DEBUG=0 + + echo + echo "List of colors:" + echo + + echo "--------------------------------------------------" + echo "color | foreground | background" + echo "--------------------------------------------------" + for i in "${!COLOR_CODE[@]}" + do + printf "%-15s %4s " $i ${COLOR_CODE[$i]} + color.set "${COLOR_CODE[$i]}" + color.set "40" + printf " Test " + + color.set "1;47" + color.set "${COLOR_CODE[$i]}" + printf " Test " + color.reset + + printf " %5s " ${BGCOLOR_CODE[$i]} + color.set ${BGCOLOR_CODE[$i]} + printf " Test " + color.reset + echo + + done | sort + color.reset + echo "--------------------------------------------------" + echo + COLOR_DEBUG=$_debug +} + +# little helper: sow defined presets and its preview +function color.presets(){ + local _label + local _value + local _colorvar + local _fg + local _bg + + color.reset + local _debug=$COLOR_DEBUG + COLOR_DEBUG=0 + + if ! set | grep "^COLOR_PRESET_.*=(" >/dev/null; then + echo "INFO: No preset was defined yet." + echo "To set one define shell variables with an array of 2 colors:" + echo " COLOR_PRESET_<LABEL>=(<FOREGROUND> <BACKGROUND>)" + echo "For more help call 'color.help' or see the docs." + else + echo + echo "List of presets:" + echo + echo "---------------------------------------------------------------------" + echo "label | foreground | background | example" + echo "---------------------------------------------------------------------" + + set | grep "^COLOR_PRESET_.*=(" | while read -r line + do + _label=$( cut -f 1 -d '=' <<< "$line" | cut -f 3- -d '_') + _example=$( color.print "$_label" "example for peset '$_label'" ) + _colorvar="COLOR_PRESET_${_label}" + eval "_fg=\${$_colorvar[0]}" + eval "_bg=\${$_colorvar[1]}" + + printf "%-10s | %-12s | %-12s | %-50s\n" "$_label" "${_fg}" "${_bg}" "$_example" + done + echo "---------------------------------------------------------------------" + echo + fi + COLOR_DEBUG=$_debug +} +# ---------------------------------------------------------------------- +# FUNCTIONS :: set color +# ---------------------------------------------------------------------- + +# set background color +# param string backround color 0..7 OR color name eg "black" or a valid color value eg "1;30" +# param string optional: foreground color +function color.bg(){ + color.__wd "$FUNCNAME $1" + color.__fgorbg "$1" 4 + test -n "$2" && color.fg "$2" +} + +# get a color of a preset +# param string name of preset +# param integer array index; 0= foreground; 1= background +function color.__getpresetcolor(){ + local _label=$1 + local _index=$2 + local _colorvar + _colorvar="COLOR_PRESET_${_label}" + eval "echo \${$_colorvar[$_index]}" +} + +# set foreground color +# param string foreground color 0..7 OR color name eg "black" or a valid color value eg "1;30" +# param string optional: background color +function color.fg(){ + color.__wd "$FUNCNAME $1" + color.__fgorbg "$1" 3 + test -n "$2" && color.bg "$2" +} + + +# set colors of a preset +# param string label of a preet +function color.preset(){ + if color.__isapreset "$1"; then + local _colorvar + local _colfg=$( color.__getpresetcolor "$1" 0) + local _colbg=$( color.__getpresetcolor "$1" 1) + color.reset + test -n "$_colfg" && color.__fgorbg "$_colfg" 3 + test -n "$_colbg" && color.__fgorbg "$_colbg" 4 + else + >&2 echo "ERROR: this value is not a valid preset: $1. See 'color.presets' to see current presets." + fi +} + +# ---------------------------------------------------------------------- + +# reset all colors to terminal default +function color.reset(){ + color.__wd "$FUNCNAME" + color.set "0" +} + +# start bold text +function color.bold(){ + color.__wd "$FUNCNAME" + color.set "1" +} + +# start underline text +function color.underline(){ + color.__wd "$FUNCNAME" + color.set "4" +} + +# start blinking text +function color.blink(){ + color.__wd "$FUNCNAME" + color.set "5" +} + +# start inverted text +function color.invert(){ + color.__wd "$FUNCNAME" + color.set "7" +} + +# ---------------------------------------------------------------------- + +# write ansicode to set color combination +# param string color 1 as ansi value +# param string color N as ansi value +function color.set(){ + local _out= + if color.__usecolor; then + for mycolor in $* + do + color.__wd "$FUNCNAME: processing color value '${mycolor}'" + _out+="${mycolor}" + done + color.__wd "$FUNCNAME: output is '\e[${_out}m'" + printf "\e[${_out}m" + else + color.__wd "$FUNCNAME: skipping - coloring is disabled." + fi +} + +# ---------------------------------------------------------------------- +# FUNCTIONS :: print +# ---------------------------------------------------------------------- + +# show a colored text WITH carriage return +# param string foreground color as code / name / value +# param string optional: background color as code / name / value +# param string text to print +function color.echo(){ + color.__wd "$FUNCNAME $*" + local _param1="$1" + local _param2="$2" + shift 1 + shift 1 + color.print "$_param1" "$_param2" "$*" + echo +} + +# show a colored text without carriage return +# param string foreground color as code / name / value or preset +# param string optional: background color as code / name / value +# param string text to print +function color.print(){ + color.__wd "$FUNCNAME $*" + if color.__isacolor "$1"; then + if color.__isacolor "$2"; then + color.fg "$1" "$2" + shift 1 + shift 1 + else + color.fg "$1" + shift 1 + fi + elif color.__isapreset "$1"; then + color.preset "$1" + shift 1 + else + >&2 echo -n "ERROR: Wrong color values detected. Command was: colors.print $*" + fi + echo -n "$*" + color.reset +} + +# ====================================================================== diff --git a/tests/example_01_simple_get.sh b/tests/example_01_simple_get.sh new file mode 100755 index 0000000000000000000000000000000000000000..4943e6c5decf841b1439ba861459766a2711fbb8 --- /dev/null +++ b/tests/example_01_simple_get.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# ====================================================================== +# +# REST API CLIENT +# +# Example 1 :: Simple GET request +# This is an introduction, how it works. +# +# ====================================================================== + +cd "$( dirname "$0" )" || exit + +# shellcheck source=../rest-api-client.sh +. ../rest-api-client.sh + +# shellcheck source=color.class.sh +. color.class.sh + +sURL="http://www.iml.unibe.ch/" + +# ---------------------------------------------------------------------- +# FUNCTIONS +# ---------------------------------------------------------------------- + +function wait4Return(){ + + local _sleep + _sleep=${1:-10} # default 10 + echo + echo + color.print "cyan" "Press return to continue or wait $_sleep seconds ... " + read -r -s -t $_sleep dummy + echo + echo + echo +} + + +# ---------------------------------------------------------------------- +# MAIN +# ---------------------------------------------------------------------- + +color.fg "yellow" +cat <<EOH +---------------------------------------------------------------------- + +Example 1 :: Simple GET request +This is a introduction, how it works. + +---------------------------------------------------------------------- + +EOH +color.reset + + +echo "We need to initialize the client with 'http.init' before each new request." +echo +color.echo "green" "> http.init" +http.init + +wait4Return 10 + +echo "Let's make a GET request to our example url $sURL." +echo +color.echo "green" "> http.makeRequest GET '$sURL'" +http.makeRequest GET "$sURL" +echo "Done." +echo "Here is no output." +echo "Now we can read information from the response." + +wait4Return 10 + +color.echo "green" "> http.getStatuscode - This returns the Http status code" +http.getStatuscode +echo +sleep 1 + +color.echo "green" "> http.getStatus - You get the Status as string OK|Redirect|Error" +http.getStatus +echo +sleep 1 + +color.echo "green" "> http.getResponseHeader - print Http response header" +http.getResponseHeader +echo +sleep 1 + +color.echo "green" "> http.getResponseData - get data from curl" +http.getResponseData +echo +sleep 1 + +color.echo "green" "> http.getResponse - get response body" +http.getResponse +echo +sleep 1 + +echo +echo "That's all for the moment. Bye." + +# ---------------------------------------------------------------------- \ No newline at end of file