activejob-retry 0.0.1 → 0.1.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -0
  3. data/.travis.yml +20 -5
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +9 -6
  6. data/Gemfile.lock +63 -51
  7. data/LICENSE +1 -1
  8. data/README.md +57 -25
  9. data/Rakefile +14 -13
  10. data/activejob-retry.gemspec +9 -12
  11. data/lib/active_job/retry.rb +69 -90
  12. data/lib/active_job/retry/constant_backoff_strategy.rb +50 -0
  13. data/lib/active_job/retry/constant_options_validator.rb +76 -0
  14. data/lib/active_job/retry/deserialize_monkey_patch.rb +17 -12
  15. data/lib/active_job/retry/errors.rb +6 -0
  16. data/lib/active_job/retry/variable_backoff_strategy.rb +34 -0
  17. data/lib/active_job/retry/variable_options_validator.rb +56 -0
  18. data/lib/active_job/retry/version.rb +1 -1
  19. data/spec/retry/constant_backoff_strategy_spec.rb +115 -0
  20. data/spec/retry/constant_options_validator_spec.rb +81 -0
  21. data/spec/retry/variable_backoff_strategy_spec.rb +121 -0
  22. data/spec/retry/variable_options_validator_spec.rb +83 -0
  23. data/spec/retry_spec.rb +114 -170
  24. data/spec/spec_helper.rb +3 -2
  25. data/test/adapters/backburner.rb +3 -0
  26. data/test/adapters/delayed_job.rb +7 -0
  27. data/test/adapters/inline.rb +1 -0
  28. data/test/adapters/qu.rb +3 -0
  29. data/test/adapters/que.rb +4 -0
  30. data/test/adapters/queue_classic.rb +2 -0
  31. data/test/adapters/resque.rb +2 -0
  32. data/test/adapters/sidekiq.rb +2 -0
  33. data/test/adapters/sneakers.rb +2 -0
  34. data/test/adapters/sucker_punch.rb +2 -0
  35. data/test/cases/adapter_test.rb +8 -0
  36. data/test/cases/argument_serialization_test.rb +84 -0
  37. data/test/cases/callbacks_test.rb +23 -0
  38. data/test/cases/job_serialization_test.rb +15 -0
  39. data/test/cases/logging_test.rb +114 -0
  40. data/test/cases/queue_naming_test.rb +102 -0
  41. data/test/cases/queuing_test.rb +44 -0
  42. data/test/cases/rescue_test.rb +35 -0
  43. data/test/cases/test_case_test.rb +14 -0
  44. data/test/cases/test_helper_test.rb +226 -0
  45. data/test/helper.rb +21 -0
  46. data/test/integration/queuing_test.rb +46 -0
  47. data/test/jobs/callback_job.rb +31 -0
  48. data/test/jobs/gid_job.rb +10 -0
  49. data/test/jobs/hello_job.rb +9 -0
  50. data/test/jobs/logging_job.rb +12 -0
  51. data/test/jobs/nested_job.rb +12 -0
  52. data/test/jobs/rescue_job.rb +31 -0
  53. data/test/models/person.rb +20 -0
  54. data/test/support/backburner/inline.rb +8 -0
  55. data/test/support/delayed_job/delayed/backend/test.rb +111 -0
  56. data/test/support/delayed_job/delayed/serialization/test.rb +0 -0
  57. data/test/support/integration/adapters/backburner.rb +38 -0
  58. data/test/support/integration/adapters/delayed_job.rb +20 -0
  59. data/test/support/integration/adapters/que.rb +37 -0
  60. data/test/support/integration/adapters/resque.rb +49 -0
  61. data/test/support/integration/adapters/sidekiq.rb +58 -0
  62. data/test/support/integration/dummy_app_template.rb +28 -0
  63. data/test/support/integration/helper.rb +30 -0
  64. data/test/support/integration/jobs_manager.rb +27 -0
  65. data/test/support/integration/test_case_helpers.rb +48 -0
  66. data/test/support/job_buffer.rb +19 -0
  67. data/test/support/que/inline.rb +9 -0
  68. metadata +60 -12
  69. data/lib/active_job-retry.rb +0 -14
  70. data/lib/active_job/retry/exponential_backoff.rb +0 -92
  71. data/lib/active_job/retry/exponential_options_validator.rb +0 -57
  72. data/lib/active_job/retry/invalid_configuration_error.rb +0 -6
  73. data/lib/active_job/retry/options_validator.rb +0 -84
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+ require 'jobs/callback_job'
3
+
4
+ require 'active_support/core_ext/object/inclusion'
5
+
6
+ class CallbacksTest < ActiveSupport::TestCase
7
+ test 'perform callbacks' do
8
+ performed_callback_job = CallbackJob.new("A-JOB-ID")
9
+ performed_callback_job.perform_now
10
+ assert "CallbackJob ran before_perform".in? performed_callback_job.history
11
+ assert "CallbackJob ran after_perform".in? performed_callback_job.history
12
+ assert "CallbackJob ran around_perform_start".in? performed_callback_job.history
13
+ assert "CallbackJob ran around_perform_stop".in? performed_callback_job.history
14
+ end
15
+
16
+ test 'enqueue callbacks' do
17
+ enqueued_callback_job = CallbackJob.perform_later
18
+ assert "CallbackJob ran before_enqueue".in? enqueued_callback_job.history
19
+ assert "CallbackJob ran after_enqueue".in? enqueued_callback_job.history
20
+ assert "CallbackJob ran around_enqueue_start".in? enqueued_callback_job.history
21
+ assert "CallbackJob ran around_enqueue_stop".in? enqueued_callback_job.history
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'helper'
2
+ require 'jobs/gid_job'
3
+ require 'models/person'
4
+
5
+ class JobSerializationTest < ActiveSupport::TestCase
6
+ setup do
7
+ JobBuffer.clear
8
+ @person = Person.find(5)
9
+ end
10
+
11
+ test 'serialize job with gid' do
12
+ GidJob.perform_later @person
13
+ assert_equal "Person with ID: 5", JobBuffer.last_value
14
+ end
15
+ end
@@ -0,0 +1,114 @@
1
+ require 'helper'
2
+ require "active_support/log_subscriber/test_helper"
3
+ require 'active_support/core_ext/numeric/time'
4
+ require 'jobs/hello_job'
5
+ require 'jobs/logging_job'
6
+ require 'jobs/nested_job'
7
+ require 'models/person'
8
+
9
+ class AdapterTest < ActiveSupport::TestCase
10
+ include ActiveSupport::LogSubscriber::TestHelper
11
+ include ActiveSupport::Logger::Severity
12
+
13
+ class TestLogger < ActiveSupport::Logger
14
+ def initialize
15
+ @file = StringIO.new
16
+ super(@file)
17
+ end
18
+
19
+ def messages
20
+ @file.rewind
21
+ @file.read
22
+ end
23
+ end
24
+
25
+ def setup
26
+ super
27
+ JobBuffer.clear
28
+ @old_logger = ActiveJob::Base.logger
29
+ @logger = ActiveSupport::TaggedLogging.new(TestLogger.new)
30
+ set_logger @logger
31
+ ActiveJob::Logging::LogSubscriber.attach_to :active_job
32
+ end
33
+
34
+ def teardown
35
+ super
36
+ ActiveJob::Logging::LogSubscriber.log_subscribers.pop
37
+ set_logger @old_logger
38
+ end
39
+
40
+ def set_logger(logger)
41
+ ActiveJob::Base.logger = logger
42
+ end
43
+
44
+
45
+ def test_uses_active_job_as_tag
46
+ HelloJob.perform_later "Cristian"
47
+ assert_match(/\[ActiveJob\]/, @logger.messages)
48
+ end
49
+
50
+ def test_uses_job_name_as_tag
51
+ LoggingJob.perform_later "Dummy"
52
+ assert_match(/\[LoggingJob\]/, @logger.messages)
53
+ end
54
+
55
+ def test_uses_job_id_as_tag
56
+ LoggingJob.perform_later "Dummy"
57
+ assert_match(/\[LOGGING-JOB-ID\]/, @logger.messages)
58
+ end
59
+
60
+ def test_logs_correct_queue_name
61
+ original_queue_name = LoggingJob.queue_name
62
+ LoggingJob.queue_as :php_jobs
63
+ LoggingJob.perform_later("Dummy")
64
+ assert_match(/to .*?\(php_jobs\).*/, @logger.messages)
65
+ ensure
66
+ LoggingJob.queue_name = original_queue_name
67
+ end
68
+
69
+ def test_globalid_parameter_logging
70
+ person = Person.new(123)
71
+ LoggingJob.perform_later person
72
+ assert_match(%r{Enqueued.*gid://aj/Person/123}, @logger.messages)
73
+ assert_match(%r{Dummy, here is it: #<Person:.*>}, @logger.messages)
74
+ assert_match(%r{Performing.*gid://aj/Person/123}, @logger.messages)
75
+ end
76
+
77
+ def test_enqueue_job_logging
78
+ HelloJob.perform_later "Cristian"
79
+ assert_match(/Enqueued HelloJob \(Job ID: .*?\) to .*?:.*Cristian/, @logger.messages)
80
+ end
81
+
82
+ def test_perform_job_logging
83
+ LoggingJob.perform_later "Dummy"
84
+ assert_match(/Performing LoggingJob from .*? with arguments:.*Dummy/, @logger.messages)
85
+ assert_match(/Dummy, here is it: Dummy/, @logger.messages)
86
+ assert_match(/Performed LoggingJob from .*? in .*ms/, @logger.messages)
87
+ end
88
+
89
+ def test_perform_nested_jobs_logging
90
+ NestedJob.perform_later
91
+ assert_match(/\[LoggingJob\] \[.*?\]/, @logger.messages)
92
+ assert_match(/\[ActiveJob\] Enqueued NestedJob \(Job ID: .*\) to/, @logger.messages)
93
+ assert_match(/\[ActiveJob\] \[NestedJob\] \[NESTED-JOB-ID\] Performing NestedJob from/, @logger.messages)
94
+ assert_match(/\[ActiveJob\] \[NestedJob\] \[NESTED-JOB-ID\] Enqueued LoggingJob \(Job ID: .*?\) to .* with arguments: "NestedJob"/, @logger.messages)
95
+ assert_match(/\[ActiveJob\].*\[LoggingJob\] \[LOGGING-JOB-ID\] Performing LoggingJob from .* with arguments: "NestedJob"/, @logger.messages)
96
+ assert_match(/\[ActiveJob\].*\[LoggingJob\] \[LOGGING-JOB-ID\] Dummy, here is it: NestedJob/, @logger.messages)
97
+ assert_match(/\[ActiveJob\].*\[LoggingJob\] \[LOGGING-JOB-ID\] Performed LoggingJob from .* in/, @logger.messages)
98
+ assert_match(/\[ActiveJob\] \[NestedJob\] \[NESTED-JOB-ID\] Performed NestedJob from .* in/, @logger.messages)
99
+ end
100
+
101
+ def test_enqueue_at_job_logging
102
+ HelloJob.set(wait_until: 24.hours.from_now).perform_later "Cristian"
103
+ assert_match(/Enqueued HelloJob \(Job ID: .*\) to .*? at.*Cristian/, @logger.messages)
104
+ rescue NotImplementedError
105
+ skip
106
+ end
107
+
108
+ def test_enqueue_in_job_logging
109
+ HelloJob.set(wait: 2.seconds).perform_later "Cristian"
110
+ assert_match(/Enqueued HelloJob \(Job ID: .*\) to .*? at.*Cristian/, @logger.messages)
111
+ rescue NotImplementedError
112
+ skip
113
+ end
114
+ end
@@ -0,0 +1,102 @@
1
+ require 'helper'
2
+ require 'jobs/hello_job'
3
+ require 'jobs/logging_job'
4
+ require 'jobs/nested_job'
5
+
6
+ class QueueNamingTest < ActiveSupport::TestCase
7
+ test 'name derived from base' do
8
+ assert_equal "default", HelloJob.queue_name
9
+ end
10
+
11
+ test 'uses given queue name job' do
12
+ original_queue_name = HelloJob.queue_name
13
+
14
+ begin
15
+ HelloJob.queue_as :greetings
16
+ assert_equal "greetings", HelloJob.new.queue_name
17
+ ensure
18
+ HelloJob.queue_name = original_queue_name
19
+ end
20
+ end
21
+
22
+ test 'allows a blank queue name' do
23
+ original_queue_name = HelloJob.queue_name
24
+
25
+ begin
26
+ HelloJob.queue_as ""
27
+ assert_equal "", HelloJob.new.queue_name
28
+ ensure
29
+ HelloJob.queue_name = original_queue_name
30
+ end
31
+ end
32
+
33
+ test 'does not use a nil queue name' do
34
+ original_queue_name = HelloJob.queue_name
35
+
36
+ begin
37
+ HelloJob.queue_as nil
38
+ assert_equal "default", HelloJob.new.queue_name
39
+ ensure
40
+ HelloJob.queue_name = original_queue_name
41
+ end
42
+ end
43
+
44
+ test 'evals block given to queue_as to determine queue' do
45
+ original_queue_name = HelloJob.queue_name
46
+
47
+ begin
48
+ HelloJob.queue_as { :another }
49
+ assert_equal "another", HelloJob.new.queue_name
50
+ ensure
51
+ HelloJob.queue_name = original_queue_name
52
+ end
53
+ end
54
+
55
+ test 'can use arguments to determine queue_name in queue_as block' do
56
+ original_queue_name = HelloJob.queue_name
57
+
58
+ begin
59
+ HelloJob.queue_as { self.arguments.first=='1' ? :one : :two }
60
+ assert_equal "one", HelloJob.new('1').queue_name
61
+ assert_equal "two", HelloJob.new('3').queue_name
62
+ ensure
63
+ HelloJob.queue_name = original_queue_name
64
+ end
65
+ end
66
+
67
+ test 'queue_name_prefix prepended to the queue name with default delimiter' do
68
+ original_queue_name_prefix = ActiveJob::Base.queue_name_prefix
69
+ original_queue_name = HelloJob.queue_name
70
+
71
+ begin
72
+ ActiveJob::Base.queue_name_prefix = 'aj'
73
+ HelloJob.queue_as :low
74
+ assert_equal 'aj_low', HelloJob.queue_name
75
+ ensure
76
+ ActiveJob::Base.queue_name_prefix = original_queue_name_prefix
77
+ HelloJob.queue_name = original_queue_name
78
+ end
79
+ end
80
+
81
+ test 'queue_name_prefix prepended to the queue name with custom delimiter' do
82
+ original_queue_name_prefix = ActiveJob::Base.queue_name_prefix
83
+ original_queue_name_delimiter = ActiveJob::Base.queue_name_delimiter
84
+ original_queue_name = HelloJob.queue_name
85
+
86
+ begin
87
+ ActiveJob::Base.queue_name_delimiter = '.'
88
+ ActiveJob::Base.queue_name_prefix = 'aj'
89
+ HelloJob.queue_as :low
90
+ assert_equal 'aj.low', HelloJob.queue_name
91
+ ensure
92
+ ActiveJob::Base.queue_name_prefix = original_queue_name_prefix
93
+ ActiveJob::Base.queue_name_delimiter = original_queue_name_delimiter
94
+ HelloJob.queue_name = original_queue_name
95
+ end
96
+ end
97
+
98
+ test 'uses queue passed to #set' do
99
+ job = HelloJob.set(queue: :some_queue).perform_later
100
+ assert_equal "some_queue", job.queue_name
101
+ end
102
+ end
@@ -0,0 +1,44 @@
1
+ require 'helper'
2
+ require 'jobs/hello_job'
3
+ require 'active_support/core_ext/numeric/time'
4
+
5
+
6
+ class QueuingTest < ActiveSupport::TestCase
7
+ setup do
8
+ JobBuffer.clear
9
+ end
10
+
11
+ test 'run queued job' do
12
+ HelloJob.perform_later
13
+ assert_equal "David says hello", JobBuffer.last_value
14
+ end
15
+
16
+ test 'run queued job with arguments' do
17
+ HelloJob.perform_later "Jamie"
18
+ assert_equal "Jamie says hello", JobBuffer.last_value
19
+ end
20
+
21
+ test 'run queued job later' do
22
+ begin
23
+ result = HelloJob.set(wait_until: 1.second.ago).perform_later "Jamie"
24
+ assert result
25
+ rescue NotImplementedError
26
+ skip
27
+ end
28
+ end
29
+
30
+ test 'job returned by enqueue has the arguments available' do
31
+ job = HelloJob.perform_later "Jamie"
32
+ assert_equal [ "Jamie" ], job.arguments
33
+ end
34
+
35
+
36
+ test 'job returned by perform_at has the timestamp available' do
37
+ begin
38
+ job = HelloJob.set(wait_until: Time.utc(2014, 1, 1)).perform_later
39
+ assert_equal Time.utc(2014, 1, 1).to_f, job.scheduled_at
40
+ rescue NotImplementedError
41
+ skip
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,35 @@
1
+ require 'helper'
2
+ require 'jobs/rescue_job'
3
+ require 'models/person'
4
+
5
+ class RescueTest < ActiveSupport::TestCase
6
+ setup do
7
+ JobBuffer.clear
8
+ end
9
+
10
+ test 'rescue perform exception with retry' do
11
+ job = RescueJob.new("david")
12
+ job.perform_now
13
+ assert_equal ["running", "rescued from ArgumentError", "running", "performed beautifully"], JobBuffer.values
14
+ end
15
+
16
+ test 'retries other errors' do
17
+ job = RescueJob.new("other")
18
+ assert_raises(RescueJob::OtherError) do
19
+ job.perform_now
20
+ assert_equal ["running", "running"], JobBuffer.values
21
+ end
22
+ end
23
+
24
+ test 'rescue from deserialization errors' do
25
+ RescueJob.perform_later Person.new(404)
26
+ assert_includes JobBuffer.values, 'rescued from DeserializationError'
27
+ assert_includes JobBuffer.values, 'DeserializationError original exception was Person::RecordNotFound'
28
+ assert_not_includes JobBuffer.values, 'performed beautifully'
29
+ end
30
+
31
+ test "should not wrap DeserializationError in DeserializationError" do
32
+ RescueJob.perform_later [Person.new(404)]
33
+ assert_includes JobBuffer.values, 'DeserializationError original exception was Person::RecordNotFound'
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ require 'helper'
2
+ require 'jobs/hello_job'
3
+ require 'jobs/logging_job'
4
+ require 'jobs/nested_job'
5
+
6
+ class ActiveJobTestCaseTest < ActiveJob::TestCase
7
+ def test_include_helper
8
+ assert_includes self.class.ancestors, ActiveJob::TestHelper
9
+ end
10
+
11
+ def test_set_test_adapter
12
+ assert_instance_of ActiveJob::QueueAdapters::TestAdapter, self.queue_adapter
13
+ end
14
+ end
@@ -0,0 +1,226 @@
1
+ require 'helper'
2
+ require 'active_support/core_ext/time'
3
+ require 'active_support/core_ext/date'
4
+ require 'jobs/hello_job'
5
+ require 'jobs/logging_job'
6
+ require 'jobs/nested_job'
7
+
8
+ class EnqueuedJobsTest < ActiveJob::TestCase
9
+ def test_assert_enqueued_jobs
10
+ assert_nothing_raised do
11
+ assert_enqueued_jobs 1 do
12
+ HelloJob.perform_later('david')
13
+ end
14
+ end
15
+ end
16
+
17
+ def test_repeated_enqueued_jobs_calls
18
+ assert_nothing_raised do
19
+ assert_enqueued_jobs 1 do
20
+ HelloJob.perform_later('abdelkader')
21
+ end
22
+ end
23
+
24
+ assert_nothing_raised do
25
+ assert_enqueued_jobs 2 do
26
+ HelloJob.perform_later('sean')
27
+ HelloJob.perform_later('yves')
28
+ end
29
+ end
30
+ end
31
+
32
+ def test_assert_enqueued_jobs_with_no_block
33
+ assert_nothing_raised do
34
+ HelloJob.perform_later('rafael')
35
+ assert_enqueued_jobs 1
36
+ end
37
+
38
+ assert_nothing_raised do
39
+ HelloJob.perform_later('aaron')
40
+ HelloJob.perform_later('matthew')
41
+ assert_enqueued_jobs 3
42
+ end
43
+ end
44
+
45
+ def test_assert_no_enqueued_jobs_with_no_block
46
+ assert_nothing_raised do
47
+ assert_no_enqueued_jobs
48
+ end
49
+ end
50
+
51
+ def test_assert_no_enqueued_jobs
52
+ assert_nothing_raised do
53
+ assert_no_enqueued_jobs do
54
+ HelloJob.perform_now
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_assert_enqueued_jobs_too_few_sent
60
+ error = assert_raise ActiveSupport::TestCase::Assertion do
61
+ assert_enqueued_jobs 2 do
62
+ HelloJob.perform_later('xavier')
63
+ end
64
+ end
65
+
66
+ assert_match(/2 .* but 1/, error.message)
67
+ end
68
+
69
+ def test_assert_enqueued_jobs_too_many_sent
70
+ error = assert_raise ActiveSupport::TestCase::Assertion do
71
+ assert_enqueued_jobs 1 do
72
+ HelloJob.perform_later('cristian')
73
+ HelloJob.perform_later('guillermo')
74
+ end
75
+ end
76
+
77
+ assert_match(/1 .* but 2/, error.message)
78
+ end
79
+
80
+ def test_assert_no_enqueued_jobs_failure
81
+ error = assert_raise ActiveSupport::TestCase::Assertion do
82
+ assert_no_enqueued_jobs do
83
+ HelloJob.perform_later('jeremy')
84
+ end
85
+ end
86
+
87
+ assert_match(/0 .* but 1/, error.message)
88
+ end
89
+
90
+ def test_assert_enqueued_job
91
+ assert_enqueued_with(job: LoggingJob, queue: 'default') do
92
+ LoggingJob.set(wait_until: Date.tomorrow.noon).perform_later
93
+ end
94
+ end
95
+
96
+ def test_assert_enqueued_job_failure
97
+ assert_raise ActiveSupport::TestCase::Assertion do
98
+ assert_enqueued_with(job: LoggingJob, queue: 'default') do
99
+ NestedJob.perform_later
100
+ end
101
+ end
102
+
103
+ error = assert_raise ActiveSupport::TestCase::Assertion do
104
+ assert_enqueued_with(job: NestedJob, queue: 'low') do
105
+ NestedJob.perform_later
106
+ end
107
+ end
108
+
109
+ assert_equal 'No enqueued job found with {:job=>NestedJob, :queue=>"low"}', error.message
110
+ end
111
+
112
+ def test_assert_enqueued_job_args
113
+ assert_raise ArgumentError do
114
+ assert_enqueued_with(class: LoggingJob) do
115
+ NestedJob.set(wait_until: Date.tomorrow.noon).perform_later
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ class PerformedJobsTest < ActiveJob::TestCase
122
+ def test_assert_performed_jobs
123
+ assert_nothing_raised do
124
+ assert_performed_jobs 1 do
125
+ HelloJob.perform_later('david')
126
+ end
127
+ end
128
+ end
129
+
130
+ def test_repeated_performed_jobs_calls
131
+ assert_nothing_raised do
132
+ assert_performed_jobs 1 do
133
+ HelloJob.perform_later('abdelkader')
134
+ end
135
+ end
136
+
137
+ assert_nothing_raised do
138
+ assert_performed_jobs 2 do
139
+ HelloJob.perform_later('sean')
140
+ HelloJob.perform_later('yves')
141
+ end
142
+ end
143
+ end
144
+
145
+ def test_assert_performed_jobs_with_no_block
146
+ assert_nothing_raised do
147
+ perform_enqueued_jobs do
148
+ HelloJob.perform_later('rafael')
149
+ end
150
+ assert_performed_jobs 1
151
+ end
152
+
153
+ assert_nothing_raised do
154
+ perform_enqueued_jobs do
155
+ HelloJob.perform_later('aaron')
156
+ HelloJob.perform_later('matthew')
157
+ assert_performed_jobs 3
158
+ end
159
+ end
160
+ end
161
+
162
+ def test_assert_no_performed_jobs_with_no_block
163
+ assert_nothing_raised do
164
+ assert_no_performed_jobs
165
+ end
166
+ end
167
+
168
+ def test_assert_no_performed_jobs
169
+ assert_nothing_raised do
170
+ assert_no_performed_jobs do
171
+ # empty block won't perform jobs
172
+ end
173
+ end
174
+ end
175
+
176
+ def test_assert_performed_jobs_too_few_sent
177
+ error = assert_raise ActiveSupport::TestCase::Assertion do
178
+ assert_performed_jobs 2 do
179
+ HelloJob.perform_later('xavier')
180
+ end
181
+ end
182
+
183
+ assert_match(/2 .* but 1/, error.message)
184
+ end
185
+
186
+ def test_assert_performed_jobs_too_many_sent
187
+ error = assert_raise ActiveSupport::TestCase::Assertion do
188
+ assert_performed_jobs 1 do
189
+ HelloJob.perform_later('cristian')
190
+ HelloJob.perform_later('guillermo')
191
+ end
192
+ end
193
+
194
+ assert_match(/1 .* but 2/, error.message)
195
+ end
196
+
197
+ def test_assert_no_performed_jobs_failure
198
+ error = assert_raise ActiveSupport::TestCase::Assertion do
199
+ assert_no_performed_jobs do
200
+ HelloJob.perform_later('jeremy')
201
+ end
202
+ end
203
+
204
+ assert_match(/0 .* but 1/, error.message)
205
+ end
206
+
207
+ def test_assert_performed_job
208
+ assert_performed_with(job: NestedJob, queue: 'default') do
209
+ NestedJob.perform_later
210
+ end
211
+ end
212
+
213
+ def test_assert_performed_job_failure
214
+ assert_raise ActiveSupport::TestCase::Assertion do
215
+ assert_performed_with(job: LoggingJob, at: Date.tomorrow.noon, queue: 'default') do
216
+ NestedJob.set(wait_until: Date.tomorrow.noon).perform_later
217
+ end
218
+ end
219
+
220
+ assert_raise ActiveSupport::TestCase::Assertion do
221
+ assert_performed_with(job: NestedJob, at: Date.tomorrow.noon, queue: 'low') do
222
+ NestedJob.set(queue: 'low', wait_until: Date.tomorrow.noon).perform_later
223
+ end
224
+ end
225
+ end
226
+ end