dm-validations 0.9.9 → 0.9.10

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.
Files changed (57) hide show
  1. data/History.txt +15 -0
  2. data/Manifest.txt +21 -2
  3. data/lib/dm-validations.rb +14 -14
  4. data/lib/dm-validations/absent_field_validator.rb +3 -4
  5. data/lib/dm-validations/acceptance_validator.rb +6 -10
  6. data/lib/dm-validations/confirmation_validator.rb +5 -5
  7. data/lib/dm-validations/contextual_validators.rb +1 -1
  8. data/lib/dm-validations/custom_validator.rb +1 -1
  9. data/lib/dm-validations/format_validator.rb +6 -5
  10. data/lib/dm-validations/generic_validator.rb +7 -10
  11. data/lib/dm-validations/length_validator.rb +7 -7
  12. data/lib/dm-validations/method_validator.rb +2 -2
  13. data/lib/dm-validations/numeric_validator.rb +4 -4
  14. data/lib/dm-validations/primitive_validator.rb +4 -4
  15. data/lib/dm-validations/required_field_validator.rb +5 -5
  16. data/lib/dm-validations/uniqueness_validator.rb +2 -2
  17. data/lib/dm-validations/validation_errors.rb +34 -2
  18. data/lib/dm-validations/version.rb +1 -1
  19. data/lib/dm-validations/within_validator.rb +15 -13
  20. data/spec/integration/absent_field_validator_spec.rb +4 -2
  21. data/spec/integration/acceptance_validator_spec.rb +3 -3
  22. data/spec/integration/auto_validate_spec.rb +16 -9
  23. data/spec/integration/block_validator_spec.rb +2 -8
  24. data/spec/integration/confirmation_validator_spec.rb +11 -8
  25. data/spec/integration/contextual_validators_spec.rb +2 -1
  26. data/spec/integration/format_validator_spec.rb +1 -1
  27. data/spec/integration/length_validator/error_message_spec.rb +23 -0
  28. data/spec/integration/length_validator/maximum_spec.rb +31 -0
  29. data/spec/integration/length_validator/minimum_spec.rb +31 -0
  30. data/spec/integration/length_validator/range_spec.rb +95 -0
  31. data/spec/integration/length_validator/spec_helper.rb +12 -0
  32. data/spec/integration/length_validator/valid_objects_spec.rb +13 -0
  33. data/spec/integration/method_validator_spec.rb +3 -3
  34. data/spec/integration/numeric_validator/float_type_spec.rb +102 -0
  35. data/spec/integration/numeric_validator/integer_only_true_spec.rb +92 -0
  36. data/spec/integration/numeric_validator/integer_type_spec.rb +100 -0
  37. data/spec/integration/numeric_validator/spec_helper.rb +77 -0
  38. data/spec/integration/numeric_validator_spec.rb +19 -6
  39. data/spec/integration/primitive_validator_spec.rb +2 -1
  40. data/spec/integration/required_field_validator/association_spec.rb +98 -0
  41. data/spec/integration/required_field_validator/boolean_type_value_spec.rb +149 -0
  42. data/spec/integration/required_field_validator/date_type_value_spec.rb +126 -0
  43. data/spec/integration/required_field_validator/datetime_type_value_spec.rb +126 -0
  44. data/spec/integration/required_field_validator/float_type_value_spec.rb +130 -0
  45. data/spec/integration/required_field_validator/integer_type_value_spec.rb +98 -0
  46. data/spec/integration/required_field_validator/plain_old_ruby_object_spec.rb +36 -0
  47. data/spec/integration/required_field_validator/shared_examples.rb +24 -0
  48. data/spec/integration/required_field_validator/spec_helper.rb +68 -0
  49. data/spec/integration/required_field_validator/string_type_value_spec.rb +164 -0
  50. data/spec/integration/required_field_validator/text_type_value_spec.rb +46 -0
  51. data/spec/integration/uniqueness_validator_spec.rb +10 -8
  52. data/spec/integration/validation_spec.rb +25 -25
  53. data/spec/integration/within_validator_spec.rb +36 -11
  54. data/tasks/spec.rb +1 -1
  55. metadata +24 -5
  56. data/spec/integration/length_validator_spec.rb +0 -115
  57. data/spec/integration/required_field_validator_spec.rb +0 -93
data/History.txt CHANGED
@@ -1,3 +1,18 @@
1
+ === 0.9.10 / 2009-01-19
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Major spec refactoring
6
+
7
+ * 2 minor enhancements:
8
+
9
+ * Moved all error messages into ValidationErrors.default_error_messages
10
+ * Added :allow_nil option to validates_within
11
+
12
+ * 1 bug fix:
13
+
14
+ * Fixed error messages and specs for within_validator
15
+
1
16
  === 0.9.9 / 2009-01-04
2
17
 
3
18
  * No changes this version
data/Manifest.txt CHANGED
@@ -35,11 +35,30 @@ spec/integration/contextual_validators_spec.rb
35
35
  spec/integration/custom_validator_spec.rb
36
36
  spec/integration/format_validator_spec.rb
37
37
  spec/integration/generic_validator_spec.rb
38
- spec/integration/length_validator_spec.rb
38
+ spec/integration/length_validator/error_message_spec.rb
39
+ spec/integration/length_validator/maximum_spec.rb
40
+ spec/integration/length_validator/minimum_spec.rb
41
+ spec/integration/length_validator/range_spec.rb
42
+ spec/integration/length_validator/spec_helper.rb
43
+ spec/integration/length_validator/valid_objects_spec.rb
39
44
  spec/integration/method_validator_spec.rb
45
+ spec/integration/numeric_validator/float_type_spec.rb
46
+ spec/integration/numeric_validator/integer_only_true_spec.rb
47
+ spec/integration/numeric_validator/integer_type_spec.rb
48
+ spec/integration/numeric_validator/spec_helper.rb
40
49
  spec/integration/numeric_validator_spec.rb
41
50
  spec/integration/primitive_validator_spec.rb
42
- spec/integration/required_field_validator_spec.rb
51
+ spec/integration/required_field_validator/association_spec.rb
52
+ spec/integration/required_field_validator/boolean_type_value_spec.rb
53
+ spec/integration/required_field_validator/date_type_value_spec.rb
54
+ spec/integration/required_field_validator/datetime_type_value_spec.rb
55
+ spec/integration/required_field_validator/float_type_value_spec.rb
56
+ spec/integration/required_field_validator/integer_type_value_spec.rb
57
+ spec/integration/required_field_validator/plain_old_ruby_object_spec.rb
58
+ spec/integration/required_field_validator/shared_examples.rb
59
+ spec/integration/required_field_validator/spec_helper.rb
60
+ spec/integration/required_field_validator/string_type_value_spec.rb
61
+ spec/integration/required_field_validator/text_type_value_spec.rb
43
62
  spec/integration/uniqueness_validator_spec.rb
44
63
  spec/integration/validation_errors_spec.rb
45
64
  spec/integration/validation_spec.rb
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'pathname'
3
3
 
4
- gem 'dm-core', '~>0.9.9'
4
+ gem 'dm-core', '~>0.9.10'
5
5
  require 'dm-core'
6
6
 
7
7
  dir = Pathname(__FILE__).dirname.expand_path / 'dm-validations'
@@ -76,7 +76,7 @@ module DataMapper
76
76
  # resource we can check if they respond to validatable? before trying to
77
77
  # recursivly validate them
78
78
  #
79
- def validatable?()
79
+ def validatable?
80
80
  true
81
81
  end
82
82
 
@@ -89,13 +89,13 @@ module DataMapper
89
89
  # Check if a resource is valid in a given context
90
90
  #
91
91
  def valid?(context = :default)
92
- self.class.validators.execute(context,self)
92
+ self.class.validators.execute(context, self)
93
93
  end
94
94
 
95
95
  # Begin a recursive walk of the model checking validity
96
96
  #
97
97
  def all_valid?(context = :default)
98
- recursive_valid?(self,context,true)
98
+ recursive_valid?(self, context, true)
99
99
  end
100
100
 
101
101
  # Do recursive validity checking
