reek 1.2.7.2 → 1.2.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/History.txt +9 -1
  2. data/config/defaults.reek +4 -4
  3. data/features/masking_smells.feature +14 -57
  4. data/features/options.feature +1 -2
  5. data/features/rake_task.feature +6 -6
  6. data/features/reports.feature +8 -38
  7. data/features/samples.feature +181 -181
  8. data/features/stdin.feature +3 -3
  9. data/lib/reek.rb +1 -1
  10. data/lib/reek/cli/command_line.rb +2 -7
  11. data/lib/reek/cli/reek_command.rb +6 -6
  12. data/lib/reek/cli/report.rb +27 -49
  13. data/lib/reek/core/code_parser.rb +6 -15
  14. data/lib/reek/core/method_context.rb +1 -1
  15. data/lib/reek/core/module_context.rb +0 -18
  16. data/lib/reek/core/smell_configuration.rb +0 -4
  17. data/lib/reek/core/sniffer.rb +11 -19
  18. data/lib/reek/core/warning_collector.rb +27 -0
  19. data/lib/reek/examiner.rb +43 -35
  20. data/lib/reek/rake/task.rb +2 -0
  21. data/lib/reek/smell_warning.rb +10 -25
  22. data/lib/reek/smells/boolean_parameter.rb +1 -1
  23. data/lib/reek/smells/control_couple.rb +4 -1
  24. data/lib/reek/smells/data_clump.rb +40 -33
  25. data/lib/reek/smells/feature_envy.rb +1 -1
  26. data/lib/reek/smells/long_parameter_list.rb +4 -1
  27. data/lib/reek/smells/long_yield_list.rb +6 -3
  28. data/lib/reek/smells/simulated_polymorphism.rb +1 -1
  29. data/lib/reek/smells/smell_detector.rb +4 -32
  30. data/lib/reek/smells/uncommunicative_method_name.rb +1 -1
  31. data/lib/reek/smells/uncommunicative_module_name.rb +1 -1
  32. data/lib/reek/smells/uncommunicative_parameter_name.rb +2 -2
  33. data/lib/reek/smells/uncommunicative_variable_name.rb +11 -18
  34. data/lib/reek/smells/utility_function.rb +7 -4
  35. data/lib/reek/source/reference_collector.rb +9 -2
  36. data/lib/reek/source/source_locator.rb +6 -0
  37. data/lib/reek/spec/should_reek.rb +3 -6
  38. data/lib/reek/spec/should_reek_only_of.rb +4 -3
  39. data/reek.gemspec +4 -4
  40. data/spec/reek/cli/reek_command_spec.rb +3 -4
  41. data/spec/reek/cli/report_spec.rb +10 -6
  42. data/spec/reek/cli/yaml_command_spec.rb +1 -1
  43. data/spec/reek/core/code_context_spec.rb +1 -3
  44. data/spec/reek/core/module_context_spec.rb +1 -1
  45. data/spec/reek/core/warning_collector_spec.rb +27 -0
  46. data/spec/reek/examiner_spec.rb +80 -19
  47. data/spec/reek/smell_warning_spec.rb +4 -61
  48. data/spec/reek/smells/attribute_spec.rb +4 -7
  49. data/spec/reek/smells/behaves_like_variable_detector.rb +2 -2
  50. data/spec/reek/smells/class_variable_spec.rb +0 -1
  51. data/spec/reek/smells/control_couple_spec.rb +8 -15
  52. data/spec/reek/smells/data_clump_spec.rb +85 -1
  53. data/spec/reek/smells/duplication_spec.rb +7 -8
  54. data/spec/reek/smells/feature_envy_spec.rb +2 -32
  55. data/spec/reek/smells/long_parameter_list_spec.rb +9 -16
  56. data/spec/reek/smells/long_yield_list_spec.rb +8 -15
  57. data/spec/reek/smells/smell_detector_shared.rb +12 -0
  58. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +9 -10
  59. data/spec/reek/smells/utility_function_spec.rb +11 -15
  60. data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
  61. data/spec/reek/spec/should_reek_spec.rb +3 -3
  62. metadata +36 -22
  63. data/lib/reek/core/class_context.rb +0 -22
  64. data/lib/reek/core/detector_stack.rb +0 -33
  65. data/lib/reek/core/masking_collection.rb +0 -52
  66. data/spec/reek/core/class_context_spec.rb +0 -53
  67. data/spec/reek/core/masking_collection_spec.rb +0 -235
@@ -35,6 +35,9 @@ module Reek
35
35
  #
36
36
  class UtilityFunction < SmellDetector
37
37
 
38
+ SMELL_SUBCLASS = self.name.split(/::/)[-1]
39
+ SMELL_CLASS = 'LowCohesion'
40
+
38
41
  # The name of the config field that sets the maximum number of
39
42
  # calls permitted within a helper method. Any method with more than
