dm-validations 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1 @@
1
+
data/Manifest.txt ADDED
@@ -0,0 +1,45 @@
1
+ History.txt
2
+ LICENSE
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ TODO
7
+ lib/dm-validations.rb
8
+ lib/dm-validations/absent_field_validator.rb
9
+ lib/dm-validations/acceptance_validator.rb
10
+ lib/dm-validations/auto_validate.rb
11
+ lib/dm-validations/confirmation_validator.rb
12
+ lib/dm-validations/contextual_validators.rb
13
+ lib/dm-validations/custom_validator.rb
14
+ lib/dm-validations/format_validator.rb
15
+ lib/dm-validations/formats/email.rb
16
+ lib/dm-validations/generic_validator.rb
17
+ lib/dm-validations/length_validator.rb
18
+ lib/dm-validations/method_validator.rb
19
+ lib/dm-validations/numeric_validator.rb
20
+ lib/dm-validations/primitive_validator.rb
21
+ lib/dm-validations/required_field_validator.rb
22
+ lib/dm-validations/support/object.rb
23
+ lib/dm-validations/uniqueness_validator.rb
24
+ lib/dm-validations/validation_errors.rb
25
+ lib/dm-validations/version.rb
26
+ lib/dm-validations/within_validator.rb
27
+ spec/integration/absent_field_validator_spec.rb
28
+ spec/integration/acceptance_validator_spec.rb
29
+ spec/integration/auto_validate_spec.rb
30
+ spec/integration/confirmation_validator_spec.rb
31
+ spec/integration/contextual_validators_spec.rb
32
+ spec/integration/custom_validator_spec.rb
33
+ spec/integration/format_validator_spec.rb
34
+ spec/integration/generic_validator_spec.rb
35
+ spec/integration/length_validator_spec.rb
36
+ spec/integration/method_validator_spec.rb
37
+ spec/integration/numeric_validator_spec.rb
38
+ spec/integration/primitive_validator_spec.rb
39
+ spec/integration/required_field_validator_spec.rb
40
+ spec/integration/uniqueness_validator_spec.rb
41
+ spec/integration/validation_errors_spec.rb
42
+ spec/integration/validation_spec.rb
43
+ spec/integration/within_validator_spec.rb
44
+ spec/spec.opts
45
+ spec/spec_helper.rb
File without changes
data/Rakefile CHANGED
@@ -1,12 +1,24 @@
1
1
  require 'rubygems'
2
2
  require 'spec'
3
- require 'rake/clean'
4
- require 'rake/rdoctask'
5
- require 'rake/gempackagetask'
6
3
  require 'spec/rake/spectask'
7
4
  require 'pathname'
8
5
 
9
- CLEAN.include '{log,pkg}/'
6
+ ROOT = Pathname(__FILE__).dirname.expand_path
7
+ require ROOT + 'lib/dm-validations/version'
8
+
9
+ AUTHOR = "Guy van den Berg"
10
+ EMAIL = "vandenberg.guy@gmail.com"
11
+ GEM_NAME = "dm-validations"
12
+ GEM_VERSION = DataMapper::Validations::VERSION
13
+ GEM_DEPENDENCIES = [["dm-core", GEM_VERSION]]
14
+ GEM_CLEAN = ["log", "pkg", "coverage"]
15
+ GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO ] }
16
+
17
+ PROJECT_NAME = "datamapper"
18
+ PROJECT_URL = "http://github.com/sam/dm-more/tree/master/dm-validations"
19
+ PROJECT_DESCRIPTION = PROJECT_SUMMARY = "DataMapper plugin for performing validations on data models"
20
+
21
+ require ROOT.parent + 'tasks/hoe'
10
22
 
11
23
  desc "Generate Documentation"
12
24
  rd = Rake::RDocTask.new do |rdoc|
@@ -16,45 +28,25 @@ rd = Rake::RDocTask.new do |rdoc|
16
28
  rdoc.rdoc_files.include(FileList[ 'lib/**/*.rb', 'README', 'LICENSE'])
