Some cosmetic fixes in ANFANG
[dbsrgits/DBIx-Class.git] / t / 101populate_rs.t
index 942d927..7f356d9 100644 (file)
@@ -1,9 +1,11 @@
+BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) }
+
 ## ----------------------------------------------------------------------------
 ## Tests for the $resultset->populate method.
 ##
 ## GOALS:  We need to test the method for both void and array context for all
 ## the following relationship types: belongs_to, has_many.  Additionally we
-## need to each each of those for both specified PK's and autogenerated PK's
+## need to test each of those for both specified PK's and autogenerated PK's
 ##
 ## Also need to test some stuff that should generate errors.
 ## ----------------------------------------------------------------------------
@@ -12,7 +14,9 @@ use strict;
 use warnings;
 
 use Test::More;
-use lib qw(t/lib);
+use Test::Warn;
+use Test::Exception;
+
 use DBICTest;
 
 
@@ -24,7 +28,7 @@ my $schema  = DBICTest->init_schema();
 my $art_rs  = $schema->resultset('Artist');
 my $cd_rs  = $schema->resultset('CD');
 
-my $restricted_art_rs  = $art_rs->search({rank => 42});
+my $restricted_art_rs  = $art_rs->search({ -and => [ rank => 42, charfield => { '=', \['(SELECT MAX(artistid) FROM artist) + ?', 6] } ] });
 
 ok( $schema, 'Got a Schema object');
 ok( $art_rs, 'Got Good Artist Resultset');
