1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Benoit Daloze 2021-10-28 18:54:01 +02:00
parent 3bf36979d8
commit c75df796d8
25 changed files with 454 additions and 38 deletions

View file

@ -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...

View file

@ -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/
ruby_exe('p Warning[:deprecated]', options: '-w -W:no-deprecated').should == "false\n"
end
end
result = ruby_exe('$; = ""', options: '-w -W:no-deprecated', args: '2>&1')
result.should == ""
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
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
end
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

View file

@ -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

View file

@ -1,5 +1,5 @@
def a
raise
raise 'oops'
end
def b

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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