whyvalidationssuckin96 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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