mongo_mapper-unstable 2010.1.6 → 2010.1.12

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 (86) hide show
  1. data/VERSION +1 -1
  2. data/lib/mongo_mapper/descendant_appends.rb +44 -0
  3. data/lib/mongo_mapper/document.rb +54 -98
  4. data/lib/mongo_mapper/embedded_document.rb +28 -348
  5. data/lib/mongo_mapper/finder_options.rb +15 -33
  6. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  7. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +28 -0
  8. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +23 -0
  9. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  10. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +49 -0
  11. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  12. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  13. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  14. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  15. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  16. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  17. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +66 -0
  18. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  19. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  20. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  21. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  22. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  23. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  24. data/lib/mongo_mapper/plugins/equality.rb +11 -0
  25. data/lib/mongo_mapper/plugins/identity_map.rb +66 -0
  26. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  27. data/lib/mongo_mapper/plugins/keys.rb +295 -0
  28. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  29. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  30. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  31. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  32. data/lib/mongo_mapper/plugins/validations.rb +48 -0
  33. data/lib/mongo_mapper/plugins.rb +19 -0
  34. data/lib/mongo_mapper/support.rb +36 -15
  35. data/lib/mongo_mapper.rb +23 -22
  36. data/performance/read_write.rb +52 -0
  37. data/specs.watchr +23 -2
  38. data/test/functional/associations/test_belongs_to_proxy.rb +1 -1
  39. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +58 -39
  40. data/test/functional/associations/test_many_embedded_proxy.rb +103 -69
  41. data/test/functional/test_dirty.rb +1 -1
  42. data/test/functional/test_document.rb +25 -25
  43. data/test/functional/test_embedded_document.rb +66 -63
  44. data/test/functional/test_identity_map.rb +233 -0
  45. data/test/functional/test_modifiers.rb +14 -0
  46. data/test/functional/test_string_id_compatibility.rb +4 -4
  47. data/test/functional/test_validations.rb +13 -0
  48. data/test/models.rb +0 -39
  49. data/test/test_helper.rb +8 -2
  50. data/test/unit/associations/test_base.rb +1 -1
  51. data/test/unit/associations/test_proxy.rb +3 -3
  52. data/test/unit/test_descendant_appends.rb +71 -0
  53. data/test/unit/test_document.rb +35 -46
  54. data/test/unit/test_embedded_document.rb +218 -271
  55. data/test/unit/{test_key.rb → test_keys.rb} +0 -0
  56. data/test/unit/test_pagination.rb +10 -2
  57. data/test/unit/test_plugins.rb +42 -0
  58. data/test/unit/test_rails.rb +123 -0
  59. data/test/unit/{test_serializations.rb → test_serialization.rb} +0 -0
  60. data/test/unit/test_support.rb +10 -6
  61. data/test/unit/test_time_zones.rb +2 -2
  62. metadata +44 -31
  63. data/lib/mongo_mapper/associations/base.rb +0 -119
  64. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +0 -26
  65. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +0 -21
  66. data/lib/mongo_mapper/associations/collection.rb +0 -19
  67. data/lib/mongo_mapper/associations/in_array_proxy.rb +0 -137
  68. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -26
  69. data/lib/mongo_mapper/associations/many_documents_proxy.rb +0 -115
  70. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +0 -31
  71. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +0 -54
  72. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +0 -11
  73. data/lib/mongo_mapper/associations/one_proxy.rb +0 -64
  74. data/lib/mongo_mapper/associations/proxy.rb +0 -116
  75. data/lib/mongo_mapper/associations.rb +0 -78
  76. data/lib/mongo_mapper/callbacks.rb +0 -61
  77. data/lib/mongo_mapper/dirty.rb +0 -117
  78. data/lib/mongo_mapper/key.rb +0 -36
  79. data/lib/mongo_mapper/mongo_mapper.rb +0 -125
  80. data/lib/mongo_mapper/pagination.rb +0 -66
  81. data/lib/mongo_mapper/rails_compatibility/document.rb +0 -15
  82. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +0 -28
  83. data/lib/mongo_mapper/serialization.rb +0 -54
  84. data/lib/mongo_mapper/serializers/json_serializer.rb +0 -48
  85. data/lib/mongo_mapper/validations.rb +0 -39
  86. data/test/functional/test_rails_compatibility.rb +0 -25
