reek 1.2.6 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. data/.yardopts +10 -0
  2. data/History.txt +20 -0
  3. data/README.md +90 -0
  4. data/bin/reek +2 -2
  5. data/config/defaults.reek +34 -4
  6. data/features/masking_smells.feature +35 -15
  7. data/features/options.feature +2 -0
  8. data/features/rake_task.feature +11 -18
  9. data/features/reports.feature +13 -15
  10. data/features/samples.feature +90 -105
  11. data/features/stdin.feature +3 -6
  12. data/features/step_definitions/reek_steps.rb +8 -4
  13. data/features/support/env.rb +2 -3
  14. data/features/yaml.feature +124 -0
  15. data/lib/reek.rb +8 -4
  16. data/lib/reek/cli/application.rb +46 -0
  17. data/lib/reek/cli/command_line.rb +106 -0
  18. data/lib/reek/cli/help_command.rb +18 -0
  19. data/lib/reek/cli/reek_command.rb +37 -0
  20. data/lib/reek/cli/report.rb +91 -0
  21. data/lib/reek/cli/version_command.rb +19 -0
  22. data/lib/reek/cli/yaml_command.rb +32 -0
  23. data/lib/reek/core/block_context.rb +18 -0
  24. data/lib/reek/core/class_context.rb +23 -0
  25. data/lib/reek/core/code_context.rb +72 -0
  26. data/lib/reek/core/code_parser.rb +192 -0
  27. data/lib/reek/core/detector_stack.rb +29 -0
  28. data/lib/reek/core/masking_collection.rb +46 -0
  29. data/lib/reek/core/method_context.rb +132 -0
  30. data/lib/reek/core/module_context.rb +64 -0
  31. data/lib/reek/{object_refs.rb → core/object_refs.rb} +8 -6
  32. data/lib/reek/{singleton_method_context.rb → core/singleton_method_context.rb} +10 -5
  33. data/lib/reek/core/smell_configuration.rb +66 -0
  34. data/lib/reek/core/sniffer.rb +110 -0
  35. data/lib/reek/core/stop_context.rb +26 -0
  36. data/lib/reek/examiner.rb +88 -0
  37. data/lib/reek/rake/task.rb +124 -0
  38. data/lib/reek/smell_warning.rb +69 -13
  39. data/lib/reek/smells.rb +29 -0
  40. data/lib/reek/smells/attribute.rb +13 -14
  41. data/lib/reek/smells/boolean_parameter.rb +33 -0
  42. data/lib/reek/smells/class_variable.rb +8 -6
  43. data/lib/reek/smells/control_couple.rb +33 -17
  44. data/lib/reek/smells/data_clump.rb +10 -6
  45. data/lib/reek/smells/duplication.rb +24 -14
  46. data/lib/reek/smells/feature_envy.rb +11 -6
  47. data/lib/reek/smells/irresponsible_module.rb +28 -0
  48. data/lib/reek/smells/large_class.rb +9 -7
  49. data/lib/reek/smells/long_method.rb +6 -5
  50. data/lib/reek/smells/long_parameter_list.rb +11 -9
  51. data/lib/reek/smells/long_yield_list.rb +37 -7
  52. data/lib/reek/smells/nested_iterators.rb +34 -9
  53. data/lib/reek/smells/simulated_polymorphism.rb +15 -11
  54. data/lib/reek/smells/smell_detector.rb +24 -12
  55. data/lib/reek/smells/uncommunicative_method_name.rb +76 -0
  56. data/lib/reek/smells/uncommunicative_module_name.rb +76 -0
  57. data/lib/reek/smells/{uncommunicative_name.rb → uncommunicative_parameter_name.rb} +14 -26
  58. data/lib/reek/smells/uncommunicative_variable_name.rb +90 -0
  59. data/lib/reek/smells/utility_function.rb +33 -9
  60. data/lib/reek/source.rb +18 -0
  61. data/lib/reek/source/code_comment.rb +19 -0
  62. data/lib/reek/source/config_file.rb +72 -0
  63. data/lib/reek/source/core_extras.rb +46 -0
  64. data/lib/reek/source/sexp_formatter.rb +16 -0
  65. data/lib/reek/source/source_code.rb +44 -0
  66. data/lib/reek/source/source_file.rb +32 -0
  67. data/lib/reek/source/source_locator.rb +36 -0
  68. data/lib/reek/source/tree_dresser.rb +128 -0
  69. data/lib/reek/spec.rb +51 -0
  70. data/lib/reek/spec/should_reek.rb +34 -0
  71. data/lib/reek/spec/should_reek_of.rb +37 -0
  72. data/lib/reek/spec/should_reek_only_of.rb +36 -0
  73. data/reek.gemspec +5 -5
  74. data/spec/reek/{help_command_spec.rb → cli/help_command_spec.rb} +3 -4
  75. data/spec/reek/{reek_command_spec.rb → cli/reek_command_spec.rb} +8 -7
  76. data/spec/reek/cli/report_spec.rb +26 -0
  77. data/spec/reek/{version_command_spec.rb → cli/version_command_spec.rb} +3 -3
  78. data/spec/reek/cli/yaml_command_spec.rb +47 -0
  79. data/spec/reek/core/block_context_spec.rb +26 -0
  80. data/spec/reek/core/class_context_spec.rb +53 -0
  81. data/spec/reek/{code_context_spec.rb → core/code_context_spec.rb} +15 -37
  82. data/spec/reek/{code_parser_spec.rb → core/code_parser_spec.rb} +5 -5
  83. data/spec/reek/{config_spec.rb → core/config_spec.rb} +2 -6
  84. data/spec/reek/{masking_collection_spec.rb → core/masking_collection_spec.rb} +3 -4
  85. data/spec/reek/{method_context_spec.rb → core/method_context_spec.rb} +6 -7
  86. data/spec/reek/core/module_context_spec.rb +42 -0
  87. data/spec/reek/{object_refs_spec.rb → core/object_refs_spec.rb} +5 -6
  88. data/spec/reek/core/singleton_method_context_spec.rb +15 -0
  89. data/spec/reek/core/smell_configuration_spec.rb +11 -0
  90. data/spec/reek/core/stop_context_spec.rb +17 -0
  91. data/spec/reek/examiner_spec.rb +42 -0
  92. data/spec/reek/smell_warning_spec.rb +82 -33
  93. data/spec/reek/smells/attribute_spec.rb +33 -7
  94. data/spec/reek/smells/boolean_parameter_spec.rb +76 -0
  95. data/spec/reek/smells/class_variable_spec.rb +15 -6
  96. data/spec/reek/smells/control_couple_spec.rb +40 -29
  97. data/spec/reek/smells/data_clump_spec.rb +28 -7
  98. data/spec/reek/smells/duplication_spec.rb +47 -41
  99. data/spec/reek/smells/feature_envy_spec.rb +76 -18
  100. data/spec/reek/smells/irresponsible_module_spec.rb +37 -0
  101. data/spec/reek/smells/large_class_spec.rb +91 -56
  102. data/spec/reek/smells/long_method_spec.rb +32 -7
  103. data/spec/reek/smells/long_parameter_list_spec.rb +42 -13
  104. data/spec/reek/smells/long_yield_list_spec.rb +65 -0
  105. data/spec/reek/smells/nested_iterators_spec.rb +94 -3
  106. data/spec/reek/smells/simulated_polymorphism_spec.rb +48 -20
  107. data/spec/reek/smells/smell_detector_shared.rb +28 -0
  108. data/spec/reek/smells/uncommunicative_method_name_spec.rb +57 -0
  109. data/spec/reek/smells/uncommunicative_module_name_spec.rb +67 -0
  110. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +61 -0
  111. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +124 -0
  112. data/spec/reek/smells/utility_function_spec.rb +45 -3
  113. data/spec/reek/source/code_comment_spec.rb +24 -0
  114. data/spec/reek/source/object_source_spec.rb +20 -0
  115. data/spec/reek/{adapters/source_spec.rb → source/source_code_spec.rb} +7 -8
  116. data/spec/reek/source/tree_dresser_spec.rb +165 -0
  117. data/spec/reek/spec/should_reek_of_spec.rb +76 -0
  118. data/spec/reek/spec/should_reek_only_of_spec.rb +89 -0
  119. data/spec/reek/{adapters → spec}/should_reek_spec.rb +8 -32
  120. data/spec/samples/all_but_one_masked/clean_one.rb +1 -0
  121. data/spec/samples/all_but_one_masked/dirty.rb +1 -0
  122. data/spec/samples/all_but_one_masked/masked.reek +5 -1
  123. data/spec/samples/clean_due_to_masking/clean_one.rb +1 -0
  124. data/spec/samples/clean_due_to_masking/clean_three.rb +1 -0
  125. data/spec/samples/clean_due_to_masking/clean_two.rb +1 -0
  126. data/spec/samples/clean_due_to_masking/dirty_one.rb +1 -1
  127. data/spec/samples/clean_due_to_masking/dirty_two.rb +1 -1
  128. data/spec/samples/clean_due_to_masking/masked.reek +5 -1
  129. data/spec/samples/corrupt_config_file/dirty.rb +1 -1
  130. data/spec/samples/empty_config_file/dirty.rb +2 -1
  131. data/spec/samples/exceptions.reek +1 -1
  132. data/spec/samples/masked/dirty.rb +2 -1
  133. data/spec/samples/masked/masked.reek +3 -1
  134. data/spec/samples/mixed_results/clean_one.rb +1 -0
  135. data/spec/samples/mixed_results/clean_three.rb +1 -0
  136. data/spec/samples/mixed_results/clean_two.rb +1 -0
  137. data/spec/samples/mixed_results/dirty_one.rb +1 -0
  138. data/spec/samples/mixed_results/dirty_two.rb +1 -0
  139. data/spec/samples/not_quite_masked/dirty.rb +2 -1
  140. data/spec/samples/not_quite_masked/masked.reek +1 -1
  141. data/spec/samples/overrides/masked/dirty.rb +2 -1
  142. data/spec/samples/overrides/masked/lower.reek +3 -1
  143. data/spec/samples/three_clean_files/clean_one.rb +1 -0
  144. data/spec/samples/three_clean_files/clean_three.rb +1 -0
  145. data/spec/samples/three_clean_files/clean_two.rb +1 -0
  146. data/spec/samples/two_smelly_files/dirty_one.rb +2 -1
  147. data/spec/samples/two_smelly_files/dirty_two.rb +2 -1
  148. data/spec/spec_helper.rb +1 -2
  149. data/tasks/reek.rake +2 -2
  150. data/tasks/test.rake +12 -3
  151. metadata +81 -62
  152. data/README.rdoc +0 -84
  153. data/lib/reek/adapters/application.rb +0 -46
  154. data/lib/reek/adapters/command_line.rb +0 -77
  155. data/lib/reek/adapters/config_file.rb +0 -31
  156. data/lib/reek/adapters/core_extras.rb +0 -64
  157. data/lib/reek/adapters/rake_task.rb +0 -121
  158. data/lib/reek/adapters/report.rb +0 -86
  159. data/lib/reek/adapters/source.rb +0 -72
  160. data/lib/reek/adapters/spec.rb +0 -133
  161. data/lib/reek/block_context.rb +0 -62
  162. data/lib/reek/class_context.rb +0 -41
  163. data/lib/reek/code_context.rb +0 -68
  164. data/lib/reek/code_parser.rb +0 -203
  165. data/lib/reek/configuration.rb +0 -57
  166. data/lib/reek/detector_stack.rb +0 -37
  167. data/lib/reek/help_command.rb +0 -14
  168. data/lib/reek/if_context.rb +0 -18
  169. data/lib/reek/masking_collection.rb +0 -33
  170. data/lib/reek/method_context.rb +0 -138
  171. data/lib/reek/module_context.rb +0 -49
  172. data/lib/reek/name.rb +0 -57
  173. data/lib/reek/reek_command.rb +0 -28
  174. data/lib/reek/sexp_formatter.rb +0 -10
  175. data/lib/reek/sniffer.rb +0 -177
  176. data/lib/reek/stop_context.rb +0 -35
  177. data/lib/reek/tree_dresser.rb +0 -82
  178. data/lib/reek/version_command.rb +0 -14
  179. data/lib/reek/yield_call_context.rb +0 -12
  180. data/spec/reek/adapters/report_spec.rb +0 -31
  181. data/spec/reek/adapters/should_reek_of_spec.rb +0 -138
  182. data/spec/reek/adapters/should_reek_only_of_spec.rb +0 -87
  183. data/spec/reek/block_context_spec.rb +0 -65
  184. data/spec/reek/class_context_spec.rb +0 -161
  185. data/spec/reek/configuration_spec.rb +0 -12
  186. data/spec/reek/if_context_spec.rb +0 -17
  187. data/spec/reek/module_context_spec.rb +0 -46
  188. data/spec/reek/name_spec.rb +0 -37
  189. data/spec/reek/object_source_spec.rb +0 -23
  190. data/spec/reek/singleton_method_context_spec.rb +0 -16
  191. data/spec/reek/smells/smell_detector_spec.rb +0 -36
  192. data/spec/reek/smells/uncommunicative_name_spec.rb +0 -146
  193. data/spec/reek/sniffer_spec.rb +0 -11
  194. data/spec/reek/stop_context_spec.rb +0 -33
  195. data/spec/reek/tree_dresser_spec.rb +0 -20
