ardm-validations 1.2.0
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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.travis.yml +11 -0
- data/Gemfile +51 -0
- data/LICENSE +21 -0
- data/README.rdoc +122 -0
- data/Rakefile +4 -0
- data/ardm-validations.gemspec +28 -0
- data/lib/ardm-validations.rb +1 -0
- data/lib/dm-validations.rb +169 -0
- data/lib/dm-validations/auto_validate.rb +252 -0
- data/lib/dm-validations/context.rb +66 -0
- data/lib/dm-validations/contextual_validators.rb +220 -0
- data/lib/dm-validations/exceptions.rb +5 -0
- data/lib/dm-validations/formats/email.rb +65 -0
- data/lib/dm-validations/formats/url.rb +27 -0
- data/lib/dm-validations/support/object.rb +18 -0
- data/lib/dm-validations/support/ordered_hash.rb +434 -0
- data/lib/dm-validations/validation_errors.rb +137 -0
- data/lib/dm-validations/validators/absent_field_validator.rb +58 -0
- data/lib/dm-validations/validators/acceptance_validator.rb +79 -0
- data/lib/dm-validations/validators/block_validator.rb +61 -0
- data/lib/dm-validations/validators/confirmation_validator.rb +92 -0
- data/lib/dm-validations/validators/format_validator.rb +124 -0
- data/lib/dm-validations/validators/generic_validator.rb +184 -0
- data/lib/dm-validations/validators/length_validator.rb +249 -0
- data/lib/dm-validations/validators/method_validator.rb +64 -0
- data/lib/dm-validations/validators/numeric_validator.rb +182 -0
- data/lib/dm-validations/validators/primitive_validator.rb +58 -0
- data/lib/dm-validations/validators/required_field_validator.rb +83 -0
- data/lib/dm-validations/validators/uniqueness_validator.rb +67 -0
- data/lib/dm-validations/validators/within_validator.rb +74 -0
- data/lib/dm-validations/version.rb +5 -0
- data/spec/fixtures/barcode.rb +40 -0
- data/spec/fixtures/basketball_court.rb +58 -0
- data/spec/fixtures/basketball_player.rb +34 -0
- data/spec/fixtures/beta_tester_account.rb +33 -0
- data/spec/fixtures/bill_of_landing.rb +47 -0
- data/spec/fixtures/boat_dock.rb +26 -0
- data/spec/fixtures/city.rb +24 -0
- data/spec/fixtures/company.rb +93 -0
- data/spec/fixtures/corporate_world.rb +39 -0
- data/spec/fixtures/country.rb +24 -0
- data/spec/fixtures/ethernet_frame.rb +56 -0
- data/spec/fixtures/event.rb +44 -0
- data/spec/fixtures/g3_concert.rb +57 -0
- data/spec/fixtures/jabberwock.rb +27 -0
- data/spec/fixtures/kayak.rb +28 -0
- data/spec/fixtures/lernean_hydra.rb +39 -0
- data/spec/fixtures/llama_spaceship.rb +15 -0
- data/spec/fixtures/mathematical_function.rb +34 -0
- data/spec/fixtures/memory_object.rb +30 -0
- data/spec/fixtures/mittelschnauzer.rb +39 -0
- data/spec/fixtures/motor_launch.rb +21 -0
- data/spec/fixtures/multibyte.rb +16 -0
- data/spec/fixtures/page.rb +32 -0
- data/spec/fixtures/phone_number.rb +28 -0
- data/spec/fixtures/pirogue.rb +28 -0
- data/spec/fixtures/programming_language.rb +83 -0
- data/spec/fixtures/reservation.rb +38 -0
- data/spec/fixtures/scm_operation.rb +56 -0
- data/spec/fixtures/sms_message.rb +22 -0
- data/spec/fixtures/udp_packet.rb +49 -0
- data/spec/integration/absent_field_validator/absent_field_validator_spec.rb +90 -0
- data/spec/integration/absent_field_validator/spec_helper.rb +7 -0
- data/spec/integration/acceptance_validator/acceptance_validator_spec.rb +196 -0
- data/spec/integration/acceptance_validator/spec_helper.rb +7 -0
- data/spec/integration/automatic_validation/custom_messages_for_inferred_validation_spec.rb +57 -0
- data/spec/integration/automatic_validation/disabling_inferred_validation_spec.rb +49 -0
- data/spec/integration/automatic_validation/inferred_boolean_properties_validation_spec.rb +100 -0
- data/spec/integration/automatic_validation/inferred_float_property_validation_spec.rb +45 -0
- data/spec/integration/automatic_validation/inferred_format_validation_spec.rb +35 -0
- data/spec/integration/automatic_validation/inferred_integer_properties_validation_spec.rb +70 -0
- data/spec/integration/automatic_validation/inferred_length_validation_spec.rb +142 -0
- data/spec/integration/automatic_validation/inferred_presence_validation_spec.rb +45 -0
- data/spec/integration/automatic_validation/inferred_primitive_validation_spec.rb +22 -0
- data/spec/integration/automatic_validation/inferred_uniqueness_validation_spec.rb +52 -0
- data/spec/integration/automatic_validation/inferred_within_validation_spec.rb +39 -0
- data/spec/integration/automatic_validation/spec_helper.rb +57 -0
- data/spec/integration/block_validator/block_validator_spec.rb +32 -0
- data/spec/integration/block_validator/spec_helper.rb +5 -0
- data/spec/integration/conditional_validation/if_condition_spec.rb +63 -0
- data/spec/integration/conditional_validation/spec_helper.rb +5 -0
- data/spec/integration/confirmation_validator/confirmation_validator_spec.rb +76 -0
- data/spec/integration/confirmation_validator/spec_helper.rb +5 -0
- data/spec/integration/datamapper_models/association_validation_spec.rb +29 -0
- data/spec/integration/datamapper_models/inheritance_spec.rb +82 -0
- data/spec/integration/dirty_attributes/dirty_attributes_spec.rb +13 -0
- data/spec/integration/duplicated_validations/duplicated_validations_spec.rb +24 -0
- data/spec/integration/duplicated_validations/spec_helper.rb +5 -0
- data/spec/integration/format_validator/email_format_validator_spec.rb +139 -0
- data/spec/integration/format_validator/format_validator_spec.rb +64 -0
- data/spec/integration/format_validator/regexp_validator_spec.rb +33 -0
- data/spec/integration/format_validator/spec_helper.rb +5 -0
- data/spec/integration/format_validator/url_format_validator_spec.rb +93 -0
- data/spec/integration/length_validator/default_value_spec.rb +14 -0
- data/spec/integration/length_validator/equality_spec.rb +87 -0
- data/spec/integration/length_validator/error_message_spec.rb +22 -0
- data/spec/integration/length_validator/maximum_spec.rb +49 -0
- data/spec/integration/length_validator/minimum_spec.rb +54 -0
- data/spec/integration/length_validator/range_spec.rb +87 -0
- data/spec/integration/length_validator/spec_helper.rb +7 -0
- data/spec/integration/method_validator/method_validator_spec.rb +241 -0
- data/spec/integration/method_validator/spec_helper.rb +5 -0
- data/spec/integration/numeric_validator/equality_with_float_type_spec.rb +65 -0
- data/spec/integration/numeric_validator/equality_with_integer_type_spec.rb +41 -0
- data/spec/integration/numeric_validator/float_type_spec.rb +90 -0
- data/spec/integration/numeric_validator/gt_with_float_type_spec.rb +37 -0
- data/spec/integration/numeric_validator/gte_with_float_type_spec.rb +37 -0
- data/spec/integration/numeric_validator/integer_only_true_spec.rb +91 -0
- data/spec/integration/numeric_validator/integer_type_spec.rb +86 -0
- data/spec/integration/numeric_validator/lt_with_float_type_spec.rb +37 -0
- data/spec/integration/numeric_validator/lte_with_float_type_spec.rb +37 -0
- data/spec/integration/numeric_validator/spec_helper.rb +5 -0
- data/spec/integration/primitive_validator/primitive_validator_spec.rb +92 -0
- data/spec/integration/primitive_validator/spec_helper.rb +5 -0
- data/spec/integration/pure_ruby_objects/plain_old_ruby_object_validation_spec.rb +118 -0
- data/spec/integration/required_field_validator/association_spec.rb +72 -0
- data/spec/integration/required_field_validator/boolean_type_value_spec.rb +155 -0
- data/spec/integration/required_field_validator/date_type_value_spec.rb +127 -0
- data/spec/integration/required_field_validator/datetime_type_value_spec.rb +127 -0
- data/spec/integration/required_field_validator/float_type_value_spec.rb +131 -0
- data/spec/integration/required_field_validator/integer_type_value_spec.rb +99 -0
- data/spec/integration/required_field_validator/plain_old_ruby_object_spec.rb +35 -0
- data/spec/integration/required_field_validator/shared_examples.rb +26 -0
- data/spec/integration/required_field_validator/spec_helper.rb +7 -0
- data/spec/integration/required_field_validator/string_type_value_spec.rb +167 -0
- data/spec/integration/required_field_validator/text_type_value_spec.rb +49 -0
- data/spec/integration/shared/default_validation_context.rb +13 -0
- data/spec/integration/shared/valid_and_invalid_model.rb +35 -0
- data/spec/integration/uniqueness_validator/spec_helper.rb +5 -0
- data/spec/integration/uniqueness_validator/uniqueness_validator_spec.rb +116 -0
- data/spec/integration/within_validator/spec_helper.rb +5 -0
- data/spec/integration/within_validator/within_validator_spec.rb +168 -0
- data/spec/public/resource_spec.rb +105 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/unit/contextual_validators/emptiness_spec.rb +50 -0
- data/spec/unit/contextual_validators/execution_spec.rb +48 -0
- data/spec/unit/contextual_validators/spec_helper.rb +37 -0
- data/spec/unit/generic_validator/equality_operator_spec.rb +26 -0
- data/spec/unit/generic_validator/optional_spec.rb +54 -0
- data/spec/unit/validation_errors/adding_spec.rb +54 -0
- data/spec/unit/validation_errors/emptiness_spec.rb +38 -0
- data/spec/unit/validation_errors/enumerable_spec.rb +32 -0
- data/spec/unit/validation_errors/reading_spec.rb +35 -0
- data/spec/unit/validation_errors/respond_to_spec.rb +15 -0
- data/spec/unit/validators/within_validator_spec.rb +23 -0
- data/tasks/spec.rake +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +256 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Validations
|
|
3
|
+
#
|
|
4
|
+
# @author Guy van den Berg
|
|
5
|
+
# @since 0.9
|
|
6
|
+
class ValidationErrors
|
|
7
|
+
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
@@default_error_messages = {
|
|
11
|
+
:absent => '%s must be absent',
|
|
12
|
+
:inclusion => '%s must be one of %s',
|
|
13
|
+
:invalid => '%s has an invalid format',
|
|
14
|
+
:confirmation => '%s does not match the confirmation',
|
|
15
|
+
:accepted => '%s is not accepted',
|
|
16
|
+
:nil => '%s must not be nil',
|
|
17
|
+
:blank => '%s must not be blank',
|
|
18
|
+
:length_between => '%s must be between %s and %s characters long',
|
|
19
|
+
:too_long => '%s must be at most %s characters long',
|
|
20
|
+
:too_short => '%s must be at least %s characters long',
|
|
21
|
+
:wrong_length => '%s must be %s characters long',
|
|
22
|
+
:taken => '%s is already taken',
|
|
23
|
+
:not_a_number => '%s must be a number',
|
|
24
|
+
:not_an_integer => '%s must be an integer',
|
|
25
|
+
:greater_than => '%s must be greater than %s',
|
|
26
|
+
:greater_than_or_equal_to => '%s must be greater than or equal to %s',
|
|
27
|
+
:equal_to => '%s must be equal to %s',
|
|
28
|
+
:not_equal_to => '%s must not be equal to %s',
|
|
29
|
+
:less_than => '%s must be less than %s',
|
|
30
|
+
:less_than_or_equal_to => '%s must be less than or equal to %s',
|
|
31
|
+
:value_between => '%s must be between %s and %s',
|
|
32
|
+
:primitive => '%s must be of type %s'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Holds a hash with all the default error messages that can be replaced by your own copy or localizations.
|
|
36
|
+
def self.default_error_messages=(default_error_messages)
|
|
37
|
+
@@default_error_messages = default_error_messages
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.default_error_message(key, field, *values)
|
|
41
|
+
field = DataMapper::Inflector.humanize(field)
|
|
42
|
+
@@default_error_messages[key] % [field, *values].flatten
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
attr_reader :resource
|
|
46
|
+
|
|
47
|
+
def initialize(resource)
|
|
48
|
+
@resource = resource
|
|
49
|
+
@errors = DataMapper::Validations::OrderedHash.new { |h,k| h[k] = [] }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Clear existing validation errors.
|
|
53
|
+
def clear!
|
|
54
|
+
errors.clear
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Add a validation error. Use the field_name :general if the errors
|
|
58
|
+
# does not apply to a specific field of the Resource.
|
|
59
|
+
#
|
|
60
|
+
# @param [Symbol] field_name
|
|
61
|
+
# The name of the field that caused the error
|
|
62
|
+
#
|
|
63
|
+
# @param [String] message
|
|
64
|
+
# The message to add
|
|
65
|
+
def add(field_name, message)
|
|
66
|
+
# see 6abe8fff in extlib, but don't enforce
|
|
67
|
+
# it unless Edge version is installed
|
|
68
|
+
if message.respond_to?(:try_call)
|
|
69
|
+
# DM resource
|
|
70
|
+
message = if (resource.respond_to?(:model) &&
|
|
71
|
+
resource.model.respond_to?(:properties))
|
|
72
|
+
message.try_call(
|
|
73
|
+
resource,
|
|
74
|
+
resource.model.properties[field_name]
|
|
75
|
+
)
|
|
76
|
+
else
|
|
77
|
+
# pure Ruby object
|
|
78
|
+
message.try_call(resource)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
(errors[field_name] ||= []) << message
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Collect all errors into a single list.
|
|
86
|
+
def full_messages
|
|
87
|
+
errors.inject([]) do |list, pair|
|
|
88
|
+
list += pair.last
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Return validation errors for a particular field_name.
|
|
93
|
+
#
|
|
94
|
+
# @param [Symbol] field_name
|
|
95
|
+
# The name of the field you want an error for.
|
|
96
|
+
#
|
|
97
|
+
# @return [Array<DataMapper::Validations::Error>]
|
|
98
|
+
# Array of validation errors or empty array, if there are no errors
|
|
99
|
+
# on given field
|
|
100
|
+
def on(field_name)
|
|
101
|
+
errors_for_field = errors[field_name]
|
|
102
|
+
DataMapper::Ext.blank?(errors_for_field) ? nil : errors_for_field.uniq
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def each
|
|
106
|
+
errors.each_value do |v|
|
|
107
|
+
yield(v) unless DataMapper::Ext.blank?(v)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def empty?
|
|
112
|
+
@errors.all? { |property_name, errors| errors.empty? }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def method_missing(meth, *args, &block)
|
|
116
|
+
errors.send(meth, *args, &block)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def respond_to?(method)
|
|
120
|
+
super || errors.respond_to?(method)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def [](property_name)
|
|
124
|
+
if (property_errors = errors[property_name.to_sym])
|
|
125
|
+
property_errors
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
private
|
|
130
|
+
|
|
131
|
+
def errors
|
|
132
|
+
@errors
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
end # class ValidationErrors
|
|
136
|
+
end # module Validations
|
|
137
|
+
end # module DataMapper
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Validations
|
|
3
|
+
#
|
|
4
|
+
# @author Guy van den Berg
|
|
5
|
+
# @since 0.9
|
|
6
|
+
class AbsenceValidator < GenericValidator
|
|
7
|
+
|
|
8
|
+
def call(target)
|
|
9
|
+
value = target.validation_property_value(field_name)
|
|
10
|
+
return true if DataMapper::Ext.blank?(value)
|
|
11
|
+
|
|
12
|
+
error_message = (
|
|
13
|
+
self.options[:message] || ValidationErrors.default_error_message(
|
|
14
|
+
:absent, field_name
|
|
15
|
+
)
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
add_error(target, error_message, field_name)
|
|
19
|
+
false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end # class AbsenceValidator
|
|
23
|
+
|
|
24
|
+
module ValidatesAbsence
|
|
25
|
+
extend Deprecate
|
|
26
|
+
|
|
27
|
+
# Validates that the specified attribute is "blank" via the
|
|
28
|
+
# attribute's #blank? method.
|
|
29
|
+
#
|
|
30
|
+
# @note
|
|
31
|
+
# dm-core's support lib adds the #blank? method to many classes,
|
|
32
|
+
# @see lib/dm-core/support/blank.rb (dm-core) for more information.
|
|
33
|
+
#
|
|
34
|
+
# @example [Usage]
|
|
35
|
+
# require 'dm-validations'
|
|
36
|
+
#
|
|
37
|
+
# class Page
|
|
38
|
+
# include DataMapper::Resource
|
|
39
|
+
#
|
|
40
|
+
# property :unwanted_attribute, String
|
|
41
|
+
# property :another_unwanted, String
|
|
42
|
+
# property :yet_again, String
|
|
43
|
+
#
|
|
44
|
+
# validates_absence_of :unwanted_attribute
|
|
45
|
+
# validates_absence_of :another_unwanted, :yet_again
|
|
46
|
+
#
|
|
47
|
+
# # a call to valid? will return false unless
|
|
48
|
+
# # all three attributes are blank
|
|
49
|
+
# end
|
|
50
|
+
#
|
|
51
|
+
def validates_absence_of(*fields)
|
|
52
|
+
validators.add(AbsenceValidator, *fields)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
deprecate :validates_absent, :validates_absence_of
|
|
56
|
+
end # module ValidatesAbsent
|
|
57
|
+
end # module Validations
|
|
58
|
+
end # module DataMapper
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Validations
|
|
3
|
+
# @author Martin Kihlgren
|
|
4
|
+
# @since 0.9
|
|
5
|
+
class AcceptanceValidator < GenericValidator
|
|
6
|
+
|
|
7
|
+
def initialize(field_name, options = {})
|
|
8
|
+
super
|
|
9
|
+
|
|
10
|
+
@options[:allow_nil] = true unless @options.key?(:allow_nil)
|
|
11
|
+
|
|
12
|
+
@options[:accept] ||= [ '1', 1, 'true', true, 't' ]
|
|
13
|
+
@options[:accept] = Array(@options[:accept])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call(target)
|
|
17
|
+
return true if valid?(target)
|
|
18
|
+
|
|
19
|
+
error_message = (
|
|
20
|
+
@options[:message] || ValidationErrors.default_error_message(
|
|
21
|
+
:accepted, field_name
|
|
22
|
+
)
|
|
23
|
+
)
|
|
24
|
+
add_error(target, error_message, field_name)
|
|
25
|
+
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def valid?(target)
|
|
32
|
+
value = target.validation_property_value(field_name)
|
|
33
|
+
return true if allow_nil?(value)
|
|
34
|
+
@options[:accept].include?(value)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def allow_nil?(value)
|
|
38
|
+
@options[:allow_nil] && value.nil?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end # class AcceptanceValidator
|
|
42
|
+
|
|
43
|
+
module ValidatesAcceptance
|
|
44
|
+
extend Deprecate
|
|
45
|
+
|
|
46
|
+
# Validates that the attributes's value is in the set of accepted
|
|
47
|
+
# values.
|
|
48
|
+
#
|
|
49
|
+
# @option [Boolean] :allow_nil (true)
|
|
50
|
+
# true if nil is allowed, false if not allowed.
|
|
51
|
+
#
|
|
52
|
+
# @option [Array] :accept (["1", 1, "true", true, "t"])
|
|
53
|
+
# A list of accepted values.
|
|
54
|
+
#
|
|
55
|
+
# @example Usage
|
|
56
|
+
# require 'dm-validations'
|
|
57
|
+
#
|
|
58
|
+
# class Page
|
|
59
|
+
# include DataMapper::Resource
|
|
60
|
+
#
|
|
61
|
+
# property :license_agreement_accepted, String
|
|
62
|
+
# property :terms_accepted, String
|
|
63
|
+
# validates_acceptance_of :license_agreement, :accept => "1"
|
|
64
|
+
# validates_acceptance_of :terms_accepted, :allow_nil => false
|
|
65
|
+
#
|
|
66
|
+
# # a call to valid? will return false unless:
|
|
67
|
+
# # license_agreement is nil or "1"
|
|
68
|
+
# # and
|
|
69
|
+
# # terms_accepted is one of ["1", 1, "true", true, "t"]
|
|
70
|
+
#
|
|
71
|
+
def validates_acceptance_of(*fields)
|
|
72
|
+
validators.add(AcceptanceValidator, *fields)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
deprecate :validates_is_accepted, :validates_acceptance_of
|
|
76
|
+
|
|
77
|
+
end # module ValidatesIsAccepted
|
|
78
|
+
end # module Validations
|
|
79
|
+
end # module DataMapper
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Validations
|
|
3
|
+
# @author teamon
|
|
4
|
+
# @since 0.9
|
|
5
|
+
module ValidatesWithBlock
|
|
6
|
+
# Validate using the given block. The block given needs to return:
|
|
7
|
+
# [result::<Boolean>, Error Message::<String>]
|
|
8
|
+
#
|
|
9
|
+
# @example [Usage]
|
|
10
|
+
# require 'dm-validations'
|
|
11
|
+
#
|
|
12
|
+
# class Page
|
|
13
|
+
# include DataMapper::Resource
|
|
14
|
+
#
|
|
15
|
+
# property :zip_code, String
|
|
16
|
+
#
|
|
17
|
+
# validates_with_block do
|
|
18
|
+
# if @zip_code == "94301"
|
|
19
|
+
# true
|
|
20
|
+
# else
|
|
21
|
+
# [false, "You're in the wrong zip code"]
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# # A call to valid? will return false and
|
|
26
|
+
# # populate the object's errors with "You're in the
|
|
27
|
+
# # wrong zip code" unless zip_code == "94301"
|
|
28
|
+
#
|
|
29
|
+
# # You can also specify field:
|
|
30
|
+
#
|
|
31
|
+
# validates_with_block :zip_code do
|
|
32
|
+
# if @zip_code == "94301"
|
|
33
|
+
# true
|
|
34
|
+
# else
|
|
35
|
+
# [false, "You're in the wrong zip code"]
|
|
36
|
+
# end
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# # it will add returned error message to :zip_code field
|
|
40
|
+
#
|
|
41
|
+
def validates_with_block(*fields, &block)
|
|
42
|
+
@__validates_with_block_count ||= 0
|
|
43
|
+
@__validates_with_block_count += 1
|
|
44
|
+
|
|
45
|
+
# create method and pass it to MethodValidator
|
|
46
|
+
unless block_given?
|
|
47
|
+
raise ArgumentError, 'You need to pass a block to validates_with_block method'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
method_name = "__validates_with_block_#{@__validates_with_block_count}".to_sym
|
|
51
|
+
define_method(method_name, &block)
|
|
52
|
+
|
|
53
|
+
options = fields.last.is_a?(Hash) ? fields.last.pop.dup : {}
|
|
54
|
+
options[:method] = method_name
|
|
55
|
+
fields = [method_name] if fields.empty?
|
|
56
|
+
|
|
57
|
+
validators.add(MethodValidator, *fields + [options])
|
|
58
|
+
end
|
|
59
|
+
end # module ValidatesWithMethod
|
|
60
|
+
end # module Validations
|
|
61
|
+
end # module DataMapper
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
module DataMapper
|
|
3
|
+
module Validations
|
|
4
|
+
# @author Guy van den Berg
|
|
5
|
+
# @since 0.9
|
|
6
|
+
class ConfirmationValidator < GenericValidator
|
|
7
|
+
|
|
8
|
+
def initialize(field_name, options = {})
|
|
9
|
+
super
|
|
10
|
+
|
|
11
|
+
set_optional_by_default
|
|
12
|
+
|
|
13
|
+
@confirm_field_name = (
|
|
14
|
+
options[:confirm] || "#{field_name}_confirmation"
|
|
15
|
+
).to_sym
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def call(target)
|
|
19
|
+
return true if valid?(target)
|
|
20
|
+
|
|
21
|
+
error_message = (
|
|
22
|
+
@options[:message] || ValidationErrors.default_error_message(
|
|
23
|
+
:confirmation, field_name
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
add_error(target, error_message, field_name)
|
|
27
|
+
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def valid?(target)
|
|
34
|
+
value = target.validation_property_value(field_name)
|
|
35
|
+
return true if optional?(value)
|
|
36
|
+
|
|
37
|
+
if target.model.properties.named?(field_name)
|
|
38
|
+
return true unless target.attribute_dirty?(field_name)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
confirm_value = target.instance_variable_get("@#{@confirm_field_name}")
|
|
42
|
+
value == confirm_value
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end # class ConfirmationValidator
|
|
46
|
+
|
|
47
|
+
module ValidatesConfirmation
|
|
48
|
+
extend Deprecate
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# Validates that the given attribute is confirmed by another
|
|
52
|
+
# attribute. A common use case scenario is when you require a user to
|
|
53
|
+
# confirm their password, for which you use both password and
|
|
54
|
+
# password_confirmation attributes.
|
|
55
|
+
#
|
|
56
|
+
# @option [Boolean] :allow_nil (true)
|
|
57
|
+
# true or false.
|
|
58
|
+
#
|
|
59
|
+
# @option [Boolean] :allow_blank (true)
|
|
60
|
+
# true or false.
|
|
61
|
+
#
|
|
62
|
+
# @option [Symbol] :confirm (firstattr_confirmation)
|
|
63
|
+
# The attribute that you want to validate against.
|
|
64
|
+
#
|
|
65
|
+
# @example Usage
|
|
66
|
+
# require 'dm-validations'
|
|
67
|
+
#
|
|
68
|
+
# class Page
|
|
69
|
+
# include DataMapper::Resource
|
|
70
|
+
#
|
|
71
|
+
# property :password, String
|
|
72
|
+
# property :email, String
|
|
73
|
+
# attr_accessor :password_confirmation
|
|
74
|
+
# attr_accessor :email_repeated
|
|
75
|
+
#
|
|
76
|
+
# validates_confirmation_of :password
|
|
77
|
+
# validates_confirmation_of :email, :confirm => :email_repeated
|
|
78
|
+
#
|
|
79
|
+
# # a call to valid? will return false unless:
|
|
80
|
+
# # password == password_confirmation
|
|
81
|
+
# # and
|
|
82
|
+
# # email == email_repeated
|
|
83
|
+
#
|
|
84
|
+
def validates_confirmation_of(*fields)
|
|
85
|
+
validators.add(ConfirmationValidator, *fields)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
deprecate :validates_is_confirmed, :validates_confirmation_of
|
|
89
|
+
|
|
90
|
+
end # module ValidatesIsConfirmed
|
|
91
|
+
end # module Validations
|
|
92
|
+
end # module DataMapper
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#require File.dirname(__FILE__) + '/formats/email'
|
|
2
|
+
|
|
3
|
+
require 'pathname'
|
|
4
|
+
require 'dm-validations/formats/email'
|
|
5
|
+
require 'dm-validations/formats/url'
|
|
6
|
+
|
|
7
|
+
module DataMapper
|
|
8
|
+
module Validations
|
|
9
|
+
class UnknownValidationFormat < ::ArgumentError; end
|
|
10
|
+
|
|
11
|
+
# @author Guy van den Berg
|
|
12
|
+
# @since 0.9
|
|
13
|
+
class FormatValidator < GenericValidator
|
|
14
|
+
|
|
15
|
+
FORMATS = {}
|
|
16
|
+
|
|
17
|
+
include DataMapper::Validations::Format::Email
|
|
18
|
+
include DataMapper::Validations::Format::Url
|
|
19
|
+
|
|
20
|
+
def initialize(field_name, options = {})
|
|
21
|
+
super
|
|
22
|
+
|
|
23
|
+
set_optional_by_default
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def call(target)
|
|
27
|
+
return true if valid?(target)
|
|
28
|
+
|
|
29
|
+
value = target.validation_property_value(field_name)
|
|
30
|
+
|
|
31
|
+
error_message = (
|
|
32
|
+
@options[:message] || ValidationErrors.default_error_message(
|
|
33
|
+
:invalid, field_name
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
add_error(
|
|
38
|
+
target,
|
|
39
|
+
error_message.try_call(humanized_field_name, value),
|
|
40
|
+
field_name
|
|
41
|
+
)
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def valid?(target)
|
|
48
|
+
value = target.validation_property_value(field_name)
|
|
49
|
+
return true if optional?(value)
|
|
50
|
+
|
|
51
|
+
validation = @options[:as] || @options[:with]
|
|
52
|
+
|
|
53
|
+
if validation.is_a?(Symbol) && !FORMATS.has_key?(validation)
|
|
54
|
+
raise("No such predefined format '#{validation}'")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
validator = if validation.is_a?(Symbol)
|
|
58
|
+
FORMATS[validation][0]
|
|
59
|
+
else
|
|
60
|
+
validation
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
case validator
|
|
64
|
+
when Proc then validator.call(value)
|
|
65
|
+
when Regexp then value ? value.to_s =~ validator : false
|
|
66
|
+
else
|
|
67
|
+
raise(UnknownValidationFormat, "Can't determine how to validate #{target.class}##{field_name} with #{validator.inspect}")
|
|
68
|
+
end
|
|
69
|
+
rescue Encoding::CompatibilityError
|
|
70
|
+
# This is to work around a bug in jruby - see formats/email.rb
|
|
71
|
+
false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end # class FormatValidator
|
|
75
|
+
|
|
76
|
+
module ValidatesFormat
|
|
77
|
+
extend Deprecate
|
|
78
|
+
|
|
79
|
+
# Validates that the attribute is in the specified format. You may
|
|
80
|
+
# use the :as (or :with, it's an alias) option to specify the
|
|
81
|
+
# pre-defined format that you want to validate against. You may also
|
|
82
|
+
# specify your own format via a Proc or Regexp passed to the the :as
|
|
83
|
+
# or :with options.
|
|
84
|
+
#
|
|
85
|
+
# @option [Boolean] :allow_nil (true)
|
|
86
|
+
# true or false.
|
|
87
|
+
#
|
|
88
|
+
# @option [Boolean] :allow_blank (true)
|
|
89
|
+
# true or false.
|
|
90
|
+
#
|
|
91
|
+
# @option [Format, Proc, Regexp] :as
|
|
92
|
+
# The pre-defined format, Proc or Regexp to validate against.
|
|
93
|
+
#
|
|
94
|
+
# @option [Format, Proc, Regexp] :with
|
|
95
|
+
# An alias for :as.
|
|
96
|
+
#
|
|
97
|
+
# :email_address (format is specified in DataMapper::Validations::Format::Email - note that unicode emails will *not* be matched under MRI1.8.7)
|
|
98
|
+
# :url (format is specified in DataMapper::Validations::Format::Url)
|
|
99
|
+
#
|
|
100
|
+
# @example Usage
|
|
101
|
+
# require 'dm-validations'
|
|
102
|
+
#
|
|
103
|
+
# class Page
|
|
104
|
+
# include DataMapper::Resource
|
|
105
|
+
#
|
|
106
|
+
# property :email, String
|
|
107
|
+
# property :zip_code, String
|
|
108
|
+
#
|
|
109
|
+
# validates_format_of :email, :as => :email_address
|
|
110
|
+
# validates_format_of :zip_code, :with => /^\d{5}$/
|
|
111
|
+
#
|
|
112
|
+
# # a call to valid? will return false unless:
|
|
113
|
+
# # email is formatted like an email address
|
|
114
|
+
# # and
|
|
115
|
+
# # zip_code is a string of 5 digits
|
|
116
|
+
#
|
|
117
|
+
def validates_format_of(*fields)
|
|
118
|
+
validators.add(FormatValidator, *fields)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
deprecate :validates_format, :validates_format_of
|
|
122
|
+
end # module ValidatesFormat
|
|
123
|
+
end # module Validations
|
|
124
|
+
end # module DataMapper
|