@@ -593,7 +593,15 @@ class DocumentTest < Test::Unit::TestCase
593
593
  end
594
594
 
595
595
  should "allow to use custom methods to assign properties" do
596
- person = RealPerson.new(:realname => 'David')
596
+ klass = Doc do
597
+ key :name, String
598
+
599
+ def realname=(value)
600
+ self.name = value
601
+ end
602
+ end
603
+
604
+ person = klass.new(:realname => 'David')
597
605
  person.save
598
606
  person.reload.name.should == 'David'
599
607
  end
@@ -713,17 +721,12 @@ class DocumentTest < Test::Unit::TestCase
713
721
  end
714
722
  end
715
723
 
716
- should "insert document" do
724
+ should "insert invalid document" do
717
725
  doc = @document.new
726
+ doc.expects(:valid?).never
718
727
  doc.save(:validate => false)
719
728
  @document.count.should == 1
720
729
  end
721
-
722
- should "work with false passed to save" do
723
- doc = @document.new
724
- doc.save(false)
725
- @document.count.should == 1
726
- end
727
730
  end
728
731
 
729
732
  context "#save (with options)" do
@@ -956,11 +959,19 @@ class DocumentTest < Test::Unit::TestCase
956
959
 
957
960
  context "timestamping" do
958
961
  setup do
959
- @document.timestamps!
962
+ @klass = Doc do
963
+ set_collection_name 'users'
964
+
965
+ key :first_name, String
966
+ key :last_name, String
967
+ key :age, Integer
968
+ key :date, Date
969
+ end
970
+ @klass.timestamps!
960
971
  end
961
972
 
962
973
  should "set created_at and updated_at on create" do
963
- doc = @document.new(:first_name => 'John', :age => 27)
974
+ doc = @klass.new(:first_name => 'John', :age => 27)
964
975
  doc.created_at.should be(nil)
965
976
  doc.updated_at.should be(nil)
966
977
  doc.save
@@ -970,7 +981,7 @@ class DocumentTest < Test::Unit::TestCase
970
981
 
971
982
  should "not overwrite created_at if it already exists" do
972
983
  original_created_at = 1.month.ago
973
- doc = @document.new(:first_name => 'John', :age => 27, :created_at => original_created_at)
984
+ doc = @klass.new(:first_name => 'John', :age => 27, :created_at => original_created_at)
974
985
  doc.created_at.to_i.should == original_created_at.to_i
975
986
  doc.updated_at.should be_nil
976
987
  doc.save
@@ -979,7 +990,7 @@ class DocumentTest < Test::Unit::TestCase
979
990
  end
980
991
 
981
992
  should "set updated_at on field update but leave created_at alone" do
982
- doc = @document.create(:first_name => 'John', :age => 27)
993
+ doc = @klass.create(:first_name => 'John', :age => 27)
983
994
  old_created_at = doc.created_at
984
995
  old_updated_at = doc.updated_at
985
996
  doc.first_name = 'Johnny'
@@ -993,12 +1004,12 @@ class DocumentTest < Test::Unit::TestCase
993
1004
  end
994
1005
 
995
1006
  should "set updated_at on document update but leave created_at alone" do
996
- doc = @document.create(:first_name => 'John', :age => 27)
1007
+ doc = @klass.create(:first_name => 'John', :age => 27)
997
1008
  old_created_at = doc.created_at
998
1009
  old_updated_at = doc.updated_at
999
1010
 
1000
1011
  Timecop.freeze(Time.now + 5.seconds) do
1001
- @document.update(doc._id, { :first_name => 'Johnny' })
1012
+ @klass.update(doc._id, { :first_name => 'Johnny' })
1002
1013
  end
1003
1014
 
1004
1015
  doc = doc.reload
@@ -1094,16 +1105,6 @@ class DocumentTest < Test::Unit::TestCase
1094
1105
  @instance.reload.object_id.should == @instance.object_id
1095
1106
  end
1096
1107
  end