@@ -10,7 +10,8 @@ Feature: Basic smell detection
10
10
  Then the exit status indicates smells
11
11
  And it reports:
12
12
  """
13
- spec/samples/inline.rb -- 39 warnings (+1 masked):
13
+ spec/samples/inline.rb -- 41 warnings (+1 masked):
14
+ File has no descriptive comment (Irresponsible Module)
14
15
  Inline declares the class variable @@directory (Class Variable)
15
16
  Inline declares the class variable @@rootdir (Class Variable)
16
17
  Inline#self.rootdir calls env.nil? twice (Duplication)
@@ -28,10 +29,10 @@ Feature: Basic smell detection
28
29
  Inline::C#build calls io.puts("#ifdef __cplusplus") twice (Duplication)
29
30
  Inline::C#build calls module_name twice (Duplication)
30
31
  Inline::C#build calls warn("Output:\n#{result}") twice (Duplication)
32
+ Inline::C#build contains iterators nested 2 deep (Nested Iterators)
31
33
  Inline::C#build has approx 60 statements (Long Method)
34
+ Inline::C#build has the variable name 'n' (Uncommunicative Name)
32
35
  Inline::C#build has the variable name 't' (Uncommunicative Name)
33
- Inline::C#build/block/block has the variable name 'n' (Uncommunicative Name)
34
- Inline::C#build/block/block is nested (Nested Iterators)
35
36
  Inline::C#c has the name 'c' (Uncommunicative Name)
36
37
  Inline::C#crap_for_windoze calls Config::CONFIG["libdir"] twice (Duplication)
37
38
  Inline::C#generate calls result.sub!(/\A\n/, "") twice (Duplication)
@@ -40,13 +41,14 @@ Feature: Basic smell detection
40
41
  Inline::C#generate has approx 32 statements (Long Method)
41
42
  Inline::C#initialize calls stack.empty? twice (Duplication)
42
43
  Inline::C#load calls so_name twice (Duplication)
43
- Inline::C#module_name/block has the variable name 'm' (Uncommunicative Name)
44
- Inline::C#module_name/block has the variable name 'x' (Uncommunicative Name)
44
+ Inline::C#module_name has the variable name 'm' (Uncommunicative Name)
45
+ Inline::C#module_name has the variable name 'x' (Uncommunicative Name)
45
46
  Inline::C#parse_signature has approx 15 statements (Long Method)
47
+ Inline::C#parse_signature has boolean parameter 'raw' (Control Couple)
48
+ Inline::C#parse_signature has the variable name 'x' (Uncommunicative Name)
46
49
  Inline::C#parse_signature is controlled by argument raw (Control Couple)
47
- Inline::C#parse_signature/block has the variable name 'x' (Uncommunicative Name)
48
- Inline::C#strip_comments doesn't depend on instance state (Utility Function)
49
- Inline::C#strip_comments refers to src more than self (Feature Envy)
50
+ Inline::C#strip_comments doesn't depend on instance state (Low Cohesion)
51
+ Inline::C#strip_comments refers to src more than self (Low Cohesion)
50
52
  Module#inline calls Inline.const_get(lang) twice (Duplication)
51
53
  Module#inline has approx 11 statements (Long Method)
52
54
  Module#inline is controlled by argument options (Control Couple)
@@ -58,20 +60,24 @@ Feature: Basic smell detection
58
60
  Then the exit status indicates smells
59
61
  And it reports:
60
62
  """
