Enforcing strict & warning as a .t file

petdance on 2002-10-10T16:39:31

Acme found that he had files that didn't use strict. I found that, too, and I wrote a .t file for it. Here it is:

#!/usr/bin/perl -w

use strict; use File::Spec; use File::Find::Rule;

use Test::More 'no_plan';

my $base = (shift || $ENV{TWROOT} || '.');

my $rule = File::Find::Rule->new; $rule->or( $rule->new->directory->name('CVS')->prune->discard, $rule->new->file->name( '*.pl','*.pm','*.t' ) ); my @files = $rule->in( $base );

for my $file ( @files ) { check( $file ); }

sub check { my $filename = shift;

my $dispname = File::Spec->abs2rel( $filename, $base );

local $/ = undef;

open( my $fh, $filename ) or return fail( "Couldn't open $dispname: $!" ); my $text = <$fh>; close $fh;

# Search for strict and warnings. You can get around this just by # having the text in comments, but that's not the point. ok( $text =~ /use strict;/, "$dispname uses strict" ); ok( $text =~ /use warnings;|perl -w/, "$dispname uses warnings" ); }


Ergh

chromatic on 2002-10-10T17:22:27

I was about to ask why you didn't use like() instead of ok(). Then I realized exactly how verbose a failure message would be. Good thinking.

Oooh

acme on 2002-10-10T18:13:42

I almost posted my code - which is eerily similar to yours. I actually count the number of files in a BEGIN block and hence get a test plan, but the code is basically the same. Ain't testing great ;-)

Re:Oooh

petdance on 2002-10-10T18:26:26

I almost posted my code - which is eerily similar to yours. I actually count the number of files in a BEGIN block and hence get a test plan, but the code is basically the same. Ain't testing great ;-)

Yes, testing IS great. :-)

I don't count the files because I don't know how many tests per file I'm going to have, and I may actually have a different number of tests for each file.

One of the things I was talking with Farmer Schwern about at YAPC::NA was the possibility of having a count of tests, with a variable number of subtests. Something like:

1..4
ok 1 - Loaded
ok 2 - Built list of files to check
block 3 - Starting foo.pl
ok 1 - Did this in foo.pl
ok 2 - Did something else
ok 3 - Did another thing
ok block 3
block 4 - Starting foo.pm
not ok 1 - foo.pm doesn't have warnings
ok 2 - foo.pm has strict
not ok block 4
There are a total of 4 top-level tests, with subtests under top-level tests #3 and #4.

Please don't bother picking on specifics of that implementation: I made it up off the top of my head. The key here is that in some cases you may not know the TOTAL number of tests including subtests, but you do know the number of files to be checking.

But does it *really* use strict?

brian_d_foy on 2002-10-10T19:45:19

How about catching the cheating programmers who put the string "use strict" somewhere in their program?
#use strict;
#Andy says to use strict, but i don't like it
Module::Info can do that :)

Re:But does it *really* use strict?

petdance on 2002-10-10T19:56:17

It's a known issue. Note:
# Search for strict and warnings.  You can get around this just by
# having the text in comments, but that's not the point.
ok( $text =~ /use strict;/,             "$dispname uses strict" );
ok( $text =~ /use warnings;|perl -w/,   "$dispname uses warnings" );

The code is to catch mistakes, not malfeasance. There's also nothing stopping you from doing

use strict;
no strict;
At that point, it's a management issue, not a technical one.

Re:But does it *really* use strict?

pudge on 2002-10-16T02:49:33

False negatives are also a problem, FWIW.
#!/usr/bin/perl -Tw
use  strict;