aboutsummaryrefslogtreecommitdiff
blob: 2930ea11231c6f880c01808f8d08e8be54a4fa39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.


##################
#Bugzilla Test 11#
##POD validation##

use 5.10.1;
use strict;
use warnings;

use lib 't';

use Support::Files;
use Pod::Checker;
use Pod::Coverage;

use Test::More tests => scalar(@Support::Files::testitems)
  + scalar(@Support::Files::module_files);

# These methods do not need to be documented by default.
use constant DEFAULT_WHITELIST =>
  qr/^(?:new|new_from_list|check|run_create_validators)$/;

# These subroutines do not need to be documented, generally because
# you shouldn't call them yourself. No need to include subroutines
# of the form _foo(); they are already treated as private.
use constant SUB_WHITELIST => (
  'Bugzilla::Flag'     => qr/^(?:(force_)?retarget|force_cleanup)$/,
  'Bugzilla::FlagType' => qr/^sqlify_criteria$/,
  'Bugzilla::JobQueue' => qr/(?:^work_once|work_until_done|subprocess_worker)$/,
  'Bugzilla::Search'   => qr/^SPECIAL_PARSING$/,
  'Bugzilla::Template' => qr/^field_name$/,
  'Bugzilla::MIME'     => qr/^as_string$/,
);

# These modules do not need to be documented, generally because they
# are subclasses of another module which already has all the relevant
# documentation. Partial names are allowed.
use constant MODULE_WHITELIST => qw(
  Bugzilla::Auth::Login::
  Bugzilla::Auth::Persist::
  Bugzilla::Auth::Verify::
  Bugzilla::BugUrl::
  Bugzilla::Config::
  Bugzilla::Extension::
  Bugzilla::Job::
  Bugzilla::Migrate::
  docs::lib::Pod::Simple::
);

# Capture the TESTOUT from Test::More or Test::Builder for printing errors.
# This will handle verbosity for us automatically.
my $fh;
{
  no warnings qw(unopened);    # Don't complain about non-existent filehandles
  if (-e \*Test::More::TESTOUT) {
    $fh = \*Test::More::TESTOUT;
  }
  elsif (-e \*Test::Builder::TESTOUT) {
    $fh = \*Test::Builder::TESTOUT;
  }
  else {
    $fh = \*STDOUT;
  }
}

my @testitems = @Support::Files::testitems;

foreach my $file (@testitems) {
  $file =~ s/\s.*$//;    # nuke everything after the first space (#comment)
  next if (!$file);      # skip null entries
  my $error_count = podchecker($file, $fh);
  if ($error_count < 0) {
    ok(1, "$file does not contain any POD");
  }
  elsif ($error_count == 0) {
    ok(1, "$file has correct POD syntax");
  }
  else {
    ok(0, "$file has incorrect POD syntax --ERROR");
  }
}

my %sub_whitelist = SUB_WHITELIST;
my @module_files  = sort @Support::Files::module_files;

foreach my $file (@module_files) {
  my $module = $file;
  $module =~ s/\.pm$//;
  $module =~ s#/#::#g;
  $module =~ s/^extensions/Bugzilla::Extension/;

  my @whitelist = (DEFAULT_WHITELIST);
  push(@whitelist, $sub_whitelist{$module}) if $sub_whitelist{$module};

  # XXX Once all methods are correctly documented, nonwhitespace should
  # be set to 1.
  my $cover = Pod::Coverage->new(
    package       => $module,
    nonwhitespace => 0,
    trustme       => \@whitelist
  );
  my $coverage = $cover->coverage;
  my $reason   = $cover->why_unrated;

  if (defined $coverage) {
    if ($coverage == 1) {
      ok(1, "$file has POD for all methods");
    }
    else {
      ok(0,
            "$file POD coverage is "
          . sprintf("%u%%", 100 * $coverage)
          . ". Undocumented methods: "
          . join(', ', $cover->uncovered));
    }
  }

  # These errors are thrown when the module couldn't be loaded due to
  # a missing dependency.
  elsif ($reason =~ /^(?:no public symbols defined|requiring '[^']+' failed)$/) {
    ok(1, "$file cannot be loaded");
  }
  elsif ($reason eq "couldn't find pod") {
    if (grep { $module =~ /^\Q$_\E/ } MODULE_WHITELIST) {
      ok(1, "$file does not contain any POD (whitelisted)");
    }
    else {
      ok(0, "$file POD coverage is 0%");
    }
  }
  else {
    ok(0, "$file: $reason");
  }
}

exit 0;