mattmatt-validatable 1.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/README.rdoc +116 -0
  2. data/Rakefile +33 -0
  3. data/VERSION.yml +5 -0
  4. data/lib/validatable.rb +28 -0
  5. data/lib/validatable/child_validation.rb +15 -0
  6. data/lib/validatable/errors.rb +93 -0
  7. data/lib/validatable/included_validation.rb +9 -0
  8. data/lib/validatable/macros.rb +314 -0
  9. data/lib/validatable/object_extension.rb +21 -0
  10. data/lib/validatable/requireable.rb +26 -0
  11. data/lib/validatable/understandable.rb +31 -0
  12. data/lib/validatable/validatable_class_methods.rb +87 -0
  13. data/lib/validatable/validatable_instance_methods.rb +106 -0
  14. data/lib/validatable/validations/validates_acceptance_of.rb +14 -0
  15. data/lib/validatable/validations/validates_associated.rb +13 -0
  16. data/lib/validatable/validations/validates_confirmation_of.rb +23 -0
  17. data/lib/validatable/validations/validates_each.rb +14 -0
  18. data/lib/validatable/validations/validates_exclusion_of.rb +17 -0
  19. data/lib/validatable/validations/validates_format_of.rb +16 -0
  20. data/lib/validatable/validations/validates_inclusion_of.rb +17 -0
  21. data/lib/validatable/validations/validates_length_of.rb +30 -0
  22. data/lib/validatable/validations/validates_numericality_of.rb +27 -0
  23. data/lib/validatable/validations/validates_presence_of.rb +17 -0
  24. data/lib/validatable/validations/validates_true_for.rb +13 -0
  25. data/lib/validatable/validations/validation_base.rb +91 -0
  26. data/test/functional/test_validatable.rb +519 -0
  27. data/test/functional/test_validates_acceptance_of.rb +16 -0
  28. data/test/functional/test_validates_associated.rb +41 -0
  29. data/test/functional/test_validates_confirmation_of.rb +56 -0
  30. data/test/functional/test_validates_each.rb +14 -0
  31. data/test/functional/test_validates_exclusion_of.rb +29 -0
  32. data/test/functional/test_validates_format_of.rb +34 -0
  33. data/test/functional/test_validates_inclusion_of.rb +29 -0
  34. data/test/functional/test_validates_length_of.rb +64 -0
  35. data/test/functional/test_validates_numericality_of.rb +57 -0
  36. data/test/functional/test_validates_presence_of.rb +16 -0
  37. data/test/functional/test_validates_true_for.rb +27 -0
  38. data/test/test_helper.rb +33 -0
  39. data/test/unit/test_errors.rb +82 -0
  40. data/test/unit/test_understandable.rb +19 -0
  41. data/test/unit/test_validatable.rb +38 -0
  42. data/test/unit/test_validates_acceptance_of.rb +45 -0
  43. data/test/unit/test_validates_associated.rb +29 -0
  44. data/test/unit/test_validates_confirmation_of.rb +76 -0
  45. data/test/unit/test_validates_exclusion_of.rb +23 -0
  46. data/test/unit/test_validates_format_of.rb +44 -0
  47. data/test/unit/test_validates_inclusion_of.rb +23 -0
  48. data/test/unit/test_validates_length_of.rb +80 -0
  49. data/test/unit/test_validates_numericality_of.rb +76 -0
  50. data/test/unit/test_validates_presence_of.rb +35 -0
  51. data/test/unit/test_validates_true_for.rb +29 -0
  52. data/test/unit/test_validation_base.rb +52 -0
  53. metadata +133 -0
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesAcceptanceOfTest < Test::Unit::TestCase
5
+ test "given no acceptance, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :name
9
+ validates_acceptance_of :name
10
+ end
11
+ instance = klass.new
12
+ instance.valid?
13
+ assert_equal "must be accepted", instance.errors.on(:name)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesAssociatedTest < Test::Unit::TestCase
5
+ def setup
6
+ @parent = Class.new do
7
+ include Validatable
8
+ attr_accessor :children
9
+ validates_associated :children
10
+ end
11
+ @child = Class.new do
12
+ include Validatable
13
+ attr_accessor :name
14
+ validates_presence_of :name
15
+ end
16
+ end
17
+
18
+ test "given invalid child, when validated, then error is in the parent's error collection" do
19
+ instance = @parent.new
20
+ instance.children = [@child.new]
21
+ instance.valid?
22
+ assert_equal "is invalid", instance.errors.on(:children)
23
+ end
24
+
25
+ test "given two invalid children, when validated, then both children have errors" do
26
+ instance = @parent.new
27
+ instance.children = [@child.new, @child.new]
28
+ instance.valid?
29
+ instance.children.each do |child|
30
+ assert_not_nil child.errors.on(:name)
31
+ end
32
+ end
33
+
34
+ test "given valid child, when validated, the parent is valid" do
35
+ instance = @parent.new
36
+ instance.children = [@child.new]
37
+ instance.children.first.name = 'x'
38
+ assert instance.valid?
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesConfirmationOfTest < Test::Unit::TestCase
5
+ test "given non matching attributes, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :name
9
+ validates_confirmation_of :name
10
+ end
11
+ instance = klass.new
12
+ instance.name = "foo"
13
+ instance.name_confirmation = "bar"
14
+ instance.valid?
15
+ assert_equal "doesn't match confirmation", instance.errors.on(:name)
16
+ end
17
+
18
+ test "given matching attributes, when validated, then no error is in the objects error collection" do
19
+ klass = Class.new do
20
+ include Validatable
21
+ attr_accessor :name
22
+ validates_confirmation_of :name
23
+ end
24
+ instance = klass.new
25
+ instance.name = "foo"
26
+ instance.name_confirmation = "foo"
27
+ assert_equal true, instance.valid?
28
+ end
29
+
30
+ test "given matching attributes of different case, when validated with case sensitive false, then no error is in the objects error collection" do
31
+ klass = Class.new do
32
+ include Validatable
33
+ attr_accessor :name
34
+ validates_confirmation_of :name, :case_sensitive => false
35
+ end
36
+ instance = klass.new
37
+ instance.name = "foo"
38
+ instance.name_confirmation = "FOO"
39
+ assert_equal true, instance.valid?
40
+ end
41
+
42
+ test "given matching attributes of different case, when validated with case sensitive true, then error is in the objects error collection" do
43
+ klass = Class.new do
44
+ include Validatable
45
+ attr_accessor :name
46
+ validates_confirmation_of :name
47
+ end
48
+ instance = klass.new
49
+ instance.name = "foo"
50
+ instance.name_confirmation = "FOO"
51
+ assert_equal false, instance.valid?
52
+ assert_equal "doesn't match confirmation", instance.errors.on(:name)
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ functional_tests do
4
+ expect :is_set do
5
+ klass = Class.new do
6
+ include Validatable
7
+ attr_accessor :name, :result
8
+ validates_each :name, :logic => lambda { @result = :is_set }
9
+ end
10
+ instance = klass.new
11
+ instance.valid?
12
+ instance.result
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesExclusionOfTest < Test::Unit::TestCase
5
+ test "given excluded state, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :state
9
+ validates_exclusion_of :state, :within => %w(in out)
10
+ end
11
+ instance = klass.new
12
+ instance.state = 'in'
13
+ instance.valid?
14
+ assert_equal "is reserved", instance.errors.on(:state)
15
+ end
16
+
17
+ test "given non-excluded state, when validated, then no error is in the objects error collection" do
18
+ klass = Class.new do
19
+ include Validatable
20
+ attr_accessor :state
21
+ validates_exclusion_of :state, :within => %w(in out)
22
+ end
23
+ instance = klass.new
24
+ instance.state = 'foo'
25
+ instance.valid?
26
+ assert_nil instance.errors.on(:state)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesFormatOfTest < Test::Unit::TestCase
5
+ test "given invalid name format, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :name
9
+ validates_format_of :name, :with => /.+/
10
+ end
11
+ instance = klass.new
12
+ instance.valid?
13
+ assert_equal "is invalid", instance.errors.on(:name)
14
+ end
15
+
16
+ test "given invalid name format and nil name, when validated, then error is in the objects error collection" do
17
+ klass = Class.new do
18
+ include Validatable
19
+ attr_accessor :name
20
+ validates_format_of :name, :with => /.+/, :if => Proc.new { !name.nil? }
21
+ end
22
+ assert_equal true, klass.new.valid?
23
+ end
24
+
25
+ test "given invalid name format and a name, when validated, then error is in the objects error collection" do
26
+ klass = Class.new do
27
+ include Validatable
28
+ attr_accessor :name
29
+ validates_format_of :name, :with => /.+/, :if => Proc.new { name.nil? }
30
+ end
31
+ assert_equal false, klass.new.valid?
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesInclusionOfTest < Test::Unit::TestCase
5
+ test "given state not in list, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :state
9
+ validates_inclusion_of :state, :within => %w(in out)
10
+ end
11
+ instance = klass.new
12
+ instance.state = 'foo'
13
+ instance.valid?
14
+ assert_equal "is not in the list", instance.errors.on(:state)
15
+ end
16
+
17
+ test "given state in list, when validated, then no error is in the objects error collection" do
18
+ klass = Class.new do
19
+ include Validatable
20
+ attr_accessor :state
21
+ validates_inclusion_of :state, :within => %w(in out)
22
+ end
23
+ instance = klass.new
24
+ instance.state = 'in'
25
+ instance.valid?
26
+ assert_nil instance.errors.on(:state)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesLengthOfTest < Test::Unit::TestCase
5
+ test "given short value, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :name
9
+ validates_length_of :name, :minimum => 2
10
+ end
11
+ instance = klass.new
12
+ instance.valid?
13
+ assert_equal "is invalid", instance.errors.on(:name)
14
+ end
15
+
16
+ test "given is constraint, when validated, then error is in the objects error collection" do
17
+ klass = Class.new do
18
+ include Validatable
19
+ attr_accessor :name
20
+ validates_length_of :name, :is => 2
21
+ end
22
+
23
+ instance = klass.new
24
+ instance.valid?
25
+ assert_equal "is invalid", instance.errors.on(:name)
26
+ end
27
+
28
+ test "given is constraint is met, when validated, then valid is true" do
29
+ klass = Class.new do
30
+ include Validatable
31
+ attr_accessor :name
32
+ validates_length_of :name, :is => 2
33
+ end
34
+
35
+ instance = klass.new
36
+ instance.name = "bk"
37
+ assert_equal true, instance.valid?
38
+ end
39
+
40
+ test "given within constraint, when validated, then error is in the objects error collection" do
41
+ klass = Class.new do
42
+ include Validatable
43
+ attr_accessor :name
44
+ validates_length_of :name, :within => 2..4
45
+ end
46
+
47
+ instance = klass.new
48
+ instance.valid?
49
+ assert_equal "is invalid", instance.errors.on(:name)
50
+ end
51
+
52
+ test "given within constraint, when validated, then valid is true" do
53
+ klass = Class.new do
54
+ include Validatable
55
+ attr_accessor :name
56
+ validates_length_of :name, :within => 2..4
57
+ end
58
+
59
+ instance = klass.new
60
+ instance.name = "bk"
61
+ assert_equal true, instance.valid?
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesNumericalityOfTest < Test::Unit::TestCase
5
+ test "when validating numericality and the value is nil an error should exist on the instance" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :nothing
9
+ validates_numericality_of :nothing
10
+ end
11
+ instance = klass.new
12
+ instance.valid?
13
+ assert_equal "must be a number", instance.errors.on(:nothing)
14
+ end
15
+
16
+ test "when validating numericality and the value has a non numeric character an error should exist on the instance" do
17
+ klass = Class.new do
18
+ include Validatable
19
+ validates_numericality_of :some_string
20
+
21
+ def some_string
22
+ "some_string"
23
+ end
24
+ end
25
+ instance = klass.new
26
+ instance.valid?
27
+ assert_equal "must be a number", instance.errors.on(:some_string)
28
+ end
29
+
30
+ test "when validating a number no error will be in the instance" do
31
+ klass = Class.new do
32
+ include Validatable
33
+ validates_numericality_of :valid_number
34
+
35
+ def valid_number
36
+ 1.23
37
+ end
38
+ end
39
+ instance = klass.new
40
+ instance.valid?
41
+ assert_equal nil, instance.errors.on(:valid_number)
42
+ end
43
+
44
+ test "when validating an integer and the value is a decimal an error should exist on the instance" do
45
+ klass = Class.new do
46
+ include Validatable
47
+ validates_numericality_of :valid_number, :only_integer => true
48
+ attr_accessor :valid_number
49
+ end
50
+
51
+ instance = klass.new
52
+ instance.valid_number = 1.23
53
+ instance.valid?
54
+ assert_equal "must be a number", instance.errors.on(:valid_number)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesPresenceOfTest < Test::Unit::TestCase
5
+ test "given no name, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :name
9
+ validates_presence_of :name
10
+ end
11
+ instance = klass.new
12
+ instance.valid?
13
+ assert_equal "can't be empty", instance.errors.on(:name)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesFormatOfTest < Test::Unit::TestCase
5
+ test "given invalid name, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :name
9
+ validates_true_for :name, :logic => lambda { name == "nombre" }
10
+ end
11
+ instance = klass.new
12
+ instance.valid?
13
+ assert_equal "is invalid", instance.errors.on(:name)
14
+ end
15
+
16
+ test "given valid name, when validated, then no error is in the objects error collection" do
17
+ klass = Class.new do
18
+ include Validatable
19
+ attr_accessor :name
20
+ validates_true_for :name, :logic => lambda { name == "nombre" }
21
+ end
22
+ instance = klass.new
23
+ instance.name = "nombre"
24
+ assert_equal true, instance.valid?
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'mocha'
4
+ require 'dust'
5
+ require 'set'
6
+ require 'expectations'
7
+
8
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/validatable')
9
+
10
+ class << Test::Unit::TestCase
11
+ def expect(expected_value, &block)
12
+ define_method :"test_#{caller.first.split("/").last}" do
13
+ begin
14
+ assert_equal expected_value, instance_eval(&block)
15
+ rescue Exception => ex
16
+ raise ex unless expected_value.is_a?(Class) && ex.is_a?(expected_value)
17
+ assert_equal expected_value, ex.class
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class Test::Unit::TestCase
24
+ def assert_array_equal a, b
25
+ assert_equal Set.new(a), Set.new(b)
26
+ end
27
+ end
28
+
29
+ class Array
30
+ def to_blank_options_hash
31
+ self.inject({}) {|hash, value| hash[value] = nil; hash }
32
+ end
33
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ Expectations do
4
+ expect "message" do
5
+ errors = Validatable::Errors.new
6
+ errors.add(:attribute, "message")
7
+ errors.on(:attribute)
8
+ end
9
+
10
+ expect ["message"] do
11
+ errors = Validatable::Errors.new
12
+ errors.add(:attribute, "message")
13
+ errors.raw(:attribute)
14
+ end
15
+
16
+ expect "something new" do
17
+ errors = Validatable::Errors.new
18
+ errors.add(:attribute, "something old")
19
+ errors.replace(:attribute, ["something new"])
20
+ errors.on(:attribute)
21
+ end
22
+
23
+ expect "Capitalized word" do
24
+ errors = Validatable::Errors.new
25
+ errors.humanize("capitalized_word")
26
+ end
27
+
28
+ expect "Capitalized word without" do
29
+ errors = Validatable::Errors.new
30
+ errors.humanize("capitalized_word_without_id")
31
+ end
32
+
33
+ expect ["A humanized message", "a base message"] do
34
+ errors = Validatable::Errors.new
35
+ errors.add(:base, "a base message")
36
+ errors.add(:a_humanized, "message")
37
+ errors.full_messages.sort
38
+ end
39
+
40
+ expect true do
41
+ Validatable::Errors.included_modules.include?(Enumerable)
42
+ end
43
+
44
+ expect ["message1", "message2"] do
45
+ errors = Validatable::Errors.new
46
+ errors.add(:attribute, "message1")
47
+ errors.add(:attribute, "message2")
48
+ errors.on(:attribute)
49
+ end
50
+
51
+ expect 2 do
52
+ errors = Validatable::Errors.new
53
+ errors.add(:attribute, "message1")
54
+ errors.add(:attribute, "message2")
55
+ errors.count
56
+ end
57
+
58
+ expect 2 do
59
+ errors = Validatable::Errors.new
60
+ errors.add(:attribute1, "message1")
61
+ errors.add(:attribute2, "message2")
62
+ errors.count
63
+ end
64
+
65
+ expect [] do
66
+ errors = Validatable::Errors.new
67
+ errors[:attribute]
68
+ end
69
+
70
+ expect ["message"] do
71
+ errors = Validatable::Errors.new
72
+ errors.add(:attribute, "message")
73
+ errors[:attribute]
74
+ end
75
+
76
+ expect ["message1", "message2"] do
77
+ errors = Validatable::Errors.new
78
+ errors.add(:attribute, "message1")
79
+ errors.add(:attribute, "message2")
80
+ errors[:attribute]
81
+ end
82
+ end