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,16 +1,17 @@
1
- require 'spec_helper'
2
- require 'reek/smells/too_many_statements'
3
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/too_many_statements'
3
+ require_relative 'smell_detector_shared'
4
+ require_relative '../../../lib/reek/source/source_code'
4
5
 
5
6
  def process_method(source)
6
- Reek::Core::TreeWalker.new.process_def(source.to_reek_source.syntax_tree)
7
+ Reek::TreeWalker.new.process_def(Reek::Source::SourceCode.from(source).syntax_tree)
7
8
  end
8
9
 
9
10
  def process_singleton_method(source)
10
- Reek::Core::TreeWalker.new.process_defs(source.to_reek_source.syntax_tree)
11
+ Reek::TreeWalker.new.process_defs(Reek::Source::SourceCode.from(source).syntax_tree)
11
12
  end
12
13
 
13
- describe Reek::Smells::TooManyStatements do
14
+ RSpec.describe Reek::Smells::TooManyStatements do
14
15
  it 'should not report short methods' do
15
16
  src = 'def short(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;end'
16
17
  expect(src).not_to reek_of(:TooManyStatements)
@@ -48,7 +49,7 @@ describe Reek::Smells::TooManyStatements do
48
49
  end
49
50
  end
50
51
 
51
- describe Reek::Smells::TooManyStatements do
52
+ RSpec.describe Reek::Smells::TooManyStatements do
52
53
  it 'counts 1 assignment' do
53
54
  method = process_method('def one() val = 4; end')
54
55
  expect(method.num_statements).to eq(1)
@@ -90,7 +91,7 @@ describe Reek::Smells::TooManyStatements do
90
91
  end
91
92
  end
92
93
 
93
- describe Reek::Smells::TooManyStatements, 'does not count control statements' do
94
+ RSpec.describe Reek::Smells::TooManyStatements, 'does not count control statements' do
94
95
  it 'counts 1 statement in a conditional expression' do
95
96
  method = process_method('def one() if val == 4; callee(); end; end')
96
97
  expect(method.num_statements).to eq(1)
@@ -247,7 +248,7 @@ describe Reek::Smells::TooManyStatements, 'does not count control statements' do
247
248
  end
248
249
  end
249
250
 
250
- describe Reek::Smells::TooManyStatements do
251
+ RSpec.describe Reek::Smells::TooManyStatements do
251
252
  before(:each) do
252
253
  @detector = build(:smell_detector, smell_type: :TooManyStatements, source: 'source_name')
253
254
  end
@@ -1,8 +1,8 @@
1
- require 'spec_helper'
2
- require 'reek/smells/uncommunicative_method_name'
3
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/uncommunicative_method_name'
3
+ require_relative 'smell_detector_shared'
4
4
 
5
- describe Reek::Smells::UncommunicativeMethodName do
5
+ RSpec.describe Reek::Smells::UncommunicativeMethodName do
6
6
  before do
7
7
  @source_name = 'dummy_source'
8
8
  @detector = build(:smell_detector, smell_type: :UncommunicativeMethodName, source: @source_name)
@@ -21,7 +21,7 @@ describe Reek::Smells::UncommunicativeMethodName do
21
21
  context 'with a bad name' do
22
22
  before do
23
23
  src = "def #{method_name}; end"
24
- ctx = Reek::Core::CodeContext.new(nil, src.to_reek_source.syntax_tree)
24
+ ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
25
25
  smells = @detector.examine_context(ctx)
26
26
  @warning = smells[0]
27
27
  end
@@ -1,9 +1,9 @@
1
- require 'spec_helper'
2
- require 'reek/smells/uncommunicative_module_name'
3
- require 'reek/smells/smell_detector_shared'
4
- require 'reek/core/code_context'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/uncommunicative_module_name'
3
+ require_relative 'smell_detector_shared'
4
+ require_relative '../../../lib/reek/context/code_context'
5
5
 
6
- describe Reek::Smells::UncommunicativeModuleName do
6
+ RSpec.describe Reek::Smells::UncommunicativeModuleName do
7
7
  before do
