File Coverage

blib/lib/Sub/Meta/Test.pm
Criterion Covered Total %
statement 130 130 100.0
branch 16 16 100.0
condition 72 72 100.0
subroutine 18 18 100.0
pod 6 6 100.0
total 242 242 100.0


line stmt bran cond sub pod time code
1             package Sub::Meta::Test;
2 26     26   245404 use strict;
  26         63  
  26         802  
3 26     26   138 use warnings;
  26         52  
  26         749  
4 26     26   12514 use parent qw(Exporter);
  26         8054  
  26         166  
5             our @EXPORT_OK = qw(
6             sub_meta
7             sub_meta_parameters
8             sub_meta_param
9             test_is_same_interface
10             test_error_message
11             DummyType
12             );
13              
14 26     26   2070 use Test2::V0;
  26         56  
  26         180  
15              
16             sub sub_meta {
17 26     26 1 97 my ($expected) = @_;
18 26   100     91 $expected //= {};
19              
20             return object {
21 26     26   2058 prop isa => 'Sub::Meta';
22 26   100     4754 call sub => $expected->{sub} // undef;
23 26   100     1725 call subname => $expected->{subname} // '';
24 26   100     1263 call stashname => $expected->{stashname} // '';
25 26   100     1265 call fullname => $expected->{fullname} // '';
26 26   100     1258 call subinfo => $expected->{subinfo} // [];
27 26   100     1241 call file => $expected->{file} // undef;
28 26   100     1211 call line => $expected->{line} // undef;
29 26   100     1227 call prototype => $expected->{prototype} // undef;
30 26   100     1265 call attribute => $expected->{attribute} // undef;
31 26   100     1277 call parameters => $expected->{parameters} // undef;
32 26   100     1237 call returns => $expected->{returns} // undef;
33 26         1218 call is_constant => !!$expected->{is_constant};
34 26         1298 call is_method => !!$expected->{is_method};
35              
36 26         1212 call has_sub => !!$expected->{sub};
37 26         1183 call has_subname => !!$expected->{subname};
38 26         1145 call has_stashname => !!$expected->{stashname};
39 26         1279 call has_file => !!$expected->{file};
40 26         1174 call has_line => !!$expected->{line};
41 26         1131 call has_prototype => !!$expected->{prototype};
42 26         1197 call has_attribute => !!$expected->{attribute};
43 26         1336 call has_parameters => !!$expected->{parameters};
44 26         1307 call has_returns => !!$expected->{returns};
45 26         231 };
46             };
47              
48             sub sub_meta_parameters {
49 23     23 1 313 my ($expected) = @_;
50 23   100     74 $expected //= {};
51              
52             return object {
53 23     23   1473 prop isa => 'Sub::Meta::Parameters';
54 23   100     3440 call nshift => $expected->{nshift} // 0;
55 23   100     1359 call slurpy => $expected->{slurpy} // undef;
56 23   100     1058 call args => $expected->{args} // [];
57 23   100     1072 call all_args => $expected->{all_args} // [];
58 23   100     1030 call _all_positional_required => $expected->{_all_positional_required} // [];
59 23   100     1024 call positional => $expected->{positional} // [];
60 23   100     1029 call positional_required => $expected->{positional_required} // [];
61 23   100     1037 call positional_optional => $expected->{positional_optional} // [];
62 23   100     1087 call named => $expected->{named} // [];
63 23   100     1089 call named_required => $expected->{named_required} // [];
64 23   100     1065 call named_optional => $expected->{named_optional} // [];
65 23   100     1070 call invocant => $expected->{invocant} // undef;
66 23   100     1100 call invocants => $expected->{invocants} // [];
67 23   100     1052 call args_min => $expected->{args_min} // 0;
68 23   100     1049 call args_max => $expected->{args_max} // 0;
69 23         975 call has_slurpy => !!$expected->{slurpy};
70 23         974 call has_invocant => !!$expected->{invocant};
71 23         151 };
72             }
73              
74             sub sub_meta_param {
75 61     61 1 215 my ($expected) = @_;
76 61   100     232 $expected //= {};
77              
78             return object {
79 61     61   3862 prop isa => 'Sub::Meta::Param';
80 61   100     8811 call name => $expected->{name} // '';
81 61         3299 call type => $expected->{type};
82 61         3315 call isa_ => $expected->{type};
83 61         2780 call default => $expected->{default};
84 61         2725 call coerce => $expected->{coerce};
85 61   100     2833 call optional => $expected->{optional} // !!0;
86 61         2721 call required => !$expected->{optional};
87 61   100     2837 call named => $expected->{named} // !!0;
88 61         2746 call positional => !$expected->{named};
89 61   100     2788 call invocant => $expected->{invocant} // !!0;
90 61         2677 call has_name => !!$expected->{name};
91 61         2703 call has_type => !!$expected->{type};
92 61         2638 call has_default => !!$expected->{default};
93 61         2620 call has_coerce => !!$expected->{coerce};
94 61         359 };
95             }
96              
97             sub test_is_same_interface {
98 30     30 1 602 my ($meta, @tests) = @_;
99              
100             ## no critic (ProhibitStringyEval)
101 30         117 my $is_same_interface = eval sprintf('sub { %s }', $meta->is_same_interface_inlined('$_[0]'));
102 30         169 my $is_relaxed_same_interface = eval sprintf('sub { %s }', $meta->is_relaxed_same_interface_inlined('$_[0]'));
103             ## use critic
104              
105 30         139 my $ctx = context;
106 30         2810 my $meta_class = ref $meta;
107 30         87 while (@tests) {
108 143         149122 my ($pass, $message, $args) = splice @tests, 0, 3;
109 143 100 100     996 my $other = ref $args && ref $args eq 'HASH'
110             ? $meta_class->new($args)
111             : $args;
112              
113 143         393 my $same = $meta->is_same_interface($other);
114 143         3800 my $same_inlined = $is_same_interface->($other);
115              
116 143         427 my $relax = $meta->is_relaxed_same_interface($other);
117 143         2725 my $relax_inlined = $is_relaxed_same_interface->($other);
118              
119             subtest "should $pass: $message" => sub {
120 143 100   143   38902 if ($pass eq 'pass') {
    100          
    100          
121 44         153 ok $same, 'is_same_interface';
122 44         10824 ok $same_inlined, 'is_same_interface_inlined';
123 44         10512 ok $relax, 'is_relaxed_same_interface';
124 44         10564 ok $relax_inlined, 'is_relaxed_same_interface_inlined';
125             }
126             elsif ($pass eq 'relax_pass') {
127 29         109 ok !$same, 'is_same_interface';
128 29         7569 ok !$same_inlined, 'is_same_interface_inlined';
129 29         6914 ok $relax, 'is_relaxed_same_interface';
130 29         6798 ok $relax_inlined, 'is_relaxed_same_interface_inlined';
131             }
132             elsif($pass eq 'fail') {
133 69         258 ok !$same, 'is_same_interface';
134 69         17930 ok !$same_inlined, 'is_same_interface_inlined';
135 69         16504 ok !$relax, 'is_relaxed_same_interface';
136 69         16585 ok !$relax_inlined, 'is_relaxed_same_interface_inlined';
137             }
138 143         1144 };
139             }
140 30         39539 $ctx->release;
141 30         762 return;
142             }
143              
144             sub test_error_message {
145 14     14 1 341 my ($meta, @tests) = @_;
146              
147 14         44 my $ctx = context;
148 14         1217 my $meta_class = ref $meta;
149              
150 14         44 while (@tests) {
151 58         58120 my ($pass, $args, $expected) = splice @tests, 0, 3;
152 58 100 100     406 my $other = ref $args && ref $args eq 'HASH'
153             ? $meta_class->new($args)
154             : $args;
155              
156 58         163 my $error_message = $meta->error_message($other);
157 58         151 my $relaxed_error_message = $meta->relaxed_error_message($other);
158              
159             subtest "should $pass: $expected" => sub {
160 58 100   58   15766 if ($pass eq 'pass') {
    100          
    100          
161 20         124 is $error_message, '', 'error_message';
162 20         7771 is $relaxed_error_message, '', 'relaxed_error_message';
163             }
164             elsif ($pass eq 'relax_pass') {
165 11         43 like $error_message, $expected, 'error_message';
166 11         4399 is $relaxed_error_message, '', 'relaxed_error_message';
167             }
168             elsif ($pass eq 'fail') {
169 26         99 like $error_message, $expected, 'error_message';
170 26         11232 like $relaxed_error_message, $expected, 'relaxed_error_message';
171             }
172 58         440 };
173             }
174              
175 14         17840 $ctx->release;
176 14         352 return;
177             }
178              
179             {
180             package ## no critic (Modules::ProhibitMultiplePackages) # hide from PAUSE
181             DummyType; ## no critic (RequireFilenameMatchesPackage)
182              
183             use overload
184             fallback => 1,
185 52     52   318 '""' => sub { 'DummyType' }
186 26     26   70512 ;
  26         71  
  26         366  
187              
188             sub new {
189 4     4   9 my $class = shift;
190 4         21 return bless {}, $class
191             }
192             };
193              
194             sub DummyType {
195 4     4 1 9246 return DummyType->new
196             }
197              
198             1;
199             __END__