reek 2.0.4 → 3.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 (275) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +13 -0
  3. data/.rubocop.yml +47 -0
  4. data/.travis.yml +31 -0
  5. data/.yardopts +3 -6
  6. data/CHANGELOG +24 -0
  7. data/CONTRIBUTING.md +111 -0
  8. data/Gemfile +16 -0
  9. data/README.md +112 -59
  10. data/bin/reek +2 -2
  11. data/config/cucumber.yml +3 -0
  12. data/config/defaults.reek +0 -1
  13. data/docs/API.md +79 -0
  14. data/docs/Attribute.md +43 -0
  15. data/docs/Basic-Smell-Options.md +44 -0
  16. data/docs/Boolean-Parameter.md +52 -0
  17. data/docs/Class-Variable.md +40 -0
  18. data/docs/Code-Smells.md +34 -0
  19. data/docs/Command-Line-Options.md +84 -0
  20. data/docs/Configuration-Files.md +49 -0
  21. data/docs/Control-Couple.md +22 -0
  22. data/docs/Control-Parameter.md +29 -0
  23. data/docs/Data-Clump.md +44 -0
  24. data/docs/Duplicate-Method-Call.md +49 -0
  25. data/docs/Feature-Envy.md +49 -0
  26. data/docs/How-reek-works-internally.md +114 -0
  27. data/docs/Irresponsible-Module.md +39 -0
  28. data/docs/Large-Class.md +20 -0
  29. data/docs/Long-Parameter-List.md +38 -0
  30. data/docs/Long-Yield-List.md +36 -0
  31. data/docs/Module-Initialize.md +62 -0
  32. data/docs/Nested-Iterators.md +38 -0
  33. data/docs/Nil-Check.md +39 -0
  34. data/docs/Prima-Donna-Method.md +53 -0
  35. data/docs/RSpec-matchers.md +137 -0
  36. data/docs/Rake-Task.md +58 -0
  37. data/docs/Reek-Driven-Development.md +37 -0
  38. data/docs/Repeated-Conditional.md +44 -0
  39. data/docs/Simulated-Polymorphism.md +16 -0
  40. data/docs/Smell-Suppression.md +32 -0
  41. data/docs/Too-Many-Instance-Variables.md +43 -0
  42. data/docs/Too-Many-Methods.md +55 -0
  43. data/docs/Too-Many-Statements.md +50 -0
  44. data/docs/Uncommunicative-Method-Name.md +24 -0
  45. data/docs/Uncommunicative-Module-Name.md +23 -0
  46. data/docs/Uncommunicative-Name.md +16 -0
  47. data/docs/Uncommunicative-Parameter-Name.md +24 -0
  48. data/docs/Uncommunicative-Variable-Name.md +24 -0
  49. data/docs/Unused-Parameters.md +27 -0
  50. data/docs/Utility-Function.md +44 -0
  51. data/docs/Versioning-Policy.md +7 -0
  52. data/docs/YAML-Reports.md +111 -0
  53. data/docs/yard_plugin.rb +14 -0
  54. data/features/{ruby_api/api.feature → command_line_interface/basic_usage.feature} +6 -5
  55. data/features/command_line_interface/options.feature +1 -0
  56. data/features/command_line_interface/smell_selection.feature +4 -8
  57. data/features/command_line_interface/smells_count.feature +25 -32
  58. data/features/command_line_interface/stdin.feature +2 -2
  59. data/features/configuration_files/masking_smells.feature +30 -41
  60. data/features/configuration_files/overrides_defaults.feature +5 -3
  61. data/features/configuration_loading.feature +26 -23
  62. data/features/programmatic_access.feature +43 -0
  63. data/features/rake_task/rake_task.feature +25 -22
  64. data/features/reports/json.feature +24 -26
  65. data/features/reports/reports.feature +77 -103
  66. data/features/reports/yaml.feature +26 -20
  67. data/features/samples.feature +26 -31
  68. data/features/step_definitions/.rubocop.yml +5 -0
  69. data/features/step_definitions/reek_steps.rb +16 -28
  70. data/features/step_definitions/sample_file_steps.rb +158 -0
  71. data/features/support/env.rb +16 -27
  72. data/lib/reek/{source → ast}/ast_node_class_map.rb +11 -12
  73. data/lib/reek/ast/node.rb +132 -0
  74. data/lib/reek/{core → ast}/object_refs.rb +2 -1
  75. data/lib/reek/ast/reference_collector.rb +32 -0
  76. data/lib/reek/{source → ast}/sexp_extensions.rb +43 -7
  77. data/lib/reek/ast/sexp_formatter.rb +31 -0
  78. data/lib/reek/cli/application.rb +5 -4
  79. data/lib/reek/cli/command.rb +2 -1
  80. data/lib/reek/cli/input.rb +6 -5
  81. data/lib/reek/cli/option_interpreter.rb +13 -9
  82. data/lib/reek/cli/options.rb +16 -8
  83. data/lib/reek/cli/reek_command.rb +4 -3
  84. data/lib/reek/cli/silencer.rb +14 -0
  85. data/lib/reek/{core → cli}/warning_collector.rb +2 -1
  86. data/lib/reek/code_comment.rb +36 -0
  87. data/lib/reek/configuration/app_configuration.rb +18 -3
  88. data/lib/reek/configuration/configuration_file_finder.rb +18 -32
  89. data/lib/reek/{core → context}/code_context.rb +8 -6
  90. data/lib/reek/{core → context}/method_context.rb +11 -5
  91. data/lib/reek/{core → context}/module_context.rb +9 -4
  92. data/lib/reek/{core/stop_context.rb → context/root_context.rb} +4 -2
  93. data/lib/reek/{core → context}/singleton_method_context.rb +3 -6
  94. data/lib/reek/examiner.rb +32 -29
  95. data/lib/reek/report/formatter.rb +70 -0
  96. data/lib/reek/report/heading_formatter.rb +45 -0
  97. data/lib/reek/report/location_formatter.rb +35 -0
  98. data/lib/reek/report/report.rb +198 -0
  99. data/lib/reek/smells/attribute.rb +41 -11
  100. data/lib/reek/smells/boolean_parameter.rb +4 -2
  101. data/lib/reek/smells/class_variable.rb +4 -2
  102. data/lib/reek/smells/control_parameter.rb +4 -2
  103. data/lib/reek/smells/data_clump.rb +4 -3
  104. data/lib/reek/smells/duplicate_method_call.rb +15 -5
  105. data/lib/reek/smells/feature_envy.rb +8 -2
  106. data/lib/reek/smells/irresponsible_module.rb +13 -8
  107. data/lib/reek/smells/long_parameter_list.rb +6 -4
  108. data/lib/reek/smells/long_yield_list.rb +4 -2
  109. data/lib/reek/smells/module_initialize.rb +4 -2
  110. data/lib/reek/smells/nested_iterators.rb +4 -2
  111. data/lib/reek/smells/nil_check.rb +6 -3
  112. data/lib/reek/smells/prima_donna_method.rb +21 -12
  113. data/lib/reek/smells/repeated_conditional.rb +7 -4
  114. data/lib/reek/{core → smells}/smell_configuration.rb +3 -1
  115. data/lib/reek/smells/smell_detector.rb +11 -5
  116. data/lib/reek/{core → smells}/smell_repository.rb +9 -5
  117. data/lib/reek/smells/smell_warning.rb +101 -0
  118. data/lib/reek/smells/too_many_instance_variables.rb +4 -2
  119. data/lib/reek/smells/too_many_methods.rb +4 -2
  120. data/lib/reek/smells/too_many_statements.rb +4 -2
  121. data/lib/reek/smells/uncommunicative_method_name.rb +4 -2
  122. data/lib/reek/smells/uncommunicative_module_name.rb +4 -2
  123. data/lib/reek/smells/uncommunicative_parameter_name.rb +4 -2
  124. data/lib/reek/smells/uncommunicative_variable_name.rb +4 -2
  125. data/lib/reek/smells/unused_parameters.rb +4 -2
  126. data/lib/reek/smells/utility_function.rb +11 -22
  127. data/lib/reek/smells.rb +24 -11
  128. data/lib/reek/source/source_code.rb +69 -12
  129. data/lib/reek/source/source_locator.rb +34 -19
  130. data/lib/reek/spec/should_reek.rb +4 -3
  131. data/lib/reek/spec/should_reek_of.rb +2 -1
  132. data/lib/reek/spec/should_reek_only_of.rb +4 -3
  133. data/lib/reek/spec.rb +3 -3
  134. data/lib/reek/tree_dresser.rb +32 -0
  135. data/lib/reek/tree_walker.rb +182 -0
  136. data/lib/reek/version.rb +1 -1
  137. data/lib/reek.rb +3 -3
  138. data/reek.gemspec +18 -25
  139. data/spec/factories/factories.rb +4 -2
  140. data/spec/gem/updates_spec.rb +1 -1
  141. data/spec/gem/yard_spec.rb +2 -2
  142. data/spec/quality/reek_source_spec.rb +3 -3
  143. data/spec/reek/{source/sexp_node_spec.rb → ast/node_spec.rb} +4 -6
  144. data/spec/reek/{core → ast}/object_refs_spec.rb +4 -6
  145. data/spec/reek/{source → ast}/reference_collector_spec.rb +27 -19
  146. data/spec/reek/{source → ast}/sexp_extensions_spec.rb +7 -19
  147. data/spec/reek/{source → ast}/sexp_formatter_spec.rb +13 -8
  148. data/spec/reek/cli/option_interpreter_spec.rb +15 -0
  149. data/spec/reek/cli/options_spec.rb +19 -0
  150. data/spec/reek/cli/warning_collector_spec.rb +28 -0
  151. data/spec/reek/{source/code_comment_spec.rb → code_comment_spec.rb} +19 -17
  152. data/spec/reek/configuration/app_configuration_spec.rb +37 -26
  153. data/spec/reek/configuration/configuration_file_finder_spec.rb +67 -21
  154. data/spec/reek/{core → context}/code_context_spec.rb +18 -21
  155. data/spec/reek/{core → context}/method_context_spec.rb +33 -27
  156. data/spec/reek/{core → context}/module_context_spec.rb +5 -7
  157. data/spec/reek/context/root_context_spec.rb +14 -0
  158. data/spec/reek/context/singleton_method_context_spec.rb +17 -0
  159. data/spec/reek/examiner_spec.rb +9 -50
  160. data/spec/reek/{cli → report}/html_report_spec.rb +6 -9
  161. data/spec/reek/report/json_report_spec.rb +20 -0
  162. data/spec/reek/{cli → report}/text_report_spec.rb +16 -19
  163. data/spec/reek/report/xml_report_spec.rb +34 -0
  164. data/spec/reek/report/yaml_report_spec.rb +20 -0
  165. data/spec/reek/smells/attribute_spec.rb +93 -88
  166. data/spec/reek/smells/behaves_like_variable_detector.rb +1 -1
  167. data/spec/reek/smells/boolean_parameter_spec.rb +31 -5
  168. data/spec/reek/smells/class_variable_spec.rb +10 -10
  169. data/spec/reek/smells/control_parameter_spec.rb +5 -5
  170. data/spec/reek/smells/data_clump_spec.rb +6 -6
  171. data/spec/reek/smells/duplicate_method_call_spec.rb +7 -7
  172. data/spec/reek/smells/feature_envy_spec.rb +12 -13
  173. data/spec/reek/smells/irresponsible_module_spec.rb +28 -32
  174. data/spec/reek/smells/long_parameter_list_spec.rb +7 -7
  175. data/spec/reek/smells/long_yield_list_spec.rb +6 -6
  176. data/spec/reek/smells/module_initialize_spec.rb +4 -4
  177. data/spec/reek/smells/nested_iterators_spec.rb +6 -6
  178. data/spec/reek/smells/nil_check_spec.rb +6 -6
  179. data/spec/reek/smells/prima_donna_method_spec.rb +8 -5
  180. data/spec/reek/smells/repeated_conditional_spec.rb +18 -17
  181. data/spec/reek/{core → smells}/smell_configuration_spec.rb +5 -7
  182. data/spec/reek/smells/smell_detector_shared.rb +6 -7
  183. data/spec/reek/smells/smell_repository_spec.rb +29 -0
  184. data/spec/reek/{smell_warning_spec.rb → smells/smell_warning_spec.rb} +7 -9
  185. data/spec/reek/smells/too_many_instance_variables_spec.rb +5 -5
  186. data/spec/reek/smells/too_many_methods_spec.rb +12 -8
  187. data/spec/reek/smells/too_many_statements_spec.rb +10 -9
  188. data/spec/reek/smells/uncommunicative_method_name_spec.rb +5 -5
  189. data/spec/reek/smells/uncommunicative_module_name_spec.rb +8 -8
  190. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +18 -6
  191. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +10 -7
  192. data/spec/reek/smells/unused_parameters_spec.rb +4 -4
  193. data/spec/reek/smells/utility_function_spec.rb +65 -39
  194. data/spec/reek/source/source_code_spec.rb +10 -10
  195. data/spec/reek/source/source_locator_spec.rb +30 -0
  196. data/spec/reek/spec/should_reek_of_spec.rb +9 -25
  197. data/spec/reek/spec/should_reek_only_of_spec.rb +4 -7
  198. data/spec/reek/spec/should_reek_spec.rb +4 -32
  199. data/spec/reek/tree_dresser_spec.rb +16 -0
  200. data/spec/reek/{core/tree_walker_spec.rb → tree_walker_spec.rb} +5 -7
  201. data/spec/samples/checkstyle.xml +2 -0
  202. data/spec/samples/configuration/with_excluded_paths.reek +4 -0
  203. data/spec/samples/{overrides/masked/lower.reek → masked_by_dotfile/.reek} +3 -1
  204. data/spec/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +5 -0
  205. data/spec/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +2 -0
  206. data/spec/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +6 -0
  207. data/spec/samples/{ruby20_syntax.rb → unusual_syntax.rb} +8 -0
  208. data/spec/spec_helper.rb +21 -10
  209. data/tasks/develop.rake +2 -2
  210. data/tasks/reek.rake +1 -1
  211. metadata +158 -141
  212. data/features/support/hooks.rb +0 -15
  213. data/lib/reek/cli/report/formatter.rb +0 -69
  214. data/lib/reek/cli/report/heading_formatter.rb +0 -45
  215. data/lib/reek/cli/report/location_formatter.rb +0 -34
  216. data/lib/reek/cli/report/report.rb +0 -131
  217. data/lib/reek/core/tree_walker.rb +0 -180
  218. data/lib/reek/smell_warning.rb +0 -87
  219. data/lib/reek/source/ast_node.rb +0 -38
  220. data/lib/reek/source/code_comment.rb +0 -37
  221. data/lib/reek/source/core_extras.rb +0 -46
  222. data/lib/reek/source/reference_collector.rb +0 -27
  223. data/lib/reek/source/sexp_formatter.rb +0 -22
  224. data/lib/reek/source/sexp_node.rb +0 -79
  225. data/lib/reek/source/source_file.rb +0 -16
  226. data/lib/reek/source/source_repository.rb +0 -45
  227. data/lib/reek/source/tree_dresser.rb +0 -24
  228. data/lib/reek/source.rb +0 -16
  229. data/spec/reek/cli/json_report_spec.rb +0 -20
  230. data/spec/reek/cli/option_interperter_spec.rb +0 -14
  231. data/spec/reek/cli/yaml_report_spec.rb +0 -23
  232. data/spec/reek/core/singleton_method_context_spec.rb +0 -9
  233. data/spec/reek/core/smell_repository_spec.rb +0 -17
  234. data/spec/reek/core/stop_context_spec.rb +0 -17
  235. data/spec/reek/core/warning_collector_spec.rb +0 -30
  236. data/spec/reek/source/object_source_spec.rb +0 -20
  237. data/spec/reek/source/tree_dresser_spec.rb +0 -18
  238. data/spec/samples/config/allow_duplication.reek +0 -3
  239. data/spec/samples/config/deeper_nested_iterators.reek +0 -3
  240. data/spec/samples/configuration_loading/minimal_dirty.rb +0 -4
  241. data/spec/samples/configuration_loading/reek-test-run-disable_smells.reek +0 -7
  242. data/spec/samples/configuration_loading/reek-test-run-enable_smells.reek +0 -7
  243. data/spec/samples/corrupt_config_file/corrupt.reek +0 -1
  244. data/spec/samples/corrupt_config_file/dirty.rb +0 -8
  245. data/spec/samples/demo/demo.rb +0 -8
  246. data/spec/samples/empty_config_file/dirty.rb +0 -8
  247. data/spec/samples/empty_config_file/empty.reek +0 -0
  248. data/spec/samples/inline_config/dirty.rb +0 -16
  249. data/spec/samples/inline_config/masked.reek +0 -7
  250. data/spec/samples/mask_some/dirty.rb +0 -8
  251. data/spec/samples/mask_some/some.reek +0 -8
  252. data/spec/samples/masked/dirty.rb +0 -8
  253. data/spec/samples/masked/masked.reek +0 -5
  254. data/spec/samples/minimal_smelly_and_masked/config.reek +0 -7
  255. data/spec/samples/minimal_smelly_and_masked/minimal_dirty.rb +0 -4
  256. data/spec/samples/mixed_results/clean_one.rb +0 -7
  257. data/spec/samples/mixed_results/clean_three.rb +0 -7
  258. data/spec/samples/mixed_results/clean_two.rb +0 -7
  259. data/spec/samples/mixed_results/dirty_one.rb +0 -8
  260. data/spec/samples/mixed_results/dirty_two.rb +0 -8
  261. data/spec/samples/not_quite_masked/dirty.rb +0 -8
  262. data/spec/samples/not_quite_masked/masked.reek +0 -5
  263. data/spec/samples/not_quite_masked/smelly.rb +0 -3
  264. data/spec/samples/one_smelly_file/dirty.rb +0 -3
  265. data/spec/samples/overrides/masked/dirty.rb +0 -8
  266. data/spec/samples/overrides/upper.reek +0 -5
  267. data/spec/samples/overrides_defaults/camel_case.rb +0 -14
  268. data/spec/samples/overrides_defaults/config.reek +0 -6
  269. data/spec/samples/ruby21_syntax.rb +0 -5
  270. data/spec/samples/standard_smelly/dirty.rb +0 -8
  271. data/spec/samples/standard_smelly/minimal_dirty.rb +0 -4
  272. data/spec/samples/three_smelly_files/dirty_one.rb +0 -3
  273. data/spec/samples/three_smelly_files/dirty_three.rb +0 -5
  274. data/spec/samples/three_smelly_files/dirty_two.rb +0 -4
  275. /data/spec/samples/{simple_configuration.reek → configuration/simple_configuration.reek} +0 -0
