reek 2.0.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +13 -0
  3. data/.rubocop.yml +47 -0
  4. data/.travis.yml +31 -0
  5. data/.yardopts +3 -6
  6. data/CHANGELOG +24 -0
  7. data/CONTRIBUTING.md +111 -0
  8. data/Gemfile +16 -0
  9. data/README.md +112 -59
  10. data/bin/reek +2 -2
  11. data/config/cucumber.yml +3 -0
  12. data/config/defaults.reek +0 -1
  13. data/docs/API.md +79 -0
  14. data/docs/Attribute.md +43 -0
  15. data/docs/Basic-Smell-Options.md +44 -0
  16. data/docs/Boolean-Parameter.md +52 -0
  17. data/docs/Class-Variable.md +40 -0
  18. data/docs/Code-Smells.md +34 -0
  19. data/docs/Command-Line-Options.md +84 -0
  20. data/docs/Configuration-Files.md +49 -0
  21. data/docs/Control-Couple.md +22 -0
  22. data/docs/Control-Parameter.md +29 -0
  23. data/docs/Data-Clump.md +44 -0
  24. data/docs/Duplicate-Method-Call.md +49 -0
  25. data/docs/Feature-Envy.md +49 -0
  26. data/docs/How-reek-works-internally.md +114 -0
  27. data/docs/Irresponsible-Module.md +39 -0
  28. data/docs/Large-Class.md +20 -0
  29. data/docs/Long-Parameter-List.md +38 -0
  30. data/docs/Long-Yield-List.md +36 -0
  31. data/docs/Module-Initialize.md +62 -0
  32. data/docs/Nested-Iterators.md +38 -0
  33. data/docs/Nil-Check.md +39 -0
  34. data/docs/Prima-Donna-Method.md +53 -0
  35. data/docs/RSpec-matchers.md +137 -0
  36. data/docs/Rake-Task.md +58 -0
  37. data/docs/Reek-Driven-Development.md +37 -0
  38. data/docs/Repeated-Conditional.md +44 -0
  39. data/docs/Simulated-Polymorphism.md +16 -0
  40. data/docs/Smell-Suppression.md +32 -0
  41. data/docs/Too-Many-Instance-Variables.md +43 -0
  42. data/docs/Too-Many-Methods.md +55 -0
  43. data/docs/Too-Many-Statements.md +50 -0
  44. data/docs/Uncommunicative-Method-Name.md +24 -0
  45. data/docs/Uncommunicative-Module-Name.md +23 -0
  46. data/docs/Uncommunicative-Name.md +16 -0
  47. data/docs/Uncommunicative-Parameter-Name.md +24 -0
  48. data/docs/Uncommunicative-Variable-Name.md +24 -0
  49. data/docs/Unused-Parameters.md +27 -0
  50. data/docs/Utility-Function.md +44 -0
  51. data/docs/Versioning-Policy.md +7 -0
  52. data/docs/YAML-Reports.md +111 -0
  53. data/docs/yard_plugin.rb +14 -0
  54. data/features/{ruby_api/api.feature → command_line_interface/basic_usage.feature} +6 -5
  55. data/features/command_line_interface/options.feature +1 -0
  56. data/features/command_line_interface/smell_selection.feature +4 -8
  57. data/features/command_line_interface/smells_count.feature +25 -32
  58. data/features/command_line_interface/stdin.feature +2 -2
  59. data/features/configuration_files/masking_smells.feature +30 -41
  60. data/features/configuration_files/overrides_defaults.feature +5 -3
  61. data/features/configuration_loading.feature +26 -23
  62. data/features/programmatic_access.feature +43 -0
  63. data/features/rake_task/rake_task.feature +25 -22
  64. data/features/reports/json.feature +24 -26
  65. data/features/reports/reports.feature +77 -103
  66. data/features/reports/yaml.feature +26 -20
  67. data/features/samples.feature +26 -31
  68. data/features/step_definitions/.rubocop.yml +5 -0
  69. data/features/step_definitions/reek_steps.rb +16 -28
  70. data/features/step_definitions/sample_file_steps.rb +158 -0
  71. data/features/support/env.rb +16 -27
  72. data/lib/reek/{source → ast}/ast_node_class_map.rb +11 -12
  73. data/lib/reek/ast/node.rb +132 -0
  74. data/lib/reek/{core → ast}/object_refs.rb +2 -1
  75. data/lib/reek/ast/reference_collector.rb +32 -0
  76. data/lib/reek/{source → ast}/sexp_extensions.rb +43 -7
  77. data/lib/reek/ast/sexp_formatter.rb +31 -0
  78. data/lib/reek/cli/application.rb +5 -4
  79. data/lib/reek/cli/command.rb +2 -1
  80. data/lib/reek/cli/input.rb +6 -5
  81. data/lib/reek/cli/option_interpreter.rb +13 -9
  82. data/lib/reek/cli/options.rb +16 -8
  83. data/lib/reek/cli/reek_command.rb +4 -3
  84. data/lib/reek/cli/silencer.rb +14 -0
  85. data/lib/reek/{core → cli}/warning_collector.rb +2 -1
  86. data/lib/reek/code_comment.rb +36 -0
  87. data/lib/reek/configuration/app_configuration.rb +18 -3
  88. data/lib/reek/configuration/configuration_file_finder.rb +18 -32
  89. data/lib/reek/{core → context}/code_context.rb +8 -6
  90. data/lib/reek/{core → context}/method_context.rb +11 -5
  91. data/lib/reek/{core → context}/module_context.rb +9 -4
  92. data/lib/reek/{core/stop_context.rb → context/root_context.rb} +4 -2
  93. data/lib/reek/{core → context}/singleton_method_context.rb +3 -6
  94. data/lib/reek/examiner.rb +32 -29
  95. data/lib/reek/report/formatter.rb +70 -0
  96. data/lib/reek/report/heading_formatter.rb +45 -0
  97. data/lib/reek/report/location_formatter.rb +35 -0
  98. data/lib/reek/report/report.rb +198 -0
  99. data/lib/reek/smells/attribute.rb +41 -11
  100. data/lib/reek/smells/boolean_parameter.rb +4 -2
  101. data/lib/reek/smells/class_variable.rb +4 -2
  102. data/lib/reek/smells/control_parameter.rb +4 -2
  103. data/lib/reek/smells/data_clump.rb +4 -3
  104. data/lib/reek/smells/duplicate_method_call.rb +15 -5
  105. data/lib/reek/smells/feature_envy.rb +8 -2
  106. data/lib/reek/smells/irresponsible_module.rb +13 -8
  107. data/lib/reek/smells/long_parameter_list.rb +6 -4
  108. data/lib/reek/smells/long_yield_list.rb +4 -2
  109. data/lib/reek/smells/module_initialize.rb +4 -2
  110. data/lib/reek/smells/nested_iterators.rb +4 -2
  111. data/lib/reek/smells/nil_check.rb +6 -3
  112. data/lib/reek/smells/prima_donna_method.rb +21 -12
  113. data/lib/reek/smells/repeated_conditional.rb +7 -4
  114. data/lib/reek/{core → smells}/smell_configuration.rb +3 -1
  115. data/lib/reek/smells/smell_detector.rb +11 -5
  116. data/lib/reek/{core → smells}/smell_repository.rb +9 -5
  117. data/lib/reek/smells/smell_warning.rb +101 -0
  118. data/lib/reek/smells/too_many_instance_variables.rb +4 -2
  119. data/lib/reek/smells/too_many_methods.rb +4 -2
  120. data/lib/reek/smells/too_many_statements.rb +4 -2
  121. data/lib/reek/smells/uncommunicative_method_name.rb +4 -2
  122. data/lib/reek/smells/uncommunicative_module_name.rb +4 -2
  123. data/lib/reek/smells/uncommunicative_parameter_name.rb +4 -2
  124. data/lib/reek/smells/uncommunicative_variable_name.rb +4 -2
  125. data/lib/reek/smells/unused_parameters.rb +4 -2
  126. data/lib/reek/smells/utility_function.rb +11 -22
  127. data/lib/reek/smells.rb +24 -11
  128. data/lib/reek/source/source_code.rb +69 -12
  129. data/lib/reek/source/source_locator.rb +34 -19
  130. data/lib/reek/spec/should_reek.rb +4 -3
  131. data/lib/reek/spec/should_reek_of.rb +2 -1
  132. data/lib/reek/spec/should_reek_only_of.rb +4 -3
  133. data/lib/reek/spec.rb +3 -3
  134. data/lib/reek/tree_dresser.rb +32 -0
  135. data/lib/reek/tree_walker.rb +182 -0
  136. data/lib/reek/version.rb +1 -1
  137. data/lib/reek.rb +3 -3
  138. data/reek.gemspec +18 -25
  139. data/spec/factories/factories.rb +4 -2
  140. data/spec/gem/updates_spec.rb +1 -1
  141. data/spec/gem/yard_spec.rb +2 -2
  142. data/spec/quality/reek_source_spec.rb +3 -3
  143. data/spec/reek/{source/sexp_node_spec.rb → ast/node_spec.rb} +4 -6
  144. data/spec/reek/{core → ast}/object_refs_spec.rb +4 -6
  145. data/spec/reek/{source → ast}/reference_collector_spec.rb +27 -19
  146. data/spec/reek/{source → ast}/sexp_extensions_spec.rb +7 -19
  147. data/spec/reek/{source → ast}/sexp_formatter_spec.rb +13 -8
  148. data/spec/reek/cli/option_interpreter_spec.rb +15 -0
  149. data/spec/reek/cli/options_spec.rb +19 -0
  150. data/spec/reek/cli/warning_collector_spec.rb +28 -0
  151. data/spec/reek/{source/code_comment_spec.rb → code_comment_spec.rb} +19 -17
  152. data/spec/reek/configuration/app_configuration_spec.rb +37 -26
  153. data/spec/reek/configuration/configuration_file_finder_spec.rb +67 -21
  154. data/spec/reek/{core → context}/code_context_spec.rb +18 -21
  155. data/spec/reek/{core → context}/method_context_spec.rb +33 -27
  156. data/spec/reek/{core → context}/module_context_spec.rb +5 -7
  157. data/spec/reek/context/root_context_spec.rb +14 -0
  158. data/spec/reek/context/singleton_method_context_spec.rb +17 -0
  159. data/spec/reek/examiner_spec.rb +9 -50
  160. data/spec/reek/{cli → report}/html_report_spec.rb +6 -9
  161. data/spec/reek/report/json_report_spec.rb +20 -0
  162. data/spec/reek/{cli → report}/text_report_spec.rb +16 -19
  163. data/spec/reek/report/xml_report_spec.rb +34 -0
  164. data/spec/reek/report/yaml_report_spec.rb +20 -0
  165. data/spec/reek/smells/attribute_spec.rb +93 -88
  166. data/spec/reek/smells/behaves_like_variable_detector.rb +1 -1
  167. data/spec/reek/smells/boolean_parameter_spec.rb +31 -5
  168. data/spec/reek/smells/class_variable_spec.rb +10 -10
  169. data/spec/reek/smells/control_parameter_spec.rb +5 -5
  170. data/spec/reek/smells/data_clump_spec.rb +6 -6
  171. data/spec/reek/smells/duplicate_method_call_spec.rb +7 -7
  172. data/spec/reek/smells/feature_envy_spec.rb +12 -13
  173. data/spec/reek/smells/irresponsible_module_spec.rb +28 -32
  174. data/spec/reek/smells/long_parameter_list_spec.rb +7 -7
  175. data/spec/reek/smells/long_yield_list_spec.rb +6 -6
  176. data/spec/reek/smells/module_initialize_spec.rb +4 -4
  177. data/spec/reek/smells/nested_iterators_spec.rb +6 -6
  178. data/spec/reek/smells/nil_check_spec.rb +6 -6
  179. data/spec/reek/smells/prima_donna_method_spec.rb +8 -5
  180. data/spec/reek/smells/repeated_conditional_spec.rb +18 -17
  181. data/spec/reek/{core → smells}/smell_configuration_spec.rb +5 -7
  182. data/spec/reek/smells/smell_detector_shared.rb +6 -7
  183. data/spec/reek/smells/smell_repository_spec.rb +29 -0
  184. data/spec/reek/{smell_warning_spec.rb → smells/smell_warning_spec.rb} +7 -9
  185. data/spec/reek/smells/too_many_instance_variables_spec.rb +5 -5
  186. data/spec/reek/smells/too_many_methods_spec.rb +12 -8
  187. data/spec/reek/smells/too_many_statements_spec.rb +10 -9
  188. data/spec/reek/smells/uncommunicative_method_name_spec.rb +5 -5
  189. data/spec/reek/smells/uncommunicative_module_name_spec.rb +8 -8
  190. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +18 -6
  191. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +10 -7
  192. data/spec/reek/smells/unused_parameters_spec.rb +4 -4
  193. data/spec/reek/smells/utility_function_spec.rb +65 -39
  194. data/spec/reek/source/source_code_spec.rb +10 -10
  195. data/spec/reek/source/source_locator_spec.rb +30 -0
  196. data/spec/reek/spec/should_reek_of_spec.rb +9 -25
  197. data/spec/reek/spec/should_reek_only_of_spec.rb +4 -7
  198. data/spec/reek/spec/should_reek_spec.rb +4 -32
  199. data/spec/reek/tree_dresser_spec.rb +16 -0
  200. data/spec/reek/{core/tree_walker_spec.rb → tree_walker_spec.rb} +5 -7
  201. data/spec/samples/checkstyle.xml +2 -0
  202. data/spec/samples/configuration/with_excluded_paths.reek +4 -0
  203. data/spec/samples/{overrides/masked/lower.reek → masked_by_dotfile/.reek} +3 -1
  204. data/spec/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +5 -0
  205. data/spec/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +2 -0
  206. data/spec/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +6 -0
  207. data/spec/samples/{ruby20_syntax.rb → unusual_syntax.rb} +8 -0
  208. data/spec/spec_helper.rb +21 -10
  209. data/tasks/develop.rake +2 -2
  210. data/tasks/reek.rake +1 -1
  211. metadata +158 -141
  212. data/features/support/hooks.rb +0 -15
  213. data/lib/reek/cli/report/formatter.rb +0 -69
  214. data/lib/reek/cli/report/heading_formatter.rb +0 -45
  215. data/lib/reek/cli/report/location_formatter.rb +0 -34
  216. data/lib/reek/cli/report/report.rb +0 -131
  217. data/lib/reek/core/tree_walker.rb +0 -180
  218. data/lib/reek/smell_warning.rb +0 -87
  219. data/lib/reek/source/ast_node.rb +0 -38
  220. data/lib/reek/source/code_comment.rb +0 -37
  221. data/lib/reek/source/core_extras.rb +0 -46
  222. data/lib/reek/source/reference_collector.rb +0 -27
  223. data/lib/reek/source/sexp_formatter.rb +0 -22
  224. data/lib/reek/source/sexp_node.rb +0 -79
  225. data/lib/reek/source/source_file.rb +0 -16
  226. data/lib/reek/source/source_repository.rb +0 -45
  227. data/lib/reek/source/tree_dresser.rb +0 -24
  228. data/lib/reek/source.rb +0 -16
  229. data/spec/reek/cli/json_report_spec.rb +0 -20
  230. data/spec/reek/cli/option_interperter_spec.rb +0 -14
  231. data/spec/reek/cli/yaml_report_spec.rb +0 -23
  232. data/spec/reek/core/singleton_method_context_spec.rb +0 -9
  233. data/spec/reek/core/smell_repository_spec.rb +0 -17
  234. data/spec/reek/core/stop_context_spec.rb +0 -17
  235. data/spec/reek/core/warning_collector_spec.rb +0 -30
  236. data/spec/reek/source/object_source_spec.rb +0 -20
  237. data/spec/reek/source/tree_dresser_spec.rb +0 -18
  238. data/spec/samples/config/allow_duplication.reek +0 -3
  239. data/spec/samples/config/deeper_nested_iterators.reek +0 -3
  240. data/spec/samples/configuration_loading/minimal_dirty.rb +0 -4
  241. data/spec/samples/configuration_loading/reek-test-run-disable_smells.reek +0 -7
  242. data/spec/samples/configuration_loading/reek-test-run-enable_smells.reek +0 -7
  243. data/spec/samples/corrupt_config_file/corrupt.reek +0 -1
  244. data/spec/samples/corrupt_config_file/dirty.rb +0 -8
  245. data/spec/samples/demo/demo.rb +0 -8
  246. data/spec/samples/empty_config_file/dirty.rb +0 -8
  247. data/spec/samples/empty_config_file/empty.reek +0 -0
  248. data/spec/samples/inline_config/dirty.rb +0 -16
  249. data/spec/samples/inline_config/masked.reek +0 -7
  250. data/spec/samples/mask_some/dirty.rb +0 -8
  251. data/spec/samples/mask_some/some.reek +0 -8
  252. data/spec/samples/masked/dirty.rb +0 -8
  253. data/spec/samples/masked/masked.reek +0 -5
  254. data/spec/samples/minimal_smelly_and_masked/config.reek +0 -7
  255. data/spec/samples/minimal_smelly_and_masked/minimal_dirty.rb +0 -4
  256. data/spec/samples/mixed_results/clean_one.rb +0 -7
  257. data/spec/samples/mixed_results/clean_three.rb +0 -7
  258. data/spec/samples/mixed_results/clean_two.rb +0 -7
  259. data/spec/samples/mixed_results/dirty_one.rb +0 -8
  260. data/spec/samples/mixed_results/dirty_two.rb +0 -8
  261. data/spec/samples/not_quite_masked/dirty.rb +0 -8
  262. data/spec/samples/not_quite_masked/masked.reek +0 -5
  263. data/spec/samples/not_quite_masked/smelly.rb +0 -3
  264. data/spec/samples/one_smelly_file/dirty.rb +0 -3
  265. data/spec/samples/overrides/masked/dirty.rb +0 -8
  266. data/spec/samples/overrides/upper.reek +0 -5
  267. data/spec/samples/overrides_defaults/camel_case.rb +0 -14
  268. data/spec/samples/overrides_defaults/config.reek +0 -6
  269. data/spec/samples/ruby21_syntax.rb +0 -5
  270. data/spec/samples/standard_smelly/dirty.rb +0 -8
  271. data/spec/samples/standard_smelly/minimal_dirty.rb +0 -4
  272. data/spec/samples/three_smelly_files/dirty_one.rb +0 -3
  273. data/spec/samples/three_smelly_files/dirty_three.rb +0 -5
  274. data/spec/samples/three_smelly_files/dirty_two.rb +0 -4
  275. /data/spec/samples/{simple_configuration.reek → configuration/simple_configuration.reek} +0 -0
