reek 4.7.3 → 5.0.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 (248) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -12
  3. data/.rubocop.yml +18 -3
  4. data/.simplecov +1 -0
  5. data/.travis.yml +3 -4
  6. data/.yardopts +1 -1
  7. data/CHANGELOG.md +45 -0
  8. data/Gemfile +4 -4
  9. data/README.md +134 -104
  10. data/Rakefile +16 -3
  11. data/bin/reek +1 -3
  12. data/docs/API.md +2 -9
  13. data/docs/Basic-Smell-Options.md +51 -11
  14. data/docs/Code-Smells.md +1 -1
  15. data/docs/Command-Line-Options.md +14 -4
  16. data/docs/Duplicate-Method-Call.md +49 -1
  17. data/docs/Feature-Envy.md +44 -0
  18. data/docs/How-To-Write-New-Detectors.md +2 -3
  19. data/docs/Instance-Variable-Assumption.md +1 -1
  20. data/docs/{Prima-Donna-Method.md → Missing-Safe-Method.md} +11 -9
  21. data/docs/Rake-Task.md +1 -1
  22. data/docs/Reek-4-to-Reek-5-migration.md +193 -0
  23. data/docs/Reek-Driven-Development.md +1 -1
  24. data/docs/Uncommunicative-Method-Name.md +45 -6
  25. data/docs/Uncommunicative-Module-Name.md +49 -7
  26. data/docs/Uncommunicative-Parameter-Name.md +43 -5
  27. data/docs/Uncommunicative-Variable-Name.md +73 -2
  28. data/docs/Unused-Private-Method.md +2 -2
  29. data/docs/defaults.reek.yml +129 -0
  30. data/docs/yard_plugin.rb +1 -0
  31. data/features/command_line_interface/basic_usage.feature +2 -2
  32. data/features/command_line_interface/options.feature +46 -4
  33. data/features/command_line_interface/show_progress.feature +4 -4
  34. data/features/command_line_interface/smell_selection.feature +1 -1
  35. data/features/command_line_interface/smells_count.feature +6 -6
  36. data/features/command_line_interface/stdin.feature +30 -8
  37. data/features/configuration_files/accept_setting.feature +45 -28
  38. data/features/configuration_files/directory_specific_directives.feature +78 -73
  39. data/features/configuration_files/exclude_directives.feature +11 -10
  40. data/features/configuration_files/exclude_paths_directives.feature +4 -4
  41. data/features/configuration_files/masking_smells.feature +38 -9
  42. data/features/configuration_files/mix_accept_reject_setting.feature +31 -28
  43. data/features/configuration_files/reject_setting.feature +52 -41
  44. data/features/configuration_files/schema_validation.feature +59 -0
  45. data/features/configuration_files/unused_private_method.feature +18 -16
  46. data/features/configuration_loading.feature +53 -10
  47. data/features/configuration_via_source_comments/erroneous_source_comments.feature +2 -2
  48. data/features/configuration_via_source_comments/well_formed_source_comments.feature +2 -2
  49. data/features/locales.feature +2 -2
  50. data/features/rake_task/rake_task.feature +15 -15
  51. data/features/reports/json.feature +3 -3
  52. data/features/reports/reports.feature +34 -34
  53. data/features/reports/yaml.feature +3 -3
  54. data/features/rspec_matcher.feature +9 -1
  55. data/features/samples.feature +287 -287
  56. data/features/step_definitions/reek_steps.rb +4 -0
  57. data/features/step_definitions/sample_file_steps.rb +9 -4
  58. data/features/support/env.rb +2 -2
  59. data/features/todo_list.feature +26 -23
  60. data/lib/reek/ast/node.rb +40 -55
  61. data/lib/reek/ast/object_refs.rb +1 -1
  62. data/lib/reek/ast/reference_collector.rb +2 -4
  63. data/lib/reek/ast/sexp_extensions/case.rb +1 -1
  64. data/lib/reek/ast/sexp_extensions/if.rb +8 -1
  65. data/lib/reek/ast/sexp_extensions/logical_operators.rb +1 -1
  66. data/lib/reek/ast/sexp_extensions/methods.rb +4 -6
  67. data/lib/reek/cli/application.rb +4 -3
  68. data/lib/reek/cli/command/report_command.rb +1 -2
  69. data/lib/reek/cli/command/todo_list_command.rb +8 -8
  70. data/lib/reek/cli/options.rb +29 -14
  71. data/lib/reek/cli/silencer.rb +14 -3
  72. data/lib/reek/code_comment.rb +14 -16
  73. data/lib/reek/configuration/app_configuration.rb +32 -28
  74. data/lib/reek/configuration/configuration_converter.rb +110 -0
  75. data/lib/reek/configuration/configuration_file_finder.rb +15 -40
  76. data/lib/reek/configuration/configuration_validator.rb +12 -23
  77. data/lib/reek/configuration/default_directive.rb +17 -3
  78. data/lib/reek/configuration/directory_directives.rb +17 -11
  79. data/lib/reek/configuration/excluded_paths.rb +1 -1
  80. data/lib/reek/configuration/rake_task_converter.rb +29 -0
  81. data/lib/reek/configuration/schema.yml +210 -0
  82. data/lib/reek/configuration/schema_validator.rb +38 -0
  83. data/lib/reek/context/attribute_context.rb +1 -1
  84. data/lib/reek/context/code_context.rb +8 -11
  85. data/lib/reek/context/method_context.rb +7 -12
  86. data/lib/reek/context/module_context.rb +4 -4
  87. data/lib/reek/context_builder.rb +11 -11
  88. data/lib/reek/detector_repository.rb +6 -0
  89. data/lib/reek/documentation_link.rb +28 -0
  90. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +13 -12
  91. data/lib/reek/errors/bad_detector_in_comment_error.rb +11 -10
  92. data/lib/reek/errors/base_error.rb +3 -0
  93. data/lib/reek/errors/config_file_error.rb +11 -0
  94. data/lib/reek/errors/encoding_error.rb +16 -11
  95. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +11 -10
  96. data/lib/reek/errors/incomprehensible_source_error.rb +20 -22
  97. data/lib/reek/errors/syntax_error.rb +41 -0
  98. data/lib/reek/examiner.rb +19 -25
  99. data/lib/reek/logging_error_handler.rb +7 -5
  100. data/lib/reek/rake/task.rb +3 -3
  101. data/lib/reek/report/base_report.rb +8 -12
  102. data/lib/reek/report/code_climate/code_climate_configuration.rb +1 -1
  103. data/lib/reek/report/code_climate/code_climate_configuration.yml +6 -10
  104. data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
  105. data/lib/reek/report/heading_formatter.rb +54 -0
  106. data/lib/reek/report/json_report.rb +1 -1
  107. data/lib/reek/report/location_formatter.rb +40 -0
  108. data/lib/reek/report/progress_formatter.rb +79 -0
  109. data/lib/reek/report/simple_warning_formatter.rb +34 -0
  110. data/lib/reek/report/text_report.rb +1 -2
  111. data/lib/reek/report/xml_report.rb +3 -3
  112. data/lib/reek/report/yaml_report.rb +1 -1
  113. data/lib/reek/report.rb +15 -10
  114. data/lib/reek/smell_configuration.rb +2 -2
  115. data/lib/reek/smell_detectors/attribute.rb +0 -1
  116. data/lib/reek/smell_detectors/base_detector.rb +9 -12
  117. data/lib/reek/smell_detectors/boolean_parameter.rb +0 -1
  118. data/lib/reek/smell_detectors/class_variable.rb +3 -11
  119. data/lib/reek/smell_detectors/control_parameter.rb +17 -32
  120. data/lib/reek/smell_detectors/data_clump.rb +3 -4
  121. data/lib/reek/smell_detectors/duplicate_method_call.rb +6 -7
  122. data/lib/reek/smell_detectors/feature_envy.rb +1 -1
  123. data/lib/reek/smell_detectors/instance_variable_assumption.rb +1 -10
  124. data/lib/reek/smell_detectors/irresponsible_module.rb +0 -1
  125. data/lib/reek/smell_detectors/long_parameter_list.rb +1 -2
  126. data/lib/reek/smell_detectors/long_yield_list.rb +2 -3
  127. data/lib/reek/smell_detectors/manual_dispatch.rb +3 -3
  128. data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +6 -7
  129. data/lib/reek/smell_detectors/module_initialize.rb +1 -2
  130. data/lib/reek/smell_detectors/nested_iterators.rb +6 -6
  131. data/lib/reek/smell_detectors/nil_check.rb +0 -1
  132. data/lib/reek/smell_detectors/repeated_conditional.rb +3 -4
  133. data/lib/reek/smell_detectors/subclassed_from_core_class.rb +0 -1
  134. data/lib/reek/smell_detectors/too_many_constants.rb +2 -3
  135. data/lib/reek/smell_detectors/too_many_instance_variables.rb +1 -2
  136. data/lib/reek/smell_detectors/too_many_methods.rb +1 -2
  137. data/lib/reek/smell_detectors/too_many_statements.rb +1 -2
  138. data/lib/reek/smell_detectors/uncommunicative_method_name.rb +2 -3
  139. data/lib/reek/smell_detectors/uncommunicative_module_name.rb +2 -3
  140. data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +2 -3
  141. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +6 -7
  142. data/lib/reek/smell_detectors/unused_parameters.rb +0 -1
  143. data/lib/reek/smell_detectors/unused_private_method.rb +0 -1
  144. data/lib/reek/smell_detectors/utility_function.rb +2 -3
  145. data/lib/reek/smell_detectors.rb +1 -2
  146. data/lib/reek/smell_warning.rb +15 -8
  147. data/lib/reek/source/source_code.rb +50 -72
  148. data/lib/reek/source/source_locator.rb +7 -7
  149. data/lib/reek/spec/should_reek.rb +2 -2
  150. data/lib/reek/spec/should_reek_of.rb +9 -16
  151. data/lib/reek/spec/should_reek_only_of.rb +4 -4
  152. data/lib/reek/spec.rb +6 -6
  153. data/lib/reek/tree_dresser.rb +5 -5
  154. data/lib/reek/version.rb +1 -1
  155. data/reek.gemspec +5 -5
  156. data/samples/checkstyle.xml +1 -1
  157. data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +29 -0
  158. data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +30 -0
  159. data/samples/configuration/full_configuration.reek +8 -4
  160. data/samples/configuration/full_mask.reek +5 -4
  161. data/samples/configuration/partial_mask.reek +3 -2
  162. data/samples/configuration/regular_configuration/.reek.yml +4 -0
  163. data/samples/paths.rb +5 -4
  164. data/samples/source_with_hidden_directories/.hidden/hidden.rb +1 -0
  165. data/samples/source_with_hidden_directories/not_hidden.rb +1 -0
  166. data/spec/factories/factories.rb +2 -13
  167. data/spec/reek/ast/node_spec.rb +103 -10
  168. data/spec/reek/ast/reference_collector_spec.rb +1 -1
  169. data/spec/reek/ast/sexp_extensions_spec.rb +2 -2
  170. data/spec/reek/cli/application_spec.rb +50 -38
  171. data/spec/reek/cli/command/todo_list_command_spec.rb +6 -4
  172. data/spec/reek/cli/silencer_spec.rb +28 -0
  173. data/spec/reek/code_comment_spec.rb +31 -38
  174. data/spec/reek/configuration/app_configuration_spec.rb +46 -33
  175. data/spec/reek/configuration/configuration_file_finder_spec.rb +133 -49
  176. data/spec/reek/configuration/default_directive_spec.rb +1 -1
  177. data/spec/reek/configuration/directory_directives_spec.rb +6 -7
  178. data/spec/reek/configuration/excluded_paths_spec.rb +6 -6
  179. data/spec/reek/configuration/rake_task_converter_spec.rb +33 -0
  180. data/spec/reek/configuration/schema_validator_spec.rb +165 -0
  181. data/spec/reek/context/code_context_spec.rb +60 -96
  182. data/spec/reek/context/ghost_context_spec.rb +1 -1
  183. data/spec/reek/context/root_context_spec.rb +1 -1
  184. data/spec/reek/documentation_link_spec.rb +20 -0
  185. data/spec/reek/errors/base_error_spec.rb +13 -0
  186. data/spec/reek/examiner_spec.rb +100 -30
  187. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +82 -80
  188. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
  189. data/spec/reek/report/json_report_spec.rb +13 -46
  190. data/spec/reek/report/{formatter/location_formatter_spec.rb → location_formatter_spec.rb} +5 -5
  191. data/spec/reek/report/{formatter/progress_formatter_spec.rb → progress_formatter_spec.rb} +4 -4
  192. data/spec/reek/report/text_report_spec.rb +4 -4
  193. data/spec/reek/report/xml_report_spec.rb +3 -3
  194. data/spec/reek/report/yaml_report_spec.rb +9 -38
  195. data/spec/reek/report_spec.rb +3 -3
  196. data/spec/reek/smell_detectors/boolean_parameter_spec.rb +2 -2
  197. data/spec/reek/smell_detectors/class_variable_spec.rb +26 -32
  198. data/spec/reek/smell_detectors/control_parameter_spec.rb +34 -4
  199. data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +3 -3
  200. data/spec/reek/smell_detectors/feature_envy_spec.rb +47 -2
  201. data/spec/reek/smell_detectors/{prima_donna_method_spec.rb → missing_safe_method_spec.rb} +9 -9
  202. data/spec/reek/smell_detectors/module_initialize_spec.rb +14 -0
  203. data/spec/reek/smell_detectors/nested_iterators_spec.rb +1 -1
  204. data/spec/reek/smell_detectors/too_many_constants_spec.rb +3 -3
  205. data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +1 -1
  206. data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +6 -6
  207. data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +6 -4
  208. data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +6 -4
  209. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +9 -9
  210. data/spec/reek/smell_detectors/unused_parameters_spec.rb +3 -3
  211. data/spec/reek/smell_detectors/unused_private_method_spec.rb +10 -10
  212. data/spec/reek/smell_detectors/utility_function_spec.rb +5 -5
  213. data/spec/reek/smell_warning_spec.rb +12 -8
  214. data/spec/reek/source/source_code_spec.rb +17 -43
  215. data/spec/reek/source/source_locator_spec.rb +17 -17
  216. data/spec/reek/spec/should_reek_of_spec.rb +7 -11
  217. data/spec/reek/spec/should_reek_only_of_spec.rb +2 -2
  218. data/spec/reek/spec/should_reek_spec.rb +3 -3
  219. data/spec/reek/spec/smell_matcher_spec.rb +3 -3
  220. data/spec/reek/tree_dresser_spec.rb +12 -17
  221. data/spec/spec_helper.rb +6 -17
  222. data/tasks/configuration.rake +8 -5
  223. metadata +71 -41
  224. data/defaults.reek +0 -131
  225. data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
  226. data/lib/reek/report/formatter/heading_formatter.rb +0 -52
  227. data/lib/reek/report/formatter/location_formatter.rb +0 -42
  228. data/lib/reek/report/formatter/progress_formatter.rb +0 -81
  229. data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
  230. data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -36
  231. data/lib/reek/report/formatter.rb +0 -33
  232. data/lib/reek/smell_detectors/syntax.rb +0 -37
  233. data/samples/configuration/non_public_modifiers_mask.reek +0 -3
  234. data/samples/smelly_with_inline_mask.rb +0 -8
  235. data/samples/smelly_with_modifiers.rb +0 -12
  236. data/samples/source_with_hidden_directories/.hidden/uncommunicative_method_name.rb +0 -5
  237. data/samples/source_with_non_ruby_files/uncommunicative_parameter_name.rb +0 -6
  238. data/spec/reek/smell_detectors/syntax_spec.rb +0 -17
  239. /data/{samples/configuration/more_than_one_configuration_file/regular.reek → .reek.yml} +0 -0
  240. /data/samples/{clean.rb → clean_source/clean.rb} +0 -0
  241. /data/samples/{exceptions.reek → configuration/home/home.reek.yml} +0 -0
  242. /data/samples/configuration/{more_than_one_configuration_file/todo.reek → regular_configuration/empty_sub_directory/.gitignore} +0 -0
  243. /data/samples/{configuration/single_configuration_file/.reek → no_config_file/.keep} +0 -0
  244. /data/samples/{inline.rb → smelly_source/inline.rb} +0 -0
  245. /data/samples/{optparse.rb → smelly_source/optparse.rb} +0 -0
  246. /data/samples/{redcloth.rb → smelly_source/redcloth.rb} +0 -0
  247. /data/samples/{smelly.rb → smelly_source/smelly.rb} +0 -0
  248. /data/samples/{source_with_hidden_directories/uncommunicative_parameter_name.rb → source_with_non_ruby_files/ruby.rb} +0 -0