8
8
  @source_name = 'dummy_source'
9
9
  @detector = build(:smell_detector, smell_type: :UncommunicativeModuleName, source: @source_name)
@@ -30,7 +30,7 @@ describe Reek::Smells::UncommunicativeModuleName do
30
30
 
31
31
  it 'reports a bad scoped name' do
32
32
  src = "#{type} Foo::X; end"
33
- ctx = Reek::Core::CodeContext.new(nil, src.to_reek_source.syntax_tree)
33
+ ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
34
34
  smells = @detector.examine_context(ctx)
35
35
  expect(smells.length).to eq(1)
36
36
  expect(smells[0].smell_category).to eq(Reek::Smells::UncommunicativeModuleName.smell_category)
@@ -43,7 +43,7 @@ describe Reek::Smells::UncommunicativeModuleName do
43
43
  context 'accepting names' do
44
44
  it 'accepts Inline::C' do
45
45
  src = 'module Inline::C; end'
46
- ctx = Reek::Core::CodeContext.new(nil, src.to_reek_source.syntax_tree)
46
+ ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
47
47
  expect(@detector.examine_context(ctx)).to be_empty
48
48
  end
49
49
  end
@@ -51,7 +51,7 @@ describe Reek::Smells::UncommunicativeModuleName do
51
51
  context 'looking at the YAML' do
52
52
  before :each do
53
53
  src = 'module Printer2; end'
54
- ctx = Reek::Core::CodeContext.new(nil, src.to_reek_source.syntax_tree)
54
+ ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
55
55
  smells = @detector.examine_context(ctx)
56
56
  @warning = smells[0]
57
57
  end
@@ -1,9 +1,9 @@
1
- require 'spec_helper'
2
- require 'reek/smells/uncommunicative_parameter_name'
3
- require 'reek/smells/smell_detector_shared'
4
- require 'reek/core/method_context'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/uncommunicative_parameter_name'
3
+ require_relative 'smell_detector_shared'
4
+ require_relative '../../../lib/reek/context/method_context'
5
5
 
6
- describe Reek::Smells::UncommunicativeParameterName do
6
+ RSpec.describe Reek::Smells::UncommunicativeParameterName do
7
7
  before :each do
8
8
  @source_name = 'dummy_source'
