reek 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +9 -0
  3. data/README.md +54 -5
  4. data/Rakefile +1 -1
  5. data/features/command_line_interface/smell_selection.feature +4 -4
  6. data/features/command_line_interface/smells_count.feature +9 -8
  7. data/features/configuration_files/masking_smells.feature +16 -51
  8. data/features/configuration_files/overrides_defaults.feature +1 -1
  9. data/features/rake_task/rake_task.feature +14 -14
  10. data/features/reports/reports.feature +21 -19
  11. data/features/reports/yaml.feature +35 -63
  12. data/features/samples.feature +55 -54
  13. data/features/support/env.rb +8 -1
  14. data/lib/reek/cli/application.rb +22 -7
  15. data/lib/reek/cli/command.rb +4 -2
  16. data/lib/reek/cli/help_command.rb +1 -1
  17. data/lib/reek/cli/options.rb +3 -3
  18. data/lib/reek/cli/reek_command.rb +4 -8
  19. data/lib/reek/cli/report/formatter.rb +8 -5
  20. data/lib/reek/cli/report/report.rb +6 -5
  21. data/lib/reek/cli/report/strategy.rb +3 -2
  22. data/lib/reek/cli/version_command.rb +1 -1
  23. data/lib/reek/configuration/app_configuration.rb +75 -0
  24. data/lib/reek/configuration/configuration_file_finder.rb +56 -0
  25. data/lib/reek/core/code_context.rb +2 -6
  26. data/lib/reek/core/module_context.rb +4 -0
  27. data/lib/reek/core/smell_repository.rb +5 -3
  28. data/lib/reek/core/sniffer.rb +12 -8
  29. data/lib/reek/examiner.rb +7 -6
  30. data/lib/reek/rake/task.rb +10 -12
  31. data/lib/reek/smell_warning.rb +25 -43
  32. data/lib/reek/smells/attribute.rb +7 -12
  33. data/lib/reek/smells/boolean_parameter.rb +9 -9
  34. data/lib/reek/smells/class_variable.rb +7 -13
  35. data/lib/reek/smells/control_parameter.rb +8 -11
  36. data/lib/reek/smells/data_clump.rb +16 -21
  37. data/lib/reek/smells/duplicate_method_call.rb +11 -18
  38. data/lib/reek/smells/feature_envy.rb +8 -8
  39. data/lib/reek/smells/irresponsible_module.rb +6 -10
  40. data/lib/reek/smells/long_parameter_list.rb +7 -15
  41. data/lib/reek/smells/long_yield_list.rb +13 -15
  42. data/lib/reek/smells/module_initialize.rb +4 -7
  43. data/lib/reek/smells/nested_iterators.rb +6 -13
  44. data/lib/reek/smells/nil_check.rb +9 -7
  45. data/lib/reek/smells/prima_donna_method.rb +5 -7
  46. data/lib/reek/smells/repeated_conditional.rb +19 -15
  47. data/lib/reek/smells/smell_detector.rb +21 -1
  48. data/lib/reek/smells/too_many_instance_variables.rb +9 -16
  49. data/lib/reek/smells/too_many_methods.rb +10 -17
  50. data/lib/reek/smells/too_many_statements.rb +14 -14
  51. data/lib/reek/smells/uncommunicative_method_name.rb +9 -10
  52. data/lib/reek/smells/uncommunicative_module_name.rb +9 -10
  53. data/lib/reek/smells/uncommunicative_parameter_name.rb +9 -9
  54. data/lib/reek/smells/uncommunicative_variable_name.rb +9 -9
  55. data/lib/reek/smells/unused_parameters.rb +8 -20
  56. data/lib/reek/smells/utility_function.rb +12 -10
  57. data/lib/reek/source.rb +0 -1
  58. data/lib/reek/source/code_comment.rb +1 -0
  59. data/lib/reek/source/source_code.rb +3 -13
  60. data/lib/reek/source/source_file.rb +0 -14
  61. data/lib/reek/source/source_repository.rb +7 -0
  62. data/lib/reek/spec/should_reek_of.rb +3 -3
  63. data/lib/reek/spec/should_reek_only_of.rb +2 -2
  64. data/lib/reek/version.rb +1 -1
  65. data/reek.gemspec +4 -2
  66. data/spec/factories/factories.rb +32 -0
  67. data/spec/matchers/smell_of_matcher.rb +3 -2
  68. data/spec/reek/cli/report_spec.rb +2 -1
  69. data/spec/reek/configuration/app_configuration_spec.rb +67 -0
  70. data/spec/reek/configuration/configuration_file_finder_spec.rb +35 -0
  71. data/spec/reek/core/code_context_spec.rb +1 -1
  72. data/spec/reek/core/module_context_spec.rb +5 -1
  73. data/spec/reek/core/smell_configuration_spec.rb +21 -13
  74. data/spec/reek/core/warning_collector_spec.rb +4 -1
  75. data/spec/reek/examiner_spec.rb +19 -1
  76. data/spec/reek/smell_warning_spec.rb +42 -36
  77. data/spec/reek/smells/attribute_spec.rb +6 -2
  78. data/spec/reek/smells/boolean_parameter_spec.rb +11 -12
  79. data/spec/reek/smells/class_variable_spec.rb +16 -6
  80. data/spec/reek/smells/control_parameter_spec.rb +17 -19
  81. data/spec/reek/smells/data_clump_spec.rb +25 -15
  82. data/spec/reek/smells/duplicate_method_call_spec.rb +18 -12
  83. data/spec/reek/smells/feature_envy_spec.rb +29 -10
  84. data/spec/reek/smells/irresponsible_module_spec.rb +7 -7
  85. data/spec/reek/smells/long_parameter_list_spec.rb +16 -10
  86. data/spec/reek/smells/long_yield_list_spec.rb +2 -2
  87. data/spec/reek/smells/module_initialize_spec.rb +26 -0
  88. data/spec/reek/smells/nested_iterators_spec.rb +21 -10
  89. data/spec/reek/smells/nil_check_spec.rb +0 -2
  90. data/spec/reek/smells/prima_donna_method_spec.rb +3 -3
  91. data/spec/reek/smells/repeated_conditional_spec.rb +0 -26
  92. data/spec/reek/smells/smell_detector_shared.rb +4 -4
  93. data/spec/reek/smells/too_many_instance_variables_spec.rb +3 -3
  94. data/spec/reek/smells/too_many_methods_spec.rb +16 -11
  95. data/spec/reek/smells/too_many_statements_spec.rb +55 -18
  96. data/spec/reek/smells/uncommunicative_method_name_spec.rb +3 -2
  97. data/spec/reek/smells/uncommunicative_module_name_spec.rb +5 -5
  98. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +4 -4
  99. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +28 -21
  100. data/spec/reek/smells/unused_parameters_spec.rb +3 -5
  101. data/spec/reek/smells/utility_function_spec.rb +2 -1
  102. data/spec/reek/source/code_comment_spec.rb +7 -2
  103. data/spec/reek/source/reference_collector_spec.rb +0 -1
  104. data/spec/reek/source/sexp_extensions_spec.rb +0 -15
  105. data/spec/reek/source/source_code_spec.rb +13 -1
  106. data/spec/reek/spec/should_reek_only_of_spec.rb +22 -10
  107. data/spec/reek/spec/should_reek_spec.rb +6 -2
  108. data/spec/samples/minimal_smelly_and_masked/config.reek +7 -0
  109. data/spec/samples/minimal_smelly_and_masked/minimal_dirty.rb +4 -0
  110. data/spec/samples/simple_configuration.reek +5 -0
  111. data/spec/samples/standard_smelly/dirty.rb +8 -0
  112. data/spec/samples/standard_smelly/minimal_dirty.rb +4 -0
  113. data/spec/spec_helper.rb +20 -0
  114. data/tasks/develop.rake +1 -1
  115. data/tasks/rubocop.rake +5 -0
  116. metadata +41 -6
  117. data/lib/reek/config_file_exception.rb +0 -7
  118. data/lib/reek/smell_description.rb +0 -26
  119. data/lib/reek/source/config_file.rb +0 -88
  120. data/spec/reek/smell_description_spec.rb +0 -43
