lib/rubocop/cop/rails/date.rb in rubocop-0.47.1 vs lib/rubocop/cop/rails/date.rb in rubocop-0.48.0

- old
+ new

@@ -23,11 +23,11 @@ # @example # # no offense # Time.zone.today # Time.zone.today - 1.day # - # # acceptable + # # flexible # Date.current # Date.yesterday # # # always reports offense # Date.today @@ -41,38 +41,33 @@ MSG = 'Do not use `%s` without zone. Use `%s` instead.'.freeze MSG_SEND = 'Do not use `%s` on Date objects, because they ' \ 'know nothing about the time zone in use.'.freeze - BAD_DAYS = [:today, :current, :yesterday, :tomorrow].freeze + BAD_DAYS = %i(today current yesterday tomorrow).freeze def on_const(node) mod, klass = *node.children # we should only check core Date class (`Date` or `::Date`) return unless (mod.nil? || mod.cbase_type?) && method_send?(node) check_date_node(node.parent) if klass == :Date end def on_send(node) - receiver, method_name, *args = *node - return unless receiver && bad_methods.include?(method_name) + return unless node.receiver && bad_methods.include?(node.method_name) - chain = extract_method_chain(node) - return if safe_chain?(chain) + return if safe_chain?(node) || safe_to_time?(node) - return if method_name == :to_time && args.length == 1 - - add_offense(node, :selector, - format(MSG_SEND, - method_name)) + add_offense(node, :selector, format(MSG_SEND, node.method_name)) end private def check_date_node(node) chain = extract_method_chain(node) + return if (chain & bad_days).empty? method_name = (chain & bad_days).join('.') add_offense(node, :selector, @@ -80,46 +75,48 @@ "Date.#{method_name}", "Time.zone.#{method_name}")) end def extract_method_chain(node) - chain = [] - while !node.nil? && node.send_type? - chain << extract_method(node) - node = node.parent - end - chain + [node, *node.each_ancestor(:send)].map(&:method_name) end - def extract_method(node) - _receiver, method_name, *_args = *node - method_name - end - # checks that parent node of send_type # and receiver is the given node def method_send?(node) return false unless node.parent && node.parent.send_type? - receiver, _method_name, *_args = *node.parent - - receiver == node + node.parent.receiver == node end - def safe_chain?(chain) + def safe_chain?(node) + chain = extract_method_chain(node) + (chain & bad_methods).empty? || !(chain & good_methods).empty? end + def safe_to_time?(node) + return unless node.method?(:to_time) + + if node.receiver.str_type? + zone_regexp = /[+-][\d:]+\z/ + + node.receiver.str_content.match(zone_regexp) + else + node.arguments.one? + end + end + def good_days - style == :strict ? [] : [:current, :yesterday, :tomorrow] + style == :strict ? [] : %i(current yesterday tomorrow) end def bad_days BAD_DAYS - good_days end def bad_methods - style == :strict ? [:to_time, :to_time_in_current_zone] : [:to_time] + style == :strict ? %i(to_time to_time_in_current_zone) : [:to_time] end def good_methods style == :strict ? [] : TimeZone::ACCEPTED_METHODS end