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