File Coverage

blib/lib/Sub/Meta/Type.pm
Criterion Covered Total %
statement 66 66 100.0
branch 20 20 100.0
condition n/a
subroutine 21 21 100.0
pod 9 9 100.0
total 116 116 100.0


line stmt bran cond sub pod time code
1             package Sub::Meta::Type;
2 5     5   1965 use 5.010;
  5         18  
3 5     5   32 use strict;
  5         13  
  5         105  
4 5     5   24 use warnings;
  5         9  
  5         143  
5              
6 5     5   1294 use parent qw(Type::Tiny);
  5         922  
  5         30  
7              
8 5     5   71732 use Type::Coercion;
  5         18911  
  5         176  
9 5     5   1740 use Types::Standard qw(Ref InstanceOf);
  5         204091  
  5         47  
10              
11 26     26 1 181 sub submeta { my $self = shift; return $self->{submeta} }
  26         124  
12 10     10 1 30 sub submeta_strict_check { my $self = shift; return $self->{submeta_strict_check} }
  10         52  
13 19     19 1 37 sub find_submeta { my $self = shift; return $self->{find_submeta} }
  19         94  
14              
15             ## override
16             sub new {
17 13     13 1 9717 my $class = shift;
18 13 100       85 my %params = ( @_ == 1 ) ? %{ $_[0] } : @_;
  1         3  
19              
20             ## no critic (Subroutines::ProtectPrivateSubs)
21 13 100       51 Type::Tiny::_croak "Need to supply submeta" unless exists $params{submeta};
22 11 100       37 Type::Tiny::_croak "Need to supply submeta_strict_check" unless exists $params{submeta_strict_check};
23 10 100       37 Type::Tiny::_croak "Need to supply find_submeta" unless exists $params{find_submeta};
24             ## use critic
25              
26 9 100       26 if (!exists $params{name}) {
27 8 100       37 $params{name} = $params{submeta_strict_check} ? 'StrictSubMeta' : 'SubMeta';
28             }
29              
30             $params{inlined} = $params{submeta_strict_check}
31 2     2   22 ? sub { my ($self, $var) = @_; $self->submeta->is_strict_same_interface_inlined($var) }
  2         10  
32 9 100   6   61 : sub { my ($self, $var) = @_; $self->submeta->is_relaxed_same_interface_inlined($var) };
  6         108  
  6         37  
33              
34 9         70 return $class->SUPER::new(%params);
35             }
36              
37             ## override
38 16     16 1 81 sub has_parent { return !!0 }
39 20     20 1 659 sub can_be_inlined { return !!1 }
40 20     20 1 2701 sub has_coercion { return !!1 }
41 12     12   2453 sub _is_null_constraint { return !!0 } ## no critic (ProhibitUnusedPrivateSubroutines)
42              
43             ## override
44             sub _build_display_name { ## no critic (ProhibitUnusedPrivateSubroutines)
45 4     4   63 my $self = shift;
46 4         15 return sprintf('%s[%s]', $self->name, $self->submeta->display);
47             }
48              
49             #
50             # e.g.
51             # Reference bless( sub { "DUMMY" }, 'Sub::WrapInType' ) did not pass type constraint "SubMeta"
52             # Reason : invalid scalar return. got: Str, expected: Int
53             # Expected : sub (Int,Int) => Int
54             # Got : sub (Int,Int) => Str
55             #
56             ## override
57             sub get_message {
58 4     4 1 17200 my $self = shift;
59 4         8 my $other_meta = shift;
60              
61 4         13 my $default_message = $self->SUPER::get_message($other_meta);
62 4         6879 my $detail_message = $self->get_detail_message($other_meta);
63              
64 4         11 my $message = <<"```";
65             $default_message
66             $detail_message
67             ```
68              
69 4         10 return $message;
70             }
71              
72             sub get_detail_message {
73 5     5 1 9 my $self = shift;
74 5         9 my $other_meta = shift;
75              
76 5         15 state $SubMeta = InstanceOf['Sub::Meta'];
77              
78 5         4238 my ($error_message, $expected, $got);
79 5 100       16 if ($self->submeta_strict_check) {
80 2         5 $error_message = $self->submeta->error_message($other_meta);
81 2         6 $expected = $self->submeta->display;
82 2 100       8 $got = $SubMeta->check($other_meta) ? $other_meta->display : "";
83             }
84             else {
85 3         10 $error_message = $self->submeta->relaxed_error_message($other_meta);
86 3         12 $expected = $self->submeta->display;
87 3 100       16 $got = $SubMeta->check($other_meta) ? $other_meta->display : "";
88             }
89              
90 5         33 my $message = <<"```";
91             Reason : $error_message
92             Expected : $expected
93             Got : $got
94             ```
95              
96 5         11 return $message;
97             }
98              
99             ## override
100             sub _build_coercion { ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)
101 4     4   666 my $self = shift;
102              
103             return Type::Coercion->new(
104             display_name => "to_${self}",
105             type_constraint => $self,
106             type_coercion_map => [
107             Ref['CODE'] => sub {
108 18     18   3728 my $sub = shift;
109 18         65 return $self->find_submeta->($sub);
110             },
111 4         23 ],
112             );
113             }
114              
115             1;
116             __END__