9
9
  @detector = build(:smell_detector,
@@ -63,13 +63,25 @@ describe Reek::Smells::UncommunicativeParameterName do
63
63
  expect("def #{host}help(_unused) basics(_unused) end").
64
64
  to reek_of(:UncommunicativeParameterName)
65
65
  end
66
+
67
+ it 'reports names inside array decomposition' do
68
+ src = "def #{host}help((b, nice)) basics(b, nice) end"
69
+ expect(src).to reek_of(:UncommunicativeParameterName,
70
+ name: 'b')
71
+ end
72
+
73
+ it 'reports names inside nested array decomposition' do
74
+ src = "def #{host}help((foo, (bar, c))) basics(foo, c) end"
75
+ expect(src).to reek_of(:UncommunicativeParameterName,
76
+ name: 'c')
77
+ end
66
78
  end
67
79
  end
68
80
 
69
81
  context 'looking at the smell result fields' do
70
82
  before :each do
71
83
  src = 'def bad(good, bad2, good_again); basics(good, bad2, good_again); end'
72
- ctx = Reek::Core::MethodContext.new(nil, src.to_reek_source.syntax_tree)
84
+ ctx = Reek::Context::MethodContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
73
85
  @smells = @detector.examine_context(ctx)
74
86
  @warning = @smells[0]
75
87
  end
@@ -1,8 +1,8 @@
1
- require 'spec_helper'
2
- require 'reek/smells/uncommunicative_variable_name'
3
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/uncommunicative_variable_name'
3
+ require_relative 'smell_detector_shared'
4
4
 
5
- describe Reek::Smells::UncommunicativeVariableName do
5
+ RSpec.describe Reek::Smells::UncommunicativeVariableName do
6
6
  before :each do
7
7
  @source_name = 'dummy_source'
8
8
  @detector = build(:smell_detector,
@@ -52,7 +52,8 @@ describe Reek::Smells::UncommunicativeVariableName do
52
52
 
53
53
  it 'reports variable name only once' do
54
54
  src = 'def simple(fred) x = jim(45); x = y end'
55
- ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
55
+ syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
56
+ ctx = Reek::Context::CodeContext.new(nil, syntax_tree)
56
57
  smells = @detector.examine_context(ctx)
57
58
  expect(smells.length).to eq(1)
58
59
  expect(smells[0].smell_type).to eq(described_class.smell_type)
@@ -163,7 +164,8 @@ describe Reek::Smells::UncommunicativeVariableName do
163
164
  end
164
165
  end
165
166
  EOS
166
- ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
167
+ syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
168
+ ctx = Reek::Context::CodeContext.new(nil, syntax_tree)
167
169
  @smells = @detector.examine_context(ctx)
168
170
  @warning = @smells[0]
169
171
  end
@@ -179,7 +181,8 @@ describe Reek::Smells::UncommunicativeVariableName do
179
181
  context 'when a smell is reported in a singleton method' do
180
182
  before :each do
181
183
  src = 'def self.bad() x2 = 4; end'
182
- ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
184
+ syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
185
+ ctx = Reek::Context::CodeContext.new(nil, syntax_tree)
183
186
  @smells = @detector.examine_context(ctx)
184
187
  @warning = @smells[0]
185
188
  end
@@ -1,8 +1,8 @@
1
- require 'spec_helper'
2
- require 'reek/smells/unused_parameters'
3
- require 'reek/smells/smell_detector_shared'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/unused_parameters'
3
+ require_relative 'smell_detector_shared'
4
4
 
5
- describe Reek::Smells::UnusedParameters do
5
+ RSpec.describe Reek::Smells::UnusedParameters do
6
6
  context 'for methods' do
7
7
  it 'reports nothing for no parameters' do
8
8
  expect('def simple; true end').not_to reek_of(:UnusedParameters)
@@ -1,30 +1,72 @@
1
- require 'spec_helper'
2
- require 'reek/smells/utility_function'
3
- require 'reek/smells/smell_detector_shared'
4
-
5
- describe Reek::Smells::UtilityFunction do
6
- before(:each) do
7
- @source_name = 'dummy_source'
8
- @detector = build(:smell_detector, smell_type: :UtilityFunction, source: @source_name)
9
- end
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/smells/utility_function'
3
+ require_relative 'smell_detector_shared'
4
+
5
+ RSpec.describe Reek::Smells::UtilityFunction do
6
+ describe 'a detector' do
7
+ before(:each) do
8
+ @source_name = 'dummy_source'
9
+ @detector = build(:smell_detector,
10
+ smell_type: :UtilityFunction,
11
+ source: @source_name)
12
+ end
13
+
14
+ it_should_behave_like 'SmellDetector'
15
+
16
+ context 'when a smells is reported' do
17
+ before :each do
18
+ src = <<-EOS
19
+ def simple(arga)
20
+ arga.b.c
21
+ end
22
+ EOS
23
+ source = Reek::Source::SourceCode.from(src)
24
+ mctx = Reek::TreeWalker.new.process_def(source.syntax_tree)
25
+ @warning = @detector.examine_context(mctx)[0] # SMELL: too cumbersome!
26
+ end
10
27
 
11
- it_should_behave_like 'SmellDetector'
28
+ it_should_behave_like 'common fields set correctly'
29
+
30
+ it 'reports the line number of the method' do
31
+ expect(@warning.lines).to eq([1])
32
+ end
33
+ end
34
+ end
12
35
 
13
36
  context 'with a singleton method' do
14
37
  ['self', 'local_call', '$global'].each do |receiver|
15
38
  it 'ignores the receiver' do
16
39
  src = "def #{receiver}.simple(arga) arga.to_s + arga.to_i end"
17
- ctx = Reek::Core::MethodContext.new(nil, src.to_reek_source.syntax_tree)
18
- expect(@detector.examine_context(ctx)).to be_empty
40
+ expect(src).not_to reek_of(:UtilityFunction)
19
41
  end
20
42
  end
21
43
  end
22
44
 
45
+ context 'Singleton methods' do
46
+ it 'for classes with `class << self` notation should not report UtilityFunction' do
47
+ src = 'class C; class << self; def m(a) a.to_s; end; end; end'
48
+ expect(src).not_to reek_of(:UtilityFunction)
49
+ end
50
+
51
+ it 'for classes with `self.` notation should not report UtilityFunction' do
52
+ src = 'class C; def self.m(a) a.to_s; end; end'
53
+ expect(src).not_to reek_of(:UtilityFunction)
54
+ end
55
+
56
+ it 'for modules with `class << self` notation should not report UtilityFunction' do
57
+ src = 'module M; class << self; def self.m(a) a.to_s; end; end; end'
58
+ expect(src).not_to reek_of(:UtilityFunction)
59
+ end
60
+
61
+ it 'for modules with `self.` notation should not report UtilityFunction' do
62
+ src = 'module M; def self.simple(a) a.to_s; end; end'
63
+ expect(src).not_to reek_of(:UtilityFunction)
64
+ end
65
+ end
66
+
23
67
  context 'with no calls' do
24
68
  it 'does not report empty method' do
25
- src = 'def simple(arga) end'
26
- ctx = Reek::Core::MethodContext.new(nil, src.to_reek_source.syntax_tree)
27
- expect(@detector.examine_context(ctx)).to be_empty
69
+ expect('def simple(arga) end').not_to reek_of(:UtilityFunction)
28
70
  end
29
71
 
30
72
  it 'does not report literal' do
@@ -53,12 +95,12 @@ describe Reek::Smells::UtilityFunction do
53
95
  end
54
96
 
55
97
  context 'with only one call' do
56
- it 'does not report a call to a parameter' do
57
- expect('def simple(arga) arga.to_s end').not_to reek_of(:UtilityFunction, name: 'simple')
98
+ it 'reports a call to a parameter' do
99
+ expect('def simple(arga) arga.to_s end').to reek_of(:UtilityFunction, name: 'simple')
58
100
  end
59
101
 
60
- it 'does not report a call to a constant' do
61
- expect('def simple(arga) FIELDS[arga] end').not_to reek_of(:UtilityFunction)
102
+ it 'reports a call to a constant' do
103
+ expect('def simple(arga) FIELDS[arga] end').to reek_of(:UtilityFunction)
62
104
  end
63
105
  end
64
106
 
@@ -66,6 +108,7 @@ describe Reek::Smells::UtilityFunction do
66
108
  it 'reports two calls' do
67
109
  src = 'def simple(arga) arga.to_s + arga.to_i end'
68
110
  expect(src).to reek_of(:UtilityFunction, name: 'simple')
111
+ expect(src).not_to reek_of(:FeatureEnvy)
69
112
  end
70
113
 
71
114
  it 'counts a local call in a param initializer' do
@@ -88,7 +131,9 @@ describe Reek::Smells::UtilityFunction do
88
131
  end
89
132
 
90
133
  it 'should report message chain' do
91
- expect('def simple(arga) arga.b.c end').to reek_of(:UtilityFunction, name: 'simple')
134
+ src = 'def simple(arga) arga.b.c end'
135
+ expect(src).to reek_of(:UtilityFunction, name: 'simple')
136
+ expect(src).not_to reek_of(:FeatureEnvy)
92
137
  end
93
138
 
94
139
  it 'does not report a method that calls super' do
@@ -110,23 +155,4 @@ describe Reek::Smells::UtilityFunction do
110
155
  expect(src).not_to reek_of(:UtilityFunction)
111
156
  end
112
157
  end
113
-
114
- context 'when a smells is reported' do
115
- before :each do
116
- src = <<-EOS
117
- def simple(arga)
118
- arga.b.c
119
- end
120
- EOS
121
- source = src.to_reek_source
122
- mctx = Reek::Core::TreeWalker.new.process_def(source.syntax_tree)
123
- @warning = @detector.examine_context(mctx)[0] # SMELL: too cumbersome!
124
- end
125
-
126
- it_should_behave_like 'common fields set correctly'
127
-
128
- it 'reports the line number of the method' do
129
- expect(@warning.lines).to eq([1])
130
- end
131
- end
132
158
  end
@@ -1,25 +1,25 @@
1
- require 'spec_helper'
1
+ require_relative '../../spec_helper'
2
2
  require 'stringio'
3
- require 'reek/source/source_code'
3
+ require_relative '../../../lib/reek/source/source_code'
4
4
 
5
- include Reek::Source
6
-
7
- describe SourceCode do
5
+ RSpec.describe Reek::Source::SourceCode do
8
6
  describe '#syntax_tree' do
9
7
  it 'associates comments with the AST' do
10
- source_code = SourceCode.new("# this is\n# a comment\ndef foo; end", '(string)')
8
+ source = "# this is\n# a comment\ndef foo; end"
9
+ source_code = Reek::Source::SourceCode.new(source, '(string)')
11
10
  result = source_code.syntax_tree
12
- expect(result.comments).to eq "# this is\n# a comment"
11
+ expect(result.leading_comment).to eq "# this is\n# a comment"
13
12
  end
14
13
 
15
14
  it 'cleanly processes empty source' do
16
- source_code = SourceCode.new('', '(string)')
15
+ source_code = Reek::Source::SourceCode.new('', '(string)')
17
16
  result = source_code.syntax_tree
18
17
  expect(result).to be_nil
19
18
  end
20
19
 
21
20
  it 'cleanly processes empty source with comments' do
22
- source_code = SourceCode.new("# this is\n# a comment\n", '(string)')
21
+ source = "# this is\n# a comment\n"
22
+ source_code = Reek::Source::SourceCode.new(source, '(string)')
23
23
  result = source_code.syntax_tree
24
24
  expect(result).to be_nil
25
25
  end
@@ -29,7 +29,7 @@ describe SourceCode do
29
29
  let(:source_name) { 'Test source' }
30
30
  let(:error_message) { 'Error message' }
31
31
  let(:parser) { double('parser') }
32
- let(:src) { SourceCode.new('', source_name, parser) }
32
+ let(:src) { Reek::Source::SourceCode.new('', source_name, parser) }
33
33
 
34
34
  before :each do
35
35
  @catcher = StringIO.new
@@ -0,0 +1,30 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/source/source_locator'
3
+
4
+ RSpec.describe Reek::Source::SourceLocator do
5
+ describe '#sources' do
6
+ context 'exclude paths' do
7
+ let(:config) { 'spec/samples/configuration/with_excluded_paths.reek' }
8
+ let(:path) { 'spec/samples/source_with_exclude_paths' }
9
+ let(:files_that_are_expected_to_be_ignored) do
10
+ [
11
+ 'spec/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb',
12
+ 'spec/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb'
13
+ ]
14
+ end
15
+
16
+ it 'does not use excluded paths' do
17
+ with_test_config(config) do
18
+ sources = described_class.new([path]).sources
19
+
20
+ expect(sources.map(&:path).sort).
21
+ not_to include(files_that_are_expected_to_be_ignored)
22
+
23
+ expect(sources.map(&:path).sort).to eq [
24
+ 'spec/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb'
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,10 +1,7 @@
1
- require 'spec_helper'
2
- require 'reek/spec'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/spec'
3
3
 
4
- include Reek
5
- include Reek::Spec
6
-
7
- describe ShouldReekOf do
4
+ RSpec.describe Reek::Spec::ShouldReekOf do
8
5
  context 'rdoc demo example' do
9
6
  before :each do
10
7
  @ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'
@@ -27,7 +24,8 @@ describe ShouldReekOf do
27
24
  before :each do
28
25
  @clean_code = 'def good() true; end'
29
26
  @smelly_code = 'def x() y = 4; end'
30
- @matcher = ShouldReekOf.new(:UncommunicativeVariableName, name: 'y')
27
+ @matcher = Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName,
28
+ name: 'y')
31
29
  end
32
30
 
33
31
  it 'matches a smelly String' do
@@ -47,7 +45,8 @@ describe ShouldReekOf do
47
45
  context 'passing in smell_details with unknown parameter name' do
48
46
  before :each do
49
47
  @smelly_code = 'def x() y = 4; end'
50
- @matcher = ShouldReekOf.new(:UncommunicativeVariableName, foo: 'y')
48
+ @matcher = Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName,
49
+ foo: 'y')
51
50
  end
52
51
 
53
52
  it 'raises ArgumentError' do
@@ -55,27 +54,12 @@ describe ShouldReekOf do
55
54
  end
56
55
  end
57
56
 
58
- context 'checking code in a Dir' do
59
- before :each do
60
- @clean_dir = Dir['spec/samples/three_clean_files/*.rb']
61
- @smelly_dir = Dir['spec/samples/two_smelly_files/*.rb']
62
- @matcher = ShouldReekOf.new(:UncommunicativeVariableName, name: '@s')
63
- end
64
-
65
- it 'matches a smelly String' do
66
- expect(@matcher.matches?(@smelly_dir)).to be_truthy
67
- end
68
-
69
- it 'doesnt match a fragrant String' do
70
- expect(@matcher.matches?(@clean_dir)).to be_falsey
71
- end
72
- end
73
-
74
57
  context 'checking code in a File' do
75
58
  before :each do
76
59
  @clean_file = File.new(Dir['spec/samples/three_clean_files/*.rb'][0])
77
60
  @smelly_file = File.new(Dir['spec/samples/two_smelly_files/*.rb'][0])
78
- @matcher = ShouldReekOf.new(:UncommunicativeVariableName, name: '@s')
61
+ @matcher = Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName,
62
+ name: '@s')
79
63
  end
