builder changes. sorry about diff noise, my editor ate trailing whitespace :(
[gitmo/Class-MOP.git] / t / 005_attributes.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 54;
7 use Test::Exception;
8
9 BEGIN {
10     use_ok('Class::MOP');
11 }
12
13 my $FOO_ATTR = Class::MOP::Attribute->new('$foo');
14 my $BAR_ATTR = Class::MOP::Attribute->new('$bar' => (
15     accessor => 'bar'
16 ));
17 my $BAZ_ATTR = Class::MOP::Attribute->new('$baz' => (
18     reader => 'get_baz',
19     writer => 'set_baz',
20 ));
21
22 my $BAR_ATTR_2 = Class::MOP::Attribute->new('$bar');
23
24 my $FOO_ATTR_2 = Class::MOP::Attribute->new('$foo' => (
25     accessor => 'foo',
26     builder => 'build_foo'
27 ));
28
29 is($FOO_ATTR->name, '$foo', '... got the attributes name correctly');
30 is($BAR_ATTR->name, '$bar', '... got the attributes name correctly');
31 is($BAZ_ATTR->name, '$baz', '... got the attributes name correctly');
32
33 {
34     package Foo;
35     use metaclass;
36
37     my $meta = Foo->meta;
38     ::lives_ok {
39         $meta->add_attribute($FOO_ATTR);
40     } '... we added an attribute to Foo successfully';
41     ::ok($meta->has_attribute('$foo'), '... Foo has $foo attribute');
42     ::is($meta->get_attribute('$foo'), $FOO_ATTR, '... got the right attribute back for Foo');
43
44     ::ok(!$meta->has_method('foo'), '... no accessor created');
45
46     ::lives_ok {
47         $meta->add_attribute($BAR_ATTR_2);
48     } '... we added an attribute to Foo successfully';
49     ::ok($meta->has_attribute('$bar'), '... Foo has $bar attribute');
50     ::is($meta->get_attribute('$bar'), $BAR_ATTR_2, '... got the right attribute back for Foo');
51
52     ::ok(!$meta->has_method('bar'), '... no accessor created');
53 }
54 {
55     package Bar;
56     our @ISA = ('Foo');
57
58     my $meta = Bar->meta;
59     ::lives_ok {
60         $meta->add_attribute($BAR_ATTR);
61     } '... we added an attribute to Bar successfully';
62     ::ok($meta->has_attribute('$bar'), '... Bar has $bar attribute');
63     ::is($meta->get_attribute('$bar'), $BAR_ATTR, '... got the right attribute back for Bar');
64
65     my $attr = $meta->get_attribute('$bar');
66     ::is($attr->get_read_method,  'bar', '... got the right read method for Bar');
67     ::is($attr->get_write_method, 'bar', '... got the right write method for Bar');
68
69     ::ok($meta->has_method('bar'), '... an accessor has been created');
70     ::isa_ok($meta->get_method('bar'), 'Class::MOP::Method::Accessor');
71 }
72 {
73     package Baz;
74     our @ISA = ('Bar');
75
76     my $meta = Baz->meta;
77     ::lives_ok {
78         $meta->add_attribute($BAZ_ATTR);
79     } '... we added an attribute to Baz successfully';
80     ::ok($meta->has_attribute('$baz'), '... Baz has $baz attribute');
81     ::is($meta->get_attribute('$baz'), $BAZ_ATTR, '... got the right attribute back for Baz');
82
83     my $attr = $meta->get_attribute('$baz');
84     ::is($attr->get_read_method,  'get_baz', '... got the right read method for Baz');
85     ::is($attr->get_write_method, 'set_baz', '... got the right write method for Baz');
86
87     ::ok($meta->has_method('get_baz'), '... a reader has been created');
88     ::ok($meta->has_method('set_baz'), '... a writer has been created');
89
90     ::isa_ok($meta->get_method('get_baz'), 'Class::MOP::Method::Accessor');
91     ::isa_ok($meta->get_method('set_baz'), 'Class::MOP::Method::Accessor');
92 }
93
94 {
95     my $meta = Baz->meta;
96     isa_ok($meta, 'Class::MOP::Class');
97
98     is($meta->find_attribute_by_name('$bar'), $BAR_ATTR, '... got the right attribute for "bar"');
99     is($meta->find_attribute_by_name('$baz'), $BAZ_ATTR, '... got the right attribute for "baz"');
100     is($meta->find_attribute_by_name('$foo'), $FOO_ATTR, '... got the right attribute for "foo"');
101
102     is_deeply(
103         [ sort { $a->name cmp $b->name } $meta->compute_all_applicable_attributes() ],
104         [
105             $BAR_ATTR,
106             $BAZ_ATTR,
107             $FOO_ATTR,
108         ],
109         '... got the right list of applicable attributes for Baz');
110
111     is_deeply(
112         [ map { $_->associated_class } sort { $a->name cmp $b->name } $meta->compute_all_applicable_attributes() ],
113         [ Bar->meta, Baz->meta, Foo->meta ],
114         '... got the right list of associated classes from the applicable attributes for Baz');
115
116     my $attr;
117     lives_ok {
118         $attr = $meta->remove_attribute('$baz');
119     } '... removed the $baz attribute successfully';
120     is($attr, $BAZ_ATTR, '... got the right attribute back for Baz');
121
122     ok(!$meta->has_attribute('$baz'), '... Baz no longer has $baz attribute');
123     is($meta->get_attribute('$baz'), undef, '... Baz no longer has $baz attribute');
124
125     ok(!$meta->has_method('get_baz'), '... a reader has been removed');
126     ok(!$meta->has_method('set_baz'), '... a writer has been removed');
127
128     is_deeply(
129         [ sort { $a->name cmp $b->name } $meta->compute_all_applicable_attributes() ],
130         [
131             $BAR_ATTR,
132             $FOO_ATTR,
133         ],
134         '... got the right list of applicable attributes for Baz');
135
136     is_deeply(
137         [ map { $_->associated_class } sort { $a->name cmp $b->name } $meta->compute_all_applicable_attributes() ],
138         [ Bar->meta, Foo->meta ],
139         '... got the right list of associated classes from the applicable attributes for Baz');
140
141      {
142          my $attr;
143          lives_ok {
144              $attr = Bar->meta->remove_attribute('$bar');
145          } '... removed the $bar attribute successfully';
146          is($attr, $BAR_ATTR, '... got the right attribute back for Bar');
147
148          ok(!Bar->meta->has_attribute('$bar'), '... Bar no longer has $bar attribute');
149
150          ok(!Bar->meta->has_method('bar'), '... a accessor has been removed');
151      }
152
153      is_deeply(
154          [ sort { $a->name cmp $b->name } $meta->compute_all_applicable_attributes() ],
155          [
156              $BAR_ATTR_2,
157              $FOO_ATTR,
158          ],
159          '... got the right list of applicable attributes for Baz');
160
161      is_deeply(
162          [ map { $_->associated_class } sort { $a->name cmp $b->name } $meta->compute_all_applicable_attributes() ],
163          [ Foo->meta, Foo->meta ],
164          '... got the right list of associated classes from the applicable attributes for Baz');
165
166     # remove attribute which is not there
167     my $val;
168     lives_ok {
169         $val = $meta->remove_attribute('$blammo');
170     } '... attempted to remove the non-existent $blammo attribute';
171     is($val, undef, '... got the right value back (undef)');
172
173 }
174
175 {
176     package Buzz;
177     use metaclass;
178     use Scalar::Util qw/blessed/;
179
180     my $meta = Buzz->meta;
181     ::lives_ok {
182         $meta->add_attribute($FOO_ATTR_2);
183     } '... we added an attribute to Buzz successfully';
184
185     ::lives_ok {
186         $meta->add_method(build_foo => sub{ blessed shift; });
187     } '... we added a method to Buzz successfully';
188 }
189
190 {
191   my $buzz;
192   ::lives_ok { $buzz = Buzz->meta->new_object } '...Buzz instantiated successfully';
193   ::is($buzz->foo, 'Buzz', 'foo builder works as expected');
194 }