Skip to content

Commit

Permalink
[Fix rubocop#1770] Add more acceptable methods to Rails/TimeZone.
Browse files Browse the repository at this point in the history
  • Loading branch information
palkan committed Apr 19, 2015
1 parent ad72874 commit 2df9ffe
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* [#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][])
* [#1806](https://github.com/bbatsov/rubocop/issues/1806): Require a newer version of `parser` and use its corrected solution for comment association in `Style/Documentation`. ([@jonas054][])
* [#1767](https://github.com/bbatsov/rubocop/pull/1767): Add more acceptable methods to `Rails/TimeZone` (`utc`, `localtime`, `to_i`, `iso8601` etc). ([@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
29 changes: 24 additions & 5 deletions lib/rubocop/cop/rails/time_zone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@ 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]

ACCEPTED_METHODS = [:in_time_zone, :utc,
:iso8601, :jisx0301, :rfc3339,
:to_i, :to_f]

def on_const(node)
_module, klass = *node

Expand All @@ -50,6 +56,9 @@ def check_time_node(klass, node)
return if (chain & DANGER_METHODS).empty? ||
!(chain & good_methods).empty?

return check_localtime(node) if (style == :acceptable) &&
chain.include?(:localtime)

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

Expand All @@ -62,10 +71,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 +104,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] : [:zone] + ACCEPTED_METHODS
end
end
end
Expand Down
47 changes: 38 additions & 9 deletions spec/rubocop/cop/rails/time_zone_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@
expect(cop.offenses.size).to eq(1)
end

it "registers an offense for #{klass}.now.in_time_zone" do
inspect_source(cop, "#{klass}.now.in_time_zone")
expect(cop.offenses.size).to eq(1)
end

it "registers an offense for #{klass}.new without argument" do
inspect_source(cop, "#{klass}.new")
expect(cop.offenses.size).to eq(1)
Expand All @@ -30,6 +25,13 @@
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.first.message).to include('Time.zone.local')
end

described_class::ACCEPTED_METHODS.each do |amethod|
it "registers an offense #{klass}.now.#{amethod}" do
inspect_source(cop, "#{klass}.now.#{amethod}")
expect(cop.offenses.size).to eq(1)
end
end
end

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

it 'registers an offense for Time.parse.localtime(offset)' do
inspect_source(cop, "Time.parse('12:00').localtime('+03:00')")
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 'accepts Time.zone.now' do
inspect_source(cop, 'Time.zone.now')
expect(cop.offenses).to be_empty
Expand Down Expand Up @@ -113,15 +125,27 @@
)
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

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

context 'when EnforcedStyle is "ignore_acceptable"' do
context 'when EnforcedStyle is "acceptable"' do
let(:cop_config) { { 'EnforcedStyle' => 'acceptable' } }

described_class::TIMECLASS.each do |klass|
it "accepts #{klass}.now.in_time_zone" do
inspect_source(cop, "#{klass}.now.in_time_zone")
expect(cop.offenses).to be_empty
described_class::ACCEPTED_METHODS.each do |amethod|
it "accepts #{klass}.now.#{amethod}" do
inspect_source(cop, "#{klass}.now.#{amethod}")
expect(cop.offenses).to be_empty
end
end
end

Expand All @@ -132,5 +156,10 @@
)
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
end
end

0 comments on commit 2df9ffe

Please sign in to comment.