reek 4.0.1 → 4.0.2

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/Gemfile +3 -3
  4. data/README.md +1 -1
  5. data/docs/Attribute.md +1 -1
  6. data/docs/Boolean-Parameter.md +8 -6
  7. data/docs/Class-Variable.md +1 -1
  8. data/docs/Command-Line-Options.md +26 -1
  9. data/docs/Control-Couple.md +13 -9
  10. data/docs/Control-Parameter.md +8 -5
  11. data/docs/Data-Clump.md +9 -7
  12. data/docs/Duplicate-Method-Call.md +1 -1
  13. data/docs/Irresponsible-Module.md +4 -3
  14. data/docs/Large-Class.md +7 -12
  15. data/docs/Long-Parameter-List.md +7 -6
  16. data/docs/Long-Yield-List.md +7 -6
  17. data/docs/Nested-Iterators.md +7 -7
  18. data/docs/Nil-Check.md +8 -4
  19. data/docs/Prima-Donna-Method.md +19 -9
  20. data/docs/Reek-Driven-Development.md +3 -1
  21. data/docs/Repeated-Conditional.md +5 -2
  22. data/docs/Too-Many-Instance-Variables.md +7 -7
  23. data/docs/Too-Many-Methods.md +10 -9
  24. data/docs/Too-Many-Statements.md +8 -4
  25. data/docs/Uncommunicative-Method-Name.md +8 -7
  26. data/docs/Uncommunicative-Module-Name.md +8 -8
  27. data/docs/Uncommunicative-Name.md +5 -3
  28. data/docs/Uncommunicative-Parameter-Name.md +9 -9
  29. data/docs/Uncommunicative-Variable-Name.md +8 -7
  30. data/docs/Unused-Parameters.md +5 -4
  31. data/docs/Unused-Private-Method.md +3 -3
  32. data/docs/Utility-Function.md +3 -3
  33. data/lib/reek/ast/object_refs.rb +4 -4
  34. data/lib/reek/cli/application.rb +40 -4
  35. data/lib/reek/cli/command/base_command.rb +3 -2
  36. data/lib/reek/cli/command/report_command.rb +35 -5
  37. data/lib/reek/cli/command/todo_list_command.rb +4 -4
  38. data/lib/reek/configuration/app_configuration.rb +15 -15
  39. data/lib/reek/configuration/default_directive.rb +2 -1
  40. data/lib/reek/context/code_context.rb +1 -1
  41. data/lib/reek/context/module_context.rb +5 -6
  42. data/lib/reek/spec.rb +6 -4
  43. data/lib/reek/spec/should_reek_of.rb +11 -3
  44. data/lib/reek/version.rb +1 -1
  45. data/spec/factories/factories.rb +0 -11
  46. data/spec/reek/cli/application_spec.rb +83 -9
  47. data/spec/reek/cli/command/report_command_spec.rb +17 -14
  48. data/spec/reek/cli/command/todo_list_command_spec.rb +12 -10
  49. data/spec/reek/smells/duplicate_method_call_spec.rb +8 -14
  50. data/spec/reek/smells/nested_iterators_spec.rb +12 -16
  51. data/spec/reek/smells/uncommunicative_method_name_spec.rb +2 -4
  52. data/spec/reek/smells/uncommunicative_module_name_spec.rb +2 -4
  53. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +2 -4
  54. data/spec/reek/smells/unused_private_method_spec.rb +47 -48
  55. data/spec/reek/smells/utility_function_spec.rb +5 -10
  56. data/spec/reek/spec/should_reek_of_spec.rb +27 -0
  57. metadata +2 -6
  58. data/lib/reek/cli/input.rb +0 -49
  59. data/lib/reek/cli/option_interpreter.rb +0 -58
  60. data/spec/reek/cli/input_spec.rb +0 -71
  61. data/spec/reek/cli/option_interpreter_spec.rb +0 -20
@@ -1,13 +1,17 @@
1
1
  require_relative '../../../spec_helper'
