Skip to content

Commit

Permalink
[Fix rubocop#8347] HashSyntax plus HashAlignment breaks the page
Browse files Browse the repository at this point in the history
Combining an autocorrect with HashAlignment with one turning hashes into `hash_rocket` syntax would leave the code in a syntax error.
  • Loading branch information
Daniel Orner committed Jul 16, 2020
1 parent a45042b commit 9ff222d
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

## master (unreleased)

* [#8347](https://github.com/rubocop-hq/rubocop/issues/8347): Fix creating syntax errors when combining `Layout/HashAlignment` with `Style/HashSyntax` set to `hash_rockets`. ([@dorner][])

### Bug fixes

* [#8324](https://github.com/rubocop-hq/rubocop/issues/8324): Fix crash for `Layout/SpaceAroundMethodCallOperator` when using `Proc#call` shorthand syntax. ([@fatkodima][])
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/hash_syntax.rb
Expand Up @@ -199,7 +199,7 @@ def argument_without_space?(node)
def autocorrect_hash_rockets(corrector, pair_node)
op = pair_node.loc.operator

corrector.wrap(pair_node.key, ':', pair_node.inverse_delimiter(true))
corrector.replace(pair_node.key, ":#{pair_node.key.source}#{pair_node.inverse_delimiter(true)}")
corrector.remove(range_with_surrounding_space(range: op))
end

Expand Down
6 changes: 4 additions & 2 deletions lib/rubocop/rspec/cop_helper.rb
Expand Up @@ -46,10 +46,12 @@ def autocorrect_source(source, file = nil)
@last_corrector.rewrite
end

def _investigate(cop, processed_source)
team = RuboCop::Cop::Team.new([cop], nil, raise_error: true)
def _investigate(cops, processed_source)
cop_array = Array(cops)
team = RuboCop::Cop::Team.new(cop_array, nil, raise_error: true)
report = team.investigate(processed_source)
@last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source)
report.correctors[1..-1].each { |corr| @last_corrector.merge!(corr) if corr }
report.offenses
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/rspec/expect_offense.rb
Expand Up @@ -130,7 +130,7 @@ def expect_offense(source, file = nil, severity: nil, **replacements)

raise 'Error parsing example code' unless @processed_source.valid_syntax?

offenses = _investigate(cop, @processed_source)
offenses = _investigate(run_first_cops + [cop], @processed_source)
actual_annotations =
expected_annotations.with_offense_annotations(offenses)

Expand Down Expand Up @@ -158,7 +158,7 @@ def expect_correction(correction, loop: true)
# Prepare for next loop
@processed_source = parse_source(corrected_source,
@processed_source.path)
_investigate(cop, @processed_source)
_investigate(run_first_cops + [cop], @processed_source)
end

expect(new_source).to eq(correction)
Expand Down
20 changes: 20 additions & 0 deletions lib/rubocop/rspec/shared_contexts.rb
Expand Up @@ -58,6 +58,8 @@

let(:other_cops) { {} }

let(:run_first) { [] }

let(:cop_options) { {} }

### Utilities
Expand Down Expand Up @@ -92,6 +94,15 @@ def source_range(range, buffer: source_buffer)
let(:config) do
hash = { 'AllCops' => all_cops_config,
cop_class.cop_name => cur_cop_config }.merge!(other_cops)
run_first.each do |run_first_cop|
run_first_cop_config = RuboCop::ConfigLoader
.default_configuration.for_cop(run_first_cop)
.merge({
'Enabled' => true, # in case it is 'pending'
'AutoCorrect' => true # in case defaults set it to false
}).merge(other_cops[run_first_cop.badge.to_s] || {})
hash.merge!(run_first_cop.badge.to_s => run_first_cop_config)
end

RuboCop::Config.new(hash, "#{Dir.pwd}/.rubocop.yml")
end
Expand All @@ -101,6 +112,15 @@ def source_range(range, buffer: source_buffer)
cop.send :begin_investigation, processed_source
end
end

let(:run_first_cops) do
run_first.map do |cop_class|
cop_class.new(config, cop_options).tap do |cop|
cop.send :begin_investigation, processed_source
end
end
end

end

RSpec.shared_context 'mock console output' do
Expand Down
32 changes: 32 additions & 0 deletions spec/rubocop/cop/style/hash_syntax_spec.rb
Expand Up @@ -24,6 +24,15 @@

let(:cop_config_overrides) { {} }

let(:other_cops) do
{
'Layout/HashAlignment' => {
'EnforcedHashRocketStyle' => 'key',
'EnforcedColonStyle' => 'key'
}
}
end

it 'registers offense for hash rocket syntax when new is possible' do
expect_offense(<<~RUBY)
x = { :a => 0 }
Expand Down Expand Up @@ -331,6 +340,28 @@
it 'does not register an offense when there is a symbol value' do
expect_no_offenses('{ :a => :b, :c => :d }')
end

context 'with Layout/HashAlignment' do
let(:run_first) { [RuboCop::Cop::Layout::HashAlignment] }
it 'should not conflict' do
expect_offense(<<~RUBY)
some_method(a: 'abc', b: 'abc',
^^ Use hash rockets syntax.
^^ Use hash rockets syntax.
c: 'abc', d: 'abc'
^^ Use hash rockets syntax.
^^ Use hash rockets syntax.
^^^^^^^^ Align the keys of a hash literal if they span more than one line.
)
RUBY

expect_correction(<<~RUBY)
some_method(:a => 'abc', :b => 'abc',
:c => 'abc', :d => 'abc'
)
RUBY
end
end
end
end

Expand Down Expand Up @@ -650,4 +681,5 @@
expect(new_source).to eq('{ :a => 1, "b" => 2 }')
end
end

end

0 comments on commit 9ff222d

Please sign in to comment.