1097
-
1098
- context "Saving a document with a custom id" do
1099
- should "clear custom id flag when saved" do
1100
- @document.key :_id, String
1101
- doc = @document.new(:id => '1234')
1102
- doc.using_custom_id?.should be_true
1103
- doc.save.should be_true
1104
- doc.using_custom_id?.should be_false
1105
- end
1106
- end
1107
1108
 
1108
1109
  context "Loading a document from the database with keys that are not defined" do
1109
1110
  setup do
@@ -1164,7 +1165,6 @@ class DocumentTest < Test::Unit::TestCase
1164
1165
  should "work with :index shortcut when defining key" do
1165
1166
  @document.key :father, String, :index => true
1166
1167
  MongoMapper.ensure_indexes!
1167
-
1168
1168
  @document.should have_index('father_1')
1169
1169
  end
1170
1170
  end
@@ -3,21 +3,29 @@ require 'models'
3
3
 
4
4
  class EmbeddedDocumentTest < Test::Unit::TestCase
5
5
  def setup
6
- @document = Doc do
7
- set_collection_name 'users'
6
+ @klass = Doc do
8
7
  key :first_name, String
9
8
  key :last_name, String
10
9
  end
10
+
11
+ @pet_klass = EDoc do
12
+ key :name, String
13
+ end
14
+
15
+ @klass.many :pets, :class => @pet_klass
16
+
17
+ @address_class = EDoc do
18
+ key :city, String
19
+ key :state, String
20
+ end
11
21
  end
12
22
 
13
23
  context "Saving a document with an embedded document" do
14
24
  setup do
15
- @document.class_eval do
16
- key :foo, Address
17
- end
25
+ @klass.key :foo, @address_class
18
26
 
19
- @address = Address.new(:city => 'South Bend', :state => 'IN')
20
- @doc = @document.new(:foo => @address)
27
+ @address = @address_class.new(:city => 'South Bend', :state => 'IN')
28
+ @doc = @klass.new(:foo => @address)
21
29
  end
22
30
 
23
31
  should "embed embedded document" do
@@ -42,27 +50,25 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
42
50
 
43
51
  context "new?" do
44
52
  setup do
45
- @document.class_eval do
46
- key :foo, Address
47
- end
53
+ @klass.key :foo, @address_class
48
54
  end
49
55
 
50
56
  should "be new until document is saved" do
51
- address = Address.new(:city => 'South Bend', :state => 'IN')
52
- doc = @document.new(:foo => address)
57
+ address = @address_class.new(:city => 'South Bend', :state => 'IN')
58
+ doc = @klass.new(:foo => address)
53
59
  address.new?.should == true
54
60
  end
55
61
 
56
62
  should "not be new after document is saved" do
57
- address = Address.new(:city => 'South Bend', :state => 'IN')
58
- doc = @document.new(:foo => address)
63
+ address = @address_class.new(:city => 'South Bend', :state => 'IN')
64
+ doc = @klass.new(:foo => address)
59
65
  doc.save
60
66
  doc.foo.new?.should == false
61
67
  end
62
68
 
63
69
  should "not be new when document is read back" do
64
- address = Address.new(:city => 'South Bend', :state => 'IN')
65
- doc = @document.new(:foo => address)
70
+ address = @address_class.new(:city => 'South Bend', :state => 'IN')
71
+ doc = @klass.new(:foo => address)
66
72
  doc.save
67
73
 
68
74
  doc = doc.reload
@@ -70,53 +76,50 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
70
76
  end
71
77
  end
72
78
 
73
- context "save" do
74
- should "save the root document" do
75
- person = RealPerson.create
76
-
77
- pet = Pet.new :name => 'sparky'
78
- person.pets << pet
79
- pet.save
80
-
81
- person = person.reload
82
- person.pets.first.should == pet
83
- end
79
+ should "be able to save" do
80
+ person = @klass.create
84
81
 
85
- should "save new keys" do
86
- person = RealPerson.new
87
- person[:new_attribute] = 'foobar'
88
- person.save
89
-
90
- person = person.reload
91
- person.new_attribute.should == 'foobar'
92
- end
82
+ pet = @pet_klass.new(:name => 'sparky')
83
+ person.pets << pet
84
+ pet.should be_new
85
+ pet.save
86
+ pet.should_not be_new
87
+
88
+ person.reload
89
+ person.pets.first.should == pet
93
90
  end
