NAME

Test::Most::Explain - Enhanced diagnostics for Test::More with structured diffs and helpful hints

VERSION

Version 0.01

SYNOPSIS

use Test::More;
use Test::Most::Explain qw(explain);

# Use explain() directly
my $msg = explain("foo", "fob");
diag $msg;

# Or rely on automatic diagnostic enhancement
is_deeply(
    { a => 1, b => [1,2,3] },
    { a => 1, b => [1,9,3] },
    'deep structure mismatch'
);

# On failure, Test::Most::Explain replaces Test::More's
# default "got/expected" output with a structured diff
# and helpful hints.

DESCRIPTION

Test::Most::Explain provides clearer, more actionable diagnostics for failing tests. It works in two complementary ways:

Automatic enhancement of Test::More diagnostics

When the module is loaded, it installs a small wrapper around Test::Builder::diag. This wrapper detects Test::More's standard failure diagnostics:

Failed test ...
#     got: ...
# expected: ...

Whenever such output is seen, Test::Most::Explain suppresses the original diagnostics and replaces them with a structured explanation generated by explain().

This means existing test code such as:

is_deeply($got, $exp, 'something');

automatically produces richer diagnostics like:

Deep structure comparison failed:
  Got:      { ... }
  Expected: { ... }
  Possible causes:
    . Missing key in got: foo
    . Array length differs

Only Test::More-style failure messages are intercepted. All other diag() calls pass through unchanged.

Motivation

Perl's default test diagnostics are functional but terse. When complex structures differ, the default output often shows only memory addresses. Test::Most::Explain aims to provide clearer diffs, contextual hints, and more helpful deep-structure reporting without adding heavy dependencies or requiring changes to existing test code.

METHODS

explain

Purpose: Produce a human-readable explanation of differences between two values. Handles scalars, arrays, hashes, blessed references, and mixed structures.

Arguments: ($got, $exp) - any two Perl values (scalars or references).

Returns: A string describing the difference. Never dies.

Side effects: None. This routine does not emit diagnostics; it only returns a string.

Notes:

Example:

my $msg = explain("foo", "fob");
diag $msg;

The explain() routine compares two values and returns a human-readable description of how they differ. It handles:

For scalars, explain() reports the first differing character and shows context around the mismatch. For deep structures, it emits compact dumps of each side and highlights structural issues such as:

explain() never dies and always returns a string.

API Specification

Input (Params::Validate::Strict compatible)

{
    got => { type => SCALAR | ARRAYREF | HASHREF | OBJECT, optional => 1 },
    exp => { type => SCALAR | ARRAYREF | HASHREF | OBJECT, optional => 1 },
}

Output (Return::Set compatible)

{
    result => STRING,   # explanation text
}

AUTHOR

Nigel Horne, <njh at nigelhorne.com>

BUGS

SEE ALSO

REPOSITORY

https://github.com/nigelhorne/Test-Most-Explain

SUPPORT

This module is provided as-is without any warranty.

Please report any bugs or feature requests to bug-test-most-explain at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Most-Explain. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

You can find documentation for this module with the perldoc command.

perldoc Test::Most::Explain

You can also look for information at:

LICENCE AND COPYRIGHT

Copyright 2026 Nigel Horne.

Usage is subject to licence terms.

The licence terms of this software are as follows: