reek 1.0.0 → 1.1.3

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 (50) hide show
  1. data/History.txt +56 -22
  2. data/config/defaults.reek +3 -5
  3. data/lib/reek.rb +1 -1
  4. data/lib/reek/block_context.rb +27 -5
  5. data/lib/reek/class_context.rb +5 -9
  6. data/lib/reek/code_parser.rb +23 -50
  7. data/lib/reek/method_context.rb +18 -12
  8. data/lib/reek/module_context.rb +1 -1
  9. data/lib/reek/name.rb +8 -1
  10. data/lib/reek/object_refs.rb +2 -3
  11. data/lib/reek/object_source.rb +53 -0
  12. data/lib/reek/report.rb +41 -2
  13. data/lib/reek/sexp_formatter.rb +4 -46
  14. data/lib/reek/smells/large_class.rb +27 -8
  15. data/lib/reek/smells/long_parameter_list.rb +1 -1
  16. data/lib/reek/smells/smells.rb +4 -8
  17. data/lib/reek/source.rb +19 -8
  18. data/lib/reek/stop_context.rb +4 -16
  19. data/lib/reek/yield_call_context.rb +1 -3
  20. data/reek.gemspec +11 -9
  21. data/spec/reek/block_context_spec.rb +40 -0
  22. data/spec/reek/class_context_spec.rb +11 -40
  23. data/spec/reek/code_context_spec.rb +2 -1
  24. data/spec/reek/code_parser_spec.rb +0 -10
  25. data/spec/reek/config_spec.rb +2 -2
  26. data/spec/reek/method_context_spec.rb +14 -0
  27. data/spec/reek/name_spec.rb +13 -0
  28. data/spec/reek/object_refs_spec.rb +11 -9
  29. data/spec/reek/report_spec.rb +1 -1
  30. data/spec/reek/singleton_method_context_spec.rb +1 -1
  31. data/spec/reek/smells/duplication_spec.rb +2 -2
  32. data/spec/reek/smells/feature_envy_spec.rb +132 -36
  33. data/spec/reek/smells/large_class_spec.rb +48 -47
  34. data/spec/reek/smells/long_method_spec.rb +1 -1
  35. data/spec/reek/smells/long_parameter_list_spec.rb +4 -11
  36. data/spec/reek/smells/uncommunicative_name_spec.rb +6 -1
  37. data/spec/reek/smells/utility_function_spec.rb +6 -9
  38. data/spec/{samples → slow}/inline_spec.rb +13 -10
  39. data/spec/{samples → slow}/optparse_spec.rb +20 -12
  40. data/spec/{samples → slow}/redcloth_spec.rb +16 -8
  41. data/spec/{integration → slow}/reek_source_spec.rb +0 -0
  42. data/spec/{samples → slow/samples}/inline.rb +0 -0
  43. data/spec/{samples → slow/samples}/optparse.rb +0 -0
  44. data/spec/{samples → slow/samples}/redcloth.rb +0 -0
  45. data/spec/{integration → slow}/script_spec.rb +0 -0
  46. data/spec/slow/source_list_spec.rb +40 -0
  47. data/spec/spec_helper.rb +2 -0
  48. data/tasks/rspec.rake +1 -1
  49. metadata +30 -15
  50. data/spec/reek/sexp_formatter_spec.rb +0 -31
@@ -8,18 +8,19 @@ include Reek::Smells
8
8
 
9
9
  describe LargeClass do
10
10
 
11
- class BigOne
12
- 26.times do |i|
13
- define_method "method#{i}".to_sym do
14
- @melting
11
+ it 'should report large class' do
12
+ class BigOne
13
+ 26.times do |i|
14
+ define_method "method#{i}".to_sym do
15
+ @melting
16
+ end
15
17
  end
16
18
  end
19
+ BigOne.should reek_only_of(:LargeClass, /BigOne/)
17
20
  end
21
+ end
18
22
 
19
- before(:each) do
20
- @rpt = Report.new
21
- @cchk = CodeParser.new(@rpt, SmellConfig.new.smell_listeners)
22
- end
23
+ describe LargeClass do
23
24
 
24
25
  it 'should not report short class' do