@@ -3,45 +3,38 @@ Feature: Reports total number of code smells
3
3
  Reek outputs the total number of smells among all files inspected.
4
4
 
5
5
  Scenario: Does not output total number of smells when inspecting single file
6
- When I run reek spec/samples/standard_smelly/dirty.rb
6
+ Given a smelly file called 'smelly.rb'
7
+ When I run reek smelly.rb
7
8
  Then the exit status indicates smells
8
9
  And it reports:
9
- """
10
- spec/samples/standard_smelly/dirty.rb -- 6 warnings:
11
- [5]:Dirty has the variable name '@s' (UncommunicativeVariableName)
12
- [4, 6]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
13
- [4, 6]:Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
14
- [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
15
- [3]:Dirty#a has the name 'a' (UncommunicativeMethodName)
16
- [5]:Dirty#a has the variable name 'x' (UncommunicativeVariableName)
17
- """
10
+ """
11
+ smelly.rb -- 3 warnings:
12
+ [4, 5]:Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
13
+ [4, 5]:Smelly#m calls puts(@foo.bar) 2 times (DuplicateMethodCall)
14
+ [3]:Smelly#m has the name 'm' (UncommunicativeMethodName)
15
+ """
18
16
 
19
17
  Scenario: Output total number of smells when inspecting multiple files
