guideline 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/bin/guideline CHANGED
@@ -8,6 +8,7 @@ options = Runner.parse(ARGV)
8
8
 
9
9
  checkers = CheckerFactory.new(
10
10
  options[:config],
11
+ AbcComplexityChecker,
11
12
  UnusedMethodChecker,
12
13
  HashCommaChecker,
13
14
  LongLineChecker,
data/guideline.yml CHANGED
@@ -2,3 +2,5 @@
2
2
  max: 80
3
3
  "Guideline::LongMethodChecker":
4
4
  max: 10
5
+ "Guideline::AbcComplexityChecker":
6
+ max: 10
@@ -0,0 +1,151 @@
1
+ require "ripper"
2
+
3
+ module Guideline
4
+ class AbcComplexityChecker < Checker
5
+ def check(path)
6
+ @current_path = path
7
+ visitor.check(path.to_s, path.read)
8
+ @current_path = nil
9
+ end
10
+
11
+ private
12
+
13
+ def checker
14
+ AbcParser.new do |complexity, method, module_name, class_method_flag|
15
+ if complexity > max
16
+ report(
17
+ :path => @current_path,
18
+ :line => method.line,
19
+ :message => "ABC Complexity of method<%s%s%s>%3d should be less than %d" % [
20
+ module_name,
21
+ class_method_flag ? "." : "#",
22
+ method.method_name,
23
+ complexity,
24
+ max,
25
+ ]
26
+ )
27
+ end
28
+ end
29
+ end
30
+
31
+ def visitor
32
+ CodeAnalyzer::CheckingVisitor::Default.new(checkers: [checker])
33
+ end
34
+
35
+ def max
36
+ @options[:max]
37
+ end
38
+
39
+ module Moduleable
40
+ def self.included(base)
41
+ base.class_eval do
42
+ interesting_nodes :class, :module
43
+
44
+ add_callback :start_class do |node|
45
+ modules << node.class_name.to_s
46
+ end
47
+
48
+ add_callback :start_module do |node|
49
+ modules << node.module_name.to_s
50
+ end
51
+
52
+ add_callback :end_class do |node|
53
+ modules.pop
54
+ end
55
+
56
+ add_callback :end_module do |node|
57
+ modules.pop
58
+ end
59
+ end
60
+ end
61
+
62
+ def current_module_name
63
+ modules.join("::")
64
+ end
65
+
66
+ def modules
67
+ @moduels ||= []
68
+ end
69
+ end
70
+
71
+ class AbcParser < CodeAnalyzer::Checker
72
+ ASSIGNMENT_NODES = [:assign, :opassign]
73
+ BRANCH_NODES = [:call, :fcall, :vcall, :zsuper, :yield0, :brace_block, :do_block]
74
+ CONDITION_NODES = [:else]
75
+ CONDITION_TOKENS = [:==, :===, :"<>", :<=, :>=, :=~, :>, :<, :<=>]
76
+ ALL_NODES = ASSIGNMENT_NODES + BRANCH_NODES + CONDITION_NODES
77
+
78
+ include Moduleable
79
+
80
+ attr_reader :assignment, :branch, :condition
81
+
82
+ interesting_files /.*\.rb/
83
+ interesting_nodes :def, :defs, :binary, :zsuper, *ALL_NODES
84
+
85
+ ASSIGNMENT_NODES.each do |name|
86
+ add_callback :"start_#{name}" do |node|
87
+ @assignment += 1
88
+ end
89
+ end
90
+
91
+ BRANCH_NODES.each do |name|
92
+ add_callback :"start_#{name}" do |node|
93
+ @branch += 1
94
+ end
95
+ end
96
+
97
+ CONDITION_NODES.each do |name|
98
+ add_callback :"start_#{name}" do |node|
99
+ @condition += 1
100
+ end
101
+ end
102
+
103
+ add_callback :start_def do |node|
104
+ @current_method = node
105
+ clear
106
+ end
107
+
108
+ add_callback :start_defs do |node|
109
+ @current_method = node
110
+ clear
111
+ end
112
+
113
+ add_callback :end_def do |node|
114
+ @callback.call(complexity, @current_method, current_module_name, false)
115
+ @current_method = nil
116
+ end
117
+
118
+ add_callback :end_defs do |node|
119
+ @callback.call(complexity, @current_method, current_module_name, true)
120
+ @current_method = nil
121
+ end
122
+
123
+ add_callback :start_binary do |node|
124
+ @condition += 1 if condition_table[node[2]]
125
+ end
126
+
127
+ def initialize(*, &callback)
128
+ clear
129
+ @callback = callback
130
+ super
131
+ end
132
+
133
+ def clear
134
+ @assignment = 0
135
+ @branch = 0
136
+ @condition = 0
137
+ end
138
+
139
+ def complexity
140
+ Math.sqrt(@assignment ** 2 + @branch ** 2 + @condition ** 2)
141
+ end
142
+
143
+ def condition_table
144
+ @condition_table ||= CONDITION_TOKENS.inject({}) do |hash, token|
145
+ hash[token] = true
146
+ hash
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -1,3 +1,3 @@
1
1
  module Guideline
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
data/lib/guideline.rb CHANGED
@@ -9,3 +9,4 @@ require "guideline/checkers/long_method_checker"
9
9
  require "guideline/checkers/hard_tab_indent_checker"
10
10
  require "guideline/checkers/hash_comma_checker"
11
11
  require "guideline/checkers/unused_method_checker"
12
+ require "guideline/checkers/abc_complexity_checker"
@@ -0,0 +1,171 @@
1
+ require "spec_helper"
2
+
3
+ module Guideline
4
+ describe AbcComplexityChecker do
5
+ describe "#check" do
6
+ subject do
7
+ checker.check(path)
8
+ checker
9
+ end
10
+
11
+ let(:checker) do
12
+ described_class.new(:max => 1.4)
13
+ end
14
+
15
+ let(:path) do
16
+ mock(:read => script, :to_s => "mock.rb")
17
+ end
18
+
19
+ context "when there is a few assignment" do
20
+ let(:script) do
21
+ <<-EOF
22
+ def a
23
+ b = 1
24
+ end
25
+ EOF
26
+ end
27
+ it { should_not have_error }
28
+ end
29
+
30
+ context "when there is too much assign" do
31
+ let(:script) do
32
+ <<-EOF
33
+ def a
34
+ b = 1
35
+ c = 2
36
+ end
37
+ EOF
38
+ end
39
+ it { should have_error }
40
+ end
41
+
42
+ context "when there is too much opassign" do
43
+ let(:script) do
44
+ <<-EOF
45
+ def a
46
+ b += 1
47
+ c += 1
48
+ end
49
+ EOF
50
+ end
51
+ it { should have_error }
52
+ end
53
+
54
+ context "when there is too much else statement" do
55
+ let(:script) do
56
+ <<-EOF
57
+ def a
58
+ if b
59
+ 1
60
+ else
61
+ 2
62
+ end
63
+
64
+ if c
65
+ 3
66
+ else
67
+ 4
68
+ end
69
+ end
70
+ EOF
71
+ end
72
+ it { should have_error }
73
+ end
74
+
75
+ context "when there is too much comparison operator" do
76
+ let(:script) do
77
+ <<-EOF
78
+ def a
79
+ b == 1
80
+ c == 2
81
+ end
82
+ EOF
83
+ end
84
+ it { should have_error }
85
+ end
86
+
87
+ context "when there is too much fcall" do
88
+ let(:script) do
89
+ <<-EOF
90
+ def a
91
+ b()
92
+ c()
93
+ end
94
+ EOF
95
+ end
96
+ it { should have_error }
97
+ end
98
+
99
+ context "when there is too much vcall" do
100
+ let(:script) do
101
+ <<-EOF
102
+ def a
103
+ b
104
+ c
105
+ end
106
+ EOF
107
+ end
108
+ it { should have_error }
109
+ end
110
+
111
+ context "when there is too much call and vcall" do
112
+ let(:script) do
113
+ <<-EOF
114
+ def a
115
+ b.c
116
+ end
117
+ EOF
118
+ end
119
+ it { should have_error }
120
+ end
121
+
122
+ context "when there is too much vcall and do_block" do
123
+ let(:script) do
124
+ <<-EOF
125
+ def a
126
+ a do
127
+ 1
128
+ end
129
+ end
130
+ EOF
131
+ end
132
+ it { should have_error }
133
+ end
134
+
135
+ context "when there is too much vcall and brace_block" do
136
+ let(:script) do
137
+ <<-EOF
138
+ def a
139
+ a { 1 }
140
+ end
141
+ EOF
142
+ end
143
+ it { should have_error }
144
+ end
145
+
146
+ context "when there is too much yield" do
147
+ let(:script) do
148
+ <<-EOF
149
+ def a
150
+ yield
151
+ yield
152
+ end
153
+ EOF
154
+ end
155
+ it { should have_error }
156
+ end
157
+
158
+ context "when there is too much super" do
159
+ let(:script) do
160
+ <<-EOF
161
+ def a
162
+ super
163
+ super
164
+ end
165
+ EOF
166
+ end
167
+ it { should have_error }
168
+ end
169
+ end
170
+ end
171
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guideline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-29 00:00:00.000000000 Z
12
+ date: 2012-11-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: slop
@@ -125,6 +125,7 @@ files:
125
125
  - guideline.yml
126
126
  - lib/guideline.rb
127
127
  - lib/guideline/checker_factory.rb
128
+ - lib/guideline/checkers/abc_complexity_checker.rb
128
129
  - lib/guideline/checkers/checker.rb
129
130
  - lib/guideline/checkers/hard_tab_indent_checker.rb
130
131
  - lib/guideline/checkers/hash_comma_checker.rb
@@ -136,6 +137,7 @@ files:
136
137
  - lib/guideline/version.rb
137
138
  - lib/guideline/visitor.rb
138
139
  - spec/guideline/checker_factory_spec.rb
140
+ - spec/guideline/checkers/abc_complexity_checker_spec.rb
139
141
  - spec/guideline/checkers/checker_spec.rb
140
142
  - spec/guideline/checkers/hard_tab_indent_checker_spec.rb
141
143
  - spec/guideline/checkers/hash_comma_checker_spec.rb
@@ -172,6 +174,7 @@ specification_version: 3
172
174
  summary: The guideline of your code
173
175
  test_files:
174
176
  - spec/guideline/checker_factory_spec.rb
177
+ - spec/guideline/checkers/abc_complexity_checker_spec.rb
175
178
  - spec/guideline/checkers/checker_spec.rb
176
179
  - spec/guideline/checkers/hard_tab_indent_checker_spec.rb
177
180
  - spec/guideline/checkers/hash_comma_checker_spec.rb