reek 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
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