rubocop-rspec 2.21.0 → 3.0.1

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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +147 -9
  3. data/README.md +2 -2
  4. data/config/default.yml +159 -244
  5. data/config/obsoletion.yml +24 -0
  6. data/lib/rubocop/cop/rspec/around_block.rb +3 -3
  7. data/lib/rubocop/cop/rspec/base.rb +0 -1
  8. data/lib/rubocop/cop/rspec/be.rb +1 -1
  9. data/lib/rubocop/cop/rspec/be_empty.rb +1 -0
  10. data/lib/rubocop/cop/rspec/be_eq.rb +1 -1
  11. data/lib/rubocop/cop/rspec/be_eql.rb +1 -1
  12. data/lib/rubocop/cop/rspec/be_nil.rb +2 -2
  13. data/lib/rubocop/cop/rspec/before_after_all.rb +7 -13
  14. data/lib/rubocop/cop/rspec/change_by_zero.rb +30 -4
  15. data/lib/rubocop/cop/rspec/context_method.rb +2 -2
  16. data/lib/rubocop/cop/rspec/context_wording.rb +1 -1
  17. data/lib/rubocop/cop/rspec/describe_symbol.rb +1 -1
  18. data/lib/rubocop/cop/rspec/described_class.rb +33 -11
  19. data/lib/rubocop/cop/rspec/dialect.rb +13 -0
  20. data/lib/rubocop/cop/rspec/duplicated_metadata.rb +1 -1
  21. data/lib/rubocop/cop/rspec/empty_example_group.rb +4 -1
  22. data/lib/rubocop/cop/rspec/empty_hook.rb +1 -1
  23. data/lib/rubocop/cop/rspec/empty_line_after_example.rb +2 -2
  24. data/lib/rubocop/cop/rspec/empty_metadata.rb +46 -0
  25. data/lib/rubocop/cop/rspec/empty_output.rb +47 -0
  26. data/lib/rubocop/cop/rspec/eq.rb +47 -0
  27. data/lib/rubocop/cop/rspec/example_length.rb +11 -5
  28. data/lib/rubocop/cop/rspec/example_without_description.rb +11 -2
  29. data/lib/rubocop/cop/rspec/example_wording.rb +11 -2
  30. data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +14 -5
  31. data/lib/rubocop/cop/rspec/expect_actual.rb +17 -14
  32. data/lib/rubocop/cop/rspec/expect_change.rb +2 -2
  33. data/lib/rubocop/cop/rspec/expect_in_hook.rb +1 -1
  34. data/lib/rubocop/cop/rspec/expect_in_let.rb +42 -0
  35. data/lib/rubocop/cop/rspec/expect_output.rb +1 -4
  36. data/lib/rubocop/cop/rspec/focus.rb +17 -2
  37. data/lib/rubocop/cop/rspec/hook_argument.rb +2 -2
  38. data/lib/rubocop/cop/rspec/hooks_before_examples.rb +1 -1
  39. data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +2 -2
  40. data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -1
  41. data/lib/rubocop/cop/rspec/implicit_subject.rb +2 -2
  42. data/lib/rubocop/cop/rspec/indexed_let.rb +32 -1
  43. data/lib/rubocop/cop/rspec/instance_spy.rb +2 -2
  44. data/lib/rubocop/cop/rspec/instance_variable.rb +4 -4
  45. data/lib/rubocop/cop/rspec/is_expected_specify.rb +45 -0
  46. data/lib/rubocop/cop/rspec/iterated_expectation.rb +3 -3
  47. data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +2 -2
  48. data/lib/rubocop/cop/rspec/let_before_examples.rb +5 -1
  49. data/lib/rubocop/cop/rspec/let_setup.rb +1 -1
  50. data/lib/rubocop/cop/rspec/message_expectation.rb +1 -2
  51. data/lib/rubocop/cop/rspec/message_spies.rb +0 -2
  52. data/lib/rubocop/cop/rspec/metadata_style.rb +202 -0
  53. data/lib/rubocop/cop/rspec/missing_expectation_target_method.rb +54 -0
  54. data/lib/rubocop/cop/rspec/mixin/file_help.rb +14 -0
  55. data/lib/rubocop/cop/rspec/mixin/metadata.rb +21 -7
  56. data/lib/rubocop/cop/rspec/mixin/skip_or_pending.rb +2 -2
  57. data/lib/rubocop/cop/rspec/multiple_describes.rb +1 -1
  58. data/lib/rubocop/cop/rspec/multiple_expectations.rb +16 -11
  59. data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +2 -4
  60. data/lib/rubocop/cop/rspec/named_subject.rb +6 -3
  61. data/lib/rubocop/cop/rspec/pending.rb +12 -2
  62. data/lib/rubocop/cop/rspec/pending_without_reason.rb +1 -1
  63. data/lib/rubocop/cop/rspec/predicate_matcher.rb +10 -10
  64. data/lib/rubocop/cop/rspec/receive_counts.rb +1 -1
  65. data/lib/rubocop/cop/rspec/receive_messages.rb +161 -0
  66. data/lib/rubocop/cop/rspec/redundant_predicate_matcher.rb +67 -0
  67. data/lib/rubocop/cop/rspec/remove_const.rb +39 -0
  68. data/lib/rubocop/cop/rspec/repeated_example.rb +6 -6
  69. data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +1 -1
  70. data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +2 -2
  71. data/lib/rubocop/cop/rspec/repeated_include_example.rb +1 -1
  72. data/lib/rubocop/cop/rspec/repeated_subject_call.rb +125 -0
  73. data/lib/rubocop/cop/rspec/return_from_stub.rb +1 -1
  74. data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
  75. data/lib/rubocop/cop/rspec/shared_context.rb +1 -1
  76. data/lib/rubocop/cop/rspec/shared_examples.rb +66 -20
  77. data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +2 -3
  78. data/lib/rubocop/cop/rspec/sort_metadata.rb +3 -2
  79. data/lib/rubocop/cop/rspec/spec_file_path_format.rb +133 -0
  80. data/lib/rubocop/cop/rspec/spec_file_path_suffix.rb +40 -0
  81. data/lib/rubocop/cop/rspec/stubbed_mock.rb +4 -2
  82. data/lib/rubocop/cop/rspec/subject_stub.rb +6 -6
  83. data/lib/rubocop/cop/rspec/undescriptive_literals_description.rb +69 -0
  84. data/lib/rubocop/cop/rspec/unspecified_exception.rb +2 -2
  85. data/lib/rubocop/cop/rspec/variable_definition.rb +4 -4
  86. data/lib/rubocop/cop/rspec/verified_double_reference.rb +6 -6
  87. data/lib/rubocop/cop/rspec/verified_doubles.rb +2 -2
  88. data/lib/rubocop/cop/rspec/void_expect.rb +4 -3
  89. data/lib/rubocop/cop/rspec_cops.rb +14 -28
  90. data/lib/rubocop/rspec/concept.rb +0 -1
  91. data/lib/rubocop/rspec/config_formatter.rb +1 -11
  92. data/lib/rubocop/rspec/cop/generator.rb +25 -0
  93. data/lib/rubocop/rspec/language.rb +8 -9
  94. data/lib/rubocop/rspec/node.rb +1 -1
  95. data/lib/rubocop/rspec/shared_contexts/default_rspec_language_config_context.rb +1 -1
  96. data/lib/rubocop/rspec/version.rb +1 -1
  97. data/lib/rubocop/rspec/wording.rb +8 -0
  98. data/lib/rubocop-rspec.rb +2 -16
  99. metadata +27 -49
  100. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +0 -39
  101. data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +0 -104
  102. data/lib/rubocop/cop/rspec/capybara/match_style.rb +0 -38
  103. data/lib/rubocop/cop/rspec/capybara/negation_matcher.rb +0 -33
  104. data/lib/rubocop/cop/rspec/capybara/specific_actions.rb +0 -29
  105. data/lib/rubocop/cop/rspec/capybara/specific_finders.rb +0 -24
  106. data/lib/rubocop/cop/rspec/capybara/specific_matcher.rb +0 -35
  107. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +0 -36
  108. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +0 -128
  109. data/lib/rubocop/cop/rspec/factory_bot/consistent_parentheses_style.rb +0 -117
  110. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +0 -260
  111. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +0 -56
  112. data/lib/rubocop/cop/rspec/factory_bot/factory_name_style.rb +0 -74
  113. data/lib/rubocop/cop/rspec/factory_bot/syntax_methods.rb +0 -89
  114. data/lib/rubocop/cop/rspec/file_path.rb +0 -173
  115. data/lib/rubocop/cop/rspec/rails/avoid_setup_hook.rb +0 -43
  116. data/lib/rubocop/cop/rspec/rails/have_http_status.rb +0 -55
  117. data/lib/rubocop/cop/rspec/rails/http_status.rb +0 -203
  118. data/lib/rubocop/cop/rspec/rails/inferred_spec_type.rb +0 -145
  119. data/lib/rubocop/cop/rspec/rails/minitest_assertions.rb +0 -60
  120. data/lib/rubocop/cop/rspec/rails/travel_around.rb +0 -92
  121. data/lib/rubocop/rspec/factory_bot/language.rb +0 -37
  122. data/lib/rubocop/rspec/factory_bot.rb +0 -64
  123. data/lib/rubocop/rspec/language/node_pattern.rb +0 -48