61
- spec/samples/optparse.rb -- 124 warnings:
63
+ spec/samples/optparse.rb -- 109 warnings:
62
64
  OptionParser has at least 42 methods (Large Class)
65
+ OptionParser has the variable name 'f' (Uncommunicative Name)
66
+ OptionParser has the variable name 'k' (Uncommunicative Name)
67
+ OptionParser has the variable name 'o' (Uncommunicative Name)
68
+ OptionParser has the variable name 's' (Uncommunicative Name)
69
+ OptionParser has the variable name 'v' (Uncommunicative Name)
63
70
  OptionParser tests ((argv.size == 1) and Array.===(argv[0])) at least 3 times (Simulated Polymorphism)
64
71
  OptionParser tests a at least 7 times (Simulated Polymorphism)
65
72
  OptionParser tests default_pattern at least 7 times (Simulated Polymorphism)
66
73
  OptionParser tests not_style at least 3 times (Simulated Polymorphism)
67
74
  OptionParser tests s at least 7 times (Simulated Polymorphism)
75
+ OptionParser#complete contains iterators nested 2 deep (Nested Iterators)
68
76
  OptionParser#complete has 4 parameters (Long Parameter List)
69
- OptionParser#complete is controlled by argument icase (Control Couple)
70
- OptionParser#complete/block/block is nested (Nested Iterators)
77
+ OptionParser#complete has boolean parameter 'icase' (Control Couple)
71
78
  OptionParser#getopts calls result[opt] = false twice (Duplication)
