reek 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +9 -0
  3. data/README.md +54 -5
  4. data/Rakefile +1 -1
  5. data/features/command_line_interface/smell_selection.feature +4 -4
  6. data/features/command_line_interface/smells_count.feature +9 -8
  7. data/features/configuration_files/masking_smells.feature +16 -51
  8. data/features/configuration_files/overrides_defaults.feature +1 -1
  9. data/features/rake_task/rake_task.feature +14 -14
  10. data/features/reports/reports.feature +21 -19
  11. data/features/reports/yaml.feature +35 -63
  12. data/features/samples.feature +55 -54
  13. data/features/support/env.rb +8 -1
  14. data/lib/reek/cli/application.rb +22 -7
  15. data/lib/reek/cli/command.rb +4 -2
  16. data/lib/reek/cli/help_command.rb +1 -1
  17. data/lib/reek/cli/options.rb +3 -3
  18. data/lib/reek/cli/reek_command.rb +4 -8
  19. data/lib/reek/cli/report/formatter.rb +8 -5
  20. data/lib/reek/cli/report/report.rb +6 -5
  21. data/lib/reek/cli/report/strategy.rb +3 -2
  22. data/lib/reek/cli/version_command.rb +1 -1
  23. data/lib/reek/configuration/app_configuration.rb +75 -0
  24. data/lib/reek/configuration/configuration_file_finder.rb +56 -0
  25. data/lib/reek/core/code_context.rb +2 -6
  26. data/lib/reek/core/module_context.rb +4 -0
  27. data/lib/reek/core/smell_repository.rb +5 -3
  28. data/lib/reek/core/sniffer.rb +12 -8
  29. data/lib/reek/examiner.rb +7 -6
  30. data/lib/reek/rake/task.rb +10 -12
  31. data/lib/reek/smell_warning.rb +25 -43
  32. data/lib/reek/smells/attribute.rb +7 -12
  33. data/lib/reek/smells/boolean_parameter.rb +9 -9
  34. data/lib/reek/smells/class_variable.rb +7 -13
  35. data/lib/reek/smells/control_parameter.rb +8 -11
  36. data/lib/reek/smells/data_clump.rb +16 -21
  37. data/lib/reek/smells/duplicate_method_call.rb +11 -18
  38. data/lib/reek/smells/feature_envy.rb +8 -8
  39. data/lib/reek/smells/irresponsible_module.rb +6 -10
  40. data/lib/reek/smells/long_parameter_list.rb +7 -15
  41. data/lib/reek/smells/long_yield_list.rb +13 -15
  42. data/lib/reek/smells/module_initialize.rb +4 -7
  43. data/lib/reek/smells/nested_iterators.rb +6 -13
  44. data/lib/reek/smells/nil_check.rb +9 -7
  45. data/lib/reek/smells/prima_donna_method.rb +5 -7
  46. data/lib/reek/smells/repeated_conditional.rb +19 -15
  47. data/lib/reek/smells/smell_detector.rb +21 -1
  48. data/lib/reek/smells/too_many_instance_variables.rb +9 -16
  49. data/lib/reek/smells/too_many_methods.rb +10 -17
  50. data/lib/reek/smells/too_many_statements.rb +14 -14
  51. data/lib/reek/smells/uncommunicative_method_name.rb +9 -10
  52. data/lib/reek/smells/uncommunicative_module_name.rb +9 -10
  53. data/lib/reek/smells/uncommunicative_parameter_name.rb +9 -9
  54. data/lib/reek/smells/uncommunicative_variable_name.rb +9 -9
  55. data/lib/reek/smells/unused_parameters.rb +8 -20
  56. data/lib/reek/smells/utility_function.rb +12 -10
  57. data/lib/reek/source.rb +0 -1
  58. data/lib/reek/source/code_comment.rb +1 -0
  59. data/lib/reek/source/source_code.rb +3 -13
  60. data/lib/reek/source/source_file.rb +0 -14
  61. data/lib/reek/source/source_repository.rb +7 -0
  62. data/lib/reek/spec/should_reek_of.rb +3 -3
  63. data/lib/reek/spec/should_reek_only_of.rb +2 -2
  64. data/lib/reek/version.rb +1 -1
  65. data/reek.gemspec +4 -2
  66. data/spec/factories/factories.rb +32 -0
  67. data/spec/matchers/smell_of_matcher.rb +3 -2
  68. data/spec/reek/cli/report_spec.rb +2 -1
  69. data/spec/reek/configuration/app_configuration_spec.rb +67 -0
  70. data/spec/reek/configuration/configuration_file_finder_spec.rb +35 -0
  71. data/spec/reek/core/code_context_spec.rb +1 -1
  72. data/spec/reek/core/module_context_spec.rb +5 -1
  73. data/spec/reek/core/smell_configuration_spec.rb +21 -13
  74. data/spec/reek/core/warning_collector_spec.rb +4 -1
  75. data/spec/reek/examiner_spec.rb +19 -1
  76. data/spec/reek/smell_warning_spec.rb +42 -36
  77. data/spec/reek/smells/attribute_spec.rb +6 -2
  78. data/spec/reek/smells/boolean_parameter_spec.rb +11 -12
  79. data/spec/reek/smells/class_variable_spec.rb +16 -6
  80. data/spec/reek/smells/control_parameter_spec.rb +17 -19
  81. data/spec/reek/smells/data_clump_spec.rb +25 -15
  82. data/spec/reek/smells/duplicate_method_call_spec.rb +18 -12
  83. data/spec/reek/smells/feature_envy_spec.rb +29 -10
  84. data/spec/reek/smells/irresponsible_module_spec.rb +7 -7
  85. data/spec/reek/smells/long_parameter_list_spec.rb +16 -10
  86. data/spec/reek/smells/long_yield_list_spec.rb +2 -2
  87. data/spec/reek/smells/module_initialize_spec.rb +26 -0
  88. data/spec/reek/smells/nested_iterators_spec.rb +21 -10
  89. data/spec/reek/smells/nil_check_spec.rb +0 -2
  90. data/spec/reek/smells/prima_donna_method_spec.rb +3 -3
  91. data/spec/reek/smells/repeated_conditional_spec.rb +0 -26
  92. data/spec/reek/smells/smell_detector_shared.rb +4 -4
  93. data/spec/reek/smells/too_many_instance_variables_spec.rb +3 -3
  94. data/spec/reek/smells/too_many_methods_spec.rb +16 -11
  95. data/spec/reek/smells/too_many_statements_spec.rb +55 -18
  96. data/spec/reek/smells/uncommunicative_method_name_spec.rb +3 -2
  97. data/spec/reek/smells/uncommunicative_module_name_spec.rb +5 -5
  98. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +4 -4
  99. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +28 -21
  100. data/spec/reek/smells/unused_parameters_spec.rb +3 -5
  101. data/spec/reek/smells/utility_function_spec.rb +2 -1
  102. data/spec/reek/source/code_comment_spec.rb +7 -2
  103. data/spec/reek/source/reference_collector_spec.rb +0 -1
  104. data/spec/reek/source/sexp_extensions_spec.rb +0 -15
  105. data/spec/reek/source/source_code_spec.rb +13 -1
  106. data/spec/reek/spec/should_reek_only_of_spec.rb +22 -10
  107. data/spec/reek/spec/should_reek_spec.rb +6 -2
  108. data/spec/samples/minimal_smelly_and_masked/config.reek +7 -0
  109. data/spec/samples/minimal_smelly_and_masked/minimal_dirty.rb +4 -0
  110. data/spec/samples/simple_configuration.reek +5 -0
  111. data/spec/samples/standard_smelly/dirty.rb +8 -0
  112. data/spec/samples/standard_smelly/minimal_dirty.rb +4 -0
  113. data/spec/spec_helper.rb +20 -0
  114. data/tasks/develop.rake +1 -1
  115. data/tasks/rubocop.rake +5 -0
  116. metadata +41 -6
  117. data/lib/reek/config_file_exception.rb +0 -7
  118. data/lib/reek/smell_description.rb +0 -26
  119. data/lib/reek/source/config_file.rb +0 -88
  120. data/spec/reek/smell_description_spec.rb +0 -43
