aequitas 0.0.1

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 (216) hide show
  1. data/.gitignore +4 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +6 -0
  4. data/LICENSE +21 -0
  5. data/README.rdoc +125 -0
  6. data/Rakefile +25 -0
  7. data/VERSION +1 -0
  8. data/aequitas.gemspec +20 -0
  9. data/lib/aequitas.rb +80 -0
  10. data/lib/aequitas/class_methods.rb +26 -0
  11. data/lib/aequitas/context.rb +53 -0
  12. data/lib/aequitas/contextual_rule_set.rb +221 -0
  13. data/lib/aequitas/exceptions.rb +10 -0
  14. data/lib/aequitas/macros.rb +466 -0
  15. data/lib/aequitas/message_transformer.rb +127 -0
  16. data/lib/aequitas/rule.rb +153 -0
  17. data/lib/aequitas/rule/absence.rb +14 -0
  18. data/lib/aequitas/rule/absence/blank.rb +21 -0
  19. data/lib/aequitas/rule/absence/nil.rb +21 -0
  20. data/lib/aequitas/rule/acceptance.rb +36 -0
  21. data/lib/aequitas/rule/block.rb +33 -0
  22. data/lib/aequitas/rule/confirmation.rb +41 -0
  23. data/lib/aequitas/rule/format.rb +81 -0
  24. data/lib/aequitas/rule/format/proc.rb +28 -0
  25. data/lib/aequitas/rule/format/regexp.rb +44 -0
  26. data/lib/aequitas/rule/formats/email.rb +52 -0
  27. data/lib/aequitas/rule/formats/url.rb +14 -0
  28. data/lib/aequitas/rule/guard.rb +51 -0
  29. data/lib/aequitas/rule/length.rb +87 -0
  30. data/lib/aequitas/rule/length/equal.rb +46 -0
  31. data/lib/aequitas/rule/length/maximum.rb +46 -0
  32. data/lib/aequitas/rule/length/minimum.rb +46 -0
  33. data/lib/aequitas/rule/length/range.rb +46 -0
  34. data/lib/aequitas/rule/method.rb +31 -0
  35. data/lib/aequitas/rule/numericalness.rb +85 -0
  36. data/lib/aequitas/rule/numericalness/equal.rb +30 -0
  37. data/lib/aequitas/rule/numericalness/greater_than.rb +30 -0
  38. data/lib/aequitas/rule/numericalness/greater_than_or_equal.rb +30 -0
  39. data/lib/aequitas/rule/numericalness/integer.rb +37 -0
  40. data/lib/aequitas/rule/numericalness/less_than.rb +30 -0
  41. data/lib/aequitas/rule/numericalness/less_than_or_equal.rb +30 -0
  42. data/lib/aequitas/rule/numericalness/non_integer.rb +64 -0
  43. data/lib/aequitas/rule/numericalness/not_equal.rb +30 -0
  44. data/lib/aequitas/rule/presence.rb +14 -0
  45. data/lib/aequitas/rule/presence/not_blank.rb +21 -0
  46. data/lib/aequitas/rule/presence/not_nil.rb +21 -0
  47. data/lib/aequitas/rule/primitive_type.rb +28 -0
  48. data/lib/aequitas/rule/skip_condition.rb +104 -0
  49. data/lib/aequitas/rule/within.rb +28 -0
  50. data/lib/aequitas/rule/within/range.rb +53 -0
  51. data/lib/aequitas/rule/within/range/bounded.rb +25 -0
  52. data/lib/aequitas/rule/within/range/unbounded_begin.rb +25 -0
  53. data/lib/aequitas/rule/within/range/unbounded_end.rb +25 -0
  54. data/lib/aequitas/rule/within/set.rb +39 -0
  55. data/lib/aequitas/rule_set.rb +80 -0
  56. data/lib/aequitas/support/blank.rb +22 -0
  57. data/lib/aequitas/support/equalizable.rb +113 -0
  58. data/lib/aequitas/support/ordered_hash.rb +438 -0
  59. data/lib/aequitas/version.rb +5 -0
  60. data/lib/aequitas/violation.rb +116 -0
  61. data/lib/aequitas/violation_set.rb +123 -0
  62. data/lib/aequitas/virtus.rb +29 -0
  63. data/lib/aequitas/virtus/inline_attribute_rule_extractor.rb +41 -0
  64. data/lib/aequitas/virtus/inline_attribute_rule_extractor/boolean.rb +17 -0
  65. data/lib/aequitas/virtus/inline_attribute_rule_extractor/object.rb +25 -0
  66. data/lib/aequitas/virtus/inline_attribute_rule_extractor/string.rb +27 -0
  67. data/spec/integration/aequitas/macros/validates_absence_of_spec.rb +19 -0
  68. data/spec/integration/aequitas/macros/validates_acceptance_of_spec.rb +19 -0
  69. data/spec/integration/aequitas/macros/validates_confirmation_of_spec.rb +25 -0
  70. data/spec/integration/aequitas/macros/validates_format_of_spec.rb +87 -0
  71. data/spec/integration/aequitas/macros/validates_length_of.rb +77 -0
  72. data/spec/integration/aequitas/macros/validates_numericalness_of_spec.rb +221 -0
  73. data/spec/integration/aequitas/macros/validates_presence_of_spec.rb +19 -0
  74. data/spec/integration/aequitas/macros/validates_with_block.rb +23 -0
  75. data/spec/integration/aequitas/macros/validates_with_method.rb +19 -0
  76. data/spec/integration/aequitas/macros/validates_within.rb +87 -0
  77. data/spec/integration/shared/macros/integration_spec.rb +67 -0
  78. data/spec/integration/virtus/boolean/presence_spec.rb +49 -0
  79. data/spec/integration/virtus/string/format/email_address_spec.rb +55 -0
  80. data/spec/integration/virtus/string/format/regexp_spec.rb +55 -0
  81. data/spec/integration/virtus/string/format/url_spec.rb +55 -0
  82. data/spec/integration/virtus/string/length/equal_spec.rb +49 -0
  83. data/spec/integration/virtus/string/length/range_spec.rb +49 -0
  84. data/spec/integration/virtus/string/presence_spec.rb +49 -0
  85. data/spec/rcov.opts +6 -0
  86. data/spec/spec_helper.rb +5 -0
  87. data/spec/suite.rb +5 -0
  88. data/spec/unit/aequitas/rule/absence/blank_spec.rb +45 -0
  89. data/spec/unit/aequitas/rule/acceptance_spec.rb +71 -0
  90. data/spec/unit/aequitas/rule/confirmation_spec.rb +80 -0
  91. data/spec/unit/aequitas/rule/guard_spec.rb +120 -0
  92. data/spec/unit/aequitas/rule/skip_condition_spec.rb +170 -0
  93. data/spec/unit/aequitas/rule_spec.rb +40 -0
  94. data/spec/unit/aequitas/support/blank_spec.rb +83 -0
  95. data/spec/unit/aequitas/support/equalizable/equalizer_spec.rb +21 -0
  96. data/spec/unit/aequitas/support/equalizable_spec.rb +67 -0
  97. data/spec/unit/aequitas/violation_set_spec.rb +154 -0
  98. data/spec_legacy/fixtures/barcode.rb +40 -0
  99. data/spec_legacy/fixtures/basketball_court.rb +58 -0
  100. data/spec_legacy/fixtures/basketball_player.rb +34 -0
  101. data/spec_legacy/fixtures/beta_tester_account.rb +33 -0
  102. data/spec_legacy/fixtures/bill_of_landing.rb +47 -0
  103. data/spec_legacy/fixtures/boat_dock.rb +26 -0
  104. data/spec_legacy/fixtures/city.rb +24 -0
  105. data/spec_legacy/fixtures/company.rb +93 -0
  106. data/spec_legacy/fixtures/corporate_world.rb +39 -0
  107. data/spec_legacy/fixtures/country.rb +24 -0
  108. data/spec_legacy/fixtures/ethernet_frame.rb +56 -0
  109. data/spec_legacy/fixtures/event.rb +44 -0
  110. data/spec_legacy/fixtures/g3_concert.rb +57 -0
  111. data/spec_legacy/fixtures/jabberwock.rb +27 -0
  112. data/spec_legacy/fixtures/kayak.rb +28 -0
  113. data/spec_legacy/fixtures/lernean_hydra.rb +39 -0
  114. data/spec_legacy/fixtures/llama_spaceship.rb +15 -0
  115. data/spec_legacy/fixtures/mathematical_function.rb +34 -0
  116. data/spec_legacy/fixtures/memory_object.rb +30 -0
  117. data/spec_legacy/fixtures/mittelschnauzer.rb +39 -0
  118. data/spec_legacy/fixtures/motor_launch.rb +21 -0
  119. data/spec_legacy/fixtures/multibyte.rb +16 -0
  120. data/spec_legacy/fixtures/page.rb +32 -0
  121. data/spec_legacy/fixtures/phone_number.rb +28 -0
  122. data/spec_legacy/fixtures/pirogue.rb +28 -0
  123. data/spec_legacy/fixtures/programming_language.rb +83 -0
  124. data/spec_legacy/fixtures/reservation.rb +38 -0
  125. data/spec_legacy/fixtures/scm_operation.rb +56 -0
  126. data/spec_legacy/fixtures/sms_message.rb +22 -0
  127. data/spec_legacy/fixtures/udp_packet.rb +49 -0
  128. data/spec_legacy/integration/absent_field_validator/absent_field_validator_spec.rb +90 -0
  129. data/spec_legacy/integration/absent_field_validator/spec_helper.rb +7 -0
  130. data/spec_legacy/integration/acceptance_validator/acceptance_validator_spec.rb +196 -0
  131. data/spec_legacy/integration/acceptance_validator/spec_helper.rb +7 -0
  132. data/spec_legacy/integration/automatic_validation/custom_messages_for_inferred_validation_spec.rb +57 -0
  133. data/spec_legacy/integration/automatic_validation/disabling_inferred_validation_spec.rb +49 -0
  134. data/spec_legacy/integration/automatic_validation/inferred_boolean_properties_validation_spec.rb +100 -0
  135. data/spec_legacy/integration/automatic_validation/inferred_float_property_validation_spec.rb +45 -0
  136. data/spec_legacy/integration/automatic_validation/inferred_format_validation_spec.rb +35 -0
  137. data/spec_legacy/integration/automatic_validation/inferred_integer_properties_validation_spec.rb +70 -0
  138. data/spec_legacy/integration/automatic_validation/inferred_length_validation_spec.rb +142 -0
  139. data/spec_legacy/integration/automatic_validation/inferred_presence_validation_spec.rb +45 -0
  140. data/spec_legacy/integration/automatic_validation/inferred_primitive_validation_spec.rb +22 -0
  141. data/spec_legacy/integration/automatic_validation/inferred_uniqueness_validation_spec.rb +48 -0
  142. data/spec_legacy/integration/automatic_validation/inferred_within_validation_spec.rb +35 -0
  143. data/spec_legacy/integration/automatic_validation/spec_helper.rb +57 -0
  144. data/spec_legacy/integration/block_validator/block_validator_spec.rb +32 -0
  145. data/spec_legacy/integration/block_validator/spec_helper.rb +5 -0
  146. data/spec_legacy/integration/conditional_validation/if_condition_spec.rb +63 -0
  147. data/spec_legacy/integration/conditional_validation/spec_helper.rb +5 -0
  148. data/spec_legacy/integration/confirmation_validator/confirmation_validator_spec.rb +76 -0
  149. data/spec_legacy/integration/confirmation_validator/spec_helper.rb +5 -0
  150. data/spec_legacy/integration/datamapper_models/association_validation_spec.rb +29 -0
  151. data/spec_legacy/integration/datamapper_models/inheritance_spec.rb +82 -0
  152. data/spec_legacy/integration/dirty_attributes/dirty_attributes_spec.rb +13 -0
  153. data/spec_legacy/integration/duplicated_validations/duplicated_validations_spec.rb +24 -0
  154. data/spec_legacy/integration/duplicated_validations/spec_helper.rb +5 -0
  155. data/spec_legacy/integration/format_validator/email_format_validator_spec.rb +139 -0
  156. data/spec_legacy/integration/format_validator/format_validator_spec.rb +64 -0
  157. data/spec_legacy/integration/format_validator/regexp_validator_spec.rb +33 -0
  158. data/spec_legacy/integration/format_validator/spec_helper.rb +5 -0
  159. data/spec_legacy/integration/format_validator/url_format_validator_spec.rb +93 -0
  160. data/spec_legacy/integration/length_validator/default_value_spec.rb +14 -0
  161. data/spec_legacy/integration/length_validator/equality_spec.rb +87 -0
  162. data/spec_legacy/integration/length_validator/error_message_spec.rb +22 -0
  163. data/spec_legacy/integration/length_validator/maximum_spec.rb +49 -0
  164. data/spec_legacy/integration/length_validator/minimum_spec.rb +54 -0
  165. data/spec_legacy/integration/length_validator/range_spec.rb +87 -0
  166. data/spec_legacy/integration/length_validator/spec_helper.rb +7 -0
  167. data/spec_legacy/integration/method_validator/method_validator_spec.rb +242 -0
  168. data/spec_legacy/integration/method_validator/spec_helper.rb +5 -0
  169. data/spec_legacy/integration/numeric_validator/equality_with_float_type_spec.rb +65 -0
  170. data/spec_legacy/integration/numeric_validator/equality_with_integer_type_spec.rb +41 -0
  171. data/spec_legacy/integration/numeric_validator/float_type_spec.rb +90 -0
  172. data/spec_legacy/integration/numeric_validator/gt_with_float_type_spec.rb +37 -0
  173. data/spec_legacy/integration/numeric_validator/gte_with_float_type_spec.rb +37 -0
  174. data/spec_legacy/integration/numeric_validator/integer_only_true_spec.rb +91 -0
  175. data/spec_legacy/integration/numeric_validator/integer_type_spec.rb +86 -0
  176. data/spec_legacy/integration/numeric_validator/lt_with_float_type_spec.rb +37 -0
  177. data/spec_legacy/integration/numeric_validator/lte_with_float_type_spec.rb +37 -0
  178. data/spec_legacy/integration/numeric_validator/spec_helper.rb +5 -0
  179. data/spec_legacy/integration/primitive_validator/primitive_validator_spec.rb +92 -0
  180. data/spec_legacy/integration/primitive_validator/spec_helper.rb +5 -0
  181. data/spec_legacy/integration/pure_ruby_objects/plain_old_ruby_object_validation_spec.rb +118 -0
  182. data/spec_legacy/integration/required_field_validator/association_spec.rb +69 -0
  183. data/spec_legacy/integration/required_field_validator/boolean_type_value_spec.rb +164 -0
  184. data/spec_legacy/integration/required_field_validator/date_type_value_spec.rb +127 -0
  185. data/spec_legacy/integration/required_field_validator/datetime_type_value_spec.rb +127 -0
  186. data/spec_legacy/integration/required_field_validator/float_type_value_spec.rb +131 -0
  187. data/spec_legacy/integration/required_field_validator/integer_type_value_spec.rb +99 -0
  188. data/spec_legacy/integration/required_field_validator/plain_old_ruby_object_spec.rb +35 -0
  189. data/spec_legacy/integration/required_field_validator/shared_examples.rb +26 -0
  190. data/spec_legacy/integration/required_field_validator/spec_helper.rb +7 -0
  191. data/spec_legacy/integration/required_field_validator/string_type_value_spec.rb +167 -0
  192. data/spec_legacy/integration/required_field_validator/text_type_value_spec.rb +49 -0
  193. data/spec_legacy/integration/shared/default_validation_context.rb +13 -0
  194. data/spec_legacy/integration/shared/valid_and_invalid_model.rb +35 -0
  195. data/spec_legacy/integration/uniqueness_validator/spec_helper.rb +5 -0
  196. data/spec_legacy/integration/uniqueness_validator/uniqueness_validator_spec.rb +116 -0
  197. data/spec_legacy/integration/within_validator/spec_helper.rb +5 -0
  198. data/spec_legacy/integration/within_validator/within_validator_spec.rb +168 -0
  199. data/spec_legacy/public/resource_spec.rb +105 -0
  200. data/spec_legacy/spec.opts +4 -0
  201. data/spec_legacy/spec_helper.rb +29 -0
  202. data/spec_legacy/unit/contextual_validators/emptiness_spec.rb +50 -0
  203. data/spec_legacy/unit/contextual_validators/execution_spec.rb +48 -0
  204. data/spec_legacy/unit/contextual_validators/spec_helper.rb +37 -0
  205. data/spec_legacy/unit/generic_validator/equality_operator_spec.rb +26 -0
  206. data/spec_legacy/unit/generic_validator/optional_spec.rb +54 -0
  207. data/spec_legacy/unit/validators/within_validator_spec.rb +23 -0
  208. data/spec_legacy/unit/violation_set/adding_spec.rb +54 -0
  209. data/spec_legacy/unit/violation_set/emptiness_spec.rb +38 -0
  210. data/spec_legacy/unit/violation_set/enumerable_spec.rb +32 -0
  211. data/spec_legacy/unit/violation_set/reading_spec.rb +35 -0
  212. data/spec_legacy/unit/violation_set/respond_to_spec.rb +15 -0
  213. data/tasks/spec.rake +38 -0
  214. data/tasks/yard.rake +9 -0
  215. data/tasks/yardstick.rake +19 -0
  216. metadata +302 -0
@@ -0,0 +1,10 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Aequitas
4
+
5
+ module Undefined; end
6
+
7
+ class InvalidContextError < StandardError; end
8
+ class UnknownValidationFormat < ArgumentError; end
9
+
10
+ end # module Aequitas
@@ -0,0 +1,466 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'aequitas/rule'
4
+
5
+ require 'aequitas/rule/absence'
6
+ require 'aequitas/rule/acceptance'
7
+ require 'aequitas/rule/block'
8
+ require 'aequitas/rule/confirmation'
9
+ require 'aequitas/rule/format'
10
+ require 'aequitas/rule/length'
11
+ require 'aequitas/rule/method'
12
+ require 'aequitas/rule/numericalness'
13
+ require 'aequitas/rule/presence'
14
+ require 'aequitas/rule/primitive_type'
15
+ require 'aequitas/rule/within'
16
+
17
+ module Aequitas
18
+ module Macros
19
+ def self.extract_options(arguments)
20
+ arguments.last.kind_of?(Hash) ? arguments.pop : {}
21
+ end
22
+
23
+ # Validates that the specified attribute is "blank" via the
24
+ # attribute's #blank? method.
25
+ #
26
+ # @note
27
+ # dm-core's support lib adds the #blank? method to many classes,
28
+ # @see lib/dm-core/support/blank.rb (dm-core) for more information.
29
+ #
30
+ # @example [Usage]
31
+ # require 'virtus'
32
+ # require 'aequitas'
33
+ #
34
+ # class Page
35
+ # include Virtus
36
+ # include Aequitas
37
+ #
38
+ # attribute :unwanted_attribute, String
39
+ # attribute :another_unwanted, String
40
+ # attribute :yet_again, String
41
+ #
42
+ # validates_absence_of :unwanted_attribute
43
+ # validates_absence_of :another_unwanted, :yet_again
44
+ #
45
+ # # a call to #validate will return false unless
46
+ # # all three attributes are blank
47
+ # end
48
+ #
49
+ def validates_absence_of(*attribute_names)
50
+ options = Macros.extract_options(attribute_names)
51
+ validation_rules.add(Rule::Absence::Blank, attribute_names, options)
52
+ end
53
+
54
+ # Validates that the attributes's value is in the set of accepted
55
+ # values.
56
+ #
57
+ # @option [Boolean] :allow_nil (true)
58
+ # true if nil is allowed, false if not allowed.
59
+ #
60
+ # @option [Array] :accept (["1", 1, "true", true, "t"])
61
+ # A list of accepted values.
62
+ #
63
+ # @example Usage
64
+ # require 'virtus'
65
+ # require 'aequitas'
66
+ #
67
+ # class Page
68
+ # include Virtus
69
+ # include Aequitas
70
+ #
71
+ # attribute :license_agreement_accepted, String
72
+ # attribute :terms_accepted, String
73
+ #
74
+ # validates_acceptance_of :license_agreement, :accept => "1"
75
+ # validates_acceptance_of :terms_accepted, :allow_nil => false
76
+ #
77
+ # # a call to valid? will return false unless:
78
+ # # license_agreement is nil or "1"
79
+ # # and
80
+ # # terms_accepted is one of ["1", 1, "true", true, "t"]
81
+ # end
82
+ #
83
+ def validates_acceptance_of(*attribute_names)
84
+ options = Macros.extract_options(attribute_names)
85
+ validation_rules.add(Rule::Acceptance, attribute_names, options)
86
+ end
87
+
88
+ # Validates that the given attribute is confirmed by another
89
+ # attribute. A common use case scenario is when you require a user to
90
+ # confirm their password, for which you use both password and
91
+ # password_confirmation attributes.
92
+ #
93
+ # @option [Boolean] :allow_nil (true)
94
+ # true or false.
95
+ #
96
+ # @option [Boolean] :allow_blank (true)
97
+ # true or false.
98
+ #
99
+ # @option [Symbol] :confirm (firstattr_confirmation)
100
+ # The attribute that you want to validate against.
101
+ #
102
+ # @example Usage
103
+ # require 'virtus'
104
+ # require 'aequitas'
105
+ #
106
+ # class Page
107
+ # include Virtus
108
+ # include Aequitas
109
+ #
110
+ # attribute :password, String
111
+ # attribute :email, String
112
+ #
113
+ # attr_accessor :password_confirmation
114
+ # attr_accessor :email_repeated
115
+ #
116
+ # validates_confirmation_of :password
117
+ # validates_confirmation_of :email, :confirm => :email_repeated
118
+ #
119
+ # # a call to valid? will return false unless:
120
+ # # password == password_confirmation
121
+ # # and
122
+ # # email == email_repeated
123
+ # end
124
+ #
125
+ def validates_confirmation_of(*attribute_names)
126
+ options = Macros.extract_options(attribute_names)
127
+ validation_rules.add(Rule::Confirmation, attribute_names, options)
128
+ end
129
+
130
+ # Validates that the attribute is in the specified format. You may
131
+ # use the :as (or :with, it's an alias) option to specify the
132
+ # pre-defined format that you want to validate against. You may also
133
+ # specify your own format via a Proc or Regexp passed to the the :as
134
+ # or :with options.
135
+ #
136
+ # @option [Boolean] :allow_nil (true)
137
+ # true or false.
138
+ #
139
+ # @option [Boolean] :allow_blank (true)
140
+ # true or false.
141
+ #
142
+ # @option [Format, Proc, Regexp] :as
143
+ # The pre-defined format, Proc or Regexp to validate against.
144
+ #
145
+ # @option [Format, Proc, Regexp] :with
146
+ # An alias for :as.
147
+ #
148
+ # :email_address (format is specified in Aequitas::Format::Email - note that unicode emails will *not* be matched under MRI1.8.7)
149
+ # :url (format is specified in Aequitas::Format::Url)
150
+ #
151
+ # @example Usage
152
+ # require 'virtus'
153
+ # require 'aequitas'
154
+ #
155
+ # class Page
156
+ # include Virtus
157
+ # include Aequitas
158
+ #
159
+ # attribute :email, String
160
+ # attribute :zip_code, String
161
+ #
162
+ # validates_format_of :email, :as => :email_address
163
+ # validates_format_of :zip_code, :with => /^\d{5}$/
164
+ #
165
+ # # a call to valid? will return false unless:
166
+ # # email is formatted like an email address
167
+ # # and
168
+ # # zip_code is a string of 5 digits
169
+ # end
170
+ #
171
+ def validates_format_of(*attribute_names)
172
+ options = Macros.extract_options(attribute_names)
173
+ validation_rules.add(Rule::Format, attribute_names, options)
174
+ end
175
+
176
+ # Validates that the length of the attribute is equal to, less than,
177
+ # greater than or within a certain range (depending upon the options
178
+ # you specify).
179
+ #
180
+ # @option [Boolean] :allow_nil (true)
181
+ # true or false.
182
+ #
183
+ # @option [Boolean] :allow_blank (true)
184
+ # true or false.
185
+ #
186
+ # @option [Boolean] :minimum
187
+ # Ensures that the attribute's length is greater than or equal to
188
+ # the supplied value.
189
+ #
190
+ # @option [Boolean] :min
191
+ # Alias for :minimum.
192
+ #
193
+ # @option [Boolean] :maximum
194
+ # Ensures the attribute's length is less than or equal to the
195
+ # supplied value.
196
+ #
197
+ # @option [Boolean] :max
198
+ # Alias for :maximum.
199
+ #
200
+ # @option [Boolean] :equals
201
+ # Ensures the attribute's length is equal to the supplied value.
202
+ #
203
+ # @option [Boolean] :is
204
+ # Alias for :equals.
205
+ #
206
+ # @option [Range] :in
207
+ # Given a Range, ensures that the attributes length is include?'ed
208
+ # in the Range.
209
+ #
210
+ # @option [Range] :within
211
+ # Alias for :in.
212
+ #
213
+ # @example Usage
214
+ # require 'virtus'
215
+ # require 'aequitas'
216
+ #
217
+ # class Page
218
+ # include Virtus
219
+ # include Aequitas
220
+ #
221
+ # attribute :high, Integer
222
+ # attribute :low, Integer
223
+ # attribute :just_right, Integer
224
+ #
225
+ # validates_length_of :high, :min => 100000000000
226
+ # validates_length_of :low, :equals => 0
227
+ # validates_length_of :just_right, :within => 1..10
228
+ #
229
+ # # a call to valid? will return false unless:
230
+ # # high is greater than or equal to 100000000000
231
+ # # low is equal to 0
232
+ # # just_right is between 1 and 10 (inclusive of both 1 and 10)
233
+ # end
234
+ #
235
+ def validates_length_of(*attribute_names)
236
+ options = Macros.extract_options(attribute_names)
237
+ validation_rules.add(Rule::Length, attribute_names, options)
238
+ end
239
+
240
+ # Validate whether a field is numeric.
241
+ #
242
+ # @option [Boolean] :allow_nil
243
+ # true if number can be nil, false if not.
244
+ #
245
+ # @option [Boolean] :allow_blank
246
+ # true if number can be blank, false if not.
247
+ #
248
+ # @option [String] :message
249
+ # Custom error message, also can be a callable object that takes
250
+ # an object (for pure Ruby objects) or object and property
251
+ # (for DM resources).
252
+ #
253
+ # @option [Numeric] :precision
254
+ # Required precision of a value.
255
+ #
256
+ # @option [Numeric] :scale
257
+ # Required scale of a value.
258
+ #
259
+ # @option [Numeric] :gte
260
+ # 'Greater than or equal to' requirement.
261
+ #
262
+ # @option [Numeric] :lte
263
+ # 'Less than or equal to' requirement.
264
+ #
265
+ # @option [Numeric] :lt
266
+ # 'Less than' requirement.
267
+ #
268
+ # @option [Numeric] :gt
269
+ # 'Greater than' requirement.
270
+ #
271
+ # @option [Numeric] :eq
272
+ # 'Equal' requirement.
273
+ #
274
+ # @option [Numeric] :ne
275
+ # 'Not equal' requirement.
276
+ #
277
+ # @option [Boolean] :integer_only
278
+ # Use to restrict allowed values to integers.
279
+ #
280
+ def validates_numericalness_of(*attribute_names)
281
+ options = Macros.extract_options(attribute_names)
282
+ validation_rules.add(Rule::Numericalness, attribute_names, options)
283
+ end
284
+
285
+ # Validates that the specified attribute is present.
286
+ #
287
+ # For most property types "being present" is the same as being "not
288
+ # blank" as determined by the attribute's #blank? method. However, in
289
+ # the case of Boolean, "being present" means not nil; i.e. true or
290
+ # false.
291
+ #
292
+ # @note
293
+ # dm-core's support lib adds the blank? method to many classes,
294
+ #
295
+ # @see lib/dm-core/support/blank.rb (dm-core) for more information.
296
+ #
297
+ # @example Usage
298
+ # require 'virtus'
299
+ # require 'aequitas'
300
+ #
301
+ # class Page
302
+ # include Virtus
303
+ # include Aequitas
304
+ #
305
+ # attribute :required_attribute, String
306
+ # attribute :another_required, String
307
+ # attribute :yet_again, String
308
+ #
309
+ # validates_presence_of :required_attribute
310
+ # validates_presence_of :another_required, :yet_again
311
+ #
312
+ # # a call to valid? will return false unless
313
+ # # all three attributes are not blank (according to Aequitas.blank?)
314
+ # end
315
+ def validates_presence_of(*attribute_names)
316
+ options = Macros.extract_options(attribute_names)
317
+ validation_rules.add(Rule::Presence::NotBlank, attribute_names, options)
318
+ end
319
+
320
+ # Validates that the specified attribute is of the correct primitive
321
+ # type.
322
+ #
323
+ # @example Usage
324
+ # require 'virtus'
325
+ # require 'aequitas'
326
+ #
327
+ # class Person
328
+ # include Virtus
329
+ # include Aequitas
330
+ #
331
+ # attribute :birth_date, Date
332
+ #
333
+ # validates_primitive_type_of :birth_date
334
+ #
335
+ # # a call to valid? will return false unless
336
+ # # the birth_date is something that can be properly
337
+ # # casted into a Date object.
338
+ # end
339
+ def validates_primitive_type_of(*attribute_names)
340
+ options = Macros.extract_options(attribute_names)
341
+ validation_rules.add(Rule::PrimitiveType, attribute_names, options)
342
+ end
343
+
344
+ # Validates that the value of a field is within a range/set.
345
+ #
346
+ # This validation is defined by passing a field along with a :set
347
+ # parameter. The :set can be a Range or any object which responds
348
+ # to the #include? method (an array, for example).
349
+ #
350
+ # @example Usage
351
+ # require 'virtus'
352
+ # require 'aequitas'
353
+ #
354
+ # class Review
355
+ # include Virtus
356
+ # include Aequitas
357
+ #
358
+ # STATES = ['new', 'in_progress', 'published', 'archived']
359
+ #
360
+ # attribute :title, String
361
+ # attribute :body, String
362
+ # attribute :review_state, String
363
+ # attribute :rating, Integer
364
+ #
365
+ # validates_within :review_state, :set => STATES
366
+ # validates_within :rating, :set => 1..5
367
+ #
368
+ # # a call to valid? will return false unless
369
+ # # the two properties conform to their sets
370
+ # end
371
+ def validates_within(*attribute_names)
372
+ options = Macros.extract_options(attribute_names)
373
+ validation_rules.add(Rule::Within, attribute_names, options)
374
+ end
375
+
376
+ # Validate using the given block. The block given needs to return:
377
+ # [result::<Boolean>, Error Message::<String>]
378
+ #
379
+ # @example [Usage]
380
+ # require 'virtus'
381
+ # require 'aequitas'
382
+ #
383
+ # class Page
384
+ # include Virtus
385
+ # include Aequitas
386
+ #
387
+ # attribute :zip_code, String
388
+ #
389
+ # validates_with_block do
390
+ # if @zip_code == "94301"
391
+ # true
392
+ # else
393
+ # [false, "You're in the wrong zip code"]
394
+ # end
395
+ # end
396
+ #
397
+ # # A call to valid? will return false and
398
+ # # populate the object's errors with "You're in the
399
+ # # wrong zip code" unless zip_code == "94301"
400
+ #
401
+ # # You can also specify field:
402
+ #
403
+ # validates_with_block :zip_code do
404
+ # if @zip_code == "94301"
405
+ # true
406
+ # else
407
+ # [false, "You're in the wrong zip code"]
408
+ # end
409
+ # end
410
+ #
411
+ # # it will add returned error message to :zip_code field
412
+ # end
413
+ #
414
+ def validates_with_block(*attribute_names, &block)
415
+ unless block_given?
416
+ raise ArgumentError, 'You need to pass a block to validates_with_block'
417
+ end
418
+
419
+ options = Macros.extract_options(attribute_names)
420
+ validation_rules.add(Rule::Block, attribute_names, options, &block)
421
+ end
422
+
423
+ # Validate using method called on validated object. The method must
424
+ # to return either true, or a pair of [false, error message string],
425
+ # and is specified as a symbol passed with :method option.
426
+ #
427
+ # This validator does support multiple attribute_names being specified at a
428
+ # time, but we encourage you to use it with one property/method at a
429
+ # time.
430
+ #
431
+ # Real world experience shows that method validation is often useful
432
+ # when attribute needs to be virtual and not a property name.
433
+ #
434
+ # @example Usage
435
+ # require 'virtus'
436
+ # require 'aequitas'
437
+ #
438
+ # class Page
439
+ # include Virtus
440
+ # include Aequita
441
+ #
442
+ # attribute :zip_code, String
443
+ #
444
+ # validates_with_method :zip_code,
445
+ # :method => :in_the_right_location?
446
+ #
447
+ # def in_the_right_location?
448
+ # if @zip_code == "94301"
449
+ # return true
450
+ # else
451
+ # return [false, "You're in the wrong zip code"]
452
+ # end
453
+ # end
454
+ #
455
+ # # A call to #valid? will return false and
456
+ # # populate the object's errors with "You're in the
457
+ # # wrong zip code" unless zip_code == "94301"
458
+ # end
459
+ #
460
+ def validates_with_method(*attribute_names)
461
+ options = Macros.extract_options(attribute_names)
462
+ validation_rules.add(Rule::Method, attribute_names, options)
463
+ end
464
+
465
+ end # module Macros
466
+ end # module Aequitas