@@ -105,11 +105,11 @@ module DataMapper
105
105
  target.instance_variables.each do |ivar|
106
106
  ivar_value = target.instance_variable_get(ivar)
107
107
  if ivar_value.validatable?
108
- valid = valid && recursive_valid?(ivar_value,context,valid)
108
+ valid = valid && recursive_valid?(ivar_value, context, valid)
109
109
  elsif ivar_value.respond_to?(:each)
110
110
  ivar_value.each do |item|
111
111
  if item.validatable?
112
- valid = valid && recursive_valid?(item,context,valid)
112
+ valid = valid && recursive_valid?(item, context, valid)
113
113
  end
114
114
  end
115
115
  end
@@ -186,21 +186,21 @@ module DataMapper
186
186
  # if it does not already exist
187
187
  #
188
188
  def create_context_instance_methods(context)
189
- name = "valid_for_#{context.to_s}?"
189
+ name = "valid_for_#{context.to_s}?" # valid_for_signup?
190
190
  if !self.instance_methods.include?(name)
191
191
  class_eval <<-EOS, __FILE__, __LINE__
192
- def #{name}
193
- valid?('#{context.to_s}'.to_sym)
194
- end
192
+ def #{name} # def valid_for_signup?
193
+ valid?('#{context.to_s}'.to_sym) # valid?('signup'.to_sym)
194
+ end # end
195
195
  EOS
196
196
  end
197
197
 
198
- all = "all_valid_for_#{context.to_s}?"
198
+ all = "all_valid_for_#{context.to_s}?" # all_valid_for_signup?
199
199
  if !self.instance_methods.include?(all)
200
200
  class_eval <<-EOS, __FILE__, __LINE__
201
- def #{all}
202
- all_valid?('#{context.to_s}'.to_sym)
203
- end
201
+ def #{all} # def all_valid_for_signup?
202
+ all_valid?('#{context.to_s}'.to_sym) # all_valid?('signup'.to_sym)
203
+ end # end
204
204
  EOS
205
205
  end
206
206
  end
@@ -13,11 +13,10 @@ module DataMapper
13
13
  end
14
14
 
15
15
  def call(target)
16
- field_value = target.send(field_name).blank?
17
- return true if field_value
16
+ return true if target.send(field_name).blank?
18
17
 
19
- error_message = @options[:message] || "%s must be absent".t(Extlib::Inflection.humanize(@field_name))
20
- add_error(target, error_message , @field_name)
18
+ error_message = @options[:message] || ValidationErrors.default_error_message(:absent, field_name)
19
+ add_error(target, error_message, field_name)
21
20
 
22
21
  return false
23
22
  end
@@ -7,23 +7,19 @@ module DataMapper
7
7
  # @since 0.9
8
8
  class AcceptanceValidator < GenericValidator
9
9
 
10
- def self.default_message_for_field(field_name)
11
- '%s is not accepted'.t(Extlib::Inflection.humanize(field_name))
12
- end
13
-
14
10
  def initialize(field_name, options = {})
15
11
  super
16
12
  @options = options
17
13
  @field_name = field_name
18
14
  @options[:allow_nil] = true unless @options.include?(:allow_nil)
19
- @options[:accept] ||= ["1",1,"true",true,"t"]
15
+ @options[:accept] ||= ["1", 1, "true", true, "t"]
20
16
  @options[:accept] = Array(@options[:accept])
21
17
  end
22
18
 
23
19
  def call(target)
24
20
  unless valid?(target)
25
- error_message = @options[:message] || DataMapper::Validate::AcceptanceValidator.default_message_for_field(@field_name)
26
- add_error(target, error_message , @field_name)
21
+ error_message = @options[:message] || ValidationErrors.default_error_message(:accepted, field_name)
22
+ add_error(target, error_message, field_name)
27
23
  return false
28
24
  end
29
25
 
@@ -31,7 +27,7 @@ module DataMapper
31
27
  end
32
28
 
33
29
  def valid?(target)
34
- field_value = target.instance_variable_get("@#{@field_name}")
30
+ field_value = target.send(field_name)
35
31
  return true if @options[:allow_nil] && field_value.nil?
