Massive cleanup of DateTime test dependencies, other interim
[dbsrgits/DBIx-Class.git] / t / cdbi / 18-has_a.t
CommitLineData
9bc6db13 1use strict;
2use Test::More;
3
4BEGIN {
289ba852 5 eval "use DBIx::Class::CDBICompat;";
6 if ($@) {
7 plan (skip_all => 'Class::Trigger and DBIx::ContextualFetch required');
289ba852 8 }
68de9438 9 plan tests => 41;
9bc6db13 10}
11
50891152 12use lib 't/cdbi/testlib';
9bc6db13 13use Film;
14use Director;
15@YA::Film::ISA = 'Film';
16
17Film->create_test_film;
18
19ok my $btaste = Film->retrieve('Bad Taste'), "We have Bad Taste";
20ok my $pj = $btaste->Director, "Bad taste has a director";
21ok !ref($pj), ' ... which is not an object';
22
23ok(Film->has_a('Director' => 'Director'), "Link Director table");
24ok(
6a3bf251 25 Director->create({
26 Name => 'Peter Jackson',
27 Birthday => -300000000,
28 IsInsane => 1
29 }
30 ),
31 'create Director'
9bc6db13 32);
33
34{
6a3bf251 35 ok $btaste = Film->retrieve('Bad Taste'), "Reretrieve Bad Taste";
36 ok $pj = $btaste->Director, "Bad taste now hasa() director";
37 isa_ok $pj => 'Director';
38 {
39 no warnings qw(redefine once);
40 local *Ima::DBI::st::execute =
41 sub { ::fail("Shouldn't need to query db"); };
42 is $pj->id, 'Peter Jackson', 'ID already stored';
43 }
44 ok $pj->IsInsane, "But we know he's insane";
9bc6db13 45}
46
47# Oh no! Its Peter Jacksons even twin, Skippy! Born one minute after him.
48my $sj = Director->create({
6a3bf251 49 Name => 'Skippy Jackson',
50 Birthday => (-300000000 + 60),
51 IsInsane => 1,
52 });
9bc6db13 53
54{
6a3bf251 55 eval { $btaste->Director($btaste) };
56 like $@, qr/Director/, "Can't set film as director";
57 is $btaste->Director->id, $pj->id, "PJ still the director";
9bc6db13 58
6a3bf251 59 # drop from cache so that next retrieve() is from db
60 $btaste->remove_from_object_index;
9bc6db13 61}
62
63{ # Still inflated after update
6a3bf251 64 my $btaste = Film->retrieve('Bad Taste');
65 isa_ok $btaste->Director, "Director";
66 $btaste->numexplodingsheep(17);
67 $btaste->update;
68 isa_ok $btaste->Director, "Director";
69
70 $btaste->Director('Someone Else');
71 $btaste->update;
72 isa_ok $btaste->Director, "Director";
73 is $btaste->Director->id, "Someone Else", "Can change director";
9bc6db13 74}
75
76is $sj->id, 'Skippy Jackson', 'Create new director - Skippy';
77Film->has_a('CoDirector' => 'Director');
78{
6a3bf251 79 eval { $btaste->CoDirector("Skippy Jackson") };
80 is $@, "", "Auto inflates";
81 isa_ok $btaste->CoDirector, "Director";
82 is $btaste->CoDirector->id, $sj->id, "To skippy";
9bc6db13 83}
84
85$btaste->CoDirector($sj);
86$btaste->update;
87is($btaste->CoDirector->Name, 'Skippy Jackson', 'He co-directed');
88is(
6a3bf251 89 $btaste->Director->Name,
90 'Peter Jackson',
91 "Didnt interfere with each other"
9bc6db13 92);
93
94{ # Inheriting hasa
6a3bf251 95 my $btaste = YA::Film->retrieve('Bad Taste');
96 is(ref($btaste->Director), 'Director', 'inheriting hasa()');
97 is(ref($btaste->CoDirector), 'Director', 'inheriting hasa()');
98 is($btaste->CoDirector->Name, 'Skippy Jackson', ' ... correctly');
9bc6db13 99}
100
101{
6a3bf251 102 $sj = Director->retrieve('Skippy Jackson');
103 $pj = Director->retrieve('Peter Jackson');
104
105 my $fail;
106 eval {
107 $fail = YA::Film->create({
108 Title => 'Tastes Bad',
109 Director => $sj,
110 codirector => $btaste,
111 Rating => 'R',
112 NumExplodingSheep => 23
113 });
114 };
115 ok $@, "Can't have film as codirector: $@";
116 is $fail, undef, "We didn't get anything";
117
118 my $tastes_bad = YA::Film->create({
119 Title => 'Tastes Bad',
120 Director => $sj,
121 codirector => $pj,
122 Rating => 'R',
123 NumExplodingSheep => 23
124 });
125 is($tastes_bad->Director->Name, 'Skippy Jackson', 'Director');
126 is(
127 $tastes_bad->_director_accessor->Name,
128 'Skippy Jackson',
129 'director_accessor'
130 );
131 is($tastes_bad->codirector->Name, 'Peter Jackson', 'codirector');
132 is(
133 $tastes_bad->_codirector_accessor->Name,
134 'Peter Jackson',
135 'codirector_accessor'
136 );
9bc6db13 137}
138
139SKIP: {
140 skip "Non-standard CDBI relationships not supported by compat", 9;
6a3bf251 141 {
142
143 YA::Film->add_relationship_type(has_a => "YA::HasA");
144
145 package YA::HasA;
146 #use base 'Class::DBI::Relationship::HasA';
147
148 sub _inflator {
149 my $self = shift;
150 my $col = $self->accessor;
151 my $super = $self->SUPER::_inflator($col);
152
153 return $super
154 unless $col eq $self->class->find_column('Director');
155
156 return sub {
157 my $self = shift;
158 $self->_attribute_store($col, 'Ghostly Peter')
159 if $self->_attribute_exists($col)
160 and not defined $self->_attrs($col);
161 return &$super($self);
162 };
163 }
164 }
165 {
166
167 package Rating;
168
169 sub new {
170 my ($class, $mpaa, @details) = @_;
171 bless {
172 MPAA => $mpaa,
173 WHY => "@details"
174 }, $class;
175 }
176 sub mpaa { shift->{MPAA}; }
177 sub why { shift->{WHY}; }
178 }
179 local *Director::mapme = sub {
180 my ($class, $val) = @_;
181 $val =~ s/Skippy/Peter/;
182 $val;
183 };
184 no warnings 'once';
185 local *Director::sanity_check = sub { $_[0]->IsInsane ? undef: $_[0] };
186 YA::Film->has_a(
187 director => 'Director',
188 inflate => 'mapme',
189 deflate => 'sanity_check'
190 );
191 YA::Film->has_a(
192 rating => 'Rating',
193 inflate => sub {
194 my ($val, $parent) = @_;
195 my $sheep = $parent->find_column('NumexplodingSheep');
196 if ($parent->_attrs($sheep) || 0 > 20) {
197 return new Rating 'NC17', 'Graphic ovine violence';
198 } else {
199 return new Rating $val, 'Just because';
200 }
201 },
202 deflate => sub {
203 shift->mpaa;
204 });
205
206 my $tbad = YA::Film->retrieve('Tastes Bad');
207
208 isa_ok $tbad->Director, 'Director';
209 is $tbad->Director->Name, 'Peter Jackson', 'Director shuffle';
210 $tbad->Director('Skippy Jackson');
211 $tbad->update;
212 is $tbad->Director, 'Ghostly Peter', 'Sanity checked';
213
214 isa_ok $tbad->Rating, 'Rating';
215 is $tbad->Rating->mpaa, 'NC17', 'Rating bumped';
216 $tbad->Rating(new Rating 'NS17', 'Shaken sheep');
217 no warnings 'redefine';
218 local *Director::mapme = sub {
219 my ($class, $obj) = @_;
220 $obj->isa('Film') ? $obj->Director : $obj;
221 };
222
223 $pj->IsInsane(0);
224 $pj->update; # Hush warnings
225
226 ok $tbad->Director($btaste), 'Cross-class mapping';
227 is $tbad->Director, 'Peter Jackson', 'Yields PJ';
228 $tbad->update;
229
230 $tbad = Film->retrieve('Tastes Bad');
231 ok !ref($tbad->Rating), 'Unmagical rating';
232 is $tbad->Rating, 'NS17', 'but prior change stuck';
9bc6db13 233}
234
235{ # Broken has_a declaration
6a3bf251 236 eval { Film->has_a(driector => "Director") };
237 like $@, qr/driector/, "Sensible error from has_a with incorrect column: $@";
9bc6db13 238}