@@ -5,42 +5,42 @@ RSpec.describe Reek::Report::CodeClimateFingerprint do
5
5
  describe '#compute' do
6
6
  let(:computed) { described_class.new(warning).compute }
7
7
 
8
- shared_examples_for 'computes a fingerprint with no parameters' do
8
+ context 'when fingerprinting a warning with no parameters' do
9
9
  let(:expected_fingerprint) { 'e68badd29db51c92363a7c6a2438d722' }
10
10
  let(:warning) do
11
- FactoryGirl.build(:smell_warning,
12
- smell_detector: Reek::SmellDetectors::UtilityFunction.new,
13
- context: 'alfa',
14
- message: "doesn't depend on instance state (maybe move it to another class?)",
15
- lines: lines,
16
- source: 'a/ruby/source/file.rb')
11
+ build(:smell_warning,
12
+ smell_detector: Reek::SmellDetectors::UtilityFunction.new,
13
+ context: 'alfa',
14
+ message: "doesn't depend on instance state (maybe move it to another class?)",
15
+ lines: lines,
16
+ source: 'a/ruby/source/file.rb')
17
17
  end
18
18
 
19
- it 'computes the fingerprint' do
20
- expect(computed).to eq expected_fingerprint
21
- end
22
- end
23
-
24
- context 'with code at a specific location' do
25
- let(:lines) { [1] }
19
+ context 'with code at a specific location' do
20
+ let(:lines) { [1] }
26
21
 