@@ -11,78 +11,50 @@ Feature: Report smells using simple YAML layout
11
11
  --- []
12
12
  """
13
13
 
14
- @masking
15
- Scenario: masked smells always appear
16
- When I run reek --yaml spec/samples/masked/dirty.rb
14
+ Scenario: Indicate smells and print them as yaml when using files
15
+ When I run reek --yaml spec/samples/standard_smelly/minimal_dirty.rb
17
16
  Then the exit status indicates smells
18
17
  And it reports this yaml:
19
18
  """
20
19
  ---
21
- - !ruby/object:Reek::SmellWarning
22
- location:
23
- lines:
24
- - 4
25
- - 6
26
- context: Dirty#a
27
- source: spec/samples/masked/dirty.rb
28
- smell:
29
- class: Duplication
30
- occurrences: 2
31
- subclass: DuplicateMethodCall
32
- call: "@s.title"
33
- message: calls @s.title twice
34
- status:
35
- is_active: true
36
- - !ruby/object:Reek::SmellWarning
37
- location:
38
- lines:
39
- - 5
40
- - 7
41
- context: Dirty#a
42
- source: spec/samples/masked/dirty.rb
43
- smell:
44
- class: Duplication
45
- occurrences: 2
46
- subclass: DuplicateMethodCall
47
- call: puts(@s.title)
48
- message: calls puts(@s.title) twice
49
- status:
50
- is_active: true
51
- - !ruby/object:Reek::SmellWarning
52
- location:
53
- lines:
54
- - 5
55
- context: Dirty#a
56
- source: spec/samples/masked/dirty.rb
57
- smell:
58
- class: NestedIterators
59
- depth: 2
60
- subclass: NestedIterators
61
- message: contains iterators nested 2 deep
62
- status:
63
- is_active: true
64
-
20
+ - smell_category: IrresponsibleModule
21
+ smell_type: IrresponsibleModule
22
+ source: spec/samples/standard_smelly/minimal_dirty.rb
23
+ context: C
24
+ lines:
25
+ - 1
26
+ message: has no descriptive comment
27
+ name: C
28
+ - smell_category: UncommunicativeName
29
+ smell_type: UncommunicativeModuleName
30
+ source: spec/samples/standard_smelly/minimal_dirty.rb
31
+ context: C
32
+ lines:
33
+ - 1
34
+ message: has the name 'C'
35
+ name: C
36
+ - smell_category: UncommunicativeName
37
+ smell_type: UncommunicativeMethodName
38
+ source: spec/samples/standard_smelly/minimal_dirty.rb
39
+ context: C#m
40
+ lines:
41
+ - 2
42
+ message: has the name 'm'
43
+ name: m
65
44
  """
66
45
 
67
- @stdin
68
- Scenario: return non-zero status when there are smells
46
+ Scenario: Indicate smells and print them as yaml when using STDIN
69
47
  When I pass "class Turn; end" to reek --yaml
70
48
  Then the exit status indicates smells
71
49
  And it reports this yaml:
72
50
  """
