rubocop-rspec 1.7.0 → 3.0.2
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 +5 -5
- data/CHANGELOG.md +955 -79
- data/CODE_OF_CONDUCT.md +17 -0
- data/MIT-LICENSE.md +1 -2
- data/README.md +35 -35
- data/config/default.yml +940 -52
- data/config/obsoletion.yml +30 -0
- data/lib/rubocop/cop/rspec/align_left_let_brace.rb +49 -0
- data/lib/rubocop/cop/rspec/align_right_let_brace.rb +49 -0
- data/lib/rubocop/cop/rspec/any_instance.rb +10 -13
- data/lib/rubocop/cop/rspec/around_block.rb +97 -0
- data/lib/rubocop/cop/rspec/base.rb +26 -0
- data/lib/rubocop/cop/rspec/be.rb +39 -0
- data/lib/rubocop/cop/rspec/be_empty.rb +45 -0
- data/lib/rubocop/cop/rspec/be_eq.rb +47 -0
- data/lib/rubocop/cop/rspec/be_eql.rb +18 -15
- data/lib/rubocop/cop/rspec/be_nil.rb +74 -0
- data/lib/rubocop/cop/rspec/before_after_all.rb +45 -0
- data/lib/rubocop/cop/rspec/change_by_zero.rb +184 -0
- data/lib/rubocop/cop/rspec/class_check.rb +101 -0
- data/lib/rubocop/cop/rspec/contain_exactly.rb +56 -0
- data/lib/rubocop/cop/rspec/context_method.rb +57 -0
- data/lib/rubocop/cop/rspec/context_wording.rb +117 -0
- data/lib/rubocop/cop/rspec/describe_class.rb +52 -21
- data/lib/rubocop/cop/rspec/describe_method.rb +26 -11
- data/lib/rubocop/cop/rspec/describe_symbol.rb +37 -0
- data/lib/rubocop/cop/rspec/described_class.rb +181 -34
- data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +38 -0
- data/lib/rubocop/cop/rspec/dialect.rb +84 -0
- data/lib/rubocop/cop/rspec/duplicated_metadata.rb +58 -0
- data/lib/rubocop/cop/rspec/empty_example_group.rb +134 -47
- data/lib/rubocop/cop/rspec/empty_hook.rb +49 -0
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +82 -0
- data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +42 -0
- data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +40 -0
- data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +82 -0
- data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +36 -0
- data/lib/rubocop/cop/rspec/empty_metadata.rb +46 -0
- data/lib/rubocop/cop/rspec/empty_output.rb +47 -0
- data/lib/rubocop/cop/rspec/eq.rb +47 -0
- data/lib/rubocop/cop/rspec/example_length.rb +38 -20
- data/lib/rubocop/cop/rspec/example_without_description.rb +98 -0
- data/lib/rubocop/cop/rspec/example_wording.rb +117 -27
- data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +110 -0
- data/lib/rubocop/cop/rspec/expect_actual.rb +46 -20
- data/lib/rubocop/cop/rspec/expect_change.rb +86 -0
- data/lib/rubocop/cop/rspec/expect_in_hook.rb +50 -0
- data/lib/rubocop/cop/rspec/expect_in_let.rb +42 -0
- data/lib/rubocop/cop/rspec/expect_output.rb +50 -0
- data/lib/rubocop/cop/rspec/focus.rb +79 -25
- data/lib/rubocop/cop/rspec/hook_argument.rb +48 -36
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +81 -0
- data/lib/rubocop/cop/rspec/identical_equality_assertion.rb +37 -0
- data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +68 -0
- data/lib/rubocop/cop/rspec/implicit_expect.rb +100 -0
- data/lib/rubocop/cop/rspec/implicit_subject.rb +167 -0
- data/lib/rubocop/cop/rspec/indexed_let.rb +112 -0
- data/lib/rubocop/cop/rspec/instance_spy.rb +74 -0
- data/lib/rubocop/cop/rspec/instance_variable.rb +28 -14
- data/lib/rubocop/cop/rspec/is_expected_specify.rb +45 -0
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +49 -0
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +74 -0
- data/lib/rubocop/cop/rspec/leading_subject.rb +57 -29
- data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +127 -0
- data/lib/rubocop/cop/rspec/let_before_examples.rb +101 -0
- data/lib/rubocop/cop/rspec/let_setup.rb +32 -16
- data/lib/rubocop/cop/rspec/match_array.rb +59 -0
- data/lib/rubocop/cop/rspec/message_chain.rb +10 -15
- data/lib/rubocop/cop/rspec/message_expectation.rb +12 -9
- data/lib/rubocop/cop/rspec/message_spies.rb +88 -0
- data/lib/rubocop/cop/rspec/metadata_style.rb +202 -0
- data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +35 -0
- data/lib/rubocop/cop/rspec/missing_expectation_target_method.rb +54 -0
- data/lib/rubocop/cop/rspec/mixin/comments_help.rb +38 -0
- data/lib/rubocop/cop/rspec/mixin/empty_line_separation.rb +59 -0
- data/lib/rubocop/cop/rspec/mixin/file_help.rb +14 -0
- data/lib/rubocop/cop/rspec/mixin/final_end_location.rb +19 -0
- data/lib/rubocop/cop/rspec/mixin/inside_example_group.rb +29 -0
- data/lib/rubocop/cop/rspec/mixin/location_help.rb +37 -0
- data/lib/rubocop/cop/rspec/mixin/metadata.rb +63 -0
- data/lib/rubocop/cop/rspec/mixin/namespace.rb +23 -0
- data/lib/rubocop/cop/rspec/mixin/skip_or_pending.rb +39 -0
- data/lib/rubocop/cop/rspec/mixin/top_level_group.rb +54 -0
- data/lib/rubocop/cop/rspec/mixin/variable.rb +21 -0
- data/lib/rubocop/cop/rspec/multiple_describes.rb +14 -12
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +86 -26
- data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +146 -0
- data/lib/rubocop/cop/rspec/multiple_subjects.rb +97 -0
- data/lib/rubocop/cop/rspec/named_subject.rb +107 -27
- data/lib/rubocop/cop/rspec/nested_groups.rb +84 -47
- data/lib/rubocop/cop/rspec/no_expectation_example.rb +102 -0
- data/lib/rubocop/cop/rspec/not_to_not.rb +30 -27
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +74 -0
- data/lib/rubocop/cop/rspec/pending.rb +80 -0
- data/lib/rubocop/cop/rspec/pending_without_reason.rb +159 -0
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +341 -0
- data/lib/rubocop/cop/rspec/receive_counts.rb +89 -0
- data/lib/rubocop/cop/rspec/receive_messages.rb +161 -0
- data/lib/rubocop/cop/rspec/receive_never.rb +41 -0
- data/lib/rubocop/cop/rspec/redundant_around.rb +65 -0
- data/lib/rubocop/cop/rspec/redundant_predicate_matcher.rb +67 -0
- data/lib/rubocop/cop/rspec/remove_const.rb +39 -0
- data/lib/rubocop/cop/rspec/repeated_description.rb +98 -0
- data/lib/rubocop/cop/rspec/repeated_example.rb +53 -0
- data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +100 -0
- data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +96 -0
- data/lib/rubocop/cop/rspec/repeated_include_example.rb +105 -0
- data/lib/rubocop/cop/rspec/repeated_subject_call.rb +125 -0
- data/lib/rubocop/cop/rspec/return_from_stub.rb +169 -0
- data/lib/rubocop/cop/rspec/scattered_let.rb +59 -0
- data/lib/rubocop/cop/rspec/scattered_setup.rb +92 -0
- data/lib/rubocop/cop/rspec/shared_context.rb +107 -0
- data/lib/rubocop/cop/rspec/shared_examples.rb +125 -0
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +93 -0
- data/lib/rubocop/cop/rspec/skip_block_inside_example.rb +46 -0
- data/lib/rubocop/cop/rspec/sort_metadata.rb +71 -0
- data/lib/rubocop/cop/rspec/spec_file_path_format.rb +133 -0
- data/lib/rubocop/cop/rspec/spec_file_path_suffix.rb +40 -0
- data/lib/rubocop/cop/rspec/stubbed_mock.rb +176 -0
- data/lib/rubocop/cop/rspec/subject_declaration.rb +46 -0
- data/lib/rubocop/cop/rspec/subject_stub.rb +93 -74
- data/lib/rubocop/cop/rspec/undescriptive_literals_description.rb +69 -0
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +67 -0
- data/lib/rubocop/cop/rspec/variable_definition.rb +77 -0
- data/lib/rubocop/cop/rspec/variable_name.rb +68 -0
- data/lib/rubocop/cop/rspec/verified_double_reference.rb +111 -0
- data/lib/rubocop/cop/rspec/verified_doubles.rb +28 -14
- data/lib/rubocop/cop/rspec/void_expect.rb +60 -0
- data/lib/rubocop/cop/rspec/yield.rb +82 -0
- data/lib/rubocop/cop/rspec_cops.rb +112 -0
- data/lib/rubocop/rspec/align_let_brace.rb +63 -0
- data/lib/rubocop/rspec/concept.rb +33 -0
- data/lib/rubocop/rspec/config_formatter.rb +27 -4
- data/lib/rubocop/rspec/cop/generator.rb +25 -0
- data/lib/rubocop/rspec/corrector/move_node.rb +51 -0
- data/lib/rubocop/rspec/description_extractor.rb +60 -18
- data/lib/rubocop/rspec/example.rb +37 -0
- data/lib/rubocop/rspec/example_group.rb +67 -0
- data/lib/rubocop/rspec/hook.rb +79 -0
- data/lib/rubocop/rspec/inject.rb +3 -1
- data/lib/rubocop/rspec/language.rb +184 -41
- data/lib/rubocop/rspec/node.rb +19 -0
- data/lib/rubocop/rspec/shared_contexts/default_rspec_language_config_context.rb +29 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop/rspec/wording.rb +61 -19
- data/lib/rubocop/rspec.rb +6 -2
- data/lib/rubocop-rspec.rb +45 -34
- metadata +130 -195
- data/Gemfile +0 -13
- data/Rakefile +0 -48
- data/lib/rubocop/cop/rspec/file_path.rb +0 -83
- data/lib/rubocop/rspec/language/node_pattern.rb +0 -16
- data/lib/rubocop/rspec/spec_only.rb +0 -61
- data/lib/rubocop/rspec/top_level_describe.rb +0 -61
- data/lib/rubocop/rspec/util.rb +0 -19
- data/rubocop-rspec.gemspec +0 -42
- data/spec/expect_violation/expectation_spec.rb +0 -85
- data/spec/project/changelog_spec.rb +0 -81
- data/spec/project/default_config_spec.rb +0 -52
- data/spec/project/project_requires_spec.rb +0 -8
- data/spec/rubocop/cop/rspec/any_instance_spec.rb +0 -30
- data/spec/rubocop/cop/rspec/be_eql_spec.rb +0 -59
- data/spec/rubocop/cop/rspec/describe_class_spec.rb +0 -113
- data/spec/rubocop/cop/rspec/describe_method_spec.rb +0 -32
- data/spec/rubocop/cop/rspec/described_class_spec.rb +0 -219
- data/spec/rubocop/cop/rspec/empty_example_group_spec.rb +0 -79
- data/spec/rubocop/cop/rspec/example_length_spec.rb +0 -117
- data/spec/rubocop/cop/rspec/example_wording_spec.rb +0 -82
- data/spec/rubocop/cop/rspec/expect_actual_spec.rb +0 -136
- data/spec/rubocop/cop/rspec/file_path_spec.rb +0 -236
- data/spec/rubocop/cop/rspec/focus_spec.rb +0 -130
- data/spec/rubocop/cop/rspec/hook_argument_spec.rb +0 -189
- data/spec/rubocop/cop/rspec/instance_variable_spec.rb +0 -75
- data/spec/rubocop/cop/rspec/leading_subject_spec.rb +0 -54
- data/spec/rubocop/cop/rspec/let_setup_spec.rb +0 -66
- data/spec/rubocop/cop/rspec/message_chain_spec.rb +0 -21
- data/spec/rubocop/cop/rspec/message_expectation_spec.rb +0 -63
- data/spec/rubocop/cop/rspec/multiple_describes_spec.rb +0 -28
- data/spec/rubocop/cop/rspec/multiple_expectations_spec.rb +0 -84
- data/spec/rubocop/cop/rspec/named_subject_spec.rb +0 -62
- data/spec/rubocop/cop/rspec/nested_groups_spec.rb +0 -55
- data/spec/rubocop/cop/rspec/not_to_not_spec.rb +0 -57
- data/spec/rubocop/cop/rspec/subject_stub_spec.rb +0 -183
- data/spec/rubocop/cop/rspec/verified_doubles_spec.rb +0 -71
- data/spec/rubocop/rspec/config_formatter_spec.rb +0 -48
- data/spec/rubocop/rspec/description_extractor_spec.rb +0 -35
- data/spec/rubocop/rspec/language/selector_set_spec.rb +0 -29
- data/spec/rubocop/rspec/spec_only_spec.rb +0 -97
- data/spec/rubocop/rspec/util/one_spec.rb +0 -21
- data/spec/rubocop/rspec/wording_spec.rb +0 -44
- data/spec/shared/rspec_only_cop_behavior.rb +0 -68
- data/spec/spec_helper.rb +0 -41
- data/spec/support/expect_violation.rb +0 -166
@@ -0,0 +1,30 @@
|
|
1
|
+
#
|
2
|
+
# Configuration of obsolete/deprecated cops used by `ConfigObsoletion`.
|
3
|
+
#
|
4
|
+
# See: https://docs.rubocop.org/rubocop/extensions.html#config-obsoletions
|
5
|
+
#
|
6
|
+
|
7
|
+
# Cop parameters that have been changed
|
8
|
+
# Can be treated as a warning instead of a failure with `severity: warning`
|
9
|
+
changed_parameters:
|
10
|
+
- cops:
|
11
|
+
- RSpec/VariableName
|
12
|
+
parameters: IgnoredPatterns
|
13
|
+
alternative: AllowedPatterns
|
14
|
+
severity: warning
|
15
|
+
|
16
|
+
split:
|
17
|
+
RSpec/FilePath:
|
18
|
+
alternatives:
|
19
|
+
- RSpec/SpecFilePathFormat
|
20
|
+
- RSpec/SpecFilePathSuffix
|
21
|
+
|
22
|
+
removed:
|
23
|
+
RSpec/Capybara/FeatureMethods:
|
24
|
+
reason: >
|
25
|
+
this cop has migrated to `RSpec/Dialect`. Please use `RSpec/Dialect` instead
|
26
|
+
|
27
|
+
extracted:
|
28
|
+
RSpec/Rails/*: rubocop-rspec_rails
|
29
|
+
RSpec/FactoryBot/*: rubocop-factory_bot
|
30
|
+
RSpec/Capybara/*: rubocop-capybara
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks that left braces for adjacent single line lets are aligned.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# let(:foobar) { blahblah }
|
11
|
+
# let(:baz) { bar }
|
12
|
+
# let(:a) { b }
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# let(:foobar) { blahblah }
|
16
|
+
# let(:baz) { bar }
|
17
|
+
# let(:a) { b }
|
18
|
+
#
|
19
|
+
class AlignLeftLetBrace < Base
|
20
|
+
extend AutoCorrector
|
21
|
+
|
22
|
+
MSG = 'Align left let brace'
|
23
|
+
|
24
|
+
def self.autocorrect_incompatible_with
|
25
|
+
[Layout::ExtraSpacing]
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_new_investigation
|
29
|
+
super
|
30
|
+
return if processed_source.blank?
|
31
|
+
|
32
|
+
token_aligner.offending_tokens.each do |let|
|
33
|
+
add_offense(let.loc.begin) do |corrector|
|
34
|
+
corrector.insert_before(
|
35
|
+
let.loc.begin, token_aligner.indent_for(let)
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def token_aligner
|
44
|
+
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks that right braces for adjacent single line lets are aligned.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# let(:foobar) { blahblah }
|
11
|
+
# let(:baz) { bar }
|
12
|
+
# let(:a) { b }
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# let(:foobar) { blahblah }
|
16
|
+
# let(:baz) { bar }
|
17
|
+
# let(:a) { b }
|
18
|
+
#
|
19
|
+
class AlignRightLetBrace < Base
|
20
|
+
extend AutoCorrector
|
21
|
+
|
22
|
+
MSG = 'Align right let brace'
|
23
|
+
|
24
|
+
def self.autocorrect_incompatible_with
|
25
|
+
[Layout::ExtraSpacing]
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_new_investigation
|
29
|
+
super
|
30
|
+
return if processed_source.blank?
|
31
|
+
|
32
|
+
token_aligner.offending_tokens.each do |let|
|
33
|
+
add_offense(let.loc.end) do |corrector|
|
34
|
+
corrector.insert_before(
|
35
|
+
let.loc.end, token_aligner.indent_for(let)
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def token_aligner
|
44
|
+
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
module Cop
|
3
5
|
module RSpec
|
@@ -20,22 +22,17 @@ module RuboCop
|
|
20
22
|
# allow(my_instance).to receive(:foo)
|
21
23
|
# end
|
22
24
|
# end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
:allow_any_instance_of,
|
31
|
-
:expect_any_instance_of
|
25
|
+
#
|
26
|
+
class AnyInstance < Base
|
27
|
+
MSG = 'Avoid stubbing using `%<method>s`.'
|
28
|
+
RESTRICT_ON_SEND = %i[
|
29
|
+
any_instance
|
30
|
+
allow_any_instance_of
|
31
|
+
expect_any_instance_of
|
32
32
|
].freeze
|
33
33
|
|
34
34
|
def on_send(node)
|
35
|
-
|
36
|
-
return unless ANY_INSTANCE_METHODS.include?(method_name)
|
37
|
-
|
38
|
-
add_offense(node, :expression, MESSAGE % { method: method_name })
|
35
|
+
add_offense(node, message: format(MSG, method: node.method_name))
|
39
36
|
end
|
40
37
|
end
|
41
38
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks that around blocks actually run the test.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# around do
|
11
|
+
# some_method
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# around do |test|
|
15
|
+
# some_method
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# around do |test|
|
20
|
+
# some_method
|
21
|
+
# test.call
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# around do |test|
|
25
|
+
# some_method
|
26
|
+
# test.run
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
class AroundBlock < Base
|
30
|
+
MSG_NO_ARG = 'Test object should be passed to around block.'
|
31
|
+
MSG_UNUSED_ARG = 'You should call `%<arg>s.call` ' \
|
32
|
+
'or `%<arg>s.run`.'
|
33
|
+
|
34
|
+
# @!method hook_block(node)
|
35
|
+
def_node_matcher :hook_block, <<~PATTERN
|
36
|
+
(block (send nil? :around sym ?) (args $...) ...)
|
37
|
+
PATTERN
|
38
|
+
|
39
|
+
# @!method hook_numblock(node)
|
40
|
+
def_node_matcher :hook_numblock, <<~PATTERN
|
41
|
+
(numblock (send nil? :around sym ?) ...)
|
42
|
+
PATTERN
|
43
|
+
|
44
|
+
# @!method find_arg_usage(node)
|
45
|
+
def_node_search :find_arg_usage, <<~PATTERN
|
46
|
+
{(send $... {:call :run}) (send _ _ $...) (yield $...) (block-pass $...)}
|
47
|
+
PATTERN
|
48
|
+
|
49
|
+
def on_block(node)
|
50
|
+
hook_block(node) do |(example_proxy)|
|
51
|
+
if example_proxy.nil?
|
52
|
+
add_no_arg_offense(node)
|
53
|
+
else
|
54
|
+
check_for_unused_proxy(node, example_proxy)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def on_numblock(node)
|
60
|
+
hook_numblock(node) do
|
61
|
+
check_for_numblock(node)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def add_no_arg_offense(node)
|
68
|
+
add_offense(node, message: MSG_NO_ARG)
|
69
|
+
end
|
70
|
+
|
71
|
+
def check_for_unused_proxy(block, proxy)
|
72
|
+
name, = *proxy
|
73
|
+
|
74
|
+
find_arg_usage(block) do |usage|
|
75
|
+
return if usage.include?(s(:lvar, name))
|
76
|
+
end
|
77
|
+
|
78
|
+
add_offense(
|
79
|
+
proxy,
|
80
|
+
message: format(MSG_UNUSED_ARG, arg: name)
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_for_numblock(block)
|
85
|
+
find_arg_usage(block) do |usage|
|
86
|
+
return if usage.include?(s(:lvar, :_1))
|
87
|
+
end
|
88
|
+
|
89
|
+
add_offense(
|
90
|
+
block.children.last,
|
91
|
+
message: format(MSG_UNUSED_ARG, arg: :_1)
|
92
|
+
)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# @abstract parent class to RSpec cops
|
7
|
+
class Base < ::RuboCop::Cop::Base
|
8
|
+
include RuboCop::RSpec::Language
|
9
|
+
|
10
|
+
exclude_from_registry
|
11
|
+
|
12
|
+
# Invoke the original inherited hook so our cops are recognized
|
13
|
+
def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
|
14
|
+
RuboCop::Cop::Base.inherited(subclass)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Set the config for dynamic DSL configuration-aware helpers
|
18
|
+
# that have no other means of accessing the configuration.
|
19
|
+
def on_new_investigation
|
20
|
+
super
|
21
|
+
RuboCop::RSpec::Language.config = config['RSpec']['Language']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Check for expectations where `be` is used without argument.
|
7
|
+
#
|
8
|
+
# The `be` matcher is too generic, as it pass on everything that is not
|
9
|
+
# nil or false. If that is the exact intend, use `be_truthy`. In all other
|
10
|
+
# cases it's better to specify what exactly is the expected value.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # bad
|
14
|
+
# expect(foo).to be
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# expect(foo).to be_truthy
|
18
|
+
# expect(foo).to be 1.0
|
19
|
+
# expect(foo).to be(true)
|
20
|
+
#
|
21
|
+
class Be < Base
|
22
|
+
MSG = "Don't use `be` without an argument."
|
23
|
+
|
24
|
+
RESTRICT_ON_SEND = Runners.all
|
25
|
+
|
26
|
+
# @!method be_without_args(node)
|
27
|
+
def_node_matcher :be_without_args, <<~PATTERN
|
28
|
+
(send _ #Runners.all $(send nil? :be))
|
29
|
+
PATTERN
|
30
|
+
|
31
|
+
def on_send(node)
|
32
|
+
be_without_args(node) do |matcher|
|
33
|
+
add_offense(matcher.loc.selector)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Prefer using `be_empty` when checking for an empty array.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# expect(array).to contain_exactly
|
11
|
+
# expect(array).to match_array([])
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# expect(array).to be_empty
|
15
|
+
#
|
16
|
+
class BeEmpty < Base
|
17
|
+
extend AutoCorrector
|
18
|
+
|
19
|
+
MSG = 'Use `be_empty` matchers for checking an empty array.'
|
20
|
+
RESTRICT_ON_SEND = %i[contain_exactly match_array].freeze
|
21
|
+
|
22
|
+
# @!method expect_array_matcher?(node)
|
23
|
+
def_node_matcher :expect_array_matcher?, <<~PATTERN
|
24
|
+
(send
|
25
|
+
(send nil? :expect _)
|
26
|
+
#Runners.all
|
27
|
+
${
|
28
|
+
(send nil? :match_array (array))
|
29
|
+
(send nil? :contain_exactly)
|
30
|
+
}
|
31
|
+
_?
|
32
|
+
)
|
33
|
+
PATTERN
|
34
|
+
|
35
|
+
def on_send(node)
|
36
|
+
expect_array_matcher?(node.parent) do |expect|
|
37
|
+
add_offense(expect) do |corrector|
|
38
|
+
corrector.replace(expect, 'be_empty')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Check for expectations where `be(...)` can replace `eq(...)`.
|
7
|
+
#
|
8
|
+
# The `be` matcher compares by identity while the `eq` matcher compares
|
9
|
+
# using `==`. Booleans and nil can be compared by identity and therefore
|
10
|
+
# the `be` matcher is preferable as it is a more strict test.
|
11
|
+
#
|
12
|
+
# @safety
|
13
|
+
# This cop is unsafe because it changes how values are compared.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# # bad
|
17
|
+
# expect(foo).to eq(true)
|
18
|
+
# expect(foo).to eq(false)
|
19
|
+
# expect(foo).to eq(nil)
|
20
|
+
#
|
21
|
+
# # good
|
22
|
+
# expect(foo).to be(true)
|
23
|
+
# expect(foo).to be(false)
|
24
|
+
# expect(foo).to be(nil)
|
25
|
+
#
|
26
|
+
class BeEq < Base
|
27
|
+
extend AutoCorrector
|
28
|
+
|
29
|
+
MSG = 'Prefer `be` over `eq`.'
|
30
|
+
RESTRICT_ON_SEND = %i[eq].freeze
|
31
|
+
|
32
|
+
# @!method eq_type_with_identity?(node)
|
33
|
+
def_node_matcher :eq_type_with_identity?, <<~PATTERN
|
34
|
+
(send nil? :eq {true false nil})
|
35
|
+
PATTERN
|
36
|
+
|
37
|
+
def on_send(node)
|
38
|
+
return unless eq_type_with_identity?(node)
|
39
|
+
|
40
|
+
add_offense(node.loc.selector) do |corrector|
|
41
|
+
corrector.replace(node.loc.selector, 'be')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,21 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
module Cop
|
3
5
|
module RSpec
|
4
6
|
# Check for expectations where `be(...)` can replace `eql(...)`.
|
5
7
|
#
|
6
8
|
# The `be` matcher compares by identity while the `eql` matcher
|
7
|
-
# compares using `eql?`. Integers, floats, booleans, and
|
9
|
+
# compares using `eql?`. Integers, floats, booleans, symbols, and nil
|
8
10
|
# can be compared by identity and therefore the `be` matcher is
|
9
11
|
# preferable as it is a more strict test.
|
10
12
|
#
|
11
|
-
# @
|
13
|
+
# @safety
|
14
|
+
# This cop is unsafe because it changes how values are compared.
|
12
15
|
#
|
16
|
+
# @example
|
13
17
|
# # bad
|
14
18
|
# expect(foo).to eql(1)
|
15
19
|
# expect(foo).to eql(1.0)
|
16
20
|
# expect(foo).to eql(true)
|
17
21
|
# expect(foo).to eql(false)
|
18
22
|
# expect(foo).to eql(:bar)
|
23
|
+
# expect(foo).to eql(nil)
|
19
24
|
#
|
20
25
|
# # good
|
21
26
|
# expect(foo).to be(1)
|
@@ -23,6 +28,7 @@ module RuboCop
|
|
23
28
|
# expect(foo).to be(true)
|
24
29
|
# expect(foo).to be(false)
|
25
30
|
# expect(foo).to be(:bar)
|
31
|
+
# expect(foo).to be(nil)
|
26
32
|
#
|
27
33
|
# This cop only looks for instances of `expect(...).to eql(...)`. We
|
28
34
|
# do not check `to_not` or `not_to` since `!eql?` is more strict
|
@@ -31,25 +37,22 @@ module RuboCop
|
|
31
37
|
# necessarily the same type as `b` since the `#==` operator can
|
32
38
|
# coerce objects for comparison.
|
33
39
|
#
|
34
|
-
class BeEql <
|
35
|
-
|
36
|
-
RuboCop::Cop::ConfigurableEnforcedStyle
|
40
|
+
class BeEql < Base
|
41
|
+
extend AutoCorrector
|
37
42
|
|
38
|
-
MSG = 'Prefer `be` over `eql
|
43
|
+
MSG = 'Prefer `be` over `eql`.'
|
44
|
+
RESTRICT_ON_SEND = %i[to].freeze
|
39
45
|
|
40
|
-
|
41
|
-
|
46
|
+
# @!method eql_type_with_identity(node)
|
47
|
+
def_node_matcher :eql_type_with_identity, <<~PATTERN
|
48
|
+
(send _ :to $(send nil? :eql {true false int float sym nil}))
|
42
49
|
PATTERN
|
43
50
|
|
44
51
|
def on_send(node)
|
45
52
|
eql_type_with_identity(node) do |eql|
|
46
|
-
add_offense(eql
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
def autocorrect(node)
|
51
|
-
lambda do |corrector|
|
52
|
-
corrector.replace(node.loc.selector, 'be')
|
53
|
+
add_offense(eql.loc.selector) do |corrector|
|
54
|
+
corrector.replace(eql.loc.selector, 'be')
|
55
|
+
end
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Ensures a consistent style is used when matching `nil`.
|
7
|
+
#
|
8
|
+
# You can either use the more specific `be_nil` matcher, or the more
|
9
|
+
# generic `be` matcher with a `nil` argument.
|
10
|
+
#
|
11
|
+
# This cop can be configured using the `EnforcedStyle` option
|
12
|
+
#
|
13
|
+
# @example `EnforcedStyle: be_nil` (default)
|
14
|
+
# # bad
|
15
|
+
# expect(foo).to be(nil)
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# expect(foo).to be_nil
|
19
|
+
#
|
20
|
+
# @example `EnforcedStyle: be`
|
21
|
+
# # bad
|
22
|
+
# expect(foo).to be_nil
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# expect(foo).to be(nil)
|
26
|
+
#
|
27
|
+
class BeNil < Base
|
28
|
+
extend AutoCorrector
|
29
|
+
include ConfigurableEnforcedStyle
|
30
|
+
|
31
|
+
BE_MSG = 'Prefer `be(nil)` over `be_nil`.'
|
32
|
+
BE_NIL_MSG = 'Prefer `be_nil` over `be(nil)`.'
|
33
|
+
RESTRICT_ON_SEND = %i[be be_nil].freeze
|
34
|
+
|
35
|
+
# @!method be_nil_matcher?(node)
|
36
|
+
def_node_matcher :be_nil_matcher?, <<~PATTERN
|
37
|
+
(send nil? :be_nil)
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
# @!method nil_value_expectation?(node)
|
41
|
+
def_node_matcher :nil_value_expectation?, <<~PATTERN
|
42
|
+
(send nil? :be nil)
|
43
|
+
PATTERN
|
44
|
+
|
45
|
+
def on_send(node)
|
46
|
+
case style
|
47
|
+
when :be
|
48
|
+
check_be_style(node)
|
49
|
+
when :be_nil
|
50
|
+
check_be_nil_style(node)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def check_be_style(node)
|
57
|
+
return unless be_nil_matcher?(node)
|
58
|
+
|
59
|
+
add_offense(node, message: BE_MSG) do |corrector|
|
60
|
+
corrector.replace(node, 'be(nil)')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def check_be_nil_style(node)
|
65
|
+
return unless nil_value_expectation?(node)
|
66
|
+
|
67
|
+
add_offense(node, message: BE_NIL_MSG) do |corrector|
|
68
|
+
corrector.replace(node, 'be_nil')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Check that before/after(:all/:context) isn't being used.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad - Faster but risk of state leaking between examples
|
10
|
+
# describe MyClass do
|
11
|
+
# before(:all) { Widget.create }
|
12
|
+
# after(:context) { Widget.delete_all }
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # good - Slower but examples are properly isolated
|
16
|
+
# describe MyClass do
|
17
|
+
# before(:each) { Widget.create }
|
18
|
+
# after(:each) { Widget.delete_all }
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
class BeforeAfterAll < Base
|
22
|
+
MSG = 'Beware of using `%<hook>s` as it may cause state to leak ' \
|
23
|
+
'between tests. If you are using `rspec-rails`, and ' \
|
24
|
+
'`use_transactional_fixtures` is enabled, then records created ' \
|
25
|
+
'in `%<hook>s` are not automatically rolled back.'
|
26
|
+
|
27
|
+
RESTRICT_ON_SEND = Set[:before, :after].freeze
|
28
|
+
|
29
|
+
# @!method before_or_after_all(node)
|
30
|
+
def_node_matcher :before_or_after_all, <<~PATTERN
|
31
|
+
$(send _ RESTRICT_ON_SEND (sym {:all :context}))
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def on_send(node)
|
35
|
+
before_or_after_all(node) do |hook|
|
36
|
+
add_offense(
|
37
|
+
node,
|
38
|
+
message: format(MSG, hook: hook.source)
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|