foo
[gitmo/Moose.git] / t / 008_basic.t
CommitLineData
fcec2383 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use Test::More tests => 63;
7use Test::Exception;
8
9BEGIN {
10 use_ok('Moose');
11}
12
13BEGIN {
14
15 package Newswriter::Meta::Instance;
16 use strict;
17 use warnings;
18 use Moose;
19
20 use DBM::Deep;
21
22 extends 'Moose::Meta::Instance';
23
24 {
25 my $instance_counter = -1;
26
27 my $db = DBM::Deep->new({
28 file => "newswriter.db",
29 autobless => 1
30 });
31 $db->{root} = [] unless exists $db->{root};
32
33 sub _get_db { $db }
34 sub _reload_db {
35 $db = DBM::Deep->new({
36 file => "newswriter.db",
37 autobless => 1
38 })
39 }
40
41 sub create_instance {
42 my $self = shift;
43 $instance_counter++;
44 $db->{root}->[$instance_counter] = {};
45
46 $self->bless_instance_structure({
47 oid => $instance_counter,
48 instance => $db->{root}->[$instance_counter]
49 });
50 }
51
52 sub find_instance {
53 my ($self, $oid) = @_;
54 my $instance_struct = $db->{root}->[$oid];
55
56 $self->bless_instance_structure({
57 oid => $oid,
58 instance => $instance_struct
59 });
60 }
61 }
62
63 sub get_instance_oid {
64 my ($self, $instance) = @_;
65 $instance->{oid};
66 }
67
68 sub clone_instance {
69 confess "&clone_instance is left as an exercise for the user";
70 }
71
72 sub get_slot_value {
73 my ($self, $instance, $slot_name) = @_;
74 return $instance->{instance}->{$slot_name};
75 }
76
77 sub set_slot_value {
78 my ($self, $instance, $slot_name, $value) = @_;
79 $instance->{instance}->{$slot_name} = $value;
80 }
81
82 sub is_slot_initialized {
83 my ($self, $instance, $slot_name, $value) = @_;
84 exists $instance->{instance}->{$slot_name} ? 1 : 0;
85 }
86
87 sub weaken_slot_value {
88 confess "Not sure how well DBM::Deep plays with weak refs, Rob says 'Writer a test'";
89 }
90
91 sub inline_slot_access {
92 my ($self, $instance, $slot_name) = @_;
93 sprintf "%s->{instance}->{%s}", $instance, $slot_name;
94 }
95
96 package Newswriter::Meta::Class;
97 use strict;
98 use warnings;
99 use Moose;
100
101 extends 'Moose::Meta::Class';
102
103 override 'construct_instance' => sub {
104 my ($class, %params) = @_;
105 return $class->get_meta_instance->find_instance($params{oid})
106 if $params{oid};
107 super();
108 };
109}
110
111{
112 package Newswriter::Base;
113 use strict;
114 use warnings;
115 use metaclass 'Newswriter::Meta::Class' => (
116 ':instance_metaclass' => 'Newswriter::Meta::Instance'
117 );
118 use Moose;
119
120 sub oid {
121 my $self = shift;
122 $self->meta
123 ->get_meta_instance
124 ->get_instance_oid($self);
125 }
126
127 package Newswriter::Author;
128 use strict;
129 use warnings;
130 use metaclass 'Newswriter::Meta::Class' => (
131 ':instance_metaclass' => 'Newswriter::Meta::Instance'
132 );
133 use Moose;
134
135 extends 'Newswriter::Base';
136
137 has 'first_name' => (is => 'rw', isa => 'Str');
138 has 'last_name' => (is => 'rw', isa => 'Str');
139
140 package Newswriter::Article;
141 use strict;
142 use warnings;
143 use metaclass 'Newswriter::Meta::Class' => (
144 ':instance_metaclass' => 'Newswriter::Meta::Instance'
145 );
146 use Moose;
147 use Moose::Util::TypeConstraints;
148
149 use DateTime::Format::MySQL;
150
151 use base 'Newswriter::Base';
152
153 subtype 'Headline'
154 => as 'Str'
155 => where { length($_) < 100 };
156
157 subtype 'Summary'
158 => as 'Str'
159 => where { length($_) < 255 };
160
161 subtype 'DateTimeFormatString'
162 => as 'Str'
163 => where { DateTime::Format::MySQL->parse_datetime($_) };
164
165 enum 'Status' => qw(draft posted pending archive);
166
167 has 'headline' => (is => 'rw', isa => 'Headline');
168 has 'summary' => (is => 'rw', isa => 'Summary');
169 has 'article' => (is => 'rw', isa => 'Str');
170
171 has 'start_date' => (is => 'rw', isa => 'DateTimeFormatString');
172 has 'end_date' => (is => 'rw', isa => 'DateTimeFormatString');
173
174 has 'author' => (is => 'rw', isa => 'Newswriter::Author');
175
176 has 'status' => (is => 'rw', isa => 'Status');
177
178 around 'start_date', 'end_date' => sub {
179 my $c = shift;
180 my $self = shift;
181 $c->($self, DateTime::Format::MySQL->format_datetime($_[0])) if @_;
182 DateTime::Format::MySQL->parse_datetime($c->($self));
183 };
184}
185
186{ # check the meta stuff first
187 isa_ok(Newswriter::Base->meta, 'Newswriter::Meta::Class');
188 isa_ok(Newswriter::Base->meta, 'Moose::Meta::Class');
189 isa_ok(Newswriter::Base->meta, 'Class::MOP::Class');
190
191 is(Newswriter::Base->meta->instance_metaclass,
192 'Newswriter::Meta::Instance',
193 '... got the right instance metaclass name');
194
195 isa_ok(Newswriter::Base->meta->get_meta_instance, 'Newswriter::Meta::Instance');
196
197 my $base = Newswriter::Base->new;
198 isa_ok($base, 'Newswriter::Base');
199 isa_ok($base, 'Moose::Object');
200
201 isa_ok($base->meta, 'Newswriter::Meta::Class');
202 isa_ok($base->meta, 'Moose::Meta::Class');
203 isa_ok($base->meta, 'Class::MOP::Class');
204
205 is($base->meta->instance_metaclass,
206 'Newswriter::Meta::Instance',
207 '... got the right instance metaclass name');
208
209 isa_ok($base->meta->get_meta_instance, 'Newswriter::Meta::Instance');
210}
211
212my $article_oid;
213my $article_ref;
214{
215 my $article;
216 lives_ok {
217 $article = Newswriter::Article->new(
218 headline => 'Home Office Redecorated',
219 summary => 'The home office was recently redecorated to match the new company colors',
220 article => '...',
221
222 author => Newswriter::Author->new(
223 first_name => 'Truman',
224 last_name => 'Capote'
225 ),
226
227 status => 'pending'
228 );
229 } '... created my article successfully';
230 isa_ok($article, 'Newswriter::Article');
231 isa_ok($article, 'Newswriter::Base');
232
233 lives_ok {
234 $article->start_date(DateTime->new(year => 2006, month => 6, day => 10));
235 $article->end_date(DateTime->new(year => 2006, month => 6, day => 17));
236 } '... add the article date-time stuff';
237
238 ## check some meta stuff
239
240 isa_ok($article->meta, 'Newswriter::Meta::Class');
241 isa_ok($article->meta, 'Moose::Meta::Class');
242 isa_ok($article->meta, 'Class::MOP::Class');
243
244 is($article->meta->instance_metaclass,
245 'Newswriter::Meta::Instance',
246 '... got the right instance metaclass name');
247
248 isa_ok($article->meta->get_meta_instance, 'Newswriter::Meta::Instance');
249
250 ok($article->oid, '... got a oid for the article');
251
252 $article_oid = $article->oid;
253 $article_ref = "$article";
254
255 is($article->headline,
256 'Home Office Redecorated',
257 '... got the right headline');
258 is($article->summary,
259 'The home office was recently redecorated to match the new company colors',
260 '... got the right summary');
261 is($article->article, '...', '... got the right article');
262
263 isa_ok($article->start_date, 'DateTime');
264 isa_ok($article->end_date, 'DateTime');
265
266 isa_ok($article->author, 'Newswriter::Author');
267 is($article->author->first_name, 'Truman', '... got the right author first name');
268 is($article->author->last_name, 'Capote', '... got the right author last name');
269
270 is($article->status, 'pending', '... got the right status');
271}
272
273Newswriter::Meta::Instance->_reload_db();
274
275{
276 my $article;
277 lives_ok {
278 $article = Newswriter::Article->new(oid => $article_oid);
279 } '... (re)-created my article successfully';
280 isa_ok($article, 'Newswriter::Article');
281 isa_ok($article, 'Newswriter::Base');
282
283 is($article->oid, $article_oid, '... got a oid for the article');
284 isnt($article_ref, "$article", '... got a new article instance');
285
286 is($article->headline,
287 'Home Office Redecorated',
288 '... got the right headline');
289 is($article->summary,
290 'The home office was recently redecorated to match the new company colors',
291 '... got the right summary');
292 is($article->article, '...', '... got the right article');
293
294 isa_ok($article->start_date, 'DateTime');
295 isa_ok($article->end_date, 'DateTime');
296
297 isa_ok($article->author, 'Newswriter::Author');
298 is($article->author->first_name, 'Truman', '... got the right author first name');
299 is($article->author->last_name, 'Capote', '... got the right author last name');
300
301 lives_ok {
302 $article->author->first_name('Dan');
303 $article->author->last_name('Rather');
304 } '... changed the value ok';
305
306 is($article->author->first_name, 'Dan', '... got the changed author first name');
307 is($article->author->last_name, 'Rather', '... got the changed author last name');
308
309 is($article->status, 'pending', '... got the right status');
310}
311
312Newswriter::Meta::Instance->_reload_db();
313
314{
315 my $article;
316 lives_ok {
317 $article = Newswriter::Article->new(oid => $article_oid);
318 } '... (re)-created my article successfully';
319 isa_ok($article, 'Newswriter::Article');
320 isa_ok($article, 'Newswriter::Base');
321
322 is($article->oid, $article_oid, '... got a oid for the article');
323 isnt($article_ref, "$article", '... got a new article instance');
324
325 is($article->headline,
326 'Home Office Redecorated',
327 '... got the right headline');
328 is($article->summary,
329 'The home office was recently redecorated to match the new company colors',
330 '... got the right summary');
331 is($article->article, '...', '... got the right article');
332
333 isa_ok($article->start_date, 'DateTime');
334 isa_ok($article->end_date, 'DateTime');
335
336 isa_ok($article->author, 'Newswriter::Author');
337 is($article->author->first_name, 'Dan', '... got the changed author first name');
338 is($article->author->last_name, 'Rather', '... got the changed author last name');
339
340 is($article->status, 'pending', '... got the right status');
341}
342
343unlink('newswriter.db') if -e 'newswriter.db';