whyvalidationssuckin96 1.1.0 → 1.2.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/VERSION +1 -1
- data/lib/whyvalidationssuckin96/constants.rb +0 -1
- data/lib/whyvalidationssuckin96/rails/active_record/association_validation.rb +38 -0
- data/lib/whyvalidationssuckin96/rails/active_record/base_validation_overrides.rb +124 -0
- data/lib/whyvalidationssuckin96/rails/active_record.rb +3 -92
- data/test/rails/active_record_test_helper.rb +37 -0
- data/test/rails/association_validation_test.rb +114 -0
- data/test/rails/{active_record_test.rb → base_validation_overrides_test.rb} +0 -0
- data/whyvalidationssuckin96.gemspec +7 -3
- metadata +7 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'active_record/autosave_association'
|
2
|
+
|
3
|
+
module WhyValidationsSuckIn96
|
4
|
+
module ActiveRecord
|
5
|
+
module AssociationValidation
|
6
|
+
|
7
|
+
def self.included(klass_or_mod)
|
8
|
+
klass_or_mod.module_eval do
|
9
|
+
extend ClassMethods
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def self.extended(klass_or_mod)
|
15
|
+
(class << klass_or_mod; self; end).instance_eval do
|
16
|
+
# FIXME - alias method chain my ass
|
17
|
+
alias_method_chain :add_autosave_association_callbacks, :validation_hooks
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_autosave_association_callbacks_with_validation_hooks(reflection)
|
22
|
+
add_autosave_association_callbacks_without_validation_hooks(reflection)
|
23
|
+
setup_validations_for_association_reflection(reflection)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def setup_validations_for_association_reflection(reflection)
|
29
|
+
return false unless reflection.options[:validate] || reflection.options[:autosave]
|
30
|
+
setup_validations { validates_associated reflection.name.to_sym, :on => :save }
|
31
|
+
end
|
32
|
+
|
33
|
+
end # ClassMethods
|
34
|
+
end # AssociationValidation
|
35
|
+
end # ActiveRecord
|
36
|
+
end # WhyValidationsSuckIn96
|
37
|
+
|
38
|
+
ActiveRecord::Base.instance_eval { include WhyValidationsSuckIn96::ActiveRecord::AssociationValidation }
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'active_record/base'
|
2
|
+
require 'active_record/callbacks'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
module ActiveRecord
|
6
|
+
class << self
|
7
|
+
attr_accessor :warn_on_deprecation
|
8
|
+
end
|
9
|
+
self.warn_on_deprecation = true
|
10
|
+
|
11
|
+
RemovableInstanceMethods = %w[invalid? validate_on_create validate_on_update validate errors]
|
12
|
+
RemovableClassMethods = %w[validate validate_on_create validate_on_update validates_format_of validates_each
|
13
|
+
validates_inclusion_of validates_size_of validates_confirmation_of validates_exclusion_of
|
14
|
+
validates_uniqueness_of validates_associated validates_acceptance_of
|
15
|
+
validates_numericality_of validates_presence_of validates_length_of]
|
16
|
+
|
17
|
+
def self.included(klass_or_mod)
|
18
|
+
remove_active_record_validation_related_methods_from(klass_or_mod)
|
19
|
+
klass_or_mod.instance_eval do
|
20
|
+
include WhyValidationsSuckIn96::ValidationSupport
|
21
|
+
include WhyValidationsSuckIn96::ActiveRecord::InstanceMethods
|
22
|
+
extend WhyValidationsSuckIn96::ActiveRecord::ClassMethods
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# FIXME - holy mother of god is this a nasty method
|
29
|
+
def self.remove_active_record_validation_related_methods_from(klass_or_mod)
|
30
|
+
method_map = {klass_or_mod => RemovableInstanceMethods, (class<<klass_or_mod;self;end) => RemovableClassMethods}
|
31
|
+
method_map.each do |context, removable_methods|
|
32
|
+
context.instance_eval do
|
33
|
+
removable_methods.each do |removable_method|
|
34
|
+
begin
|
35
|
+
remove_method removable_method
|
36
|
+
rescue => e
|
37
|
+
undef_method removable_method
|
38
|
+
end
|
39
|
+
end # removable_methods.each
|
40
|
+
end # context.instance_eval
|
41
|
+
end # method_map.each
|
42
|
+
end
|
43
|
+
|
44
|
+
module ClassMethods
|
45
|
+
|
46
|
+
# FIXME - this is a seedy hack and i blame the entire contents of active_record/autosave_association.rb
|
47
|
+
# for it being necessary.
|
48
|
+
def validate(*args)
|
49
|
+
return false unless WhyValidationsSuckIn96::ActiveRecord.warn_on_deprecation
|
50
|
+
callstack = caller
|
51
|
+
warn(<<-EOW.gsub(/^\s{10}/, ""))
|
52
|
+
This is a friendly message from WhyValidationsSuckIn96. #{self.inspect} called 'validate' which is a
|
53
|
+
deprecated method. The arguments given were:
|
54
|
+
|
55
|
+
#{args.inspect} - #{block_given? ? 'block given' : 'no block given'}
|
56
|
+
|
57
|
+
and the caller was:
|
58
|
+
|
59
|
+
#{callstack.first}
|
60
|
+
|
61
|
+
If these warnings are coming from a call to 'add_autosave_association_callbacks', do not be alarmed, as
|
62
|
+
WhyValidationsSuckIn96 has implemented its own versions of the necessary validation callbacks.
|
63
|
+
|
64
|
+
These warnings can be silenced by setting 'WhyValidationsSuckIn96::ActiveRecord.warn_on_deprecation' to false.
|
65
|
+
You will now be returned to your regularly scheduled programming.
|
66
|
+
EOW
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
end # ClassMethods
|
71
|
+
|
72
|
+
module InstanceMethods
|
73
|
+
|
74
|
+
def self.included(klass_or_mod)
|
75
|
+
klass_or_mod.module_eval do
|
76
|
+
alias_method :valid_without_callbacks?, :valid_with_lifecycle_checking?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def validations_for_current_lifecycle
|
83
|
+
validations_for_save + (new_record? ? validations_for_create : validations_for_update)
|
84
|
+
end
|
85
|
+
|
86
|
+
def valid_with_lifecycle_checking?
|
87
|
+
validations_for_current_lifecycle.collect do |validation|
|
88
|
+
validation.validates?
|
89
|
+
end.all?
|
90
|
+
end
|
91
|
+
|
92
|
+
def validations_for_update
|
93
|
+
all_validations.select do |validation|
|
94
|
+
validation.options[:on] == :update
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def validations_for_create
|
99
|
+
all_validations.select do |validation|
|
100
|
+
validation.options[:on] == :create
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def validations_for_save
|
105
|
+
all_validations.select do |validation|
|
106
|
+
validation.options[:on].nil? || validation.options[:on] == :save
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end # InstanceMethods
|
111
|
+
end # ActiveRecord
|
112
|
+
end # WhyValidationsSuckIn96
|
113
|
+
|
114
|
+
module ActiveRecord
|
115
|
+
class RecordInvalid < ActiveRecordError
|
116
|
+
attr_reader :record
|
117
|
+
def initialize(record)
|
118
|
+
@record = record
|
119
|
+
super
|
120
|
+
end
|
121
|
+
end # RecordInvalid
|
122
|
+
end # ActiveRecord
|
123
|
+
|
124
|
+
ActiveRecord::Base.instance_eval { include WhyValidationsSuckIn96::ActiveRecord }
|
@@ -1,94 +1,5 @@
|
|
1
1
|
require 'whyvalidationssuckin96'
|
2
2
|
require 'active_record'
|
3
|
-
require 'active_record/
|
4
|
-
require 'active_record/
|
5
|
-
require 'whyvalidationssuckin96/rails/macros'
|
6
|
-
|
7
|
-
module WhyValidationsSuckIn96
|
8
|
-
|
9
|
-
module ActiveRecord
|
10
|
-
RemovableInstanceMethods = %w[invalid? validate_on_create validate_on_update validate errors]
|
11
|
-
RemovableClassMethods = %w[validate validate_on_create validate_on_update validates_format_of validates_each
|
12
|
-
validates_inclusion_of validates_size_of validates_confirmation_of validates_exclusion_of
|
13
|
-
validates_uniqueness_of validates_associated validates_acceptance_of
|
14
|
-
validates_numericality_of validates_presence_of validates_length_of]
|
15
|
-
|
16
|
-
def self.included(klass_or_mod)
|
17
|
-
remove_active_record_validation_related_methods_from(klass_or_mod)
|
18
|
-
klass_or_mod.instance_eval do
|
19
|
-
include WhyValidationsSuckIn96::ValidationSupport
|
20
|
-
include WhyValidationsSuckIn96::ActiveRecord::InstanceMethods
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
# FIXME - holy mother of god is this a nasty method
|
27
|
-
def self.remove_active_record_validation_related_methods_from(klass_or_mod)
|
28
|
-
method_map = {klass_or_mod => RemovableInstanceMethods, (class<<klass_or_mod;self;end) => RemovableClassMethods}
|
29
|
-
method_map.each do |context, removable_methods|
|
30
|
-
context.instance_eval do
|
31
|
-
removable_methods.each do |removable_method|
|
32
|
-
begin
|
33
|
-
remove_method removable_method
|
34
|
-
rescue => e
|
35
|
-
undef_method removable_method
|
36
|
-
end
|
37
|
-
end # removable_methods.each
|
38
|
-
end # context.instance_eval
|
39
|
-
end # method_map.each
|
40
|
-
end
|
41
|
-
|
42
|
-
module InstanceMethods
|
43
|
-
|
44
|
-
def self.included(klass_or_mod)
|
45
|
-
klass_or_mod.module_eval do
|
46
|
-
alias_method :valid_without_callbacks?, :valid_with_lifecycle_checking?
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def validations_for_current_lifecycle
|
53
|
-
validations_for_save + (new_record? ? validations_for_create : validations_for_update)
|
54
|
-
end
|
55
|
-
|
56
|
-
def valid_with_lifecycle_checking?
|
57
|
-
validations_for_current_lifecycle.collect do |validation|
|
58
|
-
validation.validates?
|
59
|
-
end.all?
|
60
|
-
end
|
61
|
-
|
62
|
-
def validations_for_update
|
63
|
-
all_validations.select do |validation|
|
64
|
-
validation.options[:on] == :update
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def validations_for_create
|
69
|
-
all_validations.select do |validation|
|
70
|
-
validation.options[:on] == :create
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def validations_for_save
|
75
|
-
all_validations.select do |validation|
|
76
|
-
validation.options[:on].nil? || validation.options[:on] == :save
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
end # InstanceMethods
|
81
|
-
end # ActiveRecord
|
82
|
-
end # WhyValidationsSuckIn96
|
83
|
-
|
84
|
-
module ActiveRecord
|
85
|
-
class RecordInvalid < ActiveRecordError
|
86
|
-
attr_reader :record
|
87
|
-
def initialize(record)
|
88
|
-
@record = record
|
89
|
-
super
|
90
|
-
end
|
91
|
-
end # RecordInvalid
|
92
|
-
end # ActiveRecord
|
93
|
-
|
94
|
-
ActiveRecord::Base.instance_eval { include WhyValidationsSuckIn96::ActiveRecord }
|
3
|
+
require 'whyvalidationssuckin96/rails/active_record/base_validation_overrides'
|
4
|
+
require 'whyvalidationssuckin96/rails/active_record/association_validation'
|
5
|
+
require 'whyvalidationssuckin96/rails/macros'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'whyvalidationssuckin96/rails/active_record'
|
2
|
+
WhyValidationsSuckIn96::ActiveRecord.warn_on_deprecation = false
|
2
3
|
|
3
4
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
4
5
|
ActiveRecord::Schema.define(:version => 1) do
|
@@ -11,8 +12,44 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
11
12
|
t.string :author
|
12
13
|
t.string :type
|
13
14
|
end
|
15
|
+
|
16
|
+
create_table :books do |t|
|
17
|
+
t.string :name
|
18
|
+
t.has_one :glossary
|
19
|
+
t.has_many :chapters
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table :glossaries do |t|
|
23
|
+
t.belongs_to :book
|
24
|
+
end
|
25
|
+
|
26
|
+
create_table :chapters do |t|
|
27
|
+
t.string :name
|
28
|
+
t.belongs_to :book
|
29
|
+
end
|
30
|
+
|
31
|
+
create_table :genres do |t|
|
32
|
+
t.string :name
|
33
|
+
end
|
34
|
+
|
35
|
+
create_table :books_genres, :id => false do |t|
|
36
|
+
t.belongs_to :book
|
37
|
+
t.belongs_to :genre
|
38
|
+
end
|
14
39
|
end
|
15
40
|
|
41
|
+
class Glossary < ActiveRecord::Base
|
42
|
+
end
|
43
|
+
|
44
|
+
class Book < ActiveRecord::Base
|
45
|
+
end
|
46
|
+
|
47
|
+
class Chapter < ActiveRecord::Base
|
48
|
+
end
|
49
|
+
|
50
|
+
class Genre < ActiveRecord::Base
|
51
|
+
end
|
52
|
+
|
16
53
|
class MusicalWork < ActiveRecord::Base
|
17
54
|
attr_accessor :state, :callbacks_run, :validations_run
|
18
55
|
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'teststrap'
|
2
|
+
require 'rails/active_record_test_helper'
|
3
|
+
|
4
|
+
context "association validation" do
|
5
|
+
has_association_validation = lambda do |klass,assoc|
|
6
|
+
!klass.validation_collection.detect do |(validation_klass,opts)|
|
7
|
+
validation_klass == WhyValidationsSuckIn96::ValidatesAssociated && opts[:attribute] == assoc && opts[:on] == :save
|
8
|
+
end.nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
context "against has_many" do
|
12
|
+
context "with :validate set to true" do
|
13
|
+
setup do
|
14
|
+
Class.new(Book) do
|
15
|
+
has_many :chapters, :validate => true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
should "set up an association validation" do
|
20
|
+
has_association_validation[topic, :chapters]
|
21
|
+
end
|
22
|
+
end # with :validate set to true
|
23
|
+
|
24
|
+
context "with :validate set to false" do
|
25
|
+
setup do
|
26
|
+
Class.new(Book) do
|
27
|
+
has_many :chapters, :validate => false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
should "not set up an association validation" do
|
32
|
+
has_association_validation[topic, :chapters]
|
33
|
+
end.equals(false)
|
34
|
+
end # with :validate set to false
|
35
|
+
end # against has_many
|
36
|
+
|
37
|
+
context "against has_and_belongs_to_many" do
|
38
|
+
context "with :validate set to true" do
|
39
|
+
setup do
|
40
|
+
Class.new(Genre) do
|
41
|
+
has_and_belongs_to_many :books, :validate => true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
should "set up an association validation" do
|
46
|
+
has_association_validation[topic, :books]
|
47
|
+
end
|
48
|
+
end # with :validate set to true
|
49
|
+
|
50
|
+
context "with :validate set to false" do
|
51
|
+
setup do
|
52
|
+
Class.new(Genre) do
|
53
|
+
has_and_belongs_to_many :books, :validate => false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
should "not set up an association validation" do
|
58
|
+
has_association_validation[topic, :books]
|
59
|
+
end.equals(false)
|
60
|
+
end # with :validate set to false
|
61
|
+
end # against has_and_belongs_to_many
|
62
|
+
|
63
|
+
context "against has_one" do
|
64
|
+
context "with :validate set to true" do
|
65
|
+
setup do
|
66
|
+
Class.new(Book) do
|
67
|
+
has_one :glossary, :validate => true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
should "set up an association validation" do
|
72
|
+
has_association_validation[topic, :glossary]
|
73
|
+
end
|
74
|
+
end # with :validate set to true
|
75
|
+
|
76
|
+
context "with :validate set to false" do
|
77
|
+
setup do
|
78
|
+
Class.new(Book) do
|
79
|
+
has_one :glossary, :validate => false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
should "not set up an association validation" do
|
84
|
+
has_association_validation[topic, :glossary]
|
85
|
+
end.equals(false)
|
86
|
+
end # with :validate set to false
|
87
|
+
end # against has_one
|
88
|
+
|
89
|
+
context "against belongs_to" do
|
90
|
+
context "with :validate set to true" do
|
91
|
+
setup do
|
92
|
+
Class.new(Chapter) do
|
93
|
+
belongs_to :book, :validate => true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
should "set up an association validation" do
|
98
|
+
has_association_validation[topic, :book]
|
99
|
+
end
|
100
|
+
end # with :validate set to true
|
101
|
+
|
102
|
+
context "with :validate set to false" do
|
103
|
+
setup do
|
104
|
+
Class.new(Chapter) do
|
105
|
+
belongs_to :book, :validate => false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
should "not set up an association validation" do
|
110
|
+
has_association_validation[topic, :book]
|
111
|
+
end.equals(false)
|
112
|
+
end # with :validate set to false
|
113
|
+
end # against belongs_to
|
114
|
+
end # association validation
|
File without changes
|
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{whyvalidationssuckin96}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["gabrielg", "douglasmeyer"]
|
@@ -81,6 +81,8 @@ Gem::Specification.new do |s|
|
|
81
81
|
"lib/whyvalidationssuckin96/macros/validates_presence.rb",
|
82
82
|
"lib/whyvalidationssuckin96/macros/validates_url.rb",
|
83
83
|
"lib/whyvalidationssuckin96/rails/active_record.rb",
|
84
|
+
"lib/whyvalidationssuckin96/rails/active_record/association_validation.rb",
|
85
|
+
"lib/whyvalidationssuckin96/rails/active_record/base_validation_overrides.rb",
|
84
86
|
"lib/whyvalidationssuckin96/rails/macros.rb",
|
85
87
|
"lib/whyvalidationssuckin96/rails/macros/validates_uniqueness.rb",
|
86
88
|
"lib/whyvalidationssuckin96/skippable_validation.rb",
|
@@ -98,8 +100,9 @@ Gem::Specification.new do |s|
|
|
98
100
|
"test/macros/validates_numericality_test.rb",
|
99
101
|
"test/macros/validates_presence_test.rb",
|
100
102
|
"test/macros/validates_url_test.rb",
|
101
|
-
"test/rails/active_record_test.rb",
|
102
103
|
"test/rails/active_record_test_helper.rb",
|
104
|
+
"test/rails/association_validation_test.rb",
|
105
|
+
"test/rails/base_validation_overrides_test.rb",
|
103
106
|
"test/rails/macros/validates_uniqueness_test.rb",
|
104
107
|
"test/skippable_validation_test.rb",
|
105
108
|
"test/teststrap.rb",
|
@@ -125,8 +128,9 @@ Gem::Specification.new do |s|
|
|
125
128
|
"test/macros/validates_numericality_test.rb",
|
126
129
|
"test/macros/validates_presence_test.rb",
|
127
130
|
"test/macros/validates_url_test.rb",
|
128
|
-
"test/rails/active_record_test.rb",
|
129
131
|
"test/rails/active_record_test_helper.rb",
|
132
|
+
"test/rails/association_validation_test.rb",
|
133
|
+
"test/rails/base_validation_overrides_test.rb",
|
130
134
|
"test/rails/macros/validates_uniqueness_test.rb",
|
131
135
|
"test/skippable_validation_test.rb",
|
132
136
|
"test/teststrap.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whyvalidationssuckin96
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- gabrielg
|
@@ -117,6 +117,8 @@ files:
|
|
117
117
|
- lib/whyvalidationssuckin96/macros/validates_presence.rb
|
118
118
|
- lib/whyvalidationssuckin96/macros/validates_url.rb
|
119
119
|
- lib/whyvalidationssuckin96/rails/active_record.rb
|
120
|
+
- lib/whyvalidationssuckin96/rails/active_record/association_validation.rb
|
121
|
+
- lib/whyvalidationssuckin96/rails/active_record/base_validation_overrides.rb
|
120
122
|
- lib/whyvalidationssuckin96/rails/macros.rb
|
121
123
|
- lib/whyvalidationssuckin96/rails/macros/validates_uniqueness.rb
|
122
124
|
- lib/whyvalidationssuckin96/skippable_validation.rb
|
@@ -134,8 +136,9 @@ files:
|
|
134
136
|
- test/macros/validates_numericality_test.rb
|
135
137
|
- test/macros/validates_presence_test.rb
|
136
138
|
- test/macros/validates_url_test.rb
|
137
|
-
- test/rails/active_record_test.rb
|
138
139
|
- test/rails/active_record_test_helper.rb
|
140
|
+
- test/rails/association_validation_test.rb
|
141
|
+
- test/rails/base_validation_overrides_test.rb
|
139
142
|
- test/rails/macros/validates_uniqueness_test.rb
|
140
143
|
- test/skippable_validation_test.rb
|
141
144
|
- test/teststrap.rb
|
@@ -183,8 +186,9 @@ test_files:
|
|
183
186
|
- test/macros/validates_numericality_test.rb
|
184
187
|
- test/macros/validates_presence_test.rb
|
185
188
|
- test/macros/validates_url_test.rb
|
186
|
-
- test/rails/active_record_test.rb
|
187
189
|
- test/rails/active_record_test_helper.rb
|
190
|
+
- test/rails/association_validation_test.rb
|
191
|
+
- test/rails/base_validation_overrides_test.rb
|
188
192
|
- test/rails/macros/validates_uniqueness_test.rb
|
189
193
|
- test/skippable_validation_test.rb
|
190
194
|
- test/teststrap.rb
|