36
32
  return false if !@options[:allow_nil] && field_value.nil?
37
33
 
@@ -48,7 +44,7 @@ module DataMapper
48
44
  # @option :allow_nil<Boolean> true if nil is allowed, false if nil is not
49
45
  # allowed. Default is true.
50
46
  # @option :accept<Array> a list of accepted values.
51
- # Default are ["1",1,"true",true,"t"]).
47
+ # Default are ["1", 1, "true", true, "t"]).
52
48
  #
53
49
  # @example [Usage]
54
50
  # require 'dm-validations'
@@ -64,7 +60,7 @@ module DataMapper
64
60
  # # a call to valid? will return false unless:
65
61
  # # license_agreement is nil or "1"
66
62
  # # and
67
- # # terms_accepted is one of ["1",1,"true",true,"t"]
63
+ # # terms_accepted is one of ["1", 1, "true", true, "t"]
68
64
  #
69
65
  def validates_is_accepted(*fields)
70
66
  opts = opts_from_validator_args(fields)
@@ -16,8 +16,8 @@ module DataMapper
16
16
 
17
17
  def call(target)
18
18
  unless valid?(target)
19
- error_message = @options[:message] || '%s does not match the confirmation'.t(Extlib::Inflection.humanize(@field_name))
20
- add_error(target, error_message , @field_name)
19
+ error_message = @options[:message] || ValidationErrors.default_error_message(:confirmation, field_name)
20
+ add_error(target, error_message, field_name)
21
21
  return false
22
22
  end
23
23
 
@@ -25,12 +25,12 @@ module DataMapper
25
25
  end
26
26
 
27
27
  def valid?(target)
28
- field_value = target.instance_variable_get("@#{@field_name}")
28
+ field_value = target.send(field_name)
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)
32
+ if target.class.properties.has_property?(field_name)
33
+ return true unless target.attribute_dirty?(field_name)
34
34
  end
35
35
 
36
36
  confirm_value = target.instance_variable_get("@#{@confirm_field_name}")
@@ -8,7 +8,7 @@ module DataMapper
8
8
  class ContextualValidators
9
9
 
10
10
  def dump
11
- contexts.each_pair do |key,context|
11
+ contexts.each_pair do |key, context|
12
12
  puts "Key=#{key} Context: #{context}"
13
13
  end
14
14
  end
@@ -50,7 +50,7 @@ module DataMapper
50
50
  # error_message = @options[:message] || error_message || '%s is invalid'.t(field)
51
51
  # error_message = error_message.call(field, value) if Proc === error_message
52
52
  #
53
- # add_error(target, error_message , @field_name)
53
+ # add_error(target, error_message, @field_name)
54
54
  #end
55
55
 
56
56
  #return valid
@@ -24,7 +24,7 @@ module DataMapper
24
24
  end
25
25
 
26
26
  def call(target)
27
- value = target.validation_property_value(@field_name)
27
+ value = target.validation_property_value(field_name)
28
28
  return true if @options[:allow_nil] && value.nil?
29
29
 
30
30
  validation = @options[:as] || @options[:with]
@@ -36,16 +36,17 @@ module DataMapper
36
36
  when Proc then validator.call(value)
37
37
  when Regexp then value =~ validator
38
38
  else
39
- raise UnknownValidationFormat, "Can't determine how to validate #{target.class}##{@field_name} with #{validator.inspect}"
39
+ raise UnknownValidationFormat, "Can't determine how to validate #{target.class}##{field_name} with #{validator.inspect}"
40
40
  end
41
41
 
42
42
  return true if valid
43
43
 
44
- field = Extlib::Inflection.humanize(@field_name)
45
- error_message = @options[:message] || '%s has an invalid format'.t(field)
44
+ error_message = @options[:message] || ValidationErrors.default_error_message(:invalid, field_name)
45
+
46
+ field = Extlib::Inflection.humanize(field_name)
46
47
  error_message = error_message.call(field, value) if error_message.respond_to?(:call)
47
48
 
48
- add_error(target, error_message, @field_name)
49
+ add_error(target, error_message, field_name)
49
50
 
