rubocop-rspec 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +23 -0
  4. data/Rakefile +19 -1
  5. data/config/default.yml +78 -15
  6. data/lib/rubocop-rspec.rb +19 -1
  7. data/lib/rubocop/cop/rspec/any_instance.rb +5 -1
  8. data/lib/rubocop/cop/rspec/be_eql.rb +58 -0
  9. data/lib/rubocop/cop/rspec/describe_class.rb +2 -3
  10. data/lib/rubocop/cop/rspec/describe_method.rb +4 -3
  11. data/lib/rubocop/cop/rspec/described_class.rb +4 -35
  12. data/lib/rubocop/cop/rspec/empty_example_group.rb +100 -0
  13. data/lib/rubocop/cop/rspec/example_length.rb +5 -2
  14. data/lib/rubocop/cop/rspec/example_wording.rb +5 -2
  15. data/lib/rubocop/cop/rspec/expect_actual.rb +79 -0
  16. data/lib/rubocop/cop/rspec/file_path.rb +3 -1
  17. data/lib/rubocop/cop/rspec/focus.rb +12 -28
  18. data/lib/rubocop/cop/rspec/hook_argument.rb +122 -0
  19. data/lib/rubocop/cop/rspec/instance_variable.rb +53 -12
  20. data/lib/rubocop/cop/rspec/leading_subject.rb +58 -0
  21. data/lib/rubocop/cop/rspec/let_setup.rb +58 -0
  22. data/lib/rubocop/cop/rspec/message_chain.rb +33 -0
  23. data/lib/rubocop/cop/rspec/message_expectation.rb +58 -0
  24. data/lib/rubocop/cop/rspec/multiple_describes.rb +10 -7
  25. data/lib/rubocop/cop/rspec/multiple_expectations.rb +89 -0
  26. data/lib/rubocop/cop/rspec/named_subject.rb +10 -1
  27. data/lib/rubocop/cop/rspec/nested_groups.rb +125 -0
  28. data/lib/rubocop/cop/rspec/not_to_not.rb +3 -3
  29. data/lib/rubocop/cop/rspec/subject_stub.rb +136 -0
  30. data/lib/rubocop/cop/rspec/verified_doubles.rb +4 -1
  31. data/lib/rubocop/rspec.rb +10 -0
  32. data/lib/rubocop/rspec/config_formatter.rb +33 -0
  33. data/lib/rubocop/rspec/description_extractor.rb +35 -0
  34. data/lib/rubocop/rspec/inject.rb +2 -6
  35. data/lib/rubocop/rspec/language.rb +73 -0
  36. data/lib/rubocop/rspec/language/node_pattern.rb +16 -0
  37. data/lib/rubocop/rspec/spec_only.rb +61 -0
  38. data/lib/rubocop/rspec/top_level_describe.rb +6 -0
  39. data/lib/rubocop/rspec/version.rb +1 -1
  40. data/rubocop-rspec.gemspec +1 -0
  41. data/spec/project/changelog_spec.rb +81 -0
  42. data/spec/project/default_config_spec.rb +52 -0
  43. data/spec/project/project_requires_spec.rb +8 -0
  44. data/spec/rubocop/cop/rspec/be_eql_spec.rb +59 -0
  45. data/spec/rubocop/cop/rspec/described_class_spec.rb +2 -2
  46. data/spec/rubocop/cop/rspec/empty_example_group_spec.rb +79 -0
  47. data/spec/rubocop/cop/rspec/example_length_spec.rb +50 -30
  48. data/spec/rubocop/cop/rspec/example_wording_spec.rb +21 -3
  49. data/spec/rubocop/cop/rspec/expect_actual_spec.rb +136 -0
  50. data/spec/rubocop/cop/rspec/file_path_spec.rb +48 -71
  51. data/spec/rubocop/cop/rspec/focus_spec.rb +1 -1
  52. data/spec/rubocop/cop/rspec/hook_argument_spec.rb +189 -0
  53. data/spec/rubocop/cop/rspec/instance_variable_spec.rb +37 -0
  54. data/spec/rubocop/cop/rspec/leading_subject_spec.rb +54 -0
  55. data/spec/rubocop/cop/rspec/let_setup_spec.rb +66 -0
  56. data/spec/rubocop/cop/rspec/message_chain_spec.rb +21 -0
  57. data/spec/rubocop/cop/rspec/message_expectation_spec.rb +63 -0
  58. data/spec/rubocop/cop/rspec/multiple_expectations_spec.rb +84 -0
  59. data/spec/rubocop/cop/rspec/nested_groups_spec.rb +55 -0
  60. data/spec/rubocop/cop/rspec/not_to_not_spec.rb +12 -2
  61. data/spec/rubocop/cop/rspec/subject_stub_spec.rb +183 -0
  62. data/spec/rubocop/rspec/config_formatter_spec.rb +48 -0
  63. data/spec/rubocop/rspec/description_extractor_spec.rb +35 -0
  64. data/spec/rubocop/rspec/language/selector_set_spec.rb +29 -0
  65. data/spec/rubocop/rspec/spec_only_spec.rb +97 -0
  66. data/spec/shared/rspec_only_cop_behavior.rb +68 -0
  67. data/spec/spec_helper.rb +13 -1
  68. metadata +72 -5
  69. data/spec/project_spec.rb +0 -115
@@ -35,4 +35,41 @@ describe RuboCop::Cop::RSpec::InstanceVariable do
35
35
  @foo.empty?
36
36
  RUBY
37
37
  end
38
+
39
+ # Regression test for nevir/rubocop-rspec#115
40
+ it 'ignores instance variables outside of specs' do
41
+ expect_no_violations(<<-RUBY, filename: 'lib/source_code.rb')
42
+ feature do
43
+ @foo = bar
44
+
45
+ @foo
46
+ end
47
+ RUBY
48
+ end
49
+
50
+ context 'when configured with AssignmentOnly', :config do
51
+ subject(:cop) { described_class.new(config) }
52
+
53
+ let(:cop_config) do
54
+ { 'AssignmentOnly' => true }
55
+ end
56
+
57
+ it 'flags an instance variable when it is also assigned' do
58
+ expect_violation(<<-RUBY)
59
+ describe MyClass do
60
+ before { @foo = [] }
61
+ it { expect(@foo).to be_empty }
62
+ ^^^^ Use `let` instead of an instance variable
63
+ end
64
+ RUBY
65
+ end
66
+
67
+ it 'ignores an instance variable when it is not assigned' do
68
+ expect_no_violations(<<-RUBY)
69
+ describe MyClass do
70
+ it { expect(@foo).to be_empty }
71
+ end
72
+ RUBY
73
+ end
74
+ end
38
75
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe RuboCop::Cop::RSpec::LeadingSubject do
4
+ subject(:cop) { described_class.new }
5
+
6
+ it 'checks subject below let' do
7
+ expect_violation(<<-RUBY)
8
+ RSpec.describe User do
9
+ let(:params) { foo }
10
+
11
+ subject { described_class.new }
12
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Declare `subject` above any other `let` declarations
13
+ end
14
+ RUBY
15
+ end
16
+
17
+ it 'approves of subject above let' do
18
+ expect_no_violations(<<-RUBY)
19
+ RSpec.describe User do
20
+ context 'blah' do
21
+ end
22
+
23
+ subject { described_class.new }
24
+
25
+ let(:params) { foo }
26
+ end
27
+ RUBY
28
+ end
29
+
30
+ it 'handles subjects in contexts' do
31
+ expect_no_violations(<<-RUBY)
32
+ RSpec.describe User do
33
+ let(:params) { foo }
34
+
35
+ context "when something happens" do
36
+ subject { described_class.new }
37
+ end
38
+ end
39
+ RUBY
40
+ end
41
+
42
+ it 'handles subjects in tests' do
43
+ expect_no_violations(<<-RUBY)
44
+ RSpec.describe User do
45
+ # This shouldn't really ever happen in a sane codebase but I still
46
+ # want to avoid false positives
47
+ it "doesn't mind me calling a method called subject in the test" do
48
+ let(foo)
49
+ subject { bar }
50
+ end
51
+ end
52
+ RUBY
53
+ end
54
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe RuboCop::Cop::RSpec::LetSetup do
4
+ subject(:cop) { described_class.new }
5
+
6
+ it 'complains when let! is used and not referenced' do
7
+ expect_violation(<<-RUBY)
8
+ describe Foo do
9
+ let!(:foo) { bar }
10
+ ^^^^^^^^^^ Do not use `let!` for test setup.
11
+
12
+ it 'does not use foo' do
13
+ expect(baz).to eq(qux)
14
+ end
15
+ end
16
+ RUBY
17
+ end
18
+
19
+ it 'ignores let! when used in `before`' do
20
+ expect_no_violations(<<-RUBY)
21
+ describe Foo do
22
+ let!(:foo) { bar }
23
+
24
+ before do
25
+ foo
26
+ end
27
+
28
+ it 'does not use foo' do
29
+ expect(baz).to eq(qux)
30
+ end
31
+ end
32
+ RUBY
33
+ end
34
+
35
+ it 'ignores let! when used in example' do
36
+ expect_no_violations(<<-RUBY)
37
+ describe Foo do
38
+ let!(:foo) { bar }
39
+
40
+ it 'uses foo' do
41
+ foo
42
+ expect(baz).to eq(qux)
43
+ end
44
+ end
45
+ RUBY
46
+ end
47
+
48
+ it 'complains when let! is used and not referenced within nested group' do
49
+ expect_violation(<<-RUBY)
50
+ describe Foo do
51
+ context 'when something special happens' do
52
+ let!(:foo) { bar }
53
+ ^^^^^^^^^^ Do not use `let!` for test setup.
54
+
55
+ it 'does not use foo' do
56
+ expect(baz).to eq(qux)
57
+ end
58
+ end
59
+
60
+ it 'references some other foo' do
61
+ foo
62
+ end
63
+ end
64
+ RUBY
65
+ end
66
+ end
@@ -0,0 +1,21 @@
1
+ describe RuboCop::Cop::RSpec::MessageChain do
2
+ subject(:cop) { described_class.new }
3
+
4
+ it 'finds `receive_message_chain`' do
5
+ expect_violation(<<-RUBY)
6
+ before do
7
+ allow(foo).to receive_message_chain(:one, :two) { :three }
8
+ ^^^^^^^^^^^^^^^^^^^^^ Avoid stubbing using `receive_message_chain`
9
+ end
10
+ RUBY
11
+ end
12
+
13
+ it 'finds old `stub_chain` syntax' do
14
+ expect_violation(<<-RUBY)
15
+ before do
16
+ foo.stub_chain(:one, :two).and_return(:three)
17
+ ^^^^^^^^^^ Avoid stubbing using `stub_chain`
18
+ end
19
+ RUBY
20
+ end
21
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe RuboCop::Cop::RSpec::MessageExpectation, :config do
4
+ subject(:cop) { described_class.new(config) }
5
+
6
+ context 'when EnforcedStyle is allow' do
7
+ let(:cop_config) do
8
+ { 'EnforcedStyle' => 'allow' }
9
+ end
10
+
11
+ it 'flags expect(...).to receive' do
12
+ expect_violation(<<-RUBY)
13
+ expect(foo).to receive(:bar)
14
+ ^^^^^^ Prefer `allow` for setting message expectations.
15
+ RUBY
16
+ end
17
+
18
+ it 'approves of allow(...).to receive' do
19
+ expect_no_violations('allow(foo).to receive(:bar)')
20
+ end
21
+
22
+ it 'generates a todo based on the usage of the correct style' do
23
+ inspect_source(cop, 'allow(foo).to receive(:bar)', 'foo_spec.rb')
24
+
25
+ expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => 'allow')
26
+ end
27
+
28
+ it 'generates a todo based on the usage of the alternate style' do
29
+ inspect_source(cop, 'expect(foo).to receive(:bar)', 'foo_spec.rb')
30
+
31
+ expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => 'expect')
32
+ end
33
+ end
34
+
35
+ context 'when EnforcedStyle is expect' do
36
+ let(:cop_config) do
37
+ { 'EnforcedStyle' => 'expect' }
38
+ end
39
+
40
+ it 'flags allow(...).to receive' do
41
+ expect_violation(<<-RUBY)
42
+ allow(foo).to receive(:bar)
43
+ ^^^^^ Prefer `expect` for setting message expectations.
44
+ RUBY
45
+ end
46
+
47
+ it 'approves of expect(...).to receive' do
48
+ expect_no_violations('expect(foo).to receive(:bar)')
49
+ end
50
+
51
+ it 'generates a todo based on the usage of the correct style' do
52
+ inspect_source(cop, 'expect(foo).to receive(:bar)', 'foo_spec.rb')
53
+
54
+ expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => 'expect')
55
+ end
56
+
57
+ it 'generates a todo based on the usage of the alternate style' do
58
+ inspect_source(cop, 'allow(foo).to receive(:bar)', 'foo_spec.rb')
59
+
60
+ expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => 'allow')
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe RuboCop::Cop::RSpec::MultipleExpectations, :config do
4
+ subject(:cop) { described_class.new(config) }
5
+
6
+ context 'without configuration' do
7
+ let(:cop_config) { Hash.new }
8
+
9
+ it 'flags multiple expectations' do
10
+ expect_violation(<<-RUBY)
11
+ describe Foo do
12
+ it 'uses expect twice' do
13
+ ^^^^^^^^^^^^^^^^^^^^^^ Too many expectations.
14
+ expect(foo).to eq(bar)
15
+ expect(baz).to eq(bar)
16
+ end
17
+ end
18
+ RUBY
19
+ end
20
+
21
+ it 'approves of one expectation per example' do
22
+ expect_no_violations(<<-RUBY)
23
+ describe Foo do
24
+ it 'does something neat' do
25
+ expect(neat).to be(true)
26
+ end
27
+
28
+ it 'does something cool' do
29
+ expect(cool).to be(true)
30
+ end
31
+ end
32
+ RUBY
33
+ end
34
+ end
35
+
36
+ context 'with configuration' do
37
+ let(:cop_config) do
38
+ { 'Max' => '2' }
39
+ end
40
+
41
+ it 'permits two expectations' do
42
+ expect_no_violations(<<-RUBY)
43
+ describe Foo do
44
+ it 'uses expect twice' do
45
+ expect(foo).to eq(bar)
46
+ expect(baz).to eq(bar)
47
+ end
48
+ end
49
+ RUBY
50
+ end
51
+
52
+ it 'flags three expectations' do
53
+ expect_violation(<<-RUBY)
54
+ describe Foo do
55
+ it 'uses expect three times' do
56
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Too many expectations.
57
+ expect(foo).to eq(bar)
58
+ expect(baz).to eq(bar)
59
+ expect(qux).to eq(bar)
60
+ end
61
+ end
62
+ RUBY
63
+ end
64
+ end
65
+
66
+ it 'generates a todo based on the worst violation' do
67
+ inspect_source(cop, <<-RUBY, 'spec/foo_spec.rb')
68
+ describe Foo do
69
+ it 'uses expect twice' do
70
+ expect(foo).to eq(bar)
71
+ expect(baz).to eq(bar)
72
+ end
73
+
74
+ it 'uses expect three times' do
75
+ expect(foo).to eq(bar)
76
+ expect(baz).to eq(bar)
77
+ expect(qux).to eq(bar)
78
+ end
79
+ end
80
+ RUBY
81
+
82
+ expect(cop.config_to_allow_offenses).to eq('Max' => 3)
83
+ end
84
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe RuboCop::Cop::RSpec::NestedGroups, :config do
4
+ subject(:cop) { described_class.new(config) }
5
+
6
+ it 'flags nested contexts' do
7
+ expect_violation(<<-RUBY)
8
+ describe MyClass do
9
+ context 'when foo' do
10
+ context 'when bar' do
11
+ ^^^^^^^^^^^^^^^^^^ Maximum example group nesting exceeded
12
+ context 'when baz' do
13
+ ^^^^^^^^^^^^^^^^^^ Maximum example group nesting exceeded
14
+ end
15
+ end
16
+ end
17
+
18
+ context 'when qux' do
19
+ context 'when norf' do
20
+ ^^^^^^^^^^^^^^^^^^^ Maximum example group nesting exceeded
21
+ end
22
+ end
23
+ end
24
+ RUBY
25
+ end
26
+
27
+ it 'ignores non-spec context methods' do
28
+ expect_no_violations(<<-RUBY)
29
+ class MyThingy
30
+ context 'this is not rspec' do
31
+ context 'but it uses contexts' do
32
+ end
33
+ end
34
+ end
35
+ RUBY
36
+ end
37
+
38
+ context 'when MaxNesting is configured as 2' do
39
+ let(:cop_config) { { 'MaxNesting' => '3' } }
40
+
41
+ it 'only flags third level of nesting' do
42
+ expect_violation(<<-RUBY)
43
+ describe MyClass do
44
+ context 'when foo' do
45
+ context 'when bar' do
46
+ context 'when baz' do
47
+ ^^^^^^^^^^^^^^^^^^ Maximum example group nesting exceeded
48
+ end
49
+ end
50
+ end
51
+ end
52
+ RUBY
53
+ end
54
+ end
55
+ end
@@ -18,7 +18,12 @@ describe RuboCop::Cop::RSpec::NotToNot, :config do
18
18
  end