80
64
 
81
65
  it 'matches a smelly String' do
@@ -1,14 +1,11 @@
1
- require 'spec_helper'
2
- require 'reek/spec'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/spec'
3
3
 
4
- include Reek
5
- include Reek::Spec
6
-
7
- describe ShouldReekOnlyOf do
4
+ RSpec.describe Reek::Spec::ShouldReekOnlyOf do
8
5
  before :each do
9
6
  @expected_smell_type = :NestedIterators
10
7
  @expected_context_name = 'SmellyClass#big_method'
11
- @matcher = ShouldReekOnlyOf.new(@expected_smell_type)
8
+ @matcher = Reek::Spec::ShouldReekOnlyOf.new(@expected_smell_type)
12
9
  @examiner = double('examiner').as_null_object
13
10
  expect(@examiner).to receive(:smells) { smells }
14
11
  @match = @matcher.matches_examiner?(@examiner)
@@ -1,11 +1,8 @@
1
- require 'spec_helper'
2
- require 'reek/spec'
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/reek/spec'
3
3
 
4
- include Reek
5
- include Reek::Spec
6
-
7
- describe ShouldReek do
8
- let(:matcher) { ShouldReek.new }
4
+ RSpec.describe Reek::Spec::ShouldReek do
5
+ let(:matcher) { Reek::Spec::ShouldReek.new }
9
6
 
