Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Use attributes to configure Checks.

Create a 'make' method to create and configure Check instances.
  • Loading branch information...
commit 682e89d64a6fba7bedf184d1079b9e13955fe19a 1 parent 4665fe1
@mdub mdub authored
Showing with 157 additions and 81 deletions.
  1. +4 −2 lib/roodi/checks/abc_metric_method_check.rb
  2. +2 −4 lib/roodi/checks/assignment_in_conditional_check.rb
  3. +15 −0 lib/roodi/checks/check.rb
  4. +13 −3 lib/roodi/checks/class_line_count_check.rb
  5. +13 −3 lib/roodi/checks/class_name_check.rb
  6. +5 −3 lib/roodi/checks/cyclomatic_complexity_block_check.rb
  7. +5 −2 lib/roodi/checks/cyclomatic_complexity_check.rb
  8. +5 −3 lib/roodi/checks/cyclomatic_complexity_method_check.rb
  9. +4 −11 lib/roodi/checks/line_count_check.rb
  10. +13 −3 lib/roodi/checks/method_line_count_check.rb
  11. +13 −3 lib/roodi/checks/method_name_check.rb
  12. +1 −0  lib/roodi/checks/missing_foreign_key_index_check.rb
  13. +13 −3 lib/roodi/checks/module_line_count_check.rb
  14. +14 −4 lib/roodi/checks/module_name_check.rb
  15. +3 −10 lib/roodi/checks/name_check.rb
  16. +2 −0  lib/roodi/checks/npath_complexity_check.rb
  17. +4 −3 lib/roodi/checks/npath_complexity_method_check.rb
  18. +8 −4 lib/roodi/checks/parameter_number_check.rb
  19. +2 −2 lib/roodi/core/runner.rb
  20. +1 −1  spec/roodi/checks/abc_metric_method_check_spec.rb
  21. +1 −1  spec/roodi/checks/assignment_in_conditional_check_spec.rb
  22. +1 −1  spec/roodi/checks/case_missing_else_check_spec.rb
  23. +1 −1  spec/roodi/checks/class_line_count_check_spec.rb
  24. +1 −1  spec/roodi/checks/class_name_check_spec.rb
  25. +1 −1  spec/roodi/checks/class_variable_check_spec.rb
  26. +1 −1  spec/roodi/checks/control_coupling_check_spec.rb
  27. +1 −1  spec/roodi/checks/cyclomatic_complexity_block_check_spec.rb
  28. +1 −1  spec/roodi/checks/cyclomatic_complexity_method_check_spec.rb
  29. +1 −1  spec/roodi/checks/empty_rescue_body_check_spec.rb
  30. +1 −1  spec/roodi/checks/for_loop_check_spec.rb
  31. +1 −1  spec/roodi/checks/method_line_count_check_spec.rb
  32. +1 −1  spec/roodi/checks/method_name_check_spec.rb
  33. +1 −1  spec/roodi/checks/missing_foreign_key_index_check_spec.rb
  34. +1 −1  spec/roodi/checks/module_line_count_check_spec.rb
  35. +1 −1  spec/roodi/checks/module_name_check_spec.rb
  36. +1 −1  spec/roodi/checks/npath_complexity_method_check_spec.rb
  37. +1 −1  spec/roodi/checks/parameter_number_check_spec.rb
