Blame t/regexp.t

Packit 14c646
#!perl -w
Packit 14c646
use strict;
Packit 14c646
use Storable "dclone";
Packit 14c646
use Test::More;
Packit 14c646
Packit 14c646
my $version = int(($]-5)*1000);
Packit 14c646
Packit 14c646
$version >= 8
Packit 14c646
  or plan skip_all => "regexps not supported before 5.8";
Packit 14c646
Packit 14c646
my @tests;
Packit 14c646
while (<DATA>) {
Packit 14c646
    chomp;
Packit 14c646
    next if /^\s*#/ || !/\S/;
Packit 14c646
    my ($range, $code, $match, $name) = split /\s*;\s*/;
Packit 14c646
    defined $name or die "Bad test line";
Packit 14c646
    my $ascii_only = $range =~ s/A//;
Packit 14c646
    next if $ascii_only and ord("A") != 65;
Packit 14c646
    if ($range =~ /^(\d+)-$/) {
Packit 14c646
        next if $version < $1
Packit 14c646
    }
Packit 14c646
    elsif ($range =~ /^-(\d+)$/) {
Packit 14c646
        next if $version > $1
Packit 14c646
    }
Packit 14c646
    elsif ($range =~ /^(\d+)-(\d+)$/) {
Packit 14c646
        next if $version < $1 || $version > $2;
Packit 14c646
    }
Packit 14c646
    elsif ($range ne "-") {
Packit 14c646
        die "Invalid version range $range for $name";
Packit 14c646
    }
Packit 14c646
    my @match = split /\s*,\s*/, $match;
Packit 14c646
    for my $m (@match) {
Packit 14c646
	my $not = $m =~ s/^!//;
Packit 14c646
	my $cmatch = eval $m;
Packit 14c646
	die if $@;
Packit 14c646
        push @tests, [ $code, $not, $cmatch, $m, $name ];
Packit 14c646
    }
Packit 14c646
}
Packit 14c646
Packit 14c646
plan tests => 9 + 3*scalar(@tests);
Packit 14c646
Packit 14c646
SKIP:
Packit 14c646
{
Packit 14c646
    $version >= 14 && $version < 20
Packit 14c646
      or skip "p introduced in 5.14, pointless from 5.20", 4;
Packit 14c646
    my $q1 = eval "qr/b/p";
Packit 14c646
    my $q2 = eval "qr/b/";
Packit 14c646
    my $c1 = dclone($q1);
Packit 14c646
    my $c2 = dclone($q2);
Packit 14c646
    ok("abc" =~ $c1, "abc matches $c1");
Packit 14c646
    is(${^PREMATCH}, "a", "check p worked");
Packit 14c646
    ok("cba" =~ $c2, "cba matches $c2");
Packit 14c646
    isnt(${^PREMATCH}, "c", "check no p worked");
Packit 14c646
}
Packit 14c646
Packit 14c646
SKIP:
Packit 14c646
{
Packit 14c646
    $version >= 24
Packit 14c646
      or skip "n introduced in 5.22", 4;
Packit 14c646
    my $c1 = dclone(eval "qr/(\\w)/");
Packit 14c646
    my $c2 = dclone(eval "qr/(\\w)/n");
Packit 14c646
    ok("a" =~ $c1, "a matches $c1");
Packit 14c646
    is($1, "a", "check capturing preserved");
Packit 14c646
    ok("b" =~ $c2, "b matches $c2");
Packit 14c646
    isnt($1, "b", "check non-capturing preserved");
Packit 14c646
}
Packit 14c646
Packit 14c646
SKIP:
Packit 14c646
{
Packit 14c646
    $version >= 8
Packit 14c646
      or skip "Cannot retrieve before 5.8", 1;
Packit 14c646
    my $x;
Packit 14c646
    my $re = qr/a(?{ $x = 1 })/;
Packit 14c646
    use re 'eval';
Packit 14c646
    ok(!eval { dclone($re) }, "should fail to clone, even with use re 'eval'");
Packit 14c646
}
Packit 14c646
Packit 14c646
for my $test (@tests) {
Packit 14c646
    my ($code, $not, $match, $matchc, $name) = @$test;
Packit 14c646
    my $qr = eval $code;
Packit 14c646
    die "Could not compile $code: $@" if $@;
Packit 14c646
    if ($not) {
Packit 14c646
	unlike($match, $qr, "$name: pre(not) match $matchc");
Packit 14c646
    }
Packit 14c646
    else {
Packit 14c646
	like($match, $qr, "$name: prematch $matchc");
Packit 14c646
    }
Packit 14c646
    my $qr2 = dclone($qr);
Packit 14c646
    if ($not) {
Packit 14c646
	unlike($match, $qr2, "$name: (not) match $matchc");
Packit 14c646
    }
Packit 14c646
    else {
Packit 14c646
	like($match, $qr2, "$name: match $matchc");
Packit 14c646
    }
Packit 14c646
Packit 14c646
    # this is unlikely to be a problem, but make sure regexps are frozen sanely
Packit 14c646
    # as part of a data structure
Packit 14c646
    my $a2 = dclone([ $qr ]);
Packit 14c646
    if ($not) {
Packit 14c646
	unlike($match, $a2->[0], "$name: (not) match $matchc (array)");
Packit 14c646
    }
Packit 14c646
    else {
Packit 14c646
	like($match, $a2->[0], "$name: match $matchc (array)");
Packit 14c646
    }
Packit 14c646
}
Packit 14c646
Packit 14c646
__DATA__
Packit 14c646
# semi-colon separated:
Packit 14c646
# perl version range; regexp qr; match string; name
Packit 14c646
# - version range is PERL_VERSION, ie 22 for 5.22 as from-to with both from
Packit 14c646
#   and to optional (so "-" is all versions.
Packit 14c646
# - match string is , separated match strings
Packit 14c646
# - if a match string starts with ! it mustn't match, otherwise it must
Packit 14c646
#   spaces around the commas ignored.
Packit 14c646
#   The initial "!" is stripped and the remainder treated as perl code to define
Packit 14c646
#   the string to (not) be matched
Packit 14c646
-; qr/foo/ ; "foo",!"fob" ; simple
Packit 14c646
-; qr/foo/i ; "foo","FOO",!"fob" ; simple case insensitive
Packit 14c646
-; qr/f o o/x ; "foo", !"f o o" ; /x
Packit 14c646
-; qr(a/b) ; "a/b" ; alt quotes
Packit 14c646
A-; qr(\x2E) ; ".", !"a" ; \x2E - hex meta
Packit 14c646
-; qr/\./ ; "." , !"a" ; \. - backslash meta
Packit 14c646
8- ; qr/\x{100}/ ; "\x{100}" ; simple unicode
Packit 14c646
12- ; qr/fss/i ; "f\xDF\x{101}" ; case insensive unicode promoted
Packit 14c646
22-; qr/fss/ui ; "f\xDF" ; case insensitive unicode SS /iu
Packit 14c646
22-; qr/fss/aai ; !"f\xDF" ; case insensitive unicode SS /iaa
Packit 14c646
22-; qr/f\w/a ; "fo", !"f\xff" ; simple /a flag