40
43
  # this number of method calls on other objects will be considered a
@@ -62,12 +65,12 @@ module Reek
62
65
  #
63
66
  def examine_context(method_ctx)
64
67
  return false if method_ctx.num_statements == 0
65
- return false if depends_on_instance?(method_ctx.exp.body)
68
+ return false if depends_on_instance?(method_ctx.exp)
66
69
  return false if num_helper_methods(method_ctx) <= value(HELPER_CALLS_LIMIT_KEY, method_ctx, DEFAULT_HELPER_CALLS_LIMIT)
67
70
  # SMELL: loads of calls to value{} with the above pattern
68
- smell = SmellWarning.new('LowCohesion', method_ctx.full_name, [method_ctx.exp.line],
69
- "doesn't depend on instance state", @masked,
70
- @source, 'UtilityFunction')
71
+ smell = SmellWarning.new(SMELL_CLASS, method_ctx.full_name, [method_ctx.exp.line],
72
+ "doesn't depend on instance state",
73
+ @source, SMELL_SUBCLASS)
71
74
  @smells_found << smell
72
75
  #SMELL: serious duplication
73
76
  end
@@ -1,7 +1,14 @@
1
1
 
2
2
  module Reek
3
3
  module Source
4
+
5
+ #
6
+ # Locates references to the current object within a portion
7
+ # of an abstract syntax tree.
8
+ #
4
9
  class ReferenceCollector
10
+ STOP_NODES = [:class, :module, :defn, :defs]
11
+
5
12
  def initialize(ast)
6
13
  @ast = ast
7
14
  end
@@ -9,9 +16,9 @@ module Reek
9
16
  def num_refs_to_self
10
17
  result = 0
11
18
  [:self, :zsuper, :ivar, :iasgn].each do |node_type|
12
- @ast.look_for(node_type, [:class, :module, :defn, :defs]) { result += 1}
19
+ @ast.look_for(node_type, STOP_NODES) { result += 1}
13
20
  end
14
- @ast.look_for(:call, [:class, :module, :defn, :defs]) do |call|
21
+ @ast.look_for(:call, STOP_NODES) do |call|
15
22
  result += 1 unless call.receiver
16
23
  end
17
24
  result
@@ -2,6 +2,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'core_extras')
2
2
 
3
3
  module Reek
4
4
  module Source
5
+
6
+ #
7
+ # Finds Ruby source files in a filesystem.
8
+ #
5
9
  class SourceLocator
6
10
  def initialize(paths)
7
11
  @paths = paths
@@ -11,6 +15,8 @@ module Reek
11
15
  valid_paths.map {|path| File.new(path).to_reek_source }
12
16
  end
13
17
 
18
+ private
19
+
14
20
  def all_ruby_source_files(paths)
15
21
  paths.map do |path|
16
22
  if test 'd', path
@@ -1,4 +1,5 @@
1
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')
2
3
 
3
4
  module Reek
4
5
  module Spec
@@ -15,12 +16,8 @@ module Reek
15
16
  "Expected #{@examiner.description} to reek, but it didn't"
16
17
  end
17
18
  def failure_message_for_should_not
18
- "Expected no smells, but got:\n#{list_smells(@examiner)}"
19
- end
20
- def list_smells(examiner)
21
- examiner.smells.map do |smell|
22
- "#{smell.report('%c %w (%s)')}"
23
- end.join("\n")
19
+ rpt = Cli::ReportFormatter.format_list(@examiner.smells)
20
+ "Expected no smells, but got:\n#{rpt}"
24
21
  end
25
22
  end
26
23
 
@@ -1,4 +1,5 @@
1
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')
2
3
 
3
4
  module Reek
4
5
  module Spec
@@ -13,11 +14,11 @@ module Reek
13
14
  end
14
15
  def matches_examiner?(examiner)
15
16
  @examiner = examiner
16
- @all_smells = @examiner.smells
17
- @all_smells.length == 1 and @all_smells[0].matches?(@klass, @patterns)
17
+ @warnings = @examiner.smells
18
+ @warnings.length == 1 and @warnings[0].matches?(@klass, @patterns)
18
19
  end
19
20
  def failure_message_for_should
20
- rpt = @all_smells.map { |smell| "#{smell.report('%c %w (%s)')}" }.join("\n")
21
+ rpt = Cli::ReportFormatter.format_list(@warnings)
21
22
  "Expected #{@examiner.description} to reek only of #{@klass}, but got:\n#{rpt}"
22
23
  end
23
24
  def failure_message_for_should_not
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{reek}
5
- s.version = "1.2.7.2"
5
+ s.version = "1.2.7.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Kevin Rutherford"]
9
- s.date = %q{2010-03-05}
9
+ s.date = %q{2010-03-29}
10
10
  s.default_executable = %q{reek}
