reek 3.7.1 → 3.8.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.
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