excellent 1.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +69 -0
- data/README.rdoc +72 -0
- data/VERSION.yml +4 -0
- data/bin/excellent +34 -0
- data/lib/simplabs/excellent.rb +16 -0
- data/lib/simplabs/excellent/checks.rb +33 -0
- data/lib/simplabs/excellent/checks/abc_metric_method_check.rb +43 -0
- data/lib/simplabs/excellent/checks/assignment_in_conditional_check.rb +39 -0
- data/lib/simplabs/excellent/checks/base.rb +62 -0
- data/lib/simplabs/excellent/checks/case_missing_else_check.rb +34 -0
- data/lib/simplabs/excellent/checks/class_line_count_check.rb +36 -0
- data/lib/simplabs/excellent/checks/class_name_check.rb +38 -0
- data/lib/simplabs/excellent/checks/control_coupling_check.rb +35 -0
- data/lib/simplabs/excellent/checks/cyclomatic_complexity_block_check.rb +48 -0
- data/lib/simplabs/excellent/checks/cyclomatic_complexity_check.rb +23 -0
- data/lib/simplabs/excellent/checks/cyclomatic_complexity_method_check.rb +48 -0
- data/lib/simplabs/excellent/checks/empty_rescue_body_check.rb +31 -0
- 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 +42 -0
- data/lib/simplabs/excellent/checks/global_variable_check.rb +33 -0
- data/lib/simplabs/excellent/checks/line_count_check.rb +27 -0
- data/lib/simplabs/excellent/checks/method_line_count_check.rb +36 -0
- data/lib/simplabs/excellent/checks/method_name_check.rb +38 -0
- data/lib/simplabs/excellent/checks/module_line_count_check.rb +36 -0
- data/lib/simplabs/excellent/checks/module_name_check.rb +38 -0
- data/lib/simplabs/excellent/checks/name_check.rb +27 -0
- data/lib/simplabs/excellent/checks/nested_iterators_check.rb +34 -0
- data/lib/simplabs/excellent/checks/parameter_number_check.rb +38 -0
- data/lib/simplabs/excellent/checks/rails.rb +22 -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/rails/custom_initialize_method_check.rb +37 -0
- data/lib/simplabs/excellent/checks/rails/instance_var_in_partial_check.rb +37 -0
- data/lib/simplabs/excellent/checks/rails/params_hash_in_view_check.rb +38 -0
- data/lib/simplabs/excellent/checks/rails/session_hash_in_view_check.rb +38 -0
- data/lib/simplabs/excellent/checks/rails/validations_check.rb +36 -0
- data/lib/simplabs/excellent/checks/singleton_variable_check.rb +33 -0
- data/lib/simplabs/excellent/command_line_runner.rb +37 -0
- data/lib/simplabs/excellent/extensions/sexp.rb +21 -0
- data/lib/simplabs/excellent/extensions/string.rb +28 -0
- data/lib/simplabs/excellent/formatters.rb +13 -0
- data/lib/simplabs/excellent/formatters/base.rb +49 -0
- data/lib/simplabs/excellent/formatters/html.rb +153 -0
- data/lib/simplabs/excellent/formatters/text.rb +40 -0
- data/lib/simplabs/excellent/parsing.rb +10 -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 +52 -0
- data/lib/simplabs/excellent/parsing/case_context.rb +31 -0
- data/lib/simplabs/excellent/parsing/class_context.rb +99 -0
- data/lib/simplabs/excellent/parsing/code_processor.rb +165 -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/gvar_context.rb +21 -0
- data/lib/simplabs/excellent/parsing/if_context.rb +38 -0
- data/lib/simplabs/excellent/parsing/ivar_context.rb +32 -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/parsing/parser.rb +35 -0
- 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/rake.rb +1 -0
- data/lib/simplabs/excellent/rake/excellent_task.rb +61 -0
- data/lib/simplabs/excellent/runner.rb +143 -0
- data/lib/simplabs/excellent/warning.rb +53 -0
- data/spec/checks/abc_metric_method_check_spec.rb +122 -0
- data/spec/checks/assignment_in_conditional_check_spec.rb +90 -0
- data/spec/checks/case_missing_else_check_spec.rb +42 -0
- data/spec/checks/class_line_count_check_spec.rb +62 -0
- data/spec/checks/class_name_check_spec.rb +48 -0
- data/spec/checks/control_coupling_check_spec.rb +103 -0
- data/spec/checks/cyclomatic_complexity_block_check_spec.rb +47 -0
- data/spec/checks/cyclomatic_complexity_method_check_spec.rb +210 -0
- data/spec/checks/empty_rescue_body_check_spec.rb +170 -0
- 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 +52 -0
- data/spec/checks/global_variable_check_spec.rb +66 -0
- data/spec/checks/method_line_count_check_spec.rb +49 -0
- data/spec/checks/method_name_check_spec.rb +112 -0
- data/spec/checks/module_line_count_check_spec.rb +48 -0
- data/spec/checks/module_name_check_spec.rb +61 -0
- data/spec/checks/nested_iterators_check_spec.rb +44 -0
- data/spec/checks/parameter_number_check_spec.rb +97 -0
- 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/rails/custom_initialize_method_check_spec.rb +58 -0
- data/spec/checks/rails/instance_var_in_partial_check_spec.rb +40 -0
- data/spec/checks/rails/params_hash_in_view_check_spec.rb +40 -0
- data/spec/checks/rails/session_hash_in_view_check_spec.rb +40 -0
- data/spec/checks/rails/validations_check_spec.rb +81 -0
- data/spec/checks/singleton_variable_check_spec.rb +66 -0
- data/spec/extensions/string_spec.rb +13 -0
- data/spec/spec_helper.rb +13 -0
- metadata +189 -0
data/History.txt
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
= 1.5.4
|
2
|
+
|
3
|
+
* fixed handling of parser errors
|
4
|
+
|
5
|
+
= 1.5.3
|
6
|
+
|
7
|
+
* added missing dependency to facets gem
|
8
|
+
|
9
|
+
= 1.5.2
|
10
|
+
|
11
|
+
* added GlobalVariableCheck
|
12
|
+
* added Rails::CustomInitializeMethodCheck
|
13
|
+
* added Rails::ParamsHashInViewCheck
|
14
|
+
* added Rails::SessionHashInViewCheck
|
15
|
+
|
16
|
+
= 1.5.1
|
17
|
+
|
18
|
+
* removed duplication checks (they are just too coarse for dynamic languages like Ruby and especially Rails apps where you would call e.g. params all over the place)
|
19
|
+
* added Rails::ValidationsCheck to the default checks
|
20
|
+
|
21
|
+
= 1.5.0
|
22
|
+
|
23
|
+
* new check Rails::ValidationsCheck that reports ActiveRecord models that do not validate anything
|
24
|
+
* added DuplicationCheck to default checks
|
25
|
+
* split DuplicationCheck up into MethodDuplicationCheck and BlockDuplicationCheck
|
26
|
+
|
27
|
+
= 1.4.1
|
28
|
+
|
29
|
+
* added Rake Task (see Rakefile for example)
|
30
|
+
|
31
|
+
= 1.4.0
|
32
|
+
|
33
|
+
* Excellent not parses *.erb files
|
34
|
+
* added new check InstanceVarInPartialCheck
|
35
|
+
|
36
|
+
= 1.3.1
|
37
|
+
|
38
|
+
* FIX (forgot files in gemspec on 1.3.0)
|
39
|
+
|
40
|
+
= 1.3.0
|
41
|
+
|
42
|
+
* added formatters (currently text and HTML formatting is supported, see README)
|
43
|
+
|
44
|
+
= 1.2.2
|
45
|
+
|
46
|
+
* fixed specs
|
47
|
+
|
48
|
+
= 1.2.1
|
49
|
+
|
50
|
+
* renamed Error to Warning
|
51
|
+
* added documentation
|
52
|
+
|
53
|
+
= 1.2.0
|
54
|
+
|
55
|
+
* cleanup
|
56
|
+
* added 2 Rails specific checks, AttrAccessibleCheck and AttrProtectedCheck
|
57
|
+
|
58
|
+
= 1.1.0
|
59
|
+
|
60
|
+
* completely restructured, made everything running in the flow of the SexpProcessor
|
61
|
+
* added most tests from reek (except for UtilityFunction and FeatureEnvy)
|
62
|
+
|
63
|
+
= 1.0.1
|
64
|
+
|
65
|
+
* fixed some errors
|
66
|
+
|
67
|
+
= 1.0.0
|
68
|
+
|
69
|
+
* 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,72 @@
|
|
1
|
+
= Excellent
|
2
|
+
|
3
|
+
Excellent *finds the nasty lines in your code*. It implements a comprehensive set of checks for possibly buggy parts of your app that would *otherwise make it into your repo and eventually to the production server*.
|
4
|
+
|
5
|
+
See the API documentation at http://docs.github.com/simplabs/excellent and the WIKI at http://wiki.github.com/simplabs/excellent.
|
6
|
+
Join the Google Group and discuss about the future and possibilities of Excellent: http://groups.google.com/group/excellent-gem.
|
7
|
+
|
8
|
+
Excellent also has a CI server set up at http://ci.simplabs.com/excellent.
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
Simply install with Ruby Gems:
|
13
|
+
|
14
|
+
gem sources -a http://gems.github.com
|
15
|
+
sudo gem install simplabs-excellent
|
16
|
+
|
17
|
+
== Example
|
18
|
+
|
19
|
+
Assume you have the following class definition,
|
20
|
+
|
21
|
+
class ShoppingBasket < ActiveRecord::Base
|
22
|
+
|
23
|
+
def initialize(items = [])
|
24
|
+
self.items = items
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
then Excellent will report the problems in this piece of code:
|
30
|
+
|
31
|
+
$ excellent shopping_basket.rb
|
32
|
+
|
33
|
+
Excellent result:
|
34
|
+
|
35
|
+
test.rb
|
36
|
+
* Line 1: ShoppingBasket does not validate any attributes.
|
37
|
+
* Line 1: ShoppingBasket defines initialize method.
|
38
|
+
* Line 1: ShoppingBasket does not specify attr_accessible.
|
39
|
+
|
40
|
+
Found 3 warnings.
|
41
|
+
|
42
|
+
To analyse all the models in your Rails application, just do
|
43
|
+
|
44
|
+
excellent app/models
|
45
|
+
|
46
|
+
in your <tt>RAILS_ROOT</tt>. You can also invoke analysation through the Simplabs::Excellent::Runner class. Excellent can also produce HTML output. To
|
47
|
+
get a formatted HTML report, just specify <tt>html:<filename></tt>:
|
48
|
+
|
49
|
+
excellent html:out.html app/models
|
50
|
+
|
51
|
+
You can also use Excellent in a Rake task:
|
52
|
+
|
53
|
+
require 'simplabs/excellent/rake'
|
54
|
+
|
55
|
+
Simplabs::Excellent::Rake::ExcellentTask.new(:excellent) do |t|
|
56
|
+
t.html = 'doc/excellent.html' # optional, if you don't specify html, output will be written to $stdout
|
57
|
+
t.paths = %w(app lib)
|
58
|
+
end
|
59
|
+
|
60
|
+
== Static analysis
|
61
|
+
|
62
|
+
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.
|
63
|
+
|
64
|
+
== Contribute
|
65
|
+
|
66
|
+
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.
|
67
|
+
|
68
|
+
== Author
|
69
|
+
|
70
|
+
Copyright (c) 2008-2009 Marco Otte-Witte (http://simplabs.com), released under the MIT license.
|
71
|
+
|
72
|
+
Excellent was inspired by roodi (http://github.com/martinjandrews/roodi), reek (http://github.com/kevinrutherford/reek) and flog (http://github.com/seattlerb/flog).
|
data/VERSION.yml
ADDED
data/bin/excellent
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
|
4
|
+
|
5
|
+
require 'simplabs/excellent'
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
excellent = Simplabs::Excellent::Runner.new
|
9
|
+
|
10
|
+
if ARGV.first =~ /html:[^\s]+/
|
11
|
+
begin
|
12
|
+
output = File.open(ARGV.first.sub(/html:/, ''), 'w+')
|
13
|
+
formatter = Simplabs::Excellent::Formatters::Html.new(output)
|
14
|
+
ARGV.shift
|
15
|
+
rescue
|
16
|
+
end
|
17
|
+
else
|
18
|
+
formatter = Simplabs::Excellent::Formatters::Text.new
|
19
|
+
end
|
20
|
+
|
21
|
+
if ARGV.empty?
|
22
|
+
puts "\n You must specify one or more directories to analyse, e.g.:\n"
|
23
|
+
puts "\n excellent app/\n\n"
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
excellent.check_paths(ARGV, formatter)
|
29
|
+
rescue ArgumentError
|
30
|
+
puts "\n** Excellent cannot find the paths specified!\n\n"
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
exit 0
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'simplabs/excellent/checks'
|
2
|
+
require 'simplabs/excellent/parsing'
|
3
|
+
require 'simplabs/excellent/formatters'
|
4
|
+
require 'simplabs/excellent/runner'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'sexp'
|
7
|
+
|
8
|
+
module Simplabs #:nodoc:
|
9
|
+
|
10
|
+
module Excellent #:nodoc:
|
11
|
+
|
12
|
+
VERSION = '1.5.1'
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Simplabs
|
2
|
+
|
3
|
+
module Excellent
|
4
|
+
|
5
|
+
module Checks #:nodoc:
|
6
|
+
end
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'simplabs/excellent/checks/abc_metric_method_check'
|
13
|
+
require 'simplabs/excellent/checks/assignment_in_conditional_check'
|
14
|
+
require 'simplabs/excellent/checks/case_missing_else_check'
|
15
|
+
require 'simplabs/excellent/checks/class_line_count_check'
|
16
|
+
require 'simplabs/excellent/checks/class_name_check'
|
17
|
+
require 'simplabs/excellent/checks/singleton_variable_check'
|
18
|
+
require 'simplabs/excellent/checks/global_variable_check'
|
19
|
+
require 'simplabs/excellent/checks/control_coupling_check'
|
20
|
+
require 'simplabs/excellent/checks/cyclomatic_complexity_block_check'
|
21
|
+
require 'simplabs/excellent/checks/cyclomatic_complexity_method_check'
|
22
|
+
require 'simplabs/excellent/checks/empty_rescue_body_check'
|
23
|
+
require 'simplabs/excellent/checks/for_loop_check'
|
24
|
+
require 'simplabs/excellent/checks/method_line_count_check'
|
25
|
+
require 'simplabs/excellent/checks/method_name_check'
|
26
|
+
require 'simplabs/excellent/checks/module_line_count_check'
|
27
|
+
require 'simplabs/excellent/checks/module_name_check'
|
28
|
+
require 'simplabs/excellent/checks/parameter_number_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'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'simplabs/excellent/checks/base'
|
2
|
+
|
3
|
+
module Simplabs
|
4
|
+
|
5
|
+
module Excellent
|
6
|
+
|
7
|
+
module Checks
|
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
|
21
|
+
class AbcMetricMethodCheck < Base
|
22
|
+
|
23
|
+
DEFAULT_THRESHOLD = 10
|
24
|
+
|
25
|
+
def initialize(options = {}) #:nodoc:
|
26
|
+
super()
|
27
|
+
@threshold = options[:threshold] || DEFAULT_THRESHOLD
|
28
|
+
@interesting_nodes = [:defn, :defs]
|
29
|
+
end
|
30
|
+
|
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 })
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'simplabs/excellent/checks/base'
|
2
|
+
|
3
|
+
module Simplabs
|
4
|
+
|
5
|
+
module Excellent
|
6
|
+
|
7
|
+
module Checks
|
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+
|
21
|
+
class AssignmentInConditionalCheck < Base
|
22
|
+
|
23
|
+
def initialize(options = {}) #:nodoc:
|
24
|
+
super()
|
25
|
+
@interesting_nodes = [:if, :while, :until]
|
26
|
+
@interesting_files = [/\.rb$/, /\.erb$/]
|
27
|
+
end
|
28
|
+
|
29
|
+
def evaluate(context) #:nodoc:
|
30
|
+
add_warning(context, 'Assignment in condition.') if context.tests_assignment?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'simplabs/excellent/warning'
|
2
|
+
|
3
|
+
module Simplabs
|
4
|
+
|
5
|
+
module Excellent
|
6
|
+
|
7
|
+
module Checks
|
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+.
|
11
|
+
class Base
|
12
|
+
|
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
|
+
# An array of regular expressions for file names that are interesting for the check. These will usually be path extensions rather than longer
|
20
|
+
# patterns (e.g. *.rb as well as *.erb files or *.rb files only).
|
21
|
+
#
|
22
|
+
# Defaults to /\.rb$/. If you do not specify anything else in custom checks, only *.rb files will be processed
|
23
|
+
attr_reader :interesting_files
|
24
|
+
|
25
|
+
def initialize #:nodoc:
|
26
|
+
@warnings = []
|
27
|
+
@interesting_files = [/\.rb$/]
|
28
|
+
end
|
29
|
+
|
30
|
+
# 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).
|
31
|
+
#
|
32
|
+
# ==== Parameters
|
33
|
+
#
|
34
|
+
# * <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).
|
35
|
+
def evaluate_node(context)
|
36
|
+
evaluate(context)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Adds a warning
|
40
|
+
#
|
41
|
+
# ==== Parameters
|
42
|
+
#
|
43
|
+
# * <tt>context</tt> - The context the check has been executed on.
|
44
|
+
# * <tt>message</tt> - The warning message.
|
45
|
+
# * <tt>info</tt> - The information hash that contains more info on the finding.
|
46
|
+
# * <tt>offset</tt> - The line offset that is added to the context's line property.
|
47
|
+
def add_warning(context, message, info = {}, offset = 0)
|
48
|
+
klass = self.class
|
49
|
+
@warnings << Simplabs::Excellent::Warning.new(klass, message, context.file, context.line + offset, info)
|
50
|
+
end
|
51
|
+
|
52
|
+
def warnings_for(filename) #:nodoc:
|
53
|
+
warnings.select { |warning| warning.filename == filename }
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'simplabs/excellent/checks/base'
|
2
|
+
|
3
|
+
module Simplabs
|
4
|
+
|
5
|
+
module Excellent
|
6
|
+
|
7
|
+
module Checks
|
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
|
16
|
+
class CaseMissingElseCheck < Base
|
17
|
+
|
18
|
+
def initialize #:nodoc:
|
19
|
+
super
|
20
|
+
@interesting_nodes = [:case]
|
21
|
+
@interesting_files = [/\.rb$/, /\.erb$/]
|
22
|
+
end
|
23
|
+
|
24
|
+
def evaluate(context) #:nodoc:
|
25
|
+
add_warning(context, 'Case statement is missing else clause.') unless context.has_else_clause?
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'simplabs/excellent/checks/line_count_check'
|
2
|
+
|
3
|
+
module Simplabs
|
4
|
+
|
5
|
+
module Excellent
|
6
|
+
|
7
|
+
module Checks
|
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
|
15
|
+
class ClassLineCountCheck < LineCountCheck
|
16
|
+
|
17
|
+
DEFAULT_THRESHOLD = 400
|
18
|
+
|
19
|
+
def initialize(options = {}) #:nodoc:
|
20
|
+
threshold = options[:threshold] || DEFAULT_THRESHOLD
|
21
|
+
super([:class], threshold)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def warning_args(context) #:nodoc:
|
27
|
+
[context, '{{class}} has {{count}} lines.', { :class => context.full_name, :count => context.line_count }]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|