rails_best_practices 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +2 -2
- data/README.md +1 -0
- data/assets/result.html.erb +24 -6
- data/lib/rails_best_practices.rb +19 -3
- data/lib/rails_best_practices/command.rb +4 -0
- data/lib/rails_best_practices/core/error.rb +1 -0
- data/lib/rails_best_practices/core/methods.rb +14 -2
- data/lib/rails_best_practices/core/runner.rb +2 -2
- data/lib/rails_best_practices/core_ext/sexp.rb +47 -2
- data/lib/rails_best_practices/prepares/controller_prepare.rb +9 -1
- data/lib/rails_best_practices/prepares/model_prepare.rb +15 -3
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +58 -5
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +32 -24
- data/lib/rails_best_practices/reviews/review.rb +2 -1
- data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +3 -1
- data/lib/rails_best_practices/reviews/use_before_filter_review.rb +1 -1
- data/lib/rails_best_practices/version.rb +1 -2
- data/rails_best_practices.yml +2 -2
- data/rake_rubies.sh +3 -4
- data/spec/rails_best_practices/core/runner_spec.rb +14 -5
- data/spec/rails_best_practices/core_ext/sexp_spec.rb +45 -0
- data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +11 -0
- data/spec/rails_best_practices/prepares/model_prepare_spec.rb +35 -0
- data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +11 -2
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +166 -0
- data/spec/rails_best_practices/reviews/restrict_auto_generated_routes_review_spec.rb +20 -0
- data/spec/rails_best_practices/reviews/simplify_render_in_views_review_spec.rb +11 -3
- data/spec/spec_helper.rb +2 -0
- metadata +3 -3
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rails_best_practices (1.
|
4
|
+
rails_best_practices (1.3.0)
|
5
5
|
activesupport
|
6
6
|
colored
|
7
7
|
erubis
|
@@ -12,7 +12,7 @@ PATH
|
|
12
12
|
GEM
|
13
13
|
remote: http://rubygems.org/
|
14
14
|
specs:
|
15
|
-
activesupport (3.0.
|
15
|
+
activesupport (3.0.10)
|
16
16
|
colored (1.2)
|
17
17
|
diff-lcs (1.1.2)
|
18
18
|
erubis (2.7.0)
|
data/README.md
CHANGED
@@ -23,6 +23,7 @@ By default rails_best_practices will do parse codes in vendor, spec, test and fe
|
|
23
23
|
--without-color only output plain text without color
|
24
24
|
--with-textmate open file by textmate in html format
|
25
25
|
--with-mvim open file by mvim in html format
|
26
|
+
--with-git display git commit and git username in html format
|
26
27
|
--vendor include vendor files
|
27
28
|
--spec include spec files
|
28
29
|
--test include test files
|
data/assets/result.html.erb
CHANGED
@@ -12,11 +12,14 @@
|
|
12
12
|
h1 {
|
13
13
|
color: ##4E4E4E;
|
14
14
|
}
|
15
|
+
p {
|
16
|
+
margin: 5px 0;
|
17
|
+
}
|
15
18
|
table {
|
16
19
|
background: white;
|
17
20
|
border: 1px solid #666;
|
18
21
|
border-collapse: collapse;
|
19
|
-
margin:
|
22
|
+
margin: 10px 0;
|
20
23
|
font-size: 14px;
|
21
24
|
}
|
22
25
|
table th, table td {
|
@@ -33,26 +36,33 @@
|
|
33
36
|
table tr:hover {
|
34
37
|
background-color: #FFFFC0;
|
35
38
|
}
|
39
|
+
ul {
|
40
|
+
clear: both;
|
41
|
+
display: inline-block;
|
42
|
+
padding: 0;
|
43
|
+
margin: 0;
|
44
|
+
}
|
36
45
|
ul li {
|
37
46
|
list-style: none;
|
38
47
|
display: none;
|
48
|
+
float: left;
|
39
49
|
}
|
40
50
|
</style>
|
41
51
|
</head>
|
42
52
|
<body>
|
43
53
|
<h1>rails_best_practices output</h1>
|
44
|
-
<
|
54
|
+
<p>
|
45
55
|
Please go to
|
46
56
|
<a href='http://rails-bestpractices.com' target='_blank'>http://rails-bestpractices.com</a>
|
47
57
|
to see more useful Rails Best Practices.
|
48
|
-
</
|
49
|
-
<
|
58
|
+
</p>
|
59
|
+
<p>
|
50
60
|
<% if @errors.empty? %>
|
51
61
|
No error found. Cool!
|
52
62
|
<% else %>
|
53
|
-
Found <%= @errors.size %>
|
63
|
+
Found <%= @errors.size %> warnings.
|
54
64
|
<% end %>
|
55
|
-
</
|
65
|
+
</p>
|
56
66
|
<ul>
|
57
67
|
<% @error_types.each do |error_type| %>
|
58
68
|
<li><input type="checkbox" value="<%= error_type.split(':').last %>" /><%= error_type.split(':').last %></li>
|
@@ -63,6 +73,10 @@
|
|
63
73
|
<th>Filename</th>
|
64
74
|
<th>Line Number</th>
|
65
75
|
<th>Warning Message</th>
|
76
|
+
<% if @git %>
|
77
|
+
<th>Git Commit</th>
|
78
|
+
<th>Git Username</th>
|
79
|
+
<% end %>
|
66
80
|
</tr>
|
67
81
|
<% @errors.each do |error| %>
|
68
82
|
<tr class="<%= error.type.split(':').last %>">
|
@@ -79,6 +93,10 @@
|
|
79
93
|
<td class='message'>
|
80
94
|
<a href='<%= error.url %>' target='_blank'><%= error.message %></a>
|
81
95
|
</td>
|
96
|
+
<% if @git %>
|
97
|
+
<td class='git_commit'><%= error.git_commit %></td>
|
98
|
+
<td class='git_usename'><%= error.git_username %></td>
|
99
|
+
<% end %>
|
82
100
|
</tr>
|
83
101
|
<% end %>
|
84
102
|
</table>
|
data/lib/rails_best_practices.rb
CHANGED
@@ -81,12 +81,13 @@ module RailsBestPractices
|
|
81
81
|
plain_output("AlwaysAddDbIndexReview is disabled as there is no db/schema.rb file in your rails project.", 'blue')
|
82
82
|
end
|
83
83
|
|
84
|
-
@bar = ProgressBar.new('
|
84
|
+
@bar = ProgressBar.new('Source Codes', lexical_files.size + prepare_files.size + review_files.size)
|
85
85
|
["lexical", "prepare", "review"].each { |process| send(:process, process) }
|
86
86
|
@runner.on_complete
|
87
87
|
@bar.finish
|
88
88
|
|
89
89
|
if @options['format'] == 'html'
|
90
|
+
load_git_info if @options["with-git"]
|
90
91
|
output_html_errors
|
91
92
|
else
|
92
93
|
output_terminal_errors
|
@@ -148,7 +149,7 @@ module RailsBestPractices
|
|
148
149
|
# @param [Array] dirs what directories to expand
|
149
150
|
# @return [Array] all files expanded
|
150
151
|
def expand_dirs_to_files *dirs
|
151
|
-
extensions = ['rb', 'erb', 'rhtml', 'haml', 'builder']
|
152
|
+
extensions = ['rb', 'erb', 'rake', 'rhtml', 'haml', 'builder']
|
152
153
|
|
153
154
|
dirs.flatten.map { |entry|
|
154
155
|
next unless File.exist? entry
|
@@ -214,6 +215,21 @@ module RailsBestPractices
|
|
214
215
|
end
|
215
216
|
end
|
216
217
|
|
218
|
+
# load git commit and git username info.
|
219
|
+
def load_git_info
|
220
|
+
git_progressbar = ProgressBar.new('Git Info', @runner.errors.size)
|
221
|
+
@runner.errors.each do |error|
|
222
|
+
git_info = `cd #{@runner.class.base_path}; git blame #{error.filename[@runner.class.base_path.size..-1]} | sed -n #{error.line_number.split(',').first}p`
|
223
|
+
unless git_info == ""
|
224
|
+
git_commit, git_username = git_info.split(/\d{4}-\d{2}-\d{2}/).first.split("(")
|
225
|
+
error.git_commit = git_commit.split(" ").first.strip
|
226
|
+
error.git_username = git_username.strip
|
227
|
+
end
|
228
|
+
git_progressbar.inc unless @options['debug']
|
229
|
+
end
|
230
|
+
git_progressbar.finish
|
231
|
+
end
|
232
|
+
|
217
233
|
# output errors with html format.
|
218
234
|
def output_html_errors
|
219
235
|
require 'erubis'
|
@@ -221,7 +237,7 @@ module RailsBestPractices
|
|
221
237
|
|
222
238
|
File.open("rails_best_practices_output.html", "w+") do |file|
|
223
239
|
eruby = Erubis::Eruby.new(template)
|
224
|
-
file.puts eruby.evaluate(:errors => @runner.errors, :error_types => error_types, :textmate => @options["with-textmate"], :mvim => @options["with-mvim"])
|
240
|
+
file.puts eruby.evaluate(:errors => @runner.errors, :error_types => error_types, :textmate => @options["with-textmate"], :mvim => @options["with-mvim"], :git => @options["with-git"])
|
225
241
|
end
|
226
242
|
end
|
227
243
|
|
@@ -40,6 +40,10 @@ OptionParser.new do |opts|
|
|
40
40
|
options["with-mvim"] = true
|
41
41
|
end
|
42
42
|
|
43
|
+
opts.on("--with-git", "display git commit and username, only support html format") do
|
44
|
+
options["with-git"] = true
|
45
|
+
end
|
46
|
+
|
43
47
|
['vendor', 'spec', 'test', 'features'].each do |pattern|
|
44
48
|
opts.on("--#{pattern}", "include #{pattern} files") do
|
45
49
|
options[pattern] = true
|
@@ -6,6 +6,7 @@ module RailsBestPractices
|
|
6
6
|
# it indicates the filenname, line number and error message for the violation.
|
7
7
|
class Error
|
8
8
|
attr_reader :filename, :line_number, :message, :type, :url
|
9
|
+
attr_accessor :git_commit, :git_username
|
9
10
|
|
10
11
|
def initialize(filename, line_number, message, type, url = nil)
|
11
12
|
@filename = filename
|
@@ -53,15 +53,27 @@ module RailsBestPractices
|
|
53
53
|
#
|
54
54
|
# @param [String] class name
|
55
55
|
# @param [String] method name
|
56
|
-
def
|
56
|
+
def mark_parent_class_method_used(class_name, method_name)
|
57
57
|
klass = Prepares.klasses.find { |klass| klass.to_s == class_name }
|
58
58
|
if klass && klass.extend_class_name
|
59
|
-
|
59
|
+
mark_parent_class_method_used(klass.extend_class_name, method_name)
|
60
60
|
method = get_method(klass.extend_class_name, method_name)
|
61
61
|
method.mark_used if method
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
# Mark sub classes' method as used.
|
66
|
+
#
|
67
|
+
# @param [String] class name
|
68
|
+
# @param [String] method name
|
69
|
+
def mark_subclasses_method_used(class_name, method_name)
|
70
|
+
Prepares.klasses.select { |klass| klass.extend_class_name == class_name }.each do |klass|
|
71
|
+
mark_subclasses_method_used(klass.to_s, method_name)
|
72
|
+
method = get_method(klass.to_s, method_name)
|
73
|
+
method.mark_used if method
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
65
77
|
# remomber the method name, the method is probably be used for the class' public method.
|
66
78
|
#
|
67
79
|
# @param [String] method name
|
@@ -159,7 +159,7 @@ module RailsBestPractices
|
|
159
159
|
content.gsub!(/\\\d{3}/, '')
|
160
160
|
rescue LoadError
|
161
161
|
raise "In order to parse #{filename}, please install the haml gem"
|
162
|
-
rescue Haml::Error
|
162
|
+
rescue Haml::Error, SyntaxError
|
163
163
|
# do nothing, just ignore the wrong haml files.
|
164
164
|
end
|
165
165
|
end
|
@@ -202,7 +202,7 @@ module RailsBestPractices
|
|
202
202
|
# load all plugin reviews.
|
203
203
|
def load_plugin_reviews
|
204
204
|
begin
|
205
|
-
plugins =
|
205
|
+
plugins = File.join(Runner.base_path, 'lib', 'rails_best_practices', 'plugins', 'reviews')
|
206
206
|
if File.directory?(plugins)
|
207
207
|
Dir[File.expand_path(File.join(plugins, "*.rb"))].each do |review|
|
208
208
|
require review
|
@@ -22,8 +22,11 @@ class Sexp
|
|
22
22
|
# => 2
|
23
23
|
def line
|
24
24
|
if [:def, :command, :command_call, :call, :fcall, :method_add_arg, :method_add_block,
|
25
|
-
:var_ref, :const_ref, :const_path_ref, :class, :module, :if, :unless, :elsif, :binary
|
25
|
+
:var_ref, :const_ref, :const_path_ref, :class, :module, :if, :unless, :elsif, :binary,
|
26
|
+
:alias, :symbol_literal, :symbol, :aref].include? sexp_type
|
26
27
|
self[1].line
|
28
|
+
elsif :array == sexp_type
|
29
|
+
array_values[0].line
|
27
30
|
else
|
28
31
|
self.last.first if self.last.is_a? Array
|
29
32
|
end
|
@@ -294,7 +297,7 @@ class Sexp
|
|
294
297
|
when :args_add_block, :array
|
295
298
|
node = self[1]
|
296
299
|
while true
|
297
|
-
if :args_add
|
300
|
+
if [:args_add, :args_add_star].include? node.sexp_type
|
298
301
|
nodes.unshift node[2]
|
299
302
|
node = node[1]
|
300
303
|
elsif :args_new == node.sexp_type
|
@@ -675,12 +678,48 @@ class Sexp
|
|
675
678
|
if :array == sexp_type
|
676
679
|
if nil == self[1]
|
677
680
|
[]
|
681
|
+
elsif :qwords_add == self[1].sexp_type
|
682
|
+
self[1].array_values
|
678
683
|
else
|
679
684
|
arguments.all
|
680
685
|
end
|
686
|
+
elsif :qwords_add
|
687
|
+
values = []
|
688
|
+
node = self
|
689
|
+
while true
|
690
|
+
if :qwords_add == node.sexp_type
|
691
|
+
values.unshift node[2]
|
692
|
+
node = node[1]
|
693
|
+
elsif :qwords_new == node.sexp_type
|
694
|
+
break
|
695
|
+
end
|
696
|
+
end
|
697
|
+
values
|
681
698
|
end
|
682
699
|
end
|
683
700
|
|
701
|
+
# old method for alias node.
|
702
|
+
#
|
703
|
+
# s(:alias,
|
704
|
+
# s(:symbol_literal, s(:@ident, "new", s(1, 6))),
|
705
|
+
# s(:symbol_literal, s(:@ident, "old", s(1, 10)))
|
706
|
+
# )
|
707
|
+
# => s(:symbol_literal, s(:@ident, "old", s(1, 10))),
|
708
|
+
def old_method
|
709
|
+
self[2]
|
710
|
+
end
|
711
|
+
|
712
|
+
# new method for alias node.
|
713
|
+
#
|
714
|
+
# s(:alias,
|
715
|
+
# s(:symbol_literal, s(:@ident, "new", s(1, 6))),
|
716
|
+
# s(:symbol_literal, s(:@ident, "old", s(1, 10)))
|
717
|
+
# )
|
718
|
+
# => s(:symbol_literal, s(:@ident, "new", s(1, 6))),
|
719
|
+
def new_method
|
720
|
+
self[1]
|
721
|
+
end
|
722
|
+
|
684
723
|
# To object.
|
685
724
|
#
|
686
725
|
# s(:array,
|
@@ -726,6 +765,12 @@ class Sexp
|
|
726
765
|
else
|
727
766
|
self[1].to_s
|
728
767
|
end
|
768
|
+
when :qwords_add
|
769
|
+
if s(:qwords_new) == self[1]
|
770
|
+
self[2].to_s
|
771
|
+
else
|
772
|
+
self[1].to_s
|
773
|
+
end
|
729
774
|
when :const_path_ref
|
730
775
|
"#{self[1]}::#{self[2]}"
|
731
776
|
when :@label
|
@@ -54,7 +54,15 @@ module RailsBestPractices
|
|
54
54
|
# restrict actions for inherited_resources
|
55
55
|
def start_command(node)
|
56
56
|
if @inherited_resources && "actions" == node.message.to_s
|
57
|
-
|
57
|
+
if "all" == node.arguments.all[0].to_s
|
58
|
+
@actions = DEFAULT_ACTIONS
|
59
|
+
option_argument = node.arguments.all[1]
|
60
|
+
if :bare_assoc_hash == option_argument.sexp_type && option_argument.hash_value("except")
|
61
|
+
@actions -= option_argument.hash_value("except").to_object
|
62
|
+
end
|
63
|
+
else
|
64
|
+
@actions = node.arguments.all.map(&:to_s)
|
65
|
+
end
|
58
66
|
end
|
59
67
|
end
|
60
68
|
|
@@ -11,7 +11,7 @@ module RailsBestPractices
|
|
11
11
|
ASSOCIATION_METHODS = %w(belongs_to has_one has_many has_and_belongs_to_many)
|
12
12
|
|
13
13
|
def interesting_nodes
|
14
|
-
[:module, :class, :def, :command, :var_ref]
|
14
|
+
[:module, :class, :def, :command, :var_ref, :alias]
|
15
15
|
end
|
16
16
|
|
17
17
|
def interesting_files
|
@@ -62,14 +62,26 @@ module RailsBestPractices
|
|
62
62
|
# }
|
63
63
|
# }
|
64
64
|
def start_command(node)
|
65
|
-
|
65
|
+
case node.message.to_s
|
66
|
+
when *%w(named_scope scope alias_method)
|
66
67
|
method_name = node.arguments.all[0].to_s
|
67
68
|
@methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
|
68
|
-
|
69
|
+
when "alias_method_chain"
|
70
|
+
method, feature = *node.arguments.all.map(&:to_s)
|
71
|
+
@methods.add_method(current_class_name, "#{method}_with_#{feature}", {"file" => node.file, "line" => node.line}, current_access_control)
|
72
|
+
@methods.add_method(current_class_name, "#{method}", {"file" => node.file, "line" => node.line}, current_access_control)
|
73
|
+
when *ASSOCIATION_METHODS
|
69
74
|
remember_association(node)
|
75
|
+
else
|
70
76
|
end
|
71
77
|
end
|
72
78
|
|
79
|
+
# check alias node to remembr the alias methods.
|
80
|
+
def start_alias(node)
|
81
|
+
method_name = node.new_method.to_s
|
82
|
+
@methods.add_method(current_class_name, method_name, {"file" => node.file, "line" => node.line}, current_access_control)
|
83
|
+
end
|
84
|
+
|
73
85
|
private
|
74
86
|
# remember associations, with class to association names.
|
75
87
|
def remember_association(node)
|
@@ -3,14 +3,22 @@ require 'rails_best_practices/reviews/review'
|
|
3
3
|
|
4
4
|
module RailsBestPractices
|
5
5
|
module Reviews
|
6
|
+
# Find out unused methods in models.
|
7
|
+
#
|
8
|
+
# Implemenation:
|
9
|
+
#
|
10
|
+
# Review process:
|
11
|
+
# remember all method calls,
|
12
|
+
# at end, check if all defined methods are called,
|
13
|
+
# if not, non called methods are unused.
|
6
14
|
class RemoveUnusedMethodsInModelsReview < Review
|
7
15
|
include Klassable
|
8
16
|
include Completeable
|
9
17
|
|
10
|
-
EXCEPT_METHODS = %w(initialize validate to_xml to_json)
|
18
|
+
EXCEPT_METHODS = %w(initialize validate to_xml to_json assign_attributes after_find after_initialize)
|
11
19
|
|
12
20
|
def interesting_nodes
|
13
|
-
[:module, :class, :call, :fcall, :command, :method_add_arg, :var_ref]
|
21
|
+
[:module, :class, :call, :fcall, :command, :command_call, :method_add_arg, :var_ref, :alias, :bare_assoc_hash]
|
14
22
|
end
|
15
23
|
|
16
24
|
def initialize(options={})
|
@@ -19,32 +27,76 @@ module RailsBestPractices
|
|
19
27
|
@except_methods = EXCEPT_METHODS + options['except_methods']
|
20
28
|
end
|
21
29
|
|
30
|
+
# remember the message of call node.
|
22
31
|
def start_call(node)
|
23
32
|
mark_used(node.message)
|
24
33
|
end
|
25
34
|
|
35
|
+
# remember the message of fcall node.
|
26
36
|
def start_fcall(node)
|
27
37
|
mark_used(node.message)
|
28
38
|
end
|
29
39
|
|
40
|
+
# remember name of var_ref node.
|
30
41
|
def start_var_ref(node)
|
31
42
|
mark_used(node)
|
32
43
|
end
|
33
44
|
|
45
|
+
# remember the message of command call node.
|
46
|
+
def start_command_call(node)
|
47
|
+
mark_used(node.message)
|
48
|
+
end
|
49
|
+
|
50
|
+
# remember the message of command node.
|
51
|
+
# remember the argument of alias_method and alias_method_chain as well.
|
34
52
|
def start_command(node)
|
35
|
-
|
53
|
+
case node.message.to_s
|
54
|
+
when "named_scope", "scope"
|
55
|
+
# nothing
|
56
|
+
when "alias_method"
|
57
|
+
mark_used(node.arguments.all[1])
|
58
|
+
when "alias_method_chain"
|
59
|
+
method, feature = *node.arguments.all.map(&:to_s)
|
60
|
+
call_method("#{method}_with_#{feature}")
|
61
|
+
else
|
36
62
|
mark_used(node.message)
|
37
63
|
node.arguments.all.each { |argument| mark_used(argument) }
|
38
64
|
end
|
39
65
|
end
|
40
66
|
|
67
|
+
# remember the old method of alias node.
|
68
|
+
def start_alias(node)
|
69
|
+
mark_used(node.old_method)
|
70
|
+
end
|
71
|
+
|
72
|
+
# remember hash values for hash key "methods".
|
73
|
+
#
|
74
|
+
# def to_xml(options = {})
|
75
|
+
# super options.merge(:exclude => :visible, :methods => [:is_discussion_conversation])
|
76
|
+
# end
|
77
|
+
def start_bare_assoc_hash(node)
|
78
|
+
if node.hash_keys.include? "methods"
|
79
|
+
mark_used(node.hash_value("methods"))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# remember the first argument for try and send method.
|
41
84
|
def start_method_add_arg(node)
|
42
|
-
|
85
|
+
case node.message.to_s
|
86
|
+
when "try"
|
43
87
|
method_name = node.arguments.all[0].to_s
|
44
88
|
call_method(method_name)
|
89
|
+
when "send"
|
90
|
+
if [:symbol_literal, :string_literal].include?(node.arguments.all[0].sexp_type)
|
91
|
+
method_name = node.arguments.all[0].to_s
|
92
|
+
call_method(method_name)
|
93
|
+
end
|
94
|
+
else
|
95
|
+
# nothing
|
45
96
|
end
|
46
97
|
end
|
47
98
|
|
99
|
+
# get all unused methods at the end of review process.
|
48
100
|
def on_complete
|
49
101
|
@model_methods.get_all_unused_methods.each do |method|
|
50
102
|
if !@except_methods.include?(method.method_name) && method.method_name !~ /=$/
|
@@ -69,7 +121,8 @@ module RailsBestPractices
|
|
69
121
|
if @model_methods.has_method?(current_class_name, method_name)
|
70
122
|
@model_methods.get_method(current_class_name, method_name).mark_used
|
71
123
|
end
|
72
|
-
@model_methods.
|
124
|
+
@model_methods.mark_parent_class_method_used(current_class_name, method_name)
|
125
|
+
@model_methods.mark_subclasses_method_used(current_class_name, method_name)
|
73
126
|
@model_methods.possible_public_used(method_name)
|
74
127
|
end
|
75
128
|
end
|
@@ -86,10 +86,10 @@ module RailsBestPractices
|
|
86
86
|
|
87
87
|
# get the controller name.
|
88
88
|
def controller_name(node)
|
89
|
-
if node
|
90
|
-
|
91
|
-
if
|
92
|
-
name =
|
89
|
+
if option_with_hash(node)
|
90
|
+
option_node = node.arguments.all[1]
|
91
|
+
if hash_key_exist?(option_node,"controller")
|
92
|
+
name = option_node.hash_value("controller").to_s
|
93
93
|
else
|
94
94
|
name = node.arguments.all[0].to_s.tableize
|
95
95
|
end
|
@@ -111,39 +111,47 @@ module RailsBestPractices
|
|
111
111
|
|
112
112
|
# get the route actions that should be generated by resources call.
|
113
113
|
def resources_methods(node)
|
114
|
-
|
115
|
-
|
116
|
-
if node
|
117
|
-
|
118
|
-
if
|
119
|
-
Array(
|
120
|
-
elsif
|
121
|
-
|
114
|
+
methods = RESOURCES_METHODS
|
115
|
+
|
116
|
+
if option_with_hash(node)
|
117
|
+
option_node = node.arguments.all[1]
|
118
|
+
if hash_key_exist?(option_node, "only")
|
119
|
+
option_node.hash_value("only").to_s == "none" ? [] : Array(option_node.hash_value("only").to_object)
|
120
|
+
elsif hash_key_exist?(option_node, "except")
|
121
|
+
option_node.hash_value("except").to_s == "all" ? [] : (methods - Array(option_node.hash_value("except").to_object))
|
122
122
|
else
|
123
|
-
|
123
|
+
methods
|
124
124
|
end
|
125
125
|
else
|
126
|
-
|
126
|
+
methods
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
130
|
# get the route actions that should be generated by resource call.
|
131
131
|
def resource_methods(node)
|
132
|
-
|
133
|
-
|
134
|
-
if node
|
135
|
-
|
136
|
-
if
|
137
|
-
Array(
|
138
|
-
elsif
|
139
|
-
|
132
|
+
methods = RESOURCE_METHODS
|
133
|
+
|
134
|
+
if option_with_hash(node)
|
135
|
+
option_node = node.arguments.all[1]
|
136
|
+
if hash_key_exist?(option_node, "only")
|
137
|
+
option_node.hash_value("only").to_s == "none" ? [] : Array(option_node.hash_value("only").to_object)
|
138
|
+
elsif hash_key_exist?(option_node, "except")
|
139
|
+
option_node.hash_value("except").to_s == "all" ? [] : (methods - Array(option_node.hash_value("except").to_object))
|
140
140
|
else
|
141
|
-
|
141
|
+
methods
|
142
142
|
end
|
143
143
|
else
|
144
|
-
|
144
|
+
methods
|
145
145
|
end
|
146
146
|
end
|
147
|
+
|
148
|
+
def option_with_hash(node)
|
149
|
+
node.arguments.all.size > 1 && :bare_assoc_hash == node.arguments.all[1].sexp_type
|
150
|
+
end
|
151
|
+
|
152
|
+
def hash_key_exist?(node, key)
|
153
|
+
node.hash_keys && node.hash_keys.include?(key)
|
154
|
+
end
|
147
155
|
end
|
148
156
|
end
|
149
157
|
end
|
@@ -16,7 +16,8 @@ module RailsBestPractices
|
|
16
16
|
# then save it to as key in @variable_use_count hash, and add the call count (hash value).
|
17
17
|
def remember_variable_use_count(node)
|
18
18
|
variable_node = variable(node)
|
19
|
-
if variable_node && "self" != variable_node.to_s
|
19
|
+
if variable_node && "self" != variable_node.to_s && @last_variable_node != variable_node
|
20
|
+
@last_variable_node = variable_node
|
20
21
|
variable_use_count[variable_node.to_s] ||= 0
|
21
22
|
variable_use_count[variable_node.to_s] += 1
|
22
23
|
end
|
@@ -31,7 +31,9 @@ module RailsBestPractices
|
|
31
31
|
def start_command(node)
|
32
32
|
if "render" == node.message.to_s
|
33
33
|
hash_node = node.arguments.all[0]
|
34
|
-
if hash_node && hash_node.
|
34
|
+
if hash_node && :bare_assoc_hash == hash_node.sexp_type &&
|
35
|
+
hash_node.hash_keys.include?("partial") &&
|
36
|
+
!hash_node.hash_value("partial").to_s.include?('/')
|
35
37
|
add_error 'simplify render in views'
|
36
38
|
end
|
37
39
|
end
|
@@ -27,7 +27,7 @@ module RailsBestPractices
|
|
27
27
|
|
28
28
|
def initialize(options = {})
|
29
29
|
super()
|
30
|
-
@customize_count = options['customize_count'] ||
|
30
|
+
@customize_count = options['customize_count'] || 2
|
31
31
|
end
|
32
32
|
|
33
33
|
# check class define node to see if there are method define nodes whose first code line are duplicated.
|
data/rails_best_practices.yml
CHANGED
@@ -12,7 +12,7 @@ LawOfDemeterCheck: { }
|
|
12
12
|
UseObserverCheck: { }
|
13
13
|
IsolateSeedDataCheck: { }
|
14
14
|
AlwaysAddDbIndexCheck: { }
|
15
|
-
UseBeforeFilterCheck: { customize_count:
|
15
|
+
UseBeforeFilterCheck: { customize_count: 2 }
|
16
16
|
MoveCodeIntoControllerCheck: { }
|
17
17
|
MoveCodeIntoModelCheck: { use_count: 2 }
|
18
18
|
MoveCodeIntoHelperCheck: { array_count: 3 }
|
@@ -27,4 +27,4 @@ SimplifyRenderInControllersCheck: { }
|
|
27
27
|
RemoveEmptyHelpersCheck: { }
|
28
28
|
RemoveTabCheck: { }
|
29
29
|
RestrictAutoGeneratedRoutesCheck: { }
|
30
|
-
|
30
|
+
RemoveUnusedMethodsInModelsCheck: { except_methods: [] }
|
data/rake_rubies.sh
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
#!/bin/bash
|
2
|
-
rubies=( 1.
|
2
|
+
rubies=( 1.9.2-p180 1.9.2-p290 1.9.3-p0 )
|
3
3
|
gemset="rails_best_practices"
|
4
4
|
|
5
5
|
for x in ${rubies[*]}
|
6
6
|
do
|
7
|
-
|
8
|
-
bundle
|
9
|
-
rake spec:progress
|
7
|
+
echo $x@$gemset
|
8
|
+
rvm $x@$gemset do bundle exec rake spec:progress
|
10
9
|
done
|
@@ -1,13 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe RailsBestPractices::Core::Runner do
|
4
|
+
describe "load_plugin_reviews" do
|
5
|
+
shared_examples_for 'load_plugin_reviews' do
|
6
|
+
it "should load plugins in lib/rails_best_practices/plugins/reviews" do
|
7
|
+
runner = RailsBestPractices::Core::Runner.new
|
8
|
+
runner.instance_variable_get('@reviews').map(&:class).should include(RailsBestPractices::Plugins::Reviews::NotUseRailsRootReview)
|
9
|
+
end
|
10
|
+
end
|
4
11
|
|
5
|
-
|
12
|
+
context "given a path that ends with a slash" do
|
13
|
+
before { RailsBestPractices::Core::Runner.base_path = 'spec/fixtures/' }
|
14
|
+
it_should_behave_like 'load_plugin_reviews'
|
15
|
+
end
|
6
16
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
runner.instance_variable_get('@reviews').map(&:class).should include(RailsBestPractices::Plugins::Reviews::NotUseRailsRootReview)
|
17
|
+
context "given a path that does not end with a slash" do
|
18
|
+
before { RailsBestPractices::Core::Runner.base_path = 'spec/fixtures' }
|
19
|
+
it_should_behave_like 'load_plugin_reviews'
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
@@ -8,6 +8,7 @@ describe Sexp do
|
|
8
8
|
def test
|
9
9
|
ActiveRecord::Base.connection
|
10
10
|
end
|
11
|
+
alias :test_new :test
|
11
12
|
end
|
12
13
|
EOF
|
13
14
|
@node = parse_content(content)
|
@@ -28,6 +29,10 @@ describe Sexp do
|
|
28
29
|
it "should return const path line" do
|
29
30
|
@node.grep_node(:sexp_type => :const_path_ref).line.should == 3
|
30
31
|
end
|
32
|
+
|
33
|
+
it "should return alias line" do
|
34
|
+
@node.grep_node(:sexp_type => :alias).line.should == 5
|
35
|
+
end
|
31
36
|
end
|
32
37
|
|
33
38
|
describe "grep_nodes" do
|
@@ -239,6 +244,11 @@ describe Sexp do
|
|
239
244
|
node = parse_content("puts 'hello', 'world'").grep_node(:sexp_type => :args_add_block)
|
240
245
|
node.all.map(&:to_s).should == ["hello", "world"]
|
241
246
|
end
|
247
|
+
|
248
|
+
it "no error for args_add_star" do
|
249
|
+
node = parse_content("send(:\"\#{route}_url\", *args)").grep_node(:sexp_type => :args_add_block)
|
250
|
+
lambda { node.all }.should_not raise_error
|
251
|
+
end
|
242
252
|
end
|
243
253
|
|
244
254
|
describe "conditional_statement" do
|
@@ -410,6 +420,41 @@ describe Sexp do
|
|
410
420
|
node = parse_content("[]").grep_node(:sexp_type => :array)
|
411
421
|
node.array_values.should == []
|
412
422
|
end
|
423
|
+
|
424
|
+
it "should get array value with qwords" do
|
425
|
+
node = parse_content("%w(first_name last_name)").grep_node(:sexp_type => :qwords_add)
|
426
|
+
node.array_values.map(&:to_s).should == ["first_name", "last_name"]
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
describe "alias" do
|
431
|
+
context "method" do
|
432
|
+
before do
|
433
|
+
@node = parse_content("alias new old").grep_node(:sexp_type => :alias)
|
434
|
+
end
|
435
|
+
|
436
|
+
it "should get old_method" do
|
437
|
+
@node.old_method.to_s.should == "old"
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should get new_method" do
|
441
|
+
@node.new_method.to_s.should == "new"
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
context "symbol" do
|
446
|
+
before do
|
447
|
+
@node = parse_content("alias :new :old").grep_node(:sexp_type => :alias)
|
448
|
+
end
|
449
|
+
|
450
|
+
it "should get old_method" do
|
451
|
+
@node.old_method.to_s.should == "old"
|
452
|
+
end
|
453
|
+
|
454
|
+
it "should get new_method" do
|
455
|
+
@node.new_method.to_s.should == "new"
|
456
|
+
end
|
457
|
+
end
|
413
458
|
end
|
414
459
|
|
415
460
|
describe "to_object" do
|
@@ -89,6 +89,17 @@ describe RailsBestPractices::Prepares::ControllerPrepare do
|
|
89
89
|
methods.get_methods("PostsController").map(&:method_name).should == ["index", "show"]
|
90
90
|
end
|
91
91
|
|
92
|
+
it "extend inherited_resources with all actions" do
|
93
|
+
content =<<-EOF
|
94
|
+
class PostsController < InheritedResources::Base
|
95
|
+
actions :all, except: [:show]
|
96
|
+
end
|
97
|
+
EOF
|
98
|
+
runner.prepare('app/controllers/posts_controller.rb', content)
|
99
|
+
methods = RailsBestPractices::Prepares.controller_methods
|
100
|
+
methods.get_methods("PostsController").map(&:method_name).should == ["index", "new", "create", "edit", "update", "destroy"]
|
101
|
+
end
|
102
|
+
|
92
103
|
it "DSL inherit_resources" do
|
93
104
|
content =<<-EOF
|
94
105
|
class PostsController
|
@@ -181,6 +181,41 @@ describe RailsBestPractices::Prepares::ModelPrepare do
|
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
184
|
+
context "alias" do
|
185
|
+
it "should treat alias as method" do
|
186
|
+
content =<<-EOF
|
187
|
+
class Post < ActiveRecord::Base
|
188
|
+
alias :new :old
|
189
|
+
end
|
190
|
+
EOF
|
191
|
+
runner.prepare("app/models/post.rb", content)
|
192
|
+
methods = RailsBestPractices::Prepares.model_methods
|
193
|
+
methods.get_methods("Post").map(&:method_name).should == ["new"]
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should treat alias_method as method" do
|
197
|
+
content =<<-EOF
|
198
|
+
class Post < ActiveRecord::Base
|
199
|
+
alias_method :new, :old
|
200
|
+
end
|
201
|
+
EOF
|
202
|
+
runner.prepare("app/models/post.rb", content)
|
203
|
+
methods = RailsBestPractices::Prepares.model_methods
|
204
|
+
methods.get_methods("Post").map(&:method_name).should == ["new"]
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should treat alias_method_chain as method" do
|
208
|
+
content =<<-EOF
|
209
|
+
class Post < ActiveRecord::Base
|
210
|
+
alias_method_chain :method, :feature
|
211
|
+
end
|
212
|
+
EOF
|
213
|
+
runner.prepare("app/models/post.rb", content)
|
214
|
+
methods = RailsBestPractices::Prepares.model_methods
|
215
|
+
methods.get_methods("Post").map(&:method_name).should == ["method_with_feature", "method"]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
184
219
|
context "no error" do
|
185
220
|
it "should raised for finder_sql option" do
|
186
221
|
content =<<-EOF
|
@@ -5,7 +5,7 @@ describe RailsBestPractices::Reviews::MoveCodeIntoModelReview do
|
|
5
5
|
|
6
6
|
it "should move code into model" do
|
7
7
|
content =<<-EOF
|
8
|
-
<% if current_user && (current_user == @post.user || @post.editors.include?(current_user)) %>
|
8
|
+
<% if current_user && @post.user && (current_user == @post.user || @post.editors.include?(current_user)) %>
|
9
9
|
<%= link_to 'Edit this post', edit_post_url(@post) %>
|
10
10
|
<% end %>
|
11
11
|
EOF
|
@@ -16,7 +16,7 @@ describe RailsBestPractices::Reviews::MoveCodeIntoModelReview do
|
|
16
16
|
|
17
17
|
it "should move code into model with haml" do
|
18
18
|
content =<<-EOF
|
19
|
-
- if current_user && (current_user == @post.user || @post.editors.include?(current_user))
|
19
|
+
- if current_user && @post.user && (current_user == @post.user || @post.editors.include?(current_user))
|
20
20
|
= link_to 'Edit this post', edit_post_url(@post)
|
21
21
|
EOF
|
22
22
|
runner.review('app/views/posts/show.html.haml', content)
|
@@ -46,4 +46,13 @@ describe RailsBestPractices::Reviews::MoveCodeIntoModelReview do
|
|
46
46
|
runner.review('app/views/posts/show.html.erb', content)
|
47
47
|
runner.should have(0).errors
|
48
48
|
end
|
49
|
+
|
50
|
+
it "should not move code into model for multiple calls on same variable node" do
|
51
|
+
content =<<-EOF
|
52
|
+
<% if !job.company.blank? && job.company.title? %>
|
53
|
+
<% end %>
|
54
|
+
EOF
|
55
|
+
runner.review('app/views/jobs/show.html.erb', content)
|
56
|
+
runner.should have(0).errors
|
57
|
+
end
|
49
58
|
end
|
@@ -259,6 +259,68 @@ describe RailsBestPractices::Reviews::RemoveUnusedMethodsInModelsReview do
|
|
259
259
|
runner.on_complete
|
260
260
|
runner.should have(0).errors
|
261
261
|
end
|
262
|
+
|
263
|
+
it "should not remove unused methods for send" do
|
264
|
+
content =<<-EOF
|
265
|
+
class Post < ActiveRecord::Base
|
266
|
+
def find(user_id); end
|
267
|
+
end
|
268
|
+
EOF
|
269
|
+
runner.prepare('app/models/post.rb', content)
|
270
|
+
runner.review('app/models/post.rb', content)
|
271
|
+
content =<<-EOF
|
272
|
+
class PostsController < ApplicationController
|
273
|
+
def find
|
274
|
+
Post.new.send(:find, current_user.id)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
EOF
|
278
|
+
runner.review('app/controllers/posts_controller.rb', content)
|
279
|
+
runner.on_complete
|
280
|
+
runner.should have(0).errors
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should remove unused methods for send string_embexpre" do
|
284
|
+
content =<<-EOF
|
285
|
+
class Post < ActiveRecord::Base
|
286
|
+
def find_first; end
|
287
|
+
end
|
288
|
+
EOF
|
289
|
+
runner.prepare('app/models/post.rb', content)
|
290
|
+
runner.review('app/models/post.rb', content)
|
291
|
+
content =<<-EOF
|
292
|
+
class PostsController < ApplicationController
|
293
|
+
def find
|
294
|
+
type = "first"
|
295
|
+
Post.new.send("find_\#{type}")
|
296
|
+
end
|
297
|
+
end
|
298
|
+
EOF
|
299
|
+
runner.review('app/controllers/posts_controller.rb', content)
|
300
|
+
runner.on_complete
|
301
|
+
runner.should have(1).errors
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should remove unused methods for send variable" do
|
305
|
+
content =<<-EOF
|
306
|
+
class Post < ActiveRecord::Base
|
307
|
+
def first; end
|
308
|
+
end
|
309
|
+
EOF
|
310
|
+
runner.prepare('app/models/post.rb', content)
|
311
|
+
runner.review('app/models/post.rb', content)
|
312
|
+
content =<<-EOF
|
313
|
+
class PostsController < ApplicationController
|
314
|
+
def find
|
315
|
+
type = "first"
|
316
|
+
Post.new.send(type)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
EOF
|
320
|
+
runner.review('app/controllers/posts_controller.rb', content)
|
321
|
+
runner.on_complete
|
322
|
+
runner.should have(1).errors
|
323
|
+
end
|
262
324
|
end
|
263
325
|
|
264
326
|
context "protected" do
|
@@ -384,4 +446,108 @@ describe RailsBestPractices::Reviews::RemoveUnusedMethodsInModelsReview do
|
|
384
446
|
runner.errors[0].to_s.should == "app/models/post.rb:2 - remove unused methods (Post#active)"
|
385
447
|
end
|
386
448
|
end
|
449
|
+
|
450
|
+
context "alias" do
|
451
|
+
it "should not remove unused method with alias" do
|
452
|
+
content =<<-EOF
|
453
|
+
class Post < ActiveRecord::Base
|
454
|
+
def old; end
|
455
|
+
alias new old
|
456
|
+
end
|
457
|
+
EOF
|
458
|
+
runner.prepare("app/models/post.rb", content)
|
459
|
+
runner.review("app/models/post.rb", content)
|
460
|
+
content =<<-EOF
|
461
|
+
class PostsController < ApplicationController
|
462
|
+
def show
|
463
|
+
@post.new
|
464
|
+
end
|
465
|
+
end
|
466
|
+
EOF
|
467
|
+
runner.review("app/controllers/posts_controller.rb", content)
|
468
|
+
runner.on_complete
|
469
|
+
runner.should have(0).errors
|
470
|
+
end
|
471
|
+
|
472
|
+
it "should not remove unused method with symbol alias" do
|
473
|
+
content =<<-EOF
|
474
|
+
class Post < ActiveRecord::Base
|
475
|
+
def old; end
|
476
|
+
alias :new :old
|
477
|
+
end
|
478
|
+
EOF
|
479
|
+
runner.prepare("app/models/post.rb", content)
|
480
|
+
runner.review("app/models/post.rb", content)
|
481
|
+
content =<<-EOF
|
482
|
+
class PostsController < ApplicationController
|
483
|
+
def show
|
484
|
+
@post.new
|
485
|
+
end
|
486
|
+
end
|
487
|
+
EOF
|
488
|
+
runner.review("app/controllers/posts_controller.rb", content)
|
489
|
+
runner.on_complete
|
490
|
+
runner.should have(0).errors
|
491
|
+
end
|
492
|
+
|
493
|
+
it "should not remove unused method with alias_method" do
|
494
|
+
content =<<-EOF
|
495
|
+
class Post < ActiveRecord::Base
|
496
|
+
def old; end
|
497
|
+
alias_method :new, :old
|
498
|
+
end
|
499
|
+
EOF
|
500
|
+
runner.prepare("app/models/post.rb", content)
|
501
|
+
runner.review("app/models/post.rb", content)
|
502
|
+
content =<<-EOF
|
503
|
+
class PostsController < ApplicationController
|
504
|
+
def show
|
505
|
+
@post.new
|
506
|
+
end
|
507
|
+
end
|
508
|
+
EOF
|
509
|
+
runner.review("app/controllers/posts_controller.rb", content)
|
510
|
+
runner.on_complete
|
511
|
+
runner.should have(0).errors
|
512
|
+
end
|
513
|
+
|
514
|
+
it "should not remove unused method with alias_method_chain" do
|
515
|
+
content =<<-EOF
|
516
|
+
class Post < ActiveRecord::Base
|
517
|
+
def method_with_feature; end
|
518
|
+
alias_method_chain :method, :feature
|
519
|
+
end
|
520
|
+
EOF
|
521
|
+
runner.prepare("app/models/post.rb", content)
|
522
|
+
runner.review("app/models/post.rb", content)
|
523
|
+
content =<<-EOF
|
524
|
+
class PostsController < ApplicationController
|
525
|
+
def show
|
526
|
+
@post.method
|
527
|
+
end
|
528
|
+
end
|
529
|
+
EOF
|
530
|
+
runner.review("app/controllers/posts_controller.rb", content)
|
531
|
+
runner.on_complete
|
532
|
+
runner.should have(0).errors
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
context "methods hash" do
|
537
|
+
it "should not remove unused method with methods hash" do
|
538
|
+
content =<<-EOF
|
539
|
+
class Post < ActiveRecord::Base
|
540
|
+
def to_xml(options = {})
|
541
|
+
super options.merge(:exclude => :visible, :methods => [:is_discussion_conversation])
|
542
|
+
end
|
543
|
+
|
544
|
+
def is_discussion_conversation; end
|
545
|
+
end
|
546
|
+
EOF
|
547
|
+
runner.prepare("app/models/post.rb", content)
|
548
|
+
runner.review("app/models/post.rb", content)
|
549
|
+
runner.on_complete
|
550
|
+
runner.should have(0).errors
|
551
|
+
end
|
552
|
+
end
|
387
553
|
end
|
@@ -55,6 +55,26 @@ describe RailsBestPractices::Reviews::RestrictAutoGeneratedRoutesReview do
|
|
55
55
|
runner.should have(0).errors
|
56
56
|
end
|
57
57
|
|
58
|
+
it "should not restrict auto-generated routes with :only => :none" do
|
59
|
+
content =<<-EOF
|
60
|
+
ActionController::Routing::Routes.draw do |map|
|
61
|
+
map.resources :posts, :only => :none
|
62
|
+
end
|
63
|
+
EOF
|
64
|
+
runner.review('config/routes.rb', content)
|
65
|
+
runner.should have(0).errors
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should not restrict auto-generated routes with :except => :all" do
|
69
|
+
content =<<-EOF
|
70
|
+
ActionController::Routing::Routes.draw do |map|
|
71
|
+
map.resources :posts, :except => :all
|
72
|
+
end
|
73
|
+
EOF
|
74
|
+
runner.review('config/routes.rb', content)
|
75
|
+
runner.should have(0).errors
|
76
|
+
end
|
77
|
+
|
58
78
|
describe "specify a controller" do
|
59
79
|
it "should restrict auto-generated routes" do
|
60
80
|
content =<<-EOF
|
@@ -14,7 +14,7 @@ describe RailsBestPractices::Reviews::SimplifyRenderInViewsReview do
|
|
14
14
|
|
15
15
|
it "should simplify render partial with object" do
|
16
16
|
content =<<-EOF
|
17
|
-
<%= render :partial => '
|
17
|
+
<%= render :partial => 'post', :object => @post %>
|
18
18
|
EOF
|
19
19
|
runner.review('app/views/posts/index.html.erb', content)
|
20
20
|
runner.should have(1).errors
|
@@ -32,7 +32,7 @@ describe RailsBestPractices::Reviews::SimplifyRenderInViewsReview do
|
|
32
32
|
|
33
33
|
it "should simplify render partial with local variables" do
|
34
34
|
content =<<-EOF
|
35
|
-
<%= render :partial => '
|
35
|
+
<%= render :partial => 'comment', :locals => { :parent => post } %>
|
36
36
|
EOF
|
37
37
|
runner.review('app/views/posts/index.html.erb', content)
|
38
38
|
runner.should have(1).errors
|
@@ -66,7 +66,15 @@ describe RailsBestPractices::Reviews::SimplifyRenderInViewsReview do
|
|
66
66
|
|
67
67
|
it "should not simplify render partial with local variables" do
|
68
68
|
content =<<-EOF
|
69
|
-
<%= render '
|
69
|
+
<%= render 'comment', :parent => post %>
|
70
|
+
EOF
|
71
|
+
runner.review('app/views/posts/index.html.erb', content)
|
72
|
+
runner.should have(0).errors
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should not simplify render partial with complex partial" do
|
76
|
+
content =<<-EOF
|
77
|
+
<%= render :partial => 'shared/post', :object => @post %>
|
70
78
|
EOF
|
71
79
|
runner.review('app/views/posts/index.html.erb', content)
|
72
80
|
runner.should have(0).errors
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rails_best_practices
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.
|
5
|
+
version: 1.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Richard Huang
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-11-13 00:00:00 +08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -298,7 +298,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
298
298
|
requirements:
|
299
299
|
- - ">="
|
300
300
|
- !ruby/object:Gem::Version
|
301
|
-
hash:
|
301
|
+
hash: 3527788243321139328
|
302
302
|
segments:
|
303
303
|
- 0
|
304
304
|
version: "0"
|