diff options
Diffstat (limited to 'spec/ruby/optional/capi/kernel_spec.rb')
| -rw-r--r-- | spec/ruby/optional/capi/kernel_spec.rb | 301 |
1 files changed, 220 insertions, 81 deletions
diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb index 3b61d4f0f1..62eb21448b 100644 --- a/spec/ruby/optional/capi/kernel_spec.rb +++ b/spec/ruby/optional/capi/kernel_spec.rb @@ -3,11 +3,19 @@ require_relative 'fixtures/kernel' kernel_path = load_extension("kernel") +class CApiKernelSpecs::Exc < StandardError +end +exception_class = CApiKernelSpecs::Exc + describe "C-API Kernel function" do before :each do @s = CApiKernelSpecs.new end + after :each do + @s.rb_errinfo.should == nil + end + describe "rb_block_given_p" do it "returns false if no block is passed" do @s.should_not.rb_block_given_p @@ -20,7 +28,7 @@ describe "C-API Kernel function" do describe "rb_need_block" do it "raises a LocalJumpError if no block is given" do - -> { @s.rb_need_block }.should raise_error(LocalJumpError) + -> { @s.rb_need_block }.should.raise(LocalJumpError) end it "does not raise a LocalJumpError if a block is given" do @@ -45,7 +53,7 @@ describe "C-API Kernel function" do it "calls the method with no function callback and no block" do ary = [1, 3, 5] - @s.rb_block_call_no_func(ary).should be_kind_of(Enumerator) + @s.rb_block_call_no_func(ary).should.is_a?(Enumerator) end it "calls the method with no function callback and a block" do @@ -57,7 +65,7 @@ describe "C-API Kernel function" do it "can pass extra data to the function" do ary = [3] - @s.rb_block_call_extra_data(ary).should equal(ary) + @s.rb_block_call_extra_data(ary).should.equal?(ary) end end @@ -70,14 +78,30 @@ describe "C-API Kernel function" do describe "rb_raise" do it "raises an exception" do - -> { @s.rb_raise({}) }.should raise_error(TypeError) + -> { @s.rb_raise({}) }.should.raise(TypeError) end it "terminates the function at the point it was called" do h = {} - -> { @s.rb_raise(h) }.should raise_error(TypeError) + -> { @s.rb_raise(h) }.should.raise(TypeError) h[:stage].should == :before end + + it "re-raises a rescued exception" do + -> do + begin + raise StandardError, "aaa" + rescue Exception + begin + @s.rb_raise({}) + rescue TypeError + end + + # should raise StandardError "aaa" + raise + end + end.should.raise(StandardError, "aaa") + end end describe "rb_throw" do @@ -101,7 +125,7 @@ describe "C-API Kernel function" do end it "raises an ArgumentError if there is no catch block for the symbol" do - -> { @s.rb_throw(nil) }.should raise_error(ArgumentError) + -> { @s.rb_throw(nil) }.should.raise(ArgumentError) end end @@ -127,31 +151,21 @@ describe "C-API Kernel function" do end it "raises an ArgumentError if there is no catch block for the symbol" do - -> { @s.rb_throw(nil) }.should raise_error(ArgumentError) + -> { @s.rb_throw(nil) }.should.raise(ArgumentError) end end describe "rb_warn" do - before :each do - @stderr, $stderr = $stderr, IOStub.new - @verbose = $VERBOSE - end - - after :each do - $stderr = @stderr - $VERBOSE = @verbose - end - it "prints a message to $stderr if $VERBOSE evaluates to true" do - $VERBOSE = true - @s.rb_warn("This is a warning") - $stderr.should =~ /This is a warning/ + -> { + @s.rb_warn("This is a warning") + }.should complain(/warning: This is a warning/, verbose: true) end it "prints a message to $stderr if $VERBOSE evaluates to false" do - $VERBOSE = false - @s.rb_warn("This is a warning") - $stderr.should =~ /This is a warning/ + -> { + @s.rb_warn("This is a warning") + }.should complain(/warning: This is a warning/, verbose: false) end end @@ -159,13 +173,13 @@ describe "C-API Kernel function" do it "raises an exception from the value of errno" do -> do @s.rb_sys_fail("additional info") - end.should raise_error(SystemCallError, /additional info/) + end.should.raise(SystemCallError, /additional info/) end it "can take a NULL message" do -> do @s.rb_sys_fail(nil) - end.should raise_error(Errno::EPERM) + end.should.raise(Errno::EPERM) end end @@ -173,13 +187,35 @@ describe "C-API Kernel function" do it "raises an exception from the given error" do -> do @s.rb_syserr_fail(Errno::EINVAL::Errno, "additional info") - end.should raise_error(Errno::EINVAL, /additional info/) + end.should.raise(Errno::EINVAL, "Invalid argument - additional info") end it "can take a NULL message" do -> do @s.rb_syserr_fail(Errno::EINVAL::Errno, nil) - end.should raise_error(Errno::EINVAL) + end.should.raise(Errno::EINVAL, "Invalid argument") + end + + it "uses some kind of string as message when errno is unknown" do + -> { @s.rb_syserr_fail(-10, nil) }.should.raise(SystemCallError, /[[:graph:]]+/) + end + end + + describe "rb_syserr_fail_str" do + it "raises an exception from the given error" do + -> do + @s.rb_syserr_fail_str(Errno::EINVAL::Errno, "additional info") + end.should.raise(Errno::EINVAL, "Invalid argument - additional info") + end + + it "can take nil as a message" do + -> do + @s.rb_syserr_fail_str(Errno::EINVAL::Errno, nil) + end.should.raise(Errno::EINVAL, "Invalid argument") + end + + it "uses some kind of string as message when errno is unknown" do + -> { @s.rb_syserr_fail_str(-10, nil) }.should.raise(SystemCallError, /[[:graph:]]+/) end end @@ -195,7 +231,7 @@ describe "C-API Kernel function" do end it "raises LocalJumpError when no block is given" do - -> { @s.rb_yield(1) }.should raise_error(LocalJumpError) + -> { @s.rb_yield(1) }.should.raise(LocalJumpError) end it "rb_yield to a block that breaks does not raise an error" do @@ -206,10 +242,8 @@ describe "C-API Kernel function" do @s.rb_yield(1) { break 73 }.should == 73 end - platform_is_not :"solaris2.10" do # NOTE: i386-pc-solaris2.10 - it "rb_yield through a callback to a block that breaks with a value returns the value" do - @s.rb_yield_indirected(1) { break 73 }.should == 73 - end + it "rb_yield through a callback to a block that breaks with a value returns the value" do + @s.rb_yield_indirected(1) { break 73 }.should == 73 end it "rb_yield to block passed to enumerator" do @@ -235,7 +269,7 @@ describe "C-API Kernel function" do end it "raises LocalJumpError when no block is given" do - -> { @s.rb_yield_splat([1, 2]) }.should raise_error(LocalJumpError) + -> { @s.rb_yield_splat([1, 2]) }.should.raise(LocalJumpError) end end @@ -267,7 +301,7 @@ describe "C-API Kernel function" do end it "raises LocalJumpError when no block is given" do - -> { @s.rb_yield_splat([1, 2]) }.should raise_error(LocalJumpError) + -> { @s.rb_yield_splat([1, 2]) }.should.raise(LocalJumpError) end end @@ -295,30 +329,37 @@ describe "C-API Kernel function" do it "will allow cleanup code to run after a raise" do proof = [] # Hold proof of work performed after the yield. -> do - @s.rb_protect_yield(77, proof) { |x| raise NameError} - end.should raise_error(NameError) + @s.rb_protect_yield(77, proof) { |x| raise NameError } + end.should.raise(NameError) proof[0].should == 23 end it "will return nil if an error was raised" do proof = [] # Hold proof of work performed after the yield. -> do - @s.rb_protect_yield(77, proof) { |x| raise NameError} - end.should raise_error(NameError) + @s.rb_protect_yield(77, proof) { |x| raise NameError } + end.should.raise(NameError) 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 + @s.rb_protect_null_status(42) { |x| raise NameError }.should == nil + @s.rb_errinfo().should.is_a? NameError + ensure + @s.rb_set_errinfo(nil) end - it "populates errinfo with the captured exception" do + it "populates rb_errinfo() with the captured exception" do proof = [] - @s.rb_protect_errinfo(77, proof) { |x| raise NameError }.class.should == NameError + @s.rb_protect_ignore_status(77, proof) { |x| raise NameError } + @s.rb_errinfo().should.is_a? NameError + # Note: on CRuby $! is the NameError here, but not clear if that is desirable or bug proof[0].should == 23 proof[1].should == nil + ensure + @s.rb_set_errinfo(nil) end end @@ -334,7 +375,7 @@ describe "C-API Kernel function" do proof = [] -> do @s.rb_eval_string_protect('raise RuntimeError', proof) - end.should raise_error(RuntimeError) + end.should.raise(RuntimeError) proof.should == [23, nil] end end @@ -375,16 +416,28 @@ describe "C-API Kernel function" do end it "raises an exception if passed function raises an exception other than StandardError" do - -> { @s.rb_rescue(@exc_error_proc, nil, @rescue_proc_returns_arg, nil) }.should raise_error(Exception) + -> { @s.rb_rescue(@exc_error_proc, nil, @rescue_proc_returns_arg, nil) }.should.raise(Exception) end it "raises an exception if any exception is raised inside the 'rescue function'" do - -> { @s.rb_rescue(@std_error_proc, nil, @std_error_proc, nil) }.should raise_error(StandardError) + -> { @s.rb_rescue(@std_error_proc, nil, @std_error_proc, nil) }.should.raise(StandardError) end - it "makes $! available only during the 'rescue function' execution" do - @s.rb_rescue(@std_error_proc, nil, -> *_ { $! }, nil).class.should == StandardError + it "sets $! and rb_errinfo() during the 'rescue function' execution" do + @s.rb_rescue(-> *_ { raise exception_class, '' }, nil, -> _, exc { + exc.should.is_a?(exception_class) + $!.should.equal?(exc) + @s.rb_errinfo.should.equal?(exc) + }, nil) + + @s.rb_rescue(-> _ { @s.rb_raise({}) }, nil, -> _, exc { + exc.should.is_a?(TypeError) + $!.should.equal?(exc) + @s.rb_errinfo.should.equal?(exc) + }, nil) + $!.should == nil + @s.rb_errinfo.should == nil end it "returns the break value if the passed function yields to a block with a break" do @@ -402,7 +455,7 @@ describe "C-API Kernel function" do describe "rb_rescue2" do it "only rescues if one of the passed exceptions is raised" do - proc = -> x { x } + proc = -> x, _exc { x } arg_error_proc = -> *_ { raise ArgumentError, '' } run_error_proc = -> *_ { raise RuntimeError, '' } type_error_proc = -> *_ { raise Exception, 'custom error' } @@ -410,13 +463,30 @@ describe "C-API Kernel function" do @s.rb_rescue2(run_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError).should == :exc -> { @s.rb_rescue2(type_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError) - }.should raise_error(Exception, 'custom error') + }.should.raise(Exception, 'custom error') end it "raises TypeError if one of the passed exceptions is not a Module" do -> { @s.rb_rescue2(-> *_ { raise RuntimeError, "foo" }, :no_exc, -> x { x }, :exc, Object.new, 42) - }.should raise_error(TypeError, /class or module required/) + }.should.raise(TypeError, /class or module required/) + end + + it "sets $! and rb_errinfo() during the 'rescue function' execution" do + @s.rb_rescue2(-> *_ { raise exception_class, '' }, :no_exc, -> _, exc { + exc.should.is_a?(exception_class) + $!.should.equal?(exc) + @s.rb_errinfo.should.equal?(exc) + }, :exc, exception_class, ScriptError) + + @s.rb_rescue2(-> *_ { @s.rb_raise({}) }, :no_exc, -> _, exc { + exc.should.is_a?(TypeError) + $!.should.equal?(exc) + @s.rb_errinfo.should.equal?(exc) + }, :exc, TypeError, ArgumentError) + + $!.should == nil + @s.rb_errinfo.should == nil end end @@ -435,12 +505,12 @@ describe "C-API Kernel function" do throw :thrown_value ScratchPad << :after_throw end - @s.rb_catch("thrown_value", proc).should be_nil + @s.rb_catch("thrown_value", proc).should == nil ScratchPad.recorded.should == [:before_throw] end it "raises an ArgumentError if the throw symbol isn't caught" do - -> { @s.rb_catch("foo", -> { throw :bar }) }.should raise_error(ArgumentError) + -> { @s.rb_catch("foo", -> { throw :bar }) }.should.raise(ArgumentError) end end @@ -461,12 +531,46 @@ describe "C-API Kernel function" do throw @tag ScratchPad << :after_throw end - @s.rb_catch_obj(@tag, proc).should be_nil + @s.rb_catch_obj(@tag, proc).should == nil ScratchPad.recorded.should == [:before_throw] end it "raises an ArgumentError if the throw symbol isn't caught" do - -> { @s.rb_catch("foo", -> { throw :bar }) }.should raise_error(ArgumentError) + -> { @s.rb_catch("foo", -> { throw :bar }) }.should.raise(ArgumentError) + end + end + + describe "rb_category_warn" do + it "emits a warning into stderr" do + Warning[:deprecated] = true + + -> { + @s.rb_category_warn_deprecated + }.should complain(/warning: foo/, verbose: true) + end + + it "supports printf format modifiers" do + Warning[:deprecated] = true + + -> { + @s.rb_category_warn_deprecated_with_integer_extra_value(42) + }.should complain(/warning: foo 42/, verbose: true) + end + + it "does not emits a warning when a category is disabled" do + Warning[:deprecated] = false + + -> { + @s.rb_category_warn_deprecated + }.should_not complain(verbose: true) + end + + it "does not emits a warning when $VERBOSE is nil" do + Warning[:deprecated] = true + + -> { + @s.rb_category_warn_deprecated + }.should_not complain(verbose: nil) end end @@ -486,16 +590,37 @@ describe "C-API Kernel function" do it "executes passed 'ensure function' when an exception is raised" do foo = nil - raise_proc = -> { raise '' } + raise_proc = -> _ { raise exception_class } ensure_proc = -> x { foo = x } - @s.rb_ensure(raise_proc, nil, ensure_proc, :foo) rescue nil + -> { + @s.rb_ensure(raise_proc, nil, ensure_proc, :foo) + }.should.raise(exception_class) foo.should == :foo end + it "sets $! and rb_errinfo() during the 'ensure function' execution" do + -> { + @s.rb_ensure(-> _ { raise exception_class }, nil, -> _ { + $!.should.is_a?(exception_class) + @s.rb_errinfo.should.is_a?(exception_class) + }, nil) + }.should.raise(exception_class) + + -> { + @s.rb_ensure(-> _ { @s.rb_raise({}) }, nil, -> _ { + $!.should.is_a?(TypeError) + @s.rb_errinfo.should.is_a?(TypeError) + }, nil) + }.should.raise(TypeError) + + $!.should == nil + @s.rb_errinfo.should == nil + end + it "raises the same exception raised inside passed function" do raise_proc = -> *_ { raise RuntimeError, 'foo' } proc = -> *_ { } - -> { @s.rb_ensure(raise_proc, nil, proc, nil) }.should raise_error(RuntimeError, 'foo') + -> { @s.rb_ensure(raise_proc, nil, proc, nil) }.should.raise(RuntimeError, 'foo') end end @@ -510,29 +635,31 @@ describe "C-API Kernel function" do end end - describe "rb_eval_cmd_kw" do - it "evaluates a string of ruby code" do - @s.rb_eval_cmd_kw("1+1", [], 0).should == 2 - end + ruby_version_is ""..."4.0" do + describe "rb_eval_cmd_kw" do + it "evaluates a string of ruby code" do + @s.rb_eval_cmd_kw("1+1", [], 0).should == 2 + end - it "calls a proc with the supplied arguments" do - @s.rb_eval_cmd_kw(-> *x { x.map { |i| i + 1 } }, [1, 3, 7], 0).should == [2, 4, 8] - end + it "calls a proc with the supplied arguments" do + @s.rb_eval_cmd_kw(-> *x { x.map { |i| i + 1 } }, [1, 3, 7], 0).should == [2, 4, 8] + end - it "calls a proc with keyword arguments if kw_splat is non zero" do - a_proc = -> *x, **y { - res = x.map { |i| i + 1 } - y.each { |k, v| res << k; res << v } - res - } - @s.rb_eval_cmd_kw(a_proc, [1, 3, 7, {a: 1, b: 2, c: 3}], 1).should == [2, 4, 8, :a, 1, :b, 2, :c, 3] + it "calls a proc with keyword arguments if kw_splat is non zero" do + a_proc = -> *x, **y { + res = x.map { |i| i + 1 } + y.each { |k, v| res << k; res << v } + res + } + @s.rb_eval_cmd_kw(a_proc, [1, 3, 7, {a: 1, b: 2, c: 3}], 1).should == [2, 4, 8, :a, 1, :b, 2, :c, 3] + end end end describe "rb_block_proc" do it "converts the implicit block into a proc" do proc = @s.rb_block_proc { 1+1 } - proc.should be_kind_of(Proc) + proc.should.is_a?(Proc) proc.call.should == 2 proc.should_not.lambda? end @@ -540,7 +667,7 @@ describe "C-API Kernel function" do it "passes through an existing lambda and does not convert to a proc" do b = -> { 1+1 } proc = @s.rb_block_proc(&b) - proc.should equal(b) + proc.should.equal?(b) proc.call.should == 2 proc.should.lambda? end @@ -549,7 +676,7 @@ describe "C-API Kernel function" do describe "rb_block_lambda" do it "converts the implicit block into a lambda" do proc = @s.rb_block_lambda { 1+1 } - proc.should be_kind_of(Proc) + proc.should.is_a?(Proc) proc.call.should == 2 proc.should.lambda? end @@ -557,7 +684,7 @@ describe "C-API Kernel function" do it "passes through an existing Proc and does not convert to a lambda" do b = proc { 1+1 } proc = @s.rb_block_lambda(&b) - proc.should equal(b) + proc.should.equal?(b) proc.call.should == 2 proc.should_not.lambda? end @@ -576,6 +703,12 @@ describe "C-API Kernel function" do end end + describe "ruby_vm_at_exit" do + it "runs a C function after the VM is terminated" do + ruby_exe("require #{kernel_path.inspect}; CApiKernelSpecs.new.ruby_vm_at_exit").should == "ruby_vm_at_exit hook ran\n" + end + end + describe "rb_f_sprintf" do it "returns a string according to format and arguments" do @s.rb_f_sprintf(["%d %f %s", 10, 2.5, "test"]).should == "10 2.500000 test" @@ -586,7 +719,7 @@ describe "C-API Kernel function" do it "returns a caller backtrace" do backtrace = @s.rb_make_backtrace lines = backtrace.select {|l| l =~ /#{__FILE__}/ } - lines.should_not be_empty + lines.should_not.empty? end end @@ -644,7 +777,7 @@ describe "C-API Kernel function" do -> { @s.rb_funcallv_kw(self, :m, [42]) - }.should raise_error(TypeError, 'no implicit conversion of Integer into Hash') + }.should.raise(TypeError, 'no implicit conversion of Integer into Hash') end end @@ -680,7 +813,7 @@ describe "C-API Kernel function" do end it "does not call a private method" do - -> { @s.rb_funcallv_public(@obj, :method_private) }.should raise_error(NoMethodError, /private/) + -> { @s.rb_funcallv_public(@obj, :method_private) }.should.raise(NoMethodError, /private/) end end @@ -714,7 +847,7 @@ describe "C-API Kernel function" do -> { @s.rb_funcall_with_block(object, :private_method, [], proc { }) - }.should raise_error(NoMethodError, /private/) + }.should.raise(NoMethodError, /private/) end it "does not call a protected method" do @@ -722,7 +855,7 @@ describe "C-API Kernel function" do -> { @s.rb_funcall_with_block(object, :protected_method, [], proc { }) - }.should raise_error(NoMethodError, /protected/) + }.should.raise(NoMethodError, /protected/) end end @@ -741,7 +874,7 @@ describe "C-API Kernel function" do -> { @s.rb_funcall_with_block_kw(object, :private_method, [{}], proc { }) - }.should raise_error(NoMethodError, /private/) + }.should.raise(NoMethodError, /private/) end it "does not call a protected method" do @@ -749,7 +882,7 @@ describe "C-API Kernel function" do -> { @s.rb_funcall_with_block_kw(object, :protected_method, [{}], proc { }) - }.should raise_error(NoMethodError, /protected/) + }.should.raise(NoMethodError, /protected/) end end @@ -787,4 +920,10 @@ describe "C-API Kernel function" do @s.rb_check_funcall(object, :protected_method, []).should == :protected end end + + describe "rb_str_format" do + it "returns a string according to format and arguments" do + @s.rb_str_format(3, [10, 2.5, "test"], "%d %f %s").should == "10 2.500000 test" + end + end end |