94
91
 
95
- context "update_attributes" do
96
- should "save the root document" do
97
- person = RealPerson.create
98
-
99
- pet = Pet.new(:name => 'sparky')
100
- person.pets << pet
101
- pet.save
102
-
103
- person = person.reload
104
- pet = person.pets.first
105
- pet.update_attributes :name => 'koda'
106
-
107
- person = person.reload
108
- person.pets.first._id.should == pet._id
109
- person.pets.first.name.should == 'koda'
110
- end
111
- end
112
-
113
- context "update_attributes!" do
114
- should "pass the attributes to self.attributes" do
115
- person = RealPerson.create
116
- attributes = { :foo => 'bar' }
117
- person.expects(:attributes=).with(attributes)
118
- person.expects(:save!)
119
- person.update_attributes!(attributes)
120
- end
121
- end
122
- end
92
+ should "be able to dynamically add new keys and save" do
93
+ person = @klass.create
94
+
95
+ pet = @pet_klass.new(:name => 'sparky', :crazy_key => 'crazy')
96
+ person.pets << pet
97
+ pet.save
98
+
99
+ person.reload
100
+ person.pets.first.crazy_key.should == 'crazy'
101
+ end
102
+
103
+ should "be able to update_attributes" do
104
+ pet = @pet_klass.new(:name => 'sparky')
105
+ person = @klass.create(:pets => [pet])
106
+ person.reload
107
+ pet = person.pets.first
108
+
109
+ pet.update_attributes(:name => 'koda').should be_true
110
+ person.reload
111
+ person.pets.first._id.should == pet._id
112
+ person.pets.first.name.should == 'koda'
113
+ end
114
+
115
+ should "be able to update_attributes!" do
116
+ person = @klass.create(:pets => [@pet_klass.new(:name => 'sparky')])
117
+ person.reload
118
+ pet = person.pets.first
119
+
120
+ attributes = {:name => 'koda'}
121
+ pet.expects(:attributes=).with(attributes)
122
+ pet.expects(:save!)
123
+ pet.update_attributes!(attributes)
124
+ end
125
+ end
@@ -0,0 +1,233 @@
1
+ require 'test_helper'
2
+
3
+ class IdentityMapTest < Test::Unit::TestCase
4
+ def assert_in_map(resource)
5
+ resource.identity_map.keys.should include(resource.identity_map_key)
6
+ mapped_resource = resource.identity_map[resource.identity_map_key]
7
+ resource.object_id.should == mapped_resource.object_id
8
+ end
9
+
10
+ def assert_not_in_map(resource)
11
+ resource.identity_map.keys.should_not include(resource.identity_map_key)
12
+ end
13
+
14
+ context "Document" do
15
+ setup do
16
+ @person_class = Doc('Person') do
17
+ key :name, String
18
+ plugin MongoMapper::Plugins::IdentityMap
19
+ end
20
+
21
+ @post_class = Doc('Post') do
22
+ key :title, String
23
+ plugin MongoMapper::Plugins::IdentityMap
24
+ end
25
+
26
+ @person_class.identity_map = {}
27
+ @post_class.identity_map = {}
28
+ end
29
+
30
+ should "default identity map to hash" do
31
+ Doc() do
32
+ plugin MongoMapper::Plugins::IdentityMap
33
+ end.identity_map.should == {}
34
+ end
35
+
36
+ should "share identity map with other classes" do
37
+ map = @post_class.identity_map
38
+ map.object_id.should == @person_class.identity_map.object_id
39
+ end
40
+
41
+ should "have identity map key that is always unique per document and class" do
42
+ person = @person_class.new
43
+ person.identity_map_key.should == "Person:#{person.id}"
44
+ @person_class.identity_map_key(person.id).should == person.identity_map_key
45
+
46
+ post = @post_class.new
47
+ post.identity_map_key.should == "Post:#{post.id}"
48
+ @post_class.identity_map_key(post.id).should == post.identity_map_key
49
+
50
+ person.identity_map_key.should_not == post.identity_map_key
51
+ end
52
+
53
+ should "add key to map when saved" do
54
+ person = @person_class.new
55
+ assert_not_in_map(person)
56
+ person.save.should be_true
57
+ assert_in_map(person)
58
+ end
59
+
60
+ should "remove key from map when deleted" do
61
+ person = @person_class.create(:name => 'Fred')
62
+ assert_in_map(person)
63
+ person.destroy
64
+ assert_not_in_map(person)
65
+ end
66
+
67
+ context "#load" do
68
+ setup do
69
+ @id = Mongo::ObjectID.new
70
+ end
71
+
72
+ should "add document to map with _id key as symbol" do
73
+ loaded = @person_class.load({:_id => @id, :name => 'Frank'})
74
+ assert_in_map(loaded)
75
+ end
76
+
77
+ should "add document to map with _id key as string" do
78
+ loaded = @person_class.load({'_id' => @id, :name => 'Frank'})
79
+ assert_in_map(loaded)
80
+ end
81
+
82
+ should "add document to map with id key as symbol" do
83
+ loaded = @person_class.load({:id => @id, :name => 'Frank'})
84
+ assert_in_map(loaded)
85
+ end
86
+
87
+ should "add document to map with id key as string" do
88
+ loaded = @person_class.load({'id' => @id, :name => 'Frank'})
89
+ assert_in_map(loaded)
90
+ end
91
+
92
+ should "return document if already in map" do
93
+ first_load = @person_class.load({:_id => @id, :name => 'Frank'})
94
+ @person_class.identity_map.expects(:[]=).never
95
+ second_load = @person_class.load({:_id => @id, :name => 'Frank'})
96
+ first_load.object_id.should == second_load.object_id
97
+ end
98
+ end
99
+
100
+ context "#find (with one id)" do
101
+ context "for object not in map" do
102
+ setup do
103
+ @person = @person_class.create(:name => 'Fred')
104
+ @person_class.identity_map.clear
105
+ end
106
+
107
+ should "query the database" do
108
+ Mongo::Collection.any_instance.expects(:find_one).once
109
+ @person_class.find(@person.id)
110
+ end
111
+
112
+ should "add object to map" do
113
+ assert_not_in_map(@person)
114
+ found_person = @person_class.find(@person.id)
115
+ assert_in_map(found_person)
116
+ end
117
+ end
118
+
119
+ context "for object in map" do
120
+ setup do
121
+ @person = @person_class.create(:name => 'Fred')
122
+ end
123
+
124
+ should "not query database" do
125
+ Mongo::Collection.any_instance.expects(:find).never
126
+ Mongo::Collection.any_instance.expects(:find_one).never
127
+ @person_class.find(@person.id)
128
+ end
129
+
130
+ should "return exact object" do
131
+ assert_in_map(@person)
132
+ found_person = @person_class.find(@person.id)
133
+ found_person.object_id.should == @person.object_id
134
+ end
135
+ end
136
+ end
137
+
138
+ context "#find (with multiple ids)" do
139
+ should "add all documents to map" do
140
+ person1 = @person_class.create(:name => 'Fred')
141
+ person2 = @person_class.create(:name => 'Bill')
142
+ person3 = @person_class.create(:name => 'Jesse')
143
+ @person_class.identity_map.clear
144
+
145
+ people = @person_class.find(person1.id, person2.id, person3.id)
146
+ people.each { |person| assert_in_map(person) }
147
+ end
148
+
149
+ should "add missing documents to map and return existing ones" do
150
+ person1 = @person_class.create(:name => 'Fred')
151
+ @person_class.identity_map.clear
152
+ person2 = @person_class.create(:name => 'Bill')
153
+ person3 = @person_class.create(:name => 'Jesse')
154
+
155
+ assert_not_in_map(person1)
156
+ assert_in_map(person2)
157
+ assert_in_map(person3)
158
+
159
+ people = @person_class.find(person1.id, person2.id, person3.id)
160
+ assert_in_map(people.first) # making sure one that wasn't mapped now is
161
+ assert_in_map(person2)
162
+ assert_in_map(person3)
163
+ end
164
+ end
165
+
166
+ context "#first" do
167
+ context "for object not in map" do
168
+ setup do
169
+ @person = @person_class.create(:name => 'Fred')
170
+ @person_class.identity_map.clear
171
+ end
172
+
173
+ should "query the database" do
174
+ Mongo::Collection.any_instance.expects(:find_one).once
175
+ @person_class.first(:_id => @person.id)
176
+ end
177
+
178
+ should "add object to map" do
179
+ assert_not_in_map(@person)
180
+ found_person = @person_class.first(:_id => @person.id)
181
+ assert_in_map(found_person)
182
+ end
183
+ end
184
+
185
+ context "for object in map" do
186
+ setup do
187
+ @person = @person_class.create(:name => 'Fred')
188
+ end
189
+
190
+ should "not query database" do
191
+ Mongo::Collection.any_instance.expects(:find).never
192
+ Mongo::Collection.any_instance.expects(:find_one).never
193
+ @person_class.first(:_id => @person.id)
194
+ end
195
+
196
+ should "return exact object" do
197
+ assert_in_map(@person)
198
+ found_person = @person_class.first(:_id => @person.id)
199
+ found_person.object_id.should == @person.object_id
200
+ end
201
+ end
202
+ end
203
+
204
+ context "#all" do
205
+ should "add all documents to map" do
206
+ person1 = @person_class.create(:name => 'Fred')
207
+ person2 = @person_class.create(:name => 'Bill')
208
+ person3 = @person_class.create(:name => 'Jesse')
209
+ @person_class.identity_map.clear
210
+
211
+ people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
212
+ people.each { |person| assert_in_map(person) }
213
+ end
214
+
215
+ should "add missing documents to map and return existing ones" do
216
+ person1 = @person_class.create(:name => 'Fred')
217
+ @person_class.identity_map.clear
218
+ person2 = @person_class.create(:name => 'Bill')
219
+ person3 = @person_class.create(:name => 'Jesse')
220
+
221
+ assert_not_in_map(person1)
222
+ assert_in_map(person2)
223
+ assert_in_map(person3)
224
+
225
+ people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
226
+ assert_in_map(people.first) # making sure one that wasn't mapped now is
227
+ assert_in_map(person2)
228
+ assert_in_map(person3)
229
+ end
230
+ end
231
+
232
+ end
233
+ end
@@ -235,4 +235,18 @@ class ModifierTest < Test::Unit::TestCase
235
235
  page2.reload