10
7
  describe 'checking code in a string' do
11
8
  let(:clean_code) { 'def good() true; end' }
@@ -25,31 +22,6 @@ describe ShouldReek do
25
22
  end
26
23
  end
27
24
 
28
- describe 'checking code in a Dir' do
29
- let(:clean_dir) { Dir['spec/samples/three_clean_files/*.rb'] }
30
- let(:smelly_dir) { Dir['spec/samples/two_smelly_files/*.rb'] }
31
- let(:masked_dir) { Dir['spec/samples/clean_due_to_masking/*.rb'] }
32
-
33
- it 'matches a smelly Dir' do
34
- expect(matcher.matches?(smelly_dir)).to be_truthy
35
- end
36
-
37
- it 'doesnt match a fragrant Dir' do
38
- expect(matcher.matches?(clean_dir)).to be_falsey
39
- end
40
-
41
- it 'masks smells using the relevant configuration' do
42
- with_test_config('spec/samples/clean_due_to_masking/masked.reek') do
43
- expect(matcher.matches?(masked_dir)).to be_falsey
44
- end
45
- end
46
-
47
- it 'reports the smells when should_not fails' do
48
- matcher.matches?(smelly_dir)
49
- expect(matcher.failure_message_when_negated).to match('UncommunicativeVariableName')
50
- end
51
- end
52
-
53
25
  describe 'checking code in a File' do
