File Coverage

blib/lib/App/Midgen/Role/TestRequires.pm
Criterion Covered Total %
statement 18 76 23.6
branch 0 46 0.0
condition 0 14 0.0
subroutine 6 9 66.6
pod 1 1 100.0
total 25 146 17.1


line stmt bran cond sub pod time code
1             package App::Midgen::Role::TestRequires;
2              
3 2     2   921 use constant {BLANK => q{ }, NONE => q{}, TWO => 2, THREE => 3,};
  2         3  
  2         148  
4              
5 2     2   7 use Moo::Role;
  2         4  
  2         10  
6             requires
7             qw( ppi_document develop debug verbose format xtest _process_found_modules meta2 );
8              
9 2     2   3343 use PPI;
  2         2  
  2         32  
10 2     2   8 use Try::Tiny;
  2         3  
  2         199  
11 2     2   9 use Data::Printer {caller_info => 1,};
  2         3  
  2         21  
12              
13             # Load time and dependencies negate execution time
14             # use namespace::clean -except => 'meta';
15              
16             our $VERSION = '0.33_05';
17             $VERSION = eval $VERSION; ## no critic
18              
19              
20             #######
21             # composed method - xtests_test_requires
22             #######
23             sub xtests_test_requires {
24 0     0 1   my $self = shift;
25 0   0       my $phase_relationship = shift || NONE;
26              
27 0           my @modules;
28             my @version_strings;
29              
30             # PPI::Statement::Include
31             # PPI::Token::Word 'use'
32             # PPI::Token::Whitespace ' '
33             # PPI::Token::Word 'Test::Requires'
34             # PPI::Token::Whitespace ' '
35             # PPI::Structure::Constructor { ... }
36             # PPI::Token::Whitespace ' '
37             # PPI::Statement
38             # PPI::Token::Quote::Single ''Test::Pod''
39             # PPI::Token::Whitespace ' '
40             # PPI::Token::Operator '=>'
41             # PPI::Token::Whitespace ' '
42             # PPI::Token::Number::Float '1.46'
43             # PPI::Token::Whitespace ' '
44             # PPI::Token::Structure ';'
45              
46             try {
47             my @chunks
48 0 0   0     = @{$self->ppi_document->find('PPI::Statement::Include') || []};
  0            
49              
50 0           foreach my $hunk (@chunks) {
51              
52             # test for use
53 0 0         if (
54             $hunk->find(
55             sub {
56 0 0         $_[1]->isa('PPI::Token::Word')
57             and $_[1]->content =~ m{\A(?:use)\z};
58             }
59             )
60             )
61             {
62              
63             # test for Test::Requires
64 0 0         if (
65             $hunk->find(
66             sub {
67 0 0         $_[1]->isa('PPI::Token::Word')
68             and $_[1]->content =~ m{\A(?:Test::Requires)\z};
69             }
70             )
71             )
72             {
73              
74 0           foreach (0 .. $#{$hunk->{children}}) {
  0            
75              
76             # looking for use Test::Requires { 'Test::Pod' => '1.46' };
77 0 0         if ($hunk->{children}[$_]->isa('PPI::Structure::Constructor')) {
78              
79             my $ppi_sc = $hunk->{children}[$_]
80 0 0         if $hunk->{children}[$_]->isa('PPI::Structure::Constructor');
81              
82 0           foreach (0 .. $#{$ppi_sc->{children}}) {
  0            
83              
84 0 0         if ($ppi_sc->{children}[$_]->isa('PPI::Statement')) {
85              
86             my $ppi_s = $ppi_sc->{children}[$_]
87 0 0         if $ppi_sc->{children}[$_]->isa('PPI::Statement');
88              
89 0           foreach my $element (@{$ppi_s->{children}}) {
  0            
90              
91             # extract module name
92 0 0 0       if ( $element->isa('PPI::Token::Quote::Double')
      0        
93             || $element->isa('PPI::Token::Quote::Single')
94             || $element->isa('PPI::Token::Word'))
95             {
96 0           my $module_name = $element->content;
97 0           $module_name =~ s/(?:'|")//g;
98 0 0         if ($module_name =~ m/\A(?:[a-zA-Z])/) {
99 0 0         print "found module - $module_name\n" if $self->debug;
100 0           push @modules, $module_name;
101 0           $version_strings[$#modules] = undef;
102             }
103             }
104              
105             # extract version string
106 0 0 0       if ( $element->isa('PPI::Token::Number::Float')
      0        
107             || $element->isa('PPI::Token::Quote::Double')
108             || $element->isa('PPI::Token::Quote::Single'))
109             {
110 0           my $version_string = $element->content;
111 0           $version_string =~ s/(?:'|")//g;
112 0 0         if ($version_string =~ m/\A(?:[0-9])/) {
113              
114 0 0         $version_string
115             = version::is_lax($version_string)
116             ? $version_string
117             : 0;
118              
119 0 0         print "found version string - $version_string\n"
120             if $self->debug;
121 0           $self->{found_version}{$modules[$#modules]}
122             = $version_string;
123 0           $version_strings[$#modules] = $version_string;
124             }
125             }
126             }
127             }
128             }
129             }
130              
131             # looking for use Test::Requires qw(MIME::Types);
132 0 0         if ($hunk->{children}[$_]->isa('PPI::Token::QuoteLike::Words')) {
133              
134             my $ppi_tqw = $hunk->{children}[$_]
135 0 0         if $hunk->{children}[$_]->isa('PPI::Token::QuoteLike::Words');
136              
137 0           my $operator = $ppi_tqw->{operator};
138 0           my @type = split(//, $ppi_tqw->{sections}->[0]->{type});
139              
140 0           my $module = $ppi_tqw->{content};
141 0           $module =~ s/$operator//;
142 0           my $type_open = '\A\\' . $type[0];
143              
144 0           $module =~ s{$type_open}{};
145 0           my $type_close = '\\' . $type[1] . '\Z';
146              
147 0           $module =~ s{$type_close}{};
148 0           push @modules, split(BLANK, $module);
149 0           $version_strings[$#modules] = undef;
150             }
151             }
152             }
153             }
154             }
155 0           };
156              
157 0 0         @version_strings = map { defined $_ ? $_ : 0 } @version_strings;
  0            
158 0 0         p @modules if $self->debug;
159 0 0         p @version_strings if $self->debug;
160              
161 0 0         if (scalar @modules > 0) {
162              
163 0           for (0 .. $#modules) {
164 0 0         print
165             "Info: TestRequires -> Sending $modules[$_] - $version_strings[$_]\n"
166             if ($self->verbose == TWO);
167             try {
168 0     0     $self->_process_found_modules(
169             $phase_relationship, $modules[$_], $version_strings[$_],
170             __PACKAGE__, $phase_relationship,
171             );
172 0           };
173             }
174             }
175 0           return;
176             }
177              
178 2     2   3100 no Moo::Role;
  2         4  
  2         10  
179              
180             1;
181              
182             __END__
183              
184             =pod
185              
186             =encoding UTF-8
187              
188             =head1 NAME
189              
190             App::Midgen::Role::TestRequires - extra checks for test files, looking
191             for methods in use L<Test::Requires> blocks, used by L<App::Midgen>
192              
193             =head1 VERSION
194              
195             version: 0.33_05
196              
197             =head1 METHODS
198              
199             =over 4
200              
201             =item * xtests_test_requires
202              
203             Checking for the following, extracting module name and version string.
204              
205             use Test::Requires { 'Test::Pod' => 1.46 };
206             use Test::Requires { 'Test::Extra' => 1.46 };
207             use Test::Requires qw[MIME::Types];
208             use Test::Requires qw(IO::Handle::Util LWP::Protocol::http10);
209             use Test::Requires {
210             "Test::Test1" => '1.01',
211             'Test::Test2' => 2.02,
212             };
213              
214             Used to check files in t/ and xt/ directories.
215              
216             =back
217              
218             =head1 AUTHOR
219              
220             See L<App::Midgen>
221              
222             =head2 CONTRIBUTORS
223              
224             See L<App::Midgen>
225              
226             =head1 COPYRIGHT
227              
228             See L<App::Midgen>
229              
230             =head1 LICENSE
231              
232             This library is free software; you can redistribute it and/or modify
233             it under the same terms as Perl itself.
234              
235             =cut