73
51
  ---
74
- - !ruby/object:Reek::SmellWarning
75
- location:
76
- lines:
77
- - 1
78
- context: Turn
79
- source: $stdin
80
- smell:
81
- class: IrresponsibleModule
82
- subclass: IrresponsibleModule
83
- module_name: Turn
84
- message: has no descriptive comment
85
- status:
86
- is_active: true
87
-
52
+ - smell_category: IrresponsibleModule
53
+ smell_type: IrresponsibleModule
54
+ source: "$stdin"
55
+ context: Turn
56
+ lines:
57
+ - 1
58
+ message: has no descriptive comment
59
+ name: Turn
88
60
  """
@@ -10,13 +10,13 @@ Feature: Basic smell detection
10
10
  Then the exit status indicates smells
11
11
  And it reports:
12
12
  """
13
- spec/samples/inline.rb -- 43 warnings:
13
+ spec/samples/inline.rb -- 44 warnings:
14
14
  CompilationError has no descriptive comment (IrresponsibleModule)
15
15
  File has no descriptive comment (IrresponsibleModule)
16
16
  File#self.write_with_backup has approx 6 statements (TooManyStatements)
17
17
  Inline declares the class variable @@directory (ClassVariable)
18
18
  Inline declares the class variable @@rootdir (ClassVariable)
19
- Inline#self.rootdir calls env.nil? twice (DuplicateMethodCall)
19
+ Inline#self.rootdir calls env.nil? 2 times (DuplicateMethodCall)
20
20
  Inline#self.rootdir has approx 8 statements (TooManyStatements)
21
21
  Inline#self.rootdir performs a nil-check. (NilCheck)
22
22
  Inline::C declares the class variable @@type_map (ClassVariable)
@@ -25,25 +25,26 @@ Feature: Basic smell detection
25
25
  Inline::C tests $DEBUG at least 7 times (RepeatedConditional)
26
26
  Inline::C tests $TESTING at least 4 times (RepeatedConditional)
27
27
  Inline::C tests @@type_map.has_key?(type) at least 3 times (RepeatedConditional)
28
- Inline::C#build calls $? != 0 twice (DuplicateMethodCall)
28
+ Inline::C#build calls $? != 0 2 times (DuplicateMethodCall)
29
29
  Inline::C#build calls Inline.directory 5 times (DuplicateMethodCall)
30
30
  Inline::C#build calls io.puts 6 times (DuplicateMethodCall)
