reek 1.3.8 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +11 -0
  3. data/README.md +22 -14
  4. data/Rakefile +2 -15
  5. data/assets/html_output.html.erb +103 -0
  6. data/features/command_line_interface/options.feature +3 -0
  7. data/features/command_line_interface/smell_selection.feature +19 -0
  8. data/features/rake_task/rake_task.feature +1 -1
  9. data/features/reports/reports.feature +16 -0
  10. data/features/reports/yaml.feature +26 -23
  11. data/features/samples.feature +2 -1
  12. data/features/step_definitions/reek_steps.rb +15 -15
  13. data/features/support/env.rb +7 -9
  14. data/lib/reek/cli/application.rb +2 -4
  15. data/lib/reek/cli/command.rb +12 -0
  16. data/lib/reek/cli/help_command.rb +3 -6
  17. data/lib/reek/cli/options.rb +147 -0
  18. data/lib/reek/cli/reek_command.rb +18 -14
  19. data/lib/reek/cli/report/formatter.rb +56 -0
  20. data/lib/reek/cli/report/report.rb +106 -0
  21. data/lib/reek/cli/report/strategy.rb +63 -0
  22. data/lib/reek/cli/version_command.rb +3 -6
  23. data/lib/reek/config_file_exception.rb +0 -1
  24. data/lib/reek/core/code_context.rb +1 -3
  25. data/lib/reek/core/code_parser.rb +13 -12
  26. data/lib/reek/core/method_context.rb +13 -2
  27. data/lib/reek/core/module_context.rb +0 -4
  28. data/lib/reek/core/object_refs.rb +2 -3
  29. data/lib/reek/core/singleton_method_context.rb +0 -2
  30. data/lib/reek/core/smell_configuration.rb +3 -5
  31. data/lib/reek/core/smell_repository.rb +7 -8
  32. data/lib/reek/core/sniffer.rb +4 -10
  33. data/lib/reek/core/stop_context.rb +2 -4
  34. data/lib/reek/core/warning_collector.rb +0 -1
  35. data/lib/reek/examiner.rb +19 -17
  36. data/lib/reek/rake/task.rb +7 -10
  37. data/lib/reek/smell_warning.rb +4 -8
  38. data/lib/reek/smells.rb +0 -1
  39. data/lib/reek/smells/attribute.rb +8 -11
  40. data/lib/reek/smells/boolean_parameter.rb +5 -7
  41. data/lib/reek/smells/class_variable.rb +6 -7
  42. data/lib/reek/smells/control_parameter.rb +78 -45
  43. data/lib/reek/smells/data_clump.rb +13 -16
  44. data/lib/reek/smells/duplicate_method_call.rb +13 -11
  45. data/lib/reek/smells/feature_envy.rb +6 -7
  46. data/lib/reek/smells/irresponsible_module.rb +4 -6
  47. data/lib/reek/smells/long_parameter_list.rb +5 -7
  48. data/lib/reek/smells/long_yield_list.rb +2 -4
  49. data/lib/reek/smells/nested_iterators.rb +12 -22
  50. data/lib/reek/smells/nil_check.rb +35 -46
  51. data/lib/reek/smells/prima_donna_method.rb +24 -16
  52. data/lib/reek/smells/repeated_conditional.rb +8 -10
  53. data/lib/reek/smells/smell_detector.rb +9 -7
  54. data/lib/reek/smells/too_many_instance_variables.rb +7 -9
  55. data/lib/reek/smells/too_many_methods.rb +6 -8
  56. data/lib/reek/smells/too_many_statements.rb +4 -6
  57. data/lib/reek/smells/uncommunicative_method_name.rb +5 -7
  58. data/lib/reek/smells/uncommunicative_module_name.rb +5 -7
  59. data/lib/reek/smells/uncommunicative_parameter_name.rb +7 -9
  60. data/lib/reek/smells/uncommunicative_variable_name.rb +15 -18
  61. data/lib/reek/smells/unused_parameters.rb +5 -45
  62. data/lib/reek/smells/utility_function.rb +9 -10
  63. data/lib/reek/source.rb +0 -1
  64. data/lib/reek/source/code_comment.rb +7 -8
  65. data/lib/reek/source/config_file.rb +2 -4
  66. data/lib/reek/source/core_extras.rb +1 -1
  67. data/lib/reek/source/reference_collector.rb +1 -2
  68. data/lib/reek/source/sexp_extensions.rb +93 -10
  69. data/lib/reek/source/sexp_formatter.rb +2 -3
  70. data/lib/reek/source/sexp_node.rb +19 -15
  71. data/lib/reek/source/source_code.rb +4 -14
  72. data/lib/reek/source/source_file.rb +3 -5
  73. data/lib/reek/source/source_locator.rb +5 -6
  74. data/lib/reek/source/source_repository.rb +3 -3
  75. data/lib/reek/source/tree_dresser.rb +2 -2
  76. data/lib/reek/spec.rb +1 -2
  77. data/lib/reek/spec/should_reek.rb +8 -5
  78. data/lib/reek/spec/should_reek_of.rb +6 -4
  79. data/lib/reek/spec/should_reek_only_of.rb +10 -6
  80. data/lib/reek/version.rb +1 -1
  81. data/reek.gemspec +34 -30
  82. data/spec/gem/updates_spec.rb +3 -4
  83. data/spec/gem/yard_spec.rb +1 -2
  84. data/spec/matchers/smell_of_matcher.rb +12 -14
  85. data/spec/quality/reek_source_spec.rb +42 -0
  86. data/spec/reek/cli/help_command_spec.rb +7 -5
  87. data/spec/reek/cli/report_spec.rb +89 -22
  88. data/spec/reek/cli/version_command_spec.rb +8 -6
  89. data/spec/reek/core/code_context_spec.rb +25 -26
  90. data/spec/reek/core/code_parser_spec.rb +6 -6
  91. data/spec/reek/core/method_context_spec.rb +18 -18
  92. data/spec/reek/core/module_context_spec.rb +5 -5
  93. data/spec/reek/core/object_refs_spec.rb +21 -22
  94. data/spec/reek/core/smell_configuration_spec.rb +22 -21
  95. data/spec/reek/core/stop_context_spec.rb +2 -2
  96. data/spec/reek/core/warning_collector_spec.rb +3 -3
  97. data/spec/reek/examiner_spec.rb +9 -9
  98. data/spec/reek/smell_warning_spec.rb +29 -29
  99. data/spec/reek/smells/attribute_spec.rb +6 -6
  100. data/spec/reek/smells/behaves_like_variable_detector.rb +6 -6
  101. data/spec/reek/smells/boolean_parameter_spec.rb +17 -17
  102. data/spec/reek/smells/class_variable_spec.rb +9 -9
  103. data/spec/reek/smells/control_parameter_spec.rb +161 -137
  104. data/spec/reek/smells/data_clump_spec.rb +22 -19
  105. data/spec/reek/smells/duplicate_method_call_spec.rb +71 -27
  106. data/spec/reek/smells/feature_envy_spec.rb +32 -32
  107. data/spec/reek/smells/irresponsible_module_spec.rb +21 -21
  108. data/spec/reek/smells/long_parameter_list_spec.rb +14 -14
  109. data/spec/reek/smells/long_yield_list_spec.rb +6 -6
  110. data/spec/reek/smells/nested_iterators_spec.rb +21 -21
  111. data/spec/reek/smells/nil_check_spec.rb +23 -15
  112. data/spec/reek/smells/prima_donna_method_spec.rb +5 -5
  113. data/spec/reek/smells/repeated_conditional_spec.rb +14 -14
  114. data/spec/reek/smells/smell_detector_shared.rb +9 -9
  115. data/spec/reek/smells/too_many_instance_variables_spec.rb +12 -12
  116. data/spec/reek/smells/too_many_methods_spec.rb +10 -10
  117. data/spec/reek/smells/too_many_statements_spec.rb +41 -41
  118. data/spec/reek/smells/uncommunicative_method_name_spec.rb +4 -4
  119. data/spec/reek/smells/uncommunicative_module_name_spec.rb +12 -12
  120. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +21 -21
  121. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +49 -49
  122. data/spec/reek/smells/unused_parameters_spec.rb +26 -16
  123. data/spec/reek/smells/utility_function_spec.rb +20 -20
  124. data/spec/reek/source/code_comment_spec.rb +37 -37
  125. data/spec/reek/source/object_source_spec.rb +5 -5
  126. data/spec/reek/source/reference_collector_spec.rb +9 -9
  127. data/spec/reek/source/sexp_extensions_spec.rb +73 -52
  128. data/spec/reek/source/sexp_formatter_spec.rb +3 -4
  129. data/spec/reek/source/sexp_node_spec.rb +3 -3
  130. data/spec/reek/source/source_code_spec.rb +16 -15
  131. data/spec/reek/source/tree_dresser_spec.rb +2 -2
  132. data/spec/reek/spec/should_reek_of_spec.rb +11 -11
  133. data/spec/reek/spec/should_reek_only_of_spec.rb +11 -11
  134. data/spec/reek/spec/should_reek_spec.rb +11 -11
  135. data/spec/samples/one_smelly_file/dirty.rb +3 -0
  136. data/spec/spec_helper.rb +0 -6
  137. data/tasks/develop.rake +8 -16
  138. data/tasks/reek.rake +5 -13
  139. data/tasks/test.rake +5 -22
  140. metadata +56 -34
  141. data/lib/reek/cli/command_line.rb +0 -126
  142. data/lib/reek/cli/report.rb +0 -138
