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