72
79
  OptionParser#getopts has approx 17 statements (Long Method)
73
- OptionParser#getopts/block is controlled by argument val (Control Couple)
74
- OptionParser#load/block has the variable name 's' (Uncommunicative Name)
80
+ OptionParser#load has the variable name 's' (Uncommunicative Name)
75
81
  OptionParser#make_switch calls (long << o = q.downcase) twice (Duplication)
76
82
  OptionParser#make_switch calls (sdesc << "-#{q}") twice (Duplication)
77
83
  OptionParser#make_switch calls default_style.guess(arg = a) 4 times (Duplication)
@@ -83,24 +89,20 @@ Feature: Basic smell detection
83
89
  OptionParser#make_switch calls q.downcase 3 times (Duplication)
84
90
  OptionParser#make_switch calls search(:atype, FalseClass) twice (Duplication)
85
91
  OptionParser#make_switch calls search(:atype, o) 6 times (Duplication)
92
+ OptionParser#make_switch contains iterators nested 2 deep (Nested Iterators)
93
+ OptionParser#make_switch contains iterators nested 3 deep (Nested Iterators)
86
94
  OptionParser#make_switch has approx 68 statements (Long Method)
87
95
  OptionParser#make_switch has the variable name 'a' (Uncommunicative Name)
96
+ OptionParser#make_switch has the variable name 'c' (Uncommunicative Name)
88
97
  OptionParser#make_switch has the variable name 'n' (Uncommunicative Name)
89
98
  OptionParser#make_switch has the variable name 'o' (Uncommunicative Name)
90
99
  OptionParser#make_switch has the variable name 'q' (Uncommunicative Name)
91
100
  OptionParser#make_switch has the variable name 's' (Uncommunicative Name)
92
- OptionParser#make_switch/block has the variable name 'a' (Uncommunicative Name)
93
- OptionParser#make_switch/block has the variable name 'o' (Uncommunicative Name)
94
- OptionParser#make_switch/block has the variable name 'q' (Uncommunicative Name)
95
- OptionParser#make_switch/block/block has the variable name 'c' (Uncommunicative Name)
96
- OptionParser#make_switch/block/block has the variable name 'o' (Uncommunicative Name)
97
- OptionParser#make_switch/block/block has the variable name 'v' (Uncommunicative Name)
98
- OptionParser#make_switch/block/block is nested (Nested Iterators)
99
- OptionParser#make_switch/block/block/block is nested (Nested Iterators)
101
+ OptionParser#make_switch has the variable name 'v' (Uncommunicative Name)
100
102
  OptionParser#order calls argv[0] twice (Duplication)
101
- OptionParser#order refers to argv more than self (Feature Envy)
103
+ OptionParser#order refers to argv more than self (Low Cohesion)
102
104
  OptionParser#parse calls argv[0] twice (Duplication)
103
- OptionParser#parse refers to argv more than self (Feature Envy)
105
+ OptionParser#parse refers to argv more than self (Low Cohesion)
104
106
  OptionParser#parse_in_order calls $!.set_option(arg, true) twice (Duplication)
105
107
  OptionParser#parse_in_order calls cb.call(val) twice (Duplication)
106
108
  OptionParser#parse_in_order calls raise($!.set_option(arg, true)) twice (Duplication)
@@ -108,50 +110,37 @@ Feature: Basic smell detection
108
110
  OptionParser#parse_in_order calls setter.call(sw.switch_name, val) twice (Duplication)
109
111
  OptionParser#parse_in_order calls sw.block twice (Duplication)
110
112
  OptionParser#parse_in_order calls sw.switch_name twice (Duplication)
113
+ OptionParser#parse_in_order contains iterators nested 2 deep (Nested Iterators)
114
+ OptionParser#parse_in_order contains iterators nested 3 deep (Nested Iterators)
111
115
  OptionParser#parse_in_order has approx 28 statements (Long Method)
112
- OptionParser#parse_in_order/block is controlled by argument setter (Control Couple)
113
- OptionParser#parse_in_order/block/block is nested (Nested Iterators)
114
- OptionParser#parse_in_order/block/block/block is nested (Nested Iterators)
116
+ OptionParser#parse_in_order is controlled by argument setter (Control Couple)
115
117
  OptionParser#permute calls argv[0] twice (Duplication)
116
- OptionParser#permute refers to argv more than self (Feature Envy)
117
- OptionParser#search/block has the variable name 'k' (Uncommunicative Name)
118
+ OptionParser#permute refers to argv more than self (Low Cohesion)
119
+ OptionParser#search has the variable name 'k' (Uncommunicative Name)
118
120
  OptionParser#summarize has 4 parameters (Long Parameter List)
119
- OptionParser#summarize/block has the variable name 'l' (Uncommunicative Name)
121
+ OptionParser#summarize has the variable name 'l' (Uncommunicative Name)
120
122
  OptionParser#ver has the variable name 'v' (Uncommunicative Name)
121
- OptionParser/block has the variable name 'f' (Uncommunicative Name)
122
- OptionParser/block has the variable name 'k' (Uncommunicative Name)
123
- OptionParser/block has the variable name 'o' (Uncommunicative Name)
124
- OptionParser/block has the variable name 's' (Uncommunicative Name)
125
- OptionParser/block is controlled by argument o (Control Couple)
126
- OptionParser/block is controlled by argument s (Control Couple)
127
- OptionParser/block/block has the variable name 's' (Uncommunicative Name)
128
- OptionParser/block/block has the variable name 'v' (Uncommunicative Name)
129
- OptionParser/block/block is controlled by argument pkg (Control Couple)
130
- OptionParser/block/block is nested (Nested Iterators)
131
- OptionParser::CompletingHash#match/block/block is nested (Nested Iterators)
123
+ OptionParser::CompletingHash#match contains iterators nested 2 deep (Nested Iterators)
132
124
  OptionParser::Completion#complete calls candidates.size twice (Duplication)
