kevinrutherford-reek 1.1.3.9 → 1.1.3.10

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 (53) hide show
  1. data/History.txt +2 -1
  2. data/License.txt +20 -0
  3. data/bin/reek +5 -5
  4. data/features/options.feature +1 -0
  5. data/features/reports.feature +40 -0
  6. data/features/stdin.feature +10 -1
  7. data/features/step_definitions/reek_steps.rb +2 -2
  8. data/features/support/env.rb +2 -2
  9. data/lib/reek/class_context.rb +2 -2
  10. data/lib/reek/code_parser.rb +4 -0
  11. data/lib/reek/core_extras.rb +50 -0
  12. data/lib/reek/object_source.rb +7 -18
  13. data/lib/reek/options.rb +13 -3
  14. data/lib/reek/report.rb +27 -28
  15. data/lib/reek/sexp_formatter.rb +2 -0
  16. data/lib/reek/smells/control_couple.rb +5 -0
  17. data/lib/reek/sniffer.rb +98 -3
  18. data/lib/reek/source.rb +9 -112
  19. data/lib/reek/spec.rb +29 -55
  20. data/lib/reek.rb +1 -1
  21. data/reek.gemspec +4 -4
  22. data/spec/reek/object_source_spec.rb +3 -3
  23. data/spec/reek/report_spec.rb +9 -5
  24. data/spec/reek/should_reek_of_spec.rb +105 -0
  25. data/spec/reek/should_reek_only_of_spec.rb +85 -0
  26. data/spec/reek/{spec_spec.rb → should_reek_spec.rb} +24 -3
  27. data/spec/reek/smells/duplication_spec.rb +1 -1
  28. data/spec/reek/smells/large_class_spec.rb +1 -0
  29. data/spec/reek/smells/long_method_spec.rb +4 -4
  30. data/spec/reek/smells/long_parameter_list_spec.rb +1 -1
  31. data/spec/reek/smells/smell_detector_spec.rb +1 -1
  32. data/spec/reek/smells/uncommunicative_name_spec.rb +2 -1
  33. data/spec/reek/sniffer_spec.rb +10 -0
  34. data/spec/samples/all_but_one_masked/clean_one.rb +6 -0
  35. data/spec/samples/all_but_one_masked/dirty.rb +7 -0
  36. data/spec/samples/all_but_one_masked/masked.reek +5 -0
  37. data/spec/samples/clean_due_to_masking/clean_one.rb +6 -0
  38. data/spec/samples/clean_due_to_masking/clean_three.rb +6 -0
  39. data/spec/samples/clean_due_to_masking/clean_two.rb +6 -0
  40. data/spec/samples/clean_due_to_masking/dirty_one.rb +7 -0
  41. data/spec/samples/clean_due_to_masking/dirty_two.rb +7 -0
  42. data/spec/samples/clean_due_to_masking/masked.reek +7 -0
  43. data/spec/samples/mixed_results/clean_one.rb +6 -0
  44. data/spec/samples/mixed_results/clean_three.rb +6 -0
  45. data/spec/samples/mixed_results/clean_two.rb +6 -0
  46. data/spec/samples/mixed_results/dirty_one.rb +7 -0
  47. data/spec/samples/mixed_results/dirty_two.rb +7 -0
  48. data/spec/slow/inline_spec.rb +6 -2
  49. data/spec/slow/optparse_spec.rb +6 -2
  50. data/spec/slow/redcloth_spec.rb +6 -2
  51. data/tasks/test.rake +2 -0
  52. metadata +23 -4
  53. data/spec/slow/source_list_spec.rb +0 -40
data/lib/reek/source.rb CHANGED
@@ -1,139 +1,36 @@
1
- require 'reek/code_parser'
2
- require 'reek/report'
3
1
  require 'reek/sniffer'
4
- require 'ruby_parser'
5
2
 
6
3
  module Reek
7
4
 
8
5
  #
9
6
  # A +Source+ object represents a chunk of Ruby source code.
10
7
  #
11
- # The various class methods are factories that will create +Source+
12
- # instances from various types of input.
13
- #
14
8
  class Source
15
9
 
