summaryrefslogtreecommitdiff
path: root/spec/ruby
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2021-10-20 21:41:46 +0200
committerBenoit Daloze <eregontp@gmail.com>2021-10-20 21:41:46 +0200
commita6c6eef04aaa075f4bbd0eef740d011737afec91 (patch)
treee8779ca2ddc044899caabca88c16abc9a9054fff /spec/ruby
parent207a5a5bc13018344dc2ab7913fdcaeaeca01292 (diff)
Update to ruby/spec@d6921ef
Diffstat (limited to 'spec/ruby')
-rw-r--r--spec/ruby/command_line/backtrace_limit_spec.rb48
-rw-r--r--spec/ruby/command_line/fixtures/backtrace.rb35
-rw-r--r--spec/ruby/core/array/shared/slice.rb217
-rw-r--r--spec/ruby/core/binding/eval_spec.rb16
-rw-r--r--spec/ruby/core/conditionvariable/broadcast_spec.rb (renamed from spec/ruby/library/conditionvariable/broadcast_spec.rb)0
-rw-r--r--spec/ruby/core/conditionvariable/marshal_dump_spec.rb (renamed from spec/ruby/library/conditionvariable/marshal_dump_spec.rb)0
-rw-r--r--spec/ruby/core/conditionvariable/signal_spec.rb (renamed from spec/ruby/library/conditionvariable/signal_spec.rb)0
-rw-r--r--spec/ruby/core/conditionvariable/wait_spec.rb (renamed from spec/ruby/library/conditionvariable/wait_spec.rb)0
-rw-r--r--spec/ruby/core/dir/shared/glob.rb17
-rw-r--r--spec/ruby/core/env/shift_spec.rb39
-rw-r--r--spec/ruby/core/file/utime_spec.rb12
-rw-r--r--spec/ruby/core/float/comparison_spec.rb15
-rw-r--r--spec/ruby/core/hash/transform_keys_spec.rb27
-rw-r--r--spec/ruby/core/integer/zero_spec.rb21
-rw-r--r--spec/ruby/core/kernel/clone_spec.rb92
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb10
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb8
-rw-r--r--spec/ruby/core/module/autoload_spec.rb100
-rw-r--r--spec/ruby/core/module/const_set_spec.rb3
-rw-r--r--spec/ruby/core/module/constants_spec.rb6
-rw-r--r--spec/ruby/core/range/each_spec.rb24
-rw-r--r--spec/ruby/language/hash_spec.rb39
-rw-r--r--spec/ruby/language/method_spec.rb157
-rw-r--r--spec/ruby/language/pattern_matching_spec.rb173
-rw-r--r--spec/ruby/language/proc_spec.rb26
-rw-r--r--spec/ruby/language/range_spec.rb6
-rw-r--r--spec/ruby/language/singleton_class_spec.rb17
-rw-r--r--spec/ruby/language/yield_spec.rb28
-rw-r--r--spec/ruby/library/ipaddr/new_spec.rb41
-rw-r--r--spec/ruby/library/set/comparison_spec.rb29
-rw-r--r--spec/ruby/library/set/initialize_clone_spec.rb18
-rw-r--r--spec/ruby/library/set/join_spec.rb31
-rw-r--r--spec/ruby/library/set/sortedset/sortedset_spec.rb22
-rw-r--r--spec/ruby/library/socket/tcpsocket/initialize_spec.rb5
-rw-r--r--spec/ruby/library/socket/tcpsocket/new_spec.rb5
-rw-r--r--spec/ruby/library/socket/tcpsocket/shared/new.rb15
-rw-r--r--spec/ruby/library/stringio/ungetbyte_spec.rb2
-rw-r--r--spec/ruby/security/cve_2010_1330_spec.rb2
-rw-r--r--spec/ruby/security/cve_2013_4164_spec.rb4
-rw-r--r--spec/ruby/security/cve_2014_8080_spec.rb1
-rw-r--r--spec/ruby/security/cve_2018_16396_spec.rb4
-rw-r--r--spec/ruby/security/cve_2018_8778_spec.rb2
-rw-r--r--spec/ruby/security/cve_2019_8323_spec.rb54
-rw-r--r--spec/ruby/security/cve_2019_8325_spec.rb6
44 files changed, 1134 insertions, 243 deletions
diff --git a/spec/ruby/command_line/backtrace_limit_spec.rb b/spec/ruby/command_line/backtrace_limit_spec.rb
new file mode 100644
index 0000000000..c0b243841e
--- /dev/null
+++ b/spec/ruby/command_line/backtrace_limit_spec.rb
@@ -0,0 +1,48 @@
+require_relative '../spec_helper'
+
+ruby_version_is "3.0" do
+ describe "The --backtrace-limit command line option" do
+ it "limits top-level backtraces to a given number of entries" do
+ file = fixture(__FILE__ , "backtrace.rb")
+ out = ruby_exe(file, options: "--backtrace-limit=2", args: "top 2>&1", exit_status: 1)
+ out = out.gsub(__dir__, '')
+
+ out.should == <<-MSG
+top
+/fixtures/backtrace.rb:2:in `a': unhandled exception
+\tfrom /fixtures/backtrace.rb:6:in `b'
+\tfrom /fixtures/backtrace.rb:10:in `c'
+\t ... 2 levels...
+ MSG
+ end
+
+ it "affects Exception#full_message" do
+ file = fixture(__FILE__ , "backtrace.rb")
+ out = ruby_exe(file, options: "--backtrace-limit=2", args: "full_message 2>&1")
+ out = out.gsub(__dir__, '')
+
+ out.should == <<-MSG
+full_message
+/fixtures/backtrace.rb:2:in `a': unhandled exception
+\tfrom /fixtures/backtrace.rb:6:in `b'
+\tfrom /fixtures/backtrace.rb:10:in `c'
+\t ... 2 levels...
+ MSG
+ end
+
+ it "does not affect Exception#backtrace" do
+ file = fixture(__FILE__ , "backtrace.rb")
+ out = ruby_exe(file, options: "--backtrace-limit=2", args: "backtrace 2>&1")
+ out = out.gsub(__dir__, '')
+
+ out.should == <<-MSG
+backtrace
+/fixtures/backtrace.rb:2:in `a'
+/fixtures/backtrace.rb:6:in `b'
+/fixtures/backtrace.rb:10:in `c'
+/fixtures/backtrace.rb:14:in `d'
+/fixtures/backtrace.rb:29:in `<main>'
+ MSG
+ end
+ end
+end
diff --git a/spec/ruby/command_line/fixtures/backtrace.rb b/spec/ruby/command_line/fixtures/backtrace.rb
new file mode 100644
index 0000000000..19ad638d35
--- /dev/null
+++ b/spec/ruby/command_line/fixtures/backtrace.rb
@@ -0,0 +1,35 @@
+def a
+ raise
+end
+
+def b
+ a
+end
+
+def c
+ b
+end
+
+def d
+ c
+end
+
+arg = ARGV.first
+$stderr.puts arg
+
+case arg
+when 'full_message'
+ begin
+ d
+ rescue => exc
+ puts exc.full_message
+ end
+when 'backtrace'
+ begin
+ d
+ rescue => exc
+ puts exc.backtrace
+ end
+else
+ d
+end
diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb
index 19e1a3ee2b..cf195ad7a4 100644
--- a/spec/ruby/core/array/shared/slice.rb
+++ b/spec/ruby/core/array/shared/slice.rb
@@ -517,8 +517,9 @@ describe :array_slice, shared: true do
end
it "raises a RangeError if passed a range with a bound that is too large" do
- -> { "hello".send(@method, bignum_value..(bignum_value + 1)) }.should raise_error(RangeError)
- -> { "hello".send(@method, 0..bignum_value) }.should raise_error(RangeError)
+ array = [1, 2, 3, 4, 5, 6]
+ -> { array.send(@method, bignum_value..(bignum_value + 1)) }.should raise_error(RangeError)
+ -> { array.send(@method, 0..bignum_value) }.should raise_error(RangeError)
end
it "can accept endless ranges" do
@@ -533,6 +534,218 @@ describe :array_slice, shared: true do
a.send(@method, eval("(-9...)")).should == nil
end
+ ruby_version_is "3.0" do
+ describe "can be sliced with Enumerator::ArithmeticSequence" do
+ before :each do
+ @array = [0, 1, 2, 3, 4, 5]
+ end
+
+ it "has endless range and positive steps" do
+ @array.send(@method, eval("(0..).step(1)")).should == [0, 1, 2, 3, 4, 5]
+ @array.send(@method, eval("(0..).step(2)")).should == [0, 2, 4]
+ @array.send(@method, eval("(0..).step(10)")).should == [0]
+
+ @array.send(@method, eval("(2..).step(1)")).should == [2, 3, 4, 5]
+ @array.send(@method, eval("(2..).step(2)")).should == [2, 4]
+ @array.send(@method, eval("(2..).step(10)")).should == [2]
+
+ @array.send(@method, eval("(-3..).step(1)")).should == [3, 4, 5]
+ @array.send(@method, eval("(-3..).step(2)")).should == [3, 5]
+ @array.send(@method, eval("(-3..).step(10)")).should == [3]
+ end
+
+ it "has beginless range and positive steps" do
+ # end with zero index
+ @array.send(@method, eval("(..0).step(1)")).should == [0]
+ @array.send(@method, eval("(...0).step(1)")).should == []
+
+ @array.send(@method, eval("(..0).step(2)")).should == [0]
+ @array.send(@method, eval("(...0).step(2)")).should == []
+
+ @array.send(@method, eval("(..0).step(10)")).should == [0]
+ @array.send(@method, eval("(...0).step(10)")).should == []
+
+ # end with positive index
+ @array.send(@method, eval("(..3).step(1)")).should == [0, 1, 2, 3]
+ @array.send(@method, eval("(...3).step(1)")).should == [0, 1, 2]
+
+ @array.send(@method, eval("(..3).step(2)")).should == [0, 2]
+ @array.send(@method, eval("(...3).step(2)")).should == [0, 2]
+
+ @array.send(@method, eval("(..3).step(10)")).should == [0]
+ @array.send(@method, eval("(...3).step(10)")).should == [0]
+
+ # end with negative index
+ @array.send(@method, eval("(..-2).step(1)")).should == [0, 1, 2, 3, 4,]
+ @array.send(@method, eval("(...-2).step(1)")).should == [0, 1, 2, 3]
+
+ @array.send(@method, eval("(..-2).step(2)")).should == [0, 2, 4]
+ @array.send(@method, eval("(...-2).step(2)")).should == [0, 2]
+
+ @array.send(@method, eval("(..-2).step(10)")).should == [0]
+ @array.send(@method, eval("(...-2).step(10)")).should == [0]
+ end
+
+ it "has endless range and negative steps" do
+ @array.send(@method, eval("(0..).step(-1)")).should == [0]
+ @array.send(@method, eval("(0..).step(-2)")).should == [0]
+ @array.send(@method, eval("(0..).step(-10)")).should == [0]
+
+ @array.send(@method, eval("(2..).step(-1)")).should == [2, 1, 0]
+ @array.send(@method, eval("(2..).step(-2)")).should == [2, 0]
+
+ @array.send(@method, eval("(-3..).step(-1)")).should == [3, 2, 1, 0]
+ @array.send(@method, eval("(-3..).step(-2)")).should == [3, 1]
+ end
+
+ it "has closed range and positive steps" do
+ # start and end with 0
+ @array.send(@method, eval("(0..0).step(1)")).should == [0]
+ @array.send(@method, eval("(0...0).step(1)")).should == []
+
+ @array.send(@method, eval("(0..0).step(2)")).should == [0]
+ @array.send(@method, eval("(0...0).step(2)")).should == []
+
+ @array.send(@method, eval("(0..0).step(10)")).should == [0]
+ @array.send(@method, eval("(0...0).step(10)")).should == []
+
+ # start and end with positive index
+ @array.send(@method, eval("(1..3).step(1)")).should == [1, 2, 3]
+ @array.send(@method, eval("(1...3).step(1)")).should == [1, 2]
+
+ @array.send(@method, eval("(1..3).step(2)")).should == [1, 3]
+ @array.send(@method, eval("(1...3).step(2)")).should == [1]
+
+ @array.send(@method, eval("(1..3).step(10)")).should == [1]
+ @array.send(@method, eval("(1...3).step(10)")).should == [1]
+
+ # start with positive index, end with negative index
+ @array.send(@method, eval("(1..-2).step(1)")).should == [1, 2, 3, 4]
+ @array.send(@method, eval("(1...-2).step(1)")).should == [1, 2, 3]
+
+ @array.send(@method, eval("(1..-2).step(2)")).should == [1, 3]
+ @array.send(@method, eval("(1...-2).step(2)")).should == [1, 3]
+
+ @array.send(@method, eval("(1..-2).step(10)")).should == [1]
+ @array.send(@method, eval("(1...-2).step(10)")).should == [1]
+
+ # start with negative index, end with positive index
+ @array.send(@method, eval("(-4..4).step(1)")).should == [2, 3, 4]
+ @array.send(@method, eval("(-4...4).step(1)")).should == [2, 3]
+
+ @array.send(@method, eval("(-4..4).step(2)")).should == [2, 4]
+ @array.send(@method, eval("(-4...4).step(2)")).should == [2]
+
+ @array.send(@method, eval("(-4..4).step(10)")).should == [2]
+ @array.send(@method, eval("(-4...4).step(10)")).should == [2]
+
+ # start with negative index, end with negative index
+ @array.send(@method, eval("(-4..-2).step(1)")).should == [2, 3, 4]
+ @array.send(@method, eval("(-4...-2).step(1)")).should == [2, 3]
+
+ @array.send(@method, eval("(-4..-2).step(2)")).should == [2, 4]
+ @array.send(@method, eval("(-4...-2).step(2)")).should == [2]
+
+ @array.send(@method, eval("(-4..-2).step(10)")).should == [2]
+ @array.send(@method, eval("(-4...-2).step(10)")).should == [2]
+ end
+
+ it "has closed range and negative steps" do
+ # start and end with 0
+ @array.send(@method, eval("(0..0).step(-1)")).should == [0]
+ @array.send(@method, eval("(0...0).step(-1)")).should == []
+
+ @array.send(@method, eval("(0..0).step(-2)")).should == [0]
+ @array.send(@method, eval("(0...0).step(-2)")).should == []
+
+ @array.send(@method, eval("(0..0).step(-10)")).should == [0]
+ @array.send(@method, eval("(0...0).step(-10)")).should == []
+
+ # start and end with positive index
+ @array.send(@method, eval("(1..3).step(-1)")).should == []
+ @array.send(@method, eval("(1...3).step(-1)")).should == []
+
+ @array.send(@method, eval("(1..3).step(-2)")).should == []
+ @array.send(@method, eval("(1...3).step(-2)")).should == []
+
+ @array.send(@method, eval("(1..3).step(-10)")).should == []
+ @array.send(@method, eval("(1...3).step(-10)")).should == []
+
+ # start with positive index, end with negative index
+ @array.send(@method, eval("(1..-2).step(-1)")).should == []
+ @array.send(@method, eval("(1...-2).step(-1)")).should == []
+
+ @array.send(@method, eval("(1..-2).step(-2)")).should == []
+ @array.send(@method, eval("(1...-2).step(-2)")).should == []
+
+ @array.send(@method, eval("(1..-2).step(-10)")).should == []
+ @array.send(@method, eval("(1...-2).step(-10)")).should == []
+
+ # start with negative index, end with positive index
+ @array.send(@method, eval("(-4..4).step(-1)")).should == []
+ @array.send(@method, eval("(-4...4).step(-1)")).should == []
+
+ @array.send(@method, eval("(-4..4).step(-2)")).should == []
+ @array.send(@method, eval("(-4...4).step(-2)")).should == []
+
+ @array.send(@method, eval("(-4..4).step(-10)")).should == []
+ @array.send(@method, eval("(-4...4).step(-10)")).should == []
+
+ # start with negative index, end with negative index
+ @array.send(@method, eval("(-4..-2).step(-1)")).should == []
+ @array.send(@method, eval("(-4...-2).step(-1)")).should == []
+
+ @array.send(@method, eval("(-4..-2).step(-2)")).should == []
+ @array.send(@method, eval("(-4...-2).step(-2)")).should == []
+
+ @array.send(@method, eval("(-4..-2).step(-10)")).should == []
+ @array.send(@method, eval("(-4...-2).step(-10)")).should == []
+ end
+
+ it "has inverted closed range and positive steps" do
+ # start and end with positive index
+ @array.send(@method, eval("(3..1).step(1)")).should == []
+ @array.send(@method, eval("(3...1).step(1)")).should == []
+
+ @array.send(@method, eval("(3..1).step(2)")).should == []
+ @array.send(@method, eval("(3...1).step(2)")).should == []
+
+ @array.send(@method, eval("(3..1).step(10)")).should == []
+ @array.send(@method, eval("(3...1).step(10)")).should == []
+
+ # start with negative index, end with positive index
+ @array.send(@method, eval("(-2..1).step(1)")).should == []
+ @array.send(@method, eval("(-2...1).step(1)")).should == []
+
+ @array.send(@method, eval("(-2..1).step(2)")).should == []
+ @array.send(@method, eval("(-2...1).step(2)")).should == []
+
+ @array.send(@method, eval("(-2..1).step(10)")).should == []
+ @array.send(@method, eval("(-2...1).step(10)")).should == []
+
+ # start with positive index, end with negative index
+ @array.send(@method, eval("(4..-4).step(1)")).should == []
+ @array.send(@method, eval("(4...-4).step(1)")).should == []
+
+ @array.send(@method, eval("(4..-4).step(2)")).should == []
+ @array.send(@method, eval("(4...-4).step(2)")).should == []
+
+ @array.send(@method, eval("(4..-4).step(10)")).should == []
+ @array.send(@method, eval("(4...-4).step(10)")).should == []
+
+ # start with negative index, end with negative index
+ @array.send(@method, eval("(-2..-4).step(1)")).should == []
+ @array.send(@method, eval("(-2...-4).step(1)")).should == []
+
+ @array.send(@method, eval("(-2..-4).step(2)")).should == []
+ @array.send(@method, eval("(-2...-4).step(2)")).should == []
+
+ @array.send(@method, eval("(-2..-4).step(10)")).should == []
+ @array.send(@method, eval("(-2...-4).step(10)")).should == []
+ end
+ end
+ end
+
ruby_version_is "2.7" do
it "can accept beginless ranges" do
a = [0, 1, 2, 3, 4, 5]
diff --git a/spec/ruby/core/binding/eval_spec.rb b/spec/ruby/core/binding/eval_spec.rb
index b36bec799e..4bb3da7a6c 100644
--- a/spec/ruby/core/binding/eval_spec.rb
+++ b/spec/ruby/core/binding/eval_spec.rb
@@ -93,16 +93,28 @@ describe "Binding#eval" do
it "inherits __FILE__ from the enclosing scope" do
obj = BindingSpecs::Demo.new(1)
bind = obj.get_binding
- suppress_warning {bind.eval("__FILE__")}.should == obj.get_file_of_binding
+ suppress_warning { bind.eval("__FILE__") }.should == obj.get_file_of_binding
+ end
+
+ it "inherits __LINE__ from the enclosing scope" do
+ obj = BindingSpecs::Demo.new(1)
+ bind, line = obj.get_binding_and_line
+ suppress_warning { bind.eval("__LINE__") }.should == line
end
end
ruby_version_is "3.0" do
- it "Uses (eval) as __FILE__ if single argument given" do
+ it "uses (eval) as __FILE__ if single argument given" do
obj = BindingSpecs::Demo.new(1)
bind = obj.get_binding
bind.eval("__FILE__").should == '(eval)'
end
+
+ it "uses 1 as __LINE__" do
+ obj = BindingSpecs::Demo.new(1)
+ bind = obj.get_binding
+ suppress_warning { bind.eval("__LINE__") }.should == 1
+ end
end
it "uses the __FILE__ that is passed in" do
diff --git a/spec/ruby/library/conditionvariable/broadcast_spec.rb b/spec/ruby/core/conditionvariable/broadcast_spec.rb
index d88159df23..d88159df23 100644
--- a/spec/ruby/library/conditionvariable/broadcast_spec.rb
+++ b/spec/ruby/core/conditionvariable/broadcast_spec.rb
diff --git a/spec/ruby/library/conditionvariable/marshal_dump_spec.rb b/spec/ruby/core/conditionvariable/marshal_dump_spec.rb
index f951a13e28..f951a13e28 100644
--- a/spec/ruby/library/conditionvariable/marshal_dump_spec.rb
+++ b/spec/ruby/core/conditionvariable/marshal_dump_spec.rb
diff --git a/spec/ruby/library/conditionvariable/signal_spec.rb b/spec/ruby/core/conditionvariable/signal_spec.rb
index 86383073f1..86383073f1 100644
--- a/spec/ruby/library/conditionvariable/signal_spec.rb
+++ b/spec/ruby/core/conditionvariable/signal_spec.rb
diff --git a/spec/ruby/library/conditionvariable/wait_spec.rb b/spec/ruby/core/conditionvariable/wait_spec.rb
index 9a68c2b5a1..9a68c2b5a1 100644
--- a/spec/ruby/library/conditionvariable/wait_spec.rb
+++ b/spec/ruby/core/conditionvariable/wait_spec.rb
diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb
index d2824df446..173038ee24 100644
--- a/spec/ruby/core/dir/shared/glob.rb
+++ b/spec/ruby/core/dir/shared/glob.rb
@@ -38,6 +38,23 @@ describe :dir_glob, shared: true do
end
end
+ ruby_version_is "3.0" do
+ it "result is sorted by default" do
+ result = Dir.send(@method, '*')
+ result.should == result.sort
+ end
+
+ it "result is sorted with sort: true" do
+ result = Dir.send(@method, '*', sort: true)
+ result.should == result.sort
+ end
+
+ it "sort: false returns same files" do
+ result = Dir.send(@method,'*', sort: false)
+ result.sort.should == Dir.send(@method, '*').sort
+ end
+ end
+
it "matches non-dotfiles with '*'" do
expected = %w[
brace
diff --git a/spec/ruby/core/env/shift_spec.rb b/spec/ruby/core/env/shift_spec.rb
index 8717b7220e..1b92e5d1e4 100644
--- a/spec/ruby/core/env/shift_spec.rb
+++ b/spec/ruby/core/env/shift_spec.rb
@@ -2,36 +2,13 @@ require_relative '../../spec_helper'
require_relative 'fixtures/common'
describe "ENV.shift" do
- it "returns a pair and deletes it" do
- ENV.should_not.empty?
- orig = ENV.to_hash
- begin
- pair = ENV.shift
- ENV.has_key?(pair.first).should == false
- ensure
- ENV.replace orig
- end
- ENV.has_key?(pair.first).should == true
- end
-
- it "returns nil if ENV.empty?" do
- orig = ENV.to_hash
- begin
- ENV.clear
- ENV.shift.should == nil
- ensure
- ENV.replace orig
- end
- end
-end
-
-describe "ENV.shift" do
before :each do
@orig = ENV.to_hash
@external = Encoding.default_external
@internal = Encoding.default_internal
Encoding.default_external = Encoding::BINARY
+ ENV.replace({"FOO"=>"BAR"})
end
after :each do
@@ -40,6 +17,18 @@ describe "ENV.shift" do
ENV.replace @orig
end
+ it "returns a pair and deletes it" do
+ ENV.should.has_key?("FOO")
+ pair = ENV.shift
+ pair.should == ["FOO", "BAR"]
+ ENV.should_not.has_key?("FOO")
+ end
+
+ it "returns nil if ENV.empty?" do
+ ENV.clear
+ ENV.shift.should == nil
+ end
+
it "uses the locale encoding if Encoding.default_internal is nil" do
Encoding.default_internal = nil
@@ -52,9 +41,7 @@ describe "ENV.shift" do
Encoding.default_internal = Encoding::IBM437
pair = ENV.shift
- pair.first.encode(Encoding::IBM437) rescue next
pair.first.encoding.should equal(Encoding::IBM437)
- pair.last.encode(Encoding::IBM437) rescue next
pair.last.encoding.should equal(Encoding::IBM437)
end
end
diff --git a/spec/ruby/core/file/utime_spec.rb b/spec/ruby/core/file/utime_spec.rb
index 59eef20c66..45a51490e4 100644
--- a/spec/ruby/core/file/utime_spec.rb
+++ b/spec/ruby/core/file/utime_spec.rb
@@ -70,11 +70,13 @@ describe "File.utime" do
end
end
- it "may set nanosecond precision" do
- t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r)
- File.utime(t, t, @file1)
- File.atime(@file1).nsec.should.between?(0, 123500000)
- File.mtime(@file1).nsec.should.between?(0, 123500000)
+ platform_is_not :windows do
+ it "sets nanosecond precision" do
+ t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r)
+ File.utime(t, t, @file1)
+ File.atime(@file1).nsec.should == 123456789
+ File.mtime(@file1).nsec.should == 123456789
+ end
end
platform_is :linux do
diff --git a/spec/ruby/core/float/comparison_spec.rb b/spec/ruby/core/float/comparison_spec.rb
index a46841ffbf..53e7ec332a 100644
--- a/spec/ruby/core/float/comparison_spec.rb
+++ b/spec/ruby/core/float/comparison_spec.rb
@@ -90,4 +90,19 @@ describe "Float#<=>" do
end
(infinity_value <=> obj).should == 1
end
+
+ it "returns 0 for -0.0 and 0.0" do
+ (-0.0 <=> 0.0).should == 0
+ (0.0 <=> -0.0).should == 0
+ end
+
+ it "returns 0 for -0.0 and 0" do
+ (-0.0 <=> 0).should == 0
+ (0 <=> -0.0).should == 0
+ end
+
+ it "returns 0 for 0.0 and 0" do
+ (0.0 <=> 0).should == 0
+ (0 <=> 0.0).should == 0
+ end
end
diff --git a/spec/ruby/core/hash/transform_keys_spec.rb b/spec/ruby/core/hash/transform_keys_spec.rb
index 70a4cdde36..8ee1a2cd6d 100644
--- a/spec/ruby/core/hash/transform_keys_spec.rb
+++ b/spec/ruby/core/hash/transform_keys_spec.rb
@@ -42,6 +42,20 @@ describe "Hash#transform_keys" do
r.keys.should == [:xfoo]
r.class.should == Hash
end
+
+ ruby_version_is "3.0" do
+ it "allows a hash argument" do
+ @hash.transform_keys({ a: :A, b: :B, c: :C }).should == { A: 1, B: 2, C: 3 }
+ end
+
+ it "allows a partial transformation of keys when using a hash argument" do
+ @hash.transform_keys({ a: :A, c: :C }).should == { A: 1, b: 2, C: 3 }
+ end
+
+ it "allows a combination of hash and block argument" do
+ @hash.transform_keys({ a: :A }, &:to_s).should == { A: 1, 'b' => 2, 'c' => 3 }
+ end
+ end
end
describe "Hash#transform_keys!" do
@@ -98,6 +112,13 @@ describe "Hash#transform_keys!" do
end
end
+ ruby_version_is "3.0" do
+ it "allows a hash argument" do
+ @hash.transform_keys!({ a: :A, b: :B, c: :C, d: :D })
+ @hash.should == { A: 1, B: 2, C: 3, D: 4 }
+ end
+ end
+
describe "on frozen instance" do
before :each do
@hash.freeze
@@ -112,6 +133,12 @@ describe "Hash#transform_keys!" do
@hash.should == @initial_pairs
end
+ ruby_version_is "3.0" do
+ it "raises a FrozenError on hash argument" do
+ ->{ @hash.transform_keys!({ a: :A, b: :B, c: :C }) }.should raise_error(FrozenError)
+ end
+ end
+
context "when no block is given" do
it "does not raise an exception" do
@hash.transform_keys!.should be_an_instance_of(Enumerator)
diff --git a/spec/ruby/core/integer/zero_spec.rb b/spec/ruby/core/integer/zero_spec.rb
new file mode 100644
index 0000000000..2dac50c406
--- /dev/null
+++ b/spec/ruby/core/integer/zero_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../spec_helper'
+
+describe "Integer#zero?" do
+ it "returns true if self is 0" do
+ 0.should.zero?
+ 1.should_not.zero?
+ -1.should_not.zero?
+ end
+
+ ruby_version_is "3.0" do
+ it "Integer#zero? overrides Numeric#zero?" do
+ 42.method(:zero?).owner.should == Integer
+ end
+ end
+
+ ruby_version_is ""..."3.0" do
+ it "Integer#zero? uses Numeric#zero?" do
+ 42.method(:zero?).owner.should == Numeric
+ end
+ end
+end
diff --git a/spec/ruby/core/kernel/clone_spec.rb b/spec/ruby/core/kernel/clone_spec.rb
index c18af4a490..f9daa2badc 100644
--- a/spec/ruby/core/kernel/clone_spec.rb
+++ b/spec/ruby/core/kernel/clone_spec.rb
@@ -28,27 +28,88 @@ describe "Kernel#clone" do
clone.class.should equal klass
end
- it "copies frozen state from the original" do
- o2 = @obj.clone
- @obj.freeze
- o3 = @obj.clone
+ describe "with no arguments" do
+ it "copies frozen state from the original" do
+ o2 = @obj.clone
+ @obj.freeze
+ o3 = @obj.clone
+
+ o2.should_not.frozen?
+ o3.should.frozen?
+ end
- o2.should_not.frozen?
- o3.should.frozen?
+ it 'copies frozen?' do
+ o = ''.freeze.clone
+ o.frozen?.should be_true
+ end
end
- ruby_version_is '3.0' do
- it 'takes an freeze: true option to frozen copy' do
- @obj.clone(freeze: true).should.frozen?
+ describe "with freeze: true" do
+ it 'makes a frozen copy if the original is frozen' do
@obj.freeze
@obj.clone(freeze: true).should.frozen?
end
+
+ ruby_version_is ''...'3.0' do
+ it 'does not freeze the copy even if the original is not frozen' do
+ @obj.clone(freeze: true).should_not.frozen?
+ end
+
+ it "calls #initialize_clone with no kwargs" do
+ obj = KernelSpecs::CloneFreeze.new
+ obj.clone(freeze: true)
+ ScratchPad.recorded.should == [obj, {}]
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it 'freezes the copy even if the original was not frozen' do
+ @obj.clone(freeze: true).should.frozen?
+ end
+
+ it "calls #initialize_clone with kwargs freeze: true" do
+ obj = KernelSpecs::CloneFreeze.new
+ obj.clone(freeze: true)
+ ScratchPad.recorded.should == [obj, { freeze: true }]
+ end
+
+ it "calls #initialize_clone with kwargs freeze: true even if #initialize_clone only takes a single argument" do
+ obj = KernelSpecs::Clone.new
+ -> { obj.clone(freeze: true) }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 1)')
+ end
+ end
end
- it 'takes an freeze: false option to not return frozen copy' do
- @obj.clone(freeze: false).should_not.frozen?
- @obj.freeze
- @obj.clone(freeze: false).should_not.frozen?
+ describe "with freeze: false" do
+ it 'does not freeze the copy if the original is frozen' do
+ @obj.freeze
+ @obj.clone(freeze: false).should_not.frozen?
+ end
+
+ it 'does not freeze the copy if the original is not frozen' do
+ @obj.clone(freeze: false).should_not.frozen?
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "calls #initialize_clone with no kwargs" do
+ obj = KernelSpecs::CloneFreeze.new
+ obj.clone(freeze: false)
+ ScratchPad.recorded.should == [obj, {}]
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "calls #initialize_clone with kwargs freeze: false" do
+ obj = KernelSpecs::CloneFreeze.new
+ obj.clone(freeze: false)
+ ScratchPad.recorded.should == [obj, { freeze: false }]
+ end
+
+ it "calls #initialize_clone with kwargs freeze: false even if #initialize_clone only takes a single argument" do
+ obj = KernelSpecs::Clone.new
+ -> { obj.clone(freeze: false) }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 1)')
+ end
+ end
end
it "copies instance variables" do
@@ -114,11 +175,6 @@ describe "Kernel#clone" do
cloned.bar.should == ['a']
end
- it 'copies frozen?' do
- o = ''.freeze.clone
- o.frozen?.should be_true
- end
-
ruby_version_is ''...'2.7' do
it 'copies tainted?' do
o = ''.taint.clone
diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb
index 1e2764a4de..9be0f2dfd3 100644
--- a/spec/ruby/core/kernel/eval_spec.rb
+++ b/spec/ruby/core/kernel/eval_spec.rb
@@ -168,6 +168,12 @@ describe "Kernel#eval" do
suppress_warning {eval("eval '__FILE__', binding", binding)}.should == __FILE__
suppress_warning {eval("eval '__FILE__', binding", binding, 'success')}.should == 'success'
end
+
+ it 'uses the given binding file and line for __FILE__ and __LINE__' do
+ suppress_warning {
+ eval("[__FILE__, __LINE__]", binding).should == [__FILE__, __LINE__]
+ }
+ end
end
ruby_version_is "3.0" do
@@ -180,6 +186,10 @@ describe "Kernel#eval" do
eval("eval '__FILE__', binding", binding, 'success').should == '(eval)'
eval("eval '__FILE__', binding, 'success'", binding).should == 'success'
end
+
+ it 'uses (eval) for __FILE__ and 1 for __LINE__ with a binding argument' do
+ eval("[__FILE__, __LINE__]", binding).should == ["(eval)", 1]
+ end
end
# Found via Rubinius bug github:#149
diff --git a/spec/ruby/core/kernel/fixtures/classes.rb b/spec/ruby/core/kernel/fixtures/classes.rb
index 1bf5715c50..8de1407b92 100644
--- a/spec/ruby/core/kernel/fixtures/classes.rb
+++ b/spec/ruby/core/kernel/fixtures/classes.rb
@@ -288,7 +288,13 @@ module KernelSpecs
class Clone
def initialize_clone(other)
- ScratchPad.record other.object_id
+ ScratchPad.record other
+ end
+ end
+
+ class CloneFreeze
+ def initialize_clone(other, **kwargs)
+ ScratchPad.record([other, kwargs])
end
end
diff --git a/spec/ruby/core/module/autoload_spec.rb b/spec/ruby/core/module/autoload_spec.rb
index 1d61646db5..f17675846b 100644
--- a/spec/ruby/core/module/autoload_spec.rb
+++ b/spec/ruby/core/module/autoload_spec.rb
@@ -441,42 +441,21 @@ describe "Module#autoload" do
ScratchPad.recorded.should == [:raise, :raise]
end
- ruby_version_is "3.1" do
- it "removes the constant from Module#constants if the loaded file does not define it" do
- path = fixture(__FILE__, "autoload_o.rb")
- ScratchPad.record []
- ModuleSpecs::Autoload.autoload :O, path
-
- ModuleSpecs::Autoload.const_defined?(:O).should == true
- ModuleSpecs::Autoload.should have_constant(:O)
- ModuleSpecs::Autoload.autoload?(:O).should == path
-
- -> { ModuleSpecs::Autoload::O }.should raise_error(NameError)
-
- ModuleSpecs::Autoload.const_defined?(:O).should == false
- ModuleSpecs::Autoload.should_not have_constant(:O)
- ModuleSpecs::Autoload.autoload?(:O).should == nil
- -> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
- end
- end
-
- ruby_version_is ""..."3.1" do
- it "does not remove the constant from Module#constants if the loaded file does not define it, but leaves it as 'undefined'" do
- path = fixture(__FILE__, "autoload_o.rb")
- ScratchPad.record []
- ModuleSpecs::Autoload.autoload :O, path
+ it "does not remove the constant from Module#constants if the loaded file does not define it, but leaves it as 'undefined'" do
+ path = fixture(__FILE__, "autoload_o.rb")
+ ScratchPad.record []
+ ModuleSpecs::Autoload.autoload :O, path
- ModuleSpecs::Autoload.const_defined?(:O).should == true
- ModuleSpecs::Autoload.should have_constant(:O)
- ModuleSpecs::Autoload.autoload?(:O).should == path
+ ModuleSpecs::Autoload.const_defined?(:O).should == true
+ ModuleSpecs::Autoload.should have_constant(:O)
+ ModuleSpecs::Autoload.autoload?(:O).should == path
- -> { ModuleSpecs::Autoload::O }.should raise_error(NameError)
+ -> { ModuleSpecs::Autoload::O }.should raise_error(NameError)
- ModuleSpecs::Autoload.const_defined?(:O).should == false
- ModuleSpecs::Autoload.should have_constant(:O)
- ModuleSpecs::Autoload.autoload?(:O).should == nil
- -> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
- end
+ ModuleSpecs::Autoload.should have_constant(:O)
+ ModuleSpecs::Autoload.const_defined?(:O).should == false
+ ModuleSpecs::Autoload.autoload?(:O).should == nil
+ -> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
end
it "does not try to load the file again if the loaded file did not define the constant" do
@@ -575,54 +554,31 @@ describe "Module#autoload" do
# Basically, the parent autoload constant remains in a "undefined" state
self.autoload?(:DeclaredInParentDefinedInCurrent).should == nil
const_defined?(:DeclaredInParentDefinedInCurrent).should == false
+ self.should have_constant(:DeclaredInParentDefinedInCurrent)
-> { DeclaredInParentDefinedInCurrent }.should raise_error(NameError)
ModuleSpecs::Autoload::LexicalScope.send(:remove_const, :DeclaredInParentDefinedInCurrent)
end
end
- ruby_version_is "3.1" do
- it "looks up in parent scope after failed autoload" do
- @remove << :DeclaredInCurrentDefinedInParent
- module ModuleSpecs::Autoload
- ScratchPad.record -> {
- DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
- }
-
- class LexicalScope
- autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
- -> { DeclaredInCurrentDefinedInParent }.should_not raise_error(NameError)
- # Basically, the autoload constant remains in a "undefined" state
- self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
- const_defined?(:DeclaredInCurrentDefinedInParent).should == false
- -> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
- end
+ it "and fails when finding the undefined autoload constant in the current scope when declared in current and defined in parent" do
+ @remove << :DeclaredInCurrentDefinedInParent
+ module ModuleSpecs::Autoload
+ ScratchPad.record -> {
+ DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
+ }
- DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
+ class LexicalScope
+ autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
+ -> { DeclaredInCurrentDefinedInParent }.should raise_error(NameError)
+ # Basically, the autoload constant remains in a "undefined" state
+ self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
+ const_defined?(:DeclaredInCurrentDefinedInParent).should == false
+ self.should have_constant(:DeclaredInCurrentDefinedInParent)
+ -> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
end
- end
- end
-
- ruby_version_is ""..."3.1" do
- it "and fails when finding the undefined autoload constant in the current scope when declared in current and defined in parent" do
- @remove << :DeclaredInCurrentDefinedInParent
- module ModuleSpecs::Autoload
- ScratchPad.record -> {
- DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
- }
-
- class LexicalScope
- autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
- -> { DeclaredInCurrentDefinedInParent }.should raise_error(NameError)
- # Basically, the autoload constant remains in a "undefined" state
- self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
- const_defined?(:DeclaredInCurrentDefinedInParent).should == false
- self.should have_constant(:DeclaredInCurrentDefinedInParent)
- -> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
- end
- DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
- end
+ DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
end
end
diff --git a/spec/ruby/core/module/const_set_spec.rb b/spec/ruby/core/module/const_set_spec.rb
index ba7810d17b..b537d3f133 100644
--- a/spec/ruby/core/module/const_set_spec.rb
+++ b/spec/ruby/core/module/const_set_spec.rb
@@ -101,7 +101,7 @@ describe "Module#const_set" do
mod.const_get(:Foo).should == 1
end
- it "does not warn after a failed autoload" do
+ it "does not warn if the previous value was undefined" do
path = fixture(__FILE__, "autoload_o.rb")
ScratchPad.record []
mod = Module.new
@@ -109,6 +109,7 @@ describe "Module#const_set" do
mod.autoload :Foo, path
-> { mod::Foo }.should raise_error(NameError)
+ mod.should have_constant(:Foo)
mod.const_defined?(:Foo).should == false
mod.autoload?(:Foo).should == nil
diff --git a/spec/ruby/core/module/constants_spec.rb b/spec/ruby/core/module/constants_spec.rb
index fe95143872..330da1cc88 100644
--- a/spec/ruby/core/module/constants_spec.rb
+++ b/spec/ruby/core/module/constants_spec.rb
@@ -74,6 +74,12 @@ describe "Module#constants" do
it "returns only public constants" do
ModuleSpecs::PrivConstModule.constants.should == [:PUBLIC_CONSTANT]
end
+
+ it "returns only constants starting with an uppercase letter" do
+ # e.g. fatal, IO::generic_readable and IO::generic_writable should not be returned by Module#constants
+ Object.constants.each { |c| c[0].should == c[0].upcase }
+ IO.constants.each { |c| c[0].should == c[0].upcase }
+ end
end
describe "Module#constants" do
diff --git a/spec/ruby/core/range/each_spec.rb b/spec/ruby/core/range/each_spec.rb
index bd4bbb82e5..6b33f57737 100644
--- a/spec/ruby/core/range/each_spec.rb
+++ b/spec/ruby/core/range/each_spec.rb
@@ -84,9 +84,27 @@ describe "Range#each" do
enum.to_a.should == [1, 2, 3]
end
- it "raises a TypeError if the first element is a Time object" do
- t = Time.now
- -> { (t..t+1).each { |i| i } }.should raise_error(TypeError)
+ ruby_version_is "3.1" do
+ it "supports Time objects that respond to #succ" do
+ t = Time.utc(1970)
+ def t.succ; self + 1 end
+ t_succ = t.succ
+ def t_succ.succ; self + 1; end
+
+ (t..t_succ).to_a.should == [Time.utc(1970), Time.utc(1970, nil, nil, nil, nil, 1)]
+ (t...t_succ).to_a.should == [Time.utc(1970)]
+ end
+ end
+
+ ruby_version_is ""..."3.1" do
+ it "raises a TypeError if the first element is a Time object even if it responds to #succ" do
+ t = Time.utc(1970)
+ def t.succ; self + 1 end
+ t_succ = t.succ
+ def t_succ.succ; self + 1; end
+
+ -> { (t..t_succ).each { |i| i } }.should raise_error(TypeError)
+ end
end
it "passes each Symbol element by using #succ" do
diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb
index f99ff8ab3f..2f8b97199a 100644
--- a/spec/ruby/language/hash_spec.rb
+++ b/spec/ruby/language/hash_spec.rb
@@ -225,4 +225,43 @@ describe "The ** operator" do
h.should == { two: 2 }
end
end
+
+ ruby_version_is "3.1" do
+ describe "hash with omitted value" do
+ it "accepts short notation 'key' for 'key: value' syntax" do
+ a, b, c = 1, 2, 3
+ h = eval('{a:}')
+ {a: 1}.should == h
+ h = eval('{a:, b:, c:}')
+ {a: 1, b: 2, c: 3}.should == h
+ end
+
+ it "ignores hanging comma on short notation" do
+ a, b, c = 1, 2, 3
+ h = eval('{a:, b:, c:,}')
+ {a: 1, b: 2, c: 3}.should == h
+ end
+
+ it "accepts mixed syntax" do
+ a, e = 1, 5
+ h = eval('{a:, b: 2, "c" => 3, :d => 4, e:}')
+ eval('{a: 1, :b => 2, "c" => 3, "d": 4, e: 5}').should == h
+ end
+
+ it "works with methods and local vars" do
+ a = Class.new
+ a.class_eval(<<-RUBY)
+ def bar
+ "baz"
+ end
+
+ def foo(val)
+ {bar:, val:}
+ end
+ RUBY
+
+ a.new.foo(1).should == {bar: "baz", val: 1}
+ end
+ end
+ end
end
diff --git a/spec/ruby/language/method_spec.rb b/spec/ruby/language/method_spec.rb
index 449d5e6f1b..0a5bb99d0b 100644
--- a/spec/ruby/language/method_spec.rb
+++ b/spec/ruby/language/method_spec.rb
@@ -1861,15 +1861,158 @@ describe "An array-dereference method ([])" do
end
end
-ruby_version_is '3.0' do
+ruby_version_is "3.0" do
describe "An endless method definition" do
- evaluate <<-ruby do
- def m(a) = a
- ruby
+ context "without arguments" do
+ evaluate <<-ruby do
+ def m() = 42
+ ruby
+
+ m.should == 42
+ end
+ end
+
+ context "with arguments" do
+ evaluate <<-ruby do
+ def m(a, b) = a + b
+ ruby
+
+ m(1, 4).should == 5
+ end
+ end
+
+ context "with multiline body" do
+ evaluate <<-ruby do
+ def m(n) =
+ if n > 2
+ m(n - 2) + m(n - 1)
+ else
+ 1
+ end
+ ruby
+
+ m(6).should == 8
+ end
+ end
- a = b = m 1
- a.should == 1
- b.should == 1
+ context "with args forwarding" do
+ evaluate <<-ruby do
+ def mm(word, num:)
+ word * num
+ end
+
+ def m(...) = mm(...) + mm(...)
+ ruby
+
+ m("meow", num: 2).should == "meow" * 4
+ end
+ end
+ end
+
+ describe "Keyword arguments are now separated from positional arguments" do
+ context "when the method has only positional parameters" do
+ it "treats incoming keyword arguments as positional for compatibility" do
+ def foo(a, b, c, hsh)
+ hsh[:key]
+ end
+
+ foo(1, 2, 3, key: 42).should == 42
+ end
+ end
+
+ context "when the method takes a ** parameter" do
+ it "captures the passed literal keyword arguments" do
+ def foo(a, b, c, **hsh)
+ hsh[:key]
+ end
+
+ foo(1, 2, 3, key: 42).should == 42
+ end
+
+ it "captures the passed ** keyword arguments" do
+ def foo(a, b, c, **hsh)
+ hsh[:key]
+ end
+
+ h = { key: 42 }
+ foo(1, 2, 3, **h).should == 42
+ end
+
+ it "does not convert a positional Hash to keyword arguments" do
+ def foo(a, b, c, **hsh)
+ hsh[:key]
+ end
+
+ -> {
+ foo(1, 2, 3, { key: 42 })
+ }.should raise_error(ArgumentError, 'wrong number of arguments (given 4, expected 3)')
+ end
+ end
+
+ context "when the method takes a key: parameter" do
+ context "when it's called with a positional Hash and no **" do
+ it "raises ArgumentError" do
+ def foo(a, b, c, key: 1)
+ key
+ end
+
+ -> {
+ foo(1, 2, 3, { key: 42 })
+ }.should raise_error(ArgumentError, 'wrong number of arguments (given 4, expected 3)')
+ end
+ end
+
+ context "when it's called with **" do
+ it "captures the passed keyword arguments" do
+ def foo(a, b, c, key: 1)
+ key
+ end
+
+ h = { key: 42 }
+ foo(1, 2, 3, **h).should == 42
+ end
+ end
+ end
+ end
+end
+
+ruby_version_is "3.1" do
+ describe "kwarg with omitted value in a method call" do
+ context "accepts short notation 'kwarg' in method call" do
+ evaluate <<-ruby do
+ def call(*args, **kwargs) = [args, kwargs]
+ ruby
+
+ a, b, c = 1, 2, 3
+ arr, h = eval('call a:')
+ h.should == {a: 1}
+ arr.should == []
+
+ arr, h = eval('call(a:, b:, c:)')
+ h.should == {a: 1, b: 2, c: 3}
+ arr.should == []
+
+ arr, h = eval('call(a:, b: 10, c:)')
+ h.should == {a: 1, b: 10, c: 3}
+ arr.should == []
+ end
+ end
+
+ context "with methods and local variables" do
+ evaluate <<-ruby do
+ def call(*args, **kwargs) = [args, kwargs]
+
+ def bar
+ "baz"
+ end
+
+ def foo(val)
+ call bar:, val:
+ end
+ ruby
+
+ foo(1).should == [[], {bar: "baz", val: 1}]
+ end
end
end
end
diff --git a/spec/ruby/language/pattern_matching_spec.rb b/spec/ruby/language/pattern_matching_spec.rb
index c6a3008458..e4abae9412 100644
--- a/spec/ruby/language/pattern_matching_spec.rb
+++ b/spec/ruby/language/pattern_matching_spec.rb
@@ -18,6 +18,63 @@ ruby_version_is "2.7" do
RUBY
end
end
+
+ describe "find pattern" do
+ it "captures preceding elements to the pattern" do
+ eval(<<~RUBY).should == [0, 1]
+ case [0, 1, 2, 3]
+ in [*pre, 2, 3]
+ pre
+ else
+ false
+ end
+ RUBY
+ end
+
+ it "captures following elements to the pattern" do
+ eval(<<~RUBY).should == [2, 3]
+ case [0, 1, 2, 3]
+ in [0, 1, *post]
+ post
+ else
+ false
+ end
+ RUBY
+ end
+
+ it "captures both preceding and following elements to the pattern" do
+ eval(<<~RUBY).should == [[0, 1], [3, 4]]
+ case [0, 1, 2, 3, 4]
+ in [*pre, 2, *post]
+ [pre, post]
+ else
+ false
+ end
+ RUBY
+ end
+
+ it "can capture the entirety of the pattern" do
+ eval(<<~RUBY).should == [0, 1, 2, 3, 4]
+ case [0, 1, 2, 3, 4]
+ in [*everything]
+ everything
+ else
+ false
+ end
+ RUBY
+ end
+
+ it "will match an empty Array-like structure" do
+ eval(<<~RUBY).should == []
+ case []
+ in [*everything]
+ everything
+ else
+ false
+ end
+ RUBY
+ end
+ end
end
it "extends case expression with case/in construction" do
@@ -41,25 +98,49 @@ ruby_version_is "2.7" do
end
describe "warning" do
- ruby_version_is ""..."3.1" do
+ before :each do
+ @experimental, Warning[:experimental] = Warning[:experimental], true
+ end
+
+ after :each do
+ Warning[:experimental] = @experimental
+ end
+
+ context 'when regular form' do
before :each do
- ruby_version_is ""..."3.0" do
- @src = 'case [0, 1]; in [a, b]; end'
- end
+ @src = 'case [0, 1]; in [a, b]; end'
+ end
- ruby_version_is "3.0" do
- @src = '[0, 1] => [a, b]'
+ ruby_version_is ""..."3.0" do
+ it "warns about pattern matching is experimental feature" do
+ -> { eval @src }.should complain(/pattern matching is experimental, and the behavior may change in future versions of Ruby!/i)
end
-
- @experimental, Warning[:experimental] = Warning[:experimental], true
end
- after :each do
- Warning[:experimental] = @experimental
+ ruby_version_is "3.0" do
+ it "does not warn about pattern matching is experimental feature" do
+ -> { eval @src }.should_not complain
+ end
end
+ end
+
+ context 'when one-line form' do
+ ruby_version_is '3.0' do
+ before :each do
+ @src = '[0, 1] => [a, b]'
+ end
+
+ ruby_version_is ""..."3.1" do
+ it "warns about pattern matching is experimental feature" do
+ -> { eval @src }.should complain(/pattern matching is experimental, and the behavior may change in future versions of Ruby!/i)
+ end
+ end
- it "warns about pattern matching is experimental feature" do
- -> { eval @src }.should complain(/pattern matching is experimental, and the behavior may change in future versions of Ruby!/i)
+ ruby_version_is "3.1" do
+ it "does not warn about pattern matching is experimental feature" do
+ -> { eval @src }.should_not complain
+ end
+ end
end
end
end
@@ -444,6 +525,28 @@ ruby_version_is "2.7" do
end
RUBY
end
+
+ it "can be used as a nested pattern" do
+ eval(<<~RUBY).should == true
+ case [[1], ["2"]]
+ in [[0] | nil, _]
+ false
+ in [[1], [1]]
+ false
+ in [[1], [2 | "2"]]
+ true
+ end
+ RUBY
+
+ eval(<<~RUBY).should == true
+ case [1, 2]
+ in [0, _] | {a: 0}
+ false
+ in {a: 1, b: 2} | [1, 2]
+ true
+ end
+ RUBY
+ end
end
describe "AS pattern" do
@@ -705,6 +808,28 @@ ruby_version_is "2.7" do
end
RUBY
end
+
+ it "can be used as a nested pattern" do
+ eval(<<~RUBY).should == true
+ case [[1], ["2"]]
+ in [[0] | nil, _]
+ false
+ in [[1], [1]]
+ false
+ in [[1], [2 | "2"]]
+ true
+ end
+ RUBY
+
+ eval(<<~RUBY).should == true
+ case [1, 2]
+ in [0, _] | {a: 0}
+ false
+ in {a: 1, b: 2} | [1, 2]
+ true
+ end
+ RUBY
+ end
end
describe "Hash pattern" do
@@ -1060,6 +1185,30 @@ ruby_version_is "2.7" do
end
RUBY
end
+
+ it "can be used as a nested pattern" do
+ eval(<<~RUBY).should == true
+ case {a: {a: 1, b: 1}, b: {a: 1, b: 2}}
+ in {a: {a: 0}}
+ false
+ in {a: {a: 1}, b: {b: 1}}
+ false
+ in {a: {a: 1}, b: {b: 2}}
+ true
+ end
+ RUBY
+
+ eval(<<~RUBY).should == true
+ case [{a: 1, b: [1]}, {a: 1, c: ["2"]}]
+ in [{a:, c:},]
+ false
+ in [{a: 1, b:}, {a: 1, c: [Integer]}]
+ false
+ in [_, {a: 1, c: [String]}]
+ true
+ end
+ RUBY
+ end
end
describe "refinements" do
diff --git a/spec/ruby/language/proc_spec.rb b/spec/ruby/language/proc_spec.rb
index c44e711d2b..ef4a43bed6 100644
--- a/spec/ruby/language/proc_spec.rb
+++ b/spec/ruby/language/proc_spec.rb
@@ -217,4 +217,30 @@ describe "A Proc" do
lambda { @l.call(obj) }.should raise_error(TypeError)
end
end
+
+ describe "taking |*a, **kw| arguments" do
+ before :each do
+ @p = proc { |*a, **kw| [a, kw] }
+ end
+
+ ruby_version_is ""..."2.7" do
+ it 'autosplats keyword arguments' do
+ @p.call([1, {a: 1}]).should == [[1], {a: 1}]
+ end
+ end
+
+ ruby_version_is "2.7"..."3.0" do
+ it 'autosplats keyword arguments and warns' do
+ -> {
+ @p.call([1, {a: 1}]).should == [[1], {a: 1}]
+ }.should complain(/warning: Using the last argument as keyword parameters is deprecated; maybe \*\* should be added to the call/)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it 'does not autosplat keyword arguments' do
+ @p.call([1, {a: 1}]).should == [[[1, {a: 1}]], {}]
+ end
+ end
+ end
end
diff --git a/spec/ruby/language/range_spec.rb b/spec/ruby/language/range_spec.rb
index 79500c6b33..4cde7e9488 100644
--- a/spec/ruby/language/range_spec.rb
+++ b/spec/ruby/language/range_spec.rb
@@ -15,6 +15,12 @@ describe "Literal Ranges" do
(1...).should == Range.new(1, nil, true)
end
+ ruby_version_is "3.0" do
+ it "is frozen" do
+ (42..).should.frozen?
+ end
+ end
+
ruby_version_is "2.7" do
it "creates beginless ranges" do
eval("(..1)").should == Range.new(nil, 1)
diff --git a/spec/ruby/language/singleton_class_spec.rb b/spec/ruby/language/singleton_class_spec.rb
index 7e9370d6f9..c1fb682ea0 100644
--- a/spec/ruby/language/singleton_class_spec.rb
+++ b/spec/ruby/language/singleton_class_spec.rb
@@ -157,23 +157,6 @@ describe "A constant on a singleton class" do
end
end
-describe "Defining yield in singleton class" do
- ruby_version_is "2.7"..."3.0" do
- it 'emits a deprecation warning' do
- code = <<~RUBY
- def m
- class << Object.new
- yield
- end
- end
- m { :ok }
- RUBY
-
- -> { eval(code) }.should complain(/warning: `yield' in class syntax will not be supported from Ruby 3.0/)
- end
- end
-end
-
describe "Defining instance methods on a singleton class" do
before :each do
@k = ClassSpecs::K.new
diff --git a/spec/ruby/language/yield_spec.rb b/spec/ruby/language/yield_spec.rb
index 5fad7cb176..3db6d353a9 100644
--- a/spec/ruby/language/yield_spec.rb
+++ b/spec/ruby/language/yield_spec.rb
@@ -183,5 +183,33 @@ describe "The yield call" do
it "uses captured block of a block used in define_method" do
@y.deep(2).should == 4
end
+end
+
+describe "Using yield in a singleton class literal" do
+ ruby_version_is "2.7"..."3.0" do
+ it 'emits a deprecation warning' do
+ code = <<~RUBY
+ def m
+ class << Object.new
+ yield
+ end
+ end
+ m { :ok }
+ RUBY
+
+ -> { eval(code) }.should complain(/warning: `yield' in class syntax will not be supported from Ruby 3.0/)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it 'raises a SyntaxError' do
+ code = <<~RUBY
+ class << Object.new
+ yield
+ end
+ RUBY
+ -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/)
+ end
+ end
end
diff --git a/spec/ruby/library/ipaddr/new_spec.rb b/spec/ruby/library/ipaddr/new_spec.rb
index 053928c3cf..3148d6e39c 100644
--- a/spec/ruby/library/ipaddr/new_spec.rb
+++ b/spec/ruby/library/ipaddr/new_spec.rb
@@ -77,34 +77,17 @@ describe "IPAddr#new" do
a.family.should == Socket::AF_INET6
end
- ruby_version_is ""..."3.1" do
- it "raises on incorrect IPAddr strings" do
- [
- ["fe80::1%fxp0"],
- ["::1/255.255.255.0"],
- [IPAddr.new("::1").to_i],
- ["::ffff:192.168.1.2/120", Socket::AF_INET],
- ["[192.168.1.2]/120"],
- ].each { |args|
- ->{
- IPAddr.new(*args)
- }.should raise_error(ArgumentError)
- }
- end
- end
-
- ruby_version_is "3.1" do
- it "raises on incorrect IPAddr strings" do
- [
- ["::1/255.255.255.0"],
- [IPAddr.new("::1").to_i],
- ["::ffff:192.168.1.2/120", Socket::AF_INET],
- ["[192.168.1.2]/120"],
- ].each { |args|
- ->{
- IPAddr.new(*args)
- }.should raise_error(ArgumentError)
- }
- end
+ it "raises on incorrect IPAddr strings" do
+ [
+ ["fe80::1%fxp0"],
+ ["::1/255.255.255.0"],
+ [IPAddr.new("::1").to_i],
+ ["::ffff:192.168.1.2/120", Socket::AF_INET],
+ ["[192.168.1.2]/120"],
+ ].each { |args|
+ ->{
+ IPAddr.new(*args)
+ }.should raise_error(ArgumentError)
+ }
end
end
diff --git a/spec/ruby/library/set/comparison_spec.rb b/spec/ruby/library/set/comparison_spec.rb
new file mode 100644
index 0000000000..b851ea3d57
--- /dev/null
+++ b/spec/ruby/library/set/comparison_spec.rb
@@ -0,0 +1,29 @@
+require_relative '../../spec_helper'
+require 'set'
+
+ruby_version_is "3.0" do
+ describe "Set#<=>" do
+ it "returns 0 if the sets are equal" do
+ (Set[] <=> Set[]).should == 0
+ (Set[:a, :b, :c] <=> Set[:a, :b, :c]).should == 0
+ end
+
+ it "returns -1 if the set is a proper subset of the other set" do
+ (Set[] <=> Set[1]).should == -1
+ (Set[1, 2] <=> Set[1, 2, 3]).should == -1
+ end
+
+ it "returns +1 if the set is a proper superset of other set" do
+ (Set[1] <=> Set[]).should == +1
+ (Set[1, 2, 3] <=> Set[1, 2]).should == +1
+ end
+
+ it "returns nil if the set has unique elements" do
+ (Set[1, 2, 3] <=> Set[:a, :b, :c]).should be_nil
+ end
+
+ it "returns nil when the argument is not set-like" do
+ (Set[] <=> false).should be_nil
+ end
+ end
+end
diff --git a/spec/ruby/library/set/initialize_clone_spec.rb b/spec/ruby/library/set/initialize_clone_spec.rb
new file mode 100644
index 0000000000..62985987fa
--- /dev/null
+++ b/spec/ruby/library/set/initialize_clone_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../spec_helper'
+require 'set'
+
+describe "Set#initialize_clone" do
+ ruby_version_is "3.0" do
+ # See https://bugs.ruby-lang.org/issues/14266
+ it "does not freeze the new Set when called from clone(freeze: false)" do
+ set1 = Set[1, 2]
+ set1.freeze
+ set2 = set1.clone(freeze: false)
+ set1.frozen?.should == true
+ set2.frozen?.should == false
+ set2.add 3
+ set1.should == Set[1, 2]
+ set2.should == Set[1, 2, 3]
+ end
+ end
+end
diff --git a/spec/ruby/library/set/join_spec.rb b/spec/ruby/library/set/join_spec.rb
new file mode 100644
index 0000000000..7498a91d98
--- /dev/null
+++ b/spec/ruby/library/set/join_spec.rb
@@ -0,0 +1,31 @@
+require_relative '../../spec_helper'
+require 'set'
+
+ruby_version_is "3.0" do
+ describe "Set#join" do
+ it "returns an empty string if the Set is empty" do
+ Set[].join.should == ''
+ end
+
+ it "returns a new string formed by joining elements after conversion" do
+ set = Set[:a, :b, :c]
+ set.join.should == "abc"
+ end
+
+ it "does not separate elements when the passed separator is nil" do
+ set = Set[:a, :b, :c]
+ set.join(nil).should == "abc"
+ end
+
+ it "returns a string formed by concatenating each element separated by the separator" do
+ set = Set[:a, :b, :c]
+ set.join(' | ').should == "a | b | c"
+ end
+
+ it "calls #to_a to convert the Set in to an Array" do
+ set = Set[:a, :b, :c]
+ set.should_receive(:to_a).and_return([:a, :b, :c])
+ set.join.should == "abc"
+ end
+ end
+end
diff --git a/spec/ruby/library/set/sortedset/sortedset_spec.rb b/spec/ruby/library/set/sortedset/sortedset_spec.rb
new file mode 100644
index 0000000000..3ead5495fc
--- /dev/null
+++ b/spec/ruby/library/set/sortedset/sortedset_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+require 'set'
+
+ruby_version_is "3.0" do
+ describe "SortedSet" do
+ it "raises error including message that it has been extracted from the set stdlib" do
+ -> {
+ SortedSet
+ }.should raise_error(RuntimeError) { |e|
+ e.message.should.include?("The `SortedSet` class has been extracted from the `set` library")
+ }
+ end
+ end
+end
+
+ruby_version_is ""..."3.0" do
+ describe "SortedSet" do
+ it "is part of the set stdlib" do
+ SortedSet.superclass.should == Set
+ end
+ end
+end
diff --git a/spec/ruby/library/socket/tcpsocket/initialize_spec.rb b/spec/ruby/library/socket/tcpsocket/initialize_spec.rb
index a3cee05412..065c8f4190 100644
--- a/spec/ruby/library/socket/tcpsocket/initialize_spec.rb
+++ b/spec/ruby/library/socket/tcpsocket/initialize_spec.rb
@@ -1,5 +1,10 @@
require_relative '../spec_helper'
require_relative '../fixtures/classes'
+require_relative 'shared/new'
+
+describe 'TCPSocket#initialize' do
+ it_behaves_like :tcpsocket_new, :new
+end
describe 'TCPSocket#initialize' do
SocketSpecs.each_ip_protocol do |family, ip_address|
diff --git a/spec/ruby/library/socket/tcpsocket/new_spec.rb b/spec/ruby/library/socket/tcpsocket/new_spec.rb
deleted file mode 100644
index 4924468be7..0000000000
--- a/spec/ruby/library/socket/tcpsocket/new_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require_relative 'shared/new'
-
-describe "TCPSocket.new" do
- it_behaves_like :tcpsocket_new, :new
-end
diff --git a/spec/ruby/library/socket/tcpsocket/shared/new.rb b/spec/ruby/library/socket/tcpsocket/shared/new.rb
index 5ca3a0e6cc..4189acc2f8 100644
--- a/spec/ruby/library/socket/tcpsocket/shared/new.rb
+++ b/spec/ruby/library/socket/tcpsocket/shared/new.rb
@@ -14,6 +14,14 @@ describe :tcpsocket_new, shared: true do
}
end
+ ruby_version_is "3.0" do
+ it 'raises Errno::ETIMEDOUT with :connect_timeout when no server is listening on the given address' do
+ -> {
+ TCPSocket.send(@method, "192.0.2.1", 80, connect_timeout: 0)
+ }.should raise_error(Errno::ETIMEDOUT)
+ end
+ end
+
describe "with a running server" do
before :each do
@server = SocketSpecs::SpecTCPServer.new
@@ -75,5 +83,12 @@ describe :tcpsocket_new, shared: true do
@socket.addr[1].should be_kind_of(Integer)
@socket.addr[2].should =~ /^#{@hostname}/
end
+
+ ruby_version_is "3.0" do
+ it "connects to a server when passed connect_timeout argument" do
+ @socket = TCPSocket.send(@method, @hostname, @server.port, connect_timeout: 1)
+ @socket.should be_an_instance_of(TCPSocket)
+ end
+ end
end
end
diff --git a/spec/ruby/library/stringio/ungetbyte_spec.rb b/spec/ruby/library/stringio/ungetbyte_spec.rb
index 2f082acbf6..eb1cc55220 100644
--- a/spec/ruby/library/stringio/ungetbyte_spec.rb
+++ b/spec/ruby/library/stringio/ungetbyte_spec.rb
@@ -30,7 +30,7 @@ describe "StringIO#ungetbyte" do
io.string.should == 'Shis is a simple string.'
end
- it "ungets the bytes of a string if given a string as an argument" do
+ it "ungets the bytes of a string if given a string as an arugment" do
str = "\u01a9"
io = StringIO.new(str)
b = io.getbyte
diff --git a/spec/ruby/security/cve_2010_1330_spec.rb b/spec/ruby/security/cve_2010_1330_spec.rb
index fa4c756c6d..33e88d652e 100644
--- a/spec/ruby/security/cve_2010_1330_spec.rb
+++ b/spec/ruby/security/cve_2010_1330_spec.rb
@@ -1,7 +1,6 @@
require_relative '../spec_helper'
describe "String#gsub" do
-
it "resists CVE-2010-1330 by raising an exception on invalid UTF-8 bytes" do
# This original vulnerability talked about KCODE, which is no longer
# used. Instead we are forcing encodings here. But I think the idea is the
@@ -17,5 +16,4 @@ describe "String#gsub" do
str.gsub(/</, "&lt;")
}.should raise_error(ArgumentError, /invalid byte sequence in UTF-8/)
end
-
end
diff --git a/spec/ruby/security/cve_2013_4164_spec.rb b/spec/ruby/security/cve_2013_4164_spec.rb
index 94578cc7ce..d223b8fd5e 100644
--- a/spec/ruby/security/cve_2013_4164_spec.rb
+++ b/spec/ruby/security/cve_2013_4164_spec.rb
@@ -3,17 +3,13 @@ require_relative '../spec_helper'
require 'json'
describe "String#to_f" do
-
it "resists CVE-2013-4164 by converting very long Strings to a Float" do
"1.#{'1'*1000000}".to_f.should be_close(1.1111111111111112, TOLERANCE)
end
-
end
describe "JSON.parse" do
-
it "resists CVE-2013-4164 by converting very long Strings to a Float" do
JSON.parse("[1.#{'1'*1000000}]").first.should be_close(1.1111111111111112, TOLERANCE)
end
-
end
diff --git a/spec/ruby/security/cve_2014_8080_spec.rb b/spec/ruby/security/cve_2014_8080_spec.rb
index a3f4483994..23770f94b1 100644
--- a/spec/ruby/security/cve_2014_8080_spec.rb
+++ b/spec/ruby/security/cve_2014_8080_spec.rb
@@ -1,6 +1,5 @@
require_relative '../spec_helper'
-
ruby_version_is ''...'3.0' do
require 'rexml/document'
diff --git a/spec/ruby/security/cve_2018_16396_spec.rb b/spec/ruby/security/cve_2018_16396_spec.rb
index 303c47a8c7..c9624e9c63 100644
--- a/spec/ruby/security/cve_2018_16396_spec.rb
+++ b/spec/ruby/security/cve_2018_16396_spec.rb
@@ -1,7 +1,6 @@
require_relative '../spec_helper'
describe "Array#pack" do
-
ruby_version_is ''...'2.7' do
it "resists CVE-2018-16396 by tainting output based on input" do
"aAZBbHhuMmPp".each_char do |f|
@@ -9,11 +8,9 @@ describe "Array#pack" do
end
end
end
-
end
describe "String#unpack" do
-
ruby_version_is ''...'2.7' do
it "resists CVE-2018-16396 by tainting output based on input" do
"aAZBbHhuMm".each_char do |f|
@@ -21,5 +18,4 @@ describe "String#unpack" do
end
end
end
-
end
diff --git a/spec/ruby/security/cve_2018_8778_spec.rb b/spec/ruby/security/cve_2018_8778_spec.rb
index 628159a4db..62057faa53 100644
--- a/spec/ruby/security/cve_2018_8778_spec.rb
+++ b/spec/ruby/security/cve_2018_8778_spec.rb
@@ -1,12 +1,10 @@
require_relative '../spec_helper'
describe "String#unpack" do
-
it "resists CVE-2018-8778 by raising an exception when a position indicator is larger than a native integer" do
pos = (1 << PlatformGuard::POINTER_SIZE) - 99
-> {
"0123456789".unpack("@#{pos}C10")
}.should raise_error(RangeError, /pack length too big/)
end
-
end
diff --git a/spec/ruby/security/cve_2019_8323_spec.rb b/spec/ruby/security/cve_2019_8323_spec.rb
index d4606de054..3632d3b028 100644
--- a/spec/ruby/security/cve_2019_8323_spec.rb
+++ b/spec/ruby/security/cve_2019_8323_spec.rb
@@ -1,36 +1,38 @@
require_relative '../spec_helper'
-require 'optparse'
+platform_is_not :darwin do # frequent timeout/hang on macOS
+ require 'optparse'
-require 'rubygems'
-require 'rubygems/gemcutter_utilities'
+ require 'rubygems'
+ require 'rubygems/gemcutter_utilities'
-describe "CVE-2019-8323 is resisted by" do
- describe "sanitising the body" do
- it "for success codes" do
- cutter = Class.new {
- include Gem::GemcutterUtilities
- }.new
- response = Net::HTTPSuccess.new(nil, nil, nil)
- def response.body
- "\e]2;nyan\a"
+ describe "CVE-2019-8323 is resisted by" do
+ describe "sanitising the body" do
+ it "for success codes" do
+ cutter = Class.new {
+ include Gem::GemcutterUtilities
+ }.new
+ response = Net::HTTPSuccess.new(nil, nil, nil)
+ def response.body
+ "\e]2;nyan\a"
+ end
+ cutter.should_receive(:say).with(".]2;nyan.")
+ cutter.with_response response
end
- cutter.should_receive(:say).with(".]2;nyan.")
- cutter.with_response response
- end
- it "for error codes" do
- cutter = Class.new {
- include Gem::GemcutterUtilities
- }.new
- def cutter.terminate_interaction(n)
- end
- response = Net::HTTPNotFound.new(nil, nil, nil)
- def response.body
- "\e]2;nyan\a"
+ it "for error codes" do
+ cutter = Class.new {
+ include Gem::GemcutterUtilities
+ }.new
+ def cutter.terminate_interaction(n)
+ end
+ response = Net::HTTPNotFound.new(nil, nil, nil)
+ def response.body
+ "\e]2;nyan\a"
+ end
+ cutter.should_receive(:say).with(".]2;nyan.")
+ cutter.with_response response
end
- cutter.should_receive(:say).with(".]2;nyan.")
- cutter.with_response response
end
end
end
diff --git a/spec/ruby/security/cve_2019_8325_spec.rb b/spec/ruby/security/cve_2019_8325_spec.rb
index 935f127d7f..309445a50f 100644
--- a/spec/ruby/security/cve_2019_8325_spec.rb
+++ b/spec/ruby/security/cve_2019_8325_spec.rb
@@ -1,9 +1,9 @@
require_relative '../spec_helper'
-require 'rubygems'
-require 'rubygems/command_manager'
-
platform_is_not :darwin do # frequent timeout/hang on macOS
+ require 'rubygems'
+ require 'rubygems/command_manager'
+
describe "CVE-2019-8325 is resisted by" do
describe "sanitising error message components" do
it "for the 'while executing' message" do