mirror of
https://github.com/tests-always-included/mo.git
synced 2024-12-18 08:26:21 +00:00
Pass shellcheck, more specs are handled, preserve function whitespace
This closes #49.
This commit is contained in:
parent
e0e9189355
commit
7604ce3054
223
mo
223
mo
@ -15,26 +15,59 @@
|
||||
#/
|
||||
#/ Options:
|
||||
#/
|
||||
#/ --allow-function-arguments
|
||||
#/ Permit functions to be called with additional arguments. Otherwise,
|
||||
#/ the only way to get access to the arguments is to use the
|
||||
#/ MO_FUNCTION_ARGS environment variable.
|
||||
#/ -d, --debug
|
||||
#/ Enable debug logging to stderr.
|
||||
#/ -u, --fail-not-set
|
||||
#/ Fail upon expansion of an unset variable.
|
||||
#/ Fail upon expansion of an unset variable. Will silently ignore by
|
||||
#/ default. Alternately, set MO_FAIL_ON_UNSET to a non-empty value.
|
||||
#/ -x, --fail-on-function
|
||||
#/ Fail when a function returns a non-zero status code.
|
||||
#/ Fail when a function returns a non-zero status code instead of
|
||||
#/ silently ignoring it. Alternately, set MO_FAIL_ON_FUNCTION to a
|
||||
#/ non-empty value.
|
||||
#/ -f, --fail-on-file
|
||||
#/ Fail when a file (from command-line or partial) does not exist.
|
||||
#/ Alternately, set MO_FAIL_ON_FILE to a non-empty value.
|
||||
#/ -e, --false
|
||||
#/ Treat the string "false" as empty for conditionals.
|
||||
#/ Treat the string "false" as empty for conditionals. Alternately,
|
||||
#/ set MO_FALSE_IS_EMPTY to a non-empty value.
|
||||
#/ -h, --help
|
||||
#/ This message.
|
||||
#/ -s=FILE, --source=FILE
|
||||
#/ Load FILE into the environment before processing templates.
|
||||
#/ Can be used multiple times.
|
||||
#/ -d, --debug
|
||||
#/ Enable debug logging to stderr.
|
||||
#
|
||||
# Mo is under a MIT style licence with an additional non-advertising clause.
|
||||
# See LICENSE.md for the full text.
|
||||
#
|
||||
# This is open source! Please feel free to contribute.
|
||||
#
|
||||
# https://github.com/tests-always-included/mo
|
||||
#/ -- Indicate the end of options. All arguments after this will be
|
||||
#/ treated as filenames only. Use when filenames may start with
|
||||
#/ hyphens.
|
||||
#/
|
||||
#/ Mo uses the following environment variables:
|
||||
#/
|
||||
#/ MO_ALLOW_FUNCTION_ARGUMENTS - When set to a non-empty value, this allows
|
||||
#/ functions referenced in templates to receive additional options and
|
||||
#/ arguments.
|
||||
#/ MO_DEBUG - When set to a non-empty value, additional debug information is
|
||||
#/ written to stderr.
|
||||
#/ MO_FUNCTION_ARGS - Arguments passed to the function.
|
||||
#/ MO_FAIL_ON_FILE - If a filename from the command-line is missing or a
|
||||
#/ partial does not exist, abort with an error.
|
||||
#/ MO_FAIL_ON_FUNCTION - If a function returns a non-zero status code, abort
|
||||
#/ with an error.
|
||||
#/ MO_FAIL_ON_UNSET - When set to a non-empty value, expansion of an unset env
|
||||
#/ variable will be aborted with an error.
|
||||
#/ MO_FALSE_IS_EMPTY - When set to a non-empty value, the string "false" will
|
||||
#/ be treated as an empty value for the purposes of conditionals.
|
||||
#/ MO_ORIGINAL_COMMAND - Used to find the `mo` program in order to generate a
|
||||
#/ help message.
|
||||
#/
|
||||
#/ Mo is under a MIT style licence with an additional non-advertising clause.
|
||||
#/ See LICENSE.md for the full text.
|
||||
#/
|
||||
#/ This is open source! Please feel free to contribute.
|
||||
#/
|
||||
#/ https://github.com/tests-always-included/mo
|
||||
|
||||
|
||||
# Public: Template parser function. Writes templates to stdout.
|
||||
@ -42,63 +75,7 @@
|
||||
# $0 - Name of the mo file, used for getting the help message.
|
||||
# $@ - Filenames to parse.
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# --allow-function-arguments
|
||||
#
|
||||
# Permit functions in templates to be called with additional arguments. This
|
||||
# puts template data directly in to the path of an eval statement. Use with
|
||||
# caution. Not listed in the help because it only makes sense when mo is
|
||||
# sourced.
|
||||
#
|
||||
# -u, --fail-not-set
|
||||
#
|
||||
# Fail upon expansion of an unset variable. Default behavior is to silently
|
||||
# ignore and expand into empty string.
|
||||
#
|
||||
# -x, --fail-on-function
|
||||
#
|
||||
# Fail when a function used by a template returns an error status code.
|
||||
# Alternately, ou may set the MO_FAIL_ON_FUNCTION environment variable to a
|
||||
# non-empty value to enable this behavior.
|
||||
#
|
||||
# -e, --false
|
||||
#
|
||||
# Treat "false" as an empty value. You may set the MO_FALSE_IS_EMPTY
|
||||
# environment variable instead to a non-empty value to enable this behavior.
|
||||
#
|
||||
# -h, --help
|
||||
#
|
||||
# Display a help message.
|
||||
#
|
||||
# -s=FILE, --source=FILE
|
||||
#
|
||||
# Source a file into the environment before processing template files.
|
||||
# This can be used multiple times.
|
||||
#
|
||||
# --
|
||||
#
|
||||
# Used to indicate the end of options. You may optionally use this when
|
||||
# filenames may start with two hyphens.
|
||||
#
|
||||
# Mo uses the following environment variables:
|
||||
#
|
||||
# MO_ALLOW_FUNCTION_ARGUMENTS - When set to a non-empty value, this allows
|
||||
# functions referenced in templates to receive additional
|
||||
# options and arguments. This puts the content from the
|
||||
# template directly into an eval statement. Use with extreme
|
||||
# care.
|
||||
# MO_DEBUG - When set to a non-empty value, additional debug information is
|
||||
# written to stderr.
|
||||
# MO_FUNCTION_ARGS - Arguments passed to the function.
|
||||
# MO_FAIL_ON_FUNCTION - If a function returns a non-zero status code, abort
|
||||
# with an error.
|
||||
# MO_FAIL_ON_UNSET - When set to a non-empty value, expansion of an unset env
|
||||
# variable will be aborted with an error.
|
||||
# MO_FALSE_IS_EMPTY - When set to a non-empty value, the string "false" will be
|
||||
# treated as an empty value for the purposes of conditionals.
|
||||
# MO_ORIGINAL_COMMAND - Used to find the `mo` program in order to generate a
|
||||
# help message.
|
||||
# See the comment above for details.
|
||||
#
|
||||
# Returns nothing.
|
||||
mo() (
|
||||
@ -140,6 +117,11 @@ mo() (
|
||||
MO_FAIL_ON_FUNCTION=true
|
||||
;;
|
||||
|
||||
-p | --fail-on-file)
|
||||
# shellcheck disable=SC2030
|
||||
MO_FAIL_ON_FILE=true
|
||||
;;
|
||||
|
||||
-e | --false)
|
||||
# shellcheck disable=SC2030
|
||||
MO_FALSE_IS_EMPTY=true
|
||||
@ -162,6 +144,7 @@ mo() (
|
||||
;;
|
||||
|
||||
-d | --debug)
|
||||
# shellcheck disable=SC2030
|
||||
MO_DEBUG=true
|
||||
;;
|
||||
|
||||
@ -170,6 +153,10 @@ mo() (
|
||||
moDoubleHyphens=true
|
||||
;;
|
||||
|
||||
-*)
|
||||
mo::error "Unknown option: $arg (See --help for options)"
|
||||
;;
|
||||
|
||||
*)
|
||||
#: Every arg that is not a flag or a option should be a file
|
||||
moFiles=(${moFiles[@]+"${moFiles[@]}"} "$arg")
|
||||
@ -192,6 +179,7 @@ mo() (
|
||||
#
|
||||
# Returns nothing.
|
||||
mo::debug() {
|
||||
# shellcheck disable=SC2031
|
||||
if [[ -n "${MO_DEBUG:-}" ]]; then
|
||||
echo "DEBUG: $1" >&2
|
||||
fi
|
||||
@ -205,7 +193,7 @@ mo::debug() {
|
||||
# Returns nothing. Exits the program.
|
||||
mo::error() {
|
||||
echo "ERROR: $1" >&2
|
||||
exit ${2:-1}
|
||||
exit "${2:-1}"
|
||||
}
|
||||
|
||||
|
||||
@ -264,17 +252,26 @@ mo::content() {
|
||||
#
|
||||
# Returns nothing.
|
||||
mo::contentFile() {
|
||||
local moContent moLen
|
||||
local moContent moFile
|
||||
|
||||
# The subshell removes any trailing newlines. We forcibly add
|
||||
# a dot to the content to preserve all newlines.
|
||||
# As a future optimization, it would be worth considering removing
|
||||
# cat and replacing this with a read loop.
|
||||
|
||||
mo::debug "Loading content: ${2:-/dev/stdin}"
|
||||
moContent=$(cat -- "${2:-/dev/stdin}" && echo '.') || return 1
|
||||
moLen=$((${#moContent} - 1))
|
||||
moContent=${moContent:0:$moLen} # Remove last dot
|
||||
moFile=${2:-/dev/stdin}
|
||||
|
||||
# shellcheck disable=SC2031
|
||||
if [[ -e "$moFile" ]]; then
|
||||
mo::debug "Loading content: $moFile"
|
||||
moContent=$(cat -- "$moFile" && echo '.') || return 1
|
||||
moContent=${moContent%.} # Remove last dot
|
||||
elif [[ -n "${MO_FAIL_ON_FILE-}" ]]; then
|
||||
mo::error "No such file: $moFile"
|
||||
else
|
||||
mo::debug "File does not exist: $moFile"
|
||||
moContent=""
|
||||
fi
|
||||
|
||||
local "$1" && mo::indirect "$1" "$moContent"
|
||||
}
|
||||
@ -384,9 +381,9 @@ mo::trim() {
|
||||
while [[ "$moContent" != "$moLast" ]]; do
|
||||
moLast=$moContent
|
||||
moContent=${moContent# }
|
||||
moContent=${moContent#$moR}
|
||||
moContent=${moContent#$moN}
|
||||
moContent=${moContent#$moT}
|
||||
moContent=${moContent#"$moR"}
|
||||
moContent=${moContent#"$moN"}
|
||||
moContent=${moContent#"$moT"}
|
||||
done
|
||||
|
||||
local "$1" && mo::indirect "$1" "$moContent"
|
||||
@ -406,9 +403,9 @@ mo::chomp() {
|
||||
moN=$'\n'
|
||||
moT=$'\t'
|
||||
moTemp=${2%% *}
|
||||
moTemp=${moTemp%%$moR*}
|
||||
moTemp=${moTemp%%$moN*}
|
||||
moTemp=${moTemp%%$moT*}
|
||||
moTemp=${moTemp%%"$moR"*}
|
||||
moTemp=${moTemp%%"$moN"*}
|
||||
moTemp=${moTemp%%"$moT"*}
|
||||
|
||||
local "$1" && mo::indirect "$1" "$moTemp"
|
||||
}
|
||||
@ -440,7 +437,7 @@ mo::chomp() {
|
||||
#
|
||||
# Returns nothing.
|
||||
mo::parse() {
|
||||
local moContent moCurrent moOpenDelimiter moCloseDelimieter moResult moSplit moParseChunk moFastMode moStandaloneContent moRemainder
|
||||
local moContent moCurrent moOpenDelimiter moCloseDelimiter moResult moSplit moParseChunk moFastMode moStandaloneContent moRemainder
|
||||
moContent=$2
|
||||
moCurrent=$3
|
||||
moCurrentBlock=$4
|
||||
@ -777,15 +774,15 @@ mo::parsePartial() {
|
||||
moCloseDelimiter=$5
|
||||
moFastMode=$6
|
||||
moStandaloneContent=$7
|
||||
mo::chomp moFilename "${moContent%%$moCloseDelimiter*}"
|
||||
moContent="${moContent#*$moCloseDelimiter}"
|
||||
mo::chomp moFilename "${moContent%%"$moCloseDelimiter"*}"
|
||||
moContent="${moContent#*"$moCloseDelimiter"}"
|
||||
moIndentation=""
|
||||
|
||||
if mo::standaloneCheck "$moStandaloneContent" "$moContent"; then
|
||||
moN=$'\n'
|
||||
moR=$'\r'
|
||||
moIndentation="$moN${moPrevious//$moR/$moN}"
|
||||
moIndentation=${moIndentation##*$moN}
|
||||
moIndentation="$moN${moPrevious//"$moR"/"$moN"}"
|
||||
moIndentation=${moIndentation##*"$moN"}
|
||||
mo::debug "Adding indentation to partial: '$moIndentation'"
|
||||
mo::standaloneProcessBefore moPrevious "$moPrevious"
|
||||
mo::standaloneProcessAfter moContent "$moContent"
|
||||
@ -796,7 +793,6 @@ mo::parsePartial() {
|
||||
|
||||
if [[ -n "$moFastMode" ]]; then
|
||||
moResult=""
|
||||
moLen=0
|
||||
else
|
||||
mo::debug "Parsing partial: $moFilename"
|
||||
|
||||
@ -901,7 +897,7 @@ mo::parseComment() {
|
||||
moContent=$3
|
||||
moCloseDelimiter=$4
|
||||
moStandaloneContent=$5
|
||||
moContent=${moContent#*$moCloseDelimiter}
|
||||
moContent=${moContent#*"$moCloseDelimiter"}
|
||||
mo::debug "Parsing comment"
|
||||
|
||||
if mo::standaloneCheck "$moStandaloneContent" "$moContent"; then
|
||||
@ -942,8 +938,8 @@ mo::parseDelimiter() {
|
||||
mo::chomp moOpen "$moContent"
|
||||
moContent=${moContent:${#moOpen}}
|
||||
mo::trim moContent "$moContent"
|
||||
moClose="${moContent%%=$moCloseDelimiter*}"
|
||||
moContent=${moContent#*=$moCloseDelimiter}
|
||||
moClose="${moContent%%="$moCloseDelimiter"*}"
|
||||
moContent=${moContent#*="$moCloseDelimiter"}
|
||||
mo::debug "Parsing delimiters: $moOpen $moClose"
|
||||
|
||||
if mo::standaloneCheck "$moStandaloneContent" "$moContent"; then
|
||||
@ -983,7 +979,7 @@ mo::parseValue() {
|
||||
moOpenDelimiter=$5
|
||||
moCloseDelimiter=$6
|
||||
moFastMode=$7
|
||||
mo::trim moContent "${moContentOriginal#$moOpenDelimiter}"
|
||||
mo::trim moContent "${moContentOriginal#"$moOpenDelimiter"}"
|
||||
|
||||
mo::parseValueInner moArgs "$moContent" "$moCurrent" "$moCloseDelimiter"
|
||||
moContent=${moArgs[0]}
|
||||
@ -1252,7 +1248,7 @@ mo::getArgumentDefault() {
|
||||
local moTemp moContent
|
||||
|
||||
moTemp=$2
|
||||
mo::chomp moTemp "${moTemp%%$3*}"
|
||||
mo::chomp moTemp "${moTemp%%"$3"*}"
|
||||
moTemp=${moTemp%%)*}
|
||||
moTemp=${moTemp%%\}*}
|
||||
moContent=${2:${#moTemp}}
|
||||
@ -1384,6 +1380,7 @@ mo::isTruthy() {
|
||||
|
||||
moTruthy=true
|
||||
|
||||
# shellcheck disable=SC2031
|
||||
if [[ -z "${1-}" ]]; then
|
||||
moTruthy=false
|
||||
elif [[ -n "${MO_FALSE_IS_EMPTY-}" ]] && [[ "${1-}" == "false" ]]; then
|
||||
@ -1533,7 +1530,7 @@ mo::evaluateKey() {
|
||||
#
|
||||
# Returns nothing.
|
||||
mo::evaluateVariable() {
|
||||
local moResult moCurrent moArg moNameParts moJoined moKey moValue
|
||||
local moResult moCurrent moArg moNameParts
|
||||
|
||||
moArg=$2
|
||||
moCurrent=$3
|
||||
@ -1543,7 +1540,7 @@ mo::evaluateVariable() {
|
||||
|
||||
if [[ -z "${moNameParts[1]}" ]]; then
|
||||
if mo::isArray "$moArg"; then
|
||||
eval mo::join moResult "," "\${$moArg[@]}"
|
||||
eval mo::join moResult "," "\${${moArg}[@]}"
|
||||
else
|
||||
# shellcheck disable=SC2031
|
||||
if mo::isVarSet "$moArg"; then
|
||||
@ -1560,7 +1557,7 @@ mo::evaluateVariable() {
|
||||
fi
|
||||
fi
|
||||
|
||||
local $1 && mo::indirect "$1" "$moResult"
|
||||
local "$1" && mo::indirect "$1" "$moResult"
|
||||
}
|
||||
|
||||
|
||||
@ -1648,7 +1645,7 @@ moJoin() {
|
||||
#
|
||||
# Returns nothing.
|
||||
mo::evaluateFunction() {
|
||||
local moArgs moContent moFunctionArgs moFunctionResult moTarget moFunction moTemp moFunctionCall
|
||||
local moArgs moContent moFunctionResult moTarget moFunction moTemp moFunctionCall
|
||||
|
||||
moTarget=$1
|
||||
moContent=$2
|
||||
@ -1675,16 +1672,18 @@ mo::evaluateFunction() {
|
||||
fi
|
||||
|
||||
mo::debug "Calling function: $moFunctionCall"
|
||||
moContent=$(export MO_FUNCTION_ARGS=("${moArgs[@]}"); echo -n "$moContent" | eval "$moFunctionCall") || {
|
||||
|
||||
# Call the function in a subshell for safety. Employ the trick to preserve
|
||||
# whitespace at the end of the output.
|
||||
moContent=$(export MO_FUNCTION_ARGS=("${moArgs[@]}"); echo -n "$moContent" | eval "$moFunctionCall ; moFunctionResult=\$? ; echo -n '.' ; exit \"\$moFunctionResult\"") || {
|
||||
moFunctionResult=$?
|
||||
# shellcheck disable=SC2031
|
||||
if [[ -n "${MO_FAIL_ON_FUNCTION-}" && "$moFunctionResult" != 0 ]]; then
|
||||
mo::error "Function '$moFunction' with args (${moArgs[@]+"${moArgs[@]}"}) failed with status code $moFunctionResult" "$moFunctionResult"
|
||||
mo::error "Function failed with status code $moFunctionResult: $moFunctionCall" "$moFunctionResult"
|
||||
fi
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2031
|
||||
local "$moTarget" && mo::indirect "$moTarget" "$moContent"
|
||||
local "$moTarget" && mo::indirect "$moTarget" "${moContent%.}"
|
||||
}
|
||||
|
||||
|
||||
@ -1704,7 +1703,7 @@ mo::standaloneCheck() {
|
||||
moT=$'\t'
|
||||
|
||||
# Check the content before
|
||||
moContent=${1//$moR/$moN}
|
||||
moContent=${1//"$moR"/"$moN"}
|
||||
|
||||
if [[ "$moContent" != *"$moN"* ]]; then
|
||||
mo::debug "Not a standalone tag - no newline before"
|
||||
@ -1712,8 +1711,8 @@ mo::standaloneCheck() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
moContent=${moContent##*$moN}
|
||||
moContent=${moContent//$moT/}
|
||||
moContent=${moContent##*"$moN"}
|
||||
moContent=${moContent//"$moT"/}
|
||||
moContent=${moContent// /}
|
||||
|
||||
if [[ -n "$moContent" ]]; then
|
||||
@ -1723,9 +1722,9 @@ mo::standaloneCheck() {
|
||||
fi
|
||||
|
||||
# Check the content after
|
||||
moContent=${2//$moR/$moN}
|
||||
moContent=${moContent%%$moN*}
|
||||
moContent=${moContent//$moT/}
|
||||
moContent=${2//"$moR"/"$moN"}
|
||||
moContent=${moContent%%"$moN"*}
|
||||
moContent=${moContent//"$moT"/}
|
||||
moContent=${moContent// /}
|
||||
|
||||
if [[ -n "$moContent" ]]; then
|
||||
@ -1756,7 +1755,7 @@ mo::standaloneProcessBefore() {
|
||||
while [[ "$moLast" != "$moContent" ]]; do
|
||||
moLast=$moContent
|
||||
moContent=${moContent% }
|
||||
moContent=${moContent%$moT}
|
||||
moContent=${moContent%"$moT"}
|
||||
done
|
||||
|
||||
local "$1" && mo::indirect "$1" "$moContent"
|
||||
@ -1783,11 +1782,11 @@ mo::standaloneProcessAfter() {
|
||||
while [[ "$moLast" != "$moContent" ]]; do
|
||||
moLast=$moContent
|
||||
moContent=${moContent# }
|
||||
moContent=${moContent#$moT}
|
||||
moContent=${moContent#"$moT"}
|
||||
done
|
||||
|
||||
moContent=${moContent#$moR}
|
||||
moContent=${moContent#$moN}
|
||||
moContent=${moContent#"$moR"}
|
||||
moContent=${moContent#"$moN"}
|
||||
|
||||
local "$1" && mo::indirect "$1" "$moContent"
|
||||
}
|
||||
@ -1816,8 +1815,8 @@ mo::indentLines() {
|
||||
mo::debug "Applying indentation: '${moIndentation}'"
|
||||
|
||||
while [[ -n "$moContent" ]]; do
|
||||
moChunk=${moContent%%$moN*}
|
||||
moChunk=${moChunk%%$moR*}
|
||||
moChunk=${moContent%%"$moN"*}
|
||||
moChunk=${moChunk%%"$moR"*}
|
||||
moContent=${moContent:${#moChunk}}
|
||||
|
||||
if [[ -n "$moChunk" ]]; then
|
||||
|
25
run-spec.js
25
run-spec.js
@ -11,6 +11,12 @@ const fsPromises = require("fs").promises;
|
||||
//
|
||||
// To override any test property, just define that property.
|
||||
const testOverrides = {
|
||||
"Comments -> Variable Name Collision": {
|
||||
// Can't use variables with exclamation points easily
|
||||
data: {
|
||||
comment: 4
|
||||
}
|
||||
},
|
||||
"Interpolation -> HTML Escaping": {
|
||||
skip: "HTML escaping is not supported"
|
||||
},
|
||||
@ -20,6 +26,9 @@ const testOverrides = {
|
||||
"Lambdas -> Escaping": {
|
||||
skip: "HTML escaping is not supported"
|
||||
},
|
||||
"Partials -> Recursion": {
|
||||
skip: "Complex objects are not supported and context is reset to the global level, so the recursion will loop forever"
|
||||
},
|
||||
"Sections -> Deeply Nested Contexts": {
|
||||
skip: "Nested objects are not supported"
|
||||
},
|
||||
@ -268,6 +277,7 @@ function applyTestOverrides(test) {
|
||||
test[key] = value;
|
||||
}
|
||||
|
||||
test.overridesApplied = true;
|
||||
test.valuesBeforeOverride = originals;
|
||||
}
|
||||
|
||||
@ -310,6 +320,7 @@ function processSpecFile(filename) {
|
||||
testSet.pass = 0;
|
||||
testSet.fail = 0;
|
||||
testSet.skip = 0;
|
||||
testSet.passOverride = 0;
|
||||
|
||||
for (const test of testSet.tests) {
|
||||
if (test.isFailure) {
|
||||
@ -318,10 +329,14 @@ function processSpecFile(filename) {
|
||||
testSet.skip += 1;
|
||||
} else {
|
||||
testSet.pass += 1;
|
||||
|
||||
if (test.overridesApplied) {
|
||||
testSet.passOverride += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
`### ${testSet.name} Results = ${testSet.pass} passed, ${testSet.fail} failed, ${testSet.skip} skipped`
|
||||
`### ${testSet.name} Results = ${testSet.pass} passed (with ${testSet.passOverride} overridden), ${testSet.fail} failed, ${testSet.skip} skipped`
|
||||
);
|
||||
|
||||
return testSet;
|
||||
@ -344,16 +359,18 @@ processArraySequentially(process.argv.slice(2), processSpecFile).then(
|
||||
let pass = 0,
|
||||
fail = 0,
|
||||
skip = 0,
|
||||
total = 0;
|
||||
total = 0,
|
||||
passOverride = 0;
|
||||
|
||||
for (const testSet of result) {
|
||||
pass += testSet.pass;
|
||||
fail += testSet.fail;
|
||||
skip += testSet.skip;
|
||||
total += testSet.tests.length;
|
||||
passOverride += testSet.passOverride;
|
||||
|
||||
console.log(
|
||||
`* ${testSet.name}: ${testSet.tests.length} total, ${testSet.pass} pass, ${testSet.fail} fail, ${testSet.skip} skip`
|
||||
`* ${testSet.name}: ${testSet.tests.length} total, ${testSet.pass} pass (with ${passOverride} overridden), ${testSet.fail} fail, ${testSet.skip} skip`
|
||||
);
|
||||
|
||||
for (const test of testSet.tests) {
|
||||
@ -365,7 +382,7 @@ processArraySequentially(process.argv.slice(2), processSpecFile).then(
|
||||
|
||||
console.log("");
|
||||
console.log(
|
||||
`Final result: ${total} total, ${pass} pass, ${fail} fail, ${skip} skip`
|
||||
`Final result: ${total} total, ${pass} pass (with ${passOverride} overridden), ${fail} fail, ${skip} skip`
|
||||
);
|
||||
|
||||
if (fail) {
|
||||
|
@ -52,6 +52,8 @@ runTest() (
|
||||
|
||||
if [[ -n "${MO_DEBUG_TEST-}" ]]; then
|
||||
declare -p testExpected
|
||||
# Align the two declare outputs
|
||||
echo -n " "
|
||||
declare -p testActual
|
||||
fi
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
thing="Works"
|
||||
template="{{&thing}}"
|
||||
expected="Works"
|
||||
export thing="Works"
|
||||
export template="{{&thing}}"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
repo=( "resque" "hub" "rip" )
|
||||
export repo=( "resque" "hub" "rip" )
|
||||
template() {
|
||||
cat <<EOF
|
||||
{{#repo}}
|
||||
|
@ -6,6 +6,7 @@ declare -A repo
|
||||
repo[resque]="Resque"
|
||||
repo[hub]="Hub"
|
||||
repo[rip]="Rip"
|
||||
export repo
|
||||
template() {
|
||||
cat <<EOF
|
||||
{{#repo}}
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
template="Wor{{!comment}}ks"
|
||||
expected="Works"
|
||||
export template="Wor{{!comment}}ks"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -10,10 +10,6 @@ run through multiple
|
||||
lines}}.</h1>
|
||||
EOF
|
||||
}
|
||||
expected() {
|
||||
cat <<EOF
|
||||
<h1>Today.</h1>
|
||||
EOF
|
||||
}
|
||||
export expected=$'<h1>Today.</h1>\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
template="Wor{{! comment }}ks"
|
||||
expected="Works"
|
||||
export template="Wor{{! comment }}ks"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -2,9 +2,9 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
thing="Wor"
|
||||
thing2="ks"
|
||||
template="{{thing thing2}}"
|
||||
expected="Works"
|
||||
export thing="Wor"
|
||||
export thing2="ks"
|
||||
export template="{{thing thing2}}"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
thing="Works"
|
||||
template="{{=| |=}}|thing|"
|
||||
expected="Works"
|
||||
export thing="Works"
|
||||
export template="{{=| |=}}|thing|"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -2,9 +2,9 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
arguments=(-- --help)
|
||||
returnCode=1
|
||||
template=""
|
||||
expected="cat: --help: No such file or directory"$'\n'
|
||||
export arguments=(--fail-on-file -- --help)
|
||||
export returnCode=1
|
||||
export template=""
|
||||
export expected=$'ERROR: No such file: --help\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
template='{{"Works"}}'
|
||||
expected="Works"
|
||||
export template='{{"Works"}}'
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -3,10 +3,10 @@ cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
unset __NO_SUCH_VAR
|
||||
POPULATED="words"
|
||||
EMPTY=""
|
||||
arguments=(--fail-not-set)
|
||||
returnCode=1
|
||||
export POPULATED="words"
|
||||
export EMPTY=""
|
||||
export arguments=(--fail-not-set)
|
||||
export returnCode=1
|
||||
|
||||
template() {
|
||||
cat <<EOF
|
||||
@ -15,10 +15,6 @@ Empty: {{EMPTY}};
|
||||
Unset: {{__NO_SUCH_VAR}};
|
||||
EOF
|
||||
}
|
||||
expected() {
|
||||
cat <<EOF
|
||||
ERROR: Environment variable not set: __NO_SUCH_VAR
|
||||
EOF
|
||||
}
|
||||
export expected=$'ERROR: Environment variable not set: __NO_SUCH_VAR\n'
|
||||
|
||||
runTest
|
||||
|
@ -5,14 +5,9 @@ cd "${0%/*}" || exit 1
|
||||
failFunction() {
|
||||
false
|
||||
}
|
||||
arguments=(--fail-on-function)
|
||||
returnCode=1
|
||||
|
||||
template="Fail on function? {{failFunction}}"
|
||||
expected() {
|
||||
cat <<EOF
|
||||
ERROR: Function 'failFunction' with args () failed with status code 1
|
||||
EOF
|
||||
}
|
||||
export arguments=(--fail-on-function)
|
||||
export returnCode=1
|
||||
export template="Fail on function? {{failFunction}}"
|
||||
export expected=$'ERROR: Function failed with status code 1: "failFunction"\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,9 +2,9 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
USER=j.doe
|
||||
ADMIN=false
|
||||
arguments=(--false)
|
||||
export USER=j.doe
|
||||
export ADMIN=false
|
||||
export arguments=(--false)
|
||||
template() {
|
||||
cat <<EOF
|
||||
The user {{USER}} exists.
|
||||
@ -13,10 +13,6 @@ WRONG - should not be an admin.
|
||||
{{/ADMIN}}
|
||||
EOF
|
||||
}
|
||||
expected() {
|
||||
cat <<EOF
|
||||
The user j.doe exists.
|
||||
EOF
|
||||
}
|
||||
export expected=$'The user j.doe exists.\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
USER=j.doe
|
||||
ADMIN=false
|
||||
export USER=j.doe
|
||||
export ADMIN=false
|
||||
MO_FALSE_IS_EMPTY=yeppers
|
||||
template() {
|
||||
cat <<EOF
|
||||
@ -13,10 +13,6 @@ WRONG - should not be an admin.
|
||||
{{/ADMIN}}
|
||||
EOF
|
||||
}
|
||||
expected() {
|
||||
cat <<EOF
|
||||
The user j.doe exists.
|
||||
EOF
|
||||
}
|
||||
export expected=$'The user j.doe exists.\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
person=""
|
||||
export person=""
|
||||
template() {
|
||||
cat <<EOF
|
||||
Shown.
|
||||
@ -11,10 +11,6 @@ Shown.
|
||||
{{/person}}
|
||||
EOF
|
||||
}
|
||||
expected() {
|
||||
cat <<EOF
|
||||
Shown.
|
||||
EOF
|
||||
}
|
||||
export expected=$'Shown.\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,9 +2,10 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
name=Willy
|
||||
export name=Willy
|
||||
wrapped() {
|
||||
# This eats the newline in the content
|
||||
# Wrapping 'cat' in a subshell eats the trailing whitespace
|
||||
# The echo adds a newline, which is preserved.
|
||||
echo "<b>$(cat)</b>"
|
||||
}
|
||||
template() {
|
||||
@ -15,10 +16,6 @@ template() {
|
||||
... this is the last line.
|
||||
EOF
|
||||
}
|
||||
expected() {
|
||||
cat <<EOF
|
||||
<b> Willy is awesome.</b>... this is the last line.
|
||||
EOF
|
||||
}
|
||||
export expected=$'<b> Willy is awesome.</b>\n... this is the last line.\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
name=Willy
|
||||
export name=Willy
|
||||
MO_ALLOW_FUNCTION_ARGUMENTS=true
|
||||
|
||||
pipeTo() {
|
||||
|
@ -3,8 +3,10 @@ cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
testArgs() {
|
||||
local args=$(declare -p MO_FUNCTION_ARGS)
|
||||
echo "${args#*=}"
|
||||
local args
|
||||
# shellcheck disable=SC2031
|
||||
args=$(declare -p MO_FUNCTION_ARGS)
|
||||
echo -n "${args#*=}"
|
||||
}
|
||||
template() {
|
||||
cat <<EOF
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
STR=abc
|
||||
DATA=(111 222)
|
||||
export STR=abc
|
||||
export DATA=(111 222)
|
||||
template() {
|
||||
cat <<EOF
|
||||
Issue #7
|
||||
|
55
tests/help
55
tests/help
@ -2,10 +2,9 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
template=""
|
||||
arguments=(--help)
|
||||
export arguments=(--help)
|
||||
expected() {
|
||||
cat <<EOF
|
||||
cat <<'EOF'
|
||||
Mo is a mustache template rendering software written in bash. It inserts
|
||||
environment variables into templates.
|
||||
|
||||
@ -21,19 +20,59 @@ Simple usage:
|
||||
|
||||
Options:
|
||||
|
||||
--allow-function-arguments
|
||||
Permit functions to be called with additional arguments. Otherwise,
|
||||
the only way to get access to the arguments is to use the
|
||||
MO_FUNCTION_ARGS environment variable.
|
||||
-d, --debug
|
||||
Enable debug logging to stderr.
|
||||
-u, --fail-not-set
|
||||
Fail upon expansion of an unset variable.
|
||||
Fail upon expansion of an unset variable. Will silently ignore by
|
||||
default. Alternately, set MO_FAIL_ON_UNSET to a non-empty value.
|
||||
-x, --fail-on-function
|
||||
Fail when a function returns a non-zero status code.
|
||||
Fail when a function returns a non-zero status code instead of
|
||||
silently ignoring it. Alternately, set MO_FAIL_ON_FUNCTION to a
|
||||
non-empty value.
|
||||
-f, --fail-on-file
|
||||
Fail when a file (from command-line or partial) does not exist.
|
||||
Alternately, set MO_FAIL_ON_FILE to a non-empty value.
|
||||
-e, --false
|
||||
Treat the string "false" as empty for conditionals.
|
||||
Treat the string "false" as empty for conditionals. Alternately,
|
||||
set MO_FALSE_IS_EMPTY to a non-empty value.
|
||||
-h, --help
|
||||
This message.
|
||||
-s=FILE, --source=FILE
|
||||
Load FILE into the environment before processing templates.
|
||||
Can be used multiple times.
|
||||
-d, --debug
|
||||
Enable debug logging to stderr.
|
||||
-- Indicate the end of options. All arguments after this will be
|
||||
treated as filenames only. Use when filenames may start with
|
||||
hyphens.
|
||||
|
||||
Mo uses the following environment variables:
|
||||
|
||||
MO_ALLOW_FUNCTION_ARGUMENTS - When set to a non-empty value, this allows
|
||||
functions referenced in templates to receive additional options and
|
||||
arguments.
|
||||
MO_DEBUG - When set to a non-empty value, additional debug information is
|
||||
written to stderr.
|
||||
MO_FUNCTION_ARGS - Arguments passed to the function.
|
||||
MO_FAIL_ON_FILE - If a filename from the command-line is missing or a
|
||||
partial does not exist, abort with an error.
|
||||
MO_FAIL_ON_FUNCTION - If a function returns a non-zero status code, abort
|
||||
with an error.
|
||||
MO_FAIL_ON_UNSET - When set to a non-empty value, expansion of an unset env
|
||||
variable will be aborted with an error.
|
||||
MO_FALSE_IS_EMPTY - When set to a non-empty value, the string "false" will
|
||||
be treated as an empty value for the purposes of conditionals.
|
||||
MO_ORIGINAL_COMMAND - Used to find the `mo` program in order to generate a
|
||||
help message.
|
||||
|
||||
Mo is under a MIT style licence with an additional non-advertising clause.
|
||||
See LICENSE.md for the full text.
|
||||
|
||||
This is open source! Please feel free to contribute.
|
||||
|
||||
https://github.com/tests-always-included/mo
|
||||
|
||||
MO_VERSION=3.0.0
|
||||
EOF
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
thisIsTrue=true
|
||||
export thisIsTrue=true
|
||||
template() {
|
||||
cat <<EOF
|
||||
With spacing
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
boolean=true
|
||||
template=$' | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n'
|
||||
expected=$' | \n | \n'
|
||||
export boolean=true
|
||||
export template=$' | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n'
|
||||
export expected=$' | \n | \n'
|
||||
|
||||
runTest
|
||||
|
@ -2,14 +2,10 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
person=""
|
||||
template=""
|
||||
returnCode=1
|
||||
arguments=(--something)
|
||||
expected() {
|
||||
cat <<EOF
|
||||
cat: --something: No such file or directory
|
||||
EOF
|
||||
}
|
||||
export person=""
|
||||
export template=""
|
||||
export returnCode=1
|
||||
export arguments=(--something)
|
||||
export expected=$'ERROR: Unknown option: --something (See --help for options)\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
repo=()
|
||||
export repo=()
|
||||
template() {
|
||||
cat <<EOF
|
||||
{{#repo}}
|
||||
@ -13,10 +13,6 @@ template() {
|
||||
{{/repo}}
|
||||
EOF
|
||||
}
|
||||
expected() {
|
||||
cat <<EOF
|
||||
No repos :(
|
||||
EOF
|
||||
}
|
||||
export expected=$' No repos :(\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,13 +2,15 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
a=foo
|
||||
b=wrong
|
||||
export a=foo
|
||||
export b=wrong
|
||||
declare -A sec
|
||||
sec=([b]="bar")
|
||||
export sec
|
||||
declare -A c
|
||||
c=([d]="baz")
|
||||
template="{{#sec}}{{a}} {{b}} {{c.d}}{{/sec}}"
|
||||
expected="foo bar baz"
|
||||
export c
|
||||
export template="{{#sec}}{{a}} {{b}} {{c.d}}{{/sec}}"
|
||||
export expected="foo bar baz"
|
||||
|
||||
runTest
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
name="Chris"
|
||||
company="<b>GitHub</b>"
|
||||
export name="Chris"
|
||||
export company="<b>GitHub</b>"
|
||||
template() {
|
||||
cat <<EOF
|
||||
* .{{name}}.
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
multilineData=$'line 1\nline 2'
|
||||
export multilineData=$'line 1\nline 2'
|
||||
template() {
|
||||
cat <<EOF
|
||||
Partial:
|
||||
@ -26,7 +26,10 @@ Indented:
|
||||
line 1
|
||||
line 2
|
||||
EOF
|
||||
# This one looks odd, but if you check the spec spec/specs/partials.yaml, name "Standalone Indentation" (mirrors "standalone-indentation" in tests/), then the spec clearly shows that the indentation is applied before rendering.
|
||||
# This one looks odd, but if you check the spec spec/specs/partials.yaml,
|
||||
# name "Standalone Indentation" (mirrors "standalone-indentation" in
|
||||
# tests/), then the spec clearly shows that the indentation is applied
|
||||
# before rendering.
|
||||
}
|
||||
|
||||
runTest
|
||||
|
12
tests/mush
12
tests/mush
@ -2,12 +2,12 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
USER=jwerle
|
||||
GENDER=male
|
||||
THING=apple
|
||||
COLOR=red
|
||||
PERSON=tobi
|
||||
ADJECTIVE=cool
|
||||
export USER=jwerle
|
||||
export GENDER=male
|
||||
export THING=apple
|
||||
export COLOR=red
|
||||
export PERSON=tobi
|
||||
export ADJECTIVE=cool
|
||||
template() {
|
||||
cat <<EOF
|
||||
{{! this is a comment }}
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
template="Works"
|
||||
expected="Works"
|
||||
export template="Works"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
names=( "Tyler" )
|
||||
export names=( "Tyler" )
|
||||
template() {
|
||||
cat <<EOF
|
||||
<h2>Names</h2>
|
||||
|
9
tests/partial-bad-file
Executable file
9
tests/partial-bad-file
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
# This file intentionally does not exist
|
||||
export template="{{>fixtures/partial-bad-file.partial}}"
|
||||
export expected=""
|
||||
|
||||
runTest
|
@ -2,8 +2,9 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
returnCode=1
|
||||
person=""
|
||||
export returnCode=1
|
||||
export arguments=(--fail-on-file)
|
||||
export person=""
|
||||
template() {
|
||||
cat <<EOF
|
||||
Won't be there: {{> fixtures/partial-missing.partial}}
|
||||
@ -11,7 +12,7 @@ EOF
|
||||
}
|
||||
expected() {
|
||||
cat <<EOF
|
||||
cat: partial-missing.partial: No such file or directory
|
||||
ERROR: No such file: partial-missing.partial
|
||||
EOF
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
template="{{'Works'}}"
|
||||
expected="Works"
|
||||
export template="{{'Works'}}"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
thing="Works"
|
||||
template="{{thing}}"
|
||||
expected="Works"
|
||||
export thing="Works"
|
||||
export template="{{thing}}"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
arguments=(--source=fixtures/source.vars)
|
||||
export arguments=(--source=fixtures/source.vars)
|
||||
template() {
|
||||
cat <<EOF
|
||||
{{VAR}}
|
||||
|
@ -2,13 +2,9 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
arguments=(--source=invalid)
|
||||
returnCode=1
|
||||
template="Do not display this"
|
||||
expected() {
|
||||
cat <<EOF
|
||||
No such file: invalid
|
||||
EOF
|
||||
}
|
||||
export arguments=(--source=invalid)
|
||||
export returnCode=1
|
||||
export template="Do not display this"
|
||||
export expected=$'No such file: invalid\n'
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
arguments=(--source=fixtures/source-multiple-1.vars --source=fixtures/source-multiple-2.vars)
|
||||
export arguments=(--source=fixtures/source-multiple-1.vars --source=fixtures/source-multiple-2.vars)
|
||||
template() {
|
||||
cat <<EOF
|
||||
A: {{A}}
|
||||
|
@ -2,9 +2,9 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
arguments=(--source=)
|
||||
returnCode=1
|
||||
template="Do not display this"
|
||||
expected=$'No such file: \n'
|
||||
export arguments=(--source=)
|
||||
export returnCode=1
|
||||
export template="Do not display this"
|
||||
export expected=$'No such file: \n'
|
||||
|
||||
runTest
|
||||
|
@ -2,7 +2,7 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
content=$'<\n->'
|
||||
export content=$'<\n->'
|
||||
template() {
|
||||
cat <<EOF
|
||||
\
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
thing="Works"
|
||||
template="{{{thing}}}"
|
||||
expected="Works"
|
||||
export thing="Works"
|
||||
export template="{{{thing}}}"
|
||||
export expected="Works"
|
||||
|
||||
runTest
|
||||
|
@ -2,10 +2,10 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
NAME="Chris"
|
||||
VALUE=10000
|
||||
TAXED_VALUE=6000
|
||||
IN_CA=true
|
||||
export NAME="Chris"
|
||||
export VALUE=10000
|
||||
export TAXED_VALUE=6000
|
||||
export IN_CA=true
|
||||
template() {
|
||||
cat <<EOF
|
||||
Hello {{NAME}}
|
||||
|
@ -3,8 +3,8 @@ cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
declare -A a
|
||||
a=()
|
||||
template="o{{#a.b}}WRONG{{/a.b}}k"
|
||||
expected="ok"
|
||||
export a=()
|
||||
export template="o{{#a.b}}WRONG{{/a.b}}k"
|
||||
export expected="ok"
|
||||
|
||||
runTest
|
||||
|
@ -2,8 +2,8 @@
|
||||
cd "${0%/*}" || exit 1
|
||||
. ../run-tests
|
||||
|
||||
foo=bar
|
||||
template="{{#foo}}{{.}} is {{foo}}{{/foo}}"
|
||||
expected="bar is bar"
|
||||
export foo=bar
|
||||
export template="{{#foo}}{{.}} is {{foo}}{{/foo}}"
|
||||
export expected="bar is bar"
|
||||
|
||||
runTest
|
||||
|
Loading…
Reference in New Issue
Block a user