summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/ruby/core/array/pack/a_spec.rb11
-rw-r--r--spec/ruby/core/array/pack/b_spec.rb7
-rw-r--r--spec/ruby/core/array/pack/h_spec.rb5
-rw-r--r--spec/ruby/core/array/pack/shared/float.rb8
-rw-r--r--spec/ruby/core/array/pack/u_spec.rb10
-rw-r--r--spec/ruby/core/array/pack/z_spec.rb10
-rw-r--r--spec/ruby/core/file/shared/fnmatch.rb8
-rw-r--r--spec/ruby/core/hash/to_a_spec.rb10
-rw-r--r--spec/ruby/core/hash/transform_keys_spec.rb4
-rw-r--r--spec/ruby/core/integer/constants_spec.rb20
-rw-r--r--spec/ruby/core/io/ungetc_spec.rb2
-rw-r--r--spec/ruby/core/kernel/match_spec.rb10
-rw-r--r--spec/ruby/core/math/log2_spec.rb2
-rw-r--r--spec/ruby/core/module/include_spec.rb21
-rw-r--r--spec/ruby/core/module/prepend_spec.rb2
-rw-r--r--spec/ruby/core/numeric/shared/step.rb1
-rw-r--r--spec/ruby/core/numeric/step_spec.rb2
-rw-r--r--spec/ruby/core/proc/compose_spec.rb8
-rw-r--r--spec/ruby/core/proc/eql_spec.rb2
-rw-r--r--spec/ruby/core/proc/equal_value_spec.rb2
-rw-r--r--spec/ruby/core/random/default_spec.rb32
-rw-r--r--spec/ruby/core/random/raw_seed_spec.rb6
-rw-r--r--spec/ruby/core/random/shared/urandom.rb23
-rw-r--r--spec/ruby/core/random/urandom_spec.rb25
-rw-r--r--spec/ruby/core/string/allocate_spec.rb2
-rw-r--r--spec/ruby/core/string/bytesize_spec.rb2
-rw-r--r--spec/ruby/core/string/element_set_spec.rb6
-rw-r--r--spec/ruby/core/string/shared/length.rb24
-rw-r--r--spec/ruby/core/string/split_spec.rb4
-rw-r--r--spec/ruby/fixtures/class.rb4
-rw-r--r--spec/ruby/language/case_spec.rb9
-rw-r--r--spec/ruby/language/class_spec.rb13
-rw-r--r--spec/ruby/language/constants_spec.rb14
-rw-r--r--spec/ruby/language/def_spec.rb2
-rw-r--r--spec/ruby/language/pattern_matching_spec.rb59
-rw-r--r--spec/ruby/language/variables_spec.rb21
-rw-r--r--spec/ruby/library/pp/pp_spec.rb7
-rw-r--r--spec/ruby/optional/capi/ext/proc_spec.c59
-rw-r--r--spec/ruby/optional/capi/ext/thread_spec.c36
-rw-r--r--spec/ruby/optional/capi/proc_spec.rb27
-rw-r--r--spec/ruby/optional/capi/thread_spec.rb10
-rw-r--r--spec/ruby/security/cve_2019_8322_spec.rb24
42 files changed, 470 insertions, 84 deletions
diff --git a/spec/ruby/core/array/pack/a_spec.rb b/spec/ruby/core/array/pack/a_spec.rb
index 7af7a16c68..f4a40502c2 100644
--- a/spec/ruby/core/array/pack/a_spec.rb
+++ b/spec/ruby/core/array/pack/a_spec.rb
@@ -12,6 +12,17 @@ describe "Array#pack with format 'A'" do
it_behaves_like :array_pack_string, 'A'
it_behaves_like :array_pack_taint, 'A'
+ it "calls #to_str to convert an Object to a String" do
+ obj = mock("pack A string")
+ obj.should_receive(:to_str).and_return("``abcdef")
+ [obj].pack("A*").should == "``abcdef"
+ end
+
+ it "will not implicitly convert a number to a string" do
+ -> { [0].pack('A') }.should raise_error(TypeError)
+ -> { [0].pack('a') }.should raise_error(TypeError)
+ end
+
it "adds all the bytes to the output when passed the '*' modifier" do
["abc"].pack("A*").should == "abc"
end
diff --git a/spec/ruby/core/array/pack/b_spec.rb b/spec/ruby/core/array/pack/b_spec.rb
index 872c1b88d5..ec82b7d1ab 100644
--- a/spec/ruby/core/array/pack/b_spec.rb
+++ b/spec/ruby/core/array/pack/b_spec.rb
@@ -13,11 +13,16 @@ describe "Array#pack with format 'B'" do
it_behaves_like :array_pack_taint, 'B'
it "calls #to_str to convert an Object to a String" do
- obj = mock("pack H string")
+ obj = mock("pack B string")
obj.should_receive(:to_str).and_return("``abcdef")
[obj].pack("B*").should == "\x2a"
end
+ it "will not implicitly convert a number to a string" do
+ -> { [0].pack('B') }.should raise_error(TypeError)
+ -> { [0].pack('b') }.should raise_error(TypeError)
+ end
+
it "encodes one bit for each character starting with the most significant bit" do
[ [["0"], "\x00"],
[["1"], "\x80"]
diff --git a/spec/ruby/core/array/pack/h_spec.rb b/spec/ruby/core/array/pack/h_spec.rb
index 85a875fc8b..2c1dac8d4a 100644
--- a/spec/ruby/core/array/pack/h_spec.rb
+++ b/spec/ruby/core/array/pack/h_spec.rb
@@ -18,6 +18,11 @@ describe "Array#pack with format 'H'" do
[obj].pack("H").should == "\xa0"
end
+ it "will not implicitly convert a number to a string" do
+ -> { [0].pack('H') }.should raise_error(TypeError)
+ -> { [0].pack('h') }.should raise_error(TypeError)
+ end
+
it "encodes the first character as the most significant nibble when passed no count modifier" do
["ab"].pack("H").should == "\xa0"
end
diff --git a/spec/ruby/core/array/pack/shared/float.rb b/spec/ruby/core/array/pack/shared/float.rb
index c6b194007f..ba174a071a 100644
--- a/spec/ruby/core/array/pack/shared/float.rb
+++ b/spec/ruby/core/array/pack/shared/float.rb
@@ -53,6 +53,14 @@ describe :array_pack_float_le, shared: true do
it "encodes a negative Float outside the range of a single precision float" do
[-1e150].pack(pack_format).should == "\x00\x00\x80\xff"
end
+
+ it "encodes a bignum as a float" do
+ [2 ** 65].pack(pack_format).should == [(2 ** 65).to_f].pack(pack_format)
+ end
+
+ it "encodes a rational as a float" do
+ [Rational(3, 4)].pack(pack_format).should == [Rational(3, 4).to_f].pack(pack_format)
+ end
end
describe :array_pack_float_be, shared: true do
diff --git a/spec/ruby/core/array/pack/u_spec.rb b/spec/ruby/core/array/pack/u_spec.rb
index fe969cbb2d..b20093a647 100644
--- a/spec/ruby/core/array/pack/u_spec.rb
+++ b/spec/ruby/core/array/pack/u_spec.rb
@@ -18,6 +18,16 @@ describe "Array#pack with format 'u'" do
it_behaves_like :array_pack_arguments, 'u'
it_behaves_like :array_pack_taint, 'u'
+ it "calls #to_str to convert an Object to a String" do
+ obj = mock("pack u string")
+ obj.should_receive(:to_str).and_return("``abcdef")
+ [obj].pack("u*").should == "(8&!A8F-D968`\n"
+ end
+
+ it "will not implicitly convert a number to a string" do
+ -> { [0].pack('u') }.should raise_error(TypeError)
+ end
+
it "encodes an empty string as an empty string" do
[""].pack("u").should == ""
end
diff --git a/spec/ruby/core/array/pack/z_spec.rb b/spec/ruby/core/array/pack/z_spec.rb
index 82ce7b4a1c..5ad3afd69e 100644
--- a/spec/ruby/core/array/pack/z_spec.rb
+++ b/spec/ruby/core/array/pack/z_spec.rb
@@ -12,6 +12,16 @@ describe "Array#pack with format 'Z'" do
it_behaves_like :array_pack_string, 'Z'
it_behaves_like :array_pack_taint, 'Z'
+ it "calls #to_str to convert an Object to a String" do
+ obj = mock("pack Z string")
+ obj.should_receive(:to_str).and_return("``abcdef")
+ [obj].pack("Z*").should == "``abcdef\x00"
+ end
+
+ it "will not implicitly convert a number to a string" do
+ -> { [0].pack('Z') }.should raise_error(TypeError)
+ end
+
it "adds all the bytes and appends a NULL byte when passed the '*' modifier" do
["abc"].pack("Z*").should == "abc\x00"
end
diff --git a/spec/ruby/core/file/shared/fnmatch.rb b/spec/ruby/core/file/shared/fnmatch.rb
index a8488fd30a..00682bb64c 100644
--- a/spec/ruby/core/file/shared/fnmatch.rb
+++ b/spec/ruby/core/file/shared/fnmatch.rb
@@ -75,6 +75,14 @@ describe :file_fnmatch, shared: true do
File.send(@method, 'c*t', 'c/a/b/t').should == true
end
+ it "does not match unterminated range of characters" do
+ File.send(@method, 'abc[de', 'abcd').should == false
+ end
+
+ it "does not match unterminated range of characters as a literal" do
+ File.send(@method, 'abc[de', 'abc[de').should == false
+ end
+
it "matches ranges of characters using bracket expression (e.g. [a-z])" do
File.send(@method, 'ca[a-z]', 'cat').should == true
end
diff --git a/spec/ruby/core/hash/to_a_spec.rb b/spec/ruby/core/hash/to_a_spec.rb
index 46f871389a..6f6f74f73b 100644
--- a/spec/ruby/core/hash/to_a_spec.rb
+++ b/spec/ruby/core/hash/to_a_spec.rb
@@ -36,4 +36,14 @@ describe "Hash#to_a" do
{}.untrust.to_a.untrusted?.should be_true
end
end
+
+ ruby_version_is '2.7'...'3.0' do
+ it "returns a not tainted array if self is tainted" do
+ {}.taint.to_a.tainted?.should be_false
+ end
+
+ it "returns a trusted array if self is untrusted" do
+ {}.untrust.to_a.untrusted?.should be_false
+ end
+ end
end
diff --git a/spec/ruby/core/hash/transform_keys_spec.rb b/spec/ruby/core/hash/transform_keys_spec.rb
index 8ee1a2cd6d..1e82ff6547 100644
--- a/spec/ruby/core/hash/transform_keys_spec.rb
+++ b/spec/ruby/core/hash/transform_keys_spec.rb
@@ -80,7 +80,7 @@ describe "Hash#transform_keys!" do
end
ruby_version_is ""..."3.0.2" do # https://bugs.ruby-lang.org/issues/17735
- it "returns the processed keys if we broke from the block" do
+ it "returns the processed keys if we break from the block" do
@hash.transform_keys! do |v|
break if v == :c
v.succ
@@ -90,7 +90,7 @@ describe "Hash#transform_keys!" do
end
ruby_version_is "3.0.2" do
- it "returns the processed keys and non evaluated keys if we broke from the block" do
+ it "returns the processed keys and non evaluated keys if we break from the block" do
@hash.transform_keys! do |v|
break if v == :c
v.succ
diff --git a/spec/ruby/core/integer/constants_spec.rb b/spec/ruby/core/integer/constants_spec.rb
index 2aaa659d5a..2077ad451e 100644
--- a/spec/ruby/core/integer/constants_spec.rb
+++ b/spec/ruby/core/integer/constants_spec.rb
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
-ruby_version_is ""..."3.1" do
- describe "Fixnum" do
+describe "Fixnum" do
+ ruby_version_is ""..."3.2" do
it "is unified into Integer" do
suppress_warning do
Fixnum.should equal(Integer)
@@ -13,7 +13,15 @@ ruby_version_is ""..."3.1" do
end
end
- describe "Bignum" do
+ ruby_version_is "3.2" do
+ it "is no longer defined" do
+ Object.should_not.const_defined?(:Fixnum)
+ end
+ end
+end
+
+describe "Bignum" do
+ ruby_version_is ""..."3.2" do
it "is unified into Integer" do
suppress_warning do
Bignum.should equal(Integer)
@@ -24,4 +32,10 @@ ruby_version_is ""..."3.1" do
-> { Bignum }.should complain(/constant ::Bignum is deprecated/)
end
end
+
+ ruby_version_is "3.2" do
+ it "is no longer defined" do
+ Object.should_not.const_defined?(:Bignum)
+ end
+ end
end
diff --git a/spec/ruby/core/io/ungetc_spec.rb b/spec/ruby/core/io/ungetc_spec.rb
index a05d80ee9c..41a455c836 100644
--- a/spec/ruby/core/io/ungetc_spec.rb
+++ b/spec/ruby/core/io/ungetc_spec.rb
@@ -103,7 +103,7 @@ describe "IO#ungetc" do
-> { @io.sysread(1) }.should raise_error(IOError)
end
- ruby_version_is "0"..."3.0" do
+ ruby_version_is ""..."3.0" do
it "does not affect the stream and returns nil when passed nil" do
@io.getc.should == ?V
@io.ungetc(nil)
diff --git a/spec/ruby/core/kernel/match_spec.rb b/spec/ruby/core/kernel/match_spec.rb
index 6c81ed8256..aa25006163 100644
--- a/spec/ruby/core/kernel/match_spec.rb
+++ b/spec/ruby/core/kernel/match_spec.rb
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
-ruby_version_is ''...'3.2' do
- describe "Kernel#=~" do
+describe "Kernel#=~" do
+ ruby_version_is ''...'3.2' do
it "returns nil matching any object" do
o = Object.new
@@ -21,4 +21,10 @@ ruby_version_is ''...'3.2' do
end.should complain(/deprecated Object#=~ is called on Object/, verbose: true)
end
end
+
+ ruby_version_is '3.2' do
+ it "is no longer defined" do
+ Object.new.should_not.respond_to?(:=~)
+ end
+ end
end
diff --git a/spec/ruby/core/math/log2_spec.rb b/spec/ruby/core/math/log2_spec.rb
index 1594f2d7af..3d4d41d130 100644
--- a/spec/ruby/core/math/log2_spec.rb
+++ b/spec/ruby/core/math/log2_spec.rb
@@ -15,7 +15,7 @@ describe "Math.log2" do
Math.log2((2**301+45677544234809571)).should == 301.0
end
- it "raises an Errno::EDOM if the argument is less than 0" do
+ it "raises Math::DomainError if the argument is less than 0" do
-> { Math.log2(-1e-15) }.should raise_error( Math::DomainError)
end
diff --git a/spec/ruby/core/module/include_spec.rb b/spec/ruby/core/module/include_spec.rb
index 128b9af2bf..c47e052d22 100644
--- a/spec/ruby/core/module/include_spec.rb
+++ b/spec/ruby/core/module/include_spec.rb
@@ -532,6 +532,27 @@ describe "Module#include" do
B.foo.should == 'n'
end
end
+
+ it "overrides a previous super method call" do
+ c1 = Class.new do
+ def foo
+ [:c1]
+ end
+ end
+ c2 = Class.new(c1) do
+ def foo
+ [:c2] + super
+ end
+ end
+ c2.new.foo.should == [:c2, :c1]
+ m = Module.new do
+ def foo
+ [:m1]
+ end
+ end
+ c2.include(m)
+ c2.new.foo.should == [:c2, :m1]
+ end
end
describe "Module#include?" do
diff --git a/spec/ruby/core/module/prepend_spec.rb b/spec/ruby/core/module/prepend_spec.rb
index 04cc27d472..d636e023ed 100644
--- a/spec/ruby/core/module/prepend_spec.rb
+++ b/spec/ruby/core/module/prepend_spec.rb
@@ -499,7 +499,7 @@ describe "Module#prepend" do
c.dup.new.should be_kind_of(m)
end
- ruby_version_is '0'...'3.0' do
+ ruby_version_is ''...'3.0' do
it "keeps the module in the chain when dupping an intermediate module" do
m1 = Module.new { def calc(x) x end }
m2 = Module.new { prepend(m1) }
diff --git a/spec/ruby/core/numeric/shared/step.rb b/spec/ruby/core/numeric/shared/step.rb
index a4fe74f9db..8b1a7bf307 100644
--- a/spec/ruby/core/numeric/shared/step.rb
+++ b/spec/ruby/core/numeric/shared/step.rb
@@ -256,7 +256,6 @@ describe :numeric_step, :shared => true do
end
describe "when no block is given" do
- step_enum_class = Enumerator
step_enum_class = Enumerator::ArithmeticSequence
ruby_version_is ""..."3.0" do
diff --git a/spec/ruby/core/numeric/step_spec.rb b/spec/ruby/core/numeric/step_spec.rb
index 03af8b0e4d..095c474fec 100644
--- a/spec/ruby/core/numeric/step_spec.rb
+++ b/spec/ruby/core/numeric/step_spec.rb
@@ -21,7 +21,6 @@ describe "Numeric#step" do
it_behaves_like :numeric_step, :step
describe "when no block is given" do
- step_enum_class = Enumerator
step_enum_class = Enumerator::ArithmeticSequence
ruby_version_is ""..."3.0" do
@@ -61,7 +60,6 @@ describe "Numeric#step" do
end
end
end
-
end
describe 'with keyword arguments' do
diff --git a/spec/ruby/core/proc/compose_spec.rb b/spec/ruby/core/proc/compose_spec.rb
index 803a32af7b..94814d11bc 100644
--- a/spec/ruby/core/proc/compose_spec.rb
+++ b/spec/ruby/core/proc/compose_spec.rb
@@ -61,9 +61,17 @@ describe "Proc#<<" do
g = proc { |x| x + x }
lambda_proc = -> x { x }
+ # lambda << proc
(f << g).is_a?(Proc).should == true
(f << g).should_not.lambda?
+
+ # lambda << lambda
+ (f << lambda_proc).is_a?(Proc).should == true
(f << lambda_proc).should.lambda?
+
+ # proc << lambda
+ (g << f).is_a?(Proc).should == true
+ (g << f).should.lambda?
end
end
diff --git a/spec/ruby/core/proc/eql_spec.rb b/spec/ruby/core/proc/eql_spec.rb
index 5f38af72d9..06aee272e5 100644
--- a/spec/ruby/core/proc/eql_spec.rb
+++ b/spec/ruby/core/proc/eql_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/equal'
describe "Proc#eql?" do
- ruby_version_is "0"..."3.0" do
+ ruby_version_is ""..."3.0" do
it_behaves_like :proc_equal_undefined, :eql?
end
diff --git a/spec/ruby/core/proc/equal_value_spec.rb b/spec/ruby/core/proc/equal_value_spec.rb
index 4c336331d7..ee88c0537d 100644
--- a/spec/ruby/core/proc/equal_value_spec.rb
+++ b/spec/ruby/core/proc/equal_value_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/equal'
describe "Proc#==" do
- ruby_version_is "0"..."3.0" do
+ ruby_version_is ""..."3.0" do
it_behaves_like :proc_equal_undefined, :==
end
diff --git a/spec/ruby/core/random/default_spec.rb b/spec/ruby/core/random/default_spec.rb
index f9270ac7bb..b4ffcb81f4 100644
--- a/spec/ruby/core/random/default_spec.rb
+++ b/spec/ruby/core/random/default_spec.rb
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
-ruby_version_is ''...'3.2' do
- describe "Random::DEFAULT" do
+describe "Random::DEFAULT" do
+ ruby_version_is ''...'3.2' do
it "returns a random number generator" do
suppress_warning do
Random::DEFAULT.should respond_to(:rand)
@@ -13,5 +13,33 @@ ruby_version_is ''...'3.2' do
seed2 = ruby_exe('p Random::DEFAULT.seed', options: '--disable-gems')
seed1.should != seed2
end
+
+ ruby_version_is ''...'3.0' do
+ it "returns a Random instance" do
+ suppress_warning do
+ Random::DEFAULT.should be_an_instance_of(Random)
+ end
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "refers to the Random class" do
+ suppress_warning do
+ Random::DEFAULT.should.equal?(Random)
+ end
+ end
+
+ it "is deprecated" do
+ -> {
+ Random::DEFAULT.should.equal?(Random)
+ }.should complain(/constant Random::DEFAULT is deprecated/)
+ end
+ end
+ end
+
+ ruby_version_is '3.2' do
+ it "is no longer defined" do
+ Random.should_not.const_defined?(:DEFAULT)
+ end
end
end
diff --git a/spec/ruby/core/random/raw_seed_spec.rb b/spec/ruby/core/random/raw_seed_spec.rb
deleted file mode 100644
index 0e40ed0796..0000000000
--- a/spec/ruby/core/random/raw_seed_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/urandom'
-
-describe "Random.urandom" do
- it_behaves_like :random_urandom, :urandom
-end
diff --git a/spec/ruby/core/random/shared/urandom.rb b/spec/ruby/core/random/shared/urandom.rb
deleted file mode 100644
index 159716075c..0000000000
--- a/spec/ruby/core/random/shared/urandom.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-describe :random_urandom, shared: true do
- it "returns a String" do
- Random.send(@method, 1).should be_an_instance_of(String)
- end
-
- it "returns a String of the length given as argument" do
- Random.send(@method, 15).length.should == 15
- end
-
- it "raises an ArgumentError on a negative size" do
- -> {
- Random.send(@method, -1)
- }.should raise_error(ArgumentError)
- end
-
- it "returns a binary String" do
- Random.send(@method, 15).encoding.should == Encoding::BINARY
- end
-
- it "returns a random binary String" do
- Random.send(@method, 12).should_not == Random.send(@method, 12)
- end
-end
diff --git a/spec/ruby/core/random/urandom_spec.rb b/spec/ruby/core/random/urandom_spec.rb
new file mode 100644
index 0000000000..6f180e54ac
--- /dev/null
+++ b/spec/ruby/core/random/urandom_spec.rb
@@ -0,0 +1,25 @@
+require_relative '../../spec_helper'
+
+describe "Random.urandom" do
+ it "returns a String" do
+ Random.urandom(1).should be_an_instance_of(String)
+ end
+
+ it "returns a String of the length given as argument" do
+ Random.urandom(15).length.should == 15
+ end
+
+ it "raises an ArgumentError on a negative size" do
+ -> {
+ Random.urandom(-1)
+ }.should raise_error(ArgumentError)
+ end
+
+ it "returns a binary String" do
+ Random.urandom(15).encoding.should == Encoding::BINARY
+ end
+
+ it "returns a random binary String" do
+ Random.urandom(12).should_not == Random.urandom(12)
+ end
+end
diff --git a/spec/ruby/core/string/allocate_spec.rb b/spec/ruby/core/string/allocate_spec.rb
index 5b36b4fd05..30d5f60594 100644
--- a/spec/ruby/core/string/allocate_spec.rb
+++ b/spec/ruby/core/string/allocate_spec.rb
@@ -14,6 +14,6 @@ describe "String.allocate" do
end
it "returns a binary String" do
- String.new.encoding.should == Encoding::BINARY
+ String.allocate.encoding.should == Encoding::BINARY
end
end
diff --git a/spec/ruby/core/string/bytesize_spec.rb b/spec/ruby/core/string/bytesize_spec.rb
index b8b07cfbec..a31f3ae671 100644
--- a/spec/ruby/core/string/bytesize_spec.rb
+++ b/spec/ruby/core/string/bytesize_spec.rb
@@ -2,7 +2,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe "#String#bytesize" do
+describe "String#bytesize" do
it "returns the length of self in bytes" do
"hello".bytesize.should == 5
" ".bytesize.should == 1
diff --git a/spec/ruby/core/string/element_set_spec.rb b/spec/ruby/core/string/element_set_spec.rb
index c9e02a7381..0aabbacd0e 100644
--- a/spec/ruby/core/string/element_set_spec.rb
+++ b/spec/ruby/core/string/element_set_spec.rb
@@ -141,6 +141,12 @@ describe "String#[]= with Integer index" do
str.encoding.should equal(Encoding::BINARY)
end
+ it "updates the string to a compatible encoding" do
+ str = " "
+ str[1] = [0xB9].pack("C*")
+ str.encoding.should == Encoding::ASCII_8BIT
+ end
+
it "raises an Encoding::CompatibilityError if the replacement encoding is incompatible" do
str = "あれ"
rep = "が".encode Encoding::EUC_JP
diff --git a/spec/ruby/core/string/shared/length.rb b/spec/ruby/core/string/shared/length.rb
index e931961455..94e5ec135b 100644
--- a/spec/ruby/core/string/shared/length.rb
+++ b/spec/ruby/core/string/shared/length.rb
@@ -12,9 +12,9 @@ describe :string_length, shared: true do
it "returns the length of a string in different encodings" do
utf8_str = 'こにちわ' * 100
- utf8_str.size.should == 400
- utf8_str.encode(Encoding::UTF_32BE).size.should == 400
- utf8_str.encode(Encoding::SHIFT_JIS).size.should == 400
+ utf8_str.send(@method).should == 400
+ utf8_str.encode(Encoding::UTF_32BE).send(@method).should == 400
+ utf8_str.encode(Encoding::SHIFT_JIS).send(@method).should == 400
end
it "returns the length of the new self after encoding is changed" do
@@ -32,24 +32,24 @@ describe :string_length, shared: true do
concat.encoding.should == Encoding::UTF_8
concat.bytesize.should == 4
- concat.size.should == 2
+ concat.send(@method).should == 2
concat.force_encoding(Encoding::ASCII_8BIT)
- concat.size.should == 4
+ concat.send(@method).should == 4
end
it "adds 1 for every invalid byte in UTF-8" do
- "\xF4\x90\x80\x80".size.should == 4
- "a\xF4\x90\x80\x80b".size.should == 6
- "é\xF4\x90\x80\x80è".size.should == 6
+ "\xF4\x90\x80\x80".send(@method).should == 4
+ "a\xF4\x90\x80\x80b".send(@method).should == 6
+ "é\xF4\x90\x80\x80è".send(@method).should == 6
end
it "adds 1 (and not 2) for a incomplete surrogate in UTF-16" do
- "\x00\xd8".force_encoding("UTF-16LE").size.should == 1
- "\xd8\x00".force_encoding("UTF-16BE").size.should == 1
+ "\x00\xd8".force_encoding("UTF-16LE").send(@method).should == 1
+ "\xd8\x00".force_encoding("UTF-16BE").send(@method).should == 1
end
it "adds 1 for a broken sequence in UTF-32" do
- "\x04\x03\x02\x01".force_encoding("UTF-32LE").size.should == 1
- "\x01\x02\x03\x04".force_encoding("UTF-32BE").size.should == 1
+ "\x04\x03\x02\x01".force_encoding("UTF-32LE").send(@method).should == 1
+ "\x01\x02\x03\x04".force_encoding("UTF-32BE").send(@method).should == 1
end
end
diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb
index a373be360d..94f6c9aaee 100644
--- a/spec/ruby/core/string/split_spec.rb
+++ b/spec/ruby/core/string/split_spec.rb
@@ -62,6 +62,10 @@ describe "String#split with String" do
",".split(",", -1).should == ["", ""]
end
+ it "raises a RangeError when the limit is larger than int" do
+ -> { "a,b".split(" ", 2147483649) }.should raise_error(RangeError)
+ end
+
it "defaults to $; when string isn't given or nil" do
suppress_warning do
old_fs = $;
diff --git a/spec/ruby/fixtures/class.rb b/spec/ruby/fixtures/class.rb
index 68fbca7ba7..98cb6c82a2 100644
--- a/spec/ruby/fixtures/class.rb
+++ b/spec/ruby/fixtures/class.rb
@@ -122,6 +122,10 @@ module ClassSpecs
end
end
end
+
+ DEFINE_CLASS = -> do
+ class ::A; end
+ end
end
class Class
diff --git a/spec/ruby/language/case_spec.rb b/spec/ruby/language/case_spec.rb
index 410cb9afb1..bf06803764 100644
--- a/spec/ruby/language/case_spec.rb
+++ b/spec/ruby/language/case_spec.rb
@@ -156,6 +156,15 @@ describe "The 'case'-construct" do
end.should == "foo"
end
+ it "tests an empty array" do
+ case []
+ when []
+ 'foo'
+ else
+ 'bar'
+ end.should == 'foo'
+ end
+
it "expands arrays to lists of values" do
case 'z'
when *['a', 'b', 'c', 'd']
diff --git a/spec/ruby/language/class_spec.rb b/spec/ruby/language/class_spec.rb
index 83db164e1a..877895bf15 100644
--- a/spec/ruby/language/class_spec.rb
+++ b/spec/ruby/language/class_spec.rb
@@ -17,6 +17,19 @@ describe "The class keyword" do
eval "class ClassSpecsKeywordWithoutSemicolon end"
ClassSpecsKeywordWithoutSemicolon.should be_an_instance_of(Class)
end
+
+ it "can redefine a class when called from a block" do
+ ClassSpecs::DEFINE_CLASS.call
+ A.should be_an_instance_of(Class)
+
+ Object.send(:remove_const, :A)
+ defined?(A).should be_nil
+
+ ClassSpecs::DEFINE_CLASS.call
+ A.should be_an_instance_of(Class)
+ ensure
+ Object.send(:remove_const, :A) if defined?(::A)
+ end
end
describe "A class definition" do
diff --git a/spec/ruby/language/constants_spec.rb b/spec/ruby/language/constants_spec.rb
index 03f1272401..bc76c60d20 100644
--- a/spec/ruby/language/constants_spec.rb
+++ b/spec/ruby/language/constants_spec.rb
@@ -718,3 +718,17 @@ describe 'Allowed characters' do
eval("mod::ἍBB").should == 1
end
end
+
+describe 'Assignment' do
+ context 'dynamic assignment' do
+ it 'raises SyntaxError' do
+ -> do
+ eval <<-CODE
+ def test
+ B = 1
+ end
+ CODE
+ end.should raise_error(SyntaxError, /dynamic constant assignment/)
+ end
+ end
+end
diff --git a/spec/ruby/language/def_spec.rb b/spec/ruby/language/def_spec.rb
index 6b0be19d90..d72f8fa888 100644
--- a/spec/ruby/language/def_spec.rb
+++ b/spec/ruby/language/def_spec.rb
@@ -213,7 +213,7 @@ describe "An instance method with a default argument" do
end
ruby_version_is '2.7' do
- it "raises a syntaxError an existing method with the same name as the local variable" do
+ it "raises a SyntaxError when there is an existing method with the same name as the local variable" do
def bar
1
end
diff --git a/spec/ruby/language/pattern_matching_spec.rb b/spec/ruby/language/pattern_matching_spec.rb
index e4abae9412..5f5e2f4902 100644
--- a/spec/ruby/language/pattern_matching_spec.rb
+++ b/spec/ruby/language/pattern_matching_spec.rb
@@ -1297,6 +1297,65 @@ ruby_version_is "2.7" do
a
RUBY
end
+
+ it "supports pinning instance variables" do
+ eval(<<~RUBY).should == true
+ @a = /a/
+ case 'abc'
+ in ^@a
+ true
+ end
+ RUBY
+ end
+
+ it "supports pinning class variables" do
+ result = nil
+ Module.new do
+ result = module_eval(<<~RUBY)
+ @@a = 0..10
+
+ case 2
+ in ^@@a
+ true
+ end
+ RUBY
+ end
+
+ result.should == true
+ end
+
+ it "supports pinning global variables" do
+ eval(<<~RUBY).should == true
+ $a = /a/
+ case 'abc'
+ in ^$a
+ true
+ end
+ RUBY
+ end
+
+ it "supports pinning expressions" do
+ eval(<<~RUBY).should == true
+ case 'abc'
+ in ^(/a/)
+ true
+ end
+ RUBY
+
+ eval(<<~RUBY).should == true
+ case {name: '2.6', released_at: Time.new(2018, 12, 25)}
+ in {released_at: ^(Time.new(2010)..Time.new(2020))}
+ true
+ end
+ RUBY
+
+ eval(<<~RUBY).should == true
+ case 0
+ in ^(0+0)
+ true
+ end
+ RUBY
+ end
end
end
end
diff --git a/spec/ruby/language/variables_spec.rb b/spec/ruby/language/variables_spec.rb
index 699187335c..431c5aca99 100644
--- a/spec/ruby/language/variables_spec.rb
+++ b/spec/ruby/language/variables_spec.rb
@@ -797,17 +797,6 @@ describe 'Local variable shadowing' do
end
describe 'Allowed characters' do
- # new feature in 2.6 -- https://bugs.ruby-lang.org/issues/13770
- it 'does not allow non-ASCII upcased characters at the beginning' do
- -> do
- eval <<-CODE
- def test
- ἍBB = 1
- end
- CODE
- end.should raise_error(SyntaxError, /dynamic constant assignment/)
- end
-
it 'allows non-ASCII lowercased characters at the beginning' do
result = nil
@@ -821,6 +810,16 @@ describe 'Allowed characters' do
result.should == 1
end
+
+ it 'parses a non-ASCII upcased character as a constant identifier' do
+ -> do
+ eval <<-CODE
+ def test
+ ἍBB = 1
+ end
+ CODE
+ end.should raise_error(SyntaxError, /dynamic constant assignment/)
+ end
end
describe "Instance variables" do
diff --git a/spec/ruby/library/pp/pp_spec.rb b/spec/ruby/library/pp/pp_spec.rb
index 06b22601d8..243478efd9 100644
--- a/spec/ruby/library/pp/pp_spec.rb
+++ b/spec/ruby/library/pp/pp_spec.rb
@@ -20,4 +20,11 @@ describe "PP.pp" do
other_out.to_s.should == "[1, 2, 3]\n"
end
+
+ it 'correctly prints a Hash' do
+ hash = { 'key' => 42 }
+ -> {
+ PP.pp hash
+ }.should output('{"key"=>42}' + "\n")
+ end
end
diff --git a/spec/ruby/optional/capi/ext/proc_spec.c b/spec/ruby/optional/capi/ext/proc_spec.c
index e0bd8b1bbc..1137f4156b 100644
--- a/spec/ruby/optional/capi/ext/proc_spec.c
+++ b/spec/ruby/optional/capi/ext/proc_spec.c
@@ -11,10 +11,63 @@ VALUE proc_spec_rb_proc_new_function(RB_BLOCK_CALL_FUNC_ARGLIST(args, dummy)) {
return rb_funcall(args, rb_intern("inspect"), 0);
}
+VALUE proc_spec_rb_proc_new_function_arg(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return arg;
+}
+
+VALUE proc_spec_rb_proc_new_function_argc(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return INT2FIX(argc);
+}
+
+VALUE proc_spec_rb_proc_new_function_argv_n(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ int n = FIX2INT(arg);
+ if (n < argc) {
+ return argv[n];
+ } else {
+ rb_exc_raise(rb_exc_new2(rb_eArgError, "Arg index out of bounds."));
+ }
+}
+
+VALUE proc_spec_rb_proc_new_function_callback_arg(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return callback_arg;
+}
+
+VALUE proc_spec_rb_proc_new_function_blockarg(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return blockarg;
+}
+
+VALUE proc_spec_rb_proc_new_function_block_given_p(VALUE arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg) {
+ return rb_block_given_p() ? Qtrue : Qfalse;
+}
+
VALUE proc_spec_rb_proc_new(VALUE self) {
return rb_proc_new(proc_spec_rb_proc_new_function, Qnil);
}
+VALUE proc_spec_rb_proc_new_arg(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_arg, Qnil);
+}
+
+VALUE proc_spec_rb_proc_new_argc(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_argc, Qnil);
+}
+
+VALUE proc_spec_rb_proc_new_argv_n(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_argv_n, Qnil);
+}
+
+VALUE proc_spec_rb_proc_new_callback_arg(VALUE self, VALUE arg) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_callback_arg, arg);
+}
+
+VALUE proc_spec_rb_proc_new_blockarg(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_blockarg, Qnil);
+}
+
+VALUE proc_spec_rb_proc_new_block_given_p(VALUE self) {
+ return rb_proc_new(proc_spec_rb_proc_new_function_block_given_p, Qnil);
+}
+
VALUE proc_spec_rb_proc_arity(VALUE self, VALUE prc) {
return INT2FIX(rb_proc_arity(prc));
}
@@ -62,6 +115,12 @@ VALUE proc_spec_rb_Proc_new(VALUE self, VALUE scenario) {
void Init_proc_spec(void) {
VALUE cls = rb_define_class("CApiProcSpecs", rb_cObject);
rb_define_method(cls, "rb_proc_new", proc_spec_rb_proc_new, 0);
+ rb_define_method(cls, "rb_proc_new_arg", proc_spec_rb_proc_new_arg, 0);
+ rb_define_method(cls, "rb_proc_new_argc", proc_spec_rb_proc_new_argc, 0);
+ rb_define_method(cls, "rb_proc_new_argv_n", proc_spec_rb_proc_new_argv_n, 0);
+ rb_define_method(cls, "rb_proc_new_callback_arg", proc_spec_rb_proc_new_callback_arg, 1);
+ rb_define_method(cls, "rb_proc_new_blockarg", proc_spec_rb_proc_new_blockarg, 0);
+ rb_define_method(cls, "rb_proc_new_block_given_p", proc_spec_rb_proc_new_block_given_p, 0);
rb_define_method(cls, "rb_proc_arity", proc_spec_rb_proc_arity, 1);
rb_define_method(cls, "rb_proc_call", proc_spec_rb_proc_call, 2);
rb_define_method(cls, "rb_Proc_new", proc_spec_rb_Proc_new, 1);
diff --git a/spec/ruby/optional/capi/ext/thread_spec.c b/spec/ruby/optional/capi/ext/thread_spec.c
index 21f98dec52..bab5fcc211 100644
--- a/spec/ruby/optional/capi/ext/thread_spec.c
+++ b/spec/ruby/optional/capi/ext/thread_spec.c
@@ -11,6 +11,10 @@
#define pipe(p) rb_w32_pipe(p)
#endif
+#ifndef _WIN32
+#include <pthread.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -131,6 +135,36 @@ static VALUE thread_spec_rb_thread_create(VALUE self, VALUE proc, VALUE arg) {
return rb_thread_create(thread_spec_call_proc, (void*)args);
}
+static VALUE thread_spec_ruby_native_thread_p(VALUE self) {
+ if (ruby_native_thread_p()) {
+ return Qtrue;
+ } else {
+ return Qfalse;
+ }
+}
+
+static VALUE false_result = Qfalse;
+static VALUE true_result = Qtrue;
+
+static void *new_thread_check(void *args) {
+ if (ruby_native_thread_p()) {
+ return &true_result;
+ } else {
+ return &false_result;
+ }
+}
+
+static VALUE thread_spec_ruby_native_thread_p_new_thread(VALUE self) {
+#ifndef _WIN32
+ pthread_t t;
+ VALUE *result = &true_result;
+ pthread_create(&t, NULL, new_thread_check, NULL);
+ pthread_join(t, (void **)&result);
+ return *result;
+#else
+ return Qfalse;
+#endif
+}
void Init_thread_spec(void) {
VALUE cls = rb_define_class("CApiThreadSpecs", rb_cObject);
@@ -143,6 +177,8 @@ void Init_thread_spec(void) {
rb_define_method(cls, "rb_thread_wakeup", thread_spec_rb_thread_wakeup, 1);
rb_define_method(cls, "rb_thread_wait_for", thread_spec_rb_thread_wait_for, 2);
rb_define_method(cls, "rb_thread_create", thread_spec_rb_thread_create, 2);
+ rb_define_method(cls, "ruby_native_thread_p", thread_spec_ruby_native_thread_p, 0);
+ rb_define_method(cls, "ruby_native_thread_p_new_thread", thread_spec_ruby_native_thread_p_new_thread, 0);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/proc_spec.rb b/spec/ruby/optional/capi/proc_spec.rb
index 6e797fdeb4..dab143fbe7 100644
--- a/spec/ruby/optional/capi/proc_spec.rb
+++ b/spec/ruby/optional/capi/proc_spec.rb
@@ -7,6 +7,8 @@ describe "C-API Proc function" do
before :each do
@p = CApiProcSpecs.new
@prc = @p.rb_proc_new
+ @prc2 = @p.rb_proc_new_argv_n
+ @prc3 = @p.rb_proc_new_argc
end
describe "rb_proc_new" do
@@ -15,6 +17,7 @@ describe "C-API Proc function" do
end
it "calls the C function wrapped by the Proc instance when sent #call" do
+ @p.rb_proc_new_arg.call().should == nil
@prc.call(:foo_bar).should == ":foo_bar"
@prc.call([:foo, :bar]).should == "[:foo, :bar]"
end
@@ -24,6 +27,30 @@ describe "C-API Proc function" do
@prc[[:foo, :bar]].should == "[:foo, :bar]"
end
+ it "calls the C function with the arg count in argc" do
+ @prc3.call().should == 0
+ @prc3.call(:foo).should == 1
+ @prc3.call(:foo, :bar).should == 2
+ end
+
+ it "calls the C function with arguments in argv" do
+ @prc2.call(1, :foo).should == :foo
+ @prc2.call(2, :foo, :bar).should == :bar
+ -> { @prc2.call(3, :foo, :bar) }.should raise_error(ArgumentError)
+ end
+
+ it "calls the C function with the block passed in blockarg" do
+ a_block = :foo.to_proc
+ @p.rb_proc_new_blockarg.call(&a_block).should == a_block
+ @p.rb_proc_new_blockarg.call().should == nil
+ end
+
+ it "calls the C function and yields to the block passed in blockarg" do
+ @p.rb_proc_new_block_given_p.call() do
+ end.should == false
+ @p.rb_proc_new_block_given_p.call().should == false
+ end
+
it "returns a Proc instance correctly described in #inspect without source location" do
@prc.inspect.should =~ /^#<Proc:([^ :@]*?)>$/
end
diff --git a/spec/ruby/optional/capi/thread_spec.rb b/spec/ruby/optional/capi/thread_spec.rb
index 30e29681eb..5cb46bbb7c 100644
--- a/spec/ruby/optional/capi/thread_spec.rb
+++ b/spec/ruby/optional/capi/thread_spec.rb
@@ -101,6 +101,16 @@ describe "C-API Thread function" do
end
end
+ describe "ruby_native_thread_p" do
+ it "returns non-zero for a ruby thread" do
+ @t.ruby_native_thread_p.should be_true
+ end
+
+ it "returns zero for a non ruby thread" do
+ @t.ruby_native_thread_p_new_thread.should be_false
+ end
+ end
+
describe "rb_thread_call_without_gvl" do
it "runs a C function with the global lock unlocked and can be woken by Thread#wakeup" do
thr = Thread.new do
diff --git a/spec/ruby/security/cve_2019_8322_spec.rb b/spec/ruby/security/cve_2019_8322_spec.rb
index b70d78c033..a84d7a5a95 100644
--- a/spec/ruby/security/cve_2019_8322_spec.rb
+++ b/spec/ruby/security/cve_2019_8322_spec.rb
@@ -5,17 +5,19 @@ require 'rubygems'
require 'rubygems/safe_yaml'
require 'rubygems/commands/owner_command'
-describe "CVE-2019-8322 is resisted by" do
- it "sanitising owner names" do
- command = Gem::Commands::OwnerCommand.new
- def command.rubygems_api_request(*args)
- Struct.new(:body).new("---\n- email: \"\e]2;nyan\a\"\n handle: handle\n id: id\n")
+platform_is_not :darwin do # frequent timeout/hang on macOS
+ describe "CVE-2019-8322 is resisted by" do
+ it "sanitising owner names" do
+ command = Gem::Commands::OwnerCommand.new
+ def command.rubygems_api_request(*args)
+ Struct.new(:body).new("---\n- email: \"\e]2;nyan\a\"\n handle: handle\n id: id\n")
+ end
+ def command.with_response(response)
+ yield response
+ end
+ command.should_receive(:say).with("Owners for gem: name")
+ command.should_receive(:say).with("- .]2;nyan.")
+ command.show_owners "name"
end
- def command.with_response(response)
- yield response
- end
- command.should_receive(:say).with("Owners for gem: name")
- command.should_receive(:say).with("- .]2;nyan.")
- command.show_owners "name"
end
end