Fix a SyntaxError on Ruby 2.7.0 caused by arguments forwarding syntax
## Motivation and Context The gemspec already declares `required_ruby_version >= 2.7.0`, but `ServerContext` used the `...` arguments forwarding syntax in `method_missing`. That syntax was added in Ruby 2.7.3, so requiring the gem raised a `SyntaxError` on Ruby 2.7.0 through 2.7.2, and the library could not be loaded at all. RuboCop did not catch this because its Parser backend runs on Ruby 2.7.8, where the syntax is valid. CI missed it too because the test matrix tested `2.7`, which resolves to the latest 2.7.x rather than the declared minimum. ## How Has This Been Tested? Forward arguments explicitly with `*args, **kwargs, &block` so the method loads on Ruby 2.7.0, and pin the CI test matrix to 2.7.0 so the suite runs against the declared minimum instead of the latest 2.7.x. Running the suite on 2.7.0 also requires a `Hash.ruby2_keywords_hash?` shim in the test helper, since mocha would otherwise raise a `NoMethodError` on that version. ## Breaking Changes None. Closes #418
This commit is contained in:
parent
217542f812
commit
c4c73e05f5
4 changed files with 32 additions and 3 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
entry:
|
||||
- { ruby: '2.7', allowed-failure: false }
|
||||
- { ruby: '2.7.0', allowed-failure: false } # Minimum supported Ruby version.
|
||||
- { ruby: '3.0', allowed-failure: false }
|
||||
- { ruby: '3.1', allowed-failure: false }
|
||||
- { ruby: '3.2', allowed-failure: false }
|
||||
|
|
|
|||
|
|
@ -130,9 +130,14 @@ module MCP
|
|||
end
|
||||
end
|
||||
|
||||
def method_missing(name, ...)
|
||||
# Forward arguments explicitly with `*args, **kwargs, &block` rather than the `...` forwarding syntax.
|
||||
# The gem supports Ruby 2.7.0 (see `required_ruby_version`), but RuboCop's Parser backend only runs on Ruby 2.7.8,
|
||||
# so leading-argument forwarding like `def method_missing(name, ...)` is allowed by the linter even though it
|
||||
# raises a `SyntaxError` on Ruby 2.7.0 through 2.7.2 (it was added in Ruby 2.7.3). Explicit forwarding keeps
|
||||
# this method loadable on Ruby 2.7.0.
|
||||
def method_missing(name, *args, **kwargs, &block)
|
||||
if @context.respond_to?(name)
|
||||
@context.public_send(name, ...)
|
||||
@context.public_send(name, *args, **kwargs, &block)
|
||||
else
|
||||
super
|
||||
end
|
||||
|
|
|
|||
|
|
@ -201,6 +201,20 @@ module MCP
|
|||
assert_equal "custom_value", server_context.custom_method
|
||||
end
|
||||
|
||||
test "ServerContext forwards positional, keyword, and block arguments to the context" do
|
||||
context = Object.new
|
||||
def context.combine(prefix, suffix:, &block)
|
||||
block.call("#{prefix}-#{suffix}")
|
||||
end
|
||||
progress = Progress.new(notification_target: mock, progress_token: nil)
|
||||
|
||||
server_context = ServerContext.new(context, progress: progress, notification_target: mock)
|
||||
|
||||
result = server_context.combine("a", suffix: "b", &:upcase)
|
||||
|
||||
assert_equal "A-B", result
|
||||
end
|
||||
|
||||
test "ServerContext#report_progress works with nil context" do
|
||||
progress = mock
|
||||
progress.expects(:report).with(50, total: 100, message: nil).once
|
||||
|
|
|
|||
|
|
@ -6,6 +6,16 @@ require "minitest/autorun"
|
|||
require "minitest/mock"
|
||||
require "mocha/minitest"
|
||||
|
||||
# mocha relies on `Hash.ruby2_keywords_hash?`, which is absent on Ruby 2.7.0 and the earlier 2.7.x releases
|
||||
# before it was backported. Those versions also lack the flag-setting APIs, so no hash is ever flagged as
|
||||
# ruby2_keywords and returning `false` is correct. Without this shim, mocha raises `NoMethodError` and
|
||||
# the suite cannot run on Ruby 2.7.0.
|
||||
unless Hash.respond_to?(:ruby2_keywords_hash?)
|
||||
def Hash.ruby2_keywords_hash?(_hash)
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
require "active_support"
|
||||
require "active_support/test_case"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue