reek 1.3.1 → 1.3.2

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 (128) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +6 -0
  3. data/README.md +15 -9
  4. data/bin/reek +1 -1
  5. data/config/defaults.reek +71 -86
  6. data/features/command_line_interface/options.feature +0 -15
  7. data/features/reports/reports.feature +23 -0
  8. data/features/samples.feature +3 -12
  9. data/lib/reek.rb +3 -3
  10. data/lib/reek/cli/application.rb +1 -1
  11. data/lib/reek/cli/command_line.rb +10 -8
  12. data/lib/reek/cli/reek_command.rb +6 -7
  13. data/lib/reek/cli/report.rb +34 -38
  14. data/lib/reek/cli/version_command.rb +1 -1
  15. data/lib/reek/cli/yaml_command.rb +1 -1
  16. data/lib/reek/core/code_parser.rb +4 -4
  17. data/lib/reek/core/hash_extensions.rb +2 -2
  18. data/lib/reek/core/method_context.rb +2 -2
  19. data/lib/reek/core/module_context.rb +4 -4
  20. data/lib/reek/core/singleton_method_context.rb +1 -1
  21. data/lib/reek/core/smell_repository.rb +7 -6
  22. data/lib/reek/core/sniffer.rb +4 -4
  23. data/lib/reek/examiner.rb +10 -3
  24. data/lib/reek/smell_warning.rb +0 -2
  25. data/lib/reek/smells.rb +22 -21
  26. data/lib/reek/smells/attribute.rb +4 -8
  27. data/lib/reek/smells/boolean_parameter.rb +2 -2
  28. data/lib/reek/smells/class_variable.rb +3 -2
  29. data/lib/reek/smells/{control_couple.rb → control_parameter.rb} +5 -5
  30. data/lib/reek/smells/data_clump.rb +13 -29
  31. data/lib/reek/smells/{duplication.rb → duplicate_method_call.rb} +9 -11
  32. data/lib/reek/smells/feature_envy.rb +2 -2
  33. data/lib/reek/smells/irresponsible_module.rb +3 -2
  34. data/lib/reek/smells/long_parameter_list.rb +6 -10
  35. data/lib/reek/smells/long_yield_list.rb +4 -8
  36. data/lib/reek/smells/nested_iterators.rb +31 -25
  37. data/lib/reek/smells/nil_check.rb +11 -12
  38. data/lib/reek/smells/{simulated_polymorphism.rb → repeated_conditional.rb} +6 -10
  39. data/lib/reek/smells/smell_detector.rb +3 -6
  40. data/lib/reek/smells/too_many_instance_variables.rb +60 -0
  41. data/lib/reek/smells/too_many_methods.rb +62 -0
  42. data/lib/reek/smells/{long_method.rb → too_many_statements.rb} +7 -12
  43. data/lib/reek/smells/uncommunicative_method_name.rb +3 -7
  44. data/lib/reek/smells/uncommunicative_module_name.rb +3 -7
  45. data/lib/reek/smells/uncommunicative_parameter_name.rb +4 -8
  46. data/lib/reek/smells/uncommunicative_variable_name.rb +5 -9
  47. data/lib/reek/smells/unused_parameters.rb +62 -13
  48. data/lib/reek/smells/utility_function.rb +3 -7
  49. data/lib/reek/source.rb +8 -8
  50. data/lib/reek/source/core_extras.rb +1 -1
  51. data/lib/reek/source/source_code.rb +2 -2
  52. data/lib/reek/source/source_file.rb +2 -2
  53. data/lib/reek/source/source_locator.rb +1 -1
  54. data/lib/reek/source/source_repository.rb +4 -2
  55. data/lib/reek/spec.rb +9 -3
  56. data/lib/reek/spec/should_reek.rb +2 -2
  57. data/lib/reek/spec/should_reek_of.rb +1 -1
  58. data/lib/reek/spec/should_reek_only_of.rb +2 -2
  59. data/lib/reek/version.rb +1 -1
  60. data/reek.gemspec +3 -1
  61. data/spec/gem/updates_spec.rb +1 -1
  62. data/spec/gem/yard_spec.rb +1 -1
  63. data/spec/matchers/smell_of_matcher.rb +53 -19
  64. data/spec/reek/cli/help_command_spec.rb +2 -2
  65. data/spec/reek/cli/reek_command_spec.rb +6 -6
  66. data/spec/reek/cli/report_spec.rb +6 -6
  67. data/spec/reek/cli/version_command_spec.rb +2 -2
  68. data/spec/reek/cli/yaml_command_spec.rb +2 -2
  69. data/spec/reek/core/code_context_spec.rb +4 -4
  70. data/spec/reek/core/code_parser_spec.rb +2 -2
  71. data/spec/reek/core/config_spec.rb +4 -4
  72. data/spec/reek/core/method_context_spec.rb +3 -3
  73. data/spec/reek/core/module_context_spec.rb +3 -3
  74. data/spec/reek/core/object_refs_spec.rb +3 -3
  75. data/spec/reek/core/singleton_method_context_spec.rb +4 -4
  76. data/spec/reek/core/smell_configuration_spec.rb +2 -2
  77. data/spec/reek/core/stop_context_spec.rb +2 -2
  78. data/spec/reek/core/warning_collector_spec.rb +3 -3
  79. data/spec/reek/examiner_spec.rb +13 -4
  80. data/spec/reek/smell_warning_spec.rb +2 -2
  81. data/spec/reek/smells/attribute_spec.rb +4 -4
  82. data/spec/reek/smells/boolean_parameter_spec.rb +3 -3
  83. data/spec/reek/smells/class_variable_spec.rb +4 -4
  84. data/spec/reek/smells/{control_couple_spec.rb → control_parameter_spec.rb} +10 -10
  85. data/spec/reek/smells/data_clump_spec.rb +3 -3
  86. data/spec/reek/smells/{duplication_spec.rb → duplicate_method_call_spec.rb} +42 -26
  87. data/spec/reek/smells/feature_envy_spec.rb +3 -3
  88. data/spec/reek/smells/irresponsible_module_spec.rb +3 -3
  89. data/spec/reek/smells/long_parameter_list_spec.rb +3 -3
  90. data/spec/reek/smells/long_yield_list_spec.rb +3 -3
  91. data/spec/reek/smells/nested_iterators_spec.rb +42 -4
  92. data/spec/reek/smells/nil_check_spec.rb +23 -11
  93. data/spec/reek/smells/{simulated_polymorphism_spec.rb → repeated_conditional_spec.rb} +6 -6
  94. data/spec/reek/smells/smell_detector_shared.rb +2 -2
  95. data/spec/reek/smells/too_many_instance_variables_spec.rb +62 -0
  96. data/spec/reek/smells/{large_class_spec.rb → too_many_methods_spec.rb} +11 -56
  97. data/spec/reek/smells/{long_method_spec.rb → too_many_statements_spec.rb} +17 -17
  98. data/spec/reek/smells/uncommunicative_method_name_spec.rb +5 -5
  99. data/spec/reek/smells/uncommunicative_module_name_spec.rb +5 -5
  100. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +4 -4
  101. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +5 -5
  102. data/spec/reek/smells/unused_parameters_spec.rb +19 -4
  103. data/spec/reek/smells/utility_function_spec.rb +3 -3
  104. data/spec/reek/source/code_comment_spec.rb +2 -2
  105. data/spec/reek/source/object_source_spec.rb +1 -1
  106. data/spec/reek/source/reference_collector_spec.rb +2 -2
  107. data/spec/reek/source/sexp_formatter_spec.rb +2 -2
  108. data/spec/reek/source/source_code_spec.rb +2 -2
  109. data/spec/reek/source/tree_dresser_spec.rb +2 -2
  110. data/spec/reek/spec/should_reek_of_spec.rb +2 -2
  111. data/spec/reek/spec/should_reek_only_of_spec.rb +2 -2
  112. data/spec/reek/spec/should_reek_spec.rb +2 -2
  113. data/spec/samples/all_but_one_masked/masked.reek +1 -1
  114. data/spec/samples/clean_due_to_masking/masked.reek +1 -1
  115. data/spec/samples/config/allow_duplication.reek +2 -2
  116. data/spec/samples/inline_config/dirty.rb +2 -2
  117. data/spec/samples/mask_some/some.reek +1 -1
  118. data/spec/samples/masked_by_dotfile/dirty.rb +8 -0
  119. data/spec/samples/not_quite_masked/smelly.rb +3 -0
  120. data/spec/samples/overrides/masked/lower.reek +1 -1
  121. data/spec/samples/overrides/upper.reek +1 -1
  122. data/spec/spec_helper.rb +4 -9
  123. data/tasks/test.rake +0 -2
  124. metadata +253 -263
  125. data/lib/reek/smells/large_class.rb +0 -87
  126. data/lib/xp.reek +0 -66
  127. data/spec/gem/manifest_spec.rb +0 -22
  128. data/spec/spec.opts +0 -1
@@ -1,5 +1,5 @@
1
- require File.join( File.dirname( File.expand_path(__FILE__)), 'smell_detector')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'smell_warning')
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
3
 
4
4
  module Reek
5
5
  module Smells
@@ -7,13 +7,12 @@ module Reek
7
7
  #
8
8
  # A Long Method is any method that has a large number of lines.
9
9
  #
10
- # Currently +LongMethod+ reports any method with more than
11
- # 5 statements.
10
+ # +TooManyStatements+ reports any method with more than 5 statements.
12
11
  #
13
- class LongMethod < SmellDetector
12
+ class TooManyStatements < SmellDetector
14
13
 
15
- SMELL_CLASS = self.name.split(/::/)[-1]
16
- SUBCLASS_TOO_MANY_STATEMENTS = 'TooManyStatements'
14
+ SMELL_CLASS = 'LongMethod'
15
+ SMELL_SUBCLASS = self.name.split(/::/)[-1]
17
16
 
18
17
  STATEMENT_COUNT_KEY = 'statement_count'
19
18
 
@@ -30,10 +29,6 @@ module Reek
30
29
  )
31
30
  end
32
31
 
33
- def initialize(source, config = LongMethod.default_config)
34
- super(source, config)
35
- end
36
-
37
32
  #
38
33
  # Checks the length of the given +method+.