133
125
  OptionParser::Completion#complete calls k.id2name twice (Duplication)
134
126
  OptionParser::Completion#complete has approx 22 statements (Long Method)
127
+ OptionParser::Completion#complete has boolean parameter 'icase' (Control Couple)
135
128
  OptionParser::Completion#complete has the variable name 'k' (Uncommunicative Name)
136
129
  OptionParser::Completion#complete has the variable name 'v' (Uncommunicative Name)
137
- OptionParser::Completion#complete is controlled by argument icase (Control Couple)
138
- OptionParser::Completion#complete refers to candidates more than self (Feature Envy)
139
- OptionParser::Completion#complete/block has the variable name 'k' (Uncommunicative Name)
140
- OptionParser::Completion#complete/block has the variable name 'v' (Uncommunicative Name)
141
- OptionParser::List#accept has the variable name 't' (Uncommunicative Name)
130
+ OptionParser::Completion#complete refers to candidates more than self (Low Cohesion)
131
+ OptionParser::List#accept has the parameter name 't' (Uncommunicative Name)
142
132
  OptionParser::List#accept is controlled by argument pat (Control Couple)
143
- OptionParser::List#accept refers to pat more than self (Feature Envy)
144
- OptionParser::List#add_banner refers to opt more than self (Feature Envy)
133
+ OptionParser::List#accept refers to pat more than self (Low Cohesion)
134
+ OptionParser::List#add_banner refers to opt more than self (Low Cohesion)
145
135
  OptionParser::List#complete has 4 parameters (Long Parameter List)
146
- OptionParser::List#complete is controlled by argument icase (Control Couple)
147
- OptionParser::List#reject has the variable name 't' (Uncommunicative Name)
148
- OptionParser::List#summarize refers to opt more than self (Feature Envy)
136
+ OptionParser::List#complete has boolean parameter 'icase' (Control Couple)
137
+ OptionParser::List#reject has the parameter name 't' (Uncommunicative Name)
138
+ OptionParser::List#summarize refers to opt more than self (Low Cohesion)
149
139
  OptionParser::List#update has 5 parameters (Long Parameter List)
150
140
  OptionParser::List#update has approx 6 statements (Long Method)
151
141
  OptionParser::List#update has the variable name 'o' (Uncommunicative Name)
152
142
  OptionParser::List#update is controlled by argument lopts (Control Couple)
153
143
  OptionParser::List#update is controlled by argument sopts (Control Couple)
154
- OptionParser::List#update/block has the variable name 'o' (Uncommunicative Name)
155
144
  OptionParser::ParseError#set_option is controlled by argument eq (Control Couple)
156
145
  OptionParser::Switch#add_banner has the variable name 's' (Uncommunicative Name)
157
146
  OptionParser::Switch#conv_arg calls conv twice (Duplication)
@@ -162,7 +151,7 @@ Feature: Basic smell detection
162
151
  OptionParser::Switch#parse_arg has the variable name 'm' (Uncommunicative Name)
163
152
  OptionParser::Switch#parse_arg has the variable name 's' (Uncommunicative Name)
164
153
  OptionParser::Switch#self.guess has the variable name 't' (Uncommunicative Name)
165
- OptionParser::Switch#self.incompatible_argument_styles has the variable name 't' (Uncommunicative Name)
154
+ OptionParser::Switch#self.incompatible_argument_styles has the parameter name 't' (Uncommunicative Name)
166
155
  OptionParser::Switch#summarize calls (indent + l) twice (Duplication)
167
156
  OptionParser::Switch#summarize calls arg 4 times (Duplication)
168
157
  OptionParser::Switch#summarize calls left.collect twice (Duplication)
@@ -171,18 +160,16 @@ Feature: Basic smell detection
171
160
  OptionParser::Switch#summarize calls left.shift twice (Duplication)
172
161
  OptionParser::Switch#summarize calls left[-1] 3 times (Duplication)
173
162
  OptionParser::Switch#summarize calls s.length 3 times (Duplication)
163
+ OptionParser::Switch#summarize contains iterators nested 2 deep (Nested Iterators)
174
164
  OptionParser::Switch#summarize has 5 parameters (Long Parameter List)
175
165
  OptionParser::Switch#summarize has approx 25 statements (Long Method)
176
166
  OptionParser::Switch#summarize has the variable name 'l' (Uncommunicative Name)
177
167
  OptionParser::Switch#summarize has the variable name 'r' (Uncommunicative Name)
178
168
  OptionParser::Switch#summarize has the variable name 's' (Uncommunicative Name)
179
- OptionParser::Switch#summarize/block has the variable name 's' (Uncommunicative Name)
180
- OptionParser::Switch#summarize/block/block is nested (Nested Iterators)
181
169
  OptionParser::Switch::NoArgument#parse is controlled by argument arg (Control Couple)
182
170
  OptionParser::Switch::OptionalArgument#parse is controlled by argument arg (Control Couple)
183
171
  OptionParser::Switch::PlacedArgument#parse has approx 6 statements (Long Method)
184
172
  OptionParser::Switch::RequiredArgument#parse is controlled by argument arg (Control Couple)
185
- block has the variable name 'q' (Uncommunicative Name)
186
173
 
187
174
  """
188
175
 
@@ -191,84 +178,84 @@ Feature: Basic smell detection
191
178
  Then the exit status indicates smells
192
179
  And it reports:
193
180
  """
194
- spec/samples/redcloth.rb -- 96 warnings:
181
+ spec/samples/redcloth.rb -- 94 warnings:
195
182
  RedCloth has at least 44 methods (Large Class)
183
+ RedCloth has the variable name 'a' (Uncommunicative Name)
184
+ RedCloth has the variable name 'b' (Uncommunicative Name)
196
185
  RedCloth takes parameters [atts, cite, content, tag] to 3 methods (Data Clump)
197
186
  RedCloth tests atts at least 6 times (Simulated Polymorphism)
