File Coverage

inc/Test/SharedFork.pm
Criterion Covered Total %
statement 46 92 50.0
branch 2 26 7.6
condition 2 9 22.2
subroutine 12 18 66.6
pod 0 3 0.0
total 62 148 41.8


line stmt bran cond sub pod time code
1             #line 1
2 2     2   13 package Test::SharedFork;
  2         7  
  2         79  
3 2     2   11 use strict;
  2         4  
  2         209  
4 2     2   12 use warnings;
  2         4  
  2         236  
5             use base 'Test::Builder::Module';
6 2     2   11 our $VERSION = '0.16';
  2         79  
  2         51  
7 2     2   2275 use Test::Builder 0.32; # 0.32 or later is needed
  2         6  
  2         93  
8 2     2   2918 use Test::SharedFork::Scalar;
  2         8  
  2         53  
9 2     2   1840 use Test::SharedFork::Array;
  2         9  
  2         142  
10 2     2   13 use Test::SharedFork::Store;
  2         6  
  2         88  
11 2     2   128 use Config;
  2         74  
  2         1972  
12             use 5.008000;
13              
14             {
15             package #
16             Test::SharedFork::Contextual;
17              
18 0     0     sub call {
19 0           my $code = shift;
20 0 0         my $wantarray = [caller(1)]->[5];
    0          
21 0           if ($wantarray) {
22 0           my @result = $code->();
23             bless {result => \@result, wantarray => $wantarray}, __PACKAGE__;
24 0           } elsif (defined $wantarray) {
25 0           my $result = $code->();
26             bless {result => $result, wantarray => $wantarray}, __PACKAGE__;
27 0           } else {
  0            
28 0           { ; $code->(); } # void context
29             bless {wantarray => $wantarray}, __PACKAGE__;
30             }
31             }
32              
33 0     0     sub result {
34 0 0         my $self = shift;
    0          
35 0           if ($self->{wantarray}) {
  0            
36             return @{ $self->{result} };
37 0           } elsif (defined $self->{wantarray}) {
38             return $self->{result};
39 0           } else {
40             return;
41             }
42             }
43             }
44              
45             my $STORE;
46              
47 2     2   28 BEGIN {
48             my $builder = __PACKAGE__->builder;
49 2 50 33     55  
      33        
50 0         0 if( $] >= 5.008001 && $Config{useithreads} && $INC{'threads.pm'} ) {
51             die "# Current version of Test::SharedFork does not supports ithreads.";
52             }
53 2 50       56  
54             if (Test::Builder->VERSION > 2.00) {
55 0         0 # new Test::Builder
56             $STORE = Test::SharedFork::Store->new();
57 0         0  
58 0         0 our $level = 0;
59 0         0 for my $class (qw/Test::Builder2::History Test::Builder2::Counter/) {
60 0         0 my $meta = $class->meta;
61 0 0       0 my @methods = $meta->get_method_list;
62             my $orig =
63             $class eq 'Test::Builder2::History'
64             ? $builder->{History}
65 0         0 : $builder->{History}->counter;
66 0         0 $orig->{test_sharedfork_hacked}++;
67 0         0 $STORE->set($class => $orig);
68 0 0       0 for my $method (@methods) {
69 0 0       0 next if $method =~ /^_/;
70 0 0       0 next if $method eq 'meta';
71 0 0       0 next if $method eq 'create';
72             next if $method eq 'singleton';
73             $meta->add_around_method_modifier(
74 0         0 $method => sub {
75 0 0 0     0 my ($code, $orig_self, @args) = @_;
76             return $orig_self->$code(@args) if (! ref $orig_self) || ! $orig_self->{test_sharedfork_hacked};
77 0         0  
78 0         0 my $lock = $STORE->get_lock();
79 0 0       0 local $level = $level + 1;
80             my $self =
81             $level == 1 ? $STORE->get($class) : $orig_self;
82 0         0  
  0         0  
83 0         0 my $ret = Test::SharedFork::Contextual::call(sub { $self->$code(@args) });
84 0         0 $STORE->set($class => $self);
85             return $ret->result;
86 0         0 },
87             );
88             }
89             }
90             } else {
91             # older Test::Builder
92             $STORE = Test::SharedFork::Store->new(
93 2         7 cb => sub {
94 2         18 my $store = shift;
95             tie $builder->{Curr_Test}, 'Test::SharedFork::Scalar',
96 2         4 $store, 'Curr_Test';
  2         16  
97             tie @{ $builder->{Test_Results} },
98             'Test::SharedFork::Array', $store, 'Test_Results';
99 2         24 },
100             init => +{
101             Test_Results => $builder->{Test_Results},
102             Curr_Test => $builder->{Curr_Test},
103             },
104             );
105             }
106              
107 2     2   15 # make methods atomic.
  2         4  
  2         86  
108 2     2   11 no strict 'refs';
  2         5  
  2         345  
109 2         13 no warnings 'redefine';
110 8         13 for my $name (qw/ok skip todo_skip current_test/) {
  8         33  
111 8         217 my $orig = *{"Test::Builder::${name}"}{CODE};
112 0     0     *{"Test::Builder::${name}"} = sub {
113 0           local $Test::Builder::Level += 3;
114 0           my $lock = $STORE->get_lock(); # RAII
115 8         33 $orig->(@_);
116             };
117             };
118              
119             }
120              
121             {
122 0     0 0   # backward compatibility method
123 0     0 0   sub parent { }
124 0     0 0   sub child { }
125             sub fork { fork() }
126             }
127              
128             1;
129             __END__
130              
131             #line 184