View
6 lib/roodi/checks/abc_metric_method_check.rb
@@ -16,9 +16,11 @@ class AbcMetricMethodCheck < Check
OPERATORS = [:*, :/, :%, :+, :<<, :>>, :&, :|, :^]
DEFAULT_SCORE = 10
- def initialize(options = {})
+ attr_accessor :score
+
+ def initialize
super()
- @score = options['score'] || DEFAULT_SCORE
+ self.score = DEFAULT_SCORE
end
def interesting_nodes
View
6 lib/roodi/checks/assignment_in_conditional_check.rb
@@ -7,10 +7,7 @@ module Checks
# A conditional containing an assignment is likely to be a mistyped equality check. You
# should either fix the typo or factor out the assignment so that the code is clearer.
class AssignmentInConditionalCheck < Check
- def initialize(options = {})
- super()
- end
-
+
def interesting_nodes
[:if, :while]
end
@@ -29,6 +26,7 @@ def has_assignment?(node)
end
found_assignment
end
+
end
end
end
View
15 lib/roodi/checks/check.rb
@@ -3,8 +3,23 @@
module Roodi
module Checks
class Check
+
NODE_TYPES = [:defn, :module, :resbody, :lvar, :cvar, :class, :if, :while, :until, :for, :rescue, :case, :when, :and, :or]
+ class << self
+
+ def make(options = nil)
+ check = new
+ if options
+ options.each do |name, value|
+ check.send("#{name}=", value)
+ end
+ end
+ check
+ end
+
+ end
+
def initialize
@errors = []
end
View
16 lib/roodi/checks/class_line_count_check.rb
@@ -7,12 +7,22 @@ module Checks
# A class getting too large is a code smell that indicates it might be taking on too many
# responsibilities. It should probably be refactored into multiple smaller classes.
class ClassLineCountCheck < LineCountCheck
+
DEFAULT_LINE_COUNT = 300
- def initialize(options = {})
- line_count = options['line_count'] || DEFAULT_LINE_COUNT
- super([:class], line_count, 'Class')
+ def initialize
+ super()
+ self.line_count = DEFAULT_LINE_COUNT
+ end
+
+ def interesting_nodes
+ [:class]
end
+
+ def message_prefix
+ 'Class'
+ end
+
end
end
end
View
16 lib/roodi/checks/class_name_check.rb
@@ -6,16 +6,26 @@ module Checks
#
# Keeping to a consistent naming convention makes your code easier to read.
class ClassNameCheck < NameCheck
+
DEFAULT_PATTERN = /^[A-Z][a-zA-Z0-9]*$/
- def initialize(options = {})
- pattern = options['pattern'] || DEFAULT_PATTERN
- super([:class], pattern, 'Class')
+ def initialize
+ super()
+ self.pattern = DEFAULT_PATTERN
end
+ def interesting_nodes
+ [:class]
+ end
+
+ def message_prefix
+ 'Class'
+ end
+
def find_name(node)
node[1].class == Symbol ? node[1] : node[1].last
end
+
end
end
end
View
8 lib/roodi/checks/cyclomatic_complexity_block_check.rb
@@ -12,11 +12,12 @@ module Checks
# Generally, for a block, 1-2 is considered good, 3-4 ok, 5-8 consider re-factoring, and 8+
# re-factor now!
class CyclomaticComplexityBlockCheck < CyclomaticComplexityCheck
+
DEFAULT_COMPLEXITY = 4
- def initialize(options = {})
- complexity = options['complexity'] || DEFAULT_COMPLEXITY
- super(complexity)
+ def initialize
+ super()
+ self.complexity = DEFAULT_COMPLEXITY
end
def interesting_nodes
@@ -34,6 +35,7 @@ def evaluate_end_iter(node)
def evaluate_matching_end
add_error "Block cyclomatic complexity is #{@count}. It should be #{@complexity} or less." unless @count <= @complexity
end
+
end
end
end
View
7 lib/roodi/checks/cyclomatic_complexity_check.rb
@@ -3,11 +3,13 @@
module Roodi
module Checks
class CyclomaticComplexityCheck < Check
+
COMPLEXITY_NODE_TYPES = [:if, :while, :until, :for, :rescue, :case, :when, :and, :or]
- def initialize(complexity)
+ attr_accessor :complexity
+
+ def initialize
super()
- @complexity = complexity
@count = 0
@counting = 0
end
@@ -42,6 +44,7 @@ def decrease_depth
def counting?
@counting > 0
end
+
end
end
end
View
8 lib/roodi/checks/cyclomatic_complexity_method_check.rb
@@ -12,11 +12,12 @@ module Checks
# Generally, for a method, 1-4 is considered good, 5-8 ok, 9-10 consider re-factoring, and
# 11+ re-factor now!
class CyclomaticComplexityMethodCheck < CyclomaticComplexityCheck
+
DEFAULT_COMPLEXITY = 8
- def initialize(options = {})
- complexity = options['complexity'] || DEFAULT_COMPLEXITY
- super(complexity)
+ def initialize
+ super()
+ self.complexity = DEFAULT_COMPLEXITY
end
def interesting_nodes
@@ -35,6 +36,7 @@ def evaluate_end_defn(node)
def evaluate_matching_end
add_error "Method name \"#{@method_name}\" cyclomatic complexity is #{@count}. It should be #{@complexity} or less." unless @count <= @complexity
end
+
end
end
end
View
15 lib/roodi/checks/line_count_check.rb
@@ -3,20 +3,12 @@
module Roodi
module Checks
class LineCountCheck < Check
- def initialize(interesting_nodes, line_count, message_prefix)
- super()
- @interesting_nodes = interesting_nodes
- @line_count = line_count
- @message_prefix = message_prefix
- end
-
- def interesting_nodes
- @interesting_nodes
- end
+
+ attr_accessor :line_count
def evaluate_start(node)
line_count = count_lines(node)
- add_error "#{@message_prefix} \"#{node[1]}\" has #{line_count} lines. It should have #{@line_count} or less." unless line_count <= @line_count
+ add_error "#{message_prefix} \"#{node[1]}\" has #{line_count} lines. It should have #{@line_count} or less." unless line_count <= @line_count
end
protected
@@ -24,6 +16,7 @@ def evaluate_start(node)
def count_lines(node)
node.last.line - node.line - 1
end
+
end
end
end
View
16 lib/roodi/checks/method_line_count_check.rb
@@ -8,12 +8,22 @@ module Checks
# thing and becoming hard to test. It should probably be refactored into multiple methods
# that each do a single thing well.
class MethodLineCountCheck < LineCountCheck
+
DEFAULT_LINE_COUNT = 20
- def initialize(options = {})
- line_count = options['line_count'] || DEFAULT_LINE_COUNT
- super([:defn], line_count, 'Method')
+ def initialize
+ super()
+ self.line_count = DEFAULT_LINE_COUNT
+ end
+
+ def interesting_nodes
+ [:defn]
end
+
+ def message_prefix
+ 'Method'
+ end
+
end
end
end
View
16 lib/roodi/checks/method_name_check.rb
@@ -6,16 +6,26 @@ module Checks
#
# Keeping to a consistent nameing convention makes your code easier to read.
class MethodNameCheck < NameCheck
+
DEFAULT_PATTERN = /^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/
- def initialize(options = {})
- pattern = options['pattern'] || DEFAULT_PATTERN
- super([:defn], pattern, 'Method')
+ def initialize
+ super()
+ self.pattern = DEFAULT_PATTERN
end
+ def interesting_nodes
+ [:defn]
+ end
+
+ def message_prefix
+ 'Method'
+ end
+
def find_name(node)
node[1]
end
+
end
end
end
View
1  lib/roodi/checks/missing_foreign_key_index_check.rb
@@ -10,6 +10,7 @@ module Checks
# Enumerable.each with a block instead.
class MissingForeignKeyIndexCheck < Check
def initialize
+ super()
@foreign_keys = {}
@indexes = {}
end
View
16 lib/roodi/checks/module_line_count_check.rb
@@ -7,12 +7,22 @@ module Checks
# A module getting too large is a code smell that indicates it might be taking on too many
# responsibilities. It should probably be refactored into multiple smaller modules.
class ModuleLineCountCheck < LineCountCheck
+
DEFAULT_LINE_COUNT = 300
- def initialize(options = {})
- line_count = options['line_count'] || DEFAULT_LINE_COUNT
- super([:module], line_count, 'Module')
+ def initialize
+ super()
+ self.line_count = DEFAULT_LINE_COUNT
+ end
+
+ def interesting_nodes
+ [:module]
end
+
+ def message_prefix
+ 'Module'
+ end
+
end
end
end
View
18 lib/roodi/checks/module_name_check.rb
@@ -6,16 +6,26 @@ module Checks
#
# Keeping to a consistent nameing convention makes your code easier to read.
class ModuleNameCheck < NameCheck
+
DEFAULT_PATTERN = /^[A-Z][a-zA-Z0-9]*$/
- def initialize(options = {})
- pattern = options['pattern'] || DEFAULT_PATTERN
- super([:module], pattern, 'Module')
+ def initialize
+ super()
+ self.pattern = DEFAULT_PATTERN
end
-
+
+ def interesting_nodes
+ [:module]
+ end
+
+ def message_prefix
+ 'Module'
+ end
+
def find_name(node)
node[1].class == Symbol ? node[1] : node[1].last
end
+
end
end
end
View
13 lib/roodi/checks/name_check.rb
@@ -3,21 +3,14 @@
module Roodi
module Checks
class NameCheck < Check
- def initialize(interesting_nodes, pattern, message_prefix)
- super()
- @interesting_nodes = interesting_nodes
- @pattern = pattern
- @message_prefix = message_prefix
- end
- def interesting_nodes
- @interesting_nodes
- end
+ attr_accessor :pattern
def evaluate_start(node)
name = find_name(node)
- add_error "#{@message_prefix} name \"#{name}\" should match pattern #{@pattern.inspect}" unless name.to_s =~ @pattern
+ add_error "#{message_prefix} name \"#{name}\" should match pattern #{@pattern.inspect}" unless name.to_s =~ @pattern
end
+
end
end
end
View
2  lib/roodi/checks/npath_complexity_check.rb
@@ -8,6 +8,8 @@ class NpathComplexityCheck < Check
ADDING_NODE_TYPES = [:rescue]
COMPLEXITY_NODE_TYPES = MULTIPLYING_NODE_TYPES + ADDING_NODE_TYPES
+ attr_accessor :complexity
+
def initialize(complexity)
super()
@complexity = complexity
View
7 lib/roodi/checks/npath_complexity_method_check.rb
@@ -4,11 +4,11 @@ module Roodi
module Checks
# Checks Npath complexity of a method against a specified limit.
class NpathComplexityMethodCheck < NpathComplexityCheck
+
DEFAULT_COMPLEXITY = 8
- def initialize(options = {})
- complexity = options['complexity'] || DEFAULT_COMPLEXITY
- super(complexity)
+ def initialize
+ super(DEFAULT_COMPLEXITY)
end
def interesting_nodes
@@ -23,6 +23,7 @@ def evaluate_start_defn(node)
def evaluate_end_defn(node)
add_error "Method name \"#{@method_name}\" n-path complexity is #{@current_value}. It should be #{@complexity} or less." unless @current_value <= @complexity
end
+
end
end
end
View
12 lib/roodi/checks/parameter_number_check.rb
@@ -8,11 +8,14 @@ module Checks
# much, or that the parameters should be grouped into one or more objects of their own. It
# probably needs some refactoring.
class ParameterNumberCheck < Check
+
DEFAULT_PARAMETER_COUNT = 5
- def initialize(options = {})
+ attr_accessor :parameter_count
+
+ def initialize
super()
- @parameter_count = options['parameter_count'] || DEFAULT_PARAMETER_COUNT
+ self.parameter_count = DEFAULT_PARAMETER_COUNT
end
def interesting_nodes
@@ -22,9 +25,10 @@ def interesting_nodes
def evaluate_start(node)
method_name = node[1]
arguments = node[2]
- parameter_count = arguments.inject(-1) { |count, each| count = count + (each.class == Symbol ? 1 : 0) }
- add_error "Method name \"#{method_name}\" has #{parameter_count} parameters. It should have #{@parameter_count} or less." unless parameter_count <= @parameter_count
+ actual_parameter_count = arguments.inject(-1) { |count, each| count = count + (each.class == Symbol ? 1 : 0) }
+ add_error "Method name \"#{method_name}\" has #{actual_parameter_count} parameters. It should have #{@parameter_count} or less." unless actual_parameter_count <= @parameter_count
end
+
end
end
end
View
4 lib/roodi/core/runner.rb
@@ -70,11 +70,11 @@ def load_checks
checks = YAML.load_file @config
checks.each do |check_class_name, options|
check_class = Roodi::Checks.const_get(check_class_name)
- new_args = [options].compact
- check_objects << check_class.new(*new_args)
+ check_objects << check_class.make(options || {})
end
check_objects
end
+
end
end
end
View
2  spec/roodi/checks/abc_metric_method_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::AbcMetricMethodCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::AbcMetricMethodCheck.new({'score' => 0}))
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::AbcMetricMethodCheck.make({'score' => 0}))
end
def verify_content_score(content, a, b, c)
View
2  spec/roodi/checks/assignment_in_conditional_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::AssignmentInConditionalCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::AssignmentInConditionalCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::AssignmentInConditionalCheck.make)
end
it "should accept an assignment before an if clause" do
View
2  spec/roodi/checks/case_missing_else_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::CaseMissingElseCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::CaseMissingElseCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::CaseMissingElseCheck.make)
end
it "should accept case statements that do have an else" do
View
2  spec/roodi/checks/class_line_count_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::ClassLineCountCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::ClassLineCountCheck.new({'line_count' => 1}))
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::ClassLineCountCheck.make({'line_count' => 1}))
end
it "should accept classes with less lines than the threshold" do
View
2  spec/roodi/checks/class_name_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::ClassNameCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::ClassNameCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::ClassNameCheck.make)
end
it "should accept camel case class names starting in capitals" do
View
2  spec/roodi/checks/class_variable_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::ClassVariableCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::ClassVariableCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::ClassVariableCheck.make)
end
it "should reject class variables" do
View
2  spec/roodi/checks/control_coupling_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::ControlCouplingCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::ControlCouplingCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::ControlCouplingCheck.make)
end
it "should reject methods with if checks using a parameter" do
View
2  spec/roodi/checks/cyclomatic_complexity_block_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::CyclomaticComplexityBlockCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::CyclomaticComplexityBlockCheck.new({'complexity' => 0}))
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::CyclomaticComplexityBlockCheck.make({'complexity' => 0}))
end
def verify_content_complexity(content, complexity)
View
2  spec/roodi/checks/cyclomatic_complexity_method_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::CyclomaticComplexityMethodCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::CyclomaticComplexityMethodCheck.new({'complexity' => 0}))
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::CyclomaticComplexityMethodCheck.make({'complexity' => 0}))
end
def verify_content_complexity(content, complexity)
View
2  spec/roodi/checks/empty_rescue_body_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::EmptyRescueBodyCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::EmptyRescueBodyCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::EmptyRescueBodyCheck.make)
end
it "should accept a rescue body with content and no parameter" do
View
2  spec/roodi/checks/for_loop_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::ForLoopCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::ForLoopCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::ForLoopCheck.make)
end
it "should reject for loops" do
View
2  spec/roodi/checks/method_line_count_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::MethodLineCountCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::MethodLineCountCheck.new({'line_count' => 1}))
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::MethodLineCountCheck.make({'line_count' => 1}))
end
it "should accept methods with less lines than the threshold" do
View
2  spec/roodi/checks/method_name_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::MethodNameCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::MethodNameCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::MethodNameCheck.make)
end
it "should accept method names with underscores" do
View
2  spec/roodi/checks/missing_foreign_key_index_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::MissingForeignKeyIndexCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::MissingForeignKeyIndexCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::MissingForeignKeyIndexCheck.make)
end
it "should warn about a missing foreign key" do
View
2  spec/roodi/checks/module_line_count_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::ModuleLineCountCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::ModuleLineCountCheck.new({'line_count' => 1}))
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::ModuleLineCountCheck.make({'line_count' => 1}))
end
it "should accept modules with less lines than the threshold" do
View
2  spec/roodi/checks/module_name_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::ModuleNameCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::ModuleNameCheck.new)
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::ModuleNameCheck.make)
end
it "should accept camel case module names starting in capitals" do
View
2  spec/roodi/checks/npath_complexity_method_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::NpathComplexityMethodCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::NpathComplexityMethodCheck.new({'complexity' => 0}))
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::NpathComplexityMethodCheck.make({'complexity' => 0}))
end
def verify_content_complexity(content, complexity)
View
2  spec/roodi/checks/parameter_number_check_spec.rb
@@ -2,7 +2,7 @@
describe Roodi::Checks::ParameterNumberCheck do
before(:each) do
- @roodi = Roodi::Core::Runner.new(Roodi::Checks::ParameterNumberCheck.new({'parameter_count' => 1}))
+ @roodi = Roodi::Core::Runner.new(Roodi::Checks::ParameterNumberCheck.make({'parameter_count' => 1}))
end
it "should accept methods with less lines than the threshold" do
Please sign in to comment.
Something went wrong with that request. Please try again.