11
11
  s.description = %q{Reek is a tool that examines Ruby classes, modules and methods
12
12
  and reports any code smells it finds.
@@ -14,7 +14,7 @@ and reports any code smells it finds.
14
14
  s.email = ["kevin@rutherford-software.com"]
15
15
  s.executables = ["reek"]
16
16
  s.extra_rdoc_files = ["History.txt", "License.txt"]
17
- s.files = [".yardopts", "History.txt", "License.txt", "README.md", "Rakefile", "bin/reek", "config/defaults.reek", "features/masking_smells.feature", "features/options.feature", "features/rake_task.feature", "features/reports.feature", "features/samples.feature", "features/stdin.feature", "features/step_definitions/reek_steps.rb", "features/support/env.rb", "features/yaml.feature", "lib/reek.rb", "lib/reek/cli/application.rb", "lib/reek/cli/command_line.rb", "lib/reek/cli/help_command.rb", "lib/reek/cli/reek_command.rb", "lib/reek/cli/report.rb", "lib/reek/cli/version_command.rb", "lib/reek/cli/yaml_command.rb", "lib/reek/core/class_context.rb", "lib/reek/core/code_context.rb", "lib/reek/core/code_parser.rb", "lib/reek/core/detector_stack.rb", "lib/reek/core/masking_collection.rb", "lib/reek/core/method_context.rb", "lib/reek/core/module_context.rb", "lib/reek/core/object_refs.rb", "lib/reek/core/singleton_method_context.rb", "lib/reek/core/smell_configuration.rb", "lib/reek/core/sniffer.rb", "lib/reek/core/stop_context.rb", "lib/reek/examiner.rb", "lib/reek/rake/task.rb", "lib/reek/smell_warning.rb", "lib/reek/smells.rb", "lib/reek/smells/attribute.rb", "lib/reek/smells/boolean_parameter.rb", "lib/reek/smells/class_variable.rb", "lib/reek/smells/control_couple.rb", "lib/reek/smells/data_clump.rb", "lib/reek/smells/duplication.rb", "lib/reek/smells/feature_envy.rb", "lib/reek/smells/irresponsible_module.rb", "lib/reek/smells/large_class.rb", "lib/reek/smells/long_method.rb", "lib/reek/smells/long_parameter_list.rb", "lib/reek/smells/long_yield_list.rb", "lib/reek/smells/nested_iterators.rb", "lib/reek/smells/simulated_polymorphism.rb", "lib/reek/smells/smell_detector.rb", "lib/reek/smells/uncommunicative_method_name.rb", "lib/reek/smells/uncommunicative_module_name.rb", "lib/reek/smells/uncommunicative_parameter_name.rb", "lib/reek/smells/uncommunicative_variable_name.rb", "lib/reek/smells/utility_function.rb", "lib/reek/source.rb", "lib/reek/source/code_comment.rb", "lib/reek/source/config_file.rb", "lib/reek/source/core_extras.rb", "lib/reek/source/reference_collector.rb", "lib/reek/source/sexp_formatter.rb", "lib/reek/source/source_code.rb", "lib/reek/source/source_file.rb", "lib/reek/source/source_locator.rb", "lib/reek/source/tree_dresser.rb", "lib/reek/spec.rb", "lib/reek/spec/should_reek.rb", "lib/reek/spec/should_reek_of.rb", "lib/reek/spec/should_reek_only_of.rb", "reek.gemspec", "spec/reek/cli/help_command_spec.rb", "spec/reek/cli/reek_command_spec.rb", "spec/reek/cli/report_spec.rb", "spec/reek/cli/version_command_spec.rb", "spec/reek/cli/yaml_command_spec.rb", "spec/reek/core/class_context_spec.rb", "spec/reek/core/code_context_spec.rb", "spec/reek/core/code_parser_spec.rb", "spec/reek/core/config_spec.rb", "spec/reek/core/masking_collection_spec.rb", "spec/reek/core/method_context_spec.rb", "spec/reek/core/module_context_spec.rb", "spec/reek/core/object_refs_spec.rb", "spec/reek/core/singleton_method_context_spec.rb", "spec/reek/core/smell_configuration_spec.rb", "spec/reek/core/stop_context_spec.rb", "spec/reek/examiner_spec.rb", "spec/reek/smell_warning_spec.rb", "spec/reek/smells/attribute_spec.rb", "spec/reek/smells/behaves_like_variable_detector.rb", "spec/reek/smells/boolean_parameter_spec.rb", "spec/reek/smells/class_variable_spec.rb", "spec/reek/smells/control_couple_spec.rb", "spec/reek/smells/data_clump_spec.rb", "spec/reek/smells/duplication_spec.rb", "spec/reek/smells/feature_envy_spec.rb", "spec/reek/smells/irresponsible_module_spec.rb", "spec/reek/smells/large_class_spec.rb", "spec/reek/smells/long_method_spec.rb", "spec/reek/smells/long_parameter_list_spec.rb", "spec/reek/smells/long_yield_list_spec.rb", "spec/reek/smells/nested_iterators_spec.rb", "spec/reek/smells/simulated_polymorphism_spec.rb", "spec/reek/smells/smell_detector_shared.rb", "spec/reek/smells/uncommunicative_method_name_spec.rb", "spec/reek/smells/uncommunicative_module_name_spec.rb", "spec/reek/smells/uncommunicative_parameter_name_spec.rb", "spec/reek/smells/uncommunicative_variable_name_spec.rb", "spec/reek/smells/utility_function_spec.rb", "spec/reek/source/code_comment_spec.rb", "spec/reek/source/object_source_spec.rb", "spec/reek/source/reference_collector_spec.rb", "spec/reek/source/source_code_spec.rb", "spec/reek/source/tree_dresser_spec.rb", "spec/reek/spec/should_reek_of_spec.rb", "spec/reek/spec/should_reek_only_of_spec.rb", "spec/reek/spec/should_reek_spec.rb", "spec/samples/all_but_one_masked/clean_one.rb", "spec/samples/all_but_one_masked/dirty.rb", "spec/samples/all_but_one_masked/masked.reek", "spec/samples/clean_due_to_masking/clean_one.rb", "spec/samples/clean_due_to_masking/clean_three.rb", "spec/samples/clean_due_to_masking/clean_two.rb", "spec/samples/clean_due_to_masking/dirty_one.rb", "spec/samples/clean_due_to_masking/dirty_two.rb", "spec/samples/clean_due_to_masking/masked.reek", "spec/samples/corrupt_config_file/corrupt.reek", "spec/samples/corrupt_config_file/dirty.rb", "spec/samples/empty_config_file/dirty.rb", "spec/samples/empty_config_file/empty.reek", "spec/samples/exceptions.reek", "spec/samples/inline.rb", "spec/samples/masked/dirty.rb", "spec/samples/masked/masked.reek", "spec/samples/mixed_results/clean_one.rb", "spec/samples/mixed_results/clean_three.rb", "spec/samples/mixed_results/clean_two.rb", "spec/samples/mixed_results/dirty_one.rb", "spec/samples/mixed_results/dirty_two.rb", "spec/samples/not_quite_masked/dirty.rb", "spec/samples/not_quite_masked/masked.reek", "spec/samples/optparse.rb", "spec/samples/overrides/masked/dirty.rb", "spec/samples/overrides/masked/lower.reek", "spec/samples/overrides/upper.reek", "spec/samples/redcloth.rb", "spec/samples/three_clean_files/clean_one.rb", "spec/samples/three_clean_files/clean_three.rb", "spec/samples/three_clean_files/clean_two.rb", "spec/samples/two_smelly_files/dirty_one.rb", "spec/samples/two_smelly_files/dirty_two.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/reek.rake", "tasks/test.rake"]
17
+ s.files = [".yardopts", "History.txt", "License.txt", "README.md", "Rakefile", "bin/reek", "config/defaults.reek", "features/masking_smells.feature", "features/options.feature", "features/rake_task.feature", "features/reports.feature", "features/samples.feature", "features/stdin.feature", "features/step_definitions/reek_steps.rb", "features/support/env.rb", "features/yaml.feature", "lib/reek.rb", "lib/reek/cli/application.rb", "lib/reek/cli/command_line.rb", "lib/reek/cli/help_command.rb", "lib/reek/cli/reek_command.rb", "lib/reek/cli/report.rb", "lib/reek/cli/version_command.rb", "lib/reek/cli/yaml_command.rb", "lib/reek/core/code_context.rb", "lib/reek/core/code_parser.rb", "lib/reek/core/method_context.rb", "lib/reek/core/module_context.rb", "lib/reek/core/object_refs.rb", "lib/reek/core/singleton_method_context.rb", "lib/reek/core/smell_configuration.rb", "lib/reek/core/sniffer.rb", "lib/reek/core/stop_context.rb", "lib/reek/core/warning_collector.rb", "lib/reek/examiner.rb", "lib/reek/rake/task.rb", "lib/reek/smell_warning.rb", "lib/reek/smells.rb", "lib/reek/smells/attribute.rb", "lib/reek/smells/boolean_parameter.rb", "lib/reek/smells/class_variable.rb", "lib/reek/smells/control_couple.rb", "lib/reek/smells/data_clump.rb", "lib/reek/smells/duplication.rb", "lib/reek/smells/feature_envy.rb", "lib/reek/smells/irresponsible_module.rb", "lib/reek/smells/large_class.rb", "lib/reek/smells/long_method.rb", "lib/reek/smells/long_parameter_list.rb", "lib/reek/smells/long_yield_list.rb", "lib/reek/smells/nested_iterators.rb", "lib/reek/smells/simulated_polymorphism.rb", "lib/reek/smells/smell_detector.rb", "lib/reek/smells/uncommunicative_method_name.rb", "lib/reek/smells/uncommunicative_module_name.rb", "lib/reek/smells/uncommunicative_parameter_name.rb", "lib/reek/smells/uncommunicative_variable_name.rb", "lib/reek/smells/utility_function.rb", "lib/reek/source.rb", "lib/reek/source/code_comment.rb", "lib/reek/source/config_file.rb", "lib/reek/source/core_extras.rb", "lib/reek/source/reference_collector.rb", "lib/reek/source/sexp_formatter.rb", "lib/reek/source/source_code.rb", "lib/reek/source/source_file.rb", "lib/reek/source/source_locator.rb", "lib/reek/source/tree_dresser.rb", "lib/reek/spec.rb", "lib/reek/spec/should_reek.rb", "lib/reek/spec/should_reek_of.rb", "lib/reek/spec/should_reek_only_of.rb", "reek.gemspec", "spec/reek/cli/help_command_spec.rb", "spec/reek/cli/reek_command_spec.rb", "spec/reek/cli/report_spec.rb", "spec/reek/cli/version_command_spec.rb", "spec/reek/cli/yaml_command_spec.rb", "spec/reek/core/code_context_spec.rb", "spec/reek/core/code_parser_spec.rb", "spec/reek/core/config_spec.rb", "spec/reek/core/method_context_spec.rb", "spec/reek/core/module_context_spec.rb", "spec/reek/core/object_refs_spec.rb", "spec/reek/core/singleton_method_context_spec.rb", "spec/reek/core/smell_configuration_spec.rb", "spec/reek/core/stop_context_spec.rb", "spec/reek/core/warning_collector_spec.rb", "spec/reek/examiner_spec.rb", "spec/reek/smell_warning_spec.rb", "spec/reek/smells/attribute_spec.rb", "spec/reek/smells/behaves_like_variable_detector.rb", "spec/reek/smells/boolean_parameter_spec.rb", "spec/reek/smells/class_variable_spec.rb", "spec/reek/smells/control_couple_spec.rb", "spec/reek/smells/data_clump_spec.rb", "spec/reek/smells/duplication_spec.rb", "spec/reek/smells/feature_envy_spec.rb", "spec/reek/smells/irresponsible_module_spec.rb", "spec/reek/smells/large_class_spec.rb", "spec/reek/smells/long_method_spec.rb", "spec/reek/smells/long_parameter_list_spec.rb", "spec/reek/smells/long_yield_list_spec.rb", "spec/reek/smells/nested_iterators_spec.rb", "spec/reek/smells/simulated_polymorphism_spec.rb", "spec/reek/smells/smell_detector_shared.rb", "spec/reek/smells/uncommunicative_method_name_spec.rb", "spec/reek/smells/uncommunicative_module_name_spec.rb", "spec/reek/smells/uncommunicative_parameter_name_spec.rb", "spec/reek/smells/uncommunicative_variable_name_spec.rb", "spec/reek/smells/utility_function_spec.rb", "spec/reek/source/code_comment_spec.rb", "spec/reek/source/object_source_spec.rb", "spec/reek/source/reference_collector_spec.rb", "spec/reek/source/source_code_spec.rb", "spec/reek/source/tree_dresser_spec.rb", "spec/reek/spec/should_reek_of_spec.rb", "spec/reek/spec/should_reek_only_of_spec.rb", "spec/reek/spec/should_reek_spec.rb", "spec/samples/all_but_one_masked/clean_one.rb", "spec/samples/all_but_one_masked/dirty.rb", "spec/samples/all_but_one_masked/masked.reek", "spec/samples/clean_due_to_masking/clean_one.rb", "spec/samples/clean_due_to_masking/clean_three.rb", "spec/samples/clean_due_to_masking/clean_two.rb", "spec/samples/clean_due_to_masking/dirty_one.rb", "spec/samples/clean_due_to_masking/dirty_two.rb", "spec/samples/clean_due_to_masking/masked.reek", "spec/samples/corrupt_config_file/corrupt.reek", "spec/samples/corrupt_config_file/dirty.rb", "spec/samples/empty_config_file/dirty.rb", "spec/samples/empty_config_file/empty.reek", "spec/samples/exceptions.reek", "spec/samples/inline.rb", "spec/samples/masked/dirty.rb", "spec/samples/masked/masked.reek", "spec/samples/mixed_results/clean_one.rb", "spec/samples/mixed_results/clean_three.rb", "spec/samples/mixed_results/clean_two.rb", "spec/samples/mixed_results/dirty_one.rb", "spec/samples/mixed_results/dirty_two.rb", "spec/samples/not_quite_masked/dirty.rb", "spec/samples/not_quite_masked/masked.reek", "spec/samples/optparse.rb", "spec/samples/overrides/masked/dirty.rb", "spec/samples/overrides/masked/lower.reek", "spec/samples/overrides/upper.reek", "spec/samples/redcloth.rb", "spec/samples/three_clean_files/clean_one.rb", "spec/samples/three_clean_files/clean_three.rb", "spec/samples/three_clean_files/clean_two.rb", "spec/samples/two_smelly_files/dirty_one.rb", "spec/samples/two_smelly_files/dirty_two.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/reek.rake", "tasks/test.rake"]
18
18
  s.homepage = %q{http://wiki.github.com/kevinrutherford/reek}
19
19
  s.post_install_message = %q{
20
20
  For more information on reek, see http://wiki.github.com/kevinrutherford/reek
@@ -22,7 +22,7 @@ For more information on reek, see http://wiki.github.com/kevinrutherford/reek
22
22
  s.rdoc_options = ["--main", "README.md"]
23
23
  s.require_paths = ["lib"]
24
24
  s.rubyforge_project = %q{reek}
25
- s.rubygems_version = %q{1.3.5}
25
+ s.rubygems_version = %q{1.3.6}
26
26
  s.summary = %q{Code smell detector for Ruby}
27
27
 
28
28
  if s.respond_to? :specification_version then
@@ -14,11 +14,11 @@ describe ReekCommand do
14
14
  context 'with smells' do
15
15
  before :each do
16
16
  examiner = Examiner.new('def x(); end')
17
- @cmd = ReekCommand.new([examiner], QuietReport)
17
+ @cmd = ReekCommand.new(QuietReport, ['def x(); end'])
18
18
  end
19
19
 
20
20
  it 'displays the correct text on the view' do
21
- @view.should_receive(:output).with(/Uncommunicative Name/)
21
+ @view.should_receive(:output).with(/UncommunicativeName/)
22
22
  @cmd.execute(@view)
23
23
  end
24
24
 
@@ -30,8 +30,7 @@ describe ReekCommand do
30
30
 
31
31
  context 'with no smells' do
32
32
  before :each do
33
- examiner = Examiner.new('def clean(); end')
34
- @cmd = ReekCommand.new([examiner], QuietReport)
33
+ @cmd = ReekCommand.new(QuietReport, ['def clean(); end'])
35
34
  end
36
35
 
37
36
  it 'displays nothing on the view' do
@@ -5,20 +5,24 @@ require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expan
5
5
  include Reek
6
6
  include Reek::Cli
7
7
 
8
- describe ReportSection, " when empty" do
8
+ describe QuietReport, " when empty" do
9
9
  context 'empty source' do
10
10
  it 'has an empty quiet_report' do
11
11
  examiner = Examiner.new('')
12
- ReportSection.new(examiner).quiet_report.should == ''
12
+ QuietReport.new(examiner).report.should == ''
13
13
  end
14
14
  end
15
15
 
16
16
  context 'with a couple of smells' do
17
- it 'should mention every smell name' do
17
+ before :each do
18
18
  examiner = Examiner.new('def simple(a) a[3] end')
19
- rpt = ReportSection.new(examiner)
20
- @lines = rpt.smell_list.split("\n")
21
- @lines.should have_at_least(2).lines
19
+ rpt = QuietReport.new(examiner)
20
+ @lines = rpt.report.split("\n")
21
+ end
22
+ it 'has a header and a list of smells' do
23
+ @lines.should have_at_least(3).lines
24
+ end
25
+ it 'should mention every smell name' do
22
26
  @lines[0].should match('[Utility Function]')
23
27
  @lines[1].should match('[Feature Envy]')
24
28
  end
@@ -29,7 +29,7 @@ describe YamlCommand do
29
29
 
30
30
  context 'with smells' do
31
31
  before :each do
32
- @smell = SmellWarning.new('UncommunicativeName', "self", 27, "self", true)
32
+ @smell = SmellWarning.new('UncommunicativeName', "self", 27, "self")
33
33
  @examiner.should_receive(:smells).and_return([@smell])
34
34
  @cmd = YamlCommand.new([@examiner])
35
35
  end
@@ -1,5 +1,4 @@
1
1
  require File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'spec_helper')
2
- require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'class_context')
3
2
  require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'method_context')
