aequitas 0.0.1 → 0.0.2

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 (199) hide show
  1. data/VERSION +1 -1
  2. data/lib/aequitas/contextual_rule_set.rb +23 -29
  3. data/lib/aequitas/macros.rb +6 -0
  4. data/lib/aequitas/message_transformer.rb +23 -8
  5. data/lib/aequitas/rule.rb +2 -23
  6. data/lib/aequitas/rule/block.rb +5 -0
  7. data/lib/aequitas/rule/format.rb +24 -28
  8. data/lib/aequitas/rule/{formats/email.rb → format/email_address.rb} +7 -3
  9. data/lib/aequitas/rule/format/proc.rb +4 -10
  10. data/lib/aequitas/rule/format/regexp.rb +4 -6
  11. data/lib/aequitas/rule/{formats → format}/url.rb +7 -3
  12. data/lib/aequitas/rule/guard.rb +2 -2
  13. data/lib/aequitas/rule/length.rb +29 -30
  14. data/lib/aequitas/rule/length/equal.rb +4 -4
  15. data/lib/aequitas/rule/length/maximum.rb +4 -6
  16. data/lib/aequitas/rule/length/minimum.rb +4 -6
  17. data/lib/aequitas/rule/length/range.rb +4 -6
  18. data/lib/aequitas/rule/method.rb +6 -1
  19. data/lib/aequitas/rule/numericalness.rb +19 -40
  20. data/lib/aequitas/rule/numericalness/integer.rb +3 -19
  21. data/lib/aequitas/rule/numericalness/non_integer.rb +2 -18
  22. data/lib/aequitas/rule/primitive_type.rb +17 -6
  23. data/lib/aequitas/rule/primitive_type/virtus.rb +25 -0
  24. data/lib/aequitas/rule/skip_condition.rb +2 -2
  25. data/lib/aequitas/rule/value.rb +64 -0
  26. data/lib/aequitas/rule/{numericalness → value}/equal.rb +5 -7
  27. data/lib/aequitas/rule/{numericalness → value}/greater_than.rb +5 -7
  28. data/lib/aequitas/rule/{numericalness → value}/greater_than_or_equal.rb +5 -7
  29. data/lib/aequitas/rule/{numericalness → value}/less_than.rb +5 -7
  30. data/lib/aequitas/rule/{numericalness → value}/less_than_or_equal.rb +5 -7
  31. data/lib/aequitas/rule/{numericalness → value}/not_equal.rb +5 -7
  32. data/lib/aequitas/rule/value/range.rb +25 -0
  33. data/lib/aequitas/rule/within.rb +25 -13
  34. data/lib/aequitas/rule_set.rb +2 -2
  35. data/lib/aequitas/support/{equalizable.rb → value_object.rb} +2 -3
  36. data/lib/aequitas/version.rb +1 -1
  37. data/lib/aequitas/violation.rb +4 -4
  38. data/lib/aequitas/violation_set.rb +2 -3
  39. data/lib/aequitas/virtus_integration.rb +31 -0
  40. data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor.rb +30 -0
  41. data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/array.rb +29 -0
  42. data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/boolean.rb +17 -0
  43. data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/numeric.rb +22 -0
  44. data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/object.rb +38 -0
  45. data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/string.rb +35 -0
  46. data/spec/integration/aequitas/macros/validates_numericalness_of_spec.rb +77 -8
  47. data/spec/integration/aequitas/macros/validates_value_of_spec.rb +27 -0
  48. data/spec/integration/aequitas/macros/validates_within.rb +10 -74
  49. data/spec/integration/shared/macros/integration_spec.rb +10 -0
  50. data/spec/integration/virtus/array/length/equal_spec.rb +49 -0
  51. data/spec/integration/virtus/array/length/range_spec.rb +59 -0
  52. data/spec/integration/virtus/boolean/presence_spec.rb +4 -4
  53. data/spec/integration/virtus/integer/value/equal_to_spec.rb +45 -0
  54. data/spec/integration/virtus/integer/value/greater_than_or_equal.rb +45 -0
  55. data/spec/integration/virtus/integer/value/greater_than_spec.rb +45 -0
  56. data/spec/integration/virtus/integer/value/less_than_or_equal.rb +45 -0
  57. data/spec/integration/virtus/integer/value/less_than_spec.rb +45 -0
  58. data/spec/integration/virtus/integer/value/not_equal_to_spec.rb +45 -0
  59. data/spec/integration/virtus/string/format/email_address_spec.rb +3 -3
  60. data/spec/integration/virtus/string/format/regexp_spec.rb +2 -2
  61. data/spec/integration/virtus/string/format/url_spec.rb +2 -2
  62. data/spec/integration/virtus/string/length/equal_spec.rb +3 -3
  63. data/spec/integration/virtus/string/length/range_spec.rb +2 -2
  64. data/spec/integration/virtus/string/presence_spec.rb +2 -2
  65. data/spec/unit/aequitas/support/{equalizable → value_object}/equalizer_spec.rb +4 -4
  66. data/spec/unit/aequitas/support/{equalizable_spec.rb → value_object_spec.rb} +11 -11
  67. data/spec/unit/aequitas/violation_set_spec.rb +1 -1
  68. metadata +46 -149
  69. data/.gitignore +0 -4
  70. data/.rvmrc +0 -1
  71. data/aequitas.gemspec +0 -20
  72. data/lib/aequitas/rule/within/range.rb +0 -53
  73. data/lib/aequitas/rule/within/range/bounded.rb +0 -25
  74. data/lib/aequitas/rule/within/range/unbounded_begin.rb +0 -25
  75. data/lib/aequitas/rule/within/range/unbounded_end.rb +0 -25
  76. data/lib/aequitas/rule/within/set.rb +0 -39
  77. data/lib/aequitas/virtus.rb +0 -29
  78. data/lib/aequitas/virtus/inline_attribute_rule_extractor.rb +0 -41
  79. data/lib/aequitas/virtus/inline_attribute_rule_extractor/boolean.rb +0 -17
  80. data/lib/aequitas/virtus/inline_attribute_rule_extractor/object.rb +0 -25
  81. data/lib/aequitas/virtus/inline_attribute_rule_extractor/string.rb +0 -27
  82. data/spec_legacy/fixtures/barcode.rb +0 -40
  83. data/spec_legacy/fixtures/basketball_court.rb +0 -58
  84. data/spec_legacy/fixtures/basketball_player.rb +0 -34
  85. data/spec_legacy/fixtures/beta_tester_account.rb +0 -33
  86. data/spec_legacy/fixtures/bill_of_landing.rb +0 -47
  87. data/spec_legacy/fixtures/boat_dock.rb +0 -26
  88. data/spec_legacy/fixtures/city.rb +0 -24
  89. data/spec_legacy/fixtures/company.rb +0 -93
  90. data/spec_legacy/fixtures/corporate_world.rb +0 -39
  91. data/spec_legacy/fixtures/country.rb +0 -24
  92. data/spec_legacy/fixtures/ethernet_frame.rb +0 -56
  93. data/spec_legacy/fixtures/event.rb +0 -44
  94. data/spec_legacy/fixtures/g3_concert.rb +0 -57
  95. data/spec_legacy/fixtures/jabberwock.rb +0 -27
  96. data/spec_legacy/fixtures/kayak.rb +0 -28
  97. data/spec_legacy/fixtures/lernean_hydra.rb +0 -39
  98. data/spec_legacy/fixtures/llama_spaceship.rb +0 -15
  99. data/spec_legacy/fixtures/mathematical_function.rb +0 -34
  100. data/spec_legacy/fixtures/memory_object.rb +0 -30
  101. data/spec_legacy/fixtures/mittelschnauzer.rb +0 -39
  102. data/spec_legacy/fixtures/motor_launch.rb +0 -21
  103. data/spec_legacy/fixtures/multibyte.rb +0 -16
  104. data/spec_legacy/fixtures/page.rb +0 -32
  105. data/spec_legacy/fixtures/phone_number.rb +0 -28
  106. data/spec_legacy/fixtures/pirogue.rb +0 -28
  107. data/spec_legacy/fixtures/programming_language.rb +0 -83
  108. data/spec_legacy/fixtures/reservation.rb +0 -38
  109. data/spec_legacy/fixtures/scm_operation.rb +0 -56
  110. data/spec_legacy/fixtures/sms_message.rb +0 -22
  111. data/spec_legacy/fixtures/udp_packet.rb +0 -49
  112. data/spec_legacy/integration/absent_field_validator/absent_field_validator_spec.rb +0 -90
  113. data/spec_legacy/integration/absent_field_validator/spec_helper.rb +0 -7
  114. data/spec_legacy/integration/acceptance_validator/acceptance_validator_spec.rb +0 -196
  115. data/spec_legacy/integration/acceptance_validator/spec_helper.rb +0 -7
  116. data/spec_legacy/integration/automatic_validation/custom_messages_for_inferred_validation_spec.rb +0 -57
  117. data/spec_legacy/integration/automatic_validation/disabling_inferred_validation_spec.rb +0 -49
  118. data/spec_legacy/integration/automatic_validation/inferred_boolean_properties_validation_spec.rb +0 -100
  119. data/spec_legacy/integration/automatic_validation/inferred_float_property_validation_spec.rb +0 -45
  120. data/spec_legacy/integration/automatic_validation/inferred_format_validation_spec.rb +0 -35
  121. data/spec_legacy/integration/automatic_validation/inferred_integer_properties_validation_spec.rb +0 -70
  122. data/spec_legacy/integration/automatic_validation/inferred_length_validation_spec.rb +0 -142
  123. data/spec_legacy/integration/automatic_validation/inferred_presence_validation_spec.rb +0 -45
  124. data/spec_legacy/integration/automatic_validation/inferred_primitive_validation_spec.rb +0 -22
  125. data/spec_legacy/integration/automatic_validation/inferred_uniqueness_validation_spec.rb +0 -48
  126. data/spec_legacy/integration/automatic_validation/inferred_within_validation_spec.rb +0 -35
  127. data/spec_legacy/integration/automatic_validation/spec_helper.rb +0 -57
  128. data/spec_legacy/integration/block_validator/block_validator_spec.rb +0 -32
  129. data/spec_legacy/integration/block_validator/spec_helper.rb +0 -5
  130. data/spec_legacy/integration/conditional_validation/if_condition_spec.rb +0 -63
  131. data/spec_legacy/integration/conditional_validation/spec_helper.rb +0 -5
  132. data/spec_legacy/integration/confirmation_validator/confirmation_validator_spec.rb +0 -76
  133. data/spec_legacy/integration/confirmation_validator/spec_helper.rb +0 -5
  134. data/spec_legacy/integration/datamapper_models/association_validation_spec.rb +0 -29
  135. data/spec_legacy/integration/datamapper_models/inheritance_spec.rb +0 -82
  136. data/spec_legacy/integration/dirty_attributes/dirty_attributes_spec.rb +0 -13
  137. data/spec_legacy/integration/duplicated_validations/duplicated_validations_spec.rb +0 -24
  138. data/spec_legacy/integration/duplicated_validations/spec_helper.rb +0 -5
  139. data/spec_legacy/integration/format_validator/email_format_validator_spec.rb +0 -139
  140. data/spec_legacy/integration/format_validator/format_validator_spec.rb +0 -64
  141. data/spec_legacy/integration/format_validator/regexp_validator_spec.rb +0 -33
  142. data/spec_legacy/integration/format_validator/spec_helper.rb +0 -5
  143. data/spec_legacy/integration/format_validator/url_format_validator_spec.rb +0 -93
  144. data/spec_legacy/integration/length_validator/default_value_spec.rb +0 -14
  145. data/spec_legacy/integration/length_validator/equality_spec.rb +0 -87
  146. data/spec_legacy/integration/length_validator/error_message_spec.rb +0 -22
  147. data/spec_legacy/integration/length_validator/maximum_spec.rb +0 -49
  148. data/spec_legacy/integration/length_validator/minimum_spec.rb +0 -54
  149. data/spec_legacy/integration/length_validator/range_spec.rb +0 -87
  150. data/spec_legacy/integration/length_validator/spec_helper.rb +0 -7
  151. data/spec_legacy/integration/method_validator/method_validator_spec.rb +0 -242
  152. data/spec_legacy/integration/method_validator/spec_helper.rb +0 -5
  153. data/spec_legacy/integration/numeric_validator/equality_with_float_type_spec.rb +0 -65
  154. data/spec_legacy/integration/numeric_validator/equality_with_integer_type_spec.rb +0 -41
  155. data/spec_legacy/integration/numeric_validator/float_type_spec.rb +0 -90
  156. data/spec_legacy/integration/numeric_validator/gt_with_float_type_spec.rb +0 -37
  157. data/spec_legacy/integration/numeric_validator/gte_with_float_type_spec.rb +0 -37
  158. data/spec_legacy/integration/numeric_validator/integer_only_true_spec.rb +0 -91
  159. data/spec_legacy/integration/numeric_validator/integer_type_spec.rb +0 -86
  160. data/spec_legacy/integration/numeric_validator/lt_with_float_type_spec.rb +0 -37
  161. data/spec_legacy/integration/numeric_validator/lte_with_float_type_spec.rb +0 -37
  162. data/spec_legacy/integration/numeric_validator/spec_helper.rb +0 -5
  163. data/spec_legacy/integration/primitive_validator/primitive_validator_spec.rb +0 -92
  164. data/spec_legacy/integration/primitive_validator/spec_helper.rb +0 -5
  165. data/spec_legacy/integration/pure_ruby_objects/plain_old_ruby_object_validation_spec.rb +0 -118
  166. data/spec_legacy/integration/required_field_validator/association_spec.rb +0 -69
  167. data/spec_legacy/integration/required_field_validator/boolean_type_value_spec.rb +0 -164
  168. data/spec_legacy/integration/required_field_validator/date_type_value_spec.rb +0 -127
  169. data/spec_legacy/integration/required_field_validator/datetime_type_value_spec.rb +0 -127
  170. data/spec_legacy/integration/required_field_validator/float_type_value_spec.rb +0 -131
  171. data/spec_legacy/integration/required_field_validator/integer_type_value_spec.rb +0 -99
  172. data/spec_legacy/integration/required_field_validator/plain_old_ruby_object_spec.rb +0 -35
  173. data/spec_legacy/integration/required_field_validator/shared_examples.rb +0 -26
  174. data/spec_legacy/integration/required_field_validator/spec_helper.rb +0 -7
  175. data/spec_legacy/integration/required_field_validator/string_type_value_spec.rb +0 -167
  176. data/spec_legacy/integration/required_field_validator/text_type_value_spec.rb +0 -49
  177. data/spec_legacy/integration/shared/default_validation_context.rb +0 -13
  178. data/spec_legacy/integration/shared/valid_and_invalid_model.rb +0 -35
  179. data/spec_legacy/integration/uniqueness_validator/spec_helper.rb +0 -5
  180. data/spec_legacy/integration/uniqueness_validator/uniqueness_validator_spec.rb +0 -116
  181. data/spec_legacy/integration/within_validator/spec_helper.rb +0 -5
  182. data/spec_legacy/integration/within_validator/within_validator_spec.rb +0 -168
  183. data/spec_legacy/public/resource_spec.rb +0 -105
  184. data/spec_legacy/spec.opts +0 -4
  185. data/spec_legacy/spec_helper.rb +0 -29
  186. data/spec_legacy/unit/contextual_validators/emptiness_spec.rb +0 -50
  187. data/spec_legacy/unit/contextual_validators/execution_spec.rb +0 -48
  188. data/spec_legacy/unit/contextual_validators/spec_helper.rb +0 -37
  189. data/spec_legacy/unit/generic_validator/equality_operator_spec.rb +0 -26
  190. data/spec_legacy/unit/generic_validator/optional_spec.rb +0 -54
  191. data/spec_legacy/unit/validators/within_validator_spec.rb +0 -23
  192. data/spec_legacy/unit/violation_set/adding_spec.rb +0 -54
  193. data/spec_legacy/unit/violation_set/emptiness_spec.rb +0 -38
  194. data/spec_legacy/unit/violation_set/enumerable_spec.rb +0 -32
  195. data/spec_legacy/unit/violation_set/reading_spec.rb +0 -35
  196. data/spec_legacy/unit/violation_set/respond_to_spec.rb +0 -15
  197. data/tasks/spec.rake +0 -38
  198. data/tasks/yard.rake +0 -9
  199. data/tasks/yardstick.rake +0 -19
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  require 'forwardable'
4
- require 'aequitas/support/equalizable'
4
+ require 'aequitas/support/value_object'
5
5
  require 'aequitas/exceptions'
