summaryrefslogtreecommitdiff
path: root/spec/ruby
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby')
-rw-r--r--spec/ruby/.rubocop_todo.yml1
-rw-r--r--spec/ruby/core/comparable/lt_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/shared/collect.rb30
-rw-r--r--spec/ruby/core/exception/errno_spec.rb6
-rw-r--r--spec/ruby/core/exception/no_method_error_spec.rb2
-rw-r--r--spec/ruby/core/file/ftype_spec.rb8
-rw-r--r--spec/ruby/core/io/print_spec.rb2
-rw-r--r--spec/ruby/core/kernel/Float_spec.rb6
-rw-r--r--spec/ruby/core/kernel/instance_of_spec.rb2
-rw-r--r--spec/ruby/core/kernel/shared/sprintf.rb6
-rw-r--r--spec/ruby/core/module/alias_method_spec.rb12
-rw-r--r--spec/ruby/core/module/refine_spec.rb11
-rw-r--r--spec/ruby/core/process/spawn_spec.rb10
-rw-r--r--spec/ruby/core/random/default_spec.rb6
-rw-r--r--spec/ruby/core/regexp/union_spec.rb10
-rw-r--r--spec/ruby/core/symbol/match_spec.rb17
-rw-r--r--spec/ruby/language/predefined_spec.rb15
-rw-r--r--spec/ruby/language/regexp/encoding_spec.rb12
-rw-r--r--spec/ruby/language/string_spec.rb22
-rw-r--r--spec/ruby/library/bigdecimal/BigDecimal_spec.rb16
-rw-r--r--spec/ruby/library/date/parse_spec.rb17
-rw-r--r--spec/ruby/library/digest/sha2/hexdigest_spec.rb32
-rw-r--r--spec/ruby/library/digest/sha256/file_spec.rb4
-rw-r--r--spec/ruby/library/openssl/config/freeze_spec.rb3
-rw-r--r--spec/ruby/library/openssl/shared/version.rb16
-rw-r--r--spec/ruby/library/rbconfig/rbconfig_spec.rb15
-rw-r--r--spec/ruby/library/socket/socket/unpack_sockaddr_un_spec.rb2
-rw-r--r--spec/ruby/library/stringio/initialize_spec.rb40
-rw-r--r--spec/ruby/optional/capi/basic_object_spec.rb24
-rw-r--r--spec/ruby/optional/capi/constants_spec.rb108
-rw-r--r--spec/ruby/optional/capi/encoding_spec.rb8
-rw-r--r--spec/ruby/optional/capi/ext/basic_object_spec.c19
-rw-r--r--spec/ruby/optional/capi/ext/constants_spec.c367
-rw-r--r--spec/ruby/optional/capi/ext/encoding_spec.c22
-rw-r--r--spec/ruby/optional/capi/ext/float_spec.c9
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/globals_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c23
-rw-r--r--spec/ruby/optional/capi/ext/language_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c4
-rw-r--r--spec/ruby/optional/capi/ext/rubyspec.h4
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c14
-rw-r--r--spec/ruby/optional/capi/float_spec.rb13
-rw-r--r--spec/ruby/optional/capi/gc_spec.rb20
-rw-r--r--spec/ruby/optional/capi/globals_spec.rb25
-rw-r--r--spec/ruby/optional/capi/kernel_spec.rb43
-rw-r--r--spec/ruby/optional/capi/language_spec.rb6
-rw-r--r--spec/ruby/optional/capi/spec_helper.rb4
-rw-r--r--spec/ruby/optional/capi/string_spec.rb14
-rw-r--r--spec/ruby/security/cve_2020_10663_spec.rb42
50 files changed, 739 insertions, 377 deletions
diff --git a/spec/ruby/.rubocop_todo.yml b/spec/ruby/.rubocop_todo.yml
index 36e41aec87..8d9cd82f0b 100644
--- a/spec/ruby/.rubocop_todo.yml
+++ b/spec/ruby/.rubocop_todo.yml
@@ -70,6 +70,7 @@ Lint/LiteralInInterpolation:
- 'language/alias_spec.rb'
- 'language/defined_spec.rb'
- 'language/fixtures/squiggly_heredoc.rb'
+ - 'language/string_spec.rb'
- 'language/symbol_spec.rb'
- 'language/undef_spec.rb'
- 'library/net/ftp/connect_spec.rb'
diff --git a/spec/ruby/core/comparable/lt_spec.rb b/spec/ruby/core/comparable/lt_spec.rb
index 4db92719e2..bca95f8d25 100644
--- a/spec/ruby/core/comparable/lt_spec.rb
+++ b/spec/ruby/core/comparable/lt_spec.rb
@@ -40,4 +40,10 @@ describe "Comparable#<" do
a.should_receive(:<=>).any_number_of_times.and_return(nil)
-> { (a < b) }.should raise_error(ArgumentError)
end
+
+ it "raises an argument error with a message containing the value" do
+ -> { ("foo" < 7) }.should raise_error(ArgumentError) { |e|
+ e.message.should == "comparison of String with 7 failed"
+ }
+ end
end
diff --git a/spec/ruby/core/enumerable/shared/collect.rb b/spec/ruby/core/enumerable/shared/collect.rb
index 05e94777c7..71b8acd526 100644
--- a/spec/ruby/core/enumerable/shared/collect.rb
+++ b/spec/ruby/core/enumerable/shared/collect.rb
@@ -34,5 +34,35 @@ describe :enumerable_collect, shared: true do
enum.each { |i| -i }.should == [-2, -5, -3, -6, -1, -4]
end
+ it "reports the same arity as the given block" do
+ entries = [0, 1, 3, 4, 5, 6]
+ numerous = EnumerableSpecs::Numerous.new(*entries)
+
+ def numerous.each(&block)
+ ScratchPad << block.arity
+ super
+ end
+
+ numerous.send(@method) { |a, b| a % 2 }.should == [0, 1, 1, 0, 1, 0]
+ ScratchPad.recorded.should == [2]
+ ScratchPad.clear
+ ScratchPad.record []
+ numerous.send(@method) { |i| i }.should == entries
+ ScratchPad.recorded.should == [1]
+ end
+
+ it "yields 2 arguments for a Hash" do
+ c = Class.new do
+ def register(a, b)
+ ScratchPad << [a, b]
+ end
+ end
+ m = c.new.method(:register)
+
+ ScratchPad.record []
+ { 1 => 'a', 2 => 'b' }.map(&m)
+ ScratchPad.recorded.should == [[1, 'a'], [2, 'b']]
+ end
+
it_should_behave_like :enumerable_enumeratorized_with_origin_size
end
diff --git a/spec/ruby/core/exception/errno_spec.rb b/spec/ruby/core/exception/errno_spec.rb
index e76b29349e..78b3eafc2a 100644
--- a/spec/ruby/core/exception/errno_spec.rb
+++ b/spec/ruby/core/exception/errno_spec.rb
@@ -42,3 +42,9 @@ describe "Errno::EAGAIN" do
end
end
end
+
+describe "Errno::ENOTSUP" do
+ it "is defined" do
+ Errno.should have_constant(:ENOTSUP)
+ end
+end
diff --git a/spec/ruby/core/exception/no_method_error_spec.rb b/spec/ruby/core/exception/no_method_error_spec.rb
index 93224c0740..55a5fccd0d 100644
--- a/spec/ruby/core/exception/no_method_error_spec.rb
+++ b/spec/ruby/core/exception/no_method_error_spec.rb
@@ -64,7 +64,7 @@ describe "NoMethodError#message" do
NoMethodErrorSpecs::NoMethodErrorC.new.a_private_method
rescue Exception => e
e.should be_kind_of(NoMethodError)
- e.message.match(/private method/).should_not == nil
+ e.message.lines[0].should =~ /private method `a_private_method' called for #<NoMethodErrorSpecs::NoMethodErrorC:0x[\h]+>/
end
end
diff --git a/spec/ruby/core/file/ftype_spec.rb b/spec/ruby/core/file/ftype_spec.rb
index 8ff70baa80..cdddc404dc 100644
--- a/spec/ruby/core/file/ftype_spec.rb
+++ b/spec/ruby/core/file/ftype_spec.rb
@@ -35,6 +35,14 @@ describe "File.ftype" do
end
end
+ it "uses to_path to convert arguments" do
+ FileSpecs.normal_file do |file|
+ obj = mock('path')
+ obj.should_receive(:to_path).and_return(file)
+ File.ftype(obj).should == 'file'
+ end
+ end
+
# Both FreeBSD and Windows does not have block devices
platform_is_not :freebsd, :windows do
with_block_device do
diff --git a/spec/ruby/core/io/print_spec.rb b/spec/ruby/core/io/print_spec.rb
index 0e8805348e..04e971ef6d 100644
--- a/spec/ruby/core/io/print_spec.rb
+++ b/spec/ruby/core/io/print_spec.rb
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe IO, "#print" do
+describe "IO#print" do
before :each do
@old_separator = $\
suppress_warning {$\ = '->'}
diff --git a/spec/ruby/core/kernel/Float_spec.rb b/spec/ruby/core/kernel/Float_spec.rb
index 6580c38137..af64fcbe86 100644
--- a/spec/ruby/core/kernel/Float_spec.rb
+++ b/spec/ruby/core/kernel/Float_spec.rb
@@ -54,6 +54,12 @@ describe :kernel_float, shared: true do
-> { @object.send(:Float, "float") }.should raise_error(ArgumentError)
end
+ it "raises an ArgumentError for a String with string in error message" do
+ -> { @object.send(:Float, "foo") }.should raise_error(ArgumentError) { |e|
+ e.message.should == 'invalid value for Float(): "foo"'
+ }
+ end
+
it "raises an ArgumentError if there are two decimal points in the String" do
-> { @object.send(:Float, "10.0.0") }.should raise_error(ArgumentError)
end
diff --git a/spec/ruby/core/kernel/instance_of_spec.rb b/spec/ruby/core/kernel/instance_of_spec.rb
index 40e856b0d9..d1170d5047 100644
--- a/spec/ruby/core/kernel/instance_of_spec.rb
+++ b/spec/ruby/core/kernel/instance_of_spec.rb
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-describe Kernel, "#instance_of?" do
+describe "Kernel#instance_of?" do
before :each do
@o = KernelSpecs::InstanceClass.new
end
diff --git a/spec/ruby/core/kernel/shared/sprintf.rb b/spec/ruby/core/kernel/shared/sprintf.rb
index 8defbfd665..1ad6f8a3cf 100644
--- a/spec/ruby/core/kernel/shared/sprintf.rb
+++ b/spec/ruby/core/kernel/shared/sprintf.rb
@@ -336,6 +336,12 @@ describe :kernel_sprintf, shared: true do
@method.call("%s", obj)
}.should raise_error(NoMethodError)
end
+
+ it "formats a partial substring without including omitted characters" do
+ long_string = "aabbccddhelloddccbbaa"
+ sub_string = long_string[8, 5]
+ sprintf("%.#{1 * 3}s", sub_string).should == "hel"
+ end
end
describe "%" do
diff --git a/spec/ruby/core/module/alias_method_spec.rb b/spec/ruby/core/module/alias_method_spec.rb
index 662e91011f..571191fe29 100644
--- a/spec/ruby/core/module/alias_method_spec.rb
+++ b/spec/ruby/core/module/alias_method_spec.rb
@@ -42,6 +42,18 @@ describe "Module#alias_method" do
@object.was_private_one.should == 1
end
+ it "handles aliasing a method only present in a refinement" do
+ c = @class
+ Module.new do
+ refine c do
+ def uno_refined_method
+ end
+ alias_method :double_refined_method, :uno_refined_method
+ instance_method(:uno_refined_method).should == instance_method(:double_refined_method)
+ end
+ end
+ end
+
it "fails if origin method not found" do
-> { @class.make_alias :ni, :san }.should raise_error(NameError) { |e|
# a NameError and not a NoMethodError
diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb
index 66c19ddb66..81dd492362 100644
--- a/spec/ruby/core/module/refine_spec.rb
+++ b/spec/ruby/core/module/refine_spec.rb
@@ -704,6 +704,17 @@ describe "Module#refine" do
-> { [1,2].orig_count }.should raise_error(NoMethodError)
end
+ it "and instance_methods returns a list of methods including those of the refined module" do
+ methods = Array.instance_methods
+ methods_2 = []
+ Module.new do
+ refine Array do
+ methods_2 = instance_methods
+ end
+ end
+ methods.should == methods_2
+ end
+
# Refinements are inherited by module inclusion.
# That is, using activates all refinements in the ancestors of the specified module.
# Refinements in a descendant have priority over refinements in an ancestor.
diff --git a/spec/ruby/core/process/spawn_spec.rb b/spec/ruby/core/process/spawn_spec.rb
index 79a5f4ad95..6b08e0227b 100644
--- a/spec/ruby/core/process/spawn_spec.rb
+++ b/spec/ruby/core/process/spawn_spec.rb
@@ -207,13 +207,9 @@ describe "Process.spawn" do
it "unsets environment variables whose value is nil" do
ENV["FOO"] = "BAR"
- Process.wait Process.spawn({"FOO" => nil}, "echo #{@var}>#{@name}")
- expected = "\n"
- platform_is :windows do
- # Windows does not expand the variable if it is unset
- expected = "#{@var}\n"
- end
- File.read(@name).should == expected
+ -> do
+ Process.wait Process.spawn({"FOO" => nil}, ruby_cmd("p ENV['FOO']"))
+ end.should output_to_fd("nil\n")
end
it "calls #to_hash to convert the environment" do
diff --git a/spec/ruby/core/random/default_spec.rb b/spec/ruby/core/random/default_spec.rb
index 1d8b1ce5ee..1755154294 100644
--- a/spec/ruby/core/random/default_spec.rb
+++ b/spec/ruby/core/random/default_spec.rb
@@ -4,4 +4,10 @@ describe "Random::DEFAULT" do
it "returns a Random instance" do
Random::DEFAULT.should be_an_instance_of(Random)
end
+
+ it "changes seed on reboot" do
+ seed1 = ruby_exe('p Random::DEFAULT.seed', options: '--disable-gems')
+ seed2 = ruby_exe('p Random::DEFAULT.seed', options: '--disable-gems')
+ seed1.should != seed2
+ end
end
diff --git a/spec/ruby/core/regexp/union_spec.rb b/spec/ruby/core/regexp/union_spec.rb
index 81a31d89b3..8076836471 100644
--- a/spec/ruby/core/regexp/union_spec.rb
+++ b/spec/ruby/core/regexp/union_spec.rb
@@ -139,6 +139,16 @@ describe "Regexp.union" do
Regexp.union(obj, "bar").should == /foo|bar/
end
+ it "uses to_regexp to convert argument" do
+ obj = mock('pattern')
+ obj.should_receive(:to_regexp).and_return(/foo/)
+ Regexp.union(obj).should == /foo/
+ end
+
+ it "accepts a Symbol as argument" do
+ Regexp.union(:foo).should == /foo/
+ end
+
it "accepts a single array of patterns as arguments" do
Regexp.union(["skiing", "sledding"]).should == /skiing|sledding/
not_supported_on :opal do
diff --git a/spec/ruby/core/symbol/match_spec.rb b/spec/ruby/core/symbol/match_spec.rb
index d37155537b..41e058f977 100644
--- a/spec/ruby/core/symbol/match_spec.rb
+++ b/spec/ruby/core/symbol/match_spec.rb
@@ -34,6 +34,23 @@ describe "Symbol#match" do
:a.match(/(.)/)[0].should == 'a'
$1.should == "a"
end
+
+ describe "when passed a block" do
+ it "yields the MatchData" do
+ :abc.match(/./) {|m| ScratchPad.record m }
+ ScratchPad.recorded.should be_kind_of(MatchData)
+ end
+
+ it "returns the block result" do
+ :abc.match(/./) { :result }.should == :result
+ end
+
+ it "does not yield if there is no match" do
+ ScratchPad.record []
+ :b.match(/a/) {|m| ScratchPad << m }
+ ScratchPad.recorded.should == []
+ end
+ end
end
describe "Symbol#match?" do
diff --git a/spec/ruby/language/predefined_spec.rb b/spec/ruby/language/predefined_spec.rb
index e9fce1c358..970071eccd 100644
--- a/spec/ruby/language/predefined_spec.rb
+++ b/spec/ruby/language/predefined_spec.rb
@@ -399,15 +399,18 @@ describe "Predefined global $!" do
end
it "should be cleared when an exception is rescued even when a non-local return from block" do
- [ 1 ].each do
- begin
- raise StandardError.new('err')
- rescue => e
- $!.should == e
- return
+ def foo
+ [ 1 ].each do
+ begin
+ raise StandardError.new('err')
+ rescue => e
+ $!.should == e
+ return
+ end
end
end
+ foo
$!.should == nil
end
diff --git a/spec/ruby/language/regexp/encoding_spec.rb b/spec/ruby/language/regexp/encoding_spec.rb
index b8559c6b27..2db09fdda8 100644
--- a/spec/ruby/language/regexp/encoding_spec.rb
+++ b/spec/ruby/language/regexp/encoding_spec.rb
@@ -116,4 +116,16 @@ describe "Regexps with encoding modifiers" do
it "raises Encoding::CompatibilityError when trying =~ against different encodings" do
-> { /\A[[:space:]]*\z/ =~ " ".encode("UTF-16LE") }.should raise_error(Encoding::CompatibilityError)
end
+
+ it "computes the Regexp Encoding for each interpolated Regexp instance" do
+ make_regexp = -> str { /#{str}/ }
+
+ r = make_regexp.call("été".force_encoding(Encoding::UTF_8))
+ r.fixed_encoding?.should == true
+ r.encoding.should == Encoding::UTF_8
+
+ r = make_regexp.call("abc".force_encoding(Encoding::UTF_8))
+ r.fixed_encoding?.should == false
+ r.encoding.should == Encoding::US_ASCII
+ end
end
diff --git a/spec/ruby/language/string_spec.rb b/spec/ruby/language/string_spec.rb
index d0f62ff3c9..68c5fd221b 100644
--- a/spec/ruby/language/string_spec.rb
+++ b/spec/ruby/language/string_spec.rb
@@ -260,24 +260,18 @@ describe "Ruby String literals" do
end
describe "Ruby String interpolation" do
- it "creates a String having an Encoding compatible with all components" do
- a = "\u3042"
- b = "abc".encode("binary")
-
- str = "#{a} x #{b}"
-
- str.should == "\xe3\x81\x82\x20\x78\x20\x61\x62\x63".force_encoding("utf-8")
- str.encoding.should == Encoding::UTF_8
+ it "returns a string with the source encoding by default" do
+ "a#{"b"}c".encoding.should == Encoding::BINARY
+ eval('"a#{"b"}c"'.force_encoding("us-ascii")).encoding.should == Encoding::US_ASCII
+ eval("# coding: US-ASCII \n 'a#{"b"}c'").encoding.should == Encoding::US_ASCII
end
- it "creates a String having the Encoding of the components when all are the same Encoding" do
+ it "returns a string with the source encoding, even if the components have another encoding" do
a = "abc".force_encoding("euc-jp")
- b = "def".force_encoding("euc-jp")
- str = '"#{a} x #{b}"'.force_encoding("euc-jp")
+ "#{a}".encoding.should == Encoding::BINARY
- result = eval(str)
- result.should == "\x61\x62\x63\x20\x78\x20\x64\x65\x66".force_encoding("euc-jp")
- result.encoding.should == Encoding::EUC_JP
+ b = "abc".encode("utf-8")
+ "#{b}".encoding.should == Encoding::BINARY
end
it "raises an Encoding::CompatibilityError if the Encodings are not compatible" do
diff --git a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb
index 0c07e46f59..faa8dc610c 100644
--- a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb
+++ b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb
@@ -175,6 +175,22 @@ describe "Kernel#BigDecimal" do
BigDecimal(3).add(1 << 50, 3).should == BigDecimal('0.113e16')
end
+ it "does not call to_s when calling inspect" do
+ value = BigDecimal('44.44')
+ value.to_s.should == '0.4444e2'
+ value.inspect.should == '0.4444e2'
+
+ ruby_exe( <<-'EOF').should == "cheese 0.4444e2"
+ require 'bigdecimal'
+ module BigDecimalOverride
+ def to_s; "cheese"; end
+ end
+ BigDecimal.prepend BigDecimalOverride
+ value = BigDecimal('44.44')
+ print "#{value.to_s} #{value.inspect}"
+ EOF
+ end
+
describe "when interacting with Rational" do
before :each do
@a = BigDecimal('166.666666666')
diff --git a/spec/ruby/library/date/parse_spec.rb b/spec/ruby/library/date/parse_spec.rb
index 379847a6fd..ef72ba3f4e 100644
--- a/spec/ruby/library/date/parse_spec.rb
+++ b/spec/ruby/library/date/parse_spec.rb
@@ -69,6 +69,23 @@ describe "Date#parse" do
-> { Date.parse(1) }.should raise_error(TypeError)
-> { Date.parse(:invalid) }.should raise_error(TypeError)
end
+
+ it "coerces using to_str" do
+ c = Class.new do
+ attr_accessor :string
+ def to_str
+ @string
+ end
+ end
+ o = c.new
+ o.string = "19101101"
+
+ d = Date.parse(o)
+ d.should == Date.civil(1910, 11, 1)
+
+ # parse should not modify string value
+ o.to_str.should == "19101101"
+ end
end
describe "Date#parse with '.' separator" do
diff --git a/spec/ruby/library/digest/sha2/hexdigest_spec.rb b/spec/ruby/library/digest/sha2/hexdigest_spec.rb
new file mode 100644
index 0000000000..79beca5788
--- /dev/null
+++ b/spec/ruby/library/digest/sha2/hexdigest_spec.rb
@@ -0,0 +1,32 @@
+require_relative '../../../spec_helper'
+require_relative '../sha256/shared/constants'
+
+describe "Digest::SHA2#hexdigest" do
+
+ it "returns a SHA256 hexdigest by default" do
+ cur_digest = Digest::SHA2.new
+ cur_digest.hexdigest.should == SHA256Constants::BlankHexdigest
+
+ # add something to check that the state is reset later
+ cur_digest << "test"
+
+ cur_digest.hexdigest(SHA256Constants::Contents).should == SHA256Constants::Hexdigest
+ # second invocation is intentional, to make sure there are no side-effects
+ cur_digest.hexdigest(SHA256Constants::Contents).should == SHA256Constants::Hexdigest
+
+ # after all is done, verify that the digest is in the original, blank state
+ cur_digest.hexdigest.should == SHA256Constants::BlankHexdigest
+ end
+
+end
+
+describe "Digest::SHA2.hexdigest" do
+
+ it "returns a SHA256 hexdigest by default" do
+ Digest::SHA2.hexdigest(SHA256Constants::Contents).should == SHA256Constants::Hexdigest
+ # second invocation is intentional, to make sure there are no side-effects
+ Digest::SHA2.hexdigest(SHA256Constants::Contents).should == SHA256Constants::Hexdigest
+ Digest::SHA2.hexdigest("").should == SHA256Constants::BlankHexdigest
+ end
+
+end
diff --git a/spec/ruby/library/digest/sha256/file_spec.rb b/spec/ruby/library/digest/sha256/file_spec.rb
index 6103971b5a..8cbc5a2755 100644
--- a/spec/ruby/library/digest/sha256/file_spec.rb
+++ b/spec/ruby/library/digest/sha256/file_spec.rb
@@ -22,6 +22,10 @@ describe "Digest::SHA256.file" do
Digest::SHA256.file(@file).digest.should == SHA256Constants::Digest
end
+ it "can be used with frozen-string-literal" do
+ ruby_exe("require 'digest'; puts Digest::SHA256.file(#{@file.inspect}).digest.inspect", options: "--enable=frozen-string-literal").chomp.should == SHA256Constants::Digest.inspect
+ end
+
it "calls #to_str on an object and returns the Digest::SHA256 with the result" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return(@file)
diff --git a/spec/ruby/library/openssl/config/freeze_spec.rb b/spec/ruby/library/openssl/config/freeze_spec.rb
index d63c243d72..c814341b86 100644
--- a/spec/ruby/library/openssl/config/freeze_spec.rb
+++ b/spec/ruby/library/openssl/config/freeze_spec.rb
@@ -1,10 +1,9 @@
require_relative '../../../spec_helper'
require_relative '../shared/constants'
-require_relative '../shared/version'
require 'openssl'
-openssl_version_is(""..."2.2") do
+version_is(OpenSSL::VERSION, ""..."2.2") do
describe "OpenSSL::Config#freeze" do
it "needs to be reviewed for completeness"
diff --git a/spec/ruby/library/openssl/shared/version.rb b/spec/ruby/library/openssl/shared/version.rb
deleted file mode 100644
index 63837d3375..0000000000
--- a/spec/ruby/library/openssl/shared/version.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require 'openssl'
-
-class OpenSSLVersionGuard < VersionGuard
- FULL_OPENSSL_VERSION = SpecVersion.new OpenSSL::VERSION
- def match?
- if Range === @version
- @version.include? FULL_OPENSSL_VERSION
- else
- FULL_OPENSSL_VERSION >= @version
- end
- end
-end
-
-def openssl_version_is(*args, &block)
- OpenSSLVersionGuard.new(*args).run_if(:openssl_version_is, &block)
-end
diff --git a/spec/ruby/library/rbconfig/rbconfig_spec.rb b/spec/ruby/library/rbconfig/rbconfig_spec.rb
index 35b465d106..be767536fb 100644
--- a/spec/ruby/library/rbconfig/rbconfig_spec.rb
+++ b/spec/ruby/library/rbconfig/rbconfig_spec.rb
@@ -28,13 +28,26 @@ describe 'RbConfig::CONFIG' do
ruby_exe(<<-RUBY, options: '--enable-frozen-string-literal').should == "Done\n"
require 'rbconfig'
RbConfig::CONFIG.each do |k, v|
- if v.frozen?
+ # SDKROOT excluded here to workaround the issue: https://bugs.ruby-lang.org/issues/16738
+ if v.frozen? && k != 'SDKROOT'
puts "\#{k} Failure"
end
end
puts 'Done'
RUBY
end
+
+ platform_is_not :windows do
+ it "libdir/LIBRUBY_SO is the path to libruby and it exists if and only if ENABLE_SHARED" do
+ if RbConfig::CONFIG['ENABLE_SHARED'] == 'yes'
+ libdir = RbConfig::CONFIG['libdir']
+ File.should.exist?("#{libdir}/#{RbConfig::CONFIG['LIBRUBY_SO']}")
+ elsif RbConfig::CONFIG['ENABLE_SHARED'] == 'no'
+ libdir = RbConfig::CONFIG['libdir']
+ File.should_not.exist?("#{libdir}/#{RbConfig::CONFIG['LIBRUBY_SO']}")
+ end
+ end
+ end
end
describe "RbConfig::TOPDIR" do
diff --git a/spec/ruby/library/socket/socket/unpack_sockaddr_un_spec.rb b/spec/ruby/library/socket/socket/unpack_sockaddr_un_spec.rb
index bd95f1db08..12f970f89b 100644
--- a/spec/ruby/library/socket/socket/unpack_sockaddr_un_spec.rb
+++ b/spec/ruby/library/socket/socket/unpack_sockaddr_un_spec.rb
@@ -13,7 +13,7 @@ with_feature :unix_socket do
Socket.unpack_sockaddr_un(addrinfo).should == '/tmp/sock'
end
- it 'raises an ArgumentError when the sin_family is not AF_UNIX' do
+ it 'raises an ArgumentError when the sa_family is not AF_UNIX' do
sockaddr = Socket.sockaddr_in(0, '127.0.0.1')
-> { Socket.unpack_sockaddr_un(sockaddr) }.should raise_error(ArgumentError)
end
diff --git a/spec/ruby/library/stringio/initialize_spec.rb b/spec/ruby/library/stringio/initialize_spec.rb
index 1422a1592f..7b141caedc 100644
--- a/spec/ruby/library/stringio/initialize_spec.rb
+++ b/spec/ruby/library/stringio/initialize_spec.rb
@@ -1,28 +1,6 @@
require_relative '../../spec_helper'
require 'stringio'
-bug_guard = Class.new(VersionGuard) do
- self::VERSION = StringIO.const_defined?(:VERSION) ? StringIO::VERSION : "0.0.2"
-
- def initialize(bug, version)
- @bug = bug
- super(version)
- @parameters = [bug, version]
- end
- def match?
- version = self.class::VERSION
- if Range === @version
- @version.include? version
- else
- version >= @version
- end
- end
-
- def self.against(*args, &block)
- new(*args).run_unless(:stringio_version_is, &block)
- end
-end
-
describe "StringIO#initialize when passed [Object, mode]" do
before :each do
@io = StringIO.allocate
@@ -206,7 +184,7 @@ describe "StringIO#initialize when passed no arguments" do
end
end
-describe "StringIO#initialize sets the encoding to" do
+describe "StringIO#initialize sets" do
before :each do
@external = Encoding.default_external
@internal = Encoding.default_internal
@@ -219,18 +197,26 @@ describe "StringIO#initialize sets the encoding to" do
Encoding.default_internal = @internal
end
- it "Encoding.default_external when passed no arguments" do
+ it "the encoding to Encoding.default_external when passed no arguments" do
io = StringIO.new
io.external_encoding.should == Encoding::ISO_8859_2
io.string.encoding.should == Encoding::ISO_8859_2
end
- it "the same as the encoding of the String when passed a String" do
+ it "the encoding to the encoding of the String when passed a String" do
s = ''.force_encoding(Encoding::EUC_JP)
io = StringIO.new(s)
- bug_guard.against("[Bug #16497]", "0.0.3"..."0.1.1") do
+ io.string.encoding.should == Encoding::EUC_JP
+ end
+
+ guard_not -> { # [Bug #16497]
+ stringio_version = StringIO.const_defined?(:VERSION) ? StringIO::VERSION : "0.0.2"
+ version_is(stringio_version, "0.0.3"..."0.1.1")
+ } do
+ it "the #external_encoding to the encoding of the String when passed a String" do
+ s = ''.force_encoding(Encoding::EUC_JP)
+ io = StringIO.new(s)
io.external_encoding.should == Encoding::EUC_JP
end
- io.string.encoding.should == Encoding::EUC_JP
end
end
diff --git a/spec/ruby/optional/capi/basic_object_spec.rb b/spec/ruby/optional/capi/basic_object_spec.rb
new file mode 100644
index 0000000000..2922a421da
--- /dev/null
+++ b/spec/ruby/optional/capi/basic_object_spec.rb
@@ -0,0 +1,24 @@
+require_relative 'spec_helper'
+
+load_extension("basic_object")
+
+describe "C-API basic object" do
+ before :each do
+ @s = CApiBasicObjectSpecs.new
+ end
+
+ describe "RBASIC_CLASS" do
+ it "returns the class of an object" do
+ c = Class.new
+ o = c.new
+ @s.RBASIC_CLASS(o).should == c
+ end
+
+ it "returns the singleton class" do
+ o = Object.new
+ @s.RBASIC_CLASS(o).should == Object
+ singleton_class = o.singleton_class
+ @s.RBASIC_CLASS(o).should == singleton_class
+ end
+ end
+end
diff --git a/spec/ruby/optional/capi/constants_spec.rb b/spec/ruby/optional/capi/constants_spec.rb
index 11a328a91f..3d7f0cebd6 100644
--- a/spec/ruby/optional/capi/constants_spec.rb
+++ b/spec/ruby/optional/capi/constants_spec.rb
@@ -11,10 +11,22 @@ describe "C-API constant" do
@s.rb_cArray.should == Array
end
+ specify "rb_cBasicObject references the BasicObject class" do
+ @s.rb_cBasicObject.should == BasicObject
+ end
+
+ specify "rb_cBinding references the Binding class" do
+ @s.rb_cBinding.should == Binding
+ end
+
specify "rb_cClass references the Class class" do
@s.rb_cClass.should == Class
end
+ specify "rb_cComplex references the Complex class" do
+ @s.rb_cComplex.should == Complex
+ end
+
specify "rb_mComparable references the Comparable module" do
@s.rb_mComparable.should == Comparable
end
@@ -25,10 +37,22 @@ describe "C-API constant" do
end
end
+ specify "rb_cDir references the Dir class" do
+ @s.rb_cDir.should == Dir
+ end
+
+ specify "rb_cEncoding references the Encoding class" do
+ @s.rb_cEncoding.should == Encoding
+ end
+
specify "rb_mEnumerable references the Enumerable module" do
@s.rb_mEnumerable.should == Enumerable
end
+ specify "rb_cEnumerator references the Enumerator class" do
+ @s.rb_cEnumerator.should == Enumerator
+ end
+
specify "rb_cFalseClass references the FalseClass class" do
@s.rb_cFalseClass.should == FalseClass
end
@@ -37,10 +61,18 @@ describe "C-API constant" do
@s.rb_cFile.should == File
end
+ specify "rb_mFileTest references the FileTest module" do
+ @s.rb_mFileTest.should == FileTest
+ end
+
specify "rb_cFloat references the Float class" do
@s.rb_cFloat.should == Float
end
+ specify "rb_mGC references the GC module" do
+ @s.rb_mGC.should == GC
+ end
+
specify "rb_cHash references the Hash class" do
@s.rb_cHash.should == Hash
end
@@ -57,10 +89,21 @@ describe "C-API constant" do
@s.rb_mKernel.should == Kernel
end
+ # On 2.4 with require 'mathn', Math is redefined as CMath
+ ruby_version_is "2.5" do
+ specify "rb_mMath references the Math module" do
+ @s.rb_mMath.should == Math
+ end
+ end
+
specify "rb_cMatch references the MatchData class" do
@s.rb_cMatch.should == MatchData
end
+ specify "rb_cMethod references the Method class" do
+ @s.rb_cMethod.should == Method
+ end
+
specify "rb_cModule references the Module class" do
@s.rb_cModule.should == Module
end
@@ -77,14 +120,34 @@ describe "C-API constant" do
@s.rb_cObject.should == Object
end
+ specify "rb_cProc references the Proc class" do
+ @s.rb_cProc.should == Proc
+ end
+
+ specify "rb_mProcess references the Process module" do
+ @s.rb_mProcess.should == Process
+ end
+
+ specify "rb_cRandom references the Random class" do
+ @s.rb_cRandom.should == Random
+ end
+
specify "rb_cRange references the Range class" do
@s.rb_cRange.should == Range
end
+ specify "rb_cRational references the Rational class" do
+ @s.rb_cRational.should == Rational
+ end
+
specify "rb_cRegexp references the Regexp class" do
@s.rb_cRegexp.should == Regexp
end
+ specify "rb_cStat references the File::Stat class" do
+ @s.rb_cStat.should == File::Stat
+ end
+
specify "rb_cString references the String class" do
@s.rb_cString.should == String
end
@@ -109,18 +172,9 @@ describe "C-API constant" do
@s.rb_cTrueClass.should == TrueClass
end
- specify "rb_cProc references the Proc class" do
- @s.rb_cProc.should == Proc
- end
-
- specify "rb_cMethod references the Method class" do
- @s.rb_cMethod.should == Method
+ specify "rb_cUnboundMethod references the UnboundMethod class" do
+ @s.rb_cUnboundMethod.should == UnboundMethod
end
-
- specify "rb_cDir references the Dir class" do
- @s.rb_cDir.should == Dir
- end
-
end
describe "C-API exception constant" do
@@ -132,6 +186,14 @@ describe "C-API exception constant" do
@s.rb_eArgError.should == ArgumentError
end
+ specify "rb_eEncodingError references the EncodingError class" do
+ @s.rb_eEncodingError.should == EncodingError
+ end
+
+ specify "rb_eEncCompatError references the Encoding::CompatibilityError" do
+ @s.rb_eEncCompatError.should == Encoding::CompatibilityError
+ end
+
specify "rb_eEOFError references the EOFError class" do
@s.rb_eEOFError.should == EOFError
end
@@ -144,10 +206,22 @@ describe "C-API exception constant" do
@s.rb_eException.should == Exception
end
+ specify "rb_eFatal references the fatal class" do
+ fatal = @s.rb_eFatal
+ fatal.should be_kind_of(Class)
+ fatal.should < Exception
+ end
+
specify "rb_eFloatDomainError references the FloatDomainError class" do
@s.rb_eFloatDomainError.should == FloatDomainError
end
+ ruby_version_is "2.5" do
+ specify "rb_eFrozenError references the FrozenError class" do
+ @s.rb_eFrozenError.should == FrozenError
+ end
+ end
+
specify "rb_eIndexError references the IndexError class" do
@s.rb_eIndexError.should == IndexError
end
@@ -160,6 +234,10 @@ describe "C-API exception constant" do
@s.rb_eIOError.should == IOError
end
+ specify "rb_eKeyError references the KeyError class" do
+ @s.rb_eKeyError.should == KeyError
+ end
+
specify "rb_eLoadError references the LoadError class" do
@s.rb_eLoadError.should == LoadError
end
@@ -172,10 +250,6 @@ describe "C-API exception constant" do
@s.rb_eMathDomainError.should == Math::DomainError
end
- specify "rb_eEncCompatError references the Encoding::CompatibilityError" do
- @s.rb_eEncCompatError.should == Encoding::CompatibilityError
- end
-
specify "rb_eNameError references the NameError class" do
@s.rb_eNameError.should == NameError
end
@@ -220,6 +294,10 @@ describe "C-API exception constant" do
@s.rb_eStandardError.should == StandardError
end
+ specify "rb_eStopIteration references the StopIteration class" do
+ @s.rb_eStopIteration.should == StopIteration
+ end
+
specify "rb_eSyntaxError references the SyntaxError class" do
@s.rb_eSyntaxError.should == SyntaxError
end
diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb
index b74a360760..430c2dfcc6 100644
--- a/spec/ruby/optional/capi/encoding_spec.rb
+++ b/spec/ruby/optional/capi/encoding_spec.rb
@@ -257,6 +257,14 @@ describe "C-API Encoding function" do
@s.rb_to_encoding(obj).should == "UTF-8"
end
+
+ describe "when the rb_encoding struct is stored in native memory" do
+ it "can still read the name of the encoding" do
+ address = @s.rb_to_encoding_native_store(Encoding::UTF_8)
+ address.should be_kind_of(Integer)
+ @s.rb_to_encoding_native_name(address).should == "UTF-8"
+ end
+ end
end
describe "rb_to_encoding_index" do
diff --git a/spec/ruby/optional/capi/ext/basic_object_spec.c b/spec/ruby/optional/capi/ext/basic_object_spec.c
new file mode 100644
index 0000000000..1618670ceb
--- /dev/null
+++ b/spec/ruby/optional/capi/ext/basic_object_spec.c
@@ -0,0 +1,19 @@
+#include "ruby.h"
+#include "rubyspec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static VALUE basic_object_spec_RBASIC_CLASS(VALUE self, VALUE obj) {
+ return RBASIC_CLASS(obj);
+}
+
+void Init_basic_object_spec(void) {
+ VALUE cls = rb_define_class("CApiBasicObjectSpecs", rb_cObject);
+ rb_define_method(cls, "RBASIC_CLASS", basic_object_spec_RBASIC_CLASS, 1);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/spec/ruby/optional/capi/ext/constants_spec.c b/spec/ruby/optional/capi/ext/constants_spec.c
index 6f1e03f549..598d30a0be 100644
--- a/spec/ruby/optional/capi/ext/constants_spec.c
+++ b/spec/ruby/optional/capi/ext/constants_spec.c
@@ -5,292 +5,151 @@
extern "C" {
#endif
-static VALUE constants_spec_rb_cArray(VALUE self) {
- return rb_cArray;
-}
-
-static VALUE constants_spec_rb_cClass(VALUE self) {
- return rb_cClass;
-}
-
-static VALUE constants_spec_rb_cData(VALUE self) {
- return rb_cData;
-}
-
-static VALUE constants_spec_rb_cFalseClass(VALUE self) {
- return rb_cFalseClass;
-}
-
-static VALUE constants_spec_rb_cFile(VALUE self) {
- return rb_cFile;
-}
-
-static VALUE constants_spec_rb_cFloat(VALUE self) {
- return rb_cFloat;
-}
-
-static VALUE constants_spec_rb_cHash(VALUE self) {
- return rb_cHash;
-}
-
-static VALUE constants_spec_rb_cInteger(VALUE self) {
- return rb_cInteger;
-}
-
-static VALUE constants_spec_rb_cIO(VALUE self) {
- return rb_cIO;
-}
-
-static VALUE constants_spec_rb_cModule(VALUE self) {
- return rb_cModule;
-}
-
-static VALUE constants_spec_rb_cMatch(VALUE self) {
- return rb_cMatch;
-}
-
-static VALUE constants_spec_rb_cNilClass(VALUE self) {
- return rb_cNilClass;
-}
-
-static VALUE constants_spec_rb_cNumeric(VALUE self) {
- return rb_cNumeric;
-}
-
-static VALUE constants_spec_rb_cObject(VALUE self) {
- return rb_cObject;
-}
-
-static VALUE constants_spec_rb_cRange(VALUE self) {
- return rb_cRange;
-}
-
-static VALUE constants_spec_rb_cRegexp(VALUE self) {
- return rb_cRegexp;
-}
-
-static VALUE constants_spec_rb_cString(VALUE self) {
- return rb_cString;
-}
-
-static VALUE constants_spec_rb_cStruct(VALUE self) {
- return rb_cStruct;
-}
-
-static VALUE constants_spec_rb_cSymbol(VALUE self) {
- return rb_cSymbol;
-}
-
-static VALUE constants_spec_rb_cTime(VALUE self) {
- return rb_cTime;
-}
-
-static VALUE constants_spec_rb_cThread(VALUE self) {
- return rb_cThread;
-}
-
-static VALUE constants_spec_rb_cTrueClass(VALUE self) {
- return rb_cTrueClass;
-}
-
-static VALUE constants_spec_rb_cProc(VALUE self) {
- return rb_cProc;
-}
-
-static VALUE constants_spec_rb_cMethod(VALUE self) {
- return rb_cMethod;
-}
-
-static VALUE constants_spec_rb_cEnumerator(VALUE self) {
- return rb_cEnumerator;
-}
-
-static VALUE constants_spec_rb_mComparable(VALUE self) {
- return rb_mComparable;
-}
-
-static VALUE constants_spec_rb_mEnumerable(VALUE self) {
- return rb_mEnumerable;
-}
-
-static VALUE constants_spec_rb_mKernel(VALUE self) {
- return rb_mKernel;
-}
-
-static VALUE constants_spec_rb_eArgError(VALUE self) {
- return rb_eArgError;
-}
-
-static VALUE constants_spec_rb_eEOFError(VALUE self) {
- return rb_eEOFError;
-}
-
-static VALUE constants_spec_rb_mErrno(VALUE self) {
- return rb_mErrno;
-}
-
-static VALUE constants_spec_rb_eException(VALUE self) {
- return rb_eException;
-}
-
-static VALUE constants_spec_rb_eFloatDomainError(VALUE self) {
- return rb_eFloatDomainError;
-}
-
-static VALUE constants_spec_rb_eIndexError(VALUE self) {
- return rb_eIndexError;
-}
-
-static VALUE constants_spec_rb_eInterrupt(VALUE self) {
- return rb_eInterrupt;
-}
-
-static VALUE constants_spec_rb_eIOError(VALUE self) {
- return rb_eIOError;
-}
-
-static VALUE constants_spec_rb_eLoadError(VALUE self) {
- return rb_eLoadError;
-}
-
-static VALUE constants_spec_rb_eLocalJumpError(VALUE self) {
- return rb_eLocalJumpError;
-}
-
-static VALUE constants_spec_rb_eNameError(VALUE self) {
- return rb_eNameError;
-}
-
-static VALUE constants_spec_rb_eNoMemError(VALUE self) {
- return rb_eNoMemError;
-}
-
-static VALUE constants_spec_rb_eNoMethodError(VALUE self) {
- return rb_eNoMethodError;
-}
-
-static VALUE constants_spec_rb_eNotImpError(VALUE self) {
- return rb_eNotImpError;
-}
-
-static VALUE constants_spec_rb_eRangeError(VALUE self) {
- return rb_eRangeError;
-}
-
-static VALUE constants_spec_rb_eRegexpError(VALUE self) {
- return rb_eRegexpError;
-}
-
-static VALUE constants_spec_rb_eRuntimeError(VALUE self) {
- return rb_eRuntimeError;
-}
-
-static VALUE constants_spec_rb_eScriptError(VALUE self) {
- return rb_eScriptError;
-}
-
-static VALUE constants_spec_rb_eSecurityError(VALUE self) {
- return rb_eSecurityError;
-}
-
-static VALUE constants_spec_rb_eSignal(VALUE self) {
- return rb_eSignal;
-}
-
-static VALUE constants_spec_rb_eStandardError(VALUE self) {
- return rb_eStandardError;
-}
-
-static VALUE constants_spec_rb_eSyntaxError(VALUE self) {
- return rb_eSyntaxError;
-}
-
-static VALUE constants_spec_rb_eSystemCallError(VALUE self) {
- return rb_eSystemCallError;
-}
-
-static VALUE constants_spec_rb_eSystemExit(VALUE self) {
- return rb_eSystemExit;
-}
-
-static VALUE constants_spec_rb_eSysStackError(VALUE self) {
- return rb_eSysStackError;
-}
-
-static VALUE constants_spec_rb_eTypeError(VALUE self) {
- return rb_eTypeError;
-}
-
-static VALUE constants_spec_rb_eThreadError(VALUE self) {
- return rb_eThreadError;
-}
-
-static VALUE constants_spec_rb_eZeroDivError(VALUE self) {
- return rb_eZeroDivError;
-}
-
-static VALUE constants_spec_rb_eMathDomainError(VALUE self) {
- return rb_eMathDomainError;
-}
-
-static VALUE constants_spec_rb_eEncCompatError(VALUE self) {
- return rb_eEncCompatError;
-}
-
-static VALUE constants_spec_rb_mWaitReadable(VALUE self) {
- return rb_mWaitReadable;
-}
-
-static VALUE constants_spec_rb_mWaitWritable(VALUE self) {
- return rb_mWaitWritable;
-}
-
-static VALUE constants_spec_rb_cDir(VALUE self) {
- return rb_cDir;
-}
+#define defconstfunc(name) \
+static VALUE constants_spec_##name(VALUE self) { return name; }
+
+defconstfunc(rb_cArray)
+defconstfunc(rb_cBasicObject)
+defconstfunc(rb_cBinding)
+defconstfunc(rb_cClass)
+defconstfunc(rb_cComplex)
+defconstfunc(rb_mComparable)
+defconstfunc(rb_cData)
+defconstfunc(rb_cDir)
+defconstfunc(rb_cEncoding)
+defconstfunc(rb_mEnumerable)
+defconstfunc(rb_cEnumerator)
+defconstfunc(rb_cFalseClass)
+defconstfunc(rb_cFile)
+defconstfunc(rb_mFileTest)
+defconstfunc(rb_cFloat)
+defconstfunc(rb_mGC)
+defconstfunc(rb_cHash)
+defconstfunc(rb_cInteger)
+defconstfunc(rb_cIO)
+defconstfunc(rb_mKernel)
+defconstfunc(rb_mMath)
+defconstfunc(rb_cMatch)
+defconstfunc(rb_cMethod)
+defconstfunc(rb_cModule)
+defconstfunc(rb_cNilClass)
+defconstfunc(rb_cNumeric)
+defconstfunc(rb_cObject)
+defconstfunc(rb_cProc)
+defconstfunc(rb_mProcess)
+defconstfunc(rb_cRandom)
+defconstfunc(rb_cRange)
+defconstfunc(rb_cRational)
+defconstfunc(rb_cRegexp)
+defconstfunc(rb_cStat)
+defconstfunc(rb_cString)
+defconstfunc(rb_cStruct)
+defconstfunc(rb_cSymbol)
+defconstfunc(rb_cTime)
+defconstfunc(rb_cThread)
+defconstfunc(rb_cTrueClass)
+defconstfunc(rb_cUnboundMethod)
+defconstfunc(rb_eArgError)
+defconstfunc(rb_eEncodingError)
+defconstfunc(rb_eEncCompatError)
+defconstfunc(rb_eEOFError)
+defconstfunc(rb_mErrno)
+defconstfunc(rb_eException)
+defconstfunc(rb_eFatal)
+defconstfunc(rb_eFloatDomainError)
+#ifdef RUBY_VERSION_IS_2_5
+defconstfunc(rb_eFrozenError)
+#endif
+defconstfunc(rb_eIndexError)
+defconstfunc(rb_eInterrupt)
+defconstfunc(rb_eIOError)
+defconstfunc(rb_eKeyError)
+defconstfunc(rb_eLoadError)
+defconstfunc(rb_eLocalJumpError)
+defconstfunc(rb_eMathDomainError)
+defconstfunc(rb_eNameError)
+defconstfunc(rb_eNoMemError)
+defconstfunc(rb_eNoMethodError)
+defconstfunc(rb_eNotImpError)
+defconstfunc(rb_eRangeError)
+defconstfunc(rb_eRegexpError)
+defconstfunc(rb_eRuntimeError)
+defconstfunc(rb_eScriptError)
+defconstfunc(rb_eSecurityError)
+defconstfunc(rb_eSignal)
+defconstfunc(rb_eStandardError)
+defconstfunc(rb_eStopIteration)
+defconstfunc(rb_eSyntaxError)
+defconstfunc(rb_eSystemCallError)
+defconstfunc(rb_eSystemExit)
+defconstfunc(rb_eSysStackError)
+defconstfunc(rb_eTypeError)
+defconstfunc(rb_eThreadError)
+defconstfunc(rb_mWaitReadable)
+defconstfunc(rb_mWaitWritable)
+defconstfunc(rb_eZeroDivError)
void Init_constants_spec(void) {
VALUE cls = rb_define_class("CApiConstantsSpecs", rb_cObject);
rb_define_method(cls, "rb_cArray", constants_spec_rb_cArray, 0);
-
+ rb_define_method(cls, "rb_cBasicObject", constants_spec_rb_cBasicObject, 0);
+ rb_define_method(cls, "rb_cBinding", constants_spec_rb_cBinding, 0);
rb_define_method(cls, "rb_cClass", constants_spec_rb_cClass, 0);
+ rb_define_method(cls, "rb_cComplex", constants_spec_rb_cComplex, 0);
+ rb_define_method(cls, "rb_mComparable", constants_spec_rb_mComparable, 0);
rb_define_method(cls, "rb_cData", constants_spec_rb_cData, 0);
+ rb_define_method(cls, "rb_cDir", constants_spec_rb_cDir, 0);
+ rb_define_method(cls, "rb_cEncoding", constants_spec_rb_cEncoding, 0);
+ rb_define_method(cls, "rb_mEnumerable", constants_spec_rb_mEnumerable, 0);
+ rb_define_method(cls, "rb_cEnumerator", constants_spec_rb_cEnumerator, 0);
rb_define_method(cls, "rb_cFalseClass", constants_spec_rb_cFalseClass, 0);
rb_define_method(cls, "rb_cFile", constants_spec_rb_cFile, 0);
-
+ rb_define_method(cls, "rb_mFileTest", constants_spec_rb_mFileTest, 0);
rb_define_method(cls, "rb_cFloat", constants_spec_rb_cFloat, 0);
+ rb_define_method(cls, "rb_mGC", constants_spec_rb_mGC, 0);
rb_define_method(cls, "rb_cHash", constants_spec_rb_cHash, 0);
rb_define_method(cls, "rb_cInteger", constants_spec_rb_cInteger, 0);
rb_define_method(cls, "rb_cIO", constants_spec_rb_cIO, 0);
+ rb_define_method(cls, "rb_mKernel", constants_spec_rb_mKernel, 0);
+ rb_define_method(cls, "rb_mMath", constants_spec_rb_mMath, 0);
rb_define_method(cls, "rb_cMatch", constants_spec_rb_cMatch, 0);
+ rb_define_method(cls, "rb_cMethod", constants_spec_rb_cMethod, 0);
rb_define_method(cls, "rb_cModule", constants_spec_rb_cModule, 0);
rb_define_method(cls, "rb_cNilClass", constants_spec_rb_cNilClass, 0);
rb_define_method(cls, "rb_cNumeric", constants_spec_rb_cNumeric, 0);
rb_define_method(cls, "rb_cObject", constants_spec_rb_cObject, 0);
+ rb_define_method(cls, "rb_cProc", constants_spec_rb_cProc, 0);
+ rb_define_method(cls, "rb_mProcess", constants_spec_rb_mProcess, 0);
+ rb_define_method(cls, "rb_cRandom", constants_spec_rb_cRandom, 0);
rb_define_method(cls, "rb_cRange", constants_spec_rb_cRange, 0);
+ rb_define_method(cls, "rb_cRational", constants_spec_rb_cRational, 0);
rb_define_method(cls, "rb_cRegexp", constants_spec_rb_cRegexp, 0);
+ rb_define_method(cls, "rb_cStat", constants_spec_rb_cStat, 0);
rb_define_method(cls, "rb_cString", constants_spec_rb_cString, 0);
rb_define_method(cls, "rb_cStruct", constants_spec_rb_cStruct, 0);
rb_define_method(cls, "rb_cSymbol", constants_spec_rb_cSymbol, 0);
rb_define_method(cls, "rb_cTime", constants_spec_rb_cTime, 0);
rb_define_method(cls, "rb_cThread", constants_spec_rb_cThread, 0);
rb_define_method(cls, "rb_cTrueClass", constants_spec_rb_cTrueClass, 0);
- rb_define_method(cls, "rb_cProc", constants_spec_rb_cProc, 0);
- rb_define_method(cls, "rb_cMethod", constants_spec_rb_cMethod, 0);
- rb_define_method(cls, "rb_cEnumerator", constants_spec_rb_cEnumerator, 0);
- rb_define_method(cls, "rb_mComparable", constants_spec_rb_mComparable, 0);
- rb_define_method(cls, "rb_mEnumerable", constants_spec_rb_mEnumerable, 0);
- rb_define_method(cls, "rb_mKernel", constants_spec_rb_mKernel, 0);
+ rb_define_method(cls, "rb_cUnboundMethod", constants_spec_rb_cUnboundMethod, 0);
rb_define_method(cls, "rb_eArgError", constants_spec_rb_eArgError, 0);
+ rb_define_method(cls, "rb_eEncodingError", constants_spec_rb_eEncodingError, 0);
+ rb_define_method(cls, "rb_eEncCompatError", constants_spec_rb_eEncCompatError, 0);
rb_define_method(cls, "rb_eEOFError", constants_spec_rb_eEOFError, 0);
rb_define_method(cls, "rb_mErrno", constants_spec_rb_mErrno, 0);
rb_define_method(cls, "rb_eException", constants_spec_rb_eException, 0);
+ rb_define_method(cls, "rb_eFatal", constants_spec_rb_eFatal, 0);
rb_define_method(cls, "rb_eFloatDomainError", constants_spec_rb_eFloatDomainError, 0);
+ #ifdef RUBY_VERSION_IS_2_5
+ rb_define_method(cls, "rb_eFrozenError", constants_spec_rb_eFrozenError, 0);
+ #endif
rb_define_method(cls, "rb_eIndexError", constants_spec_rb_eIndexError, 0);
rb_define_method(cls, "rb_eInterrupt", constants_spec_rb_eInterrupt, 0);
rb_define_method(cls, "rb_eIOError", constants_spec_rb_eIOError, 0);
+ rb_define_method(cls, "rb_eKeyError", constants_spec_rb_eKeyError, 0);
rb_define_method(cls, "rb_eLoadError", constants_spec_rb_eLoadError, 0);
rb_define_method(cls, "rb_eLocalJumpError", constants_spec_rb_eLocalJumpError, 0);
+ rb_define_method(cls, "rb_eMathDomainError", constants_spec_rb_eMathDomainError, 0);
rb_define_method(cls, "rb_eNameError", constants_spec_rb_eNameError, 0);
rb_define_method(cls, "rb_eNoMemError", constants_spec_rb_eNoMemError, 0);
rb_define_method(cls, "rb_eNoMethodError", constants_spec_rb_eNoMethodError, 0);
@@ -302,18 +161,16 @@ void Init_constants_spec(void) {
rb_define_method(cls, "rb_eSecurityError", constants_spec_rb_eSecurityError, 0);
rb_define_method(cls, "rb_eSignal", constants_spec_rb_eSignal, 0);
rb_define_method(cls, "rb_eStandardError", constants_spec_rb_eStandardError, 0);
+ rb_define_method(cls, "rb_eStopIteration", constants_spec_rb_eStopIteration, 0);
rb_define_method(cls, "rb_eSyntaxError", constants_spec_rb_eSyntaxError, 0);
rb_define_method(cls, "rb_eSystemCallError", constants_spec_rb_eSystemCallError, 0);
rb_define_method(cls, "rb_eSystemExit", constants_spec_rb_eSystemExit, 0);
rb_define_method(cls, "rb_eSysStackError", constants_spec_rb_eSysStackError, 0);
rb_define_method(cls, "rb_eTypeError", constants_spec_rb_eTypeError, 0);
rb_define_method(cls, "rb_eThreadError", constants_spec_rb_eThreadError, 0);
- rb_define_method(cls, "rb_eZeroDivError", constants_spec_rb_eZeroDivError, 0);
- rb_define_method(cls, "rb_eMathDomainError", constants_spec_rb_eMathDomainError, 0);
- rb_define_method(cls, "rb_eEncCompatError", constants_spec_rb_eEncCompatError, 0);
rb_define_method(cls, "rb_mWaitReadable", constants_spec_rb_mWaitReadable, 0);
rb_define_method(cls, "rb_mWaitWritable", constants_spec_rb_mWaitWritable, 0);
- rb_define_method(cls, "rb_cDir", constants_spec_rb_cDir, 0);
+ rb_define_method(cls, "rb_eZeroDivError", constants_spec_rb_eZeroDivError, 0);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/encoding_spec.c b/spec/ruby/optional/capi/ext/encoding_spec.c
index 52ed4fdb2e..6b3a8be01a 100644
--- a/spec/ruby/optional/capi/ext/encoding_spec.c
+++ b/spec/ruby/optional/capi/ext/encoding_spec.c
@@ -175,6 +175,21 @@ static VALUE encoding_spec_rb_to_encoding(VALUE self, VALUE obj) {
return rb_str_new2(rb_to_encoding(obj)->name);
}
+static rb_encoding** native_rb_encoding_pointer;
+
+static VALUE encoding_spec_rb_to_encoding_native_store(VALUE self, VALUE obj) {
+ rb_encoding* enc = rb_to_encoding(obj);
+ VALUE address = SIZET2NUM((size_t) native_rb_encoding_pointer);
+ *native_rb_encoding_pointer = enc;
+ return address;
+}
+
+static VALUE encoding_spec_rb_to_encoding_native_name(VALUE self, VALUE address) {
+ rb_encoding** ptr = (rb_encoding**) NUM2SIZET(address);
+ rb_encoding* enc = *ptr;
+ return rb_str_new2(enc->name);
+}
+
static VALUE encoding_spec_rb_to_encoding_index(VALUE self, VALUE obj) {
return INT2NUM(rb_to_encoding_index(obj));
}
@@ -205,7 +220,10 @@ static VALUE encoding_spec_rb_enc_str_asciionly_p(VALUE self, VALUE str) {
}
void Init_encoding_spec(void) {
- VALUE cls = rb_define_class("CApiEncodingSpecs", rb_cObject);
+ VALUE cls;
+ native_rb_encoding_pointer = (rb_encoding**) malloc(sizeof(rb_encoding*));
+
+ cls = rb_define_class("CApiEncodingSpecs", rb_cObject);
rb_define_method(cls, "ENC_CODERANGE_ASCIIONLY",
encoding_spec_ENC_CODERANGE_ASCIIONLY, 1);
@@ -247,6 +265,8 @@ void Init_encoding_spec(void) {
rb_define_method(cls, "ENCODING_SET", encoding_spec_ENCODING_SET, 2);
rb_define_method(cls, "rb_enc_to_index", encoding_spec_rb_enc_to_index, 1);
rb_define_method(cls, "rb_to_encoding", encoding_spec_rb_to_encoding, 1);
+ rb_define_method(cls, "rb_to_encoding_native_store", encoding_spec_rb_to_encoding_native_store, 1);
+ rb_define_method(cls, "rb_to_encoding_native_name", encoding_spec_rb_to_encoding_native_name, 1);
rb_define_method(cls, "rb_to_encoding_index", encoding_spec_rb_to_encoding_index, 1);
rb_define_method(cls, "rb_enc_nth", encoding_spec_rb_enc_nth, 2);
rb_define_method(cls, "rb_enc_codepoint_len", encoding_spec_rb_enc_codepoint_len, 1);
diff --git a/spec/ruby/optional/capi/ext/float_spec.c b/spec/ruby/optional/capi/ext/float_spec.c
index 34be917965..3db05cef8c 100644
--- a/spec/ruby/optional/capi/ext/float_spec.c
+++ b/spec/ruby/optional/capi/ext/float_spec.c
@@ -25,12 +25,21 @@ static VALUE float_spec_RFLOAT_VALUE(VALUE self, VALUE float_h) {
return rb_float_new(RFLOAT_VALUE(float_h));
}
+static VALUE float_spec_RB_FLOAT_TYPE_P(VALUE self, VALUE val) {
+ if (RB_FLOAT_TYPE_P(val)) {
+ return Qtrue;
+ } else {
+ return Qfalse;
+ }
+}
+
void Init_float_spec(void) {
VALUE cls = rb_define_class("CApiFloatSpecs", rb_cObject);
rb_define_method(cls, "new_zero", float_spec_new_zero, 0);
rb_define_method(cls, "new_point_five", float_spec_new_point_five, 0);
rb_define_method(cls, "rb_Float", float_spec_rb_Float, 1);
rb_define_method(cls, "RFLOAT_VALUE", float_spec_RFLOAT_VALUE, 1);
+ rb_define_method(cls, "RB_FLOAT_TYPE_P", float_spec_RB_FLOAT_TYPE_P, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c
index 4611617c18..7dc9c347c7 100644
--- a/spec/ruby/optional/capi/ext/gc_spec.c
+++ b/spec/ruby/optional/capi/ext/gc_spec.c
@@ -29,6 +29,10 @@ static VALUE gc_spec_rb_gc(VALUE self) {
return Qnil;
}
+static VALUE gc_spec_rb_gc_latest_gc_info(VALUE self, VALUE hash_or_key){
+ return rb_gc_latest_gc_info(hash_or_key);
+}
+
static VALUE gc_spec_rb_gc_adjust_memory_usage(VALUE self, VALUE diff) {
rb_gc_adjust_memory_usage(NUM2SSIZET(diff));
return Qnil;
@@ -54,6 +58,7 @@ void Init_gc_spec(void) {
rb_define_method(cls, "rb_gc", gc_spec_rb_gc, 0);
rb_define_method(cls, "rb_gc_adjust_memory_usage", gc_spec_rb_gc_adjust_memory_usage, 1);
rb_define_method(cls, "rb_gc_register_mark_object", gc_spec_rb_gc_register_mark_object, 1);
+ rb_define_method(cls, "rb_gc_latest_gc_info", gc_spec_rb_gc_latest_gc_info, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/globals_spec.c b/spec/ruby/optional/capi/ext/globals_spec.c
index 75860d3774..28a9633f98 100644
--- a/spec/ruby/optional/capi/ext/globals_spec.c
+++ b/spec/ruby/optional/capi/ext/globals_spec.c
@@ -68,6 +68,10 @@ static VALUE global_spec_rb_defout(VALUE self) {
return rb_defout;
}
+static VALUE global_spec_rb_fs(VALUE self) {
+ return rb_fs;
+}
+
static VALUE global_spec_rb_rs(VALUE self) {
return rb_rs;
}
@@ -109,6 +113,7 @@ void Init_globals_spec(void) {
rb_define_method(cls, "rb_stdout", global_spec_rb_stdout, 0);
rb_define_method(cls, "rb_stderr", global_spec_rb_stderr, 0);
rb_define_method(cls, "rb_defout", global_spec_rb_defout, 0);
+ rb_define_method(cls, "rb_fs", global_spec_rb_fs, 0);
rb_define_method(cls, "rb_rs", global_spec_rb_rs, 0);
rb_define_method(cls, "rb_default_rs", global_spec_rb_default_rs, 0);
rb_define_method(cls, "rb_output_rs", global_spec_rb_output_rs, 0);
diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c
index 13d9598125..351a68e7f0 100644
--- a/spec/ruby/optional/capi/ext/kernel_spec.c
+++ b/spec/ruby/optional/capi/ext/kernel_spec.c
@@ -180,6 +180,21 @@ VALUE kernel_spec_rb_rescue2(int argc, VALUE *args, VALUE self) {
kernel_spec_call_proc_raise, raise_array, args[4], args[5], (VALUE)0);
}
+VALUE kernel_spec_rb_rescue2_wrong_terminator_arg_type(int argc, VALUE *args, VALUE self) {
+ VALUE main_array, raise_array;
+
+ main_array = rb_ary_new();
+ rb_ary_push(main_array, args[0]);
+ rb_ary_push(main_array, args[1]);
+
+ raise_array = rb_ary_new();
+ rb_ary_push(raise_array, args[2]);
+ rb_ary_push(raise_array, args[3]);
+
+ return rb_rescue2(kernel_spec_call_proc, main_array,
+ kernel_spec_call_proc_raise, raise_array, args[4], args[5], 0);
+}
+
static VALUE kernel_spec_rb_protect_yield(VALUE self, VALUE obj, VALUE ary) {
int status = 0;
VALUE res = rb_protect(rb_yield, obj, &status);
@@ -191,6 +206,10 @@ static VALUE kernel_spec_rb_protect_yield(VALUE self, VALUE obj, VALUE ary) {
return res;
}
+static VALUE kernel_spec_rb_protect_null_status(VALUE self, VALUE obj) {
+ return rb_protect(rb_yield, obj, NULL);
+}
+
static VALUE kernel_spec_rb_eval_string_protect(VALUE self, VALUE str, VALUE ary) {
int status = 0;
VALUE res = rb_eval_string_protect(RSTRING_PTR(str), &status);
@@ -281,7 +300,7 @@ static VALUE kernel_spec_rb_exec_recursive(VALUE self, VALUE obj) {
}
static void write_io(VALUE io) {
- rb_funcall(io, rb_intern("write"), 1, rb_str_new2("e"));
+ rb_funcall(io, rb_intern("write"), 1, rb_str_new2("in write_io"));
}
static VALUE kernel_spec_rb_set_end_proc(VALUE self, VALUE io) {
@@ -335,7 +354,9 @@ void Init_kernel_spec(void) {
rb_define_method(cls, "rb_throw_obj", kernel_spec_rb_throw_obj, 2);
rb_define_method(cls, "rb_rescue", kernel_spec_rb_rescue, 4);
rb_define_method(cls, "rb_rescue2", kernel_spec_rb_rescue2, -1);
+ rb_define_method(cls, "rb_rescue2_wrong_arg_type", kernel_spec_rb_rescue2_wrong_terminator_arg_type, -1);
rb_define_method(cls, "rb_protect_yield", kernel_spec_rb_protect_yield, 2);
+ rb_define_method(cls, "rb_protect_null_status", kernel_spec_rb_protect_null_status, 1);
rb_define_method(cls, "rb_eval_string_protect", kernel_spec_rb_eval_string_protect, 2);
rb_define_method(cls, "rb_catch", kernel_spec_rb_catch, 2);
rb_define_method(cls, "rb_catch_obj", kernel_spec_rb_catch_obj, 2);
diff --git a/spec/ruby/optional/capi/ext/language_spec.c b/spec/ruby/optional/capi/ext/language_spec.c
index 5aeac63f53..749c188956 100644
--- a/spec/ruby/optional/capi/ext/language_spec.c
+++ b/spec/ruby/optional/capi/ext/language_spec.c
@@ -24,9 +24,17 @@ static VALUE language_spec_switch(VALUE self, VALUE value) {
}
}
+/* Defining a local variable rb_mProcess which already exists as a global variable
+ * For instance eventmachine does this in Init_rubyeventmachine() */
+static VALUE language_spec_global_local_var(VALUE self) {
+ VALUE rb_mProcess = rb_const_get(rb_cObject, rb_intern("Process"));
+ return rb_mProcess;
+}
+
void Init_language_spec(void) {
VALUE cls = rb_define_class("CApiLanguageSpecs", rb_cObject);
rb_define_method(cls, "switch", language_spec_switch, 1);
+ rb_define_method(cls, "global_local_var", language_spec_global_local_var, 0);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/object_spec.c b/spec/ruby/optional/capi/ext/object_spec.c
index c95e1b553f..477105aacc 100644
--- a/spec/ruby/optional/capi/ext/object_spec.c
+++ b/spec/ruby/optional/capi/ext/object_spec.c
@@ -348,9 +348,9 @@ static VALUE object_spec_rb_class_inherited_p(VALUE self, VALUE mod, VALUE arg)
static VALUE speced_allocator(VALUE klass) {
VALUE flags = 0;
VALUE instance;
- if (rb_class_inherited_p(klass, rb_cString)) {
+ if (RTEST(rb_class_inherited_p(klass, rb_cString))) {
flags = T_STRING;
- } else if (rb_class_inherited_p(klass, rb_cArray)) {
+ } else if (RTEST(rb_class_inherited_p(klass, rb_cArray))) {
flags = T_ARRAY;
} else {
flags = T_OBJECT;
diff --git a/spec/ruby/optional/capi/ext/rubyspec.h b/spec/ruby/optional/capi/ext/rubyspec.h
index cce3af22f2..32724b1667 100644
--- a/spec/ruby/optional/capi/ext/rubyspec.h
+++ b/spec/ruby/optional/capi/ext/rubyspec.h
@@ -31,6 +31,10 @@
#define RUBY_VERSION_IS_2_6
#endif
+#if RUBY_VERSION_MAJOR > 2 || (RUBY_VERSION_MAJOR == 2 && RUBY_VERSION_MINOR >= 5)
+#define RUBY_VERSION_IS_2_5
+#endif
+
#if RUBY_VERSION_MAJOR > 2 || (RUBY_VERSION_MAJOR == 2 && RUBY_VERSION_MINOR >= 4)
#define RUBY_VERSION_IS_2_4
#endif
diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c
index 74ff2d6503..cef0e872bb 100644
--- a/spec/ruby/optional/capi/ext/string_spec.c
+++ b/spec/ruby/optional/capi/ext/string_spec.c
@@ -69,6 +69,16 @@ VALUE string_spec_rb_str_buf_new2(VALUE self) {
return rb_str_buf_new2("hello\0invisible");
}
+VALUE string_spec_rb_str_tmp_new(VALUE self, VALUE len) {
+ VALUE str = rb_str_tmp_new(NUM2LONG(len));
+ rb_obj_reveal(str, rb_cString);
+ return str;
+}
+
+VALUE string_spec_rb_str_tmp_new_klass(VALUE self, VALUE len) {
+ return RBASIC_CLASS(rb_str_tmp_new(NUM2LONG(len)));
+}
+
VALUE string_spec_rb_str_buf_cat(VALUE self, VALUE str) {
const char *question_mark = "?";
rb_str_buf_cat(str, question_mark, strlen(question_mark));
@@ -296,7 +306,7 @@ VALUE string_spec_RSTRING_PTR_iterate_uint32(VALUE self, VALUE str) {
}
VALUE string_spec_RSTRING_PTR_short_memcpy(VALUE self, VALUE str) {
- // Short memcpy operations may be optimised by the compiler to a single write.
+ /* Short memcpy operations may be optimised by the compiler to a single write. */
if (RSTRING_LEN(str) >= 8) {
memcpy(RSTRING_PTR(str), "Infinity", 8);
}
@@ -451,6 +461,8 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_str_buf_new", string_spec_rb_str_buf_new, 2);
rb_define_method(cls, "rb_str_capacity", string_spec_rb_str_capacity, 1);
rb_define_method(cls, "rb_str_buf_new2", string_spec_rb_str_buf_new2, 0);
+ rb_define_method(cls, "rb_str_tmp_new", string_spec_rb_str_tmp_new, 1);
+ rb_define_method(cls, "rb_str_tmp_new_klass", string_spec_rb_str_tmp_new_klass, 1);
rb_define_method(cls, "rb_str_buf_cat", string_spec_rb_str_buf_cat, 1);
rb_define_method(cls, "rb_str_cat", string_spec_rb_str_cat, 1);
rb_define_method(cls, "rb_str_cat2", string_spec_rb_str_cat2, 1);
diff --git a/spec/ruby/optional/capi/float_spec.rb b/spec/ruby/optional/capi/float_spec.rb
index 8381945315..4b98902b59 100644
--- a/spec/ruby/optional/capi/float_spec.rb
+++ b/spec/ruby/optional/capi/float_spec.rb
@@ -27,4 +27,17 @@ describe "CApiFloatSpecs" do
f.should eql(101.99)
end
end
+
+ describe "RB_FLOAT_TYPE_P" do
+ it "returns true for floats" do
+ @f.RB_FLOAT_TYPE_P(2.0).should == true
+ end
+
+ it "returns false for non-floats" do
+ @f.RB_FLOAT_TYPE_P(nil).should == false
+ @f.RB_FLOAT_TYPE_P(10).should == false
+ @f.RB_FLOAT_TYPE_P("string").should == false
+ @f.RB_FLOAT_TYPE_P(Object.new).should == false
+ end
+ end
end
diff --git a/spec/ruby/optional/capi/gc_spec.rb b/spec/ruby/optional/capi/gc_spec.rb
index 528dd291ba..23e2b7c9ab 100644
--- a/spec/ruby/optional/capi/gc_spec.rb
+++ b/spec/ruby/optional/capi/gc_spec.rb
@@ -64,4 +64,24 @@ describe "CApiGCSpecs" do
@f.rb_gc_register_mark_object(Object.new).should be_nil
end
end
+
+ describe "rb_gc_latest_gc_info" do
+ it "raises a TypeError when hash or symbol not given" do
+ -> { @f.rb_gc_latest_gc_info("foo") }.should raise_error(TypeError)
+ end
+
+ it "raises an ArgumentError when unknown symbol given" do
+ -> { @f.rb_gc_latest_gc_info(:unknown) }.should raise_error(ArgumentError)
+ end
+
+ it "returns the populated hash when a hash is given" do
+ h = {}
+ @f.rb_gc_latest_gc_info(h).should == h
+ h.size.should_not == 0
+ end
+
+ it "returns a value when symbol is given" do
+ @f.rb_gc_latest_gc_info(:state).should be_kind_of(Symbol)
+ end
+ end
end
diff --git a/spec/ruby/optional/capi/globals_spec.rb b/spec/ruby/optional/capi/globals_spec.rb
index 1e8ab0938f..cc6f6ef3a8 100644
--- a/spec/ruby/optional/capi/globals_spec.rb
+++ b/spec/ruby/optional/capi/globals_spec.rb
@@ -53,13 +53,32 @@ describe "CApiGlobalSpecs" do
$hooked_gvar.should == 4
end
+ describe "rb_fs" do
+ before :each do
+ @field_separator = $;
+ end
+
+ after :each do
+ suppress_warning { $; = @field_separator }
+ end
+
+ it "returns nil by default" do
+ @f.rb_fs.should == nil
+ end
+
+ it "returns the value of $;" do
+ suppress_warning { $; = "foo" }
+ @f.rb_fs.should == "foo"
+ end
+ end
+
describe "rb_rs" do
before :each do
@dollar_slash = $/
end
after :each do
- suppress_warning {$/ = @dollar_slash}
+ suppress_warning { $/ = @dollar_slash }
end
it "returns \\n by default" do
@@ -67,7 +86,7 @@ describe "CApiGlobalSpecs" do
end
it "returns the value of $/" do
- suppress_warning {$/ = "foo"}
+ suppress_warning { $/ = "foo" }
@f.rb_rs.should == "foo"
end
end
@@ -121,7 +140,7 @@ describe "CApiGlobalSpecs" do
$stdout = STDOUT
end
- it "returns $stdout" do
+ it "is an alias of rb_stdout" do
$stdout = @stream
@f.rb_defout.should equal($stdout)
end
diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb
index 5c272947ab..7795baacb6 100644
--- a/spec/ruby/optional/capi/kernel_spec.rb
+++ b/spec/ruby/optional/capi/kernel_spec.rb
@@ -1,6 +1,6 @@
require_relative 'spec_helper'
-load_extension("kernel")
+kernel_path = load_extension("kernel")
describe "C-API Kernel function" do
before :each do
@@ -295,6 +295,11 @@ describe "C-API Kernel function" do
proof[0].should == 23
proof[1].should == nil
end
+
+ it "accepts NULL as status and returns nil if it failed" do
+ @s.rb_protect_null_status(42) { |x| x + 1 }.should == 43
+ @s.rb_protect_null_status(42) { |x| raise }.should == nil
+ end
end
describe "rb_eval_string_protect" do
@@ -386,6 +391,18 @@ describe "C-API Kernel function" do
@s.rb_rescue2(type_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError)
}.should raise_error(TypeError)
end
+
+ it "works when the terminating argument has not been sizes as a VALUE" do
+ proc = -> x { x }
+ arg_error_proc = -> *_ { raise ArgumentError, '' }
+ run_error_proc = -> *_ { raise RuntimeError, '' }
+ type_error_proc = -> *_ { raise TypeError, '' }
+ @s.rb_rescue2_wrong_arg_type(arg_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError).should == :exc
+ @s.rb_rescue2_wrong_arg_type(run_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError).should == :exc
+ -> {
+ @s.rb_rescue2_wrong_arg_type(type_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError)
+ }.should raise_error(TypeError)
+ end
end
describe "rb_catch" do
@@ -514,25 +531,9 @@ describe "C-API Kernel function" do
end
end
- platform_is_not :windows do
- describe "rb_set_end_proc" do
- before :each do
- @r, @w = IO.pipe
- end
-
- after :each do
- @r.close
- @w.close
- Process.wait @pid
- end
-
- it "runs a C function on shutdown" do
- @pid = fork {
- @s.rb_set_end_proc(@w)
- }
-
- @r.read(1).should == "e"
- end
+ describe "rb_set_end_proc" do
+ it "runs a C function on shutdown" do
+ ruby_exe("require #{kernel_path.inspect}; CApiKernelSpecs.new.rb_set_end_proc(STDOUT)").should == "in write_io"
end
end
@@ -592,7 +593,7 @@ describe "C-API Kernel function" do
end
end
- it "can call a public method with 10 arguments" do
+ it "can call a public method with 15 arguments" do
@s.rb_funcall_many_args(@obj, :many_args).should == 15.downto(1).to_a
end
end
diff --git a/spec/ruby/optional/capi/language_spec.rb b/spec/ruby/optional/capi/language_spec.rb
index 7605332fbd..f59b87f2a1 100644
--- a/spec/ruby/optional/capi/language_spec.rb
+++ b/spec/ruby/optional/capi/language_spec.rb
@@ -28,4 +28,10 @@ describe "C language construct" do
@s.switch(Object.new).should == :default
end
end
+
+ describe "local variable assignment with the same name as a global" do
+ it "works for rb_mProcess" do
+ @s.global_local_var.should.equal?(Process)
+ end
+ end
end
diff --git a/spec/ruby/optional/capi/spec_helper.rb b/spec/ruby/optional/capi/spec_helper.rb
index 30e6196d05..74a6325fe0 100644
--- a/spec/ruby/optional/capi/spec_helper.rb
+++ b/spec/ruby/optional/capi/spec_helper.rb
@@ -127,7 +127,9 @@ def setup_make
end
def load_extension(name)
- require compile_extension(name)
+ ext_path = compile_extension(name)
+ require ext_path
+ ext_path
rescue LoadError => e
if %r{/usr/sbin/execerror ruby "\(ld 3 1 main ([/a-zA-Z0-9_\-.]+_spec\.so)"} =~ e.message
system('/usr/sbin/execerror', "#{RbConfig::CONFIG["bindir"]}/ruby", "(ld 3 1 main #{$1}")
diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb
index 243765cdbe..224d63f886 100644
--- a/spec/ruby/optional/capi/string_spec.rb
+++ b/spec/ruby/optional/capi/string_spec.rb
@@ -158,6 +158,20 @@ describe "C-API String function" do
end
end
+ describe "rb_str_tmp_new" do
+ it "returns a hidden string (RBasic->klass is NULL)" do
+ @s.rb_str_tmp_new_klass(4).should == false
+ end
+
+ it "returns a new String object filled with \\0 bytes" do
+ s = @s.rb_str_tmp_new(4)
+ s.encoding.should == Encoding::BINARY
+ s.bytesize.should == 4
+ s.size.should == 4
+ s.should == "\x00\x00\x00\x00"
+ end
+ end
+
describe "rb_str_new" do
it "creates a new String with BINARY Encoding" do
@s.rb_str_new("", 0).encoding.should == Encoding::BINARY
diff --git a/spec/ruby/security/cve_2020_10663_spec.rb b/spec/ruby/security/cve_2020_10663_spec.rb
new file mode 100644
index 0000000000..4738ce175e
--- /dev/null
+++ b/spec/ruby/security/cve_2020_10663_spec.rb
@@ -0,0 +1,42 @@
+require_relative '../spec_helper'
+require 'json'
+
+module JSONSpecs
+ class MyClass
+ def initialize(foo)
+ @foo = foo
+ end
+
+ def self.json_create(hash)
+ new(*hash['args'])
+ end
+
+ def to_json(*args)
+ { 'json_class' => self.class.name, 'args' => [ @foo ] }.to_json(*args)
+ end
+ end
+end
+
+guard -> {
+ ruby_version_is "2.4.10"..."2.5.0" or
+ ruby_version_is "2.5.8"..."2.6.0" or
+ ruby_version_is "2.6.6" or
+ JSON.const_defined?(:Pure) or
+ version_is(JSON::VERSION, '2.3.0')
+} do
+ describe "CVE-2020-10663 is resisted by" do
+ it "only creating custom objects if passed create_additions: true or using JSON.load" do
+ obj = JSONSpecs::MyClass.new("bar")
+ JSONSpecs::MyClass.json_creatable?.should == true
+ json = JSON.dump(obj)
+
+ JSON.parse(json, create_additions: true).class.should == JSONSpecs::MyClass
+ JSON(json, create_additions: true).class.should == JSONSpecs::MyClass
+ JSON.load(json).class.should == JSONSpecs::MyClass
+
+ JSON.parse(json).class.should == Hash
+ JSON.parse(json, nil).class.should == Hash
+ JSON(json).class.should == Hash
+ end
+ end
+end