27
- it_behaves_like 'computes a fingerprint with no parameters'
28
- end
22
+ it 'computes the fingerprint' do
23
+ expect(computed).to eq expected_fingerprint
24
+ end
25
+ end
29
26
 
30
- context 'with code at a different location' do
31
- let(:lines) { [5] }
27
+ context 'with code at a different location' do
28
+ let(:lines) { [5] }
32
29
 
33
- it_behaves_like 'computes a fingerprint with no parameters'
30
+ it 'computes the same fingerprint' do
31
+ expect(computed).to eq expected_fingerprint
32
+ end
33
+ end
34
34
  end
35
35
 
36
36
  context 'when the fingerprint should not be computed' do
37
37
  let(:warning) do
38
- FactoryGirl.build(:smell_warning,
39
- smell_detector: Reek::SmellDetectors::ManualDispatch.new,
40
- context: 'Alfa#bravo',
41
- message: 'manually dispatches method call',
42
- lines: [4],
43
- source: 'a/ruby/source/file.rb')
38
+ build(:smell_warning,
39
+ smell_detector: Reek::SmellDetectors::ManualDispatch.new,
40
+ context: 'Alfa#bravo',
41
+ message: 'manually dispatches method call',
42
+ lines: [4],
43
+ source: 'a/ruby/source/file.rb')
44
44
  end