50
51
  false
51
52
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  module DataMapper
2
3
  module Validate
3
4
 
@@ -13,8 +14,8 @@ module DataMapper
13
14
  # @since 0.9
14
15
  class GenericValidator
15
16
 
16
- attr_accessor :if_clause
17
- attr_accessor :unless_clause
17
+ attr_accessor :if_clause, :unless_clause
18
+ attr_reader :field_name
18
19
 
19
20
  # Construct a validator. Capture the :if and :unless clauses when present.
20
21
  #
@@ -28,8 +29,8 @@ module DataMapper
28
29
  # that is sub-classing this GenericValidator
29
30
  #
30
31
  def initialize(field, opts = {})
31
- @if_clause = opts.has_key?(:if) ? opts[:if] : nil
32
- @unless_clause = opts.has_key?(:unless) ? opts[:unless] : nil
32
+ @if_clause = opts.delete(:if)
33
+ @unless_clause = opts.delete(:unless)
33
34
  end
34
35
 
35
36
  # Add an error message to a target resource. If the error corresponds to a
@@ -43,7 +44,7 @@ module DataMapper
43
44
  # TODO - should the field_name for a general message be :default???
44
45
  #
45
46
  def add_error(target, message, field_name = :general)
46
- target.errors.add(field_name,message)
47
+ target.errors.add(field_name, message)
47
48
  end
48
49
 
49
50
  # Call the validator. "call" is used so the operation is BoundMethod and
@@ -53,11 +54,7 @@ module DataMapper
53
54
  # against
54
55
  # @return <Boolean> true if valid, otherwise false
55
56
  def call(target)
56
- raise "DataMapper::Validate::GenericValidator::call must be overriden in #{self.class.to_s}"
57
- end
58
-
59
- def field_name
60
- @field_name
57
+ raise NotImplementedError, "DataMapper::Validate::GenericValidator::call must be overriden in a subclass"
61
58
  end
62
59
 
63
60
  # Determines if this validator should be run against the
@@ -24,14 +24,14 @@ module DataMapper
24
24
  end
25
25
 
26
26
  def call(target)
27
- field_value = target.validation_property_value(@field_name)
27
+ field_value = target.validation_property_value(field_name)
28
28
  return true if @options[:allow_nil] && field_value.nil?
29
29
 
30
30
  field_value = '' if field_value.nil?
31
31
 
32
32
  # XXX: HACK seems hacky to do this on every validation, probably should
33
33
  # do this elsewhere?
34
- field = Extlib::Inflection.humanize(@field_name)
34
+ field = Extlib::Inflection.humanize(field_name)
35
35
  min = @range ? @range.min : @min
36
36
  max = @range ? @range.max : @max
37
37
  equal = @equal
@@ -39,25 +39,25 @@ module DataMapper
39
39
  case @validation_method
40
40
  when :range then
41
41
  unless valid = @range.include?(field_value.size)
42
- error_message = '%s must be between %s and %s characters long'.t(field, min, max)
42
+ error_message = ValidationErrors.default_error_message(:length_between, field, min, max)
43
43
  end
44
44
  when :min then
45
45
  unless valid = field_value.size >= min
46
- error_message = '%s must be more than %s characters long'.t(field, min)
46
+ error_message = ValidationErrors.default_error_message(:too_short, field, min)
47
47
  end
48
48
  when :max then
49
49
  unless valid = field_value.size <= max
50
- error_message = '%s must be less than %s characters long'.t(field, max)
50
+ error_message = ValidationErrors.default_error_message(:too_long, field, max)
51
51
  end
52
52
  when :equals then
53
53
  unless valid = field_value.size == equal
54
- error_message = '%s must be %s characters long'.t(field, equal)
54
+ error_message = ValidationErrors.default_error_message(:wrong_length, field, equal)
55
55
  end
56
56
  end
57
57
 
58
58
  error_message = @options[:message] || error_message
59
59
 
60
- add_error(target, error_message, @field_name) unless valid
60
+ add_error(target, error_message, field_name) unless valid
61
61
 
62
62
  return valid
63
63
  end
