activejob 6.0.6.1 → 6.1.0.rc1

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.
@@ -117,17 +117,17 @@ module ActiveJob
117
117
  # HelloJob.perform_later('elfassy')
118
118
  # end
119
119
  # end
120
- def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil)
120
+ def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block)
121
121
  if block_given?
122
- original_count = enqueued_jobs_with(only: only, except: except, queue: queue)
122
+ original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
123
123
 
124
- yield
124
+ assert_nothing_raised(&block)
125
125
 
126
- new_count = enqueued_jobs_with(only: only, except: except, queue: queue)
126
+ new_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
127
127
 
128
- actual_count = new_count - original_count
128
+ actual_count = (new_jobs - original_jobs).count
129
129
  else
130
- actual_count = enqueued_jobs_with(only: only, except: except, queue: queue)
130
+ actual_count = enqueued_jobs_with(only: only, except: except, queue: queue).count
131
131
  end
132
132
 
133
133
  assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
@@ -279,7 +279,7 @@ module ActiveJob
279
279
 
280
280
  performed_jobs_size = new_count - original_count
281
281
  else
282
- performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue)
282
+ performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue).count
283
283
  end
284
284
 
285
285
  assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
@@ -345,44 +345,40 @@ module ActiveJob
345
345
  #
346
346
  # def test_assert_enqueued_with
347
347
  # MyJob.perform_later(1,2,3)
348
- # assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low')
348
+ # assert_enqueued_with(job: MyJob, args: [1,2,3])
349
349
  #
350
- # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
351
- # assert_enqueued_with(job: MyJob, at: Date.tomorrow.noon)
350
+ # MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
351
+ # assert_enqueued_with(at: Date.tomorrow.noon, queue: "my_queue")
352
352
  # end
353
353
  #
354
- # The +at+ and +args+ arguments also accept a proc.
354
+ # The given arguments may also be specified as matcher procs that return a
355
+ # boolean value indicating whether a job's attribute meets certain criteria.
355
356
  #
356
- # To the +at+ proc, it will get passed the actual job's at argument.
357
+ # For example, a proc can be used to match a range of times:
357
358
  #
358
359
  # def test_assert_enqueued_with
359
- # expected_time = ->(at) do
360
- # (Date.yesterday..Date.tomorrow).cover?(at)
361
- # end
360
+ # at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
361
+ #
362
+ # MyJob.set(wait_until: Date.today.noon).perform_later
362
363
  #
363
- # MyJob.set(at: Date.today.noon).perform_later
364
- # assert_enqueued_with(job: MyJob, at: expected_time)
364
+ # assert_enqueued_with(job: MyJob, at: at_matcher)
365
365
  # end
366
366
  #
367
- # To the +args+ proc, it will get passed the actual job's arguments
368
- # Your proc needs to return a boolean value determining if
369
- # the job's arguments matches your expectation. This is useful to check only
370
- # for a subset of arguments.
367
+ # A proc can also be used to match a subset of a job's args:
371
368
  #
372
369
  # def test_assert_enqueued_with
373
- # expected_args = ->(job_args) do
374
- # assert job_args.first.key?(:foo)
375
- # end
370
+ # args_matcher = ->(job_args) { job_args[0].key?(:foo) }
376
371
  #
377
- # MyJob.perform_later(foo: 'bar', other_arg: 'No need to check in the test')
378
- # assert_enqueued_with(job: MyJob, args: expected_args, queue: 'low')
372
+ # MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
373
+ #
374
+ # assert_enqueued_with(job: MyJob, args: args_matcher)
379
375
  # end
380
376
  #
381
377
  # If a block is passed, asserts that the block will cause the job to be
382
378
  # enqueued with the given arguments.
383
379
  #
384
380
  # def test_assert_enqueued_with
385
- # assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low') do
381
+ # assert_enqueued_with(job: MyJob, args: [1,2,3]) do
386
382
  # MyJob.perform_later(1,2,3)
387
383
  # end
388
384
  #
@@ -390,22 +386,24 @@ module ActiveJob
390
386
  # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
391
387
  # end
392
388
  # end
393
- def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil)
389
+ def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, &block)
394
390
  expected = { job: job, args: args, at: at, queue: queue }.compact
395
391
  expected_args = prepare_args_for_assertion(expected)
392
+ potential_matches = []
396
393
 
397
394
  if block_given?
398
- original_enqueued_jobs_count = enqueued_jobs.count
395
+ original_enqueued_jobs = enqueued_jobs.dup
399
396
 
400
- yield
397
+ assert_nothing_raised(&block)
401
398
 
402
- jobs = enqueued_jobs.drop(original_enqueued_jobs_count)
399
+ jobs = enqueued_jobs - original_enqueued_jobs
403
400
  else
404
401
  jobs = enqueued_jobs
405
402
  end
406
403
 
407
404
  matching_job = jobs.find do |enqueued_job|
408
405
  deserialized_job = deserialize_args_for_assertion(enqueued_job)
406
+ potential_matches << deserialized_job
409
407
 
410
408
  expected_args.all? do |key, value|
411
409
  if value.respond_to?(:call)
@@ -416,7 +414,9 @@ module ActiveJob
416
414
  end
417
415
  end
418
416
 
419
- assert matching_job, "No enqueued job found with #{expected}"
417
+ message = +"No enqueued job found with #{expected}"
418
+ message << "\n\nPotential matches: #{potential_matches.join("\n")}" if potential_matches.present?
419
+ assert matching_job, message
420
420
  instantiate_job(matching_job)
421
421
  end
422
422
 
@@ -427,42 +427,40 @@ module ActiveJob
427
427
  #
428
428
  # perform_enqueued_jobs
429
429
  #
430
- # assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high')
430
+ # assert_performed_with(job: MyJob, args: [1,2,3])
431
431
  #
432
- # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
432
+ # MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
433
433
  #
434
434
  # perform_enqueued_jobs
435
435
  #
436
- # assert_performed_with(job: MyJob, at: Date.tomorrow.noon)
436
+ # assert_performed_with(at: Date.tomorrow.noon, queue: "my_queue")
437
437
  # end
438
438
  #
439
- # The +at+ and +args+ arguments also accept a proc.
439
+ # The given arguments may also be specified as matcher procs that return a
440
+ # boolean value indicating whether a job's attribute meets certain criteria.
440
441
  #
441
- # To the +at+ proc, it will get passed the actual job's at argument.
442
+ # For example, a proc can be used to match a range of times:
442
443
  #
443
- # def test_assert_enqueued_with
444
- # expected_time = ->(at) do
445
- # (Date.yesterday..Date.tomorrow).cover?(at)
446
- # end
444
+ # def test_assert_performed_with
445
+ # at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
446
+ #
447
+ # MyJob.set(wait_until: Date.today.noon).perform_later
447
448
  #
448
- # MyJob.set(at: Date.today.noon).perform_later
449
- # assert_enqueued_with(job: MyJob, at: expected_time)
449
+ # perform_enqueued_jobs
450
+ #
451
+ # assert_performed_with(job: MyJob, at: at_matcher)
450
452
  # end
451
453
  #
452
- # To the +args+ proc, it will get passed the actual job's arguments
453
- # Your proc needs to return a boolean value determining if
454
- # the job's arguments matches your expectation. This is useful to check only
455
- # for a subset of arguments.
454
+ # A proc can also be used to match a subset of a job's args:
456
455
  #
457
456
  # def test_assert_performed_with
458
- # expected_args = ->(job_args) do
459
- # assert job_args.first.key?(:foo)
460
- # end
461
- # MyJob.perform_later(foo: 'bar', other_arg: 'No need to check in the test')
457
+ # args_matcher = ->(job_args) { job_args[0].key?(:foo) }
458
+ #
459
+ # MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
462
460
  #
463
461
  # perform_enqueued_jobs
464
462
  #
465
- # assert_performed_with(job: MyJob, args: expected_args, queue: 'high')
463
+ # assert_performed_with(job: MyJob, args: args_matcher)
466
464
  # end
467
465
  #
468
466
  # If a block is passed, that block performs all of the jobs that were
@@ -470,7 +468,7 @@ module ActiveJob
470
468
  # the job has been performed with the given arguments in the block.
471
469
  #
472
470
  # def test_assert_performed_with
473
- # assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do
471
+ # assert_performed_with(job: MyJob, args: [1,2,3]) do
474
472
  # MyJob.perform_later(1,2,3)
475
473
  # end
476
474
  #
@@ -481,6 +479,7 @@ module ActiveJob
481
479
  def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, &block)
482
480
  expected = { job: job, args: args, at: at, queue: queue }.compact
483
481
  expected_args = prepare_args_for_assertion(expected)
482
+ potential_matches = []
484
483
 
485
484
  if block_given?
486
485
  original_performed_jobs_count = performed_jobs.count
@@ -494,6 +493,7 @@ module ActiveJob
494
493
 
495
494
  matching_job = jobs.find do |enqueued_job|
496
495
  deserialized_job = deserialize_args_for_assertion(enqueued_job)
496
+ potential_matches << deserialized_job
497
497
 
498
498
  expected_args.all? do |key, value|
499
499
  if value.respond_to?(:call)
@@ -504,7 +504,10 @@ module ActiveJob
504
504
  end
505
505
  end
506
506
 
507
- assert matching_job, "No performed job found with #{expected}"
507
+ message = +"No performed job found with #{expected}"
508
+ message << "\n\nPotential matches: #{potential_matches.join("\n")}" if potential_matches.present?
509
+ assert matching_job, message
510
+
508
511
  instantiate_job(matching_job)
509
512
  end
510
513
 
@@ -563,8 +566,10 @@ module ActiveJob
563
566
  # assert_performed_jobs 1
564
567
  # end
565
568
  #
566
- def perform_enqueued_jobs(only: nil, except: nil, queue: nil)
567
- return flush_enqueued_jobs(only: only, except: except, queue: queue) unless block_given?
569
+ # If the +:at+ option is specified, then only run jobs enqueued to run
570
+ # immediately or before the given time
571
+ def perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block)
572
+ return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at) unless block_given?
568
573
 
569
574
  validate_option(only: only, except: except)
570
575
 
@@ -573,6 +578,7 @@ module ActiveJob
573
578
  old_filter = queue_adapter.filter
574
579
  old_reject = queue_adapter.reject
575
580
  old_queue = queue_adapter.queue
581
+ old_at = queue_adapter.at
576
582
 
577
583
  begin
578
584
  queue_adapter.perform_enqueued_jobs = true
@@ -580,14 +586,16 @@ module ActiveJob
580
586
  queue_adapter.filter = only
581
587
  queue_adapter.reject = except
582
588
  queue_adapter.queue = queue
589
+ queue_adapter.at = at
583
590
 
584
- yield
591
+ assert_nothing_raised(&block)
585
592
  ensure
586
593
  queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs
587
594
  queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs
588
595
  queue_adapter.filter = old_filter
589
596
  queue_adapter.reject = old_reject
590
597
  queue_adapter.queue = old_queue
598
+ queue_adapter.at = old_at
591
599
  end
592
600
  end
593
601
 
@@ -609,10 +617,10 @@ module ActiveJob
609
617
  performed_jobs.clear
610
618
  end
611
619
 
612
- def jobs_with(jobs, only: nil, except: nil, queue: nil)
620
+ def jobs_with(jobs, only: nil, except: nil, queue: nil, at: nil)
613
621
  validate_option(only: only, except: except)
614
622
 
615
- jobs.count do |job|
623
+ jobs.dup.select do |job|
616
624
  job_class = job.fetch(:job)
617
625
 
618
626
  if only
@@ -625,6 +633,10 @@ module ActiveJob
625
633
  next false unless queue.to_s == job.fetch(:queue, job_class.queue_name)
626
634
  end
627
635
 
636
+ if at && job[:at]
637
+ next false if job[:at] > at.to_f
638
+ end
639
+
628
640
  yield job if block_given?
629
641
 
630
642
  true
@@ -637,41 +649,28 @@ module ActiveJob
637
649
  ->(job) { Array(filter).include?(job.fetch(:job)) }
638
650
  end
639
651
 
640
- def enqueued_jobs_with(only: nil, except: nil, queue: nil, &block)
641
- jobs_with(enqueued_jobs, only: only, except: except, queue: queue, &block)
652
+ def enqueued_jobs_with(only: nil, except: nil, queue: nil, at: nil, &block)
653
+ jobs_with(enqueued_jobs, only: only, except: except, queue: queue, at: at, &block)
642
654
  end
643
655
 
644
656
  def performed_jobs_with(only: nil, except: nil, queue: nil, &block)
645
657
  jobs_with(performed_jobs, only: only, except: except, queue: queue, &block)
646
658
  end
647
659
 
648
- def flush_enqueued_jobs(only: nil, except: nil, queue: nil)
649
- enqueued_jobs_with(only: only, except: except, queue: queue) do |payload|
650
- instantiate_job(payload).perform_now
660
+ def flush_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil)
661
+ enqueued_jobs_with(only: only, except: except, queue: queue, at: at) do |payload|
662
+ queue_adapter.enqueued_jobs.delete(payload)
651
663
  queue_adapter.performed_jobs << payload