2
2
  require_lib 'reek/cli/command/todo_list_command'
3
3
  require_lib 'reek/cli/options'
4
- require_lib 'reek/cli/option_interpreter'
5
4
 
6
5
  RSpec.describe Reek::CLI::Command::TodoListCommand do
7
6
  describe '#execute' do
8
- let(:option_interpreter) { FactoryGirl.build(:options_interpreter_with_empty_sources) }
9
- let(:app) { double 'app' }
10
- let(:command) { described_class.new(option_interpreter, sources: []) }
7
+ let(:options) { Reek::CLI::Options.new [] }
8
+ let(:configuration) { double 'configuration' }
9
+
10
+ let(:command) do
11
+ described_class.new(options: options,
12
+ sources: [],
13
+ configuration: configuration)
14
+ end
11
15
 
12
16
  before do
13
17
  $stdout = StringIO.new
@@ -26,11 +30,11 @@ RSpec.describe Reek::CLI::Command::TodoListCommand do
26
30
 
27
31
  it 'shows a proper message' do
28
32
  expected = "\n'.todo.reek' generated! You can now use this as a starting point for your configuration.\n"
29
- expect { command.execute app }.to output(expected).to_stdout
33
+ expect { command.execute }.to output(expected).to_stdout
30
34
  end
31
35
 
32
36
  it 'returns a success code' do
33
- result = command.execute app
37
+ result = command.execute
34
38
  expect(result).to eq(Reek::CLI::Options::DEFAULT_SUCCESS_EXIT_CODE)
35
39
  end
36
40
  end
@@ -42,18 +46,16 @@ RSpec.describe Reek::CLI::Command::TodoListCommand do
42
46
 
43
47
  it 'shows a proper message' do
44
48
  expected = "\n'.todo.reek' not generated because there were no smells found!\n"
45
- expect { command.execute app }.to output(expected).to_stdout
49
+ expect { command.execute }.to output(expected).to_stdout
46
50
  end
47
51
 
48
52
  it 'returns a success code' do
49
- result = command.execute app
53
+ result = command.execute
50
54
  expect(result).to eq Reek::CLI::Options::DEFAULT_SUCCESS_EXIT_CODE
51
55
  end
52
56
  end
53
57
 
54
58
  describe 'groups_for' do
55
- let(:command) { described_class.new({}, sources: []) }
56
-
57
59
  it 'returns a proper hash representation of the smells found' do
58
60
  smells = [FactoryGirl.build(:smell_warning)]
59
61
  expected = { 'FeatureEnvy' => { 'exclude' => ['self'] } }
@@ -152,19 +152,17 @@ RSpec.describe Reek::Smells::DuplicateMethodCall do
152
152
 
153
153
  context 'allowing up to 3 calls' do
154
154
  let(:config) do
155
- { Reek::Smells::DuplicateMethodCall =>
156
- { Reek::Smells::DuplicateMethodCall::MAX_ALLOWED_CALLS_KEY => 3 } }
155
+ { Reek::Smells::DuplicateMethodCall::MAX_ALLOWED_CALLS_KEY => 3 }
157
156
  end
158
- let(:configuration) { test_configuration_for(config) }
159
157
 
160
158
  it 'does not report double calls' do
161
159
  src = 'def double_thing() @other.thing + @other.thing end'
162
- expect(src).not_to reek_of(:DuplicateMethodCall, {}, configuration)
160
+ expect(src).not_to reek_of(:DuplicateMethodCall).with_config(config)
163
161
  end
164
162
 
165
163
  it 'does not report triple calls' do
166
164
  src = 'def double_thing() @other.thing + @other.thing + @other.thing end'
167
- expect(src).not_to reek_of(:DuplicateMethodCall, {}, configuration)
165
+ expect(src).not_to reek_of(:DuplicateMethodCall).with_config(config)
168
166
  end
169
167
 
170
168
  it 'reports quadruple calls' do