4
3
  require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'module_context')
5
4
  require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'stop_context')
@@ -56,8 +55,7 @@ describe CodeContext do
56
55
  stop = StopContext.new
57
56
  def stop.bananas(arg1, arg2) arg1 + arg2 + 43 end
58
57
  element = ModuleContext.new(stop, 'mod', s(:module, :mod, nil))
59
- class_element = ClassContext.new(element, [0, :klass], s())
60
- element = MethodContext.new(class_element, [0, :bad])
58
+ element = MethodContext.new(element, [0, :bad])
61
59
  element.bananas(17, -5).should == 55
62
60
  end
63
61
  end
@@ -6,7 +6,7 @@ include Reek::Core
6
6
 
7
7
  describe ModuleContext do
8
8
  it 'should report module name for smell in method' do
9
- 'module Fred; def simple(x) true; end; end'.should reek_of(:UncommunicativeParameterName, /x/, /simple/, /Fred/)
9
+ 'module Fred; def simple(x) true; end; end'.should reek_of(:UncommunicativeParameterName, /x/, /simple/)
10
10
  end
11
11
 
12
12
  it 'should not report module with empty class' do
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'spec_helper')
2
+ require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'warning_collector')
3
+ require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'smell_warning')
4
+
5
+ include Reek::Core
6
+
7
+ describe WarningCollector do
8
+ before(:each) do
9
+ @collector = WarningCollector.new
10
+ end
11
+
12
+ context 'when empty' do
13
+ it 'reports no warnings' do
14
+ @collector.warnings.should == []
15
+ end
16
+ end
17
+
18
+ context 'with one warning' do
19
+ before :each do
20
+ @warning = Reek::SmellWarning.new('ControlCouple', 'fred', [1,2,3], 'hello')
21
+ @collector.found_smell(@warning)
22
+ end
23
+ it 'reports that warning' do
24
+ @collector.warnings.should == [@warning]
25
+ end
26
+ end
27
+ end
@@ -3,40 +3,101 @@ require File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE
3
3
 