652
- end
664
+ instantiate_job(payload).perform_now
665
+ end.count
653
666
  end
654
667
 
655
668
  def prepare_args_for_assertion(args)
656
669
  args.dup.tap do |arguments|
657
- if arguments[:at] && !arguments[:at].respond_to?(:call)
670
+ if arguments[:at].acts_like?(:time)
658
671
  at_range = arguments[:at] - 1..arguments[:at] + 1
659
672
  arguments[:at] = ->(at) { at_range.cover?(at) }
660
673
  end
661
- arguments[:args] = round_time_arguments(arguments[:args]) if arguments[:args]
662
- end
663
- end
664
-
665
- def round_time_arguments(argument)
666
- case argument
667
- when Time, ActiveSupport::TimeWithZone, DateTime
668
- argument.change(usec: 0)
669
- when Hash
670
- argument.transform_values { |value| round_time_arguments(value) }
671
- when Array
672
- argument.map { |element| round_time_arguments(element) }
673
- else
674
- argument
675
674
  end
676
675
  end
677
676
 
data/lib/active_job.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2014-2019 David Heinemeier Hansson
4
+ # Copyright (c) 2014-2020 David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activejob
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.6.1
4
+ version: 6.1.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-17 00:00:00.000000000 Z
11
+ date: 2020-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 6.0.6.1
19
+ version: 6.1.0.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 6.0.6.1
26
+ version: 6.1.0.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: globalid
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -57,6 +57,8 @@ files:
57
57
  - lib/active_job/exceptions.rb
58
58
  - lib/active_job/execution.rb
59
59
  - lib/active_job/gem_version.rb
60
+ - lib/active_job/instrumentation.rb
61
+ - lib/active_job/log_subscriber.rb
60
62
  - lib/active_job/logging.rb
61
63
  - lib/active_job/queue_adapter.rb
62
64
  - lib/active_job/queue_adapters.rb
@@ -78,8 +80,10 @@ files:
78
80
  - lib/active_job/serializers/date_serializer.rb
79
81
  - lib/active_job/serializers/date_time_serializer.rb
80
82
  - lib/active_job/serializers/duration_serializer.rb
83
+ - lib/active_job/serializers/module_serializer.rb
81
84
  - lib/active_job/serializers/object_serializer.rb
82
85
  - lib/active_job/serializers/symbol_serializer.rb
86
+ - lib/active_job/serializers/time_object_serializer.rb
83
87
  - lib/active_job/serializers/time_serializer.rb
84
88
  - lib/active_job/serializers/time_with_zone_serializer.rb
85
89
  - lib/active_job/test_case.rb
@@ -95,12 +99,11 @@ licenses:
95
99
  - MIT
96
100
  metadata:
97
101
  bug_tracker_uri: https://github.com/rails/rails/issues
98
- changelog_uri: https://github.com/rails/rails/blob/v6.0.6.1/activejob/CHANGELOG.md
99
- documentation_uri: https://api.rubyonrails.org/v6.0.6.1/
102
+ changelog_uri: https://github.com/rails/rails/blob/v6.1.0.rc1/activejob/CHANGELOG.md
103
+ documentation_uri: https://api.rubyonrails.org/v6.1.0.rc1/
100
104
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
101
- source_code_uri: https://github.com/rails/rails/tree/v6.0.6.1/activejob
102
- rubygems_mfa_required: 'true'
103
- post_install_message:
105
+ source_code_uri: https://github.com/rails/rails/tree/v6.1.0.rc1/activejob
106
+ post_install_message:
104
107
  rdoc_options: []
105
108
  require_paths:
106
109
  - lib
@@ -111,12 +114,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
114
  version: 2.5.0
112
115
  required_rubygems_version: !ruby/object:Gem::Requirement
113
116
  requirements:
114
- - - ">="
117
+ - - ">"
115
118
  - !ruby/object:Gem::Version
116
- version: '0'
119
+ version: 1.3.1
117
120
  requirements: []
118
- rubygems_version: 3.4.3
119
- signing_key:
121
+ rubygems_version: 3.1.4
122
+ signing_key:
120
123
  specification_version: 4
121
124
  summary: Job framework with pluggable queues.
122
125
  test_files: []