rails_best_practices 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.textile +72 -54
- data/Rakefile +5 -5
- data/VERSION +1 -1
- data/identifier +0 -0
- data/lib/rails_best_practices/checks/always_add_db_index_check.rb +27 -62
- data/lib/rails_best_practices/checks/check.rb +12 -13
- data/lib/rails_best_practices/checks/isolate_seed_data_check.rb +7 -20
- data/lib/rails_best_practices/checks/keep_finders_on_their_own_model_check.rb +1 -1
- data/lib/rails_best_practices/checks/law_of_demeter_check.rb +6 -5
- data/lib/rails_best_practices/checks/move_code_into_helper_check.rb +8 -3
- data/lib/rails_best_practices/checks/move_code_into_model_check.rb +53 -0
- data/lib/rails_best_practices/checks/needless_deep_nesting_check.rb +36 -4
- data/lib/rails_best_practices/checks/not_use_default_route_check.rb +3 -2
- data/lib/rails_best_practices/checks/overuse_route_customizations_check.rb +23 -10
- data/lib/rails_best_practices/checks/replace_instance_variable_with_local_variable_check.rb +1 -1
- data/lib/rails_best_practices/checks/{use_filter_check.rb → use_before_filter_check.rb} +9 -7
- data/lib/rails_best_practices/checks/use_scope_access_check.rb +1 -1
- data/lib/rails_best_practices/checks.rb +2 -4
- data/lib/rails_best_practices/command.rb +7 -41
- data/lib/rails_best_practices/core/checking_visitor.rb +2 -2
- data/lib/rails_best_practices/core/runner.rb +8 -6
- data/lib/rails_best_practices/core/visitable_sexp.rb +8 -2
- data/lib/rails_best_practices.rb +41 -1
- data/rails_best_practices.gemspec +25 -30
- data/rails_best_practices.yml +3 -5
- data/spec/rails_best_practices/checks/always_add_db_index_check_spec.rb +32 -112
- data/spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb +0 -3
- data/spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb +33 -1
- data/spec/rails_best_practices/checks/law_of_demeter_check_spec.rb +66 -27
- data/spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb +2 -2
- data/spec/rails_best_practices/checks/move_code_into_model_check_spec.rb +55 -0
- data/spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb +55 -21
- data/spec/rails_best_practices/checks/not_use_default_route_check_spec.rb +51 -22
- data/spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb +134 -48
- data/spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb +11 -1
- data/spec/rails_best_practices/checks/{use_filter_check_spec.rb → use_before_filter_check_spec.rb} +6 -6
- data/spec/rails_best_practices/checks/use_scope_access_check_spec.rb +22 -0
- metadata +49 -39
- data/lib/rails_best_practices/checks/many_to_many_collection_check.rb +0 -12
- data/lib/rails_best_practices/checks/nested_model_forms_check.rb +0 -12
- data/lib/rails_best_practices/checks/use_model_callback_check.rb +0 -12
- data/spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb +0 -11
- data/spec/rails_best_practices/checks/nested_model_forms_check_spec.rb +0 -11
- data/spec/rails_best_practices/checks/use_model_callback_check_spec.rb +0 -11
|
@@ -8,7 +8,7 @@ module RailsBestPractices
|
|
|
8
8
|
class OveruseRouteCustomizationsCheck < Check
|
|
9
9
|
|
|
10
10
|
def interesting_nodes
|
|
11
|
-
[:call]
|
|
11
|
+
[:call, :iter]
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def interesting_files
|
|
@@ -21,19 +21,32 @@ module RailsBestPractices
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def evaluate_start(node)
|
|
24
|
-
|
|
25
|
-
add_error "overuse route customizations (customize_count > #{@customize_count})" if member_and_collection_count(node) > @customize_count
|
|
26
|
-
end
|
|
24
|
+
add_error "overuse route customizations (customize_count > #{@customize_count})", node.file, node.subject.line if member_and_collection_count(node) > @customize_count
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
private
|
|
28
|
+
def member_and_collection_count(node)
|
|
29
|
+
if :resources == node.message
|
|
30
|
+
member_and_collection_count_for_rails2(node)
|
|
31
|
+
elsif :iter == node.node_type and :resources == node.subject.message
|
|
32
|
+
member_and_collection_count_for_rails3(node)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
30
35
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
# this is the checker for rails3 style routes
|
|
37
|
+
def member_and_collection_count_for_rails3(node)
|
|
38
|
+
get_nodes = node.grep_nodes(:node_type => :call, :message => :get)
|
|
39
|
+
post_nodes = node.grep_nodes(:node_type => :call, :message => :post)
|
|
40
|
+
get_nodes.size + post_nodes.size
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# this is the checker for rails2 style routes
|
|
44
|
+
def member_and_collection_count_for_rails2(node)
|
|
45
|
+
hash_nodes = node.grep_nodes(:node_type => :hash)
|
|
46
|
+
return 0 if hash_nodes.empty?
|
|
47
|
+
customize_hash = eval(hash_nodes.first.to_ruby)
|
|
48
|
+
(customize_hash[:member].size || 0) + (customize_hash[:collection].size || 0)
|
|
49
|
+
end
|
|
37
50
|
end
|
|
38
51
|
end
|
|
39
52
|
end
|
|
@@ -2,10 +2,10 @@ require 'rails_best_practices/checks/check'
|
|
|
2
2
|
|
|
3
3
|
module RailsBestPractices
|
|
4
4
|
module Checks
|
|
5
|
-
# Check a controller file to make sure to use
|
|
5
|
+
# Check a controller file to make sure to use before_filter to remove duplicate call in different action.
|
|
6
6
|
#
|
|
7
|
-
# Implementation: Check all methods' first call, if they are duplicate, then should use
|
|
8
|
-
class
|
|
7
|
+
# Implementation: Check all methods' first call, if they are duplicate, then should use before_filter.
|
|
8
|
+
class UseBeforeFilterCheck < Check
|
|
9
9
|
|
|
10
10
|
def interesting_nodes
|
|
11
11
|
[:class]
|
|
@@ -18,19 +18,21 @@ module RailsBestPractices
|
|
|
18
18
|
def evaluate_start(node)
|
|
19
19
|
@methods = {}
|
|
20
20
|
node.grep_nodes({:node_type => :defn}).each { |method_node| remember_method(method_node) }
|
|
21
|
-
@methods.each do |first_call,
|
|
22
|
-
|
|
21
|
+
@methods.each do |first_call, method_nodes|
|
|
22
|
+
if method_nodes.size > 1
|
|
23
|
+
add_error "use before_filter for #{method_nodes.collect{|method_node| method_node.message_name}.join(',')}",
|
|
24
|
+
node.file, method_nodes.collect{|method_node| method_node.line}.join(',')
|
|
25
|
+
end
|
|
23
26
|
end
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
private
|
|
27
30
|
|
|
28
31
|
def remember_method(method_node)
|
|
29
|
-
method_name = method_node.message_name
|
|
30
32
|
first_call = method_node.body[1]
|
|
31
33
|
unless first_call == s(:nil)
|
|
32
34
|
@methods[first_call] ||= []
|
|
33
|
-
@methods[first_call] <<
|
|
35
|
+
@methods[first_call] << method_node
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
end
|
|
@@ -30,7 +30,7 @@ module RailsBestPractices
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def current_user?(call_node)
|
|
33
|
-
call_node.message == :current_user or (call_node.subject.message == :current_user and call_node.message == :id)
|
|
33
|
+
call_node.node_type == :call and (call_node.message == :current_user or (call_node.subject.message == :current_user and call_node.message == :id))
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
end
|
|
@@ -2,11 +2,8 @@ require 'rails_best_practices/checks/move_finder_to_named_scope_check'
|
|
|
2
2
|
require 'rails_best_practices/checks/use_model_association_check'
|
|
3
3
|
require 'rails_best_practices/checks/use_scope_access_check'
|
|
4
4
|
require 'rails_best_practices/checks/add_model_virtual_attribute_check'
|
|
5
|
-
require 'rails_best_practices/checks/use_model_callback_check'
|
|
6
5
|
require 'rails_best_practices/checks/replace_complex_creation_with_factory_method_check'
|
|
7
6
|
require 'rails_best_practices/checks/move_model_logic_into_model_check'
|
|
8
|
-
require 'rails_best_practices/checks/many_to_many_collection_check'
|
|
9
|
-
require 'rails_best_practices/checks/nested_model_forms_check'
|
|
10
7
|
require 'rails_best_practices/checks/overuse_route_customizations_check'
|
|
11
8
|
require 'rails_best_practices/checks/needless_deep_nesting_check'
|
|
12
9
|
require 'rails_best_practices/checks/not_use_default_route_check'
|
|
@@ -15,7 +12,8 @@ require 'rails_best_practices/checks/law_of_demeter_check'
|
|
|
15
12
|
require 'rails_best_practices/checks/use_observer_check'
|
|
16
13
|
require 'rails_best_practices/checks/isolate_seed_data_check'
|
|
17
14
|
require 'rails_best_practices/checks/always_add_db_index_check'
|
|
18
|
-
require 'rails_best_practices/checks/
|
|
15
|
+
require 'rails_best_practices/checks/use_before_filter_check'
|
|
19
16
|
require 'rails_best_practices/checks/move_code_into_controller_check'
|
|
17
|
+
require 'rails_best_practices/checks/move_code_into_model_check'
|
|
20
18
|
require 'rails_best_practices/checks/move_code_into_helper_check'
|
|
21
19
|
require 'rails_best_practices/checks/replace_instance_variable_with_local_variable_check'
|
|
@@ -1,39 +1,5 @@
|
|
|
1
1
|
require 'optparse'
|
|
2
2
|
|
|
3
|
-
def expand_dirs_to_files *dirs
|
|
4
|
-
extensions = ['rb', 'erb', 'builder']
|
|
5
|
-
|
|
6
|
-
dirs.flatten.map { |p|
|
|
7
|
-
if File.directory? p
|
|
8
|
-
Dir[File.join(p, '**', "*.{#{extensions.join(',')}}")]
|
|
9
|
-
else
|
|
10
|
-
p
|
|
11
|
-
end
|
|
12
|
-
}.flatten
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# for law_of_demeter_check
|
|
16
|
-
def model_first_sort files
|
|
17
|
-
files.sort { |a, b|
|
|
18
|
-
if a =~ /models\/.*rb/
|
|
19
|
-
-1
|
|
20
|
-
elsif b =~ /models\/.*rb/
|
|
21
|
-
1
|
|
22
|
-
else
|
|
23
|
-
a <=> b
|
|
24
|
-
end
|
|
25
|
-
}
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# for always_add_db_index_check
|
|
29
|
-
def add_duplicate_migrations files
|
|
30
|
-
migration_files = files.select { |file| file.index("db/migrate") }
|
|
31
|
-
(files << migration_files).flatten
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def ignore_files files, pattern
|
|
35
|
-
files.reject { |file| file.index(pattern) }
|
|
36
|
-
end
|
|
37
3
|
|
|
38
4
|
options = {}
|
|
39
5
|
OptionParser.new do |opts|
|
|
@@ -48,6 +14,11 @@ OptionParser.new do |opts|
|
|
|
48
14
|
options[pattern] = true
|
|
49
15
|
end
|
|
50
16
|
end
|
|
17
|
+
|
|
18
|
+
opts.on_tail('-v', '--version', 'Show this version') do
|
|
19
|
+
puts File.read(File.dirname(__FILE__) + '/../../VERSION')
|
|
20
|
+
exit
|
|
21
|
+
end
|
|
51
22
|
|
|
52
23
|
opts.on_tail("-h", "--help", "Show this message") do
|
|
53
24
|
puts opts
|
|
@@ -60,17 +31,12 @@ end
|
|
|
60
31
|
runner = RailsBestPractices::Core::Runner.new
|
|
61
32
|
runner.set_debug if options['debug']
|
|
62
33
|
|
|
63
|
-
files =
|
|
64
|
-
files = model_first_sort(files)
|
|
65
|
-
files = add_duplicate_migrations(files)
|
|
66
|
-
['vendor', 'spec', 'test', 'stories'].each do |pattern|
|
|
67
|
-
files = ignore_files(files, "#{pattern}/") unless options[pattern]
|
|
68
|
-
end
|
|
34
|
+
files = RailsBestPractices::analyze_files(ARGV, options)
|
|
69
35
|
files.each { |file| runner.check_file(file) }
|
|
70
36
|
|
|
71
37
|
runner.errors.each {|error| puts error}
|
|
38
|
+
puts "\nPlease go to http://rails-bestpractices.com to see more useful Rails Best Practices."
|
|
72
39
|
if runner.errors.size > 0
|
|
73
|
-
puts "\ngo to http://wiki.github.com/flyerhzm/rails_best_practices to see how to solve these errors."
|
|
74
40
|
puts "\nFound #{runner.errors.size} errors."
|
|
75
41
|
end
|
|
76
42
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module RailsBestPractices
|
|
2
2
|
module Core
|
|
3
3
|
class CheckingVisitor
|
|
4
|
-
def initialize(
|
|
4
|
+
def initialize(checks)
|
|
5
5
|
@checks ||= {}
|
|
6
|
-
checks.
|
|
6
|
+
checks.each do |check|
|
|
7
7
|
nodes = check.interesting_nodes
|
|
8
8
|
nodes.each do |node|
|
|
9
9
|
@checks[node] ||= []
|
|
@@ -10,11 +10,7 @@ module RailsBestPractices
|
|
|
10
10
|
CUSTOM_CONFIG = File.join('config', 'rails_best_practices.yml')
|
|
11
11
|
|
|
12
12
|
def initialize(*checks)
|
|
13
|
-
|
|
14
|
-
@config = CUSTOM_CONFIG
|
|
15
|
-
else
|
|
16
|
-
@config = DEFAULT_CONFIG
|
|
17
|
-
end
|
|
13
|
+
@config = File.exists?(CUSTOM_CONFIG) ? CUSTOM_CONFIG : DEFAULT_CONFIG
|
|
18
14
|
@checks = checks unless checks.empty?
|
|
19
15
|
@checks ||= load_checks
|
|
20
16
|
@checker ||= CheckingVisitor.new(@checks)
|
|
@@ -26,9 +22,15 @@ module RailsBestPractices
|
|
|
26
22
|
end
|
|
27
23
|
|
|
28
24
|
def check(filename, content)
|
|
29
|
-
if filename =~
|
|
25
|
+
if filename =~ /.*\.erb/
|
|
30
26
|
content = ERB.new(content).src
|
|
31
27
|
end
|
|
28
|
+
if filename =~ /.*\.haml/
|
|
29
|
+
require 'haml'
|
|
30
|
+
content = Haml::Engine.new(content).precompiled
|
|
31
|
+
# remove \xxx characters
|
|
32
|
+
content.gsub!(/\\\d{3}/, '')
|
|
33
|
+
end
|
|
32
34
|
node = parse(filename, content)
|
|
33
35
|
node.accept(@checker) if node
|
|
34
36
|
end
|
|
@@ -47,13 +47,13 @@ class Sexp
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def subject
|
|
50
|
-
if [:attrasgn, :call, :iasgn, :lasgn, :class].include? node_type
|
|
50
|
+
if [:attrasgn, :call, :iasgn, :lasgn, :class, :iter].include? node_type
|
|
51
51
|
self[1]
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def message
|
|
56
|
-
if [:attrasgn, :call, :defs].include? node_type
|
|
56
|
+
if [:attrasgn, :call, :defs, :iter].include? node_type
|
|
57
57
|
self[2]
|
|
58
58
|
end
|
|
59
59
|
end
|
|
@@ -70,6 +70,12 @@ class Sexp
|
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
+
def conditional_statement
|
|
74
|
+
if node_type == :if
|
|
75
|
+
self[1]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
73
79
|
def true_node
|
|
74
80
|
if :if == node_type
|
|
75
81
|
self[2]
|
data/lib/rails_best_practices.rb
CHANGED
|
@@ -2,4 +2,44 @@ require 'rails_best_practices/checks'
|
|
|
2
2
|
require 'rails_best_practices/core'
|
|
3
3
|
|
|
4
4
|
module RailsBestPractices
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
class <<self
|
|
7
|
+
def analyze_files(dir = '.', options = {})
|
|
8
|
+
files = expand_dirs_to_files(dir)
|
|
9
|
+
files = model_first_sort(files)
|
|
10
|
+
['vendor', 'spec', 'test', 'stories', 'features'].each do |pattern|
|
|
11
|
+
files = ignore_files(files, "#{pattern}/") unless options[pattern]
|
|
12
|
+
end
|
|
13
|
+
files
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def expand_dirs_to_files *dirs
|
|
17
|
+
extensions = ['rb', 'erb', 'haml', 'builder']
|
|
18
|
+
|
|
19
|
+
dirs.flatten.map { |p|
|
|
20
|
+
if File.directory? p
|
|
21
|
+
Dir[File.join(p, '**', "*.{#{extensions.join(',')}}")]
|
|
22
|
+
else
|
|
23
|
+
p
|
|
24
|
+
end
|
|
25
|
+
}.flatten
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# for law_of_demeter_check
|
|
29
|
+
def model_first_sort files
|
|
30
|
+
files.sort { |a, b|
|
|
31
|
+
if a =~ /models\/.*rb/
|
|
32
|
+
-1
|
|
33
|
+
elsif b =~ /models\/.*rb/
|
|
34
|
+
1
|
|
35
|
+
else
|
|
36
|
+
a <=> b
|
|
37
|
+
end
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def ignore_files files, pattern
|
|
42
|
+
files.reject { |file| file.index(pattern) }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{rails_best_practices}
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.4.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Richard Huang"]
|
|
12
|
-
s.date = %q{
|
|
12
|
+
s.date = %q{2010-08-15}
|
|
13
13
|
s.default_executable = %q{rails_best_practices}
|
|
14
|
-
s.description = %q{
|
|
14
|
+
s.description = %q{a code metric tool for rails codes.}
|
|
15
15
|
s.email = %q{flyerhzm@gmail.com}
|
|
16
16
|
s.executables = ["rails_best_practices"]
|
|
17
17
|
s.extra_rdoc_files = [
|
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
|
|
|
25
25
|
"Rakefile",
|
|
26
26
|
"VERSION",
|
|
27
27
|
"bin/rails_best_practices",
|
|
28
|
+
"identifier",
|
|
28
29
|
"lib/rails_best_practices.rb",
|
|
29
30
|
"lib/rails_best_practices/checks.rb",
|
|
30
31
|
"lib/rails_best_practices/checks/add_model_virtual_attribute_check.rb",
|
|
@@ -33,20 +34,18 @@ Gem::Specification.new do |s|
|
|
|
33
34
|
"lib/rails_best_practices/checks/isolate_seed_data_check.rb",
|
|
34
35
|
"lib/rails_best_practices/checks/keep_finders_on_their_own_model_check.rb",
|
|
35
36
|
"lib/rails_best_practices/checks/law_of_demeter_check.rb",
|
|
36
|
-
"lib/rails_best_practices/checks/many_to_many_collection_check.rb",
|
|
37
37
|
"lib/rails_best_practices/checks/move_code_into_controller_check.rb",
|
|
38
38
|
"lib/rails_best_practices/checks/move_code_into_helper_check.rb",
|
|
39
|
+
"lib/rails_best_practices/checks/move_code_into_model_check.rb",
|
|
39
40
|
"lib/rails_best_practices/checks/move_finder_to_named_scope_check.rb",
|
|
40
41
|
"lib/rails_best_practices/checks/move_model_logic_into_model_check.rb",
|
|
41
42
|
"lib/rails_best_practices/checks/needless_deep_nesting_check.rb",
|
|
42
|
-
"lib/rails_best_practices/checks/nested_model_forms_check.rb",
|
|
43
43
|
"lib/rails_best_practices/checks/not_use_default_route_check.rb",
|
|
44
44
|
"lib/rails_best_practices/checks/overuse_route_customizations_check.rb",
|
|
45
45
|
"lib/rails_best_practices/checks/replace_complex_creation_with_factory_method_check.rb",
|
|
46
46
|
"lib/rails_best_practices/checks/replace_instance_variable_with_local_variable_check.rb",
|
|
47
|
-
"lib/rails_best_practices/checks/
|
|
47
|
+
"lib/rails_best_practices/checks/use_before_filter_check.rb",
|
|
48
48
|
"lib/rails_best_practices/checks/use_model_association_check.rb",
|
|
49
|
-
"lib/rails_best_practices/checks/use_model_callback_check.rb",
|
|
50
49
|
"lib/rails_best_practices/checks/use_observer_check.rb",
|
|
51
50
|
"lib/rails_best_practices/checks/use_scope_access_check.rb",
|
|
52
51
|
"lib/rails_best_practices/command.rb",
|
|
@@ -63,52 +62,48 @@ Gem::Specification.new do |s|
|
|
|
63
62
|
"spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb",
|
|
64
63
|
"spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb",
|
|
65
64
|
"spec/rails_best_practices/checks/law_of_demeter_check_spec.rb",
|
|
66
|
-
"spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb",
|
|
67
65
|
"spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb",
|
|
68
66
|
"spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb",
|
|
67
|
+
"spec/rails_best_practices/checks/move_code_into_model_check_spec.rb",
|
|
69
68
|
"spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb",
|
|
70
69
|
"spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb",
|
|
71
70
|
"spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb",
|
|
72
|
-
"spec/rails_best_practices/checks/nested_model_forms_check_spec.rb",
|
|
73
71
|
"spec/rails_best_practices/checks/not_use_default_route_check_spec.rb",
|
|
74
72
|
"spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb",
|
|
75
73
|
"spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb",
|
|
76
74
|
"spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb",
|
|
77
|
-
"spec/rails_best_practices/checks/
|
|
75
|
+
"spec/rails_best_practices/checks/use_before_filter_check_spec.rb",
|
|
78
76
|
"spec/rails_best_practices/checks/use_model_association_check_spec.rb",
|
|
79
|
-
"spec/rails_best_practices/checks/use_model_callback_check_spec.rb",
|
|
80
77
|
"spec/rails_best_practices/checks/use_observer_check_spec.rb",
|
|
81
78
|
"spec/rails_best_practices/checks/use_scope_access_check_spec.rb",
|
|
82
79
|
"spec/spec.opts",
|
|
83
80
|
"spec/spec_helper.rb"
|
|
84
81
|
]
|
|
85
|
-
s.homepage = %q{http://
|
|
82
|
+
s.homepage = %q{http://rails-bestpractices.com}
|
|
86
83
|
s.rdoc_options = ["--charset=UTF-8"]
|
|
87
84
|
s.require_paths = ["lib"]
|
|
88
|
-
s.rubygems_version = %q{1.3.
|
|
89
|
-
s.summary = %q{
|
|
85
|
+
s.rubygems_version = %q{1.3.6}
|
|
86
|
+
s.summary = %q{a code metric tool for rails codes.}
|
|
90
87
|
s.test_files = [
|
|
91
|
-
"spec/rails_best_practices/checks/
|
|
92
|
-
"spec/rails_best_practices/checks/always_add_db_index_check_spec.rb",
|
|
93
|
-
"spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb",
|
|
94
|
-
"spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb",
|
|
95
|
-
"spec/rails_best_practices/checks/law_of_demeter_check_spec.rb",
|
|
96
|
-
"spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb",
|
|
97
|
-
"spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb",
|
|
98
|
-
"spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb",
|
|
99
|
-
"spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb",
|
|
88
|
+
"spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb",
|
|
100
89
|
"spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb",
|
|
101
|
-
"spec/rails_best_practices/checks/
|
|
102
|
-
"spec/rails_best_practices/checks/
|
|
103
|
-
"spec/rails_best_practices/checks/
|
|
90
|
+
"spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb",
|
|
91
|
+
"spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb",
|
|
92
|
+
"spec/rails_best_practices/checks/use_observer_check_spec.rb",
|
|
104
93
|
"spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb",
|
|
94
|
+
"spec/rails_best_practices/checks/always_add_db_index_check_spec.rb",
|
|
95
|
+
"spec/rails_best_practices/checks/use_before_filter_check_spec.rb",
|
|
96
|
+
"spec/rails_best_practices/checks/law_of_demeter_check_spec.rb",
|
|
97
|
+
"spec/rails_best_practices/checks/use_scope_access_check_spec.rb",
|
|
105
98
|
"spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb",
|
|
99
|
+
"spec/rails_best_practices/checks/not_use_default_route_check_spec.rb",
|
|
100
|
+
"spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb",
|
|
101
|
+
"spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb",
|
|
106
102
|
"spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb",
|
|
107
|
-
"spec/rails_best_practices/checks/use_filter_check_spec.rb",
|
|
108
103
|
"spec/rails_best_practices/checks/use_model_association_check_spec.rb",
|
|
109
|
-
"spec/rails_best_practices/checks/
|
|
110
|
-
"spec/rails_best_practices/checks/
|
|
111
|
-
"spec/rails_best_practices/checks/
|
|
104
|
+
"spec/rails_best_practices/checks/move_code_into_model_check_spec.rb",
|
|
105
|
+
"spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb",
|
|
106
|
+
"spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb",
|
|
112
107
|
"spec/spec_helper.rb"
|
|
113
108
|
]
|
|
114
109
|
|
data/rails_best_practices.yml
CHANGED
|
@@ -2,11 +2,8 @@ MoveFinderToNamedScopeCheck: { }
|
|
|
2
2
|
UseModelAssociationCheck: { }
|
|
3
3
|
UseScopeAccessCheck: { }
|
|
4
4
|
AddModelVirtualAttributeCheck: { }
|
|
5
|
-
# UseModelCallbackCheck: { }
|
|
6
5
|
ReplaceComplexCreationWithFactoryMethodCheck: { attribute_assignment_count: 2 }
|
|
7
6
|
MoveModelLogicIntoModelCheck: { called_count: 4 }
|
|
8
|
-
# ManyToManyCollectionCheck: { }
|
|
9
|
-
# NestedModelFormsCheck: { }
|
|
10
7
|
OveruseRouteCustomizationsCheck: { customize_count: 3 }
|
|
11
8
|
NeedlessDeepNestingCheck: { nested_count: 2 }
|
|
12
9
|
NotUseDefaultRouteCheck: { }
|
|
@@ -15,7 +12,8 @@ LawOfDemeterCheck: { }
|
|
|
15
12
|
UseObserverCheck: { }
|
|
16
13
|
IsolateSeedDataCheck: { }
|
|
17
14
|
AlwaysAddDbIndexCheck: { }
|
|
18
|
-
|
|
15
|
+
UseBeforeFilterCheck: { }
|
|
19
16
|
MoveCodeIntoControllerCheck: { }
|
|
20
|
-
|
|
17
|
+
MoveCodeIntoModelCheck: { }
|
|
18
|
+
MoveCodeIntoHelperCheck: { array_count: 3 }
|
|
21
19
|
ReplaceInstanceVariableWithLocalVariableCheck: { }
|
|
@@ -7,147 +7,67 @@ describe RailsBestPractices::Checks::AlwaysAddDbIndexCheck do
|
|
|
7
7
|
|
|
8
8
|
it "should always add db index" do
|
|
9
9
|
content = <<-EOF
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
t.integer :user_id
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def self.down
|
|
20
|
-
drop_table "comments"
|
|
10
|
+
ActiveRecord::Schema.define(:version => 20100603080629) do
|
|
11
|
+
create_table "comments", :force => true do |t|
|
|
12
|
+
t.string "content"
|
|
13
|
+
t.integer "post_id"
|
|
14
|
+
t.integer "user_id"
|
|
21
15
|
end
|
|
22
16
|
end
|
|
23
17
|
EOF
|
|
24
|
-
@runner.check('db/
|
|
25
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
18
|
+
@runner.check('db/schema.rb', content)
|
|
26
19
|
errors = @runner.errors
|
|
27
20
|
errors.should_not be_empty
|
|
28
|
-
errors[0].to_s.should == "db/
|
|
21
|
+
errors[0].to_s.should == "db/schema.rb:4 - always add db index (comments => post_id)"
|
|
22
|
+
errors[1].to_s.should == "db/schema.rb:5 - always add db index (comments => user_id)"
|
|
29
23
|
end
|
|
30
|
-
|
|
24
|
+
|
|
31
25
|
it "should always add db index with column has no id" do
|
|
32
26
|
content = <<-EOF
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
t.integer :position
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.down
|
|
42
|
-
drop_table "comments"
|
|
27
|
+
ActiveRecord::Schema.define(:version => 20100603080629) do
|
|
28
|
+
create_table "comments", :force => true do |t|
|
|
29
|
+
t.string "content"
|
|
30
|
+
t.integer "position"
|
|
43
31
|
end
|
|
44
32
|
end
|
|
45
33
|
EOF
|
|
46
|
-
@runner.check('db/
|
|
47
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
34
|
+
@runner.check('db/schema.rb', content)
|
|
48
35
|
errors = @runner.errors
|
|
49
36
|
errors.should be_empty
|
|
50
37
|
end
|
|
51
|
-
|
|
52
|
-
it "should always add db index with references" do
|
|
53
|
-
content = <<-EOF
|
|
54
|
-
class CreateComments < ActiveRecord::Migration
|
|
55
|
-
def self.up
|
|
56
|
-
create_table "comments", :force => true do |t|
|
|
57
|
-
t.string :content
|
|
58
|
-
t.references :post
|
|
59
|
-
t.references :user
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def self.down
|
|
64
|
-
drop_table "comments"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
EOF
|
|
68
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
69
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
70
|
-
errors = @runner.errors
|
|
71
|
-
errors.should_not be_empty
|
|
72
|
-
errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id, comments => user_id)"
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "should always add db index with column" do
|
|
76
|
-
content = <<-EOF
|
|
77
|
-
class CreateComments < ActiveRecord::Migration
|
|
78
|
-
def self.up
|
|
79
|
-
create_table "comments", :force => true do |t|
|
|
80
|
-
t.string :content
|
|
81
|
-
t.column :post_id, :integer
|
|
82
|
-
t.column :user_id, :integer
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def self.down
|
|
87
|
-
drop_table "comments"
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
EOF
|
|
91
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
92
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
93
|
-
errors = @runner.errors
|
|
94
|
-
errors.should_not be_empty
|
|
95
|
-
errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id, comments => user_id)"
|
|
96
|
-
end
|
|
97
|
-
|
|
38
|
+
|
|
98
39
|
it "should not always add db index with add_index" do
|
|
99
40
|
content = <<-EOF
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
t.integer :user_id
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
add_index :comments, :post_id
|
|
109
|
-
add_index :comments, :user_id
|
|
41
|
+
ActiveRecord::Schema.define(:version => 20100603080629) do
|
|
42
|
+
create_table "comments", :force => true do |t|
|
|
43
|
+
t.string "content"
|
|
44
|
+
t.integer "post_id"
|
|
45
|
+
t.integer "user_id"
|
|
110
46
|
end
|
|
111
47
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
end
|
|
48
|
+
add_index "comments", ["post_id"], :name => "index_comments_on_post_id"
|
|
49
|
+
add_index "comments", ["user_id"], :name => "index_comments_on_user_id"
|
|
115
50
|
end
|
|
116
51
|
EOF
|
|
117
|
-
@runner.check('db/
|
|
118
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
52
|
+
@runner.check('db/schema.rb', content)
|
|
119
53
|
errors = @runner.errors
|
|
120
54
|
errors.should be_empty
|
|
121
55
|
end
|
|
122
56
|
|
|
123
|
-
it "should not always add db index with
|
|
57
|
+
it "should not always add db index with multi-column index" do
|
|
124
58
|
content = <<-EOF
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
t.integer :user_id
|
|
131
|
-
end
|
|
59
|
+
ActiveRecord::Schema.define(:version => 20100603080629) do
|
|
60
|
+
create_table "versions", :force => true do |t|
|
|
61
|
+
t.integer "versioned_id"
|
|
62
|
+
t.string "versioned_type"
|
|
63
|
+
t.string "tag"
|
|
132
64
|
end
|
|
133
65
|
|
|
134
|
-
|
|
135
|
-
drop_table "comments"
|
|
136
|
-
end
|
|
66
|
+
add_index "versions", ["versioned_id", "versioned_type"], :name => "index_versions_on_versioned_id_and_versioned_type"
|
|
137
67
|
end
|
|
138
68
|
EOF
|
|
139
|
-
|
|
140
|
-
class AddIndexesToComments < ActiveRecord::Migration
|
|
141
|
-
def self.up
|
|
142
|
-
add_index :comments, :post_id
|
|
143
|
-
add_index :comments, :user_id
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
EOF
|
|
147
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
148
|
-
@runner.check('db/migrate/20090919130258_add_indexes_to_comments.rb', content)
|
|
149
|
-
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
150
|
-
@runner.check('db/migrate/20090919130258_add_indexes_to_comments.rb', content)
|
|
69
|
+
@runner.check('db/schema.rb', content)
|
|
151
70
|
errors = @runner.errors
|
|
71
|
+
errors.should be_empty
|
|
152
72
|
end
|
|
153
73
|
end
|