dm-validations 0.9.11 → 0.10.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.
- data/{History.txt → History.rdoc} +10 -3
- data/LICENSE +1 -0
- data/Manifest.txt +103 -33
- data/README.rdoc +172 -0
- data/Rakefile +4 -5
- data/lib/dm-validations.rb +73 -75
- data/lib/dm-validations/auto_validate.rb +98 -56
- data/lib/dm-validations/contextual_validators.rb +37 -14
- data/lib/dm-validations/exceptions.rb +3 -0
- data/lib/dm-validations/formats/url.rb +3 -1
- data/lib/dm-validations/support/context.rb +54 -0
- data/lib/dm-validations/validation_errors.rb +51 -27
- data/lib/dm-validations/{absent_field_validator.rb → validators/absent_field_validator.rb} +2 -8
- data/lib/dm-validations/{acceptance_validator.rb → validators/acceptance_validator.rb} +7 -7
- data/lib/dm-validations/{block_validator.rb → validators/block_validator.rb} +0 -0
- data/lib/dm-validations/{confirmation_validator.rb → validators/confirmation_validator.rb} +7 -7
- data/lib/dm-validations/{format_validator.rb → validators/format_validator.rb} +10 -16
- data/lib/dm-validations/{generic_validator.rb → validators/generic_validator.rb} +28 -6
- data/lib/dm-validations/validators/length_validator.rb +214 -0
- data/lib/dm-validations/validators/method_validator.rb +68 -0
- data/lib/dm-validations/validators/numeric_validator.rb +171 -0
- data/lib/dm-validations/{primitive_validator.rb → validators/primitive_validator.rb} +2 -7
- data/lib/dm-validations/{required_field_validator.rb → validators/required_field_validator.rb} +0 -6
- data/lib/dm-validations/{uniqueness_validator.rb → validators/uniqueness_validator.rb} +9 -20
- data/lib/dm-validations/{within_validator.rb → validators/within_validator.rb} +4 -4
- data/lib/dm-validations/version.rb +1 -1
- data/spec/fixtures/barcode.rb +32 -0
- data/spec/fixtures/basketball_court.rb +58 -0
- data/spec/fixtures/basketball_player.rb +37 -0
- data/spec/fixtures/beta_tester_account.rb +33 -0
- data/spec/fixtures/bill_of_landing.rb +42 -0
- data/spec/fixtures/boat_dock.rb +26 -0
- data/spec/fixtures/city.rb +25 -0
- data/spec/fixtures/company.rb +95 -0
- data/spec/fixtures/corporate_world.rb +47 -0
- data/spec/fixtures/country.rb +25 -0
- data/spec/fixtures/currency.rb +42 -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/mathematical_function.rb +34 -0
- data/spec/fixtures/memory_object.rb +30 -0
- data/spec/fixtures/mittelschnauzer.rb +35 -0
- data/spec/fixtures/motor_launch.rb +21 -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 +67 -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 +86 -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 +47 -0
- data/spec/integration/automatic_validation/disabling_inferred_validation_spec.rb +41 -0
- data/spec/integration/automatic_validation/inferred_boolean_properties_validation_spec.rb +104 -0
- data/spec/integration/automatic_validation/inferred_float_property_validation_spec.rb +35 -0
- data/spec/integration/automatic_validation/inferred_format_validation_spec.rb +33 -0
- data/spec/integration/automatic_validation/inferred_integer_properties_validation_spec.rb +73 -0
- data/spec/integration/automatic_validation/inferred_length_validation_spec.rb +121 -0
- data/spec/integration/automatic_validation/inferred_presence_validation_spec.rb +41 -0
- data/spec/integration/automatic_validation/inferred_primitive_validation_spec.rb +20 -0
- data/spec/integration/automatic_validation/inferred_within_validation_spec.rb +33 -0
- data/spec/integration/automatic_validation/spec_helper.rb +74 -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 +61 -0
- data/spec/integration/conditional_validation/spec_helper.rb +5 -0
- data/spec/integration/confirmation_validator/confirmation_validator_spec.rb +74 -0
- data/spec/integration/confirmation_validator/spec_helper.rb +5 -0
- data/spec/integration/datamapper_models/association_validation_spec.rb +23 -0
- data/spec/integration/datamapper_models/inheritance_spec.rb +78 -0
- data/spec/integration/duplicated_validations/duplicated_validations_spec.rb +22 -0
- data/spec/integration/duplicated_validations/spec_helper.rb +5 -0
- data/spec/integration/format_validator/email_format_validator_spec.rb +113 -0
- data/spec/integration/format_validator/format_validator_spec.rb +60 -0
- data/spec/integration/format_validator/regexp_validator_spec.rb +29 -0
- data/spec/integration/format_validator/spec_helper.rb +5 -0
- data/spec/integration/format_validator/url_format_validator_spec.rb +63 -0
- data/spec/integration/length_validator/default_value_spec.rb +12 -0
- data/spec/integration/length_validator/equality_spec.rb +79 -0
- data/spec/integration/length_validator/error_message_spec.rb +15 -18
- data/spec/integration/length_validator/maximum_spec.rb +40 -24
- data/spec/integration/length_validator/minimum_spec.rb +32 -21
- data/spec/integration/length_validator/range_spec.rb +50 -60
- data/spec/integration/length_validator/spec_helper.rb +7 -12
- data/spec/integration/method_validator/method_validator_spec.rb +239 -0
- data/spec/integration/method_validator/spec_helper.rb +5 -0
- data/spec/integration/numeric_validator/equality_with_float_type_spec.rb +61 -0
- data/spec/integration/numeric_validator/equality_with_integer_type_spec.rb +37 -0
- data/spec/integration/numeric_validator/float_type_spec.rb +42 -56
- data/spec/integration/numeric_validator/gt_with_float_type_spec.rb +35 -0
- data/spec/integration/numeric_validator/gte_with_float_type_spec.rb +35 -0
- data/spec/integration/numeric_validator/integer_only_true_spec.rb +3 -6
- data/spec/integration/numeric_validator/integer_type_spec.rb +8 -24
- data/spec/integration/numeric_validator/lt_with_float_type_spec.rb +35 -0
- data/spec/integration/numeric_validator/lte_with_float_type_spec.rb +35 -0
- data/spec/integration/numeric_validator/spec_helper.rb +5 -77
- data/spec/integration/primitive_validator/primitive_validator_spec.rb +90 -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 +5 -8
- data/spec/integration/required_field_validator/boolean_type_value_spec.rb +4 -7
- data/spec/integration/required_field_validator/date_type_value_spec.rb +3 -6
- data/spec/integration/required_field_validator/datetime_type_value_spec.rb +3 -6
- data/spec/integration/required_field_validator/float_type_value_spec.rb +3 -6
- data/spec/integration/required_field_validator/integer_type_value_spec.rb +2 -5
- data/spec/integration/required_field_validator/plain_old_ruby_object_spec.rb +5 -8
- data/spec/integration/required_field_validator/shared_examples.rb +1 -1
- data/spec/integration/required_field_validator/spec_helper.rb +6 -67
- data/spec/integration/required_field_validator/string_type_value_spec.rb +2 -5
- data/spec/integration/required_field_validator/text_type_value_spec.rb +2 -5
- data/spec/integration/shared/default_validation_context.rb +13 -0
- data/spec/integration/shared/valid_and_invalid_model.rb +27 -0
- data/spec/integration/uniqueness_validator/spec_helper.rb +5 -0
- data/spec/integration/uniqueness_validator/uniqueness_validator_spec.rb +114 -0
- data/spec/integration/within_validator/spec_helper.rb +5 -0
- data/spec/integration/within_validator/within_validator_spec.rb +164 -0
- data/spec/public/resource_spec.rb +68 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +12 -4
- data/spec/unit/contextual_validators/emptiness_spec.rb +50 -0
- data/spec/unit/contextual_validators/execution_spec.rb +55 -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/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/tasks/install.rb +1 -1
- data/tasks/spec.rb +4 -4
- metadata +118 -55
- data/README.txt +0 -72
- data/lib/dm-validations/custom_validator.rb +0 -72
- data/lib/dm-validations/length_validator.rb +0 -113
- data/lib/dm-validations/method_validator.rb +0 -68
- data/lib/dm-validations/numeric_validator.rb +0 -83
- data/spec/integration/absent_field_validator_spec.rb +0 -36
- data/spec/integration/acceptance_validator_spec.rb +0 -87
- data/spec/integration/auto_validate_spec.rb +0 -342
- data/spec/integration/block_validator_spec.rb +0 -30
- data/spec/integration/confirmation_validator_spec.rb +0 -105
- data/spec/integration/contextual_validators_spec.rb +0 -27
- data/spec/integration/custom_validator_spec.rb +0 -9
- data/spec/integration/format_validator_spec.rb +0 -193
- data/spec/integration/generic_validator_spec.rb +0 -17
- data/spec/integration/length_validator/valid_objects_spec.rb +0 -13
- data/spec/integration/method_validator_spec.rb +0 -58
- data/spec/integration/numeric_validator_spec.rb +0 -253
- data/spec/integration/primitive_validator_spec.rb +0 -30
- data/spec/integration/uniqueness_validator_spec.rb +0 -97
- data/spec/integration/validation_errors_spec.rb +0 -18
- data/spec/integration/validation_spec.rb +0 -404
- data/spec/integration/within_validator_spec.rb +0 -79
@@ -1,113 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module Validate
|
3
|
-
|
4
|
-
##
|
5
|
-
#
|
6
|
-
# @author Guy van den Berg
|
7
|
-
# @since 0.9
|
8
|
-
class LengthValidator < GenericValidator
|
9
|
-
|
10
|
-
def initialize(field_name, options)
|
11
|
-
super
|
12
|
-
@field_name = field_name
|
13
|
-
@options = options
|
14
|
-
|
15
|
-
@min = options[:minimum] || options[:min]
|
16
|
-
@max = options[:maximum] || options[:max]
|
17
|
-
@equal = options[:is] || options[:equals]
|
18
|
-
@range = options[:within] || options[:in]
|
19
|
-
|
20
|
-
@validation_method ||= :range if @range
|
21
|
-
@validation_method ||= :min if @min && @max.nil?
|
22
|
-
@validation_method ||= :max if @max && @min.nil?
|
23
|
-
@validation_method ||= :equals unless @equal.nil?
|
24
|
-
end
|
25
|
-
|
26
|
-
def call(target)
|
27
|
-
field_value = target.validation_property_value(field_name)
|
28
|
-
return true if @options[:allow_nil] && field_value.nil?
|
29
|
-
|
30
|
-
field_value = '' if field_value.nil?
|
31
|
-
|
32
|
-
# XXX: HACK seems hacky to do this on every validation, probably should
|
33
|
-
# do this elsewhere?
|
34
|
-
field = Extlib::Inflection.humanize(field_name)
|
35
|
-
min = @range ? @range.min : @min
|
36
|
-
max = @range ? @range.max : @max
|
37
|
-
equal = @equal
|
38
|
-
|
39
|
-
case @validation_method
|
40
|
-
when :range then
|
41
|
-
unless valid = @range.include?(field_value.size)
|
42
|
-
error_message = ValidationErrors.default_error_message(:length_between, field, min, max)
|
43
|
-
end
|
44
|
-
when :min then
|
45
|
-
unless valid = field_value.size >= min
|
46
|
-
error_message = ValidationErrors.default_error_message(:too_short, field, min)
|
47
|
-
end
|
48
|
-
when :max then
|
49
|
-
unless valid = field_value.size <= max
|
50
|
-
error_message = ValidationErrors.default_error_message(:too_long, field, max)
|
51
|
-
end
|
52
|
-
when :equals then
|
53
|
-
unless valid = field_value.size == equal
|
54
|
-
error_message = ValidationErrors.default_error_message(:wrong_length, field, equal)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
error_message = @options[:message] || error_message
|
59
|
-
|
60
|
-
add_error(target, error_message, field_name) unless valid
|
61
|
-
|
62
|
-
return valid
|
63
|
-
end
|
64
|
-
|
65
|
-
end # class LengthValidator
|
66
|
-
|
67
|
-
module ValidatesLength
|
68
|
-
|
69
|
-
# Validates that the length of the attribute is equal to, less than,
|
70
|
-
# greater than or within a certain range (depending upon the options
|
71
|
-
# you specify).
|
72
|
-
#
|
73
|
-
# @option :allow_nil<Boolean> true/false (default is true)
|
74
|
-
# @option :minimum ensures that the attribute's length is greater than
|
75
|
-
# or equal to the supplied value
|
76
|
-
# @option :min alias for :minimum
|
77
|
-
# @option :maximum ensures the attribute's length is less than or equal
|
78
|
-
# to the supplied value
|
79
|
-
# @option :max alias for :maximum
|
80
|
-
# @option :equals ensures the attribute's length is equal to the
|
81
|
-
# supplied value
|
82
|
-
# @option :is alias for :equals
|
83
|
-
# @option :in<Range> given a Range, ensures that the attributes length is
|
84
|
-
# include?'ed in the Range
|
85
|
-
# @option :within<Range> alias for :in
|
86
|
-
#
|
87
|
-
# @example [Usage]
|
88
|
-
# require 'dm-validations'
|
89
|
-
#
|
90
|
-
# class Page
|
91
|
-
# include DataMapper::Resource
|
92
|
-
#
|
93
|
-
# property high, Integer
|
94
|
-
# property low, Integer
|
95
|
-
# property just_right, Integer
|
96
|
-
#
|
97
|
-
# validates_length :high, :min => 100000000000
|
98
|
-
# validates_length :low, :equals => 0
|
99
|
-
# validates_length :just_right, :within => 1..10
|
100
|
-
#
|
101
|
-
# # a call to valid? will return false unless:
|
102
|
-
# # high is greater than or equal to 100000000000
|
103
|
-
# # low is equal to 0
|
104
|
-
# # just_right is between 1 and 10 (inclusive of both 1 and 10)
|
105
|
-
#
|
106
|
-
def validates_length(*fields)
|
107
|
-
opts = opts_from_validator_args(fields)
|
108
|
-
add_validator_to_context(opts, fields, DataMapper::Validate::LengthValidator)
|
109
|
-
end
|
110
|
-
|
111
|
-
end # module ValidatesLength
|
112
|
-
end # module Validate
|
113
|
-
end # module DataMapper
|
@@ -1,68 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module Validate
|
3
|
-
|
4
|
-
##
|
5
|
-
#
|
6
|
-
# @author Guy van den Berg
|
7
|
-
# @since 0.9
|
8
|
-
class MethodValidator < GenericValidator
|
9
|
-
|
10
|
-
def initialize(field_name, options={})
|
11
|
-
super
|
12
|
-
@field_name, @options = field_name, options.clone
|
13
|
-
@options[:method] = @field_name unless @options.has_key?(:method)
|
14
|
-
end
|
15
|
-
|
16
|
-
def call(target)
|
17
|
-
result, message = target.send(@options[:method])
|
18
|
-
add_error(target, message, field_name) unless result
|
19
|
-
result
|
20
|
-
end
|
21
|
-
|
22
|
-
def ==(other)
|
23
|
-
@options[:method] == other.instance_variable_get(:@options)[:method] && super
|
24
|
-
end
|
25
|
-
end # class MethodValidator
|
26
|
-
|
27
|
-
module ValidatesWithMethod
|
28
|
-
|
29
|
-
##
|
30
|
-
# Validate using the given method. The method given needs to return:
|
31
|
-
# [result::<Boolean>, Error Message::<String>]
|
32
|
-
#
|
33
|
-
# @example [Usage]
|
34
|
-
# require 'dm-validations'
|
35
|
-
#
|
36
|
-
# class Page
|
37
|
-
# include DataMapper::Resource
|
38
|
-
#
|
39
|
-
# property :zip_code, String
|
40
|
-
#
|
41
|
-
# validates_with_method :in_the_right_location?
|
42
|
-
#
|
43
|
-
# def in_the_right_location?
|
44
|
-
# if @zip_code == "94301"
|
45
|
-
# return true
|
46
|
-
# else
|
47
|
-
# return [false, "You're in the wrong zip code"]
|
48
|
-
# end
|
49
|
-
# end
|
50
|
-
#
|
51
|
-
# # A call to valid? will return false and
|
52
|
-
# # populate the object's errors with "You're in the
|
53
|
-
# # wrong zip code" unless zip_code == "94301"
|
54
|
-
#
|
55
|
-
# # You can also specify field:
|
56
|
-
#
|
57
|
-
# validates_with_method :zip_code, :in_the_right_location?
|
58
|
-
#
|
59
|
-
# # it will add returned error message to :zip_code field
|
60
|
-
#
|
61
|
-
def validates_with_method(*fields)
|
62
|
-
opts = opts_from_validator_args(fields)
|
63
|
-
add_validator_to_context(opts, fields, DataMapper::Validate::MethodValidator)
|
64
|
-
end
|
65
|
-
|
66
|
-
end # module ValidatesWithMethod
|
67
|
-
end # module Validate
|
68
|
-
end # module DataMapper
|
@@ -1,83 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module Validate
|
3
|
-
|
4
|
-
##
|
5
|
-
#
|
6
|
-
# @author Guy van den Berg
|
7
|
-
# @since 0.9
|
8
|
-
class NumericValidator < GenericValidator
|
9
|
-
|
10
|
-
def initialize(field_name, options={})
|
11
|
-
super
|
12
|
-
@field_name, @options = field_name, options
|
13
|
-
@options[:integer_only] = false unless @options.has_key?(:integer_only)
|
14
|
-
end
|
15
|
-
|
16
|
-
def call(target)
|
17
|
-
value = target.send(field_name)
|
18
|
-
return true if @options[:allow_nil] && value.nil?
|
19
|
-
|
20
|
-
value = value.kind_of?(BigDecimal) ? value.to_s('F') : value.to_s
|
21
|
-
|
22
|
-
error_message = @options[:message]
|
23
|
-
precision = @options[:precision]
|
24
|
-
scale = @options[:scale]
|
25
|
-
|
26
|
-
if @options[:integer_only]
|
27
|
-
return true if value =~ /\A[+-]?\d+\z/
|
28
|
-
error_message ||= ValidationErrors.default_error_message(:not_an_integer, field_name)
|
29
|
-
else
|
30
|
-
# FIXME: if precision and scale are not specified, can we assume that it is an integer?
|
31
|
-
# probably not, as floating point numbers don't have hard
|
32
|
-
# defined scale. the scale floats with the length of the
|
33
|
-
# integral and precision. Ie. if precision = 10 and integral
|
34
|
-
# portion of the number is 9834 (4 digits), the max scale will
|
35
|
-
# be 6 (10 - 4). But if the integral length is 1, max scale
|
36
|
-
# will be (10 - 1) = 9, so 1.234567890.
|
37
|
-
# In MySQL somehow you can hard-define scale on floats. Not
|
38
|
-
# quite sure how that works...
|
39
|
-
if precision && scale
|
40
|
-
#handles both Float when it has scale specified and BigDecimal
|
41
|
-
if precision > scale && scale > 0
|
42
|
-
return true if value =~ /\A[+-]?(?:\d{1,#{precision - scale}}|\d{0,#{precision - scale}}\.\d{1,#{scale}})\z/
|
43
|
-
elsif precision > scale && scale == 0
|
44
|
-
return true if value =~ /\A[+-]?(?:\d{1,#{precision}}(?:\.0)?)\z/
|
45
|
-
elsif precision == scale
|
46
|
-
return true if value =~ /\A[+-]?(?:0(?:\.\d{1,#{scale}})?)\z/
|
47
|
-
else
|
48
|
-
raise ArgumentError, "Invalid precision #{precision.inspect} and scale #{scale.inspect} for #{field_name} (value: #{value.inspect} #{value.class})"
|
49
|
-
end
|
50
|
-
elsif precision && scale.nil?
|
51
|
-
# for floats, if scale is not set
|
52
|
-
|
53
|
-
#total number of digits is less or equal precision
|
54
|
-
return true if value.gsub(/[^\d]/, '').length <= precision
|
55
|
-
|
56
|
-
#number of digits before decimal == precision, and the number is x.0. same as scale = 0
|
57
|
-
return true if value =~ /\A[+-]?(?:\d{1,#{precision}}(?:\.0)?)\z/
|
58
|
-
else
|
59
|
-
return true if value =~ /\A[+-]?(?:\d+|\d*\.\d+)\z/
|
60
|
-
end
|
61
|
-
error_message ||= ValidationErrors.default_error_message(:not_a_number, field_name)
|
62
|
-
end
|
63
|
-
|
64
|
-
add_error(target, error_message, field_name)
|
65
|
-
|
66
|
-
# TODO: check the gt, gte, lt, lte, and eq options
|
67
|
-
|
68
|
-
return false
|
69
|
-
end
|
70
|
-
end # class NumericValidator
|
71
|
-
|
72
|
-
module ValidatesIsNumber
|
73
|
-
|
74
|
-
# Validate whether a field is numeric
|
75
|
-
#
|
76
|
-
def validates_is_number(*fields)
|
77
|
-
opts = opts_from_validator_args(fields)
|
78
|
-
add_validator_to_context(opts, fields, DataMapper::Validate::NumericValidator)
|
79
|
-
end
|
80
|
-
|
81
|
-
end # module ValidatesIsNumber
|
82
|
-
end # module Validate
|
83
|
-
end # module DataMapper
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
|
-
|
4
|
-
describe DataMapper::Validate::AbsentFieldValidator do
|
5
|
-
before(:all) do
|
6
|
-
class ::Kayak
|
7
|
-
include DataMapper::Resource
|
8
|
-
property :id, Integer, :key => true
|
9
|
-
property :salesman, String, :auto_validation => false
|
10
|
-
validates_absent :salesman, :when => :sold
|
11
|
-
end
|
12
|
-
|
13
|
-
class ::Pirogue
|
14
|
-
include DataMapper::Resource
|
15
|
-
property :id, Integer, :key => true
|
16
|
-
property :salesman, String, :default => 'Layfayette'
|
17
|
-
validates_absent :salesman, :when => :sold
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should validate the absence of a value on an instance of a resource" do
|
22
|
-
kayak = Kayak.new
|
23
|
-
kayak.valid_for_sold?.should == true
|
24
|
-
|
25
|
-
kayak.salesman = 'Joe'
|
26
|
-
kayak.valid_for_sold?.should_not == true
|
27
|
-
kayak.errors.on(:salesman).should include('Salesman must be absent')
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should validate the absence of a value and ensure defaults" do
|
31
|
-
pirogue = Pirogue.new
|
32
|
-
pirogue.should_not be_valid_for_sold
|
33
|
-
pirogue.errors.on(:salesman).should include('Salesman must be absent')
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
|
-
|
4
|
-
describe DataMapper::Validate::AcceptanceValidator do
|
5
|
-
describe "with standard options" do
|
6
|
-
before(:all) do
|
7
|
-
class ::SkimBat
|
8
|
-
include DataMapper::Resource
|
9
|
-
property :id, Integer, :serial => true
|
10
|
-
property :sailyness, Boolean
|
11
|
-
validates_is_accepted :sailyness
|
12
|
-
end
|
13
|
-
@s = SkimBat.new
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should validate if a resource instance has been accepted" do
|
17
|
-
@s.sailyness = "1"
|
18
|
-
@s.valid?.should == true
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should not validate if a resource instance has not been accepted" do
|
22
|
-
@s.sailyness = "0"
|
23
|
-
@s.valid?.should == false
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should allow nil acceptance" do
|
27
|
-
@s.sailyness = nil
|
28
|
-
@s.valid?.should == true
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should add the default message when invalid" do
|
32
|
-
@s.sailyness = "0"
|
33
|
-
@s.valid?.should == false
|
34
|
-
@s.errors.on(:sailyness).should include('Sailyness is not accepted')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
describe "with :allow_nil => false" do
|
38
|
-
before(:all) do
|
39
|
-
SkimBat.class_eval do
|
40
|
-
validators.clear!
|
41
|
-
validates_is_accepted :sailyness, :allow_nil => false
|
42
|
-
end
|
43
|
-
@s = SkimBat.new
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should not allow nil acceptance" do
|
47
|
-
@s.sailyness = nil
|
48
|
-
@s.valid?.should == false
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe "with custom :accept" do
|
53
|
-
before(:all) do
|
54
|
-
SkimBat.class_eval do
|
55
|
-
validators.clear!
|
56
|
-
validates_is_accepted :sailyness, :accept => true
|
57
|
-
end
|
58
|
-
@s = SkimBat.new
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should validate if a resource instance has been accepted" do
|
62
|
-
@s.sailyness = "true"
|
63
|
-
@s.valid?.should == true
|
64
|
-
end
|
65
|
-
|
66
|
-
it "should not validate if a resource instance has not been accepted" do
|
67
|
-
@s.sailyness = "false"
|
68
|
-
@s.valid?.should == false
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "with custom message" do
|
73
|
-
before(:all) do
|
74
|
-
SkimBat.class_eval do
|
75
|
-
validators.clear!
|
76
|
-
validates_is_accepted :sailyness, :message => "hehu!"
|
77
|
-
end
|
78
|
-
@s = SkimBat.new
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should append the custom message when invalid" do
|
82
|
-
@s.sailyness = "0"
|
83
|
-
@s.valid?.should == false
|
84
|
-
@s.errors.on(:sailyness).should include('hehu!')
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,342 +0,0 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
|
-
|
4
|
-
module TypecastBypassSetter
|
5
|
-
# Bypass typecasting so we can set values for specs
|
6
|
-
def set(attributes)
|
7
|
-
attributes.each do |k, v|
|
8
|
-
instance_variable_set("@#{k}", v)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class SailBoat
|
14
|
-
include DataMapper::Resource
|
15
|
-
property :id, Integer, :key => true
|
16
|
-
property :name, String, :nullable => false, :validates => :presence_test
|
17
|
-
property :description, String, :length => 10, :validates => :length_test_1
|
18
|
-
property :notes, String, :length => 2..10, :validates => :length_test_2
|
19
|
-
property :no_validation, String, :auto_validation => false
|
20
|
-
property :salesman, String, :nullable => false, :validates => [:multi_context_1, :multi_context_2]
|
21
|
-
property :code, String, :format => Proc.new { |code| code =~ /A\d{4}\z/ }, :validates => :format_test
|
22
|
-
property :allow_nil, String, :size => 5..10, :nullable => true, :validates => :nil_test
|
23
|
-
property :build_date, Date, :validates => :primitive_test
|
24
|
-
property :float, Float, :precision => 2, :scale => 1
|
25
|
-
property :big_decimal, BigDecimal, :precision => 2, :scale => 1
|
26
|
-
|
27
|
-
include TypecastBypassSetter
|
28
|
-
end
|
29
|
-
|
30
|
-
class HasNullableBoolean
|
31
|
-
include DataMapper::Resource
|
32
|
-
property :id, Integer, :key => true
|
33
|
-
property :bool, Boolean # :nullable => true by default
|
34
|
-
|
35
|
-
include TypecastBypassSetter
|
36
|
-
end
|
37
|
-
|
38
|
-
class HasNotNullableBoolean
|
39
|
-
include DataMapper::Resource
|
40
|
-
property :id, Integer, :key => true
|
41
|
-
property :bool, Boolean, :nullable => false
|
42
|
-
|
43
|
-
include TypecastBypassSetter
|
44
|
-
end
|
45
|
-
|
46
|
-
class HasNotNullableParanoidBoolean
|
47
|
-
include DataMapper::Resource
|
48
|
-
property :id, Integer, :key => true
|
49
|
-
property :bool, ParanoidBoolean, :nullable => false
|
50
|
-
|
51
|
-
include TypecastBypassSetter
|
52
|
-
end
|
53
|
-
|
54
|
-
describe "Automatic Validation from Property Definition" do
|
55
|
-
it "should have a hook for adding auto validations called from
|
56
|
-
DataMapper::Property#new" do
|
57
|
-
SailBoat.should respond_to(:auto_generate_validations)
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should auto add a validates_is_present when property has option
|
61
|
-
:nullable => false" do
|
62
|
-
validator = SailBoat.validators.context(:presence_test).first
|
63
|
-
validator.should be_kind_of(DataMapper::Validate::RequiredFieldValidator)
|
64
|
-
validator.field_name.should == :name
|
65
|
-
|
66
|
-
boat = SailBoat.new
|
67
|
-
boat.valid_for_presence_test?.should == false
|
68
|
-
boat.errors.on(:name).should include('Name must not be blank')
|
69
|
-
boat.name = 'Float'
|
70
|
-
boat.valid_for_presence_test?.should == true
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should auto add a validates_length for maximum size on String properties" do
|
74
|
-
# max length test max=10
|
75
|
-
boat = SailBoat.new
|
76
|
-
boat.valid_for_length_test_1?.should == true #no minimum length
|
77
|
-
boat.description = 'ABCDEFGHIJK' #11
|
78
|
-
boat.valid_for_length_test_1?.should == false
|
79
|
-
boat.errors.on(:description).should include('Description must be less than 10 characters long')
|
80
|
-
boat.description = 'ABCDEFGHIJ' #10
|
81
|
-
boat.valid_for_length_test_1?.should == true
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should auto add validates_length within a range when option :length
|
85
|
-
or :size is a range" do
|
86
|
-
# Range test notes = 2..10
|
87
|
-
boat = SailBoat.new
|
88
|
-
boat.should be_valid_for_length_test_2
|
89
|
-
boat.notes = 'AB' #2
|
90
|
-
boat.should be_valid_for_length_test_2
|
91
|
-
boat.notes = 'ABCDEFGHIJK' #11
|
92
|
-
boat.should_not be_valid_for_length_test_2
|
93
|
-
boat.errors.on(:notes).should include('Notes must be between 2 and 10 characters long')
|
94
|
-
boat.notes = 'ABCDEFGHIJ' #10
|
95
|
-
boat.should be_valid_for_length_test_2
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should auto add a validates_format if the :format option is given" do
|
99
|
-
# format test - format = /A\d{4}\z/ on code
|
100
|
-
boat = SailBoat.new
|
101
|
-
boat.should be_valid_for_format_test
|
102
|
-
boat.code = 'A1234'
|
103
|
-
boat.should be_valid_for_format_test
|
104
|
-
boat.code = 'BAD CODE'
|
105
|
-
boat.should_not be_valid_for_format_test
|
106
|
-
boat.errors.on(:code).should include('Code has an invalid format')
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should auto validate all strings for max length" do
|
110
|
-
klass = Class.new do
|
111
|
-
include DataMapper::Resource
|
112
|
-
property :id, Integer, :serial => true
|
113
|
-
property :name, String
|
114
|
-
end
|
115
|
-
t = klass.new(:id => 1)
|
116
|
-
t.should be_valid
|
117
|
-
t.name = 'a' * 51
|
118
|
-
t.should_not be_valid
|
119
|
-
t.errors.on(:name).should include('Name must be less than 50 characters long')
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should auto validate the primitive type" do
|
123
|
-
validator = SailBoat.validators.context(:primitive_test).first
|
124
|
-
validator.should be_kind_of(DataMapper::Validate::PrimitiveValidator)
|
125
|
-
boat = SailBoat.new
|
126
|
-
boat.should be_valid_for_primitive_test
|
127
|
-
boat.build_date = 'ABC'
|
128
|
-
boat.should_not be_valid_for_primitive_test
|
129
|
-
boat.errors.on(:build_date).should include('Build date must be of type Date')
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should not auto add any validators if the option :auto_validation => false was given" do
|
133
|
-
klass = Class.new do
|
134
|
-
include DataMapper::Resource
|
135
|
-
property :id, Integer, :serial => true, :auto_validation => false
|
136
|
-
property :name, String, :nullable => false, :auto_validation => false
|
137
|
-
property :bool, DataMapper::Types::Boolean, :nullable => false, :auto_validation => false
|
138
|
-
end
|
139
|
-
klass.new.valid?.should == true
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should auto add range checking the length of a string while still allowing null values" do
|
143
|
-
boat = SailBoat.new
|
144
|
-
boat.allow_nil = 'ABC'
|
145
|
-
boat.should_not be_valid_for_nil_test
|
146
|
-
boat.errors.on(:allow_nil).should include('Allow nil must be between 5 and 10 characters long')
|
147
|
-
|
148
|
-
boat.allow_nil = 'ABCDEFG'
|
149
|
-
boat.should be_valid_for_nil_test
|
150
|
-
|
151
|
-
boat.allow_nil = 'ABCDEFGHIJKLMNOP'
|
152
|
-
boat.should_not be_valid_for_nil_test
|
153
|
-
boat.errors.on(:allow_nil).should include('Allow nil must be between 5 and 10 characters long')
|
154
|
-
|
155
|
-
boat.allow_nil = nil
|
156
|
-
boat.should be_valid_for_nil_test
|
157
|
-
end
|
158
|
-
|
159
|
-
describe 'for Integer properties' do
|
160
|
-
before do
|
161
|
-
@boat = SailBoat.new
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'should allow integers' do
|
165
|
-
@boat.set(:id => 1)
|
166
|
-
@boat.should be_valid
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'should not allow floats' do
|
170
|
-
@boat.set(:id => 1.0)
|
171
|
-
@boat.should_not be_valid
|
172
|
-
@boat.errors.on(:id).should include('Id must be an integer')
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'should not allow decimals' do
|
176
|
-
@boat.set(:id => BigDecimal('1'))
|
177
|
-
@boat.should_not be_valid
|
178
|
-
@boat.errors.on(:id).should include('Id must be an integer')
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe 'for nullable Boolean properties' do
|
183
|
-
before do
|
184
|
-
@boat = HasNullableBoolean.new(:id => 1)
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'should allow true' do
|
188
|
-
@boat.set(:bool => true)
|
189
|
-
@boat.should be_valid
|
190
|
-
end
|
191
|
-
|
192
|
-
it 'should allow false' do
|
193
|
-
@boat.set(:bool => false)
|
194
|
-
@boat.should be_valid
|
195
|
-
end
|
196
|
-
|
197
|
-
it 'should allow nil' do
|
198
|
-
@boat.set(:bool => nil)
|
199
|
-
@boat.should be_valid
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
describe 'for non-nullable Boolean properties' do
|
204
|
-
before do
|
205
|
-
@boat = HasNotNullableBoolean.new(:id => 1)
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'should allow true' do
|
209
|
-
@boat.set(:bool => true)
|
210
|
-
@boat.should be_valid
|
211
|
-
end
|
212
|
-
|
213
|
-
it 'should allow false' do
|
214
|
-
@boat.set(:bool => false)
|
215
|
-
@boat.should be_valid
|
216
|
-
end
|
217
|
-
|
218
|
-
it 'should not allow nil' do
|
219
|
-
@boat.set(:bool => nil)
|
220
|
-
@boat.should_not be_valid
|
221
|
-
@boat.errors.on(:bool).should include('Bool must not be nil')
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
describe 'for non-nullable ParanoidBoolean properties' do
|
226
|
-
before do
|
227
|
-
@boat = HasNotNullableParanoidBoolean.new(:id => 1)
|
228
|
-
end
|
229
|
-
|
230
|
-
it 'should allow true' do
|
231
|
-
@boat.set(:bool => true)
|
232
|
-
@boat.should be_valid
|
233
|
-
end
|
234
|
-
|
235
|
-
it 'should allow false' do
|
236
|
-
@boat.set(:bool => false)
|
237
|
-
@boat.should be_valid
|
238
|
-
end
|
239
|
-
|
240
|
-
it 'should not allow nil' do
|
241
|
-
@boat.set(:bool => nil)
|
242
|
-
@boat.should_not be_valid
|
243
|
-
@boat.errors.on(:bool).should include('Bool must not be nil')
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
{ :float => Float, :big_decimal => BigDecimal }.each do |column, type|
|
248
|
-
describe "for #{type} properties" do
|
249
|
-
before do
|
250
|
-
@boat = SailBoat.new(:id => 1)
|
251
|
-
end
|
252
|
-
|
253
|
-
it 'should allow integers' do
|
254
|
-
@boat.set(column => 1)
|
255
|
-
@boat.should be_valid
|
256
|
-
end
|
257
|
-
|
258
|
-
it 'should allow floats' do
|
259
|
-
@boat.set(column => '1.0')
|
260
|
-
@boat.should be_valid
|
261
|
-
end
|
262
|
-
|
263
|
-
it 'should allow decimals' do
|
264
|
-
@boat.set(column => BigDecimal('1'))
|
265
|
-
@boat.should be_valid
|
266
|
-
end
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
describe 'for within validator' do
|
271
|
-
before :all do
|
272
|
-
class ::LimitedBoat
|
273
|
-
include DataMapper::Resource
|
274
|
-
property :id, Integer, :serial => true
|
275
|
-
property :limited, String, :set => ['foo', 'bar', 'bang'], :default => 'foo'
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
before do
|
280
|
-
@boat = LimitedBoat.new
|
281
|
-
end
|
282
|
-
|
283
|
-
it 'should set default value' do
|
284
|
-
@boat.should be_valid
|
285
|
-
end
|
286
|
-
|
287
|
-
it 'should not accept value not in range' do
|
288
|
-
@boat.limited = "blah"
|
289
|
-
@boat.should_not be_valid
|
290
|
-
@boat.errors.on(:limited).should include('Limited must be one of [foo, bar, bang]')
|
291
|
-
end
|
292
|
-
|
293
|
-
end
|
294
|
-
|
295
|
-
describe 'for custom messages' do
|
296
|
-
it "should have correct error message" do
|
297
|
-
custom_boat = Class.new do
|
298
|
-
include DataMapper::Resource
|
299
|
-
property :id, Integer, :serial => true
|
300
|
-
property :name, String, :nullable => false, :message => "This boat must have name"
|
301
|
-
end
|
302
|
-
boat = custom_boat.new
|
303
|
-
boat.should_not be_valid
|
304
|
-
boat.errors.on(:name).should include('This boat must have name')
|
305
|
-
end
|
306
|
-
|
307
|
-
it "should have correct error messages" do
|
308
|
-
custom_boat = Class.new do
|
309
|
-
include DataMapper::Resource
|
310
|
-
property :id, Integer, :serial => true
|
311
|
-
property :name, String, :nullable => false, :length => 5..20, :format => /^[a-z]+$/,
|
312
|
-
:messages => {
|
313
|
-
:presence => "This boat must have name",
|
314
|
-
:length => "Name must have at least 4 and at most 20 chars",
|
315
|
-
:format => "Please use only small letters"
|
316
|
-
}
|
317
|
-
end
|
318
|
-
|
319
|
-
boat = custom_boat.new
|
320
|
-
boat.should_not be_valid
|
321
|
-
boat.errors.on(:name).should include("This boat must have name")
|
322
|
-
boat.errors.on(:name).should include("Name must have at least 4 and at most 20 chars")
|
323
|
-
boat.errors.on(:name).should include("Please use only small letters")
|
324
|
-
|
325
|
-
boat.name = "%%"
|
326
|
-
boat.should_not be_valid
|
327
|
-
boat.errors.on(:name).should_not include("This boat must have name")
|
328
|
-
boat.errors.on(:name).should include("Name must have at least 4 and at most 20 chars")
|
329
|
-
boat.errors.on(:name).should include("Please use only small letters")
|
330
|
-
|
331
|
-
boat.name = "%%asd"
|
332
|
-
boat.should_not be_valid
|
333
|
-
boat.errors.on(:name).should_not include("This boat must have name")
|
334
|
-
boat.errors.on(:name).should_not include("Name must have at least 4 and at most 20 chars")
|
335
|
-
boat.errors.on(:name).should include("Please use only small letters")
|
336
|
-
|
337
|
-
boat.name = "superboat"
|
338
|
-
boat.should be_valid
|
339
|
-
boat.errors.on(:name).should be_nil
|
340
|
-
end
|
341
|
-
end
|
342
|
-
end
|