rubocop-rspec 2.2.0 → 2.6.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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/README.md +3 -5
  4. data/config/default.yml +79 -3
  5. data/lib/rubocop/cop/rspec/around_block.rb +2 -0
  6. data/lib/rubocop/cop/rspec/be.rb +1 -0
  7. data/lib/rubocop/cop/rspec/be_eql.rb +1 -0
  8. data/lib/rubocop/cop/rspec/before_after_all.rb +1 -0
  9. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +3 -0
  10. data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +3 -0
  11. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +2 -0
  12. data/lib/rubocop/cop/rspec/context_method.rb +1 -0
  13. data/lib/rubocop/cop/rspec/context_wording.rb +7 -1
  14. data/lib/rubocop/cop/rspec/describe_class.rb +3 -0
  15. data/lib/rubocop/cop/rspec/describe_method.rb +1 -0
  16. data/lib/rubocop/cop/rspec/describe_symbol.rb +1 -0
  17. data/lib/rubocop/cop/rspec/described_class.rb +6 -1
  18. data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +2 -1
  19. data/lib/rubocop/cop/rspec/dialect.rb +1 -0
  20. data/lib/rubocop/cop/rspec/empty_hook.rb +5 -1
  21. data/lib/rubocop/cop/rspec/example_length.rb +26 -12
  22. data/lib/rubocop/cop/rspec/example_without_description.rb +1 -0
  23. data/lib/rubocop/cop/rspec/example_wording.rb +4 -0
  24. data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +100 -0
  25. data/lib/rubocop/cop/rspec/expect_actual.rb +1 -0
  26. data/lib/rubocop/cop/rspec/expect_change.rb +5 -3
  27. data/lib/rubocop/cop/rspec/expect_in_hook.rb +1 -0
  28. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +3 -0
  29. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +3 -0
  30. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -0
  31. data/lib/rubocop/cop/rspec/file_path.rb +13 -9
  32. data/lib/rubocop/cop/rspec/focus.rb +3 -0
  33. data/lib/rubocop/cop/rspec/hook_argument.rb +3 -1
  34. data/lib/rubocop/cop/rspec/hooks_before_examples.rb +1 -0
  35. data/lib/rubocop/cop/rspec/identical_equality_assertion.rb +38 -0
  36. data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +3 -0
  37. data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -0
  38. data/lib/rubocop/cop/rspec/implicit_subject.rb +18 -1
  39. data/lib/rubocop/cop/rspec/instance_spy.rb +2 -0
  40. data/lib/rubocop/cop/rspec/instance_variable.rb +4 -0
  41. data/lib/rubocop/cop/rspec/it_behaves_like.rb +1 -0
  42. data/lib/rubocop/cop/rspec/iterated_expectation.rb +4 -0
  43. data/lib/rubocop/cop/rspec/let_before_examples.rb +1 -0
  44. data/lib/rubocop/cop/rspec/let_setup.rb +3 -0
  45. data/lib/rubocop/cop/rspec/message_expectation.rb +2 -0
  46. data/lib/rubocop/cop/rspec/message_spies.rb +2 -0
  47. data/lib/rubocop/cop/rspec/mixin/variable.rb +1 -0
  48. data/lib/rubocop/cop/rspec/multiple_expectations.rb +3 -0
  49. data/lib/rubocop/cop/rspec/named_subject.rb +3 -0
  50. data/lib/rubocop/cop/rspec/nested_groups.rb +1 -1
  51. data/lib/rubocop/cop/rspec/not_to_not.rb +1 -0
  52. data/lib/rubocop/cop/rspec/overwriting_setup.rb +2 -0
  53. data/lib/rubocop/cop/rspec/pending.rb +4 -0
  54. data/lib/rubocop/cop/rspec/predicate_matcher.rb +5 -0
  55. data/lib/rubocop/cop/rspec/rails/avoid_setup_hook.rb +44 -0
  56. data/lib/rubocop/cop/rspec/rails/http_status.rb +1 -0
  57. data/lib/rubocop/cop/rspec/receive_counts.rb +2 -0
  58. data/lib/rubocop/cop/rspec/receive_never.rb +1 -0
  59. data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +8 -1
  60. data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +4 -0
  61. data/lib/rubocop/cop/rspec/repeated_include_example.rb +3 -0
  62. data/lib/rubocop/cop/rspec/return_from_stub.rb +5 -0
  63. data/lib/rubocop/cop/rspec/shared_context.rb +4 -0
  64. data/lib/rubocop/cop/rspec/shared_examples.rb +1 -0
  65. data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +2 -0
  66. data/lib/rubocop/cop/rspec/stubbed_mock.rb +1 -0
  67. data/lib/rubocop/cop/rspec/subject_declaration.rb +47 -0
  68. data/lib/rubocop/cop/rspec/subject_stub.rb +1 -0
  69. data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -0
  70. data/lib/rubocop/cop/rspec/variable_definition.rb +19 -2
  71. data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -0
  72. data/lib/rubocop/cop/rspec/void_expect.rb +2 -0
  73. data/lib/rubocop/cop/rspec/yield.rb +3 -0
  74. data/lib/rubocop/cop/rspec_cops.rb +4 -0
  75. data/lib/rubocop/rspec/align_let_brace.rb +2 -1
  76. data/lib/rubocop/rspec/config_formatter.rb +3 -0
  77. data/lib/rubocop/rspec/example.rb +5 -0
  78. data/lib/rubocop/rspec/hook.rb +1 -0
  79. data/lib/rubocop/rspec/language.rb +10 -0
  80. data/lib/rubocop/rspec/version.rb +1 -1
  81. metadata +17 -27
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Checks for excessive whitespace in example descriptions.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # it ' has excessive spacing ' do
11
+ # end
12
+ #
13
+ # # good
14
+ # it 'has excessive spacing' do
15
+ # end
16
+ #
17
+ # @example
18
+ # # bad
19
+ # context ' when a condition is met ' do
20
+ # end
21
+ #
22
+ # # good
23
+ # context 'when a condition is met' do
24
+ # end
25
+ class ExcessiveDocstringSpacing < Base
26
+ extend AutoCorrector
27
+
28
+ MSG = 'Excessive whitespace.'
29
+
30
+ # @!method example_description(node)
31
+ def_node_matcher :example_description, <<-PATTERN
32
+ (send _ {#Examples.all #ExampleGroups.all} ${
33
+ $str
34
+ $(dstr ({str dstr `sym} ...) ...)
35
+ } ...)
36
+ PATTERN
37
+
38
+ def on_send(node)
39
+ example_description(node) do |description_node, message|
40
+ return if description_node.heredoc?
41
+
42
+ text = text(message)
43
+
44
+ return unless excessive_whitespace?(text)
45
+
46
+ add_whitespace_offense(description_node, text)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ # @param text [String]
53
+ def excessive_whitespace?(text)
54
+ return true if text.start_with?(' ') || text.end_with?(' ')
55
+
56
+ text.match?(/[^\n ] +[^ ]/)
57
+ end
58
+
59
+ # @param text [String]
60
+ def strip_excessive_whitespace(text)
61
+ text.strip.gsub(/ +/, ' ')
62
+ end
63
+
64
+ # @param node [RuboCop::AST::Node]
65
+ # @param text [String]
66
+ def add_whitespace_offense(node, text)
67
+ docstring = docstring(node)
68
+ corrected = strip_excessive_whitespace(text)
69
+
70
+ add_offense(docstring) do |corrector|
71
+ corrector.replace(docstring, corrected)
72
+ end
73
+ end
74
+
75
+ def docstring(node)
76
+ expr = node.loc.expression
77
+
78
+ Parser::Source::Range.new(
79
+ expr.source_buffer,
80
+ expr.begin_pos + 1,
81
+ expr.end_pos - 1
82
+ )
83
+ end
84
+
85
+ # Recursive processing is required to process nested dstr nodes
86
+ # that is the case for \-separated multiline strings with interpolation.
87
+ def text(node)
88
+ case node.type
89
+ when :dstr
90
+ node.node_parts.map { |child_node| text(child_node) }.join
91
+ when :str, :sym
92
+ node.value
93
+ when :begin
94
+ node.source
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -45,6 +45,7 @@ module RuboCop
45
45
 
46
46
  SUPPORTED_MATCHERS = %i[eq eql equal be].freeze
47
47
 
48
+ # @!method expect_literal(node)
48
49
  def_node_matcher :expect_literal, <<~PATTERN
49
50
  (send
50
51
  (send nil? :expect $#literal?)
@@ -37,10 +37,12 @@ module RuboCop
37
37
  MSG_CALL = 'Prefer `change { %<obj>s.%<attr>s }`.'
38
38
  RESTRICT_ON_SEND = %i[change].freeze
39
39
 
40
+ # @!method expect_change_with_arguments(node)
40
41
  def_node_matcher :expect_change_with_arguments, <<-PATTERN
41
- (send nil? :change ({const send} nil? $_) (sym $_))
42
+ (send nil? :change $_ (sym $_))
42
43
  PATTERN
43
44
 
45
+ # @!method expect_change_with_block(node)
44
46
  def_node_matcher :expect_change_with_block, <<-PATTERN
45
47
  (block
46
48
  (send nil? :change)
@@ -53,9 +55,9 @@ module RuboCop
53
55
  return unless style == :block
54
56
 
55
57
  expect_change_with_arguments(node) do |receiver, message|
56
- msg = format(MSG_CALL, obj: receiver, attr: message)
58
+ msg = format(MSG_CALL, obj: receiver.source, attr: message)
57
59
  add_offense(node, message: msg) do |corrector|
58
- replacement = "change { #{receiver}.#{message} }"
60
+ replacement = "change { #{receiver.source}.#{message} }"
59
61
  corrector.replace(node, replacement)
60
62
  end
61
63
  end
@@ -23,6 +23,7 @@ module RuboCop
23
23
  class ExpectInHook < Base
24
24
  MSG = 'Do not use `%<expect>s` in `%<hook>s` hook'
25
25
 
26
+ # @!method expectation(node)
26
27
  def_node_search :expectation, send_pattern('#Expectations.all')
27
28
 
28
29
  def on_block(node)
@@ -29,10 +29,12 @@ module RuboCop
29
29
 
30
30
  MSG = 'Use a block to declare attribute values.'
31
31
 
32
+ # @!method value_matcher(node)
32
33
  def_node_matcher :value_matcher, <<-PATTERN
33
34
  (send _ !#reserved_method? $...)
34
35
  PATTERN
35
36
 
37
+ # @!method factory_attributes(node)
36
38
  def_node_matcher :factory_attributes, <<-PATTERN
37
39
  (block (send _ #attribute_defining_method? ...) _ { (begin $...) $(send ...) } )
38
40
  PATTERN
@@ -79,6 +81,7 @@ module RuboCop
79
81
  value_matcher(attribute).to_a.all?(&:block_pass_type?)
80
82
  end
81
83
 
84
+ # @!method association?(node)
82
85
  def_node_matcher :association?, '(hash <(pair (sym :factory) _) ...>)'
83
86
 
84
87
  def autocorrect_replacing_parens(corrector, node)
@@ -32,6 +32,7 @@ module RuboCop
32
32
  MSG_N_TIMES = 'Prefer %<number>s.times.'
33
33
  RESTRICT_ON_SEND = %i[create_list].freeze
34
34
 
35
+ # @!method n_times_block_without_arg?(node)
35
36
  def_node_matcher :n_times_block_without_arg?, <<-PATTERN
36
37
  (block
37
38
  (send (int _) :times)
@@ -40,10 +41,12 @@ module RuboCop
40
41
  )
41
42
  PATTERN
42
43
 
44
+ # @!method factory_call(node)
43
45
  def_node_matcher :factory_call, <<-PATTERN
44
46
  (send ${(const nil? {:FactoryGirl :FactoryBot}) nil?} :create (sym $_) $...)
45
47
  PATTERN
46
48
 
49
+ # @!method factory_list_call(node)
47
50
  def_node_matcher :factory_list_call, <<-PATTERN
48
51
  (send {(const nil? {:FactoryGirl :FactoryBot}) nil?} :create_list (sym _) (int $_) ...)
49
52
  PATTERN
@@ -27,6 +27,7 @@ module RuboCop
27
27
  ALLOWED_CONSTANTS = %w[Hash OpenStruct].freeze
28
28
  RESTRICT_ON_SEND = %i[factory].freeze
29
29
 
30
+ # @!method class_name(node)
30
31
  def_node_matcher :class_name, <<~PATTERN
31
32
  (send _ :factory _ (hash <(pair (sym :class) $(const ...)) ...>))
32
33
  PATTERN
@@ -61,28 +61,30 @@ module RuboCop
61
61
 
62
62
  MSG = 'Spec path should end with `%<suffix>s`.'
63
63
 
64
- def_node_matcher :const_described, <<~PATTERN
64
+ # @!method example_group(node)
65
+ def_node_matcher :example_group, <<~PATTERN
65
66
  (block
66
- $(send #rspec? _example_group $(const ...) $...) ...
67
+ $(send #rspec? _example_group $_ $...) ...
67
68
  )
68
69
  PATTERN
69
70
 
71
+ # @!method routing_metadata?(node)
70
72
  def_node_search :routing_metadata?, '(pair (sym :type) (sym :routing))'
71
73
 
72
74
  def on_top_level_example_group(node)
73
75
  return unless top_level_groups.one?
74
76
 
75
- const_described(node) do |send_node, described_class, arguments|
77
+ example_group(node) do |send_node, example_group, arguments|
76
78
  next if routing_spec?(arguments)
77
79
 
78
- ensure_correct_file_path(send_node, described_class, arguments)
80
+ ensure_correct_file_path(send_node, example_group, arguments)
79
81
  end
80
82
  end
81
83
 
82
84
  private
83
85
 
84
- def ensure_correct_file_path(send_node, described_class, arguments)
85
- pattern = pattern_for(described_class, arguments.first)
86
+ def ensure_correct_file_path(send_node, example_group, arguments)
87
+ pattern = pattern_for(example_group, arguments.first)
86
88
  return if filename_ends_with?(pattern)
87
89
 
88
90
  # For the suffix shown in the offense message, modify the regular
@@ -97,11 +99,13 @@ module RuboCop
97
99
  args.any?(&method(:routing_metadata?))
98
100
  end
99
101
 
100
- def pattern_for(described_class, method_name)
101
- return pattern_for_spec_suffix_only? if spec_suffix_only?
102
+ def pattern_for(example_group, method_name)
103
+ if spec_suffix_only? || !example_group.const_type?
104
+ return pattern_for_spec_suffix_only?
105
+ end
102
106
 
103
107
  [
104
- expected_path(described_class),
108
+ expected_path(example_group),
105
109
  name_pattern(method_name),
106
110
  '[^/]*_spec\.rb'
107
111
  ].join
@@ -25,6 +25,7 @@ module RuboCop
25
25
 
26
26
  MSG = 'Focused spec found.'
27
27
 
28
+ # @!method focusable_selector?(node)
28
29
  def_node_matcher :focusable_selector?, <<-PATTERN
29
30
  {
30
31
  #ExampleGroups.regular
@@ -35,11 +36,13 @@ module RuboCop
35
36
  }
36
37
  PATTERN
37
38
 
39
+ # @!method metadata(node)
38
40
  def_node_matcher :metadata, <<-PATTERN
39
41
  {(send #rspec? #focusable_selector? <$(sym :focus) ...>)
40
42
  (send #rspec? #focusable_selector? ... (hash <$(pair (sym :focus) true) ...>))}
41
43
  PATTERN
42
44
 
45
+ # @!method focused_block?(node)
43
46
  def_node_matcher :focused_block?,
44
47
  send_pattern(<<~PATTERN)
45
48
  {#ExampleGroups.focused #Examples.focused}
@@ -32,7 +32,7 @@ module RuboCop
32
32
  # # ...
33
33
  # end
34
34
  #
35
- # # good
35
+ # # bad
36
36
  # before do
37
37
  # # ...
38
38
  # end
@@ -64,10 +64,12 @@ module RuboCop
64
64
  IMPLICIT_MSG = 'Omit the default `%<scope>p` argument for RSpec hooks.'
65
65
  EXPLICIT_MSG = 'Use `%<scope>p` for RSpec hooks.'
66
66
 
67
+ # @!method scoped_hook(node)
67
68
  def_node_matcher :scoped_hook, <<-PATTERN
68
69
  (block $(send _ #Hooks.all (sym ${:each :example})) ...)
69
70
  PATTERN
70
71
 
72
+ # @!method unscoped_hook(node)
71
73
  def_node_matcher :unscoped_hook, '(block $(send _ #Hooks.all) ...)'
72
74
 
73
75
  def on_block(node)
@@ -28,6 +28,7 @@ module RuboCop
28
28
 
29
29
  MSG = 'Move `%<hook>s` above the examples in the group.'
30
30
 
31
+ # @!method example_or_group?(node)
31
32
  def_node_matcher :example_or_group?, <<-PATTERN
32
33
  {
33
34
  #{block_pattern('{#ExampleGroups.all #Examples.all}')}
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Checks for equality assertions with identical expressions on both sides.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # expect(foo.bar).to eq(foo.bar)
12
+ # expect(foo.bar).to eql(foo.bar)
13
+ #
14
+ # # good
15
+ # expect(foo.bar).to eq(2)
16
+ # expect(foo.bar).to eql(2)
17
+ #
18
+ class IdenticalEqualityAssertion < Base
19
+ MSG = 'Identical expressions on both sides of the equality ' \
20
+ 'may indicate a flawed test.'
21
+ RESTRICT_ON_SEND = %i[to].freeze
22
+
23
+ # @!method equality_check?(node)
24
+ def_node_matcher :equality_check?, <<~PATTERN
25
+ (send (send nil? :expect $_) :to
26
+ {(send nil? {:eql :eq :be} $_)
27
+ (send (send nil? :be) :== $_)})
28
+ PATTERN
29
+
30
+ def on_send(node)
31
+ equality_check?(node) do |left, right|
32
+ add_offense(node) if left == right
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -20,6 +20,7 @@ module RuboCop
20
20
  MSG = 'Avoid implicit block expectations.'
21
21
  RESTRICT_ON_SEND = %i[is_expected should should_not].freeze
22
22
 
23
+ # @!method lambda?(node)
23
24
  def_node_matcher :lambda?, <<-PATTERN
24
25
  {
25
26
  (send (const nil? :Proc) :new)
@@ -27,8 +28,10 @@ module RuboCop
27
28
  }
28
29
  PATTERN
29
30
 
31
+ # @!method lambda_subject?(node)
30
32
  def_node_matcher :lambda_subject?, '(block #lambda? ...)'
31
33
 
34
+ # @!method implicit_expect(node)
32
35
  def_node_matcher :implicit_expect, <<-PATTERN
33
36
  $(send nil? {:is_expected :should :should_not} ...)
34
37
  PATTERN
@@ -30,6 +30,7 @@ module RuboCop
30
30
 
31
31
  MSG = 'Prefer `%<good>s` over `%<bad>s`.'
32
32
 
33
+ # @!method implicit_expect(node)
33
34
  def_node_matcher :implicit_expect, <<-PATTERN
34
35
  {
35
36
  (send nil? ${:should :should_not} ...)
@@ -7,7 +7,7 @@ module RuboCop
7
7
  #
8
8
  # This cop can be configured using the `EnforcedStyle` option
9
9
  #
10
- # @example `EnforcedStyle: single_line_only`
10
+ # @example `EnforcedStyle: single_line_only` (default)
11
11
  # # bad
12
12
  # it do
13
13
  # is_expected.to be_truthy
@@ -19,6 +19,22 @@ module RuboCop
19
19
  # expect(subject).to be_truthy
20
20
  # end
21
21
  #
22
+ # @example `EnforcedStyle: single_statement_only`
23
+ # # bad
24
+ # it do
25
+ # foo = 1
26
+ # is_expected.to be_truthy
27
+ # end
28
+ #
29
+ # # good
30
+ # it do
31
+ # foo = 1
32
+ # expect(subject).to be_truthy
33
+ # end
34
+ # it do
35
+ # is_expected.to be_truthy
36
+ # end
37
+ #
22
38
  # @example `EnforcedStyle: disallow`
23
39
  # # bad
24
40
  # it { is_expected.to be_truthy }
@@ -33,6 +49,7 @@ module RuboCop
33
49
  MSG = "Don't use implicit subject."
34
50
  RESTRICT_ON_SEND = %i[is_expected should should_not].freeze
35
51
 
52
+ # @!method implicit_subject?(node)
36
53
  def_node_matcher :implicit_subject?, <<-PATTERN
37
54
  (send nil? {:should :should_not :is_expected} ...)
38
55
  PATTERN
@@ -24,6 +24,7 @@ module RuboCop
24
24
  MSG = 'Use `instance_spy` when you check your double ' \
25
25
  'with `have_received`.'
26
26
 
27
+ # @!method null_double(node)
27
28
  def_node_search :null_double, <<-PATTERN
28
29
  (lvasgn $_
29
30
  (send
@@ -31,6 +32,7 @@ module RuboCop
31
32
  ...) :as_null_object))
32
33
  PATTERN
33
34
 
35
+ # @!method have_received_usage(node)
34
36
  def_node_search :have_received_usage, <<-PATTERN
35
37
  (send
36
38
  (send nil? :expect
@@ -52,10 +52,12 @@ module RuboCop
52
52
  MSG = 'Avoid instance variables – use let, ' \
53
53
  'a method call, or a local variable (if possible).'
54
54
 
55
+ # @!method dynamic_class?(node)
55
56
  def_node_matcher :dynamic_class?, <<-PATTERN
56
57
  (block (send (const nil? :Class) :new ...) ...)
57
58
  PATTERN
58
59
 
60
+ # @!method custom_matcher?(node)
59
61
  def_node_matcher :custom_matcher?, <<-PATTERN
60
62
  (block {
61
63
  (send nil? :matcher sym)
@@ -63,8 +65,10 @@ module RuboCop
63
65
  } ...)
64
66
  PATTERN
65
67
 
68
+ # @!method ivar_usage(node)
66
69
  def_node_search :ivar_usage, '$(ivar $_)'
67
70
 
71
+ # @!method ivar_assigned?(node)
68
72
  def_node_search :ivar_assigned?, '(ivasgn % ...)'
69
73
 
70
74
  def on_top_level_group(node)
@@ -26,6 +26,7 @@ module RuboCop
26
26
  'examples in a nested context.'
27
27
  RESTRICT_ON_SEND = %i[it_behaves_like it_should_behave_like].freeze
28
28
 
29
+ # @!method example_inclusion_offense(node)
29
30
  def_node_matcher :example_inclusion_offense, '(send _ % ...)'
30
31
 
31
32
  def on_send(node)
@@ -19,6 +19,7 @@ module RuboCop
19
19
  MSG = 'Prefer using the `all` matcher instead ' \
20
20
  'of iterating over an array.'
21
21
 
22
+ # @!method each?(node)
22
23
  def_node_matcher :each?, <<-PATTERN
23
24
  (block
24
25
  (send ... :each)
@@ -27,6 +28,7 @@ module RuboCop
27
28
  )
28
29
  PATTERN
29
30
 
31
+ # @!method expectation?(node)
30
32
  def_node_matcher :expectation?, <<-PATTERN
31
33
  (send (send nil? :expect (lvar %)) :to ...)
32
34
  PATTERN
@@ -46,6 +48,8 @@ module RuboCop
46
48
  end
47
49
 
48
50
  def only_expectations?(body, arg)
51
+ return false unless body.each_child_node.any?
52
+
49
53
  body.each_child_node.all? { |child| expectation?(child, arg) }
50
54
  end
51
55
  end
@@ -35,6 +35,7 @@ module RuboCop
35
35
 
36
36
  MSG = 'Move `let` before the examples in the group.'
37
37
 
38
+ # @!method example_or_group?(node)
38
39
  def_node_matcher :example_or_group?, <<-PATTERN
39
40
  {
40
41
  #{block_pattern('{#ExampleGroups.all #Examples.all}')}
@@ -28,6 +28,7 @@ module RuboCop
28
28
  class LetSetup < Base
29
29
  MSG = 'Do not use `let!` to setup objects not referenced in tests.'
30
30
 
31
+ # @!method example_or_shared_group_or_including?(node)
31
32
  def_node_matcher :example_or_shared_group_or_including?,
32
33
  block_pattern(<<~PATTERN)
33
34
  {
@@ -37,6 +38,7 @@ module RuboCop
37
38
  }
38
39
  PATTERN
39
40
 
41
+ # @!method let_bang(node)
40
42
  def_node_matcher :let_bang, <<-PATTERN
41
43
  {
42
44
  (block $(send nil? :let! {(sym $_) (str $_)}) ...)
@@ -44,6 +46,7 @@ module RuboCop
44
46
  }
45
47
  PATTERN
46
48
 
49
+ # @!method method_called?(node)
47
50
  def_node_search :method_called?, '(send nil? %)'
48
51
 
49
52
  def on_block(node)
@@ -32,10 +32,12 @@ module RuboCop
32
32
  SUPPORTED_STYLES = %w[allow expect].freeze
33
33
  RESTRICT_ON_SEND = %i[to].freeze
34
34
 
35
+ # @!method message_expectation(node)
35
36
  def_node_matcher :message_expectation, <<-PATTERN
36
37
  (send $(send nil? {:expect :allow} ...) :to #receive_message?)
37
38
  PATTERN
38
39
 
40
+ # @!method receive_message?(node)
39
41
  def_node_search :receive_message?, '(send nil? :receive ...)'
40
42
 
41
43
  def on_send(node)
@@ -35,10 +35,12 @@ module RuboCop
35
35
 
36
36
  SUPPORTED_STYLES = %w[have_received receive].freeze
37
37
 
38
+ # @!method message_expectation(node)
38
39
  def_node_matcher :message_expectation, %(
39
40
  (send (send nil? :expect $_) #Runners.all ...)
40
41
  )
41
42
 
43
+ # @!method receive_message(node)
42
44
  def_node_search :receive_message, %(
43
45
  $(send nil? {:receive :have_received} ...)
44
46
  )
@@ -10,6 +10,7 @@ module RuboCop
10
10
  Subjects = RuboCop::RSpec::Language::Subjects
11
11
  Helpers = RuboCop::RSpec::Language::Helpers
12
12
 
13
+ # @!method variable_definition?(node)
13
14
  def_node_matcher :variable_definition?, <<~PATTERN
14
15
  (send nil? {#Subjects.all #Helpers.all}
15
16
  $({sym str dsym dstr} ...) ...)
@@ -53,6 +53,7 @@ module RuboCop
53
53
  ANYTHING = ->(_node) { true }
54
54
  TRUE = ->(node) { node.true_type? }
55
55
 
56
+ # @!method aggregate_failures?(node)
56
57
  def_node_matcher :aggregate_failures?, <<-PATTERN
57
58
  (block {
58
59
  (send _ _ <(sym :aggregate_failures) ...>)
@@ -60,7 +61,9 @@ module RuboCop
60
61
  } ...)
61
62
  PATTERN
62
63
 
64
+ # @!method expect?(node)
63
65
  def_node_matcher :expect?, send_pattern('#Expectations.all')
66
+ # @!method aggregate_failures_block?(node)
64
67
  def_node_matcher :aggregate_failures_block?, <<-PATTERN
65
68
  (block (send nil? :aggregate_failures ...) ...)
66
69
  PATTERN
@@ -44,12 +44,15 @@ module RuboCop
44
44
  class NamedSubject < Base
45
45
  MSG = 'Name your test subject if you need to reference it explicitly.'
46
46
 
47
+ # @!method example_or_hook_block?(node)
47
48
  def_node_matcher :example_or_hook_block?,
48
49
  block_pattern('{#Examples.all #Hooks.all}')
49
50
 
51
+ # @!method shared_example?(node)
50
52
  def_node_matcher :shared_example?,
51
53
  block_pattern('#SharedGroups.examples')
52
54
 
55
+ # @!method subject_usage(node)
53
56
  def_node_search :subject_usage, '$(send nil? :subject)'
54
57
 
55
58
  def on_block(node)
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # Checks for nested example groups.
7
7
  #
8
8
  # This cop is configurable using the `Max` option
9
- # and supports `--auto-gen-config
9
+ # and supports `--auto-gen-config`.
10
10
  #
11
11
  # @example
12
12
  # # bad
@@ -22,6 +22,7 @@ module RuboCop
22
22
  MSG = 'Prefer `%<replacement>s` over `%<original>s`.'
23
23
  RESTRICT_ON_SEND = %i[not_to to_not].freeze
24
24
 
25
+ # @!method not_to_not_offense(node)
25
26
  def_node_matcher :not_to_not_offense, '(send _ % ...)'
26
27
 
27
28
  def on_send(node)
@@ -24,8 +24,10 @@ module RuboCop
24
24
  class OverwritingSetup < Base
25
25
  MSG = '`%<name>s` is already defined.'
26
26
 
27
+ # @!method setup?(node)
27
28
  def_node_matcher :setup?, block_pattern('{#Helpers.all #Subjects.all}')
28
29
 
30
+ # @!method first_argument_name(node)
29
31
  def_node_matcher :first_argument_name, '(send _ _ ({str sym} $_))'
30
32
 
31
33
  def on_block(node)
@@ -34,11 +34,13 @@ module RuboCop
34
34
  class Pending < Base
35
35
  MSG = 'Pending spec found.'
36
36
 
37
+ # @!method skippable?(node)
37
38
  def_node_matcher :skippable?,
38
39
  send_pattern(<<~PATTERN)
39
40
  {#ExampleGroups.regular #Examples.regular}
40
41
  PATTERN
41
42
 
43
+ # @!method skipped_in_metadata?(node)
42
44
  def_node_matcher :skipped_in_metadata?, <<-PATTERN
43
45
  {
44
46
  (send _ _ <#skip_or_pending? ...>)
@@ -46,8 +48,10 @@ module RuboCop
46
48
  }
47
49
  PATTERN
48
50
 
51
+ # @!method skip_or_pending?(node)
49
52
  def_node_matcher :skip_or_pending?, '{(sym :skip) (sym :pending)}'
50
53
 
54
+ # @!method pending_block?(node)
51
55
  def_node_matcher :pending_block?,
52
56
  send_pattern(<<~PATTERN)
53
57
  {