i am stupid
[gitmo/Moose.git] / t / 202_example_Moose_POOP.t
CommitLineData
fcec2383 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
047248f9 6use Test::More;
7
8BEGIN {
a60285b3 9 eval "use DBM::Deep 0.983;";
10 plan skip_all => "DBM::Deep is required for this test" if $@;
11 plan skip_all => "DBM::Deep (>= 1.0) is required for this test"
12 if DBM::Deep->VERSION >= 1.0;
13 eval "use DateTime::Format::MySQL;";
14 plan skip_all => "DateTime::Format::MySQL is required for this test" if $@;
b68e5362 15 plan tests => 89;
047248f9 16}
17
fcec2383 18use Test::Exception;
19
20BEGIN {
21 use_ok('Moose');
22}
23
b68e5362 24=pod
25
26This example creates a very basic Object Database which
27links in the instances created with a backend store
28(a DBM::Deep hash). It is by no means to be taken seriously
29as a real-world ODB (see Presto for that), but is a proof
30of concept of the flexibility of the ::Instance protocol.
31
32=cut
33
fcec2383 34BEGIN {
35
8479d544 36 package Moose::POOP::Meta::Instance;
fcec2383 37 use Moose;
38
39 use DBM::Deep;
40
41 extends 'Moose::Meta::Instance';
42
43 {
b68e5362 44 my %INSTANCE_COUNTERS;
fcec2383 45
46 my $db = DBM::Deep->new({
047248f9 47 file => "newswriter.db",
48 autobless => 1,
49 locking => 1,
fcec2383 50 });
fcec2383 51
fcec2383 52 sub _reload_db {
b68e5362 53 #use Data::Dumper;
54 #warn Dumper $db;
047248f9 55 $db = undef;
fcec2383 56 $db = DBM::Deep->new({
047248f9 57 file => "newswriter.db",
58 autobless => 1,
59 locking => 1,
60 });
fcec2383 61 }
62
63 sub create_instance {
b68e5362 64 my $self = shift;
5cf3dbcf 65 my $class = $self->associated_metaclass->name;
b68e5362 66 my $oid = ++$INSTANCE_COUNTERS{$class};
67
68 $db->{$class}->[($oid - 1)] = {};
fcec2383 69
70 $self->bless_instance_structure({
b68e5362 71 oid => $oid,
72 instance => $db->{$class}->[($oid - 1)]
fcec2383 73 });
74 }
75
76 sub find_instance {
77 my ($self, $oid) = @_;
5cf3dbcf 78 my $instance = $db->{$self->associated_metaclass->name}->[($oid - 1)];
b68e5362 79 $self->bless_instance_structure({
80 oid => $oid,
81 instance => $instance
82 });
83 }
84
85 sub clone_instance {
86 my ($self, $instance) = @_;
87
88 my $class = $self->{meta}->name;
89 my $oid = ++$INSTANCE_COUNTERS{$class};
90
91 my $clone = tied($instance)->clone;
fcec2383 92
93 $self->bless_instance_structure({
94 oid => $oid,
b68e5362 95 instance => $clone
96 });
97 }
fcec2383 98 }
99
100 sub get_instance_oid {
101 my ($self, $instance) = @_;
102 $instance->{oid};
103 }
104
fcec2383 105 sub get_slot_value {
106 my ($self, $instance, $slot_name) = @_;
107 return $instance->{instance}->{$slot_name};
108 }
109
110 sub set_slot_value {
111 my ($self, $instance, $slot_name, $value) = @_;
112 $instance->{instance}->{$slot_name} = $value;
113 }
114
115 sub is_slot_initialized {
116 my ($self, $instance, $slot_name, $value) = @_;
117 exists $instance->{instance}->{$slot_name} ? 1 : 0;
118 }
119
120 sub weaken_slot_value {
e67a0fca 121 confess "Not sure how well DBM::Deep plays with weak refs, Rob says 'Write a test'";
fcec2383 122 }
123
124 sub inline_slot_access {
125 my ($self, $instance, $slot_name) = @_;
126 sprintf "%s->{instance}->{%s}", $instance, $slot_name;
127 }
128
8479d544 129 package Moose::POOP::Meta::Class;
8ecb1fa0 130 use Moose;
fcec2383 131
132 extends 'Moose::Meta::Class';
133
134 override 'construct_instance' => sub {
135 my ($class, %params) = @_;
136 return $class->get_meta_instance->find_instance($params{oid})
137 if $params{oid};
138 super();
139 };
fcec2383 140
8479d544 141}
fcec2383 142{
8479d544 143 package Moose::POOP::Object;
8479d544 144 use metaclass 'Moose::POOP::Meta::Class' => (
5cf3dbcf 145 instance_metaclass => 'Moose::POOP::Meta::Instance'
fcec2383 146 );
147 use Moose;
148
149 sub oid {
150 my $self = shift;
151 $self->meta
152 ->get_meta_instance
153 ->get_instance_oid($self);
154 }
8479d544 155
156}
157{
fcec2383 158 package Newswriter::Author;
fcec2383 159 use Moose;
160
8479d544 161 extends 'Moose::POOP::Object';
fcec2383 162
163 has 'first_name' => (is => 'rw', isa => 'Str');
164 has 'last_name' => (is => 'rw', isa => 'Str');
165
166 package Newswriter::Article;
fcec2383 167 use Moose;
168 use Moose::Util::TypeConstraints;
169
170 use DateTime::Format::MySQL;
171
8479d544 172 extends 'Moose::POOP::Object';
fcec2383 173
174 subtype 'Headline'
175 => as 'Str'
176 => where { length($_) < 100 };
177
178 subtype 'Summary'
179 => as 'Str'
180 => where { length($_) < 255 };
181
182 subtype 'DateTimeFormatString'
183 => as 'Str'
184 => where { DateTime::Format::MySQL->parse_datetime($_) };
185
186 enum 'Status' => qw(draft posted pending archive);
187
188 has 'headline' => (is => 'rw', isa => 'Headline');
189 has 'summary' => (is => 'rw', isa => 'Summary');
190 has 'article' => (is => 'rw', isa => 'Str');
191
192 has 'start_date' => (is => 'rw', isa => 'DateTimeFormatString');
193 has 'end_date' => (is => 'rw', isa => 'DateTimeFormatString');
194
195 has 'author' => (is => 'rw', isa => 'Newswriter::Author');
196
197 has 'status' => (is => 'rw', isa => 'Status');
198
199 around 'start_date', 'end_date' => sub {
200 my $c = shift;
201 my $self = shift;
202 $c->($self, DateTime::Format::MySQL->format_datetime($_[0])) if @_;
b68e5362 203 DateTime::Format::MySQL->parse_datetime($c->($self) || return undef);
fcec2383 204 };
205}
206
207{ # check the meta stuff first
8479d544 208 isa_ok(Moose::POOP::Object->meta, 'Moose::POOP::Meta::Class');
209 isa_ok(Moose::POOP::Object->meta, 'Moose::Meta::Class');
210 isa_ok(Moose::POOP::Object->meta, 'Class::MOP::Class');
fcec2383 211
8479d544 212 is(Moose::POOP::Object->meta->instance_metaclass,
213 'Moose::POOP::Meta::Instance',
fcec2383 214 '... got the right instance metaclass name');
215
8479d544 216 isa_ok(Moose::POOP::Object->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
fcec2383 217
8479d544 218 my $base = Moose::POOP::Object->new;
219 isa_ok($base, 'Moose::POOP::Object');
fcec2383 220 isa_ok($base, 'Moose::Object');
221
8479d544 222 isa_ok($base->meta, 'Moose::POOP::Meta::Class');
fcec2383 223 isa_ok($base->meta, 'Moose::Meta::Class');
224 isa_ok($base->meta, 'Class::MOP::Class');
225
226 is($base->meta->instance_metaclass,
8479d544 227 'Moose::POOP::Meta::Instance',
fcec2383 228 '... got the right instance metaclass name');
229
8479d544 230 isa_ok($base->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
fcec2383 231}
232
233my $article_oid;
234my $article_ref;
235{
236 my $article;
237 lives_ok {
238 $article = Newswriter::Article->new(
239 headline => 'Home Office Redecorated',
240 summary => 'The home office was recently redecorated to match the new company colors',
241 article => '...',
242
243 author => Newswriter::Author->new(
244 first_name => 'Truman',
245 last_name => 'Capote'
246 ),
247
248 status => 'pending'
249 );
250 } '... created my article successfully';
251 isa_ok($article, 'Newswriter::Article');
8479d544 252 isa_ok($article, 'Moose::POOP::Object');
fcec2383 253
254 lives_ok {
255 $article->start_date(DateTime->new(year => 2006, month => 6, day => 10));
256 $article->end_date(DateTime->new(year => 2006, month => 6, day => 17));
257 } '... add the article date-time stuff';
258
259 ## check some meta stuff
260
8479d544 261 isa_ok($article->meta, 'Moose::POOP::Meta::Class');
fcec2383 262 isa_ok($article->meta, 'Moose::Meta::Class');
263 isa_ok($article->meta, 'Class::MOP::Class');
264
265 is($article->meta->instance_metaclass,
8479d544 266 'Moose::POOP::Meta::Instance',
fcec2383 267 '... got the right instance metaclass name');
268
8479d544 269 isa_ok($article->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
fcec2383 270
271 ok($article->oid, '... got a oid for the article');
272
273 $article_oid = $article->oid;
274 $article_ref = "$article";
275
276 is($article->headline,
277 'Home Office Redecorated',
278 '... got the right headline');
279 is($article->summary,
280 'The home office was recently redecorated to match the new company colors',
281 '... got the right summary');
282 is($article->article, '...', '... got the right article');
283
284 isa_ok($article->start_date, 'DateTime');
285 isa_ok($article->end_date, 'DateTime');
286
287 isa_ok($article->author, 'Newswriter::Author');
288 is($article->author->first_name, 'Truman', '... got the right author first name');
289 is($article->author->last_name, 'Capote', '... got the right author last name');
290
291 is($article->status, 'pending', '... got the right status');
292}
293
8479d544 294Moose::POOP::Meta::Instance->_reload_db();
fcec2383 295
b68e5362 296my $article2_oid;
297my $article2_ref;
fcec2383 298{
b68e5362 299 my $article2;
300 lives_ok {
301 $article2 = Newswriter::Article->new(
302 headline => 'Company wins Lottery',
303 summary => 'An email was received today that informed the company we have won the lottery',
304 article => 'WoW',
305
306 author => Newswriter::Author->new(
307 first_name => 'Katie',
308 last_name => 'Couric'
309 ),
310
311 status => 'posted'
312 );
313 } '... created my article successfully';
314 isa_ok($article2, 'Newswriter::Article');
8479d544 315 isa_ok($article2, 'Moose::POOP::Object');
b68e5362 316
317 $article2_oid = $article2->oid;
318 $article2_ref = "$article2";
319
320 is($article2->headline,
321 'Company wins Lottery',
322 '... got the right headline');
323 is($article2->summary,
324 'An email was received today that informed the company we have won the lottery',
325 '... got the right summary');
326 is($article2->article, 'WoW', '... got the right article');
327
328 ok(!$article2->start_date, '... these two dates are unassigned');
329 ok(!$article2->end_date, '... these two dates are unassigned');
330
331 isa_ok($article2->author, 'Newswriter::Author');
332 is($article2->author->first_name, 'Katie', '... got the right author first name');
333 is($article2->author->last_name, 'Couric', '... got the right author last name');
334
335 is($article2->status, 'posted', '... got the right status');
336
337 ## orig-article
338
fcec2383 339 my $article;
340 lives_ok {
341 $article = Newswriter::Article->new(oid => $article_oid);
342 } '... (re)-created my article successfully';
343 isa_ok($article, 'Newswriter::Article');
8479d544 344 isa_ok($article, 'Moose::POOP::Object');
fcec2383 345
346 is($article->oid, $article_oid, '... got a oid for the article');
347 isnt($article_ref, "$article", '... got a new article instance');
348
349 is($article->headline,
350 'Home Office Redecorated',
351 '... got the right headline');
352 is($article->summary,
353 'The home office was recently redecorated to match the new company colors',
354 '... got the right summary');
355 is($article->article, '...', '... got the right article');
356
357 isa_ok($article->start_date, 'DateTime');
358 isa_ok($article->end_date, 'DateTime');
359
360 isa_ok($article->author, 'Newswriter::Author');
361 is($article->author->first_name, 'Truman', '... got the right author first name');
362 is($article->author->last_name, 'Capote', '... got the right author last name');
363
364 lives_ok {
365 $article->author->first_name('Dan');
366 $article->author->last_name('Rather');
367 } '... changed the value ok';
368
369 is($article->author->first_name, 'Dan', '... got the changed author first name');
370 is($article->author->last_name, 'Rather', '... got the changed author last name');
371
372 is($article->status, 'pending', '... got the right status');
373}
374
8479d544 375Moose::POOP::Meta::Instance->_reload_db();
fcec2383 376
377{
378 my $article;
379 lives_ok {
380 $article = Newswriter::Article->new(oid => $article_oid);
381 } '... (re)-created my article successfully';
382 isa_ok($article, 'Newswriter::Article');
8479d544 383 isa_ok($article, 'Moose::POOP::Object');
fcec2383 384
385 is($article->oid, $article_oid, '... got a oid for the article');
386 isnt($article_ref, "$article", '... got a new article instance');
387
388 is($article->headline,
389 'Home Office Redecorated',
390 '... got the right headline');
391 is($article->summary,
392 'The home office was recently redecorated to match the new company colors',
393 '... got the right summary');
394 is($article->article, '...', '... got the right article');
395
396 isa_ok($article->start_date, 'DateTime');
397 isa_ok($article->end_date, 'DateTime');
398
399 isa_ok($article->author, 'Newswriter::Author');
400 is($article->author->first_name, 'Dan', '... got the changed author first name');
401 is($article->author->last_name, 'Rather', '... got the changed author last name');
402
403 is($article->status, 'pending', '... got the right status');
b68e5362 404
405 my $article2;
406 lives_ok {
407 $article2 = Newswriter::Article->new(oid => $article2_oid);
408 } '... (re)-created my article successfully';
409 isa_ok($article2, 'Newswriter::Article');
8479d544 410 isa_ok($article2, 'Moose::POOP::Object');
b68e5362 411
412 is($article2->oid, $article2_oid, '... got a oid for the article');
413 isnt($article2_ref, "$article2", '... got a new article instance');
414
415 is($article2->headline,
416 'Company wins Lottery',
417 '... got the right headline');
418 is($article2->summary,
419 'An email was received today that informed the company we have won the lottery',
420 '... got the right summary');
421 is($article2->article, 'WoW', '... got the right article');
422
423 ok(!$article2->start_date, '... these two dates are unassigned');
424 ok(!$article2->end_date, '... these two dates are unassigned');
425
426 isa_ok($article2->author, 'Newswriter::Author');
427 is($article2->author->first_name, 'Katie', '... got the right author first name');
428 is($article2->author->last_name, 'Couric', '... got the right author last name');
429
430 is($article2->status, 'posted', '... got the right status');
431
fcec2383 432}
433
434unlink('newswriter.db') if -e 'newswriter.db';