reek 3.3.1 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/CHANGELOG.md +6 -0
  4. data/CONTRIBUTING.md +3 -0
  5. data/README.md +12 -4
  6. data/Rakefile +1 -0
  7. data/config/defaults.reek +1 -2
  8. data/docs/Nested-Iterators.md +6 -1
  9. data/docs/Smell-Suppression.md +69 -5
  10. data/docs/Uncommunicative-Module-Name.md +1 -1
  11. data/docs/Utility-Function.md +13 -1
  12. data/docs/style-guide.md +18 -0
  13. data/docs/templates/default/docstring/html/public_api_marker.erb +3 -0
  14. data/docs/templates/default/docstring/setup.rb +41 -0
  15. data/docs/templates/default/fulldoc/html/css/common.css +1 -0
  16. data/docs/yard_plugin.rb +2 -0
  17. data/features/command_line_interface/smell_selection.feature +1 -0
  18. data/features/configuration_files/masking_smells.feature +12 -0
  19. data/features/samples.feature +27 -26
  20. data/features/step_definitions/sample_file_steps.rb +25 -30
  21. data/lib/reek/ast/ast_node_class_map.rb +1 -1
  22. data/lib/reek/ast/node.rb +3 -4
  23. data/lib/reek/ast/object_refs.rb +2 -2
  24. data/lib/reek/ast/reference_collector.rb +0 -1
  25. data/lib/reek/ast/sexp_extensions.rb +1 -2
  26. data/lib/reek/ast/sexp_formatter.rb +1 -2
  27. data/lib/reek/cli/application.rb +0 -1
  28. data/lib/reek/cli/command.rb +0 -1
  29. data/lib/reek/cli/input.rb +2 -1
  30. data/lib/reek/cli/option_interpreter.rb +0 -1
  31. data/lib/reek/cli/options.rb +3 -1
  32. data/lib/reek/cli/reek_command.rb +0 -1
  33. data/lib/reek/cli/silencer.rb +4 -4
  34. data/lib/reek/cli/warning_collector.rb +0 -1
  35. data/lib/reek/code_comment.rb +6 -11
  36. data/lib/reek/configuration/app_configuration.rb +0 -3
  37. data/lib/reek/configuration/configuration_file_finder.rb +4 -1
  38. data/lib/reek/configuration/configuration_validator.rb +1 -0
  39. data/lib/reek/configuration/directory_directives.rb +4 -0
  40. data/lib/reek/configuration/excluded_paths.rb +2 -1
  41. data/lib/reek/context/code_context.rb +11 -4
  42. data/lib/reek/context/method_context.rb +1 -6
  43. data/lib/reek/context/module_context.rb +0 -1
  44. data/lib/reek/context/root_context.rb +0 -1
  45. data/lib/reek/context/singleton_method_context.rb +0 -1
  46. data/lib/reek/examiner.rb +15 -15
  47. data/lib/reek/rake/task.rb +14 -0
  48. data/lib/reek/report.rb +0 -8
  49. data/lib/reek/report/formatter.rb +13 -12
  50. data/lib/reek/report/heading_formatter.rb +2 -1
  51. data/lib/reek/report/location_formatter.rb +0 -3
  52. data/lib/reek/report/report.rb +34 -14
  53. data/lib/reek/smells/attribute.rb +6 -6
  54. data/lib/reek/smells/boolean_parameter.rb +8 -8
  55. data/lib/reek/smells/class_variable.rb +7 -6
  56. data/lib/reek/smells/control_parameter.rb +8 -7
  57. data/lib/reek/smells/data_clump.rb +18 -20
  58. data/lib/reek/smells/duplicate_method_call.rb +10 -6
  59. data/lib/reek/smells/feature_envy.rb +17 -9
  60. data/lib/reek/smells/irresponsible_module.rb +6 -6
  61. data/lib/reek/smells/long_parameter_list.rb +7 -7
  62. data/lib/reek/smells/long_yield_list.rb +10 -9
  63. data/lib/reek/smells/module_initialize.rb +7 -6
  64. data/lib/reek/smells/nested_iterators.rb +5 -6
  65. data/lib/reek/smells/nil_check.rb +4 -5
  66. data/lib/reek/smells/prima_donna_method.rb +5 -5
  67. data/lib/reek/smells/repeated_conditional.rb +9 -6
  68. data/lib/reek/smells/smell_configuration.rb +1 -7
  69. data/lib/reek/smells/smell_detector.rb +28 -25
  70. data/lib/reek/smells/smell_repository.rb +18 -19
  71. data/lib/reek/smells/smell_warning.rb +34 -21
  72. data/lib/reek/smells/too_many_instance_variables.rb +5 -6
  73. data/lib/reek/smells/too_many_methods.rb +6 -6
  74. data/lib/reek/smells/too_many_statements.rb +5 -6
  75. data/lib/reek/smells/uncommunicative_method_name.rb +6 -6
  76. data/lib/reek/smells/uncommunicative_module_name.rb +36 -22
  77. data/lib/reek/smells/uncommunicative_parameter_name.rb +27 -19
  78. data/lib/reek/smells/uncommunicative_variable_name.rb +13 -7
  79. data/lib/reek/smells/unused_parameters.rb +10 -9
  80. data/lib/reek/smells/utility_function.rb +22 -11
  81. data/lib/reek/source/source_code.rb +11 -12
  82. data/lib/reek/source/source_locator.rb +6 -1
  83. data/lib/reek/spec.rb +11 -0
  84. data/lib/reek/spec/should_reek.rb +0 -3
  85. data/lib/reek/spec/should_reek_of.rb +1 -1
  86. data/lib/reek/spec/should_reek_only_of.rb +0 -1
  87. data/lib/reek/tree_dresser.rb +3 -1
  88. data/lib/reek/tree_walker.rb +4 -5
  89. data/lib/reek/version.rb +4 -1
  90. data/reek.gemspec +1 -1
  91. data/spec/factories/factories.rb +17 -6
  92. data/spec/quality/reek_source_spec.rb +3 -1
  93. data/spec/reek/cli/warning_collector_spec.rb +3 -2
  94. data/spec/reek/code_comment_spec.rb +8 -10
  95. data/spec/reek/configuration/directory_directives_spec.rb +2 -2
  96. data/spec/reek/configuration/excluded_paths_spec.rb +2 -2
  97. data/spec/reek/context/method_context_spec.rb +0 -26
  98. data/spec/reek/report/json_report_spec.rb +83 -6
  99. data/spec/reek/report/yaml_report_spec.rb +76 -6
  100. data/spec/reek/smells/attribute_spec.rb +1 -1
  101. data/spec/reek/smells/boolean_parameter_spec.rb +2 -3
  102. data/spec/reek/smells/class_variable_spec.rb +1 -1
  103. data/spec/reek/smells/control_parameter_spec.rb +1 -1
  104. data/spec/reek/smells/data_clump_spec.rb +1 -1
  105. data/spec/reek/smells/duplicate_method_call_spec.rb +1 -1
  106. data/spec/reek/smells/feature_envy_spec.rb +1 -0
  107. data/spec/reek/smells/irresponsible_module_spec.rb +1 -1
  108. data/spec/reek/smells/long_parameter_list_spec.rb +1 -1
  109. data/spec/reek/smells/long_yield_list_spec.rb +1 -1
  110. data/spec/reek/smells/nested_iterators_spec.rb +1 -1
  111. data/spec/reek/smells/repeated_conditional_spec.rb +1 -1
  112. data/spec/reek/smells/smell_configuration_spec.rb +9 -9
  113. data/spec/reek/smells/smell_detector_shared.rb +0 -9
  114. data/spec/reek/smells/smell_repository_spec.rb +1 -8
  115. data/spec/reek/smells/smell_warning_spec.rb +3 -2
  116. data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
  117. data/spec/reek/smells/too_many_methods_spec.rb +2 -4
  118. data/spec/reek/smells/uncommunicative_method_name_spec.rb +1 -1
  119. data/spec/reek/smells/uncommunicative_module_name_spec.rb +22 -5
  120. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +1 -1
  121. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +1 -1
  122. data/spec/reek/smells/utility_function_spec.rb +49 -0
  123. metadata +9 -5