@@ -8,23 +8,17 @@ module Reek
8
8
  # passed to a block by a +yield+ call.
9
9
  #
10
10
  class LongYieldList < SmellDetector
11
- SMELL_CLASS = 'LongParameterList'
12
- SMELL_SUBCLASS = name.split(/::/)[-1]
13
-
14
11
  # The name of the config field that sets the maximum number of
15
12
  # parameters permitted in any method or block.
16
13
  MAX_ALLOWED_PARAMS_KEY = 'max_params'
17
-
18
- # The default value of the +MAX_ALLOWED_PARAMS_KEY+ configuration
19
- # value.
20
14
  DEFAULT_MAX_ALLOWED_PARAMS = 3
21
15
 
22
- PARAMETER_COUNT_KEY = 'parameter_count'
16
+ def self.smell_category
17
+ 'LongParameterList'
18
+ end
23
19
 
24
20
  def self.default_config
25
- super.merge(
26
- MAX_ALLOWED_PARAMS_KEY => DEFAULT_MAX_ALLOWED_PARAMS
27
- )
21
+ super.merge MAX_ALLOWED_PARAMS_KEY => DEFAULT_MAX_ALLOWED_PARAMS
28
22
  end
29
23
 
30
24
  #
@@ -33,14 +27,18 @@ module Reek
33
27
  # @return [Array<SmellWarning>]