39
34
  #
@@ -45,7 +40,7 @@ module Reek
45
40
  return [] if num <= @max_allowed_statements
46
41
  smell = SmellWarning.new(SMELL_CLASS, ctx.full_name, [ctx.exp.line],
47
42
  "has approx #{num} statements",
48
- @source, SUBCLASS_TOO_MANY_STATEMENTS,
43
+ @source, SMELL_SUBCLASS,
49
44
  {STATEMENT_COUNT_KEY => num})
50
45
  [smell]
51
46
  end
@@ -1,5 +1,5 @@
1
- require File.join( File.dirname( File.expand_path(__FILE__)), 'smell_detector')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'smell_warning')
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
3
 
4
4
  module Reek
5
5
  module Smells
@@ -28,7 +28,7 @@ module Reek
28
28
  REJECT_KEY = 'reject'
29
29
 
30
30
  DEFAULT_REJECT_SET = [/^[a-z]$/, /[0-9]$/, /[A-Z]/]
31
-
31
+
32
32
  # The name of the config field that lists the specific names that are
33
33
  # to be treated as exceptions; these names will not be reported as
34
34
  # uncommunicative.
@@ -47,10 +47,6 @@ module Reek
47
47
  [:defn, :defs]
48
48
  end
49
49
 
50
- def initialize(source, config = UncommunicativeMethodName.default_config)
51
- super(source, config)
52
- end
53
-
54
50
  #
55
51
  # Checks the given +context+ for uncommunicative names.
56
52
  #
@@ -1,5 +1,5 @@
1
- require File.join( File.dirname( File.expand_path(__FILE__)), 'smell_detector')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'smell_warning')
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
3
 
4
4
  module Reek
5
5
  module Smells
@@ -28,7 +28,7 @@ module Reek
28
28
  REJECT_KEY = 'reject'
29
29
 
30
30
  DEFAULT_REJECT_SET = [/^.$/, /[0-9]$/]
31
-
31
+
32
32
  # The name of the config field that lists the specific names that are
33
33
  # to be treated as exceptions; these names will not be reported as
34
34
  # uncommunicative.
@@ -47,10 +47,6 @@ module Reek
47
47
  [:module, :class]
48
48
  end
49
49
 
50
- def initialize(source, config = UncommunicativeModuleName.default_config)
51
- super(source, config)
52
- end
53
-
54
50
  #
55
51
  # Checks the given +context+ for uncommunicative names.
56
52
  #
@@ -1,5 +1,5 @@
1
- require File.join( File.dirname( File.expand_path(__FILE__)), 'smell_detector')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'smell_warning')
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
3
 
4
4
  module Reek
5
5
  module Smells
@@ -38,8 +38,8 @@ module Reek
38
38
 
39
39
  def self.default_config
40
40
  super.adopt(
41
- REJECT_KEY => DEFAULT_REJECT_SET,
42
- ACCEPT_KEY => DEFAULT_ACCEPT_SET
41
+ REJECT_KEY => DEFAULT_REJECT_SET,
42
+ ACCEPT_KEY => DEFAULT_ACCEPT_SET
43
43
  )
44
44
  end
45
45
 
@@ -47,10 +47,6 @@ module Reek
47
47
  [:defn, :defs]
48
48
  end
49
49
 
50
- def initialize(source, config = UncommunicativeParameterName.default_config)
51
- super(source, config)
52
- end
53
-
54
50
  #
55
51
  # Checks the given +context+ for uncommunicative names.
56
52
  #
@@ -1,5 +1,5 @@
1
- require File.join( File.dirname( File.expand_path(__FILE__)), 'smell_detector')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'smell_warning')
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
3
 
4
4
  module Reek
5
5
  module Smells
@@ -38,8 +38,8 @@ module Reek
38
38
 
39
39
  def self.default_config
40
40
  super.adopt(
41
- REJECT_KEY => DEFAULT_REJECT_SET,
42
- ACCEPT_KEY => DEFAULT_ACCEPT_SET
41
+ REJECT_KEY => DEFAULT_REJECT_SET,
42
+ ACCEPT_KEY => DEFAULT_ACCEPT_SET
43
43
  )
44
44
  end
45
45
 
@@ -47,10 +47,6 @@ module Reek
47
47
  [:module, :class, :defn, :defs]
48
48
  end
49
49
 
50
- def initialize(source, config = UncommunicativeVariableName.default_config)
51
- super(source, config)
52
- end
53
-
54
50
  #
55
51
  # Checks the given +context+ for uncommunicative names.
56
52
  #
@@ -78,7 +74,7 @@ module Reek
78
74
  result = Hash.new {|hash, key| hash[key] = []}
79
75
  find_assignment_variable_names(exp, result)
80
76
  find_block_argument_variable_names(exp, result)
81
- result
77
+ result.to_a.sort_by {|name, _| name.to_s}
82
78
  end
83
79
 
84
80
  def find_assignment_variable_names(exp, accumulator)
@@ -1,37 +1,86 @@
1
- require File.join( File.dirname( File.expand_path(__FILE__)), 'smell_detector')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'smell_warning')
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
3
 
4
4
  module Reek
5
5
  module Smells
6
6
 
7
7
  #
8
8
  # Methods should use their parameters.
9
- #
9
+ #
10
10
  class UnusedParameters < SmellDetector
11
11
 
