Commit | Line | Data |
638c1533 |
1 | use strict; |
2 | use warnings; |
3 | use lib 't/lib'; |
ddc15dd9 |
4 | use Test::More; |
bfd248ed |
5 | use Test::Fatal; |
638c1533 |
6 | use My::Schema; |
7 | |
1eeafdb9 |
8 | unless (eval { require DBD::SQLite; 1 }) { |
9 | plan skip_all => 'Unable to load DBD::SQLite'; |
10 | } |
11 | |
638c1533 |
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 | |
ddc15dd9 |
35 | subtest 'has_many' => sub { |
638c1533 |
36 | |
ddc15dd9 |
37 | my $join_with_min = sub { |
38 | return shift->with_parameterized_join( |
39 | urgent_assigned_tasks => { urgency_threshold => $_[0] }, |
40 | ); |
41 | }; |
638c1533 |
42 | |
bfd248ed |
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 | }; |
ddc15dd9 |
51 | |
bfd248ed |
52 | my $search_count = sub { |
ddc15dd9 |
53 | return scalar shift->search( |
54 | { 'me.name' => { -like => 'Bob%' } }, |
55 | { |
56 | '+select' => [{ |
bfd248ed |
57 | count => \[shift], |
ddc15dd9 |
58 | }], |
59 | '+as' => ['task_count'], |
60 | }, |
61 | ); |
62 | }; |
bfd248ed |
63 | my $search = sub { $search_count->(shift, 'urgent_assigned_tasks.id') }; |
ddc15dd9 |
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 { |
6d37bc62 |
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'; |
ddc15dd9 |
93 | }; |
94 | |
bfd248ed |
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 | |
eb0b3e7b |
112 | subtest 'unconstrained' => sub { |
113 | is $people |
114 | ->with_parameterized_join(unconstrained_tasks => {}) |
115 | ->$search_count('unconstrained_tasks.id') |
116 | ->$fetch_count, |
117 | 3, 'unconstrained count'; |
118 | }; |
119 | |
bfd248ed |
120 | subtest 'errors' => sub { |
121 | like exception { |
122 | $people->with_parameterized_join(urgent_assigned_tasks => {}) |
123 | ->$search |
124 | ->$fetch_count; |
125 | }, qr{urgent_assigned_tasks.+urgency_threshold}, 'missing parameter'; |
126 | like exception { |
127 | $people->with_parameterized_join(__invalid__ => {}) |
128 | ->$search |
129 | ->$fetch_count; |
130 | }, qr{__invalid__}, 'unknown relation'; |
598b28ef |
131 | like exception { |
132 | $people->with_parameterized_join(undef, {}); |
133 | }, qr{relation.+name}i, 'missing relation name'; |
134 | like exception { |
135 | $people->with_parameterized_join(foo => []); |
136 | }, qr{parameters.+hash.+not.+ARRAY}i, 'invalid parameters'; |
137 | like exception { |
138 | $people->with_parameterized_join(foo => 23); |
139 | }, qr{parameters.+hash.+not.+non-reference}i, 'non ref parameters'; |
bfd248ed |
140 | }; |
93b74da6 |
141 | |
142 | subtest 'declaration errors' => sub { |
143 | my $errors = \%My::Schema::Result::Person::ERROR; |
144 | like delete $errors->{no_args}, qr{Missing.+relation.+name}i, |
145 | 'no arguments'; |
146 | like delete $errors->{no_source}, qr{Missing.+foreign.+source}i, |
147 | 'no foreign source'; |
148 | like delete $errors->{no_cond}, qr{Condition.+non-ref.+value}i, |
149 | 'no condition'; |
150 | like delete $errors->{invalid_cond}, qr{Condition.+SCALAR}i, |
151 | 'invalid condition'; |
152 | like delete $errors->{undef_args}, qr{Arguments.+array.+non-ref}i, |
153 | 'undef args'; |
154 | like delete $errors->{invalid_args}, qr{Arguments.+array.+SCALAR}i, |
155 | 'invalid args'; |
156 | like delete $errors->{undef_builder}, qr{builder.+code.+non-ref}i, |
157 | 'undef builder'; |
158 | like delete $errors->{invalid_builder}, qr{builder.+code.+ARRAY}i, |
159 | 'invalid builder'; |
160 | is_deeply $errors, {}, 'no more errors'; |
161 | }; |
ddc15dd9 |
162 | }; |
163 | |
164 | done_testing; |