mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
50925b6409
Musl is (of course) not glibc. Its confstr(3) does not understand _CS_GNU_LIBC_VERSION. That's fair. Problem is, its unistd.h has that constant defined for unknown reason. We cannot blindly say the libc is glibc by looking at it. Instead we have to kick it, then see if it quacks like a duck. See https://git.musl-libc.org/cgit/musl/tree/include/unistd.h
1659 lines
45 KiB
Ruby
1659 lines
45 KiB
Ruby
# frozen_string_literal: false
|
|
require 'test/unit'
|
|
require 'etc'
|
|
require_relative 'allpairs'
|
|
|
|
class TestM17NComb < Test::Unit::TestCase
|
|
def assert_encoding(encname, actual, message=nil)
|
|
assert_equal(Encoding.find(encname), actual, message)
|
|
end
|
|
|
|
module AESU
|
|
def a(str) str.dup.force_encoding(Encoding::US_ASCII) end
|
|
def b(str) str.b end
|
|
def e(str) str.dup.force_encoding(Encoding::EUC_JP) end
|
|
def s(str) str.dup.force_encoding(Encoding::SJIS) end
|
|
def u(str) str.dup.force_encoding(Encoding::UTF_8) end
|
|
end
|
|
include AESU
|
|
extend AESU
|
|
|
|
def assert_strenc(bytes, enc, actual, message=nil)
|
|
assert_instance_of(String, actual, message)
|
|
enc = Encoding.find(enc) if String === enc
|
|
assert_equal(enc, actual.encoding, message)
|
|
assert_equal(b(bytes), b(actual), message)
|
|
end
|
|
|
|
STRINGS = [
|
|
b(""), e(""), s(""), u(""),
|
|
b("a"), e("a"), s("a"), u("a"),
|
|
b("."), e("."), s("."), u("."),
|
|
|
|
# single character
|
|
b("\x80"), b("\xff"),
|
|
e("\xa1\xa1"), e("\xfe\xfe"),
|
|
e("\x8e\xa1"), e("\x8e\xfe"),
|
|
e("\x8f\xa1\xa1"), e("\x8f\xfe\xfe"),
|
|
s("\x81\x40"), s("\xfc\xfc"),
|
|
s("\xa1"), s("\xdf"),
|
|
u("\xc2\x80"), u("\xf4\x8f\xbf\xbf"),
|
|
|
|
# same byte sequence
|
|
b("\xc2\xa1"), e("\xc2\xa1"), s("\xc2\xa1"), u("\xc2\xa1"),
|
|
|
|
s("\x81A"), # mutibyte character which contains "A"
|
|
s("\x81a"), # mutibyte character which contains "a"
|
|
|
|
# invalid
|
|
e("\xa1"), e("\x80"),
|
|
s("\x81"), s("\x80"),
|
|
u("\xc2"), u("\x80"),
|
|
|
|
# for transitivity test
|
|
u("\xe0\xa0\xa1"), e("\xe0\xa0\xa1"), s("\xe0\xa0\xa1"), # [ruby-dev:32693]
|
|
e("\xa1\xa1"), b("\xa1\xa1"), s("\xa1\xa1"), # [ruby-dev:36484]
|
|
]
|
|
|
|
WSTRINGS = [
|
|
"aa".force_encoding("utf-16be"),
|
|
"aaaa".force_encoding("utf-32be"),
|
|
"aaa".force_encoding("utf-32be"),
|
|
]
|
|
|
|
def combination(*args, &b)
|
|
AllPairs.each(*args, &b)
|
|
#AllPairs.exhaustive_each(*args, &b)
|
|
end
|
|
|
|
def encdump(str)
|
|
d = str.dump
|
|
if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
|
|
d
|
|
else
|
|
"#{d}.force_encoding(#{str.encoding.name.dump})"
|
|
end
|
|
end
|
|
|
|
def encdumpargs(args)
|
|
r = '('
|
|
args.each_with_index {|a, i|
|
|
r << ',' if 0 < i
|
|
if String === a
|
|
r << encdump(a)
|
|
else
|
|
r << a.inspect
|
|
end
|
|
}
|
|
r << ')'
|
|
r
|
|
end
|
|
|
|
def encdumpcall(recv, meth, *args, &block)
|
|
desc = ''
|
|
if String === recv
|
|
desc << encdump(recv)
|
|
else
|
|
desc << recv.inspect
|
|
end
|
|
desc << '.' << meth.to_s
|
|
if !args.empty?
|
|
desc << '('
|
|
args.each_with_index {|a, i|
|
|
desc << ',' if 0 < i
|
|
if String === a
|
|
desc << encdump(a)
|
|
else
|
|
desc << a.inspect
|
|
end
|
|
}
|
|
desc << ')'
|
|
end
|
|
if block
|
|
desc << ' {}'
|
|
end
|
|
desc
|
|
end
|
|
|
|
def assert_enccall(recv, meth, *args, &block)
|
|
desc = encdumpcall(recv, meth, *args, &block)
|
|
result = nil
|
|
assert_nothing_raised(desc) {
|
|
result = recv.send(meth, *args, &block)
|
|
}
|
|
result
|
|
end
|
|
alias enccall assert_enccall
|
|
|
|
def assert_str_enc_propagation(t, s1, s2)
|
|
if !s1.ascii_only?
|
|
assert_equal(s1.encoding, t.encoding)
|
|
elsif !s2.ascii_only?
|
|
assert_equal(s2.encoding, t.encoding)
|
|
else
|
|
assert_include([s1.encoding, s2.encoding], t.encoding)
|
|
end
|
|
end
|
|
|
|
def assert_same_result(expected_proc, actual_proc)
|
|
e = nil
|
|
begin
|
|
t = expected_proc.call
|
|
rescue
|
|
e = $!
|
|
end
|
|
if e
|
|
assert_raise(e.class) { actual_proc.call }
|
|
else
|
|
assert_equal(t, actual_proc.call)
|
|
end
|
|
end
|
|
|
|
def each_slice_call
|
|
combination(STRINGS, -2..2) {|s, nth|
|
|
yield s, nth
|
|
}
|
|
combination(STRINGS, -2..2, 0..2) {|s, nth, len|
|
|
yield s, nth, len
|
|
}
|
|
combination(STRINGS, STRINGS) {|s, substr|
|
|
yield s, substr
|
|
}
|
|
combination(STRINGS, -2..2, 0..2) {|s, first, last|
|
|
yield s, first..last
|
|
yield s, first...last
|
|
}
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if !s2.valid_encoding?
|
|
next
|
|
end
|
|
yield s1, Regexp.new(Regexp.escape(s2))
|
|
}
|
|
combination(STRINGS, STRINGS, 0..2) {|s1, s2, nth|
|
|
if !s2.valid_encoding?
|
|
next
|
|
end
|
|
yield s1, Regexp.new(Regexp.escape(s2)), nth
|
|
}
|
|
end
|
|
|
|
ASCII_INCOMPATIBLE_ENCODINGS = %w[
|
|
UTF-16BE
|
|
UTF-16LE
|
|
UTF-32BE
|
|
UTF-32LE
|
|
]
|
|
def str_enc_compatible?(*strs)
|
|
encs = []
|
|
ascii_incompatible_encodings = {}
|
|
has_ascii_compatible = false
|
|
strs.each {|s|
|
|
encs << s.encoding if !s.ascii_only?
|
|
if /\A#{Regexp.union ASCII_INCOMPATIBLE_ENCODINGS}\z/o =~ s.encoding.name
|
|
ascii_incompatible_encodings[s.encoding] = true
|
|
else
|
|
has_ascii_compatible = true
|
|
end
|
|
}
|
|
if ascii_incompatible_encodings.empty?
|
|
encs.uniq!
|
|
encs.length <= 1
|
|
else
|
|
!has_ascii_compatible && ascii_incompatible_encodings.size == 1
|
|
end
|
|
end
|
|
|
|
# tests start
|
|
|
|
def test_str_new
|
|
STRINGS.each {|s|
|
|
t = String.new(s)
|
|
assert_strenc(b(s), s.encoding, t)
|
|
}
|
|
end
|
|
|
|
def test_str_plus
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if s1.encoding != s2.encoding && !s1.ascii_only? && !s2.ascii_only?
|
|
assert_raise(Encoding::CompatibilityError) { s1 + s2 }
|
|
else
|
|
t = enccall(s1, :+, s2)
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_equal(b(s1) + b(s2), b(t))
|
|
assert_str_enc_propagation(t, s1, s2)
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_times
|
|
STRINGS.each {|s|
|
|
[0,1,2].each {|n|
|
|
t = s * n
|
|
assert_predicate(t, :valid_encoding?) if s.valid_encoding?
|
|
assert_strenc(b(s) * n, s.encoding, t)
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_sprintf_s
|
|
STRINGS.each {|s|
|
|
assert_strenc(b(s), s.encoding, "%s".force_encoding(s.encoding) % s)
|
|
if !s.empty? # xxx
|
|
t = enccall(b("%s"), :%, s)
|
|
assert_strenc(b(s), (b('')+s).encoding, t)
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_eq_reflexive
|
|
STRINGS.each {|s|
|
|
assert_equal(s, s, "#{encdump s} == #{encdump s}")
|
|
}
|
|
end
|
|
|
|
def test_str_eq_symmetric
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if s1 == s2
|
|
assert_equal(s2, s1, "#{encdump s2} == #{encdump s1}")
|
|
else
|
|
assert_not_equal(s2, s1, "!(#{encdump s2} == #{encdump s1})")
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_eq_transitive
|
|
combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
|
|
if s1 == s2 && s2 == s3
|
|
assert_equal(s1, s3, "transitive: #{encdump s1} == #{encdump s2} == #{encdump s3}")
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_eq
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
desc_eq = "#{encdump s1} == #{encdump s2}"
|
|
if b(s1) == b(s2) and
|
|
(s1.ascii_only? && s2.ascii_only? or
|
|
s1.encoding == s2.encoding) then
|
|
assert_operator(s1, :==, s2, desc_eq)
|
|
assert_not_operator(s1, :!=, s2)
|
|
assert_equal(0, s1 <=> s2)
|
|
assert_operator(s1, :eql?, s2, desc_eq)
|
|
else
|
|
assert_not_operator(s1, :==, s2, "!(#{desc_eq})")
|
|
assert_operator(s1, :!=, s2)
|
|
assert_not_equal(0, s1 <=> s2)
|
|
assert_not_operator(s1, :eql?, s2)
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_concat
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
s = s1.dup
|
|
if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
|
|
s << s2
|
|
assert_predicate(s, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_equal(b(s), b(s1) + b(s2))
|
|
assert_str_enc_propagation(s, s1, s2)
|
|
else
|
|
assert_raise(Encoding::CompatibilityError) { s << s2 }
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_aref
|
|
STRINGS.each {|s|
|
|
t = ''.force_encoding(s.encoding)
|
|
0.upto(s.length-1) {|i|
|
|
u = s[i]
|
|
assert_predicate(u, :valid_encoding?) if s.valid_encoding?
|
|
t << u
|
|
}
|
|
assert_equal(t, s)
|
|
}
|
|
end
|
|
|
|
def test_str_aref_len
|
|
STRINGS.each {|s|
|
|
t = ''.force_encoding(s.encoding)
|
|
0.upto(s.length-1) {|i|
|
|
u = s[i,1]
|
|
assert_predicate(u, :valid_encoding?) if s.valid_encoding?
|
|
t << u
|
|
}
|
|
assert_equal(t, s)
|
|
}
|
|
|
|
STRINGS.each {|s|
|
|
t = ''.force_encoding(s.encoding)
|
|
0.step(s.length-1, 2) {|i|
|
|
u = s[i,2]
|
|
assert_predicate(u, :valid_encoding?) if s.valid_encoding?
|
|
t << u
|
|
}
|
|
assert_equal(t, s)
|
|
}
|
|
end
|
|
|
|
def test_str_aref_substr
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
|
|
t = enccall(s1, :[], s2)
|
|
if t != nil
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_equal(s2, t)
|
|
assert_match(/#{Regexp.escape(b(s2))}/, b(s1))
|
|
if s1.valid_encoding?
|
|
assert_match(/#{Regexp.escape(s2)}/, s1)
|
|
end
|
|
end
|
|
else
|
|
assert_raise(Encoding::CompatibilityError) { s1[s2] }
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_aref_range2
|
|
combination(STRINGS, -2..2, -2..2) {|s, first, last|
|
|
desc = "#{encdump s}[#{first}..#{last}]"
|
|
t = s[first..last]
|
|
if first < 0
|
|
first += s.length
|
|
if first < 0
|
|
assert_nil(t, desc)
|
|
next
|
|
end
|
|
end
|
|
if s.length < first
|
|
assert_nil(t, desc)
|
|
next
|
|
end
|
|
assert_predicate(t, :valid_encoding?) if s.valid_encoding?
|
|
if last < 0
|
|
last += s.length
|
|
end
|
|
t2 = ''
|
|
first.upto(last) {|i|
|
|
c = s[i]
|
|
t2 << c if c
|
|
}
|
|
assert_equal(t2, t, desc)
|
|
}
|
|
end
|
|
|
|
def test_str_aref_range3
|
|
combination(STRINGS, -2..2, -2..2) {|s, first, last|
|
|
desc = "#{encdump s}[#{first}..#{last}]"
|
|
t = s[first...last]
|
|
if first < 0
|
|
first += s.length
|
|
if first < 0
|
|
assert_nil(t, desc)
|
|
next
|
|
end
|
|
end
|
|
if s.length < first
|
|
assert_nil(t, desc)
|
|
next
|
|
end
|
|
if last < 0
|
|
last += s.length
|
|
end
|
|
assert_predicate(t, :valid_encoding?) if s.valid_encoding?
|
|
t2 = ''
|
|
first.upto(last-1) {|i|
|
|
c = s[i]
|
|
t2 << c if c
|
|
}
|
|
assert_equal(t2, t, desc)
|
|
}
|
|
end
|
|
|
|
def test_str_assign
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
(-2).upto(2) {|i|
|
|
t = s1.dup
|
|
if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
|
|
if i < -s1.length || s1.length < i
|
|
assert_raise(IndexError) { t[i] = s2 }
|
|
else
|
|
t[i] = s2
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_send([b(t), :index, b(s2)])
|
|
if s1.valid_encoding? && s2.valid_encoding?
|
|
if i == s1.length && s2.empty?
|
|
assert_nil(t[i])
|
|
elsif i < 0
|
|
assert_equal(s2, t[i-s2.length+1,s2.length],
|
|
"t = #{encdump(s1)}; t[#{i}] = #{encdump(s2)}; t[#{i-s2.length+1},#{s2.length}]")
|
|
else
|
|
assert_equal(s2, t[i,s2.length],
|
|
"t = #{encdump(s1)}; t[#{i}] = #{encdump(s2)}; t[#{i},#{s2.length}]")
|
|
end
|
|
end
|
|
end
|
|
else
|
|
assert_raise(Encoding::CompatibilityError) { t[i] = s2 }
|
|
end
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_str_assign_len
|
|
combination(STRINGS, -2..2, 0..2, STRINGS) {|s1, i, len, s2|
|
|
t = s1.dup
|
|
if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
|
|
if i < -s1.length || s1.length < i
|
|
assert_raise(IndexError) { t[i,len] = s2 }
|
|
else
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
t[i,len] = s2
|
|
assert_send([b(t), :index, b(s2)])
|
|
if s1.valid_encoding? && s2.valid_encoding?
|
|
if i == s1.length && s2.empty?
|
|
assert_nil(t[i])
|
|
elsif i < 0
|
|
if -i < len
|
|
len = -i
|
|
end
|
|
assert_equal(s2, t[i-s2.length+len,s2.length],
|
|
"t = #{encdump(s1)}; t[#{i},#{len}] = #{encdump(s2)}; t[#{i-s2.length+len},#{s2.length}]")
|
|
else
|
|
assert_equal(s2, t[i,s2.length],
|
|
"t = #{encdump(s1)}; t[#{i},#{len}] = #{encdump(s2)}; t[#{i},#{s2.length}]")
|
|
end
|
|
end
|
|
end
|
|
else
|
|
assert_raise(Encoding::CompatibilityError) { t[i,len] = s2 }
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_assign_substr
|
|
combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
|
|
t = s1.dup
|
|
encs = [
|
|
!s1.ascii_only? ? s1.encoding : nil,
|
|
!s2.ascii_only? ? s2.encoding : nil,
|
|
!s3.ascii_only? ? s3.encoding : nil].uniq.compact
|
|
if 1 < encs.length
|
|
assert_raise(Encoding::CompatibilityError, IndexError) { t[s2] = s3 }
|
|
else
|
|
if encs.empty?
|
|
encs = [
|
|
s1.encoding,
|
|
s2.encoding,
|
|
s3.encoding].uniq.reject {|e| e == Encoding.find("ASCII-8BIT") }
|
|
if encs.empty?
|
|
encs = [Encoding.find("ASCII-8BIT")]
|
|
end
|
|
end
|
|
if !t[s2]
|
|
else
|
|
enccall(t, :[]=, s2, s3)
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding? && s3.valid_encoding?
|
|
end
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_assign_range2
|
|
combination(STRINGS, -2..2, -2..2, STRINGS) {|s1, first, last, s2|
|
|
t = s1.dup
|
|
if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
|
|
if first < -s1.length || s1.length < first
|
|
assert_raise(RangeError) { t[first..last] = s2 }
|
|
else
|
|
enccall(t, :[]=, first..last, s2)
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_send([b(t), :index, b(s2)])
|
|
if s1.valid_encoding? && s2.valid_encoding?
|
|
if first < 0
|
|
assert_equal(s2, t[s1.length+first, s2.length])
|
|
else
|
|
assert_equal(s2, t[first, s2.length])
|
|
end
|
|
end
|
|
end
|
|
else
|
|
assert_raise(Encoding::CompatibilityError, RangeError,
|
|
"t=#{encdump(s1)};t[#{first}..#{last}]=#{encdump(s2)}") {
|
|
t[first..last] = s2
|
|
}
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_assign_range3
|
|
combination(STRINGS, -2..2, -2..2, STRINGS) {|s1, first, last, s2|
|
|
t = s1.dup
|
|
if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
|
|
if first < -s1.length || s1.length < first
|
|
assert_raise(RangeError) { t[first...last] = s2 }
|
|
else
|
|
enccall(t, :[]=, first...last, s2)
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_send([b(t), :index, b(s2)])
|
|
if s1.valid_encoding? && s2.valid_encoding?
|
|
if first < 0
|
|
assert_equal(s2, t[s1.length+first, s2.length])
|
|
else
|
|
assert_equal(s2, t[first, s2.length])
|
|
end
|
|
end
|
|
end
|
|
else
|
|
assert_raise(Encoding::CompatibilityError, RangeError,
|
|
"t=#{encdump(s1)};t[#{first}...#{last}]=#{encdump(s2)}") {
|
|
t[first...last] = s2
|
|
}
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_cmp
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
desc = "#{encdump s1} <=> #{encdump s2}"
|
|
r = s1 <=> s2
|
|
if s1 == s2
|
|
assert_equal(0, r, desc)
|
|
else
|
|
assert_not_equal(0, r, desc)
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_capitalize
|
|
STRINGS.each {|s|
|
|
begin
|
|
t1 = s.capitalize
|
|
rescue ArgumentError
|
|
assert_not_predicate(s, :valid_encoding?)
|
|
next
|
|
end
|
|
assert_predicate(t1, :valid_encoding?) if s.valid_encoding?
|
|
assert_operator(t1, :casecmp, s)
|
|
t2 = s.dup
|
|
t2.capitalize!
|
|
assert_equal(t1, t2)
|
|
r = s.downcase
|
|
r = enccall(r, :sub, /\A[a-z]/) {|ch| b(ch).upcase }
|
|
assert_equal(r, t1)
|
|
}
|
|
end
|
|
|
|
def test_str_casecmp
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
#puts "#{encdump(s1)}.casecmp(#{encdump(s2)})"
|
|
next unless s1.valid_encoding? && s2.valid_encoding? && Encoding.compatible?(s1, s2)
|
|
r = s1.casecmp(s2)
|
|
assert_equal(s1.upcase <=> s2.upcase, r)
|
|
}
|
|
end
|
|
|
|
def test_str_center
|
|
combination(STRINGS, [0,1,2,3,10]) {|s1, width|
|
|
t = s1.center(width)
|
|
assert_send([b(t), :index, b(s1)])
|
|
}
|
|
combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
|
|
if s2.empty?
|
|
assert_raise(ArgumentError) { s1.center(width, s2) }
|
|
next
|
|
end
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.center(width, s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :center, width, s2)
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_send([b(t), :index, b(s1)])
|
|
assert_str_enc_propagation(t, s1, s2) if (t != s1)
|
|
}
|
|
end
|
|
|
|
def test_str_ljust
|
|
combination(STRINGS, [0,1,2,3,10]) {|s1, width|
|
|
t = s1.ljust(width)
|
|
assert_send([b(t), :index, b(s1)])
|
|
}
|
|
combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
|
|
if s2.empty?
|
|
assert_raise(ArgumentError) { s1.ljust(width, s2) }
|
|
next
|
|
end
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.ljust(width, s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :ljust, width, s2)
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_send([b(t), :index, b(s1)])
|
|
assert_str_enc_propagation(t, s1, s2) if (t != s1)
|
|
}
|
|
end
|
|
|
|
def test_str_rjust
|
|
combination(STRINGS, [0,1,2,3,10]) {|s1, width|
|
|
t = s1.rjust(width)
|
|
assert_send([b(t), :index, b(s1)])
|
|
}
|
|
combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
|
|
if s2.empty?
|
|
assert_raise(ArgumentError) { s1.rjust(width, s2) }
|
|
next
|
|
end
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.rjust(width, s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :rjust, width, s2)
|
|
assert_predicate(t, :valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_send([b(t), :index, b(s1)])
|
|
assert_str_enc_propagation(t, s1, s2) if (t != s1)
|
|
}
|
|
end
|
|
|
|
def test_str_chomp
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if !s1.ascii_only? && !s2.ascii_only? && !Encoding.compatible?(s1,s2)
|
|
if s1.bytesize > s2.bytesize
|
|
assert_raise(Encoding::CompatibilityError, "#{encdump(s1)}.chomp(#{encdump(s2)})") do
|
|
s1.chomp(s2)
|
|
end
|
|
end
|
|
next
|
|
end
|
|
t = enccall(s1, :chomp, s2)
|
|
assert_predicate(t, :valid_encoding?, "#{encdump(s1)}.chomp(#{encdump(s2)})") if s1.valid_encoding? && s2.valid_encoding?
|
|
assert_equal(s1.encoding, t.encoding)
|
|
t2 = s1.dup
|
|
t2.chomp!(s2)
|
|
assert_equal(t, t2)
|
|
}
|
|
end
|
|
|
|
def test_str_smart_chomp
|
|
bug10893 = '[ruby-core:68258] [Bug #10893]'
|
|
encodings = Encoding.list.select {|enc| !enc.dummy?}
|
|
combination(encodings, encodings) do |e1, e2|
|
|
expected = "abc".encode(e1)
|
|
combination(["abc\n", "abc\r\n"], ["", "\n"]) do |str, rs|
|
|
assert_equal(expected, str.encode(e1).chomp(rs.encode(e2)), bug10893)
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_str_chop
|
|
STRINGS.each {|s|
|
|
s = s.dup
|
|
desc = "#{encdump s}.chop"
|
|
t = nil
|
|
assert_nothing_raised(desc) { t = s.chop }
|
|
assert_predicate(t, :valid_encoding?) if s.valid_encoding?
|
|
assert_send([b(s), :index, b(t)])
|
|
t2 = s.dup
|
|
t2.chop!
|
|
assert_equal(t, t2)
|
|
}
|
|
end
|
|
|
|
def test_str_clear
|
|
STRINGS.each {|s|
|
|
t = s.dup
|
|
t.clear
|
|
assert_predicate(t, :valid_encoding?)
|
|
assert_empty(t)
|
|
}
|
|
end
|
|
|
|
def test_str_clone
|
|
STRINGS.each {|s|
|
|
t = s.clone
|
|
assert_equal(s, t)
|
|
assert_equal(s.encoding, t.encoding)
|
|
assert_equal(b(s), b(t))
|
|
}
|
|
end
|
|
|
|
def test_str_dup
|
|
STRINGS.each {|s|
|
|
t = s.dup
|
|
assert_equal(s, t)
|
|
assert_equal(s.encoding, t.encoding)
|
|
assert_equal(b(s), b(t))
|
|
}
|
|
end
|
|
|
|
def test_str_count
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
desc = proc {encdumpcall(s1, :count, s2)}
|
|
if !s1.valid_encoding? || !s2.valid_encoding?
|
|
assert_raise(ArgumentError, Encoding::CompatibilityError, desc) { s1.count(s2) }
|
|
next
|
|
end
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError, desc) { s1.count(s2) }
|
|
next
|
|
end
|
|
n = enccall(s1, :count, s2)
|
|
n0 = b(s1).count(b(s2))
|
|
assert_operator(n, :<=, n0)
|
|
}
|
|
end
|
|
|
|
def crypt_supports_des_crypt?
|
|
/openbsd/ !~ RUBY_PLATFORM
|
|
end
|
|
|
|
# glibc 2.16 or later denies salt contained other than [0-9A-Za-z./] #7312
|
|
# we use this check to test strict and non-strict behavior separately #11045
|
|
strict_crypt = if defined? Etc::CS_GNU_LIBC_VERSION
|
|
begin
|
|
confstr = Etc.confstr(Etc::CS_GNU_LIBC_VERSION)
|
|
rescue Errno::EINVAL
|
|
false
|
|
else
|
|
glibcver = confstr.scan(/\d+/).map(&:to_i)
|
|
(glibcver <=> [2, 16]) >= 0
|
|
end
|
|
end
|
|
|
|
def test_str_crypt
|
|
combination(STRINGS, STRINGS) {|str, salt|
|
|
# skip input other than [0-9A-Za-z./] to confirm strict behavior
|
|
next unless salt.ascii_only? && /\A[0-9a-zA-Z.\/]+\z/ =~ salt
|
|
|
|
confirm_crypt_result(str, salt)
|
|
}
|
|
end
|
|
|
|
if !strict_crypt && /openbsd/ !~ RUBY_PLATFORM
|
|
def test_str_crypt_nonstrict
|
|
combination(STRINGS, STRINGS) {|str, salt|
|
|
# only test input other than [0-9A-Za-z./] to confirm non-strict behavior
|
|
next if salt.ascii_only? && /\A[0-9a-zA-Z.\/]+\z/ =~ salt
|
|
|
|
confirm_crypt_result(str, salt)
|
|
}
|
|
end
|
|
end
|
|
|
|
private def confirm_crypt_result(str, salt)
|
|
if crypt_supports_des_crypt?
|
|
if b(salt).length < 2
|
|
assert_raise(ArgumentError) { str.crypt(salt) }
|
|
return
|
|
end
|
|
else
|
|
return if b(salt).length < 2
|
|
salt = "$2a$04$0WVaz0pV3jzfZ5G5tpmH#{salt}"
|
|
end
|
|
t = str.crypt(salt)
|
|
assert_equal(b(str).crypt(b(salt)), t, "#{encdump(str)}.crypt(#{encdump(salt)})")
|
|
assert_encoding('ASCII-8BIT', t.encoding)
|
|
end
|
|
|
|
def test_str_delete
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if s1.empty?
|
|
assert_equal(s1, s1.delete(s2))
|
|
next
|
|
end
|
|
if !s1.valid_encoding? || !s2.valid_encoding?
|
|
assert_raise(ArgumentError, Encoding::CompatibilityError) { s1.delete(s2) }
|
|
next
|
|
end
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.delete(s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :delete, s2)
|
|
assert_predicate(t, :valid_encoding?)
|
|
assert_equal(t.encoding, s1.encoding)
|
|
assert_operator(t.length, :<=, s1.length)
|
|
t2 = s1.dup
|
|
t2.delete!(s2)
|
|
assert_equal(t, t2)
|
|
}
|
|
end
|
|
|
|
def test_str_downcase
|
|
STRINGS.each {|s|
|
|
if !s.valid_encoding?
|
|
assert_raise(ArgumentError, "Offending string: #{s.inspect}, encoding: #{s.encoding}") { s.downcase }
|
|
next
|
|
end
|
|
t = s.downcase
|
|
assert_predicate(t, :valid_encoding?)
|
|
assert_equal(t.encoding, s.encoding)
|
|
assert_operator(t, :casecmp, s)
|
|
t2 = s.dup
|
|
t2.downcase!
|
|
assert_equal(t, t2)
|
|
}
|
|
end
|
|
|
|
def test_str_dump
|
|
STRINGS.each {|s|
|
|
t = s.dump
|
|
assert_predicate(t, :valid_encoding?)
|
|
assert_predicate(t, :ascii_only?)
|
|
u = eval(t)
|
|
assert_equal(b(s), b(u))
|
|
}
|
|
end
|
|
|
|
def test_str_each_line
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.each_line(s2) {} }
|
|
next
|
|
end
|
|
lines = []
|
|
enccall(s1, :each_line, s2) {|line|
|
|
assert_equal(s1.encoding, line.encoding)
|
|
lines << line
|
|
}
|
|
next if lines.size == 0
|
|
s2 = lines.join('')
|
|
assert_equal(s1.encoding, s2.encoding)
|
|
assert_equal(s1, s2)
|
|
}
|
|
end
|
|
|
|
def test_str_each_byte
|
|
STRINGS.each {|s|
|
|
bytes = []
|
|
s.each_byte {|b|
|
|
bytes << b
|
|
}
|
|
b(s).split(//).each_with_index {|ch, i|
|
|
assert_equal(ch.ord, bytes[i])
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_str_empty?
|
|
STRINGS.each {|s|
|
|
if s.length == 0
|
|
assert_empty(s)
|
|
else
|
|
assert_not_empty(s)
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_hex
|
|
STRINGS.each {|s|
|
|
t = s.hex
|
|
t2 = b(s)[/\A[0-9a-fA-Fx]*/].hex
|
|
assert_equal(t2, t)
|
|
}
|
|
end
|
|
|
|
def test_str_include?
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.include?(s2) }
|
|
assert_raise(Encoding::CompatibilityError) { s1.index(s2) }
|
|
assert_raise(Encoding::CompatibilityError) { s1.rindex(s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :include?, s2)
|
|
if t
|
|
assert_include(b(s1), b(s2))
|
|
assert_send([s1, :index, s2])
|
|
assert_send([s1, :rindex, s2])
|
|
else
|
|
assert_not_send([s1, :index, s2])
|
|
assert_not_send([s1, :rindex, s2], "!#{encdump(s1)}.rindex(#{encdump(s2)})")
|
|
end
|
|
if s2.empty?
|
|
assert_equal(true, t)
|
|
next
|
|
end
|
|
if !s1.valid_encoding? || !s2.valid_encoding?
|
|
assert_equal(false, t, "#{encdump s1}.include?(#{encdump s2})")
|
|
next
|
|
end
|
|
if t && s1.valid_encoding? && s2.valid_encoding?
|
|
assert_match(/#{Regexp.escape(s2)}/, s1)
|
|
else
|
|
assert_no_match(/#{Regexp.escape(s2)}/, s1)
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_index
|
|
combination(STRINGS, STRINGS, -2..2) {|s1, s2, pos|
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.index(s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :index, s2, pos)
|
|
if s2.empty?
|
|
if pos < 0 && pos+s1.length < 0
|
|
assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
|
|
elsif pos < 0
|
|
assert_equal(s1.length+pos, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
|
|
elsif s1.length < pos
|
|
assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
|
|
else
|
|
assert_equal(pos, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
|
|
end
|
|
next
|
|
end
|
|
if !s1.valid_encoding? || !s2.valid_encoding?
|
|
assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
|
|
next
|
|
end
|
|
if t
|
|
re = /#{Regexp.escape(s2)}/
|
|
assert(re.match(s1, pos))
|
|
assert_equal($`.length, t, "#{encdump s1}.index(#{encdump s2}, #{pos})")
|
|
else
|
|
assert_no_match(/#{Regexp.escape(s2)}/, s1[pos..-1])
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_rindex
|
|
combination(STRINGS, STRINGS, -2..2) {|s1, s2, pos|
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.rindex(s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :rindex, s2, pos)
|
|
if s2.empty?
|
|
if pos < 0 && pos+s1.length < 0
|
|
assert_equal(nil, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
|
|
elsif pos < 0
|
|
assert_equal(s1.length+pos, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
|
|
elsif s1.length < pos
|
|
assert_equal(s1.length, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
|
|
else
|
|
assert_equal(pos, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
|
|
end
|
|
next
|
|
end
|
|
if !s1.valid_encoding? || !s2.valid_encoding?
|
|
assert_equal(nil, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
|
|
next
|
|
end
|
|
if t
|
|
#puts "#{encdump s1}.rindex(#{encdump s2}, #{pos}) => #{t}"
|
|
assert_send([b(s1), :index, b(s2)])
|
|
pos2 = pos
|
|
pos2 += s1.length if pos < 0
|
|
re = /\A(.{0,#{pos2}})#{Regexp.escape(s2)}/m
|
|
m = enccall(re, :match, s1)
|
|
assert(m, "#{re.inspect}.match(#{encdump(s1)})")
|
|
assert_equal(m[1].length, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
|
|
else
|
|
re = /#{Regexp.escape(s2)}/
|
|
n = re =~ s1
|
|
if n
|
|
if pos < 0
|
|
assert_operator(n, :>, s1.length+pos)
|
|
else
|
|
assert_operator(n, :>, pos)
|
|
end
|
|
end
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_insert
|
|
combination(STRINGS, 0..2, STRINGS) {|s1, nth, s2|
|
|
t1 = s1.dup
|
|
t2 = s1.dup
|
|
begin
|
|
t1[nth, 0] = s2
|
|
rescue Encoding::CompatibilityError, IndexError => e1
|
|
end
|
|
begin
|
|
t2.insert(nth, s2)
|
|
rescue Encoding::CompatibilityError, IndexError => e2
|
|
end
|
|
assert_equal(t1, t2, "t=#{encdump s1}; t.insert(#{nth},#{encdump s2}); t")
|
|
assert_equal(e1.class, e2.class, "begin #{encdump s1}.insert(#{nth},#{encdump s2}); rescue ArgumentError, IndexError => e; e end")
|
|
}
|
|
combination(STRINGS, -2..-1, STRINGS) {|s1, nth, s2|
|
|
next if s1.length + nth < 0
|
|
next unless s1.valid_encoding?
|
|
next unless s2.valid_encoding?
|
|
t1 = s1.dup
|
|
begin
|
|
t1.insert(nth, s2)
|
|
slen = s2.length
|
|
assert_equal(t1[nth-slen+1,slen], s2, "t=#{encdump s1}; t.insert(#{nth},#{encdump s2}); t")
|
|
rescue Encoding::CompatibilityError, IndexError
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_intern
|
|
STRINGS.each {|s|
|
|
if /\0/ =~ b(s)
|
|
assert_raise(ArgumentError) { s.intern }
|
|
elsif s.valid_encoding?
|
|
sym = s.intern
|
|
assert_equal(s, sym.to_s, "#{encdump s}.intern.to_s")
|
|
assert_equal(sym, s.to_sym)
|
|
else
|
|
assert_raise(EncodingError) { s.intern }
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_length
|
|
STRINGS.each {|s|
|
|
assert_operator(s.length, :<=, s.bytesize)
|
|
}
|
|
end
|
|
|
|
def test_str_oct
|
|
STRINGS.each {|s|
|
|
t = s.oct
|
|
t2 = b(s)[/\A[0-9a-fA-FxX]*/].oct
|
|
assert_equal(t2, t)
|
|
}
|
|
end
|
|
|
|
def test_str_replace
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
t = s1.dup
|
|
t.replace s2
|
|
assert_equal(s2, t)
|
|
assert_equal(s2.encoding, t.encoding)
|
|
}
|
|
end
|
|
|
|
def test_str_reverse
|
|
STRINGS.each {|s|
|
|
t = s.reverse
|
|
assert_equal(s.bytesize, t.bytesize)
|
|
if !s.valid_encoding?
|
|
assert_operator(t.length, :<=, s.length)
|
|
next
|
|
end
|
|
assert_equal(s, t.reverse)
|
|
}
|
|
end
|
|
|
|
def test_str_scan
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
desc = proc {"#{s1.dump}.scan(#{s2.dump})"}
|
|
if !s2.valid_encoding?
|
|
assert_raise(RegexpError, desc) { s1.scan(s2) }
|
|
next
|
|
end
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
if s1.valid_encoding?
|
|
assert_raise(Encoding::CompatibilityError, desc) { s1.scan(s2) }
|
|
else
|
|
assert_raise_with_message(ArgumentError, /invalid byte sequence/, desc) { s1.scan(s2) }
|
|
end
|
|
next
|
|
end
|
|
if !s1.valid_encoding?
|
|
assert_raise(ArgumentError, desc) { s1.scan(s2) }
|
|
next
|
|
end
|
|
r = enccall(s1, :scan, s2)
|
|
r.each {|t|
|
|
assert_equal(s2, t, desc)
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_str_slice
|
|
each_slice_call {|obj, *args|
|
|
assert_same_result(lambda { obj[*args] }, lambda { obj.slice(*args) })
|
|
}
|
|
end
|
|
|
|
def test_str_slice!
|
|
each_slice_call {|s, *args|
|
|
desc_slice = "#{encdump s}.slice#{encdumpargs args}"
|
|
desc_slice_bang = "#{encdump s}.slice!#{encdumpargs args}"
|
|
t = s.dup
|
|
begin
|
|
r = t.slice!(*args)
|
|
rescue
|
|
e = $!
|
|
end
|
|
if e
|
|
assert_raise(e.class, desc_slice) { s.slice(*args) }
|
|
next
|
|
end
|
|
if !r
|
|
assert_nil(s.slice(*args), desc_slice)
|
|
next
|
|
end
|
|
assert_equal(s.slice(*args), r, desc_slice_bang)
|
|
assert_equal(s.bytesize, r.bytesize + t.bytesize)
|
|
if args.length == 1 && String === args[0]
|
|
assert_equal(args[0].encoding, r.encoding,
|
|
"#{encdump s}.slice!#{encdumpargs args}.encoding")
|
|
else
|
|
assert_equal(s.encoding, r.encoding,
|
|
"#{encdump s}.slice!#{encdumpargs args}.encoding")
|
|
end
|
|
if [s, *args].all? {|o| !(String === o) || o.valid_encoding? }
|
|
assert_predicate(r, :valid_encoding?)
|
|
assert_predicate(t, :valid_encoding?)
|
|
assert_equal(s.length, r.length + t.length)
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_split
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if !s2.valid_encoding?
|
|
assert_raise(ArgumentError, RegexpError) { s1.split(s2) }
|
|
next
|
|
end
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(ArgumentError, Encoding::CompatibilityError) { s1.split(s2) }
|
|
next
|
|
end
|
|
if !s1.valid_encoding?
|
|
assert_raise(ArgumentError) { s1.split(s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :split, s2)
|
|
t.each {|r|
|
|
assert_include(b(s1), b(r))
|
|
assert_equal(s1.encoding, r.encoding)
|
|
}
|
|
assert_include(b(s1), t.map {|u| b(u) }.join(b(s2)))
|
|
if s1.valid_encoding? && s2.valid_encoding?
|
|
t.each {|r|
|
|
assert_predicate(r, :valid_encoding?)
|
|
}
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_str_squeeze
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if !s1.valid_encoding? || !s2.valid_encoding?
|
|
assert_raise(ArgumentError, Encoding::CompatibilityError, "#{encdump s1}.squeeze(#{encdump s2})") { s1.squeeze(s2) }
|
|
next
|
|
end
|
|
if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
|
|
assert_raise(Encoding::CompatibilityError) { s1.squeeze(s2) }
|
|
next
|
|
end
|
|
t = enccall(s1, :squeeze, s2)
|
|
assert_operator(t.length, :<=, s1.length)
|
|
t2 = s1.dup
|
|
t2.squeeze!(s2)
|
|
assert_equal(t, t2)
|
|
}
|
|
end
|
|
|
|
def test_str_strip
|
|
STRINGS.each {|s|
|
|
if !s.valid_encoding?
|
|
assert_raise(ArgumentError, "#{encdump s}.strip") { s.strip }
|
|
next
|
|
end
|
|
t = s.strip
|
|
l = s.lstrip
|
|
r = s.rstrip
|
|
assert_operator(l.length, :<=, s.length)
|
|
assert_operator(r.length, :<=, s.length)
|
|
assert_operator(t.length, :<=, l.length)
|
|
assert_operator(t.length, :<=, r.length)
|
|
t2 = s.dup
|
|
t2.strip!
|
|
assert_equal(t, t2)
|
|
l2 = s.dup
|
|
l2.lstrip!
|
|
assert_equal(l, l2)
|
|
r2 = s.dup
|
|
r2.rstrip!
|
|
assert_equal(r, r2)
|
|
}
|
|
end
|
|
|
|
def test_str_sum
|
|
STRINGS.each {|s|
|
|
assert_equal(b(s).sum, s.sum)
|
|
}
|
|
end
|
|
|
|
def test_str_swapcase
|
|
STRINGS.each {|s|
|
|
if !s.valid_encoding?
|
|
assert_raise(ArgumentError, "#{encdump s}.swapcase") { s.swapcase }
|
|
next
|
|
end
|
|
t1 = s.swapcase
|
|
assert_predicate(t1, :valid_encoding?) if s.valid_encoding?
|
|
assert_operator(t1, :casecmp, s)
|
|
t2 = s.dup
|
|
t2.swapcase!
|
|
assert_equal(t1, t2)
|
|
t3 = t1.swapcase
|
|
assert_equal(s, t3);
|
|
}
|
|
end
|
|
|
|
|
|
def test_str_to_f
|
|
STRINGS.each {|s|
|
|
assert_nothing_raised { s.to_f }
|
|
}
|
|
end
|
|
|
|
def test_str_to_i
|
|
STRINGS.each {|s|
|
|
assert_nothing_raised { s.to_i }
|
|
2.upto(36) {|radix|
|
|
assert_nothing_raised { s.to_i(radix) }
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_str_to_s
|
|
STRINGS.each {|s|
|
|
assert_same(s, s.to_s)
|
|
assert_same(s, s.to_str)
|
|
}
|
|
end
|
|
|
|
def test_tr
|
|
combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
|
|
desc = "#{encdump s1}.tr(#{encdump s2}, #{encdump s3})"
|
|
if s1.empty?
|
|
assert_equal(s1, s1.tr(s2, s3), desc)
|
|
next
|
|
end
|
|
if !str_enc_compatible?(s1, s2, s3)
|
|
assert_raise(Encoding::CompatibilityError, desc) { s1.tr(s2, s3) }
|
|
next
|
|
end
|
|
if !s1.valid_encoding?
|
|
assert_raise(ArgumentError, desc) { s1.tr(s2, s3) }
|
|
next
|
|
end
|
|
if s2.empty?
|
|
t = enccall(s1, :tr, s2, s3)
|
|
assert_equal(s1, t, desc)
|
|
next
|
|
end
|
|
if !s2.valid_encoding? || !s3.valid_encoding?
|
|
assert_raise(ArgumentError, desc) { s1.tr(s2, s3) }
|
|
next
|
|
end
|
|
t = enccall(s1, :tr, s2, s3)
|
|
assert_operator(s1.length, :>=, t.length, desc)
|
|
}
|
|
end
|
|
|
|
def test_tr_sjis
|
|
expected = "\x83}\x83~\x83\x80\x83\x81\x83\x82".force_encoding(Encoding::SJIS)
|
|
source = "\xCF\xD0\xD1\xD2\xD3".force_encoding(Encoding::SJIS)
|
|
from = "\xCF-\xD3".force_encoding(Encoding::SJIS)
|
|
to = "\x83}-\x83\x82".force_encoding(Encoding::SJIS)
|
|
assert_equal(expected, source.tr(from, to))
|
|
|
|
expected = "\x84}\x84~\x84\x80\x84\x81\x84\x82".force_encoding(Encoding::SJIS)
|
|
source = "\x84M\x84N\x84O\x84P\x84Q".force_encoding(Encoding::SJIS)
|
|
from = "\x84@-\x84`".force_encoding(Encoding::SJIS)
|
|
to = "\x84p-\x84\x91".force_encoding(Encoding::SJIS)
|
|
assert_equal(expected, source.tr(from, to))
|
|
end
|
|
|
|
def test_tr_s
|
|
combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
|
|
desc = "#{encdump s1}.tr_s(#{encdump s2}, #{encdump s3})"
|
|
if s1.empty?
|
|
assert_equal(s1, s1.tr_s(s2, s3), desc)
|
|
next
|
|
end
|
|
if !s1.valid_encoding?
|
|
assert_raise(ArgumentError, Encoding::CompatibilityError, desc) { s1.tr_s(s2, s3) }
|
|
next
|
|
end
|
|
if !str_enc_compatible?(s1, s2, s3)
|
|
assert_raise(Encoding::CompatibilityError, desc) { s1.tr(s2, s3) }
|
|
next
|
|
end
|
|
if s2.empty?
|
|
t = enccall(s1, :tr_s, s2, s3)
|
|
assert_equal(s1, t, desc)
|
|
next
|
|
end
|
|
if !s2.valid_encoding? || !s3.valid_encoding?
|
|
assert_raise(ArgumentError, desc) { s1.tr_s(s2, s3) }
|
|
next
|
|
end
|
|
|
|
t = enccall(s1, :tr_s, s2, s3)
|
|
assert_operator(s1.length, :>=, t.length, desc)
|
|
}
|
|
end
|
|
|
|
def test_str_upcase
|
|
STRINGS.each {|s|
|
|
desc = "#{encdump s}.upcase"
|
|
if !s.valid_encoding?
|
|
assert_raise(ArgumentError, desc) { s.upcase }
|
|
next
|
|
end
|
|
t1 = s.upcase
|
|
assert_predicate(t1, :valid_encoding?)
|
|
assert_operator(t1, :casecmp, s)
|
|
t2 = s.dup
|
|
t2.upcase!
|
|
assert_equal(t1, t2)
|
|
}
|
|
end
|
|
|
|
def test_str_succ
|
|
STRINGS.each {|s0|
|
|
next if s0.empty?
|
|
s = s0.dup
|
|
n = 300
|
|
h = {}
|
|
n.times {|i|
|
|
if h[s]
|
|
assert(false, "#{encdump s} cycle with succ #{i-h[s]} times")
|
|
end
|
|
h[s] = i
|
|
assert_operator(s.length, :<=, s0.length + Math.log2(i+1) + 1, "#{encdump s0} succ #{i} times => #{encdump s}")
|
|
#puts encdump(s)
|
|
t = s.succ
|
|
if s.valid_encoding?
|
|
assert_predicate(t, :valid_encoding?, "#{encdump s}.succ.valid_encoding?")
|
|
end
|
|
s = t
|
|
}
|
|
}
|
|
|
|
Encoding.list.each do |enc|
|
|
next if enc.dummy?
|
|
{"A"=>"B", "A1"=>"A2", "A9"=>"B0", "9"=>"10", "Z"=>"AA"}.each do |orig, expected|
|
|
s = orig.encode(enc)
|
|
assert_strenc(expected.encode(enc), enc, s.succ, proc {"#{orig.dump}.encode(#{enc}).succ"})
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_str_succ2
|
|
assert_equal(a("\x01\x00"), a("\x7f").succ)
|
|
assert_equal(b("\x01\x00"), b("\xff").succ)
|
|
end
|
|
|
|
def test_str_hash
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
if s1.eql?(s2)
|
|
assert_equal(s1.hash, s2.hash, "#{encdump s1}.hash == #{encdump s2}.dump")
|
|
end
|
|
}
|
|
end
|
|
|
|
def test_marshal
|
|
STRINGS.each {|s|
|
|
m = Marshal.dump(s)
|
|
t = Marshal.load(m)
|
|
assert_equal(s, t)
|
|
}
|
|
end
|
|
|
|
def test_str_sub
|
|
combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
|
|
if !s2.valid_encoding?
|
|
assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }
|
|
next
|
|
end
|
|
r2 = Regexp.new(Regexp.escape(s2))
|
|
[
|
|
[
|
|
"#{encdump s1}.sub(Regexp.new(#{encdump s2}), #{encdump s3})",
|
|
lambda { s1.sub(r2, s3) },
|
|
false
|
|
],
|
|
[
|
|
"#{encdump s1}.sub(Regexp.new(#{encdump s2}), #{encdump s3})",
|
|
lambda { s1.sub(r2) { s3 } },
|
|
false
|
|
],
|
|
[
|
|
"#{encdump s1}.gsub(Regexp.new(#{encdump s2}), #{encdump s3})",
|
|
lambda { s1.gsub(r2, s3) },
|
|
true
|
|
],
|
|
[
|
|
"#{encdump s1}.gsub(Regexp.new(#{encdump s2}), #{encdump s3})",
|
|
lambda { s1.gsub(r2) { s3 } },
|
|
true
|
|
]
|
|
].each {|desc, doit, g|
|
|
if !s1.valid_encoding?
|
|
assert_raise(ArgumentError, desc) { doit.call }
|
|
next
|
|
end
|
|
if !str_enc_compatible?(s1, s2)
|
|
assert_raise(Encoding::CompatibilityError, desc) { doit.call }
|
|
next
|
|
end
|
|
if !enccall(s1, :include?, s2)
|
|
assert_equal(s1, doit.call)
|
|
next
|
|
end
|
|
if !str_enc_compatible?(g ? s1.gsub(r2, '') : s1.sub(r2, ''), s3)
|
|
assert_raise(Encoding::CompatibilityError, desc) { doit.call }
|
|
next
|
|
end
|
|
t = nil
|
|
assert_nothing_raised(desc) {
|
|
t = doit.call
|
|
}
|
|
if s2 == s3
|
|
assert_equal(s1, t, desc)
|
|
else
|
|
assert_not_equal(s1, t, desc)
|
|
end
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_str_sub!
|
|
combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
|
|
if !s2.valid_encoding?
|
|
assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }
|
|
next
|
|
end
|
|
r2 = Regexp.new(Regexp.escape(s2))
|
|
[
|
|
[
|
|
"t=#{encdump s1}.dup;t.sub!(Regexp.new(#{encdump s2}), #{encdump s3})",
|
|
lambda { t=s1.dup; [t, t.sub!(r2, s3)] },
|
|
false
|
|
],
|
|
[
|
|
"t=#{encdump s1}.dup;t.sub!(Regexp.new(#{encdump s2}), #{encdump s3})",
|
|
lambda { t=s1.dup; [t, t.sub!(r2) { s3 }] },
|
|
false
|
|
],
|
|
[
|
|
"t=#{encdump s1}.dup;t.gsub!(Regexp.new(#{encdump s2}), #{encdump s3})",
|
|
lambda { t=s1.dup; [t, t.gsub!(r2, s3)] },
|
|
true
|
|
],
|
|
[
|
|
"t=#{encdump s1}.dup;t.gsub!(Regexp.new(#{encdump s2}), #{encdump s3})",
|
|
lambda { t=s1.dup; [t, t.gsub!(r2) { s3 }] },
|
|
true
|
|
]
|
|
].each {|desc, doit, g|
|
|
if !s1.valid_encoding?
|
|
assert_raise(ArgumentError, desc) { doit.call }
|
|
next
|
|
end
|
|
if !str_enc_compatible?(s1, s2)
|
|
assert_raise(Encoding::CompatibilityError, desc) { doit.call }
|
|
next
|
|
end
|
|
if !enccall(s1, :include?, s2)
|
|
assert_equal([s1, nil], doit.call)
|
|
next
|
|
end
|
|
if !str_enc_compatible?(g ? s1.gsub(r2, '') : s1.sub(r2, ''), s3)
|
|
assert_raise(Encoding::CompatibilityError, desc) { doit.call }
|
|
next
|
|
end
|
|
t = ret = nil
|
|
assert_nothing_raised(desc) {
|
|
t, ret = doit.call
|
|
}
|
|
assert(ret)
|
|
if s2 == s3
|
|
assert_equal(s1, t, desc)
|
|
else
|
|
assert_not_equal(s1, t, desc)
|
|
end
|
|
}
|
|
}
|
|
end
|
|
|
|
def test_str_bytes
|
|
STRINGS.each {|s1|
|
|
ary = []
|
|
s1.bytes.each {|b|
|
|
ary << b
|
|
}
|
|
assert_equal(s1.unpack("C*"), ary)
|
|
}
|
|
end
|
|
|
|
def test_str_bytesize
|
|
STRINGS.each {|s1|
|
|
assert_equal(s1.unpack("C*").length, s1.bytesize)
|
|
}
|
|
end
|
|
|
|
def test_str_chars
|
|
STRINGS.each {|s1|
|
|
ary = []
|
|
s1.chars.each {|c|
|
|
ary << c
|
|
}
|
|
expected = []
|
|
s1.length.times {|i|
|
|
expected << s1[i]
|
|
}
|
|
assert_equal(expected, ary)
|
|
}
|
|
end
|
|
|
|
def test_str_chr
|
|
STRINGS.each {|s1|
|
|
if s1.empty?
|
|
assert_equal("", s1.chr)
|
|
next
|
|
end
|
|
assert_equal(s1[0], s1.chr)
|
|
}
|
|
end
|
|
|
|
def test_str_end_with?
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
desc = "#{encdump s1}.end_with?(#{encdump s2})"
|
|
if !str_enc_compatible?(s1, s2)
|
|
assert_raise(Encoding::CompatibilityError, desc) { s1.end_with?(s2) }
|
|
next
|
|
end
|
|
if s1.length < s2.length
|
|
assert_equal(false, enccall(s1, :end_with?, s2), desc)
|
|
next
|
|
end
|
|
if s1[s1.length-s2.length, s2.length] == s2
|
|
assert_equal(true, enccall(s1, :end_with?, s2), desc)
|
|
next
|
|
end
|
|
assert_equal(false, enccall(s1, :end_with?, s2), desc)
|
|
}
|
|
end
|
|
|
|
def test_str_start_with?
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
desc = "#{encdump s1}.start_with?(#{encdump s2})"
|
|
if !str_enc_compatible?(s1, s2)
|
|
assert_raise(Encoding::CompatibilityError, desc) { s1.start_with?(s2) }
|
|
next
|
|
end
|
|
s1 = s1.b
|
|
s2 = s2.b
|
|
if s1.length < s2.length
|
|
assert_equal(false, enccall(s1, :start_with?, s2), desc)
|
|
next
|
|
end
|
|
if s1[0, s2.length] == s2
|
|
assert_equal(true, enccall(s1, :start_with?, s2), desc)
|
|
next
|
|
end
|
|
assert_equal(false, enccall(s1, :start_with?, s2), desc)
|
|
}
|
|
end
|
|
|
|
def test_str_ord
|
|
STRINGS.each {|s1|
|
|
if s1.empty?
|
|
assert_raise(ArgumentError) { s1.ord }
|
|
next
|
|
end
|
|
if !s1.valid_encoding?
|
|
assert_raise(ArgumentError) { s1.ord }
|
|
next
|
|
end
|
|
assert_equal(s1[0].ord, s1.ord)
|
|
}
|
|
end
|
|
|
|
def test_str_partition
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
desc = "#{encdump s1}.partition(#{encdump s2})"
|
|
if !str_enc_compatible?(s1, s2)
|
|
assert_raise(Encoding::CompatibilityError, desc) { s1.partition(s2) }
|
|
next
|
|
end
|
|
i = enccall(s1, :index, s2)
|
|
if !i
|
|
assert_equal([s1, "", ""], s1.partition(s2), desc)
|
|
next
|
|
end
|
|
assert_equal([s1[0,i], s2, s1[(i+s2.length)..-1]], s1.partition(s2), desc)
|
|
}
|
|
end
|
|
|
|
def test_str_rpartition
|
|
combination(STRINGS, STRINGS) {|s1, s2|
|
|
desc = "#{encdump s1}.rpartition(#{encdump s2})"
|
|
if !str_enc_compatible?(s1, s2)
|
|
assert_raise(Encoding::CompatibilityError, desc) { s1.rpartition(s2) }
|
|
next
|
|
end
|
|
i = enccall(s1, :rindex, s2)
|
|
if !i
|
|
assert_equal(["", "", s1], s1.rpartition(s2), desc)
|
|
next
|
|
end
|
|
assert_equal([s1[0,i], s2, s1[(i+s2.length)..-1]], s1.rpartition(s2), desc)
|
|
}
|
|
end
|
|
|
|
def test_bug11486
|
|
bug11486 = '[Bug #11486]'
|
|
assert_nil ("\u3042"*19+"\r"*19+"\u3042"*20+"\r"*20).encode(Encoding::EUC_JP).gsub!(/xxx/i, ""), bug11486
|
|
assert_match Regexp.new("ABC\uff41".encode(Encoding::EUC_JP), Regexp::IGNORECASE), "abc\uFF21".encode(Encoding::EUC_JP), bug11486
|
|
end
|
|
end
|