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,58 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/examiner'
3
- require_lib 'reek/report/json_report'
4
-
5
- require 'json'
6
- require 'stringio'
7
-
8
- RSpec.describe Reek::Report::JSONReport do
9
- let(:options) { {} }
10
- let(:instance) { described_class.new(**options) }
11
- let(:examiner) { Reek::Examiner.new(source) }
12
-
13
- before do
14
- instance.add_examiner examiner
15
- end
16
-
17
- context 'with empty source' do
18
- let(:source) { '' }
19
-
20
- it 'prints empty json' do
21
- expect { instance.show }.to output(/^\[\]$/).to_stdout
22
- end
23
- end
24
-
25
- context 'with smelly source' do
26
- let(:source) { 'def simple(a) a[3] end' }
27
-
28
- it 'prints smells as json' do
29
- out = StringIO.new
30
- instance.show(out)
31
- out.rewind
32
- result = JSON.parse(out.read)
33
- expected = JSON.parse <<-RUBY
34
- [
35
- {
36
- "context": "simple",
37
- "lines": [1],
38
- "message": "has the parameter name 'a'",
39
- "smell_type": "UncommunicativeParameterName",
40
- "source": "string",
41
- "name": "a",
42
- "documentation_link": "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Uncommunicative-Parameter-Name.md"
43
- },
44
- {
45
- "context": "simple",
46
- "lines": [1],
47
- "message": "doesn't depend on instance state (maybe move it to another class?)",
48
- "smell_type": "UtilityFunction",
49
- "source": "string",
50
- "documentation_link": "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Utility-Function.md"
51
- }
52
- ]
53
- RUBY
54
-
55
- expect(result).to eq expected
56
- end
57
- end
58
- end
@@ -1,32 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/report/location_formatter'
3
-
4
- RSpec.describe Reek::Report::BlankLocationFormatter do
5
- let(:warning) { build_smell_warning(lines: [11, 9, 250, 100]) }
6
-
7
- describe '.format' do
8
- it 'returns a blank String regardless of the warning' do
9
- expect(described_class.format(warning)).to eq('')
10
- end
11
- end
12
- end
13
-
14
- RSpec.describe Reek::Report::DefaultLocationFormatter do
15
- let(:warning) { build_smell_warning(lines: [11, 9, 250, 100]) }
16
-
17
- describe '.format' do
18
- it 'returns a prefix with sorted line numbers' do
19
- expect(described_class.format(warning)).to eq('[9, 11, 100, 250]:')
20
- end
21
- end
22
- end
23
-
24
- RSpec.describe Reek::Report::SingleLineLocationFormatter do
25
- let(:warning) { build_smell_warning(lines: [11, 9, 250, 100]) }
26
-
27
- describe '.format' do
28
- it 'returns the first line where the smell was found' do
29
- expect(described_class.format(warning)).to eq('dummy_file:9: ')
30
- end
31
- end
32
- end
@@ -1,68 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/report/progress_formatter'
3
-
4
- RSpec.describe Reek::Report::ProgressFormatter::Dots do
5
- let(:sources_count) { 23 }
6
- let(:formatter) { described_class.new(sources_count) }
7
-
8
- describe '#header' do
9
- it 'announces the number of files to be inspected' do
10
- expect(formatter.header).to eq "Inspecting 23 file(s):\n"
11
- end
12
- end
13
-
14
- describe '#progress' do
15
- let(:clean_examiner) { instance_double(Reek::Examiner, smelly?: false) }
16
- let(:smelly_examiner) { instance_double(Reek::Examiner, smelly?: true) }
17
-
18
- context 'with colors disabled' do
19
- before do
20
- Rainbow.enabled = false
21
- end
22
-
23
- it 'returns a dot for clean files' do
24
- expect(formatter.progress(clean_examiner)).to eq '.'
25
- end
26
-
27
- it 'returns an S for smelly files' do
28
- expect(formatter.progress(smelly_examiner)).to eq 'S'
29
- end
30
- end
31
- end
32
-
33
- describe '#footer' do
34
- it 'returns some blank lines to offset the output' do
35
- expect(formatter.footer).to eq "\n\n"
36
- end
37
- end
38
- end
39
-
40
- RSpec.describe Reek::Report::ProgressFormatter::Quiet do
41
- let(:sources_count) { 23 }
42
- let(:formatter) { described_class.new(sources_count) }
43
-
44
- describe '#header' do
45
- it 'is quiet' do
46
- expect(formatter.header).to eq ''
47
- end
48
- end
49
-
50
- describe '#progress' do
51
- let(:clean_examiner) { instance_double(Reek::Examiner, smelly?: false) }
52
- let(:smelly_examiner) { instance_double(Reek::Examiner, smelly?: true) }
53
-
54
- it 'is quiet for clean files' do
55
- expect(formatter.progress(clean_examiner)).to eq ''
56
- end
57
-
58
- it 'is quiet for smelly files' do
59
- expect(formatter.progress(smelly_examiner)).to eq ''
60
- end
61
- end
62
-
63
- describe '#footer' do
64
- it 'is quiet' do
65
- expect(formatter.footer).to eq ''
66
- end
67
- end
68
- end
@@ -1,89 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/examiner'
3
- require_lib 'reek/report/text_report'
4
- require_lib 'reek/report/heading_formatter'
5
- require_lib 'reek/report/simple_warning_formatter'
6
- require 'rainbow'
7
-
8
- RSpec.describe Reek::Report::TextReport do
9
- let(:instance) { described_class.new }
10
-
11
- context 'with a single empty source' do
12
- before do
13
- instance.add_examiner Reek::Examiner.new('')
14
- end
15
-
16
- it 'has an empty quiet_report' do
17
- expect { instance.show }.not_to output.to_stdout
18
- end
19
- end
20
-
21
- context 'with non smelly files' do
22
- before do
23
- instance.add_examiner(Reek::Examiner.new('def simple() puts "a" end'))
24
- instance.add_examiner(Reek::Examiner.new('def simple() puts "a" end'))
25
- end
26
-
27
- context 'with colors disabled' do
28
- before do
29
- Rainbow.enabled = false
30
- end
31
-
32
- it 'shows total of 0 warnings' do
33
- expect { instance.show }.to output(/0 total warnings\n\Z/).to_stdout
34
- end
35
- end
36
-
37
- context 'with colors enabled' do
38
- before do
39
- Rainbow.enabled = true
40
- end
41
-
42
- it 'has a footer in color' do
43
- expect { instance.show }.to output(/\e\[32m0 total warnings\n\e\[0m\Z/).to_stdout
44
- end
45
- end
46
- end
47
-
48
- context 'with a couple of smells' do
49
- before do
50
- instance.add_examiner(Reek::Examiner.new('def simple(a) a[3] end'))
51
- instance.add_examiner(Reek::Examiner.new('def simple(a) a[3] end'))
52
- end
53
-
54
- context 'with colors disabled' do
55
- before do
56
- Rainbow.enabled = false
57
- end
58
-
59
- it 'has a heading' do
60
- expect { instance.show }.to output(/string -- 2 warnings/).to_stdout
61
- end
62
-
63
- it 'mentions every smell name' do
64
- matcher = match(/UncommunicativeParameterName/).and match(/UtilityFunction/)
65
- expect { instance.show }.to output(matcher).to_stdout
66
- end
67
-
68
- it 'shows total number of warnings' do
69
- expect { instance.show }.to output(/4 total warnings\n\Z/).to_stdout
70
- end
71
- end
72
-
73
- context 'with colors enabled' do
74
- before do
75
- Rainbow.enabled = true
76
- end
77
-
78
- it 'has a header in color' do
79
- expect { instance.show }.
80
- to output(/\A\e\[36mstring -- \e\[0m\e\[33m2 warning\e\[0m\e\[33ms\e\[0m/).to_stdout
81
- end
82
-
83
- it 'shows total number of warnings in color' do
84
- expect { instance.show }.
85
- to output(/\e\[31m4 total warnings\n\e\[0m\Z/).to_stdout
86
- end
87
- end
88
- end
89
- end
@@ -1,24 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/examiner'
3
- require_lib 'reek/report/xml_report'
4
-
5
- RSpec.describe Reek::Report::XMLReport do
6
- let(:xml_report) { described_class.new }
7
-
8
- context 'with an empty source' do
9
- it 'prints empty checkstyle XML' do
10
- xml_report.add_examiner Reek::Examiner.new('')
11
- xml = "<?xml version='1.0'?>\n<checkstyle/>\n"
12
- expect { xml_report.show }.to output(xml).to_stdout
13
- end
14
- end
15
-
16
- context 'with a source with violations' do
17
- it 'prints non-empty checkstyle XML' do
18
- xml_report.add_examiner Reek::Examiner.new(SMELLY_FILE)
19
- xml = SAMPLES_DIR.join('checkstyle.xml').read
20
- xml = xml.gsub(SMELLY_FILE.to_s, SMELLY_FILE.expand_path.to_s)
21
- expect { xml_report.show }.to output(xml).to_stdout
22
- end
23
- end
24
- end
@@ -1,55 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/examiner'
3
- require_lib 'reek/report/yaml_report'
4
-
5
- require 'yaml'
6
- require 'stringio'
7
-
8
- RSpec.describe Reek::Report::YAMLReport do
9
- let(:options) { {} }
10
- let(:instance) { described_class.new(**options) }
11
- let(:examiner) { Reek::Examiner.new(source) }
12
-
13
- before do
14
- instance.add_examiner examiner
15
- end
16
-
17
- context 'with empty source' do
18
- let(:source) { '' }
19
-
20
- it 'prints empty yaml' do
21
- expect { instance.show }.to output(/^--- \[\]\n.*$/).to_stdout
22
- end
23
- end
24
-
25
- context 'with smelly source' do
26
- let(:source) { 'def simple(a) a[3] end' }
27
-
28
- it 'prints smells as yaml' do
29
- out = StringIO.new
30
- instance.show(out)
31
- out.rewind
32
- result = YAML.safe_load(out.read)
33
- expected = YAML.safe_load <<~YAML
34
- ---
35
- - context: "simple"
36
- lines:
37
- - 1
38
- message: "has the parameter name 'a'"
39
- smell_type: "UncommunicativeParameterName"
40
- source: "string"
41
- name: "a"
42
- documentation_link: "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Uncommunicative-Parameter-Name.md"
43
- - context: "simple"
44
- lines:
45
- - 1
46
- message: "doesn't depend on instance state (maybe move it to another class?)"
47
- smell_type: "UtilityFunction"
48
- source: "string"
49
- documentation_link: "https://github.com/troessner/reek/blob/v#{Reek::Version::STRING}/docs/Utility-Function.md"
50
- YAML
51
-
52
- expect(result).to eq expected
53
- end
54
- end
55
- end
@@ -1,28 +0,0 @@
1
- require_relative '../spec_helper'
2
- require_lib 'reek/report'
3
-
4
- RSpec.describe Reek::Report do
5
- describe '.report_class' do
6
- it 'returns the correct class' do
7
- expect(described_class.report_class(:text)).to eq Reek::Report::TextReport
8
- end
9
- end
10
-
11
- describe '.location_formatter' do
12
- it 'returns the correct class' do
13
- expect(described_class.location_formatter(:plain)).to eq Reek::Report::BlankLocationFormatter
14
- end
15
- end
16
-
17
- describe '.heading_formatter' do
18
- it 'returns the correct class' do
19
- expect(described_class.heading_formatter(:quiet)).to eq Reek::Report::QuietHeadingFormatter
20
- end
21
- end
22
-
23
- describe '.warning_formatter_class' do
24
- it 'returns the correct class' do
25
- expect(described_class.warning_formatter_class(:simple)).to eq Reek::Report::SimpleWarningFormatter
26
- end
27
- end
28
- end
@@ -1,56 +0,0 @@
1
- require_relative '../spec_helper'
2
- require_lib 'reek/smell_configuration'
3
-
4
- RSpec.describe Reek::SmellConfiguration do
5
- context 'when overriding default configs' do
6
- let(:base_config) do
7
- {
8
- 'accept' => ['_'],
9
- 'enabled' => true,
10
- 'exclude' => [],
11
- 'reject' => [/^.$/, /[0-9]$/, /[A-Z]/]
12
- }
13
- end
14
-
15
- let(:smell_config) { described_class.new(base_config) }
16
-
17
- it { expect(smell_config.merge({})).to eq(base_config) }
18
- it { expect(smell_config.merge('enabled' => true)).to eq(base_config) }
19
- it { expect(smell_config.merge('exclude' => [])).to eq(base_config) }
20
- it { expect(smell_config.merge('accept' => ['_'])).to eq(base_config) }
21
-
22
- it do
23
- updated = smell_config.merge('reject' => [/^.$/, /[0-9]$/, /[A-Z]/])
24
- expect(updated).to eq(base_config)
25
- end
26
-
27
- it do
28
- updated = smell_config.merge('accept' => ['_'], 'enabled' => true)
29
- expect(updated).to eq(base_config)
30
- end
31
-
32
- it 'overrides single values' do
33
- updated = smell_config.merge('enabled' => false)
34
- expect(updated).to eq('accept' => ['_'],
35
- 'enabled' => false,
36
- 'exclude' => [],
37
- 'reject' => [/^.$/, /[0-9]$/, /[A-Z]/])
38
- end
39
-
40
- it 'overrides arrays of values' do
41
- updated = smell_config.merge('reject' => [/^.$/, /[3-9]$/])
42
- expect(updated).to eq('accept' => ['_'],
43
- 'enabled' => true,
44
- 'exclude' => [],
45
- 'reject' => [/^.$/, /[3-9]$/])
46
- end
47
-
48
- it 'overrides multiple values' do
49
- updated = smell_config.merge('accept' => [/[A-Z]$/], 'enabled' => false)
50
- expect(updated).to eq('accept' => [/[A-Z]$/],
51
- 'enabled' => false,
52
- 'exclude' => [],
53
- 'reject' => [/^.$/, /[0-9]$/, /[A-Z]/])
54
- end
55
- end
56
- end
@@ -1,197 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/smell_detectors/attribute'
3
-
4
- RSpec.describe Reek::SmellDetectors::Attribute do
5
- it 'reports the right values' do
6
- src = <<-RUBY
7
- class Alfa
8
- attr_writer :bravo
9
- end
10
- RUBY
11
-
12
- expect(src).to reek_of(:Attribute,
13
- lines: [2],
14
- context: 'Alfa#bravo',
15
- message: 'is a writable attribute')
16
- end
17
-
18
- it 'does count all occurences' do
19
- src = <<-RUBY
20
- class Alfa
21
- attr_writer :bravo
22
- attr_writer :charlie
23
- end
24
- RUBY
25
-
26
- expect(src).
27
- to reek_of(:Attribute, lines: [2], context: 'Alfa#bravo').
28
- and reek_of(:Attribute, lines: [3], context: 'Alfa#charlie')
29
- end
30
-
31
- it 'records nothing with no attributes' do
32
- src = <<-RUBY
33
- class Alfa
34
- end
35
- RUBY
36
-
37
- expect(src).not_to reek_of(:Attribute)
38
- end
39
-
40
- context 'with attributes' do
41
- it 'records nothing for attribute readers' do
42
- src = <<-RUBY
43
- class Alfa
44
- attr :bravo
45
- attr_reader :charlie
46
- end
47
- RUBY
48
-
49
- expect(src).not_to reek_of(:Attribute)
50
- end
51
-
52
- it 'records writer attribute' do
53
- src = <<-RUBY
54
- class Alfa
55
- attr_writer :bravo
56
- end
57
- RUBY
58
-
59
- expect(src).to reek_of(:Attribute, context: 'Alfa#bravo')
60
- end
61
-
62
- it 'does not record writer attribute if suppressed with a preceding code comment' do
63
- src = <<-RUBY
64
- class Alfa
65
- # :reek:Attribute
66
- attr_writer :bravo
67
- end
68
- RUBY
69
-
70
- expect(src).not_to reek_of(:Attribute)
71
- end
72
-
73
- it 'records attr_writer attribute in a module' do
74
- src = <<-RUBY
75
- module Mod
76
- attr_writer :bravo
77
- end
78
- RUBY
79
-
80
- expect(src).to reek_of(:Attribute)
81
- end
82
-
83
- it 'records accessor attribute' do
84
- src = <<-RUBY
85
- class Alfa
86
- attr_accessor :bravo
87
- end
88
- RUBY
89
-
90
- expect(src).to reek_of(:Attribute)
91
- end
92
-
93
- it 'records attr defining a writer' do
94
- src = <<-RUBY
95
- class Alfa
96
- attr :bravo, true
97
- end
98
- RUBY
99
-
100
- expect(src).to reek_of(:Attribute)
101
- end
102
-
103
- it "doesn't record protected attributes" do
104
- src = <<-RUBY
105
- class Alfa
106
- protected
107
- attr_writer :alfa
108
- attr_accessor :bravo
109
- attr :charlie
110
- attr :delta, true
111
- attr_reader :echo
112
- end
113
- RUBY
114
-
115
- expect(src).not_to reek_of(:Attribute)
116
- end
117
-
118
- it "doesn't record private attributes" do
119
- src = <<-RUBY
120
- class Alfa
121
- private
122
- attr_writer :alfa
123
- attr_accessor :bravo
124
- attr :charlie
125
- attr :delta, true
126
- attr_reader :echo
127
- end
128
- RUBY
129
-
130
- expect(src).not_to reek_of(:Attribute)
131
- end
132
-
133
- it 'records attr_writer defined in public section' do
134
- src = <<-RUBY
135
- class Alfa
136
- private
137
- public
138
- attr_writer :bravo
139
- end
140
- RUBY
141
-
142
- expect(src).to reek_of(:Attribute)
143
- end
144
-
145
- it 'records attr_writer after switching visbility to public' do
146
- src = <<-RUBY
147
- class Alfa
148
- private
149
- attr_writer :bravo
150
- public :bravo
151
- end
152
- RUBY
153
-
154
- expect(src).to reek_of(:Attribute)
155
- end
156
-
157
- it 'resets visibility in new contexts' do
158
- src = <<-RUBY
159
- class Alfa
160
- private
161
- attr_writer :bravo
162
- end
163
-
164
- class Charlie
165
- attr_writer :delta
166
- end
167
- RUBY
168
-
169
- expect(src).to reek_of(:Attribute, context: 'Charlie#delta')
170
- end
171
-
172
- it 'records attr_writer defining a class attribute' do
173
- src = <<-RUBY
174
- class Alfa
175
- class << self
176
- attr_writer :bravo
177
- end
178
- end
179
- RUBY
180
-
181
- expect(src).to reek_of(:Attribute)
182
- end
183
-
184
- it 'does not record private class attributes' do
185
- src = <<-RUBY
186
- class Alfa
187
- class << self
188
- private
189
- attr_writer :bravo
190
- end
191
- end
192
- RUBY
193
-
194
- expect(src).not_to reek_of(:Attribute)
195
- end
196
- end
197
- end
@@ -1,50 +0,0 @@
1
- require_relative '../../spec_helper'
2
- require_lib 'reek/smell_detectors/base_detector'
3
- require_lib 'reek/smell_detectors/duplicate_method_call'
4
-
5
- RSpec.describe Reek::SmellDetectors::BaseDetector do
6
- describe '.todo_configuration_for' do
7
- it 'returns exclusion configuration for the given smells' do
8
- smell = build_smell_warning(smell_type: 'Foo', context: 'Foo#bar')
9
- result = described_class.todo_configuration_for([smell])
10
- expect(result).to eq('BaseDetector' => { 'exclude' => ['Foo#bar'] })
11
- end
12
-
13
- it 'merges identical contexts' do
14
- smell = build_smell_warning(smell_type: 'Foo', context: 'Foo#bar')
15
- result = described_class.todo_configuration_for([smell, smell])
16
- expect(result).to eq('BaseDetector' => { 'exclude' => ['Foo#bar'] })
17
- end
18
-
19
- context 'with default exclusions present' do
20
- let(:subclass) { Reek::SmellDetectors::TooManyStatements }
21
-
22
- it 'includes default exclusions' do
23
- smell = build_smell_warning(smell_type: 'TooManyStatements', context: 'Foo#bar')
24
- result = subclass.todo_configuration_for([smell])
25
-
26
- aggregate_failures do
27
- expect(subclass.default_config['exclude']).to eq ['initialize']
28
- expect(result).to eq('TooManyStatements' => { 'exclude' => ['initialize', 'Foo#bar'] })
29
- end
30
- end
31
- end
32
- end
33
-
34
- describe '.to_detector' do
35
- it 'returns the right detector' do
36
- expect(described_class.to_detector('DuplicateMethodCall')).to eq(Reek::SmellDetectors::DuplicateMethodCall)
37
- end
38
-
39
- it 'raise NameError for an invalid detector name' do
40
- expect { described_class.to_detector('Unknown') }.to raise_error(NameError)
41
- end
42
- end
43
-
44
- describe '.configuration_keys' do
45
- it 'returns the right keys' do
46
- expected_keys = Reek::SmellDetectors::DuplicateMethodCall.configuration_keys.to_a
47
- expect(expected_keys).to eq([:enabled, :exclude, :max_calls, :allow_calls])
48
- end
49
- end
50
- end