mongo_mapper-unstable 2009.11.8 → 2009.11.18

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 (42) hide show
  1. data/Rakefile +3 -3
  2. data/VERSION +1 -1
  3. data/bin/mmconsole +10 -5
  4. data/lib/mongo_mapper.rb +28 -5
  5. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +1 -1
  6. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +1 -1
  7. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +2 -2
  8. data/lib/mongo_mapper/associations/many_documents_proxy.rb +2 -2
  9. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +2 -1
  10. data/lib/mongo_mapper/document.rb +3 -12
  11. data/lib/mongo_mapper/embedded_document.rb +37 -19
  12. data/lib/mongo_mapper/finder_options.rb +17 -11
  13. data/lib/mongo_mapper/rails_compatibility/document.rb +4 -0
  14. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +4 -0
  15. data/lib/mongo_mapper/serializers/json_serializer.rb +2 -2
  16. data/lib/mongo_mapper/support.rb +16 -44
  17. data/lib/mongo_mapper/types.rb +64 -0
  18. data/lib/mongo_mapper/validations.rb +1 -1
  19. data/mongo_mapper.gemspec +15 -12
  20. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +10 -10
  21. data/test/functional/associations/test_belongs_to_proxy.rb +2 -1
  22. data/test/functional/associations/test_many_documents_as_proxy.rb +13 -12
  23. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +34 -34
  24. data/test/functional/associations/test_many_embedded_proxy.rb +22 -22
  25. data/test/functional/associations/test_many_polymorphic_proxy.rb +10 -10
  26. data/test/functional/associations/test_many_proxy.rb +14 -15
  27. data/test/functional/test_associations.rb +4 -4
  28. data/test/functional/test_binary.rb +1 -1
  29. data/test/functional/test_dirty.rb +6 -6
  30. data/test/functional/test_document.rb +64 -65
  31. data/test/functional/test_embedded_document.rb +34 -14
  32. data/test/functional/test_string_id_compatibility.rb +72 -0
  33. data/test/functional/test_validations.rb +1 -1
  34. data/test/models.rb +24 -24
  35. data/test/unit/test_document.rb +7 -4
  36. data/test/unit/test_embedded_document.rb +47 -5
  37. data/test/unit/test_finder_options.rb +22 -3
  38. data/test/unit/test_mongo_mapper.rb +65 -0
  39. data/test/unit/test_rails_compatibility.rb +14 -0
  40. data/test/unit/test_support.rb +45 -0
  41. metadata +8 -5
  42. data/test/unit/test_mongomapper.rb +0 -28
@@ -28,9 +28,28 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
28
28
  @doc.foo.city.should == 'South Bend'
29
29
  @doc.foo.state.should == 'IN'
30
30
 
31
- from_db = @document.find(@doc.id)
32
- from_db.foo.city.should == 'South Bend'
33
- from_db.foo.state.should == 'IN'
31
+ doc = @doc.reload
32
+ doc.foo.city.should == 'South Bend'
33
+ doc.foo.state.should == 'IN'
34
+ end
35
+ end
36
+
37
+ context "Instantiating single collection inherited embedded documents" do
38
+ setup do
39
+ @document = Class.new do
40
+ include MongoMapper::Document
41
+ key :message, Message
42
+ end
43
+ end
44
+
45
+ should "work" do
46
+ doc1 = @document.create(:message => Enter.new)
47
+ doc2 = @document.create(:message => Exit.new)
48
+ doc3 = @document.create(:message => Chat.new)
49
+
50
+ doc1.reload.message.class.should be(Enter)
51
+ doc2.reload.message.class.should be(Exit)
52
+ doc3.reload.message.class.should be(Chat)
34
53
  end
35
54
  end
36
55
 
@@ -58,8 +77,9 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
58
77
  address = Address.new(:city => 'South Bend', :state => 'IN')
59
78
  doc = @document.new(:foo => address)
60
79
  doc.save
61
- read_doc = @document.find(doc.id)
62
- read_doc.foo.new?.should == false
80
+
81
+ doc = doc.reload
82
+ doc.foo.new?.should == false
63
83
  end
64
84
  end
65
85
 
@@ -71,15 +91,16 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
71
91
  person.pets << pet
72
92
  pet.save
73
93
 
74
- doc = RealPerson.find(person.id)
75
- doc.pets.first.should == pet
94
+ person = person.reload
95
+ person.pets.first.should == pet
76
96
  end
77
97
 
78
98
  should "save new keys" do
79
99
  person = RealPerson.new
80
100
  person[:new_attribute] = 'foobar'
81
101
  person.save
82
- from_db = RealPerson.find(person.id)
102
+
103
+ person = person.reload
83
104
  person.new_attribute.should == 'foobar'
84
105
  end
85
106
  end
@@ -92,14 +113,13 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
92
113
  person.pets << pet
