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,92 +0,0 @@
1
- # Missing Safe Method
2
-
3
- ## Introduction
4
-
5
- Candidate methods for the _Missing Safe Method_ smell are methods whose names
6
- end with an exclamation mark.
7
-
8
- An exclamation mark in method names means (the explanation below is taken from
9
- [here](http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist)):
10
-
11
- > The ! in method names that end with ! means, “This method is dangerous”—or,
12
- > more precisely, this method is the “dangerous” version of an otherwise
13
- > equivalent method, with the same name minus the !. “Danger” is relative; the
14
- > ! doesn’t mean anything at all unless the method name it’s in corresponds to
15
- > a similar but bang-less method name.
16
- >
17
- > So, for example, gsub! is the dangerous version of gsub. exit! is the
18
- > dangerous version of exit. flatten! is the dangerous version of flatten. And
19
- > so forth.
20
-
21
- Such a method is called _Missing Safe Method_ if and only if the non-bang
22
- version does not exist and this method is reported as a smell.
23
-
24
- Missing Safe Method was formerly known as Prima Donna Method.
25
-
26
- ## Example
27
-
28
- Given
29
-
30
- ```Ruby
31
- class C
32
- def foo; end
33
- def foo!; end
34
- def bar!; end
35
- end
36
- ```
37
-
38
- Reek would report the _Missing Safe Method_ smell for `bar!`, but not for `foo!`.
39
-
40
- Reek reports this smell only in a class context, not in a module context in order to allow perfectly legit code like this:
41
-
42
-
43
- ```Ruby
44
- class Parent
45
- def foo; end
46
- end
47
-
48
- module Dangerous
49
- def foo!; end
50
- end
51
-
52
- class Son < Parent
53
- include Dangerous
54
- end
55
-
56
- class Daughter < Parent
57
- end
58
- ```
59
-
60
- In this example, Reek would not report the _Missing Safe Method_ smell for the
61
- method `foo` of the `Dangerous` module.
62
-
63
- ## Configuration
64
-
65
- _Missing Safe Method_ offers the [Basic Smell Options](Basic-Smell-Options.md).
66
-
67
- ## Example configuration via source comment
68
-
69
- Imagine code like this:
70
-
71
- ```Ruby
72
- class Alfa
73
- def bravo!
74
- end
75
- end
76
- ```
77
-
78
- This would report:
79
-
80
- >>
81
- ruby.rb -- 1 warning:
82
- [1]:MissingSafeMethod: Alfa has missing safe method 'bravo!'
83
-
84
- If you want to suppress this warning you can do this via source comment like this:
85
-
86
- ```Ruby
87
- # :reek:MissingSafeMethod { exclude: [ bravo! ] }
88
- class Alfa
89
- def bravo!
90
- end
91
- end
92
- ```
@@ -1,62 +0,0 @@
1
- # Module Initialize
2
-
3
- ## Introduction
4
-
5
- A module is usually a mixin, so when an `#initialize` method is present it is
6
- hard to tell initialization order and parameters so having `#initialize`
7
- in a module is usually a bad idea.
8
-
9
- ## Example
10
-
11
- The `Foo` module below contains a method `initialize`. Although class `B` inherits from `A`, the inclusion of `Foo` stops `A#initialize` from being called.
12
-
13
- ```Ruby
14
- class A
15
- def initialize(a)
16
- @a = a
17
- end
18
- end
19
-
20
- module Foo
21
- def initialize(foo)
22
- @foo = foo
23
- end
24
- end
25
-
26
- class B < A
27
- include Foo
28
-
29
- def initialize(b)
30
- super('bar')
31
- @b = b
32
- end
33
- end
34
- ```
35
-
36
- A simple solution is to rename `Foo#initialize` and call that method by name:
37
-
38
- ```Ruby
39
- module Foo
40
- def setup_foo_module(foo)
41
- @foo = foo
42
- end
43
- end
44
-
45
- class B < A
46
- include Foo
47
-
48
- def initialize(b)
49
- super 'bar'
50
- setup_foo_module('foo')
51
- @b = b
52
- end
53
- end
54
- ```
55
-
56
- ## Current Support in Reek
57
-
58
- Reek warns about module initialize when an instance method named `initialize` is present in a module.
59
-
60
- ## Configuration
61
-
62
- Module Initialize supports the [Basic Smell Options](Basic-Smell-Options.md).
@@ -1,59 +0,0 @@
1
- # Nested Iterators
2
-
3
- ## Introduction
4
-
5
- A _Nested Iterator_ occurs when a block contains another block.
6
-
7
- ## Example
8
-
9
- Given
10
-
11
- ```Ruby
12
- class Duck
13
- class << self
14
- def duck_names
15
- %i!tick trick track!.each do |surname|
16
- %i!duck!.each do |last_name|
17
- puts "full name is #{surname} #{last_name}"
18
- end
19
- end
20
- end
21
- end
22
- end
23
- ```
24
-
25
- Reek would report the following warning:
26
-
27
- ```
28
- test.rb -- 1 warning:
29
- [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)
30
- ```
31
-
32
- ## Current Support in Reek
33
-
34
- _Nested Iterators_ reports failing methods only once.
35
- `Object#tap` is ignored by default and thus does not count as iterator.
36
- Furthermore iterators without block arguments are not counted, e.g.:
37
-
38
-
39
- ```Ruby
40
- def foo
41
- before do
42
- item.each do |part|
43
- puts part
44
- end
45
- end
46
- end
47
- ```
48
-
49
- would not smell of NestedIterators (given a maximum allowed nesting of 1) since the
50
- `before` would not be counted (because it doesn't pass any arguments to the block).
51
-
52
- ## Configuration
53
-
54
- _Nested Iterators_ offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
55
-
56
- | Option | Value | Effect |
57
- | ----------------------|---------|---------|
58
- | `max_allowed_nesting` | integer | The maximum depth of nested iterators. Defaults to 1 |
59
- | `ignore_iterators` | Array | List of iterators to be excluded from the smell check. Includes only `tap` at the moment|
data/docs/Nil-Check.md DELETED
@@ -1,47 +0,0 @@
1
- # Nil Check
2
-
3
- ## Introduction
4
-
5
- A _Nil Check_ is a type check. Failures of _Nil Check_ violate the
6
- ["tell, don't ask"](http://robots.thoughtbot.com/tell-dont-ask) principle.
7
- Additionally to that, type checks often mask bigger problems in your source
8
- code like not using OOP and / or polymorphism when you should.
9
-
10
- The _Nil Check_ code smell is a case of [Simulated Polymorphism](Simulated-Polymorphism.md).
11
-
12
- ## Example
13
-
14
- Given
15
-
16
- ```Ruby
17
- class Klass
18
- def nil_checker(argument)
19
- if argument.nil?
20
- puts "argument is nil!"
21
- end
22
- end
23
- end
24
- ```
25
-
26
- Reek would emit the following warning:
27
-
28
- ```
29
- test.rb -- 1 warning:
30
- [3]:Klass#nil_checker performs a nil-check. (NilCheck)
31
- ```
32
-
33
- ## Current Support in Reek
34
-
35
- _Nil Check_ reports use of
36
-
37
- * <code>.nil?</code> method
38
- * <code>==</code> and <code>===</code> operators when checking vs. <code>nil</code>
39
- * case statements that use syntax like <code>when nil</code>
40
-
41
- _Nil Check_ allows use of
42
-
43
- * the safe navigation operator like `foo&.bar`
44
-
45
- ## Configuration
46
-
47
- _Nil Check_ offers the [Basic Smell Options](Basic-Smell-Options.md).
@@ -1,129 +0,0 @@
1
- # RSpec matchers
2
-
3
- ## Introduction
4
-
5
- Reek offers matchers for RSpec you can easily include into your project.
6
-
7
- There are 3 matchers available:
8
-
9
- - `reek`
10
- - `reek_of`
11
- - `reek_only_of`
12
-
13
- ## Quickstart
14
-
15
- Let's install the dependencies:
16
-
17
- ```
18
- gem install reek
19
- gem install rspec
20
- ```
21
-
22
- And then use it like that in your spec file:
23
-
24
- ```Ruby
25
- require 'reek'
26
- require 'reek/spec'
27
- require 'rspec'
28
-
29
- RSpec.describe 'Reek Integration' do
30
- it 'works with Reek' do
31
- smelly_class = 'class C; def m; end; end'
32
- expect(smelly_class).not_to reek
33
- end
34
- end
35
- ```
36
-
37
- Running this via
38
-
39
- ```
40
- rspec reek-integration-spec.rb
41
- ```
42
-
43
- would give you:
44
-
45
- ```
46
- Failures:
47
-
48
- 1) Reek Integration works with Reek
49
- Failure/Error: expect(smelly_class).not_to reek
50
- Expected no smells, but got:
51
- C has no descriptive comment (IrresponsibleModule)
52
- C has the name 'C' (UncommunicativeModuleName)
53
- C#m has the name 'm' (UncommunicativeMethodName)
54
- # ./reek-integration-spec.rb:8:in `block (2 levels) in <top (required)>'
55
-
56
- Finished in 0.00284 seconds (files took 0.28815 seconds to load)
57
- 1 example, 1 failure
58
-
59
- Failed examples:
60
-
61
- rspec ./reek-integration-spec.rb:6 # Reek Integration works with Reek
62
- ```
63
-
64
- ## The matchers explained
65
-
66
- ### `reek`
67
-
68
- A very generic matcher that basically just tells you if something reeks, but
69
- not after what exactly.
70
- See the "Quickstart" example from above.
71
-
72
- ### `reek_of`
73
-
74
- Checks the target source code for instances of "smell type"
75
- and returns true only if it can find one of them that matches.
76
-
77
- You can pass the smell type you want to check for as String or as Symbol:
78
-
79
- - `:UtilityFunction`
80
- - `"UtilityFunction"`
81
-
82
- It is recommended to pass this as a symbol like `:UtilityFunction`. However we
83
- don't enforce this.
84
-
85
- Additionally you can be more specific and pass in "smell_details" you want to
86
- check for as well e.g. "name" or "count" (see the examples below). The
87
- parameters you can check for are depending on the smell you are checking for.
88
- For instance "count" doesn't make sense everywhere whereas "name" does in most
89
- cases. If you pass in a parameter that doesn't exist (e.g. you make a typo like
90
- "namme") Reek will raise an ArgumentError to give you a hint that you passed
91
- something that doesn't make much sense.
92
-
93
- So in a nutshell `reek_of` takes the following two arguments:
94
-
95
- - `smell_type` - The "smell type" we check for.
96
- - `smells_details` - A hash containing "smell warning" parameters
97
-
98
- **Examples**
99
-
100
- Without smell_details:
101
-
102
- ```Ruby
103
- reek_of(:FeatureEnvy)
104
- reek_of(:UtilityFunction)
105
- ```
106
-
107
- With smell_details:
108
-
109
- ```Ruby
110
- reek_of(:UncommunicativeParameterName, name: 'x2')
111
- reek_of(:DataClump, count: 3)
112
- ```
113
-
114
- **Examples from a real spec**
115
-
116
- ```Ruby
117
- expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing')
118
- ```
119
-
120
- ### reek_only_of
121
-
122
- See the documentaton for `reek_of`.
123
-
124
- **Notable differences to `reek_of`:**
125
-
126
- 1. `reek_of` doesn't mind if there are other smells of a different type.
127
- "reek_only_of" will fail in that case.
128
-
129
- 2. `reek_only_of` doesn't support the additional smell_details hash.
data/docs/Rake-Task.md DELETED
@@ -1,66 +0,0 @@
1
- # Rake Task
2
-
3
- ## Introduction
4
-
5
- Reek provides a Rake task that runs Reek on a set of source files. In its most simple form you just include something like that in your Rakefile:
6
-
7
- ```Ruby
8
- require 'reek/rake/task'
9
-
10
- Reek::Rake::Task.new do |t|
11
- t.fail_on_error = false
12
- end
13
- ```
14
-
15
- In its most simple form, that's it.
16
-
17
- When you now run:
18
-
19
- ```Bash
20
- rake -T
21
- ```
22
-
23
- you should see
24
-
25
- ```Bash
26
- rake reek # Check for code smells
27
- ```
28
-
29
- ## Configuration via task
30
-
31
- An more sophisticated rake task that would make use of all available configuration options could look like this:
32
-
33
- ```Ruby
34
- Reek::Rake::Task.new do |t|
35
- t.name = 'custom_rake' # Whatever name you want. Defaults to "reek".
36
- t.config_file = 'config/.reek.yml' # Defaults to nothing.
37
- t.source_files = 'vendor/**/*.rb' # Glob pattern to match source files. Defaults to lib/**/*.rb
38
- t.reek_opts = '-U' # Defaults to ''. You can pass all the options here in that are shown by "reek -h"
39
- t.fail_on_error = false # Defaults to true
40
- t.verbose = true # Defaults to false
41
- end
42
- ```
43
-
44
- Alternatively, you can create your own [Rake::FileList](http://rake.rubyforge.org/classes/Rake/FileList.html) and use that for `source_files`:
45
-
46
- ```Ruby
47
- Reek::Rake::Task.new do |t|
48
- t.source_files = FileList['lib/**/*.rb'].exclude('lib/templates/**/*.rb')
49
- end
50
- ```
51
-
52
- ## Configuration via environment variables
53
-
54
- You can overwrite the following attributes by environment variables:
55
-
56
- - "reek_opts" by using REEK_OPTS
57
- - "config_file" by using REEK_CFG
58
- - "source_files" by using REEK_SRC
59
-
60
- An example rake call using environment variables could look like this:
61
-
62
- ```Bash
63
- REEK_CFG="config/custom.reek" REEK_OPTS="-s" rake reek
64
- ```
65
-
66
- See also: [Reek-Driven-Development](Reek-Driven-Development.md)
@@ -1,188 +0,0 @@
1
- ## Reek 4 to Reek 5 migration
2
-
3
- ### Schema validation
4
-
5
- Reek now uses a schema to validate your configuration against on start up and will faily loudly in
6
- case you misspelled an option or used the wrong data type for a value like this:
7
-
8
- ```
9
- Error: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.
10
- ```
11
-
12
- Obviously this might affect existing configuration files that until now contained an error nobody noticed.
13
-
14
- ### Scoping detectors under `detectors`
15
-
16
- In Reek 4 you could just configure your detectors on top level like this:
17
-
18
- ```yaml
19
- UncommunicativeMethodName:
20
- accept:
21
- - foobar
22
- UnusedPrivateMethod:
23
- exclude:
24
- - app/controllers
25
- ```
26
-
27
- In Reek 5 you have to scope your detector configurations under the `detectors` key:
28
-
29
- ```yaml
30
- detectors:
31
- UncommunicativeMethodName:
32
- accept:
33
- - foobar
34
- UnusedPrivateMethod:
35
- exclude:
36
- - app/controllers
37
- ```
38
-
39
- ### Move directory directives under a special key
40
-
41
- In Reek 4 you could apply directory specific directives like this:
42
-
43
- ```Yaml
44
- ---
45
- "web_app/app/controllers":
46
- NestedIterators:
47
- enabled: false
48
- "web_app/app/helpers":
49
- UtilityFunction:
50
- enabled: false
51
- ```
52
-
53
- which was nice and easy but also quite messy. With Reek 5 you'll have to scope this under a `directories`
54
- key like this:
55
-
56
- ```Yaml
57
- ---
58
- directories:
59
- "web_app/app/controllers":
60
- NestedIterators:
61
- enabled: false
62
- "web_app/app/helpers":
63
- UtilityFunction:
64
- enabled: false
65
- ```
66
-
67
- ### No more regular expressions in Reeks configuration
68
-
69
- In Reek 4 you could pass regular expressions to the `accept` or `reject` settings of
70
-
71
- * [Uncommunicative Method Name](Uncommunicative-Method-Name.md)
72
- * [Uncommunicative Module Name](Uncommunicative-Module-Name.md)
73
- * [Uncommunicative Parameter Name](Uncommunicative-Parameter-Name.md)
74
- * [Uncommunicative Variable Name](Uncommunicative-Variable-Name.md)
75
-
76
- and to the `exclude` settings which are part of our [Basic Smell Options](docs/Basic-Smell-Options.md).
77
-
78
- This means that this configuration was perfectly valid:
79
-
80
- ```yaml
81
- detectors:
82
- UncommunicativeMethodName:
83
- accept:
84
- - !ruby/regexp /foobar/
85
- UnusedPrivateMethod:
86
- exclude:
87
- - !ruby/regexp /i am(.*)unused/
88
- ```
89
-
90
- Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
91
- You can still pass in regexes, you just have to wrap them into a string using a forward slash at the
92
- beginning and at the end of the string like this:
93
-
94
- ```Yaml
95
- ---
96
- UncommunicativeMethodName:
97
- accept:
98
- - "/^foobar$/"
99
- UnusedPrivateMethod:
100
- exclude:
101
- - "/i am(.*)unused/"
102
- ```
103
-
104
- Everything within the forward slashes will be loaded as a regex.
105
-
106
- ### No more single item shortcuts for list items
107
-
108
- You cant use a configuration option that is supposed to be a list with a single element like this anymore:
109
-
110
- ```Yaml
111
- ---
112
- UncommunicativeMethodName:
113
- accept: foobar
114
- UnusedPrivateMethod:
115
- exclude: omg
116
- ```
117
-
118
- You'll have to use a proper list here like this:
119
-
120
- ```Yaml
121
- ---
122
- UncommunicativeMethodName:
123
- accept:
124
- - foobar
125
- UnusedPrivateMethod:
126
- exclude:
127
- - omg
128
- ```
129
-
130
- ## Failing on syntax errors in source files
131
-
132
- Previously Reek would just continue on syntax errors in source files which might have been convenient but
133
- not necessarily fitting for a tool that's all about code quality. With Reek 5, Reek will fail hard on
134
- invalid source files.
135
-
136
- ### API changes
137
-
138
- This is something that will only affect very advanced users. In case you have no idea what this might be about
139
- you can just skip it or check out our [Developer API](docs/API.md).
140
-
141
- #### Allow only detector names in configuration hash
142
-
143
- In Reek 4 you could build your configuration like this:
144
-
145
- ```ruby
146
- config_hash = { Reek::SmellDetectors::IrresponsibleModule => { 'enabled' => false } }
147
- ```
148
-
149
- or like this:
150
-
151
- ```ruby
152
- config_hash = { 'IrresponsibleModule' => { 'enabled' => false } }
153
- ```
154
-
155
- Starting with Reek 5, the first way is not working anymore and the latter one is what you'll have to use.
156
-
157
- #### Do not accept a class as parameter for reek_of
158
-
159
- In the same vein as the change above you also can't use fully qualified detector names like this:
160
-
161
- ```Ruby
162
- reek_of(Reek::SmellDetectors::DuplicateMethodCall)
163
- ```
164
-
165
- The only supported way now is either as symbol or string:
166
-
167
- ```Ruby
168
- reek_of(:DuplicateMethodCall)
169
- reek_of('DuplicateMethodCall')
170
- ```
171
-
172
- ## Smaller changes
173
-
174
- * `PrimaDonnaMethod` has been given the better name `MissingSafeMethod`
175
- * `wiki-links` flag has been renamed to `documentation` flag
176
- * Reek assumes the default configuration file to be named ".reek.yml" and will ignore all other files. You can
177
- still use any name you want though by passing in a name via the `-c` flag
178
- * We have dropped the legacy code comment separator `:` at the end of a detector name. Before this release,
179
- to configure a smell detector via comment, you had to end with a colon after the detector name.
180
- This syntax is disallowed with Reek 5 - now you have to drop the `:` at the end, like this:
181
-
182
- ```diff
183
- -# :reek:UnusedPrivateMethod: { exclude: [ bravo ] }
184
- +# :reek:UnusedPrivateMethod { exclude: [ bravo ] }
185
- ```
186
-
187
- * We have dropped support for Ruby 2.1 and 2.2 since they are officially not supported by the Ruby core team anymore
188
-
@@ -1,46 +0,0 @@
1
- # Reek-Driven Development
2
-
3
- One way to drive quality into your code from the very beginning of a project is to run Reek as a part of your testing process.
4
-
5
- ## Rake: `Reek::Rake::Task`
6
-
7
- You can add a [Rake Task] to your Rakefile, which will run Reek on all your source files.
8
-
9
- ```Ruby
10
- require 'reek/rake/task'
11
-
12
- Reek::Rake::Task.new do |t|
13
- t.fail_on_error = true
14
- t.verbose = false
15
- t.source_files = 'lib/**/*.rb'
16
- end
17
- ```
18
-
19
- Now, `rake reek` will run Reek on your source code. And, in this case, it fails if it finds any smells.
20
-
21
- For more detailed information about Reek's integration with Rake, see [Rake Task].
22
-
23
- [Rake Task]: Rake-Task.md
24
-
25
- ## RSpec: `reek/spec`
26
-
27
- You can add Reek expectations directly into your RSpec specs.
28
-
29
- This example is from Reek's own source code:
30
-
31
- ```Ruby
32
- require 'reek/spec'
33
-
34
- it 'contains no code smells' do
35
- Pathname.glob('lib/**/*.rb').each do |file|
36
- expect(file).not_to reek
37
- end
38
- end
39
- ```
40
-
41
- By requiring [`reek/spec`] you gain access to the `reek` matcher.
42
-
43
- The `reek` matcher returns true if and only if Reek finds smells in your code. If the test fails, the matcher produces an error message that includes details of all the smells it found.
44
-
45
- [`reek/spec`]: ../lib/reek/spec.rb
46
-