metric_fu-roodi 2.2.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/bin/metric_fu-roodi +2 -19
  3. data/bin/metric_fu-roodi-describe +2 -5
  4. data/lib/roodi.rb +6 -2
  5. data/lib/roodi/version.rb +1 -1
  6. metadata +13 -119
  7. data/.gitignore +0 -3
  8. data/.rspec +0 -2
  9. data/Gemfile +0 -6
  10. data/History.txt +0 -111
  11. data/Manifest.txt +0 -56
  12. data/README.txt +0 -98
  13. data/Rakefile +0 -31
  14. data/TODO.md +0 -3
  15. data/lib/roodi/checks.rb +0 -18
  16. data/lib/roodi/checks/abc_metric_method_check.rb +0 -79
  17. data/lib/roodi/checks/assignment_in_conditional_check.rb +0 -32
  18. data/lib/roodi/checks/case_missing_else_check.rb +0 -20
  19. data/lib/roodi/checks/check.rb +0 -76
  20. data/lib/roodi/checks/class_line_count_check.rb +0 -28
  21. data/lib/roodi/checks/class_name_check.rb +0 -31
  22. data/lib/roodi/checks/class_variable_check.rb +0 -24
  23. data/lib/roodi/checks/control_coupling_check.rb +0 -20
  24. data/lib/roodi/checks/cyclomatic_complexity_block_check.rb +0 -41
  25. data/lib/roodi/checks/cyclomatic_complexity_check.rb +0 -50
  26. data/lib/roodi/checks/cyclomatic_complexity_method_check.rb +0 -42
  27. data/lib/roodi/checks/empty_rescue_body_check.rb +0 -32
  28. data/lib/roodi/checks/for_loop_check.rb +0 -20
  29. data/lib/roodi/checks/line_count_check.rb +0 -28
  30. data/lib/roodi/checks/method_line_count_check.rb +0 -29
  31. data/lib/roodi/checks/method_name_check.rb +0 -31
  32. data/lib/roodi/checks/missing_foreign_key_index_check.rb +0 -99
  33. data/lib/roodi/checks/module_line_count_check.rb +0 -28
  34. data/lib/roodi/checks/module_name_check.rb +0 -31
  35. data/lib/roodi/checks/name_check.rb +0 -16
  36. data/lib/roodi/checks/npath_complexity_check.rb +0 -75
  37. data/lib/roodi/checks/npath_complexity_method_check.rb +0 -29
  38. data/lib/roodi/checks/parameter_number_check.rb +0 -34
  39. data/lib/roodi/core.rb +0 -1
  40. data/lib/roodi/core/checking_visitor.rb +0 -26
  41. data/lib/roodi/core/error.rb +0 -17
  42. data/lib/roodi/core/parser.rb +0 -48
  43. data/lib/roodi/core/runner.rb +0 -81
  44. data/lib/roodi/core/visitable_sexp.rb +0 -25
  45. data/lib/roodi_task.rb +0 -35
  46. data/roodi.gemspec +0 -26
  47. data/roodi.yml +0 -25
  48. data/spec/roodi/checks/abc_metric_method_check_spec.rb +0 -89
  49. data/spec/roodi/checks/assignment_in_conditional_check_spec.rb +0 -105
  50. data/spec/roodi/checks/case_missing_else_check_spec.rb +0 -32
  51. data/spec/roodi/checks/class_line_count_check_spec.rb +0 -39
  52. data/spec/roodi/checks/class_name_check_spec.rb +0 -39
  53. data/spec/roodi/checks/class_variable_check_spec.rb +0 -17
  54. data/spec/roodi/checks/control_coupling_check_spec.rb +0 -23
  55. data/spec/roodi/checks/cyclomatic_complexity_block_check_spec.rb +0 -67
  56. data/spec/roodi/checks/cyclomatic_complexity_method_check_spec.rb +0 -200
  57. data/spec/roodi/checks/empty_rescue_body_check_spec.rb +0 -154
  58. data/spec/roodi/checks/for_loop_check_spec.rb +0 -18
  59. data/spec/roodi/checks/method_line_count_check_spec.rb +0 -56
  60. data/spec/roodi/checks/method_name_check_spec.rb +0 -76
  61. data/spec/roodi/checks/missing_foreign_key_index_check_spec.rb +0 -33
  62. data/spec/roodi/checks/module_line_count_check_spec.rb +0 -39
  63. data/spec/roodi/checks/module_name_check_spec.rb +0 -27
  64. data/spec/roodi/checks/npath_complexity_method_check_spec.rb +0 -53
  65. data/spec/roodi/checks/parameter_number_check_spec.rb +0 -47
  66. data/spec/roodi/core/runner_spec.rb +0 -25
  67. data/spec/roodi/roodi.yml +0 -2
  68. data/spec/spec_helper.rb +0 -3
