File Coverage

blib/lib/PDF/PDFUnit.pm
Criterion Covered Total %
statement 75 173 43.3
branch 12 60 20.0
condition 6 19 31.5
subroutine 18 22 81.8
pod 0 7 0.0
total 111 281 39.5


line stmt bran cond sub pod time code
1             #####################
2             package PDF::PDFUnit;
3             #####################
4 4     4   70624 use strict;
  4         7  
  4         84  
5 4     4   14 use warnings;
  4         5  
  4         74  
6 4     4   12 use feature ':5.10';
  4         8  
  4         378  
7 4     4   17 use File::Basename;
  4         3  
  4         234  
8 4     4   16 use File::Find;
  4         4  
  4         203  
9 4     4   2167 use Data::Dumper;
  4         25487  
  4         196  
10 4     4   1657 use English;
  4         12186  
  4         17  
11 4     4   1347 use Carp;
  4         5  
  4         249  
12              
13             BEGIN {
14 4     4   77 @PDF::PDFUnit::EXPORT = qw( DEBUG );
15             }
16              
17             # These two extend the @EXPORT list:
18 4     4   1317 use PDF::PDFUnit::Shortcuts;
  4         9  
  4         73  
19 4     4   1300 use PDF::PDFUnit::Constants;
  4         5  
  4         83  
20              
21 4     4   1165 use PDF::PDFUnit::StudyClasses;
  4         5  
  4         6560  
