File: synopsis.t

package info (click to toggle)
libtest-files-perl 0.26-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 352 kB
  • sloc: perl: 406; makefile: 7
file content (197 lines) | stat: -rw-r--r-- 9,416 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# This implements all test cases mentioned in SYNOPSIS.
# To make it runnable, the following changes have been done:
#   - Test::Expander used instead of Path::Tiny (this includes both Path::Tiny and Test2::V0).
#   - $PATH referring to a temporary directory used instead of path( 'path' ).
#   - The necessary directory structure and test files creation implemented.

use strict;
use warnings
  FATAL    => qw( all ),
  NONFATAL => qw( deprecated exec internal malloc newline once portable redefine recursion uninitialized );

use Test::Expander -tempdir => {};
use Test::Files;

use Archive::Zip          qw( :ERROR_CODES );
use File::Copy::Recursive qw( dircopy );

const my $PATH => path( $TEMP_DIR );

my $got_file       = $PATH->child( qw( got file ) );
my $reference_file = $PATH->child( qw( reference file ) );
my $got_dir        = $PATH->child( qw( got dir ) );
my $reference_dir  = $PATH->child( qw( reference dir with some stuff ) );
my @file_list      = qw( expected file );
my ( $content_check, $expected, $filter, $options );

plan( 24 );

# Simply compares file contents to a string:
$expected = "contents\nof file";
$got_file->parent->mkdir;
$got_file->spew( $expected );
file_ok( $got_file, $expected, 'got file has expected contents' );

# Two identical variants comparing file contests to a string ignoring differences in time stamps:
$expected = "filtered contents\nof file\ncreated at 00:00:00";
$got_file->spew( $expected =~ s/00:00:00/12:34:56/r );
$filter   = sub { shift =~ s{ \b (?: [01] \d | 2 [0-3] ) : (?: [0-5] \d ) : (?: [0-5] \d ) \b }{00:00:00}grx };
$options  = { FILTER => $filter };
file_ok       ( $got_file, $expected, $options, "'$got_file' has contents expected after filtering" );
file_filter_ok( $got_file, $expected, $filter,  "'$got_file' has contents expected after filtering" );

# Simply compares two file contents:
$reference_file->parent->mkdir;
$got_file->copy( $reference_file );
compare_ok( $got_file, $reference_file, 'files are the same' );

# Two identical variants comparing contents of two files ignoring differences in time stamps:
$got_file->spew( $expected );
$filter   = sub { shift =~ s{ \b (?: [01] \d | 2 [0-3] ) : (?: [0-5] \d ) : (?: [0-5] \d ) \b }{00:00:00}grx };
$options = { FILTER => $filter };
compare_ok       ( $got_file, $reference_file, $options, 'files are almost the same' );
compare_filter_ok( $got_file, $reference_file, $filter,  'files are almost the same' );

# Verifies if both got file and reference file exist:
$options = { EXISTENCE_ONLY => 1 };
compare_ok( $got_file, $reference_file, $options, 'both files exist' );

# Verifies if got file and reference file have identical size:
$options = { SIZE_ONLY => 1 };
compare_ok( $got_file, $reference_file, $options, 'both files have identical size' );

# Verifies if the directory has all expected files (not recursively!):
$expected = [ qw( files got_dir must contain ) ];
$got_dir->child( 'subdir' )->mkdir;
$got_dir->child( $_ )->touch foreach @$expected, 'additional_file';
$got_dir->child( 'subdir' )->child( 'file_in_subdir' )->touch;
dir_contains_ok( $got_dir, $expected, 'directory has all files in list' );

# Two identical variants doing the same verification as before,
# but additionally verifying if the directory has nothing but the expected files (not recursively!):
$options = { SYMMETRIC => 1 };
$got_dir->child( 'additional_file' )->remove;
dir_contains_ok     ( $got_dir, $expected, $options, 'directory has exactly the files in the list' );
dir_only_contains_ok( $got_dir, $expected,           'directory has exactly the files in the list' );

# The same as before, but recursive:
$options = { RECURSIVE => 1, SYMMETRIC => 1 };
$expected = [ @$expected, 'subdir/file_in_subdir' ];
dir_contains_ok( $got_dir, $expected, $options, 'directory and its subdirectories have exactly the files in the list' );

# The same as before, but ignoring files, which names do not match the required pattern (file "must" will be skipped):
$options = { NAME_PATTERN => '^[cfg]', RECURSIVE => 1, SYMMETRIC => 1 };
$got_dir->child( 'must' )->remove;
dir_contains_ok(
  $got_dir, $expected, $options,
  "directory and its subdirectories have exactly the files in the list except of file 'must'"
);

# Compares two directories by comparing file contents (not recursively!):
dircopy( $got_dir, $reference_dir );
$reference_dir->child( 'subdir' )->remove_tree;
compare_dirs_ok(
  $got_dir, $reference_dir,
  "all files from '$got_dir' are the same in '$reference_dir' (same names, same contents), subdirs are skipped"
);

# The same as before, but subdirectories are considered, too:
dircopy( $got_dir, $reference_dir );
$options = { RECURSIVE => 1 };
compare_dirs_ok(
  $got_dir, $reference_dir, $options, "all files from '$got_dir' and its subdirs are the same in '$reference_dir'"
);

