File Coverage

blib/lib/Module/Install/TestTarget.pm
Criterion Covered Total %
statement 18 99 18.1
branch 0 26 0.0
condition 0 15 0.0
subroutine 6 14 42.8
pod 2 2 100.0
total 26 156 16.6


line stmt bran cond sub pod time code
1             package Module::Install::TestTarget;
2 1     1   23496 use 5.006_002;
  1         3  
  1         29  
3 1     1   5 use strict;
  1         2  
  1         67  
4             #use warnings; # XXX: warnings.pm produces a lot of 'redefine' warnings!
5             our $VERSION = '0.19';
6              
7 1     1   5 use base qw(Module::Install::Base);
  1         7  
  1         796  
8 1     1   695 use Config;
  1         1  
  1         32  
9 1     1   4 use Carp qw(croak);
  1         2  
  1         348  
10              
11             our($ORIG_TEST_VIA_HARNESS);
12              
13             our $TEST_DYNAMIC = {
14             env => '',
15             includes => '',
16             load_modules => '',
17             insert_on_prepare => '',
18             insert_on_finalize => '',
19             run_on_prepare => '',
20             run_on_finalize => '',
21             };
22              
23             # override the default `make test`
24             sub default_test_target {
25 0     0 1   my ($self, %args) = @_;
26 0           my %test = _build_command_parts(%args);
27 0           $TEST_DYNAMIC = \%test;
28             }
29              
30             # create a new test target
31             sub test_target {
32 0     0 1   my ($self, $target, %args) = @_;
33 0 0         croak 'target must be spesiced at test_target()' unless $target;
34 0           my $alias = "\n";
35              
36 0 0         if($args{alias}) {
37 0           $alias .= qq{$args{alias} :: $target\n\n};
38             }
39 0 0 0       if($Module::Install::AUTHOR && $args{alias_for_author}) {
40 0           $alias .= qq{$args{alias_for_author} :: $target\n\n};
41             }
42              
43 0           my $test = _assemble(_build_command_parts(%args));
44              
45 0           $self->postamble(
46             $alias
47             . qq{$target :: pure_all\n}
48             . qq{\t} . $test
49             );
50             }
51              
52             sub _build_command_parts {
53 0     0     my %args = @_;
54              
55             #XXX: _build_command_parts() will be called first, so we put it here
56 0 0         unless(defined $ORIG_TEST_VIA_HARNESS) {
57 0           $ORIG_TEST_VIA_HARNESS = MY->can('test_via_harness');
58 1     1   4 no warnings 'redefine';
  1         2  
  1         991  
59 0           *MY::test_via_harness = \&_test_via_harness;
60             }
61              
62 0           for my $key (qw/includes load_modules run_on_prepare run_on_finalize insert_on_prepare insert_on_finalize tests/) {
63 0   0       $args{$key} ||= [];
64 0 0         $args{$key} = [$args{$key}] unless ref $args{$key} eq 'ARRAY';
65             }
66 0   0       $args{env} ||= {};
67              
68 0           my %test;
69 0 0         $test{includes} = @{$args{includes}} ? join '', map { qq|"-I$_" | } @{$args{includes}} : '';
  0            
  0            
  0            
70 0 0         $test{load_modules} = @{$args{load_modules}} ? join '', map { qq|"-M$_" | } @{$args{load_modules}} : '';
  0            
  0            
  0            
71              
72 0           $test{tests} = @{$args{tests}}
  0            
73 0 0         ? join '', map { qq|"$_" | } @{$args{tests}}
  0            
74             : '$(TEST_FILES)';
75              
76 0           for my $key (qw/run_on_prepare run_on_finalize/) {
77 0 0         $test{$key} = @{$args{$key}} ? join '', map { qq|do { local \$@; do '$_'; die \$@ if \$@ }; | } @{$args{$key}} : '';
  0            
  0            
  0            
78 0           $test{$key} = _quote($test{$key});
79             }
80 0           for my $key (qw/insert_on_prepare insert_on_finalize/) {
81 0           my $codes = join '', map { _build_funcall($_) } @{$args{$key}};
  0            
  0            
82 0           $test{$key} = _quote($codes);
83             }
84 0           $test{env} = %{$args{env}} ? _quote(join '', map {
  0            
85 0           my $key = _env_quote($_);
86 0           my $val = _env_quote($args{env}->{$_});
87 0           sprintf "\$ENV{q{%s}} = q{%s}; ", $key, $val
88 0 0         } keys %{$args{env}}) : '';
89              
90 0           return %test;
91             }
92              
93             my $bd;
94             sub _build_funcall {
95 0     0     my($code) = @_;
96 0 0         if(ref $code eq 'CODE') {
97 0   0       $bd ||= do { require B::Deparse; B::Deparse->new() };
  0            
  0            
98 0           $code = $bd->coderef2text($code);
99             }
100 0           return qq|sub { $code }->(); |;
101             }
102              
103             sub _quote {
104 0     0     my $code = shift;
105 0           $code =~ s/\$/\\\$\$/g;
106 0           $code =~ s/"/\\"/g;
107 0           $code =~ s/\n/ /g;
108 0 0         if ($^O eq 'MSWin32') {
109 0           $code =~ s/\\\$\$/\$\$/g;
110 0 0         if ($Config{make} =~ /dmake/i) {
111 0           $code =~ s/{/{{/g;
112 0           $code =~ s/}/}}/g;
113             }
114             }
115 0           return $code;
116             }
117              
118             sub _env_quote {
119 0     0     my $val = shift;
120 0           $val =~ s/}/\\}/g;
121 0           return $val;
122             }
123              
124             sub _assemble {
125 0     0     my %args = @_;
126 0   0       my $command = MY->$ORIG_TEST_VIA_HARNESS($args{perl} || '$(FULLPERLRUN)', $args{tests});
127              
128             # inject includes and modules before the first switch
129 0           $command =~ s/("- \S+? ")/$args{includes}$args{load_modules}$1/xms;
130              
131             # inject snipetts in the one-liner
132 0           $command =~ s{
133             ( "-e" \s+ ") # start the one liner
134             ( (?: [^"] | \\ . )+ ) # body of the one liner
135             ( " ) # end the one liner
136             }{
137 0           join '', $1,
138             $args{env},
139             $args{run_on_prepare},
140             $args{insert_on_prepare},
141             "$2; ",
142             $args{run_on_finalize},
143             $args{insert_on_finalize},
144             $3,
145             }xmse;
146 0           return $command;
147             }
148              
149             sub _test_via_harness {
150 0     0     my($self, $perl, $tests) = @_;
151              
152 0           $TEST_DYNAMIC->{perl} = $perl;
153 0   0       $TEST_DYNAMIC->{tests} ||= $tests;
154 0           return _assemble(%$TEST_DYNAMIC);
155             }
156              
157             1;
158             __END__