lookout-mongo_mapper 0.11.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.
Files changed (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +33 -0
  3. data/UPGRADES +26 -0
  4. data/bin/mmconsole +59 -0
  5. data/examples/attr_accessible.rb +22 -0
  6. data/examples/attr_protected.rb +22 -0
  7. data/examples/cache_key.rb +24 -0
  8. data/examples/custom_types.rb +24 -0
  9. data/examples/identity_map.rb +33 -0
  10. data/examples/identity_map/automatic.rb +2 -0
  11. data/examples/keys.rb +40 -0
  12. data/examples/modifiers/set.rb +25 -0
  13. data/examples/plugins.rb +38 -0
  14. data/examples/querying.rb +35 -0
  15. data/examples/safe.rb +43 -0
  16. data/examples/scopes.rb +52 -0
  17. data/examples/validating/embedded_docs.rb +29 -0
  18. data/lib/mongo_mapper.rb +94 -0
  19. data/lib/mongo_mapper/connection.rb +96 -0
  20. data/lib/mongo_mapper/document.rb +42 -0
  21. data/lib/mongo_mapper/embedded_document.rb +32 -0
  22. data/lib/mongo_mapper/exceptions.rb +30 -0
  23. data/lib/mongo_mapper/extensions/array.rb +19 -0
  24. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  25. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  26. data/lib/mongo_mapper/extensions/date.rb +25 -0
  27. data/lib/mongo_mapper/extensions/float.rb +14 -0
  28. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  29. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  30. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  31. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  32. data/lib/mongo_mapper/extensions/object.rb +26 -0
  33. data/lib/mongo_mapper/extensions/object_id.rb +32 -0
  34. data/lib/mongo_mapper/extensions/set.rb +20 -0
  35. data/lib/mongo_mapper/extensions/string.rb +18 -0
  36. data/lib/mongo_mapper/extensions/time.rb +28 -0
  37. data/lib/mongo_mapper/locale/en.yml +5 -0
  38. data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
  39. data/lib/mongo_mapper/plugins.rb +22 -0
  40. data/lib/mongo_mapper/plugins/accessible.rb +52 -0
  41. data/lib/mongo_mapper/plugins/active_model.rb +18 -0
  42. data/lib/mongo_mapper/plugins/associations.rb +90 -0
  43. data/lib/mongo_mapper/plugins/associations/base.rb +92 -0
  44. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +54 -0
  45. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +34 -0
  46. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
  47. data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
  48. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +44 -0
  49. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +133 -0
  50. data/lib/mongo_mapper/plugins/associations/many_association.rb +63 -0
  51. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  52. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +118 -0
  53. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  54. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  55. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  56. data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +22 -0
  57. data/lib/mongo_mapper/plugins/associations/one_association.rb +48 -0
  58. data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  59. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
  60. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +95 -0
  61. data/lib/mongo_mapper/plugins/associations/proxy.rb +134 -0
  62. data/lib/mongo_mapper/plugins/associations/single_association.rb +46 -0
  63. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  64. data/lib/mongo_mapper/plugins/callbacks.rb +29 -0
  65. data/lib/mongo_mapper/plugins/clone.rb +22 -0
  66. data/lib/mongo_mapper/plugins/dirty.rb +60 -0
  67. data/lib/mongo_mapper/plugins/document.rb +41 -0
  68. data/lib/mongo_mapper/plugins/dynamic_querying.rb +45 -0
  69. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  70. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +56 -0
  71. data/lib/mongo_mapper/plugins/embedded_document.rb +53 -0
  72. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  73. data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
  74. data/lib/mongo_mapper/plugins/indexes.rb +13 -0
  75. data/lib/mongo_mapper/plugins/inspect.rb +16 -0
  76. data/lib/mongo_mapper/plugins/keys.rb +313 -0
  77. data/lib/mongo_mapper/plugins/keys/key.rb +61 -0
  78. data/lib/mongo_mapper/plugins/logger.rb +18 -0
  79. data/lib/mongo_mapper/plugins/modifiers.rb +134 -0
  80. data/lib/mongo_mapper/plugins/pagination.rb +16 -0
  81. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  82. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  83. data/lib/mongo_mapper/plugins/querying.rb +165 -0
  84. data/lib/mongo_mapper/plugins/querying/decorator.rb +36 -0
  85. data/lib/mongo_mapper/plugins/rails.rb +58 -0
  86. data/lib/mongo_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  87. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  88. data/lib/mongo_mapper/plugins/sci.rb +36 -0
  89. data/lib/mongo_mapper/plugins/scopes.rb +27 -0
  90. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  91. data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
  92. data/lib/mongo_mapper/plugins/touch.rb +18 -0
  93. data/lib/mongo_mapper/plugins/userstamps.rb +18 -0
  94. data/lib/mongo_mapper/plugins/validations.rb +86 -0
  95. data/lib/mongo_mapper/railtie.rb +48 -0
  96. data/lib/mongo_mapper/railtie/database.rake +65 -0
  97. data/lib/mongo_mapper/translation.rb +10 -0
  98. data/lib/mongo_mapper/version.rb +4 -0
  99. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +24 -0
  100. data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +18 -0
  101. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +23 -0
  102. data/lib/rails/generators/mongo_mapper/model/templates/model.rb +13 -0
  103. data/test/_NOTE_ON_TESTING +1 -0
  104. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
  105. data/test/functional/associations/test_belongs_to_proxy.rb +238 -0
  106. data/test/functional/associations/test_in_array_proxy.rb +349 -0
  107. data/test/functional/associations/test_many_documents_as_proxy.rb +231 -0
  108. data/test/functional/associations/test_many_documents_proxy.rb +866 -0
  109. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +239 -0
  110. data/test/functional/associations/test_many_embedded_proxy.rb +289 -0
  111. data/test/functional/associations/test_many_polymorphic_proxy.rb +303 -0
  112. data/test/functional/associations/test_one_as_proxy.rb +491 -0
  113. data/test/functional/associations/test_one_embedded_polymorphic_proxy.rb +208 -0
  114. data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
  115. data/test/functional/associations/test_one_proxy.rb +383 -0
  116. data/test/functional/test_accessible.rb +198 -0
  117. data/test/functional/test_associations.rb +46 -0
  118. data/test/functional/test_binary.rb +27 -0
  119. data/test/functional/test_caching.rb +77 -0
  120. data/test/functional/test_callbacks.rb +232 -0
  121. data/test/functional/test_dirty.rb +301 -0
  122. data/test/functional/test_document.rb +282 -0
  123. data/test/functional/test_dynamic_querying.rb +75 -0
  124. data/test/functional/test_embedded_document.rb +288 -0
  125. data/test/functional/test_equality.rb +20 -0
  126. data/test/functional/test_identity_map.rb +513 -0
  127. data/test/functional/test_indexes.rb +50 -0
  128. data/test/functional/test_logger.rb +20 -0
  129. data/test/functional/test_modifiers.rb +537 -0
  130. data/test/functional/test_pagination.rb +91 -0
  131. data/test/functional/test_protected.rb +201 -0
  132. data/test/functional/test_querying.rb +935 -0
  133. data/test/functional/test_safe.rb +76 -0
  134. data/test/functional/test_sci.rb +240 -0
  135. data/test/functional/test_scopes.rb +171 -0
  136. data/test/functional/test_timestamps.rb +62 -0
  137. data/test/functional/test_touch.rb +125 -0
  138. data/test/functional/test_userstamps.rb +44 -0
  139. data/test/functional/test_validations.rb +414 -0
  140. data/test/models.rb +261 -0
  141. data/test/support/railtie.rb +4 -0
  142. data/test/support/railtie/autoloaded.rb +2 -0
  143. data/test/support/railtie/not_autoloaded.rb +3 -0
  144. data/test/support/railtie/parent.rb +3 -0
  145. data/test/test_active_model_lint.rb +18 -0
  146. data/test/test_helper.rb +93 -0
  147. data/test/unit/associations/test_base.rb +146 -0
  148. data/test/unit/associations/test_belongs_to_association.rb +29 -0
  149. data/test/unit/associations/test_many_association.rb +63 -0
  150. data/test/unit/associations/test_one_association.rb +47 -0
  151. data/test/unit/associations/test_proxy.rb +100 -0
  152. data/test/unit/serializers/test_json_serializer.rb +216 -0
  153. data/test/unit/serializers/test_xml_serializer.rb +196 -0
  154. data/test/unit/test_clone.rb +69 -0
  155. data/test/unit/test_document.rb +249 -0
  156. data/test/unit/test_dynamic_finder.rb +125 -0
  157. data/test/unit/test_embedded_document.rb +682 -0
  158. data/test/unit/test_equality.rb +38 -0
  159. data/test/unit/test_exceptions.rb +12 -0
  160. data/test/unit/test_extensions.rb +380 -0
  161. data/test/unit/test_identity_map_middleware.rb +34 -0
  162. data/test/unit/test_inspect.rb +47 -0
  163. data/test/unit/test_key.rb +205 -0
  164. data/test/unit/test_keys.rb +65 -0
  165. data/test/unit/test_mongo_mapper.rb +143 -0
  166. data/test/unit/test_pagination.rb +11 -0
  167. data/test/unit/test_plugins.rb +89 -0
  168. data/test/unit/test_rails.rb +183 -0
  169. data/test/unit/test_rails_compatibility.rb +38 -0
  170. data/test/unit/test_rails_reflect_on_association.rb +118 -0
  171. data/test/unit/test_railtie.rb +66 -0
  172. data/test/unit/test_serialization.rb +166 -0
  173. data/test/unit/test_time_zones.rb +44 -0
  174. data/test/unit/test_translation.rb +27 -0
  175. data/test/unit/test_validations.rb +562 -0
  176. metadata +285 -0
@@ -0,0 +1,166 @@
1
+ require 'test_helper'
2
+
3
+ class SerializationTest < Test::Unit::TestCase
4
+ def setup
5
+ @document = EDoc do
6
+ key :name, String
7
+ key :age, Integer
8
+ key :awesome, Boolean
9
+ key :preferences, Hash
10
+ key :created_at, Time
11
+ end
12
+
13
+ @instance = @document.new(
14
+ :name => 'John Doe',
15
+ :age => 25,
16
+ :awesome => true,
17
+ :preferences => {:language => 'Ruby'},
18
+ :created_at => Time.now.change(:usec => 0)
19
+ )
20
+ end
21
+
22
+ context "#serializable_hash" do
23
+ class List
24
+ include MongoMapper::Document
25
+ key :name
26
+ many :items, :class_name => 'SerializationTest::Item'
27
+ belongs_to :creator, :class_name => 'SerializationTest::User'
28
+ end
29
+
30
+ class Item
31
+ include MongoMapper::Document
32
+
33
+ key :title
34
+ key :description
35
+ many :assignments, :class_name => 'SerializationTest::Assignment'
36
+
37
+ def a_method
38
+ 1
39
+ end
40
+ end
41
+
42
+ class Assignment
43
+ include MongoMapper::EmbeddedDocument
44
+ belongs_to :assigned_by, :class_name => 'SerializationTest::User'
45
+ belongs_to :user, :class_name => 'SerializationTest::User'
46
+
47
+ def serializable_hash(options = {})
48
+ super({:only => :user_id}.merge(options))
49
+ end
50
+ end
51
+
52
+ class User
53
+ include MongoMapper::Document
54
+ key :name, String
55
+ end
56
+
57
+ setup do
58
+ @user1 = User.new(:name => 'Brandon')
59
+ @user2 = User.new(:name => 'John')
60
+ @item = Item.new(
61
+ :title => 'Serialization',
62
+ :description => 'Make it work like magic!',
63
+ :assignments => [
64
+ Assignment.new(:assigned_by => @user1, :user => @user2)
65
+ ]
66
+ )
67
+ end
68
+
69
+ should "only include specified attributes with :only option" do
70
+ @item.serializable_hash(:only => :title).should == {'title' => 'Serialization'}
71
+ end
72
+
73
+ should "exclude attributes specified with :except option" do
74
+ hash = @item.serializable_hash(:except => :description)
75
+ hash['title'].should_not be_nil
76
+ hash['description'].should be_nil
77
+ end
78
+
79
+ should "add :methods with :only option" do
80
+ @item.serializable_hash(:only => :title, :methods => :a_method).should == {
81
+ 'title' => 'Serialization',
82
+ 'a_method' => 1
83
+ }
84
+ end
85
+
86
+ should "call #serializable_hash on embedded many docs" do
87
+ @item.serializable_hash.should == {
88
+ 'id' => @item.id,
89
+ 'title' => 'Serialization',
90
+ 'description' => 'Make it work like magic!',
91
+ 'assignments' => [{'user_id' => @user2.id}]
92
+ }
93
+ end
94
+
95
+ context "with :include" do
96
+ setup do
97
+ @list = List.new(:title => 'MongoMapper', :items => [@item], :creator => @user1)
98
+ end
99
+
100
+ should "add many association" do
101
+ hash = @list.serializable_hash(:include => :items)
102
+ hash['items'].should be_instance_of(Array)
103
+ hash['items'].first['title'].should == 'Serialization'
104
+ end
105
+
106
+ should "add belongs_to association" do
107
+ hash = @list.serializable_hash(:include => :creator)
108
+ hash['creator'].should == @user1.serializable_hash
109
+ end
110
+
111
+ should "add one association" do
112
+ author_class = Doc do
113
+ key :post_id, ObjectId
114
+ end
115
+ post_class = Doc('Post') do
116
+ one :author, :class => author_class
117
+ end
118
+
119
+ author = author_class.new
120
+ hash = post_class.new(:author => author).serializable_hash(:include => :author)
121
+ hash['author'].should == author.serializable_hash
122
+ end
123
+
124
+ should "include multiple associations" do
125
+ hash = @list.serializable_hash(:include => [:items, :creator])
126
+ hash['items'].should be_instance_of(Array)
127
+ hash['creator'].should == @user1.serializable_hash
128
+ end
129
+
130
+ should "include multiple associations with options" do
131
+ hash = @list.serializable_hash(:include => {:creator => {:only => :name}})
132
+ hash['creator'].should == @user1.serializable_hash(:only => :name)
133
+ end
134
+ end
135
+ end
136
+
137
+ [:json, :xml].each do |format|
138
+ context format do
139
+ should "be reversable" do
140
+ serialized = @instance.send("to_#{format}")
141
+ unserialized = @document.send("from_#{format}", serialized)
142
+
143
+ assert_equal @instance, unserialized
144
+ end
145
+
146
+ should "allow attribute only filtering" do
147
+ serialized = @instance.send("to_#{format}", :only => [ :age, :name ])
148
+ unserialized = @document.send("from_#{format}", serialized)
149
+
150
+ assert_equal @instance.name, unserialized.name
151
+ assert_equal @instance.age, unserialized.age
152
+ assert ! unserialized.awesome
153
+ assert_nil unserialized.created_at
154
+ end
155
+
156
+ should "allow attribute except filtering" do
157
+ serialized = @instance.send("to_#{format}", :except => [ :age, :name ])
158
+ unserialized = @document.send("from_#{format}", serialized)
159
+
160
+ assert_nil unserialized.name
161
+ assert_nil unserialized.age
162
+ assert_equal @instance.awesome, unserialized.awesome
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,44 @@
1
+ require 'test_helper'
2
+
3
+ class TimeZonesTest < Test::Unit::TestCase
4
+ context "An instance of an embedded document" do
5
+ setup do
6
+ @document = EDoc do
7
+ key :name, String
8
+ key :created_at, Time
9
+ end
10
+ end
11
+
12
+ should "preserve milliseconds" do
13
+ doc = @document.new(:created_at => '2011-02-12 16:01:02.543Z')
14
+ doc.created_at.should be_close(Time.parse('2011-02-12 16:01:02.543Z'), 0.0000001)
15
+ end
16
+
17
+ should "work without Time.zone" do
18
+ Time.zone = nil
19
+
20
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
21
+ doc.created_at.should == Time.local(2009, 8, 15, 14, 0, 0).utc
22
+ end
23
+
24
+ should "work with Time.zone set to the (default) UTC" do
25
+ Time.zone = 'UTC'
26
+
27
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
28
+ doc.created_at.is_a?(ActiveSupport::TimeWithZone).should be_true
29
+ doc.created_at.should == Time.utc(2009, 8, 15, 14)
30
+
31
+ Time.zone = nil
32
+ end
33
+
34
+ should "work with timezones that are not UTC" do
35
+ Time.zone = 'Hawaii'
36
+
37
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
38
+ doc.created_at.is_a?(ActiveSupport::TimeWithZone).should be_true
39
+ doc.created_at.should == Time.utc(2009, 8, 16)
40
+
41
+ Time.zone = nil
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class TranslationTest < Test::Unit::TestCase
4
+ should "translate add mongo_mapper translations" do
5
+ I18n.translate("mongo_mapper.errors.messages.taken").should == "has already been taken"
6
+ end
7
+
8
+ should "set i18n_scope" do
9
+ Doc().i18n_scope.should == :mongo_mapper
10
+ end
11
+
12
+ should "translate document attributes" do
13
+ I18n.config.backend.store_translations(:en, :mongo_mapper => {:attributes => {:thing => {:foo => 'Bar'}}})
14
+ doc = Doc('Thing') do
15
+ key :foo, String
16
+ end
17
+ doc.human_attribute_name(:foo).should == 'Bar'
18
+ end
19
+
20
+ should "translate embedded document attributes" do
21
+ I18n.config.backend.store_translations(:en, :mongo_mapper => {:attributes => {:thing => {:foo => 'Bar'}}})
22
+ doc = EDoc('Thing') do
23
+ key :foo, String
24
+ end
25
+ doc.human_attribute_name(:foo).should == 'Bar'
26
+ end
27
+ end
@@ -0,0 +1,562 @@
1
+ require 'test_helper'
2
+
3
+ class ValidationsTest < Test::Unit::TestCase
4
+ context "Validations" do
5
+ context "on a Document" do
6
+ setup do
7
+ @document = Doc('John')
8
+ end
9
+
10
+ context "Validating acceptance of" do
11
+ should "work with validates_acceptance_of macro" do
12
+ @document.key :terms, String
13
+ @document.validates_acceptance_of :terms
14
+ doc = @document.new(:terms => '')
15
+ doc.should have_error_on(:terms)
16
+ doc.terms = '1'
17
+ doc.should_not have_error_on(:terms)
18
+ end
19
+ end
20
+
21
+ context "validating confirmation of" do
22
+ should "work with validates_confirmation_of macro" do
23
+ @document.key :password, String
24
+ @document.validates_confirmation_of :password
25
+
26
+ # NOTE: Api change as ActiveModel passes if password_confirmation is nil
27
+ doc = @document.new
28
+ doc.password = 'foobar'
29
+ doc.password_confirmation = 'foobar1'
30
+ doc.should have_error_on(:password)
31
+
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, :in => %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 "work with :not_in shortcut on key definition" do
184
+ @document.key :action, String, :not_in => %w(kick run)
185
+
186
+ doc = @document.new
187
+ doc.should_not have_error_on(:action)
188
+
189
+ doc.action = 'fart'
190
+ doc.should_not have_error_on(:action)
191
+
192
+ doc.action = 'kick'
193
+ doc.should have_error_on(:action, 'is reserved')
194
+ end
195
+
196
+ should "not have error if allow nil is true and value is nil" do
197
+ @document.key :action, String
198
+ @document.validates_exclusion_of :action, :in => %w(kick run), :allow_nil => true
199
+
200
+ doc = @document.new
201
+ doc.should_not have_error_on(:action)
202
+ end
203
+
204
+ should "not have error if allow blank is true and value is blank" do
205
+ @document.key :action, String
206
+ @document.validates_exclusion_of :action, :in => %w(kick run), :allow_nil => true
207
+
208
+ doc = @document.new(:action => '')
209
+ doc.should_not have_error_on(:action)
210
+ end
211
+ end
212
+
213
+ context "validating inclusion of" do
214
+ should "throw error if enumerator not provided" do
215
+ @document.key :action, String
216
+ lambda {
217
+ @document.validates_inclusion_of :action
218
+ }.should raise_error(ArgumentError)
219
+ end
220
+
221
+ should "work with validates_inclusion_of macro" do
222
+ @document.key :action, String
223
+ @document.validates_inclusion_of :action, :in => %w(kick run)
224
+
225
+ doc = @document.new
226
+ doc.should have_error_on(:action, 'is not included in the list')
227
+
228
+ doc.action = 'fart'
229
+ doc.should have_error_on(:action, 'is not included in the list')
230
+
231
+ doc.action = 'kick'
232
+ doc.should_not have_error_on(:action)
233
+ end
234
+
235
+ should "work with :in shortcut on key definition" do
236
+ @document.key :action, String, :in => %w(kick run)
237
+
238
+ doc = @document.new
239
+ doc.should have_error_on(:action, 'is not included in the list')
240
+
241
+ doc.action = 'fart'
242
+ doc.should have_error_on(:action, 'is not included in the list')
243
+
244
+ doc.action = 'kick'
245
+ doc.should_not have_error_on(:action)
246
+ end
247
+
248
+ should "work with :required shortcut on Boolean type" do
249
+ @document.key :flag, Boolean, :required => true
250
+
251
+ doc = @document.new
252
+ doc.should have_error_on(:flag, 'is not included in the list')
253
+
254
+ doc.flag = true
255
+ doc.should_not have_error_on(:action)
256
+
257
+ doc.flag = false
258
+ doc.should_not have_error_on(:action)
259
+ end
260
+
261
+ should "not have error if allow nil is true and value is nil" do
262
+ @document.key :action, String
263
+ @document.validates_inclusion_of :action, :in => %w(kick run), :allow_nil => true
264
+
265
+ doc = @document.new
266
+ doc.should_not have_error_on(:action)
267
+ end
268
+
269
+ should "not have error if allow blank is true and value is blank" do
270
+ @document.key :action, String
271
+ @document.validates_inclusion_of :action, :in => %w(kick run), :allow_blank => true
272
+
273
+ doc = @document.new(:action => '')
274
+ doc.should_not have_error_on(:action)
275
+ end
276
+ end
277
+
278
+ end # End on a Document
279
+
280
+ context "On an EmbeddedDocument" do
281
+ setup do
282
+ @embedded_doc = EDoc()
283
+ end
284
+
285
+ context "Validating acceptance of" do
286
+ should "work with validates_acceptance_of macro" do
287
+ @embedded_doc.key :terms, String
288
+ @embedded_doc.validates_acceptance_of :terms
289
+ doc = @embedded_doc.new(:terms => '')
290
+ doc.should have_error_on(:terms)
291
+ doc.terms = '1'
292
+ doc.should_not have_error_on(:terms)
293
+ end
294
+ end
295
+
296
+ context "validating confirmation of" do
297
+ should "work with validates_confirmation_of macro" do
298
+ @embedded_doc.key :password, String
299
+ @embedded_doc.validates_confirmation_of :password
300
+ doc = @embedded_doc.new
301
+ doc.password = 'foobar'
302
+ doc.password_confirmation = 'foobar1'
303
+ doc.should have_error_on(:password)
304
+ doc.password_confirmation = 'foobar'
305
+ doc.should_not have_error_on(:password)
306
+ end
307
+ end
308
+
309
+ context "validating format of" do
310
+ should "work with validates_format_of macro" do
311
+ @embedded_doc.key :name, String
312
+ @embedded_doc.validates_format_of :name, :with => /.+/
313
+ doc = @embedded_doc.new
314
+ doc.should have_error_on(:name)
315
+ doc.name = 'John'
316
+ doc.should_not have_error_on(:name)
317
+ end
318
+
319
+ should "work with :format shorcut key" do
320
+ @embedded_doc.key :name, String, :format => /.+/
321
+ doc = @embedded_doc.new
322
+ doc.should have_error_on(:name)
323
+ doc.name = 'John'
324
+ doc.should_not have_error_on(:name)
325
+ end
326
+ end
327
+
328
+ context "validating length of" do
329
+ should "work with validates_length_of macro" do
330
+ @embedded_doc.key :name, String
331
+ @embedded_doc.validates_length_of :name, :minimum => 5
332
+ doc = @embedded_doc.new
333
+ doc.should have_error_on(:name)
334
+ end
335
+
336
+ context "with :length => integer shortcut" do
337
+ should "set maximum of integer provided" do
338
+ @embedded_doc.key :name, String, :length => 5
339
+ doc = @embedded_doc.new
340
+ doc.name = '123456'
341
+ doc.should have_error_on(:name)
342
+ doc.name = '12345'
343
+ doc.should_not have_error_on(:name)
344
+ end
345
+ end
346
+
347
+ context "with :length => range shortcut" do
348
+ setup do
349
+ @embedded_doc.key :name, String, :length => 5..7
350
+ end
351
+
352
+ should "set minimum of range min" do
353
+ doc = @embedded_doc.new
354
+ doc.should have_error_on(:name)
355
+ doc.name = '123456'
356
+ doc.should_not have_error_on(:name)
357
+ end
358
+
359
+ should "set maximum of range max" do
360
+ doc = @embedded_doc.new
361
+ doc.should have_error_on(:name)
362
+ doc.name = '12345678'
363
+ doc.should have_error_on(:name)
364
+ doc.name = '123456'
365
+ doc.should_not have_error_on(:name)
366
+ end
367
+ end
368
+
369
+ context "with :length => hash shortcut" do
370
+ should "pass options through" do
371
+ @embedded_doc.key :name, String, :length => {:minimum => 2}
372
+ doc = @embedded_doc.new
373
+ doc.should have_error_on(:name)
374
+ doc.name = '12'
375
+ doc.should_not have_error_on(:name)
376
+ end
377
+ end
378
+ end # validates_length_of
379
+
380
+ context "Validating numericality of" do
381
+ should "work with validates_numericality_of macro" do
382
+ @embedded_doc.key :age, Integer
383
+ @embedded_doc.validates_numericality_of :age
384
+ doc = @embedded_doc.new
385
+ doc.age = 'String'
386
+ doc.should have_error_on(:age)
387
+ doc.age = 23
388
+ doc.should_not have_error_on(:age)
389
+ end
390
+
391
+ context "with :numeric shortcut" do
392
+ should "work with integer or float" do
393
+ @embedded_doc.key :weight, Float, :numeric => true
394
+ doc = @embedded_doc.new
395
+ doc.weight = 'String'
396
+ doc.should have_error_on(:weight)
397
+ doc.weight = 23.0
398
+ doc.should_not have_error_on(:weight)
399
+ doc.weight = 23
400
+ doc.should_not have_error_on(:weight)
401
+ end
402
+ end
403
+
404
+ context "with :numeric shortcut on Integer key" do
405
+ should "only work with integers" do
406
+ @embedded_doc.key :age, Integer, :numeric => true
407
+ doc = @embedded_doc.new
408
+ doc.age = 'String'
409
+ doc.should have_error_on(:age)
410
+ doc.age = 23.1
411
+ doc.should have_error_on(:age)
412
+ doc.age = 23
413
+ doc.should_not have_error_on(:age)
414
+ end
415
+ end
416
+ end # numericality of
417
+
418
+ context "validating presence of" do
419
+ should "work with validates_presence_of macro" do
420
+ @embedded_doc.key :name, String
421
+ @embedded_doc.validates_presence_of :name
422
+ doc = @embedded_doc.new
423
+ doc.should have_error_on(:name)
424
+ end
425
+
426
+ should "work with :required shortcut on key definition" do
427
+ @embedded_doc.key :name, String, :required => true
428
+ doc = @embedded_doc.new
429
+ doc.should have_error_on(:name)
430
+ end
431
+ end
432
+
433
+ context "validating exclusion of" do
434
+ should "throw error if enumerator not provided" do
435
+ @embedded_doc.key :action, String
436
+ lambda {
437
+ @embedded_doc.validates_exclusion_of :action
438
+ }.should raise_error(ArgumentError)
439
+ end
440
+
441
+ should "work with validates_exclusion_of macro" do
442
+ @embedded_doc.key :action, String
443
+ @embedded_doc.validates_exclusion_of :action, :in => %w(kick run)
444
+
445
+ doc = @embedded_doc.new
446
+ doc.should_not have_error_on(:action)
447
+
448
+ doc.action = 'fart'
449
+ doc.should_not have_error_on(:action)
450
+
451
+ doc.action = 'kick'
452
+ doc.should have_error_on(:action, 'is reserved')
453
+ end
454
+
455
+ should "work with :not_in shortcut on key definition" do
456
+ @embedded_doc.key :action, String, :not_in => %w(kick run)
457
+
458
+ doc = @embedded_doc.new
459
+ doc.should_not have_error_on(:action)
460
+
461
+ doc.action = 'fart'
462
+ doc.should_not have_error_on(:action)
463
+
464
+ doc.action = 'kick'
465
+ doc.should have_error_on(:action, 'is reserved')
466
+ end
467
+
468
+ should "not have error if allow nil is true and value is nil" do
469
+ @embedded_doc.key :action, String
470
+ @embedded_doc.validates_exclusion_of :action, :in => %w(kick run), :allow_nil => true
471
+
472
+ doc = @embedded_doc.new
473
+ doc.should_not have_error_on(:action)
474
+ end
475
+
476
+ should "not have error if allow blank is true and value is blank" do
477
+ @embedded_doc.key :action, String
478
+ @embedded_doc.validates_exclusion_of :action, :in => %w(kick run), :allow_nil => true
479
+
480
+ doc = @embedded_doc.new(:action => '')
481
+ doc.should_not have_error_on(:action)
482
+ end
483
+ end
484
+
485
+ context "validating inclusion of" do
486
+ should "throw error if enumerator not provided" do
487
+ @embedded_doc.key :action, String
488
+ lambda {
489
+ @embedded_doc.validates_inclusion_of :action
490
+ }.should raise_error(ArgumentError)
491
+ end
492
+
493
+ should "work with validates_inclusion_of macro" do
494
+ @embedded_doc.key :action, String
495
+ @embedded_doc.validates_inclusion_of :action, :in => %w(kick run)
496
+
497
+ doc = @embedded_doc.new
498
+ doc.should have_error_on(:action, 'is not included in the list')
499
+
500
+ doc.action = 'fart'
501
+ doc.should have_error_on(:action, 'is not included in the list')
502
+
503
+ doc.action = 'kick'
504
+ doc.should_not have_error_on(:action)
505
+ end
506
+
507
+ should "work with :in shortcut on key definition" do
508
+ @embedded_doc.key :action, String, :in => %w(kick run)
509
+
510
+ doc = @embedded_doc.new
511
+ doc.should have_error_on(:action, 'is not included in the list')
512
+
513
+ doc.action = 'fart'
514
+ doc.should have_error_on(:action, 'is not included in the list')
515
+
516
+ doc.action = 'kick'
517
+ doc.should_not have_error_on(:action)
518
+ end
519
+
520
+ should "not have error if allow nil is true and value is nil" do
521
+ @embedded_doc.key :action, String
522
+ @embedded_doc.validates_inclusion_of :action, :in => %w(kick run), :allow_nil => true
523
+
524
+ doc = @embedded_doc.new
525
+ doc.should_not have_error_on(:action)
526
+ end
527
+
528
+ should "not have error if allow blank is true and value is blank" do
529
+ @embedded_doc.key :action, String
530
+ @embedded_doc.validates_inclusion_of :action, :in => %w(kick run), :allow_blank => true
531
+
532
+ doc = @embedded_doc.new(:action => '')
533
+ doc.should_not have_error_on(:action)
534
+ end
535
+ end
536
+
537
+ end # End on an EmbeddedDocument
538
+
539
+ end # Validations
540
+
541
+ context "Adding validation errors" do
542
+ setup do
543
+ @document = Doc do
544
+ key :action, String
545
+ def action_present
546
+ errors.add(:action, 'is invalid') if action.blank?
547
+ end
548
+ end
549
+ end
550
+
551
+ should "work with validate callback" do
552
+ @document.validate :action_present
553
+
554
+ doc = @document.new
555
+ doc.action = nil
556
+ doc.should have_error_on(:action)
557
+
558
+ doc.action = 'kick'
559
+ doc.should_not have_error_on(:action)
560
+ end
561
+ end
562
+ end