Fix tests failing due to unspecified resultset retrieval order
Peter Rabbitson [Sat, 20 Apr 2013 22:09:54 +0000 (00:09 +0200)]
An upcoming version of DBD::SQLite bundles an SQLite library
with different behavior wrt retrieval of unordered indexed columns.

Fix all tests that could be affected now or in the future, and
add travis smoking to detect the condition early

22 files changed:
Changes
maint/travis-ci_scripts/30_before_script.bash
t/53lean_startup.t
t/60core.t
t/80unique.t
t/83cache.t
t/88result_set_column.t
t/90join_torture.t
t/admin/03data.t
t/lib/DBICTest.pm
t/multi_create/in_memory.t
t/multi_create/standard.t
t/prefetch/incomplete.t
t/prefetch/manual.t
t/prefetch/multiple_hasmany_torture.t
t/prefetch/restricted_children_set.t
t/prefetch/standard.t
t/relationship/core.t
t/relationship/update_or_create_multi.t
t/resultset/inflatemap_abuse.t
t/search/deprecated_attributes.t
t/update/ident_cond.t

diff --git a/Changes b/Changes
index e8ec6c5..14a1c77 100644 (file)
--- a/Changes
+++ b/Changes
@@ -57,6 +57,10 @@ Revision history for DBIx::Class
         - Make sure deployment_statements() and cursor_class() are called on
           a resolved storage subclass
 
+    * Misc
+        - Fix tests failing due to unspecified resultset retrieval order
+          (test suite now will pass with newest SQLite libs)
+
 0.08210 2013-04-04 15:30 (UTC)
     * New Features / Changes
         - Officially deprecate the 'cols' and 'include_columns' resultset
index 4430e12..69d74be 100755 (executable)
@@ -9,6 +9,8 @@ if [[ "$POISON_ENV" = "true" ]] ; then
   for var in $(grep -P '\$ENV\{' -r lib/ | grep -oP 'DBIC_\w+' | sort -u | grep -v DBIC_TRACE) ; do
     export $var=1
   done
+
+  export DBICTEST_SQLITE_REVERSE_DEFAULT_ORDER=1
 fi
 
 # try Schwern's latest offering on a stock perl and a threaded blead
