From d89bcdaa72fde71df0a6a2f92a9bfb21f08f33f2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 29 Oct 2025 12:37:07 -0700 Subject: [PATCH] Support cases where there are multiple missing / wrong kwargs This commit fixes the case when there are multiple missing or incorrect keywords provided to a method. Without this fix, ErrorHighlight itself will raise an exception --- lib/error_highlight/core_ext.rb | 2 +- test/test_error_highlight.rb | 44 ++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/error_highlight/core_ext.rb b/lib/error_highlight/core_ext.rb index d4f91e1..e6cacba 100644 --- a/lib/error_highlight/core_ext.rb +++ b/lib/error_highlight/core_ext.rb @@ -3,7 +3,7 @@ module ErrorHighlight module CoreExt private def generate_snippet - if ArgumentError === self && message =~ /\A(?:wrong number of arguments|missing keyword|unknown keyword|no keywords accepted)\b/ + if ArgumentError === self && message =~ /\A(?:wrong number of arguments|missing keyword[s]?|unknown keyword[s]?|no keywords accepted)\b/ locs = self.backtrace_locations return "" if locs.size < 2 callee_loc, caller_loc = locs diff --git a/test/test_error_highlight.rb b/test/test_error_highlight.rb index 208dea8..43e2320 100644 --- a/test/test_error_highlight.rb +++ b/test/test_error_highlight.rb @@ -44,7 +44,7 @@ def preprocess(msg) def assert_error_message(klass, expected_msg, &blk) omit unless klass < ErrorHighlight::CoreExt err = assert_raise(klass, &blk) - unless klass == ArgumentError && err.message =~ /\A(?:wrong number of arguments|missing keyword|unknown keyword|no keywords accepted)\b/ + 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]) @@ -1502,6 +1502,27 @@ def test_missing_keyword end end + def test_missing_keywords # multiple missing keywords + lineno = __LINE__ + assert_error_message(ArgumentError, <<~END) do +missing keywords: :kw2, :kw3 (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 16 } + | keyword_test(kw1: 1) + ^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ KEYWORD_TEST_LINENO } + #{ + MethodDefLocationSupported ? + "| def keyword_test(kw1:, kw2:, kw3:) + ^^^^^^^^^^^^" : + "(cannot highlight method definition; try Ruby 3.5 or later)" + } + END + + keyword_test(kw1: 1) + end + end + def test_unknown_keyword lineno = __LINE__ assert_error_message(ArgumentError, <<~END) do @@ -1523,6 +1544,27 @@ def test_unknown_keyword end end + def test_unknown_keywords + lineno = __LINE__ + assert_error_message(ArgumentError, <<~END) do +unknown keywords: :kw4, :kw5 (ArgumentError) + + caller: #{ __FILE__ }:#{ lineno + 16 } + | keyword_test(kw1: 1, kw2: 2, kw3: 3, kw4: 4, kw5: 5) + ^^^^^^^^^^^^ + callee: #{ __FILE__ }:#{ KEYWORD_TEST_LINENO } + #{ + MethodDefLocationSupported ? + "| def keyword_test(kw1:, kw2:, kw3:) + ^^^^^^^^^^^^" : + "(cannot highlight method definition; try Ruby 3.5 or later)" + } + 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,