carrierwave_backgrounder 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +8 -0
- data/CHANGELOG.md +6 -1
- data/README.md +21 -2
- data/carrierwave_backgrounder.gemspec +3 -4
- data/lib/backgrounder/orm/activemodel.rb +19 -13
- data/lib/backgrounder/orm/base.rb +26 -29
- data/lib/backgrounder/orm/data_mapper.rb +14 -28
- data/lib/backgrounder/support/backends.rb +43 -26
- data/lib/backgrounder/version.rb +1 -1
- data/lib/backgrounder/workers/process_asset.rb +9 -5
- data/lib/backgrounder/workers/store_asset.rb +19 -9
- data/lib/carrierwave_backgrounder.rb +2 -1
- data/spec/backgrounder/orm/activemodel_spec.rb +61 -4
- data/spec/backgrounder/orm/base_spec.rb +15 -44
- data/spec/backgrounder/support/backends_spec.rb +163 -29
- data/spec/backgrounder/workers/fixtures/{test.jpg → images/test.jpg} +0 -0
- data/spec/backgrounder/workers/process_asset_spec.rb +38 -14
- data/spec/backgrounder/workers/store_asset_spec.rb +63 -11
- data/spec/spec_helper.rb +0 -1
- data/spec/support/backend_constants.rb +8 -0
- data/spec/support/mock_worker.rb +17 -0
- metadata +14 -10
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 0.1.3
|
2
|
+
|
3
|
+
### enhancements
|
4
|
+
* CarrierWave::Workers::ProcessAsset now uses #update_attribute when setting [column]_processing.
|
5
|
+
|
1
6
|
## 0.1.2
|
2
7
|
|
3
8
|
### enhancements
|
@@ -7,7 +12,7 @@
|
|
7
12
|
```
|
8
13
|
|
9
14
|
### bug fixes
|
10
|
-
* Check [column]_cache to make sure we are
|
15
|
+
* Check [column]_cache to make sure we are processing when a form fails and [column]_cache is used.
|
11
16
|
|
12
17
|
## 0.1.1
|
13
18
|
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# CarrierWave Backgrounder
|
1
|
+
# CarrierWave Backgrounder
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/lardawge/carrierwave_backgrounder.png)](http://travis-ci.org/lardawge/carrierwave_backgrounder)
|
4
|
+
[![Code Quality](https://codeclimate.com/badge.png)](https://codeclimate.com/github/lardawge/carrierwave_backgrounder)
|
2
5
|
|
3
6
|
I like CarrierWave. That being said, I don't like tying up app instances waiting for images to process.
|
4
7
|
|
@@ -35,6 +38,8 @@ These instructions assume you have previously set up [CarrierWave](https://githu
|
|
35
38
|
In Rails, add the following your Gemfile:
|
36
39
|
|
37
40
|
```ruby
|
41
|
+
# IMPORTANT: Be sure to list the backend job processor you intend to use, before carrierwave_backgrounder
|
42
|
+
gem 'sidekiq' # or delayed_job, resque, ect...
|
38
43
|
gem 'carrierwave_backgrounder'
|
39
44
|
```
|
40
45
|
|
@@ -105,7 +110,21 @@ To overide the worker in cases where additional methods need to be called or you
|
|
105
110
|
second argument:
|
106
111
|
|
107
112
|
```ruby
|
108
|
-
process_in_background :avatar,
|
113
|
+
process_in_background :avatar, MyParanoidWorker
|
114
|
+
```
|
115
|
+
|
116
|
+
Then create a worker that subclasses carrierwave_backgrounder's worker:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
class MyParanoidWorker < ::CarrierWave::Workers::ProcessAsset
|
120
|
+
# ...or subclass CarrierWave::Workers::StoreAsset if you're using store_in_background
|
121
|
+
|
122
|
+
def error(job, exception)
|
123
|
+
report_job_failure # or whatever
|
124
|
+
end
|
125
|
+
|
126
|
+
# other hooks you might care about
|
127
|
+
end
|
109
128
|
```
|
110
129
|
### Testing with Rspec
|
111
130
|
We use the after_commit hook when using active_record. This creates a problem when testing with Rspec because after_commit never gets fired
|
@@ -8,10 +8,9 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Larry Sprock"]
|
10
10
|
s.email = ["larry@lucidbleu.com"]
|
11
|
-
s.homepage = ""
|
12
|
-
s.
|
13
|
-
|
14
|
-
s.rubyforge_project = "carrierwave_backgrounder"
|
11
|
+
s.homepage = "https://github.com/lardawge/carrierwave_backgrounder"
|
12
|
+
s.licenses = ["MIT"]
|
13
|
+
s.summary = %q{Offload CarrierWave's image processing and storage to a background process using Delayed Job, Resque, Sidekiq, Qu, Queue Classic or Girl Friday}
|
15
14
|
|
16
15
|
s.files = `git ls-files`.split("\n")
|
17
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -8,25 +8,31 @@ module CarrierWave
|
|
8
8
|
include CarrierWave::Backgrounder::ORM::Base
|
9
9
|
|
10
10
|
def process_in_background(column, worker=::CarrierWave::Workers::ProcessAsset)
|
11
|
+
before_save :"set_#{column}_processing", :if => :"enqueue_#{column}_background_job?"
|
12
|
+
send _supported_am_after_callback, :"enqueue_#{column}_background_job", :if => :"enqueue_#{column}_background_job?"
|
11
13
|
super
|
12
|
-
|
13
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
14
|
-
def trigger_#{column}_background_processing?
|
15
|
-
process_#{column}_upload != true &&
|
16
|
-
(#{column}_changed? || previous_changes.has_key?(:#{column}) || remote_#{column}_url.present? || #{column}_cache.present?)
|
17
|
-
end
|
18
|
-
RUBY
|
19
14
|
end
|
20
15
|
|
21
16
|
def store_in_background(column, worker=::CarrierWave::Workers::StoreAsset)
|
17
|
+
send _supported_am_after_callback, :"enqueue_#{column}_background_job", :if => :"enqueue_#{column}_background_job?"
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def _supported_am_after_callback
|
24
|
+
respond_to?(:after_commit) ? :after_commit : :after_save
|
25
|
+
end
|
26
|
+
|
27
|
+
def _define_shared_backgrounder_methods(mod, column, worker)
|
22
28
|
super
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
define_method :"#{column}_updated?" do
|
31
|
+
send(:"#{column}_changed?") || # after_save support
|
32
|
+
previous_changes.has_key?(:"#{column}") || # after_commit support
|
33
|
+
send(:"remote_#{column}_url").present? || # Remote upload support
|
34
|
+
send(:"#{column}_cache").present? # Form failure support
|
35
|
+
end
|
30
36
|
end
|
31
37
|
end # ActiveModel
|
32
38
|
|
@@ -39,27 +39,17 @@ module CarrierWave
|
|
39
39
|
# end
|
40
40
|
#
|
41
41
|
def process_in_background(column, worker=::CarrierWave::Workers::ProcessAsset)
|
42
|
-
|
43
|
-
|
44
|
-
send :before_save, :"set_#{column}_processing", :if => :"trigger_#{column}_background_processing?"
|
45
|
-
callback = self.respond_to?(:after_commit) ? :after_commit : :after_save
|
46
|
-
send callback, :"enqueue_#{column}_background_job", :if => :"trigger_#{column}_background_processing?"
|
47
|
-
|
48
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
42
|
+
attr_accessor :"process_#{column}_upload"
|
49
43
|
|
44
|
+
mod = Module.new
|
45
|
+
include mod
|
46
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
50
47
|
def set_#{column}_processing
|
51
48
|
self.#{column}_processing = true if respond_to?(:#{column}_processing)
|
52
49
|
end
|
53
|
-
|
54
|
-
def enqueue_#{column}_background_job
|
55
|
-
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id.to_s, #{column}.mounted_as)
|
56
|
-
end
|
57
|
-
|
58
|
-
def trigger_#{column}_background_processing?
|
59
|
-
process_#{column}_upload != true
|
60
|
-
end
|
61
|
-
|
62
50
|
RUBY
|
51
|
+
|
52
|
+
_define_shared_backgrounder_methods(mod, column, worker)
|
63
53
|
end
|
64
54
|
|
65
55
|
##
|
@@ -85,30 +75,37 @@ module CarrierWave
|
|
85
75
|
# end
|
86
76
|
#
|
87
77
|
def store_in_background(column, worker=::CarrierWave::Workers::StoreAsset)
|
88
|
-
|
89
|
-
|
90
|
-
callback = self.respond_to?(:after_commit) ? :after_commit : :after_save
|
91
|
-
send callback, :"enqueue_#{column}_background_job", :if => :"trigger_#{column}_background_storage?"
|
92
|
-
|
93
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
78
|
+
attr_accessor :"process_#{column}_upload"
|
94
79
|
|
80
|
+
mod = Module.new
|
81
|
+
include mod
|
82
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
95
83
|
def write_#{column}_identifier
|
96
|
-
super
|
84
|
+
super and return if process_#{column}_upload
|
97
85
|
self.#{column}_tmp = _mounter(:#{column}).cache_name if _mounter(:#{column}).cache_name
|
98
86
|
end
|
99
87
|
|
100
88
|
def store_#{column}!
|
101
|
-
super
|
89
|
+
super if process_#{column}_upload
|
102
90
|
end
|
91
|
+
RUBY
|
103
92
|
|
104
|
-
|
105
|
-
|
106
|
-
end
|
93
|
+
_define_shared_backgrounder_methods(mod, column, worker)
|
94
|
+
end
|
107
95
|
|
108
|
-
|
109
|
-
|
96
|
+
private
|
97
|
+
|
98
|
+
def _define_shared_backgrounder_methods(mod, column, worker)
|
99
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
100
|
+
def #{column}_updated?; true; end
|
101
|
+
|
102
|
+
def enqueue_#{column}_background_job?
|
103
|
+
!process_#{column}_upload && #{column}_updated?
|
110
104
|
end
|
111
105
|
|
106
|
+
def enqueue_#{column}_background_job
|
107
|
+
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id.to_s, #{column}.mounted_as)
|
108
|
+
end
|
112
109
|
RUBY
|
113
110
|
end
|
114
111
|
|
@@ -10,60 +10,46 @@ module CarrierWave
|
|
10
10
|
after :save, :"enqueue_#{column}_background_job"
|
11
11
|
|
12
12
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
13
|
-
attr_accessor :process_#{column}_upload
|
14
|
-
attr_reader :#{column}_changed
|
15
|
-
|
16
13
|
def set_#{column}_processing
|
17
14
|
@#{column}_changed = attribute_dirty?(:#{column})
|
18
|
-
self.#{column}_processing = true if respond_to?(:#{column}_processing)
|
15
|
+
self.#{column}_processing = true if respond_to?(:#{column}_processing)
|
19
16
|
end
|
20
|
-
|
21
|
-
def enqueue_#{column}_background_job
|
22
|
-
if trigger_#{column}_background_processing?
|
23
|
-
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id, #{column}.mounted_as)
|
24
|
-
@#{column}_changed = false
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def trigger_#{column}_background_processing?
|
29
|
-
process_#{column}_upload != true && #{column}_changed
|
30
|
-
end
|
31
|
-
|
32
17
|
RUBY
|
33
18
|
end
|
34
19
|
|
35
20
|
def store_in_background(column, worker=::CarrierWave::Workers::StoreAsset)
|
36
21
|
before :save, :"set_#{column}_changed"
|
37
|
-
after
|
22
|
+
after :save, :"enqueue_#{column}_background_job"
|
38
23
|
|
39
24
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
40
|
-
attr_accessor :process_#{column}_upload
|
41
|
-
attr_reader :#{column}_changed
|
42
|
-
|
43
25
|
def set_#{column}_changed
|
44
26
|
@#{column}_changed = attribute_dirty?(:#{column})
|
45
27
|
end
|
46
28
|
|
47
29
|
def write_#{column}_identifier
|
48
|
-
super
|
30
|
+
super and return if process_#{column}_upload
|
49
31
|
self.#{column}_tmp = _mounter(:#{column}).cache_name
|
50
32
|
end
|
33
|
+
RUBY
|
34
|
+
end
|
51
35
|
|
52
|
-
|
53
|
-
|
54
|
-
|
36
|
+
private
|
37
|
+
|
38
|
+
def _define_shared_backgrounder_methods(mod, column, worker)
|
39
|
+
super
|
40
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
41
|
+
attr_reader :#{column}_changed
|
55
42
|
|
56
43
|
def enqueue_#{column}_background_job
|
57
|
-
if
|
44
|
+
if enqueue_#{column}_background_job?
|
58
45
|
CarrierWave::Backgrounder.enqueue_for_backend(#{worker}, self.class.name, id, #{column}.mounted_as)
|
59
46
|
@#{column}_changed = false
|
60
47
|
end
|
61
48
|
end
|
62
49
|
|
63
|
-
def
|
64
|
-
|
50
|
+
def #{column}_updated?
|
51
|
+
#{column}_changed
|
65
52
|
end
|
66
|
-
|
67
53
|
RUBY
|
68
54
|
end
|
69
55
|
end # DataMapper
|
@@ -25,34 +25,12 @@ module Support
|
|
25
25
|
backends << :qu if defined? ::Qu
|
26
26
|
backends << :sidekiq if defined? ::Sidekiq
|
27
27
|
backends << :qc if defined? ::QC
|
28
|
-
backends
|
28
|
+
backends
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def enqueue_for_backend(worker, class_name, subject_id, mounted_as)
|
33
|
-
|
34
|
-
when :girl_friday
|
35
|
-
@girl_friday_queue ||= GirlFriday::WorkQueue.new(queue_options.delete(:queue) || :carrierwave, queue_options) do |msg|
|
36
|
-
worker = msg[:worker]
|
37
|
-
worker.perform
|
38
|
-
end
|
39
|
-
@girl_friday_queue << { :worker => worker.new(class_name, subject_id, mounted_as) }
|
40
|
-
when :delayed_job
|
41
|
-
::Delayed::Job.enqueue worker.new(class_name, subject_id, mounted_as), :queue => queue_options[:queue]
|
42
|
-
when :resque
|
43
|
-
worker.instance_variable_set('@queue', queue_options[:queue] || :carrierwave)
|
44
|
-
::Resque.enqueue worker, class_name, subject_id, mounted_as
|
45
|
-
when :qu
|
46
|
-
worker.instance_variable_set('@queue', queue_options[:queue] || :carrierwave)
|
47
|
-
::Qu.enqueue worker, class_name, subject_id, mounted_as
|
48
|
-
when :sidekiq
|
49
|
-
worker.sidekiq_options queue_options
|
50
|
-
::Sidekiq::Client.enqueue worker, class_name, subject_id, mounted_as
|
51
|
-
when :qc
|
52
|
-
::QC.enqueue "#{worker.name}.perform", class_name, subject_id, mounted_as.to_s
|
53
|
-
when :immediate
|
54
|
-
worker.new(class_name, subject_id, mounted_as).perform
|
55
|
-
end
|
33
|
+
self.send :"enqueue_#{backend}", worker, class_name, subject_id, mounted_as
|
56
34
|
end
|
57
35
|
|
58
36
|
private
|
@@ -62,13 +40,52 @@ module Support
|
|
62
40
|
warn 'WARNING: No available queue backends found for CarrierWave::Backgrounder. Using the :immediate.'
|
63
41
|
:immediate
|
64
42
|
elsif available_backends.size > 1
|
65
|
-
raise ::CarrierWave::Backgrounder::
|
66
|
-
"You have
|
43
|
+
raise ::CarrierWave::Backgrounder::TooManyBackendsAvailableError,
|
44
|
+
"You have too many backends available: #{available_backends.inspect}. Please specify which one to use in configuration block"
|
67
45
|
else
|
68
46
|
available_backends.first
|
69
47
|
end
|
70
48
|
end
|
71
49
|
|
50
|
+
def enqueue_delayed_job(worker, *args)
|
51
|
+
::Delayed::Job.enqueue worker.new(*args), :queue => queue_options[:queue]
|
52
|
+
end
|
53
|
+
|
54
|
+
def enqueue_resque(worker, *args)
|
55
|
+
worker.instance_variable_set('@queue', queue_options[:queue] || :carrierwave)
|
56
|
+
::Resque.enqueue worker, *args
|
57
|
+
end
|
58
|
+
|
59
|
+
def enqueue_sidekiq(worker, *args)
|
60
|
+
sidekiq_client_args = { 'class' => worker, 'args' => args }
|
61
|
+
sidekiq_client_args['queue'] = queue_options[:queue] unless queue_options[:queue].nil?
|
62
|
+
sidekiq_client_args['retry'] = queue_options[:retry] unless queue_options[:retry].nil?
|
63
|
+
sidekiq_client_args['timeout'] = queue_options[:timeout] unless queue_options[:timeout].nil?
|
64
|
+
sidekiq_client_args['backtrace'] = queue_options[:backtrace] unless queue_options[:backtrace].nil?
|
65
|
+
worker.client_push(sidekiq_client_args)
|
66
|
+
end
|
67
|
+
|
68
|
+
def enqueue_girl_friday(worker, *args)
|
69
|
+
@girl_friday_queue ||= GirlFriday::WorkQueue.new(queue_options.delete(:queue) || :carrierwave, queue_options) do |msg|
|
70
|
+
worker = msg[:worker]
|
71
|
+
worker.perform
|
72
|
+
end
|
73
|
+
@girl_friday_queue << { :worker => worker.new(*args) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def enqueue_qu(worker, *args)
|
77
|
+
worker.instance_variable_set('@queue', queue_options[:queue] || :carrierwave)
|
78
|
+
::Qu.enqueue worker, *args
|
79
|
+
end
|
80
|
+
|
81
|
+
def enqueue_qc(worker, *args)
|
82
|
+
class_name, subject_id, mounted_as = args
|
83
|
+
::QC.enqueue "#{worker.name}.perform", class_name, subject_id, mounted_as.to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
def enqueue_immediate(worker, *args)
|
87
|
+
worker.new(*args).perform
|
88
|
+
end
|
72
89
|
end
|
73
90
|
end
|
74
91
|
end
|
data/lib/backgrounder/version.rb
CHANGED
@@ -10,23 +10,27 @@ module CarrierWave
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def perform(*args)
|
13
|
-
set_args(*args)
|
14
|
-
|
15
|
-
record = resource.find id
|
13
|
+
set_args(*args) if args.present?
|
14
|
+
record = constantized_resource.find id
|
16
15
|
|
17
16
|
if record
|
18
17
|
record.send(:"process_#{column}_upload=", true)
|
19
18
|
if record.send(:"#{column}").recreate_versions! && record.respond_to?(:"#{column}_processing")
|
20
|
-
record.
|
21
|
-
record.save!
|
19
|
+
record.update_attribute :"#{column}_processing", nil
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
25
23
|
|
24
|
+
private
|
25
|
+
|
26
26
|
def set_args(klass, id, column)
|
27
27
|
self.klass, self.id, self.column = klass, id, column
|
28
28
|
end
|
29
29
|
|
30
|
+
def constantized_resource
|
31
|
+
klass.is_a?(String) ? klass.constantize : klass
|
32
|
+
end
|
33
|
+
|
30
34
|
end # ProcessAsset
|
31
35
|
|
32
36
|
end # Workers
|
@@ -4,33 +4,43 @@ module CarrierWave
|
|
4
4
|
|
5
5
|
class StoreAsset < Struct.new(:klass, :id, :column)
|
6
6
|
include ::Sidekiq::Worker if defined?(::Sidekiq)
|
7
|
+
attr_reader :cache_path, :tmp_directory
|
7
8
|
|
8
9
|
def self.perform(*args)
|
9
10
|
new(*args).perform
|
10
11
|
end
|
11
12
|
|
12
13
|
def perform(*args)
|
13
|
-
set_args(*args)
|
14
|
-
|
15
|
-
|
16
|
-
if
|
17
|
-
|
18
|
-
cache_dir = [asset.root, asset.cache_dir].join("/")
|
19
|
-
cache_path = [cache_dir, tmp].join("/")
|
20
|
-
tmp_dir = [cache_dir, tmp.split("/")[0]].join("/")
|
14
|
+
set_args(*args) if args.present?
|
15
|
+
record = constantized_resource.find id
|
16
|
+
|
17
|
+
if record.send(:"#{column}_tmp")
|
18
|
+
store_directories(record)
|
21
19
|
record.send :"process_#{column}_upload=", true
|
22
20
|
record.send :"#{column}_tmp=", nil
|
23
21
|
File.open(cache_path) { |f| record.send :"#{column}=", f }
|
24
22
|
if record.save!
|
25
|
-
FileUtils.rm_r(
|
23
|
+
FileUtils.rm_r(tmp_directory, :force => true)
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
28
|
+
private
|
29
|
+
|
30
30
|
def set_args(klass, id, column)
|
31
31
|
self.klass, self.id, self.column = klass, id, column
|
32
32
|
end
|
33
33
|
|
34
|
+
def constantized_resource
|
35
|
+
klass.is_a?(String) ? klass.constantize : klass
|
36
|
+
end
|
37
|
+
|
38
|
+
def store_directories(record)
|
39
|
+
asset, asset_tmp = record.send(:"#{column}"), record.send(:"#{column}_tmp")
|
40
|
+
cache_directory = File.join(asset.root, asset.cache_dir)
|
41
|
+
@cache_path = File.join(cache_directory, asset_tmp)
|
42
|
+
@tmp_directory = File.join(cache_directory, asset_tmp.split("/").first)
|
43
|
+
end
|
34
44
|
end # StoreAsset
|
35
45
|
|
36
46
|
end # Workers
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/object'
|
1
2
|
require 'backgrounder/support/backends'
|
2
3
|
require 'backgrounder/orm/base'
|
3
4
|
require 'backgrounder/delay'
|
@@ -7,7 +8,7 @@ module CarrierWave
|
|
7
8
|
include Support::Backends
|
8
9
|
|
9
10
|
class UnsupportedBackendError < StandardError ; end
|
10
|
-
class
|
11
|
+
class TooManyBackendsAvailableError < StandardError ; end
|
11
12
|
|
12
13
|
def self.configure
|
13
14
|
yield self
|
@@ -13,14 +13,71 @@ describe CarrierWave::Backgrounder::ORM::ActiveModel do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
@mock_class.extend CarrierWave::Backgrounder::ORM::ActiveModel
|
16
|
-
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.store_in_background' do
|
19
|
+
context 'setting up callbacks' do
|
20
|
+
it 'creates an after_commit hook' do
|
21
|
+
@mock_class.expects(:after_commit).with(:enqueue_avatar_background_job, :if => :enqueue_avatar_background_job?)
|
22
|
+
@mock_class.store_in_background :avatar
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '.process_in_background' do
|
28
|
+
context 'setting up callbacks' do
|
29
|
+
it 'creates a before_save hook' do
|
30
|
+
@mock_class.expects(:before_save).with(:set_avatar_processing, :if => :enqueue_avatar_background_job?)
|
31
|
+
@mock_class.process_in_background :avatar
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'creates an after_save hook' do
|
35
|
+
@mock_class.expects(:after_commit).with(:enqueue_avatar_background_job, :if => :enqueue_avatar_background_job?)
|
36
|
+
@mock_class.process_in_background :avatar
|
37
|
+
end
|
38
|
+
end
|
17
39
|
end
|
18
40
|
|
19
41
|
describe '#trigger_column_background_processing?' do
|
20
|
-
|
21
|
-
|
42
|
+
let(:instance) { @mock_class.new }
|
43
|
+
|
44
|
+
before do
|
45
|
+
@mock_class.process_in_background :avatar
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns true if process_avatar_upload is false" do
|
22
49
|
instance.expects(:process_avatar_upload)
|
23
|
-
instance.
|
50
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "calls column_changed?" do
|
54
|
+
instance.expects(:process_avatar_upload).returns(false)
|
55
|
+
instance.expects(:avatar_changed?)
|
56
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
57
|
+
end
|
58
|
+
|
59
|
+
it "calls previous_changes" do
|
60
|
+
instance.expects(:process_avatar_upload).returns(false)
|
61
|
+
instance.expects(:avatar_changed?).returns(false)
|
62
|
+
instance.expects(:previous_changes).returns({:avatar => true})
|
63
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it "calls avatar_remote_url" do
|
67
|
+
instance.expects(:process_avatar_upload).returns(false)
|
68
|
+
instance.expects(:avatar_changed?).returns(false)
|
69
|
+
instance.expects(:previous_changes).returns({})
|
70
|
+
instance.expects(:remote_avatar_url).returns('yup')
|
71
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "calls avatar_cache" do
|
75
|
+
instance.expects(:process_avatar_upload).returns(false)
|
76
|
+
instance.expects(:avatar_changed?).returns(false)
|
77
|
+
instance.expects(:previous_changes).returns({})
|
78
|
+
instance.expects(:remote_avatar_url).returns(nil)
|
79
|
+
instance.expects(:avatar_cache).returns('yup')
|
80
|
+
expect(instance.enqueue_avatar_background_job?).to be_true
|
24
81
|
end
|
25
82
|
end
|
26
83
|
end
|
@@ -12,64 +12,37 @@ describe CarrierWave::Backgrounder::ORM::Base do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'mixes in the two DSL methods' do
|
15
|
-
@mock_class.
|
16
|
-
@mock_class.
|
15
|
+
expect(@mock_class).to respond_to(:process_in_background)
|
16
|
+
expect(@mock_class).to respond_to(:store_in_background)
|
17
17
|
end
|
18
18
|
|
19
|
-
describe '
|
20
|
-
|
21
|
-
describe 'setting up callbacks' do
|
22
|
-
|
23
|
-
it 'creates a before_save hook' do
|
24
|
-
@mock_class.expects(:before_save).with(:set_avatar_processing, :if => :trigger_avatar_background_processing?)
|
25
|
-
@mock_class.process_in_background :avatar
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'creates an after_save hook' do
|
29
|
-
@mock_class.expects(:after_commit).with(:enqueue_avatar_background_job, :if => :trigger_avatar_background_processing?)
|
30
|
-
@mock_class.process_in_background :avatar
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
describe 'including new methods' do
|
19
|
+
describe '.process_in_background' do
|
20
|
+
context 'including new methods' do
|
36
21
|
before do
|
37
22
|
@mock_class.process_in_background :avatar
|
38
23
|
@instance = @mock_class.new
|
39
24
|
end
|
40
25
|
|
41
26
|
it 'creates a processing enabled accessor' do
|
42
|
-
@instance.
|
43
|
-
@instance.
|
27
|
+
expect(@instance).to respond_to(:process_avatar_upload)
|
28
|
+
expect(@instance).to respond_to(:process_avatar_upload=)
|
44
29
|
end
|
45
30
|
|
46
31
|
it 'create a setter for the processing attribute' do
|
47
|
-
@instance.
|
32
|
+
expect(@instance).to respond_to(:set_avatar_processing)
|
48
33
|
end
|
49
34
|
|
50
35
|
it 'create a background job queuer' do
|
51
|
-
@instance.
|
36
|
+
expect(@instance).to respond_to(:enqueue_avatar_background_job)
|
52
37
|
end
|
53
38
|
|
54
39
|
it 'create a trigger interrogator' do
|
55
|
-
@instance.
|
40
|
+
expect(@instance).to respond_to(:enqueue_avatar_background_job?)
|
56
41
|
end
|
57
|
-
|
58
42
|
end
|
59
|
-
|
60
43
|
end
|
61
44
|
|
62
45
|
describe 'store in background' do
|
63
|
-
|
64
|
-
describe 'setting up callbacks' do
|
65
|
-
|
66
|
-
it 'creates an after_save hook' do
|
67
|
-
@mock_class.expects(:after_commit).with(:enqueue_avatar_background_job, :if => :trigger_avatar_background_storage?)
|
68
|
-
@mock_class.store_in_background :avatar
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
46
|
describe 'including new methods' do
|
74
47
|
before do
|
75
48
|
@mock_class.store_in_background :avatar
|
@@ -77,27 +50,25 @@ describe CarrierWave::Backgrounder::ORM::Base do
|
|
77
50
|
end
|
78
51
|
|
79
52
|
it 'creates a processing enabled accessor' do
|
80
|
-
@instance.
|
81
|
-
@instance.
|
53
|
+
expect(@instance).to respond_to(:process_avatar_upload)
|
54
|
+
expect(@instance).to respond_to(:process_avatar_upload=)
|
82
55
|
end
|
83
56
|
|
84
57
|
it 'overrides the write column identifier method from carrierwave' do
|
85
|
-
@instance.
|
58
|
+
expect(@instance).to respond_to(:write_avatar_identifier)
|
86
59
|
end
|
87
60
|
|
88
61
|
it 'overrides the store column method from carrierwave' do
|
89
|
-
@instance.
|
62
|
+
expect(@instance).to respond_to(:store_avatar!)
|
90
63
|
end
|
91
64
|
|
92
65
|
it 'create a background job queuer' do
|
93
|
-
@instance.
|
66
|
+
expect(@instance).to respond_to(:enqueue_avatar_background_job)
|
94
67
|
end
|
95
68
|
|
96
69
|
it 'create a trigger interrogator' do
|
97
|
-
@instance.
|
70
|
+
expect(@instance).to respond_to(:enqueue_avatar_background_job?)
|
98
71
|
end
|
99
|
-
|
100
72
|
end
|
101
73
|
end
|
102
|
-
|
103
74
|
end
|
@@ -1,87 +1,221 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'support/backend_constants'
|
3
|
+
require 'support/mock_worker'
|
2
4
|
|
3
5
|
describe Support::Backends do
|
4
|
-
let(:
|
6
|
+
let(:mock_module) { Module.new }
|
5
7
|
|
6
8
|
before do
|
7
|
-
|
9
|
+
mock_module.send :include, Support::Backends
|
8
10
|
end
|
9
11
|
|
10
12
|
describe 'enumerating available backends' do
|
11
13
|
it 'detects GirlFriday' do
|
12
|
-
|
14
|
+
expect(mock_module.available_backends).to include(:girl_friday)
|
13
15
|
end
|
14
16
|
|
15
17
|
it 'detects Delayed::Job' do
|
16
|
-
|
18
|
+
expect(mock_module.available_backends).to include(:delayed_job)
|
17
19
|
end
|
18
20
|
|
19
21
|
it 'detects Resque' do
|
20
|
-
|
22
|
+
expect(mock_module.available_backends).to include(:resque)
|
21
23
|
end
|
22
24
|
|
23
25
|
it 'detects Qu' do
|
24
|
-
|
26
|
+
expect(mock_module.available_backends).to include(:qu)
|
25
27
|
end
|
26
28
|
|
27
29
|
it 'detects Sidekiq' do
|
28
|
-
|
30
|
+
expect(mock_module.available_backends).to include(:sidekiq)
|
29
31
|
end
|
30
32
|
|
31
33
|
it 'detects QC' do
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'detects Immediate' do
|
36
|
-
test_module.available_backends.should include(:immediate)
|
34
|
+
expect(mock_module.available_backends).to include(:qc)
|
37
35
|
end
|
38
36
|
end
|
39
37
|
|
40
38
|
describe 'setting backend' do
|
41
39
|
it 'using #backend=' do
|
42
|
-
|
43
|
-
expect(
|
40
|
+
mock_module.backend = :delayed_job
|
41
|
+
expect(mock_module.backend).to eql(:delayed_job)
|
44
42
|
end
|
45
43
|
|
46
44
|
it 'using #backend' do
|
47
|
-
|
48
|
-
expect(
|
45
|
+
mock_module.backend(:delayed_job)
|
46
|
+
expect(mock_module.backend).to eql(:delayed_job)
|
49
47
|
end
|
50
48
|
|
51
49
|
it 'allows passing of queue_options' do
|
52
|
-
|
53
|
-
expect(
|
50
|
+
mock_module.backend(:delayed_job, :queue => :awesome_queue)
|
51
|
+
expect(mock_module.queue_options).to eql({:queue => :awesome_queue})
|
54
52
|
end
|
55
53
|
end
|
56
54
|
|
57
|
-
describe '
|
55
|
+
describe 'auto detect backends' do
|
58
56
|
before do
|
59
|
-
|
57
|
+
mock_module.instance_variable_set('@backend', nil)
|
60
58
|
end
|
61
59
|
|
62
60
|
it 'sets the backend to immediate if none available' do
|
63
61
|
suppress_warnings do
|
64
|
-
|
65
|
-
expect(
|
62
|
+
mock_module.stubs(:available_backends).returns([])
|
63
|
+
expect(mock_module.backend).to eql(:immediate)
|
66
64
|
end
|
67
65
|
end
|
68
66
|
|
69
67
|
it 'sets a backend automatically if only one is available' do
|
70
|
-
|
71
|
-
|
68
|
+
mock_module.stubs(:available_backends).returns([ :qu ])
|
69
|
+
expect(mock_module.backend).to eql(:qu)
|
72
70
|
end
|
73
71
|
|
74
72
|
it 'raises an error if more than one backend is available' do
|
75
|
-
|
73
|
+
mock_module.stubs(:available_backends).returns([:qu, :resque])
|
76
74
|
expect {
|
77
|
-
|
78
|
-
}.to raise_error(CarrierWave::Backgrounder::
|
75
|
+
mock_module.backend
|
76
|
+
}.to raise_error(CarrierWave::Backgrounder::TooManyBackendsAvailableError)
|
79
77
|
end
|
80
78
|
|
81
79
|
it 'does not clobber a manually set backend' do
|
82
|
-
|
83
|
-
|
80
|
+
mock_module.backend = :not_a_backend
|
81
|
+
expect(mock_module.backend).to eql(:not_a_backend)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#enqueue_for_backend' do
|
86
|
+
let!(:worker) { MockWorker.new('FakeClass', 1, :image) }
|
87
|
+
|
88
|
+
context 'delayed_job' do
|
89
|
+
before do
|
90
|
+
@mock_worker = Class.new do
|
91
|
+
def self.perform(*args); new(*args).perform; end
|
92
|
+
end
|
93
|
+
|
94
|
+
MockWorker.expects(:new).returns(worker)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'defaults the queue name to nil if none passed to #backend' do
|
98
|
+
mock_module.backend :delayed_job
|
99
|
+
Delayed::Job.expects(:enqueue).with(worker, :queue => nil)
|
100
|
+
mock_module.enqueue_for_backend MockWorker, 'FakeClass', 1, :image
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'sets the queue name to the queue name passed to #backend' do
|
104
|
+
mock_module.backend :delayed_job, :queue => :awesome_queue
|
105
|
+
Delayed::Job.expects(:enqueue).with(worker, :queue => :awesome_queue)
|
106
|
+
mock_module.enqueue_for_backend MockWorker, 'FakeClass', 1, :image
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'resque' do
|
111
|
+
let(:args) { [MockWorker, 'FakeClass', 1, :image] }
|
112
|
+
|
113
|
+
before do
|
114
|
+
Resque.expects(:enqueue).with(*args)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'sets a variable with the queue name, defaults to :carrierwave' do
|
118
|
+
mock_module.backend :resque
|
119
|
+
mock_module.enqueue_for_backend(*args)
|
120
|
+
expect(MockWorker.instance_variable_get '@queue').to eql(:carrierwave)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'sets a variable to the queue name passed to #backend' do
|
124
|
+
mock_module.backend :resque, :queue => :awesome_queue
|
125
|
+
mock_module.enqueue_for_backend(*args)
|
126
|
+
expect(MockWorker.instance_variable_get '@queue').to eql(:awesome_queue)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'sidekiq' do
|
131
|
+
let(:args) { ['FakeClass', 1, :image] }
|
132
|
+
|
133
|
+
it 'invokes client_push on the class with passed args' do
|
134
|
+
MockSidekiqWorker.expects(:client_push).with({ 'class' => MockSidekiqWorker, 'args' => args })
|
135
|
+
mock_module.backend :sidekiq
|
136
|
+
mock_module.enqueue_for_backend(MockSidekiqWorker, *args)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'invokes client_push and includes the options passed to backend' do
|
140
|
+
MockSidekiqWorker.expects(:client_push).with({ 'class' => MockSidekiqWorker,
|
141
|
+
'retry' => false,
|
142
|
+
'timeout' => 60,
|
143
|
+
'queue' => :awesome_queue,
|
144
|
+
'args' => args })
|
145
|
+
options = {:retry => false, :timeout => 60, :queue => :awesome_queue}
|
146
|
+
mock_module.backend :sidekiq, options
|
147
|
+
mock_module.enqueue_for_backend(MockSidekiqWorker, *args)
|
148
|
+
end
|
84
149
|
end
|
150
|
+
|
151
|
+
context 'girl_friday' do
|
152
|
+
let(:args) { [MockWorker, 'FakeClass', 1, :image] }
|
153
|
+
|
154
|
+
it 'instantiates a GirlFriday work queue if one does not exist' do
|
155
|
+
mock_module.backend :girl_friday
|
156
|
+
GirlFriday::WorkQueue.expects(:new).with(:carrierwave, {}).returns([])
|
157
|
+
mock_module.enqueue_for_backend(*args)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'instantiates a GirlFriday work queue passing the args to the queue' do
|
161
|
+
mock_module.backend :girl_friday, :queue => :awesome_queue, :size => 3
|
162
|
+
GirlFriday::WorkQueue.expects(:new).with(:awesome_queue, {:size => 3}).returns([])
|
163
|
+
mock_module.enqueue_for_backend(*args)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'does not instantiate a GirlFriday work queue if one exists' do
|
167
|
+
mock_module.backend :girl_friday
|
168
|
+
mock_module.instance_variable_set('@girl_friday_queue', [])
|
169
|
+
GirlFriday::WorkQueue.expects(:new).never
|
170
|
+
mock_module.enqueue_for_backend(*args)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'add a worker to the girl_friday queue' do
|
174
|
+
expected = [{ :worker => MockWorker.new('FakeClass', 1, :image) }]
|
175
|
+
mock_module.backend :girl_friday
|
176
|
+
mock_module.instance_variable_set('@girl_friday_queue', [])
|
177
|
+
mock_module.enqueue_for_backend(*args)
|
178
|
+
expect(mock_module.instance_variable_get '@girl_friday_queue').to eql(expected)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'qu' do
|
183
|
+
let(:args) { [MockWorker, 'FakeClass', 1, :image] }
|
184
|
+
before do
|
185
|
+
Qu.expects(:enqueue).with(*args)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'sets a variable with the queue name, defaults to :carrierwave' do
|
189
|
+
mock_module.backend :qu
|
190
|
+
mock_module.enqueue_for_backend(*args)
|
191
|
+
expect(MockWorker.instance_variable_get '@queue').to eql(:carrierwave)
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'sets a variable to the queue name passed to #backend' do
|
195
|
+
mock_module.backend :qu, :queue => :awesome_queue
|
196
|
+
mock_module.enqueue_for_backend(*args)
|
197
|
+
expect(MockWorker.instance_variable_get '@queue').to eql(:awesome_queue)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'qc' do
|
202
|
+
it 'calls enqueue with the passed args' do
|
203
|
+
QC.expects(:enqueue).with("MockWorker.perform", 'FakeClass', 1, 'image')
|
204
|
+
mock_module.backend :qc
|
205
|
+
mock_module.enqueue_for_backend(MockWorker, 'FakeClass', 1, :image)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'immediate' do
|
210
|
+
it 'instantiates a worker passing the args and calls perform' do
|
211
|
+
worker = mock('Worker')
|
212
|
+
MockWorker.expects(:new).with('FakeClass', 1, :image).returns(worker)
|
213
|
+
worker.expects(:perform)
|
214
|
+
mock_module.backend :immediate
|
215
|
+
mock_module.enqueue_for_backend(MockWorker, 'FakeClass', 1, :image)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
85
219
|
end
|
86
220
|
end
|
87
221
|
|
File without changes
|
@@ -5,10 +5,9 @@ require 'backgrounder/workers/process_asset'
|
|
5
5
|
describe CarrierWave::Workers::ProcessAsset do
|
6
6
|
let(:worker_class) { CarrierWave::Workers::ProcessAsset }
|
7
7
|
let(:user) { mock('User') }
|
8
|
-
let(:image) { mock('UserAsset') }
|
9
8
|
let!(:worker) { worker_class.new(user, '22', :image) }
|
10
9
|
|
11
|
-
|
10
|
+
describe ".perform" do
|
12
11
|
it 'creates a new instance and calls perform' do
|
13
12
|
args = [user, '22', :image]
|
14
13
|
worker_class.expects(:new).with(*args).returns(worker)
|
@@ -18,29 +17,54 @@ describe CarrierWave::Workers::ProcessAsset do
|
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
|
-
|
22
|
-
|
20
|
+
describe "#perform" do
|
21
|
+
let(:image) { mock('UserAsset') }
|
22
|
+
|
23
|
+
before do
|
23
24
|
user.expects(:find).with('22').returns(user).once
|
24
25
|
user.expects(:image).once.returns(image)
|
25
26
|
user.expects(:process_image_upload=).with(true).once
|
26
|
-
|
27
27
|
image.expects(:recreate_versions!).once.returns(true)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'processes versions with image_processing column' do
|
28
31
|
user.expects(:respond_to?).with(:image_processing).once.returns(true)
|
29
|
-
user.expects(:
|
30
|
-
user.expects(:save!)
|
32
|
+
user.expects(:update_attribute).with(:image_processing, nil).once
|
31
33
|
worker.perform
|
32
34
|
end
|
33
35
|
|
34
36
|
it 'processes versions without image_processing column' do
|
35
|
-
user.expects(:find).with('22').returns(user).once
|
36
|
-
user.expects(:image).once.returns(image)
|
37
|
-
user.expects(:process_image_upload=).with(true).once
|
38
|
-
|
39
|
-
image.expects(:recreate_versions!).once.returns(true)
|
40
37
|
user.expects(:respond_to?).with(:image_processing).once.returns(false)
|
41
|
-
user.expects(:
|
42
|
-
user.expects(:save!).never
|
38
|
+
user.expects(:update_attribute).never
|
43
39
|
worker.perform
|
44
40
|
end
|
45
41
|
end
|
42
|
+
|
43
|
+
describe '#perform with args' do
|
44
|
+
let(:admin) { mock('Admin') }
|
45
|
+
let(:avatar) { mock('AdminAsset') }
|
46
|
+
let(:worker) { worker_class.new }
|
47
|
+
|
48
|
+
before do
|
49
|
+
admin.expects(:find).with('23').returns(admin).once
|
50
|
+
admin.expects(:avatar).once.returns(avatar)
|
51
|
+
admin.expects(:process_avatar_upload=).with(true).once
|
52
|
+
admin.expects(:respond_to?).with(:avatar_processing).once.returns(false)
|
53
|
+
avatar.expects(:recreate_versions!).once.returns(true)
|
54
|
+
|
55
|
+
worker.perform admin, '23', :avatar
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'sets klass' do
|
59
|
+
expect(worker.klass).to eql(admin)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'sets column' do
|
63
|
+
expect(worker.id).to eql('23')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'sets id' do
|
67
|
+
expect(worker.column).to eql(:avatar)
|
68
|
+
end
|
69
|
+
end
|
46
70
|
end
|
@@ -3,35 +3,87 @@ require 'spec_helper'
|
|
3
3
|
require 'backgrounder/workers/store_asset'
|
4
4
|
|
5
5
|
describe CarrierWave::Workers::StoreAsset do
|
6
|
+
let(:fixtures_path) { File.expand_path('../fixtures/images', __FILE__) }
|
6
7
|
let(:worker_class) { CarrierWave::Workers::StoreAsset }
|
7
|
-
let(:user)
|
8
|
-
let(:image) { mock('UserAsset') }
|
8
|
+
let(:user) { mock('User') }
|
9
9
|
let!(:worker) { worker_class.new(user, '22', :image) }
|
10
10
|
|
11
|
-
|
11
|
+
describe ".perform" do
|
12
12
|
it 'creates a new instance and calls perform' do
|
13
13
|
args = [user, '22', :image]
|
14
14
|
worker_class.expects(:new).with(*args).returns(worker)
|
15
15
|
worker_class.any_instance.expects(:perform)
|
16
|
-
|
17
16
|
worker_class.perform(*args)
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
user.expects(:image_tmp).once.returns('test.jpg')
|
26
|
-
user.expects(:image).once.returns(image)
|
20
|
+
describe "#perform" do
|
21
|
+
let(:image) { mock('UserAsset') }
|
22
|
+
|
23
|
+
before do
|
27
24
|
image.expects(:root).once.returns(File.expand_path('..', __FILE__))
|
28
25
|
image.expects(:cache_dir).once.returns('fixtures')
|
26
|
+
user.expects(:image_tmp).twice.returns('images/test.jpg')
|
27
|
+
user.expects(:find).with('22').once.returns(user)
|
28
|
+
user.expects(:image).once.returns(image)
|
29
29
|
user.expects(:process_image_upload=).with(true).once
|
30
30
|
user.expects(:image=).once
|
31
31
|
user.expects(:image_tmp=).with(nil).once
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'removes tmp directory on success' do
|
35
|
+
FileUtils.expects(:rm_r).with(fixtures_path, :force => true).once
|
32
36
|
user.expects(:save!).once.returns(true)
|
37
|
+
worker.perform
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'does not remove the tmp directory if save! fails' do
|
41
|
+
FileUtils.expects(:rm_r).never
|
42
|
+
user.expects(:save!).once.returns(false)
|
43
|
+
worker.perform
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'sets the cache_path' do
|
47
|
+
user.expects(:save!).once.returns(false)
|
48
|
+
worker.perform
|
49
|
+
expect(worker.cache_path).to eql(fixtures_path + '/test.jpg')
|
50
|
+
end
|
33
51
|
|
52
|
+
it 'sets the tmp_directory' do
|
53
|
+
user.expects(:save!).once.returns(false)
|
34
54
|
worker.perform
|
55
|
+
expect(worker.tmp_directory).to eql(fixtures_path)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#perform with args' do
|
60
|
+
let(:admin) { mock('Admin') }
|
61
|
+
let(:image) { mock('AdminAsset') }
|
62
|
+
let(:worker) { worker_class.new }
|
63
|
+
|
64
|
+
before do
|
65
|
+
image.expects(:root).once.returns(File.expand_path('..', __FILE__))
|
66
|
+
image.expects(:cache_dir).once.returns('fixtures')
|
67
|
+
admin.expects(:avatar_tmp).twice.returns('images/test.jpg')
|
68
|
+
admin.expects(:find).with('23').once.returns(admin)
|
69
|
+
admin.expects(:avatar).once.returns(image)
|
70
|
+
admin.expects(:process_avatar_upload=).with(true).once
|
71
|
+
admin.expects(:avatar=).once
|
72
|
+
admin.expects(:avatar_tmp=).with(nil).once
|
73
|
+
admin.expects(:save!).once.returns(false)
|
74
|
+
worker.perform admin, '23', :avatar
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'sets klass' do
|
78
|
+
expect(worker.klass).to eql(admin)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'sets column' do
|
82
|
+
expect(worker.id).to eql('23')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'sets id' do
|
86
|
+
expect(worker.column).to eql(:avatar)
|
35
87
|
end
|
36
88
|
end
|
37
|
-
end
|
89
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Fixture module declarations for backend detection testing
|
2
2
|
|
3
3
|
module GirlFriday
|
4
|
+
class WorkQueue
|
5
|
+
end
|
4
6
|
end
|
5
7
|
|
6
8
|
module Delayed
|
@@ -15,6 +17,9 @@ module Qu
|
|
15
17
|
end
|
16
18
|
|
17
19
|
module Sidekiq
|
20
|
+
module Client
|
21
|
+
end
|
22
|
+
|
18
23
|
module Worker
|
19
24
|
def self.included(base)
|
20
25
|
base.extend(ClassMethods)
|
@@ -23,6 +28,9 @@ module Sidekiq
|
|
23
28
|
module ClassMethods
|
24
29
|
def sidekiq_options(opts = {})
|
25
30
|
end
|
31
|
+
|
32
|
+
def client_push(item)
|
33
|
+
end
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class MockWorker < Struct.new(:klass, :id, :column)
|
2
|
+
def self.perform(*args)
|
3
|
+
new(*args).perform
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform(*args)
|
7
|
+
set_args(*args) unless args.empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
def set_args(klass, id, column)
|
11
|
+
self.klass, self.id, self.column = klass, id, column
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class MockSidekiqWorker < MockWorker
|
16
|
+
include Sidekiq::Worker
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave_backgrounder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: carrierwave
|
@@ -84,6 +84,7 @@ extra_rdoc_files: []
|
|
84
84
|
files:
|
85
85
|
- .gitignore
|
86
86
|
- .rspec
|
87
|
+
- .travis.yml
|
87
88
|
- CHANGELOG.md
|
88
89
|
- Gemfile
|
89
90
|
- README.md
|
@@ -105,13 +106,15 @@ files:
|
|
105
106
|
- spec/backgrounder/orm/activemodel_spec.rb
|
106
107
|
- spec/backgrounder/orm/base_spec.rb
|
107
108
|
- spec/backgrounder/support/backends_spec.rb
|
108
|
-
- spec/backgrounder/workers/fixtures/test.jpg
|
109
|
+
- spec/backgrounder/workers/fixtures/images/test.jpg
|
109
110
|
- spec/backgrounder/workers/process_asset_spec.rb
|
110
111
|
- spec/backgrounder/workers/store_asset_spec.rb
|
111
112
|
- spec/spec_helper.rb
|
112
113
|
- spec/support/backend_constants.rb
|
113
|
-
|
114
|
-
|
114
|
+
- spec/support/mock_worker.rb
|
115
|
+
homepage: https://github.com/lardawge/carrierwave_backgrounder
|
116
|
+
licenses:
|
117
|
+
- MIT
|
115
118
|
post_install_message:
|
116
119
|
rdoc_options: []
|
117
120
|
require_paths:
|
@@ -124,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
124
127
|
version: '0'
|
125
128
|
segments:
|
126
129
|
- 0
|
127
|
-
hash: -
|
130
|
+
hash: -2596358502417703338
|
128
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
132
|
none: false
|
130
133
|
requirements:
|
@@ -133,20 +136,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
136
|
version: '0'
|
134
137
|
segments:
|
135
138
|
- 0
|
136
|
-
hash: -
|
139
|
+
hash: -2596358502417703338
|
137
140
|
requirements: []
|
138
|
-
rubyforge_project:
|
141
|
+
rubyforge_project:
|
139
142
|
rubygems_version: 1.8.24
|
140
143
|
signing_key:
|
141
144
|
specification_version: 3
|
142
145
|
summary: Offload CarrierWave's image processing and storage to a background process
|
143
|
-
using Delayed Job
|
146
|
+
using Delayed Job, Resque, Sidekiq, Qu, Queue Classic or Girl Friday
|
144
147
|
test_files:
|
145
148
|
- spec/backgrounder/orm/activemodel_spec.rb
|
146
149
|
- spec/backgrounder/orm/base_spec.rb
|
147
150
|
- spec/backgrounder/support/backends_spec.rb
|
148
|
-
- spec/backgrounder/workers/fixtures/test.jpg
|
151
|
+
- spec/backgrounder/workers/fixtures/images/test.jpg
|
149
152
|
- spec/backgrounder/workers/process_asset_spec.rb
|
150
153
|
- spec/backgrounder/workers/store_asset_spec.rb
|
151
154
|
- spec/spec_helper.rb
|
152
155
|
- spec/support/backend_constants.rb
|
156
|
+
- spec/support/mock_worker.rb
|