34
28
  #
35
29
  def examine_context(method_ctx)
36
- @max_allowed_params = value(MAX_ALLOWED_PARAMS_KEY, method_ctx, DEFAULT_MAX_ALLOWED_PARAMS)
30
+ @max_allowed_params = value(MAX_ALLOWED_PARAMS_KEY,
31
+ method_ctx,
32
+ DEFAULT_MAX_ALLOWED_PARAMS)
37
33
  method_ctx.local_nodes(:yield).select do |yield_node|
38
34
  yield_node.args.length > @max_allowed_params
39
35
  end.map do |yield_node|
40
- num_params = yield_node.args.length
41
- SmellWarning.new(SMELL_CLASS, method_ctx.full_name, [yield_node.line],
42
- "yields #{num_params} parameters",
43
- @source, SMELL_SUBCLASS, PARAMETER_COUNT_KEY => num_params)
36
+ count = yield_node.args.length
37
+ SmellWarning.new self,
38
+ context: method_ctx.full_name,
39
+ lines: [yield_node.line],
40
+ message: "yields #{count} parameters",
41
+ parameters: { count: count }
44
42
  end
45
43
  end
46
44
  end
@@ -9,10 +9,7 @@ module Reek
9
9
  # in a module is usually a bad idea
10
10
  #
11
11
  class ModuleInitialize < SmellDetector
12
- SMELL_CLASS = smell_class_name
13
- SMELL_SUBCLASS = SMELL_CLASS
14
-
15
- def self.contexts # :nodoc:
12
+ def self.contexts # :nodoc:
16
13
  [:module]
17
14
  end
18
15
 
@@ -25,9 +22,9 @@ module Reek
25
22
  module_ctx.local_nodes(:def) do |node| # FIXME: also search for :defs?
26
23
  if node.name.to_s == 'initialize'
27
24
  return [
28
- SmellWarning.new(SMELL_CLASS, module_ctx.full_name, [module_ctx.exp.line],
29
- 'has initialize method',
30
- @source, SMELL_SUBCLASS, {})
25
+ SmellWarning.new(self, context: module_ctx.full_name,
26
+ lines: [module_ctx.exp.line],
27
+ message: 'has initialize method')
31
28
  ]
32
29
  end
33
30
  end
@@ -9,21 +9,14 @@ module Reek
9
9
  # +NestedIterators+ reports failing methods only once.
10
10
  #
11
11
  class NestedIterators < SmellDetector
12
- SMELL_CLASS = name.split(/::/)[-1]
13
- SMELL_SUBCLASS = SMELL_CLASS
14
- # SMELL: should be a subclass of UnnecessaryComplexity
15
- NESTING_DEPTH_KEY = 'depth'
16
-
17
12
  # The name of the config field that sets the maximum depth
