      assert_equal(expected, source.tr(from, to))
    end
  
-@@ -1362,9 +1371,8 @@ def test_str_succ
+   def test_tr_s
+-    combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
++    strings_3 {|s1, s2, s3|
+       desc = "#{encdump s1}.tr_s(#{encdump s2}, #{encdump s3})"
+       if s1.empty?
+         assert_equal(s1, s1.tr_s(s2, s3), desc)
+@@ -1362,9 +1382,8 @@ def test_str_succ
          s = t
        }
      }

       0.upto(s.length-1) {|i|
         u = s[i]
         assert_predicate(u, :valid_encoding?) if s.valid_encoding?
@@ -316,7 +320,7 @@ def test_str_aref
 
   def test_str_aref_len
     STRINGS.each {|s|

     if String === recv
       desc << encdump(recv)
     else
@@ -115,6 +115,22 @@ def encdumpcall(recv, meth, *args, &block)
     desc
   end
 
+  def strings_2
+    STRINGS.each { |s1| STRINGS.each { |s2| yield s1, s2 } }
+  end
+
+  def strings_3
+    len = STRINGS.length
+    i = 0 ; j = 0
+    STRINGS.each { |s1|
+      STRINGS.each { |s2|
+        yield s1, s2, STRINGS[(i+j) % len]
+        j += 1
+      }
+      i += 1 ; j = 0
+    }
+  end
+
   def assert_enccall(recv, meth, *args, &block)
     desc = encdumpcall(recv, meth, *args, &block)
     result = nil
@@ -156,18 +172,17 @@ def each_slice_call
     combination(STRINGS, -2..2, 0..2) {|s, nth, len|
       yield s, nth, len
     }
-    combination(STRINGS, STRINGS) {|s, substr|
+    strings_2 {|s, substr|
       yield s, substr
     }
     combination(STRINGS, -2..2, 0..2) {|s, first, last|
       yield s, first..last
       yield s, first...last
