mongo_mapper-unstable 2009.11.8 → 2009.11.18

Sign up to get free protection for your applications and to get access to all the features.
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