85ec3e16dca7c96cd23e825ad53d5f3596e1b96e
[dbsrgits/DBIx-Class.git] / t / resultset / inflate_result_api.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5 use Test::Deep;
6 use lib qw(t/lib);
7 use DBICTest;
8
9 my $schema = DBICTest->init_schema(no_populate => 1);
10
11 $schema->resultset('Artist')->create({ name => 'JMJ', cds => [{
12   title => 'Magnetic Fields',
13   year => 1981,
14   genre => { name => 'electro' },
15   tracks => [
16     { title => 'm1' },
17     { title => 'm2' },
18     { title => 'm3' },
19     { title => 'm4' },
20   ],
21 } ] });
22
23 $schema->resultset('CD')->create({
24   title => 'Equinoxe',
25   year => 1978,
26   artist => { name => 'JMJ' },
27   genre => { name => 'electro' },
28   tracks => [
29     { title => 'e1' },
30     { title => 'e2' },
31     { title => 'e3' },
32   ],
33   single_track => {
34     title => 'o1',
35     cd => {
36       title => 'Oxygene',
37       year => 1976,
38       artist => { name => 'JMJ' },
39       tracks => [
40         { title => 'o2', position => 2},  # the position should not be needed here, bug in MC
41       ],
42     },
43   },
44 });
45
46 $schema->resultset('CD')->create({ artist => 1, year => 1977, title => "fuzzy_1" });
47
48 {
49   package DBICTest::_IRCapture;
50   sub inflate_result { [@_[2,3]] };
51 }
52
53 cmp_structures(
54   ([$schema->resultset ('CD')->search ({}, {
55     result_class => 'DBICTest::_IRCapture',
56     prefetch => { single_track => { cd => 'artist' } },
57     order_by => 'me.cdid',
58   })->all]),
59   [
60     [
61       { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
62       { single_track => bless( [
63         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
64         {  cd => bless ( [
65           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
66           {
67             artist => bless ( [
68               { artistid => undef, name => undef, charfield => undef, rank => undef }
69             ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class )
70           }
71         ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
72       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
73     ],
74     [
75       { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
76       { single_track => bless( [
77         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
78         {  cd => bless ( [
79           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
80           {
81             artist => bless ( [
82               { artistid => undef, name => undef, charfield => undef, rank => undef }
83             ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class )
84           }
85         ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
86       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
87     ],
88     [
89       { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
90       { single_track => [
91         { trackid => 6, title => 'o1', position => 1, cd => 2, last_updated_at => undef, last_updated_on => undef },
92         {  cd => [
93           { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
94           {
95             artist => [
96               { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 }
97             ]
98           }
99         ] }
100       ] }
101     ],
102     [
103       { cdid => 4, single_track => undef, artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
104       { single_track => bless( [
105         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
106         {  cd => bless ( [
107           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
108           {
109             artist => bless ( [
110               { artistid => undef, name => undef, charfield => undef, rank => undef }
111             ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class )
112           }
113         ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
114       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
115     ],
116   ],
117   'Simple 1:1 descend with classic prefetch'
118 );
119
120 cmp_structures(
121   [$schema->resultset ('CD')->search ({}, {
122     result_class => 'DBICTest::_IRCapture',
123     join => { single_track => { cd => 'artist' } },
124     columns => [
125       { 'year'                                    => 'me.year' },
126       { 'genreid'                                 => 'me.genreid' },
127       { 'single_track.cd.artist.artistid'         => 'artist.artistid' },
128       { 'title'                                   => 'me.title' },
129       { 'artist'                                  => 'me.artist' },
130     ],
131     order_by => 'me.cdid',
132   })->all],
133   [
134     [
135       { artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
136       { single_track => bless( [
137         undef,
138         {  cd => [
139           undef,
140           {
141             artist => [
142               { artistid => undef }
143             ]
144           }
145         ] }
146       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
147     ],
148     [
149       { artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
150       { single_track => bless( [
151         undef,
152         {  cd => [
153           undef,
154           {
155             artist => [
156               { artistid => undef }
157             ]
158           }
159         ] }
160       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
161     ],
162     [
163       { artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
164       { single_track => [
165         undef,
166         {  cd => [
167           undef,
168           {
169             artist => [
170               { artistid => 1 }
171             ]
172           }
173         ] }
174       ] }
175     ],
176     [
177       { artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
178       { single_track => bless( [
179         undef,
180         {  cd => [
181           undef,
182           {
183             artist => [
184               { artistid => undef }
185             ]
186           }
187         ] }
188       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) }
189     ],
190   ],
191   'Simple 1:1 descend with missing selectors'
192 );
193
194 cmp_structures(
195   ([$schema->resultset ('CD')->search ({}, {
196     result_class => 'DBICTest::_IRCapture',
197     prefetch => [ { single_track => { cd => { artist => { cds => 'tracks' } } } } ],
198     order_by => [qw/me.cdid tracks.trackid/],
199   })->all]),
200   [
201     [
202       { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
203       { single_track => bless( [
204         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
205         {  cd => [
206           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
207           {
208             artist => [
209               { artistid => undef, name => undef, charfield => undef, rank => undef },
210               { cds => bless( [ [
211                 { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
212                 { tracks => bless( [ [
213                   { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
214                 ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
215               ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
216             ],
217           },
218         ] },
219       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
220     ],
221     [
222       { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
223       { single_track => bless( [
224         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
225         {  cd => [
226           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
227           {
228             artist => [
229               { artistid => undef, name => undef, charfield => undef, rank => undef },
230               { cds => bless( [ [
231                 { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
232                 { tracks => bless( [ [
233                   { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
234                 ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
235               ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
236             ],
237           },
238         ] },
239       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
240     ],
241     [
242       { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
243       { single_track => [
244         { trackid => 6, title => 'o1', position => 1, cd => 2, last_updated_at => undef, last_updated_on => undef },
245         {  cd => [
246           { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
247           {
248             artist => [
249               { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
250               { cds => [
251                 [
252                   { cdid => 4, single_track => undef, artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
253                   { tracks => bless( [
254                     [ { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef } ],
255                   ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
256                 ],
257                 [
258                   { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
259                   { tracks => [
260                     [ { trackid => 1, title => 'm1', position => 1, cd => 1, last_updated_at => undef, last_updated_on => undef } ],
261                     [ { trackid => 2, title => 'm2', position => 2, cd => 1, last_updated_at => undef, last_updated_on => undef } ],
262                     [ { trackid => 3, title => 'm3', position => 3, cd => 1, last_updated_at => undef, last_updated_on => undef } ],
263                     [ { trackid => 4, title => 'm4', position => 4, cd => 1, last_updated_at => undef, last_updated_on => undef } ],
264                   ]},
265                 ],
266                 [
267                   { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
268                   { tracks => [
269                     [ { trackid => 5, title => 'o2', position => 2, cd => 2, last_updated_at => undef, last_updated_on => undef } ],
270                     [ { trackid => 6, title => 'o1', position => 1, cd => 2, last_updated_at => undef, last_updated_on => undef } ],
271                   ]},
272                 ],
273                 [
274                   { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
275                   { tracks => [
276                     [ { trackid => 7, title => 'e1', position => 1, cd => 3, last_updated_at => undef, last_updated_on => undef } ],
277                     [ { trackid => 8, title => 'e2', position => 2, cd => 3, last_updated_at => undef, last_updated_on => undef } ],
278                     [ { trackid => 9, title => 'e3', position => 3, cd => 3, last_updated_at => undef, last_updated_on => undef } ],
279                   ]},
280                 ],
281               ]},
282             ]
283           }
284         ] }
285       ] }
286     ],
287     [
288       { cdid => 4, single_track => undef, artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
289       { single_track => bless( [
290         { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
291         {  cd => [
292           { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
293           {
294             artist => [
295               { artistid => undef, name => undef, charfield => undef, rank => undef },
296               { cds => bless( [ [
297                 { cdid => undef, single_track => undef, artist => undef, genreid => undef, year => undef, title => undef },
298                 { tracks => bless( [ [
299                   { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
300                 ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
301               ] ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
302             ],
303           },
304         ] },
305       ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
306     ],
307   ],
308   'Collapsing 1:1 ending in chained has_many with classic prefetch'
309 );
310
311 cmp_structures (
312   ([$schema->resultset ('Artist')->search ({}, {
313     result_class => 'DBICTest::_IRCapture',
314     join => { cds => 'tracks' },
315     '+columns' => [
316       (map { "cds.$_" } $schema->source('CD')->columns),
317       (map { +{ "cds.tracks.$_" => "tracks.$_" } } $schema->source('Track')->columns),
318     ],
319     order_by => [qw/cds.cdid tracks.trackid/],
320   })->all]),
321   [
322     [
323       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
324       { cds => [
325         { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
326         { tracks => [
327           { trackid => 1, title => 'm1', position => 1, cd => 1, last_updated_at => undef, last_updated_on => undef },
328         ]},
329       ]},
330     ],
331     [
332       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
333       { cds => [
334         { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
335         { tracks => [
336           { trackid => 2, title => 'm2', position => 2, cd => 1, last_updated_at => undef, last_updated_on => undef },
337         ]},
338       ]},
339     ],
340     [
341       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
342       { cds => [
343         { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
344         { tracks => [
345           { trackid => 3, title => 'm3', position => 3, cd => 1, last_updated_at => undef, last_updated_on => undef },
346         ]},
347       ]},
348     ],
349     [
350       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
351       { cds => [
352         { cdid => 1, single_track => undef, artist => 1, genreid => 1, year => 1981, title => "Magnetic Fields" },
353         { tracks => [
354           { trackid => 4, title => 'm4', position => 4, cd => 1, last_updated_at => undef, last_updated_on => undef },
355         ]},
356       ]},
357     ],
358     [
359       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
360       { cds => [
361         { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
362         { tracks => [
363           { trackid => 5, title => 'o2', position => 2, cd => 2, last_updated_at => undef, last_updated_on => undef },
364         ]},
365       ]},
366     ],
367     [
368       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
369       { cds => [
370         { cdid => 2, single_track => undef, artist => 1, genreid => undef, year => 1976, title => "Oxygene" },
371         { tracks => [
372           { trackid => 6, title => 'o1', position => 1, cd => 2, last_updated_at => undef, last_updated_on => undef },
373         ]},
374       ]},
375     ],
376     [
377       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
378       { cds => [
379         { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
380         { tracks => [
381           { trackid => 7, title => 'e1', position => 1, cd => 3, last_updated_at => undef, last_updated_on => undef },
382         ]},
383       ]},
384     ],
385     [
386       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
387       { cds => [
388         { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
389         { tracks => [
390           { trackid => 8, title => 'e2', position => 2, cd => 3, last_updated_at => undef, last_updated_on => undef },
391         ]},
392       ]},
393     ],
394     [
395       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
396       { cds => [
397         { cdid => 3, single_track => 6, artist => 1, genreid => 1, year => 1978, title => "Equinoxe" },
398         { tracks => [
399           { trackid => 9, title => 'e3', position => 3, cd => 3, last_updated_at => undef, last_updated_on => undef },
400         ]},
401       ]},
402     ],
403     [
404       { artistid => 1, name => 'JMJ', charfield => undef, rank => 13 },
405       { cds => [
406         { cdid => 4, single_track => undef, artist => 1, genreid => undef, year => 1977, title => "fuzzy_1" },
407         { tracks => bless( [
408           { trackid => undef, title => undef, position => undef, cd => undef, last_updated_at => undef, last_updated_on => undef },
409         ], $DBIx::Class::ResultSource::RowParser::Util::null_branch_class ) },
410       ]},
411     ],
412   ],
413   'Non-Collapsing chained has_many'
414 );
415
416 $schema->resultset('Artist')->create({ name => "${_}_cdless" })
417   for (qw( Z A ));
418
419 cmp_structures (
420   [$schema->resultset ('Artist')->search ({}, {
421     result_class => 'DBICTest::_IRCapture',
422     collapse => 1,
423     join => 'cds',
424     columns => [qw( cds.title cds.artist )],
425     order_by => [qw( me.name cds.title )],
426   })->all],
427   [
428     [
429       undef,
430       { cds => bless( [
431         [ { artist => undef, title => undef } ]
432       ], 'DBIx::ResultParser::RelatedNullBranch' ) },
433     ],
434     [
435       undef,
436       { cds => [
437         [ { artist => 1, title => "Equinoxe" } ],
438         [ { artist => 1, title => "Magnetic Fields" } ],
439         [ { artist => 1, title => "Oxygene" } ],
440         [ { artist => 1, title => "fuzzy_1" } ],
441       ] }
442     ],
443     [
444       undef,
445       { cds => bless( [
446         [ { artist => undef, title => undef } ]
447       ], 'DBIx::ResultParser::RelatedNullBranch' ) },
448     ],
449   ],
450   'Expected output of collapsing 1:M with empty root selection',
451 );
452
453 sub cmp_structures {
454   my ($left, $right, $msg) = @_;
455
456   local $Test::Builder::Level = $Test::Builder::Level + 1;
457   cmp_deeply($left, $right, $msg||());
458 }
459
460 done_testing;