delayed_job_unique_key 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.textile +246 -0
  3. data/contrib/delayed_job.monitrc +14 -0
  4. data/contrib/delayed_job_multiple.monitrc +23 -0
  5. data/lib/delayed/backend/base.rb +152 -0
  6. data/lib/delayed/backend/shared_spec.rb +566 -0
  7. data/lib/delayed/command.rb +101 -0
  8. data/lib/delayed/deserialization_error.rb +4 -0
  9. data/lib/delayed/lifecycle.rb +84 -0
  10. data/lib/delayed/message_sending.rb +54 -0
  11. data/lib/delayed/performable_mailer.rb +21 -0
  12. data/lib/delayed/performable_method.rb +33 -0
  13. data/lib/delayed/plugin.rb +15 -0
  14. data/lib/delayed/plugins/clear_locks.rb +15 -0
  15. data/lib/delayed/psych_ext.rb +75 -0
  16. data/lib/delayed/railtie.rb +16 -0
  17. data/lib/delayed/recipes.rb +50 -0
  18. data/lib/delayed/serialization/active_record.rb +19 -0
  19. data/lib/delayed/syck_ext.rb +34 -0
  20. data/lib/delayed/tasks.rb +11 -0
  21. data/lib/delayed/worker.rb +222 -0
  22. data/lib/delayed/yaml_ext.rb +10 -0
  23. data/lib/delayed_job.rb +22 -0
  24. data/lib/generators/delayed_job/delayed_job_generator.rb +11 -0
  25. data/lib/generators/delayed_job/templates/script +5 -0
  26. data/recipes/delayed_job.rb +1 -0
  27. data/spec/autoloaded/clazz.rb +7 -0
  28. data/spec/autoloaded/instance_clazz.rb +6 -0
  29. data/spec/autoloaded/instance_struct.rb +6 -0
  30. data/spec/autoloaded/struct.rb +7 -0
  31. data/spec/delayed/backend/test.rb +113 -0
  32. data/spec/delayed/serialization/test.rb +0 -0
  33. data/spec/fixtures/bad_alias.yml +1 -0
  34. data/spec/lifecycle_spec.rb +107 -0
  35. data/spec/message_sending_spec.rb +116 -0
  36. data/spec/performable_mailer_spec.rb +46 -0
  37. data/spec/performable_method_spec.rb +89 -0
  38. data/spec/sample_jobs.rb +75 -0
  39. data/spec/spec_helper.rb +45 -0
  40. data/spec/test_backend_spec.rb +13 -0
  41. data/spec/worker_spec.rb +19 -0
  42. data/spec/yaml_ext_spec.rb +41 -0
  43. metadata +197 -0