12
- SMELL_CLASS = 'ControlCouple'
12
+ SMELL_CLASS = 'UnusedCode'
13
13
  SMELL_SUBCLASS = name.split(/::/)[-1]
14
14
 
15
15
  PARAMETER_KEY = 'parameter'
16
16
 
17
+ EMPTY_ARRAY = [].freeze
18
+ EMPTY_STRING = ''.freeze
19
+ SPLAT_MATCH = /^\*/.freeze
20
+ UNDERSCORE = '_'.freeze
21
+
17
22
  #
18
23
  # Checks whether the given method has any unused parameters.
19
24
  #
20
25
  # @return [Array<SmellWarning>]
21
26
  #
22
27
  def examine_context(method_ctx)
23
- params = method_ctx.exp.arg_names || []
24
- params.select do |param|
25
- param = param.to_s.sub(/^\*/, '')
26
- !["", "_"].include?(param) &&
27
- !method_ctx.local_nodes(:lvar).include?(Sexp.new(:lvar, param.to_sym))
28
- end.map do |param|
29
- SmellWarning.new(SMELL_CLASS, method_ctx.full_name, [method_ctx.exp.line],
30
- "has unused parameter '#{param.to_s}'",
31
- @source, SMELL_SUBCLASS, {PARAMETER_KEY => param.to_s})
28
+ return EMPTY_ARRAY if zsuper?(method_ctx)
29
+ unused_params(method_ctx).map do |param|
30
+ smell_warning(method_ctx, param)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def unused_params(method_ctx)
37
+ params(method_ctx).select do |param|
38
+ param = sanitized_param(param)
39
+ next if skip?(param)
40
+ unused?(method_ctx, param)
32
41
  end
33
42
  end
34
43
 
44
+ def skip?(param)
45
+ anonymous_splat?(param) || marked_unused?(param)
46
+ end
47
+
48
+ def unused?(method_ctx, param)
49
+ !method_ctx.local_nodes(:lvar).include?(Sexp.new(:lvar, param.to_sym))
50
+ end
51
+
52
+ def params(method_ctx)
53
+ method_ctx.exp.arg_names || EMPTY_ARRAY
54
+ end
55
+
56
+ def sanitized_param(param)
57
+ param.to_s.sub(SPLAT_MATCH, EMPTY_STRING)
58
+ end
59
+
60
+ def marked_unused?(param)
61
+ param.start_with?(UNDERSCORE)
62
+ end
63
+
64
+ def anonymous_splat?(param)
65
+ param == EMPTY_STRING
66
+ end
67
+
68
+ def zsuper?(method_ctx)
69
+ method_ctx.exp.body.find_node :zsuper
70
+ end
71
+
72
+ def smell_warning(method_ctx, param)
73
+ SmellWarning.new(
74
+ SMELL_CLASS,
75
+ method_ctx.full_name,
76
+ [ method_ctx.exp.line ],
77
+ "has unused parameter '#{param.to_s}'",
78
+ @source,
79
+ SMELL_SUBCLASS,
80
+ { PARAMETER_KEY => param.to_s }
81
+ )
82
+ end
83
+
35
84
  end
36
85
  end
37
86
  end
@@ -1,6 +1,6 @@
1
- require File.join( File.dirname( File.expand_path(__FILE__)), 'smell_detector')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'smell_warning')
3
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'source', 'reference_collector')
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
+ require 'reek/source/reference_collector'
4
4
 
5
5
  module Reek
6
6
  module Smells
@@ -55,10 +55,6 @@ module Reek
55
55
  end
56
56
  end
57
57
 
58
- def initialize(source, config = UtilityFunction.default_config)
59
- super(source, config)
60
- end
61
-
62
58
  #
63
59
  # Checks whether the given +method+ is a utility function.
64
60
  #