198
187
  RedCloth tests codepre.zero? at least 3 times (Simulated Polymorphism)
199
188
  RedCloth tests href at least 3 times (Simulated Polymorphism)
200
189
  RedCloth tests title at least 4 times (Simulated Polymorphism)
201
- RedCloth#block_markdown_atx refers to text more than self (Feature Envy)
190
+ RedCloth#block_markdown_atx refers to text more than self (Low Cohesion)
202
191
  RedCloth#block_markdown_bq has approx 6 statements (Long Method)
203
- RedCloth#block_markdown_rule refers to text more than self (Feature Envy)
204
- RedCloth#block_markdown_setext refers to text more than self (Feature Envy)
192
+ RedCloth#block_markdown_rule refers to text more than self (Low Cohesion)
193
+ RedCloth#block_markdown_setext refers to text more than self (Low Cohesion)
205
194
  RedCloth#block_textile_lists calls (line_id - 1) twice (Duplication)
206
195
  RedCloth#block_textile_lists calls depth.last 5 times (Duplication)
207
196
  RedCloth#block_textile_lists calls depth.last.length twice (Duplication)
208
197
  RedCloth#block_textile_lists calls depth[i] twice (Duplication)
209
198
  RedCloth#block_textile_lists calls lines[(line_id - 1)] twice (Duplication)
210
199
  RedCloth#block_textile_lists calls tl.length 3 times (Duplication)
200
+ RedCloth#block_textile_lists contains iterators nested 3 deep (Nested Iterators)
211
201
  RedCloth#block_textile_lists has approx 20 statements (Long Method)
212
- RedCloth#block_textile_lists refers to depth more than self (Feature Envy)
213
- RedCloth#block_textile_lists/block/block is nested (Nested Iterators)
214
- RedCloth#block_textile_lists/block/block/block has the variable name 'i' (Uncommunicative Name)
215
- RedCloth#block_textile_lists/block/block/block has the variable name 'v' (Uncommunicative Name)
216
- RedCloth#block_textile_lists/block/block/block is nested (Nested Iterators)
202
+ RedCloth#block_textile_lists has the variable name 'i' (Uncommunicative Name)
203
+ RedCloth#block_textile_lists has the variable name 'v' (Uncommunicative Name)
204
+ RedCloth#block_textile_lists refers to depth more than self (Low Cohesion)
205
+ RedCloth#block_textile_table contains iterators nested 2 deep (Nested Iterators)
206
+ RedCloth#block_textile_table contains iterators nested 3 deep (Nested Iterators)
217
207
  RedCloth#block_textile_table has approx 18 statements (Long Method)
218
- RedCloth#block_textile_table/block/block has the variable name 'x' (Uncommunicative Name)
219
- RedCloth#block_textile_table/block/block is nested (Nested Iterators)
220
- RedCloth#block_textile_table/block/block/block is nested (Nested Iterators)
208
+ RedCloth#block_textile_table has the variable name 'x' (Uncommunicative Name)
209
+ RedCloth#blocks contains iterators nested 2 deep (Nested Iterators)
221
210
  RedCloth#blocks has approx 18 statements (Long Method)
211
+ RedCloth#blocks has boolean parameter 'deep_code' (Control Couple)
222
212
  RedCloth#blocks is controlled by argument deep_code (Control Couple)
223
- RedCloth#blocks/block is controlled by argument deep_code (Control Couple)
224
- RedCloth#blocks/block/block is nested (Nested Iterators)
225
213
  RedCloth#check_refs is controlled by argument text (Control Couple)
226
214
  RedCloth#clean_html calls tags[tag] twice (Duplication)
227
- RedCloth#clean_html doesn't depend on instance state (Utility Function)
215
+ RedCloth#clean_html contains iterators nested 3 deep (Nested Iterators)
216
+ RedCloth#clean_html doesn't depend on instance state (Low Cohesion)
228
217
  RedCloth#clean_html has approx 14 statements (Long Method)
229
- RedCloth#clean_html refers to raw more than self (Feature Envy)
230
- RedCloth#clean_html refers to tags more than self (Feature Envy)
231
- RedCloth#clean_html/block/block is nested (Nested Iterators)
232
- RedCloth#clean_html/block/block/block has the variable name 'q' (Uncommunicative Name)
233
- RedCloth#clean_html/block/block/block has the variable name 'q2' (Uncommunicative Name)
234
- RedCloth#clean_html/block/block/block is nested (Nested Iterators)
218
+ RedCloth#clean_html has the variable name 'q' (Uncommunicative Name)
219
+ RedCloth#clean_html has the variable name 'q2' (Uncommunicative Name)
220
+ RedCloth#clean_html refers to raw more than self (Low Cohesion)
221
+ RedCloth#clean_html refers to tags more than self (Low Cohesion)
235
222
  RedCloth#clean_white_space has approx 7 statements (Long Method)
236
- RedCloth#clean_white_space refers to text more than self (Feature Envy)
237
- RedCloth#flush_left doesn't depend on instance state (Utility Function)
238
- RedCloth#flush_left refers to indt more than self (Feature Envy)
239
- RedCloth#flush_left refers to text more than self (Feature Envy)
240
- RedCloth#footnote_ref refers to text more than self (Feature Envy)
223
+ RedCloth#clean_white_space refers to text more than self (Low Cohesion)
224
+ RedCloth#flush_left doesn't depend on instance state (Low Cohesion)
225
+ RedCloth#flush_left refers to indt more than self (Low Cohesion)
226
+ RedCloth#flush_left refers to text more than self (Low Cohesion)
227
+ RedCloth#footnote_ref refers to text more than self (Low Cohesion)
241
228
  RedCloth#glyphs_textile has approx 10 statements (Long Method)
