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 +1 -0
- data/Manifest.txt +45 -0
- data/{README → README.txt} +0 -0
- data/Rakefile +22 -30
- data/lib/dm-validations.rb +34 -14
- data/lib/dm-validations/auto_validate.rb +54 -8
- data/lib/dm-validations/confirmation_validator.rb +4 -0
- data/lib/dm-validations/length_validator.rb +1 -1
- data/lib/dm-validations/numeric_validator.rb +17 -0
- data/lib/dm-validations/uniqueness_validator.rb +1 -1
- data/lib/dm-validations/version.rb +5 -0
- data/spec/integration/acceptance_validator_spec.rb +1 -1
- data/spec/integration/auto_validate_spec.rb +49 -0
- data/spec/integration/confirmation_validator_spec.rb +42 -6
- data/spec/integration/length_validator_spec.rb +2 -0
- data/spec/integration/numeric_validator_spec.rb +49 -1
- data/spec/integration/validation_spec.rb +53 -0
- data/spec/spec_helper.rb +2 -1
- metadata +31 -15
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
|
data/{README → README.txt}
RENAMED
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
|
-
|
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
|
-
|
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/#{
|
38
|
+
sh "#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources", :verbose => false
|
47
39
|
end
|
48
40
|
|
49
|
-
desc "Uninstall #{
|
41
|
+
desc "Uninstall #{GEM_NAME} #{GEM_VERSION} (default ruby)"
|
50
42
|
task :uninstall => [ :clobber ] do
|
51
|
-
sh "#{SUDO} gem uninstall #{
|
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 #{
|
47
|
+
desc "Install #{GEM_NAME} #{GEM_VERSION} with JRuby"
|
56
48
|
task :install => [ :package ] do
|
57
|
-
sh %{#{SUDO} jruby -S gem install --local pkg/#{
|
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
|
|
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.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
|
-
|
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
|
111
|
-
|
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
|
131
|
+
if model.relationships.has_key?(name)
|
117
132
|
result = []
|
118
|
-
relation =
|
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])
|
194
|
-
|
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)
|
198
|
-
|
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
|
@@ -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
|
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|
|
@@ -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 =>
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
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.
|
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.
|
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-
|
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.
|
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:
|
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
|
-
-
|
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
|
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
|