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
@@ -2,72 +2,215 @@
|
|
2
2
|
|
3
3
|
module RuboCop
|
4
4
|
module RSpec
|
5
|
-
#
|
5
|
+
# Contains node matchers for common RSpec DSL.
|
6
|
+
#
|
7
|
+
# RSpec allows for configuring aliases for commonly used DSL elements, e.g.
|
8
|
+
# example groups and hooks. It is possible to configure RuboCop RSpec to
|
9
|
+
# be able to properly detect these elements in the `RSpec/Language` section
|
10
|
+
# of the RuboCop YAML configuration file.
|
11
|
+
#
|
12
|
+
# In addition to providing useful matchers, this class is responsible for
|
13
|
+
# using the configured aliases.
|
6
14
|
module Language
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
15
|
+
extend RuboCop::NodePattern::Macros
|
16
|
+
|
17
|
+
class << self
|
18
|
+
attr_accessor :config
|
19
|
+
end
|
20
|
+
|
21
|
+
# @!method rspec?(node)
|
22
|
+
def_node_matcher :rspec?, '{#explicit_rspec? nil?}'
|
23
|
+
|
24
|
+
# @!method explicit_rspec?(node)
|
25
|
+
def_node_matcher :explicit_rspec?, '(const {nil? cbase} :RSpec)'
|
26
|
+
|
27
|
+
# @!method example_group?(node)
|
28
|
+
def_node_matcher :example_group?, <<~PATTERN
|
29
|
+
({block numblock} (send #rspec? #ExampleGroups.all ...) ...)
|
30
|
+
PATTERN
|
31
|
+
|
32
|
+
# @!method shared_group?(node)
|
33
|
+
def_node_matcher :shared_group?,
|
34
|
+
'(block (send #rspec? #SharedGroups.all ...) ...)'
|
35
|
+
|
36
|
+
# @!method spec_group?(node)
|
37
|
+
def_node_matcher :spec_group?, <<~PATTERN
|
38
|
+
({block numblock} (send #rspec?
|
39
|
+
{#SharedGroups.all #ExampleGroups.all}
|
40
|
+
...) ...)
|
41
|
+
PATTERN
|
42
|
+
|
43
|
+
# @!method example_group_with_body?(node)
|
44
|
+
def_node_matcher :example_group_with_body?, <<~PATTERN
|
45
|
+
(block (send #rspec? #ExampleGroups.all ...) args !nil?)
|
46
|
+
PATTERN
|
12
47
|
|
13
|
-
|
14
|
-
|
48
|
+
# @!method example?(node)
|
49
|
+
def_node_matcher :example?, '(block (send nil? #Examples.all ...) ...)'
|
50
|
+
|
51
|
+
# @!method hook?(node)
|
52
|
+
def_node_matcher :hook?, <<~PATTERN
|
53
|
+
{
|
54
|
+
(numblock (send nil? #Hooks.all ...) ...)
|
55
|
+
(block (send nil? #Hooks.all ...) ...)
|
56
|
+
}
|
57
|
+
PATTERN
|
58
|
+
|
59
|
+
# @!method let?(node)
|
60
|
+
def_node_matcher :let?, <<~PATTERN
|
61
|
+
{
|
62
|
+
(block (send nil? #Helpers.all ...) ...)
|
63
|
+
(send nil? #Helpers.all _ block_pass)
|
64
|
+
}
|
65
|
+
PATTERN
|
66
|
+
|
67
|
+
# @!method include?(node)
|
68
|
+
def_node_matcher :include?, <<~PATTERN
|
69
|
+
{
|
70
|
+
(block (send nil? #Includes.all ...) ...)
|
71
|
+
(send nil? #Includes.all ...)
|
72
|
+
}
|
73
|
+
PATTERN
|
74
|
+
|
75
|
+
# @!method subject?(node)
|
76
|
+
def_node_matcher :subject?, '(block (send nil? #Subjects.all ...) ...)'
|
77
|
+
|
78
|
+
module ExampleGroups # :nodoc:
|
79
|
+
class << self
|
80
|
+
def all(element)
|
81
|
+
regular(element) ||
|
82
|
+
skipped(element) ||
|
83
|
+
focused(element)
|
84
|
+
end
|
85
|
+
|
86
|
+
def regular(element)
|
87
|
+
Language.config['ExampleGroups']['Regular'].include?(element.to_s)
|
88
|
+
end
|
89
|
+
|
90
|
+
def focused(element)
|
91
|
+
Language.config['ExampleGroups']['Focused'].include?(element.to_s)
|
92
|
+
end
|
93
|
+
|
94
|
+
def skipped(element)
|
95
|
+
Language.config['ExampleGroups']['Skipped'].include?(element.to_s)
|
96
|
+
end
|
15
97
|
end
|
98
|
+
end
|
16
99
|
|
17
|
-
|
18
|
-
|
100
|
+
module Examples # :nodoc:
|
101
|
+
class << self
|
102
|
+
def all(element)
|
103
|
+
regular(element) ||
|
104
|
+
focused(element) ||
|
105
|
+
skipped(element) ||
|
106
|
+
pending(element)
|
107
|
+
end
|
108
|
+
|
109
|
+
def regular(element)
|
110
|
+
Language.config['Examples']['Regular'].include?(element.to_s)
|
111
|
+
end
|
112
|
+
|
113
|
+
def focused(element)
|
114
|
+
Language.config['Examples']['Focused'].include?(element.to_s)
|
115
|
+
end
|
116
|
+
|
117
|
+
def skipped(element)
|
118
|
+
Language.config['Examples']['Skipped'].include?(element.to_s)
|
119
|
+
end
|
120
|
+
|
121
|
+
def pending(element)
|
122
|
+
Language.config['Examples']['Pending'].include?(element.to_s)
|
123
|
+
end
|
19
124
|
end
|
125
|
+
end
|
20
126
|
|
21
|
-
|
22
|
-
|
127
|
+
module Expectations # :nodoc:
|
128
|
+
def self.all(element)
|
129
|
+
Language.config['Expectations'].include?(element.to_s)
|
23
130
|
end
|
131
|
+
end
|
24
132
|
|
25
|
-
|
26
|
-
|
133
|
+
module Helpers # :nodoc:
|
134
|
+
def self.all(element)
|
135
|
+
Language.config['Helpers'].include?(element.to_s)
|
27
136
|
end
|
137
|
+
end
|
28
138
|
|
29
|
-
|
139
|
+
module Hooks # :nodoc:
|
140
|
+
def self.all(element)
|
141
|
+
Language.config['Hooks'].include?(element.to_s)
|
142
|
+
end
|
143
|
+
end
|
30
144
|
|
31
|
-
|
145
|
+
module HookScopes # :nodoc:
|
146
|
+
ALL = %i[each example context all suite].freeze
|
147
|
+
def self.all(element)
|
148
|
+
ALL.include?(element)
|
149
|
+
end
|
32
150
|
end
|
33
151
|
|
34
|
-
module
|
35
|
-
|
36
|
-
|
37
|
-
|
152
|
+
module Includes # :nodoc:
|
153
|
+
class << self
|
154
|
+
def all(element)
|
155
|
+
examples(element) ||
|
156
|
+
context(element)
|
157
|
+
end
|
158
|
+
|
159
|
+
def examples(element)
|
160
|
+
Language.config['Includes']['Examples'].include?(element.to_s)
|
161
|
+
end
|
38
162
|
|
39
|
-
|
163
|
+
def context(element)
|
164
|
+
Language.config['Includes']['Context'].include?(element.to_s)
|
165
|
+
end
|
166
|
+
end
|
40
167
|
end
|
41
168
|
|
42
|
-
module
|
43
|
-
ALL =
|
44
|
-
|
45
|
-
|
169
|
+
module Runners # :nodoc:
|
170
|
+
ALL = %i[to to_not not_to].freeze
|
171
|
+
class << self
|
172
|
+
def all(element = nil)
|
173
|
+
return ALL if element.nil?
|
174
|
+
|
175
|
+
ALL.include?(element)
|
176
|
+
end
|
177
|
+
end
|
46
178
|
end
|
47
179
|
|
48
|
-
module
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
180
|
+
module SharedGroups # :nodoc:
|
181
|
+
class << self
|
182
|
+
def all(element)
|
183
|
+
examples(element) ||
|
184
|
+
context(element)
|
185
|
+
end
|
53
186
|
|
54
|
-
|
187
|
+
def examples(element)
|
188
|
+
Language.config['SharedGroups']['Examples'].include?(element.to_s)
|
189
|
+
end
|
190
|
+
|
191
|
+
def context(element)
|
192
|
+
Language.config['SharedGroups']['Context'].include?(element.to_s)
|
193
|
+
end
|
194
|
+
end
|
55
195
|
end
|
56
196
|
|
57
|
-
module
|
58
|
-
|
197
|
+
module Subjects # :nodoc:
|
198
|
+
def self.all(element)
|
199
|
+
Language.config['Subjects'].include?(element.to_s)
|
200
|
+
end
|
59
201
|
end
|
60
202
|
|
61
|
-
|
62
|
-
|
203
|
+
# This is used in Dialect and DescribeClass cops to detect RSpec blocks.
|
204
|
+
module ALL # :nodoc:
|
205
|
+
def self.all(element)
|
206
|
+
[ExampleGroups, Examples, Expectations, Helpers, Hooks, Includes,
|
207
|
+
Runners, SharedGroups, Subjects]
|
208
|
+
.find { |concept| concept.all(element) }
|
209
|
+
end
|
63
210
|
end
|
64
211
|
|
65
|
-
|
66
|
-
|
67
|
-
SharedGroups::ALL +
|
68
|
-
Examples::ALL +
|
69
|
-
Hooks::ALL +
|
70
|
-
Helpers::ALL
|
212
|
+
private_constant :ExampleGroups, :Examples, :Expectations, :Hooks,
|
213
|
+
:Includes, :Runners, :SharedGroups, :ALL
|
71
214
|
end
|
72
215
|
end
|
73
216
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module RSpec
|
5
|
+
# RuboCop RSpec specific extensions of RuboCop::AST::Node
|
6
|
+
module Node
|
7
|
+
# In various cops we want to regard const as literal although it's not
|
8
|
+
# strictly literal.
|
9
|
+
def recursive_literal_or_const?
|
10
|
+
case type
|
11
|
+
when :begin, :pair, *AST::Node::COMPOSITE_LITERALS
|
12
|
+
children.compact.all?(&:recursive_literal_or_const?)
|
13
|
+
else
|
14
|
+
literal? || const_type?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_context 'with default RSpec/Language config' do
|
4
|
+
include_context 'config'
|
5
|
+
|
6
|
+
# Deep duplication is needed to prevent config leakage between examples
|
7
|
+
let(:other_cops) do
|
8
|
+
default_language = RuboCop::ConfigLoader
|
9
|
+
.default_configuration['RSpec']['Language']
|
10
|
+
default_include = RuboCop::ConfigLoader
|
11
|
+
.default_configuration['RSpec']['Include']
|
12
|
+
{ 'RSpec' =>
|
13
|
+
{
|
14
|
+
'Include' => default_include,
|
15
|
+
'Language' => deep_dup(default_language)
|
16
|
+
} }
|
17
|
+
end
|
18
|
+
|
19
|
+
def deep_dup(object)
|
20
|
+
case object
|
21
|
+
when Array
|
22
|
+
object.map { |item| deep_dup(item) }
|
23
|
+
when Hash
|
24
|
+
object.transform_values { |value| deep_dup(value) }
|
25
|
+
else
|
26
|
+
object # only collections undergo modifications and need duping
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -4,44 +4,86 @@ module RuboCop
|
|
4
4
|
module RSpec
|
5
5
|
# RSpec example wording rewriter
|
6
6
|
class Wording
|
7
|
+
SHOULDNT_PREFIX = /\Ashould(?:n't| not)\b/i.freeze
|
8
|
+
SHOULDNT_BE_PREFIX = /#{SHOULDNT_PREFIX} be\b/i.freeze
|
9
|
+
WILL_NOT_PREFIX = /\Awill not\b/i.freeze
|
10
|
+
WONT_PREFIX = /\Awon't\b/i.freeze
|
11
|
+
ES_SUFFIX_PATTERN = /(?:o|s|x|ch|sh|z)\z/i.freeze
|
12
|
+
IES_SUFFIX_PATTERN = /[^aeou]y\z/i.freeze
|
13
|
+
|
7
14
|
def initialize(text, ignore:, replace:)
|
8
15
|
@text = text
|
9
16
|
@ignores = ignore
|
10
17
|
@replacements = replace
|
11
18
|
end
|
12
19
|
|
20
|
+
# rubocop:disable Metrics/MethodLength
|
13
21
|
def rewrite
|
14
|
-
text
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
case text
|
23
|
+
when SHOULDNT_BE_PREFIX
|
24
|
+
replace_prefix(SHOULDNT_BE_PREFIX, 'is not')
|
25
|
+
when SHOULDNT_PREFIX
|
26
|
+
replace_prefix(SHOULDNT_PREFIX, 'does not')
|
27
|
+
when WILL_NOT_PREFIX
|
28
|
+
replace_prefix(WILL_NOT_PREFIX, 'does not')
|
29
|
+
when WONT_PREFIX
|
30
|
+
replace_prefix(WONT_PREFIX, 'does not')
|
31
|
+
else
|
32
|
+
remove_should_and_pluralize
|
33
|
+
end
|
24
34
|
end
|
35
|
+
# rubocop:enable Metrics/MethodLength
|
25
36
|
|
26
37
|
private
|
27
38
|
|
28
39
|
attr_reader :text, :ignores, :replacements
|
29
40
|
|
30
|
-
def
|
31
|
-
|
41
|
+
def replace_prefix(pattern, replacement)
|
42
|
+
text.sub(pattern) do |matched|
|
43
|
+
uppercase?(matched) ? replacement.upcase : replacement
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def uppercase?(word)
|
48
|
+
word.upcase.eql?(word)
|
49
|
+
end
|
50
|
+
|
51
|
+
def remove_should_and_pluralize
|
52
|
+
_should, *words = text.split
|
53
|
+
|
54
|
+
words.each_with_index do |word, index|
|
55
|
+
next if ignored_word?(word)
|
32
56
|
|
33
|
-
|
34
|
-
|
35
|
-
|
57
|
+
words[index] = substitute(word)
|
58
|
+
|
59
|
+
break
|
36
60
|
end
|
37
61
|
|
38
|
-
|
39
|
-
|
40
|
-
|
62
|
+
words.join(' ')
|
63
|
+
end
|
64
|
+
|
65
|
+
def ignored_word?(word)
|
66
|
+
ignores.any? { |ignore| ignore.casecmp(word).zero? }
|
67
|
+
end
|
68
|
+
|
69
|
+
def substitute(word)
|
70
|
+
# NOTE: Custom replacements are case sensitive.
|
71
|
+
return replacements.fetch(word) if replacements.key?(word)
|
72
|
+
|
73
|
+
case word
|
74
|
+
when ES_SUFFIX_PATTERN then append_suffix(word, 'es')
|
75
|
+
when IES_SUFFIX_PATTERN then append_suffix(word[0..-2], 'ies')
|
76
|
+
else append_suffix(word, 's')
|
41
77
|
end
|
78
|
+
end
|
42
79
|
|
43
|
-
|
80
|
+
def append_suffix(word, suffix)
|
81
|
+
suffix = suffix.upcase if uppercase?(word)
|
82
|
+
|
83
|
+
"#{word}#{suffix}"
|
44
84
|
end
|
85
|
+
|
86
|
+
private_constant(*constants(false))
|
45
87
|
end
|
46
88
|
end
|
47
89
|
end
|
data/lib/rubocop/rspec.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RuboCop
|
2
4
|
# RuboCop RSpec project namespace
|
3
5
|
module RSpec
|
4
6
|
PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
|
5
7
|
CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
|
6
|
-
CONFIG = YAML.load(CONFIG_DEFAULT.read).freeze
|
7
8
|
|
8
|
-
private_constant(
|
9
|
+
private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
|
10
|
+
|
11
|
+
::RuboCop::ConfigObsoletion.files << PROJECT_ROOT.join('config',
|
12
|
+
'obsoletion.yml')
|
9
13
|
end
|
10
14
|
end
|
data/lib/rubocop-rspec.rb
CHANGED
@@ -1,42 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'pathname'
|
2
4
|
require 'yaml'
|
3
5
|
|
4
6
|
require 'rubocop'
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
require_relative 'rubocop/rspec'
|
9
|
+
require_relative 'rubocop/rspec/inject'
|
10
|
+
require_relative 'rubocop/rspec/language'
|
11
|
+
require_relative 'rubocop/rspec/node'
|
12
|
+
require_relative 'rubocop/rspec/version'
|
13
|
+
require_relative 'rubocop/rspec/wording'
|
14
|
+
|
15
|
+
require_relative 'rubocop/cop/rspec/mixin/file_help'
|
16
|
+
require_relative 'rubocop/cop/rspec/mixin/final_end_location'
|
17
|
+
require_relative 'rubocop/cop/rspec/mixin/inside_example_group'
|
18
|
+
require_relative 'rubocop/cop/rspec/mixin/location_help'
|
19
|
+
require_relative 'rubocop/cop/rspec/mixin/metadata'
|
20
|
+
require_relative 'rubocop/cop/rspec/mixin/namespace'
|
21
|
+
require_relative 'rubocop/cop/rspec/mixin/skip_or_pending'
|
22
|
+
require_relative 'rubocop/cop/rspec/mixin/top_level_group'
|
23
|
+
require_relative 'rubocop/cop/rspec/mixin/variable'
|
24
|
+
|
25
|
+
# Dependent on `RuboCop::Cop::RSpec::FinalEndLocation`.
|
26
|
+
require_relative 'rubocop/cop/rspec/mixin/comments_help'
|
27
|
+
require_relative 'rubocop/cop/rspec/mixin/empty_line_separation'
|
28
|
+
|
29
|
+
require_relative 'rubocop/cop/rspec/base'
|
30
|
+
require_relative 'rubocop/rspec/align_let_brace'
|
31
|
+
require_relative 'rubocop/rspec/concept'
|
32
|
+
require_relative 'rubocop/rspec/corrector/move_node'
|
33
|
+
require_relative 'rubocop/rspec/example'
|
34
|
+
require_relative 'rubocop/rspec/example_group'
|
35
|
+
require_relative 'rubocop/rspec/hook'
|
15
36
|
|
16
37
|
RuboCop::RSpec::Inject.defaults!
|
17
38
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
require 'rubocop/cop/rspec/let_setup'
|
34
|
-
require 'rubocop/cop/rspec/message_chain'
|
35
|
-
require 'rubocop/cop/rspec/message_expectation'
|
36
|
-
require 'rubocop/cop/rspec/multiple_describes'
|
37
|
-
require 'rubocop/cop/rspec/multiple_expectations'
|
38
|
-
require 'rubocop/cop/rspec/named_subject'
|
39
|
-
require 'rubocop/cop/rspec/nested_groups'
|
40
|
-
require 'rubocop/cop/rspec/not_to_not'
|
41
|
-
require 'rubocop/cop/rspec/subject_stub'
|
42
|
-
require 'rubocop/cop/rspec/verified_doubles'
|
39
|
+
require_relative 'rubocop/cop/rspec_cops'
|
40
|
+
|
41
|
+
# We have to register our autocorrect incompatibilities in RuboCop's cops
|
42
|
+
# as well so we do not hit infinite loops
|
43
|
+
|
44
|
+
RuboCop::Cop::Layout::ExtraSpacing.singleton_class.prepend(
|
45
|
+
Module.new do
|
46
|
+
def autocorrect_incompatible_with
|
47
|
+
super.push(RuboCop::Cop::RSpec::AlignLeftLetBrace)
|
48
|
+
.push(RuboCop::Cop::RSpec::AlignRightLetBrace)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
)
|
52
|
+
|
53
|
+
RuboCop::AST::Node.include(RuboCop::RSpec::Node)
|