@@ -174,35 +172,31 @@ RSpec.describe Reek::Smells::DuplicateMethodCall do
174
172
  end
175
173
  '
176
174
  expect(src).to reek_of(:DuplicateMethodCall,
177
- { name: '@other.thing', count: 4 },
178
- configuration)
175
+ name: '@other.thing', count: 4).with_config(config)
179
176
  end
180
177
  end
181
178
 
182
179
  context 'allowing calls to some methods' do
183
180
  let(:config) do
184
- { Reek::Smells::DuplicateMethodCall =>
185
- { Reek::Smells::DuplicateMethodCall::ALLOW_CALLS_KEY =>
186
- ['@some.thing', /puts/] } }
181
+ { Reek::Smells::DuplicateMethodCall::ALLOW_CALLS_KEY => ['@some.thing', /puts/] }
187
182
  end
188
- let(:configuration) { test_configuration_for(config) }
189
183
 
190
184
  it 'does not report calls to some methods' do
191
185
  src = 'def double_some_thing() @some.thing + @some.thing end'
192
186
 
193
- expect(src).not_to reek_of(:DuplicateMethodCall, {}, configuration)
187
+ expect(src).not_to reek_of(:DuplicateMethodCall).with_config(config)
194
188
  end
195
189
 
196
190
  it 'reports calls to other methods' do
197
191
  src = 'def double_other_thing() @other.thing + @other.thing end'
198
192
 
199
- expect(src).to reek_of(:DuplicateMethodCall, { name: '@other.thing' }, configuration)
193
+ expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing').with_config(config)
200
194
  end
201
195
 
202
196
  it 'does not report calls to methods specifed with a regular expression' do
203
197
  src = 'def double_puts() puts @other.thing; puts @other.thing end'
204
198
 
205
- expect(src).to reek_of(:DuplicateMethodCall, { name: '@other.thing' }, configuration)
199
+ expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing').with_config(config)
206
200
  end
207
201
  end
208
202
  end
@@ -174,10 +174,8 @@ RSpec.describe Reek::Smells::NestedIterators do
174
174
  end
175
175
 
176
176
  context 'when the allowed nesting depth is 3' do
177
- let(:configuration) do
178
- config = { Reek::Smells::NestedIterators =>
179
- { Reek::Smells::NestedIterators::MAX_ALLOWED_NESTING_KEY => 3 } }
180
- test_configuration_for(config)
177
+ let(:config) do
178
+ { Reek::Smells::NestedIterators::MAX_ALLOWED_NESTING_KEY => 3 }
181
179
  end
182
180
 
183
181
  it 'should not report nested iterators 2 levels deep' do
@@ -187,7 +185,7 @@ RSpec.describe Reek::Smells::NestedIterators do
187
185
  end
188
186
  EOS
189
187
 
190
- expect(src).not_to reek_of(:NestedIterators, {}, configuration)
188
+ expect(src).not_to reek_of(:NestedIterators).with_config(config)
191
189
  end
192
190
 
193
191
  it 'should not report nested iterators 3 levels deep' do
@@ -197,7 +195,7 @@ RSpec.describe Reek::Smells::NestedIterators do
197
195
  end
198
196
  EOS
199
197
 
200
- expect(src).not_to reek_of(:NestedIterators, {}, configuration)
198
+ expect(src).not_to reek_of(:NestedIterators).with_config(config)
201
199
  end
202
200
 
203
201
  it 'should report nested iterators 4 levels deep' do
@@ -207,25 +205,23 @@ RSpec.describe Reek::Smells::NestedIterators do
207
205
  end
208
206
  EOS
209
207
 
210
- expect(src).to reek_of(:NestedIterators, {}, configuration)
208
+ expect(src).to reek_of(:NestedIterators).with_config(config)
211
209
  end
212
210
  end
213
211
 
214
212
  context 'when ignoring iterators' do
