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