rubocop-rspec 1.8.0 → 1.9.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 +8 -0
- data/Gemfile +2 -1
- data/Rakefile +3 -1
- data/config/default.yml +16 -0
- data/lib/rubocop-rspec.rb +6 -1
- data/lib/rubocop/cop/rspec/any_instance.rb +0 -2
- data/lib/rubocop/cop/rspec/be_eql.rb +1 -2
- data/lib/rubocop/cop/rspec/cop.rb +66 -0
- data/lib/rubocop/cop/rspec/describe_class.rb +6 -1
- data/lib/rubocop/cop/rspec/describe_method.rb +1 -2
- data/lib/rubocop/cop/rspec/described_class.rb +3 -6
- data/lib/rubocop/cop/rspec/empty_example_group.rb +1 -11
- data/lib/rubocop/cop/rspec/example_length.rb +1 -1
- data/lib/rubocop/cop/rspec/example_wording.rb +0 -2
- data/lib/rubocop/cop/rspec/expect_actual.rb +0 -2
- data/lib/rubocop/cop/rspec/file_path.rb +1 -1
- data/lib/rubocop/cop/rspec/focus.rb +4 -9
- data/lib/rubocop/cop/rspec/hook_argument.rb +3 -5
- data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -1
- data/lib/rubocop/cop/rspec/instance_variable.rb +1 -5
- data/lib/rubocop/cop/rspec/leading_subject.rb +0 -2
- data/lib/rubocop/cop/rspec/let_setup.rb +1 -4
- data/lib/rubocop/cop/rspec/message_chain.rb +1 -8
- data/lib/rubocop/cop/rspec/message_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/message_spies.rb +79 -0
- data/lib/rubocop/cop/rspec/multiple_describes.rb +1 -2
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +2 -6
- data/lib/rubocop/cop/rspec/named_subject.rb +0 -2
- data/lib/rubocop/cop/rspec/nested_groups.rb +2 -6
- data/lib/rubocop/cop/rspec/not_to_not.rb +1 -2
- data/lib/rubocop/cop/rspec/repeated_description.rb +59 -0
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +48 -0
- data/lib/rubocop/cop/rspec/subject_stub.rb +1 -4
- data/lib/rubocop/cop/rspec/verified_doubles.rb +0 -2
- data/lib/rubocop/rspec.rb +1 -1
- data/lib/rubocop/rspec/description_extractor.rb +55 -18
- data/lib/rubocop/rspec/example.rb +56 -0
- data/lib/rubocop/rspec/example_group.rb +57 -0
- data/lib/rubocop/rspec/language.rb +28 -1
- data/lib/rubocop/rspec/language/node_pattern.rb +1 -3
- data/lib/rubocop/rspec/top_level_describe.rb +6 -10
- data/lib/rubocop/rspec/version.rb +1 -1
- data/spec/project/default_config_spec.rb +8 -5
- data/spec/project/project_requires_spec.rb +1 -1
- data/spec/rubocop/{rspec/spec_only_spec.rb → cop/rspec/cop_spec.rb} +2 -4
- data/spec/rubocop/cop/rspec/describe_class_spec.rb +36 -0
- data/spec/rubocop/cop/rspec/described_class_spec.rb +2 -2
- data/spec/rubocop/cop/rspec/example_length_spec.rb +48 -60
- data/spec/rubocop/cop/rspec/implicit_expect_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/message_spies_spec.rb +93 -0
- data/spec/rubocop/cop/rspec/repeated_description_spec.rb +76 -0
- data/spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb +75 -0
- data/spec/rubocop/rspec/description_extractor_spec.rb +46 -24
- data/spec/rubocop/rspec/example_group_spec.rb +44 -0
- data/spec/rubocop/rspec/example_spec.rb +62 -0
- data/spec/rubocop/rspec/language/selector_set_spec.rb +22 -2
- data/spec/spec_helper.rb +2 -9
- data/spec/support/expect_violation.rb +4 -2
- metadata +21 -8
- data/lib/rubocop/rspec/spec_only.rb +0 -61
- data/spec/shared/rspec_only_cop_behavior.rb +0 -68
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module RSpec
|
5
|
+
# Wrapper for RSpec example groups
|
6
|
+
class ExampleGroup
|
7
|
+
include Language
|
8
|
+
extend NodePattern::Macros
|
9
|
+
|
10
|
+
def_node_matcher :example?, Examples::ALL.block_pattern
|
11
|
+
|
12
|
+
# @!method scope_change?(node)
|
13
|
+
#
|
14
|
+
# Detect if the node is an example group or shared example
|
15
|
+
#
|
16
|
+
# Selectors which indicate that we should stop searching
|
17
|
+
#
|
18
|
+
def_node_matcher :scope_change?,
|
19
|
+
(ExampleGroups::ALL + SharedGroups::ALL).block_pattern
|
20
|
+
|
21
|
+
def initialize(node)
|
22
|
+
@node = node
|
23
|
+
end
|
24
|
+
|
25
|
+
def examples
|
26
|
+
examples_in_scope(node).map(&Example.public_method(:new))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :node
|
32
|
+
|
33
|
+
def examples_in_scope(node)
|
34
|
+
node.each_child_node.flat_map do |child|
|
35
|
+
find_examples(child)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Recursively search for examples within the current scope
|
40
|
+
#
|
41
|
+
# Searches node for examples and halts when a scope change is detected
|
42
|
+
#
|
43
|
+
# @param node [RuboCop::Node] node to recursively search for examples
|
44
|
+
#
|
45
|
+
# @return [Array<RuboCop::Node>] discovered example nodes
|
46
|
+
def find_examples(node)
|
47
|
+
return [] if scope_change?(node)
|
48
|
+
|
49
|
+
if example?(node)
|
50
|
+
[node]
|
51
|
+
else
|
52
|
+
examples_in_scope(node)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -22,7 +22,19 @@ module RuboCop
|
|
22
22
|
selectors.include?(selector)
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def block_pattern
|
26
|
+
"(block #{send_pattern} ...)"
|
27
|
+
end
|
28
|
+
|
29
|
+
def send_pattern
|
30
|
+
"(send _ #{node_pattern_union} ...)"
|
31
|
+
end
|
32
|
+
|
33
|
+
def node_pattern_union
|
34
|
+
"{#{node_pattern}}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def node_pattern
|
26
38
|
selectors.map(&:inspect).join(' ')
|
27
39
|
end
|
28
40
|
|
@@ -31,6 +43,10 @@ module RuboCop
|
|
31
43
|
attr_reader :selectors
|
32
44
|
end
|
33
45
|
|
46
|
+
module Matchers
|
47
|
+
MESSAGE_CHAIN = SelectorSet.new(%i(receive_message_chain stub_chain))
|
48
|
+
end
|
49
|
+
|
34
50
|
module ExampleGroups
|
35
51
|
GROUPS = SelectorSet.new(%i(describe context feature example_group))
|
36
52
|
SKIPPED = SelectorSet.new(%i(xdescribe xcontext xfeature))
|
@@ -45,6 +61,17 @@ module RuboCop
|
|
45
61
|
)
|
46
62
|
end
|
47
63
|
|
64
|
+
module Includes
|
65
|
+
ALL = SelectorSet.new(
|
66
|
+
%i(
|
67
|
+
it_behaves_like
|
68
|
+
it_should_behave_like
|
69
|
+
include_context
|
70
|
+
include_examples
|
71
|
+
)
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
48
75
|
module Examples
|
49
76
|
EXAMPLES = SelectorSet.new(%i(it specify example scenario its))
|
50
77
|
FOCUSED = SelectorSet.new(%i(fit fspecify fexample fscenario focus))
|
@@ -7,9 +7,7 @@ module RuboCop
|
|
7
7
|
module NodePattern
|
8
8
|
extend RuboCop::NodePattern::Macros
|
9
9
|
|
10
|
-
def_node_matcher :example_group?,
|
11
|
-
(block (send _ {#{ExampleGroups::ALL.to_node_pattern}} ...) ...)
|
12
|
-
PATTERN
|
10
|
+
def_node_matcher :example_group?, ExampleGroups::ALL.block_pattern
|
13
11
|
end
|
14
12
|
end
|
15
13
|
end
|
@@ -31,9 +31,9 @@ module RuboCop
|
|
31
31
|
# If we have no top level describe statements, we need to check any
|
32
32
|
# blocks on the top level (e.g. after a require).
|
33
33
|
if nodes.empty?
|
34
|
-
nodes =
|
35
|
-
describe_statement_children(child)
|
36
|
-
end
|
34
|
+
nodes = root_node.each_child_node(:block).flat_map do |child|
|
35
|
+
describe_statement_children(child)
|
36
|
+
end
|
37
37
|
end
|
38
38
|
|
39
39
|
nodes
|
@@ -44,18 +44,14 @@ module RuboCop
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def single_top_level_describe?
|
47
|
-
top_level_nodes.
|
47
|
+
top_level_nodes.one?
|
48
48
|
end
|
49
49
|
|
50
50
|
def describe_statement_children(node)
|
51
|
-
|
52
|
-
element.
|
51
|
+
node.each_child_node(:send).select do |element|
|
52
|
+
element.children[1] == :describe
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
56
|
-
def node_children(node)
|
57
|
-
node.children.select { |e| e.is_a? Parser::AST::Node }
|
58
|
-
end
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
@@ -6,12 +6,15 @@ describe 'config/default.yml' do
|
|
6
6
|
let(:cop_names) do
|
7
7
|
glob = SpecHelper::ROOT.join('lib', 'rubocop', 'cop', 'rspec', '*.rb')
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
cop_names =
|
10
|
+
Pathname.glob(glob).map do |file|
|
11
|
+
file_name = file.basename('.rb').to_s
|
12
|
+
cop_name = file_name.gsub(/(^|_)(.)/) { Regexp.last_match(2).upcase }
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
"RSpec/#{cop_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
cop_names - %w(RSpec/Cop)
|
15
18
|
end
|
16
19
|
|
17
20
|
let(:config_keys) do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
describe 'Project requires' do
|
2
2
|
it 'alphabetizes cop requires' do
|
3
3
|
source = SpecHelper::ROOT.join('lib', 'rubocop-rspec.rb').read
|
4
|
-
requires = source.split("\n").grep(%r{rubocop/cop})
|
4
|
+
requires = source.split("\n").grep(%r{rubocop/cop/rspec/[^(?:cop)]})
|
5
5
|
|
6
6
|
expect(requires.join("\n")).to eql(requires.sort.join("\n"))
|
7
7
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
RSpec.describe RuboCop::RSpec::
|
3
|
+
RSpec.describe RuboCop::Cop::RSpec::Cop do
|
4
4
|
subject(:cop) { fake_cop.new(config) }
|
5
5
|
|
6
6
|
let(:config) do
|
@@ -20,9 +20,7 @@ RSpec.describe RuboCop::RSpec::SpecOnly do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
let(:fake_cop) do
|
23
|
-
Class.new(
|
24
|
-
include RuboCop::RSpec::SpecOnly
|
25
|
-
|
23
|
+
Class.new(described_class) do
|
26
24
|
def self.name
|
27
25
|
'RuboCop::RSpec::FakeCop'
|
28
26
|
end
|
@@ -110,4 +110,40 @@ describe RuboCop::Cop::RSpec::DescribeClass do
|
|
110
110
|
it "doesn't blow up on single-line describes" do
|
111
111
|
expect_no_violations('describe Some::Class')
|
112
112
|
end
|
113
|
+
|
114
|
+
it "doesn't flag top level describe in a shared example" do
|
115
|
+
expect_no_violations(<<-RUBY)
|
116
|
+
shared_examples 'Common::Interface' do
|
117
|
+
describe '#public_interface' do
|
118
|
+
it 'conforms to interface' do
|
119
|
+
# ...
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
RUBY
|
124
|
+
end
|
125
|
+
|
126
|
+
it "doesn't flag top level describe in a shared context" do
|
127
|
+
expect_no_violations(<<-RUBY)
|
128
|
+
RSpec.shared_context 'Common::Interface' do
|
129
|
+
describe '#public_interface' do
|
130
|
+
it 'conforms to interface' do
|
131
|
+
# ...
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
RUBY
|
136
|
+
end
|
137
|
+
|
138
|
+
it "doesn't flag top level describe in an unnamed shared context" do
|
139
|
+
expect_no_violations(<<-RUBY)
|
140
|
+
shared_context do
|
141
|
+
describe '#public_interface' do
|
142
|
+
it 'conforms to interface' do
|
143
|
+
# ...
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
RUBY
|
148
|
+
end
|
113
149
|
end
|
@@ -160,7 +160,7 @@ describe RuboCop::Cop::RSpec::DescribedClass, :config do
|
|
160
160
|
RUBY
|
161
161
|
end
|
162
162
|
|
163
|
-
it 'does not flag violations within a scope change' do
|
163
|
+
it 'does not flag violations within a class scope change' do
|
164
164
|
expect_no_violations(<<-RUBY)
|
165
165
|
describe MyNamespace::MyClass do
|
166
166
|
before do
|
@@ -172,7 +172,7 @@ describe RuboCop::Cop::RSpec::DescribedClass, :config do
|
|
172
172
|
RUBY
|
173
173
|
end
|
174
174
|
|
175
|
-
it 'does not flag violations within a scope change' do
|
175
|
+
it 'does not flag violations within a hook scope change' do
|
176
176
|
expect_no_violations(<<-RUBY)
|
177
177
|
describe do
|
178
178
|
before do
|
@@ -4,63 +4,42 @@ describe RuboCop::Cop::RSpec::ExampleLength, :config do
|
|
4
4
|
let(:cop_config) { { 'Max' => 3 } }
|
5
5
|
|
6
6
|
it 'ignores non-spec blocks' do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
'end'
|
16
|
-
],
|
17
|
-
'foo_spec.rb'
|
18
|
-
)
|
19
|
-
|
20
|
-
expect(cop.offenses).to be_empty
|
7
|
+
expect_no_violations(<<-RUBY)
|
8
|
+
foo do
|
9
|
+
line 1
|
10
|
+
line 2
|
11
|
+
line 3
|
12
|
+
line 4
|
13
|
+
end
|
14
|
+
RUBY
|
21
15
|
end
|
22
16
|
|
23
17
|
it 'allows an empty example' do
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
'end'
|
29
|
-
],
|
30
|
-
'foo_spec.rb'
|
31
|
-
)
|
32
|
-
expect(cop.offenses).to be_empty
|
18
|
+
expect_no_violations(<<-RUBY)
|
19
|
+
it do
|
20
|
+
end
|
21
|
+
RUBY
|
33
22
|
end
|
34
23
|
|
35
24
|
it 'allows a short example' do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
'end'
|
44
|
-
],
|
45
|
-
'spec/foo_spec.rb'
|
46
|
-
)
|
47
|
-
expect(cop.offenses).to be_empty
|
25
|
+
expect_no_violations(<<-RUBY)
|
26
|
+
it do
|
27
|
+
line 1
|
28
|
+
line 2
|
29
|
+
line 3
|
30
|
+
end
|
31
|
+
RUBY
|
48
32
|
end
|
49
33
|
|
50
34
|
it 'ignores comments' do
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
'end'
|
60
|
-
],
|
61
|
-
'spec/foo_spec.rb'
|
62
|
-
)
|
63
|
-
expect(cop.offenses).to be_empty
|
35
|
+
expect_no_violations(<<-RUBY)
|
36
|
+
it do
|
37
|
+
line 1
|
38
|
+
line 2
|
39
|
+
# comment
|
40
|
+
line 3
|
41
|
+
end
|
42
|
+
RUBY
|
64
43
|
end
|
65
44
|
|
66
45
|
shared_examples 'large example violation' do
|
@@ -82,18 +61,17 @@ describe RuboCop::Cop::RSpec::ExampleLength, :config do
|
|
82
61
|
end
|
83
62
|
|
84
63
|
context 'when inspecting large examples' do
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
64
|
+
it 'flags the example' do
|
65
|
+
expect_violation(<<-RUBY)
|
66
|
+
it do
|
67
|
+
^^^^^ Example has too many lines. [4/3]
|
68
|
+
line 1
|
69
|
+
line 2
|
70
|
+
line 3
|
71
|
+
line 4
|
72
|
+
end
|
73
|
+
RUBY
|
94
74
|
end
|
95
|
-
|
96
|
-
include_examples 'large example violation'
|
97
75
|
end
|
98
76
|
|
99
77
|
context 'with CountComments enabled' do
|
@@ -112,6 +90,16 @@ describe RuboCop::Cop::RSpec::ExampleLength, :config do
|
|
112
90
|
]
|
113
91
|
end
|
114
92
|
|
115
|
-
|
93
|
+
it 'flags the example' do
|
94
|
+
expect_violation(<<-RUBY)
|
95
|
+
it do
|
96
|
+
^^^^^ Example has too many lines. [4/3]
|
97
|
+
line 1
|
98
|
+
line 2
|
99
|
+
# comment
|
100
|
+
line 3
|
101
|
+
end
|
102
|
+
RUBY
|
103
|
+
end
|
116
104
|
end
|
117
105
|
end
|
@@ -30,7 +30,7 @@ describe RuboCop::Cop::RSpec::ImplicitExpect, :config do
|
|
30
30
|
expect_no_violations('it { is_expected.to_not be_truthy }')
|
31
31
|
end
|
32
32
|
|
33
|
-
it 'approves of is_expected.
|
33
|
+
it 'approves of is_expected.not_to' do
|
34
34
|
expect_no_violations('it { is_expected.not_to be_truthy }')
|
35
35
|
end
|
36
36
|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe RuboCop::Cop::RSpec::MessageSpies, :config do
|
4
|
+
subject(:cop) { described_class.new(config) }
|
5
|
+
|
6
|
+
context 'when EnforcedStyle is have_received' do
|
7
|
+
let(:cop_config) do
|
8
|
+
{ 'EnforcedStyle' => 'have_received' }
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'flags expect(...).to receive' do
|
12
|
+
expect_violation(<<-RUBY)
|
13
|
+
expect(foo).to receive(:bar)
|
14
|
+
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
15
|
+
RUBY
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'flags expect(...).to receive with' do
|
19
|
+
expect_violation(<<-RUBY)
|
20
|
+
expect(foo).to receive(:bar).with(:baz)
|
21
|
+
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
22
|
+
RUBY
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'flags expect(...).to receive at_most' do
|
26
|
+
expect_violation(<<-RUBY)
|
27
|
+
expect(foo).to receive(:bar).at_most(42).times
|
28
|
+
^^^^^^^ Prefer `have_received` for setting message expectations. Setup `foo` as a spy using `allow` or `instance_spy`.
|
29
|
+
RUBY
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'approves of expect(...).to have_received' do
|
33
|
+
expect_no_violations('expect(foo).to have_received(:bar)')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'generates a todo based on the usage of the correct style' do
|
37
|
+
inspect_source(cop, 'expect(foo).to have_received(:bar)', 'foo_spec.rb')
|
38
|
+
|
39
|
+
expect(cop.config_to_allow_offenses)
|
40
|
+
.to eq('EnforcedStyle' => 'have_received')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'generates a todo based on the usage of the alternate style' do
|
44
|
+
inspect_source(cop, 'expect(foo).to receive(:bar)', 'foo_spec.rb')
|
45
|
+
|
46
|
+
expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => 'receive')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when EnforcedStyle is receive' do
|
51
|
+
let(:cop_config) do
|
52
|
+
{ 'EnforcedStyle' => 'receive' }
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'flags expect(...).to have_received' do
|
56
|
+
expect_violation(<<-RUBY)
|
57
|
+
expect(foo).to have_received(:bar)
|
58
|
+
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
59
|
+
RUBY
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'flags expect(...).to have_received with' do
|
63
|
+
expect_violation(<<-RUBY)
|
64
|
+
expect(foo).to have_received(:bar).with(:baz)
|
65
|
+
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
66
|
+
RUBY
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'flags expect(...).to have_received at_most' do
|
70
|
+
expect_violation(<<-RUBY)
|
71
|
+
expect(foo).to have_received(:bar).at_most(42).times
|
72
|
+
^^^^^^^^^^^^^ Prefer `receive` for setting message expectations.
|
73
|
+
RUBY
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'approves of expect(...).to receive' do
|
77
|
+
expect_no_violations('expect(foo).to receive(:bar)')
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'generates a todo based on the usage of the correct style' do
|
81
|
+
inspect_source(cop, 'expect(foo).to receive(:bar)', 'foo_spec.rb')
|
82
|
+
|
83
|
+
expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => 'receive')
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'generates a todo based on the usage of the alternate style' do
|
87
|
+
inspect_source(cop, 'expect(foo).to have_received(:bar)', 'foo_spec.rb')
|
88
|
+
|
89
|
+
expect(cop.config_to_allow_offenses)
|
90
|
+
.to eq('EnforcedStyle' => 'have_received')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|