aequitas 0.0.1 → 0.0.2

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