simplabs-excellent 1.0.1 → 1.2.1
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.
- data/History.txt +19 -0
- data/README.rdoc +34 -0
- data/VERSION.yml +1 -1
- data/bin/excellent +21 -6
- data/lib/simplabs/excellent.rb +7 -5
- data/lib/simplabs/excellent/checks.rb +18 -1
- data/lib/simplabs/excellent/checks/abc_metric_method_check.rb +19 -56
- data/lib/simplabs/excellent/checks/assignment_in_conditional_check.rb +16 -16
- data/lib/simplabs/excellent/checks/base.rb +30 -21
- data/lib/simplabs/excellent/checks/case_missing_else_check.rb +13 -5
- data/lib/simplabs/excellent/checks/class_line_count_check.rb +10 -8
- data/lib/simplabs/excellent/checks/class_name_check.rb +11 -10
- data/lib/simplabs/excellent/checks/control_coupling_check.rb +13 -10
- data/lib/simplabs/excellent/checks/cyclomatic_complexity_block_check.rb +25 -9
- data/lib/simplabs/excellent/checks/cyclomatic_complexity_check.rb +4 -20
- data/lib/simplabs/excellent/checks/cyclomatic_complexity_method_check.rb +25 -10
- data/lib/simplabs/excellent/checks/duplication_check.rb +50 -0
- data/lib/simplabs/excellent/checks/empty_rescue_body_check.rb +10 -18
- data/lib/simplabs/excellent/checks/flog_block_check.rb +40 -0
- data/lib/simplabs/excellent/checks/flog_check.rb +27 -0
- data/lib/simplabs/excellent/checks/flog_class_check.rb +40 -0
- data/lib/simplabs/excellent/checks/flog_method_check.rb +40 -0
- data/lib/simplabs/excellent/checks/for_loop_check.rb +20 -4
- data/lib/simplabs/excellent/checks/line_count_check.rb +3 -21
- data/lib/simplabs/excellent/checks/method_line_count_check.rb +9 -7
- data/lib/simplabs/excellent/checks/method_name_check.rb +13 -9
- data/lib/simplabs/excellent/checks/module_line_count_check.rb +9 -7
- data/lib/simplabs/excellent/checks/module_name_check.rb +11 -7
- data/lib/simplabs/excellent/checks/name_check.rb +3 -8
- data/lib/simplabs/excellent/checks/nested_iterators_check.rb +33 -0
- data/lib/simplabs/excellent/checks/parameter_number_check.rb +13 -12
- data/lib/simplabs/excellent/checks/rails.rb +17 -0
- data/lib/simplabs/excellent/checks/rails/attr_accessible_check.rb +38 -0
- data/lib/simplabs/excellent/checks/rails/attr_protected_check.rb +39 -0
- data/lib/simplabs/excellent/checks/singleton_variable_check.rb +32 -0
- data/lib/simplabs/excellent/extensions/sexp.rb +21 -0
- data/lib/simplabs/excellent/extensions/string.rb +23 -0
- data/lib/simplabs/excellent/parsing.rb +12 -0
- data/lib/simplabs/excellent/parsing/abc_measure.rb +52 -0
- data/lib/simplabs/excellent/parsing/block_context.rb +43 -0
- data/lib/simplabs/excellent/parsing/call_context.rb +36 -0
- data/lib/simplabs/excellent/parsing/case_context.rb +31 -0
- data/lib/simplabs/excellent/parsing/class_context.rb +68 -0
- data/lib/simplabs/excellent/parsing/code_processor.rb +154 -0
- data/lib/simplabs/excellent/parsing/conditional_context.rb +25 -0
- data/lib/simplabs/excellent/parsing/cvar_context.rb +28 -0
- data/lib/simplabs/excellent/parsing/cyclomatic_complexity_measure.rb +73 -0
- data/lib/simplabs/excellent/parsing/flog_measure.rb +192 -0
- data/lib/simplabs/excellent/parsing/for_loop_context.rb +15 -0
- data/lib/simplabs/excellent/parsing/if_context.rb +38 -0
- data/lib/simplabs/excellent/parsing/method_context.rb +50 -0
- data/lib/simplabs/excellent/parsing/module_context.rb +29 -0
- data/lib/simplabs/excellent/{core → parsing}/parser.rb +4 -2
- data/lib/simplabs/excellent/parsing/resbody_context.rb +39 -0
- data/lib/simplabs/excellent/parsing/scopeable.rb +34 -0
- data/lib/simplabs/excellent/parsing/sexp_context.rb +125 -0
- data/lib/simplabs/excellent/parsing/singleton_method_context.rb +55 -0
- data/lib/simplabs/excellent/parsing/until_context.rb +24 -0
- data/lib/simplabs/excellent/parsing/while_context.rb +24 -0
- data/lib/simplabs/excellent/runner.rb +105 -0
- data/lib/simplabs/excellent/warning.rb +53 -0
- data/spec/checks/abc_metric_method_check_spec.rb +36 -8
- data/spec/checks/assignment_in_conditional_check_spec.rb +31 -14
- data/spec/checks/case_missing_else_check_spec.rb +8 -8
- data/spec/checks/class_line_count_check_spec.rb +24 -11
- data/spec/checks/class_name_check_spec.rb +9 -9
- data/spec/checks/control_coupling_check_spec.rb +84 -13
- data/spec/checks/cyclomatic_complexity_block_check_spec.rb +13 -17
- data/spec/checks/cyclomatic_complexity_method_check_spec.rb +32 -6
- data/spec/checks/duplication_check_spec.rb +139 -0
- data/spec/checks/empty_rescue_body_check_spec.rb +54 -16
- data/spec/checks/flog_block_check_spec.rb +28 -0
- data/spec/checks/flog_class_check_spec.rb +28 -0
- data/spec/checks/flog_method_check_spec.rb +46 -0
- data/spec/checks/for_loop_check_spec.rb +11 -11
- data/spec/checks/method_line_count_check_spec.rb +11 -12
- data/spec/checks/method_name_check_spec.rb +34 -13
- data/spec/checks/module_line_count_check_spec.rb +11 -12
- data/spec/checks/module_name_check_spec.rb +31 -7
- data/spec/checks/nested_iterators_check_spec.rb +44 -0
- data/spec/checks/parameter_number_check_spec.rb +48 -12
- data/spec/checks/rails/attr_accessible_check_spec.rb +79 -0
- data/spec/checks/rails/attr_protected_check_spec.rb +77 -0
- data/spec/checks/singleton_variable_check_spec.rb +66 -0
- data/spec/{core/extensions/underscore_spec.rb → extensions/string_spec.rb} +1 -1
- metadata +58 -15
- data/README.markdown +0 -30
- data/lib/simplabs/excellent/checks/class_variable_check.rb +0 -25
- data/lib/simplabs/excellent/core.rb +0 -2
- data/lib/simplabs/excellent/core/checking_visitor.rb +0 -34
- data/lib/simplabs/excellent/core/error.rb +0 -31
- data/lib/simplabs/excellent/core/extensions/underscore.rb +0 -27
- data/lib/simplabs/excellent/core/iterator_visitor.rb +0 -29
- data/lib/simplabs/excellent/core/parse_tree_runner.rb +0 -88
- data/lib/simplabs/excellent/core/visitable_sexp.rb +0 -31
- data/spec/checks/class_variable_check_spec.rb +0 -26
data/History.txt
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
= 1.2.1
|
2
|
+
|
3
|
+
* renamed Error to Warning
|
4
|
+
* added documentation
|
5
|
+
|
6
|
+
= 1.2.0
|
7
|
+
|
8
|
+
* cleanup
|
9
|
+
* added 2 Rails specific checks, AttrAccessibleCheck and AttrProtectedCheck
|
10
|
+
|
11
|
+
= 1.1.0
|
12
|
+
|
13
|
+
* completely restructured, made everything running in the flow of the SexpProcessor
|
14
|
+
* added most tests from reek (except for UtilityFunction and FeatureEnvy)
|
15
|
+
|
16
|
+
= 1.0.1
|
17
|
+
|
18
|
+
* fixed some errors
|
19
|
+
|
1
20
|
= 1.0.0
|
2
21
|
|
3
22
|
* this is basically just a custom version of roodi, converted to ruby_parser to be 1.9 safe
|
data/README.rdoc
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
= Excellent
|
2
|
+
|
3
|
+
Excellent detects commonly regarded bad code snippets like empty +rescue+ blocks etc. It combines roodi (http://github.com/martinjandrews/roodi), most checks of reek (http://github.com/kevinrutherford/reek), flog (http://github.com/seattlerb/flog) and also adds some Rails specific checks.
|
4
|
+
|
5
|
+
See the API documentation at http://docs.github.com/simplabs/excellent and the WIKI at http://wiki.github.com/simplabs/excellent.
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
Simply install with Ruby Gems:
|
10
|
+
|
11
|
+
gem sources -a http://gems.github.com
|
12
|
+
sudo gem install simplabs-excellent
|
13
|
+
|
14
|
+
== Example
|
15
|
+
|
16
|
+
To analyse all the models in your Rails application, just do
|
17
|
+
|
18
|
+
excellent app/models
|
19
|
+
|
20
|
+
in your <tt>RAILS_ROOT</tt>. You can also invoke analysation through the Simplabs::Excellent::Runner class.
|
21
|
+
|
22
|
+
== Static analysis
|
23
|
+
|
24
|
+
A few words regarding static code analysis: Static code analysis tools like Excellent can never really understand the code. They just search for patterns that *might* inidicate problematic code. The word *might* really has to be stressed here since static analysis will usually return a reasonable number of false positives. For example, there might be pretty good reasons for empty +rescue+ blocks that suppress all errors (Excellent itself does it). So, don't try and code with the aim of passing Excellent with zero warnings. That will most likely make your code a mess. Instead use Excellent as a helper to find *possibly* problematic code early.
|
25
|
+
|
26
|
+
== Contribute
|
27
|
+
|
28
|
+
If you want to contribute, just fork the repo. Also I would appretiate suggestions for more checks (especially Rails specific checks) - simply open a new issue: http://github.com/simplabs/excellent/issues.
|
29
|
+
|
30
|
+
== Author
|
31
|
+
|
32
|
+
Copyright (c) 2008-2009 Marco Otte-Witte (http://simplabs.com), released under the MIT license.
|
33
|
+
|
34
|
+
Excellent was inspired by and is in parts based on roodi (http://github.com/martinjandrews/roodi), reek (http://github.com/kevinrutherford/reek) and flog (http://github.com/seattlerb/flog).
|
data/VERSION.yml
CHANGED
data/bin/excellent
CHANGED
@@ -5,16 +5,31 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
|
|
5
5
|
require 'simplabs/excellent'
|
6
6
|
require 'pathname'
|
7
7
|
|
8
|
-
excellent = Simplabs::Excellent::
|
8
|
+
excellent = Simplabs::Excellent::Runner.new
|
9
|
+
|
10
|
+
if ARGV.empty?
|
11
|
+
puts "\n You must specify one or more directories to analyse, e.g.:\n"
|
12
|
+
puts "\n excellent app/\n\n"
|
13
|
+
exit 1
|
14
|
+
end
|
9
15
|
|
10
16
|
ARGV.each do |arg|
|
11
|
-
|
17
|
+
if File.file?(arg)
|
18
|
+
excellent.check_file(arg)
|
19
|
+
elsif File.directory?(arg)
|
20
|
+
Dir.glob("#{arg}/**/*.rb").each { |file| excellent.check_file(file) }
|
21
|
+
else
|
22
|
+
puts "\n** Excellent cannot find '#{arg}'\n\n"
|
23
|
+
exit 1
|
24
|
+
end
|
12
25
|
end
|
13
26
|
|
14
|
-
|
15
|
-
|
16
|
-
|
27
|
+
unless excellent.warnings.empty?
|
28
|
+
puts "\n Warnings:\n\n"
|
29
|
+
excellent.warnings.each do |warning|
|
30
|
+
puts " * File #{warning.filename}, line #{warning.line_number}: #{warning.message}"
|
31
|
+
end
|
17
32
|
end
|
18
|
-
puts
|
33
|
+
puts "\n Found #{excellent.warnings.size} warnings.\n\n"
|
19
34
|
|
20
35
|
exit 0
|
data/lib/simplabs/excellent.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'simplabs/excellent/checks'
|
2
|
-
require 'simplabs/excellent/
|
2
|
+
require 'simplabs/excellent/parsing'
|
3
3
|
require 'rubygems'
|
4
4
|
require 'sexp'
|
5
5
|
|
6
|
-
module
|
6
|
+
module Simplabs #:nodoc:
|
7
7
|
|
8
|
-
|
8
|
+
module Excellent #:nodoc:
|
9
9
|
|
10
|
-
|
10
|
+
VERSION = '1.2.0'
|
11
|
+
|
12
|
+
end
|
11
13
|
|
12
|
-
|
14
|
+
end
|
@@ -1,9 +1,20 @@
|
|
1
|
+
module Simplabs
|
2
|
+
|
3
|
+
module Excellent
|
4
|
+
|
5
|
+
module Checks #:nodoc:
|
6
|
+
end
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
1
12
|
require 'simplabs/excellent/checks/abc_metric_method_check'
|
2
13
|
require 'simplabs/excellent/checks/assignment_in_conditional_check'
|
3
14
|
require 'simplabs/excellent/checks/case_missing_else_check'
|
4
15
|
require 'simplabs/excellent/checks/class_line_count_check'
|
5
16
|
require 'simplabs/excellent/checks/class_name_check'
|
6
|
-
require 'simplabs/excellent/checks/
|
17
|
+
require 'simplabs/excellent/checks/singleton_variable_check'
|
7
18
|
require 'simplabs/excellent/checks/control_coupling_check'
|
8
19
|
require 'simplabs/excellent/checks/cyclomatic_complexity_block_check'
|
9
20
|
require 'simplabs/excellent/checks/cyclomatic_complexity_method_check'
|
@@ -14,3 +25,9 @@ require 'simplabs/excellent/checks/method_name_check'
|
|
14
25
|
require 'simplabs/excellent/checks/module_line_count_check'
|
15
26
|
require 'simplabs/excellent/checks/module_name_check'
|
16
27
|
require 'simplabs/excellent/checks/parameter_number_check'
|
28
|
+
require 'simplabs/excellent/checks/duplication_check'
|
29
|
+
require 'simplabs/excellent/checks/nested_iterators_check'
|
30
|
+
require 'simplabs/excellent/checks/flog_method_check'
|
31
|
+
require 'simplabs/excellent/checks/flog_block_check'
|
32
|
+
require 'simplabs/excellent/checks/flog_class_check'
|
33
|
+
require 'simplabs/excellent/checks/rails'
|
@@ -6,70 +6,33 @@ module Simplabs
|
|
6
6
|
|
7
7
|
module Checks
|
8
8
|
|
9
|
+
# This check reports methods with an ABC metric score that is higher than the threshold. The ABC metric is basically a measure for complexity
|
10
|
+
# and is calculated as:
|
11
|
+
#
|
12
|
+
# a = number of assignments
|
13
|
+
# b = number of branches
|
14
|
+
# c = number of conditions
|
15
|
+
#
|
16
|
+
# score = Math.sqrt(a*a + b*b + c*c)
|
17
|
+
#
|
18
|
+
# ==== Applies to
|
19
|
+
#
|
20
|
+
# * methods
|
9
21
|
class AbcMetricMethodCheck < Base
|
10
22
|
|
11
|
-
ASSIGNMENTS = [:lasgn]
|
12
|
-
BRANCHES = [:vcall, :call]
|
13
|
-
CONDITIONS = [:==, :<=, :>=, :<, :>]
|
14
|
-
OPERATORS = [:*, :/, :%, :+, :<<, :>>, :&, :|, :^, :-, :**]
|
15
23
|
DEFAULT_THRESHOLD = 10
|
16
24
|
|
17
|
-
def initialize(options = {})
|
25
|
+
def initialize(options = {}) #:nodoc:
|
18
26
|
super()
|
19
|
-
@threshold
|
27
|
+
@threshold = options[:threshold] || DEFAULT_THRESHOLD
|
28
|
+
@interesting_nodes = [:defn, :defs]
|
20
29
|
end
|
21
30
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def evaluate(node)
|
27
|
-
method_name = node[1]
|
28
|
-
a = count_assignments(node)
|
29
|
-
b = count_branches(node)
|
30
|
-
c = count_conditionals(node)
|
31
|
-
score = Math.sqrt(a*a + b*b + c*c)
|
32
|
-
add_error('Method {{method}} has abc score of {{score}}.', { :method => method_name, :score => score }) unless score <= @threshold
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def count_assignments(node)
|
38
|
-
count = 0
|
39
|
-
count = count + 1 if assignment?(node)
|
40
|
-
node.children.each { |node| count += count_assignments(node) }
|
41
|
-
count
|
42
|
-
end
|
43
|
-
|
44
|
-
def count_branches(node)
|
45
|
-
count = 0
|
46
|
-
count = count + 1 if branch?(node)
|
47
|
-
node.children.each { |node| count += count_branches(node) }
|
48
|
-
count
|
49
|
-
end
|
50
|
-
|
51
|
-
def count_conditionals(node)
|
52
|
-
count = 0
|
53
|
-
count = count + 1 if conditional?(node)
|
54
|
-
node.children.each { |node| count += count_conditionals(node) }
|
55
|
-
count
|
31
|
+
def evaluate(context) #:nodoc:
|
32
|
+
unless context.abc_score <= @threshold
|
33
|
+
add_warning(context, '{{method}} has abc score of {{score}}.', { :method => context.full_name, :score => context.abc_score })
|
56
34
|
end
|
57
|
-
|
58
|
-
def assignment?(node)
|
59
|
-
ASSIGNMENTS.include?(node.node_type)
|
60
|
-
end
|
61
|
-
|
62
|
-
def branch?(node)
|
63
|
-
BRANCHES.include?(node.node_type) && !conditional?(node) && !operator?(node)
|
64
|
-
end
|
65
|
-
|
66
|
-
def conditional?(node)
|
67
|
-
(:call == node.node_type) && CONDITIONS.include?(node[2])
|
68
|
-
end
|
69
|
-
|
70
|
-
def operator?(node)
|
71
|
-
(:call == node.node_type) && OPERATORS.include?(node[2])
|
72
|
-
end
|
35
|
+
end
|
73
36
|
|
74
37
|
end
|
75
38
|
|
@@ -6,29 +6,29 @@ module Simplabs
|
|
6
6
|
|
7
7
|
module Checks
|
8
8
|
|
9
|
+
# This check reports conditionals that test an assignment as in
|
10
|
+
#
|
11
|
+
# something(var) if var = method()
|
12
|
+
#
|
13
|
+
# Assignments in conditions are often typos.
|
14
|
+
#
|
15
|
+
# ==== Applies to
|
16
|
+
#
|
17
|
+
# * +if+
|
18
|
+
# * +else+
|
19
|
+
# * +while+
|
20
|
+
# * +until+
|
9
21
|
class AssignmentInConditionalCheck < Base
|
10
22
|
|
11
|
-
def initialize(options = {})
|
23
|
+
def initialize(options = {}) #:nodoc:
|
12
24
|
super()
|
25
|
+
@interesting_nodes = [:if, :while, :until]
|
13
26
|
end
|
14
27
|
|
15
|
-
def
|
16
|
-
|
28
|
+
def evaluate(context) #:nodoc:
|
29
|
+
add_warning(context, 'Assignment in condition.') if context.tests_assignment?
|
17
30
|
end
|
18
31
|
|
19
|
-
def evaluate(node)
|
20
|
-
add_error('Assignment in condition.') if has_assignment?(node[1])
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def has_assignment?(node)
|
26
|
-
found_assignment = false
|
27
|
-
found_assignment = found_assignment || node.node_type == :lasgn
|
28
|
-
node.children.each { |child| found_assignment = found_assignment || has_assignment?(child) }
|
29
|
-
found_assignment
|
30
|
-
end
|
31
|
-
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'simplabs/excellent/
|
1
|
+
require 'simplabs/excellent/warning'
|
2
2
|
|
3
3
|
module Simplabs
|
4
4
|
|
@@ -6,33 +6,42 @@ module Simplabs
|
|
6
6
|
|
7
7
|
module Checks
|
8
8
|
|
9
|
+
# This is the base class for all code checks. All checks must specify +interesting_nodes+. When one of these nodes is processed by Excellent, it
|
10
|
+
# will invoke the +evaluate_node+ method of all checks that specify the node as one if their +interesting_nodes+.
|
9
11
|
class Base
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
attr_reader :warnings
|
14
|
+
|
15
|
+
# An array of node types that are interesting for the check. These are symbols as returned by RubyParser (see http://parsetree.rubyforge.org/ruby_parser/),
|
16
|
+
# e.g. <tt>:if</tt> or <tt>:defn</tt>
|
17
|
+
attr_reader :interesting_nodes
|
18
|
+
|
19
|
+
def initialize #:nodoc:
|
20
|
+
@warnings = []
|
17
21
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
|
23
|
+
# This method is called whenever Excellent processes a node that the check specified as one of the nodes it is interested in (see interesting_nodes).
|
24
|
+
#
|
25
|
+
# ==== Parameters
|
26
|
+
#
|
27
|
+
# * <tt>context</tt> - This is the last context the code processor has constructed. It contains all information required to execute the check (see Simplabs::Excellent::Parsing::SexpContext).
|
28
|
+
def evaluate_node(context)
|
29
|
+
evaluate(context)
|
25
30
|
end
|
26
|
-
|
27
|
-
|
31
|
+
|
32
|
+
# Adds a warning
|
33
|
+
#
|
34
|
+
# ==== Parameters
|
35
|
+
#
|
36
|
+
# * <tt>context</tt> - The context the check has been executed on.
|
37
|
+
# * <tt>message</tt> - The warning message.
|
38
|
+
# * <tt>info</tt> - The information hash that contains more info on the finding.
|
39
|
+
# * <tt>offset</tt> - The line offset that is added to the context's line property.
|
40
|
+
def add_warning(context, message, info = {}, offset = 0)
|
28
41
|
klass = self.class
|
29
|
-
@
|
42
|
+
@warnings << Simplabs::Excellent::Warning.new(klass, message, context.file, context.line + offset, info)
|
30
43
|
end
|
31
44
|
|
32
|
-
def errors
|
33
|
-
@errors
|
34
|
-
end
|
35
|
-
|
36
45
|
end
|
37
46
|
|
38
47
|
end
|
@@ -6,14 +6,22 @@ module Simplabs
|
|
6
6
|
|
7
7
|
module Checks
|
8
8
|
|
9
|
+
# This check reports +case+ statements that don't have an +else+ clause that would be executed when no case matches. If the tested value will never
|
10
|
+
# adopt any other values than the ones tested for in the cases, this should be expressed in the code by e.g. throwing an exception in the +else+
|
11
|
+
# clause.
|
12
|
+
#
|
13
|
+
# ==== Applies to
|
14
|
+
#
|
15
|
+
# * +case+ statements
|
9
16
|
class CaseMissingElseCheck < Base
|
10
17
|
|
11
|
-
def
|
12
|
-
|
18
|
+
def initialize #:nodoc:
|
19
|
+
super
|
20
|
+
@interesting_nodes = [:case]
|
13
21
|
end
|
14
|
-
|
15
|
-
def evaluate(
|
16
|
-
|
22
|
+
|
23
|
+
def evaluate(context) #:nodoc:
|
24
|
+
add_warning(context, 'Case statement is missing else clause.') unless context.has_else_clause?
|
17
25
|
end
|
18
26
|
|
19
27
|
end
|
@@ -6,23 +6,25 @@ module Simplabs
|
|
6
6
|
|
7
7
|
module Checks
|
8
8
|
|
9
|
+
# This check reports classes which have more lines than the threshold. Classes with a large number of lines are hard to read and understand and
|
10
|
+
# often an indicator for badly designed code as well.
|
11
|
+
#
|
12
|
+
# ==== Applies to
|
13
|
+
#
|
14
|
+
# * classes
|
9
15
|
class ClassLineCountCheck < LineCountCheck
|
10
16
|
|
11
|
-
DEFAULT_THRESHOLD =
|
17
|
+
DEFAULT_THRESHOLD = 400
|
12
18
|
|
13
|
-
def initialize(options = {})
|
19
|
+
def initialize(options = {}) #:nodoc:
|
14
20
|
threshold = options[:threshold] || DEFAULT_THRESHOLD
|
15
21
|
super([:class], threshold)
|
16
22
|
end
|
17
23
|
|
18
24
|
protected
|
19
25
|
|
20
|
-
def
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def error_args(node, line_count)
|
25
|
-
['Class {{class}} has {{count}} lines.', { :class => node[1], :count => line_count }]
|
26
|
+
def warning_args(context) #:nodoc:
|
27
|
+
[context, '{{class}} has {{count}} lines.', { :class => context.full_name, :count => context.line_count }]
|
26
28
|
end
|
27
29
|
|
28
30
|
end
|
@@ -6,26 +6,27 @@ module Simplabs
|
|
6
6
|
|
7
7
|
module Checks
|
8
8
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
9
|
+
# This check reports classes with bad names. Badly named classes make reading and understanding the code much harder. Class names regarded as bad
|
10
|
+
# are for example:
|
11
|
+
#
|
12
|
+
# * names that are not Pascal cased (camel cased, starting with an upper case letter)
|
13
|
+
#
|
14
|
+
# ==== Applies to
|
15
|
+
#
|
16
|
+
# * classes
|
12
17
|
class ClassNameCheck < NameCheck
|
13
18
|
|
14
19
|
DEFAULT_PATTERN = /^[A-Z]{1}[a-zA-Z0-9]*$/
|
15
20
|
|
16
|
-
def initialize(options = {})
|
21
|
+
def initialize(options = {}) #:nodoc:
|
17
22
|
pattern = options[:pattern] || DEFAULT_PATTERN
|
18
23
|
super([:class], pattern)
|
19
24
|
end
|
20
25
|
|
21
|
-
def find_name(node)
|
22
|
-
node[1].class == Symbol ? node[1] : node[1].last
|
23
|
-
end
|
24
|
-
|
25
26
|
protected
|
26
27
|
|
27
|
-
def
|
28
|
-
['Bad class name {{class}}.', { :class =>
|
28
|
+
def warning_args(context) #:nodoc:
|
29
|
+
[context, 'Bad class name {{class}}.', { :class => context.full_name }]
|
29
30
|
end
|
30
31
|
|
31
32
|
end
|