diff --git a/faraday.gemspec b/faraday.gemspec index c72bd9275..2212e9811 100644 --- a/faraday.gemspec +++ b/faraday.gemspec @@ -19,6 +19,7 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 2.4' spec.add_dependency 'multipart-post', '>= 1.2', '< 3' + spec.add_dependency 'ruby2_keywords' files = %w[CHANGELOG.md LICENSE.md README.md Rakefile examples lib spec] spec.files = `git ls-files -z #{files.join(' ')}`.split("\0") diff --git a/lib/faraday/dependency_loader.rb b/lib/faraday/dependency_loader.rb index 57345646d..3f1708f8c 100644 --- a/lib/faraday/dependency_loader.rb +++ b/lib/faraday/dependency_loader.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'ruby2_keywords' + module Faraday # DependencyLoader helps Faraday adapters and middleware load dependencies. module DependencyLoader @@ -13,7 +15,7 @@ def dependency(lib = nil) self.load_error = e end - def new(*) + ruby2_keywords def new(*) unless loaded? raise "missing dependency for #{self}: #{load_error.message}" end diff --git a/lib/faraday/rack_builder.rb b/lib/faraday/rack_builder.rb index 5157bf50c..33ba562c3 100644 --- a/lib/faraday/rack_builder.rb +++ b/lib/faraday/rack_builder.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'ruby2_keywords' require 'faraday/adapter_registry' module Faraday @@ -27,7 +28,7 @@ class Handler attr_reader :name - def initialize(klass, *args, &block) + ruby2_keywords def initialize(klass, *args, &block) @name = klass.to_s REGISTRY.set(klass) if klass.respond_to?(:name) @args = args @@ -89,7 +90,7 @@ def locked? @handlers.frozen? end - def use(klass, *args, &block) + ruby2_keywords def use(klass, *args, &block) if klass.is_a? Symbol use_symbol(Faraday::Middleware, klass, *args, &block) else @@ -99,15 +100,15 @@ def use(klass, *args, &block) end end - def request(key, *args, &block) + ruby2_keywords def request(key, *args, &block) use_symbol(Faraday::Request, key, *args, &block) end - def response(key, *args, &block) + ruby2_keywords def response(key, *args, &block) use_symbol(Faraday::Response, key, *args, &block) end - def adapter(klass = NO_ARGUMENT, *args, &block) + ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block) return @adapter if klass == NO_ARGUMENT klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol) @@ -116,7 +117,7 @@ def adapter(klass = NO_ARGUMENT, *args, &block) ## methods to push onto the various positions in the stack: - def insert(index, *args, &block) + ruby2_keywords def insert(index, *args, &block) raise_if_locked index = assert_index(index) handler = self.class::Handler.new(*args, &block) @@ -125,12 +126,12 @@ def insert(index, *args, &block) alias insert_before insert - def insert_after(index, *args, &block) + ruby2_keywords def insert_after(index, *args, &block) index = assert_index(index) insert(index + 1, *args, &block) end - def swap(index, *args, &block) + ruby2_keywords def swap(index, *args, &block) raise_if_locked index = assert_index(index) @handlers.delete_at(index) @@ -234,7 +235,7 @@ def is_adapter?(klass) # rubocop:disable Naming/PredicateName klass.ancestors.include?(Faraday::Adapter) end - def use_symbol(mod, key, *args, &block) + ruby2_keywords def use_symbol(mod, key, *args, &block) use(mod.lookup_middleware(key), *args, &block) end diff --git a/spec/faraday/rack_builder_spec.rb b/spec/faraday/rack_builder_spec.rb index b9882054d..28978291f 100644 --- a/spec/faraday/rack_builder_spec.rb +++ b/spec/faraday/rack_builder_spec.rb @@ -193,4 +193,148 @@ class Broken < Faraday::Middleware end end end + + context 'when middleware is added with named arguments' do + let(:conn) { Faraday::Connection.new {} } + + let(:dog_middleware) do + Class.new(Faraday::Middleware) do + attr_accessor :name + def initialize(app, name:) + super(app) + @name = name + end + end + end + let(:dog) do + subject.handlers.find { |handler| handler == dog_middleware }.build + end + + it 'adds a handler to construct middleware with options passed to use' do + subject.use dog_middleware, name: 'Rex' + expect { dog }.to_not output( + /warning: Using the last argument as keyword parameters is deprecated/ + ).to_stderr + expect(dog.name).to eq('Rex') + end + end + + context 'when a request adapter is added with named arguments' do + let(:conn) { Faraday::Connection.new {} } + + let(:cat_request) do + Class.new(Faraday::Middleware) do + attr_accessor :name + def initialize(app, name:) + super(app) + @name = name + end + end + end + let(:cat) do + subject.handlers.find { |handler| handler == cat_request }.build + end + + it 'adds a handler to construct request adapter with options passed to request' do + Faraday::Request.register_middleware cat_request: cat_request + subject.request :cat_request, name: 'Felix' + expect { cat }.to_not output( + /warning: Using the last argument as keyword parameters is deprecated/ + ).to_stderr + expect(cat.name).to eq('Felix') + end + end + + context 'when a response adapter is added with named arguments' do + let(:conn) { Faraday::Connection.new {} } + + let(:fish_response) do + Class.new(Faraday::Response::Middleware) do + attr_accessor :name + def initialize(app, name:) + super(app) + @name = name + end + end + end + let(:fish) do + subject.handlers.find { |handler| handler == fish_response }.build + end + + it 'adds a handler to construct response adapter with options passed to response' do + Faraday::Response.register_middleware fish_response: fish_response + subject.response :fish_response, name: 'Bubbles' + expect { fish }.to_not output( + /warning: Using the last argument as keyword parameters is deprecated/ + ).to_stderr + expect(fish.name).to eq('Bubbles') + end + end + + context 'when a plain adapter is added with named arguments' do + let(:conn) { Faraday::Connection.new {} } + + let(:rabbit_adapter) do + Class.new(Faraday::Adapter) do + attr_accessor :name + def initialize(app, name:) + super(app) + @name = name + end + end + end + let(:rabbit) do + subject.adapter.build + end + + it 'adds a handler to construct adapter with options passed to adapter' do + Faraday::Adapter.register_middleware rabbit_adapter: rabbit_adapter + subject.adapter :rabbit_adapter, name: 'Thumper' + expect { rabbit }.to_not output( + /warning: Using the last argument as keyword parameters is deprecated/ + ).to_stderr + expect(rabbit.name).to eq('Thumper') + end + end + + context 'when handlers are directly added or updated' do + let(:conn) { Faraday::Connection.new {} } + + let(:rock_handler) do + Class.new do + attr_accessor :name + def initialize(_app, name:) + @name = name + end + end + end + let(:rock) do + subject.handlers.find { |handler| handler == rock_handler }.build + end + + it 'adds a handler to construct adapter with options passed to insert' do + subject.insert 0, rock_handler, name: 'Stony' + expect { rock }.to_not output( + /warning: Using the last argument as keyword parameters is deprecated/ + ).to_stderr + expect(rock.name).to eq('Stony') + end + + it 'adds a handler with options passed to insert_after' do + subject.insert_after 0, rock_handler, name: 'Rocky' + expect { rock }.to_not output( + /warning: Using the last argument as keyword parameters is deprecated/ + ).to_stderr + expect(rock.name).to eq('Rocky') + end + + it 'adds a handler with options passed to swap' do + subject.insert 0, rock_handler, name: 'Flint' + subject.swap 0, rock_handler, name: 'Chert' + expect { rock }.to_not output( + /warning: Using the last argument as keyword parameters is deprecated/ + ).to_stderr + expect(rock.name).to eq('Chert') + end + end end