# The same as before, but only file sizes are compared:
$got_dir      ->child( 'contain' )->spew( 'abc' );
$reference_dir->child( 'contain' )->spew( 'xyz' );
$options = { RECURSIVE => 1, SIZE_ONLY => 1 };
compare_dirs_ok(
  $got_dir, $reference_dir, $options, "all files from '$got_dir' and its subdirs have same sizes in '$reference_dir'"
);

# The same as before, but only file existence is verified:
$reference_dir->child( 'contain' )->spew( 'some longer text' );
$options = { EXISTENCE_ONLY => 1, RECURSIVE => 1 };
compare_dirs_ok(
  $got_dir, $reference_dir, $options, "all files from '$got_dir' and its subdirs exist in '$reference_dir'"
);

# The same as before, but only files with base names starting with 'A' are considered:
$got_dir      ->child( 'contain' )->remove;
$got_dir      ->child( 'A.txt' )->touch;
$reference_dir->child( 'A.txt' )->touch;
$reference_dir->child( qw( subdir A.txt ) )->touch;
$options = { EXISTENCE_ONLY => 1, NAME_PATTERN => '^A', RECURSIVE => 1 };
compare_dirs_ok(
  $got_dir, $reference_dir, $options,
  "all files from '$got_dir' and its subdirs with base names starting with 'A' exist in '$reference_dir'"
);

# The same as before, but the symmetric verification is requested:
$got_dir->child( qw( subdir A.txt ) )->touch;
$options = { EXISTENCE_ONLY => 1, NAME_PATTERN => '^A', RECURSIVE => 1, SYMMETRIC => 1 };
compare_dirs_ok(
  $got_dir, $reference_dir, $options,
  "all files from '$got_dir' and its subdirs with base names starting with 'A' exist in '$reference_dir' and vice versa"
);

# Two identical version of comparison of two directories by file contents,
# whereas these contents are first filtered so that time stamps in form of 'HH:MM:SS' are replaced by '00:00:00'
# like in examples for file_filter_ok and compare_filter_ok:
dircopy( $reference_dir, $got_dir );
$expected = "filtered contents\nof file\ncreated at 00:00:00";
$got_dir      ->child( 'A.txt' )->spew( $expected =~ s/00:00:00/12:34:56/r );
$reference_dir->child( 'A.txt' )->spew( $expected =~ s/00:00:00/21:43:05/r );
$filter   = sub { shift =~ s{ \b (?: [01] \d | 2 [0-3] ) : (?: [0-5] \d ) : (?: [0-5] \d ) \b }{00:00:00}grx };
$options = { FILTER => $filter };
compare_dirs_ok(
  $got_dir, $reference_dir, $options,
  "all files from '$got_dir' are the same in '$reference_dir', subdirs are skipped, differences of time stamps ignored"
);
compare_dirs_filter_ok(
  $got_dir, $reference_dir, $filter,
  "all files from '$got_dir' are the same in '$reference_dir', subdirs are skipped, differences of time stamps ignored"
);

# Verifies if all plain files in directory and its subdirectories contain the word 'good'
# (take into consideration the -f test below excluding special files from comparison!):
$got_dir->visit( sub { $_->spew( 'This is a good plain file!' ) unless $_->is_dir }, { recurse => 1 } );
$content_check = sub { my ( $file ) = @_; not -f $file or path( $file )->slurp =~ / \b good \b /x };
$options       = { RECURSIVE => 1 };
find_ok( $got_dir, $content_check, $options, "all files from '$got_dir' and subdirectories contain the word 'good'" );

# Compares PKZIP archives considering both global and file comments.
# Both archives contain the same members in different order:
my @fileNos = ( 0, 1 );
foreach my $archive ( $got_file, $reference_file ) {
  my $zip = Archive::Zip->new();
  $zip->zipfileComment( 'Global comment' );
  $zip->addString( "This is file No. $_", "file_$_" )->fileComment( "Some comment to file No. $_" ) foreach @fileNos;
  bail_out( "Cannot create '$archive.zip'" ) if $zip->writeToFileNamed( "$archive.zip" ) != AZ_OK;
  @fileNos = reverse( @fileNos );
}
my $extract = sub {
  my ( $file ) = @_;
  my $zip = Archive::Zip->new();
  die( "Cannot read '$file'" ) if $zip->read( $file ) != AZ_OK;
  die( "Cannot extract from '$file'" ) if $zip->extractTree != AZ_OK;
};
my $meta_data = sub {
  my ( $file ) = @_;
  my $zip = Archive::Zip->new();
  die( "Cannot read '$file'" ) if $zip->read( $file ) != AZ_OK;
  my %meta_data = ( '' => $zip->zipfileComment );
  $meta_data{ $_->fileName } = $_->fileComment foreach $zip->members;
  return \%meta_data;
};
my $got_compressed_content       = path( "$got_file.zip"       )->slurp;
my $reference_compressed_content = path( "$reference_file.zip" )->slurp;
ok(
  $got_compressed_content ne $reference_compressed_content,
  "'$got_file.zip' and '$reference_file.zip' are physically different, but"
);
compare_archives_ok(
  "$got_file.zip", "$reference_file.zip", { EXTRACT => $extract, META_DATA => $meta_data },
  "'$got_file.zip' and '$reference_file.zip' are logically identical"
);