From fa2919deb4889c0e30661b117c965dc94d11dfd5 Mon Sep 17 00:00:00 2001 From: Curtis Vogt Date: Thu, 8 Jun 2017 13:38:42 -0500 Subject: [PATCH 1/2] Show evaluated expr with `@test isequal(...)` --- NEWS.md | 2 ++ base/test.jl | 40 +++++++++++++++++++++++++++++----------- test/test.jl | 10 ++++++++++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6bcc2fc706f35..f01bbcf899a1b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -79,6 +79,8 @@ Library improvements * Added `unique!` which is an inplace version of `unique` ([#20549]). + * `@test isequal(x, y)` now prints an evaluated expression when the test fails ([#22296]). + Compiler/Runtime improvements ----------------------------- diff --git a/base/test.jl b/base/test.jl index c841552bb9a88..fff67157c16a3 100644 --- a/base/test.jl +++ b/base/test.jl @@ -76,7 +76,7 @@ function Base.show(io::IO, t::Pass) if t.test_type == :test_throws # The correct type of exception was thrown print(io, "\n Thrown: ", typeof(t.value)) - elseif t.test_type == :test && isa(t.data,Expr) && t.data.head == :comparison + elseif t.test_type == :test && isa(t.data, Expr) # The test was an expression, so display the term-by-term # evaluated version as well print(io, "\n Evaluated: ", t.data) @@ -106,7 +106,7 @@ function Base.show(io::IO, t::Fail) # An exception was expected, but no exception was thrown print(io, "\n Expected: ", t.data) print(io, "\n No exception thrown") - elseif t.test_type == :test && isa(t.data,Expr) && t.data.head == :comparison + elseif t.test_type == :test && isa(t.data, Expr) # The test was an expression, so display the term-by-term # evaluated version as well print(io, "\n Evaluated: ", t.data) @@ -188,20 +188,31 @@ struct Threw <: ExecutionResult backtrace end -function eval_comparison(evaluated::Expr, quoted::Expr) +function eval_test(evaluated::Expr, quoted::Expr) res = true i = 1 args = evaluated.args quoted_args = quoted.args n = length(args) - while i < n - a, op, b = args[i], args[i+1], args[i+2] - if res - res = op(a, b) === true # Keep `res` type stable + if evaluated.head == :comparison + while i < n + a, op, b = args[i], args[i+1], args[i+2] + if res + res = op(a, b) === true # Keep `res` type stable + end + quoted_args[i] = a + quoted_args[i+2] = b + i += 2 + end + + elseif evaluated.head == :call + op = args[1] + res = op(args[2:n]...) === true + for i in 2:n + quoted_args[i] = args[i] end - quoted_args[i] = a - quoted_args[i+2] = b - i += 2 + else + throw(ArgumentError("Unhandled expression type: $(evaluated.head)")) end Returned(res, quoted) end @@ -307,10 +318,17 @@ function get_test_result(ex) # pass all terms of the comparison to `eval_comparison`, as an Expr escaped_terms = [esc(arg) for arg in ex.args] quoted_terms = [QuoteNode(arg) for arg in ex.args] - testret = :(eval_comparison( + testret = :(eval_test( Expr(:comparison, $(escaped_terms...)), Expr(:comparison, $(quoted_terms...)), )) + elseif isa(ex, Expr) && ex.head == :call && ex.args[1] == :isequal + escaped_terms = [esc(arg) for arg in ex.args] + quoted_terms = [QuoteNode(arg) for arg in ex.args] + testret = :(eval_test( + Expr(:call, $(escaped_terms...)), + Expr(:call, $(quoted_terms...)), + )) else testret = :(Returned($(esc(ex)), nothing)) end diff --git a/test/test.jl b/test/test.jl index fc023c548ea20..11ecd3c72592f 100644 --- a/test/test.jl +++ b/test/test.jl @@ -11,6 +11,10 @@ let g = Int[], f = (x) -> (push!(g, x); x) @test f(1) == 1 @test g == [1] + + empty!(g) + @test isequal(f(2), 2) + @test g == [2] end # Test @test_broken with fail @@ -74,6 +78,8 @@ fails = @testset NoThrowTestSet begin @test 1+0 == 2+0 == 3+0 # Fail - comparison call @test ==(1 - 2, 2 - 1) + # Fail - isequal + @test isequal(0 / 0, 1 / 0) # Error - unexpected pass @test_broken true end @@ -106,6 +112,10 @@ str = sprint(show, fails[6]) @test contains(str, "Evaluated: -1 == 1") str = sprint(show, fails[7]) +@test contains(str, "Expression: isequal(0 / 0, 1 / 0)") +@test contains(str, "Evaluated: isequal(NaN, Inf)") + +str = sprint(show, fails[8]) @test contains(str, "Unexpected Pass") @test contains(str, "Expression: true") From 3b3302bfc995c8b7b994aa99c4ff9c7c5387769a Mon Sep 17 00:00:00 2001 From: Curtis Vogt Date: Fri, 9 Jun 2017 10:06:33 -0500 Subject: [PATCH 2/2] Show evaluated expr with `@test isapprox(...)` --- NEWS.md | 3 ++- base/test.jl | 2 +- test/test.jl | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index f01bbcf899a1b..b78e03c269e17 100644 --- a/NEWS.md +++ b/NEWS.md @@ -79,7 +79,8 @@ Library improvements * Added `unique!` which is an inplace version of `unique` ([#20549]). - * `@test isequal(x, y)` now prints an evaluated expression when the test fails ([#22296]). + * `@test isequal(x, y)` and `@test isapprox(x, y)` now prints an evaluated expression when + the test fails ([#22296]). Compiler/Runtime improvements ----------------------------- diff --git a/base/test.jl b/base/test.jl index fff67157c16a3..83d42558d8867 100644 --- a/base/test.jl +++ b/base/test.jl @@ -322,7 +322,7 @@ function get_test_result(ex) Expr(:comparison, $(escaped_terms...)), Expr(:comparison, $(quoted_terms...)), )) - elseif isa(ex, Expr) && ex.head == :call && ex.args[1] == :isequal + elseif isa(ex, Expr) && ex.head == :call && ex.args[1] in (:isequal, :isapprox) escaped_terms = [esc(arg) for arg in ex.args] quoted_terms = [QuoteNode(arg) for arg in ex.args] testret = :(eval_test( diff --git a/test/test.jl b/test/test.jl index 11ecd3c72592f..67a9217c9a567 100644 --- a/test/test.jl +++ b/test/test.jl @@ -80,6 +80,8 @@ fails = @testset NoThrowTestSet begin @test ==(1 - 2, 2 - 1) # Fail - isequal @test isequal(0 / 0, 1 / 0) + # Fail - isapprox + @test isapprox(0 / 1, -1 / 0) # Error - unexpected pass @test_broken true end @@ -116,6 +118,10 @@ str = sprint(show, fails[7]) @test contains(str, "Evaluated: isequal(NaN, Inf)") str = sprint(show, fails[8]) +@test contains(str, "Expression: isapprox(0 / 1, -1 / 0)") +@test contains(str, "Evaluated: isapprox(0.0, -Inf)") + +str = sprint(show, fails[9]) @test contains(str, "Unexpected Pass") @test contains(str, "Expression: true")