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.
- data/LICENSE +20 -0
- data/README.rdoc +33 -0
- data/UPGRADES +26 -0
- data/bin/mmconsole +59 -0
- data/examples/attr_accessible.rb +22 -0
- data/examples/attr_protected.rb +22 -0
- data/examples/cache_key.rb +24 -0
- data/examples/custom_types.rb +24 -0
- data/examples/identity_map.rb +33 -0
- data/examples/identity_map/automatic.rb +2 -0
- data/examples/keys.rb +40 -0
- data/examples/modifiers/set.rb +25 -0
- data/examples/plugins.rb +38 -0
- data/examples/querying.rb +35 -0
- data/examples/safe.rb +43 -0
- data/examples/scopes.rb +52 -0
- data/examples/validating/embedded_docs.rb +29 -0
- data/lib/mongo_mapper.rb +94 -0
- data/lib/mongo_mapper/connection.rb +96 -0
- data/lib/mongo_mapper/document.rb +42 -0
- data/lib/mongo_mapper/embedded_document.rb +32 -0
- data/lib/mongo_mapper/exceptions.rb +30 -0
- data/lib/mongo_mapper/extensions/array.rb +19 -0
- data/lib/mongo_mapper/extensions/binary.rb +22 -0
- data/lib/mongo_mapper/extensions/boolean.rb +44 -0
- data/lib/mongo_mapper/extensions/date.rb +25 -0
- data/lib/mongo_mapper/extensions/float.rb +14 -0
- data/lib/mongo_mapper/extensions/hash.rb +14 -0
- data/lib/mongo_mapper/extensions/integer.rb +19 -0
- data/lib/mongo_mapper/extensions/kernel.rb +9 -0
- data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
- data/lib/mongo_mapper/extensions/object.rb +26 -0
- data/lib/mongo_mapper/extensions/object_id.rb +32 -0
- data/lib/mongo_mapper/extensions/set.rb +20 -0
- data/lib/mongo_mapper/extensions/string.rb +18 -0
- data/lib/mongo_mapper/extensions/time.rb +28 -0
- data/lib/mongo_mapper/locale/en.yml +5 -0
- data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
- data/lib/mongo_mapper/plugins.rb +22 -0
- data/lib/mongo_mapper/plugins/accessible.rb +52 -0
- data/lib/mongo_mapper/plugins/active_model.rb +18 -0
- data/lib/mongo_mapper/plugins/associations.rb +90 -0
- data/lib/mongo_mapper/plugins/associations/base.rb +92 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +54 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +34 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
- data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +44 -0
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +133 -0
- data/lib/mongo_mapper/plugins/associations/many_association.rb +63 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +118 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
- data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +22 -0
- data/lib/mongo_mapper/plugins/associations/one_association.rb +48 -0
- data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
- data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +95 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +134 -0
- data/lib/mongo_mapper/plugins/associations/single_association.rb +46 -0
- data/lib/mongo_mapper/plugins/caching.rb +21 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +29 -0
- data/lib/mongo_mapper/plugins/clone.rb +22 -0
- data/lib/mongo_mapper/plugins/dirty.rb +60 -0
- data/lib/mongo_mapper/plugins/document.rb +41 -0
- data/lib/mongo_mapper/plugins/dynamic_querying.rb +45 -0
- data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
- data/lib/mongo_mapper/plugins/embedded_callbacks.rb +56 -0
- data/lib/mongo_mapper/plugins/embedded_document.rb +53 -0
- data/lib/mongo_mapper/plugins/equality.rb +23 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
- data/lib/mongo_mapper/plugins/indexes.rb +13 -0
- data/lib/mongo_mapper/plugins/inspect.rb +16 -0
- data/lib/mongo_mapper/plugins/keys.rb +313 -0
- data/lib/mongo_mapper/plugins/keys/key.rb +61 -0
- data/lib/mongo_mapper/plugins/logger.rb +18 -0
- data/lib/mongo_mapper/plugins/modifiers.rb +134 -0
- data/lib/mongo_mapper/plugins/pagination.rb +16 -0
- data/lib/mongo_mapper/plugins/persistence.rb +69 -0
- data/lib/mongo_mapper/plugins/protected.rb +45 -0
- data/lib/mongo_mapper/plugins/querying.rb +165 -0
- data/lib/mongo_mapper/plugins/querying/decorator.rb +36 -0
- data/lib/mongo_mapper/plugins/rails.rb +58 -0
- data/lib/mongo_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
- data/lib/mongo_mapper/plugins/safe.rb +28 -0
- data/lib/mongo_mapper/plugins/sci.rb +36 -0
- data/lib/mongo_mapper/plugins/scopes.rb +27 -0
- data/lib/mongo_mapper/plugins/serialization.rb +109 -0
- data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
- data/lib/mongo_mapper/plugins/touch.rb +18 -0
- data/lib/mongo_mapper/plugins/userstamps.rb +18 -0
- data/lib/mongo_mapper/plugins/validations.rb +86 -0
- data/lib/mongo_mapper/railtie.rb +48 -0
- data/lib/mongo_mapper/railtie/database.rake +65 -0
- data/lib/mongo_mapper/translation.rb +10 -0
- data/lib/mongo_mapper/version.rb +4 -0
- data/lib/rails/generators/mongo_mapper/config/config_generator.rb +24 -0
- data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +18 -0
- data/lib/rails/generators/mongo_mapper/model/model_generator.rb +23 -0
- data/lib/rails/generators/mongo_mapper/model/templates/model.rb +13 -0
- data/test/_NOTE_ON_TESTING +1 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +238 -0
- data/test/functional/associations/test_in_array_proxy.rb +349 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +231 -0
- data/test/functional/associations/test_many_documents_proxy.rb +866 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +239 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +289 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +303 -0
- data/test/functional/associations/test_one_as_proxy.rb +491 -0
- data/test/functional/associations/test_one_embedded_polymorphic_proxy.rb +208 -0
- data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
- data/test/functional/associations/test_one_proxy.rb +383 -0
- data/test/functional/test_accessible.rb +198 -0
- data/test/functional/test_associations.rb +46 -0
- data/test/functional/test_binary.rb +27 -0
- data/test/functional/test_caching.rb +77 -0
- data/test/functional/test_callbacks.rb +232 -0
- data/test/functional/test_dirty.rb +301 -0
- data/test/functional/test_document.rb +282 -0
- data/test/functional/test_dynamic_querying.rb +75 -0
- data/test/functional/test_embedded_document.rb +288 -0
- data/test/functional/test_equality.rb +20 -0
- data/test/functional/test_identity_map.rb +513 -0
- data/test/functional/test_indexes.rb +50 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_modifiers.rb +537 -0
- data/test/functional/test_pagination.rb +91 -0
- data/test/functional/test_protected.rb +201 -0
- data/test/functional/test_querying.rb +935 -0
- data/test/functional/test_safe.rb +76 -0
- data/test/functional/test_sci.rb +240 -0
- data/test/functional/test_scopes.rb +171 -0
- data/test/functional/test_timestamps.rb +62 -0
- data/test/functional/test_touch.rb +125 -0
- data/test/functional/test_userstamps.rb +44 -0
- data/test/functional/test_validations.rb +414 -0
- data/test/models.rb +261 -0
- data/test/support/railtie.rb +4 -0
- data/test/support/railtie/autoloaded.rb +2 -0
- data/test/support/railtie/not_autoloaded.rb +3 -0
- data/test/support/railtie/parent.rb +3 -0
- data/test/test_active_model_lint.rb +18 -0
- data/test/test_helper.rb +93 -0
- data/test/unit/associations/test_base.rb +146 -0
- data/test/unit/associations/test_belongs_to_association.rb +29 -0
- data/test/unit/associations/test_many_association.rb +63 -0
- data/test/unit/associations/test_one_association.rb +47 -0
- data/test/unit/associations/test_proxy.rb +100 -0
- data/test/unit/serializers/test_json_serializer.rb +216 -0
- data/test/unit/serializers/test_xml_serializer.rb +196 -0
- data/test/unit/test_clone.rb +69 -0
- data/test/unit/test_document.rb +249 -0
- data/test/unit/test_dynamic_finder.rb +125 -0
- data/test/unit/test_embedded_document.rb +682 -0
- data/test/unit/test_equality.rb +38 -0
- data/test/unit/test_exceptions.rb +12 -0
- data/test/unit/test_extensions.rb +380 -0
- data/test/unit/test_identity_map_middleware.rb +34 -0
- data/test/unit/test_inspect.rb +47 -0
- data/test/unit/test_key.rb +205 -0
- data/test/unit/test_keys.rb +65 -0
- data/test/unit/test_mongo_mapper.rb +143 -0
- data/test/unit/test_pagination.rb +11 -0
- data/test/unit/test_plugins.rb +89 -0
- data/test/unit/test_rails.rb +183 -0
- data/test/unit/test_rails_compatibility.rb +38 -0
- data/test/unit/test_rails_reflect_on_association.rb +118 -0
- data/test/unit/test_railtie.rb +66 -0
- data/test/unit/test_serialization.rb +166 -0
- data/test/unit/test_time_zones.rb +44 -0
- data/test/unit/test_translation.rb +27 -0
- data/test/unit/test_validations.rb +562 -0
- metadata +285 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class AccessibleTest < Test::Unit::TestCase
|
|
4
|
+
context 'A document with accessible attributes' do
|
|
5
|
+
setup do
|
|
6
|
+
@doc_class = Doc do
|
|
7
|
+
key :name, String
|
|
8
|
+
key :admin, Boolean, :default => false
|
|
9
|
+
|
|
10
|
+
attr_accessible :name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
@doc = @doc_class.create(:name => 'Steve Sloan')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
should 'have accessible attributes class method' do
|
|
17
|
+
@doc_class.accessible_attributes.should == [:name].to_set
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
should "default accessible attributes to nil" do
|
|
21
|
+
Doc().accessible_attributes.should be_nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
should "have accessible_attributes instance method" do
|
|
25
|
+
@doc.accessible_attributes.should equal(@doc_class.accessible_attributes)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
should "raise error if there are protected attributes" do
|
|
29
|
+
doc = Doc('Post')
|
|
30
|
+
doc.attr_protected :admin
|
|
31
|
+
lambda { doc.attr_accessible :name }.
|
|
32
|
+
should raise_error(/Declare either attr_protected or attr_accessible for Post/)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
should "know if using accessible attributes" do
|
|
36
|
+
@doc_class.accessible_attributes?.should be(true)
|
|
37
|
+
Doc().accessible_attributes?.should be(false)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
should "assign inaccessible attribute through accessor" do
|
|
41
|
+
@doc.admin = true
|
|
42
|
+
@doc.admin.should be_true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
should "ignore inaccessible attribute on #initialize" do
|
|
46
|
+
doc = @doc_class.new(:name => 'John', :admin => true)
|
|
47
|
+
doc.admin.should be_false
|
|
48
|
+
doc.name.should == 'John'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
should "not ignore inaccessible attributes on #initialize from the database" do
|
|
52
|
+
doc = @doc_class.new(:name => 'John')
|
|
53
|
+
doc.admin = true
|
|
54
|
+
doc.save!
|
|
55
|
+
|
|
56
|
+
doc = @doc_class.first(:name => 'John')
|
|
57
|
+
doc.admin.should be_true
|
|
58
|
+
doc.name.should == 'John'
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
should "not ignore inaccessible attributes on #reload" do
|
|
62
|
+
doc = @doc_class.new(:name => 'John')
|
|
63
|
+
doc.admin = true
|
|
64
|
+
doc.save!
|
|
65
|
+
|
|
66
|
+
doc.reload
|
|
67
|
+
doc.admin.should be_true
|
|
68
|
+
doc.name.should == 'John'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
should "not ignore inaccessible attribute on #update_attribute" do
|
|
72
|
+
@doc.update_attribute('admin', true)
|
|
73
|
+
@doc.admin.should be_true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
should "ignore inaccessible attribute on #update_attributes" do
|
|
77
|
+
@doc.update_attributes(:name => 'Ren Hoek', :admin => true)
|
|
78
|
+
@doc.name.should == 'Ren Hoek'
|
|
79
|
+
@doc.admin.should be_false
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
should "ignore inaccessible attribute on #update_attributes!" do
|
|
83
|
+
@doc.update_attributes!(:name => 'Stimpson J. Cat', :admin => true)
|
|
84
|
+
@doc.name.should == 'Stimpson J. Cat'
|
|
85
|
+
@doc.admin.should be_false
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
should "ignore inaccessible attribute on #attributes=" do
|
|
89
|
+
@doc.attributes = {:name => 'Ren Hoek', :admin => true}
|
|
90
|
+
@doc.name.should == 'Ren Hoek'
|
|
91
|
+
@doc.admin.should be_false
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
should "be indifferent to whether the accessible keys are strings or symbols" do
|
|
95
|
+
@doc.update_attributes!("name" => 'Stimpson J. Cat', "admin" => true)
|
|
96
|
+
@doc.name.should == 'Stimpson J. Cat'
|
|
97
|
+
@doc.admin.should be_false
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
should "accept nil as constructor's argument without raising exception" do
|
|
101
|
+
lambda { @doc_class.new(nil) }.should_not raise_error
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
should "ignore all attributes if called with no args" do
|
|
105
|
+
@doc_class = Doc do
|
|
106
|
+
key :name
|
|
107
|
+
attr_accessible
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
@doc_class.new(:name => 'Steve Sloan').name.should be_nil
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context "Single collection inherited accessible attributes" do
|
|
115
|
+
setup do
|
|
116
|
+
class ::GrandParent
|
|
117
|
+
include MongoMapper::Document
|
|
118
|
+
attr_accessible :name
|
|
119
|
+
key :name, String
|
|
120
|
+
key :site_id, ObjectId
|
|
121
|
+
end
|
|
122
|
+
GrandParent.collection.remove
|
|
123
|
+
|
|
124
|
+
class ::Child < ::GrandParent
|
|
125
|
+
attr_accessible :position
|
|
126
|
+
key :position, Integer
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
class ::GrandChild < ::Child; end
|
|
130
|
+
|
|
131
|
+
class ::OtherChild < ::GrandParent
|
|
132
|
+
attr_accessible :favorite_color
|
|
133
|
+
key :favorite_color, String
|
|
134
|
+
key :blog_id, ObjectId
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
teardown do
|
|
139
|
+
Object.send :remove_const, 'GrandParent' if defined?(::GrandParent)
|
|
140
|
+
Object.send :remove_const, 'Child' if defined?(::Child)
|
|
141
|
+
Object.send :remove_const, 'GrandChild' if defined?(::GrandChild)
|
|
142
|
+
Object.send :remove_const, 'OtherChild' if defined?(::OtherChild)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
should "share keys down the inheritance trail" do
|
|
146
|
+
GrandParent.accessible_attributes.should == [:name].to_set
|
|
147
|
+
Child.accessible_attributes.should == [:name, :position].to_set
|
|
148
|
+
GrandChild.accessible_attributes.should == [:name, :position].to_set
|
|
149
|
+
OtherChild.accessible_attributes.should == [:name, :favorite_color].to_set
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context "An embedded document with accessible attributes" do
|
|
154
|
+
setup do
|
|
155
|
+
@doc_class = Doc('Project')
|
|
156
|
+
@edoc_class = EDoc('Person') do
|
|
157
|
+
key :name, String
|
|
158
|
+
key :admin, Boolean, :default => false
|
|
159
|
+
|
|
160
|
+
attr_accessible :name
|
|
161
|
+
end
|
|
162
|
+
@doc_class.many :people, :class => @edoc_class
|
|
163
|
+
|
|
164
|
+
@doc = @doc_class.create(:title => 'MongoMapper')
|
|
165
|
+
@edoc = @edoc_class.new(:name => 'Steve Sloan')
|
|
166
|
+
@doc.people << @edoc
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
should "have accessible attributes class method" do
|
|
170
|
+
@edoc_class.accessible_attributes.should == [:name].to_set
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
should "default accessible attributes to nil" do
|
|
174
|
+
EDoc().accessible_attributes.should be_nil
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
should "have accessible attributes instance method" do
|
|
178
|
+
@edoc.accessible_attributes.should equal(@edoc_class.accessible_attributes)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
should "assign inaccessible attribute through accessor" do
|
|
182
|
+
@edoc.admin = true
|
|
183
|
+
@edoc.admin.should be_true
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
should "ignore inaccessible attribute on #update_attributes" do
|
|
187
|
+
@edoc.update_attributes(:name => 'Ren Hoek', :admin => true)
|
|
188
|
+
@edoc.name.should == 'Ren Hoek'
|
|
189
|
+
@edoc.admin.should be_false
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
should "ignore inaccessible attribute on #update_attributes!" do
|
|
193
|
+
@edoc.update_attributes!(:name => 'Stimpson J. Cat', :admin => true)
|
|
194
|
+
@edoc.name.should == 'Stimpson J. Cat'
|
|
195
|
+
@edoc.admin.should be_false
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'models'
|
|
3
|
+
|
|
4
|
+
class AssociationsTest < Test::Unit::TestCase
|
|
5
|
+
should "allow changing class names" do
|
|
6
|
+
class AwesomeUser
|
|
7
|
+
include MongoMapper::Document
|
|
8
|
+
|
|
9
|
+
many :posts, :class_name => 'AssociationsTest::AwesomePost', :foreign_key => :creator_id
|
|
10
|
+
end
|
|
11
|
+
AwesomeUser.collection.remove
|
|
12
|
+
|
|
13
|
+
class AwesomeTag
|
|
14
|
+
include MongoMapper::EmbeddedDocument
|
|
15
|
+
|
|
16
|
+
key :name, String
|
|
17
|
+
key :post_id, ObjectId
|
|
18
|
+
|
|
19
|
+
belongs_to :post, :class_name => 'AssociationsTest::AwesomeUser'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class AwesomePost
|
|
23
|
+
include MongoMapper::Document
|
|
24
|
+
|
|
25
|
+
key :creator_id, ObjectId
|
|
26
|
+
|
|
27
|
+
belongs_to :creator, :class_name => 'AssociationsTest::AwesomeUser'
|
|
28
|
+
many :tags, :class_name => 'AssociationsTest::AwesomeTag', :foreign_key => :post_id
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
AwesomeUser.collection.remove
|
|
32
|
+
AwesomePost.collection.remove
|
|
33
|
+
|
|
34
|
+
user = AwesomeUser.create
|
|
35
|
+
tag1 = AwesomeTag.new(:name => 'awesome')
|
|
36
|
+
tag2 = AwesomeTag.new(:name => 'grand')
|
|
37
|
+
post1 = AwesomePost.create(:creator => user, :tags => [tag1])
|
|
38
|
+
post2 = AwesomePost.create(:creator => user, :tags => [tag2])
|
|
39
|
+
|
|
40
|
+
user.reload
|
|
41
|
+
user.posts.should == [post1, post2]
|
|
42
|
+
|
|
43
|
+
post1 = post1.reload
|
|
44
|
+
post1.tags.should == [tag1]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class BinaryTest < Test::Unit::TestCase
|
|
4
|
+
should "serialize and deserialize correctly" do
|
|
5
|
+
klass = Doc do
|
|
6
|
+
key :contents, Binary
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
doc = klass.new(:contents => '010101')
|
|
10
|
+
doc.save
|
|
11
|
+
|
|
12
|
+
doc = doc.reload
|
|
13
|
+
doc.contents.to_s.should == BSON::Binary.new('010101').to_s
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context "Saving a document with a blank binary value" do
|
|
17
|
+
setup do
|
|
18
|
+
@document = Doc do
|
|
19
|
+
key :file, Binary
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
should "not fail" do
|
|
24
|
+
assert_nothing_raised { @document.new(:file => nil).save }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class CachingTest < Test::Unit::TestCase
|
|
4
|
+
context "Caching" do
|
|
5
|
+
setup do
|
|
6
|
+
@klass = Class.new do
|
|
7
|
+
extend MongoMapper::Plugins
|
|
8
|
+
plugin MongoMapper::Plugins::Caching
|
|
9
|
+
end
|
|
10
|
+
@klass.stubs(:name).returns('Post')
|
|
11
|
+
@klass.any_instance.stubs(:persisted?).returns(true)
|
|
12
|
+
@klass.any_instance.stubs(:[]).returns(nil)
|
|
13
|
+
@klass.any_instance.stubs(:[]=).returns(nil)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context "new" do
|
|
17
|
+
setup do
|
|
18
|
+
@doc = @klass.new
|
|
19
|
+
@doc.stubs(:persisted?).returns(false)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should "be class/new" do
|
|
23
|
+
@doc.cache_key.should == 'Post/new'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
should "work with suffix" do
|
|
27
|
+
@doc.cache_key(:foo).
|
|
28
|
+
should == 'Post/new/foo'
|
|
29
|
+
|
|
30
|
+
@doc.cache_key(:foo, :bar).
|
|
31
|
+
should == 'Post/new/foo/bar'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "not new" do
|
|
36
|
+
setup do
|
|
37
|
+
@object_id = BSON::ObjectId.new
|
|
38
|
+
@doc = @klass.new
|
|
39
|
+
@doc.stubs(:persisted).returns(true)
|
|
40
|
+
@doc.stubs(:id).returns(@object_id)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "with updated_at" do
|
|
44
|
+
setup do
|
|
45
|
+
time = Time.utc(2010, 6, 20, 8, 10, 7)
|
|
46
|
+
@doc.stubs(:[]).with(:updated_at).returns(time)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
should "be class/id-timestamp" do
|
|
50
|
+
@doc.cache_key.should == "Post/#{@object_id}-20100620081007"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
should "work with suffix" do
|
|
54
|
+
@doc.cache_key(:foo).
|
|
55
|
+
should == "Post/#{@object_id}-20100620081007/foo"
|
|
56
|
+
|
|
57
|
+
@doc.cache_key(:foo, :bar).
|
|
58
|
+
should == "Post/#{@object_id}-20100620081007/foo/bar"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "without updated_at" do
|
|
63
|
+
should "be class/id" do
|
|
64
|
+
@doc.cache_key.should == "Post/#{@object_id}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
should "work with suffix" do
|
|
68
|
+
@doc.cache_key(:foo).
|
|
69
|
+
should == "Post/#{@object_id}/foo"
|
|
70
|
+
|
|
71
|
+
@doc.cache_key(:foo, :bar, :baz).
|
|
72
|
+
should == "Post/#{@object_id}/foo/bar/baz"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module CallbacksSupport
|
|
4
|
+
def self.included base
|
|
5
|
+
base.key :name, String
|
|
6
|
+
|
|
7
|
+
[ :before_validation, :after_validation,
|
|
8
|
+
:before_create, :after_create,
|
|
9
|
+
:before_update, :after_update,
|
|
10
|
+
:before_save, :after_save,
|
|
11
|
+
:before_destroy, :after_destroy
|
|
12
|
+
].each do |callback|
|
|
13
|
+
base.send(callback) do
|
|
14
|
+
history << callback.to_sym
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def history
|
|
20
|
+
@history ||= []
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def clear_history
|
|
24
|
+
embedded_associations.each { |a| self.send(a.name).each(&:clear_history) }
|
|
25
|
+
@history = nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class CallbacksTest < Test::Unit::TestCase
|
|
30
|
+
CreateCallbackOrder = [
|
|
31
|
+
:before_validation,
|
|
32
|
+
:after_validation,
|
|
33
|
+
:before_save,
|
|
34
|
+
:before_create,
|
|
35
|
+
:after_create,
|
|
36
|
+
:after_save
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
UpdateCallbackOrder = [
|
|
40
|
+
:before_validation,
|
|
41
|
+
:after_validation,
|
|
42
|
+
:before_save,
|
|
43
|
+
:before_update,
|
|
44
|
+
:after_update,
|
|
45
|
+
:after_save
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
context "Defining and running callbacks on documents" do
|
|
49
|
+
setup do
|
|
50
|
+
@document = Doc { include CallbacksSupport }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
should "get the order right for creating documents" do
|
|
54
|
+
doc = @document.create(:name => 'John Nunemaker')
|
|
55
|
+
doc.history.should == CreateCallbackOrder
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
should "get the order right for updating documents" do
|
|
59
|
+
doc = @document.create(:name => 'John Nunemaker')
|
|
60
|
+
doc.clear_history
|
|
61
|
+
doc.name = 'John'
|
|
62
|
+
doc.save
|
|
63
|
+
doc.history.should == UpdateCallbackOrder
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
should "work for before and after validation" do
|
|
67
|
+
doc = @document.new(:name => 'John Nunemaker')
|
|
68
|
+
doc.valid?
|
|
69
|
+
doc.history.should include(:before_validation)
|
|
70
|
+
doc.history.should include(:after_validation)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
should "work for before and after create" do
|
|
74
|
+
doc = @document.create(:name => 'John Nunemaker')
|
|
75
|
+
doc.history.should include(:before_create)
|
|
76
|
+
doc.history.should include(:after_create)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
should "work for before and after update" do
|
|
80
|
+
doc = @document.create(:name => 'John Nunemaker')
|
|
81
|
+
doc.name = 'John Doe'
|
|
82
|
+
doc.save
|
|
83
|
+
doc.history.should include(:before_update)
|
|
84
|
+
doc.history.should include(:after_update)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
should "work for before and after save" do
|
|
88
|
+
doc = @document.new
|
|
89
|
+
doc.name = 'John Doe'
|
|
90
|
+
doc.save
|
|
91
|
+
doc.history.should include(:before_save)
|
|
92
|
+
doc.history.should include(:after_save)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
should "work for before and after destroy" do
|
|
96
|
+
doc = @document.create(:name => 'John Nunemaker')
|
|
97
|
+
doc.destroy
|
|
98
|
+
doc.history.should include(:before_destroy)
|
|
99
|
+
doc.history.should include(:after_destroy)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "Defining and running callbacks on many embedded documents" do
|
|
104
|
+
setup do
|
|
105
|
+
@root_class = Doc { include CallbacksSupport }
|
|
106
|
+
@child_class = EDoc { include CallbacksSupport }
|
|
107
|
+
@grand_child_class = EDoc { include CallbacksSupport }
|
|
108
|
+
|
|
109
|
+
@root_class.many :children, :class => @child_class
|
|
110
|
+
@child_class.many :children, :class => @grand_child_class
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
should "get the order right based on root document creation" do
|
|
114
|
+
grand = @grand_child_class.new(:name => 'Grand Child')
|
|
115
|
+
child = @child_class.new(:name => 'Child', :children => [grand])
|
|
116
|
+
root = @root_class.create(:name => 'Parent', :children => [child])
|
|
117
|
+
|
|
118
|
+
root.children.first.history.should == CreateCallbackOrder
|
|
119
|
+
root.children.first.children.first.history.should == CreateCallbackOrder
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
should "get the order right based on root document updating" do
|
|
123
|
+
grand = @grand_child_class.new(:name => 'Grand Child')
|
|
124
|
+
child = @child_class.new(:name => 'Child', :children => [grand])
|
|
125
|
+
root = @root_class.create(:name => 'Parent', :children => [child])
|
|
126
|
+
root.clear_history
|
|
127
|
+
root.update_attributes(:name => 'Updated Parent')
|
|
128
|
+
|
|
129
|
+
root.children.first.history.should == UpdateCallbackOrder
|
|
130
|
+
root.children.first.children.first.history.should == UpdateCallbackOrder
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
should "work for before and after destroy" do
|
|
134
|
+
grand = @grand_child_class.new(:name => 'Grand Child')
|
|
135
|
+
child = @child_class.new(:name => 'Child', :children => [grand])
|
|
136
|
+
root = @root_class.create(:name => 'Parent', :children => [child])
|
|
137
|
+
root.destroy
|
|
138
|
+
child = root.children.first
|
|
139
|
+
child.history.should include(:before_destroy)
|
|
140
|
+
child.history.should include(:after_destroy)
|
|
141
|
+
|
|
142
|
+
grand = root.children.first.children.first
|
|
143
|
+
grand.history.should include(:before_destroy)
|
|
144
|
+
grand.history.should include(:after_destroy)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
should "not attempt to run callback defined on root that is not defined on embedded association" do
|
|
148
|
+
@root_class.define_callbacks :after_publish
|
|
149
|
+
@root_class.after_save { |d| d.run_callbacks(:after_publish) }
|
|
150
|
+
|
|
151
|
+
assert_nothing_raised do
|
|
152
|
+
child = @child_class.new(:name => 'Child')
|
|
153
|
+
root = @root_class.create(:name => 'Parent', :children => [child])
|
|
154
|
+
child.history.should_not include(:after_publish)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context "Turning embedded callbacks off" do
|
|
160
|
+
setup do
|
|
161
|
+
@root_class = Doc { include CallbacksSupport; embedded_callbacks_off }
|
|
162
|
+
@child_class = EDoc { include CallbacksSupport; embedded_callbacks_off }
|
|
163
|
+
@grand_child_class = EDoc { include CallbacksSupport; embedded_callbacks_off }
|
|
164
|
+
|
|
165
|
+
@root_class.many :children, :class => @child_class
|
|
166
|
+
@child_class.many :children, :class => @grand_child_class
|
|
167
|
+
|
|
168
|
+
@root_class.many :children, :class => @child_class
|
|
169
|
+
@child_class.many :children, :class => @grand_child_class
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
should "not run create callbacks" do
|
|
173
|
+
grand = @grand_child_class.new(:name => 'Grand Child')
|
|
174
|
+
child = @child_class.new(:name => 'Child', :children => [grand])
|
|
175
|
+
root = @root_class.create(:name => 'Parent', :children => [child])
|
|
176
|
+
|
|
177
|
+
root.children.first.history.should == []
|
|
178
|
+
root.children.first.children.first.history.should == []
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
should "not run update callbacks" do
|
|
182
|
+
grand = @grand_child_class.new(:name => 'Grand Child')
|
|
183
|
+
child = @child_class.new(:name => 'Child', :children => [grand])
|
|
184
|
+
root = @root_class.create(:name => 'Parent', :children => [child])
|
|
185
|
+
root.clear_history
|
|
186
|
+
root.update_attributes(:name => 'Updated Parent')
|
|
187
|
+
|
|
188
|
+
root.children.first.history.should == []
|
|
189
|
+
root.children.first.children.first.history.should == []
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
should "not run destroy callbacks" do
|
|
193
|
+
grand = @grand_child_class.new(:name => 'Grand Child')
|
|
194
|
+
child = @child_class.new(:name => 'Child', :children => [grand])
|
|
195
|
+
root = @root_class.create(:name => 'Parent', :children => [child])
|
|
196
|
+
root.destroy
|
|
197
|
+
child = root.children.first
|
|
198
|
+
child.history.should == []
|
|
199
|
+
|
|
200
|
+
grand = root.children.first.children.first
|
|
201
|
+
grand.history.should == []
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context "Running validation callbacks with conditional execution" do
|
|
206
|
+
setup do
|
|
207
|
+
@document = Doc do
|
|
208
|
+
include CallbacksSupport
|
|
209
|
+
key :message, String
|
|
210
|
+
|
|
211
|
+
before_validation :set_message, :on => 'create'
|
|
212
|
+
|
|
213
|
+
def set_message
|
|
214
|
+
self['message'] = 'Hi!'
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
should 'run callback on create' do
|
|
220
|
+
doc = @document.create
|
|
221
|
+
doc.history.should include(:before_validation)
|
|
222
|
+
doc.message.should == 'Hi!'
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
should 'skip callback on update' do
|
|
226
|
+
doc = @document.create
|
|
227
|
+
doc.message = 'Ho!'
|
|
228
|
+
doc.save
|
|
229
|
+
doc.message.should == 'Ho!'
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|