simplabs-excellent 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ = 1.4.0
2
+
3
+ * Excellent not parses *.erb files
4
+ * added new check InstanceVarInPartialCheck
5
+
1
6
  = 1.3.1
2
7
 
3
8
  * FIX (forgot files in gemspec on 1.3.0)
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
- :minor: 3
4
- :patch: 1
3
+ :minor: 4
4
+ :patch: 0
@@ -9,7 +9,7 @@ module Simplabs #:nodoc:
9
9
 
10
10
  module Excellent #:nodoc:
11
11
 
12
- VERSION = '1.3.1'
12
+ VERSION = '1.4.0'
13
13
 
14
14
  end
15
15
 
@@ -23,6 +23,7 @@ module Simplabs
23
23
  def initialize(options = {}) #:nodoc:
24
24
  super()
25
25
  @interesting_nodes = [:if, :while, :until]
26
+ @interesting_files = [/\.rb$/, /\.erb$/]
26
27
  end
27
28
 
28
29
  def evaluate(context) #:nodoc:
@@ -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).
@@ -18,6 +18,7 @@ module Simplabs
18
18
  def initialize #:nodoc:
19
19
  super
20
20
  @interesting_nodes = [:case]
21
+ @interesting_files = [/\.rb$/, /\.erb$/]
21
22
  end
22
23
 
23
24
  def evaluate(context) #:nodoc:
@@ -26,6 +26,7 @@ module Simplabs
26
26
  def initialize #:nodoc:
27
27
  super
28
28
  @interesting_nodes = [:for]
29
+ @interesting_files = [/\.rb$/, /\.erb$/]
29
30
  end
30
31
 
31
32
  def evaluate(context) #:nodoc:
@@ -16,6 +16,7 @@ module Simplabs
16
16
  def initialize #:nodoc:
17
17
  super
18
18
  @interesting_nodes = [:iter]
19
+ @interesting_files = [/\.rb$/, /\.erb$/]
19
20
  end
20
21
 
21
22
  def evaluate(context) #:nodoc:
@@ -15,3 +15,4 @@ end
15
15
 
16
16
  require 'simplabs/excellent/checks/rails/attr_accessible_check'
17
17
  require 'simplabs/excellent/checks/rails/attr_protected_check'
18
+ require 'simplabs/excellent/checks/rails/instance_var_in_partial_check'
@@ -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
@@ -17,6 +17,7 @@ module Simplabs
17
17
  def initialize #:nodoc:
18
18
  super
19
19
  @interesting_nodes = [:cvar]
20
+ @interesting_files = [/\.rb$/, /\.erb$/]
20
21
  end
21
22
 
22
23
  def evaluate(context) #:nodoc:
@@ -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) } unless checks.nil?
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 => { :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' => { }
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.3.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