@@ -2,7 +2,7 @@ shared_examples_for 'a variable detector' do
2
2
  context 'with no variables' do
3
3
  it "doesn't record a smell" do
4
4
  @detector.examine_context(@ctx)
5
- @detector.smells_found.length.should == 0
5
+ expect(@detector.smells_found.length).to eq(0)
6
6
  end
7
7
  end
8
8
 
@@ -14,10 +14,10 @@ shared_examples_for 'a variable detector' do
14
14
  end
15
15
 
16
16
  it 'records only one smell' do
17
- @detector.smells_found.length.should == 1
17
+ expect(@detector.smells_found.length).to eq(1)
18
18
  end
19
19
  it 'mentions the variable name in the report' do
20
- @detector.should have_smell([/something/])
20
+ expect(@detector).to have_smell([/something/])
21
21
  end
22
22
  end
23
23
 
@@ -29,11 +29,11 @@ shared_examples_for 'a variable detector' do
29
29
  end
30
30
 
31
31
  it 'records both smells' do
32
- @detector.num_smells.should == 2
32
+ expect(@detector.num_smells).to eq(2)
33
33
  end
34
34
  it 'mentions both variable names in the report' do
35
- @detector.should have_smell([/something/])
36
- @detector.should have_smell([/something_else/])
35
+ expect(@detector).to have_smell([/something/])
36
+ expect(@detector).to have_smell([/something_else/])
37
37
  end
