From d29fc900bc7c7a2208230e2864ed6efbca9c18c0 Mon Sep 17 00:00:00 2001 From: Julien Caillon Date: Fri, 17 Jan 2025 00:07:53 +0100 Subject: [PATCH] :recycle: refactoring test lib and tests --- README.md | 2 +- commands.d/self-build-utils | 2 +- commands.d/self-install.sh | 14 +- commands.d/self-test.sh | 85 ++++- docs/content/docs/002.installation/_index.md | 2 +- docs/content/docs/030.test-commands/_index.md | 2 +- docs/content/docs/800.roadmap/_index.md | 1 + libraries.d/core | 9 +- libraries.d/lib-io | 49 ++- libraries.d/lib-test | 328 ++++++++++++++---- libraries.d/main | 3 + .../1005-lib-io/resources/dir/subdir/file1 | 0 tests.d/1005-lib-io/resources/search/file1 | 0 .../resources/search/subfolder1/file2 | 0 .../search/subfolder1/subfolder2/file3 | 0 tests.d/1011-lib-core/results.approved.md | 4 - tests.d/1012-lib-bash/00.tests.sh | 15 - tests.d/1012-lib-bash/results.approved.md | 28 -- tests.d/1013-lib-test/after-each-test | 7 - tests.d/1013-lib-test/resources/text-to-read | 0 tests.d/1013-lib-test/results.approved.md | 21 -- .../01.logging.sh} | 21 +- tests.d/cli-logging/results.approved.md | 34 ++ .../00.profiler.sh | 2 +- .../results.approved.md | 2 +- tests.d/{0900-valet-cli => cli}/.after-test | 0 tests.d/{0900-valet-cli => cli}/.before-test | 0 .../01.command-help.sh | 0 .../02.command-misc.sh | 0 .../03.event-handlers.sh | 0 .../04.interactive-mode.sh | 0 tests.d/{0900-valet-cli => cli}/06.misc.sh | 2 +- tests.d/{0900-valet-cli => cli}/08.submenu.sh | 0 .../resources/file-to-read | 0 .../results.approved.md | 2 +- .../.fuzzy-filter-benchmark.sh | 0 .../.sort-benchmark.sh | 0 .../{1006-lib-array => lib-array}/00.tests.sh | 0 .../results.approved.md | 2 +- .../sort-test-keys | 0 .../sort-test-values | 0 tests.d/{1006-lib-array => lib-array}/words | 0 .../{1011-lib-core => lib-bash}/00.tests.sh | 0 tests.d/lib-bash/results.approved.md | 4 + .../00.tests.sh | 0 .../results.approved.md | 2 +- .../{1013-lib-test => lib-core}/00.tests.sh | 1 - tests.d/lib-core/results.approved.md | 4 + .../{1002-lib-curl => lib-curl}/00.curl.sh | 0 .../results.approved.md | 2 +- .../00.tests.sh | 0 .../01.utilities.sh | 0 .../results.approved.md | 2 +- tests.d/{1005-lib-io => lib-io}/00.tests.sh | 32 +- tests.d/{1005-lib-io => lib-io}/01.invoke.sh | 3 +- .../{1005-lib-io => lib-io}/02.listPaths.sh | 0 .../resources/file-to-read | 0 .../resources/search/.hidden-file | 0 .../.hidden3/.hidden-file-13 | 0 .../search/.hidden-subfolder/.hidden3/file13 | 0 .../resources/search/.hidden-subfolder/file10 | 0 .../subfolder4/.hidden-file-14 | 0 .../.hidden-subfolder/subfolder4/file14 | 0 .../resources/search/subfolder1/.hidden-file2 | 0 .../subfolder1/subfolder2/.hidden-file3 | 0 .../results.approved.md | 267 ++++++++------ tests.d/{1010-lib-log => lib-log}/00.tests.sh | 8 +- .../{1010-lib-log => lib-log}/file-to-read | 0 .../results.approved.md | 42 +-- .../01.sort-commands.sh | 0 .../02.arguments-parser.sh | 0 .../{1001-lib-main => lib-main}/99.tests.sh | 0 .../results.approved.md | 2 +- .../00.tests.sh | 0 .../results.approved.md | 2 +- .../00.tests.sh | 0 .../results.approved.md | 2 +- .../00.tests.sh | 0 .../results.approved.md | 2 +- tests.d/lib-test/00.tests.sh | 99 ++++++ tests.d/lib-test/after-each-test | 6 + .../before-each-test | 0 tests.d/lib-test/results.approved.md | 188 ++++++++++ .../01.self-add-x.sh | 0 .../results.approved.md | 18 +- .../00.self-build-utils.sh | 0 .../resources/extract-command-yamls-test-file | 0 .../results.approved.md | 2 +- .../01.self-build.sh | 0 .../results.approved.md | 2 +- .../01.self-config.sh | 0 .../results.approved.md | 2 +- .../01.self-document.sh | 0 .../results.approved.md | 4 +- .../01.self-export.sh | 0 .../results.approved.md | 2 +- .../docker-valet-test/Dockerfile | 0 .../results.approved.md | 0 .../{1106-self-install => self-install}/test | 0 .../01.self-release.sh | 0 .../results.approved.md | 21 +- .../00.self-setup.sh | 0 .../results.approved.md | 2 +- .../01.self-uninstall.sh | 0 .../results.approved.md | 2 +- valet | 11 +- version | 2 +- 107 files changed, 1004 insertions(+), 369 deletions(-) delete mode 100644 tests.d/1005-lib-io/resources/dir/subdir/file1 delete mode 100644 tests.d/1005-lib-io/resources/search/file1 delete mode 100644 tests.d/1005-lib-io/resources/search/subfolder1/file2 delete mode 100644 tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/file3 delete mode 100644 tests.d/1011-lib-core/results.approved.md delete mode 100644 tests.d/1012-lib-bash/00.tests.sh delete mode 100644 tests.d/1012-lib-bash/results.approved.md delete mode 100644 tests.d/1013-lib-test/after-each-test delete mode 100644 tests.d/1013-lib-test/resources/text-to-read delete mode 100644 tests.d/1013-lib-test/results.approved.md rename tests.d/{0900-valet-cli/05.logging.sh => cli-logging/01.logging.sh} (89%) create mode 100644 tests.d/cli-logging/results.approved.md rename tests.d/{0901-profiler => cli-profiler}/00.profiler.sh (90%) rename tests.d/{0901-profiler => cli-profiler}/results.approved.md (99%) rename tests.d/{0900-valet-cli => cli}/.after-test (100%) rename tests.d/{0900-valet-cli => cli}/.before-test (100%) rename tests.d/{0900-valet-cli => cli}/01.command-help.sh (100%) rename tests.d/{0900-valet-cli => cli}/02.command-misc.sh (100%) rename tests.d/{0900-valet-cli => cli}/03.event-handlers.sh (100%) rename tests.d/{0900-valet-cli => cli}/04.interactive-mode.sh (100%) rename tests.d/{0900-valet-cli => cli}/06.misc.sh (97%) rename tests.d/{0900-valet-cli => cli}/08.submenu.sh (100%) rename tests.d/{0900-valet-cli => cli}/resources/file-to-read (100%) rename tests.d/{0900-valet-cli => cli}/results.approved.md (99%) rename tests.d/{1006-lib-array => lib-array}/.fuzzy-filter-benchmark.sh (100%) rename tests.d/{1006-lib-array => lib-array}/.sort-benchmark.sh (100%) rename tests.d/{1006-lib-array => lib-array}/00.tests.sh (100%) rename tests.d/{1006-lib-array => lib-array}/results.approved.md (99%) rename tests.d/{1006-lib-array => lib-array}/sort-test-keys (100%) rename tests.d/{1006-lib-array => lib-array}/sort-test-values (100%) rename tests.d/{1006-lib-array => lib-array}/words (100%) rename tests.d/{1011-lib-core => lib-bash}/00.tests.sh (100%) create mode 100644 tests.d/lib-bash/results.approved.md rename tests.d/{1009-lib-benchmark => lib-benchmark}/00.tests.sh (100%) rename tests.d/{1009-lib-benchmark => lib-benchmark}/results.approved.md (96%) rename tests.d/{1013-lib-test => lib-core}/00.tests.sh (98%) create mode 100644 tests.d/lib-core/results.approved.md rename tests.d/{1002-lib-curl => lib-curl}/00.curl.sh (100%) rename tests.d/{1002-lib-curl => lib-curl}/results.approved.md (99%) rename tests.d/{1007-lib-interactive => lib-interactive}/00.tests.sh (100%) rename tests.d/{1007-lib-interactive => lib-interactive}/01.utilities.sh (100%) rename tests.d/{1007-lib-interactive => lib-interactive}/results.approved.md (99%) rename tests.d/{1005-lib-io => lib-io}/00.tests.sh (89%) rename tests.d/{1005-lib-io => lib-io}/01.invoke.sh (96%) rename tests.d/{1005-lib-io => lib-io}/02.listPaths.sh (100%) rename tests.d/{1005-lib-io => lib-io}/resources/file-to-read (100%) rename tests.d/{1005-lib-io => lib-io}/resources/search/.hidden-file (100%) rename tests.d/{1005-lib-io => lib-io}/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 (100%) rename tests.d/{1005-lib-io => lib-io}/resources/search/.hidden-subfolder/.hidden3/file13 (100%) rename tests.d/{1005-lib-io => lib-io}/resources/search/.hidden-subfolder/file10 (100%) rename tests.d/{1005-lib-io => lib-io}/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 (100%) rename tests.d/{1005-lib-io => lib-io}/resources/search/.hidden-subfolder/subfolder4/file14 (100%) rename tests.d/{1005-lib-io => lib-io}/resources/search/subfolder1/.hidden-file2 (100%) rename tests.d/{1005-lib-io => lib-io}/resources/search/subfolder1/subfolder2/.hidden-file3 (100%) rename tests.d/{1005-lib-io => lib-io}/results.approved.md (66%) rename tests.d/{1010-lib-log => lib-log}/00.tests.sh (96%) rename tests.d/{1010-lib-log => lib-log}/file-to-read (100%) rename tests.d/{1010-lib-log => lib-log}/results.approved.md (95%) rename tests.d/{1001-lib-main => lib-main}/01.sort-commands.sh (100%) rename tests.d/{1001-lib-main => lib-main}/02.arguments-parser.sh (100%) rename tests.d/{1001-lib-main => lib-main}/99.tests.sh (100%) rename tests.d/{1001-lib-main => lib-main}/results.approved.md (99%) rename tests.d/{1008-lib-prompt => lib-prompt}/00.tests.sh (100%) rename tests.d/{1008-lib-prompt => lib-prompt}/results.approved.md (99%) rename tests.d/{1003-lib-string => lib-string}/00.tests.sh (100%) rename tests.d/{1003-lib-string => lib-string}/results.approved.md (99%) rename tests.d/{1004-lib-system => lib-system}/00.tests.sh (100%) rename tests.d/{1004-lib-system => lib-system}/results.approved.md (99%) create mode 100644 tests.d/lib-test/00.tests.sh create mode 100644 tests.d/lib-test/after-each-test rename tests.d/{1013-lib-test => lib-test}/before-each-test (100%) create mode 100644 tests.d/lib-test/results.approved.md rename tests.d/{1109-self-add-x => self-add-x}/01.self-add-x.sh (100%) rename tests.d/{1109-self-add-x => self-add-x}/results.approved.md (73%) rename tests.d/{1101-self-build-utils => self-build-utils}/00.self-build-utils.sh (100%) rename tests.d/{1101-self-build-utils => self-build-utils}/resources/extract-command-yamls-test-file (100%) rename tests.d/{1101-self-build-utils => self-build-utils}/results.approved.md (99%) rename tests.d/{1102-self-build => self-build}/01.self-build.sh (100%) rename tests.d/{1102-self-build => self-build}/results.approved.md (99%) rename tests.d/{1100-self-config => self-config}/01.self-config.sh (100%) rename tests.d/{1100-self-config => self-config}/results.approved.md (99%) rename tests.d/{1107-self-document => self-document}/01.self-document.sh (100%) rename tests.d/{1107-self-document => self-document}/results.approved.md (98%) rename tests.d/{1105-self-export => self-export}/01.self-export.sh (100%) rename tests.d/{1105-self-export => self-export}/results.approved.md (89%) rename tests.d/{1106-self-install => self-install}/docker-valet-test/Dockerfile (100%) rename tests.d/{1106-self-install => self-install}/results.approved.md (100%) rename tests.d/{1106-self-install => self-install}/test (100%) rename tests.d/{1103-self-release => self-release}/01.self-release.sh (100%) rename tests.d/{1103-self-release => self-release}/results.approved.md (97%) rename tests.d/{1104-self-setup => self-setup}/00.self-setup.sh (100%) rename tests.d/{1104-self-setup => self-setup}/results.approved.md (99%) rename tests.d/{1108-self-uninstall => self-uninstall}/01.self-uninstall.sh (100%) rename tests.d/{1108-self-uninstall => self-uninstall}/results.approved.md (90%) diff --git a/README.md b/README.md index cdc60e9..dbd2f88 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Latest Release](https://img.shields.io/github/v/release/jcaillon/valet?sort=date&style=flat&logo=github&logoColor=white&label=Latest%20release&color=%2350C878)][latest-release] [![Total downloads](https://img.shields.io/github/downloads/jcaillon/valet/total.svg?style=flat)][releases] [![MIT license](https://img.shields.io/badge/License-MIT-74A5C2.svg?style=flat)][license] -[![bash 5+ required](https://img.shields.io/badge/Requires-bash%20v5+-865FC5.svg?logo=gnubash&logoColor=white)][bash] +[![bash 5.1+ required](https://img.shields.io/badge/Requires-bash%20v5.1+-865FC5.svg?logo=gnubash&logoColor=white)][bash] [![icon](docs/static/logo.png)][valet-site] diff --git a/commands.d/self-build-utils b/commands.d/self-build-utils index 39b9e79..4aa0004 100644 --- a/commands.d/self-build-utils +++ b/commands.d/self-build-utils @@ -300,7 +300,7 @@ _CMD_INCLUDED=1 " # shellcheck disable=SC2086 - io::invoke declare -p ${!CMD_*} + io::captureOutput declare -p ${!CMD_*} local line local IFS while IFS=$'\n' read -r -d $'\n' line; do diff --git a/commands.d/self-install.sh b/commands.d/self-install.sh index 9dbe42d..0ce32ae 100644 --- a/commands.d/self-install.sh +++ b/commands.d/self-install.sh @@ -1,15 +1,13 @@ #!/usr/bin/env bash -set -Eeu -o pipefail # Title: commands.d/* # Author: github.com/jcaillon -# if not executing in bash, we can stop here -if [[ -z "${BASH_VERSION:-}" ]]; then - printf '%s\n' "❌ This script must be run with bash." 1>&2 - exit 1 -fi -if [[ ${BASH_VERSINFO[0]:-0} -lt 5 ]]; then - printf '%s\n' "❌ Bash 5 or higher is required to run valet." 1>&2 +# check the bash version (and that we are running in bash), make it POSIX compliant +# shellcheck disable=SC2292 +# shellcheck disable=SC2086 +# shellcheck disable=SC2128 +if [ ${BASH_VERSINFO:-0} -lt 5 ] || { [ ${BASH_VERSINFO} -eq 5 ] && [ ${BASH_VERSINFO[1]:-0} -lt 1 ]; }; then + printf '%s\n' "❌ Bash 5.1 or higher is required to run valet." exit 1 fi diff --git a/commands.d/self-test.sh b/commands.d/self-test.sh index d71b5bd..1183a8b 100644 --- a/commands.d/self-test.sh +++ b/commands.d/self-test.sh @@ -376,7 +376,7 @@ function selfTest_runSingleTestSuite() { # the global execution of the tests. if ! ( core::setShellOptions - trap 'selfTest_onExitTestInternal $? ' EXIT; + trap 'selfTest_onExitTestInternal $?' EXIT; trap 'selfTest_onErrTestInternal' ERR; selfTest_runSingleTest "${testSuiteDirectory}" "${testScript}" || exit $? ) >"${GLOBAL_TEST_STACK_FILE}" 2>"${GLOBAL_TEST_LOG_FILE}"; then @@ -390,26 +390,57 @@ function selfTest_runSingleTestSuite() { eval "${RETURNED_VALUE//declare -a/}" selfTestUtils_displayTestLogs - if log::isDebugEnabled; then - selfTestUtils_displayTestLogs - fi selfTestUtils_displayTestSuiteOutputs - log::error "The program exited with code ⌜${exitCode}⌝."$'\n'"Test scripts must not exit or return an error (do not forget that shell options are set to exit on error)."$'\n'$'\n'"If you expect a tested function or command to exit or fail, then run it in a subshell and capture the exit code like that:"$'\n'"⌜(myFunctionThatFails) || echo 'failed as expected with code \${PIPESTATUS[0]:-}'⌝"$'\n'$'\n'"Error in ⌜${testScript/#"${GLOBAL_PROGRAM_STARTED_AT_DIRECTORY}/"/}⌝." - log::printCallStack 1 7 + if (( exitCode == 142 )); then + # the function test::fail was called, there was a coding mistake in the test script that we caught + io::readFile "${GLOBAL_TEST_LOG_FILE}" + log::error "The test script ⌜${testScript##*/}⌝ failed because of a bad test implementation." \ + "" \ + "${RETURNED_VALUE}" \ + "" \ + "Error in ⌜${testScript/#"${GLOBAL_PROGRAM_STARTED_AT_DIRECTORY}/"/}⌝." + + elif [[ -n ${_STACK_FUNCTION_NAMES_ERR:-} ]]; then + log::error "The test script ⌜${testScript##*/}⌝ had an error and exited with code ⌜${exitCode}⌝." \ + "Test scripts will exit if a command ends with an error (shell option to exit on error)." \ + ""\ + "If you expect a tested function or command to fail, use one of these two methods to display the failure without exiting the script:" \ + ""\ + "- ⌜myCommandThatFails || echo 'failed as expected with code \$?'⌝" \ + "- ⌜test::exec myCommandThatFails⌝" \ + ""\ + "Error in ⌜${testScript/#"${GLOBAL_PROGRAM_STARTED_AT_DIRECTORY}/"/}⌝:" + _STACK_FUNCTION_NAMES=("${_STACK_FUNCTION_NAMES_ERR[@]}") + _STACK_SOURCE_FILES=("${_STACK_SOURCE_FILES_ERR[@]}") + _STACK_LINE_NUMBERS=("${_STACK_LINE_NUMBERS_ERR[@]}") + # print the last line of the err output, which is supposed to be the bash error message + io::tail "${GLOBAL_TEST_STANDARD_ERROR_FILE}" 1 true + if [[ -n ${RETURNED_ARRAY[0]:-} ]]; then + log::printString "░ ${RETURNED_ARRAY[0]:-}" "░ " + fi + log::printCallStack 2 7 + else + log::error "The test script ⌜${testScript##*/}⌝ exited with code ⌜${exitCode}⌝." \ + "Test scripts must not exit or return an error (shell options are set to exit on error)." \ + "" \ + "If you expect a tested function or command to exit, run it in a subshell using one of these two methods:" \ + "" \ + "- ⌜(myCommandThatFails) || echo 'failed as expected with code \${PIPESTATUS[0]:-}'⌝" \ + "- ⌜test::exit myCommandThatFails⌝" \ + "" \ + "Error in ⌜${testScript/#"${GLOBAL_PROGRAM_STARTED_AT_DIRECTORY}/"/}⌝:" + log::printCallStack 1 7 + fi nbOfScriptsWithErrors+=1 else - # end of test - if log::isDebugEnabled; then - selfTestUtils_displayTestLogs - fi - # check if the user forgot to call test::endTest if [[ -s "${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" || -s "${GLOBAL_TEST_STANDARD_ERROR_FILE}" ]]; then selfTestUtils_displayTestSuiteOutputs - log::error "Test script did not call ⌜test::endTest⌝ or it had outputs after the last call or ⌜test::endTest⌝."$'\n'$'\n'"Make sure to conclude all tests by calling the ⌜test::endTest⌝ function (nothing should be printed to the standard or error output after that)."$'\n'$'\n'"Error in ⌜${testScript/#"${GLOBAL_PROGRAM_STARTED_AT_DIRECTORY}/"/}⌝." + selfTestUtils_displayTestLogs + log::error "The test script had un-flushed when it ended."$'\n'$'\n'"Make sure to conclude all test scripts by calling the ⌜test::flush⌝ or ⌜test::endTest⌝ functions (nothing should be printed to the standard or error output after that)."$'\n'$'\n'"Error in ⌜${testScript/#"${GLOBAL_PROGRAM_STARTED_AT_DIRECTORY}/"/}⌝." nbOfScriptsWithErrors+=1 fi @@ -423,8 +454,20 @@ function selfTest_runSingleTestSuite() { # run a custom user script after the test suite if it exists selfTestUtils_runHookScript "${testsDotDirectory}/after-each-test-suite" - ((nbOfScriptsWithErrors > 0)) && return 1 - selfTestUtils_compareWithApproved "${testSuiteDirectory}" "${GLOBAL_TEST_REPORT_FILE}" || return 1 + # exit with an error if there were errors in the test scripts + if ((nbOfScriptsWithErrors > 0)); then + return 1 + fi + + # compare the test suite outputs with the approved files + if selfTestUtils_compareWithApproved "${testSuiteDirectory}" "${GLOBAL_TEST_REPORT_FILE}"; then + selfTestUtils_displayTestLogs + return 1 + fi + + if log::isDebugEnabled; then + selfTestUtils_displayTestLogs + fi return 0 } @@ -434,7 +477,7 @@ function selfTest_runSingleTestSuite() { # It will output the stack trace in a file. # We need to capture the stack trace within the subshell that runs the test script. function selfTest_onExitTestInternal() { - # handle an error in the test script + # handle an exit in the test script local exitCode="${1}" if ((exitCode == 0)); then @@ -447,6 +490,18 @@ function selfTest_onExitTestInternal() { declare -p _STACK_FUNCTION_NAMES _STACK_SOURCE_FILES _STACK_LINE_NUMBERS 1>&3 } +# ## selfTest_onErrTestInternal +# +# Will be called if a test script has an error. +# We need to capture the stack trace within the subshell that runs the test script. +function selfTest_onErrTestInternal() { + # handle an error in the test script + _STACK_FUNCTION_NAMES_ERR=("${FUNCNAME[@]}") + _STACK_SOURCE_FILES_ERR=("${BASH_SOURCE[@]}") + _STACK_LINE_NUMBERS_ERR=("${BASH_LINENO[@]}") + declare -p _STACK_FUNCTION_NAMES_ERR _STACK_SOURCE_FILES_ERR _STACK_LINE_NUMBERS_ERR 1>&3 +} + # ## selfTest_runSingleTest # # Run a single test script. diff --git a/docs/content/docs/002.installation/_index.md b/docs/content/docs/002.installation/_index.md index b3f6ca8..8f3b9d6 100644 --- a/docs/content/docs/002.installation/_index.md +++ b/docs/content/docs/002.installation/_index.md @@ -9,7 +9,7 @@ description: Learn how to install Valet on your system. ## 📦 Dependencies -- Bash version 5 or superior is required (it uses bash `EPOCHREALTIME`). +- Bash version 5.1 or superior is required (it uses bash `EPOCHREALTIME`). - From [GNU coreutils][gnu-core-utils]: it uses `rm`, `mv`, `mkdir` for all commands. It uses `cp`, `chmod`, `touch` for the installation/updates. *You most likely already have all of these!* - [curl][curl] and [tar][tar] are needed only if you want to use the `self update` or `self extend` command. diff --git a/docs/content/docs/030.test-commands/_index.md b/docs/content/docs/030.test-commands/_index.md index bbc5d9e..5f7b65c 100644 --- a/docs/content/docs/030.test-commands/_index.md +++ b/docs/content/docs/030.test-commands/_index.md @@ -80,7 +80,7 @@ Tests are implemented in `.sh` scripts directly under a test suite directory. Th You have 2 extra functions at your disposal in test scripts (see [libraries/test][libraries-tests] for more details): -- `test::commentTest "comment"`: Add a text paragraph in the test result file. E.g. `test::commentTest "Here we are testing that 1+1 is equal to 2. Awesome."` +- `test::comment "comment"`: Add a text paragraph in the test result file. E.g. `test::comment "Here we are testing that 1+1 is equal to 2. Awesome."` - `test::endTest "title" $? "description"`: Call this function after each test to append the test results to the report file. This create a new `h3` header with the title, write the given exit code and include the stdout and stderr of the test inside markdown code. It optionally can add a description to the test. You can check a script example to [test the Valet string library here][valet-string-lib-tests]. diff --git a/docs/content/docs/800.roadmap/_index.md b/docs/content/docs/800.roadmap/_index.md index e5bc364..b4a2bb3 100644 --- a/docs/content/docs/800.roadmap/_index.md +++ b/docs/content/docs/800.roadmap/_index.md @@ -8,6 +8,7 @@ url: /docs/roadmap This page lists the features that I would like to implement in Valet. They come in addition to new features described in the [issues][valet-issues]. +- document the test; use the lib-test test as an example, and also link to the test:: lib. - test the new bash:: lib - refacto progress bar; use signal to tell the bg job to redraw the progress bar after displaying a log. - after logging, if progress bar is in progress, we need to redraw it immediately. diff --git a/libraries.d/core b/libraries.d/core index 1c32061..790f955 100644 --- a/libraries.d/core +++ b/libraries.d/core @@ -3,8 +3,13 @@ # Description: this script contains the core functions and variables and it # should be sourced, not called directly # Author: github.com/jcaillon -if [[ ${BASH_VERSINFO[0]:-0} -lt 5 ]]; then - printf '%s\n' "Bash 5 or higher is required to run valet." + +# check the bash version (and that we are running in bash), make it POSIX compliant +# shellcheck disable=SC2292 +# shellcheck disable=SC2086 +# shellcheck disable=SC2128 +if [ ${BASH_VERSINFO:-0} -lt 5 ] || { [ ${BASH_VERSINFO} -eq 5 ] && [ ${BASH_VERSINFO[1]:-0} -lt 1 ]; }; then + printf '%s\n' "❌ Bash 5.1 or higher is required to run valet." exit 1 fi diff --git a/libraries.d/lib-io b/libraries.d/lib-io index c71d758..3dafab8 100644 --- a/libraries.d/lib-io +++ b/libraries.d/lib-io @@ -671,19 +671,20 @@ function io::cat() { # The number of lines to print. # - $3: to variable _as bool_: # (optional) Can be set using the variable `_OPTION_TO_VARIABLE`. -# If true, the output will be stored in the variable `RETURNED_VALUE` +# If true, the output will be stored in the variable `RETURNED_ARRAY` # instead of being printed to stdout. # (defaults to false) # # ```bash # io::head "myFile" 10 # ``` - +# +# > #TODO: faster with mapfile? function io::head() { local filePath="${1}" local -i numberOfLines="${2}" local toVariable="${3:-${_OPTION_TO_VARIABLE:-false}}" - RETURNED_VALUE="" + RETURNED_ARRAY=() local IFS=$'\n' line nb=0 while read -rd $'\n' line || [[ -n ${line:-} ]]; do @@ -691,13 +692,53 @@ function io::head() { break fi if [[ ${toVariable} == "true" ]]; then - RETURNED_VALUE+="${line}"$'\n' + RETURNED_ARRAY+=("${line}") else printf '%s\n' "${line}" fi done <"${filePath}" } +# ## io::tail +# +# Print the last lines of a file to stdout. +# This is a pure bash equivalent of tail. +# However, because we have to read the whole file, it is not efficient for large files. +# +# - $1: **path** _as string_: +# The file to print. +# - $2: **number of lines** _as int_: +# The number of lines to print from the end of the file. +# - $3: to variable _as bool_: +# (optional) Can be set using the variable `_OPTION_TO_VARIABLE`. +# If true, the output will be stored in the variable `RETURNED_ARRAY` +# instead of being printed to stdout. +# (defaults to false) +# +# ```bash +# io::tail "myFile" 10 +# ``` +# +# > #TODO: use mapfile quantum to not have to read the whole file in a single go. +function io::tail() { + local filePath="${1}" + local -i numberOfLines="${2}" + local toVariable="${3:-${_OPTION_TO_VARIABLE:-false}}" + RETURNED_ARRAY=() + local IFS=$'\n' + local -a lines + mapfile -d $'\n' -t lines <"${filePath}" + local -i startLine=$(( ${#lines[@]} - numberOfLines )) + if [[ ${startLine} -lt 0 ]]; then + startLine=0 + fi + if [[ ${toVariable} == "true" ]]; then + RETURNED_ARRAY=("${lines[@]:${startLine}}") + else + printf '%s\n' "${lines[@]:${startLine}}" + fi +} + # ## io::readStdIn # # Read the content of the standard input. diff --git a/libraries.d/lib-test b/libraries.d/lib-test index 4e8f844..f8295d4 100644 --- a/libraries.d/lib-test +++ b/libraries.d/lib-test @@ -2,6 +2,22 @@ # author: github.com/jcaillon # description: This script can be sourced by commands to provide convenient functions. +# ## test::log +# +# Call this function to log a message during a test. +# This log will only show in case of a script error or when the debug +# log level is enabled when running the tests. +# +# - $@: **messages** _as string_: +# The messages to log. +# +# ```bash +# test::log "This is a log message." +# ``` +function test::log() { + printf '%s\n' "${@}" >&4 +} + # ## test::title # # Call this function to add an H3 title in the report file. @@ -16,25 +32,42 @@ function test::title() { printf "%s\n\n" "### ${1:-"Test"}" >>"${GLOBAL_TEST_REPORT_FILE}" } -# ## test::commentTest +# ## test::comment # # Call this function to add a paragraph in the report file. # -# - $1: **comment** _as string_: -# The text to add in the report file. +# - $@: **comment paragraphs** _as string_: +# The paragraphs to add in the report file. +# +# ```bash +# test::comment "This is a comment." +# ``` +function test::comment() { + printf "%s\n\n" "${@}" >>"${GLOBAL_TEST_REPORT_FILE}" +} + +# ## test::func +# +# Call this function to test a function that returns a value using the valet +# conventions (RETURNED_VALUE, RETURNED_ARRAY, etc...). +# +# It will write the command and its output to the report file. +# +# - $@: **command** _as string_: +# The command to execute (function and its arguments). # # ```bash -# test::commentTest "This is a comment." +# test::func myFunction # ``` -function test::commentTest() { - printf "%s\n\n" "${1:-}" >>"${GLOBAL_TEST_REPORT_FILE}" +function test::func() { + test_exec false true "$@" } # ## test::exec # # Call this function to execute a command and write the command and its output to the report file. # The command can fail, in which case the returned exit code is written to the report file. -# However, the command must not call `exit` (in which case, use test::execExiting). +# However, the command must not call `exit` (in which case, use test::exit). # # - $@: **command** _as string_: # The command to execute. @@ -43,10 +76,10 @@ function test::commentTest() { # test::exec echo "Hello, world!" # ``` function test::exec() { - test_execInternal false "$@" + test_exec false false "$@" } -# ## test::execExiting +# ## test::exit # # Call this function to execute a command that can call `exit` and write the command and its output to the report file. # The command is executed in a subshell to catch the exit. @@ -55,96 +88,185 @@ function test::exec() { # The command to execute. # # ```bash -# test::execExiting exit 3 +# test::exit exit 3 # ``` -function test::execExiting() { - test_execInternal true "$@" +function test::exit() { + test_exec true false "$@" } -# ## test_execInternal (private) +# ## test:: + +# ## test_exec (private) # -# This function is called by test::exec and test::execExiting to execute a command and +# This function is called by test::exec and test::exit to execute a command and # write the command and its output to the report file. # -# - $1: **canExit** _as boolean_: +# - $1: **can exit** _as boolean_: # Whether the command can call `exit`. +# - $2: **display returned values** _as boolean_: +# Whether the returned values should be displayed in the report. +# (e.g. RETURNED_VALUE, RETURNED_VALUE2, RETURNED_ARRAY...) # - $@: **command** _as string_: # The command to execute. # # ```bash -# test_execInternal false echo "Hello, world!" +# test_exec false echo "Hello, world!" # ``` -function test_execInternal() { +function test_exec() { local canExit="${1}" - shift 1 - local arg - local reportSection="Prompt:"$'\n'$'\n'"\`\`\`bash"$'\n' - for arg in "$@"; do - if [[ ${arg} == *[[:space:]]* ]]; then - reportSection+="\"${arg}\" " - else - reportSection+="${arg} " - fi - done - reportSection="${reportSection% }"$'\n'"\`\`\`"$'\n'$'\n' + local displayReturnedValues="${2}" + shift 2 - printf '%s' "${reportSection}" >>"${GLOBAL_TEST_REPORT_FILE}" + local IFS=' ' + # compute the command to run, escaping special characters + local compoundCommand="${*//[\\[:space:]]/\\&}" - # reset the standard output and error output files - # It is necessary to first close the file descriptors before resetting the files - exec 1>&- - exec 2>&- - : >"${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" - : >"${GLOBAL_TEST_STANDARD_ERROR_FILE}" - exec 1>"${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" - exec 2>"${GLOBAL_TEST_STANDARD_ERROR_FILE}" + # shellcheck disable=SC2016 + printf 'Prompt:\n\n```bash\n%s\n```\n\n' "${compoundCommand}" >>"${GLOBAL_TEST_REPORT_FILE}" + + if [[ -s "${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" || -s "${GLOBAL_TEST_STANDARD_ERROR_FILE}" ]]; then + test::fail "⌜${FUNCNAME[1]}⌝ was called in ⌜${BASH_SOURCE[2]:-}:${BASH_LINENO[1]:-}⌝ but the standard/error output were not empty, call ⌜test::flush⌝ first or do not write to these streams." + fi + + if [[ ${displayReturnedValues} == "true" ]]; then + local RETURNED_VALUE RETURNED_VALUE2 RETURNED_VALUE3 RETURNED_VALUE4 + local -a RETURNED_ARRAY RETURNED_ARRAY2 + local -A RETURNED_ASSOCIATIVE_ARRAY + fi + + # reset IFS to ensure consistent behavior + IFS=' '$'\t'$'\n' # execute the command local -i exitCode=0 if [[ ${canExit} == "true" ]]; then - if ! ("$@") 1>>"${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" 2>>"${GLOBAL_TEST_STANDARD_ERROR_FILE}"; then + if ! (eval "${compoundCommand}") 1>>"${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" 2>>"${GLOBAL_TEST_STANDARD_ERROR_FILE}"; then exitCode=${PIPESTATUS[0]:-} fi else - if ! "$@" 1>>"${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" 2>>"${GLOBAL_TEST_STANDARD_ERROR_FILE}"; then + if ! eval "${compoundCommand}" 1>>"${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" 2>>"${GLOBAL_TEST_STANDARD_ERROR_FILE}"; then exitCode=$? fi fi - if (( exitCode != 0 )); then - printf '%s\n\n' "Exited with code: \`${exitCode}\`" >>"${GLOBAL_TEST_REPORT_FILE}" + if ((exitCode != 0)); then + # shellcheck disable=SC2016 + printf 'Exited with code: `%s`\n\n' "${exitCode}" >>"${GLOBAL_TEST_REPORT_FILE}" fi - test::flushFdToCodeBlock 1 true - test::flushFdToCodeBlock 2 true + test_flushFdToCodeBlock 1 "Standard output" + test_flushFdToCodeBlock 2 "Error output" + + if [[ ${displayReturnedValues} == "true" ]]; then + test::revealReturnedVars + fi } -# ## test::flushFdToCodeBlock +# ## test::revealReturnedVars +# +# This function can be called to display the returned values, +# e.g. RETURNED_VALUE, RETURNED_VALUE2, RETURNED_ARRAY... +# They will each be displayed in a code block in the report file. +# +# ```bash +# test::revealReturnedVars +# ``` +function test::revealReturnedVars() { + local IFS=$'\n' output key + if [[ -n ${RETURNED_VALUE:-} ]]; then + # shellcheck disable=SC2016 + printf 'RETURNED_VALUE:\n\n```text\n%s\n```\n\n' "${RETURNED_VALUE}" >>"${GLOBAL_TEST_REPORT_FILE}" + fi + if [[ -n ${RETURNED_VALUE2:-} ]]; then + # shellcheck disable=SC2016 + printf 'RETURNED_VALUE2:\n\n```text\n%s\n```\n\n' "${RETURNED_VALUE2}" >>"${GLOBAL_TEST_REPORT_FILE}" + fi + if [[ -n ${RETURNED_VALUE3:-} ]]; then + # shellcheck disable=SC2016 + printf 'RETURNED_VALUE3:\n\n```text\n%s\n```\n\n' "${RETURNED_VALUE3}" >>"${GLOBAL_TEST_REPORT_FILE}" + fi + if [[ -n ${RETURNED_VALUE4:-} ]]; then + # shellcheck disable=SC2016 + printf 'RETURNED_VALUE4:\n\n```text\n%s\n```\n\n' "${RETURNED_VALUE4}" >>"${GLOBAL_TEST_REPORT_FILE}" + fi + if [[ -n ${RETURNED_ARRAY:-} ]]; then + for key in "${!RETURNED_ARRAY[@]}"; do + output+="[${key}]=${RETURNED_ARRAY[${key}]}"$'\n' + done + # shellcheck disable=SC2016 + printf 'RETURNED_ARRAY:\n\n```text\n%s\n```\n\n' "${output}" >>"${GLOBAL_TEST_REPORT_FILE}" + fi + if [[ -n ${RETURNED_ARRAY2:-} ]]; then + for key in "${!RETURNED_ARRAY2[@]}"; do + output+="[${key}]=${RETURNED_ARRAY2[${key}]}"$'\n' + done + # shellcheck disable=SC2016 + printf 'RETURNED_ARRAY2:\n\n```text\n%s\n```\n\n' "${output}" >>"${GLOBAL_TEST_REPORT_FILE}" + fi + if [[ -n ${RETURNED_ASSOCIATIVE_ARRAY:-} ]]; then + for key in "${!RETURNED_ASSOCIATIVE_ARRAY[@]}"; do + output+="[${key}]=${RETURNED_ASSOCIATIVE_ARRAY[${key}]}"$'\n' + done + # shellcheck disable=SC2016 + printf 'RETURNED_ASSOCIATIVE_ARRAY:\n\n```text\n%s\n```\n\n' "${output}" >>"${GLOBAL_TEST_REPORT_FILE}" + fi +} + +# ## test::resetReturnedVars +# +# Resets the value of each RETURNED_ variable. +# +# ```bash +# test::resetReturnedVars +# ``` +function test::resetReturnedVars() { + local IFS=' ' + # shellcheck disable=SC2086 + unset ${!RETURNED_*} +} + +# ## test::revealVars +# +# This function can be called to display the global variables in the report file. +# They will displayed in a code block in the report file. +# +# - $@: **variables** _as string_: +# The variables to display. +# +# ```bash +# test::revealVars myVar +# ``` +function test::revealVars() { + local IFS=$'\n' output + io::captureOutput declare -p "${@}" + output="${RETURNED_VALUE//declare -? /}" + # shellcheck disable=SC2016 + printf '```text\n%s\n```\n\n' "${output}" >>"${GLOBAL_TEST_REPORT_FILE}" +} + +# ## test_flushFdToCodeBlock (private) # # This function write the captured standard and error outputs to the report file # and reset these file descriptors. # # - $1: **fdNumber** _as int_: # The file descriptor number to flush (1 or 2). -# - $2: **blockTitle** _as boolean_: +# - $2: **blockTitle** _as string_: # (optional) Can be set using the variable `_OPTION_BLOCK_TITLE`. -# Whether to add a title to the code block. -# (defaults to false) +# Add a 'title' to the code block (`**title**:` before the code block). +# (defaults to '' which will not add a title) # # ```bash -# test::flushFdToCodeBlock 1 true +# test_flushFdToCodeBlock 1 true # ``` -function test::flushFdToCodeBlock() { +function test_flushFdToCodeBlock() { local -i fdNumber="${1}" - local blockTitle="${2:-${_OPTION_BLOCK_TITLE:-false}}" + local blockTitle="${2:-${_OPTION_BLOCK_TITLE:-}}" local file - local codeBlockName - if (( fdNumber == 1 )); then + if ((fdNumber == 1)); then file="${GLOBAL_TEST_STANDARD_OUTPUT_FILE}" - codeBlockName="Standard output" else file="${GLOBAL_TEST_STANDARD_ERROR_FILE}" - codeBlockName="Error output" fi if [[ ! -s "${file}" ]]; then return 0 @@ -156,9 +278,9 @@ function test::flushFdToCodeBlock() { text="${text//${GLOBAL_TEMPORARY_DIRECTORY_PREFIX}/\/tmp/valet}" text="${text//${GLOBAL_TEMPORARY_FILE_PREFIX}/\/tmp/valet}" - if [[ ${blockTitle} == "true" ]]; then + if [[ -n ${blockTitle} ]]; then # shellcheck disable=SC2016 - printf '**%s**:\n\n```text\n%s\n```\n\n' "${codeBlockName}" "${text%$'\n'}" >>"${GLOBAL_TEST_REPORT_FILE}" + printf '**%s**:\n\n```text\n%s\n```\n\n' "${blockTitle}" "${text%$'\n'}" >>"${GLOBAL_TEST_REPORT_FILE}" else # shellcheck disable=SC2016 printf '```text\n%s\n```\n\n' "${text%$'\n'}" >>"${GLOBAL_TEST_REPORT_FILE}" @@ -168,25 +290,66 @@ function test::flushFdToCodeBlock() { eval " exec ${fdNumber}>&-; : >'${file}'; exec ${fdNumber}>'${file}';" } - +# ## test::flush +# +# Call this function to flush the standard and error outputs to the report file. +# They will be added as code blocks in the report file (one for the standard +# output, one for the standard error). +# +# ```bash +# test::flush +# ``` function test::flush() { - test::flushFdToCodeBlock 1 true - test::flushFdToCodeBlock 2 true + test_flushFdToCodeBlock 1 "Standard output" + test_flushFdToCodeBlock 2 "Error output" +} + +# ## test::flushStdout +# +# Call this function to flush the standard output to the report file. +# It will be added as a code block in the report file. +# +# - $1: blockTitle _as string_: +# (optional) Can be set using the variable `_OPTION_BLOCK_TITLE`. +# Add a 'title' to the code block (`**title**:` before the code block). +# (defaults to '' which will not add a title) +# +# ```bash +# test::flushStdout +# ``` +function test::flushStdout() { + test_flushFdToCodeBlock 1 "${1:-${_OPTION_BLOCK_TITLE:-}}" +} + +# ## test::flushStderr +# +# Call this function to flush the standard error to the report file. +# It will be added as a code block in the report file. +# +# - $1: blockTitle _as string_: +# (optional) Can be set using the variable `_OPTION_BLOCK_TITLE`. +# Add a 'title' to the code block (`**title**:` before the code block). +# (defaults to '' which will not add a title) +# +# ```bash +# test::flushStderr +# ``` +function test::flushStderr() { + test_flushFdToCodeBlock 2 "${1:-${_OPTION_BLOCK_TITLE:-}}" } # ## test::endTest # # Call this function after a test to write a test result section to the report file. -# This create a new H3 section in the report file with the given test description, -# the exit code, and the standard and error outputs (if any). -# # +# This create a new H3 section in the report file with the given test description, +# the exit code, and the standard and error outputs captured from the last flush (if any). # # - $1: **title** _as string_: # The title of the test. # - $2: **exit code** _as int_: # The exit code of the test. -# - $3: comment _as string_: +# - $@: comments _as string_: # (optional) Can be set using the variable `_OPTION_COMMENT`. # A text to explain what is being tested. # (defaults to "") @@ -197,23 +360,36 @@ function test::flush() { function test::endTest() { local testTitle="${1:-}" local exitCode="${2:-}" - local testDescription="${3:-${_OPTION_COMMENT:-}}" - - # write the test title - local reportSection="### ${testTitle:-test}" - - # write the test description if any - if [[ -n "${testDescription}" ]]; then - reportSection+=$'\n'$'\n'"${testDescription}" + local testDescription IFS=$'\n' + if [[ -n ${3:-} ]]; then + printf -v testDescription '%s\n\n' "${@:3}" + else + testDescription+="${_OPTION_COMMENT:-}"$'\n'$'\n' fi - # write the exit code - reportSection+=$'\n'$'\n'"Exit code: \`${exitCode}\`" + # shellcheck disable=SC2183 + # shellcheck disable=SC2016 + printf '### %s\n\n%sExit code: `%s`\n\n' "${testTitle:-test}" "${testDescription}" "${exitCode}" >>"${GLOBAL_TEST_REPORT_FILE}" - printf '%s\n\n' "${reportSection}" >>"${GLOBAL_TEST_REPORT_FILE}" + test_flushFdToCodeBlock 1 "Standard output" + test_flushFdToCodeBlock 2 "Error output" +} - test::flushFdToCodeBlock 1 true - test::flushFdToCodeBlock 2 true +# ## test::fail +# +# Call this function to log a message and exit with the status 142, which +# indicates to the self test command that the test failed and that we know the +# reason (it is a bad implementation of the test itself). +# +# - $@: **message** _as string_: +# The message to log. +# +# ```bash +# test::fail "This is a failure message with a clear reason." +# ``` +function test::fail() { + test::log "$@" + exit 142 } # Replaces the line numbers from an error log in the given file with XXX. diff --git a/libraries.d/main b/libraries.d/main index 41e8425..bb675e8 100644 --- a/libraries.d/main +++ b/libraries.d/main @@ -555,6 +555,9 @@ function main::runFunction() { profiler::enable "${VALET_CONFIG_COMMAND_PROFILING_FILE:-"${HOME}/valet-profiler-${BASHPID}-command.txt"}" fi + # reset IFS to ensure consistent behavior + local IFS=' '$'\t'$'\n' + # execute the function "${functionName}" "$@" diff --git a/tests.d/1005-lib-io/resources/dir/subdir/file1 b/tests.d/1005-lib-io/resources/dir/subdir/file1 deleted file mode 100644 index e69de29..0000000 diff --git a/tests.d/1005-lib-io/resources/search/file1 b/tests.d/1005-lib-io/resources/search/file1 deleted file mode 100644 index e69de29..0000000 diff --git a/tests.d/1005-lib-io/resources/search/subfolder1/file2 b/tests.d/1005-lib-io/resources/search/subfolder1/file2 deleted file mode 100644 index e69de29..0000000 diff --git a/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/file3 b/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/file3 deleted file mode 100644 index e69de29..0000000 diff --git a/tests.d/1011-lib-core/results.approved.md b/tests.d/1011-lib-core/results.approved.md deleted file mode 100644 index d5a3058..0000000 --- a/tests.d/1011-lib-core/results.approved.md +++ /dev/null @@ -1,4 +0,0 @@ -# Test suite 1011-lib-core - -## Test script 00.tests - diff --git a/tests.d/1012-lib-bash/00.tests.sh b/tests.d/1012-lib-bash/00.tests.sh deleted file mode 100644 index b7ce9b5..0000000 --- a/tests.d/1012-lib-bash/00.tests.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -function main() { - test::title "Testing lib-bash" - test::commentTest "This is a comment" - test::exec printf '%s' 'ergihezrghgeruh zefzfe' - - test::execExiting fuu -} - -function fuu() { - exit 2 -} - -main diff --git a/tests.d/1012-lib-bash/results.approved.md b/tests.d/1012-lib-bash/results.approved.md deleted file mode 100644 index d89ca91..0000000 --- a/tests.d/1012-lib-bash/results.approved.md +++ /dev/null @@ -1,28 +0,0 @@ -# Test suite 1012-lib-bash - -## Test script 00.tests - -### Testing lib-bash - -This is a comment - -Prompt: - -```bash -printf %s "ergihezrghgeruh zefzfe" -``` - -**Standard output**: - -```text -ergihezrghgeruh zefzfe -``` - -Prompt: - -```bash -fuu -``` - -Exited with code: `2` - diff --git a/tests.d/1013-lib-test/after-each-test b/tests.d/1013-lib-test/after-each-test deleted file mode 100644 index 7ea1fcc..0000000 --- a/tests.d/1013-lib-test/after-each-test +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -if [[ ${GLOBAL_TEST_SUITE_NAME:-} == "1013-lib-test" ]]; then - TESTING_HOOKS+="after-each-test"$'\n' - echo "→ " - echo "${TESTING_HOOKS}" - test::endTest "Testing the self test hooks" 0 "We can't check for after each test suites/tests hooks because they are executed after the test." -fi \ No newline at end of file diff --git a/tests.d/1013-lib-test/resources/text-to-read b/tests.d/1013-lib-test/resources/text-to-read deleted file mode 100644 index e69de29..0000000 diff --git a/tests.d/1013-lib-test/results.approved.md b/tests.d/1013-lib-test/results.approved.md deleted file mode 100644 index 39887a4..0000000 --- a/tests.d/1013-lib-test/results.approved.md +++ /dev/null @@ -1,21 +0,0 @@ -# Test suite 1013-lib-test - -## Test script 00.tests - -### Testing the self test hooks - -We can't check for after each test suites/tests hooks because they are executed after the test. - -Exit code: `0` - -**Standard output**: - -```text -→ -before-tests -before-each-test-suite -before-each-test -after-each-test - -``` - diff --git a/tests.d/0900-valet-cli/05.logging.sh b/tests.d/cli-logging/01.logging.sh similarity index 89% rename from tests.d/0900-valet-cli/05.logging.sh rename to tests.d/cli-logging/01.logging.sh index b5e1649..8ff75c1 100644 --- a/tests.d/0900-valet-cli/05.logging.sh +++ b/tests.d/cli-logging/01.logging.sh @@ -1,25 +1,22 @@ #!/usr/bin/env bash -builtin source ".before-test" - function testLogging() { - # testing log level - echo "→ VALET_LOG_LEVEL=success valet self mock1 logging-level" - export VALET_LOG_LEVEL="success" - ("${GLOBAL_VALET_HOME}/valet" self mock1 logging-level) - unset VALET_LOG_LEVEL - test::endTest "Testing log with success level" 0 + test::title "Passing logging level through an environment variable" + + test::exec printf '%s\n' 'coucou' 'hello 2nd' + + test::exec VALET_LOG_LEVEL=success "${GLOBAL_VALET_HOME}/valet" self mock1 logging-level echo "→ valet --log-level warning self mock1 logging-level" ("${GLOBAL_VALET_HOME}/valet" --log-level "warning" self mock1 logging-level) test::endTest "Testing log with warning level" 0 echo "→ valet -v self mock1 logging-level" - ("${GLOBAL_VALET_HOME}/valet" -v self mock1 logging-level) + (unset SECONDS; SECONDS=0; "${GLOBAL_VALET_HOME}/valet" -v self mock1 logging-level) test::endTest "Testing log with debug level" 0 echo "→ valet -w self mock1 logging-level" - ("${GLOBAL_VALET_HOME}/valet" -w self mock1 logging-level) + (unset SECONDS; SECONDS=0; "${GLOBAL_VALET_HOME}/valet" -w self mock1 logging-level) test::endTest "Testing log with trace level" 0 # testing the different log options @@ -98,10 +95,6 @@ function testFileLogging() { function main() { testLogging - testLog::printRawAndFile - testFileLogging } main - -builtin source ".after-test" \ No newline at end of file diff --git a/tests.d/cli-logging/results.approved.md b/tests.d/cli-logging/results.approved.md new file mode 100644 index 0000000..131879b --- /dev/null +++ b/tests.d/cli-logging/results.approved.md @@ -0,0 +1,34 @@ +# Test suite cli-logging + +## Test script 01.logging + +### Passing logging level through an environment variable + +Prompt: + +```bash +printf %s\\n coucou hello\ 2nd +``` + +**Standard output**: + +```text +coucou +hello 2nd +``` + +Prompt: + +```bash +VALET_LOG_LEVEL=success ${GLOBAL_VALET_HOME}/valet self mock1 logging-level +``` + +**Error output**: + +```text +TRACE This is an error trace message which is always displayed. +SUCCESS This is a success message. +WARNING This is a warning message. +With a second line. +``` + diff --git a/tests.d/0901-profiler/00.profiler.sh b/tests.d/cli-profiler/00.profiler.sh similarity index 90% rename from tests.d/0901-profiler/00.profiler.sh rename to tests.d/cli-profiler/00.profiler.sh index 709cda2..b2fdc03 100644 --- a/tests.d/0901-profiler/00.profiler.sh +++ b/tests.d/cli-profiler/00.profiler.sh @@ -3,7 +3,7 @@ # shellcheck source=../../libraries.d/lib-io source io -test::commentTest "The profiler is an excellent tool to debug your command. The following example shows what you would get when you enable it."$'\n\n'"Notice that the profiling file has been cleanup after the command execution to maximize readability." +test::comment "The profiler is an excellent tool to debug your command. The following example shows what you would get when you enable it."$'\n\n'"Notice that the profiling file has been cleanup after the command execution to maximize readability." function testProfiler() { # testing command profiling + startup diff --git a/tests.d/0901-profiler/results.approved.md b/tests.d/cli-profiler/results.approved.md similarity index 99% rename from tests.d/0901-profiler/results.approved.md rename to tests.d/cli-profiler/results.approved.md index 43949a6..f566cba 100644 --- a/tests.d/0901-profiler/results.approved.md +++ b/tests.d/cli-profiler/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 0901-profiler +# Test suite cli-profiler ## Test script 00.profiler diff --git a/tests.d/0900-valet-cli/.after-test b/tests.d/cli/.after-test similarity index 100% rename from tests.d/0900-valet-cli/.after-test rename to tests.d/cli/.after-test diff --git a/tests.d/0900-valet-cli/.before-test b/tests.d/cli/.before-test similarity index 100% rename from tests.d/0900-valet-cli/.before-test rename to tests.d/cli/.before-test diff --git a/tests.d/0900-valet-cli/01.command-help.sh b/tests.d/cli/01.command-help.sh similarity index 100% rename from tests.d/0900-valet-cli/01.command-help.sh rename to tests.d/cli/01.command-help.sh diff --git a/tests.d/0900-valet-cli/02.command-misc.sh b/tests.d/cli/02.command-misc.sh similarity index 100% rename from tests.d/0900-valet-cli/02.command-misc.sh rename to tests.d/cli/02.command-misc.sh diff --git a/tests.d/0900-valet-cli/03.event-handlers.sh b/tests.d/cli/03.event-handlers.sh similarity index 100% rename from tests.d/0900-valet-cli/03.event-handlers.sh rename to tests.d/cli/03.event-handlers.sh diff --git a/tests.d/0900-valet-cli/04.interactive-mode.sh b/tests.d/cli/04.interactive-mode.sh similarity index 100% rename from tests.d/0900-valet-cli/04.interactive-mode.sh rename to tests.d/cli/04.interactive-mode.sh diff --git a/tests.d/0900-valet-cli/06.misc.sh b/tests.d/cli/06.misc.sh similarity index 97% rename from tests.d/0900-valet-cli/06.misc.sh rename to tests.d/cli/06.misc.sh index 46a9870..5a4d6c7 100644 --- a/tests.d/0900-valet-cli/06.misc.sh +++ b/tests.d/cli/06.misc.sh @@ -38,7 +38,7 @@ function testCleaning() { } function testUserDirectory() { - # testing with a non exising user directory + # testing with a non existing user directory local previousUserDirectory="${VALET_USER_DIRECTORY:-}" io::createTempDirectory && export VALET_USER_DIRECTORY="${RETURNED_VALUE}/non-existing" diff --git a/tests.d/0900-valet-cli/08.submenu.sh b/tests.d/cli/08.submenu.sh similarity index 100% rename from tests.d/0900-valet-cli/08.submenu.sh rename to tests.d/cli/08.submenu.sh diff --git a/tests.d/0900-valet-cli/resources/file-to-read b/tests.d/cli/resources/file-to-read similarity index 100% rename from tests.d/0900-valet-cli/resources/file-to-read rename to tests.d/cli/resources/file-to-read diff --git a/tests.d/0900-valet-cli/results.approved.md b/tests.d/cli/results.approved.md similarity index 99% rename from tests.d/0900-valet-cli/results.approved.md rename to tests.d/cli/results.approved.md index 79a1591..715e66b 100644 --- a/tests.d/0900-valet-cli/results.approved.md +++ b/tests.d/cli/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 0900-valet-cli +# Test suite cli ## Test script 01.command-help diff --git a/tests.d/1006-lib-array/.fuzzy-filter-benchmark.sh b/tests.d/lib-array/.fuzzy-filter-benchmark.sh similarity index 100% rename from tests.d/1006-lib-array/.fuzzy-filter-benchmark.sh rename to tests.d/lib-array/.fuzzy-filter-benchmark.sh diff --git a/tests.d/1006-lib-array/.sort-benchmark.sh b/tests.d/lib-array/.sort-benchmark.sh similarity index 100% rename from tests.d/1006-lib-array/.sort-benchmark.sh rename to tests.d/lib-array/.sort-benchmark.sh diff --git a/tests.d/1006-lib-array/00.tests.sh b/tests.d/lib-array/00.tests.sh similarity index 100% rename from tests.d/1006-lib-array/00.tests.sh rename to tests.d/lib-array/00.tests.sh diff --git a/tests.d/1006-lib-array/results.approved.md b/tests.d/lib-array/results.approved.md similarity index 99% rename from tests.d/1006-lib-array/results.approved.md rename to tests.d/lib-array/results.approved.md index e803404..25ab125 100644 --- a/tests.d/1006-lib-array/results.approved.md +++ b/tests.d/lib-array/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1006-lib-array +# Test suite lib-array ## Test script 00.tests diff --git a/tests.d/1006-lib-array/sort-test-keys b/tests.d/lib-array/sort-test-keys similarity index 100% rename from tests.d/1006-lib-array/sort-test-keys rename to tests.d/lib-array/sort-test-keys diff --git a/tests.d/1006-lib-array/sort-test-values b/tests.d/lib-array/sort-test-values similarity index 100% rename from tests.d/1006-lib-array/sort-test-values rename to tests.d/lib-array/sort-test-values diff --git a/tests.d/1006-lib-array/words b/tests.d/lib-array/words similarity index 100% rename from tests.d/1006-lib-array/words rename to tests.d/lib-array/words diff --git a/tests.d/1011-lib-core/00.tests.sh b/tests.d/lib-bash/00.tests.sh similarity index 100% rename from tests.d/1011-lib-core/00.tests.sh rename to tests.d/lib-bash/00.tests.sh diff --git a/tests.d/lib-bash/results.approved.md b/tests.d/lib-bash/results.approved.md new file mode 100644 index 0000000..f78fb6e --- /dev/null +++ b/tests.d/lib-bash/results.approved.md @@ -0,0 +1,4 @@ +# Test suite lib-bash + +## Test script 00.tests + diff --git a/tests.d/1009-lib-benchmark/00.tests.sh b/tests.d/lib-benchmark/00.tests.sh similarity index 100% rename from tests.d/1009-lib-benchmark/00.tests.sh rename to tests.d/lib-benchmark/00.tests.sh diff --git a/tests.d/1009-lib-benchmark/results.approved.md b/tests.d/lib-benchmark/results.approved.md similarity index 96% rename from tests.d/1009-lib-benchmark/results.approved.md rename to tests.d/lib-benchmark/results.approved.md index f5958bc..4e37512 100644 --- a/tests.d/1009-lib-benchmark/results.approved.md +++ b/tests.d/lib-benchmark/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1009-lib-benchmark +# Test suite lib-benchmark ## Test script 00.tests diff --git a/tests.d/1013-lib-test/00.tests.sh b/tests.d/lib-core/00.tests.sh similarity index 98% rename from tests.d/1013-lib-test/00.tests.sh rename to tests.d/lib-core/00.tests.sh index bb06ce1..33a77c1 100644 --- a/tests.d/1013-lib-test/00.tests.sh +++ b/tests.d/lib-core/00.tests.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash - function main() { : } diff --git a/tests.d/lib-core/results.approved.md b/tests.d/lib-core/results.approved.md new file mode 100644 index 0000000..49d47f1 --- /dev/null +++ b/tests.d/lib-core/results.approved.md @@ -0,0 +1,4 @@ +# Test suite lib-core + +## Test script 00.tests + diff --git a/tests.d/1002-lib-curl/00.curl.sh b/tests.d/lib-curl/00.curl.sh similarity index 100% rename from tests.d/1002-lib-curl/00.curl.sh rename to tests.d/lib-curl/00.curl.sh diff --git a/tests.d/1002-lib-curl/results.approved.md b/tests.d/lib-curl/results.approved.md similarity index 99% rename from tests.d/1002-lib-curl/results.approved.md rename to tests.d/lib-curl/results.approved.md index 4ec783b..4c3ea97 100644 --- a/tests.d/1002-lib-curl/results.approved.md +++ b/tests.d/lib-curl/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1002-lib-curl +# Test suite lib-curl ## Test script 00.curl diff --git a/tests.d/1007-lib-interactive/00.tests.sh b/tests.d/lib-interactive/00.tests.sh similarity index 100% rename from tests.d/1007-lib-interactive/00.tests.sh rename to tests.d/lib-interactive/00.tests.sh diff --git a/tests.d/1007-lib-interactive/01.utilities.sh b/tests.d/lib-interactive/01.utilities.sh similarity index 100% rename from tests.d/1007-lib-interactive/01.utilities.sh rename to tests.d/lib-interactive/01.utilities.sh diff --git a/tests.d/1007-lib-interactive/results.approved.md b/tests.d/lib-interactive/results.approved.md similarity index 99% rename from tests.d/1007-lib-interactive/results.approved.md rename to tests.d/lib-interactive/results.approved.md index dbea71b..132793e 100644 --- a/tests.d/1007-lib-interactive/results.approved.md +++ b/tests.d/lib-interactive/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1007-lib-interactive +# Test suite lib-interactive ## Test script 00.tests diff --git a/tests.d/1005-lib-io/00.tests.sh b/tests.d/lib-io/00.tests.sh similarity index 89% rename from tests.d/1005-lib-io/00.tests.sh rename to tests.d/lib-io/00.tests.sh index b35ecac..0e392ee 100644 --- a/tests.d/1005-lib-io/00.tests.sh +++ b/tests.d/lib-io/00.tests.sh @@ -226,9 +226,10 @@ function test_io::head() { test::endTest "Testing io::head limited to 99 lines" 0 - echo "→ io::head 'resources/file-to-read' 10 true" - io::head 'resources/file-to-read' 10 true - echo "${RETURNED_VALUE}" + echo "→ io::head 'resources/file-to-read' 3 true" + io::head 'resources/file-to-read' 3 true + local IFS=$'\n' + echo "${RETURNED_ARRAY[*]}" test::endTest "Testing io::head to var" 0 } @@ -252,6 +253,30 @@ function test_io::captureOutput() { test::endTest "Testing io::captureOutput when command is failing" 0 } +function test_io::tail() { + echo "→ io::tail 'resources/file-to-read' 3" + io::tail 'resources/file-to-read' 3 + + test::endTest "Testing io::tail limited to 3 lines" 0 + + echo "→ io::tail 'resources/file-to-read' 0" + io::tail 'resources/file-to-read' 0 + + test::endTest "Testing io::tail limited to 0 lines" 0 + + echo "→ io::tail 'resources/file-to-read' 99" + io::tail 'resources/file-to-read' 99 + + test::endTest "Testing io::tail limited to 99 lines" 0 + + echo "→ io::tail 'resources/file-to-read' 3 true" + io::tail 'resources/file-to-read' 3 true + local IFS=$'\n' + echo "${RETURNED_ARRAY[*]}" + + test::endTest "Testing io::tail to var" 0 +} + function main() { test_io::toAbsolutePath @@ -268,6 +293,7 @@ function main() { test_io::convertFromWindowsPath test_io::head test_io::captureOutput + test_io::tail } main \ No newline at end of file diff --git a/tests.d/1005-lib-io/01.invoke.sh b/tests.d/lib-io/01.invoke.sh similarity index 96% rename from tests.d/1005-lib-io/01.invoke.sh rename to tests.d/lib-io/01.invoke.sh index 9196fb8..920a86e 100644 --- a/tests.d/1005-lib-io/01.invoke.sh +++ b/tests.d/lib-io/01.invoke.sh @@ -53,8 +53,7 @@ function test_io::invoke() { local -i exitCode echo "→ io::invoke fakeexec --error" - (io::invoke fakeexec --error 2> "${GLOBAL_TEST_TEMP_FILE}") && exitCode=0 || exitCode=$? - test::echoFileWithLineNumberSubstitution "${GLOBAL_TEST_TEMP_FILE}" 1>&2 + ( io::invoke fakeexec --error ) && exitCode=0 || exitCode=${PIPESTATUS[0]} test::endTest "Testing io::invoke, should fail" ${exitCode} echo "→ io::invoke fakeexec --option argument1 argument2" diff --git a/tests.d/1005-lib-io/02.listPaths.sh b/tests.d/lib-io/02.listPaths.sh similarity index 100% rename from tests.d/1005-lib-io/02.listPaths.sh rename to tests.d/lib-io/02.listPaths.sh diff --git a/tests.d/1005-lib-io/resources/file-to-read b/tests.d/lib-io/resources/file-to-read similarity index 100% rename from tests.d/1005-lib-io/resources/file-to-read rename to tests.d/lib-io/resources/file-to-read diff --git a/tests.d/1005-lib-io/resources/search/.hidden-file b/tests.d/lib-io/resources/search/.hidden-file similarity index 100% rename from tests.d/1005-lib-io/resources/search/.hidden-file rename to tests.d/lib-io/resources/search/.hidden-file diff --git a/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 b/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 similarity index 100% rename from tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 rename to tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 diff --git a/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/file13 b/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13 similarity index 100% rename from tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/file13 rename to tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13 diff --git a/tests.d/1005-lib-io/resources/search/.hidden-subfolder/file10 b/tests.d/lib-io/resources/search/.hidden-subfolder/file10 similarity index 100% rename from tests.d/1005-lib-io/resources/search/.hidden-subfolder/file10 rename to tests.d/lib-io/resources/search/.hidden-subfolder/file10 diff --git a/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 b/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 similarity index 100% rename from tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 rename to tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 diff --git a/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/file14 b/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14 similarity index 100% rename from tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/file14 rename to tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14 diff --git a/tests.d/1005-lib-io/resources/search/subfolder1/.hidden-file2 b/tests.d/lib-io/resources/search/subfolder1/.hidden-file2 similarity index 100% rename from tests.d/1005-lib-io/resources/search/subfolder1/.hidden-file2 rename to tests.d/lib-io/resources/search/subfolder1/.hidden-file2 diff --git a/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/.hidden-file3 b/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3 similarity index 100% rename from tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/.hidden-file3 rename to tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3 diff --git a/tests.d/1005-lib-io/results.approved.md b/tests.d/lib-io/results.approved.md similarity index 66% rename from tests.d/1005-lib-io/results.approved.md rename to tests.d/lib-io/results.approved.md index 24c4be3..45bd629 100644 --- a/tests.d/1005-lib-io/results.approved.md +++ b/tests.d/lib-io/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1005-lib-io +# Test suite lib-io ## Test script 00.tests @@ -10,31 +10,31 @@ Exit code: `0` ```text → io::toAbsolutePath ${PWD}/01.invoke.sh -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/01.invoke.sh +$GLOBAL_VALET_HOME/tests.d/lib-io/01.invoke.sh → io::toAbsolutePath . -$GLOBAL_VALET_HOME/tests.d/1005-lib-io +$GLOBAL_VALET_HOME/tests.d/lib-io → io::toAbsolutePath .. $GLOBAL_VALET_HOME/tests.d → io::toAbsolutePath 01.invoke.sh -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/01.invoke.sh +$GLOBAL_VALET_HOME/tests.d/lib-io/01.invoke.sh → io::toAbsolutePath ../1004-lib-system/00.tests.sh -$GLOBAL_VALET_HOME/tests.d/1004-lib-system/00.tests.sh +$GLOBAL_VALET_HOME/tests.d/lib-io/../1004-lib-system/00.tests.sh → io::toAbsolutePath resources -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources +$GLOBAL_VALET_HOME/tests.d/lib-io/resources → io::toAbsolutePath ./01.invoke.sh -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/01.invoke.sh +$GLOBAL_VALET_HOME/tests.d/lib-io/01.invoke.sh → io::toAbsolutePath ./resources -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources +$GLOBAL_VALET_HOME/tests.d/lib-io/resources → io::toAbsolutePath missing-file -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/missing-file +$GLOBAL_VALET_HOME/tests.d/lib-io/missing-file ``` ### Testing io::readFile limited to x chars @@ -92,19 +92,19 @@ Exit code: `0` ```text → io::createDirectoryIfNeeded 'resources/dir/subdir' -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/dir/subdir +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/dir/subdir → io::createDirectoryIfNeeded 'resources/dir/subdir/file1' Failed as expected because its a file → io::createDirectoryIfNeeded 'resources/gitignored/derp' -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/gitignored/derp +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/gitignored/derp Directory created successfully! ``` **Error output**: ```text -mkdir: cannot create directory ‘$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/dir/subdir/file1’: File exists -ERROR Failed to create the directory ⌜$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/dir/subdir/file1⌝. +mkdir: cannot create directory ‘$GLOBAL_VALET_HOME/tests.d/lib-io/resources/dir/subdir/file1’: File exists +ERROR Failed to create the directory ⌜$GLOBAL_VALET_HOME/tests.d/lib-io/resources/dir/subdir/file1⌝. ``` ### Testing io::createFilePathIfNeeded @@ -115,9 +115,9 @@ Exit code: `0` ```text → io::createFilePathIfNeeded 'resources/dir/subdir/file1' -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/dir/subdir/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/dir/subdir/file1 → io::createFilePathIfNeeded 'resources/gitignored/allo/file1' -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/gitignored/allo/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/gitignored/allo/file1 File created successfully! ``` @@ -228,11 +228,11 @@ Exit code: `0` ```text → io::createLink 'resources/gitignored/file' 'resources/gitignored/try/file2' true -ln: $GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/gitignored/file $GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/gitignored/try/file2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/gitignored/try +ln: $GLOBAL_VALET_HOME/tests.d/lib-io/resources/gitignored/file $GLOBAL_VALET_HOME/tests.d/lib-io/resources/gitignored/try/file2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/gitignored/try → io::createLink 'resources/gitignored/try' 'resources/gitignored/new' -ln: -s $GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/gitignored/try $GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/gitignored/new -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/gitignored +ln: -s $GLOBAL_VALET_HOME/tests.d/lib-io/resources/gitignored/try $GLOBAL_VALET_HOME/tests.d/lib-io/resources/gitignored/new +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/gitignored ``` ### Testing io::convertFromWindowsPath @@ -319,18 +319,10 @@ Exit code: `0` **Standard output**: ```text -→ io::head 'resources/file-to-read' 10 true +→ io::head 'resources/file-to-read' 3 true # Explore why veganism is kinder to animals, to people and to our planet's future. Source: - -## For the animals - -Preventing the exploitation of animals is not the only reason for becoming vegan, but for many it remains the key factor in their decision to go vegan and stay vegan. Having emotional attachments with animals may form part of that reason, while many believe that all sentient creatures have a right to life and freedom. Specifics aside, avoiding animal products is one of the most obvious ways you can take a stand against animal cruelty and animal exploitation everywhere. Read a detailed overview on why being vegan demonstrates true compassion for animals. - -## For your health - - ``` ### Testing io::captureOutput @@ -366,6 +358,77 @@ Exit code: `0` Failed as expected ``` +### Testing io::tail limited to 3 lines + +Exit code: `0` + +**Standard output**: + +```text +→ io::tail 'resources/file-to-read' 3 +## For people + +Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. +``` + +### Testing io::tail limited to 0 lines + +Exit code: `0` + +**Standard output**: + +```text +→ io::tail 'resources/file-to-read' 0 + +``` + +### Testing io::tail limited to 99 lines + +Exit code: `0` + +**Standard output**: + +```text +→ io::tail 'resources/file-to-read' 99 +# Explore why veganism is kinder to animals, to people and to our planet's future. + +Source: + +## For the animals + +Preventing the exploitation of animals is not the only reason for becoming vegan, but for many it remains the key factor in their decision to go vegan and stay vegan. Having emotional attachments with animals may form part of that reason, while many believe that all sentient creatures have a right to life and freedom. Specifics aside, avoiding animal products is one of the most obvious ways you can take a stand against animal cruelty and animal exploitation everywhere. Read a detailed overview on why being vegan demonstrates true compassion for animals. + +## For your health + +Well-planned vegan diets follow healthy eating guidelines, and contain all the nutrients that our bodies need. Both the British Dietetic Association and the American Academy of Nutrition and Dietetics recognise that they are suitable for every age and stage of life. Some research has linked that there are certain health benefits to vegan diets with lower blood pressure and cholesterol, and lower rates of heart disease, type 2 diabetes and some types of cancer. + +Going vegan is a great opportunity to learn more about nutrition and cooking, and improve your diet. Getting your nutrients from plant foods allows more room in your diet for health-promoting options like whole grains, fruit, nuts, seeds and vegetables, which are packed full of beneficial fibre, vitamins and minerals. + +## For the environment + +From recycling our household rubbish to cycling to work, we're all aware of ways to live a greener life. One of the most effective things an individual can do to lower their carbon footprint is to avoid all animal products. This goes way beyond the problem of cow flatulence and air pollution! +Why is meat and dairy so bad for the environment? + +The production of meat and other animal derived products places a heavy burden on the environment. The vast amount of grain feed required for meat production is a significant contributor to deforestation, habitat loss and species extinction. In Brazil alone, the equivalent of 5.6 million acres of land is used to grow soya beans for animals in Europe. This land contributes to developing world malnutrition by driving impoverished populations to grow cash crops for animal feed, rather than food for themselves. On the other hand, considerably lower quantities of crops and water are required to sustain a vegan diet, making the switch to veganism one of the easiest, most enjoyable and most effective ways to reduce our impact on the environment. For more on how veganism is the way forward for the environment, see our environment section. + +## For people + +Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. +``` + +### Testing io::tail to var + +Exit code: `0` + +**Standard output**: + +```text +→ io::tail 'resources/file-to-read' 3 true +## For people + +Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. +``` + ## Test script 01.invoke ### Testing io::invoke5, should return 1, input stream from string @@ -624,60 +687,60 @@ Exit code: `0` ```text → io::listPaths ${PWD}/resources/search -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 → io::listPaths ${PWD}/resources/search true -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/file2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/file3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/file2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3 → io::listPaths ${PWD}/resources/search false true -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-file -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-file +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 → io::listPaths ${PWD}/resources/search true true -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-file -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/file13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/file10 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/file14 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/.hidden-file2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/file2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/.hidden-file3 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/file3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-file +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/file10 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/.hidden-file2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/file2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3 fileNamedFile() { if [[ ${1##*/} =~ ^file[[:digit:]]+$ ]]; then return 0; else return 1; fi; } → io::listPaths ${PWD}/resources/search true true fileNamedFile -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/file13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/file10 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/file14 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/file2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/file3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/file10 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/file2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3 fileNamedFile() { if [[ ${1##*/} =~ ^file[[:digit:]]+$ ]]; then return 0; else return 1; fi; } → io::listPaths ${PWD}/resources/search true true folderNamedHidden -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-file -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/file13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/file10 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-file +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/file10 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 ``` ### Testing io::listFiles @@ -688,33 +751,33 @@ Exit code: `0` ```text → io::listFiles ${PWD}/resources/search -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 → io::listFiles ${PWD}/resources/search true -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/file2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/file3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/file2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3 → io::listFiles ${PWD}/resources/search true true -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-file -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/file13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/file10 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4/file14 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/.hidden-file2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/file2 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/.hidden-file3 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2/file3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-file +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/file10 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/.hidden-file2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/file2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3 fileNamedFile() { if [[ ${1##*/} =~ ^file[[:digit:]]+$ ]]; then return 0; else return 1; fi; } → io::listFiles ${PWD}/resources/search true true folderNamedHidden -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-file -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3/file13 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/file10 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/file1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-file +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/file10 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/file1 ``` ### Testing io::listDirectories @@ -725,24 +788,24 @@ Exit code: `0` ```text → io::listDirectories ${PWD}/resources/search -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 → io::listDirectories ${PWD}/resources/search true -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2 → io::listDirectories ${PWD}/resources/search true true -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1/subfolder2 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1/subfolder2 fileNamedFile() { if [[ ${1##*/} =~ ^file[[:digit:]]+$ ]]; then return 0; else return 1; fi; } → io::listDirectories ${PWD}/resources/search true true folderNamedHidden -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/.hidden3 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/.hidden-subfolder/subfolder4 -$GLOBAL_VALET_HOME/tests.d/1005-lib-io/resources/search/subfolder1 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4 +$GLOBAL_VALET_HOME/tests.d/lib-io/resources/search/subfolder1 ``` diff --git a/tests.d/1010-lib-log/00.tests.sh b/tests.d/lib-log/00.tests.sh similarity index 96% rename from tests.d/1010-lib-log/00.tests.sh rename to tests.d/lib-log/00.tests.sh index 291bb53..fd34711 100644 --- a/tests.d/1010-lib-log/00.tests.sh +++ b/tests.d/lib-log/00.tests.sh @@ -61,11 +61,9 @@ function test_log_log_one_of_each_level() { log::isDebugEnabled && echo 0 || echo 1 # fix stuff for printCallStack - unset LINENO FUNCNAME - export LINENO=0 - export FUNCNAME=(log::printCallStack log::error myCmd::subFunction myCmd::function) - export BASH_LINENO=(100 200 300) - export BASH_SOURCE=("" "core" "${PWD}/path/to/subFunction.sh" "${PWD}/path/to/function.sh") + _STACK_FUNCTION_NAMES=(log::printCallStack log::error myCmd::subFunction myCmd::function) + _STACK_SOURCE_FILES=("" "core" "${PWD}/path/to/subFunction.sh" "${PWD}/path/to/function.sh") + _STACK_LINE_NUMBERS=(100 200 300) echo echo "→ log::error 'This is an error message.'" diff --git a/tests.d/1010-lib-log/file-to-read b/tests.d/lib-log/file-to-read similarity index 100% rename from tests.d/1010-lib-log/file-to-read rename to tests.d/lib-log/file-to-read diff --git a/tests.d/1010-lib-log/results.approved.md b/tests.d/lib-log/results.approved.md similarity index 95% rename from tests.d/1010-lib-log/results.approved.md rename to tests.d/lib-log/results.approved.md index 8a80a86..4226af4 100644 --- a/tests.d/1010-lib-log/results.approved.md +++ b/tests.d/lib-log/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1010-lib-log +# Test suite lib-log ## Test script 00.tests @@ -32,19 +32,19 @@ ERROR This is an error message. ├─ in log::printCallS │ tack() at tests.d/ - │ 1010-lib-log/00.te - │ sts.sh:72 + │ lib-log/00.tests.s + │ h:72 ├─ in log::error() at - │ tests.d/1010-lib-l - │ og/00.tests.sh:17 + │ tests.d/lib-log/00 + │ .tests.sh:17 ├─ in myCmd::subFunct - │ ion() at tests.d/1 - │ 010-lib-log/00.tes - │ ts.sh:169 + │ ion() at tests.d/l + │ ib-log/00.tests.sh + │ :169 └─ in myCmd::function - () at tests.d/1010 - -lib-log/00.tests. - sh:175 + () at tests.d/lib- + log/00.tests.sh:17 + 5 → log::warning 'This is a warning message.' WARNING This is a warning @@ -93,19 +93,19 @@ ERROR This is an error message. ├─ in log::printCallS │ tack() at tests.d/ - │ 1010-lib-log/00.te - │ sts.sh:72 + │ lib-log/00.tests.s + │ h:72 ├─ in log::error() at - │ tests.d/1010-lib-l - │ og/00.tests.sh:23 + │ tests.d/lib-log/00 + │ .tests.sh:23 ├─ in myCmd::subFunct - │ ion() at tests.d/1 - │ 010-lib-log/00.tes - │ ts.sh:169 + │ ion() at tests.d/l + │ ib-log/00.tests.sh + │ :169 └─ in myCmd::function - () at tests.d/1010 - -lib-log/00.tests. - sh:175 + () at tests.d/lib- + log/00.tests.sh:17 + 5 → log::warning 'This is a warning message.' WARNING This is a warning diff --git a/tests.d/1001-lib-main/01.sort-commands.sh b/tests.d/lib-main/01.sort-commands.sh similarity index 100% rename from tests.d/1001-lib-main/01.sort-commands.sh rename to tests.d/lib-main/01.sort-commands.sh diff --git a/tests.d/1001-lib-main/02.arguments-parser.sh b/tests.d/lib-main/02.arguments-parser.sh similarity index 100% rename from tests.d/1001-lib-main/02.arguments-parser.sh rename to tests.d/lib-main/02.arguments-parser.sh diff --git a/tests.d/1001-lib-main/99.tests.sh b/tests.d/lib-main/99.tests.sh similarity index 100% rename from tests.d/1001-lib-main/99.tests.sh rename to tests.d/lib-main/99.tests.sh diff --git a/tests.d/1001-lib-main/results.approved.md b/tests.d/lib-main/results.approved.md similarity index 99% rename from tests.d/1001-lib-main/results.approved.md rename to tests.d/lib-main/results.approved.md index 8ceccac..2232cad 100644 --- a/tests.d/1001-lib-main/results.approved.md +++ b/tests.d/lib-main/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1001-lib-main +# Test suite lib-main ## Test script 01.sort-commands diff --git a/tests.d/1008-lib-prompt/00.tests.sh b/tests.d/lib-prompt/00.tests.sh similarity index 100% rename from tests.d/1008-lib-prompt/00.tests.sh rename to tests.d/lib-prompt/00.tests.sh diff --git a/tests.d/1008-lib-prompt/results.approved.md b/tests.d/lib-prompt/results.approved.md similarity index 99% rename from tests.d/1008-lib-prompt/results.approved.md rename to tests.d/lib-prompt/results.approved.md index e9a442d..0efe0a5 100644 --- a/tests.d/1008-lib-prompt/results.approved.md +++ b/tests.d/lib-prompt/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1008-lib-prompt +# Test suite lib-prompt ## Test script 00.tests diff --git a/tests.d/1003-lib-string/00.tests.sh b/tests.d/lib-string/00.tests.sh similarity index 100% rename from tests.d/1003-lib-string/00.tests.sh rename to tests.d/lib-string/00.tests.sh diff --git a/tests.d/1003-lib-string/results.approved.md b/tests.d/lib-string/results.approved.md similarity index 99% rename from tests.d/1003-lib-string/results.approved.md rename to tests.d/lib-string/results.approved.md index a6f7fad..43d424f 100644 --- a/tests.d/1003-lib-string/results.approved.md +++ b/tests.d/lib-string/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1003-lib-string +# Test suite lib-string ## Test script 00.tests diff --git a/tests.d/1004-lib-system/00.tests.sh b/tests.d/lib-system/00.tests.sh similarity index 100% rename from tests.d/1004-lib-system/00.tests.sh rename to tests.d/lib-system/00.tests.sh diff --git a/tests.d/1004-lib-system/results.approved.md b/tests.d/lib-system/results.approved.md similarity index 99% rename from tests.d/1004-lib-system/results.approved.md rename to tests.d/lib-system/results.approved.md index 2991356..af653c9 100644 --- a/tests.d/1004-lib-system/results.approved.md +++ b/tests.d/lib-system/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1004-lib-system +# Test suite lib-system ## Test script 00.tests diff --git a/tests.d/lib-test/00.tests.sh b/tests.d/lib-test/00.tests.sh new file mode 100644 index 0000000..cc6a3cf --- /dev/null +++ b/tests.d/lib-test/00.tests.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +# 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::comment "You can insert comments that will appear as a paragraph in the test report." \ + "Everything written to the standard or error output (file descriptor 1 and 2 respectively) is captured and can then be flushed to the test report (usually as a code block)." \ + 'You can use the `test::flush` function to flush both captured outputs.' + + echo "This was written to the standard output using: echo '...'" + echo "This was written to the error output using: echo '...' 1>&2" 1>&2 + test::flush + + + test::title "🚽 Testing the more flushing functions" + test::comment 'You can flush a specific file descriptor using the `test::flushStdout` or `test::flushStderr` function.' + echo "This was written to the standard output using: echo '...'" + echo "Then flushed with test::flushStdout" + test::flushStdout + echo "This was written to the error output using: echo '...' 1>&2" 1>&2 + echo "Then flushed with test::flushStderr" 1>&2 + test::flushStderr "Optional title for the code block:" + + + # 🧫 Testing using test::endTest + functionToTest "I am testing functionToTest." "This is supposed to be in the error output" 0 + functionToTest "Second test." "Second test." 2 || echo "Failed as expected because functionToTest returned $?." + (functionThatExit "Third test." "Third test." 3) || echo "Failed as expected because functionToTest returned ${PIPESTATUS[0]}." + test::endTest "🧫 Testing using test::endTest" 42 'One way to test your commands is to simply call them, let them write their output to the standard or error (logs) file descriptors as they normally do.' \ + 'An important thing to keep in mind is that shell options are set to exit on error, and exiting during a test is considered a failure.' \ + 'You can use the `commandThatFails || echo "Failed as expected."` pattern to handle expected failures (unexpected failure are supposed to crash your tests anyway).' \ + 'For commands that directly call `exit`, you must run them in a subshell to avoid the test script to exit as well: `(myCommandThatExit) || || echo "Failed as expected."`.' + + + + test::title "🧪 Testing any command with test::exec" + test::comment 'Another approach is to use `test::exec` to run any command.' \ + 'The command will be executed and its output will be captured then automatically flushed to the test report.' \ + 'This convenient function also logs the command that was executed, handles errors and output the exit code if it is not zero.' \ + '> However, it is not adapted to handle commands that `exit`, see the next test on `test::exit` for that.' + test::exec functionToTest "I am testing functionToTest." "This is supposed to be in the error output" 0 + test::comment 'In this second test, we expect the command to fail and return the exit code 2.' + test::exec functionToTest "Second test." "Second test." 2 + + + test::title "👋 Testing an exiting command with test::exit" + test::comment 'The `test::exit` function is a variant of `test::exec` that is adapted to handle commands that `exit`.' \ + 'It will run the command in a subshell and output the same format as `test::exec`.' + test::exit functionThatExit "I am testing functionThatExit." "This is supposed to be in the error output" 3 + + + test::title "🔬 Testing a function with test::func" + test::comment 'The `test::func` function is a variant of `test::exec` that is adapted to handle functions developed using the coding style of Valet.' \ + 'Meaning functions that usually return values in a variables named `RETURNED_VALUE...` (or `RETURNED_ARRAY...`) and that can optionally print results to the standard output and push logs to the error output.' \ + 'It function will be executed and its output will be added the report, including any declare `RETURNED_*` variable.' + + + test::title "🙈 Display reporting RETURNED variables" + test::comment 'You can manually report the content of the `RETURNED_*` variables using the `test::revealReturnedVars` function.' \ + 'The function `test::resetReturnedVars` can also be used to reset the content of the `RETURNED_*` variables.' + RETURNED_VALUE="This will be overridden". + test::resetReturnedVars + test::revealReturnedVars + + + test::title "👁️ Display the value of any variable" + test::comment 'You can manually report the definition of any variable using the `test::revealVars` function.' + GLOBAL_VAR1="This is the value of a global string" + GLOBAL_VAR2=("This" "is" "the" "value" "of" "a" "global" "array.") + echo "> test::revealVars GLOBAL_VAR1 GLOBAL_VAR2" + test::flushStdout "Command executed in the test script:" + test::revealVars GLOBAL_VAR1 GLOBAL_VAR2 +} + +function functionToTest() { + echo "${1}" + echo "${2}" 1>&2 + return "${3}" +} + +function functionThatExit() { + echo "${1}" + echo "${2}" 1>&2 + exit "${3}" +} + +# shellcheck disable=SC2034 +function typicalValetFunction() { + echo "OUTPUT: ${1}" + echo "LOG: ${2}" 1>&2 + RETURNED_VALUE="This is the returned value." + RETURNED_ARRAY=("This" "is" "the" "returned" "array.") + RETURNED_ASSOCIATIVE_ARRAY=([key1]="This" [key2]="is" [key3]="the" [key4]="returned" [key5]="associative" [key6]="array.") +} + +main diff --git a/tests.d/lib-test/after-each-test b/tests.d/lib-test/after-each-test new file mode 100644 index 0000000..6fdfd30 --- /dev/null +++ b/tests.d/lib-test/after-each-test @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +if [[ ${GLOBAL_TEST_SUITE_NAME:-} == "lib-test" ]]; then + TESTING_HOOKS+="after-each-test"$'\n' + echo "${TESTING_HOOKS}" + test::endTest "🪝 Testing the self test hooks" 0 "This shows which hook have been executed. This test is written in the 'after-each-test' script. We can't see the 'after-each-test-suites' and 'after-tests' because they are executed after the test script exits, thus we can't output their results in this report." +fi \ No newline at end of file diff --git a/tests.d/1013-lib-test/before-each-test b/tests.d/lib-test/before-each-test similarity index 100% rename from tests.d/1013-lib-test/before-each-test rename to tests.d/lib-test/before-each-test diff --git a/tests.d/lib-test/results.approved.md b/tests.d/lib-test/results.approved.md new file mode 100644 index 0000000..ee3f417 --- /dev/null +++ b/tests.d/lib-test/results.approved.md @@ -0,0 +1,188 @@ +# Test suite lib-test + +## Test script 00.tests + +### #️⃣ Testing the basic functions of lib-test + +You can insert comments that will appear as a paragraph in the test report. + +Everything written to the standard or error output (file descriptor 1 and 2 respectively) is captured and can then be flushed to the test report (usually as a code block). + +You can use the `test::flush` function to flush both captured outputs. + +**Standard output**: + +```text +This was written to the standard output using: echo '...' +``` + +**Error output**: + +```text +This was written to the error output using: echo '...' 1>&2 +``` + +### 🚽 Testing the more flushing functions + +You can flush a specific file descriptor using the `test::flushStdout` or `test::flushStderr` function. + +```text +This was written to the standard output using: echo '...' +Then flushed with test::flushStdout +``` + +**Optional title for the code block:**: + +```text +This was written to the error output using: echo '...' 1>&2 +Then flushed with test::flushStderr +``` + +### 🧫 Testing using test::endTest + +One way to test your commands is to simply call them, let them write their output to the standard or error (logs) file descriptors as they normally do. + +An important thing to keep in mind is that shell options are set to exit on error, and exiting during a test is considered a failure. + +You can use the `commandThatFails || echo "Failed as expected."` pattern to handle expected failures (unexpected failure are supposed to crash your tests anyway). + +For commands that directly call `exit`, you must run them in a subshell to avoid the test script to exit as well: `(myCommandThatExit) || || echo "Failed as expected."`. + +Exit code: `42` + +**Standard output**: + +```text +I am testing functionToTest. +Second test. +Failed as expected because functionToTest returned 2. +Third test. +Failed as expected because functionToTest returned 3. +``` + +**Error output**: + +```text +This is supposed to be in the error output +Second test. +Third test. +``` + +### 🧪 Testing any command with test::exec + +Another approach is to use `test::exec` to run any command. + +The command will be executed and its output will be captured then automatically flushed to the test report. + +This convenient function also logs the command that was executed, handles errors and output the exit code if it is not zero. + +> However, it is not adapted to handle commands that `exit`, see the next test on `test::exit` for that. + +Prompt: + +```bash +functionToTest I\ am\ testing\ functionToTest. This\ is\ supposed\ to\ be\ in\ the\ error\ output 0 +``` + +**Standard output**: + +```text +I am testing functionToTest. +``` + +**Error output**: + +```text +This is supposed to be in the error output +``` + +In this second test, we expect the command to fail and return the exit code 2. + +Prompt: + +```bash +functionToTest Second\ test. Second\ test. 2 +``` + +**Standard output**: + +```text +Second test. +``` + +**Error output**: + +```text +Second test. +``` + +### 👋 Testing an exiting command with test::exit + +The `test::exit` function is a variant of `test::exec` that is adapted to handle commands that `exit`. + +It will run the command in a subshell and output the same format as `test::exec`. + +Prompt: + +```bash +functionThatExit I\ am\ testing\ functionThatExit. This\ is\ supposed\ to\ be\ in\ the\ error\ output 3 +``` + +Exited with code: `3` + +**Standard output**: + +```text +I am testing functionThatExit. +``` + +**Error output**: + +```text +This is supposed to be in the error output +``` + +### 🔬 Testing a function with test::func + +The `test::func` function is a variant of `test::exec` that is adapted to handle functions developed using the coding style of Valet. + +Meaning functions that usually return values in a variables named `RETURNED_VALUE...` (or `RETURNED_ARRAY...`) and that can optionally print results to the standard output and push logs to the error output. + +It function will be executed and its output will be added the report, including any declare `RETURNED_*` variable. + +### 🙈 Display reporting RETURNED variables + +You can manually report the content of the `RETURNED_*` variables using the `test::revealReturnedVars` function. + +The function `test::resetReturnedVars` can also be used to reset the content of the `RETURNED_*` variables. + +### 👁️ Display the value of any variable + +You can manually report the definition of any variable using the `test::revealVars` function. + +**Command executed in the test script:**: + +```text +> test::revealVars GLOBAL_VAR1 GLOBAL_VAR2 +``` + +```text +GLOBAL_VAR1="This is the value of a global string" +GLOBAL_VAR2=([0]="This" [1]="is" [2]="the" [3]="value" [4]="of" [5]="a" [6]="global" [7]="array.") + +``` + +### 🪝 Testing the self test hooks + +This shows which hook have been executed. This test is written in the 'after-each-test' script. We can't see the 'after-each-test-suites' and 'after-tests' because they are executed after the test script exits, thus we can't output their results in this report. + +Exit code: `0` + +**Standard output**: + +```text +before-tests +after-each-test + +``` + diff --git a/tests.d/1109-self-add-x/01.self-add-x.sh b/tests.d/self-add-x/01.self-add-x.sh similarity index 100% rename from tests.d/1109-self-add-x/01.self-add-x.sh rename to tests.d/self-add-x/01.self-add-x.sh diff --git a/tests.d/1109-self-add-x/results.approved.md b/tests.d/self-add-x/results.approved.md similarity index 73% rename from tests.d/1109-self-add-x/results.approved.md rename to tests.d/self-add-x/results.approved.md index 49bf0d9..007581e 100644 --- a/tests.d/1109-self-add-x/results.approved.md +++ b/tests.d/self-add-x/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1109-self-add-x +# Test suite self-add-x ## Test script 01.self-add-x @@ -10,7 +10,7 @@ Exit code: `0` ```text → selfAddCommand 'new cool command' -prompt: It does not look like the current directory ⌜$GLOBAL_VALET_HOME/tests.d/1109-self-add-x/resources/gitignored⌝ is a valet extension, do you want to proceed anyway? +prompt: It does not look like the current directory ⌜$GLOBAL_VALET_HOME/tests.d/self-add-x/resources/gitignored⌝ is a valet extension, do you want to proceed anyway? → selfAddCommand 'new cool command' prompt: Do you want to override the existing command file? @@ -75,9 +75,9 @@ function newCoolCommand() { ```text WARNING The current directory is not under the valet user directory ⌜/nop/.valet.d⌝. -SUCCESS The command ⌜new cool command⌝ has been created with the file ⌜$GLOBAL_VALET_HOME/tests.d/1109-self-add-x/resources/gitignored/commands.d/new-cool-command.sh⌝. -WARNING The command file ⌜$GLOBAL_VALET_HOME/tests.d/1109-self-add-x/resources/gitignored/commands.d/new-cool-command.sh⌝ already exists. -SUCCESS The command ⌜new cool command⌝ has been created with the file ⌜$GLOBAL_VALET_HOME/tests.d/1109-self-add-x/resources/gitignored/commands.d/new-cool-command.sh⌝. +SUCCESS The command ⌜new cool command⌝ has been created with the file ⌜$GLOBAL_VALET_HOME/tests.d/self-add-x/resources/gitignored/commands.d/new-cool-command.sh⌝. +WARNING The command file ⌜$GLOBAL_VALET_HOME/tests.d/self-add-x/resources/gitignored/commands.d/new-cool-command.sh⌝ already exists. +SUCCESS The command ⌜new cool command⌝ has been created with the file ⌜$GLOBAL_VALET_HOME/tests.d/self-add-x/resources/gitignored/commands.d/new-cool-command.sh⌝. ``` ### Testing selfAddLibrary @@ -88,7 +88,7 @@ Exit code: `0` ```text → selfAddLibrary 'new-cool-lib' -prompt: It does not look like the current directory ⌜$GLOBAL_VALET_HOME/tests.d/1109-self-add-x/resources/gitignored⌝ is a valet extension, do you want to proceed anyway? +prompt: It does not look like the current directory ⌜$GLOBAL_VALET_HOME/tests.d/self-add-x/resources/gitignored⌝ is a valet extension, do you want to proceed anyway? → selfAddLibrary 'new-cool-lib' prompt: Do you want to override the existing library file? @@ -100,8 +100,8 @@ prompt: Do you want to override the existing library file? ```text WARNING The current directory is not under the valet user directory ⌜/nop/.valet.d⌝. -SUCCESS The library ⌜new-cool-lib⌝ has been created with the file ⌜$GLOBAL_VALET_HOME/tests.d/1109-self-add-x/resources/gitignored/libraries.d/lib-new-cool-lib⌝. -WARNING The library file ⌜$GLOBAL_VALET_HOME/tests.d/1109-self-add-x/resources/gitignored/libraries.d/lib-new-cool-lib⌝ already exists. -SUCCESS The library ⌜new-cool-lib⌝ has been created with the file ⌜$GLOBAL_VALET_HOME/tests.d/1109-self-add-x/resources/gitignored/libraries.d/lib-new-cool-lib⌝. +SUCCESS The library ⌜new-cool-lib⌝ has been created with the file ⌜$GLOBAL_VALET_HOME/tests.d/self-add-x/resources/gitignored/libraries.d/lib-new-cool-lib⌝. +WARNING The library file ⌜$GLOBAL_VALET_HOME/tests.d/self-add-x/resources/gitignored/libraries.d/lib-new-cool-lib⌝ already exists. +SUCCESS The library ⌜new-cool-lib⌝ has been created with the file ⌜$GLOBAL_VALET_HOME/tests.d/self-add-x/resources/gitignored/libraries.d/lib-new-cool-lib⌝. ``` diff --git a/tests.d/1101-self-build-utils/00.self-build-utils.sh b/tests.d/self-build-utils/00.self-build-utils.sh similarity index 100% rename from tests.d/1101-self-build-utils/00.self-build-utils.sh rename to tests.d/self-build-utils/00.self-build-utils.sh diff --git a/tests.d/1101-self-build-utils/resources/extract-command-yamls-test-file b/tests.d/self-build-utils/resources/extract-command-yamls-test-file similarity index 100% rename from tests.d/1101-self-build-utils/resources/extract-command-yamls-test-file rename to tests.d/self-build-utils/resources/extract-command-yamls-test-file diff --git a/tests.d/1101-self-build-utils/results.approved.md b/tests.d/self-build-utils/results.approved.md similarity index 99% rename from tests.d/1101-self-build-utils/results.approved.md rename to tests.d/self-build-utils/results.approved.md index 0c17147..69c7426 100644 --- a/tests.d/1101-self-build-utils/results.approved.md +++ b/tests.d/self-build-utils/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1101-self-build-utils +# Test suite self-build-utils ## Test script 00.self-build-utils diff --git a/tests.d/1102-self-build/01.self-build.sh b/tests.d/self-build/01.self-build.sh similarity index 100% rename from tests.d/1102-self-build/01.self-build.sh rename to tests.d/self-build/01.self-build.sh diff --git a/tests.d/1102-self-build/results.approved.md b/tests.d/self-build/results.approved.md similarity index 99% rename from tests.d/1102-self-build/results.approved.md rename to tests.d/self-build/results.approved.md index 6533873..efbd64c 100644 --- a/tests.d/1102-self-build/results.approved.md +++ b/tests.d/self-build/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1102-self-build +# Test suite self-build ## Test script 01.self-build diff --git a/tests.d/1100-self-config/01.self-config.sh b/tests.d/self-config/01.self-config.sh similarity index 100% rename from tests.d/1100-self-config/01.self-config.sh rename to tests.d/self-config/01.self-config.sh diff --git a/tests.d/1100-self-config/results.approved.md b/tests.d/self-config/results.approved.md similarity index 99% rename from tests.d/1100-self-config/results.approved.md rename to tests.d/self-config/results.approved.md index 916b5a8..ceb9bcd 100644 --- a/tests.d/1100-self-config/results.approved.md +++ b/tests.d/self-config/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1100-self-config +# Test suite self-config ## Test script 01.self-config diff --git a/tests.d/1107-self-document/01.self-document.sh b/tests.d/self-document/01.self-document.sh similarity index 100% rename from tests.d/1107-self-document/01.self-document.sh rename to tests.d/self-document/01.self-document.sh diff --git a/tests.d/1107-self-document/results.approved.md b/tests.d/self-document/results.approved.md similarity index 98% rename from tests.d/1107-self-document/results.approved.md rename to tests.d/self-document/results.approved.md index 1841b60..40ee31e 100644 --- a/tests.d/1107-self-document/results.approved.md +++ b/tests.d/self-document/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1107-self-document +# Test suite self-document ## Test script 01.self-document @@ -142,7 +142,7 @@ function ansi-codes::*() { :; } ```text INFO Generating documentation for the core functions only. -INFO Found 148 functions with documentation. +INFO Found 153 functions with documentation. INFO The documentation has been generated in ⌜/tmp/valet.d/d1-2/lib-valet.md⌝. INFO The prototype script has been generated in ⌜/tmp/valet.d/d1-2/lib-valet⌝. INFO The vscode snippets have been generated in ⌜/tmp/valet.d/d1-2/valet.code-snippets⌝. diff --git a/tests.d/1105-self-export/01.self-export.sh b/tests.d/self-export/01.self-export.sh similarity index 100% rename from tests.d/1105-self-export/01.self-export.sh rename to tests.d/self-export/01.self-export.sh diff --git a/tests.d/1105-self-export/results.approved.md b/tests.d/self-export/results.approved.md similarity index 89% rename from tests.d/1105-self-export/results.approved.md rename to tests.d/self-export/results.approved.md index 8579cff..e82a281 100644 --- a/tests.d/1105-self-export/results.approved.md +++ b/tests.d/self-export/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1105-self-export +# Test suite self-export ## Test script 01.self-export diff --git a/tests.d/1106-self-install/docker-valet-test/Dockerfile b/tests.d/self-install/docker-valet-test/Dockerfile similarity index 100% rename from tests.d/1106-self-install/docker-valet-test/Dockerfile rename to tests.d/self-install/docker-valet-test/Dockerfile diff --git a/tests.d/1106-self-install/results.approved.md b/tests.d/self-install/results.approved.md similarity index 100% rename from tests.d/1106-self-install/results.approved.md rename to tests.d/self-install/results.approved.md diff --git a/tests.d/1106-self-install/test b/tests.d/self-install/test similarity index 100% rename from tests.d/1106-self-install/test rename to tests.d/self-install/test diff --git a/tests.d/1103-self-release/01.self-release.sh b/tests.d/self-release/01.self-release.sh similarity index 100% rename from tests.d/1103-self-release/01.self-release.sh rename to tests.d/self-release/01.self-release.sh diff --git a/tests.d/1103-self-release/results.approved.md b/tests.d/self-release/results.approved.md similarity index 97% rename from tests.d/1103-self-release/results.approved.md rename to tests.d/self-release/results.approved.md index f7a18f1..6f983ff 100644 --- a/tests.d/1103-self-release/results.approved.md +++ b/tests.d/self-release/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1103-self-release +# Test suite self-release ## Test script 01.self-release @@ -202,6 +202,7 @@ DEBUG Found function: ⌜io::createFilePathIfNeeded⌝ DEBUG Found function: ⌜io::sleep⌝ DEBUG Found function: ⌜io::cat⌝ DEBUG Found function: ⌜io::head⌝ +DEBUG Found function: ⌜io::tail⌝ DEBUG Found function: ⌜io::readStdIn⌝ DEBUG Found function: ⌜io::countArgs⌝ DEBUG Found function: ⌜io::listPaths⌝ @@ -245,13 +246,17 @@ DEBUG Found function: ⌜system::addToPath⌝ DEBUG Found function: ⌜system::windowsSetEnvVar⌝ DEBUG Found function: ⌜system::windowsGetEnvVar⌝ DEBUG Found function: ⌜system::windowsAddToPath⌝ +DEBUG Found function: ⌜test::log⌝ DEBUG Found function: ⌜test::title⌝ DEBUG Found function: ⌜test::commentTest⌝ DEBUG Found function: ⌜test::exec⌝ DEBUG Found function: ⌜test::execExiting⌝ DEBUG Found function: ⌜test::flushFdToCodeBlock⌝ +DEBUG Found function: ⌜test::flush⌝ +DEBUG Found function: ⌜test::flushStdout⌝ +DEBUG Found function: ⌜test::flushStderr⌝ DEBUG Found function: ⌜test::endTest⌝ -INFO Found 148 functions with documentation. +INFO Found 153 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⌝. ▶ called io::writeToFile $GLOBAL_VALET_HOME/extras/lib-valet @@ -259,7 +264,7 @@ INFO The documentation has been generated in ⌜$GLOBAL_VALET_HOME/extras/li INFO The prototype script has been generated in ⌜$GLOBAL_VALET_HOME/extras/lib-valet⌝. ▶ called io::writeToFile $GLOBAL_VALET_HOME/extras/valet.code-snippets INFO The vscode snippets have been generated in ⌜$GLOBAL_VALET_HOME/extras/valet.code-snippets⌝. -INFO Writing the 148 functions documentation to the core libraries docs. +INFO Writing the 153 functions documentation to the core libraries docs. ▶ called io::invoke rm -f $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/array.md ▶ called io::invoke rm -f $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/codes.md ▶ called io::invoke rm -f $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/core.md @@ -465,6 +470,8 @@ INFO Writing the 148 functions documentation to the core libraries docs. ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/io.md ▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/io.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/io.md +▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/io.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/io.md ▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/log.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/log.md ▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/log.md @@ -573,6 +580,14 @@ INFO Writing the 148 functions documentation to the core libraries docs. ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md ▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md ▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md +▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md +▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md +▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md +▶ called io::writeToFileFromRef $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.md +▶ called io::writeToFile $GLOBAL_VALET_HOME/docs/content/docs/300.libraries/test.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/tests.d/1104-self-setup/00.self-setup.sh b/tests.d/self-setup/00.self-setup.sh similarity index 100% rename from tests.d/1104-self-setup/00.self-setup.sh rename to tests.d/self-setup/00.self-setup.sh diff --git a/tests.d/1104-self-setup/results.approved.md b/tests.d/self-setup/results.approved.md similarity index 99% rename from tests.d/1104-self-setup/results.approved.md rename to tests.d/self-setup/results.approved.md index f99f7d2..a0993f9 100644 --- a/tests.d/1104-self-setup/results.approved.md +++ b/tests.d/self-setup/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1104-self-setup +# Test suite self-setup ## Test script 00.self-setup diff --git a/tests.d/1108-self-uninstall/01.self-uninstall.sh b/tests.d/self-uninstall/01.self-uninstall.sh similarity index 100% rename from tests.d/1108-self-uninstall/01.self-uninstall.sh rename to tests.d/self-uninstall/01.self-uninstall.sh diff --git a/tests.d/1108-self-uninstall/results.approved.md b/tests.d/self-uninstall/results.approved.md similarity index 90% rename from tests.d/1108-self-uninstall/results.approved.md rename to tests.d/self-uninstall/results.approved.md index b1f83b3..f0c871a 100644 --- a/tests.d/1108-self-uninstall/results.approved.md +++ b/tests.d/self-uninstall/results.approved.md @@ -1,4 +1,4 @@ -# Test suite 1108-self-uninstall +# Test suite self-uninstall ## Test script 01.self-uninstall diff --git a/valet b/valet index ce3102d..4faf52f 100644 --- a/valet +++ b/valet @@ -1,10 +1,13 @@ #!/usr/bin/env bash -set -Eeu -o pipefail - -if [[ ${BASH_VERSINFO[0]:-0} -lt 5 ]]; then - printf '%s\n' "Bash 5 or higher is required to run valet." +# check the bash version (and that we are running in bash), make it POSIX compliant +# shellcheck disable=SC2292 +# shellcheck disable=SC2086 +# shellcheck disable=SC2128 +if [ ${BASH_VERSINFO:-0} -lt 5 ] || { [ ${BASH_VERSINFO} -eq 5 ] && [ ${BASH_VERSINFO[1]:-0} -lt 1 ]; }; then + printf '%s\n' "❌ Bash 5.1 or higher is required to run valet." exit 1 fi +set -Eeu -o pipefail ##<