16
- #
17
- # Factory method: creates a +Source+ object by reading Ruby code from
18
- # the +IO+ stream. The stream is consumed upto end-of-file, but the
19
- # source code is not parsed until +report+ is called. +desc+ provides
20
- # a string description to be used in the header of formatted reports.
21
- #
22
- def self.from_io(ios, desc)
23
- code = ios.readlines.join
24
- return new(code, desc)
25
- end
26
-
27
- #
28
- # Factory method: creates a +Source+ object by reading Ruby code from
29
- # the +code+ string. The code is not parsed until +report+ is called.
30
- #
31
- def self.from_s(code)
32
- return new(code, 'string')
33
- end
34
-
35
- #
36
- # Factory method: creates a +Source+ object by reading Ruby code from
37
- # File +file+. The source code is not parsed until +report+ is called.
38
- #
39
- def self.from_f(file)
40
- from_path(file.path)
41
- end
42
-
43
10
  #
44
11
  # Factory method: creates a +Source+ object by reading Ruby code from
45
12
  # the named file. The source code is not parsed until +report+ is called.
46
13
  #
47
- def self.from_path(filename)
14
+ def self.from_path(filename, sniffer)
48
15
  code = IO.readlines(filename).join
49
- sniffer = Sniffer.new.configure_along_path(filename)
16
+ # SMELL: Greedy Method
17
+ # The Sniffer should ask this source to configure it.
18
+ sniffer.configure_along_path(filename)
50
19
  return new(code, filename, sniffer)
51
20
  end
52
21
 
53
- #
54
- # Factory method: creates a +Source+ object from an array of file paths.
55
- # No source code is actually parsed until the report is accessed.
56
- #
57
- def self.from_pathlist(paths)
58
- sources = paths.map {|path| Source.from_path(path) }
59
- SourceList.new(sources)
60
- end
22
+ attr_reader :desc
23
+ attr_reader :sniffer # SMELL -- bidirectional link
61
24
 
62
- def initialize(code, desc, sniffer = Sniffer.new) # :nodoc:
25
+ def initialize(code, desc, sniffer) # :nodoc:
63
26
  @source = code
64
27
  @desc = desc
65
28
  @sniffer = sniffer
29
+ @sniffer.source = self
66
30
  end
67
31
 
68
- def generate_syntax_tree
32
+ def syntax_tree
69
33
  RubyParser.new.parse(@source, @desc) || s()
70
34
  end
71
-
72
- #
73
- # Returns a +Report+ listing the smells found in this source. The first
74
- # call to +report+ parses the source code and constructs a list of
75
- # +SmellWarning+s found; subsequent calls simply return this same list.
76
- #
77
- def report
78
- unless @report
79
- parser = CodeParser.new(@sniffer)
80
- parser.process(generate_syntax_tree)
81
- @report = Report.new(@sniffer)
82
- end
83
- @report
84
- end
85
-
86
- def smelly?
87
- report.length > 0
88
- end
89
-
90
- #
91
- # Checks this source for instances of +smell_class+, and returns +true+
92
- # only if one of them has a report string matching all of the +patterns+.
93
- #
94
- def has_smell?(smell_class, patterns)
95
- report.has_smell?(smell_class, patterns)
96
- end
97
-
98
- # Creates a formatted report of all the +Smells::SmellWarning+ objects recorded in
99
- # this report, with a heading.
100
- def full_report
101
- report.full_report(@desc)
102
- end
103
-
104
- def to_s
105
- @desc
106
- end
107
- end
108
-
109
- #
110
- # Represents a list of Sources as if they were a single source.
111
- #
112
- class SourceList
113
- def initialize(sources)
114
- @sources = sources
115
- end
116
-
117
- #
118
- # Checks this source for instances of +smell_class+, and returns +true+
119
- # only if one of them has a report string matching all of the +patterns+.
120
- #
121
- def has_smell?(smell_class, patterns=[])
122
- report.has_smell?(smell_class, patterns)
123
- end
124
-
125
- def smelly?
126
- @sources.any? {|source| source.smelly? }
127
- end
128
-
129
- def full_report
130
- ReportList.new(@sources).full_report
131
- end
132
-
133
- def report
134
- ReportList.new(@sources)
135
- end
136
35
  end
137
36
  end
138
-
139
- require 'reek/object_source'
data/lib/reek/spec.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'reek/source'
1
+ require 'reek/sniffer'
2
2
 
3
3
  module Reek
4
4
 