38
38
  end
39
39
  end
@@ -9,34 +9,34 @@ describe BooleanParameter do
9
9
  context 'in a method' do
10
10
  it 'reports a parameter defaulted to true' do
11
11
  src = 'def cc(arga = true) end'
12
- src.should smell_of(BooleanParameter, BooleanParameter::PARAMETER_KEY => 'arga')
12
+ expect(src).to smell_of(BooleanParameter, BooleanParameter::PARAMETER_KEY => 'arga')
13
13
  end
14
14
  it 'reports a parameter defaulted to false' do
15
15
  src = 'def cc(arga = false) end'
16
- src.should smell_of(BooleanParameter, BooleanParameter::PARAMETER_KEY => 'arga')
16
+ expect(src).to smell_of(BooleanParameter, BooleanParameter::PARAMETER_KEY => 'arga')
17
17
  end
18
18
  it 'reports two parameters defaulted to booleans' do
19
19
  src = 'def cc(nowt, arga = true, argb = false, &blk) end'
20
- src.should smell_of(BooleanParameter,
21
- {BooleanParameter::PARAMETER_KEY => 'arga'},
22
- {BooleanParameter::PARAMETER_KEY => 'argb'})
20
+ expect(src).to smell_of(BooleanParameter,
21
+ { BooleanParameter::PARAMETER_KEY => 'arga' },
22
+ BooleanParameter::PARAMETER_KEY => 'argb')
23
23
  end
