excellent 1.5.4
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 +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
|