1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Benoit Daloze 2020-03-28 00:22:51 +01:00
parent 296f68816c
commit f234d51eab
50 changed files with 739 additions and 377 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 {$\ = '->'}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -399,6 +399,7 @@ describe "Predefined global $!" do
end
it "should be cleared when an exception is rescued even when a non-local return from block" do
def foo
[ 1 ].each do
begin
raise StandardError.new('err')
@ -407,7 +408,9 @@ describe "Predefined global $!" do
return
end
end
end
foo
$!.should == nil
end

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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.external_encoding.should == Encoding::EUC_JP
end
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
end
end

View file

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

View file

@ -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
specify "rb_cUnboundMethod references the UnboundMethod class" do
@s.rb_cUnboundMethod.should == UnboundMethod
end
specify "rb_cMethod references the Method class" do
@s.rb_cMethod.should == Method
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

View file

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

View file

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

View file

@ -5,292 +5,151 @@
extern "C" {
#endif
static VALUE constants_spec_rb_cArray(VALUE self) {
return rb_cArray;
}
#define defconstfunc(name) \
static VALUE constants_spec_##name(VALUE self) { return name; }
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;
}
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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -53,6 +53,25 @@ 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 = $/
@ -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

View file

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

View file

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

View file

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

View file

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

View file

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