4
4
  include Reek
5
5
 
6
+ shared_examples_for 'supports the deprecated api' do
7
+ it 'returns all smells as active' do
8
+ @examiner.all_active_smells.should == @examiner.smells
9
+ end
10
+ it 'returns all smells as active' do
11
+ @examiner.all_smells.should == @examiner.smells
12
+ end
13
+ it 'counts all smells as active smells' do
14
+ @examiner.num_active_smells.should == @examiner.smells.length
15
+ end
16
+ it 'never reports masked smells' do
17
+ @examiner.num_masked_smells.should == 0
18
+ end
19
+ end
20
+
21
+ shared_examples_for 'no smells found' do
22
+ it 'is not smelly' do
23
+ @examiner.should_not be_smelly
24
+ end
25
+ it 'finds no smells' do
26
+ @examiner.smells.length.should == 0
27
+ end
28
+
29
+ it_should_behave_like 'supports the deprecated api'
30
+ end
31
+
32
+ shared_examples_for 'one smell found' do
33
+ it 'is smelly' do
34
+ @examiner.should be_smelly
35
+ end
36
+ it 'reports the smell' do
37
+ @examiner.smells.length.should == 1
38
+ end
39
+ it 'reports the correct smell' do
40
+ @examiner.smells[0].smell_class.should == @expected_first_smell
41
+ end
42
+
43
+ it_should_behave_like 'supports the deprecated api'
44
+ end
45
+
6
46
  describe Examiner do
