File Coverage

blib/lib/Dist/Zilla/Tester.pm
Criterion Covered Total %
statement 93 111 83.7
branch 2 8 25.0
condition n/a
subroutine 31 36 86.1
pod 1 12 8.3
total 127 167 76.0


line stmt bran cond sub pod time code
1             package Dist::Zilla::Tester 6.037;
2             # ABSTRACT: a testing-enabling stand-in for Dist::Zilla
3              
4 49     49   110932 use Moose;
  49         19026865  
  49         418  
5             extends 'Dist::Zilla::Dist::Builder';
6              
7 49     49   382734 use Dist::Zilla::Pragmas;
  49         105  
  49         537  
8              
9 49     49   26193 use autodie;
  49         706812  
  49         318  
10 49     49   365144 use Dist::Zilla::Chrome::Test;
  49         901  
  49         2637  
11 49     49   40273 use File::pushd ();
  49         1054606  
  49         1743  
12 49     49   451 use File::Spec;
  49         106  
  49         1035  
13 49     49   203 use File::Temp;
  49         94  
  49         4270  
14 49     49   25849 use Dist::Zilla::Path;
  49         759  
  49         482  
15              
16 49     49   17362 use Sub::Exporter::Util ();
  49         235  
  49         6649  
17             use Sub::Exporter -setup => {
18             exports => [
19 1         391 Builder => sub { $_[0]->can('builder') },
20 1         24 Minter => sub { $_[0]->can('minter') },
21 49         554 ],
22              
23             groups => [ default => [ qw(Builder Minter) ] ],
24 49     49   390 };
  49         91  
25              
26 49     49   27703 use namespace::autoclean -except => 'import';
  49         111  
  49         283  
