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,301 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class DirtyTest < Test::Unit::TestCase
|
|
4
|
+
def setup
|
|
5
|
+
@document = Doc { key :phrase, String }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
context "marking changes" do
|
|
9
|
+
should "not happen if there are none" do
|
|
10
|
+
doc = @document.new
|
|
11
|
+
doc.phrase_changed?.should be_false
|
|
12
|
+
doc.phrase_change.should be_nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
should "happen when change happens" do
|
|
16
|
+
doc = @document.new
|
|
17
|
+
doc.phrase = 'Golly Gee Willikers Batman'
|
|
18
|
+
doc.phrase_changed?.should be_true
|
|
19
|
+
doc.phrase_was.should be_nil
|
|
20
|
+
doc.phrase_change.should == [nil, 'Golly Gee Willikers Batman']
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
should "happen when initializing" do
|
|
24
|
+
doc = @document.new(:phrase => 'Foo')
|
|
25
|
+
doc.changed?.should be_true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
should "clear changes on save" do
|
|
29
|
+
doc = @document.new
|
|
30
|
+
doc.phrase = 'Golly Gee Willikers Batman'
|
|
31
|
+
doc.phrase_changed?.should be_true
|
|
32
|
+
doc.save
|
|
33
|
+
doc.phrase_changed?.should_not be_true
|
|
34
|
+
doc.phrase_change.should be_nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
should "clear changes on save!" do
|
|
38
|
+
doc = @document.new
|
|
39
|
+
doc.phrase = 'Golly Gee Willikers Batman'
|
|
40
|
+
doc.phrase_changed?.should be_true
|
|
41
|
+
doc.save!
|
|
42
|
+
doc.phrase_changed?.should_not be_true
|
|
43
|
+
doc.phrase_change.should be_nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
should "not happen when loading from database" do
|
|
47
|
+
doc = @document.create(:phrase => 'Foo')
|
|
48
|
+
doc = @document.find(doc.id)
|
|
49
|
+
|
|
50
|
+
doc.changed?.should be_false
|
|
51
|
+
doc.phrase = 'Fart'
|
|
52
|
+
doc.changed?.should be_true
|
|
53
|
+
doc.reload
|
|
54
|
+
doc.changed?.should be_false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
should "happen if changed after loading from database" do
|
|
58
|
+
doc = @document.create(:phrase => 'Foo')
|
|
59
|
+
doc.reload
|
|
60
|
+
doc.changed?.should be_false
|
|
61
|
+
doc.phrase = 'Bar'
|
|
62
|
+
doc.changed?.should be_true
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context "blank new value and type integer" do
|
|
67
|
+
should "not mark changes" do
|
|
68
|
+
@document.key :age, Integer
|
|
69
|
+
|
|
70
|
+
[nil, ''].each do |value|
|
|
71
|
+
doc = @document.new
|
|
72
|
+
doc.age = value
|
|
73
|
+
doc.age_changed?.should be_false
|
|
74
|
+
doc.age_change.should be_nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "blank new value and type float" do
|
|
80
|
+
should "not mark changes" do
|
|
81
|
+
@document.key :amount, Float
|
|
82
|
+
|
|
83
|
+
[nil, ''].each do |value|
|
|
84
|
+
doc = @document.new
|
|
85
|
+
doc.amount = value
|
|
86
|
+
doc.amount_changed?.should be_false
|
|
87
|
+
doc.amount_change.should be_nil
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context "changed?" do
|
|
93
|
+
should "be true if key changed" do
|
|
94
|
+
doc = @document.new
|
|
95
|
+
doc.phrase = 'A penny saved is a penny earned.'
|
|
96
|
+
doc.changed?.should be_true
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
should "be false if no keys changed" do
|
|
100
|
+
@document.new.changed?.should be_false
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
should "not raise when key name is 'value'" do
|
|
104
|
+
@document.key :value, Integer
|
|
105
|
+
|
|
106
|
+
doc = @document.new
|
|
107
|
+
doc.value_changed?.should be_false
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
should "be false if the same ObjectId was assigned in String format" do
|
|
111
|
+
@document.key :doc_id, ObjectId
|
|
112
|
+
|
|
113
|
+
doc = @document.create!(:doc_id => BSON::ObjectId.new)
|
|
114
|
+
doc.changed?.should be_false
|
|
115
|
+
doc.doc_id = doc.doc_id.to_s
|
|
116
|
+
doc.changed?.should be_false
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context "changes" do
|
|
121
|
+
should "be empty hash if no changes" do
|
|
122
|
+
@document.new.changes.should == {}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
should "be hash of keys with values of changes if there are changes" do
|
|
126
|
+
doc = @document.new
|
|
127
|
+
doc.phrase = 'A penny saved is a penny earned.'
|
|
128
|
+
doc.changes['phrase'].should == [nil, 'A penny saved is a penny earned.']
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context "changed" do
|
|
133
|
+
should "be empty array if no changes" do
|
|
134
|
+
@document.new.changed.should == []
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
should "be array of keys that have changed if there are changes" do
|
|
138
|
+
doc = @document.new
|
|
139
|
+
doc.phrase = 'A penny saved is a penny earned.'
|
|
140
|
+
doc.changed.should == ['phrase']
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
context "will_change!" do
|
|
145
|
+
should "mark changes" do
|
|
146
|
+
doc = @document.create(:phrase => 'Foo')
|
|
147
|
+
|
|
148
|
+
doc.phrase << 'bar'
|
|
149
|
+
doc.phrase_changed?.should be_false
|
|
150
|
+
|
|
151
|
+
doc.phrase_will_change!
|
|
152
|
+
doc.phrase_changed?.should be_true
|
|
153
|
+
doc.phrase_change.should == ['Foobar', 'Foobar']
|
|
154
|
+
|
|
155
|
+
doc.phrase << '!'
|
|
156
|
+
doc.phrase_changed?.should be_true
|
|
157
|
+
doc.phrase_change.should == ['Foobar', 'Foobar!']
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context "changing a foreign key through association" do
|
|
162
|
+
should "mark changes" do
|
|
163
|
+
project_class = Doc do
|
|
164
|
+
key :name, String
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
milestone_class = Doc do
|
|
168
|
+
key :project_id, ObjectId
|
|
169
|
+
key :name, String
|
|
170
|
+
end
|
|
171
|
+
milestone_class.belongs_to :project, :class => project_class
|
|
172
|
+
|
|
173
|
+
milestone = milestone_class.create(:name => 'Launch')
|
|
174
|
+
milestone.project = project_class.create(:name => 'Harmony')
|
|
175
|
+
milestone.changed?.should be_true
|
|
176
|
+
milestone.changed.should == %w(project_id)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
context "save with an invalid document" do
|
|
181
|
+
should "not clear changes" do
|
|
182
|
+
validated_class = Doc do
|
|
183
|
+
key :name, String
|
|
184
|
+
key :required, String, :required=>true
|
|
185
|
+
end
|
|
186
|
+
validated_doc = validated_class.new
|
|
187
|
+
validated_doc.name = "I'm a changin"
|
|
188
|
+
validated_doc.save
|
|
189
|
+
validated_doc.changed?.should be_true
|
|
190
|
+
|
|
191
|
+
validated_doc.required = 1
|
|
192
|
+
validated_doc.save
|
|
193
|
+
validated_doc.changed?.should be_false
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
context "changing an already changed attribute" do
|
|
198
|
+
should "preserve the original value" do
|
|
199
|
+
doc = @document.create(:a=>"b")
|
|
200
|
+
doc.a = "c"
|
|
201
|
+
doc.a_change.should == ["b","c"]
|
|
202
|
+
doc.a = "d"
|
|
203
|
+
doc.a_change.should == ["b","d"]
|
|
204
|
+
end
|
|
205
|
+
should "reset changes when set back to the original value" do
|
|
206
|
+
doc = @document.create(:a=>"b")
|
|
207
|
+
doc.a = "c"
|
|
208
|
+
doc.a = "b"
|
|
209
|
+
doc.changed?.should be_false
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
context "reset_attribute!" do
|
|
214
|
+
should "reset the attribute back to the previous value" do
|
|
215
|
+
doc = @document.create(:a=>"b")
|
|
216
|
+
doc.a = "c"
|
|
217
|
+
doc.reset_a!
|
|
218
|
+
doc.changed?.should be_false
|
|
219
|
+
doc.a.should == "b"
|
|
220
|
+
end
|
|
221
|
+
should "reset the attribute back to the original value after several changes" do
|
|
222
|
+
doc = @document.create(:a=>"b")
|
|
223
|
+
doc.a = "c"
|
|
224
|
+
doc.a = "d"
|
|
225
|
+
doc.a = "e"
|
|
226
|
+
doc.reset_a!
|
|
227
|
+
doc.changed?.should be_false
|
|
228
|
+
doc.a.should == "b"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
context "previous_changes" do
|
|
233
|
+
should "reflect previously committed change" do
|
|
234
|
+
doc = @document.create(:a=>"b")
|
|
235
|
+
doc.a = "c"
|
|
236
|
+
changes = doc.changes
|
|
237
|
+
doc.save!
|
|
238
|
+
doc.previous_changes.should == changes
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
should "not include attributes loaded from db" do
|
|
242
|
+
doc = @document.create(:a => "b")
|
|
243
|
+
@document.find(doc.id).previous_changes.should be_blank
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
context "Embedded documents" do
|
|
248
|
+
setup do
|
|
249
|
+
@edoc = EDoc('Duck') { key :name, String }
|
|
250
|
+
@edoc.plugin MongoMapper::Plugins::Dirty
|
|
251
|
+
@document = Doc('Long') { key :name, String }
|
|
252
|
+
@document.many :ducks, :class=>@edoc
|
|
253
|
+
@doc = @document.new
|
|
254
|
+
@duck = @doc.ducks.build
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
should "track changes" do
|
|
258
|
+
@duck.name = "hi"
|
|
259
|
+
@duck.changed?.should be_true
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
should "clear changes when saved" do
|
|
263
|
+
@duck.name = "hi"
|
|
264
|
+
@duck.changed?.should be_true
|
|
265
|
+
@duck.save!
|
|
266
|
+
@duck.changed?.should_not be_true
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
should "clear changes when the parent is saved" do
|
|
270
|
+
@duck.name = "hi"
|
|
271
|
+
@duck.changed?.should be_true
|
|
272
|
+
@doc.save!
|
|
273
|
+
@duck.changed?.should_not be_true
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
context "with nested embedded documents" do
|
|
277
|
+
setup do
|
|
278
|
+
@inner_edoc = EDoc('Dong') {key :name, String}
|
|
279
|
+
@inner_edoc.plugin MongoMapper::Plugins::Dirty
|
|
280
|
+
@edoc.many :dongs, :class=>@inner_edoc
|
|
281
|
+
@dong = @duck.dongs.build
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
should "track changes" do
|
|
285
|
+
@dong.name = "hi"
|
|
286
|
+
@dong.changed?.should be_true
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
should "clear changes when the root saves" do
|
|
290
|
+
@dong.name = "hi"
|
|
291
|
+
@dong.changed?.should be_true
|
|
292
|
+
@doc.save!
|
|
293
|
+
@dong.changed?.should be_false
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
end
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'models'
|
|
3
|
+
|
|
4
|
+
class DocumentTest < Test::Unit::TestCase
|
|
5
|
+
def setup
|
|
6
|
+
@document = Doc do
|
|
7
|
+
key :first_name, String
|
|
8
|
+
key :last_name, String
|
|
9
|
+
key :age, Integer
|
|
10
|
+
key :date, Date
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "array key" do
|
|
15
|
+
setup do
|
|
16
|
+
@document.key :tags, Array
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
should "give correct default" do
|
|
20
|
+
doc = @document.new
|
|
21
|
+
doc.tags.should == []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
should "work with assignment" do
|
|
25
|
+
doc = @document.new
|
|
26
|
+
doc.tags = %w(foo bar)
|
|
27
|
+
doc.tags.should == %w(foo bar)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
should "work with assignment after saving" do
|
|
31
|
+
doc = @document.new
|
|
32
|
+
doc.tags = %w(foo bar)
|
|
33
|
+
doc.save
|
|
34
|
+
doc.tags.should == %w(foo bar)
|
|
35
|
+
doc.reload.tags.should == %w(foo bar)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
should "work with assignment then <<" do
|
|
39
|
+
doc = @document.new
|
|
40
|
+
doc.tags = []
|
|
41
|
+
doc.tags << "foo"
|
|
42
|
+
doc.tags.should == ["foo"]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
should "work with <<" do
|
|
46
|
+
doc = @document.new
|
|
47
|
+
doc.tags << "foo"
|
|
48
|
+
doc.tags.should == ["foo"]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
should "work with << then save" do
|
|
52
|
+
doc = @document.new
|
|
53
|
+
doc.tags << "foo"
|
|
54
|
+
doc.tags << "bar"
|
|
55
|
+
doc.save
|
|
56
|
+
doc.tags.should == %w(foo bar)
|
|
57
|
+
doc.reload.tags.should == %w(foo bar)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context "hash key" do
|
|
62
|
+
setup do
|
|
63
|
+
@document.key :foo, Hash
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
should "give correct default" do
|
|
67
|
+
doc = @document.new
|
|
68
|
+
doc.foo.should == {}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
should "work with []=" do
|
|
72
|
+
doc = @document.new
|
|
73
|
+
doc.foo["quux"] = "bar"
|
|
74
|
+
doc.foo["quux"].should == "bar"
|
|
75
|
+
doc.foo.should == { "quux" => "bar" }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
should "work with indifferent access" do
|
|
79
|
+
doc = @document.new
|
|
80
|
+
doc.foo = {:baz => 'bar'}
|
|
81
|
+
doc.foo[:baz].should == 'bar'
|
|
82
|
+
doc.foo['baz'].should == 'bar'
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
should "work with indifferent access after save" do
|
|
86
|
+
doc = @document.new
|
|
87
|
+
doc.foo = {:baz => 'bar'}
|
|
88
|
+
doc.save
|
|
89
|
+
|
|
90
|
+
doc = doc.reload
|
|
91
|
+
doc.foo[:baz].should == 'bar'
|
|
92
|
+
doc.foo['baz'].should == 'bar'
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "custom type key with default" do
|
|
97
|
+
setup do
|
|
98
|
+
@document.key :window, WindowSize, :default => WindowSize.new(600, 480)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
should "default to default" do
|
|
102
|
+
doc = @document.new
|
|
103
|
+
doc.window.should == WindowSize.new(600, 480)
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
should "save and load from mongo" do
|
|
108
|
+
doc = @document.new
|
|
109
|
+
doc.save
|
|
110
|
+
|
|
111
|
+
doc = doc.reload
|
|
112
|
+
doc.window.should == WindowSize.new(600, 480)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "key with proc default value" do
|
|
117
|
+
setup do
|
|
118
|
+
@document.key :proc_default, String, :default => lambda { return 'string' }
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
should "detect and run proc default" do
|
|
122
|
+
doc = @document.new
|
|
123
|
+
doc.proc_default.should == 'string'
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
should "save and load from mongo" do
|
|
127
|
+
doc = @document.create
|
|
128
|
+
doc = doc.reload
|
|
129
|
+
doc.proc_default.should == 'string'
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
should "have instance method for collection" do
|
|
134
|
+
@document.new.collection.name.should == @document.collection.name
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
should "have instance method for database" do
|
|
138
|
+
@document.new.database.should == @document.database
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context "#destroyed?" do
|
|
142
|
+
setup do
|
|
143
|
+
@doc1 = @document.create(:first_name => 'John', :last_name => 'Nunemaker', :age => '27')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
should "be true if deleted" do
|
|
147
|
+
@doc1.delete
|
|
148
|
+
assert @doc1.destroyed?
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
should "be true if destroyed" do
|
|
152
|
+
@doc1.destroy
|
|
153
|
+
assert @doc1.destroyed?
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
should "be false if not deleted or destroyed" do
|
|
157
|
+
assert ! @doc1.destroyed?
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context "#persisted?" do
|
|
162
|
+
setup do
|
|
163
|
+
@doc = @document.new(:first_name => 'John', :last_name => 'Nunemaker', :age => '27')
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
should "be false if new" do
|
|
167
|
+
@doc.should_not be_persisted
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
should "be false if destroyed" do
|
|
171
|
+
@doc.save
|
|
172
|
+
@doc.destroy
|
|
173
|
+
@doc.should be_destroyed
|
|
174
|
+
@doc.should_not be_persisted
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
should "be true if not new or destroyed" do
|
|
178
|
+
@doc.save
|
|
179
|
+
@doc.should be_persisted
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context "#reload" do
|
|
184
|
+
setup do
|
|
185
|
+
@foo_class = Doc do
|
|
186
|
+
key :name
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
@bar_class = EDoc do
|
|
190
|
+
key :name
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
@document.many :foos, :class => @foo_class
|
|
194
|
+
@document.many :bars, :class => @bar_class
|
|
195
|
+
@document.belongs_to :foo, :class => @foo_class
|
|
196
|
+
@document.one :bar, :class => @bar_class
|
|
197
|
+
|
|
198
|
+
@instance = @document.create({
|
|
199
|
+
:age => 39,
|
|
200
|
+
:foos => [@foo_class.new(:name => '1')],
|
|
201
|
+
:bars => [@bar_class.new(:name => '1')],
|
|
202
|
+
:foo => @foo_class.new(:name => '2'),
|
|
203
|
+
:bar => @bar_class.new(:name => '2')
|
|
204
|
+
})
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
should "reload keys from the database" do
|
|
208
|
+
@instance.age = 37
|
|
209
|
+
@instance.age.should == 37
|
|
210
|
+
@instance.reload
|
|
211
|
+
@instance.age.should == 39
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
should "reset many associations" do
|
|
215
|
+
@instance.foos.expects(:reset).at_least_once
|
|
216
|
+
@instance.bars.expects(:reset).at_least_once
|
|
217
|
+
@instance.reload
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
should "reset belongs_to association" do
|
|
221
|
+
@instance.foo = nil
|
|
222
|
+
@instance.reload
|
|
223
|
+
@instance.foo.should_not be_nil
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
should "reset one association" do
|
|
227
|
+
@instance.bar = nil
|
|
228
|
+
@instance.reload
|
|
229
|
+
@instance.bar.should_not be_nil
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
should "reset nil one association" do
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
should "reinstantiate embedded associations" do
|
|
236
|
+
@instance.reload
|
|
237
|
+
@instance.bars.first.name.should == '1'
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
should "return self" do
|
|
241
|
+
@instance.reload.object_id.should == @instance.object_id
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
should "raise DocumentNotFound if not found" do
|
|
245
|
+
@instance.destroy
|
|
246
|
+
assert_raises(MongoMapper::DocumentNotFound) { @instance.reload }
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
should "clear keys that were removed from the database" do
|
|
250
|
+
@instance.unset(:age)
|
|
251
|
+
@instance.reload.age.should be_nil
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
context "database has keys not defined in model" do
|
|
256
|
+
setup do
|
|
257
|
+
@id = BSON::ObjectId.new
|
|
258
|
+
@document.collection.insert({
|
|
259
|
+
:_id => @id,
|
|
260
|
+
:first_name => 'John',
|
|
261
|
+
:last_name => 'Nunemaker',
|
|
262
|
+
:age => 27,
|
|
263
|
+
:favorite_color => 'red',
|
|
264
|
+
:skills => ['ruby', 'rails', 'javascript', 'xhtml', 'css']
|
|
265
|
+
})
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
should "assign all keys from database" do
|
|
269
|
+
doc = @document.find(@id)
|
|
270
|
+
doc.first_name.should == 'John'
|
|
271
|
+
doc.last_name.should == 'Nunemaker'
|
|
272
|
+
doc.age.should == 27
|
|
273
|
+
doc.favorite_color.should == 'red'
|
|
274
|
+
doc.skills.should == ['ruby', 'rails', 'javascript', 'xhtml', 'css']
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
should "not walk ObjectSpace when creating a model" do
|
|
279
|
+
ObjectSpace.expects(:each_object).never
|
|
280
|
+
Doc()
|
|
281
|
+
end
|
|
282
|
+
end
|