7
- it 'detects smells in a file' do
8
- dirty_file = Dir['spec/samples/two_smelly_files/*.rb'][0]
9
- Examiner.new(File.new(dirty_file)).should be_smelly
47
+ before :each do
48
+ @expected_first_smell = 'NestedIterators'
10
49
  end
11
- it 'doesnt match a fragrant String' do
12
- examiner = Examiner.new('def good() true; end')
13
- examiner.smells.should == []
50
+
51
+ context 'with a fragrant String' do
52
+ before :each do
53
+ @examiner = Examiner.new('def good() true; end')
54
+ end
55
+
56
+ it_should_behave_like 'no smells found'
14
57
  end
15
- it 'matches a smelly String' do
16
- Examiner.new('def fine() y = 4; end').smells.length.should == 1
58
+
59
+ context 'with a smelly String' do
60
+ before :each do
61
+ @examiner = Examiner.new('def fine() y = 4; end')
62
+ @expected_first_smell = 'UncommunicativeName'
63
+ end
64
+
65
+ it_should_behave_like 'one smell found'
17
66
  end
18
67
 
19
- context 'checking code in a Dir' do
20
- it 'matches a smelly Dir' do
68
+ context 'with a smelly Dir' do
69
+ before :each do
21
70
  smelly_dir = Dir['spec/samples/all_but_one_masked/*.rb']
