Index: /branches/release-40/t/driver-tests.pl
===================================================================
--- /branches/release-40/t/driver-tests.pl (revision 2574)
+++ /branches/release-40/t/driver-tests.pl (revision 2584)
@@ -24,5 +24,4 @@
 
 use Test::More;
-use Test::Deep;
 use lib 't/lib';
 
@@ -198,19 +197,43 @@
 
 sub clean_db : Test(teardown) {
-    for my $class (qw( Foo Bar )) {
-        my $driver    = $class->dbi_driver;
-        my $dbh       = $driver->rw_handle;
-        my $ddl_class = $driver->dbd->ddl_class;
-        
-        $dbh->do($ddl_class->drop_table_sql($class)) or die $dbh->errstr;
-        $dbh->do($ddl_class->create_table_sql($class)) or die $dbh->errstr;
-        $dbh->do($_) or die $dbh->errstr for $ddl_class->index_table_sql($class);
-        $ddl_class->create_sequence($class);  # may do nothing
-    }
-}
+    MT::Test->reset_table_for(qw( Foo Bar ));
+}
+
+
+package Test::Search;
+use MT::Test;
+use base qw( Test::Class MT::Test );
+
+sub make_foos : Test(setup) {
+    MT::Test->reset_table_for('Foo');
+
+    my $foo = Foo->new;
+    $foo->set_values({
+        name => 'foo',
+        status => 2,
+        text => 'bar',
+    });
+    $foo->save or die "Could not save test Foo: ", $foo->errstr, "\n";
+}
+
+sub basic : Tests(5) {
+    my $foo = Foo->load(1);  # not a search
+    
+    is_object(scalar Foo->load({ id => 1 }), $foo, 'Foo #1 by id hash is Foo #1');
+    is_object(scalar Foo->load({ id => 1, name => 'foo' }), $foo, 'Foo #1 by id-name hash is Foo #1');
+    is_object(scalar Foo->load({ name => 'foo' }), $foo, 'Foo #1 by name hash is Foo #1');
+    is_object(scalar Foo->load({ created_on => $foo->created_on }), $foo, 'Foo #1 by created_on hash is Foo #1');
+    is_object(scalar Foo->load({ status => 2 }), $foo, 'Foo #1 by status hash is Foo #1');
+}
+
+sub unmake_foos : Test(teardown) {
+    MT::Test->reset_table_for('Foo');
+}
+
 
 package main;
-
-Test::GroupBy->runtests( +152 );
+use MT::Test;
+
+Test::Class->runtests(qw( Test::GroupBy Test::Search +147 ));
 
 my($foo, @foo, @bar);
@@ -238,70 +261,5 @@
 is($foo->column('id'), 1, 'First Foo was given an id of 1, says column()');
 
-sub _is_object {
-    my ($got, $expected, $name) = @_;
-
-    if (!defined $got) {
-        fail($name);
-        diag('    got undef, not an object');
-        return;
-    }
-
-    if (!$got->isa(ref $expected)) {
-        fail($name);
-        diag('    got a ', ref($got), ' but expected a ', ref $expected);
-        return;
-    }
-
-    if ($got == $expected) {
-        fail($name);
-        diag('    got the exact same instance as expected, when really expected a different but equivalent object');
-        return;
-    }
-
-    # Ignore object columns that have undefined values.
-    my (%got_values, %expected_values);
-    while (my ($field, $value) = each %{ $got->{column_values} }) {
-        $got_values{$field} = $value if defined $value;
-    }
-    while (my ($field, $value) = each %{ $expected->{column_values} }) {
-        $expected_values{$field} = $value if defined $value;
-    }
-
-    if (!eq_deeply(\%got_values, \%expected_values)) {
-        # 'Test' again so the helpful failure diagnostics are output.
-        is_deeply(\%got_values, \%expected_values, $name);
-        return;
-    }
-
-    return 1;
-}
-
-sub is_object {
-    my ($got, $expected, $name) = @_;
-    pass($name) if _is_object(@_);
-}
-
-sub are_objects {
-    my ($got, $expected, $name) = @_;
-
-    my $count = scalar @$expected;
-    if ($count != scalar @$got) {
-        fail($name);
-        diag('    got ', scalar(@$got), ' objects but expected ', $count);
-        return;
-    }
-
-    for my $i (0..$count-1) {
-        return if !_is_object($$got[$i], $$expected[$i], "$name (#$i)");
-    }
-    pass($name);
-}
-
 is_object(scalar Foo->load(1), $foo, 'Foo #1 by id is Foo #1');
