Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show evaluated test arguments for functions with 1 & 2 arguments #57825

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
1 change: 0 additions & 1 deletion stdlib/Test/docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ Test Passed
julia> @test 1 ≈ 0.999999
Test Failed at none:1
Expression: 1 ≈ 0.999999
Evaluated: 1 ≈ 0.999999

ERROR: There was an error during testing
```
Expand Down
41 changes: 38 additions & 3 deletions stdlib/Test/src/Test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ using InteractiveUtils: gen_call_with_extracted_types
using Base: typesplit, remove_linenums!
using Serialization: Serialization

# Whitelist boolean functions which show their evaluated arguments when the test fails
const DISPLAY_FAILED = (
:isequal,
:isapprox,
Expand Down Expand Up @@ -197,7 +198,7 @@ function Base.show(io::IO, t::Fail)
print(io, "\n Expected: ", data)
print(io, "\n No exception thrown")
elseif t.test_type === :test
if data !== nothing
if data !== nothing && t.orig_expr != data
# The test was an expression, so display the term-by-term
# evaluated version as well
print(io, "\n Evaluated: ", data)
Expand Down Expand Up @@ -583,6 +584,37 @@ macro test_skip(ex, kws...)
return :(record(get_testset(), $testres))
end

function _is_simple_call(@nospecialize ex)
ex.head === :call || return false

# Broadcasted functions are not currently supported
first(string(ex.args[1])) != '.' || return false

num_pargs = 0
for x in ex.args[2:end]
if isa(x, Expr) && x.head === :parameters
return false
elseif isa(x, Expr) && x.head === :kw
return false
elseif isa(x, Expr) && x.head === :...
return false # Unable to determine number of arguments
else
num_pargs += 1
end
end

return 1 <= num_pargs <= 2
end

function _function_name(@nospecialize ex)
ex.head === :call || throw(ArgumentError("$ex is not a call expression"))
if isa(ex.args[1], Expr) && ex.args[1].head === :.
ex.args[1].args[2].value
else
ex.args[1]
end
end

# An internal function, called by the code generated by the @test
# macro to get results of the test expression.
# In the special case of a comparison, e.g. x == 5, generate code to
Expand Down Expand Up @@ -619,7 +651,8 @@ function get_test_result(ex, source)
$(QuoteNode(source)),
$negate,
))
elseif isa(ex, Expr) && ex.head === :call && ex.args[1] in DISPLAY_FAILED
elseif isa(ex, Expr) && ex.head === :call &&
(_is_simple_call(ex) || _function_name(ex) in DISPLAY_FAILED)
escaped_func = esc(ex.args[1])
quoted_func = QuoteNode(ex.args[1])

Expand Down Expand Up @@ -816,7 +849,7 @@ function do_test_throws(result::ExecutionResult, orig_expr, extype)
Base.depwarn("macroexpand no longer throws a LoadError so `@test_throws LoadError ...` is deprecated and passed without checking the error type!", :do_test_throws)
true
elseif extype == ErrorException && isa(exc, FieldError)
Base.depwarn(lazy"ErrorException should no longer be used to test field access; FieldError should be used instead!", :do_test_throws)
Base.depwarn(lazy"Using ErrorException to test field access is deprecated; use FieldError instead.", :do_test_throws)
true
else
isa(exc, extype)
Expand Down Expand Up @@ -1623,6 +1656,7 @@ julia> @testset let logi = log(im)
end
Test Failed at none:3
Expression: !(iszero(real(logi)))
Evaluated: !(iszero(0.0))
Context: logi = 0.0 + 1.5707963267948966im

ERROR: There was an error during testing
Expand All @@ -1633,6 +1667,7 @@ julia> @testset let logi = log(im), op = !iszero
end
Test Failed at none:3
Expression: op(real(logi))
Evaluated: op(0.0)
Context: logi = 0.0 + 1.5707963267948966im
op = !iszero

Expand Down
Loading