@@ -34,7 +34,7 @@ module Reek
34
34
  # And a more complex example, making use of one of the factory methods for
35
35
  # +Source+ so that the code is parsed and analysed only once:
36
36
  #
37
- # ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'.to_source
37
+ # ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'.sniff
38
38
  # ruby.should reek_of(:Duplication, /@other.thing[^\.]/)
39
39
  # ruby.should reek_of(:Duplication, /@other.thing.foo/)
40
40
  # ruby.should_not reek_of(:FeatureEnvy)
@@ -42,67 +42,67 @@ module Reek
42
42
  module Spec
43
43
  class ShouldReek # :nodoc:
44
44
  def matches?(actual)
45
- @source = actual.to_source
46
- @source.smelly?
45
+ @sniffer = actual.sniff
46
+ @sniffer.smelly?
47
47
  end
48
48
  def failure_message_for_should
49
49
  "Expected source to reek, but it didn't"
50
50
  end
51
51
  def failure_message_for_should_not
52
- "Expected no smells, but got:\n#{@source.full_report}"
52
+ "Expected no smells, but got:\n#{@sniffer.quiet_report}"
53
53
  end
54
54
  end
55
55
 
56
- #
57
- # Returns +true+ if and only if the target source code contains smells.
58
- #
59
- def reek
60
- ShouldReek.new
61
- end
62
-
63
56
  class ShouldReekOf # :nodoc:
64
57
  def initialize(klass, patterns)
65
58
  @klass = klass
66
59
  @patterns = patterns
67
60
  end
68
61
  def matches?(actual)
69
- @source = actual.to_source
70
- @source.has_smell?(@klass, @patterns)
62
+ @sniffer = actual.sniff
63
+ @sniffer.has_smell?(@klass, @patterns)
71
64
  end
72
65
  def failure_message_for_should
73
- "Expected #{@source} to reek of #{@klass}, but it didn't"
66
+ "Expected #{@sniffer.desc} to reek of #{@klass}, but it didn't"
74
67
  end
75
68
  def failure_message_for_should_not
76
- "Expected #{@source} not to reek of #{@klass}, but got:\n#{@source.full_report}"
69
+ "Expected #{@sniffer.desc} not to reek of #{@klass}, but got:\n#{@sniffer.quiet_report}"
77
70
  end
78
71
  end
79
72
 
80
- #
81
- # Checks the target source code for instances of +smell_class+,
82
- # and returns +true+ only if one of them has a report string matching
83
- # all of the +patterns+.
84
- #
85
- def reek_of(smell_class, *patterns)
86
- ShouldReekOf.new(smell_class, patterns)
87
- end
88
-
89
73
  class ShouldReekOnlyOf # :nodoc:
90
74
  def initialize(klass, patterns)
91
75
  @klass = klass
92
76
  @patterns = patterns
93
77
  end
94
78
  def matches?(actual)
95
- @source = actual.to_source
96
- @source.report.length == 1 and @source.has_smell?(@klass, @patterns)
79
+ @sniffer = actual.sniff
80
+ @sniffer.smells_only_of?(@klass, @patterns)
97
81
  end
98
82
  def failure_message_for_should
99
- "Expected source to reek only of #{@klass}, but got:\n#{@source.full_report}"
83
+ "Expected #{@sniffer.desc} to reek only of #{@klass}, but got:\n#{@sniffer.quiet_report}"
100
84
  end
101
85
  def failure_message_for_should_not
102
- "Expected source not to reek only of #{@klass}, but it did"
86
+ "Expected #{@sniffer.desc} not to reek only of #{@klass}, but it did"
103
87
  end
104
88
  end
105
89
 
90
+ #
91
+ # Returns +true+ if and only if the target source code contains smells.
92
+ #
93
+ def reek
94
+ ShouldReek.new
95
+ end
96
+
97
+ #
98
+ # Checks the target source code for instances of +smell_class+,
99
+ # and returns +true+ only if one of them has a report string matching
100
+ # all of the +patterns+.
101
+ #
102
+ def reek_of(smell_class, *patterns)
103
+ ShouldReekOf.new(smell_class, patterns)
104
+ end
105
+
106
106
  #
107
107
  # As for reek_of, but the matched smell warning must be the only warning of
108
108
  # any kind in the target source code's Reek report.