22
- Examiner.new(smelly_dir).smells.length.should == 1
71
+ @examiner = Examiner.new(smelly_dir)
23
72
  end
24
- it 'doesnt match a fragrant Dir' do
73
+
74
+ it_should_behave_like 'one smell found'
75
+ end
76
+
77
+ context 'with a fragrant Dir' do
78
+ before :each do
25
79
  clean_dir = Dir['spec/samples/three_clean_files/*.rb']
26
- Examiner.new(clean_dir).smells.length.should == 0
80
+ @examiner = Examiner.new(clean_dir)
27
81
  end
82
+
83
+ it_should_behave_like 'no smells found'
28
84
  end
29
85
 
30
- context 'checking code in a File' do
31
- it 'matches a smelly File' do
86
+ context 'with a smelly File' do
87
+ before :each do
32
88
  smelly_file = File.new(Dir['spec/samples/all_but_one_masked/d*.rb'][0])
33
- Examiner.new(smelly_file).smells.length.should == 1
89
+ @examiner = Examiner.new(smelly_file)
34
90
  end
35
91
 
36
- it 'doesnt match a fragrant File' do
92
+ it_should_behave_like 'one smell found'
93
+ end
94
+
95
+ context 'with a fragrant File' do
96
+ before :each do
37
97
  clean_file = File.new(Dir['spec/samples/three_clean_files/*.rb'][0])
