make Sinatra::Delegator play nice with method_missing proxies, fixes #245
This commit is contained in:
parent
1632f24b7d
commit
53b5ccde48
|
@ -1490,6 +1490,14 @@ module Sinatra
|
||||||
methods.each do |method_name|
|
methods.each do |method_name|
|
||||||
eval <<-RUBY, binding, '(__DELEGATE__)', 1
|
eval <<-RUBY, binding, '(__DELEGATE__)', 1
|
||||||
def #{method_name}(*args, &b)
|
def #{method_name}(*args, &b)
|
||||||
|
arity = ::Sinatra::Delegator.target.method(#{method_name.inspect}).arity
|
||||||
|
if arity < 0 ? args.size < -arity - 1 : args.size != arity
|
||||||
|
begin
|
||||||
|
return super
|
||||||
|
rescue NameError => e
|
||||||
|
raise e unless e.message.include? #{method_name.to_s.inspect}
|
||||||
|
end
|
||||||
|
end
|
||||||
::Sinatra::Delegator.target.send(#{method_name.inspect}, *args, &b)
|
::Sinatra::Delegator.target.send(#{method_name.inspect}, *args, &b)
|
||||||
end
|
end
|
||||||
private #{method_name.inspect}
|
private #{method_name.inspect}
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
class DelegatorTest < Test::Unit::TestCase
|
class DelegatorTest < Test::Unit::TestCase
|
||||||
class Mirror
|
class Mirror
|
||||||
attr_reader :last_call
|
attr_reader :last_call
|
||||||
|
|
||||||
|
Sinatra::Delegator.private_instance_methods.each do |method|
|
||||||
|
define_method(method) do |*a, &b|
|
||||||
|
method_missing(method, *a, &b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def method_missing(*a, &b)
|
def method_missing(*a, &b)
|
||||||
@last_call = [*a.map(&:to_s)]
|
@last_call = [*a.map(&:to_s)]
|
||||||
@last_call << b if b
|
@last_call << b if b
|
||||||
|
@ -100,13 +107,62 @@ class DelegatorTest < Test::Unit::TestCase
|
||||||
assert_equal app.last_call, ["helpers", mixin.to_s ]
|
assert_equal app.last_call, ["helpers", mixin.to_s ]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it "registers helpers with the delegation target" do
|
it "registers helpers with the delegation target" do
|
||||||
app, mixin = mirror, Module.new
|
app, mixin = mirror, Module.new
|
||||||
Sinatra.use mixin
|
Sinatra.use mixin
|
||||||
assert_equal app.last_call, ["use", mixin.to_s ]
|
assert_equal app.last_call, ["use", mixin.to_s ]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should work with method_missing proxies for options" do
|
||||||
|
mixin = Module.new do
|
||||||
|
def method_missing(method, *args, &block)
|
||||||
|
return super unless method.to_sym == :options
|
||||||
|
{:some => :option}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
app = mirror
|
||||||
|
def app.options(arg, *rest) "yay" end
|
||||||
|
|
||||||
|
a = b = c = nil
|
||||||
|
delegate do
|
||||||
|
extend mixin
|
||||||
|
a, b, c = options, options(1), options(1, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal({:some => :option}, a)
|
||||||
|
assert_equal("yay", b)
|
||||||
|
assert_equal("yay", c)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should work with method_missing proxies for methods arity > 0" do
|
||||||
|
mixin = Module.new do
|
||||||
|
def method_missing(method, *args, &block)
|
||||||
|
return super unless method.to_sym == :options
|
||||||
|
{:some => :option}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
app = mirror
|
||||||
|
def app.options(arg) "yay" end
|
||||||
|
|
||||||
|
a = b = c = nil
|
||||||
|
delegate do
|
||||||
|
extend mixin
|
||||||
|
a, b, c = options, options(1), options(1, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal({:some => :option}, a)
|
||||||
|
assert_equal("yay", b)
|
||||||
|
assert_equal({:some => :option}, c)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not raise a NameError for methods not handled by a proxy" do
|
||||||
|
app = mirror
|
||||||
|
def app.options(arg) "yay" end
|
||||||
|
assert_raises(ArgumentError) { delegate { options }}
|
||||||
|
end
|
||||||
|
|
||||||
delegates 'get'
|
delegates 'get'
|
||||||
delegates 'patch'
|
delegates 'patch'
|
||||||
delegates 'put'
|
delegates 'put'
|
||||||
|
|
Loading…
Reference in New Issue