@@ -113,32 +113,6 @@ module Reek
113
113
  end
114
114
  end
115
115
 
116
- class File
117
- def to_source
118
- Reek::Source.from_f(self)
119
- end
120
- end
121
-
122
- class String
123
- def to_source
124
- Reek::Source.from_s(self)
125
- end
126
- end
127
-
128
- class Array
129
- def to_source
130
- Reek::Source.from_pathlist(self)
131
- end
132
- end
133
-
134
- module Reek
135
- class Source
136
- def to_source
137
- self
138
- end
139
- end
140
- end
141
-
142
116
  if Object.const_defined?(:Spec)
143
117
  Spec::Runner.configure do |config|
144
118
  config.include(Reek::Spec)
data/lib/reek.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
2
 
3
3
  module Reek # :doc:
4
- VERSION = '1.1.3.9'
4
+ VERSION = '1.1.3.10'
5
5
  end
data/reek.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{reek}
5
- s.version = "1.1.3.9"
5
+ s.version = "1.1.3.10"
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{2009-07-06}
9
+ s.date = %q{2009-07-15}
10
10
  s.default_executable = %q{reek}
11
11
  s.description = %q{Code smell detector for Ruby}
12
12
  s.email = ["kevin@rutherford-software.com"]
13
13
  s.executables = ["reek"]
