File Coverage

blib/lib/Test/NewVersion.pm
Criterion Covered Total %
statement 88 91 96.7
branch 20 30 66.6
condition 11 21 52.3
subroutine 22 22 100.0
pod 2 2 100.0
total 143 166 86.1


line stmt bran cond sub pod time code
1 3     3   115852 use strict;
  3         5  
  3         122  
2 3     3   13 use warnings;
  3         4  
  3         160  
3             package Test::NewVersion; # git description: v0.001-3-g256c382
4             # ABSTRACT: provides a test interface for checking that you are using a new $VERSION
5             # KEYWORDS: test distribution release author version unique new
6             # vim: set ts=8 sw=4 tw=78 et :
7              
8             our $VERSION = '0.002';
9              
10 3     3   933 use parent 'Exporter';
  3         612  
  3         19  
11             our @EXPORT = qw(all_new_version_ok new_version_ok);
12              
13 3     3   190 use File::Find;
  3         41  
  3         226  
14 3     3   14 use File::Spec;
  3         3  
  3         49  
15 3     3   1900 use Encode ();
  3         33443  
  3         119  
16 3     3   2372 use HTTP::Tiny;
  3         190043  
  3         169  
17 3     3   2136 use JSON::MaybeXS;
  3         24525  
  3         263  
18 3     3   2055 use version;
  3         6427  
  3         29  
19 3     3   2557 use Module::Metadata;
  3         25608  
  3         162  
20 3     3   26 use List::Util 'first';
  3         5  
  3         373  
21 3     3   2219 use CPAN::Meta 2.120920;
  3         81628  
  3         106  
22 3     3   31 use Test::Builder 0.88;
  3         57  
  3         66  
23 3     3   1898 use namespace::clean;
  3         46640  
  3         19  
24              
25             my $no_plan;
26              
27             sub import
28             {
29             # END block will check for this status
30 3     3   23 my @symbols = grep { $_ ne ':no_plan' } @_;
  3         10  
31 3         7 $no_plan = (@symbols != @_);
32              
33 3         508 __PACKAGE__->export_to_level(1, @symbols);
34             }
35              
36             # for testing this module only!
37             my $tb;
38             sub _builder(;$)
39             {
40 3 50   3   16 if (not @_)
41             {
42 3   33     28 $tb ||= Test::Builder->new;
43 3         41 return $tb;
44             }
45              
46 0         0 $tb = shift;
47             }
48              
49             END {
50 3 50 33 3   32852 if (not $no_plan
      33        
51             and not _builder->expected_tests
52             # skip this if no tests have been run (e.g. compilation tests of this module!)
53             and (_builder->current_test > 0)
54             )
55             {
56 0         0 _builder->done_testing;
57             }
58             }
59              
60              
61             sub all_new_version_ok
62             {
63             # find all files in blib or lib
64 3     3 1 566 my @files;
65 3         10 my @lib_dirs = grep { -d } qw(blib/lib lib);
  6         62  
66              
67             find(
68             {
69             wanted => sub {
70 16 100 66 16   956 push @files, File::Spec->no_upwards($File::Find::name)
      100        
71             if -r $File::Find::name
72             and $File::Find::name =~ /\.pm$/ or $File::Find::name =~ /\.pod$/;
73             },
74 3 50       304 no_chdir => 1,
75             },
76             $lib_dirs[0],
77             ) if @lib_dirs;
78              
79             # also add .pod, .pm files in the top level directory
80 3         240 push @files, grep { -f } glob('*.pod'), glob('*.pm');
  0         0  
81              
82 3         41 new_version_ok($_) foreach sort @files;
83             }
84              
85             sub new_version_ok
86             {
87 9     9 1 835 my $filename = shift;
88              
89 9         135 my $builder = Test::Builder->new;
90              
91 9         112 my $module_metadata = Module::Metadata->new_from_file($filename);
92 9         6771 foreach my $pkg ($module_metadata->packages_inside)
93             {
94 8 50       83 next if $pkg eq 'main';
95 8         28 my ($bumped, $message) = _version_is_bumped($module_metadata, $pkg);
96              
97 8         32 local $Test::Builder::Level = $Test::Builder::Level + 1;
98 8 50       120 $builder->ok($bumped, $pkg . ' (' . $filename . ') VERSION is ok'
99             . ( $message ? (' (' . $message . ')') : '' )
100             );
101             }
102             }
103              
104             # 'provides' field from dist metadata, if needed
105             my $dist_provides;
106              
107             # returns bool, detailed message
108             sub _version_is_bumped
109             {
110 8     8   13 my ($module_metadata, $pkg) = @_;
111              
112 8         63 my $res = HTTP::Tiny->new->get("http://cpanidx.org/cpanidx/json/mod/$pkg");
113 8 50       181445 return (0, 'index could not be queried?') if not $res->{success};
114              
115 8         30 my $data = $res->{content};
116              
117 8         28129 require HTTP::Headers;
118 8 50       32168 if (my $charset = HTTP::Headers->new(%{ $res->{headers} })->content_type_charset)
  8         100  
119             {
120 8         6424 $data = Encode::decode($charset, $data, Encode::FB_CROAK);
121             }
122              
123 8         1176 my $payload = decode_json($data);
124 8 50       32 return (0, 'invalid payload returned') unless $payload;
125 8 100       69 return (1, 'not indexed') if not defined $payload->[0]{mod_vers};
126 4 100       22 return (1, 'VERSION is not set in index') if $payload->[0]{mod_vers} eq 'undef';
127              
128 3         43 my $indexed_version = version->parse($payload->[0]{mod_vers});
129 3         19 my $current_version = $module_metadata->version($pkg);
130              
131 3 100       43 if (not defined $current_version)
132             {
133 2   66     6 $dist_provides ||= do {
134 1     3   10 my $metafile = first { -e $_ } qw(MYMETA.json MYMETA.yml META.json META.yml);
  3         26  
135 1 50       21 my $dist_metadata = $metafile ? CPAN::Meta->load_file($metafile) : undef;
136 1 50       5731 $dist_metadata->provides if $dist_metadata;
137             };
138              
139 2         661 $current_version = $dist_provides->{$pkg}{version};
140 2 100 33     50 return (0, 'VERSION is not set; indexed version is ' . $indexed_version)
141             if not $dist_provides or not $current_version;
142             }
143              
144             return (
145 2         71 $indexed_version < $current_version,
146             'indexed at ' . $indexed_version . '; local version is ' . $current_version,
147             );
148             }
149              
150             1;
151              
152             __END__