@@ -3,18 +3,88 @@ require_relative '../../../lib/reek/examiner'
3
3
  require_relative '../../../lib/reek/report/report'
4
4
  require_relative '../../../lib/reek/report/formatter'
5
5
 
6
+ require 'yaml'
7
+ require 'stringio'
8
+
6
9
  RSpec.describe Reek::Report::YAMLReport do
7
- let(:instance) { Reek::Report::YAMLReport.new }
10
+ let(:options) { {} }
11
+ let(:instance) { Reek::Report::YAMLReport.new(options) }
12
+ let(:examiner) { Reek::Examiner.new(source) }
8
13
 
9
- context 'empty source' do
10
- let(:examiner) { Reek::Examiner.new('') }
14
+ before do
15
+ instance.add_examiner examiner
16
+ end
11
17
 
12
- before do
13
- instance.add_examiner examiner
14
- end
18
+ context 'with empty source' do
19
+ let(:source) { '' }
15
20
 
16
21
  it 'prints empty yaml' do
17
22
  expect { instance.show }.to output(/^--- \[\]\n.*$/).to_stdout
18
23
  end
19
24
  end
25
+
26
+ context 'with smelly source' do
27
+ let(:source) { 'def simple(a) a[3] end' }
28
+
29
+ it 'prints smells as yaml' do
30
+ out = StringIO.new
31
+ instance.show(out)
32
+ out.rewind
33
+ result = YAML.load(out.read)
34
+ expected = YAML.load <<-EOS
35
+ ---
36
+ - context: "simple"
37
+ lines:
38
+ - 1
39
+ message: "doesn't depend on instance state (maybe move it to another class?)"
40
+ smell_category: "LowCohesion"
41
+ smell_type: "UtilityFunction"
42
+ source: "string"
43
+ name: "simple"
44
+ - context: "simple"
45
+ lines:
46
+ - 1
47
+ message: "has the parameter name 'a'"
48
+ smell_category: "UncommunicativeName"
49
+ smell_type: "UncommunicativeParameterName"
50
+ source: "string"
51
+ name: "a"
52
+ EOS
53
+
54
+ expect(result).to eq expected
55
+ end
56
+ context 'with link formatter' do
57
+ let(:options) { { warning_formatter: Reek::Report::WikiLinkWarningFormatter.new } }
58
+
59
+ it 'prints documentation links' do
60
+ out = StringIO.new
61
+ instance.show(out)
62
+ out.rewind
63
+ result = YAML.load(out.read)
64
+ expected = YAML.load <<-EOS
65
+ ---
66
+ - context: "simple"
67
+ lines:
68
+ - 1
69
+ message: "doesn't depend on instance state (maybe move it to another class?)"
70
+ smell_category: "LowCohesion"
71
+ smell_type: "UtilityFunction"
72
+ source: "string"
73
+ name: "simple"
74
+ wiki_link: "https://github.com/troessner/reek/blob/master/docs/Utility-Function.md"
75
+ - context: "simple"
76
+ lines:
77
+ - 1
78
+ message: "has the parameter name 'a'"
79
+ smell_category: "UncommunicativeName"
80
+ smell_type: "UncommunicativeParameterName"
81
+ source: "string"
82
+ name: "a"
83
+ wiki_link: "https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Parameter-Name.md"
84
+ EOS
85
+
86
+ expect(result).to eq expected
87
+ end
88
+ end
89
+ end
20
90
  end