25
26
  class ShortClass
@@ -30,57 +31,57 @@ describe LargeClass do
30
31
  def method5() @var5; end
31
32
  def method6() @var6; end
32
33
  end
33
- @cchk.check_object(ShortClass)
34
- @rpt.should be_empty
34
+ ShortClass.should_not reek
35
35
  end
36
+ end
36
37
 
37
- it 'should report large class' do
38
- @cchk.check_object(BigOne)
39
- @rpt.length.should == 1
40
- end
38
+ describe LargeClass, 'when exceptions are listed' do
41
39
 
42
- it 'should report class name' do
43
- @cchk.check_object(BigOne)
44
- @rpt[0].report.should match(/BigOne/)
40
+ before(:each) do
41
+ @rpt = Report.new
42
+ @ctx = ClassContext.create(StopContext.new, [0, :Humungous])
43
+ 30.times { |num| @ctx.record_method("method#{num}") }
44
+ @config = LargeClass.default_config
45
45
  end
46
46
 
47
- describe 'when exceptions are listed' do
48
- before :each do
49
- @ctx = ClassContext.create(StopContext.new, [0, :Humungous])
50
- 30.times { |num| @ctx.record_method("method#{num}") }
51
- @config = LargeClass.default_config
52
- end
47
+ it 'should ignore first excepted name' do
48
+ @config[LargeClass::EXCLUDE_KEY] = ['Humungous']
49
+ lc = LargeClass.new(@config)
50
+ lc.examine(@ctx, @rpt).should == false
51
+ @rpt.length.should == 0
52
+ end
53
53
 
54
- it 'should ignore first excepted name' do
55
- @config[LargeClass::EXCLUDE_KEY] = ['Humungous']
56
- lc = LargeClass.new(@config)
57
- lc.examine(@ctx, @rpt).should == false
58
- @rpt.length.should == 0
59
- end
54
+ it 'should ignore second excepted name' do
55
+ @config[LargeClass::EXCLUDE_KEY] = ['Oversized', 'Humungous']
56
+ lc = LargeClass.new(@config)
57
+ lc.examine(@ctx, @rpt).should == false
58
+ @rpt.length.should == 0
59
+ end
60
60
 
61
- it 'should ignore second excepted name' do
62
- @config[LargeClass::EXCLUDE_KEY] = ['Oversized', 'Humungous']
63
- lc = LargeClass.new(@config)
64
- lc.examine(@ctx, @rpt).should == false
65
- @rpt.length.should == 0
66
- end
61
+ it 'should report non-excepted name' do
62
+ @config[LargeClass::EXCLUDE_KEY] = ['SmellMe']
63
+ lc = LargeClass.new(@config)
64
+ lc.examine(@ctx, @rpt).should == true
65
+ @rpt.length.should == 1
66
+ end
67
+ end
67
68
 
68
- it 'should report non-excepted name' do
69
- @config[LargeClass::EXCLUDE_KEY] = ['SmellMe']
70
- lc = LargeClass.new(@config)
71
- lc.examine(@ctx, @rpt).should == true
72
- @rpt.length.should == 1
69
+ describe LargeClass, 'counting instance variables' do
70
+ it 'warns about class with 10 ivars' do
71
+ class ManyIvars
72
+ def method
73
+ @vara = @varb = @varc = @vard = @vare
74
+ @varf = @varg = @varh = @vari = @varj
75
+ end
73
76
  end
77
+ ManyIvars.should reek_of(:LargeClass, /10/)
74
78
  end
75
- end
76
79
 
77
- describe LargeClass do
78
- it 'should not report empty class in another module' do
79
- 'class Treetop::Runtime::SyntaxNode; end'.should_not reek
80
+ it 'ignores class with only a couple of ivars' do
81
+ LargeClass.should_not reek_of(:LargeClass)
80
82
  end
81
83
 
82
- it 'should deal with :: scoped names' do
83
- element = ClassContext.create(StopContext.new, [:colon2, [:colon2, [:const, :Treetop], :Runtime], :SyntaxNode])
84
- element.num_methods.should == 0
84
+ it 'ignores fq class with only a couple of ivars' do
85
+ Reek::Smells::LargeClass.should_not reek_of(:LargeClass)
85
86
  end
