"Fossies" - the Fresh Open Source Software Archive

Member "RPerl-5.002000/t/09_interpret_execute.t" (30 Aug 2019, 22670 Bytes) of package /linux/misc/RPerl-5.002000.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "09_interpret_execute.t": 4.002000_vs_5.000000.

    1 #!/usr/bin/env perl  ## no critic qw(ProhibitExcessMainComplexity)  # SYSTEM SPECIAL 4: allow complex code outside subroutines, must be on line 1
    2 
    3 # [[[ PRE-HEADER ]]]
    4 # suppress 'WEXRP00: Found multiple rperl executables' due to blib/ & pre-existing installation(s),
    5 # also 'WARNING WCOCODE00, COMPILER, FIND DEPENDENCIES: Failed to eval-use package' due to RPerl/Test/*/*Bad*.pm & RPerl/Test/*/*bad*.pl
    6 BEGIN { $ENV{RPERL_WARNINGS} = 0; }
    7 
    8 # [[[ HEADER ]]]
    9 use strict;
   10 use warnings;
   11 use RPerl::AfterSubclass;
   12 our $VERSION = 0.010_000;
   13 
   14 # [[[ CRITICS ]]]
   15 ## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls)  # USER DEFAULT 1: allow numeric values & print operator
   16 ## no critic qw(RequireBriefOpen)  # USER DEFAULT 5: allow open() in perltidy-expanded code
   17 ## no critic qw(RequireInterpolationOfMetachars)  # USER DEFAULT 2: allow single-quoted control characters & sigils
   18 ## no critic qw(ProhibitDeepNests)  # SYSTEM SPECIAL 7: allow deeply-nested code
   19 
   20 # [[[ INCLUDES ]]]
   21 use RPerl::Test;
   22 use RPerl::Parser;
   23 use RPerl::Generator;
   24 use RPerl::Compiler;
   25 use Test::More;
   26 use Test::Exception;
   27 use File::Find qw(find);
   28 #use IPC::Open3;
   29 #use IO::Select;
   30 use IPC::Run3 qw(run3);
   31 use Cwd;
   32 use File::Spec;
   33 
   34 # [[[ CONSTANTS ]]]
   35 use constant PATH_TESTS => my string $TYPED_PATH_TESTS = $RPerl::INCLUDE_PATH . '/RPerl/Test';
   36 
   37 # [[[ OPERATIONS ]]]
   38 
   39 BEGIN {
   40     if ( $ENV{RPERL_VERBOSE} ) {
   41         Test::More::diag("[[[ Beginning Interpret-Execute Pre-Test Loading, RPerl Execution System ]]]");
   42     }
   43     # DEV NOTE: can't do use_ok() or require_ok() because it will place them before all other BEGIN blocks,
   44     # which means we wil have 4 tests passing before we call 'plan tests',
   45     # which means we will fail to have 'plan tests' first OR done_testing() last, which causes a TAP failure;
   46     # must be included w/ regular 'use' operators above
   47 #    lives_and( sub { require_ok('RPerl::AfterSubclass'); },            q{require_ok('RPerl::AfterSubclass') lives} );
   48 #    lives_and( sub { require_ok('RPerl::Parser'); }, q{require_ok('RPerl::Parser') lives} );
   49 #    lives_and( sub { require_ok('RPerl::Generator'); }, q{require_ok('RPerl::Generator') lives} );
   50 #    lives_and( sub { require_ok('RPerl::Compiler'); }, q{require_ok('RPerl::Compiler') lives} );
   51 }
   52 
   53 # DEV NOTE: must specify number of tests in EITHER 'plan tests' or done_testing() below, not both
   54 #my integer $number_of_tests_run = 4;  # initialize to 4 for use_ok() calls in BEGIN block above
   55 
   56 my $test_files = {};    # string_hashref
   57 
   58 # NEED UPDATE: use 'no_chdir => 1' like 13_generate.t
   59 # save current directory for file checks, because File::Find changes directory;
   60 # use File::Spec for MS Windows support, etc.
   61 my $current_working_directory = getcwd;
   62 (my $volume, my $directories, my $dummy_file) = File::Spec->splitpath( $current_working_directory, 1 );  # no_file = 1
   63 
   64 find(
   65     sub {
   66         my $file = $File::Find::name;
   67 #        RPerl::diag('in 09_interpret_execute.t, have $file = ' . $file . "\n");
   68 
   69         if (defined $ARGV[0]) {
   70             # restore saved path, because File::Find changes directories while searching for files
   71             my $file_full_path = File::Spec->catpath( $volume, $directories, $file );
   72 #            RPerl::diag('in 09_interpret_execute.t, have $file_full_path = ' . $file_full_path . "\n");
   73             $file = $file_full_path;
   74         }
   75 
   76         #        if ( $file !~ m/.*OperatorVoid01NamedVoid.*[.]p[ml]$/xms ) { # TEMP DEBUGGING, ONLY FIND OperatorVoid01NamedVoid*/*.pm & *.pl
   77         if ( $file !~ m/.pl$/xms ) {
   78             return;
   79         }
   80         elsif ( ( $file =~ m/NotGood/ms ) or ( $file =~ m/not_good/ms ) ) {
   81             preprocess_execute_error($test_files, $file);
   82         }
   83 
   84         if ( ( $file =~ m/Good/ms ) or ( $file =~ m/good/ms ) or ( $file =~ m/NotBad/ms ) or ( $file =~ m/not_bad/ms ) ) {
   85             open my filehandleref $FILE_HANDLE, '<', $file
   86                 or croak 'ERROR, Cannot open file ' . $file . ' for reading,' . $OS_ERROR . ', croaking';
   87             while (<$FILE_HANDLE>) {
   88                 if (m/^\#\s*\<\<\<\s*EXECUTE_SUCCESS\s*\:\s*['"](.*)['"]\s*\>\>\>/xms) {
   89                     push @{ $test_files->{$file}->{successes} }, $1;
   90                 }
   91                 elsif (m/^\#\s*\<\<\<\s*EXECUTE_SUCCESS_REGEX\s*\:\s*['"](.*)['"]\s*\>\>\>/xms) {
   92                     push @{ $test_files->{$file}->{successes} }, ('[IS_REGEX]' . $1);
   93                     RPerl::diag( 'in 09_interpret_execute.t, EXECUTE_SUCCESS_REGEX, have pattern = ', $1, "\n" );
   94                     RPerl::diag( 'in 09_interpret_execute.t, EXECUTE_SUCCESS_REGEX, have $test_files->{$file} = ', Dumper($test_files->{$file}), "\n" );
   95                 }
   96                 elsif (m/^\#\s*\<\<\<\s*EXECUTE_SUCCESS_INTEGER_32\s*\:\s*['"](.*)['"]\s*\>\>\>/xms) {
   97                     push @{ $test_files->{$file}->{successes_integer_32} }, $1;
   98                 }
   99                 elsif (m/^\#\s*\<\<\<\s*EXECUTE_SUCCESS_INTEGER_64\s*\:\s*['"](.*)['"]\s*\>\>\>/xms) {
  100                     push @{ $test_files->{$file}->{successes_integer_64} }, $1;
  101                 }
  102                 elsif (m/^\#\s*\<\<\<\s*EXECUTE_SUCCESS_NUMBER_32\s*\:\s*['"](.*)['"]\s*\>\>\>/xms) {
  103                     push @{ $test_files->{$file}->{successes_number_32} }, $1;
  104                 }
  105                 elsif (m/^\#\s*\<\<\<\s*EXECUTE_SUCCESS_NUMBER_64\s*\:\s*['"](.*)['"]\s*\>\>\>/xms) {
  106                     push @{ $test_files->{$file}->{successes_number_64} }, $1;
  107                 }
  108 #                else { RPerl::diag( 'in 09_interpret_execute.t, have unrecognized input file line = ', $_, "\n" ); }
  109                 
  110                 if (m/^\#\s*\<\<\<\s*EXECUTE\s*\:\s*OFF\s*\>\>\>/xms) {
  111                     delete $test_files->{$file};
  112                     last;
  113                 }
  114             }
  115             close $FILE_HANDLE
  116                 or croak 'ERROR, Cannot close file ' . $file . ' after reading,' . $OS_ERROR . ', croaking';
  117         }
  118         elsif ( ( $file =~ m/Bad/ms ) or ( $file =~ m/bad/ms ) ) {
  119             preprocess_execute_error($test_files, $file);
  120         }
  121         else {
  122             return;
  123         }
  124     },
  125     (defined $ARGV[0]) ? $ARGV[0] : PATH_TESTS()
  126 );
  127 
  128 # trim unnecessary (and possibly problematic) absolute paths from input file names
  129 # must be done outside find() to properly utilize getcwd()
  130 foreach my string $test_file_key (sort keys %{$test_files}) {
  131     my string $test_file_key_trimmed = RPerl::Compiler::post_processor__absolute_path_delete($test_file_key);
  132     if ($test_file_key_trimmed ne $test_file_key) {
  133         $test_files->{$test_file_key_trimmed} = $test_files->{$test_file_key};
  134         delete $test_files->{$test_file_key};
  135     }
  136 }
  137 
  138 my integer $number_of_test_files = scalar keys %{$test_files};
  139 
  140 #RPerl::diag( 'in 09_interpret_execute.t, have $test_files = ' . "\n" . Dumper($test_files) . "\n" );
  141 #RPerl::diag( 'in 09_interpret_execute.t, have sort keys %{$test_files} = ' . "\n" . Dumper(sort keys %{$test_files}) . "\n" );
  142 #RPerl::diag( 'in 09_interpret_execute.t, have $number_of_test_files = ' . $number_of_test_files . "\n" );
  143 
  144 plan tests => $number_of_test_files;
  145 
  146 if ( $ENV{RPERL_VERBOSE} ) {
  147     Test::More::diag( '[[[ Beginning Interpret-Execute Tests, RPerl Execution System, PERL Operations & PERL Data Types' . ' ]]]' );
  148 }
  149 
  150 # [[[ PRIMARY RUNLOOP ]]]
  151 # [[[ PRIMARY RUNLOOP ]]]
  152 # [[[ PRIMARY RUNLOOP ]]]
  153 
  154 my integer $i = 0;
  155 
  156 # NEED ANSWER: keep IPC::Run3 code, or revert back to original IPC::Open3 code???
  157 foreach my $test_file ( sort keys %{$test_files} ) {
  158     $i++;
  159     if ( $ENV{RPERL_VERBOSE} ) {
  160         Test::More::diag( 'Test File #' . $i . ' of ' . $number_of_test_files . ': ' . $test_file );
  161     }
  162 
  163 #    RPerl::diag( 'in 09_interpret_execute.t, have $test_file = ' . $test_file . "\n" );
  164     #my $pid;
  165     my $stdout_generated = q{};
  166     my $stderr_generated = q{};
  167     if ( $RPerl::INCLUDE_PATH =~ /blib/ ) {
  168         #$pid = open3( 0, \*STDOUT_TEST, \*STDERR_TEST, $test_file_execute_command );    # disable STDIN w/ 0
  169         my string $test_file_execute_command = $EXECUTABLE_NAME . ' -Mblib=' . $RPerl::INCLUDE_PATH . ' ' . $test_file;
  170 #        RPerl::diag( 'in 09_interpret_execute.t, yes blib INCLUDE_PATH, have $test_file_execute_command = ' . $test_file_execute_command . "\n" );
  171 #        RPerl::diag( 'in 09_interpret_execute.t, yes blib INCLUDE_PATH, about to call open3()...' . "\n" );
  172     run3( $test_file_execute_command, \undef, \$stdout_generated, \$stderr_generated );
  173     #$pid = open3( 0, \*STDOUT_TEST, \*STDERR_TEST, $test_file_execute_command );    # disable STDIN w/ 0
  174 #        RPerl::diag( 'in 09_interpret_execute.t, yes blib INCLUDE_PATH, returned from open3(), have $pid = ' . $pid . "\n" );
  175     }
  176     else {
  177         my string $test_file_execute_command = $EXECUTABLE_NAME . ' -I' . $RPerl::INCLUDE_PATH . ' ' . $test_file;
  178 #        RPerl::diag( 'in 09_interpret_execute.t, not blib INCLUDE_PATH, have $test_file_execute_command = ' . $test_file_execute_command . "\n" );
  179 #        RPerl::diag( 'in 09_interpret_execute.t, not blib INCLUDE_PATH, about to call open3()...' . "\n" );
  180 #         my $stdout_select;
  181 #    my $stderr_select;
  182 #    if ( $OSNAME ne 'MSWin32' ) {
  183 ##        RPerl::diag( 'in 09_interpret_execute.t, no MSWin32, about to call IO::Select->new()...' . "\n" );
  184 #        $stdout_select = IO::Select->new();
  185 #        $stderr_select = IO::Select->new();
  186 ##        RPerl::diag( 'in 09_interpret_execute.t, no MSWin32, about to call $stdout_select->add( \*STDOUT_TEST )...' . "\n" );
  187 #        $stdout_select->add( \*STDOUT_TEST );
  188 #        $stderr_select->add( \*STDERR_TEST );
  189 ##        RPerl::diag( 'in 09_interpret_execute.t, no MSWin32, returned from $stdout_select->add( \*STDOUT_TEST )' . "\n" );
  190 #    }
  191 #
  192 #    my $stdout_generated = q{};
  193 #    my $stderr_generated = q{};
  194 #
  195     run3( $test_file_execute_command, \undef, \$stdout_generated, \$stderr_generated );
  196     #$pid = open3( 0, \*STDOUT_TEST, \*STDERR_TEST, $test_file_execute_command );    # disable STDIN w/ 0
  197 #        RPerl::diag( 'in 09_interpret_execute.t, not blib INCLUDE_PATH, returned from open3(), have $pid = ' . $pid . "\n" );
  198     }
  199 
  200     # DISABLED: no user input accepted
  201     #    while (1) {
  202     #        print "Enter input\n";
  203     #        chomp( my $stdin_received = <STDIN_TEST> );
  204     #        print STDIN_TEST "$stdin_received\n";
  205    #    select( undef, undef, undef, 0.1 ); # allow time for output to be generated; not needed with waitpid() before sysread() calls below
  206 #
  207 #    #        if ( $stdout_select->can_read(0) )  { RPerl::diag('in 09_interpret_execute.t, can read STDOUT_TEST for $test_file = ' . $test_file . "\n"); }
  208 #    #        if ( $stderr_select->can_read(0) )  { RPerl::diag('in 09_interpret_execute.t, can read STDERR_TEST for $test_file = ' . $test_file . "\n"); }
  209 #
  210 #    if ( $OSNAME eq 'MSWin32' || $stdout_select->can_read(0) ) {
  211 ##        RPerl::diag( 'in 09_interpret_execute.t, yes MSWin32 or $stdout_select->can_read(0), about to call sysread STDOUT_TEST...' . "\n" );
  212 #        sysread STDOUT_TEST, $stdout_generated, 4096;
  213 ##        RPerl::diag( 'in 09_interpret_execute.t, yes MSWin32 or $stdout_select->can_read(0), returned from sysread STDOUT_TEST, have $stdout_generated = ' . "\n" . '[BEGIN STDOUT]' . "\n" . $stdout_generated . '[END STDOUT]' . "\n" );
  214 #    }
  215 #    if ( $OSNAME eq 'MSWin32' || $stderr_select->can_read(0) ) {
  216 ##        RPerl::diag( 'in 09_interpret_execute.t, yes MSWin32 or $stderr_select->can_read(0), about to call sysread STDERR_TEST...' . "\n" );
  217 #        sysread STDERR_TEST, $stderr_generated, 4096;
  218 ##        RPerl::diag( 'in 09_interpret_execute.t, yes MSWin32 or $stderr_select->can_read(0), returned from sysread STDERR_TEST, have $stderr_generated = ' . "\n" . '[BEGIN STDERR]' . "\n" . $stderr_generated . '[END STDERR]' . "\n" );
  219 #    }
  220 #
  221 ##    RPerl::diag( 'in 09_interpret_execute.t, have $pid = ' . $pid . ', about to call waitpid...' . "\n" );
  222 #    waitpid $pid, 0;
  223 ##    RPerl::diag( 'in 09_interpret_execute.t, have $pid = ' . $pid . ', returned from waitpid...' . "\n" );
  224 #
  225 #    if ( $OSNAME eq 'MSWin32' || $stdout_select->can_read(0) ) {
  226 ##        RPerl::diag( 'in 09_interpret_execute.t, yes MSWin32 or $stdout_select->can_read(0), about to call sysread STDOUT_TEST...' . "\n" );
  227 #        my string $stdout_generated_continued;
  228 #        sysread STDOUT_TEST, $stdout_generated_continued, 4096;
  229 #        $stdout_generated .= $stdout_generated_continued;
  230 ##        RPerl::diag( 'in 09_interpret_execute.t, yes MSWin32 or $stdout_select->can_read(0), returned from sysread STDOUT_TEST, have $stdout_generated_continued = ' . "\n" . '[BEGIN STDOUT]' . "\n" . $stdout_generated_continued . '[END STDOUT]' . "\n" );
  231 #    }
  232 #    if ( $OSNAME eq 'MSWin32' || $stderr_select->can_read(0) ) {
  233 ##        RPerl::diag( 'in 09_interpret_execute.t, yes MSWin32 or $stderr_select->can_read(0), about to call sysread STDERR_TEST...' . "\n" );
  234 #        my string $stderr_generated_continued;
  235 #        sysread STDERR_TEST, $stderr_generated_continued, 4096;
  236 #        $stderr_generated .= $stderr_generated_continued;
  237 ##        RPerl::diag( 'in 09_interpret_execute.t, yes MSWin32 or $stderr_select->can_read(0), returned from sysread STDERR_TEST, have $stderr_generated_continued = ' . "\n" . '[BEGIN STDERR]' . "\n" . $stderr_generated_continued . '[END STDERR]' . "\n" );
  238 #    }
  239   
  240 
  241     # DISABLED: no user input accepted
  242     #        $stdout_generated = q{};
  243     #        $stderr_generated = q{};
  244     #    }
  245 
  246     my $test_exit_status = $CHILD_ERROR >> 8;
  247 
  248 #    RPerl::diag( 'in 09_interpret_execute.t, have $CHILD_ERROR = ' . $CHILD_ERROR . "\n" );
  249 #    RPerl::diag( 'in 09_interpret_execute.t, have $test_exit_status = ' . $test_exit_status . "\n" );
  250 
  251 #    if ($stdout_generated) { RPerl::diag( "===STDOUT=BEGIN====\n" . $stdout_generated . "===STDOUT=END======\n" ); }
  252 #    if ($stderr_generated) { RPerl::diag( "===STDERR=BEGIN====\n" . $stderr_generated . "===STDERR=END======\n" ); }
  253 
  254     my @stdout_generated_lines_array = split( "\n", $stdout_generated );
  255     my string_arrayref $stdout_generated_lines = \@stdout_generated_lines_array;
  256 
  257     if ( $test_exit_status == 0 ) {    # UNIX process return code 0, success
  258         if ( ( $test_file =~ m/NotGood/xms ) or ( $test_file =~ m/not_good/xms ) ) {
  259             ok( ( missing_errors_count($test_files, $test_file, $stdout_generated, $stderr_generated) == 0 ), 'Program interprets and executes with expected error(s):' . ( q{ } x 2 ) . $test_file );
  260 #            $number_of_tests_run++;
  261         }
  262         elsif ( ( $test_file =~ m/Good/xms ) or ( $test_file =~ m/good/xms ) or ( $test_file =~ m/NotBad/xms ) or ( $test_file =~ m/not_bad/xms ) ) {
  263             my $missing_successes = [];
  264 #            RPerl::diag( 'in 09_interpret_execute.t, run success on good code, have $test_files->{$test_file} = ' . Dumper($test_files->{$test_file}) . "\n\n" );
  265 
  266             if ( defined $test_files->{$test_file}->{successes} ) {
  267                 success_match($test_file, $test_files->{$test_file}->{successes}, $stdout_generated_lines);
  268             }
  269             elsif ( ( defined $test_files->{$test_file}->{successes_integer_32} ) and ( rperltypessizes::type_integer_bitsize() == 32 ) ) {
  270                 success_match($test_file, $test_files->{$test_file}->{successes_integer_32}, $stdout_generated_lines);
  271             }
  272             elsif ( ( defined $test_files->{$test_file}->{successes_integer_64} ) and ( rperltypessizes::type_integer_bitsize() == 64 ) ) {
  273                 success_match($test_file, $test_files->{$test_file}->{successes_integer_64}, $stdout_generated_lines);
  274             }
  275             elsif ( ( defined $test_files->{$test_file}->{successes_number_32} ) and ( rperltypessizes::type_number_bitsize() == 32 ) ) {
  276                 success_match($test_file, $test_files->{$test_file}->{successes_number_32}, $stdout_generated_lines);
  277             }
  278             elsif ( ( defined $test_files->{$test_file}->{successes_number_64} ) and ( rperltypessizes::type_number_bitsize() == 64 ) ) {
  279                 success_match($test_file, $test_files->{$test_file}->{successes_number_64}, $stdout_generated_lines);
  280             }
  281 
  282             #DISABLE
  283             # NEED UPGRADE: below code allows success strings to be matched out-of-order in captured output
  284             # enable with some appropriate preprocessor keyword
  285             #                foreach my $success (
  286             #                    @{ $test_files->{$test_file}->{successes} } )
  287             #                {
  288             #                    if ( $stdout_generated !~ /\Q$success\E/xms ) {
  289             #                        push @{$missing_successes},
  290             #                            "Success message '$success' expected, but not found";
  291             #                    }
  292             #                }
  293             #            }
  294             #            RPerl::verbose( 'in 09_interpret_execute.t, have $missing_successes =' . "\n" . Dumper($missing_successes) . "\n" );
  295             #            ok( ( ( scalar @{$missing_successes} ) == 0 ), 'Program interprets and executes without errors:' . (q{ } x 10) . $test_file );
  296 
  297         }
  298         else {
  299             ok( 0, 'Program interprets and executes with errors:' . ( q{ } x 13 ) . $test_file );
  300 #            $number_of_tests_run++;
  301         }
  302     }
  303     else {    # UNIX process return code not 0, error
  304         if ( ( $test_file =~ m/NotBad/ms ) or ( $test_file =~ m/not_bad/ms ) ) {
  305             ok( 0, 'Program interprets and executes without errors:' . ( q{ } x 10 ) . $test_file );
  306 #            $number_of_tests_run++;
  307         }
  308         elsif ( ( $test_file =~ m/Bad/ms ) or ( $test_file =~ m/bad/ms ) or ( $test_file =~ m/NotGood/ms ) or ( $test_file =~ m/not_good/ms )  ) {
  309             ok( ( missing_errors_count($test_files, $test_file, $stdout_generated, $stderr_generated) == 0 ), 'Program interprets and executes with expected error(s):' . ( q{ } x 2 ) . $test_file );
  310 #            $number_of_tests_run++;
  311         }
  312         else {
  313             ok( 0, 'Program interprets and executes without errors:' . ( q{ } x 10 ) . $test_file );
  314 #            $number_of_tests_run++;
  315         }
  316     }
  317 }
  318 
  319 sub preprocess_execute_error {
  320     (my string_hashref $test_files, my string $file) = @ARG;
  321     open my filehandleref $FILE_HANDLE, '<', $file
  322         or croak 'ERROR, Cannot open file ' . $file . ' for reading,' . $OS_ERROR . ', croaking';
  323     while (<$FILE_HANDLE>) {
  324         if (m/^\#\s*\<\<\<\s*EXECUTE\s*\:\s*OFF\s*\>\>\>/xms) {
  325             delete $test_files->{$file};
  326             last;
  327         }
  328         if (m/^\#\s*\<\<\<\s*EXECUTE_ERROR\s*\:\s*['"](.*)['"]\s*\>\>\>/xms) {
  329             push @{ $test_files->{$file}->{errors} }, $1;
  330         }
  331     }
  332     close $FILE_HANDLE
  333         or croak 'ERROR, Cannot close file ' . $file . ' after reading,' . $OS_ERROR . ', croaking';
  334 }
  335 
  336 sub missing_errors_count {
  337     (my string_hashref $test_files, my string $test_file, my string $stdout_generated, my string $stderr_generated) = @ARG;
  338     my $missing_errors = [];
  339     if ( defined $test_files->{$test_file}->{errors} ) {
  340         foreach my $error ( @{ $test_files->{$test_file}->{errors} } ) {
  341             if (    ( $stdout_generated !~ /\Q$error\E/xms )
  342                 and ( $stderr_generated !~ /\Q$error\E/xms ) )
  343             {
  344                 push @{$missing_errors}, "Error message '$error' expected, but not found";
  345             }
  346         }
  347     }
  348    return scalar @{$missing_errors};
  349 }
  350 
  351 sub success_match {
  352     (my string $test_file, my string_arrayref $test_file_successes, my string $stdout_generated_lines) = @ARG;
  353 #    $RPerl::DEBUG   = 0;
  354 #    $RPerl::VERBOSE = 0;
  355 
  356 #    RPerl::diag( 'in 09_interpret_execute.t success_match(), before foreach loop, received $test_file_successes =', Dumper( $test_file_successes ) );
  357 
  358     my string $success = $test_file_successes->[0];
  359 
  360     # match success strings in-order in captured output
  361 FOREACH_STDOUT_LINE: foreach my string $stdout_generated_line ( @{$stdout_generated_lines} ) {
  362         my boolean $is_regex = 0;
  363         if ((substr $success, 0, 10) eq '[IS_REGEX]') {
  364             substr $success, 0, 10, '';  # discard [IS_REGEX] prefix
  365             $is_regex = 1;
  366         }
  367 
  368 
  369 # START HERE: copy new regex parts to physicsperl & mathperl
  370 # START HERE: copy new regex parts to physicsperl & mathperl
  371 # START HERE: copy new regex parts to physicsperl & mathperl
  372 
  373 
  374 #        RPerl::diag( 'in 09_interpret_execute.t success_match(), top of foreach loop, have $is_regex = ' . $is_regex . "\n" );
  375 #        RPerl::diag( 'in 09_interpret_execute.t success_match(), top of foreach loop, have $success               = ' . $success . "\n" );
  376 #        RPerl::diag( 'in 09_interpret_execute.t success_match(), top of foreach loop, have $stdout_generated_line = ' . $stdout_generated_line . "\n" );
  377 
  378         if ($is_regex) {
  379             # each stdout line is only allowed to match one success string
  380             if ( $stdout_generated_line =~ /$success/ms ) {  # omit quotemeta \Q and \E regex modifiers for regex strings to be matched, also omit /x modifier to correctly match spaces
  381 #                RPerl::diag( 'in 09_interpret_execute.t success_match(), YES REGEX, MATCH' . "\n" );
  382                 shift @{ $test_file_successes };
  383                 if ( ( scalar @{ $test_file_successes } ) == 0 ) { last FOREACH_STDOUT_LINE; }
  384                 $success = $test_file_successes->[0];
  385             }
  386 #            else { RPerl::diag( 'in 09_interpret_execute.t success_match(), YES REGEX, NO MATCH' . "\n" ); }
  387         }
  388         else {
  389             # each stdout line is only allowed to match one success string
  390             if ( $stdout_generated_line =~ /\Q$success\E/xms ) {  # include quotemeta \Q and \E regex modifiers for normal literal strings to be matched
  391 #                RPerl::diag( 'in 09_interpret_execute.t success_match(), no regex, MATCH' . "\n" );
  392                 shift @{ $test_file_successes };
  393                 if ( ( scalar @{ $test_file_successes } ) == 0 ) { last FOREACH_STDOUT_LINE; }
  394                 $success = $test_file_successes->[0];
  395             }
  396 #            else { RPerl::diag( 'in 09_interpret_execute.t success_match(), no regex, NO MATCH' . "\n" ); }
  397         }
  398     }
  399 #    RPerl::diag( 'in 09_interpret_execute.t success_match(), have missing successes =' . "\n" . Dumper( $test_file_successes ) . "\n" );
  400     ok( ( ( scalar @{ $test_file_successes } ) == 0 ), 'Program interprets and executes without errors & with expected output:' . ( q{ } x 10 ) . $test_file );
  401 #    $number_of_tests_run++;
  402 }
  403 
  404 #RPerl::diag( 'in 09_interpret_execute.t, have $number_of_tests_run =' . $number_of_tests_run . "\n" );
  405 
  406 done_testing();
  407 #done_testing($number_of_tests_run);