throw error when doing parameterized join twice on same relation
[dbsrgits/DBIx-Class-ParameterizedJoinHack.git] / t / 00basic.t
1 use strict;
2 use warnings;
3 use lib 't/lib';
4 use Test::More;
5 use Test::Fatal;
6 use My::Schema;
7
8 unless (eval { require DBD::SQLite; 1 }) {
9     plan skip_all => 'Unable to load DBD::SQLite';
10 }
11
12 my $schema = My::Schema->connect('dbi:SQLite:dbname=:memory:');
13
14 $schema->deploy;
15
16 my $people = $schema->resultset('Person');
17
18 my $bob = $people->create({
19     name => 'Bob Testuser',
20 });
21
22 $bob->create_related(assigned_tasks => {
23     summary => 'Task A',
24     urgency => 10,
25 });
26 $bob->create_related(assigned_tasks => {
27     summary => 'Task B',
28     urgency => 20,
29 });
30 $bob->create_related(assigned_tasks => {
31     summary => 'Task C',
32     urgency => 30,
33 });
34
35 subtest 'has_many' => sub {
36
37     my $join_with_min = sub {
38         return shift->with_parameterized_join(
39             urgent_assigned_tasks => { urgency_threshold => $_[0] },
40         );
41     };
42
43     my $join_with_range = sub {
44         return shift->with_parameterized_join(
45             tasks_in_urgency_range => {
46                 min => $_[0],
47                 max => $_[1],
48             },
49         );
50     };
51
52     my $search_count = sub {
53         return scalar shift->search(
54             { 'me.name' => { -like => 'Bob%' } },
55             {
56                 '+select' => [{
57                     count => \[shift],
58                 }],
59                 '+as' => ['task_count'],
60             },
61         );
62     };
63     my $search = sub { $search_count->(shift, 'urgent_assigned_tasks.id') };
64
65     my $fetch_count = sub {
66         return shift->next->get_column('task_count');
67     };
68
69     subtest 'simple filter' => sub {
70         is $people->$join_with_min(19)->$search->$fetch_count,
71             2, 'filter min 19';
72         is $people->$join_with_min(29)->$search->$fetch_count,
73             1, 'filter min 29';
74         is $people->$join_with_min(39)->$search->$fetch_count,
75             0, 'filter min 39';
76     };
77
78     subtest 'multiple filters' => sub {
79         my $rs1 = $people->$join_with_min(19)->$search;
80         my $rs2 = $people->$join_with_min(29)->$search;
81         is $rs1->$fetch_count, 2, 'first';
82         is $rs2->$fetch_count, 1, 'second';
83     };
84
85     subtest 'overrides' => sub {
86         like exception {
87             $people
88                 ->$join_with_min(19)
89                 ->$join_with_min(29)
90                 ->$search
91                 ->$fetch_count;
92         }, qr{once.+per.+relation}i, 'throws error';
93     };
94
95     subtest 'multi parameter' => sub {
96         my $search = sub {
97             $search_count->(shift, 'tasks_in_urgency_range.id');
98         };
99         is $people->$join_with_range(10, 30)->$search->$fetch_count,
100             3, 'full range';
101     };
102
103     subtest 'multi join' => sub {
104         is $people
105             ->$join_with_min(19)
106             ->$join_with_range(10, 30)
107             ->$search
108             ->$fetch_count,
109             2*3, 'full count';
110     };
111
112     subtest 'errors' => sub {
113         like exception {
114             $people->with_parameterized_join(urgent_assigned_tasks => {})
115                 ->$search
116                 ->$fetch_count;
117         }, qr{urgent_assigned_tasks.+urgency_threshold}, 'missing parameter';
118         like exception {
119             $people->with_parameterized_join(__invalid__ => {})
120                 ->$search
121                 ->$fetch_count;
122         }, qr{__invalid__}, 'unknown relation';
123         like exception {
124             $people->with_parameterized_join(undef, {});
125         }, qr{relation.+name}i, 'missing relation name';
126         like exception {
127             $people->with_parameterized_join(foo => []);
128         }, qr{parameters.+hash.+not.+ARRAY}i, 'invalid parameters';
129         like exception {
130             $people->with_parameterized_join(foo => 23);
131         }, qr{parameters.+hash.+not.+non-reference}i, 'non ref parameters';
132     };
133
134     subtest 'declaration errors' => sub {
135         my $errors = \%My::Schema::Result::Person::ERROR;
136         like delete $errors->{no_args}, qr{Missing.+relation.+name}i,
137             'no arguments';
138         like delete $errors->{no_source}, qr{Missing.+foreign.+source}i,
139             'no foreign source';
140         like delete $errors->{no_cond}, qr{Condition.+non-ref.+value}i,
141             'no condition';
142         like delete $errors->{invalid_cond}, qr{Condition.+SCALAR}i,
143             'invalid condition';
144         like delete $errors->{undef_args}, qr{Arguments.+array.+non-ref}i,
145             'undef args';
146         like delete $errors->{invalid_args}, qr{Arguments.+array.+SCALAR}i,
147             'invalid args';
148         like delete $errors->{undef_builder}, qr{builder.+code.+non-ref}i,
149             'undef builder';
150         like delete $errors->{invalid_builder}, qr{builder.+code.+ARRAY}i,
151             'invalid builder';
152         is_deeply $errors, {}, 'no more errors';
153     };
154 };
155
156 done_testing;