54
26
  let(:clean_file) { File.new('spec/samples/three_clean_files/clean_one.rb') }
55
27
  let(:smelly_file) { File.new('spec/samples/two_smelly_files/dirty_one.rb') }
@@ -0,0 +1,16 @@
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/reek/tree_dresser'
3
+
4
+ RSpec.describe Reek::TreeDresser do
5
+ let(:ifnode) { ::Parser::AST::Node.new(:if) }
6
+ let(:sendnode) { ::Parser::AST::Node.new(:send) }
7
+ let(:dresser) { described_class.new }
8
+
9
+ it 'dresses :if sexp with IfNode' do
10
+ expect(dresser.dress(ifnode, {})).to be_a Reek::AST::SexpExtensions::IfNode
11
+ end
12
+
13
+ it 'dresses :send sexp with SendNode' do
14
+ expect(dresser.dress(sendnode, {})).to be_a Reek::AST::SexpExtensions::SendNode
15
+ end
16
+ end
@@ -1,9 +1,7 @@
1
- require 'spec_helper'
2
- require 'reek/core/tree_walker'
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/reek/tree_walker'
3
3
 
4
- include Reek::Core
5
-
6
- describe TreeWalker, 'with no method definitions' do
4
+ RSpec.describe Reek::TreeWalker, 'with no method definitions' do
7
5
  it 'reports no problems for empty source code' do
