reek 4.4.0 → 4.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/CONTRIBUTING.md +41 -4
  4. data/README.md +15 -3
  5. data/defaults.reek +1 -1
  6. data/docs/Basic-Smell-Options.md +2 -2
  7. data/docs/Code-Smells.md +4 -0
  8. data/docs/How-To-Write-New-Detectors.md +116 -0
  9. data/docs/How-reek-works-internally.md +3 -4
  10. data/docs/Instance-Variable-Assumption.md +134 -0
  11. data/docs/Simulated-Polymorphism.md +1 -1
  12. data/docs/Smell-Suppression.md +6 -6
  13. data/docs/{style-guide.md → Style-Guide.md} +0 -0
  14. data/docs/Unused-Private-Method.md +1 -1
  15. data/docs/YAML-Reports.md +0 -18
  16. data/features/configuration_files/directory_specific_directives.feature +4 -4
  17. data/features/configuration_files/unused_private_method.feature +2 -2
  18. data/features/samples.feature +122 -117
  19. data/features/smells/subclassed_from_core_class.feature +1 -1
  20. data/lib/reek/code_comment.rb +13 -4
  21. data/lib/reek/context/code_context.rb +1 -0
  22. data/lib/reek/examiner.rb +24 -27
  23. data/lib/reek/smells/class_variable.rb +1 -1
  24. data/lib/reek/smells/control_parameter.rb +1 -1
  25. data/lib/reek/smells/data_clump.rb +1 -1
  26. data/lib/reek/smells/duplicate_method_call.rb +1 -1
  27. data/lib/reek/smells/feature_envy.rb +1 -1
  28. data/lib/reek/smells/instance_variable_assumption.rb +1 -1
  29. data/lib/reek/smells/prima_donna_method.rb +1 -1
  30. data/lib/reek/smells/repeated_conditional.rb +1 -1
  31. data/lib/reek/smells/smell_detector.rb +5 -14
  32. data/lib/reek/smells/smell_repository.rb +1 -5
  33. data/lib/reek/smells/smell_warning.rb +6 -8
  34. data/lib/reek/smells/subclassed_from_core_class.rb +1 -1
  35. data/lib/reek/smells/uncommunicative_variable_name.rb +22 -12
  36. data/lib/reek/smells/unused_private_method.rb +1 -1
  37. data/lib/reek/spec.rb +2 -2
  38. data/lib/reek/spec/should_reek_of.rb +12 -8
  39. data/lib/reek/version.rb +1 -1
  40. data/spec/reek/code_comment_spec.rb +13 -5
  41. data/spec/reek/examiner_spec.rb +2 -2
  42. data/spec/reek/smells/attribute_spec.rb +91 -78
  43. data/spec/reek/smells/boolean_parameter_spec.rb +72 -64
  44. data/spec/reek/smells/class_variable_spec.rb +81 -68
  45. data/spec/reek/smells/control_parameter_spec.rb +101 -141
  46. data/spec/reek/smells/data_clump_spec.rb +94 -149
  47. data/spec/reek/smells/duplicate_method_call_spec.rb +98 -85
  48. data/spec/reek/smells/feature_envy_spec.rb +164 -183
  49. data/spec/reek/smells/instance_variable_assumption_spec.rb +51 -147
  50. data/spec/reek/smells/irresponsible_module_spec.rb +153 -170
  51. data/spec/reek/smells/long_parameter_list_spec.rb +44 -88
  52. data/spec/reek/smells/long_yield_list_spec.rb +41 -41
  53. data/spec/reek/smells/manual_dispatch_spec.rb +36 -18
  54. data/spec/reek/smells/module_initialize_spec.rb +31 -33
  55. data/spec/reek/smells/nested_iterators_spec.rb +189 -183
  56. data/spec/reek/smells/nil_check_spec.rb +48 -37
  57. data/spec/reek/smells/prima_donna_method_spec.rb +41 -26
  58. data/spec/reek/smells/repeated_conditional_spec.rb +75 -87
  59. data/spec/reek/smells/smell_warning_spec.rb +7 -0
  60. data/spec/reek/smells/subclassed_from_core_class_spec.rb +37 -112
  61. data/spec/reek/smells/too_many_constants_spec.rb +109 -199
  62. data/spec/reek/smells/too_many_instance_variables_spec.rb +105 -128
  63. data/spec/reek/smells/too_many_methods_spec.rb +38 -62
  64. data/spec/reek/smells/too_many_statements_spec.rb +69 -45
  65. data/spec/reek/smells/uncommunicative_method_name_spec.rb +16 -29
  66. data/spec/reek/smells/uncommunicative_module_name_spec.rb +24 -37
  67. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +55 -60
  68. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +108 -95
  69. data/spec/reek/smells/unused_parameters_spec.rb +73 -49
  70. data/spec/reek/smells/unused_private_method_spec.rb +97 -50
  71. data/spec/reek/smells/utility_function_spec.rb +130 -188
  72. data/spec/reek/spec/should_reek_of_spec.rb +2 -2
  73. metadata +6 -7
  74. data/lib/reek/cli/warning_collector.rb +0 -27
  75. data/spec/reek/cli/warning_collector_spec.rb +0 -25
  76. data/spec/reek/smells/smell_detector_shared.rb +0 -29
