summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorStan Lo <stan001212@gmail.com>2023-02-27 19:07:14 +0800
committergit <svn-admin@ruby-lang.org>2023-02-27 11:07:19 +0000
commit0aa50a03b1ea8d37069ae57c469f43860abbcf05 (patch)
treee489108876b1dd857eb888f9679f89196c443dcb /test
parent4f611df3f7f61fbdf83b02121dd1edea0b7c68ec (diff)
[ruby/irb] Provide more useful message when
`IRB::Inspector#inspect_value` errors (https://github.com/ruby/irb/pull/511) **Before** ``` irb(main):001:0> c = Cat.new "foo" (Object doesn't support #inspect) => ``` **After** ``` irb(main):001:0> c = Cat.new "foo" An error occurred when inspecting the object: #<NoMethodError: undefined method `is_a?' for foo:Cat if obj.is_a?(String) ^^^^^^> Result of Kernel#inspect: #<Cat:0x0000000109090d80 @name="foo"> => ```
Diffstat (limited to 'test')
-rw-r--r--test/irb/test_context.rb62
1 files changed, 57 insertions, 5 deletions
diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb
index c0a5164a32..55f258de88 100644
--- a/test/irb/test_context.rb
+++ b/test/irb/test_context.rb
@@ -125,11 +125,11 @@ module TestIRB
[:marshal, "123", Marshal.dump(123)],
],
failed: [
- [false, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
- [:p, "class Foo; undef inspect ;end; Foo.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
- [true, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
- [:yaml, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
- [:marshal, "[Object.new, Class.new]", /\(Object doesn't support #inspect\)\n(=> )?\n/]
+ [false, "BasicObject.new", /#<NoMethodError: undefined method `to_s' for/],
+ [:p, "class Foo; undef inspect ;end; Foo.new", /#<NoMethodError: undefined method `inspect' for/],
+ [true, "BasicObject.new", /#<NoMethodError: undefined method `is_a\?' for/],
+ [:yaml, "BasicObject.new", /#<NoMethodError: undefined method `inspect' for/],
+ [:marshal, "[Object.new, Class.new]", /#<TypeError: can't dump anonymous class #<Class:/]
]
}.each do |scenario, cases|
cases.each do |inspect_mode, input, expected|
@@ -149,6 +149,58 @@ module TestIRB
end
end
+ def test_object_inspection_falls_back_to_kernel_inspect_when_errored
+ omit if RUBY_ENGINE == "truffleruby"
+ verbose, $VERBOSE = $VERBOSE, nil
+ main = Object.new
+ main.singleton_class.module_eval <<~RUBY
+ class Foo
+ def inspect
+ raise "foo"
+ end
+ end
+ RUBY
+
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new(["Foo.new"]))
+ out, err = capture_output do
+ irb.eval_input
+ end
+ assert_empty err
+ assert_match(/An error occurred when inspecting the object: #<RuntimeError: foo>/, out)
+ assert_match(/Result of Kernel#inspect: #<#<Class:.*>::Foo:/, out)
+ ensure
+ $VERBOSE = verbose
+ end
+
+ def test_object_inspection_prints_useful_info_when_kernel_inspect_also_errored
+ omit if RUBY_VERSION < '2.7' || RUBY_ENGINE == "truffleruby"
+ verbose, $VERBOSE = $VERBOSE, nil
+ main = Object.new
+ main.singleton_class.module_eval <<~RUBY
+ class Foo
+ def initialize
+ # Kernel#inspect goes through instance variables with #inspect
+ # So this will cause Kernel#inspect to fail
+ @foo = BasicObject.new
+ end
+
+ def inspect
+ raise "foo"
+ end
+ end
+ RUBY
+
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new(["Foo.new"]))
+ out, err = capture_output do
+ irb.eval_input
+ end
+ assert_empty err
+ assert_match(/An error occurred when inspecting the object: #<RuntimeError: foo>/, out)
+ assert_match(/An error occurred when running Kernel#inspect: #<NoMethodError: undefined method `inspect' for/, out)
+ ensure
+ $VERBOSE = verbose
+ end
+
def test_default_config
assert_equal(true, @context.use_autocomplete?)
end