8
6
  expect('').not_to reek
9
7
  end
@@ -13,14 +11,14 @@ class Fred; end').not_to reek
13
11
  end
14
12
  end
15
13
 
16
- describe TreeWalker, 'with a global method definition' do
14
+ RSpec.describe Reek::TreeWalker, 'with a global method definition' do
17
15
  it 'reports no problems for simple method' do
18
16
  src = 'def Outermost::fred() true; end'
19
17
  expect(src).not_to reek
20
18
  end
21
19
  end
22
20
 
23
- describe TreeWalker, 'when a yield is the receiver' do
21
+ RSpec.describe Reek::TreeWalker, 'when a yield is the receiver' do
24
22
  it 'reports no problems' do
25
23
  src = <<EOS
26
24
  def values(*args)
@@ -0,0 +1,2 @@
1
+ <?xml version='1.0'?>
2
+ <checkstyle><file name='/some/path'><error column='0' line='1' message='doesn&apos;t depend on instance state' severity='warning' source='UtilityFunction'/><error column='0' line='1' message='has the parameter name &apos;a&apos;' severity='warning' source='UncommunicativeParameterName'/></file></checkstyle>
@@ -0,0 +1,4 @@
1
+ ---
2
+ exclude_paths:
3
+ - spec/samples/source_with_exclude_paths/ignore_me/
4
+ - spec/samples/source_with_exclude_paths/nested/ignore_me_as_well
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  DuplicateMethodCall:
3
- enabled: true
3
+ enabled: false
4
4
  UncommunicativeVariableName:
5
5
  enabled: false
6
6
  UncommunicativeMethodName:
7
7
  enabled: false
8
+ UncommunicativeParameterName:
9
+ enabled: false
@@ -0,0 +1,5 @@
1
+ # Klass comment.
2
+ class Klass
3
+ def m
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ # Klass comment
2
+ class Klass
3
+ def method(a)
4
+ a + @x
5
+ end
6
+ end