27              
28             sub from_config {
29 1     1 1 4 my ($self, @arg) = @_;
30              
31             # The only thing using a local time zone should be NextRelease. Normally it
32             # defaults to "local," but since some users won't have an automatically
33             # determinable time zone, we'll switch to not-local times for testing.
34             # -- rjbs, 2015-11-26
35 1         5 local $Dist::Zilla::Plugin::NextRelease::DEFAULT_TIME_ZONE = 'GMT';
36              
37 1         7 return $self->builder->from_config(@arg);
38             }
39              
40 167     167 0 2301 sub builder { 'Dist::Zilla::Tester::_Builder' }
41              
42 1     1 0 17 sub minter { 'Dist::Zilla::Tester::_Minter' }
43              
44             {
45             package
46             Dist::Zilla::Tester::_Role;
47              
48 49     49   14231 use Moose::Role;
  49         109  
  49         645  
49              
50             has tempdir_root => (
51             is => 'rw', isa => 'Str|Undef',
52             writer => '_set_tempdir_root',
53             );
54             has tempdir_obj => (
55             is => 'ro', isa => 'File::Temp::Dir',
56             clearer => '_clear_tempdir_obj',
57             writer => '_set_tempdir_obj',
58             );
59              
60       10 0   sub DEMOLISH {}
61             around DEMOLISH => sub {
62             my $orig = shift;
63             my $self = shift;
64              
65             # File::Temp deletes the directory when it goes out of scope
66             $self->_clear_tempdir_obj;
67              
68             rmdir $self->tempdir_root if $self->tempdir_root;
69             return $self->$orig(@_);
70             };
71              
72             has tempdir => (
73             is => 'ro',
74             writer => '_set_tempdir',
75             init_arg => undef,
76             );
77              
78             sub clear_log_events {
79 0     0 0 0 my ($self) = @_;
80 0         0 $self->chrome->logger->clear_events;
81             }
82              
83             sub log_events {
84 0     0 0 0 my ($self) = @_;
85 0         0 $self->chrome->logger->events;
86             }
87              
88             sub log_messages {
89 27     27 0 32066 my ($self) = @_;
90 27         81 [ map {; $_->{message} } @{ $self->chrome->logger->events } ];
  168         912  
  27         2709  
91             }
92              
93             sub slurp_file {
94 112     112 0 114654 my ($self, $filename) = @_;
95              
96 112         4885 Dist::Zilla::Path::path(
97             $self->tempdir->child($filename)
98             )->slurp_utf8;
99             }
100              
101             sub slurp_file_raw {
102 0     0 0 0 my ($self, $filename) = @_;
103              
104 0         0 Dist::Zilla::Path::path(
105             $self->tempdir->child($filename)
106             )->slurp_raw;
107             }
108              
109 147     147   5118 sub _metadata_generator_id { 'Dist::Zilla::Tester' }
110              
111 49     49   326199 no Moose::Role;
  49         151  
  49         351  
112             }
113              
114             {
115             package Dist::Zilla::Tester::_Builder 6.037;
116              
117 49     49   15603 use Moose;
  49         109  
  49         384  
118             extends 'Dist::Zilla::Dist::Builder';
119             with 'Dist::Zilla::Tester::_Role';
120              
121 49     49   393923 use File::Copy::Recursive 0.41 qw(dircopy);
  49         413911  
  49         4300  
122 49     49   499 use Dist::Zilla::Path;
  49         136  
  49         440  
123              
124             our $Log_Events = [];
125             sub most_recent_log_events {
126 0     0 0 0 return @{ $Log_Events }
  0         0  
127             }
128              
129             around from_config => sub {
130             my ($orig, $self, $arg, $tester_arg) = @_;
131              
132             confess "dist_root required for from_config" unless $arg->{dist_root};
133              
134             my $source = $arg->{dist_root};
135              
136             my $tempdir_root = exists $tester_arg->{tempdir_root}
137             ? $tester_arg->{tempdir_root}
138             : 'tmp';
139              
140             mkdir $tempdir_root if defined $tempdir_root and not -d $tempdir_root;
141              
142             my $tempdir_obj = File::Temp->newdir(
143             CLEANUP => 1,
144             (defined $tempdir_root ? (DIR => $tempdir_root) : ()),
145             );
146              
147             my $tempdir = path( path($tempdir_obj)->absolute) ;
148              
149             my $root = $tempdir->child('source');
150             $root->mkpath;
151              
152             dircopy($source, $root);
153              
154             if ($tester_arg->{also_copy}) {
155             while (my ($src, $dest) = each %{ $tester_arg->{also_copy} }) {
156             dircopy($src, $tempdir->child($dest));
157             }
158             }
159              
160             if (my $files = $tester_arg->{add_files}) {
161             while (my ($name, $content) = each %$files) {
162             die "Unix path '$name' does not seem to be portable to the current OS"
163             if !unix_path_seems_portable($name);
164             my $fn = $tempdir->child($name);
165             $fn->parent->mkpath;
166             Dist::Zilla::Path::path($fn)->spew_utf8($content);
167             }
168             }
169              
170             local $arg->{dist_root} = "$root";
171             local $arg->{chrome} = Dist::Zilla::Chrome::Test->new;
172              
173             $Log_Events = $arg->{chrome}->logger->events;
174              
175             local @INC = @INC;
176              
177             my $had_dot;
178             if ($INC[-1] eq '.') {
179             $had_dot = 1;
180             pop @INC;
181             }
182              
183             @INC = map {; ref($_) ? $_ : File::Spec->rel2abs($_) } @INC;
184              
185             push @INC, '.' if $had_dot;
186              
187             # We do this so that . in @INC will find plugins like [=inc::YourFace]
188             # -- rjbs, 2016-04-24
189             my $wd = File::pushd::pushd($arg->{dist_root});
190              
191              
192             local $ENV{DZIL_GLOBAL_CONFIG_ROOT};
193             $ENV{DZIL_GLOBAL_CONFIG_ROOT} = $tester_arg->{global_config_root}
194             if defined $tester_arg->{global_config_root};
195              
196             my $zilla = $self->$orig($arg);
197              
198             $zilla->_set_tempdir_root($tempdir_root);
199             $zilla->_set_tempdir_obj($tempdir_obj);
200             $zilla->_set_tempdir($tempdir);
201              
202             return $zilla;
203             };
204              
205             around build_in => sub {
206             my ($orig, $self, $target) = @_;
207              
208             # Sometimes, we can't get a local time zone. When that happens, we're just
209             # going to pretend to be in UTC. We don't do this during actual runtime
210             # because the user can fix their own environment, but we'll let them do
211             # that after they get the software installed. -- rjbs, 2020-01-26
212             my $ok = eval { DateTime::TimeZone->new(name => 'local'); 1 };
213             local $ENV{TZ} = $ok ? $ENV{TZ} : 'UTC';
214              
215             # XXX: We *must eliminate* the need for this! It's only here because right
216             # now building a dist with (root <> cwd) doesn't work. -- rjbs, 2010-03-08
217             my $wd = File::pushd::pushd($self->root);
218              
219             $target ||= do {
220             my $target = path($self->tempdir)->child('build');
221             $target->mkpath;
222             $target;
223             };
224              
225             return $self->$orig($target);
226             };
227              
228             around ['test', 'release'] => sub {
229             my ($orig, $self) = @_;
230              
231             # XXX: We *must eliminate* the need for this! It's only here because right
232             # now building a dist with (root <> cwd) doesn't work. -- rjbs, 2010-03-08
233             my $wd = File::pushd::pushd($self->root);
234              
235             return $self->$orig;
236             };
237              
238 49     49   76753 no Moose;
  49         150  
  49         453  
239              
240             sub unix_path_seems_portable {
241 289 50   289 0 1751 return 1 if $^O eq "linux"; # this check only makes sense on non-unixes
242              
243 0         0 my ($unix_path) = @_;
244              
245             # split the $unix_path into 3 strings: $volume, $directories, $file; with:
246 0         0 my @native_parts = File::Spec->splitpath($unix_path); # current OS rules
247 0         0 my @unix_parts = File::Spec::Unix->splitpath($unix_path); # unix rules
248 0 0       0 return unless join(qq{\0}, @native_parts) eq join(qq{\0}, @unix_parts);
249              
250             # split the $directories string into a list of the sub-directories; with:
251 0         0 my @native_dirs = File::Spec->splitdir($native_parts[1]); # current OS rules
252 0         0 my @unix_dirs = File::Spec::Unix->splitdir($unix_parts[1]); # unix rules
253 0 0       0 return unless join(qq{\0}, @native_dirs) eq join(qq{\0}, @unix_dirs);
254              
255 0         0 return 1;
256             }
257             }
258              
259             {
260             package Dist::Zilla::Tester::_Minter 6.037;
261              
262 49     49   25740 use Moose;
  49         103  
  49         290  
263             extends 'Dist::Zilla::Dist::Minter';
264             with 'Dist::Zilla::Tester::_Role';
265              
266 49     49   362283 use File::Copy::Recursive 0.41 qw(dircopy);
  49         845  
  49         3438  
267 49     49   343 use Dist::Zilla::Path;
  49         114  
  49         277  
268              
269             our $Log_Events = [];
270             sub most_recent_log_events {
271 0     0 0 0 return @{ $Log_Events }
  0         0  
272             }
273              
274             sub _mint_target_dir {
275 1     1   4 my ($self) = @_;
276              
277 1         37 my $name = $self->name;
278 1         78 my $dir = $self->tempdir->child('mint')->absolute;
279              
280 1 50       215 $self->log_fatal("$dir already exists") if -e $dir;
281              
282 1         106 return $dir;
283             }
284              
285             sub _setup_global_config {
286 1     1   4 my ($self, $dir, $arg) = @_;
287              
288 1         5 my $config_base = path($dir)->child('config');
289              
290 1         162 my $stash_registry = {};
291              
292 1         720 require Dist::Zilla::MVP::Assembler::GlobalConfig;
293 1         797 require Dist::Zilla::MVP::Section;
294             my $assembler = Dist::Zilla::MVP::Assembler::GlobalConfig->new({
295             chrome => $arg->{chrome},
296 1         87 stash_registry => $stash_registry,
297             section_class => 'Dist::Zilla::MVP::Section', # make this DZMA default
298             });
299              
300 1         788 require Dist::Zilla::MVP::Reader::Finder;
301 1         70 my $reader = Dist::Zilla::MVP::Reader::Finder->new;
302              
303 1         11 my $seq = $reader->read_config($config_base, { assembler => $assembler });
304              
305 1         967 return $stash_registry;
306             }
307              
308             around _new_from_profile => sub {
309             my ($orig, $self, $profile_data, $arg, $tester_arg) = @_;
310              
311             # Sometimes, we can't get a local time zone. When that happens, we're just
312             # going to pretend to be in UTC. We don't do this during actual runtime
313             # because the user can fix their own environment, but we'll let them do
314             # that after they get the software installed. -- rjbs, 2020-01-26
315             my $ok = eval { DateTime::TimeZone->new(name => 'local'); 1 };
316             local $ENV{TZ} = $ok ? $ENV{TZ} : 'UTC';
317              
318             my $tempdir_root = exists $tester_arg->{tempdir_root}
319             ? $tester_arg->{tempdir_root}
320             : 'tmp';
321              
322             mkdir $tempdir_root if defined $tempdir_root and not -d $tempdir_root;
323              
324             my $tempdir_obj = File::Temp->newdir(
325             CLEANUP => 1,
326             (defined $tempdir_root ? (DIR => $tempdir_root) : ()),
327             );
328             my $tempdir = path($tempdir_obj)->absolute;
329              
330             local $arg->{chrome} = Dist::Zilla::Chrome::Test->new;
331             $Log_Events = $arg->{chrome}->logger->events;
332              
333             local @INC = map {; ref($_) ? $_ : File::Spec->rel2abs($_) } @INC;
334              
335             my $global_config_root = path($tester_arg->{global_config_root})->absolute;
336              
337             local $ENV{DZIL_GLOBAL_CONFIG_ROOT} = $global_config_root;
338              
339             my $global_stashes = $self->_setup_global_config(
340             $global_config_root,
341             { chrome => $arg->{chrome} },
342             );
343              
344             local $arg->{_global_stashes} = $global_stashes;
345              
346             my $zilla = $self->$orig($profile_data, $arg);
347              
348             $zilla->_set_tempdir_root($tempdir_root);
349             $zilla->_set_tempdir_obj($tempdir_obj);
350             $zilla->_set_tempdir($tempdir);
351              
352             return $zilla;
353             };
354             }
355              
356 49     49   59951 no Moose; # XXX: namespace::autoclean caused problems -- rjbs, 2011-08-19
  49         108  
  49         329  
357             __PACKAGE__->meta->make_immutable;
358             1;
359              
360             __END__
361              
362             =pod
363              
364             =encoding UTF-8
365              
366             =head1 NAME
367              
368             Dist::Zilla::Tester - a testing-enabling stand-in for Dist::Zilla
369              
370             =head1 VERSION
371              
372             version 6.037
373              
374             =head1 PERL VERSION
375              
376             This module should work on any version of perl still receiving updates from
377             the Perl 5 Porters. This means it should work on any version of perl
378             released in the last two to three years. (That is, if the most recently
379             released version is v5.40, then this module should work on both v5.40 and
380             v5.38.)
381              
382             Although it may work on older versions of perl, no guarantee is made that the
383             minimum required version will not be increased. The version may be increased
384             for any reason, and there is no promise that patches will be accepted to
385             lower the minimum required perl.
386              
387             =head1 AUTHOR
388              
389             Ricardo SIGNES 😏 <cpan@semiotic.systems>
390              
391             =head1 COPYRIGHT AND LICENSE
392              
393             This software is copyright (c) 2026 by Ricardo SIGNES.
394              
395             This is free software; you can redistribute it and/or modify it under
396             the same terms as the Perl 5 programming language system itself.
397              
398             =cut