simplabs-excellent 1.3.1 → 1.4.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.
- data/History.txt +5 -0
- data/VERSION.yml +2 -2
- data/lib/simplabs/excellent.rb +1 -1
- data/lib/simplabs/excellent/checks/assignment_in_conditional_check.rb +1 -0
- data/lib/simplabs/excellent/checks/base.rb +8 -1
- data/lib/simplabs/excellent/checks/case_missing_else_check.rb +1 -0
- data/lib/simplabs/excellent/checks/for_loop_check.rb +1 -0
- data/lib/simplabs/excellent/checks/nested_iterators_check.rb +1 -0
- data/lib/simplabs/excellent/checks/rails.rb +1 -0
- data/lib/simplabs/excellent/checks/rails/instance_var_in_partial_check.rb +37 -0
- data/lib/simplabs/excellent/checks/singleton_variable_check.rb +1 -0
- data/lib/simplabs/excellent/formatters/html.rb +21 -0
- data/lib/simplabs/excellent/parsing/code_processor.rb +7 -2
- data/lib/simplabs/excellent/parsing/ivar_context.rb +32 -0
- data/lib/simplabs/excellent/parsing/parser.rb +2 -0
- data/lib/simplabs/excellent/runner.rb +21 -20
- data/spec/checks/rails/instance_var_in_partial_check_spec.rb +40 -0
- metadata +4 -1
data/History.txt
CHANGED
data/VERSION.yml
CHANGED
data/lib/simplabs/excellent.rb
CHANGED
@@ -16,8 +16,15 @@ module Simplabs
|
|
16
16
|
# e.g. <tt>:if</tt> or <tt>:defn</tt>
|
17
17
|
attr_reader :interesting_nodes
|
18
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
|
+
|
19
25
|
def initialize #:nodoc:
|
20
|
-
@warnings
|
26
|
+
@warnings = []
|
27
|
+
@interesting_files = [/\.rb$/]
|
21
28
|
end
|
22
29
|
|
23
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).
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'simplabs/excellent/checks/base'
|
2
|
+
|
3
|
+
module Simplabs
|
4
|
+
|
5
|
+
module Excellent
|
6
|
+
|
7
|
+
module Checks
|
8
|
+
|
9
|
+
module Rails
|
10
|
+
|
11
|
+
# This check reports partials that use instance variables. Using instance variables in partials couples the partial to the controller action or
|
12
|
+
# template that includes the partial and that has to define the instance variable.
|
13
|
+
#
|
14
|
+
# ==== Applies to
|
15
|
+
#
|
16
|
+
# * instance variables
|
17
|
+
class InstanceVarInPartialCheck < Base
|
18
|
+
|
19
|
+
def initialize #:nodoc:
|
20
|
+
super
|
21
|
+
@interesting_nodes = [:ivar]
|
22
|
+
@interesting_files = [/^_.*\.erb$/]
|
23
|
+
end
|
24
|
+
|
25
|
+
def evaluate(context) #:nodoc:
|
26
|
+
add_warning(context, 'Instance variable {{variable}} used in partial.', { :variable => context.full_name })
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -91,6 +91,24 @@ module Simplabs
|
|
91
91
|
text-align: right;
|
92
92
|
display: inline-block;
|
93
93
|
}
|
94
|
+
|
95
|
+
#footer {
|
96
|
+
margin: 20px 0 20px 0;
|
97
|
+
padding: 5px;
|
98
|
+
text-align: center;
|
99
|
+
}
|
100
|
+
|
101
|
+
#footer a {
|
102
|
+
color: #000;
|
103
|
+
background-color: #ddd;
|
104
|
+
text-decoration: none;
|
105
|
+
padding: 0 2px 0 2px;
|
106
|
+
}
|
107
|
+
|
108
|
+
#footer a:active, #footer a:hover {
|
109
|
+
color: #fff;
|
110
|
+
background-color: #222;
|
111
|
+
}
|
94
112
|
</style>
|
95
113
|
</head>
|
96
114
|
<body>
|
@@ -119,6 +137,9 @@ module Simplabs
|
|
119
137
|
|
120
138
|
FOOTER_TEMPLATE = <<-END
|
121
139
|
</div>
|
140
|
+
<div id="footer">
|
141
|
+
<a href="http://github.com/simplabs/excellent" title="Excellent at github">Excellent</a> by <a href="http://simplabs.com" title="simplabs">simplabs</a>
|
142
|
+
</div>
|
122
143
|
</body>
|
123
144
|
</html>
|
124
145
|
END
|
@@ -11,6 +11,7 @@ require 'simplabs/excellent/parsing/for_loop_context'
|
|
11
11
|
require 'simplabs/excellent/parsing/while_context'
|
12
12
|
require 'simplabs/excellent/parsing/until_context'
|
13
13
|
require 'simplabs/excellent/parsing/cvar_context'
|
14
|
+
require 'simplabs/excellent/parsing/ivar_context'
|
14
15
|
require 'simplabs/excellent/parsing/resbody_context'
|
15
16
|
require 'simplabs/excellent/parsing/call_context'
|
16
17
|
|
@@ -53,6 +54,10 @@ module Simplabs
|
|
53
54
|
process_default(exp, SingletonMethodContext.new(exp, @contexts.last))
|
54
55
|
end
|
55
56
|
|
57
|
+
def process_ivar(exp)
|
58
|
+
process_default(exp, IvarContext.new(exp, @contexts.last))
|
59
|
+
end
|
60
|
+
|
56
61
|
def process_cvar(exp)
|
57
62
|
process_default(exp, CvarContext.new(exp, @contexts.last))
|
58
63
|
end
|
@@ -118,8 +123,8 @@ module Simplabs
|
|
118
123
|
|
119
124
|
def apply_checks(exp)
|
120
125
|
if exp.is_a?(Sexp)
|
121
|
-
checks = @checks[exp.node_type]
|
122
|
-
checks.each { |check| check.evaluate_node(@contexts.last)
|
126
|
+
checks = @checks[exp.node_type] || []
|
127
|
+
checks.each { |check| check.evaluate_node(@contexts.last) if check.interesting_files.any? { |pattern| File.basename(exp.file) =~ pattern } }
|
123
128
|
end
|
124
129
|
end
|
125
130
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Simplabs
|
2
|
+
|
3
|
+
module Excellent
|
4
|
+
|
5
|
+
module Parsing
|
6
|
+
|
7
|
+
class IvarContext < SexpContext #:nodoc:
|
8
|
+
|
9
|
+
def initialize(exp, parent)
|
10
|
+
super
|
11
|
+
@name = exp[1].to_s.sub(/^@+/, '')
|
12
|
+
end
|
13
|
+
|
14
|
+
def full_name
|
15
|
+
return @name if @parent.nil?
|
16
|
+
full_name = @name
|
17
|
+
parent = @parent
|
18
|
+
parent = parent.parent until parent.is_a?(ClassContext) || parent.is_a?(ModuleContext) || parent.nil?
|
19
|
+
if parent
|
20
|
+
full_name = "#{parent.full_name}.#{full_name}"
|
21
|
+
else
|
22
|
+
@name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'ruby_parser'
|
3
3
|
require 'facets'
|
4
|
+
require 'erb'
|
4
5
|
|
5
6
|
module Simplabs
|
6
7
|
|
@@ -22,6 +23,7 @@ module Simplabs
|
|
22
23
|
|
23
24
|
def silent_parse(content, filename)
|
24
25
|
@parser ||= RubyParser.new
|
26
|
+
content = ::ERB.new(content, nil, '-').src if filename =~ /\.erb$/
|
25
27
|
sexp = @parser.parse(content, filename)
|
26
28
|
sexp
|
27
29
|
end
|
@@ -12,25 +12,26 @@ module Simplabs
|
|
12
12
|
class Runner
|
13
13
|
|
14
14
|
DEFAULT_CONFIG = {
|
15
|
-
:AssignmentInConditionalCheck
|
16
|
-
:CaseMissingElseCheck
|
17
|
-
:ClassLineCountCheck
|
18
|
-
:ClassNameCheck
|
19
|
-
:SingletonVariableCheck
|
20
|
-
:CyclomaticComplexityBlockCheck
|
21
|
-
:CyclomaticComplexityMethodCheck
|
22
|
-
:EmptyRescueBodyCheck
|
23
|
-
:ForLoopCheck
|
24
|
-
:MethodLineCountCheck
|
25
|
-
:MethodNameCheck
|
26
|
-
:ModuleLineCountCheck
|
27
|
-
:ModuleNameCheck
|
28
|
-
:ParameterNumberCheck
|
29
|
-
:FlogMethodCheck
|
30
|
-
:FlogBlockCheck
|
31
|
-
:FlogClassCheck
|
32
|
-
:'Rails::AttrProtectedCheck'
|
33
|
-
:'Rails::AttrAccessibleCheck'
|
15
|
+
:AssignmentInConditionalCheck => { },
|
16
|
+
:CaseMissingElseCheck => { },
|
17
|
+
:ClassLineCountCheck => { :threshold => 300 },
|
18
|
+
:ClassNameCheck => { :pattern => /^[A-Z][a-zA-Z0-9]*$/ },
|
19
|
+
:SingletonVariableCheck => { },
|
20
|
+
:CyclomaticComplexityBlockCheck => { :complexity => 4 },
|
21
|
+
:CyclomaticComplexityMethodCheck => { :complexity => 8 },
|
22
|
+
:EmptyRescueBodyCheck => { },
|
23
|
+
:ForLoopCheck => { },
|
24
|
+
:MethodLineCountCheck => { :line_count => 20 },
|
25
|
+
:MethodNameCheck => { :pattern => /^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/ },
|
26
|
+
:ModuleLineCountCheck => { :line_count => 300 },
|
27
|
+
:ModuleNameCheck => { :pattern => /^[A-Z][a-zA-Z0-9]*$/ },
|
28
|
+
:ParameterNumberCheck => { :parameter_count => 3 },
|
29
|
+
:FlogMethodCheck => { },
|
30
|
+
:FlogBlockCheck => { },
|
31
|
+
:FlogClassCheck => { },
|
32
|
+
:'Rails::AttrProtectedCheck' => { },
|
33
|
+
:'Rails::AttrAccessibleCheck' => { },
|
34
|
+
:'Rails::InstanceVarInPartialCheck' => { }
|
34
35
|
}
|
35
36
|
|
36
37
|
attr_accessor :config #:nodoc:
|
@@ -119,7 +120,7 @@ module Simplabs
|
|
119
120
|
if File.file?(path)
|
120
121
|
files << path
|
121
122
|
elsif File.directory?(path)
|
122
|
-
files += Dir.glob(File.join(path, '**/*.rb'))
|
123
|
+
files += Dir.glob(File.join(path, '**/*.{rb,erb}'))
|
123
124
|
else
|
124
125
|
raise ArgumentError.new("#{path} is neither a File nor a directory!")
|
125
126
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Simplabs::Excellent::Checks::Rails::InstanceVarInPartialCheck do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@excellent = Simplabs::Excellent::Runner.new(Simplabs::Excellent::Checks::Rails::InstanceVarInPartialCheck.new)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#evaluate' do
|
10
|
+
|
11
|
+
it 'should accept partials that do not use instance variables' do
|
12
|
+
code = <<-END
|
13
|
+
<div>
|
14
|
+
<%= 'some text' %>
|
15
|
+
</div>
|
16
|
+
END
|
17
|
+
@excellent.check('_dummy-file.html.erb', code)
|
18
|
+
warnings = @excellent.warnings
|
19
|
+
|
20
|
+
warnings.should be_empty
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should reject partials that use instance variables' do
|
24
|
+
code = <<-END
|
25
|
+
<div>
|
26
|
+
<%= @ivar %>
|
27
|
+
</div>
|
28
|
+
END
|
29
|
+
@excellent.check('_dummy-file.html.erb', code)
|
30
|
+
warnings = @excellent.warnings
|
31
|
+
|
32
|
+
warnings.should_not be_empty
|
33
|
+
warnings[0].info.should == { :variable => 'ivar' }
|
34
|
+
warnings[0].line_number.should == 2
|
35
|
+
warnings[0].message.should == 'Instance variable ivar used in partial.'
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simplabs-excellent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Otte-Witte
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- lib/simplabs/excellent/checks/parameter_number_check.rb
|
73
73
|
- lib/simplabs/excellent/checks/rails/attr_accessible_check.rb
|
74
74
|
- lib/simplabs/excellent/checks/rails/attr_protected_check.rb
|
75
|
+
- lib/simplabs/excellent/checks/rails/instance_var_in_partial_check.rb
|
75
76
|
- lib/simplabs/excellent/checks/rails.rb
|
76
77
|
- lib/simplabs/excellent/checks/singleton_variable_check.rb
|
77
78
|
- lib/simplabs/excellent/checks.rb
|
@@ -94,6 +95,7 @@ files:
|
|
94
95
|
- lib/simplabs/excellent/parsing/flog_measure.rb
|
95
96
|
- lib/simplabs/excellent/parsing/for_loop_context.rb
|
96
97
|
- lib/simplabs/excellent/parsing/if_context.rb
|
98
|
+
- lib/simplabs/excellent/parsing/ivar_context.rb
|
97
99
|
- lib/simplabs/excellent/parsing/method_context.rb
|
98
100
|
- lib/simplabs/excellent/parsing/module_context.rb
|
99
101
|
- lib/simplabs/excellent/parsing/parser.rb
|
@@ -129,6 +131,7 @@ files:
|
|
129
131
|
- spec/checks/parameter_number_check_spec.rb
|
130
132
|
- spec/checks/rails/attr_accessible_check_spec.rb
|
131
133
|
- spec/checks/rails/attr_protected_check_spec.rb
|
134
|
+
- spec/checks/rails/instance_var_in_partial_check_spec.rb
|
132
135
|
- spec/checks/singleton_variable_check_spec.rb
|
133
136
|
- spec/extensions/string_spec.rb
|
134
137
|
- spec/spec_helper.rb
|