Extract kwargs to fix 2.7 warnings
Related: gitlab-org/gitlab#257438 (closed)
It fixes 2.7 warning related to actionpack-6.0.3.3/lib/action_dispatch/testing/integration.rb:418
https://github.com/rails/rails/blob/v6.0.3.3/actionpack/lib/action_dispatch/testing/integration.rb#L425 already contains ruby2_keywords, so the reason happens somewhere up in the chain.
The stacktrace from running: rspec './ee/spec/requests/api/wikis_spec.rb[1:6:3:2:1]'
"/Users/igordrozdov/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/actionpack-6.0.3.4/lib/action_dispatch/testing/integration.rb:419:in `method_missing'",
"/Users/igordrozdov/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/grape-path-helpers-1.5.0/lib/grape-path-helpers/named_route_matcher.rb:7:in `method_missing'",
"/Users/igordrozdov/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/rails-controller-testing-1.0.5/lib/rails/controller/testing/template_assertions.rb:62:in `process'",
"/Users/igordrozdov/Documents/Projects/gdk-new/gitlab/spec/support/helpers/workhorse_helpers.rb:75:in `workhorse_request_with_multiple_files'",
"/Users/igordrozdov/Documents/Projects/gdk-new/gitlab/spec/support/helpers/workhorse_helpers.rb:51:in `workhorse_request_with_file'",
"/Users/igordrozdov/Documents/Projects/gdk-new/gitlab/spec/support/helpers/workhorse_helpers.rb:27:in `workhorse_post_with_file'",
"/Users/igordrozdov/Documents/Projects/gdk-new/gitlab/spec/support/shared_examples/lib/wikis_api_examples.rb:140:in `block (2 levels) in <main>'",
Since the calling of process method goes through grape-path-helpers, we need to properly propagate it.
At first I came up with a solution that squashes kwargs into segments:
def method_missing(method_id, *args, **kwargs)
return super unless method_id.to_s =~ /_path$/
first_arg, *rest_args = args
segments = first_arg || {}
unless segments.is_a?(Hash)
raise ArgumentError, 'Helper options must be a hash'
end
segments.merge!(kwargs) # in case options were passed as kwargs
route = Grape::API::Instance.decorated_routes.detect do |r|
route_match?(r, method_id, segments)
end
if route
route.send(method_id, segments, *rest_args)
else
super
end
end
But maybe let's just extract path-methods-logic into a separate method and leave the propagation logic in the method-missing, it looks more safe:
def method_missing(method_id, *args, **kwargs)
return super unless method_id.to_s =~ /_path$/
success, result = call_path_method(method_id, *args, **kwargs)
if success
result
else
super
end
end
def call_path_method(method_id, *arguments)
segments = arguments.first || {}
route = Grape::API::Instance.decorated_routes.detect do |r|
route_match?(r, method_id, segments)
end
return false unless route
[true, route.send(method_id, *arguments)]
end
Edited by Igor Drozdov