whyvalidationssuckin96 1.0.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.
Files changed (88) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/LICENSE +20 -0
  4. data/README.md +121 -0
  5. data/Rakefile +45 -0
  6. data/VERSION +1 -0
  7. data/doc/ActiveRecord/RecordInvalid.html +258 -0
  8. data/doc/ActiveRecord.html +93 -0
  9. data/doc/FalseClass.html +87 -0
  10. data/doc/NilClass.html +87 -0
  11. data/doc/Numeric.html +87 -0
  12. data/doc/Object.html +79 -0
  13. data/doc/String.html +87 -0
  14. data/doc/TrueClass.html +87 -0
  15. data/doc/WhyValidationsSuckIn96/ActiveRecord/InstanceMethods.html +156 -0
  16. data/doc/WhyValidationsSuckIn96/ActiveRecord.html +192 -0
  17. data/doc/WhyValidationsSuckIn96/AttributeBasedValidation.html +464 -0
  18. data/doc/WhyValidationsSuckIn96/SkippableValidation.html +194 -0
  19. data/doc/WhyValidationsSuckIn96/ValidatesAcceptance.html +254 -0
  20. data/doc/WhyValidationsSuckIn96/ValidatesAssociated.html +250 -0
  21. data/doc/WhyValidationsSuckIn96/ValidatesConfirmation.html +251 -0
  22. data/doc/WhyValidationsSuckIn96/ValidatesExclusion.html +388 -0
  23. data/doc/WhyValidationsSuckIn96/ValidatesFormat.html +387 -0
  24. data/doc/WhyValidationsSuckIn96/ValidatesInclusion.html +388 -0
  25. data/doc/WhyValidationsSuckIn96/ValidatesLength.html +469 -0
  26. data/doc/WhyValidationsSuckIn96/ValidatesNumericality.html +267 -0
  27. data/doc/WhyValidationsSuckIn96/ValidatesPresence.html +244 -0
  28. data/doc/WhyValidationsSuckIn96/ValidatesUniqueness.html +289 -0
  29. data/doc/WhyValidationsSuckIn96/Validation.html +934 -0
  30. data/doc/WhyValidationsSuckIn96/ValidationBuilder.html +391 -0
  31. data/doc/WhyValidationsSuckIn96/ValidationSupport/ClassMethods.html +249 -0
  32. data/doc/WhyValidationsSuckIn96/ValidationSupport/InstanceMethods.html +484 -0
  33. data/doc/WhyValidationsSuckIn96/ValidationSupport.html +168 -0
  34. data/doc/WhyValidationsSuckIn96.html +97 -0
  35. data/doc/_index.html +346 -0
  36. data/doc/class_list.html +293 -0
  37. data/doc/css/common.css +1 -0
  38. data/doc/css/full_list.css +23 -0
  39. data/doc/css/style.css +263 -0
  40. data/doc/file.README.html +173 -0
  41. data/doc/file_list.html +29 -0
  42. data/doc/index.html +173 -0
  43. data/doc/js/app.js +91 -0
  44. data/doc/js/full_list.js +39 -0
  45. data/doc/js/jquery.js +19 -0
  46. data/doc/method_list.html +462 -0
  47. data/doc/top-level-namespace.html +81 -0
  48. data/lib/whyvalidationssuckin96/attribute_based_validation.rb +46 -0
  49. data/lib/whyvalidationssuckin96/constants.rb +3 -0
  50. data/lib/whyvalidationssuckin96/ext/blank.rb +47 -0
  51. data/lib/whyvalidationssuckin96/macros/validates_acceptance.rb +36 -0
  52. data/lib/whyvalidationssuckin96/macros/validates_associated.rb +33 -0
  53. data/lib/whyvalidationssuckin96/macros/validates_confirmation.rb +40 -0
  54. data/lib/whyvalidationssuckin96/macros/validates_exclusion.rb +38 -0
  55. data/lib/whyvalidationssuckin96/macros/validates_format.rb +38 -0
  56. data/lib/whyvalidationssuckin96/macros/validates_inclusion.rb +38 -0
  57. data/lib/whyvalidationssuckin96/macros/validates_length.rb +98 -0
  58. data/lib/whyvalidationssuckin96/macros/validates_numericality.rb +56 -0
  59. data/lib/whyvalidationssuckin96/macros/validates_presence.rb +30 -0
  60. data/lib/whyvalidationssuckin96/macros.rb +9 -0
  61. data/lib/whyvalidationssuckin96/rails/active_record.rb +94 -0
  62. data/lib/whyvalidationssuckin96/rails/macros/validates_uniqueness.rb +87 -0
  63. data/lib/whyvalidationssuckin96/rails/macros.rb +1 -0
  64. data/lib/whyvalidationssuckin96/skippable_validation.rb +59 -0
  65. data/lib/whyvalidationssuckin96/validation.rb +88 -0
  66. data/lib/whyvalidationssuckin96/validation_builder.rb +56 -0
  67. data/lib/whyvalidationssuckin96/validation_support.rb +74 -0
  68. data/lib/whyvalidationssuckin96.rb +4 -0
  69. data/test/attribute_based_validation_test.rb +58 -0
  70. data/test/macros/validates_acceptance_test.rb +64 -0
  71. data/test/macros/validates_associated_test.rb +60 -0
  72. data/test/macros/validates_confirmation_test.rb +63 -0
  73. data/test/macros/validates_exclusion_test.rb +37 -0
  74. data/test/macros/validates_format_test.rb +43 -0
  75. data/test/macros/validates_inclusion_test.rb +37 -0
  76. data/test/macros/validates_length_test.rb +179 -0
  77. data/test/macros/validates_numericality_test.rb +129 -0
  78. data/test/macros/validates_presence_test.rb +31 -0
  79. data/test/rails/active_record_test.rb +187 -0
  80. data/test/rails/active_record_test_helper.rb +90 -0
  81. data/test/rails/macros/validates_uniqueness_test.rb +153 -0
  82. data/test/skippable_validation_test.rb +102 -0
  83. data/test/teststrap.rb +4 -0
  84. data/test/validation_builder_test.rb +62 -0
  85. data/test/validation_support_test.rb +209 -0
  86. data/test/validation_test.rb +101 -0
  87. data/whyvalidationssuckin96.gemspec +153 -0
  88. metadata +189 -0