@@ -1,9 +1,7 @@
1
- require 'spec_helper'
2
- require 'reek/examiner'
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/reek/examiner'
3
3
 
4
- include Reek
5
-
6
- shared_examples_for 'no smells found' do
4
+ RSpec.shared_examples_for 'no smells found' do
7
5
  it 'is not smelly' do
8
6
  expect(@examiner).not_to be_smelly
9
7
  end
@@ -12,7 +10,7 @@ shared_examples_for 'no smells found' do
12
10
  end
13
11
  end
14
12
 
15
- shared_examples_for 'one smell found' do
13
+ RSpec.shared_examples_for 'one smell found' do
16
14
  it 'is smelly' do
17
15
  expect(@examiner).to be_smelly
18
16
  end
@@ -24,14 +22,14 @@ shared_examples_for 'one smell found' do
24
22
  end
25
23
  end
26
24
 
27
- describe Examiner do
25
+ RSpec.describe Reek::Examiner do
28
26
  before :each do
29
27
  @expected_first_smell = 'NestedIterators'
30
28
  end
31
29
 
32
30
  context 'with a fragrant String' do
33
31
  before :each do
34
- @examiner = Examiner.new('def good() true; end')
32
+ @examiner = described_class.new('def good() true; end')
35
33
  end
36
34
 