86
87
  end
@@ -5,7 +5,7 @@ require 'reek/report'
5
5
 
6
6
  include Reek
7
7
 
8
- describe CodeParser, "(Long Method)" do
8
+ describe LongMethod do
9
9
  it 'should not report short methods' do
10
10
  'def short(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;end'.should_not reek
11
11
  end
@@ -7,7 +7,7 @@ require 'reek/report'
7
7
  include Reek
8
8
  include Reek::Smells
9
9
 
10
- describe CodeParser, "(Long Parameter List)" do
10
+ describe LongParameterList do
11
11
 
12
12
  describe 'for methods with few parameters' do
13
13
  it 'should report nothing for no parameters' do
@@ -25,7 +25,7 @@ describe CodeParser, "(Long Parameter List)" do
25
25
  it 'should not report inner block with too many parameters' do
26
26
  'def simple(yep,zero); m[3]; rand(34); f.each { |arga, argb, argc, argd| true}; end'.should_not reek
27
27
  end
28
-
28
+
29
29
  describe 'and default values' do
30
30
  it 'should report nothing for 1 parameter' do
31
31
  'def simple(zero=nil) f(3);false end'.should_not reek
@@ -57,20 +57,13 @@ describe CodeParser, "(Long Parameter List)" do
57
57
  end
58
58
 
59
59
  describe 'in a class' do
60
- before(:each) do
61
- @rpt = Report.new
62
- @cchk = CodeParser.new(@rpt, SmellConfig.new.smell_listeners)
63
- end
64
-
65
60
  class InnerTest
66
61
  def xyzero(arga,argb) f(3);true end
67
62
  def abc(argx,yep,zero,argm) f(3);false end
68
63
  end
69
64
 
70
65
  it 'should only report long param list' do
71
- @cchk.check_object(InnerTest)
72
- @rpt.length.should == 1
73
- @rpt[0].report.should match(/Long Parameter List/)
66
+ InnerTest.should reek_only_of(:LongParameterList, /abc/)
74
67
  end
75
68
  end
76
69
  end
@@ -83,7 +76,7 @@ describe CodeParser, "(Long Parameter List)" do
83
76
  'def simple(arga, argb, &blk) f(3);yield a,b; end'.should_not reek
84
77
  end
85
78
  it 'should report yield with many parameters' do
86
- 'def simple(arga, argb, &blk) f(3);yield a,b,a,b; end'.should reek_only_of(:LongYieldList, /simple/, /yields/, /4/)
79
+ 'def simple(arga, argb, &blk) f(3);yield arga,argb,arga,argb; end'.should reek_only_of(:LongYieldList, /simple/, /yields/, /4/)
87
80
  end
88
81
  it 'should not report yield of a long expression' do
89
82
  'def simple(arga, argb, &blk) f(3);yield(if @dec then argb else 5+3 end); end'.should_not reek
@@ -46,6 +46,11 @@ describe UncommunicativeName, "local variable name" do
46
46
  it 'should report variable name only once' do
47
47
  'def simple(fred) x = jim(45); x = y end'.should reek_only_of(:UncommunicativeName, /x/)
48
48
  end
49
+
50
+ it 'should report a bad name inside a block' do
51
+ src = 'def clean(text) text.each { q2 = 3 } end'
52
+ src.should reek_of(:UncommunicativeName, /q2/)
53
+ end
49
54
  end
50
55
 
51
56
  describe UncommunicativeName, "parameter name" do
@@ -64,7 +69,7 @@ describe UncommunicativeName, "block parameter name" do
64
69
  it "should report parameter's name" do
65
70
  'def help() @stuff.each {|x|} end'.should reek_only_of(:UncommunicativeName, /x/, /block/, /variable name/)
66
71
  end
67
-
72
+
68
73
  it "should report method name via if context" do
69
74
  src = <<EOS
70
75
  def bad
@@ -7,17 +7,11 @@ include Reek::Smells
7
7
 
8
8
  describe UtilityFunction do
9
9
 
