Skip to content

Commit

Permalink
update tests, format, bump version
Browse files Browse the repository at this point in the history
  • Loading branch information
Jutho committed Mar 8, 2024
1 parent 6c29e29 commit 1e6d07e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 44 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "TestExtras"
uuid = "5ed8adda-3752-4e41-b88a-e8b09835ee3a"
authors = ["Jutho Haegeman <[email protected]> and contributors"]
version = "0.2.1"
version = "0.2.2"

[deps]
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
Expand Down
3 changes: 2 additions & 1 deletion src/constinferred.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ function _constinferred(ex, mod, src, test_f, allow=:(Union{}))
xkey = x
xval = x
else
return Expr(:call, :error, "syntax: invalid keyword argument syntax \"$x\" at $src")
return Expr(:call, :error,
"syntax: invalid keyword argument syntax \"$x\" at $src")
end
if xval isa ConstantValue
push!(rightkwargs, x)
Expand Down
93 changes: 52 additions & 41 deletions src/timedtest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ macro timedtestset(ex...)
# instead we do: var = TestExtras.TimedTests.TimedTestSet; @testset var begin ...
return esc(Expr(:block,
Expr(:(=), timedtestsetvar, :($TimedTestSet)),
Expr(:macrocall, Symbol("@testset"), __source__, timedtestsetvar, ex... )))
Expr(:macrocall, Symbol("@testset"), __source__, timedtestsetvar,
ex...)))
end

mutable struct TimedTestSet <: AbstractTestSet
Expand All @@ -26,7 +27,10 @@ mutable struct TimedTestSet <: AbstractTestSet
time_start::Float64
time_end::Union{Float64,Nothing}
end
TimedTestSet(desc::AbstractString; verbose::Bool = false, showtiming::Bool = true) = TimedTestSet(String(desc)::String, [], 0, false, verbose, showtiming, time(), nothing)
function TimedTestSet(desc::AbstractString; verbose::Bool=false, showtiming::Bool=true)
return TimedTestSet(String(desc)::String, [], 0, false, verbose, showtiming, time(),
nothing)
end

# For a broken result, simply store the result
Test.record(ts::TimedTestSet, t::Broken) = (push!(ts.results, t); t)
Expand All @@ -35,7 +39,7 @@ Test.record(ts::TimedTestSet, t::Pass) = (ts.n_passed += 1; t)

# For the other result types, immediately print the error message
# but do not terminate. Print a backtrace.
function Test.record(ts::TimedTestSet, t::Union{Fail, Error})
function Test.record(ts::TimedTestSet, t::Union{Fail,Error})
if TESTSET_PRINT_ENABLE[]
print(ts.description, ": ")
# don't print for interrupted tests
Expand Down Expand Up @@ -74,23 +78,23 @@ function Test.print_test_results(ts::TimedTestSet, depth_pad=0)
# Calculate the overall number for each type so each of
# the test result types are aligned
passes, fails, errors, broken, c_passes, c_fails, c_errors, c_broken, duration = get_test_counts(ts)
total_pass = passes + c_passes
total_fail = fails + c_fails
total_error = errors + c_errors
total_pass = passes + c_passes
total_fail = fails + c_fails
total_error = errors + c_errors
total_broken = broken + c_broken
dig_pass = total_pass > 0 ? ndigits(total_pass) : 0
dig_fail = total_fail > 0 ? ndigits(total_fail) : 0
dig_error = total_error > 0 ? ndigits(total_error) : 0
dig_pass = total_pass > 0 ? ndigits(total_pass) : 0
dig_fail = total_fail > 0 ? ndigits(total_fail) : 0
dig_error = total_error > 0 ? ndigits(total_error) : 0
dig_broken = total_broken > 0 ? ndigits(total_broken) : 0
total = total_pass + total_fail + total_error + total_broken
dig_total = total > 0 ? ndigits(total) : 0
# For each category, take max of digits and header width if there are
# tests of that type
pass_width = dig_pass > 0 ? max(length("Pass"), dig_pass) : 0
fail_width = dig_fail > 0 ? max(length("Fail"), dig_fail) : 0
error_width = dig_error > 0 ? max(length("Error"), dig_error) : 0
pass_width = dig_pass > 0 ? max(length("Pass"), dig_pass) : 0
fail_width = dig_fail > 0 ? max(length("Fail"), dig_fail) : 0
error_width = dig_error > 0 ? max(length("Error"), dig_error) : 0
broken_width = dig_broken > 0 ? max(length("Broken"), dig_broken) : 0
total_width = dig_total > 0 ? max(length("Total"), dig_total) : 0
total_width = dig_total > 0 ? max(length("Total"), dig_total) : 0
duration_width = max(length("Time"), length(duration))
# Calculate the alignment of the test result counts by
# recursively walking the tree of test sets
Expand All @@ -102,23 +106,28 @@ function Test.print_test_results(ts::TimedTestSet, depth_pad=0)
printstyled(lpad("Pass", pass_width, " "), " "; bold=true, color=:green)
end
if fail_width > 0
printstyled(lpad("Fail", fail_width, " "), " "; bold=true, color=Base.error_color())
printstyled(lpad("Fail", fail_width, " "), " "; bold=true,
color=Base.error_color())
end
if error_width > 0
printstyled(lpad("Error", error_width, " "), " "; bold=true, color=Base.error_color())
printstyled(lpad("Error", error_width, " "), " "; bold=true,
color=Base.error_color())
end
if broken_width > 0
printstyled(lpad("Broken", broken_width, " "), " "; bold=true, color=Base.warn_color())
printstyled(lpad("Broken", broken_width, " "), " "; bold=true,
color=Base.warn_color())
end
if total_width > 0
printstyled(lpad("Total", total_width, " "), " "; bold=true, color=Base.info_color())
printstyled(lpad("Total", total_width, " "), " "; bold=true,
color=Base.info_color())
end
if ts.showtiming
printstyled(lpad("Time", duration_width, " "); bold=true)
end
println()
# Recursively print a summary at every level
print_counts(ts, depth_pad, align, pass_width, fail_width, error_width, broken_width, total_width, duration_width, ts.showtiming)
return print_counts(ts, depth_pad, align, pass_width, fail_width, error_width,
broken_width, total_width, duration_width, ts.showtiming)
end

# Called at the end of a @testset, behaviour depends on whether
Expand All @@ -134,9 +143,9 @@ function Test.finish(ts::TimedTestSet)
return ts
end
passes, fails, errors, broken, c_passes, c_fails, c_errors, c_broken, duration = get_test_counts(ts)
total_pass = passes + c_passes
total_fail = fails + c_fails
total_error = errors + c_errors
total_pass = passes + c_passes
total_fail = fails + c_fails
total_error = errors + c_errors
total_broken = broken + c_broken
total = total_pass + total_fail + total_error + total_broken

Expand All @@ -152,7 +161,7 @@ function Test.finish(ts::TimedTestSet)
end

# return the testset so it is returned from the @testset macro
ts
return ts
end

# Recursive function that finds the column that the result counts
Expand All @@ -162,13 +171,13 @@ end
# in calculating the alignment
function Test.get_alignment(ts::TimedTestSet, depth::Int)
# The minimum width at this depth is
ts_width = 2*depth + length(ts.description)
ts_width = 2 * depth + length(ts.description)
# If not verbose and all passing, no need to look at children
!ts.verbose && !ts.anynonpass && return ts_width
# Return the maximum of this width and the minimum width
# for all children (if they exist)
isempty(ts.results) && return ts_width
child_widths = map(t->get_alignment(t, depth+1), ts.results)
child_widths = map(t -> get_alignment(t, depth + 1), ts.results)
return max(ts_width, maximum(child_widths))
end

Expand All @@ -179,11 +188,11 @@ function Test.filter_errors(ts::TimedTestSet)
for t in ts.results
if isa(t, TimedTestSet)
append!(efs, filter_errors(t))
elseif isa(t, Union{Fail, Error})
elseif isa(t, Union{Fail,Error})
append!(efs, [t])
end
end
efs
return efs
end

# Recursive function that counts the number of test results of each
Expand All @@ -192,13 +201,13 @@ function Test.get_test_counts(ts::TimedTestSet)
passes, fails, errors, broken = ts.n_passed, 0, 0, 0
c_passes, c_fails, c_errors, c_broken = 0, 0, 0, 0
for t in ts.results
isa(t, Fail) && (fails += 1)
isa(t, Error) && (errors += 1)
isa(t, Fail) && (fails += 1)
isa(t, Error) && (errors += 1)
isa(t, Broken) && (broken += 1)
if isa(t, TimedTestSet)
np, nf, ne, nb, ncp, ncf, nce , ncb, duration = get_test_counts(t)
np, nf, ne, nb, ncp, ncf, nce, ncb, duration = get_test_counts(t)
c_passes += np + ncp
c_fails += nf + ncf
c_fails += nf + ncf
c_errors += ne + nce
c_broken += nb + ncb
end
Expand All @@ -209,10 +218,10 @@ function Test.get_test_counts(ts::TimedTestSet)
else
dur_s = ts.time_end - ts.time_start
if dur_s < 60
string(round(dur_s, digits = 1), "s")
string(round(dur_s; digits=1), "s")
else
m, s = divrem(dur_s, 60)
s = lpad(string(round(s, digits = 1)), 4, "0")
s = lpad(string(round(s; digits=1)), 4, "0")
string(round(Int, m), "m", s, "s")
end
end
Expand All @@ -222,7 +231,8 @@ end
# Recursive function that prints out the results at each level of
# the tree of test sets
function Test.print_counts(ts::TimedTestSet, depth, align,
pass_width, fail_width, error_width, broken_width, total_width, duration_width, showtiming)
pass_width, fail_width, error_width, broken_width, total_width,
duration_width, showtiming)
# Count results by each type at this level, and recursively
# through any child test sets
passes, fails, errors, broken, c_passes, c_fails, c_errors, c_broken, duration = get_test_counts(ts)
Expand All @@ -233,40 +243,40 @@ function Test.print_counts(ts::TimedTestSet, depth, align,

np = passes + c_passes
if np > 0
printstyled(lpad(string(np), pass_width, " "), " ", color=:green)
printstyled(lpad(string(np), pass_width, " "), " "; color=:green)
elseif pass_width > 0
# No passes at this level, but some at another level
print(lpad(" ", pass_width), " ")
end

nf = fails + c_fails
if nf > 0
printstyled(lpad(string(nf), fail_width, " "), " ", color=Base.error_color())
printstyled(lpad(string(nf), fail_width, " "), " "; color=Base.error_color())
elseif fail_width > 0
# No fails at this level, but some at another level
print(lpad(" ", fail_width), " ")
end

ne = errors + c_errors
if ne > 0
printstyled(lpad(string(ne), error_width, " "), " ", color=Base.error_color())
printstyled(lpad(string(ne), error_width, " "), " "; color=Base.error_color())
elseif error_width > 0
# No errors at this level, but some at another level
print(lpad(" ", error_width), " ")
end

nb = broken + c_broken
if nb > 0
printstyled(lpad(string(nb), broken_width, " "), " ", color=Base.warn_color())
printstyled(lpad(string(nb), broken_width, " "), " "; color=Base.warn_color())
elseif broken_width > 0
# None broken at this level, but some at another level
print(lpad(" ", broken_width), " ")
end

if np == 0 && nf == 0 && ne == 0 && nb == 0
printstyled(lpad("None", total_width, " "), " ", color=Base.info_color())
printstyled(lpad("None", total_width, " "), " "; color=Base.info_color())
else
printstyled(lpad(string(subtotal), total_width, " "), " ", color=Base.info_color())
printstyled(lpad(string(subtotal), total_width, " "), " "; color=Base.info_color())
end

if showtiming
Expand All @@ -280,10 +290,11 @@ function Test.print_counts(ts::TimedTestSet, depth, align,
for t in ts.results
if isa(t, TimedTestSet)
print_counts(t, depth + 1, align,
pass_width, fail_width, error_width, broken_width, total_width, duration_width, ts.showtiming)
pass_width, fail_width, error_width, broken_width, total_width,
duration_width, ts.showtiming)
end
end
end
end

end
end
6 changes: 5 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ end
5678
end)
let a
@test_throws UndefVarError(:a) a
@static if VERSION >= v"1.11-DEV"
@test_throws UndefVarError(:a, :local) a
else
@test_throws UndefVarError(:a) a
end
@test_nowarn a = 1
@test a === 1
end
Expand Down

2 comments on commit 1e6d07e

@Jutho
Copy link
Owner Author

@Jutho Jutho commented on 1e6d07e Mar 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/102564

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.2 -m "<description of version>" 1e6d07eccc03d69f2431174781d5c83d223b6682
git push origin v0.2.2

Please sign in to comment.