37
35
  it_should_behave_like 'no smells found'
@@ -39,52 +37,13 @@ describe Examiner do
39
37
 
40
38
  context 'with a smelly String' do
41
39
  before :each do
42
- @examiner = Examiner.new('def fine() y = 4; end')
40
+ @examiner = described_class.new('def fine() y = 4; end')
43
41
  @expected_first_smell = 'UncommunicativeName'
44
42
  end
45
43
 
46
44
  it_should_behave_like 'one smell found'
47
45
  end
48
46
 
49
- context 'with a partially masked smelly Dir' do
50
- around(:each) do |example|
51
- with_test_config('spec/samples/all_but_one_masked/masked.reek') do
52
- example.run
53
- end
54
- end
55
-
56
- before :each do
57
- smelly_dir = Dir['spec/samples/all_but_one_masked/*.rb']
58
- @examiner = Examiner.new(smelly_dir)
59
- end
60
-
61
- it_should_behave_like 'one smell found'
62
- end
63
-
64
- context 'with a fragrant Dir' do
65
- before :each do
66
- clean_dir = Dir['spec/samples/three_clean_files/*.rb']
67
- @examiner = Examiner.new(clean_dir)
68
- end
69
-
70
- it_should_behave_like 'no smells found'
71
- end
72
-
73
- context 'with a smelly Dir masked by a dotfile' do
74
- around(:each) do |example|
75
- with_test_config('spec/samples/masked_by_dotfile/.reek') do
76
- example.run
77
- end
78
- end
79
-
80
- before :each do
81
- smelly_dir = Dir['spec/samples/masked_by_dotfile/*.rb']
82
- @examiner = Examiner.new(smelly_dir)
83
- end
84
-
85
- it_should_behave_like 'one smell found'
86
- end
87
-
88
47
  context 'with a partially masked smelly File' do
