diff --git a/shunit2 b/shunit2 index 57a45da..3ec8909 100755 --- a/shunit2 +++ b/shunit2 @@ -49,6 +49,8 @@ SHUNIT_CMD_TPUT=${SHUNIT_CMD_TPUT:-${__SHUNIT_CMD_TPUT}} # Enable color output. Options are 'auto', 'always', or 'never'. SHUNIT_COLOR=${SHUNIT_COLOR:-auto} +# Enable difference alignment output. Options are 'auto', 'always', or 'never'. +SHUNIT_DIFF_ALIGN=${SHUNIT_DIFF_ALIGN:-never} # # Internal constants. @@ -647,6 +649,35 @@ fail() { # shellcheck disable=SC2016,SC2034 _FAIL_='eval fail --lineno "${LINENO:-}"' +_shunit_different() { + expected="$1" + actually="$2" + len1=${#expected} + len2=${#actually} + min_len=$len1 + if ${__SHUNIT_BUILTIN} [ "$min_len" -gt "$len2" ]; then + min_len=$len2; + fi + + i=1; + while ${__SHUNIT_BUILTIN} [ "$i" -le "$min_len" ]; + do + charA=$(echo "$expected"|cut -c$i); + charB=$(echo "$actually"|cut -c$i); + if ${__SHUNIT_BUILTIN} [ "$charA" = "$charB" ]; then + printf "%c" "-"; + else + printf "%c" "^"; + break; + fi + i=$((i + 1)); + done + if ${__SHUNIT_BUILTIN} [ "$i" -gt "$min_len" ]; then + printf "%c" "^"; + fi + +} + # Records a test failure, stating two values were not equal. # # Args: @@ -675,9 +706,14 @@ failNotEquals() { shunit_actual_=$2 shunit_message_=${shunit_message_%% } + if ${__SHUNIT_BUILTIN} [ ${__shunit_diff_align} -eq ${SHUNIT_TRUE} ]; then + diff_position_=$(_shunit_different "${shunit_expected_}" "${shunit_actual_})") + _shunit_assertFail "${shunit_message_:+${shunit_message_} }\\nexpected:<${shunit_expected_}>\\n----------${diff_position_}\\n but was:<${shunit_actual_}>" + return + fi _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected:<${shunit_expected_}> but was:<${shunit_actual_}>" - unset shunit_message_ shunit_expected_ shunit_actual_ + unset shunit_message_ shunit_expected_ shunit_actual_ diff_position_ return ${SHUNIT_FALSE} } # shellcheck disable=SC2016,SC2034 @@ -1043,6 +1079,26 @@ _shunit_cleanup() { unset _shunit_name_ _shunit_signal_ } +# configureDiff difference alignment. +# +# Args: +# alignment: string: align state (one of `always`, `auto`, or `never`). +_shunit_configureDiff() { + _shunit_diff_conf_=${SHUNIT_FALSE} + case $1 in + 'always') _shunit_diff_conf_=${SHUNIT_TRUE} ;; + 'auto') + if which cut|grep cut >/dev/null 2>&1; then + _shunit_diff_conf_=${SHUNIT_TRUE} + fi + ;; + 'never'|'none') _shunit_diff_conf_=${SHUNIT_FALSE} ;; + *) _shunit_fatal "unrecognized difference alignment option '$1'" ;; + esac + __shunit_diff_align=${_shunit_diff_conf_} + unset _shunit_diff_conf_ +} + # configureColor based on user color preference. # # Args: @@ -1329,6 +1385,9 @@ fi # Configure default output coloring behavior. _shunit_configureColor "${SHUNIT_COLOR}" +# Configure default difference alignment behavior. +_shunit_configureDiff "${SHUNIT_DIFF_ALIGN}" + # Execute the oneTimeSetUp function (if it exists). if ! oneTimeSetUp; then _shunit_fatal "oneTimeSetUp() returned non-zero return code." diff --git a/shunit2_misc_test.sh b/shunit2_misc_test.sh index 12cc2d4..8be7434 100755 --- a/shunit2_misc_test.sh +++ b/shunit2_misc_test.sh @@ -58,6 +58,8 @@ EOF testIssue7() { # Disable coloring so 'ASSERT:' lines can be matched correctly. _shunit_configureColor 'none' + # Disable difference alignment so 'ASSERT:' lines can be matched correctly. + _shunit_configureDiff 'none' # Ignoring errors with `|| :` as we only care about the message in this test. ( assertEquals 'Some message.' 1 2 >"${stdoutF}" 2>"${stderrF}" ) || : @@ -165,6 +167,34 @@ EOF fi } +testIssue89() { + tempdiff="${SHUNIT_TMPDIR}/difference.diff" + _shunit_configureColor none + # test new aligned difference + _shunit_configureDiff always + ( assertEquals "deadbeef" "deadbuff" >"${stdoutF}" 2>"${stderrF}" ) || : + diff -u "${stdoutF}" - >"${tempdiff}" 2>&1 < +---------------^ + but was: +EOF + rtrn=$? + [ "${rtrn}" -eq "${SHUNIT_TRUE}" ] || cat "${tempdiff}" >&2 + rm "${tempdiff}" + # test does it breaks original diff implementation + _shunit_configureColor none + _shunit_configureDiff none + ( assertEquals "deadbeef" "deadbuff" >"${stdoutF}" 2>"${stderrF}" ) || : + diff -u "${stdoutF}" - >"${tempdiff}" 2>&1 < but was: +EOF + rtrn=$? + [ "${rtrn}" -eq "${SHUNIT_TRUE}" ] || cat "${tempdiff}" >&2 + rm "${tempdiff}" +} + + # Demonstrate that asserts are no longer executed in subshells. # https://github.com/kward/shunit2/issues/123 #