From 54981a9a80de5ad181f3e8dedd806525278bb628 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Fri, 17 Mar 2017 14:28:00 -0700 Subject: [PATCH] test-lib-functions-tg.sh: introduce TopGit-specific test functions library The "test-lib-functions-tg.sh" file works very similarly to the "test-lib-functions.sh" file but contains only TopGit specific functions. The testing library now arranges to source it just like it does for the "test-lib-functions.sh" file. Also the following changes were made to better accomodate the new "test-lib-functions-tg.sh" file and its contents: * the test library now sets and exports TG_FULL_PATH which is the full path to the "tg" binary (might be the wrapper) that should be used for testing * the "tg" wrapper now supports the special "tg__include" variable and, if set, will source the wrapped "tg" as the final line rather than exec'ing it * the "die" and "fatal" functions have been renamed to "_die" and "_fatal" with one-line pass-through "die" and "fatal" function front ends * the EXIT trap now uses "_die" rather than "die" in case some included file (such as tg) replaces the "die" function A single initial TopGit specific function is provided named "tg_include" which, as you might have guessed, sources the target "tg" in "include" mode (i.e. with "tg__include=1" set). It does support a few options to make use of the "include" mode easier (-C, -u, -r, -f) but does not otherwise do anything beyond the actual "include". Signed-off-by: Kyle J. McKay --- Makefile | 3 +- t/test-lib-functions-tg.sh | 135 +++++++++++++++++++++++++++++++++++++++++++++ t/test-lib-main.sh | 21 ++++--- t/test-lib.sh | 3 +- 4 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 t/test-lib-functions-tg.sh diff --git a/Makefile b/Makefile index 9087c2a..b8f4e10 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,8 @@ bin-wrappers/tg : $(commands_out) $(utils_out) $(hooks_out) $(helpers_out) tg echo "TG_INST_CMDDIR='$$curdir' && export TG_INST_CMDDIR" >>"$@" && \ echo "TG_INST_SHAREDIR='$$curdir' && export TG_INST_SHAREDIR" >>"$@" && \ echo "TG_INST_HOOKSDIR='$$curdir' && export TG_INST_HOOKSDIR" >>"$@" && \ - echo "exec '$$curdir/tg' \"\$$@\"" >>"$@" && \ + echo "[ -n \"\$$tg__include\" ] || exec '$$curdir/tg' \"\$$@\" || exit" >>"$@" && \ + echo ". '$$curdir/tg'" >>"$@" && \ chmod a+x "$@" $(help_out): README create-help.sh diff --git a/t/test-lib-functions-tg.sh b/t/test-lib-functions-tg.sh new file mode 100644 index 0000000..9ef4fd1 --- /dev/null +++ b/t/test-lib-functions-tg.sh @@ -0,0 +1,135 @@ +# test-lib-functions-tg.sh - test library functions specific to TopGit +# Copyright (C) 2017 Kyle J. McKay +# All rights reserved +# License GPL2 + +# The test library itself is expected to set and export TG_FULL_PATH as the +# full path to the current "tg" executable being tested +# +# IMPORTANT: test-lib-functions-tg.sh MUST NOT EXECUTE ANY CODE! +# +# Also since this file is sourced BEFORE test-lib-functions.sh it may not +# override any functions in there either +# +# The function test_lib_functions_tg_init, which should ALWAYS be kept as +# the very LAST function in this file, will be called once (AFTER +# test-lib-functions.sh has been sourced and inited) but before any other +# functions in it are called + + +## +## TopGit specific test functions +## + + +# tg_include [-C ] [-r ] [-u] [-f] +# +# Source tg in "tg__include=1" mode to provide access to internal functions +# Since this bypasses normal tg options parsing provide a few options +# +# While -C options are indeed parsed and acted upon and the "include" +# itself will occur with the result of any -C options still active, +# the directory will be changed back to the saved "$PWD" (saved at the +# beginning of this function) immediately after the "include" takes place. +# As a result, if any -C options are used it may subsequently be +# necessary to do an explicit cd later on before calling any of the +# internal tg functions. +# +# This function, obviously, causes the "tg" file to be sourced at the current +# shell level so there's no "tg_uninclude" possible, but since the various +# test_expect/tolerate functions run the test code itself in a subshell by +# default, use of tg_include from within a test body will be effectively local +# for that specific test body and be "undone" after it's finished. +# +# Note that the special "tg__include" variable IS left set to "1" after this +# function returns (but it is NOT exported) and all temporary variables used by +# this function are unset +# +# Return status will be "0" on success or last failing status (which will be +# from the include itself if that's the last thing to fail) +# +# However, if the "-f" option is passed any failure is immediately fatal +# +# Since the test library always sets TG_FULL_PATH it's a fatal error to call +# this function when that's unset or invalid (not a readable file) +# +# Note that the "-u" option causes the base_remote variable to always be unset +# immediately after the include while the "-r " option causes +# the base_remote variable to be set before the include; if neither option is +# used and the caller has set base_remote, it will end up as the remote since +# the "tg" command will keep it; however, if the base_remote variable is either +# unset or empty and the "-u" option is not used when this function is called +# then any base_remote setting that "tg" itself picks up will be kept +# +tg_include() { + [ -f "$TG_FULL_PATH" ] && [ -r "$TG_FULL_PATH" ] || + fatal "tg_include called while TG_FULL_PATH is unset or invalid" + unset _tgf_noremote _tgf_fatal _tgf_curdir _tgf_errcode + _tgf_curdir="$PWD" + while [ $# -gt 0 ]; do case "$1" in + -h|--help) + unset _tgf_noremote _tgf_fatal _tgf_curdir + echo "tg_include [-C ] [-r ] [-u]" + return 0 + ;; + -C) + shift + [ -n "$1" ] || fatal "tg_include option -C requires an argument" + cd "$1" || return 1 + ;; + -u) + _tgf_noremote=1 + ;; + -r) + shift + [ -n "$1" ] || fatal "tg_include option -r requires an argument" + base_remote="$1" + unset _tgf_noremote + ;; + -f) + _tgf_fatal=1 + ;; + --) + shift + break + ;; + -?*) + echo "Unknown option: $1" >&2 + usage 1 + ;; + *) + break + ;; + esac; shift; done + [ $# -eq 0 ] || fatal "tg_include non-option arguments prohibited: $*" + unset tg__include # make sure it's not exported + tg__include=1 + # MUST do this AFTER changing the current directory since it sets $git_dir! + _tgf_errcode=0 + . "$TG_FULL_PATH" || _tgf_errcode=$? + [ -z "$_tgf_noremote" ] || base_remote= + cd "$_tgf_curdir" || _fatal "tg_include post-include cd failed to: $_tgf_curdir" + set -- "$_tgf_errcode" "$_tgf_fatal" + unset _tgf_noremote _tgf_fatal _tgf_curdir _tgf_errcode + [ -z "$2" ] || [ "$1" = "0" ] || _fatal "tg_include sourcing of tg failed with status $1" + return $1 +} + + +## +## TopGit specific test functions "init" function +## + + +# +# THIS SHOULD ALWAYS BE THE LAST FUNCTION DEFINED IN THIS FILE +# +# Any client that sources this file should immediately call this function +# afterwards +# +# THERE SHOULD NOT BE ANY DIRECTLY EXECUTED LINES OF CODE IN THIS FILE +# +test_lib_functions_tg_init() { + # Nothing to do here yet, but a function must have at least one command + : +} diff --git a/t/test-lib-main.sh b/t/test-lib-main.sh index 6188d5f..e3c1c7d 100644 --- a/t/test-lib-main.sh +++ b/t/test-lib-main.sh @@ -11,7 +11,7 @@ # and MUST contain any lines of code to be executed. This will ALWAYS # be the LAST function defined in this file for easy locatability. # -# * Added cmd_path, fatal, whats_the_dir, vcmp, getcmd, say_tap, say_color_tap, +# * Added cmd_path, _?fatal, whats_the_dir, vcmp, getcmd, say_tap, say_color_tap, # fail_, test_possibly_broken_ok_ and test_possibly_broken_failure_ functions # # * Anything related to valgrind or perf has been stripped out @@ -45,11 +45,12 @@ cmd_path() ( command -v "$1" ) -fatal() { +_fatal() { printf '%s\n' "$*" >&2 TESTLIB_EXIT_OK=1 exit 1 } +fatal() { _fatal "$@"; } # usage: cmdget [...] # return code is that of [/dev/null && pwd -P || :)" [ -x "$tg_bin_dir/tg" ] || fatal 'error: no ../bin-wrappers/tg executable found!' PATH="$tg_bin_dir:$PATH" + TG_FULL_PATH="$tg_bin_dir/tg" fi +export TG_FULL_PATH tg_version="$(tg --version)" || fatal 'error: tg --version failed!' case "$tg_version" in [Tt][Oo][Pp][Gg][Ii][Tt]\ [Vv][Ee][Rr][Ss][Ii][Oo][Nn]\ [0-9]*);;*) @@ -1253,7 +1260,7 @@ else fi TESTLIB_EXIT_OK= -trap 'die' EXIT +trap '_die' EXIT trap 'exit $?' HUP INT QUIT ABRT PIPE TERM trap 'TESTLIB_EXIT_OK=t; exit 1' USR1 diff --git a/t/test-lib.sh b/t/test-lib.sh index ea581c6..f21b808 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -41,7 +41,7 @@ if [ "$1" = "--cache" ]; then _x05 _x40 _z40 EMPTY_TREE EMPTY_BLOB LF u200c UNAME_S \ TERM SHELL_PATH PERL_PATH GIT_PATH DIFF TG_TEST_INSTALLED \ test_prereq TESTLIB_NO_TOLERATE TESTLIB_TEST_LONG \ - GIT_CEILING_DIRECTORIES" + GIT_CEILING_DIRECTORIES TG_FULL_PATH" UNSET_VARS="VISUAL EMAIL LANGUAGE COLUMNS XDG_CONFIG_HOME GITPERLLIB \ CDPATH GREP_OPTIONS UNZIP TESTLIB_EXIT_OK last_verbose" @@ -143,6 +143,7 @@ if [ "$1" = "--cache" ]; then echo export $EXPORT_VARS "&&" printf '%s\n' \ "cd $PWD_SQ &&" \ + ". $TD_SQ/test-lib-functions-tg.sh &&" \ ". $TD_SQ/test-lib-functions.sh &&" \ ". $TD_SQ/test-lib-main.sh &&" echo "TESTLIB_CACHE_ACTIVE=1" -- 2.11.4.GIT