@@ -0,0 +1,11 @@
1
+ require 'rails/generators'
2
+
3
+ class DelayedJobGenerator < Rails::Generators::Base
4
+
5
+ self.source_paths << File.join(File.dirname(__FILE__), 'templates')
6
+
7
+ def create_script_file
8
+ template 'script', 'script/delayed_job'
9
+ chmod 'script/delayed_job', 0755
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
4
+ require 'delayed/command'
5
+ Delayed::Command.new(ARGV).daemonize
@@ -0,0 +1 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'delayed', 'recipes'))
@@ -0,0 +1,7 @@
1
+ # Make sure this file does not get required manually
2
+ module Autoloaded
3
+ class Clazz
4
+ def perform
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module Autoloaded
2
+ class InstanceClazz
3
+ def perform
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Autoloaded
2
+ class InstanceStruct < ::Struct.new(nil)
3
+ def perform
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ # Make sure this file does not get required manually
2
+ module Autoloaded
3
+ class Struct < ::Struct.new(nil)
4
+ def perform
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,113 @@
1
+ require 'ostruct'
2
+
3
+ # An in-memory backend suitable only for testing. Tries to behave as if it were an ORM.
4
+ module Delayed
5
+ module Backend
6
+ module Test
7
+ class Job
8
+ attr_accessor :id
9
+ attr_accessor :priority
10
+ attr_accessor :attempts
11
+ attr_accessor :handler
12
+ attr_accessor :last_error
13
+ attr_accessor :run_at
14
+ attr_accessor :locked_at
15
+ attr_accessor :locked_by
16
+ attr_accessor :failed_at
17
+ attr_accessor :queue
18
+ attr_accessor :unique_key
19
+
20
+ include Delayed::Backend::Base
21
+
22
+ cattr_accessor :id
23
+ self.id = 0
24
+
25
+ def initialize(hash = {})
26
+ self.attempts = 0
27
+ self.priority = 0
28
+ self.id = (self.class.id += 1)
29
+ hash.each{|k,v| send(:"#{k}=", v)}
30
+ end
31
+
32
+ @jobs = []
33
+ def self.all
34
+ @jobs
35
+ end
36
+
37
+ def self.count
38
+ all.size
39
+ end
40
+
41
+ def self.delete_all
42
+ all.clear
43
+ end
44
+
45
+ def self.create(attrs = {})
46
+ new(attrs).tap do |o|
47
+ o.save
48
+ end
49
+ end
50
+
51
+ def self.create!(*args); create(*args); end
52
+
53
+ def self.clear_locks!(worker_name)
54
+ all.select{|j| j.locked_by == worker_name}.each {|j| j.locked_by = nil; j.locked_at = nil}
55
+ end
56
+
57
+ # Find a few candidate jobs to run (in case some immediately get locked by others).
58
+ def self.find_available(worker_name, limit = 5, max_run_time = Worker.max_run_time)
59
+ jobs = all.select do |j|
60
+ j.run_at <= db_time_now &&
61
+ (j.locked_at.nil? || j.locked_at < db_time_now - max_run_time || j.locked_by == worker_name) &&
62
+ j.failed_at.nil?
63
+ end
64
+
65
+ jobs = jobs.select{|j| Worker.queues.include?(j.queue)} if Worker.queues.any?
66
+ jobs = jobs.select{|j| j.priority >= Worker.min_priority} if Worker.min_priority
67
+ jobs = jobs.select{|j| j.priority <= Worker.max_priority} if Worker.max_priority
68
+ jobs.sort_by{|j| [j.priority, j.run_at]}[0..limit-1]
69
+ end
70
+
71
+ # Lock this job for this worker.
72
+ # Returns true if we have the lock, false otherwise.
73
+ def lock_exclusively!(max_run_time, worker)
74
+ now = self.class.db_time_now
75
+ if locked_by != worker
76
+ # We don't own this job so we will update the locked_by name and the locked_at
77
+ self.locked_at = now
78
+ self.locked_by = worker
79
+ end
80
+
81
+ return true
82
+ end
83
+
84
+ def self.db_time_now
85
+ Time.current
86
+ end
87
+
88
+ def update_attributes(attrs = {})
89
+ attrs.each{|k,v| send(:"#{k}=", v)}
90
+ save
91
+ end
92
+
93
+ def destroy
94
+ self.class.all.delete(self)
95
+ end
96
+
97
+ def save
98
+ self.run_at ||= Time.current
99
+
100
+ self.class.all << self unless self.class.all.include?(self)
101
+ true
102
+ end
103
+
104
+ def save!; save; end
105
+
106
+ def reload
107
+ reset
108
+ self
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
File without changes
@@ -0,0 +1 @@
1
+ foo: *bar
@@ -0,0 +1,107 @@
1
+ require 'spec_helper'
2
+
3
+ describe Delayed::Lifecycle do
4
+ let(:lifecycle) { Delayed::Lifecycle.new }
5
+ let(:callback) { lambda {|*args|} }
6
+ let(:arguments) { [1] }
7
+ let(:behavior) { mock(Object, :before! => nil, :after! => nil, :inside! => nil) }
8
+ let(:wrapped_block) { Proc.new { behavior.inside! } }
9
+
10
+ describe "before callbacks" do
11
+ before(:each) do
12
+ lifecycle.before(:execute, &callback)
13
+ end
14
+
15
+ it 'should execute before wrapped block' do
16
+ callback.should_receive(:call).with(*arguments).ordered
17
+ behavior.should_receive(:inside!).ordered
18
+ lifecycle.run_callbacks :execute, *arguments, &wrapped_block
19
+ end
20
+ end
21
+
22
+ describe "after callbacks" do
23
+ before(:each) do
24
+ lifecycle.after(:execute, &callback)
25
+ end
26
+
27
+ it 'should execute after wrapped block' do
28
+ behavior.should_receive(:inside!).ordered
29
+ callback.should_receive(:call).with(*arguments).ordered
30
+ lifecycle.run_callbacks :execute, *arguments, &wrapped_block
31
+ end
32
+ end
33
+
34
+ describe "around callbacks" do
35
+ before(:each) do
36
+ lifecycle.around(:execute) do |*args, &block|
37
+ behavior.before!
38
+ block.call(*args)
39
+ behavior.after!
40
+ end
41
+ end
42
+
43
+ it 'should before and after wrapped block' do
44
+ behavior.should_receive(:before!).ordered
45
+ behavior.should_receive(:inside!).ordered
46
+ behavior.should_receive(:after!).ordered
47
+ lifecycle.run_callbacks :execute, *arguments, &wrapped_block
48
+ end
49
+
50
+ it "should execute multiple callbacks in order" do
51
+ behavior.should_receive(:one).ordered
52
+ behavior.should_receive(:two).ordered
53
+ behavior.should_receive(:three).ordered
54
+
55
+ lifecycle.around(:execute) { |*args, &block| behavior.one; block.call(*args) }
56
+ lifecycle.around(:execute) { |*args, &block| behavior.two; block.call(*args) }
57
+ lifecycle.around(:execute) { |*args, &block| behavior.three; block.call(*args) }
58
+
59
+ lifecycle.run_callbacks(:execute, *arguments, &wrapped_block)
60
+ end
61
+ end
62
+
63
+ it "should raise if callback is executed with wrong number of parameters" do
64
+ lifecycle.before(:execute, &callback)
65
+ expect { lifecycle.run_callbacks(:execute, 1,2,3) {} }.to raise_error(ArgumentError, /1 parameter/)
66
+ end
67
+
68
+ # # This is a spectacularly crappy way to test callbacks. What's a better way?
69
+ # describe 'arguments callbacks' do
70
+ # subject do
71
+ # class Testarguments < Delayed::arguments
72
+ # def before_execute; end
73
+ # def before_loop; end
74
+ # def before_perform; end
75
+ #
76
+ # set_callback :execute, :before, :before_execute
77
+ # set_callback :loop, :before, :before_loop
78
+ # set_callback :perform, :before, :before_perform
79
+ # end
80
+ #
81
+ # Testarguments.new.tap { |w| w.stop }
82
+ # end
83
+ #
84
+ # it "should trigger for execute event" do
85
+ # subject.should_receive(:before_execute).with()
86
+ # subject.start
87
+ # end
88
+ #
89
+ # it "should trigger for loop event" do
90
+ # subject.should_receive(:before_loop).with()
91
+ # subject.start
92
+ # end
93
+ #
94
+ # it "should trigger for perform event" do
95
+ # "foo".delay.length
96
+ # subject.should_receive(:before_perform).with()
97
+ # subject.start
98
+ # end
99
+ # end
100
+ #
101
+ # describe 'job callbacks' do
102
+ # it "should trigger for enqueue event" do
103
+ # pending 'figure out how to test this'
104
+ # end
105
+ # end
106
+
107
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+ describe Delayed::MessageSending do
4
+ describe "handle_asynchronously" do
5
+ class Story
6
+ def tell!(arg)
7
+ end
8
+ handle_asynchronously :tell!
9
+ end
10
+
11
+ it "should alias original method" do
12
+ Story.new.should respond_to(:tell_without_delay!)
13
+ Story.new.should respond_to(:tell_with_delay!)
14
+ end
15
+
16
+ it "should create a PerformableMethod" do
17
+ story = Story.new
18
+ lambda {
19
+ job = story.tell!(1)
20
+ job.payload_object.class.should == Delayed::PerformableMethod
21
+ job.payload_object.method_name.should == :tell_without_delay!
22
+ job.payload_object.args.should == [1]
23
+ }.should change { Delayed::Job.count }
24
+ end
25
+
26
+ describe 'with options' do
27
+ class Fable
28
+ class << self
29
+ attr_accessor :importance
30
+ end
31
+ def tell
32
+ end
33
+ handle_asynchronously :tell, :priority => Proc.new { self.importance }
34
+ end
35
+
36
+ it 'should set the priority based on the Fable importance' do
37
+ Fable.importance = 10
38
+ job = Fable.new.tell
39
+ job.priority.should == 10
40
+
41
+ Fable.importance = 20
42
+ job = Fable.new.tell
43
+ job.priority.should == 20
44
+ end
45
+
46
+ describe 'using a proc with parament' do
47
+ class Yarn
48
+ attr_accessor :importance
49
+ def spin
50
+ end
51
+ handle_asynchronously :spin, :priority => Proc.new {|y| y.importance }
52
+ end
53
+
54
+ it 'should set the priority based on the Fable importance' do
55
+ job = Yarn.new.tap {|y| y.importance = 10 }.spin
56
+ job.priority.should == 10
57
+
58
+ job = Yarn.new.tap {|y| y.importance = 20 }.spin
59
+ job.priority.should == 20
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ context "delay" do
66
+ it "should create a new PerformableMethod job" do
67
+ lambda {
68
+ job = "hello".delay.count('l')
69
+ job.payload_object.class.should == Delayed::PerformableMethod
70
+ job.payload_object.method_name.should == :count
71
+ job.payload_object.args.should == ['l']
72
+ }.should change { Delayed::Job.count }.by(1)
73
+ end
74
+
75
+ it "should set default priority" do
76
+ Delayed::Worker.default_priority = 99
77
+ job = Object.delay.to_s
78
+ job.priority.should == 99
79
+ Delayed::Worker.default_priority = 0
80
+ end
81
+
82
+ it "should set job options" do
83
+ run_at = Time.parse('2010-05-03 12:55 AM')
84
+ job = Object.delay(:priority => 20, :run_at => run_at).to_s
85
+ job.run_at.should == run_at
86
+ job.priority.should == 20
87
+ end
88
+
89
+ class FairyTail
90
+ attr_accessor :happy_ending
91
+ def tell
92
+ @happy_ending = true
93
+ end
94
+ end
95
+
96
+ it "should not delay the job when delay_jobs is false" do
97
+ Delayed::Worker.delay_jobs = false
98
+ fairy_tail = FairyTail.new
99
+ lambda {
100
+ lambda {
101
+ fairy_tail.delay.tell
102
+ }.should change(fairy_tail, :happy_ending).from(nil).to(true)
103
+ }.should_not change { Delayed::Job.count }
104
+ end
105
+
106
+ it "should delay the job when delay_jobs is true" do
107
+ Delayed::Worker.delay_jobs = true
108
+ fairy_tail = FairyTail.new
109
+ lambda {
110
+ lambda {
111
+ fairy_tail.delay.tell
112
+ }.should_not change(fairy_tail, :happy_ending)
113
+ }.should change { Delayed::Job.count }.by(1)
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ require 'action_mailer'
4
+ class MyMailer < ActionMailer::Base
5
+ def signup(email)
6
+ mail :to => email, :subject => "Delaying Emails"
7
+ end
8
+ end
9
+
10
+ describe ActionMailer::Base do
11
+ describe "delay" do
12
+ it "should enqueue a PerformableEmail job" do
13
+ lambda {
14
+ job = MyMailer.delay.signup('john@example.com')
15
+ job.payload_object.class.should == Delayed::PerformableMailer
16
+ job.payload_object.method_name.should == :signup
17
+ job.payload_object.args.should == ['john@example.com']
18
+ }.should change { Delayed::Job.count }.by(1)
19
+ end
20
+ end
21
+
22
+ describe "delay on a mail object" do
23
+ it "should raise an exception" do
24
+ lambda {
25
+ MyMailer.signup('john@example.com').delay
26
+ }.should raise_error(RuntimeError)
27
+ end
28
+ end
29
+
30
+ describe Delayed::PerformableMailer do
31
+ describe "perform" do
32
+ before do
33
+ @email = mock('email', :deliver => true)
34
+ @mailer_class = mock('MailerClass', :signup => @email)
35
+ @mailer = Delayed::PerformableMailer.new(@mailer_class, :signup, ['john@example.com'])
36
+ end
37
+
38
+ it "should call the method and #deliver on the mailer" do
39
+ @mailer_class.should_receive(:signup).with('john@example.com')
40
+ @email.should_receive(:deliver)
41
+ @mailer.perform
42
+ end
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe Delayed::PerformableMethod do
4
+ describe "perform" do
5
+ before do
6
+ @method = Delayed::PerformableMethod.new("foo", :count, ['o'])
7
+ end
8
+
9
+ context "with the persisted record cannot be found" do
10
+ before do
11
+ @method.object = nil
12
+ end
13
+
14
+ it "should be a no-op if object is nil" do
15
+ lambda { @method.perform }.should_not raise_error
16
+ end
17
+ end
18
+
19
+ it "should call the method on the object" do
20
+ @method.object.should_receive(:count).with('o')
21
+ @method.perform
22
+ end
23
+ end
24
+
25
+ it "should raise a NoMethodError if target method doesn't exist" do
26
+ lambda {
27
+ Delayed::PerformableMethod.new(Object, :method_that_does_not_exist, [])
28
+ }.should raise_error(NoMethodError)
29
+ end
30
+
31
+ it "should not raise NoMethodError if target method is private" do
32
+ clazz = Class.new do
33
+ def private_method
34
+ end
35
+ private :private_method
36
+ end
37
+ lambda {
38
+ Delayed::PerformableMethod.new(clazz.new, :private_method, [])
39
+ }.should_not raise_error(NoMethodError)
40
+ end
41
+
42
+ describe "hooks" do
43
+ %w(enqueue before after success).each do |hook|
44
+ it "should delegate #{hook} hook to object" do
45
+ story = Story.new
46
+ story.should_receive(hook).with(an_instance_of(Delayed::Job))
47
+ story.delay.tell.invoke_job
48
+ end
49
+ end
50
+
51
+ %w(before after success).each do |hook|
52
+ it "should delegate #{hook} hook to object when delay_jobs = false" do
53
+ Delayed::Worker.delay_jobs = false
54
+ story = Story.new
55
+ story.should_receive(hook).with(an_instance_of(Delayed::Job))
56
+ story.delay.tell
57
+ end
58
+ end
59
+
60
+ it "should delegate error hook to object" do
61
+ story = Story.new
62
+ story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
63
+ story.should_receive(:tell).and_raise(RuntimeError)
64
+ lambda { story.delay.tell.invoke_job }.should raise_error
65
+ end
66
+
67
+ it "should delegate error hook to object when delay_jobs = false" do
68
+ Delayed::Worker.delay_jobs = false
69
+ story = Story.new
70
+ story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
71
+ story.should_receive(:tell).and_raise(RuntimeError)
72
+ lambda { story.delay.tell }.should raise_error
73
+ end
74
+
75
+ it "should delegate failure hook to object" do
76
+ method = Delayed::PerformableMethod.new("object", :size, [])
77
+ method.object.should_receive(:failure)
78
+ method.failure
79
+ end
80
+
81
+ it "should delegate failure hook to object when delay_jobs = false" do
82
+ Delayed::Worker.delay_jobs = false
83
+ method = Delayed::PerformableMethod.new("object", :size, [])
84
+ method.object.should_receive(:failure)
85
+ method.failure
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,75 @@
1
+ class NamedJob < Struct.new(:perform)
2
+ def display_name
3
+ 'named_job'
4
+ end
5
+ end
6
+
7
+ class SimpleJob
8
+ cattr_accessor :runs; self.runs = 0
9
+ def perform; @@runs += 1; end
10
+ end
11
+
12
+ class ErrorJob
13
+ cattr_accessor :runs; self.runs = 0
14
+ def perform; raise 'did not work'; end
15
+ end
16
+
17
+ class CustomRescheduleJob < Struct.new(:offset)
18
+ cattr_accessor :runs; self.runs = 0
19
+ def perform; raise 'did not work'; end
20
+ def reschedule_at(time, attempts); time + offset; end
21
+ end
22
+
23
+ class LongRunningJob
24
+ def perform; sleep 250; end
25
+ end
26
+
27
+ class OnPermanentFailureJob < SimpleJob
28
+ def failure; end
29
+ def max_attempts; 1; end
30
+ end
31
+
32
+ module M
33
+ class ModuleJob
34
+ cattr_accessor :runs; self.runs = 0
35
+ def perform; @@runs += 1; end
36
+ end
37
+ end
38
+
39
+ class CallbackJob
40
+ cattr_accessor :messages
41
+
42
+ def enqueue(job)
43
+ self.class.messages << 'enqueue'
44
+ end
45
+
46
+ def before(job)
47
+ self.class.messages << 'before'
48
+ end
49
+
50
+ def perform
51
+ self.class.messages << 'perform'
52
+ end
53
+
54
+ def after(job)
55
+ self.class.messages << 'after'
56
+ end
57
+
58
+ def success(job)
59
+ self.class.messages << 'success'
60
+ end
61
+
62
+ def error(job, error)
63
+ self.class.messages << "error: #{error.class}"
64
+ end
65
+
66
+ def failure(job)
67
+ self.class.messages << 'failure'
68
+ end
69
+ end
70
+
71
+ class EnqueueJobMod < SimpleJob
72
+ def enqueue(job)
73
+ job.run_at = 20.minutes.from_now
74
+ end
75
+ end
@@ -0,0 +1,45 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+
3
+ require 'bundler/setup'
4
+ require 'logger'
5
+
6
+ require 'rails'
7
+ require 'action_mailer'
8
+ require 'active_support/dependencies'
9
+ require 'active_record'
10
+
11
+ require 'delayed_job'
12
+ require 'delayed/backend/shared_spec'
13
+
14
+ Delayed::Worker.logger = Logger.new('/tmp/dj.log')
15
+ ENV['RAILS_ENV'] = 'test'
16
+
17
+ Delayed::Worker.backend = :test
18
+
19
+ # Add this directory so the ActiveSupport autoloading works
20
+ ActiveSupport::Dependencies.autoload_paths << File.dirname(__FILE__)
21
+
22
+ # Add this to simulate Railtie initializer being executed
23
+ ActionMailer::Base.send(:extend, Delayed::DelayMail)
24
+
25
+
26
+ # Used to test interactions between DJ and an ORM
27
+ ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
28
+ ActiveRecord::Base.logger = Delayed::Worker.logger
29
+ ActiveRecord::Migration.verbose = false
30
+
31
+ ActiveRecord::Schema.define do
32
+ create_table :stories, :primary_key => :story_id, :force => true do |table|
33
+ table.string :text
34
+ table.boolean :scoped, :default => true
35
+ end
36
+ end
37
+
38
+ class Story < ActiveRecord::Base
39
+ set_primary_key :story_id
40
+ def tell; text; end
41
+ def whatever(n, _); tell*n; end
42
+ default_scope where(:scoped => true)
43
+
44
+ handle_asynchronously :whatever
45
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Delayed::Backend::Test::Job do
4
+ it_should_behave_like 'a delayed_job backend'
5
+
6
+ describe "#reload" do
7
+ it 'should cause the payload object to be reloaded' do
8
+ job = "foo".delay.length
9
+ o = job.payload_object
10
+ o.object_id.should_not == job.reload.payload_object.object_id
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Delayed::Worker do
4
+ describe "backend=" do
5
+ before do
6
+ @clazz = Class.new
7
+ Delayed::Worker.backend = @clazz
8
+ end
9
+
10
+ it "should set the Delayed::Job constant to the backend" do
11
+ Delayed::Job.should == @clazz
12
+ end
13
+
14
+ it "should set backend with a symbol" do
15
+ Delayed::Worker.backend = :test
16
+ Delayed::Worker.backend.should == Delayed::Backend::Test::Job
17
+ end
18
+ end
19
+ end