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.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.rdoc +125 -0
- data/Rakefile +25 -0
- data/VERSION +1 -0
- data/aequitas.gemspec +20 -0
- data/lib/aequitas.rb +80 -0
- data/lib/aequitas/class_methods.rb +26 -0
- data/lib/aequitas/context.rb +53 -0
- data/lib/aequitas/contextual_rule_set.rb +221 -0
- data/lib/aequitas/exceptions.rb +10 -0
- data/lib/aequitas/macros.rb +466 -0
- data/lib/aequitas/message_transformer.rb +127 -0
- data/lib/aequitas/rule.rb +153 -0
- data/lib/aequitas/rule/absence.rb +14 -0
- data/lib/aequitas/rule/absence/blank.rb +21 -0
- data/lib/aequitas/rule/absence/nil.rb +21 -0
- data/lib/aequitas/rule/acceptance.rb +36 -0
- data/lib/aequitas/rule/block.rb +33 -0
- data/lib/aequitas/rule/confirmation.rb +41 -0
- data/lib/aequitas/rule/format.rb +81 -0
- data/lib/aequitas/rule/format/proc.rb +28 -0
- data/lib/aequitas/rule/format/regexp.rb +44 -0
- data/lib/aequitas/rule/formats/email.rb +52 -0
- data/lib/aequitas/rule/formats/url.rb +14 -0
- data/lib/aequitas/rule/guard.rb +51 -0
- data/lib/aequitas/rule/length.rb +87 -0
- data/lib/aequitas/rule/length/equal.rb +46 -0
- data/lib/aequitas/rule/length/maximum.rb +46 -0
- data/lib/aequitas/rule/length/minimum.rb +46 -0
- data/lib/aequitas/rule/length/range.rb +46 -0
- data/lib/aequitas/rule/method.rb +31 -0
- data/lib/aequitas/rule/numericalness.rb +85 -0
- data/lib/aequitas/rule/numericalness/equal.rb +30 -0
- data/lib/aequitas/rule/numericalness/greater_than.rb +30 -0
- data/lib/aequitas/rule/numericalness/greater_than_or_equal.rb +30 -0
- data/lib/aequitas/rule/numericalness/integer.rb +37 -0
- data/lib/aequitas/rule/numericalness/less_than.rb +30 -0
- data/lib/aequitas/rule/numericalness/less_than_or_equal.rb +30 -0
- data/lib/aequitas/rule/numericalness/non_integer.rb +64 -0
- data/lib/aequitas/rule/numericalness/not_equal.rb +30 -0
- data/lib/aequitas/rule/presence.rb +14 -0
- data/lib/aequitas/rule/presence/not_blank.rb +21 -0
- data/lib/aequitas/rule/presence/not_nil.rb +21 -0
- data/lib/aequitas/rule/primitive_type.rb +28 -0
- data/lib/aequitas/rule/skip_condition.rb +104 -0
- data/lib/aequitas/rule/within.rb +28 -0
- data/lib/aequitas/rule/within/range.rb +53 -0
- data/lib/aequitas/rule/within/range/bounded.rb +25 -0
- data/lib/aequitas/rule/within/range/unbounded_begin.rb +25 -0
- data/lib/aequitas/rule/within/range/unbounded_end.rb +25 -0
- data/lib/aequitas/rule/within/set.rb +39 -0
- data/lib/aequitas/rule_set.rb +80 -0
- data/lib/aequitas/support/blank.rb +22 -0
- data/lib/aequitas/support/equalizable.rb +113 -0
- data/lib/aequitas/support/ordered_hash.rb +438 -0
- data/lib/aequitas/version.rb +5 -0
- data/lib/aequitas/violation.rb +116 -0
- data/lib/aequitas/violation_set.rb +123 -0
- data/lib/aequitas/virtus.rb +29 -0
- data/lib/aequitas/virtus/inline_attribute_rule_extractor.rb +41 -0
- data/lib/aequitas/virtus/inline_attribute_rule_extractor/boolean.rb +17 -0
- data/lib/aequitas/virtus/inline_attribute_rule_extractor/object.rb +25 -0
- data/lib/aequitas/virtus/inline_attribute_rule_extractor/string.rb +27 -0
- data/spec/integration/aequitas/macros/validates_absence_of_spec.rb +19 -0
- data/spec/integration/aequitas/macros/validates_acceptance_of_spec.rb +19 -0
- data/spec/integration/aequitas/macros/validates_confirmation_of_spec.rb +25 -0
- data/spec/integration/aequitas/macros/validates_format_of_spec.rb +87 -0
- data/spec/integration/aequitas/macros/validates_length_of.rb +77 -0
- data/spec/integration/aequitas/macros/validates_numericalness_of_spec.rb +221 -0
- data/spec/integration/aequitas/macros/validates_presence_of_spec.rb +19 -0
- data/spec/integration/aequitas/macros/validates_with_block.rb +23 -0
- data/spec/integration/aequitas/macros/validates_with_method.rb +19 -0
- data/spec/integration/aequitas/macros/validates_within.rb +87 -0
- data/spec/integration/shared/macros/integration_spec.rb +67 -0
- data/spec/integration/virtus/boolean/presence_spec.rb +49 -0
- data/spec/integration/virtus/string/format/email_address_spec.rb +55 -0
- data/spec/integration/virtus/string/format/regexp_spec.rb +55 -0
- data/spec/integration/virtus/string/format/url_spec.rb +55 -0
- data/spec/integration/virtus/string/length/equal_spec.rb +49 -0
- data/spec/integration/virtus/string/length/range_spec.rb +49 -0
- data/spec/integration/virtus/string/presence_spec.rb +49 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/suite.rb +5 -0
- data/spec/unit/aequitas/rule/absence/blank_spec.rb +45 -0
- data/spec/unit/aequitas/rule/acceptance_spec.rb +71 -0
- data/spec/unit/aequitas/rule/confirmation_spec.rb +80 -0
- data/spec/unit/aequitas/rule/guard_spec.rb +120 -0
- data/spec/unit/aequitas/rule/skip_condition_spec.rb +170 -0
- data/spec/unit/aequitas/rule_spec.rb +40 -0
- data/spec/unit/aequitas/support/blank_spec.rb +83 -0
- data/spec/unit/aequitas/support/equalizable/equalizer_spec.rb +21 -0
- data/spec/unit/aequitas/support/equalizable_spec.rb +67 -0
- data/spec/unit/aequitas/violation_set_spec.rb +154 -0
- data/spec_legacy/fixtures/barcode.rb +40 -0
- data/spec_legacy/fixtures/basketball_court.rb +58 -0
- data/spec_legacy/fixtures/basketball_player.rb +34 -0
- data/spec_legacy/fixtures/beta_tester_account.rb +33 -0
- data/spec_legacy/fixtures/bill_of_landing.rb +47 -0
- data/spec_legacy/fixtures/boat_dock.rb +26 -0
- data/spec_legacy/fixtures/city.rb +24 -0
- data/spec_legacy/fixtures/company.rb +93 -0
- data/spec_legacy/fixtures/corporate_world.rb +39 -0
- data/spec_legacy/fixtures/country.rb +24 -0
- data/spec_legacy/fixtures/ethernet_frame.rb +56 -0
- data/spec_legacy/fixtures/event.rb +44 -0
- data/spec_legacy/fixtures/g3_concert.rb +57 -0
- data/spec_legacy/fixtures/jabberwock.rb +27 -0
- data/spec_legacy/fixtures/kayak.rb +28 -0
- data/spec_legacy/fixtures/lernean_hydra.rb +39 -0
- data/spec_legacy/fixtures/llama_spaceship.rb +15 -0
- data/spec_legacy/fixtures/mathematical_function.rb +34 -0
- data/spec_legacy/fixtures/memory_object.rb +30 -0
- data/spec_legacy/fixtures/mittelschnauzer.rb +39 -0
- data/spec_legacy/fixtures/motor_launch.rb +21 -0
- data/spec_legacy/fixtures/multibyte.rb +16 -0
- data/spec_legacy/fixtures/page.rb +32 -0
- data/spec_legacy/fixtures/phone_number.rb +28 -0
- data/spec_legacy/fixtures/pirogue.rb +28 -0
- data/spec_legacy/fixtures/programming_language.rb +83 -0
- data/spec_legacy/fixtures/reservation.rb +38 -0
- data/spec_legacy/fixtures/scm_operation.rb +56 -0
- data/spec_legacy/fixtures/sms_message.rb +22 -0
- data/spec_legacy/fixtures/udp_packet.rb +49 -0
- data/spec_legacy/integration/absent_field_validator/absent_field_validator_spec.rb +90 -0
- data/spec_legacy/integration/absent_field_validator/spec_helper.rb +7 -0
- data/spec_legacy/integration/acceptance_validator/acceptance_validator_spec.rb +196 -0
- data/spec_legacy/integration/acceptance_validator/spec_helper.rb +7 -0
- data/spec_legacy/integration/automatic_validation/custom_messages_for_inferred_validation_spec.rb +57 -0
- data/spec_legacy/integration/automatic_validation/disabling_inferred_validation_spec.rb +49 -0
- data/spec_legacy/integration/automatic_validation/inferred_boolean_properties_validation_spec.rb +100 -0
- data/spec_legacy/integration/automatic_validation/inferred_float_property_validation_spec.rb +45 -0
- data/spec_legacy/integration/automatic_validation/inferred_format_validation_spec.rb +35 -0
- data/spec_legacy/integration/automatic_validation/inferred_integer_properties_validation_spec.rb +70 -0
- data/spec_legacy/integration/automatic_validation/inferred_length_validation_spec.rb +142 -0
- data/spec_legacy/integration/automatic_validation/inferred_presence_validation_spec.rb +45 -0
- data/spec_legacy/integration/automatic_validation/inferred_primitive_validation_spec.rb +22 -0
- data/spec_legacy/integration/automatic_validation/inferred_uniqueness_validation_spec.rb +48 -0
- data/spec_legacy/integration/automatic_validation/inferred_within_validation_spec.rb +35 -0
- data/spec_legacy/integration/automatic_validation/spec_helper.rb +57 -0
- data/spec_legacy/integration/block_validator/block_validator_spec.rb +32 -0
- data/spec_legacy/integration/block_validator/spec_helper.rb +5 -0
- data/spec_legacy/integration/conditional_validation/if_condition_spec.rb +63 -0
- data/spec_legacy/integration/conditional_validation/spec_helper.rb +5 -0
- data/spec_legacy/integration/confirmation_validator/confirmation_validator_spec.rb +76 -0
- data/spec_legacy/integration/confirmation_validator/spec_helper.rb +5 -0
- data/spec_legacy/integration/datamapper_models/association_validation_spec.rb +29 -0
- data/spec_legacy/integration/datamapper_models/inheritance_spec.rb +82 -0
- data/spec_legacy/integration/dirty_attributes/dirty_attributes_spec.rb +13 -0
- data/spec_legacy/integration/duplicated_validations/duplicated_validations_spec.rb +24 -0
- data/spec_legacy/integration/duplicated_validations/spec_helper.rb +5 -0
- data/spec_legacy/integration/format_validator/email_format_validator_spec.rb +139 -0
- data/spec_legacy/integration/format_validator/format_validator_spec.rb +64 -0
- data/spec_legacy/integration/format_validator/regexp_validator_spec.rb +33 -0
- data/spec_legacy/integration/format_validator/spec_helper.rb +5 -0
- data/spec_legacy/integration/format_validator/url_format_validator_spec.rb +93 -0
- data/spec_legacy/integration/length_validator/default_value_spec.rb +14 -0
- data/spec_legacy/integration/length_validator/equality_spec.rb +87 -0
- data/spec_legacy/integration/length_validator/error_message_spec.rb +22 -0
- data/spec_legacy/integration/length_validator/maximum_spec.rb +49 -0
- data/spec_legacy/integration/length_validator/minimum_spec.rb +54 -0
- data/spec_legacy/integration/length_validator/range_spec.rb +87 -0
- data/spec_legacy/integration/length_validator/spec_helper.rb +7 -0
- data/spec_legacy/integration/method_validator/method_validator_spec.rb +242 -0
- data/spec_legacy/integration/method_validator/spec_helper.rb +5 -0
- data/spec_legacy/integration/numeric_validator/equality_with_float_type_spec.rb +65 -0
- data/spec_legacy/integration/numeric_validator/equality_with_integer_type_spec.rb +41 -0
- data/spec_legacy/integration/numeric_validator/float_type_spec.rb +90 -0
- data/spec_legacy/integration/numeric_validator/gt_with_float_type_spec.rb +37 -0
- data/spec_legacy/integration/numeric_validator/gte_with_float_type_spec.rb +37 -0
- data/spec_legacy/integration/numeric_validator/integer_only_true_spec.rb +91 -0
- data/spec_legacy/integration/numeric_validator/integer_type_spec.rb +86 -0
- data/spec_legacy/integration/numeric_validator/lt_with_float_type_spec.rb +37 -0
- data/spec_legacy/integration/numeric_validator/lte_with_float_type_spec.rb +37 -0
- data/spec_legacy/integration/numeric_validator/spec_helper.rb +5 -0
- data/spec_legacy/integration/primitive_validator/primitive_validator_spec.rb +92 -0
- data/spec_legacy/integration/primitive_validator/spec_helper.rb +5 -0
- data/spec_legacy/integration/pure_ruby_objects/plain_old_ruby_object_validation_spec.rb +118 -0
- data/spec_legacy/integration/required_field_validator/association_spec.rb +69 -0
- data/spec_legacy/integration/required_field_validator/boolean_type_value_spec.rb +164 -0
- data/spec_legacy/integration/required_field_validator/date_type_value_spec.rb +127 -0
- data/spec_legacy/integration/required_field_validator/datetime_type_value_spec.rb +127 -0
- data/spec_legacy/integration/required_field_validator/float_type_value_spec.rb +131 -0
- data/spec_legacy/integration/required_field_validator/integer_type_value_spec.rb +99 -0
- data/spec_legacy/integration/required_field_validator/plain_old_ruby_object_spec.rb +35 -0
- data/spec_legacy/integration/required_field_validator/shared_examples.rb +26 -0
- data/spec_legacy/integration/required_field_validator/spec_helper.rb +7 -0
- data/spec_legacy/integration/required_field_validator/string_type_value_spec.rb +167 -0
- data/spec_legacy/integration/required_field_validator/text_type_value_spec.rb +49 -0
- data/spec_legacy/integration/shared/default_validation_context.rb +13 -0
- data/spec_legacy/integration/shared/valid_and_invalid_model.rb +35 -0
- data/spec_legacy/integration/uniqueness_validator/spec_helper.rb +5 -0
- data/spec_legacy/integration/uniqueness_validator/uniqueness_validator_spec.rb +116 -0
- data/spec_legacy/integration/within_validator/spec_helper.rb +5 -0
- data/spec_legacy/integration/within_validator/within_validator_spec.rb +168 -0
- data/spec_legacy/public/resource_spec.rb +105 -0
- data/spec_legacy/spec.opts +4 -0
- data/spec_legacy/spec_helper.rb +29 -0
- data/spec_legacy/unit/contextual_validators/emptiness_spec.rb +50 -0
- data/spec_legacy/unit/contextual_validators/execution_spec.rb +48 -0
- data/spec_legacy/unit/contextual_validators/spec_helper.rb +37 -0
- data/spec_legacy/unit/generic_validator/equality_operator_spec.rb +26 -0
- data/spec_legacy/unit/generic_validator/optional_spec.rb +54 -0
- data/spec_legacy/unit/validators/within_validator_spec.rb +23 -0
- data/spec_legacy/unit/violation_set/adding_spec.rb +54 -0
- data/spec_legacy/unit/violation_set/emptiness_spec.rb +38 -0
- data/spec_legacy/unit/violation_set/enumerable_spec.rb +32 -0
- data/spec_legacy/unit/violation_set/reading_spec.rb +35 -0
- data/spec_legacy/unit/violation_set/respond_to_spec.rb +15 -0
- data/tasks/spec.rake +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +302 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
module Aequitas
|
|
4
|
+
# Transforms Violations to error message strings.
|
|
5
|
+
#
|
|
6
|
+
# @abstract
|
|
7
|
+
# Subclass and override {#transform} to implement a custom message
|
|
8
|
+
# transformer. Use {Violation.message_transformer=} to set a new
|
|
9
|
+
# message transformer or pass the transformer to {Violation#message}.
|
|
10
|
+
class MessageTransformer
|
|
11
|
+
def self.default
|
|
12
|
+
defined?(I18n) ? DefaultI18n.new : Default.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Transforms the specified Violation to an error message string.
|
|
16
|
+
#
|
|
17
|
+
# @param [Violation] violation
|
|
18
|
+
# The Violation to transform.
|
|
19
|
+
#
|
|
20
|
+
# @return [String]
|
|
21
|
+
# The transformed message.
|
|
22
|
+
#
|
|
23
|
+
# @raise [ArgumentError]
|
|
24
|
+
# +violation+ is +nil+.
|
|
25
|
+
def transform(violation)
|
|
26
|
+
raise NotImplementedError, "#{self.class}#transform has not been implemented"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Default < self
|
|
30
|
+
@error_messages = {
|
|
31
|
+
:nil => '%s must not be nil',
|
|
32
|
+
:blank => '%s must not be blank',
|
|
33
|
+
:not_nil => '%s must be nil',
|
|
34
|
+
:not_blank => '%s must be blank',
|
|
35
|
+
:invalid => '%s has an invalid format',
|
|
36
|
+
:inclusion => '%s must be one of %s',
|
|
37
|
+
:accepted => '%s is not accepted',
|
|
38
|
+
:confirmation => '%s does not match the confirmation',
|
|
39
|
+
:length_between => '%s must be between %s and %s characters long',
|
|
40
|
+
:too_long => '%s must be at most %s characters long',
|
|
41
|
+
:too_short => '%s must be at least %s characters long',
|
|
42
|
+
:wrong_length => '%s must be %s characters long',
|
|
43
|
+
:not_a_number => '%s must be a number',
|
|
44
|
+
:not_an_integer => '%s must be an integer',
|
|
45
|
+
:greater_than => '%s must be greater than %s',
|
|
46
|
+
:greater_than_or_equal_to => '%s must be greater than or equal to %s',
|
|
47
|
+
:equal_to => '%s must be equal to %s',
|
|
48
|
+
:not_equal_to => '%s must not be equal to %s',
|
|
49
|
+
:less_than => '%s must be less than %s',
|
|
50
|
+
:less_than_or_equal_to => '%s must be less than or equal to %s',
|
|
51
|
+
:value_between => '%s must be between %s and %s',
|
|
52
|
+
:not_unique => '%s is already taken',
|
|
53
|
+
:primitive => '%s must be of type %s'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class << self
|
|
57
|
+
# Gets the hash of error messages used to transform violations.
|
|
58
|
+
#
|
|
59
|
+
# @return [Hash{Symbol=>String}]
|
|
60
|
+
attr_reader :error_messages
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Merges the specified +error_messages+ hash into the internal hash of
|
|
64
|
+
# error messages.
|
|
65
|
+
#
|
|
66
|
+
# @param [Hash{Symbol=>String}] error_messages
|
|
67
|
+
# The error messages to be merged.
|
|
68
|
+
def self.error_messages=(error_messages)
|
|
69
|
+
unless error_messages.is_a?(Hash)
|
|
70
|
+
raise ArgumentError, "+error_messages+ must be a hash"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
self.error_messages.merge!(error_messages)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.error_message(violation_type, attribute_name, violation_values)
|
|
77
|
+
if message = self.error_messages[violation_type]
|
|
78
|
+
attribute_name = DataMapper::Inflector.humanize(attribute_name)
|
|
79
|
+
message % [attribute_name, *violation_values].flatten
|
|
80
|
+
else
|
|
81
|
+
violation_type.to_s
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def transform(violation)
|
|
86
|
+
raise ArgumentError, "+violation+ must be specified" if violation.nil?
|
|
87
|
+
|
|
88
|
+
attribute_name = violation.attribute_name
|
|
89
|
+
|
|
90
|
+
self.class.error_message(violation.type, attribute_name, violation.values)
|
|
91
|
+
end
|
|
92
|
+
end # class Default
|
|
93
|
+
|
|
94
|
+
class DefaultI18n < self
|
|
95
|
+
def initialize
|
|
96
|
+
require 'i18n'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def transform(violation)
|
|
100
|
+
raise ArgumentError, "+violation+ must be specified" if violation.nil?
|
|
101
|
+
|
|
102
|
+
resource = violation.resource
|
|
103
|
+
model_name = resource.model.model_name
|
|
104
|
+
attribute_name = violation.attribute_name
|
|
105
|
+
# TODO: Include attribute value in Violation; it may have changed by now
|
|
106
|
+
# attribute_value = violation.attribute_value
|
|
107
|
+
|
|
108
|
+
options = {
|
|
109
|
+
:model => ::I18n.translate("models.#{model_name}"),
|
|
110
|
+
:attribute => ::I18n.translate("attributes.#{model_name}.#{attribute_name}"),
|
|
111
|
+
# TODO: Include attribute value in Violation; it may have changed by now
|
|
112
|
+
:value => resource.validation_attribute_value(attribute_name)
|
|
113
|
+
}.merge(violation.info)
|
|
114
|
+
|
|
115
|
+
::I18n.translate("#{i18n_namespace}.#{violation.type}", options)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# configure the I18n namespace used for looking up error message text
|
|
119
|
+
attr_writer :i18n_namespace
|
|
120
|
+
|
|
121
|
+
def i18n_namespace
|
|
122
|
+
@i18n_namespace || 'aequitas.validation.errors'
|
|
123
|
+
end
|
|
124
|
+
end # class DefaultI18n
|
|
125
|
+
|
|
126
|
+
end # class MessageTransformer
|
|
127
|
+
end # module Aequitas
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'aequitas/support/blank'
|
|
4
|
+
require 'aequitas/support/equalizable'
|
|
5
|
+
require 'aequitas/rule/guard'
|
|
6
|
+
require 'aequitas/rule/skip_condition'
|
|
7
|
+
require 'aequitas/violation'
|
|
8
|
+
|
|
9
|
+
module Aequitas
|
|
10
|
+
class Rule
|
|
11
|
+
extend Equalizable
|
|
12
|
+
|
|
13
|
+
equalize_on :attribute_name, :custom_message, :guard, :skip_condition
|
|
14
|
+
|
|
15
|
+
# @api private
|
|
16
|
+
attr_reader :attribute_name
|
|
17
|
+
# @api private
|
|
18
|
+
attr_reader :custom_message
|
|
19
|
+
# @api private
|
|
20
|
+
attr_reader :guard
|
|
21
|
+
# @api private
|
|
22
|
+
attr_reader :skip_condition
|
|
23
|
+
|
|
24
|
+
# Get the validators for the given attribute_name and options
|
|
25
|
+
#
|
|
26
|
+
# @param [Symbol] attribute_name
|
|
27
|
+
# the name of the attribute to which the returned validators will be bound
|
|
28
|
+
# @param [Hash] options
|
|
29
|
+
# the options with which to configure the returned validators
|
|
30
|
+
#
|
|
31
|
+
# @return [#each(Rule)]
|
|
32
|
+
# a collection of validators which collectively
|
|
33
|
+
#
|
|
34
|
+
def self.rules_for(attribute_name, options, &block)
|
|
35
|
+
Array(new(attribute_name, options, &block))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Construct a validator. Capture the :if and :unless clauses when
|
|
39
|
+
# present.
|
|
40
|
+
#
|
|
41
|
+
# @param [String, Symbol] attribute_name
|
|
42
|
+
# The name of the attribute to validate.
|
|
43
|
+
#
|
|
44
|
+
# TODO: remove Hash as a value for :message
|
|
45
|
+
# (see Violation#[] in backwards.rb)
|
|
46
|
+
#
|
|
47
|
+
# @option [String, Hash] :message
|
|
48
|
+
# A custom message that will be used for any violations of this rule
|
|
49
|
+
# @option [Symbol, Proc] :if
|
|
50
|
+
# The name of a method (on the valiated resource) or a Proc to call
|
|
51
|
+
# (with the resource) to determine if the rule should be applied.
|
|
52
|
+
# @option [Symbol, Proc] :unless
|
|
53
|
+
# The name of a method (on the valiated resource) or a Proc to call
|
|
54
|
+
# (with the resource) to determine if the rule should *not* be applied.
|
|
55
|
+
# @option [Boolean] :allow_nil
|
|
56
|
+
# Whether to skip applying this rule on nil values
|
|
57
|
+
# @option [Boolean] :allow_blank
|
|
58
|
+
# Whether to skip applying this rule on blank values
|
|
59
|
+
def initialize(attribute_name, options = {})
|
|
60
|
+
@attribute_name = attribute_name
|
|
61
|
+
@custom_message = options.fetch(:message, nil)
|
|
62
|
+
@guard = options.fetch(:guard) { Guard.new(options) }
|
|
63
|
+
@skip_condition = options.fetch(:skip_condition) { SkipCondition.new(options) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Validate the +resource+ arg against this Rule
|
|
67
|
+
#
|
|
68
|
+
# @param [Object] resource
|
|
69
|
+
# the target object to be validated
|
|
70
|
+
#
|
|
71
|
+
# @return [NilClass, Violation]
|
|
72
|
+
# NilClass if +resource+ is valid
|
|
73
|
+
# Violation with additional info if +resource+ is invalid
|
|
74
|
+
def validate(resource)
|
|
75
|
+
if valid?(resource)
|
|
76
|
+
nil
|
|
77
|
+
else
|
|
78
|
+
Violation.new(resource, custom_message, self)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Determines if this validator should be run against the resource
|
|
83
|
+
# by delegating to the guard configured for this rule
|
|
84
|
+
def execute?(resource)
|
|
85
|
+
guard.allow?(resource)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Test the value to see if it is blank or nil, and if it is allowed.
|
|
89
|
+
# Note that allowing blank without explicitly denying nil allows nil
|
|
90
|
+
# values, since nil.blank? is true.
|
|
91
|
+
#
|
|
92
|
+
# @param [Object] value
|
|
93
|
+
# The value to test.
|
|
94
|
+
#
|
|
95
|
+
# @return [Boolean]
|
|
96
|
+
# true if blank/nil is allowed, and the value is blank/nil.
|
|
97
|
+
#
|
|
98
|
+
# @api private
|
|
99
|
+
def skip?(value)
|
|
100
|
+
skip_condition.skip?(value)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def attribute_value(resource)
|
|
104
|
+
resource.validation_attribute_value(attribute_name)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# @api private
|
|
108
|
+
def violation_info(resource)
|
|
109
|
+
Hash[ violation_data(resource) ]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# @api private
|
|
113
|
+
def violation_values(resource)
|
|
114
|
+
violation_data(resource).map { |(_, value)| value }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# @api private
|
|
118
|
+
def violation_data(resource)
|
|
119
|
+
[ ]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
alias_method :to_s, :inspect
|
|
123
|
+
|
|
124
|
+
private
|
|
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
|
+
def assert_kind_of(name, value, *klasses)
|
|
148
|
+
klasses.each { |k| return if value.kind_of?(k) }
|
|
149
|
+
raise ArgumentError, "+#{name}+ should be #{klasses.map { |k| k.name } * ' or '}, but was #{value.class.name}", caller(2)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end # class Rule
|
|
153
|
+
end # module Aequitas
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'aequitas/rule'
|
|
4
|
+
|
|
5
|
+
module Aequitas
|
|
6
|
+
class Rule
|
|
7
|
+
class Absence < Rule
|
|
8
|
+
|
|
9
|
+
end # class Absence
|
|
10
|
+
end # class Rule
|
|
11
|
+
end # module Aequitas
|
|
12
|
+
|
|
13
|
+
require 'aequitas/rule/absence/blank'
|
|
14
|
+
require 'aequitas/rule/absence/nil'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'aequitas/rule/absence'
|
|
4
|
+
|
|
5
|
+
module Aequitas
|
|
6
|
+
class Rule
|
|
7
|
+
class Absence
|
|
8
|
+
class Blank < Absence
|
|
9
|
+
|
|
10
|
+
def valid?(resource)
|
|
11
|
+
Aequitas.blank?(attribute_value(resource))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def violation_type(resource)
|
|
15
|
+
:not_blank
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end # class Blank
|
|
19
|
+
end # class Absence
|
|
20
|
+
end # class Rule
|
|
21
|
+
end # module Aequitas
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'aequitas/rule/absence'
|
|
4
|
+
|
|
5
|
+
module Aequitas
|
|
6
|
+
class Rule
|
|
7
|
+
class Absence
|
|
8
|
+
class Nil < Absence
|
|
9
|
+
|
|
10
|
+
def valid?(resource)
|
|
11
|
+
attribute_value(resource).nil?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def violation_type(resource)
|
|
15
|
+
:not_nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end # class Nil
|
|
19
|
+
end # class Absence
|
|
20
|
+
end # class Rule
|
|
21
|
+
end # module Aequitas
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'aequitas/rule'
|
|
4
|
+
|
|
5
|
+
module Aequitas
|
|
6
|
+
class Rule
|
|
7
|
+
# TODO: update this to inherit from Rule::Within::Set
|
|
8
|
+
class Acceptance < Rule
|
|
9
|
+
|
|
10
|
+
equalize_on *(superclass.equalizer.keys + [:accept])
|
|
11
|
+
|
|
12
|
+
DEFAULT_ACCEPTED_VALUES = [ '1', 1, 'true', true, 't' ]
|
|
13
|
+
|
|
14
|
+
attr_reader :accept
|
|
15
|
+
|
|
16
|
+
def initialize(attribute_name, options = {})
|
|
17
|
+
super
|
|
18
|
+
|
|
19
|
+
@accept = Array(options.fetch(:accept, DEFAULT_ACCEPTED_VALUES))
|
|
20
|
+
|
|
21
|
+
skip_condition.default_to_allowing_nil!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def valid?(resource)
|
|
25
|
+
value = attribute_value(resource)
|
|
26
|
+
|
|
27
|
+
skip?(value) || accept.include?(value)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def violation_type(resource)
|
|
31
|
+
:accepted
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end # class Acceptance
|
|
35
|
+
end # class Rule
|
|
36
|
+
end # module Aequitas
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'aequitas/rule'
|
|
4
|
+
|
|
5
|
+
module Aequitas
|
|
6
|
+
class Rule
|
|
7
|
+
class Block < Rule
|
|
8
|
+
|
|
9
|
+
attr_reader :block
|
|
10
|
+
|
|
11
|
+
def initialize(attribute_name, options, &block)
|
|
12
|
+
unless block_given?
|
|
13
|
+
raise ArgumentError, 'cannot initialize a Block validator without a block'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
super
|
|
17
|
+
|
|
18
|
+
@block = block
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def validate(resource)
|
|
22
|
+
result, error_message = resource.instance_eval(&self.block)
|
|
23
|
+
|
|
24
|
+
if result
|
|
25
|
+
nil
|
|
26
|
+
else
|
|
27
|
+
Violation.new(resource, error_message, self)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end # class Block
|
|
32
|
+
end # class Rule
|
|
33
|
+
end # module Aequitas
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'aequitas/rule'
|
|
4
|
+
|
|
5
|
+
module Aequitas
|
|
6
|
+
class Rule
|
|
7
|
+
class Confirmation < Rule
|
|
8
|
+
|
|
9
|
+
equalize_on *(superclass.equalizer.keys + [:confirmation_attribute_name])
|
|
10
|
+
|
|
11
|
+
attr_reader :confirmation_attribute_name
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def initialize(attribute_name, options = {})
|
|
15
|
+
super
|
|
16
|
+
|
|
17
|
+
@confirmation_attribute_name = options.fetch(:confirm) do
|
|
18
|
+
:"#{attribute_name}_confirmation"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
skip_condition.default_to_allowing_nil!
|
|
22
|
+
skip_condition.default_to_allowing_blank!
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def valid?(resource)
|
|
26
|
+
value = attribute_value(resource)
|
|
27
|
+
|
|
28
|
+
skip?(value) || value == confirmation_value(resource)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def confirmation_value(resource)
|
|
32
|
+
resource.instance_variable_get("@#{@confirmation_attribute_name}")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def violation_type(resource)
|
|
36
|
+
:confirmation
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end # class Confirmation
|
|
40
|
+
end # class Rule
|
|
41
|
+
end # module Aequitas
|