215
- let(:configuration) do
216
- config = { Reek::Smells::NestedIterators =>
217
- { Reek::Smells::NestedIterators::IGNORE_ITERATORS_KEY => ['ignore_me'] } }
218
- test_configuration_for(config)
213
+ let(:config) do
214
+ { Reek::Smells::NestedIterators::IGNORE_ITERATORS_KEY => ['ignore_me'] }
219
215
  end
220
216
 
221
217
  it 'should not report nesting the ignored iterator inside another' do
222
218
  src = 'def bad(fred) @fred.each {|item| item.ignore_me {|ting| ting.ting} } end'
223
- expect(src).not_to reek_of(:NestedIterators, {}, configuration)
219
+ expect(src).not_to reek_of(:NestedIterators).with_config(config)
224
220
  end
225
221
 
226
222
  it 'should not report nesting inside the ignored iterator' do
227
223
  src = 'def bad(fred) @fred.ignore_me {|item| item.each {|ting| ting.ting} } end'
228
- expect(src).not_to reek_of(:NestedIterators, {}, configuration)
224
+ expect(src).not_to reek_of(:NestedIterators).with_config(config)
229
225
  end
230
226
 
231
227
  it 'should report nested iterators inside the ignored iterator' do
@@ -234,7 +230,7 @@ RSpec.describe Reek::Smells::NestedIterators do
234
230
  @fred.ignore_me {|item| item.each {|ting| ting.each {|other| other.other} } }
235
231
  end
236
232
  '
237
- expect(src).to reek_of(:NestedIterators, { count: 2 }, configuration)
233
+ expect(src).to reek_of(:NestedIterators, count: 2).with_config(config)
238
234
  end
239
235
 
240
236
  it 'should report nested iterators outside the ignored iterator' do
@@ -243,7 +239,7 @@ RSpec.describe Reek::Smells::NestedIterators do
243
239
  @fred.each {|item| item.each {|ting| ting.ignore_me {|other| other.other} } }
244
240
  end
245
241
  '
246
- expect(src).to reek_of(:NestedIterators, { count: 2 }, configuration)
242
+ expect(src).to reek_of(:NestedIterators, count: 2).with_config(config)
247
243
  end
248
244
 
249
245
  it 'should report nested iterators with the ignored iterator between them' do
@@ -252,7 +248,7 @@ RSpec.describe Reek::Smells::NestedIterators do
252
248
  @fred.each {|item| item.ignore_me {|ting| ting.ting {|other| other.other} } }
253
249
  end
254
250
  '
255
- expect(src).to reek_of(:NestedIterators, { count: 2 }, configuration)
251
+ expect(src).to reek_of(:NestedIterators, count: 2).with_config(config)
256
252
  end
257
253
  end
258
254
  end
@@ -53,8 +53,7 @@ RSpec.describe Reek::Smells::UncommunicativeMethodName do
53
53
 
54
54
  it 'make smelly names pass via regex / strings given by list / literal' do
55
55
  [[/x/], /x/, ['x'], 'x'].each do |pattern|
56
- configuration = accept_configuration_for(described_class, pattern: pattern)
57
- expect(source).to_not reek_of(described_class, {}, configuration)
56
+ expect(source).to_not reek_of(described_class).with_config('accept' => pattern)
58
57
  end
59
58
  end
60
59
  end
@@ -64,8 +63,7 @@ RSpec.describe Reek::Smells::UncommunicativeMethodName do
64
63
 
65
64
  it 'reject smelly names via regex / strings given by list / literal' do
66
65
  [[/helper/], /helper/, ['helper'], 'helper'].each do |pattern|
67
- configuration = reject_configuration_for(described_class, pattern: pattern)
68
- expect(source).to reek_of(described_class, {}, configuration)
66
+ expect(source).to reek_of(described_class).with_config('reject' => pattern)
69
67
  end
70
68
  end
71
69
  end
@@ -54,8 +54,7 @@ RSpec.describe Reek::Smells::UncommunicativeModuleName do
54
54
 
