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,86 +0,0 @@
1
- require_relative '../../../spec_helper'
2
- require_lib 'reek/cli/command/todo_list_command'
3
- require_lib 'reek/cli/options'
4
- require_lib 'reek/configuration/app_configuration'
5
-
6
- RSpec.describe Reek::CLI::Command::TodoListCommand do
7
- let(:existing_configuration) do
8
- <<~YAML
9
- ---
10
- detectors:
11
- UncommunicativeMethodName:
12
- exclude:
13
- - Smelly#x
14
- YAML
15
- end
16
-
17
- let(:smelly_file) do
18
- <<~RUBY
19
- # Smelly class
20
- class Smelly
21
- # This will reek of UncommunicativeMethodName
22
- def x
23
- y = 10 # This will reek of UncommunicativeVariableName
24
- end
25
- end
26
- RUBY
27
- end
28
-
29
- let(:new_configuration_file) do
30
- <<~YAML
31
- # Auto generated by Reeks --todo flag
32
- ---
33
- detectors:
34
- UncommunicativeMethodName:
35
- exclude:
36
- - Smelly#x
37
- UncommunicativeVariableName:
38
- exclude:
39
- - Smelly#x
40
- YAML
41
- end
42
-
43
- describe '#execute on smelly source' do
44
- around do |example|
45
- Dir.mktmpdir do |tmp|
46
- Dir.chdir(tmp) do
47
- File.write SMELLY_FILE.basename, smelly_file
48
- example.run
49
- end
50
- end
51
- end
52
-
53
- context 'with default configuration file' do
54
- let(:default_configuration_file_name) { Reek::DEFAULT_CONFIGURATION_FILE_NAME }
55
-
56
- context 'when does not exist yet' do
57
- it 'creates it' do
58
- Reek::CLI::Silencer.silently { todo_command.execute }
59
-
60
- actual_content = File.read(default_configuration_file_name)
61
- expect(actual_content).to match(new_configuration_file)
62
- end
63
- end
64
-
65
- context 'when exists already' do
66
- it 'does not update the configuration' do
67
- File.write default_configuration_file_name, existing_configuration
68
- command = todo_command
69
-
70
- Reek::CLI::Silencer.silently { command.execute }
71
-
72
- actual_content = File.read(default_configuration_file_name)
73
- expect(actual_content).to match(existing_configuration)
74
- end
75
- end
76
- end
77
-
78
- def todo_command(options: Reek::CLI::Options.new([]),
79
- sources: [Pathname.new(SMELLY_FILE.basename.to_s)],
80
- configuration: Reek::Configuration::AppConfiguration.default)
81
- described_class.new options: options,
82
- sources: sources,
83
- configuration: configuration
84
- end
85
- end
86
- end
@@ -1,51 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/cli/options'
3
-
4
- RSpec.describe Reek::CLI::Options do
5
- let(:options) { described_class.new }
6
-
7
- describe '#initialize' do
8
- it 'sets a valid default value for report_format' do
9
- expect(options.report_format).to eq :text
10
- end
11
-
12
- it 'sets a valid default value for location_format' do
13
- expect(options.location_format).to eq :numbers
14
- end
15
-
16
- it 'enables colors when stdout is a TTY' do
17
- allow($stdout).to receive_messages(tty?: true)
18
- expect(options.colored).to be true
19
- end
20
-
21
- it 'does not enable colors when stdout is not a TTY' do
22
- allow($stdout).to receive_messages(tty?: false)
23
- expect(options.colored).to be false
24
- end
25
-
26
- it 'enables progress when stdout is a TTY' do
27
- allow($stdout).to receive_messages(tty?: true)
28
- expect(options.progress_format).to eq :dots
29
- end
30
-
31
- it 'does not enable progress when stdout is not a TTY' do
32
- allow($stdout).to receive_messages(tty?: false)
33
- expect(options.progress_format).to eq :quiet
34
- end
35
-
36
- it 'sets force_exclusion to false by default' do
37
- expect(options.force_exclusion?).to be false
38
- end
39
- end
40
-
41
- describe 'parse' do
42
- it 'raises on invalid argument in ARGV' do
43
- options = described_class.new ['-z']
44
- expect { options.parse }.to raise_error(OptionParser::InvalidOption)
45
- end
46
-
47
- it 'returns self' do
48
- expect(options.parse).to be_a(described_class)
49
- end
50
- end
51
- end
@@ -1,28 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/cli/silencer'
3
-
4
- RSpec.describe Reek::CLI::Silencer do
5
- describe '.silently' do
6
- it 'blocks output from the block on $stdout' do
7
- expect { described_class.silently { puts 'Hi!' } }.not_to output.to_stdout
8
- end
9
-
10
- it 'blocks output from the block on $stderr' do
11
- expect { described_class.silently { warn 'Hi!' } }.not_to output.to_stderr
12
- end
13
-
14
- it 'restores output on $stdout after the block' do
15
- expect do
16
- described_class.silently { puts 'Hi!' }
17
- puts 'there!'
18
- end.to output("there!\n").to_stdout
19
- end
20
-
21
- it 'restores output on $stderr after the block' do
22
- expect do
23
- described_class.silently { warn 'Hi!' }
24
- warn 'there!'
25
- end.to output("there!\n").to_stderr
26
- end
27
- end
28
- end
@@ -1,184 +0,0 @@
1
- require_relative '../spec_helper'
2
- require_lib 'reek/code_comment'
3
-
4
- RSpec.describe Reek::CodeComment do
5
- context 'with an empty comment' do
6
- let(:comment) { build_code_comment(comment: '') }
7
-
8
- it 'is not descriptive' do
9
- expect(comment).not_to be_descriptive
10
- end
11
-
12
- it 'has an empty config' do
13
- expect(comment.config).to be_empty
14
- end
15
- end
16
-
17
- describe '#descriptive' do
18
- it 'rejects an empty comment' do
19
- comment = build_code_comment(comment: '#')
20
- expect(comment).not_to be_descriptive
21
- end
22
-
23
- it 'rejects a 1-word comment' do
24
- comment = build_code_comment(comment: "# alpha\n# ")
25
- expect(comment).not_to be_descriptive
26
- end
27
-
28
- it 'accepts a 2-word comment' do
29
- comment = build_code_comment(comment: '# alpha bravo ')
30
- expect(comment).to be_descriptive
31
- end
32
-
33
- it 'accepts a multi-word comment' do
34
- comment = build_code_comment(comment: "# alpha bravo \n# charlie \n # delta ")
35
- expect(comment).to be_descriptive
36
- end
37
- end
38
-
39
- describe 'good comment config' do
40
- it 'parses hashed options' do
41
- comment = '# :reek:DuplicateMethodCall { max_calls: 3 }'
42
- config = build_code_comment(comment: comment).config
43
-
44
- expect(config).to include('DuplicateMethodCall')
45
- expect(config['DuplicateMethodCall']).to have_key 'max_calls'
46
- expect(config['DuplicateMethodCall']['max_calls']).to eq 3
47
- end
48
-
49
- it 'parses multiple hashed options' do
50
- comment = <<-RUBY
51
- # :reek:DuplicateMethodCall { max_calls: 3 }
52
- # :reek:NestedIterators { enabled: true }
53
- RUBY
54
- config = build_code_comment(comment: comment).config
55
-
56
- expect(config).to include('DuplicateMethodCall', 'NestedIterators')
57
- expect(config['DuplicateMethodCall']['max_calls']).to eq 3
58
- expect(config['NestedIterators']['enabled']).to be_truthy
59
- end
60
-
61
- it 'parses multiple hashed options on the same line' do
62
- comment = <<-RUBY
63
- #:reek:DuplicateMethodCall { max_calls: 3 } and :reek:NestedIterators { enabled: true }
64
- RUBY
65
- config = build_code_comment(comment: comment).config
66
-
67
- expect(config).to include('DuplicateMethodCall', 'NestedIterators')
68
- expect(config['DuplicateMethodCall']['max_calls']).to eq 3
69
- expect(config['NestedIterators']).to include('enabled')
70
- expect(config['NestedIterators']['enabled']).to be_truthy
71
- end
72
-
73
- it 'parses multiple unhashed options on the same line' do
74
- comment = '# :reek:DuplicateMethodCall and :reek:NestedIterators'
75
- config = build_code_comment(comment: comment).config
76
-
77
- expect(config).to include('DuplicateMethodCall', 'NestedIterators')
78
- expect(config['DuplicateMethodCall']).to include('enabled')
79
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
80
- expect(config['NestedIterators']).to include('enabled')
81
- expect(config['NestedIterators']['enabled']).to be_falsey
82
- end
83
-
84
- it 'disables the smell if no options are specifed' do
85
- comment = '# :reek:DuplicateMethodCall'
86
- config = build_code_comment(comment: comment).config
87
-
88
- expect(config).to include('DuplicateMethodCall')
89
- expect(config['DuplicateMethodCall']).to include('enabled')
90
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
91
- end
92
-
93
- it 'does not disable the smell if options are specifed' do
94
- comment = '# :reek:DuplicateMethodCall { max_calls: 3 }'
95
- config = build_code_comment(comment: comment).config
96
-
97
- expect(config['DuplicateMethodCall']).not_to include('enabled')
98
- end
99
-
100
- it 'ignores smells after a space' do
101
- config = build_code_comment(comment: '# :reek: DuplicateMethodCall').config
102
- expect(config).not_to include('DuplicateMethodCall')
103
- end
104
-
105
- it 'removes the configuration options from the comment' do
106
- original_comment = <<-RUBY
107
- # Actual
108
- # :reek:DuplicateMethodCall { max_calls: 3 }
109
- # :reek:NestedIterators { enabled: true }
110
- # comment
111
- RUBY
112
- comment = build_code_comment(comment: original_comment)
113
-
114
- expect(comment.send(:sanitized_comment)).to eq('Actual comment')
115
- end
116
- end
117
- end
118
-
119
- RSpec.describe Reek::CodeComment::CodeCommentValidator do
120
- context 'when the comment contains an unknown detector name' do
121
- it 'raises BadDetectorInCommentError' do
122
- expect do
123
- build_code_comment(comment: '# :reek:DoesNotExist')
124
- end.to raise_error(Reek::Errors::BadDetectorInCommentError)
125
- end
126
- end
127
-
128
- context 'when the comment contains an unparsable detector configuration' do
129
- it 'raises GarbageDetectorConfigurationInCommentError' do
130
- expect do
131
- comment = '# :reek:UncommunicativeMethodName { thats: a: bad: config }'
132
- build_code_comment(comment: comment)
133
- end.to raise_error(Reek::Errors::GarbageDetectorConfigurationInCommentError)
134
- end
135
- end
136
-
137
- context 'when the legacy comment format was used' do
138
- it 'raises LegacyCommentSeparatorError' do
139
- comment = '# :reek:DuplicateMethodCall:'
140
- expect { build_code_comment(comment: comment) }.
141
- to raise_error Reek::Errors::LegacyCommentSeparatorError
142
- end
143
- end
144
-
145
- describe 'validating configuration keys' do
146
- context 'when basic options are mispelled' do
147
- it 'raises BadDetectorConfigurationKeyInCommentError' do
148
- expect do
149
- # exclude -> exlude and enabled -> nabled
150
- comment = '# :reek:UncommunicativeMethodName { exlude: alfa, nabled: true }'
151
- build_code_comment(comment: comment)
152
- end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
153
- end
154
- end
155
-
156
- context 'when basic options are not mispelled' do
157
- it 'does not raise' do
158
- expect do
159
- comment = '# :reek:UncommunicativeMethodName { exclude: alfa, enabled: true }'
160
- build_code_comment(comment: comment)
161
- end.not_to raise_error
162
- end
163
- end
164
-
165
- context 'when unknown custom options are specified' do
166
- it 'raises BadDetectorConfigurationKeyInCommentError' do
167
- expect do
168
- # max_copies -> mx_copies and min_clump_size -> mn_clump_size
169
- comment = '# :reek:DataClump { mx_copies: 4, mn_clump_size: 3 }'
170
- build_code_comment(comment: comment)
171
- end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
172
- end
173
- end
174
-
175
- context 'when valid custom options are specified' do
176
- it 'does not raise' do
177
- expect do
178
- comment = '# :reek:DataClump { max_copies: 4, min_clump_size: 3 }'
179
- build_code_comment(comment: comment)
180
- end.not_to raise_error
181
- end
182
- end
183
- end
184
- end
@@ -1,195 +0,0 @@
1
- require 'pathname'
2
- require_relative '../../spec_helper'
3
- require_lib 'reek/configuration/app_configuration'
4
- require_lib 'reek/configuration/directory_directives'
5
- require_lib 'reek/configuration/default_directive'
6
- require_lib 'reek/configuration/excluded_paths'
7
-
8
- RSpec.describe Reek::Configuration::AppConfiguration do
9
- describe 'factory methods' do
10
- around do |example|
11
- Dir.mktmpdir do |tmp|
12
- Dir.chdir(tmp) do
13
- example.run
14
- end
15
- end
16
- end
17
-
18
- let(:expected_exclude_file_names) do
19
- %w(exclude_me.rb exclude_me_too.rb)
20
- end
21
-
22
- let(:expected_exclude_directories) do
23
- %w(directory_with_trailing_slash/ directory_without_trailing_slash)
24
- end
25
-
26
- let(:expected_excluded_paths) do
27
- (expected_exclude_file_names + expected_exclude_directories).map { |path| Pathname(path) }
28
- end
29
-
30
- let(:expected_default_directive) do
31
- { Reek::SmellDetectors::IrresponsibleModule => { 'enabled' => false } }
32
- end
33
-
34
- let(:expected_directory_directives) do
35
- { Pathname('directory_with_some_ruby_files') => {
36
- Reek::SmellDetectors::UtilityFunction => { 'enabled' => false }
37
- } }
38
- end
39
-
40
- describe '#from_path' do
41
- let(:configuration_path) { 'config.reek' }
42
- let(:configuration) do
43
- <<~YAML
44
- ---
45
- detectors:
46
- IrresponsibleModule:
47
- enabled: false
48
- directories:
49
- "directory_with_some_ruby_files":
50
- UtilityFunction:
51
- enabled: false
52
- exclude_paths:
53
- - "exclude_me.rb"
54
- - "exclude_me_too.rb"
55
- - "directory_with_trailing_slash/"
56
- - "directory_without_trailing_slash"
57
- YAML
58
- end
59
-
60
- before do
61
- File.write configuration_path, configuration
62
- FileUtils.touch expected_exclude_file_names
63
- FileUtils.mkdir expected_exclude_directories
64
- end
65
-
66
- it 'properly loads configuration and processes it' do
67
- config = described_class.from_path configuration_path
68
-
69
- expect(config.send(:excluded_paths)).to eq(expected_excluded_paths)
70
- expect(config.send(:default_directive)).to eq(expected_default_directive)
71
- expect(config.send(:directory_directives)).to eq(expected_directory_directives)
72
- end
73
- end
74
-
75
- describe '#from_hash' do
76
- before do
77
- FileUtils.touch expected_exclude_file_names
78
- FileUtils.mkdir expected_exclude_directories
79
- end
80
-
81
- let(:default_directive_value) do
82
- { Reek::DETECTORS_KEY => {
83
- 'IrresponsibleModule' => { 'enabled' => false }
84
- } }
85
- end
86
-
87
- let(:directory_directives_value) do
88
- { Reek::DIRECTORIES_KEY => {
89
- 'directory_with_some_ruby_files' => {
90
- 'UtilityFunction' => { 'enabled' => false }
91
- }
92
- } }
93
- end
94
-
95
- let(:exclude_paths_value) do
96
- { Reek::EXCLUDE_PATHS_KEY => (expected_exclude_file_names + expected_exclude_directories) }
97
- end
98
-
99
- let(:combined_value) do
100
- directory_directives_value.
101
- merge(default_directive_value).
102
- merge(exclude_paths_value)
103
- end
104
-
105
- it 'sets the configuration a unified simple data structure' do
106
- config = described_class.from_hash(combined_value)
107
-
108
- expect(config.send(:excluded_paths)).to eq(expected_excluded_paths)
109
- expect(config.send(:default_directive)).to eq(expected_default_directive)
110
- expect(config.send(:directory_directives)).to eq(expected_directory_directives)
111
- end
112
- end
113
- end
114
-
115
- describe '#default' do
116
- it 'returns a blank AppConfiguration' do
117
- config = described_class.default
118
- expect(config).to be_instance_of described_class
119
- expect(config.send(:excluded_paths)).to eq([])
120
- expect(config.send(:default_directive)).to eq({})
121
- expect(config.send(:directory_directives)).to eq({})
122
- end
123
- end
124
-
125
- describe '#directive_for' do
126
- context 'with multiple directory directives and no default directive present' do
127
- let(:source_via) { 'samples/some_files/dummy1.rb' }
128
- let(:baz_config) { { IrresponsibleModule: { enabled: false } } }
129
- let(:bang_config) { { Attribute: { enabled: true } } }
130
- let(:expected_result) { { Reek::SmellDetectors::Attribute => { enabled: true } } }
131
-
132
- let(:directory_directives) do
133
- {
134
- Reek::DIRECTORIES_KEY => {
135
- 'samples/some_files' => bang_config,
136
- 'samples/other_files' => baz_config
137
- }
138
- }
139
- end
140
-
141
- it 'returns the corresponding directive' do
142
- configuration = described_class.from_hash directory_directives
143
- expect(configuration.directive_for(source_via)).to eq expected_result
144
- end
145
- end
146
-
147
- context 'with directory directive and default directive present' do
148
- let(:directory) { 'spec/samples/two_smelly_files/' }
149
- let(:source_via) { "#{directory}/dummy.rb" }
150
-
151
- let(:configuration_as_hash) do
152
- {
153
- Reek::DIRECTORIES_KEY => {
154
- directory => { TooManyStatements: { max_statements: 8 } }
155
- },
156
- Reek::DETECTORS_KEY => {
157
- IrresponsibleModule: { enabled: false },
158
- TooManyStatements: { max_statements: 15 }
159
- }
160
- }
161
- end
162
-
163
- it 'returns the directory directive with the default directive reverse-merged' do
164
- configuration = described_class.from_hash configuration_as_hash
165
- actual = configuration.directive_for(source_via)
166
-
167
- expect(actual[Reek::SmellDetectors::IrresponsibleModule]).to be_truthy
168
- expect(actual[Reek::SmellDetectors::TooManyStatements]).to be_truthy
169
- expect(actual[Reek::SmellDetectors::TooManyStatements][:max_statements]).to eq(8)
170
- end
171
- end
172
-
173
- context 'with a path not covered by a directory directive but a default directive present' do
174
- let(:source_via) { 'samples/some_files/dummy.rb' }
175
-
176
- let(:configuration_as_hash) do
177
- {
178
- Reek::DETECTORS_KEY => {
179
- IrresponsibleModule: { enabled: false }
180
- },
181
- Reek::DIRECTORIES_KEY => {
182
- 'samples/other_files' => { Attribute: { enabled: false } }
183
- }
184
- }
185
- end
186
-
187
- let(:expected_result) { { Reek::SmellDetectors::IrresponsibleModule => { enabled: false } } }
188
-
189
- it 'returns the default directive' do
190
- configuration = described_class.from_hash configuration_as_hash
191
- expect(configuration.directive_for(source_via)).to eq expected_result
192
- end
193
- end
194
- end
195
- end