rails_best_practices 0.2.0 → 0.3.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 +32 -14
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/rails_best_practices/checks/add_model_virtual_attribute_check.rb +12 -7
- data/lib/rails_best_practices/checks/always_add_db_index_check.rb +90 -0
- data/lib/rails_best_practices/checks/check.rb +9 -3
- data/lib/rails_best_practices/checks/isolate_seed_data_check.rb +59 -0
- data/lib/rails_best_practices/checks/keep_finders_on_their_own_model_check.rb +29 -0
- data/lib/rails_best_practices/checks/law_of_demeter_check.rb +47 -0
- data/lib/rails_best_practices/checks/move_code_into_controller_check.rb +31 -0
- data/lib/rails_best_practices/checks/move_code_into_helper_check.rb +29 -0
- data/lib/rails_best_practices/checks/move_finder_to_named_scope_check.rb +1 -1
- data/lib/rails_best_practices/checks/move_model_logic_into_model_check.rb +1 -1
- data/lib/rails_best_practices/checks/replace_complex_creation_with_factory_method_check.rb +1 -1
- data/lib/rails_best_practices/checks/replace_instance_variable_with_local_variable_check.rb +23 -0
- data/lib/rails_best_practices/checks/use_filter_check.rb +38 -0
- data/lib/rails_best_practices/checks/use_observer_check.rb +49 -0
- data/lib/rails_best_practices/checks/use_scope_access_check.rb +3 -3
- data/lib/rails_best_practices/checks.rb +10 -1
- data/lib/rails_best_practices/command.rb +50 -5
- data/lib/rails_best_practices/core/core_ext.rb +12 -1
- data/lib/rails_best_practices/core/runner.rb +12 -3
- data/lib/rails_best_practices/core/visitable_sexp.rb +21 -5
- data/rails_best_practices.gemspec +43 -16
- data/rails_best_practices.yml +9 -0
- data/spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb +57 -4
- data/spec/rails_best_practices/checks/always_add_db_index_check_spec.rb +153 -0
- data/spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb +79 -0
- data/spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb +71 -0
- data/spec/rails_best_practices/checks/law_of_demeter_check_spec.rb +37 -0
- data/spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb +33 -0
- data/spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb +29 -0
- data/spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb +6 -6
- data/spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb +4 -4
- data/spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb +5 -5
- data/spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb +26 -0
- data/spec/rails_best_practices/checks/use_filter_check_spec.rb +85 -0
- data/spec/rails_best_practices/checks/use_model_association_check_spec.rb +6 -6
- data/spec/rails_best_practices/checks/use_observer_check_spec.rb +67 -0
- data/spec/rails_best_practices/checks/use_scope_access_check_spec.rb +17 -17
- metadata +38 -11
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'optparse'
|
|
2
2
|
|
|
3
3
|
def expand_dirs_to_files *dirs
|
|
4
|
-
extensions = ['rb']
|
|
4
|
+
extensions = ['rb', 'erb', 'builder']
|
|
5
5
|
|
|
6
6
|
dirs.flatten.map { |p|
|
|
7
7
|
if File.directory? p
|
|
@@ -9,13 +9,46 @@ def expand_dirs_to_files *dirs
|
|
|
9
9
|
else
|
|
10
10
|
p
|
|
11
11
|
end
|
|
12
|
-
}.flatten
|
|
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) }
|
|
13
36
|
end
|
|
14
37
|
|
|
15
38
|
options = {}
|
|
16
39
|
OptionParser.new do |opts|
|
|
17
40
|
opts.banner = "Usage: rails_best_practices [options]"
|
|
18
41
|
|
|
42
|
+
opts.on("-d", "--debug", "Debug mode") do
|
|
43
|
+
options['debug'] = true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
['vendor', 'spec', 'test', 'stories'].each do |pattern|
|
|
47
|
+
opts.on("--#{pattern}", "include #{pattern} files") do
|
|
48
|
+
options[pattern] = true
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
19
52
|
opts.on_tail("-h", "--help", "Show this message") do
|
|
20
53
|
puts opts
|
|
21
54
|
exit
|
|
@@ -25,8 +58,20 @@ OptionParser.new do |opts|
|
|
|
25
58
|
end
|
|
26
59
|
|
|
27
60
|
runner = RailsBestPractices::Core::Runner.new
|
|
28
|
-
|
|
61
|
+
runner.set_debug if options['debug']
|
|
62
|
+
|
|
63
|
+
files = expand_dirs_to_files(ARGV)
|
|
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
|
|
69
|
+
files.each { |file| runner.check_file(file) }
|
|
70
|
+
|
|
29
71
|
runner.errors.each {|error| puts error}
|
|
30
|
-
|
|
72
|
+
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
|
+
puts "\nFound #{runner.errors.size} errors."
|
|
75
|
+
end
|
|
31
76
|
|
|
32
|
-
exit runner.errors.size
|
|
77
|
+
exit runner.errors.size
|
|
@@ -4,8 +4,19 @@ module Enumerable
|
|
|
4
4
|
end
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
+
class String
|
|
8
|
+
# copy from rails
|
|
9
|
+
def underscore
|
|
10
|
+
self.gsub(/::/, '/').
|
|
11
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
|
12
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
|
13
|
+
tr("-", "_").
|
|
14
|
+
downcase
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
7
18
|
class NilClass
|
|
8
19
|
def method_missing(method_sym, *arguments, &block)
|
|
9
20
|
return nil
|
|
10
21
|
end
|
|
11
|
-
end
|
|
22
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
2
|
require 'ruby_parser'
|
|
3
|
+
require 'erb'
|
|
3
4
|
require 'yaml'
|
|
4
5
|
|
|
5
6
|
module RailsBestPractices
|
|
@@ -17,10 +18,17 @@ module RailsBestPractices
|
|
|
17
18
|
@checks = checks unless checks.empty?
|
|
18
19
|
@checks ||= load_checks
|
|
19
20
|
@checker ||= CheckingVisitor.new(@checks)
|
|
20
|
-
@
|
|
21
|
+
@debug = false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def set_debug
|
|
25
|
+
@debug = true
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
def check(filename, content)
|
|
29
|
+
if filename =~ /.*erb/
|
|
30
|
+
content = ERB.new(content).src
|
|
31
|
+
end
|
|
24
32
|
node = parse(filename, content)
|
|
25
33
|
node.accept(@checker) if node
|
|
26
34
|
end
|
|
@@ -42,10 +50,11 @@ module RailsBestPractices
|
|
|
42
50
|
private
|
|
43
51
|
|
|
44
52
|
def parse(filename, content)
|
|
53
|
+
puts filename if @debug
|
|
45
54
|
begin
|
|
46
|
-
|
|
55
|
+
RubyParser.new.parse(content, filename)
|
|
47
56
|
rescue Exception => e
|
|
48
|
-
puts "#{filename} looks like it's not a valid Ruby file. Skipping..." if
|
|
57
|
+
puts "#{filename} looks like it's not a valid Ruby file. Skipping..." if @debug
|
|
49
58
|
nil
|
|
50
59
|
end
|
|
51
60
|
end
|
|
@@ -47,13 +47,13 @@ class Sexp
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def subject
|
|
50
|
-
if [:attrasgn, :call, :iasgn, :lasgn].include? node_type
|
|
50
|
+
if [:attrasgn, :call, :iasgn, :lasgn, :class].include? node_type
|
|
51
51
|
self[1]
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def message
|
|
56
|
-
if [:attrasgn, :call].include? node_type
|
|
56
|
+
if [:attrasgn, :call, :defs].include? node_type
|
|
57
57
|
self[2]
|
|
58
58
|
end
|
|
59
59
|
end
|
|
@@ -81,15 +81,31 @@ class Sexp
|
|
|
81
81
|
self[3]
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
|
+
|
|
85
|
+
def message_name
|
|
86
|
+
if :defn == node_type
|
|
87
|
+
self[1]
|
|
88
|
+
end
|
|
89
|
+
end
|
|
84
90
|
|
|
85
|
-
def
|
|
91
|
+
def body
|
|
86
92
|
if :block == node_type
|
|
87
93
|
self[1..-1]
|
|
88
|
-
|
|
94
|
+
elsif :class == node_type
|
|
95
|
+
self[3]
|
|
96
|
+
elsif :defn == node_type
|
|
97
|
+
self[3][1]
|
|
98
|
+
elsif :defs == node_type
|
|
99
|
+
self[4][1]
|
|
89
100
|
end
|
|
90
101
|
end
|
|
91
102
|
|
|
92
103
|
def to_ruby
|
|
93
|
-
Ruby2Ruby.new.process(self)
|
|
104
|
+
Ruby2Ruby.new.process(self) unless self.empty?
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def to_ruby_string
|
|
108
|
+
return nil if self.empty?
|
|
109
|
+
eval(Ruby2Ruby.new.process(self)).to_s
|
|
94
110
|
end
|
|
95
111
|
end
|
|
@@ -5,11 +5,11 @@
|
|
|
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.3.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{2009-11-
|
|
12
|
+
s.date = %q{2009-11-10}
|
|
13
13
|
s.default_executable = %q{rails_best_practices}
|
|
14
14
|
s.description = %q{check rails files according to ihower's presentation 'rails best practices'}
|
|
15
15
|
s.email = %q{flyerhzm@gmail.com}
|
|
@@ -28,8 +28,14 @@ Gem::Specification.new do |s|
|
|
|
28
28
|
"lib/rails_best_practices.rb",
|
|
29
29
|
"lib/rails_best_practices/checks.rb",
|
|
30
30
|
"lib/rails_best_practices/checks/add_model_virtual_attribute_check.rb",
|
|
31
|
+
"lib/rails_best_practices/checks/always_add_db_index_check.rb",
|
|
31
32
|
"lib/rails_best_practices/checks/check.rb",
|
|
33
|
+
"lib/rails_best_practices/checks/isolate_seed_data_check.rb",
|
|
34
|
+
"lib/rails_best_practices/checks/keep_finders_on_their_own_model_check.rb",
|
|
35
|
+
"lib/rails_best_practices/checks/law_of_demeter_check.rb",
|
|
32
36
|
"lib/rails_best_practices/checks/many_to_many_collection_check.rb",
|
|
37
|
+
"lib/rails_best_practices/checks/move_code_into_controller_check.rb",
|
|
38
|
+
"lib/rails_best_practices/checks/move_code_into_helper_check.rb",
|
|
33
39
|
"lib/rails_best_practices/checks/move_finder_to_named_scope_check.rb",
|
|
34
40
|
"lib/rails_best_practices/checks/move_model_logic_into_model_check.rb",
|
|
35
41
|
"lib/rails_best_practices/checks/needless_deep_nesting_check.rb",
|
|
@@ -37,8 +43,11 @@ Gem::Specification.new do |s|
|
|
|
37
43
|
"lib/rails_best_practices/checks/not_use_default_route_check.rb",
|
|
38
44
|
"lib/rails_best_practices/checks/overuse_route_customizations_check.rb",
|
|
39
45
|
"lib/rails_best_practices/checks/replace_complex_creation_with_factory_method_check.rb",
|
|
46
|
+
"lib/rails_best_practices/checks/replace_instance_variable_with_local_variable_check.rb",
|
|
47
|
+
"lib/rails_best_practices/checks/use_filter_check.rb",
|
|
40
48
|
"lib/rails_best_practices/checks/use_model_association_check.rb",
|
|
41
49
|
"lib/rails_best_practices/checks/use_model_callback_check.rb",
|
|
50
|
+
"lib/rails_best_practices/checks/use_observer_check.rb",
|
|
42
51
|
"lib/rails_best_practices/checks/use_scope_access_check.rb",
|
|
43
52
|
"lib/rails_best_practices/command.rb",
|
|
44
53
|
"lib/rails_best_practices/core.rb",
|
|
@@ -50,7 +59,13 @@ Gem::Specification.new do |s|
|
|
|
50
59
|
"rails_best_practices.gemspec",
|
|
51
60
|
"rails_best_practices.yml",
|
|
52
61
|
"spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb",
|
|
62
|
+
"spec/rails_best_practices/checks/always_add_db_index_check_spec.rb",
|
|
63
|
+
"spec/rails_best_practices/checks/isolate_seed_data_check_spec.rb",
|
|
64
|
+
"spec/rails_best_practices/checks/keep_finders_on_their_own_model_check_spec.rb",
|
|
65
|
+
"spec/rails_best_practices/checks/law_of_demeter_check_spec.rb",
|
|
53
66
|
"spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb",
|
|
67
|
+
"spec/rails_best_practices/checks/move_code_into_controller_check_spec.rb",
|
|
68
|
+
"spec/rails_best_practices/checks/move_code_into_helper_check_spec.rb",
|
|
54
69
|
"spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb",
|
|
55
70
|
"spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb",
|
|
56
71
|
"spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb",
|
|
@@ -58,8 +73,11 @@ Gem::Specification.new do |s|
|
|
|
58
73
|
"spec/rails_best_practices/checks/not_use_default_route_check_spec.rb",
|
|
59
74
|
"spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb",
|
|
60
75
|
"spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb",
|
|
76
|
+
"spec/rails_best_practices/checks/replace_instance_variable_with_local_variable_check_spec.rb",
|
|
77
|
+
"spec/rails_best_practices/checks/use_filter_check_spec.rb",
|
|
61
78
|
"spec/rails_best_practices/checks/use_model_association_check_spec.rb",
|
|
62
79
|
"spec/rails_best_practices/checks/use_model_callback_check_spec.rb",
|
|
80
|
+
"spec/rails_best_practices/checks/use_observer_check_spec.rb",
|
|
63
81
|
"spec/rails_best_practices/checks/use_scope_access_check_spec.rb",
|
|
64
82
|
"spec/spec.opts",
|
|
65
83
|
"spec/spec_helper.rb"
|
|
@@ -70,18 +88,27 @@ Gem::Specification.new do |s|
|
|
|
70
88
|
s.rubygems_version = %q{1.3.5}
|
|
71
89
|
s.summary = %q{check rails files according to ihower's presentation 'rails best practices'}
|
|
72
90
|
s.test_files = [
|
|
73
|
-
"spec/rails_best_practices/checks/
|
|
74
|
-
"spec/rails_best_practices/checks/
|
|
75
|
-
"spec/rails_best_practices/checks/
|
|
76
|
-
"spec/rails_best_practices/checks/
|
|
91
|
+
"spec/rails_best_practices/checks/add_model_virtual_attribute_check_spec.rb",
|
|
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",
|
|
77
96
|
"spec/rails_best_practices/checks/many_to_many_collection_check_spec.rb",
|
|
78
|
-
"spec/rails_best_practices/checks/
|
|
79
|
-
"spec/rails_best_practices/checks/
|
|
80
|
-
"spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb",
|
|
81
|
-
"spec/rails_best_practices/checks/nested_model_forms_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",
|
|
82
99
|
"spec/rails_best_practices/checks/move_finder_to_named_scope_check_spec.rb",
|
|
100
|
+
"spec/rails_best_practices/checks/move_model_logic_into_model_check_spec.rb",
|
|
83
101
|
"spec/rails_best_practices/checks/needless_deep_nesting_check_spec.rb",
|
|
102
|
+
"spec/rails_best_practices/checks/nested_model_forms_check_spec.rb",
|
|
103
|
+
"spec/rails_best_practices/checks/not_use_default_route_check_spec.rb",
|
|
84
104
|
"spec/rails_best_practices/checks/overuse_route_customizations_check_spec.rb",
|
|
105
|
+
"spec/rails_best_practices/checks/replace_complex_creation_with_factory_method_check_spec.rb",
|
|
106
|
+
"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
|
+
"spec/rails_best_practices/checks/use_model_association_check_spec.rb",
|
|
109
|
+
"spec/rails_best_practices/checks/use_model_callback_check_spec.rb",
|
|
110
|
+
"spec/rails_best_practices/checks/use_observer_check_spec.rb",
|
|
111
|
+
"spec/rails_best_practices/checks/use_scope_access_check_spec.rb",
|
|
85
112
|
"spec/spec_helper.rb"
|
|
86
113
|
]
|
|
87
114
|
|
|
@@ -90,15 +117,15 @@ Gem::Specification.new do |s|
|
|
|
90
117
|
s.specification_version = 3
|
|
91
118
|
|
|
92
119
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
93
|
-
s.add_runtime_dependency(%q<ruby_parser>, [">= 0"])
|
|
94
|
-
s.add_runtime_dependency(%q<ruby2ruby>, [">=
|
|
120
|
+
s.add_runtime_dependency(%q<ruby_parser>, [">= 2.0.4"])
|
|
121
|
+
s.add_runtime_dependency(%q<ruby2ruby>, [">= 1.2.4"])
|
|
95
122
|
else
|
|
96
|
-
s.add_dependency(%q<ruby_parser>, [">= 0"])
|
|
97
|
-
s.add_dependency(%q<ruby2ruby>, [">=
|
|
123
|
+
s.add_dependency(%q<ruby_parser>, [">= 2.0.4"])
|
|
124
|
+
s.add_dependency(%q<ruby2ruby>, [">= 1.2.4"])
|
|
98
125
|
end
|
|
99
126
|
else
|
|
100
|
-
s.add_dependency(%q<ruby_parser>, [">= 0"])
|
|
101
|
-
s.add_dependency(%q<ruby2ruby>, [">=
|
|
127
|
+
s.add_dependency(%q<ruby_parser>, [">= 2.0.4"])
|
|
128
|
+
s.add_dependency(%q<ruby2ruby>, [">= 1.2.4"])
|
|
102
129
|
end
|
|
103
130
|
end
|
|
104
131
|
|
data/rails_best_practices.yml
CHANGED
|
@@ -10,3 +10,12 @@ MoveModelLogicIntoModelCheck: { called_count: 4 }
|
|
|
10
10
|
OveruseRouteCustomizationsCheck: { customize_count: 3 }
|
|
11
11
|
NeedlessDeepNestingCheck: { nested_count: 2 }
|
|
12
12
|
NotUseDefaultRouteCheck: { }
|
|
13
|
+
KeepFindersOnTheirOwnModelCheck: { }
|
|
14
|
+
LawOfDemeterCheck: { }
|
|
15
|
+
UseObserverCheck: { }
|
|
16
|
+
IsolateSeedDataCheck: { }
|
|
17
|
+
AlwaysAddDbIndexCheck: { }
|
|
18
|
+
UseFilterCheck: { }
|
|
19
|
+
MoveCodeIntoControllerCheck: { }
|
|
20
|
+
MoveCodeIntoHelperCheck: { }
|
|
21
|
+
ReplaceInstanceVariableWithLocalVariableCheck: { }
|
|
@@ -17,10 +17,28 @@ describe RailsBestPractices::Checks::AddModelVirtualAttributeCheck do
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
EOF
|
|
20
|
-
@runner.check('app/
|
|
20
|
+
@runner.check('app/controllers/users_controller.rb', content)
|
|
21
21
|
errors = @runner.errors
|
|
22
22
|
errors.should_not be_empty
|
|
23
|
-
errors[0].to_s.should == "app/
|
|
23
|
+
errors[0].to_s.should == "app/controllers/users_controller.rb:3 - add model virtual attribute (for @user)"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should add model virtual attribute with local assignment" do
|
|
27
|
+
content = <<-EOF
|
|
28
|
+
class UsersController < ApplicationController
|
|
29
|
+
|
|
30
|
+
def create
|
|
31
|
+
user = User.new(params[:user])
|
|
32
|
+
user.first_name = params[:full_name].split(' ', 2).first
|
|
33
|
+
user.last_name = params[:full_name].split(' ', 2).last
|
|
34
|
+
user.save
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
EOF
|
|
38
|
+
@runner.check('app/controllers/users_controller.rb', content)
|
|
39
|
+
errors = @runner.errors
|
|
40
|
+
errors.should_not be_empty
|
|
41
|
+
errors[0].to_s.should == "app/controllers/users_controller.rb:3 - add model virtual attribute (for user)"
|
|
24
42
|
end
|
|
25
43
|
|
|
26
44
|
it "should not add model virtual attribute with differen param" do
|
|
@@ -35,7 +53,7 @@ describe RailsBestPractices::Checks::AddModelVirtualAttributeCheck do
|
|
|
35
53
|
end
|
|
36
54
|
end
|
|
37
55
|
EOF
|
|
38
|
-
@runner.check('app/
|
|
56
|
+
@runner.check('app/controllers/users_controller.rb', content)
|
|
39
57
|
errors = @runner.errors
|
|
40
58
|
errors.should be_empty
|
|
41
59
|
end
|
|
@@ -53,7 +71,42 @@ describe RailsBestPractices::Checks::AddModelVirtualAttributeCheck do
|
|
|
53
71
|
end
|
|
54
72
|
end
|
|
55
73
|
EOF
|
|
56
|
-
@runner.check('app/
|
|
74
|
+
@runner.check('app/controllers/users_controller.rb', content)
|
|
75
|
+
errors = @runner.errors
|
|
76
|
+
errors.should be_empty
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should add model virtual attribute with two dimension params" do
|
|
80
|
+
content = <<-EOF
|
|
81
|
+
class UsersController < ApplicationController
|
|
82
|
+
|
|
83
|
+
def create
|
|
84
|
+
@user = User.new(params[:user])
|
|
85
|
+
@user.first_name = params[:user][:full_name].split(' ', 2).first
|
|
86
|
+
@user.last_name = params[:user][:full_name].split(' ', 2).last
|
|
87
|
+
@user.save
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
EOF
|
|
91
|
+
@runner.check('app/controllers/users_controller.rb', content)
|
|
92
|
+
errors = @runner.errors
|
|
93
|
+
errors.should_not be_empty
|
|
94
|
+
errors[0].to_s.should == "app/controllers/users_controller.rb:3 - add model virtual attribute (for @user)"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should no add model virtual attribute with two dimension params" do
|
|
98
|
+
content = <<-EOF
|
|
99
|
+
class UsersController < ApplicationController
|
|
100
|
+
|
|
101
|
+
def create
|
|
102
|
+
@user = User.new(params[:user])
|
|
103
|
+
@user.first_name = params[:user][:first_name]
|
|
104
|
+
@user.last_name = params[:user][:last_name]
|
|
105
|
+
@user.save
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
EOF
|
|
109
|
+
@runner.check('app/controllers/users_controller.rb', content)
|
|
57
110
|
errors = @runner.errors
|
|
58
111
|
errors.should be_empty
|
|
59
112
|
end
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
|
+
|
|
3
|
+
describe RailsBestPractices::Checks::AlwaysAddDbIndexCheck do
|
|
4
|
+
before(:each) do
|
|
5
|
+
@runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::AlwaysAddDbIndexCheck.new)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "should always add db index" do
|
|
9
|
+
content = <<-EOF
|
|
10
|
+
class CreateComments < ActiveRecord::Migration
|
|
11
|
+
def self.up
|
|
12
|
+
create_table "comments", :force => true do |t|
|
|
13
|
+
t.string :content
|
|
14
|
+
t.integer :post_id
|
|
15
|
+
t.integer :user_id
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.down
|
|
20
|
+
drop_table "comments"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
EOF
|
|
24
|
+
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
25
|
+
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
26
|
+
errors = @runner.errors
|
|
27
|
+
errors.should_not be_empty
|
|
28
|
+
errors[0].to_s.should == "db/migrate/20090918130258_create_comments.rb:2 - always add db index (comments => post_id, comments => user_id)"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should always add db index with column has no id" do
|
|
32
|
+
content = <<-EOF
|
|
33
|
+
class CreateComments < ActiveRecord::Migration
|
|
34
|
+
def self.up
|
|
35
|
+
create_table "comments", :force => true do |t|
|
|
36
|
+
t.string :content
|
|
37
|
+
t.integer :position
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.down
|
|
42
|
+
drop_table "comments"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
EOF
|
|
46
|
+
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
47
|
+
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
48
|
+
errors = @runner.errors
|
|
49
|
+
errors.should be_empty
|
|
50
|
+
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
|
+
|
|
98
|
+
it "should not always add db index with add_index" do
|
|
99
|
+
content = <<-EOF
|
|
100
|
+
class CreateComments < ActiveRecord::Migration
|
|
101
|
+
def self.up
|
|
102
|
+
create_table "comments", :force => true do |t|
|
|
103
|
+
t.string :content
|
|
104
|
+
t.integer :post_id
|
|
105
|
+
t.integer :user_id
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
add_index :comments, :post_id
|
|
109
|
+
add_index :comments, :user_id
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def self.down
|
|
113
|
+
drop_table "comments"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
EOF
|
|
117
|
+
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
118
|
+
@runner.check('db/migrate/20090918130258_create_comments.rb', content)
|
|
119
|
+
errors = @runner.errors
|
|
120
|
+
errors.should be_empty
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should not always add db index with add_index in another migration file" do
|
|
124
|
+
content = <<-EOF
|
|
125
|
+
class CreateComments < ActiveRecord::Migration
|
|
126
|
+
def self.up
|
|
127
|
+
create_table "comments", :force => true do |t|
|
|
128
|
+
t.string :content
|
|
129
|
+
t.integer :post_id
|
|
130
|
+
t.integer :user_id
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def self.down
|
|
135
|
+
drop_table "comments"
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
EOF
|
|
139
|
+
add_index_content = <<-EOF
|
|
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)
|
|
151
|
+
errors = @runner.errors
|
|
152
|
+
end
|
|
153
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
|
+
|
|
3
|
+
describe RailsBestPractices::Checks::IsolateSeedDataCheck do
|
|
4
|
+
before(:each) do
|
|
5
|
+
@runner = RailsBestPractices::Core::Runner.new(RailsBestPractices::Checks::IsolateSeedDataCheck.new)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "should isolate seed data" do
|
|
9
|
+
content = <<-EOF
|
|
10
|
+
class CreateRoles < ActiveRecord::Migration
|
|
11
|
+
def self.up
|
|
12
|
+
create_table "roles", :force => true do |t|
|
|
13
|
+
t.string :name
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
["admin", "author", "editor", "account"].each do |name|
|
|
17
|
+
Role.create!(:name => name)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.down
|
|
22
|
+
drop_table "roles"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
EOF
|
|
26
|
+
@runner.check('db/migrate/20090818130258_create_roles.rb', content)
|
|
27
|
+
@runner.check('db/migrate/20090818130258_create_roles.rb', content)
|
|
28
|
+
errors = @runner.errors
|
|
29
|
+
errors.should_not be_empty
|
|
30
|
+
errors[0].to_s.should == "db/migrate/20090818130258_create_roles.rb:8 - isolate seed data"
|
|
31
|
+
errors.size.should == 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should isolate seed data with new and save" do
|
|
35
|
+
content = <<-EOF
|
|
36
|
+
class CreateRoles < ActiveRecord::Migration
|
|
37
|
+
def self.up
|
|
38
|
+
create_table "roles", :force => true do |t|
|
|
39
|
+
t.string :name
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
["admin", "author", "editor", "account"].each do |name|
|
|
43
|
+
role = Role.new(:name => name)
|
|
44
|
+
role.save!
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.down
|
|
49
|
+
drop_table "roles"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
EOF
|
|
53
|
+
@runner.check('db/migrate/20090818130258_create_roles.rb', content)
|
|
54
|
+
@runner.check('db/migrate/20090818130258_create_roles.rb', content)
|
|
55
|
+
errors = @runner.errors
|
|
56
|
+
errors.should_not be_empty
|
|
57
|
+
errors[0].to_s.should == "db/migrate/20090818130258_create_roles.rb:9 - isolate seed data"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should not isolate seed data without data insert" do
|
|
61
|
+
content = <<-EOF
|
|
62
|
+
class CreateRoles < ActiveRecord::Migration
|
|
63
|
+
def self.up
|
|
64
|
+
create_table "roles", :force => true do |t|
|
|
65
|
+
t.string :name
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.down
|
|
70
|
+
drop_table "roles"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
EOF
|
|
74
|
+
@runner.check('db/migrate/20090818130258_create_roles.rb', content)
|
|
75
|
+
@runner.check('db/migrate/20090818130258_create_roles.rb', content)
|
|
76
|
+
errors = @runner.errors
|
|
77
|
+
errors.should be_empty
|
|
78
|
+
end
|
|
79
|
+
end
|