@@ -14,8 +14,8 @@ module DataMapper
14
14
  end
15
15
 
16
16
  def call(target)
17
- result,message = target.send(@options[:method])
18
- add_error(target,message,@field_name) if !result
17
+ result, message = target.send(@options[:method])
18
+ add_error(target, message, field_name) unless result
19
19
  result
20
20
  end
21
21
 
@@ -25,7 +25,7 @@ module DataMapper
25
25
 
26
26
  if @options[:integer_only]
27
27
  return true if value =~ /\A[+-]?\d+\z/
28
- error_message ||= '%s must be an integer'.t(Extlib::Inflection.humanize(@field_name))
28
+ error_message ||= ValidationErrors.default_error_message(:not_an_integer, field_name)
29
29
  else
30
30
  # FIXME: if precision and scale are not specified, can we assume that it is an integer?
31
31
  # probably not, as floating point numbers don't have hard
@@ -51,17 +51,17 @@ module DataMapper
51
51
  # for floats, if scale is not set
52
52
 
53
53
  #total number of digits is less or equal precision
54
- return true if value.gsub(/[^\d]/,'').length <= precision
54
+ return true if value.gsub(/[^\d]/, '').length <= precision
55
55
 
56
56
  #number of digits before decimal == precision, and the number is x.0. same as scale = 0
57
57
  return true if value =~ /\A[+-]?(?:\d{1,#{precision}}(?:\.0)?)\z/
58
58
  else
59
59
  return true if value =~ /\A[+-]?(?:\d+|\d*\.\d+)\z/
60
60
  end
61
- error_message ||= '%s must be a number'.t(Extlib::Inflection.humanize(@field_name))
61
+ error_message ||= ValidationErrors.default_error_message(:not_a_number, field_name)
62
62
  end
63
63
 
64
- add_error(target, error_message, @field_name)
64
+ add_error(target, error_message, field_name)
65
65
 
66
66
  # TODO: check the gt, gte, lt, lte, and eq options
67
67
 
@@ -13,12 +13,12 @@ module DataMapper
13
13
  end
14
14
 
15
15
  def call(target)
16
- value = target.validation_property_value(@field_name)
17
- property = target.validation_property(@field_name)
16
+ value = target.validation_property_value(field_name)
17
+ property = target.validation_property(field_name)
18
18
  return true if value.nil? || value.kind_of?(property.primitive) || property.primitive == TrueClass && value.kind_of?(FalseClass)
19
19
 
20
20
  error_message = @options[:message] || default_error(property)
21
- add_error(target, error_message, @field_name)
21
+ add_error(target, error_message, field_name)
22
22
 
23
23
  false
24
24
  end
@@ -26,7 +26,7 @@ module DataMapper
26
26
  protected
27
27
 
28
28
  def default_error(property)
29
- "%s must be of type %s".t(Extlib::Inflection.humanize(@field_name), property.primitive)
29
+ ValidationErrors.default_error_message(:primitive, field_name, property.primitive)
30
30
  end
31
31
 
32
32
  end # class PrimitiveValidator
@@ -13,12 +13,12 @@ module DataMapper
13
13
  end
14
14
 
15
15
  def call(target)
16
- value = target.validation_property_value(@field_name)
17
- property = target.validation_property(@field_name)
16
+ value = target.validation_property_value(field_name)
17
+ property = target.validation_property(field_name)
18
18
  return true if present?(value, property)
19
19
 
20
20
  error_message = @options[:message] || default_error(property)
21
- add_error(target, error_message, @field_name)
21
+ add_error(target, error_message, field_name)
22
22
 
23
23
  false
24
24
  end
@@ -33,8 +33,8 @@ module DataMapper
33
33
  end
34
34
 
35
35
  def default_error(property)
36
- actual = boolean_type?(property) ? "nil".t : "blank".t
37
- "%s must not be %s".t(Extlib::Inflection.humanize(@field_name), actual)
36
+ actual = boolean_type?(property) ? :nil : :blank
37
+ ValidationErrors.default_error_message(actual, field_name)
38
38
  end
39
39
 
40
40
  # Is +property+ a boolean property?