89
48
  around(:each) do |example|
90
49
  with_test_config('spec/samples/all_but_one_masked/masked.reek') do
@@ -94,7 +53,7 @@ describe Examiner do
94
53
 
95
54
  before :each do
96
55
  smelly_file = File.new(Dir['spec/samples/all_but_one_masked/d*.rb'][0])
97
- @examiner = Examiner.new(smelly_file)
56
+ @examiner = described_class.new(smelly_file)
98
57
  end
99
58
 
100
59
  it_should_behave_like 'one smell found'
@@ -103,7 +62,7 @@ describe Examiner do
103
62
  context 'with a fragrant File' do
104
63
  before :each do
105
64
  clean_file = File.new(Dir['spec/samples/three_clean_files/*.rb'][0])
106
- @examiner = Examiner.new(clean_file)
65
+ @examiner = described_class.new(clean_file)
107
66
  end
108
67
 
109
68
  it_should_behave_like 'no smells found'
@@ -1,15 +1,12 @@
1
- require 'spec_helper'
2
- require 'reek/examiner'
3
- require 'reek/cli/report/report'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/examiner'
3
+ require_relative '../../../lib/reek/report/report'
4
4
 
5
- include Reek
6
- include Reek::Cli
7
-
8
- describe Report::HtmlReport do
9
- let(:instance) { Report::HtmlReport.new }
5
+ RSpec.describe Reek::Report::HTMLReport do
6
+ let(:instance) { Reek::Report::HTMLReport.new }
10
7
 
