rubocop-rspec 1.42.0 → 1.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/config/default.yml +12 -2
- data/lib/rubocop-rspec.rb +2 -1
- data/lib/rubocop/cop/rspec/align_left_let_brace.rb +1 -1
- data/lib/rubocop/cop/rspec/align_right_let_brace.rb +1 -1
- data/lib/rubocop/cop/rspec/any_instance.rb +1 -1
- data/lib/rubocop/cop/rspec/around_block.rb +1 -1
- data/lib/rubocop/cop/rspec/base.rb +74 -0
- data/lib/rubocop/cop/rspec/be.rb +1 -1
- data/lib/rubocop/cop/rspec/be_eql.rb +1 -1
- data/lib/rubocop/cop/rspec/before_after_all.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +6 -3
- data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +1 -1
- data/lib/rubocop/cop/rspec/context_method.rb +2 -2
- data/lib/rubocop/cop/rspec/context_wording.rb +3 -3
- data/lib/rubocop/cop/rspec/cop.rb +2 -66
- data/lib/rubocop/cop/rspec/describe_class.rb +21 -30
- data/lib/rubocop/cop/rspec/describe_method.rb +14 -6
- data/lib/rubocop/cop/rspec/describe_symbol.rb +2 -2
- data/lib/rubocop/cop/rspec/described_class.rb +2 -2
- data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -1
- data/lib/rubocop/cop/rspec/dialect.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_example_group.rb +91 -7
- data/lib/rubocop/cop/rspec/empty_hook.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +4 -8
- data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +4 -8
- data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +7 -10
- data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +4 -8
- data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +5 -8
- data/lib/rubocop/cop/rspec/example_length.rb +1 -1
- data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
- data/lib/rubocop/cop/rspec/example_wording.rb +4 -4
- data/lib/rubocop/cop/rspec/expect_actual.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_change.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_in_hook.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_output.rb +1 -1
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +3 -3
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +10 -6
- data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -1
- data/lib/rubocop/cop/rspec/file_path.rb +25 -17
- data/lib/rubocop/cop/rspec/focus.rb +7 -11
- data/lib/rubocop/cop/rspec/hook_argument.rb +5 -6
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +1 -1
- data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -1
- data/lib/rubocop/cop/rspec/implicit_subject.rb +8 -6
- data/lib/rubocop/cop/rspec/instance_spy.rb +1 -1
- data/lib/rubocop/cop/rspec/instance_variable.rb +1 -1
- data/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb +1 -1
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +1 -1
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/leading_subject.rb +20 -17
- data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +1 -1
- data/lib/rubocop/cop/rspec/let_before_examples.rb +1 -1
- data/lib/rubocop/cop/rspec/let_setup.rb +6 -3
- data/lib/rubocop/cop/rspec/message_chain.rb +1 -1
- data/lib/rubocop/cop/rspec/message_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/message_spies.rb +1 -1
- data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +1 -1
- data/lib/rubocop/cop/rspec/multiple_describes.rb +11 -8
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +7 -11
- data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +148 -0
- data/lib/rubocop/cop/rspec/multiple_subjects.rb +1 -1
- data/lib/rubocop/cop/rspec/named_subject.rb +1 -1
- data/lib/rubocop/cop/rspec/nested_groups.rb +4 -4
- data/lib/rubocop/cop/rspec/not_to_not.rb +1 -1
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/pending.rb +1 -1
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +7 -14
- data/lib/rubocop/cop/rspec/rails/http_status.rb +1 -1
- data/lib/rubocop/cop/rspec/receive_counts.rb +1 -1
- data/lib/rubocop/cop/rspec/receive_never.rb +2 -2
- data/lib/rubocop/cop/rspec/repeated_description.rb +1 -1
- data/lib/rubocop/cop/rspec/repeated_example.rb +2 -2
- data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +1 -1
- data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +1 -1
- data/lib/rubocop/cop/rspec/return_from_stub.rb +1 -1
- data/lib/rubocop/cop/rspec/scattered_let.rb +1 -1
- data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/shared_context.rb +1 -1
- data/lib/rubocop/cop/rspec/shared_examples.rb +1 -1
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +1 -1
- data/lib/rubocop/cop/rspec/subject_stub.rb +2 -2
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -1
- data/lib/rubocop/cop/rspec/variable_definition.rb +6 -6
- data/lib/rubocop/cop/rspec/variable_name.rb +28 -9
- data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
- data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
- data/lib/rubocop/cop/rspec/yield.rb +1 -1
- data/lib/rubocop/cop/rspec_cops.rb +1 -0
- data/lib/rubocop/rspec/corrector/move_node.rb +7 -5
- data/lib/rubocop/rspec/description_extractor.rb +1 -1
- data/lib/rubocop/rspec/{blank_line_separation.rb → empty_line_separation.rb} +13 -2
- data/lib/rubocop/rspec/example_group.rb +2 -2
- data/lib/rubocop/rspec/language.rb +6 -4
- data/lib/rubocop/rspec/language/node_pattern.rb +6 -1
- data/lib/rubocop/rspec/top_level_describe.rb +2 -2
- data/lib/rubocop/rspec/top_level_group.rb +24 -13
- data/lib/rubocop/rspec/variable.rb +1 -1
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +23 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afae94ff975b0caf19f7aa7cad514296a15cb28afc2c4ae18dba8bb8446290d2
|
4
|
+
data.tar.gz: 15fa2c9138a72d6c54247ea384793abbf9c3d6f8eaa2d7346803c8a296b7335c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4552fb307a57b49ed209ac12a30744b97cfd5bc57460a2a385a16a176903f439083a634e92a8f4faf308c3cca570a79bc8ba85b8a51ceff295920614f1bfe95b
|
7
|
+
data.tar.gz: f6b9ed4c0d486fb41c477f6b9d95b7a8897b2011f80bc91edd1a872dca11fce0e5de05387f5e0a3112a0849f371fa93c1eba220019ff5b81ba9959daf06e089c
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,19 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 1.43.0 (2020-08-17)
|
6
|
+
|
7
|
+
* Add a new base cop class `::RuboCop::Cop::RSpec::Base`. The old base class `::RuboCop::Cop::RSpec::Cop` is deprecated, and will be removed in the next major release. ([@bquorning][])
|
8
|
+
* Add support for subject detection after includes and example groups in `RSpec/LeadingSubject`. ([@pirj][])
|
9
|
+
* Ignore trailing punctuation in context description prefix. ([@elliterate][])
|
10
|
+
* Relax `RSpec/VariableDefinition` cop so interpolated and multiline strings are accepted even when configured to enforce the `symbol` style. ([@bquorning][])
|
11
|
+
* Fix `RSpec/EmptyExampleGroup` to flag example groups with examples in invalid scopes. ([@mlarraz][])
|
12
|
+
* Fix `RSpec/EmptyExampleGroup` to ignore examples groups with examples defined inside iterators. ([@pirj][])
|
13
|
+
* Improve `RSpec/NestedGroups`, `RSpec/FilePath`, `RSpec/DescribeMethod`, `RSpec/MultipleDescribes`, `RSpec/DescribeClass`'s top-level example group detection. ([@pirj][])
|
14
|
+
* Add detection of `let!` with a block-pass or a string literal to `RSpec/LetSetup`. ([@pirj][])
|
15
|
+
* Add `IgnoredPatterns` configuration option to `RSpec/VariableName`. ([@jtannas][])
|
16
|
+
* Add `RSpec/MultipleMemoizedHelpers` cop. ([@mockdeep][])
|
17
|
+
|
5
18
|
## 1.42.0 (2020-07-09)
|
6
19
|
|
7
20
|
* Update RuboCop dependency to 0.87.0 because of changes to internal APIs. ([@bquorning][], [@Darhazer][])
|
@@ -529,3 +542,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
529
542
|
[@rolfschmidt]: https://github.com/rolfschmidt
|
530
543
|
[@andrykonchin]: https://github.com/andrykonchin
|
531
544
|
[@harrylewis]: https://github.com/harrylewis
|
545
|
+
[@elliterate]: https://github.com/elliterate
|
546
|
+
[@mlarraz]: https://github.com/mlarraz
|
547
|
+
[@jtannas]: https://github.com/jtannas
|
548
|
+
[@mockdeep]: https://github.com/mockdeep
|
data/config/default.yml
CHANGED
@@ -74,7 +74,7 @@ RSpec/ContextWording:
|
|
74
74
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ContextWording
|
75
75
|
|
76
76
|
RSpec/DescribeClass:
|
77
|
-
Description: Check that the first argument to the top
|
77
|
+
Description: Check that the first argument to the top-level describe is a constant.
|
78
78
|
Enabled: true
|
79
79
|
VersionAdded: '1.0'
|
80
80
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeClass
|
@@ -381,7 +381,7 @@ RSpec/MissingExampleGroupArgument:
|
|
381
381
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MissingExampleGroupArgument
|
382
382
|
|
383
383
|
RSpec/MultipleDescribes:
|
384
|
-
Description: Checks for multiple top
|
384
|
+
Description: Checks for multiple top-level example groups.
|
385
385
|
Enabled: true
|
386
386
|
VersionAdded: '1.0'
|
387
387
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleDescribes
|
@@ -394,6 +394,14 @@ RSpec/MultipleExpectations:
|
|
394
394
|
VersionChanged: '1.21'
|
395
395
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleExpectations
|
396
396
|
|
397
|
+
RSpec/MultipleMemoizedHelpers:
|
398
|
+
Description: Checks if example groups contain too many `let` and `subject` calls.
|
399
|
+
Enabled: true
|
400
|
+
AllowSubject: true
|
401
|
+
Max: 5
|
402
|
+
VersionAdded: '1.43'
|
403
|
+
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleMemoizedHelpers
|
404
|
+
|
397
405
|
RSpec/MultipleSubjects:
|
398
406
|
Description: Checks if an example group defines `subject` multiple times.
|
399
407
|
Enabled: true
|
@@ -558,7 +566,9 @@ RSpec/VariableName:
|
|
558
566
|
SupportedStyles:
|
559
567
|
- snake_case
|
560
568
|
- camelCase
|
569
|
+
IgnoredPatterns: []
|
561
570
|
VersionAdded: '1.40'
|
571
|
+
VersionChanged: '1.43'
|
562
572
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VariableName
|
563
573
|
|
564
574
|
RSpec/VerifiedDoubles:
|
data/lib/rubocop-rspec.rb
CHANGED
@@ -19,11 +19,12 @@ require_relative 'rubocop/rspec/example_group'
|
|
19
19
|
require_relative 'rubocop/rspec/example'
|
20
20
|
require_relative 'rubocop/rspec/hook'
|
21
21
|
require_relative 'rubocop/rspec/variable'
|
22
|
+
require_relative 'rubocop/cop/rspec/base'
|
22
23
|
require_relative 'rubocop/cop/rspec/cop'
|
23
24
|
require_relative 'rubocop/rspec/align_let_brace'
|
24
25
|
require_relative 'rubocop/rspec/factory_bot'
|
25
26
|
require_relative 'rubocop/rspec/final_end_location'
|
26
|
-
require_relative 'rubocop/rspec/
|
27
|
+
require_relative 'rubocop/rspec/empty_line_separation'
|
27
28
|
require_relative 'rubocop/rspec/corrector/move_node'
|
28
29
|
|
29
30
|
RuboCop::RSpec::Inject.defaults!
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# @abstract parent class to RSpec cops
|
7
|
+
#
|
8
|
+
# The criteria for whether rubocop-rspec analyzes a certain ruby file
|
9
|
+
# is configured via `AllCops/RSpec`. For example, if you want to
|
10
|
+
# customize your project to scan all files within a `test/` directory
|
11
|
+
# then you could add this to your configuration:
|
12
|
+
#
|
13
|
+
# @example configuring analyzed paths
|
14
|
+
# # .rubocop.yml
|
15
|
+
# # AllCops:
|
16
|
+
# # RSpec:
|
17
|
+
# # Patterns:
|
18
|
+
# # - '_test.rb$'
|
19
|
+
# # - '(?:^|/)test/'
|
20
|
+
class Base < ::RuboCop::Cop::Base
|
21
|
+
include RuboCop::RSpec::Language
|
22
|
+
include RuboCop::RSpec::Language::NodePattern
|
23
|
+
|
24
|
+
DEFAULT_CONFIGURATION =
|
25
|
+
RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec')
|
26
|
+
|
27
|
+
DEFAULT_PATTERN_RE = Regexp.union(
|
28
|
+
DEFAULT_CONFIGURATION.fetch('Patterns')
|
29
|
+
.map(&Regexp.public_method(:new))
|
30
|
+
)
|
31
|
+
|
32
|
+
# Invoke the original inherited hook so our cops are recognized
|
33
|
+
def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
|
34
|
+
RuboCop::Cop::Base.inherited(subclass)
|
35
|
+
end
|
36
|
+
|
37
|
+
def relevant_file?(file)
|
38
|
+
relevant_rubocop_rspec_file?(file) && super
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def relevant_rubocop_rspec_file?(file)
|
44
|
+
rspec_pattern.match?(file)
|
45
|
+
end
|
46
|
+
|
47
|
+
def rspec_pattern
|
48
|
+
if rspec_pattern_config?
|
49
|
+
Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new)))
|
50
|
+
else
|
51
|
+
DEFAULT_PATTERN_RE
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def all_cops_config
|
56
|
+
config
|
57
|
+
.for_all_cops
|
58
|
+
end
|
59
|
+
|
60
|
+
def rspec_pattern_config?
|
61
|
+
return unless all_cops_config.key?('RSpec')
|
62
|
+
|
63
|
+
all_cops_config.fetch('RSpec').key?('Patterns')
|
64
|
+
end
|
65
|
+
|
66
|
+
def rspec_pattern_config
|
67
|
+
all_cops_config
|
68
|
+
.fetch('RSpec', DEFAULT_CONFIGURATION)
|
69
|
+
.fetch('Patterns')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/rubocop/cop/rspec/be.rb
CHANGED
@@ -23,7 +23,7 @@ module RuboCop
|
|
23
23
|
# before(:each) { Widget.create }
|
24
24
|
# after(:each) { Widget.delete_all }
|
25
25
|
# end
|
26
|
-
class BeforeAfterAll <
|
26
|
+
class BeforeAfterAll < Base
|
27
27
|
MSG = 'Beware of using `%<hook>s` as it may cause state to leak '\
|
28
28
|
'between tests. If you are using `rspec-rails`, and '\
|
29
29
|
'`use_transactional_fixtures` is enabled, then records created '\
|
@@ -23,7 +23,7 @@ module RuboCop
|
|
23
23
|
# expect(page).to have_current_path("/callback")
|
24
24
|
# expect(page).to have_current_path(/widgets/)
|
25
25
|
#
|
26
|
-
class CurrentPathExpectation <
|
26
|
+
class CurrentPathExpectation < Base
|
27
27
|
extend AutoCorrector
|
28
28
|
|
29
29
|
MSG = 'Do not set an RSpec expectation on `current_path` in ' \
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
# # ...
|
41
41
|
# end
|
42
42
|
# end
|
43
|
-
class FeatureMethods <
|
43
|
+
class FeatureMethods < Base
|
44
44
|
extend AutoCorrector
|
45
45
|
|
46
46
|
MSG = 'Use `%<replacement>s` instead of `%<method>s`.'
|
@@ -55,15 +55,18 @@ module RuboCop
|
|
55
55
|
feature: :describe
|
56
56
|
}.freeze
|
57
57
|
|
58
|
+
def_node_matcher :capybara_speak,
|
59
|
+
SelectorSet.new(MAP.keys).node_pattern_union
|
60
|
+
|
58
61
|
def_node_matcher :spec?, <<-PATTERN
|
59
62
|
(block
|
60
|
-
(send #
|
63
|
+
(send #rspec? {:describe :feature} ...)
|
61
64
|
...)
|
62
65
|
PATTERN
|
63
66
|
|
64
67
|
def_node_matcher :feature_method, <<-PATTERN
|
65
68
|
(block
|
66
|
-
$(send #
|
69
|
+
$(send #rspec? $#capybara_speak ...)
|
67
70
|
...)
|
68
71
|
PATTERN
|
69
72
|
|
@@ -26,7 +26,7 @@ module RuboCop
|
|
26
26
|
# expect(page).to have_css('.foo', visible: :all)
|
27
27
|
# expect(page).to have_link('my link', visible: :hidden)
|
28
28
|
#
|
29
|
-
class VisibilityMatcher <
|
29
|
+
class VisibilityMatcher < Base
|
30
30
|
MSG_FALSE = 'Use `:all` or `:hidden` instead of `false`.'
|
31
31
|
MSG_TRUE = 'Use `:visible` instead of `true`.'
|
32
32
|
CAPYBARA_MATCHER_METHODS = %i[
|
@@ -23,13 +23,13 @@ module RuboCop
|
|
23
23
|
# describe '.foo_bar' do
|
24
24
|
# # ...
|
25
25
|
# end
|
26
|
-
class ContextMethod <
|
26
|
+
class ContextMethod < Base
|
27
27
|
extend AutoCorrector
|
28
28
|
|
29
29
|
MSG = 'Use `describe` for testing methods.'
|
30
30
|
|
31
31
|
def_node_matcher :context_method, <<-PATTERN
|
32
|
-
(block (send #
|
32
|
+
(block (send #rspec? :context $(str #method_name?) ...) ...)
|
33
33
|
PATTERN
|
34
34
|
|
35
35
|
def on_block(node)
|
@@ -34,11 +34,11 @@ module RuboCop
|
|
34
34
|
# context 'when the display name is not present' do
|
35
35
|
# # ...
|
36
36
|
# end
|
37
|
-
class ContextWording <
|
37
|
+
class ContextWording < Base
|
38
38
|
MSG = 'Start context description with %<prefixes>s.'
|
39
39
|
|
40
40
|
def_node_matcher :context_wording, <<-PATTERN
|
41
|
-
(block (send #
|
41
|
+
(block (send #rspec? { :context :shared_context } $(str #bad_prefix?) ...) ...)
|
42
42
|
PATTERN
|
43
43
|
|
44
44
|
def on_block(node)
|
@@ -51,7 +51,7 @@ module RuboCop
|
|
51
51
|
private
|
52
52
|
|
53
53
|
def bad_prefix?(description)
|
54
|
-
!prefixes.include?(description.split.first)
|
54
|
+
!prefixes.include?(description.split(/\b/).first)
|
55
55
|
end
|
56
56
|
|
57
57
|
def joined_prefixes
|
@@ -3,72 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module RSpec
|
6
|
-
# @
|
7
|
-
|
8
|
-
# The criteria for whether rubocop-rspec analyzes a certain ruby file
|
9
|
-
# is configured via `AllCops/RSpec`. For example, if you want to
|
10
|
-
# customize your project to scan all files within a `test/` directory
|
11
|
-
# then you could add this to your configuration:
|
12
|
-
#
|
13
|
-
# @example configuring analyzed paths
|
14
|
-
# # .rubocop.yml
|
15
|
-
# # AllCops:
|
16
|
-
# # RSpec:
|
17
|
-
# # Patterns:
|
18
|
-
# # - '_test.rb$'
|
19
|
-
# # - '(?:^|/)test/'
|
20
|
-
class Cop < ::RuboCop::Cop::Base
|
21
|
-
include RuboCop::RSpec::Language
|
22
|
-
include RuboCop::RSpec::Language::NodePattern
|
23
|
-
|
24
|
-
DEFAULT_CONFIGURATION =
|
25
|
-
RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec')
|
26
|
-
|
27
|
-
DEFAULT_PATTERN_RE = Regexp.union(
|
28
|
-
DEFAULT_CONFIGURATION.fetch('Patterns')
|
29
|
-
.map(&Regexp.public_method(:new))
|
30
|
-
)
|
31
|
-
|
32
|
-
# Invoke the original inherited hook so our cops are recognized
|
33
|
-
def self.inherited(subclass)
|
34
|
-
RuboCop::Cop::Cop.inherited(subclass)
|
35
|
-
end
|
36
|
-
|
37
|
-
def relevant_file?(file)
|
38
|
-
relevant_rubocop_rspec_file?(file) && super
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def relevant_rubocop_rspec_file?(file)
|
44
|
-
rspec_pattern =~ file
|
45
|
-
end
|
46
|
-
|
47
|
-
def rspec_pattern
|
48
|
-
if rspec_pattern_config?
|
49
|
-
Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new)))
|
50
|
-
else
|
51
|
-
DEFAULT_PATTERN_RE
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def all_cops_config
|
56
|
-
config
|
57
|
-
.for_all_cops
|
58
|
-
end
|
59
|
-
|
60
|
-
def rspec_pattern_config?
|
61
|
-
return unless all_cops_config.key?('RSpec')
|
62
|
-
|
63
|
-
all_cops_config.fetch('RSpec').key?('Patterns')
|
64
|
-
end
|
65
|
-
|
66
|
-
def rspec_pattern_config
|
67
|
-
all_cops_config
|
68
|
-
.fetch('RSpec', DEFAULT_CONFIGURATION)
|
69
|
-
.fetch('Patterns')
|
70
|
-
end
|
71
|
-
end
|
6
|
+
# @deprecated Use ::RuboCop::Cop::RSpec::Base instead
|
7
|
+
Cop = Base
|
72
8
|
end
|
73
9
|
end
|
74
10
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module RSpec
|
6
|
-
# Check that the first argument to the top
|
6
|
+
# Check that the first argument to the top-level describe is a constant.
|
7
7
|
#
|
8
8
|
# @example
|
9
9
|
# # bad
|
@@ -21,50 +21,41 @@ module RuboCop
|
|
21
21
|
#
|
22
22
|
# describe "A feature example", type: :feature do
|
23
23
|
# end
|
24
|
-
class DescribeClass <
|
25
|
-
include RuboCop::RSpec::
|
24
|
+
class DescribeClass < Base
|
25
|
+
include RuboCop::RSpec::TopLevelGroup
|
26
26
|
|
27
27
|
MSG = 'The first argument to describe should be '\
|
28
28
|
'the class or module being tested.'
|
29
29
|
|
30
|
-
def_node_matcher :valid_describe?, <<-PATTERN
|
31
|
-
{
|
32
|
-
(send #{RSPEC} :describe const ...)
|
33
|
-
(send #{RSPEC} :describe)
|
34
|
-
}
|
35
|
-
PATTERN
|
36
|
-
|
37
|
-
def_node_matcher :describe_with_rails_metadata?, <<-PATTERN
|
38
|
-
(send #{RSPEC} :describe !const ...
|
39
|
-
(hash <#rails_metadata? ...>)
|
40
|
-
)
|
41
|
-
PATTERN
|
42
|
-
|
43
30
|
def_node_matcher :rails_metadata?, <<-PATTERN
|
44
31
|
(pair
|
45
32
|
(sym :type)
|
46
|
-
(sym {
|
47
|
-
:
|
48
|
-
:routing :view :feature :system :mailbox
|
49
|
-
}
|
50
|
-
)
|
33
|
+
(sym { :channel :controller :helper :job :mailer :model :request
|
34
|
+
:routing :view :feature :system :mailbox })
|
51
35
|
)
|
52
36
|
PATTERN
|
53
37
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
38
|
+
def_node_matcher :example_group_with_rails_metadata?, <<~PATTERN
|
39
|
+
(send #rspec? :describe ... (hash <#rails_metadata? ...>))
|
40
|
+
PATTERN
|
41
|
+
|
42
|
+
def_node_matcher :not_a_const_described, <<~PATTERN
|
43
|
+
(send #rspec? :describe $[!const !#string_constant?] ...)
|
44
|
+
PATTERN
|
45
|
+
|
46
|
+
def on_top_level_group(top_level_node)
|
47
|
+
return if example_group_with_rails_metadata?(top_level_node.send_node)
|
59
48
|
|
60
|
-
|
49
|
+
not_a_const_described(top_level_node.send_node) do |described|
|
50
|
+
add_offense(described)
|
51
|
+
end
|
61
52
|
end
|
62
53
|
|
63
54
|
private
|
64
55
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
56
|
+
def string_constant?(described)
|
57
|
+
described.str_type? &&
|
58
|
+
described.value.match?(/^(?:(?:::)?[A-Z]\w*)+$/)
|
68
59
|
end
|
69
60
|
end
|
70
61
|
end
|