diff --git a/.gitignore b/.gitignore index b82509d..b8eb2d2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -.*.swp -.DS_Store +# Are your editor's temp files, OS metadata files, etc. showing up in `git +# status`? Try adding them to `$HOME/.config/git/ignore` instead. tests/bats/ tests/coverage/ tests/kcov/ diff --git a/go-core.bash b/go-core.bash index f5a7540..2063c45 100755 --- a/go-core.bash +++ b/go-core.bash @@ -112,6 +112,9 @@ declare _GO_IMPORTED_MODULE_CALLERS=() # Path to the project's script directory declare _GO_SCRIPTS_DIR= +# Directory containing Bats tests, relative to `_GO_ROOTDIR` +declare -r -x _GO_TEST_DIR="${_GO_TEST_DIR:-tests}" + # Path to the main ./go script in the project's root directory declare -r -x _GO_SCRIPT="$_GO_ROOTDIR/${0##*/}" diff --git a/lib/bats-main b/lib/bats-main index 4e8f74a..00301c7 100644 --- a/lib/bats-main +++ b/lib/bats-main @@ -40,9 +40,6 @@ # make the Bats repository a submodule if so desired. The Bats version so cloned # may be set by overriding `_GO_BATS_VERSION`. -# Directory containing Bats tests, relative to `_GO_ROOTDIR` -export _GO_TEST_DIR="${_GO_TEST_DIR:-tests}" - # Directory in which kcov will be built export _GO_KCOV_DIR="${_GO_KCOV_DIR:-$_GO_TEST_DIR/kcov}" diff --git a/lib/complete b/lib/complete index 816c80e..50f492a 100644 --- a/lib/complete +++ b/lib/complete @@ -15,7 +15,7 @@ # `-f` or `-d` options to generate file or directory paths. # # Arguments: -# ...: Arguments passed directly ot the builtin `compgen` +# ...: Arguments passed directly to the builtin `compgen` @go.compgen() { local add_slashes local compreply=() diff --git a/lib/testing/environment b/lib/testing/environment index c1cf107..34810b4 100644 --- a/lib/testing/environment +++ b/lib/testing/environment @@ -108,3 +108,19 @@ test-go() { @go.create_test_command_script "$parent.d/$subcommand" done } + +# Assigns the results of `@go.compgen` to a caller-defined test data array +# +# While more compact than writing a `while` loop by hand, it's also faster +# thanks to the fact that it disables the Bats function tracing mechanism. +# +# Arguments: +# result: Name of the caller-declared output array +# ...: Arguments passed directly to `@go.compgen` +@go.test_compgen() { + . "$_GO_CORE_DIR/lib/bats/assertions" + set "$BATS_ASSERTION_DISABLE_SHELL_OPTIONS" + . "$_GO_USE_MODULES" 'complete' 'strings' + @go.split $'\n' "$(@go.compgen "${@:2}")" "$1" + return_from_bats_assertion +} diff --git a/lib/testing/stack-trace-item b/lib/testing/stack-trace-item index af5c956..e022937 100755 --- a/lib/testing/stack-trace-item +++ b/lib/testing/stack-trace-item @@ -5,8 +5,6 @@ # DO NOT USE THIS FILE DIRECTLY! Source `_GO_CORE_DIR/lib/testing/stack-trace` # and use the `stack_trace_item` function instead. -. "$_GO_CORE_DIR/lib/bats/helpers" - __@go.stack_trace_item() { local filepath="$1" local function_name="$2" diff --git a/scripts/test b/scripts/test index 5736c64..a13d6df 100755 --- a/scripts/test +++ b/scripts/test @@ -26,7 +26,8 @@ # Passes all arguments through to `@go.bats_main` from `lib/bats-main`. _test_main() { local _GO_BATS_COVERAGE_INCLUDE - _GO_BATS_COVERAGE_INCLUDE=('go' 'go-core.bash' 'lib/' 'libexec/' 'scripts/') + _GO_BATS_COVERAGE_INCLUDE=('go' 'go-core.bash' 'go-template' + 'lib/' 'libexec/' 'scripts/') local _GO_COVERALLS_URL='https://coveralls.io/github/mbland/go-script-bash' . "$_GO_USE_MODULES" 'bats-main' diff --git a/tests/command-descriptions/from-file.bats b/tests/command-descriptions/from-file.bats index 6ed45f4..d9e7450 100644 --- a/tests/command-descriptions/from-file.bats +++ b/tests/command-descriptions/from-file.bats @@ -5,8 +5,18 @@ load ../environment TEST_COMMAND_SCRIPT_PATH="$TEST_GO_SCRIPTS_DIR/test-command" setup() { - . 'lib/internal/command_descriptions' + test_filter + + @go.create_test_go_script \ + ". '$_GO_CORE_DIR/lib/internal/command_descriptions'" \ + 'declare __go_cmd_desc=""' \ + '"$@"' \ + 'declare result="$?"' \ + 'printf "%s\n" "$__go_cmd_desc"' \ + 'exit "$result"' +} +create_script_with_description() { local script='# # Command that does something in {{root}} # @@ -51,14 +61,14 @@ teardown() { @test "$SUITE: return error if there's an error reading" { skip_if_cannot_trigger_file_permission_failure + printf '\n' >"$TEST_COMMAND_SCRIPT_PATH" chmod ugo-r "$TEST_COMMAND_SCRIPT_PATH" - run _@go.command_summary "$TEST_COMMAND_SCRIPT_PATH" + run "$TEST_GO_SCRIPT" _@go.command_summary "$TEST_COMMAND_SCRIPT_PATH" assert_failure assert_output_matches "ERROR: problem reading $TEST_COMMAND_SCRIPT_PATH\$" - output='' - run _@go.command_description "$TEST_COMMAND_SCRIPT_PATH" + run "$TEST_GO_SCRIPT" _@go.command_description "$TEST_COMMAND_SCRIPT_PATH" assert_failure assert_output_matches "ERROR: problem reading $TEST_COMMAND_SCRIPT_PATH\$" } @@ -67,39 +77,32 @@ teardown() { @go.create_test_command_script 'test-command' \ 'echo "This script has no description"' - local __go_cmd_desc='' - _@go.command_summary "$TEST_COMMAND_SCRIPT_PATH" - assert_equal 'No description available' "$__go_cmd_desc" 'command summary' + run "$TEST_GO_SCRIPT" _@go.command_summary "$TEST_COMMAND_SCRIPT_PATH" + assert_success 'No description available' __go_cmd_desc='' - _@go.command_description "$TEST_COMMAND_SCRIPT_PATH" - assert_equal 'No description available' "$__go_cmd_desc" 'command description' + run "$TEST_GO_SCRIPT" _@go.command_description "$TEST_COMMAND_SCRIPT_PATH" + assert_success 'No description available' } @test "$SUITE: parse summary from command script" { - _GO_ROOTDIR='/foo/bar' - _@go.command_summary "$TEST_COMMAND_SCRIPT_PATH" - assert_equal 'Command that does something in /foo/bar' "$__go_cmd_desc" \ - 'command summary' + create_script_with_description + run "$TEST_GO_SCRIPT" _@go.command_summary "$TEST_COMMAND_SCRIPT_PATH" + assert_success "Command that does something in $TEST_GO_ROOTDIR" } @test "$SUITE: one-line description from command script has no trailing space" { echo '# Command that does something in {{root}}' > "$TEST_COMMAND_SCRIPT_PATH" - _GO_ROOTDIR='/foo/bar' - COLUMNS=40 - - _@go.command_description "$TEST_COMMAND_SCRIPT_PATH" - assert_equal 'Command that does something in /foo/bar' "$__go_cmd_desc" \ - 'one-line command description' + COLUMNS=40 run "$TEST_GO_SCRIPT" _@go.command_description \ + "$TEST_COMMAND_SCRIPT_PATH" + assert_success "Command that does something in $TEST_GO_ROOTDIR" } @test "$SUITE: parse description from command script" { - _GO_CMD='test-go' - _GO_ROOTDIR='/foo/bar' - COLUMNS=40 - _@go.command_description "$TEST_COMMAND_SCRIPT_PATH" + create_script_with_description + COLUMNS=40 run test-go _@go.command_description "$TEST_COMMAND_SCRIPT_PATH" - local expected='Command that does something in /foo/bar + local expected='Command that does something in TEST_GO_ROOTDIR Usage: test-go test-command [args...] @@ -125,13 +128,12 @@ Indented lines that look like tables (there are two or more adjacent spaces afte xyzzy all work and no play makes mike a Dull Boy. plugh all werk and no play makes - mike a dull Boy -' + mike a dull Boy' # With this test, I learned that you _do_ have to quote strings even inside of # '[[' and ']]' in case the strings themselves contain '[' or ']', as with # '[args...]' above. - assert_equal "$expected" "$__go_cmd_desc" 'command description' + assert_success "${expected/TEST_GO_ROOTDIR/$TEST_GO_ROOTDIR}" } @test "$SUITE: format subcommand description" { @@ -144,15 +146,9 @@ Indented lines that look like tables (there are two or more adjacent spaces afte echo The command script starts now. ' - local _GO_CMD='test-go' - local expected=("Leaf command that does something in $_GO_ROOTDIR" - '' - "Usage: $_GO_CMD root-command node-command leaf-command [args...]" - '') - local __go_cmd_desc - _@go.command_description \ + run test-go _@go.command_description \ "$TEST_GO_SCRIPTS_DIR/root-command.d/node-command.d/leaf-command" - - local IFS=$'\n' - assert_equal "${expected[*]}" "$__go_cmd_desc" + assert_success "Leaf command that does something in $TEST_GO_ROOTDIR" \ + '' \ + "Usage: test-go root-command node-command leaf-command [args...]" } diff --git a/tests/complete.bats b/tests/complete.bats index b957bda..8e6f7a8 100644 --- a/tests/complete.bats +++ b/tests/complete.bats @@ -70,7 +70,7 @@ teardown() { while IFS= read -r item; do expected+=("${item#$TEST_GO_ROOTDIR/}") - done<<<"$(@go.compgen -d "$TEST_GO_SCRIPTS_DIR/")" + done < <(@go.compgen -d "$TEST_GO_SCRIPTS_DIR/") run "$TEST_GO_SCRIPT" complete 1 cd 'scripts/' assert_success "${expected[@]}" @@ -85,16 +85,12 @@ teardown() { touch "${files[@]/#/$TEST_GO_SCRIPTS_DIR/}" local top_level=() - local all_scripts_entries=() - local item - - while IFS= read -r item; do - top_level+=("${item#$TEST_GO_ROOTDIR/}") - done <<<"$(@go.compgen -f "$TEST_GO_ROOTDIR/")" + @go.test_compgen top_level -f "$TEST_GO_ROOTDIR/" + top_level=("${top_level[@]#$TEST_GO_ROOTDIR/}") - while IFS= read -r item; do - all_scripts_entries+=("${item#$TEST_GO_ROOTDIR/}") - done <<<"$(@go.compgen -f "$TEST_GO_SCRIPTS_DIR/")" + local all_scripts_entries=() + @go.test_compgen all_scripts_entries -f "$TEST_GO_SCRIPTS_DIR/" + all_scripts_entries=("${all_scripts_entries[@]#$TEST_GO_ROOTDIR/}") run "$TEST_GO_SCRIPT" complete 1 edit '' assert_success "${top_level[@]}" diff --git a/tests/get/file.bats b/tests/get/file.bats index 774ef7d..81b05ed 100644 --- a/tests/get/file.bats +++ b/tests/get/file.bats @@ -26,12 +26,7 @@ teardown() { assert_success '-f' local expected=() - local item - - . "$_GO_USE_MODULES" 'complete' - while IFS= read -r item; do - expected+=("$item") - done <<<"$(@go.compgen -f -- "$TEST_GO_ROOTDIR/")" + @go.test_compgen expected -f -- "$TEST_GO_ROOTDIR/" run "$TEST_GO_SCRIPT" get file --complete 1 -f assert_success "${expected[@]#$TEST_GO_ROOTDIR/}" diff --git a/tests/get/git-repo.bats b/tests/get/git-repo.bats index 4e29e9f..5dbc046 100644 --- a/tests/get/git-repo.bats +++ b/tests/get/git-repo.bats @@ -24,10 +24,8 @@ teardown() { run "$TEST_GO_SCRIPT" get git-repo --complete 1 assert_success '' - . "$_GO_USE_MODULES" 'complete' - while IFS= read -r item; do - expected+=("$item") - done <<<"$(@go.compgen -f -- "$TEST_GO_ROOTDIR/")" + local expected=() + @go.test_compgen expected -f -- "$TEST_GO_ROOTDIR/" run "$TEST_GO_SCRIPT" get git-repo --complete 2 assert_success "${expected[@]#$TEST_GO_ROOTDIR/}" diff --git a/tests/test.bats b/tests/test.bats index d0002d5..bc3e4ef 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -118,7 +118,7 @@ write_bats_dummy_stub_kcov_lib_and_copy_test_script() { local expected_kcov_args=( 'tests/kcov' 'tests/coverage' - 'go,go-core.bash,lib/,libexec/,scripts/' + 'go,go-core.bash,go-template,lib/,libexec/,scripts/' '/tmp/,tests/bats/' 'https://coveralls.io/github/mbland/go-script-bash' "$TEST_GO_SCRIPT" diff --git a/tests/testing/environment.bats b/tests/testing/environment.bats index 8311cdd..9350319 100644 --- a/tests/testing/environment.bats +++ b/tests/testing/environment.bats @@ -93,3 +93,28 @@ teardown() { run test-go assert_success '_GO_CMD: test-go' } + +@test "$SUITE: @go.test_compgen" { + mkdir -p "$TEST_GO_ROOTDIR/lib" + printf 'foo' >"$TEST_GO_ROOTDIR/lib/foo" + printf 'bar' >"$TEST_GO_ROOTDIR/lib/bar" + printf 'baz' >"$TEST_GO_ROOTDIR/lib/baz" + + local expected=() + local item + + . "$_GO_USE_MODULES" 'complete' + while IFS= read -r item; do + expected+=("${item#$TEST_GO_ROOTDIR/}") + done < <(@go.compgen -f -- "$TEST_GO_ROOTDIR/lib/") + + export -f @go.test_compgen + @go.create_test_go_script \ + '. "$_GO_USE_MODULES" "complete"' \ + 'declare results=()' \ + '@go.test_compgen "results" -f -- lib/' \ + 'printf "%s\n" "${results[@]}"' + + run "$TEST_GO_SCRIPT" + assert_success "${expected[@]}" +} diff --git a/tests/vars.bats b/tests/vars.bats index d4ce102..1abda87 100644 --- a/tests/vars.bats +++ b/tests/vars.bats @@ -55,7 +55,7 @@ quotify_expected() { "declare -rx _GO_SCRIPT=\"$TEST_GO_SCRIPT\"" "declare -- _GO_SCRIPTS_DIR=\"$TEST_GO_SCRIPTS_DIR\"" "declare -a _GO_SEARCH_PATHS=(${search_paths[*]})" - "declare -x _GO_TEST_DIR=\"$_GO_TEST_DIR\"" + "declare -rx _GO_TEST_DIR=\"$_GO_TEST_DIR\"" "declare -rx _GO_USE_MODULES=\"$_GO_CORE_DIR/lib/internal/use\"") quotify_expected @@ -127,7 +127,7 @@ quotify_expected() { "declare -rx _GO_SCRIPT=\"$TEST_GO_SCRIPT\"" "declare -- _GO_SCRIPTS_DIR=\"$TEST_GO_SCRIPTS_DIR\"" "declare -a _GO_SEARCH_PATHS=(${search_paths[*]})" - "declare -x _GO_TEST_DIR=\"$_GO_TEST_DIR\"" + "declare -rx _GO_TEST_DIR=\"$_GO_TEST_DIR\"" "declare -rx _GO_USE_MODULES=\"$_GO_CORE_DIR/lib/internal/use\"") quotify_expected