@@ -1,78 +1,54 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/too_many_methods'
3
- require_relative 'smell_detector_shared'
4
3
 
5
4
  RSpec.describe Reek::Smells::TooManyMethods do
6
- let(:detector) { described_class.new('max_methods' => 2) }
7
- let(:source_name) { 'string' }
8
-
9
- it_should_behave_like 'SmellDetector'
5
+ let(:config) do
6
+ { Reek::Smells::TooManyMethods::MAX_ALLOWED_METHODS_KEY => 3 }
7
+ end
10
8
 
11
- context 'counting methods' do
12
- it 'should not report if we stay below max_methods' do
13
- src = <<-EOS
14
- class Dummy
15
- def m1; end
16
- def m2; end
17
- end
18
- EOS
19
- syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
20
- ctx = Reek::Context::ModuleContext.new(nil, syntax_tree)
21
- expect(detector.sniff(ctx)).to be_empty
22
- end
9
+ it 'reports the right values' do
10
+ src = <<-EOS
11
+ class Alfa
12
+ def bravo; end
13
+ def charlie; end
14
+ def delta; end
15
+ def echo; end
16
+ end
17
+ EOS
23
18
 
24
- it 'should report if we exceed max_methods' do
25
- src = <<-EOS
26
- class Dummy
27
- def m1; end
28
- def m2; end
29
- def m3; end
30
- end
31
- EOS
32
- syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
33
- ctx = Reek::Context::ModuleContext.new(nil, syntax_tree)
34
- smells = detector.sniff(ctx)
35
- expect(smells.length).to eq(1)
36
- expect(smells[0].smell_type).to eq(described_class.smell_type)
37
- expect(smells[0].parameters[:count]).to eq(3)
38
- end
19
+ expect(src).to reek_of(:TooManyMethods,
20
+ lines: [1],
21
+ context: 'Alfa',
22
+ message: 'has at least 4 methods',
23
+ source: 'string',
24
+ count: 4).with_config(config)
39
25
  end
40
26
 
41
- context 'with a nested module' do
42
- it 'stops at a nested module' do
43
- src = <<-EOS
44
- class Dummy
45
- def m1; end
46
- def m2; end
47
- module Hidden
48
- def m3; end
49
- def m4; end
50
- def m5; end
51
- def m6; end
52
- end
53
- end
54
- EOS
55
- syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
56
- ctx = Reek::Context::ModuleContext.new(nil, syntax_tree)
57
- expect(detector.sniff(ctx)).to be_empty
58
- end
27
+ it 'should not report if we stay below max_methods' do
28
+ src = <<-EOS
29
+ class Alfa
30
+ def bravo; end
31
+ def charlie; end
32
+ def delta; end
33
+ end
34
+ EOS
35
+
36
+ expect(src).not_to reek_of(:TooManyMethods).with_config(config)
59
37
  end
60
38
 
61
- it 'reports correctly when the class has many methods' do
39
+ it 'stops at a nested module' do
62
40
  src = <<-EOS
63
- class Dummy
64
- def m1; end
65
- def m2; end
66
- def m3; end
41
+ class Alfa
42
+ def bravo; end
43
+ def charlie; end
44
+
45
+ module Hidden
46
+ def delta; end
47
+ def echo; end
48
+ end
67
49
  end
