1use strict; 2use Test::More; 3 4BEGIN { 5 eval "use DBD::SQLite"; 6 plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 42); 7} 8 9use lib 't/testlib'; 10use Film; 11use Actor; 12use Director; 13 14Film->has_many(actors => Actor => 'Film', { order_by => 'name' }); 15Director->has_many(films => Film => 'Director', { order_by => 'title' }); 16Director->has_many( 17 r_rated_films => 18 Film => 'Director', 19 { order_by => 'title', constraint => { Rating => 'R' } } 20); 21 22Actor->has_a(Film => 'Film'); 23is(Actor->primary_column, 'id', "Actor primary OK"); 24 25ok(Actor->can('Salary'), "Actor table set-up OK"); 26ok(Film->can('actors'), " and have a suitable method in Film"); 27 28Film->create_test_film; 29ok(my $btaste = Film->retrieve('Bad Taste'), "We have Bad Taste"); 30 31ok( 32 my $pvj = Actor->insert( 33 { 34 Name => 'Peter Vere-Jones', 35 Film => undef, 36 Salary => '30_000', # For a voice! 37 } 38 ), 39 'insert Actor' 40); 41is $pvj->Name, "Peter Vere-Jones", "PVJ name ok"; 42is $pvj->Film, undef, "No film"; 43ok $pvj->set_Film($btaste), "Set film"; 44$pvj->update; 45is $pvj->Film->id, $btaste->id, "Now film"; 46{ 47 my @actors = $btaste->actors; 48 is(@actors, 1, "Bad taste has one actor"); 49 is($actors[0]->Name, $pvj->Name, " - the correct one"); 50} 51 52my %pj_data = ( 53 Name => 'Peter Jackson', 54 Salary => '0', # it's a labour of love 55); 56 57eval { my $pj = Film->add_to_actors(\%pj_data) }; 58like $@, qr/class/, "add_to_actors must be object method"; 59 60eval { my $pj = $btaste->add_to_actors(%pj_data) }; 61like $@, qr/needs/, "add_to_actors takes hash"; 62 63ok( 64 my $pj = $btaste->add_to_actors( 65 { 66 Name => 'Peter Jackson', 67 Salary => '0', # it's a labour of love 68 } 69 ), 70 'add_to_actors' 71); 72is $pj->Name, "Peter Jackson", "PJ ok"; 73is $pvj->Name, "Peter Vere-Jones", "PVJ still ok"; 74 75{ 76 my @actors = $btaste->actors; 77 is @actors, 2, " - so now we have 2"; 78 is $actors[0]->Name, $pj->Name, "PJ first"; 79 is $actors[1]->Name, $pvj->Name, "PVJ first"; 80} 81 82eval { 83 my @actors = $btaste->actors({Name => $pj->Name}); 84 is @actors, 1, "One actor from restricted (sorted) has_many"; 85 is $actors[0]->Name, $pj->Name, "It's PJ"; 86}; 87is $@, '', "No errors"; 88 89my $as = Actor->insert( 90 { 91 Name => 'Arnold Schwarzenegger', 92 Film => 'Terminator 2', 93 Salary => '15_000_000' 94 } 95); 96 97eval { $btaste->actors($pj, $pvj, $as) }; 98ok $@, $@; 99is($btaste->actors, 2, " - so we still only have 2 actors"); 100 101my @bta_before = Actor->search(Film => 'Bad Taste'); 102is(@bta_before, 2, "We have 2 actors in bad taste"); 103ok($btaste->delete, "Delete bad taste"); 104my @bta_after = Actor->search(Film => 'Bad Taste'); 105is(@bta_after, 0, " - after deleting there are no actors"); 106 107# While we're here, make sure Actors have unreadable mutators and 108# unwritable accessors 109 110eval { $as->Name("Paul Reubens") }; 111ok $@, $@; 112eval { my $name = $as->set_Name }; 113ok $@, $@; 114 115is($as->Name, 'Arnold Schwarzenegger', "Arnie's still Arnie"); 116 117ok(my $director = Director->insert({ Name => 'Director 1', }), 118 'insert Director'); 119 120ok( 121 $director->add_to_films( 122 { 123 Title => 'Film 1', 124 Director => 'Director 1', 125 Rating => 'PG', 126 } 127 ), 128 'add_to_films' 129); 130 131ok( 132 $director->add_to_r_rated_films( 133 { 134 Title => 'Film 2', 135 Director => 'Director 1', 136 } 137 ), 138 'add_to_r_rated_films' 139); 140 141eval { 142 $director->add_to_r_rated_films( 143 { 144 Title => 'Film 3', 145 Director => 'Director 1', 146 Rating => 'G', 147 } 148 ); 149}; 150ok $@, $@; 151 152{ 153 my @films = $director->films; 154 is(@films, 2, "Director 1 has three films"); 155 is $films[0]->Title, "Film 1", "Film 1"; 156 is $films[0]->Rating, "PG", "is PG"; 157 is $films[1]->Title, "Film 2", "Film 2"; 158 is $films[1]->Rating, "R", "is R"; 159} 160 161{ 162 my @films = $director->r_rated_films; 163 is @films, 1, "... but only 1 R-Rated"; 164 is $films[0]->Title, "Film 2", "- Film 2"; 165} 166 167# Subclass can override has_many 168 169package Film::Subclass; 170 171use base 'Film'; 172 173eval { 174 Film::Subclass->has_many(actors => Actor => 'Film', { order_by => 'id' }); 175}; 176 177package main; 178 179ok ! $@, "We can set up a has_many subclass"; 180 181 182 183