reek 1.2.7.1 → 1.2.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +13 -1
- data/config/defaults.reek +4 -1
- data/features/masking_smells.feature +7 -7
- data/features/rake_task.feature +2 -2
- data/features/reports.feature +3 -3
- data/features/samples.feature +5 -2
- data/features/yaml.feature +0 -39
- data/lib/reek.rb +1 -1
- data/lib/reek/cli/command_line.rb +3 -3
- data/lib/reek/cli/reek_command.rb +5 -6
- data/lib/reek/cli/report.rb +9 -20
- data/lib/reek/cli/yaml_command.rb +1 -1
- data/lib/reek/core/class_context.rb +1 -2
- data/lib/reek/core/code_context.rb +10 -27
- data/lib/reek/core/code_parser.rb +1 -18
- data/lib/reek/core/detector_stack.rb +4 -0
- data/lib/reek/core/masking_collection.rb +6 -0
- data/lib/reek/core/method_context.rb +8 -56
- data/lib/reek/core/module_context.rb +6 -32
- data/lib/reek/core/object_refs.rb +36 -36
- data/lib/reek/core/singleton_method_context.rb +10 -21
- data/lib/reek/core/sniffer.rb +3 -2
- data/lib/reek/examiner.rb +39 -31
- data/lib/reek/smell_warning.rb +8 -0
- data/lib/reek/smells/attribute.rb +4 -2
- data/lib/reek/smells/class_variable.rb +3 -3
- data/lib/reek/smells/control_couple.rb +1 -2
- data/lib/reek/smells/data_clump.rb +86 -9
- data/lib/reek/smells/duplication.rb +2 -3
- data/lib/reek/smells/feature_envy.rb +9 -4
- data/lib/reek/smells/simulated_polymorphism.rb +1 -2
- data/lib/reek/smells/smell_detector.rb +0 -6
- data/lib/reek/smells/uncommunicative_method_name.rb +8 -2
- data/lib/reek/smells/uncommunicative_parameter_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_variable_name.rb +1 -1
- data/lib/reek/smells/utility_function.rb +17 -5
- data/lib/reek/source/reference_collector.rb +21 -0
- data/lib/reek/source/sexp_formatter.rb +1 -0
- data/lib/reek/source/tree_dresser.rb +67 -9
- data/lib/reek/spec/should_reek.rb +1 -1
- data/lib/reek/spec/should_reek_of.rb +1 -1
- data/lib/reek/spec/should_reek_only_of.rb +1 -1
- data/reek.gemspec +3 -3
- data/spec/reek/cli/reek_command_spec.rb +3 -2
- data/spec/reek/cli/report_spec.rb +2 -2
- data/spec/reek/cli/yaml_command_spec.rb +2 -2
- data/spec/reek/core/code_context_spec.rb +39 -54
- data/spec/reek/core/method_context_spec.rb +7 -26
- data/spec/reek/core/module_context_spec.rb +0 -15
- data/spec/reek/core/singleton_method_context_spec.rb +0 -6
- data/spec/reek/examiner_spec.rb +6 -6
- data/spec/reek/smells/attribute_spec.rb +30 -32
- data/spec/reek/smells/class_variable_spec.rb +15 -18
- data/spec/reek/smells/data_clump_spec.rb +22 -6
- data/spec/reek/smells/duplication_spec.rb +33 -19
- data/spec/reek/smells/feature_envy_spec.rb +82 -88
- data/spec/reek/smells/large_class_spec.rb +1 -1
- data/spec/reek/smells/smell_detector_shared.rb +1 -1
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +37 -35
- data/spec/reek/smells/utility_function_spec.rb +7 -0
- data/spec/reek/source/reference_collector_spec.rb +53 -0
- data/spec/reek/source/tree_dresser_spec.rb +10 -0
- data/spec/reek/spec/should_reek_only_of_spec.rb +1 -1
- data/spec/spec_helper.rb +7 -0
- metadata +4 -5
- data/features/profile.feature +0 -34
- data/lib/reek/core/block_context.rb +0 -18
- data/spec/reek/core/block_context_spec.rb +0 -26
@@ -21,7 +21,7 @@ shared_examples_for 'SmellDetector' do
|
|
21
21
|
|
22
22
|
context 'configuration' do
|
23
23
|
it 'becomes disabled when disabled' do
|
24
|
-
@detector.
|
24
|
+
@detector.configure_with({SmellConfiguration::ENABLED_KEY => false})
|
25
25
|
@detector.should_not be_enabled
|
26
26
|
end
|
27
27
|
end
|
@@ -15,43 +15,45 @@ describe UncommunicativeMethodName do
|
|
15
15
|
|
16
16
|
it_should_behave_like 'SmellDetector'
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
'def x(fred) basics(17) end'.should reek_only_of(:UncommunicativeMethodName, /x/)
|
23
|
-
end
|
24
|
-
it 'should report name of the form "x2"' do
|
25
|
-
'def x2(fred) basics(17) end'.should reek_only_of(:UncommunicativeMethodName, /x2/)
|
26
|
-
end
|
27
|
-
it 'should report long name ending in a number' do
|
28
|
-
'def method2(fred) basics(17) end'.should reek_only_of(:UncommunicativeMethodName, /method2/)
|
18
|
+
['help', '+', '-', '/', '*'].each do |method_name|
|
19
|
+
it "accepts the method name '#{method_name}'" do
|
20
|
+
"def #{method_name}(fred) basics(17) end".should_not reek
|
21
|
+
end
|
29
22
|
end
|
30
23
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
24
|
+
['x', 'x2', 'method2'].each do |method_name|
|
25
|
+
context 'with a bad name' do
|
26
|
+
before :each do
|
27
|
+
@full_name = 'anything you like'
|
28
|
+
ctx = mock('method', :null_object => true)
|
29
|
+
ctx.should_receive(:name).and_return(method_name)
|
30
|
+
ctx.should_receive(:full_name).at_least(:once).and_return(@full_name)
|
31
|
+
ctx.should_receive(:exp).and_return(ast(:defn))
|
32
|
+
@detector.examine_context(ctx)
|
33
|
+
@smells = @detector.smells_found.to_a
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'records only that attribute' do
|
37
|
+
@smells.length.should == 1
|
38
|
+
end
|
39
|
+
it 'reports the attribute name' do
|
40
|
+
@smells[0].smell[UncommunicativeMethodName::METHOD_NAME_KEY].should == method_name
|
41
|
+
end
|
42
|
+
it 'reports the declaration line number' do
|
43
|
+
@smells[0].lines.should == [1]
|
44
|
+
end
|
45
|
+
it 'reports the correct smell class' do
|
46
|
+
@smells[0].smell_class.should == UncommunicativeMethodName::SMELL_CLASS
|
47
|
+
end
|
48
|
+
it 'reports the correct smell subclass' do
|
49
|
+
@smells[0].subclass.should == UncommunicativeMethodName::SMELL_SUBCLASS
|
50
|
+
end
|
51
|
+
it 'reports the context fq name' do
|
52
|
+
@smells[0].context.should == @full_name
|
53
|
+
end
|
54
|
+
it 'reports the source name' do
|
55
|
+
@smells[0].source.should == @source_name
|
56
|
+
end
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
@@ -6,6 +6,13 @@ include Reek
|
|
6
6
|
include Reek::Smells
|
7
7
|
|
8
8
|
describe UtilityFunction do
|
9
|
+
context 'with a singleton method' do
|
10
|
+
['self', 'local_call', '$global'].each do |receiver|
|
11
|
+
it 'ignores the receiver' do
|
12
|
+
"def #{receiver}.simple(arga) arga.to_s + arga.to_i end".should_not reek
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
9
16
|
context 'with no calls' do
|
10
17
|
it 'does not report empty method' do
|
11
18
|
'def simple(arga) end'.should_not reek
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'spec_helper')
|
2
|
+
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'source', 'reference_collector')
|
3
|
+
|
4
|
+
include Reek::Source
|
5
|
+
|
6
|
+
describe ReferenceCollector do
|
7
|
+
|
8
|
+
context 'counting refs to self' do
|
9
|
+
def refs_to_self(src)
|
10
|
+
ReferenceCollector.new(src.to_reek_source.syntax_tree).num_refs_to_self
|
11
|
+
end
|
12
|
+
it 'with no refs to self' do
|
13
|
+
refs_to_self('def no_envy(arga) arga.barg end').should == 0
|
14
|
+
end
|
15
|
+
it 'counts a call to super' do
|
16
|
+
refs_to_self('def simple() super; end').should == 1
|
17
|
+
end
|
18
|
+
it 'counts a local call' do
|
19
|
+
refs_to_self('def simple() to_s; end').should == 1
|
20
|
+
end
|
21
|
+
it 'counts a use of self' do
|
22
|
+
refs_to_self('def simple() lv = self; end').should == 1
|
23
|
+
end
|
24
|
+
it 'counts a call with self as receiver' do
|
25
|
+
refs_to_self('def simple() self.to_s; end').should == 1
|
26
|
+
end
|
27
|
+
it 'counts uses of an ivar' do
|
28
|
+
refs_to_self('def no_envy() @item.to_a; @item = 4; @item end').should == 3
|
29
|
+
end
|
30
|
+
it 'counts an ivar passed to a method' do
|
31
|
+
refs_to_self('def no_envy(arga) arga.barg(@item); arga end').should == 1
|
32
|
+
end
|
33
|
+
it 'ignores global variables' do
|
34
|
+
refs_to_self('def no_envy(arga) $s2.to_a; $s2[arga] end').should == 0
|
35
|
+
end
|
36
|
+
it 'ignores global variables' do
|
37
|
+
src = <<EOS
|
38
|
+
def accept(t, pat = /.*/nm, &block)
|
39
|
+
if pat
|
40
|
+
pat.respond_to?(:match) or raise TypeError, "has no `match'"
|
41
|
+
else
|
42
|
+
pat = t if t.respond_to?(:match)
|
43
|
+
end
|
44
|
+
unless block
|
45
|
+
block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
|
46
|
+
end
|
47
|
+
@atype[t] = [pat, block]
|
48
|
+
end
|
49
|
+
EOS
|
50
|
+
refs_to_self(src).should == 2
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -15,6 +15,16 @@ describe TreeDresser do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
describe SexpNode do
|
19
|
+
context 'format' do
|
20
|
+
it 'formats self' do
|
21
|
+
@node = s(:self)
|
22
|
+
@node.extend(SexpNode)
|
23
|
+
@node.format.should == 'self'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
18
28
|
describe SexpExtensions::DefnNode do
|
19
29
|
context 'with no parameters' do
|
20
30
|
before :each do
|
@@ -10,7 +10,7 @@ describe ShouldReekOnlyOf do
|
|
10
10
|
@expected_context_name = 'SmellyClass#big_method'
|
11
11
|
@matcher = ShouldReekOnlyOf.new(@expected_smell_class, [/#{@expected_context_name}/])
|
12
12
|
@examiner = mock('examiner', :null_object => true)
|
13
|
-
@examiner.should_receive(:
|
13
|
+
@examiner.should_receive(:smells).and_return {smells}
|
14
14
|
@match = @matcher.matches_examiner?(@examiner)
|
15
15
|
end
|
16
16
|
|
data/spec/spec_helper.rb
CHANGED
@@ -10,5 +10,12 @@ end
|
|
10
10
|
require 'spec/autorun'
|
11
11
|
|
12
12
|
require File.join((File.dirname(File.dirname(File.expand_path(__FILE__)))), 'lib', 'reek', 'spec')
|
13
|
+
require File.join((File.dirname(File.dirname(File.expand_path(__FILE__)))), 'lib', 'reek', 'source', 'tree_dresser')
|
13
14
|
|
14
15
|
SAMPLES_DIR = 'spec/samples' unless Object.const_defined?('SAMPLES_DIR')
|
16
|
+
|
17
|
+
def ast(*args)
|
18
|
+
result = Reek::Source::TreeDresser.new.dress(s(*args))
|
19
|
+
result.line = 1
|
20
|
+
result
|
21
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reek
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.7.
|
4
|
+
version: 1.2.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Rutherford
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-05 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -65,7 +65,6 @@ files:
|
|
65
65
|
- config/defaults.reek
|
66
66
|
- features/masking_smells.feature
|
67
67
|
- features/options.feature
|
68
|
-
- features/profile.feature
|
69
68
|
- features/rake_task.feature
|
70
69
|
- features/reports.feature
|
71
70
|
- features/samples.feature
|
@@ -81,7 +80,6 @@ files:
|
|
81
80
|
- lib/reek/cli/report.rb
|
82
81
|
- lib/reek/cli/version_command.rb
|
83
82
|
- lib/reek/cli/yaml_command.rb
|
84
|
-
- lib/reek/core/block_context.rb
|
85
83
|
- lib/reek/core/class_context.rb
|
86
84
|
- lib/reek/core/code_context.rb
|
87
85
|
- lib/reek/core/code_parser.rb
|
@@ -122,6 +120,7 @@ files:
|
|
122
120
|
- lib/reek/source/code_comment.rb
|
123
121
|
- lib/reek/source/config_file.rb
|
124
122
|
- lib/reek/source/core_extras.rb
|
123
|
+
- lib/reek/source/reference_collector.rb
|
125
124
|
- lib/reek/source/sexp_formatter.rb
|
126
125
|
- lib/reek/source/source_code.rb
|
127
126
|
- lib/reek/source/source_file.rb
|
@@ -137,7 +136,6 @@ files:
|
|
137
136
|
- spec/reek/cli/report_spec.rb
|
138
137
|
- spec/reek/cli/version_command_spec.rb
|
139
138
|
- spec/reek/cli/yaml_command_spec.rb
|
140
|
-
- spec/reek/core/block_context_spec.rb
|
141
139
|
- spec/reek/core/class_context_spec.rb
|
142
140
|
- spec/reek/core/code_context_spec.rb
|
143
141
|
- spec/reek/core/code_parser_spec.rb
|
@@ -174,6 +172,7 @@ files:
|
|
174
172
|
- spec/reek/smells/utility_function_spec.rb
|
175
173
|
- spec/reek/source/code_comment_spec.rb
|
176
174
|
- spec/reek/source/object_source_spec.rb
|
175
|
+
- spec/reek/source/reference_collector_spec.rb
|
177
176
|
- spec/reek/source/source_code_spec.rb
|
178
177
|
- spec/reek/source/tree_dresser_spec.rb
|
179
178
|
- spec/reek/spec/should_reek_of_spec.rb
|
data/features/profile.feature
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
@profile
|
2
|
-
Feature: Reek's configuration can be based on any number of canned profiles
|
3
|
-
The starting point for configuring the smell detectors can be
|
4
|
-
selected from a list of supplied config files.
|
5
|
-
|
6
|
-
# Scenario: XP profile reveals Attribute smells
|
7
|
-
# When I run reek --profile xp spec/samples/not_quite_masked/dirty.rb
|
8
|
-
# Then the exit status indicates smells
|
9
|
-
# And it reports:
|
10
|
-
# """
|
11
|
-
# spec/samples/not_quite_masked/dirty.rb -- 5 warnings (+2 masked):
|
12
|
-
# Dirty declares the attribute property (Attribute)
|
13
|
-
# Dirty has the variable name '@s' (Uncommunicative Name)
|
14
|
-
# Dirty#a calls @s.title twice (Duplication)
|
15
|
-
# Dirty#a calls puts(@s.title) twice (Duplication)
|
16
|
-
# Dirty#a has the name 'a' (Uncommunicative Name)
|
17
|
-
#
|
18
|
-
# """
|
19
|
-
#
|
20
|
-
# Scenario: XP profile works with unmasked smells
|
21
|
-
# When I run reek --show-all --profile xp spec/samples/not_quite_masked/dirty.rb
|
22
|
-
# Then the exit status indicates smells
|
23
|
-
# And it reports:
|
24
|
-
# """
|
25
|
-
# spec/samples/not_quite_masked/dirty.rb -- 5 warnings (+2 masked):
|
26
|
-
# Dirty declares the attribute property (Attribute)
|
27
|
-
# Dirty has the variable name '@s' (Uncommunicative Name)
|
28
|
-
# Dirty#a calls @s.title twice (Duplication)
|
29
|
-
# Dirty#a calls puts(@s.title) twice (Duplication)
|
30
|
-
# Dirty#a has the name 'a' (Uncommunicative Name)
|
31
|
-
# (masked) Dirty#a/block has the variable name 'x' (Uncommunicative Name)
|
32
|
-
# (masked) Dirty#a/block/block is nested (Nested Iterators)
|
33
|
-
#
|
34
|
-
# """
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(File.expand_path(__FILE__)), 'code_context')
|
2
|
-
|
3
|
-
module Reek
|
4
|
-
module Core
|
5
|
-
|
6
|
-
#
|
7
|
-
# A context wrapper for any block found in a syntax tree.
|
8
|
-
#
|
9
|
-
class BlockContext < CodeContext
|
10
|
-
|
11
|
-
def initialize(outer, exp)
|
12
|
-
super
|
13
|
-
@name = 'block'
|
14
|
-
@scope_connector = '/'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'spec_helper')
|
2
|
-
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'block_context')
|
3
|
-
require File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'lib', 'reek', 'core', 'method_context')
|
4
|
-
|
5
|
-
include Reek::Core
|
6
|
-
|
7
|
-
describe BlockContext do
|
8
|
-
context 'full_name' do
|
9
|
-
it "reports full context" do
|
10
|
-
bctx = BlockContext.new(StopContext.new, s(nil, nil))
|
11
|
-
bctx.full_name.should == 'block'
|
12
|
-
end
|
13
|
-
it 'uses / to connect to the class name' do
|
14
|
-
element = StopContext.new
|
15
|
-
element = ClassContext.new(element, :Fred, s(:class, :Fred))
|
16
|
-
element = BlockContext.new(element, s(:iter, nil, s(:lasgn, :x), nil))
|
17
|
-
element.full_name.should == 'Fred/block'
|
18
|
-
end
|
19
|
-
it 'uses / to connect to the module name' do
|
20
|
-
element = StopContext.new
|
21
|
-
element = ModuleContext.new(element, :Fred, s(:module, :Fred))
|
22
|
-
element = BlockContext.new(element, s(:iter, nil, s(:lasgn, :x), nil))
|
23
|
-
element.full_name.should == 'Fred/block'
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|