10
- before(:each) do
11
- @rpt = Report.new
12
- @cchk = CodeParser.new(@rpt, SmellConfig.new.smell_listeners)
13
- end
14
-
15
10
  it 'should not report attrset' do
16
11
  class Fred
17
12
  attr_writer :xyz
18
13
  end
19
- @cchk.check_object(Fred)
20
- @rpt.should be_empty
14
+ Fred.should_not reek
21
15
  end
22
16
 
23
17
  it 'should count usages of self'do
@@ -43,8 +37,7 @@ describe UtilityFunction do
43
37
  class Son < Father
44
38
  def thing(ff); ff; end
45
39
  end
46
- @cchk.check_object(Son)
47
- @rpt.should be_empty
40
+ Son.should_not reek
48
41
  end
49
42
 
50
43
  it 'should not report class method' do
@@ -93,4 +86,8 @@ describe UtilityFunction, 'should only report a method containing a call' do
93
86
  it 'should not report references to self' do
94
87
  'def into; self; end'.should_not reek
95
88
  end
89
+
90
+ it 'should recognise an ivar reference within a block' do
91
+ 'def clean(text) text.each { @fred = 3} end'.should_not reek
92
+ end
96
93
  end
@@ -2,23 +2,26 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
2
 
3
3
  describe 'sample gem source code' do
4
4
  it "reports the correct smells in inline.rb" do
