Skip to content

Commit

Permalink
[Fix rubocop#1770] Add utc/localtime support to Rails/TimeZone
Browse files Browse the repository at this point in the history
  • Loading branch information
palkan committed Apr 16, 2015
1 parent 10a9ecf commit 9f91860
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Fix handling of `while` and `until` with assignment in `IndentationWidth`. ([@lumeet][])
* [#1793](https://github.com/bbatsov/rubocop/pull/1793): Fix bug in `TrailingComma` that caused `,` in comment to count as a trailing comma. ([@jonas054][])
* [#1765](https://github.com/bbatsov/rubocop/pull/1765): Update 1.9 hash to stop triggering when the symbol is not valid in the 1.9 hash syntax. ([@crimsonknave][])
* [#1767](https://github.com/bbatsov/rubocop/pull/1767): Do not register offenses on Time.utc and Time.localtime(offset) by `Rails/TimeZone`. ([@palkan][])

## 0.30.0 (06/04/2015)

Expand Down
7 changes: 3 additions & 4 deletions lib/rubocop/cop/rails/date.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,9 @@ def check_date_node(node)

def extract_method_chain(node)
chain = []
p = node
while !p.nil? && p.send_type?
chain << extract_method(p)
p = p.parent
while !node.nil? && node.send_type?
chain << extract_method(node)
node = node.parent
end
chain
end
Expand Down
24 changes: 19 additions & 5 deletions lib/rubocop/cop/rails/time_zone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class TimeZone < Cop

MSG = 'Do not use `%s` without zone. Use `%s` instead.'

MSG_LOCALTIME = 'Do not use `Time.localtime` without offset or zone.'

TIMECLASS = [:Time, :DateTime]

DANGER_METHODS = [:now, :local, :new, :strftime, :parse, :at]
Expand All @@ -50,6 +52,8 @@ def check_time_node(klass, node)
return if (chain & DANGER_METHODS).empty? ||
!(chain & good_methods).empty?

return check_localtime(node) if chain.include?(:localtime)

method_name = (chain & DANGER_METHODS).join('.')
safe_method_name = safe_method(method_name, node)

Expand All @@ -62,10 +66,9 @@ def check_time_node(klass, node)

def extract_method_chain(node)
chain = []
p = node
while !p.nil? && p.send_type?
chain << extract_method(p)
p = p.parent
while !node.nil? && node.send_type?
chain << extract_method(node)
node = node.parent
end
chain
end
Expand Down Expand Up @@ -96,8 +99,19 @@ def safe_method(method_name, node)
end
end

def check_localtime(node)
selector_node = node
while !node.nil? && node.send_type?
break if extract_method(node) == :localtime
node = node.parent
end
_receiver, _method, args = *node

add_offense(selector_node, :selector, MSG_LOCALTIME) if args.nil?
end

def good_methods
style == :always ? [:zone] : [:zone, :in_time_zone]
style == :always ? [:zone, :utc] : [:zone, :utc, :in_time_zone]
end
end
end
Expand Down
20 changes: 20 additions & 0 deletions spec/rubocop/cop/rails/time_zone_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.first.message).to include('Time.zone.local')
end

it "accepts #{klass}.now.utc" do
inspect_source(cop, "#{klass}.now.utc")
expect(cop.offenses).to be_empty
end
end

it 'registers an offense for Time.parse' do
Expand Down Expand Up @@ -71,6 +76,11 @@
expect(cop.offenses.size).to eq(1)
end

it 'registers an offense for Time.parse.localtime' do
inspect_source(cop, "Time.parse('12:00').localtime")
expect(cop.offenses.size).to eq(1)
end

it 'registers an offense for Time.at.in_time_zone' do
inspect_source(cop, 'Time.at(ts).in_time_zone')
expect(cop.offenses.size).to eq(1)
Expand Down Expand Up @@ -113,6 +123,16 @@
)
expect(cop.offenses).to be_empty
end

it 'accepts Time.parse.localtime(offset)' do
inspect_source(cop, "Time.parse('12:00').localtime('+03:00')")
expect(cop.offenses).to be_empty
end

it 'accepts Time.zone.parse.localtime' do
inspect_source(cop, "Time.zone.parse('12:00').localtime")
expect(cop.offenses).to be_empty
end
end

context 'when EnforcedStyle is "ignore_acceptable"' do
Expand Down

0 comments on commit 9f91860

Please sign in to comment.