dm-validations 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
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?