diff options
author | Benoit Daloze <[email protected]> | 2020-03-28 00:22:51 +0100 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2020-03-28 00:22:51 +0100 |
commit | f234d51eaba861edea925eabb564a0bee41b96a0 (patch) | |
tree | 3334f36a91fe81ec704f2980ab169231f52c41d0 /spec/ruby/optional | |
parent | 296f68816cf575b3ff920f92aec8a4109a7d81d4 (diff) |
Update to ruby/spec@ec84479
Diffstat (limited to 'spec/ruby/optional')
21 files changed, 445 insertions, 300 deletions
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 |