rails_best_practices 1.11.1 → 1.12.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/.gitignore +1 -1
- data/README.md +3 -1
- data/assets/result.html.erb +15 -13
- data/lib/rails_best_practices/analyzer.rb +17 -11
- data/lib/rails_best_practices/core/error.rb +1 -2
- data/lib/rails_best_practices/reviews.rb +1 -0
- data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +18 -3
- data/lib/rails_best_practices/reviews/not_rescue_exception_review.rb +28 -0
- data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +59 -26
- data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +8 -3
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.yml +1 -0
- data/spec/rails_best_practices/analyzer_spec.rb +0 -18
- data/spec/rails_best_practices/core/error_spec.rb +0 -4
- data/spec/rails_best_practices/reviews/always_add_db_index_review_spec.rb +18 -0
- data/spec/rails_best_practices/reviews/not_rescue_exception_spec.rb +95 -0
- data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +16 -6
- data/spec/rails_best_practices/reviews/remove_empty_helpers_review_spec.rb +9 -0
- metadata +91 -28
data/.gitignore
CHANGED
data/README.md
CHANGED
|
@@ -128,6 +128,7 @@ Now you can customize this configuration file, the default configuration is as f
|
|
|
128
128
|
MoveFinderToNamedScopeCheck: { }
|
|
129
129
|
MoveModelLogicIntoModelCheck: { use_count: 4 }
|
|
130
130
|
NeedlessDeepNestingCheck: { nested_count: 2 }
|
|
131
|
+
NotRescueExceptionCheck: { }
|
|
131
132
|
NotUseDefaultRouteCheck: { }
|
|
132
133
|
NotUseTimeAgoInWordsCheck: {}
|
|
133
134
|
OveruseRouteCustomizationsCheck: { customize_count: 3 }
|
|
@@ -219,9 +220,10 @@ Other
|
|
|
219
220
|
|
|
220
221
|
1. Remove trailing whitespace
|
|
221
222
|
2. Remove tab (disabled by default)
|
|
222
|
-
3. Hash
|
|
223
|
+
3. Hash syntax (disabled by default)
|
|
223
224
|
4. Use parentheses in method def (disabled by default)
|
|
224
225
|
5. Long line (disabled by default)
|
|
226
|
+
6. Not rescue exception
|
|
225
227
|
|
|
226
228
|
## Write Your Own Check List
|
|
227
229
|
|
data/assets/result.html.erb
CHANGED
|
@@ -72,22 +72,24 @@
|
|
|
72
72
|
<% end %>
|
|
73
73
|
</p>
|
|
74
74
|
<table>
|
|
75
|
-
<%
|
|
75
|
+
<% unless @errors.empty? %>
|
|
76
|
+
<% columnize(@error_types, 3).each do |row| %>
|
|
77
|
+
<tr>
|
|
78
|
+
<% row.map { |error_type| error_type.split(':').last }.each do |error_type| %>
|
|
79
|
+
<td>
|
|
80
|
+
<input type="checkbox" class="error-type" id="<%= error_type %>" value="<%= error_type %>"
|
|
81
|
+
/> <label for="<%= error_type %>"><%= error_type.sub(/(Check|Review)$/, '').gsub(/([a-z\d])([A-Z])/,'\1 \2') %></label>
|
|
82
|
+
</td>
|
|
83
|
+
<% end %>
|
|
84
|
+
</tr>
|
|
85
|
+
<% end %>
|
|
76
86
|
<tr>
|
|
77
|
-
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
</td>
|
|
82
|
-
<% end %>
|
|
87
|
+
<td colspan="3">
|
|
88
|
+
<button id="show-all">Check all</button>
|
|
89
|
+
<button id="show-none">Uncheck all</button>
|
|
90
|
+
</td>
|
|
83
91
|
</tr>
|
|
84
92
|
<% end %>
|
|
85
|
-
<tr>
|
|
86
|
-
<td colspan="3">
|
|
87
|
-
<button id="show-all">Check all</button>
|
|
88
|
-
<button id="show-none">Uncheck all</button>
|
|
89
|
-
</td>
|
|
90
|
-
</tr>
|
|
91
93
|
</table>
|
|
92
94
|
<table class="result">
|
|
93
95
|
<thead>
|
|
@@ -17,7 +17,7 @@ module RailsBestPractices
|
|
|
17
17
|
#
|
|
18
18
|
# After analyzing, output the violations.
|
|
19
19
|
class Analyzer
|
|
20
|
-
attr_accessor :runner
|
|
20
|
+
attr_accessor :runner
|
|
21
21
|
|
|
22
22
|
DEFAULT_CONFIG = File.join(File.dirname(__FILE__), "..", "..", "rails_best_practices.yml")
|
|
23
23
|
|
|
@@ -49,21 +49,22 @@ module RailsBestPractices
|
|
|
49
49
|
def analyze
|
|
50
50
|
@options["exclude"] ||= []
|
|
51
51
|
@options["only"] ||= []
|
|
52
|
-
@options["output-file"] ||= "rails_best_practices_output.html"
|
|
53
52
|
|
|
54
53
|
Core::Runner.base_path = @path
|
|
55
54
|
@runner = Core::Runner.new
|
|
56
55
|
|
|
57
56
|
analyze_source_codes
|
|
58
57
|
analyze_vcs
|
|
59
|
-
|
|
60
|
-
errors_filter_block.call(errors) if errors_filter_block
|
|
61
58
|
end
|
|
62
59
|
|
|
63
60
|
# Output the analyze result.
|
|
64
61
|
def output
|
|
65
62
|
if @options["format"] == 'html'
|
|
63
|
+
@options["output-file"] ||= "rails_best_practices_output.html"
|
|
66
64
|
output_html_errors
|
|
65
|
+
elsif @options["format"] == 'yaml'
|
|
66
|
+
@options["output-file"] ||= "rails_best_practices_output.yaml"
|
|
67
|
+
output_yaml_errors
|
|
67
68
|
else
|
|
68
69
|
output_terminal_errors
|
|
69
70
|
end
|
|
@@ -181,7 +182,7 @@ module RailsBestPractices
|
|
|
181
182
|
def load_hg_info
|
|
182
183
|
hg_progressbar = ProgressBar.new('Hg Info', errors.size) if display_bar?
|
|
183
184
|
errors.each do |error|
|
|
184
|
-
hg_info = `cd #{@runner.class.base_path}
|
|
185
|
+
hg_info = `cd #{@runner.class.base_path} && hg blame -lvcu #{error.filename[@runner.class.base_path.size..-1].gsub(/^\//, "")} | sed -n /:#{error.line_number.split(',').first}:/p`
|
|
185
186
|
unless hg_info == ""
|
|
186
187
|
hg_commit_username = hg_info.split(':')[0].strip
|
|
187
188
|
error.hg_username = hg_commit_username.split(/\ /)[0..-2].join(' ')
|
|
@@ -197,7 +198,7 @@ module RailsBestPractices
|
|
|
197
198
|
git_progressbar = ProgressBar.new('Git Info', errors.size) if display_bar?
|
|
198
199
|
start = @runner.class.base_path =~ /\/$/ ? @runner.class.base_path.size : @runner.class.base_path.size + 1
|
|
199
200
|
errors.each do |error|
|
|
200
|
-
git_info = `cd #{@runner.class.base_path}
|
|
201
|
+
git_info = `cd #{@runner.class.base_path} && git blame -L #{error.line_number.split(',').first},+1 #{error.filename[start..-1]}`
|
|
201
202
|
unless git_info == ""
|
|
202
203
|
git_commit, git_username = git_info.split(/\d{4}-\d{2}-\d{2}/).first.split("(")
|
|
203
204
|
error.git_commit = git_commit.split(" ").first.strip
|
|
@@ -214,7 +215,7 @@ module RailsBestPractices
|
|
|
214
215
|
template = @options["template"] ? File.read(File.expand_path(@options["template"])) : File.read(File.join(File.dirname(__FILE__), "..", "..", "assets", "result.html.erb"))
|
|
215
216
|
|
|
216
217
|
if @options["with-github"]
|
|
217
|
-
last_commit_id = @options["last-commit-id"] ? @options["last-commit-id"] : `cd #{@runner.class.base_path}
|
|
218
|
+
last_commit_id = @options["last-commit-id"] ? @options["last-commit-id"] : `cd #{@runner.class.base_path} && git rev-parse HEAD`.chomp
|
|
218
219
|
end
|
|
219
220
|
File.open(@options["output-file"], "w+") do |file|
|
|
220
221
|
eruby = Erubis::Eruby.new(template)
|
|
@@ -232,6 +233,13 @@ module RailsBestPractices
|
|
|
232
233
|
end
|
|
233
234
|
end
|
|
234
235
|
|
|
236
|
+
# output errors with yaml format.
|
|
237
|
+
def output_yaml_errors
|
|
238
|
+
File.open(@options["output-file"], "w+") do |file|
|
|
239
|
+
file.write YAML.dump(errors)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
235
243
|
# plain output with color.
|
|
236
244
|
#
|
|
237
245
|
# @param [String] message to output
|
|
@@ -253,10 +261,8 @@ module RailsBestPractices
|
|
|
253
261
|
|
|
254
262
|
# analyze version control system info.
|
|
255
263
|
def analyze_vcs
|
|
256
|
-
if @options["
|
|
257
|
-
|
|
258
|
-
load_hg_info if @options["with-hg"]
|
|
259
|
-
end
|
|
264
|
+
load_git_info if @options["with-git"]
|
|
265
|
+
load_hg_info if @options["with-hg"]
|
|
260
266
|
end
|
|
261
267
|
|
|
262
268
|
# if disaply progress bar.
|
|
@@ -6,7 +6,7 @@ module RailsBestPractices
|
|
|
6
6
|
# it indicates the filenname, line number and error message for the violation.
|
|
7
7
|
class Error < CodeAnalyzer::Warning
|
|
8
8
|
attr_reader :type, :url
|
|
9
|
-
attr_accessor :git_commit, :git_username, :hg_commit, :hg_username
|
|
9
|
+
attr_accessor :git_commit, :git_username, :hg_commit, :hg_username
|
|
10
10
|
|
|
11
11
|
def initialize(options={})
|
|
12
12
|
super
|
|
@@ -16,7 +16,6 @@ module RailsBestPractices
|
|
|
16
16
|
@git_username = options[:git_username]
|
|
17
17
|
@hg_commit = options[:hg_commit]
|
|
18
18
|
@hg_username = options[:hg_username]
|
|
19
|
-
@highlight = false
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
def short_filename
|
|
@@ -33,3 +33,4 @@ require 'rails_best_practices/reviews/not_use_time_ago_in_words_review'
|
|
|
33
33
|
require 'rails_best_practices/reviews/protect_mass_assignment_review'
|
|
34
34
|
require 'rails_best_practices/reviews/use_parentheses_in_method_def_review'
|
|
35
35
|
require 'rails_best_practices/reviews/hash_syntax_review'
|
|
36
|
+
require 'rails_best_practices/reviews/not_rescue_exception_review'
|
|
@@ -42,6 +42,8 @@ module RailsBestPractices
|
|
|
42
42
|
add_callback :start_command_call do |node|
|
|
43
43
|
if %w(integer string).include? node.message.to_s
|
|
44
44
|
remember_foreign_key_columns(node)
|
|
45
|
+
elsif "index" == node.message.to_s
|
|
46
|
+
remember_index_columns_inside_table(node)
|
|
45
47
|
end
|
|
46
48
|
end
|
|
47
49
|
|
|
@@ -57,7 +59,7 @@ module RailsBestPractices
|
|
|
57
59
|
when "create_table"
|
|
58
60
|
remember_table_nodes(node)
|
|
59
61
|
when "add_index"
|
|
60
|
-
|
|
62
|
+
remember_index_columns_outside_table(node)
|
|
61
63
|
end
|
|
62
64
|
end
|
|
63
65
|
|
|
@@ -81,8 +83,10 @@ module RailsBestPractices
|
|
|
81
83
|
end
|
|
82
84
|
|
|
83
85
|
private
|
|
84
|
-
# remember the node as index columns
|
|
85
|
-
|
|
86
|
+
# remember the node as index columns, when used outside a table
|
|
87
|
+
# block, i.e.
|
|
88
|
+
# add_index :table_name, :column_name
|
|
89
|
+
def remember_index_columns_outside_table(node)
|
|
86
90
|
table_name = node.arguments.all.first.to_s
|
|
87
91
|
index_column = node.arguments.all[1].to_object
|
|
88
92
|
|
|
@@ -90,6 +94,17 @@ module RailsBestPractices
|
|
|
90
94
|
@index_columns[table_name] << index_column
|
|
91
95
|
end
|
|
92
96
|
|
|
97
|
+
# remember the node as index columns, when used inside a table
|
|
98
|
+
# block, i.e.
|
|
99
|
+
# t.index [:column_name, ...]
|
|
100
|
+
def remember_index_columns_inside_table(node)
|
|
101
|
+
table_name = @table_name
|
|
102
|
+
index_column = node.arguments.all.first.to_object
|
|
103
|
+
|
|
104
|
+
@index_columns[table_name] ||= []
|
|
105
|
+
@index_columns[table_name] << index_column
|
|
106
|
+
end
|
|
107
|
+
|
|
93
108
|
# remember table nodes
|
|
94
109
|
def remember_table_nodes(node)
|
|
95
110
|
@table_name = node.arguments.all.first.to_s
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'rails_best_practices/reviews/review'
|
|
3
|
+
|
|
4
|
+
module RailsBestPractices
|
|
5
|
+
module Reviews
|
|
6
|
+
# Review all code to make sure we don't rescue Exception
|
|
7
|
+
# This is a common mistake by Java or C# devs in ruby.
|
|
8
|
+
#
|
|
9
|
+
# See the best practice details here http://rails-bestpractices.com/posts/702-don-t-rescue-exception-rescue-standarderror
|
|
10
|
+
#
|
|
11
|
+
# Implementation:
|
|
12
|
+
#
|
|
13
|
+
# Review process:
|
|
14
|
+
# check all rescue node to see if its type is Exception
|
|
15
|
+
class NotRescueExceptionReview < Review
|
|
16
|
+
interesting_nodes :rescue
|
|
17
|
+
interesting_files ALL_FILES
|
|
18
|
+
url "http://rails-bestpractices.com/posts/702-don-t-rescue-exception-rescue-standarderror"
|
|
19
|
+
|
|
20
|
+
# check rescue node to see if its type is Exception
|
|
21
|
+
add_callback :start_rescue do |rescue_node|
|
|
22
|
+
if rescue_node.exception_classes.any? { |rescue_class| "Exception" == rescue_class.to_s }
|
|
23
|
+
add_error "not rescue Exception", rescue_node.file, rescue_node.exception_classes.first.line
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -3,56 +3,89 @@ require 'rails_best_practices/reviews/review'
|
|
|
3
3
|
|
|
4
4
|
module RailsBestPractices
|
|
5
5
|
module Reviews
|
|
6
|
-
# Review model files to make sure to use attr_accessible or
|
|
6
|
+
# Review model files to make sure to use attr_accessible, attr_protected or strong_parameters to protect mass assignment.
|
|
7
7
|
#
|
|
8
8
|
# See the best practices details here http://rails-bestpractices.com/posts/148-protect-mass-assignment.
|
|
9
9
|
#
|
|
10
10
|
# Implmentation:
|
|
11
11
|
#
|
|
12
12
|
# Review process:
|
|
13
|
-
# check
|
|
13
|
+
# check nodes to see if there is a command with message attr_accessible or attr_protected,
|
|
14
|
+
# or include ActiveModel::ForbiddenAttributesProtection.
|
|
14
15
|
class ProtectMassAssignmentReview < Review
|
|
15
|
-
interesting_nodes :class
|
|
16
16
|
interesting_files MODEL_FILES
|
|
17
|
+
interesting_nodes :class, :command, :var_ref, :vcall, :fcall
|
|
17
18
|
url "http://rails-bestpractices.com/posts/148-protect-mass-assignment"
|
|
18
19
|
|
|
19
|
-
#
|
|
20
|
-
# if config.active_record.whitelist_attributes is not set true,
|
|
21
|
-
# and if none of them is with message attr_accessible or attr_protected,
|
|
22
|
-
# and if not use devise or authlogic,
|
|
23
|
-
# then it should add attr_accessible or attr_protected to protect mass assignment.
|
|
20
|
+
# we treat it as mass assignment by default.
|
|
24
21
|
add_callback :start_class do |node|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
@mass_assignement = true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# check if it is ActiveRecord::Base subclass and
|
|
26
|
+
# if it sets config.active_record.whitelist_attributes to true.
|
|
27
|
+
add_callback :end_class do |node|
|
|
28
|
+
check_active_record(node)
|
|
29
|
+
check_whitelist_attributes_config
|
|
30
|
+
|
|
31
|
+
add_error "protect mass assignment" if @mass_assignement
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# check if it is attr_accessible or attr_protected command,
|
|
35
|
+
# if it uses strong_parameters,
|
|
36
|
+
# and if it uses devise.
|
|
37
|
+
add_callback :start_command do |node|
|
|
38
|
+
check_rails_builtin(node)
|
|
39
|
+
check_strong_parameters(node)
|
|
40
|
+
check_devise(node)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# check if it is attr_accessible, attr_protected, acts_as_authlogic without parameters.
|
|
44
|
+
add_callback :start_var_ref, :start_vcall do |node|
|
|
45
|
+
check_rails_builtin(node)
|
|
46
|
+
check_authlogic(node)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# check if it uses authlogic.
|
|
50
|
+
add_callback :start_fcall do |node|
|
|
51
|
+
check_authlogic(node)
|
|
29
52
|
end
|
|
30
53
|
|
|
31
54
|
private
|
|
32
|
-
def
|
|
33
|
-
Prepares.configs["config.active_record.whitelist_attributes"]
|
|
55
|
+
def check_whitelist_attributes_config
|
|
56
|
+
if "true" == Prepares.configs["config.active_record.whitelist_attributes"]
|
|
57
|
+
@mass_assignement = false
|
|
58
|
+
end
|
|
34
59
|
end
|
|
35
60
|
|
|
36
|
-
def
|
|
37
|
-
node.
|
|
38
|
-
|
|
61
|
+
def check_rails_builtin(node)
|
|
62
|
+
if [node.to_s, node.message.to_s].any? { |str| %w(attr_accessible attr_protected).include? str }
|
|
63
|
+
@mass_assignement = false
|
|
64
|
+
end
|
|
39
65
|
end
|
|
40
66
|
|
|
41
|
-
def
|
|
42
|
-
|
|
67
|
+
def check_strong_parameters(command_node)
|
|
68
|
+
if "include" == command_node.message.to_s && "ActiveModel::ForbiddenAttributesProtection" == command_node.arguments.all.first.to_s
|
|
69
|
+
@mass_assignement = false
|
|
70
|
+
end
|
|
43
71
|
end
|
|
44
72
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
73
|
+
def check_devise(command_node)
|
|
74
|
+
if "devise" == command_node.message.to_s
|
|
75
|
+
@mass_assignement = false
|
|
76
|
+
end
|
|
48
77
|
end
|
|
49
78
|
|
|
50
|
-
def
|
|
51
|
-
node.
|
|
79
|
+
def check_authlogic(node)
|
|
80
|
+
if [node.to_s, node.message.to_s].include? "acts_as_authentic"
|
|
81
|
+
@mass_assignement = false
|
|
82
|
+
end
|
|
52
83
|
end
|
|
53
84
|
|
|
54
|
-
def
|
|
55
|
-
|
|
85
|
+
def check_active_record(const_path_ref_node)
|
|
86
|
+
if "ActiveRecord::Base" != const_path_ref_node.base_class.to_s
|
|
87
|
+
@mass_assignement = false
|
|
88
|
+
end
|
|
56
89
|
end
|
|
57
90
|
end
|
|
58
91
|
end
|
|
@@ -17,11 +17,16 @@ module RailsBestPractices
|
|
|
17
17
|
url "http://rails-bestpractices.com/posts/72-remove-empty-helpers"
|
|
18
18
|
|
|
19
19
|
# check the body of module node, if it is nil, then it should be removed.
|
|
20
|
-
add_callback :start_module do |
|
|
21
|
-
if
|
|
22
|
-
add_error "remove empty helpers"
|
|
20
|
+
add_callback :start_module do |module_node|
|
|
21
|
+
if "ApplicationHelper" != module_node.module_name.to_s && empty_body?(module_node)
|
|
22
|
+
add_error "remove empty helpers"
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
def empty_body?(module_node)
|
|
28
|
+
s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil) == module_node.body
|
|
29
|
+
end
|
|
25
30
|
end
|
|
26
31
|
end
|
|
27
32
|
end
|
data/rails_best_practices.yml
CHANGED
|
@@ -12,6 +12,7 @@ MoveCodeIntoModelCheck: { use_count: 2 }
|
|
|
12
12
|
MoveFinderToNamedScopeCheck: { }
|
|
13
13
|
MoveModelLogicIntoModelCheck: { use_count: 4 }
|
|
14
14
|
NeedlessDeepNestingCheck: { nested_count: 2 }
|
|
15
|
+
NotRescueExceptionCheck: { }
|
|
15
16
|
NotUseDefaultRouteCheck: { }
|
|
16
17
|
NotUseTimeAgoInWordsCheck: { }
|
|
17
18
|
OveruseRouteCustomizationsCheck: { customize_count: 3 }
|
|
@@ -43,23 +43,5 @@ module RailsBestPractices
|
|
|
43
43
|
result.should == ["app/models/user.rb:10 - law of demeter".red, "app/models/post.rb:100 - use query attribute".red, "\nPlease go to http://rails-bestpractices.com to see more useful Rails Best Practices.".green, "\nFound 2 warnings.".red].join("\n") + "\n"
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
|
-
|
|
47
|
-
describe "errors_filter_block" do
|
|
48
|
-
it "should call errors_filter_block after analyze" do
|
|
49
|
-
analyzer = Analyzer.new("path", "silent" => true)
|
|
50
|
-
analyzer.errors_filter_block = lambda { |errors| errors.each { |error| error.highlight = true } }
|
|
51
|
-
analyzer.stub(:expand_dirs_to_files).and_return([])
|
|
52
|
-
analyzer.stub(:file_sort).and_return([])
|
|
53
|
-
analyzer.stub(:file_ignore).and_return([])
|
|
54
|
-
analyzer.stub(:process)
|
|
55
|
-
runner = stub
|
|
56
|
-
runner.stub(:color=)
|
|
57
|
-
errors = [Core::Error.new, Core::Error.new]
|
|
58
|
-
Core::Runner.stub(:new).and_return(runner)
|
|
59
|
-
runner.stub(:errors).and_return(errors)
|
|
60
|
-
analyzer.analyze
|
|
61
|
-
analyzer.send(:errors).should be_all(&:highlight)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
46
|
end
|
|
65
47
|
end
|
|
@@ -2,10 +2,6 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
module RailsBestPractices::Core
|
|
4
4
|
describe Error do
|
|
5
|
-
it "should have highlight with false by default" do
|
|
6
|
-
Error.new.highlight.should == false
|
|
7
|
-
end
|
|
8
|
-
|
|
9
5
|
it "should return error with filename, line number and message" do
|
|
10
6
|
Error.new(
|
|
11
7
|
filename: "app/models/user.rb",
|
|
@@ -153,6 +153,24 @@ module RailsBestPractices
|
|
|
153
153
|
runner.should have(0).errors
|
|
154
154
|
end
|
|
155
155
|
|
|
156
|
+
it "should not always add db index with t.index" do
|
|
157
|
+
# e.g. schema_plus creates indices like this https://github.com/lomba/schema_plus
|
|
158
|
+
content = <<-EOF
|
|
159
|
+
ActiveRecord::Schema.define(version: 20100603080629) do
|
|
160
|
+
create_table "comments", force: true do |t|
|
|
161
|
+
t.string "content"
|
|
162
|
+
t.integer "post_id"
|
|
163
|
+
t.index ["post_id"], :name => "index_comments_on_post_id"
|
|
164
|
+
end
|
|
165
|
+
create_table "posts", force: true do |t|
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
EOF
|
|
169
|
+
runner.review('db/schema.rb', content)
|
|
170
|
+
runner.after_review
|
|
171
|
+
runner.should have(0).errors
|
|
172
|
+
end
|
|
173
|
+
|
|
156
174
|
it "should not always add db index with only _type column" do
|
|
157
175
|
content = <<-EOF
|
|
158
176
|
ActiveRecord::Schema.define(version: 20100603080629) do
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module RailsBestPractices
|
|
4
|
+
module Reviews
|
|
5
|
+
describe NotRescueExceptionReview do
|
|
6
|
+
let(:runner) { Core::Runner.new(reviews: NotRescueExceptionReview.new) }
|
|
7
|
+
|
|
8
|
+
describe "not_rescue_exception" do
|
|
9
|
+
it "should not rescue exception in method rescue with named var" do
|
|
10
|
+
content =<<-EOF
|
|
11
|
+
def my_method
|
|
12
|
+
do_something
|
|
13
|
+
rescue Exception => e
|
|
14
|
+
logger.error e
|
|
15
|
+
end
|
|
16
|
+
EOF
|
|
17
|
+
runner.review('app/helpers/posts_helper.rb', content)
|
|
18
|
+
runner.should have(1).errors
|
|
19
|
+
runner.errors[0].to_s.should == "app/helpers/posts_helper.rb:3 - not rescue Exception"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should not rescue exception in method rescue without named var" do
|
|
23
|
+
content =<<-EOF
|
|
24
|
+
def my_method
|
|
25
|
+
do_something
|
|
26
|
+
rescue Exception
|
|
27
|
+
logger.error $!
|
|
28
|
+
end
|
|
29
|
+
EOF
|
|
30
|
+
runner.review('app/helpers/posts_helper.rb', content)
|
|
31
|
+
runner.should have(1).errors
|
|
32
|
+
runner.errors[0].to_s.should == "app/helpers/posts_helper.rb:3 - not rescue Exception"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should not rescue exception in block rescue with named var" do
|
|
36
|
+
content =<<-EOF
|
|
37
|
+
def my_method
|
|
38
|
+
begin
|
|
39
|
+
do_something
|
|
40
|
+
rescue Exception => e
|
|
41
|
+
logger.error e
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
EOF
|
|
45
|
+
runner.review('app/helpers/posts_helper.rb', content)
|
|
46
|
+
runner.should have(1).errors
|
|
47
|
+
runner.errors[0].to_s.should == "app/helpers/posts_helper.rb:4 - not rescue Exception"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should not rescue exception in block rescue without named var" do
|
|
51
|
+
content =<<-EOF
|
|
52
|
+
def my_method
|
|
53
|
+
begin
|
|
54
|
+
do_something
|
|
55
|
+
rescue Exception
|
|
56
|
+
logger.error $!
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
EOF
|
|
60
|
+
runner.review('app/helpers/posts_helper.rb', content)
|
|
61
|
+
runner.should have(1).errors
|
|
62
|
+
runner.errors[0].to_s.should == "app/helpers/posts_helper.rb:4 - not rescue Exception"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should allow rescue implicit StandardError in block rescue without named var" do
|
|
66
|
+
content =<<-EOF
|
|
67
|
+
def my_method
|
|
68
|
+
begin
|
|
69
|
+
do_something
|
|
70
|
+
rescue
|
|
71
|
+
logger.error $!
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
EOF
|
|
75
|
+
runner.review('app/helpers/posts_helper.rb', content)
|
|
76
|
+
runner.should have(0).errors
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should allow rescue explicit StandardError in block rescue without named var" do
|
|
80
|
+
content =<<-EOF
|
|
81
|
+
def my_method
|
|
82
|
+
begin
|
|
83
|
+
do_something
|
|
84
|
+
rescue StandardError
|
|
85
|
+
logger.error $!
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
EOF
|
|
89
|
+
runner.review('app/helpers/posts_helper.rb', content)
|
|
90
|
+
runner.should have(0).errors
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -95,13 +95,23 @@ module RailsBestPractices
|
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
it "should not protect mass assignment if checking non ActiveRecord::Base inherited model" do
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
content =<<-EOF
|
|
99
|
+
class User < Person
|
|
100
|
+
end
|
|
101
|
+
EOF
|
|
102
|
+
runner.review('app/models/user.rb', content)
|
|
103
|
+
runner.should have(0).errors
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "should not protect mass assignment for strong_parameters" do
|
|
107
|
+
content =<<-EOF
|
|
108
|
+
class User < ActiveRecord::Base
|
|
109
|
+
include ActiveModel::ForbiddenAttributesProtection
|
|
104
110
|
end
|
|
111
|
+
EOF
|
|
112
|
+
runner.review('app/models/user.rb', content)
|
|
113
|
+
runner.should have(0).errors
|
|
114
|
+
end
|
|
105
115
|
end
|
|
106
116
|
end
|
|
107
117
|
end
|
|
@@ -26,6 +26,15 @@ module RailsBestPractices
|
|
|
26
26
|
runner.review('app/helpers/posts_helper.rb', content)
|
|
27
27
|
runner.should have(0).errors
|
|
28
28
|
end
|
|
29
|
+
|
|
30
|
+
it "should not remove empty application_helper" do
|
|
31
|
+
content =<<-EOF
|
|
32
|
+
module ApplicationHelper
|
|
33
|
+
end
|
|
34
|
+
EOF
|
|
35
|
+
runner.review('app/helpers/application_helper.rb', content)
|
|
36
|
+
runner.should have(0).errors
|
|
37
|
+
end
|
|
29
38
|
end
|
|
30
39
|
end
|
|
31
40
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_best_practices
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.12.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,11 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-11-02 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: code_analyzer
|
|
16
|
-
requirement:
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ! '>='
|
|
@@ -21,10 +21,15 @@ dependencies:
|
|
|
21
21
|
version: '0'
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements:
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ! '>='
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '0'
|
|
25
30
|
- !ruby/object:Gem::Dependency
|
|
26
31
|
name: progressbar
|
|
27
|
-
requirement:
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
28
33
|
none: false
|
|
29
34
|
requirements:
|
|
30
35
|
- - ! '>='
|
|
@@ -32,10 +37,15 @@ dependencies:
|
|
|
32
37
|
version: '0'
|
|
33
38
|
type: :runtime
|
|
34
39
|
prerelease: false
|
|
35
|
-
version_requirements:
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
36
46
|
- !ruby/object:Gem::Dependency
|
|
37
47
|
name: colored
|
|
38
|
-
requirement:
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
39
49
|
none: false
|
|
40
50
|
requirements:
|
|
41
51
|
- - ! '>='
|
|
@@ -43,10 +53,15 @@ dependencies:
|
|
|
43
53
|
version: '0'
|
|
44
54
|
type: :runtime
|
|
45
55
|
prerelease: false
|
|
46
|
-
version_requirements:
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
47
62
|
- !ruby/object:Gem::Dependency
|
|
48
63
|
name: erubis
|
|
49
|
-
requirement:
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
65
|
none: false
|
|
51
66
|
requirements:
|
|
52
67
|
- - ! '>='
|
|
@@ -54,10 +69,15 @@ dependencies:
|
|
|
54
69
|
version: '0'
|
|
55
70
|
type: :runtime
|
|
56
71
|
prerelease: false
|
|
57
|
-
version_requirements:
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
58
78
|
- !ruby/object:Gem::Dependency
|
|
59
79
|
name: i18n
|
|
60
|
-
requirement:
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
61
81
|
none: false
|
|
62
82
|
requirements:
|
|
63
83
|
- - ! '>='
|
|
@@ -65,10 +85,15 @@ dependencies:
|
|
|
65
85
|
version: '0'
|
|
66
86
|
type: :runtime
|
|
67
87
|
prerelease: false
|
|
68
|
-
version_requirements:
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ! '>='
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
69
94
|
- !ruby/object:Gem::Dependency
|
|
70
95
|
name: activesupport
|
|
71
|
-
requirement:
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
97
|
none: false
|
|
73
98
|
requirements:
|
|
74
99
|
- - ! '>='
|
|
@@ -76,10 +101,15 @@ dependencies:
|
|
|
76
101
|
version: '0'
|
|
77
102
|
type: :runtime
|
|
78
103
|
prerelease: false
|
|
79
|
-
version_requirements:
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ! '>='
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
80
110
|
- !ruby/object:Gem::Dependency
|
|
81
111
|
name: awesome_print
|
|
82
|
-
requirement:
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
113
|
none: false
|
|
84
114
|
requirements:
|
|
85
115
|
- - ! '>='
|
|
@@ -87,10 +117,15 @@ dependencies:
|
|
|
87
117
|
version: '0'
|
|
88
118
|
type: :runtime
|
|
89
119
|
prerelease: false
|
|
90
|
-
version_requirements:
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
none: false
|
|
122
|
+
requirements:
|
|
123
|
+
- - ! '>='
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '0'
|
|
91
126
|
- !ruby/object:Gem::Dependency
|
|
92
127
|
name: rake
|
|
93
|
-
requirement:
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
94
129
|
none: false
|
|
95
130
|
requirements:
|
|
96
131
|
- - ! '>='
|
|
@@ -98,10 +133,15 @@ dependencies:
|
|
|
98
133
|
version: '0'
|
|
99
134
|
type: :development
|
|
100
135
|
prerelease: false
|
|
101
|
-
version_requirements:
|
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
137
|
+
none: false
|
|
138
|
+
requirements:
|
|
139
|
+
- - ! '>='
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: '0'
|
|
102
142
|
- !ruby/object:Gem::Dependency
|
|
103
143
|
name: rspec
|
|
104
|
-
requirement:
|
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
|
105
145
|
none: false
|
|
106
146
|
requirements:
|
|
107
147
|
- - ! '>='
|
|
@@ -109,10 +149,15 @@ dependencies:
|
|
|
109
149
|
version: '0'
|
|
110
150
|
type: :development
|
|
111
151
|
prerelease: false
|
|
112
|
-
version_requirements:
|
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
153
|
+
none: false
|
|
154
|
+
requirements:
|
|
155
|
+
- - ! '>='
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: '0'
|
|
113
158
|
- !ruby/object:Gem::Dependency
|
|
114
159
|
name: haml
|
|
115
|
-
requirement:
|
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
|
116
161
|
none: false
|
|
117
162
|
requirements:
|
|
118
163
|
- - ! '>='
|
|
@@ -120,10 +165,15 @@ dependencies:
|
|
|
120
165
|
version: '0'
|
|
121
166
|
type: :development
|
|
122
167
|
prerelease: false
|
|
123
|
-
version_requirements:
|
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
169
|
+
none: false
|
|
170
|
+
requirements:
|
|
171
|
+
- - ! '>='
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0'
|
|
124
174
|
- !ruby/object:Gem::Dependency
|
|
125
175
|
name: slim
|
|
126
|
-
requirement:
|
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
177
|
none: false
|
|
128
178
|
requirements:
|
|
129
179
|
- - ! '>='
|
|
@@ -131,10 +181,15 @@ dependencies:
|
|
|
131
181
|
version: '0'
|
|
132
182
|
type: :development
|
|
133
183
|
prerelease: false
|
|
134
|
-
version_requirements:
|
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
185
|
+
none: false
|
|
186
|
+
requirements:
|
|
187
|
+
- - ! '>='
|
|
188
|
+
- !ruby/object:Gem::Version
|
|
189
|
+
version: '0'
|
|
135
190
|
- !ruby/object:Gem::Dependency
|
|
136
191
|
name: bundler
|
|
137
|
-
requirement:
|
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
|
138
193
|
none: false
|
|
139
194
|
requirements:
|
|
140
195
|
- - ! '>='
|
|
@@ -142,7 +197,12 @@ dependencies:
|
|
|
142
197
|
version: '0'
|
|
143
198
|
type: :development
|
|
144
199
|
prerelease: false
|
|
145
|
-
version_requirements:
|
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
201
|
+
none: false
|
|
202
|
+
requirements:
|
|
203
|
+
- - ! '>='
|
|
204
|
+
- !ruby/object:Gem::Version
|
|
205
|
+
version: '0'
|
|
146
206
|
description: a code metric tool for rails codes, written in Ruby.
|
|
147
207
|
email:
|
|
148
208
|
- flyerhzm@gmail.com
|
|
@@ -209,6 +269,7 @@ files:
|
|
|
209
269
|
- lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb
|
|
210
270
|
- lib/rails_best_practices/reviews/move_model_logic_into_model_review.rb
|
|
211
271
|
- lib/rails_best_practices/reviews/needless_deep_nesting_review.rb
|
|
272
|
+
- lib/rails_best_practices/reviews/not_rescue_exception_review.rb
|
|
212
273
|
- lib/rails_best_practices/reviews/not_use_default_route_review.rb
|
|
213
274
|
- lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb
|
|
214
275
|
- lib/rails_best_practices/reviews/overuse_route_customizations_review.rb
|
|
@@ -275,6 +336,7 @@ files:
|
|
|
275
336
|
- spec/rails_best_practices/reviews/move_finder_to_named_scope_review_spec.rb
|
|
276
337
|
- spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb
|
|
277
338
|
- spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb
|
|
339
|
+
- spec/rails_best_practices/reviews/not_rescue_exception_spec.rb
|
|
278
340
|
- spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb
|
|
279
341
|
- spec/rails_best_practices/reviews/not_use_times_ago_in_words_review_spec.rb
|
|
280
342
|
- spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb
|
|
@@ -316,7 +378,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
316
378
|
version: '0'
|
|
317
379
|
segments:
|
|
318
380
|
- 0
|
|
319
|
-
hash:
|
|
381
|
+
hash: 876012672984771359
|
|
320
382
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
321
383
|
none: false
|
|
322
384
|
requirements:
|
|
@@ -325,7 +387,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
325
387
|
version: 1.3.6
|
|
326
388
|
requirements: []
|
|
327
389
|
rubyforge_project:
|
|
328
|
-
rubygems_version: 1.8.
|
|
390
|
+
rubygems_version: 1.8.24
|
|
329
391
|
signing_key:
|
|
330
392
|
specification_version: 3
|
|
331
393
|
summary: a code metric tool for rails codes.
|
|
@@ -370,6 +432,7 @@ test_files:
|
|
|
370
432
|
- spec/rails_best_practices/reviews/move_finder_to_named_scope_review_spec.rb
|
|
371
433
|
- spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb
|
|
372
434
|
- spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb
|
|
435
|
+
- spec/rails_best_practices/reviews/not_rescue_exception_spec.rb
|
|
373
436
|
- spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb
|
|
374
437
|
- spec/rails_best_practices/reviews/not_use_times_ago_in_words_review_spec.rb
|
|
375
438
|
- spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb
|