Permalink
Browse files

Fix hooks on PerformableMethod and PerformableMailer [Closes #113]

  • Loading branch information...
1 parent 2cc1573 commit e132b5ddecc906f58dc04f7ccb50fadb6cd31f8b @bkeepers bkeepers committed Sep 9, 2010
@@ -61,6 +61,7 @@ def name
end
def payload_object=(object)
+ @payload_object = object
self.handler = object.to_yaml
end
@@ -10,10 +10,7 @@ def initialize(payload_class, target, options)
end
def method_missing(method, *args)
- Job.create({
- :payload_object => @payload_class.new(@target, method.to_sym, args),
- :priority => ::Delayed::Worker.default_priority
- }.merge(@options))
+ Job.enqueue({:payload_object => @payload_class.new(@target, method.to_sym, args)}.merge(@options))
end
end
@@ -22,7 +19,7 @@ def delay(options = {})
DelayProxy.new(PerformableMethod, self, options)
end
alias __delay__ delay
-
+
def send_later(method, *args)
warn "[DEPRECATION] `object.send_later(:method)` is deprecated. Use `object.delay.method"
__delay__.__send__(method, *args)
@@ -32,7 +29,7 @@ def send_at(time, method, *args)
warn "[DEPRECATION] `object.send_at(time, :method)` is deprecated. Use `object.delay(:run_at => time).method"
__delay__(:run_at => time).__send__(method, *args)
end
-
+
module ClassMethods
def handle_asynchronously(method)
aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
@@ -43,5 +40,5 @@ def handle_asynchronously(method)
alias_method_chain method, :delay
end
end
- end
+ end
end
@@ -3,7 +3,7 @@
module Delayed
class PerformableMailer < PerformableMethod
def perform
- object.send(method, *args).deliver
+ object.send(method_name, *args).deliver
end
end
end
@@ -1,27 +1,29 @@
module Delayed
- class PerformableMethod < Struct.new(:object, :method, :args)
- def initialize(object, method, args)
- raise NoMethodError, "undefined method `#{method}' for #{object.inspect}" unless object.respond_to?(method, true)
+ class PerformableMethod < Struct.new(:object, :method_name, :args)
+ delegate :method, :to => :object
- self.object = object
- self.args = args
- self.method = method.to_sym
+ def initialize(object, method_name, args)
+ raise NoMethodError, "undefined method `#{method_name}' for #{object.inspect}" unless object.respond_to?(method_name, true)
+
+ self.object = object
+ self.args = args
+ self.method_name = method_name.to_sym
end
-
+
def display_name
- "#{object.class}##{method}"
+ "#{object.class}##{method_name}"
end
-
+
def perform
- object.send(method, *args) if object
+ object.send(method_name, *args) if object
end
-
+
def method_missing(symbol, *args)
- object.respond_to?(symbol) ? object.send(symbol, *args) : super
+ object.send(symbol, *args)
end
-
+
def respond_to?(symbol, include_private=false)
- object.respond_to?(symbol, include_private) || super
- end
+ super || object.respond_to?(symbol, include_private)
+ end
end
end
@@ -7,18 +7,18 @@ def tell!(arg)
end
handle_asynchronously :tell!
end
-
+
it "should alias original method" do
Story.new.should respond_to(:tell_without_delay!)
Story.new.should respond_to(:tell_with_delay!)
end
-
+
it "should create a PerformableMethod" do
story = Story.create!
lambda {
job = story.tell!(1)
job.payload_object.class.should == Delayed::PerformableMethod
- job.payload_object.method.should == :tell_without_delay!
+ job.payload_object.method_name.should == :tell_without_delay!
job.payload_object.args.should == [1]
}.should change { Delayed::Job.count }
end
@@ -29,7 +29,7 @@ def tell!(arg)
lambda {
job = "hello".delay.count('l')
job.payload_object.class.should == Delayed::PerformableMethod
- job.payload_object.method.should == :count
+ job.payload_object.method_name.should == :count
job.payload_object.args.should == ['l']
}.should change { Delayed::Job.count }.by(1)
end
@@ -13,20 +13,20 @@ def signup(email)
lambda {
job = MyMailer.delay.signup('john@example.com')
job.payload_object.class.should == Delayed::PerformableMailer
- job.payload_object.method.should == :signup
+ job.payload_object.method_name.should == :signup
job.payload_object.args.should == ['john@example.com']
}.should change { Delayed::Job.count }.by(1)
end
end
-
+
describe "delay on a mail object" do
it "should raise an exception" do
lambda {
MyMailer.signup('john@example.com').delay
}.should raise_error(RuntimeError)
end
end
-
+
describe Delayed::PerformableMailer do
describe "perform" do
before do
@@ -42,5 +42,5 @@ def signup(email)
end
end
end
-
+
end
@@ -5,36 +5,36 @@
before do
@method = Delayed::PerformableMethod.new("foo", :count, ['o'])
end
-
+
context "with the persisted record cannot be found" do
before do
@method.object = nil
end
-
+
it "should be a no-op if object is nil" do
lambda { @method.perform }.should_not raise_error
end
end
-
+
it "should call the method on the object" do
@method.object.should_receive(:count).with('o')
@method.perform
end
-
+
it "should respond to failure when implemented and target object is called via object.delay.do_something" do
@method = Delayed::PerformableMethod.new(OnPermanentFailureJob.new, :perform, [])
@method.respond_to?(:failure).should be_true
@method.object.should_receive(:failure)
@method.failure
- end
+ end
end
it "should raise a NoMethodError if target method doesn't exist" do
lambda {
Delayed::PerformableMethod.new(Object, :method_that_does_not_exist, [])
}.should raise_error(NoMethodError)
end
-
+
it "should not raise NoMethodError if target method is private" do
clazz = Class.new do
def private_method
@@ -45,4 +45,21 @@ def private_method
Delayed::PerformableMethod.new(clazz.new, :private_method, [])
}.should_not raise_error(NoMethodError)
end
+
+ describe "hooks" do
+ %w(enqueue before after success).each do |hook|
+ it "should delegate #{hook} hook to object" do
+ story = Story.new
+ story.should_receive(hook).with(an_instance_of(Delayed::Job))
+ story.delay.tell.invoke_job
+ end
+ end
+
+ it "should delegate error hook to object" do
+ story = Story.new
+ story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
+ story.should_receive(:tell).and_raise(RuntimeError)
+ lambda { story.delay.tell.invoke_job }.should raise_error
+ end
+ end
end

0 comments on commit e132b5d

Please sign in to comment.