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