dm-validations 0.9.3 → 0.9.4
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/Manifest.txt +2 -0
- data/lib/dm-validations.rb +10 -8
- data/lib/dm-validations/auto_validate.rb +11 -2
- data/lib/dm-validations/block_validator.rb +60 -0
- data/lib/dm-validations/contextual_validators.rb +4 -4
- data/lib/dm-validations/format_validator.rb +13 -13
- data/lib/dm-validations/generic_validator.rb +19 -13
- data/lib/dm-validations/method_validator.rb +15 -5
- data/lib/dm-validations/numeric_validator.rb +2 -2
- data/lib/dm-validations/uniqueness_validator.rb +5 -2
- data/lib/dm-validations/version.rb +2 -2
- data/lib/dm-validations/within_validator.rb +17 -5
- data/spec/integration/auto_validate_spec.rb +24 -0
- data/spec/integration/block_validator_spec.rb +36 -0
- data/spec/integration/format_validator_spec.rb +50 -12
- data/spec/integration/length_validator_spec.rb +1 -1
- data/spec/integration/method_validator_spec.rb +27 -0
- data/spec/integration/numeric_validator_spec.rb +5 -5
- data/spec/integration/uniqueness_validator_spec.rb +14 -0
- data/spec/integration/validation_spec.rb +1 -1
- data/spec/integration/within_validator_spec.rb +19 -0
- data/spec/spec_helper.rb +1 -1
- metadata +5 -3
data/Manifest.txt
CHANGED
@@ -8,6 +8,7 @@ lib/dm-validations.rb
|
|
8
8
|
lib/dm-validations/absent_field_validator.rb
|
9
9
|
lib/dm-validations/acceptance_validator.rb
|
10
10
|
lib/dm-validations/auto_validate.rb
|
11
|
+
lib/dm-validations/block_validator.rb
|
11
12
|
lib/dm-validations/confirmation_validator.rb
|
12
13
|
lib/dm-validations/contextual_validators.rb
|
13
14
|
lib/dm-validations/custom_validator.rb
|
@@ -27,6 +28,7 @@ lib/dm-validations/within_validator.rb
|
|
27
28
|
spec/integration/absent_field_validator_spec.rb
|
28
29
|
spec/integration/acceptance_validator_spec.rb
|
29
30
|
spec/integration/auto_validate_spec.rb
|
31
|
+
spec/integration/block_validator_spec.rb
|
30
32
|
spec/integration/confirmation_validator_spec.rb
|
31
33
|
spec/integration/contextual_validators_spec.rb
|
32
34
|
spec/integration/custom_validator_spec.rb
|
data/lib/dm-validations.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'pathname'
|
3
3
|
|
4
|
-
gem 'dm-core', '=0.9.
|
4
|
+
gem 'dm-core', '=0.9.4'
|
5
5
|
require 'dm-core'
|
6
6
|
|
7
7
|
dir = Pathname(__FILE__).dirname.expand_path / 'dm-validations'
|
@@ -20,6 +20,7 @@ require dir / 'length_validator'
|
|
20
20
|
require dir / 'within_validator'
|
21
21
|
require dir / 'numeric_validator'
|
22
22
|
require dir / 'method_validator'
|
23
|
+
require dir / 'block_validator'
|
23
24
|
require dir / 'uniqueness_validator'
|
24
25
|
require dir / 'acceptance_validator'
|
25
26
|
require dir / 'custom_validator'
|
@@ -30,13 +31,13 @@ module DataMapper
|
|
30
31
|
module Validate
|
31
32
|
|
32
33
|
def self.included(model)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
35
|
+
if method_defined?(:save) && !method_defined?(:save!)
|
36
|
+
alias save! save
|
37
|
+
alias save save_with_validations
|
38
|
+
end
|
39
|
+
|
40
|
+
class << self
|
40
41
|
def create(attributes = {}, context = :default)
|
41
42
|
resource = new(attributes)
|
42
43
|
return resource unless resource.valid?(context)
|
@@ -150,6 +151,7 @@ module DataMapper
|
|
150
151
|
include DataMapper::Validate::ValidatesWithin
|
151
152
|
include DataMapper::Validate::ValidatesIsNumber
|
152
153
|
include DataMapper::Validate::ValidatesWithMethod
|
154
|
+
include DataMapper::Validate::ValidatesWithBlock
|
153
155
|
include DataMapper::Validate::ValidatesIsUnique
|
154
156
|
include DataMapper::Validate::AutoValidate
|
155
157
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module DataMapper
|
2
2
|
class Property
|
3
3
|
# for options_with_message
|
4
|
-
PROPERTY_OPTIONS << :message << :messages
|
4
|
+
PROPERTY_OPTIONS << :message << :messages << :set
|
5
5
|
end
|
6
6
|
|
7
7
|
module Validate
|
@@ -47,6 +47,10 @@ module DataMapper
|
|
47
47
|
# Setting the :format option causes a validates_format_of
|
48
48
|
# validator to be automatically created on the property
|
49
49
|
#
|
50
|
+
# :set => ["foo", "bar", "baz"]
|
51
|
+
# Setting the :set option causes a validates_within
|
52
|
+
# validator to be automatically created on the property
|
53
|
+
#
|
50
54
|
# Integer type
|
51
55
|
# Using a Integer type causes a validates_is_number
|
52
56
|
# validator to be created for the property. integer_only
|
@@ -65,7 +69,7 @@ module DataMapper
|
|
65
69
|
# with custom ones. For instance:
|
66
70
|
# :messages => {:presence => "Field is required",
|
67
71
|
# :format => "Field has invalid format"}
|
68
|
-
# Hash keys are: :presence, :format, :length, :is_unique,
|
72
|
+
# Hash keys are: :presence, :format, :length, :is_unique,
|
69
73
|
# :is_number, :is_primitive
|
70
74
|
#
|
71
75
|
# :message => "Some message"
|
@@ -118,6 +122,11 @@ module DataMapper
|
|
118
122
|
end
|
119
123
|
end
|
120
124
|
|
125
|
+
# within validator
|
126
|
+
if property.options.has_key?(:set)
|
127
|
+
validates_within property.name, options_with_message({:set => property.options[:set]}, property, :within)
|
128
|
+
end
|
129
|
+
|
121
130
|
# numeric validator
|
122
131
|
if Integer == property.type
|
123
132
|
opts[:integer_only] = true
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Validate
|
3
|
+
|
4
|
+
##
|
5
|
+
#
|
6
|
+
# @author teamon
|
7
|
+
# @since 0.9
|
8
|
+
module ValidatesWithBlock
|
9
|
+
|
10
|
+
##
|
11
|
+
# Validate using the given block. The block given needs to return:
|
12
|
+
# [result::<Boolean>, Error Message::<String>]
|
13
|
+
#
|
14
|
+
# @example [Usage]
|
15
|
+
# require 'dm-validations'
|
16
|
+
#
|
17
|
+
# class Page
|
18
|
+
# include DataMapper::Resource
|
19
|
+
#
|
20
|
+
# property :zip_code, String
|
21
|
+
#
|
22
|
+
# validates_with_block do
|
23
|
+
# if @zip_code == "94301"
|
24
|
+
# true
|
25
|
+
# else
|
26
|
+
# [false, "You're in the wrong zip code"]
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# # A call to valid? will return false and
|
31
|
+
# # populate the object's errors with "You're in the
|
32
|
+
# # wrong zip code" unless zip_code == "94301"
|
33
|
+
#
|
34
|
+
# # You can also specify field:
|
35
|
+
#
|
36
|
+
# validates_with_block :zip_code do
|
37
|
+
# if @zip_code == "94301"
|
38
|
+
# true
|
39
|
+
# else
|
40
|
+
# [false, "You're in the wrong zip code"]
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# # it will add returned error message to :zip_code field
|
45
|
+
#
|
46
|
+
def validates_with_block(*fields, &block)
|
47
|
+
@__validates_with_block_count ||= 0
|
48
|
+
@__validates_with_block_count += 1
|
49
|
+
# create method and pass it to MethodValidator
|
50
|
+
raise ArgumentError.new('You need to pass a block to validates_with_block method') unless block_given?
|
51
|
+
method_name = "__validates_with_block_#{@__validates_with_block_count}".to_sym
|
52
|
+
define_method(method_name, block)
|
53
|
+
opts = opts_from_validator_args(fields)
|
54
|
+
opts[:method] = method_name
|
55
|
+
add_validator_to_context(opts, fields.empty? ? [method_name] : fields, DataMapper::Validate::MethodValidator)
|
56
|
+
end
|
57
|
+
|
58
|
+
end # module ValidatesWithMethod
|
59
|
+
end # module Validate
|
60
|
+
end # module DataMapper
|
@@ -44,11 +44,11 @@ module DataMapper
|
|
44
44
|
target.errors.clear!
|
45
45
|
result = true
|
46
46
|
context(named_context).each do |validator|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
47
|
+
next unless validator.execute?(target)
|
48
|
+
result = false unless validator.call(target)
|
50
49
|
end
|
51
|
-
|
50
|
+
|
51
|
+
result
|
52
52
|
end
|
53
53
|
|
54
54
|
end # module ContextualValidators
|
@@ -25,27 +25,27 @@ module DataMapper
|
|
25
25
|
value = target.validation_property_value(@field_name)
|
26
26
|
return true if @options[:allow_nil] && value.nil?
|
27
27
|
|
28
|
-
validation =
|
28
|
+
validation = @options[:as] || @options[:with]
|
29
29
|
|
30
30
|
raise "No such predefined format '#{validation}'" if validation.is_a?(Symbol) && !FORMATS.has_key?(validation)
|
31
31
|
validator = validation.is_a?(Symbol) ? FORMATS[validation][0] : validation
|
32
32
|
|
33
|
-
field = Extlib::Inflection.humanize(@field_name)
|
34
|
-
error_message = @options[:message] || '%s has an invalid format'.t(field)
|
35
|
-
|
36
33
|
valid = case validator
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
when Proc then validator.call(value)
|
35
|
+
when Regexp then value =~ validator
|
36
|
+
else
|
37
|
+
raise UnknownValidationFormat, "Can't determine how to validate #{target.class}##{@field_name} with #{validator.inspect}"
|
40
38
|
end
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
return true if valid
|
41
|
+
|
42
|
+
field = Extlib::Inflection.humanize(@field_name)
|
43
|
+
error_message = @options[:message] || '%s has an invalid format'.t(field)
|
44
|
+
error_message = error_message.call(field, value) if error_message.respond_to?(:call)
|
45
|
+
|
46
|
+
add_error(target, error_message, @field_name)
|
47
47
|
|
48
|
-
|
48
|
+
false
|
49
49
|
end
|
50
50
|
|
51
51
|
#class UnknownValidationFormat < StandardError; end
|
@@ -67,24 +67,30 @@ module DataMapper
|
|
67
67
|
# @param <Object> target the resource that we check against
|
68
68
|
# @return <Boolean> true if should be run, otherwise false
|
69
69
|
def execute?(target)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
return false if
|
75
|
-
elsif self.unless_clause.respond_to?(:call)
|
76
|
-
return false if self.unless_clause.call(target)
|
70
|
+
if unless_clause = self.unless_clause
|
71
|
+
if unless_clause.is_a?(Symbol)
|
72
|
+
return false if target.send(unless_clause)
|
73
|
+
elsif unless_clause.respond_to?(:call)
|
74
|
+
return false if unless_clause.call(target)
|
77
75
|
end
|
78
76
|
end
|
79
77
|
|
80
|
-
if self.if_clause
|
81
|
-
if
|
82
|
-
return target.send(
|
83
|
-
elsif
|
84
|
-
return
|
78
|
+
if if_clause = self.if_clause
|
79
|
+
if if_clause.is_a?(Symbol)
|
80
|
+
return target.send(if_clause)
|
81
|
+
elsif if_clause.respond_to?(:call)
|
82
|
+
return if_clause.call(target)
|
85
83
|
end
|
86
84
|
end
|
87
|
-
|
85
|
+
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
def ==(other)
|
90
|
+
self.field_name == other.field_name &&
|
91
|
+
self.if_clause == other.if_clause &&
|
92
|
+
self.unless_clause == other.unless_clause &&
|
93
|
+
self.instance_variable_get(:@options) == other.instance_variable_get(:@options)
|
88
94
|
end
|
89
95
|
|
90
96
|
end # class GenericValidator
|
@@ -7,17 +7,21 @@ module DataMapper
|
|
7
7
|
# @since 0.9
|
8
8
|
class MethodValidator < GenericValidator
|
9
9
|
|
10
|
-
def initialize(
|
10
|
+
def initialize(field_name, options={})
|
11
11
|
super
|
12
|
-
@
|
13
|
-
@options[:
|
12
|
+
@field_name, @options = field_name, options.clone
|
13
|
+
@options[:method] = @field_name unless @options.has_key?(:method)
|
14
14
|
end
|
15
15
|
|
16
16
|
def call(target)
|
17
|
-
result,message = target.send(@
|
18
|
-
add_error(target,message,@
|
17
|
+
result,message = target.send(@options[:method])
|
18
|
+
add_error(target,message,@field_name) if !result
|
19
19
|
result
|
20
20
|
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
@options[:method] == other.instance_variable_get(:@options)[:method] && super
|
24
|
+
end
|
21
25
|
end # class MethodValidator
|
22
26
|
|
23
27
|
module ValidatesWithMethod
|
@@ -48,6 +52,12 @@ module DataMapper
|
|
48
52
|
# # populate the object's errors with "You're in the
|
49
53
|
# # wrong zip code" unless zip_code == "94301"
|
50
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
|
+
#
|
51
61
|
def validates_with_method(*fields)
|
52
62
|
opts = opts_from_validator_args(fields)
|
53
63
|
add_validator_to_context(opts, fields, DataMapper::Validate::MethodValidator)
|
@@ -49,10 +49,10 @@ module DataMapper
|
|
49
49
|
end
|
50
50
|
elsif precision && scale.nil?
|
51
51
|
# for floats, if scale is not set
|
52
|
-
|
52
|
+
|
53
53
|
#total number of digits is less or equal precision
|
54
54
|
return true if value.gsub(/[^\d]/,'').length <= precision
|
55
|
-
|
55
|
+
|
56
56
|
#number of digits before decimal == precision, and the number is x.0. same as scale = 0
|
57
57
|
return true if value =~ /\A[+-]?(?:\d{1,#{precision}}(?:\.0)?)\z/
|
58
58
|
else
|
@@ -21,7 +21,10 @@ module DataMapper
|
|
21
21
|
|
22
22
|
repository_name = target.repository.name
|
23
23
|
|
24
|
-
opts = {
|
24
|
+
opts = {
|
25
|
+
:fields => target.model.key,
|
26
|
+
field_name => target.validation_property_value(field_name)
|
27
|
+
}
|
25
28
|
|
26
29
|
scope.each do |item|
|
27
30
|
if target.model.properties(repository_name).has_property?(item)
|
@@ -38,7 +41,7 @@ module DataMapper
|
|
38
41
|
return true if resource.nil?
|
39
42
|
|
40
43
|
# is target and found resource identic? same instance... but not ==
|
41
|
-
return true if resource.repository.name == repository_name && resource.model == target.model && resource.key == target.key
|
44
|
+
return true if !target.new_record? && resource.repository.name == repository_name && resource.model == target.model && resource.key == target.key
|
42
45
|
|
43
46
|
error_message = @options[:message] || "%s is already taken".t(Extlib::Inflection.humanize(field_name))
|
44
47
|
add_error(target, error_message , field_name)
|
@@ -17,14 +17,26 @@ module DataMapper
|
|
17
17
|
includes = @options[:set].include?(target.send(field_name))
|
18
18
|
return true if includes
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
if @options[:set].is_a?(Range)
|
21
|
+
if @options[:set].first != -n && @options[:set].last != n
|
22
|
+
message = "%s must be between #{@options[:set].first} and #{@options[:set].last}"
|
23
|
+
elsif @options[:set].first == -n
|
24
|
+
message = "%s must be less than #{@options[:set].last}"
|
25
|
+
elsif @options[:set].last == n
|
26
|
+
message = "%s must be greater than #{@options[:set].first}"
|
27
|
+
end
|
28
|
+
else
|
29
|
+
message = "%s must be one of [#{ @options[:set].join(', ')}]"
|
30
|
+
end
|
31
|
+
|
32
|
+
error_message = @options[:message] || message.t(Extlib::Inflection.humanize(@field_name))
|
25
33
|
add_error(target, error_message , @field_name)
|
26
34
|
return false
|
27
35
|
end
|
36
|
+
|
37
|
+
def n
|
38
|
+
1.0/0
|
39
|
+
end
|
28
40
|
end # class WithinValidator
|
29
41
|
|
30
42
|
module ValidatesWithin
|
@@ -260,6 +260,30 @@ describe "Automatic Validation from Property Definition" do
|
|
260
260
|
end
|
261
261
|
end
|
262
262
|
|
263
|
+
describe 'for within validator' do
|
264
|
+
before :all do
|
265
|
+
class LimitedBoat
|
266
|
+
include DataMapper::Resource
|
267
|
+
property :id, Integer, :serial => true
|
268
|
+
property :limited, String, :set => ['foo', 'bar', 'bang'], :default => 'foo'
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
before do
|
273
|
+
@boat = LimitedBoat.new
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'should set default value' do
|
277
|
+
@boat.should be_valid
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'should not accept value not in range' do
|
281
|
+
@boat.limited = "blah"
|
282
|
+
@boat.should_not be_valid
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
|
263
287
|
describe 'for custom messages' do
|
264
288
|
it "should have correct error message" do
|
265
289
|
custom_boat = Class.new do
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
|
+
|
4
|
+
describe DataMapper::Validate::ValidatesWithBlock do
|
5
|
+
before(:all) do
|
6
|
+
class Ship
|
7
|
+
include DataMapper::Resource
|
8
|
+
property :id, Integer, :key => true
|
9
|
+
property :name, String
|
10
|
+
|
11
|
+
validates_with_block :when => [:testing_failure] do
|
12
|
+
[false, 'Validation failed']
|
13
|
+
end
|
14
|
+
validates_with_block :when => [:testing_success] do
|
15
|
+
true
|
16
|
+
end
|
17
|
+
validates_with_block :name, :when => [:testing_name_validation] do
|
18
|
+
[false, 'Name is invalid']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should validate via a block on the resource" do
|
24
|
+
Ship.new.valid_for_testing_failure?.should == false
|
25
|
+
Ship.new.valid_for_testing_success?.should == true
|
26
|
+
ship = Ship.new
|
27
|
+
ship.valid_for_testing_failure?.should == false
|
28
|
+
ship.errors.full_messages.include?('Validation failed').should == true
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should validate via a block and add error to field" do
|
32
|
+
ship = Ship.new
|
33
|
+
ship.should_not be_valid_for_testing_name_validation
|
34
|
+
ship.errors.on(:name).should include('Name is invalid')
|
35
|
+
end
|
36
|
+
end
|
@@ -2,35 +2,43 @@ require 'pathname'
|
|
2
2
|
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
3
|
|
4
4
|
describe DataMapper::Validate::FormatValidator do
|
5
|
-
before
|
5
|
+
before :all do
|
6
6
|
class BillOfLading
|
7
7
|
include DataMapper::Resource
|
8
|
-
|
9
|
-
property :
|
10
|
-
property :
|
8
|
+
|
9
|
+
property :id, Serial
|
10
|
+
property :doc_no, String, :auto_validation => false
|
11
|
+
property :email, String, :auto_validation => false
|
12
|
+
property :username, String, :auto_validation => false
|
11
13
|
|
12
14
|
# this is a trivial example
|
13
15
|
validates_format :doc_no, :with => lambda { |code|
|
14
|
-
|
16
|
+
code =~ /\AA\d{4}\z/ || code =~ /\A[B-Z]\d{6}X12\z/
|
15
17
|
}
|
16
18
|
|
17
19
|
validates_format :email, :as => :email_address
|
20
|
+
|
21
|
+
validates_format :username, :with => /[a-z]/, :message => 'Username must have at least one letter', :allow_nil => true
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
25
|
+
def valid_attributes
|
26
|
+
{ :id => 1, :doc_no => 'A1234', :email => 'user@example.com' }
|
27
|
+
end
|
28
|
+
|
21
29
|
it 'should validate the format of a value on an instance of a resource' do
|
22
|
-
bol = BillOfLading.new
|
30
|
+
bol = BillOfLading.new(valid_attributes)
|
31
|
+
bol.should be_valid
|
32
|
+
|
23
33
|
bol.doc_no = 'BAD CODE :)'
|
24
34
|
bol.should_not be_valid
|
25
35
|
bol.errors.on(:doc_no).should include('Doc no has an invalid format')
|
26
36
|
|
27
37
|
bol.doc_no = 'A1234'
|
28
|
-
bol.
|
29
|
-
bol.errors.on(:doc_no).should be_nil
|
38
|
+
bol.should be_valid
|
30
39
|
|
31
40
|
bol.doc_no = 'B123456X12'
|
32
|
-
bol.
|
33
|
-
bol.errors.on(:doc_no).should be_nil
|
41
|
+
bol.should be_valid
|
34
42
|
end
|
35
43
|
|
36
44
|
it 'should have a pre-defined e-mail format' do
|
@@ -55,7 +63,7 @@ describe DataMapper::Validate::FormatValidator do
|
|
55
63
|
'guy@123.com'
|
56
64
|
]
|
57
65
|
|
58
|
-
bol = BillOfLading.new
|
66
|
+
bol = BillOfLading.new(valid_attributes.except(:email))
|
59
67
|
bol.should_not be_valid
|
60
68
|
bol.errors.on(:email).should include('Email has an invalid format')
|
61
69
|
|
@@ -73,7 +81,37 @@ describe DataMapper::Validate::FormatValidator do
|
|
73
81
|
|
74
82
|
end
|
75
83
|
|
76
|
-
|
84
|
+
describe 'with a regexp' do
|
85
|
+
before do
|
86
|
+
@bol = BillOfLading.new(valid_attributes)
|
87
|
+
@bol.should be_valid
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'if matched' do
|
91
|
+
before do
|
92
|
+
@bol.username = 'a12345'
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should validate' do
|
96
|
+
@bol.should be_valid
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'if not matched' do
|
101
|
+
before do
|
102
|
+
@bol.username = '12345'
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should not validate' do
|
106
|
+
@bol.should_not be_valid
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should set an error message' do
|
110
|
+
@bol.valid?
|
111
|
+
@bol.errors.on(:username).should include('Username must have at least one letter')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
77
115
|
end
|
78
116
|
|
79
117
|
=begin
|
@@ -26,7 +26,7 @@ describe DataMapper::Validate::LengthValidator do
|
|
26
26
|
end
|
27
27
|
wock = Jabberwock.new
|
28
28
|
wock.valid?.should == false
|
29
|
-
wock.errors.full_messages.
|
29
|
+
wock.errors.full_messages.sort.last.should == 'worble warble'
|
30
30
|
wock.snickersnack = "hello"
|
31
31
|
wock.id = 1
|
32
32
|
wock.valid?.should == true
|
@@ -7,9 +7,12 @@ describe DataMapper::Validate::MethodValidator do
|
|
7
7
|
include DataMapper::Resource
|
8
8
|
property :id, Integer, :key => true
|
9
9
|
property :name, String
|
10
|
+
property :size, String
|
10
11
|
|
11
12
|
validates_with_method :fail_validation, :when => [:testing_failure]
|
12
13
|
validates_with_method :pass_validation, :when => [:testing_success]
|
14
|
+
validates_with_method :first_validation, :second_validation, :when => [:multiple_validations]
|
15
|
+
validates_with_method :name, :method => :name_validation, :when => [:testing_name_validation]
|
13
16
|
|
14
17
|
def fail_validation
|
15
18
|
return false, 'Validation failed'
|
@@ -18,6 +21,18 @@ describe DataMapper::Validate::MethodValidator do
|
|
18
21
|
def pass_validation
|
19
22
|
return true
|
20
23
|
end
|
24
|
+
|
25
|
+
def first_validation
|
26
|
+
return true
|
27
|
+
end
|
28
|
+
|
29
|
+
def second_validation
|
30
|
+
return false, 'Second Validation was false'
|
31
|
+
end
|
32
|
+
|
33
|
+
def name_validation
|
34
|
+
return false, 'Name is invalid'
|
35
|
+
end
|
21
36
|
end
|
22
37
|
end
|
23
38
|
|
@@ -28,4 +43,16 @@ describe DataMapper::Validate::MethodValidator do
|
|
28
43
|
ship.valid_for_testing_failure?.should == false
|
29
44
|
ship.errors.full_messages.include?('Validation failed').should == true
|
30
45
|
end
|
46
|
+
|
47
|
+
it "should run multiple validation methods" do
|
48
|
+
ship = Ship.new
|
49
|
+
ship.valid_for_multiple_validations?.should == false
|
50
|
+
ship.errors.full_messages.should include('Second Validation was false')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should validate via a method and add error to field" do
|
54
|
+
ship = Ship.new
|
55
|
+
ship.should_not be_valid_for_testing_name_validation
|
56
|
+
ship.errors.on(:name).should include('Name is invalid')
|
57
|
+
end
|
31
58
|
end
|
@@ -89,19 +89,19 @@ describe DataMapper::Validate::NumericValidator do
|
|
89
89
|
@cloud_fish.average_weight = 0
|
90
90
|
@cloud_fish.should be_valid
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
it 'should allow any digits after the decimal' do
|
94
94
|
@cloud_fish.average_weight = 1.2
|
95
95
|
@cloud_fish.should be_valid
|
96
|
-
|
96
|
+
|
97
97
|
@cloud_fish.average_weight = 123.456
|
98
98
|
@cloud_fish.should be_valid
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
it "should only allow up to 10 digits overall" do
|
102
102
|
@cloud_fish.average_weight = 1.234567890
|
103
103
|
@cloud_fish.should be_valid
|
104
|
-
|
104
|
+
|
105
105
|
@cloud_fish.average_weight = 1.2345678901
|
106
106
|
@cloud_fish.should_not be_valid
|
107
107
|
end
|
@@ -156,7 +156,7 @@ describe DataMapper::Validate::NumericValidator do
|
|
156
156
|
before do
|
157
157
|
@gold_fish = GoldFish.new
|
158
158
|
end
|
159
|
-
|
159
|
+
|
160
160
|
it "should have scale of 2" do
|
161
161
|
@gold_fish.model.average_weight.scale.should == 2
|
162
162
|
end
|
@@ -65,6 +65,20 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
it 'should validate uniqueness on a string key' do
|
69
|
+
class Department
|
70
|
+
include DataMapper::Resource
|
71
|
+
property :name, String, :key => true
|
72
|
+
|
73
|
+
validates_is_unique :name
|
74
|
+
auto_migrate!
|
75
|
+
end
|
76
|
+
|
77
|
+
hr = Department.create(:name => "HR")
|
78
|
+
hr2 = Department.new(:name => "HR")
|
79
|
+
hr2.valid?.should == false
|
80
|
+
end
|
81
|
+
|
68
82
|
it 'should validate the uniqueness of a value with scope' do
|
69
83
|
repository do
|
70
84
|
u = User.new(:id => 2, :organisation_id=>1, :user_name => 'guy')
|
@@ -108,7 +108,7 @@ describe DataMapper::Validate do
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
-
it "should respond to validatable? (for recursing
|
111
|
+
it "should respond to validatable? (for recursing associations)" do
|
112
112
|
Yacht.new.should be_validatable
|
113
113
|
Class.new.new.should_not be_validatable
|
114
114
|
end
|
@@ -10,6 +10,17 @@ describe DataMapper::Validate::WithinValidator do
|
|
10
10
|
validates_within :type_of_number, :set => ['Home','Work','Cell']
|
11
11
|
end
|
12
12
|
|
13
|
+
class Inf
|
14
|
+
include DataMapper::Resource
|
15
|
+
property :id, Integer, :serial => true
|
16
|
+
property :greater_than, String, :auto_validation => false
|
17
|
+
property :less_than, String, :auto_validation => false
|
18
|
+
property :between, String, :auto_validation => false
|
19
|
+
validates_within :greater_than, :set => (10..n)
|
20
|
+
validates_within :less_than, :set => (-n..10)
|
21
|
+
validates_within :between, :set => (10..20)
|
22
|
+
end
|
23
|
+
|
13
24
|
class Reciever
|
14
25
|
include DataMapper::Resource
|
15
26
|
property :id, Integer, :serial => true
|
@@ -28,6 +39,14 @@ describe DataMapper::Validate::WithinValidator do
|
|
28
39
|
tel.valid?.should == true
|
29
40
|
end
|
30
41
|
|
42
|
+
it "should validate a value within range with infinity" do
|
43
|
+
inf = Inf.new
|
44
|
+
inf.should_not be_valid
|
45
|
+
inf.errors.on(:greater_than).first.should == 'Greater than must be greater than 10'
|
46
|
+
inf.errors.on(:less_than).first.should == 'Less than must be less than 10'
|
47
|
+
inf.errors.on(:between).first.should == 'Between must be between 10 and 20'
|
48
|
+
end
|
49
|
+
|
31
50
|
it "should validate a value by its default" do
|
32
51
|
tel = Reciever.new
|
33
52
|
tel.should be_valid
|
data/spec/spec_helper.rb
CHANGED
@@ -9,7 +9,7 @@ def load_driver(name, default_uri)
|
|
9
9
|
lib = "do_#{name}"
|
10
10
|
|
11
11
|
begin
|
12
|
-
gem lib, '=0.9.
|
12
|
+
gem lib, '=0.9.4'
|
13
13
|
require lib
|
14
14
|
DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
|
15
15
|
DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guy van den Berg
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-08-21 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - "="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.9.
|
23
|
+
version: 0.9.4
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: hoe
|
@@ -54,6 +54,7 @@ files:
|
|
54
54
|
- lib/dm-validations/absent_field_validator.rb
|
55
55
|
- lib/dm-validations/acceptance_validator.rb
|
56
56
|
- lib/dm-validations/auto_validate.rb
|
57
|
+
- lib/dm-validations/block_validator.rb
|
57
58
|
- lib/dm-validations/confirmation_validator.rb
|
58
59
|
- lib/dm-validations/contextual_validators.rb
|
59
60
|
- lib/dm-validations/custom_validator.rb
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- spec/integration/absent_field_validator_spec.rb
|
74
75
|
- spec/integration/acceptance_validator_spec.rb
|
75
76
|
- spec/integration/auto_validate_spec.rb
|
77
|
+
- spec/integration/block_validator_spec.rb
|
76
78
|
- spec/integration/confirmation_validator_spec.rb
|
77
79
|
- spec/integration/contextual_validators_spec.rb
|
78
80
|
- spec/integration/custom_validator_spec.rb
|