We only need local $? if we inline calls to DEMOLISH
[gitmo/Moose.git] / t / type_constraints / inlining.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::Fatal;
7 use Test::More;
8
9 use Moose::Util::TypeConstraints;
10
11 #<<<
12 subtype 'Inlinable',
13     as 'Str',
14     where       { $_ !~ /Q/ },
15     inline_as   { "defined $_[1] && ! ref $_[1] && $_[1] !~ /Q/" };
16
17 subtype 'NotInlinable',
18     as 'Str',
19     where { $_ !~ /Q/ };
20 #>>>
21
22 my $inlinable     = find_type_constraint('Inlinable');
23 my $not_inlinable = find_type_constraint('NotInlinable');
24
25 {
26     ok(
27         $inlinable->can_be_inlined,
28         'Inlinable returns true for can_be_inlined'
29     );
30
31     is(
32         $inlinable->_inline_check('$foo'),
33         '( do { defined $foo && ! ref $foo && $foo !~ /Q/ } )',
34         'got expected inline code for Inlinable constraint'
35     );
36
37     ok(
38         !$not_inlinable->can_be_inlined,
39         'NotInlinable returns false for can_be_inlined'
40     );
41
42     like(
43         exception { $not_inlinable->_inline_check('$foo') },
44         qr/Cannot inline a type constraint check for NotInlinable/,
45         'threw an exception when asking for inlinable code from type which cannot be inlined'
46     );
47 }
48
49 {
50     my $aofi = Moose::Util::TypeConstraints::find_or_create_type_constraint(
51         'ArrayRef[Inlinable]');
52
53     ok(
54         $aofi->can_be_inlined,
55         'ArrayRef[Inlinable] returns true for can_be_inlined'
56     );
57
58     is(
59         $aofi->_inline_check('$foo'),
60         q{( do { do {my $check = $foo;ref($check) eq "ARRAY" && &List::MoreUtils::all(sub { ( do { defined $_ && ! ref $_ && $_ !~ /Q/ } ) }, @{$check})} } )},
61         'got expected inline code for ArrayRef[Inlinable] constraint'
62     );
63
64     my $aofni = Moose::Util::TypeConstraints::find_or_create_type_constraint(
65         'ArrayRef[NotInlinable]');
66
67     ok(
68         !$aofni->can_be_inlined,
69         'ArrayRef[NotInlinable] returns false for can_be_inlined'
70     );
71 }
72
73 subtype 'ArrayOfInlinable',
74     as 'ArrayRef[Inlinable]';
75
76 subtype 'ArrayOfNotInlinable',
77     as 'ArrayRef[NotInlinable]';
78 {
79     my $aofi = Moose::Util::TypeConstraints::find_or_create_type_constraint(
80         'ArrayOfInlinable');
81
82     ok(
83         $aofi->can_be_inlined,
84         'ArrayOfInlinable returns true for can_be_inlined'
85     );
86
87     is(
88         $aofi->_inline_check('$foo'),
89         q{( do { do {my $check = $foo;ref($check) eq "ARRAY" && &List::MoreUtils::all(sub { ( do { defined $_ && ! ref $_ && $_ !~ /Q/ } ) }, @{$check})} } )},
90         'got expected inline code for ArrayOfInlinable constraint'
91     );
92
93     my $aofni = Moose::Util::TypeConstraints::find_or_create_type_constraint(
94         'ArrayOfNotInlinable');
95
96     ok(
97         !$aofni->can_be_inlined,
98         'ArrayOfNotInlinable returns false for can_be_inlined'
99     );
100 }
101
102 {
103     my $hoaofi = Moose::Util::TypeConstraints::find_or_create_type_constraint(
104         'HashRef[ArrayRef[Inlinable]]');
105
106     ok(
107         $hoaofi->can_be_inlined,
108         'HashRef[ArrayRef[Inlinable]] returns true for can_be_inlined'
109     );
110
111     is(
112         $hoaofi->_inline_check('$foo'),
113         q{( do { do {my $check = $foo;ref($check) eq "HASH" && &List::MoreUtils::all(sub { ( do { do {my $check = $_;ref($check) eq "ARRAY" && &List::MoreUtils::all(sub { ( do { defined $_ && ! ref $_ && $_ !~ /Q/ } ) }, @{$check})} } ) }, values %{$check})} } )},
114         'got expected inline code for HashRef[ArrayRef[Inlinable]] constraint'
115     );
116
117     my $hoaofni = Moose::Util::TypeConstraints::find_or_create_type_constraint(
118         'HashRef[ArrayRef[NotInlinable]]');
119
120     ok(
121         !$hoaofni->can_be_inlined,
122         'HashRef[ArrayRef[NotInlinable]] returns false for can_be_inlined'
123     );
124 }
125
126 {
127     my $iunion = Moose::Util::TypeConstraints::find_or_create_type_constraint(
128         'Inlinable | Object');
129
130     ok(
131         $iunion->can_be_inlined,
132         'Inlinable | Object returns true for can_be_inlined'
133     );
134
135     is(
136         $iunion->_inline_check('$foo'),
137         '((( do { defined $foo && ! ref $foo && $foo !~ /Q/ } )) || (( do { Scalar::Util::blessed($foo) } )))',
138         'got expected inline code for Inlinable | Object constraint'
139     );
140
141     my $niunion = Moose::Util::TypeConstraints::find_or_create_type_constraint(
142         'NotInlinable | Object');
143
144     ok(
145         !$niunion->can_be_inlined,
146         'NotInlinable | Object returns false for can_be_inlined'
147     );
148 }
149
150 {
151     my $iunion = Moose::Util::TypeConstraints::find_or_create_type_constraint(
152         'Object | Inlinable');
153
154     ok(
155         $iunion->can_be_inlined,
156         'Object | Inlinable returns true for can_be_inlined'
157     );
158
159     is(
160         $iunion->_inline_check('$foo'),
161         '((( do { Scalar::Util::blessed($foo) } )) || (( do { defined $foo && ! ref $foo && $foo !~ /Q/ } )))',
162         'got expected inline code for Object | Inlinable constraint'
163     );
164
165     my $niunion = Moose::Util::TypeConstraints::find_or_create_type_constraint(
166         'Object | NotInlinable');
167
168     ok(
169         !$niunion->can_be_inlined,
170         'Object | NotInlinable returns false for can_be_inlined'
171     );
172 }
173
174 {
175     my $iunion = Moose::Util::TypeConstraints::find_or_create_type_constraint(
176         'Object | Inlinable | CodeRef');
177
178     ok(
179         $iunion->can_be_inlined,
180         'Object | Inlinable | CodeRef returns true for can_be_inlined'
181     );
182
183     is(
184         $iunion->_inline_check('$foo'),
185         q{((( do { Scalar::Util::blessed($foo) } )) || (( do { defined $foo && ! ref $foo && $foo !~ /Q/ } )) || (( do { ref($foo) eq "CODE" } )))},
186         'got expected inline code for Object | Inlinable | CodeRef constraint'
187     );
188
189     my $niunion = Moose::Util::TypeConstraints::find_or_create_type_constraint(
190         'Object | NotInlinable | CodeRef');
191
192     ok(
193         !$niunion->can_be_inlined,
194         'Object | NotInlinable | CodeRef returns false for can_be_inlined'
195     );
196 }
197
198 done_testing;