mirror of
https://github.com/tests-always-included/mo.git
synced 2024-12-22 09:47:48 +00:00
394 lines
13 KiB
Bash
Executable File
394 lines
13 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Test individual functions in mo and make sure they are performing their
|
|
# tasks correctly. This can be used to help determine what needs to get
|
|
# fixed when making mo work on another version of bash, or another shell
|
|
# entirely.
|
|
#
|
|
# Functions are tested from the most primitive to the most advanced.
|
|
# Errors, once found, halt the program. This way we can more easily
|
|
# diagnose what's not working and fix those low-level functions first.
|
|
|
|
PARENT_PID=$$
|
|
cd "$(dirname "$0")"
|
|
rm -f diagnostic.test
|
|
rm -f diagnostic.partial
|
|
|
|
# Load mo's functions
|
|
. ./mo
|
|
|
|
fail() {
|
|
echo "$1"
|
|
kill $PARENT_PID
|
|
exit 1
|
|
}
|
|
|
|
# No dependencies
|
|
|
|
echo -n "moIndirect ... "
|
|
(
|
|
a() {
|
|
local V
|
|
V="a"
|
|
b
|
|
echo -n "$V"
|
|
}
|
|
|
|
b() {
|
|
local V
|
|
V="b"
|
|
c V
|
|
echo -n "$V"
|
|
}
|
|
|
|
c() {
|
|
local "$1" && moIndirect "$1" c
|
|
}
|
|
|
|
[[ "$(a)" != "ca" ]] && fail "Did not assign or scope bled '$RESULT'"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moIndirectArray ... "
|
|
(
|
|
a() {
|
|
local V
|
|
V=( "a" )
|
|
b
|
|
echo -n "${#V[@]}"
|
|
}
|
|
|
|
b() {
|
|
local V
|
|
V=( "b" "b" )
|
|
c V
|
|
echo -n "${#V[@]}"
|
|
}
|
|
|
|
c() {
|
|
local "$1" && moIndirectArray "$1" c c c
|
|
}
|
|
|
|
[[ "$(a)" != "31" ]] && fail "Did not assign or scope bled '$RESULT'"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moIsArray ... "
|
|
(
|
|
TEST=1
|
|
moIsArray TEST && fail "Wrongly said number was an array"
|
|
)
|
|
(
|
|
TEST=()
|
|
moIsArray TEST || fail "Wrongly said array was not an array"
|
|
)
|
|
(
|
|
# shellcheck disable=SC2034
|
|
TEST=""
|
|
moIsArray TEST && fail "Wrongly said string was an array"
|
|
)
|
|
(
|
|
unset TEST
|
|
moIsArray TEST && fail "Wrongly said undefined was an array"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moIsFunction ... "
|
|
(
|
|
aa() { echo "hi"; }
|
|
|
|
moIsFunction aa || fail "Did not find a function"
|
|
|
|
moIsFunction dd && fail "Wrongly found a function"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moFindString ... "
|
|
(
|
|
moFindString POS "abcdefg" "ab"
|
|
[[ "$POS" == "0" ]] || fail "Did not find at beginning of string"
|
|
|
|
moFindString POS "abcdefg" "fg"
|
|
[[ "$POS" == "5" ]] || fail "Did not find at end of string"
|
|
|
|
moFindString POS "abcdefg" "de"
|
|
[[ "$POS" == "3" ]] || fail "Did not find at middle of string"
|
|
|
|
moFindString POS "abcdefg" "CD"
|
|
[[ "$POS" == "-1" ]] || fail "Did not correctly return a miss"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moFullTagName ... "
|
|
(
|
|
moFullTagName TAG "abc" "def"
|
|
[[ "$TAG" == "abc.def" ]] || fail "Did not work with a context"
|
|
|
|
moFullTagName TAG "" "one"
|
|
[[ "$TAG" == "one" ]] || fail "Did not work without a context"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moLoadFile ... "
|
|
(
|
|
# TODO - find a way to test reading from stdin that is not painful.
|
|
|
|
touch diagnostic.test
|
|
moLoadFile RESULT diagnostic.test
|
|
[[ "${#RESULT}" == "0" ]] || fail "Did not read from empty file '$RESULT'"
|
|
|
|
echo "abc" >> diagnostic.test
|
|
moLoadFile RESULT diagnostic.test
|
|
[[ "${#RESULT}" == "4" ]] || fail "Did not read from file '$RESULT'"
|
|
|
|
echo "" >> diagnostic.test
|
|
moLoadFile RESULT diagnostic.test
|
|
[[ "${#RESULT}" == "5" ]] || fail "Trimmed newline from file '$RESULT'"
|
|
|
|
rm diagnostic.test
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moStandaloneDenied ... "
|
|
(
|
|
moStandaloneDenied RESULT before tag after > diagnostic.test
|
|
[[ "$(cat diagnostic.test)" == "before" ]] || fail "Did not output content before tag '$(cat diagnostic.test)'"
|
|
[[ "$RESULT" == "after" ]] || fail "Did not set the remaining content '$RESULT'"
|
|
rm diagnostic.test
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moTest ... "
|
|
# shellcheck disable=SC2034
|
|
(
|
|
aa() { echo "hi"; }
|
|
bb="bb"
|
|
cc=3
|
|
dd=( dd )
|
|
xx=()
|
|
unset yy
|
|
zz=""
|
|
|
|
moTest aa || fail "Did not detect a function"
|
|
moTest bb || fail "Did not detect a non-empty string"
|
|
moTest cc || fail "Did not detect a number"
|
|
moTest dd || fail "Did not detect a populated array"
|
|
moTest xx && fail "Erroneously flagged an empty array"
|
|
moTest yy && fail "Erroneously flagged an undefined value"
|
|
moTest zz && fail "Erroneously flagged an empty string"
|
|
MO_FALSE_IF_EMPTY=true moTest zz && fail "Erroneously flagged an empty value as non-false when empty should be false"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moTrimChars ... "
|
|
(
|
|
moTrimChars RESULT "abcdabc" true true a b c
|
|
[[ "$RESULT" == "d" ]] || fail "Did not trim multiple characters '$RESULT'"
|
|
|
|
moTrimChars RESULT "abc" true false a c
|
|
[[ "$RESULT" == "bc" ]] || fail "Did not trim only from the front '$RESULT'"
|
|
|
|
moTrimChars RESULT "abc" false true a c
|
|
[[ "$RESULT" == "ab" ]] || fail "Did not trim only from the end '$RESULT'"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moGetContent ... "
|
|
(
|
|
# TODO - find a way to test reading from stdin that is not painful.
|
|
# Until then, mock it
|
|
|
|
moLoadFile() { local "$1" && moIndirect "$1" "STDIN"; }
|
|
|
|
moGetContent RESULT a
|
|
[[ "$RESULT" == "{{>a}}" ]] || fail "Did not construct 1 partial correctly '$RESULT'"
|
|
|
|
moGetContent RESULT a b c
|
|
[[ "$RESULT" == "{{>a}}{{>b}}{{>c}}" ]] || fail "Did not construct 3 partials correctly '$RESULT'"
|
|
|
|
moGetContent RESULT
|
|
[[ "$RESULT" == "STDIN" ]] || fail "Did not call moLoadFile correctly"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moIndentLines ... "
|
|
(
|
|
CR=$'\r'
|
|
LF=$'\n'
|
|
# shellcheck disable=SC2034
|
|
CRLF="$CR$LF"
|
|
|
|
# CAUTION
|
|
# This must have a dot at the end of the input string
|
|
# That is part of how moPartial calls this function
|
|
for NEWLINE in "CR" "LF" "CRLF"; do
|
|
NL="${!NEWLINE}"
|
|
|
|
moIndentLines RESULT "" "has${NL}${NEWLINE}${NL}."
|
|
printf -v QUOTED '%q' "$RESULT"
|
|
[[ "$RESULT" == "has${NL}${NEWLINE}${NL}" ]] || fail "Should not have changed string $QUOTED"
|
|
|
|
moIndentLines RESULT "" "without${NL}trailing${NL}${NEWLINE}."
|
|
printf -v QUOTED '%q' "$RESULT"
|
|
[[ "$RESULT" == "without${NL}trailing${NL}${NEWLINE}" ]] || fail "Should not have changed string $QUOTED"
|
|
|
|
moIndentLines RESULT "_-_" "has${NL}${NL}${NEWLINE}${NL}."
|
|
printf -v QUOTED '%q' "$RESULT"
|
|
[[ "$RESULT" == "_-_has${NL}${NL}_-_${NEWLINE}${NL}" ]] || fail "Should have indented $QUOTED"
|
|
|
|
moIndentLines RESULT "_-_" "without${NL}${NL}trailing${NL}${NEWLINE}."
|
|
printf -v QUOTED '%q' "$RESULT"
|
|
[[ "$RESULT" == "_-_without${NL}${NL}_-_trailing${NL}_-_${NEWLINE}" ]] || fail "Should have indented $QUOTED"
|
|
done
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moIsStandalone ... "
|
|
(
|
|
CR=$'\r'
|
|
LF=$'\n'
|
|
TAB=$'\t'
|
|
|
|
moIsStandalone RESULT "" "" false && fail "Needs newline before or beginning of content flag"
|
|
moIsStandalone RESULT "" "" true || fail "Has beginning of content flag and no other content"
|
|
[[ "$RESULT" == "0 0" ]] || fail "Wrong returned value for no content '$RESULT'"
|
|
moIsStandalone RESULT "moo" "cow" false && fail "Needs newlines when there is content"
|
|
moIsStandalone RESULT "moo$CR$LF$TAB $TAB " " $TAB $TAB$CR${LF}pasture" false || fail "Has newlines and content but did not flag"
|
|
[[ "$RESULT" == "5 6" ]] || fail "Wrong returned value when there was whitespace '$RESULT'"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moSplit ... "
|
|
(
|
|
moSplit RESULT "abc-def-ghi" "-"
|
|
[[ "${#RESULT[@]}" == "2" ]] || fail "Returned wrong number of elements with one delimiter ${#RESULT[@]}"
|
|
[[ "${RESULT[0]}" == "abc" ]] || fail "Returned wrong left hand string with one delimiter '${RESULT[0]}'"
|
|
[[ "${RESULT[1]}" == "def-ghi" ]] || fail "Returned wrong right hand string with one delimiter '${RESULT[1]}'"
|
|
|
|
moSplit RESULT "abc-def-ghi" "-" "g"
|
|
[[ "${#RESULT[@]}" == "3" ]] || fail "Returned wrong number of elements with two delimiters ${#RESULT[@]}"
|
|
[[ "${RESULT[0]}" == "abc" ]] || fail "Returned wrong left hand string with two delimiters '${RESULT[0]}'"
|
|
[[ "${RESULT[1]}" == "def-" ]] || fail "Returned wrong middle string with two delimiters '${RESULT[1]}'"
|
|
[[ "${RESULT[2]}" == "hi" ]] || fail "Returned wrong right hand string with two delimiters '${RESULT[2]}'"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moTrimWhitespace ... "
|
|
(
|
|
CR=$'\r'
|
|
LF=$'\n'
|
|
TAB=$'\t'
|
|
|
|
moTrimWhitespace RESULT "ab cd"
|
|
printf -v QUOTED '%q' "$RESULT"
|
|
[[ "${RESULT}" == "ab cd" ]] || fail "Trimmed a string that did not need trimming $QUOTED"
|
|
|
|
moTrimWhitespace RESULT "$CR$LF$TAB ab $CR$LF$TAB cd $CR$LF$TAB $CR$LF$TAB"
|
|
printf -v QUOTED '%q' "$RESULT"
|
|
[[ "${RESULT}" == "ab $CR$LF$TAB cd" ]] || fail "Did not fully trim a string $QUOTED"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moStandaloneAllowed ... "
|
|
(
|
|
# Mock moIsStandalone to make things simpler
|
|
|
|
moIsStandalone() { return 1; }
|
|
|
|
moStandaloneAllowed RESULT before tag after > diagnostic.test
|
|
[[ "$(cat diagnostic.test)" == "before" ]] || fail "Did not output content before tag when not standalone '$(cat diagnostic.test)'"
|
|
[[ "$RESULT" == "after" ]] || fail "Did not set the remaining content when not standalone '$RESULT'"
|
|
|
|
moIsStandalone() { local "$1" && moIndirect "$1" "3 5"; return 0; }
|
|
|
|
moStandaloneAllowed RESULT before tag afterwards > diagnostic.test
|
|
[[ "$(cat diagnostic.test)" == "bef" ]] || fail "Did not output content before tag when standalone '$(cat diagnostic.test)'"
|
|
[[ "$RESULT" == "wards" ]] || fail "Did not set the remaining content when standalone '$RESULT'"
|
|
|
|
rm diagnostic.test
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moFindEndTag ... "
|
|
(
|
|
LF=$'\n'
|
|
|
|
moFindEndTag RESULT "moo{{ / cow }}pasture" "cow"
|
|
[[ "${#RESULT[@]}" == "3" ]] || fail "(simple) Wrong number of elements in the array ${#RESULT[@]}"
|
|
[[ "${RESULT[0]}" == "moo" ]] || fail "(simple) Wrong left-hand '${RESULT[0]}'"
|
|
[[ "${RESULT[1]}" == "{{ / cow }}" ]] || fail "(simple) Wrong middle '${RESULT[1]}'"
|
|
[[ "${RESULT[2]}" == "pasture" ]] || fail "(simple) Wrong right-hand '${RESULT[2]}'"
|
|
|
|
moFindEndTag RESULT "moo$LF {{/cow}} $LF pasture" "cow"
|
|
[[ "${#RESULT[@]}" == "3" ]] || fail "(standalone) Wrong number of elements in the array ${#RESULT[@]}"
|
|
[[ "${RESULT[0]}" == "moo$LF" ]] || fail "(standalone) Wrong left-hand '${RESULT[0]}'"
|
|
[[ "${RESULT[1]}" == " {{/cow}} $LF" ]] || fail "(standalone) Wrong middle '${RESULT[1]}'"
|
|
[[ "${RESULT[2]}" == " pasture" ]] || fail "(standalone) Wrong right-hand '${RESULT[2]}'"
|
|
|
|
moFindEndTag RESULT "aa{{#bb}}cc{{/bb}}dd{{^bb}}ee{{/bb}}ff{{/bb}}gg" "bb"
|
|
[[ "${#RESULT[@]}" == "3" ]] || fail "(recursive) Wrong number of elements in the array ${#RESULT[@]}"
|
|
[[ "${RESULT[0]}" == "aa{{#bb}}cc{{/bb}}dd{{^bb}}ee{{/bb}}ff" ]] || fail "(recursive) Wrong left-hand '${RESULT[0]}'"
|
|
[[ "${RESULT[1]}" == "{{/bb}}" ]] || fail "(recursive) Wrong middle '${RESULT[1]}'"
|
|
[[ "${RESULT[2]}" == "gg" ]] || fail "(recursive) Wrong right-hand '${RESULT[2]}'"
|
|
|
|
moFindEndTag RESULT "aa{{#bb}}cc{{/dd}}ee" "dd"
|
|
[[ "${#RESULT[@]}" == "3" ]] || fail "(unbalanced) Wrong number of elements in the array ${#RESULT[@]}"
|
|
[[ "${RESULT[0]}" == "aa{{#bb}}cc{{/dd}}ee" ]] || fail "(unbalanced) Wrong left-hand '${RESULT[0]}'"
|
|
[[ "${RESULT[1]}" == "" ]] || fail "(unbalanced) Wrong middle '${RESULT[1]}'"
|
|
[[ "${RESULT[2]}" == "" ]] || fail "(unbalanced) Wrong right-hand '${RESULT[2]}'"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moLoop ... "
|
|
(
|
|
moParse() { echo "parse[$1] context[$2] flag[$3]"; }
|
|
|
|
moLoop "content" "prefix" a b c > diagnostic.test
|
|
(
|
|
echo "parse[content] context[prefix.a] flag[false]"
|
|
echo "parse[content] context[prefix.b] flag[false]"
|
|
echo "parse[content] context[prefix.c] flag[false]"
|
|
) | diff -q diagnostic.test - || fail "Result was not as expected '$(cat diagnostic.test)'"
|
|
|
|
rm diagnostic.test
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moPartial ... "
|
|
(
|
|
NL=$'\n'
|
|
moParse() { echo "parse[$1] context[$2] flag[$3]"; }
|
|
echo "partial" > diagnostic.partial
|
|
|
|
moPartial RESULT "line$NL" ">diagnostic.partial" " ${NL}line2" false "moo" > diagnostic.test
|
|
[[ "$RESULT" == "line2" ]] || fail "Did not consume newline for standalone '$RESULT'"
|
|
printf -v QUOTED '%q' "$(cat diagnostic.test)"
|
|
[[ "$(cat diagnostic.test)" == "line${NL}parse[partial${NL}] context[moo] flag[true]" ]] || fail "Did not parse right standalone content $QUOTED"
|
|
|
|
moPartial RESULT "line" ">diagnostic.partial" "line2" false "moo" > diagnostic.test
|
|
[[ "$RESULT" == "line2" ]] || fail "Did not preserve content for non-standalone '$RESULT'"
|
|
printf -v QUOTED '%q' "$(cat diagnostic.test)"
|
|
[[ "$(cat diagnostic.test)" == "lineparse[partial${NL}] context[moo] flag[true]" ]] || fail "Did not parse right non-standalone content $QUOTED"
|
|
|
|
rm diagnostic.test diagnostic.partial
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moShow ... "
|
|
# shellcheck disable=SC2034
|
|
(
|
|
aa() { echo "this is aa"; }
|
|
bb="BB"
|
|
cc=( zero one two )
|
|
|
|
[[ "$(moShow aa)" == "this is aa" ]] || fail "Did not load function"
|
|
[[ "$(moShow bb)" == "BB" ]] || fail "Did not show variable"
|
|
[[ "$(moShow cc.1)" == "one" ]] || fail "Did not show value from indexed array"
|
|
)
|
|
echo "ok"
|
|
|
|
echo -n "moParse ... skipped (tested by specs)"
|
|
|
|
echo ""
|
|
echo "All diagnostic tests pass"
|