reek 6.0.2 → 6.2.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 (271) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +13 -0
  3. data/.github/workflows/ruby.yml +57 -0
  4. data/.rubocop.yml +6 -12
  5. data/.rubocop_todo.yml +6 -4
  6. data/CHANGELOG.md +95 -0
  7. data/CONTRIBUTING.md +10 -10
  8. data/Dockerfile +1 -1
  9. data/Gemfile +8 -7
  10. data/README.md +29 -29
  11. data/bin/code_climate_reek +56 -8
  12. data/lib/reek/ast/ast_node_class_map.rb +1 -1
  13. data/lib/reek/ast/node.rb +1 -1
  14. data/lib/reek/ast/sexp_extensions/arguments.rb +20 -0
  15. data/lib/reek/ast/sexp_extensions/case.rb +1 -1
  16. data/lib/reek/ast/sexp_extensions/if.rb +1 -1
  17. data/lib/reek/ast/sexp_extensions/send.rb +22 -7
  18. data/lib/reek/cli/command/todo_list_command.rb +3 -3
  19. data/lib/reek/cli/options.rb +6 -6
  20. data/lib/reek/{report/code_climate → code_climate}/code_climate_configuration.rb +1 -1
  21. data/lib/reek/{report/code_climate → code_climate}/code_climate_configuration.yml +41 -41
  22. data/lib/reek/{report/code_climate → code_climate}/code_climate_fingerprint.rb +2 -2
  23. data/lib/reek/{report/code_climate → code_climate}/code_climate_formatter.rb +2 -4
  24. data/lib/reek/{report/code_climate → code_climate}/code_climate_report.rb +3 -3
  25. data/lib/reek/code_comment.rb +25 -20
  26. data/lib/reek/configuration/app_configuration.rb +5 -5
  27. data/lib/reek/configuration/configuration_converter.rb +1 -1
  28. data/lib/reek/configuration/configuration_file_finder.rb +5 -4
  29. data/lib/reek/configuration/default_directive.rb +1 -1
  30. data/lib/reek/configuration/directory_directives.rb +1 -1
  31. data/lib/reek/configuration/excluded_paths.rb +3 -2
  32. data/lib/reek/configuration/schema.rb +177 -0
  33. data/lib/reek/configuration/schema_validator.rb +12 -13
  34. data/lib/reek/context/attribute_context.rb +1 -1
  35. data/lib/reek/context/code_context.rb +1 -1
  36. data/lib/reek/context/method_context.rb +1 -1
  37. data/lib/reek/context/module_context.rb +4 -0
  38. data/lib/reek/context/refinement_context.rb +16 -0
  39. data/lib/reek/context/send_context.rb +7 -1
  40. data/lib/reek/context_builder.rb +17 -3
  41. data/lib/reek/documentation_link.rb +3 -5
  42. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +2 -2
  43. data/lib/reek/errors/bad_detector_in_comment_error.rb +2 -2
  44. data/lib/reek/errors/encoding_error.rb +1 -1
  45. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +2 -2
  46. data/lib/reek/errors/incomprehensible_source_error.rb +1 -1
  47. data/lib/reek/errors/legacy_comment_separator_error.rb +2 -2
  48. data/lib/reek/errors/syntax_error.rb +1 -1
  49. data/lib/reek/rake/task.rb +5 -5
  50. data/lib/reek/smell_detectors/base_detector.rb +1 -1
  51. data/lib/reek/smell_detectors/class_variable.rb +2 -2
  52. data/lib/reek/smell_detectors/control_parameter_helpers/candidate.rb +6 -6
  53. data/lib/reek/smell_detectors/control_parameter_helpers/control_parameter_finder.rb +1 -1
  54. data/lib/reek/smell_detectors/duplicate_method_call.rb +5 -5
  55. data/lib/reek/smell_detectors/instance_variable_assumption.rb +8 -8
  56. data/lib/reek/smell_detectors/nested_iterators.rb +4 -3
  57. data/lib/reek/smell_detectors/unused_private_method.rb +3 -2
  58. data/lib/reek/smell_warning.rb +1 -1
  59. data/lib/reek/source/source_locator.rb +1 -3
  60. data/lib/reek/spec/should_reek_of.rb +11 -9
  61. data/lib/reek/spec.rb +1 -1
  62. data/lib/reek/version.rb +2 -2
  63. data/reek.gemspec +29 -25
  64. metadata +37 -250
  65. data/.travis.yml +0 -40
  66. data/docs/API.md +0 -174
  67. data/docs/Attribute.md +0 -39
  68. data/docs/Basic-Smell-Options.md +0 -85
  69. data/docs/Boolean-Parameter.md +0 -54
  70. data/docs/Class-Variable.md +0 -40
  71. data/docs/Code-Smells.md +0 -39
  72. data/docs/Command-Line-Options.md +0 -119
  73. data/docs/Control-Couple.md +0 -26
  74. data/docs/Control-Parameter.md +0 -32
  75. data/docs/Data-Clump.md +0 -46
  76. data/docs/Duplicate-Method-Call.md +0 -264
  77. data/docs/Feature-Envy.md +0 -93
  78. data/docs/How-To-Write-New-Detectors.md +0 -132
  79. data/docs/How-reek-works-internally.md +0 -114
  80. data/docs/Instance-Variable-Assumption.md +0 -163
  81. data/docs/Irresponsible-Module.md +0 -47
  82. data/docs/Large-Class.md +0 -16
  83. data/docs/Long-Parameter-List.md +0 -39
  84. data/docs/Long-Yield-List.md +0 -37
  85. data/docs/Manual-Dispatch.md +0 -30
  86. data/docs/Missing-Safe-Method.md +0 -92
  87. data/docs/Module-Initialize.md +0 -62
  88. data/docs/Nested-Iterators.md +0 -59
  89. data/docs/Nil-Check.md +0 -47
  90. data/docs/RSpec-matchers.md +0 -129
  91. data/docs/Rake-Task.md +0 -66
  92. data/docs/Reek-4-to-Reek-5-migration.md +0 -188
  93. data/docs/Reek-Driven-Development.md +0 -46
  94. data/docs/Repeated-Conditional.md +0 -47
  95. data/docs/Simulated-Polymorphism.md +0 -16
  96. data/docs/Smell-Suppression.md +0 -96
  97. data/docs/Style-Guide.md +0 -19
  98. data/docs/Subclassed-From-Core-Class.md +0 -79
  99. data/docs/Too-Many-Constants.md +0 -37
  100. data/docs/Too-Many-Instance-Variables.md +0 -43
  101. data/docs/Too-Many-Methods.md +0 -56
  102. data/docs/Too-Many-Statements.md +0 -54
  103. data/docs/Uncommunicative-Method-Name.md +0 -94
  104. data/docs/Uncommunicative-Module-Name.md +0 -92
  105. data/docs/Uncommunicative-Name.md +0 -18
  106. data/docs/Uncommunicative-Parameter-Name.md +0 -90
  107. data/docs/Uncommunicative-Variable-Name.md +0 -96
  108. data/docs/Unused-Parameters.md +0 -28
  109. data/docs/Unused-Private-Method.md +0 -101
  110. data/docs/Utility-Function.md +0 -56
  111. data/docs/Versioning-Policy.md +0 -7
  112. data/docs/YAML-Reports.md +0 -93
  113. data/docs/defaults.reek.yml +0 -129
  114. data/docs/templates/default/docstring/html/public_api_marker.erb +0 -3
  115. data/docs/templates/default/docstring/setup.rb +0 -37
  116. data/docs/templates/default/fulldoc/html/css/common.css +0 -1
  117. data/docs/yard_plugin.rb +0 -17
  118. data/features/command_line_interface/basic_usage.feature +0 -15
  119. data/features/command_line_interface/options.feature +0 -123
  120. data/features/command_line_interface/show_progress.feature +0 -33
  121. data/features/command_line_interface/smell_selection.feature +0 -15
  122. data/features/command_line_interface/smells_count.feature +0 -38
  123. data/features/command_line_interface/stdin.feature +0 -65
  124. data/features/configuration_files/accept_setting.feature +0 -87
  125. data/features/configuration_files/directory_specific_directives.feature +0 -274
  126. data/features/configuration_files/exclude_directives.feature +0 -35
  127. data/features/configuration_files/exclude_paths_directives.feature +0 -42
  128. data/features/configuration_files/masking_smells.feature +0 -94
  129. data/features/configuration_files/mix_accept_reject_setting.feature +0 -84
  130. data/features/configuration_files/reject_setting.feature +0 -89
  131. data/features/configuration_files/schema_validation.feature +0 -59
  132. data/features/configuration_files/show_configuration_file.feature +0 -44
  133. data/features/configuration_files/unused_private_method.feature +0 -68
  134. data/features/configuration_loading.feature +0 -91
  135. data/features/configuration_via_source_comments/erroneous_source_comments.feature +0 -68
  136. data/features/configuration_via_source_comments/well_formed_source_comments.feature +0 -116
  137. data/features/locales.feature +0 -32
  138. data/features/programmatic_access.feature +0 -41
  139. data/features/rake_task/rake_task.feature +0 -138
  140. data/features/reports/codeclimate.feature +0 -59
  141. data/features/reports/json.feature +0 -59
  142. data/features/reports/reports.feature +0 -219
  143. data/features/reports/yaml.feature +0 -52
  144. data/features/rspec_matcher.feature +0 -41
  145. data/features/samples.feature +0 -305
  146. data/features/step_definitions/.rubocop.yml +0 -5
  147. data/features/step_definitions/reek_steps.rb +0 -102
  148. data/features/step_definitions/sample_file_steps.rb +0 -63
  149. data/features/support/env.rb +0 -33
  150. data/features/todo_list.feature +0 -108
  151. data/lib/reek/configuration/schema.yml +0 -210
  152. data/samples/checkstyle.xml +0 -7
  153. data/samples/clean_source/clean.rb +0 -6
  154. data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +0 -29
  155. data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +0 -30
  156. data/samples/configuration/corrupt.reek +0 -1
  157. data/samples/configuration/empty.reek +0 -0
  158. data/samples/configuration/full_configuration.reek +0 -13
  159. data/samples/configuration/full_mask.reek +0 -6
  160. data/samples/configuration/home/home.reek.yml +0 -4
  161. data/samples/configuration/partial_mask.reek +0 -4
  162. data/samples/configuration/regular_configuration/.reek.yml +0 -4
  163. data/samples/configuration/regular_configuration/empty_sub_directory/.gitignore +0 -0
  164. data/samples/configuration/with_excluded_paths.reek +0 -5
  165. data/samples/no_config_file/.keep +0 -0
  166. data/samples/paths.rb +0 -5
  167. data/samples/smelly_source/inline.rb +0 -704
  168. data/samples/smelly_source/optparse.rb +0 -1788
  169. data/samples/smelly_source/redcloth.rb +0 -1130
  170. data/samples/smelly_source/ruby.rb +0 -368
  171. data/samples/smelly_source/smelly.rb +0 -7
  172. data/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +0 -5
  173. data/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +0 -2
  174. data/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +0 -6
  175. data/samples/source_with_exclude_paths/nested/uncommunicative_variable_name.rb +0 -6
  176. data/samples/source_with_hidden_directories/.hidden/hidden.rb +0 -1
  177. data/samples/source_with_hidden_directories/not_hidden.rb +0 -1
  178. data/samples/source_with_non_ruby_files/gibberish +0 -1
  179. data/samples/source_with_non_ruby_files/python_source.py +0 -1
  180. data/samples/source_with_non_ruby_files/ruby.rb +0 -6
  181. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +0 -15
  182. data/spec/quality/documentation_spec.rb +0 -41
  183. data/spec/quality/reek_source_spec.rb +0 -11
  184. data/spec/reek/ast/node_spec.rb +0 -211
  185. data/spec/reek/ast/object_refs_spec.rb +0 -83
  186. data/spec/reek/ast/reference_collector_spec.rb +0 -47
  187. data/spec/reek/ast/sexp_extensions_spec.rb +0 -498
  188. data/spec/reek/cli/application_spec.rb +0 -168
  189. data/spec/reek/cli/command/report_command_spec.rb +0 -44
  190. data/spec/reek/cli/command/todo_list_command_spec.rb +0 -86
  191. data/spec/reek/cli/options_spec.rb +0 -51
  192. data/spec/reek/cli/silencer_spec.rb +0 -28
  193. data/spec/reek/code_comment_spec.rb +0 -184
  194. data/spec/reek/configuration/app_configuration_spec.rb +0 -195
  195. data/spec/reek/configuration/configuration_file_finder_spec.rb +0 -230
  196. data/spec/reek/configuration/default_directive_spec.rb +0 -13
  197. data/spec/reek/configuration/directory_directives_spec.rb +0 -122
  198. data/spec/reek/configuration/excluded_paths_spec.rb +0 -16
  199. data/spec/reek/configuration/rake_task_converter_spec.rb +0 -33
  200. data/spec/reek/configuration/schema_validator_spec.rb +0 -165
  201. data/spec/reek/context/code_context_spec.rb +0 -192
  202. data/spec/reek/context/ghost_context_spec.rb +0 -60
  203. data/spec/reek/context/method_context_spec.rb +0 -72
  204. data/spec/reek/context/module_context_spec.rb +0 -55
  205. data/spec/reek/context/root_context_spec.rb +0 -12
  206. data/spec/reek/context/statement_counter_spec.rb +0 -24
  207. data/spec/reek/context_builder_spec.rb +0 -457
  208. data/spec/reek/detector_repository_spec.rb +0 -22
  209. data/spec/reek/documentation_link_spec.rb +0 -20
  210. data/spec/reek/errors/base_error_spec.rb +0 -13
  211. data/spec/reek/examiner_spec.rb +0 -309
  212. data/spec/reek/logging_error_handler_spec.rb +0 -24
  213. data/spec/reek/rake/task_spec.rb +0 -56
  214. data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +0 -22
  215. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +0 -126
  216. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +0 -51
  217. data/spec/reek/report/code_climate/code_climate_report_spec.rb +0 -56
  218. data/spec/reek/report/html_report_spec.rb +0 -19
  219. data/spec/reek/report/json_report_spec.rb +0 -58
  220. data/spec/reek/report/location_formatter_spec.rb +0 -32
  221. data/spec/reek/report/progress_formatter_spec.rb +0 -68
  222. data/spec/reek/report/text_report_spec.rb +0 -89
  223. data/spec/reek/report/xml_report_spec.rb +0 -24
  224. data/spec/reek/report/yaml_report_spec.rb +0 -55
  225. data/spec/reek/report_spec.rb +0 -28
  226. data/spec/reek/smell_configuration_spec.rb +0 -56
  227. data/spec/reek/smell_detectors/attribute_spec.rb +0 -197
  228. data/spec/reek/smell_detectors/base_detector_spec.rb +0 -50
  229. data/spec/reek/smell_detectors/boolean_parameter_spec.rb +0 -93
  230. data/spec/reek/smell_detectors/class_variable_spec.rb +0 -106
  231. data/spec/reek/smell_detectors/control_parameter_spec.rb +0 -300
  232. data/spec/reek/smell_detectors/data_clump_spec.rb +0 -134
  233. data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +0 -211
  234. data/spec/reek/smell_detectors/feature_envy_spec.rb +0 -295
  235. data/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +0 -96
  236. data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -226
  237. data/spec/reek/smell_detectors/long_parameter_list_spec.rb +0 -61
  238. data/spec/reek/smell_detectors/long_yield_list_spec.rb +0 -49
  239. data/spec/reek/smell_detectors/manual_dispatch_spec.rb +0 -75
  240. data/spec/reek/smell_detectors/missing_safe_method_spec.rb +0 -68
  241. data/spec/reek/smell_detectors/module_initialize_spec.rb +0 -77
  242. data/spec/reek/smell_detectors/nested_iterators_spec.rb +0 -333
  243. data/spec/reek/smell_detectors/nil_check_spec.rb +0 -100
  244. data/spec/reek/smell_detectors/repeated_conditional_spec.rb +0 -100
  245. data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -77
  246. data/spec/reek/smell_detectors/too_many_constants_spec.rb +0 -144
  247. data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +0 -132
  248. data/spec/reek/smell_detectors/too_many_methods_spec.rb +0 -54
  249. data/spec/reek/smell_detectors/too_many_statements_spec.rb +0 -90
  250. data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +0 -78
  251. data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +0 -78
  252. data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +0 -147
  253. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +0 -201
  254. data/spec/reek/smell_detectors/unused_parameters_spec.rb +0 -114
  255. data/spec/reek/smell_detectors/unused_private_method_spec.rb +0 -205
  256. data/spec/reek/smell_detectors/utility_function_spec.rb +0 -293
  257. data/spec/reek/smell_warning_spec.rb +0 -137
  258. data/spec/reek/source/source_code_spec.rb +0 -79
  259. data/spec/reek/source/source_locator_spec.rb +0 -166
  260. data/spec/reek/spec/should_reek_of_spec.rb +0 -153
  261. data/spec/reek/spec/should_reek_only_of_spec.rb +0 -91
  262. data/spec/reek/spec/should_reek_spec.rb +0 -52
  263. data/spec/reek/spec/smell_matcher_spec.rb +0 -87
  264. data/spec/reek/tree_dresser_spec.rb +0 -46
  265. data/spec/spec_helper.rb +0 -110
  266. data/tasks/configuration.rake +0 -18
  267. data/tasks/console.rake +0 -5
  268. data/tasks/reek.rake +0 -6
  269. data/tasks/rubocop.rake +0 -11
  270. data/tasks/test.rake +0 -32
  271. /data/lib/reek/{report/code_climate.rb → code_climate.rb} +0 -0