@@ -4,7 +4,7 @@ require_relative 'smell_detector_shared'
4
4
 
5
5
  RSpec.describe Reek::Smells::Attribute do
6
6
  let(:detector) { build(:smell_detector, smell_type: :Attribute, source: source_name) }
7
- let(:source_name) { 'dummy_source' }
7
+ let(:source_name) { 'source' }
8
8
 
9
9
  it_should_behave_like 'SmellDetector'
10
10
 
@@ -67,15 +67,14 @@ RSpec.describe Reek::Smells::BooleanParameter do
67
67
 
68
68
  context 'when a smell is reported' do
69
69
  let(:detector) { build(:smell_detector, smell_type: :BooleanParameter, source: source_name) }
70
- let(:source_name) { 'dummy_source' }
70
+ let(:source_name) { 'string' }
71
71
 
72
72
  it_should_behave_like 'SmellDetector'
73
73
 
74
74
  it 'reports the fields correctly' do
75
75
  src = 'def cc(arga = true) end'
76
76
  ctx = Reek::Context::MethodContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
77
- detector.examine(ctx)
78
- smells = detector.smells_found.to_a
77
+ smells = detector.examine_context(ctx)
79
78
  expect(smells.length).to eq(1)
80
79
  expect(smells[0].smell_category).to eq(described_class.smell_category)
