Somewhat fix bloody messy test
[dbsrgits/DBIx-Class.git] / t / 87ordered.t
1 # vim: filetype=perl
2 use strict;
3 use warnings;  
4
5 use Test::More;
6 use lib qw(t/lib);
7 use DBICTest;
8
9 use POSIX qw(ceil);
10
11 my $schema = DBICTest->init_schema();
12
13 plan tests => 1269;
14
15 my $employees = $schema->resultset('Employee');
16 $employees->delete();
17
18 foreach (1..5) {
19     $employees->create({ name=>'temp' });
20 }
21 $employees = $employees->search(undef,{order_by=>'position'});
22 ok( check_rs($employees), "intial positions" );
23
24 hammer_rs( $employees );
25
26 DBICTest::Employee->grouping_column('group_id');
27 $employees->delete();
28 foreach my $group_id (1..4) {
29     foreach (1..6) {
30         $employees->create({ name=>'temp', group_id=>$group_id });
31     }
32 }
33 $employees = $employees->search(undef,{order_by=>'group_id,position'});
34
35 foreach my $group_id (1..4) {
36     my $group_employees = $employees->search({group_id=>$group_id});
37     $group_employees->all();
38     ok( check_rs($group_employees), "group intial positions" );
39     hammer_rs( $group_employees );
40 }
41
42 my $group_3 = $employees->search({group_id=>3});
43 my $to_group = 1;
44 my $to_pos = undef;
45 while (my $employee = $group_3->next) {
46         $employee->discard_changes;     # since we are effective shift()ing the $rs
47         $employee->move_to_group($to_group, $to_pos);
48         $to_pos++;
49         $to_group = $to_group==1 ? 2 : 1;
50 }
51 foreach my $group_id (1..4) {
52     my $group_employees = $employees->search({group_id=>$group_id});
53     $group_employees->all();
54     ok( check_rs($group_employees), "group positions after move_to_group" );
55 }
56
57 my $employee = $employees->search({group_id=>4})->first;
58 $employee->position(2);
59 $employee->update;
60 ok( check_rs($employees->search_rs({group_id=>4})), "overloaded update 1" );
61 $employee = $employees->search({group_id=>4})->first;
62 $employee->update({position=>3});
63 ok( check_rs($employees->search_rs({group_id=>4})), "overloaded update 2" );
64 $employee = $employees->search({group_id=>4})->first;
65 $employee->group_id(1);
66 $employee->update;
67 ok(
68         check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
69         "overloaded update 3"
70 );
71 $employee = $employees->search({group_id=>4})->first;
72 $employee->update({group_id=>2});
73 ok(
74         check_rs($employees->search_rs({group_id=>2})) && check_rs($employees->search_rs({group_id=>4})),
75         "overloaded update 4"
76 );
77 $employee = $employees->search({group_id=>4})->first;
78 $employee->group_id(1);
79 $employee->position(3);
80 $employee->update;
81 ok(
82         check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
83         "overloaded update 5"
84 );
85 $employee = $employees->search({group_id=>4})->first;
86 $employee->group_id(2);
87 $employee->position(undef);
88 $employee->update;
89 ok(
90         check_rs($employees->search_rs({group_id=>2})) && check_rs($employees->search_rs({group_id=>4})),
91         "overloaded update 6"
92 );
93 $employee = $employees->search({group_id=>4})->first;
94 $employee->update({group_id=>1,position=>undef});
95 ok(
96         check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
97         "overloaded update 7"
98 );
99
100 # multicol tests begin here
101 DBICTest::Employee->grouping_column(['group_id_2', 'group_id_3']);
102 $employees->delete();
103 foreach my $group_id_2 (1..4) {
104     foreach my $group_id_3 (1..4) {
105         foreach (1..4) {
106             $employees->create({ name=>'temp', group_id_2=>$group_id_2, group_id_3=>$group_id_3 });
107         }
108     }
109 }
110 $employees = $employees->search(undef,{order_by=>[qw/group_id_2 group_id_3 position/]});
111
112 foreach my $group_id_2 (1..3) {
113     foreach my $group_id_3 (1..3) {
114         my $group_employees = $employees->search({group_id_2=>$group_id_2, group_id_3=>$group_id_3});
115         $group_employees->all();
116         ok( check_rs($group_employees), "group intial positions" );
117         hammer_rs( $group_employees );
118     }
119 }
120
121 # move_to_group, specifying group by hash
122 my $group_4 = $employees->search({group_id_2=>4});
123 $to_group = 1;
124 my $to_group_2_base = 7;
125 my $to_group_2 = 1;
126 $to_pos = undef;
127 while (my $employee = $group_4->next) {
128         $employee->move_to_group({group_id_2=>$to_group, group_id_3=>$to_group_2}, $to_pos);
129         $to_pos++;
130     $to_group = ($to_group % 3) + 1;
131     $to_group_2_base++;
132     $to_group_2 = (ceil($to_group_2_base/3.0) %3) +1
133 }
134 foreach my $group_id_2 (1..4) {
135     foreach my $group_id_3 (1..4) {
136         my $group_employees = $employees->search({group_id_2=>$group_id_2,group_id_3=>$group_id_3});
137         $group_employees->all();
138         ok( check_rs($group_employees), "group positions after move_to_group" );
139     }
140 }
141
142 $employees->delete();
143 foreach my $group_id_2 (1..4) {
144     foreach my $group_id_3 (1..4) {
145         foreach (1..4) {
146             $employees->create({ name=>'temp', group_id_2=>$group_id_2, group_id_3=>$group_id_3 });
147         }
148     }
149 }
150 $employees = $employees->search(undef,{order_by=>[qw/group_id_2 group_id_3 position/]});
151
152 $employee = $employees->search({group_id_2=>4, group_id_3=>1})->first;
153 $employee->group_id_2(1);
154 $employee->update;
155 ok( 
156     check_rs($employees->search_rs({group_id_2=>4, group_id_3=>1}))
157     && check_rs($employees->search_rs({group_id_2=>1, group_id_3=>1})), 
158     "overloaded multicol update 1" 
159 );
160
161 $employee = $employees->search({group_id_2=>4, group_id_3=>1})->first;
162 $employee->update({group_id_2=>2});
163 ok( check_rs($employees->search_rs({group_id_2=>4, group_id_3=>1}))
164     && check_rs($employees->search_rs({group_id_2=>2, group_id_3=>1})), 
165    "overloaded multicol update 2" 
166 );
167
168 $employee = $employees->search({group_id_2=>3, group_id_3=>1})->first;
169 $employee->group_id_2(1);
170 $employee->group_id_3(3);
171 $employee->update();
172 ok( check_rs($employees->search_rs({group_id_2=>3, group_id_3=>1}))
173     && check_rs($employees->search_rs({group_id_2=>1, group_id_3=>3})),
174     "overloaded multicol update 3" 
175 );
176
177 $employee = $employees->search({group_id_2=>3, group_id_3=>1})->first;
178 $employee->update({group_id_2=>2, group_id_3=>3});
179 ok( check_rs($employees->search_rs({group_id_2=>3, group_id_3=>1}))
180     && check_rs($employees->search_rs({group_id_2=>2, group_id_3=>3})), 
181     "overloaded multicol update 4" 
182 );
183
184 $employee = $employees->search({group_id_2=>3, group_id_3=>2})->first;
185 $employee->update({group_id_2=>2, group_id_3=>4, position=>2});
186 ok( check_rs($employees->search_rs({group_id_2=>3, group_id_3=>2}))
187     && check_rs($employees->search_rs({group_id_2=>2, group_id_3=>4})), 
188     "overloaded multicol update 5" 
189 );
190
191 sub hammer_rs {
192     my $rs = shift;
193     my $employee;
194     my $count = $rs->count();
195     my $position_column = $rs->result_class->position_column();
196     my $row;
197
198     foreach my $position (1..$count) {
199
200         ($row) = $rs->search({ $position_column=>$position })->all();
201         $row->move_previous();
202         ok( check_rs($rs), "move_previous( $position )" );
203
204         ($row) = $rs->search({ $position_column=>$position })->all();
205         $row->move_next();
206         ok( check_rs($rs), "move_next( $position )" );
207
208         ($row) = $rs->search({ $position_column=>$position })->all();
209         $row->move_first();
210         ok( check_rs($rs), "move_first( $position )" );
211
212         ($row) = $rs->search({ $position_column=>$position })->all();
213         $row->move_last();
214         ok( check_rs($rs), "move_last( $position )" );
215
216         foreach my $to_position (1..$count) {
217             ($row) = $rs->search({ $position_column=>$position })->all();
218             $row->move_to($to_position);
219             ok( check_rs($rs), "move_to( $position => $to_position )" );
220         }
221
222         $row = $rs->find({ position => $position });
223         if ($position==1) {
224             ok( !$row->previous_sibling(), 'no previous sibling' );
225             ok( !$row->first_sibling(), 'no first sibling' );
226             ok( $row->next_sibling->position > $position, 'next sibling position > than us');
227             is( $row->next_sibling->previous_sibling->position, $position, 'next-prev sibling is us');
228             ok( $row->last_sibling->position > $position, 'last sibling position > than us');
229         }
230         else {
231             ok( $row->previous_sibling(), 'previous sibling' );
232             ok( $row->first_sibling(), 'first sibling' );
233             ok( $row->previous_sibling->position < $position, 'prev sibling position < than us');
234             is( $row->previous_sibling->next_sibling->position, $position, 'prev-next sibling is us');
235             ok( $row->first_sibling->position < $position, 'first sibling position < than us');
236         }
237         if ($position==$count) {
238             ok( !$row->next_sibling(), 'no next sibling' );
239             ok( !$row->last_sibling(), 'no last sibling' );
240             ok( $row->previous_sibling->position < $position, 'prev sibling position < than us');
241             is( $row->previous_sibling->next_sibling->position, $position, 'prev-next sibling is us');
242             ok( $row->first_sibling->position < $position, 'first sibling position < than us');
243         }
244         else {
245             ok( $row->next_sibling(), 'next sibling' );
246             ok( $row->last_sibling(), 'last sibling' );
247             ok( $row->next_sibling->position > $row->position, 'next sibling position > than us');
248             is( $row->next_sibling->previous_sibling->position, $position, 'next-prev sibling is us');
249             ok( $row->last_sibling->position > $row->position, 'last sibling position > than us');
250         }
251
252     }
253 }
254
255 sub check_rs {
256     my( $rs ) = @_;
257     $rs->reset();
258     my $position_column = $rs->result_class->position_column();
259     my $expected_position = 0;
260     while (my $row = $rs->next()) {
261         $expected_position ++;
262         if ($row->get_column($position_column)!=$expected_position) {
263             return 0;
264         }
265     }
266     return 1;
267 }
268