18
13
  # of nested iterators to be permitted within any single method.
19
14
  MAX_ALLOWED_NESTING_KEY = 'max_allowed_nesting'
20
-
21
15
  DEFAULT_MAX_ALLOWED_NESTING = 1
22
16
 
23
17
  # The name of the config field that sets the names of any
24
18
  # methods for which nesting should not be considered
25
19
  IGNORE_ITERATORS_KEY = 'ignore_iterators'
26
-
27
20
  DEFAULT_IGNORE_ITERATORS = []
28
21
 
29
22
  def self.default_config
@@ -42,11 +35,11 @@ module Reek
42
35
  exp, depth = *find_deepest_iterator(ctx)
43
36
 
44
37
  if depth && depth > value(MAX_ALLOWED_NESTING_KEY, ctx, DEFAULT_MAX_ALLOWED_NESTING)
45
- smell = SmellWarning.new(SMELL_CLASS, ctx.full_name, [exp.line],
46
- "contains iterators nested #{depth} deep",
47
- @source, SMELL_SUBCLASS,
48
- NESTING_DEPTH_KEY => depth)
49
- [smell]
38
+ [SmellWarning.new(self,
39
+ context: ctx.full_name,
40
+ lines: [exp.line],
41
+ message: "contains iterators nested #{depth} deep",
42
+ parameters: { count: depth })]
50
43
  else
51
44
  []
52
45
  end
@@ -71,7 +64,7 @@ module Reek
71
64
  def find_iters_for_iter_node(exp, depth)
72
65
  ignored = ignored_iterator? exp
73
66
  result = find_iters(exp.call, depth) +
74
- find_iters(exp.block, depth + (ignored ? 0 : 1))
67
+ find_iters(exp.block, depth + (ignored ? 0 : 1))
75
68
  result << [exp, depth] unless ignored
76
69
  result
77
70
  end
@@ -6,8 +6,9 @@ module Reek
6
6
  # Checking for nil is a special kind of type check, and therefore a case of
7
7
  # SimulatedPolymorphism.
8
8
  class NilCheck < SmellDetector
9
- SMELL_CLASS = 'SimulatedPolymorphism'
10
- SMELL_SUBCLASS = name.split(/::/)[-1]
9
+ def self.smell_category
10
+ 'SimulatedPolymorphism'
11
+ end
11
12
 
12
13
  def examine_context(ctx)
13
14
  call_node_finder = NodeFinder.new(ctx, :send, NilCallNodeDetector)
@@ -15,9 +16,10 @@ module Reek
15
16
  smelly_nodes = call_node_finder.smelly_nodes + case_node_finder.smelly_nodes
16
17
 
17
18
  smelly_nodes.map do |node|
18
- SmellWarning.new(SMELL_CLASS, ctx.full_name, Array(node.line),
19
- 'performs a nil-check.',
20
- @source, SMELL_SUBCLASS)
19
+ SmellWarning.new self,
20
+ context: ctx.full_name,
21
+ lines: [node.line],
22
+ message: 'performs a nil-check.'
21
23
  end
22
24
  end
23
25
 
@@ -50,10 +52,10 @@ module Reek
50
52
  end
51
53
 
52
54
  def nil_comparison?(call)
53
- is_comparison_call?(call) && involves_nil?(call)
55
+ comparison_call?(call) && involves_nil?(call)
54
56
  end
55
57
 
56
- def is_comparison_call?(call)
58
+ def comparison_call?(call)
57
59
  comparison_methods.include? call.method_name
58
60
  end
59
61
 
@@ -23,10 +23,7 @@ module Reek
23
23
  # Such a method is called PrimaDonnaMethod and is reported as a smell.
24
24
  #
25
25
  class PrimaDonnaMethod < SmellDetector
26
- SMELL_CLASS = smell_class_name
27
- SMELL_SUBCLASS = smell_class_name
28
-
29
- def self.contexts
26
+ def self.contexts # :nodoc:
30
27
  [:class]
31
28
  end
32
29
 
@@ -39,9 +36,10 @@ module Reek
39
36
  end
40
37
  next if version_without_bang
41
38
 
