reek 1.2.7.1 → 1.2.7.2
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 +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
|