Mouse::Util::does_role() respects $thing->does() method
[gitmo/Mouse.git] / t / 000_recipes / moose_cookbook_basics_recipe1.t
CommitLineData
596dcb26 1#!/usr/bin/perl -w
2
3use strict;
4use Test::More 'no_plan';
5use Test::Exception;
6$| = 1;
7
8
9
10# =begin testing SETUP
11{
12
13 package Point;
14 use Mouse;
15
16 has 'x' => (isa => 'Int', is => 'rw', required => 1);
17 has 'y' => (isa => 'Int', is => 'rw', required => 1);
18
19 sub clear {
20 my $self = shift;
21 $self->x(0);
22 $self->y(0);
23 }
24
25 package Point3D;
26 use Mouse;
27
28 extends 'Point';
29
30 has 'z' => (isa => 'Int', is => 'rw', required => 1);
31
32 after 'clear' => sub {
33 my $self = shift;
34 $self->z(0);
35 };
36
37 package main;
38
39 # hash or hashrefs are ok for the constructor
40 my $point1 = Point->new(x => 5, y => 7);
41 my $point2 = Point->new({x => 5, y => 7});
42
43 my $point3d = Point3D->new(x => 5, y => 42, z => -5);
44}
45
46
47
48# =begin testing
49{
50my $point = Point->new( x => 1, y => 2 );
51isa_ok( $point, 'Point' );
52isa_ok( $point, 'Mouse::Object' );
53
54is( $point->x, 1, '... got the right value for x' );
55is( $point->y, 2, '... got the right value for y' );
56
57$point->y(10);
58is( $point->y, 10, '... got the right (changed) value for y' );
59
60dies_ok {
61 $point->y('Foo');
62}
63'... cannot assign a non-Int to y';
64
65dies_ok {
66 Point->new();
67}
68'... must provide required attributes to new';
69
70$point->clear();
71
72is( $point->x, 0, '... got the right (cleared) value for x' );
73is( $point->y, 0, '... got the right (cleared) value for y' );
74
75# check the type constraints on the constructor
76
77lives_ok {
78 Point->new( x => 0, y => 0 );
79}
80'... can assign a 0 to x and y';
81
82dies_ok {
83 Point->new( x => 10, y => 'Foo' );
84}
85'... cannot assign a non-Int to y';
86
87dies_ok {
88 Point->new( x => 'Foo', y => 10 );
89}
90'... cannot assign a non-Int to x';
91
92# Point3D
93
94my $point3d = Point3D->new( { x => 10, y => 15, z => 3 } );
95isa_ok( $point3d, 'Point3D' );
96isa_ok( $point3d, 'Point' );
97isa_ok( $point3d, 'Mouse::Object' );
98
99is( $point3d->x, 10, '... got the right value for x' );
100is( $point3d->y, 15, '... got the right value for y' );
101is( $point3d->{'z'}, 3, '... got the right value for z' );
102
103$point3d->clear();
104
105is( $point3d->x, 0, '... got the right (cleared) value for x' );
106is( $point3d->y, 0, '... got the right (cleared) value for y' );
107is( $point3d->z, 0, '... got the right (cleared) value for z' );
108
109dies_ok {
110 Point3D->new( x => 10, y => 'Foo', z => 3 );
111}
112'... cannot assign a non-Int to y';
113
114dies_ok {
115 Point3D->new( x => 'Foo', y => 10, z => 3 );
116}
117'... cannot assign a non-Int to x';
118
119dies_ok {
120 Point3D->new( x => 0, y => 10, z => 'Bar' );
121}
122'... cannot assign a non-Int to z';
123
124dies_ok {
125 Point3D->new( x => 10, y => 3 );
126}
127'... z is a required attribute for Point3D';
128
129# test some class introspection
130
131can_ok( 'Point', 'meta' );
132isa_ok( Point->meta, 'Mouse::Meta::Class' );
133
134can_ok( 'Point3D', 'meta' );
135isa_ok( Point3D->meta, 'Mouse::Meta::Class' );
136
137isnt( Point->meta, Point3D->meta,
138 '... they are different metaclasses as well' );
139
140# poke at Point
141
142is_deeply(
143 [ Point->meta->superclasses ],
144 ['Mouse::Object'],
145 '... Point got the automagic base class'
146);
147
148my @Point_methods = qw(meta x y clear);
149my @Point_attrs = ( 'x', 'y' );
150
151is_deeply(
152 [ sort @Point_methods ],
153 [ sort Point->meta->get_method_list() ],
154 '... we match the method list for Point'
155);
156
157is_deeply(
158 [ sort @Point_attrs ],
159 [ sort Point->meta->get_attribute_list() ],
160 '... we match the attribute list for Point'
161);
162
163foreach my $method (@Point_methods) {
164 ok( Point->meta->has_method($method),
165 '... Point has the method "' . $method . '"' );
166}
167
168foreach my $attr_name (@Point_attrs) {
169 ok( Point->meta->has_attribute($attr_name),
170 '... Point has the attribute "' . $attr_name . '"' );
171 my $attr = Point->meta->get_attribute($attr_name);
172 ok( $attr->has_type_constraint,
173 '... Attribute ' . $attr_name . ' has a type constraint' );
174 isa_ok( $attr->type_constraint, 'Mouse::Meta::TypeConstraint' );
175 is( $attr->type_constraint->name, 'Int',
176 '... Attribute ' . $attr_name . ' has an Int type constraint' );
177}
178
179# poke at Point3D
180
181is_deeply(
182 [ Point3D->meta->superclasses ],
183 ['Point'],
184 '... Point3D gets the parent given to it'
185);
186
187my @Point3D_methods = qw( meta z clear );
188my @Point3D_attrs = ('z');
189
190is_deeply(
191 [ sort @Point3D_methods ],
192 [ sort Point3D->meta->get_method_list() ],
193 '... we match the method list for Point3D'
194);
195
196is_deeply(
197 [ sort @Point3D_attrs ],
198 [ sort Point3D->meta->get_attribute_list() ],
199 '... we match the attribute list for Point3D'
200);
201
202foreach my $method (@Point3D_methods) {
203 ok( Point3D->meta->has_method($method),
204 '... Point3D has the method "' . $method . '"' );
205}
206
207foreach my $attr_name (@Point3D_attrs) {
208 ok( Point3D->meta->has_attribute($attr_name),
209 '... Point3D has the attribute "' . $attr_name . '"' );
210 my $attr = Point3D->meta->get_attribute($attr_name);
211 ok( $attr->has_type_constraint,
212 '... Attribute ' . $attr_name . ' has a type constraint' );
213 isa_ok( $attr->type_constraint, 'Mouse::Meta::TypeConstraint' );
214 is( $attr->type_constraint->name, 'Int',
215 '... Attribute ' . $attr_name . ' has an Int type constraint' );
216}
217}
218
219
220
221
2221;