42
- SmellWarning.new(SMELL_CLASS, ctx.full_name, [ctx.exp.line],
43
- "has prima donna method `#{method_sexp.name}`",
44
- @source, SMELL_SUBCLASS)
39
+ SmellWarning.new self,
40
+ context: ctx.full_name,
41
+ lines: [ctx.exp.line],
42
+ message: "has prima donna method `#{method_sexp.name}`"
45
43
  end.compact
46
44
  end
47
45
  end
@@ -6,8 +6,10 @@ module Reek
6
6
  #
7
7
  # Simulated Polymorphism occurs when
8
8
  # * code uses a case statement (especially on a type field);
9
- # * or code has several if statements in a row (especially if they're comparing against the same value);
10
- # * or code uses instance_of?, kind_of?, is_a?, or === to decide what type it's working with;
9
+ # * or code has several if statements in a row
10
+ # (especially if they're comparing against the same value);
11
+ # * or code uses instance_of?, kind_of?, is_a?, or ===
12
+ # to decide what type it's working with;
11
13
  # * or multiple conditionals in different places test the same value.
12
14
  #
13
15
  # Conditional code is hard to read and understand, because the reader must
@@ -21,20 +23,21 @@ module Reek
21
23
  # testing the same value throughout a single class.
22
24
  #
23
25
  class RepeatedConditional < SmellDetector
24
- SMELL_CLASS = 'SimulatedPolymorphism'
25
- SMELL_SUBCLASS = name.split(/::/)[-1]
26
+ # The name of the config field that sets the maximum number of
27
+ # identical conditionals permitted within any single class.
28
+ MAX_IDENTICAL_IFS_KEY = 'max_ifs'
29
+ DEFAULT_MAX_IFS = 2
30
+
31
+ def self.smell_category
32
+ 'SimulatedPolymorphism'
33
+ end
34
+
26
35
  BLOCK_GIVEN_CONDITION = AST::Node.new(:send, [nil, :block_given?])
27
36
 
28
37
  def self.contexts # :nodoc:
29
38
  [:class]
30
39
  end
31
40
 
32
- # The name of the config field that sets the maximum number of
33
- # identical conditionals permitted within any single class.
34
- MAX_IDENTICAL_IFS_KEY = 'max_ifs'
35
-
36
- DEFAULT_MAX_IFS = 2
37
-
38
41
  def self.default_config
39
42
  super.merge(MAX_IDENTICAL_IFS_KEY => DEFAULT_MAX_IFS)
40
43
  end
@@ -50,11 +53,12 @@ module Reek
50
53
  lines.length > @max_identical_ifs
51
54
  end.map do |key, lines|
52
55
  occurs = lines.length
53
- expr = key.format_ruby
54
- SmellWarning.new(SMELL_CLASS, ctx.full_name, lines,
55
- "tests #{expr} at least #{occurs} times",
56
- @source, SMELL_SUBCLASS,
57
- 'expression' => expr, 'occurrences' => occurs)
56
+ expression = key.format_ruby
57
+ SmellWarning.new self,
58
+ context: ctx.full_name,
59
+ lines: lines,
60
+ message: "tests #{expression} at least #{occurs} times",
61
+ parameters: { name: expression, count: occurs }
58
62
  end
59
63
  end
60
64
 
@@ -14,6 +14,8 @@ module Reek
14
14
  # Shared responsibilities of all smell detectors.
15
15
  #
16
16
  class SmellDetector
17
+ attr_reader :source, :smell_category, :smell_type
18
+
17
19
  # The name of the config field that lists the names of code contexts
18
20
  # that should not be checked. Add this field to the config for each
19
21
  # smell that should ignore this code element.
@@ -34,8 +36,26 @@ module Reek
34
36
  EXCLUDE_KEY => DEFAULT_EXCLUDE_SET.dup
35
37
  }
36
38
  end
39
+ end
40
+
41
+ def smell_category
42
+ self.class.smell_category
43
+ end
44
+
45
+ def smell_type
46
+ self.class.smell_type
47
+ end
48
+
49
+ class << self
50
+ def smell_category
51
+ @smell_category ||= default_smell_category
52
+ end
53
+
54
+ def smell_type
55
+ @smell_type ||= default_smell_category
56
+ end
37
57
 