22              
23             require Exporter;
24             our @ISA = qw(Exporter);
25              
26              
27             $PDF::PDFUnit::VERSION = 0.16;
28              
29             $PDF::PDFUnit::PDFUNIT_JAVA_VERSION = "2016.05";
30              
31              
32              
33              
34             our $instance = {
35             is_loaded => 0,
36             is_sane => 0,
37             config_path => undef,
38             classpath_elements => [],
39             };
40              
41              
42             sub val {
43 0     0 0 0 my ($class, $key);
44              
45            
46 0 0       0 if ($_[0] eq __PACKAGE__) {
47 0         0 ($class, $key) = @_;
48             }
49             else {
50 0         0 ($key) = @_;
51             }
52              
53 0         0 return $instance->{$key};
54             }
55              
56              
57             ###########
58             sub DEBUG {
59             ###########
60 20   50 20 0 65 my $debug_level = $ENV{PDFUNIT_PERL_DEBUG} // 0;
61              
62 20         18 my ($msg, $level) = @_;
63 20   100     36 $level //= 1;
64 20 50       32 return unless $debug_level >= $level;
65              
66 0         0 my $prefix = "***[${level}] ";
67              
68 0         0 my @msg = split(/\n/, $msg);
69            
70 0         0 say STDERR $prefix, $_ foreach @msg;
71             }
72              
73              
74             sub import {
75 4     4   30 my ($package, $init_style) = @_;
76              
77 4 50       12 if (defined $init_style) {
78              
79 4 50       5 unless (grep {$init_style eq $_} qw(:skip_on_error :noinit)) {
  8         20  
80 0         0 carp "Unknown import tag: '$init_style'";
81             }
82             }
83              
84 4 50 33     24 if (defined $init_style && $init_style eq ':skip_on_error') {
85 4         8 $package->init(skip_on_error => 1);
86             }
87            
88 0 0 0     0 unless (defined $init_style && $init_style eq ':noinit') {
89 0         0 $package->init();
90             }
91              
92 0         0 @_ = ($package);
93              
94 0         0 goto &Exporter::import;
95             }
96              
97              
98             ##########
99             sub init {
100             ##########
101 4     4 0 4 my $class = shift;
102              
103 4 0 0     7 $class->load_config(@_) &&
104             $class->build_classpath(@_) &&
105             $class->attach_java(@_);
106             }
107            
108              
109              
110              
111             #################
112             sub load_config {
113             #################
114 4     4 0 4 my $class = shift;
115 4         5 my %args = @_;
116              
117 4 50       14 return 1 if $instance->{is_loaded};
118            
119 4         12 DEBUG "Operating system: $OSNAME";
120              
121 4         3 my $config_found;
122            
123 4         4 foreach (@{os_dep()->{cfg_locations}}) {
  4         7  
124              
125 16         15 my $location_as_text = $_;
126 16         11 my $location = $_;
127              
128            
129 16 100       58 if ( my ($envar) = m/ENV%(.*?)%/ ) { # Environment var
130              
131 8         11 my $env_prefix = $class->os_dep()->{env_prefix};
132 8         19 my $env_suffix = $class->os_dep()->{env_suffix};
133            
134 8         42 $location_as_text =~ s/ENV%(.*?)%/$env_prefix$envar$env_suffix/;
135              
136 8 100       18 if (exists $ENV{$envar}) {
137 4         15 $location =~ s/ENV%(.*?)%/$ENV{$envar}/;
138             }
139             else {
140 4         6 $location = undef;
141             }
142             }
143              
144 16         27 DEBUG "Possible config location: $location_as_text", 2;
145              
146 16 50 66     195 if (defined $location && -r $location) {
147 0         0 $config_found = $location;
148 0         0 DEBUG "Found readable config: $location";
149 0         0 last;
150             }
151             }
152              
153 4 50       12 unless ($config_found) {
154 4         4 my $msg = "No configuration found";
155            
156 4 50       10 if ($args{skip_on_error}) {
157 4         8 _skip_all_tests($msg);
158             }
159            
160 0         0 warn "$msg\n";
161 0         0 return 0;
162             }
163              
164 0         0 $instance->{config_path} = $config_found;
165              
166 0 0       0 open(my $cfghandle, "<", $config_found)
167             || die "$config_found: $!\n";
168 0         0 DEBUG "Config opened for reading", 2;
169              
170              
171             # Valid configuration options:
172 0         0 my %config_schema = (
173             pdfunit_java_home => 'mandatory',
174             pdfunit_root => 'deprecated;pdfunit_java_home',
175             outfox_display => 'optional',
176             );
177              
178 0         0 my %config = (); # This will be filled
179              
180 0         0 while (<$cfghandle>) {
181 0         0 chomp;
182 0 0       0 next if /^#/;
183 0 0       0 next if /^\s*$/;
184              
185 0         0 my ($key, $value) = split(/\s*=\s*/, $_, 2);
186            
187 0 0       0 if (!exists $config_schema{$key}) {
188 0         0 warn("$config_found: Invalid key: $key\n");
189             }
190             else {
191 0         0 DEBUG "Found key/value: $key = $value";
192            
193 0 0       0 if ($config_schema{$key} =~ /^deprecated;/) {
194 0         0 my ($new_name) = (split(/;/, $config_schema{$key}))[1];
195 0         0 warn "Deprecated configuration key: $key "
196             . "(use $new_name instead)\n";
197 0         0 $config{$new_name} = $value;
198             }
199             else {
200 0         0 $config{$key} = $value;
201             }
202             }
203              
204             }
205 0         0 close $cfghandle;
206            
207             # Do we have values for all mandatory config keys?
208 0         0 foreach (grep { $config_schema{$_} eq 'mandatory'} keys %config_schema) {
  0         0  
209 0 0       0 unless (exists $config{$_}) {
210 0         0 my $msg = "Missing mandatory key in configuration: $_";
211            
212 0 0       0 if ($args{skip_on_error}) {
213 0         0 _skip_all_tests($msg);
214             }
215            
216 0         0 die "$msg\n";
217             }
218             }
219              
220             # Now put all found keys into the instance:
221 0         0 foreach (keys %config) {
222 0         0 $instance->{$_} = $config{$_};
223             }
224              
225            
226              
227 0         0 $instance->{is_loaded} = 1;
228              
229 0         0 return 1;
230             }
231              
232              
233              
234              
235             #####################
236             sub build_classpath {
237             #####################
238 0     0 0 0 my $class = shift;
239 0         0 my %args = @_;
240            
241 0 0       0 return 1 if $instance->{is_sane};
242              
243 0         0 DEBUG "Building CLASSPATH.";
244              
245 0         0 my $pdfunit_java_home = glob($class->val('pdfunit_java_home'));
246              
247 0         0 DEBUG "Searching for jar files under $pdfunit_java_home";
248              
249 0 0       0 unless (-d $pdfunit_java_home) {
250 0         0 my $msg = "Configured pdfunit_java_home is not a directory";
251            
252 0 0       0 if ($args{skip_on_error}) {
253 0         0 _skip_all_tests($msg);
254             }
255              
256 0         0 die "$msg\n";
257             }
258            
259 0         0 find(\&_wanted, $pdfunit_java_home);
260              
261             # The root directory of PDFUnit has to be in the classpath
262             # (otherwise the license file cannot be read):
263 0         0 unshift @{$instance->{classpath_elements}}, $pdfunit_java_home;
  0         0  
264              
265 0         0 my $count = @{$instance->{classpath_elements}};
  0         0  
266 0         0 DEBUG "Detected $count elements for classpath.";
267              
268             $ENV{CLASSPATH} = join(os_dep()->{env_pathlist_sep_char},
269 0         0 @{$instance->{classpath_elements}});
  0         0  
270              
271            
272             # (Weak) consisteny check of classpath elements:
273            
274             my @contains_main_jar =
275 0         0 grep { /^pdfunit-java-.*\.jar$/ }
276 0         0 map { basename $_ } @{$instance->{classpath_elements}};
  0         0  
  0         0  
277              
278            
279 0 0 0     0 if ( @contains_main_jar && $count >= 20) {
280 0         0 DEBUG "Setup seems to be sane!";
281            
282 0         0 $instance->{is_sane} = 1;
283              
284 0         0 return 1;
285             }
286             else {
287 0         0 my $msg = "Cannot build a sane CLASSPATH - no suitable jars found in "
288             . $pdfunit_java_home;
289            
290 0 0       0 if ($args{skip_on_error}) {
291 0         0 _skip_all_tests($msg);
292             }
293              
294 0         0 die "$msg\n";
295             }
296             }
297              
298              
299             sub _wanted {
300 0 0   0   0 return unless /\.jar$/i;
301              
302 0         0 DEBUG "Found jar: $_", 2;
303 0         0 push @{$instance->{classpath_elements}}, $File::Find::name;
  0         0  
304             }
305              
306              
307             #################
308             sub attach_java {
309             #################
310 0     0 0 0 my $class = shift;
311 0         0 my %args = @_;
312              
313 0 0       0 return 0 unless $instance->{is_sane};
314              
315            
316 0 0       0 $ENV{DISPLAY} = $class->val('outfox_display')
317             if defined $class->val('outfox_display');
318              
319              
320 0         0 DEBUG("Attaching Java with Inline::Java");
321            
322 0         0 eval {
323 0         0 require Inline;
324 0         0 import Inline (
325             Java => 'STUDY',
326             STUDY => $PDF::PDFUnit::StudyClasses::java_classes,
327             PACKAGE => 'main',
328             AUTOSTUDY => 1,
329             );
330             };
331              
332 0 0       0 if ($@) {
333 0 0       0 if ($args{skip_on_error}) {
334 0         0 _skip_all_tests($@);
335             }
336              
337 0         0 warn $@;
338 0         0 return 0;
339             }
340              
341 0         0 return 1;
342             }
343              
344              
345             sub _skip_all_tests {
346 4     4   8 my ($msg) = @_;
347            
348 4         26 require Test::More;
349 4         15 import Test::More (
350             skip_all => ($msg)
351             );
352              
353 0         0 exit 1;
354             }
355              
356              
357              
358             ############
359             sub os_dep {
360             ############
361 20     20 0 17 my $class = shift;
362              
363 20         37 my $cfgname = 'pdfunit-perl.cfg';
364              
365 20         101 my $os_dep = {
366             linux => {
367             env_pathlist_sep_char => ':',
368              
369             env_prefix => '$',
370             env_suffix => '',
371            
372             cfg_locations => [
373             "ENV%PDFUNIT_PERL_CONFIG%",
374             "./$cfgname",
375             "ENV%HOME%/.$cfgname",
376             "/etc/$cfgname"
377             ],
378             },
379            
380             MSWin32 => {
381             env_pathlist_sep_char => ';',
382            
383             env_prefix => '%',
384             env_suffix => '%',
385              
386             cfg_locations => [
387             "ENV%PDFUNIT_PERL_CONFIG%",
388             ".\\$cfgname",
389             "ENV%HOMEPATH%\\.$cfgname",
390             "ENV%USERPROFILE%\\.$cfgname",
391             "ENV%LOCALAPPDATA%\\pdfunit-perl\\$cfgname",
392             ],
393             },
394             };
395              
396 20         60 return $os_dep->{$OSNAME};
397             }
398              
399              
400              
401              
402              
403              
404              
405             1;
406              
407              
408             __END__