@@ -0,0 +1,187 @@
1
+ require 'teststrap'
2
+ require 'rails/active_record_test_helper'
3
+
4
+ context "active record integration" do
5
+
6
+ should "automatically be mixed into the records of the active variety" do
7
+ ActiveRecord::Base
8
+ end.respond_to(:validation_collection)
9
+
10
+ context "given an example class, 'VisualWork'" do
11
+ setup { VisualWork }
12
+
13
+ should "not save when invalid?" do
14
+ inst = topic.new
15
+ inst.save
16
+ inst.new_record?
17
+ end
18
+
19
+ should "save when valid" do
20
+ inst = topic.new(:name => "test")
21
+ inst.save
22
+ !inst.new_record?
23
+ end
24
+
25
+ should "raise the expected exception when invalid and using save!" do
26
+ inst = topic.new
27
+ inst.save!
28
+ end.raises(ActiveRecord::RecordInvalid)
29
+
30
+ should "raise the expected exception when invalid and using create!" do
31
+ topic.create!
32
+ end.raises(ActiveRecord::RecordInvalid)
33
+
34
+ end # given an example class, 'VisualWork'
35
+
36
+ context "given an example class, 'MusicalWork'" do
37
+ setup { MusicalWork }
38
+
39
+ should "have four validations in the collection" do
40
+ topic.validation_collection.size
41
+ end.equals(4)
42
+
43
+ context "an instance testing basic validation functionality" do
44
+ setup { topic.new }
45
+
46
+ should "have three passes when the 'state' attribute is nil" do
47
+ topic.state = nil
48
+ topic.valid?
49
+ topic.passed_validations.size
50
+ end.equals(3)
51
+
52
+ should "have one fail when the 'state' attribute is :fail" do
53
+ topic.state = :fail
54
+ topic.valid?
55
+ topic.failed_validations.size
56
+ end.equals(1)
57
+
58
+ should "have two passes when the 'state' attribute is :fail" do
59
+ topic.state = :fail
60
+ topic.valid?
61
+ topic.passed_validations.size
62
+ end.equals(2)
63
+
64
+ should "not be allowed to be saved in an invalid state" do
65
+ topic.state = :fail
66
+ topic.save
67
+ end.equals(false)
68
+
69
+ should "not respond to the 'errors' method" do
70
+ topic.respond_to?(:errors)
71
+ end.equals(false)
72
+
73
+ end # an instance testing basic validation functionality
74
+
75
+ context "an instance testing validation :on specification" do
76
+ context "on create" do
77
+ setup do
78
+ instance = topic.new
79
+ instance.save
80
+ instance.validations_run
81
+ end
82
+
83
+ should "not have run the validation specified for :update" do
84
+ topic.include?(:validation_that_runs_on_update)
85
+ end.equals(false)
86
+
87
+ should "have run the validation specified for :create" do
88
+ topic
89
+ end.includes(:validation_that_runs_on_create)
90
+ end # on create
91
+
92
+ context "on update" do
93
+ setup do
94
+ instance = topic.new
95
+ instance.save
96
+ raise "Whoa there. Topic needs to be a saved record." if instance.new_record?
97
+ instance.validations_run.clear
98
+ instance.save
99
+ instance.validations_run
100
+ end
101
+
102
+ should "have run the validation specified for :update" do
103
+ topic
104
+ end.includes(:validation_that_runs_on_update)
105
+
106
+ should "not have run the validation specified for :create" do
107
+ topic.include?(:validation_that_runs_on_create)
108
+ end.equals(false)
109
+ end # on update
110
+ end # an instance testing validation :on specification
111
+
112
+ context "an instance testing callback functionality" do
113
+
114
+ context "on create" do
115
+ setup do
116
+ instance = topic.new
117
+ instance.state = :fail
118
+ instance.save
119
+ instance.callbacks_run
120
+ end
121
+
122
+ should "have run the before_validation callback" do
123
+ topic
124
+ end.includes(:before_validation)
125
+
126
+ should "have run the before_validation_on_create callback" do
127
+ topic
128
+ end.includes(:before_validation_on_create)
129
+
130
+ should "not have run the before_validation_on_update callback" do
131
+ topic.include?(:before_validation_on_update)
132
+ end.equals(false)
133
+
134
+ should "have run the after_validation callback" do
135
+ topic
136
+ end.includes(:after_validation)
137
+
138
+ should "have run the after_validation_on_create callback" do
139
+ topic
140
+ end.includes(:after_validation_on_create)
141
+
142
+ should "not have run the after_validation_on_update callback" do
143
+ topic.include?(:after_validation_on_update)
144
+ end.equals(false)
145
+
146
+ end # on create
147
+
148
+ context "on update" do
149
+ setup do
150
+ instance = topic.new
151
+ instance.state = nil
152
+ instance.save
153
+ raise "Whoa there. Topic needs to be a saved record." if instance.new_record?
154
+ instance.callbacks_run.clear
155
+ instance.save
156
+ instance.callbacks_run
157
+ end
158
+
159
+ should "have run the before_validation callback" do
160
+ topic
161
+ end.includes(:before_validation)
162
+
163
+ should "not have run the before_validation_on_create callback" do
164
+ topic.include?(:before_validation_on_create)
165
+ end.equals(false)
166
+
167
+ should "not have run the before_validation_on_update callback" do
168
+ topic
169
+ end.includes(:before_validation_on_update)
170
+
171
+ should "have run the after_validation callback" do
172
+ topic
173
+ end.includes(:after_validation)
174
+
175
+ should "have run the after_validation_on_create callback" do
176
+ topic.include?(:after_validation_on_create)
177
+ end.equals(false)
178
+
179
+ should "not have run the after_validation_on_update callback" do
180
+ topic
181
+ end.includes(:after_validation_on_update)
182
+
183
+ end # on create
184
+
185
+ end # an instance testing callback functionality
186
+ end # given an example class, 'MusicalWork'
187
+ end # active record integration
@@ -0,0 +1,90 @@
1
+ require 'whyvalidationssuckin96/rails/active_record'
2
+
3
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
4
+ ActiveRecord::Schema.define(:version => 1) do
5
+ create_table :musical_works do |t|
6
+ t.string :name
7
+ end
8
+
9
+ create_table :visual_works do |t|
10
+ t.string :name
11
+ t.string :author
12
+ t.string :type
13
+ end
14
+ end
15
+
16
+ class MusicalWork < ActiveRecord::Base
17
+ attr_accessor :state, :callbacks_run, :validations_run
18
+
19
+ def after_initialize
20
+ @callbacks_run = []
21
+ @validations_run = []
22
+ end
23
+
24
+ setup_validations do
25
+ validate :something_that_passes do
26
+ pass if validatable.state == :pass
27
+ end
28
+
29
+ validate :something_that_fails do
30
+ fail if validatable.state == :fail
31
+ end
32
+
33
+ validate :validation_that_runs_on_update, :on => :update do
34
+ validatable.validations_run << :validation_that_runs_on_update
35
+ end
36
+
37
+ validate :validation_that_runs_on_create, :on => :create do
38
+ validatable.validations_run << :validation_that_runs_on_create
39
+ end
40
+ end
41
+
42
+ def before_validation_on_update
43
+ callbacks_run << :before_validation_on_update
44
+ end
45
+
46
+ def before_validation
47
+ callbacks_run << :before_validation
48
+ end
49
+
50
+ def before_validation_on_create
51
+ callbacks_run << :before_validation_on_create
52
+ end
53
+
54
+ def after_validation_on_update
55
+ callbacks_run << :after_validation_on_update
56
+ end
57
+
58
+ def after_validation
59
+ callbacks_run << :after_validation
60
+ end
61
+
62
+ def after_validation_on_create
63
+ callbacks_run << :after_validation_on_create
64
+ end
65
+
66
+ end
67
+
68
+ class VisualWork < ActiveRecord::Base
69
+ setup_validations do
70
+ validates_presence_of :name
71
+ end
72
+ end
73
+
74
+ class Photograph < VisualWork
75
+ setup_validations do
76
+ validates_uniqueness_of :author, :base_class_scope => false
77
+ end
78
+ end
79
+
80
+ class Painting < VisualWork
81
+ setup_validations do
82
+ validates_uniqueness_of :author, :base_class_scope => true
83
+ end
84
+ end
85
+
86
+ class Collage < VisualWork
87
+ setup_validations do
88
+ validates_uniqueness_of :name, :scope => :author
89
+ end
90
+ end
@@ -0,0 +1,153 @@
1
+ require 'teststrap'
2
+ require 'rails/active_record_test_helper'
3
+
4
+ context "validates uniqueness" do
5
+
6
+ should "add a validation macro" do
7
+ WhyValidationsSuckIn96::ValidationBuilder.instance_methods
8
+ end.includes('validates_uniqueness_of')
9
+
10
+ context "with some default options" do
11
+ setup do
12
+ WhyValidationsSuckIn96::ValidatesUniqueness.new(Object.new, :attribute => :username)
13
+ end
14
+
15
+ should "have a message accessor with a default message" do
16
+ topic.message
17
+ end.equals("has already been taken")
18
+
19
+ should "default to being case insensitive" do
20
+ topic.options[:case_sensitive]
21
+ end.equals(false)
22
+
23
+ should "default :base_class_scope to true" do
24
+ topic.options[:base_class_scope]
25
+ end.equals(true)
26
+ end # with some default options
27
+
28
+ context "validating an object" do
29
+
30
+ context "with default options" do
31
+ setup do
32
+ Class.new(VisualWork) do
33
+ setup_validations do
34
+ validates_uniqueness_of :name
35
+ end
36
+ end # VisualWork
37
+ end # setup do
38
+
39
+ should "mark the second object with the same name as invalid" do
40
+ work = topic.new(:name => "example")
41
+ work.save!
42
+ other_work = topic.new(:name => "example")
43
+ !other_work.valid? && other_work.failed_validations.detect do |fv|
44
+ fv.kind_of?(WhyValidationsSuckIn96::ValidatesUniqueness) && fv.attribute == :name
45
+ end
46
+ end
47
+
48
+ should "allow two objects with different names" do
49
+ work = topic.new(:name => "example one")
50
+ work.save!
51
+ other = topic.new(:name => "example two")
52
+ other.valid?
53
+ end
54
+
55
+ should "not care about case sensitivity by default" do
56
+ work = topic.new(:name => "cAsE SeNsItiViTy")
57
+ work.save!
58
+ other_work = topic.new(:name => "case sensitivity")
59
+ !other_work.valid? && other_work.failed_validations.detect do |fv|
60
+ fv.kind_of?(WhyValidationsSuckIn96::ValidatesUniqueness) && fv.attribute == :name
61
+ end
62
+ end
63
+
64
+ should "allow the one object to be saved twice and not violate the constraint" do
65
+ work = topic.new(:name => "screenshot")
66
+ work.save
67
+ work.author = "gabe"
68
+ work.save
69
+ end
70
+ end # with default options
71
+
72
+ context "specifying case sensitivity" do
73
+ setup do
74
+ Class.new(VisualWork) do
75
+ setup_validations do
76
+ validates_uniqueness_of :name, :case_sensitive => true
77
+ end
78
+ end # VisualWork
79
+ end # setup do
80
+
81
+ should "allow objects with the same name and different case to be valid" do
82
+ work = topic.create!(:name => "CASE SENSITIVE IS TRUE")
83
+ other_work = topic.new(:name => "case sensitive is true")
84
+ other_work.valid?
85
+ end
86
+
87
+ should "mark the second object with the name in the same case as invalid" do
88
+ work = topic.create(:name => "SO WHAT")
89
+ other_work = topic.new(:name => "SO WHAT")
90
+ !other_work.valid? && other_work.failed_validations.detect do |fv|
91
+ fv.kind_of?(WhyValidationsSuckIn96::ValidatesUniqueness) && fv.attribute == :name
92
+ end
93
+ end
94
+ end # specifying case sensitivity
95
+
96
+ context "specifying base class scope" do
97
+ context "as false" do
98
+ should "allow records to be created in different subclasses that violate the uniqueness" do
99
+ Painting.create!(:name => "painting one", :author => "humbug")
100
+ Photograph.new(:name => "photo one", :author => "humbug").valid?
101
+ end
102
+
103
+ should "not allow records to be created in the same class that violate the uniqueness" do
104
+ Photograph.create!(:name => "photo one", :author => "gus")
105
+ photo = Photograph.new(:name => "photo two", :author => "gus")
106
+ !photo.valid? && photo.failed_validations.detect do |fv|
107
+ fv.kind_of?(WhyValidationsSuckIn96::ValidatesUniqueness) && fv.attribute == :author
108
+ end
109
+ end
110
+ end # as false
111
+
112
+ context "as true" do
113
+ should "not allow records to be created that violate a uniqueness constraint based on the base class" do
114
+ VisualWork.create!(:name => "mspaint", :author => "dan")
115
+ work = Painting.new(:name => "the treachery of images", :author => "dan")
116
+ !work.valid? && work.failed_validations.detect do |fv|
117
+ fv.kind_of?(WhyValidationsSuckIn96::ValidatesUniqueness) && fv.attribute == :author
118
+ end
119
+ end
120
+
121
+ should "allow records to be created that don't violate the uniqueness constraint" do
122
+ VisualWork.create!(:name => "photoshop", :author => "alex")
123
+ Painting.create!(:name => "paintshop", :author => "evan")
124
+ end
125
+ end # as true
126
+ end # specifying base class scope
127
+
128
+ context "specifying scope options" do
129
+ should "pass when uniqueness is valid against the given scope column" do
130
+ Collage.create!(:name => "wired snippets", :author => "dan")
131
+ work = Collage.new(:name => "wired snippets", :author => "gabe")
132
+ work.valid?
133
+ end
134
+
135
+ should "fail when uniqueness is invalid against the given scope column" do
136
+ Collage.create!(:name => "rolling stone snippets", :author => "gabe")
137
+ work = Collage.new(:name => "rolling stone snippets", :author => "gabe")
138
+ !work.valid? && work.failed_validations.detect do |fv|
139
+ fv.kind_of?(WhyValidationsSuckIn96::ValidatesUniqueness) && fv.attribute == :name
140
+ end
141
+ end
142
+ end # specifying scope options
143
+
144
+ context "when using with_scope" do
145
+ should "basically just ignore with_scope" do
146
+ Painting.create!(:author => "fred", :name => "bbzzzt")
147
+ Painting.send(:with_scope, :find => {:conditions => {:author => "fred"}}) do
148
+ Painting.create!(:author => "myles", :name => "bitchesbrew")
149
+ end
150
+ end
151
+ end # when using with_scope
152
+ end # validating an object
153
+ end # validates uniqueness
@@ -0,0 +1,102 @@
1
+ require 'teststrap'
2
+ require 'whyvalidationssuckin96/skippable_validation'
3
+
4
+ context "skippable validation mixin" do
5
+ context "when mixed into a class" do
6
+
7
+ setup do
8
+ Class.new(WhyValidationsSuckIn96::Validation) do
9
+ include WhyValidationsSuckIn96::SkippableValidation
10
+ attr_accessor :skip_validation
11
+
12
+ def validate
13
+ super
14
+ options[:should_pass] ? pass : fail
15
+ end
16
+ end # Class.new
17
+ end # setup
18
+
19
+ context "when specifying an :if option" do
20
+ context "as a block" do
21
+
22
+ setup do
23
+ topic.new(Object.new, :if => lambda { !skip_validation })
24
+ end
25
+
26
+ should "not have run if the block returns false" do
27
+ topic.skip_validation = true
28
+ topic.validates?
29
+ topic.has_run?
30
+ end.equals(false)
31
+
32
+ should "have run if the block returns true" do
33
+ topic.skip_validation = false
34
+ topic.validates?
35
+ topic.has_run?
36
+ end
37
+ end # as a block
38
+
39
+ context "as a symbol" do
40
+ validatable = nil
41
+
42
+ setup do
43
+ validatable = OpenStruct.new(:allow_validation => true)
44
+ topic.new(validatable, :if => :allow_validation)
45
+ end
46
+
47
+ should "not have run if the method named by the symbol returns false" do
48
+ validatable.allow_validation = false
49
+ topic.validates?
50
+ topic.has_run?
51
+ end.equals(false)
52
+
53
+ should "have run if the method named by the symbol returns true" do
54
+ validatable.allow_validation = true
55
+ topic.validates?
56
+ topic.has_run?
57
+ end
58
+ end # as a symbol
59
+ end # when specifying an :if option
60
+
61
+ context "when specifying an :unless option" do
62
+ context "as a block" do
63
+ setup do
64
+ topic.new(Object.new, :unless => lambda { skip_validation })
65
+ end
66
+
67
+ should "have run if the block returns false" do
68
+ topic.skip_validation = false
69
+ topic.validates?
70
+ topic.has_run?
71
+ end
72
+
73
+ should "not have run if the block returns true" do
74
+ topic.skip_validation = true
75
+ topic.validates?
76
+ topic.has_run?
77
+ end.equals(false)
78
+ end # as a block
79
+
80
+ context "as a symbol" do
81
+ validatable = nil
82
+
83
+ setup do
84
+ validatable = OpenStruct.new(:skip_validation => true)
85
+ topic.new(validatable, :unless => :skip_validation)
86
+ end
87
+
88
+ should "have run if the method named by the symbol returns false" do
89
+ validatable.skip_validation = false
90
+ topic.validates?
91
+ topic.has_run?
92
+ end
93
+
94
+ should "not have run if the method named by the symbol returns true" do
95
+ validatable.skip_validation = true
96
+ topic.validates?
97
+ topic.has_run?
98
+ end.equals(false)
99
+ end # as a symbol
100
+ end # when specifying an :unless option
101
+ end # when mixed into a class
102
+ end # skippable validation mixin
data/test/teststrap.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'riot'
3
+ require 'whyvalidationssuckin96'
4
+ require 'ostruct'
@@ -0,0 +1,62 @@
1
+ require 'teststrap'
2
+ require 'ostruct'
3
+
4
+ context "validation builder" do
5
+ context "when defining some standard validations" do
6
+ setup do
7
+ fake_validation_target = OpenStruct.new(:validation_collection => [])
8
+ validation_block = lambda do
9
+ validate(:validates_whatever) {}
10
+ validate(:validates_whenever) {}
11
+ end
12
+ WhyValidationsSuckIn96::ValidationBuilder.new(fake_validation_target, validation_block).create_validations!
13
+ fake_validation_target
14
+ end
15
+
16
+ should "have a validates_whatever validation in the collection" do
17
+ topic.validation_collection.detect { |(validation, opts)| validation.name == :validates_whatever }
18
+ end
19
+
20
+ should "have a validates_whenever validation in the collection" do
21
+ topic.validation_collection.detect { |(validation, opts)| validation.name == :validates_whenever }
22
+ end
23
+
24
+ should "have Validation subclasses as the values for the validation_collection" do
25
+ topic.validation_collection.all? {|(klass,opts)| klass.ancestors.include?(WhyValidationsSuckIn96::Validation)}
26
+ end
27
+ end # when defining some standard validations
28
+
29
+ context "when defining multiple validations with the same name in the one validation definition" do
30
+ setup do
31
+ fake_validation_target = OpenStruct.new(:validation_collection => [])
32
+ validation_block = lambda do
33
+ validate(:we_are_clones) {}
34
+ validate(:we_are_clones) {}
35
+ end # validation_block
36
+ WhyValidationsSuckIn96::ValidationBuilder.new(fake_validation_target, validation_block).create_validations!
37
+ fake_validation_target
38
+ end
39
+
40
+ should "only have one validation in the collection on the target" do
41
+ topic.validation_collection.size
42
+ end.equals(1)
43
+
44
+ end # when defining multiple validations with the same name in the one validation definition
45
+
46
+ context "when defining multiple validations with the same name in more than one validation definition" do
47
+ setup do
48
+ fake_validation_target = OpenStruct.new(:validation_collection => [])
49
+ validation_block = lambda do
50
+ validate(:we_are_clones) {}
51
+ end # validation_block
52
+ WhyValidationsSuckIn96::ValidationBuilder.new(fake_validation_target, validation_block).create_validations!
53
+ WhyValidationsSuckIn96::ValidationBuilder.new(fake_validation_target, validation_block).create_validations!
54
+ fake_validation_target
55
+ end
56
+
57
+ should "only have one validation in the collection on the target" do
58
+ topic.validation_collection.size
59
+ end.equals(1)
60
+
61
+ end # when defining multiple validations with the same name in the one validation definition
62
+ end # validation builder