-##
-# DBM::Deep Test
-##
use strict;
-use Test::More tests => 7;
+use warnings FATAL => 'all';
+
+use Test::More;
use Test::Exception;
+use t::common qw( new_fh );
+
+# Need to have an explicit plan in order for the sub-testing to work right.
+#XXX Figure out how to use subtests for that.
+my $pre_fork_tests = 14;
+plan tests => $pre_fork_tests + 2;
+
+use_ok( 'DBM::Deep' );
-use DBM::Deep;
+{
+ my ($fh, $filename) = new_fh();
-open(FILE, "t/27_filehandle.t.db") || die("Can't open t/27_filehandle.t.db\n");
+ # Create the datafile to be used
+ {
+ my $db = DBM::Deep->new( $filename );
+ $db->{hash} = { foo => [ 'a' .. 'c' ] };
+ }
-my $db;
+ {
+ open(my $fh, '<', $filename) || die("Can't open '$filename' for reading: $!\n");
-# test if we can open and read a db using its filehandle
+ # test if we can open and read a db using its filehandle
-ok(($db = DBM::Deep->new(fh => *FILE)), "open db in filehandle");
-ok($db->{hash}->{foo}->[1] eq 'b', "and get at stuff in the database");
+ my $db;
+ ok( ($db = DBM::Deep->new( fh => $fh )), "open db in filehandle" );
+ ok( $db->{hash}{foo}[1] eq 'b', "and get at stuff in the database" );
+ throws_ok {
+ $db->{foo} = 1;
+ } qr/Cannot write to a readonly filehandle/, "Can't write to a read-only filehandle";
+ ok( !$db->exists( 'foo' ), "foo doesn't exist" );
-undef $db;
-close(FILE);
+ throws_ok {
+ delete $db->{foo};
+ } qr/Cannot write to a readonly filehandle/, "Can't delete from a read-only filehandle";
+
+ throws_ok {
+ %$db = ();
+ } qr/Cannot write to a readonly filehandle/, "Can't clear from a read-only filehandle";
+
+ SKIP: {
+ skip( "No inode tests on Win32", 1 )
+ if ( $^O eq 'MSWin32' || $^O eq 'cygwin' );
+ my $db_obj = $db->_get_self;
+ ok( $db_obj->_engine->storage->{inode}, "The inode has been set" );
+ }
+
+ close($fh);
+ }
+}
# now the same, but with an offset into the file. Use the database that's
# embedded in the test for the DATA filehandle. First, find the database ...
-open(FILE, "t/28_DATA.t") || die("Can't open t/28_DATA.t\n");
-while(my $line = <FILE>) {
- last if($line =~ /^__DATA__/);
+{
+ my ($fh,$filename) = new_fh();
+
+ print $fh "#!$^X\n";
+ print $fh <<"__END_FH__";
+use strict;
+use Test::More 'no_plan';
+Test::More->builder->no_ending(1);
+Test::More->builder->{Curr_Test} = $pre_fork_tests;
+
+use_ok( 'DBM::Deep' );
+
+my \$db = DBM::Deep->new({
+ fh => *DATA,
+});
+is(\$db->{x}, 'b', "and get at stuff in the database");
+__END_FH__
+
+ # The exec below prevents END blocks from doing this.
+ (my $esc_dir = $t::common::dir) =~ s/(.)/sprintf "\\x{%x}", ord $1/egg;
+ print $fh <<__END_FH_AGAIN__;
+use File::Path 'rmtree';
+rmtree "$esc_dir";
+__END_FH_AGAIN__
+
+ print $fh "__DATA__\n";
+ close $fh;
+
+ my $offset = do {
+ open my $fh, '<', $filename;
+ while(my $line = <$fh>) {
+ last if($line =~ /^__DATA__/);
+ }
+ tell($fh);
+ };
+
+ {
+ my $db = DBM::Deep->new({
+ file => $filename,
+ file_offset => $offset,
+ #XXX For some reason, this is needed to make the test pass. Figure
+ #XXX out why later.
+ locking => 0,
+ });
+
+ $db->{x} = 'b';
+ is( $db->{x}, 'b', 'and it was stored' );
+ }
+
+ {
+ open my $fh, '<', $filename;
+ my $db = DBM::Deep->new({
+ fh => $fh,
+ file_offset => $offset,
+ });
+
+ is($db->{x}, 'b', "and get at stuff in the database");
+
+ ok( !$db->exists( 'foo' ), "foo doesn't exist yet" );
+ throws_ok {
+ $db->{foo} = 1;
+ } qr/Cannot write to a readonly filehandle/, "Can't write to a read-only filehandle";
+ ok( !$db->exists( 'foo' ), "foo still doesn't exist" );
+
+ is( $db->{x}, 'b' );
+ }
+
+ exec( "$^X -Iblib/lib $filename" );
}
-my $offset = tell(FILE);
-close(FILE);
-
-open(FILE, '<', "t/28_DATA.t");
-ok(($db = DBM::Deep->new(fh => *FILE, file_offset => $offset)), "open db in filehandle with offset");
-ok($db->{hash}->{foo}->[1] eq 'b', "and get at stuff in the database");
-
-ok( !$db->{foo}, "foo doesn't exist yet" );
-throws_ok {
- $db->{foo} = 1;
-} qr/Cannot write to a readonly filehandle/, "Can't write to a read-only filehandle";
-ok( !$db->{foo}, "foo doesn't exist yet" );