Fix [RT#66098] -- stricter checking on SvIVX exposed a lack of SvIOK check
[p5sagit/p5-mst-13.2.git] / t / op / regexp.t
index 1b5ac5b..ba5da62 100755 (executable)
 #      y       expect a match
 #      n       expect no match
 #      c       expect an error
+#      T       the test is a TODO (can be combined with y/n/c)
 #      B       test exposes a known bug in Perl, should be skipped
 #      b       test exposes a known bug in Perl, should be skipped if noamp
+#      t       test exposes a bug with threading, TODO if qr_embed_thr
 #
 # Columns 4 and 5 are used only if column 3 contains C<y> or C<c>.
 #
@@ -49,12 +51,25 @@ BEGIN {
 
     chdir 't' if -d 't';
     @INC = '../lib';
+
+    if ($qr_embed_thr) {
+       require Config;
+       if (!$Config::Config{useithreads}) {
+           print "1..0 # Skip: no ithreads\n";
+               exit 0;
+       }
+       if ($ENV{PERL_CORE_MINITEST}) {
+           print "1..0 # Skip: no dynamic loading on miniperl, no threads\n";
+               exit 0;
+       }
+       require threads;
+    }
 }
 
 use strict;
 use warnings FATAL=>"all";
 use vars qw($iters $numtests $bang $ffff $nulnul $OP);
-use vars qw($qr $skip_amp $qr_embed); # set by our callers
+use vars qw($qr $skip_amp $qr_embed $qr_embed_thr); # set by our callers
 
 
 if (!defined $file) {
@@ -73,13 +88,14 @@ $OP = $qr ? 'qr' : 'm';
 
 $| = 1;
 printf "1..%d\n# $iters iterations\n", scalar @tests;
+
 my $test;
 TEST:
 foreach (@tests) {
     $test++;
-    if (!/\S/ || /^\s*#/) {
+    if (!/\S/ || /^\s*#/ || /^__END__$/) {
         print "ok $test # (Blank line or comment)\n";
-        if (/\S/) { print $_ };
+        if (/#/) { print $_ };
         next;
     }
     chomp;
@@ -87,17 +103,25 @@ foreach (@tests) {
     my ($pat, $subject, $result, $repl, $expect, $reason) = split(/\t/,$_,6);
     $reason = '' unless defined $reason;
     my $input = join(':',$pat,$subject,$result,$repl,$expect);
-    $pat = "'$pat'" unless $pat =~ /^[:'\/]/;
+    # the double '' below keeps simple syntax highlighters from going crazy
+    $pat = "'$pat'" unless $pat =~ /^[:''\/]/; 
     $pat =~ s/(\$\{\w+\})/$1/eeg;
     $pat =~ s/\\n/\n/g;
     $subject = eval qq("$subject"); die $@ if $@;
     $expect  = eval qq("$expect"); die $@ if $@;
     $expect = $repl = '-' if $skip_amp and $input =~ /\$[&\`\']/;
+    my $todo_qr = $qr_embed_thr && ($result =~ s/t//);
     my $skip = ($skip_amp ? ($result =~ s/B//i) : ($result =~ s/B//));
     $reason = 'skipping $&' if $reason eq  '' && $skip_amp;
     $result =~ s/B//i unless $skip;
+    my $todo= $result =~ s/T// ? " # TODO" : "";
+    
 
-    for my $study ('', 'study $subject') {
+    for my $study ('', 'study $subject', 'utf8::upgrade($subject)',
+                  'utf8::upgrade($subject); study $subject') {
+       # Need to make a copy, else the utf8::upgrade of an alreay studied
+       # scalar confuses things.
+       my $subject = $subject;
        my $c = $iters;
        my ($code, $match, $got);
         if ($repl eq 'pos') {
@@ -116,6 +140,16 @@ EOFCODE
                 \$got = "$repl";
 EOFCODE
         }
+        elsif ($qr_embed_thr) {
+            $code= <<EOFCODE;
+               # Can't run the match in a subthread, but can do this and
+               # clone the pattern the other way.
+                my \$RE = threads->new(sub {qr$pat})->join();
+                $study;
+                \$match = (\$subject =~ /(?:)\$RE(?:)/) while \$c--;
+                \$got = "$repl";
+EOFCODE
+        }
         else {
             $code= <<EOFCODE;
                 $study;
@@ -123,6 +157,9 @@ EOFCODE
                 \$got = "$repl";
 EOFCODE
         }
+        #$code.=qq[\n\$expect="$expect";\n];
+        #use Devel::Peek;
+        #die Dump($code) if $pat=~/\\h/ and $subject=~/\x{A0}/;
        {
            # Probably we should annotate specific tests with which warnings
            # categories they're known to trigger, and hence should be
@@ -132,35 +169,39 @@ EOFCODE
        }
        chomp( my $err = $@ );
        if ($result eq 'c') {
-           if ($err !~ m!^\Q$expect!) { print "not ok $test (compile) $input => `$err'\n"; next TEST }
+           if ($err !~ m!^\Q$expect!) { print "not ok $test$todo (compile) $input => `$err'\n"; next TEST }
            last;  # no need to study a syntax error
        }
        elsif ( $skip ) {
            print "ok $test # skipped", length($reason) ? " $reason" : '', "\n";
            next TEST;
        }
+       elsif ( $todo_qr ) {
+           print "not ok $test # TODO", length($reason) ? " - $reason" : '', "\n";
+           next TEST;
+       }
        elsif ($@) {
-           print "not ok $test $input => error `$err'\n$code\n$@\n"; next TEST;
+           print "not ok $test$todo $input => error `$err'\n$code\n$@\n"; next TEST;
        }
-       elsif ($result eq 'n') {
-           if ($match) { print "not ok $test ($study) $input => false positive\n"; next TEST }
+       elsif ($result =~ /^n/) {
+           if ($match) { print "not ok $test$todo ($study) $input => false positive\n"; next TEST }
        }
        else {
            if (!$match || $got ne $expect) {
                eval { require Data::Dumper };
                if ($@) {
-                   print "not ok $test ($study) $input => `$got', match=$match\n$code\n";
+                   print "not ok $test$todo ($study) $input => `$got', match=$match\n$code\n";
                }
                else { # better diagnostics
                    my $s = Data::Dumper->new([$subject],['subject'])->Useqq(1)->Dump;
                    my $g = Data::Dumper->new([$got],['got'])->Useqq(1)->Dump;
-                   print "not ok $test ($study) $input => `$got', match=$match\n$s\n$g\n$code\n";
+                   print "not ok $test$todo ($study) $input => `$got', match=$match\n$s\n$g\n$code\n";
                }
                next TEST;
            }
        }
     }
-    print "ok $test\n";
+    print "ok $test$todo\n";
 }
 
 1;