Move several functions to Utilities.pm
authorJames E. Keenan <jkeenan@cpan.org>
Sun, 11 Apr 2010 17:52:39 +0000 (13:52 -0400)
committerSteffen Mueller <smueller@cpan.org>
Tue, 12 Jul 2011 18:53:56 +0000 (20:53 +0200)
Namely: check_conditional_preprocessor_statements(), Warn(),
blurt() and death() to Utilities.pm.

Add file to test blurt, death and Warn.  (death() is not
really testable yet due to hard-coded 'exit'.)  ovid++, rjbs++,
xdg+++ for assistance in developing tests."

MANIFEST
dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Utilities.pm
dist/ExtUtils-ParseXS/t/113-check_cond_preproc_statements.t
dist/ExtUtils-ParseXS/t/114-blurt_death_Warn.t [new file with mode: 0644]

index 577eb58..cff5970 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -2995,6 +2995,7 @@ dist/ExtUtils-ParseXS/t/110-assign_func_args.t                    ExtUtils::ParseXS tests
 dist/ExtUtils-ParseXS/t/111-print_preprocessor_statements.t    ExtUtils::ParseXS tests
 dist/ExtUtils-ParseXS/t/112-set_cond.t                         ExtUtils::ParseXS tests
 dist/ExtUtils-ParseXS/t/113-check_cond_preproc_statements.t    ExtUtils::ParseXS tests
+dist/ExtUtils-ParseXS/t/114-blurt_death_Warn.t                 ExtUtils::ParseXS tests
 dist/ExtUtils-ParseXS/t/lib/IncludeTester.pm                   ExtUtils::ParseXS testing utility
 dist/ExtUtils-ParseXS/t/pseudotypemap1                         A test-typemap
 dist/ExtUtils-ParseXS/t/typemap                                        Standard typemap for controlled testing
index f6b3333..37f6552 100644 (file)
@@ -23,8 +23,11 @@ use ExtUtils::ParseXS::Utilities qw(
   assign_func_args
   print_preprocessor_statements
   set_cond
+  Warn
+  blurt
+  death
+  check_conditional_preprocessor_statements
 );
