File Coverage

blib/lib/Test/NewVersion.pm
Criterion Covered Total %
statement 84 88 95.4
branch 20 30 66.6
condition 11 21 52.3
subroutine 21 21 100.0
pod 2 2 100.0
total 138 162 85.1


line stmt bran cond sub pod time code
1 3     3   131180 use strict;
  3         8  
  3         133  
2 3     3   19 use warnings;
  3         4  
  3         190  
3             package Test::NewVersion; # git description: v0.002-7-g29dae93
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 sts=4 sw=4 tw=78 et :
7              
8             our $VERSION = '0.003';
9              
10 3     3   1055 use parent 'Exporter';
  3         582  
  3         22  
11             our @EXPORT = qw(all_new_version_ok new_version_ok);
12              
13 3     3   236 use File::Find ();
  3         6  
  3         55  
14 3     3   17 use File::Spec;
  3         4  
  3         67  
15 3     3   2035 use Encode ();
  3         29605  
  3         82  
16 3     3   2116 use HTTP::Tiny;
  3         135138  
  3         191  
17 3     3   1800 use JSON::MaybeXS ();
  3         18110  
  3         73  
18 3     3   1472 use version ();
  3         5080  
  3         92  
19 3     3   1956 use Module::Metadata;
  3         21632  
  3         174  
20 3     3   24 use List::Util;
  3         5  
  3         214  
21 3     3   1978 use CPAN::Meta 2.120920;
  3         76832  
  3         128  
22 3     3   34 use Test::Builder 0.88;
  3         80  
  3         2885  
23              
24             my $no_plan;
25              
26             sub import
27             {
28             # END block will check for this status
29 3     3   33 my @symbols = grep { $_ ne ':no_plan' } @_;
  3         13  
30 3         9 $no_plan = (@symbols != @_);
31              
32 3         454 __PACKAGE__->export_to_level(1, @symbols);
33             }
34              
35             # for testing this module only!
36             my $tb;
37             sub _builder(;$)
38             {
39 3 50   3   14 if (not @_)
40             {
41 3   33     23 $tb ||= Test::Builder->new;
42 3         40 return $tb;
43             }
44              
45 0         0 $tb = shift;
46             }
47              
48             END {
49 3 50 33 3   34062 if (not $no_plan
      33        
50             and not _builder->expected_tests
51             # skip this if no tests have been run (e.g. compilation tests of this module!)
52             and (_builder->current_test > 0)
53             )
54             {
55 0         0 _builder->done_testing;
56             }
57             }
58              
59              
60             sub all_new_version_ok
61             {
62             # find all files in blib or lib
63 3     3 1 610 my @files;
64 3         9 my @lib_dirs = grep { -d } qw(blib/lib lib);
  6         57  
65              
66             File::Find::find(
67             {
68             wanted => sub {
69 16 100 66 16   1243 push @files, File::Spec->no_upwards($File::Find::name)
      100        
70             if -r $File::Find::name
71             and $File::Find::name =~ /\.pm$/ or $File::Find::name =~ /\.pod$/;
72             },
73 3 50       297 no_chdir => 1,
74             },
75             $lib_dirs[0],
76             ) if @lib_dirs;
77              
78             # also add .pod, .pm files in the top level directory
79 3         289 push @files, grep { -f } glob('*.pod'), glob('*.pm');
  0         0  
80              
81 3         34 new_version_ok($_) foreach sort @files;
82             }
83              
84             sub new_version_ok
85             {
86 9     9 1 912 my $filename = shift;
87              
88 9         62 my $builder = Test::Builder->new;
89              
90 9         104 my $module_metadata = Module::Metadata->new_from_file($filename);
91 9         6272 foreach my $pkg ($module_metadata->packages_inside)
92             {
93 8 50       130 next if $pkg eq 'main';
94 8         29 my ($bumped, $message) = _version_is_bumped($module_metadata, $pkg);
95              
96 8         25 local $Test::Builder::Level = $Test::Builder::Level + 1;
97 8 50       132 $builder->ok($bumped, $pkg . ' (' . $filename . ') VERSION is ok'
98             . ( $message ? (' (' . $message . ')') : '' )
99             );
100             }
101             }
102              
103             # 'provides' field from dist metadata, if needed
104             my $dist_provides;
105              
106             # returns bool, detailed message
107             sub _version_is_bumped
108             {
109 8     8   13 my ($module_metadata, $pkg) = @_;
110              
111 8         63 my $res = HTTP::Tiny->new->get("http://cpanidx.org/cpanidx/json/mod/$pkg");
112 8 50       4240 return (0, 'index could not be queried?') if not $res->{success};
113              
114 8         17 my $data = $res->{content};
115              
116 8         1910 require HTTP::Headers;
117 8 50       21718 if (my $charset = HTTP::Headers->new(%{ $res->{headers} })->content_type_charset)
  8         76  
118             {
119 0         0 $data = Encode::decode($charset, $data, Encode::FB_CROAK);
120             }
121              
122 8         5060 my $payload = JSON::MaybeXS::decode_json($data);
123 8 50       30 return (0, 'invalid payload returned') unless $payload;
124 8 100       57 return (1, 'not indexed') if not defined $payload->[0]{mod_vers};
125 4 100       24 return (1, 'VERSION is not set in index') if $payload->[0]{mod_vers} eq 'undef';
126              
127 3         38 my $indexed_version = version->parse($payload->[0]{mod_vers});
128 3         16 my $current_version = $module_metadata->version($pkg);
129              
130 3 100       46 if (not defined $current_version)
131             {
132 2   66     9 $dist_provides ||= do {
133 1     3   21 my $metafile = List::Util::first { -e $_ } qw(MYMETA.json MYMETA.yml META.json META.yml);
  3         27  
134 1 50       19 my $dist_metadata = $metafile ? CPAN::Meta->load_file($metafile) : undef;
135 1 50       8476 $dist_metadata->provides if $dist_metadata;
136             };
137              
138 2         1119 $current_version = $dist_provides->{$pkg}{version};
139 2 100 33     77 return (0, 'VERSION is not set; indexed version is ' . $indexed_version)
140             if not $dist_provides or not $current_version;
141             }
142              
143             return (
144 2         85 $indexed_version < $current_version,
145             'indexed at ' . $indexed_version . '; local version is ' . $current_version,
146             );
147             }
148              
149             1;
150              
151             __END__