55
55
  it 'make smelly names pass via regex / strings given by list / literal' do
56
56
  [[/lassy/], /lassy/, ['lassy'], 'lassy'].each do |pattern|
57
- configuration = accept_configuration_for(described_class, pattern: pattern)
58
- expect(source).to_not reek_of(described_class, {}, configuration)
57
+ expect(source).to_not reek_of(described_class).with_config('accept' => pattern)
59
58
  end
60
59
  end
61
60
  end
@@ -65,8 +64,7 @@ RSpec.describe Reek::Smells::UncommunicativeModuleName do
65
64
 
66
65
  it 'reject smelly names via regex / strings given by list / literal' do
67
66
  [[/Helper/], /Helper/, ['Helper'], 'Helper'].each do |pattern|
68
- configuration = reject_configuration_for(described_class, pattern: pattern)
69
- expect(source).to reek_of(described_class, {}, configuration)
67
+ expect(source).to reek_of(described_class).with_config('reject' => pattern)
70
68
  end
71
69
  end
72
70
  end
@@ -99,8 +99,7 @@ RSpec.describe Reek::Smells::UncommunicativeParameterName do
99
99
 
100
100
  it 'make smelly names pass via regex / strings given by list / literal' do
101
101
  [[/bar2/], /bar2/, ['bar2'], 'bar2'].each do |pattern|
102
- configuration = accept_configuration_for(described_class, pattern: pattern)
103
- expect(source).to_not reek_of(described_class, {}, configuration)
102
+ expect(source).to_not reek_of(described_class).with_config('accept' => pattern)
104
103
  end
105
104
  end
106
105
  end
@@ -110,8 +109,7 @@ RSpec.describe Reek::Smells::UncommunicativeParameterName do
110
109
 
111
110
  it 'reject smelly names via regex / strings given by list / literal' do
112
111
  [[/bar/], /bar/, ['bar'], 'bar'].each do |pattern|
113
- configuration = reject_configuration_for(described_class, pattern: pattern)
114
- expect(source).to reek_of(described_class, {}, configuration)
112
+ expect(source).to reek_of(described_class).with_config('reject' => pattern)
115
113
  end
116
114
  end
117
115
  end
@@ -4,12 +4,6 @@ require_lib 'reek/examiner'
4
4
  require_relative 'smell_detector_shared'
5
5
 
6
6
  RSpec.describe Reek::Smells::UnusedPrivateMethod do
7
- let(:configuration) do
8
- test_configuration_for(
9
- described_class =>
10
- { Reek::Smells::SmellConfiguration::ENABLED_KEY => true }
11
- )
12
- end
13
7
  let(:detector) { build(:smell_detector, smell_type: :UnusedPrivateMethod) }
14
8
 
15
9
  it_should_behave_like 'SmellDetector'
@@ -24,32 +18,54 @@ RSpec.describe Reek::Smells::UnusedPrivateMethod do
24
18
  end
25
19
  EOF
26
20
 
27
- expect(source).to reek_of(:UnusedPrivateMethod, { name: :start }, configuration)
28
- expect(source).to reek_of(:UnusedPrivateMethod, { name: :drive }, configuration)
21
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :start)
22
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :drive)
29
23
  end
30
24
 
31
- it 'creates warnings correctly' do
25
+ it 'reports instance methods in the correct class' do
26
+ source = <<-EOF
27
+ class Car
28
+ class Engine
29
+ private
30
+ def start; end
31
+ end
32
+ end
33
+ EOF
34
+
35
+ expect(source).to reek_of(:UnusedPrivateMethod, context: 'Car::Engine', name: :start)
36
+ expect(source).not_to reek_of(:UnusedPrivateMethod, context: 'Car', name: :start)
37
+ end
38
+
39
+ it 'discounts calls to identically named methods in nested classes' do
32
40
  source = <<-EOF
33
41
  class Car