38
- def smell_class_name
58
+ def default_smell_category
39
59
  name.split(/::/)[-1]
40
60
  end
41
61
  end
@@ -11,16 +11,15 @@ module Reek
11
11
  # configurable number of instance variables.
12
12
  #
13
13
  class TooManyInstanceVariables < SmellDetector
14
- SMELL_CLASS = 'LargeClass'
15
- SMELL_SUBCLASS = name.split(/::/)[-1]
16
- IVAR_COUNT_KEY = 'ivar_count'
17
-
18
14
  # The name of the config field that sets the maximum number of instance
19
15
  # variables permitted in a class.
20
16
  MAX_ALLOWED_IVARS_KEY = 'max_instance_variables'
21
-
22
17
  DEFAULT_MAX_IVARS = 9
23
18
 
19
+ def self.smell_category
20
+ 'LargeClass'
21
+ end
22
+
24
23
  def self.contexts # :nodoc:
25
24
  [:class]
26
25
  end
@@ -39,19 +38,13 @@ module Reek
39
38
  #
40
39
  def examine_context(ctx)
41
40
  @max_allowed_ivars = value(MAX_ALLOWED_IVARS_KEY, ctx, DEFAULT_MAX_IVARS)
42
- check_num_ivars(ctx)
43
- end
44
-
45
- private
46
-
47
- def check_num_ivars(ctx) # :nodoc:
48
41
  count = ctx.local_nodes(:ivasgn).map { |ivasgn| ivasgn[1] }.uniq.length
49
42
  return [] if count <= @max_allowed_ivars
50
- smell = SmellWarning.new(SMELL_CLASS, ctx.full_name, [ctx.exp.line],
51
- "has at least #{count} instance variables",
52
- @source, SMELL_SUBCLASS,
53
- IVAR_COUNT_KEY => count)
54
- [smell]
43
+ [SmellWarning.new(self,
44
+ context: ctx.full_name,
45
+ lines: [ctx.exp.line],
46
+ message: "has at least #{count} instance variables",
47
+ parameters: { count: count })]
55
48
  end
56
49
  end
57
50
  end
@@ -13,17 +13,16 @@ module Reek
13
13
  # modules.
14
14
  #
15
15
  class TooManyMethods < SmellDetector
16
- SMELL_CLASS = 'LargeClass'
17
- SMELL_SUBCLASS = name.split(/::/)[-1]
18
- METHOD_COUNT_KEY = 'method_count'
19
-
20
16
  # The name of the config field that sets the maximum number of methods
21
17
  # permitted in a class.
22
18
  MAX_ALLOWED_METHODS_KEY = 'max_methods'
23
-
24
19
  DEFAULT_MAX_METHODS = 25
25
20
 
26
- def self.contexts # :nodoc:
21
+ def self.smell_category
22
+ 'LargeClass'
23
+ end
24
+
25
+ def self.contexts # :nodoc:
27
26
  [:class]
28
27
  end
29
28
 
@@ -41,19 +40,13 @@ module Reek
41
40
  #
42
41
  def examine_context(ctx)
43
42
  @max_allowed_methods = value(MAX_ALLOWED_METHODS_KEY, ctx, DEFAULT_MAX_METHODS)
44
- check_num_methods(ctx)
45
- end
46
-
47
- private
48
-
49
- def check_num_methods(ctx) # :nodoc:
50
43
  actual = ctx.node_instance_methods.length
51
44
  return [] if actual <= @max_allowed_methods
52
- smell = SmellWarning.new(SMELL_CLASS, ctx.full_name, [ctx.exp.line],
53
- "has at least #{actual} methods",
54
- @source, SMELL_SUBCLASS,
55
- METHOD_COUNT_KEY => actual)
56
- [smell]
45
+ [SmellWarning.new(self,
46
+ context: ctx.full_name,
47
+ lines: [ctx.exp.line],
48
+ message: "has at least #{actual} methods",
49
+ parameters: { count: actual })]
57
50
  end
58
51
  end
59
52
  end