-#  check_conditional_preprocessor_statements
 
 our @ISA = qw(Exporter);
 our @EXPORT_OK = qw(
@@ -1364,7 +1367,7 @@ sub SCOPE_handler () {
     if $self->{scope_in_this_xsub}++;
 
   trim_whitespace($_);
-  death ("Error: SCOPE: ENABLE/DISABLE")
+  death("Error: SCOPE: ENABLE/DISABLE")
       unless /^(ENABLE|DISABLE)\b/i;
   $self->{ScopeThisXSUB} = ( uc($1) eq 'ENABLE' );
 }
@@ -1376,7 +1379,7 @@ sub PROTOTYPES_handler () {
   trim_whitespace($_);
 
   # check for ENABLE/DISABLE
-  death ("Error: PROTOTYPES: ENABLE/DISABLE")
+  death("Error: PROTOTYPES: ENABLE/DISABLE")
     unless /^(ENABLE|DISABLE)/i;
 
   $self->{WantPrototypes} = 1 if $1 eq 'ENABLE';
@@ -1552,29 +1555,6 @@ EOF
   return 1;
 }
 
-sub check_conditional_preprocessor_statements {
-  my ($self) = @_;
-  my @cpp = grep(/^\#\s*(?:if|e\w+)/, @{ $self->{line} });
-  if (@cpp) {
-    my $cpplevel;
-    for my $cpp (@cpp) {
-      if ($cpp =~ /^\#\s*if/) {
-        $cpplevel++;
-      }
-      elsif (!$cpplevel) {
-        Warn( $self, "Warning: #else/elif/endif without #if in this function");
-        print STDERR "    (precede it with a blank line if the matching #if is outside the function)\n"
-          if $self->{XSStack}->[-1]{type} eq 'if';
-        return;
-      }
-      elsif ($cpp =~ /^\#\s*endif/) {
-        $cpplevel--;
-      }
-    }
-    Warn( $self, "Warning: #if without #endif in this function") if $cpplevel;
-  }
-}
-
 sub Q {
   my($text) = @_;
   $text =~ s/^#//gm;
@@ -1586,7 +1566,7 @@ sub Q {
 # Read next xsub into @{ $self->{line} } from ($lastline, <$FH>).
 sub fetch_para {
   # parse paragraph
-  death ("Error: Unterminated `#if/#ifdef/#ifndef'")
+  death("Error: Unterminated `#if/#ifdef/#ifndef'")
     if !defined $self->{lastline} && $self->{XSStack}->[-1]{type} eq 'if';
   @{ $self->{line} } = ();
   @{ $self->{line_no} } = ();
@@ -1611,7 +1591,7 @@ sub fetch_para {
       while ($self->{lastline} = <$FH>) {
         last if ($self->{lastline} =~ /^=cut\s*$/);
       }
-      death ("Error: Unterminated pod") unless $self->{lastline};
+      death("Error: Unterminated pod") unless $self->{lastline};
       $self->{lastline} = <$FH>;
       chomp $self->{lastline};
       $self->{lastline} =~ s/^\s+$//;
@@ -1858,26 +1838,6 @@ sub generate_output {
   }
 }
 
-sub Warn {
-  my $self = shift;
-  # work out the line number
-  my $warn_line_number = $self->{line_no}->[@{ $self->{line_no} } - @{ $self->{line} } -1];
-
-  print STDERR "@_ in $self->{filename}, line $warn_line_number\n";
-}
-
-sub blurt {
-  my $self = shift;
-  Warn($self, @_);
-  $self->{errors}++
-}
-
-sub death {
-  my $self = shift;
-  Warn($self, @_);
-  exit 1;
-}
-
 1;
 
 # vim: ts=2 sw=2 et:
index 3af5e5f..ef22fdc 100644 (file)
@@ -21,8 +21,11 @@ our (@ISA, @EXPORT_OK);
   assign_func_args
   print_preprocessor_statements
   set_cond
+  Warn
+  blurt
+  death
+  check_conditional_preprocessor_statements
 );
-#  check_conditional_preprocessor_statements
 
 =head1 NAME
 
@@ -554,28 +557,48 @@ sub set_cond {
   return $cond;
 }
 
-#sub check_conditional_preprocessor_statements {
-#  my ($self) = @_;
-#  my @cpp = grep(/^\#\s*(?:if|e\w+)/, @{ $self->{line} });
-#  if (@cpp) {
-#    my $cpplevel;
-#    for my $cpp (@cpp) {
-#      if ($cpp =~ /^\#\s*if/) {
-#        $cpplevel++;
-#      }
-#      elsif (!$cpplevel) {
-#        Warn("Warning: #else/elif/endif without #if in this function");
-#        print STDERR "    (precede it with a blank line if the matching #if is outside the function)\n"
-#          if $self->{XSStack}->[-1]{type} eq 'if';
-#        return;
-#      }
-#      elsif ($cpp =~ /^\#\s*endif/) {
-#        $cpplevel--;
-#      }
-#    }
-#    Warn("Warning: #if without #endif in this function") if $cpplevel;
-#  }
-#}
+sub Warn {
+  my $self = shift;
+  # work out the line number
+  my $warn_line_number = $self->{line_no}->[@{ $self->{line_no} } - @{ $self->{line} } -1];
+
+  print STDERR "@_ in $self->{filename}, line $warn_line_number\n";
+}
+
+sub blurt {
+  my $self = shift;
+  Warn($self, @_);
+  $self->{errors}++
+}
+
+sub death {
+  my $self = shift;
+  Warn($self, @_);
+  exit 1;
+}
+
+sub check_conditional_preprocessor_statements {
+  my ($self) = @_;
+  my @cpp = grep(/^\#\s*(?:if|e\w+)/, @{ $self->{line} });
+  if (@cpp) {
+    my $cpplevel;
+    for my $cpp (@cpp) {
+      if ($cpp =~ /^\#\s*if/) {
+        $cpplevel++;
+      }
+      elsif (!$cpplevel) {
+        Warn( $self, "Warning: #else/elif/endif without #if in this function");
+        print STDERR "    (precede it with a blank line if the matching #if is outside the function)\n"
+          if $self->{XSStack}->[-1]{type} eq 'if';
+        return;
+      }
+      elsif ($cpp =~ /^\#\s*endif/) {
+        $cpplevel--;
+      }
+    }
+    Warn( $self, "Warning: #if without #endif in this function") if $cpplevel;
+  }
+}
 
 1;
 
index dd2e7b9..a6cbd50 100644 (file)
@@ -5,74 +5,144 @@ use Carp;
 use Cwd;
 use File::Spec;
 use File::Temp qw( tempdir );
-use Test::More qw(no_plan); # tests =>  7;
+use Capture::Tiny qw( capture );
+use Test::More tests => 13;
 use lib qw( lib );
 use ExtUtils::ParseXS::Utilities qw(
+    check_conditional_preprocessor_statements
 );
-#    check_conditional_preprocessor_statements
 
 my $self = {};
 $self->{line} = [];
 $self->{XSStack} = [];
 $self->{XSStack}->[0] = {};
-my @capture = ();
-sub capture { push @capture, $_[0] };
 
-#{
-#    $self->{line} = [
-#        "#if this_is_an_if_statement",
-#        "Alpha this is not an if/elif/elsif/endif",
-#        "#elif this_is_an_elif_statement",
-#        "Beta this is not an if/elif/elsif/endif",
-#        "#else this_is_an_else_statement",
-#        "Gamma this is not an if/elif/elsif/endif",
-#        "#endif this_is_an_endif_statement",
-#    ];
-#    $self->{XSStack}->[-1]{type} = 'if';
-#
-#    @capture = ();
-#    local $SIG{__WARN__} = \&capture;
-#    is( check_conditional_preprocessor_statements($self), 0,
-#        "basic case: returned 0: all ifs resolved" );
-#    ok( ! @capture, "No warnings captured, as expected" );
-#}
-#
-#{
-#    $self->{line} = [
-#        "#if this_is_an_if_statement",
-#        "Alpha this is not an if/elif/elsif/endif",
-#        "#if this_is_a_different_if_statement",
-#        "Beta this is not an if/elif/elsif/endif",
-#        "#endif this_is_a_different_endif_statement",
-#        "Gamma this is not an if/elif/elsif/endif",
-#        "#endif this_is_an_endif_statement",
-#    ];
-#    $self->{XSStack}->[-1]{type} = 'if';
-#
-#    @capture = ();
-#    local $SIG{__WARN__} = \&capture;
-#    is( check_conditional_preprocessor_statements($self), 0,
-#        "one nested if case: returned 0: all ifs resolved" );
-#    ok( ! @capture, "No warnings captured, as expected" );
-#}
-#
-#{
-#    $self->{line} = [
-#        "Alpha this is not an if/elif/elsif/endif",
-#        "#elif this_is_an_elif_statement",
-#        "Beta this is not an if/elif/elsif/endif",
-#        "#else this_is_an_else_statement",
-#        "Gamma this is not an if/elif/elsif/endif",
-#        "#endif this_is_an_endif_statement",
-#    ];
-#    $self->{XSStack}->[-1]{type} = 'if';
-#
-#    @capture = ();
-#    local $SIG{__WARN__} = \&capture;
-#    is( check_conditional_preprocessor_statements($self), undef,
-#        "missing 'if' case: returned undef: all ifs resolved" );
-#    ok( @capture, "Warning captured, as expected" );
-#}
+{
+    $self->{line} = [
+        "#if this_is_an_if_statement",
+        "Alpha this is not an if/elif/elsif/endif",
+        "#elif this_is_an_elif_statement",
+        "Beta this is not an if/elif/elsif/endif",
+        "#else this_is_an_else_statement",
+        "Gamma this is not an if/elif/elsif/endif",
+        "#endif this_is_an_endif_statement",
+    ];
+    $self->{line_no} = [ 17 .. 23 ];
+    $self->{XSStack}->[-1]{type} = 'if';
+    $self->{filename} = 'myfile1';
 
+    my ($stdout, $stderr, $rv);
+    ($stdout, $stderr) = capture {
+        $rv = check_conditional_preprocessor_statements($self);
+    };
+        
+    is( $rv, 0, "Basic case: returned 0: all ifs resolved" );
+    ok( ! $stderr, "No warnings captured, as expected" );
+}
+
+{
+    $self->{line} = [
+        "#if this_is_an_if_statement",
+        "Alpha this is not an if/elif/elsif/endif",
+        "#if this_is_a_different_if_statement",
+        "Beta this is not an if/elif/elsif/endif",
+        "#endif this_is_a_different_endif_statement",
+        "Gamma this is not an if/elif/elsif/endif",
+        "#endif this_is_an_endif_statement",
+    ];
+    $self->{line_no} = [ 17 .. 23 ];
+    $self->{XSStack}->[-1]{type} = 'if';
+    $self->{filename} = 'myfile1';
+
+    my ($stdout, $stderr, $rv);
+    ($stdout, $stderr) = capture {
+        $rv = check_conditional_preprocessor_statements($self);
+    };
+    is( $rv, 0, "One nested if case: returned 0: all ifs resolved" );
+    ok( ! $stderr, "No warnings captured, as expected" );
+}
+
+{
+    $self->{line} = [
+        "Alpha this is not an if/elif/elsif/endif",
+        "#elif this_is_an_elif_statement",
+        "Beta this is not an if/elif/elsif/endif",
+        "#else this_is_an_else_statement",
+        "Gamma this is not an if/elif/elsif/endif",
+        "#endif this_is_an_endif_statement",
+    ];
+    $self->{line_no} = [ 17 .. 22 ];
+    $self->{XSStack}->[-1]{type} = 'if';
+    $self->{filename} = 'myfile1';
+
+    my ($stdout, $stderr, $rv);
+    ($stdout, $stderr) = capture {
+        $rv = check_conditional_preprocessor_statements($self);
+    };
+    is( $rv, undef,
+        "Missing 'if' case: returned undef: all ifs resolved" );
+    like( $stderr,
+        qr/Warning: #else\/elif\/endif without #if in this function/,
+        "Got expected warning: lack of #if"
+    );
+    like( $stderr,
+        qr/precede it with a blank line/s,
+        "Got expected warning: advice re blank line"
+    );
+}
+
+{
+    $self->{line} = [
+        "Alpha this is not an if/elif/elsif/endif",
+        "#elif this_is_an_elif_statement",
+        "Beta this is not an if/elif/elsif/endif",
+        "#else this_is_an_else_statement",
+        "Gamma this is not an if/elif/elsif/endif",
+        "#endif this_is_an_endif_statement",
+    ];
+    $self->{line_no} = [ 17 .. 22 ];
+    $self->{XSStack}->[-1]{type} = 'file';
+    $self->{filename} = 'myfile1';
+
+    my ($stdout, $stderr, $rv);
+    ($stdout, $stderr) = capture {
+        $rv = check_conditional_preprocessor_statements($self);
+    };
+    is( $rv, undef,
+        "Missing 'if' case: returned undef: all ifs resolved" );
+    like( $stderr,
+        qr/Warning: #else\/elif\/endif without #if in this function/,
+        "Got expected warning: lack of #if"
+    );
+    unlike( $stderr,
+        qr/precede it with a blank line/s,
+        "Did not get unexpected stderr"
+    );
+}
+
+{
+    $self->{line} = [
+        "#if this_is_an_if_statement",
+        "Alpha this is not an if/elif/elsif/endif",
+        "#elif this_is_an_elif_statement",
+        "Beta this is not an if/elif/elsif/endif",
+        "#else this_is_an_else_statement",
+        "Gamma this is not an if/elif/elsif/endif",
+    ];
+    $self->{line_no} = [ 17 .. 22 ];
+    $self->{XSStack}->[-1]{type} = 'if';
+    $self->{filename} = 'myfile1';
+
+    my ($stdout, $stderr, $rv);
+    ($stdout, $stderr) = capture {
+        $rv = check_conditional_preprocessor_statements($self);
+    };
+    isnt( $rv, 0,
+        "Missing 'endif' case: returned non-zero as expected" );
+    like( $stderr,
+        qr/Warning: #if without #endif in this function/s,
+        "Got expected warning: lack of #endif"
+    );
+}
 
 pass("Passed all tests in $0");
diff --git a/dist/ExtUtils-ParseXS/t/114-blurt_death_Warn.t b/dist/ExtUtils-ParseXS/t/114-blurt_death_Warn.t
new file mode 100644 (file)
index 0000000..298bf10
--- /dev/null
@@ -0,0 +1,130 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Carp;
+use Cwd;
+use File::Spec;
+use File::Temp qw( tempdir );
+use Capture::Tiny qw( capture );
+use Test::More tests =>  7;
+use lib qw( lib );
+use ExtUtils::ParseXS::Utilities qw(
+    Warn
+    blurt
+    death
+);
+
+my $self = {};
+$self->{line} = [];
+$self->{line_no} = [];
+
+{
+    $self->{line} = [
+        'Alpha',
+        'Beta',
+        'Gamma',
+        'Delta',
+    ];
+    $self->{line_no} = [ 17 .. 20 ];
+    $self->{filename} = 'myfile1';
+
+    my $message = 'Warning: Ignoring duplicate alias';
+    
+    my ($stdout, $stderr) = capture {
+        Warn( $self, $message);
+    };
+    like( $stderr,
+        qr/$message in $self->{filename}, line 20/,
+        "Got expected Warn output",
+    );
+}
+
+{
+    $self->{line} = [
+        'Alpha',
+        'Beta',
+        'Gamma',
+        'Delta',
+        'Epsilon',
+    ];
+    $self->{line_no} = [ 17 .. 20 ];
+    $self->{filename} = 'myfile2';
+
+    my $message = 'Warning: Ignoring duplicate alias';
+    my ($stdout, $stderr) = capture {
+        Warn( $self, $message);
+    };
+    like( $stderr,
+        qr/$message in $self->{filename}, line 19/,
+        "Got expected Warn output",
+    );
+}
+
+{
+    $self->{line} = [
+        'Alpha',
+        'Beta',
+        'Gamma',
+        'Delta',
+    ];
+    $self->{line_no} = [ 17 .. 21 ];
+    $self->{filename} = 'myfile1';
+
+    my $message = 'Warning: Ignoring duplicate alias';
+    my ($stdout, $stderr) = capture {
+        Warn( $self, $message);
+    };
+    like( $stderr,
+        qr/$message in $self->{filename}, line 17/,
+        "Got expected Warn output",
+    );
+}
+
+{
+    $self->{line} = [
+        'Alpha',
+        'Beta',
+        'Gamma',
+        'Delta',
+    ];
+    $self->{line_no} = [ 17 .. 20 ];
+    $self->{filename} = 'myfile1';
+    $self->{errors} = 0;
+
+
+    my $message = 'Error: Cannot parse function definition';
+    my ($stdout, $stderr) = capture {
+        blurt( $self, $message);
+    };
+    like( $stderr,
+        qr/$message in $self->{filename}, line 20/,
+        "Got expected blurt output",
+    );
+    is( $self->{errors}, 1, "Error count incremented correctly" );
+}
+
+SKIP: {
+    skip "death() not testable as long as it contains hard-coded 'exit'", 1;
+
+    $self->{line} = [
+        'Alpha',
+        'Beta',
+        'Gamma',
+        'Delta',
+    ];
+    $self->{line_no} = [ 17 .. 20 ];
+    $self->{filename} = 'myfile1';
+
+    my $message = "Code is not inside a function";
+    eval {
+        my ($stdout, $stderr) = capture {
+            death( $self, $message);
+        };
+        like( $stderr,
+            qr/$message in $self->{filename}, line 20/,
+            "Got expected death output",
+        );
+    };
+}
+
+pass("Passed all tests in $0");