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.
@@ -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.
@@ -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/class_name_check_spec.rb
26
- spec/checks/cyclomatic_complexity_block_check_spec.rb
27
- spec/checks/cyclomatic_complexity_method_check_spec.rb
28
- spec/checks/empty_rescue_body_check_spec.rb
29
- spec/checks/for_loop_check_spec.rb
30
- spec/checks/method_line_count_check_spec.rb
31
- spec/checks/method_name_check_spec.rb
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
 
@@ -2,5 +2,5 @@ require 'roodi/checks'
2
2
  require 'roodi/core'
3
3
 
4
4
  module Roodi
5
- VERSION = '1.1.1'
5
+ VERSION = '1.2.0'
6
6
  end
@@ -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
- begin
23
- node = @parser.parse(content, filename)
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, complexity: 2 }
4
- - { name: CyclomaticComplexityMethodCheck, complexity: 5 }
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
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Roodi::Checks::ClassNameCheck do
4
4
  before(:each) do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Roodi::Checks::CyclomaticComplexityBlockCheck do
4
4
  before(:each) do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Roodi::Checks::CyclomaticComplexityMethodCheck do
4
4
  before(:each) do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Roodi::Checks::EmptyRescueBodyCheck do
4
4
  before(:each) do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Roodi::Checks::ForLoopCheck do
4
4
  before(:each) do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Roodi::Checks::MethodLineCountCheck do
4
4
  before(:each) do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Roodi::Checks::MethodNameCheck do
4
4
  before(:each) do
@@ -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.1.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/class_name_check_spec.rb
83
- - spec/checks/cyclomatic_complexity_block_check_spec.rb
84
- - spec/checks/cyclomatic_complexity_method_check_spec.rb
85
- - spec/checks/empty_rescue_body_check_spec.rb
86
- - spec/checks/for_loop_check_spec.rb
87
- - spec/checks/method_line_count_check_spec.rb
88
- - spec/checks/method_name_check_spec.rb
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