Skip to content

Test coverage improvements#748

Merged
rs merged 2 commits into
rs:masterfrom
IDisposable:chore/test-coverage
Jan 12, 2026
Merged

Test coverage improvements#748
rs merged 2 commits into
rs:masterfrom
IDisposable:chore/test-coverage

Conversation

@IDisposable

@IDisposable IDisposable commented Jan 12, 2026

Copy link
Copy Markdown
Contributor

Implements #397 and #591, might help with #473
Test coverage for core is 97.6% with only real fringe cases remaining.
Improve Fields isNilValue() portability.
Added a new global handler FatalExitFunc to allow intercepting Fatal() messages.
Fixed CBOR float constants (removed the CBOR prefix)

Added tests for:

  • global FatalExitFunc to allow intercepting Fatal messages (both for testing and public use).
  • Logger
    • DisableSampling
    • .With() copying existing context if present.
    • .With().Fields() all forms of ErrorStackMarshaler returns.
    • .WithLevel() for FatalLevel, PanicLevel, and DisabledLevel.
    • .Err() with nil and non-nil error and test the resulting log level.
    • .should() covering nil writer.
    • .Output() gets context values.
    • .UpdateContext() on a disabled logger doesn't panic and is a nop.
    • .With() all forms of ErrorStackMarshaler returns.
    • with a nilwriter.
  • .Hook() passing no hooks.
  • Array
    • .MarshalZerologArray is a nop that won't panic.
  • Context
    • .Err() and .AnErr() for nil errors and all forms of ErrorStackMarshaler returns.
  • Event
    • .Caller() to ensure we don't panic or add invalid information if runtime.Caller() fails
    • .Err() and .AnErr() for nil errors and all forms of ErrorStackMarshaler returns.
  • Fields
    • .appendFields() all forms of ErrorStackMarshaler returns.
  • HookLevel
    • .Run() methods.
  • LevelSampler
    • `.Sample() methods.
  • Syslog
    • .Write(), .WriteLevel(), and .Close() methods.
    • .WriteLevel() with an InvalidLevel.
  • Writer
    • .Write() short write and error cases.
    • MultiLevelWriter .WriteLevel() and for .Write() error and .Close() cases.
  • test of unmarshalling a level byte returns correct error.
  • CBOR decodeStream
    • .decodeFloat(), .binaryFmt(), .DecodeIfBinaryToString(), .DecodeObjectToStr(), .DecodeIfBinaryToBytes(), .decodeTagData(), and .decodeSimpleFloat()
    • handling of invalid UTF-8 sequences
    • handling of UTC times.
    • handling of timestamps
    • handling of various map lengths

Restructure Event .caller() so we test for ok and eliminate untestable coverage hole.

Restructure Context .Err() when the ErrorStackMarshaler returns a nil so there's code to cover.

Inverted logic forEvent .Caller()'s call to runtime.Caller() for simpler testing.

Inverted logic for Array .putArray() and Event .putEvent() so there isn't uncoverable code.

Restructure Field .appendFieldList() to early return when ErrorStackMarshaler returns a nil

Added comments for things we can't get coverage on.

Did a go fmt ./...

Coverage of core is now 100% on Array, Context, Ctx, Event, Field, Hook, and Syslog.

Coverage of Globals, Log, Sampler, and Writer is almost all except some real edge-cases.

JSON encoder coverage is 100%

CBOR encoder coverage is 96.3% with base, cbor, string, time and types at 100% and decode_stream (which it lacks coverage on some panic states, and two incorrect coverage-tool lapses)

Copilot AI review requested due to automatic review settings January 12, 2026 09:57
Comment thread internal/cbor/cbor.go
Comment thread array.go
Comment thread array.go
Comment thread console.go

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This pull request significantly improves test coverage for the zerolog library, bringing core coverage to 97.6% with several modules reaching 100%. The changes implement feature requests from issues #397 (exit function override) and #591 (Fatal call hooks), and help with #473 (Fatal behavior when disabled).

Changes:

  • Added FatalExitFunc global handler to allow intercepting Fatal() calls, enabling cleanup operations and testing
  • Fixed CBOR float constants by removing the type prefix bytes (previously incorrectly included)
  • Refactored isNilValue() function to use reflection instead of unsafe pointer operations for better portability
  • Added comprehensive test coverage for Logger, Event, Context, Array, Hook, Sampler, Writer, Syslog, and CBOR components
  • Refactored several methods with inverted logic to eliminate untestable code branches and improve readability

Reviewed changes

Copilot reviewed 19 out of 20 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
globals.go Added FatalExitFunc global variable to override fatal exit behavior
log.go Updated Fatal() to use FatalExitFunc and reformatted documentation
fields.go Replaced unsafe pointer-based isNilValue() with reflection-based implementation
event.go Inverted logic in putEvent() and caller() for better testability and added early return in Err() for nil stack marshaler results
array.go Inverted logic in putArray() for consistency with putEvent()
context.go Added early return in Err() for nil stack marshaler results
ctx.go Reformatted documentation comments
console.go Minor formatting alignment in struct initialization
internal/cbor/cbor.go Fixed float constants by removing CBOR type prefix bytes
internal/cbor/string_test.go Added tests for invalid UTF-8, embedded JSON, and embedded CBOR
internal/cbor/decoder_test.go Added comprehensive decoder tests including float decoding, timestamps, embedded types, and edge cases
internal/testcases.go Added IPv6 test case
writer_test.go Added tests for LevelWriterAdapter, SyncWriter, MultiLevelWriter, FilteredLevelWriter, and error conditions
syslog_test.go Fixed Write return value and added tests for all syslog levels, Close, and invalid level handling
sampler_test.go Added LevelSampler tests covering all log levels
log_test.go Added extensive tests for DisableSampling, stacked With(), WithLevel for all levels, Fatal/Panic disabled states, nil writer, Output with context, and UpdateContext on disabled logger
hook_test.go Added tests for Hook with no hooks and LevelHook covering all levels
event_test.go Added tests for Caller with runtime failure and ErrorStackMarshaler with various return types
context_test.go Added tests for ErrorStackMarshaler with various return types in context operations
array_test.go Added test for MarshalZerologArray no-op method

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread fields.go
Comment thread context.go
Comment thread ctx.go
Comment thread event.go
Comment thread event.go
Comment thread event.go
Comment thread fields.go
Comment thread fields.go
Comment thread globals.go
Comment thread log.go
Comment thread log.go

@IDisposable IDisposable left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@rs this gets zerolog to almost complete code coverage and adds the global FatalExitFunc feature which has been requested (and I needed to be able to cover those parts of Logger.

I think this should wrap up pretty much everything I was expecting to address here, so a release would be welcome, and I would be happy to address any outstanding issues you would like addressed.

Implements rs#397 and rs#591, might help with rs#473
Test coverage for core is 97.6% with only real fringe cases remaining.
Improve `Fields` `isNilValue()` portability.
Added a new global handler `FatalExitFunc` to allow intercepting `Fatal()` messages.
Fixed CBOR float constants (removed the CBOR prefix)

Added tests for:
  - global `FatalExitFunc` to allow intercepting Fatal messages (both for testing and public use).
  - `Logger`
    -  `DisableSampling`
    -  `.With()` copying existing context if present.
    -  `.With().Fields()` all forms of `ErrorStackMarshaler` returns.
    - `.WithLevel()` for `FatalLevel`, `PanicLevel`, and `DisabledLevel`.
    - `.Err()` with `nil` and non-`nil` `error` and test the resulting log level.
    - `.should()` covering `nil` writer.
    - `.Output()` gets context values.
    - `.UpdateContext()` on a disabled logger doesn't panic and is a nop.
    - `.With()` all forms of `ErrorStackMarshaler` returns.
  - with a `nil`writer.
  - `.Hook()` passing no hooks.
- `Array`
  - `.MarshalZerologArray` is a nop that won't panic.
- `Context`
  - ` .Err()` and `.AnErr()` for `nil` errors and all forms of `ErrorStackMarshaler` returns.
  - `Event`
    - `.Caller()` to ensure we don't panic or add invalid information if `runtime.Caller()` fails
    -` .Err()` and `.AnErr()` for `nil` errors and all forms of `ErrorStackMarshaler` returns.
  - `Fields`
    - ` .appendFields()`  all forms of `ErrorStackMarshaler` returns.
  - `HookLevel`
    - `.Run()` methods.
  - `LevelSampler`
    - `.Sample() methods.
  - `Syslog`
    - `.Write()`, `.WriteLevel()`, and `.Close()` methods.
    - `.WriteLevel()` with an `InvalidLevel`.
  - `Writer`
    - `.Write()` short write and error cases.
    - `MultiLevelWriter` `.WriteLevel()` and for `.Write()` error and  `.Close()` cases.
  - test of unmarshalling a level byte returns correct error.
  - CBOR decodeStream
    - `.decodeFloat()`, `.binaryFmt()`, `.DecodeIfBinaryToString()`, `.DecodeObjectToStr()`, `.DecodeIfBinaryToBytes()`, `.decodeTagData()`, and `.decodeSimpleFloat()`
    - handling of invalid UTF-8 sequences
    - handling of UTC times.
    - handling of timestamps
    - handling of various map lengths

