File Coverage

blib/lib/Sub/Meta/Test.pm
Criterion Covered Total %
statement 143 143 100.0
branch 20 20 100.0
condition 81 81 100.0
subroutine 20 20 100.0
pod 7 7 100.0
total 271 271 100.0


line stmt bran cond sub pod time code
1             package Sub::Meta::Test;
2 28     28   193664 use strict;
  28         64  
  28         695  
3 28     28   115 use warnings;
  28         48  
  28         648  
4 28     28   9110 use parent qw(Exporter);
  28         6793  
  28         141  
5             our @EXPORT_OK = qw(
6             sub_meta
7             sub_meta_parameters
8             sub_meta_param
9             sub_meta_returns
10             test_is_same_interface
11             test_error_message
12             DummyType
13             );
14              
15 28     28   1751 use Test2::V0;
  28         56  
  28         147  
16              
17             sub sub_meta {
18 27     27 1 82 my ($expected) = @_;
19 27   100     84 $expected //= {};
20              
21 27 100       103 my $parameters = defined $expected->{parameters} ? $expected->{parameters} : sub_meta_parameters();
22 27 100       1140 my $returns = defined $expected->{returns} ? $expected->{returns} : sub_meta_returns();
23              
24             return object {
25 27     27   1113 prop isa => 'Sub::Meta';
26 27   100     2563 call sub => $expected->{sub} // undef;
27 27   100     1108 call subname => $expected->{subname} // '';
28 27   100     1010 call stashname => $expected->{stashname} // '';
29 27   100     1006 call fullname => $expected->{fullname} // '';
30 27   100     1018 call subinfo => $expected->{subinfo} // [];
31 27   100     1028 call file => $expected->{file} // undef;
32 27   100     1044 call line => $expected->{line} // undef;
33 27   100     1019 call prototype => $expected->{prototype} // undef;
34 27   100     1004 call attribute => $expected->{attribute} // undef;
35 27         993 call parameters => $parameters;
36 27         954 call returns => $returns;
37 27         970 call is_constant => !!$expected->{is_constant};
38 27         1003 call is_method => !!$expected->{is_method};
39              
40 27         960 call has_sub => !!$expected->{sub};
41 27         938 call has_subname => !!$expected->{subname};
42 27         992 call has_stashname => !!$expected->{stashname};
43 27         1002 call has_file => !!$expected->{file};
44 27         949 call has_line => !!$expected->{line};
45 27         948 call has_prototype => !!$expected->{prototype};
46 27         1032 call has_attribute => !!$expected->{attribute};
47 27         1202 };
48             };
49              
50             sub sub_meta_parameters {
51 45     45 1 297 my ($expected) = @_;
52 45   100     145 $expected //= {};
53              
54             return object {
55 45     45   2431 prop isa => 'Sub::Meta::Parameters';
56 45   100     5757 call nshift => $expected->{nshift} // 0;
57 45   100     2135 call slurpy => $expected->{slurpy} // undef;
58 45   100     1743 call args => $expected->{args} // [];
59 45   100     1681 call all_args => $expected->{all_args} // [];
60 45   100     1624 call _all_positional_required => $expected->{_all_positional_required} // [];
61 45   100     1647 call positional => $expected->{positional} // [];
62 45   100     1665 call positional_required => $expected->{positional_required} // [];
63 45   100     1688 call positional_optional => $expected->{positional_optional} // [];
64 45   100     1679 call named => $expected->{named} // [];
65 45   100     1684 call named_required => $expected->{named_required} // [];
66 45   100     1641 call named_optional => $expected->{named_optional} // [];
67 45   100     1666 call invocant => $expected->{invocant} // undef;
68 45   100     1696 call invocants => $expected->{invocants} // [];
69 45   100     1676 call args_min => $expected->{args_min} // 0;
70 45   100     1716 call args_max => $expected->{args_max} // 0;
71 45   100     1832 call has_args => $expected->{has_args} // !!$expected->{args};
72 45         1648 call has_slurpy => !!$expected->{slurpy};
73 45         1558 call has_invocant => !!$expected->{invocant};
74 45         240 };
75             }
76              
77             sub sub_meta_param {
78 61     61 1 190 my ($expected) = @_;
79 61   100     134 $expected //= {};
80              
81             return object {
82 61     61   2950 prop isa => 'Sub::Meta::Param';
83 61   100     7079 call name => $expected->{name} // '';
84 61         2644 call type => $expected->{type};
85 61         2720 call isa_ => $expected->{type};
86 61         2214 call default => $expected->{default};
87 61         2210 call coerce => $expected->{coerce};
88 61   100     2294 call optional => $expected->{optional} // !!0;
89 61         2259 call required => !$expected->{optional};
90 61   100     2254 call named => $expected->{named} // !!0;
91 61         2171 call positional => !$expected->{named};
92 61   100     2280 call invocant => $expected->{invocant} // !!0;
93 61         2237 call has_name => !!$expected->{name};
94 61         2222 call has_type => !!$expected->{type};
95 61         2194 call has_default => !!$expected->{default};
96 61         2350 call has_coerce => !!$expected->{coerce};
97 61         264 };
98             }
99              
100              
101             sub sub_meta_returns {
102 38     38 1 186 my ($expected) = @_;
103 38   100     139 $expected //= {};
104              
105             return object {
106 38     38   1891 prop isa => 'Sub::Meta::Returns';
107 38   100     4349 call scalar => $expected->{scalar} // undef;
108 38   100     1623 call list => $expected->{list} // undef;
109 38   100     1451 call void => $expected->{void} // undef;
110 38   100     1679 call coerce => $expected->{coerce} // undef;
111              
112 38         1442 call has_scalar => !!$expected->{scalar};
113 38         1400 call has_list => !!$expected->{list};
114 38         1361 call has_void => !!$expected->{void};
115 38         1387 call has_coerce => !!$expected->{coerce};
116 38         197 };
117             };
118              
119             sub test_is_same_interface {
120 30     30 1 561 my ($meta, @tests) = @_;
121              
122             ## no critic (ProhibitStringyEval)
123 30         103 my $is_same_interface = eval sprintf('sub { %s }', $meta->is_same_interface_inlined('$_[0]'));
124 30         138 my $is_relaxed_same_interface = eval sprintf('sub { %s }', $meta->is_relaxed_same_interface_inlined('$_[0]'));
125             ## use critic
126              
127 30         123 my $ctx = context;
128 30         2297 my $meta_class = ref $meta;
129 30         78 while (@tests) {
130 144         126362 my ($pass, $message, $args) = splice @tests, 0, 3;
131 144 100 100     920 my $other = ref $args && ref $args eq 'HASH'
132             ? $meta_class->new($args)
133             : $args;
134              
135 144         380 my $same = $meta->is_same_interface($other);
136 144         3385 my $same_inlined = $is_same_interface->($other);
137              
138 144         398 my $relax = $meta->is_relaxed_same_interface($other);
139 144         2378 my $relax_inlined = $is_relaxed_same_interface->($other);
140             subtest "should $pass: $message" => sub {
141 144 100   144   33328 if ($pass eq 'pass') {
    100          
    100          
142 45         146 ok $same, 'is_same_interface';
143 45         9753 ok $same_inlined, 'is_same_interface_inlined';
144 45         8812 ok $relax, 'is_relaxed_same_interface';
145 45         8898 ok $relax_inlined, 'is_relaxed_same_interface_inlined';
146             }
147             elsif ($pass eq 'relax_pass') {
148 29         93 ok !$same, 'is_same_interface';
149 29         6106 ok !$same_inlined, 'is_same_interface_inlined';
150 29         5656 ok $relax, 'is_relaxed_same_interface';
151 29         5602 ok $relax_inlined, 'is_relaxed_same_interface_inlined';
152             }
153             elsif($pass eq 'fail') {
154 69         243 ok !$same, 'is_same_interface';
155 69         15553 ok !$same_inlined, 'is_same_interface_inlined';
156 69         13582 ok !$relax, 'is_relaxed_same_interface';
157 69         13678 ok !$relax_inlined, 'is_relaxed_same_interface_inlined';
158             }
159 144         1060 };
160             }
161 30         33055 $ctx->release;
162 30         669 return;
163             }
164              
165             sub test_error_message {
166 14     14 1 314 my ($meta, @tests) = @_;
167              
168 14         36 my $ctx = context;
169 14         1027 my $meta_class = ref $meta;
170              
171 14         36 while (@tests) {
172 60         51044 my ($pass, $args, $expected) = splice @tests, 0, 3;
173 60 100 100     334 my $other = ref $args && ref $args eq 'HASH'
174             ? $meta_class->new($args)
175             : $args;
176              
177 60         140 my $error_message = $meta->error_message($other);
178 60         135 my $relaxed_error_message = $meta->relaxed_error_message($other);
179              
180             subtest "should $pass: $expected" => sub {
181 60 100   60   13279 if ($pass eq 'pass') {
    100          
    100          
182 20         59 is $error_message, '', 'error_message';
183 20         6321 is $relaxed_error_message, '', 'relaxed_error_message';
184             }
185             elsif ($pass eq 'relax_pass') {
186 11         36 like $error_message, $expected, 'error_message';
187 11         3718 is $relaxed_error_message, '', 'relaxed_error_message';
188             }
189             elsif ($pass eq 'fail') {
190 28         88 like $error_message, $expected, 'error_message';
191 28         10195 like $relaxed_error_message, $expected, 'relaxed_error_message';
192             }
193 60         377 };
194             }
195              
196 14         14925 $ctx->release;
197 14         286 return;
198             }
199              
200             {
201             package ## no critic (Modules::ProhibitMultiplePackages) # hide from PAUSE
202             DummyType; ## no critic (RequireFilenameMatchesPackage)
203              
204             use overload
205             fallback => 1,
206 52     52   219 '""' => sub { 'DummyType' }
207 28     28   64076 ;
  28         82  
  28         245  
208              
209             sub new {
210 4     4   7 my $class = shift;
211 4         21 return bless {}, $class
212             }
213             };
214              
215             sub DummyType {
216 4     4 1 14108 return DummyType->new
217             }
218              
219              
220             1;
221             __END__