42
+ class Engine
43
+ def vroom
44
+ start
45
+ end
46
+ private
47
+ def start; end
48
+ end
34
49
  private
35
50
  def start; end
36
- def drive; end
37
51
  end
38
52
  EOF
39
53
 
40
- examiner = Reek::Examiner.new(source,
41
- filter_by_smells: 'UnusedPrivateMethod',
42
- configuration: configuration)
54
+ expect(source).not_to reek_of(:UnusedPrivateMethod, context: 'Car::Engine', name: :start)
55
+ expect(source).to reek_of(:UnusedPrivateMethod, context: 'Car', name: :start)
56
+ end
43
57
 
44
- first_warning = examiner.smells.first
45
- expect(first_warning.smell_type).to eq(Reek::Smells::UnusedPrivateMethod.smell_type)
46
- expect(first_warning.parameters[:name]).to eq(:drive)
47
- expect(first_warning.lines).to eq([4])
58
+ it 'creates warnings correctly' do
59
+ source = <<-EOF
60
+ class Car
61
+ private
62
+ def start; end
63
+ def drive; end
64
+ end
65
+ EOF
48
66
 
49
- second_warning = examiner.smells.last
50
- expect(second_warning.smell_type).to eq(Reek::Smells::UnusedPrivateMethod.smell_type)
51
- expect(second_warning.parameters[:name]).to eq(:start)
52
- expect(second_warning.lines).to eq([3])
67
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :drive, lines: [4])
68
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :start, lines: [3])
53
69
  end
54
70
  end
55
71
 
@@ -64,13 +80,8 @@ RSpec.describe Reek::Smells::UnusedPrivateMethod do
64
80
  end
65
81
  EOF
66
82
 
67
- examiner = Reek::Examiner.new(source,
68
- filter_by_smells: 'UnusedPrivateMethod',
69
- configuration: configuration)
70
-
71
- expect(examiner.smells.size).to eq(1)
72
- warning_for_drive = examiner.smells.first
73
- expect(warning_for_drive.parameters[:name]).to eq(:drive)
83
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :drive)
84
+ expect(source).not_to reek_of(:UnusedPrivateMethod, name: :start)
74
85
  end
75
86
  end
76
87
 
@@ -128,29 +139,17 @@ RSpec.describe Reek::Smells::UnusedPrivateMethod do
128
139
  end
129
140
 
130
141
  it 'excludes them via direct match in the app configuration' do
131
- configuration = test_configuration_for(
132
- described_class =>
133
- {
134
- Reek::Smells::SmellConfiguration::ENABLED_KEY => true,
135
- Reek::Smells::SmellDetector::EXCLUDE_KEY => ['Car#drive']
136
- }
137
- )
138
-
139
- expect(source).to reek_of(:UnusedPrivateMethod, { name: :start }, configuration)
140
- expect(source).not_to reek_of(:UnusedPrivateMethod, { name: :drive }, configuration)
142
+ config = { Reek::Smells::SmellDetector::EXCLUDE_KEY => ['Car#drive'] }
143
+
144
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :start).with_config(config)
145
+ expect(source).not_to reek_of(:UnusedPrivateMethod, name: :drive).with_config(config)
141
146
  end
142
147
 
143
148
  it 'excludes them via regex in the app configuration' do
144
- configuration = test_configuration_for(
145
- described_class =>
146
- {
147
- Reek::Smells::SmellConfiguration::ENABLED_KEY => true,
148
- Reek::Smells::SmellDetector::EXCLUDE_KEY => [/drive/]
149
- }
150
- )
151
-
152
- expect(source).to reek_of(:UnusedPrivateMethod, { name: :start }, configuration)
153
- expect(source).not_to reek_of(:UnusedPrivateMethod, { name: :drive }, configuration)
149
+ config = { Reek::Smells::SmellDetector::EXCLUDE_KEY => [/drive/] }
150
+
151
+ expect(source).to reek_of(:UnusedPrivateMethod, name: :start).with_config(config)
152
+ expect(source).not_to reek_of(:UnusedPrivateMethod, name: :drive).with_config(config)
154
153
  end