11
8
  context 'with an empty source' do
12
- let(:examiner) { Examiner.new('') }
9
+ let(:examiner) { Reek::Examiner.new('') }
13
10
 
14
11
  before do
15
12
  instance.add_examiner examiner
@@ -0,0 +1,20 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/examiner'
3
+ require_relative '../../../lib/reek/report/report'
4
+ require_relative '../../../lib/reek/report/formatter'
5
+
6
+ RSpec.describe Reek::Report::JSONReport do
7
+ let(:instance) { Reek::Report::JSONReport.new }
8
+
9
+ context 'empty source' do
10
+ let(:examiner) { Reek::Examiner.new('') }
11
+
12
+ before do
13
+ instance.add_examiner examiner
14
+ end
15
+
16
+ it 'prints empty json' do
17
+ expect { instance.show }.to output(/^\[\]$/).to_stdout
18
+ end
19
+ end
20
+ end
@@ -1,26 +1,23 @@
1
- require 'spec_helper'
2
- require 'reek/examiner'
3
- require 'reek/cli/report/report'
4
- require 'reek/cli/report/formatter'
5
- require 'reek/cli/report/heading_formatter'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/examiner'
3
+ require_relative '../../../lib/reek/report/report'
4
+ require_relative '../../../lib/reek/report/formatter'
5
+ require_relative '../../../lib/reek/report/heading_formatter'
6
6
  require 'rainbow'
7
7
 
8
- include Reek
9
- include Reek::Cli
10
-
11
- describe Report::TextReport do
8
+ RSpec.describe Reek::Report::TextReport do
12
9
  let(:report_options) do
13
10
  {
14
- warning_formatter: Report::SimpleWarningFormatter.new,
15
- report_formatter: Report::Formatter,
16
- heading_formatter: Report::HeadingFormatter::Quiet
11
+ warning_formatter: Reek::Report::SimpleWarningFormatter.new,
12
+ report_formatter: Reek::Report::Formatter,
13
+ heading_formatter: Reek::Report::HeadingFormatter::Quiet
17
14
  }
18
15
  end
19
- let(:instance) { Report::TextReport.new report_options }
16
+ let(:instance) { Reek::Report::TextReport.new report_options }
20
17
 
21
18
  context 'with a single empty source' do
22
19
  before do
23
- instance.add_examiner Examiner.new('')
20
+ instance.add_examiner Reek::Examiner.new('')
24
21
  end
25
22
 
26
23
  it 'has an empty quiet_report' do
@@ -30,8 +27,8 @@ describe Report::TextReport do
30
27
 
31
28
  context 'with non smelly files' do
32
29
  before do
33
- instance.add_examiner(Examiner.new('def simple() puts "a" end'))
34
- instance.add_examiner(Examiner.new('def simple() puts "a" end'))
30
+ instance.add_examiner(Reek::Examiner.new('def simple() puts "a" end'))
31
+ instance.add_examiner(Reek::Examiner.new('def simple() puts "a" end'))
35
32
  end
36
33
 
37
34
  context 'with colors disabled' do
@@ -57,8 +54,8 @@ describe Report::TextReport do
57
54
 
58
55
  context 'with a couple of smells' do
59
56
  before do
60
- instance.add_examiner(Examiner.new('def simple(a) a[3] end'))
61
- instance.add_examiner(Examiner.new('def simple(a) a[3] end'))
57
+ instance.add_examiner(Reek::Examiner.new('def simple(a) a[3] end'))
58
+ instance.add_examiner(Reek::Examiner.new('def simple(a) a[3] end'))
62
59
  end
63
60
 
64
61
  context 'with colors disabled' do
@@ -72,7 +69,7 @@ describe Report::TextReport do
72
69
 