68
50
  EOS
69
51
 
70
- syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
71
- ctx = Reek::Context::ModuleContext.new(nil, syntax_tree)
72
- warning = detector.sniff(ctx)[0]
73
- expect(warning.source).to eq(source_name)
74
- expect(warning.smell_type).to eq(described_class.smell_type)
75
- expect(warning.parameters[:count]).to eq(3)
76
- expect(warning.lines).to eq([1])
52
+ expect(src).not_to reek_of(:TooManyMethods).with_config(config)
77
53
  end
78
54
  end
@@ -1,69 +1,93 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/too_many_statements'
3
- require_relative 'smell_detector_shared'
4
3
 
5
4
  RSpec.describe Reek::Smells::TooManyStatements do
6
- it 'should not report short methods' do
7
- src = 'def short(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;end'
8
- expect(src).not_to reek_of(:TooManyStatements)
5
+ let(:config) do
6
+ { Reek::Smells::TooManyStatements::MAX_ALLOWED_STATEMENTS_KEY => 2 }
9
7
  end
10
8
 
11
- it 'should report long methods' do
12
- src = 'def long() alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;@fry = 6;end'
13
- expect(src).to reek_of(:TooManyStatements)
14
- end
15
-
16
- it 'should not report initialize' do
9
+ it 'reports the right values' do
17
10
  src = <<-EOS
18
- def initialize(arga)
19
- alf = f(1); @bet = 2; @cut = 3; @dit = 4; @emp = 5; @fry = 6
11
+ class Alfa
12
+ def bravo
13
+ charlie = 1
14
+ delta = 2
15
+ echo = 3
16
+ end
20
17
  end
21
18
  EOS
22
- expect(src).not_to reek_of(:TooManyStatements)
19
+
20
+ expect(src).to reek_of(:TooManyStatements,
21
+ lines: [2],
22
+ context: 'Alfa#bravo',
23
+ message: 'has approx 3 statements',
24
+ source: 'string',
25
+ count: 3).with_config(config)
23
26
  end
24
27
 
25
- it 'should report long inner block' do
28
+ it 'does count all occurences' do
26
29
  src = <<-EOS
27
- def long()
28
- f(3)
29
- self.each do |xyzero|
30
- xyzero = 1
31
- xyzero = 2
32
- xyzero = 3
33
- xyzero = 4
34
- xyzero = 5
35
- xyzero = 6
30
+ class Alfa
31
+ def bravo
32
+ charlie = 1
33
+ delta = 2
34
+ echo = 3
35
+ end
36
+
37
+ def foxtrot
38
+ golf = 1
39
+ hotel = 2
40
+ india = 3
36
41
  end
37
42
  end
38
43
  EOS
39
- expect(src).to reek_of(:TooManyStatements)
44
+
45
+ expect(src).to reek_of(:TooManyStatements,
46
+ lines: [2],
47
+ context: 'Alfa#bravo').with_config(config)
48
+ expect(src).to reek_of(:TooManyStatements,
49
+ lines: [8],
50
+ context: 'Alfa#foxtrot').with_config(config)
40
51
  end
41
- end
42
52
 
43
- RSpec.describe Reek::Smells::TooManyStatements do
44
- let(:detector) { build(:smell_detector, smell_type: :TooManyStatements) }
53
+ it 'does not report short methods' do
54
+ src = <<-EOS
55
+ class Alfa
56
+ def bravo
57
+ charlie = 1
58
+ delta = 2
59
+ end
60
+ end
61
+ EOS
45
62
 
46
- it_should_behave_like 'SmellDetector'
63
+ expect(src).not_to reek_of(:TooManyStatements).with_config(config)
64
+ end
47
65
 
48
- context 'when the method has 30 statements' do
49
- let(:number_of_statements) { 30 }
50
- let(:smells) do
51
- ctx = double('method_context').as_null_object
52
- expect(ctx).to receive(:number_of_statements).and_return(number_of_statements)
53
- expect(ctx).to receive(:config_for).with(described_class).and_return({})
54
- detector.sniff(ctx)
55
- end
66
+ it 'does not report initialize' do
67
+ src = <<-EOS
68
+ class Alfa
69
+ def initialize
70
+ charlie = 1
71
+ delta = 2
72
+ echo = 3
73
+ end
74
+ end
75
+ EOS
56
76
 