24
24
  end
25
25
 
26
26
  context 'in a singleton method' do
27
27
  it 'reports a parameter defaulted to true' do
28
28
  src = 'def self.cc(arga = true) end'
29
- src.should smell_of(BooleanParameter, BooleanParameter::PARAMETER_KEY => 'arga')
29
+ expect(src).to smell_of(BooleanParameter, BooleanParameter::PARAMETER_KEY => 'arga')
30
30
  end
31
31
  it 'reports a parameter defaulted to false' do
32
32
  src = 'def fred.cc(arga = false) end'
33
- src.should smell_of(BooleanParameter, BooleanParameter::PARAMETER_KEY => 'arga')
33
+ expect(src).to smell_of(BooleanParameter, BooleanParameter::PARAMETER_KEY => 'arga')
34
34
  end
35
35
  it 'reports two parameters defaulted to booleans' do
36
36
  src = 'def Module.cc(nowt, arga = true, argb = false, &blk) end'
37
- src.should smell_of(BooleanParameter,
38
- {BooleanParameter::PARAMETER_KEY => 'arga'},
39
- {BooleanParameter::PARAMETER_KEY => 'argb'})
37
+ expect(src).to smell_of(BooleanParameter,
38
+ { BooleanParameter::PARAMETER_KEY => 'arga' },
39
+ BooleanParameter::PARAMETER_KEY => 'argb')
40
40
  end
41
41
  end
42
42
  end
@@ -54,13 +54,13 @@ describe BooleanParameter do
54
54
  ctx = MethodContext.new(nil, src.to_reek_source.syntax_tree)
55
55
  @detector.examine(ctx)
56
56
  smells = @detector.smells_found.to_a
57
- smells.length.should == 1
58
- smells[0].smell_class.should == BooleanParameter::SMELL_CLASS
59
- smells[0].smell[BooleanParameter::PARAMETER_KEY].should == 'arga'
60
- smells[0].source.should == @source_name
61
- smells[0].smell_class.should == BooleanParameter::SMELL_CLASS
62
- smells[0].subclass.should == BooleanParameter::SMELL_SUBCLASS
63
- smells[0].lines.should == [1]
57
+ expect(smells.length).to eq(1)
58
+ expect(smells[0].smell_class).to eq(BooleanParameter::SMELL_CLASS)
59
+ expect(smells[0].smell[BooleanParameter::PARAMETER_KEY]).to eq('arga')
60
+ expect(smells[0].source).to eq(@source_name)
61
+ expect(smells[0].smell_class).to eq(BooleanParameter::SMELL_CLASS)
62
+ expect(smells[0].subclass).to eq(BooleanParameter::SMELL_SUBCLASS)
63
+ expect(smells[0].lines).to eq([1])
64
64
  end
65
65
  end
66
66
  end
@@ -18,11 +18,11 @@ describe ClassVariable do
18
18
  context 'with no class variables' do
19
19
  it 'records nothing in the class' do
20
20
  exp = ast(:class, :Fred)
21
- @detector.examine_context(CodeContext.new(nil, exp)).should be_empty
21
+ expect(@detector.examine_context(CodeContext.new(nil, exp))).to be_empty
22
22
  end
23
23
  it 'records nothing in the module' do
24
24
  exp = ast(:module, :Fred)
25
- @detector.examine_context(CodeContext.new(nil, exp)).should be_empty
25
+ expect(@detector.examine_context(CodeContext.new(nil, exp))).to be_empty
26
26
  end