73
70
  it 'should mention every smell name' do
74
71
  expect { instance.show }.to output(/UncommunicativeParameterName/).to_stdout
75
- expect { instance.show }.to output(/FeatureEnvy/).to_stdout
72
+ expect { instance.show }.to output(/UtilityFunction/).to_stdout
76
73
  end
77
74
  end
78
75
 
@@ -0,0 +1,34 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/examiner'
3
+ require_relative '../../../lib/reek/report/report'
4
+ require_relative '../../../lib/reek/report/formatter'
5
+
6
+ RSpec.describe Reek::Report::XMLReport do
7
+ let(:instance) { Reek::Report::XMLReport.new }
8
+
9
+ context 'empty source' do
10
+ let(:examiner) { Reek::Examiner.new('') }
11
+
12
+ before do
13
+ instance.add_examiner examiner
14
+ end
15
+
16
+ it 'prints empty checkstyle xml' do
17
+ expect { instance.show }.to output("<?xml version='1.0'?>\n<checkstyle/>\n").to_stdout
18
+ end
19
+ end
20
+
21
+ context 'source with voliations' do
22
+ let(:examiner) { Reek::Examiner.new('def simple(a) a[0] end') }
23
+
24
+ before do
25
+ allow(File).to receive(:realpath).and_return('/some/path')
26
+ instance.add_examiner examiner
27
+ end
28
+
29
+ it 'prints non-empty checkstyle xml' do
30
+ sample_path = File.expand_path 'checkstyle.xml', 'spec/samples'
31
+ expect { instance.show }.to output(File.read(sample_path)).to_stdout
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,20 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/examiner'
3
+ require_relative '../../../lib/reek/report/report'
4
+ require_relative '../../../lib/reek/report/formatter'
5
+
6
+ RSpec.describe Reek::Report::YAMLReport do
7
+ let(:instance) { Reek::Report::YAMLReport.new }
8
+
9
+ context 'empty source' do
10
+ let(:examiner) { Reek::Examiner.new('') }
11
+
12
+ before do
13
+ instance.add_examiner examiner
14
+ end
15
+
16
+ it 'prints empty yaml' do
17
+ expect { instance.show }.to output(/^--- \[\]\n.*$/).to_stdout
18
+ end
19
+ end
20
+ end
@@ -1,118 +1,123 @@
1
- require 'spec_helper'
2
- require 'reek/smells/attribute'
3
- require 'reek/core/module_context'
4
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/attribute'
3
+ require_relative '../../../lib/reek/smells/smell_configuration'
4
+ require_relative 'smell_detector_shared'
5
+
6
+ RSpec.describe Reek::Smells::Attribute do
7
+ let(:config) do
8
+ {
9
+ Attribute: { Reek::Smells::SmellConfiguration::ENABLED_KEY => true }
10
+ }
11
+ end
5
12
 
6
- describe Reek::Smells::Attribute do
7
- before :each do
13
+ before(:each) do
8
14
  @source_name = 'dummy_source'
9
15
  @detector = build(:smell_detector, smell_type: :Attribute, source: @source_name)
10
16
  end
11
17
 
18
+ around(:each) do |example|
19
+ with_test_config(config) do
20
+ example.run
21
+ end
22
+ end
23
+
12
24
  it_should_behave_like 'SmellDetector'
13
25
 
14
26
  context 'with no attributes' do