45
45
 
46
46
  it 'returns nil' do
@@ -48,77 +48,79 @@ RSpec.describe Reek::Report::CodeClimateFingerprint do
48
48
  end
49
49
  end
50
50
 
51
- shared_examples_for 'computes a fingerprint with identifying parameters' do
51
+ context 'when the smell warning has only identifying parameters' do
52
52
  let(:warning) do
53
- FactoryGirl.build(:smell_warning,
54
- smell_detector: Reek::SmellDetectors::ClassVariable.new,
55
- context: 'Alfa',
56
- message: "declares the class variable '@@#{name}'",
57
- lines: [4],
58
- parameters: { name: "@@#{name}" },
59
- source: 'a/ruby/source/file.rb')
53
+ build(:smell_warning,
54
+ smell_detector: Reek::SmellDetectors::ClassVariable.new,
55
+ context: 'Alfa',
56
+ message: "declares the class variable '@@#{name}'",
57
+ lines: [4],
58
+ parameters: { name: "@@#{name}" },
59
+ source: 'a/ruby/source/file.rb')
60
60
  end
61
61
 
62
- it 'computes the fingerprint' do
63
- expect(computed).to eq expected_fingerprint
64
- end
65
- end
62
+ context 'when the name is one thing' do
63
+ let(:name) { 'bravo' }
64
+ let(:expected_fingerprint) { '9c3fd378178118a67e9509f87cae24f9' }
66
65
 
67
- context 'when the name is one thing it has one fingerprint' do
68
- let(:name) { 'bravo' }
69
- let(:expected_fingerprint) { '9c3fd378178118a67e9509f87cae24f9' }
70
-
71
- it_behaves_like 'computes a fingerprint with identifying parameters'
72
- end
66
+ it 'computes the fingerprint' do
67
+ expect(computed).to eq expected_fingerprint
68
+ end
69
+ end
73
70
 
