mongo_mapper 0.6.10 → 0.7.0
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/README.rdoc +5 -14
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/mongo_mapper.rb +48 -56
- data/lib/mongo_mapper/document.rb +136 -164
- data/lib/mongo_mapper/embedded_document.rb +29 -354
- data/lib/mongo_mapper/plugins.rb +31 -0
- data/lib/mongo_mapper/plugins/associations.rb +105 -0
- data/lib/mongo_mapper/plugins/associations/base.rb +123 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
- data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
- data/lib/mongo_mapper/plugins/clone.rb +13 -0
- data/lib/mongo_mapper/plugins/descendants.rb +16 -0
- data/lib/mongo_mapper/plugins/dirty.rb +119 -0
- data/lib/mongo_mapper/plugins/equality.rb +23 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
- data/lib/mongo_mapper/plugins/inspect.rb +14 -0
- data/lib/mongo_mapper/plugins/keys.rb +324 -0
- data/lib/mongo_mapper/plugins/logger.rb +17 -0
- data/lib/mongo_mapper/plugins/pagination.rb +24 -0
- data/lib/mongo_mapper/plugins/pagination/proxy.rb +68 -0
- data/lib/mongo_mapper/plugins/protected.rb +45 -0
- data/lib/mongo_mapper/plugins/rails.rb +45 -0
- data/lib/mongo_mapper/plugins/serialization.rb +105 -0
- data/lib/mongo_mapper/plugins/validations.rb +46 -0
- data/lib/mongo_mapper/query.rb +130 -0
- data/lib/mongo_mapper/support.rb +40 -17
- data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
- data/lib/mongo_mapper/support/find.rb +77 -0
- data/mongo_mapper.gemspec +55 -38
- data/performance/read_write.rb +52 -0
- data/specs.watchr +23 -2
- data/test/functional/associations/test_belongs_to_proxy.rb +12 -10
- data/test/functional/associations/test_many_documents_as_proxy.rb +4 -21
- data/test/functional/associations/test_many_documents_proxy.rb +2 -8
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +59 -39
- data/test/functional/associations/test_many_embedded_proxy.rb +145 -81
- data/test/functional/associations/test_many_polymorphic_proxy.rb +2 -40
- data/test/functional/associations/test_one_proxy.rb +25 -10
- data/test/functional/test_binary.rb +2 -8
- data/test/functional/test_callbacks.rb +1 -5
- data/test/functional/test_dirty.rb +27 -23
- data/test/functional/test_document.rb +224 -165
- data/test/functional/test_embedded_document.rb +72 -82
- data/test/functional/test_identity_map.rb +508 -0
- data/test/functional/test_modifiers.rb +15 -5
- data/test/functional/test_pagination.rb +1 -3
- data/test/functional/test_protected.rb +155 -0
- data/test/functional/test_string_id_compatibility.rb +7 -12
- data/test/functional/test_validations.rb +26 -58
- data/test/models.rb +0 -39
- data/test/test_helper.rb +37 -3
- data/test/unit/associations/test_base.rb +5 -5
- data/test/unit/associations/test_proxy.rb +8 -6
- data/test/unit/test_descendant_appends.rb +71 -0
- data/test/unit/test_document.rb +71 -76
- data/test/unit/test_dynamic_finder.rb +27 -29
- data/test/unit/test_embedded_document.rb +555 -601
- data/test/unit/{test_key.rb → test_keys.rb} +2 -5
- data/test/unit/test_mongo_mapper.rb +69 -9
- data/test/unit/test_pagination.rb +40 -32
- data/test/unit/test_plugins.rb +50 -0
- data/test/unit/{test_finder_options.rb → test_query.rb} +74 -65
- data/test/unit/test_rails.rb +123 -0
- data/test/unit/{test_serializations.rb → test_serialization.rb} +1 -2
- data/test/unit/test_support.rb +23 -7
- data/test/unit/test_time_zones.rb +3 -4
- data/test/unit/test_validations.rb +58 -17
- metadata +53 -36
- data/lib/mongo_mapper/associations.rb +0 -78
- data/lib/mongo_mapper/associations/base.rb +0 -119
- data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +0 -26
- data/lib/mongo_mapper/associations/belongs_to_proxy.rb +0 -21
- data/lib/mongo_mapper/associations/collection.rb +0 -19
- data/lib/mongo_mapper/associations/in_array_proxy.rb +0 -137
- data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -26
- data/lib/mongo_mapper/associations/many_documents_proxy.rb +0 -115
- data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +0 -31
- data/lib/mongo_mapper/associations/many_embedded_proxy.rb +0 -54
- data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +0 -11
- data/lib/mongo_mapper/associations/one_proxy.rb +0 -64
- data/lib/mongo_mapper/associations/proxy.rb +0 -116
- data/lib/mongo_mapper/callbacks.rb +0 -61
- data/lib/mongo_mapper/dirty.rb +0 -117
- data/lib/mongo_mapper/dynamic_finder.rb +0 -74
- data/lib/mongo_mapper/finder_options.rb +0 -145
- data/lib/mongo_mapper/key.rb +0 -36
- data/lib/mongo_mapper/mongo_mapper.rb +0 -125
- data/lib/mongo_mapper/pagination.rb +0 -66
- data/lib/mongo_mapper/rails_compatibility/document.rb +0 -15
- data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +0 -28
- data/lib/mongo_mapper/serialization.rb +0 -54
- data/lib/mongo_mapper/serializers/json_serializer.rb +0 -48
- data/lib/mongo_mapper/validations.rb +0 -39
- data/test/functional/test_rails_compatibility.rb +0 -25
data/specs.watchr
CHANGED
@@ -1,6 +1,27 @@
|
|
1
|
+
def growl(title, msg, img)
|
2
|
+
%x{growlnotify -m #{ msg.inspect} -t #{title.inspect} --image ~/.watchr/#{img}.png}
|
3
|
+
end
|
4
|
+
|
5
|
+
def form_growl_message(str)
|
6
|
+
results = str.split("\n").last
|
7
|
+
if results =~ /[1-9]\s(failure|error)s?/
|
8
|
+
growl "Test Results", "#{results}", "fail"
|
9
|
+
elsif results != ""
|
10
|
+
growl "Test Results", "#{results}", "pass"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
1
14
|
def run(cmd)
|
2
15
|
puts(cmd)
|
3
|
-
|
16
|
+
output = ""
|
17
|
+
IO.popen(cmd) do |com|
|
18
|
+
com.each_char do |c|
|
19
|
+
print c
|
20
|
+
output << c
|
21
|
+
$stdout.flush
|
22
|
+
end
|
23
|
+
end
|
24
|
+
form_growl_message output
|
4
25
|
end
|
5
26
|
|
6
27
|
def run_test_file(file)
|
@@ -17,7 +38,7 @@ end
|
|
17
38
|
|
18
39
|
watch('test/test_helper\.rb') { system('clear'); run_all_tests }
|
19
40
|
watch('test/.*/test_.*\.rb') { |m| system('clear'); run_test_file(m[0]) }
|
20
|
-
watch('lib/.*') { |m| related_test_files(m[0]).each { |file|
|
41
|
+
watch('lib/.*') { |m| related_test_files(m[0]).each { |file| run_test_file(file) } }
|
21
42
|
|
22
43
|
# Ctrl-\
|
23
44
|
Signal.trap('QUIT') do
|
@@ -3,24 +3,26 @@ require 'models'
|
|
3
3
|
|
4
4
|
class BelongsToProxyTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
@post_class =
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
@comment_class = Class.new do
|
11
|
-
include MongoMapper::Document
|
6
|
+
@post_class = Doc()
|
7
|
+
@comment_class = Doc do
|
12
8
|
key :post_id, String
|
13
9
|
end
|
14
|
-
@comment_class.belongs_to :post, :class => @post_class
|
15
10
|
|
16
|
-
@post_class
|
17
|
-
@comment_class.collection.remove
|
11
|
+
@comment_class.belongs_to :post, :class => @post_class
|
18
12
|
end
|
19
13
|
|
20
14
|
should "default to nil" do
|
21
15
|
@comment_class.new.post.nil?.should be_true
|
22
16
|
end
|
23
17
|
|
18
|
+
should "send object id to target" do
|
19
|
+
post = @post_class.new(:name => 'mongomapper')
|
20
|
+
comment = @comment_class.new(:name => 'Foo!', :post => post)
|
21
|
+
comment.save
|
22
|
+
|
23
|
+
comment.post.object_id.should == comment.post.target.object_id
|
24
|
+
end
|
25
|
+
|
24
26
|
should "have boolean presence method" do
|
25
27
|
comment = @comment_class.new(:name => 'Foo!')
|
26
28
|
comment.post?.should be_false
|
@@ -78,7 +80,7 @@ class BelongsToProxyTest < Test::Unit::TestCase
|
|
78
80
|
setup do
|
79
81
|
Property.key :thing_id, ObjectId
|
80
82
|
Property.belongs_to :thing, :dependent => :destroy
|
81
|
-
Thing.
|
83
|
+
Thing.many :properties
|
82
84
|
|
83
85
|
@thing = Thing.create(:name => "Tree")
|
84
86
|
@property1 = Property.create
|
@@ -131,23 +131,6 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
|
|
131
131
|
@post2.save
|
132
132
|
end
|
133
133
|
|
134
|
-
context "with :all" do
|
135
|
-
should "work" do
|
136
|
-
@post.comments.find(:all).should include(@comment1)
|
137
|
-
@post.comments.find(:all).should include(@comment2)
|
138
|
-
end
|
139
|
-
|
140
|
-
should "work with conditions" do
|
141
|
-
comments = @post.comments.find(:all, :body => 'comment1')
|
142
|
-
comments.should == [@comment1]
|
143
|
-
end
|
144
|
-
|
145
|
-
should "work with order" do
|
146
|
-
comments = @post.comments.find(:all, :order => 'body desc')
|
147
|
-
comments.should == [@comment2, @comment1]
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
134
|
context "with #all" do
|
152
135
|
should "work" do
|
153
136
|
@post.comments.all.should include(@comment1)
|
@@ -171,9 +154,9 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
|
|
171
154
|
end
|
172
155
|
|
173
156
|
should "not work for id not in association" do
|
174
|
-
|
157
|
+
assert_raises(MongoMapper::DocumentNotFound) do
|
175
158
|
@post.comments.find!(@comment5._id)
|
176
|
-
|
159
|
+
end
|
177
160
|
end
|
178
161
|
end
|
179
162
|
|
@@ -184,9 +167,9 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
|
|
184
167
|
end
|
185
168
|
|
186
169
|
should "not work for ids not in association" do
|
187
|
-
|
170
|
+
assert_raises(MongoMapper::DocumentNotFound) do
|
188
171
|
@post.comments.find!(@comment1._id, @comment2._id, @comment4._id)
|
189
|
-
|
172
|
+
end
|
190
173
|
end
|
191
174
|
end
|
192
175
|
|
@@ -242,36 +242,30 @@ class ManyDocumentsProxyTest < Test::Unit::TestCase
|
|
242
242
|
|
243
243
|
context "all" do
|
244
244
|
should "work" do
|
245
|
-
@project1.statuses.find(:all, :order => "position asc").should == [@brand_new, @complete]
|
246
245
|
@project1.statuses.all(:order => "position asc").should == [@brand_new, @complete]
|
247
246
|
end
|
248
247
|
|
249
248
|
should "work with conditions" do
|
250
|
-
@project1.statuses.find(:all, :name => 'Complete').should == [@complete]
|
251
249
|
@project1.statuses.all(:name => 'Complete').should == [@complete]
|
252
250
|
end
|
253
251
|
end
|
254
252
|
|
255
253
|
context "first" do
|
256
254
|
should "work" do
|
257
|
-
@project1.statuses.find(:first, :order => 'name').should == @complete
|
258
255
|
@project1.statuses.first(:order => 'name').should == @complete
|
259
256
|
end
|
260
257
|
|
261
258
|
should "work with conditions" do
|
262
|
-
@project1.statuses.find(:first, :name => 'Complete').should == @complete
|
263
259
|
@project1.statuses.first(:name => 'Complete').should == @complete
|
264
260
|
end
|
265
261
|
end
|
266
262
|
|
267
263
|
context "last" do
|
268
264
|
should "work" do
|
269
|
-
@project1.statuses.find(:last, :order => "position asc").should == @complete
|
270
265
|
@project1.statuses.last(:order => "position asc").should == @complete
|
271
266
|
end
|
272
267
|
|
273
268
|
should "work with conditions" do
|
274
|
-
@project1.statuses.find(:last, :order => 'position', :name => 'New').should == @brand_new
|
275
269
|
@project1.statuses.last(:order => 'position', :name => 'New').should == @brand_new
|
276
270
|
end
|
277
271
|
end
|
@@ -295,9 +289,9 @@ class ManyDocumentsProxyTest < Test::Unit::TestCase
|
|
295
289
|
end
|
296
290
|
|
297
291
|
should "not work for ids not in association" do
|
298
|
-
|
292
|
+
assert_raises(MongoMapper::DocumentNotFound) do
|
299
293
|
@project1.statuses.find!(@brand_new.id, @complete.id, @archived.id)
|
300
|
-
|
294
|
+
end
|
301
295
|
end
|
302
296
|
end
|
303
297
|
|
@@ -21,30 +21,50 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
should "be able to replace the association" do
|
23
23
|
catalog = Catalog.new
|
24
|
-
catalog.medias = [Video.new(
|
24
|
+
catalog.medias = [Video.new('file' => 'video.mpg', 'length' => 3600)]
|
25
25
|
catalog.save.should be_true
|
26
26
|
|
27
27
|
catalog = catalog.reload
|
28
28
|
catalog.medias.size.should == 1
|
29
|
-
catalog.medias[0].file.should ==
|
29
|
+
catalog.medias[0].file.should == 'video.mpg'
|
30
|
+
catalog.medias[0].new?.should == false
|
30
31
|
end
|
31
|
-
|
32
|
+
|
33
|
+
context "count" do
|
34
|
+
should "default to 0" do
|
35
|
+
Catalog.new.medias.count.should == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
should 'return correct count if any are embedded' do
|
39
|
+
catalog = Catalog.new
|
40
|
+
catalog.medias = [
|
41
|
+
Video.new('file' => 'video.mpg', 'length' => 3600),
|
42
|
+
Music.new('file' => 'music.mp3', 'bitrate' => '128kbps'),
|
43
|
+
Image.new('file' => 'image.png', 'width' => 800, 'height' => 600)
|
44
|
+
]
|
45
|
+
catalog.medias.count.should == 3
|
46
|
+
catalog.save.should be_true
|
47
|
+
catalog.reload
|
48
|
+
catalog.medias.count.should == 3
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
32
52
|
should "store different associations" do
|
33
53
|
catalog = Catalog.new
|
34
54
|
catalog.medias = [
|
35
|
-
Video.new(
|
36
|
-
Music.new(
|
37
|
-
Image.new(
|
55
|
+
Video.new('file' => 'video.mpg', 'length' => 3600),
|
56
|
+
Music.new('file' => 'music.mp3', 'bitrate' => '128kbps'),
|
57
|
+
Image.new('file' => 'image.png', 'width' => 800, 'height' => 600)
|
38
58
|
]
|
39
59
|
catalog.save.should be_true
|
40
60
|
|
41
61
|
catalog = catalog.reload
|
42
62
|
catalog.medias.size.should == 3
|
43
|
-
catalog.medias[0].file.should ==
|
63
|
+
catalog.medias[0].file.should == 'video.mpg'
|
44
64
|
catalog.medias[0].length.should == 3600
|
45
|
-
catalog.medias[1].file.should ==
|
65
|
+
catalog.medias[1].file.should == 'music.mp3'
|
46
66
|
catalog.medias[1].bitrate.should == "128kbps"
|
47
|
-
catalog.medias[2].file.should ==
|
67
|
+
catalog.medias[2].file.should == 'image.png'
|
48
68
|
catalog.medias[2].width.should == 800
|
49
69
|
catalog.medias[2].height.should == 600
|
50
70
|
end
|
@@ -52,38 +72,38 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
52
72
|
context "With modularized models" do
|
53
73
|
should "set associations correctly" do
|
54
74
|
fleet_attributes = {
|
55
|
-
|
56
|
-
|
57
|
-
{
|
58
|
-
{
|
59
|
-
{
|
75
|
+
'name' => 'My Fleet',
|
76
|
+
'transports' => [
|
77
|
+
{'_type' => 'TrModels::Ambulance', 'license_plate' => 'GGG123', 'icu' => true},
|
78
|
+
{'_type' => 'TrModels::Car', 'license_plate' => 'ABC123', 'model' => 'VW Golf', 'year' => 2001},
|
79
|
+
{'_type' => 'TrModels::Car', 'license_plate' => 'DEF123', 'model' => 'Honda Accord', 'year' => 2008},
|
60
80
|
]
|
61
81
|
}
|
62
82
|
|
63
83
|
fleet = TrModels::Fleet.new(fleet_attributes)
|
64
84
|
fleet.transports.size.should == 3
|
65
85
|
fleet.transports[0].class.should == TrModels::Ambulance
|
66
|
-
fleet.transports[0].license_plate.should ==
|
86
|
+
fleet.transports[0].license_plate.should == 'GGG123'
|
67
87
|
fleet.transports[0].icu.should be_true
|
68
88
|
fleet.transports[1].class.should == TrModels::Car
|
69
|
-
fleet.transports[1].license_plate.should ==
|
70
|
-
fleet.transports[1].model.should ==
|
89
|
+
fleet.transports[1].license_plate.should == 'ABC123'
|
90
|
+
fleet.transports[1].model.should == 'VW Golf'
|
71
91
|
fleet.transports[1].year.should == 2001
|
72
92
|
fleet.transports[2].class.should == TrModels::Car
|
73
|
-
fleet.transports[2].license_plate.should ==
|
74
|
-
fleet.transports[2].model.should ==
|
93
|
+
fleet.transports[2].license_plate.should == 'DEF123'
|
94
|
+
fleet.transports[2].model.should == 'Honda Accord'
|
75
95
|
fleet.transports[2].year.should == 2008
|
76
96
|
fleet.save.should be_true
|
77
97
|
|
78
98
|
fleet = fleet.reload
|
79
99
|
fleet.transports.size.should == 3
|
80
|
-
fleet.transports[0].license_plate.should ==
|
100
|
+
fleet.transports[0].license_plate.should == 'GGG123'
|
81
101
|
fleet.transports[0].icu.should be_true
|
82
|
-
fleet.transports[1].license_plate.should ==
|
83
|
-
fleet.transports[1].model.should ==
|
102
|
+
fleet.transports[1].license_plate.should == 'ABC123'
|
103
|
+
fleet.transports[1].model.should == 'VW Golf'
|
84
104
|
fleet.transports[1].year.should == 2001
|
85
|
-
fleet.transports[2].license_plate.should ==
|
86
|
-
fleet.transports[2].model.should ==
|
105
|
+
fleet.transports[2].license_plate.should == 'DEF123'
|
106
|
+
fleet.transports[2].model.should == 'Honda Accord'
|
87
107
|
fleet.transports[2].year.should == 2008
|
88
108
|
end
|
89
109
|
|
@@ -101,31 +121,31 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
101
121
|
|
102
122
|
should "be able to replace the association" do
|
103
123
|
fleet = TrModels::Fleet.new
|
104
|
-
fleet.transports = [TrModels::Car.new(
|
124
|
+
fleet.transports = [TrModels::Car.new('license_plate' => 'DCU2013', 'model' => 'Honda Civic')]
|
105
125
|
fleet.save.should be_true
|
106
126
|
|
107
127
|
fleet = fleet.reload
|
108
128
|
fleet.transports.size.should == 1
|
109
|
-
fleet.transports[0].license_plate.should ==
|
129
|
+
fleet.transports[0].license_plate.should == 'DCU2013'
|
110
130
|
end
|
111
131
|
|
112
132
|
should "store different associations" do
|
113
133
|
fleet = TrModels::Fleet.new
|
114
134
|
fleet.transports = [
|
115
|
-
TrModels::Car.new(
|
116
|
-
TrModels::Bus.new(
|
117
|
-
TrModels::Ambulance.new(
|
135
|
+
TrModels::Car.new('license_plate' => 'ABC1223', 'model' => 'Honda Civic', 'year' => 2003),
|
136
|
+
TrModels::Bus.new('license_plate' => 'XYZ9090', 'max_passengers' => 51),
|
137
|
+
TrModels::Ambulance.new('license_plate' => 'HDD3030', 'icu' => true)
|
118
138
|
]
|
119
139
|
fleet.save.should be_true
|
120
140
|
|
121
141
|
fleet = fleet.reload
|
122
142
|
fleet.transports.size.should == 3
|
123
|
-
fleet.transports[0].license_plate.should ==
|
124
|
-
fleet.transports[0].model.should ==
|
143
|
+
fleet.transports[0].license_plate.should == 'ABC1223'
|
144
|
+
fleet.transports[0].model.should == 'Honda Civic'
|
125
145
|
fleet.transports[0].year.should == 2003
|
126
|
-
fleet.transports[1].license_plate.should ==
|
146
|
+
fleet.transports[1].license_plate.should == 'XYZ9090'
|
127
147
|
fleet.transports[1].max_passengers.should == 51
|
128
|
-
fleet.transports[2].license_plate.should ==
|
148
|
+
fleet.transports[2].license_plate.should == 'HDD3030'
|
129
149
|
fleet.transports[2].icu.should == true
|
130
150
|
end
|
131
151
|
end
|
@@ -134,9 +154,9 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
134
154
|
should "work using a block passed to many" do
|
135
155
|
catalog = Catalog.new
|
136
156
|
medias = catalog.medias = [
|
137
|
-
Video.new(
|
138
|
-
Music.new(
|
139
|
-
Image.new(
|
157
|
+
Video.new('file' => 'video.mpg', 'length' => 3600, :visible => true),
|
158
|
+
Music.new('file' => 'music.mp3', 'bitrate' => '128kbps', :visible => true),
|
159
|
+
Image.new('file' => 'image.png', 'width' => 800, 'height' => 600, :visible => false)
|
140
160
|
]
|
141
161
|
catalog.save
|
142
162
|
catalog.medias.visible.should == [medias[0], medias[1]]
|
@@ -145,9 +165,9 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
145
165
|
should "work using many's :extend option" do
|
146
166
|
fleet = TrModels::Fleet.new
|
147
167
|
transports = fleet.transports = [
|
148
|
-
TrModels::Car.new(
|
149
|
-
TrModels::Bus.new(
|
150
|
-
TrModels::Ambulance.new(
|
168
|
+
TrModels::Car.new('license_plate' => 'ABC1223', 'model' => 'Honda Civic', 'year' => 2003, :purchased_on => 2.years.ago.to_date),
|
169
|
+
TrModels::Bus.new('license_plate' => 'XYZ9090', 'max_passengers' => 51, :purchased_on => 3.years.ago.to_date),
|
170
|
+
TrModels::Ambulance.new('license_plate' => 'HDD3030', 'icu' => true, :purchased_on => 1.year.ago.to_date)
|
151
171
|
]
|
152
172
|
fleet.save
|
153
173
|
fleet.transports.to_be_replaced.should == [transports[1]]
|
@@ -3,126 +3,153 @@ require 'models'
|
|
3
3
|
|
4
4
|
class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
|
7
|
-
|
6
|
+
@comment_class = EDoc do
|
7
|
+
key :name, String
|
8
|
+
key :body, String
|
9
|
+
end
|
10
|
+
@post_class = Doc do
|
11
|
+
key :title, String
|
12
|
+
end
|
13
|
+
@post_class.many :comments, :class => @comment_class
|
14
|
+
|
15
|
+
@pet_class = EDoc do
|
16
|
+
key :name, String
|
17
|
+
end
|
18
|
+
@pet_class.embedded_in :person
|
19
|
+
@person_class = EDoc do
|
20
|
+
key :name, String
|
21
|
+
end
|
22
|
+
@person_class.key :child, @person_class
|
23
|
+
@person_class.many :pets, :class => @pet_class
|
24
|
+
|
25
|
+
@owner_class = Doc do
|
26
|
+
key :name, String
|
27
|
+
end
|
28
|
+
@owner_class.many :pets, :class => @pet_class
|
8
29
|
end
|
9
30
|
|
10
31
|
should "default reader to empty array" do
|
11
|
-
|
32
|
+
@post_class.new.comments.should == []
|
12
33
|
end
|
13
34
|
|
14
35
|
should "allow adding to association like it was an array" do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
36
|
+
post = @post_class.new
|
37
|
+
post.comments << @comment_class.new
|
38
|
+
post.comments.push @comment_class.new
|
39
|
+
post.comments.size.should == 2
|
19
40
|
end
|
20
41
|
|
21
42
|
should "be embedded in document on save" do
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
43
|
+
frank = @comment_class.new(:name => 'Frank', :body => 'Hi!')
|
44
|
+
bill = @comment_class.new(:name => 'Bill', :body => 'Hi!')
|
45
|
+
post = @post_class.new
|
46
|
+
post.comments << frank
|
47
|
+
post.comments << bill
|
48
|
+
post.save
|
28
49
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
50
|
+
post.reload
|
51
|
+
post.comments.size.should == 2
|
52
|
+
post.comments[0].should == frank
|
53
|
+
post.comments[0].new?.should == false
|
54
|
+
post.comments[1].should == bill
|
55
|
+
post.comments[1].new?.should == false
|
33
56
|
end
|
34
57
|
|
35
58
|
should "allow embedding arbitrarily deep" do
|
36
|
-
@
|
37
|
-
|
38
|
-
set_collection_name 'test'
|
39
|
-
key :person, Person
|
40
|
-
end
|
41
|
-
@document.collection.remove
|
59
|
+
@klass = Doc()
|
60
|
+
@klass.key :person, @person_class
|
42
61
|
|
43
|
-
meg
|
44
|
-
meg.child
|
45
|
-
meg.child.child =
|
62
|
+
meg = @person_class.new(:name => 'Meg')
|
63
|
+
meg.child = @person_class.new(:name => 'Steve')
|
64
|
+
meg.child.child = @person_class.new(:name => 'Linda')
|
46
65
|
|
47
|
-
doc = @
|
66
|
+
doc = @klass.new(:person => meg)
|
48
67
|
doc.save
|
49
|
-
|
50
68
|
doc.reload
|
69
|
+
|
51
70
|
doc.person.name.should == 'Meg'
|
52
71
|
doc.person.child.name.should == 'Steve'
|
53
72
|
doc.person.child.child.name.should == 'Linda'
|
54
73
|
end
|
55
74
|
|
56
|
-
should "allow assignment of
|
75
|
+
should "allow assignment of many embedded documents using a hash" do
|
57
76
|
person_attributes = {
|
58
|
-
|
59
|
-
|
60
|
-
{
|
61
|
-
{
|
77
|
+
'name' => 'Mr. Pet Lover',
|
78
|
+
'pets' => [
|
79
|
+
{'name' => 'Jimmy', 'species' => 'Cocker Spainel'},
|
80
|
+
{'name' => 'Sasha', 'species' => 'Siberian Husky'},
|
62
81
|
]
|
63
82
|
}
|
64
83
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
84
|
+
owner = @owner_class.new(person_attributes)
|
85
|
+
owner.name.should == 'Mr. Pet Lover'
|
86
|
+
owner.pets[0].name.should == 'Jimmy'
|
87
|
+
owner.pets[0].species.should == 'Cocker Spainel'
|
88
|
+
owner.pets[1].name.should == 'Sasha'
|
89
|
+
owner.pets[1].species.should == 'Siberian Husky'
|
90
|
+
|
91
|
+
owner.save.should be_true
|
92
|
+
owner.reload
|
93
|
+
|
94
|
+
owner.name.should == 'Mr. Pet Lover'
|
95
|
+
owner.pets[0].name.should == 'Jimmy'
|
96
|
+
owner.pets[0].species.should == 'Cocker Spainel'
|
97
|
+
owner.pets[1].name.should == 'Sasha'
|
98
|
+
owner.pets[1].species.should == 'Siberian Husky'
|
79
99
|
end
|
80
100
|
|
81
101
|
context "embedding many embedded documents" do
|
82
102
|
setup do
|
83
|
-
@
|
84
|
-
|
85
|
-
set_collection_name 'test'
|
86
|
-
many :people
|
87
|
-
end
|
88
|
-
@document.collection.remove
|
103
|
+
@klass = Doc()
|
104
|
+
@klass.many :people, :class => @person_class
|
89
105
|
end
|
90
106
|
|
91
107
|
should "persist all embedded documents" do
|
92
|
-
meg
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
meg.pets << koda
|
108
|
+
meg = @person_class.new(:name => 'Meg', :pets => [
|
109
|
+
@pet_class.new(:name => 'Sparky', :species => 'Dog'),
|
110
|
+
@pet_class.new(:name => 'Koda', :species => 'Dog')
|
111
|
+
])
|
112
|
+
|
113
|
+
doc = @klass.new
|
99
114
|
doc.people << meg
|
100
115
|
doc.save
|
101
|
-
|
102
116
|
doc.reload
|
103
|
-
|
117
|
+
|
118
|
+
doc.people.first.name.should == 'Meg'
|
104
119
|
doc.people.first.pets.should_not == []
|
105
|
-
doc.people.first.pets.first.name.should ==
|
106
|
-
doc.people.first.pets.first.species.should ==
|
107
|
-
doc.people.first.pets[1].name.should ==
|
108
|
-
doc.people.first.pets[1].species.should ==
|
120
|
+
doc.people.first.pets.first.name.should == 'Sparky'
|
121
|
+
doc.people.first.pets.first.species.should == 'Dog'
|
122
|
+
doc.people.first.pets[1].name.should == 'Koda'
|
123
|
+
doc.people.first.pets[1].species.should == 'Dog'
|
109
124
|
end
|
110
125
|
|
111
126
|
should "create a reference to the root document for all embedded documents before save" do
|
112
|
-
|
113
|
-
|
114
|
-
|
127
|
+
doc = @klass.new
|
128
|
+
meg = @person_class.new(:name => 'Meg')
|
129
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
130
|
+
|
115
131
|
doc.people << meg
|
116
|
-
meg.pets <<
|
132
|
+
meg.pets << pet
|
117
133
|
|
118
134
|
doc.people.first._root_document.should == doc
|
119
135
|
doc.people.first.pets.first._root_document.should == doc
|
120
136
|
end
|
137
|
+
should "create a reference to the owning document for all embedded documents before save" do
|
138
|
+
doc = @klass.new
|
139
|
+
meg = @person_class.new(:name => 'Meg')
|
140
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
141
|
+
|
142
|
+
doc.people << meg
|
143
|
+
meg.pets << pet
|
144
|
+
|
145
|
+
doc.people.first._parent_document.should == doc
|
146
|
+
doc.people.first.pets.first._parent_document.should == doc.people.first
|
147
|
+
end
|
121
148
|
|
122
149
|
should "create a reference to the root document for all embedded documents" do
|
123
|
-
sparky =
|
124
|
-
meg =
|
125
|
-
doc = @
|
150
|
+
sparky = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
151
|
+
meg = @person_class.new(:name => 'Meg', :pets => [sparky])
|
152
|
+
doc = @klass.new
|
126
153
|
doc.people << meg
|
127
154
|
doc.save
|
128
155
|
|
@@ -130,32 +157,69 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
|
130
157
|
doc.people.first._root_document.should == doc
|
131
158
|
doc.people.first.pets.first._root_document.should == doc
|
132
159
|
end
|
160
|
+
should "create a reference to the owning document for all embedded documents" do
|
161
|
+
doc = @klass.new
|
162
|
+
meg = @person_class.new(:name => 'Meg')
|
163
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
164
|
+
|
165
|
+
doc.people << meg
|
166
|
+
meg.pets << pet
|
167
|
+
doc.save
|
168
|
+
|
169
|
+
doc.reload
|
170
|
+
doc.people.first._parent_document.should == doc
|
171
|
+
doc.people.first.pets.first._parent_document.should == doc.people.first
|
172
|
+
end
|
173
|
+
|
174
|
+
should "create embedded_in relationship for embedded docs" do
|
175
|
+
doc = @klass.new
|
176
|
+
meg = @person_class.new(:name => 'Meg')
|
177
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
178
|
+
|
179
|
+
doc.people << meg
|
180
|
+
meg.pets << pet
|
181
|
+
doc.save
|
182
|
+
|
183
|
+
doc.reload
|
184
|
+
doc.people.first.pets.first.person.should == doc.people.first
|
185
|
+
end
|
133
186
|
end
|
134
187
|
|
135
188
|
should "allow finding by id" do
|
136
|
-
sparky =
|
137
|
-
meg =
|
189
|
+
sparky = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
190
|
+
meg = @owner_class.create(:name => 'Meg', :pets => [sparky])
|
138
191
|
|
139
192
|
meg.pets.find(sparky._id).should == sparky # oid
|
140
193
|
meg.pets.find(sparky.id.to_s).should == sparky # string
|
141
194
|
end
|
142
195
|
|
196
|
+
context "count" do
|
197
|
+
should "default to 0" do
|
198
|
+
@owner_class.new.pets.count.should == 0
|
199
|
+
end
|
200
|
+
|
201
|
+
should "return correct count if any are embedded" do
|
202
|
+
owner = @owner_class.new(:name => 'Meg')
|
203
|
+
owner.pets = [@pet_class.new, @pet_class.new]
|
204
|
+
owner.pets.count.should == 2
|
205
|
+
owner.save
|
206
|
+
owner.reload
|
207
|
+
owner.pets.count.should == 2
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
143
211
|
context "extending the association" do
|
144
212
|
setup do
|
145
|
-
@address_class =
|
146
|
-
include MongoMapper::EmbeddedDocument
|
213
|
+
@address_class = EDoc do
|
147
214
|
key :address, String
|
148
215
|
key :city, String
|
149
216
|
key :state, String
|
150
217
|
key :zip, Integer
|
151
218
|
end
|
152
219
|
|
153
|
-
@project_class =
|
154
|
-
include MongoMapper::Document
|
220
|
+
@project_class = Doc do
|
155
221
|
key :name, String
|
156
222
|
end
|
157
|
-
|
158
|
-
@project_class.collection.remove
|
159
223
|
end
|
160
224
|
|
161
225
|
should "work using a block passed to many" do
|