From 9ed9cc9852a7cf12c71114c3c65b239c7af1518b Mon Sep 17 00:00:00 2001 From: Noah Gibbs Date: Fri, 10 Jun 2022 18:52:43 +0100 Subject: 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 --- bootstraptest/test_yjit.rb | 79 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) (limited to 'bootstraptest/test_yjit.rb') 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) -- cgit v1.2.3