NAME

Test::CPAN::Health::Check::PODCoverage - Check that all public methods have POD

SYNOPSIS

use Test::CPAN::Health::Check::PODCoverage;

my $check  = Test::CPAN::Health::Check::PODCoverage->new;
my $result = $check->run($dist);

printf "%s: %s\n", $result->status, $result->summary;

DESCRIPTION

Parses each .pm file under lib/ to identify public subroutines (those not prefixed with _ and not in the exempt set: DESTROY, AUTOLOAD, BEGIN, END, etc.) and checks whether each one appears as a =head2, =head3, or =head4 entry in the file's POD.

Score = (documented_subs / total_public_subs) * 100, averaged across all files. Status thresholds: pass ≥ 90, warn ≥ 50, fail otherwise.

LIMITATIONS

  • Documentation inherited from a parent class is not counted -- each file is analysed in isolation.

  • Only =head2/=head3/=head4 headings are matched against sub names; =item entries are not counted.

  • Generated or XS subs not visible in the .pm source are not counted.

run

PURPOSE

Compute the fraction of public subroutines that have a corresponding POD heading across all .pm files in the distribution.

API SPECIFICATION

INPUT

dist     Test::CPAN::Health::Distribution  required
context  Hashref                           optional

OUTPUT

Test::CPAN::Health::Result with check_id 'pod_coverage'.

MESSAGES

Code  | Severity | Message                                    | Resolution
------+----------+--------------------------------------------+-----------
PC001 | SKIP     | No .pm files found under lib/              | Add lib/ modules
PC002 | SKIP     | No public subs found in any .pm file       | Add public methods
PC003 | PASS     | POD coverage N%                            |
PC004 | WARN     | POD coverage N% -- some methods undocumented| Add POD
PC005 | FAIL     | POD coverage N% -- most methods undocumented| Add POD

FORMAL SPECIFICATION

-- Z schema (placeholder) --
PODCoverageOp
subs_total    : N
subs_covered  : N
score         : 0..100
-------------------------------------------------------
subs_total = 0    => status = skip
score >= 90       => status = pass
score >= 50       => status = warn
score < 50        => status = fail

SIDE EFFECTS

Reads source files; no network or subprocess I/O.

USAGE EXAMPLE

my $result = Test::CPAN::Health::Check::PODCoverage->new->run($dist);
print $result->summary;

AUTHOR

Nigel Horne, <njh at nigelhorne.com>

LICENSE AND COPYRIGHT

Copyright (C) 2025-2026 Nigel Horne.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.