Added sessions
This commit is contained in:
parent
b8a8b0e258
commit
29d58016e0
24
run_tests.sh
24
run_tests.sh
@ -1,10 +1,24 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source "$(dirname "$0")/src/exprash.sh";
|
file_dir="$(dirname "$0")"
|
||||||
|
|
||||||
source "$(dirname "$0")/tests/utils.sh";
|
source "$file_dir/src/exprash.sh"
|
||||||
|
|
||||||
printf '%s\n' "Routes:";
|
source "$file_dir/tests/utils.sh"
|
||||||
source "$(dirname "$0")/tests/routes.sh";
|
|
||||||
|
printf '%s\n' "Routes:"
|
||||||
|
source "$file_dir/tests/routes.sh"
|
||||||
|
printf '\n'
|
||||||
|
|
||||||
|
printf '%s\n' "Query String:"
|
||||||
|
source "$file_dir/tests/query.sh"
|
||||||
|
printf '\n'
|
||||||
|
|
||||||
|
printf '%s\n' "Cookies:"
|
||||||
|
source "$file_dir/tests/cookies.sh"
|
||||||
|
printf '\n'
|
||||||
|
|
||||||
|
printf '%s\n' "Session:"
|
||||||
|
source "$file_dir/tests/session.sh"
|
||||||
|
printf '\n'
|
||||||
|
|
||||||
printf '\n';
|
|
||||||
testSummary;
|
testSummary;
|
||||||
|
224
src/exprash.sh
224
src/exprash.sh
@ -1,5 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# shellcheck disable=SC2034 # false flags nameref params
|
# shellcheck disable=SC2034 # false flags nameref params
|
||||||
|
# shellcheck disable=SC2178 # false flags nameref params
|
||||||
|
|
||||||
# ======================
|
# ======================
|
||||||
# Required shell options
|
# Required shell options
|
||||||
@ -172,6 +173,12 @@ function lenQuery() {
|
|||||||
_multiLen _exprashQuery "$1"
|
_multiLen _exprashQuery "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Call this function to parse URLencoded request bodies
|
||||||
|
function useBody() {
|
||||||
|
if [[ "${HTTP_CONTENT_TYPE,,}" == "application/x-www-form-urlencoded" ]]; then
|
||||||
|
_parseUrlEncoded _exprashBody
|
||||||
|
fi
|
||||||
|
}
|
||||||
# $1: key
|
# $1: key
|
||||||
# $2: (optional) index for accessing array parameters
|
# $2: (optional) index for accessing array parameters
|
||||||
function body() {
|
function body() {
|
||||||
@ -186,11 +193,18 @@ function lenBody() {
|
|||||||
_multiLen _exprashBody "$1"
|
_multiLen _exprashBody "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Call this function to parse URLencoded request bodies
|
# $1: key
|
||||||
function bodyParser() {
|
function cookie() {
|
||||||
if [[ "${HTTP_CONTENT_TYPE,,}" == "application/x-www-form-urlencoded" ]]; then
|
printf '%s' "${_exprashCookies[$1]}"
|
||||||
_parseUrlEncoded _exprashBody
|
}
|
||||||
fi
|
# $1: key
|
||||||
|
function hasCookie() {
|
||||||
|
[[ -v "_exprashCookies[$1]" ]]
|
||||||
|
}
|
||||||
|
# $1: key
|
||||||
|
# $2: value
|
||||||
|
function setCookie() {
|
||||||
|
_exprashSetCookies["$1"]="$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==================
|
# ==================
|
||||||
@ -240,9 +254,48 @@ function sendHeaders() {
|
|||||||
[ "$key" == 'Content-Type' ] && continue
|
[ "$key" == 'Content-Type' ] && continue
|
||||||
printf '%s\n' "${key}: ${_exprashHeaders[$key]}" | _sendRaw
|
printf '%s\n' "${key}: ${_exprashHeaders[$key]}" | _sendRaw
|
||||||
done;
|
done;
|
||||||
|
for key in "${!_exprashSetCookies[@]}"; do
|
||||||
|
printf '%s\n' "Set-Cookie: ${key}=${_exprashSetCookies[$key]}" | _sendRaw
|
||||||
|
done;
|
||||||
printf '\n' | _sendRaw
|
printf '\n' | _sendRaw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# =======
|
||||||
|
# Session
|
||||||
|
# =======
|
||||||
|
|
||||||
|
# Call this function to automatically manage sessions
|
||||||
|
# $1: (optional) session dir, defaults to "session" in the current directory
|
||||||
|
function useSession() {
|
||||||
|
local session_dir=$1
|
||||||
|
|
||||||
|
# Create default session directory
|
||||||
|
if [ -z "$session_dir" ]; then
|
||||||
|
session_dir="./session"
|
||||||
|
mkdir -p "$session_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Setup session globals
|
||||||
|
_exprashUseSession=1
|
||||||
|
_exprashSessionDir=$session_dir
|
||||||
|
|
||||||
|
_loadSession || _createSession || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set a session variable
|
||||||
|
# $1: variable name
|
||||||
|
# $2: (optional) vairable value
|
||||||
|
function session() {
|
||||||
|
local name="$1"
|
||||||
|
if [[ -v 2 ]]; then
|
||||||
|
local value="$2"
|
||||||
|
_exprashSession["$name"]="$value"
|
||||||
|
else
|
||||||
|
printf '%s' "${_exprashSession["$name"]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# =========
|
# =========
|
||||||
# Internals
|
# Internals
|
||||||
# =========
|
# =========
|
||||||
@ -287,7 +340,7 @@ function _pathMatch() {
|
|||||||
local pathComponent="${pathArr[$i]}";
|
local pathComponent="${pathArr[$i]}";
|
||||||
|
|
||||||
# If route component starts with ":"
|
# If route component starts with ":"
|
||||||
if [[ "$routeComponent" == :* ]]; then
|
if [[ "$routeComponent" == :* ]] && [ -n "$pathComponent" ]; then
|
||||||
routeParams["${routeComponent:1}"]="$pathComponent";
|
routeParams["${routeComponent:1}"]="$pathComponent";
|
||||||
elif [[ "$routeComponent" == '*' ]] && [ -n "$pathComponent" ]; then
|
elif [[ "$routeComponent" == '*' ]] && [ -n "$pathComponent" ]; then
|
||||||
continue;
|
continue;
|
||||||
@ -315,7 +368,7 @@ function _multiAdd() {
|
|||||||
local value="$3"
|
local value="$3"
|
||||||
local i=0
|
local i=0
|
||||||
while [[ -v "multiArr[$i,$key]" ]]; do
|
while [[ -v "multiArr[$i,$key]" ]]; do
|
||||||
let i++
|
(( i++ ))
|
||||||
done
|
done
|
||||||
multiArr["$i,$key"]="$value"
|
multiArr["$i,$key"]="$value"
|
||||||
}
|
}
|
||||||
@ -325,10 +378,9 @@ function _multiAdd() {
|
|||||||
function _multiLen() {
|
function _multiLen() {
|
||||||
local -n multiArr="$1"
|
local -n multiArr="$1"
|
||||||
local key="$2"
|
local key="$2"
|
||||||
local value="$3"
|
|
||||||
local i=0
|
local i=0
|
||||||
while [[ -v "multiArr[$i,$key]" ]]; do
|
while [[ -v "multiArr[$i,$key]" ]]; do
|
||||||
let i++
|
(( i++ ))
|
||||||
done
|
done
|
||||||
printf '%s' "$i"
|
printf '%s' "$i"
|
||||||
}
|
}
|
||||||
@ -355,15 +407,19 @@ function _multiGet() {
|
|||||||
# URL Encoded Parser
|
# URL Encoded Parser
|
||||||
# ==================
|
# ==================
|
||||||
|
|
||||||
# $1: urlencoded string
|
# $1 | stdin: urlencoded string
|
||||||
decodeUri () {
|
decodeUri () {
|
||||||
local i="${*//+/ }";
|
local input_str="${1-"$(< /dev/stdin)"}"
|
||||||
echo -e "${i//%/\\x}";
|
input_str="${input_str//+/ }";
|
||||||
|
echo -e "${input_str//%/\\x}";
|
||||||
}
|
}
|
||||||
|
|
||||||
# $1: multi associative array
|
# $1: (nameref) multi associative array
|
||||||
|
# $2 | stdin: url encoded data
|
||||||
function _parseUrlEncoded() {
|
function _parseUrlEncoded() {
|
||||||
local -n parsedArr="$1"
|
local -n parsedArr="$1"
|
||||||
|
local url_encoded_str="${2-"$(< /dev/stdin)"}"
|
||||||
|
local pair name value
|
||||||
|
|
||||||
while IFS= read -d '&' -r pair || [ "$pair" ]; do
|
while IFS= read -d '&' -r pair || [ "$pair" ]; do
|
||||||
name=$(decodeUri "${pair%%=*}")
|
name=$(decodeUri "${pair%%=*}")
|
||||||
@ -371,48 +427,140 @@ function _parseUrlEncoded() {
|
|||||||
if [ -n "$name" ]; then
|
if [ -n "$name" ]; then
|
||||||
_multiAdd parsedArr "$name" "$value"
|
_multiAdd parsedArr "$name" "$value"
|
||||||
fi;
|
fi;
|
||||||
done
|
done <<< "$url_encoded_str"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# =======
|
# =======
|
||||||
# Globals
|
# Cookies
|
||||||
# =======
|
# =======
|
||||||
|
|
||||||
# Setup globals
|
# $1: (nameref) associative array
|
||||||
_exprashRedirectStdout=''
|
# $2 | stdin: cookie string to parse
|
||||||
|
function _parseCookies() {
|
||||||
|
local -n parsedArr="$1"
|
||||||
|
local cookie_str="${2-"$(< /dev/stdin)"}"
|
||||||
|
|
||||||
# Route Parameters
|
local pair name value
|
||||||
declare -gA _exprashParams
|
|
||||||
|
|
||||||
# Body Parameters
|
while IFS= read -d ';' -r pair || [ "$pair" ]; do
|
||||||
declare -gA _exprashBody
|
name="$(_trim "${pair%%=*}" | decodeUri)"
|
||||||
|
value="$(_trim "${pair#*=}" | decodeUri)"
|
||||||
|
if [ -n "$name" ]; then
|
||||||
|
parsedArr["$name"]="$value"
|
||||||
|
fi
|
||||||
|
done <<< "$cookie_str"
|
||||||
|
}
|
||||||
|
|
||||||
# Query Parameters
|
# =======
|
||||||
declare -gA _exprashQuery
|
# Session
|
||||||
|
# =======
|
||||||
|
|
||||||
# Headers
|
function _loadSession() {
|
||||||
declare -gA _exprashHeaders
|
[ "$_exprashUseSession" -eq 1 ] || return 1
|
||||||
|
[ -n "$_exprashSessionDir" ] || return 1
|
||||||
|
hasCookie "$_exprashSessionCookieName" || return 1
|
||||||
|
|
||||||
function _exprashResetRouteGlobals() {
|
local session_id
|
||||||
_exprashParams=()
|
session_id="$(cookie "$_exprashSessionCookieName")"
|
||||||
_exprashBody=()
|
local session_file="${_exprashSessionDir%/}/$session_id.session"
|
||||||
_exprashQuery=()
|
|
||||||
_exprashHeaders=()
|
# shellcheck disable=SC1090
|
||||||
|
source "$session_file" || return 1
|
||||||
|
|
||||||
|
# Set globals
|
||||||
|
_exprashSessionId=$session_id
|
||||||
|
}
|
||||||
|
|
||||||
|
function _createSession() {
|
||||||
|
[ "$_exprashUseSession" -eq 1 ] || return 1
|
||||||
|
[ -n "$_exprashSessionDir" ] || return 1
|
||||||
|
|
||||||
|
# mktemp args
|
||||||
|
local args=()
|
||||||
|
args+=('-p' "$_exprashSessionDir")
|
||||||
|
args+=("$(printf 'X%.0s' {1..32}).session")
|
||||||
|
|
||||||
|
local session_file
|
||||||
|
session_file=$(mktemp -u "${args[@]}") || return 1
|
||||||
|
local session_file_name=${session_file##*/}
|
||||||
|
local session_id=${session_file_name%%.*}
|
||||||
|
|
||||||
|
# Set cookie
|
||||||
|
setCookie "$_exprashSessionCookieName" "$session_id"
|
||||||
|
|
||||||
|
# Set globals
|
||||||
|
_exprashSessionId=$session_id
|
||||||
|
_exprashSession=()
|
||||||
|
}
|
||||||
|
|
||||||
|
function _saveSession() {
|
||||||
|
[ "$_exprashUseSession" -eq 1 ] || return 1
|
||||||
|
[ -n "$_exprashSessionDir" ] || return 1
|
||||||
|
[ -n "$_exprashSessionId" ] || return 1
|
||||||
|
|
||||||
|
local session_file="${_exprashSessionDir%/}/${_exprashSessionId}.session"
|
||||||
|
|
||||||
|
declare -p _exprashSession | sed '1 s/\([^-]*-\)/\1g/' > "$session_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# =================
|
||||||
|
# Utility Functions
|
||||||
|
# =================
|
||||||
|
|
||||||
|
# $1 | stdin: string to trim
|
||||||
|
function _trim() {
|
||||||
|
local str="${1-"$(< /dev/stdin)"}"
|
||||||
|
|
||||||
|
# trim leading spaces
|
||||||
|
str="${str#"${str%%[![:space:]]*}"}"
|
||||||
|
# trim trailing spaces
|
||||||
|
str="${str%"${str##*[![:space:]]}"}"
|
||||||
|
|
||||||
|
printf '%s' "$str"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ========
|
||||||
|
# Shutdown
|
||||||
|
# ========
|
||||||
|
|
||||||
|
function _exprashShutdown() {
|
||||||
|
_saveSession
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============
|
||||||
|
# Initialization
|
||||||
|
# ==============
|
||||||
|
function _exprashInit() {
|
||||||
|
_exprashRedirectStdout=''
|
||||||
|
|
||||||
|
declare -gA _exprashParams=()
|
||||||
|
declare -gA _exprashBody=()
|
||||||
|
declare -gA _exprashQuery=()
|
||||||
|
declare -gA _exprashHeaders=()
|
||||||
|
declare -gA _exprashCookies=()
|
||||||
|
declare -gA _exprashSetCookies=()
|
||||||
|
|
||||||
|
_exprashUseSession=0
|
||||||
|
_exprashSessionDir=''
|
||||||
|
_exprashSessionId=''
|
||||||
|
declare -gA _exprashSession=()
|
||||||
|
_exprashSessionCookieName='exprash_session'
|
||||||
|
|
||||||
_exprashRouteHandled=0
|
_exprashRouteHandled=0
|
||||||
_exprashErrorMessage=''
|
_exprashErrorMessage=''
|
||||||
_exprashHeadersSent=0
|
_exprashHeadersSent=0
|
||||||
_exprashHeaders['Content-Type']='text/html'
|
_exprashHeaders['Content-Type']='text/html'
|
||||||
|
|
||||||
|
# Parse query string
|
||||||
|
_parseUrlEncoded _exprashQuery "$QUERY_STRING"
|
||||||
|
|
||||||
|
# Parse cookies
|
||||||
|
_parseCookies _exprashCookies "$HTTP_COOKIE"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set up route globals
|
# Shutdown trap
|
||||||
_exprashResetRouteGlobals
|
trap _exprashShutdown EXIT
|
||||||
|
|
||||||
# ==============
|
# Initialize exprash
|
||||||
# Initialization
|
_exprashInit
|
||||||
# ==============
|
|
||||||
|
|
||||||
# Parse query string
|
|
||||||
_parseUrlEncoded _exprashQuery < <(echo "$QUERY_STRING")
|
|
||||||
|
20
tests/cookies.sh
Executable file
20
tests/cookies.sh
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
it "Should parse cookies" "$({
|
||||||
|
HTTP_COOKIE='bob=gob; job=tob'
|
||||||
|
_exprashInit
|
||||||
|
output=$(declare -p _exprashCookies)
|
||||||
|
expected_output='declare -A _exprashCookies=([bob]="gob" [job]="tob" )'
|
||||||
|
[ "$output" == "$expected_output" ]
|
||||||
|
})"
|
||||||
|
|
||||||
|
it "Should get cookie value by name" "$({
|
||||||
|
HTTP_COOKIE='bob=gob; job=tob'
|
||||||
|
_exprashInit
|
||||||
|
[ "$(cookie 'bob')" == 'gob' ]
|
||||||
|
})"
|
||||||
|
|
||||||
|
it "Should determine if a cookie exists by name" "$({
|
||||||
|
HTTP_COOKIE='bob=gob; job=tob'
|
||||||
|
_exprashInit
|
||||||
|
hasCookie 'bob' && ! hasCookie 'kob'
|
||||||
|
})"
|
||||||
|
|
6
tests/query.sh
Normal file
6
tests/query.sh
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
it "Should parse query string" "$({
|
||||||
|
QUERY_STRING='ohmy=zsh&exit=vim'
|
||||||
|
_exprashInit
|
||||||
|
hasQuery 'ohmy' && ! hasQuery 'ohno' && [ "$(query 'exit')" == 'vim' ]
|
||||||
|
})"
|
||||||
|
|
@ -1,55 +1,62 @@
|
|||||||
it "Should match plain route" $({
|
it "Should match plain route" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
PATH_INFO='/plain/route'
|
PATH_INFO='/plain/route'
|
||||||
|
_exprashInit
|
||||||
all '/plain/route'
|
all '/plain/route'
|
||||||
})
|
})
|
||||||
|
|
||||||
it "Should not match incorrect plain route" $({
|
it "Should not match incorrect plain route" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
PATH_INFO='/plain/WRONG'
|
PATH_INFO='/plain/WRONG'
|
||||||
|
_exprashInit
|
||||||
! all '/plain/route'
|
! all '/plain/route'
|
||||||
})
|
})
|
||||||
|
|
||||||
it "Should extract parameter" $({
|
it "Should extract parameter" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
PATH_INFO='/cats/calico/pet'
|
PATH_INFO='/cats/calico/pet'
|
||||||
|
_exprashInit
|
||||||
all '/cats/:cat/pet' && hasParam 'cat' && [ "$(param 'cat')" == 'calico' ]
|
all '/cats/:cat/pet' && hasParam 'cat' && [ "$(param 'cat')" == 'calico' ]
|
||||||
})
|
})
|
||||||
|
|
||||||
it "Should match wildcard route" $({
|
it "Should match wildcard route" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
PATH_INFO='/cats/calico/pet'
|
PATH_INFO='/cats/calico/pet'
|
||||||
|
_exprashInit
|
||||||
all '/cats/*/pet'
|
all '/cats/*/pet'
|
||||||
})
|
})
|
||||||
|
|
||||||
it "Should not match incorrect wildcard route" $({
|
it "Should not match incorrect wildcard route" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
PATH_INFO='/cats/calico/'
|
PATH_INFO='/cats/calico/'
|
||||||
|
_exprashInit
|
||||||
! all '/cats/*/pet'
|
! all '/cats/*/pet'
|
||||||
})
|
})
|
||||||
|
|
||||||
it "Should match multi-wildcard route" $({
|
it "Should match multi-wildcard route" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
PATH_INFO='/cats/calico/pet/donkey'
|
PATH_INFO='/cats/calico/pet/donkey'
|
||||||
|
_exprashInit
|
||||||
all '/cats/**'
|
all '/cats/**'
|
||||||
})
|
})
|
||||||
|
|
||||||
it "Should not match incorrect multi-wildcard route" $({
|
it "Should not match incorrect multi-wildcard route" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
PATH_INFO='/INCORRECT/calico/pet/donkey'
|
PATH_INFO='/INCORRECT/calico/pet/donkey'
|
||||||
|
_exprashInit
|
||||||
! all '/cats/**'
|
! all '/cats/**'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it "Should not match path shorter than route" $({
|
||||||
|
PATH_INFO='/year'
|
||||||
|
_exprashInit
|
||||||
|
! all '/year/:year'
|
||||||
|
})
|
||||||
|
|
||||||
it "Should match get route" $({
|
it "Should match get route" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
REQUEST_METHOD='GET'
|
REQUEST_METHOD='GET'
|
||||||
PATH_INFO='/simple/route'
|
PATH_INFO='/simple/route'
|
||||||
|
_exprashInit
|
||||||
get '/simple/route'
|
get '/simple/route'
|
||||||
})
|
})
|
||||||
|
|
||||||
it "Should not match get route with incorrect method" $({
|
it "Should not match get route with incorrect method" $({
|
||||||
_exprashResetRouteGlobals
|
|
||||||
REQUEST_METHOD='POST'
|
REQUEST_METHOD='POST'
|
||||||
PATH_INFO='/simple/route'
|
PATH_INFO='/simple/route'
|
||||||
|
_exprashInit
|
||||||
! get '/simple/route'
|
! get '/simple/route'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
30
tests/session.sh
Normal file
30
tests/session.sh
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# shellcheck disable=SC2154,SC2034
|
||||||
|
|
||||||
|
testSessionDir='/tmp/exprash_test_sessions'
|
||||||
|
mkdir -p "$testSessionDir"
|
||||||
|
|
||||||
|
it "Should set session directory" "$({
|
||||||
|
_exprashInit
|
||||||
|
useSession "$testSessionDir"
|
||||||
|
[ "$_exprashSessionDir" == "$testSessionDir" ]
|
||||||
|
})"
|
||||||
|
|
||||||
|
it "Should save and load session" "$({
|
||||||
|
_exprashInit
|
||||||
|
useSession "$testSessionDir"
|
||||||
|
session 'data' 'value'
|
||||||
|
session_id=$_exprashSessionId
|
||||||
|
cookie_value=${_exprashSetCookies[$_exprashSessionCookieName]}
|
||||||
|
_exprashShutdown
|
||||||
|
|
||||||
|
# Forcibly clear session data just in case (but it should also get cleared by
|
||||||
|
# _exprashInit)
|
||||||
|
_exprashSession=()
|
||||||
|
_exprashSessionId=''
|
||||||
|
|
||||||
|
HTTP_COOKIE="${_exprashSessionCookieName}=$cookie_value"
|
||||||
|
_exprashInit
|
||||||
|
useSession "$testSessionDir"
|
||||||
|
[ "$(session 'data')" == "value" ]
|
||||||
|
})"
|
||||||
|
|
@ -1,23 +1,30 @@
|
|||||||
_testPassCount=0;
|
_testPassCount=0
|
||||||
_testTotalCount=0;
|
_testTotalCount=0
|
||||||
|
|
||||||
|
# $1: Message
|
||||||
|
# $2: Subshell output
|
||||||
function it() {
|
function it() {
|
||||||
local exitCode=$?;
|
local exitCode=$?
|
||||||
local message=$1;
|
local message="$1"
|
||||||
local status;
|
local output="$2"
|
||||||
|
local status
|
||||||
|
|
||||||
_testTotalCount=$((_testTotalCount+1));
|
_testTotalCount=$((_testTotalCount+1))
|
||||||
|
|
||||||
if [ "$exitCode" -eq 0 ]; then
|
if [ "$exitCode" -eq 0 ]; then
|
||||||
status='✓';
|
status='✓'
|
||||||
_testPassCount=$((_testPassCount+1));
|
_testPassCount=$((_testPassCount+1))
|
||||||
else
|
else
|
||||||
status='✗';
|
status='✗'
|
||||||
fi;
|
fi
|
||||||
|
|
||||||
printf '%s %s\n' "$status" "$message";
|
if [ -n "$output" ]; then
|
||||||
|
printf '%s\n' "$output"
|
||||||
|
fi
|
||||||
|
printf '%s %s\n' "$status" "$message"
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSummary() {
|
function testSummary() {
|
||||||
printf 'Passed: %s of %s tests\n' "$_testPassCount" "$_testTotalCount";
|
printf 'Passed: %s of %s tests\n' "$_testPassCount" "$_testTotalCount"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user