xref: /openbsd-src/gnu/usr.bin/perl/cpan/Archive-Tar/t/02_methods.t (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
1b39c5158SmillertBEGIN { chdir 't' if -d 't' }
2b39c5158Smillert
3b39c5158Smillertuse Test::More 'no_plan';
4b39c5158Smillertuse strict;
5b39c5158Smillertuse lib '../lib';
6b39c5158Smillert
7b39c5158Smillertuse Cwd;
8b39c5158Smillertuse Config;
9b39c5158Smillertuse IO::File;
10b39c5158Smillertuse File::Copy;
11b39c5158Smillertuse File::Path;
12b39c5158Smillertuse File::Spec          ();
13b39c5158Smillertuse File::Spec::Unix    ();
14b39c5158Smillertuse File::Basename      ();
15b39c5158Smillertuse Data::Dumper;
16b39c5158Smillert
17b39c5158Smillert### need the constants at compile time;
18b39c5158Smillertuse Archive::Tar::Constant;
19b39c5158Smillert
20b39c5158Smillertmy $Class   = 'Archive::Tar';
21b39c5158Smillertmy $FClass  = $Class . '::File';
22b39c5158Smillertuse_ok( $Class );
23b39c5158Smillert
24b39c5158Smillert
25b39c5158Smillert
26b39c5158Smillert### XXX TODO:
27b39c5158Smillert### * change to fullname
28b39c5158Smillert### * add tests for global variables
29b39c5158Smillert
30b39c5158Smillert### set up the environment ###
31b39c5158Smillertmy @EXPECT_NORMAL = (
32b39c5158Smillert    ### dirs        filename    contents
33b39c5158Smillert    [   [],         'c',        qr/^iiiiiiiiiiii\s*$/ ],
34b39c5158Smillert    [   [],         'd',        qr/^uuuuuuuu\s*$/ ],
35b39c5158Smillert);
36b39c5158Smillert
37b39c5158Smillert### includes binary data
38b39c5158Smillertmy $ALL_CHARS = join '', "\r\n", map( chr, 1..255 ), "zzz\n\r";
39b39c5158Smillert
40b39c5158Smillert### @EXPECTBIN is used to ensure that $tarbin is written in the right
41b39c5158Smillert### order and that the contents and order match exactly when extracted
42b39c5158Smillertmy @EXPECTBIN = (
43b39c5158Smillert    ###  dirs   filename      contents       ###
44b39c5158Smillert    [    [],    'bIn11',      $ALL_CHARS x 11 ],
45b39c5158Smillert    [    [],    'bIn3',       $ALL_CHARS x  3 ],
46b39c5158Smillert    [    [],    'bIn4',       $ALL_CHARS x  4 ],
47b39c5158Smillert    [    [],    'bIn1',       $ALL_CHARS      ],
48b39c5158Smillert    [    [],    'bIn2',       $ALL_CHARS x  2 ],
49b39c5158Smillert);
50b39c5158Smillert
51b39c5158Smillert### @EXPECTX is used to ensure that $tarx is written in the right
52b39c5158Smillert### order and that the contents and order match exactly when extracted
53b39c5158Smillert### the 'x/x' extraction used to fail before A::T 1.08
54b39c5158Smillertmy @EXPECTX = (
55b39c5158Smillert    ###  dirs       filename    contents
56b39c5158Smillert    [    [ 'x' ],   'k',        '',     ],
57b39c5158Smillert    [    [ 'x' ],   'x',        'j',    ],   # failed before A::T 1.08
58b39c5158Smillert);
59b39c5158Smillert
60b39c5158Smillertmy $LONG_FILE = qq[directory/really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-really-long-directory-name/myfile];
61b39c5158Smillert
62b39c5158Smillert### wintendo can't deal with too long paths, so we might have to skip tests ###
63b39c5158Smillertmy $TOO_LONG    =   ($^O eq 'MSWin32' or $^O eq 'cygwin' or $^O eq 'VMS')
64b39c5158Smillert                    && length( cwd(). $LONG_FILE ) > 247;
65b39c5158Smillert
66898184e3Ssthenif(!$TOO_LONG) {
67898184e3Ssthen    my $alt = File::Spec->catfile( cwd(), $LONG_FILE);
68898184e3Ssthen    eval 'mkpath([$alt]);';
69898184e3Ssthen    if($@)
70898184e3Ssthen    {
71898184e3Ssthen        $TOO_LONG = 1;
72898184e3Ssthen    }
73898184e3Ssthen    else
74898184e3Ssthen    {
75898184e3Ssthen        $@ = '';
76898184e3Ssthen        my $base = File::Spec->catfile( cwd(), 'directory');
77898184e3Ssthen        rmtree $base;
78898184e3Ssthen    }
79898184e3Ssthen}
80b39c5158Smillert### warn if we are going to skip long file names
81b39c5158Smillertif ($TOO_LONG) {
82b39c5158Smillert    diag("No long filename support - long filename extraction disabled") if ! $ENV{PERL_CORE};
83b39c5158Smillert} else {
84b39c5158Smillert    push @EXPECT_NORMAL, [ [], $LONG_FILE, qr/^hello\s*$/];
85b39c5158Smillert}
86b39c5158Smillert
87b39c5158Smillertmy @ROOT        = grep { length }   'src', $TOO_LONG ? 'short' : 'long';
88b39c5158Smillertmy $NO_UNLINK   = $ARGV[0] ? 1 : 0;
89b39c5158Smillert
90b39c5158Smillert### enable debugging?
91b39c5158Smillert### pesky warnings
92b39c5158Smillert$Archive::Tar::DEBUG = $Archive::Tar::DEBUG = 1 if $ARGV[1];
93b39c5158Smillert
94b39c5158Smillert### tests for binary and x/x files
95b39c5158Smillertmy $TARBIN      = $Class->new;
96b39c5158Smillertmy $TARX        = $Class->new;
97b39c5158Smillert
98b39c5158Smillert### paths to a .tar and .tgz file to use for tests
99b39c5158Smillertmy $TAR_FILE        = File::Spec->catfile( @ROOT, 'bar.tar' );
100b39c5158Smillertmy $TGZ_FILE        = File::Spec->catfile( @ROOT, 'foo.tgz' );
101b39c5158Smillertmy $TBZ_FILE        = File::Spec->catfile( @ROOT, 'foo.tbz' );
102de8cc8edSafresh1my $TXZ_FILE        = File::Spec->catfile( @ROOT, 'foo.txz' );
103b39c5158Smillertmy $OUT_TAR_FILE    = File::Spec->catfile( @ROOT, 'out.tar' );
104b39c5158Smillertmy $OUT_TGZ_FILE    = File::Spec->catfile( @ROOT, 'out.tgz' );
105b39c5158Smillertmy $OUT_TBZ_FILE    = File::Spec->catfile( @ROOT, 'out.tbz' );
106de8cc8edSafresh1my $OUT_TXZ_FILE    = File::Spec->catfile( @ROOT, 'out.txz' );
107b39c5158Smillert
108b39c5158Smillertmy $COMPRESS_FILE = 'copy';
109b39c5158Smillert$^O eq 'VMS' and $COMPRESS_FILE .= '.';
110b39c5158Smillertcopy( File::Basename::basename($0), $COMPRESS_FILE );
111b39c5158Smillertchmod 0644, $COMPRESS_FILE;
112b39c5158Smillert
113b39c5158Smillert### done setting up environment ###
114b39c5158Smillert
115de8cc8edSafresh1### check for zlib/bzip2/xz support
116de8cc8edSafresh1{   for my $meth ( qw[has_zlib_support has_bzip2_support has_xz_support] ) {
117b39c5158Smillert        can_ok( $Class, $meth );
118b39c5158Smillert    }
119b39c5158Smillert}
120b39c5158Smillert
121b39c5158Smillert
122b39c5158Smillert
123b39c5158Smillert### tar error tests
124b39c5158Smillert{   my $tar     = $Class->new;
125b39c5158Smillert
126b39c5158Smillert    ok( $tar,                       "Object created" );
127b39c5158Smillert    isa_ok( $tar,                   $Class );
128b39c5158Smillert
129b39c5158Smillert    local $Archive::Tar::WARN  = 0;
130b39c5158Smillert
131b39c5158Smillert    ### should be empty to begin with
132b39c5158Smillert    is( $tar->error, '',            "The error string is empty" );
133b39c5158Smillert
134b39c5158Smillert    ### try a read on nothing
135b39c5158Smillert    my @list = $tar->read();
136b39c5158Smillert
137b39c5158Smillert    ok(!(scalar @list),             "Function read returns 0 files on error" );
138b39c5158Smillert    ok( $tar->error,                "   error string is non empty" );
139b39c5158Smillert    like( $tar->error, qr/No file to read from/,
140b39c5158Smillert                                    "   error string from create()" );
141b39c5158Smillert    unlike( $tar->error, qr/add/,   "   error string does not contain add" );
142b39c5158Smillert
143b39c5158Smillert    ### now, add empty data
144b39c5158Smillert    my $obj = $tar->add_data( '' );
145b39c5158Smillert
146b39c5158Smillert    ok( !$obj,                      "'add_data' returns undef on error" );
147b39c5158Smillert    ok( $tar->error,                "   error string is non empty" );
148b39c5158Smillert    like( $tar->error, qr/add/,     "   error string contains add" );
149b39c5158Smillert    unlike( $tar->error, qr/create/,"   error string does not contain create" );
150b39c5158Smillert
151b39c5158Smillert    ### check if ->error eq $error
152b39c5158Smillert    is( $tar->error, $Archive::Tar::error,
153b39c5158Smillert                                    "Error '$Archive::Tar::error' matches $Class->error method" );
154b39c5158Smillert
155b39c5158Smillert    ### check that 'contains_file' doesn't warn about missing files.
156b39c5158Smillert    {   ### turn on warnings in general!
157b39c5158Smillert        local $Archive::Tar::WARN  = 1;
158b39c5158Smillert
159b39c5158Smillert        my $warnings = '';
160b39c5158Smillert        local $SIG{__WARN__} = sub { $warnings .= "@_" };
161b39c5158Smillert
162b39c5158Smillert        my $rv = $tar->contains_file( $$ );
163b39c5158Smillert        ok( !$rv,                   "Does not contain file '$$'" );
164b39c5158Smillert        is( $warnings, '',          "   No warnings issued during lookup" );
165b39c5158Smillert    }
166b39c5158Smillert}
167b39c5158Smillert
168256a93a4Safresh1my $ebcdic_skip_msg = "File contains an alien character set";
169256a93a4Safresh1
170b39c5158Smillert### read tests ###
171256a93a4Safresh1SKIP: {
172256a93a4Safresh1    my @to_try;
173256a93a4Safresh1
174256a93a4Safresh1    if (ord 'A' == 65) {
175256a93a4Safresh1        push @to_try, $TAR_FILE;
176b39c5158Smillert        push @to_try, $TGZ_FILE if $Class->has_zlib_support;
177b39c5158Smillert        push @to_try, $TBZ_FILE if $Class->has_bzip2_support;
178de8cc8edSafresh1        push @to_try, $TXZ_FILE if $Class->has_xz_support;
179256a93a4Safresh1    }
180256a93a4Safresh1    else {
181256a93a4Safresh1        skip $ebcdic_skip_msg, 4;
182256a93a4Safresh1    }
183b39c5158Smillert
184b39c5158Smillert    for my $type( @to_try ) {
185b39c5158Smillert
186b39c5158Smillert        ### normal tar + gz compressed file
187b39c5158Smillert        my $tar             = $Class->new;
188b39c5158Smillert
189b39c5158Smillert        ### check we got the object
190b39c5158Smillert        ok( $tar,               "Object created" );
191b39c5158Smillert        isa_ok( $tar,           $Class );
192b39c5158Smillert
193b39c5158Smillert        ### ->read test
194b39c5158Smillert        my @list    = $tar->read( $type );
195b39c5158Smillert        my $cnt     = scalar @list;
196b39c5158Smillert        my $expect  = scalar __PACKAGE__->get_expect();
197b39c5158Smillert
198b39c5158Smillert        ok( $cnt,               "Reading '$type' using 'read()'" );
199b39c5158Smillert        is( $cnt, $expect,      "   All files accounted for" );
200b39c5158Smillert
201b39c5158Smillert        for my $file ( @list ) {
202b39c5158Smillert            ok( $file,          "       Got File object" );
203b39c5158Smillert            isa_ok( $file,  $FClass );
204b39c5158Smillert
205b39c5158Smillert            ### whitebox test -- make sure find_entry gets the
206b39c5158Smillert            ### right files
207b39c5158Smillert            for my $test ( $file->full_path, $file ) {
208b39c5158Smillert                is( $tar->_find_entry( $test ), $file,
209b39c5158Smillert                                "           Found proper object" );
210b39c5158Smillert            }
211b39c5158Smillert
212b39c5158Smillert            next unless $file->is_file;
213b39c5158Smillert
214b39c5158Smillert            my $name = $file->full_path;
215b39c5158Smillert            my($expect_name, $expect_content) =
216b39c5158Smillert                get_expect_name_and_contents( $name, \@EXPECT_NORMAL );
217b39c5158Smillert
218b39c5158Smillert            ### ->fullname!
219b39c5158Smillert            ok($expect_name,    "           Found expected file '$name'" );
220b39c5158Smillert
221b39c5158Smillert            like($tar->get_content($name), $expect_content,
222b39c5158Smillert                                "           Content OK" );
223b39c5158Smillert        }
224b39c5158Smillert
225b39c5158Smillert
226b39c5158Smillert        ### list_archive test
227b39c5158Smillert        {   my @list    = $Class->list_archive( $type );
228b39c5158Smillert            my $cnt     = scalar @list;
229b39c5158Smillert            my $expect  = scalar __PACKAGE__->get_expect();
230b39c5158Smillert
231b39c5158Smillert            ok( $cnt,           "Reading '$type' using 'list_archive'");
232b39c5158Smillert            is( $cnt, $expect,  "   All files accounted for" );
233b39c5158Smillert
234b39c5158Smillert            for my $file ( @list ) {
235b39c5158Smillert                next if __PACKAGE__->is_dir( $file ); # directories
236b39c5158Smillert
237b39c5158Smillert                my($expect_name, $expect_content) =
238b39c5158Smillert                    get_expect_name_and_contents( $file, \@EXPECT_NORMAL );
239b39c5158Smillert
240b39c5158Smillert                ok( $expect_name,
241b39c5158Smillert                                "   Found expected file '$file'" );
242b39c5158Smillert            }
243b39c5158Smillert        }
244b39c5158Smillert    }
245b39c5158Smillert}
246b39c5158Smillert
247b39c5158Smillert### add files tests ###
248b39c5158Smillert{   my @add     = map { File::Spec->catfile( @ROOT, @$_ ) } ['b'];
249b39c5158Smillert    my @addunix = map { File::Spec::Unix->catfile( @ROOT, @$_ ) } ['b'];
250b39c5158Smillert    my $tar     = $Class->new;
251b39c5158Smillert
252b39c5158Smillert    ### check we got the object
253b39c5158Smillert    ok( $tar,                       "Object created" );
254b39c5158Smillert    isa_ok( $tar,                   $Class );
255b39c5158Smillert
256b39c5158Smillert    ### add the files
257b39c5158Smillert    {   my @files = $tar->add_files( @add );
258b39c5158Smillert
259b39c5158Smillert        is( scalar @files, scalar @add,
260b39c5158Smillert                                    "   Adding files");
261b39c5158Smillert        is( $files[0]->name,'b',    "      Proper name" );
262b39c5158Smillert
263b39c5158Smillert        SKIP: {
264b39c5158Smillert            skip( "You are building perl using symlinks", 1)
265b39c5158Smillert                if ($ENV{PERL_CORE} and $Config{config_args} =~/Dmksymlinks/);
266b39c5158Smillert
267b39c5158Smillert            is( $files[0]->is_file, 1,
268b39c5158Smillert                                    "       Proper type" );
269b39c5158Smillert        }
270b39c5158Smillert
271b39c5158Smillert        like( $files[0]->get_content, qr/^bbbbbbbbbbb\s*$/,
272b39c5158Smillert                                    "       Content OK" );
273b39c5158Smillert
274b39c5158Smillert        ### check if we have then in our tar object
275b39c5158Smillert        for my $file ( @addunix ) {
276b39c5158Smillert            ok( $tar->contains_file($file),
277b39c5158Smillert                                    "       File found in archive" );
278b39c5158Smillert        }
279b39c5158Smillert    }
280b39c5158Smillert
281b39c5158Smillert    ### check adding files doesn't conflict with a secondary archive
282b39c5158Smillert    ### old A::T bug, we should keep testing for it
283b39c5158Smillert    {   my $tar2    = $Class->new;
284b39c5158Smillert        my @added   = $tar2->add_files( $COMPRESS_FILE );
285b39c5158Smillert        my @count   = $tar2->list_files;
286b39c5158Smillert
287b39c5158Smillert        is( scalar @added, 1,       "   Added files to secondary archive" );
288b39c5158Smillert        is( scalar @added, scalar @count,
289b39c5158Smillert                                    "       No conflict with first archive" );
290b39c5158Smillert
291b39c5158Smillert        ### check the adding of directories
292b39c5158Smillert        my @add_dirs  = File::Spec->catfile( @ROOT );
293b39c5158Smillert        my @dirs      = $tar2->add_files( @add_dirs );
294b39c5158Smillert        is( scalar @dirs, scalar @add_dirs,
295b39c5158Smillert                                    "       Adding dirs");
296b39c5158Smillert        ok( $dirs[0]->is_dir,       "           Proper type" );
297b39c5158Smillert    }
298b39c5158Smillert
299b39c5158Smillert    ### check if we can add a A::T::File object
300b39c5158Smillert    {   my $tar2    = $Class->new;
301b39c5158Smillert        my($added)  = $tar2->add_files( $add[0] );
302b39c5158Smillert
303b39c5158Smillert        ok( $added,                 "   Added a file '$add[0]' to new object" );
304b39c5158Smillert        isa_ok( $added, $FClass,    "       Object" );
305b39c5158Smillert
306b39c5158Smillert        my($added2) = $tar2->add_files( $added );
307b39c5158Smillert        ok( $added2,                "       Added an $FClass object" );
308b39c5158Smillert        isa_ok( $added2, $FClass,   "           Object" );
309b39c5158Smillert
310b39c5158Smillert        is_deeply( [$added, $added2], [$tar2->get_files],
311b39c5158Smillert                                    "       All files accounted for" );
312b39c5158Smillert        isnt( $added, $added2,      "       Different memory allocations" );
313b39c5158Smillert    }
314b39c5158Smillert}
315b39c5158Smillert
316b39c5158Smillert### add data tests ###
317b39c5158Smillert{
318b39c5158Smillert    {   ### standard data ###
319b39c5158Smillert        my @to_add  = ( 'a', 'aaaaa' );
320b39c5158Smillert        my $tar     = $Class->new;
321b39c5158Smillert
322b39c5158Smillert        ### check we got the object
323b39c5158Smillert        ok( $tar,                   "Object created" );
324b39c5158Smillert        isa_ok( $tar,               $Class );
325b39c5158Smillert
326b39c5158Smillert        ### add a new file item as data
327b39c5158Smillert        my $obj = $tar->add_data( @to_add );
328b39c5158Smillert
329b39c5158Smillert        ok( $obj,                   "   Adding data" );
330b39c5158Smillert        is( $obj->name, $to_add[0], "       Proper name" );
331b39c5158Smillert        is( $obj->is_file, 1,       "       Proper type" );
332b39c5158Smillert        like( $obj->get_content, qr/^$to_add[1]\s*$/,
333b39c5158Smillert                                    "       Content OK" );
334b39c5158Smillert    }
335b39c5158Smillert
336b39c5158Smillert    {   ### binary data +
337b39c5158Smillert        ### dir/file structure -- x/y always went ok, x/x used to extract
338b39c5158Smillert        ### in the wrong way -- this test catches that
339b39c5158Smillert        for my $list (  [$TARBIN,   \@EXPECTBIN],
340b39c5158Smillert                        [$TARX,     \@EXPECTX],
341b39c5158Smillert        ) {
342b39c5158Smillert            ### XXX GLOBAL! changes may affect other tests!
343b39c5158Smillert            my($tar,$struct) = @$list;
344b39c5158Smillert
345b39c5158Smillert            for my $aref ( @$struct ) {
346b39c5158Smillert                my ($dirs,$file,$data) = @$aref;
347b39c5158Smillert
348b39c5158Smillert                my $path = File::Spec::Unix->catfile(
349b39c5158Smillert                                grep { length } @$dirs, $file );
350b39c5158Smillert
351b39c5158Smillert                my $obj = $tar->add_data( $path, $data );
352b39c5158Smillert
353b39c5158Smillert                ok( $obj,               "   Adding data '$file'" );
354b39c5158Smillert                is( $obj->full_path, $path,
355b39c5158Smillert                                        "       Proper name" );
356b39c5158Smillert                ok( $obj->is_file,      "       Proper type" );
357b39c5158Smillert                is( $obj->get_content, $data,
358b39c5158Smillert                                        "       Content OK" );
359b39c5158Smillert            }
360b39c5158Smillert        }
361b39c5158Smillert    }
362b39c5158Smillert}
363b39c5158Smillert
364b39c5158Smillert### rename/replace_content tests ###
365256a93a4Safresh1
366256a93a4Safresh1SKIP: {
367256a93a4Safresh1    skip $ebcdic_skip_msg, 9 if ord "A" != 65;
368256a93a4Safresh1
369256a93a4Safresh1    my $tar     = $Class->new;
370b39c5158Smillert    my $from    = 'c';
371b39c5158Smillert    my $to      = 'e';
372b39c5158Smillert
373b39c5158Smillert    ### read in the file, check the proper files are there
374b39c5158Smillert    ok( $tar->read( $TAR_FILE ),    "Read in '$TAR_FILE'" );
375b39c5158Smillert    ok( $tar->get_files($from),     "   Found file '$from'" );
376b39c5158Smillert    {   local $Archive::Tar::WARN = 0;
377b39c5158Smillert        ok(!$tar->get_files($to),   "   File '$to' not yet found" );
378b39c5158Smillert    }
379b39c5158Smillert
380b39c5158Smillert    ### rename an entry, check the rename has happened
381b39c5158Smillert    ok( $tar->rename( $from, $to ), "   Renamed '$from' to '$to'" );
382b39c5158Smillert    ok( $tar->get_files($to),       "   File '$to' now found" );
383b39c5158Smillert    {   local $Archive::Tar::WARN = 0;
384b39c5158Smillert        ok(!$tar->get_files($from), "   File '$from' no longer found'");
385b39c5158Smillert    }
386b39c5158Smillert
387b39c5158Smillert    ### now, replace the content
388b39c5158Smillert    my($expect_name, $expect_content) =
389b39c5158Smillert                        get_expect_name_and_contents( $from, \@EXPECT_NORMAL );
390b39c5158Smillert
391b39c5158Smillert    like( $tar->get_content($to), $expect_content,
392b39c5158Smillert                                    "Original content of '$from' in '$to'" );
393b39c5158Smillert    ok( $tar->replace_content( $to, $from ),
394b39c5158Smillert                                    "   Set content for '$to' to '$from'" );
395b39c5158Smillert    is( $tar->get_content($to), $from,
396b39c5158Smillert                                    "   Content for '$to' is indeed '$from'" );
397b39c5158Smillert}
398b39c5158Smillert
399b39c5158Smillert### remove tests ###
400256a93a4Safresh1SKIP: {
401256a93a4Safresh1    skip $ebcdic_skip_msg, 3 if ord "A" != 65;
402256a93a4Safresh1
403256a93a4Safresh1    my $remove  = 'c';
404b39c5158Smillert    my $tar     = $Class->new;
405b39c5158Smillert
406b39c5158Smillert    ok( $tar->read( $TAR_FILE ),    "Read in '$TAR_FILE'" );
407b39c5158Smillert
408b39c5158Smillert    ### remove returns the files left, which should be equal to list_files
409b39c5158Smillert    is( scalar($tar->remove($remove)), scalar($tar->list_files),
410b39c5158Smillert                                    "   Removing file '$remove'" );
411b39c5158Smillert
412b39c5158Smillert    ### so what's left should be all expected files minus 1
413b39c5158Smillert    is( scalar($tar->list_files), scalar(__PACKAGE__->get_expect) - 1,
414b39c5158Smillert                                    "   Proper files remaining" );
415b39c5158Smillert}
416b39c5158Smillert
417b39c5158Smillert### write + read + extract tests ###
418b39c5158SmillertSKIP: {                             ### pesky warnings
419256a93a4Safresh1    skip $ebcdic_skip_msg, 326 if ord "A" != 65;
420256a93a4Safresh1
421b39c5158Smillert    skip('no IO::String', 326) if   !$Archive::Tar::HAS_PERLIO &&
422b39c5158Smillert                                    !$Archive::Tar::HAS_PERLIO &&
423b39c5158Smillert                                    !$Archive::Tar::HAS_IO_STRING &&
424b39c5158Smillert                                    !$Archive::Tar::HAS_IO_STRING;
425b39c5158Smillert
426b39c5158Smillert    my $tar = $Class->new;
427b39c5158Smillert    my $new = $Class->new;
428b39c5158Smillert    ok( $tar->read( $TAR_FILE ),    "Read in '$TAR_FILE'" );
429b39c5158Smillert
430b39c5158Smillert    for my $aref (  [$tar,    \@EXPECT_NORMAL],
431b39c5158Smillert                    [$TARBIN, \@EXPECTBIN],
432b39c5158Smillert                    [$TARX,   \@EXPECTX]
433b39c5158Smillert    ) {
434b39c5158Smillert        my($obj,$struct) = @$aref;
435b39c5158Smillert
436b39c5158Smillert        ### check if we stringify it ok
437b39c5158Smillert        {   my $string = $obj->write;
438b39c5158Smillert            ok( $string,           "    Stringified tar file has size" );
439b39c5158Smillert            cmp_ok( length($string) % BLOCK, '==', 0,
440b39c5158Smillert                                    "       Tar archive stringified" );
441b39c5158Smillert        }
442b39c5158Smillert
443b39c5158Smillert        ### write tar tests
444b39c5158Smillert        {   my $out = $OUT_TAR_FILE;
445b39c5158Smillert
446b39c5158Smillert            ### bug #41798: 'Nonempty $\ when writing a TAR file produces a
447b39c5158Smillert            ### corrupt TAR file' shows that setting $\ breaks writing tar files
448b39c5158Smillert            ### set it here purposely so we can verify NOTHING breaks
449b39c5158Smillert            local $\ = 'FOOBAR';
450b39c5158Smillert
451b39c5158Smillert            {   ### write()
452b39c5158Smillert                ok( $obj->write($out),
453b39c5158Smillert                                    "       Wrote tarfile using 'write'" );
454b39c5158Smillert                check_tar_file( $out );
455b39c5158Smillert                check_tar_object( $obj, $struct );
456b39c5158Smillert
457b39c5158Smillert                ### now read it in again
458b39c5158Smillert                ok( $new->read( $out ),
459b39c5158Smillert                                    "       Read '$out' in again" );
460b39c5158Smillert
461b39c5158Smillert                check_tar_object( $new, $struct );
462b39c5158Smillert
463b39c5158Smillert                ### now extract it again
464b39c5158Smillert                ok( $new->extract,  "       Extracted '$out' with 'extract'" );
465b39c5158Smillert                check_tar_extract( $new, $struct );
466b39c5158Smillert
467b39c5158Smillert                rm( $out ) unless $NO_UNLINK;
468b39c5158Smillert            }
469b39c5158Smillert
470b39c5158Smillert
471b39c5158Smillert            {   ### create_archive()
472b39c5158Smillert                ok( $Class->create_archive( $out, 0, $COMPRESS_FILE ),
473b39c5158Smillert                                    "       Wrote tarfile using 'create_archive'" );
474b39c5158Smillert                check_tar_file( $out );
475b39c5158Smillert
476b39c5158Smillert                ### now extract it again
477b39c5158Smillert                ok( $Class->extract_archive( $out ),
478b39c5158Smillert                                    "       Extracted file using 'extract_archive'");
479b39c5158Smillert                rm( $out ) unless $NO_UNLINK;
480b39c5158Smillert            }
481b39c5158Smillert        }
482b39c5158Smillert
483b39c5158Smillert        ## write tgz tests
484b39c5158Smillert        {   my @out;
485b39c5158Smillert            push @out, [ $OUT_TGZ_FILE => 1             ] if $Class->has_zlib_support;
486b39c5158Smillert            push @out, [ $OUT_TBZ_FILE => COMPRESS_BZIP ] if $Class->has_bzip2_support;
487de8cc8edSafresh1            push @out, [ $OUT_TXZ_FILE => COMPRESS_XZ   ] if $Class->has_xz_support;
488b39c5158Smillert
489b39c5158Smillert            for my $entry ( @out ) {
490b39c5158Smillert
491b39c5158Smillert                my( $out, $compression ) = @$entry;
492b39c5158Smillert
493b39c5158Smillert                {   ### write()
494b39c5158Smillert                    ok($obj->write($out, $compression),
495b39c5158Smillert                                    "       Writing compressed file '$out' using 'write'" );
496b39c5158Smillert                    check_compressed_file( $out );
497b39c5158Smillert
498b39c5158Smillert                    check_tar_object( $obj, $struct );
499b39c5158Smillert
500b39c5158Smillert                    ### now read it in again
501b39c5158Smillert                    ok( $new->read( $out ),
502b39c5158Smillert                                    "       Read '$out' in again" );
503b39c5158Smillert                    check_tar_object( $new, $struct );
504b39c5158Smillert
505b39c5158Smillert                    ### now extract it again
506b39c5158Smillert                    ok( $new->extract,
507b39c5158Smillert                                    "       Extracted '$out' again" );
508b39c5158Smillert                    check_tar_extract( $new, $struct );
509b39c5158Smillert
510b39c5158Smillert                    rm( $out ) unless $NO_UNLINK;
511b39c5158Smillert                }
512b39c5158Smillert
513b39c5158Smillert                {   ### create_archive()
514b39c5158Smillert                    ok( $Class->create_archive( $out, $compression, $COMPRESS_FILE ),
515b39c5158Smillert                                    "       Wrote '$out' using 'create_archive'" );
516b39c5158Smillert                    check_compressed_file( $out );
517b39c5158Smillert
518b39c5158Smillert                    ### now extract it again
519b39c5158Smillert                    ok( $Class->extract_archive( $out, $compression ),
520b39c5158Smillert                                    "       Extracted file using 'extract_archive'");
521b39c5158Smillert                    rm( $out ) unless $NO_UNLINK;
522b39c5158Smillert                }
523b39c5158Smillert            }
524b39c5158Smillert        }
525b39c5158Smillert    }
526b39c5158Smillert}
527b39c5158Smillert
528b39c5158Smillert
529b39c5158Smillert### limited read + extract tests ###
530256a93a4Safresh1SKIP: {                             ### pesky warnings
531256a93a4Safresh1    skip $ebcdic_skip_msg, 8 if ord "A" != 65;
532256a93a4Safresh1
533256a93a4Safresh1    my $tar     = $Class->new;
534b39c5158Smillert    my @files   = $tar->read( $TAR_FILE, 0, { limit => 1 } );
535b39c5158Smillert    my $obj     = $files[0];
536b39c5158Smillert
537b39c5158Smillert    is( scalar @files, 1,           "Limited read" );
538b39c5158Smillert
539b39c5158Smillert    my ($name,$content) = get_expect_name_and_contents(
540b39c5158Smillert                                $obj->full_path, \@EXPECT_NORMAL );
541b39c5158Smillert
542b39c5158Smillert    is( $obj->name, $name,          "   Expected file found" );
543b39c5158Smillert
544b39c5158Smillert
545b39c5158Smillert    ### extract this single file to cwd()
546b39c5158Smillert    for my $meth (qw[extract extract_file]) {
547b39c5158Smillert
548b39c5158Smillert        ### extract it by full path and object
549b39c5158Smillert        for my $arg ( $obj, $obj->full_path ) {
550b39c5158Smillert
551b39c5158Smillert            ok( $tar->$meth( $arg ),
552b39c5158Smillert                                    "   Extract '$name' to cwd() with $meth" );
553b39c5158Smillert            ok( -e $obj->full_path, "       Extracted file exists" );
554b39c5158Smillert            rm( $obj->full_path ) unless $NO_UNLINK;
555b39c5158Smillert        }
556b39c5158Smillert    }
557b39c5158Smillert
558b39c5158Smillert    ### extract this file to @ROOT
559b39c5158Smillert    ### can only do that with 'extract_file', not with 'extract'
560b39c5158Smillert    for my $meth (qw[extract_file]) {
561b39c5158Smillert        my $outpath = File::Spec->catdir( @ROOT );
562b39c5158Smillert        my $outfile = File::Spec->catfile( $outpath, $$ ); #$obj->full_path );
563b39c5158Smillert
564b39c5158Smillert        ok( $tar->$meth( $obj->full_path, $outfile ),
565b39c5158Smillert                                    "   Extract file '$name' to $outpath with $meth" );
566b39c5158Smillert        ok( -e $outfile,            "       Extracted file '$outfile' exists" );
567b39c5158Smillert        rm( $outfile ) unless $NO_UNLINK;
568b39c5158Smillert    }
569b39c5158Smillert
570b39c5158Smillert}
571b39c5158Smillert
572b39c5158Smillert
573*5486feefSafresh1### extract tests with different $EXTRACT_BLOCK_SIZE values ###
574*5486feefSafresh1SKIP: {                             ### pesky warnings
575*5486feefSafresh1    skip $ebcdic_skip_msg, 431 if ord "A" != 65;
576*5486feefSafresh1
577*5486feefSafresh1    skip('no IO::String', 431) if   !$Archive::Tar::HAS_PERLIO &&
578*5486feefSafresh1                                    !$Archive::Tar::HAS_PERLIO &&
579*5486feefSafresh1                                    !$Archive::Tar::HAS_IO_STRING &&
580*5486feefSafresh1                                    !$Archive::Tar::HAS_IO_STRING;
581*5486feefSafresh1
582*5486feefSafresh1    my $tar = $Class->new;
583*5486feefSafresh1    ok( $tar->read( $TAR_FILE ),    "Read in '$TAR_FILE'" );
584*5486feefSafresh1
585*5486feefSafresh1    for my $aref (  [$tar,    \@EXPECT_NORMAL],
586*5486feefSafresh1                    [$TARBIN, \@EXPECTBIN],
587*5486feefSafresh1                    [$TARX,   \@EXPECTX]
588*5486feefSafresh1    ) {
589*5486feefSafresh1        my($obj, $struct) = @$aref;
590*5486feefSafresh1
591*5486feefSafresh1        for my $block_size ((1, BLOCK, 1024 * 1024, 2**31 - 4096, 2**31 - 1)) {
592*5486feefSafresh1            local $Archive::Tar::EXTRACT_BLOCK_SIZE = $block_size;
593*5486feefSafresh1
594*5486feefSafresh1            ok( $obj->extract,  "   Extracted with 'extract'" );
595*5486feefSafresh1            check_tar_extract( $obj, $struct );
596*5486feefSafresh1        }
597*5486feefSafresh1    }
598*5486feefSafresh1}
599*5486feefSafresh1
600*5486feefSafresh1
601b39c5158Smillert### clear tests ###
602256a93a4Safresh1SKIP: {                             ### pesky warnings
603256a93a4Safresh1    skip $ebcdic_skip_msg, 3 if ord "A" != 65;
604256a93a4Safresh1
605256a93a4Safresh1    my $tar     = $Class->new;
606b39c5158Smillert    my @files   = $tar->read( $TAR_FILE );
607b39c5158Smillert
608b39c5158Smillert    my $cnt = $tar->list_files();
609b39c5158Smillert    ok( $cnt,                       "Found old data" );
610b39c5158Smillert    ok( $tar->clear,                "   Clearing old data" );
611b39c5158Smillert
612b39c5158Smillert    my $new_cnt = $tar->list_files;
613b39c5158Smillert    ok( !$new_cnt,                  "   Old data cleared" );
614b39c5158Smillert}
615b39c5158Smillert
616b39c5158Smillert### $DO_NOT_USE_PREFIX tests
617b39c5158Smillert{   my $tar     = $Class->new;
618b39c5158Smillert
619b39c5158Smillert
620b39c5158Smillert    ### first write a tar file without prefix
621b39c5158Smillert    {   my ($obj)   = $tar->add_files( $COMPRESS_FILE );
622b39c5158Smillert        my $dir     = '';   # dir is empty!
623b39c5158Smillert        my $file    = File::Basename::basename( $COMPRESS_FILE );
624b39c5158Smillert
625b39c5158Smillert        ok( $obj,                   "File added" );
626b39c5158Smillert        isa_ok( $obj,               $FClass );
627b39c5158Smillert
628b39c5158Smillert        ### internal storage ###
629b39c5158Smillert        is( $obj->name, $file,      "   Name set to '$file'" );
630b39c5158Smillert        is( $obj->prefix, $dir,     "   Prefix set to '$dir'" );
631b39c5158Smillert
632b39c5158Smillert        ### write the tar file without a prefix in it
633b39c5158Smillert        ### pesky warnings
634b39c5158Smillert        local $Archive::Tar::DO_NOT_USE_PREFIX = 1;
635b39c5158Smillert        local $Archive::Tar::DO_NOT_USE_PREFIX = 1;
636b39c5158Smillert
637b39c5158Smillert        ok( $tar->write( $OUT_TAR_FILE ),
638b39c5158Smillert                                    "   Tar file written" );
639b39c5158Smillert
640b39c5158Smillert        ### and forget all about it...
641b39c5158Smillert        $tar->clear;
642b39c5158Smillert    }
643b39c5158Smillert
644b39c5158Smillert    ### now read it back in, there should be no prefix
645b39c5158Smillert    {   ok( $tar->read( $OUT_TAR_FILE ),
646b39c5158Smillert                                    "   Tar file read in again" );
647b39c5158Smillert
648b39c5158Smillert        my ($obj) = $tar->get_files;
649b39c5158Smillert        ok( $obj,                   "       File retrieved" );
650b39c5158Smillert        isa_ok( $obj, $FClass,      "       Object" );
651b39c5158Smillert
652b39c5158Smillert        is( $obj->name, $COMPRESS_FILE,
653b39c5158Smillert                                    "       Name now set to '$COMPRESS_FILE'" );
654b39c5158Smillert        is( $obj->prefix, '',       "       Prefix now empty" );
655b39c5158Smillert
656b39c5158Smillert        my $re = quotemeta $COMPRESS_FILE;
657b39c5158Smillert        like( $obj->raw, qr/^$re/,  "       Prefix + name in name slot of header" );
658b39c5158Smillert    }
659b39c5158Smillert
660b39c5158Smillert    rm( $OUT_TAR_FILE ) unless $NO_UNLINK;
661b39c5158Smillert}
662b39c5158Smillert
663b39c5158Smillert### clean up stuff
664b39c5158SmillertEND {
665b39c5158Smillert    for my $struct ( \@EXPECT_NORMAL, \@EXPECTBIN, \@EXPECTX ) {
666b39c5158Smillert        for my $aref (@$struct) {
667b39c5158Smillert
668b39c5158Smillert            my $dir = $aref->[0]->[0];
669b39c5158Smillert            rmtree $dir if $dir && -d $dir && not $NO_UNLINK;
670b39c5158Smillert        }
671b39c5158Smillert    }
672b39c5158Smillert
673b39c5158Smillert    my ($dir) = File::Spec::Unix->splitdir( $LONG_FILE );
674b39c5158Smillert    rmtree $dir if $dir && -d $dir && not $NO_UNLINK;
675b39c5158Smillert    1 while unlink $COMPRESS_FILE;
676b39c5158Smillert}
677b39c5158Smillert
678b39c5158Smillert###########################
679b39c5158Smillert###     helper subs     ###
680b39c5158Smillert###########################
681b39c5158Smillertsub get_expect {
682b39c5158Smillert    return  map {
683b39c5158Smillert                split '/', $_
684b39c5158Smillert            } map {
685b39c5158Smillert                File::Spec::Unix->catfile(
686b39c5158Smillert                    grep { defined } @{$_->[0]}, $_->[1]
687b39c5158Smillert                )
688b39c5158Smillert            } @EXPECT_NORMAL;
689b39c5158Smillert}
690b39c5158Smillert
691b39c5158Smillertsub is_dir {
692b39c5158Smillert    my $file = pop();
693b39c5158Smillert    return $file =~ m|/$| ? 1 : 0;
694b39c5158Smillert}
695b39c5158Smillert
696b39c5158Smillertsub rm {
697b39c5158Smillert    my $x = shift;
698b39c5158Smillert    if  ( is_dir($x) ) {
699b39c5158Smillert         rmtree($x);
700b39c5158Smillert    } else {
701b39c5158Smillert         1 while unlink $x;
702b39c5158Smillert    }
703b39c5158Smillert}
704b39c5158Smillert
705b39c5158Smillertsub check_tar_file {
706b39c5158Smillert    my $file        = shift;
707b39c5158Smillert    my $filesize    = -s $file;
708b39c5158Smillert    my $contents    = slurp_binfile( $file );
709b39c5158Smillert
710b39c5158Smillert    ok( defined( $contents ),   "   File read" );
711b39c5158Smillert    ok( $filesize,              "   File written size=$filesize" );
712b39c5158Smillert
713b39c5158Smillert    cmp_ok( $filesize % BLOCK,     '==', 0,
714b39c5158Smillert                        "   File size is a multiple of 512" );
715b39c5158Smillert
716b39c5158Smillert    cmp_ok( length($contents), '==', $filesize,
717b39c5158Smillert                        "   File contents match size" );
718b39c5158Smillert
719b39c5158Smillert    is( TAR_END x 2, substr( $contents, -(BLOCK*2) ),
720b39c5158Smillert                        "   Ends with 1024 null bytes" );
721b39c5158Smillert
722b39c5158Smillert    return $contents;
723b39c5158Smillert}
724b39c5158Smillert
725b39c5158Smillertsub check_compressed_file {
726b39c5158Smillert    my $file                = shift;
727b39c5158Smillert    my $filesize            = -s $file;
728b39c5158Smillert    my $contents            = slurp_compressed_file( $file );
729b39c5158Smillert    my $uncompressedsize    = length $contents;
730b39c5158Smillert
731b39c5158Smillert    ok( defined( $contents ),   "   File read and uncompressed" );
732b39c5158Smillert    ok( $filesize,              "   File written size=$filesize uncompressed size=$uncompressedsize" );
733b39c5158Smillert
734b39c5158Smillert    cmp_ok( $uncompressedsize % BLOCK, '==', 0,
735b39c5158Smillert                                "   Uncompressed size is a multiple of 512" );
736b39c5158Smillert
737b39c5158Smillert    is( TAR_END x 2, substr($contents, -(BLOCK*2)),
738b39c5158Smillert                                "   Ends with 1024 null bytes" );
739b39c5158Smillert
740b39c5158Smillert    cmp_ok( $filesize, '<',  $uncompressedsize,
741b39c5158Smillert                                "   Compressed size < uncompressed size" );
742b39c5158Smillert
743b39c5158Smillert    return $contents;
744b39c5158Smillert}
745b39c5158Smillert
746b39c5158Smillertsub check_tar_object {
747b39c5158Smillert    my $obj     = shift;
748b39c5158Smillert    my $struct  = shift or return;
749b39c5158Smillert
750b39c5158Smillert    ### amount of files (not dirs!) there should be in the object
751b39c5158Smillert    my $expect  = scalar @$struct;
752b39c5158Smillert    my @files   = grep { $_->is_file } $obj->get_files;
753b39c5158Smillert
754b39c5158Smillert    ### count how many files there are in the object
755b39c5158Smillert    ok( scalar @files,          "   Found some files in the archive" );
756b39c5158Smillert    is( scalar @files, $expect, "   Found expected number of files" );
757b39c5158Smillert
758b39c5158Smillert    for my $file (@files) {
759b39c5158Smillert
760b39c5158Smillert        ### XXX ->fullname
761b39c5158Smillert        #my $path = File::Spec::Unix->catfile(
762b39c5158Smillert        #            grep { length } $file->prefix, $file->name );
763b39c5158Smillert        my($ename,$econtent) =
764b39c5158Smillert            get_expect_name_and_contents( $file->full_path, $struct );
765b39c5158Smillert
766b39c5158Smillert        ok( $file->is_file,     "   It is a file" );
767b39c5158Smillert        is( $file->full_path, $ename,
768b39c5158Smillert                                "   Name matches expected name" );
769b39c5158Smillert        like( $file->get_content, $econtent,
770b39c5158Smillert                                "   Content as expected" );
771b39c5158Smillert    }
772b39c5158Smillert}
773b39c5158Smillert
774b39c5158Smillertsub check_tar_extract {
775b39c5158Smillert    my $tar     = shift;
776b39c5158Smillert    my $struct  = shift;
777b39c5158Smillert
778b39c5158Smillert    my @dirs;
779b39c5158Smillert    for my $file ($tar->get_files) {
780b39c5158Smillert        push @dirs, $file && next if $file->is_dir;
781b39c5158Smillert
782b39c5158Smillert
783b39c5158Smillert        my $path = $file->full_path;
784b39c5158Smillert        my($ename,$econtent) =
785b39c5158Smillert            get_expect_name_and_contents( $path, $struct );
786b39c5158Smillert
787b39c5158Smillert
788b39c5158Smillert        is( $ename, $path,          "   Expected file found" );
789b39c5158Smillert        ok( -e $path,               "   File '$path' exists" );
790b39c5158Smillert
791b39c5158Smillert        my $fh;
792b39c5158Smillert        open $fh, "$path" or warn "Error opening file '$path': $!\n";
793b39c5158Smillert        binmode $fh;
794b39c5158Smillert
795b39c5158Smillert        ok( $fh,                    "   Opening file" );
796b39c5158Smillert
797b39c5158Smillert        my $content = do{local $/;<$fh>}; chomp $content;
798b39c5158Smillert        like( $content, qr/$econtent/,
799b39c5158Smillert                                    "   Contents OK" );
800b39c5158Smillert
801b39c5158Smillert        close $fh;
802b39c5158Smillert        $NO_UNLINK or 1 while unlink $path;
803b39c5158Smillert
804b39c5158Smillert        ### alternate extract path tests
805b39c5158Smillert        ### to abs and rel paths
806b39c5158Smillert        {   for my $outpath (   File::Spec->catdir( @ROOT ),
807b39c5158Smillert                                File::Spec->rel2abs(
808b39c5158Smillert                                    File::Spec->catdir( @ROOT )
809b39c5158Smillert                                )
810b39c5158Smillert            ) {
811b39c5158Smillert
812b39c5158Smillert                my $outfile = File::Spec->catfile( $outpath, $$ );
813b39c5158Smillert
814b39c5158Smillert                ok( $tar->extract_file( $file->full_path, $outfile ),
815b39c5158Smillert                                "   Extracted file '$path' to $outfile" );
816b39c5158Smillert                ok( -e $outfile,"   Extracted file '$outfile' exists" );
817b39c5158Smillert
818b39c5158Smillert                rm( $outfile ) unless $NO_UNLINK;
819b39c5158Smillert            }
820b39c5158Smillert        }
821b39c5158Smillert    }
822b39c5158Smillert
823b39c5158Smillert    ### now check if list_files is returning the same info as get_files
824b39c5158Smillert    is_deeply( [$tar->list_files], [ map { $_->full_path } $tar->get_files],
825b39c5158Smillert                                    "   Verified via list_files as well" );
826b39c5158Smillert
827b39c5158Smillert    #do { rmtree $_->full_path if -d $_->full_path && not $NO_UNLINK }
828b39c5158Smillert    #    for @dirs;
829b39c5158Smillert}
830b39c5158Smillert
831b39c5158Smillertsub slurp_binfile {
832b39c5158Smillert    my $file    = shift;
833b39c5158Smillert    my $fh      = IO::File->new;
834b39c5158Smillert
835b39c5158Smillert    $fh->open( $file ) or warn( "Error opening '$file': $!" ), return undef;
836b39c5158Smillert
837b39c5158Smillert    binmode $fh;
838b39c5158Smillert    local $/;
839b39c5158Smillert    return <$fh>;
840b39c5158Smillert}
841b39c5158Smillert
842b39c5158Smillertsub slurp_compressed_file {
843b39c5158Smillert    my $file = shift;
844b39c5158Smillert    my $fh;
845b39c5158Smillert
846de8cc8edSafresh1    ### xz
847de8cc8edSafresh1    if( $file =~ /.txz$/ ) {
848de8cc8edSafresh1        require IO::Uncompress::UnXz;
849de8cc8edSafresh1        $fh = IO::Uncompress::UnXz->new( $file )
850de8cc8edSafresh1            or warn( "Error opening '$file' with IO::Uncompress::UnXz" ), return
851de8cc8edSafresh1
852b39c5158Smillert    ### bzip2
853de8cc8edSafresh1    } elsif( $file =~ /.tbz$/ ) {
854b39c5158Smillert        require IO::Uncompress::Bunzip2;
855b39c5158Smillert        $fh = IO::Uncompress::Bunzip2->new( $file )
856b39c5158Smillert            or warn( "Error opening '$file' with IO::Uncompress::Bunzip2" ), return
857b39c5158Smillert
858b39c5158Smillert    ### gzip
859b39c5158Smillert    } else {
860b39c5158Smillert        require IO::Zlib;
861256a93a4Safresh1        $fh = IO::Zlib->new();
862b39c5158Smillert        $fh->open( $file, READ_ONLY->(1) )
863b39c5158Smillert            or warn( "Error opening '$file' with IO::Zlib" ), return
864b39c5158Smillert    }
865b39c5158Smillert
866b39c5158Smillert    my $str;
867b39c5158Smillert    my $buff;
868b39c5158Smillert    $str .= $buff while $fh->read( $buff, 4096 ) > 0;
869b39c5158Smillert    $fh->close();
870b39c5158Smillert
871b39c5158Smillert    return $str;
872b39c5158Smillert}
873b39c5158Smillert
874b39c5158Smillertsub get_expect_name_and_contents {
875b39c5158Smillert    my $find    = shift;
876b39c5158Smillert    my $struct  = shift or return;
877b39c5158Smillert
878b39c5158Smillert    ### find the proper name + contents for this file from
879b39c5158Smillert    ### the expect structure
880b39c5158Smillert    my ($name, $content) =
881b39c5158Smillert        map {
882b39c5158Smillert            @$_;
883b39c5158Smillert        } grep {
884b39c5158Smillert            $_->[0] eq $find
885b39c5158Smillert        } map {
886b39c5158Smillert            [   ### full path ###
887b39c5158Smillert                File::Spec::Unix->catfile(
888b39c5158Smillert                    grep { length } @{$_->[0]}, $_->[1]
889b39c5158Smillert                ),
890b39c5158Smillert                ### regex
891b39c5158Smillert                $_->[2],
892b39c5158Smillert            ]
893b39c5158Smillert        } @$struct;
894b39c5158Smillert
895b39c5158Smillert    ### not a qr// yet?
896b39c5158Smillert    unless( ref $content ) {
897b39c5158Smillert        my $x     = quotemeta ($content || '');
898b39c5158Smillert        $content = qr/$x/;
899b39c5158Smillert    }
900b39c5158Smillert
901b39c5158Smillert    unless( $name ) {
902b39c5158Smillert        warn "Could not find '$find' in " . Dumper $struct;
903b39c5158Smillert    }
904b39c5158Smillert
905b39c5158Smillert    return ($name, $content);
906b39c5158Smillert}
907b39c5158Smillert
908b39c5158Smillert__END__
909