@@ -1,11 +1,11 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source', 'code_comment')
2
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source', 'config_file')
3
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source', 'core_extras')
4
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source', 'sexp_formatter')
5
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source', 'source_code')
6
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source', 'source_file')
7
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source', 'source_locator')
8
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source', 'tree_dresser')
1
+ require 'reek/source/code_comment'
2
+ require 'reek/source/config_file'
3
+ require 'reek/source/core_extras'
4
+ require 'reek/source/sexp_formatter'
5
+ require 'reek/source/source_code'
6
+ require 'reek/source/source_file'
7
+ require 'reek/source/source_locator'
8
+ require 'reek/source/tree_dresser'
9
9
 
10
10
  module Reek
11
11
 
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source_code')
1
+ require 'reek/source/source_code'
2
2
 
3
3
  #
4
4
  # Extensions to +File+ needed by Reek.
@@ -1,6 +1,6 @@
1
1
  require 'ruby_parser'
2
- require File.join(File.dirname(File.expand_path(__FILE__)), 'config_file')
3
- require File.join(File.dirname(File.expand_path(__FILE__)), 'tree_dresser')
2
+ require 'reek/source/config_file'
3
+ require 'reek/source/tree_dresser'
4
4
 
5
5
  module Reek
6
6
  module Source
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'source_code')
1
+ require 'reek/source/source_code'
2
2
 
3
3
  module Reek
4
4
  module Source
@@ -25,7 +25,7 @@ module Reek
25
25
  return [] unless File.exist?(path)
26
26
  parent = File.dirname(path)
27
27
  return [] if path == parent
28
- all_config_files(parent) + Dir["#{path}/*.reek"]
28
+ all_config_files(parent) + Dir["#{path}/*.reek", "#{path}/.reek"]
29
29
  end
30
30
  end
31
31
  end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'core_extras')
1
+ require 'reek/source/core_extras'
2
2
 
3
3
  module Reek
4
4
  module Source
@@ -1,4 +1,6 @@
1
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'source')
1
+ require 'reek/source/core_extras'
2
+ require 'reek/source/source_code'
3
+ require 'reek/source/source_locator'
2
4
 
3
5
  module Reek
4
6
  module Source
@@ -24,7 +26,7 @@ module Reek
24
26
  end
25
27
 
26
28
  def each &block
27
- @sources.each &block
29
+ @sources.each(&block)
28
30
  end
29
31
  end
30
32
  end
@@ -1,6 +1,6 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec', 'should_reek')
2
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec', 'should_reek_of')
3
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec', 'should_reek_only_of')
1
+ require 'reek/spec/should_reek'
2
+ require 'reek/spec/should_reek_of'
3
+ require 'reek/spec/should_reek_only_of'
4
4
 
5
5
  module Reek
6
6
 
@@ -49,3 +49,9 @@ if Object.const_defined?(:Spec)
49
49
  config.include(Reek::Spec)
50
50
  end
51
51
  end
52
+
53
+ if Object.const_defined?(:RSpec)
54
+ RSpec.configure do |config|
55
+ config.include(Reek::Spec)
56
+ end
57
+ end
@@ -1,5 +1,5 @@
1
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'examiner')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'cli', 'report')
1
+ require 'reek/examiner'
2
+ require 'reek/cli/report'
3
3
 
4
4
  module Reek
5
5
  module Spec
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'examiner')
1
+ require 'reek/examiner'
2
2
 
3
3
  module Reek
4
4
  module Spec
@@ -1,5 +1,5 @@
1
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'examiner')
2
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'cli', 'report')
1
+ require 'reek/examiner'
2
+ require 'reek/cli/report'
3
3
 
4
4
  module Reek
5
5
  module Spec
@@ -1,3 +1,3 @@
1
1
  module Reek
2
- VERSION = '1.3.1'
2
+ VERSION = '1.3.2'
3
3
  end
@@ -1,5 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.join(File.dirname(__FILE__), 'lib/reek/version.rb')
2
+ $:.push File.join(File.dirname(__FILE__), "lib")
3
+ require 'reek/version'
3
4
 
