roodi 1.1.1 → 1.2.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/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
|