81
80
  expect(smells[0].parameters[:name]).to eq('arga')
@@ -6,7 +6,7 @@ require_relative 'smell_detector_shared'
6
6
  RSpec.describe Reek::Smells::ClassVariable do
7
7
  let(:class_variable) { '@@things' }
8
8
  let(:detector) { build(:smell_detector, smell_type: :ClassVariable, source: source_name) }
9
- let(:source_name) { 'dummy_source' }
9
+ let(:source_name) { 'string' }
10
10
 
11
11
  it_should_behave_like 'SmellDetector'
12
12
 
@@ -4,7 +4,7 @@ require_relative 'smell_detector_shared'
4
4
 
5
5
  RSpec.describe Reek::Smells::ControlParameter do
6
6
  let(:detector) { build(:smell_detector, smell_type: :ControlParameter, source: source_name) }
7
- let(:source_name) { 'dummy_source' }
7
+ let(:source_name) { 'string' }
8
8
 
9
9
  it_should_behave_like 'SmellDetector'
10
10
 
@@ -42,7 +42,7 @@ RSpec.shared_examples_for 'a data clump detector' do
42
42
  end
43
43
 
44
44
  it 'reports all methods' do
45
- expect(smells[0].parameters[:methods]).to eq(['first', 'second', 'third'])
45
+ expect(smells[0].parameters[:methods]).to eq([:first, :second, :third])
46
46
  end
47
47
 
48
48
  it 'reports the declaration line numbers' do
@@ -7,7 +7,7 @@ require_relative 'smell_detector_shared'
7
7
  RSpec.describe Reek::Smells::DuplicateMethodCall do
8
8
  context 'when a smell is reported' do
9
9
  let(:detector) { build(:smell_detector, smell_type: :DuplicateMethodCall, source: source_name) }
10
- let(:source_name) { 'dummy_source' }
10
+ let(:source_name) { 'string' }
11
11
 
12
12
  let(:warning) do
13
13
  src = <<-EOS
@@ -3,6 +3,7 @@ require_relative '../../../lib/reek/smells/feature_envy'
3
3
  require_relative '../../../lib/reek/examiner'
4
4
  require_relative 'smell_detector_shared'
5
5
 
6
+ # TODO: Bring specs in line with specs for other detectors
6
7
  RSpec.describe Reek::Smells::FeatureEnvy do
7
8
  context 'with no smell' do
8
9
  it 'should not report use of self' do
@@ -185,7 +185,7 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
185
185
 
186
186
  context 'when a smell is reported' do
187
187
  let(:detector) { build(:smell_detector, smell_type: :IrresponsibleModule, source: source_name) }
188
- let(:source_name) { 'dummy_source' }
188
+ let(:source_name) { 'string' }
189
189
 
190
190
  it_should_behave_like 'SmellDetector'
191
191
  end
@@ -75,7 +75,7 @@ end
75
75
 
76
76
  RSpec.describe Reek::Smells::LongParameterList do
77
77
  let(:detector) { build(:smell_detector, smell_type: :LongParameterList, source: source_name) }
78
- let(:source_name) { 'dummy_source' }
78
+ let(:source_name) { 'string' }
79
79
 
80
80
  it_should_behave_like 'SmellDetector'
81
81
 
@@ -5,7 +5,7 @@ require_relative 'smell_detector_shared'
5
5
 
6
6
  RSpec.describe Reek::Smells::LongYieldList do
7
7
  let(:detector) { build(:smell_detector, smell_type: :LongYieldList, source: source_name) }
8
- let(:source_name) { 'dummy_source' }
8
+ let(:source_name) { 'string' }
9
9
 
10
10
  it_should_behave_like 'SmellDetector'
11
11
 
@@ -213,7 +213,7 @@ end
213
213
 
214
214
  RSpec.describe Reek::Smells::NestedIterators do
215
215
  let(:detector) { build(:smell_detector, smell_type: :NestedIterators, source: source_name) }
