From c75df796d875b02d7b97974c7fe840f0a9de171f Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 28 Oct 2021 18:54:01 +0200 Subject: Update to ruby/spec@21a48d9 --- spec/ruby/command_line/backtrace_limit_spec.rb | 4 +- spec/ruby/command_line/dash_upper_w_spec.rb | 33 +++++----- spec/ruby/command_line/dash_w_spec.rb | 6 ++ spec/ruby/command_line/fixtures/backtrace.rb | 2 +- spec/ruby/core/array/shared/join.rb | 1 + spec/ruby/core/enumerable/grep_spec.rb | 6 ++ spec/ruby/core/enumerable/grep_v_spec.rb | 6 ++ spec/ruby/core/fiber/blocking_spec.rb | 62 +++++++++++++++++++ spec/ruby/core/fiber/shared/blocking.rb | 41 +++++++++++++ spec/ruby/core/gc/auto_compact_spec.rb | 19 ++++++ spec/ruby/core/io/nonblock_spec.rb | 70 ++++++++++++++++++++++ spec/ruby/core/kernel/lambda_spec.rb | 12 ++++ spec/ruby/core/kernel/open_spec.rb | 12 ++++ spec/ruby/core/module/deprecate_constant_spec.rb | 25 ++++++-- spec/ruby/core/module/private_class_method_spec.rb | 12 ++++ spec/ruby/core/module/public_class_method_spec.rb | 16 +++++ spec/ruby/core/random/default_spec.rb | 1 - spec/ruby/core/string/encode_spec.rb | 50 ++++++++++++++-- spec/ruby/core/symbol/to_proc_spec.rb | 4 +- spec/ruby/core/thread/ignore_deadlock_spec.rb | 21 +++++++ spec/ruby/core/warning/element_reference_spec.rb | 10 ++-- spec/ruby/language/class_variable_spec.rb | 26 ++++++++ spec/ruby/language/numbered_parameters_spec.rb | 14 +++++ spec/ruby/language/safe_spec.rb | 10 ++++ spec/ruby/language/variables_spec.rb | 29 +++++++++ 25 files changed, 454 insertions(+), 38 deletions(-) create mode 100644 spec/ruby/core/fiber/blocking_spec.rb create mode 100644 spec/ruby/core/fiber/shared/blocking.rb create mode 100644 spec/ruby/core/gc/auto_compact_spec.rb create mode 100644 spec/ruby/core/io/nonblock_spec.rb create mode 100644 spec/ruby/core/thread/ignore_deadlock_spec.rb diff --git a/spec/ruby/command_line/backtrace_limit_spec.rb b/spec/ruby/command_line/backtrace_limit_spec.rb index c0b243841e..56afa8efef 100644 --- a/spec/ruby/command_line/backtrace_limit_spec.rb +++ b/spec/ruby/command_line/backtrace_limit_spec.rb @@ -9,7 +9,7 @@ ruby_version_is "3.0" do out.should == <<-MSG top -/fixtures/backtrace.rb:2:in `a': unhandled exception +/fixtures/backtrace.rb:2:in `a': oops (RuntimeError) \tfrom /fixtures/backtrace.rb:6:in `b' \tfrom /fixtures/backtrace.rb:10:in `c' \t ... 2 levels... @@ -23,7 +23,7 @@ top out.should == <<-MSG full_message -/fixtures/backtrace.rb:2:in `a': unhandled exception +/fixtures/backtrace.rb:2:in `a': oops (RuntimeError) \tfrom /fixtures/backtrace.rb:6:in `b' \tfrom /fixtures/backtrace.rb:10:in `c' \t ... 2 levels... diff --git a/spec/ruby/command_line/dash_upper_w_spec.rb b/spec/ruby/command_line/dash_upper_w_spec.rb index 1b36a1cc22..cbb040a8dd 100644 --- a/spec/ruby/command_line/dash_upper_w_spec.rb +++ b/spec/ruby/command_line/dash_upper_w_spec.rb @@ -19,34 +19,29 @@ describe "The -W command line option with 2" do it_behaves_like :command_line_verbose, "-W2" end +# Regarding the defaults, see core/warning/element_reference_spec.rb ruby_version_is "2.7" do + describe "The -W command line option with :deprecated" do + it "enables deprecation warnings" do + ruby_exe('p Warning[:deprecated]', options: '-W:deprecated').should == "true\n" + end + end + describe "The -W command line option with :no-deprecated" do it "suppresses deprecation warnings" do - result = ruby_exe('$; = ""', options: '-w', args: '2>&1') - result.should =~ /is deprecated/ - - result = ruby_exe('$; = ""', options: '-w -W:no-deprecated', args: '2>&1') - result.should == "" + ruby_exe('p Warning[:deprecated]', options: '-w -W:no-deprecated').should == "false\n" end end - describe "The -W command line option with :no-experimental" do - before do - ruby_version_is ""..."3.0" do - @src = 'case [0, 1]; in [a, b]; end' - end - - ruby_version_is "3.0" do - @src = 'warn "This is experimental warning.", category: :experimental' - end + describe "The -W command line option with :experimental" do + it "enables experimental warnings" do + ruby_exe('p Warning[:experimental]', options: '-W:experimental').should == "true\n" end + end + describe "The -W command line option with :no-experimental" do it "suppresses experimental warnings" do - result = ruby_exe(@src, args: '2>&1') - result.should =~ /is experimental/ - - result = ruby_exe(@src, options: '-W:no-experimental', args: '2>&1') - result.should == "" + ruby_exe('p Warning[:experimental]', options: '-w -W:no-experimental').should == "false\n" end end end diff --git a/spec/ruby/command_line/dash_w_spec.rb b/spec/ruby/command_line/dash_w_spec.rb index 1d93e0347b..c262df12cc 100644 --- a/spec/ruby/command_line/dash_w_spec.rb +++ b/spec/ruby/command_line/dash_w_spec.rb @@ -3,4 +3,10 @@ require_relative 'shared/verbose' describe "The -w command line option" do it_behaves_like :command_line_verbose, "-w" + + ruby_version_is "2.7" do + it "enables both deprecated and experimental warnings" do + ruby_exe('p Warning[:deprecated]; p Warning[:experimental]', options: '-w').should == "true\ntrue\n" + end + end end diff --git a/spec/ruby/command_line/fixtures/backtrace.rb b/spec/ruby/command_line/fixtures/backtrace.rb index 19ad638d35..99acae95c8 100644 --- a/spec/ruby/command_line/fixtures/backtrace.rb +++ b/spec/ruby/command_line/fixtures/backtrace.rb @@ -1,5 +1,5 @@ def a - raise + raise 'oops' end def b diff --git a/spec/ruby/core/array/shared/join.rb b/spec/ruby/core/array/shared/join.rb index c443d9a628..dfdb4ae1e4 100644 --- a/spec/ruby/core/array/shared/join.rb +++ b/spec/ruby/core/array/shared/join.rb @@ -124,6 +124,7 @@ describe :array_join_with_default_separator, shared: true do it "warns" do -> { [].join }.should complain(/warning: \$, is set to non-nil value/) + -> { [].join(nil) }.should complain(/warning: \$, is set to non-nil value/) end end end diff --git a/spec/ruby/core/enumerable/grep_spec.rb b/spec/ruby/core/enumerable/grep_spec.rb index 4e66bb85ea..ac3d3db641 100644 --- a/spec/ruby/core/enumerable/grep_spec.rb +++ b/spec/ruby/core/enumerable/grep_spec.rb @@ -59,6 +59,12 @@ describe "Enumerable#grep" do ["abc", "def"].grep(/b/).should == ["abc"] $&.should == "z" end + + it "does not modify Regexp.last_match without block" do + "z" =~ /z/ # Reset last match + ["abc", "def"].grep(/b/).should == ["abc"] + Regexp.last_match[0].should == "z" + end end describe "with a block" do diff --git a/spec/ruby/core/enumerable/grep_v_spec.rb b/spec/ruby/core/enumerable/grep_v_spec.rb index 8cae3ac618..892640efa4 100644 --- a/spec/ruby/core/enumerable/grep_v_spec.rb +++ b/spec/ruby/core/enumerable/grep_v_spec.rb @@ -39,6 +39,12 @@ describe "Enumerable#grep_v" do ["abc", "def"].grep_v(/e/).should == ["abc"] $&.should == "z" end + + it "does not modify Regexp.last_match without block" do + "z" =~ /z/ # Reset last match + ["abc", "def"].grep_v(/e/).should == ["abc"] + Regexp.last_match[0].should == "z" + end end describe "without block" do diff --git a/spec/ruby/core/fiber/blocking_spec.rb b/spec/ruby/core/fiber/blocking_spec.rb new file mode 100644 index 0000000000..5ae5fbd577 --- /dev/null +++ b/spec/ruby/core/fiber/blocking_spec.rb @@ -0,0 +1,62 @@ +require_relative '../../spec_helper' +require_relative 'shared/blocking' + +ruby_version_is "3.0" do + require "fiber" + + describe "Fiber.blocking?" do + it_behaves_like :non_blocking_fiber, -> { Fiber.blocking? } + + context "when fiber is blocking" do + context "root Fiber of the main thread" do + it "returns 1 for blocking: true" do + fiber = Fiber.new(blocking: true) { Fiber.blocking? } + blocking = fiber.resume + + blocking.should == 1 + end + end + + context "root Fiber of a new thread" do + it "returns 1 for blocking: true" do + thread = Thread.new do + fiber = Fiber.new(blocking: true) { Fiber.blocking? } + blocking = fiber.resume + + blocking.should == 1 + end + + thread.join + end + end + end + end + + describe "Fiber#blocking?" do + it_behaves_like :non_blocking_fiber, -> { Fiber.current.blocking? } + + context "when fiber is blocking" do + context "root Fiber of the main thread" do + it "returns true for blocking: true" do + fiber = Fiber.new(blocking: true) { Fiber.current.blocking? } + blocking = fiber.resume + + blocking.should == true + end + end + + context "root Fiber of a new thread" do + it "returns true for blocking: true" do + thread = Thread.new do + fiber = Fiber.new(blocking: true) { Fiber.current.blocking? } + blocking = fiber.resume + + blocking.should == true + end + + thread.join + end + end + end + end +end diff --git a/spec/ruby/core/fiber/shared/blocking.rb b/spec/ruby/core/fiber/shared/blocking.rb new file mode 100644 index 0000000000..21707e1ea7 --- /dev/null +++ b/spec/ruby/core/fiber/shared/blocking.rb @@ -0,0 +1,41 @@ +describe :non_blocking_fiber, shared: true do + context "root Fiber of the main thread" do + it "returns false" do + fiber = Fiber.new { @method.call } + blocking = fiber.resume + + blocking.should == false + end + + it "returns false for blocking: false" do + fiber = Fiber.new(blocking: false) { @method.call } + blocking = fiber.resume + + blocking.should == false + end + end + + context "root Fiber of a new thread" do + it "returns false" do + thread = Thread.new do + fiber = Fiber.new { @method.call } + blocking = fiber.resume + + blocking.should == false + end + + thread.join + end + + it "returns false for blocking: false" do + thread = Thread.new do + fiber = Fiber.new(blocking: false) { @method.call } + blocking = fiber.resume + + blocking.should == false + end + + thread.join + end + end +end diff --git a/spec/ruby/core/gc/auto_compact_spec.rb b/spec/ruby/core/gc/auto_compact_spec.rb new file mode 100644 index 0000000000..d77ed44452 --- /dev/null +++ b/spec/ruby/core/gc/auto_compact_spec.rb @@ -0,0 +1,19 @@ +require_relative '../../spec_helper' + +ruby_version_is "3.0" do + describe "GC.auto_compact" do + before :each do + @default = GC.auto_compact + end + + after :each do + GC.auto_compact = @default + end + + it "can set and get a boolean value" do + original = GC.auto_compact + GC.auto_compact = !original + GC.auto_compact.should == !original + end + end +end diff --git a/spec/ruby/core/io/nonblock_spec.rb b/spec/ruby/core/io/nonblock_spec.rb new file mode 100644 index 0000000000..e81ac10c58 --- /dev/null +++ b/spec/ruby/core/io/nonblock_spec.rb @@ -0,0 +1,70 @@ +require_relative '../../spec_helper' + +platform_is_not :windows do + describe "IO#nonblock?" do + before :all do + require 'io/nonblock' + end + + it "returns false for a file by default" do + File.open(__FILE__) do |f| + f.nonblock?.should == false + end + end + + ruby_version_is ""..."3.0" do + it "returns false for pipe by default" do + r, w = IO.pipe + begin + r.nonblock?.should == false + w.nonblock?.should == false + ensure + r.close + w.close + end + end + + it "returns false for socket by default" do + require 'socket' + TCPServer.open(0) do |socket| + socket.nonblock?.should == false + end + end + end + + ruby_version_is "3.0" do + it "returns true for pipe by default" do + r, w = IO.pipe + begin + r.nonblock?.should == true + w.nonblock?.should == true + ensure + r.close + w.close + end + end + + it "returns true for socket by default" do + require 'socket' + TCPServer.open(0) do |socket| + socket.nonblock?.should == true + end + end + end + end + + describe "IO#nonblock=" do + before :all do + require 'io/nonblock' + end + + it "changes the IO to non-blocking mode" do + File.open(__FILE__) do |f| + f.nonblock = true + f.nonblock?.should == true + f.nonblock = false + f.nonblock?.should == false + end + end + end +end diff --git a/spec/ruby/core/kernel/lambda_spec.rb b/spec/ruby/core/kernel/lambda_spec.rb index 9a960f3589..2aa4d4f2fb 100644 --- a/spec/ruby/core/kernel/lambda_spec.rb +++ b/spec/ruby/core/kernel/lambda_spec.rb @@ -135,4 +135,16 @@ describe "Kernel.lambda" do klass.new.lambda { 42 }.should be_an_instance_of Proc klass.new.ret.should == 1 end + + ruby_version_is "3.0" do + context "when called without a literal block" do + it "warns when proc isn't a lambda" do + -> { lambda(&proc{}) }.should complain("#{__FILE__}:#{__LINE__}: warning: lambda without a literal block is deprecated; use the proc without lambda instead\n") + end + + it "doesn't warn when proc is lambda" do + -> { lambda(&lambda{}) }.should_not complain(verbose: true) + end + end + end end diff --git a/spec/ruby/core/kernel/open_spec.rb b/spec/ruby/core/kernel/open_spec.rb index 8d936d8ca0..569f2f6a7f 100644 --- a/spec/ruby/core/kernel/open_spec.rb +++ b/spec/ruby/core/kernel/open_spec.rb @@ -148,6 +148,18 @@ describe "Kernel#open" do ruby_exe(code, args: "2>&1").should == "true\n" end end + + ruby_version_is "3.0" do + it "is not redefined by open-uri" do + code = <<~RUBY + before = Kernel.instance_method(:open) + require 'open-uri' + after = Kernel.instance_method(:open) + p before == after + RUBY + ruby_exe(code, args: "2>&1").should == "true\n" + end + end end describe "Kernel.open" do diff --git a/spec/ruby/core/module/deprecate_constant_spec.rb b/spec/ruby/core/module/deprecate_constant_spec.rb index 7bcced981b..faacbea03e 100644 --- a/spec/ruby/core/module/deprecate_constant_spec.rb +++ b/spec/ruby/core/module/deprecate_constant_spec.rb @@ -9,7 +9,6 @@ describe "Module#deprecate_constant" do @module::PRIVATE = @value @module.private_constant :PRIVATE @module.deprecate_constant :PRIVATE - @pattern = /deprecated/ end describe "when accessing the deprecated module" do @@ -19,7 +18,7 @@ describe "Module#deprecate_constant" do value = nil -> { value = @module::PUBLIC1 - }.should complain(@pattern) + }.should complain(/warning: constant .+::PUBLIC1 is deprecated/) value.should equal(@value) -> { @module::PRIVATE }.should raise_error(NameError) @@ -28,16 +27,30 @@ describe "Module#deprecate_constant" do it "warns with a message" do @module.deprecate_constant :PUBLIC1 - -> { @module::PUBLIC1 }.should complain(@pattern) - -> { @module.const_get :PRIVATE }.should complain(@pattern) + -> { @module::PUBLIC1 }.should complain(/warning: constant .+::PUBLIC1 is deprecated/) + -> { @module.const_get :PRIVATE }.should complain(/warning: constant .+::PRIVATE is deprecated/) + end + + ruby_version_is '2.7' do + it "does not warn if Warning[:deprecated] is false" do + @module.deprecate_constant :PUBLIC1 + + deprecated = Warning[:deprecated] + begin + Warning[:deprecated] = false + -> { @module::PUBLIC1 }.should_not complain + ensure + Warning[:deprecated] = deprecated + end + end end end it "accepts multiple symbols and strings as constant names" do @module.deprecate_constant "PUBLIC1", :PUBLIC2 - -> { @module::PUBLIC1 }.should complain(@pattern) - -> { @module::PUBLIC2 }.should complain(@pattern) + -> { @module::PUBLIC1 }.should complain(/warning: constant .+::PUBLIC1 is deprecated/) + -> { @module::PUBLIC2 }.should complain(/warning: constant .+::PUBLIC2 is deprecated/) end it "returns self" do diff --git a/spec/ruby/core/module/private_class_method_spec.rb b/spec/ruby/core/module/private_class_method_spec.rb index e35b50d986..407779cccc 100644 --- a/spec/ruby/core/module/private_class_method_spec.rb +++ b/spec/ruby/core/module/private_class_method_spec.rb @@ -78,4 +78,16 @@ describe "Module#private_class_method" do end end.should raise_error(NameError) end + + ruby_version_is "3.0" do + context "when single argument is passed and is an array" do + it "sets the visibility of the given methods to private" do + c = Class.new do + def self.foo() "foo" end + private_class_method [:foo] + end + -> { c.foo }.should raise_error(NoMethodError) + end + end + end end diff --git a/spec/ruby/core/module/public_class_method_spec.rb b/spec/ruby/core/module/public_class_method_spec.rb index c09cc64863..b5d76e7b7a 100644 --- a/spec/ruby/core/module/public_class_method_spec.rb +++ b/spec/ruby/core/module/public_class_method_spec.rb @@ -77,4 +77,20 @@ describe "Module#public_class_method" do end end.should raise_error(NameError) end + + ruby_version_is "3.0" do + context "when single argument is passed and is an array" do + it "makes a class method public" do + c = Class.new do + class << self + private + def foo() "foo" end + end + public_class_method [:foo] + end + + c.foo.should == "foo" + end + end + end end diff --git a/spec/ruby/core/random/default_spec.rb b/spec/ruby/core/random/default_spec.rb index a709eddd53..db444d203d 100644 --- a/spec/ruby/core/random/default_spec.rb +++ b/spec/ruby/core/random/default_spec.rb @@ -1,7 +1,6 @@ require_relative '../../spec_helper' describe "Random::DEFAULT" do - it "returns a random number generator" do suppress_warning do Random::DEFAULT.should respond_to(:rand) diff --git a/spec/ruby/core/string/encode_spec.rb b/spec/ruby/core/string/encode_spec.rb index ae641b2110..5604ab7210 100644 --- a/spec/ruby/core/string/encode_spec.rb +++ b/spec/ruby/core/string/encode_spec.rb @@ -67,10 +67,52 @@ describe "String#encode" do "\rfoo".encode(universal_newline: true).should == "\nfoo" end - it "replaces invalid encoding" do - encoded = "ち\xE3\x81\xFF".encode("UTF-16LE", invalid: :replace, replace: "?") - encoded.should == "\u3061??".encode("UTF-16LE") - encoded.encode("UTF-8").should == "ち??" + it "replaces invalid encoding in source with default replacement" do + encoded = "ち\xE3\x81\xFF".encode("UTF-16LE", invalid: :replace) + encoded.should == "\u3061\ufffd\ufffd".encode("UTF-16LE") + encoded.encode("UTF-8").should == "ち\ufffd\ufffd" + end + + it "replaces invalid encoding in source with a specified replacement" do + encoded = "ち\xE3\x81\xFF".encode("UTF-16LE", invalid: :replace, replace: "foo") + encoded.should == "\u3061foofoo".encode("UTF-16LE") + encoded.encode("UTF-8").should == "ちfoofoo" + end + + it "replaces invalid encoding in source using a specified replacement even when a fallback is given" do + encoded = "ち\xE3\x81\xFF".encode("UTF-16LE", invalid: :replace, replace: "foo", fallback: -> c { "bar" }) + encoded.should == "\u3061foofoo".encode("UTF-16LE") + encoded.encode("UTF-8").should == "ちfoofoo" + end + + it "replaces undefined encoding in destination with default replacement" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, undef: :replace) + encoded.should == "B?".encode(Encoding::US_ASCII) + encoded.encode("UTF-8").should == "B?" + end + + it "replaces undefined encoding in destination with a specified replacement" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, undef: :replace, replace: "foo") + encoded.should == "Bfoo".encode(Encoding::US_ASCII) + encoded.encode("UTF-8").should == "Bfoo" + end + + it "replaces undefined encoding in destination with a specified replacement even if a fallback is given" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, undef: :replace, replace: "foo", fallback: proc {|x| "bar"}) + encoded.should == "Bfoo".encode(Encoding::US_ASCII) + encoded.encode("UTF-8").should == "Bfoo" + end + + it "replaces undefined encoding in destination using a fallback proc" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: proc {|x| "bar"}) + encoded.should == "Bbar".encode(Encoding::US_ASCII) + encoded.encode("UTF-8").should == "Bbar" + end + + it "replaces invalid encoding in source using replace even when fallback is given as proc" do + encoded = "ち\xE3\x81\xFF".encode("UTF-16LE", invalid: :replace, replace: "foo", fallback: proc {|x| "bar"}) + encoded.should == "\u3061foofoo".encode("UTF-16LE") + encoded.encode("UTF-8").should == "ちfoofoo" end end diff --git a/spec/ruby/core/symbol/to_proc_spec.rb b/spec/ruby/core/symbol/to_proc_spec.rb index e9261e6cdf..47f2a939ab 100644 --- a/spec/ruby/core/symbol/to_proc_spec.rb +++ b/spec/ruby/core/symbol/to_proc_spec.rb @@ -47,7 +47,9 @@ describe "Symbol#to_proc" do end it "raises an ArgumentError when calling #call on the Proc without receiver" do - -> { :object_id.to_proc.call }.should raise_error(ArgumentError, "no receiver given") + -> { + :object_id.to_proc.call + }.should raise_error(ArgumentError, /no receiver given|wrong number of arguments \(given 0, expected 1\+\)/) end it "passes along the block passed to Proc#call" do diff --git a/spec/ruby/core/thread/ignore_deadlock_spec.rb b/spec/ruby/core/thread/ignore_deadlock_spec.rb new file mode 100644 index 0000000000..53cc2a7f5b --- /dev/null +++ b/spec/ruby/core/thread/ignore_deadlock_spec.rb @@ -0,0 +1,21 @@ +require_relative '../../spec_helper' + +ruby_version_is "3.0" do + describe "Thread.ignore_deadlock" do + it "returns false by default" do + Thread.ignore_deadlock.should == false + end + end + + describe "Thread.ignore_deadlock=" do + it "changes the value of Thread.ignore_deadlock" do + ignore_deadlock = Thread.ignore_deadlock + Thread.ignore_deadlock = true + begin + Thread.ignore_deadlock.should == true + ensure + Thread.ignore_deadlock = ignore_deadlock + end + end + end +end diff --git a/spec/ruby/core/warning/element_reference_spec.rb b/spec/ruby/core/warning/element_reference_spec.rb index c3bf06a95b..a346cf535b 100644 --- a/spec/ruby/core/warning/element_reference_spec.rb +++ b/spec/ruby/core/warning/element_reference_spec.rb @@ -1,10 +1,12 @@ require_relative '../../spec_helper' -ruby_version_is '2.7.2' do +ruby_version_is '2.7' do describe "Warning.[]" do - it "returns default values for categories :deprecated and :experimental" do - ruby_exe('p Warning[:deprecated]').chomp.should == "false" - ruby_exe('p Warning[:experimental]').chomp.should == "true" + ruby_version_is '2.7.2' do + it "returns default values for categories :deprecated and :experimental" do + ruby_exe('p Warning[:deprecated]').chomp.should == "false" + ruby_exe('p Warning[:experimental]').chomp.should == "true" + end end it "raises for unknown category" do diff --git a/spec/ruby/language/class_variable_spec.rb b/spec/ruby/language/class_variable_spec.rb index dffab47a6b..9a4b36e82b 100644 --- a/spec/ruby/language/class_variable_spec.rb +++ b/spec/ruby/language/class_variable_spec.rb @@ -82,3 +82,29 @@ describe 'A class variable definition' do c.class_variable_get(:@@cv).should == :next end end + +ruby_version_is "3.0" do + describe 'Accessing a class variable' do + it "raises a RuntimeError when accessed from the toplevel scope (not in some module or class)" do + -> { + eval "@@cvar_toplevel1" + }.should raise_error(RuntimeError, 'class variable access from toplevel') + -> { + eval "@@cvar_toplevel2 = 2" + }.should raise_error(RuntimeError, 'class variable access from toplevel') + end + + it "raises a RuntimeError when a class variable is overtaken in an ancestor class" do + parent = Class.new() + subclass = Class.new(parent) + subclass.class_variable_set(:@@cvar_overtaken, :subclass) + parent.class_variable_set(:@@cvar_overtaken, :parent) + + -> { + subclass.class_variable_get(:@@cvar_overtaken) + }.should raise_error(RuntimeError, /class variable @@cvar_overtaken of .+ is overtaken by .+/) + + parent.class_variable_get(:@@cvar_overtaken).should == :parent + end + end +end diff --git a/spec/ruby/language/numbered_parameters_spec.rb b/spec/ruby/language/numbered_parameters_spec.rb index cd1ddf4555..838822b2d6 100644 --- a/spec/ruby/language/numbered_parameters_spec.rb +++ b/spec/ruby/language/numbered_parameters_spec.rb @@ -80,6 +80,20 @@ ruby_version_is "2.7" do -> { eval("['a'].map { |x| _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) end + describe "assigning to a numbered parameter" do + ruby_version_is '2.7'...'3.0' do + it "warns" do + -> { eval("proc { _1 = 0 }") }.should complain(/warning: `_1' is reserved for numbered parameter; consider another name/) + end + end + + ruby_version_is '3.0' do + it "raises SyntaxError" do + -> { eval("proc { _1 = 0 }") }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/) + end + end + end + it "affects block arity" do -> { _1 }.arity.should == 1 -> { _2 }.arity.should == 2 diff --git a/spec/ruby/language/safe_spec.rb b/spec/ruby/language/safe_spec.rb index 062381d729..89830a2069 100644 --- a/spec/ruby/language/safe_spec.rb +++ b/spec/ruby/language/safe_spec.rb @@ -106,4 +106,14 @@ describe "The $SAFE variable" do }.should complain(/\$SAFE will become a normal global variable in Ruby 3.0/) end end + + ruby_version_is "3.0" do + it "$SAFE is a regular global variable" do + $SAFE.should == nil + $SAFE = 42 + $SAFE.should == 42 + ensure + $SAFE = nil + end + end end diff --git a/spec/ruby/language/variables_spec.rb b/spec/ruby/language/variables_spec.rb index 7d6969e659..699187335c 100644 --- a/spec/ruby/language/variables_spec.rb +++ b/spec/ruby/language/variables_spec.rb @@ -822,3 +822,32 @@ describe 'Allowed characters' do result.should == 1 end end + +describe "Instance variables" do + context "when instance variable is uninitialized" do + ruby_version_is ""..."3.0" do + it "warns about accessing uninitialized instance variable" do + obj = Object.new + def obj.foobar; a = @a; end + + -> { obj.foobar }.should complain(/warning: instance variable @a not initialized/, verbose: true) + end + end + + ruby_version_is "3.0" do + it "doesn't warn about accessing uninitialized instance variable" do + obj = Object.new + def obj.foobar; a = @a; end + + -> { obj.foobar }.should_not complain(verbose: true) + end + end + + it "doesn't warn at lazy initialization" do + obj = Object.new + def obj.foobar; @a ||= 42; end + + -> { obj.foobar }.should_not complain(verbose: true) + end + end +end -- cgit v1.2.3