diff options
Diffstat (limited to 'spec/ruby/core/exception/full_message_spec.rb')
| -rw-r--r-- | spec/ruby/core/exception/full_message_spec.rb | 144 |
1 files changed, 132 insertions, 12 deletions
diff --git a/spec/ruby/core/exception/full_message_spec.rb b/spec/ruby/core/exception/full_message_spec.rb index 9757a2f407..5a5e0a2b3a 100644 --- a/spec/ruby/core/exception/full_message_spec.rb +++ b/spec/ruby/core/exception/full_message_spec.rb @@ -6,10 +6,10 @@ describe "Exception#full_message" do e.set_backtrace(["a.rb:1", "b.rb:2"]) full_message = e.full_message - full_message.should include "RuntimeError" - full_message.should include "Some runtime error" - full_message.should include "a.rb:1" - full_message.should include "b.rb:2" + full_message.should.include? "RuntimeError" + full_message.should.include? "Some runtime error" + full_message.should.include? "a.rb:1" + full_message.should.include? "b.rb:2" end it "supports :highlight option and adds escape sequences to highlight some strings" do @@ -42,16 +42,77 @@ describe "Exception#full_message" do e = RuntimeError.new("Some runtime error") e.backtrace.should == nil full_message = e.full_message(highlight: false, order: :top).lines - full_message[0].should.start_with?("#{__FILE__}:#{__LINE__-1}:in `") + full_message[0].should.start_with?("#{__FILE__}:#{__LINE__-1}:in ") full_message[0].should.end_with?("': Some runtime error (RuntimeError)\n") end + describe "includes details about whether an exception was handled" do + describe "RuntimeError" do + it "should report as unhandled if message is empty" do + err = RuntimeError.new("") + + err.full_message.should =~ /unhandled exception/ + err.full_message(highlight: true).should =~ /unhandled exception/ + err.full_message(highlight: false).should =~ /unhandled exception/ + end + + it "should not report as unhandled if the message is not empty" do + err = RuntimeError.new("non-empty") + + err.full_message.should !~ /unhandled exception/ + err.full_message(highlight: true).should !~ /unhandled exception/ + err.full_message(highlight: false).should !~ /unhandled exception/ + end + + it "should not report as unhandled if the message is nil" do + err = RuntimeError.new(nil) + + err.full_message.should !~ /unhandled exception/ + err.full_message(highlight: true).should !~ /unhandled exception/ + err.full_message(highlight: false).should !~ /unhandled exception/ + end + + it "should not report as unhandled if the message is not specified" do + err = RuntimeError.new() + + err.full_message.should !~ /unhandled exception/ + err.full_message(highlight: true).should !~ /unhandled exception/ + err.full_message(highlight: false).should !~ /unhandled exception/ + end + + it "adds escape sequences to highlight some strings if the message is not specified and :highlight option is specified" do + e = RuntimeError.new("") + + full_message = e.full_message(highlight: true, order: :top).lines + full_message[0].should.end_with? "\e[1;4munhandled exception\e[m\n" + + full_message = e.full_message(highlight: true, order: :bottom).lines + full_message[0].should == "\e[1mTraceback\e[m (most recent call last):\n" + full_message[-1].should.end_with? "\e[1;4munhandled exception\e[m\n" + + full_message = e.full_message(highlight: false, order: :top).lines + full_message[0].should.end_with? "unhandled exception\n" + + full_message = e.full_message(highlight: false, order: :bottom).lines + full_message[0].should == "Traceback (most recent call last):\n" + full_message[-1].should.end_with? "unhandled exception\n" + end + end + + describe "generic Error" do + it "should not report as unhandled in any event" do + StandardError.new("").full_message.should !~ /unhandled exception/ + StandardError.new("non-empty").full_message.should !~ /unhandled exception/ + end + end + end + it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do begin line = __LINE__; raise "first line\nsecond line" rescue => e full_message = e.full_message(highlight: false, order: :top).lines - full_message[0].should.start_with?("#{__FILE__}:#{line}:in `") + full_message[0].should.start_with?("#{__FILE__}:#{line}:in ") full_message[0].should.end_with?(": first line (RuntimeError)\n") full_message[1].should == "second line\n" end @@ -62,7 +123,7 @@ describe "Exception#full_message" do line = __LINE__; raise "first line\nsecond line\nthird line" rescue => e full_message = e.full_message(highlight: true, order: :top).lines - full_message[0].should.start_with?("#{__FILE__}:#{line}:in `") + full_message[0].should.start_with?("#{__FILE__}:#{line}:in ") full_message[0].should.end_with?(": \e[1mfirst line (\e[1;4mRuntimeError\e[m\e[1m)\e[m\n") full_message[1].should == "\e[1msecond line\e[m\n" full_message[2].should == "\e[1mthird line\e[m\n" @@ -80,8 +141,8 @@ describe "Exception#full_message" do exception = e end - exception.full_message.should include "main exception" - exception.full_message.should include "the cause" + exception.full_message.should.include? "main exception" + exception.full_message.should.include? "the cause" end it 'contains all the chain of exceptions' do @@ -99,8 +160,67 @@ describe "Exception#full_message" do exception = e end - exception.full_message.should include "last exception" - exception.full_message.should include "intermediate exception" - exception.full_message.should include "origin exception" + exception.full_message.should.include? "last exception" + exception.full_message.should.include? "intermediate exception" + exception.full_message.should.include? "origin exception" + end + + it "relies on #detailed_message" do + e = RuntimeError.new("new error") + e.define_singleton_method(:detailed_message) { |**| "DETAILED MESSAGE" } + + e.full_message.lines.first.should =~ /DETAILED MESSAGE/ + end + + it "passes all its own keyword arguments (with :highlight default value and without :order default value) to #detailed_message" do + e = RuntimeError.new("new error") + options_passed = nil + e.define_singleton_method(:detailed_message) do |**options| + options_passed = options + "DETAILED MESSAGE" + end + + e.full_message(foo: "bar") + options_passed.should == { foo: "bar", highlight: Exception.to_tty? } + end + + it "converts #detailed_message returned value to String if it isn't a String" do + message = Object.new + def message.to_str; "DETAILED MESSAGE"; end + + e = RuntimeError.new("new error") + e.define_singleton_method(:detailed_message) { |**| message } + + e.full_message.lines.first.should =~ /DETAILED MESSAGE/ + end + + it "uses class name if #detailed_message returns nil" do + e = RuntimeError.new("new error") + e.define_singleton_method(:detailed_message) { |**| nil } + + e.full_message(highlight: false).lines.first.should =~ /RuntimeError/ + e.full_message(highlight: true).lines.first.should =~ /#{Regexp.escape("\e[1;4mRuntimeError\e[m")}/ + end + + it "uses class name if exception object doesn't respond to #detailed_message" do + e = RuntimeError.new("new error") + class << e + undef :detailed_message + end + + e.full_message(highlight: false).lines.first.should =~ /RuntimeError/ + e.full_message(highlight: true).lines.first.should =~ /#{Regexp.escape("\e[1;4mRuntimeError\e[m")}/ + end + + it "allows cause with empty backtrace" do + begin + raise RuntimeError.new("Some runtime error"), cause: RuntimeError.new("Some other runtime error") + rescue => e + end + + full_message = e.full_message + full_message.should.include? "RuntimeError" + full_message.should.include? "Some runtime error" + full_message.should.include? "Some other runtime error" end end |
