# 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: - Undef is normalized to an empty string for scalar comparison. - Deep structures are dumped using Data::Dumper. 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: - simple scalars - arrays - hashes - blessed references - mixed or unexpected structures 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: - differing array lengths - missing or extra hash keys - blessed vs unblessed mismatches - Unicode differences - leading or trailing whitespace - case-only differences `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, `` # BUGS # SEE ALSO # REPOSITORY [https://github.com/nigelhorne/Test-Most-Explain](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](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: - MetaCPAN [https://metacpan.org/dist/Test-Most-Explain](https://metacpan.org/dist/Test-Most-Explain) - RT: CPAN's request tracker [https://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-Most-Explain](https://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-Most-Explain) - CPAN Testers' Matrix [http://matrix.cpantesters.org/?dist=Test-Most-Explain](http://matrix.cpantesters.org/?dist=Test-Most-Explain) - CPAN Testers Dependencies [http://deps.cpantesters.org/?module=Test::Most::Explain](http://deps.cpantesters.org/?module=Test::Most::Explain) # LICENCE AND COPYRIGHT Copyright 2026 Nigel Horne. Usage is subject to licence terms. The licence terms of this software are as follows: - Personal single user, single computer use: GPL2 - All other users (including Commercial, Charity, Educational, Government) must apply in writing for a licence for use from Nigel Horne at the above e-mail.