From da97cac2f645446f67b43b6e07245a615500a52e Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Tue, 8 Feb 2022 14:26:53 -0500 Subject: [PATCH] Test: document and export `TestLogger` and `LogRecord`. --- NEWS.md | 3 +++ stdlib/Test/docs/src/index.md | 11 +++++++- stdlib/Test/src/Test.jl | 1 + stdlib/Test/src/logging.jl | 51 ++++++++++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 76896ab2bad24..053ed9e711ecb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -206,6 +206,9 @@ Standard library changes function is provided to reproduce the mapping used in identifier normalization by the Julia parser ([#42561]). +#### Test +* `TestLogger` and `LogRecord` are now exported from the Test stdlib. ([#44080]) + Deprecated or removed --------------------- diff --git a/stdlib/Test/docs/src/index.md b/stdlib/Test/docs/src/index.md index 0409c33a3fabf..077d350554775 100644 --- a/stdlib/Test/docs/src/index.md +++ b/stdlib/Test/docs/src/index.md @@ -200,6 +200,16 @@ Foo Tests | 3 1 4 0.0s ERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken. ``` +## Testing Log Statements + +One can use the [`@test_logs`](@ref) macro to test log statements, or use a [`TestLogger`](@ref). + +```@docs +Test.@test_logs +Test.TestLogger +Test.LogRecord +``` + ## Other Test Macros As calculations on floating-point values can be imprecise, you can perform approximate equality @@ -226,7 +236,6 @@ Note that this is not a specific feature of the `≈` but rather a general featu ```@docs Test.@inferred -Test.@test_logs Test.@test_deprecated Test.@test_warn Test.@test_nowarn diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index bd281e41b7ccd..bd5f9d3fbba5a 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -22,6 +22,7 @@ export @inferred export detect_ambiguities, detect_unbound_args export GenericString, GenericSet, GenericDict, GenericArray, GenericOrder export TestSetException +export TestLogger, LogRecord using Random using Random: AbstractRNG, default_rng diff --git a/stdlib/Test/src/logging.jl b/stdlib/Test/src/logging.jl index b8e4d00e33b5b..d7146b121d47d 100644 --- a/stdlib/Test/src/logging.jl +++ b/stdlib/Test/src/logging.jl @@ -4,7 +4,20 @@ using Logging: Logging, AbstractLogger, LogLevel, Info, with_logger import Base: occursin #------------------------------------------------------------------------------- -# Log records +""" + LogRecord + +Stores the results of a single log event. Fields: + +* `level`: the [`LogLevel`](@ref) of the log message +* `message`: the textual content of the log message +* `_module`: the module of the log event +* `group`: the logging group (by default, the name of the file containing the log event) +* `id`: the ID of the log event +* `file`: the file containing the log event +* `line`: the line within the file of the log event +* `kwargs`: any keyword arguments passed to the log event +""" struct LogRecord level message @@ -30,6 +43,42 @@ mutable struct TestLogger <: AbstractLogger respect_maxlog::Bool end +""" + TestLogger(; min_level=Info, catch_exceptions=false) + +Create a `TestLogger` which captures logged messages in its `logs::Vector{LogRecord}` field. + +Set `min_level` to control the `LogLevel`, `catch_exceptions` for whether or not exceptions +thrown as part of log event generation should be caught, and `respect_maxlog` for whether +or not to follow the convention of logging messages with `maxlog=n` for some integer `n` at +most `n` times. + +See also: [`LogRecord`](@ref). + +## Example + +```jldoctest +julia> using Test, Logging + +julia> f() = @info "Hi" number=5; + +julia> test_logger = TestLogger(); + +julia> with_logger(test_logger) do + f() + @info "Bye!" + end + +julia> @test test_logger.logs[1].message == "Hi" +Test Passed + +julia> @test test_logger.logs[1].kwargs[:number] == 5 +Test Passed + +julia> @test test_logger.logs[2].message == "Bye!" +Test Passed +``` +""" TestLogger(; min_level=Info, catch_exceptions=false, respect_maxlog=true) = TestLogger(LogRecord[], min_level, catch_exceptions, nothing, Dict{Any, Int}(), respect_maxlog) Logging.min_enabled_level(logger::TestLogger) = logger.min_level