rubocop-rspec 1.43.1 → 2.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -4
- data/README.md +4 -0
- data/config/default.yml +141 -25
- data/lib/rubocop-rspec.rb +7 -8
- data/lib/rubocop/cop/rspec/align_left_let_brace.rb +7 -3
- data/lib/rubocop/cop/rspec/align_right_let_brace.rb +7 -3
- data/lib/rubocop/cop/rspec/around_block.rb +1 -1
- data/lib/rubocop/cop/rspec/base.rb +7 -54
- data/lib/rubocop/cop/rspec/be.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +2 -2
- data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +3 -2
- data/lib/rubocop/cop/rspec/describe_class.rb +33 -14
- data/lib/rubocop/cop/rspec/describe_method.rb +1 -1
- data/lib/rubocop/cop/rspec/described_class.rb +1 -2
- data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -2
- data/lib/rubocop/cop/rspec/dialect.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_example_group.rb +33 -38
- data/lib/rubocop/cop/rspec/empty_hook.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +2 -2
- data/lib/rubocop/cop/rspec/expect_actual.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_in_hook.rb +1 -1
- data/lib/rubocop/cop/rspec/file_path.rb +2 -2
- data/lib/rubocop/cop/rspec/focus.rb +13 -7
- data/lib/rubocop/cop/rspec/hook_argument.rb +2 -4
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +2 -2
- data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -2
- data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -1
- data/lib/rubocop/cop/rspec/instance_variable.rb +1 -1
- data/lib/rubocop/cop/rspec/leading_subject.rb +5 -1
- data/lib/rubocop/cop/rspec/let_before_examples.rb +2 -2
- data/lib/rubocop/cop/rspec/let_setup.rb +7 -4
- data/lib/rubocop/cop/rspec/message_spies.rb +1 -1
- data/lib/rubocop/cop/rspec/mixin/empty_line_separation.rb +51 -0
- data/lib/rubocop/cop/rspec/mixin/final_end_location.rb +19 -0
- data/lib/rubocop/cop/rspec/mixin/top_level_group.rb +54 -0
- data/lib/rubocop/cop/rspec/mixin/variable.rb +20 -0
- data/lib/rubocop/cop/rspec/multiple_describes.rb +1 -1
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +1 -1
- data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +3 -1
- data/lib/rubocop/cop/rspec/named_subject.rb +8 -12
- data/lib/rubocop/cop/rspec/nested_groups.rb +1 -1
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +2 -1
- data/lib/rubocop/cop/rspec/pending.rb +13 -5
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +3 -3
- data/lib/rubocop/cop/rspec/repeated_include_example.rb +104 -0
- data/lib/rubocop/cop/rspec/shared_context.rb +16 -6
- data/lib/rubocop/cop/rspec/shared_examples.rb +3 -1
- data/lib/rubocop/cop/rspec/stubbed_mock.rb +172 -0
- data/lib/rubocop/cop/rspec/subject_stub.rb +6 -6
- data/lib/rubocop/cop/rspec/variable_definition.rb +1 -1
- data/lib/rubocop/cop/rspec/variable_name.rb +1 -1
- data/lib/rubocop/cop/rspec_cops.rb +2 -1
- data/lib/rubocop/rspec/align_let_brace.rb +1 -1
- data/lib/rubocop/rspec/concept.rb +2 -2
- data/lib/rubocop/rspec/config_formatter.rb +3 -3
- data/lib/rubocop/rspec/corrector/move_node.rb +1 -1
- data/lib/rubocop/rspec/example_group.rb +15 -5
- data/lib/rubocop/rspec/hook.rb +2 -6
- data/lib/rubocop/rspec/inject.rb +4 -2
- data/lib/rubocop/rspec/language.rb +144 -105
- data/lib/rubocop/rspec/language/node_pattern.rb +7 -24
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +25 -13
- data/lib/rubocop/cop/rspec/cop.rb +0 -10
- data/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb +0 -41
- data/lib/rubocop/rspec.rb +0 -12
- data/lib/rubocop/rspec/empty_line_separation.rb +0 -48
- data/lib/rubocop/rspec/final_end_location.rb +0 -17
- data/lib/rubocop/rspec/top_level_describe.rb +0 -52
- data/lib/rubocop/rspec/top_level_group.rb +0 -57
- data/lib/rubocop/rspec/variable.rb +0 -16
@@ -59,14 +59,24 @@ module RuboCop
|
|
59
59
|
MSG_CONTEXT = "Use `shared_context` when you don't "\
|
60
60
|
'define examples.'
|
61
61
|
|
62
|
-
examples
|
63
|
-
|
62
|
+
def_node_search :examples?,
|
63
|
+
send_pattern('{#Includes.examples #Examples.all}')
|
64
64
|
|
65
|
-
context
|
66
|
-
|
65
|
+
def_node_search :context?, <<-PATTERN
|
66
|
+
(
|
67
|
+
send #rspec? {
|
68
|
+
#Subjects.all
|
69
|
+
#Helpers.all
|
70
|
+
#Includes.context
|
71
|
+
#Hooks.all
|
72
|
+
} ...
|
73
|
+
)
|
74
|
+
PATTERN
|
67
75
|
|
68
|
-
def_node_matcher :shared_context,
|
69
|
-
|
76
|
+
def_node_matcher :shared_context,
|
77
|
+
block_pattern('#SharedGroups.context')
|
78
|
+
def_node_matcher :shared_example,
|
79
|
+
block_pattern('#SharedGroups.examples')
|
70
80
|
|
71
81
|
def on_block(node)
|
72
82
|
context_with_only_examples(node) do
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks that message expectations do not have a configured response.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# expect(foo).to receive(:bar).with(42).and_return("hello world")
|
12
|
+
#
|
13
|
+
# # good (without spies)
|
14
|
+
# allow(foo).to receive(:bar).with(42).and_return("hello world")
|
15
|
+
# expect(foo).to receive(:bar).with(42)
|
16
|
+
#
|
17
|
+
class StubbedMock < Base
|
18
|
+
MSG = 'Prefer `%<replacement>s` over `%<method_name>s` when ' \
|
19
|
+
'configuring a response.'
|
20
|
+
|
21
|
+
# @!method message_expectation?(node)
|
22
|
+
# Match message expectation matcher
|
23
|
+
#
|
24
|
+
# @example source that matches
|
25
|
+
# receive(:foo)
|
26
|
+
#
|
27
|
+
# @example source that matches
|
28
|
+
# receive_message_chain(:foo, :bar)
|
29
|
+
#
|
30
|
+
# @example source that matches
|
31
|
+
# receive(:foo).with('bar')
|
32
|
+
#
|
33
|
+
# @param node [RuboCop::AST::Node]
|
34
|
+
# @return [Array<RuboCop::AST::Node>] matching nodes
|
35
|
+
def_node_matcher :message_expectation?, <<-PATTERN
|
36
|
+
{
|
37
|
+
(send nil? { :receive :receive_message_chain } ...) # receive(:foo)
|
38
|
+
(send (send nil? :receive ...) :with ...) # receive(:foo).with('bar')
|
39
|
+
}
|
40
|
+
PATTERN
|
41
|
+
|
42
|
+
def_node_matcher :configured_response?, <<~PATTERN
|
43
|
+
{ :and_return :and_raise :and_throw :and_yield
|
44
|
+
:and_call_original :and_wrap_original }
|
45
|
+
PATTERN
|
46
|
+
|
47
|
+
# @!method expectation(node)
|
48
|
+
# Match expectation
|
49
|
+
#
|
50
|
+
# @example source that matches
|
51
|
+
# is_expected.to be_in_the_bar
|
52
|
+
#
|
53
|
+
# @example source that matches
|
54
|
+
# expect(cocktail).to contain_exactly(:fresh_orange_juice, :campari)
|
55
|
+
#
|
56
|
+
# @example source that matches
|
57
|
+
# expect_any_instance_of(Officer).to be_alert
|
58
|
+
#
|
59
|
+
# @param node [RuboCop::AST::Node]
|
60
|
+
# @yield [RuboCop::AST::Node] expectation, method name, matcher
|
61
|
+
def_node_matcher :expectation, <<~PATTERN
|
62
|
+
(send
|
63
|
+
$(send nil? $#Expectations.all ...)
|
64
|
+
:to $_)
|
65
|
+
PATTERN
|
66
|
+
|
67
|
+
# @!method matcher_with_configured_response(node)
|
68
|
+
# Match matcher with a configured response
|
69
|
+
#
|
70
|
+
# @example source that matches
|
71
|
+
# receive(:foo).and_return('bar')
|
72
|
+
#
|
73
|
+
# @example source that matches
|
74
|
+
# receive(:lower).and_raise(SomeError)
|
75
|
+
#
|
76
|
+
# @example source that matches
|
77
|
+
# receive(:redirect).and_call_original
|
78
|
+
#
|
79
|
+
# @param node [RuboCop::AST::Node]
|
80
|
+
# @yield [RuboCop::AST::Node] matcher
|
81
|
+
def_node_matcher :matcher_with_configured_response, <<~PATTERN
|
82
|
+
(send #message_expectation? #configured_response? _)
|
83
|
+
PATTERN
|
84
|
+
|
85
|
+
# @!method matcher_with_return_block(node)
|
86
|
+
# Match matcher with a return block
|
87
|
+
#
|
88
|
+
# @example source that matches
|
89
|
+
# receive(:foo) { 'bar' }
|
90
|
+
#
|
91
|
+
# @param node [RuboCop::AST::Node]
|
92
|
+
# @yield [RuboCop::AST::Node] matcher
|
93
|
+
def_node_matcher :matcher_with_return_block, <<~PATTERN
|
94
|
+
(block #message_expectation? args _) # receive(:foo) { 'bar' }
|
95
|
+
PATTERN
|
96
|
+
|
97
|
+
# @!method matcher_with_hash(node)
|
98
|
+
# Match matcher with a configured response defined as a hash
|
99
|
+
#
|
100
|
+
# @example source that matches
|
101
|
+
# receive_messages(foo: 'bar', baz: 'qux')
|
102
|
+
#
|
103
|
+
# @example source that matches
|
104
|
+
# receive_message_chain(:foo, bar: 'baz')
|
105
|
+
#
|
106
|
+
# @param node [RuboCop::AST::Node]
|
107
|
+
# @yield [RuboCop::AST::Node] matcher
|
108
|
+
def_node_matcher :matcher_with_hash, <<~PATTERN
|
109
|
+
{
|
110
|
+
(send nil? :receive_messages hash) # receive_messages(foo: 'bar', baz: 'qux')
|
111
|
+
(send nil? :receive_message_chain ... hash) # receive_message_chain(:foo, bar: 'baz')
|
112
|
+
}
|
113
|
+
PATTERN
|
114
|
+
|
115
|
+
# @!method matcher_with_blockpass(node)
|
116
|
+
# Match matcher with a configured response in block-pass
|
117
|
+
#
|
118
|
+
# @example source that matches
|
119
|
+
# receive(:foo, &canned)
|
120
|
+
#
|
121
|
+
# @example source that matches
|
122
|
+
# receive_message_chain(:foo, :bar, &canned)
|
123
|
+
#
|
124
|
+
# @example source that matches
|
125
|
+
# receive(:foo).with('bar', &canned)
|
126
|
+
#
|
127
|
+
# @param node [RuboCop::AST::Node]
|
128
|
+
# @yield [RuboCop::AST::Node] matcher
|
129
|
+
def_node_matcher :matcher_with_blockpass, <<~PATTERN
|
130
|
+
{
|
131
|
+
(send nil? { :receive :receive_message_chain } ... block_pass) # receive(:foo, &canned)
|
132
|
+
(send (send nil? :receive ...) :with ... block_pass) # receive(:foo).with('foo', &canned)
|
133
|
+
}
|
134
|
+
PATTERN
|
135
|
+
|
136
|
+
def on_send(node)
|
137
|
+
expectation(node, &method(:on_expectation))
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def on_expectation(expectation, method_name, matcher)
|
143
|
+
flag_expectation = lambda do
|
144
|
+
add_offense(expectation, message: msg(method_name))
|
145
|
+
end
|
146
|
+
|
147
|
+
matcher_with_configured_response(matcher, &flag_expectation)
|
148
|
+
matcher_with_return_block(matcher, &flag_expectation)
|
149
|
+
matcher_with_hash(matcher, &flag_expectation)
|
150
|
+
matcher_with_blockpass(matcher, &flag_expectation)
|
151
|
+
end
|
152
|
+
|
153
|
+
def msg(method_name)
|
154
|
+
format(MSG,
|
155
|
+
method_name: method_name,
|
156
|
+
replacement: replacement(method_name))
|
157
|
+
end
|
158
|
+
|
159
|
+
def replacement(method_name)
|
160
|
+
case method_name
|
161
|
+
when :expect
|
162
|
+
:allow
|
163
|
+
when :is_expected
|
164
|
+
'allow(subject)'
|
165
|
+
when :expect_any_instance_of
|
166
|
+
:allow_any_instance_of
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -22,7 +22,7 @@ module RuboCop
|
|
22
22
|
# end
|
23
23
|
#
|
24
24
|
class SubjectStub < Base
|
25
|
-
include
|
25
|
+
include TopLevelGroup
|
26
26
|
|
27
27
|
MSG = 'Do not stub methods of the object under test.'
|
28
28
|
|
@@ -43,10 +43,10 @@ module RuboCop
|
|
43
43
|
#
|
44
44
|
# @yield [Symbol] subject name
|
45
45
|
def_node_matcher :subject, <<-PATTERN
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
(block
|
47
|
+
(send nil?
|
48
|
+
{:subject (sym $_) | $:subject}
|
49
|
+
) args ...)
|
50
50
|
PATTERN
|
51
51
|
|
52
52
|
# @!method message_expectation?(node, method_name)
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
66
66
|
(send nil? { :expect :allow } (send nil? {% :subject}))
|
67
67
|
(send nil? :is_expected)
|
68
68
|
}
|
69
|
-
#
|
69
|
+
#Runners.all
|
70
70
|
#message_expectation_matcher?
|
71
71
|
)
|
72
72
|
PATTERN
|
@@ -52,7 +52,6 @@ require_relative 'rspec/implicit_expect'
|
|
52
52
|
require_relative 'rspec/implicit_subject'
|
53
53
|
require_relative 'rspec/instance_spy'
|
54
54
|
require_relative 'rspec/instance_variable'
|
55
|
-
require_relative 'rspec/invalid_predicate_matcher'
|
56
55
|
require_relative 'rspec/it_behaves_like'
|
57
56
|
require_relative 'rspec/iterated_expectation'
|
58
57
|
require_relative 'rspec/leading_subject'
|
@@ -79,12 +78,14 @@ require_relative 'rspec/repeated_description'
|
|
79
78
|
require_relative 'rspec/repeated_example'
|
80
79
|
require_relative 'rspec/repeated_example_group_body'
|
81
80
|
require_relative 'rspec/repeated_example_group_description'
|
81
|
+
require_relative 'rspec/repeated_include_example'
|
82
82
|
require_relative 'rspec/return_from_stub'
|
83
83
|
require_relative 'rspec/scattered_let'
|
84
84
|
require_relative 'rspec/scattered_setup'
|
85
85
|
require_relative 'rspec/shared_context'
|
86
86
|
require_relative 'rspec/shared_examples'
|
87
87
|
require_relative 'rspec/single_argument_message_chain'
|
88
|
+
require_relative 'rspec/stubbed_mock'
|
88
89
|
require_relative 'rspec/subject_stub'
|
89
90
|
require_relative 'rspec/unspecified_exception'
|
90
91
|
require_relative 'rspec/variable_definition'
|
@@ -4,9 +4,9 @@ module RuboCop
|
|
4
4
|
module RSpec
|
5
5
|
# Wrapper for RSpec DSL methods
|
6
6
|
class Concept
|
7
|
+
extend RuboCop::NodePattern::Macros
|
8
|
+
extend Language::NodePattern
|
7
9
|
include Language
|
8
|
-
include Language::NodePattern
|
9
|
-
extend NodePattern::Macros
|
10
10
|
|
11
11
|
def initialize(node)
|
12
12
|
@node = node
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
module RSpec
|
7
7
|
# Builds a YAML config file from two config hashes
|
8
8
|
class ConfigFormatter
|
9
|
-
|
9
|
+
EXTENSION_ROOT_DEPARTMENT = %r{^(RSpec/)}.freeze
|
10
10
|
STYLE_GUIDE_BASE_URL = 'https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/'
|
11
11
|
|
12
12
|
def initialize(config, descriptions)
|
@@ -15,7 +15,7 @@ module RuboCop
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def dump
|
18
|
-
YAML.dump(unified_config).gsub(
|
18
|
+
YAML.dump(unified_config).gsub(EXTENSION_ROOT_DEPARTMENT, "\n\\1")
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def cops
|
32
|
-
(descriptions.keys | config.keys).grep(
|
32
|
+
(descriptions.keys | config.keys).grep(EXTENSION_ROOT_DEPARTMENT)
|
33
33
|
end
|
34
34
|
|
35
35
|
attr_reader :config, :descriptions
|
@@ -10,9 +10,14 @@ module RuboCop
|
|
10
10
|
#
|
11
11
|
# Selectors which indicate that we should stop searching
|
12
12
|
#
|
13
|
-
def_node_matcher :scope_change?,
|
14
|
-
|
15
|
-
|
13
|
+
def_node_matcher :scope_change?,
|
14
|
+
block_pattern(<<~PATTERN)
|
15
|
+
{
|
16
|
+
#SharedGroups.all
|
17
|
+
#ExampleGroups.all
|
18
|
+
#Includes.all
|
19
|
+
}
|
20
|
+
PATTERN
|
16
21
|
|
17
22
|
def lets
|
18
23
|
find_all_in_scope(node, :let?)
|
@@ -23,11 +28,15 @@ module RuboCop
|
|
23
28
|
end
|
24
29
|
|
25
30
|
def examples
|
26
|
-
find_all_in_scope(node, :example?).map
|
31
|
+
find_all_in_scope(node, :example?).map do |node|
|
32
|
+
Example.new(node)
|
33
|
+
end
|
27
34
|
end
|
28
35
|
|
29
36
|
def hooks
|
30
|
-
find_all_in_scope(node, :hook?).map
|
37
|
+
find_all_in_scope(node, :hook?).map do |node|
|
38
|
+
Hook.new(node)
|
39
|
+
end
|
31
40
|
end
|
32
41
|
|
33
42
|
private
|
@@ -37,6 +46,7 @@ module RuboCop
|
|
37
46
|
# Searches node and halts when a scope change is detected
|
38
47
|
#
|
39
48
|
# @param node [RuboCop::AST::Node] node to recursively search
|
49
|
+
# @param predicate [Symbol] method to call with node as argument
|
40
50
|
#
|
41
51
|
# @return [Array<RuboCop::AST::Node>] discovered nodes
|
42
52
|
def find_all_in_scope(node, predicate)
|
data/lib/rubocop/rspec/hook.rb
CHANGED
@@ -6,11 +6,7 @@ module RuboCop
|
|
6
6
|
class Hook < Concept
|
7
7
|
def_node_matcher :extract_metadata, <<~PATTERN
|
8
8
|
(block
|
9
|
-
|
10
|
-
(send _ _ #valid_scope? $...)
|
11
|
-
(send _ _ $...)
|
12
|
-
}
|
13
|
-
...
|
9
|
+
(send _ _ #valid_scope? ? $...) ...
|
14
10
|
)
|
15
11
|
PATTERN
|
16
12
|
|
@@ -48,7 +44,7 @@ module RuboCop
|
|
48
44
|
private
|
49
45
|
|
50
46
|
def valid_scope?(node)
|
51
|
-
node&.sym_type? &&
|
47
|
+
node&.sym_type? && Language::HookScopes.all(node.value)
|
52
48
|
end
|
53
49
|
|
54
50
|
def transform_metadata(meta)
|
data/lib/rubocop/rspec/inject.rb
CHANGED
@@ -6,9 +6,11 @@ module RuboCop
|
|
6
6
|
# bit of our configuration.
|
7
7
|
module Inject
|
8
8
|
def self.defaults!
|
9
|
-
|
9
|
+
project_root = Pathname.new(__dir__).parent.parent.parent.expand_path
|
10
|
+
config_default = project_root.join('config', 'default.yml')
|
11
|
+
path = config_default.to_s
|
10
12
|
hash = ConfigLoader.send(:load_yaml_configuration, path)
|
11
|
-
config = Config.new(hash, path)
|
13
|
+
config = RuboCop::Config.new(hash, path)
|
12
14
|
puts "configuration from #{path}" if ConfigLoader.debug?
|
13
15
|
config = ConfigLoader.merge_with_default(config, path)
|
14
16
|
ConfigLoader.instance_variable_set(:@default_configuration, config)
|
@@ -2,147 +2,186 @@
|
|
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
|
-
def initialize(selectors)
|
10
|
-
@selectors = selectors
|
11
|
-
end
|
15
|
+
extend RuboCop::NodePattern::Macros
|
16
|
+
extend NodePattern
|
12
17
|
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
class << self
|
19
|
+
attr_accessor :config
|
20
|
+
end
|
16
21
|
|
17
|
-
|
18
|
-
self.class.new(selectors + other.selectors)
|
19
|
-
end
|
22
|
+
def_node_matcher :rspec?, '{(const {nil? cbase} :RSpec) nil?}'
|
20
23
|
|
21
|
-
|
22
|
-
selectors.include?(selector)
|
23
|
-
end
|
24
|
+
def_node_matcher :example_group?, block_pattern('#ExampleGroups.all')
|
24
25
|
|
25
|
-
|
26
|
-
"(block #{send_pattern} ...)"
|
27
|
-
end
|
26
|
+
def_node_matcher :shared_group?, block_pattern('#SharedGroups.all')
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
end
|
28
|
+
def_node_matcher :spec_group?,
|
29
|
+
block_pattern('{#SharedGroups.all #ExampleGroups.all}')
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
def_node_matcher :example_group_with_body?, <<-PATTERN
|
32
|
+
(block #{send_pattern('#ExampleGroups.all')} args !nil?)
|
33
|
+
PATTERN
|
36
34
|
|
37
|
-
|
38
|
-
"(send #rspec? #{node_pattern_union} ...)"
|
39
|
-
end
|
35
|
+
def_node_matcher :example?, block_pattern('#Examples.all')
|
40
36
|
|
41
|
-
|
42
|
-
"{#{send_pattern} #{block_pattern} #{block_pass_pattern}}"
|
43
|
-
end
|
37
|
+
def_node_matcher :hook?, block_pattern('#Hooks.all')
|
44
38
|
|
45
|
-
|
46
|
-
|
47
|
-
|
39
|
+
def_node_matcher :let?, <<-PATTERN
|
40
|
+
{
|
41
|
+
#{block_pattern('#Helpers.all')}
|
42
|
+
(send #rspec? #Helpers.all _ block_pass)
|
43
|
+
}
|
44
|
+
PATTERN
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
def_node_matcher :include?, <<-PATTERN
|
47
|
+
{
|
48
|
+
#{send_pattern('#Includes.all')}
|
49
|
+
#{block_pattern('#Includes.all')}
|
50
|
+
}
|
51
|
+
PATTERN
|
52
52
|
|
53
|
-
|
53
|
+
def_node_matcher :subject?, block_pattern('#Subjects.all')
|
54
54
|
|
55
|
-
|
56
|
-
|
55
|
+
module ExampleGroups # :nodoc:
|
56
|
+
class << self
|
57
|
+
def all(element)
|
58
|
+
regular(element) ||
|
59
|
+
skipped(element) ||
|
60
|
+
focused(element)
|
61
|
+
end
|
62
|
+
|
63
|
+
def regular(element)
|
64
|
+
Language.config['ExampleGroups']['Regular'].include?(element.to_s)
|
65
|
+
end
|
57
66
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
FOCUSED = SelectorSet.new(%i[fdescribe fcontext ffeature])
|
67
|
+
def focused(element)
|
68
|
+
Language.config['ExampleGroups']['Focused'].include?(element.to_s)
|
69
|
+
end
|
62
70
|
|
63
|
-
|
71
|
+
def skipped(element)
|
72
|
+
Language.config['ExampleGroups']['Skipped'].include?(element.to_s)
|
73
|
+
end
|
74
|
+
end
|
64
75
|
end
|
65
76
|
|
66
|
-
module
|
67
|
-
|
68
|
-
|
77
|
+
module Examples # :nodoc:
|
78
|
+
class << self
|
79
|
+
def all(element)
|
80
|
+
regular(element) ||
|
81
|
+
focused(element) ||
|
82
|
+
skipped(element) ||
|
83
|
+
pending(element)
|
84
|
+
end
|
85
|
+
|
86
|
+
def regular(element)
|
87
|
+
Language.config['Examples']['Regular'].include?(element.to_s)
|
88
|
+
end
|
89
|
+
|
90
|
+
def focused(element)
|
91
|
+
Language.config['Examples']['Focused'].include?(element.to_s)
|
92
|
+
end
|
93
|
+
|
94
|
+
def skipped(element)
|
95
|
+
Language.config['Examples']['Skipped'].include?(element.to_s)
|
96
|
+
end
|
97
|
+
|
98
|
+
def pending(element)
|
99
|
+
Language.config['Examples']['Pending'].include?(element.to_s)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
69
103
|
|
70
|
-
|
104
|
+
module Expectations # :nodoc:
|
105
|
+
def self.all(element)
|
106
|
+
Language.config['Expectations'].include?(element.to_s)
|
107
|
+
end
|
71
108
|
end
|
72
109
|
|
73
|
-
module
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
it_should_behave_like
|
78
|
-
include_examples
|
79
|
-
]
|
80
|
-
)
|
81
|
-
CONTEXT = SelectorSet.new(%i[include_context])
|
82
|
-
|
83
|
-
ALL = EXAMPLES + CONTEXT
|
110
|
+
module Helpers # :nodoc:
|
111
|
+
def self.all(element)
|
112
|
+
Language.config['Helpers'].include?(element.to_s)
|
113
|
+
end
|
84
114
|
end
|
85
115
|
|
86
|
-
module
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
116
|
+
module Hooks # :nodoc:
|
117
|
+
def self.all(element)
|
118
|
+
Language.config['Hooks'].include?(element.to_s)
|
119
|
+
end
|
120
|
+
end
|
91
121
|
|
92
|
-
|
122
|
+
module HookScopes # :nodoc:
|
123
|
+
def self.all(element)
|
124
|
+
Language.config['HookScopes'].include?(element.to_s)
|
125
|
+
end
|
93
126
|
end
|
94
127
|
|
95
|
-
module
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
ALL = SelectorSet.new(
|
110
|
-
%i[
|
111
|
-
each
|
112
|
-
example
|
113
|
-
context
|
114
|
-
all
|
115
|
-
suite
|
116
|
-
]
|
117
|
-
)
|
128
|
+
module Includes # :nodoc:
|
129
|
+
class << self
|
130
|
+
def all(element)
|
131
|
+
examples(element) ||
|
132
|
+
context(element)
|
133
|
+
end
|
134
|
+
|
135
|
+
def examples(element)
|
136
|
+
Language.config['Includes']['Examples'].include?(element.to_s)
|
137
|
+
end
|
138
|
+
|
139
|
+
def context(element)
|
140
|
+
Language.config['Includes']['Context'].include?(element.to_s)
|
141
|
+
end
|
118
142
|
end
|
119
143
|
end
|
120
144
|
|
121
|
-
module
|
122
|
-
|
145
|
+
module Runners # :nodoc:
|
146
|
+
def self.all(element)
|
147
|
+
Language.config['Runners'].include?(element.to_s)
|
148
|
+
end
|
123
149
|
end
|
124
150
|
|
125
|
-
module
|
126
|
-
|
151
|
+
module SharedGroups # :nodoc:
|
152
|
+
class << self
|
153
|
+
def all(element)
|
154
|
+
examples(element) ||
|
155
|
+
context(element)
|
156
|
+
end
|
157
|
+
|
158
|
+
def examples(element)
|
159
|
+
Language.config['SharedGroups']['Examples'].include?(element.to_s)
|
160
|
+
end
|
161
|
+
|
162
|
+
def context(element)
|
163
|
+
Language.config['SharedGroups']['Context'].include?(element.to_s)
|
164
|
+
end
|
165
|
+
end
|
127
166
|
end
|
128
167
|
|
129
|
-
module
|
130
|
-
|
168
|
+
module Subjects # :nodoc:
|
169
|
+
def self.all(element)
|
170
|
+
Language.config['Subjects'].include?(element.to_s)
|
171
|
+
end
|
131
172
|
end
|
132
173
|
|
133
|
-
|
134
|
-
|
174
|
+
# This is used in Dialect and DescribeClass cops to detect RSpec blocks.
|
175
|
+
module ALL # :nodoc:
|
176
|
+
def self.all(element)
|
177
|
+
[ExampleGroups, Examples, Expectations, Helpers, Hooks, Includes,
|
178
|
+
Runners, SharedGroups, Subjects]
|
179
|
+
.find { |concept| concept.all(element) }
|
180
|
+
end
|
135
181
|
end
|
136
182
|
|
137
|
-
|
138
|
-
|
139
|
-
SharedGroups::ALL +
|
140
|
-
Examples::ALL +
|
141
|
-
Hooks::ALL +
|
142
|
-
Helpers::ALL +
|
143
|
-
Subject::ALL +
|
144
|
-
Expectations::ALL +
|
145
|
-
Runners::ALL
|
183
|
+
private_constant :ExampleGroups, :Examples, :Expectations, :Hooks,
|
184
|
+
:Includes, :Runners, :SharedGroups, :ALL
|
146
185
|
end
|
147
186
|
end
|
148
187
|
end
|