Fix error reporting in duck_type
[gitmo/Moose.git] / t / roles / apply_role.t
CommitLineData
78cd1d3b 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
a28e50e4 6use Test::More;
b10dde3a 7use Test::Fatal;
78cd1d3b 8
78cd1d3b 9{
10 package FooRole;
78cd1d3b 11 use Moose::Role;
0be0b30e 12
2e7f6cf4 13 our $VERSION = 23;
14
0be0b30e 15 has 'bar' => ( is => 'rw', isa => 'FooClass' );
16 has 'baz' => ( is => 'ro' );
17
18 sub goo {'FooRole::goo'}
19 sub foo {'FooRole::foo'}
20
21 override 'boo' => sub { 'FooRole::boo -> ' . super() };
22
23 around 'blau' => sub {
0558683c 24 my $c = shift;
25 'FooRole::blau -> ' . $c->();
0be0b30e 26 };
27}
78cd1d3b 28
0be0b30e 29{
3f562dd9 30 package BarRole;
31 use Moose::Role;
0be0b30e 32 sub woot {'BarRole::woot'}
33}
34
35{
78cd1d3b 36 package BarClass;
78cd1d3b 37 use Moose;
8ecb1fa0 38
0be0b30e 39 sub boo {'BarClass::boo'}
40 sub foo {'BarClass::foo'} # << the role overrides this ...
0be0b30e 41}
42
43{
78cd1d3b 44 package FooClass;
78cd1d3b 45 use Moose;
0be0b30e 46
78cd1d3b 47 extends 'BarClass';
2e7f6cf4 48
b10dde3a 49 ::like( ::exception { with 'FooRole' => { -version => 42 } }, qr/FooRole version 42 required--this is only version 23/, 'applying role with unsatisfied version requirement' );
2e7f6cf4 50
b10dde3a 51 ::is( ::exception { with 'FooRole' => { -version => 13 } }, undef, 'applying role with satisfied version requirement' );
0be0b30e 52
53 sub blau {'FooClass::blau'} # << the role wraps this ...
54
55 sub goo {'FooClass::goo'} # << overrides the one from the role ...
0be0b30e 56}
57
58{
3f562dd9 59 package FooBarClass;
60 use Moose;
0be0b30e 61
3f562dd9 62 extends 'FooClass';
0be0b30e 63 with 'FooRole', 'BarRole';
78cd1d3b 64}
65
66my $foo_class_meta = FooClass->meta;
0be0b30e 67isa_ok( $foo_class_meta, 'Moose::Meta::Class' );
78cd1d3b 68
3f562dd9 69my $foobar_class_meta = FooBarClass->meta;
0be0b30e 70isa_ok( $foobar_class_meta, 'Moose::Meta::Class' );
3f562dd9 71
b10dde3a 72isnt( exception {
0be0b30e 73 $foo_class_meta->does_role();
b10dde3a 74}, undef, '... does_role requires a role name' );
bbd2fe69 75
b10dde3a 76isnt( exception {
e016145b 77 $foo_class_meta->add_role();
b10dde3a 78}, undef, '... apply_role requires a role' );
bbd2fe69 79
b10dde3a 80isnt( exception {
e016145b 81 $foo_class_meta->add_role( bless( {} => 'Fail' ) );
b10dde3a 82}, undef, '... apply_role requires a role' );
bbd2fe69 83
0be0b30e 84ok( $foo_class_meta->does_role('FooRole'),
85 '... the FooClass->meta does_role FooRole' );
86ok( !$foo_class_meta->does_role('OtherRole'),
87 '... the FooClass->meta !does_role OtherRole' );
ef333f17 88
0be0b30e 89ok( $foobar_class_meta->does_role('FooRole'),
90 '... the FooBarClass->meta does_role FooRole' );
91ok( $foobar_class_meta->does_role('BarRole'),
92 '... the FooBarClass->meta does_role BarRole' );
93ok( !$foobar_class_meta->does_role('OtherRole'),
94 '... the FooBarClass->meta !does_role OtherRole' );
3f562dd9 95
0558683c 96foreach my $method_name (qw(bar baz foo boo blau goo)) {
0be0b30e 97 ok( $foo_class_meta->has_method($method_name),
98 '... FooClass has the method ' . $method_name );
99 ok( $foobar_class_meta->has_method($method_name),
100 '... FooBarClass has the method ' . $method_name );
78cd1d3b 101}
102
0be0b30e 103ok( !$foo_class_meta->has_method('woot'),
104 '... FooClass lacks the method woot' );
105ok( $foobar_class_meta->has_method('woot'),
106 '... FooBarClass has the method woot' );
3f562dd9 107
78cd1d3b 108foreach my $attr_name (qw(bar baz)) {
0be0b30e 109 ok( $foo_class_meta->has_attribute($attr_name),
110 '... FooClass has the attribute ' . $attr_name );
111 ok( $foobar_class_meta->has_attribute($attr_name),
112 '... FooBarClass has the attribute ' . $attr_name );
78cd1d3b 113}
114
0be0b30e 115can_ok( 'FooClass', 'does' );
116ok( FooClass->does('FooRole'), '... the FooClass does FooRole' );
117ok( !FooClass->does('BarRole'), '... the FooClass does not do BarRole' );
118ok( !FooClass->does('OtherRole'), '... the FooClass does not do OtherRole' );
ef333f17 119
0be0b30e 120can_ok( 'FooBarClass', 'does' );
121ok( FooBarClass->does('FooRole'), '... the FooClass does FooRole' );
122ok( FooBarClass->does('BarRole'), '... the FooBarClass does FooBarRole' );
123ok( !FooBarClass->does('OtherRole'),
124 '... the FooBarClass does not do OtherRole' );
3f562dd9 125
78cd1d3b 126my $foo = FooClass->new();
0be0b30e 127isa_ok( $foo, 'FooClass' );
78cd1d3b 128
3f562dd9 129my $foobar = FooBarClass->new();
0be0b30e 130isa_ok( $foobar, 'FooBarClass' );
131
132is( $foo->goo, 'FooClass::goo', '... got the right value of goo' );
133is( $foobar->goo, 'FooRole::goo', '... got the right value of goo' );
134
135is( $foo->boo, 'FooRole::boo -> BarClass::boo',
136 '... got the right value from ->boo' );
137is( $foobar->boo, 'FooRole::boo -> FooRole::boo -> BarClass::boo',
138 '... got the right value from ->boo (double wrapped)' );
139
140is( $foo->blau, 'FooRole::blau -> FooClass::blau',
141 '... got the right value from ->blau' );
142is( $foobar->blau, 'FooRole::blau -> FooRole::blau -> FooClass::blau',
143 '... got the right value from ->blau' );
144
145foreach my $foo ( $foo, $foobar ) {
146 can_ok( $foo, 'does' );
147 ok( $foo->does('FooRole'), '... an instance of FooClass does FooRole' );
148 ok( !$foo->does('OtherRole'),
149 '... and instance of FooClass does not do OtherRole' );
150
151 can_ok( $foobar, 'does' );
152 ok( $foobar->does('FooRole'),
153 '... an instance of FooBarClass does FooRole' );
154 ok( $foobar->does('BarRole'),
155 '... an instance of FooBarClass does BarRole' );
156 ok( !$foobar->does('OtherRole'),
157 '... and instance of FooBarClass does not do OtherRole' );
78cd1d3b 158
fb1e11d5 159 for my $method (qw/bar baz foo boo goo blau/) {
0be0b30e 160 can_ok( $foo, $method );
fb1e11d5 161 }
78cd1d3b 162
0be0b30e 163 is( $foo->foo, 'FooRole::foo', '... got the right value of foo' );
78cd1d3b 164
0be0b30e 165 ok( !defined( $foo->baz ), '... $foo->baz is undefined' );
166 ok( !defined( $foo->bar ), '... $foo->bar is undefined' );
78cd1d3b 167
b10dde3a 168 isnt( exception {
0be0b30e 169 $foo->baz(1);
b10dde3a 170 }, undef, '... baz is a read-only accessor' );
78cd1d3b 171
b10dde3a 172 isnt( exception {
0be0b30e 173 $foo->bar(1);
b10dde3a 174 }, undef, '... bar is a read-write accessor with a type constraint' );
78cd1d3b 175
fb1e11d5 176 my $foo2 = FooClass->new();
0be0b30e 177 isa_ok( $foo2, 'FooClass' );
06b30515 178
b10dde3a 179 is( exception {
0be0b30e 180 $foo->bar($foo2);
b10dde3a 181 }, undef, '... bar is a read-write accessor with a type constraint' );
fb1e11d5 182
0be0b30e 183 is( $foo->bar, $foo2, '... got the right value for bar now' );
fb1e11d5 184}
a28e50e4 185
8e590ae4 186{
187 {
188 package MRole;
189 use Moose::Role;
190 sub meth { }
191 }
192
193 {
194 package MRole2;
195 use Moose::Role;
196 sub meth2 { }
197 }
198
199 {
200 use Moose::Meta::Class;
201 use Moose::Object;
202 use Moose::Util qw(apply_all_roles);
203
204 my $class = Moose::Meta::Class->create( 'Class' => (
205 superclasses => [ 'Moose::Object' ],
206 ));
207
208 apply_all_roles($class, MRole->meta, MRole2->meta);
209
210 ok(Class->can('meth'), "can meth");
211 ok(Class->can('meth2'), "can meth2");
212 }
213}
214
a28e50e4 215done_testing;