236
236
  page.tags.should == %w(foo)
237
237
  end
238
+
239
+ should "be able to remove the last element the array" do
240
+ page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
241
+ @page_class.pop(page.id, :tags => 1)
242
+ page.reload
243
+ page.tags.should == %w(foo)
244
+ end
245
+
246
+ should "be able to remove the first element of the array" do
247
+ page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
248
+ @page_class.pop(page.id, :tags => -1)
249
+ page.reload
250
+ page.tags.should == %w(bar)
251
+ end
238
252
  end
@@ -19,7 +19,7 @@ class StringIdCompatibilityTest < Test::Unit::TestCase
19
19
 
20
20
  @task_class.belongs_to :project, :class => @project_class
21
21
  @project_class.many :notes, :class => @note_class
22
- @project_class.many :tasks, :class => @task_class, :foreign_key => 'project_id'
22
+ @project_class.many :tasks, :class => @task_class, :foreign_key => 'project_id', :order => :position.asc
23
23
  end
24
24
 
25
25
  should "assign correct _id for documents" do
@@ -55,9 +55,9 @@ class StringIdCompatibilityTest < Test::Unit::TestCase
55
55
  end
56
56
 
57
57
  should "be able to associate records" do
58
- t1 = @task_class.new(:body => 'First task')
59
- t2 = @task_class.new(:body => 'Second task')
60
- t3 = @task_class.new(:body => 'Third task')
58
+ t1 = @task_class.new(:body => 'First task', :position => 1)
59
+ t2 = @task_class.new(:body => 'Second task', :position => 2)
60
+ t3 = @task_class.new(:body => 'Third task', :position => 3)
61
61
  project = @project_class.create(:name => 'MM', :tasks => [t1, t2, t3])