@@ -1,128 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module RSpec
6
- module FactoryBot
7
- # Always declare attribute values as blocks.
8
- #
9
- # @example
10
- # # bad
11
- # kind [:active, :rejected].sample
12
- #
13
- # # good
14
- # kind { [:active, :rejected].sample }
15
- #
16
- # # bad
17
- # closed_at 1.day.from_now
18
- #
19
- # # good
20
- # closed_at { 1.day.from_now }
21
- #
22
- # # bad
23
- # count 1
24
- #
25
- # # good
26
- # count { 1 }
27
- #
28
- class AttributeDefinedStatically < ::RuboCop::Cop::Base
29
- extend AutoCorrector
30
-
31
- MSG = 'Use a block to declare attribute values.'
32
-
33
- # @!method value_matcher(node)
34
- def_node_matcher :value_matcher, <<-PATTERN
35
- (send _ !#reserved_method? $...)
36
- PATTERN
37
-
38
- # @!method factory_attributes(node)
39
- def_node_matcher :factory_attributes, <<-PATTERN
40
- (block (send _ #attribute_defining_method? ...) _ { (begin $...) $(send ...) } )
41
- PATTERN
42
-
43
- def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
44
- attributes = factory_attributes(node) || []
45
- attributes = [attributes] unless attributes.is_a?(Array) # rubocop:disable Style/ArrayCoercion, Lint/RedundantCopDisableDirective
46
-
47
- attributes.each do |attribute|
48
- next unless offensive_receiver?(attribute.receiver, node)
49
- next if proc?(attribute) || association?(attribute.first_argument)
50
-
51
- add_offense(attribute) do |corrector|
52
- autocorrect(corrector, attribute)
53
- end
54
- end
55
- end
56
-
57
- private
58
-
59
- def autocorrect(corrector, node)
60
- if node.parenthesized?
61
- autocorrect_replacing_parens(corrector, node)
62
- else
63
- autocorrect_without_parens(corrector, node)
64
- end
65
- end
66
-
67
- def offensive_receiver?(receiver, node)
68
- receiver.nil? ||
69
- receiver.self_type? ||
70
- receiver_matches_first_block_argument?(receiver, node)
71
- end
72
-
73
- def receiver_matches_first_block_argument?(receiver, node)
74
- first_block_argument = node.arguments.first
75
-
76
- !first_block_argument.nil? &&
77
- receiver.lvar_type? &&
78
- receiver.node_parts == first_block_argument.node_parts
79
- end
80
-
81
- def proc?(attribute)
82
- value_matcher(attribute).to_a.all?(&:block_pass_type?)
83
- end
84
-
85
- # @!method association?(node)
86
- def_node_matcher :association?, '(hash <(pair (sym :factory) _) ...>)'
87
-
88
- def autocorrect_replacing_parens(corrector, node)
89
- left_braces, right_braces = braces(node)
90
-
91
- corrector.replace(node.location.begin, " #{left_braces}")
92
- corrector.replace(node.location.end, right_braces)
93
- end
94
-
95
- def autocorrect_without_parens(corrector, node)
96
- left_braces, right_braces = braces(node)
97
-
98
- argument = node.first_argument
99
- expression = argument.source_range
100
- corrector.insert_before(expression, left_braces)
101
- corrector.insert_after(expression, right_braces)
102
- end
103
-
104
- def braces(node)
105
- if value_hash_without_braces?(node.first_argument)
106
- ['{ { ', ' } }']
107
- else
108
- ['{ ', ' }']
109
- end
110
- end
111
-
112
- def value_hash_without_braces?(node)
113
- node.hash_type? && !node.braces?
114
- end
115
-
116
- def reserved_method?(method_name)
117
- RuboCop::RSpec::FactoryBot.reserved_methods.include?(method_name)
118
- end
119
-
120
- def attribute_defining_method?(method_name)
121
- RuboCop::RSpec::FactoryBot.attribute_defining_methods
122
- .include?(method_name)
123
- end
124
- end
125
- end
126
- end
127
- end
128
- end
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module RSpec
6
- module FactoryBot
7
- # Use a consistent style for parentheses in factory bot calls.
8
- #
9
- # @example
10
- #
11
- # # bad
12
- # create :user
13
- # build(:user)
14
- # create(:login)
15
- # create :login
16
- #
17
- # @example `EnforcedStyle: require_parentheses` (default)
18
- #
19
- # # good
20
- # create(:user)
21
- # create(:user)
22
- # create(:login)
23
- # build(:login)
24
- #
25
- # @example `EnforcedStyle: omit_parentheses`
26
- #
27
- # # good
28
- # create :user
29
- # build :user
30
- # create :login
31
- # create :login
32
- #
33
- # # also good
34
- # # when method name and first argument are not on same line
35
- # create(
36
- # :user
37
- # )
38
- # build(
39
- # :user,
40
- # name: 'foo'
41
- # )
42
- #
43
- class ConsistentParenthesesStyle < ::RuboCop::Cop::Base
44
- extend AutoCorrector
45
- include ConfigurableEnforcedStyle
46
- include RuboCop::RSpec::FactoryBot::Language
47
- include RuboCop::Cop::Util
48
-
49
- def self.autocorrect_incompatible_with
50
- [Style::MethodCallWithArgsParentheses]
51
- end
52
-
53
- MSG_REQUIRE_PARENS = 'Prefer method call with parentheses'
54
- MSG_OMIT_PARENS = 'Prefer method call without parentheses'
55
-
56
- FACTORY_CALLS = RuboCop::RSpec::FactoryBot::Language::METHODS
57
-
58
- RESTRICT_ON_SEND = FACTORY_CALLS
59
-
60
- # @!method factory_call(node)
61
- def_node_matcher :factory_call, <<-PATTERN
62
- (send
63
- {#factory_bot? nil?} %FACTORY_CALLS
64
- {sym str send lvar} _*
65
- )
66
- PATTERN
67
-
68
- def on_send(node)
69
- return if ambiguous_without_parentheses?(node)
70
-
71
- factory_call(node) do
72
- return if node.method?(:generate) && node.arguments.count > 1
73
-
74
- if node.parenthesized?
75
- process_with_parentheses(node)
76
- else
77
- process_without_parentheses(node)
78
- end
79
- end
80
- end
81
-
82
- private
83
-
84
- def process_with_parentheses(node)
85
- return unless style == :omit_parentheses
86
- return unless same_line?(node, node.first_argument)
87
-
88
- add_offense(node.loc.selector,
89
- message: MSG_OMIT_PARENS) do |corrector|
90
- remove_parentheses(corrector, node)
91
- end
92
- end
93
-
94
- def process_without_parentheses(node)
95
- return unless style == :require_parentheses
96
-
97
- add_offense(node.loc.selector,
98
- message: MSG_REQUIRE_PARENS) do |corrector|
99
- add_parentheses(node, corrector)
100
- end
101
- end
102
-
103
- AMBIGUOUS_TYPES = %i[send pair array and or if].freeze
104
-
105
- def ambiguous_without_parentheses?(node)
106
- node.parent && AMBIGUOUS_TYPES.include?(node.parent.type)
107
- end
108
-
109
- def remove_parentheses(corrector, node)
110
- corrector.replace(node.location.begin, ' ')
111
- corrector.remove(node.location.end)
112
- end
113
- end
114
- end
115
- end
116
- end
117
- end
@@ -1,260 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module RSpec
6
- module FactoryBot
7
- # Checks for create_list usage.
8
- #
9
- # This cop can be configured using the `EnforcedStyle` option
10
- #
11
- # @example `EnforcedStyle: create_list` (default)
12
- # # bad
13
- # 3.times { create :user }
14
- #
15
- # # good
16
- # create_list :user, 3
17
- #
18
- # # bad
19
- # 3.times { create :user, age: 18 }
20
- #
21
- # # good - index is used to alter the created models attributes
22
- # 3.times { |n| create :user, age: n }
23
- #
24
- # # good - contains a method call, may return different values
25
- # 3.times { create :user, age: rand }
26
- #
27
- # @example `EnforcedStyle: n_times`
28
- # # bad
29
- # create_list :user, 3
30
- #
31
- # # good
32
- # 3.times { create :user }
33
- #
34
- class CreateList < ::RuboCop::Cop::Base
35
- extend AutoCorrector
36
- include ConfigurableEnforcedStyle
37
- include RuboCop::RSpec::FactoryBot::Language
38
-
39
- MSG_CREATE_LIST = 'Prefer create_list.'
40
- MSG_N_TIMES = 'Prefer %<number>s.times.'
41
- RESTRICT_ON_SEND = %i[create_list].freeze
42
-
43
- # @!method array_new_or_n_times_block?(node)
44
- def_node_matcher :array_new_or_n_times_block?, <<-PATTERN
45
- (block
46
- {
47
- (send (const {nil? | cbase} :Array) :new (int _)) |
48
- (send (int _) :times)
49
- }
50
- ...
51
- )
52
- PATTERN
53
-
54
- # @!method block_with_arg_and_used?(node)
55
- def_node_matcher :block_with_arg_and_used?, <<-PATTERN
56
- (block
57
- _
58
- (args (arg _value))
59
- `_value
60
- )
61
- PATTERN
62
-
63
- # @!method arguments_include_method_call?(node)
64
- def_node_matcher :arguments_include_method_call?, <<-PATTERN
65
- (send ${nil? #factory_bot?} :create (sym $_) `$(send ...))
66
- PATTERN
67
-
68
- # @!method factory_call(node)
69
- def_node_matcher :factory_call, <<-PATTERN
70
- (send ${nil? #factory_bot?} :create (sym $_) $...)
71
- PATTERN
72
-
73
- # @!method factory_list_call(node)
74
- def_node_matcher :factory_list_call, <<-PATTERN
75
- (send {nil? #factory_bot?} :create_list (sym _) (int $_) ...)
76
- PATTERN
77
-
78
- def on_block(node) # rubocop:todo InternalAffairs/NumblockHandler
79
- return unless style == :create_list
80
-
81
- return unless array_new_or_n_times_block?(node)
82
- return if block_with_arg_and_used?(node)
83
- return unless node.body
84
- return if arguments_include_method_call?(node.body)
85
- return unless contains_only_factory?(node.body)
86
-
87
- add_offense(node.send_node, message: MSG_CREATE_LIST) do |corrector|
88
- CreateListCorrector.new(node.send_node).call(corrector)
89
- end
90
- end
91
-
92
- def on_send(node)
93
- return unless style == :n_times
94
-
95
- factory_list_call(node) do |count|
96
- message = format(MSG_N_TIMES, number: count)
97
- add_offense(node.loc.selector, message: message) do |corrector|
98
- TimesCorrector.new(node).call(corrector)
99
- end
100
- end
101
- end
102
-
103
- private
104
-
105
- def contains_only_factory?(node)
106
- if node.block_type?
107
- factory_call(node.send_node)
108
- else
109
- factory_call(node)
110
- end
111
- end
112
-
113
- # :nodoc
114
- module Corrector
115
- private
116
-
117
- def build_options_string(options)
118
- options.map(&:source).join(', ')
119
- end
120
-
121
- def format_method_call(node, method, arguments)
122
- if node.block_type? || node.parenthesized?
123
- "#{method}(#{arguments})"
124
- else
125
- "#{method} #{arguments}"
126
- end
127
- end
128
-
129
- def format_receiver(receiver)
130
- return '' unless receiver
131
-
132
- "#{receiver.source}."
133
- end
134
- end
135
-
136
- # :nodoc
137
- class TimesCorrector
138
- include Corrector
139
-
140
- def initialize(node)
141
- @node = node
142
- end
143
-
144
- def call(corrector)
145
- replacement = generate_n_times_block(node)
146
- corrector.replace(node.block_node || node, replacement)
147
- end
148
-
149
- private
150
-
151
- attr_reader :node
152
-
153
- def generate_n_times_block(node)
154
- factory, count, *options = node.arguments
155
-
156
- arguments = factory.source
157
- options = build_options_string(options)
158
- arguments += ", #{options}" unless options.empty?
159
-
160
- replacement = format_receiver(node.receiver)
161
- replacement += format_method_call(node, 'create', arguments)
162
- replacement += " #{factory_call_block_source}" if node.block_node
163
- "#{count.source}.times { #{replacement} }"
164
- end
165
-
166
- def factory_call_block_source
167
- node.block_node.location.begin.with(
168
- end_pos: node.block_node.location.end.end_pos
169
- ).source
170
- end
171
- end
172
-
173
- # :nodoc:
174
- class CreateListCorrector
175
- include Corrector
176
-
177
- def initialize(node)
178
- @node = node.parent
179
- end
180
-
181
- def call(corrector)
182
- replacement = if node.body.block_type?
183
- call_with_block_replacement(node)
184
- else
185
- call_replacement(node)
186
- end
187
-
188
- corrector.replace(node, replacement)
189
- end
190
-
191
- private
192
-
193
- attr_reader :node
194
-
195
- def call_with_block_replacement(node)
196
- block = node.body
197
- arguments = build_arguments(block, count_from(node))
198
- replacement = format_receiver(block.receiver)
199
- replacement += format_method_call(block, 'create_list', arguments)
200
- replacement += format_block(block)
201
- replacement
202
- end
203
-
204
- def build_arguments(node, count)
205
- factory, *options = *node.send_node.arguments
206
-
207
- arguments = ":#{factory.value}, #{count}"
208
- options = build_options_string(options)
209
- arguments += ", #{options}" unless options.empty?
210
- arguments
211
- end
212
-
213
- def call_replacement(node)
214
- block = node.body
215
- factory, *options = *block.arguments
216
-
217
- arguments = "#{factory.source}, #{count_from(node)}"
218
- options = build_options_string(options)
219
- arguments += ", #{options}" unless options.empty?
220
-
221
- replacement = format_receiver(block.receiver)
222
- replacement += format_method_call(block, 'create_list', arguments)
223
- replacement
224
- end
225
-
226
- def count_from(node)
227
- count_node =
228
- if node.receiver.int_type?
229
- node.receiver
230
- else
231
- node.send_node.first_argument
232
- end
233
- count_node.source
234
- end
235
-
236
- def format_block(node)
237
- if node.body.begin_type?
238
- format_multiline_block(node)
239
- else
240
- format_singleline_block(node)
241
- end
242
- end
243
-
244
- def format_multiline_block(node)
245
- indent = ' ' * node.body.loc.column
246
- indent_end = ' ' * node.parent.loc.column
247
- " do #{node.arguments.source}\n" \
248
- "#{indent}#{node.body.source}\n" \
249
- "#{indent_end}end"
250
- end
251
-
252
- def format_singleline_block(node)
253
- " { #{node.arguments.source} #{node.body.source} }"
254
- end
255
- end
256
- end
257
- end
258
- end
259
- end
260
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module RSpec
6
- module FactoryBot
7
- # Use string value when setting the class attribute explicitly.
8
- #
9
- # This cop would promote faster tests by lazy-loading of
10
- # application files. Also, this could help you suppress potential bugs
11
- # in combination with external libraries by avoiding a preload of
12
- # application files from the factory files.
13
- #
14
- # @example
15
- # # bad
16
- # factory :foo, class: Foo do
17
- # end
18
- #
19
- # # good
20
- # factory :foo, class: 'Foo' do
21
- # end
22
- #
23
- class FactoryClassName < ::RuboCop::Cop::Base
24
- extend AutoCorrector
25
-
26
- MSG = "Pass '%<class_name>s' string instead of `%<class_name>s` " \
27
- 'constant.'
28
- ALLOWED_CONSTANTS = %w[Hash OpenStruct].freeze
29
- RESTRICT_ON_SEND = %i[factory].freeze
30
-
31
- # @!method class_name(node)
32
- def_node_matcher :class_name, <<~PATTERN
33
- (send _ :factory _ (hash <(pair (sym :class) $(const ...)) ...>))
34
- PATTERN
35
-
36
- def on_send(node)
37
- class_name(node) do |cn|
38
- next if allowed?(cn.const_name)
39
-
40
- msg = format(MSG, class_name: cn.const_name)
41
- add_offense(cn, message: msg) do |corrector|
42
- corrector.replace(cn, "'#{cn.source}'")
43
- end
44
- end
45
- end
46
-
47
- private
48
-
49
- def allowed?(const_name)
50
- ALLOWED_CONSTANTS.include?(const_name)
51
- end
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module RSpec
6
- module FactoryBot
7
- # Checks for name style for argument of FactoryBot::Syntax::Methods.
8
- #
9
- # @example EnforcedStyle: symbol (default)
10
- # # bad
11
- # create('user')
12
- # build "user", username: "NAME"
13
- #
14
- # # good
15
- # create(:user)
16
- # build :user, username: "NAME"
17
- #
18
- # @example EnforcedStyle: string
19
- # # bad
20
- # create(:user)
21
- # build :user, username: "NAME"
22
- #
23
- # # good
24
- # create('user')
25
- # build "user", username: "NAME"
26
- #
27
- class FactoryNameStyle < ::RuboCop::Cop::Base
28
- extend AutoCorrector
29
- include ConfigurableEnforcedStyle
30
- include RuboCop::RSpec::FactoryBot::Language
31
-
32
- MSG = 'Use %<prefer>s to refer to a factory.'
33
- FACTORY_CALLS = RuboCop::RSpec::FactoryBot::Language::METHODS
34
- RESTRICT_ON_SEND = FACTORY_CALLS
35
-
36
- # @!method factory_call(node)
37
- def_node_matcher :factory_call, <<-PATTERN
38
- (send
39
- {#factory_bot? nil?} %FACTORY_CALLS
40
- ${str sym} ...
41
- )
42
- PATTERN
43
-
44
- def on_send(node)
45
- factory_call(node) do |name|
46
- if offense_for_symbol_style?(name)
47
- register_offense(name, name.value.to_sym.inspect)
48
- elsif offense_for_string_style?(name)
49
- register_offense(name, name.value.to_s.inspect)
50
- end
51
- end
52
- end
53
-
54
- private
55
-
56
- def offense_for_symbol_style?(name)
57
- name.str_type? && style == :symbol
58
- end
59
-
60
- def offense_for_string_style?(name)
61
- name.sym_type? && style == :string
62
- end
63
-
64
- def register_offense(name, prefer)
65
- add_offense(name,
66
- message: format(MSG, prefer: style.to_s)) do |corrector|
67
- corrector.replace(name, prefer)
68
- end
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end