PageRenderTime 56ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/test/ruby/test_m17n_comb.rb

http://github.com/ruby/ruby
Ruby | 1659 lines | 1534 code | 111 blank | 14 comment | 306 complexity | bd416c83fbe3de852d839c60ee0a3cc3 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. # frozen_string_literal: false
  2. require 'test/unit'
  3. require 'etc'
  4. require_relative 'allpairs'
  5. class TestM17NComb < Test::Unit::TestCase
  6. def assert_encoding(encname, actual, message=nil)
  7. assert_equal(Encoding.find(encname), actual, message)
  8. end
  9. module AESU
  10. def a(str) str.dup.force_encoding(Encoding::US_ASCII) end
  11. def b(str) str.b end
  12. def e(str) str.dup.force_encoding(Encoding::EUC_JP) end
  13. def s(str) str.dup.force_encoding(Encoding::SJIS) end
  14. def u(str) str.dup.force_encoding(Encoding::UTF_8) end
  15. end
  16. include AESU
  17. extend AESU
  18. def assert_strenc(bytes, enc, actual, message=nil)
  19. assert_instance_of(String, actual, message)
  20. enc = Encoding.find(enc) if String === enc
  21. assert_equal(enc, actual.encoding, message)
  22. assert_equal(b(bytes), b(actual), message)
  23. end
  24. STRINGS = [
  25. b(""), e(""), s(""), u(""),
  26. b("a"), e("a"), s("a"), u("a"),
  27. b("."), e("."), s("."), u("."),
  28. # single character
  29. b("\x80"), b("\xff"),
  30. e("\xa1\xa1"), e("\xfe\xfe"),
  31. e("\x8e\xa1"), e("\x8e\xfe"),
  32. e("\x8f\xa1\xa1"), e("\x8f\xfe\xfe"),
  33. s("\x81\x40"), s("\xfc\xfc"),
  34. s("\xa1"), s("\xdf"),
  35. u("\xc2\x80"), u("\xf4\x8f\xbf\xbf"),
  36. # same byte sequence
  37. b("\xc2\xa1"), e("\xc2\xa1"), s("\xc2\xa1"), u("\xc2\xa1"),
  38. s("\x81A"), # mutibyte character which contains "A"
  39. s("\x81a"), # mutibyte character which contains "a"
  40. # invalid
  41. e("\xa1"), e("\x80"),
  42. s("\x81"), s("\x80"),
  43. u("\xc2"), u("\x80"),
  44. # for transitivity test
  45. u("\xe0\xa0\xa1"), e("\xe0\xa0\xa1"), s("\xe0\xa0\xa1"), # [ruby-dev:32693]
  46. e("\xa1\xa1"), b("\xa1\xa1"), s("\xa1\xa1"), # [ruby-dev:36484]
  47. ]
  48. WSTRINGS = [
  49. "aa".force_encoding("utf-16be"),
  50. "aaaa".force_encoding("utf-32be"),
  51. "aaa".force_encoding("utf-32be"),
  52. ]
  53. def combination(*args, &b)
  54. AllPairs.each(*args, &b)
  55. #AllPairs.exhaustive_each(*args, &b)
  56. end
  57. def encdump(str)
  58. d = str.dump
  59. if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
  60. d
  61. else
  62. "#{d}.force_encoding(#{str.encoding.name.dump})"
  63. end
  64. end
  65. def encdumpargs(args)
  66. r = '('
  67. args.each_with_index {|a, i|
  68. r << ',' if 0 < i
  69. if String === a
  70. r << encdump(a)
  71. else
  72. r << a.inspect
  73. end
  74. }
  75. r << ')'
  76. r
  77. end
  78. def encdumpcall(recv, meth, *args, &block)
  79. desc = ''
  80. if String === recv
  81. desc << encdump(recv)
  82. else
  83. desc << recv.inspect
  84. end
  85. desc << '.' << meth.to_s
  86. if !args.empty?
  87. desc << '('
  88. args.each_with_index {|a, i|
  89. desc << ',' if 0 < i
  90. if String === a
  91. desc << encdump(a)
  92. else
  93. desc << a.inspect
  94. end
  95. }
  96. desc << ')'
  97. end
  98. if block
  99. desc << ' {}'
  100. end
  101. desc
  102. end
  103. def assert_enccall(recv, meth, *args, &block)
  104. desc = encdumpcall(recv, meth, *args, &block)
  105. result = nil
  106. assert_nothing_raised(desc) {
  107. result = recv.send(meth, *args, &block)
  108. }
  109. result
  110. end
  111. alias enccall assert_enccall
  112. def assert_str_enc_propagation(t, s1, s2)
  113. if !s1.ascii_only?
  114. assert_equal(s1.encoding, t.encoding)
  115. elsif !s2.ascii_only?
  116. assert_equal(s2.encoding, t.encoding)
  117. else
  118. assert_include([s1.encoding, s2.encoding], t.encoding)
  119. end
  120. end
  121. def assert_same_result(expected_proc, actual_proc)
  122. e = nil
  123. begin
  124. t = expected_proc.call
  125. rescue
  126. e = $!
  127. end
  128. if e
  129. assert_raise(e.class) { actual_proc.call }
  130. else
  131. assert_equal(t, actual_proc.call)
  132. end
  133. end
  134. def each_slice_call
  135. combination(STRINGS, -2..2) {|s, nth|
  136. yield s, nth
  137. }
  138. combination(STRINGS, -2..2, 0..2) {|s, nth, len|
  139. yield s, nth, len
  140. }
  141. combination(STRINGS, STRINGS) {|s, substr|
  142. yield s, substr
  143. }
  144. combination(STRINGS, -2..2, 0..2) {|s, first, last|
  145. yield s, first..last
  146. yield s, first...last
  147. }
  148. combination(STRINGS, STRINGS) {|s1, s2|
  149. if !s2.valid_encoding?
  150. next
  151. end
  152. yield s1, Regexp.new(Regexp.escape(s2))
  153. }
  154. combination(STRINGS, STRINGS, 0..2) {|s1, s2, nth|
  155. if !s2.valid_encoding?
  156. next
  157. end
  158. yield s1, Regexp.new(Regexp.escape(s2)), nth
  159. }
  160. end
  161. ASCII_INCOMPATIBLE_ENCODINGS = %w[
  162. UTF-16BE
  163. UTF-16LE
  164. UTF-32BE
  165. UTF-32LE
  166. ]
  167. def str_enc_compatible?(*strs)
  168. encs = []
  169. ascii_incompatible_encodings = {}
  170. has_ascii_compatible = false
  171. strs.each {|s|
  172. encs << s.encoding if !s.ascii_only?
  173. if /\A#{Regexp.union ASCII_INCOMPATIBLE_ENCODINGS}\z/o =~ s.encoding.name
  174. ascii_incompatible_encodings[s.encoding] = true
  175. else
  176. has_ascii_compatible = true
  177. end
  178. }
  179. if ascii_incompatible_encodings.empty?
  180. encs.uniq!
  181. encs.length <= 1
  182. else
  183. !has_ascii_compatible && ascii_incompatible_encodings.size == 1
  184. end
  185. end
  186. # tests start
  187. def test_str_new
  188. STRINGS.each {|s|
  189. t = String.new(s)
  190. assert_strenc(b(s), s.encoding, t)
  191. }
  192. end
  193. def test_str_plus
  194. combination(STRINGS, STRINGS) {|s1, s2|
  195. if s1.encoding != s2.encoding && !s1.ascii_only? && !s2.ascii_only?
  196. assert_raise(Encoding::CompatibilityError) { s1 + s2 }
  197. else
  198. t = enccall(s1, :+, s2)
  199. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  200. assert_equal(b(s1) + b(s2), b(t))
  201. assert_str_enc_propagation(t, s1, s2)
  202. end
  203. }
  204. end
  205. def test_str_times
  206. STRINGS.each {|s|
  207. [0,1,2].each {|n|
  208. t = s * n
  209. assert_predicate(t, :valid_encoding?) if s.valid_encoding?
  210. assert_strenc(b(s) * n, s.encoding, t)
  211. }
  212. }
  213. end
  214. def test_sprintf_s
  215. STRINGS.each {|s|
  216. assert_strenc(b(s), s.encoding, "%s".force_encoding(s.encoding) % s)
  217. if !s.empty? # xxx
  218. t = enccall(b("%s"), :%, s)
  219. assert_strenc(b(s), (b('')+s).encoding, t)
  220. end
  221. }
  222. end
  223. def test_str_eq_reflexive
  224. STRINGS.each {|s|
  225. assert_equal(s, s, "#{encdump s} == #{encdump s}")
  226. }
  227. end
  228. def test_str_eq_symmetric
  229. combination(STRINGS, STRINGS) {|s1, s2|
  230. if s1 == s2
  231. assert_equal(s2, s1, "#{encdump s2} == #{encdump s1}")
  232. else
  233. assert_not_equal(s2, s1, "!(#{encdump s2} == #{encdump s1})")
  234. end
  235. }
  236. end
  237. def test_str_eq_transitive
  238. combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
  239. if s1 == s2 && s2 == s3
  240. assert_equal(s1, s3, "transitive: #{encdump s1} == #{encdump s2} == #{encdump s3}")
  241. end
  242. }
  243. end
  244. def test_str_eq
  245. combination(STRINGS, STRINGS) {|s1, s2|
  246. desc_eq = "#{encdump s1} == #{encdump s2}"
  247. if b(s1) == b(s2) and
  248. (s1.ascii_only? && s2.ascii_only? or
  249. s1.encoding == s2.encoding) then
  250. assert_operator(s1, :==, s2, desc_eq)
  251. assert_not_operator(s1, :!=, s2)
  252. assert_equal(0, s1 <=> s2)
  253. assert_operator(s1, :eql?, s2, desc_eq)
  254. else
  255. assert_not_operator(s1, :==, s2, "!(#{desc_eq})")
  256. assert_operator(s1, :!=, s2)
  257. assert_not_equal(0, s1 <=> s2)
  258. assert_not_operator(s1, :eql?, s2)
  259. end
  260. }
  261. end
  262. def test_str_concat
  263. combination(STRINGS, STRINGS) {|s1, s2|
  264. s = s1.dup
  265. if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
  266. s << s2
  267. assert_predicate(s, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  268. assert_equal(b(s), b(s1) + b(s2))
  269. assert_str_enc_propagation(s, s1, s2)
  270. else
  271. assert_raise(Encoding::CompatibilityError) { s << s2 }
  272. end
  273. }
  274. end
  275. def test_str_aref
  276. STRINGS.each {|s|
  277. t = ''.force_encoding(s.encoding)
  278. 0.upto(s.length-1) {|i|
  279. u = s[i]
  280. assert_predicate(u, :valid_encoding?) if s.valid_encoding?
  281. t << u
  282. }
  283. assert_equal(t, s)
  284. }
  285. end
  286. def test_str_aref_len
  287. STRINGS.each {|s|
  288. t = ''.force_encoding(s.encoding)
  289. 0.upto(s.length-1) {|i|
  290. u = s[i,1]
  291. assert_predicate(u, :valid_encoding?) if s.valid_encoding?
  292. t << u
  293. }
  294. assert_equal(t, s)
  295. }
  296. STRINGS.each {|s|
  297. t = ''.force_encoding(s.encoding)
  298. 0.step(s.length-1, 2) {|i|
  299. u = s[i,2]
  300. assert_predicate(u, :valid_encoding?) if s.valid_encoding?
  301. t << u
  302. }
  303. assert_equal(t, s)
  304. }
  305. end
  306. def test_str_aref_substr
  307. combination(STRINGS, STRINGS) {|s1, s2|
  308. if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
  309. t = enccall(s1, :[], s2)
  310. if t != nil
  311. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  312. assert_equal(s2, t)
  313. assert_match(/#{Regexp.escape(b(s2))}/, b(s1))
  314. if s1.valid_encoding?
  315. assert_match(/#{Regexp.escape(s2)}/, s1)
  316. end
  317. end
  318. else
  319. assert_raise(Encoding::CompatibilityError) { s1[s2] }
  320. end
  321. }
  322. end
  323. def test_str_aref_range2
  324. combination(STRINGS, -2..2, -2..2) {|s, first, last|
  325. desc = "#{encdump s}[#{first}..#{last}]"
  326. t = s[first..last]
  327. if first < 0
  328. first += s.length
  329. if first < 0
  330. assert_nil(t, desc)
  331. next
  332. end
  333. end
  334. if s.length < first
  335. assert_nil(t, desc)
  336. next
  337. end
  338. assert_predicate(t, :valid_encoding?) if s.valid_encoding?
  339. if last < 0
  340. last += s.length
  341. end
  342. t2 = ''
  343. first.upto(last) {|i|
  344. c = s[i]
  345. t2 << c if c
  346. }
  347. assert_equal(t2, t, desc)
  348. }
  349. end
  350. def test_str_aref_range3
  351. combination(STRINGS, -2..2, -2..2) {|s, first, last|
  352. desc = "#{encdump s}[#{first}..#{last}]"
  353. t = s[first...last]
  354. if first < 0
  355. first += s.length
  356. if first < 0
  357. assert_nil(t, desc)
  358. next
  359. end
  360. end
  361. if s.length < first
  362. assert_nil(t, desc)
  363. next
  364. end
  365. if last < 0
  366. last += s.length
  367. end
  368. assert_predicate(t, :valid_encoding?) if s.valid_encoding?
  369. t2 = ''
  370. first.upto(last-1) {|i|
  371. c = s[i]
  372. t2 << c if c
  373. }
  374. assert_equal(t2, t, desc)
  375. }
  376. end
  377. def test_str_assign
  378. combination(STRINGS, STRINGS) {|s1, s2|
  379. (-2).upto(2) {|i|
  380. t = s1.dup
  381. if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
  382. if i < -s1.length || s1.length < i
  383. assert_raise(IndexError) { t[i] = s2 }
  384. else
  385. t[i] = s2
  386. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  387. assert_send([b(t), :index, b(s2)])
  388. if s1.valid_encoding? && s2.valid_encoding?
  389. if i == s1.length && s2.empty?
  390. assert_nil(t[i])
  391. elsif i < 0
  392. assert_equal(s2, t[i-s2.length+1,s2.length],
  393. "t = #{encdump(s1)}; t[#{i}] = #{encdump(s2)}; t[#{i-s2.length+1},#{s2.length}]")
  394. else
  395. assert_equal(s2, t[i,s2.length],
  396. "t = #{encdump(s1)}; t[#{i}] = #{encdump(s2)}; t[#{i},#{s2.length}]")
  397. end
  398. end
  399. end
  400. else
  401. assert_raise(Encoding::CompatibilityError) { t[i] = s2 }
  402. end
  403. }
  404. }
  405. end
  406. def test_str_assign_len
  407. combination(STRINGS, -2..2, 0..2, STRINGS) {|s1, i, len, s2|
  408. t = s1.dup
  409. if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
  410. if i < -s1.length || s1.length < i
  411. assert_raise(IndexError) { t[i,len] = s2 }
  412. else
  413. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  414. t[i,len] = s2
  415. assert_send([b(t), :index, b(s2)])
  416. if s1.valid_encoding? && s2.valid_encoding?
  417. if i == s1.length && s2.empty?
  418. assert_nil(t[i])
  419. elsif i < 0
  420. if -i < len
  421. len = -i
  422. end
  423. assert_equal(s2, t[i-s2.length+len,s2.length],
  424. "t = #{encdump(s1)}; t[#{i},#{len}] = #{encdump(s2)}; t[#{i-s2.length+len},#{s2.length}]")
  425. else
  426. assert_equal(s2, t[i,s2.length],
  427. "t = #{encdump(s1)}; t[#{i},#{len}] = #{encdump(s2)}; t[#{i},#{s2.length}]")
  428. end
  429. end
  430. end
  431. else
  432. assert_raise(Encoding::CompatibilityError) { t[i,len] = s2 }
  433. end
  434. }
  435. end
  436. def test_str_assign_substr
  437. combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
  438. t = s1.dup
  439. encs = [
  440. !s1.ascii_only? ? s1.encoding : nil,
  441. !s2.ascii_only? ? s2.encoding : nil,
  442. !s3.ascii_only? ? s3.encoding : nil].uniq.compact
  443. if 1 < encs.length
  444. assert_raise(Encoding::CompatibilityError, IndexError) { t[s2] = s3 }
  445. else
  446. if encs.empty?
  447. encs = [
  448. s1.encoding,
  449. s2.encoding,
  450. s3.encoding].uniq.reject {|e| e == Encoding.find("ASCII-8BIT") }
  451. if encs.empty?
  452. encs = [Encoding.find("ASCII-8BIT")]
  453. end
  454. end
  455. if !t[s2]
  456. else
  457. enccall(t, :[]=, s2, s3)
  458. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding? && s3.valid_encoding?
  459. end
  460. end
  461. }
  462. end
  463. def test_str_assign_range2
  464. combination(STRINGS, -2..2, -2..2, STRINGS) {|s1, first, last, s2|
  465. t = s1.dup
  466. if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
  467. if first < -s1.length || s1.length < first
  468. assert_raise(RangeError) { t[first..last] = s2 }
  469. else
  470. enccall(t, :[]=, first..last, s2)
  471. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  472. assert_send([b(t), :index, b(s2)])
  473. if s1.valid_encoding? && s2.valid_encoding?
  474. if first < 0
  475. assert_equal(s2, t[s1.length+first, s2.length])
  476. else
  477. assert_equal(s2, t[first, s2.length])
  478. end
  479. end
  480. end
  481. else
  482. assert_raise(Encoding::CompatibilityError, RangeError,
  483. "t=#{encdump(s1)};t[#{first}..#{last}]=#{encdump(s2)}") {
  484. t[first..last] = s2
  485. }
  486. end
  487. }
  488. end
  489. def test_str_assign_range3
  490. combination(STRINGS, -2..2, -2..2, STRINGS) {|s1, first, last, s2|
  491. t = s1.dup
  492. if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
  493. if first < -s1.length || s1.length < first
  494. assert_raise(RangeError) { t[first...last] = s2 }
  495. else
  496. enccall(t, :[]=, first...last, s2)
  497. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  498. assert_send([b(t), :index, b(s2)])
  499. if s1.valid_encoding? && s2.valid_encoding?
  500. if first < 0
  501. assert_equal(s2, t[s1.length+first, s2.length])
  502. else
  503. assert_equal(s2, t[first, s2.length])
  504. end
  505. end
  506. end
  507. else
  508. assert_raise(Encoding::CompatibilityError, RangeError,
  509. "t=#{encdump(s1)};t[#{first}...#{last}]=#{encdump(s2)}") {
  510. t[first...last] = s2
  511. }
  512. end
  513. }
  514. end
  515. def test_str_cmp
  516. combination(STRINGS, STRINGS) {|s1, s2|
  517. desc = "#{encdump s1} <=> #{encdump s2}"
  518. r = s1 <=> s2
  519. if s1 == s2
  520. assert_equal(0, r, desc)
  521. else
  522. assert_not_equal(0, r, desc)
  523. end
  524. }
  525. end
  526. def test_str_capitalize
  527. STRINGS.each {|s|
  528. begin
  529. t1 = s.capitalize
  530. rescue ArgumentError
  531. assert_not_predicate(s, :valid_encoding?)
  532. next
  533. end
  534. assert_predicate(t1, :valid_encoding?) if s.valid_encoding?
  535. assert_operator(t1, :casecmp, s)
  536. t2 = s.dup
  537. t2.capitalize!
  538. assert_equal(t1, t2)
  539. r = s.downcase
  540. r = enccall(r, :sub, /\A[a-z]/) {|ch| b(ch).upcase }
  541. assert_equal(r, t1)
  542. }
  543. end
  544. def test_str_casecmp
  545. combination(STRINGS, STRINGS) {|s1, s2|
  546. #puts "#{encdump(s1)}.casecmp(#{encdump(s2)})"
  547. next unless s1.valid_encoding? && s2.valid_encoding? && Encoding.compatible?(s1, s2)
  548. r = s1.casecmp(s2)
  549. assert_equal(s1.upcase <=> s2.upcase, r)
  550. }
  551. end
  552. def test_str_center
  553. combination(STRINGS, [0,1,2,3,10]) {|s1, width|
  554. t = s1.center(width)
  555. assert_send([b(t), :index, b(s1)])
  556. }
  557. combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
  558. if s2.empty?
  559. assert_raise(ArgumentError) { s1.center(width, s2) }
  560. next
  561. end
  562. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  563. assert_raise(Encoding::CompatibilityError) { s1.center(width, s2) }
  564. next
  565. end
  566. t = enccall(s1, :center, width, s2)
  567. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  568. assert_send([b(t), :index, b(s1)])
  569. assert_str_enc_propagation(t, s1, s2) if (t != s1)
  570. }
  571. end
  572. def test_str_ljust
  573. combination(STRINGS, [0,1,2,3,10]) {|s1, width|
  574. t = s1.ljust(width)
  575. assert_send([b(t), :index, b(s1)])
  576. }
  577. combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
  578. if s2.empty?
  579. assert_raise(ArgumentError) { s1.ljust(width, s2) }
  580. next
  581. end
  582. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  583. assert_raise(Encoding::CompatibilityError) { s1.ljust(width, s2) }
  584. next
  585. end
  586. t = enccall(s1, :ljust, width, s2)
  587. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  588. assert_send([b(t), :index, b(s1)])
  589. assert_str_enc_propagation(t, s1, s2) if (t != s1)
  590. }
  591. end
  592. def test_str_rjust
  593. combination(STRINGS, [0,1,2,3,10]) {|s1, width|
  594. t = s1.rjust(width)
  595. assert_send([b(t), :index, b(s1)])
  596. }
  597. combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
  598. if s2.empty?
  599. assert_raise(ArgumentError) { s1.rjust(width, s2) }
  600. next
  601. end
  602. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  603. assert_raise(Encoding::CompatibilityError) { s1.rjust(width, s2) }
  604. next
  605. end
  606. t = enccall(s1, :rjust, width, s2)
  607. assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
  608. assert_send([b(t), :index, b(s1)])
  609. assert_str_enc_propagation(t, s1, s2) if (t != s1)
  610. }
  611. end
  612. def test_str_chomp
  613. combination(STRINGS, STRINGS) {|s1, s2|
  614. if !s1.ascii_only? && !s2.ascii_only? && !Encoding.compatible?(s1,s2)
  615. if s1.bytesize > s2.bytesize
  616. assert_raise(Encoding::CompatibilityError, "#{encdump(s1)}.chomp(#{encdump(s2)})") do
  617. s1.chomp(s2)
  618. end
  619. end
  620. next
  621. end
  622. t = enccall(s1, :chomp, s2)
  623. assert_predicate(t, :valid_encoding?, "#{encdump(s1)}.chomp(#{encdump(s2)})") if s1.valid_encoding? && s2.valid_encoding?
  624. assert_equal(s1.encoding, t.encoding)
  625. t2 = s1.dup
  626. t2.chomp!(s2)
  627. assert_equal(t, t2)
  628. }
  629. end
  630. def test_str_smart_chomp
  631. bug10893 = '[ruby-core:68258] [Bug #10893]'
  632. encodings = Encoding.list.select {|enc| !enc.dummy?}
  633. combination(encodings, encodings) do |e1, e2|
  634. expected = "abc".encode(e1)
  635. combination(["abc\n", "abc\r\n"], ["", "\n"]) do |str, rs|
  636. assert_equal(expected, str.encode(e1).chomp(rs.encode(e2)), bug10893)
  637. end
  638. end
  639. end
  640. def test_str_chop
  641. STRINGS.each {|s|
  642. s = s.dup
  643. desc = "#{encdump s}.chop"
  644. t = nil
  645. assert_nothing_raised(desc) { t = s.chop }
  646. assert_predicate(t, :valid_encoding?) if s.valid_encoding?
  647. assert_send([b(s), :index, b(t)])
  648. t2 = s.dup
  649. t2.chop!
  650. assert_equal(t, t2)
  651. }
  652. end
  653. def test_str_clear
  654. STRINGS.each {|s|
  655. t = s.dup
  656. t.clear
  657. assert_predicate(t, :valid_encoding?)
  658. assert_empty(t)
  659. }
  660. end
  661. def test_str_clone
  662. STRINGS.each {|s|
  663. t = s.clone
  664. assert_equal(s, t)
  665. assert_equal(s.encoding, t.encoding)
  666. assert_equal(b(s), b(t))
  667. }
  668. end
  669. def test_str_dup
  670. STRINGS.each {|s|
  671. t = s.dup
  672. assert_equal(s, t)
  673. assert_equal(s.encoding, t.encoding)
  674. assert_equal(b(s), b(t))
  675. }
  676. end
  677. def test_str_count
  678. combination(STRINGS, STRINGS) {|s1, s2|
  679. desc = proc {encdumpcall(s1, :count, s2)}
  680. if !s1.valid_encoding? || !s2.valid_encoding?
  681. assert_raise(ArgumentError, Encoding::CompatibilityError, desc) { s1.count(s2) }
  682. next
  683. end
  684. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  685. assert_raise(Encoding::CompatibilityError, desc) { s1.count(s2) }
  686. next
  687. end
  688. n = enccall(s1, :count, s2)
  689. n0 = b(s1).count(b(s2))
  690. assert_operator(n, :<=, n0)
  691. }
  692. end
  693. def crypt_supports_des_crypt?
  694. /openbsd/ !~ RUBY_PLATFORM
  695. end
  696. # glibc 2.16 or later denies salt contained other than [0-9A-Za-z./] #7312
  697. # we use this check to test strict and non-strict behavior separately #11045
  698. strict_crypt = if defined? Etc::CS_GNU_LIBC_VERSION
  699. begin
  700. confstr = Etc.confstr(Etc::CS_GNU_LIBC_VERSION)
  701. rescue Errno::EINVAL
  702. false
  703. else
  704. glibcver = confstr.scan(/\d+/).map(&:to_i)
  705. (glibcver <=> [2, 16]) >= 0
  706. end
  707. end
  708. def test_str_crypt
  709. combination(STRINGS, STRINGS) {|str, salt|
  710. # skip input other than [0-9A-Za-z./] to confirm strict behavior
  711. next unless salt.ascii_only? && /\A[0-9a-zA-Z.\/]+\z/ =~ salt
  712. confirm_crypt_result(str, salt)
  713. }
  714. end
  715. if !strict_crypt && /openbsd/ !~ RUBY_PLATFORM
  716. def test_str_crypt_nonstrict
  717. combination(STRINGS, STRINGS) {|str, salt|
  718. # only test input other than [0-9A-Za-z./] to confirm non-strict behavior
  719. next if salt.ascii_only? && /\A[0-9a-zA-Z.\/]+\z/ =~ salt
  720. confirm_crypt_result(str, salt)
  721. }
  722. end
  723. end
  724. private def confirm_crypt_result(str, salt)
  725. if crypt_supports_des_crypt?
  726. if b(salt).length < 2
  727. assert_raise(ArgumentError) { str.crypt(salt) }
  728. return
  729. end
  730. else
  731. return if b(salt).length < 2
  732. salt = "$2a$04$0WVaz0pV3jzfZ5G5tpmH#{salt}"
  733. end
  734. t = str.crypt(salt)
  735. assert_equal(b(str).crypt(b(salt)), t, "#{encdump(str)}.crypt(#{encdump(salt)})")
  736. assert_encoding('ASCII-8BIT', t.encoding)
  737. end
  738. def test_str_delete
  739. combination(STRINGS, STRINGS) {|s1, s2|
  740. if s1.empty?
  741. assert_equal(s1, s1.delete(s2))
  742. next
  743. end
  744. if !s1.valid_encoding? || !s2.valid_encoding?
  745. assert_raise(ArgumentError, Encoding::CompatibilityError) { s1.delete(s2) }
  746. next
  747. end
  748. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  749. assert_raise(Encoding::CompatibilityError) { s1.delete(s2) }
  750. next
  751. end
  752. t = enccall(s1, :delete, s2)
  753. assert_predicate(t, :valid_encoding?)
  754. assert_equal(t.encoding, s1.encoding)
  755. assert_operator(t.length, :<=, s1.length)
  756. t2 = s1.dup
  757. t2.delete!(s2)
  758. assert_equal(t, t2)
  759. }
  760. end
  761. def test_str_downcase
  762. STRINGS.each {|s|
  763. if !s.valid_encoding?
  764. assert_raise(ArgumentError, "Offending string: #{s.inspect}, encoding: #{s.encoding}") { s.downcase }
  765. next
  766. end
  767. t = s.downcase
  768. assert_predicate(t, :valid_encoding?)
  769. assert_equal(t.encoding, s.encoding)
  770. assert_operator(t, :casecmp, s)
  771. t2 = s.dup
  772. t2.downcase!
  773. assert_equal(t, t2)
  774. }
  775. end
  776. def test_str_dump
  777. STRINGS.each {|s|
  778. t = s.dump
  779. assert_predicate(t, :valid_encoding?)
  780. assert_predicate(t, :ascii_only?)
  781. u = eval(t)
  782. assert_equal(b(s), b(u))
  783. }
  784. end
  785. def test_str_each_line
  786. combination(STRINGS, STRINGS) {|s1, s2|
  787. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  788. assert_raise(Encoding::CompatibilityError) { s1.each_line(s2) {} }
  789. next
  790. end
  791. lines = []
  792. enccall(s1, :each_line, s2) {|line|
  793. assert_equal(s1.encoding, line.encoding)
  794. lines << line
  795. }
  796. next if lines.size == 0
  797. s2 = lines.join('')
  798. assert_equal(s1.encoding, s2.encoding)
  799. assert_equal(s1, s2)
  800. }
  801. end
  802. def test_str_each_byte
  803. STRINGS.each {|s|
  804. bytes = []
  805. s.each_byte {|b|
  806. bytes << b
  807. }
  808. b(s).split(//).each_with_index {|ch, i|
  809. assert_equal(ch.ord, bytes[i])
  810. }
  811. }
  812. end
  813. def test_str_empty?
  814. STRINGS.each {|s|
  815. if s.length == 0
  816. assert_empty(s)
  817. else
  818. assert_not_empty(s)
  819. end
  820. }
  821. end
  822. def test_str_hex
  823. STRINGS.each {|s|
  824. t = s.hex
  825. t2 = b(s)[/\A[0-9a-fA-Fx]*/].hex
  826. assert_equal(t2, t)
  827. }
  828. end
  829. def test_str_include?
  830. combination(STRINGS, STRINGS) {|s1, s2|
  831. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  832. assert_raise(Encoding::CompatibilityError) { s1.include?(s2) }
  833. assert_raise(Encoding::CompatibilityError) { s1.index(s2) }
  834. assert_raise(Encoding::CompatibilityError) { s1.rindex(s2) }
  835. next
  836. end
  837. t = enccall(s1, :include?, s2)
  838. if t
  839. assert_include(b(s1), b(s2))
  840. assert_send([s1, :index, s2])
  841. assert_send([s1, :rindex, s2])
  842. else
  843. assert_not_send([s1, :index, s2])
  844. assert_not_send([s1, :rindex, s2], "!#{encdump(s1)}.rindex(#{encdump(s2)})")
  845. end
  846. if s2.empty?
  847. assert_equal(true, t)
  848. next
  849. end
  850. if !s1.valid_encoding? || !s2.valid_encoding?
  851. assert_equal(false, t, "#{encdump s1}.include?(#{encdump s2})")
  852. next
  853. end
  854. if t && s1.valid_encoding? && s2.valid_encoding?
  855. assert_match(/#{Regexp.escape(s2)}/, s1)
  856. else
  857. assert_no_match(/#{Regexp.escape(s2)}/, s1)
  858. end
  859. }
  860. end
  861. def test_str_index
  862. combination(STRINGS, STRINGS, -2..2) {|s1, s2, pos|
  863. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  864. assert_raise(Encoding::CompatibilityError) { s1.index(s2) }
  865. next
  866. end
  867. t = enccall(s1, :index, s2, pos)
  868. if s2.empty?
  869. if pos < 0 && pos+s1.length < 0
  870. assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
  871. elsif pos < 0
  872. assert_equal(s1.length+pos, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
  873. elsif s1.length < pos
  874. assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
  875. else
  876. assert_equal(pos, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
  877. end
  878. next
  879. end
  880. if !s1.valid_encoding? || !s2.valid_encoding?
  881. assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
  882. next
  883. end
  884. if t
  885. re = /#{Regexp.escape(s2)}/
  886. assert(re.match(s1, pos))
  887. assert_equal($`.length, t, "#{encdump s1}.index(#{encdump s2}, #{pos})")
  888. else
  889. assert_no_match(/#{Regexp.escape(s2)}/, s1[pos..-1])
  890. end
  891. }
  892. end
  893. def test_str_rindex
  894. combination(STRINGS, STRINGS, -2..2) {|s1, s2, pos|
  895. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  896. assert_raise(Encoding::CompatibilityError) { s1.rindex(s2) }
  897. next
  898. end
  899. t = enccall(s1, :rindex, s2, pos)
  900. if s2.empty?
  901. if pos < 0 && pos+s1.length < 0
  902. assert_equal(nil, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
  903. elsif pos < 0
  904. assert_equal(s1.length+pos, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
  905. elsif s1.length < pos
  906. assert_equal(s1.length, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
  907. else
  908. assert_equal(pos, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
  909. end
  910. next
  911. end
  912. if !s1.valid_encoding? || !s2.valid_encoding?
  913. assert_equal(nil, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
  914. next
  915. end
  916. if t
  917. #puts "#{encdump s1}.rindex(#{encdump s2}, #{pos}) => #{t}"
  918. assert_send([b(s1), :index, b(s2)])
  919. pos2 = pos
  920. pos2 += s1.length if pos < 0
  921. re = /\A(.{0,#{pos2}})#{Regexp.escape(s2)}/m
  922. m = enccall(re, :match, s1)
  923. assert(m, "#{re.inspect}.match(#{encdump(s1)})")
  924. assert_equal(m[1].length, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
  925. else
  926. re = /#{Regexp.escape(s2)}/
  927. n = re =~ s1
  928. if n
  929. if pos < 0
  930. assert_operator(n, :>, s1.length+pos)
  931. else
  932. assert_operator(n, :>, pos)
  933. end
  934. end
  935. end
  936. }
  937. end
  938. def test_str_insert
  939. combination(STRINGS, 0..2, STRINGS) {|s1, nth, s2|
  940. t1 = s1.dup
  941. t2 = s1.dup
  942. begin
  943. t1[nth, 0] = s2
  944. rescue Encoding::CompatibilityError, IndexError => e1
  945. end
  946. begin
  947. t2.insert(nth, s2)
  948. rescue Encoding::CompatibilityError, IndexError => e2
  949. end
  950. assert_equal(t1, t2, "t=#{encdump s1}; t.insert(#{nth},#{encdump s2}); t")
  951. assert_equal(e1.class, e2.class, "begin #{encdump s1}.insert(#{nth},#{encdump s2}); rescue ArgumentError, IndexError => e; e end")
  952. }
  953. combination(STRINGS, -2..-1, STRINGS) {|s1, nth, s2|
  954. next if s1.length + nth < 0
  955. next unless s1.valid_encoding?
  956. next unless s2.valid_encoding?
  957. t1 = s1.dup
  958. begin
  959. t1.insert(nth, s2)
  960. slen = s2.length
  961. assert_equal(t1[nth-slen+1,slen], s2, "t=#{encdump s1}; t.insert(#{nth},#{encdump s2}); t")
  962. rescue Encoding::CompatibilityError, IndexError
  963. end
  964. }
  965. end
  966. def test_str_intern
  967. STRINGS.each {|s|
  968. if /\0/ =~ b(s)
  969. assert_raise(ArgumentError) { s.intern }
  970. elsif s.valid_encoding?
  971. sym = s.intern
  972. assert_equal(s, sym.to_s, "#{encdump s}.intern.to_s")
  973. assert_equal(sym, s.to_sym)
  974. else
  975. assert_raise(EncodingError) { s.intern }
  976. end
  977. }
  978. end
  979. def test_str_length
  980. STRINGS.each {|s|
  981. assert_operator(s.length, :<=, s.bytesize)
  982. }
  983. end
  984. def test_str_oct
  985. STRINGS.each {|s|
  986. t = s.oct
  987. t2 = b(s)[/\A[0-9a-fA-FxX]*/].oct
  988. assert_equal(t2, t)
  989. }
  990. end
  991. def test_str_replace
  992. combination(STRINGS, STRINGS) {|s1, s2|
  993. t = s1.dup
  994. t.replace s2
  995. assert_equal(s2, t)
  996. assert_equal(s2.encoding, t.encoding)
  997. }
  998. end
  999. def test_str_reverse
  1000. STRINGS.each {|s|
  1001. t = s.reverse
  1002. assert_equal(s.bytesize, t.bytesize)
  1003. if !s.valid_encoding?
  1004. assert_operator(t.length, :<=, s.length)
  1005. next
  1006. end
  1007. assert_equal(s, t.reverse)
  1008. }
  1009. end
  1010. def test_str_scan
  1011. combination(STRINGS, STRINGS) {|s1, s2|
  1012. desc = proc {"#{s1.dump}.scan(#{s2.dump})"}
  1013. if !s2.valid_encoding?
  1014. assert_raise(RegexpError, desc) { s1.scan(s2) }
  1015. next
  1016. end
  1017. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  1018. if s1.valid_encoding?
  1019. assert_raise(Encoding::CompatibilityError, desc) { s1.scan(s2) }
  1020. else
  1021. assert_raise_with_message(ArgumentError, /invalid byte sequence/, desc) { s1.scan(s2) }
  1022. end
  1023. next
  1024. end
  1025. if !s1.valid_encoding?
  1026. assert_raise(ArgumentError, desc) { s1.scan(s2) }
  1027. next
  1028. end
  1029. r = enccall(s1, :scan, s2)
  1030. r.each {|t|
  1031. assert_equal(s2, t, desc)
  1032. }
  1033. }
  1034. end
  1035. def test_str_slice
  1036. each_slice_call {|obj, *args|
  1037. assert_same_result(lambda { obj[*args] }, lambda { obj.slice(*args) })
  1038. }
  1039. end
  1040. def test_str_slice!
  1041. each_slice_call {|s, *args|
  1042. desc_slice = "#{encdump s}.slice#{encdumpargs args}"
  1043. desc_slice_bang = "#{encdump s}.slice!#{encdumpargs args}"
  1044. t = s.dup
  1045. begin
  1046. r = t.slice!(*args)
  1047. rescue
  1048. e = $!
  1049. end
  1050. if e
  1051. assert_raise(e.class, desc_slice) { s.slice(*args) }
  1052. next
  1053. end
  1054. if !r
  1055. assert_nil(s.slice(*args), desc_slice)
  1056. next
  1057. end
  1058. assert_equal(s.slice(*args), r, desc_slice_bang)
  1059. assert_equal(s.bytesize, r.bytesize + t.bytesize)
  1060. if args.length == 1 && String === args[0]
  1061. assert_equal(args[0].encoding, r.encoding,
  1062. "#{encdump s}.slice!#{encdumpargs args}.encoding")
  1063. else
  1064. assert_equal(s.encoding, r.encoding,
  1065. "#{encdump s}.slice!#{encdumpargs args}.encoding")
  1066. end
  1067. if [s, *args].all? {|o| !(String === o) || o.valid_encoding? }
  1068. assert_predicate(r, :valid_encoding?)
  1069. assert_predicate(t, :valid_encoding?)
  1070. assert_equal(s.length, r.length + t.length)
  1071. end
  1072. }
  1073. end
  1074. def test_str_split
  1075. combination(STRINGS, STRINGS) {|s1, s2|
  1076. if !s2.valid_encoding?
  1077. assert_raise(ArgumentError, RegexpError) { s1.split(s2) }
  1078. next
  1079. end
  1080. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  1081. assert_raise(ArgumentError, Encoding::CompatibilityError) { s1.split(s2) }
  1082. next
  1083. end
  1084. if !s1.valid_encoding?
  1085. assert_raise(ArgumentError) { s1.split(s2) }
  1086. next
  1087. end
  1088. t = enccall(s1, :split, s2)
  1089. t.each {|r|
  1090. assert_include(b(s1), b(r))
  1091. assert_equal(s1.encoding, r.encoding)
  1092. }
  1093. assert_include(b(s1), t.map {|u| b(u) }.join(b(s2)))
  1094. if s1.valid_encoding? && s2.valid_encoding?
  1095. t.each {|r|
  1096. assert_predicate(r, :valid_encoding?)
  1097. }
  1098. end
  1099. }
  1100. end
  1101. def test_str_squeeze
  1102. combination(STRINGS, STRINGS) {|s1, s2|
  1103. if !s1.valid_encoding? || !s2.valid_encoding?
  1104. assert_raise(ArgumentError, Encoding::CompatibilityError, "#{encdump s1}.squeeze(#{encdump s2})") { s1.squeeze(s2) }
  1105. next
  1106. end
  1107. if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
  1108. assert_raise(Encoding::CompatibilityError) { s1.squeeze(s2) }
  1109. next
  1110. end
  1111. t = enccall(s1, :squeeze, s2)
  1112. assert_operator(t.length, :<=, s1.length)
  1113. t2 = s1.dup
  1114. t2.squeeze!(s2)
  1115. assert_equal(t, t2)
  1116. }
  1117. end
  1118. def test_str_strip
  1119. STRINGS.each {|s|
  1120. if !s.valid_encoding?
  1121. assert_raise(ArgumentError, "#{encdump s}.strip") { s.strip }
  1122. next
  1123. end
  1124. t = s.strip
  1125. l = s.lstrip
  1126. r = s.rstrip
  1127. assert_operator(l.length, :<=, s.length)
  1128. assert_operator(r.length, :<=, s.length)
  1129. assert_operator(t.length, :<=, l.length)
  1130. assert_operator(t.length, :<=, r.length)
  1131. t2 = s.dup
  1132. t2.strip!
  1133. assert_equal(t, t2)
  1134. l2 = s.dup
  1135. l2.lstrip!
  1136. assert_equal(l, l2)
  1137. r2 = s.dup
  1138. r2.rstrip!
  1139. assert_equal(r, r2)
  1140. }
  1141. end
  1142. def test_str_sum
  1143. STRINGS.each {|s|
  1144. assert_equal(b(s).sum, s.sum)
  1145. }
  1146. end
  1147. def test_str_swapcase
  1148. STRINGS.each {|s|
  1149. if !s.valid_encoding?
  1150. assert_raise(ArgumentError, "#{encdump s}.swapcase") { s.swapcase }
  1151. next
  1152. end
  1153. t1 = s.swapcase
  1154. assert_predicate(t1, :valid_encoding?) if s.valid_encoding?
  1155. assert_operator(t1, :casecmp, s)
  1156. t2 = s.dup
  1157. t2.swapcase!
  1158. assert_equal(t1, t2)
  1159. t3 = t1.swapcase
  1160. assert_equal(s, t3);
  1161. }
  1162. end
  1163. def test_str_to_f
  1164. STRINGS.each {|s|
  1165. assert_nothing_raised { s.to_f }
  1166. }
  1167. end
  1168. def test_str_to_i
  1169. STRINGS.each {|s|
  1170. assert_nothing_raised { s.to_i }
  1171. 2.upto(36) {|radix|
  1172. assert_nothing_raised { s.to_i(radix) }
  1173. }
  1174. }
  1175. end
  1176. def test_str_to_s
  1177. STRINGS.each {|s|
  1178. assert_same(s, s.to_s)
  1179. assert_same(s, s.to_str)
  1180. }
  1181. end
  1182. def test_tr
  1183. combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
  1184. desc = "#{encdump s1}.tr(#{encdump s2}, #{encdump s3})"
  1185. if s1.empty?
  1186. assert_equal(s1, s1.tr(s2, s3), desc)
  1187. next
  1188. end
  1189. if !str_enc_compatible?(s1, s2, s3)
  1190. assert_raise(Encoding::CompatibilityError, desc) { s1.tr(s2, s3) }
  1191. next
  1192. end
  1193. if !s1.valid_encoding?
  1194. assert_raise(ArgumentError, desc) { s1.tr(s2, s3) }
  1195. next
  1196. end
  1197. if s2.empty?
  1198. t = enccall(s1, :tr, s2, s3)
  1199. assert_equal(s1, t, desc)
  1200. next
  1201. end
  1202. if !s2.valid_encoding? || !s3.valid_encoding?
  1203. assert_raise(ArgumentError, desc) { s1.tr(s2, s3) }
  1204. next
  1205. end
  1206. t = enccall(s1, :tr, s2, s3)
  1207. assert_operator(s1.length, :>=, t.length, desc)
  1208. }
  1209. end
  1210. def test_tr_sjis
  1211. expected = "\x83}\x83~\x83\x80\x83\x81\x83\x82".force_encoding(Encoding::SJIS)
  1212. source = "\xCF\xD0\xD1\xD2\xD3".force_encoding(Encoding::SJIS)
  1213. from = "\xCF-\xD3".force_encoding(Encoding::SJIS)
  1214. to = "\x83}-\x83\x82".force_encoding(Encoding::SJIS)
  1215. assert_equal(expected, source.tr(from, to))
  1216. expected = "\x84}\x84~\x84\x80\x84\x81\x84\x82".force_encoding(Encoding::SJIS)
  1217. source = "\x84M\x84N\x84O\x84P\x84Q".force_encoding(Encoding::SJIS)
  1218. from = "\x84@-\x84`".force_encoding(Encoding::SJIS)
  1219. to = "\x84p-\x84\x91".force_encoding(Encoding::SJIS)
  1220. assert_equal(expected, source.tr(from, to))
  1221. end
  1222. def test_tr_s
  1223. combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
  1224. desc = "#{encdump s1}.tr_s(#{encdump s2}, #{encdump s3})"
  1225. if s1.empty?
  1226. assert_equal(s1, s1.tr_s(s2, s3), desc)
  1227. next
  1228. end
  1229. if !s1.valid_encoding?
  1230. assert_raise(ArgumentError, Encoding::CompatibilityError, desc) { s1.tr_s(s2, s3) }
  1231. next
  1232. end
  1233. if !str_enc_compatible?(s1, s2, s3)
  1234. assert_raise(Encoding::CompatibilityError, desc) { s1.tr(s2, s3) }
  1235. next
  1236. end
  1237. if s2.empty?
  1238. t = enccall(s1, :tr_s, s2, s3)
  1239. assert_equal(s1, t, desc)
  1240. next
  1241. end
  1242. if !s2.valid_encoding? || !s3.valid_encoding?
  1243. assert_raise(ArgumentError, desc) { s1.tr_s(s2, s3) }
  1244. next
  1245. end
  1246. t = enccall(s1, :tr_s, s2, s3)
  1247. assert_operator(s1.length, :>=, t.length, desc)
  1248. }
  1249. end
  1250. def test_str_upcase
  1251. STRINGS.each {|s|
  1252. desc = "#{encdump s}.upcase"
  1253. if !s.valid_encoding?
  1254. assert_raise(ArgumentError, desc) { s.upcase }
  1255. next
  1256. end
  1257. t1 = s.upcase
  1258. assert_predicate(t1, :valid_encoding?)
  1259. assert_operator(t1, :casecmp, s)
  1260. t2 = s.dup
  1261. t2.upcase!
  1262. assert_equal(t1, t2)
  1263. }
  1264. end
  1265. def test_str_succ
  1266. STRINGS.each {|s0|
  1267. next if s0.empty?
  1268. s = s0.dup
  1269. n = 300
  1270. h = {}
  1271. n.times {|i|
  1272. if h[s]
  1273. assert(false, "#{encdump s} cycle with succ #{i-h[s]} times")
  1274. end
  1275. h[s] = i
  1276. assert_operator(s.length, :<=, s0.length + Math.log2(i+1) + 1, "#{encdump s0} succ #{i} times => #{encdump s}")
  1277. #puts encdump(s)
  1278. t = s.succ
  1279. if s.valid_encoding?
  1280. assert_predicate(t, :valid_encoding?, "#{encdump s}.succ.valid_encoding?")
  1281. end
  1282. s = t
  1283. }
  1284. }
  1285. Encoding.list.each do |enc|
  1286. next if enc.dummy?
  1287. {"A"=>"B", "A1"=>"A2", "A9"=>"B0", "9"=>"10", "Z"=>"AA"}.each do |orig, expected|
  1288. s = orig.encode(enc)
  1289. assert_strenc(expected.encode(enc), enc, s.succ, proc {"#{orig.dump}.encode(#{enc}).succ"})
  1290. end
  1291. end
  1292. end
  1293. def test_str_succ2
  1294. assert_equal(a("\x01\x00"), a("\x7f").succ)
  1295. assert_equal(b("\x01\x00"), b("\xff").succ)
  1296. end
  1297. def test_str_hash
  1298. combination(STRINGS, STRINGS) {|s1, s2|
  1299. if s1.eql?(s2)
  1300. assert_equal(s1.hash, s2.hash, "#{encdump s1}.hash == #{encdump s2}.dump")
  1301. end
  1302. }
  1303. end
  1304. def test_marshal
  1305. STRINGS.each {|s|
  1306. m = Marshal.dump(s)
  1307. t = Marshal.load(m)
  1308. assert_equal(s, t)
  1309. }
  1310. end
  1311. def test_str_sub
  1312. combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
  1313. if !s2.valid_encoding?
  1314. assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }
  1315. next
  1316. end
  1317. r2 = Regexp.new(Regexp.escape(s2))
  1318. [
  1319. [
  1320. "#{encdump s1}.sub(Regexp.new(#{encdump s2}), #{encdump s3})",
  1321. lambda { s1.sub(r2, s3) },
  1322. false
  1323. ],
  1324. [
  1325. "#{encdump s1}.sub(Regexp.new(#{encdump s2}), #{encdump s3})",
  1326. lambda { s1.sub(r2) { s3 } },
  1327. false
  1328. ],
  1329. [
  1330. "#{encdump s1}.gsub(Regexp.new(#{encdump s2}), #{encdump s3})",
  1331. lambda { s1.gsub(r2, s3) },
  1332. true
  1333. ],
  1334. [
  1335. "#{encdump s1}.gsub(Regexp.new(#{encdump s2}), #{encdump s3})",
  1336. lambda { s1.gsub(r2) { s3 } },
  1337. true
  1338. ]
  1339. ].each {|desc, doit, g|
  1340. if !s1.valid_encoding?
  1341. assert_raise(ArgumentError, desc) { doit.call }
  1342. next
  1343. end
  1344. if !str_enc_compatible?(s1, s2)
  1345. assert_raise(Encoding::CompatibilityError, desc) { doit.call }
  1346. next
  1347. end
  1348. if !enccall(s1, :include?, s2)
  1349. assert_equal(s1, doit.call)
  1350. next
  1351. end
  1352. if !str_enc_compatible?(g ? s1.gsub(r2, '') : s1.sub(r2, ''), s3)
  1353. assert_raise(Encoding::CompatibilityError, desc) { doit.call }
  1354. next
  1355. end
  1356. t = nil
  1357. assert_nothing_raised(desc) {
  1358. t = doit.call
  1359. }
  1360. if s2 == s3
  1361. assert_equal(s1, t, desc)
  1362. else
  1363. assert_not_equal(s1, t, desc)
  1364. end
  1365. }
  1366. }
  1367. end
  1368. def test_str_sub!
  1369. combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
  1370. if !s2.valid_encoding?
  1371. assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }
  1372. next
  1373. end
  1374. r2 = Regexp.new(Regexp.escape(s2))
  1375. [
  1376. [
  1377. "t=#{encdump s1}.dup;t.sub!(Regexp.new(#{encdump s2}), #{encdump s3})",
  1378. lambda { t=s1.dup; [t, t.sub!(r2, s3)] },
  1379. false
  1380. ],
  1381. [
  1382. "t=#{encdump s1}.dup;t.sub!(Regexp.new(#{encdump s2}), #{encdump s3})",
  1383. lambda { t=s1.dup; [t, t.sub!(r2) { s3 }] },
  1384. false
  1385. ],
  1386. [
  1387. "t=#{encdump s1}.dup;t.gsub!(Regexp.new(#{encdump s2}), #{encdump s3})",
  1388. lambda { t=s1.dup; [t, t.gsub!(r2, s3)] },
  1389. true
  1390. ],
  1391. [
  1392. "t=#{encdump s1}.dup;t.gsub!(Regexp.new(#{encdump s2}), #{encdump s3})",
  1393. lambda { t=s1.dup; [t, t.gsub!(r2) { s3 }] },
  1394. true
  1395. ]
  1396. ].each {|desc, doit, g|
  1397. if !s1.valid_encoding?
  1398. assert_raise(ArgumentError, desc) { doit.call }
  1399. next
  1400. end
  1401. if !str_enc_compatible?(s1, s2)
  1402. assert_raise(Encoding::CompatibilityError, desc) { doit.call }
  1403. next
  1404. end
  1405. if !enccall(s1, :include?, s2)
  1406. assert_equal([s1, nil], doit.call)
  1407. next
  1408. end
  1409. if !str_enc_compatible?(g ? s1.gsub(r2, '') : s1.sub(r2, ''), s3)
  1410. assert_raise(Encoding::CompatibilityError, desc) { doit.call }
  1411. next
  1412. end
  1413. t = ret = nil
  1414. assert_nothing_raised(desc) {
  1415. t, ret = doit.call
  1416. }
  1417. assert(ret)
  1418. if s2 == s3
  1419. assert_equal(s1, t, desc)
  1420. else
  1421. assert_not_equal(s1, t, desc)
  1422. end
  1423. }
  1424. }
  1425. end
  1426. def test_str_bytes
  1427. STRINGS.each {|s1|
  1428. ary = []
  1429. s1.bytes.each {|b|
  1430. ary << b
  1431. }
  1432. assert_equal(s1.unpack("C*"), ary)
  1433. }
  1434. end
  1435. def test_str_bytesize
  1436. STRINGS.each {|s1|
  1437. assert_equal(s1.unpack("C*").length, s1.bytesize)
  1438. }
  1439. end
  1440. def test_str_chars
  1441. STRINGS.each {|s1|
  1442. ary = []
  1443. s1.chars.each {|c|
  1444. ary << c
  1445. }
  1446. expected = []
  1447. s1.length.times {|i|
  1448. expected << s1[i]
  1449. }
  1450. assert_equal(expected, ary)
  1451. }
  1452. end
  1453. def test_str_chr
  1454. STRINGS.each {|s1|
  1455. if s1.empty?
  1456. assert_equal("", s1.chr)
  1457. next
  1458. end
  1459. assert_equal(s1[0], s1.chr)
  1460. }
  1461. end
  1462. def test_str_end_with?
  1463. combination(STRINGS, STRINGS) {|s1, s2|
  1464. desc = "#{encdump s1}.end_with?(#{encdump s2})"
  1465. if !str_enc_compatible?(s1, s2)
  1466. assert_raise(Encoding::CompatibilityError, desc) { s1.end_with?(s2) }
  1467. next
  1468. end
  1469. if s1.length < s2.length
  1470. assert_equal(false, enccall(s1, :end_with?, s2), desc)
  1471. next
  1472. end
  1473. if s1[s1.length-s2.length, s2.length] == s2
  1474. assert_equal(true, enccall(s1, :end_with?, s2), desc)
  1475. next
  1476. end
  1477. assert_equal(false, enccall(s1, :end_with?, s2), desc)
  1478. }
  1479. end
  1480. def test_str_start_with?
  1481. combination(STRINGS, STRINGS) {|s1, s2|
  1482. desc = "#{encdump s1}.start_with?(#{encdump s2})"
  1483. if !str_enc_compatible?(s1, s2)
  1484. assert_raise(Encoding::CompatibilityError, desc) { s1.start_with?(s2) }
  1485. next
  1486. end
  1487. s1 = s1.b
  1488. s2 = s2.b
  1489. if s1.length < s2.length
  1490. assert_equal(false, enccall(s1, :start_with?, s2), desc)
  1491. next
  1492. end
  1493. if s1[0, s2.length] == s2
  1494. assert_equal(true, enccall(s1, :start_with?, s2), desc)
  1495. next
  1496. end
  1497. assert_equal(false, enccall(s1, :start_with?, s2), desc)
  1498. }
  1499. end
  1500. def test_str_ord
  1501. STRINGS.each {|s1|
  1502. if s1.empty?
  1503. assert_raise(ArgumentError) { s1.ord }
  1504. next
  1505. end
  1506. if !s1.valid_encoding?
  1507. assert_raise(ArgumentError) { s1.ord }
  1508. next
  1509. end
  1510. assert_equal(s1[0].ord, s1.ord)
  1511. }
  1512. end
  1513. def test_str_partition
  1514. combination(STRINGS, STRINGS) {|s1, s2|
  1515. desc = "#{encdump s1}.partition(#{encdump s2})"
  1516. if !str_enc_compatible?(s1, s2)
  1517. assert_raise(Encoding::CompatibilityError, desc) { s1.partition(s2) }
  1518. next
  1519. end
  1520. i = enccall(s1, :index, s2)
  1521. if !i
  1522. assert_equal([s1, "", ""], s1.partition(s2), desc)
  1523. next
  1524. end
  1525. assert_equal([s1[0,i], s2, s1[(i+s2.length)..-1]], s1.partition(s2), desc)
  1526. }
  1527. end
  1528. def test_str_rpartition
  1529. combination(STRINGS, STRINGS) {|s1, s2|
  1530. desc = "#{encdump s1}.rpartition(#{encdump s2})"
  1531. if !str_enc_compatible?(s1, s2)
  1532. assert_raise(Encoding::CompatibilityError, desc) { s1.rpartition(s2) }
  1533. next
  1534. end
  1535. i = enccall(s1, :rindex, s2)
  1536. if !i
  1537. assert_equal(["", "", s1], s1.rpartition(s2), desc)
  1538. next
  1539. end
  1540. assert_equal([s1[0,i], s2, s1[(i+s2.length)..-1]], s1.rpartition(s2), desc)
  1541. }
  1542. end
  1543. def test_bug11486
  1544. bug11486 = '[Bug #11486]'
  1545. assert_nil ("\u3042"*19+"\r"*19+"\u3042"*20+"\r"*20).encode(Encoding::EUC_JP).gsub!(/xxx/i, ""), bug11486
  1546. assert_match Regexp.new("ABC\uff41".encode(Encoding::EUC_JP), Regexp::IGNORECASE), "abc\uFF21".encode(Encoding::EUC_JP), bug11486
  1547. end
  1548. end