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