74
- context 'when the name is another thing it has another fingerprint' do
75
- let(:name) { 'echo' }
76
- let(:expected_fingerprint) { 'd2a6d2703ce04cca65e7300b7de4b89f' }
71
+ context 'when the name is another thing' do
72
+ let(:name) { 'echo' }
73
+ let(:expected_fingerprint) { 'd2a6d2703ce04cca65e7300b7de4b89f' }
77
74
 
78
- it_behaves_like 'computes a fingerprint with identifying parameters'
75
+ it 'computes another fingerprint' do
76
+ expect(computed).to eq expected_fingerprint
77
+ end
78
+ end
79
79
  end
80
80
 
81
- shared_examples_for 'computes a fingerprint with identifying and non-identifying parameters' do
81
+ context 'when the smell warning has identifying and non-identifying parameters' do
82
82
  let(:warning) do
83
- FactoryGirl.build(:smell_warning,
84
- smell_detector: Reek::SmellDetectors::DuplicateMethodCall.new,
85
- context: "Alfa##{name}",
86
- message: "calls '#{name}' #{count} times",
87
- lines: lines,
88
- parameters: { name: "@@#{name}", count: count },
89
- source: 'a/ruby/source/file.rb')
83
+ build(:smell_warning,
84
+ smell_detector: Reek::SmellDetectors::DuplicateMethodCall.new,
85
+ context: "Alfa##{name}",
86
+ message: "calls '#{name}' #{count} times",
87
+ lines: lines,
88
+ parameters: { name: "@@#{name}", count: count },
89
+ source: 'a/ruby/source/file.rb')
90
90
  end
91
91
 
92
- it 'computes the fingerprint' do
93
- expect(computed).to eq expected_fingerprint
94
- end
95
- end
96
-
97
- context 'when the parameters are provided' do
98
- let(:name) { 'bravo' }
99
- let(:count) { 5 }
100
- let(:lines) { [1, 7, 10, 13, 15] }
101
- let(:expected_fingerprint) { '238733f4f51ba5473dcbe94a43ec5400' }
92
+ context 'when the parameters are provided' do
93
+ let(:name) { 'bravo' }
94
+ let(:count) { 5 }
95
+ let(:lines) { [1, 7, 10, 13, 15] }
96
+ let(:expected_fingerprint) { '238733f4f51ba5473dcbe94a43ec5400' }
102
97
 
103
- it_behaves_like 'computes a fingerprint with identifying and non-identifying parameters'
104
- end
98
+ it 'computes the fingerprint' do
99
+ expect(computed).to eq expected_fingerprint
100
+ end
101
+ end
105
102
 
106
- context 'when the non-identifying parameters change, it computes the same fingerprint' do
107
- let(:name) { 'bravo' }
108
- let(:count) { 9 }
109
- let(:lines) { [1, 7, 10, 13, 15, 17, 19, 20, 25] }
110
- let(:expected_fingerprint) { '238733f4f51ba5473dcbe94a43ec5400' }
103
+ context 'when the non-identifying parameters change' do
104
+ let(:name) { 'bravo' }
105
+ let(:count) { 9 }
106
+ let(:lines) { [1, 7, 10, 13, 15, 17, 19, 20, 25] }
107
+ let(:expected_fingerprint) { '238733f4f51ba5473dcbe94a43ec5400' }
111
108
 
112
- it_behaves_like 'computes a fingerprint with identifying and non-identifying parameters'
113
- end
109
+ it 'computes the same fingerprint' do
110
+ expect(computed).to eq expected_fingerprint
111
+ end
112
+ end
114
113
 
115
- context 'but when the identifying parameters change, it computes a different fingerprint' do
116
- let(:name) { 'echo' }
117
- let(:count) { 5 }
118
- let(:lines) { [1, 7, 10, 13, 15] }
119
- let(:expected_fingerprint) { 'e0c35e9223cc19bdb9a04fb3e60573e1' }
114
+ context 'when the identifying parameters change' do
115
+ let(:name) { 'echo' }
116
+ let(:count) { 5 }
117
+ let(:lines) { [1, 7, 10, 13, 15] }
118
+ let(:expected_fingerprint) { 'e0c35e9223cc19bdb9a04fb3e60573e1' }
120
119
 
121
- it_behaves_like 'computes a fingerprint with identifying and non-identifying parameters'
120
+ it 'computes a different fingerprint' do
121
+ expect(computed).to eq expected_fingerprint
122
+ end
123
+ end
122
124
  end
123
125
  end
124
126
  end
@@ -4,12 +4,12 @@ require_lib 'reek/report/code_climate/code_climate_formatter'
4
4
  RSpec.describe Reek::Report::CodeClimateFormatter do
5
5
  describe '#render' do
6
6
  let(:warning) do
7
- FactoryGirl.build(:smell_warning,
8
- smell_detector: Reek::SmellDetectors::UtilityFunction.new,
9
- context: 'context foo',
10
- message: 'message bar',
11
- lines: [1, 2],
12
- source: 'a/ruby/source/file.rb')
7
+ build(:smell_warning,
8
+ smell_detector: Reek::SmellDetectors::UtilityFunction.new,
9
+ context: 'context foo',
10
+ message: 'message bar',
11
+ lines: [1, 2],
12
+ source: 'a/ruby/source/file.rb')
13
13
  end
14
14
  let(:rendered) { described_class.new(warning).render }
15
15
  let(:json) { JSON.parse rendered.chop }
