kevinrutherford-reek 0.3.1.4

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 (70) hide show
  1. data/History.txt +92 -0
  2. data/README.txt +6 -0
  3. data/Rakefile +7 -0
  4. data/bin/reek +19 -0
  5. data/lib/reek/block_context.rb +37 -0
  6. data/lib/reek/class_context.rb +73 -0
  7. data/lib/reek/code_context.rb +47 -0
  8. data/lib/reek/code_parser.rb +204 -0
  9. data/lib/reek/exceptions.reek +13 -0
  10. data/lib/reek/if_context.rb +25 -0
  11. data/lib/reek/method_context.rb +85 -0
  12. data/lib/reek/module_context.rb +34 -0
  13. data/lib/reek/name.rb +42 -0
  14. data/lib/reek/object_refs.rb +53 -0
  15. data/lib/reek/options.rb +92 -0
  16. data/lib/reek/rake_task.rb +121 -0
  17. data/lib/reek/report.rb +42 -0
  18. data/lib/reek/sexp_formatter.rb +52 -0
  19. data/lib/reek/singleton_method_context.rb +27 -0
  20. data/lib/reek/smell_warning.rb +49 -0
  21. data/lib/reek/smells/control_couple.rb +61 -0
  22. data/lib/reek/smells/duplication.rb +50 -0
  23. data/lib/reek/smells/feature_envy.rb +58 -0
  24. data/lib/reek/smells/large_class.rb +50 -0
  25. data/lib/reek/smells/long_method.rb +43 -0
  26. data/lib/reek/smells/long_parameter_list.rb +43 -0
  27. data/lib/reek/smells/long_yield_list.rb +18 -0
  28. data/lib/reek/smells/nested_iterators.rb +28 -0
  29. data/lib/reek/smells/smell_detector.rb +66 -0
  30. data/lib/reek/smells/smells.rb +85 -0
  31. data/lib/reek/smells/uncommunicative_name.rb +80 -0
  32. data/lib/reek/smells/utility_function.rb +34 -0
  33. data/lib/reek/source.rb +116 -0
  34. data/lib/reek/spec.rb +130 -0
  35. data/lib/reek/stop_context.rb +62 -0
  36. data/lib/reek/yield_call_context.rb +14 -0
  37. data/lib/reek.rb +8 -0
  38. data/spec/integration/reek_source_spec.rb +20 -0
  39. data/spec/integration/script_spec.rb +55 -0
  40. data/spec/reek/class_context_spec.rb +198 -0
  41. data/spec/reek/code_context_spec.rb +92 -0
  42. data/spec/reek/code_parser_spec.rb +44 -0
  43. data/spec/reek/config_spec.rb +42 -0
  44. data/spec/reek/module_context_spec.rb +38 -0
  45. data/spec/reek/object_refs_spec.rb +129 -0
  46. data/spec/reek/options_spec.rb +13 -0
  47. data/spec/reek/report_spec.rb +48 -0
  48. data/spec/reek/sexp_formatter_spec.rb +31 -0
  49. data/spec/reek/singleton_method_context_spec.rb +17 -0
  50. data/spec/reek/smells/control_couple_spec.rb +23 -0
  51. data/spec/reek/smells/duplication_spec.rb +81 -0
  52. data/spec/reek/smells/feature_envy_spec.rb +129 -0
  53. data/spec/reek/smells/large_class_spec.rb +86 -0
  54. data/spec/reek/smells/long_method_spec.rb +59 -0
  55. data/spec/reek/smells/long_parameter_list_spec.rb +92 -0
  56. data/spec/reek/smells/nested_iterators_spec.rb +33 -0
  57. data/spec/reek/smells/smell_spec.rb +24 -0
  58. data/spec/reek/smells/uncommunicative_name_spec.rb +118 -0
  59. data/spec/reek/smells/utility_function_spec.rb +96 -0
  60. data/spec/samples/inline.rb +704 -0
  61. data/spec/samples/inline_spec.rb +40 -0
  62. data/spec/samples/optparse.rb +1788 -0
  63. data/spec/samples/optparse_spec.rb +100 -0
  64. data/spec/samples/redcloth.rb +1130 -0
  65. data/spec/samples/redcloth_spec.rb +93 -0
  66. data/spec/spec.opts +1 -0
  67. data/spec/spec_helper.rb +15 -0
  68. data/tasks/reek.rake +20 -0
  69. data/tasks/rspec.rake +22 -0
  70. metadata +167 -0
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ require 'reek/code_parser'
4
+ require 'reek/sexp_formatter'
5
+
6
+ include Reek
7
+
8
+ def should_print(example)
9
+ it "should format #{example} correctly" do
10
+ sexp = CodeParser.parse_tree_for(example)[0]
11
+ SexpFormatter.format(sexp).should == example
12
+ end
13
+ end
14
+
15
+ describe SexpFormatter do
16
+ should_print 'self'
17
+ should_print 'Alpha'
18
+ should_print 'Alpha::Beta'
19
+ should_print '@@fred'
20
+ should_print '`ls`'
21
+ should_print 'array[0]'
22
+ should_print 'array[0, 1, 2]'
23
+ should_print 'obj.method(arg1, arg2)'
24
+ should_print 'obj.method'
25
+ should_print '$1'
26
+ should_print 'o=q.downcase'
27
+ should_print 'true'
28
+ should_print '"-#{q}xxx#{z.size}"'
29
+ should_print '0..5'
30
+ should_print '0..temp'
31
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ require 'reek/module_context'
4
+ require 'reek/singleton_method_context'
5
+ require 'reek/stop_context'
6
+
7
+ include Reek
8
+
9
+ describe SingletonMethodContext, 'outer_name' do
10
+
11
+ it "should report full context" do
12
+ element = StopContext.new
13
+ element = ModuleContext.new(element, [0, :mod])
14
+ element = SingletonMethodContext.new(element, [:defs, [:vcall, :a], :b, nil])
15
+ element.outer_name.should match(/mod::a\.b/)
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ require 'reek/smells/control_couple'
4
+
5
+ include Reek::Smells
6
+
7
+ describe ControlCouple do
8
+ it 'should report a ternary check on a parameter' do
9
+ 'def simple(arga) arga ? @ivar : 3 end'.should reek_of(:ControlCouple, /arga/)
10
+ end
11
+
12
+ it 'should not report a ternary check on an ivar' do
13
+ 'def simple(arga) @ivar ? arga : 3 end'.should_not reek
14
+ end
15
+
16
+ it 'should not report a ternary check on a lvar' do
17
+ 'def simple(arga) lvar = 27; lvar ? arga : @ivar end'.should_not reek
18
+ end
19
+
20
+ it 'should spot a couple inside a block' do
21
+ 'def blocks(arg) @text.map { |blk| arg ? blk : "#{blk}" } end'.should reek_of(:ControlCouple, /arg/)
22
+ end
23
+ end
@@ -0,0 +1,81 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+ require 'reek/report'
3
+ require 'reek/method_context'
4
+ require 'reek/stop_context'
5
+ require 'reek/smells/duplication'
6
+
7
+ include Reek
8
+ include Reek::Smells
9
+
10
+ describe Duplication, "repeated method calls" do
11
+ it 'should report repeated call' do
12
+ 'def double_thing() @other.thing + @other.thing end'.should reek_only_of(:Duplication, /@other.thing/)
13
+ end
14
+
15
+ it 'should report repeated call to lvar' do
16
+ 'def double_thing() other[@thing] + other[@thing] end'.should reek_only_of(:Duplication, /other\[@thing\]/)
17
+ end
18
+
19
+ it 'should report call parameters' do
20
+ 'def double_thing() @other.thing(2,3) + @other.thing(2,3) end'.should reek_only_of(:Duplication, /@other.thing\(2, 3\)/)
21
+ end
22
+
23
+ it 'should report nested calls' do
24
+ ruby = 'def double_thing() @other.thing.foo + @other.thing.foo end'.to_source
25
+ ruby.should reek_of(:Duplication, /@other.thing[^\.]/)
26
+ ruby.should reek_of(:Duplication, /@other.thing.foo/)
27
+ end
28
+
29
+ it 'should ignore calls to new' do
30
+ 'def double_thing() @other.new + @other.new end'.should_not reek
31
+ end
32
+ end
33
+
34
+ describe Duplication, "non-repeated method calls" do
35
+ it 'should not report similar calls' do
36
+ 'def equals(other) other.thing == self.thing end'.should_not reek
37
+ end
38
+
39
+ it 'should respect call parameters' do
40
+ 'def double_thing() @other.thing(3) + @other.thing(2) end'.should_not reek
41
+ end
42
+ end
43
+
44
+ require 'ostruct'
45
+
46
+ describe Duplication, '#examine' do
47
+ before :each do
48
+ @mc = OpenStruct.new
49
+ @dup = Duplication.new
50
+ end
51
+
52
+ it 'should return true when reporting a smell' do
53
+ @mc.calls = {'x' => 47}
54
+ @dup.examine(@mc, []).should == true
55
+ end
56
+
57
+ it 'should return false when not reporting a smell' do
58
+ @mc.calls = []
59
+ @dup.examine(@mc, []).should == false
60
+ end
61
+
62
+ it 'should return false when not reporting calls to new' do
63
+ @mc.calls = {[:call, :Set, :new] => 4}
64
+ @dup.examine(@mc, []).should == false
65
+ end
66
+ end
67
+
68
+ describe Duplication, 'when disabled' do
69
+ before :each do
70
+ @ctx = MethodContext.new(StopContext.new, [0, :double_thing])
71
+ @dup = Duplication.new({SmellDetector::ENABLED_KEY => false})
72
+ @rpt = Report.new
73
+ end
74
+
75
+ it 'should not report repeated call' do
76
+ @ctx.record_call_to([:fred])
77
+ @ctx.record_call_to([:fred])
78
+ @dup.examine(@ctx, @rpt).should == false
79
+ @rpt.length.should == 0
80
+ end
81
+ end
@@ -0,0 +1,129 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+ require 'reek/smells/feature_envy'
3
+ require 'reek/method_context'
4
+ require 'reek/stop_context'
5
+
6
+ include Reek
7
+ include Reek::Smells
8
+
9
+ describe FeatureEnvy, 'with only messages to self' do
10
+ it 'should not report use of self' do
11
+ 'def simple() self.to_s + self.to_i end'.should_not reek
12
+ end
13
+
14
+ it 'should not report vcall with no argument' do
15
+ 'def simple() func; end'.should_not reek
16
+ end
17
+
18
+ it 'should not report vcall with argument' do
19
+ 'def simple(arga) func(17); end'.should_not reek
20
+ end
21
+ end
22
+
23
+ describe FeatureEnvy, 'when the receiver is a parameter' do
24
+ it 'should not report single use' do
25
+ 'def no_envy(arga) arga.barg(@item) end'.should_not reek
26
+ end
27
+
28
+ it 'should not report return value' do
29
+ 'def no_envy(arga) arga.barg(@item); arga end'.should_not reek
30
+ end
31
+
32
+ it 'should report many calls to parameter' do
33
+ 'def envy(arga) arga.b(arga) + arga.c(@fred) end'.should reek_only_of(:FeatureEnvy, /arga/)
34
+ end
35
+ end
36
+
37
+ describe FeatureEnvy, 'when there are many possible receivers' do
38
+ it 'should report highest affinity' do
39
+ ruby = 'def total_envy
40
+ fred = @item
41
+ total = 0
42
+ total += fred.price
43
+ total += fred.tax
44
+ total *= 1.15
45
+ end'
46
+ ruby.should reek_only_of(:FeatureEnvy, /total/)
47
+ end
48
+
49
+ it 'should report multiple affinities' do
50
+ ruby = 'def total_envy
51
+ fred = @item
52
+ total = 0
53
+ total += fred.price
54
+ total += fred.tax
55
+ end'
56
+ ruby.should reek_of(:FeatureEnvy, /total/)
57
+ ruby.should reek_of(:FeatureEnvy, /fred/)
58
+ end
59
+ end
60
+
61
+ describe FeatureEnvy, 'when the receiver is external' do
62
+ it 'should ignore global variables' do
63
+ 'def no_envy() $s2.to_a; $s2[@item] end'.should_not reek
64
+ end
65
+
66
+ it 'should not report class methods' do
67
+ 'def simple() self.class.new.flatten_merge(self) end'.should_not reek
68
+ end
69
+ end
70
+
71
+ describe FeatureEnvy, 'when the receiver is an ivar' do
72
+ it 'should not report single use of an ivar' do
73
+ 'def no_envy() @item.to_a end'.should_not reek
74
+ end
75
+
76
+ it 'should not report returning an ivar' do
77
+ 'def no_envy() @item.to_a; @item end'.should_not reek
78
+ end
79
+
80
+ it 'should not report ivar usage in a parameter' do
81
+ 'def no_envy; @item.price + tax(@item) - savings(@item) end'.should_not reek
82
+ end
83
+
84
+ it 'should not be fooled by duplication' do
85
+ ruby = Source.from_s('def feed(thing); @cow.feed_to(thing.pig); @duck.feed_to(thing.pig); end')
86
+ ruby.should reek_only_of(:Duplication, /thing.pig/)
87
+ end
88
+
89
+ it 'should count local calls' do
90
+ ruby = Source.from_s('def feed(thing); cow.feed_to(thing.pig); duck.feed_to(thing.pig); end')
91
+ ruby.should reek_only_of(:Duplication, /thing.pig/)
92
+ end
93
+ end
94
+
95
+ describe FeatureEnvy, '#examine' do
96
+
97
+ before :each do
98
+ @context = MethodContext.new(StopContext.new, [:defn, :cool])
99
+ @fe = FeatureEnvy.new
100
+ end
101
+
102
+ it 'should return true when reporting a smell' do
103
+ @context.refs.record_ref([:lvar, :thing])
104
+ @context.refs.record_ref([:lvar, :thing])
105
+ @fe.examine(@context, []).should == true
106
+ end
107
+
108
+ it 'should return false when not reporting a smell' do
109
+ @fe.examine(@context, []).should == false
110
+ end
111
+ end
112
+
113
+ describe FeatureEnvy, 'when the receiver is an lvar' do
114
+ it 'should not report single use of an lvar' do
115
+ 'def no_envy() lv = @item; lv.to_a end'.should_not reek
116
+ end
117
+
118
+ it 'should not report returning an lvar' do
119
+ 'def no_envy() lv = @item; lv.to_a; lv end'.should_not reek
120
+ end
121
+
122
+ it 'should report many calls to lvar' do
123
+ 'def envy; lv = @item; lv.price + lv.tax end'.should reek_only_of(:FeatureEnvy, /lv/)
124
+ end
125
+
126
+ it 'should not report lvar usage in a parameter' do
127
+ 'def no_envy; lv = @item; lv.price + tax(lv) - savings(lv) end'.should_not reek
128
+ end
129
+ end
@@ -0,0 +1,86 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+ require 'reek/code_parser'
3
+ require 'reek/report'
4
+ require 'reek/smells/large_class'
5
+
6
+ include Reek
7
+ include Reek::Smells
8
+
9
+ describe LargeClass do
10
+
11
+ class BigOne
12
+ 26.times do |i|
13
+ define_method "method#{i}".to_sym do
14
+ @melting
15
+ end
16
+ end
17
+ end
18
+
19
+ before(:each) do
20
+ @rpt = Report.new
21
+ @cchk = CodeParser.new(@rpt, SmellConfig.new.smell_listeners)
22
+ end
23
+
24
+ it 'should not report short class' do
25
+ class ShortClass
26
+ def method1() @var1; end
27
+ def method2() @var2; end
28
+ def method3() @var3; end
29
+ def method4() @var4; end
30
+ def method5() @var5; end
31
+ def method6() @var6; end
32
+ end
33
+ @cchk.check_object(ShortClass)
34
+ @rpt.should be_empty
35
+ end
36
+
37
+ it 'should report large class' do
38
+ @cchk.check_object(BigOne)
39
+ @rpt.length.should == 1
40
+ end
41
+
42
+ it 'should report class name' do
43
+ @cchk.check_object(BigOne)
44
+ @rpt[0].report.should match(/BigOne/)
45
+ end
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
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
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
67
+
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
73
+ end
74
+ end
75
+ end
76
+
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
+ end
81
+
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
85
+ end
86
+ end
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ require 'reek/code_parser'
4
+ require 'reek/report'
5
+
6
+ include Reek
7
+
8
+ describe CodeParser, "(Long Method)" do
9
+ it 'should not report short methods' do
10
+ 'def short(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;end'.should_not reek
11
+ end
12
+
13
+ it 'should report long methods' do
14
+ 'def long(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;@fry = 6;end'.should reek_only_of(:LongMethod, /6 statements/)
15
+ end
16
+
17
+ it 'should not report initialize' do
18
+ 'def initialize(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;@fry = 6;end'.should_not reek
19
+ end
20
+
21
+ it 'should only report a long method once' do
22
+ source =<<EOS
23
+ def standard_entries(rbconfig)
24
+ @abc = rbconfig
25
+ rubypath = File.join(@abc['bindir'], @abcf['ruby_install_name'] + cff['EXEEXT'])
26
+ major = yyy['MAJOR'].to_i
27
+ minor = zzz['MINOR'].to_i
28
+ teeny = ccc['TEENY'].to_i
29
+ version = ""
30
+ if c['rubylibdir']
31
+ @libruby = "/lib/ruby"
32
+ @librubyver = "/lib/ruby/"
33
+ @librubyverarch = "/lib/ruby/"
34
+ @siteruby = "lib/ruby/version/site_ruby"
35
+ @siterubyver = siteruby
36
+ @siterubyverarch = "$siterubyver/['arch']}"
37
+ end
38
+ end
39
+ EOS
40
+ source.should reek_only_of(:LongMethod)
41
+ end
42
+
43
+ it 'should report long inner block' do
44
+ src = <<EOS
45
+ def long(arga)
46
+ f(3)
47
+ self.each do |xyzero|
48
+ xyzero = 1
49
+ xyzero = 2
50
+ xyzero = 3
51
+ xyzero = 4
52
+ xyzero = 5
53
+ xyzero = 6
54
+ end
55
+ end
56
+ EOS
57
+ src.should reek_only_of(:LongMethod)
58
+ end
59
+ end
@@ -0,0 +1,92 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ require 'reek/code_parser'
4
+ require 'reek/smells/long_parameter_list'
5
+ require 'reek/report'
6
+
7
+ include Reek
8
+ include Reek::Smells
9
+
10
+ describe CodeParser, "(Long Parameter List)" do
11
+
12
+ describe 'for methods with few parameters' do
13
+ it 'should report nothing for no parameters' do
14
+ 'def simple; f(3);true; end'.should_not reek
15
+ end
16
+ it 'should report nothing for 1 parameter' do
17
+ 'def simple(yep) f(3);true end'.should_not reek
18
+ end
19
+ it 'should report nothing for 2 parameters' do
20
+ 'def simple(yep,zero) f(3);true end'.should_not reek
21
+ end
22
+ it 'should not count an optional block' do
23
+ 'def simple(alpha, yep, zero, &opt) f(3);true end'.should_not reek
24
+ end
25
+ it 'should not report inner block with too many parameters' do
26
+ 'def simple(yep,zero); m[3]; rand(34); f.each { |arga, argb, argc, argd| true}; end'.should_not reek
27
+ end
28
+
29
+ describe 'and default values' do
30
+ it 'should report nothing for 1 parameter' do
31
+ 'def simple(zero=nil) f(3);false end'.should_not reek
32
+ end
33
+ it 'should report nothing for 2 parameters with 1 default' do
34
+ 'def simple(yep, zero=nil) f(3);false end'.should_not reek
35
+ end
36
+ it 'should report nothing for 2 defaulted parameters' do
37
+ 'def simple(yep=4, zero=nil) f(3);false end'.should_not reek
38
+ end
39
+ end
40
+ end
41
+
42
+ describe 'for methods with too many parameters' do
43
+ it 'should report 4 parameters' do
44
+ 'def simple(arga, argb, argc, argd) f(3);true end'.should reek_only_of(:LongParameterList, /4 parameters/)
45
+ end
46
+ it 'should report 8 parameters' do
47
+ 'def simple(arga, argb, argc, argd,arge, argf, argg, argh) f(3);true end'.should reek_only_of(:LongParameterList, /8 parameters/)
48
+ end
49
+
50
+ describe 'and default values' do
51
+ it 'should report 3 with 1 defaulted' do
52
+ 'def simple(polly, queue, yep, zero=nil) f(3);false end'.should reek_only_of(:LongParameterList, /4 parameters/)
53
+ end
54
+ it 'should report with 3 defaulted' do
55
+ 'def simple(aarg, polly=2, yep=true, zero=nil) f(3);false end'.should reek_only_of(:LongParameterList, /4 parameters/)
56
+ end
57
+ end
58
+
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
+ class InnerTest
66
+ def xyzero(arga,argb) f(3);true end
67
+ def abc(argx,yep,zero,argm) f(3);false end
68
+ end
69
+
70
+ 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/)
74
+ end
75
+ end
76
+ end
77
+
78
+ describe 'yield' do
79
+ it 'should not report yield with no parameters' do
80
+ 'def simple(arga, argb, &blk) f(3);yield; end'.should_not reek
81
+ end
82
+ it 'should not report yield with few parameters' do
83
+ 'def simple(arga, argb, &blk) f(3);yield a,b; end'.should_not reek
84
+ end
85
+ 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/)
87
+ end
88
+ it 'should not report yield of a long expression' do
89
+ 'def simple(arga, argb, &blk) f(3);yield(if @dec then argb else 5+3 end); end'.should_not reek
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ require 'reek/smells/nested_iterators'
4
+
5
+ include Reek::Smells
6
+
7
+ describe NestedIterators do
8
+
9
+ it 'should report nested iterators in a method' do
10
+ 'def bad(fred) @fred.each {|item| item.each {|ting| ting.ting} } end'.should reek_only_of(:NestedIterators)
11
+ end
12
+
13
+ it 'should not report method with successive iterators' do
14
+ 'def bad(fred)
15
+ @fred.each {|item| item.each }
16
+ @jim.each {|ting| ting.each }
17
+ end'.should_not reek
18
+ end
19
+
20
+ it 'should not report method with chained iterators' do
21
+ 'def chained
22
+ @sig.keys.sort_by { |xray| xray.to_s }.each { |min| md5 << min.to_s }
23
+ end'.should_not reek
24
+ end
25
+
26
+ it 'should report nested iterators only once per method' do
27
+ 'def bad(fred)
28
+ @fred.each {|item| item.each {|part| @joe.send} }
29
+ @jim.each {|ting| ting.each {|piece| @hal.send} }
30
+ end'.should reek_only_of(:NestedIterators)
31
+ end
32
+ end
33
+
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ require 'reek/smells/smells'
4
+
5
+ include Reek
6
+
7
+ describe SmellWarning, ' in comparisons' do
8
+ before :each do
9
+ @first = SmellWarning.new(Smells::FeatureEnvy.new, "self", "self")
10
+ @second = SmellWarning.new(Smells::FeatureEnvy.new, "self", "self")
11
+ end
12
+
13
+ it 'should hash equal when the smell is the same' do
14
+ @first.hash.should == @second.hash
15
+ end
16
+
17
+ it 'should compare equal when the smell is the same' do
18
+ @first.should == @second
19
+ end
20
+
21
+ it 'should compare equal when using <=>' do
22
+ (@first <=> @second).should == 0
23
+ end
24
+ end