93
114
  pet.save
94
115
 
95
- doc = RealPerson.find(person.id)
96
- pet = doc.pets.first
116
+ person = person.reload
117
+ pet = person.pets.first
97
118
  pet.update_attributes :name => 'koda'
98
119
 
99
- doc = RealPerson.find(person.id)
100
- embedded = doc.pets.first
101
- embedded.id.should == pet.id
102
- embedded.name.should == 'koda'
120
+ person = person.reload
121
+ person.pets.first._id.should == pet._id
122
+ person.pets.first.name.should == 'koda'
103
123
  end
104
124
  end
105
125
  end
@@ -0,0 +1,72 @@
1
+ require 'test_helper'
2
+
3
+ class StringIdCompatibilityTest < Test::Unit::TestCase
4
+ def setup
5
+ @note_class = Class.new do
6
+ include MongoMapper::EmbeddedDocument
7
+ key :_id, String
8
+ end
9
+
10
+ @task_class = Class.new do
11
+ include MongoMapper::Document
12
+ key :_id, String
13
+ key :project_id, String
14
+ belongs_to :project
15
+ end
16
+
17
+ @project_class = Class.new do
18
+ include MongoMapper::Document
19
+ key :_id, String
20
+ end
21
+
22
+ @task_class.belongs_to :project, :class => @project_class
23
+ @project_class.many :notes, :class => @note_class
24
+ @project_class.many :tasks, :class => @task_class, :foreign_key => 'project_id'
25
+
26
+ @project_class.collection.remove
27
+ @task_class.collection.remove
28
+ end
29
+
30
+ should "assign correct _id for documents" do
31
+ project = @project_class.create
32
+ project._id.should == project.id
33
+ project._id.should be_instance_of(String)
34
+ project.id.size.should == 24
35
+ lambda {
36
+ Mongo::ObjectID.from_string(project.id)
37
+ }.should_not raise_error
38
+ end
39
+
40
+ should "assign correct _id for embedded documents" do
41
+ note = @note_class.new
42
+ note.id.should == note._id
43
+ note.id.size.should == 24
44
+ end
45
+
46
+ should "find records" do
47
+ project = @project_class.create
48
+ @project_class.find(project.id).should == project
49
+ end
50
+
51
+ should "save embedded docs" do
52
+ n1 = @note_class.new
53
+ n2 = @note_class.new
54
+ n3 = @note_class.new
55
+ project = @project_class.create(:notes => [n1, n2, n3])
56
+
57
+ project = project.reload
58
+ project.notes.size.should == 3
59
+ project.notes.should == [n1, n2, n3]
60
+ end
61
+
62
+ should "be able to associate records" do
63
+ t1 = @task_class.new(:body => 'First task')
64
+ t2 = @task_class.new(:body => 'Second task')
65
+ t3 = @task_class.new(:body => 'Third task')
66
+ project = @project_class.create(:name => 'MM', :tasks => [t1, t2, t3])
67
+
68
+ project = project.reload
69
+ project.tasks.count.should == 3
70
+ project.tasks.should == [t1, t2, t3]
71
+ end
72
+ end
@@ -93,7 +93,7 @@ class ValidationsTest < Test::Unit::TestCase
93
93
  should "not update document" do
94
94
  @doc.name = nil
95
95
  @doc.save
96
- @document.find(@doc.id).name.should == 'John Nunemaker'
96
+ @doc.reload.name.should == 'John Nunemaker'
97
97
  end
98
98
 
99
99
  should "populate document's errors" do
data/test/models.rb CHANGED
@@ -23,6 +23,12 @@ class WindowSize
23
23
  end
24
24
  end
25
25
 
26
+ module AccountsExtensions
27
+ def inactive
28
+ all(:last_logged_in => nil)
29
+ end
30
+ end
31
+
26
32
  class Post
27
33
  include MongoMapper::Document
28
34
 
@@ -40,7 +46,7 @@ class PostComment
40
46
  key :username, String, :default => 'Anonymous'
41
47
  key :body, String
42
48
 
43
- key :commentable_id, String
49
+ key :commentable_id, ObjectId
44
50
  key :commentable_type, String
45
51
  belongs_to :commentable, :polymorphic => true
46
52
 
@@ -62,7 +68,7 @@ class Message
62
68
  key :body, String
63
69
  key :position, Integer
64
70
  key :_type, String
65
- key :room_id, String
71
+ key :room_id, ObjectId
66
72
 
67
73
  belongs_to :room
68
74
  end
@@ -71,17 +77,25 @@ class Enter < Message; end
71
77
  class Exit < Message; end
72
78
  class Chat < Message; end
73
79
 
74
- module AccountsExtensions
75
- def inactive
76
- all(:last_logged_in => nil)
80
+ class Room
81
+ include MongoMapper::Document
82
+
83
+ key :name, String
84
+ many :messages, :polymorphic => true, :order => 'position' do
85
+ def older
86
+ all(:position => {'$gt' => 5})
87
+ end
77
88
  end
