File Coverage

blib/lib/Test/Perinci/Sub/Wrapper.pm
Criterion Covered Total %
statement 122 123 99.1
branch 75 102 73.5
condition 15 16 93.7
subroutine 30 30 100.0
pod 0 1 0.0
total 242 272 88.9


line stmt bran cond sub pod time code
1             package Test::Perinci::Sub::Wrapper;
2              
3             our $DATE = '2019-04-15'; # DATE
4             our $VERSION = '0.850'; # VERSION
5              
6 17     17   1867848 use 5.010;
  17         89  
7 17     17   98 use strict;
  17         227  
  17         295  
8 17     15   1424 use warnings;
  15         123  
  15         423  
9              
10 15     15   5641 use Function::Fallback::CoreOrPP qw(clone);
  15         7770  
  15         736  
11             #use List::Util qw(shuffle);
12 15     15   7508 use Perinci::Sub::Wrapper qw(wrap_sub);
  15         136  
  15         938  
13 15     15   428 use Test::More 0.96;
  15         365  
  15         92  
14              
15             our @ISA = qw(Exporter);
16             our @EXPORT_OK = qw(test_wrap);
17              
18             sub test_wrap {
19 59     59 0 191056 my %test_args = @_;
20 59 50       353 $test_args{wrap_args} or die "BUG: wrap_args not defined";
21 59 50       217 my $test_name = $test_args{name} or die "BUG: test_name not defined";
22              
23 59         492 for my $wrapper_type (qw/dynamic embed/) {
24 116 100 100     156184 next if $wrapper_type eq 'dynamic' && $test_args{skip_dynamic};
25 115 100 100     613 next if $wrapper_type eq 'embed' && $test_args{skip_embed};
26             subtest "$test_name ($wrapper_type)" => sub {
27              
28 114 50   114   111280 if ($test_args{pretest}) {
29 2         6 $test_args{pretest}->();
30             }
31              
32 114         617 my $wrap_args = clone($test_args{wrap_args});
33             die "BUG: embed must not be specified in wrap_args, test_wrap() ".
34             "will always test dynamic (embed=0) *and* embed mode"
35 114 50       22324 if exists $wrap_args->{embed};
36 114 100       398 if ($wrapper_type eq 'embed') {
37 58         516 $wrap_args->{embed} = 1;
38             #diag explain $wrap_args->{meta};
39             } else {
40 57         246 $wrap_args->{embed} = 0;
41             }
42              
43 113         201 my $wrap_res;
44 113         499 eval { $wrap_res = wrap_sub(%$wrap_args) };
  113         563  
45 113         34745 my $wrap_eval_err = $@;
46 113 100       495 if ($test_args{wrap_dies}) {
47 9         122 ok($wrap_eval_err, "wrap dies");
48 9         9025 return;
49             } else {
50 105 50       976 ok(!$wrap_eval_err, "wrap doesn't die") or do {
51 1         7 diag $wrap_eval_err;
52 1         2 return;
53             };
54             }
55              
56 105 100       76773 if (defined $test_args{wrap_status}) {
57 27         243 is(ref($wrap_res), 'ARRAY', 'wrap res is array');
58             is($wrap_res->[0], $test_args{wrap_status},
59 27 50       9666 "wrap status is $test_args{wrap_status}")
60             or diag "wrap res: ", explain($wrap_res);
61             }
62              
63 105 50       9951 return unless $wrap_res->[0] == 200;
64              
65 105         225 my $sub;
66 105 100       351 if ($wrapper_type eq 'embed') {
67 53         138 my $src = $wrap_res->[2]{source};
68 53         239 my $meta = $wrap_res->[2]{meta};
69 53         152 my $args_as = $meta->{args_as};
70 53   100     589 my $orig_args_as = $wrap_args->{meta}{args_as} // 'hash';
71 53         128 my $sub_name = $wrap_res->[2]{sub_name};
72             my $eval_src = join(
73             "\n",
74             $src->{presub1},
75             $src->{presub2},
76             'sub {',
77             ' my %args;',
78             (' my @args;') x !!($orig_args_as eq 'array' || $args_as eq 'array'),
79             (' my $args;') x !!($orig_args_as =~ /ref/ || $args_as =~ /ref/),
80             ' '.
81             ($args_as eq 'hash' ? '%args = @_;' :
82             $args_as eq 'hashref' ? '$args = $_[0] // {}; %args = %$args;' :
83             $args_as eq 'array' ? '@args = @_;' :
84             '$args = $_[0] // [];'),
85             $src->{preamble},
86             ($src->{postamble} ? ' $_w_res = do {' : ''),
87             $sub_name. ($sub_name =~ /\A\$/ ? '->':'').'('.
88             ($orig_args_as eq 'hash' ? '%args' :
89             $orig_args_as eq 'hashref' ? '$args' :
90             $orig_args_as eq 'array' ? '@args' :
91             '$args').');',
92             ($src->{postamble} ? '}; # do' : ''),
93             $src->{postamble},
94 53 100 100     1577 '}; # sub',
    100 66        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
95             );
96 53     10   5643 $sub = eval $eval_src;
  8     10   59  
  8     1   20  
  8     1   52  
  8     1   654  
  8     1   18  
  8     1   2361  
        1      
        1      
        1      
        1      
        1      
        1      
        1      
        1      
        1      
        1      
        1      
        1      
        1      
        1      
        1      
97 53         258 my $eval_err = $@;
98 53 50       244 ok(!$eval_err, "embed code compiles ok") or do {
99 1         319 diag "eval err: ", $eval_err;
100 1         8 diag "eval source: ", $eval_src;
101 1         2 return;
102             };
103             diag "eval source: ", $eval_src
104 53 50       20175 if $ENV{LOG_PERINCI_WRAPPER_CODE};
105             } else {
106              
107             # check that we don't generate comment after code (unless it
108             # uses '##' instead of '#'), because this makes cutting comments
109             # easier. XXX this is using a simple regex and misses some.
110 53         764 for my $line (split /^/, $wrap_res->[2]{source}) {
111 2539 100       4910 if ($line =~ /(.*?)\s+#\s+(.*)/) {
112 400         1189 my ($before, $after) = ($1, $2);
113 400 50       759 next unless $before =~ /\S/;
114 1         2 ok 0; diag "Source code contains comment line after some code '$line' (if you do this, you must use ## instead of # to help ease removing comment lines (e.g. in Dist::Zilla::Plugin::Rinci::Wrap))";
  1         7  
115             }
116             }
117              
118 53         362 $sub = $wrap_res->[2]{sub};
119             }
120              
121             # testing a single sub call
122 105         236 my $call_argsr = $test_args{call_argsr};
123 105         537 my $call_res;
124 105 100       290 if ($call_argsr) {
125 11         20 eval { $call_res = $sub->(@$call_argsr) };
  11         276  
126 11         127 my $call_eval_err = $@;
127 11 50       32 if ($test_args{call_dies}) {
128 1         614 ok($call_eval_err, "call dies");
129 1 0       8 if ($test_args{call_die_message}) {
130             like($call_eval_err, $test_args{call_die_message},
131 1         3 "call die message");
132             }
133 1         8 return;
134             } else {
135 11 50       126 ok(!$call_eval_err, "call doesn't die")
136             or diag $call_eval_err;
137             }
138              
139 11 50       3413 if (defined $test_args{call_status}) {
140 11 50       702 is(ref($call_res), 'ARRAY', 'call res is array')
141             or diag "call res = ", explain($call_res);
142             is($call_res->[0], $test_args{call_status},
143 11 50       3637 "call status is $test_args{call_status}")
144             or diag "call res = ", explain($call_res);
145             }
146              
147 11 100       3442 if (exists $test_args{call_res}) {
148             is_deeply($call_res, $test_args{call_res},
149 3 50       17 "call res")
150             or diag explain $call_res;
151             }
152              
153 11 50       1222 if (exists $test_args{call_actual_res}) {
154             is_deeply($call_res->[2], $test_args{call_actual_res},
155 1 0       2 "call actual res")
156             or diag explain $call_res->[2];
157             }
158              
159 11 100       36 if (exists $test_args{call_actual_res_re}) {
160             like($call_res->[2], $test_args{call_actual_res_re},
161 3         101 "call actual res");
162             }
163             }
164              
165             # testing multiple sub calls
166 105 100       985 if ($test_args{calls}) {
167 67         519 my $i = 0;
168 66         125 for my $call (@{$test_args{calls}}) {
  66         199  
169 170         185534 $i++;
170             subtest "call #$i: ".($call->{name} // "") => sub {
171 170         170729 my $res;
172 170         287 eval { $res = $sub->(@{$call->{argsr}}) };
  170         285  
  170         4630  
173 170         394 my $eval_err = $@;
174 170 100       505 if ($call->{dies}) {
175 2         10 ok($eval_err, "dies");
176 2 50       756 if ($call->{die_message}) {
177             like($eval_err, $call->{die_message},
178 0         0 "die message");
179             }
180 2         6 return;
181             } else {
182 168 50       562 ok(!$eval_err, "doesn't die")
183             or diag $eval_err;
184             }
185              
186 168 100       63689 if (defined $call->{status}) {
187 154 50       582 is(ref($res), 'ARRAY', 'res is array')
188             or diag "res = ", explain($res);
189             is($res->[0], $call->{status},
190 154 50       59276 "status is $call->{status}")
191             or diag "res = ", explain($res);
192             }
193              
194 168 100       58659 if (exists $call->{res}) {
195 16 50       79 is_deeply($res, $call->{res}, "res")
196             or diag explain $res;
197             }
198              
199 168 100       11768 if (exists $call->{actual_res}) {
200 32 50       150 is_deeply($res->[2], $call->{actual_res}, "actual res")
201             or diag explain $res->[2];
202             }
203              
204 168 100       16714 if (exists $call->{actual_res_re}) {
205             like($res->[2], $call->{actual_res_re},
206 4         18 "actual res re");
207             }
208 170   100     1852 }; # subtest call #$i
209             }
210             } # if calls
211              
212 104 100       115462 if ($test_args{posttest}) {
213 24         98 $test_args{posttest}->($wrap_res, $call_res, $sub);
214             }
215              
216 104         27843 done_testing();
217              
218 114         1534 }; # subtest
219             } # for $wrapper_type
220             }
221              
222             1;
223             # ABSTRACT: Provide test_wrap() to test wrapper
224              
225             __END__
226              
227             =pod
228              
229             =encoding UTF-8
230              
231             =head1 NAME
232              
233             Test::Perinci::Sub::Wrapper - Provide test_wrap() to test wrapper
234              
235             =head1 VERSION
236              
237             This document describes version 0.850 of Test::Perinci::Sub::Wrapper (from Perl distribution Perinci-Sub-Wrapper), released on 2019-04-15.
238              
239             =for Pod::Coverage test_wrap
240              
241             =head1 HOMEPAGE
242              
243             Please visit the project's homepage at L<https://metacpan.org/release/Perinci-Sub-Wrapper>.
244              
245             =head1 SOURCE
246              
247             Source repository is at L<https://github.com/perlancar/perl-Perinci-Sub-Wrapper>.
248              
249             =head1 BUGS
250              
251             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Perinci-Sub-Wrapper>
252              
253             When submitting a bug or request, please include a test-file or a
254             patch to an existing test-file that illustrates the bug or desired
255             feature.
256              
257             =head1 AUTHOR
258              
259             perlancar <perlancar@cpan.org>
260              
261             =head1 COPYRIGHT AND LICENSE
262              
263             This software is copyright (c) 2019, 2017, 2016, 2015, 2014, 2013, 2012, 2011 by perlancar@cpan.org.
264              
265             This is free software; you can redistribute it and/or modify it under
266             the same terms as the Perl 5 programming language system itself.
267              
268             =cut