31
- Inline::C#build calls io.puts("#endif") twice (DuplicateMethodCall)
32
- Inline::C#build calls io.puts("#ifdef __cplusplus") twice (DuplicateMethodCall)
33
- Inline::C#build calls warn("Output:\n#{result}") twice (DuplicateMethodCall)
31
+ Inline::C#build calls io.puts("#endif") 2 times (DuplicateMethodCall)
32
+ Inline::C#build calls io.puts("#ifdef __cplusplus") 2 times (DuplicateMethodCall)
33
+ Inline::C#build calls warn("Output:\n#{result}") 2 times (DuplicateMethodCall)
34
34
  Inline::C#build contains iterators nested 2 deep (NestedIterators)
35
35
  Inline::C#build has approx 63 statements (TooManyStatements)
36
36
  Inline::C#build has the variable name 'n' (UncommunicativeVariableName)
37
37
  Inline::C#build has the variable name 't' (UncommunicativeVariableName)
38
38
  Inline::C#c has the name 'c' (UncommunicativeMethodName)
39
- Inline::C#crap_for_windoze calls Config::CONFIG["libdir"] twice (DuplicateMethodCall)
40
- Inline::C#generate calls result.sub!(/\A\n/, "") twice (DuplicateMethodCall)
41
- Inline::C#generate calls signature["args"] twice (DuplicateMethodCall)
42
- Inline::C#generate calls signature["args"].map twice (DuplicateMethodCall)
39
+ Inline::C#crap_for_windoze calls Config::CONFIG["libdir"] 2 times (DuplicateMethodCall)
40
+ Inline::C#generate calls result.sub!(/\A\n/, "") 2 times (DuplicateMethodCall)
41
+ Inline::C#generate calls signature["args"] 2 times (DuplicateMethodCall)
42
+ Inline::C#generate calls signature["args"].map 2 times (DuplicateMethodCall)
43
43
  Inline::C#generate has approx 35 statements (TooManyStatements)
44
- Inline::C#initialize calls stack.empty? twice (DuplicateMethodCall)
44
+ Inline::C#initialize calls stack.empty? 2 times (DuplicateMethodCall)
45
45
  Inline::C#module_name has approx 7 statements (TooManyStatements)
46
46
  Inline::C#module_name has the variable name 'm' (UncommunicativeVariableName)
47
+ Inline::C#module_name has the variable name 'md5' (UncommunicativeVariableName)
47
48
  Inline::C#module_name has the variable name 'x' (UncommunicativeVariableName)
48
49
  Inline::C#parse_signature has approx 16 statements (TooManyStatements)
49
50
  Inline::C#parse_signature has boolean parameter 'raw' (BooleanParameter)
@@ -51,8 +52,8 @@ Feature: Basic smell detection
51
52
  Inline::C#parse_signature is controlled by argument raw (ControlParameter)
52
53
  Inline::C#strip_comments doesn't depend on instance state (UtilityFunction)
53
54
  Inline::C#strip_comments refers to src more than self (FeatureEnvy)
54
- Module#inline calls Inline.const_get(lang) twice (DuplicateMethodCall)
55
- Module#inline calls options[:testing] twice (DuplicateMethodCall)
55
+ Module#inline calls Inline.const_get(lang) 2 times (DuplicateMethodCall)
56
+ Module#inline calls options[:testing] 2 times (DuplicateMethodCall)
56
57
  Module#inline has approx 12 statements (TooManyStatements)
