This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Let taint.t run under miniperl
[perl5.git] / t / op / tr.t
old mode 100755 (executable)
new mode 100644 (file)
index c38b208..580d55a
--- a/t/op/tr.t
+++ b/t/op/tr.t
@@ -1,12 +1,14 @@
 # tr.t
 
+use utf8;
+
 BEGIN {
     chdir 't' if -d 't';
     @INC = '../lib';
     require './test.pl';
 }
 
-plan tests => 118;
+plan tests => 134;
 
 my $Is_EBCDIC = (ord('i') == 0x89 & ord('J') == 0xd1);
 
@@ -44,6 +46,27 @@ is($_, "aBCDEFGHIJKLMNOPQRSTUVWXYz",    'partial uc');
 (my $g = 1.5) =~ tr/1/3/;
 is($x + $y + $f + $g, 71,   'tr cancels IOK and NOK');
 
+# /r
+$_ = 'adam';
+is y/dam/ve/rd, 'eve', '/r';
+is $_, 'adam', '/r leaves param alone';
+$g = 'ruby';
+is $g =~ y/bury/repl/r, 'perl', '/r with explicit param';
+is $g, 'ruby', '/r leaves explicit param alone';
+is "aaa" =~ y\a\b\r, 'bbb', '/r with constant param';
+ok !eval '$_ !~ y///r', "!~ y///r is forbidden";
+like $@, qr\^Using !~ with tr///r doesn't make sense\,
+  "!~ y///r error message";
+{
+  my $w;
+  my $wc;
+  local $SIG{__WARN__} = sub { $w = shift; ++$wc };
+  local $^W = 1;
+  eval 'y///r; 1';
+  like $w, qr '^Useless use of non-destructive transliteration \(tr///r\)',
+    '/r warns in void context';
+  is $wc, 1, '/r warns just once';
+}
 
 # perlbug [ID 20000511.005]
 $_ = 'fred';
@@ -163,10 +186,6 @@ eval "tr/m-d/ /";
 like($@, qr/^Invalid range "m-d" in transliteration operator/,
               'reversed range check');
 
-eval '$1 =~ tr/x/y/';
-like($@, qr/^Modification of a read-only value attempted/,
-              'cannot update read-only var');
-
 'abcdef' =~ /(bcd)/;
 is(eval '$1 =~ tr/abcd//', 3,  'explicit read-only count');
 is($@, '',                      '    no error');
@@ -465,3 +484,54 @@ is($s, "AxBC", "utf8, DELETE");
     is($c, "\x20\x30\x40\x50\x60", "tr/\\x00-\\x1f//d");
 }
 
+($s) = keys %{{pie => 3}};
+SKIP: {
+    if (!eval { require XS::APItest }) { skip "no XS::APItest", 2 }
+    my $wasro = XS::APItest::SvIsCOW($s);
+    ok $wasro, "have a COW";
+    $s =~ tr/i//;
+    ok( XS::APItest::SvIsCOW($s),
+       "count-only tr doesn't deCOW COWs" );
+}
+
+# [ RT #61520 ]
+#
+# under threads, unicode tr within a cloned closure would SEGV or assert
+# fail, since the pointer in the pad to the swash was getting zeroed out
+# in the proto-CV
+
+{
+    my $x = "\x{142}";
+    sub {
+       $x =~ tr[\x{142}][\x{143}];
+    }->();
+    is($x,"\x{143}", "utf8 + closure");
+}
+
+# Freeing of trans ops prior to pmtrans() [perl #102858].
+eval q{ $a ~= tr/a/b/; };
+ok 1;
+SKIP: {
+    no warnings "deprecated";
+    skip "no encoding", 1 unless eval { require encoding; 1 };
+    eval q{ use encoding "utf8"; $a ~= tr/a/b/; };
+    ok 1;
+}
+
+{ # [perl #113584]
+
+    my $x = "Perlα";
+    $x =~ tr/αα/βγ/;
+    { no warnings 'utf8'; print "# $x\n"; } # No note() to avoid wide warning.
+    is($x, "Perlβ", "Only first of multiple transliterations is used");
+}
+
+# tr/a/b/ should fail even on zero-length read-only strings
+use constant nullrocow => (keys%{{""=>undef}})[0];
+for ("", nullrocow) {
+    eval { $_ =~ y/a/b/ };
+    like $@, qr/^Modification of a read-only value attempted at /,
+        'tr/a/b/ fails on zero-length ro string';
+}
+
+1;