You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
4.5 KiB
121 lines
4.5 KiB
commit 018b25811118c3bb95162324b3feae3a1e2b9923
|
|
Author: Yehuda Katz <wycats@gmail.com>
|
|
Date: Sat Jul 2 20:51:23 2011 -0700
|
|
|
|
Get method_missing working again. I'm not sure how it was working before, but the tests didn't pass.
|
|
|
|
# Altered a bit to work with this version.
|
|
diff --git a/lib/thor/task.rb b/lib/thor/task.rb
|
|
index 8dcff53..f94d5b6 100644
|
|
--- a/lib/thor/task.rb
|
|
+++ b/lib/thor/task.rb
|
|
@@ -18,8 +18,15 @@ class Thor
|
|
# By default, a task invokes a method in the thor class. You can change this
|
|
# implementation to create custom tasks.
|
|
def run(instance, args=[])
|
|
- public_method?(instance) ?
|
|
- instance.send(name, *args) : instance.class.handle_no_task_error(name)
|
|
+ if private_method?(instance)
|
|
+ instance.class.handle_no_task_error(name)
|
|
+ elsif public_method?(instance)
|
|
+ instance.send(name, *args)
|
|
+ elsif local_method?(instance, :method_missing)
|
|
+ instance.send(:method_missing, name.to_sym, *args)
|
|
+ else
|
|
+ instance.class.handle_no_task_error(name)
|
|
+ end
|
|
rescue ArgumentError => e
|
|
handle_argument_error?(instance, e, caller) ?
|
|
instance.class.handle_argument_error(self, e) : (raise e)
|
|
@@ -71,6 +78,15 @@ class Thor
|
|
(collection & [name.to_s, name.to_sym]).empty?
|
|
end
|
|
|
|
+ def private_method?(instance)
|
|
+ !(instance.private_methods & [name.to_s, name.to_sym]).empty?
|
|
+ end
|
|
+
|
|
+ def local_method?(instance, name)
|
|
+ methods = instance.public_methods(false) + instance.private_methods(false) + instance.protected_methods(false)
|
|
+ !(methods & [name.to_s, name.to_sym]).empty?
|
|
+ end
|
|
+
|
|
def sans_backtrace(backtrace, caller) #:nodoc:
|
|
saned = backtrace.reject { |frame| frame =~ FILE_REGEXP }
|
|
saned -= caller
|
|
@@ -105,11 +121,7 @@ class Thor
|
|
|
|
def run(instance, args=[])
|
|
if (instance.methods & [name.to_s, name.to_sym]).empty?
|
|
- if ((instance.protected_methods + instance.public_methods) & ([:method_missing, "method_missing"])).empty?
|
|
- super
|
|
- else
|
|
- instance.send(:method_missing, name.to_sym, *args)
|
|
- end
|
|
+ super
|
|
else
|
|
instance.class.handle_no_task_error(name)
|
|
end
|
|
diff --git a/spec/task_spec.rb b/spec/task_spec.rb
|
|
index 1c7ea7c..3372de1 100644
|
|
--- a/spec/task_spec.rb
|
|
+++ b/spec/task_spec.rb
|
|
@@ -11,21 +11,18 @@ describe Thor::Task do
|
|
|
|
describe "#formatted_usage" do
|
|
it "includes namespace within usage" do
|
|
- Object.stub!(:namespace).and_return("foo")
|
|
- Object.stub!(:arguments).and_return([])
|
|
- task(:bar => :required).formatted_usage(Object).should == "foo:can_has --bar=BAR"
|
|
+ object = Struct.new(:namespace, :arguments).new("foo", [])
|
|
+ task(:bar => :required).formatted_usage(object).should == "foo:can_has --bar=BAR"
|
|
end
|
|
|
|
it "removes default from namespace" do
|
|
- Object.stub!(:namespace).and_return("default:foo")
|
|
- Object.stub!(:arguments).and_return([])
|
|
- task(:bar => :required).formatted_usage(Object).should == ":foo:can_has --bar=BAR"
|
|
+ object = Struct.new(:namespace, :arguments).new("default:foo", [])
|
|
+ task(:bar => :required).formatted_usage(object).should == ":foo:can_has --bar=BAR"
|
|
end
|
|
|
|
it "injects arguments into usage" do
|
|
- Object.stub!(:namespace).and_return("foo")
|
|
- Object.stub!(:arguments).and_return([ Thor::Argument.new(:bar, nil, true, :string) ])
|
|
- task(:foo => :required).formatted_usage(Object).should == "foo:can_has BAR --foo=FOO"
|
|
+ object = Struct.new(:namespace, :arguments).new("foo", [Thor::Argument.new(:bar, nil, true, :string)])
|
|
+ task(:foo => :required).formatted_usage(object).should == "foo:can_has BAR --foo=FOO"
|
|
end
|
|
end
|
|
|
|
@@ -55,15 +52,23 @@ describe Thor::Task do
|
|
describe "#run" do
|
|
it "runs a task by calling a method in the given instance" do
|
|
mock = mock()
|
|
- mock.should_receive(:send).with("can_has", 1, 2, 3)
|
|
- task.run(mock, [1, 2, 3])
|
|
+ mock.should_receive(:can_has).and_return {|*args| args }
|
|
+ task.run(mock, [1, 2, 3]).should == [1, 2, 3]
|
|
end
|
|
|
|
it "raises an error if the method to be invoked is private" do
|
|
- mock = mock()
|
|
- mock.should_receive(:private_methods).and_return(['can_has'])
|
|
- mock.class.should_receive(:handle_no_task_error).with("can_has")
|
|
- task.run(mock)
|
|
+ klass = Class.new do
|
|
+ def self.handle_no_task_error(name)
|
|
+ name
|
|
+ end
|
|
+
|
|
+ private
|
|
+ def can_has
|
|
+ "fail"
|
|
+ end
|
|
+ end
|
|
+
|
|
+ task.run(klass.new).should == "can_has"
|
|
end
|
|
end
|
|
end
|