diff --git a/src/ArgCheck.jl b/src/ArgCheck.jl index 9125935..fdcf84e 100644 --- a/src/ArgCheck.jl +++ b/src/ArgCheck.jl @@ -1,7 +1,7 @@ __precompile__() module ArgCheck using Base.Meta -export @argcheck, @check +export @argcheck, @check, CheckError include("checks.jl") end diff --git a/src/checks.jl b/src/checks.jl index becfe06..faf72ab 100644 --- a/src/checks.jl +++ b/src/checks.jl @@ -1,3 +1,6 @@ +struct CheckError <: Exception + msg::String +end abstract type AbstractCheckFlavor end struct ArgCheckFlavor <: AbstractCheckFlavor end struct CheckFlavor <: AbstractCheckFlavor end @@ -164,7 +167,7 @@ function expr_error_block(info, condition, preamble...) end default_exception_type(::ArgCheckFlavor) = ArgumentError -default_exception_type(::CheckFlavor) = ErrorException +default_exception_type(::CheckFlavor) = CheckError function build_error(info) build_error(info, info.checkflavor, info.options...) @@ -187,14 +190,27 @@ error_message(info::FallbackErrorInfo) = "$(info.code) must hold." error_message(info::CallErrorInfo) = fancy_error_message(info) error_message(info::ComparisonErrorInfo) = fancy_error_message(info) +function pretty_string(data) + io = IOBuffer() + ioc = IOContext(io; limit=true, compact=true) + show(ioc, data) + seekstart(io) + String(take!(io)) +end +pretty_string(x::Number) = string(x) +pretty_string(s::Symbol) = string(s) +pretty_string(ex::Expr) = string(ex) + function fancy_error_message(info) code = info.code exprs = info.argument_expressions values = info.argument_values lines = String[] foreach(exprs, values) do ex, val - if string(ex) != string(val) - push!(lines, "$ex => $val") + pex = pretty_string(ex) + pval = pretty_string(val) + if pex != pval + push!(lines, "$pex => $pval") end end firstline = if isempty(lines) diff --git a/test/checks.jl b/test/checks.jl index 6c16b47..338565b 100644 --- a/test/checks.jl +++ b/test/checks.jl @@ -1,3 +1,4 @@ +using ArgCheck: pretty_string macro catch_exception_object(code) quote err = try @@ -77,12 +78,12 @@ truthy(args...;kw...) = true @test err === MyExoticError(1,2) end -@testset "error message comparison" begin +@testset "error messages" begin x = 1.23455475675 y = 2.345345345 # comparison err = @catch_exception_object @argcheck x == y MyError - @test isa(err, MyError) + @test err isa MyError msg = err.msg @test contains(msg, string(x)) @test contains(msg, string(y)) @@ -110,6 +111,17 @@ end @test contains(msg, string(x)) @test contains(msg, string(y)) @test contains(msg, "≦") + + s = randstring() + arr = rand(1000:9999, 1000) + x = randn() + err = @catch_exception_object @check falsy(x, arr, s) + @test typeof(err) == CheckError + msg = err.msg + @test length(msg) < 2000 + @test contains(msg, pretty_string(x)) + @test contains(msg, pretty_string(arr)) + @test contains(msg, pretty_string(s)) end # In @@ -172,8 +184,22 @@ end @testset "@check" begin @check true - E = ErrorException + E = CheckError @test_throws E @check false @test_throws E @check false "oh no" @test_throws DimensionMismatch @check false DimensionMismatch end + +@testset "pretty_string" begin + @test pretty_string("asd") == "\"asd\"" + + data = rand(10000:99999, 1000) + str = pretty_string(data) + @test length(str) < 1000 + @test contains(str, string(last(data))) + @test contains(str, string(first(data))) + @test !contains(str, "\n") + + data = randn() + @test parse(Float64,pretty_string(data)) === data +end