Skip to content

Commit

Permalink
Implement auto-correct for ScatteredLet cop
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxim Krizhanovski committed Apr 28, 2020
1 parent 6d87a0f commit 1d9615b
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,7 @@
* Add new `Capybara/VisibilityMatcher` cop. ([@aried3r][])
* Ignore String constants by `RSpec/Describe`. ([@AlexWayfer][])
* Drop support for ruby 2.3. ([@bquorning][])
* Add autocorrect support for `RSpec/ScatteredLet`. ([@Darhazer][])

## 1.38.1 (2020-02-15)

Expand Down
1 change: 1 addition & 0 deletions config/default.yml
Expand Up @@ -416,6 +416,7 @@ RSpec/ScatteredLet:
Description: Checks for let scattered across the example group.
Enabled: true
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredLet
VersionChanged: '1.39'

RSpec/ScatteredSetup:
Description: Checks for setup scattered across multiple hooks in an example group.
Expand Down
13 changes: 13 additions & 0 deletions lib/rubocop/cop/rspec/scattered_let.rb
Expand Up @@ -35,6 +35,15 @@ def on_block(node)
check_let_declarations(node.body)
end

def autocorrect(node)
lambda do |corrector|
first_let = find_first_let(node.parent)
RuboCop::RSpec::Corrector::MoveNode.new(
node, corrector, processed_source
).move_after(first_let)
end
end

private

def check_let_declarations(body)
Expand All @@ -47,6 +56,10 @@ def check_let_declarations(body)
add_offense(node)
end
end

def find_first_let(node)
node.children.find { |child| let?(child) }
end
end
end
end
Expand Down
8 changes: 7 additions & 1 deletion manual/cops_rspec.md
Expand Up @@ -2723,7 +2723,7 @@ EnforcedStyle | `and_return` | `and_return`, `block`

Enabled by default | Supports autocorrection
--- | ---
Enabled | No
Enabled | Yes

Checks for let scattered across the example group.

Expand Down Expand Up @@ -2751,6 +2751,12 @@ describe Foo do
end
```

### Configurable attributes

Name | Default value | Configurable values
--- | --- | ---
VersionChanged | `1.39` | String

### References

* [https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredLet](https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredLet)
Expand Down
70 changes: 70 additions & 0 deletions spec/rubocop/cop/rspec/scattered_let_spec.rb
Expand Up @@ -12,6 +12,76 @@
^^^^^^^^^^^^^ Group all let/let! blocks in the example group together.
end
RUBY

expect_correction(<<-RUBY)
RSpec.describe User do
let(:a) { a }
let(:b) { b }
subject { User }
end
RUBY
end

it 'works with heredocs' do
expect_offense(<<-RUBY)
RSpec.describe User do
let(:a) { <<-BAR }
hello
world
BAR
subject { User }
let(:b) { <<-BAZ }
^^^^^^^^^^^^^^^^^^ Group all let/let! blocks in the example group together.
again
BAZ
end
RUBY

expect_correction(<<-RUBY)
RSpec.describe User do
let(:a) { <<-BAR }
hello
world
BAR
let(:b) { <<-BAZ }
again
BAZ
subject { User }
end
RUBY
end

it 'flags `let` at different nesting levels' do
expect_offense(<<-RUBY)
RSpec.describe User do
let(:a) { a }
subject { User }
describe '#property' do
let(:c) { c }
it { expect(subject.property).to eq c }
let(:d) { d }
^^^^^^^^^^^^^ Group all let/let! blocks in the example group together.
end
end
RUBY

expect_correction(<<-RUBY)
RSpec.describe User do
let(:a) { a }
subject { User }
describe '#property' do
let(:c) { c }
let(:d) { d }
it { expect(subject.property).to eq c }
end
end
RUBY
end

it 'doesnt flag `let!` in the middle of multiple `let`s' do
Expand Down

0 comments on commit 1d9615b

Please sign in to comment.