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