6
6
  require 'aequitas/context'
7
7
  require 'aequitas/rule_set'
8
8
 
9
9
  module Aequitas
10
10
  class ContextualRuleSet
11
- extend Equalizable
11
+ extend ValueObject
12
12
  extend Forwardable
13
13
  include Enumerable
14
14
 
@@ -16,9 +16,9 @@ module Aequitas
16
16
 
17
17
  # MessageTransformer to use for transforming Violations on Resources
18
18
  # instantiated from the model to which this ContextualRuleSet is bound
19
- #
19
+ #
20
20
  # @api public
21
- # attr_accessor :transformer
21
+ attr_accessor :transformer
22
22
 
23
23
  # @api private
24
24
  attr_reader :rule_sets
@@ -44,7 +44,7 @@ module Aequitas
44
44
  end
45
45
 
46
46
  # Delegate #validate to RuleSet
47
- #
47
+ #
48
48
  # @api public
49
49
  def validate(resource, context_name)
50
50
  context(context_name).validate(resource)
@@ -56,17 +56,17 @@ module Aequitas
56
56
  # Context name for which to return a RuleSet
57
57
  # @return [RuleSet]
58
58
  # RuleSet for the given context
59
- #
59
+ #
60
60
  # @api public
61
61
  def context(context_name)
