mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Add tests for a variety of string-subclass operations (#5999)
This way YJIT has to match CRuby for each of them. Remove unused string_p() Rust function
This commit is contained in:
parent
46333f59d4
commit
9ed9cc9852
Notes:
git
2022-06-11 02:53:04 +09:00
Merged-By: maximecb <maximecb@ruby-lang.org>
2 changed files with 77 additions and 7 deletions
|
@ -1354,7 +1354,7 @@ assert_equal 'meh', %q{
|
||||||
inval_method
|
inval_method
|
||||||
}
|
}
|
||||||
|
|
||||||
# test that overriding to_s on a String subclass isn't over-optimised
|
# test that overriding to_s on a String subclass works consistently
|
||||||
assert_equal 'meh', %q{
|
assert_equal 'meh', %q{
|
||||||
class MyString < String
|
class MyString < String
|
||||||
def to_s
|
def to_s
|
||||||
|
@ -1368,7 +1368,7 @@ assert_equal 'meh', %q{
|
||||||
|
|
||||||
OBJ = MyString.new
|
OBJ = MyString.new
|
||||||
|
|
||||||
# Should return 'meh' both times
|
# Should return '' both times
|
||||||
test_to_s("")
|
test_to_s("")
|
||||||
test_to_s("")
|
test_to_s("")
|
||||||
|
|
||||||
|
@ -1421,6 +1421,81 @@ assert_equal 'false', %q{
|
||||||
uplus_str.frozen?
|
uplus_str.frozen?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# String-subclass objects should behave as expected inside string-interpolation via concatstrings
|
||||||
|
assert_equal 'monkeys, yo!', %q{
|
||||||
|
class MyString < String
|
||||||
|
# This is a terrible idea in production code, but we'd like YJIT to match CRuby
|
||||||
|
def to_s
|
||||||
|
super + ", yo!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
m = MyString.new('monkeys')
|
||||||
|
"#{m.to_s}"
|
||||||
|
|
||||||
|
raise "String-subclass to_s should not be called for interpolation" if "#{m}" != 'monkeys'
|
||||||
|
raise "String-subclass to_s should be called explicitly during interpolation" if "#{m.to_s}" != 'monkeys, yo!'
|
||||||
|
|
||||||
|
m.to_s
|
||||||
|
}
|
||||||
|
|
||||||
|
# String-subclass objects should behave as expected for string equality
|
||||||
|
assert_equal 'a', %q{
|
||||||
|
class MyString < String
|
||||||
|
# This is a terrible idea in production code, but we'd like YJIT to match CRuby
|
||||||
|
def ==(b)
|
||||||
|
"#{self}_" == b
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ma = MyString.new("a")
|
||||||
|
|
||||||
|
raise "Not dispatching to string-subclass equality!" if ma == "a" || ma != "a_"
|
||||||
|
raise "Incorrectly dispatching for String equality!" if "a_" == ma || "a" != ma
|
||||||
|
raise "Error in equality between string subclasses!" if ma != MyString.new("a_")
|
||||||
|
# opt_equality has an explicit "string always equals itself" test, but should never be used when == is redefined
|
||||||
|
raise "Error in reflexive equality!" if ma == ma
|
||||||
|
|
||||||
|
ma.to_s
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal '', %q{
|
||||||
|
class MyString < String; end
|
||||||
|
|
||||||
|
a = "a"
|
||||||
|
ma = MyString.new("a")
|
||||||
|
fma = MyString.new("a").freeze
|
||||||
|
|
||||||
|
# Test to_s on string subclass
|
||||||
|
raise "to_s should not duplicate a String!" if a.object_id != a.to_s.object_id
|
||||||
|
raise "to_s should duplicate a String subclass!" if ma.object_id == ma.to_s.object_id
|
||||||
|
|
||||||
|
# Test freeze, uminus and uplus on string subclass
|
||||||
|
raise "Freezing a string subclass should not duplicate it!" if fma.object_id != fma.freeze.object_id
|
||||||
|
raise "Unary minus on frozen string subclass should not duplicate it!" if fma.object_id != (-fma).object_id
|
||||||
|
raise "Unary minus on unfrozen string subclass should duplicate it!" if ma.object_id == (-ma).object_id
|
||||||
|
raise "Unary plus on unfrozen string subclass should not duplicate it!" if ma.object_id != (+ma).object_id
|
||||||
|
raise "Unary plus on frozen string subclass should duplicate it!" if fma.object_id == (+fma).object_id
|
||||||
|
|
||||||
|
''
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test << operator on string subclass
|
||||||
|
assert_equal 'abab', %q{
|
||||||
|
class MyString < String; end
|
||||||
|
|
||||||
|
a = -"a"
|
||||||
|
mb = MyString.new("b")
|
||||||
|
|
||||||
|
buf = String.new
|
||||||
|
mbuf = MyString.new
|
||||||
|
|
||||||
|
buf << a << mb
|
||||||
|
mbuf << a << mb
|
||||||
|
|
||||||
|
buf + mbuf
|
||||||
|
}
|
||||||
|
|
||||||
# test invokebuiltin as used in struct assignment
|
# test invokebuiltin as used in struct assignment
|
||||||
assert_equal '123', %q{
|
assert_equal '123', %q{
|
||||||
def foo(obj)
|
def foo(obj)
|
||||||
|
|
|
@ -461,11 +461,6 @@ impl VALUE {
|
||||||
self == Qnil
|
self == Qnil
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true or false depending whether the value is a string
|
|
||||||
pub fn string_p(self) -> bool {
|
|
||||||
unsafe { CLASS_OF(self) == rb_cString }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read the flags bits from the RBasic object, then return a Ruby type enum (e.g. RUBY_T_ARRAY)
|
/// Read the flags bits from the RBasic object, then return a Ruby type enum (e.g. RUBY_T_ARRAY)
|
||||||
pub fn builtin_type(self) -> ruby_value_type {
|
pub fn builtin_type(self) -> ruby_value_type {
|
||||||
assert!(!self.special_const_p());
|
assert!(!self.special_const_p());
|
||||||
|
|
Loading…
Add table
Reference in a new issue