From 29f358e0559465c86cadd3efb430afe7de77b72a Mon Sep 17 00:00:00 2001 From: Andrew Konchin Date: Mon, 1 Apr 2024 15:11:19 +0300 Subject: [PATCH] Update to ruby/spec@573cf97 --- spec/ruby/command_line/dash_v_spec.rb | 2 +- .../fixtures/string_literal_frozen_comment.rb | 4 ++ .../string_literal_mutable_comment.rb | 4 ++ .../fixtures/string_literal_raw.rb | 3 + spec/ruby/command_line/frozen_strings_spec.rb | 44 ++++++++++++ spec/ruby/command_line/rubyopt_spec.rb | 4 +- spec/ruby/core/class/subclasses_spec.rb | 29 +++++++- spec/ruby/core/exception/top_level_spec.rb | 33 +++++---- spec/ruby/core/kernel/eval_spec.rb | 19 ++--- spec/ruby/core/string/chilled_string_spec.rb | 69 +++++++++++++++++++ spec/ruby/language/ensure_spec.rb | 17 +++++ spec/ruby/language/rescue_spec.rb | 17 +++++ spec/ruby/language/string_spec.rb | 6 +- .../library/net-ftp/shared/puttextfile.rb | 4 +- spec/ruby/library/stringio/binmode_spec.rb | 2 +- spec/ruby/optional/capi/util_spec.rb | 2 +- spec/ruby/shared/kernel/object_id.rb | 14 +++- spec/ruby/shared/kernel/raise.rb | 7 +- 18 files changed, 241 insertions(+), 39 deletions(-) create mode 100644 spec/ruby/command_line/fixtures/string_literal_frozen_comment.rb create mode 100644 spec/ruby/command_line/fixtures/string_literal_mutable_comment.rb create mode 100644 spec/ruby/command_line/fixtures/string_literal_raw.rb create mode 100644 spec/ruby/core/string/chilled_string_spec.rb diff --git a/spec/ruby/command_line/dash_v_spec.rb b/spec/ruby/command_line/dash_v_spec.rb index 15569fa6423b..747db7f75588 100644 --- a/spec/ruby/command_line/dash_v_spec.rb +++ b/spec/ruby/command_line/dash_v_spec.rb @@ -6,7 +6,7 @@ describe "when used alone" do it "prints version and ends" do - ruby_exe(nil, args: '-v').sub("+PRISM ", "").should include(RUBY_DESCRIPTION) + ruby_exe(nil, args: '-v').sub("+PRISM ", "").should include(RUBY_DESCRIPTION.sub("+PRISM ", "")) end unless (defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?) || (defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?) || (ENV['RUBY_MN_THREADS'] == '1') diff --git a/spec/ruby/command_line/fixtures/string_literal_frozen_comment.rb b/spec/ruby/command_line/fixtures/string_literal_frozen_comment.rb new file mode 100644 index 000000000000..fb84b546c0a7 --- /dev/null +++ b/spec/ruby/command_line/fixtures/string_literal_frozen_comment.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true +frozen = "test".frozen? +interned = "test".equal?("test") +puts "frozen:#{frozen} interned:#{interned}" diff --git a/spec/ruby/command_line/fixtures/string_literal_mutable_comment.rb b/spec/ruby/command_line/fixtures/string_literal_mutable_comment.rb new file mode 100644 index 000000000000..381a74200171 --- /dev/null +++ b/spec/ruby/command_line/fixtures/string_literal_mutable_comment.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: false +frozen = "test".frozen? +interned = "test".equal?("test") +puts "frozen:#{frozen} interned:#{interned}" diff --git a/spec/ruby/command_line/fixtures/string_literal_raw.rb b/spec/ruby/command_line/fixtures/string_literal_raw.rb new file mode 100644 index 000000000000..56b1841296b5 --- /dev/null +++ b/spec/ruby/command_line/fixtures/string_literal_raw.rb @@ -0,0 +1,3 @@ +frozen = "test".frozen? +interned = "test".equal?("test") +puts "frozen:#{frozen} interned:#{interned}" diff --git a/spec/ruby/command_line/frozen_strings_spec.rb b/spec/ruby/command_line/frozen_strings_spec.rb index 647b69daed19..334b98273b78 100644 --- a/spec/ruby/command_line/frozen_strings_spec.rb +++ b/spec/ruby/command_line/frozen_strings_spec.rb @@ -19,6 +19,50 @@ end end +describe "The --disable-frozen-string-literal flag causes string literals to" do + + it "produce a different object each time" do + ruby_exe(fixture(__FILE__, "freeze_flag_one_literal.rb"), options: "--disable-frozen-string-literal").chomp.should == "false" + end + +end + +describe "With neither --enable-frozen-string-literal nor --disable-frozen-string-literal flag set" do + before do + # disable --enable-frozen-string-literal and --disable-frozen-string-literal passed in $RUBYOPT + @rubyopt = ENV["RUBYOPT"] + ENV["RUBYOPT"] = "" + end + + after do + ENV["RUBYOPT"] = @rubyopt + end + + it "produce a different object each time" do + ruby_exe(fixture(__FILE__, "freeze_flag_one_literal.rb")).chomp.should == "false" + end + + ruby_version_is "3.4" do + it "if file has no frozen_string_literal comment produce different frozen strings each time" do + ruby_exe(fixture(__FILE__, "string_literal_raw.rb")).chomp.should == "frozen:true interned:false" + end + end + + ruby_version_is ""..."3.4" do + 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" + end + end + + it "if file has frozen_string_literal:true comment produce same frozen strings each time" do + ruby_exe(fixture(__FILE__, "string_literal_frozen_comment.rb")).chomp.should == "frozen:true interned:true" + end + + it "if file has frozen_string_literal:false comment produce different mutable strings each time" do + ruby_exe(fixture(__FILE__, "string_literal_mutable_comment.rb")).chomp.should == "frozen:false interned:false" + end +end + describe "The --debug flag produces" do it "debugging info on attempted frozen string modification" do error_str = ruby_exe(fixture(__FILE__, 'debug_info.rb'), options: '--debug', args: "2>&1") diff --git a/spec/ruby/command_line/rubyopt_spec.rb b/spec/ruby/command_line/rubyopt_spec.rb index 734db8d519e2..18a5959b18cd 100644 --- a/spec/ruby/command_line/rubyopt_spec.rb +++ b/spec/ruby/command_line/rubyopt_spec.rb @@ -25,12 +25,12 @@ guard -> { not CROSS_COMPILING } do it "prints the version number for '-v'" do ENV["RUBYOPT"] = '-v' - ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION + ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "") end it "ignores whitespace around the option" do ENV["RUBYOPT"] = ' -v ' - ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION + ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION.sub("+PRISM ", "") end end diff --git a/spec/ruby/core/class/subclasses_spec.rb b/spec/ruby/core/class/subclasses_spec.rb index a16b934d4fc5..50eb5358d974 100644 --- a/spec/ruby/core/class/subclasses_spec.rb +++ b/spec/ruby/core/class/subclasses_spec.rb @@ -7,7 +7,7 @@ assert_subclasses(ModuleSpecs::Parent, [ModuleSpecs::Child, ModuleSpecs::Child2]) end - it "does not return included modules" do + it "does not return included modules from the parent" do parent = Class.new child = Class.new(parent) mod = Module.new @@ -16,6 +16,33 @@ assert_subclasses(parent, [child]) end + it "does not return included modules from the child" do + parent = Class.new + child = Class.new(parent) + mod = Module.new + parent.include(mod) + + assert_subclasses(parent, [child]) + end + + it "does not return prepended modules from the parent" do + parent = Class.new + child = Class.new(parent) + mod = Module.new + parent.prepend(mod) + + assert_subclasses(parent, [child]) + end + + it "does not return prepended modules from the child" do + parent = Class.new + child = Class.new(parent) + mod = Module.new + child.prepend(mod) + + assert_subclasses(parent, [child]) + end + it "does not return singleton classes" do a = Class.new diff --git a/spec/ruby/core/exception/top_level_spec.rb b/spec/ruby/core/exception/top_level_spec.rb index b8708054ff0c..cc961d06d565 100644 --- a/spec/ruby/core/exception/top_level_spec.rb +++ b/spec/ruby/core/exception/top_level_spec.rb @@ -8,29 +8,32 @@ it "the Exception#cause is printed to STDERR with backtraces" do code = <<-RUBY def raise_cause - raise "the cause" + raise "the cause" # 2 end def raise_wrapped - raise "wrapped" + raise "wrapped" # 5 end begin - raise_cause + raise_cause # 8 rescue - raise_wrapped + raise_wrapped # 10 end RUBY lines = ruby_exe(code, args: "2>&1", exit_status: 1).lines - lines.map! { |l| l.chomp[/:(in.+)/, 1] } - expected = [ - /\Ain [`'](?:Object#)?raise_wrapped': wrapped \(RuntimeError\)\z/, - # https://bugs.ruby-lang.org/issues/20275 - *(/\Ain [`'](?:rescue in )?
'\z/ if RUBY_ENGINE == 'ruby'), - /\Ain [`']
'\z/, - /\Ain [`'](?:Object#)?raise_cause': the cause \(RuntimeError\)\z/, - /\Ain [`']
'\z/, - ] - lines.size.should == expected.size - lines.zip(expected) { |l,e| l.should =~ e } + + lines.map! { |l| l.chomp[/:(\d+:in.+)/, 1] } + lines[0].should =~ /\A5:in [`'](?:Object#)?raise_wrapped': wrapped \(RuntimeError\)\z/ + if lines[1].include? 'rescue in' + # CRuby < 3.4 has an extra 'rescue in' backtrace entry + lines[1].should =~ /\A10:in [`']rescue in
'\z/ + lines.delete_at 1 + lines[1].should =~ /\A7:in [`']
'\z/ + else + lines[1].should =~ /\A10:in [`']
'\z/ + end + lines[2].should =~ /\A2:in [`'](?:Object#)?raise_cause': the cause \(RuntimeError\)\z/ + lines[3].should =~ /\A8:in [`']
'\z/ + lines.size.should == 4 end describe "with a custom backtrace" do diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb index eab8b72feb41..454bc4a58e5c 100644 --- a/spec/ruby/core/kernel/eval_spec.rb +++ b/spec/ruby/core/kernel/eval_spec.rb @@ -350,9 +350,11 @@ class EvalSpecs end it "allows a magic encoding comment and a subsequent frozen_string_literal magic comment" do + frozen_string_default = "test".frozen? + code = < { eval(code) }.should complain(/warning: [`']frozen_string_literal' is ignored after any tokens/, verbose: true) - EvalSpecs::Vπstring_not_frozen.frozen?.should == default_frozen_string_literal + EvalSpecs::Vπstring_not_frozen.frozen?.should == frozen_string_default EvalSpecs.send :remove_const, :Vπstring_not_frozen -> { eval(code) }.should_not complain(verbose: false) - EvalSpecs::Vπstring_not_frozen.frozen?.should == default_frozen_string_literal + EvalSpecs::Vπstring_not_frozen.frozen?.should == frozen_string_default EvalSpecs.send :remove_const, :Vπstring_not_frozen end end diff --git a/spec/ruby/core/string/chilled_string_spec.rb b/spec/ruby/core/string/chilled_string_spec.rb new file mode 100644 index 000000000000..8de4fc421b47 --- /dev/null +++ b/spec/ruby/core/string/chilled_string_spec.rb @@ -0,0 +1,69 @@ +require_relative '../../spec_helper' + +describe "chilled String" do + guard -> { ruby_version_is "3.4" and !"test".equal?("test") } do + describe "#frozen?" do + it "returns true" do + "chilled".frozen?.should == true + end + end + + describe "#-@" do + it "returns a different instance" do + input = "chilled" + interned = (-input) + interned.frozen?.should == true + interned.object_id.should_not == input.object_id + end + end + + describe "#+@" do + it "returns a different instance" do + input = "chilled" + duped = (+input) + duped.frozen?.should == false + duped.object_id.should_not == input.object_id + end + end + + describe "#clone" do + it "preserves chilled status" do + input = "chilled".clone + -> { + input << "-mutated" + }.should complain(/literal string will be frozen in the future/) + input.should == "chilled-mutated" + end + end + + describe "mutation" do + it "emits a warning" do + input = "chilled" + -> { + input << "-mutated" + }.should complain(/literal string will be frozen in the future/) + input.should == "chilled-mutated" + end + + it "emits a warning on singleton_class creaation" do + -> { + "chilled".singleton_class + }.should complain(/literal string will be frozen in the future/) + end + + it "emits a warning on instance variable assignment" do + -> { + "chilled".instance_variable_set(:@ivar, 42) + }.should complain(/literal string will be frozen in the future/) + end + + it "raises FrozenError after the string was explictly frozen" do + input = "chilled" + input.freeze + -> { + input << "mutated" + }.should raise_error(FrozenError) + end + end + end +end diff --git a/spec/ruby/language/ensure_spec.rb b/spec/ruby/language/ensure_spec.rb index e893904bcb16..16e626b4d0be 100644 --- a/spec/ruby/language/ensure_spec.rb +++ b/spec/ruby/language/ensure_spec.rb @@ -328,4 +328,21 @@ class EnsureInClassExample result.should == :begin end + + ruby_version_is "3.4" do + it "does not introduce extra backtrace entries" do + def foo + begin + raise "oops" + ensure + return caller(0, 2) # rubocop:disable Lint/EnsureReturn + end + end + line = __LINE__ + foo.should == [ + "#{__FILE__}:#{line-3}:in 'foo'", + "#{__FILE__}:#{line+1}:in 'block (3 levels) in '" + ] + end + end end diff --git a/spec/ruby/language/rescue_spec.rb b/spec/ruby/language/rescue_spec.rb index d6e7b6c80246..a3ee4807acd0 100644 --- a/spec/ruby/language/rescue_spec.rb +++ b/spec/ruby/language/rescue_spec.rb @@ -553,6 +553,23 @@ class RescueInClassExample eval('1.+((1 rescue 1))').should == 2 end + ruby_version_is "3.4" do + it "does not introduce extra backtrace entries" do + def foo + begin + raise "oops" + rescue + return caller(0, 2) + end + end + line = __LINE__ + foo.should == [ + "#{__FILE__}:#{line-3}:in 'foo'", + "#{__FILE__}:#{line+1}:in 'block (3 levels) in '" + ] + end + end + describe "inline form" do it "can be inlined" do a = 1/0 rescue 1 diff --git a/spec/ruby/language/string_spec.rb b/spec/ruby/language/string_spec.rb index e4aa0308449a..083a7f5db50d 100644 --- a/spec/ruby/language/string_spec.rb +++ b/spec/ruby/language/string_spec.rb @@ -231,16 +231,14 @@ def long_string_literals ruby_exe(fixture(__FILE__, "freeze_magic_comment_across_files.rb")).chomp.should == "true" end - guard -> { !eval("'test'").frozen? } do + guard -> { !(eval("'test'").frozen? && "test".equal?("test")) } do it "produces different objects for literals with the same content in different files if the other file doesn't have the comment and String literals aren't frozen by default" do - frozen_literals_by_default = eval("'test'").frozen? ruby_exe(fixture(__FILE__, "freeze_magic_comment_across_files_no_comment.rb")).chomp.should == "true" end end - guard -> { eval("'test'").frozen? } do + guard -> { eval("'test'").frozen? && "test".equal?("test") } do it "produces the same objects for literals with the same content in different files if the other file doesn't have the comment and String literals are frozen by default" do - frozen_literals_by_default = eval("'test'").frozen? ruby_exe(fixture(__FILE__, "freeze_magic_comment_across_files_no_comment.rb")).chomp.should == "false" end end diff --git a/spec/ruby/library/net-ftp/shared/puttextfile.rb b/spec/ruby/library/net-ftp/shared/puttextfile.rb index 3836e954b807..4722439674af 100644 --- a/spec/ruby/library/net-ftp/shared/puttextfile.rb +++ b/spec/ruby/library/net-ftp/shared/puttextfile.rb @@ -27,8 +27,8 @@ it "sends the contents of the passed local_file, using \\r\\n as the newline separator" do @ftp.send(@method, @local_fixture_file, "text") - remote_lines = open(@remote_tmp_file, "rb") {|f| f.read } - local_lines = open(@local_fixture_file, "rb") {|f| f.read } + remote_lines = File.binread(@remote_tmp_file) + local_lines = File.binread(@local_fixture_file) remote_lines.should_not == local_lines remote_lines.should == local_lines.gsub("\n", "\r\n") diff --git a/spec/ruby/library/stringio/binmode_spec.rb b/spec/ruby/library/stringio/binmode_spec.rb index 853d9c9bd665..9e92c63814e8 100644 --- a/spec/ruby/library/stringio/binmode_spec.rb +++ b/spec/ruby/library/stringio/binmode_spec.rb @@ -3,7 +3,7 @@ describe "StringIO#binmode" do it "returns self" do - io = StringIO.new("example") + io = StringIO.new(+"example") io.binmode.should equal(io) end diff --git a/spec/ruby/optional/capi/util_spec.rb b/spec/ruby/optional/capi/util_spec.rb index 2c16999cdc35..9ff8b4760a83 100644 --- a/spec/ruby/optional/capi/util_spec.rb +++ b/spec/ruby/optional/capi/util_spec.rb @@ -48,7 +48,7 @@ ScratchPad.recorded.should == [1, 2, [3, 4]] end - it "assigns the required and optional arguments and and empty Array when there are no arguments to splat" do + it "assigns the required and optional arguments and empty Array when there are no arguments to splat" do @o.rb_scan_args([1, 2], "11*", 3, @acc).should == 2 ScratchPad.recorded.should == [1, 2, []] end diff --git a/spec/ruby/shared/kernel/object_id.rb b/spec/ruby/shared/kernel/object_id.rb index 3e032102f18b..099df8ff94c4 100644 --- a/spec/ruby/shared/kernel/object_id.rb +++ b/spec/ruby/shared/kernel/object_id.rb @@ -52,7 +52,7 @@ o1.send(@method).should_not == o2.send(@method) end - guard -> { "test".frozen? } do # --enable-frozen-string-literal in $RUBYOPT + guard -> { "test".frozen? && "test".equal?("test") } do # --enable-frozen-string-literal in $RUBYOPT it "returns the same value for two identical String literals" do o1 = "hello" o2 = "hello" @@ -60,7 +60,17 @@ end end - guard_not -> { "test".frozen? } do + guard -> { "test".frozen? && !"test".equal?("test") } do # chilled string literals + it "returns a different frozen value for two String literals" do + o1 = "hello" + o2 = "hello" + o1.send(@method).should_not == o2.send(@method) + o1.frozen?.should == true + o2.frozen?.should == true + end + end + + guard -> { !"test".frozen? } do it "returns a different value for two String literals" do o1 = "hello" o2 = "hello" diff --git a/spec/ruby/shared/kernel/raise.rb b/spec/ruby/shared/kernel/raise.rb index 4b60951f241a..1917a4c92387 100644 --- a/spec/ruby/shared/kernel/raise.rb +++ b/spec/ruby/shared/kernel/raise.rb @@ -148,10 +148,13 @@ def initialize end ruby_version_is "3.4" do + locations = caller_locations(1, 2) it "allows Exception, message, and backtrace_locations parameters" do -> do - @object.raise(ArgumentError, "message", caller_locations) - end.should raise_error(ArgumentError, "message") + @object.raise(ArgumentError, "message", locations) + end.should raise_error(ArgumentError, "message") { |error| + error.backtrace_locations.map(&:to_s).should == locations.map(&:to_s) + } end end end