@@ -1,7 +1,6 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/examiner'
3
3
  require_lib 'reek/report/json_report'
4
- require_lib 'reek/report/formatter'
5
4
 
6
5
  require 'json'
7
6
  require 'stringio'
@@ -34,58 +33,26 @@ RSpec.describe Reek::Report::JSONReport do
34
33
  expected = JSON.parse <<-EOS
35
34
  [
36
35
  {
37
- "context": "simple",
38
- "lines": [1],
39
- "message": "has the parameter name 'a'",
40
- "smell_type": "UncommunicativeParameterName",
41
- "source": "string",
42
- "name": "a"
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
43
  },
44
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"
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"
50
51
  }
51
52
  ]
52
53
  EOS
53
54
 
54
55
  expect(result).to eq expected
55
56
  end
56
-
57
- context 'with link formatter' do
58
- let(:options) { { warning_formatter: Reek::Report::Formatter::WikiLinkWarningFormatter.new } }
59
-
60
- it 'prints documentation links' do
61
- out = StringIO.new
62
- instance.show(out)
63
- out.rewind
64
- result = JSON.parse(out.read)
65
- expected = JSON.parse <<-EOS
66
- [
67
- {
68
- "context": "simple",
69
- "lines": [1],
70
- "message": "has the parameter name 'a'",
71
- "smell_type": "UncommunicativeParameterName",
72
- "source": "string",
73
- "name": "a",
74
- "wiki_link": "https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Parameter-Name.md"
75
- },
76
- {
77
- "context": "simple",
78
- "lines": [1],
79
- "message": "doesn't depend on instance state (maybe move it to another class?)",
80
- "smell_type": "UtilityFunction",
81
- "source": "string",
82
- "wiki_link": "https://github.com/troessner/reek/blob/master/docs/Utility-Function.md"
83
- }
84
- ]
85
- EOS
86
-
87
- expect(result).to eq expected
88
- end
89
- end
90
57
  end
91
58
  end
@@ -1,7 +1,7 @@
1
- require_relative '../../../spec_helper'
2
- require_lib 'reek/report/formatter'
1
+ require_relative '../../spec_helper'
2
+ require_lib 'reek/report/location_formatter'
3
3
 
4
- RSpec.describe Reek::Report::Formatter::BlankLocationFormatter do
4
+ RSpec.describe Reek::Report::BlankLocationFormatter do
5
5
  let(:warning) { build(:smell_warning, lines: [11, 9, 250, 100]) }
6
6
 
7
7
  describe '.format' do
@@ -11,7 +11,7 @@ RSpec.describe Reek::Report::Formatter::BlankLocationFormatter do
11
11
  end
12
12
  end
13
13
 
14
- RSpec.describe Reek::Report::Formatter::DefaultLocationFormatter do
14
+ RSpec.describe Reek::Report::DefaultLocationFormatter do
15
15
  let(:warning) { build(:smell_warning, lines: [11, 9, 250, 100]) }
16
16
 
17
17
  describe '.format' do
@@ -21,7 +21,7 @@ RSpec.describe Reek::Report::Formatter::DefaultLocationFormatter do
21
21
  end
22
22
  end
23
23
 
24
- RSpec.describe Reek::Report::Formatter::SingleLineLocationFormatter do
24
+ RSpec.describe Reek::Report::SingleLineLocationFormatter do
25
25
  let(:warning) { build(:smell_warning, lines: [11, 9, 250, 100]) }
26
26
 
27
27
  describe '.format' do
@@ -1,7 +1,7 @@
1
- require_relative '../../../spec_helper'
2
- require_lib 'reek/report/formatter/progress_formatter'
1
+ require_relative '../../spec_helper'
2
+ require_lib 'reek/report/progress_formatter'
3
3
 
4
- RSpec.describe Reek::Report::Formatter::ProgressFormatter::Dots do
4
+ RSpec.describe Reek::Report::ProgressFormatter::Dots do
5
5
  let(:sources_count) { 23 }
6
6
  let(:formatter) { described_class.new(sources_count) }
7
7
 
@@ -37,7 +37,7 @@ RSpec.describe Reek::Report::Formatter::ProgressFormatter::Dots do
37
37
  end
38
38
  end
39
39
 
40
- RSpec.describe Reek::Report::Formatter::ProgressFormatter::Quiet do
40
+ RSpec.describe Reek::Report::ProgressFormatter::Quiet do
41
41
  let(:sources_count) { 23 }
42
42
  let(:formatter) { described_class.new(sources_count) }
43
43
 
@@ -1,15 +1,15 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/examiner'
3
3
  require_lib 'reek/report/text_report'
4
- require_lib 'reek/report/formatter'
4
+ require_lib 'reek/report/heading_formatter'
5
+ require_lib 'reek/report/simple_warning_formatter'
5
6
  require 'rainbow'
6
7
 
7
8
  RSpec.describe Reek::Report::TextReport do
8
9
  let(:report_options) do
9
10
  {
10
- warning_formatter: Reek::Report::Formatter::SimpleWarningFormatter.new,
11
- report_formatter: Reek::Report::Formatter,
12
- heading_formatter: Reek::Report::Formatter::QuietHeadingFormatter
11
+ warning_formatter: Reek::Report::SimpleWarningFormatter.new,
12
+ heading_formatter: Reek::Report::QuietHeadingFormatter
13
13
  }
14
14
  end
15
15
  let(:instance) { described_class.new report_options }