17
29
  end
18
30
 
19
- spec = Gem::Specification.new do |s|
20
- s.name = 'dm-validations'
21
- s.version = '0.9.2'
22
- s.platform = Gem::Platform::RUBY
23
- s.has_rdoc = true
24
- s.extra_rdoc_files = %w[ README LICENSE TODO ]
25
- s.summary = 'DataMapper plugin for performing validations on data models'
26
- s.description = s.summary
27
- s.author = 'Guy van den Berg'
28
- s.email = 'vandenberg.guy@gmail.com'
29
- s.homepage = 'http://github.com/sam/dm-more/tree/master/dm-validations'
30
- s.require_path = 'lib'
31
- s.files = FileList[ '{lib,spec}/**/*.rb', 'spec/spec.opts', 'Rakefile', *s.extra_rdoc_files ]
32
- s.add_dependency('dm-core', "=#{s.version}")
33
- end
34
-
35
31
  task :default => [ :spec ]
36
32
 
37
33
  WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
38
34
  SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
39
35
 
40
- Rake::GemPackageTask.new(spec) do |pkg|
41
- pkg.gem_spec = spec
42
- end
43
-
44
- desc "Install #{spec.name} #{spec.version} (default ruby)"
36
+ desc "Install #{GEM_NAME} #{GEM_VERSION} (default ruby)"
45
37
  task :install => [ :package ] do
46
- sh "#{SUDO} gem install --local pkg/#{spec.name}-#{spec.version} --no-update-sources", :verbose => false
38
+ sh "#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources", :verbose => false
47
39
  end
48
40
 
49
- desc "Uninstall #{spec.name} #{spec.version} (default ruby)"
41
+ desc "Uninstall #{GEM_NAME} #{GEM_VERSION} (default ruby)"
50
42
  task :uninstall => [ :clobber ] do
51
- sh "#{SUDO} gem uninstall #{spec.name} -v#{spec.version} -I -x", :verbose => false
43
+ sh "#{SUDO} gem uninstall #{GEM_NAME} -v#{GEM_VERSION} -I -x", :verbose => false
52
44
  end
53
45
 
54
46
  namespace :jruby do
55
- desc "Install #{spec.name} #{spec.version} with JRuby"
47
+ desc "Install #{GEM_NAME} #{GEM_VERSION} with JRuby"
56
48
  task :install => [ :package ] do