38
- Examiner.new(clean_file).smells.length.should == 0
98
+ @examiner = Examiner.new(clean_file)
39
99
  end
40
- end
41
100
 
101
+ it_should_behave_like 'no smells found'
102
+ end
42
103
  end
@@ -5,27 +5,6 @@ include Reek
5
5
 
6
6
  describe SmellWarning do
7
7
  context 'sort order' do
8
- context 'smells differing only by masking' do
9
- before :each do
10
- @first = SmellWarning.new('FeatureEnvy', "self", 27, "self", true)
11
- @second = SmellWarning.new('FeatureEnvy', "self", 27, "self", false)
12
- end
13
-
14
- it 'should hash equal when the smell is the same' do
15
- @first.hash.should == @second.hash
16
- end
17
- it 'should compare equal when the smell is the same' do
18
- @first.should == @second
19
- end
20
- it 'should compare equal when using <=>' do
21
- (@first <=> @second).should == 0
22
- end
23
- it 'matches using eql?' do
24
- @first.should eql(@second)
25
- @second.should eql(@first)
26
- end
27
- end
28
-
29
8
  shared_examples_for 'first sorts ahead of second' do
30
9
  it 'hash differently' do
31
10
  @first.hash.should_not == @second.hash
@@ -88,48 +67,12 @@ describe SmellWarning do
88
67
  end
89
68
  end
90
69
 
91
- context 'masked reporting' do
92
- class CountingReport
93
- attr_reader :masked, :non_masked
94
- def initialize
95
- @masked = @non_masked = 0
96
- end
97
- def found_smell(sw)
98
- @non_masked += 1
99
- end
100
-
101
- def found_masked_smell(sw)
102
- @masked += 1
103
- end
104
- end
105
-
106
- before :each do
107
- @masked = SmellWarning.new('FeatureEnvy', 'Fred', 27, "self", true)
108
- @visible = SmellWarning.new('FeatureEnvy', 'Fred', 27, "self", false)
109
- end
110
-
111
- it 'reports as masked when masked' do
112
- rpt = CountingReport.new
113
- @masked.report_on(rpt)
114
- rpt.masked.should == 1
115
- rpt.non_masked.should == 0
116
- end
117
-
118
- it 'reports as non-masked when non-masked' do
119
- rpt = CountingReport.new
120
- @visible.report_on(rpt)
121
- rpt.masked.should == 0
122
- rpt.non_masked.should == 1
123
- end
124
- end
125
-
126
70
  context 'YAML representation' do
127
71
  before :each do
128
72
  @message = 'test message'
129
73
  @lines = [24, 513]
130
74
  @class = 'FeatureEnvy'
131
75
  @context_name = 'Module::Class#method/block'
132
- @is_active = true
133
76
  # Use a random string and a random bool
134
77
  end
135
78
 
@@ -144,7 +87,7 @@ describe SmellWarning do
144
87
  @yaml.should match(/message:\s*#{@message}/)
145
88
  end
146
89
  it 'indicates the masking' do
147
- @yaml.should match(/is_active:\s*#{@is_active}/)
90
+ @yaml.should match(/is_active:\s*true/)
148
91
  end
149
92
  it 'includes the line numbers' do
150
93
  @lines.each do |line|
@@ -158,9 +101,9 @@ describe SmellWarning do
158
101
  @source = 'a/ruby/source/file.rb'
159
102
  @subclass = 'TooManyParties'
160
103
  @parameters = {'one' => 34, 'two' => 'second'}
161
- warning = SmellWarning.new(@class, @context_name, @lines, @message, @is_masked,
104
+ @warning = SmellWarning.new(@class, @context_name, @lines, @message,
162
105
  @source, @subclass, @parameters)
163
- @yaml = warning.to_yaml
106
+ @yaml = @warning.to_yaml
164
107
  end
165
108
 
166
109
  it_should_behave_like 'common fields'
@@ -180,7 +123,7 @@ describe SmellWarning do
180
123
 
181
124
  context 'with all defaults used' do
182
125
  before :each do
183
- warning = SmellWarning.new(@class, @context_name, @lines, @message, @is_masked)
126
+ warning = SmellWarning.new(@class, @context_name, @lines, @message)
184
127
  @yaml = warning.to_yaml
185
128
  end
186
129