hashrocket-mongomapper 0.3.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/.gitignore +7 -0
- data/History +70 -0
- data/LICENSE +20 -0
- data/README.rdoc +39 -0
- data/Rakefile +73 -0
- data/VERSION +1 -0
- data/bin/mmconsole +56 -0
- data/lib/mongomapper.rb +70 -0
- data/lib/mongomapper/associations.rb +84 -0
- data/lib/mongomapper/associations/base.rb +69 -0
- data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +34 -0
- data/lib/mongomapper/associations/belongs_to_proxy.rb +22 -0
- data/lib/mongomapper/associations/many_documents_proxy.rb +103 -0
- data/lib/mongomapper/associations/many_embedded_polymorphic_proxy.rb +33 -0
- data/lib/mongomapper/associations/many_embedded_proxy.rb +17 -0
- data/lib/mongomapper/associations/many_polymorphic_proxy.rb +11 -0
- data/lib/mongomapper/associations/many_proxy.rb +6 -0
- data/lib/mongomapper/associations/proxy.rb +63 -0
- data/lib/mongomapper/callbacks.rb +106 -0
- data/lib/mongomapper/document.rb +337 -0
- data/lib/mongomapper/dynamic_finder.rb +38 -0
- data/lib/mongomapper/embedded_document.rb +267 -0
- data/lib/mongomapper/finder_options.rb +85 -0
- data/lib/mongomapper/key.rb +76 -0
- data/lib/mongomapper/observing.rb +50 -0
- data/lib/mongomapper/pagination.rb +52 -0
- data/lib/mongomapper/rails_compatibility/document.rb +15 -0
- data/lib/mongomapper/rails_compatibility/embedded_document.rb +25 -0
- data/lib/mongomapper/save_with_validation.rb +19 -0
- data/lib/mongomapper/serialization.rb +55 -0
- data/lib/mongomapper/serializers/json_serializer.rb +92 -0
- data/lib/mongomapper/support.rb +30 -0
- data/lib/mongomapper/validations.rb +61 -0
- data/mongomapper.gemspec +142 -0
- data/test/NOTE_ON_TESTING +1 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +53 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +45 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +131 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +106 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +261 -0
- data/test/functional/associations/test_many_proxy.rb +295 -0
- data/test/functional/test_associations.rb +47 -0
- data/test/functional/test_callbacks.rb +85 -0
- data/test/functional/test_document.rb +952 -0
- data/test/functional/test_pagination.rb +81 -0
- data/test/functional/test_rails_compatibility.rb +30 -0
- data/test/functional/test_validations.rb +172 -0
- data/test/models.rb +139 -0
- data/test/test_helper.rb +67 -0
- data/test/unit/serializers/test_json_serializer.rb +157 -0
- data/test/unit/test_association_base.rb +144 -0
- data/test/unit/test_document.rb +123 -0
- data/test/unit/test_embedded_document.rb +526 -0
- data/test/unit/test_finder_options.rb +183 -0
- data/test/unit/test_key.rb +247 -0
- data/test/unit/test_mongomapper.rb +28 -0
- data/test/unit/test_observing.rb +101 -0
- data/test/unit/test_pagination.rb +113 -0
- data/test/unit/test_rails_compatibility.rb +34 -0
- data/test/unit/test_serializations.rb +52 -0
- data/test/unit/test_validations.rb +500 -0
- metadata +189 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Comment
|
4
|
+
include MongoMapper::Document
|
5
|
+
|
6
|
+
key :name, String
|
7
|
+
key :body, String
|
8
|
+
|
9
|
+
attr_accessor :callers
|
10
|
+
before_validation :record_callers
|
11
|
+
|
12
|
+
def after_validation
|
13
|
+
record_callers
|
14
|
+
end
|
15
|
+
|
16
|
+
def record_callers
|
17
|
+
callers << self.class if callers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Article
|
22
|
+
include MongoMapper::Document
|
23
|
+
|
24
|
+
key :title, String
|
25
|
+
key :body, String
|
26
|
+
end
|
27
|
+
|
28
|
+
class CommentObserver < MongoMapper::Observer
|
29
|
+
attr_accessor :callers
|
30
|
+
|
31
|
+
def after_validation(model)
|
32
|
+
callers << self.class if callers
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class AuditObserver < MongoMapper::Observer
|
37
|
+
observe Article, Comment
|
38
|
+
attr_reader :document
|
39
|
+
|
40
|
+
def after_validation(document)
|
41
|
+
@document = document
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class GlobalObserver < MongoMapper::Observer
|
46
|
+
observe Article, Comment
|
47
|
+
attr_reader :document
|
48
|
+
|
49
|
+
def before_save(document)
|
50
|
+
@document = document
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class NonAutomaticObserver < MongoMapper::Observer
|
55
|
+
observe Comment
|
56
|
+
attr_reader :comment
|
57
|
+
|
58
|
+
def after_validation(comment)
|
59
|
+
@comment = comment
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class ObserverTest < Test::Unit::TestCase
|
64
|
+
should "fire model callbacks before observer" do
|
65
|
+
callers = []
|
66
|
+
comment = Comment.new
|
67
|
+
comment.callers = callers
|
68
|
+
|
69
|
+
CommentObserver.instance.callers = callers
|
70
|
+
|
71
|
+
comment.valid?
|
72
|
+
callers.should == [Comment, Comment, CommentObserver]
|
73
|
+
end
|
74
|
+
|
75
|
+
should "automatically observe model based on name when possible" do
|
76
|
+
CommentObserver.observed_class.should == Comment
|
77
|
+
end
|
78
|
+
|
79
|
+
should "be able to observe other models using observe" do
|
80
|
+
obs = NonAutomaticObserver.instance
|
81
|
+
comment = Comment.new(:name => 'John Nunemaker', :body => 'is awesome')
|
82
|
+
comment.valid?
|
83
|
+
obs.comment.name.should == 'John Nunemaker'
|
84
|
+
obs.comment.body.should == 'is awesome'
|
85
|
+
end
|
86
|
+
|
87
|
+
should "be able to observe multiple models" do
|
88
|
+
obs = AuditObserver.instance
|
89
|
+
comment = Comment.new(:name => 'Steve Smith', :body => 'is awesome')
|
90
|
+
comment.valid?
|
91
|
+
|
92
|
+
obs.document.name.should == 'Steve Smith'
|
93
|
+
obs.document.body.should == 'is awesome'
|
94
|
+
|
95
|
+
article = Article.new(:title => 'Ordered List Is Awesome', :body => 'Learn to accept it!')
|
96
|
+
article.valid?
|
97
|
+
|
98
|
+
obs.document.title.should == 'Ordered List Is Awesome'
|
99
|
+
obs.document.body.should == 'Learn to accept it!'
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PaginationTest < Test::Unit::TestCase
|
4
|
+
context "Pagination proxy" do
|
5
|
+
include MongoMapper::Pagination
|
6
|
+
|
7
|
+
should "should have accessors for subject" do
|
8
|
+
subject = [1,2,3,4,5]
|
9
|
+
collection = PaginationProxy.new(25, 2)
|
10
|
+
collection.subject = subject
|
11
|
+
collection.subject.should == subject
|
12
|
+
end
|
13
|
+
|
14
|
+
should "delegate any methods not defined to the subject" do
|
15
|
+
subject = [1,2,3,4,5]
|
16
|
+
collection = PaginationProxy.new(25, 2, 10)
|
17
|
+
collection.subject = subject
|
18
|
+
collection.size.should == 5
|
19
|
+
collection.each_with_index do |value, i|
|
20
|
+
value.should == subject[i]
|
21
|
+
end
|
22
|
+
collection[0..2].should == [1,2,3]
|
23
|
+
collection.class.should == Array
|
24
|
+
end
|
25
|
+
|
26
|
+
should "return correct value for total_entries" do
|
27
|
+
PaginationProxy.new(25, 2, 10).total_entries.should == 25
|
28
|
+
PaginationProxy.new('25', 2, 10).total_entries.should == 25
|
29
|
+
end
|
30
|
+
|
31
|
+
should "return correct value for per_page" do
|
32
|
+
PaginationProxy.new(25, 2, 10).per_page.should == 10
|
33
|
+
PaginationProxy.new(25, 2, '10').per_page.should == 10
|
34
|
+
end
|
35
|
+
|
36
|
+
should "alias limit to per_page" do
|
37
|
+
PaginationProxy.new(100, 1, 300).limit.should == 300
|
38
|
+
end
|
39
|
+
|
40
|
+
should "set per_page to 25 if nil or blank" do
|
41
|
+
PaginationProxy.new(25, 2).per_page.should == 25
|
42
|
+
PaginationProxy.new(25, 2, '').per_page.should == 25
|
43
|
+
end
|
44
|
+
|
45
|
+
should "return correct value for current_page" do
|
46
|
+
PaginationProxy.new(25, 2, 10).current_page.should == 2
|
47
|
+
PaginationProxy.new(25, '2', 10).current_page.should == 2
|
48
|
+
end
|
49
|
+
|
50
|
+
should "not allow value less than 1 for current page" do
|
51
|
+
PaginationProxy.new(25, -1).current_page.should == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
should "automatically calculate total_pages from total_entries and per page" do
|
55
|
+
PaginationProxy.new(25, 2, 10).total_pages.should == 3
|
56
|
+
end
|
57
|
+
|
58
|
+
should "know how many records to skip" do
|
59
|
+
PaginationProxy.new(25, 2, 10).skip.should == 10
|
60
|
+
end
|
61
|
+
|
62
|
+
should "alias offset to skip" do
|
63
|
+
PaginationProxy.new(25, 2, 10).offset.should == 10
|
64
|
+
end
|
65
|
+
|
66
|
+
context "previous_page" do
|
67
|
+
should "be nil if current page 1" do
|
68
|
+
PaginationProxy.new(25, 1, 10).previous_page.should be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
should "be one less than current page if current is > 1" do
|
72
|
+
PaginationProxy.new(25, 2, 10).previous_page.should == 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "next_page" do
|
77
|
+
should "be nil if current page is last page" do
|
78
|
+
PaginationProxy.new(25, 3, 10).next_page.should be_nil
|
79
|
+
end
|
80
|
+
|
81
|
+
should "work for any page that is not last" do
|
82
|
+
PaginationProxy.new(25, 1, 10).next_page.should == 2
|
83
|
+
PaginationProxy.new(25, 2, 10).next_page.should == 3
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "previous_page" do
|
88
|
+
should "be nil if current page is first page" do
|
89
|
+
PaginationProxy.new(25, 1, 10).previous_page.should be_nil
|
90
|
+
end
|
91
|
+
|
92
|
+
should "work for any page other than first" do
|
93
|
+
PaginationProxy.new(25, 2, 10).previous_page.should == 1
|
94
|
+
PaginationProxy.new(25, 3, 10).previous_page.should == 2
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "out_of_bounds?" do
|
99
|
+
should "be true if current_page is greater than total_pages" do
|
100
|
+
PaginationProxy.new(25, 10, 4).out_of_bounds?.should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
should "be false if current_page is less than total_pages" do
|
104
|
+
PaginationProxy.new(25, 10, 1).out_of_bounds?.should be_false
|
105
|
+
PaginationProxy.new(25, 2, 10).out_of_bounds?.should be_false
|
106
|
+
end
|
107
|
+
|
108
|
+
should "be false if current_page is equal to total_pages" do
|
109
|
+
PaginationProxy.new(25, 3, 10).out_of_bounds?.should be_false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end # end of pagination proxy
|
113
|
+
end # end of test case
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestRailsCompatibility < Test::Unit::TestCase
|
4
|
+
class Item
|
5
|
+
include MongoMapper::EmbeddedDocument
|
6
|
+
key :for_all, String
|
7
|
+
end
|
8
|
+
|
9
|
+
class FirstItem < Item
|
10
|
+
key :first_only, String
|
11
|
+
many :second_items
|
12
|
+
end
|
13
|
+
|
14
|
+
class SecondItem < Item
|
15
|
+
key :second_only, String
|
16
|
+
end
|
17
|
+
|
18
|
+
context "EmbeddedDocument" do
|
19
|
+
should "raise error for to_param as embedded do not have id's" do
|
20
|
+
lambda { Item.new.to_param }.should raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
should "alias many to has_many" do
|
24
|
+
FirstItem.should respond_to(:has_many)
|
25
|
+
FirstItem.method(:has_many).should == FirstItem.method(:many)
|
26
|
+
end
|
27
|
+
|
28
|
+
should "have column names" do
|
29
|
+
Item.column_names.sort.should == ['_id', 'for_all']
|
30
|
+
FirstItem.column_names.sort.should == ['_id', 'first_only', 'for_all']
|
31
|
+
SecondItem.column_names.sort.should == ['_id', 'for_all', 'second_only']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SerializationTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@document = Class.new do
|
6
|
+
include MongoMapper::EmbeddedDocument
|
7
|
+
key :name, String
|
8
|
+
key :age, Integer
|
9
|
+
key :awesome, Boolean
|
10
|
+
key :preferences, Hash
|
11
|
+
key :created_at, Time
|
12
|
+
end
|
13
|
+
|
14
|
+
@instance = @document.new(
|
15
|
+
:name => 'John Doe',
|
16
|
+
:age => 25,
|
17
|
+
:awesome => true,
|
18
|
+
:preferences => {:language => 'Ruby'},
|
19
|
+
:created_at => Time.now.change(:usec => 0)
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
[:json].each do |format|
|
24
|
+
context format do
|
25
|
+
should "be reversable" do
|
26
|
+
serialized = @instance.send("to_#{format}")
|
27
|
+
unserialized = @document.new.send("from_#{format}", serialized)
|
28
|
+
|
29
|
+
assert_equal @instance, unserialized
|
30
|
+
end
|
31
|
+
|
32
|
+
should "allow attribute only filtering" do
|
33
|
+
serialized = @instance.send("to_#{format}", :only => [ :age, :name ])
|
34
|
+
unserialized = @document.new.send("from_#{format}", serialized)
|
35
|
+
|
36
|
+
assert_equal @instance.name, unserialized.name
|
37
|
+
assert_equal @instance.age, unserialized.age
|
38
|
+
assert_nil unserialized.awesome
|
39
|
+
assert_nil unserialized.created_at
|
40
|
+
end
|
41
|
+
|
42
|
+
should "allow attribute except filtering" do
|
43
|
+
serialized = @instance.send("to_#{format}", :except => [ :age, :name ])
|
44
|
+
unserialized = @document.new.send("from_#{format}", serialized)
|
45
|
+
|
46
|
+
assert_nil unserialized.name
|
47
|
+
assert_nil unserialized.age
|
48
|
+
assert_equal @instance.awesome, unserialized.awesome
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,500 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ValidationsTest < Test::Unit::TestCase
|
4
|
+
context "Validations" do
|
5
|
+
|
6
|
+
context "on a Document" do
|
7
|
+
|
8
|
+
setup do
|
9
|
+
@document = Class.new do
|
10
|
+
include MongoMapper::Document
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "Validating acceptance of" do
|
15
|
+
should "work with validates_acceptance_of macro" do
|
16
|
+
@document.key :terms, String
|
17
|
+
@document.validates_acceptance_of :terms
|
18
|
+
doc = @document.new(:terms => '')
|
19
|
+
doc.should have_error_on(:terms)
|
20
|
+
doc.terms = '1'
|
21
|
+
doc.should_not have_error_on(:terms)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "validating confirmation of" do
|
26
|
+
should "work with validates_confirmation_of macro" do
|
27
|
+
@document.key :password, String
|
28
|
+
@document.validates_confirmation_of :password
|
29
|
+
doc = @document.new
|
30
|
+
doc.password = 'foobar'
|
31
|
+
doc.should have_error_on(:password)
|
32
|
+
doc.password_confirmation = 'foobar'
|
33
|
+
doc.should_not have_error_on(:password)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "validating format of" do
|
38
|
+
should "work with validates_format_of macro" do
|
39
|
+
@document.key :name, String
|
40
|
+
@document.validates_format_of :name, :with => /.+/
|
41
|
+
doc = @document.new
|
42
|
+
doc.should have_error_on(:name)
|
43
|
+
doc.name = 'John'
|
44
|
+
doc.should_not have_error_on(:name)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "work with :format shorcut key" do
|
48
|
+
@document.key :name, String, :format => /.+/
|
49
|
+
doc = @document.new
|
50
|
+
doc.should have_error_on(:name)
|
51
|
+
doc.name = 'John'
|
52
|
+
doc.should_not have_error_on(:name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "validating length of" do
|
57
|
+
should "work with validates_length_of macro" do
|
58
|
+
@document.key :name, String
|
59
|
+
@document.validates_length_of :name, :minimum => 5
|
60
|
+
doc = @document.new
|
61
|
+
doc.should have_error_on(:name)
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with :length => integer shortcut" do
|
65
|
+
should "set maximum of integer provided" do
|
66
|
+
@document.key :name, String, :length => 5
|
67
|
+
doc = @document.new
|
68
|
+
doc.name = '123456'
|
69
|
+
doc.should have_error_on(:name)
|
70
|
+
doc.name = '12345'
|
71
|
+
doc.should_not have_error_on(:name)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "with :length => range shortcut" do
|
76
|
+
setup do
|
77
|
+
@document.key :name, String, :length => 5..7
|
78
|
+
end
|
79
|
+
|
80
|
+
should "set minimum of range min" do
|
81
|
+
doc = @document.new
|
82
|
+
doc.should have_error_on(:name)
|
83
|
+
doc.name = '123456'
|
84
|
+
doc.should_not have_error_on(:name)
|
85
|
+
end
|
86
|
+
|
87
|
+
should "set maximum of range max" do
|
88
|
+
doc = @document.new
|
89
|
+
doc.should have_error_on(:name)
|
90
|
+
doc.name = '12345678'
|
91
|
+
doc.should have_error_on(:name)
|
92
|
+
doc.name = '123456'
|
93
|
+
doc.should_not have_error_on(:name)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "with :length => hash shortcut" do
|
98
|
+
should "pass options through" do
|
99
|
+
@document.key :name, String, :length => {:minimum => 2}
|
100
|
+
doc = @document.new
|
101
|
+
doc.should have_error_on(:name)
|
102
|
+
doc.name = '12'
|
103
|
+
doc.should_not have_error_on(:name)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end # validates_length_of
|
107
|
+
|
108
|
+
context "Validating numericality of" do
|
109
|
+
should "work with validates_numericality_of macro" do
|
110
|
+
@document.key :age, Integer
|
111
|
+
@document.validates_numericality_of :age
|
112
|
+
doc = @document.new
|
113
|
+
doc.age = 'String'
|
114
|
+
doc.should have_error_on(:age)
|
115
|
+
doc.age = 23
|
116
|
+
doc.should_not have_error_on(:age)
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with :numeric shortcut" do
|
120
|
+
should "work with integer or float" do
|
121
|
+
@document.key :weight, Float, :numeric => true
|
122
|
+
doc = @document.new
|
123
|
+
doc.weight = 'String'
|
124
|
+
doc.should have_error_on(:weight)
|
125
|
+
doc.weight = 23.0
|
126
|
+
doc.should_not have_error_on(:weight)
|
127
|
+
doc.weight = 23
|
128
|
+
doc.should_not have_error_on(:weight)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "with :numeric shortcut on Integer key" do
|
133
|
+
should "only work with integers" do
|
134
|
+
@document.key :age, Integer, :numeric => true
|
135
|
+
doc = @document.new
|
136
|
+
doc.age = 'String'
|
137
|
+
doc.should have_error_on(:age)
|
138
|
+
doc.age = 23.1
|
139
|
+
doc.should have_error_on(:age)
|
140
|
+
doc.age = 23
|
141
|
+
doc.should_not have_error_on(:age)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end # numericality of
|
145
|
+
|
146
|
+
context "validating presence of" do
|
147
|
+
should "work with validates_presence_of macro" do
|
148
|
+
@document.key :name, String
|
149
|
+
@document.validates_presence_of :name
|
150
|
+
doc = @document.new
|
151
|
+
doc.should have_error_on(:name)
|
152
|
+
end
|
153
|
+
|
154
|
+
should "work with :required shortcut on key definition" do
|
155
|
+
@document.key :name, String, :required => true
|
156
|
+
doc = @document.new
|
157
|
+
doc.should have_error_on(:name)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "validating exclusion of" do
|
162
|
+
should "throw error if enumerator not provided" do
|
163
|
+
@document.key :action, String
|
164
|
+
lambda {
|
165
|
+
@document.validates_exclusion_of :action
|
166
|
+
}.should raise_error(ArgumentError)
|
167
|
+
end
|
168
|
+
|
169
|
+
should "work with validates_exclusion_of macro" do
|
170
|
+
@document.key :action, String
|
171
|
+
@document.validates_exclusion_of :action, :within => %w(kick run)
|
172
|
+
|
173
|
+
doc = @document.new
|
174
|
+
doc.should_not have_error_on(:action)
|
175
|
+
|
176
|
+
doc.action = 'fart'
|
177
|
+
doc.should_not have_error_on(:action)
|
178
|
+
|
179
|
+
doc.action = 'kick'
|
180
|
+
doc.should have_error_on(:action, 'is reserved')
|
181
|
+
end
|
182
|
+
|
183
|
+
should "not have error if allow nil is true and value is nil" do
|
184
|
+
@document.key :action, String
|
185
|
+
@document.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
|
186
|
+
|
187
|
+
doc = @document.new
|
188
|
+
doc.should_not have_error_on(:action)
|
189
|
+
end
|
190
|
+
|
191
|
+
should "not have error if allow blank is true and value is blank" do
|
192
|
+
@document.key :action, String
|
193
|
+
@document.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
|
194
|
+
|
195
|
+
doc = @document.new(:action => '')
|
196
|
+
doc.should_not have_error_on(:action)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context "validating inclusion of" do
|
201
|
+
should "throw error if enumerator not provided" do
|
202
|
+
@document.key :action, String
|
203
|
+
lambda {
|
204
|
+
@document.validates_inclusion_of :action
|
205
|
+
}.should raise_error(ArgumentError)
|
206
|
+
end
|
207
|
+
|
208
|
+
should "work with validates_inclusion_of macro" do
|
209
|
+
@document.key :action, String
|
210
|
+
@document.validates_inclusion_of :action, :within => %w(kick run)
|
211
|
+
|
212
|
+
doc = @document.new
|
213
|
+
doc.should have_error_on(:action, 'is not in the list')
|
214
|
+
|
215
|
+
doc.action = 'fart'
|
216
|
+
doc.should have_error_on(:action, 'is not in the list')
|
217
|
+
|
218
|
+
doc.action = 'kick'
|
219
|
+
doc.should_not have_error_on(:action)
|
220
|
+
end
|
221
|
+
|
222
|
+
should "not have error if allow nil is true and value is nil" do
|
223
|
+
@document.key :action, String
|
224
|
+
@document.validates_inclusion_of :action, :within => %w(kick run), :allow_nil => true
|
225
|
+
|
226
|
+
doc = @document.new
|
227
|
+
doc.should_not have_error_on(:action)
|
228
|
+
end
|
229
|
+
|
230
|
+
should "not have error if allow blank is true and value is blank" do
|
231
|
+
@document.key :action, String
|
232
|
+
@document.validates_inclusion_of :action, :within => %w(kick run), :allow_blank => true
|
233
|
+
|
234
|
+
doc = @document.new(:action => '')
|
235
|
+
doc.should_not have_error_on(:action)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
end # End on a Document
|
240
|
+
|
241
|
+
context "On an EmbeddedDocument" do
|
242
|
+
|
243
|
+
setup do
|
244
|
+
@embedded_doc = Class.new do
|
245
|
+
include MongoMapper::EmbeddedDocument
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context "Validating acceptance of" do
|
250
|
+
should "work with validates_acceptance_of macro" do
|
251
|
+
@embedded_doc.key :terms, String
|
252
|
+
@embedded_doc.validates_acceptance_of :terms
|
253
|
+
doc = @embedded_doc.new(:terms => '')
|
254
|
+
doc.should have_error_on(:terms)
|
255
|
+
doc.terms = '1'
|
256
|
+
doc.should_not have_error_on(:terms)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context "validating confirmation of" do
|
261
|
+
should "work with validates_confirmation_of macro" do
|
262
|
+
@embedded_doc.key :password, String
|
263
|
+
@embedded_doc.validates_confirmation_of :password
|
264
|
+
doc = @embedded_doc.new
|
265
|
+
doc.password = 'foobar'
|
266
|
+
doc.should have_error_on(:password)
|
267
|
+
doc.password_confirmation = 'foobar'
|
268
|
+
doc.should_not have_error_on(:password)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context "validating format of" do
|
273
|
+
should "work with validates_format_of macro" do
|
274
|
+
@embedded_doc.key :name, String
|
275
|
+
@embedded_doc.validates_format_of :name, :with => /.+/
|
276
|
+
doc = @embedded_doc.new
|
277
|
+
doc.should have_error_on(:name)
|
278
|
+
doc.name = 'John'
|
279
|
+
doc.should_not have_error_on(:name)
|
280
|
+
end
|
281
|
+
|
282
|
+
should "work with :format shorcut key" do
|
283
|
+
@embedded_doc.key :name, String, :format => /.+/
|
284
|
+
doc = @embedded_doc.new
|
285
|
+
doc.should have_error_on(:name)
|
286
|
+
doc.name = 'John'
|
287
|
+
doc.should_not have_error_on(:name)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
context "validating length of" do
|
292
|
+
should "work with validates_length_of macro" do
|
293
|
+
@embedded_doc.key :name, String
|
294
|
+
@embedded_doc.validates_length_of :name, :minimum => 5
|
295
|
+
doc = @embedded_doc.new
|
296
|
+
doc.should have_error_on(:name)
|
297
|
+
end
|
298
|
+
|
299
|
+
context "with :length => integer shortcut" do
|
300
|
+
should "set maximum of integer provided" do
|
301
|
+
@embedded_doc.key :name, String, :length => 5
|
302
|
+
doc = @embedded_doc.new
|
303
|
+
doc.name = '123456'
|
304
|
+
doc.should have_error_on(:name)
|
305
|
+
doc.name = '12345'
|
306
|
+
doc.should_not have_error_on(:name)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
context "with :length => range shortcut" do
|
311
|
+
setup do
|
312
|
+
@embedded_doc.key :name, String, :length => 5..7
|
313
|
+
end
|
314
|
+
|
315
|
+
should "set minimum of range min" do
|
316
|
+
doc = @embedded_doc.new
|
317
|
+
doc.should have_error_on(:name)
|
318
|
+
doc.name = '123456'
|
319
|
+
doc.should_not have_error_on(:name)
|
320
|
+
end
|
321
|
+
|
322
|
+
should "set maximum of range max" do
|
323
|
+
doc = @embedded_doc.new
|
324
|
+
doc.should have_error_on(:name)
|
325
|
+
doc.name = '12345678'
|
326
|
+
doc.should have_error_on(:name)
|
327
|
+
doc.name = '123456'
|
328
|
+
doc.should_not have_error_on(:name)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
context "with :length => hash shortcut" do
|
333
|
+
should "pass options through" do
|
334
|
+
@embedded_doc.key :name, String, :length => {:minimum => 2}
|
335
|
+
doc = @embedded_doc.new
|
336
|
+
doc.should have_error_on(:name)
|
337
|
+
doc.name = '12'
|
338
|
+
doc.should_not have_error_on(:name)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end # validates_length_of
|
342
|
+
|
343
|
+
context "Validating numericality of" do
|
344
|
+
should "work with validates_numericality_of macro" do
|
345
|
+
@embedded_doc.key :age, Integer
|
346
|
+
@embedded_doc.validates_numericality_of :age
|
347
|
+
doc = @embedded_doc.new
|
348
|
+
doc.age = 'String'
|
349
|
+
doc.should have_error_on(:age)
|
350
|
+
doc.age = 23
|
351
|
+
doc.should_not have_error_on(:age)
|
352
|
+
end
|
353
|
+
|
354
|
+
context "with :numeric shortcut" do
|
355
|
+
should "work with integer or float" do
|
356
|
+
@embedded_doc.key :weight, Float, :numeric => true
|
357
|
+
doc = @embedded_doc.new
|
358
|
+
doc.weight = 'String'
|
359
|
+
doc.should have_error_on(:weight)
|
360
|
+
doc.weight = 23.0
|
361
|
+
doc.should_not have_error_on(:weight)
|
362
|
+
doc.weight = 23
|
363
|
+
doc.should_not have_error_on(:weight)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
context "with :numeric shortcut on Integer key" do
|
368
|
+
should "only work with integers" do
|
369
|
+
@embedded_doc.key :age, Integer, :numeric => true
|
370
|
+
doc = @embedded_doc.new
|
371
|
+
doc.age = 'String'
|
372
|
+
doc.should have_error_on(:age)
|
373
|
+
doc.age = 23.1
|
374
|
+
doc.should have_error_on(:age)
|
375
|
+
doc.age = 23
|
376
|
+
doc.should_not have_error_on(:age)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end # numericality of
|
380
|
+
|
381
|
+
context "validating presence of" do
|
382
|
+
should "work with validates_presence_of macro" do
|
383
|
+
@embedded_doc.key :name, String
|
384
|
+
@embedded_doc.validates_presence_of :name
|
385
|
+
doc = @embedded_doc.new
|
386
|
+
doc.should have_error_on(:name)
|
387
|
+
end
|
388
|
+
|
389
|
+
should "work with :required shortcut on key definition" do
|
390
|
+
@embedded_doc.key :name, String, :required => true
|
391
|
+
doc = @embedded_doc.new
|
392
|
+
doc.should have_error_on(:name)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
context "validating exclusion of" do
|
397
|
+
should "throw error if enumerator not provided" do
|
398
|
+
@embedded_doc.key :action, String
|
399
|
+
lambda {
|
400
|
+
@embedded_doc.validates_exclusion_of :action
|
401
|
+
}.should raise_error(ArgumentError)
|
402
|
+
end
|
403
|
+
|
404
|
+
should "work with validates_exclusion_of macro" do
|
405
|
+
@embedded_doc.key :action, String
|
406
|
+
@embedded_doc.validates_exclusion_of :action, :within => %w(kick run)
|
407
|
+
|
408
|
+
doc = @embedded_doc.new
|
409
|
+
doc.should_not have_error_on(:action)
|
410
|
+
|
411
|
+
doc.action = 'fart'
|
412
|
+
doc.should_not have_error_on(:action)
|
413
|
+
|
414
|
+
doc.action = 'kick'
|
415
|
+
doc.should have_error_on(:action, 'is reserved')
|
416
|
+
end
|
417
|
+
|
418
|
+
should "not have error if allow nil is true and value is nil" do
|
419
|
+
@embedded_doc.key :action, String
|
420
|
+
@embedded_doc.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
|
421
|
+
|
422
|
+
doc = @embedded_doc.new
|
423
|
+
doc.should_not have_error_on(:action)
|
424
|
+
end
|
425
|
+
|
426
|
+
should "not have error if allow blank is true and value is blank" do
|
427
|
+
@embedded_doc.key :action, String
|
428
|
+
@embedded_doc.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
|
429
|
+
|
430
|
+
doc = @embedded_doc.new(:action => '')
|
431
|
+
doc.should_not have_error_on(:action)
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
context "validating inclusion of" do
|
436
|
+
should "throw error if enumerator not provided" do
|
437
|
+
@embedded_doc.key :action, String
|
438
|
+
lambda {
|
439
|
+
@embedded_doc.validates_inclusion_of :action
|
440
|
+
}.should raise_error(ArgumentError)
|
441
|
+
end
|
442
|
+
|
443
|
+
should "work with validates_inclusion_of macro" do
|
444
|
+
@embedded_doc.key :action, String
|
445
|
+
@embedded_doc.validates_inclusion_of :action, :within => %w(kick run)
|
446
|
+
|
447
|
+
doc = @embedded_doc.new
|
448
|
+
doc.should have_error_on(:action, 'is not in the list')
|
449
|
+
|
450
|
+
doc.action = 'fart'
|
451
|
+
doc.should have_error_on(:action, 'is not in the list')
|
452
|
+
|
453
|
+
doc.action = 'kick'
|
454
|
+
doc.should_not have_error_on(:action)
|
455
|
+
end
|
456
|
+
|
457
|
+
should "not have error if allow nil is true and value is nil" do
|
458
|
+
@embedded_doc.key :action, String
|
459
|
+
@embedded_doc.validates_inclusion_of :action, :within => %w(kick run), :allow_nil => true
|
460
|
+
|
461
|
+
doc = @embedded_doc.new
|
462
|
+
doc.should_not have_error_on(:action)
|
463
|
+
end
|
464
|
+
|
465
|
+
should "not have error if allow blank is true and value is blank" do
|
466
|
+
@embedded_doc.key :action, String
|
467
|
+
@embedded_doc.validates_inclusion_of :action, :within => %w(kick run), :allow_blank => true
|
468
|
+
|
469
|
+
doc = @embedded_doc.new(:action => '')
|
470
|
+
doc.should_not have_error_on(:action)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
end # End on an EmbeddedDocument
|
475
|
+
|
476
|
+
end # Validations
|
477
|
+
|
478
|
+
context "Adding validation errors" do
|
479
|
+
setup do
|
480
|
+
@document = Class.new do
|
481
|
+
include MongoMapper::Document
|
482
|
+
key :action, String
|
483
|
+
def action_present
|
484
|
+
errors.add(:action, 'is invalid') if action.blank?
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
should "work with validate callback" do
|
490
|
+
@document.validate :action_present
|
491
|
+
|
492
|
+
doc = @document.new
|
493
|
+
doc.action = nil
|
494
|
+
doc.should have_error_on(:action)
|
495
|
+
|
496
|
+
doc.action = 'kick'
|
497
|
+
doc.should_not have_error_on(:action)
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|