1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
describe :kernel_raise, shared: true do
before :each do
ScratchPad.clear
end
it "aborts execution" do
-> do
@object.raise Exception, "abort"
ScratchPad.record :no_abort
end.should raise_error(Exception, "abort")
ScratchPad.recorded.should be_nil
end
it "accepts an exception that implements to_hash" do
custom_error = Class.new(StandardError) do
def to_hash
{}
end
end
error = custom_error.new
-> { @object.raise(error) }.should raise_error(custom_error)
end
it "allows the message parameter to be a hash" do
data_error = Class.new(StandardError) do
attr_reader :data
def initialize(data)
@data = data
end
end
-> { @object.raise(data_error, {data: 42}) }.should raise_error(data_error) do |ex|
ex.data.should == {data: 42}
end
end
# https://bugs.ruby-lang.org/issues/8257#note-36
it "allows extra keyword arguments for compatibility" do
data_error = Class.new(StandardError) do
attr_reader :data
def initialize(data)
@data = data
end
end
-> { @object.raise(data_error, data: 42) }.should raise_error(data_error) do |ex|
ex.data.should == {data: 42}
end
end
it "does not allow message and extra keyword arguments" do
data_error = Class.new(StandardError) do
attr_reader :data
def initialize(data)
@data = data
end
end
-> { @object.raise(data_error, {a: 1}, b: 2) }.should raise_error(StandardError) do |e|
[TypeError, ArgumentError].should.include?(e.class)
end
-> { @object.raise(data_error, {a: 1}, [], b: 2) }.should raise_error(ArgumentError)
end
it "raises RuntimeError if no exception class is given" do
-> { @object.raise }.should raise_error(RuntimeError, "")
end
it "raises a given Exception instance" do
error = RuntimeError.new
-> { @object.raise(error) }.should raise_error(error)
end
it "raises a RuntimeError if string given" do
-> { @object.raise("a bad thing") }.should raise_error(RuntimeError)
end
it "passes no arguments to the constructor when given only an exception class" do
klass = Class.new(Exception) do
def initialize
end
end
-> { @object.raise(klass) }.should raise_error(klass) { |e| e.message.should == klass.to_s }
end
it "raises a TypeError when passed a non-Exception object" do
-> { @object.raise(Object.new) }.should raise_error(TypeError)
end
it "raises a TypeError when passed true" do
-> { @object.raise(true) }.should raise_error(TypeError)
end
it "raises a TypeError when passed false" do
-> { @object.raise(false) }.should raise_error(TypeError)
end
it "raises a TypeError when passed nil" do
-> { @object.raise(nil) }.should raise_error(TypeError)
end
it "re-raises a previously rescued exception without overwriting the backtrace" do
# This spec is written using #backtrace and matching the line number
# from the string, as backtrace_locations is a more advanced
# method that is not always supported by implementations.
#
initial_raise_line = nil
raise_again_line = nil
raised_again = nil
if defined?(FiberSpecs::NewFiberToRaise) and @object == FiberSpecs::NewFiberToRaise
fiber = Fiber.new do
begin
initial_raise_line = __LINE__; Fiber.yield
rescue => raised
begin
raise_again_line = __LINE__; Fiber.yield raised
rescue => raised_again
raised_again
end
end
end
fiber.resume
raised = fiber.raise 'raised'
raised_again = fiber.raise raised
else
begin
initial_raise_line = __LINE__; @object.raise 'raised'
rescue => raised
begin
raise_again_line = __LINE__; @object.raise raised
rescue => raised_again
raised_again
end
end
end
raised_again.backtrace.first.should include("#{__FILE__}:#{initial_raise_line}:")
raised_again.backtrace.first.should_not include("#{__FILE__}:#{raise_again_line}:")
end
it "allows Exception, message, and backtrace parameters" do
-> do
@object.raise(ArgumentError, "message", caller)
end.should raise_error(ArgumentError, "message")
end
end
|