diff options
Diffstat (limited to 'test/error_highlight/test_error_highlight.rb')
| -rw-r--r-- | test/error_highlight/test_error_highlight.rb | 309 |
1 files changed, 270 insertions, 39 deletions
diff --git a/test/error_highlight/test_error_highlight.rb b/test/error_highlight/test_error_highlight.rb index 8aa5eb9c8d..5f664de502 100644 --- a/test/error_highlight/test_error_highlight.rb +++ b/test/error_highlight/test_error_highlight.rb @@ -44,14 +44,16 @@ class ErrorHighlightTest < Test::Unit::TestCase def assert_error_message(klass, expected_msg, &blk) omit unless klass < ErrorHighlight::CoreExt err = assert_raise(klass, &blk) - spot = ErrorHighlight.spot(err) - if spot - assert_kind_of(Integer, spot[:first_lineno]) - assert_kind_of(Integer, spot[:first_column]) - assert_kind_of(Integer, spot[:last_lineno]) - assert_kind_of(Integer, spot[:last_column]) - assert_kind_of(String, spot[:snippet]) - assert_kind_of(Array, spot[:script_lines]) + unless klass == ArgumentError && err.message =~ /\A(?:wrong number of arguments|missing keyword[s]?|unknown keyword[s]?|no keywords accepted)\b/ + spot = ErrorHighlight.spot(err) + if spot + assert_kind_of(Integer, spot[:first_lineno]) + assert_kind_of(Integer, spot[:first_column]) + assert_kind_of(Integer, spot[:last_lineno]) + assert_kind_of(Integer, spot[:last_column]) + assert_kind_of(String, spot[:snippet]) + assert_kind_of(Array, spot[:script_lines]) + end end assert_equal(preprocess(expected_msg).chomp, err.detailed_message(highlight: false).sub(/ \((?:NoMethod|Name)Error\)/, "")) end @@ -889,27 +891,13 @@ uninitialized constant ErrorHighlightTest::NotDefined end end - if ErrorHighlight.const_get(:Spotter).const_get(:OPT_GETCONSTANT_PATH) - def test_COLON2_5 - # Unfortunately, we cannot identify which `NotDefined` caused the NameError - assert_error_message(NameError, <<~END) do - uninitialized constant ErrorHighlightTest::NotDefined - END - - ErrorHighlightTest::NotDefined::NotDefined - end - end - else - def test_COLON2_5 - assert_error_message(NameError, <<~END) do + def test_COLON2_5 + # Unfortunately, we cannot identify which `NotDefined` caused the NameError + assert_error_message(NameError, <<~END) do uninitialized constant ErrorHighlightTest::NotDefined + END - ErrorHighlightTest::NotDefined::NotDefined - ^^^^^^^^^^^^ - END - - ErrorHighlightTest::NotDefined::NotDefined - end + ErrorHighlightTest::NotDefined::NotDefined end end @@ -1097,10 +1085,11 @@ nil can't be coerced into Integer (TypeError) end end + OF_NIL_INTO_INTEGER = RUBY_VERSION < "4.1." ? "from nil to integer" : "of nil into Integer" def test_args_CALL_2 v = [] assert_error_message(TypeError, <<~END) do -no implicit conversion from nil to integer (TypeError) +no implicit conversion #{OF_NIL_INTO_INTEGER} (TypeError) v[nil] ^^^ @@ -1111,12 +1100,13 @@ no implicit conversion from nil to integer (TypeError) end def test_args_ATTRASGN_1 - v = [] - assert_error_message(ArgumentError, <<~END) do -wrong number of arguments (given 1, expected 2..3) (ArgumentError) + v = method(:raise).to_proc + recv = NEW_MESSAGE_FORMAT ? "an instance of Proc" : v.inspect + assert_error_message(NoMethodError, <<~END) do +undefined method `[]=' for #{ recv } v [ ] = 1 - ^^^^^^ + ^^^^^ END v [ ] = 1 @@ -1126,7 +1116,7 @@ wrong number of arguments (given 1, expected 2..3) (ArgumentError) def test_args_ATTRASGN_2 v = [] assert_error_message(TypeError, <<~END) do -no implicit conversion from nil to integer (TypeError) +no implicit conversion #{OF_NIL_INTO_INTEGER} (TypeError) v [nil] = 1 ^^^^^^^^ @@ -1188,7 +1178,7 @@ no implicit conversion of Symbol into String (TypeError) v = [] assert_error_message(TypeError, <<~END) do -no implicit conversion from nil to integer (TypeError) +no implicit conversion #{OF_NIL_INTO_INTEGER} (TypeError) v [nil] += 42 ^^^^^^^^^^ @@ -1199,16 +1189,16 @@ no implicit conversion from nil to integer (TypeError) end def test_args_OP_ASGN1_aref_2 - v = [] + v = method(:raise).to_proc assert_error_message(ArgumentError, <<~END) do -wrong number of arguments (given 0, expected 1..2) (ArgumentError) +ArgumentError (ArgumentError) - v [ ] += 42 - ^^^^^^^^ + v [ArgumentError] += 42 + ^^^^^^^^^^^^^^^^^^^^ END - v [ ] += 42 + v [ArgumentError] += 42 end end @@ -1453,6 +1443,199 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE } end end + begin + ->{}.call(1) + rescue ArgumentError => exc + MethodDefLocationSupported = + RubyVM::AbstractSyntaxTree.respond_to?(:node_id_for_backtrace_location) && + RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(exc.backtrace_locations.first) + end + + def process_callee_snippet(str) + return str if MethodDefLocationSupported + + str.sub(/\n +\|.*\n +\^+\n\z/, "") + end + + WRONG_NUMBER_OF_ARGUMENTS_LINENO = __LINE__ + 1 + def wrong_number_of_arguments_test(x, y) + x + y + end + + def test_wrong_number_of_arguments_for_method + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +wrong number of arguments (given 1, expected 2) (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | wrong_number_of_arguments_test(1) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ WRONG_NUMBER_OF_ARGUMENTS_LINENO } + | def wrong_number_of_arguments_test(x, y) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + END + + wrong_number_of_arguments_test(1) + end + end + + KEYWORD_TEST_LINENO = __LINE__ + 1 + def keyword_test(kw1:, kw2:, kw3:) + kw1 + kw2 + kw3 + end + + def test_missing_keyword + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +missing keyword: :kw3 (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | keyword_test(kw1: 1, kw2: 2) + ^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ KEYWORD_TEST_LINENO } + | def keyword_test(kw1:, kw2:, kw3:) + ^^^^^^^^^^^^ + END + + keyword_test(kw1: 1, kw2: 2) + end + end + + def test_missing_keywords # multiple missing keywords + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +missing keywords: :kw2, :kw3 (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | keyword_test(kw1: 1) + ^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ KEYWORD_TEST_LINENO } + | def keyword_test(kw1:, kw2:, kw3:) + ^^^^^^^^^^^^ + END + + keyword_test(kw1: 1) + end + end + + def test_unknown_keyword + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +unknown keyword: :kw4 (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | keyword_test(kw1: 1, kw2: 2, kw3: 3, kw4: 4) + ^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ KEYWORD_TEST_LINENO } + | def keyword_test(kw1:, kw2:, kw3:) + ^^^^^^^^^^^^ + END + + keyword_test(kw1: 1, kw2: 2, kw3: 3, kw4: 4) + end + end + + def test_unknown_keywords + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +unknown keywords: :kw4, :kw5 (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | keyword_test(kw1: 1, kw2: 2, kw3: 3, kw4: 4, kw5: 5) + ^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ KEYWORD_TEST_LINENO } + | def keyword_test(kw1:, kw2:, kw3:) + ^^^^^^^^^^^^ + END + + keyword_test(kw1: 1, kw2: 2, kw3: 3, kw4: 4, kw5: 5) + end + end + + WRONG_NUBMER_OF_ARGUMENTS_TEST2_LINENO = __LINE__ + 1 + def wrong_number_of_arguments_test2( + long_argument_name_x, + long_argument_name_y, + long_argument_name_z + ) + long_argument_name_x + long_argument_name_y + long_argument_name_z + end + + def test_wrong_number_of_arguments_for_method2 + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +wrong number of arguments (given 1, expected 3) (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | wrong_number_of_arguments_test2(1) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ WRONG_NUBMER_OF_ARGUMENTS_TEST2_LINENO } + | def wrong_number_of_arguments_test2( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + END + + wrong_number_of_arguments_test2(1) + end + end + + def test_wrong_number_of_arguments_for_lambda_literal + v = -> {} + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +wrong number of arguments (given 1, expected 0) (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | v.call(1) + ^^^^^ + callee: #{ __FILE__ }:#{ lineno - 1 } + | v = -> {} + ^^ + END + + v.call(1) + end + end + + def test_wrong_number_of_arguments_for_lambda_method + v = lambda { } + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +wrong number of arguments (given 1, expected 0) (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | v.call(1) + ^^^^^ + callee: #{ __FILE__ }:#{ lineno - 1 } + | v = lambda { } + ^ + END + + v.call(1) + end + end + + DEFINE_METHOD_TEST_LINENO = __LINE__ + 1 + define_method :define_method_test do |x, y| + x + y + end + + def test_wrong_number_of_arguments_for_define_method + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +wrong number of arguments (given 1, expected 2) (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | define_method_test(1) + ^^^^^^^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ DEFINE_METHOD_TEST_LINENO } + | define_method :define_method_test do |x, y| + ^^ + END + + define_method_test(1) + end + end + def test_spoofed_filename Tempfile.create(["error_highlight_test", ".rb"], binmode: true) do |tmp| tmp << "module Dummy\nend\n" @@ -1521,6 +1704,54 @@ undefined method `foo' for #{ NIL_RECV_MESSAGE } assert_equal expected_spot, actual_spot end + module SingletonMethodWithSpacing + LINENO = __LINE__ + 1 + def self . baz(x:) + x + end + end + + def test_singleton_method_with_spacing_missing_keyword + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +missing keyword: :x (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | SingletonMethodWithSpacing.baz + ^^^^ + callee: #{ __FILE__ }:#{ SingletonMethodWithSpacing::LINENO } + | def self . baz(x:) + ^^^^^ + END + + SingletonMethodWithSpacing.baz + end + end + + module SingletonMethodMultipleKwargs + LINENO = __LINE__ + 1 + def self.run(shop_id:, param1:) + shop_id + param1 + end + end + + def test_singleton_method_multiple_missing_keywords + lineno = __LINE__ + assert_error_message(ArgumentError, process_callee_snippet(<<~END)) do +missing keywords: :shop_id, :param1 (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 12 } + | SingletonMethodMultipleKwargs.run + ^^^^ + callee: #{ __FILE__ }:#{ SingletonMethodMultipleKwargs::LINENO } + | def self.run(shop_id:, param1:) + ^^^^ + END + + SingletonMethodMultipleKwargs.run + end + end + private def find_node_by_id(node, node_id) |
