1 

# frozen_string_literal: false


1 
# frozen_string_literal: true

2 
2 
require 'test/unit'

3 
3 
require 'etc'

4 
4 
require_relative 'allpairs'

...  ...  
56 
56 
]

57 
57 

58 
58 
WSTRINGS = [

59 

"aa".force_encoding("utf16be"),

60 

"aaaa".force_encoding("utf32be"),

61 

"aaa".force_encoding("utf32be"),


59 
"aa".dup.force_encoding("utf16be"),


60 
"aaaa".dup.force_encoding("utf32be"),


61 
"aaa".dup.force_encoding("utf32be"),

62 
62 
]

63 
63 

64 
64 
def combination(*args, &b)

...  ...  
71 
71 
if /\.force_encoding\("[AZaz09.:_+]*"\)\z/ =~ d

72 
72 
d

73 
73 
else

74 

"#{d}.force_encoding(#{str.encoding.name.dump})"


74 
"#{d}.dup.force_encoding(#{str.encoding.name.dump})"

75 
75 
end

76 
76 
end

77 
77 

78 
78 
def encdumpargs(args)

79 

r = '('


79 
r = '('.dup

80 
80 
args.each_with_index {a, i

81 
81 
r << ',' if 0 < i

82 
82 
if String === a

...  ...  
90 
90 
end

91 
91 

92 
92 
def encdumpcall(recv, meth, *args, &block)

93 

desc = ''


93 
desc = ''.dup

94 
94 
if String === recv

95 
95 
desc << encdump(recv)

96 
96 
else

...  ...  
115 
115 
desc

116 
116 
end

117 
117 


118 
def strings_2


119 
STRINGS.each { s1 STRINGS.each { s2 yield s1, s2 } }


120 
end


121 


122 
def strings_3


123 
len = STRINGS.length


124 
i = 0 ; j = 0


125 
STRINGS.each { s1


126 
STRINGS.each { s2


127 
yield s1, s2, STRINGS[(i+j) % len]


128 
j += 1


129 
}


130 
i += 1 ; j = 0


131 
}


132 
end


133 

118 
134 
def assert_enccall(recv, meth, *args, &block)

119 
135 
desc = encdumpcall(recv, meth, *args, &block)

120 
136 
result = nil

...  ...  
156 
172 
combination(STRINGS, 2..2, 0..2) {s, nth, len

157 
173 
yield s, nth, len

158 
174 
}

159 

combination(STRINGS, STRINGS) {s, substr


175 
strings_2 {s, substr

160 
176 
yield s, substr

161 
177 
}

162 
178 
combination(STRINGS, 2..2, 0..2) {s, first, last

163 
179 
yield s, first..last

164 
180 
yield s, first...last

165 
181 
}

166 

combination(STRINGS, STRINGS) {s1, s2

167 

if !s2.valid_encoding?

168 

next

169 

end

170 

yield s1, Regexp.new(Regexp.escape(s2))


182 
STRINGS.each { s2


183 
next unless s2.valid_encoding?


184 
re = Regexp.new(Regexp.escape(s2))


185 
STRINGS.each { s1 yield s1, re }

171 
186 
}

172 
187 
combination(STRINGS, STRINGS, 0..2) {s1, s2, nth

173 
188 
if !s2.valid_encoding?

...  ...  
213 
228 
end

214 
229 

215 
230 
def test_str_plus

216 

combination(STRINGS, STRINGS) {s1, s2


231 
strings_2 {s1, s2

217 
232 
if s1.encoding != s2.encoding && !s1.ascii_only? && !s2.ascii_only?

218 
233 
assert_raise(Encoding::CompatibilityError) { s1 + s2 }

219 
234 
else

...  ...  
237 
252 

238 
253 
def test_sprintf_s

239 
254 
STRINGS.each {s

240 

assert_strenc(b(s), s.encoding, "%s".force_encoding(s.encoding) % s)


255 
assert_strenc(b(s), s.encoding, "%s".dup.force_encoding(s.encoding) % s)

241 
256 
if !s.empty? # xxx

242 
257 
t = enccall(b("%s"), :%, s)

243 
258 
assert_strenc(b(s), (b('')+s).encoding, t)

...  ...  
252 
267 
end

253 
268 

254 
269 
def test_str_eq_symmetric

255 

combination(STRINGS, STRINGS) {s1, s2


270 
strings_2 {s1, s2

256 
271 
if s1 == s2

257 
272 
assert_equal(s2, s1, "#{encdump s2} == #{encdump s1}")

258 
273 
else

...  ...  
262 
277 
end

263 
278 

264 
279 
def test_str_eq_transitive

265 

combination(STRINGS, STRINGS, STRINGS) {s1, s2, s3


280 
strings_3 {s1, s2, s3

266 
281 
if s1 == s2 && s2 == s3

267 
282 
assert_equal(s1, s3, "transitive: #{encdump s1} == #{encdump s2} == #{encdump s3}")

268 
283 
end

...  ...  
270 
285 
end

271 
286 

272 
287 
def test_str_eq

273 

combination(STRINGS, STRINGS) {s1, s2


288 
strings_2 {s1, s2

274 
289 
desc_eq = "#{encdump s1} == #{encdump s2}"

275 
290 
if b(s1) == b(s2) and

276 
291 
(s1.ascii_only? && s2.ascii_only? or

...  ...  
289 
304 
end

290 
305 

291 
306 
def test_str_concat

292 

combination(STRINGS, STRINGS) {s1, s2


307 
strings_2 {s1, s2

293 
308 
s = s1.dup

294 
309 
if s1.ascii_only?  s2.ascii_only?  s1.encoding == s2.encoding

295 
310 
s << s2

...  ...  
304 
319 

305 
320 
def test_str_aref

306 
321 
STRINGS.each {s

307 

t = ''.force_encoding(s.encoding)


322 
t = ''.dup.force_encoding(s.encoding)

308 
323 
0.upto(s.length1) {i

309 
324 
u = s[i]

310 
325 
assert_predicate(u, :valid_encoding?) if s.valid_encoding?

...  ...  
316 
331 

317 
332 
def test_str_aref_len

318 
333 
STRINGS.each {s

319 

t = ''.force_encoding(s.encoding)


334 
t = ''.dup.force_encoding(s.encoding)

320 
335 
0.upto(s.length1) {i

321 
336 
u = s[i,1]

322 
337 
assert_predicate(u, :valid_encoding?) if s.valid_encoding?

...  ...  
326 
341 
}

327 
342 

328 
343 
STRINGS.each {s

329 

t = ''.force_encoding(s.encoding)


344 
t = ''.dup.force_encoding(s.encoding)

330 
345 
0.step(s.length1, 2) {i

331 
346 
u = s[i,2]

332 
347 
assert_predicate(u, :valid_encoding?) if s.valid_encoding?

...  ...  
337 
352 
end

338 
353 

339 
354 
def test_str_aref_substr

340 

combination(STRINGS, STRINGS) {s1, s2


355 
strings_2 {s1, s2

341 
356 
if s1.ascii_only?  s2.ascii_only?  s1.encoding == s2.encoding

342 
357 
t = enccall(s1, :[], s2)

343 
358 
if t != nil

...  ...  
373 
388 
if last < 0

374 
389 
last += s.length

375 
390 
end

376 

t2 = ''


391 
t2 = ''.dup

377 
392 
first.upto(last) {i

378 
393 
c = s[i]

379 
394 
t2 << c if c

...  ...  
401 
416 
last += s.length

402 
417 
end

403 
418 
assert_predicate(t, :valid_encoding?) if s.valid_encoding?

404 

t2 = ''


419 
t2 = ''.dup

405 
420 
first.upto(last1) {i

406 
421 
c = s[i]

407 
422 
t2 << c if c

...  ...  
411 
426 
end

412 
427 

413 
428 
def test_str_assign

414 

combination(STRINGS, STRINGS) {s1, s2


429 
strings_2 {s1, s2

415 
430 
(2).upto(2) {i

416 
431 
t = s1.dup

417 
432 
if s1.ascii_only?  s2.ascii_only?  s1.encoding == s2.encoding

...  ...  
472 
487 
end

473 
488 

474 
489 
def test_str_assign_substr

475 

combination(STRINGS, STRINGS, STRINGS) {s1, s2, s3


490 
strings_3 {s1, s2, s3

476 
491 
t = s1.dup

477 
492 
encs = [

478 
493 
!s1.ascii_only? ? s1.encoding : nil,

...  ...  
554 
569 
end

555 
570 

556 
571 
def test_str_cmp

557 

combination(STRINGS, STRINGS) {s1, s2


572 
strings_2 {s1, s2

558 
573 
desc = "#{encdump s1} <=> #{encdump s2}"

559 
574 
r = s1 <=> s2

560 
575 
if s1 == s2

...  ...  
585 
600 
end

586 
601 

587 
602 
def test_str_casecmp

588 

combination(STRINGS, STRINGS) {s1, s2


603 
strings_2 {s1, s2

589 
604 
#puts "#{encdump(s1)}.casecmp(#{encdump(s2)})"

590 
605 
next unless s1.valid_encoding? && s2.valid_encoding? && Encoding.compatible?(s1, s2)

591 
606 
r = s1.casecmp(s2)

...  ...  
657 
672 
end

658 
673 

659 
674 
def test_str_chomp

660 

combination(STRINGS, STRINGS) {s1, s2


675 
strings_2 {s1, s2

661 
676 
if !s1.ascii_only? && !s2.ascii_only? && !Encoding.compatible?(s1,s2)

662 
677 
if s1.bytesize > s2.bytesize

663 
678 
assert_raise(Encoding::CompatibilityError, "#{encdump(s1)}.chomp(#{encdump(s2)})") do

...  ...  
677 
692 

678 
693 
def test_str_smart_chomp

679 
694 
bug10893 = '[rubycore:68258] [Bug #10893]'

680 

encodings = Encoding.list.select {enc !enc.dummy?}

681 

combination(encodings, encodings) do e1, e2


695 
encodings = Encoding.list.reject {enc enc.dummy?}.uniq


696 
ary_test = [ ["abc\n", ""], ["abc\n", "\n"], ["abc\r\n", ""], ["abc\r\n", "\n"] ]


697 
encodings.each { e1


698 
ary_test[0][0] = "abc\n".encode(e1)


699 
ary_test[1][0] = "abc\n".encode(e1)


700 
ary_test[2][0] = "abc\r\n".encode(e1)


701 
ary_test[3][0] = "abc\r\n".encode(e1)

682 
702 
expected = "abc".encode(e1)

683 

combination(["abc\n", "abc\r\n"], ["", "\n"]) do str, rs

684 

assert_equal(expected, str.encode(e1).chomp(rs.encode(e2)), bug10893)

685 

end

686 

end


703 
encodings.each { e2


704 
ary_test.each do str, rs


705 
assert_equal(expected, str.chomp(rs.encode(e2)), bug10893)


706 
end


707 
}


708 
}

687 
709 
end

688 
710 

689 
711 
def test_str_chop

...  ...  
728 
750 
end

729 
751 

730 
752 
def test_str_count

731 

combination(STRINGS, STRINGS) {s1, s2


753 
strings_2 {s1, s2

732 
754 
desc = proc {encdumpcall(s1, :count, s2)}

733 
755 
if !s1.valid_encoding?  !s2.valid_encoding?

734 
756 
assert_raise(ArgumentError, Encoding::CompatibilityError, desc) { s1.count(s2) }

...  ...  
752 
774 
end

753 
775 

754 
776 
def test_str_crypt

755 

combination(STRINGS, STRINGS) {str, salt


777 
STRINGS.each { salt

756 
778 
# skip input other than [09AZaz./] to confirm strict behavior

757 
779 
next unless salt.ascii_only? && /\A[09azAZ.\/]+\z/ =~ salt

758 


759 

confirm_crypt_result(str, salt)


780 
STRINGS.each { str confirm_crypt_result(str, salt) }

760 
781 
}

761 
782 
end

762 
783 

763 
784 
if !strict_crypt

764 
785 
def test_str_crypt_nonstrict

765 

combination(STRINGS, STRINGS) {str, salt


786 
STRINGS.each { salt

766 
787 
# only test input other than [09AZaz./] to confirm nonstrict behavior

767 
788 
next if salt.ascii_only? && /\A[09azAZ.\/]+\z/ =~ salt

768 


769 

confirm_crypt_result(str, salt)


789 
STRINGS.each { str confirm_crypt_result(str, salt) }

770 
790 
}

771 
791 
end

772 
792 
end

...  ...  
782 
802 
end

783 
803 

784 
804 
def test_str_delete

785 

combination(STRINGS, STRINGS) {s1, s2


805 
strings_2 {s1, s2

786 
806 
if s1.empty?

787 
807 
assert_equal(s1, s1.delete(s2))

788 
808 
next

...  ...  
832 
852 
end

833 
853 

834 
854 
def test_str_each_line

835 

combination(STRINGS, STRINGS) {s1, s2


855 
strings_2 {s1, s2

836 
856 
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding

837 
857 
assert_raise(Encoding::CompatibilityError) { s1.each_line(s2) {} }

838 
858 
next

...  ...  
880 
900 
end

881 
901 

882 
902 
def test_str_include?

883 

combination(STRINGS, STRINGS) {s1, s2


903 
strings_2 {s1, s2

884 
904 
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding

885 
905 
assert_raise(Encoding::CompatibilityError) { s1.include?(s2) }

886 
906 
assert_raise(Encoding::CompatibilityError) { s1.index(s2) }

...  ...  
1049 
1069 
end

1050 
1070 

1051 
1071 
def test_str_replace

1052 

combination(STRINGS, STRINGS) {s1, s2


1072 
strings_2 {s1, s2

1053 
1073 
t = s1.dup

1054 
1074 
t.replace s2

1055 
1075 
assert_equal(s2, t)

...  ...  
1070 
1090 
end

1071 
1091 

1072 
1092 
def test_str_scan

1073 

combination(STRINGS, STRINGS) {s1, s2


1093 
strings_2 {s1, s2

1074 
1094 
desc = proc {"#{s1.dump}.scan(#{s2.dump})"}

1075 
1095 
if !s2.valid_encoding?

1076 
1096 
assert_raise(RegexpError, desc) { s1.scan(s2) }

...  ...  
1137 
1157 
end

1138 
1158 

1139 
1159 
def test_str_split

1140 

combination(STRINGS, STRINGS) {s1, s2


1160 
strings_2 {s1, s2

1141 
1161 
if !s2.valid_encoding?

1142 
1162 
assert_raise(ArgumentError, RegexpError) { s1.split(s2) }

1143 
1163 
next

...  ...  
1165 
1185 
end

1166 
1186 

1167 
1187 
def test_str_squeeze

1168 

combination(STRINGS, STRINGS) {s1, s2


1188 
strings_2 {s1, s2

1169 
1189 
if !s1.valid_encoding?  !s2.valid_encoding?

1170 
1190 
assert_raise(ArgumentError, Encoding::CompatibilityError, "#{encdump s1}.squeeze(#{encdump s2})") { s1.squeeze(s2) }

1171 
1191 
next

...  ...  
1254 
1274 
end

1255 
1275 

1256 
1276 
def test_tr

1257 

combination(STRINGS, STRINGS, STRINGS) {s1, s2, s3


1277 
strings_3 {s1, s2, s3

1258 
1278 
desc = "#{encdump s1}.tr(#{encdump s2}, #{encdump s3})"

1259 
1279 
if s1.empty?

1260 
1280 
assert_equal(s1, s1.tr(s2, s3), desc)

...  ...  
1283 
1303 
end

1284 
1304 

1285 
1305 
def test_tr_sjis

1286 

expected = "\x83}\x83~\x83\x80\x83\x81\x83\x82".force_encoding(Encoding::SJIS)

1287 

source = "\xCF\xD0\xD1\xD2\xD3".force_encoding(Encoding::SJIS)

1288 

from = "\xCF\xD3".force_encoding(Encoding::SJIS)

1289 

to = "\x83}\x83\x82".force_encoding(Encoding::SJIS)


1306 
expected = "\x83}\x83~\x83\x80\x83\x81\x83\x82".dup.force_encoding(Encoding::SJIS)


1307 
source = "\xCF\xD0\xD1\xD2\xD3".dup.force_encoding(Encoding::SJIS)


1308 
from = "\xCF\xD3".dup.force_encoding(Encoding::SJIS)


1309 
to = "\x83}\x83\x82".dup.force_encoding(Encoding::SJIS)

1290 
1310 
assert_equal(expected, source.tr(from, to))

1291 
1311 

1292 

expected = "\x84}\x84~\x84\x80\x84\x81\x84\x82".force_encoding(Encoding::SJIS)

1293 

source = "\x84M\x84N\x84O\x84P\x84Q".force_encoding(Encoding::SJIS)

1294 

from = "\x84@\x84`".force_encoding(Encoding::SJIS)

1295 

to = "\x84p\x84\x91".force_encoding(Encoding::SJIS)


1312 
expected = "\x84}\x84~\x84\x80\x84\x81\x84\x82".dup.force_encoding(Encoding::SJIS)


1313 
source = "\x84M\x84N\x84O\x84P\x84Q".dup.force_encoding(Encoding::SJIS)


1314 
from = "\x84@\x84`".dup.force_encoding(Encoding::SJIS)


1315 
to = "\x84p\x84\x91".dup.force_encoding(Encoding::SJIS)

1296 
1316 
assert_equal(expected, source.tr(from, to))

1297 
1317 
end

1298 
1318 

1299 
1319 
def test_tr_s

1300 

combination(STRINGS, STRINGS, STRINGS) {s1, s2, s3


1320 
strings_3 {s1, s2, s3

1301 
1321 
desc = "#{encdump s1}.tr_s(#{encdump s2}, #{encdump s3})"

1302 
1322 
if s1.empty?

1303 
1323 
assert_equal(s1, s1.tr_s(s2, s3), desc)

...  ...  
1362 
1382 
s = t

1363 
1383 
}

1364 
1384 
}

1365 


1366 

Encoding.list.each do enc

1367 

next if enc.dummy?


1385 
encodings = Encoding.list.reject {enc enc.dummy?}.uniq


1386 
encodings.each do enc

1368 
1387 
{"A"=>"B", "A1"=>"A2", "A9"=>"B0", "9"=>"10", "Z"=>"AA"}.each do orig, expected

1369 
1388 
s = orig.encode(enc)

1370 
1389 
assert_strenc(expected.encode(enc), enc, s.succ, proc {"#{orig.dump}.encode(#{enc}).succ"})

...  ...  
1378 
1397 
end

1379 
1398 

1380 
1399 
def test_str_hash

1381 

combination(STRINGS, STRINGS) {s1, s2


1400 
strings_2 {s1, s2

1382 
1401 
if s1.eql?(s2)

1383 
1402 
assert_equal(s1.hash, s2.hash, "#{encdump s1}.hash == #{encdump s2}.dump")

1384 
1403 
end

...  ...  
1394 
1413 
end

1395 
1414 

1396 
1415 
def test_str_sub

1397 

combination(STRINGS, STRINGS, STRINGS) {s1, s2, s3


1416 
strings_3 {s1, s2, s3

1398 
1417 
if !s2.valid_encoding?

1399 
1418 
assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }

1400 
1419 
next

...  ...  
1452 
1471 
end

1453 
1472 

1454 
1473 
def test_str_sub!

1455 

combination(STRINGS, STRINGS, STRINGS) {s1, s2, s3


1474 
strings_3 {s1, s2, s3

1456 
1475 
if !s2.valid_encoding?

1457 
1476 
assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }

1458 
1477 
next

...  ...  
1551 
1570 
end

1552 
1571 

1553 
1572 
def test_str_end_with?

1554 

combination(STRINGS, STRINGS) {s1, s2


1573 
strings_2 {s1, s2

1555 
1574 
desc = "#{encdump s1}.end_with?(#{encdump s2})"

1556 
1575 
if !str_enc_compatible?(s1, s2)

1557 
1576 
assert_raise(Encoding::CompatibilityError, desc) { s1.end_with?(s2) }

...  ...  
1570 
1589 
end

1571 
1590 

1572 
1591 
def test_str_start_with?

1573 

combination(STRINGS, STRINGS) {s1, s2


1592 
strings_2 {s1, s2

1574 
1593 
desc = "#{encdump s1}.start_with?(#{encdump s2})"

1575 
1594 
if !str_enc_compatible?(s1, s2)

1576 
1595 
assert_raise(Encoding::CompatibilityError, desc) { s1.start_with?(s2) }

...  ...  
1605 
1624 
end

1606 
1625 

1607 
1626 
def test_str_partition

1608 

combination(STRINGS, STRINGS) {s1, s2


1627 
strings_2 {s1, s2

1609 
1628 
desc = "#{encdump s1}.partition(#{encdump s2})"

1610 
1629 
if !str_enc_compatible?(s1, s2)

1611 
1630 
assert_raise(Encoding::CompatibilityError, desc) { s1.partition(s2) }

...  ...  
1621 
1640 
end

1622 
1641 

1623 
1642 
def test_str_rpartition

1624 

combination(STRINGS, STRINGS) {s1, s2


1643 
strings_2 {s1, s2

1625 
1644 
desc = "#{encdump s1}.rpartition(#{encdump s2})"

1626 
1645 
if !str_enc_compatible?(s1, s2)

1627 
1646 
assert_raise(Encoding::CompatibilityError, desc) { s1.rpartition(s2) }