27
27
  end
28
28
 
@@ -33,10 +33,10 @@ describe ClassVariable do
33
33
  @smells = @detector.examine_context(CodeContext.new(nil, ast))
34
34
  end
35
35
  it 'records only that class variable' do
36
- @smells.length.should == 1
36
+ expect(@smells.length).to eq(1)
37
37
  end
38
38
  it 'records the variable name' do
39
- @smells[0].smell[ClassVariable::VARIABLE_KEY].should == @class_variable
39
+ expect(@smells[0].smell[ClassVariable::VARIABLE_KEY]).to eq(@class_variable)
40
40
  end
41
41
  end
42
42
 
@@ -91,10 +91,10 @@ end
91
91
  EOS
92
92
  ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
93
93
  @warning = @detector.examine_context(ctx)[0]
94
- @warning.source.should == @source_name
95
- @warning.smell_class.should == ClassVariable::SMELL_CLASS
96
- @warning.subclass.should == ClassVariable::SMELL_SUBCLASS
97
- @warning.smell[ClassVariable::VARIABLE_KEY].should == @class_variable
98
- @warning.lines.should == [2]
94
+ expect(@warning.source).to eq(@source_name)
95
+ expect(@warning.smell_class).to eq(ClassVariable::SMELL_CLASS)
96
+ expect(@warning.subclass).to eq(ClassVariable::SMELL_SUBCLASS)
97
+ expect(@warning.smell[ClassVariable::VARIABLE_KEY]).to eq(@class_variable)
98
+ expect(@warning.lines).to eq([2])
99
99
  end
100
100
  end
@@ -12,233 +12,257 @@ describe ControlParameter do
12
12
 
13
13
  it_should_behave_like 'SmellDetector'
14
14
 
15
- it 'should not report a ternary check on an ivar' do
16
- src = 'def simple(arga) @ivar ? arga : 3 end'
17
- src.should_not smell_of(ControlParameter)
18
- end
19
-
20
- it 'should not report a ternary check on a lvar' do
21
- src = 'def simple(arga) lvar = 27; lvar ? arga : @ivar end'
22
- src.should_not smell_of(ControlParameter)
23
- end
24
15
 
25
- it 'should not report when parameter is unused' do
26
- src = 'def simple(arg) test = 1 end'
27
- src.should_not smell_of(ControlParameter)
28
- end
16
+ context 'parameter not used to determine code path' do
17
+ it 'does not report a ternary check on an ivar' do
18
+ src = 'def simple(arga) @ivar ? arga : 3 end'
19
+ expect(src).not_to smell_of(ControlParameter)
20
+ end
29
21
 
30
- it 'should not report when parameter is used inside conditional' do
31
- src = 'def simple(arg) if true then puts arg end end'
32
- src.should_not smell_of(ControlParameter)
33
- end
22
+ it 'does not report a ternary check on a lvar' do
23
+ src = 'def simple(arga) lvar = 27; lvar ? arga : @ivar end'
24
+ expect(src).not_to smell_of(ControlParameter)
25
+ end
34
26
 
35
- it 'should not report when used in first conditional but not second' do
36
- src = <<EOS
37
- def things(arg)
38
- if arg
39
- puts arg
40
- end
41
- if arg
42
- puts 'a'
43
- end
44
- end
45
- EOS
46
- src.should_not smell_of(ControlParameter)
47
- end
27
+ it 'does not report when parameter is unused' do
28
+ src = 'def simple(arg) test = 1 end'
29
+ expect(src).not_to smell_of(ControlParameter)
30
+ end
48
31
 
49
- it 'should not report when used in second conditional but not first' do
50
- src = <<EOS
51
- def things(arg)
52
- if arg
53
- puts 'a'
54
- end
55
- if arg
56
- puts arg
57
- end
58
- end
59
- EOS
60
- src.should_not smell_of(ControlParameter)
32
+ it 'does not report when parameter is used inside conditional' do
33
+ src = 'def simple(arg) if true then puts arg end end'
34
+ expect(src).not_to smell_of(ControlParameter)
35
+ end
61
36
  end
