reek 6.0.2 → 6.5.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 (280) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +13 -0
  3. data/.github/workflows/ruby.yml +58 -0
  4. data/.gitignore +0 -1
  5. data/.rubocop.yml +7 -20
  6. data/.rubocop_todo.yml +6 -4
  7. data/.simplecov +2 -0
  8. data/CHANGELOG.md +114 -0
  9. data/CONTRIBUTING.md +10 -10
  10. data/Dockerfile +1 -1
  11. data/Gemfile +17 -24
  12. data/README.md +38 -40
  13. data/Rakefile +2 -0
  14. data/bin/code_climate_reek +56 -8
  15. data/docs/yard_plugin.rb +3 -1
  16. data/lib/reek/ast/ast_node_class_map.rb +1 -1
  17. data/lib/reek/ast/node.rb +16 -10
  18. data/lib/reek/ast/sexp_extensions/arguments.rb +20 -0
  19. data/lib/reek/ast/sexp_extensions/case.rb +1 -1
  20. data/lib/reek/ast/sexp_extensions/if.rb +1 -1
  21. data/lib/reek/ast/sexp_extensions/send.rb +22 -7
  22. data/lib/reek/cli/command/todo_list_command.rb +3 -3
  23. data/lib/reek/cli/options.rb +8 -8
  24. data/lib/reek/{report/code_climate → code_climate}/code_climate_configuration.rb +1 -1
  25. data/lib/reek/{report/code_climate → code_climate}/code_climate_configuration.yml +41 -41
  26. data/lib/reek/{report/code_climate → code_climate}/code_climate_fingerprint.rb +2 -2
  27. data/lib/reek/{report/code_climate → code_climate}/code_climate_formatter.rb +2 -4
  28. data/lib/reek/{report/code_climate → code_climate}/code_climate_report.rb +3 -3
  29. data/lib/reek/code_comment.rb +25 -20
  30. data/lib/reek/configuration/app_configuration.rb +5 -5
  31. data/lib/reek/configuration/configuration_converter.rb +1 -1
  32. data/lib/reek/configuration/configuration_file_finder.rb +5 -4
  33. data/lib/reek/configuration/default_directive.rb +1 -1
  34. data/lib/reek/configuration/directory_directives.rb +1 -1
  35. data/lib/reek/configuration/excluded_paths.rb +3 -2
  36. data/lib/reek/configuration/schema.rb +177 -0
  37. data/lib/reek/configuration/schema_validator.rb +12 -13
  38. data/lib/reek/context/attribute_context.rb +1 -1
  39. data/lib/reek/context/code_context.rb +3 -3
  40. data/lib/reek/context/method_context.rb +1 -1
  41. data/lib/reek/context/module_context.rb +4 -0
  42. data/lib/reek/context/refinement_context.rb +16 -0
  43. data/lib/reek/context/send_context.rb +7 -1
  44. data/lib/reek/context_builder.rb +17 -3
  45. data/lib/reek/documentation_link.rb +3 -5
  46. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +2 -2
  47. data/lib/reek/errors/bad_detector_in_comment_error.rb +2 -2
  48. data/lib/reek/errors/encoding_error.rb +1 -1
  49. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +2 -2
  50. data/lib/reek/errors/incomprehensible_source_error.rb +1 -1
  51. data/lib/reek/errors/legacy_comment_separator_error.rb +2 -2
  52. data/lib/reek/errors/syntax_error.rb +1 -1
  53. data/lib/reek/rake/task.rb +5 -5
  54. data/lib/reek/report/github_report.rb +55 -0
  55. data/lib/reek/report/text_report.rb +1 -1
  56. data/lib/reek/report.rb +7 -5
  57. data/lib/reek/smell_detectors/base_detector.rb +1 -1
  58. data/lib/reek/smell_detectors/class_variable.rb +2 -2
  59. data/lib/reek/smell_detectors/control_parameter_helpers/candidate.rb +6 -6
  60. data/lib/reek/smell_detectors/control_parameter_helpers/control_parameter_finder.rb +1 -1
  61. data/lib/reek/smell_detectors/data_clump.rb +1 -1
  62. data/lib/reek/smell_detectors/duplicate_method_call.rb +5 -5
  63. data/lib/reek/smell_detectors/instance_variable_assumption.rb +8 -8
  64. data/lib/reek/smell_detectors/nested_iterators.rb +4 -3
  65. data/lib/reek/smell_detectors/uncommunicative_module_name.rb +1 -1
  66. data/lib/reek/smell_detectors/unused_private_method.rb +3 -2
  67. data/lib/reek/smell_warning.rb +1 -1
  68. data/lib/reek/source/source_code.rb +11 -5
  69. data/lib/reek/source/source_locator.rb +1 -3
  70. data/lib/reek/spec/should_reek_of.rb +11 -9
  71. data/lib/reek/spec.rb +1 -1
  72. data/lib/reek/version.rb +2 -2
  73. data/reek.gemspec +33 -25
  74. metadata +41 -238
  75. data/.travis.yml +0 -40
  76. data/docs/API.md +0 -174
  77. data/docs/Attribute.md +0 -39
  78. data/docs/Basic-Smell-Options.md +0 -85
  79. data/docs/Boolean-Parameter.md +0 -54
  80. data/docs/Class-Variable.md +0 -40
  81. data/docs/Code-Smells.md +0 -39
  82. data/docs/Command-Line-Options.md +0 -119
  83. data/docs/Control-Couple.md +0 -26
  84. data/docs/Control-Parameter.md +0 -32
  85. data/docs/Data-Clump.md +0 -46
  86. data/docs/Duplicate-Method-Call.md +0 -264
  87. data/docs/Feature-Envy.md +0 -93
  88. data/docs/How-To-Write-New-Detectors.md +0 -132
  89. data/docs/How-reek-works-internally.md +0 -114
  90. data/docs/Instance-Variable-Assumption.md +0 -163
  91. data/docs/Irresponsible-Module.md +0 -47
  92. data/docs/Large-Class.md +0 -16
  93. data/docs/Long-Parameter-List.md +0 -39
  94. data/docs/Long-Yield-List.md +0 -37
  95. data/docs/Manual-Dispatch.md +0 -30
  96. data/docs/Missing-Safe-Method.md +0 -92
  97. data/docs/Module-Initialize.md +0 -62
  98. data/docs/Nested-Iterators.md +0 -59
  99. data/docs/Nil-Check.md +0 -47
  100. data/docs/RSpec-matchers.md +0 -129
  101. data/docs/Rake-Task.md +0 -66
  102. data/docs/Reek-4-to-Reek-5-migration.md +0 -188
  103. data/docs/Reek-Driven-Development.md +0 -46
  104. data/docs/Repeated-Conditional.md +0 -47
  105. data/docs/Simulated-Polymorphism.md +0 -16
  106. data/docs/Smell-Suppression.md +0 -96
  107. data/docs/Style-Guide.md +0 -19
  108. data/docs/Subclassed-From-Core-Class.md +0 -79
  109. data/docs/Too-Many-Constants.md +0 -37
  110. data/docs/Too-Many-Instance-Variables.md +0 -43
  111. data/docs/Too-Many-Methods.md +0 -56
  112. data/docs/Too-Many-Statements.md +0 -54
  113. data/docs/Uncommunicative-Method-Name.md +0 -94
  114. data/docs/Uncommunicative-Module-Name.md +0 -92
  115. data/docs/Uncommunicative-Name.md +0 -18
  116. data/docs/Uncommunicative-Parameter-Name.md +0 -90
  117. data/docs/Uncommunicative-Variable-Name.md +0 -96
  118. data/docs/Unused-Parameters.md +0 -28
  119. data/docs/Unused-Private-Method.md +0 -101
  120. data/docs/Utility-Function.md +0 -56
  121. data/docs/Versioning-Policy.md +0 -7
  122. data/docs/YAML-Reports.md +0 -93
  123. data/docs/defaults.reek.yml +0 -129
  124. data/docs/templates/default/docstring/html/public_api_marker.erb +0 -3
  125. data/docs/templates/default/docstring/setup.rb +0 -37
  126. data/docs/templates/default/fulldoc/html/css/common.css +0 -1
  127. data/features/command_line_interface/basic_usage.feature +0 -15
  128. data/features/command_line_interface/options.feature +0 -123
  129. data/features/command_line_interface/show_progress.feature +0 -33
  130. data/features/command_line_interface/smell_selection.feature +0 -15
  131. data/features/command_line_interface/smells_count.feature +0 -38
  132. data/features/command_line_interface/stdin.feature +0 -65
  133. data/features/configuration_files/accept_setting.feature +0 -87
  134. data/features/configuration_files/directory_specific_directives.feature +0 -274
  135. data/features/configuration_files/exclude_directives.feature +0 -35
  136. data/features/configuration_files/exclude_paths_directives.feature +0 -42
  137. data/features/configuration_files/masking_smells.feature +0 -94
  138. data/features/configuration_files/mix_accept_reject_setting.feature +0 -84
  139. data/features/configuration_files/reject_setting.feature +0 -89
  140. data/features/configuration_files/schema_validation.feature +0 -59
  141. data/features/configuration_files/show_configuration_file.feature +0 -44
  142. data/features/configuration_files/unused_private_method.feature +0 -68
  143. data/features/configuration_loading.feature +0 -91
  144. data/features/configuration_via_source_comments/erroneous_source_comments.feature +0 -68
  145. data/features/configuration_via_source_comments/well_formed_source_comments.feature +0 -116
  146. data/features/locales.feature +0 -32
  147. data/features/programmatic_access.feature +0 -41
  148. data/features/rake_task/rake_task.feature +0 -138
  149. data/features/reports/codeclimate.feature +0 -59
  150. data/features/reports/json.feature +0 -59
  151. data/features/reports/reports.feature +0 -219
  152. data/features/reports/yaml.feature +0 -52
  153. data/features/rspec_matcher.feature +0 -41
  154. data/features/samples.feature +0 -305
  155. data/features/step_definitions/.rubocop.yml +0 -5
  156. data/features/step_definitions/reek_steps.rb +0 -102
  157. data/features/step_definitions/sample_file_steps.rb +0 -63
  158. data/features/support/env.rb +0 -33
  159. data/features/todo_list.feature +0 -108
  160. data/lib/reek/configuration/schema.yml +0 -210
  161. data/samples/checkstyle.xml +0 -7
  162. data/samples/clean_source/clean.rb +0 -6
  163. data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +0 -29
  164. data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +0 -30
  165. data/samples/configuration/corrupt.reek +0 -1
  166. data/samples/configuration/empty.reek +0 -0
  167. data/samples/configuration/full_configuration.reek +0 -13
  168. data/samples/configuration/full_mask.reek +0 -6
  169. data/samples/configuration/home/home.reek.yml +0 -4
  170. data/samples/configuration/partial_mask.reek +0 -4
  171. data/samples/configuration/regular_configuration/.reek.yml +0 -4
  172. data/samples/configuration/regular_configuration/empty_sub_directory/.gitignore +0 -0
  173. data/samples/configuration/with_excluded_paths.reek +0 -5
  174. data/samples/no_config_file/.keep +0 -0
  175. data/samples/paths.rb +0 -5
  176. data/samples/smelly_source/inline.rb +0 -704
  177. data/samples/smelly_source/optparse.rb +0 -1788
  178. data/samples/smelly_source/redcloth.rb +0 -1130
  179. data/samples/smelly_source/ruby.rb +0 -368
  180. data/samples/smelly_source/smelly.rb +0 -7
  181. data/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +0 -5
  182. data/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +0 -2
  183. data/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +0 -6
  184. data/samples/source_with_exclude_paths/nested/uncommunicative_variable_name.rb +0 -6
  185. data/samples/source_with_hidden_directories/.hidden/hidden.rb +0 -1
  186. data/samples/source_with_hidden_directories/not_hidden.rb +0 -1
  187. data/samples/source_with_non_ruby_files/gibberish +0 -1
  188. data/samples/source_with_non_ruby_files/python_source.py +0 -1
  189. data/samples/source_with_non_ruby_files/ruby.rb +0 -6
  190. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +0 -15
  191. data/spec/quality/documentation_spec.rb +0 -41
  192. data/spec/quality/reek_source_spec.rb +0 -11
  193. data/spec/reek/ast/node_spec.rb +0 -211
  194. data/spec/reek/ast/object_refs_spec.rb +0 -83
  195. data/spec/reek/ast/reference_collector_spec.rb +0 -47
  196. data/spec/reek/ast/sexp_extensions_spec.rb +0 -498
  197. data/spec/reek/cli/application_spec.rb +0 -168
  198. data/spec/reek/cli/command/report_command_spec.rb +0 -44
  199. data/spec/reek/cli/command/todo_list_command_spec.rb +0 -86
  200. data/spec/reek/cli/options_spec.rb +0 -51
  201. data/spec/reek/cli/silencer_spec.rb +0 -28
  202. data/spec/reek/code_comment_spec.rb +0 -184
  203. data/spec/reek/configuration/app_configuration_spec.rb +0 -195
  204. data/spec/reek/configuration/configuration_file_finder_spec.rb +0 -230
  205. data/spec/reek/configuration/default_directive_spec.rb +0 -13
  206. data/spec/reek/configuration/directory_directives_spec.rb +0 -122
  207. data/spec/reek/configuration/excluded_paths_spec.rb +0 -16
  208. data/spec/reek/configuration/rake_task_converter_spec.rb +0 -33
  209. data/spec/reek/configuration/schema_validator_spec.rb +0 -165
  210. data/spec/reek/context/code_context_spec.rb +0 -192
  211. data/spec/reek/context/ghost_context_spec.rb +0 -60
  212. data/spec/reek/context/method_context_spec.rb +0 -72
  213. data/spec/reek/context/module_context_spec.rb +0 -55
  214. data/spec/reek/context/root_context_spec.rb +0 -12
  215. data/spec/reek/context/statement_counter_spec.rb +0 -24
  216. data/spec/reek/context_builder_spec.rb +0 -457
  217. data/spec/reek/detector_repository_spec.rb +0 -22
  218. data/spec/reek/documentation_link_spec.rb +0 -20
  219. data/spec/reek/errors/base_error_spec.rb +0 -13
  220. data/spec/reek/examiner_spec.rb +0 -309
  221. data/spec/reek/logging_error_handler_spec.rb +0 -24
  222. data/spec/reek/rake/task_spec.rb +0 -56
  223. data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +0 -22
  224. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +0 -126
  225. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +0 -51
  226. data/spec/reek/report/code_climate/code_climate_report_spec.rb +0 -56
  227. data/spec/reek/report/html_report_spec.rb +0 -19
  228. data/spec/reek/report/json_report_spec.rb +0 -58
  229. data/spec/reek/report/location_formatter_spec.rb +0 -32
  230. data/spec/reek/report/progress_formatter_spec.rb +0 -68
  231. data/spec/reek/report/text_report_spec.rb +0 -89
  232. data/spec/reek/report/xml_report_spec.rb +0 -24
  233. data/spec/reek/report/yaml_report_spec.rb +0 -55
  234. data/spec/reek/report_spec.rb +0 -28
  235. data/spec/reek/smell_configuration_spec.rb +0 -56
  236. data/spec/reek/smell_detectors/attribute_spec.rb +0 -197
  237. data/spec/reek/smell_detectors/base_detector_spec.rb +0 -50
  238. data/spec/reek/smell_detectors/boolean_parameter_spec.rb +0 -93
  239. data/spec/reek/smell_detectors/class_variable_spec.rb +0 -106
  240. data/spec/reek/smell_detectors/control_parameter_spec.rb +0 -300
  241. data/spec/reek/smell_detectors/data_clump_spec.rb +0 -134
  242. data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +0 -211
  243. data/spec/reek/smell_detectors/feature_envy_spec.rb +0 -295
  244. data/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +0 -96
  245. data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -226
  246. data/spec/reek/smell_detectors/long_parameter_list_spec.rb +0 -61
  247. data/spec/reek/smell_detectors/long_yield_list_spec.rb +0 -49
  248. data/spec/reek/smell_detectors/manual_dispatch_spec.rb +0 -75
  249. data/spec/reek/smell_detectors/missing_safe_method_spec.rb +0 -68
  250. data/spec/reek/smell_detectors/module_initialize_spec.rb +0 -77
  251. data/spec/reek/smell_detectors/nested_iterators_spec.rb +0 -333
  252. data/spec/reek/smell_detectors/nil_check_spec.rb +0 -100
  253. data/spec/reek/smell_detectors/repeated_conditional_spec.rb +0 -100
  254. data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -77
  255. data/spec/reek/smell_detectors/too_many_constants_spec.rb +0 -144
  256. data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +0 -132
  257. data/spec/reek/smell_detectors/too_many_methods_spec.rb +0 -54
  258. data/spec/reek/smell_detectors/too_many_statements_spec.rb +0 -90
  259. data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +0 -78
  260. data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +0 -78
  261. data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +0 -147
  262. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +0 -201
  263. data/spec/reek/smell_detectors/unused_parameters_spec.rb +0 -114
  264. data/spec/reek/smell_detectors/unused_private_method_spec.rb +0 -205
  265. data/spec/reek/smell_detectors/utility_function_spec.rb +0 -293
  266. data/spec/reek/smell_warning_spec.rb +0 -137
  267. data/spec/reek/source/source_code_spec.rb +0 -79
  268. data/spec/reek/source/source_locator_spec.rb +0 -166
  269. data/spec/reek/spec/should_reek_of_spec.rb +0 -153
  270. data/spec/reek/spec/should_reek_only_of_spec.rb +0 -91
  271. data/spec/reek/spec/should_reek_spec.rb +0 -52
  272. data/spec/reek/spec/smell_matcher_spec.rb +0 -87
  273. data/spec/reek/tree_dresser_spec.rb +0 -46
  274. data/spec/spec_helper.rb +0 -110
  275. data/tasks/configuration.rake +0 -18
  276. data/tasks/console.rake +0 -5
  277. data/tasks/reek.rake +0 -6
  278. data/tasks/rubocop.rake +0 -11
  279. data/tasks/test.rake +0 -32
  280. /data/lib/reek/{report/code_climate.rb → code_climate.rb} +0 -0
