Fixed problem with block vs. string evals
[dbsrgits/DBM-Deep.git] / t / 44_upgrade_db.t
1 $|++;
2 use strict;
3 use Test::More;
4
5 # Add skips here
6 BEGIN {
7     plan skip_all => "Skipping the upgrade_db.pl tests on Win32/cygwin for now."
8         if ( $^O eq 'MSWin32' || $^O eq 'cygwin' );
9
10     plan skip_all => "Skipping the upgrade_db.pl tests on *bsd for now."
11         if ( $^O =~ /bsd/i );
12
13     my @failures;
14     eval " use Pod::Usage 1.3;"; push @failures, 'Pod::Usage' if $@;
15     eval " use IO::Scalar;"; push @failures, 'IO::Scalar' if $@;
16     eval " use FileHandle::Fmode;"; push @failures, 'FileHandle::Fmode' if $@;
17     if ( @failures ) {
18         my $missing = join ',', @failures;
19         plan skip_all => "'$missing' must be installed to run these tests";
20     }
21 }
22
23 plan tests => 302;
24
25 use t::common qw( new_fh );
26 use File::Spec;
27 use Test::Deep;
28
29 my $PROG = File::Spec->catfile( qw( utils upgrade_db.pl ) );
30
31 my $short = get_pod( $PROG, 0 );
32 my $long = get_pod( $PROG, 1 );
33
34 is( run_prog( $PROG ), "Missing required parameters.\n$long", "Failed no params" );
35 is( run_prog( $PROG, '-input foo' ), "Missing required parameters.\n$long", "Failed only -input" );
36 is( run_prog( $PROG, '-output foo' ), "Missing required parameters.\n$long", "Failed only -output" );
37 is(
38     run_prog( $PROG, '-input foo', '-output foo' ),
39     "Cannot use the same filename for both input and output.\n$short",
40     "Failed same name",
41 );
42
43 is(
44     run_prog( $PROG, '-input foo', '-output bar' ),
45     "'foo' is not a file.\n$short",
46     "Failed input does not exist",
47 );
48
49 my (undef, $input_filename) = new_fh();
50 my (undef, $output_filename) = new_fh();
51
52 is(
53     run_prog( $PROG, "-input $input_filename", "-output $output_filename" ),
54     "'$input_filename' is not a DBM::Deep file.\n$short",
55     "Input is not a DBM::Deep file",
56 );
57
58 unlink $input_filename;unlink $output_filename;
59
60 # All files are of the form:
61 #   $db->{foo} = [ 1 .. 3 ];
62
63 my @input_files = (
64     '0-983',
65     '0-99_04',
66     '1-0000',
67     '1-0003',
68 );
69
70 my @output_versions = (
71     '0.91', '0.92', '0.93', '0.94', '0.95', '0.96', '0.97', '0.98',
72     '0.981', '0.982', '0.983',
73     '0.99_01', '0.99_02', '0.99_03', '0.99_04',
74     '1.00', '1.000', '1.0000', '1.0001', '1.0002',
75     '1.0003', '1.0004', '1.0005', '1.0006', '1.0007', '1.0008', '1.0009', '1.0010',
76     '1.0011', '1.0012', '1.0013', '1.0014',
77 );
78
79 foreach my $input_filename (
80     map { 
81         File::Spec->catfile( qw( t etc ), "db-$_" )
82     } @input_files
83 ) {
84     # chmod it writable because old DBM::Deep versions don't handle readonly
85     # files correctly. This is fixed in DBM::Deep 1.0000
86     chmod 0600, $input_filename;
87
88     foreach my $v ( @output_versions ) {
89         my (undef, $output_filename) = new_fh();
90         my $output = run_prog(
91             $PROG,
92             "-input $input_filename",
93             "-output $output_filename",
94             "-version $v",
95         );
96
97         #warn "Testing $input_filename against $v\n";
98
99         # Clone was removed as a requirement in 1.0006
100         if ( $output =~ /Can\'t locate Clone\.pm in \@INC/ ) {
101             ok( 1 );
102             unless ( $input_filename =~ /_/ || $v =~ /_/ ) {
103                 ok( 1 ); ok( 1 );
104             }
105             next;
106         }
107
108         if ( $input_filename =~ /_/ ) {
109             is(
110                 $output, "'$input_filename' is a dev release and not supported.\n$short",
111                 "Input file is a dev release - not supported",
112             );
113
114             next;
115         }
116
117         if ( $v =~ /_/ ) {
118             is(
119                 $output, "-version '$v' is a dev release and not supported.\n$short",
120                 "Output version is a dev release - not supported",
121             );
122
123             next;
124         }
125
126         # Now, read the output file with the right version.
127         ok( !$output, "A successful run produces no output" );
128         die "$output\n" if $output;
129
130         my $db;
131         if ( $v =~ /^1\.001[0-4]/ || $v =~ /^1\.000[3-9]/ ) {
132             push @INC, 'lib';
133             eval "use DBM::Deep";
134             $db = DBM::Deep->new( $output_filename );
135         }
136         elsif ( $v =~ /^1\.000?[0-2]?/ ) {
137             push @INC, File::Spec->catdir( 'utils', 'lib' );
138             eval "use DBM::Deep::10002";
139             $db = DBM::Deep::10002->new( $output_filename );
140         }
141         elsif ( $v =~ /^0/ ) {
142             push @INC, File::Spec->catdir( 'utils', 'lib' );
143             eval "use DBM::Deep::09830";
144             $db = DBM::Deep::09830->new( $output_filename );
145         }
146         else {
147             die "How did we get here?!\n";
148         }
149
150         ok( $db, "Writing to version $v made a file" );
151
152         cmp_deeply(
153             $db->export,
154             { foo => [ 1 .. 3 ] },
155             "We can read the output file",
156         );
157     }
158 }
159
160 ################################################################################
161
162 #XXX This needs to be made OS-portable
163 sub run_prog {
164     open( my $fh, '-|', "$^X @_ 2>&1" )
165       or die "Cannot launch '@_' as a piped filehandle: $!\n";
166     return join '', <$fh>;
167 }
168
169 # In 5.8, we could use in-memory filehandles and have done:
170 #     open( my $fh, '>', \my $pod ) or die "Cannot open in-memory filehandle: $!\n";
171 #     ...
172 #     return $pod;
173 # However, DBM::Deep requires 5.6, so this set of contortions will have to do.
174 sub get_pod {
175     my ($p,$v) = @_;
176
177     my ($fh, $fn) = new_fh();
178     close $fh;
179
180     open $fh, '>', $fn;
181     pod2usage({
182         -input   => $p,
183         -output  => $fh,
184         -verbose => $v,
185         -exitval => 'NOEXIT',
186     });
187     close $fh;
188
189     open $fh, '<', $fn;
190     return join '', <$fh>;
191 }