-is_object(scalar Foo->load({ id => 1 }), $foo, 'Foo #1 by id hash is Foo #1');
-is_object(scalar Foo->load({ id => 1, name => 'foo' }), $foo, 'Foo #1 by id-name hash is Foo #1');
-is_object(scalar Foo->load({ name => 'foo' }), $foo, 'Foo #1 by name hash is Foo #1');
-is_object(scalar Foo->load({ created_on => $foo->created_on }), $foo, 'Foo #1 by created_on hash is Foo #1');
-is_object(scalar Foo->load({ status => 2 }), $foo, 'Foo #1 by status hash is Foo #1');
 
 ##     Change column value, save, try to load using old value (fail?),
Index: /branches/release-40/t/lib/MT/Test.pm
===================================================================
--- /branches/release-40/t/lib/MT/Test.pm (revision 2578)
+++ /branches/release-40/t/lib/MT/Test.pm (revision 2584)
@@ -1,3 +1,6 @@
 package MT::Test;
+use base qw( Exporter );
+
+our @EXPORT = qw( is_object are_objects );
 
 use strict;
@@ -8,4 +11,5 @@
 
 use Test::More;
+use Test::Deep qw( eq_deeply );
 
 BEGIN {
@@ -43,4 +47,6 @@
 sub import {
     my $pkg = shift;
+    my @to_export;
+    # TODO: only use these init_* calls as calls, not as import args, now that we have real functions to export.
     foreach my $opt (@_) {
         if ($opt =~ m{ \A : (.+) \z }xms) {
@@ -48,5 +54,10 @@
             $pkg->$command() if $pkg->can($command);
         }
-    }
+        else {
+            push @to_export, $opt;
+        }
+    }
+    # Export requested or all exportable functions.
+    $pkg->export_to_level(1, @to_export || qw( :DEFAULT ));
 }
 
@@ -926,3 +937,77 @@
 }
 
+sub _is_object {
+    my ($got, $expected, $name) = @_;
+
+    if (!defined $got) {
+        fail($name);
+        diag('    got undef, not an object');
+        return;
+    }
+
+    if (!$got->isa(ref $expected)) {
+        fail($name);
+        diag('    got a ', ref($got), ' but expected a ', ref $expected);
+        return;
+    }
+
+    if ($got == $expected) {
+        fail($name);
+        diag('    got the exact same instance as expected, when really expected a different but equivalent object');
+        return;
+    }
+
+    # Ignore object columns that have undefined values.
+    my (%got_values, %expected_values);
+    while (my ($field, $value) = each %{ $got->{column_values} }) {
+        $got_values{$field} = $value if defined $value;
+    }
+    while (my ($field, $value) = each %{ $expected->{column_values} }) {
+        $expected_values{$field} = $value if defined $value;
+    }
+
+    if (!eq_deeply(\%got_values, \%expected_values)) {
+        # 'Test' again so the helpful failure diagnostics are output.
+        is_deeply(\%got_values, \%expected_values, $name);
+        return;
+    }
+
+    return 1;
+}
+
+sub is_object {
+    my ($got, $expected, $name) = @_;
+    pass($name) if _is_object(@_);
+}
+
+sub are_objects {
+    my ($got, $expected, $name) = @_;
+
+    my $count = scalar @$expected;
+    if ($count != scalar @$got) {
+        fail($name);
+        diag('    got ', scalar(@$got), ' objects but expected ', $count);
+        return;
+    }
+
+    for my $i (0..$count-1) {
+        return if !_is_object($$got[$i], $$expected[$i], "$name (#$i)");
+    }
+    pass($name);
+}
+
+sub reset_table_for {
+    my $self = shift;
+    for my $class (@_) {
+        my $driver    = $class->dbi_driver;
+        my $dbh       = $driver->rw_handle;
+        my $ddl_class = $driver->dbd->ddl_class;
+
+        $dbh->do($ddl_class->drop_table_sql($class)) or die $dbh->errstr;
+        $dbh->do($ddl_class->create_table_sql($class)) or die $dbh->errstr;
+        $dbh->do($_) or die $dbh->errstr for $ddl_class->index_table_sql($class);
+        $ddl_class->create_sequence($class);  # may do nothing        
+    }
+}
+
 1;