57
58
  """
58
59
 
@@ -77,20 +78,20 @@ Feature: Basic smell detection
77
78
  OptionParser#complete has 4 parameters (LongParameterList)
78
79
  OptionParser#complete has approx 6 statements (TooManyStatements)
79
80
  OptionParser#complete has boolean parameter 'icase' (BooleanParameter)
80
- OptionParser#getopts calls result[opt] = false twice (DuplicateMethodCall)
81
+ OptionParser#getopts calls result[opt] = false 2 times (DuplicateMethodCall)
81
82
  OptionParser#getopts has approx 18 statements (TooManyStatements)
82
83
  OptionParser#load has approx 6 statements (TooManyStatements)
83
84
  OptionParser#load has the variable name 's' (UncommunicativeVariableName)
84
85
  OptionParser#make_switch calls default_style.guess(arg = a) 4 times (DuplicateMethodCall)
85
- OptionParser#make_switch calls long << (o = q.downcase) twice (DuplicateMethodCall)
86
- OptionParser#make_switch calls notwice(NilClass, klass, "type") twice (DuplicateMethodCall)
87
- OptionParser#make_switch calls notwice(if a ... end, klass, "type") twice (DuplicateMethodCall)
88
- OptionParser#make_switch calls pattern.method(:convert) twice (DuplicateMethodCall)
89
- OptionParser#make_switch calls pattern.method(:convert).to_proc twice (DuplicateMethodCall)
90
- OptionParser#make_switch calls pattern.respond_to?(:convert) twice (DuplicateMethodCall)
86
+ OptionParser#make_switch calls long << (o = q.downcase) 2 times (DuplicateMethodCall)
87
+ OptionParser#make_switch calls notwice(NilClass, klass, "type") 2 times (DuplicateMethodCall)
88
+ OptionParser#make_switch calls notwice(if a ... end, klass, "type") 2 times (DuplicateMethodCall)
89
+ OptionParser#make_switch calls pattern.method(:convert) 2 times (DuplicateMethodCall)
90
+ OptionParser#make_switch calls pattern.method(:convert).to_proc 2 times (DuplicateMethodCall)
91
+ OptionParser#make_switch calls pattern.respond_to?(:convert) 2 times (DuplicateMethodCall)
91
92
  OptionParser#make_switch calls q.downcase 3 times (DuplicateMethodCall)
92
- OptionParser#make_switch calls sdesc << "-#{q}" twice (DuplicateMethodCall)
93
- OptionParser#make_switch calls search(:atype, FalseClass) twice (DuplicateMethodCall)
93
+ OptionParser#make_switch calls sdesc << "-#{q}" 2 times (DuplicateMethodCall)
94
+ OptionParser#make_switch calls search(:atype, FalseClass) 2 times (DuplicateMethodCall)
94
95
  OptionParser#make_switch calls search(:atype, o) 6 times (DuplicateMethodCall)
95
96
  OptionParser#make_switch contains iterators nested 3 deep (NestedIterators)
96
97
  OptionParser#make_switch has approx 72 statements (TooManyStatements)
@@ -102,20 +103,20 @@ Feature: Basic smell detection
102
103
  OptionParser#make_switch has the variable name 's' (UncommunicativeVariableName)
103
104
  OptionParser#make_switch has the variable name 'v' (UncommunicativeVariableName)
104
105
  OptionParser#make_switch performs a nil-check. (NilCheck)
105
- OptionParser#order calls argv[0] twice (DuplicateMethodCall)
106
+ OptionParser#order calls argv[0] 2 times (DuplicateMethodCall)
106
107
  OptionParser#order refers to argv more than self (FeatureEnvy)
107
- OptionParser#parse calls argv[0] twice (DuplicateMethodCall)
108
+ OptionParser#parse calls argv[0] 2 times (DuplicateMethodCall)
108
109
  OptionParser#parse refers to argv more than self (FeatureEnvy)
109
- OptionParser#parse_in_order calls $!.set_option(arg, true) twice (DuplicateMethodCall)
110
- OptionParser#parse_in_order calls cb.call(val) twice (DuplicateMethodCall)
111
- OptionParser#parse_in_order calls raise($!.set_option(arg, true)) twice (DuplicateMethodCall)
112
- OptionParser#parse_in_order calls raise(*exc) twice (DuplicateMethodCall)
113
- OptionParser#parse_in_order calls setter.call(sw.switch_name, val) twice (DuplicateMethodCall)
114
- OptionParser#parse_in_order calls sw.block twice (DuplicateMethodCall)
115
- OptionParser#parse_in_order calls sw.switch_name twice (DuplicateMethodCall)
110
+ OptionParser#parse_in_order calls $!.set_option(arg, true) 2 times (DuplicateMethodCall)
111
+ OptionParser#parse_in_order calls cb.call(val) 2 times (DuplicateMethodCall)
112
+ OptionParser#parse_in_order calls raise($!.set_option(arg, true)) 2 times (DuplicateMethodCall)
113
+ OptionParser#parse_in_order calls raise(*exc) 2 times (DuplicateMethodCall)
114
+ OptionParser#parse_in_order calls setter.call(sw.switch_name, val) 2 times (DuplicateMethodCall)
115
+ OptionParser#parse_in_order calls sw.block 2 times (DuplicateMethodCall)
116
+ OptionParser#parse_in_order calls sw.switch_name 2 times (DuplicateMethodCall)
116
117
  OptionParser#parse_in_order contains iterators nested 3 deep (NestedIterators)
117
118
  OptionParser#parse_in_order has approx 35 statements (TooManyStatements)
118
- OptionParser#permute calls argv[0] twice (DuplicateMethodCall)
119
+ OptionParser#permute calls argv[0] 2 times (DuplicateMethodCall)
119
120
  OptionParser#permute refers to argv more than self (FeatureEnvy)
120
121
  OptionParser#permute! has approx 6 statements (TooManyStatements)
121
122
  OptionParser#search has the variable name 'k' (UncommunicativeVariableName)
@@ -128,8 +129,8 @@ Feature: Basic smell detection
128
129
  OptionParser::Arguable#options has approx 6 statements (TooManyStatements)
129
130
  OptionParser::Arguable#options= is controlled by argument opt (ControlParameter)
130
131
  OptionParser::CompletingHash#match contains iterators nested 2 deep (NestedIterators)
131
- OptionParser::Completion#complete calls candidates.size twice (DuplicateMethodCall)
132
- OptionParser::Completion#complete calls k.id2name twice (DuplicateMethodCall)
132
+ OptionParser::Completion#complete calls candidates.size 2 times (DuplicateMethodCall)
133
+ OptionParser::Completion#complete calls k.id2name 2 times (DuplicateMethodCall)
133
134
  OptionParser::Completion#complete has approx 23 statements (TooManyStatements)
134
135
  OptionParser::Completion#complete has boolean parameter 'icase' (BooleanParameter)
135
136
  OptionParser::Completion#complete has the variable name 'k' (UncommunicativeVariableName)
@@ -149,19 +150,19 @@ Feature: Basic smell detection
149
150
  OptionParser::ParseError#set_option is controlled by argument eq (ControlParameter)
150
151
  OptionParser::Switch#add_banner has the variable name 's' (UncommunicativeVariableName)
151
152
  OptionParser::Switch#initialize has 7 parameters (LongParameterList)
152
- OptionParser::Switch#parse_arg calls s.length twice (DuplicateMethodCall)
153
+ OptionParser::Switch#parse_arg calls s.length 2 times (DuplicateMethodCall)
153
154
  OptionParser::Switch#parse_arg has approx 11 statements (TooManyStatements)
154
155
  OptionParser::Switch#parse_arg has the variable name 'm' (UncommunicativeVariableName)
155
156
  OptionParser::Switch#parse_arg has the variable name 's' (UncommunicativeVariableName)
156
157
  OptionParser::Switch#self.guess has approx 6 statements (TooManyStatements)
157
158
  OptionParser::Switch#self.guess has the variable name 't' (UncommunicativeVariableName)
158
159
  OptionParser::Switch#self.incompatible_argument_styles has the parameter name 't' (UncommunicativeParameterName)
159
- OptionParser::Switch#summarize calls indent + l twice (DuplicateMethodCall)
160
- OptionParser::Switch#summarize calls left.collect do |s| ... end twice (DuplicateMethodCall)
161
- OptionParser::Switch#summarize calls left.collect do |s| ... end.max twice (DuplicateMethodCall)
162
- OptionParser::Switch#summarize calls left.collect do |s| ... end.max.to_i twice (DuplicateMethodCall)
163
- OptionParser::Switch#summarize calls left.collect twice (DuplicateMethodCall)
164
- OptionParser::Switch#summarize calls left.shift twice (DuplicateMethodCall)
160
+ OptionParser::Switch#summarize calls indent + l 2 times (DuplicateMethodCall)
161
+ OptionParser::Switch#summarize calls left.collect 2 times (DuplicateMethodCall)
162
+ OptionParser::Switch#summarize calls left.collect do |s| ... end 2 times (DuplicateMethodCall)
163
+ OptionParser::Switch#summarize calls left.collect do |s| ... end.max 2 times (DuplicateMethodCall)
164
+ OptionParser::Switch#summarize calls left.collect do |s| ... end.max.to_i 2 times (DuplicateMethodCall)
165
+ OptionParser::Switch#summarize calls left.shift 2 times (DuplicateMethodCall)
165
166
  OptionParser::Switch#summarize calls left[(-1)] 3 times (DuplicateMethodCall)
166
167
  OptionParser::Switch#summarize calls s.length 3 times (DuplicateMethodCall)
167
168
  OptionParser::Switch#summarize contains iterators nested 2 deep (NestedIterators)
@@ -195,10 +196,10 @@ Feature: Basic smell detection
195
196
  RedCloth#block_markdown_rule refers to text more than self (FeatureEnvy)
196
197
  RedCloth#block_markdown_setext refers to text more than self (FeatureEnvy)
197
198
  RedCloth#block_textile_lists calls depth.last 5 times (DuplicateMethodCall)
198
- RedCloth#block_textile_lists calls depth.last.length twice (DuplicateMethodCall)
199
- RedCloth#block_textile_lists calls depth[i] twice (DuplicateMethodCall)
200
- RedCloth#block_textile_lists calls line_id - 1 twice (DuplicateMethodCall)
201
- RedCloth#block_textile_lists calls lines[line_id - 1] twice (DuplicateMethodCall)
199
+ RedCloth#block_textile_lists calls depth.last.length 2 times (DuplicateMethodCall)
200
+ RedCloth#block_textile_lists calls depth[i] 2 times (DuplicateMethodCall)
201
+ RedCloth#block_textile_lists calls line_id - 1 2 times (DuplicateMethodCall)
202
+ RedCloth#block_textile_lists calls lines[line_id - 1] 2 times (DuplicateMethodCall)
202
203
  RedCloth#block_textile_lists calls tl.length 3 times (DuplicateMethodCall)
203
204
  RedCloth#block_textile_lists contains iterators nested 3 deep (NestedIterators)
204
205
  RedCloth#block_textile_lists has approx 21 statements (TooManyStatements)
@@ -213,7 +214,7 @@ Feature: Basic smell detection
213
214
  RedCloth#blocks has boolean parameter 'deep_code' (BooleanParameter)
214
215
  RedCloth#blocks is controlled by argument deep_code (ControlParameter)
215
216
  RedCloth#blocks refers to blk more than self (FeatureEnvy)
216
- RedCloth#clean_html calls tags[tag] twice (DuplicateMethodCall)
217
+ RedCloth#clean_html calls tags[tag] 2 times (DuplicateMethodCall)
217
218
  RedCloth#clean_html contains iterators nested 3 deep (NestedIterators)
218
219
  RedCloth#clean_html doesn't depend on instance state (UtilityFunction)
219
220
  RedCloth#clean_html has approx 15 statements (TooManyStatements)
@@ -252,7 +253,7 @@ Feature: Basic smell detection
252
253
  RedCloth#lT refers to text more than self (FeatureEnvy)
253
254
  RedCloth#no_textile doesn't depend on instance state (UtilityFunction)
254
255
  RedCloth#no_textile refers to text more than self (FeatureEnvy)
255
- RedCloth#pba calls $1.length twice (DuplicateMethodCall)
256
+ RedCloth#pba calls $1.length 2 times (DuplicateMethodCall)
256
257
  RedCloth#pba has approx 21 statements (TooManyStatements)
257
258
  RedCloth#pba is controlled by argument element (ControlParameter)
258
259
  RedCloth#pba refers to text more than self (FeatureEnvy)
@@ -260,13 +261,13 @@ Feature: Basic smell detection
260
261
  RedCloth#refs_textile has the variable name 'm' (UncommunicativeVariableName)
261
262
  RedCloth#retrieve has the variable name 'i' (UncommunicativeVariableName)
262
263
  RedCloth#retrieve has the variable name 'r' (UncommunicativeVariableName)
263
- RedCloth#rip_offtags calls (codepre - used_offtags.length) > 0 twice (DuplicateMethodCall)
264
- RedCloth#rip_offtags calls @pre_list.last << line twice (DuplicateMethodCall)
265
- RedCloth#rip_offtags calls @pre_list.last twice (DuplicateMethodCall)
266
- RedCloth#rip_offtags calls codepre - used_offtags.length twice (DuplicateMethodCall)
267
- RedCloth#rip_offtags calls codepre.zero? twice (DuplicateMethodCall)
268
- RedCloth#rip_offtags calls htmlesc(line, :NoQuotes) twice (DuplicateMethodCall)
269
- RedCloth#rip_offtags calls used_offtags.length twice (DuplicateMethodCall)
264
+ RedCloth#rip_offtags calls (codepre - used_offtags.length) > 0 2 times (DuplicateMethodCall)
265
+ RedCloth#rip_offtags calls @pre_list.last 2 times (DuplicateMethodCall)
266
+ RedCloth#rip_offtags calls @pre_list.last << line 2 times (DuplicateMethodCall)
267
+ RedCloth#rip_offtags calls codepre - used_offtags.length 2 times (DuplicateMethodCall)
268
+ RedCloth#rip_offtags calls codepre.zero? 2 times (DuplicateMethodCall)
269
+ RedCloth#rip_offtags calls htmlesc(line, :NoQuotes) 2 times (DuplicateMethodCall)
270
+ RedCloth#rip_offtags calls used_offtags.length 2 times (DuplicateMethodCall)
270
271
  RedCloth#rip_offtags calls used_offtags["notextile"] 3 times (DuplicateMethodCall)
271
272
  RedCloth#rip_offtags has approx 18 statements (TooManyStatements)
272
273
  RedCloth#textile_bq has 4 parameters (LongParameterList)
@@ -1,14 +1,21 @@
1
+ require 'English'
1
2
  require 'tempfile'
2
3
  require 'fileutils'
3
4
  require 'open3'
4
5
  require 'reek/cli/application'
5
6
 
7
+ begin
8
+ require 'pry'
9
+ require 'byebug'
10
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
11
+ end
12
+
6
13
  class ReekWorld
7
14
  def run(cmd)
8
15
  stderr_file = Tempfile.new('reek-world')
9
16
  stderr_file.close
10
17
  @last_stdout = `#{cmd} 2> #{stderr_file.path}`
11
- @last_exit_status = $?.exitstatus
18
+ @last_exit_status = $CHILD_STATUS.exitstatus
12
19
  @last_stderr = IO.read(stderr_file.path)
13
20
  end
14
21
 
@@ -1,4 +1,5 @@
1
1
  require 'reek/cli/options'
2
+ require 'reek/configuration/app_configuration'
2
3
 
3
4
  module Reek
4
5
  module Cli
@@ -8,26 +9,34 @@ module Reek
8
9
  # command line.
9
10
  #
10
11
  class Application
12
+ attr_reader :options
13
+
11
14
  STATUS_SUCCESS = 0
12
15
  STATUS_ERROR = 1
13
16
  STATUS_SMELLS = 2
14
17
 
15
18
  def initialize(argv)
19
+ @status = STATUS_SUCCESS
16
20
  @options = Options.new(argv)
17
- @status = STATUS_SUCCESS
18
- end
19
-
20
- def execute
21
21
  begin
22
- cmd = @options.parse
23
- cmd.execute(self)
24
- rescue OptionParser::InvalidOption, ConfigFileException => error
22
+ @command = @options.parse
23
+ initialize_configuration
24
+ rescue OptionParser::InvalidOption, Reek::Configuration::ConfigFileException => error
25
25
  $stderr.puts "Error: #{error}"
26
26
  @status = STATUS_ERROR
27
27
  end
28
+ end
29
+
30
+ def execute
31
+ return @status if error_occured?
32
+ @command.execute self
28
33
  @status
29
34
  end
30
35
 
36
+ def initialize_configuration
37
+ Configuration::AppConfiguration.initialize_with self
38
+ end
39
+
31
40
  def output(text)
32
41
  print text
33
42
  end
@@ -39,6 +48,12 @@ module Reek
39
48
  def report_smells
40
49
  @status = STATUS_SMELLS
41
50
  end
51
+
52
+ private
53
+
54
+ def error_occured?
55
+ @status == STATUS_ERROR
56
+ end
42
57
  end
43
58
  end
44
59
  end
@@ -4,8 +4,10 @@ module Reek
4
4
  # Base class for all commands
5
5
  #
6
6
  class Command
7
- def initialize(parser)
8
- @parser = parser
7
+ attr_reader :options
8
+
9
+ def initialize(options)
10
+ @options = options
9
11
  end
10
12
  end
11
13
  end
@@ -7,7 +7,7 @@ module Reek
7
7
  #
8
8
  class HelpCommand < Command
9
9
  def execute(view)
10
- view.output(@parser.help_text)
10
+ view.output(@options.help_text)
11
11
  view.report_success
12
12
  end
13
13
  end
@@ -22,7 +22,7 @@ module Reek
22
22
  @strategy = Report::Strategy::Quiet
23
23
  @warning_formatter = Report::WarningFormatterWithLineNumbers
24
24
  @command_class = ReekCommand
25
- @config_files = []
25
+ @config_file = nil
26
26
  @sort_by_issue_count = false
27
27
  @smells_to_detect = []
28
28
  set_options
@@ -72,7 +72,7 @@ EOB
72
72
 
73
73
  @parser.separator "\nConfiguration:"
74
74
  @parser.on('-c', '--config FILE', 'Read configuration options from FILE') do |file|
75
- @config_files << file
75
+ @config_file = file
76
76
  end
77
77
  @parser.on('--smell SMELL', 'Detect smell SMELL (default is all enabled smells)') do |smell|
78
78
  @smells_to_detect << smell
@@ -117,7 +117,7 @@ EOB
117
117
  @command_class.new(self)
118
118
  end
119
119
 
120
- attr_reader :config_files
120
+ attr_reader :config_file
121
121
  attr_reader :smells_to_detect
122
122
 
123
123
  def reporter