Skip to content

Commit

Permalink
Support EnforcedStyleForEmptyBraces for SpaceBeforeBlockBraces cop
Browse files Browse the repository at this point in the history
  • Loading branch information
palkan committed Aug 25, 2017
1 parent 5ced1c5 commit f594f4d
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

### New features

* [#4464](https://github.com/bbatsov/rubocop/pull/4464): Add `EnforcedStyleForEmptyBraces` parameter to `Layout/SpaceBeforeBlockBraces` cop. ([@palkan][])
* [#4453](https://github.com/bbatsov/rubocop/pull/4453): New cop `Style/RedundantConditional` checks for conditionals that return true/false. ([@petehamilton][])
* [#4448](https://github.com/bbatsov/rubocop/pull/4448): Add new `TapFormatter`. ([@cyberdelia][])
* Add new `Style/HeredocDelimiters` cop. ([@drenmi][])
Expand Down
3 changes: 3 additions & 0 deletions config/default.yml
Expand Up @@ -490,6 +490,9 @@ Layout/SpaceBeforeBlockBraces:
SupportedStyles:
- space
- no_space
SupportedStylesForEmptyBraces:
- space
- no_space

Layout/SpaceBeforeFirstArg:
# When `true`, allows most uses of extra spacing if the intent is to align
Expand Down
48 changes: 43 additions & 5 deletions lib/rubocop/cop/layout/space_before_block_braces.rb
Expand Up @@ -19,6 +19,9 @@ module Layout
class SpaceBeforeBlockBraces < Cop
include ConfigurableEnforcedStyle

MISSING_MSG = 'Space missing to the left of {.'.freeze
DETECTED_MSG = 'Space detected to the left of {.'.freeze

def self.autocorrect_incompatible_with
[Style::SymbolProc]
end
Expand All @@ -31,30 +34,61 @@ def on_block(node)
used_style =
space_plus_brace.source.start_with?('{') ? :no_space : :space

if empty_braces?(node.loc)
check_empty(left_brace, space_plus_brace, used_style)
else
check_non_empty(left_brace, space_plus_brace, used_style)
end
end

private

def check_empty(left_brace, space_plus_brace, used_style)
return if style_for_empty_braces == used_style

config_to_allow_offenses['EnforcedStyleForEmptyBraces'] =
used_style.to_s

if style_for_empty_braces == :space
add_offense(left_brace, left_brace, MISSING_MSG)
else
space = range_between(space_plus_brace.begin_pos,
left_brace.begin_pos)
add_offense(space, space, DETECTED_MSG)
end
end

def check_non_empty(left_brace, space_plus_brace, used_style)
case used_style
when style then correct_style_detected
when :space then space_detected(left_brace, space_plus_brace)
else space_missing(left_brace)
end
end

private

def space_missing(left_brace)
add_offense(left_brace, left_brace,
'Space missing to the left of {.') do
add_offense(left_brace, left_brace, MISSING_MSG) do
opposite_style_detected
end
end

def space_detected(left_brace, space_plus_brace)
space = range_between(space_plus_brace.begin_pos,
left_brace.begin_pos)
add_offense(space, space, 'Space detected to the left of {.') do
add_offense(space, space, DETECTED_MSG) do
opposite_style_detected
end
end

def style_for_empty_braces
case cop_config['EnforcedStyleForEmptyBraces']
when 'space' then :space
when 'no_space' then :no_space
when nil then style
else raise 'Unknown EnforcedStyleForEmptyBraces selected!'
end
end

def autocorrect(range)
lambda do |corrector|
case range.source
Expand All @@ -63,6 +97,10 @@ def autocorrect(range)
end
end
end

def empty_braces?(loc)
loc.begin.end_pos == loc.end.begin_pos
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions manual/cops_layout.md
Expand Up @@ -2062,6 +2062,7 @@ Attribute | Value
--- | ---
EnforcedStyle | space
SupportedStyles | space, no_space
SupportedStylesForEmptyBraces | space, no_space
## Layout/SpaceBeforeComma
Expand Down
61 changes: 61 additions & 0 deletions spec/rubocop/cop/layout/space_before_block_braces_spec.rb
Expand Up @@ -71,4 +71,65 @@
expect_no_offenses('each{ puts }')
end
end

context 'with space before empty braces not allowed' do
let(:cop_config) do
{
'EnforcedStyle' => 'space',
'EnforcedStyleForEmptyBraces' => 'no_space'
}
end

it 'accepts empty braces without outer space' do
expect_no_offenses('->{}')
end

it 'registers an offense for empty braces' do
inspect_source('-> {}')
expect(cop.messages).to eq(['Space detected to the left of {.'])
expect(cop.highlights).to eq([' '])
expect(cop.config_to_allow_offenses)
.to eq('EnforcedStyleForEmptyBraces' => 'space')
end

it 'auto-corrects unwanted space' do
new_source = autocorrect_source('-> {}')
expect(new_source).to eq('->{}')
end
end

context 'with space before empty braces allowed' do
let(:cop_config) do
{
'EnforcedStyle' => 'no_space',
'EnforcedStyleForEmptyBraces' => 'space'
}
end

it 'accepts empty braces with outer space' do
expect_no_offenses('-> {}')
end

it 'registers an offense for empty braces' do
inspect_source('->{}')
expect(cop.messages).to eq(['Space missing to the left of {.'])
expect(cop.highlights).to eq(['{'])
expect(cop.config_to_allow_offenses)
.to eq('EnforcedStyleForEmptyBraces' => 'no_space')
end

it 'auto-corrects missing space' do
new_source = autocorrect_source('->{}')
expect(new_source).to eq('-> {}')
end
end

context 'with invalid value for EnforcedStyleForEmptyBraces' do
let(:cop_config) { { 'EnforcedStyleForEmptyBraces' => 'unknown' } }

it 'fails with an error' do
expect { inspect_source('each {}') }
.to raise_error('Unknown EnforcedStyleForEmptyBraces selected!')
end
end
end

0 comments on commit f594f4d

Please sign in to comment.