diff options
author | Malfurious <m@lfurio.us> | 2021-07-20 20:10:34 -0400 |
---|---|---|
committer | Malfurious <m@lfurio.us> | 2021-07-20 20:10:34 -0400 |
commit | 0173bdcf5bc2bb97bd125679ee25e12ed8be544f (patch) | |
tree | d2381fa960c55dfcfda4ae0b87396ca0f7fc24c7 /test | |
parent | 3d5a9a7c893f3505216d00348e94ccf1aa5d9084 (diff) | |
download | git-sonar-0173bdcf5bc2bb97bd125679ee25e12ed8be544f.tar.gz git-sonar-0173bdcf5bc2bb97bd125679ee25e12ed8be544f.zip |
Move test files to subdirectory
Signed-off-by: Malfurious <m@lfurio.us>
Diffstat (limited to 'test')
-rwxr-xr-x | test/shunit/shunit2 | 1048 | ||||
-rwxr-xr-x | test/shunit/shunit2_test.sh | 124 | ||||
-rwxr-xr-x | test/shunit/shunit2_test_asserts.sh | 209 | ||||
-rwxr-xr-x | test/shunit/shunit2_test_failures.sh | 89 | ||||
-rw-r--r-- | test/shunit/shunit2_test_helpers | 177 | ||||
-rwxr-xr-x | test/shunit/shunit2_test_macros.sh | 249 | ||||
-rwxr-xr-x | test/shunit/shunit2_test_misc.sh | 165 | ||||
-rwxr-xr-x | test/shunit/shunit2_test_standalone.sh | 41 | ||||
-rwxr-xr-x | test/test (renamed from test) | 0 | ||||
-rwxr-xr-x | test/test-branches.sh | 110 | ||||
-rwxr-xr-x | test/test-colors.sh | 493 | ||||
-rwxr-xr-x | test/test-commits.sh | 436 | ||||
-rwxr-xr-x | test/test-directories.sh | 95 | ||||
-rwxr-xr-x | test/test-files.sh | 274 | ||||
-rwxr-xr-x | test/test-format-config.sh | 235 | ||||
-rwxr-xr-x | test/test-performance.sh | 231 | ||||
-rwxr-xr-x | test/test-sonar-base.sh | 29 | ||||
-rwxr-xr-x | test/test-stash.sh | 50 | ||||
-rwxr-xr-x | test/test-status.sh | 145 |
19 files changed, 4200 insertions, 0 deletions
diff --git a/test/shunit/shunit2 b/test/shunit/shunit2 new file mode 100755 index 0000000..8862ffd --- /dev/null +++ b/test/shunit/shunit2 @@ -0,0 +1,1048 @@ +#! /bin/sh +# $Id: shunit2 335 2011-05-01 20:10:33Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# +# Copyright 2008 Kate Ward. All Rights Reserved. +# Released under the LGPL (GNU Lesser General Public License) +# +# shUnit2 -- Unit testing framework for Unix shell scripts. +# http://code.google.com/p/shunit2/ +# +# Author: kate.ward@forestent.com (Kate Ward) +# +# shUnit2 is a xUnit based unit test framework for Bourne shell scripts. It is +# based on the popular JUnit unit testing framework for Java. + +# return if shunit already loaded +[ -n "${SHUNIT_VERSION:-}" ] && exit 0 + +SHUNIT_VERSION='2.1.6' + +SHUNIT_TRUE=0 +SHUNIT_FALSE=1 +SHUNIT_ERROR=2 + +# enable strict mode by default +SHUNIT_STRICT=${SHUNIT_STRICT:-${SHUNIT_TRUE}} + +_shunit_warn() { echo "shunit2:WARN $@" >&2; } +_shunit_error() { echo "shunit2:ERROR $@" >&2; } +_shunit_fatal() { echo "shunit2:FATAL $@" >&2; exit ${SHUNIT_ERROR}; } + +# specific shell checks +if [ -n "${ZSH_VERSION:-}" ]; then + setopt |grep "^shwordsplit$" >/dev/null + if [ $? -ne ${SHUNIT_TRUE} ]; then + _shunit_fatal 'zsh shwordsplit option is required for proper operation' + fi + if [ -z "${SHUNIT_PARENT:-}" ]; then + _shunit_fatal "zsh does not pass \$0 through properly. please declare \ +\"SHUNIT_PARENT=\$0\" before calling shUnit2" + fi +fi + +# +# constants +# + +__SHUNIT_ASSERT_MSG_PREFIX='ASSERT:' +__SHUNIT_MODE_SOURCED='sourced' +__SHUNIT_MODE_STANDALONE='standalone' +__SHUNIT_PARENT=${SHUNIT_PARENT:-$0} + +# set the constants readonly +shunit_constants_=`set |grep '^__SHUNIT_' |cut -d= -f1` +echo "${shunit_constants_}" |grep '^Binary file' >/dev/null && \ + shunit_constants_=`set |grep -a '^__SHUNIT_' |cut -d= -f1` +for shunit_constant_ in ${shunit_constants_}; do + shunit_ro_opts_='' + case ${ZSH_VERSION:-} in + '') ;; # this isn't zsh + [123].*) ;; # early versions (1.x, 2.x, 3.x) + *) shunit_ro_opts_='-g' ;; # all later versions. declare readonly globally + esac + readonly ${shunit_ro_opts_} ${shunit_constant_} +done +unset shunit_constant_ shunit_constants_ shunit_ro_opts_ + +# variables +__shunit_lineno='' # line number of executed test +__shunit_mode=${__SHUNIT_MODE_SOURCED} # operating mode +__shunit_reportGenerated=${SHUNIT_FALSE} # is report generated +__shunit_script='' # filename of unittest script (standalone mode) +__shunit_skip=${SHUNIT_FALSE} # is skipping enabled +__shunit_suite='' # suite of tests to execute + +# counts of tests +__shunit_testSuccess=${SHUNIT_TRUE} +__shunit_testsTotal=0 +__shunit_testsPassed=0 +__shunit_testsFailed=0 + +# counts of asserts +__shunit_assertsTotal=0 +__shunit_assertsPassed=0 +__shunit_assertsFailed=0 +__shunit_assertsSkipped=0 + +# macros +_SHUNIT_LINENO_='eval __shunit_lineno=""; if [ "${1:-}" = "--lineno" ]; then [ -n "$2" ] && __shunit_lineno="[$2] "; shift 2; fi' + +#----------------------------------------------------------------------------- +# assert functions +# + +# Assert that two values are equal to one another. +# +# Args: +# message: string: failure message [optional] +# expected: string: expected value +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +assertEquals() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error "assertEquals() requires two or three arguments; $# given" + _shunit_error "1: ${1:+$1} 2: ${2:+$2} 3: ${3:+$3}${4:+ 4: $4}" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_expected_=$1 + shunit_actual_=$2 + + shunit_return=${SHUNIT_TRUE} + if [ "${shunit_expected_}" = "${shunit_actual_}" ]; then + _shunit_assertPass + else + failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}" + shunit_return=${SHUNIT_FALSE} + fi + + unset shunit_message_ shunit_expected_ shunit_actual_ + return ${shunit_return} +} +_ASSERT_EQUALS_='eval assertEquals --lineno "${LINENO:-}"' + +# Assert that two values are not equal to one another. +# +# Args: +# message: string: failure message [optional] +# expected: string: expected value +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +assertNotEquals() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error "assertNotEquals() requires two or three arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_expected_=$1 + shunit_actual_=$2 + + shunit_return=${SHUNIT_TRUE} + if [ "${shunit_expected_}" != "${shunit_actual_}" ]; then + _shunit_assertPass + else + failSame "${shunit_message_}" "$@" + shunit_return=${SHUNIT_FALSE} + fi + + unset shunit_message_ shunit_expected_ shunit_actual_ + return ${shunit_return} +} +_ASSERT_NOT_EQUALS_='eval assertNotEquals --lineno "${LINENO:-}"' + +# Assert that a value is null (i.e. an empty string) +# +# Args: +# message: string: failure message [optional] +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +assertNull() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 1 -o $# -gt 2 ]; then + _shunit_error "assertNull() requires one or two arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 2 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + assertTrue "${shunit_message_}" "[ -z '$1' ]" + shunit_return=$? + + unset shunit_message_ + return ${shunit_return} +} +_ASSERT_NULL_='eval assertNull --lineno "${LINENO:-}"' + +# Assert that a value is not null (i.e. a non-empty string) +# +# Args: +# message: string: failure message [optional] +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +assertNotNull() +{ + ${_SHUNIT_LINENO_} + if [ $# -gt 2 ]; then # allowing 0 arguments as $1 might actually be null + _shunit_error "assertNotNull() requires one or two arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 2 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_actual_=`_shunit_escapeCharactersInString "${1:-}"` + test -n "${shunit_actual_}" + assertTrue "${shunit_message_}" $? + shunit_return=$? + + unset shunit_actual_ shunit_message_ + return ${shunit_return} +} +_ASSERT_NOT_NULL_='eval assertNotNull --lineno "${LINENO:-}"' + +# Assert that two values are the same (i.e. equal to one another). +# +# Args: +# message: string: failure message [optional] +# expected: string: expected value +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +assertSame() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error "assertSame() requires two or three arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + assertEquals "${shunit_message_}" "$1" "$2" + shunit_return=$? + + unset shunit_message_ + return ${shunit_return} +} +_ASSERT_SAME_='eval assertSame --lineno "${LINENO:-}"' + +# Assert that two values are not the same (i.e. not equal to one another). +# +# Args: +# message: string: failure message [optional] +# expected: string: expected value +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +assertNotSame() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error "assertNotSame() requires two or three arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_:-}$1" + shift + fi + assertNotEquals "${shunit_message_}" "$1" "$2" + shunit_return=$? + + unset shunit_message_ + return ${shunit_return} +} +_ASSERT_NOT_SAME_='eval assertNotSame --lineno "${LINENO:-}"' + +# Assert that a value or shell test condition is true. +# +# In shell, a value of 0 is true and a non-zero value is false. Any integer +# value passed can thereby be tested. +# +# Shell supports much more complicated tests though, and a means to support +# them was needed. As such, this function tests that conditions are true or +# false through evaluation rather than just looking for a true or false. +# +# The following test will succeed: +# assertTrue 0 +# assertTrue "[ 34 -gt 23 ]" +# The folloing test will fail with a message: +# assertTrue 123 +# assertTrue "test failed" "[ -r '/non/existant/file' ]" +# +# Args: +# message: string: failure message [optional] +# condition: string: integer value or shell conditional statement +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +assertTrue() +{ + ${_SHUNIT_LINENO_} + if [ $# -gt 2 ]; then + _shunit_error "assertTrue() takes one two arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 2 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_condition_=$1 + + # see if condition is an integer, i.e. a return value + shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'` + shunit_return=${SHUNIT_TRUE} + if [ -z "${shunit_condition_}" ]; then + # null condition + shunit_return=${SHUNIT_FALSE} + elif [ -n "${shunit_match_}" -a "${shunit_condition_}" = "${shunit_match_}" ] + then + # possible return value. treating 0 as true, and non-zero as false. + [ ${shunit_condition_} -ne 0 ] && shunit_return=${SHUNIT_FALSE} + else + # (hopefully) a condition + ( eval ${shunit_condition_} ) >/dev/null 2>&1 + [ $? -ne 0 ] && shunit_return=${SHUNIT_FALSE} + fi + + # record the test + if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then + _shunit_assertPass + else + _shunit_assertFail "${shunit_message_}" + fi + + unset shunit_message_ shunit_condition_ shunit_match_ + return ${shunit_return} +} +_ASSERT_TRUE_='eval assertTrue --lineno "${LINENO:-}"' + +# Assert that a value or shell test condition is false. +# +# In shell, a value of 0 is true and a non-zero value is false. Any integer +# value passed can thereby be tested. +# +# Shell supports much more complicated tests though, and a means to support +# them was needed. As such, this function tests that conditions are true or +# false through evaluation rather than just looking for a true or false. +# +# The following test will succeed: +# assertFalse 1 +# assertFalse "[ 'apples' = 'oranges' ]" +# The folloing test will fail with a message: +# assertFalse 0 +# assertFalse "test failed" "[ 1 -eq 1 -a 2 -eq 2 ]" +# +# Args: +# message: string: failure message [optional] +# condition: string: integer value or shell conditional statement +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +assertFalse() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 1 -o $# -gt 2 ]; then + _shunit_error "assertFalse() quires one or two arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 2 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_condition_=$1 + + # see if condition is an integer, i.e. a return value + shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'` + shunit_return=${SHUNIT_TRUE} + if [ -z "${shunit_condition_}" ]; then + # null condition + shunit_return=${SHUNIT_FALSE} + elif [ -n "${shunit_match_}" -a "${shunit_condition_}" = "${shunit_match_}" ] + then + # possible return value. treating 0 as true, and non-zero as false. + [ ${shunit_condition_} -eq 0 ] && shunit_return=${SHUNIT_FALSE} + else + # (hopefully) a condition + ( eval ${shunit_condition_} ) >/dev/null 2>&1 + [ $? -eq 0 ] && shunit_return=${SHUNIT_FALSE} + fi + + # record the test + if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then + _shunit_assertPass + else + _shunit_assertFail "${shunit_message_}" + fi + + unset shunit_message_ shunit_condition_ shunit_match_ + return ${shunit_return} +} +_ASSERT_FALSE_='eval assertFalse --lineno "${LINENO:-}"' + +#----------------------------------------------------------------------------- +# failure functions +# + +# Records a test failure. +# +# Args: +# message: string: failure message [optional] +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +fail() +{ + ${_SHUNIT_LINENO_} + if [ $# -gt 1 ]; then + _shunit_error "fail() requires zero or one arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 1 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + + _shunit_assertFail "${shunit_message_}" + + unset shunit_message_ + return ${SHUNIT_FALSE} +} +_FAIL_='eval fail --lineno "${LINENO:-}"' + +# Records a test failure, stating two values were not equal. +# +# Args: +# message: string: failure message [optional] +# expected: string: expected value +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +failNotEquals() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error "failNotEquals() requires one or two arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + shunit_expected_=$1 + shunit_actual_=$2 + + _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected:<${shunit_expected_}> but was:<${shunit_actual_}>" + + unset shunit_message_ shunit_expected_ shunit_actual_ + return ${SHUNIT_FALSE} +} +_FAIL_NOT_EQUALS_='eval failNotEquals --lineno "${LINENO:-}"' + +# Records a test failure, stating two values should have been the same. +# +# Args: +# message: string: failure message [optional] +# expected: string: expected value +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +failSame() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error "failSame() requires two or three arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + + _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected not same" + + unset shunit_message_ + return ${SHUNIT_FALSE} +} +_FAIL_SAME_='eval failSame --lineno "${LINENO:-}"' + +# Records a test failure, stating two values were not equal. +# +# This is functionally equivalent to calling failNotEquals(). +# +# Args: +# message: string: failure message [optional] +# expected: string: expected value +# actual: string: actual value +# Returns: +# integer: success (TRUE/FALSE/ERROR constant) +failNotSame() +{ + ${_SHUNIT_LINENO_} + if [ $# -lt 2 -o $# -gt 3 ]; then + _shunit_error "failNotEquals() requires one or two arguments; $# given" + return ${SHUNIT_ERROR} + fi + _shunit_shouldSkip && return ${SHUNIT_TRUE} + + shunit_message_=${__shunit_lineno} + if [ $# -eq 3 ]; then + shunit_message_="${shunit_message_}$1" + shift + fi + failNotEquals "${shunit_message_}" "$1" "$2" + shunit_return=$? + + unset shunit_message_ + return ${shunit_return} +} +_FAIL_NOT_SAME_='eval failNotSame --lineno "${LINENO:-}"' + +#----------------------------------------------------------------------------- +# skipping functions +# + +# Force remaining assert and fail functions to be "skipped". +# +# This function forces the remaining assert and fail functions to be "skipped", +# i.e. they will have no effect. Each function skipped will be recorded so that +# the total of asserts and fails will not be altered. +# +# Args: +# None +startSkipping() +{ + __shunit_skip=${SHUNIT_TRUE} +} + +# Resume the normal recording behavior of assert and fail calls. +# +# Args: +# None +endSkipping() +{ + __shunit_skip=${SHUNIT_FALSE} +} + +# Returns the state of assert and fail call skipping. +# +# Args: +# None +# Returns: +# boolean: (TRUE/FALSE constant) +isSkipping() +{ + return ${__shunit_skip} +} + +#----------------------------------------------------------------------------- +# suite functions +# + +# Stub. This function should contains all unit test calls to be made. +# +# DEPRECATED (as of 2.1.0) +# +# This function can be optionally overridden by the user in their test suite. +# +# If this function exists, it will be called when shunit2 is sourced. If it +# does not exist, shunit2 will search the parent script for all functions +# beginning with the word 'test', and they will be added dynamically to the +# test suite. +# +# This function should be overridden by the user in their unit test suite. +# Note: see _shunit_mktempFunc() for actual implementation +# +# Args: +# None +#suite() { :; } # DO NOT UNCOMMENT THIS FUNCTION + +# Adds a function name to the list of tests schedule for execution. +# +# This function should only be called from within the suite() function. +# +# Args: +# function: string: name of a function to add to current unit test suite +suite_addTest() +{ + shunit_func_=${1:-} + + __shunit_suite="${__shunit_suite:+${__shunit_suite} }${shunit_func_}" + __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1` + + unset shunit_func_ +} + +# Stub. This function will be called once before any tests are run. +# +# Common one-time environment preparation tasks shared by all tests can be +# defined here. +# +# This function should be overridden by the user in their unit test suite. +# Note: see _shunit_mktempFunc() for actual implementation +# +# Args: +# None +#oneTimeSetUp() { :; } # DO NOT UNCOMMENT THIS FUNCTION + +# Stub. This function will be called once after all tests are finished. +# +# Common one-time environment cleanup tasks shared by all tests can be defined +# here. +# +# This function should be overridden by the user in their unit test suite. +# Note: see _shunit_mktempFunc() for actual implementation +# +# Args: +# None +#oneTimeTearDown() { :; } # DO NOT UNCOMMENT THIS FUNCTION + +# Stub. This function will be called before each test is run. +# +# Common environment preparation tasks shared by all tests can be defined here. +# +# This function should be overridden by the user in their unit test suite. +# Note: see _shunit_mktempFunc() for actual implementation +# +# Args: +# None +#setUp() { :; } + +# Note: see _shunit_mktempFunc() for actual implementation +# Stub. This function will be called after each test is run. +# +# Common environment cleanup tasks shared by all tests can be defined here. +# +# This function should be overridden by the user in their unit test suite. +# Note: see _shunit_mktempFunc() for actual implementation +# +# Args: +# None +#tearDown() { :; } # DO NOT UNCOMMENT THIS FUNCTION + +#------------------------------------------------------------------------------ +# internal shUnit2 functions +# + +# Create a temporary directory to store various run-time files in. +# +# This function is a cross-platform temporary directory creation tool. Not all +# OSes have the mktemp function, so one is included here. +# +# Args: +# None +# Outputs: +# string: the temporary directory that was created +_shunit_mktempDir() +{ + # try the standard mktemp function + ( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ) && return + + # the standard mktemp didn't work. doing our own. + if [ -r '/dev/urandom' -a -x '/usr/bin/od' ]; then + _shunit_random_=`/usr/bin/od -vAn -N4 -tx4 </dev/urandom \ + |sed 's/^[^0-9a-f]*//'` + elif [ -n "${RANDOM:-}" ]; then + # $RANDOM works + _shunit_random_=${RANDOM}${RANDOM}${RANDOM}$$ + else + # $RANDOM doesn't work + _shunit_date_=`date '+%Y%m%d%H%M%S'` + _shunit_random_=`expr ${_shunit_date_} / $$` + fi + + _shunit_tmpDir_="${TMPDIR:-/tmp}/shunit.${_shunit_random_}" + ( umask 077 && mkdir "${_shunit_tmpDir_}" ) || \ + _shunit_fatal 'could not create temporary directory! exiting' + + echo ${_shunit_tmpDir_} + unset _shunit_date_ _shunit_random_ _shunit_tmpDir_ +} + +# This function is here to work around issues in Cygwin. +# +# Args: +# None +_shunit_mktempFunc() +{ + for _shunit_func_ in oneTimeSetUp oneTimeTearDown setUp tearDown suite noexec + do + _shunit_file_="${__shunit_tmpDir}/${_shunit_func_}" + cat <<EOF >"${_shunit_file_}" +#! /bin/sh +exit ${SHUNIT_TRUE} +EOF + chmod +x "${_shunit_file_}" + done + + unset _shunit_file_ +} + +# Final cleanup function to leave things as we found them. +# +# Besides removing the temporary directory, this function is in charge of the +# final exit code of the unit test. The exit code is based on how the script +# was ended (e.g. normal exit, or via Ctrl-C). +# +# Args: +# name: string: name of the trap called (specified when trap defined) +_shunit_cleanup() +{ + _shunit_name_=$1 + + case ${_shunit_name_} in + EXIT) _shunit_signal_=0 ;; + INT) _shunit_signal_=2 ;; + TERM) _shunit_signal_=15 ;; + *) + _shunit_warn "unrecognized trap value (${_shunit_name_})" + _shunit_signal_=0 + ;; + esac + + # do our work + rm -fr "${__shunit_tmpDir}" + + # exit for all non-EXIT signals + if [ ${_shunit_name_} != 'EXIT' ]; then + _shunit_warn "trapped and now handling the (${_shunit_name_}) signal" + # disable EXIT trap + trap 0 + # add 128 to signal and exit + exit `expr ${_shunit_signal_} + 128` + elif [ ${__shunit_reportGenerated} -eq ${SHUNIT_FALSE} ] ; then + _shunit_assertFail 'Unknown failure encountered running a test' + _shunit_generateReport + exit ${SHUNIT_ERROR} + fi + + unset _shunit_name_ _shunit_signal_ +} + +# The actual running of the tests happens here. +# +# Args: +# None +_shunit_execSuite() +{ + for _shunit_test_ in ${__shunit_suite}; do + __shunit_testSuccess=${SHUNIT_TRUE} + + # disable skipping + endSkipping + + # execute the per-test setup function + setUp + + # execute the test + echo "${_shunit_test_}" + eval ${_shunit_test_} + + # execute the per-test tear-down function + tearDown + + # update stats + if [ ${__shunit_testSuccess} -eq ${SHUNIT_TRUE} ]; then + __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1` + else + __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1` + fi + done + + unset _shunit_test_ +} + +# Generates the user friendly report with appropriate OK/FAILED message. +# +# Args: +# None +# Output: +# string: the report of successful and failed tests, as well as totals. +_shunit_generateReport() +{ + _shunit_ok_=${SHUNIT_TRUE} + + # if no exit code was provided one, determine an appropriate one + [ ${__shunit_testsFailed} -gt 0 \ + -o ${__shunit_testSuccess} -eq ${SHUNIT_FALSE} ] \ + && _shunit_ok_=${SHUNIT_FALSE} + + echo + if [ ${__shunit_testsTotal} -eq 1 ]; then + echo "Ran ${__shunit_testsTotal} test." + else + echo "Ran ${__shunit_testsTotal} tests." + fi + + _shunit_failures_='' + _shunit_skipped_='' + [ ${__shunit_assertsFailed} -gt 0 ] \ + && _shunit_failures_="failures=${__shunit_assertsFailed}" + [ ${__shunit_assertsSkipped} -gt 0 ] \ + && _shunit_skipped_="skipped=${__shunit_assertsSkipped}" + + if [ ${_shunit_ok_} -eq ${SHUNIT_TRUE} ]; then + _shunit_msg_='OK' + [ -n "${_shunit_skipped_}" ] \ + && _shunit_msg_="${_shunit_msg_} (${_shunit_skipped_})" + else + _shunit_msg_="FAILED (${_shunit_failures_}" + [ -n "${_shunit_skipped_}" ] \ + && _shunit_msg_="${_shunit_msg_},${_shunit_skipped_}" + _shunit_msg_="${_shunit_msg_})" + fi + + echo + echo ${_shunit_msg_} + __shunit_reportGenerated=${SHUNIT_TRUE} + + unset _shunit_failures_ _shunit_msg_ _shunit_ok_ _shunit_skipped_ +} + +# Test for whether a function should be skipped. +# +# Args: +# None +# Returns: +# boolean: whether the test should be skipped (TRUE/FALSE constant) +_shunit_shouldSkip() +{ + [ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE} + _shunit_assertSkip +} + +# Records a successful test. +# +# Args: +# None +_shunit_assertPass() +{ + __shunit_assertsPassed=`expr ${__shunit_assertsPassed} + 1` + __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1` +} + +# Records a test failure. +# +# Args: +# message: string: failure message to provide user +_shunit_assertFail() +{ + _shunit_msg_=$1 + + __shunit_testSuccess=${SHUNIT_FALSE} + __shunit_assertsFailed=`expr ${__shunit_assertsFailed} + 1` + __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1` + echo "${__SHUNIT_ASSERT_MSG_PREFIX}${_shunit_msg_}" + + unset _shunit_msg_ +} + +# Records a skipped test. +# +# Args: +# None +_shunit_assertSkip() +{ + __shunit_assertsSkipped=`expr ${__shunit_assertsSkipped} + 1` + __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1` +} + +# Prepare a script filename for sourcing. +# +# Args: +# script: string: path to a script to source +# Returns: +# string: filename prefixed with ./ (if necessary) +_shunit_prepForSourcing() +{ + _shunit_script_=$1 + case "${_shunit_script_}" in + /*|./*) echo "${_shunit_script_}" ;; + *) echo "./${_shunit_script_}" ;; + esac + unset _shunit_script_ +} + +# Escape a character in a string. +# +# Args: +# c: string: unescaped character +# s: string: to escape character in +# Returns: +# string: with escaped character(s) +_shunit_escapeCharInStr() +{ + [ -n "$2" ] || return # no point in doing work on an empty string + + # Note: using shorter variable names to prevent conflicts with + # _shunit_escapeCharactersInString(). + _shunit_c_=$1 + _shunit_s_=$2 + + + # escape the character + echo ''${_shunit_s_}'' |sed 's/\'${_shunit_c_}'/\\\'${_shunit_c_}'/g' + + unset _shunit_c_ _shunit_s_ +} + +# Escape a character in a string. +# +# Args: +# str: string: to escape characters in +# Returns: +# string: with escaped character(s) +_shunit_escapeCharactersInString() +{ + [ -n "$1" ] || return # no point in doing work on an empty string + + _shunit_str_=$1 + + # Note: using longer variable names to prevent conflicts with + # _shunit_escapeCharInStr(). + for _shunit_char_ in '"' '$' "'" '`'; do + _shunit_str_=`_shunit_escapeCharInStr "${_shunit_char_}" "${_shunit_str_}"` + done + + echo "${_shunit_str_}" + unset _shunit_char_ _shunit_str_ +} + +# Extract list of functions to run tests against. +# +# Args: +# script: string: name of script to extract functions from +# Returns: +# string: of function names +_shunit_extractTestFunctions() +{ + _shunit_script_=$1 + + # extract the lines with test function names, strip of anything besides the + # function name, and output everything on a single line. + _shunit_regex_='^[ ]*(function )*test[A-Za-z0-9_]* *\(\)' + egrep "${_shunit_regex_}" "${_shunit_script_}" \ + |sed 's/^[^A-Za-z0-9_]*//;s/^function //;s/\([A-Za-z0-9_]*\).*/\1/g' \ + |xargs + + unset _shunit_regex_ _shunit_script_ +} + +#------------------------------------------------------------------------------ +# main +# + +# determine the operating mode +if [ $# -eq 0 ]; then + __shunit_script=${__SHUNIT_PARENT} + __shunit_mode=${__SHUNIT_MODE_SOURCED} +else + __shunit_script=$1 + [ -r "${__shunit_script}" ] || \ + _shunit_fatal "unable to read from ${__shunit_script}" + __shunit_mode=${__SHUNIT_MODE_STANDALONE} +fi + +# create a temporary storage location +__shunit_tmpDir=`_shunit_mktempDir` + +# provide a public temporary directory for unit test scripts +# TODO(kward): document this +SHUNIT_TMPDIR="${__shunit_tmpDir}/tmp" +mkdir "${SHUNIT_TMPDIR}" + +# setup traps to clean up after ourselves +trap '_shunit_cleanup EXIT' 0 +trap '_shunit_cleanup INT' 2 +trap '_shunit_cleanup TERM' 15 + +# create phantom functions to work around issues with Cygwin +_shunit_mktempFunc +PATH="${__shunit_tmpDir}:${PATH}" + +# make sure phantom functions are executable. this will bite if /tmp (or the +# current $TMPDIR) points to a path on a partition that was mounted with the +# 'noexec' option. the noexec command was created with _shunit_mktempFunc(). +noexec 2>/dev/null || _shunit_fatal \ + 'please declare TMPDIR with path on partition with exec permission' + +# we must manually source the tests in standalone mode +if [ "${__shunit_mode}" = "${__SHUNIT_MODE_STANDALONE}" ]; then + . "`_shunit_prepForSourcing \"${__shunit_script}\"`" +fi + +# execute the oneTimeSetUp function (if it exists) +oneTimeSetUp + +# execute the suite function defined in the parent test script +# deprecated as of 2.1.0 +suite + +# if no suite function was defined, dynamically build a list of functions +if [ -z "${__shunit_suite}" ]; then + shunit_funcs_=`_shunit_extractTestFunctions "${__shunit_script}"` + for shunit_func_ in ${shunit_funcs_}; do + suite_addTest ${shunit_func_} + done +fi +unset shunit_func_ shunit_funcs_ + +# execute the tests +_shunit_execSuite + +# execute the oneTimeTearDown function (if it exists) +oneTimeTearDown + +# generate the report +_shunit_generateReport + +# that's it folks +[ ${__shunit_testsFailed} -eq 0 ] +exit $? diff --git a/test/shunit/shunit2_test.sh b/test/shunit/shunit2_test.sh new file mode 100755 index 0000000..f5a0ff8 --- /dev/null +++ b/test/shunit/shunit2_test.sh @@ -0,0 +1,124 @@ +#! /bin/sh +# $Id: shunit2_test.sh 322 2011-04-24 00:09:45Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# +# Copyright 2008 Kate Ward. All Rights Reserved. +# Released under the LGPL (GNU Lesser General Public License) +# Author: kate.ward@forestent.com (Kate Ward) +# +# shUnit2 unit test suite runner. +# +# This script runs all the unit tests that can be found, and generates a nice +# report of the tests. + +MY_NAME=`basename $0` +MY_PATH=`dirname $0` + +PREFIX='shunit2_test_' +SHELLS='/bin/sh /bin/bash /bin/dash /bin/ksh /bin/pdksh /bin/zsh' +TESTS='' +for test in ${PREFIX}[a-z]*.sh; do + TESTS="${TESTS} ${test}" +done + +# load common unit test functions +. ../lib/versions +. ./shunit2_test_helpers + +usage() +{ + echo "usage: ${MY_NAME} [-e key=val ...] [-s shell(s)] [-t test(s)]" +} + +env='' + +# process command line flags +while getopts 'e:hs:t:' opt; do + case ${opt} in + e) # set an environment variable + key=`expr "${OPTARG}" : '\([^=]*\)='` + val=`expr "${OPTARG}" : '[^=]*=\(.*\)'` + if [ -z "${key}" -o -z "${val}" ]; then + usage + exit 1 + fi + eval "${key}='${val}'" + export ${key} + env="${env:+${env} }${key}" + ;; + h) usage; exit 0 ;; # output help + s) shells=${OPTARG} ;; # list of shells to run + t) tests=${OPTARG} ;; # list of tests to run + *) usage; exit 1 ;; + esac +done +shift `expr ${OPTIND} - 1` + +# fill shells and/or tests +shells=${shells:-${SHELLS}} +tests=${tests:-${TESTS}} + +# error checking +if [ -z "${tests}" ]; then + th_error 'no tests found to run; exiting' + exit 1 +fi + +cat <<EOF +#------------------------------------------------------------------------------ +# System data +# + +# test run info +shells: ${shells} +tests: ${tests} +EOF +for key in ${env}; do + eval "echo \"${key}=\$${key}\"" +done +echo + +# output system data +echo "# system info" +echo "$ date" +date +echo + +echo "$ uname -mprsv" +uname -mprsv + +# +# run tests +# + +for shell in ${shells}; do + echo + + # check for existance of shell + if [ ! -x ${shell} ]; then + th_warn "unable to run tests with the ${shell} shell" + continue + fi + + cat <<EOF + +#------------------------------------------------------------------------------ +# Running the test suite with ${shell} +# +EOF + + SHUNIT_SHELL=${shell} # pass shell onto tests + shell_name=`basename ${shell}` + shell_version=`versions_shellVersion "${shell}"` + + echo "shell name: ${shell_name}" + echo "shell version: ${shell_version}" + + # execute the tests + for suite in ${tests}; do + suiteName=`expr "${suite}" : "${PREFIX}\(.*\).sh"` + echo + echo "--- Executing the '${suiteName}' test suite ---" + ( exec ${shell} ./${suite} 2>&1; ) + done +done diff --git a/test/shunit/shunit2_test_asserts.sh b/test/shunit/shunit2_test_asserts.sh new file mode 100755 index 0000000..1f8040d --- /dev/null +++ b/test/shunit/shunit2_test_asserts.sh @@ -0,0 +1,209 @@ +#! /bin/sh +# $Id: shunit2_test_asserts.sh 312 2011-03-14 22:41:29Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# +# Copyright 2008 Kate Ward. All Rights Reserved. +# Released under the LGPL (GNU Lesser General Public License) +# +# Author: kate.ward@forestent.com (Kate Ward) +# +# shUnit2 unit test for assert functions + +# load test helpers +. ./shunit2_test_helpers + +#------------------------------------------------------------------------------ +# suite tests +# + +commonEqualsSame() +{ + fn=$1 + + ( ${fn} 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'equal' $? "${stdoutF}" "${stderrF}" + + ( ${fn} "${MSG}" 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'equal; with msg' $? "${stdoutF}" "${stderrF}" + + ( ${fn} 'abc def' 'abc def' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'equal with spaces' $? "${stdoutF}" "${stderrF}" + + ( ${fn} 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'not equal' $? "${stdoutF}" "${stderrF}" + + ( ${fn} '' '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'null values' $? "${stdoutF}" "${stderrF}" + + ( ${fn} arg1 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too few arguments' $? "${stdoutF}" "${stderrF}" + + ( ${fn} arg1 arg2 arg3 arg4 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +commonNotEqualsSame() +{ + fn=$1 + + ( ${fn} 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'not same' $? "${stdoutF}" "${stderrF}" + + ( ${fn} "${MSG}" 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'not same, with msg' $? "${stdoutF}" "${stderrF}" + + ( ${fn} 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'same' $? "${stdoutF}" "${stderrF}" + + ( ${fn} '' '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'null values' $? "${stdoutF}" "${stderrF}" + + ( ${fn} arg1 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too few arguments' $? "${stdoutF}" "${stderrF}" + + ( ${fn} arg1 arg2 arg3 arg4 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +testAssertEquals() +{ + commonEqualsSame 'assertEquals' +} + +testAssertNotEquals() +{ + commonNotEqualsSame 'assertNotEquals' +} + +testAssertSame() +{ + commonEqualsSame 'assertSame' +} + +testAssertNotSame() +{ + commonNotEqualsSame 'assertNotSame' +} + +testAssertNull() +{ + ( assertNull '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'null' $? "${stdoutF}" "${stderrF}" + + ( assertNull "${MSG}" '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'null, with msg' $? "${stdoutF}" "${stderrF}" + + ( assertNull 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'not null' $? "${stdoutF}" "${stderrF}" + + ( assertNull >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too few arguments' $? "${stdoutF}" "${stderrF}" + + ( assertNull arg1 arg2 arg3 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +testAssertNotNull() +{ + ( assertNotNull 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'not null' $? "${stdoutF}" "${stderrF}" + + ( assertNotNull "${MSG}" 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'not null, with msg' $? "${stdoutF}" "${stderrF}" + + ( assertNotNull 'x"b' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'not null, with double-quote' $? \ + "${stdoutF}" "${stderrF}" + + ( assertNotNull "x'b" >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'not null, with single-quote' $? \ + "${stdoutF}" "${stderrF}" + + ( assertNotNull 'x$b' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'not null, with dollar' $? \ + "${stdoutF}" "${stderrF}" + + ( assertNotNull 'x`b' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'not null, with backtick' $? \ + "${stdoutF}" "${stderrF}" + + ( assertNotNull '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'null' $? "${stdoutF}" "${stderrF}" + + # there is no test for too few arguments as $1 might actually be null + + ( assertNotNull arg1 arg2 arg3 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +testAssertTrue() +{ + ( assertTrue 0 >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'true' $? "${stdoutF}" "${stderrF}" + + ( assertTrue "${MSG}" 0 >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'true, with msg' $? "${stdoutF}" "${stderrF}" + + ( assertTrue '[ 0 -eq 0 ]' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'true condition' $? "${stdoutF}" "${stderrF}" + + ( assertTrue 1 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'false' $? "${stdoutF}" "${stderrF}" + + ( assertTrue '[ 0 -eq 1 ]' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'false condition' $? "${stdoutF}" "${stderrF}" + + ( assertTrue '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'null' $? "${stdoutF}" "${stderrF}" + + ( assertTrue >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too few arguments' $? "${stdoutF}" "${stderrF}" + + ( assertTrue arg1 arg2 arg3 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +testAssertFalse() +{ + ( assertFalse 1 >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'false' $? "${stdoutF}" "${stderrF}" + + ( assertFalse "${MSG}" 1 >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'false, with msg' $? "${stdoutF}" "${stderrF}" + + ( assertFalse '[ 0 -eq 1 ]' >"${stdoutF}" 2>"${stderrF}" ) + th_assertTrueWithNoOutput 'false condition' $? "${stdoutF}" "${stderrF}" + + ( assertFalse 0 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'true' $? "${stdoutF}" "${stderrF}" + + ( assertFalse '[ 0 -eq 0 ]' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'true condition' $? "${stdoutF}" "${stderrF}" + + ( assertFalse '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'true condition' $? "${stdoutF}" "${stderrF}" + + ( assertFalse >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too few arguments' $? "${stdoutF}" "${stderrF}" + + ( assertFalse arg1 arg2 arg3 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +#------------------------------------------------------------------------------ +# suite functions +# + +oneTimeSetUp() +{ + tmpDir="${__shunit_tmpDir}/output" + mkdir "${tmpDir}" + stdoutF="${tmpDir}/stdout" + stderrF="${tmpDir}/stderr" + + MSG='This is a test message' +} + +# load and run shUnit2 +[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 +. ${TH_SHUNIT} diff --git a/test/shunit/shunit2_test_failures.sh b/test/shunit/shunit2_test_failures.sh new file mode 100755 index 0000000..4aec943 --- /dev/null +++ b/test/shunit/shunit2_test_failures.sh @@ -0,0 +1,89 @@ +#! /bin/sh +# $Id: shunit2_test_failures.sh 286 2008-11-24 21:42:34Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# +# Copyright 2008 Kate Ward. All Rights Reserved. +# Released under the LGPL (GNU Lesser General Public License) +# +# Author: kate.ward@forestent.com (Kate Ward) +# +# shUnit2 unit test for failure functions + +# load common unit-test functions +. ./shunit2_test_helpers + +#----------------------------------------------------------------------------- +# suite tests +# + +testFail() +{ + ( fail >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'fail' $? "${stdoutF}" "${stderrF}" + + ( fail "${MSG}" >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'fail with msg' $? "${stdoutF}" "${stderrF}" + + ( fail arg1 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +testFailNotEquals() +{ + ( failNotEquals 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'same' $? "${stdoutF}" "${stderrF}" + + ( failNotEquals "${MSG}" 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'same with msg' $? "${stdoutF}" "${stderrF}" + + ( failNotEquals 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'not same' $? "${stdoutF}" "${stderrF}" + + ( failNotEquals '' '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'null values' $? "${stdoutF}" "${stderrF}" + + ( failNotEquals >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too few arguments' $? "${stdoutF}" "${stderrF}" + + ( failNotEquals arg1 arg2 arg3 arg4 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +testFailSame() +{ + ( failSame 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'same' $? "${stdoutF}" "${stderrF}" + + ( failSame "${MSG}" 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'same with msg' $? "${stdoutF}" "${stderrF}" + + ( failSame 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'not same' $? "${stdoutF}" "${stderrF}" + + ( failSame '' '' >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithOutput 'null values' $? "${stdoutF}" "${stderrF}" + + ( failSame >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too few arguments' $? "${stdoutF}" "${stderrF}" + + ( failSame arg1 arg2 arg3 arg4 >"${stdoutF}" 2>"${stderrF}" ) + th_assertFalseWithError 'too many arguments' $? "${stdoutF}" "${stderrF}" +} + +#----------------------------------------------------------------------------- +# suite functions +# + +oneTimeSetUp() +{ + tmpDir="${__shunit_tmpDir}/output" + mkdir "${tmpDir}" + stdoutF="${tmpDir}/stdout" + stderrF="${tmpDir}/stderr" + + MSG='This is a test message' +} + +# load and run shUnit2 +[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 +. ${TH_SHUNIT} diff --git a/test/shunit/shunit2_test_helpers b/test/shunit/shunit2_test_helpers new file mode 100644 index 0000000..82a0eef --- /dev/null +++ b/test/shunit/shunit2_test_helpers @@ -0,0 +1,177 @@ +# $Id: shunit2_test_helpers 286 2008-11-24 21:42:34Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# +# Copyright 2008 Kate Ward. All Rights Reserved. +# Released under the LGPL (GNU Lesser General Public License) +# +# Author: kate.ward@forestent.com (Kate Ward) +# +# shUnit2 unit test common functions + +# treat unset variables as an error when performing parameter expansion +set -u + +# set shwordsplit for zsh +[ -n "${ZSH_VERSION:-}" ] && setopt shwordsplit + +# +# constants +# + +# path to shUnit2 library. can be overridden by setting SHUNIT_INC +TH_SHUNIT=${SHUNIT_INC:-./shunit2} + +# configure debugging. set the DEBUG environment variable to any +# non-empty value to enable debug output, or TRACE to enable trace +# output. +TRACE=${TRACE:+'th_trace '} +[ -n "${TRACE}" ] && DEBUG=1 +[ -z "${TRACE}" ] && TRACE=':' + +DEBUG=${DEBUG:+'th_debug '} +[ -z "${DEBUG}" ] && DEBUG=':' + +# +# variables +# + +th_RANDOM=0 + +# +# functions +# + +# message functions +th_trace() { echo "${MY_NAME}:TRACE $@" >&2; } +th_debug() { echo "${MY_NAME}:DEBUG $@" >&2; } +th_info() { echo "${MY_NAME}:INFO $@" >&2; } +th_warn() { echo "${MY_NAME}:WARN $@" >&2; } +th_error() { echo "${MY_NAME}:ERROR $@" >&2; } +th_fatal() { echo "${MY_NAME}:FATAL $@" >&2; } + +# output subtest name +th_subtest() { echo " $@" >&2; } + +# generate a random number +th_generateRandom() +{ + tfgr_random=${th_RANDOM} + + while [ "${tfgr_random}" = "${th_RANDOM}" ]; do + if [ -n "${RANDOM:-}" ]; then + # $RANDOM works + tfgr_random=${RANDOM}${RANDOM}${RANDOM}$$ + elif [ -r '/dev/urandom' ]; then + tfgr_random=`od -vAn -N4 -tu4 </dev/urandom |sed 's/^[^0-9]*//'` + else + tfgr_date=`date '+%H%M%S'` + tfgr_random=`expr ${tfgr_date} \* $$` + unset tfgr_date + fi + [ "${tfgr_random}" = "${th_RANDOM}" ] && sleep 1 + done + + th_RANDOM=${tfgr_random} + unset tfgr_random +} + +# this section returns the data section from the specified section of a file. a +# datasection is defined by a [header], one or more lines of data, and then a +# blank line. +th_getDataSect() +{ + th_sgrep "\\[$1\\]" "$2" |sed '1d' +} + +# this function greps a section from a file. a section is defined as a group of +# lines preceeded and followed by blank lines. +th_sgrep() +{ + th_pattern_=$1 + shift + + sed -e '/./{H;$!d;}' -e "x;/${th_pattern_}/"'!d;' $@ |sed '1d' + + unset th_pattern_ +} + +# Custom assert that checks for true return value (0), and no output to STDOUT +# or STDERR. If a non-zero return value is encountered, the output of STDERR +# will be output. +# +# Args: +# th_test_: string: name of the subtest +# th_rtrn_: integer: the return value of the subtest performed +# th_stdout_: string: filename where stdout was redirected to +# th_stderr_: string: filename where stderr was redirected to +th_assertTrueWithNoOutput() +{ + th_test_=$1 + th_rtrn_=$2 + th_stdout_=$3 + th_stderr_=$4 + + assertTrue "${th_test_}; expected return value of zero" ${th_rtrn_} + [ ${th_rtrn_} -ne ${SHUNIT_TRUE} ] && cat "${th_stderr_}" + assertFalse "${th_test_}; expected no output to STDOUT" \ + "[ -s '${th_stdout_}' ]" + assertFalse "${th_test_}; expected no output to STDERR" \ + "[ -s '${th_stderr_}' ]" + + unset th_test_ th_rtrn_ th_stdout_ th_stderr_ +} + +# Custom assert that checks for non-zero return value, output to STDOUT, but no +# output to STDERR. +# +# Args: +# th_test_: string: name of the subtest +# th_rtrn_: integer: the return value of the subtest performed +# th_stdout_: string: filename where stdout was redirected to +# th_stderr_: string: filename where stderr was redirected to +th_assertFalseWithOutput() +{ + th_test_=$1 + th_rtrn_=$2 + th_stdout_=$3 + th_stderr_=$4 + + assertFalse "${th_test_}; expected non-zero return value" ${th_rtrn_} + assertTrue "${th_test_}; expected output to STDOUT" \ + "[ -s '${th_stdout_}' ]" + assertFalse "${th_test_}; expected no output to STDERR" \ + "[ -s '${th_stderr_}' ]" + + unset th_test_ th_rtrn_ th_stdout_ th_stderr_ +} + +# Custom assert that checks for non-zero return value, no output to STDOUT, but +# output to STDERR. +# +# Args: +# th_test_: string: name of the subtest +# th_rtrn_: integer: the return value of the subtest performed +# th_stdout_: string: filename where stdout was redirected to +# th_stderr_: string: filename where stderr was redirected to +th_assertFalseWithError() +{ + th_test_=$1 + th_rtrn_=$2 + th_stdout_=$3 + th_stderr_=$4 + + assertFalse "${th_test_}; expected non-zero return value" ${th_rtrn_} + assertFalse "${th_test_}; expected no output to STDOUT" \ + "[ -s '${th_stdout_}' ]" + assertTrue "${th_test_}; expected output to STDERR" \ + "[ -s '${th_stderr_}' ]" + + unset th_test_ th_rtrn_ th_stdout_ th_stderr_ +} + +# +# main +# + +${TRACE} 'trace output enabled' +${DEBUG} 'debug output enabled' diff --git a/test/shunit/shunit2_test_macros.sh b/test/shunit/shunit2_test_macros.sh new file mode 100755 index 0000000..94fdbed --- /dev/null +++ b/test/shunit/shunit2_test_macros.sh @@ -0,0 +1,249 @@ +#! /bin/sh +# $Id: shunit2_test_macros.sh 299 2010-05-03 12:44:20Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# +# Copyright 2008 Kate Ward. All Rights Reserved. +# Released under the LGPL (GNU Lesser General Public License) +# Author: kate.ward@forestent.com (Kate Ward) +# +# shUnit2 unit test for macros. + +# load test helpers +. ./shunit2_test_helpers + +#------------------------------------------------------------------------------ +# suite tests +# + +testAssertEquals() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_ASSERT_EQUALS_} 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_EQUALS_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_ASSERT_EQUALS_} '"some msg"' 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_EQUALS_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testAssertNotEquals() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_ASSERT_NOT_EQUALS_} 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_NOT_EQUALS_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_ASSERT_NOT_EQUALS_} '"some msg"' 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_NOT_EQUALS_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testSame() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_ASSERT_SAME_} 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_SAME_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_ASSERT_SAME_} '"some msg"' 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_SAME_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testNotSame() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_ASSERT_NOT_SAME_} 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_NOT_SAME_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_ASSERT_NOT_SAME_} '"some msg"' 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_NOT_SAME_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testNull() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_ASSERT_NULL_} 'x' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_NULL_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_ASSERT_NULL_} '"some msg"' 'x' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_NULL_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testNotNull() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_ASSERT_NOT_NULL_} '' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_NOT_NULL_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_ASSERT_NOT_NULL_} '"some msg"' '""' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_NOT_NULL_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stdoutF}" "${stderrF}" >&2 +} + +testAssertTrue() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_ASSERT_TRUE_} ${SHUNIT_FALSE} >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_TRUE_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + + ( ${_ASSERT_TRUE_} '"some msg"' ${SHUNIT_FALSE} >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_TRUE_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testAssertFalse() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_ASSERT_FALSE_} ${SHUNIT_TRUE} >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_FALSE_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_ASSERT_FALSE_} '"some msg"' ${SHUNIT_TRUE} >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_ASSERT_FALSE_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testFail() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_FAIL_} >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_FAIL_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_FAIL_} '"some msg"' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_FAIL_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testFailNotEquals() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_FAIL_NOT_EQUALS_} 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_FAIL_NOT_EQUALS_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_FAIL_NOT_EQUALS_} '"some msg"' 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_FAIL_NOT_EQUALS_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testFailSame() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_FAIL_SAME_} 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_FAIL_SAME_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_FAIL_SAME_} '"some msg"' 'x' 'x' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_FAIL_SAME_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testFailNotSame() +{ + # start skipping if LINENO not available + [ -z "${LINENO:-}" ] && startSkipping + + ( ${_FAIL_NOT_SAME_} 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_FAIL_NOT_SAME_ failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 + + ( ${_FAIL_NOT_SAME_} '"some msg"' 'x' 'y' >"${stdoutF}" 2>"${stderrF}" ) + grep '^ASSERT:\[[0-9]*\] *' "${stdoutF}" >/dev/null + rtrn=$? + assertTrue '_FAIL_NOT_SAME_ w/ msg failure' ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +#------------------------------------------------------------------------------ +# suite functions +# + +oneTimeSetUp() +{ + tmpDir="${__shunit_tmpDir}/output" + mkdir "${tmpDir}" + stdoutF="${tmpDir}/stdout" + stderrF="${tmpDir}/stderr" +} + +# load and run shUnit2 +[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 +. ${TH_SHUNIT} diff --git a/test/shunit/shunit2_test_misc.sh b/test/shunit/shunit2_test_misc.sh new file mode 100755 index 0000000..e3be229 --- /dev/null +++ b/test/shunit/shunit2_test_misc.sh @@ -0,0 +1,165 @@ +#! /bin/sh +# $Id: shunit2_test_misc.sh 322 2011-04-24 00:09:45Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# +# Copyright 2008 Kate Ward. All Rights Reserved. +# Released under the LGPL (GNU Lesser General Public License) +# +# Author: kate.ward@forestent.com (Kate Ward) +# +# shUnit2 unit tests of miscellaneous things + +# load test helpers +. ./shunit2_test_helpers + +#------------------------------------------------------------------------------ +# suite tests +# + +# Note: the test script is prefixed with '#' chars so that shUnit2 does not +# incorrectly interpret the embedded functions as real functions. +testUnboundVariable() +{ + sed 's/^#//' >"${unittestF}" <<EOF +## treat unset variables as an error when performing parameter expansion +#set -u +# +#boom() { x=\$1; } # this function goes boom if no parameters are passed! +#test_boom() +#{ +# assertEquals 1 1 +# boom # No parameter given +# assertEquals 0 \$? +#} +#. ${TH_SHUNIT} +EOF + ( exec ${SHUNIT_SHELL:-sh} "${unittestF}" >"${stdoutF}" 2>"${stderrF}" ) + assertFalse 'expected a non-zero exit value' $? + grep '^ASSERT:Unknown failure' "${stdoutF}" >/dev/null + assertTrue 'assert message was not generated' $? + grep '^Ran [0-9]* test' "${stdoutF}" >/dev/null + assertTrue 'test count message was not generated' $? + grep '^FAILED' "${stdoutF}" >/dev/null + assertTrue 'failure message was not generated' $? +} + +testIssue7() +{ + ( assertEquals 'Some message.' 1 2 >"${stdoutF}" 2>"${stderrF}" ) + diff "${stdoutF}" - >/dev/null <<EOF +ASSERT:Some message. expected:<1> but was:<2> +EOF + rtrn=$? + assertEquals ${SHUNIT_TRUE} ${rtrn} + [ ${rtrn} -ne ${SHUNIT_TRUE} ] && cat "${stderrF}" >&2 +} + +testPrepForSourcing() +{ + assertEquals '/abc' `_shunit_prepForSourcing '/abc'` + assertEquals './abc' `_shunit_prepForSourcing './abc'` + assertEquals './abc' `_shunit_prepForSourcing 'abc'` +} + +testEscapeCharInStr() +{ + actual=`_shunit_escapeCharInStr '\' ''` + assertEquals '' "${actual}" + assertEquals 'abc\\' `_shunit_escapeCharInStr '\' 'abc\'` + assertEquals 'abc\\def' `_shunit_escapeCharInStr '\' 'abc\def'` + assertEquals '\\def' `_shunit_escapeCharInStr '\' '\def'` + + actual=`_shunit_escapeCharInStr '"' ''` + assertEquals '' "${actual}" + assertEquals 'abc\"' `_shunit_escapeCharInStr '"' 'abc"'` + assertEquals 'abc\"def' `_shunit_escapeCharInStr '"' 'abc"def'` + assertEquals '\"def' `_shunit_escapeCharInStr '"' '"def'` + + actual=`_shunit_escapeCharInStr '$' ''` + assertEquals '' "${actual}" + assertEquals 'abc\$' `_shunit_escapeCharInStr '$' 'abc$'` + assertEquals 'abc\$def' `_shunit_escapeCharInStr '$' 'abc$def'` + assertEquals '\$def' `_shunit_escapeCharInStr '$' '$def'` + +# actual=`_shunit_escapeCharInStr "'" ''` +# assertEquals '' "${actual}" +# assertEquals "abc\\'" `_shunit_escapeCharInStr "'" "abc'"` +# assertEquals "abc\\'def" `_shunit_escapeCharInStr "'" "abc'def"` +# assertEquals "\\'def" `_shunit_escapeCharInStr "'" "'def"` + +# # must put the backtick in a variable so the shell doesn't misinterpret it +# # while inside a backticked sequence (e.g. `echo '`'` would fail). +# backtick='`' +# actual=`_shunit_escapeCharInStr ${backtick} ''` +# assertEquals '' "${actual}" +# assertEquals '\`abc' \ +# `_shunit_escapeCharInStr "${backtick}" ${backtick}'abc'` +# assertEquals 'abc\`' \ +# `_shunit_escapeCharInStr "${backtick}" 'abc'${backtick}` +# assertEquals 'abc\`def' \ +# `_shunit_escapeCharInStr "${backtick}" 'abc'${backtick}'def'` +} + +testEscapeCharInStr_specialChars() +{ + # make sure our forward slash doesn't upset sed + assertEquals '/' `_shunit_escapeCharInStr '\' '/'` + + # some shells escape these differently + #assertEquals '\\a' `_shunit_escapeCharInStr '\' '\a'` + #assertEquals '\\b' `_shunit_escapeCharInStr '\' '\b'` +} + +# Test the various ways of declaring functions. +# +# Prefixing (then stripping) with comment symbol so these functions aren't +# treated as real functions by shUnit2. +testExtractTestFunctions() +{ + f="${tmpD}/extract_test_functions" + sed 's/^#//' <<EOF >"${f}" +#testABC() { echo 'ABC'; } +#test_def() { +# echo 'def' +#} +#testG3 () +#{ +# echo 'G3' +#} +#function test4() { echo '4'; } +# test5() { echo '5'; } +#some_test_function() { echo 'some func'; } +#func_with_test_vars() { +# testVariable=1234 +#} +EOF + + actual=`_shunit_extractTestFunctions "${f}"` + assertEquals 'testABC test_def testG3 test4 test5' "${actual}" +} + +#------------------------------------------------------------------------------ +# suite functions +# + +setUp() +{ + for f in ${expectedF} ${stdoutF} ${stderrF}; do + cp /dev/null ${f} + done + rm -fr "${tmpD}" + mkdir "${tmpD}" +} + +oneTimeSetUp() +{ + tmpD="${SHUNIT_TMPDIR}/tmp" + expectedF="${SHUNIT_TMPDIR}/expected" + stdoutF="${SHUNIT_TMPDIR}/stdout" + stderrF="${SHUNIT_TMPDIR}/stderr" + unittestF="${SHUNIT_TMPDIR}/unittest" +} + +# load and run shUnit2 +[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 +. ${TH_SHUNIT} diff --git a/test/shunit/shunit2_test_standalone.sh b/test/shunit/shunit2_test_standalone.sh new file mode 100755 index 0000000..6df64b3 --- /dev/null +++ b/test/shunit/shunit2_test_standalone.sh @@ -0,0 +1,41 @@ +#! /bin/sh +# $Id: shunit2_test_standalone.sh 303 2010-05-03 13:11:27Z kate.ward@forestent.com $ +# vim:et:ft=sh:sts=2:sw=2 +# +# Copyright 2010 Kate Ward. All Rights Reserved. +# Released under the LGPL (GNU Lesser General Public License) +# Author: kate.ward@forestent.com (Kate Ward) +# +# shUnit2 unit test for standalone operation. +# +# This unit test is purely to test that calling shunit2 directly, while passing +# the name of a unit test script, works. When run, this script determines if it +# is running as a standalone program, and calls main() if it is. + +ARGV0=`basename "$0"` + +# load test helpers +. ./shunit2_test_helpers + +#------------------------------------------------------------------------------ +# suite tests +# + +testStandalone() +{ + assertTrue ${SHUNIT_TRUE} +} + +#------------------------------------------------------------------------------ +# main +# + +main() +{ + ${TH_SHUNIT} "${ARGV0}" +} + +# are we running as a standalone? +if [ "${ARGV0}" = 'shunit2_test_standalone.sh' ]; then + if [ $# -gt 0 ]; then main "$@"; else main; fi +fi diff --git a/test/test-branches.sh b/test/test-branches.sh new file mode 100755 index 0000000..ce779b3 --- /dev/null +++ b/test/test-branches.sh @@ -0,0 +1,110 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +tmpfile="" + +cd_to_tmp() { + tmpfile="/tmp/git-prompt-tests-$(time_now)" + mkdir -p "$tmpfile" + cd "$tmpfile" +} + +rm_tmp() { + cd $scriptDir + rm -rf /tmp/git-prompt-tests* +} + +test_branch_name_in_repo() { + cd_to_tmp + git init --quiet + git checkout -b foo --quiet + assertEquals "foo" "$(branch_name)" + + git checkout -b bar --quiet + assertEquals "bar" "$(branch_name)" + + git checkout -b baz --quiet + assertEquals "baz" "$(branch_name)" + + rm_tmp +} + +test_branch_name_not_in_repo() { + cd_to_tmp + assertEquals "" "$(branch_name)" + rm_tmp +} + +test_detached_from_branch() { + cd_to_tmp + git init --quiet + assertEquals "master" "$(branch_name)" + + touch README + git add . + git commit -m "initial commit" --quiet + + touch foo + git add . + git commit -m "foo" --quiet + + git checkout --quiet HEAD^ >/dev/null + sha="$(commit_short_sha)" + + assertNotEquals "master" "$(branch_name)" + assertEquals "$sha" "$(branch_ref)" + assertEquals "detached@$sha" "$(zsh_readable_branch_name)" + assertEquals "detached@$sha" "$(bash_readable_branch_name)" + assertEquals "detached@$sha" "$(readable_branch_name)" + + rm_tmp +} + +test_branch_name_returns_error() { + cd_to_tmp + git init --quiet + + touch README + git add . + git commit -m "initial commit" --quiet + + touch foo + git add . + git commit -m "foo" --quiet + + git checkout --quiet HEAD^ >/dev/null + + retcode="$(branch_name; echo $?)" + assertEquals "1" "$retcode" + rm_tmp +} + +test_remote_branch_name_quiet_when_not_in_repo() { + cd_to_tmp + + debug_output="$( + { + output="$( + remote_branch_name; + )" + } 2>&1 + echo "$output" + )" + + usages="$(echo "$debug_output" | grep -E "(usage|fatal):" | wc -l)" + + echo "$debug_output" + + if [[ $OSTYPE == darwin* ]];then + expected=" 0" + else + expected="0" + fi; + assertEquals "$expected" "$usages" + + rm_tmp +} + +. ./shunit/shunit2 diff --git a/test/test-colors.sh b/test/test-colors.sh new file mode 100755 index 0000000..b6f6688 --- /dev/null +++ b/test/test-colors.sh @@ -0,0 +1,493 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +cd_to_tmp() { + tmpfile="/tmp/git-prompt-tests-$(time_now)$1" + mkdir -p "$tmpfile" + cd "$tmpfile" +} + +rm_tmp() { + cd $scriptDir + rm -rf /tmp/git-prompt-tests* +} + +mock_zsh_colors() { + fg_bold[green]=1 + fg_bold[red]=2 + fg_bold[yellow]=3 + fg_bold[white]=4 + + reset_color=0 +} + +test_no_rcfile_bash() { + reset_env_vars + prepare_bash_colors + + assertEquals "$COLOR_REMOTE_AHEAD" "\x01\033[1;32m\x02" + assertEquals "$COLOR_REMOTE_BEHIND" "\x01\033[1;31m\x02" + assertEquals "$COLOR_REMOTE_DIVERGED" "\x01\033[1;33m\x02" + assertEquals "$COLOR_REMOTE_NOT_UPSTREAM" "\x01\033[1;31m\x02" + + assertEquals "$COLOR_LOCAL_AHEAD" "\x01\033[1;32m\x02" + assertEquals "$COLOR_LOCAL_BEHIND" "\x01\033[1;31m\x02" + assertEquals "$COLOR_LOCAL_DIVERGED" "\x01\033[1;33m\x02" + + assertEquals "$COLOR_CHANGES_STAGED" "\x01\033[1;32m\x02" + assertEquals "$COLOR_CHANGES_UNSTAGED" "\x01\033[1;31m\x02" + assertEquals "$COLOR_CHANGES_CONFLICTED" "\x01\033[1;33m\x02" + assertEquals "$COLOR_CHANGES_UNTRACKED" "\x01\033[1;37m\x02" + + assertEquals "$RESET_COLOR_LOCAL" "\x01\033[0m\x02" + assertEquals "$RESET_COLOR_REMOTE" "\x01\033[0m\x02" + assertEquals "$RESET_COLOR_CHANGES" "\x01\033[0m\x02" +} + +test_no_rcfile_zsh() { + reset_env_vars + mock_zsh_colors + prepare_zsh_colors + + assertEquals "$COLOR_REMOTE_AHEAD" "%{$fg_bold[green]%}" + assertEquals "$COLOR_REMOTE_BEHIND" "%{$fg_bold[red]%}" + assertEquals "$COLOR_REMOTE_DIVERGED" "%{$fg_bold[yellow]%}" + assertEquals "$COLOR_REMOTE_NOT_UPSTREAM" "%{$fg_bold[red]%}" + + assertEquals "$COLOR_LOCAL_AHEAD" "%{$fg_bold[green]%}" + assertEquals "$COLOR_LOCAL_BEHIND" "%{$fg_bold[red]%}" + assertEquals "$COLOR_LOCAL_DIVERGED" "%{$fg_bold[yellow]%}" + + assertEquals "$COLOR_CHANGES_STAGED" "%{$fg_bold[green]%}" + assertEquals "$COLOR_CHANGES_UNSTAGED" "%{$fg_bold[red]%}" + assertEquals "$COLOR_CHANGES_CONFLICTED" "%{$fg_bold[yellow]%}" + assertEquals "$COLOR_CHANGES_UNTRACKED" "%{$fg_bold[white]%}" + + assertEquals "$RESET_COLOR_LOCAL" "%{$reset_color%}" + assertEquals "$RESET_COLOR_REMOTE" "%{$reset_color%}" + assertEquals "$RESET_COLOR_CHANGES" "%{$reset_color%}" +} + +set_env_vars() { + export GIT_RADAR_COLOR_REMOTE_AHEAD="remote-ahead" + export GIT_RADAR_COLOR_REMOTE_BEHIND="remote-behind" + export GIT_RADAR_COLOR_REMOTE_DIVERGED="remote-diverged" + export GIT_RADAR_COLOR_REMOTE_NOT_UPSTREAM="not-upstream" + + export GIT_RADAR_COLOR_LOCAL_AHEAD="local-ahead" + export GIT_RADAR_COLOR_LOCAL_BEHIND="local-behind" + export GIT_RADAR_COLOR_LOCAL_DIVERGED="local-diverged" + + export GIT_RADAR_COLOR_CHANGES_STAGED="changes-staged" + export GIT_RADAR_COLOR_CHANGES_UNSTAGED="changes-unstaged" + export GIT_RADAR_COLOR_CHANGES_CONFLICTED="changes-conflicted" + export GIT_RADAR_COLOR_CHANGES_UNTRACKED="changes-untracked" + + export GIT_RADAR_COLOR_BRANCH="branch-color" + export GIT_RADAR_MASTER_SYMBOL="m" + + export GIT_RADAR_COLOR_LOCAL_RESET="local-reset" + export GIT_RADAR_COLOR_REMOTE_RESET="remote-reset" + export GIT_RADAR_COLOR_CHANGES_RESET="change-reset" + export GIT_RADAR_COLOR_BRANCH_RESET="branch-reset" +} + +reset_env_vars() { + export GIT_RADAR_COLOR_REMOTE_AHEAD="" + export GIT_RADAR_COLOR_REMOTE_BEHIND="" + export GIT_RADAR_COLOR_REMOTE_DIVERGED="" + export GIT_RADAR_COLOR_REMOTE_NOT_UPSTREAM="" + + export GIT_RADAR_COLOR_LOCAL_AHEAD="" + export GIT_RADAR_COLOR_LOCAL_BEHIND="" + export GIT_RADAR_COLOR_LOCAL_DIVERGED="" + + export GIT_RADAR_COLOR_CHANGES_STAGED="" + export GIT_RADAR_COLOR_CHANGES_UNSTAGED="" + export GIT_RADAR_COLOR_CHANGES_CONFLICTED="" + export GIT_RADAR_COLOR_CHANGES_UNTRACKED="" + + export GIT_RADAR_COLOR_BRANCH="" + export GIT_RADAR_MASTER_SYMBOL="" + + export GIT_RADAR_COLOR_LOCAL_RESET="" + export GIT_RADAR_COLOR_REMOTE_RESET="" + export GIT_RADAR_COLOR_CHANGES_RESET="" + export GIT_RADAR_COLOR_BRANCH_RESET="" +} + +create_rc_file() { + echo 'GIT_RADAR_COLOR_REMOTE_AHEAD="remote-ahead"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_REMOTE_BEHIND="remote-behind"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_REMOTE_DIVERGED="remote-diverged"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_REMOTE_NOT_UPSTREAM="not-upstream"' >> .gitradarrc$1 + + echo 'GIT_RADAR_COLOR_LOCAL_AHEAD="local-ahead"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_LOCAL_BEHIND="local-behind"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_LOCAL_DIVERGED="local-diverged"' >> .gitradarrc$1 + + echo 'GIT_RADAR_COLOR_CHANGES_STAGED="changes-staged"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_CHANGES_UNSTAGED="changes-unstaged"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_CHANGES_CONFLICTED="changes-conflicted"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_CHANGES_UNTRACKED="changes-untracked"' >> .gitradarrc$1 + + echo 'export GIT_RADAR_COLOR_BRANCH="branch-color"' >> .gitradarrc$1 + echo 'export GIT_RADAR_MASTER_SYMBOL="m"' >> .gitradarrc$1 + + echo 'GIT_RADAR_COLOR_LOCAL_RESET="local-reset"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_REMOTE_RESET="remote-reset"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_CHANGES_RESET="change-reset"' >> .gitradarrc$1 + echo 'GIT_RADAR_COLOR_BRANCH_RESET="branch-reset"' >> .gitradarrc$1 +} + +test_with_rcfile_bash() { + reset_env_vars + cd_to_tmp + + rcfile_path="$(pwd)" + + create_rc_file ".bash" + prepare_bash_colors + + assertEquals "$COLOR_REMOTE_AHEAD" "\x01remote-ahead\x02" + assertEquals "$COLOR_REMOTE_BEHIND" "\x01remote-behind\x02" + assertEquals "$COLOR_REMOTE_DIVERGED" "\x01remote-diverged\x02" + assertEquals "$COLOR_REMOTE_NOT_UPSTREAM" "\x01not-upstream\x02" + + assertEquals "$COLOR_LOCAL_AHEAD" "\x01local-ahead\x02" + assertEquals "$COLOR_LOCAL_BEHIND" "\x01local-behind\x02" + assertEquals "$COLOR_LOCAL_DIVERGED" "\x01local-diverged\x02" + + assertEquals "$COLOR_CHANGES_STAGED" "\x01changes-staged\x02" + assertEquals "$COLOR_CHANGES_UNSTAGED" "\x01changes-unstaged\x02" + assertEquals "$COLOR_CHANGES_CONFLICTED" "\x01changes-conflicted\x02" + assertEquals "$COLOR_CHANGES_UNTRACKED" "\x01changes-untracked\x02" + + assertEquals "$COLOR_BRANCH" "\x01branch-color\x02" + assertEquals "$MASTER_SYMBOL" "m" + + assertEquals "$RESET_COLOR_LOCAL" "\x01local-reset\x02" + assertEquals "$RESET_COLOR_REMOTE" "\x01remote-reset\x02" + assertEquals "$RESET_COLOR_CHANGES" "\x01change-reset\x02" + assertEquals "$RESET_COLOR_BRANCH" "\x01branch-reset\x02" + + rm_tmp +} + +test_with_rcfile_zsh() { + reset_env_vars + cd_to_tmp + + rcfile_path="$(pwd)" + + create_rc_file ".zsh" + mock_zsh_colors + prepare_zsh_colors + + assertEquals "$COLOR_REMOTE_AHEAD" "%{remote-ahead%}" + assertEquals "$COLOR_REMOTE_BEHIND" "%{remote-behind%}" + assertEquals "$COLOR_REMOTE_DIVERGED" "%{remote-diverged%}" + assertEquals "$COLOR_REMOTE_NOT_UPSTREAM" "%{not-upstream%}" + + assertEquals "$COLOR_LOCAL_AHEAD" "%{local-ahead%}" + assertEquals "$COLOR_LOCAL_BEHIND" "%{local-behind%}" + assertEquals "$COLOR_LOCAL_DIVERGED" "%{local-diverged%}" + + assertEquals "$COLOR_CHANGES_STAGED" "%{changes-staged%}" + assertEquals "$COLOR_CHANGES_UNSTAGED" "%{changes-unstaged%}" + assertEquals "$COLOR_CHANGES_CONFLICTED" "%{changes-conflicted%}" + assertEquals "$COLOR_CHANGES_UNTRACKED" "%{changes-untracked%}" + + assertEquals "$COLOR_BRANCH" "%{branch-color%}" + assertEquals "$MASTER_SYMBOL" "m" + + assertEquals "$RESET_COLOR_LOCAL" "%{local-reset%}" + assertEquals "$RESET_COLOR_REMOTE" "%{remote-reset%}" + assertEquals "$RESET_COLOR_CHANGES" "%{change-reset%}" + assertEquals "$RESET_COLOR_BRANCH" "%{branch-reset%}" + + rm_tmp +} + +test_with_env_vars_bash() { + reset_env_vars + set_env_vars + prepare_bash_colors + + assertEquals "$COLOR_REMOTE_AHEAD" "\x01remote-ahead\x02" + assertEquals "$COLOR_REMOTE_BEHIND" "\x01remote-behind\x02" + assertEquals "$COLOR_REMOTE_DIVERGED" "\x01remote-diverged\x02" + assertEquals "$COLOR_REMOTE_NOT_UPSTREAM" "\x01not-upstream\x02" + + assertEquals "$COLOR_LOCAL_AHEAD" "\x01local-ahead\x02" + assertEquals "$COLOR_LOCAL_BEHIND" "\x01local-behind\x02" + assertEquals "$COLOR_LOCAL_DIVERGED" "\x01local-diverged\x02" + + assertEquals "$COLOR_CHANGES_STAGED" "\x01changes-staged\x02" + assertEquals "$COLOR_CHANGES_UNSTAGED" "\x01changes-unstaged\x02" + assertEquals "$COLOR_CHANGES_CONFLICTED" "\x01changes-conflicted\x02" + assertEquals "$COLOR_CHANGES_UNTRACKED" "\x01changes-untracked\x02" + + assertEquals "$COLOR_BRANCH" "\x01branch-color\x02" + assertEquals "$MASTER_SYMBOL" "m" + + assertEquals "$RESET_COLOR_LOCAL" "\x01local-reset\x02" + assertEquals "$RESET_COLOR_REMOTE" "\x01remote-reset\x02" + assertEquals "$RESET_COLOR_CHANGES" "\x01change-reset\x02" + assertEquals "$RESET_COLOR_BRANCH" "\x01branch-reset\x02" +} + +test_with_env_vars_zsh() { + reset_env_vars + set_env_vars + mock_zsh_colors + prepare_zsh_colors + + assertEquals "$COLOR_REMOTE_AHEAD" "%{remote-ahead%}" + assertEquals "$COLOR_REMOTE_BEHIND" "%{remote-behind%}" + assertEquals "$COLOR_REMOTE_DIVERGED" "%{remote-diverged%}" + assertEquals "$COLOR_REMOTE_NOT_UPSTREAM" "%{not-upstream%}" + + assertEquals "$COLOR_LOCAL_AHEAD" "%{local-ahead%}" + assertEquals "$COLOR_LOCAL_BEHIND" "%{local-behind%}" + assertEquals "$COLOR_LOCAL_DIVERGED" "%{local-diverged%}" + + assertEquals "$COLOR_CHANGES_STAGED" "%{changes-staged%}" + assertEquals "$COLOR_CHANGES_UNSTAGED" "%{changes-unstaged%}" + assertEquals "$COLOR_CHANGES_CONFLICTED" "%{changes-conflicted%}" + assertEquals "$COLOR_CHANGES_UNTRACKED" "%{changes-untracked%}" + + assertEquals "$COLOR_BRANCH" "%{branch-color%}" + assertEquals "$MASTER_SYMBOL" "m" + + assertEquals "$RESET_COLOR_LOCAL" "%{local-reset%}" + assertEquals "$RESET_COLOR_REMOTE" "%{remote-reset%}" + assertEquals "$RESET_COLOR_CHANGES" "%{change-reset%}" + assertEquals "$RESET_COLOR_BRANCH" "%{branch-reset%}" +} + +test_bash_colors_local() { + reset_env_vars + set_env_vars + prepare_bash_colors + + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "repo" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + git push --quiet -u origin master >/dev/null + repoLocation="$(pwd)" + + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + + printf -v expected "1\x01local-ahead\x02↑\x01local-reset\x02" + assertEquals "$expected" "$(bash_color_local_commits)" + assertEquals "$expected" "$(color_local_commits)" + + git push --quiet >/dev/null + git reset --hard HEAD^ --quiet >/dev/null + + printf -v expected "1\x01local-behind\x02↓\x01local-reset\x02" + assertEquals "$expected" "$(bash_color_local_commits)" + assertEquals "$expected" "$(color_local_commits)" + + echo "foo" > foo + git add . + git commit -m "new commit" --quiet + + printf -v expected "1\x01local-diverged\x02⇵\x01local-reset\x021" + assertEquals "$expected" "$(bash_color_local_commits)" + assertEquals "$expected" "$(color_local_commits)" + + rm_tmp +} + +test_zsh_colors_local() { + reset_env_vars + set_env_vars + prepare_zsh_colors + + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "repo" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + git push --quiet -u origin master >/dev/null + repoLocation="$(pwd)" + + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + + assertEquals "1%{local-ahead%}↑%{local-reset%}" "$(zsh_color_local_commits)" + + git push --quiet >/dev/null + git reset --hard HEAD^ --quiet >/dev/null + + assertEquals "1%{local-behind%}↓%{local-reset%}" "$(zsh_color_local_commits)" + + echo "foo" > foo + git add . + git commit -m "new commit" --quiet + + assertEquals "1%{local-diverged%}⇵%{local-reset%}1" "$(zsh_color_local_commits)" + + rm_tmp +} + +test_bash_colors_remote() { + reset_env_vars + set_env_vars + prepare_bash_colors + + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "repo" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + git push --quiet -u origin master >/dev/null + repoLocation="$(pwd)" + + git reset --hard HEAD^ --quiet >/dev/null + git checkout -b mybranch --quiet + git push --quiet -u origin mybranch >/dev/null + + printf -v expected "m 1 \x01remote-behind\x02→\x01remote-reset\x02" + assertEquals "$expected" "$(bash_color_remote_commits)" + assertEquals "$expected" "$(color_remote_commits)" + + echo "bar" > bar + git add . + git commit -m "new commit" --quiet + git push --quiet origin mybranch >/dev/null + + printf -v expected "m 1 \x01remote-diverged\x02⇄\x01remote-reset\x02 1" + assertEquals "$expected" "$(bash_color_remote_commits)" + assertEquals "$expected" "$(color_remote_commits)" + + git pull origin master --quiet --ff >/dev/null + git push --quiet >/dev/null + + printf -v expected "m \x01remote-ahead\x02←\x01remote-reset\x02 2" + assertEquals "$expected" "$(bash_color_remote_commits)" + assertEquals "$expected" "$(color_remote_commits)" + + rm_tmp +} + +test_zsh_colors_remote() { + reset_env_vars + set_env_vars + prepare_zsh_colors + + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "repo" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + git push --quiet -u origin master >/dev/null + repoLocation="$(pwd)" + + git reset --hard HEAD^ --quiet >/dev/null + git checkout -b mybranch --quiet + git push --quiet -u origin mybranch >/dev/null + + assertEquals "m 1 %{remote-behind%}→%{remote-reset%}" "$(zsh_color_remote_commits)" + + echo "bar" > bar + git add . + git commit -m "new commit" --quiet + git push --quiet >/dev/null + + assertEquals "m 1 %{remote-diverged%}⇄%{remote-reset%} 1" "$(zsh_color_remote_commits)" + + git pull origin master --quiet --ff >/dev/null + git push --quiet >/dev/null + + assertEquals "m %{remote-ahead%}←%{remote-reset%} 2" "$(zsh_color_remote_commits)" + + rm_tmp +} + +test_bash_colors_changes() { + reset_env_vars + set_env_vars + prepare_bash_colors + + cd_to_tmp + git init --quiet + + touch foo + touch bar + git add bar + echo "bar" > bar + untracked="1\x01changes-untracked\x02?\x01change-reset\x02" + unstaged="1\x01changes-unstaged\x02M\x01change-reset\x02" + staged="1\x01changes-staged\x02A\x01change-reset\x02" + + printf -v expected "$staged $unstaged $untracked" + assertEquals "$expected" "$(bash_color_changes_status)" + assertEquals "$expected" "$(color_changes_status)" + rm_tmp +} + +test_zsh_colors_changes() { + reset_env_vars + set_env_vars + prepare_zsh_colors + + cd_to_tmp + git init --quiet + + touch foo + touch bar + git add bar + echo "bar" > bar + untracked="1%{changes-untracked%}?%{change-reset%}" + unstaged="1%{changes-unstaged%}M%{change-reset%}" + staged="1%{changes-staged%}A%{change-reset%}" + + assertEquals "$staged $unstaged $untracked" "$(zsh_color_changes_status)" + rm_tmp +} + +. ./shunit/shunit2 diff --git a/test/test-commits.sh b/test/test-commits.sh new file mode 100755 index 0000000..4593918 --- /dev/null +++ b/test/test-commits.sh @@ -0,0 +1,436 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +tmpfile="" + +cd_to_tmp() { + tmpfile="/tmp/git-prompt-tests-$(time_now)$1" + mkdir -p "$tmpfile" + cd "$tmpfile" +} + +rm_tmp() { + cd $scriptDir + rm -rf /tmp/git-prompt-tests* +} +test_commits_with_no_commits() { + cd_to_tmp + git init --quiet + + assertEquals "0" "$(commits_ahead_of_remote)" + assertEquals "0" "$(commits_behind_of_remote)" + + rm_tmp +} + +test_commits_behind_no_remote() { + cd_to_tmp + git init --quiet + + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + assertEquals "0" "$(commits_behind_of_remote)" + + rm_tmp +} + +test_commits_ahead_no_remote() { + cd_to_tmp + git init --quiet + + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + assertEquals "0" "$(commits_ahead_of_remote)" + + echo "bar" > bar + git add . + git commit -m "test commit" --quiet + assertEquals "0" "$(commits_ahead_of_remote)" + + rm_tmp +} + +test_commits_ahead_with_remote() { + cd_to_tmp "remote" + git init --quiet + touch README + git add . + git commit -m "initial commit" --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout master --quiet + repoLocation="$(pwd)" + + cd "$remoteLocation" + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + cd "$repoLocation" + git fetch origin --quiet + assertEquals "1" "$(commits_ahead_of_remote)" + + cd "$remoteLocation" + echo "bar" > bar + git add . + git commit -m "test commit" --quiet + cd "$repoLocation" + git fetch origin --quiet + assertEquals "2" "$(commits_ahead_of_remote)" + + rm_tmp +} + +test_commits_ahead_with_remote() { + cd_to_tmp "remote" + git init --quiet + touch README + git add . + git commit -m "initial commit" --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout master --quiet + + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + assertEquals "1" "$(commits_ahead_of_remote)" + + echo "bar" > bar + git add . + git commit -m "test commit" --quiet + assertEquals "2" "$(commits_ahead_of_remote)" + + rm_tmp +} + +test_remote_ahead_master() { + cd_to_tmp "remote" + git init --quiet + touch README + git add . + git commit -m "initial commit" --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout master --quiet + + git checkout -b foo --quiet + git push --quiet -u origin foo >/dev/null + + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + assertEquals "0" "$(remote_ahead_of_master)" + git push --quiet + assertEquals "1" "$(remote_ahead_of_master)" + + echo "bar" > bar + git add . + git commit -m "test commit" --quiet + assertEquals "1" "$(remote_ahead_of_master)" + git push --quiet + assertEquals "2" "$(remote_ahead_of_master)" + + rm_tmp +} + +test_remote_behind_master() { + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + + git push --quiet -u origin master >/dev/null + git reset --quiet --hard HEAD + + git checkout -b foo --quiet + git push --quiet -u origin foo >/dev/null + + assertEquals "0" "$(remote_behind_of_master)" + git checkout master --quiet + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + git push --quiet >/dev/null + git checkout foo --quiet + assertEquals "1" "$(remote_behind_of_master)" + + git checkout master --quiet + echo "bar" > bar + git add . + git commit -m "test commit" --quiet + git push --quiet >/dev/null + git checkout foo --quiet + assertEquals "2" "$(remote_behind_of_master)" + + rm_tmp +} + +test_remote_branch_starts_with_local_branch_name() { + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "local" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + + git push --quiet -u origin master >/dev/null + git reset --quiet --hard HEAD + + git checkout -b foobar --quiet + touch foobarfile + git add foobarfile + git commit -m "added foobar" --quiet + git push --quiet -u origin foobar >/dev/null + + git checkout -b foo --quiet + + assertEquals "0" "$(remote_ahead_of_master)" + assertEquals "0" "$(remote_behind_of_master)" + assertEquals "0" "$(commits_behind_of_remote)" + assertEquals "0" "$(commits_ahead_of_remote)" + + rm_tmp +} +test_remote_branch_ends_with_local_branch_name() { + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "local" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + + git push --quiet -u origin master >/dev/null + git reset --quiet --hard HEAD + + git checkout -b foobar --quiet + touch foobarfile + git add foobarfile + git commit -m "added foobar" --quiet + git push --quiet -u origin foobar >/dev/null + + git checkout -b bar --quiet + + assertEquals "0" "$(remote_ahead_of_master)" + assertEquals "0" "$(remote_behind_of_master)" + assertEquals "0" "$(commits_behind_of_remote)" + assertEquals "0" "$(commits_ahead_of_remote)" + + rm_tmp +} + +test_dont_call_remote_branch_name() { + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + + git push --quiet -u origin master >/dev/null + git reset --quiet --hard HEAD + + git checkout -b foo --quiet + git push --quiet -u origin foo >/dev/null + + remote_branch="$(remote_branch_name)" + + debug_output="$( + { + set -x + output="$( + remote_behind_of_master "$remote_branch"; + remote_ahead_of_master "$remote_branch"; + commits_ahead_of_remote "$remote_branch"; + commits_behind_of_remote "$remote_branch"; + )" + set +x + } 2>&1 + echo "$output" + )" + + #Grep through the output and look for remote_branch_name being called + usages="$(echo "$debug_output" | grep 'remote_branch_name' | wc -l )" + + #wc -l has a weird output + if [[ $OSTYPE == darwin* ]];then + expected=" 0" + else + expected="0" + fi; + assertEquals "$expected" "$usages" + + rm_tmp +} +test_dont_remote_if_remote_is_master() { + cd_to_tmp + git init --quiet + + remote_branch="origin/master" + + debug_output="$( + { + set -x + output="$( + remote_behind_of_master "$remote_branch"; + remote_ahead_of_master "$remote_branch"; + )" + set +x + } 2>&1 + echo "$output" + )" + + usages="$(echo "$debug_output" | grep 'git rev-list' | wc -l )" + + if [[ $OSTYPE == darwin* ]];then + expected=" 0" + else + expected="0" + fi; + assertEquals "$expected" "$usages" + + rm_tmp +} + +test_quiet_if_no_remote_master() { + cd_to_tmp "remote" + git init --quiet + touch README + git add . + git checkout -b foo --quiet + git commit -m "initial commit" --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout foo --quiet + repoLocation="$(pwd)" + + remote_branch="$(remote_branch_name)" + + debug_output="$( + { + output="$( + remote_behind_of_master "$remote_branch"; + )" + } 2>&1 + echo "$output" + )" + + assertEquals "0" "$debug_output" + debug_output="$( + { + output="$( + remote_ahead_of_master "$remote_branch"; + )" + } 2>&1 + echo "$output" + )" + + assertEquals "0" "$debug_output" + + rm_tmp +} + +test_local_commits() { + local up="↑" + local both="⇵" + local down="↓" + + cd_to_tmp "remote" + + assertEquals "" "$(zsh_color_local_commits)" + assertEquals "" "$(bash_color_local_commits)" + assertEquals "" "$(color_local_commits)" + + git init --quiet + touch README + git add . + git commit -m "initial commit" --quiet + remote="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remote + git fetch origin --quiet + git checkout master --quiet + repo="$(pwd)" + + assertEquals "" "$(zsh_color_local_commits)" + assertEquals "" "$(bash_color_local_commits)" + assertEquals "" "$(color_local_commits)" + + cd "$repo" + echo "bar" > bar + git add . + git commit -m "test commit" --quiet + + assertEquals "1$up" "$(zsh_color_local_commits)" + assertEquals "1$up" "$(bash_color_local_commits)" + assertEquals "1$up" "$(color_local_commits)" + + cd "$remote" + echo "foo" > foo + git add . + git commit -m "test commit" --quiet + + cd "$repo" + git fetch origin --quiet + + assertEquals "1${both}1" "$(zsh_color_local_commits)" + assertEquals "1${both}1" "$(bash_color_local_commits)" + assertEquals "1${both}1" "$(color_local_commits)" + + git reset --hard HEAD^ --quiet + + assertEquals "1$down" "$(zsh_color_local_commits)" + assertEquals "1$down" "$(bash_color_local_commits)" + assertEquals "1$down" "$(color_local_commits)" +} + +. ./shunit/shunit2 diff --git a/test/test-directories.sh b/test/test-directories.sh new file mode 100755 index 0000000..d440072 --- /dev/null +++ b/test/test-directories.sh @@ -0,0 +1,95 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +tmpfile="" + +cd_to_tmp() { + tmpfile="/tmp/git-prompt-tests-$(time_now)" + mkdir -p "$tmpfile" + cd "$tmpfile" +} + +rm_tmp() { + cd $scriptDir + rm -rf /tmp/git-prompt-tests* +} + +test_git_root_in_repo() { + cd $scriptDir + local root="$(git_root)" + assertEquals "$scriptDir" "$root" +} + +test_git_root_not_in_repo() { + cd_to_tmp + local root="$(git_root)" + assertEquals "" "$root" + rm_tmp +} + +test_dot_git_location_not_in_repo() { + cd_to_tmp + local filePath="$(dot_git)" + assertEquals "" "$filePath" + rm_tmp +} + +test_dot_git_location_in_repo() { + cd $scriptDir + local filePath="$(dot_git)" + local expected=".git" + assertEquals "$expected" "$filePath" +} + +test_is_repo_not_in_repo() { + cd_to_tmp + assertFalse is_repo + rm_tmp +} + +test_is_repo_in_repo() { + cd $scriptDir + assertTrue is_repo +} + +test_record_timestamp_in_repo() { + cd $scriptDir + record_timestamp + local timestamp="$(timestamp)" + local timenow="$(time_now)" + assertSame "$timenow" "$timestamp" +} + +test_time_to_update_when_timestamp_is_old() { + cd $scriptDir + FETCH_TIME="$((5 * 60))" # Fetch every 5 mins + if [[ $OSTYPE == darwin* ]];then + touch -A "-010000" "$(dot_git)/lastupdatetime" + else + newtimestamp=$(date -d "now -1 hour" +%Y%m%d%H%M) + touch -t $newtimestamp "$(dot_git)/lastupdatetime" + fi; + assertTrue time_to_update +} + +test_not_time_to_update_when_just_recorded() { + cd $scriptDir + FETCH_TIME="$((5 * 60))" # Fetch every 5 mins + record_timestamp + assertFalse time_to_update +} + +test_time_to_update_when_no_timestamp() { + cd_to_tmp + git init --quiet + + FETCH_TIME="$((5 * 60))" # Fetch every 5 mins + time_to_update + assertTrue time_to_update + + rm_tmp +} + +. ./shunit/shunit2 diff --git a/test/test-files.sh b/test/test-files.sh new file mode 100755 index 0000000..fff5144 --- /dev/null +++ b/test/test-files.sh @@ -0,0 +1,274 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +tmpfile="" + +cd_to_tmp() { + tmpfile="/tmp/git-prompt-tests-$(time_now)$1" + mkdir -p "$tmpfile" + cd "$tmpfile" +} + +rm_tmp() { + cd $scriptDir + rm -rf /tmp/git-prompt-tests* +} + +test_untracked_files() { + cd_to_tmp + git init --quiet + + assertEquals "" "$(untracked_status)" + + touch foo + assertEquals "1?" "$(untracked_status)" + + git add --all + assertEquals "" "$(untracked_status)" + + rm_tmp +} + +test_unstaged_modified_files() { + cd_to_tmp + git init --quiet + + assertEquals "" "$(unstaged_status)" + + touch foo + touch bar + git add --all + git commit -m "foo and bar" >/dev/null + + echo "foo" >> foo + assertEquals "1M" "$(unstaged_status)" + + echo "bar" >> bar + assertEquals "2M" "$(unstaged_status)" + + rm_tmp +} + +test_unstaged_deleted_files() { + cd_to_tmp + git init --quiet + + assertEquals "" "$(unstaged_status)" + + touch foo + touch bar + git add --all + git commit -m "foo and bar" >/dev/null + + rm foo + assertEquals "1D" "$(unstaged_status)" + + rm bar + assertEquals "2D" "$(unstaged_status)" + + rm_tmp +} + +test_staged_added_files() { + cd_to_tmp + git init --quiet + + assertEquals "" "$(staged_status)" + + touch foo + git add --all + assertEquals "1A" "$(staged_status)" + + touch bar + git add --all + assertEquals "2A" "$(staged_status)" + + rm_tmp +} + +test_staged_modified_files() { + cd_to_tmp + git init --quiet + + assertEquals "" "$(staged_status)" + + touch foo + touch bar + git add --all + git commit -m "foo and bar" >/dev/null + + echo "foo" >> foo + git add --all + assertEquals "1M" "$(staged_status)" + + echo "bar" >> bar + git add --all + assertEquals "2M" "$(staged_status)" + + rm_tmp +} + +test_staged_deleted_files() { + cd_to_tmp + git init --quiet + + assertEquals "" "$(staged_status)" + + touch foo + touch bar + git add --all + git commit -m "foo and bar" >/dev/null + + rm foo + git add --all + assertEquals "1D" "$(staged_status)" + + rm bar + git add --all + assertEquals "2D" "$(staged_status)" + + rm_tmp +} + +test_staged_renamed_files() { + cd_to_tmp + git init --quiet + + assertEquals "" "$(staged_status)" + + touch foo + touch bar + git add --all + git commit -m "foo and bar" >/dev/null + + mv foo foo2 + git add --all + assertEquals "1R" "$(staged_status)" + + mv bar bar2 + git add --all + assertEquals "2R" "$(staged_status)" + + rm_tmp +} + +test_conflicted_both_changes() { + cd_to_tmp + git init --quiet + + git checkout -b foo --quiet + echo "foo" >> foo + git add --all + git commit -m "foo" --quiet + + git checkout -b foo2 --quiet + echo "bar" >> foo + git add --all + git commit -m "bar" --quiet + + git checkout foo --quiet + echo "foo2" >> foo + git add --all + git commit -m "foo2" --quiet + + assertEquals "" "$(conflicted_status)" + + git merge foo2 >/dev/null + + assertEquals "1B" "$(conflicted_status)" + + rm_tmp +} + +test_conflicted_them_changes() { + cd_to_tmp + git init --quiet + + git checkout -b foo --quiet + echo "foo" >> foo + git add --all + git commit -m "foo" --quiet + + git checkout -b foo2 --quiet + rm foo + git add --all + git commit -m "delete foo" --quiet + + git checkout foo --quiet + echo "foo2" >> foo + git add --all + git commit -m "foo2" --quiet + + assertEquals "" "$(conflicted_status)" + + git merge foo2 >/dev/null + + assertEquals "1T" "$(conflicted_status)" + + rm_tmp +} + +test_conflicted_us_changes() { + cd_to_tmp + git init --quiet + + git checkout -b foo --quiet + echo "foo" >> foo + git add --all + git commit -m "foo" --quiet + + git checkout -b foo2 --quiet + echo "bar" >> foo + git add --all + git commit -m "bar" --quiet + + git checkout foo --quiet + rm foo + git add --all + git commit -m "delete foo" --quiet + + assertEquals "" "$(conflicted_status)" + + git merge foo2 >/dev/null + + assertEquals "1U" "$(conflicted_status)" + + rm_tmp +} + +test_is_dirty() { + cd_to_tmp + + assertFalse "not in repo" is_dirty + + git init --quiet + assertFalse "in repo and clean" is_dirty + + touch foo + assertTrue "untracked files" is_dirty + + mkdir sneakSubDir + cd sneakSubDir + assertTrue "untracked files while in an empty sub dir" is_dirty + + cd ../ + + git add --all + assertTrue "staged addition files" is_dirty + + git commit -m "inital commit" --quiet + + assertFalse "commited and clean" is_dirty + + echo "foo" >> foo + assertTrue "modified file unstaged" is_dirty + + git add --all + assertTrue "modified file staged" is_dirty + + rm_tmp +} + +. ./shunit/shunit2 diff --git a/test/test-format-config.sh b/test/test-format-config.sh new file mode 100755 index 0000000..b72a14a --- /dev/null +++ b/test/test-format-config.sh @@ -0,0 +1,235 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +cd_to_tmp() { + tmpfile="/tmp/git-prompt-tests-$(time_now)$1" + mkdir -p "$tmpfile" + cd "$tmpfile" +} + +rm_tmp() { + cd $scriptDir + rm -rf /tmp/git-prompt-tests* +} + +unset_colours() { + export COLOR_REMOTE_AHEAD="" + export COLOR_REMOTE_BEHIND="" + export COLOR_REMOTE_DIVERGED="" + export COLOR_REMOTE_NOT_UPSTREAM="" + + export COLOR_LOCAL_AHEAD="" + export COLOR_LOCAL_BEHIND="" + export COLOR_LOCAL_DIVERGED="" + + export COLOR_CHANGES_STAGED="" + export COLOR_CHANGES_UNSTAGED="" + export COLOR_CHANGES_CONFLICTED="" + export COLOR_CHANGES_UNTRACKED="" + + export COLOR_BRANCH="" + export MASTER_SYMBOL="m" + + export RESET_COLOR_LOCAL="" + export RESET_COLOR_REMOTE="" + export RESET_COLOR_CHANGES="" + export RESET_COLOR_BRANCH="" +} + +prepare_test_repo() { + cd_to_tmp "remote" + + git init --quiet + touch README + git add . + git commit -m "initial commit" --quiet + origin="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $origin + git fetch origin --quiet + git checkout master --quiet + git checkout -b foo --quiet + git push --quiet -u origin foo >/dev/null + repo="$(pwd)" + + cd "$origin" + echo "foo" > foo + git add . + git commit -m "remote commit" --quiet + cd "$repo" + echo "foo" > foo + git add . + git commit -m "local commit" --quiet + echo "foo" > bar + git fetch origin --quiet +} + +test_all_options_set_config() { + cd_to_tmp "empty" + export GIT_RADAR_FORMAT="%{branch}%{local}%{changes}" + # Don't test remote as in no repo you will get upstream error message + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "$prompt" "" + + export GIT_RADAR_FORMAT="%{remote}" + # Don't test remote as in no repo you will get upstream error message + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "$prompt" "upstream ⚡" + prepare_test_repo + + export GIT_RADAR_FORMAT="%{remote}%{branch}%{local}%{changes}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "$prompt" "m 1 →foo1↑1?" + + export GIT_RADAR_FORMAT="%{remote}%{branch}%{changes}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "$prompt" "m 1 →foo1?" + + export GIT_RADAR_FORMAT="%{branch}%{local}%{changes}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "$prompt" "foo1↑1?" + + export GIT_RADAR_FORMAT="%{branch}%{changes}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "$prompt" "foo1?" + + export GIT_RADAR_FORMAT="%{branch}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "$prompt" "foo" + + rm_tmp +} + +test_reorder_parts() { + prepare_test_repo + + export GIT_RADAR_FORMAT="%{branch}%{local}%{changes}%{remote}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "foo1↑1?m 1 →" "$prompt" + + export GIT_RADAR_FORMAT="%{local}%{changes}%{remote}%{branch}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "1↑1?m 1 →foo" "$prompt" + + export GIT_RADAR_FORMAT="%{changes}%{remote}%{branch}%{local}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "1?m 1 →foo1↑" "$prompt" + + rm_tmp +} + +test_prefix_and_suffix_changes() { + prepare_test_repo + + export GIT_RADAR_FORMAT="%{changes}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "1?" "$prompt" + + export GIT_RADAR_FORMAT="%{[:changes:]}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "[1?]" "$prompt" + + rm_tmp +} + +test_prefix_and_suffix_local() { + prepare_test_repo + + export GIT_RADAR_FORMAT="%{local}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "1↑" "$prompt" + + export GIT_RADAR_FORMAT="%{[:local:]}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "[1↑]" "$prompt" + + rm_tmp +} + +test_prefix_and_suffix_branch() { + prepare_test_repo + + export GIT_RADAR_FORMAT="%{branch}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "foo" "$prompt" + + export GIT_RADAR_FORMAT="%{[:branch:]}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "[foo]" "$prompt" + + rm_tmp +} + +test_prefix_and_suffix_remote() { + prepare_test_repo + + export GIT_RADAR_FORMAT="%{remote}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "m 1 →" "$prompt" + + export GIT_RADAR_FORMAT="%{[:remote:]}" + prepare_zsh_colors + unset_colours + + prompt="$(render_prompt)" + assertEquals "[m 1 →]" "$prompt" + + rm_tmp +} + +. ./shunit/shunit2 diff --git a/test/test-performance.sh b/test/test-performance.sh new file mode 100755 index 0000000..cb19666 --- /dev/null +++ b/test/test-performance.sh @@ -0,0 +1,231 @@ +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +cd_to_tmp() { + tmpfile="/tmp/git-prompt-tests-$(time_now)$1" + mkdir -p "$tmpfile" + cd "$tmpfile" +} + +rm_tmp() { + cd $scriptDir + rm -rf /tmp/git-prompt-tests* +} + +report() { + arr=( "$@" ) + printf '%s\n' "${arr[@]}" | sort -n | awk ' + function colored(s) { + OFMT="%2.3fs"; + OFS=""; + ORS=""; + if( s > 0.2 ) { + print "\033[1;31m", s, "\033[0m" + } else if( s > 0.1 ) { + print "\033[1;33m", s, "\033[0m" + } else { + print "\033[1;32m", s, "\033[0m" + } + OFS="\t"; + ORS="\n"; + } + BEGIN { + c = 0; + sum = 0; + } + $1 ~ /^[0-9]*(\.[0-9]*)?$/ { + a[c++] = $1; + sum += $1; + } + END { + min = a[0] + 0; + max = a[c-1] + 0; + ave = sum / c; + if( (c % 2) == 1 ) { + median = a[ int(c/2) ]; + } else { + median = ( a[c/2] + a[c/2-1] ) / 2; + } + OFS="\t"; + OFMT="%2.3fs"; + print c, colored(ave), colored(median), colored(min), colored(max); + } +' +} + +table_headers() { + printf " Count\tMean\tMedian\tMin\tMax\n" +} + +profile () { + cmd="$2" + for (( i = 0; i < 100; i++ )); do + start=$(gdate +%s.%N) + eval $cmd > /dev/null + duration=$(echo "$(gdate +%s.%N) - $start" | bc) + timings[$i]=$duration + done + printf '%-25s' "$1" + report "${timings[@]}" +} + +test_empty_repo() { + cd_to_tmp + git init --quiet + + table_headers + profile "prompt.zsh" "/.$scriptDir/prompt.zsh" + profile "prompt.bash" "/.$scriptDir/prompt.bash" + + rm_tmp +} + +test_lots_of_file_changes() { + cd_to_tmp + git init --quiet + + table_headers + + profile "no changes zsh" "/.$scriptDir/prompt.zsh" + profile "no changes bash" "/.$scriptDir/prompt.bash" + + for (( i = 0; i < 100; i++ )); do + touch foo$i + done + + profile "100 untracked zsh" "/.$scriptDir/prompt.zsh" + profile "100 untracked bash" "/.$scriptDir/prompt.bash" + + for (( i = 0; i < 100; i++ )); do + touch bar$i + git add bar$i + done + + profile "100 added zsh" "/.$scriptDir/prompt.zsh" + profile "100 added bash" "/.$scriptDir/prompt.bash" + + for (( i = 0; i < 100; i++ )); do + echo "bar$i" > bar$i + done + + profile "100 modify zsh" "/.$scriptDir/prompt.zsh" + profile "100 modify bash" "/.$scriptDir/prompt.bash" + + rm_tmp +} + +test_commits_local_and_remote_ahead() { + cd_to_tmp "remote" + git init --quiet + touch README + git add . + git commit -m "initial commit" --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout master --quiet + + git checkout -b foo --quiet + git push --quiet -u origin foo >/dev/null + + table_headers + + profile "0 commits zsh" "/.$scriptDir/prompt.zsh" + profile "0 commits bash" "/.$scriptDir/prompt.bash" + + for (( i = 0; i < 100; i++ )); do + echo "foo$i" >> foo + git add . + git commit -m "foo $i" --quiet + done + + profile "100 local zsh" "/.$scriptDir/prompt.zsh" + profile "100 local bash" "/.$scriptDir/prompt.bash" + + git push --quiet + + profile "100 remote zsh" "/.$scriptDir/prompt.zsh" + profile "100 remote bash" "/.$scriptDir/prompt.bash" + + rm_tmp +} + +test_commits_local_and_remote_behind() { + cd_to_tmp "remote" + git init --bare --quiet + remoteLocation="$(pwd)" + + cd_to_tmp "new" + git init --quiet + git remote add origin $remoteLocation + git fetch origin --quiet + git checkout -b master --quiet + touch README + git add README + git commit -m "initial commit" --quiet + + git push --quiet -u origin master >/dev/null + git reset --quiet --hard HEAD + + git checkout -b foo --quiet + git push --quiet -u origin foo >/dev/null + + git checkout master --quiet + + table_headers + + profile "0 commits zsh" "/.$scriptDir/prompt.zsh" + profile "0 commits bash" "/.$scriptDir/prompt.bash" + + for (( i = 0; i < 100; i++ )); do + echo "foo$i" >> foo + git add . + git commit -m "foo $i" --quiet + done + + git push --quiet + git checkout foo --quiet + + profile "100 behind remote zsh" "/.$scriptDir/prompt.zsh" + profile "100 behind remote bash" "/.$scriptDir/prompt.bash" + + git checkout master --quiet + git checkout -b bar --quiet + git push --quiet -u origin bar >/dev/null + git reset --hard origin/foo --quiet + + profile "100 behind mine zsh" "/.$scriptDir/prompt.zsh" + profile "100 behind mine bash" "/.$scriptDir/prompt.bash" + +} + +test_large_repo() { + cd_to_tmp + git clone https://github.com/Homebrew/homebrew --quiet + cd homebrew + + table_headers + profile "prompt.zsh" "/.$scriptDir/prompt.zsh" + profile "prompt.bash" "/.$scriptDir/prompt.bash" + + rm_tmp +} + +test_lots_of_submodules() { + cd_to_tmp + git clone https://github.com/michaeldfallen/dotfiles --quiet + cd dotfiles + git submodule update --init --quiet + + table_headers + profile "prompt.zsh" "/.$scriptDir/prompt.zsh" + profile "prompt.bash" "/.$scriptDir/prompt.bash" + + rm_tmp +} + +. ./shunit/shunit2 diff --git a/test/test-sonar-base.sh b/test/test-sonar-base.sh new file mode 100755 index 0000000..7c0c742 --- /dev/null +++ b/test/test-sonar-base.sh @@ -0,0 +1,29 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +test_show_remote_status() { + show_remote_status + assertTrue $? + + show_remote_status --bash + assertTrue $? + + show_remote_status --bash --fetch + assertTrue $? + + show_remote_status --bash --no-remote-status --fetch + assertFalse $? + + show_remote_status --bash --fetch --no-remote-status + assertFalse $? + + show_remote_status --no-remote-status --bash --fetch + assertFalse $? + + show_remote_status --bash --fetch --minimal --no-remote-status + assertFalse $? +} + +. ./shunit/shunit2 diff --git a/test/test-stash.sh b/test/test-stash.sh new file mode 100755 index 0000000..862aef1 --- /dev/null +++ b/test/test-stash.sh @@ -0,0 +1,50 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +tmpfile="" + +cd_to_tmp() { + tmpfile="/tmp/git-prompt-tests-$(time_now)$1" + mkdir -p "$tmpfile" + cd "$tmpfile" +} + +rm_tmp() { + cd $scriptDir + rm -rf /tmp/git-prompt-tests* +} + +test_unstashed_status() { + cd_to_tmp + git init --quiet + + assertEquals "0" "$(stashed_status)" + + rm_tmp +} + +test_stashed_status() { + cd_to_tmp + git init --quiet + + touch foo + git add --all + git commit -m "Initial commit" >/dev/null + echo "test">foo + git stash > /dev/null + assertEquals "1" "$(stashed_status)" + + echo "test2">foo + git stash > /dev/null + assertEquals "2" "$(stashed_status)" + + git stash drop > /dev/null + assertEquals "1" "$(stashed_status)" + + + rm_tmp +} + +. ./shunit/shunit2 diff --git a/test/test-status.sh b/test/test-status.sh new file mode 100755 index 0000000..56a2716 --- /dev/null +++ b/test/test-status.sh @@ -0,0 +1,145 @@ +#!/bin/bash +scriptDir="$(cd "$(dirname "$0")"; pwd)" + +source "$scriptDir/sonar-base.sh" + +test_prefix_and_suffix() { + status=""" + M unstaged-modified + D unstaged-deleted +M staged-modified +A staged-added +D staged-deleted +C staged-copied +R staged-renamed +MM staged-and-unstaged-modified +UD deleted-them-conflicted +AU added-us-conflicted +UU modified-both-conflicted +?? untacked +""" + + prefix="_" + suffix="-" + + assertEquals "line:${LINENO}" "1_D-2_M-"\ + "$(unstaged_status "$status" "$prefix" "$suffix")" + + assertEquals "line:${LINENO}" "1_A-1_D-2_M-1_R-1_C-"\ + "$(staged_status "$status" "$prefix" "$suffix")" + + assertEquals "line:${LINENO}" "1_U-1_T-1_B-"\ + "$(conflicted_status "$status" "$prefix" "$suffix")" + + assertEquals "line:${LINENO}" "1_?-"\ + "$(untracked_status "$status" "$prefix" "$suffix")" +} + +test_basic_unstaged_options() { + status=""" + M modified-and-unstaged + D deleted-and-unstaged + A impossible-added-and-unstaged-(as-added-and-unstaged-is-untracked) + C impossible-copied-and-unstaged-(as-copied-and-unstaged-is-untracked) + R impossible-renamed-and-unstaged-(as-renamed-and-unstaged-is-untracked) + U impossible-updated-but-unmerged + ! impossible-ignored-without-!-in-position-1 + ? impossible-untracked-without-?-in-position-1 + empty-spaces-mean-nothing + """ + assertEquals "line:${LINENO} staged status failed match" "" "$(staged_status "$status")" + assertEquals "line:${LINENO} untracked status failed match" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO} unstaged status failed match"\ + "1D1M" "$(unstaged_status "$status")" + assertEquals "line:${LINENO} conflicted status failed match" "" "$(conflicted_status "$status")" +} + +test_basic_staged_options() { + status=""" +A added-and-staged + """ + assertEquals "line:${LINENO} staged status failed match"\ + "1A" "$(staged_status "$status")" + assertEquals "line:${LINENO} untracked status failed match" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO} unstaged status failed match" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO} conflicted status failed match" "" "$(conflicted_status "$status")" + + status=""" +M modified-and-staged + """ + assertEquals "line:${LINENO} staged status failed match"\ + "1M" "$(staged_status "$status")" + assertEquals "line:${LINENO} untracked status failed match" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO} unstaged status failed match" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO} conflicted status failed match" "" "$(conflicted_status "$status")" + + status=""" +D deleted-and-staged + """ + assertEquals "line:${LINENO} staged status failed match"\ + "1D" "$(staged_status "$status")" + assertEquals "line:${LINENO} untracked status failed match" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO} unstaged status failed match" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO} conflicted status failed match" "" "$(conflicted_status "$status")" + + status=""" +C copied-and-staged + """ + assertEquals "line:${LINENO} staged status failed match"\ + "1C" "$(staged_status "$status")" + assertEquals "line:${LINENO} untracked status failed match" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO} unstaged status failed match" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO} conflicted status failed match" "" "$(conflicted_status "$status")" + + status=""" +R renamed-and-staged + """ + assertEquals "line:${LINENO} staged status failed match"\ + "1R" "$(staged_status "$status")" + assertEquals "line:${LINENO} untracked status failed match" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO} unstaged status failed match" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO} conflicted status failed match" "" "$(conflicted_status "$status")" + + status=""" +U impossible-unmerged-without-a-character-in-position-2 +? impossible-untracked-without-?-in-position-2 +! impossible-ignored-without-!-in-position-2 + empty-spaces-do-nothing + """ + assertEquals "line:${LINENO} staged status failed match" "" "$(staged_status "$status")" + assertEquals "line:${LINENO} untracked status failed match" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO} unstaged status failed match" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO} conflicted status failed match" "" "$(conflicted_status "$status")" +} + +test_conflicts() { + status=""" +UD unmerged-deleted-by-them +UA unmerged-added-by-them + """ + assertEquals "line:${LINENO}" "" "$(staged_status "$status")" + assertEquals "line:${LINENO}" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO}" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO}" "2T" "$(conflicted_status "$status")" + + status=""" +AU unmerged-added-by-us +DU unmerged-deleted-by-us + """ + assertEquals "line:${LINENO}" "" "$(staged_status "$status")" + assertEquals "line:${LINENO}" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO}" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO}" "2U" "$(conflicted_status "$status")" + + status=""" +AA unmerged-both-added +DD unmerged-both-deleted +UU unmerged-both-modified + """ + assertEquals "line:${LINENO}" "" "$(staged_status "$status")" + assertEquals "line:${LINENO}" "" "$(untracked_status "$status")" + assertEquals "line:${LINENO}" "" "$(unstaged_status "$status")" + assertEquals "line:${LINENO}" "3B" "$(conflicted_status "$status")" +} + +. ./shunit/shunit2 |