Skip to content

Commit

Permalink
first cut at file_contains_like
Browse files Browse the repository at this point in the history
this addresses GitHub issue briandfoy#3
code and tests; added to test_manifest and MANIFEST
added POD
still need to allow multiple tests on the contents
also should add file_contains_unlike
  • Loading branch information
barefootcoder committed Jan 2, 2012
1 parent 46b9a4c commit cba254e
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 1 deletion.
1 change: 1 addition & 0 deletions MANIFEST
Expand Up @@ -6,6 +6,7 @@ Makefile.PL
MANIFEST This list of files
README
t/dm_skeleton.t
t/file_contains.t
t/file_sizes.t
t/line_counters.t
t/link_counts.t
Expand Down
63 changes: 62 additions & 1 deletion lib/File.pm
Expand Up @@ -21,6 +21,7 @@ use Test::Builder;
owner_is owner_isnt
group_is group_isnt
file_line_count_is file_line_count_isnt file_line_count_between
file_contains_like
);

$VERSION = '1.28';
Expand Down Expand Up @@ -504,7 +505,67 @@ sub file_line_count_between
}

}


=item file_contains_like ( FILENAME, PATTERN [, NAME ] )
Ok if the file exists and its contents (as one big string) match
PATTERN, not ok if the file does not exist, is not readable, or exists
but doesn't match PATTERN.
Since the file contents are read into memory, you should not use this
for large files. Besides memory consumption, test diagnostics for
failing tests might be difficult to decipher. However, for short
files this works very well.
Because the entire contents are treated as one large string, you can
make a pattern that tests multiple lines. Don't forget that you may
need to use the /s modifier for such patterns:
# make sure file has one or more paragraphs with CSS class X
file_contains_like($html_file, qr{<p class="X">.*?</p>}s);
Contrariwise, if you need to match at the beginning or end of a line
inside the file, use the /m modifier:
# make sure file has a setting for foo
file_contains_like($config_file, qr/^ foo \s* = \s* bar $/mx);
=cut

sub file_contains_like
{
my $filename = _normalize( shift );
my $pattern = shift;
my $name = shift || "$filename contains $pattern";

unless( -e $filename )
{
$Test->diag( "File [$filename] does not exist!" );
return $Test->ok(0, $name);
}

unless( -r $filename )
{
$Test->diag( "File [$filename] is not readable!" );
return $Test->ok(0, $name);
}

# do the slurp
my $file_contents;
{
unless (open(FH, $filename))
{
$Test->diag( "Could not open [$filename]: \$! is [$!]!" );
return $Test->ok( 0, $name );
}
local $/ = undef;
$file_contents = <FH>;
close FH;
}

return $Test->like($file_contents, $pattern, $name);
}

=item file_readable_ok( FILENAME [, NAME ] )
Ok if the file exists and is readable, not ok
Expand Down
69 changes: 69 additions & 0 deletions t/file_contains.t
@@ -0,0 +1,69 @@
use strict;
use warnings;

use Test::Builder::Tester;
use Test::More 0.88;
use Test::File;


my $test_directory = 'test_files';
require "t/setup_common" unless -d $test_directory;

chdir $test_directory or print "bail out! Could not change directories: $!";


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

my $file = 'min_file';
my $contents = do { open FH, $file; local $/; <FH> }; close FH;
my $pattern1 = 'x' x 11; $pattern1 = qr/^ $pattern1 $/mx;
my $pattern2 = 'x' x 40; $pattern2 = qr/^ $pattern2 $/mx;
my $bad_pattern = 'x' x 20; $bad_pattern = qr/^ $bad_pattern $/mx;

test_out( "ok 1 - min_file contains $pattern1" );
file_contains_like( $file, $pattern1 );
test_test();

test_out( "not ok 1 - bmoogle contains $pattern1" );
test_diag( 'File [bmoogle] does not exist!' );
test_fail(+1);
file_contains_like( 'bmoogle', $pattern1 );
test_test();

test_out( "not ok 1 - not_readable contains $pattern1" );
test_diag( 'File [not_readable] is not readable!' );
test_fail(+1);
file_contains_like( 'not_readable', $pattern1 );
test_test();

test_out( "not ok 1 - min_file contains $bad_pattern" );
test_fail(+2);
like_diag($contents, $bad_pattern);
file_contains_like( 'min_file', $bad_pattern );
test_test();


done_testing();


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

END {
chdir '..' or print "bail out! Could not change directories: $!";
unlink glob( "test_files/*" );
rmdir "test_files";
}


# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

sub like_diag
{
my ($string, $pattern) = @_;

my $diag = ' ' x 18 . "'$string'\n";
$diag .= ' ' x 4 . "doesn't match '$pattern'";
$diag =~ s/^/# /mg;

test_err($diag);
}
1 change: 1 addition & 0 deletions t/test_manifest
Expand Up @@ -11,5 +11,6 @@ links.t
link_counts.t
line_counters.t
file_sizes.t
file_contains.t
owner.t
rt/30346.t

0 comments on commit cba254e

Please sign in to comment.