summaryrefslogtreecommitdiff
path: root/bootstraptest
diff options
context:
space:
mode:
authorNoah Gibbs <noah.gibbs@shopify.com>2022-06-10 18:52:43 +0100
committerGitHub <noreply@github.com>2022-06-10 13:52:43 -0400
commit9ed9cc9852a7cf12c71114c3c65b239c7af1518b (patch)
tree3aed5cc5ddcbcc7ed98aaf020d96559f001e406c /bootstraptest
parent46333f59d4266b8a2bc80a5e80cc394a1c7ad9c1 (diff)
downloadruby-9ed9cc9852a7cf12c71114c3c65b239c7af1518b.tar.gz
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
Diffstat (limited to 'bootstraptest')
-rw-r--r--bootstraptest/test_yjit.rb79
1 files changed, 77 insertions, 2 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 3ae0cdb33a..09bce6735b 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1354,7 +1354,7 @@ assert_equal 'meh', %q{
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{
class MyString < String
def to_s
@@ -1368,7 +1368,7 @@ assert_equal 'meh', %q{
OBJ = MyString.new
- # Should return 'meh' both times
+ # Should return '' both times
test_to_s("")
test_to_s("")
@@ -1421,6 +1421,81 @@ assert_equal 'false', %q{
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
assert_equal '123', %q{
def foo(obj)