4
5
  Gem::Specification.new do |s|
5
6
  s.name = %q{reek}
@@ -33,5 +34,6 @@ and reports any code smells it finds.
33
34
  s.add_development_dependency(%q<rake>)
34
35
  s.add_development_dependency(%q<cucumber>)
35
36
  s.add_development_dependency(%q<rspec>, ["~> 2.12"])
37
+ s.add_development_dependency(%q<flay>)
36
38
  s.add_development_dependency(%q<yard>)
37
39
  end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'spec_helper')
1
+ require 'spec_helper'
2
2
  require 'find'
3
3
 
4
4
  release_timestamp_file = 'build/.last-release'
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'spec_helper')
1
+ require 'spec_helper'
2
2
  require 'tempfile'
3
3
 
4
4
  describe 'yardoc' do
@@ -16,34 +16,68 @@ module SmellOfMatcher
16
16
 
17
17
  def matches?(src)
18
18
  @source = src.to_reek_source
19
+
20
+ detect_smells
21
+
22
+ return false if no_smells_found?
23
+ return false if wrong_smell_class_found?
24
+ return false if wrong_number_of_smells_found?
25
+ return false if wrong_smell_details_found?
26
+
27
+ true
28
+ end
29
+
30
+ def with_config(options)
31
+ @config = options
32
+ self
33
+ end
34
+
35
+ private
36
+
37
+ def detect_smells
19
38
  ctx = MethodContext.new(nil, @source.syntax_tree)
20
39
  detector = @klass.new(@source.desc, @klass.default_config.merge(@config))
21
40
  detector.examine(ctx)
22
- actual_smells = detector.smells_found.to_a
23
- if actual_smells.empty?
41
+ @actual_smells = detector.smells_found.to_a
42
+ end
43
+
44
+ def no_smells_found?
45
+ if @actual_smells.empty?
24
46
  @reason = 'no smells found by detector'
25
- return false
47
+ return true
26
48
  end
27
- return false if actual_smells.any? do |expected_smell|
28
- @reason = "Found #{expected_smell.smell_class}/#{expected_smell.subclass}" &&
29
- expected_smell.smell_class != @klass::SMELL_CLASS &&
30
- expected_smell.subclass != @klass::SMELL_SUBCLASS
31
- end
32
- return actual_smells.length == 1 if @expected_smells.empty?
33
- return false unless @expected_smells.length == actual_smells.length
34
- @expected_smells.each_with_index do |expected_smell,index|
35
- expected_smell.each do |(key,value)|
36
- if actual_smells[index].smell[key] != value
37
- @reason = "#{key} != #{value}"
38
- end
49
+ end
50
+
51
+ def wrong_smell_class_found?
52
+ @actual_smells.each do |smell|
53
+ if smell.smell_class != @klass::SMELL_CLASS ||
54
+ smell.subclass != @klass::SMELL_SUBCLASS
55
+ @reason = "Found #{smell.smell_class}/#{smell.subclass}"
56
+ return true
39
57
  end
40
58
  end
41
- true
59
+ false
42
60
  end
43
61
 
44
- def with_config(options)
45
- @config = options
46
- self
62
+ def wrong_number_of_smells_found?
63
+ expected_number_of_smells = @expected_smells.empty? ? 1 : @expected_smells.length
64
+ if expected_number_of_smells != @actual_smells.length
65
+ @reason = "expected #{expected_number_of_smells} smell(s), found #{@actual_smells.length}"
66
+ true
67
+ end
68
+ end
69
+
70
+ def wrong_smell_details_found?
71
+ @expected_smells.zip(@actual_smells).each do |expected_smell, actual_smell|
72
+ expected_smell.each do |key, value|
73
+ actual_value = actual_smell.smell[key]
74
+ if actual_value != value
75
+ @reason = "expected #{key} to be #{value}, was #{actual_value}"
76
+ return true
77
+ end
78
+ end
79
+ end
80
+ false
47
81
  end
48
82
  end
49
83