20
- When I run reek spec/samples/two_smelly_files
18
+ Given a directory called 'smelly' containing two smelly files
19
+ When I run reek smelly
21
20
  Then the exit status indicates smells
22
21
  And it reports:
23
- """
24
- spec/samples/two_smelly_files/dirty_one.rb -- 6 warnings:
25
- [5]:Dirty has the variable name '@s' (UncommunicativeVariableName)
26
- [4, 6]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
27
- [4, 6]:Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
28
- [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
29
- [3]:Dirty#a has the name 'a' (UncommunicativeMethodName)
30
- [5]:Dirty#a has the variable name 'x' (UncommunicativeVariableName)
31
- spec/samples/two_smelly_files/dirty_two.rb -- 6 warnings:
32
- [5]:Dirty has the variable name '@s' (UncommunicativeVariableName)
33
- [4, 6]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
34
- [4, 6]:Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
35
- [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
36
- [3]:Dirty#a has the name 'a' (UncommunicativeMethodName)
37
- [5]:Dirty#a has the variable name 'x' (UncommunicativeVariableName)
38
- 12 total warnings
39
- """
22
+ """
23
+ smelly/dirty_one.rb -- 2 warnings:
24
+ [1]:Dirty has no descriptive comment (IrresponsibleModule)
25
+ [2]:Dirty#a has the name 'a' (UncommunicativeMethodName)
26
+ smelly/dirty_two.rb -- 3 warnings:
27
+ [1]:Dirty has no descriptive comment (IrresponsibleModule)
28
+ [2]:Dirty#a has the name 'a' (UncommunicativeMethodName)
29
+ [3]:Dirty#b has the name 'b' (UncommunicativeMethodName)
30
+ 5 total warnings
31
+ """
40
32
 
