diff --git a/.vscode/settings.json b/.vscode/settings.json index 97990d6..c2ab8a3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,6 @@ "cSpell.words": [ "nocasematch", "Pids" - ] + ], + "editor.wordSeparators": "`~!@#$%^&*()-=+[{]}\\|;'\",.<>/?" } \ No newline at end of file diff --git a/commands.d/help.sh b/commands.d/help.sh index aad8133..3825bf0 100644 --- a/commands.d/help.sh +++ b/commands.d/help.sh @@ -47,7 +47,7 @@ examples: function showCommandHelp() { local -a commands local parsingErrors help columns noColors help - main::parseFunctionArguments "${FUNCNAME[0]:-}" "$@" + command::parseFunctionArguments "${FUNCNAME[0]:-}" "$@" eval "${RETURNED_VALUE}" core::checkParseResults "${help:-}" "${parsingErrors:-}" diff --git a/commands.d/self-build.sh b/commands.d/self-build.sh index 6c5241e..e002a41 100644 --- a/commands.d/self-build.sh +++ b/commands.d/self-build.sh @@ -262,7 +262,7 @@ function bumpValetBuildVersion() { local currentVersion="${RETURNED_VALUE:-0.0.0}" currentVersion="${currentVersion%%$'\n'*}" - string::bumpSemanticVersion "${currentVersion}" "patch" "false" + version::bump "${currentVersion}" "patch" "false" printf '%s' "${RETURNED_VALUE}" >"${GLOBAL_VALET_HOME}/version" @@ -716,6 +716,8 @@ source array source io # shellcheck source=../libraries.d/lib-string source string +# shellcheck source=../libraries.d/lib-version +source version # if this script is run directly, execute the function, otherwise valet will do it if [[ ${_NOT_EXECUTED_FROM_VALET:-false} == "true" ]]; then diff --git a/commands.d/self-install.sh b/commands.d/self-install.sh index b35689e..bde1cae 100644 --- a/commands.d/self-install.sh +++ b/commands.d/self-install.sh @@ -233,7 +233,7 @@ function selfUpdate() { currentVersion="${currentVersion%%$'\n'*}" # compare local and distant versions - string::compareSemanticVersion "${currentVersion}" "${version}" + version::compare "${currentVersion}" "${version}" if [[ ${RETURNED_VALUE} == "0" || ${RETURNED_VALUE} == "1" ]]; then log::info "The current local version ⌜${currentVersion}⌝ is higher or equal to the distant version ⌜${version}⌝." log::success "You already have the latest version." @@ -597,6 +597,8 @@ function selfUpdate_sourceDependencies() { source io # shellcheck source=../libraries.d/lib-string source string + # shellcheck source=../libraries.d/lib-version + source version } # Create a shim (script that calls valet) in a bin directory. diff --git a/commands.d/self-release.sh b/commands.d/self-release.sh index cfed99e..6677f07 100644 --- a/commands.d/self-release.sh +++ b/commands.d/self-release.sh @@ -21,6 +21,8 @@ source interactive source system # shellcheck source=../libraries.d/lib-array source array +# shellcheck source=../libraries.d/lib-version +source version #=============================================================== # >>> self release valet @@ -312,7 +314,7 @@ function selfRelease::bumpVersion() { log::info "The current version of valet is: ${version}." # bump the version - string::bumpSemanticVersion "${version}" "${bumpLevel}" && newVersion="${RETURNED_VALUE}" + version::bump "${version}" "${bumpLevel}" && newVersion="${RETURNED_VALUE}" if [[ "${dryRun:-}" != "true" ]]; then io::writeToFile "${GLOBAL_VALET_HOME}/version" "${newVersion}"; fi log::info "The bumped version of valet is: ${newVersion}." diff --git a/commands.d/self-test-utils b/commands.d/self-test-utils index 69c0174..e68edec 100644 --- a/commands.d/self-test-utils +++ b/commands.d/self-test-utils @@ -73,8 +73,9 @@ function selfTestUtils_setupValetForConsistency() { # fix the time to a known value export TZ=Etc/GMT+0 - # unset EPOCHSECONDS EPOCHREALTIME + unset EPOCHSECONDS export EPOCHSECONDS=548902800 + # can't unset EPOCHREALTIME because we use it in PS4 during debug, #TODO: need to fix that export EPOCHREALTIME=548902800.000000 log::createPrintFunction diff --git a/docs/content/docs/800.roadmap/_index.md b/docs/content/docs/800.roadmap/_index.md index 4edfc8b..400bdd5 100644 --- a/docs/content/docs/800.roadmap/_index.md +++ b/docs/content/docs/800.roadmap/_index.md @@ -57,5 +57,6 @@ This page lists the features that I would like to implement in Valet. They come - handle shift + arrows to highlight text - add a stack for kill/yank - add a stack for undo/redo +- add a new command self diagnostic that will run a series of tests to check the environment and help figure out what's wrong. [valet-issues]: https://github.com/jcaillon/valet/issues diff --git a/libraries.d/core b/libraries.d/core index ce80b68..dc6a839 100644 --- a/libraries.d/core +++ b/libraries.d/core @@ -49,8 +49,11 @@ function core::setShellOptions() { # default IFS IFS=' '$'\t'$'\n' - # set a fixed locale (otherwise we would risk to have comma as decimal separator - # for EPOCHREALTIME for instance). + # Set a locale otherwise we will face inconsistencies in the output of commands: + # - file listing will not sort the same way + # - string comparison < and > will not have the same behavior + # - `EPOCHREALTIME` can output with a comma as decimal separator instead of a dot + # - ... # If the user does not have the locale, they will get a warning here. # In which case they must either generate the locale C.utf8 or set an existing locale # listed in `locale -a` via the VALET_CONFIG_LOCALE environment variable. @@ -1706,7 +1709,7 @@ function core::parseArguments() { # get the function name of the calling function functionName="${FUNCNAME[1]?"This function must be called from a command function."}" - main::parseFunctionArgumentsOrGoInteractive "${functionName}" "$@" + main::parseCmdFunctionArgumentsOrGoInteractive "${functionName}" "$@" } # ## core::checkParseResults diff --git a/libraries.d/lib-string b/libraries.d/lib-string index c12da08..75a06bc 100644 --- a/libraries.d/lib-string +++ b/libraries.d/lib-string @@ -47,118 +47,6 @@ function string::cutField() { RETURNED_VALUE="" } -# ## string::compareSemanticVersion -# -# This function allows to compare two semantic versions formatted like: -# major.minor.patch-prerelease+build -# -# - $1: **version1** _as string_: -# the first version to compare -# - $2: **version2** _as string_: -# the second version to compare -# -# Returns: -# -# - `RETURNED_VALUE`: -# - 0 if the versions are equal, -# - 1 if version1 is greater, -# - -1 if version2 is greater -# -# ```bash -# string::compareSemanticVersion "2.3.4-prerelease+build" "1.2.3-prerelease+build" -# local comparison="${RETURNED_VALUE}" -# ``` -# -# > The prerelease and build are ignored in the comparison. -function string::compareSemanticVersion() { - local version1="${1#v}" - local version2="${2#v}" - - local -i semVerIndex - local semVerNumber1 semVerNumber2 - for semVerIndex in {0..2}; do - string::cutField "${version1}" "${semVerIndex}" "." - semVerNumber1="${RETURNED_VALUE%%-*}" - semVerNumber1="${semVerNumber1%%+*}" - string::cutField "${version2}" "${semVerIndex}" "." - semVerNumber2="${RETURNED_VALUE%%-*}" - semVerNumber2="${semVerNumber2%%+*}" - if [[ ! ${semVerNumber1} =~ ^[0-9]+$ || ! ${semVerNumber2} =~ ^[0-9]+$ ]]; then - core::fail "Failed to compare versions ⌜${version1}⌝ and ⌜${version2}⌝ because they are not valid semantic versions." - elif (( semVerNumber1 > semVerNumber2 )); then - RETURNED_VALUE=1 - return 0 - elif (( semVerNumber1 < semVerNumber2 )); then - RETURNED_VALUE=-1 - return 0 - fi - done - RETURNED_VALUE=0 -} - -# ## string::bumpSemanticVersion -# -# This function allows to bump a semantic version formatted like: -# major.minor.patch-prerelease+build -# -# - $1: **version** _as string_: -# the version to bump -# - $2: **level** _as string_: -# the level to bump (major, minor, patch) -# - $3: clear build and prerelease _as bool_: -# (optional) clear the prerelease and build -# (defaults to true) -# -# Returns: -# -# - `RETURNED_VALUE`: the new version string -# -# ```bash -# string::bumpSemanticVersion "1.2.3-prerelease+build" "major" -# local newVersion="${RETURNED_VALUE}" -# ``` -function string::bumpSemanticVersion() { - local version level clearPreRelease - version="${1}" - bumpLevel="${2}" - clearPreRelease="${3:-true}" - - local prerelease build modifiedVersion - modifiedVersion="${version}-+" - prerelease="${modifiedVersion#*-}" - prerelease="${prerelease%%+*}" - if [[ -n "${prerelease}" ]]; then prerelease="-${prerelease%-}"; fi - build="${modifiedVersion#*+}" - if [[ -n "${build}" ]]; then - build="+${build%-+}" - fi - - # bump the version - local -i level semVerNumber semVerIndex - level=2 - if [[ ${bumpLevel:-} == "major" ]]; then level=0; fi - if [[ ${bumpLevel:-} == "minor" ]]; then level=1; fi - local newVersion semVerString - for semVerIndex in {0..2}; do - string::cutField "${version}" "${semVerIndex}" "." - semVerString="${RETURNED_VALUE%-*}" - if [[ ! ${semVerString} =~ ^[0-9]+$ ]]; then - core::fail "Failed to bump the version ⌜${version}⌝ because it is not valid semantic version." - fi - semVerNumber="${semVerString%+}" - if [[ semVerIndex -eq level ]]; then semVerNumber=$((semVerNumber + 1)); fi - if [[ semVerIndex -gt level ]]; then semVerNumber=0; fi - newVersion+="${semVerNumber}." - done - newVersion="${newVersion%.}" - - if [[ "${clearPreRelease}" != "true" ]]; then - newVersion="${newVersion%.}${prerelease}${build}" - fi - - RETURNED_VALUE="${newVersion}" -} - # ## string::camelCaseToSnakeCase # # This function convert a camelCase string to a SNAKE_CASE string. diff --git a/libraries.d/lib-system b/libraries.d/lib-system index ec35575..6f745dc 100644 --- a/libraries.d/lib-system +++ b/libraries.d/lib-system @@ -71,7 +71,7 @@ function system::env() { # # > This function avoid to call $(date) in a subshell (date is a an external executable). function system::date() { - local format="${1:-'%(%F_%Hh%Mm%Ss)T'}" + local format="${1:-"%(%F_%Hh%Mm%Ss)T"}" # shellcheck disable=SC2059 printf -v RETURNED_VALUE "${format}" "${EPOCHSECONDS}" } diff --git a/libraries.d/lib-version b/libraries.d/lib-version new file mode 100644 index 0000000..0aa7df0 --- /dev/null +++ b/libraries.d/lib-version @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +# author: github.com/jcaillon +# description: This script can be sourced by commands to provide convenient functions. + +# shellcheck source=lib-string +source string + +# ## version::compare +# +# This function allows to compare two semantic versions formatted like: +# major.minor.patch-prerelease+build +# +# - $1: **version1** _as string_: +# the first version to compare +# - $2: **version2** _as string_: +# the second version to compare +# +# Returns: +# +# - `RETURNED_VALUE`: +# - 0 if the versions are equal, +# - 1 if version1 is greater, +# - -1 if version2 is greater +# +# ```bash +# version::compare "2.3.4-prerelease+build" "1.2.3-prerelease+build" +# local comparison="${RETURNED_VALUE}" +# ``` +# +# > The prerelease and build are ignored in the comparison. +function version::compare() { + local version1="${1#v}" + local version2="${2#v}" + + local -i semVerIndex + local semVerNumber1 semVerNumber2 + for semVerIndex in {0..2}; do + string::cutField "${version1}" "${semVerIndex}" "." + semVerNumber1="${RETURNED_VALUE%%-*}" + semVerNumber1="${semVerNumber1%%+*}" + string::cutField "${version2}" "${semVerIndex}" "." + semVerNumber2="${RETURNED_VALUE%%-*}" + semVerNumber2="${semVerNumber2%%+*}" + if [[ ! ${semVerNumber1} =~ ^[0-9]+$ || ! ${semVerNumber2} =~ ^[0-9]+$ ]]; then + core::fail "Failed to compare versions ⌜${version1}⌝ and ⌜${version2}⌝ because they are not valid semantic versions." + elif (( semVerNumber1 > semVerNumber2 )); then + RETURNED_VALUE=1 + return 0 + elif (( semVerNumber1 < semVerNumber2 )); then + RETURNED_VALUE=-1 + return 0 + fi + done + RETURNED_VALUE=0 +} + +# ## version::bump +# +# This function allows to bump a semantic version formatted like: +# major.minor.patch-prerelease+build +# +# - $1: **version** _as string_: +# the version to bump +# - $2: **level** _as string_: +# the level to bump (major, minor, patch) +# - $3: clear build and prerelease _as bool_: +# (optional) clear the prerelease and build +# (defaults to true) +# +# Returns: +# +# - `RETURNED_VALUE`: the new version string +# +# ```bash +# version::bump "1.2.3-prerelease+build" "major" +# local newVersion="${RETURNED_VALUE}" +# ``` +function version::bump() { + local version level clearPreRelease + version="${1}" + bumpLevel="${2}" + clearPreRelease="${3:-true}" + + local prerelease build modifiedVersion + modifiedVersion="${version}-+" + prerelease="${modifiedVersion#*-}" + prerelease="${prerelease%%+*}" + if [[ -n "${prerelease}" ]]; then prerelease="-${prerelease%-}"; fi + build="${modifiedVersion#*+}" + if [[ -n "${build}" ]]; then + build="+${build%-+}" + fi + + # bump the version + local -i level semVerNumber semVerIndex + level=2 + if [[ ${bumpLevel:-} == "major" ]]; then level=0; fi + if [[ ${bumpLevel:-} == "minor" ]]; then level=1; fi + local newVersion semVerString + for semVerIndex in {0..2}; do + string::cutField "${version}" "${semVerIndex}" "." + semVerString="${RETURNED_VALUE%-*}" + if [[ ! ${semVerString} =~ ^[0-9]+$ ]]; then + core::fail "Failed to bump the version ⌜${version}⌝ because it is not valid semantic version." + fi + semVerNumber="${semVerString%+}" + if [[ semVerIndex -eq level ]]; then semVerNumber=$((semVerNumber + 1)); fi + if [[ semVerIndex -gt level ]]; then semVerNumber=0; fi + newVersion+="${semVerNumber}." + done + newVersion="${newVersion%.}" + + if [[ "${clearPreRelease}" != "true" ]]; then + newVersion="${newVersion%.}${prerelease}${build}" + fi + + RETURNED_VALUE="${newVersion}" +} + diff --git a/libraries.d/main b/libraries.d/main index 1266f28..d7fbaf2 100644 --- a/libraries.d/main +++ b/libraries.d/main @@ -447,6 +447,7 @@ function main::parseMainArgumentsSwitch() { VALET_FORCE_INTERACTIVE_MODE=true ;; --disable-progress-bars) + # shellcheck disable=SC2034 VALET_DISABLE_PROGRESS_BARS=true ;; --version) @@ -604,7 +605,7 @@ function main::runMenuWithSubCommands() { CMD_COMMAND__menu="${command}" local parsedArguments - main::parseFunctionArguments "_menu" "$@" + command::parseFunctionArguments "_menu" "$@" parsedArguments="${RETURNED_VALUE}" if log::isDebugEnabled; then log::debug "Parsed arguments:" @@ -932,19 +933,17 @@ function main::fuzzyMatchCommandToFunctionNameOrFail() { # Usage: # main::getMaxPossibleCommandLevel "cmd1" "subcmd2" "subsubcmd3" && level="${RETURNED_VALUE}" function main::getMaxPossibleCommandLevel() { - local command commandPart level maxLevel - # count the number of spaces - command="${*}" + local level maxLevel + local IFS=' ' level=0 - # shellcheck disable=SC2034 - for commandPart in ${command}; do + # shellcheck disable=SC2048 + for _ in ${*}; do level=$((level + 1)) done maxLevel=$((CMD_MAX_SUB_COMMAND_LEVEL + 1)) - if [[ "${level}" -gt "${maxLevel}" ]]; then + if (( level > CMD_MAX_SUB_COMMAND_LEVEL + 1 )); then level="${maxLevel}" fi - RETURNED_VALUE="${level}" } @@ -954,7 +953,7 @@ function main::getMaxPossibleCommandLevel() { # Parses the arguments and options of a function. # Usage: -# main::parseFunctionArguments "functionName" "$@" && eval "${RETURNED_VALUE}" +# command::parseFunctionArguments "functionName" "$@" && eval "${RETURNED_VALUE}" # # Notes: # - It will return a string that can be evaluated to set the variables @@ -966,7 +965,7 @@ function main::getMaxPossibleCommandLevel() { # - It will also set the variable parsingErrors if there are any errors. # - Variable name for an option is taken from the first --long version of the option. # - It will set the variable as an array if the (last) argument name ends with '...' -function main::parseFunctionArguments() { +function command::parseFunctionArguments() { local functionName functionName="${1}" shift @@ -1350,13 +1349,13 @@ function main::getSingleLetterOptions() { # See the @core::parseArguments function for more details on parsing. # # Usage: -# main::parseFunctionArgumentsOrGoInteractive "functionName" "$@" && eval "${RETURNED_VALUE}" -function main::parseFunctionArgumentsOrGoInteractive() { +# main::parseCmdFunctionArgumentsOrGoInteractive "functionName" "$@" && eval "${RETURNED_VALUE}" +function main::parseCmdFunctionArgumentsOrGoInteractive() { local functionName functionName="${1}" shift - main::parseFunctionArguments "${functionName}" "$@" + command::parseFunctionArguments "${functionName}" "$@" local parsedArguments="${RETURNED_VALUE}" if log::isDebugEnabled; then log::debug "Parsed arguments:" diff --git a/tests.d/after-each-test b/tests.d/after-each-test index fd3f10e..8d446d4 100644 --- a/tests.d/after-each-test +++ b/tests.d/after-each-test @@ -2,7 +2,7 @@ if [[ ${GLOBAL_TEST_SUITE_NAME:-} == "lib-test" ]]; then TESTING_HOOKS+="after-each-test" test::title "🪝 Testing the self test hooks" - test::markdown "The variable TESTING_HOOKS shows that the hooks [before-tests](../before-tests), [before-each-test-suite](../before-each-test-suite), [before-each-test](before-each-test) have been executed." \ - "This test is written in the [after-each-test](after-each-test) script. The \`after-each-test-suites\` and \`after-tests\` are executed after the test script exits, thus we can't output their results in this report." + test::markdown "The variable TESTING_HOOKS shows that the hooks [before-tests](../before-tests), [before-each-test-suite](../before-each-test-suite), [before-each-test](../before-each-test) have been executed." \ + "This test is written in the [after-each-test](../after-each-test) script. The \`after-each-test-suites\` and \`after-tests\` are executed after the test script exits, thus we can't output their results in this report." test::printVars TESTING_HOOKS fi \ No newline at end of file diff --git a/tests.d/cli-features/results.approved.md b/tests.d/cli-features/results.approved.md index d8f2d7b..4268af3 100644 --- a/tests.d/cli-features/results.approved.md +++ b/tests.d/cli-features/results.approved.md @@ -44,7 +44,7 @@ Returned code: `1` WARNING This is for testing valet core functions, the next statement will return 1 and create an error. ERROR Error code 1 in selfMock1(), stack: ├─ in selfMock1() at $GLOBAL_VALET_HOME/tests.d/.commands.d/self-mock.sh:52 -├─ in main::runFunction() at $GLOBAL_VALET_HOME/libraries.d/main:564 +├─ in main::runFunction() at $GLOBAL_VALET_HOME/libraries.d/main:565 ├─ in main::parseMainArguments() at $GLOBAL_VALET_HOME/libraries.d/main:423 └─ in main() at valet:110 ``` @@ -62,7 +62,7 @@ WARNING This is for testing valet core functions, exiting with code 5. WARNING This is a custom on exit function. EXIT Exiting with code 5, stack: ├─ in selfMock1() at $GLOBAL_VALET_HOME/tests.d/.commands.d/self-mock.sh:1 -├─ in main::runFunction() at $GLOBAL_VALET_HOME/libraries.d/main:564 +├─ in main::runFunction() at $GLOBAL_VALET_HOME/libraries.d/main:565 ├─ in main::parseMainArguments() at $GLOBAL_VALET_HOME/libraries.d/main:423 └─ in main() at valet:110 ``` @@ -105,7 +105,7 @@ ERROR Command not found: ⌜thisIsAnUnknownCommandForTesting⌝. Please check your ⌜PATH⌝ variable. ERROR Error code 1 in selfMock1(), stack: ├─ in selfMock1() at $GLOBAL_VALET_HOME/tests.d/.commands.d/self-mock.sh:70 -├─ in main::runFunction() at $GLOBAL_VALET_HOME/libraries.d/main:564 +├─ in main::runFunction() at $GLOBAL_VALET_HOME/libraries.d/main:565 ├─ in main::parseMainArguments() at $GLOBAL_VALET_HOME/libraries.d/main:423 └─ in main() at valet:110 ``` diff --git a/tests.d/lib-command/00.parser.sh b/tests.d/lib-command/00.parser.sh new file mode 100644 index 0000000..3b2899a --- /dev/null +++ b/tests.d/lib-command/00.parser.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +function main() { + test_command::parseFunctionArguments +} + +function test_command::parseFunctionArguments() { + test::title "✅ Testing command::parseFunctionArguments" + + test::markdown "Missing argument:" + test::func command::parseFunctionArguments selfMock2 + + test::markdown "ok" + test::func command::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 more1 more2 + + test::markdown "missing argument" + test::func command::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 + + test::markdown "unknown options" + test::func command::parseFunctionArguments selfMock2 --unknown --what optionValue2 arg + + test::markdown "ok with the option at the end" + test::func command::parseFunctionArguments selfMock2 arg more1 more2 -o + + test::markdown "fuzzy match the option --this" + test::func command::parseFunctionArguments selfMock2 --this arg more1 + + test::markdown "ok, --option1 is interpreted as the value for --this-is-option2" + test::func command::parseFunctionArguments selfMock2 --this-is-option2 --option1 arg more1 + + test::markdown "ok only args" + test::func command::parseFunctionArguments selfMock4 arg1 arg2 + + test::markdown "ok with -- to separate options from args" + test::func command::parseFunctionArguments selfMock2 -- --arg1-- --arg2-- + + test::markdown "missing a value for the option 2" + test::func command::parseFunctionArguments selfMock2 arg1 arg2 --this-is-option2 + + test::markdown "ambiguous fuzzy match" + test::func command::parseFunctionArguments selfMock2 arg1 arg2 --th + + test::markdown "ok single letter options grouped together" + test::func command::parseFunctionArguments selfMock2 -o3 allo1 allo2 allo3 allo4 + + test::markdown "ok single letter options, consume argument as option values" + test::func command::parseFunctionArguments selfMock2 -o243 allo1 allo2 allo3 allo4 + + test::markdown "ko, single letter options, invalid one" + test::func command::parseFunctionArguments selfMock2 -3ao allo1 allo2 + + test::markdown "ko, missing a value for the option 4" + test::func command::parseFunctionArguments selfMock2 arg1 arg2 -4 + + test::markdown "ko, missing multiple values in a group" + test::func command::parseFunctionArguments selfMock2 arg1 arg2 -4444 +} + +function test::transformReturnedVarsBeforePrinting() { + unset -v RETURNED_VALUE2 RETURNED_ARRAY RETURNED_ARRAY2 + unset -v RETURNED_VALUE2 RETURNED_ARRAY RETURNED_ARRAY2 +} + +main diff --git a/tests.d/lib-command/01.command.sh b/tests.d/lib-command/01.command.sh new file mode 100644 index 0000000..7836040 --- /dev/null +++ b/tests.d/lib-command/01.command.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +function main() { + test_main::getFunctionNameFromCommand + test_main::fuzzyMatchCommandToFunctionNameOrFail + test_main::getMaxPossibleCommandLevel + test_main::fuzzyFindOption + test_main::getSingleLetterOptions + test_main::getDisplayableFilteredArray +} + +function test_main::getFunctionNameFromCommand() { + test::title "✅ Testing main::getFunctionNameFromCommand" + + test::func main::getFunctionNameFromCommand "self build" +} + +function test_main::fuzzyMatchCommandToFunctionNameOrFail() { + test::title "✅ Testing main::fuzzyMatchCommandToFunctionNameOrFail" + + test::markdown "Fuzzy match with single result:" + test::func main::fuzzyMatchCommandToFunctionNameOrFail "se bu other stuff thing derp" + + test::markdown "Fuzzy match by strict mode is enabled so it fails:" + test::exit VALET_CONFIG_STRICT_MATCHING=true main::fuzzyMatchCommandToFunctionNameOrFail "se bu other stuff stuff thing derp" + + test::markdown "Fuzzy match with ambiguous result:" + test::exit main::fuzzyMatchCommandToFunctionNameOrFail "sf" "nop" "other" "stuff" "stuff thing derp" +} + +function test_main::getMaxPossibleCommandLevel() { + test::title "✅ Testing main::getMaxPossibleCommandLevel" + + test::func main::getMaxPossibleCommandLevel "1" "2" "3" + test::func main::getMaxPossibleCommandLevel "1 2 3" + test::func main::getMaxPossibleCommandLevel "1" + test::func main::getMaxPossibleCommandLevel +} + +function test_main::fuzzyFindOption() { + test::title "✅ Testing main::fuzzyFindOption" + + test::markdown "single match, strict mode is enabled" + test::func VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption de --opt1 --derp2 --allo3 + + test::markdown "single match, strict mode is disabled" + test::func main::fuzzyFindOption de --opt1 --derp2 --allo3 + + test::markdown "multiple matches, strict mode is enabled" + test::func VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption -p --opt1 --derp2 --allo3 + + test::markdown "multiple matches, strict mode is disabled" + test::func main::fuzzyFindOption -p --opt1 --derp2 --allo3 + + test::markdown "no match" + test::func main::fuzzyFindOption thing --opt1 --derp2 --allo3 +} + +function test_main::getSingleLetterOptions() { + test::title "✅ Testing main::getSingleLetterOptions" + + test::func main::getSingleLetterOptions -a --opt1 --derp2 -b --allo3 -c +} + +function test_main::getDisplayableFilteredArray() { + test::title "✅ Testing main::getDisplayableFilteredArray" + + # shellcheck disable=SC2034 + ARRAY=(banana apple orange grape ananas lemon) + test::printVars ARRAY + test::func main::getDisplayableFilteredArray ae ARRAY +} + +# shellcheck disable=SC2317 +function test::transformReturnedVarsBeforePrinting() { + unset -v RETURNED_ARRAY RETURNED_ARRAY2 + unset -v RETURNED_ARRAY RETURNED_ARRAY2 +} + +main diff --git a/tests.d/lib-command/results.approved.md b/tests.d/lib-command/results.approved.md new file mode 100644 index 0000000..9d745e8 --- /dev/null +++ b/tests.d/lib-command/results.approved.md @@ -0,0 +1,587 @@ +# Test suite lib-command + +## Test script 00.parser + +### ✅ Testing command::parseFunctionArguments + +Missing argument: + +❯ `command::parseFunctionArguments selfMock2` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="Expecting ⌜2⌝ argument(s) but got ⌜0⌝. +Use ⌜valet self mock2 --help⌝ to get help. + +Usage: +valet [global options] self mock2 [options] [--] " +more=( +)' +``` + +ok + +❯ `command::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 more1 more2` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="" +option1="true" +thisIsOption2="optionValue2" +firstArg="arg1" +more=( +"more1" +"more2" +)' +``` + +missing argument + +❯ `command::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="Expecting ⌜2⌝ argument(s) but got ⌜1⌝. +Use ⌜valet self mock2 --help⌝ to get help. + +Usage: +valet [global options] self mock2 [options] [--] " +option1="true" +thisIsOption2="optionValue2" +firstArg="arg1" +more=( +)' +``` + +unknown options + +❯ `command::parseFunctionArguments selfMock2 --unknown --what optionValue2 arg` + +**Error output**: + +```text +INFO Fuzzy matching the option ⌜--what⌝ to ⌜--with-default⌝. +``` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +flag3="${VALET_FLAG3:-}" +help="" +parsingErrors="Unknown option ⌜--unknown⌝, valid options are: +-o --option1 +-2 --this-is-option2 +-3 --flag3 +-4 --with-default +-h --help +Expecting ⌜2⌝ argument(s) but got ⌜1⌝. +Use ⌜valet self mock2 --help⌝ to get help. + +Usage: +valet [global options] self mock2 [options] [--] " +withDefault="optionValue2" +firstArg="arg" +more=( +)' +``` + +ok with the option at the end + +❯ `command::parseFunctionArguments selfMock2 arg more1 more2 -o` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="" +firstArg="arg" +option1="true" +more=( +"more1" +"more2" +)' +``` + +fuzzy match the option --this + +❯ `command::parseFunctionArguments selfMock2 --this arg more1` + +**Error output**: + +```text +INFO Fuzzy matching the option ⌜--this⌝ to ⌜--this-is-option2⌝. +``` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="Expecting ⌜2⌝ argument(s) but got ⌜1⌝. +Use ⌜valet self mock2 --help⌝ to get help. + +Usage: +valet [global options] self mock2 [options] [--] " +thisIsOption2="arg" +firstArg="more1" +more=( +)' +``` + +ok, --option1 is interpreted as the value for --this-is-option2 + +❯ `command::parseFunctionArguments selfMock2 --this-is-option2 --option1 arg more1` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="" +thisIsOption2="--option1" +firstArg="arg" +more=( +"more1" +)' +``` + +ok only args + +❯ `command::parseFunctionArguments selfMock4 arg1 arg2` + +Returned variables: + +```text +RETURNED_VALUE='' +``` + +ok with -- to separate options from args + +❯ `command::parseFunctionArguments selfMock2 -- --arg1-- --arg2--` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="" +firstArg="--arg1--" +more=( +"--arg2--" +)' +``` + +missing a value for the option 2 + +❯ `command::parseFunctionArguments selfMock2 arg1 arg2 --this-is-option2` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="Missing value for option ⌜thisIsOption2⌝. +Use ⌜valet self mock2 --help⌝ to get help." +firstArg="arg1" +more=( +"arg2" +)' +``` + +ambiguous fuzzy match + +❯ `command::parseFunctionArguments selfMock2 arg1 arg2 --th` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +flag3="${VALET_FLAG3:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="Found multiple matches for the option ⌜--th⌝, please be more specific: +CHI-CDECHI-CDECHItCDECHIhCDEis-is-option2 +CHI-CDECHI-CDEwiCHItCDECHIhCDE-default + +Use ⌜valet self mock2 --help⌝ to get help." +firstArg="arg1" +more=( +"arg2" +)' +``` + +ok single letter options grouped together + +❯ `command::parseFunctionArguments selfMock2 -o3 allo1 allo2 allo3 allo4` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="" +option1="true" +flag3="true" +firstArg="allo1" +more=( +"allo2" +"allo3" +"allo4" +)' +``` + +ok single letter options, consume argument as option values + +❯ `command::parseFunctionArguments selfMock2 -o243 allo1 allo2 allo3 allo4` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +help="" +parsingErrors="" +option1="true" +thisIsOption2="allo1" +withDefault="allo2" +flag3="true" +firstArg="allo3" +more=( +"allo4" +)' +``` + +ko, single letter options, invalid one + +❯ `command::parseFunctionArguments selfMock2 -3ao allo1 allo2` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +withDefault="${VALET_WITH_DEFAULT:-"cool"}" +help="" +parsingErrors="Unknown option letter ⌜a⌝ in group ⌜-3ao⌝. Valid single letter options are: ⌜o⌝, ⌜2⌝, ⌜3⌝, ⌜4⌝, ⌜h⌝. +Use ⌜valet self mock2 --help⌝ to get help." +flag3="true" +option1="true" +firstArg="allo1" +more=( +"allo2" +)' +``` + +ko, missing a value for the option 4 + +❯ `command::parseFunctionArguments selfMock2 arg1 arg2 -4` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +flag3="${VALET_FLAG3:-}" +help="" +parsingErrors="Missing value for option ⌜withDefault⌝. +Use ⌜valet self mock2 --help⌝ to get help." +firstArg="arg1" +more=( +"arg2" +)' +``` + +ko, missing multiple values in a group + +❯ `command::parseFunctionArguments selfMock2 arg1 arg2 -4444` + +Returned variables: + +```text +RETURNED_VALUE='local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +local -a more +option1="" +thisIsOption2="${VALET_THIS_IS_OPTION2:-}" +flag3="${VALET_FLAG3:-}" +help="" +parsingErrors="Missing value for option ⌜withDefault⌝. +Missing value for option ⌜withDefault⌝. +Missing value for option ⌜withDefault⌝. +Missing value for option ⌜withDefault⌝. +Use ⌜valet self mock2 --help⌝ to get help." +firstArg="arg1" +more=( +"arg2" +)' +``` + +## Test script 01.command + +### ✅ Testing main::getFunctionNameFromCommand + +❯ `main::getFunctionNameFromCommand self\ build` + +Returned variables: + +```text +RETURNED_VALUE='selfBuild' +``` + +### ✅ Testing main::fuzzyMatchCommandToFunctionNameOrFail + +Fuzzy match with single result: + +❯ `main::fuzzyMatchCommandToFunctionNameOrFail se\ bu\ other\ stuff\ thing\ derp` + +**Error output**: + +```text +INFO Fuzzy matching the command ⌜se bu⌝ to ⌜self build⌝. +``` + +Returned variables: + +```text +RETURNED_VALUE='selfBuild' +RETURNED_VALUE2='2' +RETURNED_VALUE3='self build' +``` + +Fuzzy match by strict mode is enabled so it fails: + +❯ `VALET_CONFIG_STRICT_MATCHING=true main::fuzzyMatchCommandToFunctionNameOrFail se\ bu\ other\ stuff\ stuff\ thing\ derp` + +Exited with code: `1` + +**Error output**: + +```text +ERROR Could not find an exact command for ⌜se⌝, use ⌜--help⌝ to get a list of valid commands. +``` + +Fuzzy match with ambiguous result: + +❯ `main::fuzzyMatchCommandToFunctionNameOrFail sf nop other stuff stuff\ thing\ derp` + +Exited with code: `1` + +**Error output**: + +```text +ERROR Found multiple matches for the command ⌜sf⌝, please be more specific: +CHIsCDEelCHIfCDE add-command +CHIsCDEelCHIfCDE add-library +CHIsCDEelCHIfCDE build +CHIsCDEelCHIfCDE config +CHIsCDEelCHIfCDE document +CHIsCDEelCHIfCDE export +CHIsCDEelCHIfCDE extend +CHIsCDEelCHIfCDE mock1 +CHIsCDEelCHIfCDE mock2 +CHIsCDEelCHIfCDE mock3 +CHIsCDEelCHIfCDE release +CHIsCDEelCHIfCDE setup +CHIsCDEelCHIfCDE test +CHIsCDEelCHIfCDE uninstall +CHIsCDEelCHIfCDE update + +``` + +### ✅ Testing main::getMaxPossibleCommandLevel + +❯ `main::getMaxPossibleCommandLevel 1 2 3` + +Returned variables: + +```text +RETURNED_VALUE='2' +``` + +❯ `main::getMaxPossibleCommandLevel 1\ 2\ 3` + +Returned variables: + +```text +RETURNED_VALUE='2' +``` + +❯ `main::getMaxPossibleCommandLevel 1` + +Returned variables: + +```text +RETURNED_VALUE='1' +``` + +❯ `main::getMaxPossibleCommandLevel` + +Returned variables: + +```text +RETURNED_VALUE='0' +``` + +### ✅ Testing main::fuzzyFindOption + +single match, strict mode is enabled + +❯ `VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption de --opt1 --derp2 --allo3` + +Returned variables: + +```text +RETURNED_VALUE='Unknown option ⌜de⌝, did you mean ⌜--derp2⌝?' +RETURNED_VALUE2='' +``` + +single match, strict mode is disabled + +❯ `main::fuzzyFindOption de --opt1 --derp2 --allo3` + +**Error output**: + +```text +INFO Fuzzy matching the option ⌜de⌝ to ⌜--derp2⌝. +``` + +Returned variables: + +```text +RETURNED_VALUE='' +RETURNED_VALUE2='--derp2' +``` + +multiple matches, strict mode is enabled + +❯ `VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption -p --opt1 --derp2 --allo3` + +Returned variables: + +```text +RETURNED_VALUE='Unknown option ⌜-p⌝, valid matches are: +CHI-CDE-oCHIpCDEt1 +CHI-CDE-derCHIpCDE2 +' +RETURNED_VALUE2='' +``` + +multiple matches, strict mode is disabled + +❯ `main::fuzzyFindOption -p --opt1 --derp2 --allo3` + +Returned variables: + +```text +RETURNED_VALUE='Found multiple matches for the option ⌜-p⌝, please be more specific: +CHI-CDE-oCHIpCDEt1 +CHI-CDE-derCHIpCDE2 +' +RETURNED_VALUE2='' +``` + +no match + +❯ `main::fuzzyFindOption thing --opt1 --derp2 --allo3` + +Returned variables: + +```text +RETURNED_VALUE='Unknown option ⌜thing⌝, valid options are: +--opt1 +--derp2 +--allo3' +RETURNED_VALUE2='' +``` + +### ✅ Testing main::getSingleLetterOptions + +❯ `main::getSingleLetterOptions -a --opt1 --derp2 -b --allo3 -c` + +Returned variables: + +```text +RETURNED_VALUE='Valid single letter options are: ⌜a⌝, ⌜b⌝, ⌜c⌝.' +``` + +### ✅ Testing main::getDisplayableFilteredArray + +```text +ARRAY=( +[0]='banana' +[1]='apple' +[2]='orange' +[3]='grape' +[4]='ananas' +[5]='lemon' +) +``` + +❯ `main::getDisplayableFilteredArray ae ARRAY` + +Returned variables: + +```text +RETURNED_VALUE='bCHIaCDEnana +CHIaCDEpplCHIeCDE +orCHIaCDEngCHIeCDE +grCHIaCDEpCHIeCDE +CHIaCDEnanas +lemon +' +``` + diff --git a/tests.d/lib-log/00.log.sh b/tests.d/lib-log/00.log.sh new file mode 100644 index 0000000..b6c56ca --- /dev/null +++ b/tests.d/lib-log/00.log.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +function main() { + test::title "✅ Testing log::createPrintFunction" + + export VALET_CONFIG_ENABLE_COLORS=true + export VALET_CONFIG_ENABLE_NERDFONT_ICONS=true + export VALET_CONFIG_LOG_DISABLE_TIME=false + export VALET_CONFIG_LOG_DISABLE_WRAP=false + export VALET_CONFIG_LOG_ENABLE_TIMESTAMP=true + export VALET_CONFIG_LOG_COLUMNS=50 + + # fix the time to a known value + export TZ=Etc/GMT+0 + unset EPOCHSECONDS EPOCHREALTIME + export EPOCHSECONDS=548902800 + export EPOCHREALTIME=548902800.000000 + + test::printVars VALET_CONFIG_ENABLE_COLORS VALET_CONFIG_ENABLE_NERDFONT_ICONS VALET_CONFIG_LOG_DISABLE_TIME VALET_CONFIG_LOG_COLUMNS VALET_CONFIG_LOG_DISABLE_WRAP VALET_CONFIG_LOG_ENABLE_TIMESTAMP TZ EPOCHSECONDS EPOCHREALTIME + + test::exec log::createPrintFunction + test::prompt eval "\${GLOBAL_LOG_PRINT_FUNCTION}" + eval "${GLOBAL_LOG_PRINT_FUNCTION}" + + test::title "✅ Testing log::print" + test::exec log::print SUCCESS  OK '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' + + export VALET_CONFIG_ENABLE_COLORS=false + export VALET_CONFIG_ENABLE_NERDFONT_ICONS=false + export VALET_CONFIG_LOG_DISABLE_TIME=true + export VALET_CONFIG_LOG_COLUMNS=40 + + test::printVars VALET_CONFIG_ENABLE_COLORS VALET_CONFIG_ENABLE_NERDFONT_ICONS VALET_CONFIG_LOG_DISABLE_TIME VALET_CONFIG_LOG_COLUMNS + + test::exec log::createPrintFunction + test::prompt eval "\${GLOBAL_LOG_PRINT_FUNCTION}" + eval "${GLOBAL_LOG_PRINT_FUNCTION}" + + test::exec log::info 'Next up is a big line with a lot of numbers not separated by spaces. Which means they will be truncated by characters and not by word boundaries like this sentence.' '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' + + test::title "✅ Testing log::printFile" + test::exec log::printFile file-to-read 2 + test::exec log::printFile file-to-read + + # shellcheck disable=SC2034 + local text="What is Lorem Ipsum? + +Lorem Ipsum is simply dummy text of the printing and typesetting industry. +Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. +It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. +It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + +01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +Why do we use it? + +It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. +The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. +Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. +Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like)." + test::printVars text + + test::title "✅ Testing log::printFileString" + test::exec log::printFileString "\"\${text}\"" 2 + test::exec log::printFileString "\"\${text}\"" +} + +main diff --git a/tests.d/lib-log/00.tests.sh b/tests.d/lib-log/00.tests.sh deleted file mode 100644 index 03ad8b8..0000000 --- a/tests.d/lib-log/00.tests.sh +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env bash - -function test_log_level() { - export VALET_CONFIG_ENABLE_COLORS=false - export VALET_CONFIG_ENABLE_NERDFONT_ICONS=false - export VALET_CONFIG_LOG_DISABLE_TIME=true - export VALET_CONFIG_LOG_COLUMNS=30 - export VALET_CONFIG_LOG_DISABLE_WRAP=false - - log::createPrintFunction - eval "${GLOBAL_LOG_PRINT_FUNCTION}" - - echo - echo "→ log::setLevel trace" - log::setLevel trace - - test_log_log_one_of_each_level - - echo - echo "→ log::setLevel debug" - log::setLevel debug - - test_log_log_one_of_each_level - - echo - echo "→ log::setLevel info" - log::setLevel info - - test_log_log_one_of_each_level - - echo - echo "→ log::setLevel success" - log::setLevel success - - test_log_log_one_of_each_level - - echo - echo "→ log::setLevel warning" - log::setLevel warning - - test_log_log_one_of_each_level - - echo - echo "→ log::setLevel error" - log::setLevel error - - test_log_log_one_of_each_level -} - -function test_log_log_one_of_each_level() { - echo - echo "→ log::getLevel" - log::getLevel && echo "${RETURNED_VALUE}" - - echo - echo "→ log::isTraceEnabled" - log::isTraceEnabled && echo 0 || echo 1 - - echo - echo "→ log::isDebugEnabled" - log::isDebugEnabled && echo 0 || echo 1 - - # fix stuff for printCallStack - GLOBAL_STACK_FUNCTION_NAMES=(log::printCallStack log::error myCmd::subFunction myCmd::function) - GLOBAL_STACK_SOURCE_FILES=("" "core" "${PWD}/path/to/subFunction.sh" "${PWD}/path/to/function.sh") - GLOBAL_STACK_LINE_NUMBERS=(100 200 300) - - echo - echo "→ log::error 'This is an error message.'" - log::error 'This is an error message.' - - echo - echo "→ log::warning 'This is a warning message.'" - log::warning 'This is a warning message.' - - echo - echo "→ log::success 'This is an success message.'" - log::success 'This is an success message.' - - echo - echo "→ log::info 'This is an info message.'" - log::info 'This is an info message.' - - echo - echo "→ log::debug 'This is a debug message.'" - log::debug 'This is a debug message.' - - echo - echo "→ log::trace 'This is a trace message.'" - log::trace 'This is a trace message.' - - echo - echo "→ log::errorTrace 'This is a errorTrace message, always shown.'" - log::errorTrace 'This is a errorTrace message, always shown.' -} - -function test_log() { - export VALET_CONFIG_ENABLE_COLORS=true - export VALET_CONFIG_ENABLE_NERDFONT_ICONS=true - export VALET_CONFIG_LOG_DISABLE_TIME=false - export VALET_CONFIG_LOG_DISABLE_WRAP=false - export VALET_CONFIG_LOG_ENABLE_TIMESTAMP=true - export VALET_CONFIG_LOG_COLUMNS=50 - - # fix the time to a known value - export TZ=Etc/GMT+0 - unset EPOCHSECONDS EPOCHREALTIME - export EPOCHSECONDS=548902800 - export EPOCHREALTIME=548902800.000000 - - log::createPrintFunction - echo - - echo "→ log::createPrintFunction" - eval "${GLOBAL_LOG_PRINT_FUNCTION}" - - echo - echo "→ log::print SUCCESS  OK ..." - log::print SUCCESS  OK '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' - - export VALET_CONFIG_ENABLE_COLORS=false - export VALET_CONFIG_ENABLE_NERDFONT_ICONS=false - export VALET_CONFIG_LOG_DISABLE_TIME=true - export VALET_CONFIG_LOG_COLUMNS=40 - - log::createPrintFunction - eval "${GLOBAL_LOG_PRINT_FUNCTION}" - - echo - echo "→ log::info ..." - log::info 'Next up is a big line with a lot of numbers not separated by spaces. Which means they will be truncated by characters and not by word boundaries like this sentence.' '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' - - echo - echo "→ log::printFile file-to-read 2" - log::printFile file-to-read 2 - - echo - echo "→ log::printFile file-to-read" - log::printFile file-to-read - - local text="What is Lorem Ipsum? - -Lorem Ipsum is simply dummy text of the printing and typesetting industry. -Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. -It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. -It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - -01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 - -Why do we use it? - -It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. -The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. -Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. -Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like)." - - echo - echo "→ log::printFileString \"\${text}\" 2" - log::printFileString "${text}" 2 - - echo - echo "→ log::printFileString \"\${text}\"" - log::printFileString "${text}" -} - -function main() { - (test_log_level 1>&2) - test::endTest "Testing log level" 0 - (test_log 1>&2) - test::endTest "Testing log::xx functions" 0 -} - -main diff --git a/tests.d/lib-log/01.log-level.sh b/tests.d/lib-log/01.log-level.sh new file mode 100644 index 0000000..55d30ca --- /dev/null +++ b/tests.d/lib-log/01.log-level.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# shellcheck disable=SC2034 +function main() { + test::title "✅ Testing log levels" + + VALET_CONFIG_ENABLE_COLORS=false + VALET_CONFIG_ENABLE_NERDFONT_ICONS=false + VALET_CONFIG_LOG_DISABLE_TIME=true + VALET_CONFIG_LOG_COLUMNS=30 + VALET_CONFIG_LOG_DISABLE_WRAP=false + + # fix stuff for printCallStack + GLOBAL_STACK_FUNCTION_NAMES=(log::printCallStack log::error myCmd::subFunction myCmd::function) + GLOBAL_STACK_SOURCE_FILES=("" "core" "${PWD}/path/to/subFunction.sh" "${PWD}/path/to/function.sh") + GLOBAL_STACK_LINE_NUMBERS=(100 200 300) + + test::printVars VALET_CONFIG_ENABLE_COLORS VALET_CONFIG_ENABLE_NERDFONT_ICONS VALET_CONFIG_LOG_DISABLE_TIME VALET_CONFIG_LOG_COLUMNS VALET_CONFIG_LOG_DISABLE_WRAP GLOBAL_STACK_FUNCTION_NAMES GLOBAL_STACK_SOURCE_FILES GLOBAL_STACK_LINE_NUMBERS + + test::exec log::createPrintFunction + test::prompt eval "\${GLOBAL_LOG_PRINT_FUNCTION}" + eval "${GLOBAL_LOG_PRINT_FUNCTION}" + + test::exec log::setLevel trace + + test_log_log_one_of_each_level + + test::exec log::setLevel debug + + test_log_log_one_of_each_level + + test::exec log::setLevel info + + test_log_log_one_of_each_level + + test::exec log::setLevel success + + test_log_log_one_of_each_level + + test::exec log::setLevel warning + + test_log_log_one_of_each_level + + test::exec log::setLevel error + + test_log_log_one_of_each_level +} + +function test_log_log_one_of_each_level() { + test::func log::getLevel + test::exec log::isTraceEnabled + test::exec log::isDebugEnabled + + test::exec log::error 'This is an error message.' + test::exec log::warning 'This is a warning message.' + test::exec log::success 'This is an success message.' + test::exec log::info 'This is an info message.' + test::exec log::debug 'This is a debug message.' + test::exec log::trace 'This is a trace message.' + test::exec log::errorTrace 'This is a errorTrace message, always shown.' +} + +main diff --git a/tests.d/lib-log/results.approved.md b/tests.d/lib-log/results.approved.md index 3b2ca59..c88df2b 100644 --- a/tests.d/lib-log/results.approved.md +++ b/tests.d/lib-log/results.approved.md @@ -1,269 +1,32 @@ # Test suite lib-log -## Test script 00.tests +## Test script 00.log -### Testing log level - - - -Exit code: `0` - -Error output +### ✅ Testing log::createPrintFunction ```text - -→ log::setLevel trace -DEBUG Log level set to - trace. -WARNING Beware that debug log - level might lead to - secret leak, use it - only if necessary. - -→ log::getLevel -trace - -→ log::isTraceEnabled -0 - -→ log::isDebugEnabled -0 - -→ log::error 'This is an error message.' -ERROR This is an error - message. - ├─ in myCmd::subFunct - │ ion() at tests.d/l - │ ib-log/path/to/sub - │ Function.sh:200 - └─ in myCmd::function - () at tests.d/lib- - log/path/to/functi - on.sh:300 - -→ log::warning 'This is a warning message.' -WARNING This is a warning - message. - -→ log::success 'This is an success message.' -SUCCESS This is an success - message. - -→ log::info 'This is an info message.' -INFO This is an info - message. - -→ log::debug 'This is a debug message.' -DEBUG This is a debug - message. - -→ log::trace 'This is a trace message.' -TRACE This is a trace - message. - -→ log::errorTrace 'This is a errorTrace message, always shown.' -TRACE This is a errorTrace - message, always - shown. - -→ log::setLevel debug -DEBUG Log level set to - debug. -WARNING Beware that debug log - level might lead to - secret leak, use it - only if necessary. - -→ log::getLevel -debug - -→ log::isTraceEnabled -1 - -→ log::isDebugEnabled -0 - -→ log::error 'This is an error message.' -ERROR This is an error - message. - ├─ in myCmd::subFunct - │ ion() at tests.d/l - │ ib-log/path/to/sub - │ Function.sh:200 - └─ in myCmd::function - () at tests.d/lib- - log/path/to/functi - on.sh:300 - -→ log::warning 'This is a warning message.' -WARNING This is a warning - message. - -→ log::success 'This is an success message.' -SUCCESS This is an success - message. - -→ log::info 'This is an info message.' -INFO This is an info - message. - -→ log::debug 'This is a debug message.' -DEBUG This is a debug - message. - -→ log::trace 'This is a trace message.' - -→ log::errorTrace 'This is a errorTrace message, always shown.' -TRACE This is a errorTrace - message, always - shown. - -→ log::setLevel info - -→ log::getLevel -info - -→ log::isTraceEnabled -1 - -→ log::isDebugEnabled -1 - -→ log::error 'This is an error message.' -ERROR This is an error - message. - -→ log::warning 'This is a warning message.' -WARNING This is a warning - message. - -→ log::success 'This is an success message.' -SUCCESS This is an success - message. - -→ log::info 'This is an info message.' -INFO This is an info - message. - -→ log::debug 'This is a debug message.' - -→ log::trace 'This is a trace message.' - -→ log::errorTrace 'This is a errorTrace message, always shown.' -TRACE This is a errorTrace - message, always - shown. - -→ log::setLevel success - -→ log::getLevel -success - -→ log::isTraceEnabled -1 - -→ log::isDebugEnabled -1 - -→ log::error 'This is an error message.' -ERROR This is an error - message. - -→ log::warning 'This is a warning message.' -WARNING This is a warning - message. - -→ log::success 'This is an success message.' -SUCCESS This is an success - message. - -→ log::info 'This is an info message.' - -→ log::debug 'This is a debug message.' - -→ log::trace 'This is a trace message.' - -→ log::errorTrace 'This is a errorTrace message, always shown.' -TRACE This is a errorTrace - message, always - shown. - -→ log::setLevel warning - -→ log::getLevel -warning - -→ log::isTraceEnabled -1 - -→ log::isDebugEnabled -1 - -→ log::error 'This is an error message.' -ERROR This is an error - message. - -→ log::warning 'This is a warning message.' -WARNING This is a warning - message. - -→ log::success 'This is an success message.' - -→ log::info 'This is an info message.' - -→ log::debug 'This is a debug message.' - -→ log::trace 'This is a trace message.' - -→ log::errorTrace 'This is a errorTrace message, always shown.' -TRACE This is a errorTrace - message, always - shown. - -→ log::setLevel error - -→ log::getLevel -error - -→ log::isTraceEnabled -1 - -→ log::isDebugEnabled -1 - -→ log::error 'This is an error message.' -ERROR This is an error - message. - -→ log::warning 'This is a warning message.' - -→ log::success 'This is an success message.' - -→ log::info 'This is an info message.' - -→ log::debug 'This is a debug message.' - -→ log::trace 'This is a trace message.' - -→ log::errorTrace 'This is a errorTrace message, always shown.' -TRACE This is a errorTrace - message, always - shown. +VALET_CONFIG_ENABLE_COLORS='true' +VALET_CONFIG_ENABLE_NERDFONT_ICONS='true' +VALET_CONFIG_LOG_DISABLE_TIME='false' +VALET_CONFIG_LOG_COLUMNS='50' +VALET_CONFIG_LOG_DISABLE_WRAP='false' +VALET_CONFIG_LOG_ENABLE_TIMESTAMP='true' +TZ='Etc/GMT+0' +EPOCHSECONDS='548902800' +EPOCHREALTIME='548902800.000000' ``` -### Testing log::xx functions +❯ `log::createPrintFunction` +❯ `eval ${GLOBAL_LOG_PRINT_FUNCTION}` +### ✅ Testing log::print -Exit code: `0` +❯ `log::print SUCCESS  OK 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567` -Error output +**Error output**: ```text - -→ log::createPrintFunction - -→ log::print SUCCESS  OK ... 1987-05-25_01:00:00 CSUOK  CDE 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 @@ -284,8 +47,24 @@ Error output 012345678901234567890123456789 012345678901234567890123456789 01234567 +``` + +```text +VALET_CONFIG_ENABLE_COLORS='false' +VALET_CONFIG_ENABLE_NERDFONT_ICONS='false' +VALET_CONFIG_LOG_DISABLE_TIME='true' +VALET_CONFIG_LOG_COLUMNS='40' +``` + +❯ `log::createPrintFunction` + +❯ `eval ${GLOBAL_LOG_PRINT_FUNCTION}` -→ log::info ... +❯ `log::info Next\ up\ is\ a\ big\ line\ with\ a\ lot\ of\ numbers\ not\ separated\ by\ spaces.\ Which\ means\ they\ will\ be\ truncated\ by\ characters\ and\ not\ by\ word\ boundaries\ like\ this\ sentence. 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567` + +**Error output**: + +```text INFO Next up is a big line with a lot of numbers not separated by spaces. Which means they will @@ -310,13 +89,25 @@ INFO Next up is a big line with a 6789012345678901234567890123456 7890123456789012345678901234567 890123456789012345678901234567 +``` -→ log::printFile file-to-read 2 +### ✅ Testing log::printFile + +❯ `log::printFile file-to-read 2` + +**Error output**: + +```text 1 ░ What is Lorem Ipsum? 2 ░ … ░ (truncated) +``` + +❯ `log::printFile file-to-read` -→ log::printFile file-to-read +**Error output**: + +```text 1 ░ What is Lorem Ipsum? 2 ░ 3 ░ Lorem Ipsum is simply du @@ -400,13 +191,43 @@ INFO Next up is a big line with a ░ etimes on purpose (injec ░ ted humour and the like) ░ . +``` + +```text +text='What is Lorem Ipsum? + +Lorem Ipsum is simply dummy text of the printing and typesetting industry. +Lorem Ipsum has been the industry'"'"'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. +It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. +It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + +01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +Why do we use it? + +It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. +The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using '"'"'Content here, content here'"'"', making it look like readable English. +Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for '"'"'lorem ipsum'"'"' will uncover many web sites still in their infancy. +Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).' +``` + +### ✅ Testing log::printFileString + +❯ `log::printFileString "${text}" 2` + +**Error output**: -→ log::printFileString "${text}" 2 +```text 1 ░ What is Lorem Ipsum? 2 ░ … ░ (truncated) +``` + +❯ `log::printFileString "${text}"` + +**Error output**: -→ log::printFileString "${text}" +```text 1 ░ What is Lorem Ipsum? 2 ░ 3 ░ Lorem Ipsum is simply du @@ -492,3 +313,455 @@ INFO Next up is a big line with a ░ . ``` +## Test script 01.log-level + +### ✅ Testing log levels + +```text +VALET_CONFIG_ENABLE_COLORS='false' +VALET_CONFIG_ENABLE_NERDFONT_ICONS='false' +VALET_CONFIG_LOG_DISABLE_TIME='true' +VALET_CONFIG_LOG_COLUMNS='30' +VALET_CONFIG_LOG_DISABLE_WRAP='false' +GLOBAL_STACK_FUNCTION_NAMES=( +[0]='log::printCallStack' +[1]='log::error' +[2]='myCmd::subFunction' +[3]='myCmd::function' +) +GLOBAL_STACK_SOURCE_FILES=( +[0]='' +[1]='core' +[2]='$GLOBAL_VALET_HOME/tests.d/lib-log/path/to/subFunction.sh' +[3]='$GLOBAL_VALET_HOME/tests.d/lib-log/path/to/function.sh' +) +GLOBAL_STACK_LINE_NUMBERS=( +[0]='100' +[1]='200' +[2]='300' +) +``` + +❯ `log::createPrintFunction` + +❯ `eval ${GLOBAL_LOG_PRINT_FUNCTION}` + +❯ `log::setLevel trace` + +**Error output**: + +```text +DEBUG Log level set to + trace. +WARNING Beware that debug log + level might lead to + secret leak, use it + only if necessary. +``` + +❯ `log::getLevel` + +Returned variables: + +```text +RETURNED_VALUE='trace' +``` + +❯ `log::isTraceEnabled` + +❯ `log::isDebugEnabled` + +❯ `log::error This\ is\ an\ error\ message.` + +**Error output**: + +```text +ERROR This is an error + message. + ├─ in myCmd::subFunct + │ ion() at tests.d/l + │ ib-log/path/to/sub + │ Function.sh:200 + └─ in myCmd::function + () at tests.d/lib- + log/path/to/functi + on.sh:300 +``` + +❯ `log::warning This\ is\ a\ warning\ message.` + +**Error output**: + +```text +WARNING This is a warning + message. +``` + +❯ `log::success This\ is\ an\ success\ message.` + +**Error output**: + +```text +SUCCESS This is an success + message. +``` + +❯ `log::info This\ is\ an\ info\ message.` + +**Error output**: + +```text +INFO This is an info + message. +``` + +❯ `log::debug This\ is\ a\ debug\ message.` + +**Error output**: + +```text +DEBUG This is a debug + message. +``` + +❯ `log::trace This\ is\ a\ trace\ message.` + +**Error output**: + +```text +TRACE This is a trace + message. +``` + +❯ `log::errorTrace This\ is\ a\ errorTrace\ message,\ always\ shown.` + +**Error output**: + +```text +TRACE This is a errorTrace + message, always + shown. +``` + +❯ `log::setLevel debug` + +**Error output**: + +```text +DEBUG Log level set to + debug. +WARNING Beware that debug log + level might lead to + secret leak, use it + only if necessary. +``` + +❯ `log::getLevel` + +Returned variables: + +```text +RETURNED_VALUE='debug' +``` + +❯ `log::isTraceEnabled` + +Returned code: `1` + +❯ `log::isDebugEnabled` + +❯ `log::error This\ is\ an\ error\ message.` + +**Error output**: + +```text +ERROR This is an error + message. + ├─ in myCmd::subFunct + │ ion() at tests.d/l + │ ib-log/path/to/sub + │ Function.sh:200 + └─ in myCmd::function + () at tests.d/lib- + log/path/to/functi + on.sh:300 +``` + +❯ `log::warning This\ is\ a\ warning\ message.` + +**Error output**: + +```text +WARNING This is a warning + message. +``` + +❯ `log::success This\ is\ an\ success\ message.` + +**Error output**: + +```text +SUCCESS This is an success + message. +``` + +❯ `log::info This\ is\ an\ info\ message.` + +**Error output**: + +```text +INFO This is an info + message. +``` + +❯ `log::debug This\ is\ a\ debug\ message.` + +**Error output**: + +```text +DEBUG This is a debug + message. +``` + +❯ `log::trace This\ is\ a\ trace\ message.` + +❯ `log::errorTrace This\ is\ a\ errorTrace\ message,\ always\ shown.` + +**Error output**: + +```text +TRACE This is a errorTrace + message, always + shown. +``` + +❯ `log::setLevel info` + +❯ `log::getLevel` + +Returned variables: + +```text +RETURNED_VALUE='info' +``` + +❯ `log::isTraceEnabled` + +Returned code: `1` + +❯ `log::isDebugEnabled` + +Returned code: `1` + +❯ `log::error This\ is\ an\ error\ message.` + +**Error output**: + +```text +ERROR This is an error + message. +``` + +❯ `log::warning This\ is\ a\ warning\ message.` + +**Error output**: + +```text +WARNING This is a warning + message. +``` + +❯ `log::success This\ is\ an\ success\ message.` + +**Error output**: + +```text +SUCCESS This is an success + message. +``` + +❯ `log::info This\ is\ an\ info\ message.` + +**Error output**: + +```text +INFO This is an info + message. +``` + +❯ `log::debug This\ is\ a\ debug\ message.` + +❯ `log::trace This\ is\ a\ trace\ message.` + +❯ `log::errorTrace This\ is\ a\ errorTrace\ message,\ always\ shown.` + +**Error output**: + +```text +TRACE This is a errorTrace + message, always + shown. +``` + +❯ `log::setLevel success` + +❯ `log::getLevel` + +Returned variables: + +```text +RETURNED_VALUE='success' +``` + +❯ `log::isTraceEnabled` + +Returned code: `1` + +❯ `log::isDebugEnabled` + +Returned code: `1` + +❯ `log::error This\ is\ an\ error\ message.` + +**Error output**: + +```text +ERROR This is an error + message. +``` + +❯ `log::warning This\ is\ a\ warning\ message.` + +**Error output**: + +```text +WARNING This is a warning + message. +``` + +❯ `log::success This\ is\ an\ success\ message.` + +**Error output**: + +```text +SUCCESS This is an success + message. +``` + +❯ `log::info This\ is\ an\ info\ message.` + +❯ `log::debug This\ is\ a\ debug\ message.` + +❯ `log::trace This\ is\ a\ trace\ message.` + +❯ `log::errorTrace This\ is\ a\ errorTrace\ message,\ always\ shown.` + +**Error output**: + +```text +TRACE This is a errorTrace + message, always + shown. +``` + +❯ `log::setLevel warning` + +❯ `log::getLevel` + +Returned variables: + +```text +RETURNED_VALUE='warning' +``` + +❯ `log::isTraceEnabled` + +Returned code: `1` + +❯ `log::isDebugEnabled` + +Returned code: `1` + +❯ `log::error This\ is\ an\ error\ message.` + +**Error output**: + +```text +ERROR This is an error + message. +``` + +❯ `log::warning This\ is\ a\ warning\ message.` + +**Error output**: + +```text +WARNING This is a warning + message. +``` + +❯ `log::success This\ is\ an\ success\ message.` + +❯ `log::info This\ is\ an\ info\ message.` + +❯ `log::debug This\ is\ a\ debug\ message.` + +❯ `log::trace This\ is\ a\ trace\ message.` + +❯ `log::errorTrace This\ is\ a\ errorTrace\ message,\ always\ shown.` + +**Error output**: + +```text +TRACE This is a errorTrace + message, always + shown. +``` + +❯ `log::setLevel error` + +❯ `log::getLevel` + +Returned variables: + +```text +RETURNED_VALUE='error' +``` + +❯ `log::isTraceEnabled` + +Returned code: `1` + +❯ `log::isDebugEnabled` + +Returned code: `1` + +❯ `log::error This\ is\ an\ error\ message.` + +**Error output**: + +```text +ERROR This is an error + message. +``` + +❯ `log::warning This\ is\ a\ warning\ message.` + +❯ `log::success This\ is\ an\ success\ message.` + +❯ `log::info This\ is\ an\ info\ message.` + +❯ `log::debug This\ is\ a\ debug\ message.` + +❯ `log::trace This\ is\ a\ trace\ message.` + +❯ `log::errorTrace This\ is\ a\ errorTrace\ message,\ always\ shown.` + +**Error output**: + +```text +TRACE This is a errorTrace + message, always + shown. +``` + diff --git a/tests.d/lib-main/01.sort-commands.sh b/tests.d/lib-main/01.sort-commands.sh index ae253ab..0dd79b6 100644 --- a/tests.d/lib-main/01.sort-commands.sh +++ b/tests.d/lib-main/01.sort-commands.sh @@ -1,73 +1,67 @@ #!/usr/bin/env bash +function main() { + test_main::sortCommands +} + +# shellcheck disable=SC2034 function test_main::sortCommands() { + test::title "✅ Testing main::sortCommands" + # overriding core::getLocalStateDirectory to return a temporary directory - io::createTempDirectory && local localStateDirectory="${RETURNED_VALUE}" - VALET_CONFIG_LOCAL_STATE_DIRECTORY="${localStateDirectory}" + io::createTempDirectory + VALET_CONFIG_LOCAL_STATE_DIRECTORY="${RETURNED_VALUE}" VALET_CONFIG_REMEMBER_LAST_CHOICES=5 + local -a commands=("cm1 This is command 1" "cm2 This is command 2" "sub cmd1 This is sub command 1" "sub cmd2 This is sub command 2" "another3 This is another command 3") + declare -a -g COMMANDS=("${commands[@]}") - declare -a -g _COMMANDS + test::printVars VALET_CONFIG_LOCAL_STATE_DIRECTORY VALET_CONFIG_REMEMBER_LAST_CHOICES COMMANDS local IFS=$'\n' - # testing commands sort and that without prior choices, the order of commands is kept - echo "→ main::sortCommands myid1 \"\${commands}\"" - _COMMANDS=("${commands[@]}") - main::sortCommands "myid1" _COMMANDS && echo "${_COMMANDS[*]}" - test::endTest "Testing main::sortCommands without prior choices, the order of commands is kept" $? + test::markdown "testing commands sort and that without prior choices, the order of commands is kept" + test::exec main::sortCommands "my-id1" COMMANDS + test::printVars COMMANDS - # testing commands sort after choosing another3 then cm2 - echo "→ main::addLastChoice myid1 another3" - echo "→ main::addLastChoice myid1 cm2" - echo "→ main::sortCommands myid1 \"\${commands}\"" - main::addLastChoice "myid1" "another3" - main::addLastChoice "myid1" "cm2" - _COMMANDS=("${commands[@]}") - main::sortCommands "myid1" _COMMANDS && echo "${_COMMANDS[*]}" - test::endTest "Testing main::sortCommands after choosing another3 then cm2" $? + test::markdown "testing commands sort after choosing another3 then cm2" + test::exec main::addLastChoice "my-id1" "another3" + test::exec main::addLastChoice "my-id1" "cm2" + COMMANDS=("${commands[@]}") + test::exec main::sortCommands "my-id1" COMMANDS + test::printVars COMMANDS + + test::markdown "testing with VALET_CONFIG_REMEMBER_LAST_CHOICES=0" + COMMANDS=("${commands[@]}") + test::exec VALET_CONFIG_REMEMBER_LAST_CHOICES=0 main::sortCommands "my-id1" COMMANDS + test::printVars COMMANDS - # testing with VALET_CONFIG_REMEMBER_LAST_CHOICES=0 - echo "→ VALET_CONFIG_REMEMBER_LAST_CHOICES=0 main::sortCommands myid1 \"\${commands}\"" - _COMMANDS=("${commands[@]}") - VALET_CONFIG_REMEMBER_LAST_CHOICES=0 main::sortCommands "myid1" _COMMANDS && echo "${_COMMANDS[*]}" - test::endTest "Testing main::sortCommands, with VALET_CONFIG_REMEMBER_LAST_CHOICES=0 the order does not change" $? VALET_CONFIG_REMEMBER_LAST_CHOICES=5 - # testing commands sort for another id, the order of commands should be the initial one - echo "→ main::sortCommands myid2 \"\${commands}\"" - _COMMANDS=("${commands[@]}") - main::sortCommands "myid2" _COMMANDS && echo "${_COMMANDS[*]}" - test::endTest "Testing main::sortCommands for another id, the order of commands should be the initial one" $? + test::markdown "testing commands sort for another id, the order of commands should be the initial one" + COMMANDS=("${commands[@]}") + test::exec main::sortCommands "my-id2" COMMANDS + test::printVars COMMANDS - # testing that after adding more than x commands, we only keep the last x - VALET_CONFIG_REMEMBER_LAST_CHOICES=5 + test::markdown "testing that after adding more than x commands, we only keep the last x" + VALET_CONFIG_REMEMBER_LAST_CHOICES=2 + test::printVars VALET_CONFIG_REMEMBER_LAST_CHOICES local -i i - for i in {1..10}; do - main::addLastChoice "myid1" "cm${i}" + for i in {1..4}; do + test::exec main::addLastChoice "my-id1" "cm${i}" done - io::readFile "${localStateDirectory}/last-choices-myid1" && local content="${RETURNED_VALUE}" - echo "Content of last-choices-myid1:" - echo "${content}" - test::endTest "Testing main::addLastChoice after adding more than ${VALET_CONFIG_REMEMBER_LAST_CHOICES} commands, we only keep the last ${VALET_CONFIG_REMEMBER_LAST_CHOICES}" 0 - - # testing commands that adding the same command multiple times only keeps the last one - main::addLastChoice "myid1" "another3" - main::addLastChoice "myid1" "another3" - main::addLastChoice "myid1" "another3" - io::readFile "${localStateDirectory}/last-choices-myid1" && content="${RETURNED_VALUE}" - echo "Content of last-choices-myid1:" - echo "${content}" - test::endTest "Testing main::addLastChoice after adding the same command multiple times only keeps the last one" 0 -} + test::exec io::cat "${VALET_CONFIG_LOCAL_STATE_DIRECTORY}/last-choices-my-id1" -function main() { - test_main::sortCommands + test::markdown "testing commands that adding the same command multiple times only keeps the last one" + test::exec main::addLastChoice "my-id1" "another3" + test::exec main::addLastChoice "my-id1" "another3" + test::exec main::addLastChoice "my-id1" "another3" + test::exec io::cat "${VALET_CONFIG_LOCAL_STATE_DIRECTORY}/last-choices-my-id1" } main diff --git a/tests.d/lib-main/02.arguments-parser.sh b/tests.d/lib-main/02.arguments-parser.sh deleted file mode 100644 index 23c8acf..0000000 --- a/tests.d/lib-main/02.arguments-parser.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash - -function test_main::parseFunctionArguments() { - - echo "# missing argument" - echo "→ main::parseFunctionArguments selfMock2" - main::parseFunctionArguments selfMock2 && echo "${RETURNED_VALUE}" - echo - - echo "# ok" - echo "→ main::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 more1 more2" - main::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 more1 more2 && echo "${RETURNED_VALUE}" - echo - - echo "# missing argument" - echo "→ main::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1" - main::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 && echo "${RETURNED_VALUE}" - echo - - echo "# unknown options" - echo "→ main::parseFunctionArguments selfMock2 --unknown --what optionValue2 arg" - main::parseFunctionArguments selfMock2 --unknown --what optionValue2 arg && echo "${RETURNED_VALUE}" - echo - - echo "# ok with the option at the end" - echo "→ main::parseFunctionArguments selfMock2 arg more1 more2 -o" - main::parseFunctionArguments selfMock2 arg more1 more2 -o && echo "${RETURNED_VALUE}" - echo - - echo "# fuzzy match the option --this" - echo "→ main::parseFunctionArguments selfMock2 --this arg more1" - main::parseFunctionArguments selfMock2 --this arg more1 && echo "${RETURNED_VALUE}" - echo - - echo "# ok, --option1 is interpreted as the value for --this-is-option2" - echo "→ main::parseFunctionArguments selfMock2 --this-is-option2 --option1 arg more1" - main::parseFunctionArguments selfMock2 --this-is-option2 --option1 arg more1 && echo "${RETURNED_VALUE}" - echo - - echo "# ok only args" - echo "→ main::parseFunctionArguments selfMock4 arg1 arg2" - main::parseFunctionArguments selfMock4 arg1 arg2 && echo "${RETURNED_VALUE}" - echo - - echo "# ok with -- to separate options from args" - echo "→ main::parseFunctionArguments selfMock2 -- --arg1-- --arg2--" - main::parseFunctionArguments selfMock2 -- --arg1-- --arg2-- && echo "${RETURNED_VALUE}" - echo - - echo "# missing a value for the option 2" - echo "→ main::parseFunctionArguments selfMock2 arg1 arg2 --this-is-option2" - main::parseFunctionArguments selfMock2 arg1 arg2 --this-is-option2 && echo "${RETURNED_VALUE}" - echo - - echo "# ambiguous fuzzy match" - echo "→ main::parseFunctionArguments selfMock2 arg1 arg2 --th" - main::parseFunctionArguments selfMock2 arg1 arg2 --th && echo "${RETURNED_VALUE}" - echo - - echo "# ok single letter options grouped together" - echo "→ main::parseFunctionArguments selfMock2 -o3 allo1 allo2 allo3 allo4" - main::parseFunctionArguments selfMock2 -o3 allo1 allo2 allo3 allo4 && echo "${RETURNED_VALUE}" - echo - - echo "# ok single letter options, consume argument as option values" - echo "→ main::parseFunctionArguments selfMock2 -o243 allo1 allo2 allo3 allo4" - main::parseFunctionArguments selfMock2 -o243 allo1 allo2 allo3 allo4 && echo "${RETURNED_VALUE}" - echo - - echo "# ko, single letter options, invalid one" - echo "→ main::parseFunctionArguments selfMock2 -3ao allo1 allo2" - main::parseFunctionArguments selfMock2 -3ao allo1 allo2 && echo "${RETURNED_VALUE}" - echo - - echo "# ko, missing a value for the option 4" - echo "→ main::parseFunctionArguments selfMock2 arg1 arg2 -4" - main::parseFunctionArguments selfMock2 arg1 arg2 -4 && echo "${RETURNED_VALUE}" - echo - - echo "# ko, missing multiple values in a group" - echo "→ main::parseFunctionArguments selfMock2 arg1 arg2 -4444" - main::parseFunctionArguments selfMock2 arg1 arg2 -4444 && echo "${RETURNED_VALUE}" - echo - - test::endTest "Testing main::parseFunctionArguments" 0 -} - -function main() { - test_main::parseFunctionArguments -} - -main diff --git a/tests.d/lib-main/99.tests.sh b/tests.d/lib-main/99.tests.sh deleted file mode 100644 index 37ef2f1..0000000 --- a/tests.d/lib-main/99.tests.sh +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env bash - -function test_main::getFunctionNameFromCommand() { - echo "→ main::getFunctionNameFromCommand 'self build'" - main::getFunctionNameFromCommand "self build" && echo "${RETURNED_VALUE}" - - test::endTest "Testing main::getFunctionNameFromCommand" $? -} - -function test_main::fuzzyMatchCommandToFunctionNameOrFail() { - - # fuzzy match with single result - echo "→ main::fuzzyMatchCommandToFunctionNameOrFail 'se bu other stuff dont care'" - main::fuzzyMatchCommandToFunctionNameOrFail "se bu other stuff dont care" - echo "${RETURNED_VALUE}" - echo "${RETURNED_VALUE2}" - echo "${RETURNED_VALUE3}" - - # fuzzy match by strict mode is enabled so it fails - echo - echo "→ VALET_CONFIG_STRICT_MATCHING=true main::fuzzyMatchCommandToFunctionNameOrFail 'se bu other stuff dont care'" - (VALET_CONFIG_STRICT_MATCHING=true main::fuzzyMatchCommandToFunctionNameOrFail "se bu other stuff dont care") || echo "Failed as expected because strict mode is activated" - - # fuzzy match with ambiguous result - echo - echo "→ main::fuzzyMatchCommandToFunctionNameOrFail 'sf' 'nop' 'other' 'stuff' 'dont care'" - (main::fuzzyMatchCommandToFunctionNameOrFail "sf" "nop" "other" "stuff" "dont care") || echo "Failed as expected on ambiguous result" - - test::endTest "Testing main::fuzzyMatchCommandToFunctionNameOrFail" 0 -} - -function test_main::getMaxPossibleCommandLevel() { - - echo "→ main::getMaxPossibleCommandLevel '1' '2' '3'" - main::getMaxPossibleCommandLevel "1" "2" "3" && echo "${RETURNED_VALUE}" - - echo - echo "→ main::getMaxPossibleCommandLevel '1 2 3'" - main::getMaxPossibleCommandLevel "1 2 3" && echo "${RETURNED_VALUE}" - - echo - echo "→ main::getMaxPossibleCommandLevel '1'" - main::getMaxPossibleCommandLevel "1" && echo "${RETURNED_VALUE}" - - echo - echo "→ main::getMaxPossibleCommandLevel" - main::getMaxPossibleCommandLevel && echo "${RETURNED_VALUE}" - - test::endTest "Testing main::getMaxPossibleCommandLevel" 0 -} - -function test_main::fuzzyFindOption() { - - # single match, strict mode is enabled - echo "→ VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption de --opt1 --derp2 --allo3" - - VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption de --opt1 --derp2 --allo3 && echo "${RETURNED_VALUE}" && echo "${RETURNED_VALUE2}" - unset VALET_CONFIG_STRICT_MATCHING - - # single match, strict mode is disabled - echo - echo "→ main::fuzzyFindOption de --opt1 --derp2 --allo3" - main::fuzzyFindOption de --opt1 --derp2 --allo3 && echo "${RETURNED_VALUE}" && echo "${RETURNED_VALUE2}" - - # multiple matches, strict mode is enabled - echo - echo "→ VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption -a --opt1 --derp2 --allo3" - VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption -p --opt1 --derp2 --allo3 && echo "${RETURNED_VALUE}" && echo "${RETURNED_VALUE2}" - - # multiple matches, strict mode is disabled - echo - echo "→ main::fuzzyFindOption -a --opt1 --derp2 --allo3" - main::fuzzyFindOption -p --opt1 --derp2 --allo3 && echo "${RETURNED_VALUE}" && echo "${RETURNED_VALUE2}" - - # no match - echo - echo "→ main::fuzzyFindOption thing --opt1 --derp2 --allo3" - main::fuzzyFindOption thing --opt1 --derp2 --allo3 && echo "${RETURNED_VALUE}" && echo "${RETURNED_VALUE2}" - - test::endTest "Testing main::fuzzyFindOption" 0 -} - -function test_main::getSingleLetterOptions() { - echo "→ main::getSingleLetterOptions -a --opt1 --derp2 -b --allo3 -c" - main::getSingleLetterOptions -a --opt1 --derp2 -b --allo3 -c && echo "${RETURNED_VALUE}" - - test::endTest "Testing main::getSingleLetterOptions" 0 -} - -function test_main::getDisplayableFilteredArray() { - ARRAY=(banana apple orange grape ananas lemon) - echo "→ main::getDisplayableFilteredArray ae ARRAY" - main::getDisplayableFilteredArray ae ARRAY && echo "${RETURNED_VALUE}" - - test::endTest "Testing main::getDisplayableFilteredArray" 0 -} - -function main() { - test_main::getFunctionNameFromCommand - test_main::fuzzyMatchCommandToFunctionNameOrFail - test_main::getMaxPossibleCommandLevel - test_main::fuzzyFindOption - test_main::getSingleLetterOptions - test_main::getDisplayableFilteredArray -} - -main diff --git a/tests.d/lib-main/results.approved.md b/tests.d/lib-main/results.approved.md index 1595aab..9d86174 100644 --- a/tests.d/lib-main/results.approved.md +++ b/tests.d/lib-main/results.approved.md @@ -2,546 +2,119 @@ ## Test script 01.sort-commands -### Testing main::sortCommands without prior choices, the order of commands is kept - - - -Exit code: `0` - -Standard output - -```text -→ main::sortCommands myid1 "${commands}" -cm1 This is command 1 -cm2 This is command 2 -sub cmd1 This is sub command 1 -sub cmd2 This is sub command 2 -another3 This is another command 3 -``` - -### Testing main::sortCommands after choosing another3 then cm2 - - - -Exit code: `0` - -Standard output - -```text -→ main::addLastChoice myid1 another3 -→ main::addLastChoice myid1 cm2 -→ main::sortCommands myid1 "${commands}" -cm2 This is command 2 -another3 This is another command 3 -cm1 This is command 1 -sub cmd1 This is sub command 1 -sub cmd2 This is sub command 2 -``` - -### Testing main::sortCommands, with VALET_CONFIG_REMEMBER_LAST_CHOICES=0 the order does not change - - - -Exit code: `0` - -Standard output - -```text -→ VALET_CONFIG_REMEMBER_LAST_CHOICES=0 main::sortCommands myid1 "${commands}" -cm1 This is command 1 -cm2 This is command 2 -sub cmd1 This is sub command 1 -sub cmd2 This is sub command 2 -another3 This is another command 3 -``` - -### Testing main::sortCommands for another id, the order of commands should be the initial one - - - -Exit code: `0` - -Standard output - -```text -→ main::sortCommands myid2 "${commands}" -cm1 This is command 1 -cm2 This is command 2 -sub cmd1 This is sub command 1 -sub cmd2 This is sub command 2 -another3 This is another command 3 -``` - -### Testing main::addLastChoice after adding more than 5 commands, we only keep the last 5 - - - -Exit code: `0` - -Standard output +### ✅ Testing main::sortCommands ```text -Content of last-choices-myid1: -cm10 -cm9 -cm8 -cm7 -cm6 - +VALET_CONFIG_LOCAL_STATE_DIRECTORY='/tmp/valet.d/d1-2' +VALET_CONFIG_REMEMBER_LAST_CHOICES='5' +COMMANDS=( +[0]='cm1 This is command 1' +[1]='cm2 This is command 2' +[2]='sub cmd1 This is sub command 1' +[3]='sub cmd2 This is sub command 2' +[4]='another3 This is another command 3' +) ``` -### Testing main::addLastChoice after adding the same command multiple times only keeps the last one - +testing commands sort and that without prior choices, the order of commands is kept - -Exit code: `0` - -Standard output +❯ `main::sortCommands my-id1 COMMANDS` ```text -Content of last-choices-myid1: -another3 -cm10 -cm9 -cm8 -cm7 - +COMMANDS=( +[0]='cm1 This is command 1' +[1]='cm2 This is command 2' +[2]='sub cmd1 This is sub command 1' +[3]='sub cmd2 This is sub command 2' +[4]='another3 This is another command 3' +) ``` -## Test script 02.arguments-parser - -### Testing main::parseFunctionArguments +testing commands sort after choosing another3 then cm2 +❯ `main::addLastChoice my-id1 another3` +❯ `main::addLastChoice my-id1 cm2` -Exit code: `0` - -Standard output +❯ `main::sortCommands my-id1 COMMANDS` ```text -# missing argument -→ main::parseFunctionArguments selfMock2 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="Expecting ⌜2⌝ argument(s) but got ⌜0⌝. -Use ⌜valet self mock2 --help⌝ to get help. - -Usage: -valet [global options] self mock2 [options] [--] " -more=( -) - -# ok -→ main::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 more1 more2 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="" -option1="true" -thisIsOption2="optionValue2" -firstArg="arg1" -more=( -"more1" -"more2" -) - -# missing argument -→ main::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="Expecting ⌜2⌝ argument(s) but got ⌜1⌝. -Use ⌜valet self mock2 --help⌝ to get help. - -Usage: -valet [global options] self mock2 [options] [--] " -option1="true" -thisIsOption2="optionValue2" -firstArg="arg1" -more=( -) - -# unknown options -→ main::parseFunctionArguments selfMock2 --unknown --what optionValue2 arg -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -flag3="${VALET_FLAG3:-}" -help="" -parsingErrors="Unknown option ⌜--unknown⌝, valid options are: --o --option1 --2 --this-is-option2 --3 --flag3 --4 --with-default --h --help -Expecting ⌜2⌝ argument(s) but got ⌜1⌝. -Use ⌜valet self mock2 --help⌝ to get help. - -Usage: -valet [global options] self mock2 [options] [--] " -withDefault="optionValue2" -firstArg="arg" -more=( -) - -# ok with the option at the end -→ main::parseFunctionArguments selfMock2 arg more1 more2 -o -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="" -firstArg="arg" -option1="true" -more=( -"more1" -"more2" -) - -# fuzzy match the option --this -→ main::parseFunctionArguments selfMock2 --this arg more1 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="Expecting ⌜2⌝ argument(s) but got ⌜1⌝. -Use ⌜valet self mock2 --help⌝ to get help. - -Usage: -valet [global options] self mock2 [options] [--] " -thisIsOption2="arg" -firstArg="more1" -more=( -) - -# ok, --option1 is interpreted as the value for --this-is-option2 -→ main::parseFunctionArguments selfMock2 --this-is-option2 --option1 arg more1 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="" -thisIsOption2="--option1" -firstArg="arg" -more=( -"more1" -) - -# ok only args -→ main::parseFunctionArguments selfMock4 arg1 arg2 - - -# ok with -- to separate options from args -→ main::parseFunctionArguments selfMock2 -- --arg1-- --arg2-- -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="" -firstArg="--arg1--" -more=( -"--arg2--" -) - -# missing a value for the option 2 -→ main::parseFunctionArguments selfMock2 arg1 arg2 --this-is-option2 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="Missing value for option ⌜thisIsOption2⌝. -Use ⌜valet self mock2 --help⌝ to get help." -firstArg="arg1" -more=( -"arg2" +COMMANDS=( +[0]='cm2 This is command 2' +[1]='another3 This is another command 3' +[2]='cm1 This is command 1' +[3]='sub cmd1 This is sub command 1' +[4]='sub cmd2 This is sub command 2' ) - -# ambiguous fuzzy match -→ main::parseFunctionArguments selfMock2 arg1 arg2 --th -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -flag3="${VALET_FLAG3:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="Found multiple matches for the option ⌜--th⌝, please be more specific: -CHI-CDECHI-CDECHItCDECHIhCDEis-is-option2 -CHI-CDECHI-CDEwiCHItCDECHIhCDE-default - -Use ⌜valet self mock2 --help⌝ to get help." -firstArg="arg1" -more=( -"arg2" -) - -# ok single letter options grouped together -→ main::parseFunctionArguments selfMock2 -o3 allo1 allo2 allo3 allo4 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="" -option1="true" -flag3="true" -firstArg="allo1" -more=( -"allo2" -"allo3" -"allo4" -) - -# ok single letter options, consume argument as option values -→ main::parseFunctionArguments selfMock2 -o243 allo1 allo2 allo3 allo4 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -help="" -parsingErrors="" -option1="true" -thisIsOption2="allo1" -withDefault="allo2" -flag3="true" -firstArg="allo3" -more=( -"allo4" -) - -# ko, single letter options, invalid one -→ main::parseFunctionArguments selfMock2 -3ao allo1 allo2 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -withDefault="${VALET_WITH_DEFAULT:-"cool"}" -help="" -parsingErrors="Unknown option letter ⌜a⌝ in group ⌜-3ao⌝. Valid single letter options are: ⌜o⌝, ⌜2⌝, ⌜3⌝, ⌜4⌝, ⌜h⌝. -Use ⌜valet self mock2 --help⌝ to get help." -flag3="true" -option1="true" -firstArg="allo1" -more=( -"allo2" -) - -# ko, missing a value for the option 4 -→ main::parseFunctionArguments selfMock2 arg1 arg2 -4 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -flag3="${VALET_FLAG3:-}" -help="" -parsingErrors="Missing value for option ⌜withDefault⌝. -Use ⌜valet self mock2 --help⌝ to get help." -firstArg="arg1" -more=( -"arg2" -) - -# ko, missing multiple values in a group -→ main::parseFunctionArguments selfMock2 arg1 arg2 -4444 -local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -local -a more -option1="" -thisIsOption2="${VALET_THIS_IS_OPTION2:-}" -flag3="${VALET_FLAG3:-}" -help="" -parsingErrors="Missing value for option ⌜withDefault⌝. -Missing value for option ⌜withDefault⌝. -Missing value for option ⌜withDefault⌝. -Missing value for option ⌜withDefault⌝. -Use ⌜valet self mock2 --help⌝ to get help." -firstArg="arg1" -more=( -"arg2" -) - ``` -Error output - -```text -INFO Fuzzy matching the option ⌜--what⌝ to ⌜--with-default⌝. -INFO Fuzzy matching the option ⌜--this⌝ to ⌜--this-is-option2⌝. -``` +testing with VALET_CONFIG_REMEMBER_LAST_CHOICES=0 -## Test script 99.tests - -### Testing main::getFunctionNameFromCommand - - - -Exit code: `0` - -Standard output +❯ `VALET_CONFIG_REMEMBER_LAST_CHOICES=0 main::sortCommands my-id1 COMMANDS` ```text -→ main::getFunctionNameFromCommand 'self build' -selfBuild +COMMANDS=( +[0]='cm1 This is command 1' +[1]='cm2 This is command 2' +[2]='sub cmd1 This is sub command 1' +[3]='sub cmd2 This is sub command 2' +[4]='another3 This is another command 3' +) ``` -### Testing main::fuzzyMatchCommandToFunctionNameOrFail - - +testing commands sort for another id, the order of commands should be the initial one -Exit code: `0` - -Standard output +❯ `main::sortCommands my-id2 COMMANDS` ```text -→ main::fuzzyMatchCommandToFunctionNameOrFail 'se bu other stuff dont care' -selfBuild -2 -self build - -→ VALET_CONFIG_STRICT_MATCHING=true main::fuzzyMatchCommandToFunctionNameOrFail 'se bu other stuff dont care' -Failed as expected because strict mode is activated - -→ main::fuzzyMatchCommandToFunctionNameOrFail 'sf' 'nop' 'other' 'stuff' 'dont care' -Failed as expected on ambiguous result +COMMANDS=( +[0]='cm1 This is command 1' +[1]='cm2 This is command 2' +[2]='sub cmd1 This is sub command 1' +[3]='sub cmd2 This is sub command 2' +[4]='another3 This is another command 3' +) ``` -Error output +testing that after adding more than x commands, we only keep the last x ```text -INFO Fuzzy matching the command ⌜se bu⌝ to ⌜self build⌝. -ERROR Could not find an exact command for ⌜se⌝, use ⌜--help⌝ to get a list of valid commands. -ERROR Found multiple matches for the command ⌜sf⌝, please be more specific: -CHIsCDEelCHIfCDE add-command -CHIsCDEelCHIfCDE add-library -CHIsCDEelCHIfCDE build -CHIsCDEelCHIfCDE config -CHIsCDEelCHIfCDE document -CHIsCDEelCHIfCDE export -CHIsCDEelCHIfCDE extend -CHIsCDEelCHIfCDE mock1 -CHIsCDEelCHIfCDE mock2 -CHIsCDEelCHIfCDE mock3 -CHIsCDEelCHIfCDE release -CHIsCDEelCHIfCDE setup -CHIsCDEelCHIfCDE test -CHIsCDEelCHIfCDE uninstall -CHIsCDEelCHIfCDE update - +VALET_CONFIG_REMEMBER_LAST_CHOICES='2' ``` -### Testing main::getMaxPossibleCommandLevel - +❯ `main::addLastChoice my-id1 cm1` +❯ `main::addLastChoice my-id1 cm2` -Exit code: `0` +❯ `main::addLastChoice my-id1 cm3` -Standard output +❯ `main::addLastChoice my-id1 cm4` -```text -→ main::getMaxPossibleCommandLevel '1' '2' '3' -2 +❯ `io::cat /tmp/valet.d/d1-2/last-choices-my-id1` -→ main::getMaxPossibleCommandLevel '1 2 3' -2 - -→ main::getMaxPossibleCommandLevel '1' -1 - -→ main::getMaxPossibleCommandLevel -0 -``` - -### Testing main::fuzzyFindOption - - - -Exit code: `0` - -Standard output +**Standard output**: ```text -→ VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption de --opt1 --derp2 --allo3 -Unknown option ⌜de⌝, did you mean ⌜--derp2⌝? - - -→ main::fuzzyFindOption de --opt1 --derp2 --allo3 - ---derp2 - -→ VALET_CONFIG_STRICT_MATCHING=true main::fuzzyFindOption -a --opt1 --derp2 --allo3 -Unknown option ⌜-p⌝, valid matches are: -CHI-CDE-oCHIpCDEt1 -CHI-CDE-derCHIpCDE2 - - - -→ main::fuzzyFindOption -a --opt1 --derp2 --allo3 -Found multiple matches for the option ⌜-p⌝, please be more specific: -CHI-CDE-oCHIpCDEt1 -CHI-CDE-derCHIpCDE2 - - - -→ main::fuzzyFindOption thing --opt1 --derp2 --allo3 -Unknown option ⌜thing⌝, valid options are: ---opt1 ---derp2 ---allo3 +cm4 +cm3 ``` -Error output - -```text -INFO Fuzzy matching the option ⌜de⌝ to ⌜--derp2⌝. -``` +testing commands that adding the same command multiple times only keeps the last one -### Testing main::getSingleLetterOptions +❯ `main::addLastChoice my-id1 another3` +❯ `main::addLastChoice my-id1 another3` +❯ `main::addLastChoice my-id1 another3` -Exit code: `0` +❯ `io::cat /tmp/valet.d/d1-2/last-choices-my-id1` -Standard output +**Standard output**: ```text -→ main::getSingleLetterOptions -a --opt1 --derp2 -b --allo3 -c -Valid single letter options are: ⌜a⌝, ⌜b⌝, ⌜c⌝. -``` - -### Testing main::getDisplayableFilteredArray - - - -Exit code: `0` - -Standard output - -```text -→ main::getDisplayableFilteredArray ae ARRAY -bCHIaCDEnana -CHIaCDEpplCHIeCDE -orCHIaCDEngCHIeCDE -grCHIaCDEpCHIeCDE -CHIaCDEnanas -lemon +another3 +cm4 ``` diff --git a/tests.d/lib-prompt/00.tests.sh b/tests.d/lib-prompt/00.tests.sh index f77f545..8260472 100644 --- a/tests.d/lib-prompt/00.tests.sh +++ b/tests.d/lib-prompt/00.tests.sh @@ -3,7 +3,14 @@ # shellcheck source=../../libraries.d/lib-prompt source prompt +function main() { + test_prompt_getDisplayedPromptString + test_prompt::getItemDisplayedString +} + function test_prompt_getDisplayedPromptString() { + test::title "✅ Testing prompt_getDisplayedPromptString" + test_prompt_internal 5 "" 0 "" 0 test_prompt_internal 5 "a" 1 "a" 1 test_prompt_internal 5 "ab" 2 "ab" 2 @@ -31,19 +38,15 @@ function test_prompt_getDisplayedPromptString() { test_prompt_internal 10 "This is a long string that will be displayed in the screen." 20 "…g string…" 8 test_prompt_internal 4 "bl" 0 "bl" 0 - - test::endTest "Testing prompt_getDisplayedPromptString" 0 } function test_prompt_internal() { _PROMPT_STRING_SCREEN_WIDTH="${1}" _PROMPT_STRING="${2}" _PROMPT_STRING_INDEX="${3}" - echo - declare -p _PROMPT_STRING _PROMPT_STRING_INDEX _PROMPT_STRING_SCREEN_WIDTH - echo "→ prompt_getDisplayedPromptString" - prompt_getDisplayedPromptString - echo " ░${RETURNED_VALUE}░ ${RETURNED_VALUE2}" + test::printVars _PROMPT_STRING _PROMPT_STRING_INDEX _PROMPT_STRING_SCREEN_WIDTH + test::exec prompt_getDisplayedPromptString + test::markdown "\`░${RETURNED_VALUE}░ ${RETURNED_VALUE2}\`" if [[ "░${RETURNED_VALUE}░ ${RETURNED_VALUE2}" != "░${4}░ ${5}" ]]; then echo "Expected: ░${4}░ ${5}" exit 1 @@ -51,6 +54,8 @@ function test_prompt_internal() { } function test_prompt::getItemDisplayedString() { + test::title "✅ Testing prompt::getItemDisplayedString" + local FG_CYAN=$'\033[36m' local FG_RESET=$'\033[0m' @@ -61,51 +66,36 @@ function test_prompt::getItemDisplayedString() { _PROMPT_ITEMS_BOX_ITEM_WIDTH=5 _PROMPT_ITEMS_BOX_FILTER_STRING="eLor" _PROMPT_ITEMS_BOX_ITEM_DISPLAYED="HellO wOrld" - declare -p _PROMPT_ITEMS_BOX_ITEM_DISPLAYED _PROMPT_ITEMS_BOX_ITEM_WIDTH _PROMPT_ITEMS_BOX_FILTER_STRING - echo "→ prompt::getItemDisplayedString" - prompt::getItemDisplayedString - echo "${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED}" - echo + test::printVars _PROMPT_COLOR_LETTER_HIGHLIGHT _PROMPT_COLOR_LETTER_HIGHLIGHT_RESET _PROMPT_ITEMS_BOX_ITEM_WIDTH _PROMPT_ITEMS_BOX_FILTER_STRING _PROMPT_ITEMS_BOX_ITEM_DISPLAYED + test::exec prompt::getItemDisplayedString + test::markdown "\`${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED}\`" + _PROMPT_ITEMS_BOX_ITEM_DISPLAYED="${FG_CYAN}HellO${FG_RESET} wOrld" _PROMPT_ITEMS_BOX_ITEM_WIDTH=10 - echo "_PROMPT_ITEMS_BOX_ITEM_DISPLAYED=${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED@Q}" - declare -p _PROMPT_ITEMS_BOX_ITEM_WIDTH _PROMPT_ITEMS_BOX_FILTER_STRING - echo "→ prompt::getItemDisplayedString" - prompt::getItemDisplayedString - echo "${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED}" - echo + test::printVars _PROMPT_ITEMS_BOX_ITEM_WIDTH _PROMPT_ITEMS_BOX_ITEM_DISPLAYED + test::exec prompt::getItemDisplayedString + test::markdown "\`${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED}\`" + _PROMPT_ITEMS_BOX_ITEM_DISPLAYED="${FG_CYAN}HellO${FG_RESET} wOrld" _PROMPT_ITEMS_BOX_ITEM_WIDTH=11 - echo "_PROMPT_ITEMS_BOX_ITEM_DISPLAYED=${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED@Q}" - declare -p _PROMPT_ITEMS_BOX_ITEM_WIDTH _PROMPT_ITEMS_BOX_FILTER_STRING - echo "→ prompt::getItemDisplayedString" - prompt::getItemDisplayedString - echo "${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED}" - - echo - # shellcheck disable=SC2089 + + test::printVars _PROMPT_ITEMS_BOX_ITEM_WIDTH _PROMPT_ITEMS_BOX_ITEM_DISPLAYED + test::exec prompt::getItemDisplayedString + test::markdown "\`${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED}\`" + _PROMPT_COLOR_LETTER_HIGHLIGHT=$'\033[4m' _PROMPT_COLOR_LETTER_HIGHLIGHT_RESET=$'\033[24m' _PROMPT_ITEMS_BOX_ITEM_DISPLAYED='disable the monitor mode to avoid the "Terminated" message with exit code once the spinner is stopped' _PROMPT_ITEMS_BOX_FILTER_STRING="abomamwesspp" _PROMPT_ITEMS_BOX_ITEM_WIDTH=71 - # shellcheck disable=SC2090 - echo "_PROMPT_ITEMS_BOX_ITEM_DISPLAYED=${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED@Q}" - declare -p _PROMPT_ITEMS_BOX_ITEM_WIDTH _PROMPT_ITEMS_BOX_FILTER_STRING - echo "→ prompt::getItemDisplayedString" - prompt::getItemDisplayedString - echo "${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED}" - shopt -u nocasematch - - test::endTest "Testing prompt::getItemDisplayedString" 0 -} + test::printVars _PROMPT_COLOR_LETTER_HIGHLIGHT _PROMPT_COLOR_LETTER_HIGHLIGHT_RESET _PROMPT_ITEMS_BOX_ITEM_WIDTH _PROMPT_ITEMS_BOX_FILTER_STRING _PROMPT_ITEMS_BOX_ITEM_DISPLAYED + test::exec prompt::getItemDisplayedString + test::markdown "\`${_PROMPT_ITEMS_BOX_ITEM_DISPLAYED}\`" -function main() { - test_prompt_getDisplayedPromptString - test_prompt::getItemDisplayedString + shopt -u nocasematch } main diff --git a/tests.d/lib-prompt/results.approved.md b/tests.d/lib-prompt/results.approved.md index 6d99e51..b8baa71 100644 --- a/tests.d/lib-prompt/results.approved.md +++ b/tests.d/lib-prompt/results.approved.md @@ -2,168 +2,249 @@ ## Test script 00.tests -### Testing prompt_getDisplayedPromptString - - - -Exit code: `0` - -Standard output - -```text - -declare -- _PROMPT_STRING="" -declare -- _PROMPT_STRING_INDEX="0" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░░ 0 - -declare -- _PROMPT_STRING="a" -declare -- _PROMPT_STRING_INDEX="1" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░a░ 1 - -declare -- _PROMPT_STRING="ab" -declare -- _PROMPT_STRING_INDEX="2" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░ab░ 2 - -declare -- _PROMPT_STRING="abc" -declare -- _PROMPT_STRING_INDEX="3" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░abc░ 3 - -declare -- _PROMPT_STRING="abcd" -declare -- _PROMPT_STRING_INDEX="4" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░abcd░ 4 - -declare -- _PROMPT_STRING="abcde" -declare -- _PROMPT_STRING_INDEX="0" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░abcde░ 0 - -declare -- _PROMPT_STRING="abcdef" -declare -- _PROMPT_STRING_INDEX="4" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░…cdef░ 3 - -declare -- _PROMPT_STRING="abcdef" -declare -- _PROMPT_STRING_INDEX="3" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░abcd…░ 3 - -declare -- _PROMPT_STRING="abcdef" -declare -- _PROMPT_STRING_INDEX="1" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░abcd…░ 1 - -declare -- _PROMPT_STRING="abcde" -declare -- _PROMPT_STRING_INDEX="5" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░…cde░ 4 - -declare -- _PROMPT_STRING="abcdef" -declare -- _PROMPT_STRING_INDEX="6" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░…def░ 4 - -declare -- _PROMPT_STRING="abcdef" -declare -- _PROMPT_STRING_INDEX="5" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░…cdef░ 4 - -declare -- _PROMPT_STRING="abcdef" -declare -- _PROMPT_STRING_INDEX="4" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░…cdef░ 3 - -declare -- _PROMPT_STRING="abcdef" -declare -- _PROMPT_STRING_INDEX="3" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░abcd…░ 3 - -declare -- _PROMPT_STRING="abcdefghij" -declare -- _PROMPT_STRING_INDEX="6" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░…efg…░ 3 - -declare -- _PROMPT_STRING="abcdefghij" -declare -- _PROMPT_STRING_INDEX="3" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░abcd…░ 3 - -declare -- _PROMPT_STRING="abcdefghij" -declare -- _PROMPT_STRING_INDEX="4" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░…cde…░ 3 - -declare -- _PROMPT_STRING="abcdefghij" -declare -- _PROMPT_STRING_INDEX="5" -declare -- _PROMPT_STRING_SCREEN_WIDTH="5" -→ prompt_getDisplayedPromptString - ░…def…░ 3 - -declare -- _PROMPT_STRING="This is a long string that will be displayed in the screen." -declare -- _PROMPT_STRING_INDEX="20" -declare -- _PROMPT_STRING_SCREEN_WIDTH="10" -→ prompt_getDisplayedPromptString - ░…g string…░ 8 - -declare -- _PROMPT_STRING="bl" -declare -- _PROMPT_STRING_INDEX="0" -declare -- _PROMPT_STRING_SCREEN_WIDTH="4" -→ prompt_getDisplayedPromptString - ░bl░ 0 -``` - -### Testing prompt::getItemDisplayedString - - - -Exit code: `0` - -Standard output - -```text -declare -- _PROMPT_ITEMS_BOX_ITEM_DISPLAYED="HellO wOrld" -declare -- _PROMPT_ITEMS_BOX_ITEM_WIDTH="5" -declare -- _PROMPT_ITEMS_BOX_FILTER_STRING="eLor" -→ prompt::getItemDisplayedString -H>e<>le<>lO< wO>r<… - -_PROMPT_ITEMS_BOX_ITEM_DISPLAYED=$'\E[36mHellO\E[0m wOrld' -declare -- _PROMPT_ITEMS_BOX_ITEM_WIDTH="11" -declare -- _PROMPT_ITEMS_BOX_FILTER_STRING="eLor" -→ prompt::getItemDisplayedString -H>e<>lO< wO>re<>le<>lO< wO>r<…` + +```text +_PROMPT_ITEMS_BOX_ITEM_WIDTH='11' +_PROMPT_ITEMS_BOX_ITEM_DISPLAYED='HellO wOrld' ``` +❯ `prompt::getItemDisplayedString` + +`H>e<>lO< wO>r' '<'" - string::highlight 'This is a texT to highlight.' 'TTTTT' '>' '<' && echo "${RETURNED_VALUE}" + test::markdown "Wrapping characters" + test::func string::wrapCharacters 'A message.'$'\n''A new line' 13 '░░░' 10 - echo - echo "→ string::highlight '' 'ttttt'" - string::highlight '' 'ttttt' && echo "${RETURNED_VALUE}" + test::markdown "Wrapping characters, spaces at the beginning of the line are kept" + test::func string::wrapCharacters ' Start With spaces that must be kept! Other spaces can be ignored at wrapping.'$'\n'' Also start with spaces' 17 ' ' 14 +} - echo - echo "→ string::highlight 'This is a text to highlight.' ''" - string::highlight 'This is a text to highlight.' '' && echo "${RETURNED_VALUE}" +function test_string::highlight() { + test::title "✅ Testing string::highlight" - test::endTest "Testing string::highlight" 0 + test::func string::highlight 'This is a Text to highlight.' 'ttttt' + test::func string::highlight 'This is a texT to highlight.' 'TTTTT' "'>'" "'<'" + test::func string::highlight "''" 'ttttt' + test::func string::highlight 'This is a text to highlight.' "''" } function test_string::head() { - _TEST_MULTILINE_STRING="The first line. -The second line. -The third line. -The fourth line. -The fifth line." - test::title "✅ Testing string::head" - test::markdown "**Global variables:**" - test::printVars _TEST_MULTILINE_STRING + test::printVars MULTI_LINES_TEXT2 - test::markdown "Testing string::head with 3 lines" - test::func string::head "${_TEST_MULTILINE_STRING}" 3 + test::markdown "Testing string::head with 2 lines" + test::func string::head "\"\${MULTI_LINES_TEXT2}\"" 2 test::markdown "Testing string::head with 0 line" - test::func string::head "${_TEST_MULTILINE_STRING}" 0 + test::func string::head "\"\${MULTI_LINES_TEXT2}\"" 0 test::markdown "Testing string::head with 10 lines" - test::func string::head "${_TEST_MULTILINE_STRING}" 10 + test::func string::head "\"\${MULTI_LINES_TEXT2}\"" 10 } -function main() { - test_string::cutField - test_string::compareSemanticVersion - test_string::bumpSemanticVersion - test_string::kebabCaseToSnakeCase - test_string::kebabCaseToSnakeCase - test_string::kebabCaseToCamelCase - test_string::trimAll - test_string::trim - test_string::indexOf - test_string::extractBetween - test_string::count - test_string::split - test_string::regexGetFirst - test_string::microsecondsToHuman - test_string::wrapText - test_string::wrapCharacters - test_string::highlight - test_string::head -} +# shellcheck disable=SC2034 +# shellcheck disable=SC2016 +MULTI_LINES_TEXT='You don`t get better on the days when you feel like going. You get better on the days when you don`t want to go, but you go anyway. If you can overcome the negative energy coming from your tired body or unmotivated mind, you will grow and become better. It won`t be the best workout you have, you won`t accomplish as much as what you usually do when you actually feel good, but that doesn`t matter. Growth is a long term game, and the crappy days are more important. + +As long as I focus on what I feel and don`t worry about where I`m going, it works out. Having no expectations but being open to everything is what makes wonderful things happen. If I don`t worry, there`s no obstruction and life flows easily. It sounds impractical, but `Expect nothing; be open to everything` is really all it is. 01234567890123456789 on new line 01234567890123456789234 line new line. +https://en.wikipedia.org/wiki/Veganism + +There were 2 new lines before this.' + +# shellcheck disable=SC2034 +MULTI_LINES_TEXT2="1 line one +2 line two +3 line three +4 line four" main \ No newline at end of file diff --git a/tests.d/lib-string/results.approved.md b/tests.d/lib-string/results.approved.md index fe90f55..06bfe09 100644 --- a/tests.d/lib-string/results.approved.md +++ b/tests.d/lib-string/results.approved.md @@ -2,325 +2,321 @@ ## Test script 00.tests -### Testing string::cutField +### ✅ Testing string::cutField +❯ `string::cutField field1\ field2\ field3 0 \ ` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::cutField 'field1 field2 field3' 0 ' ' -field1 - -→ string::cutField 'field1 field2 field3' 1 ' ' -field2 - -→ string::cutField 'field1,field2,field3' 2 ',' -field3 +RETURNED_VALUE='field1' +``` -→ string::cutField 'field1,field2,field3' 4 ',' +❯ `string::cutField field1\ field2\ field3 1 \ ` +Returned variables: -→ string::cutField 'line1 hm I wonder -line2 does it work on lines? -line3 seems so' 2 $'\n' -line3 seems so +```text +RETURNED_VALUE='field2' ``` -### Testing string::compareSemanticVersion function +❯ `string::cutField field1,field2,field3 2 ,` +Returned variables: +```text +RETURNED_VALUE='field3' +``` -Exit code: `0` +❯ `string::cutField field1,field2,field3 4 ,` -Standard output +Returned variables: ```text -→ string::compareSemanticVersion '1.2.3' '1.2.3' -0 - -→ string::compareSemanticVersion '1.2.3-alpha' '1.2.4+az123' --1 +RETURNED_VALUE='' +``` -→ string::compareSemanticVersion '1.2.3' '1.2.2' -1 +❯ `string::cutField line1\ hm\ I\ wonder$'\n'line2\ does\ it\ work\ on\ lines?$'\n'line3\ seems\ so 2 $'\n'` -→ string::compareSemanticVersion '2.2.3' '1.2.3-alpha' -1 +Returned variables: -→ string::compareSemanticVersion '1.2.3+a1212' '1.3.3' --1 +```text +RETURNED_VALUE='line3 seems so' +``` -→ string::compareSemanticVersion '1.2.3-alpha+a123123' '1.2.3-alpha+123zer' -0 +### ✅ Testing string::kebabCaseToSnakeCase -→ string::compareSemanticVersion '1.2a.3' '1.2.3derp' -Failed as expected -``` +❯ `string::kebabCaseToSnakeCase this-is-a-test0` -Error output +Returned variables: ```text -ERROR Failed to compare versions ⌜1.2a.3⌝ and ⌜1.2.3derp⌝ because they are not valid semantic versions. +RETURNED_VALUE='THIS_IS_A_TEST0' ``` -### Testing string::bumpSemanticVersion +❯ `string::kebabCaseToSnakeCase --another-test` +Returned variables: +```text +RETURNED_VALUE='ANOTHER_TEST' +``` -Exit code: `0` +### ✅ Testing string::kebabCaseToSnakeCase -Standard output +❯ `string::kebabCaseToSnakeCase this-is-a-test0` -```text -→ bumping 0.0.0 minor -0.1.0 +Returned variables: -→ bumping 1.2.3-alpha+zae345 major -2.0.0 +```text +RETURNED_VALUE='THIS_IS_A_TEST0' +``` -→ bumping 1.2.3-alpha+zae345 minor -1.3.0 +❯ `string::kebabCaseToSnakeCase --another-test` -→ bumping 1.2.3-alpha+zae345 patch -1.2.4 +Returned variables: -→ bumping 1.2.3-alpha+zae345 major false -2.0.0-alpha+zae345 +```text +RETURNED_VALUE='ANOTHER_TEST' +``` -→ bumping 1.2.3-alpha patch false -1.2.157-alpha +### ✅ Testing string::kebabCaseToCamelCase -→ bumping aze patch false -Failed as expected -``` +❯ `string::kebabCaseToCamelCase this-is-a-test0` -Error output +Returned variables: ```text -ERROR Failed to bump the version ⌜aze⌝ because it is not valid semantic version. +RETURNED_VALUE='thisIsATest0' ``` -### Testing string::kebabCaseToSnakeCase +❯ `string::kebabCaseToCamelCase --another-test` +Returned variables: +```text +RETURNED_VALUE='anotherTest' +``` -Exit code: `0` +❯ `string::kebabCaseToCamelCase --last--` -Standard output +Returned variables: ```text -→ string::kebabCaseToSnakeCase this-is-a-test0 -THIS_IS_A_TEST0 - -→ string::kebabCaseToSnakeCase --another-test -ANOTHER_TEST +RETURNED_VALUE='last' ``` -### Testing string::kebabCaseToSnakeCase - - +### ✅ Testing string::trimAll -Exit code: `0` +❯ `string::trimAll \ \ a\ \ super\ test\ \ ` -Standard output +Returned variables: ```text -→ string::kebabCaseToSnakeCase this-is-a-test0 -THIS_IS_A_TEST0 - -→ string::kebabCaseToSnakeCase --another-test -ANOTHER_TEST +RETURNED_VALUE='a super test' ``` -### Testing string::kebabCaseToCamelCase +❯ `string::trimAll this\ is\ a\ command\ \ ` +Returned variables: +```text +RETURNED_VALUE='this is a command' +``` -Exit code: `0` +❯ `string::trimAll \ $'\n'this\ is\ a\ \ command\ \ ` -Standard output +Returned variables: ```text -→ string::kebabCaseToCamelCase this-is-a-test0 -thisIsATest0 - -→ string::kebabCaseToCamelCase --another-test -anotherTest - -→ string::kebabCaseToSnakeCase --last-- -last +RETURNED_VALUE='this is a command' ``` -### Testing string::trimAll - +### ✅ Testing string::trim +❯ `string::trim \ \ hello\ \ world\ \ ` -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::trimAll ' a super test ' -⌜a super test⌝ +RETURNED_VALUE='hello world' +``` -→ string::trimAll 'this is a command ' -⌜this is a command⌝ +❯ `string::trim hello\ \ \ ` -→ string::trimAll '\t\nthis is a \tcommand ' -⌜this is a command⌝ +Returned variables: + +```text +RETURNED_VALUE='hello' ``` -### Testing string::trim function +❯ `string::trim \ \ hello` +Returned variables: +```text +RETURNED_VALUE='hello' +``` -Exit code: `0` +❯ `string::trim $'\n'\ \ \ hello$'\n'\ \ ` -Standard output +Returned variables: ```text -→ string::trim ' hello world ' -⌜hello world⌝ +RETURNED_VALUE='hello' +``` + +### ✅ Testing string::indexOf function -→ string::trim 'hello ' -⌜hello⌝ +❯ `string::indexOf hello l` -→ string::trim ' hello' -⌜hello⌝ +Returned variables: -→ string::trim $'\n'$'\t'' hello'$'\n'$'\t'' ' -⌜hello⌝ +```text +RETURNED_VALUE='2' ``` -### Testing string::indexOf function +❯ `string::indexOf hello he` +Returned variables: +```text +RETURNED_VALUE='0' +``` -Exit code: `0` +❯ `string::indexOf hello he 10` -Standard output +Returned variables: ```text -→ string::indexOf 'hello' 'l' -2 +RETURNED_VALUE='-1' +``` -→ string::indexOf 'hello' 'he' -0 +❯ `string::indexOf yes-yes ye 1` -→ string::indexOf 'hello' 'he' 10 --1 +Returned variables: -→ string::indexOf 'yesyes' 'ye' 1 -3 +```text +RETURNED_VALUE='4' +``` -→ string::indexOf 'yesyes' 'yes' 3 -3 +❯ `string::indexOf yes-yes yes 5` -→ string::indexOf 'yesyes' 'yes' 5 --1 +Returned variables: +```text +RETURNED_VALUE='-1' ``` -### Testing string::extractBetween function +### ✅ Testing string::extractBetween function +❯ `string::extractBetween hello e o` +Returned variables: + +```text +RETURNED_VALUE='ll' +``` -Exit code: `0` +❯ `string::extractBetween hello e ''` -Standard output +Returned variables: ```text -→ string::extractBetween 'hello' 'e' 'o' -⌜ll⌝ - -→ string::extractBetween 'hello' '' 'l' -⌜he⌝ +RETURNED_VALUE='llo' +``` -→ string::extractBetween 'hello' 'e' '' -⌜llo⌝ +❯ `string::extractBetween hello h a` -→ string::extractBetween 'hello' 'a' '' -⌜⌝ +Returned variables: -→ string::extractBetween 'hello' 'h' 'a' -⌜⌝ +```text +RETURNED_VALUE='' +``` -multilinetext="1 line one +```text +MULTI_LINES_TEXT2='1 line one 2 line two 3 line three -4 line four" - -→ string::extractBetween "${multilinetext}" "one"$'\n' '4' -⌜2 line two -3 line three -⌝ - -→ string::extractBetween "${multilinetext}" "2 " $'\n' -⌜line two⌝ +4 line four' ``` -### Testing string::count function +❯ `string::extractBetween "${MULTI_LINES_TEXT2}" one$'\n' 4` +Returned variables: +```text +RETURNED_VALUE='2 line two +3 line three +' +``` -Exit code: `0` +❯ `string::extractBetween "${MULTI_LINES_TEXT2}" 2\ $'\n'` -Standard output +Returned variables: ```text -→ string::count 'name,firstname,address' ',' -⌜2⌝ - -→ string::count 'bonjour mon bon ami, bonne journée!' 'bo' -⌜3⌝ +RETURNED_VALUE='line two' ``` -### Testing string::split function +### ✅ Testing string::count function + +❯ `string::count name,firstname,address ,` +Returned variables: +```text +RETURNED_VALUE='2' +``` -Exit code: `0` +❯ `string::count bonjour\ mon\ bon\ ami,\ bonne\ journée! bo` -Standard output +Returned variables: ```text -→ string:::split 'name:firstname:address' ':' -name -firstname -address - -→ string::split 'one\ntwo\nthree' '\n' -one -two -three +RETURNED_VALUE='3' ``` -### Testing string::regexGetFirst function +### ✅ Testing string::split function + +❯ `string::split name:firstname:address :` +Returned variables: +```text +RETURNED_ARRAY=( +[0]='name' +[1]='firstname' +[2]='address' +) +``` -Exit code: `0` +❯ `string::split one$'\n'two$'\n'three $'\n'` -Standard output +Returned variables: ```text -→ string::regexGetFirst 'name: julien' 'name:[[:space:]]*([[:alnum:]]*)' -julien +RETURNED_ARRAY=( +[0]='one' +[1]='two' +[2]='three' +) ``` -### Testing string::microsecondsToHuman function +### ✅ Testing string::regexGetFirst function +❯ `string::regexGetFirst name:\ julien 'name:[[:space:]]*([[:alnum:]]*)'` +Returned variables: -Exit code: `0` +```text +RETURNED_VALUE='julien' +``` -Standard output +### ✅ Testing string::microsecondsToHuman function ```text -→ string::microsecondsToHuman 18243002234 'Hours: %HH +format='Hours: %HH Minutes: %MM Seconds: %SS Milliseconds: %LL @@ -336,8 +332,14 @@ Total minutes: %M Total seconds: %S Total milliseconds: %L Total microseconds: %U' +``` + +❯ `string::microsecondsToHuman 18243002234 "${format}"` -Hours: 05 +Returned variables: + +```text +RETURNED_VALUE='Hours: 05 Minutes: 04 Seconds: 03 Milliseconds: 002 @@ -352,193 +354,235 @@ Microseconds: 234 Total minutes: 304 Total seconds: 18243 Total milliseconds: 4320003002 -Total microseconds: 18243002234 +Total microseconds: 18243002234' +``` + +❯ `string::microsecondsToHuman 18243002234` -→ string::microsecondsToHuman 18243002234 -05:04:03 +Returned variables: -→ _OPTION_FORMAT='%U' string::microsecondsToHuman 18243002234 -18243002234 +```text +RETURNED_VALUE='05:04:03' ``` -### Wrapping text at column 30 with no padding +❯ `_OPTION_FORMAT=%U string::microsecondsToHuman 18243002234` + +Returned variables: + +```text +RETURNED_VALUE='18243002234' +``` +### ✅ Testing string::wrapText +Wrapping text at column 30 with no padding -Exit code: `0` +❯ `string::wrapText "${MULTI_LINES_TEXT}" 30` -Standard output +Returned variables: ```text -→ string::wrapText "${shortText}" 20 ------------------------------- -You don't get better -on the days when you -feel like going. You -get better on the -days when you don't -want to go, but you -go anyway. If you -can overcome the -negative energy -coming from your -tired body or -unmotivated mind, -you will grow and -become better. It -won't be the best -workout you have, -you won't accomplish -as much as what you -usually do when you -actually feel good, -but that doesn't -matter. Growth is a -long term game, and -the crappy days are -more important. - -As long as I focus -on what I feel and -don't worry about -where I'm going, it -works out. Having no -expectations but -being open to -everything is what -makes wonderful -things happen. If I -don't worry, there's -no obstruction and -life flows easily. -It sounds -impractical, but -'Expect nothing; be -open to everything' -is really all it is. -01234567890123456789 -on new line 01234567 -890123456789234 line +RETURNED_VALUE='You don`t get better on the +days when you feel like going. +You get better on the days +when you don`t want to go, but +you go anyway. If you can +overcome the negative energy +coming from your tired body or +unmotivated mind, you will +grow and become better. It +won`t be the best workout you +have, you won`t accomplish as +much as what you usually do +when you actually feel good, +but that doesn`t matter. +Growth is a long term game, +and the crappy days are more +important. + +As long as I focus on what I +feel and don`t worry about +where I`m going, it works out. +Having no expectations but +being open to everything is +what makes wonderful things +happen. If I don`t worry, +there`s no obstruction and +life flows easily. It sounds +impractical, but `Expect +nothing; be open to +everything` is really all it +is. 01234567890123456789 on +new line +01234567890123456789234 line new line. -https://en.wikipedia -.org/wiki/Veganism +https://en.wikipedia.org/wiki/ +Veganism -There were 2 new -lines before this. +There were 2 new lines before +this.' +RETURNED_VALUE2='8' ``` -### Wrapping text at column 50 with padding of 4 on new lines +Wrapping text at column 50 with padding of 4 on new lines +❯ `string::wrapText "${MULTI_LINES_TEXT}" 50 \ \ \ \ ` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapText "${shortText}" 90 ' ' ------------------------------------------------------------------------------------------- -You don't get better on the days when you feel +RETURNED_VALUE='You don`t get better on the days when you feel like going. You get better on the days when - you don't want to go, but you go anyway. If + you don`t want to go, but you go anyway. If you can overcome the negative energy coming from your tired body or unmotivated mind, you - will grow and become better. It won't be the - best workout you have, you won't accomplish as + will grow and become better. It won`t be the + best workout you have, you won`t accomplish as much as what you usually do when you actually - feel good, but that doesn't matter. Growth is + feel good, but that doesn`t matter. Growth is a long term game, and the crappy days are more important. - As long as I focus on what I feel and don't - worry about where I'm going, it works out. + As long as I focus on what I feel and don`t + worry about where I`m going, it works out. Having no expectations but being open to everything is what makes wonderful things - happen. If I don't worry, there's no + happen. If I don`t worry, there`s no obstruction and life flows easily. It sounds - impractical, but 'Expect nothing; be open to - everything' is really all it is. + impractical, but `Expect nothing; be open to + everything` is really all it is. 01234567890123456789 on new line 01234567890123456789234 line new line. https://en.wikipedia.org/wiki/Veganism - There were 2 new lines before this. + There were 2 new lines before this.' ``` -### Wrapping text at column 20 with padding of 3 on all lines +Wrapping text at column 20 with padding of 3 on all lines +❯ `string::wrapText "${MULTI_LINES_TEXT}" 20 \ \ \ 17` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapText "${shortText}" 90 ' ' 88 ------------------------------------------------------------------------------------------- - $ {RETURNED_VALUE} +RETURNED_VALUE='You don`t get + better on the + days when you + feel like going. + You get better on + the days when you + don`t want to go, + but you go + anyway. If you + can overcome the + negative energy + coming from your + tired body or + unmotivated mind, + you will grow and + become better. It + won`t be the best + workout you have, + you won`t + accomplish as + much as what you + usually do when + you actually feel + good, but that + doesn`t matter. + Growth is a long + term game, and + the crappy days + are more + important. + + As long as I + focus on what I + feel and don`t + worry about where + I`m going, it + works out. Having + no expectations + but being open to + everything is + what makes + wonderful things + happen. If I + don`t worry, + there`s no + obstruction and + life flows + easily. It sounds + impractical, but + `Expect nothing; + be open to + everything` is + really all it is. + 01234567890123456 + 789 on new line 0 + 12345678901234567 + 89234 line new + line. + + https://en.wikipe + dia.org/wiki/Vega + nism + + There were 2 new + lines before + this.' +RETURNED_VALUE2='4' ``` -### Wrapping words, shortcut because the message is a short single line +Wrapping words, shortcut because the message is a short single line +❯ `string::wrapText A\ message. 80` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapText 'A message.' 80 -A message. +RETURNED_VALUE='A message.' ``` -### Wrapping words, no shortcut! +Wrapping words, no shortcut! +❯ `string::wrapText A\ message. 80 '' 5` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapText 'A message.' 80 '' 5 -A -message. +RETURNED_VALUE='A +message.' ``` -### Wrapping words +Wrapping words +❯ `string::wrapText A\ message.$'\n'A\ new\ line 13 ░░░ 10` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapText 'A message.'$'\n''A new line' 13 '░░░' 10 -░░░A message. -░░░A new line +RETURNED_VALUE='A message. +░░░A new line' ``` -### Wrapping characters at column 20 with padding of 3 on all lines +### ✅ Testing string::wrapCharacters +Wrapping characters at column 20 with padding of 3 on all lines +❯ `string::wrapCharacters "${MULTI_LINES_TEXT}" 20 \ \ \ 17` -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapCharacters "${shortText}" 20 " " 17 --------------------- - You don't get bet +RETURNED_VALUE='You don`t get bet ter on the days w hen you feel like going. You get be tter on the days - when you don't wa + when you don`t wa nt to go, but you go anyway. If you can overcome the @@ -548,14 +592,14 @@ Standard output tivated mind, you will grow and bec ome better. It wo - n't be the best w + n`t be the best w orkout you have, - you won't accompl + you won`t accompl ish as much as wh at you usually do when you actually feel good, but th - at doesn't matter + at doesn`t matter . Growth is a lon g term game, and the crappy days a @@ -564,22 +608,22 @@ Standard output As long as I focu s on what I feel - and don't worry a - bout where I'm go + and don`t worry a + bout where I`m go ing, it works out . Having no expec tations but being open to everythin g is what makes w onderful things h - appen. If I don't - worry, there's no + appen. If I don`t + worry, there`s no obstruction and l ife flows easily. It sounds impract - ical, but 'Expect + ical, but `Expect nothing; be open - to everything' is + to everything` is really all it is. 01234567890123456 789 on new line 0 @@ -593,25 +637,22 @@ Standard output There were 2 new lines before this - . + .' +RETURNED_VALUE2='1' ``` -### Wrapping characters at 20, no other options +Wrapping characters at 20, no other options +❯ `string::wrapCharacters "${MULTI_LINES_TEXT}" 20` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapCharacters "${shortText}" 20 --------------------- -You don't get better +RETURNED_VALUE='You don`t get better on the days when you feel like going. You get better on the da -ys when you don't wa +ys when you don`t wa nt to go, but you go anyway. If you can o vercome the negative @@ -619,34 +660,34 @@ energy coming from y our tired body or un motivated mind, you will grow and become -better. It won't be +better. It won`t be the best workout you -have, you won't acco +have, you won`t acco mplish as much as wh at you usually do wh en you actually feel good, but that doesn -'t matter. Growth is +`t matter. Growth is a long term game, an d the crappy days ar e more important. As long as I focus o n what I feel and do -n't worry about wher -e I'm going, it work +n`t worry about wher +e I`m going, it work s out. Having no exp ectations but being open to everything i s what makes wonderf ul things happen. If -I don't worry, there -'s no obstruction an +I don`t worry, there +`s no obstruction an d life flows easily. It sounds impractica -l, but 'Expect nothi +l, but `Expect nothi ng; be open to every -thing' is really all +thing` is really all it is. 0123456789012 3456789 on new line 01234567890123456789 @@ -656,110 +697,111 @@ https://en.wikipedia .org/wiki/Veganism There were 2 new lin -es before this. +es before this.' +RETURNED_VALUE2='15' ``` -### Wrapping characters +Wrapping characters +❯ `string::wrapCharacters 01234567890123456789234 17 \ \ \ 1` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapCharacters 01234567890123456789234 17 ' ' 1 ------------------ - 0 +RETURNED_VALUE='0 12345678901234 - 56789234 + 56789234' +RETURNED_VALUE2='8' ``` -### Wrapping characters +Wrapping characters +❯ `string::wrapCharacters A\ message.$'\n'A\ new\ line 13 ░░░ 10` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapCharacters 'A message.'$'\n''A new line' 13 '░░░' 10 -░░░A message. -░░░A new line +RETURNED_VALUE='A message. +░░░A new line' +RETURNED_VALUE2='0' ``` -### Wrapping characters, spaces at the beginning of the line are kept +Wrapping characters, spaces at the beginning of the line are kept +❯ `string::wrapCharacters \ \ Start\ With\ spaces\ that\ must\ be\ kept!\ Other\ spaces\ can\ be\ ignored\ at\ wrapping.$'\n'\ \ Also\ start\ with\ spaces 17 \ \ \ 14` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ string::wrapCharacters ' Start With spaces that must be kept! Other spaces can be ignored at wrapping.'$'\n'' Also start with spaces' 17 ' ' 1 ------------------ - Start With s +RETURNED_VALUE=' Start With s paces that mus t be kept! Oth er spaces can be ignored at wrapping. Also start w - ith spaces + ith spaces' +RETURNED_VALUE2='10' ``` -### Testing string::highlight +### ✅ Testing string::highlight +❯ `string::highlight This\ is\ a\ Text\ to\ highlight. ttttt` +Returned variables: + +```text +RETURNED_VALUE='CHITCDEhis is a CHITCDEexCHItCDE CHItCDEo highlighCHItCDE.' +``` -Exit code: `0` +❯ `string::highlight This\ is\ a\ texT\ to\ highlight. TTTTT '>' '<'` -Standard output +Returned variables: ```text -→ string::highlight 'This is a text to highlight.' 'ttttt' -CHITCDEhis is a CHITCDEexCHItCDE CHItCDEo highlighCHItCDE. +RETURNED_VALUE='>TtT< >tt<.' +``` -→ string::highlight 'This is a text to highlight.' 'TTTTT' '>' '<' ->TtT< >tt<. +❯ `string::highlight '' ttttt` -→ string::highlight '' 'ttttt' +Returned variables: +```text +RETURNED_VALUE='' +``` + +❯ `string::highlight This\ is\ a\ text\ to\ highlight. ''` + +Returned variables: -→ string::highlight 'This is a text to highlight.' '' -This is a text to highlight. +```text +RETURNED_VALUE='This is a text to highlight.' ``` ### ✅ Testing string::head -**Global variables:** - ```text -_TEST_MULTILINE_STRING='The first line. -The second line. -The third line. -The fourth line. -The fifth line.' +MULTI_LINES_TEXT2='1 line one +2 line two +3 line three +4 line four' ``` -Testing string::head with 3 lines +Testing string::head with 2 lines -❯ `string::head The\ first\ line.$'\n'The\ second\ line.$'\n'The\ third\ line.$'\n'The\ fourth\ line.$'\n'The\ fifth\ line. 3` +❯ `string::head "${MULTI_LINES_TEXT2}" 2` Returned variables: ```text -RETURNED_VALUE='The first line. -The second line. -The third line. +RETURNED_VALUE='1 line one +2 line two ' ``` Testing string::head with 0 line -❯ `string::head The\ first\ line.$'\n'The\ second\ line.$'\n'The\ third\ line.$'\n'The\ fourth\ line.$'\n'The\ fifth\ line. 0` +❯ `string::head "${MULTI_LINES_TEXT2}" 0` Returned variables: @@ -769,16 +811,15 @@ RETURNED_VALUE='' Testing string::head with 10 lines -❯ `string::head The\ first\ line.$'\n'The\ second\ line.$'\n'The\ third\ line.$'\n'The\ fourth\ line.$'\n'The\ fifth\ line. 10` +❯ `string::head "${MULTI_LINES_TEXT2}" 10` Returned variables: ```text -RETURNED_VALUE='The first line. -The second line. -The third line. -The fourth line. -The fifth line. +RETURNED_VALUE='1 line one +2 line two +3 line three +4 line four ' ``` diff --git a/tests.d/lib-system/00.tests.sh b/tests.d/lib-system/00.tests.sh index 735c022..3d4898d 100644 --- a/tests.d/lib-system/00.tests.sh +++ b/tests.d/lib-system/00.tests.sh @@ -5,109 +5,72 @@ source system # shellcheck source=../../libraries.d/lib-io source io -function test_system::os() { - - echo "→ OSTYPE=linux-bsd system::os" - OSTYPE=linux-bsd system::os && echo "${RETURNED_VALUE}" - echo - - echo "→ OSTYPE=msys system::os" - OSTYPE=msys system::os && echo "${RETURNED_VALUE}" - echo - - echo "→ OSTYPE=darwin-stuff system::os" - OSTYPE=darwin-stuff system::os && echo "${RETURNED_VALUE}" - echo +function main() { + test_system::os + test_system::env + test_system::date + test_system::getUndeclaredVariables + test_system::getNotExistingCommands + test_system::commandExists + test_system::addToPath + test_system::windowsSetEnvVar + test_system::windowsGetEnvVar + test_system::windowsAddToPath +} - echo "→ OSTYPE=nop system::os" - OSTYPE=nop system::os && echo "${RETURNED_VALUE}" - echo +function test_system::os() { + test::title "✅ Testing system::os" - test::endTest "Testing system::os" 0 + test::func OSTYPE=linux-bsd system::os + test::func OSTYPE=msys system::os + test::func OSTYPE=darwin-stuff system::os + test::func OSTYPE=nop system::os } function test_system::env() { + test::title "✅ Testing system::env" RETURNED_ARRAY=() - echo "→ system::env" - system::env + test::exec system::env if ((${#RETURNED_ARRAY[*]} > 0)); then - echo "Found environment variables." + test::markdown "Found environment variables in RETURNED_ARRAY." fi - - test::endTest "Testing system::env" 0 } function test_system::date() { + test::title "✅ Testing system::date" - echo "→ system::date" - system::date && echo "Returned date with length ${#RETURNED_VALUE}." - echo - - echo "→ system::date %(%H:%M:%S)T" - system::date '%(%H:%M:%S)T' && echo "Returned date with length ${#RETURNED_VALUE}." - - test::endTest "Testing system::date" 0 + test::func system::date + test::func system::date "'%(%H:%M:%S)T'" } function test_system::getUndeclaredVariables() { + test::title "✅ Testing system::getUndeclaredVariables" - echo "→ system::getUndeclaredVariables" - if ! system::getUndeclaredVariables; then - echo "No undeclared variables found.${RETURNED_ARRAY[*]}" - fi - - echo - local abc="ok" - echo "→ system::getUndeclaredVariables GLOBAL_TEST_TEMP_FILE" - system::getUndeclaredVariables GLOBAL_TEST_TEMP_FILE abc dfg NOP - if system::getUndeclaredVariables GLOBAL_TEST_TEMP_FILE abc dfg NOP; then - echo "Found undeclared variables: ⌜${RETURNED_ARRAY[*]}⌝." - fi - - test::endTest "Testing system::date" 0 + test::func system::getUndeclaredVariables + test::exec ABC="ok" + test::func system::getUndeclaredVariables GLOBAL_TEST_TEMP_FILE dfg ABC NOP } function test_system::getNotExistingCommands() { + test::title "✅ Testing system::getNotExistingCommands" - echo "→ system::getNotExistingCommands" - if ! system::getNotExistingCommands; then - echo "No not existing commands found.${RETURNED_ARRAY[*]}" - fi - - echo - echo "→ system::getNotExistingCommands NONEXISTINGSTUFF system::getNotExistingCommands rm YETANOTHERONEMISSING" - if system::getNotExistingCommands NONEXISTINGSTUFF system::getNotExistingCommands rm YETANOTHERONEMISSING; then - echo "Found not existing commands: ⌜${RETURNED_ARRAY[*]}⌝." - fi + test::func system::getNotExistingCommands - test::endTest "Testing system::getNotExistingCommands" 0 + test::func system::getNotExistingCommands NONEXISTINGSTUFF system::getNotExistingCommands rm YETANOTHERONEMISSING } function test_system::commandExists() { + test::title "✅ Testing system::commandExists" - echo "→ system::commandExists" - if ! system::commandExists; then - echo "Command not found." - fi - - echo - echo "→ system::commandExists NONEXISTINGSTUFF" - if ! system::commandExists NONEXISTINGSTUFF; then - echo "Command not found." - fi - - echo - echo "→ system::commandExists rm ls" - if system::commandExists rm ls; then - echo "Found command." - fi - - test::endTest "Testing system::commandExists" 0 + test::exec system::commandExists + test::exec system::commandExists NONEXISTINGSTUFF + test::exec system::commandExists rm } +# shellcheck disable=SC2317 function test_system::addToPath() { - local oldHome="${HOME}" + test::title "✅ Testing system::addToPath" HOME="resources/gitignored" function zsh() { :; } @@ -118,71 +81,44 @@ function test_system::addToPath() { function ksh() { :; } function nu() { :; } - echo "→ system::addToPath" - system::addToPath "/coucou" - echo - echo "content of files:" - cat resources/gitignored/.zshrc - cat resources/gitignored/.tcshrc - cat resources/gitignored/.cshrc - cat resources/gitignored/.xonshrc - cat resources/gitignored/.config/fish/config.fish - cat resources/gitignored/.kshrc - cat resources/gitignored/.config/nushell/env.nu - - system::addToPath "/coucou" - - unset -f zsh tcsh csh xonsh fish ksh nu - HOME="${oldHome}" + test::exec system::addToPath "/coucou" + + test::exec io::cat resources/gitignored/.zshrc + test::exec io::cat resources/gitignored/.tcshrc + test::exec io::cat resources/gitignored/.cshrc + test::exec io::cat resources/gitignored/.xonshrc + test::exec io::cat resources/gitignored/.config/fish/config.fish + test::exec io::cat resources/gitignored/.kshrc + test::exec io::cat resources/gitignored/.config/nushell/env.nu + + test::exec system::addToPath "/coucou" + rm -Rf resources/gitignored - test::endTest "Testing system::addToPath" 0 } function test_system::windowsSetEnvVar() { - echo "→ system::windowsSetEnvVar VAR VALUE" - OSTYPE=msys system::windowsSetEnvVar VAR VALUE - echo - echo "→ system::windowsSetEnvVar VAR ''" - OSTYPE=msys system::windowsSetEnvVar VAR '' - echo - test::endTest "Testing system::windowsSetEnvVar" 0 + test::title "✅ Testing system::windowsSetEnvVar" + + test::exec OSTYPE=msys system::windowsSetEnvVar VAR VALUE + test::exec OSTYPE=msys system::windowsSetEnvVar VAR "''" } function test_system::windowsGetEnvVar() { - echo "→ system::windowsGetEnvVar VAR" - OSTYPE=msys system::windowsGetEnvVar VAR - echo - test::endTest "Testing system::windowsGetEnvVar" 0 + test::title "✅ Testing system::windowsGetEnvVar" + + test::exec OSTYPE=msys system::windowsGetEnvVar VAR } function test_system::windowsAddToPath() { - echo "→ system::windowsAddToPath /coucou" - OSTYPE=msys system::windowsAddToPath /coucou - echo - test::endTest "Testing system::windowsAddToPath" 0 -} + test::title "✅ Testing system::windowsAddToPath" -function main() { - test_system::os - test_system::env - test_system::date - test_system::getUndeclaredVariables - test_system::getNotExistingCommands - test_system::commandExists - test_system::addToPath - test_system::windowsSetEnvVar - test_system::windowsGetEnvVar - test_system::windowsAddToPath + test::exec OSTYPE=msys system::windowsAddToPath /coucou } -# backup original function -io::invoke declare -f io::windowsRunInPowershell -_ORIGINAL_FUNCTION="${RETURNED_VALUE//declare -? /}" - +# mocking windowsRunInPowershell function # shellcheck disable=SC2317 -function io::windowsRunInPowershell() { echo "io::windowsRunInPowershell: $*"; } +function io::windowsRunInPowershell() { + echo "🙈 mocking io::windowsRunInPowershell: $*"; +} main - -unset -f io::windowsRunInPowershell -eval "${_ORIGINAL_FUNCTION}" \ No newline at end of file diff --git a/tests.d/lib-system/results.approved.md b/tests.d/lib-system/results.approved.md index 9462450..0818cbb 100644 --- a/tests.d/lib-system/results.approved.md +++ b/tests.d/lib-system/results.approved.md @@ -2,145 +2,117 @@ ## Test script 00.tests -### Testing system::os +### ✅ Testing system::os +❯ `OSTYPE=linux-bsd system::os` - -Exit code: `0` - -Standard output +Returned variables: ```text -→ OSTYPE=linux-bsd system::os -linux - -→ OSTYPE=msys system::os -windows - -→ OSTYPE=darwin-stuff system::os -darwin - -→ OSTYPE=nop system::os -unknown - +RETURNED_VALUE='linux' ``` -### Testing system::env - - +❯ `OSTYPE=msys system::os` -Exit code: `0` - -Standard output +Returned variables: ```text -→ system::env -Found environment variables. +RETURNED_VALUE='windows' ``` -### Testing system::date - - - -Exit code: `0` +❯ `OSTYPE=darwin-stuff system::os` -Standard output +Returned variables: ```text -→ system::date -Returned date with length 22. - -→ system::date %(%H:%M:%S)T -Returned date with length 8. +RETURNED_VALUE='darwin' ``` -### Testing system::date - - +❯ `OSTYPE=nop system::os` -Exit code: `0` - -Standard output +Returned variables: ```text -→ system::getUndeclaredVariables -No undeclared variables found. - -→ system::getUndeclaredVariables GLOBAL_TEST_TEMP_FILE -Found undeclared variables: ⌜dfg NOP⌝. +RETURNED_VALUE='unknown' ``` -### Testing system::getNotExistingCommands +### ✅ Testing system::env +❯ `system::env` +Found environment variables in RETURNED_ARRAY. -Exit code: `0` +### ✅ Testing system::date -Standard output +❯ `system::date` -```text -→ system::getNotExistingCommands -No not existing commands found. +Returned variables: -→ system::getNotExistingCommands NONEXISTINGSTUFF system::getNotExistingCommands rm YETANOTHERONEMISSING -Found not existing commands: ⌜NONEXISTINGSTUFF YETANOTHERONEMISSING⌝. +```text +RETURNED_VALUE='1987-05-25_01h00m00s' ``` -### Testing system::commandExists - - - -Exit code: `0` +❯ `system::date '%(%H:%M:%S)T'` -Standard output +Returned variables: ```text -→ system::commandExists -Command not found. - -→ system::commandExists NONEXISTINGSTUFF -Command not found. - -→ system::commandExists rm ls -Found command. +RETURNED_VALUE='01:00:00' ``` -### Testing system::addToPath +### ✅ Testing system::getUndeclaredVariables +❯ `system::getUndeclaredVariables` +Returned code: `1` -Exit code: `0` +❯ `ABC=ok` -Standard output +❯ `system::getUndeclaredVariables GLOBAL_TEST_TEMP_FILE dfg ABC NOP` -```text -→ system::addToPath +Returned variables: -content of files: +```text +RETURNED_ARRAY=( +[0]='dfg' +[1]='NOP' +) +``` +### ✅ Testing system::getNotExistingCommands -export PATH="/coucou:${PATH}" +❯ `system::getNotExistingCommands` +Returned code: `1` -set path = ($path '/coucou') +❯ `system::getNotExistingCommands NONEXISTINGSTUFF system::getNotExistingCommands rm YETANOTHERONEMISSING` +Returned variables: -set path = ($path '/coucou') +```text +RETURNED_ARRAY=( +[0]='NONEXISTINGSTUFF' +[1]='YETANOTHERONEMISSING' +) +``` +### ✅ Testing system::commandExists -$PATH.append('/coucou') +❯ `system::commandExists` +Returned code: `1` -fish_add_path '/coucou' +❯ `system::commandExists NONEXISTINGSTUFF` +Returned code: `1` -export PATH="/coucou:${PATH}" +❯ `system::commandExists rm` +### ✅ Testing system::addToPath -$env.PATH = ($env.PATH | split row (char esep) | append "/coucou") -``` +❯ `system::addToPath /coucou` -Error output +**Error output**: ```text INFO Adding directory ⌜/coucou⌝ to the PATH for ⌜bash⌝ shell. @@ -169,6 +141,90 @@ Appending to ⌜resources/gitignored/.config/nushell/env.nu⌝: $env.PATH = ($env.PATH | split row (char esep) | append "/coucou") WARNING The directory ⌜/coucou⌝ has been added to the PATH for 8 shells. Please login again to apply the changes on your current shell if you are not using bash. +``` + +❯ `io::cat resources/gitignored/.zshrc` + +**Standard output**: + +```text + + +export PATH="/coucou:${PATH}" + +``` + +❯ `io::cat resources/gitignored/.tcshrc` + +**Standard output**: + +```text + + +set path = ($path '/coucou') + +``` + +❯ `io::cat resources/gitignored/.cshrc` + +**Standard output**: + +```text + + +set path = ($path '/coucou') + +``` + +❯ `io::cat resources/gitignored/.xonshrc` + +**Standard output**: + +```text + + +$PATH.append('/coucou') + +``` + +❯ `io::cat resources/gitignored/.config/fish/config.fish` + +**Standard output**: + +```text + + +fish_add_path '/coucou' + +``` + +❯ `io::cat resources/gitignored/.kshrc` + +**Standard output**: + +```text + + +export PATH="/coucou:${PATH}" + +``` + +❯ `io::cat resources/gitignored/.config/nushell/env.nu` + +**Standard output**: + +```text + + +$env.PATH = ($env.PATH | split row (char esep) | append "/coucou") + +``` + +❯ `system::addToPath /coucou` + +**Error output**: + +```text INFO The directory ⌜/coucou⌝ is already in the PATH for ⌜bash⌝ shell. INFO The directory ⌜/coucou⌝ is already in the PATH for ⌜ksh⌝ shell. INFO The directory ⌜/coucou⌝ is already in the PATH for ⌜zsh⌝ shell. @@ -179,53 +235,47 @@ INFO The directory ⌜/coucou⌝ is already in the PATH for ⌜fish⌝ shell INFO The directory ⌜/coucou⌝ is already in the PATH for ⌜nu⌝ shell. ``` -### Testing system::windowsSetEnvVar - +### ✅ Testing system::windowsSetEnvVar +❯ `OSTYPE=msys system::windowsSetEnvVar VAR VALUE` -Exit code: `0` - -Standard output +**Standard output**: ```text -→ system::windowsSetEnvVar VAR VALUE -io::windowsRunInPowershell: $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); $key.SetValue('VAR', 'VALUE', 'ExpandString'); - -→ system::windowsSetEnvVar VAR '' -io::windowsRunInPowershell: $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); $key.DeleteValue('VAR'); - +🙈 mocking io::windowsRunInPowershell: $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); $key.SetValue('VAR', 'VALUE', 'ExpandString'); ``` -### Testing system::windowsGetEnvVar +❯ `OSTYPE=msys system::windowsSetEnvVar VAR ''` +**Standard output**: +```text +🙈 mocking io::windowsRunInPowershell: $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); $key.DeleteValue('VAR'); +``` -Exit code: `0` +### ✅ Testing system::windowsGetEnvVar -Standard output +❯ `OSTYPE=msys system::windowsGetEnvVar VAR` + +**Standard output**: ```text -→ system::windowsGetEnvVar VAR -io::windowsRunInPowershell: +🙈 mocking io::windowsRunInPowershell: $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); $value = $key.GetValue('VAR', '', 'DoNotExpandEnvironmentNames'); $key.Dispose(); Write-Output $value; - ``` -### Testing system::windowsAddToPath +### ✅ Testing system::windowsAddToPath +❯ `OSTYPE=msys system::windowsAddToPath /coucou` - -Exit code: `0` - -Standard output +**Standard output**: ```text -→ system::windowsAddToPath /coucou -io::windowsRunInPowershell: +🙈 mocking io::windowsRunInPowershell: $pathToAdd = '\coucou'; $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); $oldPath = $key.GetValue('Path', '', 'DoNotExpandEnvironmentNames').TrimEnd([IO.Path]::PathSeparator); @@ -235,6 +285,5 @@ io::windowsRunInPowershell: }; $key.Dispose(); - ``` diff --git a/tests.d/lib-test/00.tests.sh b/tests.d/lib-test/00.tests.sh index ec9c170..b21e478 100644 --- a/tests.d/lib-test/00.tests.sh +++ b/tests.d/lib-test/00.tests.sh @@ -3,7 +3,6 @@ # shellcheck disable=SC2016 # shellcheck disable=SC2034 function main() { - test::title "✅ Testing the basic functions of lib-test" test::log "This push logs for debugging purposes. They will only appear if the test fails." test::markdown "You can insert comments that will appear as a paragraph in the test report." \ diff --git a/tests.d/lib-test/results.approved.md b/tests.d/lib-test/results.approved.md index 31f4cf4..1041309 100644 --- a/tests.d/lib-test/results.approved.md +++ b/tests.d/lib-test/results.approved.md @@ -275,9 +275,9 @@ Third test. ### 🪝 Testing the self test hooks -The variable TESTING_HOOKS shows that the hooks [before-tests](../before-tests), [before-each-test-suite](../before-each-test-suite), [before-each-test](before-each-test) have been executed. +The variable TESTING_HOOKS shows that the hooks [before-tests](../before-tests), [before-each-test-suite](../before-each-test-suite), [before-each-test](../before-each-test) have been executed. -This test is written in the [after-each-test](after-each-test) script. The `after-each-test-suites` and `after-tests` are executed after the test script exits, thus we can't output their results in this report. +This test is written in the [after-each-test](../after-each-test) script. The `after-each-test-suites` and `after-tests` are executed after the test script exits, thus we can't output their results in this report. ```text TESTING_HOOKS='before-tests,before-each-test-suite,before-each-test,after-each-test' diff --git a/tests.d/lib-version/00.version.sh b/tests.d/lib-version/00.version.sh new file mode 100644 index 0000000..561f6f3 --- /dev/null +++ b/tests.d/lib-version/00.version.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# shellcheck source=../../libraries.d/lib-version +source version + +function main() { + test_version::compare + test_version::bump +} + +function test_version::compare() { + test::title "✅ Testing version::compare function" + + test::func version::compare "1.2.3" "1.2.3" + test::func version::compare "1.2.3-alpha" "1.2.4+az123" + test::func version::compare "1.2.3" "1.2.2" + test::func version::compare "2.2.3" "1.2.3-alpha" + test::func version::compare "1.2.3+a1212" "1.3.3" + test::func version::compare "1.2.3-alpha+a123123" "1.2.3-alpha+123zer" + test::exit version::compare "1.2a.3" "1.2.3derp" +} + +function test_version::bump() { + test::title "✅ Testing version::bump" + + test::func version::bump "0.0.0" "minor" + test::func version::bump "1.2.3-alpha+zae345" "major" + test::func version::bump "1.2.3-alpha+zae345" "minor" + test::func version::bump "1.2.3-alpha+zae345" "patch" + test::func version::bump "1.2.3-alpha+zae345" "major" "false" + test::func version::bump "1.2.156-alpha" "patch" "false" + test::exit version::bump "aze" "patch" "false" +} + +main \ No newline at end of file diff --git a/tests.d/lib-version/results.approved.md b/tests.d/lib-version/results.approved.md new file mode 100644 index 0000000..892aa41 --- /dev/null +++ b/tests.d/lib-version/results.approved.md @@ -0,0 +1,124 @@ +# Test suite lib-version + +## Test script 00.version + +### ✅ Testing version::compare function + +❯ `version::compare 1.2.3 1.2.3` + +Returned variables: + +```text +RETURNED_VALUE='0' +``` + +❯ `version::compare 1.2.3-alpha 1.2.4+az123` + +Returned variables: + +```text +RETURNED_VALUE='-1' +``` + +❯ `version::compare 1.2.3 1.2.2` + +Returned variables: + +```text +RETURNED_VALUE='1' +``` + +❯ `version::compare 2.2.3 1.2.3-alpha` + +Returned variables: + +```text +RETURNED_VALUE='1' +``` + +❯ `version::compare 1.2.3+a1212 1.3.3` + +Returned variables: + +```text +RETURNED_VALUE='-1' +``` + +❯ `version::compare 1.2.3-alpha+a123123 1.2.3-alpha+123zer` + +Returned variables: + +```text +RETURNED_VALUE='0' +``` + +❯ `version::compare 1.2a.3 1.2.3derp` + +Exited with code: `1` + +**Error output**: + +```text +ERROR Failed to compare versions ⌜1.2a.3⌝ and ⌜1.2.3derp⌝ because they are not valid semantic versions. +``` + +### ✅ Testing version::bump + +❯ `version::bump 0.0.0 minor` + +Returned variables: + +```text +RETURNED_VALUE='0.1.0' +``` + +❯ `version::bump 1.2.3-alpha+zae345 major` + +Returned variables: + +```text +RETURNED_VALUE='2.0.0' +``` + +❯ `version::bump 1.2.3-alpha+zae345 minor` + +Returned variables: + +```text +RETURNED_VALUE='1.3.0' +``` + +❯ `version::bump 1.2.3-alpha+zae345 patch` + +Returned variables: + +```text +RETURNED_VALUE='1.2.4' +``` + +❯ `version::bump 1.2.3-alpha+zae345 major false` + +Returned variables: + +```text +RETURNED_VALUE='2.0.0-alpha+zae345' +``` + +❯ `version::bump 1.2.156-alpha patch false` + +Returned variables: + +```text +RETURNED_VALUE='1.2.157-alpha' +``` + +❯ `version::bump aze patch false` + +Exited with code: `1` + +**Error output**: + +```text +ERROR Failed to bump the version ⌜aze⌝ because it is not valid semantic version. +``` + diff --git a/tests.d/self-release/results.approved.md b/tests.d/self-release/results.approved.md index 7c68e82..161f7e7 100644 --- a/tests.d/self-release/results.approved.md +++ b/tests.d/self-release/results.approved.md @@ -108,7 +108,8 @@ DEBUG Analyzing the following files: 15 ░ $GLOBAL_VALET_HOME/libraries.d/lib-system 16 ░ $GLOBAL_VALET_HOME/libraries.d/lib-test 17 ░ $GLOBAL_VALET_HOME/libraries.d/lib-tui - 18 ░ $GLOBAL_VALET_HOME/libraries.d/main + 18 ░ $GLOBAL_VALET_HOME/libraries.d/lib-version + 19 ░ $GLOBAL_VALET_HOME/libraries.d/main DEBUG Found function: ⌜io::createTempFile⌝ DEBUG Found function: ⌜io::createTempDirectory⌝ DEBUG Found function: ⌜io::cleanupTempFiles⌝ @@ -210,8 +211,6 @@ DEBUG Found function: ⌜progress::update⌝ DEBUG Found function: ⌜progress::stop⌝ DEBUG Found function: ⌜prompt_getDisplayedPromptString⌝ DEBUG Found function: ⌜string::cutField⌝ -DEBUG Found function: ⌜string::compareSemanticVersion⌝ -DEBUG Found function: ⌜string::bumpSemanticVersion⌝ DEBUG Found function: ⌜string::camelCaseToSnakeCase⌝ DEBUG Found function: ⌜string::kebabCaseToSnakeCase⌝ DEBUG Found function: ⌜string::kebabCaseToCamelCase⌝ @@ -268,6 +267,8 @@ DEBUG Found function: ⌜tui::waitForKeyPress⌝ DEBUG Found function: ⌜tui::rebindKeymap⌝ DEBUG Found function: ⌜tui::resetBindings⌝ DEBUG Found function: ⌜tui::clearKeyPressed⌝ +DEBUG Found function: ⌜version::compare⌝ +DEBUG Found function: ⌜version::bump⌝ INFO Found 159 functions with documentation. ▶ called io::writeToFile $GLOBAL_VALET_HOME/extras/lib-valet.md INFO The documentation has been generated in ⌜$GLOBAL_VALET_HOME/extras/lib-valet.md⌝. @@ -521,10 +522,6 @@ INFO Writing the 159 functions documentation to the core libraries docs. ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/string.md ▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/string.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/string.md -▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/string.md -▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/string.md -▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/string.md -▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/string.md ▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/system.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/system.md ▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/system.md @@ -633,6 +630,12 @@ INFO Writing the 159 functions documentation to the core libraries docs. ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/tui.md ▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/tui.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/tui.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/version.md +▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/version.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/version.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/version.md +▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/version.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/version.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/array.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/codes.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/core.md diff --git a/version b/version index 5387769..2d8c872 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.28.2270 \ No newline at end of file +0.28.2358 \ No newline at end of file