rails_best_practices 1.11.1 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -7,4 +7,4 @@ pkg/**
7
7
  rdoc/**
8
8
  doc/**
9
9
  .yardoc/**
10
- rails_best_practices_output.html
10
+ rails_best_practices_output.*
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 Syntax (disabled by default)
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
 
@@ -72,22 +72,24 @@
72
72
  <% end %>
73
73
  </p>
74
74
  <table>
75
- <% columnize(@error_types, 3).each do |row| %>
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
+ />&nbsp;<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
- <% row.map { |error_type| error_type.split(':').last }.each do |error_type| %>
78
- <td>
79
- <input type="checkbox" class="error-type" id="<%= error_type %>" value="<%= error_type %>"
80
- />&nbsp;<label for="<%= error_type %>"><%= error_type.sub(/(Check|Review)$/, '').gsub(/([a-z\d])([A-Z])/,'\1 \2') %></label>
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, :errors_filter_block
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}; hg blame -lvcu #{error.filename[@runner.class.base_path.size..-1].gsub(/^\//, "")} | sed -n /:#{error.line_number.split(',').first}:/p`
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}; git blame -L #{error.line_number.split(',').first},+1 #{error.filename[start..-1]}`
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}; git rev-parse HEAD`.chomp
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["format"] == 'html'
257
- load_git_info if @options["with-git"]
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, :highlight
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
- remember_index_columns(node)
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
- def remember_index_columns(node)
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 attr_protected to protect mass assignment.
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 class node to see if there is a command with message attr_accessible or attr_protected.
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
- # check class node, grep all command nodes,
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
- if !whitelist_attributes_config? && !rails_builtin?(node) && !devise?(node) &&
26
- !authlogic?(node) && is_active_record?(node)
27
- add_error "protect mass assignment"
28
- end
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 whitelist_attributes_config?
33
- Prepares.configs["config.active_record.whitelist_attributes"] == "true"
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 rails_builtin?(node)
37
- node.grep_node(sexp_type: [:vcall, :var_ref], to_s: "attr_accessible").present? ||
38
- node.grep_node(sexp_type: :command, message: %w(attr_accessible attr_protected)).present?
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 devise?(node)
42
- node.grep_node(sexp_type: :command, message: "devise").present?
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 authlogic?(node)
46
- node.grep_node(sexp_type: [:vcall, :var_ref], to_s: "acts_as_authentic").present? ||
47
- node.grep_node(sexp_type: :fcall, message: "acts_as_authentic").present?
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 is_active_record?(node)
51
- node.grep_node(sexp_type: [:const_path_ref, :@const], to_s: "ActiveRecord::Base").present?
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 is_active_record?(node)
55
- node.grep_node(:sexp_type => [:const_path_ref, :@const], :to_s => "ActiveRecord::Base").present?
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 |node|
21
- if s(:bodystmt, s(:stmts_add, s(:stmts_new), s(:void_stmt)), nil, nil, nil) == node.body
22
- add_error "remove empty helpers", node.file, node.line
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
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module RailsBestPractices
3
- VERSION = "1.11.1"
3
+ VERSION = "1.12.0"
4
4
  end
@@ -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
- content =<<-EOF
99
- class User < Person
100
- end
101
- EOF
102
- runner.review('app/models/user.rb', content)
103
- runner.should have(0).errors
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.11.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-09-22 00:00:00.000000000 Z
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: &70335874056360 !ruby/object:Gem::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: *70335874056360
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: &70335874055620 !ruby/object:Gem::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: *70335874055620
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: &70335874071220 !ruby/object:Gem::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: *70335874071220
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: &70335874070660 !ruby/object:Gem::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: *70335874070660
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: &70335874070200 !ruby/object:Gem::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: *70335874070200
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: &70335874069580 !ruby/object:Gem::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: *70335874069580
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: &70335874069120 !ruby/object:Gem::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: *70335874069120
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: &70335874068660 !ruby/object:Gem::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: *70335874068660
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: &70335874068200 !ruby/object:Gem::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: *70335874068200
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: &70335874067720 !ruby/object:Gem::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: *70335874067720
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: &70335874067260 !ruby/object:Gem::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: *70335874067260
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: &70335874066820 !ruby/object:Gem::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: *70335874066820
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: 4208678771119730568
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.17
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