Restructure `Event` `.caller()` so we test for ok and eliminate untestable coverage hole.

Restructure `Context` `.Err()` when the `ErrorStackMarshaler` returns a `nil` so there's code to cover.

Inverted logic for`Event` `.Caller()`'s call to `runtime.Caller()` for simpler testing.

Inverted logic for `Array` `.putArray()` and `Event` `.putEvent()` so there isn't uncoverable code.

Restructure `Field` `.appendFieldList()` to early return when `ErrorStackMarshaler` returns a `nil`

Added comments for things we can't get coverage on.

Did a go fmt ./...

Coverage of core is now 100% on `Array`, `Context`, `Ctx`, `Event`, `Field`, `Hook`, and `Syslog`.

Coverage of `Globals`, `Log`, `Sampler`, and `Writer` is almost all except some real edge-cases.

JSON encoder coverage is 100%

CBOR encoder coverage is 96.3% with base, cbor, string, time and types at 100% and decode_stream (which is lacks coverage on some panic states, and two incorrect coverage-tool lapses)
Forgot to use the `decodeIfBinaryToString()`
Comment thread context_test.go
@rs rs requested a review from Copilot January 12, 2026 14:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 20 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/cbor/string_test.go
Comment thread fields.go
Comment thread log_test.go
@rs rs merged commit f6fbd33 into rs:master Jan 12, 2026
5 checks passed
@IDisposable IDisposable deleted the chore/test-coverage branch January 12, 2026 15:29
walsm232 added a commit to walsm232/zerolog that referenced this pull request Apr 6, 2026
A nil return from ErrorStackMarshaler means no stack trace is
available, not that the error itself should be omitted. Restore
pre-v1.35 behavior where Err() continues to call AnErr() so the
error field is always recorded.
Fixes a regression introduced in rs#748.

Signed-off-by: Michael Walsh <michael.walsh@elastic.co>
walsm232 added a commit to walsm232/zerolog that referenced this pull request Apr 6, 2026
A nil return from ErrorStackMarshaler means no stack trace is
available, not that the error itself should be omitted. Restore
pre-v1.35 behavior where Err() continues to call AnErr() so the
error field is always recorded.
Fixes a regression introduced in rs#748.

Signed-off-by: Michael Walsh <michael.walsh@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants