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