15
- it 'records nothing in the module' do
16
- src = 'module Fred; end'
17
- ctx = Reek::Core::CodeContext.new(nil, src.to_reek_source.syntax_tree)
18
- expect(@detector.examine_context(ctx)).to be_empty
27
+ it 'records nothing' do
28
+ expect('
29
+ class Klass
30
+ end
31
+ ').to_not reek_of(:Attribute)
19
32
  end
20
33
  end
21
34
 
22
- context 'with one attribute' do
23
- before :each do
24
- @attr_name = 'super_thing'
35
+ context 'with attributes' do
36
+ it 'records nothing' do
37
+ expect('
38
+ class Klass
39
+ attr :super_private, :super_private2
40
+ private :super_private, :super_private2
41
+ private
42
+ attr :super_thing
43
+ public
44
+ attr :super_thing2
45
+ private
46
+ attr :super_thing2
47
+ end
48
+ ').to_not reek_of(:Attribute)
25
49
  end
26
50
 
27
- shared_examples_for 'one attribute found' do
28
- before :each do
29
- ctx = Reek::Core::CodeContext.new(nil, @src.to_reek_source.syntax_tree)
30
- @smells = @detector.examine_context(ctx)
31
- end
32
-
33
- it 'records only that attribute' do
34
- expect(@smells.length).to eq(1)
35
- end
36
-
37
- it 'reports the attribute name' do
38
- expect(@smells[0].parameters[:name]).to eq(@attr_name)
39
- end
40
-
41
- it 'reports the declaration line number' do
42
- expect(@smells[0].lines).to eq([1])
43
- end
44
-
45
- it 'reports the correct smell class' do
46
- expect(@smells[0].smell_category).to eq(described_class.smell_category)
47
- end
48
-
49
- it 'reports the context fq name' do
50
- expect(@smells[0].context).to eq('Fred')
51
- end
51
+ it 'records attr attribute in a module' do
52
+ expect('
53
+ module Mod
54
+ attr :my_attr
55
+ end
56
+ ').to reek_of(:Attribute, name: 'my_attr')
52
57
  end
53
58
 
54
- context 'declared in a class' do
55
- before :each do
56
- @src = "class Fred; attr :#{@attr_name}; end"
57
- end
58
-
59
- it_should_behave_like 'one attribute found'
59
+ it 'records attr attribute' do
60
+ expect('
61
+ class Klass
62
+ attr :my_attr
63
+ end
64
+ ').to reek_of(:Attribute, name: 'my_attr')
60
65
  end
61
66
 
62
- context 'reader in a class' do
63
- before :each do
64
- @src = "class Fred; attr_reader :#{@attr_name}; end"
65
- end
66
-
67
- it_should_behave_like 'one attribute found'
67
+ it 'records reader attribute' do
68
+ expect('
69
+ class Klass
70
+ attr_reader :my_attr
71
+ end
72
+ ').to reek_of(:Attribute, name: 'my_attr')
68
73
  end
69
74
 
70
- context 'writer in a class' do
71
- before :each do
72
- @src = "class Fred; attr_writer :#{@attr_name}; end"
73
- end
74
-
75
- it_should_behave_like 'one attribute found'
75
+ it 'records writer attribute' do
76
+ expect('
77
+ class Klass
78
+ attr_writer :my_attr
79
+ end
80
+ ').to reek_of(:Attribute, name: 'my_attr')
76
81
  end
77
82
 
78
- context 'accessor in a class' do
79
- before :each do
80
- @src = "class Fred; attr_accessor :#{@attr_name}; end"
81
- end
82
-
83
- it_should_behave_like 'one attribute found'
83
+ it 'records accessor attribute' do
84
+ expect('
85
+ class Klass
86
+ attr_accessor :my_attr
87
+ end
88
+ ').to reek_of(:Attribute, name: 'my_attr')
84
89
  end
85
90
 
86
- context 'declared in a module' do
87
- before :each do
88
- @src = "module Fred; attr :#{@attr_name}; end"
89
- end
90
-
91
- it_should_behave_like 'one attribute found'
91
+ it 'records attr attribute after switching visbility' do
92
+ expect('
93
+ class Klass
94
+ private
95
+ attr :my_attr
96
+ public :my_attr
97
+ private :my_attr
98
+ public :my_attr
99
+ end
100
+ ').to reek_of(:Attribute, name: 'my_attr')
92
101
  end
93
102
 
94
- context 'reader in a module' do
95
- before :each do
96
- @src = "module Fred; attr_reader :#{@attr_name}; end"
97
- end
98
-
99
- it_should_behave_like 'one attribute found'
103
+ it "doesn't record protected attributes" do
104
+ src = '
105
+ class Klass
106
+ protected
107
+ attr :iam_protected
108
+ end
109
+ '
110
+ expect(src).to_not reek_of(:Attribute, name: 'iam_protected')
100
111
  end
101
112
 
102
- context 'writer in a module' do
103
- before :each do
104
- @src = "module Fred; attr_writer :#{@attr_name}; end"
105
- end
106
-
107
- it_should_behave_like 'one attribute found'
108
- end
109
-
110
- context 'accessor in a module' do
111
- before :each do
112
- @src = "module Fred; attr_accessor :#{@attr_name}; end"
113
- end
114
-
115
- it_should_behave_like 'one attribute found'
113
+ it "doesn't record private attributes" do
114
+ src = '
115
+ class Klass
116
+ private
117
+ attr :iam_private
118
+ end
119
+ '
120
+ expect(src).to_not reek_of(:Attribute, name: 'iam_private')
116
121
  end
117
122
  end
118
123
  end
@@ -1,4 +1,4 @@
1
- shared_examples_for 'a variable detector' do
1
+ RSpec.shared_examples_for 'a variable detector' do
2
2
  context 'with no variables' do
3
3
  it "doesn't record a smell" do
4
4
  @detector.examine_context(@ctx)
@@ -1,8 +1,8 @@
1
- require 'spec_helper'
2
- require 'reek/smells/boolean_parameter'
3
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/boolean_parameter'
3
+ require_relative 'smell_detector_shared'
4
4
 
5
- describe Reek::Smells::BooleanParameter do
5
+ RSpec.describe Reek::Smells::BooleanParameter do
6
6
  context 'parameter defaulted with boolean' do
7
7
  context 'in a method' do
8
8
  it 'reports a parameter defaulted to true' do
@@ -20,6 +20,32 @@ describe Reek::Smells::BooleanParameter do
20
20
  expect(src).to reek_of(:BooleanParameter, name: 'arga')
21
21
  expect(src).to reek_of(:BooleanParameter, name: 'argb')
22
22
  end
23
+
24
+ it 'reports keyword parameters defaulted to booleans' do
25
+ src = 'def cc(arga: true, argb: false) end'
26
+ expect(src).to reek_of(:BooleanParameter, name: 'arga')
27
+ expect(src).to reek_of(:BooleanParameter, name: 'argb')
28
+ end
29
+
30
+ it 'does not report regular parameters' do
31
+ src = 'def cc(a, b) end'
32
+ expect(src).not_to reek_of(:BooleanParameter)
33
+ end
34
+
35
+ it 'does not report array decomposition parameters' do
36
+ src = 'def cc((a, b)) end'
37
+ expect(src).not_to reek_of(:BooleanParameter)
38
+ end
39
+
40
+ it 'does not report keyword parameters with no default' do
41
+ src = 'def cc(a:, b:) end'
42
+ expect(src).not_to reek_of(:BooleanParameter)
43
+ end
44
+
45
+ it 'does not report keyword parameters with non-boolean default' do
46
+ src = 'def cc(a: 42, b: "32") end'
47
+ expect(src).not_to reek_of(:BooleanParameter)
48
+ end
23
49
  end
24
50
 
25
51
  context 'in a singleton method' do
@@ -49,7 +75,7 @@ describe Reek::Smells::BooleanParameter do
49
75
 
50
76
  it 'reports the fields correctly' do
51
77
  src = 'def cc(arga = true) end'
52
- ctx = Reek::Core::MethodContext.new(nil, src.to_reek_source.syntax_tree)
78
+ ctx = Reek::Context::MethodContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
53
79
  @detector.examine(ctx)
54
80
  smells = @detector.smells_found.to_a
55
81
  expect(smells.length).to eq(1)
@@ -1,9 +1,9 @@
1
- require 'spec_helper'
2
- require 'reek/smells/class_variable'
3
- require 'reek/core/module_context'
4
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/class_variable'
3
+ require_relative '../../../lib/reek/context/module_context'
4
+ require_relative 'smell_detector_shared'
5
5
 
6
- describe Reek::Smells::ClassVariable do
6
+ RSpec.describe Reek::Smells::ClassVariable do
7
7
  before :each do
8
8
  @source_name = 'dummy_source'
9
9
  @detector = build(:smell_detector, smell_type: :ClassVariable, source: @source_name)
@@ -15,20 +15,20 @@ describe Reek::Smells::ClassVariable do
15
15
  context 'with no class variables' do
16
16
  it 'records nothing in the class' do
17
17
  exp = ast(:class, :Fred)
18
- expect(@detector.examine_context(Reek::Core::CodeContext.new(nil, exp))).to be_empty
18
+ expect(@detector.examine_context(Reek::Context::CodeContext.new(nil, exp))).to be_empty
19
19
  end
20
20
 
21
21
  it 'records nothing in the module' do
22
22
  exp = ast(:module, :Fred)
23
- expect(@detector.examine_context(Reek::Core::CodeContext.new(nil, exp))).to be_empty
23
+ expect(@detector.examine_context(Reek::Context::CodeContext.new(nil, exp))).to be_empty
24
24
  end
25
25
  end
26
26
 
27
27
  context 'with one class variable' do
28
28
  shared_examples_for 'one variable found' do
29
29
  before :each do
30
- ast = @src.to_reek_source.syntax_tree
31
- @smells = @detector.examine_context(Reek::Core::CodeContext.new(nil, ast))
30
+ ast = Reek::Source::SourceCode.from(@src).syntax_tree
31
+ @smells = @detector.examine_context(Reek::Context::CodeContext.new(nil, ast))
32
32
  end
33
33
 
34
34
  it 'records only that class variable' do
@@ -99,7 +99,7 @@ describe Reek::Smells::ClassVariable do
99
99
  #{@class_variable} = {}
100
100
  end
101
101
  EOS
102
- ctx = Reek::Core::CodeContext.new(nil, src.to_reek_source.syntax_tree)
102
+ ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
103
103
  @warning = @detector.examine_context(ctx)[0]
104
104
  expect(@warning.source).to eq(@source_name)
105
105
  expect(@warning.smell_category).to eq(described_class.smell_category)
@@ -1,8 +1,8 @@
1
- require 'spec_helper'
2
- require 'reek/smells/control_parameter'
3
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/control_parameter'
3
+ require_relative 'smell_detector_shared'
4
4
 
5
- describe Reek::Smells::ControlParameter do
5
+ RSpec.describe Reek::Smells::ControlParameter do
6
6
  before(:each) do
7
7
  @source_name = 'dummy_source'
8
8
  @detector = build(:smell_detector, smell_type: :ControlParameter, source: @source_name)
@@ -272,7 +272,7 @@ describe Reek::Smells::ControlParameter do
272
272
  puts "hello" if arg
273
273
  end
274
274
  EOS
275
- ctx = Reek::Core::MethodContext.new(nil, src.to_reek_source.syntax_tree)
275
+ ctx = Reek::Context::MethodContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
276
276
  smells = @detector.examine(ctx)
277
277
  expect(smells.length).to eq(1)
278
278
  @warning = smells[0]
@@ -1,8 +1,8 @@
1
- require 'spec_helper'
2
- require 'reek/smells/data_clump'
3
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/data_clump'
3
+ require_relative 'smell_detector_shared'
4
4
 
5
- shared_examples_for 'a data clump detector' do
5
+ RSpec.shared_examples_for 'a data clump detector' do
6
6
  it 'does not report small parameter sets' do
7
7
  src = <<-EOS
8
8
  # test module
@@ -25,7 +25,7 @@ shared_examples_for 'a data clump detector' do
25
25
  def third(pa, pb) pa - pb + @fred; end
26
26
  end
27
27
  EOS
28
- ctx = Reek::Core::ModuleContext.new(nil, @src.to_reek_source.syntax_tree)
28
+ ctx = Reek::Context::ModuleContext.new(nil, Reek::Source::SourceCode.from(@src).syntax_tree)
29
29
  detector = build(:smell_detector, smell_type: :DataClump)
30
30
  @smells = detector.examine_context(ctx)
31
31
  end
@@ -160,7 +160,7 @@ shared_examples_for 'a data clump detector' do
160
160
  end
161
161
  end
162
162
 
163
- describe Reek::Smells::DataClump do
163
+ RSpec.describe Reek::Smells::DataClump do
164
164
  before(:each) do
165
165
  @detector = build(:smell_detector, smell_type: :DataClump)
166
166
  end