@@ -5,7 +5,7 @@ require_lib 'reek/report/xml_report'
5
5
  RSpec.describe Reek::Report::XMLReport do
6
6
  let(:xml_report) { described_class.new }
7
7
 
8
- context 'empty source' do
8
+ context 'with an empty source' do
9
9
  it 'prints empty checkstyle XML' do
10
10
  xml_report.add_examiner Reek::Examiner.new('')
11
11
  xml = "<?xml version='1.0'?>\n<checkstyle/>\n"
@@ -13,10 +13,10 @@ RSpec.describe Reek::Report::XMLReport do
13
13
  end
14
14
  end
15
15
 
16
- context 'source with voliations' do
16
+ context 'with a source with violations' do
17
17
  it 'prints non-empty checkstyle XML' do
18
18
  xml_report.add_examiner Reek::Examiner.new(SMELLY_FILE)
19
- xml = SAMPLES_PATH.join('checkstyle.xml').read
19
+ xml = SAMPLES_DIR.join('checkstyle.xml').read
20
20
  xml = xml.gsub(SMELLY_FILE.to_s, SMELLY_FILE.expand_path.to_s)
21
21
  expect { xml_report.show }.to output(xml).to_stdout
22
22
  end
@@ -1,7 +1,6 @@
1
1
  require_relative '../../spec_helper'
2
2
  require_lib 'reek/examiner'
3
3
  require_lib 'reek/report/yaml_report'
4
- require_lib 'reek/report/formatter'
5
4
 
6
5
  require 'yaml'
7
6
  require 'stringio'
@@ -36,49 +35,21 @@ RSpec.describe Reek::Report::YAMLReport do
36
35
  - context: "simple"
37
36
  lines:
38
37
  - 1
39
- message: "has the parameter name 'a'"
40
- smell_type: "UncommunicativeParameterName"
41
- source: "string"
42
- name: "a"
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
43
  - context: "simple"
44
44
  lines:
45
45
  - 1
46
- message: "doesn't depend on instance state (maybe move it to another class?)"
47
- smell_type: "UtilityFunction"
48
- source: "string"
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"
49
50
  EOS
50
51
 
51
52
  expect(result).to eq expected
52
53
  end
53
- context 'with link formatter' do
54
- let(:options) { { warning_formatter: Reek::Report::Formatter::WikiLinkWarningFormatter.new } }
55
-
56
- it 'prints documentation links' do
57
- out = StringIO.new
58
- instance.show(out)
59
- out.rewind
60
- result = YAML.safe_load(out.read)
61
- expected = YAML.safe_load <<-EOS.strip_heredoc
62
- ---
63
- - context: "simple"
64
- lines:
65
- - 1
66
- message: "has the parameter name 'a'"
67
- smell_type: "UncommunicativeParameterName"
68
- source: "string"
69
- name: "a"
70
- wiki_link: "https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Parameter-Name.md"
71
- - context: "simple"
72
- lines:
73
- - 1
74
- message: "doesn't depend on instance state (maybe move it to another class?)"
75
- smell_type: "UtilityFunction"
76
- source: "string"
77
- wiki_link: "https://github.com/troessner/reek/blob/master/docs/Utility-Function.md"
78
- EOS
79
-
80
- expect(result).to eq expected
81
- end
82
- end
83
54
  end
84
55
  end
@@ -10,19 +10,19 @@ RSpec.describe Reek::Report do
10
10
 
11
11
  describe '.location_formatter' do
12
12
  it 'returns the correct class' do
13
- expect(described_class.location_formatter(:plain)).to eq Reek::Report::Formatter::BlankLocationFormatter
13
+ expect(described_class.location_formatter(:plain)).to eq Reek::Report::BlankLocationFormatter
14
14
  end
15
15
  end
16
16
 
17
17
  describe '.heading_formatter' do
18
18
  it 'returns the correct class' do
19
- expect(described_class.heading_formatter(:quiet)).to eq Reek::Report::Formatter::QuietHeadingFormatter
19
+ expect(described_class.heading_formatter(:quiet)).to eq Reek::Report::QuietHeadingFormatter
20
20
  end
21
21
  end
22
22
 
23
23
  describe '.warning_formatter_class' do
24
24
  it 'returns the correct class' do
25
- expect(described_class.warning_formatter_class(:simple)).to eq Reek::Report::Formatter::SimpleWarningFormatter
25
+ expect(described_class.warning_formatter_class(:simple)).to eq Reek::Report::SimpleWarningFormatter
26
26
  end
27
27
  end
28
28
  end
@@ -27,7 +27,7 @@ RSpec.describe Reek::SmellDetectors::BooleanParameter do
27
27
  and reek_of(:BooleanParameter, lines: [1], context: 'alfa', parameter: 'charlie')
28
28
  end
29
29
 
30
- context 'in a method' do
30
+ context 'when examining an instance method' do
31
31
  it 'reports a parameter defaulted to false' do
32
32
  src = 'def alfa(bravo = false) end'
33
33
  expect(src).to reek_of(:BooleanParameter)
@@ -70,7 +70,7 @@ RSpec.describe Reek::SmellDetectors::BooleanParameter do
70
70
  end
71
71
  end
72
72
 
73
- context 'in a singleton method' do
73
+ context 'when examining a singleton method' do
74
74
  it 'reports a parameter defaulted to true' do
75
75
  src = 'def self.alfa(bravo = true) end'