57
- sh %{#{SUDO} jruby -S gem install --local pkg/#{spec.name}-#{spec.version} --no-update-sources}, :verbose => false
49
+ sh %{#{SUDO} jruby -S gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources}, :verbose => false
58
50
  end
59
51
  end
60
52
 
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'pathname'
3
3
 
4
- gem 'dm-core', '=0.9.2'
4
+ gem 'dm-core', '=0.9.3'
5
5
  require 'dm-core'
6
6
 
7
7
  dir = Pathname(__FILE__).dirname.expand_path / 'dm-validations'
@@ -34,6 +34,23 @@ module DataMapper
34
34
  model.send(:alias_method, :save!, :save)
35
35
  model.send(:alias_method, :save, :save_with_validations)
36
36
  end
37
+ model.class_eval <<-EOS
38
+ class << self
39
+ method_defined?(:create) && !method_defined?(:create!)
40
+ def create(attributes = {}, context = :default)
41
+ resource = new(attributes)
42
+ return resource unless resource.valid?(context)
43
+ resource.save
44
+ resource
45
+ end
46
+
47
+ def create!(attributes = {})
48
+ resource = new(attributes)
49
+ resource.save!
50
+ resource
51
+ end
52
+ end
53
+ EOS
37
54
  end
38
55
 
39
56
  # Validate the resource before saving. Use #save! to save
@@ -97,9 +114,7 @@ module DataMapper
97
114
 
98
115
 
99
116
  def validation_property_value(name)
100
- return self.instance_variable_get("@#{name}") if self.instance_variables.include?(name)
101
- return self.send(name) if self.respond_to?(name)
102
- nil
117
+ self.respond_to?(name, true) ? self.send(name) : nil
103
118
  end
104
119
 
105
120
  # Get the corresponding Resource property, if it exists.
@@ -107,15 +122,15 @@ module DataMapper
107
122
  # Note: DataMapper validations can be used on non-DataMapper resources.
108
123
  # In such cases, the return value will be nil.
109
124
  def validation_property(field_name)
110
- if DataMapper::Resource > self.class
111
- self.class.properties(self.repository.name)[field_name]
125
+ if respond_to?(:model) && (properties = model.properties(self.repository.name)) && properties.has_property?(field_name)
126
+ properties[field_name]
112
127
  end
113
128
  end
114
129
 
115
130
  def validation_association_keys(name)
116
- if self.class.relationships.has_key?(name)
131
+ if model.relationships.has_key?(name)
117
132
  result = []
118
- relation = self.class.relationships[name]
133
+ relation = model.relationships[name]
119
134
  relation.child_key.each do |key|
120
135
  result << key.name
121
136
  end
@@ -167,7 +182,7 @@ module DataMapper
167
182
  def create_context_instance_methods(context)
168
183
  name = "valid_for_#{context.to_s}?"
169
184
  if !self.instance_methods.include?(name)
170
- class_eval <<-EOS
185
+ class_eval <<-EOS, __FILE__, __LINE__
171
186
  def #{name}
172
187
  valid?('#{context.to_s}'.to_sym)
173
188
  end
@@ -176,7 +191,7 @@ module DataMapper
176
191
 
177
192
  all = "all_valid_for_#{context.to_s}?"
178
193
  if !self.instance_methods.include?(all)
179
- class_eval <<-EOS
194
+ class_eval <<-EOS, __FILE__, __LINE__
180
195
  def #{all}
181
196
  all_valid?('#{context.to_s}'.to_sym)
182
197
  end
@@ -189,13 +204,18 @@ module DataMapper
189
204
  #
190
205
  def add_validator_to_context(opts, fields, klazz)
191
206
  fields.each do |field|
207
+ validator = klazz.new(field, opts)
192
208
  if opts[:context].is_a?(Symbol)
193
- validators.context(opts[:context]) << klazz.new(field, opts)
194
- create_context_instance_methods(opts[:context])
209
+ unless validators.context(opts[:context]).include?(validator)
210
+ validators.context(opts[:context]) << validator
211
+ create_context_instance_methods(opts[:context])
212
+ end
195
213
  elsif opts[:context].is_a?(Array)
196
214
  opts[:context].each do |c|
197
- validators.context(c) << klazz.new(field, opts)
198
- create_context_instance_methods(c)
215
+ unless validators.context(c).include?(validator)
216
+ validators.context(c) << validator
217
+ create_context_instance_methods(c)
218
+ end
199
219
  end
200
220
  end
201
221
  end
@@ -1,6 +1,29 @@
1
1
  module DataMapper
2
+ class Property
3
+ # for options_with_message
4
+ PROPERTY_OPTIONS << :message << :messages
5
+ end
6
+
2
7
  module Validate
3
8
  module AutoValidate
9
+ # adds message for validator
10
+ def options_with_message(base_options, property, validator_name)
11
+ options = base_options.clone
12
+ opts = property.options
13
+ options[:message] = if opts[:messages]
14
+ if opts[:messages].is_a?(Hash) and msg = opts[:messages][validator_name]
15
+ msg
16
+ else
17
+ nil
18
+ end
19
+ elsif opts[:message]
20
+ opts[:message]
21
+ else
22
+ nil
23
+ end
24
+ options
25
+ end
26
+
4
27
 
5
28
  ##
6
29
  # Auto-generate validations for a given property. This will only occur
@@ -33,6 +56,21 @@ module DataMapper
33
56
  # Using a Integer type causes a validates_is_number
34
57
  # validator to be created for the property. integer_only
35
58
  # is set to false, and precision/scale match the property
59
+ #
60
+ #
61
+ # Messages
62
+ #
63
+ # :messages => {..}
64
+ # Setting :messages hash replaces standard error messages
65
+ # with custom ones. For instance:
66
+ # :messages => {:presence => "Field is required",
67
+ # :format => "Field has invalid format"}
68
+ # Hash keys are: :presence, :format, :length, :is_unique,
69
+ # :is_number, :is_primitive
70
+ #
71
+ # :message => "Some message"
72
+ # It is just shortcut if only one validation option is set
73
+ #
36
74
  def auto_generate_validations(property)
37
75
  property.options[:auto_validation] = true unless property.options.has_key?(:auto_validation)
38
76
  return unless property.options[:auto_validation]
@@ -44,7 +82,8 @@ module DataMapper
44
82
 
45
83
  # presence
46
84
  unless opts[:allow_nil]
47
- validates_present property.name, opts
85
+ # validates_present property.name, opts
86
+ validates_present property.name, options_with_message(opts, property, :presence)
48
87
  end
49
88
 
50
89
  # length
@@ -56,39 +95,46 @@ module DataMapper
56
95
  else
57
96
  opts[:maximum] = len
58
97
  end
59
- validates_length property.name, opts
98
+ # validates_length property.name, opts
99
+ validates_length property.name, options_with_message(opts, property, :length)
60
100
  end
61
101
 
62
102
  # format
63
103
  if property.options.has_key?(:format)
64
104
  opts[:with] = property.options[:format]
65
- validates_format property.name, opts
105
+ # validates_format property.name, opts
106
+ validates_format property.name, options_with_message(opts, property, :format)
66
107
  end
67
108
 
68
109
  # uniqueness validator
69
110
  if property.options.has_key?(:unique)
70
111
  value = property.options[:unique]
71
112
  if value.is_a?(Array) || value.is_a?(Symbol)
72
- validates_is_unique property.name, :scope => Array(value)
113
+ # validates_is_unique property.name, :scope => Array(value)
114
+ validates_is_unique property.name, options_with_message({:scope => Array(value)}, property, :is_unique)
73
115
  elsif value.is_a?(TrueClass)
74
- validates_is_unique property.name
116
+ # validates_is_unique property.name
117
+ validates_is_unique property.name, options_with_message({}, property, :is_unique)
75
118
  end
76
119
  end
77
120
 
78
121
  # numeric validator
79
122
  if Integer == property.type
80
123
  opts[:integer_only] = true
81
- validates_is_number property.name, opts
124
+ # validates_is_number property.name, opts
125
+ validates_is_number property.name, options_with_message(opts, property, :is_number)
82
126
  elsif BigDecimal == property.type || Float == property.type
83
127
  opts[:precision] = property.precision
84
128
  opts[:scale] = property.scale
85
- validates_is_number property.name, opts
129
+ # validates_is_number property.name, opts
130
+ validates_is_number property.name, options_with_message(opts, property, :is_number)
86
131
  else
87
132
  # We only need this in the case we don't already
88
133
  # have a numeric validator, because otherwise
89
134
  # it will cause duplicate validation errors
90
135
  unless property.custom?
91
- validates_is_primitive property.name, opts
136
+ # validates_is_primitive property.name, opts
137
+ validates_is_primitive property.name, options_with_message(opts, property, :is_primitive)
92
138
  end
93
139
  end
94
140
  end
@@ -29,6 +29,10 @@ module DataMapper
29
29
  return true if @options[:allow_nil] && field_value.nil?
30
30
  return false if !@options[:allow_nil] && field_value.nil?
31
31
 
32
+ if target.class.properties.has_property?(@field_name)
33
+ return true unless target.attribute_dirty?(@field_name)
34
+ end
35
+
32
36
  confirm_value = target.instance_variable_get("@#{@confirm_field_name}")
33
37
  field_value == confirm_value
34
38
  end
@@ -55,7 +55,7 @@ module DataMapper
55
55
  end
56
56
  end
57
57
 
58
- error_message ||= @options[:message]
58
+ error_message = @options[:message] || error_message
59
59
 
60
60
  add_error(target, error_message, @field_name) unless valid
61
61
 
@@ -28,7 +28,16 @@ module DataMapper
28
28
  error_message ||= '%s must be an integer'.t(Extlib::Inflection.humanize(@field_name))
29
29
  else
30
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...
31
39
  if precision && scale
40
+ #handles both Float when it has scale specified and BigDecimal
32
41
  if precision > scale && scale > 0
33
42
  return true if value =~ /\A[+-]?(?:\d{1,#{precision - scale}}|\d{0,#{precision - scale}}\.\d{1,#{scale}})\z/
34
43
  elsif precision > scale && scale == 0
@@ -38,6 +47,14 @@ module DataMapper
38
47
  else
39
48
  raise ArgumentError, "Invalid precision #{precision.inspect} and scale #{scale.inspect} for #{field_name} (value: #{value.inspect} #{value.class})"
40
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/
41
58
  else
42
59
  return true if value =~ /\A[+-]?(?:\d+|\d*\.\d+)\z/
43
60
  end
@@ -24,7 +24,7 @@ module DataMapper
24
24
  opts = { field_name => target.validation_property_value(field_name) }
25
25
 
26
26
  scope.each do |item|
27
- if !target.model.properties(repository_name)[item].nil?
27
+ if target.model.properties(repository_name).has_property?(item)
28
28
  opts[item] = target.validation_property_value(item)
29
29
  elsif target.model.relationships(repository_name).has_key?(item)
30
30
  target.validation_association_keys(item).each do |key|
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ module Validations
3
+ VERSION = "0.9.3"
4
+ end
5
+ end
@@ -53,7 +53,7 @@ describe DataMapper::Validate::AcceptanceValidator do
53
53
  before(:all) do
54
54
  SkimBat.class_eval do
55
55
  validators.clear!
56
- validates_is_accepted :sailyness, :accept => "true"
56
+ validates_is_accepted :sailyness, :accept => true
57
57
  end
58
58
  @s = SkimBat.new
59
59
  end
@@ -259,4 +259,53 @@ describe "Automatic Validation from Property Definition" do
259
259
  end
260
260
  end
261
261
  end
262
+
263
+ describe 'for custom messages' do
264
+ it "should have correct error message" do
265
+ custom_boat = Class.new do
266
+ include DataMapper::Resource
267
+ property :id, Integer, :serial => true
268
+ property :name, String, :nullable => false, :message => "This boat must have name"
269
+ end
270
+ boat = custom_boat.new
271
+ boat.should_not be_valid
272
+
273
+ boat.errors.on(:name).should eql(["This boat must have name"])
274
+ end
275
+
276
+ it "should have correct error messages" do
277
+ custom_boat = Class.new do
278
+ include DataMapper::Resource
279
+ property :id, Integer, :serial => true
280
+ property :name, String, :nullable => false, :length => 5..20, :format => /^[a-z]+$/,
281
+ :messages => {
282
+ :presence => "This boat must have name",
283
+ :length => "Name must have at least 4 and at most 20 chars",
284
+ :format => "Please use only small letters"
285
+ }
286
+ end
287
+
288
+ boat = custom_boat.new
289
+ boat.should_not be_valid
290
+ boat.errors.on(:name).should include("This boat must have name")
291
+ boat.errors.on(:name).should include("Name must have at least 4 and at most 20 chars")
292
+ boat.errors.on(:name).should include("Please use only small letters")
293
+
294
+ boat.name = "%%"
295
+ boat.should_not be_valid
296
+ boat.errors.on(:name).should_not include("This boat must have name")
297
+ boat.errors.on(:name).should include("Name must have at least 4 and at most 20 chars")
298
+ boat.errors.on(:name).should include("Please use only small letters")
299
+
300
+ boat.name = "%%asd"
301
+ boat.should_not be_valid
302
+ boat.errors.on(:name).should_not include("This boat must have name")
303
+ boat.errors.on(:name).should_not include("Name must have at least 4 and at most 20 chars")
304
+ boat.errors.on(:name).should include("Please use only small letters")
305
+
306
+ boat.name = "superboat"
307
+ boat.should be_valid
308
+ boat.errors.on(:name).should be_nil
309
+ end
310
+ end
262
311
  end
@@ -9,20 +9,42 @@ describe DataMapper::Validate::ConfirmationValidator do
9
9
  property :id, Integer, :serial => true
10
10
  property :name, String
11
11
  property :name_confirmation, String
12
+ property :size, Integer
12
13
 
13
14
  validates_is_confirmed :name
14
15
  end
15
16
  end
16
17
 
18
+ it "should only validate if the attribute is dirty" do
19
+ class Transformer
20
+ include DataMapper::Resource
21
+
22
+ property :id, Integer, :serial => true
23
+ property :name, String
24
+ property :assoc, String
25
+
26
+ validates_is_confirmed :name
27
+
28
+ attr_accessor :name_confirmation
29
+ end
30
+ Transformer.auto_migrate!
31
+ # attribute_dirty?
32
+ tf = Transformer.new(:name => "Optimus Prime", :name_confirmation => "Optimus Prime", :assoc => "Autobot")
33
+ tf.should be_valid
34
+ tf.save.should == true
35
+ tf = Transformer.first
36
+ tf.update_attributes(:assoc => "Autobot!").should == true
37
+ end
38
+
17
39
  it "should validate the confirmation of a value on an instance of a resource" do
18
40
  canoe = Canoe.new
19
41
  canoe.name = 'White Water'
20
42
  canoe.name_confirmation = 'Not confirmed'
21
- canoe.valid?.should_not == true
43
+ canoe.should_not be_valid
22
44
  canoe.errors.full_messages.first.should == 'Name does not match the confirmation'
23
45
 
24
46
  canoe.name_confirmation = 'White Water'
25
- canoe.valid?.should == true
47
+ canoe.should be_valid
26
48
  end
27
49
 
28
50
  it "should default the name of the confirmation field to <field>_confirmation
@@ -30,11 +52,11 @@ describe DataMapper::Validate::ConfirmationValidator do
30
52
  canoe = Canoe.new
31
53
  canoe.name = 'White Water'
32
54
  canoe.name_confirmation = 'White Water'
33
- canoe.valid?.should == true
55
+ canoe.should be_valid
34
56
  end
35
57
 
36
58
  it "should default to allowing nil values on the fields if not specified to" do
37
- Canoe.new.valid?.should == true
59
+ Canoe.new.should be_valid
38
60
  end
39
61
 
40
62
  it "should not pass validation with a nil value when specified to" do
@@ -42,7 +64,7 @@ describe DataMapper::Validate::ConfirmationValidator do
42
64
  validators.clear!
43
65
  validates_is_confirmed :name, :allow_nil => false
44
66
  end
45
- Canoe.new.valid?.should_not == true
67
+ Canoe.new.should_not be_valid
46
68
  end
47
69
 
48
70
  it "should allow the name of the confirmation field to be set" do
@@ -60,7 +82,21 @@ describe DataMapper::Validate::ConfirmationValidator do
60
82
  canoe = Canoe.new
61
83
  canoe.name = 'Float'
62
84
  canoe.name_check = 'Float'
63
- canoe.valid?.should == true
85
+ canoe.should be_valid
86
+ end
87
+
88
+ it "should not require that the confirmation field be a property" do
89
+ class Raft
90
+ include DataMapper::Resource
91
+ attr_accessor :name, :name_confirmation
92
+
93
+ property :id, Integer, :serial => true
94
+
95
+ validates_is_confirmed :name
96
+ end
64
97
 
98
+ raft = Raft.new
99
+ raft.name = 'Lifeboat'
100
+ lambda { raft.should_not be_valid }.should_not raise_error
65
101
  end
66
102
  end
@@ -25,6 +25,8 @@ describe DataMapper::Validate::LengthValidator do
25
25
  validates_length :snickersnack, :within => 3..40, :message => "worble warble"
26
26
  end
27
27
  wock = Jabberwock.new
28
+ wock.valid?.should == false
29
+ wock.errors.full_messages.first.should == 'worble warble'
28
30
  wock.snickersnack = "hello"
29
31
  wock.id = 1
30
32
  wock.valid?.should == true
@@ -65,11 +65,55 @@ describe DataMapper::Validate::NumericValidator do
65
65
  describe 'Float' do
66
66
  describe 'with default precision and scale' do
67
67
  before :all do
68
- class RobotFish < Fish
68
+ class CloudFish < Fish
69
69
  property :average_weight, Float
70
70
  end
71
71
  end
72
72
 
73
+ before do
74
+ @cloud_fish = CloudFish.new
75
+ end
76
+
77
+ it 'should allow up to 10 digits before the decimal' do
78
+ @cloud_fish.average_weight = 0
79
+ @cloud_fish.should be_valid
80
+
81
+ @cloud_fish.average_weight = 9_999_999_999
82
+ @cloud_fish.should be_valid
83
+
84
+ @cloud_fish.average_weight = 10_000_000_000
85
+ @cloud_fish.should_not be_valid
86
+ end
87
+
88
+ it 'should allow 0 digits after the decimal' do
89
+ @cloud_fish.average_weight = 0
90
+ @cloud_fish.should be_valid
91
+ end
92
+
93
+ it 'should allow any digits after the decimal' do
94
+ @cloud_fish.average_weight = 1.2
95
+ @cloud_fish.should be_valid
96
+
97
+ @cloud_fish.average_weight = 123.456
98
+ @cloud_fish.should be_valid
99
+ end
100
+
101
+ it "should only allow up to 10 digits overall" do
102
+ @cloud_fish.average_weight = 1.234567890
103
+ @cloud_fish.should be_valid
104
+
105
+ @cloud_fish.average_weight = 1.2345678901
106
+ @cloud_fish.should_not be_valid
107
+ end
108
+ end
109
+
110
+ describe 'with default precision and scaleof 0' do
111
+ before :all do
112
+ class RobotFish < Fish
113
+ property :average_weight, Float, :scale => 0
114
+ end
115
+ end
116
+
73
117
  before do
74
118
  @robot_fish = RobotFish.new
75
119
  end
@@ -112,6 +156,10 @@ describe DataMapper::Validate::NumericValidator do
112
156
  before do
113
157
  @gold_fish = GoldFish.new
114
158
  end
159
+
160
+ it "should have scale of 2" do
161
+ @gold_fish.model.average_weight.scale.should == 2
162
+ end
115
163
 
116
164
  it 'should allow up to 2 digits before the decimal' do
117
165
  @gold_fish.average_weight = 0
@@ -88,6 +88,26 @@ describe DataMapper::Validate do
88
88
  end
89
89
  end
90
90
 
91
+ describe '#create!' do
92
+ before do
93
+ Yacht.auto_migrate!
94
+ end
95
+
96
+ it "should save object without running validations" do
97
+ Yacht.create!.should be_a_kind_of(Yacht)
98
+ end
99
+ end
100
+
101
+ describe "#create" do
102
+ before do
103
+ Yacht.auto_migrate!
104
+ end
105
+
106
+ it "should run validations" do
107
+ Yacht.create.new_record?.should be_true
108
+ end
109
+ end
110
+
91
111
  it "should respond to validatable? (for recursing assocations)" do
92
112
  Yacht.new.should be_validatable
93
113
  Class.new.new.should_not be_validatable
@@ -336,4 +356,37 @@ describe DataMapper::Validate do
336
356
 
337
357
  invoice.all_valid?.should == true
338
358
  end
359
+
360
+ it "should retrieve private instance variables for validation" do
361
+ class Raft
362
+ include DataMapper::Resource
363
+ property :length, Integer, :accessor => :private
364
+
365
+ def initialize(length)
366
+ @length = length
367
+ end
368
+ end
369
+
370
+ Raft.new(10).validation_property_value("length").should == 10
371
+ end
372
+
373
+ it "should duplicate validations to STI models" do
374
+ class Company
375
+ include DataMapper::Resource
376
+
377
+ validates_present :title, :message => "Company name is a required field"
378
+
379
+ property :id, Integer, :serial => true, :key => true
380
+ property :title, String
381
+ property :type, Discriminator
382
+ end
383
+
384
+ class ServiceCompany < Company
385
+ end
386
+
387
+ class ProductCompany < Company
388
+ end
389
+ company = ServiceCompany.new
390
+ company.should_not be_valid
391
+ end
339
392
  end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'spec'
2
3
  require 'pathname'
3
4
  require Pathname(__FILE__).dirname.expand_path.parent + 'lib/dm-validations'
4
5
 
@@ -8,7 +9,7 @@ def load_driver(name, default_uri)
8
9
  lib = "do_#{name}"
9
10
 
10
11
  begin
11
- gem lib, '=0.9.2'
12
+ gem lib, '=0.9.3'
12
13
  require lib
13
14
  DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
14
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.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guy van den Berg
@@ -9,29 +9,48 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-25 00:00:00 -05:00
12
+ date: 2008-07-24 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: dm-core
17
+ type: :runtime
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
20
21
  - - "="
21
22
  - !ruby/object:Gem::Version
22
- version: 0.9.2
23
+ version: 0.9.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.7.0
23
34
  version:
24
35
  description: DataMapper plugin for performing validations on data models
25
- email: vandenberg.guy@gmail.com
36
+ email:
37
+ - vandenberg.guy@gmail.com
26
38
  executables: []
27
39
 
28
40
  extensions: []
29
41
 
30
42
  extra_rdoc_files:
31
- - README
43
+ - README.txt
32
44
  - LICENSE
33
45
  - TODO
34
46
  files:
47
+ - History.txt
48
+ - LICENSE
49
+ - Manifest.txt
50
+ - README.txt
51
+ - Rakefile
52
+ - TODO
53
+ - lib/dm-validations.rb
35
54
  - lib/dm-validations/absent_field_validator.rb
36
55
  - lib/dm-validations/acceptance_validator.rb
37
56
  - lib/dm-validations/auto_validate.rb
@@ -49,8 +68,8 @@ files:
49
68
  - lib/dm-validations/support/object.rb
50
69
  - lib/dm-validations/uniqueness_validator.rb
51
70
  - lib/dm-validations/validation_errors.rb
71
+ - lib/dm-validations/version.rb
52
72
  - lib/dm-validations/within_validator.rb
53
- - lib/dm-validations.rb
54
73
  - spec/integration/absent_field_validator_spec.rb
55
74
  - spec/integration/acceptance_validator_spec.rb
56
75
  - spec/integration/auto_validate_spec.rb
@@ -68,17 +87,14 @@ files:
68
87
  - spec/integration/validation_errors_spec.rb
69
88
  - spec/integration/validation_spec.rb
70
89
  - spec/integration/within_validator_spec.rb
71
- - spec/spec_helper.rb
72
90
  - spec/spec.opts
73
- - Rakefile
74
- - README
75
- - LICENSE
76
- - TODO
91
+ - spec/spec_helper.rb
77
92
  has_rdoc: true
78
93
  homepage: http://github.com/sam/dm-more/tree/master/dm-validations
79
94
  post_install_message:
80
- rdoc_options: []
81
-
95
+ rdoc_options:
96
+ - --main
97
+ - README.txt
82
98
  require_paths:
83
99
  - lib
84
100
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -95,8 +111,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
111
  version:
96
112
  requirements: []
97
113
 
98
- rubyforge_project:
99
- rubygems_version: 1.0.1
114
+ rubyforge_project: datamapper
115
+ rubygems_version: 1.2.0
100
116
  signing_key:
101
117
  specification_version: 2
102
118
  summary: DataMapper plugin for performing validations on data models