19
19
 
20
20
  it 'auto-corrects `to_not` to `not_to`' do
21
- corrected = autocorrect_source(cop, ['it { expect(0).to_not equal 1 }'])
21
+ corrected =
22
+ autocorrect_source(
23
+ cop,
24
+ ['it { expect(0).to_not equal 1 }'],
25
+ 'spec/foo_spec.rb'
26
+ )
22
27
  expect(corrected).to eq 'it { expect(0).not_to equal 1 }'
23
28
  end
24
29
  end
@@ -40,7 +45,12 @@ describe RuboCop::Cop::RSpec::NotToNot, :config do
40
45
  end
41
46
 
42
47
  it 'auto-corrects `not_to` to `to_not`' do
43
- corrected = autocorrect_source(cop, ['it { expect(0).not_to equal 1 }'])
48
+ corrected =
49
+ autocorrect_source(
50
+ cop,
51
+ ['it { expect(0).not_to equal 1 }'],
52
+ 'spec/foo_spec.rb'
53
+ )
44
54
  expect(corrected).to eq 'it { expect(0).to_not equal 1 }'
45
55
  end
46
56
  end
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe RuboCop::Cop::RSpec::SubjectStub do
4
+ subject(:cop) { described_class.new }
5
+
6
+ it 'complains when subject is stubbed' do
7
+ expect_violation(<<-RUBY)
8
+ describe Foo do
9
+ subject(:foo) { described_class.new }
10
+
11
+ before do
12
+ allow(foo).to receive(:bar).and_return(baz)
13
+ ^^^^^^^^^^ Do not stub your test subject.
14
+ end
15
+
16
+ it 'uses expect twice' do
17
+ expect(foo.bar).to eq(baz)
18
+ end
19
+ end
20
+ RUBY
21
+ end
22
+
23
+ it 'complains when subject is mocked' do
24
+ expect_violation(<<-RUBY)
25
+ describe Foo do
26
+ subject(:foo) { described_class.new }
27
+
28
+ before do
29
+ expect(foo).to receive(:bar).and_return(baz)
30
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not stub your test subject.
31
+ expect(foo).to receive(:bar)
32
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not stub your test subject.
33
+ expect(foo).to receive(:bar).with(1)
34
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not stub your test subject.
35
+ expect(foo).to receive(:bar).with(1).and_return(2)
36
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not stub your test subject.
37
+ end
38
+
39
+ it 'uses expect twice' do
40
+ expect(foo.bar).to eq(baz)
41
+ end
42
+ end
43
+ RUBY
44
+ end
45
+
46
+ it 'ignores stub within context where subject name changed' do
47
+ expect_no_violations(<<-RUBY)
48
+ describe Foo do
49
+ subject(:foo) { described_class.new }
50
+
51
+ context 'when I shake things up' do
52
+ subject(:bar) { described_class.new }
53
+
54
+ it 'tries to trick rubocop-rspec' do
55
+ allow(foo).to receive(:baz)
56
+ end
57
+ end
58
+ end
59
+ RUBY
60
+ end
61
+
62
+ it 'flags nested subject stubs when nested subject uses same name' do
63
+ expect_violation(<<-RUBY)
64
+ describe Foo do
65
+ subject(:foo) { described_class.new }
66
+
67
+ context 'when I shake things up' do
68
+ subject(:foo) { described_class.new }
69
+
70
+ before do
71
+ allow(foo).to receive(:wow)
72
+ ^^^^^^^^^^ Do not stub your test subject.
73
+ end
74
+
75
+ it 'tries to trick rubocop-rspec' do
76
+ expect(foo).to eql(:neat)
77
+ end
78
+ end
79
+ end
80
+ RUBY
81
+ end
82
+
83
+ it 'ignores nested stubs when nested subject is anonymous' do
84
+ expect_no_violations(<<-RUBY)
85
+ describe Foo do
86
+ subject(:foo) { described_class.new }
87
+
88
+ context 'when I shake things up' do
89
+ subject { described_class.new }
90
+
91
+ before do
92
+ allow(foo).to receive(:wow)
93
+ end
94
+
95
+ it 'tries to trick rubocop-rspec' do
96
+ expect(foo).to eql(:neat)
97
+ end
98
+ end
99
+ end
100
+ RUBY
101
+ end
102
+
103
+ it 'flags nested subject stubs when example group does not define subject' do
104
+ expect_violation(<<-RUBY)
105
+ describe Foo do
106
+ subject(:foo) { described_class.new }
107
+
108
+ context 'when I shake things up' do
109
+ before do
110
+ allow(foo).to receive(:wow)
111
+ ^^^^^^^^^^ Do not stub your test subject.
112
+ end
113
+
114
+ it 'tries to trick rubocop-rspec' do
115
+ expect(foo).to eql(:neat)
116
+ end
117
+ end
118
+ end
119
+ RUBY
120
+ end
121
+
122
+ it 'flags nested subject stubs' do
123
+ expect_violation(<<-RUBY)
124
+ describe Foo do
125
+ subject(:foo) { described_class.new }
126
+
127
+ context 'when I shake things up' do
128
+ subject(:bar) { described_class.new }
129
+
130
+ before do
131
+ allow(foo).to receive(:wow)
132
+ allow(bar).to receive(:wow)
133
+ ^^^^^^^^^^ Do not stub your test subject.
134
+ end
135
+
136
+ it 'tries to trick rubocop-rspec' do
137
+ expect(bar).to eql(foo)
138
+ end
139
+ end
140
+ end
141
+ RUBY
142
+ end
143
+
144
+ it 'flags nested subject stubs when adjacent context redefines' do
145
+ expect_violation(<<-RUBY)
146
+ describe Foo do
147
+ subject(:foo) { described_class.new }
148
+
149
+ context 'when I do something in a context' do
150
+ subject { blah }
151
+ end
152
+
153
+ it 'still flags this test' do
154
+ allow(foo).to receive(:blah)
155
+ ^^^^^^^^^^ Do not stub your test subject.
156
+ end
157
+ end
158
+ RUBY
159
+ end
160
+
161
+ it 'flags deeply nested subject stubs' do
162
+ expect_violation(<<-RUBY)
163
+ describe Foo do
164
+ subject(:foo) { described_class.new }
165
+
166
+ context 'level 1' do
167
+ subject(:bar) { described_class.new }
168
+
169
+ context 'level 2' do
170
+ subject(:baz) { described_class.new }
171
+
172
+ before do
173
+ allow(foo).to receive(:wow)
174
+ allow(bar).to receive(:wow)
175
+ allow(baz).to receive(:wow)
176
+ ^^^^^^^^^^ Do not stub your test subject.
177
+ end
178
+ end
179
+ end
180
+ end
181
+ RUBY
182
+ end
183
+ end