@@ -1,47 +0,0 @@
1
- # Repeated Conditional
2
-
3
- ## Introduction
4
-
5
- _Repeated Conditional_ is a case of
6
- [Simulated Polymorphism](Simulated-Polymorphism.md). Basically it means you are
7
- checking the same value throughout a single class and take decisions based on
8
- this.
9
-
10
- ## Example
11
-
12
- Given
13
-
14
- ```Ruby
15
- class RepeatedConditionals
16
- attr_accessor :switch
17
-
18
- def repeat_1
19
- puts "Repeat 1!" if switch
20
- end
21
-
22
- def repeat_2
23
- puts "Repeat 2!" if switch
24
- end
25
-
26
- def repeat_3
27
- puts "Repeat 3!" if switch
28
- end
29
- end
30
- ```
31
-
32
- Reek would emit the following warning:
33
-
34
- ```
35
- test.rb -- 4 warnings:
36
- [5, 9, 13]:RepeatedConditionals tests switch at least 3 times (RepeatedConditional)
37
- ```
38
-
39
- If you get this warning then you are probably not using the right abstraction or even more probable, missing an additional abstraction.
40
-
41
- ## Configuration
42
-
43
- Reek's _Repeated Conditional_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
44
-
45
- | Option | Value | Effect |
46
- | ---------------|-------------|---------|
47
- | `max_ifs` | integer | The maximum number of identical conditional tests permitted before Reek raises a warning. Defaults to 2. |
@@ -1,16 +0,0 @@
1
- # Simulated Polymorphism
2
-
3
- ## Introduction
4
-
5
- Simulated Polymorphism occurs when
6
-
7
- * code uses a case statement (especially on a type field);
8
- * or code has several if statements in a row (especially if they're comparing against the same value);
9
- * or code uses instance_of?, kind_of?, is_a?, or === to decide what type it's working with;
10
- * or multiple conditionals in different places test the same value.
11
-
12
- Conditional code is hard to read and understand, because the reader must hold more state in their head. When the same value is tested in multiple places throughout an application, any change to the set of possible values will require many methods and classes to change. Tests for the type of an object may indicate that the abstraction represented by that type is not completely defined (or understood).
13
-
14
- ## Current Support in Reek
15
-
16
- Reek checks for [Manual Dispatch](Manual-Dispatch.md), [Repeated Conditional](Repeated-Conditional.md) and for [Nil Check](Nil-Check.md).
@@ -1,96 +0,0 @@
1
- ## Introduction
2
-
3
- In some cases, it might be necessary to suppress one or more of Reek's smell
4
- warnings for a particular method or class.
5
-
6
- Possible reasons for this could be:
7
-
8
- * The code is outside of your control and you can't fix it
9
- * Reek is not the police. You might have legit reasons why your source code
10
- is good as it is.
11
-
12
- ## How to disable smell detection
13
-
14
- There are always the [Basic Smell Options](Basic-Smell-Options.md)
15
- you can use in your configuration file.
16
-
17
- But in this document we would like to focus on a completely different
18
- way - via special comments.
19
-
20
- A simple example:
21
-
22
- ```ruby
23
- # This method smells of :reek:NestedIterators
24
- def smelly_method foo
25
- foo.each {|bar| bar.each {|baz| baz.qux}}
26
- end
27
- ```
28
-
29
- The method `smelly_method` will not be reported. The general pattern is to put
30
- the string ':reek:', followed by the smell class, in a comment before the
31
- method or class.
32
-
33
- ## Extended examples
34
-
35
- Multiple smells may be configured for the same method or class:
36
-
37
- ```ruby
38
- # :reek:LongParameterList and :reek:NestedIterators
39
- def many_parameters_it_has foo, bar, baz, qux
40
- foo.each {|bar| bar.each {|baz| baz.qux(qux)}}
41
- end
42
- ```
43
-
44
- Or across several lines which is arguably more readable:
45
-
46
- ```ruby
47
- # :reek:LongParameterList
48
- # :reek:NestedIterators
49
- def many_parameters_it_has foo, bar, baz, qux
50
- foo.each {|bar| bar.each {|baz| baz.qux(qux)}}
51
- end
52
- ```
53
-
54
- It is also possible to specify options for a particular smell detector in hash-style:
55
-
56
- ```ruby
57
- # :reek:LongParameterList { max_params: 4 }
58
- def many_parameters_it_has foo, bar, baz, qux
59
- # ...
60
- end
61
- ```
62
-
63
- Every configuration setting that you can pass via configuration file you can
64
- also use via comment.
65
-
66
- E.g.:
67
-
68
- ```ruby
69
- # :reek:TooManyStatements { max_statements: 6 }
70
- def too_many
71
- # ...
72
- end
73
-
74
- # :reek:NestedIterators { max_allowed_nesting: 2 }
75
- def quax
76
- foo.each {|bar| bar.each {|baz| baz.qux(qux)}}
77
- end
78
-
79
- # :reek:DuplicateMethodCall { max_calls: 3 }
80
- def quax
81
- foo.to_i + foo.to_i + foo.to_i
82
- end
83
- ```
84
-
85
- Keep in mind that there are also smell detectors that operate on a class or
86
- module level, e.g.:
87
-
88
- ```ruby
89
- # :reek:TooManyInstanceVariables { max_instance_variables: 8 }
90
- class Klass
91
- # ...
92
- end
93
- ```
94
-
95
- To see what smell detector takes what special configuration just check out the
96
- dedicated documentation for this smell detector.
data/docs/Style-Guide.md DELETED
@@ -1,19 +0,0 @@
1
- # Style guide
2
-
3
- ## Instance variables and getters / setters
4
-
5
- We use instance vars only:
6
-
7
- - in the constructor
8
- - for [memoization](http://gavinmiller.io/2013/basics-of-ruby-memoization/)
9
-
10
- For everything else we use proper getters / setters.
11
-
12
- If possible those should be private.
13
-
14
- ## Data types
15
-
16
- - Class or module names that are carried around in hashes and configuration and what
17
- not should be designated by constants. So `DuplicateMethodCall`, not `:DuplicateMethodCall` or `"DuplicateMethodCall"`
18
- - Hash keys should be all symbols unless they designate classes / modules - see above.
19
- - Everything else like messages or parameters in smell warnings should be strings, nothing else.
@@ -1,79 +0,0 @@
1
- # Subclassed From Core Class
2
-
3
- ## Introduction
4
-
5
- Candidate classes for the _Subclassed From Core Class_ smell are classes which inherit from Core Classes like Hash, String and Array.
6
-
7
- Inheriting from Core Classes means that you are going to have a bad time debugging (the explanation below is taken from [here](http://words.steveklabnik.com/beware-subclassing-ruby-core-classes)):
8
-
9
- > What do you think this code should do?
10
-
11
- ```Ruby
12
- List = Class.new(Array)
13
-
14
- l = List.new
15
- l << 1
16
- l << 2
17
- puts l.reverse.class # => Array
18
- ```
19
-
20
- > If you said “it prints Array” you’d be right.
21
- > Let’s talk about a more pernicious issue: Strings.
22
-
23
- ```Ruby
24
- class MyString < String
25
- def to_s
26
- "lol"
27
- end
28
- end
29
-
30
- s = MyString.new
31
- s.concat "Hey"
32
-
33
- puts s # => Hey
34
- puts s.to_s # => lol
35
- puts "#{s}" # => Hey
36
- ```
37
-
38
- > That’s right! With Strings, Ruby doesn’t call #to_s: it puts the value in directly.
39
- > Generally speaking, subclassing isn’t the right idea here.
40
-
41
- ## Example
42
-
43
- Given
44
-
45
- ```Ruby
46
- class Ary < Array
47
- end
48
-
49
- class Str < String
50
- end
51
- ```
52
-
53
- Reek would report the _Subclassed From Core Class_ smell for both classes. Instead of subclassing them you want a data structure that uses one of these core classes internally, but isn’t exactly like one. For instance:
54
-
55
- ```Ruby
56
- require 'forwardable'
57
-
58
- class List
59
- extend Forwardable
60
- def_delegators :@list, :<<, :length # and anything else
61
-
62
- def initialize(list = [])
63
- @list = list
64
- end
65
-
66
- def reverse
67
- List.new(@list.reverse)
68
- end
69
- end
70
-
71
- l = List.new
72
- l << 1
73
- l << 2
74
- puts l.reverse.class # => List
75
- ```
76
-
77
- ## Configuration
78
-
79
- _Subclassed From Core Class_ offers the [Basic Smell Options](Basic-Smell-Options.md).
@@ -1,37 +0,0 @@
1
- ## Introduction
2
-
3
- _Too Many Constants_ is a case of [Large Class](Large-Class.md).
4
-
5
- ## Example
6
-
7
- Given this configuration
8
-
9
- ```yaml
10
- TooManyConstants:
11
- max_constants: 3
12
- ```
13
-
14
- and this code:
15
-
16
- ```Ruby
17
- class Smelly
18
- CONST_1 = :dummy
19
- CONST_2 = :dummy
20
- CONST_3 = :dummy
21
- CONST_4 = :dummy
22
- end
23
- ```
24
-
25
- Reek would emit the following warning:
26
-
27
- ```
28
- test.rb -- 1 warning:
29
- [1]:TooManyConstants: Smelly has 4 constants
30
- ```
31
- ## Configuration
32
-
33
- Reek's _Too Many Constants_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
34
-
35
- | Option | Value | Effect |
36
- | -------------------------|---------|---------|
37
- | `max_constants` | integer | The maximum number of constants that are permitted. Defaults to 5 |
@@ -1,43 +0,0 @@
1
- ## Introduction
2
-
3
- _Too Many Instance Variables_ is a case of [Large Class](Large-Class.md).
4
-
5
- ## Example
6
-
7
- Given this configuration
8
-
9
- ```yaml
10
- TooManyInstanceVariables:
11
- max_instance_variables: 3
12
- ```
13
-
14
- and this code:
15
-
16
- ```Ruby
17
- class Smelly
18
- def initialize
19
- @arg_1 = :dummy
20
- @arg_2 = :dummy
21
- @arg_3 = :dummy
22
- @arg_4 = :dummy
23
- end
24
- end
25
- ```
26
-
27
- Reek would emit the following warning:
28
-
29
- ```
30
- test.rb -- 5 warnings:
31
- [1]:TooManyInstanceVariables: Smelly has at least 4 instance variables
32
- ```
33
- ## Current Support in Reek
34
-
35
- Reek only counts the instance variables you use explicitly like in the example above. Class macros like `attr_accessor` are disregarded.
36
-
37
- ## Configuration
38
-
39
- Reek's _Too Many Instance Variables_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
40
-
41
- | Option | Value | Effect |
42
- | -------------------------|---------|---------|
43
- | `max_instance_variables` | integer | The maximum number of instance variables that are permitted. Defaults to 4 |
@@ -1,56 +0,0 @@
1
- ## Introduction
2
-
3
- _Too Many Methods_ is a case of [Large Class](Large-Class.md).
4
-
5
- ## Example
6
-
7
- Given this configuration
8
-
9
- ```yaml
10
- TooManyMethods:
11
- max_methods: 3
12
- ```
13
-
14
- and this code:
15
-
16
- ```Ruby
17
- class Smelly
18
- def one; end
19
- def two; end
20
- def three; end
21
- def four; end
22
- end
23
- ```
24
-
25
- Reek would emit the following warning:
26
-
27
- ```
28
- test.rb -- 1 warning:
29
- [1]:TooManyMethods: Smelly has at least 4 methods
30
- ```
31
- ## Current Support in Reek
32
-
33
- Reek counts all the methods it can find in a class &mdash; instance *and* class
34
- methods. So given `max_methods` from above is 4, this:
35
-
36
- ```Ruby
37
- class Smelly
38
- class << self
39
- def one; end
40
- def two; end
41
- end
42
-
43
- def three; end
44
- def four; end
45
- end
46
- ```
47
-
48
- would cause Reek to emit the same warning as in the example above.
49
-
50
- ## Configuration
51
-
52
- Reek's _Too Many Methods_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
53
-
54
- | Option | Value | Effect |
55
- | --------------|---------|---------|
56
- | `max_methods` | integer | The maximum number of methods that are permitted. Defaults to 15 |
@@ -1,54 +0,0 @@
1
- # Too Many Statements
2
-
3
- ## Introduction
4
-
5
- A method with _Too Many Statements_ is any method that has a large number of lines.
6
-
7
- ## Current Support in Reek
8
-
9
- _Too Many Statements_ warns about any method that has more than 5 statements.
10
- Reek's smell detector for _Too Many Statements_ counts +1 for every simple
11
- statement in a method and +1 for every statement within a control structure
12
- (`if`, `else`, `case`, `when`, `for`, `while`, `until`, `begin`, `rescue`) but
13
- it doesn't count the control structure itself.
14
-
15
- So the following method would score +6 in Reek's statement-counting algorithm:
16
-
17
- ```Ruby
18
- def parse(arg, argv, &error)
19
- if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
20
- return nil, block, nil # +1
21
- end
22
- opt = (val = parse_arg(val, &error))[1] # +2
23
- val = conv_arg(*val) # +3
24
- if opt and !arg
25
- argv.shift # +4
26
- else
27
- val[0] = nil # +5
28
- end
29
- val # +6
30
- end
31
- ```
32
-
33
- (You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
34
-
35
- ## Configuration
36
-
37
- Reek's _Too Many Statements_ detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
38
-
39
- | Option | Value | Effect |
40
- | ---------------|-------------|---------|
41
- | `max_statements` | integer | The maximum number of statements allowed in a method before a warning is issued. Defaults to 5. |
42
-
43
- _Too Many Statements_'s default configuration is:
44
-
45
- ```yaml
46
- ---
47
- TooManyStatements:
48
- enabled: true
49
- exclude:
50
- - initialize
51
- max_statements: 5
52
- ```
53
-
54
- By default, `initialize` is not checked for length; any class's constructor can be as long as necessary.
@@ -1,94 +0,0 @@
1
- # Uncommunicative Method Name
2
-
3
- ## Introduction
4
-
5
- An _Uncommunicative Method Name_ is a method name that doesn't communicate its
6
- intent well enough. This code smell is a case of
7
- [Uncommunicative Name](Uncommunicative-Name.md).
8
-
9
- ## Current Support in Reek
10
-
11
- _Uncommunicative Method Name_ checks for:
12
-
13
- * single-character names
14
- * any name ending with a number
15
- * camelCaseMethodNames
16
-
17
- ## Configuration
18
-
19
- Reek's _Uncommunicative Method Name_ detector supports the
20
- [Basic Smell Options](Basic-Smell-Options.md), plus:
21
-
22
- | Option | Value | Effect |
23
- | ---------------|-------------|---------|
24
- | `reject` | array of strings | The set of names that Reek uses to check for bad names. Defaults to single-letter names, names ending with a number or names containing upper case letters. |
25
- | `accept` | array of strings | The set of names that Reek will accept (and not report) even if they match one of the `reject` expressions. |
26
-
27
- An example configuration could look like this:
28
-
29
- ```Yaml
30
- ---
31
- UncommunicativeMethodName:
32
- accept:
33
- - x
34
- - meth1
35
- reject:
36
- - helper
37
- - foobar
38
- ```
39
-
40
- Reek will convert whatever you give it as a string to the corresponding regex, so "foobar" from above will be converted to /foobar/ internally.
41
-
42
- Applying a configuration to a source file like this:
43
-
44
- ```Ruby
45
- def x; end # Should not be reported
46
- def meth1; end # Should not be reported
47
- def foobar; end # Should be reported
48
- def awesome_helper; end # Should be reported
49
- ```
50
-
51
- Reek would report:
52
-
53
- ```
54
- smelly.rb -- 2 warnings:
55
- [4]:UncommunicativeMethodName: awesome_helper has the name 'awesome_helper'
56
- [3]:UncommunicativeMethodName: foobar has the name 'foobar'
57
- ```
58
-
59
- ## Advanced configuration
60
-
61
- Sometimes just strings are not enough for configuration. E.g. consider this code sample:
62
-
63
- ```Ruby
64
- class Klass
65
- def foo; end
66
- def foobar; end;
67
- end
68
- ```
69
-
70
- and now imagine that you want to reject the name "foo" but not "foobar". This wouldn't be possible with just using strings.
71
- For this reason Reek has a special syntax that allows you to use regexes by using a forward slash at the beginning and the end of the string.
72
- Everything within the forward slashes will be loaded as a regex.
73
-
74
- A possible configuration that allows "foobar" but rejects "foo" could look like this:
75
-
76
- ```Yaml
77
- ---
78
- UncommunicativeMethodName:
79
- reject:
80
- - "/^foo$/"
81
- ```
82
-
83
- ## Reek 4
84
-
85
- In Reek 4 you could also pass regexes to `accept` or `reject`, meaning this was perfectly valid as well:
86
-
87
- ```yaml
88
- UncommunicativeMethodName:
89
- accept:
90
- - !ruby/regexp /foobar/
91
- ```
92
-
93
- Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
94
- You can still pass in regexes, you just have to wrap them into a string. Please see "Advanced configuration" above.
@@ -1,92 +0,0 @@
1
- # Uncommunicative Module Name
2
-
3
- ## Introduction
4
-
5
- An _Uncommunicative Module Name_ is a module name that doesn't communicate its
6
- intent well enough. This code smell is a case of
7
- [Uncommunicative Name](Uncommunicative-Name.md).
8
-
9
- ## Current Support in Reek
10
-
11
- _Uncommunicative Module Name_ checks for:
12
-
13
- * single-character names
14
- * any name ending with a number
15
-
16
- ## Configuration
17
-
18
- Reek's _Uncommunicative Module Name_ detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
19
-
20
- | Option | Value | Effect |
21
- | ---------------|-------------|---------|
22
- | `reject` | array of strings | The set of names that Reek uses to check for bad names. Defaults to single-letter names and names ending with a number. |
23
- | `accept` | array or strings | The set of names that Reek will accept (and not report) even if they match one of the `reject` expressions. Empty by default.|
24
-
25
- An example configuration could look like this:
26
-
27
- ```Yaml
28
- ---
29
- UncommunicativeModuleName:
30
- accept:
31
- - lassy
32
- - Util
33
- reject:
34
- - Helper
35
- ```
36
-
37
- Reek will convert whatever you give it as a string to the corresponding regex, so "Helper" from above will be converted to /Helper/ internally.
38
-
39
- Applying a configuration to a source file like this:
40
-
41
- ```Ruby
42
- class Classy1; end # Should not be reported
43
- class Util; end # Should not be reported
44
- class BaseHelper; end # Should be reported
45
- ```
46
-
47
- Reek would report:
48
-
49
- ```
50
- smelly.rb -- 1 warning:
51
- [3]:UncommunicativeModuleName: BaseHelper has the name 'BaseHelper'
52
- ```
53
-
54
- ## Advanced configuration
55
-
56
- Sometimes just strings are not enough for configuration. E.g. consider this code sample:
57
-
58
- ```Ruby
59
- class Klassy
60
- # ...
61
- end
62
-
63
- class KlassyModule
64
- # ...
65
- end
66
- ```
67
-
68
- and now imagine that you want to reject the name "Klassy" but not "KlassyModule". This wouldn't be possible with just using strings.
69
- For this reason Reek has a special syntax that allows you to use regexes by using a forward slash at the beginning and the end of the string.
70
- Everything within the forward slashes will be loaded as a regex.
71
-
72
- A possible configuration that allows "KlassyModule" but rejects "Klassy" could look like this:
73
-
74
- ```Yaml
75
- ---
76
- UncommunicativeModuleName:
77
- reject:
78
- - "/^Klassy$/"
79
- ```
80
-
81
- ## Reek 4
82
-
83
- In Reek 4 you could also pass regexes to `accept` or `reject`, meaning this was perfectly valid as well:
84
-
85
- ```yaml
86
- UncommunicativeModuleName:
87
- accept:
88
- - !ruby/regexp /foobar/
89
- ```
90
-
91
- Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
92
- You can still pass in regexes, you just have to wrap them into a string. Please see "Advanced configuration" above.
@@ -1,18 +0,0 @@
1
- # Uncommunicative Name
2
-
3
- ## Introduction
4
-
5
- An _Uncommunicative Name_ is a name that doesn't communicate its intent well enough.
6
-
7
- Poor names make it hard for the reader to build a mental picture of what's
8
- going on in the code. They can also be mis-interpreted; and they hurt the flow
9
- of reading, because the reader must slow down to interpret the names.
10
-
11
- ## Current Support in Reek
12
-
13
- Reek offers four checks in this category:
14
-
15
- * [Uncommunicative Method Name](Uncommunicative-Method-Name.md)
16
- * [Uncommunicative Module Name](Uncommunicative-Module-Name.md)
17
- * [Uncommunicative Parameter Name](Uncommunicative-Parameter-Name.md)
18
- * [Uncommunicative Variable Name](Uncommunicative-Variable-Name.md)