reek 3.7.1 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -1
  3. data/CHANGELOG.md +5 -0
  4. data/README.md +1 -1
  5. data/defaults.reek +3 -0
  6. data/docs/Code-Smells.md +1 -0
  7. data/docs/How-reek-works-internally.md +3 -2
  8. data/docs/Unused-Private-Method.md +47 -0
  9. data/features/samples.feature +22 -2
  10. data/features/step_definitions/sample_file_steps.rb +3 -0
  11. data/lib/reek/ast/node.rb +1 -2
  12. data/lib/reek/ast/object_refs.rb +30 -7
  13. data/lib/reek/code_comment.rb +25 -19
  14. data/lib/reek/context/class_context.rb +11 -0
  15. data/lib/reek/context/code_context.rb +58 -78
  16. data/lib/reek/context/module_context.rb +18 -0
  17. data/lib/reek/context/send_context.rb +17 -0
  18. data/lib/reek/context/singleton_method_context.rb +0 -3
  19. data/lib/reek/context/statement_counter.rb +32 -0
  20. data/lib/reek/context/visibility_tracker.rb +54 -0
  21. data/lib/reek/context_builder.rb +473 -0
  22. data/lib/reek/examiner.rb +14 -14
  23. data/lib/reek/smells/feature_envy.rb +3 -3
  24. data/lib/reek/smells/smell_detector.rb +1 -0
  25. data/lib/reek/smells/smell_repository.rb +11 -0
  26. data/lib/reek/smells/too_many_statements.rb +1 -1
  27. data/lib/reek/smells/unused_private_method.rb +82 -0
  28. data/lib/reek/smells/utility_function.rb +1 -1
  29. data/lib/reek/smells.rb +1 -0
  30. data/lib/reek/version.rb +1 -1
  31. data/spec/reek/ast/object_refs_spec.rb +20 -20
  32. data/spec/reek/cli/input_spec.rb +55 -0
  33. data/spec/reek/code_comment_spec.rb +10 -0
  34. data/spec/reek/context/code_context_spec.rb +8 -0
  35. data/spec/reek/context/module_context_spec.rb +10 -8
  36. data/spec/reek/context_builder_spec.rb +221 -0
  37. data/spec/reek/examiner_spec.rb +13 -0
  38. data/spec/reek/smells/boolean_parameter_spec.rb +2 -0
  39. data/spec/reek/smells/duplicate_method_call_spec.rb +1 -1
  40. data/spec/reek/smells/feature_envy_spec.rb +1 -1
  41. data/spec/reek/smells/too_many_statements_spec.rb +3 -3
  42. data/spec/reek/smells/unused_private_method_spec.rb +110 -0
  43. data/spec/spec_helper.rb +7 -0
  44. data/tasks/console.rake +5 -0
  45. metadata +13 -5
  46. data/lib/reek/tree_walker.rb +0 -237
  47. data/spec/reek/context/singleton_method_context_spec.rb +0 -16
  48. data/spec/reek/tree_walker_spec.rb +0 -237
@@ -0,0 +1,82 @@
1
+ require_relative 'smell_detector'
2
+ require_relative 'smell_warning'
3
+ require_relative '../context/method_context'
4
+
5
+ module Reek
6
+ module Smells
7
+ #
8
+ # Classes should use their private methods. Otherwise this is dead
9
+ # code which is confusing and bad for maintenance.
10
+ #
11
+ # See {file:docs/Unused-Private-Method.md} for details.
12
+ #
13
+ class UnusedPrivateMethod < SmellDetector
14
+ # Class for storing `hits` which are unused private methods
15
+ # we found in the given context. `name` and `line` are then used to
16
+ # construct SmellWarnings.
17
+ class Hit
18
+ attr_reader :name, :line
19
+
20
+ def initialize(context)
21
+ @name = context.name
22
+ @line = context.exp.line
23
+ end
24
+ end
25
+
26
+ def self.contexts
27
+ [:class]
28
+ end
29
+
30
+ #
31
+ # @param ctx [Context::ClassContext]
32
+ # @return [Array<SmellWarning>]
33
+ #
34
+ # :reek:FeatureEnvy
35
+ def inspect(ctx)
36
+ hits(ctx).map do |hit|
37
+ name = hit.name
38
+ smell_warning(
39
+ context: ctx,
40
+ lines: [hit.line],
41
+ message: "has the unused private instance method `#{name}`",
42
+ parameters: { name: name })
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ #
49
+ # @param ctx [Context::ClassContext]
50
+ # @return [Array<Hit>]
51
+ #
52
+ def hits(ctx)
53
+ unused_private_methods(ctx).map do |defined_method|
54
+ Hit.new(defined_method) unless ignore_method?(ctx, defined_method)
55
+ end.compact
56
+ end
57
+
58
+ #
59
+ # @param ctx [Context::ClassContext]
60
+ # @return [Array<Context::MethodContext]
61
+ #
62
+ # :reek:UtilityFunction
63
+ def unused_private_methods(ctx)
64
+ defined_private_methods = ctx.defined_instance_methods(visibility: :private)
65
+ called_method_names = ctx.instance_method_calls.map(&:name)
66
+
67
+ defined_private_methods.select do |defined_method|
68
+ !called_method_names.include?(defined_method.name)
69
+ end
70
+ end
71
+
72
+ #
73
+ # @param ctx [Context::ClassContext]
74
+ # @return [Boolean]
75
+ #
76
+ def ignore_method?(ctx, method)
77
+ ignore_methods = value(EXCLUDE_KEY, ctx, DEFAULT_EXCLUDE_SET)
78
+ ignore_methods.any? { |ignore_method| method.name[ignore_method] }
79
+ end
80
+ end
81
+ end
82
+ end
@@ -59,7 +59,7 @@ module Reek
59
59
  # :reek:TooManyStatements: { max_statements: 6 }
60
60
  def inspect(ctx)
61
61
  return [] if ctx.singleton_method?
62
- return [] if ctx.num_statements == 0
62
+ return [] if ctx.number_of_statements == 0
63
63
  return [] if ctx.references_self?
64
64
  return [] if num_helper_methods(ctx).zero?
65
65
  return [] if ignore_method?(ctx)
data/lib/reek/smells.rb CHANGED
@@ -21,4 +21,5 @@ require_relative 'smells/uncommunicative_module_name'
21
21
  require_relative 'smells/uncommunicative_parameter_name'
22
22
  require_relative 'smells/uncommunicative_variable_name'
23
23
  require_relative 'smells/unused_parameters'
24
+ require_relative 'smells/unused_private_method'
24
25
  require_relative 'smells/utility_function'
data/lib/reek/version.rb CHANGED
@@ -6,6 +6,6 @@ module Reek
6
6
  # @public
7
7
  module Version
8
8
  # @public
9
- STRING = '3.7.1'
9
+ STRING = '3.8.0'
10
10
  end
11
11
  end
@@ -13,9 +13,9 @@ RSpec.describe Reek::AST::ObjectRefs do
13
13
  context 'with references to a, b, and a' do
14
14
  context 'with no refs to self' do
15
15
  before(:each) do
16
- refs.record_reference_to(:a)
17
- refs.record_reference_to(:b)
18
- refs.record_reference_to(:a)
16
+ refs.record_reference(name: :a)
17
+ refs.record_reference(name: :b)
18
+ refs.record_reference(name: :a)
19
19
  end
20
20
 
21
21
  it 'should report no refs to self' do
@@ -32,7 +32,7 @@ RSpec.describe Reek::AST::ObjectRefs do
32
32
 
33
33
  context 'with one reference to self' do
34
34
  before(:each) do
35
- refs.record_reference_to(:self)
35
+ refs.record_reference(name: :self)
36
36
  end
37
37
 
38
38
  it 'should report 1 ref to self' do
@@ -53,13 +53,13 @@ RSpec.describe Reek::AST::ObjectRefs do
53
53
 
54
54
  context 'with many refs to self' do
55
55
  before(:each) do
56
- refs.record_reference_to(:self)
57
- refs.record_reference_to(:self)
58
- refs.record_reference_to(:a)
59
- refs.record_reference_to(:self)
60
- refs.record_reference_to(:b)
61
- refs.record_reference_to(:a)
62
- refs.record_reference_to(:self)
56
+ refs.record_reference(name: :self)
57
+ refs.record_reference(name: :self)
58
+ refs.record_reference(name: :a)
59
+ refs.record_reference(name: :self)
60
+ refs.record_reference(name: :b)
61
+ refs.record_reference(name: :a)
62
+ refs.record_reference(name: :self)
63
63
  end
64
64
 
65
65
  it 'should report all refs to self' do
@@ -77,11 +77,11 @@ RSpec.describe Reek::AST::ObjectRefs do
77
77
 
78
78
  context 'when self is not the only max' do
79
79
  before(:each) do
