require 'spec_helper' describe RescueAny do let(:subject_class) { Class.new } let(:subject) { subject_class.new } before :each do subject_class.class_eval do include RescueAny end end describe '.rescue_any' do context 'without an exception' do it 'raises an ArgumentError for nil' do expect { subject_class.class_eval do rescue_any nil, :on => :create, :with => lambda { |ex| "#{ex} caught by rescue_any" } end }.to raise_error ArgumentError end it 'raises an ArgumentError for something other than a class' do expect { subject_class.class_eval do rescue_any 'StandardError', :on => :create, :with => lambda { |ex| "#{ex} caught by rescue_any" } end }.to raise_error ArgumentError end it 'raises an ArgumentError for something other than an Exception or sub-class' do expect { subject_class.class_eval do rescue_any Object, :on => :create, :with => lambda { |ex| "#{ex} caught by rescue_any" } end }.to raise_error ArgumentError end end context 'for one method' do before :each do subject_class.class_eval do rescue_any StandardError, :on => :create, :with => lambda { |ex| "#{ex} caught by rescue_any" } end end it 'will rescue the given exception' do subject_class.class_eval do def create raise StandardError.new("Raised by #create") end end expect { subject.create }.to_not raise_error end it 'will not rescue other exception types' do subject_class.class_eval do def create raise ArgumentError.new("ArgumentError raised by #create") end end expect { subject.create }.to raise_error end end context 'for a list of methods' do before :each do subject_class.class_eval do rescue_any StandardError, :on => [:create, :update], :with => lambda { |ex| "#{ex} caught by rescue_any" } end end it 'will rescue the given exception' do subject_class.class_eval do def create raise StandardError.new("Raised by #create") end def update raise StandardError.new("Raised by #update") end end expect { subject.create }.to_not raise_error expect { subject.update }.to_not raise_error end end context 'when you forget to specify any methods' do before :each do subject_class.class_eval do rescue_any StandardError, :with => lambda { |ex| "#{ex} caught by rescue_any" } def create raise StandardError.new("Raised by #create") end def update raise StandardError.new("Raised by #update") end end end it "just won't rescue anything" do expect { subject.create }.to raise_error expect { subject.update }.to raise_error end end context "with a lambda handler" do it "it receives an invocation" do expect(Kernel).to receive(:puts) subject_class.class_eval do rescue_any StandardError, :on => :create, :with => lambda { |ex| Kernel.puts(ex.message) } def create raise StandardError.new("Raised by #create") end end expect { subject.create }.to_not raise_error end it 'propagates exceptions from within the handler' do subject_class.class_eval do rescue_any StandardError, :on => :create, :with => lambda { raise Exception.new("Raised by .rescue_any handler") } def create raise StandardError.new("Raised by #create") end end expect { subject.create }.to raise_error Exception end end context 'without a handler' do it 'raises an argument error' do expect { subject_class.class_eval do rescue_any StandardError, :on => :create end }.to raise_error ArgumentError end end end end