bats-core / bats-assert

Common assertions for Bats
Creative Commons Zero v1.0 Universal
94 stars 39 forks source link

add option to show diff in assert_output and assert_equal #65

Open justinledford opened 8 months ago

justinledford commented 8 months ago

fixes #60

gioele commented 4 months ago

Why an option? The diffing could happen automatically if diff is available.

jasonkarns commented 3 months ago

Is there an opportunity here instead of trying to bake this into the matcher, to instead have a form of assert_output | diff? (diff here being function we own, not the command)

Having a generic diff utility would be more composable to other existing and future matchers. And allow multiple types of formatters to coexist. (Rather than an explosion of matcher options.)

This would require having a structured format/spec the assertions can construct that "renders" can consume as an api.

mmetc commented 2 months ago

I'm just giving my 2c as a happy bats user

For TUI output, I find it way faster to reconcile the differences with a tool like github.com/dandavison/delta

So I know what you mean about colors and the meaning of red, but it would be very useful to customize the diff command in some way.

Then when it comes to comparing contents, I would welcome anything that makes it easier to write stuff like this. I am not proud but it makes tests more compact and readable. That's what you mean by matcher I suppose

# Compare ignoring the key order, and allow "expected" without quoted identifiers.
# Preserve the output variable in case the following commands require it.
assert_json() {
    local oldout="${output}"
    # validate actual, sort
    run -0 jq -Sen "${output}"
    local actual="${output}"

    # handle stdin, quote identifiers, sort
    local expected="$1"
    if [[ "${expected}" == "-" ]]; then
        expected="$(cat)"
    fi
    run -0 jq -Sn "${expected}"
    expected="${output}"

    #shellcheck disable=SC2016
    run jq -ne --argjson a "${actual}" --argjson b "${expected}" '$a == $b'
    #shellcheck disable=SC2154
    if [[ "${status}" -ne 0 ]]; then
        echo "expect: $(jq -c <<<"${expected}")"
        echo "actual: $(jq -c <<<"${actual}")"
        diff <(echo "${actual}") <(echo "${expected}")
        fail "json does not match"
    fi
    output="${oldout}"
}
export -f assert_json