80
- refs.record_reference_to(:a)
81
- refs.record_reference_to(:self)
82
- refs.record_reference_to(:self)
83
- refs.record_reference_to(:b)
84
- refs.record_reference_to(:a)
80
+ refs.record_reference(name: :a)
81
+ refs.record_reference(name: :self)
82
+ refs.record_reference(name: :self)
83
+ refs.record_reference(name: :b)
84
+ refs.record_reference(name: :a)
85
85
  end
86
86
 
87
87
  it 'should report all refs to self' do
@@ -100,10 +100,10 @@ RSpec.describe Reek::AST::ObjectRefs do
100
100
 
101
101
  context 'when self is not among the max' do
102
102
  before(:each) do
103
- refs.record_reference_to(:a)
104
- refs.record_reference_to(:b)
105
- refs.record_reference_to(:a)
106
- refs.record_reference_to(:b)
103
+ refs.record_reference(name: :a)
104
+ refs.record_reference(name: :b)
105
+ refs.record_reference(name: :a)
106
+ refs.record_reference(name: :b)
107
107
  end
108
108
 
109
109
  it 'should report all refs to self' do
@@ -0,0 +1,55 @@
1
+ require_relative '../../spec_helper'
2
+ require_lib 'reek/cli/input'
3
+
4
+ RSpec.describe Reek::CLI::Input do
5
+ # dummy class which includes module under test
6
+ class DummyClass
7
+ include Reek::CLI::Input
8
+
9
+ def argv; end
10
+ end
11
+
12
+ subject { DummyClass.new }
13
+
14
+ describe '#sources' do
15
+ context 'when no source files given' do
16
+ before do
17
+ allow(subject).to receive(:argv).and_return([])
18
+ end
19
+
20
+ context 'and input was piped' do
21
+ before do
22
+ allow_any_instance_of(IO).to receive(:tty?).and_return(false)
23
+ expect(subject).to receive(:source_from_pipe).and_call_original
24
+ end
25
+
26
+ it 'should use source form pipe' do
27
+ expect(subject.sources).to_not be_empty
28
+ end
29
+ end
30
+
31
+ context 'and input was not piped' do
32
+ before do
33
+ allow_any_instance_of(IO).to receive(:tty?).and_return(true)
34
+ expect(subject).to receive(:working_directory_as_source).
35
+ and_call_original
36
+ end
37
+
38
+ it 'should use working directory as source' do
39
+ expect(subject.sources).to_not be_empty
40
+ end
41
+ end
42
+ end
43
+
44
+ context 'when source files given' do
45
+ before do
46
+ allow(subject).to receive(:argv).and_return(['.'])
47
+ expect(subject).to receive(:sources_from_argv).and_call_original
48
+ end
49
+
50
+ it 'should use sources from argv' do
51
+ expect(subject.sources).to_not be_empty
52
+ end
53
+ end
54
+ end
55
+ end
@@ -81,5 +81,15 @@ RSpec.describe Reek::CodeComment do
81
81
  config = described_class.new('# :reek: Duplication').config
82
82
  expect(config).not_to include('Duplication')
83
83
  end
84
+
85
+ it 'removes the configuration options from the comment' do
86
+ subject = described_class.new('
87
+ # Actual
88
+ # :reek:Duplication: { enabled: false }
89
+ # :reek:NestedIterators: { enabled: true }
90
+ # comment
91
+ ')
92
+ expect(subject.send(:sanitized_comment)).to eq('Actual comment')
93
+ end
84
94
  end
85
95
  end
@@ -17,21 +17,27 @@ RSpec.describe Reek::Context::CodeContext do
17
17
  it 'gets its short name from the exp' do
18
18
  expect(ctx.name).to eq(exp_name)
19
19
  end
20
+
20
21
  it 'does not match an empty list' do
21
22
  expect(ctx.matches?([])).to eq(false)
22
23
  end
24
+
23
25
  it 'does not match when its own short name is not given' do
24
26
  expect(ctx.matches?(['banana'])).to eq(false)
25
27
  end
28
+
26
29
  it 'does not let pipe-ended Strings make matching ignore the rest' do
27
30
  expect(ctx.matches?(['banana|'])).to eq(false)
28
31
  end
32
+
29
33
  it 'recognises its own short name' do
30
34
  expect(ctx.matches?(['banana', exp_name])).to eq(true)
31
35
  end
36
+
32
37
  it 'recognises its short name as a regex' do
33
38
  expect(ctx.matches?([/banana/, /#{exp_name}/])).to eq(true)
34
39
  end
40
+
35
41
  it 'does not blow up on []-ended Strings' do
36
42
  expect(ctx.matches?(['banana[]', exp_name])).to eq(true)
37
43
  end
@@ -49,9 +55,11 @@ RSpec.describe Reek::Context::CodeContext do
49
55
  it 'creates the correct full name' do
50
56
  expect(ctx.full_name).to eq(full_name)
51
57
  end
58
+
52
59
  it 'recognises its own full name' do
53
60
  expect(ctx.matches?(['banana', full_name])).to eq(true)
54
61
  end
62
+
55
63
  it 'recognises its full name as a regex' do
56
64
  expect(ctx.matches?([/banana/, /#{full_name}/])).to eq(true)
57
65
  end
@@ -12,18 +12,20 @@ RSpec.describe Reek::Context::ModuleContext do
12
12
  end
13
13
 
14
14
  it 'should not report module with empty class' do
15
- expect('# module for test
16
- module Fred
17
- # module for test
18
- class Jim; end; end').not_to reek
15
+ expect('
16
+ # module for test
17
+ module Fred
18
+ # module for test
19
+ class Jim; end; end').not_to reek
19
20
  end
20
21
  end
21
22
 
22
23
  RSpec.describe Reek::Context::ModuleContext do
23
24
  it 'should recognise global constant' do
24
- expect('# module for test
25
- module ::Global
26
- # module for test
27
- class Inside; end; end').not_to reek
25
+ expect('
26
+ # module for test
27
+ module ::Global
28
+ # module for test
29
+ class Inside; end; end').not_to reek
28
30
  end
29
31
  end
@@ -0,0 +1,221 @@
1
+ require_relative '../spec_helper'
2
+ require_lib 'reek/context_builder'
3
+
4
+ RSpec.describe Reek::ContextBuilder do
5
+ describe '#initialize' do
6
+ describe 'the structure of the context_tree' do
7
+ let(:walker) do
8
+ code = 'class Car; def drive; end; end'
9
+ described_class.new(syntax_tree(code))
10
+ end
11
+ let(:context_tree) { walker.context_tree }
12
+
13
+ it 'starts with a root node' do
14
+ expect(context_tree.type).to eq(:root)
15
+ expect(context_tree).to be_a(Reek::Context::RootContext)
16
+ end
17
+
18
+ it 'has one child' do
19
+ expect(context_tree.children.size).to eq(1)
20
+ end
21
+
22
+ describe 'the root node' do
23
+ let(:module_context) { context_tree.children.first }
24
+
25
+ it 'has one module_context' do
26
+ expect(module_context).to be_a(Reek::Context::ModuleContext)
27
+ end
28
+
29
+ it 'holds a reference to the parent context' do
30
+ expect(module_context.send(:context)).to eq(context_tree)
31
+ end
32
+
33
+ describe 'the module node' do
34
+ let(:method_context) { module_context.children.first }
35
+
36
+ it 'has one method_context' do
37
+ expect(method_context).to be_a(Reek::Context::MethodContext)
38
+ expect(module_context.children.size).to eq(1)
39
+ end
40
+
41
+ it 'holds a reference to the parent context' do
42
+ expect(method_context.send(:context)).to eq(module_context)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'statement counting' do
50
+ def tree(code)
51
+ described_class.new(syntax_tree(code)).context_tree
52
+ end
53
+
54
+ def number_of_statements_for(code)
55
+ tree(code).children.first.number_of_statements
56
+ end
57
+
58
+ it 'counts 1 assignment' do
59
+ code = 'def one() val = 4; end'
60
+ expect(number_of_statements_for(code)).to eq(1)
61
+ end
62
+
63
+ it 'counts 3 assignments' do
64
+ code = 'def one() val = 4; val = 4; val = 4; end'
65
+ expect(number_of_statements_for(code)).to eq(3)
66
+ end
67
+
68
+ it 'counts 1 attr assignment' do
69
+ code = 'def one() val[0] = 4; end'
70
+ expect(number_of_statements_for(code)).to eq(1)
71
+ end
72
+
73
+ it 'counts 1 increment assignment' do
74
+ code = 'def one() val += 4; end'
75
+ expect(number_of_statements_for(code)).to eq(1)
76
+ end
77
+
78
+ it 'counts 1 increment attr assignment' do
79
+ code = 'def one() val[0] += 4; end'
80
+ expect(number_of_statements_for(code)).to eq(1)
81
+ end
82
+
83
+ it 'counts 1 nested assignment' do
84
+ code = 'def one() val = fred = 4; end'
85
+ expect(number_of_statements_for(code)).to eq(1)
86
+ end
87
+
88
+ it 'counts returns' do
89
+ code = 'def one() val = 4; true; end'
90
+ expect(number_of_statements_for(code)).to eq(2)
91
+ end
92
+
93
+ it 'counts nil returns' do
94
+ code = 'def one() val = 4; nil; end'
95
+ expect(number_of_statements_for(code)).to eq(2)
96
+ end
97
+
98
+ context 'with control statements' do
99
+ it 'counts 3 statements in a conditional expression' do
100
+ code = 'def one() if val == 4; callee(); callee(); callee(); end; end'
101
+ expect(number_of_statements_for(code)).to eq(3)
102
+ end
103
+
104
+ it 'counts 3 statements in an else' do
105
+ code = <<-EOS
106
+ def one()
107
+ if val == 4
108
+ callee(); callee(); callee()
109
+ else
110
+ callee(); callee(); callee()
111
+ end
112
+ end
113
+ EOS
114
+
115
+ expect(number_of_statements_for(code)).to eq(6)
116
+ end
117
+
118
+ it 'does not count constant assignment with or equals' do
119
+ code = 'class Hi; CONST ||= 1; end'
120
+ expect(number_of_statements_for(code)).to eq(0)
121
+ end
122
+
123
+ it 'does not count multi constant assignment' do
124
+ code = 'class Hi; CONST, OTHER_CONST = 1, 2; end'
125
+ expect(number_of_statements_for(code)).to eq(0)
126
+ end
127
+
128
+ it 'does not count empty conditional expression' do
129
+ code = 'def one() if val == 4; ; end; end'
130
+ expect(number_of_statements_for(code)).to eq(0)
131
+ end
132
+
133
+ it 'does not count empty else' do
134
+ code = 'def one() if val == 4; ; else; ; end; end'
135
+ expect(number_of_statements_for(code)).to eq(0)
136
+ end
137
+
138
+ it 'counts extra statements in an if condition' do
139
+ code = 'def one() if begin val = callee(); val < 4 end; end; end'
140
+ expect(number_of_statements_for(code)).to eq(1)
141
+ end
142
+
143
+ it 'counts 3 statements in a while loop' do
144
+ code = 'def one() while val < 4; callee(); callee(); callee(); end; end'
145
+ expect(number_of_statements_for(code)).to eq(3)
146
+ end
147
+
148
+ it 'counts extra statements in a while condition' do
149
+ code = 'def one() while begin val = callee(); val < 4 end; end; end'
150
+ expect(number_of_statements_for(code)).to eq(1)
151
+ end
152
+
153
+ it 'counts 3 statements in a until loop' do
154
+ code = 'def one() until val < 4; callee(); callee(); callee(); end; end'
155
+ expect(number_of_statements_for(code)).to eq(3)
156
+ end
157
+
158
+ it 'counts 3 statements in a for loop' do
159
+ code = 'def one() for i in 0..4; callee(); callee(); callee(); end; end'
160
+ expect(number_of_statements_for(code)).to eq(3)
161
+ end
162
+
163
+ it 'counts 3 statements in a rescue' do
164
+ code = <<-EOS
165
+ def one()
166
+ begin
167
+ callee(); callee(); callee()
168
+ rescue
169
+ callee(); callee(); callee()
170
+ end
171
+ end
172
+ EOS
173
+ expect(number_of_statements_for(code)).to eq(6)
174
+ end
175
+
176
+ it 'counts 3 statements in a when' do
177
+ code = <<-EOS
178
+ def one()
179
+ case fred
180
+ when "hi" then callee(); callee()
181
+ when "lo" then callee()
182
+ end
183
+ end
184
+ EOS
185
+ expect(number_of_statements_for(code)).to eq(3)
186
+ end
187
+
188
+ it 'counts 3 statements in a case else' do
189
+ code = <<-EOS
190
+ def one()
191
+ case fred
192
+ when "hi" then callee(); callee(); callee()
193
+ else callee(); callee(); callee()
194
+ end
195
+ end
196
+ EOS
197
+ expect(number_of_statements_for(code)).to eq(6)
198
+ end
199
+
200
+ it 'does not count empty case' do
201
+ code = 'def one() case fred; when "hi"; ; when "lo"; ; end; end'
202
+ expect(number_of_statements_for(code)).to eq(0)
203
+ end
204
+
205
+ it 'does not count empty case else' do
206
+ code = 'def one() case fred; when "hi"; ; else; ; end; end'
207
+ expect(number_of_statements_for(code)).to eq(0)
208
+ end
209
+
210
+ it 'counts 4 statements in an iterator' do
211
+ code = 'def one() fred.each do; callee(); callee(); callee(); end; end'
212
+ expect(number_of_statements_for(code)).to eq(4)
213
+ end
214
+
215
+ it 'counts 1 statement in a singleton method' do
216
+ code = 'def self.foo; callee(); end'
217
+ expect(number_of_statements_for(code)).to eq(1)
218
+ end
219
+ end
220
+ end
221
+ end
@@ -14,9 +14,11 @@ RSpec.shared_examples_for 'one smell found' do
14
14
  it 'is smelly' do
15
15
  expect(examiner).to be_smelly
16
16
  end
17
+
17
18
  it 'reports the smell' do
18
19
  expect(examiner.smells.length).to eq(1)
19
20
  end
21
+
20
22
  it 'reports the correct smell' do
21
23
  expect(examiner.smells[0].smell_category).to eq(expected_first_smell)
22
24
  end
@@ -53,4 +55,15 @@ RSpec.describe Reek::Examiner do
53
55
 
54
56
  it_should_behave_like 'no smells found'
55
57
  end
58
+
59
+ describe '#smells' do
60
+ it 'returns the detected smell warnings' do
61
+ code = 'def foo; bar.call_me(); bar.call_me(); end'
62
+ examiner = described_class.new code, ['DuplicateMethodCall']
63
+
64
+ smell = examiner.smells.first
65
+ expect(smell).to be_a(Reek::Smells::SmellWarning)
66
+ expect(smell.message).to eq('calls bar.call_me 2 times')
67
+ end
68
+ end
56
69
  end
@@ -53,10 +53,12 @@ RSpec.describe Reek::Smells::BooleanParameter do
53
53
  src = 'def self.cc(arga = true) end'
54
54
  expect(src).to reek_of(:BooleanParameter, name: 'arga')
55
55
  end
56
+
56
57
  it 'reports a parameter defaulted to false' do
57
58
  src = 'def fred.cc(arga = false) end'
58
59
  expect(src).to reek_of(:BooleanParameter, name: 'arga')
59
60
  end
61
+
60
62
  it 'reports two parameters defaulted to booleans' do
61
63
  src = 'def Module.cc(nowt, arga = true, argb = false, &blk) end'
62
64
  expect(src).to reek_of(:BooleanParameter, name: 'arga')
@@ -1,7 +1,7 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/duplicate_method_call'
3
3
  require_lib 'reek/context/code_context'
4
- require_lib 'reek/tree_walker'
4
+ require_lib 'reek/context_builder'
5
5
  require_relative 'smell_detector_shared'
6
6
 
7
7
  RSpec.describe Reek::Smells::DuplicateMethodCall do
@@ -190,7 +190,7 @@ RSpec.describe Reek::Smells::FeatureEnvy do
190
190
  @report = Report.new
191
191
  cf = SmellConfig.new
192
192
  cf = cf.load_local(@dir) if @dir
193
- TreeWalker.new(@report, cf.smell_listeners).check_source(@source)
193
+ ContextBuilder.new(@report, cf.smell_listeners).check_source(@source)
194
194
  end
195
195
  @report
196
196
  end
@@ -46,10 +46,10 @@ RSpec.describe Reek::Smells::TooManyStatements do
46
46
  it_should_behave_like 'SmellDetector'
47
47
 
48
48
  context 'when the method has 30 statements' do
49
- let(:num_statements) { 30 }
49
+ let(:number_of_statements) { 30 }
50
50
  let(:smells) do
51
51
  ctx = double('method_context').as_null_object
52
- expect(ctx).to receive(:num_statements).and_return(num_statements)
52
+ expect(ctx).to receive(:number_of_statements).and_return(number_of_statements)
53
53
  expect(ctx).to receive(:config_for).with(described_class).and_return({})
54
54
  detector.inspect(ctx)
55
55
  end
@@ -59,7 +59,7 @@ RSpec.describe Reek::Smells::TooManyStatements do
59
59
  end
60
60
 
61
61
  it 'reports the number of statements' do
62
- expect(smells[0].parameters[:count]).to eq(num_statements)
62
+ expect(smells[0].parameters[:count]).to eq(number_of_statements)
63
63
  end
64
64
 
65
65
  it 'reports the correct smell sub class' do