57
- it 'reports only 1 smell' do
58
- expect(smells.length).to eq(1)
59
- end
77
+ expect(src).not_to reek_of(:TooManyStatements).with_config(config)
78
+ end
60
79
 
61
- it 'reports the number of statements' do
62
- expect(smells[0].parameters[:count]).to eq(number_of_statements)
63
- end
80
+ it 'reports long inner block' do
81
+ src = <<-EOS
82
+ def long
83
+ self.each do |x|
84
+ charlie = 1
85
+ delta = 2
86
+ echo = 3
87
+ end
88
+ end
89
+ EOS
64
90
 
65
- it 'reports the correct smell sub class' do
66
- expect(smells[0].smell_type).to eq(described_class.smell_type)
67
- end
91
+ expect(src).to reek_of(:TooManyStatements).with_config(config)
68
92
  end
69
93
  end
@@ -1,10 +1,19 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/uncommunicative_method_name'
3
- require_relative 'smell_detector_shared'
4
3
 
5
4
  RSpec.describe Reek::Smells::UncommunicativeMethodName do
6
- let(:detector) { build(:smell_detector, smell_type: :UncommunicativeMethodName) }
7
- it_should_behave_like 'SmellDetector'
5
+ it 'reports the right values' do
6
+ src = <<-EOS
7
+ def m; end
8
+ EOS
9
+
10
+ expect(src).to reek_of(:UncommunicativeMethodName,
11
+ lines: [1],
12
+ context: 'm',
13
+ message: "has the name 'm'",
14
+ source: 'string',
15
+ name: 'm')
16
+ end
8
17
 
9
18
  describe 'default configuration' do
10
19
  it 'reports one-word names' do
@@ -26,44 +35,22 @@ RSpec.describe Reek::Smells::UncommunicativeMethodName do
26
35
  end
27
36
  end
28
37
 
