metric_fu-roodi 2.2.2 → 3.0.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.
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