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.
- data/History.txt +56 -22
- data/config/defaults.reek +3 -5
- data/lib/reek.rb +1 -1
- data/lib/reek/block_context.rb +27 -5
- data/lib/reek/class_context.rb +5 -9
- data/lib/reek/code_parser.rb +23 -50
- data/lib/reek/method_context.rb +18 -12
- data/lib/reek/module_context.rb +1 -1
- data/lib/reek/name.rb +8 -1
- data/lib/reek/object_refs.rb +2 -3
- data/lib/reek/object_source.rb +53 -0
- data/lib/reek/report.rb +41 -2
- data/lib/reek/sexp_formatter.rb +4 -46
- data/lib/reek/smells/large_class.rb +27 -8
- data/lib/reek/smells/long_parameter_list.rb +1 -1
- data/lib/reek/smells/smells.rb +4 -8
- data/lib/reek/source.rb +19 -8
- data/lib/reek/stop_context.rb +4 -16
- data/lib/reek/yield_call_context.rb +1 -3
- data/reek.gemspec +11 -9
- data/spec/reek/block_context_spec.rb +40 -0
- data/spec/reek/class_context_spec.rb +11 -40
- data/spec/reek/code_context_spec.rb +2 -1
- data/spec/reek/code_parser_spec.rb +0 -10
- data/spec/reek/config_spec.rb +2 -2
- data/spec/reek/method_context_spec.rb +14 -0
- data/spec/reek/name_spec.rb +13 -0
- data/spec/reek/object_refs_spec.rb +11 -9
- data/spec/reek/report_spec.rb +1 -1
- data/spec/reek/singleton_method_context_spec.rb +1 -1
- data/spec/reek/smells/duplication_spec.rb +2 -2
- data/spec/reek/smells/feature_envy_spec.rb +132 -36
- data/spec/reek/smells/large_class_spec.rb +48 -47
- data/spec/reek/smells/long_method_spec.rb +1 -1
- data/spec/reek/smells/long_parameter_list_spec.rb +4 -11
- data/spec/reek/smells/uncommunicative_name_spec.rb +6 -1
- data/spec/reek/smells/utility_function_spec.rb +6 -9
- data/spec/{samples → slow}/inline_spec.rb +13 -10
- data/spec/{samples → slow}/optparse_spec.rb +20 -12
- data/spec/{samples → slow}/redcloth_spec.rb +16 -8
- data/spec/{integration → slow}/reek_source_spec.rb +0 -0
- data/spec/{samples → slow/samples}/inline.rb +0 -0
- data/spec/{samples → slow/samples}/optparse.rb +0 -0
- data/spec/{samples → slow/samples}/redcloth.rb +0 -0
- data/spec/{integration → slow}/script_spec.rb +0 -0
- data/spec/slow/source_list_spec.rb +40 -0
- data/spec/spec_helper.rb +2 -0
- data/tasks/rspec.rake +1 -1
- metadata +30 -15
- data/spec/reek/sexp_formatter_spec.rb +0 -31
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
require 'reek/block_context'
|
4
|
+
require 'reek/method_context'
|
5
|
+
|
6
|
+
include Reek
|
7
|
+
|
8
|
+
describe BlockContext do
|
9
|
+
|
10
|
+
it "should record single parameter" do
|
11
|
+
element = StopContext.new
|
12
|
+
element = BlockContext.new(element, s(s(:lasgn, :x), nil))
|
13
|
+
element.variable_names.should == [Name.new(:x)]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should record single parameter within a method" do
|
17
|
+
element = StopContext.new
|
18
|
+
element = MethodContext.new(element, s(:defn, :help))
|
19
|
+
element = BlockContext.new(element, s(s(:lasgn, :x), nil))
|
20
|
+
element.variable_names.should == [Name.new(:x)]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "records multiple parameters" do
|
24
|
+
element = StopContext.new
|
25
|
+
element = BlockContext.new(element, s(s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))), nil))
|
26
|
+
element.variable_names.should == [Name.new(:x), Name.new(:y)]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not pass parameters upward" do
|
30
|
+
mc = MethodContext.new(StopContext.new, s(:defn, :help))
|
31
|
+
element = BlockContext.new(mc, s(s(:lasgn, :x)))
|
32
|
+
mc.variable_names.should be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'records local variables' do
|
36
|
+
bctx = BlockContext.new(StopContext.new, nil)
|
37
|
+
bctx.record_local_variable(:q2)
|
38
|
+
bctx.variable_names.should include(Name.new(:q2))
|
39
|
+
end
|
40
|
+
end
|
@@ -39,46 +39,6 @@ EOEX
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
describe Class do
|
43
|
-
|
44
|
-
module Insert
|
45
|
-
def meth_a() end
|
46
|
-
private
|
47
|
-
def meth_b() end
|
48
|
-
protected
|
49
|
-
def meth_c() end
|
50
|
-
end
|
51
|
-
|
52
|
-
class Parent
|
53
|
-
def meth1() end
|
54
|
-
private
|
55
|
-
def meth2() end
|
56
|
-
protected
|
57
|
-
def meth3() end
|
58
|
-
end
|
59
|
-
|
60
|
-
class FullChild < Parent
|
61
|
-
include Insert
|
62
|
-
def meth7() end
|
63
|
-
private
|
64
|
-
def meth8() end
|
65
|
-
protected
|
66
|
-
def meth6() end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe 'with no superclass or modules' do
|
70
|
-
it 'should report correct number of methods' do
|
71
|
-
Parent.non_inherited_methods.length.should == 3
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe 'with superclass and modules' do
|
76
|
-
it 'should report correct number of methods' do
|
77
|
-
FullChild.non_inherited_methods.length.should == 3
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
42
|
describe ClassContext, 'overridden methods' do
|
83
43
|
class Above
|
84
44
|
def above() end
|
@@ -196,3 +156,14 @@ describe CodeContext, 'find class' do
|
|
196
156
|
end
|
197
157
|
end
|
198
158
|
end
|
159
|
+
|
160
|
+
describe ClassContext do
|
161
|
+
it 'should not report empty class in another module' do
|
162
|
+
'class Treetop::Runtime::SyntaxNode; end'.should_not reek
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should deal with :: scoped names' do
|
166
|
+
element = ClassContext.create(StopContext.new, [:colon2, [:colon2, [:const, :Treetop], :Runtime], :SyntaxNode])
|
167
|
+
element.num_methods.should == 0
|
168
|
+
end
|
169
|
+
end
|
@@ -45,7 +45,8 @@ describe CodeContext, 'instance variables' do
|
|
45
45
|
element = MethodContext.new(class_element, [0, :bad])
|
46
46
|
element = BlockContext.new(element, nil)
|
47
47
|
element.record_instance_variable(:fred)
|
48
|
-
class_element.variable_names.should ==
|
48
|
+
class_element.variable_names.size.should == 1
|
49
|
+
class_element.variable_names.should include(Name.new(:fred))
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
@@ -20,16 +20,6 @@ describe CodeParser, 'with a global method definition' do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
describe CodeParser, 'when given a C extension' do
|
24
|
-
before(:each) do
|
25
|
-
@cchk = CodeParser.new(Report.new, SmellConfig.new.smell_listeners)
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should ignore :cfunc' do
|
29
|
-
@cchk.check_object(Enumerable)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
23
|
describe CodeParser, 'when a yield is the receiver' do
|
34
24
|
it 'should report no problems' do
|
35
25
|
source = 'def values(*args)
|
data/spec/reek/config_spec.rb
CHANGED
@@ -17,7 +17,7 @@ describe 'Config' do
|
|
17
17
|
other = Hash.new {|hash,key| hash[key] = {} }
|
18
18
|
other['one']['gunk'] = 45
|
19
19
|
other['two']['four'] = false
|
20
|
-
@first
|
20
|
+
other.push_keys(@first)
|
21
21
|
@first['two']['four'].should == false
|
22
22
|
@first['one'].keys.length.should == 3
|
23
23
|
end
|
@@ -36,7 +36,7 @@ describe Config, 'merging arrays' do
|
|
36
36
|
it 'should merge array values' do
|
37
37
|
first = {'key' => {'one' => [1,2,3]}}
|
38
38
|
second = {'key' => {'one' => [4,5]}}
|
39
|
-
|
39
|
+
second.push_keys(first)
|
40
40
|
first['key']['one'].should == [1,2,3,4,5]
|
41
41
|
end
|
42
42
|
end
|
@@ -49,4 +49,18 @@ describe MethodContext do
|
|
49
49
|
mctx.record_call_to([:call, [:ivar, :@cow], :feed_to])
|
50
50
|
mctx.envious_receivers.should == []
|
51
51
|
end
|
52
|
+
|
53
|
+
it 'should count calls to self' do
|
54
|
+
mctx = MethodContext.new(StopContext.new, [:defn, :equals])
|
55
|
+
mctx.refs.record_ref([:lvar, :other])
|
56
|
+
mctx.record_call_to([:call, [:self], :thing])
|
57
|
+
mctx.envious_receivers.should be_empty
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should recognise a call on self' do
|
61
|
+
mc = MethodContext.new(StopContext.new, s(:defn, :deep))
|
62
|
+
mc.record_call_to(s(:call, s(:lvar, :text), :each, s(:arglist)))
|
63
|
+
mc.record_call_to(s(:call, nil, :shelve, s(:arglist)))
|
64
|
+
mc.envious_receivers.should be_empty
|
65
|
+
end
|
52
66
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'reek/name'
|
3
|
+
|
4
|
+
include Reek
|
5
|
+
|
6
|
+
describe Name, 'resolving symbols' do
|
7
|
+
it 'finds fq loaded class' do
|
8
|
+
exp = [:class, :"Reek::Smells::LargeClass", nil]
|
9
|
+
ctx = StopContext.new
|
10
|
+
res = Name.resolve(exp[1], ctx)
|
11
|
+
res[1].should == "LargeClass"
|
12
|
+
end
|
13
|
+
end
|
@@ -9,8 +9,8 @@ describe ObjectRefs, 'when empty' do
|
|
9
9
|
@refs = ObjectRefs.new
|
10
10
|
end
|
11
11
|
|
12
|
-
it 'should report
|
13
|
-
@refs.refs_to_self.should ==
|
12
|
+
it 'should report no refs to self' do
|
13
|
+
@refs.refs_to_self.should == 0
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -23,7 +23,7 @@ describe ObjectRefs, 'with no refs to self' do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'should report no refs to self' do
|
26
|
-
@refs.refs_to_self.should ==
|
26
|
+
@refs.refs_to_self.should == 0
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'should report :a as the max' do
|
@@ -45,16 +45,16 @@ describe ObjectRefs, 'with one ref to self' do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'should report 1 ref to self' do
|
48
|
-
@refs.refs_to_self.should ==
|
48
|
+
@refs.refs_to_self.should == 1
|
49
49
|
end
|
50
50
|
|
51
|
-
it 'should report self among the max' do
|
51
|
+
it 'should not report self among the max' do
|
52
52
|
@refs.max_keys.should be_include('a')
|
53
|
-
@refs.max_keys.
|
53
|
+
@refs.max_keys.should_not include(Sexp.from_array([:lit, :self]))
|
54
54
|
end
|
55
55
|
|
56
|
-
it 'should report self as the max' do
|
57
|
-
@refs.self_is_max?.should ==
|
56
|
+
it 'should not report self as the max' do
|
57
|
+
@refs.self_is_max?.should == false
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -62,6 +62,7 @@ describe ObjectRefs, 'with many refs to self' do
|
|
62
62
|
before(:each) do
|
63
63
|
@refs = ObjectRefs.new
|
64
64
|
@refs.record_reference_to_self
|
65
|
+
@refs.record_reference_to_self
|
65
66
|
@refs.record_ref('a')
|
66
67
|
@refs.record_reference_to_self
|
67
68
|
@refs.record_ref('b')
|
@@ -87,6 +88,7 @@ describe ObjectRefs, 'when self is not the only max' do
|
|
87
88
|
@refs = ObjectRefs.new
|
88
89
|
@refs.record_ref('a')
|
89
90
|
@refs.record_reference_to_self
|
91
|
+
@refs.record_reference_to_self
|
90
92
|
@refs.record_ref('b')
|
91
93
|
@refs.record_ref('a')
|
92
94
|
end
|
@@ -115,7 +117,7 @@ describe ObjectRefs, 'when self is not among the max' do
|
|
115
117
|
end
|
116
118
|
|
117
119
|
it 'should report all refs to self' do
|
118
|
-
@refs.refs_to_self.should ==
|
120
|
+
@refs.refs_to_self.should == 0
|
119
121
|
end
|
120
122
|
|
121
123
|
it 'should not report self among the max' do
|
data/spec/reek/report_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe SingletonMethodContext, 'outer_name' do
|
|
11
11
|
it "should report full context" do
|
12
12
|
element = StopContext.new
|
13
13
|
element = ModuleContext.new(element, [0, :mod])
|
14
|
-
element = SingletonMethodContext.new(element, [:defs, [:
|
14
|
+
element = SingletonMethodContext.new(element, [:defs, [:call, nil, :a, [:arglist]], :b, nil])
|
15
15
|
element.outer_name.should match(/mod::a\.b/)
|
16
16
|
end
|
17
17
|
end
|
@@ -13,7 +13,7 @@ describe Duplication, "repeated method calls" do
|
|
13
13
|
end
|
14
14
|
|
15
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\]/)
|
16
|
+
'def double_thing(other) other[@thing] + other[@thing] end'.should reek_only_of(:Duplication, /other\[@thing\]/)
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'should report call parameters' do
|
@@ -50,7 +50,7 @@ describe Duplication, '#examine' do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'should return true when reporting a smell' do
|
53
|
-
@mc.calls = {
|
53
|
+
@mc.calls = {s(:call, nil, :other, s(:arglist)) => 47}
|
54
54
|
@dup.examine(@mc, []).should == true
|
55
55
|
end
|
56
56
|
|
@@ -6,7 +6,7 @@ require 'reek/stop_context'
|
|
6
6
|
include Reek
|
7
7
|
include Reek::Smells
|
8
8
|
|
9
|
-
describe FeatureEnvy
|
9
|
+
describe FeatureEnvy do
|
10
10
|
it 'should not report use of self' do
|
11
11
|
'def simple() self.to_s + self.to_i end'.should_not reek
|
12
12
|
end
|
@@ -18,23 +18,26 @@ describe FeatureEnvy, 'with only messages to self' do
|
|
18
18
|
it 'should not report vcall with argument' do
|
19
19
|
'def simple(arga) func(17); end'.should_not reek
|
20
20
|
end
|
21
|
-
end
|
22
21
|
|
23
|
-
describe FeatureEnvy, 'when the receiver is a parameter' do
|
24
22
|
it 'should not report single use' do
|
25
|
-
'def no_envy(arga)
|
23
|
+
'def no_envy(arga)
|
24
|
+
arga.barg(@item)
|
25
|
+
end'.should_not reek
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'should not report return value' do
|
29
|
-
'def no_envy(arga)
|
29
|
+
'def no_envy(arga)
|
30
|
+
arga.barg(@item)
|
31
|
+
arga
|
32
|
+
end'.should_not reek
|
30
33
|
end
|
31
34
|
|
32
35
|
it 'should report many calls to parameter' do
|
33
|
-
'def envy(arga)
|
36
|
+
'def envy(arga)
|
37
|
+
arga.b(arga) + arga.c(@fred)
|
38
|
+
end'.should reek_only_of(:FeatureEnvy, /arga/)
|
34
39
|
end
|
35
|
-
end
|
36
40
|
|
37
|
-
describe FeatureEnvy, 'when there are many possible receivers' do
|
38
41
|
it 'should report highest affinity' do
|
39
42
|
ruby = 'def total_envy
|
40
43
|
fred = @item
|
@@ -56,9 +59,7 @@ describe FeatureEnvy, 'when there are many possible receivers' do
|
|
56
59
|
ruby.should reek_of(:FeatureEnvy, /total/)
|
57
60
|
ruby.should reek_of(:FeatureEnvy, /fred/)
|
58
61
|
end
|
59
|
-
end
|
60
62
|
|
61
|
-
describe FeatureEnvy, 'when the receiver is external' do
|
62
63
|
it 'should ignore global variables' do
|
63
64
|
'def no_envy() $s2.to_a; $s2[@item] end'.should_not reek
|
64
65
|
end
|
@@ -66,9 +67,7 @@ describe FeatureEnvy, 'when the receiver is external' do
|
|
66
67
|
it 'should not report class methods' do
|
67
68
|
'def simple() self.class.new.flatten_merge(self) end'.should_not reek
|
68
69
|
end
|
69
|
-
end
|
70
70
|
|
71
|
-
describe FeatureEnvy, 'when the receiver is an ivar' do
|
72
71
|
it 'should not report single use of an ivar' do
|
73
72
|
'def no_envy() @item.to_a end'.should_not reek
|
74
73
|
end
|
@@ -78,17 +77,132 @@ describe FeatureEnvy, 'when the receiver is an ivar' do
|
|
78
77
|
end
|
79
78
|
|
80
79
|
it 'should not report ivar usage in a parameter' do
|
81
|
-
'def no_envy
|
80
|
+
'def no_envy
|
81
|
+
@item.price + tax(@item) - savings(@item)
|
82
|
+
end'.should_not reek
|
82
83
|
end
|
83
84
|
|
84
85
|
it 'should not be fooled by duplication' do
|
85
|
-
|
86
|
-
|
86
|
+
'def feed(thing)
|
87
|
+
@cow.feed_to(thing.pig)
|
88
|
+
@duck.feed_to(thing.pig)
|
89
|
+
end'.should reek_only_of(:Duplication, /thing.pig/)
|
87
90
|
end
|
88
91
|
|
89
92
|
it 'should count local calls' do
|
90
|
-
|
91
|
-
|
93
|
+
'def feed(thing)
|
94
|
+
cow.feed_to(thing.pig)
|
95
|
+
duck.feed_to(thing.pig)
|
96
|
+
end'.should reek_only_of(:Duplication, /thing.pig/)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should not report single use of an lvar' do
|
100
|
+
'def no_envy()
|
101
|
+
lv = @item
|
102
|
+
lv.to_a
|
103
|
+
end'.should_not reek
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should not report returning an lvar' do
|
107
|
+
'def no_envy()
|
108
|
+
lv = @item
|
109
|
+
lv.to_a
|
110
|
+
lv
|
111
|
+
end'.should_not reek
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should report many calls to lvar' do
|
115
|
+
'def envy
|
116
|
+
lv = @item
|
117
|
+
lv.price + lv.tax
|
118
|
+
end'.should reek_only_of(:FeatureEnvy, /lv/)
|
119
|
+
#
|
120
|
+
# def moved_version
|
121
|
+
# price + tax
|
122
|
+
# end
|
123
|
+
#
|
124
|
+
# def envy
|
125
|
+
# @item.moved_version
|
126
|
+
# end
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'ignores lvar usage in a parameter' do
|
130
|
+
'def no_envy
|
131
|
+
lv = @item
|
132
|
+
lv.price + tax(lv) - savings(lv)
|
133
|
+
end'.should_not reek
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'reports the most-used ivar' do
|
137
|
+
pending('bug')
|
138
|
+
'def func
|
139
|
+
@other.a
|
140
|
+
@other.b
|
141
|
+
@nother.c
|
142
|
+
end'.should reek_of(:FeatureEnvy, /@other/)
|
143
|
+
#
|
144
|
+
# def other.func(me)
|
145
|
+
# a
|
146
|
+
# b
|
147
|
+
# me.nother_c
|
148
|
+
# end
|
149
|
+
#
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'ignores multiple ivars' do
|
153
|
+
'def func
|
154
|
+
@other.a
|
155
|
+
@other.b
|
156
|
+
@nother.c
|
157
|
+
@nother.d
|
158
|
+
end'.should_not reek
|
159
|
+
#
|
160
|
+
# def other.func(me)
|
161
|
+
# a
|
162
|
+
# b
|
163
|
+
# me.nother_c
|
164
|
+
# me.nother_d
|
165
|
+
# end
|
166
|
+
#
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'ignores frequent use of a call' do
|
170
|
+
'def func
|
171
|
+
other.a
|
172
|
+
other.b
|
173
|
+
nother.c
|
174
|
+
end'.should_not reek_of(:FeatureEnvy)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'counts self references correctly' do
|
178
|
+
'def adopt!(other)
|
179
|
+
other.keys.each do |key|
|
180
|
+
ov = other[key]
|
181
|
+
if Array === ov and has_key?(key)
|
182
|
+
self[key] += ov
|
183
|
+
else
|
184
|
+
self[key] = ov
|
185
|
+
end
|
186
|
+
end
|
187
|
+
self
|
188
|
+
end'.should_not reek
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe FeatureEnvy do
|
193
|
+
it 'counts references to self correctly' do
|
194
|
+
ruby = <<EOS
|
195
|
+
def report
|
196
|
+
unless @report
|
197
|
+
@report = Report.new
|
198
|
+
cf = SmellConfig.new
|
199
|
+
cf = cf.load_local(@dir) if @dir
|
200
|
+
CodeParser.new(@report, cf.smell_listeners).check_source(@source)
|
201
|
+
end
|
202
|
+
@report
|
203
|
+
end
|
204
|
+
EOS
|
205
|
+
ruby.should reek_only_of(:LongMethod)
|
92
206
|
end
|
93
207
|
end
|
94
208
|
|
@@ -104,26 +218,8 @@ describe FeatureEnvy, '#examine' do
|
|
104
218
|
@context.refs.record_ref([:lvar, :thing])
|
105
219
|
@fe.examine(@context, []).should == true
|
106
220
|
end
|
107
|
-
|
221
|
+
|
108
222
|
it 'should return false when not reporting a smell' do
|
109
223
|
@fe.examine(@context, []).should == false
|
110
224
|
end
|
111
225
|
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
|