62
62
 
63
63
  project = project.reload
@@ -186,6 +186,19 @@ class ValidationsTest < Test::Unit::TestCase
186
186
  doc2.should_not have_error_on(:name)
187
187
  end
188
188
 
189
+ should "allow multiple nil entries if :allow_nil => true" do
190
+ document = Doc do
191
+ key :name
192
+ validates_uniqueness_of :name, :allow_nil => :true
193
+ end
194
+
195
+ doc = document.new('name' => nil)
196
+ doc.save.should be_true
197
+
198
+ doc2 = document.new('name' => nil)
199
+ doc2.should_not have_error_on(:name)
200
+ end
201
+
189
202
  should "allow entries that differ only in case by default" do
190
203
  document = Doc do
191
204
  key :name
data/test/models.rb CHANGED
@@ -109,12 +109,6 @@ class Answer
109
109
  key :body, String
110
110
  end
111
111
 
112
- module PeopleExtensions
113
- def find_by_name(name)
114
- detect { |p| p.name == name }
115
- end
116
- end
117
-
118
112
  module CollaboratorsExtensions
119
113
  def top
120
114
  first
@@ -126,9 +120,7 @@ class Project
126
120
 
127
121
  key :name, String
128
122
 
129
- many :people, :extend => PeopleExtensions
130
123
  many :collaborators, :extend => CollaboratorsExtensions