242
- RedCloth#htmlesc doesn't depend on instance state (Utility Function)
243
- RedCloth#htmlesc refers to str more than self (Feature Envy)
244
- RedCloth#incoming_entities refers to text more than self (Feature Envy)
245
- RedCloth#initialize/block has the variable name 'r' (Uncommunicative Name)
246
- RedCloth#inline/block/block is nested (Nested Iterators)
229
+ RedCloth#htmlesc doesn't depend on instance state (Low Cohesion)
230
+ RedCloth#htmlesc refers to str more than self (Low Cohesion)
231
+ RedCloth#incoming_entities refers to text more than self (Low Cohesion)
232
+ RedCloth#initialize has the variable name 'r' (Uncommunicative Name)
233
+ RedCloth#inline contains iterators nested 2 deep (Nested Iterators)
247
234
  RedCloth#inline_markdown_link has approx 6 statements (Long Method)
248
- RedCloth#inline_markdown_link/block has the variable name 'm' (Uncommunicative Name)
235
+ RedCloth#inline_markdown_link has the variable name 'm' (Uncommunicative Name)
249
236
  RedCloth#inline_markdown_reflink has approx 8 statements (Long Method)
250
- RedCloth#inline_markdown_reflink/block has the variable name 'm' (Uncommunicative Name)
251
- RedCloth#inline_textile_code/block has the variable name 'm' (Uncommunicative Name)
237
+ RedCloth#inline_markdown_reflink has the variable name 'm' (Uncommunicative Name)
238
+ RedCloth#inline_textile_code has the variable name 'm' (Uncommunicative Name)
252
239
  RedCloth#inline_textile_image has approx 17 statements (Long Method)
253
- RedCloth#inline_textile_image/block has the variable name 'href_a1' (Uncommunicative Name)
254
- RedCloth#inline_textile_image/block has the variable name 'href_a2' (Uncommunicative Name)
255
- RedCloth#inline_textile_image/block has the variable name 'm' (Uncommunicative Name)
240
+ RedCloth#inline_textile_image has the variable name 'href_a1' (Uncommunicative Name)
241
+ RedCloth#inline_textile_image has the variable name 'href_a2' (Uncommunicative Name)
242
+ RedCloth#inline_textile_image has the variable name 'm' (Uncommunicative Name)
256
243
  RedCloth#inline_textile_link has approx 9 statements (Long Method)
257
- RedCloth#inline_textile_link/block has the variable name 'm' (Uncommunicative Name)
244
+ RedCloth#inline_textile_link has the variable name 'm' (Uncommunicative Name)
245
+ RedCloth#inline_textile_span contains iterators nested 2 deep (Nested Iterators)
258
246
  RedCloth#inline_textile_span has approx 8 statements (Long Method)
259
- RedCloth#inline_textile_span/block/block has the variable name 'm' (Uncommunicative Name)
260
- RedCloth#inline_textile_span/block/block is nested (Nested Iterators)
261
- RedCloth#no_textile doesn't depend on instance state (Utility Function)
262
- RedCloth#no_textile refers to text more than self (Feature Envy)
247
+ RedCloth#inline_textile_span has the variable name 'm' (Uncommunicative Name)
248
+ RedCloth#no_textile doesn't depend on instance state (Low Cohesion)
249
+ RedCloth#no_textile refers to text more than self (Low Cohesion)
263
250
  RedCloth#pba calls $1.length twice (Duplication)
264
251
  RedCloth#pba has approx 21 statements (Long Method)
265
252
  RedCloth#pba is controlled by argument text_in (Control Couple)
266
- RedCloth#pba refers to style more than self (Feature Envy)
267
- RedCloth#pba refers to text more than self (Feature Envy)
268
- RedCloth#refs_markdown/block has the variable name 'm' (Uncommunicative Name)
269
- RedCloth#refs_textile/block has the variable name 'm' (Uncommunicative Name)
270
- RedCloth#retrieve/block has the variable name 'i' (Uncommunicative Name)
271
- RedCloth#retrieve/block has the variable name 'r' (Uncommunicative Name)
253
+ RedCloth#pba refers to style more than self (Low Cohesion)
254
+ RedCloth#pba refers to text more than self (Low Cohesion)
255
+ RedCloth#refs_markdown has the variable name 'm' (Uncommunicative Name)
256
+ RedCloth#refs_textile has the variable name 'm' (Uncommunicative Name)
257
+ RedCloth#retrieve has the variable name 'i' (Uncommunicative Name)
258
+ RedCloth#retrieve has the variable name 'r' (Uncommunicative Name)
272
259
  RedCloth#rip_offtags calls ((codepre - used_offtags.length) > 0) twice (Duplication)
273
260
  RedCloth#rip_offtags calls (@pre_list.last << line) twice (Duplication)
274
261
  RedCloth#rip_offtags calls (codepre - used_offtags.length) twice (Duplication)
@@ -286,7 +273,5 @@ Feature: Basic smell detection
286
273
  RedCloth#textile_p has 4 parameters (Long Parameter List)
287
274
  RedCloth#textile_p is controlled by argument atts (Control Couple)
288
275
  RedCloth#to_html has approx 24 statements (Long Method)
289
- RedCloth/block has the variable name 'a' (Uncommunicative Name)
290
- RedCloth/block has the variable name 'b' (Uncommunicative Name)
291
276
 
292
277
  """
@@ -25,18 +25,15 @@ Feature: Reek reads from $stdin when no files are given
25
25
  Scenario: outputs nothing on empty stdin in quiet mode
26
26
  When I pass "" to reek --quiet
27
27
  Then it succeeds
28
- And it reports:
29
- """
30
-
31
-
32
- """
28
+ And stdout equals ""
33
29
 
34
30
  Scenario: return non-zero status when there are smells
35
31
  When I pass "class Turn; def y() @x = 3; end end" to reek
36
32
  Then the exit status indicates smells
37
33
  And it reports:
38
34
  """
39
- $stdin -- 2 warnings:
35
+ $stdin -- 3 warnings:
36
+ Turn has no descriptive comment (Irresponsible Module)
40
37
  Turn has the variable name '@x' (Uncommunicative Name)
41
38
  Turn#y has the name 'y' (Uncommunicative Name)
42
39
 
@@ -14,16 +14,20 @@ Then /^stdout equals "([^\"]*)"$/ do |report|
14
14
  @last_stdout.should == report