41
33
  Scenario: Output total number of smells even if total equals 0
42
- When I run reek spec/samples/three_clean_files
34
+ Given a directory called 'clean_files' containing some clean files
35
+ When I run reek clean_files
43
36
  Then it succeeds
44
37
  And it reports:
45
- """
46
- 0 total warnings
47
- """
38
+ """
39
+ 0 total warnings
40
+ """
@@ -18,7 +18,7 @@ Feature: Reek reads from $stdin when no files are given
18
18
  Then it succeeds
19
19
  And it reports:
20
20
  """
21
- $stdin -- 0 warnings
21
+ STDIN -- 0 warnings
22
22
  """
23
23
 
24
24
  Scenario: return non-zero status when there are smells
@@ -26,7 +26,7 @@ Feature: Reek reads from $stdin when no files are given
26
26
  Then the exit status indicates smells
27
27
  And it reports:
28
28
  """
29
- $stdin -- 3 warnings:
29
+ STDIN -- 3 warnings:
30
30
  [1]:Turn has no descriptive comment (IrresponsibleModule)
31
31
  [1]:Turn has the variable name '@x' (UncommunicativeVariableName)
32
32
  [1]:Turn#y has the name 'y' (UncommunicativeMethodName)
@@ -4,69 +4,58 @@ Feature: Masking smells using config files
4
4
  I want to mask some smells using config files
5
5
 
6
6
  Scenario: empty config file is ignored
7
- When I run reek -c spec/samples/empty_config_file/empty.reek spec/samples/empty_config_file/dirty.rb
7
+ Given a smelly file called 'smelly.rb'
8
+ And an empty configuration file called 'empty.reek'
9
+ When I run reek -c empty.reek smelly.rb
8
10
  Then it reports the error 'Warning: Invalid configuration file "empty.reek" -- Empty file'
9
11
  And the exit status indicates smells
10
12
  And it reports:
11
13
  """