216
- let(:source_name) { 'dummy_source' }
216
+ let(:source_name) { 'string' }
217
217
 
218
218
  it_should_behave_like 'SmellDetector'
219
219
 
@@ -6,7 +6,7 @@ require_relative '../../../lib/reek/source/source_code'
6
6
 
7
7
  RSpec.describe Reek::Smells::RepeatedConditional do
8
8
  let(:detector) { build(:smell_detector, smell_type: :RepeatedConditional, source: source_name) }
9
- let(:source_name) { 'dummy_source' }
9
+ let(:source_name) { 'string' }
10
10
 
11
11
  it_should_behave_like 'SmellDetector'
12
12
 
@@ -19,21 +19,21 @@ RSpec.describe Reek::Smells::SmellConfiguration do
19
19
 
20
20
  let(:smell_config) { described_class.new(base_config) }
21
21
 
22
- it { expect(smell_config.merge!({})).to eq(base_config) }
23
- it { expect(smell_config.merge!('enabled' => true)).to eq(base_config) }
24
- it { expect(smell_config.merge!('exclude' => [])).to eq(base_config) }
25
- it { expect(smell_config.merge!('accept' => ['_'])).to eq(base_config) }
22
+ it { expect(smell_config.merge({})).to eq(base_config) }
23
+ it { expect(smell_config.merge('enabled' => true)).to eq(base_config) }
24
+ it { expect(smell_config.merge('exclude' => [])).to eq(base_config) }
25
+ it { expect(smell_config.merge('accept' => ['_'])).to eq(base_config) }
26
26
  it do
27
- updated = smell_config.merge!('reject' => [/^.$/, /[0-9]$/, /[A-Z]/])
27
+ updated = smell_config.merge('reject' => [/^.$/, /[0-9]$/, /[A-Z]/])
28
28
  expect(updated).to eq(base_config)
29
29
  end
30
30
  it do
31
- updated = smell_config.merge!('accept' => ['_'], 'enabled' => true)
31
+ updated = smell_config.merge('accept' => ['_'], 'enabled' => true)
32
32
  expect(updated).to eq(base_config)
33
33
  end
34
34
 
35
35
  it 'should override single values' do
