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 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
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'pathname'
3
3
 
4
- gem 'dm-core', '=0.9.3'
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
- if model.method_defined?(:save) && !model.method_defined?(:save!)
34
- model.send(:alias_method, :save!, :save)
35
- model.send(:alias_method, :save, :save_with_validations)
36
- end
37
- model.class_eval <<-EOS
38
- class << self
39
- method_defined?(:create) && !method_defined?(:create!)
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
- if validator.execute?(target)
48
- result = false if !validator.call(target)
49
- end
47
+ next unless validator.execute?(target)
48
+ result = false unless validator.call(target)
50
49
  end
51
- return result
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 = (@options[:as] || @options[:with])
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
- when Proc then validator.call(value)
38
- when Regexp then validator =~ value
39
- else raise UnknownValidationFormat, "Can't determine how to validate #{target.class}##{@field_name} with #{validator.inspect}"
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
- unless valid
43
- error_message = @options[:message] || error_message || '%s is invalid'.t(field)
44
- error_message = error_message.call(field, value) if Proc === error_message
45
- add_error(target, error_message , @field_name)
46
- end
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
- return valid
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
- return true if self.if_clause.nil? && self.unless_clause.nil?
71
-
72
- if self.unless_clause
73
- if self.unless_clause.is_a?(Symbol)
74
- return false if target.send(self.unless_clause)
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 self.if_clause.is_a?(Symbol)
82
- return target.send(self.if_clause)
83
- elsif self.if_clause.respond_to?(:call)
84
- return self.if_clause.call(target)
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
- return true
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(method_name, options={})
10
+ def initialize(field_name, options={})
11
11
  super
12
- @method_name, @options = method_name, options
13
- @options[:integer_only] = false unless @options.has_key?(:integer_only)
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(@method_name)
18
- add_error(target,message,@method_name) if !result
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 = { field_name => target.validation_property_value(field_name) }
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)
@@ -1,5 +1,5 @@
1
1
  module DataMapper
2
2
  module Validations
3
- VERSION = "0.9.3"
3
+ VERSION = "0.9.4"
4
4
  end
5
- end
5
+ end
@@ -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
- s = ''
21
- @options[:set].each {|item| s = s + "#{item}, "}
22
- s = '[' + s[0..(s.length-3)] + ']'
23
-
24
- error_message = @options[:message] || "%s must be one of #{s}".t(Extlib::Inflection.humanize(@field_name))
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(:all) do
5
+ before :all do
6
6
  class BillOfLading
7
7
  include DataMapper::Resource
8
- property :id, Integer, :key => true
9
- property :doc_no, String, :auto_validation => false
10
- property :email, String, :auto_validation => false
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
- (code =~ /A\d{4}/) || (code =~ /[B-Z]\d{6}X12/)
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.valid?
29
- bol.errors.on(:doc_no).should be_nil
38
+ bol.should be_valid
30
39
 
31
40
  bol.doc_no = 'B123456X12'
32
- bol.valid?
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
- it 'should have pre-defined formats'
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.first.should == 'worble warble'
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 assocations)" do
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.3'
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.3
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-07-24 00:00:00 -05:00
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.3
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