5
- ruby = File.new('spec/samples/inline.rb').to_source
5
+ ruby = File.new("#{SAMPLES_DIR}/inline.rb").to_source
6
6
  ruby.should reek_of(:ControlCouple, /Inline::C#parse_signature/, /raw/)
7
7
  ruby.should reek_of(:ControlCouple, /Module#inline/, /options/)
8
- ruby.should reek_of(:Duplication, /Inline::C#build/, /\$\?\.==\(0\)/)
8
+ ruby.should reek_of(:Duplication, /Inline::C#build/, /\(\$\?\ == 0\)/)
9
9
  ruby.should reek_of(:Duplication, /Inline::C#build/, /Inline.directory/)
10
10
  ruby.should reek_of(:Duplication, /Inline::C#build/, /io.puts/)
11
- ruby.should reek_of(:Duplication, /Inline::C#build/, /io.puts\(#endif\)/)
12
- ruby.should reek_of(:Duplication, /Inline::C#build/, /io.puts\(#ifdef __cplusplus\)/)
13
- ruby.should reek_of(:Duplication, /Inline::C#crap_for_windoze/, /Config::CONFIG\[libdir\]/)
14
- ruby.should reek_of(:Duplication, /Inline::C#generate/, /result.sub!\(\(\?-mix:\\A\\n\), \)/)
15
- ruby.should reek_of(:Duplication, /Inline::C#generate/, /signature\[args\]/)
16
- ruby.should reek_of(:Duplication, /Inline::C#generate/, /signature\[args\].map/)
11
+ ruby.should reek_of(:Duplication, /Inline::C#build/, /io.puts\("#endif"\)/)
12
+ ruby.should reek_of(:Duplication, /Inline::C#build/, /io.puts\("#ifdef __cplusplus"\)/)
13
+ ruby.should reek_of(:Duplication, /Inline::C#build/, /module_name/)
14
+ ruby.should reek_of(:Duplication, /Inline::C#build/, /warn\("Output:\\n\#\{result\}"\)/)
15
+ ruby.should reek_of(:Duplication, /Inline::C#crap_for_windoze/, /Config::CONFIG\["libdir"\]/)
16
+ ruby.should reek_of(:Duplication, /Inline::C#generate/, /result.sub!\(\/\\A\\n\/, ""\)/)
17
+ ruby.should reek_of(:Duplication, /Inline::C#generate/, /signature\["args"\]/)
18
+ ruby.should reek_of(:Duplication, /Inline::C#generate/, /signature\["args"\].map/)
17
19
  ruby.should reek_of(:Duplication, /Inline::C#initialize/, /stack.empty?/)
20
+ ruby.should reek_of(:Duplication, /Inline::C#load/, /so_name/)
18
21
  ruby.should reek_of(:Duplication, /Inline::self.rootdir/, /env.nil?/)
19
22
  ruby.should reek_of(:Duplication, /Module#inline/, /Inline.const_get\(lang\)/)
20
23
  ruby.should reek_of(:FeatureEnvy, /Inline::C#strip_comments/, /src/)
21
- ruby.should reek_of(:LargeClass, /Inline::C/)
24
+ ruby.should reek_of(:LargeClass, /Inline::C/, /instance variables/)
22
25
  ruby.should reek_of(:LongMethod, /File#self.write_with_backup/)
23
26
  ruby.should reek_of(:LongMethod, /Inline::C#build/)
24
27
  ruby.should reek_of(:LongMethod, /Inline::C#generate/)
@@ -35,6 +38,6 @@ describe 'sample gem source code' do
35
38
  ruby.should reek_of(:UncommunicativeName, /Inline::C#module_name/, /'x'/)
36
39
  ruby.should reek_of(:UncommunicativeName, /Inline::C#parse_signature/, /'x'/)
37
40
  ruby.should reek_of(:UtilityFunction, /Inline::C#strip_comments/)
38
- ruby.report.should have_at_most(32).smells
41
+ ruby.report.should have_at_most(35).smells
39
42
  end
40
43
  end
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
2
 
3
3
  describe 'sample gem source code' do
4
4
  it "reports the correct smells in optparse.rb" do
5
- ruby = File.new('spec/samples/optparse.rb').to_source
5
+ ruby = File.new("#{SAMPLES_DIR}/optparse.rb").to_source
6
6
  ruby.should reek_of(:ControlCouple, /OptionParser#List#accept/, /pat/)
7
7
  ruby.should reek_of(:ControlCouple, /OptionParser#List#update/, /lopts/)
8
8
  ruby.should reek_of(:ControlCouple, /OptionParser#List#update/, /sopts/)
@@ -10,24 +10,33 @@ describe 'sample gem source code' do
10
10
  ruby.should reek_of(:ControlCouple, /OptionParser#Switch#NoArgument#parse/, /arg/)
11
11
  ruby.should reek_of(:ControlCouple, /OptionParser#Switch#OptionalArgument#parse/, /arg/)
12
12
  ruby.should reek_of(:ControlCouple, /OptionParser#Switch#RequiredArgument#parse/, /arg/)
13
+ ruby.should reek_of(:ControlCouple, /OptionParser#block/, /o/)
14
+ ruby.should reek_of(:ControlCouple, /OptionParser#block/, /s/)
15
+ ruby.should reek_of(:ControlCouple, /OptionParser#block\/block/, /pkg/)
16
+ ruby.should reek_of(:ControlCouple, /OptionParser#getopts\/block/, /val/)
13
17
  ruby.should reek_of(:ControlCouple, /OptionParser#parse_in_order/, /setter/)
14
18
  ruby.should reek_of(:Duplication, /OptionParser#Completion::complete/, /candidates.size/)
15
19
  ruby.should reek_of(:Duplication, /OptionParser#Completion::complete/, /k.id2name/)
16
20
  ruby.should reek_of(:Duplication, /OptionParser#Switch#parse_arg/, /s.length/)
17
- ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /block.max/)
18
- ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /block.max.to_i/)
19
- ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /indent.+\(l\)/)
21
+ ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /left.collect \{ \|s\| s\.length \}\.max/)
22
+ ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /left.collect \{ \|s\| s\.length \}\.max\.to_i/)
23
+ ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /\(indent \+ l\)/)
20
24
  ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /left.collect/)
21
25
  ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /left.shift/)
22
26
  ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /left\[-1\]/)
23
27
  ruby.should reek_of(:Duplication, /OptionParser#Switch#summarize/, /s.length/)
24
- ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /default_style.guess\(arg=a\)/)
25
- ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /long.<<\(o=q.downcase\)/)
26
- ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /pattern.method\(convert\)/)
27
- ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /pattern.method\(convert\).to_proc/)
28
- ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /pattern.respond_to\?\(convert\)/)
28
+ ruby.should reek_of(:Duplication, /OptionParser#getopts/, /result\[opt\] = false/)
29
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /default_style.guess\(arg = a\)/)
30
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /\(long << o = q.downcase\)/)
31
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /notwice\(a \? \(Object\) : \(TrueClass\), klass, "type"\)/)
32
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /notwice\(NilClass, klass, "type"\)/)
33
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /pattern.method\(:convert\)/)
34
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /pattern.method\(:convert\).to_proc/)
35
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /pattern.respond_to\?\(:convert\)/)
29
36
  ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /q.downcase/)
30
- ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /sdesc.<<\("-\#\{q\}"\)/)
37
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /search\(:atype, o\)/)
38
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /search\(:atype, FalseClass\)/)
39
+ ruby.should reek_of(:Duplication, /OptionParser#make_switch/, /\(sdesc << "-\#\{q\}"\)/)
31
40
  ruby.should reek_of(:Duplication, /OptionParser#order/, /argv\[0\]/)
32
41
  ruby.should reek_of(:Duplication, /OptionParser#parse/, /argv\[0\]/)
33
42
  ruby.should reek_of(:Duplication, /OptionParser#parse_in_order/, /\$\!.set_option\(arg, true\)/)
@@ -45,7 +54,6 @@ describe 'sample gem source code' do
45
54
  ruby.should reek_of(:LargeClass, /OptionParser/)
46
55
  ruby.should reek_of(:LongMethod, /OptionParser#Completion::complete/)
47
56
  ruby.should reek_of(:LongMethod, /OptionParser#List#update/)
48
- ruby.should reek_of(:LongMethod, /OptionParser#Switch#PlacedArgument#parse/)
49
57
  ruby.should reek_of(:LongMethod, /OptionParser#Switch#parse_arg/)
50
58
  ruby.should reek_of(:LongMethod, /OptionParser#Switch#summarize/)
51
59
  ruby.should reek_of(:LongMethod, /OptionParser#getopts/)
@@ -95,6 +103,6 @@ describe 'sample gem source code' do
95
103
  ruby.should reek_of(:UncommunicativeName, /OptionParser#summarize/, /'l'/)
96
104
  ruby.should reek_of(:UncommunicativeName, /OptionParser#ver/, /'v'/)
97
105
  ruby.should reek_of(:UncommunicativeName, /block/, /'q'/)
98
- ruby.report.should have_at_most(92).smells
106
+ ruby.report.should have_at_most(116).smells
99
107
  end
100
108
  end
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
2
 
3
3
  describe 'sample gem source code' do
4
4
  it "reports the correct smells in redcloth.rb" do
5
- ruby = File.new('spec/samples/redcloth.rb').to_source
5
+ ruby = File.new("#{SAMPLES_DIR}/redcloth.rb").to_source
6
6
  ruby.should reek_of(:ControlCouple, /RedCloth#blocks\/block/, /deep_code/)
7
7
  ruby.should reek_of(:ControlCouple, /RedCloth#check_refs/, /text/)
8
8
  ruby.should reek_of(:ControlCouple, /RedCloth#pba/, /text_in/)
@@ -13,23 +13,31 @@ describe 'sample gem source code' do
13
13
  ruby.should reek_of(:Duplication, /RedCloth#block_textile_lists/, /depth.last/)
14
14
  ruby.should reek_of(:Duplication, /RedCloth#block_textile_lists/, /depth.last.length/)
15
15
  ruby.should reek_of(:Duplication, /RedCloth#block_textile_lists/, /depth\[i\]/)
16
- ruby.should reek_of(:Duplication, /RedCloth#block_textile_lists/, /line_id.-\(1\)/)
17
- ruby.should reek_of(:Duplication, /RedCloth#block_textile_lists/, /lines\[line_id.-\(1\)\]/)
16
+ ruby.should reek_of(:Duplication, /RedCloth#block_textile_lists/, /\(line_id - 1\)/)
17
+ ruby.should reek_of(:Duplication, /RedCloth#block_textile_lists/, /lines\[\(line_id - 1\)\]/)
18
18
  ruby.should reek_of(:Duplication, /RedCloth#block_textile_lists/, /tl.length/)
19
19
  ruby.should reek_of(:Duplication, /RedCloth#clean_html/, /tags\[tag\]/)
20
20
  ruby.should reek_of(:Duplication, /RedCloth#pba/, /\$1.length/)
21
21
  ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /@pre_list.last/)
22
- ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /@pre_list.last.<<\(line\)/)
23
- ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /codepre.-\(used_offtags.length\)/)
24
- ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /codepre.-\(used_offtags.length\).>\(0\)/)
22
+ ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /\(@pre_list.last << line\)/)
23
+ ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /\(codepre - used_offtags.length\)/)
24
+ ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /\(\(codepre - used_offtags.length\) > 0\)/)
25
25
  ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /codepre.zero?/)
26
+ ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /htmlesc\(line, :NoQuotes\)/)
26
27
  ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /used_offtags.length/)
27
- ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /used_offtags\[notextile\]/)
28
+ ruby.should reek_of(:Duplication, /RedCloth#rip_offtags/, /used_offtags\["notextile"\]/)
29
+ ruby.should reek_of(:FeatureEnvy, /RedCloth#block_markdown_atx/, /text/)
30
+ ruby.should reek_of(:FeatureEnvy, /RedCloth#block_markdown_rule/, /text/)
31
+ ruby.should reek_of(:FeatureEnvy, /RedCloth#block_markdown_setext/, /text/)
32
+ ruby.should reek_of(:FeatureEnvy, /RedCloth#block_textile_lists/, /depth/)
33
+ ruby.should reek_of(:FeatureEnvy, /RedCloth#clean_html/, /raw/)
28
34
  ruby.should reek_of(:FeatureEnvy, /RedCloth#clean_html/, /tags/)
29
35
  ruby.should reek_of(:FeatureEnvy, /RedCloth#clean_white_space/, /text/)
30
36
  ruby.should reek_of(:FeatureEnvy, /RedCloth#flush_left/, /indt/)
31
37
  ruby.should reek_of(:FeatureEnvy, /RedCloth#flush_left/, /text/)
38
+ ruby.should reek_of(:FeatureEnvy, /RedCloth#footnote_ref/, /text/)
32
39
  ruby.should reek_of(:FeatureEnvy, /RedCloth#htmlesc/, /str/)
40
+ ruby.should reek_of(:FeatureEnvy, /RedCloth#incoming_entities/, /text/)
33
41
  ruby.should reek_of(:FeatureEnvy, /RedCloth#no_textile/, /text/)
34
42
  ruby.should reek_of(:FeatureEnvy, /RedCloth#pba/, /style/)
35
43
  ruby.should reek_of(:FeatureEnvy, /RedCloth#pba/, /text/)
@@ -88,6 +96,6 @@ describe 'sample gem source code' do
88
96
  ruby.should reek_of(:UtilityFunction, /RedCloth#incoming_entities/)
89
97
  ruby.should reek_of(:UtilityFunction, /RedCloth#no_textile/)
90
98
  ruby.should reek_of(:UtilityFunction, /RedCloth#v_align/)
91
- ruby.report.should have_at_most(85).smells
99
+ ruby.report.should have_at_most(93).smells
92
100
  end
93
101
  end
File without changes
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ require 'reek/source'
4
+
5
+ include Reek
6
+
7
+ describe SourceList, 'from_pathlist' do
8
+
9
+ describe 'with no smells in any source' do
10
+ before :each do
11
+ @src = Dir['lib/reek/*.rb'].to_source
12
+ end
13
+
14
+ it 'reports no smells' do
15
+ @src.report.length.should == 0
16
+ end
17
+
18
+ it 'is empty' do
19
+ @src.report.should be_empty
20
+ end
21
+ end
22
+
23
+ describe 'with smells in one source' do
24
+ before :each do
25
+ @src = Source.from_pathlist(["#{SAMPLES_DIR}/inline.rb", 'lib/reek.rb'])
26
+ end
27
+
28
+ it 'reports some smells in the samples' do
29
+ @src.report.should have_at_least(30).smells
30
+ end
31
+
32
+ it 'is smelly' do
33
+ @src.should be_smelly
34
+ end
35
+
36
+ it 'reports an UncommunicativeName' do
37
+ @src.report.any? {|warning| warning.report =~ /Uncommunicative Name/}.should be_true
38
+ end
39
+ end
40
+ end