131
-
132
124
  many :statuses, :order => 'position' do
133
125
  def open
134
126
  all(:name => %w(New Assigned))
@@ -163,37 +155,6 @@ class Status
163
155
  belongs_to :target, :polymorphic => true
164
156
  end
165
157
 
166
- class RealPerson
167
- include MongoMapper::Document
168
-
169
- key :room_id, ObjectId
170
- key :name, String
171
-
172
- belongs_to :room
173
-
174
- many :pets
175
-
176
- def realname=(n)
177
- self.name = n
178
- end
179
- end
180
-
181
- class Person
182
- include MongoMapper::EmbeddedDocument
183
-
184
- key :name, String
185
- key :child, Person
186
-
187
- many :pets
188
- end
189
-
190
- class Pet
191
- include MongoMapper::EmbeddedDocument
192
-
193
- key :name, String
194
- key :species, String
195
- end
196
-
197
158
  class Media
198
159
  include MongoMapper::EmbeddedDocument
199
160
 
data/test/test_helper.rb CHANGED
@@ -38,10 +38,16 @@ class Test::Unit::TestCase
38
38
  klass
39
39
  end
40
40
 
41
- def EDoc(&block)
41
+ def EDoc(name=nil, &block)
42
42
  Class.new do
43
43
  include MongoMapper::EmbeddedDocument
44
- instance_eval(&block) if block_given?
44
+
45
+ if name
46
+ class_eval "def self.name; '#{name}' end"
47
+ class_eval "def self.to_s; '#{name}' end"
48
+ end
49
+
50
+ class_eval(&block) if block_given?
45
51
  end
46
52
  end
47
53
  end
@@ -4,7 +4,7 @@ require 'models'
4
4
  class FooMonster; end
5
5
 
6
6
  class AssociationBaseTest < Test::Unit::TestCase
7
- include MongoMapper::Associations
7
+ include MongoMapper::Plugins::Associations
8
8
 
9
9
  should "initialize with type and name" do
10
10
  base = Base.new(:many, :foos)
@@ -1,14 +1,14 @@
1
1
  require 'test_helper'
2
2
 
3
- class FakeNilProxy < MongoMapper::Associations::Proxy
3
+ class FakeNilProxy < MongoMapper::Plugins::Associations::Proxy
4
4
  def find_target; nil end
5
5
  end
6
6
 
7
- class FakeBlankProxy < MongoMapper::Associations::Proxy
7
+ class FakeBlankProxy < MongoMapper::Plugins::Associations::Proxy
8
8
  def find_target; '' end
9
9
  end
10
10
 
11
- class FakeProxy < MongoMapper::Associations::Proxy
11
+ class FakeProxy < MongoMapper::Plugins::Associations::Proxy
12
12
  def find_target
13
13
  [1, 2]
14
14
  end