Skip to content

Commit

Permalink
Merge pull request #1139 from stephannv/master
Browse files Browse the repository at this point in the history
Add  `CountAsOne` config option to `RSpec/ExampleLength`
  • Loading branch information
bquorning committed Apr 14, 2021
2 parents b375a8f + 368aecb commit 098bd42
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,8 @@
* Allow `RSpec/ContextWording` to accept multi-word prefixes. ([@hosamaly][])
* Drop support for ruby 2.4. ([@bquorning][])

* Add `CountAsOne` configuration option to `RSpec/ExampleLength`. ([@stephannv][])

## 2.2.0 (2021-02-02)

* Fix `HooksBeforeExamples`, `LeadingSubject`, `LetBeforeExamples` and `ScatteredLet` autocorrection to take into account inline comments and comments immediately before the moved node. ([@Darhazer][])
Expand Down Expand Up @@ -607,3 +609,4 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
[@ahukkanen]: https://github.com/ahukkanen
[@dvandersluis]: https://github.com/dvandersluis
[@hosamaly]: https://github.com/hosamaly
[@stephannv]: https://github.com/stephannv
2 changes: 2 additions & 0 deletions config/default.yml
Expand Up @@ -253,7 +253,9 @@ RSpec/ExampleLength:
Description: Checks for long examples.
Enabled: true
Max: 5
CountAsOne: []
VersionAdded: '1.5'
VersionChanged: '2.3'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleLength

RSpec/ExampleWithoutDescription:
Expand Down
31 changes: 30 additions & 1 deletion docs/modules/ROOT/pages/cops_rspec.adoc
Expand Up @@ -1051,7 +1051,7 @@ let(:foo) { bar }
| Yes
| No
| 1.5
| -
| 2.3
|===

Checks for long examples.
Expand All @@ -1060,6 +1060,10 @@ A long example is usually more difficult to understand. Consider
extracting out some behaviour, e.g. with a `let` block, or a helper
method.

You can set literals you want to fold with `CountAsOne`.
Available are: 'array', 'hash', and 'heredoc'. Each literal
will be counted as one line regardless of its actual size.

=== Examples

[source,ruby]
Expand All @@ -1081,6 +1085,27 @@ it do
end
----

==== CountAsOne: ['array', 'heredoc']

[source,ruby]
----
it do
array = [ # +1
1,
2
]
hash = { # +3
key: 'value'
}
msg = <<~HEREDOC # +1
Heredoc
content.
HEREDOC
end # 5 points
----

=== Configurable attributes

|===
Expand All @@ -1089,6 +1114,10 @@ end
| Max
| `5`
| Integer

| CountAsOne
| `[]`
| Array
|===

=== References
Expand Down
38 changes: 26 additions & 12 deletions lib/rubocop/cop/rspec/example_length.rb
Expand Up @@ -25,29 +25,43 @@ module RSpec
# result = service.call
# expect(result).to be(true)
# end
#
# You can set literals you want to fold with `CountAsOne`.
# Available are: 'array', 'hash', and 'heredoc'. Each literal
# will be counted as one line regardless of its actual size.
#
# @example CountAsOne: ['array', 'heredoc']
#
# it do
# array = [ # +1
# 1,
# 2
# ]
#
# hash = { # +3
# key: 'value'
# }
#
# msg = <<~HEREDOC # +1
# Heredoc
# content.
# HEREDOC
# end # 5 points
class ExampleLength < Base
include CodeLength

MSG = 'Example has too many lines [%<total>d/%<max>d].'
LABEL = 'Example'

def on_block(node)
return unless example?(node)

length = code_length(node)

return unless length > max_length

add_offense(node, message: message(length))
check_code_length(node)
end

private

def code_length(node)
node.source.lines[1..-2].count { |line| !irrelevant_line(line) }
end

def message(length)
format(MSG, total: length, max: max_length)
def cop_label
LABEL
end
end
end
Expand Down
26 changes: 24 additions & 2 deletions spec/rubocop/cop/rspec/example_length_spec.rb
Expand Up @@ -46,7 +46,7 @@
it 'flags the example' do
expect_offense(<<-RUBY)
it do
^^^^^ Example has too many lines [4/3].
^^^^^ Example has too many lines. [4/3]
line 1
line 2
line 3
Expand All @@ -64,7 +64,7 @@
it 'flags the example' do
expect_offense(<<-RUBY)
it do
^^^^^ Example has too many lines [4/3].
^^^^^ Example has too many lines. [4/3]
line 1
line 2
# comment
Expand All @@ -73,4 +73,26 @@
RUBY
end
end

context 'when `CountAsOne` is not empty' do
before { cop_config['CountAsOne'] = ['array'] }

it 'folds array into one line' do
expect_no_offenses(<<~RUBY)
it do
a = 1
a = [
2,
3,
4,
5,
6,
7,
8,
9
]
end
RUBY
end
end
end

0 comments on commit 098bd42

Please sign in to comment.