@@ -37,10 +41,10 @@ ok( $cd_rs, 'Got Good CD Resultset');
 
 SCHEMA_POPULATE1: {
 
-  ## Test to make sure that the old $schema->populate is using the new method
-  ## for $resultset->populate when in void context and with sub objects.
+  # throw a monkey wrench
+  my $post_jnap_monkeywrench = $schema->resultset('Artist')->find(1)->update({ name => undef });
 
-  $schema->populate('Artist', [
+  warnings_exist { $schema->populate('Artist', [
 
     [qw/name cds/],
     ["001First Artist", [
@@ -55,28 +59,30 @@ SCHEMA_POPULATE1: {
     [undef, [
       {title=>"004Title1", year=>2010}
     ]],
-  ]);
+  ]) } qr/\QFast-path populate() of non-uniquely identifiable rows with related data is not possible/;
 
   isa_ok $schema, 'DBIx::Class::Schema';
 
-  my ($undef, $artist1, $artist2, $artist3 ) = $schema->resultset('Artist')->search({
+  my ( $preexisting_undef, $artist1, $artist2, $artist3, $undef ) = $schema->resultset('Artist')->search({
     name=>["001First Artist","002Second Artist","003Third Artist", undef]},
-    {order_by=>'name ASC'})->all;
+    {order_by => { -asc => 'artistid' }})->all;
 
   isa_ok  $artist1, 'DBICTest::Artist';
   isa_ok  $artist2, 'DBICTest::Artist';
   isa_ok  $artist3, 'DBICTest::Artist';
-  isa_ok  $undef, 'DBICTest::Artist';  
+  isa_ok  $undef, 'DBICTest::Artist';
 
   ok $artist1->name eq '001First Artist', "Got Expected Artist Name for Artist001";
   ok $artist2->name eq '002Second Artist', "Got Expected Artist Name for Artist002";
   ok $artist3->name eq '003Third Artist', "Got Expected Artist Name for Artist003";
-  ok !defined $undef->name, "Got Expected Artist Name for Artist004";  
+  ok !defined $undef->name, "Got Expected Artist Name for Artist004";
 
   ok $artist1->cds->count eq 3, "Got Right number of CDs for Artist1";
   ok $artist2->cds->count eq 0, "Got Right number of CDs for Artist2";
   ok $artist3->cds->count eq 1, "Got Right number of CDs for Artist3";
-  ok $undef->cds->count eq 1, "Got Right number of CDs for Artist4";  
+  ok $undef->cds->count eq 1, "Got Right number of CDs for Artist4";
+
+  $post_jnap_monkeywrench->delete;
 
   ARTIST1CDS: {
 
@@ -128,7 +134,7 @@ SCHEMA_POPULATE1: {
 ARRAY_CONTEXT: {
 
   ## These first set of tests are cake because array context just delegates
-  ## all it's processing to $resultset->create
+  ## all its processing to $resultset->create
 
   HAS_MANY_NO_PKS: {
 
@@ -170,7 +176,7 @@ ARRAY_CONTEXT: {
 
     isa_ok( $crap, 'DBICTest::Artist', "Got 'Artist'");
     isa_ok( $girl, 'DBICTest::Artist', "Got 'Artist'");
-    isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");  
+    isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");
     isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");
 
     ## Find the expected information?
@@ -244,7 +250,7 @@ ARRAY_CONTEXT: {
 
     isa_ok( $crap, 'DBICTest::Artist', "Got 'Artist'");
     isa_ok( $girl, 'DBICTest::Artist', "Got 'Artist'");
-    isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");  
+    isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");
     isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");
 
     ## Find the expected information?
@@ -258,7 +264,7 @@ ARRAY_CONTEXT: {
     ## Create the expected children sub objects?
 
     ok( $crap->cds->count == 0, "got Expected Number of Cds");
-    ok( $girl->cds->count == 2, "got Expected Number of Cds");  
+    ok( $girl->cds->count == 2, "got Expected Number of Cds");
     ok( $damn->cds->count == 3, "got Expected Number of Cds");
     ok( $formerly->cds->count == 1, "got Expected Number of Cds");
 
@@ -272,7 +278,7 @@ ARRAY_CONTEXT: {
 
   BELONGS_TO_NO_PKs: {
 
-    ## Test from a belongs_to perspective, should create artist first, 
+    ## Test from a belongs_to perspective, should create artist first,
     ## then CD with artistid.  This test we let the system automatically
     ## create the PK's.  Chances are good you'll use it this way mostly.
 
@@ -286,7 +292,7 @@ ARRAY_CONTEXT: {
         title => 'Some CD4',
         year => '1997',
         artist => { name => 'Fred BloggsD'},
-      },    
+      },
     ];
 
     my ($cdA, $cdB) = $cd_rs->populate($cds);
@@ -304,7 +310,7 @@ ARRAY_CONTEXT: {
 
   BELONGS_TO_WITH_PKs: {
 
-    ## Test from a belongs_to perspective, should create artist first, 
+    ## Test from a belongs_to perspective, should create artist first,
     ## then CD with artistid.  This time we try setting the PK's
 
     my $aid  = $art_rs->get_column('artistid')->max || 0;
@@ -313,24 +319,24 @@ ARRAY_CONTEXT: {
       {
         title => 'Some CD3',
         year => '1997',
-        artist => { artistid=> ++$aid, name => 'Fred BloggsC'},
+        artist => { artistid=> ++$aid, name => 'Fred BloggsE'},
       },
       {
         title => 'Some CD4',
         year => '1997',
-        artist => { artistid=> ++$aid, name => 'Fred BloggsD'},
-      },    
+        artist => { artistid=> ++$aid, name => 'Fred BloggsF'},
+      },
     ];
 
     my ($cdA, $cdB) = $cd_rs->populate($cds);
 
     isa_ok($cdA, 'DBICTest::CD', 'Created CD');
     isa_ok($cdA->artist, 'DBICTest::Artist', 'Set Artist');
-    is($cdA->artist->name, 'Fred BloggsC', 'Set Artist to FredC');
+    is($cdA->artist->name, 'Fred BloggsE', 'Set Artist to FredE');
 
     isa_ok($cdB, 'DBICTest::CD', 'Created CD');
     isa_ok($cdB->artist, 'DBICTest::Artist', 'Set Artist');
-    is($cdB->artist->name, 'Fred BloggsD', 'Set Artist to FredD');
+    is($cdB->artist->name, 'Fred BloggsF', 'Set Artist to FredF');
     ok($cdB->artist->artistid == $aid, "Got Expected Artist ID");
   }
 
@@ -343,8 +349,10 @@ ARRAY_CONTEXT: {
     ]);
 
     ## Did it use the condition in the resultset?
+    $more_crap->discard_changes;
     cmp_ok( $more_crap->rank, '==', 42, "Got Correct rank for result object");
-  } 
+    cmp_ok( $more_crap->charfield, '==', $more_crap->id + 5, "Got Correct charfield for result object");
+  }
 }
 
 
@@ -354,7 +362,7 @@ ARRAY_CONTEXT: {
 
 VOID_CONTEXT: {
 
-  ## All these tests check the ability to use populate without asking for 
+  ## All these tests check the ability to use populate without asking for
   ## any returned resultsets.  This uses bulk_insert as much as possible
   ## in order to increase speed.
 
@@ -386,7 +394,7 @@ VOID_CONTEXT: {
         cds => [
           { title => 'VOID_PK_My parents sold me to a record company' ,year => 2005 },
           { title => 'VOID_PK_Why Am I So Ugly?', year => 2006 },
-          { title => 'VOID_PK_I Got Surgery and am now Popular', year => 2007 }        
+          { title => 'VOID_PK_I Got Surgery and am now Popular', year => 2007 }
         ],
       },
       {
@@ -419,27 +427,27 @@ VOID_CONTEXT: {
 
     isa_ok( $crap, 'DBICTest::Artist', "Got 'Artist'");
     isa_ok( $girl, 'DBICTest::Artist', "Got 'Artist'");
-    isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");  
-    isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");  
-    isa_ok( $undef, 'DBICTest::Artist', "Got 'Artist'");    
+    isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");
+    isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");
+    isa_ok( $undef, 'DBICTest::Artist', "Got 'Artist'");
 
     ## Find the expected information?
 
     ok( $crap->name eq 'VOID_PK_Manufactured Crap', "Got Correct name 'VOID_PK_Manufactured Crap' for result object");
     ok( $girl->name eq 'VOID_PK_Angsty-Whiny Girl', "Got Correct name for result object");
-    ok( $damn->name eq 'VOID_PK_Like I Give a Damn', "Got Correct name for result object");  
+    ok( $damn->name eq 'VOID_PK_Like I Give a Damn', "Got Correct name for result object");
     ok( $formerly->name eq 'VOID_PK_Formerly Named', "Got Correct name for result object");
-    ok( !defined $undef->name, "Got Correct name 'is undef' for result object");    
+    ok( !defined $undef->name, "Got Correct name 'is undef' for result object");
 
     ## Create the expected children sub objects?
     ok( $crap->can('cds'), "Has cds relationship");
     ok( $girl->can('cds'), "Has cds relationship");
     ok( $damn->can('cds'), "Has cds relationship");
     ok( $formerly->can('cds'), "Has cds relationship");
-    ok( $undef->can('cds'), "Has cds relationship");  
+    ok( $undef->can('cds'), "Has cds relationship");
 
     ok( $crap->cds->count == 0, "got Expected Number of Cds");
-    ok( $girl->cds->count == 2, "got Expected Number of Cds");  
+    ok( $girl->cds->count == 2, "got Expected Number of Cds");
     ok( $damn->cds->count == 3, "got Expected Number of Cds");
     ok( $formerly->cds->count == 1, "got Expected Number of Cds");
     ok( $undef->cds->count == 1, "got Expected Number of Cds");
@@ -455,7 +463,7 @@ VOID_CONTEXT: {
 
   BELONGS_TO_WITH_PKs: {
 
-    ## Test from a belongs_to perspective, should create artist first, 
+    ## Test from a belongs_to perspective, should create artist first,
     ## then CD with artistid.  This time we try setting the PK's
 
     my $aid  = $art_rs->get_column('artistid')->max || 0;
@@ -473,7 +481,9 @@ VOID_CONTEXT: {
       },
     ];
 
-    $cd_rs->populate($cds);
+    warnings_exist {
+      $cd_rs->populate($cds)
+    } qr/\QFast-path populate() of belongs_to relationship data is not possible/;
 
     my ($cdA, $cdB) = $cd_rs->search(
       {title=>[sort map {$_->{title}} @$cds]},
@@ -492,7 +502,7 @@ VOID_CONTEXT: {
 
   BELONGS_TO_NO_PKs: {
 
-    ## Test from a belongs_to perspective, should create artist first, 
+    ## Test from a belongs_to perspective, should create artist first,
     ## then CD with artistid.
 
     my $cds = [
@@ -510,10 +520,12 @@ VOID_CONTEXT: {
         title => 'Some CD5BB',
         year => '1997',
         artist => { name => undef},
-      },    
+      },
     ];
 
-    $cd_rs->populate($cds);
+    warnings_exist {
+      $cd_rs->populate($cds);
+    } qr/\QFast-path populate() of belongs_to relationship data is not possible/;
 
     my ($cdA, $cdB, $cdC) = $cd_rs->search(
       {title=>[sort map {$_->{title}} @$cds]},
@@ -543,13 +555,13 @@ VOID_CONTEXT: {
     ## with the parent having many children and let the keys be automatic
 
     my $artists = [
-      {  
+      {
         name => 'VOID_Angsty-Whiny Girl',
         cds => [
           { title => 'VOID_My First CD', year => 2006 },
           { title => 'VOID_Yet More Tweeny-Pop crap', year => 2007 },
-        ],          
-      },    
+        ],
+      },
       {
         name => 'VOID_Manufactured Crap',
       },
@@ -558,15 +570,15 @@ VOID_CONTEXT: {
         cds => [
           { title => 'VOID_My parents sold me to a record company' ,year => 2005 },
           { title => 'VOID_Why Am I So Ugly?', year => 2006 },
-          { title => 'VOID_I Got Surgery and am now Popular', year => 2007 }        
+          { title => 'VOID_I Got Surgery and am now Popular', year => 2007 }
         ],
       },
-      {  
+      {
         name => 'VOID_Formerly Named',
         cds => [
           { title => 'VOID_One Hit Wonder', year => 2006 },
-        ],          
-      },      
+        ],
+      },
     ];
 
     ## Get the result row objects.
@@ -582,14 +594,14 @@ VOID_CONTEXT: {
 
     isa_ok( $crap, 'DBICTest::Artist', "Got 'Artist'");
     isa_ok( $girl, 'DBICTest::Artist', "Got 'Artist'");
-    isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");  
-    isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");  
+    isa_ok( $damn, 'DBICTest::Artist', "Got 'Artist'");
+    isa_ok( $formerly, 'DBICTest::Artist', "Got 'Artist'");
 
     ## Find the expected information?
 
     ok( $crap->name eq 'VOID_Manufactured Crap', "Got Correct name for result object");
     ok( $girl->name eq 'VOID_Angsty-Whiny Girl', "Got Correct name for result object");
-    ok( $damn->name eq 'VOID_Like I Give a Damn', "Got Correct name for result object");  
+    ok( $damn->name eq 'VOID_Like I Give a Damn', "Got Correct name for result object");
     ok( $formerly->name eq 'VOID_Formerly Named', "Got Correct name for result object");
 
     ## Create the expected children sub objects?
@@ -599,7 +611,7 @@ VOID_CONTEXT: {
     ok( $formerly->can('cds'), "Has cds relationship");
 
     ok( $crap->cds->count == 0, "got Expected Number of Cds");
-    ok( $girl->cds->count == 2, "got Expected Number of Cds");  
+    ok( $girl->cds->count == 2, "got Expected Number of Cds");
     ok( $damn->cds->count == 3, "got Expected Number of Cds");
     ok( $formerly->cds->count == 1, "got Expected Number of Cds");
 
@@ -626,8 +638,10 @@ VOID_CONTEXT: {
     })->first;
 
     ## Did it use the condition in the resultset?
+    $more_crap->discard_changes;
     cmp_ok( $more_crap->rank, '==', 42, "Got Correct rank for result object");
-  } 
+    cmp_ok( $more_crap->charfield, '==', $more_crap->id + 5, "Got Correct charfield for result object");
+  }
 }
 
 ARRAYREF_OF_ARRAYREF_STYLE: {
@@ -649,13 +663,17 @@ ARRAYREF_OF_ARRAYREF_STYLE: {
   my ($cooler, $lamer) = $restricted_art_rs->populate([
     [qw/artistid name/],
     [1003, 'Cooler'],
-    [1004, 'Lamer'],  
+    [1004, 'Lamer'],
   ]);
 
   is $cooler->name, 'Cooler', 'Correct Name';
-  is $lamer->name, 'Lamer', 'Correct Name';  
+  is $lamer->name, 'Lamer', 'Correct Name';
 
-  cmp_ok $cooler->rank, '==', 42, 'Correct Rank';
+  for ($cooler, $lamer) {
+    $_->discard_changes;
+    cmp_ok( $_->rank, '==', 42, "Got Correct rank for result object");
+    cmp_ok( $_->charfield, '==', $_->id + 5, "Got Correct charfield for result object");
+  }
 
   ARRAY_CONTEXT_WITH_COND_FROM_RS: {
 
@@ -666,8 +684,10 @@ ARRAYREF_OF_ARRAYREF_STYLE: {
     ]);
 
     ## Did it use the condition in the resultset?
+    $mega_lamer->discard_changes;
     cmp_ok( $mega_lamer->rank, '==', 42, "Got Correct rank for result object");
-  } 
+    cmp_ok( $mega_lamer->charfield, '==', $mega_lamer->id + 5, "Got Correct charfield for result object");
+  }
 
   VOID_CONTEXT_WITH_COND_FROM_RS: {
 
@@ -683,6 +703,29 @@ ARRAYREF_OF_ARRAYREF_STYLE: {
 
     ## Did it use the condition in the resultset?
     cmp_ok( $mega_lamer->rank, '==', 42, "Got Correct rank for result object");
+    cmp_ok( $mega_lamer->charfield, '==', $mega_lamer->id + 5, "Got Correct charfield for result object");
+  }
+}
+
+EMPTY_POPULATE: {
+  foreach(
+    [ empty         => [] ],
+    [ columns_only  => [ [qw(name rank charfield)] ] ],
+  ) {
+    my ($desc, $arg) = @{$_};
+
+    $schema->is_executed_sql_bind( sub {
+
+      my $rs = $art_rs;
+      lives_ok { $rs->populate($arg); 1 } "$desc populate in void context lives";
+
+      my @r = $art_rs->populate($arg);
+      is_deeply( \@r, [], "$desc populate in list context returns empty list" );
+
+      my $r = $art_rs->populate($arg);
+      is( $r, undef, "$desc populate in scalar context returns undef" );
+
+    }, [], "$desc populate executed no statements" );
   }
 }