data/Rakefile DELETED
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env rake
2
- require 'bundler/setup'
3
- require 'bundler/gem_tasks'
4
- begin
5
- require 'spec/rake/spectask'
6
- desc "Run all specs in spec directory"
7
- Spec::Rake::SpecTask.new(:spec) do |t|
8
- t.spec_files = FileList['spec/**/*_spec.rb']
9
- end
10
- rescue LoadError
11
- require 'rspec/core/rake_task'
12
- desc "Run all specs in spec directory"
13
- RSpec::Core::RakeTask.new(:spec)
14
- end
15
-
16
- require File.expand_path('lib/roodi',File.dirname(__FILE__))
17
-
18
- def roodi(ruby_files)
19
- roodi = Roodi::Core::Runner.new
20
- ruby_files.each { |file| roodi.check_file(file) }
21
- roodi.errors.each {|error| puts error}
22
- puts "\nFound #{roodi.errors.size} errors."
23
- end
24
-
25
- desc "Run Roodi against all source files"
26
- task :roodi do
27
- pattern = File.join(File.dirname(__FILE__), "**", "*.rb")
28
- roodi(Dir.glob(pattern))
29
- end
30
-
31
- task :default => :spec
data/TODO.md DELETED
@@ -1,3 +0,0 @@
1
- * Fix failing tests
2
- * Look if https://github.com/martinjandrews/roodi is being actively developed again
3
- * Add travis
@@ -1,18 +0,0 @@
1
- require 'roodi/checks/abc_metric_method_check'
2
- require 'roodi/checks/assignment_in_conditional_check'
3
- require 'roodi/checks/case_missing_else_check'
4
- require 'roodi/checks/class_line_count_check'
5
- require 'roodi/checks/class_name_check'
6
- require 'roodi/checks/class_variable_check'
7
- require 'roodi/checks/control_coupling_check'
8
- require 'roodi/checks/cyclomatic_complexity_block_check'
9
- require 'roodi/checks/cyclomatic_complexity_method_check'
10
- require 'roodi/checks/empty_rescue_body_check'
11
- require 'roodi/checks/for_loop_check'
12
- require 'roodi/checks/method_line_count_check'
13
- require 'roodi/checks/method_name_check'
14
- require 'roodi/checks/missing_foreign_key_index_check'
15
- require 'roodi/checks/module_line_count_check'
16
- require 'roodi/checks/module_name_check'
17
- require 'roodi/checks/npath_complexity_method_check'
18
- require 'roodi/checks/parameter_number_check'
@@ -1,79 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- # TODO: Add summary
6
- #
7
- # TODO: Add detail
8
- class AbcMetricMethodCheck < Check
9
- # ASSIGNMENTS = [:attrasgn, :attrset, :dasgn_curr, :iasgn, :lasgn, :masgn]
10
- ASSIGNMENTS = [:lasgn]
11
- # BRANCHES = [:if, :else, :while, :until, :for, :rescue, :case, :when, :and, :or]
12
- BRANCHES = [:vcall, :call]
13
- # CONDITIONS = [:and, :or]
14
- CONDITIONS = [:==, :<=, :>=, :<, :>]
15
- # = *= /= %= += <<= >>= &= |= ^=
16
- OPERATORS = [:*, :/, :%, :+, :<<, :>>, :&, :|, :^]
17
- DEFAULT_SCORE = 10
18
-
19
- attr_accessor :score
20
-
21
- def initialize
22
- super()
23
- self.score = DEFAULT_SCORE
24
- end
25
-
26
- def interesting_nodes
27
- [:defn]
28
- end
29
-
30
- def evaluate_start(node)
31
- method_name = node[1]
32
- a = count_assignments(node)
33
- b = count_branches(node)
34
- c = count_conditionals(node)
35
- score = Math.sqrt(a*a + b*b + c*c)
36
- add_error "Method name \"#{method_name}\" has an ABC metric score of <#{a},#{b},#{c}> = #{score}. It should be #{@score} or less." unless score <= @score
37
- end
38
-
39
- private
40
-
41
- def count_assignments(node)
42
- count = 0
43
- count = count + 1 if assignment?(node)
44
- node.children.each {|node| count += count_assignments(node)}
45
- count
46
- end
47
-
48
- def count_branches(node)
49
- count = 0
50
- count = count + 1 if branch?(node)
51
- node.children.each {|node| count += count_branches(node)}
52
- count
53
- end
54
-
55
- def count_conditionals(node)
56
- count = 0
57
- count = count + 1 if conditional?(node)
58
- node.children.each {|node| count += count_conditionals(node)}
59
- count
60
- end
61
-
62
- def assignment?(node)
63
- ASSIGNMENTS.include?(node.node_type)
64
- end
65
-
66
- def branch?(node)
67
- BRANCHES.include?(node.node_type) && !conditional?(node) && !operator?(node)
68
- end
69
-
70
- def conditional?(node)
71
- (:call == node.node_type) && CONDITIONS.include?(node[2])
72
- end
73
-
74
- def operator?(node)
75
- (:call == node.node_type) && OPERATORS.include?(node[2])
76
- end
77
- end
78
- end
79
- end
@@ -1,32 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks a conditional to see if it contains an assignment.
6
- #
7
- # A conditional containing an assignment is likely to be a mistyped equality check. You
8
- # should either fix the typo or factor out the assignment so that the code is clearer.
9
- class AssignmentInConditionalCheck < Check
10
-
11
- def interesting_nodes
12
- [:if, :while]
13
- end
14
-
15
- def evaluate_start(node)
16
- add_error("Found = in conditional. It should probably be an ==") if has_assignment?(node[1])
17
- end
18
-
19
- private
20
-
21
- def has_assignment?(node)
22
- found_assignment = false
23
- found_assignment = found_assignment || node.node_type == :lasgn
24
- if (node.node_type == :and or node.node_type == :or)
25
- node.children.each { |child| found_assignment = found_assignment || has_assignment?(child) }
26
- end
27
- found_assignment
28
- end
29
-
30
- end
31
- end
32
- end
@@ -1,20 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks a case statement to make sure it has an 'else' clause.
6
- #
7
- # It's usually a good idea to have an else clause in every case statement. Even if the
8
- # developer is sure that all currently possible cases are covered, this should be
9
- # expressed in the else clause. This way the code is protected aginst later changes,
10
- class CaseMissingElseCheck < Check
11
- def interesting_nodes
12
- [:case]
13
- end
14
-
15
- def evaluate_start(node)
16
- add_error "Case statement is missing an else clause." unless node.last
17
- end
18
- end
19
- end
20
- end
@@ -1,76 +0,0 @@
1
- require 'roodi/core/error'
2
-
3
- module Roodi
4
- module Checks
5
- class Check
6
-
7
- NODE_TYPES = [:defn, :module, :resbody, :lvar, :cvar, :class, :if, :while, :until, :for, :rescue, :case, :when, :and, :or]
8
-
9
- class << self
10
-
11
- def make(options = nil)
12
- check = new
13
- if options
14
- options.each do |name, value|
15
- check.send("#{name}=", value)
16
- end
17
- end
18
- check
19
- end
20
-
21
- end
22
-
23
- def initialize
24
- @errors = []
25
- end
26
-
27
- NODE_TYPES.each do |node|
28
- start_node_method = "evaluate_start_#{node}"
29
- end_node_method = "evaluate_end_#{node}"
30
- define_method(start_node_method) { |node| return } unless self.respond_to?(start_node_method)
31
- define_method(end_node_method) { |node| return } unless self.respond_to?(end_node_method)
32
- end
33
-
34
- def position(offset = 0)
35
- "#{@line[2]}:#{@line[1] + offset}"
36
- end
37
-
38
- def start_file(filename)
39
- end
40
-
41
- def end_file(filename)
42
- end
43
-
44
- def evaluate_start(node)
45
- end
46
-
47
- def evaluate_end(node)
48
- end
49
-
50
- def evaluate_node(position, node)
51
- @node = node
52
- eval_method = "evaluate_#{position}_#{node.node_type}"
53
- self.send(eval_method, node)
54
- end
55
-
56
- def evaluate_node_start(node)
57
- evaluate_node(:start, node)
58
- evaluate_start(node)
59
- end
60
-
61
- def evaluate_node_end(node)
62
- evaluate_node(:end, node)
63
- evaluate_end(node)
64
- end
65
-
66
- def add_error(error, filename = @node.file, line = @node.line)
67
- @errors ||= []
68
- @errors << Roodi::Core::Error.new("#{filename}", "#{line}", error)
69
- end
70
-
71
- def errors
72
- @errors
73
- end
74
- end
75
- end
76
- end
@@ -1,28 +0,0 @@
1
- require 'roodi/checks/line_count_check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks a class to make sure the number of lines it has is under the specified limit.
6
- #
7
- # A class getting too large is a code smell that indicates it might be taking on too many
8
- # responsibilities. It should probably be refactored into multiple smaller classes.
9
- class ClassLineCountCheck < LineCountCheck
10
-
11
- DEFAULT_LINE_COUNT = 300
12
-
13
- def initialize
14
- super()
15
- self.line_count = DEFAULT_LINE_COUNT
16
- end
17
-
18
- def interesting_nodes
19
- [:class]
20
- end
21
-
22
- def message_prefix
23
- 'Class'
24
- end
25
-
26
- end
27
- end
28
- end
@@ -1,31 +0,0 @@
1
- require 'roodi/checks/name_check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks a class name to make sure it matches the specified pattern.
6
- #
7
- # Keeping to a consistent naming convention makes your code easier to read.
8
- class ClassNameCheck < NameCheck
9
-
10
- DEFAULT_PATTERN = /^[A-Z][a-zA-Z0-9]*$/
11
-
12
- def initialize
13
- super()
14
- self.pattern = DEFAULT_PATTERN
15
- end
16
-
17
- def interesting_nodes
18
- [:class]
19
- end
20
-
21
- def message_prefix
22
- 'Class'
23
- end
24
-
25
- def find_name(node)
26
- node[1].class == Symbol ? node[1] : node[1].last
27
- end
28
-
29
- end
30
- end
31
- end
@@ -1,24 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks to make sure class variables are not being used..
6
- #
7
- # Class variables in Ruby have a complicated inheritance policy, and their use
8
- # can lead to mistakes. Often an alternate design can be used to solve the
9
- # problem instead.
10
- #
11
- # This check is looking for a code smell rather than a definite error. If you're
12
- # sure that you're doing the right thing, try turning this check off in your
13
- # config file.
14
- class ClassVariableCheck < Check
15
- def interesting_nodes
16
- [:cvar]
17
- end
18
-
19
- def evaluate_start(node)
20
- add_error "Don't use class variables. You might want to try a different design."
21
- end
22
- end
23
- end
24
- end
@@ -1,20 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- class ControlCouplingCheck < Check
6
- def interesting_nodes
7
- [:defn, :lvar]
8
- end
9
-
10
- def evaluate_start_defn(node)
11
- @method_name = node[1]
12
- @arguments = node[2][1..-1]
13
- end
14
-
15
- def evaluate_start_lvar(node)
16
- add_error "Method \"#{@method_name}\" uses the argument \"#{node[1]}\" for internal control." if @arguments.detect {|each| each == node[1]}
17
- end
18
- end
19
- end
20
- end
@@ -1,41 +0,0 @@
1
- require 'roodi/checks/cyclomatic_complexity_check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks cyclomatic complexity of a block against a specified limit.
6
- #
7
- # The cyclomatic complexity is measured by the number of "if", "unless", "elsif", "?:",
8
- # "while", "until", "for", "rescue", "case", "when", "&amp;&amp;", "and", "||" and "or"
9
- # statements (plus one) in the body of the member. It is a measure of the minimum
10
- # number of possible paths through the source and therefore the number of required tests.
11
- #
12
- # Generally, for a block, 1-2 is considered good, 3-4 ok, 5-8 consider re-factoring, and 8+
13
- # re-factor now!
14
- class CyclomaticComplexityBlockCheck < CyclomaticComplexityCheck
15
-
16
- DEFAULT_COMPLEXITY = 4
17
-
18
- def initialize
19
- super()
20
- self.complexity = DEFAULT_COMPLEXITY
21
- end
22
-
23
- def interesting_nodes
24
- [:iter] + COMPLEXITY_NODE_TYPES
25
- end
26
-
27
- def evaluate_start_iter(node)
28
- increase_depth
29
- end
30
-
31
- def evaluate_end_iter(node)
32
- decrease_depth
33
- end
34
-
35
- def evaluate_matching_end
36
- add_error "Block cyclomatic complexity is #{@count}. It should be #{@complexity} or less." unless @count <= @complexity
37
- end
38
-
39
- end
40
- end
41
- end
@@ -1,50 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- class CyclomaticComplexityCheck < Check
6
-
7
- COMPLEXITY_NODE_TYPES = [:if, :while, :until, :for, :rescue, :case, :when, :and, :or]
8
-
9
- attr_accessor :complexity
10
-
11
- def initialize
12
- super()
13
- @count = 0
14
- @counting = 0
15
- end
16
-
17
- COMPLEXITY_NODE_TYPES.each do |type|
18
- define_method "evaluate_start_#{type}" do |node|
19
- @count = @count + 1 if counting?
20
- end
21
- end
22
-
23
- protected
24
-
25
- def count_complexity(node)
26
- count_branches(node) + 1
27
- end
28
-
29
- def increase_depth
30
- @count = 1 unless counting?
31
- @counting = @counting + 1
32
- end
33
-
34
- def decrease_depth
35
- @counting = @counting - 1
36
- if @counting <= 0
37
- @counting = 0
38
- evaluate_matching_end
39
- end
40
- end
41
-
42
- private
43
-
44
- def counting?
45
- @counting > 0
46
- end
47
-
48
- end
49
- end
50
- end