62
62
  rule_sets.fetch(context_name)
63
63
  end
64
64
 
65
65
  # Retrieve Rules applicable to a given attribute name
66
- #
66
+ #
67
67
  # @param [Symbol] attribute_name
68
68
  # name of the attribute for which to retrieve applicable Rules
69
- #
69
+ #
70
70
  # @return [Array]
71
71
  # list of Rules applicable to +attribute_name+
72
72
  def [](attribute_name)
@@ -75,21 +75,21 @@ module Aequitas
75
75
 
76
76
  # Create a new rule of the given class for each name in +attribute_names+
77
77
  # and add the rules to the RuleSet(s) indicated
78
- #
78
+ #
79
79
  # @param [Aequitas::Rule] rule_class
80
80
  # Rule class, example: Aequitas::Rule::Presence
81
81
  #
82
82
  # @param [Array<Symbol>] attribute_names
83
83
  # Attribute names given to validation macro, example:
84
84
  # [:first_name, :last_name] in validates_presence_of :first_name, :last_name
85
- #
85
+ #
86
86
  # @param [Hash] options
87
87
  # Options supplied to validation macro, example:
88
88
  # {:context=>:default, :maximum=>50, :allow_nil=>true, :message=>nil}
89
- #
89
+ #
90
90
  # @option [Symbol] :context, :group, :when, :on
91
91
  # the context in which the new rule should be run
92
- #
92
+ #
93
93
  # @return [self]
94
94
  def add(rule_class, attribute_names, options = {}, &block)
95
95
  context_names = extract_context_names(options)
@@ -104,10 +104,10 @@ module Aequitas
104
104
  end
105
105
 
106
106
  # Assimilate all rules contained in +other+ into the receiver
107
- #
107
+ #
108
108
  # @param [ContextualRuleSet] other
109
109
  # the ContextualRuleSet whose rules are to be assimilated
110
- #
110
+ #
111
111
  # @return [self]
112
112
  def concat(other)
113
113
  other.rule_sets.each do |context_name, rule_set|
@@ -118,12 +118,12 @@ module Aequitas
118
118
  end
119
119
 
120
120
  # Define a context and append rules to it
121
- #
121
+ #
122
122
  # @param [Symbol] context_name
123
123
  # name of the context to define and append rules to
124
124
  # @param [RuleSet, Array] rules
125
125
  # Rules to append to +context_name+
126
- #
126
+ #
127
127
  # @return [self]
128
128
  def add_rules_to_context(context_name, rules)
129
129
  define_context(context_name)
@@ -144,9 +144,9 @@ module Aequitas
144
144
  # this model, or :default if the context on the stack is invalid for
145
145
  # this model or no context is on the stack and this model has at least
146
146
  # one validation context
147
- #
147
+ #
148
148
  # @api private
149
- #
149
+ #
150
150
  # TODO: this logic behind this method is too complicated.
151
151
  # simplify the semantics of #current_context, #validate
152
152
  def current_context
@@ -185,7 +185,7 @@ module Aequitas
185
185
  # raised if the context is not valid for this contextual rule set
186
186
  #
187
187
  # @api private
188
- #
188
+ #
189
189
  # TODO: is this method actually needed?
190
190
  def assert_valid_context(context_name)
191
191
  unless valid_context?(context_name)
@@ -198,22 +198,16 @@ module Aequitas
198
198
  private
199
199
 
200
200
  # Allow :context to be aliased to :group, :when & :on
201
- #
201
+ #
202
202
  # @param [Hash] options
203
203
  # the options from which +context_names+ is to be extracted
204
- #
204
+ #
205
205
  # @return [Array(Symbol)]
206
206
  # the context name(s) from +options+
207
- #
207
+ #
208
208
  # @api private
209
209
  def extract_context_names(options)
210
- context_name = [
211
- options.delete(:context),
212
- options.delete(:group),
213
- options.delete(:when),
214
- options.delete(:on)
215
- ].compact.first
216
-
210
+ context_name = options.values_at(:context, :group, :when, :on).compact.first
217
211
  Array(context_name || :default)
218
212
  end
219
213
 
@@ -279,6 +279,7 @@ module Aequitas
279
279
  #
280
280
  def validates_numericalness_of(*attribute_names)
281
281
  options = Macros.extract_options(attribute_names)
282
+ validation_rules.add(Rule::Value, attribute_names, options)
282
283
  validation_rules.add(Rule::Numericalness, attribute_names, options)
283
284
  end
284
285
 
@@ -341,6 +342,11 @@ module Aequitas
341
342
  validation_rules.add(Rule::PrimitiveType, attribute_names, options)
342
343
  end
343
344
 
345
+ def validates_value_of(*attribute_names)
346
+ options = Macros.extract_options(attribute_names)
347
+ validation_rules.add(Rule::Value, attribute_names, options)
348
+ end
349
+
344
350
  # Validates that the value of a field is within a range/set.
345
351
  #
346
352
  # This validation is defined by passing a field along with a :set
@@ -1,15 +1,23 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  module Aequitas
4
+
4
5
  # Transforms Violations to error message strings.
5
6
  #
6
7
  # @abstract
7
8
  # Subclass and override {#transform} to implement a custom message
8
- # transformer. Use {Violation.message_transformer=} to set a new
9
+ # transformer. Use {Violation.default_transformer=} to set a new default
9
10
  # message transformer or pass the transformer to {Violation#message}.
10
11
  class MessageTransformer
12
+ # Get the default MessageTransformer for this process
13
+ #
14
+ # @return [MessageTransformer]
15
+ # default MessageTransformer for this process
16
+ #
17
+ # @see {Violation.default_transformer}
18
+ #
11
19
  def self.default
12
- defined?(I18n) ? DefaultI18n.new : Default.new
20
+ defined?(::I18n) ? DefaultI18n.new : DefaultStatic.new
13
21
  end
14
22
 
15
23
  # Transforms the specified Violation to an error message string.
@@ -26,7 +34,7 @@ module Aequitas
26
34
  raise NotImplementedError, "#{self.class}#transform has not been implemented"
27
35
  end
28
36
 
29
- class Default < self
37
+ class DefaultStatic < MessageTransformer
30
38
  @error_messages = {
31
39
  :nil => '%s must not be nil',
32
40
  :blank => '%s must not be blank',
@@ -50,7 +58,8 @@ module Aequitas
50
58
  :less_than_or_equal_to => '%s must be less than or equal to %s',
51
59
  :value_between => '%s must be between %s and %s',
52
60
  :not_unique => '%s is already taken',
53
- :primitive => '%s must be of type %s'
61
+ :primitive => '%s must be of type %s',
62
+ :unsatisfied_condition => '%s condition was not satisfied',
54
63
  }
55
64
 
56
65
  class << self
@@ -75,13 +84,17 @@ module Aequitas
75
84
 
76
85
  def self.error_message(violation_type, attribute_name, violation_values)
77
86
  if message = self.error_messages[violation_type]
78
- attribute_name = DataMapper::Inflector.humanize(attribute_name)
87
+ attribute_name = ::DataMapper::Inflector.humanize(attribute_name)
79
88
  message % [attribute_name, *violation_values].flatten
80
89
  else
81
90
  violation_type.to_s
82
91
  end
83
92
  end
84
93
 
94
+ def initialize
95
+ require 'dm-core'
96
+ end
97
+
85
98
  def transform(violation)
86
99
  raise ArgumentError, "+violation+ must be specified" if violation.nil?
87
100
 
@@ -89,9 +102,9 @@ module Aequitas
89
102
 
90
103
  self.class.error_message(violation.type, attribute_name, violation.values)
91
104
  end
92
- end # class Default
105
+ end # class DefaultStatic
93
106
 
94
- class DefaultI18n < self
107
+ class DefaultI18n < MessageTransformer
95
108
  def initialize
96
109
  require 'i18n'
97
110
  end
@@ -100,6 +113,8 @@ module Aequitas
100
113
  raise ArgumentError, "+violation+ must be specified" if violation.nil?
101
114
 
102
115
  resource = violation.resource
116
+ # TODO: resource#model and Model#model_name are assumptions from DM
117
+ # Figure out a more flexible way to lookup error messages in I18n
103
118
  model_name = resource.model.model_name
104
119
  attribute_name = violation.attribute_name
105
120
  # TODO: Include attribute value in Violation; it may have changed by now
@@ -109,7 +124,7 @@ module Aequitas
109
124
  :model => ::I18n.translate("models.#{model_name}"),
110
125
  :attribute => ::I18n.translate("attributes.#{model_name}.#{attribute_name}"),
111
126
  # TODO: Include attribute value in Violation; it may have changed by now
112
- :value => resource.validation_attribute_value(attribute_name)
127
+ :value => resource.validation_attribute_value(attribute_name),
113
128
  }.merge(violation.info)
114
129
 
115
130
  ::I18n.translate("#{i18n_namespace}.#{violation.type}", options)
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  require 'aequitas/support/blank'
4
- require 'aequitas/support/equalizable'
4
+ require 'aequitas/support/value_object'
5
5
  require 'aequitas/rule/guard'
6
6
  require 'aequitas/rule/skip_condition'
7
7
  require 'aequitas/violation'
8
8
 
9
9
  module Aequitas
10
10
  class Rule
11
- extend Equalizable
11
+ extend ValueObject
12
12
 
13
13
  equalize_on :attribute_name, :custom_message, :guard, :skip_condition
14
14
 
@@ -123,27 +123,6 @@ module Aequitas
123
123
 
124
124
  private
125
125
 
126
- # def allow_nil!
127
- # @allow_nil = true
128
- # end
129
-
130
- # def allow_blank!
131
- # @allow_blank = true
132
- # end
133
-
134
- # Get the corresponding Resource property, if it exists.
135
- #
136
- # Note: DataMapper validations can be used on non-DataMapper resources.
137
- # In such cases, the return value will be nil.
138
- #
139
- # @api private
140
- def get_resource_property(resource, property_name)
141
- model = resource.model if resource.respond_to?(:model)
142
- repository = resource.repository if model
143
- properties = model.properties(repository.name) if model
144
- properties[property_name] if properties
145
- end
146
-
147
126
  def assert_kind_of(name, value, *klasses)
148
127
  klasses.each { |k| return if value.kind_of?(k) }
149
128
  raise ArgumentError, "+#{name}+ should be #{klasses.map { |k| k.name } * ' or '}, but was #{value.class.name}", caller(2)
@@ -16,6 +16,7 @@ module Aequitas
16
16
  super
17
17
 
18
18
  @block = block
19
+ @violation_type = options.fetch(:violation_type, :unsatisfied_condition)
19
20
  end
20
21
 
21
22
  def validate(resource)
@@ -28,6 +29,10 @@ module Aequitas
28
29
  end
29
30
  end
30
31
 
32
+ def violation_type(resource)
33
+ @violation_type
34
+ end
35
+
31
36
  end # class Block
32
37
  end # class Rule
33
38
  end # module Aequitas
@@ -3,17 +3,11 @@
3
3
  require 'aequitas/rule'
4
4
  require 'aequitas/exceptions'
5
5
 
6
- require 'aequitas/rule/formats/email'
7
- require 'aequitas/rule/formats/url'
8
-
9
6
  module Aequitas
10
7
  class Rule
11
- module Format
8
+ class Format < Rule
12
9
 
13
- FORMATS = {
14
- :email_address => Formats::EmailAddress,
15
- :url => Formats::Url
16
- }
10
+ FORMATS = {}
17
11
  # TODO: evaluate re-implementing custom error messages per format type
18
12
  # previously these strings were wrapped in lambdas, which were, at one
19
13
  # point, invoked with #try_call with the humanized attribute name and value
@@ -22,32 +16,31 @@ module Aequitas
22
16
  :url => '%s is not a valid URL',
23
17
  }
24
18
 
25
-
26
- def self.rules_for(attribute_name, options)
27
- Array(new(attribute_name, options))
28
- end
19
+ equalize_on *superclass.equalizer.keys + [:format]
29
20
 
30
21
  # @raise [UnknownValidationFormat]
31
22
  # if the :as (or :with) option is a Symbol that is not a key in FORMATS,
32
23
  # or if the provided format is not a Regexp, Symbol or Proc
33
- def self.new(attribute_name, options)
34
- format = options.delete(:as) || options.delete(:with)
35
-
36
- case format
37
- when Symbol
38
- regexp = FORMATS.fetch(format) do
39
- raise UnknownValidationFormat, "No such predefined format '#{format}'"
24
+ def self.rules_for(attribute_name, options)
25
+ format = options.values_at(:as, :with).compact.first
26
+
27
+ rule =
28
+ case format
29
+ when Symbol
30
+ regexp = FORMATS.fetch(format) do
31
+ raise UnknownValidationFormat, "No such predefined format '#{format}'"
32
+ end
33
+ self::Regexp.new(attribute_name, options.merge(:format => regexp, :format_name => format))
34
+ when ::Regexp
35
+ self::Regexp.new(attribute_name, options.merge(:format => format))
36
+ when ::Proc
37
+ self::Proc.new(attribute_name, options.merge(:format => format))
38
+ else
39
+ raise UnknownValidationFormat, "Expected a Regexp, Symbol, or Proc format. Got: #{format.inspect}"
40
40
  end
41
- self::Regexp.new(attribute_name, options.merge(:format => regexp, :format_name => format))
42
- when ::Regexp
43
- self::Regexp.new(attribute_name, options.merge(:format => format))
44
- when ::Proc
45
- self::Proc.new(attribute_name, options.merge(:format => format))
46
- else
47
- raise UnknownValidationFormat, "Expected a Regexp, Symbol, or Proc format. Got: #{format.inspect}"
48
- end
49
- end
50
41
 
42
+ Array(rule)
43
+ end
51
44
 
52
45
  attr_reader :format
53
46
 
@@ -77,5 +70,8 @@ module Aequitas
77
70
  end # class Rule
78
71
  end # module Aequitas
79
72
 
73
+ require 'aequitas/rule/format/email_address'
74
+ require 'aequitas/rule/format/url'
75
+
80
76
  require 'aequitas/rule/format/proc'
81
77
  require 'aequitas/rule/format/regexp'
@@ -1,15 +1,17 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'aequitas/rule/format'
4
+
3
5
  module Aequitas
4
6
  class Rule
5
- module Formats
7
+ class Format
6
8
 
7
9
  # Almost RFC2822 (No attribution reference available).
8
10
  #
9
11
  # This differs in that it does not allow local domains (test@localhost).
10
12
  # 99% of the time you do not want to allow these email addresses
11
13
  # in a public web application.
12
- EmailAddress = begin
14
+ EMAIL_ADDRESS = begin
13
15
  if (RUBY_VERSION == '1.9.2' && RUBY_ENGINE == 'jruby' && JRUBY_VERSION <= '1.6.3') || RUBY_VERSION == '1.9.3'
14
16
  # There is an obscure bug in jruby 1.6 that prevents matching
15
17
  # on unicode properties here. Remove this logic branch once
@@ -47,6 +49,8 @@ module Aequitas
47
49
  pattern = /\A#{addr_spec}\z/u
48
50
  end
49
51
 
50
- end # module Formats
52
+ Format::FORMATS[:email_address] = EMAIL_ADDRESS
53
+
54
+ end # class Format
51
55
  end # class Rule
52
56
  end # module Aequitas
@@ -4,25 +4,19 @@ require 'aequitas/rule/format'
4
4
 
5
5
  module Aequitas
6
6
  class Rule
7
- module Format
8
- class Proc < Rule
9
-
10
- include Format
11
-
12
- equalize_on *(superclass.equalizer.keys + [:format])
13
-
7
+ class Format
8
+ class Proc < Format
14
9
 
15
10
  def valid?(resource)
16
11
  value = attribute_value(resource)
17
- return true if skip?(value)
18
12
 
19
- self.format.call(value)
13
+ skip?(value) || format.call(value)
20
14
  # rescue ::Encoding::CompatibilityError
21
15
  # # This is to work around a bug in jruby - see formats/email.rb
22
16
  # false
23
17
  end
24
18
 
25
19
  end # class Proc
26
- end # module Format
20
+ end # class Format
27
21
  end # class Rule
28
22
  end # module Aequitas