diff --git a/mo b/mo index d782dfb..49068d7 100755 --- a/mo +++ b/mo @@ -517,7 +517,7 @@ mo::parseBlock() { mo::tokensToString moTokensString "${moTokens[@]}" mo::debug "Parsing block: $moTokensString" - if mo::standaloneCheck; then + if mo::standaloneCheck "$MO_STANDALONE_CONTENT"; then mo::standaloneProcess fi @@ -671,7 +671,7 @@ mo::parsePartial() { MO_UNPARSED="${MO_UNPARSED#*"$MO_CLOSE_DELIMITER"}" moIndentation="" - if mo::standaloneCheck; then + if mo::standaloneCheck "$MO_STANDALONE_CONTENT"; then moN=$'\n' moR=$'\r' moIndentation="$moN${MO_PARSED//"$moR"/"$moN"}" @@ -725,7 +725,7 @@ mo::parseComment() { MO_UNPARSED=${MO_UNPARSED#*"$MO_CLOSE_DELIMITER"} mo::debug "Parsing comment" - if mo::standaloneCheck; then + if mo::standaloneCheck "$MO_STANDALONE_CONTENT"; then mo::standaloneProcess fi } @@ -746,7 +746,7 @@ mo::parseDelimiter() { MO_UNPARSED=${MO_UNPARSED#*="$MO_CLOSE_DELIMITER"} mo::debug "Parsing delimiters: $moOpen $moClose" - if mo::standaloneCheck; then + if mo::standaloneCheck "$MO_STANDALONE_CONTENT"; then mo::standaloneProcess fi @@ -1234,6 +1234,8 @@ mo::evaluateFunction() { # it on a line. There must be a new line before and there must be a newline # after or the end of a string # +# $1 - The content before the tag. +# # Returns 0 if this is a standalone tag, 1 otherwise. mo::standaloneCheck() { local moContent moN moR moT @@ -1243,7 +1245,7 @@ mo::standaloneCheck() { moT=$'\t' # Check the content before - moContent=${MO_STANDALONE_CONTENT//"$moR"/"$moN"} + moContent=${1//"$moR"/"$moN"} # By default, signal to the next check that this one failed MO_STANDALONE_CONTENT="" @@ -1283,7 +1285,11 @@ mo::standaloneCheck() { } -# Internal: Process content before and after a tag. Remove prior whitespace up to the previous newline. Remove following whitespace up to and including the next newline. +# Internal: Process content before and after a tag. Remove prior whitespace up +# to the previous newline. Remove following whitespace up to and including the +# next newline. +# +# No arguments. # # Returns nothing. mo::standaloneProcess() { @@ -1380,14 +1386,14 @@ mo::escape() { # # Returns nothing. mo::getContentUntilClose() { - local moChunk moResult moTemp moTokensString moTokens moTarget moTagStack moResultTemp + local moChunk moResult moTemp moTokensString moTokens moTarget moTagStack moResultTemp moStandaloneTemp moTarget=$1 moTagStack=("$2") mo::debug "Get content until close tag: ${moTagStack[0]}" moResult="" - while [[ -n "$MO_UNPARSED" ]]; do + while [[ -n "$MO_UNPARSED" ]] && [[ "${#moTagStack[@]}" -gt 0 ]]; do moChunk=${MO_UNPARSED%%"$MO_OPEN_DELIMITER"*} moResult="$moResult$moChunk" MO_UNPARSED=${MO_UNPARSED:${#moChunk}} @@ -1482,9 +1488,13 @@ mo::getContentUntilClose() { fi done - # FIXME - handle standalone - mo::debug "FIXME handle standalone" - mo::debug "Block: $moResult" + if mo::standaloneCheck "$moResult"; then + moResultTemp=$MO_PARSED + MO_PARSED=$moResult + mo::standaloneProcess + moResult=$MO_PARSED + MO_PARSED=$moResultTemp + fi local "$moTarget" && mo::indirect "$moTarget" "$moResult" } diff --git a/run-tests b/run-tests index 04ec115..774d649 100755 --- a/run-tests +++ b/run-tests @@ -1,4 +1,42 @@ #!/usr/bin/env bash +# +# Run one or more tests. +# +# Command-line usage to run all tests. +# +# ./run-tests +# +# To run only one test, run "tests/test-name". +# +# Usage within a test as a template. Source run-tests to get functions, export +# any necessary variables, then call runTest. +# +# #!/usr/bin/env bash +# cd "${0%/*}" || exit 1 +# . ../run-tests +# +# export template="This is a template" +# export expected="This is a template" +# runTest +# +# When used within the test, you control various aspects with environment +# variables or functions. +# +# - The content passed into mo is either the variable "$template" or the output +# of the function called template. +# - The expected result is either "$expected" or the function called expected. +# - The expected return code is "$returnCode" and defaults to 0. +# - The arguments to pass to mo is the array "${arguments[@]}" and defaults to (). +# +# When $MO_DEBUG is set to a non-empty value, the test does not run, but mo is +# simply executed directly. This allows for calling mo in the same manner as +# the test but does not buffer output nor expect the output to match the +# expected. +# +# When $MO_DEBUG_TEST is set to a non-empty value, the expected and actual +# results are shown using "declare -p" to provide an easier time seeing the +# differences, especially with whitespace. + testCase() { echo "Input: $1" echo "Expected: $2" @@ -38,6 +76,12 @@ runTest() ( getValue testTemplate template getValue testExpected expected + if [[ -n "${MO_DEBUG:-}" ]]; then + echo -n "$testTemplate" | mo ${arguments[@]+"${arguments[@]}"} 2>&1 + + return $? + fi + testActual=$(echo -n "$testTemplate" | mo ${arguments[@]+"${arguments[@]}"} 2>&1; echo -n "$hardSpace$?") testReturnCode=${testActual##*$hardSpace} testActual=${testActual%$hardSpace*}