@@ -1,293 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/smell_detectors/utility_function'
3
-
4
- RSpec.describe Reek::SmellDetectors::UtilityFunction do
5
- it 'reports the right values' do
6
- src = <<-RUBY
7
- def alfa(bravo)
8
- bravo.charlie.delta
9
- end
10
- RUBY
11
-
12
- expect(src).to reek_of(:UtilityFunction,
13
- lines: [1],
14
- context: 'alfa',
15
- message: "doesn't depend on instance state (maybe move it to another class?)",
16
- source: 'string')
17
- end
18
-
19
- it 'counts a local call in a param initializer' do
20
- src = 'def alfa(bravo = charlie) bravo.to_s end'
21
- expect(src).not_to reek_of(:UtilityFunction)
22
- end
23
-
24
- it 'counts usages of self' do
25
- src = 'def alfa(bravo); alfa.bravo(self); end'
26
- expect(src).not_to reek_of(:UtilityFunction)
27
- end
28
-
29
- it 'counts self reference within a dstr' do
30
- src = 'def alfa(bravo); "#{self} #{bravo}"; end'
31
- expect(src).not_to reek_of(:UtilityFunction)
32
- end
33
-
34
- it 'counts calls to self within a dstr' do
35
- src = 'def alfa(bravo); "#{self.gsub(/charlie/, /delta/)}"; end'
36
- expect(src).
37
- not_to reek_of(:UtilityFunction)
38
- end
39
-
40
- it 'does not report a method that calls super' do
41
- src = 'def alfa(bravo) super; bravo.to_s; end'
42
- expect(src).not_to reek_of(:UtilityFunction)
43
- end
44
-
45
- it 'does not report a method that calls super with arguments' do
46
- src = 'def alfa(bravo) super(bravo); bravo.to_s; end'
47
- expect(src).not_to reek_of(:UtilityFunction)
48
- end
49
-
50
- it 'recognises a deep call' do
51
- src = <<-RUBY
52
- class Alfa
53
- def bravo(charlie)
54
- charlie.each { |delta| foxtrot(delta) }
55
- end
56
-
57
- def foxtrot(golf)
58
- @india << golf
59
- end
60
- end
61
- RUBY
62
-
63
- expect(src).not_to reek_of(:UtilityFunction)
64
- end
65
-
66
- it 'does not report empty method' do
67
- src = 'def alfa(bravo); end'
68
- expect(src).not_to reek_of(:UtilityFunction)
69
- end
70
-
71
- it 'does not report literal' do
72
- src = 'def alfa; 3; end'
73
- expect(src).not_to reek_of(:UtilityFunction)
74
- end
75
-
76
- it 'does not report instance variable reference' do
77
- src = 'def alfa; @bravo; end'
78
- expect(src).not_to reek_of(:UtilityFunction)
79
- end
80
-
81
- it 'does not report vcall' do
82
- src = 'def alfa; bravo; end'
83
- expect(src).not_to reek_of(:UtilityFunction)
84
- end
85
-
86
- it 'does not report references to self' do
87
- src = 'def alfa; self; end'
88
- expect(src).not_to reek_of(:UtilityFunction)
89
- end
90
-
91
- it 'recognises an ivar reference within a block' do
92
- src = 'def alfa(bravo) bravo.each { @charlie = 3} end'
93
- expect(src).not_to reek_of(:UtilityFunction)
94
- end
95
-
96
- it 'reports a call to a constant' do
97
- src = 'def simple(arga) FIELDS[arga] end'
98
- expect(src).to reek_of(:UtilityFunction, context: 'simple')
99
- end
100
-
101
- context 'when examining singleton methods' do
102
- ['class', 'module'].each do |scope|
103
- it "does not report for #{scope} with `class << self` notation" do
104
- src = "#{scope} Alfa; class << self; def bravo(charlie) charlie.to_s; end; end; end"
105
- expect(src).not_to reek_of(:UtilityFunction)
106
- end
107
-
108
- it "does not report for #{scope} with `self.` notation" do
109
- src = "#{scope} Alfa; def self.bravo(charlie) charlie.to_s; end; end"
110
- expect(src).not_to reek_of(:UtilityFunction)
111
- end
112
- end
113
-
114
- context 'when defined by using `module_function`' do
115
- it 'does not report UtilityFunction also when using multiple arguments' do
116
- src = <<-RUBY
117
- class Alfa
118
- def bravo(charlie) charlie.to_s; end
119
- def delta(echo) echo.to_s; end
120
- module_function :bravo, :delta
121
- end
122
- RUBY
123
-
124
- expect(src).not_to reek_of(:UtilityFunction)
125
- end
126
-
127
- it 'does not report module functions defined by earlier modifier' do
128
- src = <<-RUBY
129
- module Alfa
130
- module_function
131
- def bravo(charlie) charlie.to_s; end
132
- end
133
- RUBY
134
-
135
- expect(src).not_to reek_of(:UtilityFunction)
136
- end
137
-
138
- it 'reports functions preceded by canceled modifier' do
139
- src = <<-RUBY
140
- module Alfa
141
- module_function
142
- public
143
- def bravo(charlie) charlie.to_s; end
144
- end
145
- RUBY
146
-
147
- expect(src).to reek_of(:UtilityFunction, context: 'Alfa#bravo')
148
- end
149
-
150
- it 'does not report when module_function is called in separate scope' do
151
- src = <<-RUBY
152
- class Alfa
153
- def bravo(charlie) charlie.to_s; end
154
- begin
155
- module_function :bravo
156
- end
157
- end
158
- RUBY
159
- expect(src).not_to reek_of(:UtilityFunction)
160
- end
161
- end
162
- end
163
-
164
- describe 'method visibility' do
165
- it 'reports private methods' do
166
- src = <<-RUBY
167
- class Alfa
168
- private
169
- def bravo(charlie)
170
- charlie.delta.echo
171
- end
172
- end
173
- RUBY
174
-
175
- expect(src).to reek_of(:UtilityFunction, context: 'Alfa#bravo')
176
- end
177
-
178
- it 'reports protected methods' do
179
- src = <<-RUBY
180
- class Alfa
181
- protected
182
- def bravo(charlie)
183
- charlie.delta.echo
184
- end
185
- end
186
- RUBY
187
-
188
- expect(src).to reek_of(:UtilityFunction, context: 'Alfa#bravo')
189
- end
190
- end
191
-
192
- describe 'disabling UtilityFunction via configuration for non-public methods' do
193
- let(:config) do
194
- { Reek::SmellDetectors::UtilityFunction::PUBLIC_METHODS_ONLY_KEY => true }
195
- end
196
-
197
- context 'when examining public methods' do
198
- it 'still reports UtilityFunction' do
199
- src = <<-RUBY
200
- class Alfa
201
- def bravo(charlie)
202
- charlie.delta.echo
203
- end
204
- end
205
- RUBY
206
-
207
- expect(src).to reek_of(:UtilityFunction, context: 'Alfa#bravo').with_config(config)
208
- end
209
- end
210
-
211
- context 'when examining private methods' do
212
- it 'does not report UtilityFunction' do
213
- src = <<-RUBY
214
- class Alfa
215
- private
216
- def bravo(charlie)
217
- charlie.delta.echo
218
- end
219
- end
220
- RUBY
221
-
222
- expect(src).not_to reek_of(:UtilityFunction).with_config(config)
223
- end
224
-
225
- it 'does not report UtilityFunction when private is used as a def modifier' do
226
- src = <<-RUBY
227
- class Alfa
228
- private def bravo(charlie)
229
- charlie.delta.echo
230
- end
231
- end
232
- RUBY
233
-
234
- expect(src).not_to reek_of(:UtilityFunction).with_config(config)
235
- end
236
- end
237
-
238
- context 'when examining protected methods' do
239
- it 'does not report UtilityFunction' do
240
- src = <<-RUBY
241
- class Alfa
242
- protected
243
- def bravo(charlie)
244
- charlie.delta.echo
245
- end
246
- end
247
- RUBY
248
-
249
- expect(src).not_to reek_of(:UtilityFunction).with_config(config)
250
- end
251
-
252
- it 'does not report UtilityFunction when protected is used as a def modifier' do
253
- src = <<-RUBY
254
- class Alfa
255
- protected def bravo(charlie)
256
- charlie.delta.echo
257
- end
258
- end
259
- RUBY
260
-
261
- expect(src).not_to reek_of(:UtilityFunction).with_config(config)
262
- end
263
- end
264
- end
265
-
266
- describe 'disabling with a comment' do
267
- it 'disables the method following the comment' do
268
- src = <<-RUBY
269
- class Alfa
270
- # :reek:UtilityFunction
271
- def bravo(charlie)
272
- charlie.delta.echo
273
- end
274
- end
275
- RUBY
276
-
277
- expect(src).not_to reek_of(:UtilityFunction)
278
- end
279
-
280
- it 'disables a method when it has a visibility modifier' do
281
- src = <<-RUBY
282
- class Alfa
283
- # :reek:UtilityFunction
284
- private def bravo(charlie)
285
- charlie.delta.echo
286
- end
287
- end
288
- RUBY
289
-
290
- expect(src).not_to reek_of(:UtilityFunction)
291
- end
292
- end
293
- end
@@ -1,137 +0,0 @@
1
- require_relative '../spec_helper'
2
- require_lib 'reek/smell_warning'
3
-
4
- RSpec.describe Reek::SmellWarning do
5
- let(:uncommunicative_name_detector) { build(:smell_detector, smell_type: 'UncommunicativeVariableName') }
6
-
7
- describe 'sort order' do
8
- shared_examples_for 'first sorts ahead of second' do
9
- it 'hash differently' do
10
- expect(first.hash).not_to eq(second.hash)
11
- end
12
-
13
- it 'are not equal' do
14
- expect(first).not_to eq(second)
15
- end
16
-
17
- it 'sort correctly' do
18
- expect(first <=> second).to be < 0
19
- end
20
-
21
- it 'does not match using eql?' do
22
- expect(first).not_to eql(second)
23
- end
24
- end
25
-
26
- context 'when smells differ only by detector' do
27
- let(:first) { build_smell_warning(smell_type: 'DuplicateMethodCall') }
28
- let(:second) { build_smell_warning(smell_type: 'FeatureEnvy') }
29
-
30
- it_behaves_like 'first sorts ahead of second'
31
- end
32
-
33
- context 'when smells differ only by lines' do
34
- let(:first) { build_smell_warning(smell_type: 'FeatureEnvy', lines: [2]) }
35
- let(:second) { build_smell_warning(smell_type: 'FeatureEnvy', lines: [3]) }
36
-
37
- it_behaves_like 'first sorts ahead of second'
38
- end
39
-
40
- context 'when smells differ only by context' do
41
- let(:first) { build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'first') }
42
- let(:second) do
43
- build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'second')
44
- end
45
-
46
- it_behaves_like 'first sorts ahead of second'
47
- end
48
-
49
- context 'when smells differ only by message' do
50
- let(:first) do
51
- build_smell_warning(smell_type: 'DuplicateMethodCall',
52
- context: 'ctx', message: 'first message')
53
- end
54
- let(:second) do
55
- build_smell_warning(smell_type: 'DuplicateMethodCall',
56
- context: 'ctx', message: 'second message')
57
- end
58
-
59
- it_behaves_like 'first sorts ahead of second'
60
- end
61
-
62
- context 'when smells differ by name and message' do
63
- let(:first) do
64
- build_smell_warning(smell_type: 'FeatureEnvy', message: 'second message')
65
- end
66
- let(:second) do
67
- build_smell_warning(smell_type: 'UtilityFunction', message: 'first message')
68
- end
69
-
70
- it_behaves_like 'first sorts ahead of second'
71
- end
72
-
73
- context 'when smells differ everywhere' do
74
- let(:first) do
75
- build_smell_warning(smell_type: 'DuplicateMethodCall',
76
- context: 'Dirty#a',
77
- message: 'calls @s.title twice')
78
- end
79
-
80
- let(:second) do
81
- build_smell_warning(smell_type: 'UncommunicativeVariableName',
82
- context: 'Dirty',
83
- message: "has the variable name '@s'")
84
- end
85
-
86
- it_behaves_like 'first sorts ahead of second'
87
- end
88
- end
89
-
90
- describe '#yaml_hash' do
91
- let(:context_name) { 'Module::Class#method/block' }
92
- let(:lines) { [24, 513] }
93
- let(:message) { 'test message' }
94
- let(:parameters) { { 'one' => 34, 'two' => 'second' } }
95
- let(:smell_type) { 'FeatureEnvy' }
96
- let(:source) { 'a/ruby/source/file.rb' }
97
-
98
- let(:yaml) do
99
- warning = described_class.new(smell_type, source: source,
100
- context: context_name,
101
- lines: lines,
102
- message: message,
103
- parameters: parameters)
104
- warning.yaml_hash
105
- end
106
-
107
- it 'includes the smell type' do
108
- expect(yaml['smell_type']).to eq 'FeatureEnvy'
109
- end
110
-
111
- it 'includes the context' do
112
- expect(yaml['context']).to eq context_name
113
- end
114
-
115
- it 'includes the message' do
116
- expect(yaml['message']).to eq message
117
- end
118
-
119
- it 'includes the line numbers' do
120
- expect(yaml['lines']).to match_array lines
121
- end
122
-
123
- it 'includes the source' do
124
- expect(yaml['source']).to eq source
125
- end
126
-
127
- it 'includes the documentation link' do
128
- expect(yaml['documentation_link']).to eq Reek::DocumentationLink.build('FeatureEnvy')
129
- end
130
-
131
- it 'includes the parameters' do
132
- parameters.each do |key, value|
133
- expect(yaml[key]).to eq value
134
- end
135
- end
136
- end
137
- end
@@ -1,79 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require 'stringio'
3
- require_lib 'reek/source/source_code'
4
-
5
- RSpec.describe Reek::Source::SourceCode do
6
- describe '#syntax_tree' do
7
- it 'associates comments with the AST' do
8
- source = "# this is\n# a comment\ndef foo; end"
9
- source_code = described_class.new(source: source, origin: '(string)')
10
- result = source_code.syntax_tree
11
- expect(result.leading_comment).to eq "# this is\n# a comment"
12
- end
13
-
14
- it 'cleanly processes empty source' do
15
- source_code = described_class.new(source: '', origin: '(string)')
16
- result = source_code.syntax_tree
17
- expect(result.type).to eq :empty
18
- end
19
-
20
- it 'cleanly processes empty source with comments' do
21
- source = "# this is\n# a comment\n"
22
- source_code = described_class.new(source: source, origin: '(string)')
23
- result = source_code.syntax_tree
24
- expect(result.type).to eq :empty
25
- end
26
-
27
- it 'does not crash with sequences incompatible with UTF-8' do
28
- source = '"\xFF"'
29
- source_code = described_class.new(source: source, origin: '(string)')
30
- result = source_code.syntax_tree
31
- expect(result.children.first).to eq "\xFF"
32
- end
33
-
34
- it 'returns a :lambda node for lambda expressions' do
35
- source = '->() { }'
36
- source_code = described_class.new(source: source, origin: '(string)')
37
- result = source_code.syntax_tree
38
- expect(result.children.first.type).to eq :lambda
39
- end
40
-
41
- context 'when the parser fails with a Parser::SyntaxError' do
42
- let(:src) { described_class.new(source: code) }
43
- let(:code) { '== Invalid Syntax ==' }
44
-
45
- it 'raises the error' do
46
- expect { src.syntax_tree }.to raise_error Parser::SyntaxError
47
- end
48
- end
49
-
50
- context 'when the parser fails with a generic error' do
51
- let(:code) { '' }
52
- let(:parser) { instance_double('Parser::Ruby25') }
53
- let(:src) { described_class.new(source: code, parser: parser) }
54
- let(:error_class) { RuntimeError }
55
- let(:error_message) { 'An error' }
56
-
57
- before do
58
- allow(parser).to receive(:parse_with_comments).and_raise(error_class, error_message)
59
- end
60
-
61
- it 'raises the error' do
62
- expect { src.syntax_tree }.to raise_error error_class, error_message
63
- end
64
- end
65
-
66
- if RUBY_VERSION >= '2.7'
67
- context 'with ruby 2.7 syntax' do
68
- context 'with forward_args (`...`)' do
69
- let(:source_code) { described_class.new(source: 'def alpha(...) bravo(...); end') }
70
-
71
- it 'returns a :forward_args node' do
72
- result = source_code.syntax_tree
73
- expect(result.children[1].type).to eq(:forward_args)
74
- end
75
- end
76
- end
77
- end
78
- end
79
- end
@@ -1,166 +0,0 @@
1
- require 'pathname'
2
- require_relative '../../spec_helper'
3
- require_lib 'reek/configuration/app_configuration'
4
- require_lib 'reek/source/source_locator'
5
-
6
- RSpec.describe Reek::Source::SourceLocator do
7
- describe '#sources' do
8
- context 'when applied to hidden directories' do
9
- let(:path) { SAMPLES_DIR.join('source_with_hidden_directories') }
10
-
11
- let(:expected_paths) do
12
- [path.join('not_hidden.rb')]
13
- end
14
-
15
- let(:paths_that_are_expected_to_be_ignored) do
16
- [path.join('.hidden/hidden.rb')]
17
- end
18
-
19
- it 'does not scan hidden directories' do
20
- sources = described_class.new([path]).sources
21
-
22
- expect(sources).not_to include(*paths_that_are_expected_to_be_ignored)
23
- end
24
-
25
- it 'scans directories that are not hidden' do
26
- sources = described_class.new([path]).sources
27
-
28
- expect(sources).to match_array expected_paths
29
- end
30
- end
31
-
32
- context 'with excluded paths' do
33
- let(:configuration) do
34
- test_configuration_for(CONFIGURATION_DIR.join('with_excluded_paths.reek'))
35
- end
36
-
37
- let(:options) { instance_double('Reek::CLI::Options', force_exclusion?: false) }
38
-
39
- context 'when the path is absolute' do
40
- let(:path) do
41
- SAMPLES_DIR.join('source_with_exclude_paths',
42
- 'ignore_me',
43
- 'uncommunicative_method_name.rb').expand_path
44
- end
45
-
46
- context 'when options.force_exclusion? is true' do
47
- before do
48
- allow(options).to receive(:force_exclusion?).and_return(true)
49
- end
50
-
51
- it 'excludes this file' do
52
- sources = described_class.new([path], configuration: configuration, options: options).sources
53
- expect(sources).not_to include(path)
54
- end
55
- end
56
-
57
- context 'when options.force_exclusion? is false' do
58
- before do
59
- allow(options).to receive(:force_exclusion?).and_return(false)
60
- end
61
-
62
- it 'includes this file' do
63
- sources = described_class.new([path], configuration: configuration, options: options).sources
64
- expect(sources).to include(path)
65
- end
66
- end
67
- end
68
-
69
- context 'when the path is a file name in an excluded directory' do
70
- let(:path) { SAMPLES_DIR.join('source_with_exclude_paths', 'ignore_me', 'uncommunicative_method_name.rb') }
71
-
72
- context 'when options.force_exclusion? is true' do
73
- before do
74
- allow(options).to receive(:force_exclusion?).and_return(true)
75
- end
76
-
77
- it 'excludes this file' do
78
- sources = described_class.new([path], configuration: configuration, options: options).sources
79
- expect(sources).not_to include(path)
80
- end
81
- end
82
-
83
- context 'when options.force_exclusion? is false' do
84
- before do
85
- allow(options).to receive(:force_exclusion?).and_return(false)
86
- end
87
-
88
- it 'includes this file' do
89
- sources = described_class.new([path], configuration: configuration, options: options).sources
90
- expect(sources).to include(path)
91
- end
92
- end
93
- end
94
-
95
- context 'when path is a directory or a file' do
96
- let(:path) { SAMPLES_DIR.join('source_with_exclude_paths') }
97
-
98
- let(:expected_paths) do
99
- [path.join('nested/uncommunicative_variable_name.rb')]
100
- end
101
-
102
- let(:paths_that_are_expected_to_be_ignored) do
103
- [
104
- path.join('ignore_me/uncommunicative_method_name.rb'),
105
- path.join('nested/ignore_me_as_well/irresponsible_module.rb'),
106
- path.join('nested/uncommunicative_parameter_name.rb')
107
- ]
108
- end
109
-
110
- it 'does not use excluded paths' do
111
- sources = described_class.new([path], configuration: configuration, options: options).sources
112
- expect(sources).not_to include(*paths_that_are_expected_to_be_ignored)
113
- end
114
-
115
- it 'scans directories and files that are not excluded' do
116
- sources = described_class.new([path], configuration: configuration).sources
117
- expect(sources).to eq expected_paths
118
- end
119
- end
120
- end
121
-
122
- context 'with non-Ruby paths' do
123
- let(:path) { SAMPLES_DIR.join('source_with_non_ruby_files') }
124
- let(:expected_sources) do
125
- [path.join('ruby.rb')]
126
- end
127
- let(:paths_that_are_expected_to_be_ignored) do
128
- [
129
- path.join('gibberish'),
130
- path.join('python_source.py')
131
- ]
132
- end
133
-
134
- it 'uses Ruby source paths' do
135
- sources = described_class.new([path]).sources
136
-
137
- expect(sources).to include(*expected_sources)
138
- end
139
-
140
- it 'does not use non-Ruby source paths' do
141
- sources = described_class.new([path]).sources
142
-
143
- expect(sources).not_to include(*paths_that_are_expected_to_be_ignored)
144
- end
145
- end
146
-
147
- context 'when passing "." or "./" as argument' do
148
- let(:expected_sources) do
149
- [Pathname.new('spec/spec_helper.rb'), Pathname.new('lib/reek.rb')]
150
- end
151
-
152
- it 'expands it correctly' do
153
- sources_for_dot = described_class.new([Pathname.new('.')]).sources
154
-
155
- expect(sources_for_dot).to include(*expected_sources)
156
- end
157
-
158
- it 'ignores the trailing slash' do
159
- sources_for_dot = described_class.new([Pathname.new('.')]).sources
160
- sources_for_dot_slash = described_class.new([Pathname.new('./')]).sources
161
-
162
- expect(sources_for_dot).to eq(sources_for_dot_slash)
163
- end
164
- end
165
- end
166
- end