76
76
  expect(src).to reek_of(:BooleanParameter)
@@ -63,49 +63,43 @@ RSpec.describe Reek::SmellDetectors::ClassVariable do
63
63
  end
64
64
 
65
65
  ['class', 'module'].each do |scope|
66
- context "Scoped to #{scope}" do
67
- context 'set in a method' do
68
- it 'reports correctly' do
69
- src = <<-EOS
70
- #{scope} Alfa
71
- def bravo
72
- @@charlie = {}
73
- end
66
+ context "when examining a #{scope}" do
67
+ it 'reports a class variable set in a method' do
68
+ src = <<-EOS
69
+ #{scope} Alfa
70
+ def bravo
71
+ @@charlie = {}
74
72
  end
75
- EOS
73
+ end
74
+ EOS
76
75
 
77
- expect(src).to reek_of(:ClassVariable)
78
- end
76
+ expect(src).to reek_of(:ClassVariable, name: '@@charlie')
79
77
  end
80
78
 
81
- context 'used in a method' do
82
- it 'reports correctly' do
83
- src = <<-EOS
84
- #{scope} Alfa
85
- def bravo
86
- puts @@charlie
87
- end
79
+ it 'reports a class variable used in a method' do
80
+ src = <<-EOS
81
+ #{scope} Alfa
82
+ def bravo
83
+ puts @@charlie
88
84
  end
89
- EOS
85
+ end
86
+ EOS
90
87
 
91
- expect(src).to reek_of(:ClassVariable)
92
- end
88
+ expect(src).to reek_of(:ClassVariable, name: '@@charlie')
93
89
  end
94
90
 
95
- context "set in #{scope} and used in a method" do
96
- it 'reports correctly' do
97
- src = <<-EOS
98
- #{scope} Alfa
99
- @@bravo = 42
91
+ it "reports a class variable set in the #{scope} body and used in a method" do
92
+ src = <<-EOS
93
+ #{scope} Alfa
94
+ @@bravo = 42
100
95
 
101
- def charlie
102
- puts @@bravo
103
- end
96
+ def charlie
97
+ puts @@bravo
104
98
  end
105
- EOS
99
+ end
100
+ EOS
106
101
 
107
- expect(src).to reek_of(:ClassVariable)
108
- end
102
+ expect(src).to reek_of(:ClassVariable, name: '@@bravo')
109
103
  end
110
104
  end
111
105
  end
@@ -30,7 +30,7 @@ RSpec.describe Reek::SmellDetectors::ControlParameter do
30
30
  and reek_of(:ControlParameter, lines: [3], argument: 'charlie')
31
31
  end
32
32
 
33
- context 'parameter not used to determine code path' do
33
+ context 'when a parameter is not used to determine code path' do
34
34
  it 'does not report a ternary check on an ivar' do
35
35
  src = 'def alfa(bravo) @charlie ? bravo : false end'
36
36
  expect(src).not_to reek_of(:ControlParameter)
@@ -52,7 +52,7 @@ RSpec.describe Reek::SmellDetectors::ControlParameter do
52
52
  end
53
53
  end
54
54
 
55
- context 'parameter only used to determine code path' do
55
+ context 'when a parameter is only used to determine code path' do
56
56
  it 'reports a ternary check on a parameter' do
57
57
  src = 'def alfa(bravo); bravo ? true : false; end'
58
58
  expect(src).to reek_of(:ControlParameter)
@@ -144,7 +144,7 @@ RSpec.describe Reek::SmellDetectors::ControlParameter do
144
144
  expect(src).to reek_of(:ControlParameter)
145
145
  end
146
146
 
147
- it 'reports on nested if statements where the inner if is a control parameter' do
147
+ it 'reports on nested suffix if statements where the inner if is a control parameter' do
148
148
  src = <<-EOS
149
149
  def nested(bravo)
150
150
  if true
@@ -157,6 +157,36 @@ RSpec.describe Reek::SmellDetectors::ControlParameter do
157
157
  expect(src).to reek_of(:ControlParameter)
158
158
  end
159
159
 
160
+ it 'reports on nested full if statements where the inner if is a control parameter' do
161
+ src = <<-EOS
162
+ def alfa(bravo)
163
+ if true
164
+ charlie
165
+ else
166
+ if bravo
167
+ delta
168
+ end
169
+ end
170
+ end
171
+ EOS
172
+
173
+ expect(src).to reek_of(:ControlParameter)
174
+ end
175
+
176
+ it 'reports on elsif statements' do
177
+ src = <<-EOS
178
+ def alfa(bravo)
179
+ if true
180
+ charlie
181
+ elsif bravo
182
+ delta
183
+ end
184
+ end
185
+ EOS
186
+
187
+ expect(src).to reek_of(:ControlParameter)
188
+ end
189
+
160
190
  it 'reports on explicit comparison in the condition' do
161
191
  src = 'def alfa(bravo); if bravo == charlie then charlie end; end'
162
192
  expect(src).to reek_of(:ControlParameter)
@@ -188,7 +218,7 @@ RSpec.describe Reek::SmellDetectors::ControlParameter do
188
218
  end
189
219
  end
190
220
 
191
- context 'parameter used besides determining code path' do
221
+ context 'when a parameter is used besides determining code path' do
192
222
  it 'does not report on if conditional expression' do
193
223
  src = 'def alfa(bravo); if bravo then charlie(bravo); end end'
194
224
  expect(src).not_to reek_of(:ControlParameter)