ruby-watchr 0.0.1 → 0.1.0
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/lib/watchr/analysers/flog.rb +61 -0
- data/lib/watchr/file_analyse.rb +9 -25
- data/lib/watchr/smell.rb +9 -31
- data/lib/watchr/smell_types.rb +33 -0
- data/lib/watchr/version.rb +1 -1
- data/lib/watchr.rb +0 -3
- data/spec/watchr/analysers/flog_spec.rb +90 -0
- data/spec/watchr/file_analyse_spec.rb +3 -0
- data/spec/watchr/smell_spec.rb +7 -7
- metadata +7 -3
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'watchr/smell'
|
2
|
+
|
3
|
+
module Watchr
|
4
|
+
module Analysers
|
5
|
+
module Flog
|
6
|
+
include SmellTypes
|
7
|
+
|
8
|
+
VERY_COMPLEX_OBJECT_THRESHOLD = 100
|
9
|
+
|
10
|
+
COMPLEX_OBJECT_THRESHOLD = 50
|
11
|
+
|
12
|
+
VERY_COMPLEX_METHOD_THRESHOLD = 40
|
13
|
+
|
14
|
+
COMPLEX_METHOD_THRESHOLD = 20
|
15
|
+
|
16
|
+
def analyse_flog(report)
|
17
|
+
report.classes.each do |klass|
|
18
|
+
analyse_class_complexity(klass)
|
19
|
+
|
20
|
+
klass.methods.each do |method|
|
21
|
+
analyse_method_complexity(method)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def analyse_class_complexity(klass)
|
29
|
+
analyse_complexity(klass, :object)
|
30
|
+
end
|
31
|
+
|
32
|
+
def analyse_method_complexity(method)
|
33
|
+
analyse_complexity(method, :method)
|
34
|
+
end
|
35
|
+
|
36
|
+
def analyse_complexity(target, type)
|
37
|
+
add_smell(
|
38
|
+
Watchr::Smell.new(
|
39
|
+
get_smell_level?(target, type),
|
40
|
+
target.name, '', target.location, {:score => target.total_score}
|
41
|
+
)
|
42
|
+
) if target.total_score >= get_threshold(:complex, type.upcase)
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_smell_level?(target, type)
|
46
|
+
threshold = get_threshold(:very_complex, type)
|
47
|
+
complexity = target.total_score >= threshold ? :very_complex : :complex
|
48
|
+
|
49
|
+
get_smell_type(complexity, type.upcase)
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_threshold(complexity, type)
|
53
|
+
Watchr::Analysers::Flog.const_get("#{complexity.upcase}_#{type.upcase}_THRESHOLD")
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_smell_type(complexity, type)
|
57
|
+
Watchr::SmellTypes.const_get("#{complexity.upcase}_#{type.upcase}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/watchr/file_analyse.rb
CHANGED
@@ -2,6 +2,8 @@ require 'watchr/flog_metric/report'
|
|
2
2
|
require 'watchr/smell'
|
3
3
|
require 'watchr/smells_collector'
|
4
4
|
|
5
|
+
require 'watchr/analysers/flog'
|
6
|
+
|
5
7
|
module Watchr
|
6
8
|
#
|
7
9
|
# Analyse for one given file. All the different metric analyse data are
|
@@ -9,6 +11,7 @@ module Watchr
|
|
9
11
|
# improvements.
|
10
12
|
#
|
11
13
|
class FileAnalyse
|
14
|
+
include Analysers::Flog
|
12
15
|
|
13
16
|
attr_reader :path
|
14
17
|
|
@@ -21,30 +24,7 @@ module Watchr
|
|
21
24
|
@path = path
|
22
25
|
@smells = SmellsCollector.new
|
23
26
|
|
24
|
-
|
25
|
-
flog_metric.classes.each do |klass|
|
26
|
-
if klass.total_score > 150
|
27
|
-
@smells.add(
|
28
|
-
Smell.new(
|
29
|
-
Smell::VERY_COMPLEX_OBJECT,
|
30
|
-
klass.name,
|
31
|
-
[klass.location],
|
32
|
-
klass.total_score
|
33
|
-
)
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
if klass.total_score > 50
|
38
|
-
@smells.add(
|
39
|
-
Smell.new(
|
40
|
-
Smell::COMPLEX_OBJECT,
|
41
|
-
klass.name,
|
42
|
-
[klass.location],
|
43
|
-
klass.total_score
|
44
|
-
)
|
45
|
-
)
|
46
|
-
end
|
47
|
-
end
|
27
|
+
analyse_flog(FlogMetric::Report.new([path]))
|
48
28
|
end
|
49
29
|
|
50
30
|
def smelly?
|
@@ -55,7 +35,7 @@ module Watchr
|
|
55
35
|
# Store the flay report, which was evaluated on global basis
|
56
36
|
# to check for duplications across multiple files.
|
57
37
|
#
|
58
|
-
# @param {Array
|
38
|
+
# @param {Array<Watchr::FlayMetric::Diff>} Duplication details.
|
59
39
|
# @return nil
|
60
40
|
#
|
61
41
|
def flay(report)
|
@@ -65,5 +45,9 @@ module Watchr
|
|
65
45
|
def smells
|
66
46
|
@smells.all
|
67
47
|
end
|
48
|
+
|
49
|
+
def add_smell(smell)
|
50
|
+
@smells.add(smell)
|
51
|
+
end
|
68
52
|
end
|
69
53
|
end
|
data/lib/watchr/smell.rb
CHANGED
@@ -1,41 +1,15 @@
|
|
1
|
+
require 'watchr/smell_types'
|
2
|
+
|
1
3
|
module Watchr
|
2
4
|
class Smell
|
5
|
+
include SmellTypes
|
3
6
|
|
4
|
-
|
5
|
-
# Method complexity is high.
|
6
|
-
#
|
7
|
-
COMPLEX_METHOD = :complex_method
|
8
|
-
|
9
|
-
#
|
10
|
-
# Method complexity is very high.
|
11
|
-
#
|
12
|
-
VERY_COMPLEX_METHOD = :very_complex_method
|
13
|
-
|
14
|
-
#
|
15
|
-
# Object (class / module) total complexity is high.
|
16
|
-
#
|
17
|
-
COMPLEX_OBJECT = :complex_object
|
18
|
-
|
19
|
-
#
|
20
|
-
# Object (class / module) total complexity is very high.
|
21
|
-
#
|
22
|
-
VERY_COMPLEX_OBJECT = :very_complex_object
|
23
|
-
|
24
|
-
#
|
25
|
-
# Code in multiple places is identical.
|
26
|
-
#
|
27
|
-
IDENTICAL_CODE = :identical_code
|
28
|
-
|
29
|
-
#
|
30
|
-
# Code in multiple places is similar (not identical).
|
31
|
-
#
|
32
|
-
SIMILAR_CODE = :similar_code
|
33
|
-
|
34
|
-
def initialize(type, context, description, locations)
|
7
|
+
def initialize(type, context, description, locations, options)
|
35
8
|
@type = type
|
36
9
|
@context = context
|
37
10
|
@description = description
|
38
11
|
@locations = []
|
12
|
+
@options = options
|
39
13
|
|
40
14
|
Array(locations).each {|l| add_location(l)}
|
41
15
|
end
|
@@ -56,6 +30,10 @@ module Watchr
|
|
56
30
|
@context
|
57
31
|
end
|
58
32
|
|
33
|
+
def options
|
34
|
+
@options
|
35
|
+
end
|
36
|
+
|
59
37
|
def add_location(location)
|
60
38
|
@locations << location
|
61
39
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Watchr
|
2
|
+
module SmellTypes
|
3
|
+
#
|
4
|
+
# Method complexity is high.
|
5
|
+
#
|
6
|
+
COMPLEX_METHOD = :complex_method
|
7
|
+
|
8
|
+
#
|
9
|
+
# Method complexity is very high.
|
10
|
+
#
|
11
|
+
VERY_COMPLEX_METHOD = :very_complex_method
|
12
|
+
|
13
|
+
#
|
14
|
+
# Object (class / module) total complexity is high.
|
15
|
+
#
|
16
|
+
COMPLEX_OBJECT = :complex_object
|
17
|
+
|
18
|
+
#
|
19
|
+
# Object (class / module) total complexity is very high.
|
20
|
+
#
|
21
|
+
VERY_COMPLEX_OBJECT = :very_complex_object
|
22
|
+
|
23
|
+
#
|
24
|
+
# Code in multiple places is identical.
|
25
|
+
#
|
26
|
+
IDENTICAL_CODE = :identical_code
|
27
|
+
|
28
|
+
#
|
29
|
+
# Code in multiple places is similar (not identical).
|
30
|
+
#
|
31
|
+
SIMILAR_CODE = :similar_code
|
32
|
+
end
|
33
|
+
end
|
data/lib/watchr/version.rb
CHANGED
data/lib/watchr.rb
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'watchr/analysers/flog'
|
3
|
+
|
4
|
+
describe Watchr::Analysers::Flog do
|
5
|
+
let(:analyse) {
|
6
|
+
analyse = stub('analyse', :add_smell => true)
|
7
|
+
analyse.extend Watchr::Analysers::Flog
|
8
|
+
|
9
|
+
analyse
|
10
|
+
}
|
11
|
+
|
12
|
+
let(:method) { stub('method',
|
13
|
+
:name => 'method',
|
14
|
+
:location => stub('location'),
|
15
|
+
:total_score => 10)
|
16
|
+
}
|
17
|
+
|
18
|
+
let(:complex_method) { stub('method',
|
19
|
+
:name => 'complex_method',
|
20
|
+
:location => stub('location'),
|
21
|
+
:total_score => 30)
|
22
|
+
}
|
23
|
+
|
24
|
+
let(:very_complex_method) { stub('method',
|
25
|
+
:name => 'very_complex_method',
|
26
|
+
:location => stub('location'),
|
27
|
+
:total_score => 100)
|
28
|
+
}
|
29
|
+
|
30
|
+
let(:clazz) { stub('class',
|
31
|
+
:name => 'Class',
|
32
|
+
:location => stub('location'),
|
33
|
+
:total_score => 100,
|
34
|
+
:methods => [method, complex_method, very_complex_method])
|
35
|
+
}
|
36
|
+
|
37
|
+
let(:classes) { [clazz] }
|
38
|
+
|
39
|
+
let(:report) { stub('report', :classes => classes) }
|
40
|
+
|
41
|
+
subject { analyse.analyse_flog(report) }
|
42
|
+
|
43
|
+
describe '#analyse_flog' do
|
44
|
+
let(:smell) { stub('smell') }
|
45
|
+
|
46
|
+
before { Watchr::Smell.stubs(:new).returns(smell) }
|
47
|
+
|
48
|
+
it 'should add smell for complex method' do
|
49
|
+
Watchr::Smell.expects(:new).with(
|
50
|
+
Watchr::Smell::COMPLEX_METHOD,
|
51
|
+
complex_method.name,
|
52
|
+
'',
|
53
|
+
complex_method.location,
|
54
|
+
{ :score => complex_method.total_score }
|
55
|
+
)
|
56
|
+
|
57
|
+
analyse.expects(:add_smell).returns(smell)
|
58
|
+
|
59
|
+
subject
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should add smell for very complex method' do
|
63
|
+
Watchr::Smell.expects(:new).with(
|
64
|
+
Watchr::Smell::VERY_COMPLEX_METHOD,
|
65
|
+
very_complex_method.name,
|
66
|
+
'',
|
67
|
+
very_complex_method.location,
|
68
|
+
{ :score => very_complex_method.total_score }
|
69
|
+
)
|
70
|
+
|
71
|
+
analyse.expects(:add_smell).returns(smell)
|
72
|
+
|
73
|
+
subject
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should add smell for very complex object' do
|
77
|
+
Watchr::Smell.expects(:new).with(
|
78
|
+
Watchr::Smell::VERY_COMPLEX_OBJECT,
|
79
|
+
clazz.name,
|
80
|
+
'',
|
81
|
+
clazz.location,
|
82
|
+
{ :score => clazz.total_score }
|
83
|
+
)
|
84
|
+
|
85
|
+
analyse.expects(:add_smell).returns(smell)
|
86
|
+
|
87
|
+
subject
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -2,6 +2,9 @@ require 'spec_helper'
|
|
2
2
|
require 'watchr/file_analyse'
|
3
3
|
|
4
4
|
describe Watchr::FileAnalyse do
|
5
|
+
|
6
|
+
it { Watchr::FileAnalyse.ancestors.should include(Watchr::Analysers::Flog) }
|
7
|
+
|
5
8
|
let(:path) { 'spec/fixtures/class.rb' }
|
6
9
|
|
7
10
|
let(:file_analyse) { Watchr::FileAnalyse.new(path) }
|
data/spec/watchr/smell_spec.rb
CHANGED
@@ -13,7 +13,9 @@ describe Watchr::Smell do
|
|
13
13
|
|
14
14
|
let(:context) { 'context' }
|
15
15
|
|
16
|
-
let(:
|
16
|
+
let(:options) { stub('options') }
|
17
|
+
|
18
|
+
let(:smell) { Watchr::Smell.new(type, context, description, locations, options) }
|
17
19
|
|
18
20
|
subject { smell }
|
19
21
|
|
@@ -35,11 +37,9 @@ describe Watchr::Smell do
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
|
-
|
39
|
-
its(:description) { should == description }
|
40
|
-
end
|
40
|
+
its(:description) { should == description }
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
its(:options) { should == options }
|
43
|
+
|
44
|
+
its(:context) { should == context }
|
45
45
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 0
|
8
7
|
- 1
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Petr Janda
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-07-
|
17
|
+
date: 2012-07-06 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- Rakefile
|
74
74
|
- lib/watchr.rb
|
75
75
|
- lib/watchr/analyse.rb
|
76
|
+
- lib/watchr/analysers/flog.rb
|
76
77
|
- lib/watchr/file_analyse.rb
|
77
78
|
- lib/watchr/flay_metric/diff.rb
|
78
79
|
- lib/watchr/flay_metric/report.rb
|
@@ -82,12 +83,14 @@ files:
|
|
82
83
|
- lib/watchr/location.rb
|
83
84
|
- lib/watchr/paths.rb
|
84
85
|
- lib/watchr/smell.rb
|
86
|
+
- lib/watchr/smell_types.rb
|
85
87
|
- lib/watchr/smells_collector.rb
|
86
88
|
- lib/watchr/version.rb
|
87
89
|
- spec/fixtures/class.rb
|
88
90
|
- spec/fixtures/module.rb
|
89
91
|
- spec/spec_helper.rb
|
90
92
|
- spec/watchr/analyse_spec.rb
|
93
|
+
- spec/watchr/analysers/flog_spec.rb
|
91
94
|
- spec/watchr/file_analyse_spec.rb
|
92
95
|
- spec/watchr/flay/report_spec.rb
|
93
96
|
- spec/watchr/flog_metric/flog_matric/flog_report_spec.rb
|
@@ -133,6 +136,7 @@ test_files:
|
|
133
136
|
- spec/fixtures/module.rb
|
134
137
|
- spec/spec_helper.rb
|
135
138
|
- spec/watchr/analyse_spec.rb
|
139
|
+
- spec/watchr/analysers/flog_spec.rb
|
136
140
|
- spec/watchr/file_analyse_spec.rb
|
137
141
|
- spec/watchr/flay/report_spec.rb
|
138
142
|
- spec/watchr/flog_metric/flog_matric/flog_report_spec.rb
|