Skip to content

Fix ruby 3 error when keyword argument is passed #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/middleware/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ def flatten
# of the middleware.
#
# @param [Class] middleware The middleware class
def use(middleware, *args, &block)
def use(middleware, *args, **kwargs, &block)
if middleware.is_a?(Builder)
# Merge in the other builder's stack into our own
stack.concat(middleware.stack)
else
stack << [middleware, args, block]
stack << [middleware, args, kwargs, block]
end

self
Expand Down
5 changes: 3 additions & 2 deletions lib/middleware/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,18 @@ def build_call_chain(stack)
# is always the empty middleware, which does nothing but return.
stack.reverse.inject(EMPTY_MIDDLEWARE) do |next_middleware, current_middleware|
# Unpack the actual item
klass, args, block = current_middleware
klass, args, kwargs, block = current_middleware

# Default the arguments to an empty array. Otherwise in Ruby 1.8
# a `nil` args will actually pass `nil` into the class. Not what
# we want!
args ||= []
kwargs ||= {}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only added this line because runner_spec omits args, and only passes in klass. This wouldn't happen if builder is used.

However, if we no longer support Ruby 1.8, I wonder if we should remove this block all together, and amend runner_spec instead?


if klass.is_a?(Class)
# If the klass actually is a class, then instantiate it with
# the app and any other arguments given.
klass.new(next_middleware, *args, &block)
klass.new(next_middleware, *args, **kwargs, &block)
elsif klass.respond_to?(:call)
# Make it a lambda which calls the item then forwards up
# the chain.
Expand Down
26 changes: 25 additions & 1 deletion spec/middleware/builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@
let(:data) { { data: [] } }
let(:instance) { described_class.new }

class Foo
def initialize app, pos, key:
@app = app
@pos = pos
@key = key
end

def call env
env[:pos] = @pos
env[:key] = @key
@app.call(env)
end
end

# This returns a proc that can be used with the builder
# that simply appends data to an array in the env.
def appender_proc(data)
Expand Down Expand Up @@ -53,6 +67,16 @@ def appender_proc(data)
expect(data[:data]).to eq true
end

it 'handles positional and keyword arguments' do
data = {}

instance.use Foo, 1, key: 2
instance.call(data)

expect(data[:pos]).to eq 1
expect(data[:key]).to eq 2
end

it 'is able to add multiple items' do
data = {}
proc1 = ->(env) { env.tap { |obj| obj[:one] = :value_1 } }
Expand Down Expand Up @@ -239,4 +263,4 @@ def call env
end
end

end
end
23 changes: 22 additions & 1 deletion spec/middleware/runner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,27 @@ def call(env)
expect(env[:result]).to eq 42
end

it 'passes in keyword arguments if given' do
a = Class.new do
def initialize(_app, foo = nil, bar: nil)
@foo = foo
@bar = bar
end

def call(env)
env[:foo] = @foo
env[:bar] = @bar
end
end

env = {}
instance = described_class.new([[a, [42], { bar: 1764 }, nil]])
instance.call(env)

expect(env[:foo]).to eq 42
expect(env[:bar]).to eq 1764
end

it 'passes in a block if given' do
a = Class.new do
def initialize(_app, &block)
Expand All @@ -98,7 +119,7 @@ def call(env)

block = proc { 42 }
env = {}
instance = described_class.new([[a, nil, block]])
instance = described_class.new([[a, [], {}, block]])
instance.call(env)

expect(env[:result]).to eq 42
Expand Down