Skip to content

Commit

Permalink
Add new RSpec/UndescriptiveLiterals cop
Browse files Browse the repository at this point in the history
Fix: #1754
  • Loading branch information
ydah committed Feb 16, 2024
1 parent c53802d commit 895c908
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ RSpec/ClassCheck:
Enabled: true
RSpec/ContainExactly:
Enabled: true
RSpec/UndescriptiveLiteralsDescription:
Enabled: true
RSpec/DuplicatedMetadata:
Enabled: true
RSpec/EmptyMetadata:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Master (Unreleased)

- Add support for `assert_true` and `assert_false` to `RSpec/Rails/MinitestAssertions`. ([@ydah])
- Add new `RSpec/UndescriptiveLiteralsDescription` cop. ([@ydah])
- Support asserts with messages in `Rspec/BeEmpty`. ([@G-Rath])
- Add support for `assert_empty`, `assert_not_empty` and `refute_empty` to `RSpec/Rails/MinitestAssertions`. ([@ydah])
- Support correcting some `*_predicate` assertions in `RSpec/Rails/MinitestAssertions`. ([@G-Rath])
Expand Down
6 changes: 6 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,12 @@ RSpec/SubjectStub:
StyleGuide: https://rspec.rubystyle.guide/#dont-stub-subject
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SubjectStub

RSpec/UndescriptiveLiteralsDescription:
Description: Description should be descriptive.
Enabled: pending
VersionAdded: "<<next>>"
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/UndescriptiveLiteralsDescription

RSpec/UnspecifiedException:
Description: Checks for a specified error in checking raised errors.
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/pages/cops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
* xref:cops_rspec.adoc#rspecstubbedmock[RSpec/StubbedMock]
* xref:cops_rspec.adoc#rspecsubjectdeclaration[RSpec/SubjectDeclaration]
* xref:cops_rspec.adoc#rspecsubjectstub[RSpec/SubjectStub]
* xref:cops_rspec.adoc#rspecundescriptiveliteralsdescription[RSpec/UndescriptiveLiteralsDescription]
* xref:cops_rspec.adoc#rspecunspecifiedexception[RSpec/UnspecifiedException]
* xref:cops_rspec.adoc#rspecvariabledefinition[RSpec/VariableDefinition]
* xref:cops_rspec.adoc#rspecvariablename[RSpec/VariableName]
Expand Down
61 changes: 61 additions & 0 deletions docs/modules/ROOT/pages/cops_rspec.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5530,6 +5530,67 @@ end
* https://robots.thoughtbot.com/don-t-stub-the-system-under-test
* https://penelope.zone/2015/12/27/introducing-rspec-smells-and-where-to-find-them.html#smell-1-stubjec
== RSpec/UndescriptiveLiteralsDescription
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Pending
| Yes
| No
| <<next>>
| -
|===
Description should be descriptive.
If `example group` or `example` contains only `execute string`, numbers,
and regular expressions, the description is not clear.
=== Examples
[source,ruby]
----
# bad
describe `time` do
# ...
end
# bad
context /when foo/ do
# ...
end
# bad
it 10000 do
# ...
end
# good
describe Foo do
# ...
end
# good
describe '#foo' do
# ...
end
# good
context "when #{foo} is bar" do
# ...
end
# good
it 'does something' do
# ...
end
----
=== References
* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/UndescriptiveLiteralsDescription
== RSpec/UnspecifiedException
|===
Expand Down
73 changes: 73 additions & 0 deletions lib/rubocop/cop/rspec/undescriptive_literals_description.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

module RuboCop
module Cop
module RSpec
# Description should be descriptive.
#
# If `example group` or `example` contains only `execute string`, numbers,
# and regular expressions, the description is not clear.
#
# @example
# # bad
# describe `time` do
# # ...
# end
#
# # bad
# context /when foo/ do
# # ...
# end
#
# # bad
# it 10000 do
# # ...
# end
#
# # good
# describe Foo do
# # ...
# end
#
# # good
# describe '#foo' do
# # ...
# end
#
# # good
# context "when #{foo} is bar" do
# # ...
# end
#
# # good
# it 'does something' do
# # ...
# end
#
class UndescriptiveLiteralsDescription < Base
MSG = 'Description should be descriptive.'

# @!method example_groups_or_example?(node)
def_node_matcher :example_groups_or_example?, <<~PATTERN
(block (send #rspec? {#ExampleGroups.all #Examples.all} $_) ...)
PATTERN

def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
example_groups_or_example?(node) do |arg|
add_offense(arg) if offense?(arg)
end
end

private

def offense?(node)
if node.send_type?
node.child_nodes.all? { |child| offense?(child) }
else
node.xstr_type? || node.int_type? || node.regexp_type?
end
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/rspec_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
require_relative 'rspec/stubbed_mock'
require_relative 'rspec/subject_declaration'
require_relative 'rspec/subject_stub'
require_relative 'rspec/undescriptive_literals_description'
require_relative 'rspec/unspecified_exception'
require_relative 'rspec/variable_definition'
require_relative 'rspec/variable_name'
Expand Down
97 changes: 97 additions & 0 deletions spec/rubocop/cop/rspec/undescriptive_literals_description_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::UndescriptiveLiteralsDescription, :config do
it 'registers an offense when using `describe` with only execute string' do
expect_offense(<<~RUBY)
describe `time` do
^^^^^^ Description should be descriptive.
end
RUBY
end

it 'registers an offense when using `context` with only execute string' do
expect_offense(<<~RUBY)
context `time` do
^^^^^^ Description should be descriptive.
end
RUBY
end

it 'registers an offense when using `it` with only execute string' do
expect_offense(<<~RUBY)
it `time` do
^^^^^^ Description should be descriptive.
end
RUBY
end

it 'registers an offense when using `describe` with only regex' do
expect_offense(<<~RUBY)
describe /time/ do
^^^^^^ Description should be descriptive.
end
RUBY
end

it 'registers an offense when using `describe` with only Integer' do
expect_offense(<<~RUBY)
describe 10000 do
^^^^^ Description should be descriptive.
end
RUBY
end

it 'does not register an offense when using `describe` with a string' do
expect_no_offenses(<<~RUBY)
describe '#foo' do
end
RUBY
end

it 'does not register an offense when using `describe` with a class' do
expect_no_offenses(<<~RUBY)
describe Foo do
end
RUBY
end

it 'does not register an offense when using `context` with a string' do
expect_no_offenses(<<~RUBY)
context 'when foo is bar' do
end
RUBY
end

it 'does not register an offense when using `it` with a string' do
expect_no_offenses(<<~RUBY)
it 'does something' do
end
RUBY
end

it 'does not register an offense when using `describe` with an ' \
'interpolation string' do
expect_no_offenses(<<~RUBY)
describe "foo \#{bar}" do
end
RUBY
end

it 'does not register an offense when using `describe` with a ' \
'heredoc string' do
expect_no_offenses(<<~RUBY)
describe <<~DESC do
foo
DESC
end
RUBY
end

it 'does not register an offense when using `describe` with a string and ' \
'execute string' do
expect_no_offenses(<<~RUBY)
describe 'foo' + `time` do
end
RUBY
end
end

0 comments on commit 895c908

Please sign in to comment.