62
37
 
63
- it 'should not report on complex non smelly method' do
64
- src = <<EOS
65
- def self.guess(arg)
66
- case arg
67
- when ""
68
- t = self
69
- when "a"
70
- t = Switch::OptionalArgument
71
- when "b"
72
- t = Switch::PlacedArgument
73
- else
74
- t = Switch::RequiredArgument
75
- end
76
- self >= t or incompatible_argument_styles(arg, t)
77
- t
78
- end
79
- EOS
80
- src.should_not smell_of(ControlParameter)
81
- end
82
38
 
83
39
  context 'parameter only used to determine code path' do
84
- it 'should report a ternary check on a parameter' do
40
+ it 'reports a ternary check on a parameter' do
85
41
  src = 'def simple(arga) arga ? @ivar : 3 end'
86
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arga')
42
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arga')
87
43
  end
88
44
 
89
- it 'should spot a couple inside a block' do
45
+ it 'reports a couple inside a block' do
90
46
  src = 'def blocks(arg) @text.map { |blk| arg ? blk : "#{blk}" } end'
91
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
47
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
92
48
  end
93
49
 
94
- it 'should report on an if statement modifier' do
50
+ it 'reports on an if statement modifier' do
95
51
  src = 'def simple(arg) args = {}; args.merge(\'a\' => \'A\') if arg end'
96
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
52
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
97
53
  end
98
54
 
99
- it 'should report on an unless statement modifier' do
55
+ it 'reports on an unless statement modifier' do
100
56
  src = 'def simple(arg) args = {}; args.merge(\'a\' => \'A\') unless arg end'
101
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
57
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
102
58
  end
103
59
 
104
- it 'should report on if control expression' do
60
+ it 'reports on if control expression' do
105
61
  src = 'def simple(arg) args = {}; if arg then args.merge(\'a\' => \'A\') end end'
106
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
62
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
107
63
  end
108
64
 
109
- it 'should report on if control expression with &&' do
65
+ it 'reports on if control expression with &&' do
110
66
  src = 'def simple(arg) if arg && true then puts "arg" end end'
111
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
67
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
112
68
  end
113
69
 
114
- it 'should report on if control expression with preceding &&' do
70
+ it 'reports on if control expression with preceding &&' do
115
71
  src = 'def simple(arg) if true && arg then puts "arg" end end'
116
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
72
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
117
73
  end
118
74
 
119
- it 'should report on if control expression with two && conditions' do
75
+ it 'reports on if control expression with two && conditions' do
120
76
  src = 'def simple(a) ag = {}; if a && true && true then puts "2" end end'
121
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'a')
77
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'a')
122
78
  end
123
79
 
124
- it 'should report on if control expression with ||' do
80
+ it 'reports on if control expression with ||' do
125
81
  src = 'def simple(arg) args = {}; if arg || true then puts "arg" end end'
126
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
82
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
127
83
  end
128
84
 
129
- it 'should report on if control expression with or' do
85
+ it 'reports on if control expression with or' do
130
86
  src = 'def simple(arg) args = {}; if arg or true then puts "arg" end end'
131
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
87
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
132
88
  end
133
89
 
134
- it 'should report on && notation' do
90
+ it 'reports on if control expression with if' do
91
+ src = 'def simple(arg) args = {}; if (arg if true) then puts "arg" end end'
92
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
93
+ end
94
+
95
+ it 'reports on && notation' do
135
96
  src = 'def simple(arg) args = {}; arg && args.merge(\'a\' => \'A\') end'
136
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
97
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
137
98
  end
138
99
 
139
- it 'should report on || notation' do
100
+ it 'reports on || notation' do
140
101
  src = 'def simple(arg) args = {}; arg || args.merge(\'a\' => \'A\') end'
141
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
102
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
142
103
  end
143
104
 
144
- it 'should report on case statement' do
105
+ it 'reports on case statement' do
145
106
  src = 'def simple(arg) case arg when nil; nil when false; nil else nil end end'
