roodi 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/Manifest.txt +15 -7
- data/README.txt +2 -0
- data/lib/roodi.rb +1 -1
- data/lib/roodi/checks.rb +5 -1
- data/lib/roodi/checks/class_line_count_check.rb +30 -0
- data/lib/roodi/checks/module_line_count_check.rb +30 -0
- data/lib/roodi/checks/module_name_check.rb +17 -0
- data/lib/roodi/checks/parameter_number_check.rb +23 -0
- data/lib/roodi/core/parse_tree_runner.rb +11 -7
- data/roodi.yml +6 -2
- data/spec/roodi/checks/class_line_count_check_spec.rb +39 -0
- data/spec/{checks → roodi/checks}/class_name_check_spec.rb +1 -1
- data/spec/{checks → roodi/checks}/cyclomatic_complexity_block_check_spec.rb +1 -1
- data/spec/{checks → roodi/checks}/cyclomatic_complexity_method_check_spec.rb +1 -1
- data/spec/{checks → roodi/checks}/empty_rescue_body_check_spec.rb +1 -1
- data/spec/{checks → roodi/checks}/for_loop_check_spec.rb +1 -1
- data/spec/{checks → roodi/checks}/method_line_count_check_spec.rb +1 -1
- data/spec/{checks → roodi/checks}/method_name_check_spec.rb +1 -1
- data/spec/roodi/checks/module_line_count_check_spec.rb +39 -0
- data/spec/roodi/checks/module_name_check_spec.rb +27 -0
- data/spec/roodi/checks/parameter_number_check_spec.rb +47 -0
- metadata +16 -8
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
= 1.2.0
|
2
|
+
|
3
|
+
* added module name check.
|
4
|
+
* added parameter number check.
|
5
|
+
* added module line count check.
|
6
|
+
* added class line count check.
|
7
|
+
|
1
8
|
= 1.1.1
|
2
9
|
|
3
10
|
* I'd initially published to Rubyforge under a 1.0.0 gem, and I've since tried to retrospectively fix up the version number system. It turns out that Rubyforge caches old gems permanently, so I have to re-start at a larger number again.
|
data/Manifest.txt
CHANGED
@@ -7,6 +7,7 @@ bin/roodi-describe
|
|
7
7
|
lib/roodi.rb
|
8
8
|
lib/roodi/checks.rb
|
9
9
|
lib/roodi/checks/check.rb
|
10
|
+
lib/roodi/checks/class_line_count_check.rb
|
10
11
|
lib/roodi/checks/class_name_check.rb
|
11
12
|
lib/roodi/checks/cyclomatic_complexity_block_check.rb
|
12
13
|
lib/roodi/checks/cyclomatic_complexity_check.rb
|
@@ -15,6 +16,9 @@ lib/roodi/checks/empty_rescue_body_check.rb
|
|
15
16
|
lib/roodi/checks/for_loop_check.rb
|
16
17
|
lib/roodi/checks/method_line_count_check.rb
|
17
18
|
lib/roodi/checks/method_name_check.rb
|
19
|
+
lib/roodi/checks/module_line_count_check.rb
|
20
|
+
lib/roodi/checks/module_name_check.rb
|
21
|
+
lib/roodi/checks/parameter_number_check.rb
|
18
22
|
lib/roodi/core.rb
|
19
23
|
lib/roodi/core/checking_visitor.rb
|
20
24
|
lib/roodi/core/iterator_visitor.rb
|
@@ -22,11 +26,15 @@ lib/roodi/core/parse_tree_runner.rb
|
|
22
26
|
lib/roodi/core/parser.rb
|
23
27
|
lib/roodi/core/visitable_sexp.rb
|
24
28
|
roodi.yml
|
25
|
-
spec/checks/
|
26
|
-
spec/checks/
|
27
|
-
spec/checks/
|
28
|
-
spec/checks/
|
29
|
-
spec/checks/
|
30
|
-
spec/checks/
|
31
|
-
spec/checks/
|
29
|
+
spec/roodi/checks/class_line_count_check_spec.rb
|
30
|
+
spec/roodi/checks/class_name_check_spec.rb
|
31
|
+
spec/roodi/checks/cyclomatic_complexity_block_check_spec.rb
|
32
|
+
spec/roodi/checks/cyclomatic_complexity_method_check_spec.rb
|
33
|
+
spec/roodi/checks/empty_rescue_body_check_spec.rb
|
34
|
+
spec/roodi/checks/for_loop_check_spec.rb
|
35
|
+
spec/roodi/checks/method_line_count_check_spec.rb
|
36
|
+
spec/roodi/checks/method_name_check_spec.rb
|
37
|
+
spec/roodi/checks/module_line_count_check_spec.rb
|
38
|
+
spec/roodi/checks/module_name_check_spec.rb
|
39
|
+
spec/roodi/checks/parameter_number_check_spec.rb
|
32
40
|
spec/spec_helper.rb
|
data/README.txt
CHANGED
@@ -39,6 +39,8 @@ If you're writing a check, it is useful to see the structure of a file the way t
|
|
39
39
|
* ForLoopCheck - Check that for loops aren't used (Use Enumerable.each instead)
|
40
40
|
* MethodNameCheck - Check that method names match convention.
|
41
41
|
* MethodLineCountCheck - Check that the number of lines in a method is below the threshold.
|
42
|
+
* ModuleNameCheck - Check that module names match convention.
|
43
|
+
* ParameterNumberCheck - Check that the number of parameters on a method is below the threshold.
|
42
44
|
|
43
45
|
== LICENSE:
|
44
46
|
|
data/lib/roodi.rb
CHANGED
data/lib/roodi/checks.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
+
require 'roodi/checks/class_line_count_check'
|
1
2
|
require 'roodi/checks/class_name_check'
|
2
3
|
require 'roodi/checks/cyclomatic_complexity_block_check'
|
3
4
|
require 'roodi/checks/cyclomatic_complexity_method_check'
|
4
5
|
require 'roodi/checks/empty_rescue_body_check'
|
5
6
|
require 'roodi/checks/for_loop_check'
|
6
|
-
require 'roodi/checks/method_name_check'
|
7
7
|
require 'roodi/checks/method_line_count_check'
|
8
|
+
require 'roodi/checks/method_name_check'
|
9
|
+
require 'roodi/checks/module_line_count_check'
|
10
|
+
require 'roodi/checks/module_name_check'
|
11
|
+
require 'roodi/checks/parameter_number_check'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'roodi/checks/check'
|
2
|
+
|
3
|
+
module Roodi
|
4
|
+
module Checks
|
5
|
+
class ClassLineCountCheck < Check
|
6
|
+
def initialize(line_count = 300)
|
7
|
+
super()
|
8
|
+
@line_count = line_count
|
9
|
+
end
|
10
|
+
|
11
|
+
def interesting_nodes
|
12
|
+
[:class]
|
13
|
+
end
|
14
|
+
|
15
|
+
def evaluate(node)
|
16
|
+
line_count = count_lines(node)
|
17
|
+
add_error "Class \"#{node[1]}\" has #{line_count} lines. It should have #{@line_count} or less." unless line_count <= @line_count
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def count_lines(node)
|
23
|
+
count = 0
|
24
|
+
count = count + 1 if node.node_type == :newline
|
25
|
+
node.children.each {|node| count += count_lines(node)}
|
26
|
+
count
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'roodi/checks/check'
|
2
|
+
|
3
|
+
module Roodi
|
4
|
+
module Checks
|
5
|
+
class ModuleLineCountCheck < Check
|
6
|
+
def initialize(line_count = 300)
|
7
|
+
super()
|
8
|
+
@line_count = line_count
|
9
|
+
end
|
10
|
+
|
11
|
+
def interesting_nodes
|
12
|
+
[:module]
|
13
|
+
end
|
14
|
+
|
15
|
+
def evaluate(node)
|
16
|
+
line_count = count_lines(node)
|
17
|
+
add_error "Module \"#{node[1]}\" has #{line_count} lines. It should have #{@line_count} or less." unless line_count <= @line_count
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def count_lines(node)
|
23
|
+
count = 0
|
24
|
+
count = count + 1 if node.node_type == :newline
|
25
|
+
node.children.each {|node| count += count_lines(node)}
|
26
|
+
count
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'roodi/checks/check'
|
2
|
+
|
3
|
+
module Roodi
|
4
|
+
module Checks
|
5
|
+
class ModuleNameCheck < Check
|
6
|
+
def interesting_nodes
|
7
|
+
[:module]
|
8
|
+
end
|
9
|
+
|
10
|
+
def evaluate(node)
|
11
|
+
class_name = node[1].class == Symbol ? node[1] : node[1].last
|
12
|
+
pattern = /^[A-Z][a-zA-Z0-9]*$/
|
13
|
+
add_error "Module name \"#{node[1]}\" should match pattern #{pattern.inspect}" unless class_name.to_s =~ pattern
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'roodi/checks/check'
|
2
|
+
|
3
|
+
module Roodi
|
4
|
+
module Checks
|
5
|
+
class ParameterNumberCheck < Check
|
6
|
+
def initialize(parameter_count = 5)
|
7
|
+
super()
|
8
|
+
@parameter_count = parameter_count
|
9
|
+
end
|
10
|
+
|
11
|
+
def interesting_nodes
|
12
|
+
[:defn]
|
13
|
+
end
|
14
|
+
|
15
|
+
def evaluate(node)
|
16
|
+
method_name = node[1]
|
17
|
+
arguments = node[2][1][1]
|
18
|
+
parameter_count = arguments.inject(-1) { |count, each| count = count + (each.class == Symbol ? 1 : 0) }
|
19
|
+
add_error "Method name \"#{method_name}\" has #{parameter_count} parameters. It should have #{@parameter_count} or less." unless parameter_count <= @parameter_count
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -19,13 +19,8 @@ module Roodi
|
|
19
19
|
|
20
20
|
def check(filename, content)
|
21
21
|
@checks ||= load_checks
|
22
|
-
|
23
|
-
|
24
|
-
node.accept(IteratorVisitor.new(CheckingVisitor.new(@checks)))
|
25
|
-
rescue Exception => e
|
26
|
-
# puts e
|
27
|
-
puts "#{filename} looks like it's not a valid Ruby file. Skipping..."
|
28
|
-
end
|
22
|
+
node = parse(filename, content)
|
23
|
+
node.accept(IteratorVisitor.new(CheckingVisitor.new(@checks))) if node
|
29
24
|
end
|
30
25
|
|
31
26
|
def check_content(content)
|
@@ -57,6 +52,15 @@ module Roodi
|
|
57
52
|
|
58
53
|
private
|
59
54
|
|
55
|
+
def parse(filename, content)
|
56
|
+
begin
|
57
|
+
@parser.parse(content, filename)
|
58
|
+
rescue Exception => e
|
59
|
+
puts "#{filename} looks like it's not a valid Ruby file. Skipping..." if ENV["ROODI_DEBUG"]
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
60
64
|
def load_checks
|
61
65
|
check_objects = []
|
62
66
|
check_config = YAML.load_file @config
|
data/roodi.yml
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
checks:
|
2
|
+
- { name: ClassLineCountCheck }
|
2
3
|
- { name: ClassNameCheck }
|
3
|
-
- { name: CyclomaticComplexityBlockCheck
|
4
|
-
- { name: CyclomaticComplexityMethodCheck
|
4
|
+
- { name: CyclomaticComplexityBlockCheck }
|
5
|
+
- { name: CyclomaticComplexityMethodCheck }
|
5
6
|
- { name: EmptyRescueBodyCheck }
|
6
7
|
- { name: ForLoopCheck }
|
7
8
|
- { name: MethodLineCountCheck }
|
8
9
|
- { name: MethodNameCheck }
|
10
|
+
- { name: ModuleLineCountCheck }
|
11
|
+
- { name: ModuleNameCheck }
|
12
|
+
- { name: ParameterNumberCheck }
|
9
13
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Roodi::Checks::ClassLineCountCheck do
|
4
|
+
before(:each) do
|
5
|
+
@roodi = Roodi::Core::ParseTreeRunner.new(Roodi::Checks::ClassLineCountCheck.new(1))
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should accept classes with less lines than the threshold" do
|
9
|
+
content = <<-END
|
10
|
+
class ZeroLineClass
|
11
|
+
end
|
12
|
+
END
|
13
|
+
@roodi.check_content(content)
|
14
|
+
@roodi.errors.should be_empty
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept classes with the same number of lines as the threshold" do
|
18
|
+
content = <<-END
|
19
|
+
Class OneLineClass
|
20
|
+
@foo = 1
|
21
|
+
end
|
22
|
+
END
|
23
|
+
@roodi.check_content(content)
|
24
|
+
@roodi.errors.should be_empty
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should reject classes with more lines than the threshold" do
|
28
|
+
content = <<-END
|
29
|
+
class TwoLineClass
|
30
|
+
@foo = 1
|
31
|
+
@bar = 2
|
32
|
+
end
|
33
|
+
END
|
34
|
+
@roodi.check_content(content)
|
35
|
+
errors = @roodi.errors
|
36
|
+
errors.should_not be_empty
|
37
|
+
errors[0].should eql("dummy-file.rb:1 - Class \"TwoLineClass\" has 2 lines. It should have 1 or less.")
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Roodi::Checks::ModuleLineCountCheck do
|
4
|
+
before(:each) do
|
5
|
+
@roodi = Roodi::Core::ParseTreeRunner.new(Roodi::Checks::ModuleLineCountCheck.new(1))
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should accept modules with less lines than the threshold" do
|
9
|
+
content = <<-END
|
10
|
+
module ZeroLineModule
|
11
|
+
end
|
12
|
+
END
|
13
|
+
@roodi.check_content(content)
|
14
|
+
@roodi.errors.should be_empty
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept modules with the same number of lines as the threshold" do
|
18
|
+
content = <<-END
|
19
|
+
module OneLineModule
|
20
|
+
@foo = 1
|
21
|
+
end
|
22
|
+
END
|
23
|
+
@roodi.check_content(content)
|
24
|
+
@roodi.errors.should be_empty
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should reject modules with more lines than the threshold" do
|
28
|
+
content = <<-END
|
29
|
+
module TwoLineModule
|
30
|
+
@foo = 1
|
31
|
+
@bar = 2
|
32
|
+
end
|
33
|
+
END
|
34
|
+
@roodi.check_content(content)
|
35
|
+
errors = @roodi.errors
|
36
|
+
errors.should_not be_empty
|
37
|
+
errors[0].should eql("dummy-file.rb:1 - Module \"TwoLineModule\" has 2 lines. It should have 1 or less.")
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Roodi::Checks::ModuleNameCheck do
|
4
|
+
before(:each) do
|
5
|
+
@roodi = Roodi::Core::ParseTreeRunner.new(Roodi::Checks::ModuleNameCheck.new)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should accept camel case module names starting in capitals" do
|
9
|
+
content = <<-END
|
10
|
+
module GoodModuleName
|
11
|
+
end
|
12
|
+
END
|
13
|
+
@roodi.check_content(content)
|
14
|
+
@roodi.errors.should be_empty
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should reject module names with underscores" do
|
18
|
+
content = <<-END
|
19
|
+
module Bad_ModuleName
|
20
|
+
end
|
21
|
+
END
|
22
|
+
@roodi.check_content(content)
|
23
|
+
errors = @roodi.errors
|
24
|
+
errors.should_not be_empty
|
25
|
+
errors[0].should eql("dummy-file.rb:1 - Module name \"Bad_ModuleName\" should match pattern /^[A-Z][a-zA-Z0-9]*$/")
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Roodi::Checks::ParameterNumberCheck do
|
4
|
+
before(:each) do
|
5
|
+
@roodi = Roodi::Core::ParseTreeRunner.new(Roodi::Checks::ParameterNumberCheck.new(1))
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should accept methods with less lines than the threshold" do
|
9
|
+
content = <<-END
|
10
|
+
def zero_parameter_method
|
11
|
+
end
|
12
|
+
END
|
13
|
+
@roodi.check_content(content)
|
14
|
+
@roodi.errors.should be_empty
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept methods with the same number of parameters as the threshold" do
|
18
|
+
content = <<-END
|
19
|
+
def one_parameter_method(first_parameter)
|
20
|
+
end
|
21
|
+
END
|
22
|
+
@roodi.check_content(content)
|
23
|
+
@roodi.errors.should be_empty
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should reject methods with more parameters than the threshold" do
|
27
|
+
content = <<-END
|
28
|
+
def two_parameter_method(first_parameter, second_parameter)
|
29
|
+
end
|
30
|
+
END
|
31
|
+
@roodi.check_content(content)
|
32
|
+
errors = @roodi.errors
|
33
|
+
errors.should_not be_empty
|
34
|
+
errors[0].should eql("dummy-file.rb:1 - Method name \"two_parameter_method\" has 2 parameters. It should have 1 or less.")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should cope with default values on parameters" do
|
38
|
+
content = <<-END
|
39
|
+
def two_parameter_method(first_parameter = 1, second_parameter = 2)
|
40
|
+
end
|
41
|
+
END
|
42
|
+
@roodi.check_content(content)
|
43
|
+
errors = @roodi.errors
|
44
|
+
errors.should_not be_empty
|
45
|
+
errors[0].should eql("dummy-file.rb:1 - Method name \"two_parameter_method\" has 2 parameters. It should have 1 or less.")
|
46
|
+
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roodi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marty Andrews
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- lib/roodi.rb
|
65
65
|
- lib/roodi/checks.rb
|
66
66
|
- lib/roodi/checks/check.rb
|
67
|
+
- lib/roodi/checks/class_line_count_check.rb
|
67
68
|
- lib/roodi/checks/class_name_check.rb
|
68
69
|
- lib/roodi/checks/cyclomatic_complexity_block_check.rb
|
69
70
|
- lib/roodi/checks/cyclomatic_complexity_check.rb
|
@@ -72,6 +73,9 @@ files:
|
|
72
73
|
- lib/roodi/checks/for_loop_check.rb
|
73
74
|
- lib/roodi/checks/method_line_count_check.rb
|
74
75
|
- lib/roodi/checks/method_name_check.rb
|
76
|
+
- lib/roodi/checks/module_line_count_check.rb
|
77
|
+
- lib/roodi/checks/module_name_check.rb
|
78
|
+
- lib/roodi/checks/parameter_number_check.rb
|
75
79
|
- lib/roodi/core.rb
|
76
80
|
- lib/roodi/core/checking_visitor.rb
|
77
81
|
- lib/roodi/core/iterator_visitor.rb
|
@@ -79,13 +83,17 @@ files:
|
|
79
83
|
- lib/roodi/core/parser.rb
|
80
84
|
- lib/roodi/core/visitable_sexp.rb
|
81
85
|
- roodi.yml
|
82
|
-
- spec/checks/
|
83
|
-
- spec/checks/
|
84
|
-
- spec/checks/
|
85
|
-
- spec/checks/
|
86
|
-
- spec/checks/
|
87
|
-
- spec/checks/
|
88
|
-
- spec/checks/
|
86
|
+
- spec/roodi/checks/class_line_count_check_spec.rb
|
87
|
+
- spec/roodi/checks/class_name_check_spec.rb
|
88
|
+
- spec/roodi/checks/cyclomatic_complexity_block_check_spec.rb
|
89
|
+
- spec/roodi/checks/cyclomatic_complexity_method_check_spec.rb
|
90
|
+
- spec/roodi/checks/empty_rescue_body_check_spec.rb
|
91
|
+
- spec/roodi/checks/for_loop_check_spec.rb
|
92
|
+
- spec/roodi/checks/method_line_count_check_spec.rb
|
93
|
+
- spec/roodi/checks/method_name_check_spec.rb
|
94
|
+
- spec/roodi/checks/module_line_count_check_spec.rb
|
95
|
+
- spec/roodi/checks/module_name_check_spec.rb
|
96
|
+
- spec/roodi/checks/parameter_number_check_spec.rb
|
89
97
|
- spec/spec_helper.rb
|
90
98
|
has_rdoc: true
|
91
99
|
homepage: http://roodi.rubyforge.org
|