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   229287 use strict;
  28         76  
  28         893  
3 28     28   155 use warnings;
  28         57  
  28         807  
4 28     28   11351 use parent qw(Exporter);
  28         9009  
  28         165  
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   2139 use Test2::V0;
  28         66  
  28         194  
16              
17             sub sub_meta {
18 27     27 1 86 my ($expected) = @_;
19 27   100     80 $expected //= {};
20              
21 27 100       95 my $parameters = defined $expected->{parameters} ? $expected->{parameters} : sub_meta_parameters();
22 27 100       1307 my $returns = defined $expected->{returns} ? $expected->{returns} : sub_meta_returns();
23              
24             return object {
25 27     27   1370 prop isa => 'Sub::Meta';
26 27   100     2987 call sub => $expected->{sub} // undef;
27 27   100     1255 call subname => $expected->{subname} // '';
28 27   100     1204 call stashname => $expected->{stashname} // '';
29 27   100     1219 call fullname => $expected->{fullname} // '';
30 27   100     1220 call subinfo => $expected->{subinfo} // [];
31 27   100     1267 call file => $expected->{file} // undef;
32 27   100     1228 call line => $expected->{line} // undef;
33 27   100     1225 call prototype => $expected->{prototype} // undef;
34 27   100     1183 call attribute => $expected->{attribute} // undef;
35 27         1139 call parameters => $parameters;
36 27         1141 call returns => $returns;
37 27         1166 call is_constant => !!$expected->{is_constant};
38 27         1172 call is_method => !!$expected->{is_method};
39              
40 27         1178 call has_sub => !!$expected->{sub};
41 27         1159 call has_subname => !!$expected->{subname};
42 27         1157 call has_stashname => !!$expected->{stashname};
43 27         1211 call has_file => !!$expected->{file};
44 27         1208 call has_line => !!$expected->{line};
45 27         1232 call has_prototype => !!$expected->{prototype};
46 27         1141 call has_attribute => !!$expected->{attribute};
47 27         1396 };
48             };
49              
50             sub sub_meta_parameters {
51 45     45 1 409 my ($expected) = @_;
52 45   100     197 $expected //= {};
53              
54             return object {
55 45     45   3036 prop isa => 'Sub::Meta::Parameters';
56 45   100     7073 call nshift => $expected->{nshift} // 0;
57 45   100     2720 call slurpy => $expected->{slurpy} // undef;
58 45   100     2143 call args => $expected->{args} // [];
59 45   100     2053 call all_args => $expected->{all_args} // [];
60 45   100     2131 call _all_positional_required => $expected->{_all_positional_required} // [];
61 45   100     2042 call positional => $expected->{positional} // [];
62 45   100     2069 call positional_required => $expected->{positional_required} // [];
63 45   100     2057 call positional_optional => $expected->{positional_optional} // [];
64 45   100     1995 call named => $expected->{named} // [];
65 45   100     2020 call named_required => $expected->{named_required} // [];
66 45   100     2056 call named_optional => $expected->{named_optional} // [];
67 45   100     2126 call invocant => $expected->{invocant} // undef;
68 45   100     2094 call invocants => $expected->{invocants} // [];
69 45   100     2049 call args_min => $expected->{args_min} // 0;
70 45   100     2065 call args_max => $expected->{args_max} // 0;
71 45   100     2053 call has_args => $expected->{has_args} // !!$expected->{args};
72 45         2125 call has_slurpy => !!$expected->{slurpy};
73 45         1936 call has_invocant => !!$expected->{invocant};
74 45         325 };
75             }
76              
77             sub sub_meta_param {
78 61     61 1 230 my ($expected) = @_;
79 61   100     181 $expected //= {};
80              
81             return object {
82 61     61   3993 prop isa => 'Sub::Meta::Param';
83 61   100     9814 call name => $expected->{name} // '';
84 61         3602 call type => $expected->{type};
85 61         2855 call isa_ => $expected->{type};
86 61         2756 call default => $expected->{default};
87 61         2733 call coerce => $expected->{coerce};
88 61   100     2882 call optional => $expected->{optional} // !!0;
89 61         2788 call required => !$expected->{optional};
90 61   100     2801 call named => $expected->{named} // !!0;
91 61         2618 call positional => !$expected->{named};
92 61   100     2763 call invocant => $expected->{invocant} // !!0;
93 61         2850 call has_name => !!$expected->{name};
94 61         2718 call has_type => !!$expected->{type};
95 61         2742 call has_default => !!$expected->{default};
96 61         2782 call has_coerce => !!$expected->{coerce};
97 61         347 };
98             }
99              
100              
101             sub sub_meta_returns {
102 38     38 1 253 my ($expected) = @_;
103 38   100     156 $expected //= {};
104              
105             return object {
106 38     38   2366 prop isa => 'Sub::Meta::Returns';
107 38   100     5636 call scalar => $expected->{scalar} // undef;
108 38   100     2083 call list => $expected->{list} // undef;
109 38   100     1742 call void => $expected->{void} // undef;
110 38   100     1691 call coerce => $expected->{coerce} // undef;
111              
112 38         1597 call has_scalar => !!$expected->{scalar};
113 38         1618 call has_list => !!$expected->{list};
114 38         1641 call has_void => !!$expected->{void};
115 38         1942 call has_coerce => !!$expected->{coerce};
116 38         236 };
117             };
118              
119             sub test_is_same_interface {
120 30     30 1 642 my ($meta, @tests) = @_;
121              
122             ## no critic (ProhibitStringyEval)
123 30         140 my $is_same_interface = eval sprintf('sub { %s }', $meta->is_same_interface_inlined('$_[0]'));
124 30         171 my $is_relaxed_same_interface = eval sprintf('sub { %s }', $meta->is_relaxed_same_interface_inlined('$_[0]'));
125             ## use critic
126              
127 30         137 my $ctx = context;
128 30         2985 my $meta_class = ref $meta;
129 30         104 while (@tests) {
130 144         166215 my ($pass, $message, $args) = splice @tests, 0, 3;
131 144 100 100     1250 my $other = ref $args && ref $args eq 'HASH'
132             ? $meta_class->new($args)
133             : $args;
134              
135 144         520 my $same = $meta->is_same_interface($other);
136 144         4443 my $same_inlined = $is_same_interface->($other);
137              
138 144         538 my $relax = $meta->is_relaxed_same_interface($other);
139 144         2948 my $relax_inlined = $is_relaxed_same_interface->($other);
140             subtest "should $pass: $message" => sub {
141 144 100   144   44785 if ($pass eq 'pass') {
    100          
    100          
142 45         256 ok $same, 'is_same_interface';
143 45         12406 ok $same_inlined, 'is_same_interface_inlined';
144 45         10822 ok $relax, 'is_relaxed_same_interface';
145 45         10947 ok $relax_inlined, 'is_relaxed_same_interface_inlined';
146             }
147             elsif ($pass eq 'relax_pass') {
148 29         128 ok !$same, 'is_same_interface';
149 29         8355 ok !$same_inlined, 'is_same_interface_inlined';
150 29         7199 ok $relax, 'is_relaxed_same_interface';
151 29         7089 ok $relax_inlined, 'is_relaxed_same_interface_inlined';
152             }
153             elsif($pass eq 'fail') {
154 69         314 ok !$same, 'is_same_interface';
155 69         19845 ok !$same_inlined, 'is_same_interface_inlined';
156 69         16944 ok !$relax, 'is_relaxed_same_interface';
157 69         16653 ok !$relax_inlined, 'is_relaxed_same_interface_inlined';
158             }
159 144         1428 };
160             }
161 30         41529 $ctx->release;
162 30         762 return;
163             }
164              
165             sub test_error_message {
166 14     14 1 375 my ($meta, @tests) = @_;
167              
168 14         401 my $ctx = context;
169 14         1260 my $meta_class = ref $meta;
170              
171 14         44 while (@tests) {
172 60         63881 my ($pass, $args, $expected) = splice @tests, 0, 3;
173 60 100 100     465 my $other = ref $args && ref $args eq 'HASH'
174             ? $meta_class->new($args)
175             : $args;
176              
177 60         193 my $error_message = $meta->error_message($other);
178 60         176 my $relaxed_error_message = $meta->relaxed_error_message($other);
179              
180             subtest "should $pass: $expected" => sub {
181 60 100   60   17195 if ($pass eq 'pass') {
    100          
    100          
182 20         81 is $error_message, '', 'error_message';
183 20         8276 is $relaxed_error_message, '', 'relaxed_error_message';
184             }
185             elsif ($pass eq 'relax_pass') {
186 11         50 like $error_message, $expected, 'error_message';
187 11         4716 is $relaxed_error_message, '', 'relaxed_error_message';
188             }
189             elsif ($pass eq 'fail') {
190 28         132 like $error_message, $expected, 'error_message';
191 28         13033 like $relaxed_error_message, $expected, 'relaxed_error_message';
192             }
193 60         497 };
194             }
195              
196 14         18096 $ctx->release;
197 14         348 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   302 '""' => sub { 'DummyType' }
207 28     28   78532 ;
  28         73  
  28         300  
208              
209             sub new {
210 4     4   7 my $class = shift;
211 4         26 return bless {}, $class
212             }
213             };
214              
215             sub DummyType {
216 4     4 1 9273 return DummyType->new
217             }
218              
219              
220             1;
221             __END__