index e106da2..de46c8c 100644 (file)
@@ -153,7 +153,7 @@ BEGIN {
 {
   require DBICTest;
   my $s = DBICTest->init_schema;
-  is ($s->resultset('Artist')->next->name, 'Caterwauler McCrae');
+  is ($s->resultset('Artist')->find(1)->name, 'Caterwauler McCrae');
   assert_no_missing_expected_requires();
 }
 
index 3a674de..f2e363a 100644 (file)
@@ -243,7 +243,7 @@ is($schema->class("Artist")->field_name_for->{name}, 'artist name', 'mk_classdat
 
 my $search = [ { 'tags.tag' => 'Cheesy' }, { 'tags.tag' => 'Blue' } ];
 
-my( $or_rs ) = $schema->resultset("CD")->search_rs($search, { join => 'tags',
+my $or_rs = $schema->resultset("CD")->search_rs($search, { join => 'tags',
                                                   order_by => 'cdid' });
 is($or_rs->all, 5, 'Joined search with OR returned correct number of rows');
 is($or_rs->count, 5, 'Search count with OR ok');
@@ -292,7 +292,7 @@ is ($collapsed_or_rs->count, 4, 'Collapsed search count with OR ok');
 my $tag_rs = $schema->resultset('Tag')->search(
                [ { 'me.tag' => 'Cheesy' }, { 'me.tag' => 'Blue' } ]);
 
-my $rel_rs = $tag_rs->search_related('cd');
+my $rel_rs = $tag_rs->search_related('cd', {}, { order_by => 'cd.cdid'} );
 
 is($rel_rs->count, 5, 'Related search ok');
 
index 7f78ef5..ba5a181 100644 (file)
@@ -226,7 +226,7 @@ is($row->baz, 3, 'baz is correct');
 
 # make sure the ident condition is assembled sanely
 {
-  my $artist = $schema->resultset('Artist')->next;
+  my $artist = $schema->resultset('Artist')->find(1);
 
   my ($sql, @bind);
   my $old_debugobj = $schema->storage->debugobj;
index 294bb1b..9edfe71 100644 (file)
@@ -116,6 +116,7 @@ $rs = $schema->resultset("Artist")->search(
     prefetch => {
       cds => 'tags'
     },
+    order_by => { -desc => 'cds.cdid' },
   }
 );
 {
@@ -138,16 +139,9 @@ $artist = ($rs->all)[0];
 
 is($queries, 1, 'only one SQL statement executed');
 
-$schema->storage->debug($sdebug);
-$schema->storage->debugcb (undef);
-
-my @objs;
-#$artist = $rs->find(1);
-
 $queries = 0;
-$schema->storage->debug(1);
-$schema->storage->debugcb ($debugcb);
 
+my @objs;
 my $cds = $artist->cds;
 my $tags = $cds->next->tags;
 while( my $tag = $tags->next ) {
@@ -162,7 +156,7 @@ while( my $tag = $tags->next ) {
   push @objs, $tag->id; #warn "tag: ", $tag->ID;
 }
 
-is_deeply( \@objs, [ 2, 5, 8 ], 'third cd has correct tags' );
+is_deeply( [ sort @objs] , [ 2, 5, 8 ], 'third cd has correct tags' );
 
 $tags = $cds->next->tags;
 @objs = ();
index ff8db9e..320f3fe 100644 (file)
@@ -14,7 +14,7 @@ my $rs = $schema->resultset("CD");
 
 cmp_ok (
   $rs->count,
-    '!=',
+    '>',
   $rs->search ({}, {columns => ['year'], distinct => 1})->count,
   'At least one year is the same in rs'
 );
@@ -23,25 +23,31 @@ my $rs_title = $rs->get_column('title');
 my $rs_year = $rs->get_column('year');
 my $max_year = $rs->get_column(\'MAX (year)');
 
-is($rs_title->next, 'Spoonful of bees', "next okay");
+my @all_titles = $rs_title->all;
+cmp_ok(scalar @all_titles, '==', 5, "five titles returned");
+
+my @nexted_titles;
+while (my $r = $rs_title->next) {
+  push @nexted_titles, $r;
+}
+
+is_deeply (\@all_titles, \@nexted_titles, 'next works');
+
 is_deeply( [ sort $rs_year->func('DISTINCT') ], [ 1997, 1998, 1999, 2001 ],  "wantarray context okay");
 ok ($max_year->next == $rs_year->max, q/get_column (\'FUNC') ok/);
 
-my @all = $rs_title->all;
-cmp_ok(scalar @all, '==', 5, "five titles returned");
-
 cmp_ok($rs_year->max, '==', 2001, "max okay for year");
 is($rs_title->min, 'Caterwaulin\' Blues', "min okay for title");
 
 cmp_ok($rs_year->sum, '==', 9996, "three artists returned");
 
-$rs_year->reset;
-is($rs_year->next, 1999, "reset okay");
+my $rso_year = $rs->search({}, { order_by => 'cdid' })->get_column('year');
+is($rso_year->next, 1999, "reset okay");
 
-is($rs_year->first, 1999, "first okay");
+is($rso_year->first, 1999, "first okay");
 
 warnings_exist (sub {
-  is($rs_year->single, 1999, "single okay");
+  is($rso_year->single, 1999, "single okay");
 }, qr/Query returned more than one row/, 'single warned');
 
 
@@ -136,7 +142,6 @@ is ($owner->search_related ('books')->get_column ('price')->sum, 60, 'Correctly
 
 
 # make sure joined/prefetched get_column of a PK dtrt
-
 $rs->reset;
 my $j_rs = $rs->search ({}, { join => 'tracks' })->get_column ('cdid');
 is_deeply (
@@ -148,8 +153,8 @@ is_deeply (
 $rs->reset;
 my $p_rs = $rs->search ({}, { prefetch => 'tracks' })->get_column ('cdid');
 is_deeply (
-  [ $p_rs->all ],
-  [ $rs->get_column ('cdid')->all ],
+  [ sort $p_rs->all ],
+  [ sort $rs->get_column ('cdid')->all ],
   'prefetch properly collapses amount of rows from get_column',
 );
 
index aa8c3fb..2bc86b2 100644 (file)
@@ -78,7 +78,9 @@ cmp_ok(scalar($rs3->all), '==', 15, "All cds for artist returned");
 
 cmp_ok($rs3->count, '==', 15, "All cds for artist returned via count");
 
-my $rs4 = $schema->resultset("CD")->search({ 'artist.artistid' => '1' }, { join => ['tracks', 'artist'], prefetch => 'artist' });
+my $rs4 = $schema->resultset("CD")->search({ 'artist.artistid' => '1' }, {
+  join => ['tracks', 'artist'], prefetch => 'artist', order_by => 'me.cdid'
+});
 my @rs4_results = $rs4->all;
 
 is($rs4_results[0]->cdid, 1, "correct artist returned");
index 05ae009..ee35001 100644 (file)
@@ -51,7 +51,7 @@ use_ok 'DBIx::Class::Admin';
     [2,2,undef,undef,undef,'Aran',undef]
   ];
   my $data;
-  lives_ok { $data = $admin->select('Employee')} 'can retrive data from database';
+  lives_ok { $data = $admin->select('Employee', undef, { order_by => 'employee_id' })} 'can retrive data from database';
   is_deeply($data, $expected_data, 'DB matches whats expected');
 
   $admin->delete('Employee', {name=>'Trout'});
index 75599eb..f95c8e7 100644 (file)
@@ -187,6 +187,9 @@ sub _database {
         # no fsync on commit
         $dbh->do ('PRAGMA synchronous = OFF');
 
+        $dbh->do ('PRAGMA reverse_unordered_selects = ON')
+          if $ENV{DBICTEST_SQLITE_REVERSE_DEFAULT_ORDER};
+
         # set a *DBI* disconnect callback, to make sure the physical SQLite
         # file is still there (i.e. the test does not attempt to delete
         # an open database, which fails on Win32)
index 25d290a..9533af5 100644 (file)
@@ -75,7 +75,7 @@ my $schema = DBICTest->init_schema();
 # test both sides of a 1:(1|0)
 {
   for my $reldir ('might_have', 'belongs_to') {
-    my $artist = $schema->resultset('Artist')->next;
+    my $artist = $schema->resultset('Artist')->find(1);
 
     my $new_track = $schema->resultset('Track')->new ({
       title => "$reldir: First track of latest cd",
index 6eb2b9a..5a02947 100644 (file)
@@ -112,7 +112,7 @@ lives_ok ( sub {
 #                                               /
 #                                          Producer
 lives_ok ( sub {
-  my $artist = $schema->resultset('Artist')->first;
+  my $artist = $schema->resultset('Artist')->find(1);
   my $cd = $schema->resultset('CD')->create ({
     artist => $artist,
     title => 'Music to code by at night',
@@ -152,7 +152,7 @@ lives_ok ( sub {
   is ($cd->title, 'Music to code by at night', 'Correct CD title');
   is ($cd->tracks->count, 2, 'Two tracks on main CD');
 
-  my ($t1, $t2) = $cd->tracks->all;
+  my ($t1, $t2) = sort { $a->id <=> $b->id } $cd->tracks->all;
   is ($t1->title, 'Off by one again', 'Correct 1st track name');
   is ($t1->cd_single, undef, 'No single for 1st track');
   is ($t2->title, 'The dereferencer', 'Correct 2nd track name');
index a710fbb..fe939cd 100644 (file)
@@ -116,6 +116,7 @@ throws_ok(
   my $pref_rs = $schema->resultset('Owners')->search({}, {
     rows => 3,
     offset => 1,
+    order_by => 'name',
     columns => 'name',  # only the owner name, still prefetch all the books
     prefetch => 'books',
   });
@@ -127,11 +128,13 @@ throws_ok(
         FROM (
           SELECT me.name, me.id
             FROM owners me
+          ORDER BY name
           LIMIT ?
           OFFSET ?
         ) me
         LEFT JOIN books books
           ON books.owner = me.id
+      ORDER BY name
     )',
     [ [ { sqlt_datatype => "integer" } => 3 ], [ { sqlt_datatype => "integer" } => 1 ] ],
     'Expected SQL on complex limited prefetch with non-selected join condition',
index 97f45c9..2228142 100644 (file)
@@ -63,7 +63,7 @@ my $rs = $schema->resultset ('CD')->search ({}, {
     { 'title'                                   => 'me.title' },              # uniquiness for me
     { 'artist'                                  => 'me.artist' },             # uniquiness for me
   ],
-  order_by => [{ -desc => 'cds.year' }, { -desc => 'me.title'} ],
+  order_by => [{ -desc => 'cds.year' }, { -desc => 'me.title'}, 'tracks.title', 'tracks_2.title' ],
 });
 
 my $hri_rs = $rs->search({}, { result_class => 'DBIx::Class::ResultClass::HashRefInflator' });
index 75ba477..b524aa9 100644 (file)
@@ -24,7 +24,7 @@ my $mo_rs = $schema->resultset('Artist')->search(
 
     result_class => 'DBIx::Class::ResultClass::HashRefInflator',
 
-    order_by => [qw/tracks.position tracks.trackid producer.producerid/],
+    order_by => [qw/tracks.position tracks.trackid producer.producerid tracks_2.trackid artwork.cd_id/],
   }
 );
 
@@ -72,7 +72,7 @@ $schema->resultset('Artist')->create(
       }
     ],
     artwork_to_artist => [
-      { artwork => {cd_id => 1 } },
+      { artwork => { cd_id => 1 } },
       { artwork => { cd_id => 2 } }
     ]
   }
index 959c87d..9b0f3ee 100644 (file)
@@ -19,7 +19,7 @@ my $cds_rs = $schema->resultset('CD')->search(
     },
   ],
   {
-    order_by => 'me.cdid',
+    order_by => [qw(me.cdid cds.title)],
     prefetch => { artist => 'cds' },
     result_class => 'DBIx::Class::ResultClass::HashRefInflator',
   },
index f316e10..26d3354 100644 (file)
@@ -50,7 +50,7 @@ $schema->storage->debugcb(sub { $queries++ });
 $schema->storage->debug(1);
 
 $rs = $schema->resultset('Tag')->search(
-  {},
+  { 'me.tagid' => 1 },
   {
     prefetch => { cd => 'artist' }
   }
@@ -86,7 +86,7 @@ $queries = 0;
 
 $schema->storage->debugcb(sub { $queries++; });
 
-$cd = $schema->resultset('CD')->find(1, { prefetch => { cd_to_producer => 'producer' } });
+$cd = $schema->resultset('CD')->find(1, { prefetch => { cd_to_producer => 'producer' }, order_by => 'producer.producerid' });
 
 is($cd->producers->first->name, 'Matt S Trout', 'many_to_many accessor ok');
 
@@ -289,10 +289,13 @@ is_deeply( $prefetch_result, $nonpre_result,
 
 $queries = 0;
 
-is($art_rs_pr->search_related('cds')->search_related('tracks')->first->title,
-   'Fowlin',
-   'chained has_many->has_many search_related ok'
-  );
+is_deeply(
+  [ sort map { $_->title } $art_rs_pr->search_related('cds')->search_related('tracks')->all ],
+  [ 'Apiary', 'Beehind You', 'Boring Name', 'Boring Song', 'Fowlin', 'Howlin',
+    'No More Ideas', 'Sad', 'Sticky Honey', 'Stripy', 'Stung with Success',
+    'Suicidal', 'The Bees Knees', 'Under The Weather', 'Yowlin' ],
+  'chained has_many->has_many search_related ok'
+);
 
 is($queries, 0, 'chained search_related after has_many->has_many prefetch ran no queries');
 
index af63a59..23d829d 100644 (file)
@@ -155,7 +155,7 @@ throws_ok {
 
 # many_to_many helper tests
 $cd = $schema->resultset("CD")->find(1);
-my @producers = $cd->producers();
+my @producers = $cd->producers(undef, { order_by => 'producerid'} );
 is( $producers[0]->name, 'Matt S Trout', 'many_to_many ok' );
 is( $cd->producers_sorted->next->name, 'Bob The Builder',
     'sorted many_to_many ok' );
index 25dfe79..8710048 100644 (file)
@@ -11,7 +11,7 @@ use DBIC::SqlMakerTest;
 my $schema = DBICTest->init_schema();
 my $sdebug = $schema->storage->debug;
 
-my $artist = $schema->resultset ('Artist')->first;
+my $artist = $schema->resultset ('Artist')->find(1);
 
 my $genre = $schema->resultset ('Genre')
             ->create ({ name => 'par excellence' });
index 1645ca1..9c60765 100644 (file)
@@ -26,8 +26,8 @@ my $rs_2nd_track = $s->resultset('Track')->search(
   { 'me.position' => 2 },
   {
     join => { cd => 'artist' },
-    'columns' => [ 'me.title', { 'artist.cdtitle' => 'cd.title' }, 'artist.name' ],
-    order_by => 'artist.name',
+    columns => [ 'me.title', { 'artist.cdtitle' => 'cd.title' }, 'artist.name' ],
+    order_by => [ 'artist.name', { -desc => 'cd.cdid' }, 'me.trackid' ],
   }
 );
 
index f4d2e28..8eed20b 100644 (file)
@@ -8,7 +8,7 @@ use DBICTest;
 
 my $schema = DBICTest->init_schema();
 
-my $cd_rs = $schema->resultset("CD");
+my $cd_rs = $schema->resultset("CD")->search({ 'me.cdid' => 1 });
 
 warnings_exist( sub {
   my $cd = $cd_rs->search( undef, {
index b79d56b..d7d4cf0 100644 (file)
@@ -7,7 +7,7 @@ use DBICTest;
 
 my $schema = DBICTest->init_schema();
 
-my $artist = $schema->resultset('Artist')->next;
+my $artist = $schema->resultset('Artist')->find(1);
 
 is_deeply(
   [ $artist->id, $artist->ident_condition, $artist->_storage_ident_condition ],