Class: RuboCop::Cop::Sidekiq::DateTimeArgument

Inherits:
Cop
  • Object
show all
Includes:
Helpers
Defined in:
lib/rubocop/cop/sidekiq/date_time_argument.rb

Overview

This cop checks for date/time objects being passed as arguments to perform a Sidekiq worker. Dates, times, durations, and related classes cannot be serialized to Redis. Use an integer or string representation of the date/time instead.

By default, this only allows ‘to_i` and `to_s` as valid, serializable methods for these classes. Use `AllowedMethods` to specify other allowed methods.

Examples:

# bad
MyWorker.perform_async(Time.now)
MyWorker.perform_async(Date.today)
MyWorker.perform_async(DateTime.now)
MyWorker.perform_async(ActiveSupport::TimeWithZone.new)
MyWorker.perform_async(1.hour)
MyWorker.perform_async(1.hour.ago)

# good
MyWorker.perform_async(Time.now.to_i)
MyWorker.perform_async(Date.today.to_s)

AllowedMethods: [] (default)

# bad
MyWorker.perform_async(Time.now.mday)

AllowedMethods: [‘mday’]

# good
MyWorker.perform_async(Time.now.mday)

Constant Summary collapse

DURATION_METHODS =
%i[
  second
  seconds
  minute
  minutes
  hour
  hours
  day
  days
  week
  weeks
  fortnight
  fortnights
].freeze
DURATION_TO_TIME_METHODS =
%i[
  from_now
  since
  after
  ago
  until
  before
].freeze
DURATION_MSG =
'Durations are not Sidekiq-serializable; use the integer instead.'
MSG =
'Date/Time objects are not Sidekiq-serializable; convert to integers or strings instead.'
ALLOWED_METHODS =
%i[to_i to_s].freeze

Constants included from Helpers

Helpers::NODE_MATCHERS

Instance Method Summary collapse

Methods included from Helpers

#approve_node, #expand_arguments, #in_sidekiq_worker?, included, #node_approved?, #sidekiq_arguments, #within?

Instance Method Details

#allowed_methodsObject



111
112
113
# File 'lib/rubocop/cop/sidekiq/date_time_argument.rb', line 111

def allowed_methods
  Array(cop_config['AllowedMethods']).concat(ALLOWED_METHODS).map(&:to_sym)
end

#duration_method?(sym) ⇒ Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/rubocop/cop/sidekiq/date_time_argument.rb', line 115

def duration_method?(sym)
  DURATION_METHODS.include?(sym)
end

#duration_to_time_method?(sym) ⇒ Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/rubocop/cop/sidekiq/date_time_argument.rb', line 119

def duration_to_time_method?(sym)
  DURATION_TO_TIME_METHODS.include?(sym)
end

#message(node) ⇒ Object



123
124
125
126
127
# File 'lib/rubocop/cop/sidekiq/date_time_argument.rb', line 123

def message(node)
  return DURATION_MSG if duration?(node)

  super
end

#on_send(node) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/rubocop/cop/sidekiq/date_time_argument.rb', line 95

def on_send(node)
  sidekiq_arguments(node).each do |arg|
    next unless date_time_arg?(arg)
    next if node_approved?(arg)

    # If the outer send (ie. the last method in the chain) is in the allowed method
    # list, approve the node (so that sub chains aren't flagged).
    if allowed_methods.include?(arg.method_name)
      approve_node(arg)
      next
    end

    add_offense(arg)
  end
end