29
- describe 'sniff' do
30
- let(:source) { 'def x; end' }
31
- let(:context) { code_context(source) }
32
- let(:detector) { build(:smell_detector, smell_type: :UncommunicativeMethodName) }
33
-
34
- it 'returns an array of smell warnings' do
35
- smells = detector.sniff(context)
36
- expect(smells.length).to eq(1)
37
- expect(smells[0]).to be_a_kind_of(Reek::Smells::SmellWarning)
38
- end
39
-
40
- it 'contains proper smell warnings' do
41
- smells = detector.sniff(context)
42
- warning = smells[0]
43
-
44
- expect(warning.smell_type).to eq(Reek::Smells::UncommunicativeMethodName.smell_type)
45
- expect(warning.parameters[:name]).to eq('x')
46
- expect(warning.context).to match(/#{warning.parameters[:name]}/)
47
- expect(warning.lines).to eq([1])
48
- end
49
- end
50
-
51
38
  describe '`accept` patterns' do
52
39
  let(:source) { 'def x; end' }
53
40
 
54
41
  it 'make smelly names pass via regex / strings given by list / literal' do
55
42
  [[/x/], /x/, ['x'], 'x'].each do |pattern|
56
- expect(source).to_not reek_of(described_class).with_config('accept' => pattern)
43
+ expect(source).to_not reek_of(:UncommunicativeMethodName).with_config('accept' => pattern)
57
44
  end
58
45
  end
59
46
  end
60
47
 
61
48
  describe '`reject` patterns' do
62
- let(:source) { 'def helper; end' }
49
+ let(:source) { 'def alfa; end' }
63
50
 
64
51
  it 'reject smelly names via regex / strings given by list / literal' do
65
- [[/helper/], /helper/, ['helper'], 'helper'].each do |pattern|
66
- expect(source).to reek_of(described_class).with_config('reject' => pattern)
52
+ [[/alfa/], /alfa/, ['alfa'], 'alfa'].each do |pattern|
53
+ expect(source).to reek_of(:UncommunicativeMethodName).with_config('reject' => pattern)
67
54
  end
68
55
  end
69
56
  end
@@ -1,16 +1,25 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/uncommunicative_module_name'
3
- require_relative 'smell_detector_shared'
4
- require_lib 'reek/context/code_context'
5
3
 
6
4
  RSpec.describe Reek::Smells::UncommunicativeModuleName do
7
- let(:detector) { build(:smell_detector, smell_type: :UncommunicativeModuleName) }
8
- it_should_behave_like 'SmellDetector'
5
+ it 'reports the right values' do
6
+ src = <<-EOS
7
+ class K
8
+ end
9
+ EOS
10
+
11
+ expect(src).to reek_of(:UncommunicativeModuleName,
12
+ lines: [1],
13
+ context: 'K',
14
+ message: "has the name 'K'",
15
+ source: 'string',
16
+ name: 'K')
17
+ end
9
18
 
10
19
  describe 'default configuration' do
11
20
  ['class', 'module'].each do |type|
12
21
  it 'does not report one-word name' do
13
- expect("#{type} Helper; end").not_to reek_of(:UncommunicativeModuleName)
22
+ expect("#{type} Alfa; end").not_to reek_of(:UncommunicativeModuleName)
14
23
  end
15
24
 
16
25
  it 'reports one-letter name' do
@@ -22,49 +31,27 @@ RSpec.describe Reek::Smells::UncommunicativeModuleName do
22
31
  end
23
32
 
24
33
  it 'reports long name ending in a number' do
25
- expect("#{type} Printer2; end").to reek_of(:UncommunicativeModuleName, name: 'Printer2')
34
+ expect("#{type} Alfa2; end").to reek_of(:UncommunicativeModuleName, name: 'Alfa2')
26
35
  end
27
36
  end
28
37
  end
29
38
 
30
- describe 'sniff' do
31
- let(:source) { 'class Foo::X; end' }
32
- let(:context) { code_context(source) }
33
- let(:detector) { build(:smell_detector, smell_type: :UncommunicativeModuleName) }
34
-
35
- it 'returns an array of smell warnings' do
36
- smells = detector.sniff(context)
37
- expect(smells.length).to eq(1)
38
- expect(smells[0]).to be_a_kind_of(Reek::Smells::SmellWarning)
39
- end
40
-
41
- it 'contains proper smell warnings' do
42
- smells = detector.sniff(context)
43
- warning = smells[0]
44
-
45
- expect(warning.smell_type).to eq(Reek::Smells::UncommunicativeModuleName.smell_type)
46
- expect(warning.parameters[:name]).to eq('X')
47
- expect(warning.context).to match(/#{warning.parameters[:name]}/)
48
- expect(warning.lines).to eq([1])
49
- end
50
- end
51
-
52
39
  describe '`accept` patterns' do
53
- let(:source) { 'class Classy1; end' }
40
+ let(:source) { 'class Alfa1; end' }
54
41
 
55
- it 'make smelly names pass via regex / strings given by list / literal' do
56
- [[/lassy/], /lassy/, ['lassy'], 'lassy'].each do |pattern|
57
- expect(source).to_not reek_of(described_class).with_config('accept' => pattern)
42
+ it 'makes smelly names pass via regex / strings given by list / literal' do
43
+ [[/lfa/], /lfa/, ['lfa'], 'lfa'].each do |pattern|
44
+ expect(source).to_not reek_of(:UncommunicativeModuleName).with_config('accept' => pattern)
58
45
  end
59
46
  end
60
47
  end
61
48
 
62
49
  describe '`reject` patterns' do
63
- let(:source) { 'class BaseHelper; end' }
50
+ let(:source) { 'class Alfa; end' }
64
51
 
65
- it 'reject smelly names via regex / strings given by list / literal' do
66
- [[/Helper/], /Helper/, ['Helper'], 'Helper'].each do |pattern|
67
- expect(source).to reek_of(described_class).with_config('reject' => pattern)
52
+ it 'rejects smelly names via regex / strings given by list / literal' do
53
+ [[/Alfa/], /Alfa/, ['Alfa'], 'Alfa'].each do |pattern|
54
+ expect(source).to reek_of(:UncommunicativeModuleName).with_config('reject' => pattern)
68
55
  end
69
56
  end
70
57
  end
@@ -82,7 +69,7 @@ RSpec.describe Reek::Smells::UncommunicativeModuleName do
82
69
  end
83
70
 
84
71
  describe '.contexts' do
85
- it 'should be scoped to classes and modules' do
72
+ it 'are scoped to classes and modules' do
86
73
  expect(described_class.contexts).to eq([:module, :class])
87
74
  end
88
75
  end
@@ -1,115 +1,109 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/smells/uncommunicative_parameter_name'
3
- require_relative 'smell_detector_shared'
4
- require_lib 'reek/context/method_context'
5
3
 
6
4
  RSpec.describe Reek::Smells::UncommunicativeParameterName do
7
- let(:detector) { build(:smell_detector, smell_type: :UncommunicativeParameterName) }
8
- it_should_behave_like 'SmellDetector'
5
+ it 'reports the right values' do
6
+ src = <<-EOS
7
+ def alfa(x)
8
+ x
9
+ end
10
+ EOS
11
+
12
+ expect(src).to reek_of(:UncommunicativeParameterName,
13
+ lines: [1],
14
+ context: 'alfa',
15
+ message: "has the parameter name 'x'",
16
+ source: 'string',
17
+ name: 'x')
18
+ end
19
+
20
+ it 'does count all occurences' do
21
+ src = <<-EOS
22
+ def alfa(x, y)
23
+ [x, y]
24
+ end
25
+ EOS
26
+
27
+ expect(src).to reek_of(:UncommunicativeParameterName,
28
+ lines: [1],
29
+ name: 'x')
30
+ expect(src).to reek_of(:UncommunicativeParameterName,
31
+ lines: [1],
32
+ name: 'y')
33
+ end
9
34
 
10
- { 'obj.' => 'with a receiver',
35
+ { 'alfa.' => 'with a receiver',
11
36
  '' => 'without a receiver' }.each do |host, description|
12
37
  context "in a method definition #{description}" do
13
38
  it 'does not recognise *' do
14
- expect("def #{host}help(xray, *) basics(17) end").
15
- not_to reek_of(:UncommunicativeParameterName)
16
- end
17
-
18
- it "reports parameter's name" do
19
- src = "def #{host}help(x) basics(x) end"
20
- expect(src).to reek_of(:UncommunicativeParameterName,
21
- name: 'x')
39
+ expect("def #{host}bravo(*); end").not_to reek_of(:UncommunicativeParameterName)
22
40
  end
23
41
 
24
42
  it 'does not report unused parameters' do
25
- src = "def #{host}help(x) basics(17) end"
43
+ src = "def #{host}bravo(x); charlie; end"
26
44
  expect(src).not_to reek_of(:UncommunicativeParameterName)
27
45
  end
28
46
 
29
47
  it 'does not report two-letter parameter names' do
30
- expect("def #{host}help(ab) basics(ab) end").
31
- not_to reek_of(:UncommunicativeParameterName)
48
+ src = "def #{host}bravo(ab); charlie(ab); end"
49
+ expect(src).not_to reek_of(:UncommunicativeParameterName)
32
50
  end
33
51
 
34
52
  it 'reports names of the form "x2"' do
35
- src = "def #{host}help(x2) basics(x2) end"
36
- expect(src).to reek_of(:UncommunicativeParameterName,
37
- name: 'x2')
53
+ src = "def #{host}bravo(x2) charlie(x2) end"
54
+ expect(src).to reek_of(:UncommunicativeParameterName, name: 'x2')
38
55
  end
39
56
 
40
57
  it 'reports long name ending in a number' do
41
- src = "def #{host}help(param2) basics(param2) end"
42
- expect(src).to reek_of(:UncommunicativeParameterName,
43
- name: 'param2')
58
+ src = "def #{host}bravo(param2) charlie(param2) end"
59
+ expect(src).to reek_of(:UncommunicativeParameterName, name: 'param2')
44
60
  end
45
61
 
46
62
  it 'does not report unused anonymous parameter' do
47
- expect("def #{host}help(_) basics(17) end").
48
- not_to reek_of(:UncommunicativeParameterName)
63
+ src = "def #{host}bravo(_); charlie; end"
64
+ expect(src).not_to reek_of(:UncommunicativeParameterName)
49
65
  end
50
66
 
51
67
  it 'reports used anonymous parameter' do
52
- expect("def #{host}help(_) basics(_) end").
53
- to reek_of(:UncommunicativeParameterName)
68
+ src = "def #{host}bravo(_); charlie(_) end"
69
+ expect(src).to reek_of(:UncommunicativeParameterName)
54
70
  end
55
71
 
56
72
  it 'reports used parameters marked as unused' do
57
- expect("def #{host}help(_unused) basics(_unused) end").
58
- to reek_of(:UncommunicativeParameterName)
73
+ src = "def #{host}bravo(_unused) charlie(_unused) end"
74
+ expect(src).to reek_of(:UncommunicativeParameterName)
59
75
  end
60
76
 
61
77
  it 'reports names inside array decomposition' do
62
- src = "def #{host}help((b, nice)) basics(b, nice) end"
78
+ src = "def #{host}bravo((x, charlie)) delta(x, charlie) end"
63
79
  expect(src).to reek_of(:UncommunicativeParameterName,
64
- name: 'b')
80
+ name: 'x')
65
81
  end
66
82
 
67
83
  it 'reports names inside nested array decomposition' do
68
- src = "def #{host}help((foo, (bar, c))) basics(foo, c) end"
84
+ src = "def #{host}bravo((charlie, (delta, x))) echo(charlie, x) end"
69
85
  expect(src).to reek_of(:UncommunicativeParameterName,
70
- name: 'c')
86
+ name: 'x')
71
87
  end
72
88
  end
73
89
  end
74
90
 
75
- describe 'sniff' do
76
- let(:source) { 'def foo(bar2); baz(bar2); end' }
77
- let(:context) { method_context(source) }
78
- let(:detector) { build(:smell_detector, smell_type: :UncommunicativeParameterName) }
79
-
80
- it 'returns an array of smell warnings' do
81
- smells = detector.sniff(context)
82
- expect(smells.length).to eq(1)
83
- expect(smells[0]).to be_a_kind_of(Reek::Smells::SmellWarning)
84
- end
85
-
86
- it 'contains proper smell warnings' do
87
- smells = detector.sniff(context)
88
- warning = smells[0]
89
-
90
- expect(warning.smell_type).to eq(Reek::Smells::UncommunicativeParameterName.smell_type)
91
- expect(warning.parameters[:name]).to eq('bar2')
92
- expect(warning.context).to match('foo')
93
- expect(warning.lines).to eq([1])
94
- end
95
- end
96
-
97
91
  describe '`accept` patterns' do
98
- let(:source) { 'def foo(bar2); baz(bar2); end' }
92
+ let(:source) { 'def alfa(bar2); charlie(bar2); end' }
99
93
 
100
94
  it 'make smelly names pass via regex / strings given by list / literal' do
101
95
  [[/bar2/], /bar2/, ['bar2'], 'bar2'].each do |pattern|
102
- expect(source).to_not reek_of(described_class).with_config('accept' => pattern)
96
+ expect(source).to_not reek_of(:UncommunicativeParameterName).with_config('accept' => pattern)
103
97
  end
104
98
  end
105
99
  end
106
100
 
107
101
  describe '`reject` patterns' do
108
- let(:source) { 'def foo(bar); baz(bar); end' }
102
+ let(:source) { 'def alfa(bravo); charlie(bravo); end' }
109
103
 
110
104
  it 'reject smelly names via regex / strings given by list / literal' do
111
- [[/bar/], /bar/, ['bar'], 'bar'].each do |pattern|
112
- expect(source).to reek_of(described_class).with_config('reject' => pattern)
105
+ [[/bravo/], /bravo/, ['bravo'], 'bravo'].each do |pattern|
106
+ expect(source).to reek_of(:UncommunicativeParameterName).with_config('reject' => pattern)
113
107
  end
114
108
  end
115
109
  end
@@ -122,12 +116,13 @@ RSpec.describe Reek::Smells::UncommunicativeParameterName do
122
116
  'reject' => [/^.$/, /[0-9]$/, /[A-Z]/, /^_/],
123
117
  'accept' => []
124
118
  }
119
+
125
120
  expect(described_class.default_config).to eq(expected)
126
121
  end
127
122
  end
128
123
 
129
124
  describe '.contexts' do
130
- it 'should be scoped to classes and modules' do
125
+ it 'are scoped to classes and modules' do
131
126
  expect(described_class.contexts).to eq([:def, :defs])
132
127
  end
133
128
  end