146
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
107
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
147
108
  end
148
109
 
149
- it 'should report when the argument is a hash on which we access a key' do
150
- src = 'def simple(arg) if arg[\'a\'] then puts \'a\' else puts \'b\' end end'
151
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
110
+ it 'reports on nested if statements that are both control parameters' do
111
+ src = <<-EOS
112
+ def nested(arg)
113
+ if arg
114
+ puts 'a'
115
+ puts 'b' if arg
116
+ end
117
+ end
118
+ EOS
119
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
152
120
  end
153
121
 
154
- it 'should report on nested if statements that are both control parameters' do
155
- src = <<EOS
156
- def nested(arg)
157
- if arg
158
- puts 'a'
159
- puts 'b' if arg
160
- end
161
- end
162
- EOS
163
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
122
+ it 'reports on nested if statements where the inner if is a control parameter' do
123
+ src = <<-EOS
124
+ def nested(arg)
125
+ if true
126
+ puts 'a'
127
+ puts 'b' if arg
128
+ end
129
+ end
130
+ EOS
131
+ expect(src).to smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
164
132
  end
165
133
 
166
- it 'should report on nested if statements where the inner if is a control parameter' do
167
- src = <<EOS
168
- def nested(arg)
169
- if true
170
- puts 'a'
171
- puts 'b' if arg
172
- end
173
- end
174
- EOS
175
- src.should smell_of(ControlParameter, ControlParameter::PARAMETER_KEY => 'arg')
134
+ it 'reports on explicit comparison in the condition' do
135
+ src = 'def simple(arg) if arg == :foo then :foo else :bar end end'
136
+ expect(src).to smell_of(ControlParameter)
137
+ end
138
+
139
+ it 'reports on explicit negative comparison in the condition' do
140
+ src = 'def simple(arg) if arg != :foo then :bar else :foo end end'
141
+ expect(src).to smell_of(ControlParameter)
176
142
  end
177
143
  end
178
144
 
179
145
  context 'parameter used besides determining code path' do
180
- it 'should not report on if conditional expression' do
146
+ it 'does not report on if conditional expression' do
181
147
  src = 'def simple(arg) if arg then use(arg) else use(@other) end end'
182
- src.should_not smell_of(ControlParameter)
148
+ expect(src).not_to smell_of(ControlParameter)
183
149
  end
184
150
 
185
- it 'should not report on an if statement modifier' do
151
+ it 'does not report on an if statement modifier' do
186
152
  src = 'def simple(arg) args = {}; args.merge(\'a\' => arg) if arg end'
187
- src.should_not smell_of(ControlParameter)
153
+ expect(src).not_to smell_of(ControlParameter)
188
154
  end
189
155
 
190
- it 'should not report on an unless statement modifier' do
156
+ it 'does not report on an unless statement modifier' do
191
157
  src = 'def simple(arg) args = {}; args.merge(\'a\' => arg) unless arg end'
192
- src.should_not smell_of(ControlParameter)
158
+ expect(src).not_to smell_of(ControlParameter)
193
159
  end
194
160
 
195
- it 'should not report on if control expression' do
161
+ it 'does not report on if control expression' do
196
162
  src = 'def simple(arg) args = {}; if arg then args.merge(\'a\' => arg) end end'
197
- src.should_not smell_of(ControlParameter)
163
+ expect(src).not_to smell_of(ControlParameter)
198
164
  end
199
165
 
200
- it 'should not report on if control expression with &&' do
166
+ it 'does not report on if control expression with &&' do
201
167
  src = 'def simple(arg) if arg && true then puts arg end end'
202
- src.should_not smell_of(ControlParameter)
168
+ expect(src).not_to smell_of(ControlParameter)
203
169
  end
204
170
 
205
- it 'should not report on && notation' do
171
+ it 'does not report on && notation' do
206
172
  src = 'def simple(arg) args = {}; arg && args.merge(\'a\' => arg) end'
