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
@@ -1,42 +0,0 @@
1
- require 'roodi/checks/cyclomatic_complexity_check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks cyclomatic complexity of a method 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", "&&", "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 method, 1-4 is considered good, 5-8 ok, 9-10 consider re-factoring, and
13
- # 11+ re-factor now!
14
- class CyclomaticComplexityMethodCheck < CyclomaticComplexityCheck
15
-
16
- DEFAULT_COMPLEXITY = 8
17
-
18
- def initialize
19
- super()
20
- self.complexity = DEFAULT_COMPLEXITY
21
- end
22
-
23
- def interesting_nodes
24
- [:defn] + COMPLEXITY_NODE_TYPES
25
- end
26
-
27
- def evaluate_start_defn(node)
28
- @method_name = @node[1]
29
- increase_depth
30
- end
31
-
32
- def evaluate_end_defn(node)
33
- decrease_depth
34
- end
35
-
36
- def evaluate_matching_end
37
- add_error "Method name \"#{@method_name}\" cyclomatic complexity is #{@count}. It should be #{@complexity} or less." unless @count <= @complexity
38
- end
39
-
40
- end
41
- end
42
- end
@@ -1,32 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks the body of a rescue block to make sure it's not empty..
6
- #
7
- # When the body of a rescue block is empty, exceptions can get caught and swallowed without
8
- # any feedback to the user.
9
- class EmptyRescueBodyCheck < Check
10
- STATEMENT_NODES = [:fcall, :return, :attrasgn, :vcall, :nil, :call, :lasgn, :true, :false, :next]
11
-
12
- def interesting_nodes
13
- [:resbody]
14
- end
15
-
16
- def evaluate_start(node)
17
- add_error("Rescue block should not be empty.") unless has_statement?(node.children[1])
18
- end
19
-
20
- private
21
-
22
- def has_statement?(node)
23
- false unless node
24
- has_local_statement?(node) or node.children.any? { |child| has_statement?(child) } if node
25
- end
26
-
27
- def has_local_statement?(node)
28
- STATEMENT_NODES.include?(node.node_type)
29
- end
30
- end
31
- end
32
- end
@@ -1,20 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks to make sure for loops are not being used..
6
- #
7
- # Using a for loop is not idiomatic use of Ruby, and is usually a sign that someone with
8
- # more experience in a different programming language is trying out Ruby. Use
9
- # Enumerable.each with a block instead.
10
- class ForLoopCheck < Check
11
- def interesting_nodes
12
- [:for]
13
- end
14
-
15
- def evaluate_start(node)
16
- add_error "Don't use 'for' loops. Use Enumerable.each instead."
17
- end
18
- end
19
- end
20
- end
@@ -1,28 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- class LineCountCheck < Check
6
-
7
- attr_accessor :line_count
8
-
9
- def evaluate_start(node)
10
- line_count = count_lines(node)
11
- add_error "#{message_prefix} \"#{node[1]}\" has #{line_count} lines. It should have #{@line_count} or less." unless line_count <= @line_count
12
- end
13
-
14
- protected
15
-
16
- def count_lines(node)
17
- node.last.line - node.line - 1
18
- rescue NoMethodError => e
19
- if ENV['DEBUG'] =~ /true/i
20
- STDERR.puts "!! line counting error #{e.message}\t #{node.inspect}"
21
- STDERR.puts "!! Does the node have any lines?"
22
- end
23
- 0
24
- end
25
-
26
- end
27
- end
28
- end
@@ -1,29 +0,0 @@
1
- require 'roodi/checks/line_count_check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks a method to make sure the number of lines it has is under the specified limit.
6
- #
7
- # A method getting too large is a code smell that indicates it might be doing more than one
8
- # thing and becoming hard to test. It should probably be refactored into multiple methods
9
- # that each do a single thing well.
10
- class MethodLineCountCheck < LineCountCheck
11
-
12
- DEFAULT_LINE_COUNT = 20
13
-
14
- def initialize
15
- super()
16
- self.line_count = DEFAULT_LINE_COUNT
17
- end
18
-
19
- def interesting_nodes
20
- [:defn]
21
- end
22
-
23
- def message_prefix
24
- 'Method'
25
- end
26
-
27
- end
28
- end
29
- end
@@ -1,31 +0,0 @@
1
- require 'roodi/checks/name_check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks a method name to make sure it matches the specified pattern.
6
- #
7
- # Keeping to a consistent nameing convention makes your code easier to read.
8
- class MethodNameCheck < NameCheck
9
-
10
- DEFAULT_PATTERN = /^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/
11
-
12
- def initialize
13
- super()
14
- self.pattern = DEFAULT_PATTERN
15
- end
16
-
17
- def interesting_nodes
18
- [:defn]
19
- end
20
-
21
- def message_prefix
22
- 'Method'
23
- end
24
-
25
- def find_name(node)
26
- node[1]
27
- end
28
-
29
- end
30
- end
31
- end
@@ -1,99 +0,0 @@
1
- require 'roodi/checks/check'
2
- require 'pathname'
3
-
4
- module Roodi
5
- module Checks
6
- # Checks to make sure for loops are not being used..
7
- #
8
- # Using a for loop is not idiomatic use of Ruby, and is usually a sign that someone with
9
- # more experience in a different programming language is trying out Ruby. Use
10
- # Enumerable.each with a block instead.
11
- class MissingForeignKeyIndexCheck < Check
12
- def initialize
13
- super()
14
- @foreign_keys = {}
15
- @indexes = {}
16
- end
17
-
18
- def interesting_nodes
19
- [:call]
20
- end
21
-
22
- def evaluate_start_call(node)
23
- if analyzing_schema(node)
24
- if creating_table(node)
25
- @current_table = create_table_name(node)
26
- end
27
-
28
- if creating_foreign_key(node)
29
- @foreign_keys[@current_table] ||= []
30
- @foreign_keys[@current_table] << foreign_key_column_name(node)
31
- end
32
-
33
- if adding_index(node)
34
- @indexes[index_table_name(node)] ||= []
35
- @indexes[index_table_name(node)] << index_column_name(node)
36
- end
37
- end
38
- end
39
-
40
- def evaluate_end_call(node)
41
- #ignored
42
- end
43
-
44
- def analyzing_schema(node)
45
- pathname = Pathname.new(node.file)
46
- @analyzing_schema ||= ("schema.rb" == pathname.basename.to_s)
47
- end
48
-
49
- def creating_table(node)
50
- :create_table == node[2]
51
- end
52
-
53
- def create_table_name(node)
54
- # Get table name out of this:
55
- # s(:call, nil, :create_table, s(:arglist, s(:str, "duplicate_blocks"), s(:hash, s(:lit, :force), s(:true))))
56
- node[3][1][1]
57
- end
58
-
59
- def creating_foreign_key(node)
60
- #s(:call, s(:lvar, :t), :integer, s(:arglist, s(:str, "duplicate_set_id"), s(:hash, s(:lit, :null), s(:false))))
61
- column_type = node[2]
62
- column_name = node[3][1][1]
63
- :integer == column_type && "_id" == column_name[-3,3]
64
- end
65
-
66
- def foreign_key_column_name(node)
67
- #s(:call, s(:lvar, :t), :integer, s(:arglist, s(:str, "duplicate_set_id"), s(:hash, s(:lit, :null), s(:false))))
68
- column_name = node[3][1][1]
69
- end
70
-
71
- def adding_index(node)
72
- :add_index == node[2]
73
- end
74
-
75
- def index_table_name(node)
76
- # Get table name out of this:
77
- # s(:call, nil, :add_index, s(:arglist, s(:str, "duplicate_blocks"), s(:array, s(:str, "duplicate_set_id")), s(:hash, s(:lit, :name), s(:str, "index_duplicate_blocks_on_duplicate_set_id"))))
78
- node[3][1][1]
79
- end
80
-
81
- def index_column_name(node)
82
- # Get index column name out of this:
83
- # s(:call, nil, :add_index, s(:arglist, s(:str, "duplicate_blocks"), s(:array, s(:str, "duplicate_set_id")), s(:hash, s(:lit, :name), s(:str, "index_duplicate_blocks_on_duplicate_set_id"))))
84
- node[3][2][1][1]
85
- end
86
-
87
- def end_file(filename)
88
- @foreign_keys.keys.each do |table|
89
- foreign_keys = @foreign_keys[table] || []
90
- indexes = @indexes[table] || []
91
- missing_indexes = foreign_keys - indexes
92
- missing_indexes.each do |fkey|
93
- add_error("Table '#{table}' is missing an index on the foreign key '#{fkey}'", filename, 1)
94
- end
95
- end
96
- end
97
- end
98
- end
99
- end
@@ -1,28 +0,0 @@
1
- require 'roodi/checks/line_count_check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks a module to make sure the number of lines it has is under the specified limit.
6
- #
7
- # A module 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 modules.
9
- class ModuleLineCountCheck < 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
- [:module]
20
- end
21
-
22
- def message_prefix
23
- 'Module'
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 module name to make sure it matches the specified pattern.
6
- #
7
- # Keeping to a consistent nameing convention makes your code easier to read.
8
- class ModuleNameCheck < 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
- [:module]
19
- end
20
-
21
- def message_prefix
22
- 'Module'
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,16 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- class NameCheck < Check
6
-
7
- attr_accessor :pattern
8
-
9
- def evaluate_start(node)
10
- name = find_name(node)
11
- add_error "#{message_prefix} name \"#{name}\" should match pattern #{@pattern.inspect}" unless name.to_s =~ @pattern
12
- end
13
-
14
- end
15
- end
16
- end
@@ -1,75 +0,0 @@
1
- require 'roodi/checks/check'
2
-
3
- module Roodi
4
- module Checks
5
- class NpathComplexityCheck < Check
6
- # , :when, :and, :or
7
- MULTIPLYING_NODE_TYPES = [:if, :while, :until, :for, :case]
8
- ADDING_NODE_TYPES = [:rescue]
9
- COMPLEXITY_NODE_TYPES = MULTIPLYING_NODE_TYPES + ADDING_NODE_TYPES
10
-
11
- attr_accessor :complexity
12
-
13
- def initialize(complexity)
14
- super()
15
- @complexity = complexity
16
- @value_stack = []
17
- @current_value = 1
18
- end
19
-
20
- def evalute_start_if(node)
21
- push_value
22
- end
23
-
24
- def evalute_start_while(node)
25
- push_value
26
- end
27
-
28
- def evalute_start_until(node)
29
- push_value
30
- end
31
-
32
- def evalute_start_for(node)
33
- push_value
34
- end
35
-
36
- def evalute_start_case(node)
37
- push_value
38
- end
39
-
40
- def evalute_start_rescue(node)
41
- push_value
42
- end
43
-
44
- MULTIPLYING_NODE_TYPES.each do |type|
45
- define_method "evaluate_end_#{type}" do |node|
46
- leave_multiplying_conditional
47
- end
48
- end
49
-
50
- ADDING_NODE_TYPES.each do |type|
51
- define_method "evaluate_end_#{type}" do |node|
52
- leave_multiplying_conditional
53
- end
54
- end
55
-
56
- protected
57
-
58
- def push_value
59
- @value_stack.push @current_value
60
- @current_value = 1
61
- end
62
-
63
- def leave_multiplying_conditional
64
- pop = @value_stack.pop
65
- @current_value = (@current_value + 1) * pop
66
- end
67
-
68
- def leave_adding_conditional
69
- pop = @value_stack.pop
70
- puts "#{type}, so adding #{pop}"
71
- @current_value = @current_value - 1 + pop
72
- end
73
- end
74
- end
75
- end
@@ -1,29 +0,0 @@
1
- require 'roodi/checks/npath_complexity_check'
2
-
3
- module Roodi
4
- module Checks
5
- # Checks Npath complexity of a method against a specified limit.
6
- class NpathComplexityMethodCheck < NpathComplexityCheck
7
-
8
- DEFAULT_COMPLEXITY = 8
9
-
10
- def initialize
11
- super(DEFAULT_COMPLEXITY)
12
- end
13
-
14
- def interesting_nodes
15
- [:defn] + COMPLEXITY_NODE_TYPES
16
- end
17
-
18
- def evaluate_start_defn(node)
19
- @method_name = @node[1]
20
- push_value
21
- end
22
-
23
- def evaluate_end_defn(node)
24
- add_error "Method name \"#{@method_name}\" n-path complexity is #{@current_value}. It should be #{@complexity} or less." unless @current_value <= @complexity
25
- end
26
-
27
- end
28
- end
29
- end