36
- updated = smell_config.merge!('enabled' => false)
36
+ updated = smell_config.merge('enabled' => false)
37
37
  expect(updated).to eq('accept' => ['_'],
38
38
  'enabled' => false,
39
39
  'exclude' => [],
@@ -41,7 +41,7 @@ RSpec.describe Reek::Smells::SmellConfiguration do
41
41
  end
42
42
 
43
43
  it 'should override arrays of values' do
44
- updated = smell_config.merge!('reject' => [/^.$/, /[3-9]$/])
44
+ updated = smell_config.merge('reject' => [/^.$/, /[3-9]$/])
45
45
  expect(updated).to eq('accept' => ['_'],
46
46
  'enabled' => true,
47
47
  'exclude' => [],
@@ -49,7 +49,7 @@ RSpec.describe Reek::Smells::SmellConfiguration do
49
49
  end
50
50
 
51
51
  it 'should override multiple values' do
52
- updated = smell_config.merge!('accept' => [/[A-Z]$/], 'enabled' => false)
52
+ updated = smell_config.merge('accept' => [/[A-Z]$/], 'enabled' => false)
53
53
  expect(updated).to eq('accept' => [/[A-Z]$/],
54
54
  'enabled' => false,
55
55
  'exclude' => [],
@@ -1,5 +1,4 @@
1
1
  require_relative '../../spec_helper'
2
- require_relative '../../../lib/reek/smells/smell_configuration'
3
2
 
4
3
  RSpec.shared_examples_for 'SmellDetector' do
5
4
  context 'exception matching follows the context' do
@@ -17,14 +16,6 @@ RSpec.shared_examples_for 'SmellDetector' do
17
16
  expect(detector.exception?(ctx)).to eq(true)
18
17
  end
19
18
  end
20
-
21
- context 'configuration' do
22
- it 'becomes disabled when disabled' do
23
- enabled_key = Reek::Smells::SmellConfiguration::ENABLED_KEY
24
- detector.configure_with(enabled_key => false)
25
- expect(detector).not_to be_enabled
26
- end
27
- end
28
19
  end
29
20
 
30
21
  RSpec.shared_examples_for 'common fields set correctly' do
@@ -11,19 +11,12 @@ RSpec.describe Reek::Smells::SmellRepository do
11
11
  expect(smell_types).to include(Reek::Smells::TooManyStatements)
12
12
  end
13
13
 
14
- it 'should exclude certain smell_types' do
14
+ it 'should exclude the smell detector base class' do
15
15
  expect(smell_types).to_not include(Reek::Smells::SmellDetector)
16
16
  end
17
17
 
18
18
  it 'should return the smell types in alphabetic order' do
19
19
  expect(smell_types).to eq(smell_types.sort_by(&:name))
20
20
  end
21
-
22
- it "should raise an ArgumentError if smell to configure doesn't exist" do
23
- repository = described_class.new
24
- expect { repository.configure('SomethingNonExistant', {}) }.
25
- to raise_error ArgumentError,
26
- 'Unknown smell type SomethingNonExistant found in configuration'
27
- end
28
21
  end
29
22
  end
@@ -108,12 +108,13 @@ RSpec.describe Reek::Smells::SmellWarning do
108
108
  end
109
109
 
110
110
  context 'with all details specified' do
111
- let(:detector) { Reek::Smells::FeatureEnvy.new source }
111
+ let(:detector) { Reek::Smells::FeatureEnvy.new }
112
112
  let(:parameters) { { 'one' => 34, 'two' => 'second' } }
113
113
  let(:smell_type) { 'FeatureEnvy' }
114
114
  let(:source) { 'a/ruby/source/file.rb' }
115
115
  let(:yaml) do
116
- warning = Reek::Smells::SmellWarning.new(detector, context: context_name,
116
+ warning = Reek::Smells::SmellWarning.new(detector, source: source,
117
+ context: context_name,
117
118
  lines: lines,
118
119
  message: message,
119
120
  parameters: parameters)
@@ -3,7 +3,7 @@ require_relative '../../../lib/reek/smells/too_many_instance_variables'
3
3
  require_relative 'smell_detector_shared'
4
4
 
5
5
  RSpec.describe Reek::Smells::TooManyInstanceVariables do
6
- let(:source_name) { 'dummy_source' }
6
+ let(:source_name) { 'string' }
7
7
  let(:detector) do
8
8
  build(:smell_detector, smell_type: :TooManyInstanceVariables, source: source_name)
9
9
  end
@@ -3,10 +3,8 @@ require_relative '../../../lib/reek/smells/too_many_methods'
3
3
  require_relative 'smell_detector_shared'
4
4
 
5
5
  RSpec.describe Reek::Smells::TooManyMethods do
6
- let(:detector) { described_class.new(source_name) }
7
- let(:source_name) { 'dummy_name' }
8
-
9
- before(:each) { detector.configure_with 'max_methods' => 2 }
6
+ let(:detector) { described_class.new('max_methods' => 2) }
7
+ let(:source_name) { 'string' }
10
8
 
11
9
  it_should_behave_like 'SmellDetector'
12
10
 
@@ -3,7 +3,7 @@ require_relative '../../../lib/reek/smells/uncommunicative_method_name'
3
3
  require_relative 'smell_detector_shared'
4
4
 
5
5
  RSpec.describe Reek::Smells::UncommunicativeMethodName do
6
- let(:source_name) { 'dummy_source' }
6
+ let(:source_name) { 'string' }
7
7
  let(:detector) do
8
8
  build(:smell_detector, smell_type: :UncommunicativeMethodName, source: source_name)
9
9
  end
@@ -4,7 +4,7 @@ require_relative 'smell_detector_shared'
4
4
  require_relative '../../../lib/reek/context/code_context'
5
5
 
6
6
  RSpec.describe Reek::Smells::UncommunicativeModuleName do
7
- let(:source_name) { 'dummy_source' }
7
+ let(:source_name) { 'string' }
8
8
  let(:detector) do
9
9
  build(:smell_detector, smell_type: :UncommunicativeModuleName, source: source_name)
10
10
  end
@@ -40,11 +40,28 @@ RSpec.describe Reek::Smells::UncommunicativeModuleName do
40
40
  end
41
41
  end
42
42
 
43
- context 'accepting names' do
44
- it 'accepts Inline::C' do
43
+ context 'accept patterns' do
44
+ let(:configuration) do
45
+ default_directive_for_smell = {
46
+ default_directive: {
47
+ Reek::Smells::UncommunicativeModuleName => {
48
+ 'accept' => ['Inline::C']
49
+ }
50
+ }
51
+ }
52
+ Reek::Configuration::AppConfiguration.from_map(default_directive_for_smell)
53
+ end
54
+
55
+ it 'make smelly name pass' do
45
56
  src = 'module Inline::C; end'
46
- ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
47
- expect(detector.examine_context(ctx)).to be_empty
57
+
58
+ expect(src).to_not reek_of(described_class, {}, configuration)
59
+ end
60
+
61
+ it 'reports names with typos' do
62
+ src = 'module Inline::K; end'
63
+
64
+ expect(src).to reek_of(described_class, {}, configuration)
48
65
  end
49
66
  end
50
67
 
@@ -7,7 +7,7 @@ RSpec.describe Reek::Smells::UncommunicativeParameterName do
7
7
  let(:detector) do
8
8
  build(:smell_detector, smell_type: :UncommunicativeParameterName, source: source_name)
9
9
  end
10
- let(:source_name) { 'dummy_source' }
10
+ let(:source_name) { 'string' }
11
11
 
12
12
  it_should_behave_like 'SmellDetector'
13
13
 
@@ -3,7 +3,7 @@ require_relative '../../../lib/reek/smells/uncommunicative_variable_name'
3
3
  require_relative 'smell_detector_shared'
4
4
 
5
5
  RSpec.describe Reek::Smells::UncommunicativeVariableName do
6
- let(:source_name) { 'dummy_source' }
6
+ let(:source_name) { 'string' }
7
7
  let(:detector) do
8
8
  build(:smell_detector, smell_type: :UncommunicativeVariableName, source: source_name)
9
9
  end
@@ -3,6 +3,7 @@ require_relative '../../../lib/reek/smells/utility_function'
3
3
  require_relative '../../../lib/reek/examiner'
4
4
  require_relative 'smell_detector_shared'
5
5
 
6
+ # TODO: Bring specs in line with specs for other detectors
6
7
  RSpec.describe Reek::Smells::UtilityFunction do
7
8
  describe 'a detector' do
8
9
  let(:detector) { build(:smell_detector, smell_type: :UtilityFunction, source: source_name) }
@@ -213,4 +214,52 @@ RSpec.describe Reek::Smells::UtilityFunction do
213
214
  expect(src).not_to reek_of(:UtilityFunction)
214
215
  end
215
216
  end
217
+
218
+ describe 'disabling UtilityFunction via configuration for non-public methods' do
219
+ let(:configuration) do
220
+ default_directive = {
221
+ default_directive: {
222
+ Reek::Smells::UtilityFunction => {
223
+ Reek::Smells::UtilityFunction::PUBLIC_METHODS_ONLY_KEY => true
224
+ }
225
+ }
226
+ }
227
+ Reek::Configuration::AppConfiguration.from_map(default_directive)
228
+ end
229
+
230
+ context 'public methods' do
231
+ it 'should still report UtilityFunction' do
232
+ src = <<-EOS
233
+ class C
234
+ def m1(a) a.to_s; end
235
+ end
236
+ EOS
237
+ expect(src).to reek_of(:UtilityFunction, { name: 'C#m1' }, configuration)
238
+ end
239
+ end
240
+
241
+ context 'private methods' do
242
+ it 'should not report UtilityFunction' do
243
+ src = <<-EOS
244
+ class C
245
+ private
246
+ def m1(a) a.to_s; end
247
+ end
248
+ EOS
249
+ expect(src).not_to reek_of(:UtilityFunction, {}, configuration)
250
+ end
251
+ end
252
+
253
+ context 'protected methods' do
254
+ it 'should not report UtilityFunction' do
255
+ src = <<-EOS
256
+ class C
257
+ protected
258
+ def m1(a) a.to_s; end
259
+ end
260
+ EOS
261
+ expect(src).not_to reek_of(:UtilityFunction, {}, configuration)
262
+ end
263
+ end
264
+ end
216
265
  end