@@ -9,17 +9,15 @@ module Reek
9
9
  # +TooManyStatements+ reports any method with more than 5 statements.
10
10
  #
11
11
  class TooManyStatements < SmellDetector
12
- SMELL_CLASS = 'LongMethod'
13
- SMELL_SUBCLASS = name.split(/::/)[-1]
14
-
15
- STATEMENT_COUNT_KEY = 'statement_count'
16
-
17
12
  # The name of the config field that sets the maximum number of
18
13
  # statements permitted in any method.
19
14
  MAX_ALLOWED_STATEMENTS_KEY = 'max_statements'
20
-
21
15
  DEFAULT_MAX_STATEMENTS = 5
22
16
 
17
+ def self.smell_category
18
+ 'LongMethod'
19
+ end
20
+
23
21
  def self.default_config
24
22
  super.merge(
25
23
  MAX_ALLOWED_STATEMENTS_KEY => DEFAULT_MAX_STATEMENTS,
@@ -33,14 +31,16 @@ module Reek
33
31
  # @return [Array<SmellWarning>]
34
32
  #
35
33
  def examine_context(ctx)
36
- @max_allowed_statements = value(MAX_ALLOWED_STATEMENTS_KEY, ctx, DEFAULT_MAX_STATEMENTS)
37
- num = ctx.num_statements
38
- return [] if num <= @max_allowed_statements
39
- smell = SmellWarning.new(SMELL_CLASS, ctx.full_name, [ctx.exp.line],
40
- "has approx #{num} statements",
41
- @source, SMELL_SUBCLASS,
42
- STATEMENT_COUNT_KEY => num)
43
- [smell]
34
+ @max_allowed_statements = value(MAX_ALLOWED_STATEMENTS_KEY,
35
+ ctx,
36
+ DEFAULT_MAX_STATEMENTS)
37
+ count = ctx.num_statements
38
+ return [] if count <= @max_allowed_statements
39
+ [SmellWarning.new(self,
40
+ context: ctx.full_name,
41
+ lines: [ctx.exp.line],
42
+ message: "has approx #{count} statements",
43
+ parameters: { count: count })]
44
44
  end
45
45
  end
46
46
  end
@@ -17,23 +17,21 @@ module Reek
17
17
  # * names ending with a number
18
18
  #
19
19
  class UncommunicativeMethodName < SmellDetector
20
- SMELL_CLASS = 'UncommunicativeName'
21
- SMELL_SUBCLASS = name.split(/::/)[-1]
22
- METHOD_NAME_KEY = 'method_name'
23
-
24
20
  # The name of the config field that lists the regexps of
25
21
  # smelly names to be reported.
26
22
  REJECT_KEY = 'reject'
27
-
28
23
  DEFAULT_REJECT_SET = [/^[a-z]$/, /[0-9]$/, /[A-Z]/]
29
24
 
30
25
  # The name of the config field that lists the specific names that are
31
26
  # to be treated as exceptions; these names will not be reported as
32
27
  # uncommunicative.
33
28
  ACCEPT_KEY = 'accept'
34
-
35
29
  DEFAULT_ACCEPT_SET = []
36
30
 
31
+ def self.smell_category
32
+ 'UncommunicativeName'
33
+ end
34
+
37
35
  def self.default_config
38
36
  super.merge(
39
37
  REJECT_KEY => DEFAULT_REJECT_SET,
@@ -54,10 +52,11 @@ module Reek
54
52
  var = name.gsub(/^[@\*\&]*/, '')
55
53
  return [] if @accept_names.include?(var)
56
54
  return [] unless @reject_names.find { |patt| patt =~ var }
57
- smell = SmellWarning.new('UncommunicativeName', ctx.full_name, [ctx.exp.line],
58
- "has the name '#{name}'",
59
- @source, 'UncommunicativeMethodName', METHOD_NAME_KEY => name)
60
- [smell]
55
+ [SmellWarning.new(self,
56
+ context: ctx.full_name,
57
+ lines: [ctx.exp.line],
58
+ message: "has the name '#{name}'",
59
+ parameters: { name: name })]
61
60
  end
62
61
  end
63
62
  end