207
- src.should_not smell_of(ControlParameter)
173
+ expect(src).not_to smell_of(ControlParameter)
208
174
  end
209
175
 
210
- it 'should not report on || notation' do
176
+ it 'does not report on || notation' do
211
177
  src = 'def simple(arg) args = {}; arg || args.merge(\'a\' => arg) end'
212
- src.should_not smell_of(ControlParameter)
178
+ expect(src).not_to smell_of(ControlParameter)
213
179
  end
214
180
 
215
- it 'should not report when parameter is used outside conditional' do
181
+ it 'does not report when parameter is used outside conditional' do
216
182
  src = 'def simple(arg) puts arg; if arg then @a = 1 end end'
217
- src.should_not smell_of(ControlParameter)
183
+ expect(src).not_to smell_of(ControlParameter)
184
+ end
185
+
186
+ it 'does not report when parameter is used as a method call argument in a condition' do
187
+ src = 'def simple(arg) if foo(arg) then @a = 1 end end'
188
+ expect(src).not_to smell_of(ControlParameter)
189
+ end
190
+
191
+ it 'does not report when parameter is used as a method call receiver in a condition' do
192
+ src = 'def simple(arg) if arg.foo? then @a = 1 end end'
193
+ expect(src).not_to smell_of(ControlParameter)
194
+ end
195
+
196
+ it 'does not report when the argument is a hash on which we access a key' do
197
+ src = 'def simple(arg) if arg[\'a\'] then puts \'a\' else puts \'b\' end end'
198
+ expect(src).not_to smell_of ControlParameter
199
+ end
200
+
201
+ it 'does not report when used in first conditional but not second' do
202
+ src = <<-EOS
203
+ def things(arg)
204
+ if arg
205
+ puts arg
206
+ end
207
+ if arg
208
+ puts 'a'
209
+ end
210
+ end
211
+ EOS
212
+ expect(src).not_to smell_of(ControlParameter)
213
+ end
214
+
215
+ it 'does not report when used in second conditional but not first' do
216
+ src = <<-EOS
217
+ def things(arg)
218
+ if arg
219
+ puts 'a'
220
+ end
221
+ if arg
222
+ puts arg
223
+ end
224
+ end
225
+ EOS
226
+ expect(src).not_to smell_of(ControlParameter)
227
+ end
228
+
229
+ it 'does not report when used in body of control flow operator' do
230
+ src = <<-EOS
231
+ def foo(arg)
232
+ case arg
233
+ when :bar
234
+ puts 'a'
235
+ else
236
+ puts 'b'
237
+ end
238
+ qux or quuz(arg)
239
+ end
240
+ EOS
241
+ expect(src).not_to smell_of(ControlParameter)
218
242
  end
219
243
  end
220
244
 
221
245
  context 'when a smell is reported' do
222
246
  before :each do
223
- src = <<EOS
224
- def things(arg)
225
- @text.map do |blk|
226
- arg ? blk : "blk"
227
- end
228
- puts "hello" if arg
229
- end
230
- EOS
247
+ src = <<-EOS
248
+ def things(arg)
249
+ @text.map do |blk|
250
+ arg ? blk : "blk"
251
+ end
252
+ puts "hello" if arg
253
+ end
254
+ EOS
231
255
  ctx = MethodContext.new(nil, src.to_reek_source.syntax_tree)
232
256
  smells = @detector.examine(ctx)
233
- smells.length.should == 1
257
+ expect(smells.length).to eq(1)
234
258
  @warning = smells[0]
235
259
  end
236
260
 
237
261
  it_should_behave_like 'common fields set correctly'
238
262
 
239
263
  it 'has the correct fields' do
240
- @warning.smell[ControlParameter::PARAMETER_KEY].should == 'arg'
241
- @warning.lines.should == [3, 5]
264
+ expect(@warning.smell[ControlParameter::PARAMETER_KEY]).to eq('arg')
265
+ expect(@warning.lines).to eq([3, 5])
242
266
  end
243
267
  end
244
268
  end