15
15
  end
16
16
 
17
+ Then /^stdout includes \/([^\"]*)\/$/ do |report|
18
+ @last_stdout.should match(report)
19
+ end
20
+
17
21
  Then /^it succeeds$/ do
18
- @last_exit_status.should == Reek::Application::STATUS_SUCCESS
22
+ @last_exit_status.should == Reek::Cli::Application::STATUS_SUCCESS
19
23
  end
20
24
 
21
25
  Then /^the exit status indicates an error$/ do
22
- @last_exit_status.should == Reek::Application::STATUS_ERROR
26
+ @last_exit_status.should == Reek::Cli::Application::STATUS_ERROR
23
27
  end
24
28
 
25
29
  Then /^the exit status indicates smells$/ do
26
- @last_exit_status.should == Reek::Application::STATUS_SMELLS
30
+ @last_exit_status.should == Reek::Cli::Application::STATUS_SMELLS
27
31
  end
28
32
 
29
33
  Then /^it reports:$/ do |report|
@@ -39,5 +43,5 @@ Then /^it reports the error ['"](.*)['"]$/ do |string|
39
43
  end
40
44
 
41
45
  Then /^it reports the current version$/ do
42
- @last_stdout.chomp.should == "reek #{Reek::VERSION}"
46
+ @last_stdout.should == "reek #{Reek::VERSION}\n"
43
47
  end
@@ -4,8 +4,7 @@ require 'rubygems'
4
4
  require 'tempfile'
5
5
  require 'spec/expectations'
6
6
  require 'fileutils'
7
- require 'reek'
8
- require 'reek/adapters/application'
7
+ require 'reek/cli/application'
9
8
 
10
9
  class ReekWorld
11
10
  def run(cmd)
@@ -27,7 +26,7 @@ class ReekWorld
27
26
  def rake(name, task_def)
28
27
  header = <<EOS
29
28
  $:.unshift('lib')
30
- require 'reek/adapters/rake_task'
29
+ require 'reek/rake/task'
31
30
 
32
31
  EOS
33
32
  rakefile = Tempfile.new('rake_task', '.')
@@ -0,0 +1,124 @@
1
+ @yaml
2
+ Feature: Report smells using simple YAML layout
3
+ In order to parse reek's output simply and consistently, simply
4
+ output a list of smells in Yaml.
5
+
6
+ Scenario: output is empty when there are no smells
7
+ When I run reek --yaml spec/samples/three_clean_files
8
+ Then it succeeds
9
+ And stdout equals ""
10
+
11
+ @masking
12
+ Scenario: masked smells always appear
13
+ When I run reek --yaml spec/samples/masked/dirty.rb
14
+ Then the exit status indicates smells
15
+ And it reports:
16
+ """
17
+ ---
18
+ - !ruby/object:Reek::SmellWarning
19
+ location:
20
+ lines:
21
+ - 5
22
+ context: Dirty
23
+ source: spec/samples/masked/dirty.rb
24
+ smell:
25
+ class: UncommunicativeName
26
+ subclass: UncommunicativeVariableName
27
+ variable_name: "@s"
28
+ message: has the variable name '@s'
29
+ status:
30
+ is_active: false
31
+ - !ruby/object:Reek::SmellWarning
32
+ location:
33
+ lines:
34
+ - 4
35
+ - 6
36
+ context: Dirty#a
37
+ source: spec/samples/masked/dirty.rb
38
+ smell:
39
+ class: Duplication
40
+ occurrences: 2
41
+ subclass: DuplicateMethodCall
42
+ call: "@s.title"
43
+ message: calls @s.title twice
44
+ status:
45
+ is_active: true
46
+ - !ruby/object:Reek::SmellWarning
47
+ location:
48
+ lines:
49
+ - 5
50
+ - 7
51
+ context: Dirty#a
52
+ source: spec/samples/masked/dirty.rb
53
+ smell:
54
+ class: Duplication
55
+ occurrences: 2
56
+ subclass: DuplicateMethodCall
57
+ call: puts(@s.title)
58
+ message: calls puts(@s.title) twice
59
+ status:
60
+ is_active: true
61
+ - !ruby/object:Reek::SmellWarning
62
+ location:
63
+ lines:
64
+ - 5
65
+ context: Dirty#a
66
+ source: spec/samples/masked/dirty.rb
67
+ smell:
68
+ class: NestedIterators
69
+ depth: 2
70
+ subclass: ""
71
+ message: contains iterators nested 2 deep
72
+ status:
73
+ is_active: true
74
+ - !ruby/object:Reek::SmellWarning
75
+ location:
76
+ lines:
77
+ - 3
78
+ context: Dirty#a
79
+ source: spec/samples/masked/dirty.rb
80
+ smell:
81
+ method_name: a
82
+ class: UncommunicativeName
83
+ subclass: UncommunicativeMethodName
84
+ message: has the name 'a'
85
+ status:
86
+ is_active: false
87
+ - !ruby/object:Reek::SmellWarning
88
+ location:
89
+ lines:
90
+ - 5
91
+ context: Dirty#a
92
+ source: spec/samples/masked/dirty.rb
93
+ smell:
94
+ class: UncommunicativeName
95
+ subclass: UncommunicativeVariableName
96
+ variable_name: x
97
+ message: has the variable name 'x'
98
+ status:
99
+ is_active: false
100
+
101
+ """
102
+
103
+ @stdin
104
+ Scenario: return non-zero status when there are smells
105
+ When I pass "# test class\nclass Turn; def fred(arg = true) end end" to reek --yaml
106
+ Then the exit status indicates smells
107
+ And it reports:
108
+ """
109
+ ---
110
+ - !ruby/object:Reek::SmellWarning
111
+ location:
112
+ lines:
113
+ - 2
114
+ context: Turn#fred
115
+ source: $stdin
116
+ smell:
117
+ parameter: arg
118
+ class: ControlCouple
119
+ subclass: BooleanParameter
120
+ message: has boolean parameter 'arg'
121
+ status:
122
+ is_active: true
123
+
124
+ """