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