14
- s.extra_rdoc_files = ["History.txt", "README.txt"]
15
- s.files = ["History.txt", "README.txt", "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", "lib/reek.rb", "lib/reek/block_context.rb", "lib/reek/class_context.rb", "lib/reek/code_context.rb", "lib/reek/code_parser.rb", "lib/reek/config_file.rb", "lib/reek/detector_stack.rb", "lib/reek/exceptions.reek", "lib/reek/if_context.rb", "lib/reek/method_context.rb", "lib/reek/module_context.rb", "lib/reek/name.rb", "lib/reek/object_refs.rb", "lib/reek/object_source.rb", "lib/reek/options.rb", "lib/reek/rake_task.rb", "lib/reek/report.rb", "lib/reek/sexp_formatter.rb", "lib/reek/singleton_method_context.rb", "lib/reek/smell_warning.rb", "lib/reek/smells/control_couple.rb", "lib/reek/smells/duplication.rb", "lib/reek/smells/feature_envy.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/smell_detector.rb", "lib/reek/smells/uncommunicative_name.rb", "lib/reek/smells/utility_function.rb", "lib/reek/sniffer.rb", "lib/reek/source.rb", "lib/reek/spec.rb", "lib/reek/stop_context.rb", "lib/reek/yield_call_context.rb", "reek.gemspec", "spec/reek/block_context_spec.rb", "spec/reek/class_context_spec.rb", "spec/reek/code_context_spec.rb", "spec/reek/code_parser_spec.rb", "spec/reek/config_spec.rb", "spec/reek/if_context_spec.rb", "spec/reek/method_context_spec.rb", "spec/reek/module_context_spec.rb", "spec/reek/name_spec.rb", "spec/reek/object_refs_spec.rb", "spec/reek/object_source_spec.rb", "spec/reek/options_spec.rb", "spec/reek/report_spec.rb", "spec/reek/singleton_method_context_spec.rb", "spec/reek/smell_warning_spec.rb", "spec/reek/smells/control_couple_spec.rb", "spec/reek/smells/duplication_spec.rb", "spec/reek/smells/feature_envy_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/nested_iterators_spec.rb", "spec/reek/smells/smell_detector_spec.rb", "spec/reek/smells/uncommunicative_name_spec.rb", "spec/reek/smells/utility_function_spec.rb", "spec/reek/spec_spec.rb", "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/inline.rb", "spec/samples/masked/dirty.rb", "spec/samples/masked/masked.reek", "spec/samples/optparse.rb", "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/slow/inline_spec.rb", "spec/slow/optparse_spec.rb", "spec/slow/redcloth_spec.rb", "spec/slow/reek_source_spec.rb", "spec/slow/source_list_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/reek.rake", "tasks/test.rake"]
14
+ s.extra_rdoc_files = ["History.txt", "License.txt", "README.txt"]
15
+ s.files = ["History.txt", "License.txt", "README.txt", "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", "lib/reek.rb", "lib/reek/block_context.rb", "lib/reek/class_context.rb", "lib/reek/code_context.rb", "lib/reek/code_parser.rb", "lib/reek/config_file.rb", "lib/reek/core_extras.rb", "lib/reek/detector_stack.rb", "lib/reek/exceptions.reek", "lib/reek/if_context.rb", "lib/reek/method_context.rb", "lib/reek/module_context.rb", "lib/reek/name.rb", "lib/reek/object_refs.rb", "lib/reek/object_source.rb", "lib/reek/options.rb", "lib/reek/rake_task.rb", "lib/reek/report.rb", "lib/reek/sexp_formatter.rb", "lib/reek/singleton_method_context.rb", "lib/reek/smell_warning.rb", "lib/reek/smells/control_couple.rb", "lib/reek/smells/duplication.rb", "lib/reek/smells/feature_envy.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/smell_detector.rb", "lib/reek/smells/uncommunicative_name.rb", "lib/reek/smells/utility_function.rb", "lib/reek/sniffer.rb", "lib/reek/source.rb", "lib/reek/spec.rb", "lib/reek/stop_context.rb", "lib/reek/yield_call_context.rb", "reek.gemspec", "spec/reek/block_context_spec.rb", "spec/reek/class_context_spec.rb", "spec/reek/code_context_spec.rb", "spec/reek/code_parser_spec.rb", "spec/reek/config_spec.rb", "spec/reek/if_context_spec.rb", "spec/reek/method_context_spec.rb", "spec/reek/module_context_spec.rb", "spec/reek/name_spec.rb", "spec/reek/object_refs_spec.rb", "spec/reek/object_source_spec.rb", "spec/reek/options_spec.rb", "spec/reek/report_spec.rb", "spec/reek/should_reek_of_spec.rb", "spec/reek/should_reek_only_of_spec.rb", "spec/reek/should_reek_spec.rb", "spec/reek/singleton_method_context_spec.rb", "spec/reek/smell_warning_spec.rb", "spec/reek/smells/control_couple_spec.rb", "spec/reek/smells/duplication_spec.rb", "spec/reek/smells/feature_envy_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/nested_iterators_spec.rb", "spec/reek/smells/smell_detector_spec.rb", "spec/reek/smells/uncommunicative_name_spec.rb", "spec/reek/smells/utility_function_spec.rb", "spec/reek/sniffer_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/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/optparse.rb", "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/slow/inline_spec.rb", "spec/slow/optparse_spec.rb", "spec/slow/redcloth_spec.rb", "spec/slow/reek_source_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/reek.rake", "tasks/test.rake"]
16
16
  s.homepage = %q{http://wiki.github.com/kevinrutherford/reek}
17
17
  s.post_install_message = %q{
18
18
  For more information on reek, see http://wiki.github.com/kevinrutherford/reek
@@ -8,9 +8,9 @@ describe Dir do
8
8
  Dir['spec/samples/two_smelly_files/*.rb'].should reek_of(:UncommunicativeName)
9
9
  end
10
10
 
11
- it 'reports correct smells via SourceList' do
12
- src = Dir['spec/samples/two_smelly_files/*.rb'].to_source
13
- src.has_smell?(:UncommunicativeName).should be_true
11
+ it 'reports correct smells via Dir' do
12
+ sniffer = Dir['spec/samples/two_smelly_files/*.rb'].sniff
13
+ sniffer.has_smell?(:UncommunicativeName).should be_true
14
14
  end
15
15
 
16
16
  it 'copes with daft file specs' do
@@ -9,7 +9,7 @@ include Reek
9
9
 
10
10
  describe Report, " when empty" do
11
11
  before(:each) do
12
- @rpt = Report.new
12
+ @rpt = Report.new(Sniffer.new)
13
13
  end
14
14
 
15
15
  it 'should have zero length' do
@@ -19,12 +19,16 @@ describe Report, " when empty" do
19
19
  it 'should claim to be empty' do
20
20
  @rpt.should be_empty
21
21
  end
22
+
23
+ it 'has an empty quiet_report' do
24
+ @rpt.quiet_report.should == ''
25
+ end
22
26
  end
23
27
 
24
- describe Report, "to_s" do
28
+ describe Report, "smell_list" do
25
29
  before(:each) do
26
- rpt = Source.from_s('def simple(a) a[3] end').report
27
- @report = rpt.to_s.split("\n")
30
+ rpt = 'def simple(a) a[3] end'.sniff.report
31
+ @report = rpt.smell_list.split("\n")
28
32
  end
29
33
 
30
34
  it 'should mention every smell name' do
@@ -36,7 +40,7 @@ end
36
40
 
37
41
  describe Report, " as a SortedSet" do
38
42
  it 'should only add a smell once' do
39
- rpt = Report.new
43
+ rpt = Report.new(Sniffer.new)
40
44
  rpt << SmellWarning.new(Smells::FeatureEnvy.new, "self", 'too many!')
41
45
  rpt.length.should == 1
42
46
  rpt << SmellWarning.new(Smells::FeatureEnvy.new, "self", 'too many!')
@@ -0,0 +1,105 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ require 'reek/spec'
4
+
5
+ include Reek::Spec
6
+
7
+ describe ShouldReekOf, 'rdoc demo example' do
8
+ it 'works on a common source' do
9
+ ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'
10
+ ruby.should reek_of(:Duplication, /@other.thing[^\.]/)
11
+ ruby.should reek_of(:Duplication, /@other.thing.foo/)
12
+ ruby.should_not reek_of(:FeatureEnvy)
13
+ end
14
+
15
+ it 'works on a common sniffer' do
16
+ ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'.sniff
17
+ ruby.should reek_of(:Duplication, /@other.thing[^\.]/)
18
+ ruby.should reek_of(:Duplication, /@other.thing.foo/)
19
+ ruby.should_not reek_of(:FeatureEnvy)
20
+ end
21
+ end
22
+
23
+ describe ShouldReekOf, 'checking code in a string' do
24
+ before :each do
25
+ @clean_code = 'def good() true; end'
26
+ @smelly_code = 'def x() y = 4; end'
27
+ @matcher = ShouldReekOf.new(:UncommunicativeName, [/x/, /y/])
28
+ end
29
+
30
+ it 'matches a smelly String' do
31
+ @matcher.matches?(@smelly_code).should be_true
32
+ end
33
+
34
+ it 'doesnt match a fragrant String' do
35
+ @matcher.matches?(@clean_code).should be_false
36
+ end
37
+
38
+ it 'reports the smells when should_not fails' do
39
+ @matcher.matches?(@smelly_code).should be_true
40
+ @matcher.failure_message_for_should_not.should include(@smelly_code.sniff.quiet_report)
41
+ end
42
+ end
43
+
44
+ describe ShouldReekOf, 'checking code in a Dir' do
45
+ before :each do
46
+ @clean_dir = Dir['spec/samples/three_clean_files/*.rb']
47
+ @smelly_dir = Dir['spec/samples/two_smelly_files/*.rb']
48
+ @matcher = ShouldReekOf.new(:UncommunicativeName, [/Dirty/, /@s/])
49
+ end
50
+
51
+ it 'matches a smelly String' do
52
+ @matcher.matches?(@smelly_dir).should be_true
53
+ end
54
+
55
+ it 'doesnt match a fragrant String' do
56
+ @matcher.matches?(@clean_dir).should be_false
57
+ end
58
+
59
+ it 'reports the smells when should_not fails' do
60
+ @matcher.matches?(@smelly_dir).should be_true
61
+ @matcher.failure_message_for_should_not.should include(@smelly_dir.sniff.quiet_report)
62
+ end
63
+ end
64
+
65
+ describe ShouldReekOf, 'checking code in a File' do
66
+ before :each do
67
+ @clean_file = File.new(Dir['spec/samples/three_clean_files/*.rb'][0])
68
+ @smelly_file = File.new(Dir['spec/samples/two_smelly_files/*.rb'][0])
69
+ @matcher = ShouldReekOf.new(:UncommunicativeName, [/Dirty/, /@s/])
70
+ end
71
+
72
+ it 'matches a smelly String' do
73
+ @matcher.matches?(@smelly_file).should be_true
74
+ end
75
+
76
+ it 'doesnt match a fragrant String' do
77
+ @matcher.matches?(@clean_file).should be_false
78
+ end
79
+
80
+ it 'reports the smells when should_not fails' do
81
+ @matcher.matches?(@smelly_file).should be_true
82
+ @matcher.failure_message_for_should_not.should include(@smelly_file.sniff.quiet_report)
83
+ end
84
+ end
85
+
86
+ describe ShouldReekOf, 'report formatting' do
87
+ before :each do
88
+ @smelly_dir = Dir['spec/samples/mixed_results/*.rb']
89
+ @matcher = ShouldReekOf.new(:UncommunicativeName, [/Dirty/, /@s/])
90
+ @matcher.matches?(@smelly_dir)
91
+ @lines = @matcher.failure_message_for_should_not.split("\n").map {|str| str.chomp}
92
+ @error_message = @lines.shift
93
+ @smells = @lines.grep(/^ /)
94
+ @headers = (@lines - @smells)
95
+ end
96
+
97
+ it 'mentions every smell in the report' do
98
+ @smells.should have(12).warnings
99
+ end
100
+
101
+ it 'doesnt mention the clean files' do
102
+ @headers.should have(2).headers
103
+ @headers.should_not include('clean')
104
+ end
105
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ require 'reek/spec'
4
+
5
+ include Reek::Spec
6
+
7
+ describe ShouldReekOnlyOf, 'checking code in a string' do
8
+ before :each do
9
+ @clean_code = 'def good() true; end'
10
+ @smelly_code = 'def fine() y = 4; end'
11
+ @matcher = ShouldReekOnlyOf.new(:UncommunicativeName, [/y/])
12
+ end
13
+
14
+ it 'matches a smelly String' do
15
+ @matcher.matches?(@smelly_code).should be_true
16
+ end
17
+
18
+ it 'doesnt match a fragrant String' do
19
+ @matcher.matches?(@clean_code).should be_false
20
+ end
21
+
22
+ it 'reports the smells when should_not fails' do
23
+ @matcher.matches?(@smelly_code).should be_true
24
+ @matcher.failure_message_for_should_not.should include('UncommunicativeName')
25
+ end
26
+ end
27
+
28
+ describe ShouldReekOnlyOf, 'checking code in a Dir' do
29
+ before :each do
30
+ @clean_dir = Dir['spec/samples/three_clean_files/*.rb']
31
+ @smelly_dir = Dir['spec/samples/all_but_one_masked/*.rb']
32
+ @matcher = ShouldReekOnlyOf.new(:NestedIterators, [/Dirty\#a/])
33
+ end
34
+
35
+ it 'matches a smelly String' do
36
+ @matcher.matches?(@smelly_dir).should be_true
37
+ end
38
+
39
+ it 'doesnt match a fragrant String' do
40
+ @matcher.matches?(@clean_dir).should be_false
41
+ end
42
+
43
+ it 'reports the smells when should_not fails' do
44
+ @matcher.matches?(@smelly_dir).should be_true
45
+ @matcher.failure_message_for_should.should include(@smelly_dir.sniff.quiet_report)
46
+ end
47
+ end
48
+
49
+ describe ShouldReekOnlyOf, 'checking code in a File' do
50
+ before :each do
51
+ @clean_file = File.new(Dir['spec/samples/three_clean_files/*.rb'][0])
52
+ @smelly_file = File.new(Dir['spec/samples/all_but_one_masked/d*.rb'][0])
53
+ @matcher = ShouldReekOnlyOf.new(:NestedIterators, [/Dirty\#a/])
54
+ end
55
+
56
+ it 'matches a smelly String' do
57
+ @matcher.matches?(@smelly_file).should be_true
58
+ end
59
+
60
+ it 'doesnt match a fragrant String' do
61
+ @matcher.matches?(@clean_file).should be_false
62
+ end
63
+
64
+ it 'reports the smells when should_not fails' do
65
+ @matcher.matches?(@smelly_file).should be_true
66
+ @matcher.failure_message_for_should.should include(@smelly_file.sniff.quiet_report)
67
+ end
68
+ end
69
+
70
+ describe ShouldReekOnlyOf, 'report formatting' do
71
+ before :each do
72
+ @smelly_dir = Dir['spec/samples/all_but_one_masked/*.rb']
73
+ @matcher = ShouldReekOnlyOf.new(:NestedIterators, [/Dirty\#a/])
74
+ @matcher.matches?(@smelly_dir)
75
+ @lines = @matcher.failure_message_for_should.split("\n").map {|str| str.chomp}
76
+ @error_message = @lines.shift
77
+ @smells = @lines.grep(/^ /)
78
+ @headers = (@lines - @smells)
79
+ end
80
+
81
+ it 'doesnt mention the clean files' do
82
+ @headers.should have(1).header
83
+ @headers.should_not include('clean')
84
+ end
85
+ end
@@ -21,7 +21,7 @@ describe ShouldReek, 'checking code in a string' do
21
21
 
22
22
  it 'reports the smells when should_not fails' do
23
23
  @matcher.matches?(@smelly_code).should be_true
24
- @matcher.failure_message_for_should_not.should include(@smelly_code.to_source.full_report)
24
+ @matcher.failure_message_for_should_not.should include(@smelly_code.sniff.quiet_report)
25
25
  end
26
26
  end
27
27
 
@@ -42,7 +42,7 @@ describe ShouldReek, 'checking code in a Dir' do
42
42
 
43
43
  it 'reports the smells when should_not fails' do
44
44
  @matcher.matches?(@smelly_dir).should be_true
45
- @matcher.failure_message_for_should_not.should include(@smelly_dir.to_source.full_report)
45
+ @matcher.failure_message_for_should_not.should include(@smelly_dir.sniff.quiet_report)
46
46
  end
47
47
  end
48
48
 
@@ -63,6 +63,27 @@ describe ShouldReek, 'checking code in a File' do
63
63
 
64
64
  it 'reports the smells when should_not fails' do
65
65
  @matcher.matches?(@smelly_file).should be_true
66
- @matcher.failure_message_for_should_not.should include(@smelly_file.to_source.full_report)
66
+ @matcher.failure_message_for_should_not.should include(@smelly_file.sniff.quiet_report)
67
+ end
68
+ end
69
+
70
+ describe ShouldReek, 'report formatting' do
71
+ before :each do
72
+ @smelly_dir = Dir['spec/samples/mixed_results/*.rb']
73
+ @matcher = ShouldReek.new
74
+ @matcher.matches?(@smelly_dir)
75
+ @lines = @matcher.failure_message_for_should_not.split("\n").map {|str| str.chomp}
76
+ @error_message = @lines.shift
77
+ @smells = @lines.grep(/^ /)
78
+ @headers = (@lines - @smells)
79
+ end
80
+
81
+ it 'mentions every smell in the report' do
82
+ @smells.should have(12).warnings
83
+ end
84
+
85
+ it 'doesnt mention the clean files' do
86
+ @headers.should have(2).headers
87
+ @headers.should_not include('clean')
67
88
  end
68
89
  end
@@ -21,7 +21,7 @@ describe Duplication, "repeated method calls" do
21
21
  end
22
22
 
23
23
  it 'should report nested calls' do
24
- ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'.to_source
24
+ ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'.sniff
25
25
  ruby.should reek_of(:Duplication, /@other.thing[^\.]/)
26
26
  ruby.should reek_of(:Duplication, /@other.thing.foo/)
27
27
  end
@@ -1,6 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
2
  require 'reek/code_parser'
3
3
  require 'reek/report'
4
+ require 'reek/object_source'
4
5
  require 'reek/smells/large_class'
5
6
 
6
7
  include Reek
@@ -8,8 +8,8 @@ include Reek
8
8
  include Reek::Smells
9
9
 
10
10
  def process_method(src)
11
- source = Source.from_s(src)
12
- CodeParser.new(Sniffer.new).process_defn(source.generate_syntax_tree)
11
+ sniffer = src.sniff
12
+ CodeParser.new(sniffer).process_defn(sniffer.source.syntax_tree)
13
13
  end
14
14
 
15
15
  describe LongMethod do
@@ -26,7 +26,7 @@ describe LongMethod do
26
26
  end
27
27
 
28
28
  it 'should only report a long method once' do
29
- source =<<EOS
29
+ src = <<EOS
30
30
  def standard_entries(rbconfig)
31
31
  @abc = rbconfig
32
32
  rubypath = File.join(@abc['bindir'], @abcf['ruby_install_name'] + cff['EXEEXT'])
@@ -44,7 +44,7 @@ def standard_entries(rbconfig)
44
44
  end
45
45
  end
46
46
  EOS
47
- source.should reek_only_of(:LongMethod)
47
+ src.should reek_only_of(:LongMethod)
48
48
  end
49
49
 
50
50
  it 'should report long inner block' do