12
- spec/samples/empty_config_file/dirty.rb -- 6 warnings:
13
- [5]:Dirty has the variable name '@s' (UncommunicativeVariableName)
14
- [4, 6]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
15
- [4, 6]:Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
16
- [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
17
- [3]:Dirty#a has the name 'a' (UncommunicativeMethodName)
18
- [5]:Dirty#a has the variable name 'x' (UncommunicativeVariableName)
14
+ smelly.rb -- 3 warnings:
15
+ [4, 5]:Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
16
+ [4, 5]:Smelly#m calls puts(@foo.bar) 2 times (DuplicateMethodCall)
17
+ [3]:Smelly#m has the name 'm' (UncommunicativeMethodName)
19
18
  """
20
19
 
21
20
  Scenario: corrupt config file prevents normal output
22
- When I run reek -c spec/samples/corrupt_config_file/corrupt.reek spec/samples/corrupt_config_file
21
+ Given a smelly file called 'smelly.rb'
22
+ And a corrupt configuration file called 'corrupt.reek'
23
+ When I run reek -c corrupt.reek smelly.rb
23
24
  Then it reports the error 'Error: Invalid configuration file "corrupt.reek" -- Not a hash'
24
25
  And the exit status indicates an error
25
26
  And it reports nothing
26
27
 
27
28
  Scenario: missing source file is an error
28
- When I run reek spec/samples/missing_source_file/dirty.rb
29
- Then it reports the error "Error: No such file - spec/samples/missing_source_file/dirty.rb"
30
-
31
- Scenario: switch off one smell
32
- When I run reek -c spec/samples/masked/masked.reek spec/samples/masked/dirty.rb
33
- Then the exit status indicates smells
34
- And it reports:
35
- """
36
- spec/samples/masked/dirty.rb -- 3 warnings:
37
- [4, 6]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
38
- [4, 6]:Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
39
- [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
40
- """
29
+ When I run reek not_here.rb
30
+ Then it reports the error "Error: No such file - not_here.rb"
41
31
 
42
- Scenario: non-masked smells are only counted once
43
- When I run reek -c spec/samples/not_quite_masked/masked.reek spec/samples/not_quite_masked/dirty.rb
44
- Then the exit status indicates smells
45
- And it reports:
46
- """
47
- spec/samples/not_quite_masked/dirty.rb -- 5 warnings:
48
- [5]:Dirty has the variable name '@s' (UncommunicativeVariableName)
49
- [4, 6]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
50
- [4, 6]:Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
51
- [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
52
- [3]:Dirty#a has the name 'a' (UncommunicativeMethodName)
53
- """
32
+ Scenario: masking smells in the configuration file
33
+ Given a smelly file called 'smelly.rb'
34
+ And a masking configuration file called 'config.reek'
35
+ When I run reek -c config.reek smelly.rb
36
+ Then it succeeds
37
+ And it reports nothing
54
38
 
55
39
  Scenario: allow masking some calls for duplication smell
56
- When I run reek -c spec/samples/mask_some/some.reek spec/samples/mask_some/dirty.rb
40
+ Given a smelly file called 'smelly.rb'
41
+ And a configuration file masking some duplication smells called 'config.reek'
42
+ When I run reek -c config.reek smelly.rb
57
43
  Then the exit status indicates smells
58
44
  And it reports:
59
45
  """
60
- spec/samples/mask_some/dirty.rb -- 2 warnings:
61
- [4, 6]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
62
- [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
46
+ smelly.rb -- 2 warnings:
47
+ [4, 5]:Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
48
+ [3]:Smelly#m has the name 'm' (UncommunicativeMethodName)
63
49
  """
64
50
 
65
51
  Scenario: provide extra masking inline in comments
66
- When I run reek -c spec/samples/inline_config/masked.reek spec/samples/inline_config
52
+ Given a smelly file with inline masking called 'inline.rb'
53
+ And a masking configuration file called 'config.reek'
54
+ When I run reek -c config.reek inline.rb
67
55
  Then the exit status indicates smells
68
56
  And it reports:
69
57
  """
70
- spec/samples/inline_config/dirty.rb -- 1 warning:
71
- [5, 7]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
58
+ inline.rb -- 2 warnings:
59
+ [5]:Dirty has the variable name '@s' (UncommunicativeVariableName)
60
+ [5]:Dirty#a has the variable name 'x' (UncommunicativeVariableName)
72
61
  """
@@ -3,11 +3,13 @@ Feature: Overriding current rules by specifying new configuration values
3
3
  As a developer
4
4
  I want to be able to override the default configuration values
5
5
 
6
- Scenario: List of configuration values is overridden by a lower config file
7
- When I run reek -c spec/samples/overrides_defaults/config.reek spec/samples/overrides_defaults/camel_case.rb
6
+ Scenario: List of configuration values is overridden by a lower configuration file
7
+ Given a file with smelly variable names called 'camel_case.rb'
8
+ And a configuration file allowing camel case variables
9
+ When I run reek camel_case.rb
8
10
  Then the exit status indicates smells
9
11
  And it reports:
10
12
  """
11
- spec/samples/overrides_defaults/camel_case.rb -- 1 warning:
13
+ camel_case.rb -- 1 warning:
12
14
  [9]:CamelCase#initialize has the variable name 'x1' (UncommunicativeVariableName)
13
15
  """
@@ -11,52 +11,55 @@ Feature: Offer different ways how to load configuration
11
11
  And finally, it should check your HOME directory.
12
12
 
13
13
  Scenario: No configuration
14
- When I run reek spec/samples/configuration_loading/minimal_dirty.rb
14
+ Given a smelly file called 'smelly.rb'
15
+ When I run reek smelly.rb
15
16
  Then the exit status indicates smells
16
17
  And it reports:
17
18
  """
18
- spec/samples/configuration_loading/minimal_dirty.rb -- 3 warnings:
19
- [1]:C has no descriptive comment (IrresponsibleModule)
20
- [1]:C has the name 'C' (UncommunicativeModuleName)
21
- [2]:C#m has the name 'm' (UncommunicativeMethodName)
19
+ smelly.rb -- 3 warnings:
20
+ [4, 5]:Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
21
+ [4, 5]:Smelly#m calls puts(@foo.bar) 2 times (DuplicateMethodCall)
22
+ [3]:Smelly#m has the name 'm' (UncommunicativeMethodName)
22
23
  """
23
24
 
24
25
  Scenario: Configuration via CLI
25
- When I run reek -c spec/samples/minimal_smelly_and_masked/config.reek spec/samples/minimal_smelly_and_masked/minimal_dirty.rb
26
+ Given a smelly file called 'smelly.rb'
27
+ And a masking configuration file called 'config.reek'
28
+ When I run reek -c config.reek smelly.rb
26
29
  Then it reports no errors
27
30
  And it succeeds
28
31
 
29
- @remove-disable-smell-config-from-current-dir
30
32
  Scenario: Configuration file in working directory
31
- Given "spec/samples/configuration_loading/reek-test-run-disable_smells.reek" exists in the working directory
32
- When I run reek spec/samples/configuration_loading/minimal_dirty.rb
33
+ Given a smelly file called 'smelly.rb'
34
+ And a masking configuration file called 'config.reek'
35
+ When I run reek smelly.rb
33
36
  Then it reports no errors
34
37
  And it succeeds
35
38
 
36
- @remove-disable-smell-config-from-parent-dir
37
39
  Scenario: Configuration file in the parent directory of the working directory
38
- Given "spec/samples/configuration_loading/reek-test-run-disable_smells.reek" exists in the parent directory of the working directory
39
- When I run reek spec/samples/configuration_loading/minimal_dirty.rb
40
+ Given a smelly file called 'smelly.rb' in a subdirectory
41
+ And a masking configuration file called 'config.reek'
42
+ When I run "reek smelly.rb" in the subdirectory
40
43
  Then it reports no errors
41
44
  And it succeeds
42
45
 
43
- @remove-disable-smell-config-from-home-dir
44
46
  Scenario: Configuration file in the HOME directory
45
- Given "spec/samples/configuration_loading/reek-test-run-disable_smells.reek" exists in the HOME directory
46
- When I run reek spec/samples/configuration_loading/minimal_dirty.rb
47
+ Given a smelly file called 'smelly.rb'
48
+ And a masking configuration file in the HOME directory
49
+ When I run reek smelly.rb
47
50
  Then it reports no errors
48
51
  And it succeeds
49
52
 
50
- @remove-enable-smell-config-from-current-dir @remove-disable-smell-config-from-parent-dir
51
53
  Scenario: Two opposing configuration files and we stop after the first one
52
- Given "spec/samples/configuration_loading/reek-test-run-enable_smells.reek" exists in the working directory
53
- And "spec/samples/configuration_loading/reek-test-run-disable_smells.reek" exists in the parent directory of the working directory
54
- When I run reek spec/samples/configuration_loading/minimal_dirty.rb
54
+ Given a smelly file called 'smelly.rb' in a subdirectory
55
+ And an enabling configuration file in the subdirectory
56
+ And a masking configuration file called 'config.reek'
57
+ When I run "reek smelly.rb" in the subdirectory
55
58
  Then the exit status indicates smells
56
59
  And it reports:
57
60
  """
58
- spec/samples/configuration_loading/minimal_dirty.rb -- 3 warnings:
59
- [1]:C has no descriptive comment (IrresponsibleModule)
60
- [1]:C has the name 'C' (UncommunicativeModuleName)
61
- [2]:C#m has the name 'm' (UncommunicativeMethodName)
61
+ smelly.rb -- 3 warnings:
62
+ [4, 5]:Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
63
+ [4, 5]:Smelly#m calls puts(@foo.bar) 2 times (DuplicateMethodCall)
64
+ [3]:Smelly#m has the name 'm' (UncommunicativeMethodName)
62
65
  """
@@ -0,0 +1,43 @@
1
+ Feature: Using reek programmatically
2
+ In order to use reek from inside my program
3
+ As a developer
4
+ I want to be able to use its classes
5
+
6
+ Scenario: Accessing smells found by an examiner
7
+ Given a smelly file called 'smelly.rb'
8
+ And a file named "examine.rb" with:
9
+ """
10
+ require 'reek'
11
+ examiner = Reek::Examiner.new(File.new('smelly.rb'))
12
+ examiner.smells.each do |smell|
13
+ puts smell.message
14
+ end
15
+ """
16
+ When I run `ruby examine.rb`
17
+ Then it reports no errors
18
+ And it reports:
19
+ """
20
+ calls @foo.bar 2 times
21
+ calls puts(@foo.bar) 2 times
22
+ has the name 'm'
23
+ """
24
+
25
+ Scenario: Using reek's built-in report classes
26
+ Given a smelly file called 'smelly.rb'
27
+ And a file named "examine.rb" with:
28
+ """
29
+ require 'reek'
30
+ examiner = Reek::Examiner.new(File.new('smelly.rb'))
31
+ report = Reek::Report::TextReport.new
32
+ report.add_examiner examiner
33
+ report.show
34
+ """
35
+ When I run `ruby examine.rb`
36
+ Then it reports no errors
37
+ And it reports:
38
+ """
39
+ smelly.rb -- 3 warnings:
40
+ Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
41
+ Smelly#m calls puts(@foo.bar) 2 times (DuplicateMethodCall)
42
+ Smelly#m has the name 'm' (UncommunicativeMethodName)
43
+ """
@@ -3,56 +3,60 @@ Feature: Reek can be driven through its Task
3
3
  via the Task class. These scenarios test its various options.
4
4
 
5
5
  Scenario: source_files points at the desired files
6
+ Given a smelly file called 'smelly.rb'
6
7
  When I run rake reek with:
7
8
  """
8
9
  Reek::Rake::Task.new do |t|
9
- t.source_files = 'spec/samples/standard_smelly/minimal_dirty.rb'
10
+ t.source_files = 'smelly.rb'
10
11
  t.reek_opts = '--no-color'
11
12
  end
12
13
  """
13
14
  Then the exit status indicates an error
14
15
  And it reports:
15
16
  """
16
- spec/samples/standard_smelly/minimal_dirty.rb -- 3 warnings:
17
- [1]:C has no descriptive comment (IrresponsibleModule)
18
- [1]:C has the name 'C' (UncommunicativeModuleName)
19
- [2]:C#m has the name 'm' (UncommunicativeMethodName)
17
+ smelly.rb -- 3 warnings:
18
+ [4, 5]:Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
19
+ [4, 5]:Smelly#m calls puts(@foo.bar) 2 times (DuplicateMethodCall)
20
+ [3]:Smelly#m has the name 'm' (UncommunicativeMethodName)
20
21
  """
21
22
 
22
23
  Scenario: name changes the task name
24
+ Given a smelly file called 'smelly.rb'
23
25
  When I run rake silky with:
24
26
  """
25
27
  Reek::Rake::Task.new('silky') do |t|
26
- t.source_files = 'spec/samples/standard_smelly/minimal_dirty.rb'
28
+ t.source_files = 'smelly.rb'
27
29
  t.reek_opts = '--no-color'
28
30
  end
29
31
  """
30
32
  Then the exit status indicates an error
31
33
  And it reports:
32
34
  """
33
- spec/samples/standard_smelly/minimal_dirty.rb -- 3 warnings:
34
- [1]:C has no descriptive comment (IrresponsibleModule)
35
- [1]:C has the name 'C' (UncommunicativeModuleName)
36
- [2]:C#m has the name 'm' (UncommunicativeMethodName)
35
+ smelly.rb -- 3 warnings:
36
+ [4, 5]:Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
37
+ [4, 5]:Smelly#m calls puts(@foo.bar) 2 times (DuplicateMethodCall)
38
+ [3]:Smelly#m has the name 'm' (UncommunicativeMethodName)
37
39
  """
38
40
 
39
41
  Scenario: verbose prints the reek command
42
+ Given a smelly file called 'smelly.rb'
40
43
  When I run rake reek with:
41
44
  """
42
45
  Reek::Rake::Task.new do |t|
43
- t.source_files = 'spec/samples/masked/dirty.rb'
46
+ t.source_files = 'smelly.rb'
44
47
  t.verbose = true
45
48
  end
46
49
  """
47
50
  Then the exit status indicates an error
48
- And stdout includes "spec/samples/masked/dirty.rb"
51
+ And stdout includes "Running 'reek' rake command"
49
52
 
50
53
  Scenario: fail_on_error can hide the error status
54
+ Given a smelly file called 'smelly.rb'
51
55
  When I run rake reek with:
52
56
  """
53
57
  Reek::Rake::Task.new do |t|
54
58
  t.fail_on_error = false
55
- t.source_files = 'spec/samples/no_config_file/dirty.rb'
59
+ t.source_files = 'smelly.rb'
56
60
  t.reek_opts = '--no-color'
57
61
  end
58
62
  """
@@ -60,21 +64,20 @@ Feature: Reek can be driven through its Task
60
64
  And it succeeds
61
65
  And it reports:
62
66
  """
63
- spec/samples/no_config_file/dirty.rb -- 6 warnings:
64
- [5]:Dirty has the variable name '@s' (UncommunicativeVariableName)
65
- [4, 6]:Dirty#a calls @s.title 2 times (DuplicateMethodCall)
66
- [4, 6]:Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
67
- [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
68
- [3]:Dirty#a has the name 'a' (UncommunicativeMethodName)
69
- [5]:Dirty#a has the variable name 'x' (UncommunicativeVariableName)
67
+ smelly.rb -- 3 warnings:
68
+ [4, 5]:Smelly#m calls @foo.bar 2 times (DuplicateMethodCall)
69
+ [4, 5]:Smelly#m calls puts(@foo.bar) 2 times (DuplicateMethodCall)
70
+ [3]:Smelly#m has the name 'm' (UncommunicativeMethodName)
70
71
  """
71
72
 
72
73
  Scenario: can be configured with config_file
74
+ Given a smelly file called 'smelly.rb'
75
+ And a masking configuration file called 'config.reek'
73
76
  When I run rake reek with:
74
77
  """
75
78
  Reek::Rake::Task.new do |t|
76
- t.config_file = 'spec/samples/minimal_smelly_and_masked/config.reek'
77
- t.source_files = 'spec/samples/minimal_smelly_and_masked/minimal_dirty.rb'
79
+ t.config_file = 'config.reek'
80
+ t.source_files = 'smelly.rb'
78
81
  end
79
82
  """
80
83
  Then it succeeds
@@ -3,7 +3,8 @@ Feature: Report smells using simple JSON layout
3
3
  output a list of smells in JSON.
4
4
 
5
5
  Scenario: output is empty when there are no smells
6
- When I run reek --format json spec/samples/three_clean_files
6
+ Given a directory called 'clean_files' containing some clean files
7
+ When I run reek --format json clean_files
7
8
  Then it succeeds
8
9
  And it reports this JSON:
9
10
  """
@@ -11,41 +12,38 @@ Feature: Report smells using simple JSON layout
11
12
  """
12
13
 
13
14
  Scenario: Indicate smells and print them as JSON when using files
14
- When I run reek --format json spec/samples/standard_smelly/minimal_dirty.rb
15
+ Given a smelly file called 'smelly.rb'
16
+ When I run reek --format json smelly.rb
15
17
  Then the exit status indicates smells
16
18
  And it reports this JSON:
17
19
  """
18
20
  [
19
21
  {
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
- ],
27
- "message": "has no descriptive comment",
28
- "name": "C"
22
+ "smell_category": "Duplication",
23
+ "smell_type": "DuplicateMethodCall",
24
+ "source": "smelly.rb",
25
+ "context": "Smelly#m",
26
+ "lines": [ 4, 5 ],
27
+ "message": "calls @foo.bar 2 times",
28
+ "name": "@foo.bar",
29
+ "count": 2
29
30
  },
30
31
  {
31
- "smell_category": "UncommunicativeName",
32
- "smell_type": "UncommunicativeModuleName",
33
- "source": "spec/samples/standard_smelly/minimal_dirty.rb",
34
- "context": "C",
35
- "lines": [
36
- 1
37
- ],
38
- "message": "has the name 'C'",
39
- "name": "C"
32
+ "smell_category": "Duplication",
33
+ "smell_type": "DuplicateMethodCall",
34
+ "source": "smelly.rb",
35
+ "context": "Smelly#m",
36
+ "lines": [ 4, 5 ],
37
+ "message": "calls puts(@foo.bar) 2 times",
38
+ "name": "puts(@foo.bar)",
39
+ "count": 2
40
40
  },
41
41
  {
42
42
  "smell_category": "UncommunicativeName",
43
43
  "smell_type": "UncommunicativeMethodName",
44
- "source": "spec/samples/standard_smelly/minimal_dirty.rb",
45
- "context": "C#m",
46
- "lines": [
47
- 2
48
- ],
44
+ "source": "smelly.rb",
45
+ "context": "Smelly#m",
46
+ "lines": [ 3 ],
49
47
  "message": "has the name 'm'",
50
48
  "name": "m"
51
49
  }
@@ -61,7 +59,7 @@ Feature: Report smells using simple JSON layout
61
59
  {
62
60
  "smell_category": "IrresponsibleModule",
63
61
  "smell_type": "IrresponsibleModule",
64
- "source": "$stdin",
62
+ "source": "STDIN",
65
63
  "context": "Turn",
66
64
  "lines": [
67
65
  1