89
+ many :latest_messages, :class_name => 'Message', :order => 'position desc', :limit => 2
90
+
91
+ many :accounts, :polymorphic => true, :extend => AccountsExtensions
78
92
  end
79
93
 
80
94
  class Account
81
95
  include MongoMapper::Document
82
96
 
83
97
  key :_type, String
84
- key :room_id, String
98
+ key :room_id, ObjectId
85
99
  key :last_logged_in, Time
86
100
 
87
101
  belongs_to :room
@@ -89,20 +103,6 @@ end
89
103
  class User < Account; end
90
104
  class Bot < Account; end
91
105
 
92
- class Room
93
- include MongoMapper::Document
94
-
95
- key :name, String
96
- many :messages, :polymorphic => true do
97
- def older
98
- all(:position => {'$gt' => 5})
99
- end
100
- end
101
- many :latest_messages, :class_name => 'Message', :order => 'position desc', :limit => 2
102
-
103
- many :accounts, :polymorphic => true, :extend => AccountsExtensions
104
- end
105
-
106
106
  class Answer
107
107
  include MongoMapper::Document
108
108
 
@@ -145,7 +145,7 @@ end
145
145
 
146
146
  class Collaborator
147
147
  include MongoMapper::Document
148
- key :project_id, String
148
+ key :project_id, ObjectId
149
149
  key :name, String
150
150
  belongs_to :project
151
151
  end
@@ -153,8 +153,8 @@ end
153
153
  class Status
154
154
  include MongoMapper::Document
155
155
 
156
- key :project_id, String
157
- key :target_id, String
156
+ key :project_id, ObjectId
157
+ key :target_id, ObjectId
158
158
  key :target_type, String
159
159
  key :name, String, :required => true
160
160
  key :position, Integer
@@ -166,7 +166,7 @@ end
166
166
  class RealPerson
167
167
  include MongoMapper::Document
168
168
 
169
- key :room_id, String
169
+ key :room_id, ObjectId
170
170
  key :name, String
171
171
 
172
172
  belongs_to :room
@@ -157,6 +157,7 @@ class DocumentTest < Test::Unit::TestCase
157
157
  end
158
158
 
159
159
  should "be true if id but using custom id and not saved yet" do
160
+ @document.key :_id, String
160
161
  doc = @document.new
161
162
  doc.id = '1234'
162
163
  doc.new?.should be_true
@@ -178,14 +179,16 @@ class DocumentTest < Test::Unit::TestCase
178
179
  end
179
180
  end
180
181
 
181
-
182
182
  context "equality" do
183
+ setup do
184
+ @oid = Mongo::ObjectID.new
185
+ end
183
186
  should "be equal if id and class are the same" do
184
- (@document.new('_id' => 1) == @document.new('_id' => 1)).should be(true)
187
+ (@document.new('_id' => @oid) == @document.new('_id' => @oid)).should be(true)
185
188
  end
186
189
 
187
190
  should "not be equal if class same but id different" do
188
- (@document.new('_id' => 1) == @document.new('_id' => 2)).should be(false)
191
+ (@document.new('_id' => @oid) == @document.new('_id' => Mongo::ObjectID.new)).should be(false)
189
192
  end
190
193
 
191
194
  should "not be equal if id same but class different" do
@@ -194,7 +197,7 @@ class DocumentTest < Test::Unit::TestCase
194
197
  set_collection_name 'test'
195
198
  end
196
199
 
197
- (@document.new('_id' => 1) == @another_document.new('_id' => 1)).should be(false)
200
+ (@document.new('_id' => @oid) == @another_document.new('_id' => @oid)).should be(false)
198
201
  end
199
202
  end
200
203
  end # instance of a document
@@ -49,6 +49,15 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
49
49
  @klass.keys['_id'].should_not be_nil
50
50
  end
51
51
 
52
+ should "know it is using object id" do
53
+ @klass.using_object_id?.should be_true
54
+ end
55
+
56
+ should "know it is not using object id if _id type is changed" do
57
+ @klass.key :_id, String
58
+ @klass.using_object_id?.should be_false
59
+ end
60
+
52
61
  context "#to_mongo" do
53
62
  should "be nil if nil" do
54
63
  @klass.to_mongo(nil).should be_nil
@@ -80,6 +89,15 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
80
89
  end
81
90
  end
82
91
 
92
+ context "looking up type constants" do
93
+ should "not raise an error" do
94
+ klass = Class.new do
95
+ include MongoMapper::EmbeddedDocument
96
+ key :file, Binary
97
+ end
98
+ end
99
+ end
100
+
83
101
  context "parent_model" do
