Redid conversion to Test::Fatal
[gitmo/Moose.git] / t / 030_roles / 013_method_aliasing_in_composition.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More;
7 use Test::Fatal;
8
9
10 {
11     package My::Role;
12     use Moose::Role;
13
14     sub foo { 'Foo::foo' }
15     sub bar { 'Foo::bar' }
16     sub baz { 'Foo::baz' }
17
18     requires 'role_bar';
19
20     package My::Class;
21     use Moose;
22
23     ::is( ::exception {
24         with 'My::Role' => { -alias => { bar => 'role_bar' } };
25     }, undef, '... this succeeds' );
26
27     package My::Class::Failure;
28     use Moose;
29
30     ::like( ::exception {
31         with 'My::Role' => { -alias => { bar => 'role_bar' } };
32     }, qr/Cannot create a method alias if a local method of the same name exists/, '... this succeeds' );
33
34     sub role_bar { 'FAIL' }
35 }
36
37 ok(My::Class->meta->has_method($_), "we have a $_ method") for qw(foo baz bar role_bar);
38
39 {
40     package My::OtherRole;
41     use Moose::Role;
42
43     ::is( ::exception {
44         with 'My::Role' => { -alias => { bar => 'role_bar' } };
45     }, undef, '... this succeeds' );
46
47     sub bar { 'My::OtherRole::bar' }
48
49     package My::OtherRole::Failure;
50     use Moose::Role;
51
52     ::like( ::exception {
53         with 'My::Role' => { -alias => { bar => 'role_bar' } };
54     }, qr/Cannot create a method alias if a local method of the same name exists/, '... cannot alias to a name that exists' );
55
56     sub role_bar { 'FAIL' }
57 }
58
59 ok(My::OtherRole->meta->has_method($_), "we have a $_ method") for qw(foo baz role_bar);
60 ok(My::OtherRole->meta->requires_method('bar'), '... and the &bar method is required');
61 ok(!My::OtherRole->meta->requires_method('role_bar'), '... and the &role_bar method is not required');
62
63 {
64     package My::AliasingRole;
65     use Moose::Role;
66
67     ::is( ::exception {
68         with 'My::Role' => { -alias => { bar => 'role_bar' } };
69     }, undef, '... this succeeds' );
70 }
71
72 ok(My::AliasingRole->meta->has_method($_), "we have a $_ method") for qw(foo baz role_bar);
73 ok(!My::AliasingRole->meta->requires_method('bar'), '... and the &bar method is not required');
74
75 {
76     package Foo::Role;
77     use Moose::Role;
78
79     sub foo { 'Foo::Role::foo' }
80
81     package Bar::Role;
82     use Moose::Role;
83
84     sub foo { 'Bar::Role::foo' }
85
86     package Baz::Role;
87     use Moose::Role;
88
89     sub foo { 'Baz::Role::foo' }
90
91     package My::Foo::Class;
92     use Moose;
93
94     ::is( ::exception {
95         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
96              'Bar::Role' => { -alias => { 'foo' => 'bar_foo' }, -excludes => 'foo' },
97              'Baz::Role';
98     }, undef, '... composed our roles correctly' );
99
100     package My::Foo::Class::Broken;
101     use Moose;
102
103     ::like( ::exception {
104         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
105              'Bar::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
106              'Baz::Role';
107     }, qr/Due to a method name conflict in roles 'Bar::Role' and 'Foo::Role', the method 'foo_foo' must be implemented or excluded by 'My::Foo::Class::Broken'/, '... composed our roles correctly' );
108 }
109
110 {
111     my $foo = My::Foo::Class->new;
112     isa_ok($foo, 'My::Foo::Class');
113     can_ok($foo, $_) for qw/foo foo_foo bar_foo/;
114     is($foo->foo, 'Baz::Role::foo', '... got the right method');
115     is($foo->foo_foo, 'Foo::Role::foo', '... got the right method');
116     is($foo->bar_foo, 'Bar::Role::foo', '... got the right method');
117 }
118
119 {
120     package My::Foo::Role;
121     use Moose::Role;
122
123     ::is( ::exception {
124         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
125              'Bar::Role' => { -alias => { 'foo' => 'bar_foo' }, -excludes => 'foo' },
126              'Baz::Role';
127     }, undef, '... composed our roles correctly' );
128 }
129
130 ok(My::Foo::Role->meta->has_method($_), "we have a $_ method") for qw/foo foo_foo bar_foo/;;
131 ok(!My::Foo::Role->meta->requires_method('foo'), '... and the &foo method is not required');
132
133
134 {
135     package My::Foo::Role::Other;
136     use Moose::Role;
137
138     ::is( ::exception {
139         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
140              'Bar::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
141              'Baz::Role';
142     }, undef, '... composed our roles correctly' );
143 }
144
145 ok(!My::Foo::Role::Other->meta->has_method('foo_foo'), "we dont have a foo_foo method");
146 ok(My::Foo::Role::Other->meta->requires_method('foo_foo'), '... and the &foo method is required');
147
148 {
149     package My::Foo::AliasOnly;
150     use Moose;
151
152     ::is( ::exception {
153         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' } },
154     }, undef, '... composed our roles correctly' );
155 }
156
157 ok(My::Foo::AliasOnly->meta->has_method('foo'), 'we have a foo method');
158 ok(My::Foo::AliasOnly->meta->has_method('foo_foo'), '.. and the aliased foo_foo method');
159
160 {
161     package Role::Foo;
162     use Moose::Role;
163
164     sub x1 {}
165     sub y1 {}
166 }
167
168 {
169     package Role::Bar;
170     use Moose::Role;
171
172     ::is( ::exception {
173         with 'Role::Foo' => {
174             -alias    => { x1 => 'foo_x1' },
175             -excludes => ['y1'],
176         };
177     }, undef, 'Compose Role::Foo into Role::Bar with alias and exclude' );
178
179     sub x1 {}
180     sub y1 {}
181 }
182
183 {
184     my $bar = Role::Bar->meta;
185     ok( $bar->has_method($_), "has $_ method" )
186         for qw( x1 y1 foo_x1 );
187 }
188
189 {
190     package Role::Baz;
191     use Moose::Role;
192
193     ::is( ::exception {
194         with 'Role::Foo' => {
195             -alias    => { x1 => 'foo_x1' },
196             -excludes => ['y1'],
197         };
198     }, undef, 'Compose Role::Foo into Role::Baz with alias and exclude' );
199 }
200
201 {
202     my $baz = Role::Baz->meta;
203     ok( $baz->has_method($_), "has $_ method" )
204         for qw( x1 foo_x1 );
205     ok( ! $baz->has_method('y1'), 'Role::Baz has no y1 method' );
206 }
207
208 done_testing;