From b0190f766370c354e1f9deb69c6b70cc26094ee0 Mon Sep 17 00:00:00 2001 From: Alexander Bulancov <6594487+trinistr@users.noreply.github.com> Date: Tue, 11 Nov 2025 23:54:04 +0300 Subject: [PATCH 1/2] Add tests for changes to String#+@ in 3.4 --- core/string/uplus_spec.rb | 44 ++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/core/string/uplus_spec.rb b/core/string/uplus_spec.rb index c0b0c49ede..20767bcc01 100644 --- a/core/string/uplus_spec.rb +++ b/core/string/uplus_spec.rb @@ -13,14 +13,48 @@ output.should == 'foobar' end - it 'returns self if the String is not frozen' do - input = 'foo' + it 'returns a mutable String itself' do + input = String.new("foo") output = +input - output.equal?(input).should == true + output.should.equal?(input) + + input << "bar" + output.should == "foobar" + end + + context 'if file has "frozen_string_literal: true" magic comment' do + it 'returns mutable copy of a literal' do + ruby_exe(fixture(__FILE__, "freeze_magic_comment.rb")).should == 'mutable' + end end - it 'returns mutable copy despite freeze-magic-comment in file' do - ruby_exe(fixture(__FILE__, "freeze_magic_comment.rb")).should == 'mutable' + context 'if file has "frozen_string_literal: false" magic comment' do + it 'returns literal string itself' do + input = 'foo' + output = +input + + output.equal?(input).should == true + end + end + + context 'if file has no frozen_string_literal magic comment' do + ruby_version_is ''...'3.4' do + it 'returns literal string itself' do + eval(<<~RUBY).should == true + s = "foo" + s.equal?(+s) + RUBY + end + end + + ruby_version_is '3.4' do + it 'returns mutable copy of a literal' do + eval(<<~RUBY).should == false + s = "foo" + s.equal?(+s) + RUBY + end + end end end From 80c71353c968b02879db00bb3636a157e1679873 Mon Sep 17 00:00:00 2001 From: Alexander Bulancov <6594487+trinistr@users.noreply.github.com> Date: Wed, 12 Nov 2025 00:23:39 +0300 Subject: [PATCH 2/2] Add test for warning about modifying chilled literal strings --- command_line/frozen_strings_spec.rb | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/command_line/frozen_strings_spec.rb b/command_line/frozen_strings_spec.rb index 014153e0b4..8acab5bc1d 100644 --- a/command_line/frozen_strings_spec.rb +++ b/command_line/frozen_strings_spec.rb @@ -42,8 +42,28 @@ ruby_exe(fixture(__FILE__, "freeze_flag_one_literal.rb")).chomp.should == "false" end - it "if file has no frozen_string_literal comment produce different mutable strings each time" do - ruby_exe(fixture(__FILE__, "string_literal_raw.rb")).chomp.should == "frozen:false interned:false" + context "if file has no frozen_string_literal comment" do + it "produce different mutable strings each time" do + ruby_exe(fixture(__FILE__, "string_literal_raw.rb")).chomp.should == "frozen:false interned:false" + end + + guard -> { ruby_version_is "3.4" and !"test".frozen? } do + it "complain about modification of produced mutable strings" do + -> { eval(<<~RUBY) }.should complain(/warning: literal string will be frozen in the future \(run with --debug-frozen-string-literal for more information\)/) + "test" << "!" + RUBY + end + + it "does not complain about modification if Warning[:deprecated] is false" do + deprecated = Warning[:deprecated] + Warning[:deprecated] = false + -> { eval(<<~RUBY) }.should_not complain + "test" << "!" + RUBY + ensure + Warning[:deprecated] = deprecated + end + end end it "if file has frozen_string_literal:true comment produce same frozen strings each time" do