3 ##############################################################################
4 # $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/t/05_utils.t $
5 # $Date: 2008-06-06 00:48:04 -0500 (Fri, 06 Jun 2008) $
8 ##############################################################################
16 use Test::More tests => 115;
18 #-----------------------------------------------------------------------------
22 # Needs to be in BEGIN for global vars
23 use_ok('Perl::Critic::Utils', qw{ :all } );
26 #-----------------------------------------------------------------------------
29 can_ok('main', 'all_perl_files');
30 can_ok('main', 'find_keywords');
31 can_ok('main', 'interpolate');
32 can_ok('main', 'is_hash_key');
33 can_ok('main', 'is_method_call');
34 can_ok('main', 'is_perl_builtin');
35 can_ok('main', 'is_perl_global');
36 can_ok('main', 'is_script');
37 can_ok('main', 'is_subroutine_name');
38 can_ok('main', 'first_arg');
39 can_ok('main', 'parse_arg_list');
40 can_ok('main', 'policy_long_name');
41 can_ok('main', 'policy_short_name');
42 can_ok('main', 'precedence_of');
43 can_ok('main', 'severity_to_number');
44 can_ok('main', 'shebang_line');
45 can_ok('main', 'verbosity_to_format');
46 can_ok('main', 'is_unchecked_call');
48 is($SPACE, ' ', 'character constants');
49 is($SEVERITY_LOWEST, 1, 'severity constants');
50 is($POLICY_NAMESPACE, 'Perl::Critic::Policy', 'Policy namespace');
52 #-----------------------------------------------------------------------------
55 sub count_matches { my $val = shift; return defined $val ? scalar @$val : 0; }
56 sub make_doc { my $code = shift; return PPI::Document->new( ref $code ? $code : \$code); }
59 my $doc = PPI::Document->new(); #Empty doc
60 is( count_matches( find_keywords($doc, 'return') ), 0, 'find_keywords, no doc' );
63 $doc = make_doc( $code );
64 is( count_matches( find_keywords($doc, 'return') ), 1, 'find_keywords, find 1');
66 $code = 'sub foo { }';
67 $doc = make_doc( $code );
68 is( count_matches( find_keywords($doc, 'return') ), 0, 'find_keywords, find 0');
70 $code = 'sub foo { return 1; }';
71 $doc = make_doc( $code );
72 is( count_matches( find_keywords($doc, 'return') ), 1, 'find_keywords, find 1');
74 $code = 'sub foo { return 0 if @_; return 1; }';
75 $doc = make_doc( $code );
76 is( count_matches( find_keywords($doc, 'return') ), 2, 'find_keywords, find 2');
79 #-----------------------------------------------------------------------------
83 my $code = 'sub foo { return $h1{bar}, $h2->{baz}, $h3->{ nuts() } }';
84 my $doc = PPI::Document->new(\$code);
85 my @words = @{$doc->find('PPI::Token::Word')};
94 is(scalar @words, scalar @expect, 'is_hash_key count');
95 for my $i (0 .. $#expect)
97 is($words[$i], $expect[$i][0], 'is_hash_key word');
98 is(is_hash_key($words[$i]), $expect[$i][1], 'is_hash_key boolean');
102 #-----------------------------------------------------------------------------
108 "#!/usr/bin/perl -w\n",
109 "#!C:\\Perl\\bin\\perl\n",
118 for my $code (@good) {
119 my $doc = PPI::Document->new(\$code) || die;
120 $doc->index_locations();
121 ok(is_script($doc), 'is_script, true');
124 for my $code (@bad) {
125 my $doc = PPI::Document->new(\$code) || die;
126 $doc->index_locations();
127 ok(!is_script($doc), 'is_script, false');
130 #-----------------------------------------------------------------------------
131 # is_perl_builtin tests
134 is( is_perl_builtin('print'), 1, 'Is perl builtin function' );
135 isnt( is_perl_builtin('foobar'), 1, 'Is not perl builtin function' );
137 my $code = 'sub print {}';
138 my $doc = make_doc( $code );
139 my $sub = $doc->find_first('Statement::Sub');
140 is( is_perl_builtin($sub), 1, 'Is perl builtin function (PPI)' );
142 $code = 'sub foobar {}';
143 $doc = make_doc( $code );
144 $sub = $doc->find_first('Statement::Sub');
145 isnt( is_perl_builtin($sub), 1, 'Is not perl builtin function (PPI)' );
149 #-----------------------------------------------------------------------------
150 # is_perl_global tests
153 is( is_perl_global('$OSNAME'), 1, '$OSNAME is a perl global var' );
154 is( is_perl_global('*STDOUT'), 1, '*STDOUT is a perl global var' );
155 isnt( is_perl_global('%FOOBAR'), 1, '%FOOBAR is a not perl global var' );
157 my $code = '$OSNAME';
158 my $doc = make_doc($code);
159 my $var = $doc->find_first('Token::Symbol');
160 is( is_perl_global($var), 1, '$OSNAME is perl a global var (PPI)' );
163 $doc = make_doc($code);
164 $var = $doc->find_first('Token::Symbol');
165 is( is_perl_global($var), 1, '*STDOUT is perl a global var (PPI)' );
168 $doc = make_doc($code);
169 $var = $doc->find_first('Token::Symbol');
170 isnt( is_perl_global($var), 1, '%FOOBAR is not a perl global var (PPI)' );
174 #-----------------------------------------------------------------------------
175 # precedence_of tests
179 cmp_ok( precedence_of('*'), '<', precedence_of('+'), 'Precedence' );
182 my $doc1 = make_doc($code1);
183 my $op1 = $doc1->find_first('Token::Operator');
186 my $doc2 = make_doc($code2);
187 my $op2 = $doc2->find_first('Token::Operator');
189 cmp_ok( precedence_of($op2), '<', precedence_of($op1), 'Precedence (PPI)' );
193 #-----------------------------------------------------------------------------
194 # is_subroutine_name tests
198 my $code = 'sub foo {}';
199 my $doc = make_doc( $code );
200 my $word = $doc->find_first( sub { $_[1] eq 'foo' } );
201 is( is_subroutine_name( $word ), 1, 'Is a subroutine name');
203 $code = '$bar = foo()';
204 $doc = make_doc( $code );
205 $word = $doc->find_first( sub { $_[1] eq 'foo' } );
206 isnt( is_subroutine_name( $word ), 1, 'Is not a subroutine name');
210 #-----------------------------------------------------------------------------
211 # policy_long_name and policy_short_name tests
214 my $short_name = 'Baz::Nuts';
215 my $long_name = "${POLICY_NAMESPACE}::$short_name";
216 is( policy_long_name( $short_name ), $long_name, 'policy_long_name' );
217 is( policy_long_name( $long_name ), $long_name, 'policy_long_name' );
218 is( policy_short_name( $short_name ), $short_name, 'policy_short_name' );
219 is( policy_short_name( $long_name ), $short_name, 'policy_short_name' );
222 #-----------------------------------------------------------------------------
223 # interpolate() tests
225 is( interpolate( '\r%l\t%c\n' ), "\r%l\t%c\n", 'Interpolation' );
226 is( interpolate( 'literal' ), "literal", 'Interpolation' );
229 #-----------------------------------------------------------------------------
230 # Test _is_perl() and shebang_line() subroutines.
233 for ( qw(foo.t foo.pm foo.pl foo.PL) ) {
234 ok( Perl::Critic::Utils::_is_perl($_), qq{Is perl: '$_'} );
237 for ( qw(foo.doc foo.txt foo.conf foo) ) {
238 ok( ! Perl::Critic::Utils::_is_perl($_), qq{Is not perl: '$_'} );
241 use File::Temp qw<tempfile>;
243 my @perl_shebangs = (
245 '#!/usr/local/bin/perl',
246 '#!/usr/local/bin/perl-5.8',
248 '#!perl ## no critic',
249 '#!perl ## no critic (foo)',
252 for my $shebang (@perl_shebangs) {
253 my ($fh, $filename) = tempfile() or die 'Could not open tempfile';
254 print {$fh} "$shebang\n"; close $fh; # Must close to flush buffer
255 ok( Perl::Critic::Utils::_is_perl($filename), qq{Is perl: '$shebang'});
257 my $document = PPI::Document->new(\$shebang);
259 Perl::Critic::Utils::shebang_line($document),
261 qq<shebang_line($shebang)>,
265 my @not_perl_shebangs = (
271 for my $shebang (@not_perl_shebangs) {
272 my ($fh, $filename) = tempfile or die 'Could not open tempfile';
273 print {$fh} "$shebang\n"; close $fh; # Must close to flush buffer
274 ok( ! Perl::Critic::Utils::_is_perl($filename), qq{Is not perl: '$shebang'});
276 my $document = PPI::Document->new(\$shebang);
278 Perl::Critic::Utils::shebang_line($document),
279 ($shebang eq 'shazbot' ? undef : $shebang),
280 qq<shebang_line($shebang)>,
285 #-----------------------------------------------------------------------------
289 for ( qw( foo.swp foo.bak foo~ ), '#foo#' ) {
290 ok( Perl::Critic::Utils::_is_backup($_), qq{Is backup: '$_'} );
293 for ( qw( swp.pm Bak ~foo ) ) {
294 ok( ! Perl::Critic::Utils::_is_backup($_), qq{Is not backup: '$_'} );
298 #-----------------------------------------------------------------------------
303 q{eval { some_code() };} => q{{ some_code() }},
304 q{eval( {some_code() } );} => q{{some_code() }},
308 for (my $i = 0; $i < @tests; $i += 2) {
309 my $code = $tests[$i];
310 my $expect = $tests[$i+1];
311 my $doc = PPI::Document->new(\$code);
312 my $got = first_arg($doc->first_token());
313 is($got ? "$got" : undef, $expect, 'first_arg - '.$code);
317 #-----------------------------------------------------------------------------
318 # parse_arg_list tests
322 [ q/foo($bar, 'baz', 1)/ => [ [ q<$bar> ], [ q<'baz'> ], [ q<1> ], ] ],
324 q/foo( { bar => 1 }, { bar => 1 }, 'blah' )/
332 q/foo( { bar() }, {}, 'blah' )/
341 foreach my $test (@tests) {
342 my ($code, $expected) = @{ $test };
344 my $document = PPI::Document->new( \$code );
345 my @got = parse_arg_list( $document->first_token() );
346 is_deeply( \@got, $expected, "parse_arg_list: $code" );
350 #-----------------------------------------------------------------------------
353 my $code = 'sub foo{}';
354 my $doc = PPI::Document->new( \$code );
355 my $words = $doc->find('PPI::Token::Word');
356 is(scalar @{$words}, 2, 'count PPI::Token::Words');
357 is((scalar grep {is_function_call($_)} @{$words}), 0, 'is_function_call');
360 #-----------------------------------------------------------------------------
363 use Perl::Critic::PolicyFactory;
364 use Perl::Critic::TestUtils qw(bundled_policy_names);
365 Perl::Critic::TestUtils::block_perlcriticrc();
368 my @native_policies = bundled_policy_names();
369 my $policy_dir = File::Spec->catfile( qw(lib Perl Critic Policy) );
370 my @found_policies = all_perl_files( $policy_dir );
371 is( scalar @found_policies, scalar @native_policies, 'Find all perl code');
373 #-----------------------------------------------------------------------------
374 # is_unchecked_call tests
377 # just an obvious failure to check the return value
378 { code => q( open( $fh, $mode, $filename ); ),
380 # check the value with a trailing conditional
381 { code => q( open( $fh, $mode, $filename ) or die 'unable to open'; ),
383 # assign the return value to a variable (and assume that it's checked later)
384 { code => q( my $error = open( $fh, $mode, $filename ); ),
386 # the system call is in a conditional
387 { code => q( return $EMPTY if not open my $fh, '<', $file; ),
389 # open call in list context, checked with 'not'
390 { code => q( return $EMPTY if not ( open my $fh, '<', $file ); ),
392 # just putting the system call in a list context doesn't mean the return value is checked
393 { code => q( ( open my $fh, '<', $file ); ),
397 foreach my $trial ( @trials ) {
398 my $doc = make_doc( $trial->{'code'} );
399 my $statement = $doc->find_first( sub { $_[1] eq 'open' } );
400 if ( $trial->{'pass'} ) {
401 ok( is_unchecked_call( $statement ), 'is_unchecked_call returns true' );
403 ok( ! is_unchecked_call( $statement ), 'is_unchecked_call returns false' );
408 #-----------------------------------------------------------------------------
410 # ensure we run true if this test is loaded by
411 # t/05_utils.t_without_optional_dependencies.t
416 # cperl-indent-level: 4
418 # indent-tabs-mode: nil
419 # c-indentation-style: bsd
421 # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :