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.
- data/VERSION +1 -1
- data/lib/aequitas/contextual_rule_set.rb +23 -29
- data/lib/aequitas/macros.rb +6 -0
- data/lib/aequitas/message_transformer.rb +23 -8
- data/lib/aequitas/rule.rb +2 -23
- data/lib/aequitas/rule/block.rb +5 -0
- data/lib/aequitas/rule/format.rb +24 -28
- data/lib/aequitas/rule/{formats/email.rb → format/email_address.rb} +7 -3
- data/lib/aequitas/rule/format/proc.rb +4 -10
- data/lib/aequitas/rule/format/regexp.rb +4 -6
- data/lib/aequitas/rule/{formats → format}/url.rb +7 -3
- data/lib/aequitas/rule/guard.rb +2 -2
- data/lib/aequitas/rule/length.rb +29 -30
- data/lib/aequitas/rule/length/equal.rb +4 -4
- data/lib/aequitas/rule/length/maximum.rb +4 -6
- data/lib/aequitas/rule/length/minimum.rb +4 -6
- data/lib/aequitas/rule/length/range.rb +4 -6
- data/lib/aequitas/rule/method.rb +6 -1
- data/lib/aequitas/rule/numericalness.rb +19 -40
- data/lib/aequitas/rule/numericalness/integer.rb +3 -19
- data/lib/aequitas/rule/numericalness/non_integer.rb +2 -18
- data/lib/aequitas/rule/primitive_type.rb +17 -6
- data/lib/aequitas/rule/primitive_type/virtus.rb +25 -0
- data/lib/aequitas/rule/skip_condition.rb +2 -2
- data/lib/aequitas/rule/value.rb +64 -0
- data/lib/aequitas/rule/{numericalness → value}/equal.rb +5 -7
- data/lib/aequitas/rule/{numericalness → value}/greater_than.rb +5 -7
- data/lib/aequitas/rule/{numericalness → value}/greater_than_or_equal.rb +5 -7
- data/lib/aequitas/rule/{numericalness → value}/less_than.rb +5 -7
- data/lib/aequitas/rule/{numericalness → value}/less_than_or_equal.rb +5 -7
- data/lib/aequitas/rule/{numericalness → value}/not_equal.rb +5 -7
- data/lib/aequitas/rule/value/range.rb +25 -0
- data/lib/aequitas/rule/within.rb +25 -13
- data/lib/aequitas/rule_set.rb +2 -2
- data/lib/aequitas/support/{equalizable.rb → value_object.rb} +2 -3
- data/lib/aequitas/version.rb +1 -1
- data/lib/aequitas/violation.rb +4 -4
- data/lib/aequitas/violation_set.rb +2 -3
- data/lib/aequitas/virtus_integration.rb +31 -0
- data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor.rb +30 -0
- data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/array.rb +29 -0
- data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/boolean.rb +17 -0
- data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/numeric.rb +22 -0
- data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/object.rb +38 -0
- data/lib/aequitas/virtus_integration/inline_attribute_rule_extractor/string.rb +35 -0
- data/spec/integration/aequitas/macros/validates_numericalness_of_spec.rb +77 -8
- data/spec/integration/aequitas/macros/validates_value_of_spec.rb +27 -0
- data/spec/integration/aequitas/macros/validates_within.rb +10 -74
- data/spec/integration/shared/macros/integration_spec.rb +10 -0
- data/spec/integration/virtus/array/length/equal_spec.rb +49 -0
- data/spec/integration/virtus/array/length/range_spec.rb +59 -0
- data/spec/integration/virtus/boolean/presence_spec.rb +4 -4
- data/spec/integration/virtus/integer/value/equal_to_spec.rb +45 -0
- data/spec/integration/virtus/integer/value/greater_than_or_equal.rb +45 -0
- data/spec/integration/virtus/integer/value/greater_than_spec.rb +45 -0
- data/spec/integration/virtus/integer/value/less_than_or_equal.rb +45 -0
- data/spec/integration/virtus/integer/value/less_than_spec.rb +45 -0
- data/spec/integration/virtus/integer/value/not_equal_to_spec.rb +45 -0
- data/spec/integration/virtus/string/format/email_address_spec.rb +3 -3
- data/spec/integration/virtus/string/format/regexp_spec.rb +2 -2
- data/spec/integration/virtus/string/format/url_spec.rb +2 -2
- data/spec/integration/virtus/string/length/equal_spec.rb +3 -3
- data/spec/integration/virtus/string/length/range_spec.rb +2 -2
- data/spec/integration/virtus/string/presence_spec.rb +2 -2
- data/spec/unit/aequitas/support/{equalizable → value_object}/equalizer_spec.rb +4 -4
- data/spec/unit/aequitas/support/{equalizable_spec.rb → value_object_spec.rb} +11 -11
- data/spec/unit/aequitas/violation_set_spec.rb +1 -1
- metadata +46 -149
- data/.gitignore +0 -4
- data/.rvmrc +0 -1
- data/aequitas.gemspec +0 -20
- data/lib/aequitas/rule/within/range.rb +0 -53
- data/lib/aequitas/rule/within/range/bounded.rb +0 -25
- data/lib/aequitas/rule/within/range/unbounded_begin.rb +0 -25
- data/lib/aequitas/rule/within/range/unbounded_end.rb +0 -25
- data/lib/aequitas/rule/within/set.rb +0 -39
- data/lib/aequitas/virtus.rb +0 -29
- data/lib/aequitas/virtus/inline_attribute_rule_extractor.rb +0 -41
- data/lib/aequitas/virtus/inline_attribute_rule_extractor/boolean.rb +0 -17
- data/lib/aequitas/virtus/inline_attribute_rule_extractor/object.rb +0 -25
- data/lib/aequitas/virtus/inline_attribute_rule_extractor/string.rb +0 -27
- data/spec_legacy/fixtures/barcode.rb +0 -40
- data/spec_legacy/fixtures/basketball_court.rb +0 -58
- data/spec_legacy/fixtures/basketball_player.rb +0 -34
- data/spec_legacy/fixtures/beta_tester_account.rb +0 -33
- data/spec_legacy/fixtures/bill_of_landing.rb +0 -47
- data/spec_legacy/fixtures/boat_dock.rb +0 -26
- data/spec_legacy/fixtures/city.rb +0 -24
- data/spec_legacy/fixtures/company.rb +0 -93
- data/spec_legacy/fixtures/corporate_world.rb +0 -39
- data/spec_legacy/fixtures/country.rb +0 -24
- data/spec_legacy/fixtures/ethernet_frame.rb +0 -56
- data/spec_legacy/fixtures/event.rb +0 -44
- data/spec_legacy/fixtures/g3_concert.rb +0 -57
- data/spec_legacy/fixtures/jabberwock.rb +0 -27
- data/spec_legacy/fixtures/kayak.rb +0 -28
- data/spec_legacy/fixtures/lernean_hydra.rb +0 -39
- data/spec_legacy/fixtures/llama_spaceship.rb +0 -15
- data/spec_legacy/fixtures/mathematical_function.rb +0 -34
- data/spec_legacy/fixtures/memory_object.rb +0 -30
- data/spec_legacy/fixtures/mittelschnauzer.rb +0 -39
- data/spec_legacy/fixtures/motor_launch.rb +0 -21
- data/spec_legacy/fixtures/multibyte.rb +0 -16
- data/spec_legacy/fixtures/page.rb +0 -32
- data/spec_legacy/fixtures/phone_number.rb +0 -28
- data/spec_legacy/fixtures/pirogue.rb +0 -28
- data/spec_legacy/fixtures/programming_language.rb +0 -83
- data/spec_legacy/fixtures/reservation.rb +0 -38
- data/spec_legacy/fixtures/scm_operation.rb +0 -56
- data/spec_legacy/fixtures/sms_message.rb +0 -22
- data/spec_legacy/fixtures/udp_packet.rb +0 -49
- data/spec_legacy/integration/absent_field_validator/absent_field_validator_spec.rb +0 -90
- data/spec_legacy/integration/absent_field_validator/spec_helper.rb +0 -7
- data/spec_legacy/integration/acceptance_validator/acceptance_validator_spec.rb +0 -196
- data/spec_legacy/integration/acceptance_validator/spec_helper.rb +0 -7
- data/spec_legacy/integration/automatic_validation/custom_messages_for_inferred_validation_spec.rb +0 -57
- data/spec_legacy/integration/automatic_validation/disabling_inferred_validation_spec.rb +0 -49
- data/spec_legacy/integration/automatic_validation/inferred_boolean_properties_validation_spec.rb +0 -100
- data/spec_legacy/integration/automatic_validation/inferred_float_property_validation_spec.rb +0 -45
- data/spec_legacy/integration/automatic_validation/inferred_format_validation_spec.rb +0 -35
- data/spec_legacy/integration/automatic_validation/inferred_integer_properties_validation_spec.rb +0 -70
- data/spec_legacy/integration/automatic_validation/inferred_length_validation_spec.rb +0 -142
- data/spec_legacy/integration/automatic_validation/inferred_presence_validation_spec.rb +0 -45
- data/spec_legacy/integration/automatic_validation/inferred_primitive_validation_spec.rb +0 -22
- data/spec_legacy/integration/automatic_validation/inferred_uniqueness_validation_spec.rb +0 -48
- data/spec_legacy/integration/automatic_validation/inferred_within_validation_spec.rb +0 -35
- data/spec_legacy/integration/automatic_validation/spec_helper.rb +0 -57
- data/spec_legacy/integration/block_validator/block_validator_spec.rb +0 -32
- data/spec_legacy/integration/block_validator/spec_helper.rb +0 -5
- data/spec_legacy/integration/conditional_validation/if_condition_spec.rb +0 -63
- data/spec_legacy/integration/conditional_validation/spec_helper.rb +0 -5
- data/spec_legacy/integration/confirmation_validator/confirmation_validator_spec.rb +0 -76
- data/spec_legacy/integration/confirmation_validator/spec_helper.rb +0 -5
- data/spec_legacy/integration/datamapper_models/association_validation_spec.rb +0 -29
- data/spec_legacy/integration/datamapper_models/inheritance_spec.rb +0 -82
- data/spec_legacy/integration/dirty_attributes/dirty_attributes_spec.rb +0 -13
- data/spec_legacy/integration/duplicated_validations/duplicated_validations_spec.rb +0 -24
- data/spec_legacy/integration/duplicated_validations/spec_helper.rb +0 -5
- data/spec_legacy/integration/format_validator/email_format_validator_spec.rb +0 -139
- data/spec_legacy/integration/format_validator/format_validator_spec.rb +0 -64
- data/spec_legacy/integration/format_validator/regexp_validator_spec.rb +0 -33
- data/spec_legacy/integration/format_validator/spec_helper.rb +0 -5
- data/spec_legacy/integration/format_validator/url_format_validator_spec.rb +0 -93
- data/spec_legacy/integration/length_validator/default_value_spec.rb +0 -14
- data/spec_legacy/integration/length_validator/equality_spec.rb +0 -87
- data/spec_legacy/integration/length_validator/error_message_spec.rb +0 -22
- data/spec_legacy/integration/length_validator/maximum_spec.rb +0 -49
- data/spec_legacy/integration/length_validator/minimum_spec.rb +0 -54
- data/spec_legacy/integration/length_validator/range_spec.rb +0 -87
- data/spec_legacy/integration/length_validator/spec_helper.rb +0 -7
- data/spec_legacy/integration/method_validator/method_validator_spec.rb +0 -242
- data/spec_legacy/integration/method_validator/spec_helper.rb +0 -5
- data/spec_legacy/integration/numeric_validator/equality_with_float_type_spec.rb +0 -65
- data/spec_legacy/integration/numeric_validator/equality_with_integer_type_spec.rb +0 -41
- data/spec_legacy/integration/numeric_validator/float_type_spec.rb +0 -90
- data/spec_legacy/integration/numeric_validator/gt_with_float_type_spec.rb +0 -37
- data/spec_legacy/integration/numeric_validator/gte_with_float_type_spec.rb +0 -37
- data/spec_legacy/integration/numeric_validator/integer_only_true_spec.rb +0 -91
- data/spec_legacy/integration/numeric_validator/integer_type_spec.rb +0 -86
- data/spec_legacy/integration/numeric_validator/lt_with_float_type_spec.rb +0 -37
- data/spec_legacy/integration/numeric_validator/lte_with_float_type_spec.rb +0 -37
- data/spec_legacy/integration/numeric_validator/spec_helper.rb +0 -5
- data/spec_legacy/integration/primitive_validator/primitive_validator_spec.rb +0 -92
- data/spec_legacy/integration/primitive_validator/spec_helper.rb +0 -5
- data/spec_legacy/integration/pure_ruby_objects/plain_old_ruby_object_validation_spec.rb +0 -118
- data/spec_legacy/integration/required_field_validator/association_spec.rb +0 -69
- data/spec_legacy/integration/required_field_validator/boolean_type_value_spec.rb +0 -164
- data/spec_legacy/integration/required_field_validator/date_type_value_spec.rb +0 -127
- data/spec_legacy/integration/required_field_validator/datetime_type_value_spec.rb +0 -127
- data/spec_legacy/integration/required_field_validator/float_type_value_spec.rb +0 -131
- data/spec_legacy/integration/required_field_validator/integer_type_value_spec.rb +0 -99
- data/spec_legacy/integration/required_field_validator/plain_old_ruby_object_spec.rb +0 -35
- data/spec_legacy/integration/required_field_validator/shared_examples.rb +0 -26
- data/spec_legacy/integration/required_field_validator/spec_helper.rb +0 -7
- data/spec_legacy/integration/required_field_validator/string_type_value_spec.rb +0 -167
- data/spec_legacy/integration/required_field_validator/text_type_value_spec.rb +0 -49
- data/spec_legacy/integration/shared/default_validation_context.rb +0 -13
- data/spec_legacy/integration/shared/valid_and_invalid_model.rb +0 -35
- data/spec_legacy/integration/uniqueness_validator/spec_helper.rb +0 -5
- data/spec_legacy/integration/uniqueness_validator/uniqueness_validator_spec.rb +0 -116
- data/spec_legacy/integration/within_validator/spec_helper.rb +0 -5
- data/spec_legacy/integration/within_validator/within_validator_spec.rb +0 -168
- data/spec_legacy/public/resource_spec.rb +0 -105
- data/spec_legacy/spec.opts +0 -4
- data/spec_legacy/spec_helper.rb +0 -29
- data/spec_legacy/unit/contextual_validators/emptiness_spec.rb +0 -50
- data/spec_legacy/unit/contextual_validators/execution_spec.rb +0 -48
- data/spec_legacy/unit/contextual_validators/spec_helper.rb +0 -37
- data/spec_legacy/unit/generic_validator/equality_operator_spec.rb +0 -26
- data/spec_legacy/unit/generic_validator/optional_spec.rb +0 -54
- data/spec_legacy/unit/validators/within_validator_spec.rb +0 -23
- data/spec_legacy/unit/violation_set/adding_spec.rb +0 -54
- data/spec_legacy/unit/violation_set/emptiness_spec.rb +0 -38
- data/spec_legacy/unit/violation_set/enumerable_spec.rb +0 -32
- data/spec_legacy/unit/violation_set/reading_spec.rb +0 -35
- data/spec_legacy/unit/violation_set/respond_to_spec.rb +0 -15
- data/tasks/spec.rake +0 -38
- data/tasks/yard.rake +0 -9
- data/tasks/yardstick.rake +0 -19
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.2
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
2
|
|
|
3
3
|
require 'forwardable'
|
|
4
|
-
require 'aequitas/support/
|
|
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
|
|
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
|
-
|
|
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
|
|
data/lib/aequitas/macros.rb
CHANGED
|
@@ -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.
|
|
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 :
|
|
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
|
|
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
|
|
105
|
+
end # class DefaultStatic
|
|
93
106
|
|
|
94
|
-
class DefaultI18n <
|
|
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)
|
data/lib/aequitas/rule.rb
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
2
|
|
|
3
3
|
require 'aequitas/support/blank'
|
|
4
|
-
require 'aequitas/support/
|
|
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
|
|
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)
|
data/lib/aequitas/rule/block.rb
CHANGED
|
@@ -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
|
data/lib/aequitas/rule/format.rb
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
34
|
-
format = options.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8
|
-
class Proc <
|
|
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
|
-
|
|
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 #
|
|
20
|
+
end # class Format
|
|
27
21
|
end # class Rule
|
|
28
22
|
end # module Aequitas
|