rubocop-rspec 2.2.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
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
  {