84
102
  should "be nil if none of parents ancestors include EmbeddedDocument" do
85
103
  parent = Class.new
@@ -150,11 +168,11 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
150
168
  @document.keys['age'].type.should == Integer
151
169
  end
152
170
 
153
- should "not be redefinable" do
171
+ should "be redefinable" do
154
172
  @document.key(:foo, String)
155
173
  @document.keys['foo'].type.should == String
156
174
  @document.key(:foo, Integer)
157
- @document.keys['foo'].type.should == String
175
+ @document.keys['foo'].type.should == Integer
158
176
  end
159
177
 
160
178
  should "create reader method" do
@@ -292,6 +310,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
292
310
  should "have to_param that is id" do
293
311
  doc = @document.new
294
312
  doc.to_param.should == doc.id
313
+ doc.to_param.should be_instance_of(String)
295
314
  end
296
315
 
297
316
  should "have access to class logger" do
@@ -308,6 +327,24 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
308
327
  doc = @document.new
309
328
  doc.id.should == doc._id.to_s
310
329
  end
330
+
331
+ context "assigning id with _id ObjectId type" do
332
+ should "not set custom id flag" do
333
+ doc = @document.new
334
+ doc.using_custom_id?.should be_false
335
+ doc.id = Mongo::ObjectID.new
336
+ doc.using_custom_id?.should be_false
337
+ end
338
+
339
+ should "convert string object id to mongo object id" do
340
+ id = Mongo::ObjectID.new
341
+ doc = @document.new
342
+ doc.id = id.to_s
343
+ doc._id.should == id
344
+ doc.id.should == id.to_s
345
+ doc.using_custom_id?.should be_false
346
+ end
347
+ end
311
348
 
312
349
  should "have a nil _root_document" do
313
350
  @document.new._root_document.should be_nil
@@ -315,11 +352,13 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
315
352
 
316
353
  context "setting custom id" do
317
354
  should "set _id" do
355
+ @document.key :_id, String
318
356
  doc = @document.new(:id => '1234')
319
357
  doc._id.should == '1234'
320
358
  end
321
359
 
322
360
  should "know that custom id is set" do
361
+ @document.key :_id, String
323
362
  doc = @document.new
324
363
  doc.using_custom_id?.should be_false
325
364
  doc.id = '1234'
@@ -656,12 +695,15 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
656
695
  end
657
696
 
658
697
  context "equality" do
698
+ setup do
699
+ @oid = Mongo::ObjectID.new
700
+ end
659
701
  should "be equal if id and class are the same" do
660
- (@document.new('_id' => 1) == @document.new('_id' => 1)).should be(true)
702
+ (@document.new('_id' => @oid) == @document.new('_id' => @oid)).should be(true)
661
703
  end
662
704
 
663
705
  should "not be equal if class same but id different" do
664
- (@document.new('_id' => 1) == @document.new('_id' => 2)).should be(false)
706
+ (@document.new('_id' => @oid) == @document.new('_id' => Mongo::ObjectID.new)).should be(false)
665
707
  end
666
708
 
667
709
  should "not be equal if id same but class different" do
@@ -669,7 +711,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
669
711
  include MongoMapper::Document
670
712
  end
671
713
 
672
- (@document.new('_id' => 1) == @another_document.new('_id' => 1)).should be(false)
714
+ (@document.new('_id' => @oid) == @another_document.new('_id' => @oid)).should be(false)
673
715
  end
674
716
  end
675
717
  end # instance of a embedded document
@@ -57,9 +57,28 @@ class FinderOptionsTest < Test::Unit::TestCase
57
57
  end
58
58
 
59
59
  should "convert id to _id" do
60
- FinderOptions.new(Room, :id => '1').criteria.should == {
61
- :_id => '1'
62
- }
60
+ id = Mongo::ObjectID.new
61
+ FinderOptions.new(Room, :id => id).criteria.should == {:_id => id}
62
+ end
63
+
64
+ should "make sure that _id's are object ids" do
65
+ id = Mongo::ObjectID.new
66
+ FinderOptions.new(Room, :_id => id.to_s).criteria.should == {:_id => id}
67
+ end
68
+
69
+ should "work fine with _id's that are object ids" do
70
+ id = Mongo::ObjectID.new
71
+ FinderOptions.new(Room, :_id => id).criteria.should == {:_id => id}
72
+ end
73
+
74
+ should "make sure other object id typed keys get converted" do
75
+ id = Mongo::ObjectID.new
76
+ FinderOptions.new(Message, :room_id => id.to_s).criteria.should == {:room_id => id}
77
+ end
78
+
79
+ should "work fine with object ids for object id typed keys" do
80
+ id = Mongo::ObjectID.new
81
+ FinderOptions.new(Message, :room_id => id).criteria.should == {:room_id => id}
63
82
  end
64
83
 
65
84
  should "use $in for arrays" do