dm-validations 0.9.2 → 0.9.3
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/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
|