155
154
  end
156
155
  end
@@ -218,13 +218,8 @@ RSpec.describe Reek::Smells::UtilityFunction do
218
218
  end
219
219
 
220
220
  describe 'disabling UtilityFunction via configuration for non-public methods' do
221
- let(:configuration) do
222
- default_directive = {
223
- Reek::Smells::UtilityFunction => {
224
- Reek::Smells::UtilityFunction::PUBLIC_METHODS_ONLY_KEY => true
225
- }
226
- }
227
- Reek::Configuration::AppConfiguration.from_hash(default_directive)
221
+ let(:config) do
222
+ { Reek::Smells::UtilityFunction::PUBLIC_METHODS_ONLY_KEY => true }
228
223
  end
229
224
 
230
225
  context 'public methods' do
@@ -234,7 +229,7 @@ RSpec.describe Reek::Smells::UtilityFunction do
234
229
  def m1(a) a.to_s; end
235
230
  end
236
231
  EOS
237
- expect(src).to reek_of(:UtilityFunction, { name: 'C#m1' }, configuration)
232
+ expect(src).to reek_of(:UtilityFunction, name: 'C#m1').with_config(config)
238
233
  end
239
234
  end
240
235
 
@@ -246,7 +241,7 @@ RSpec.describe Reek::Smells::UtilityFunction do
246
241
  def m1(a) a.to_s; end
247
242
  end
248
243
  EOS
249
- expect(src).not_to reek_of(:UtilityFunction, {}, configuration)
244
+ expect(src).not_to reek_of(:UtilityFunction).with_config(config)
250
245
  end
251
246
  end
252
247
 
@@ -258,7 +253,7 @@ RSpec.describe Reek::Smells::UtilityFunction do
258
253
  def m1(a) a.to_s; end
259
254
  end
260
255
  EOS
261
- expect(src).not_to reek_of(:UtilityFunction, {}, configuration)
256
+ expect(src).not_to reek_of(:UtilityFunction).with_config(config)
262
257
  end
263
258
  end
264
259
  end
@@ -32,6 +32,11 @@ RSpec.describe Reek::Spec::ShouldReekOf do
32
32
  it 'doesnt match a fragrant String' do
33
33
  expect(matcher.matches?(clean_code)).to be_falsey
34
34
  end
35
+
36
+ it 're-calculates matches every time' do
37
+ matcher.matches? smelly_code
38
+ expect(matcher.matches?(clean_code)).to be_falsey
39
+ end
35
40
  end
36
41
 
37
42
  context 'checking code in a File' do
@@ -117,4 +122,26 @@ RSpec.describe Reek::Spec::ShouldReekOf do
117
122
  end
118
123
  end
119
124
  end
125
+
126
+ it 'enables the smell detector to match automatically' do
127
+ default_config = Reek::Smells::UnusedPrivateMethod.default_config
128
+ expect(default_config[Reek::Smells::SmellConfiguration::ENABLED_KEY]).to be_falsy
129
+
130
+ expect('class C; private; def foo; end; end').to reek_of(:UnusedPrivateMethod)
131
+ end
132
+
133
+ describe '#with_config' do
134
+ let(:matcher) { Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName) }
135
+ let(:configured_matcher) { matcher.with_config('accept' => 'x') }
136
+
137
+ it 'uses the passed-in configuration for matching' do
138
+ expect(configured_matcher.matches?('def foo; q = 2; end')).to be_truthy
139
+ expect(configured_matcher.matches?('def foo; x = 2; end')).to be_falsey
140
+ end
141
+
142
+ it 'leaves the original matcher intact' do
143
+ expect(configured_matcher.matches?('def foo; x = 2; end')).to be_falsey
144
+ expect(matcher.matches?('def foo; x = 2; end')).to be_truthy
145
+ end
146
+ end
120
147
  end