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.
- data/VERSION +1 -1
- data/lib/mongo_mapper/descendant_appends.rb +44 -0
- data/lib/mongo_mapper/document.rb +54 -98
- data/lib/mongo_mapper/embedded_document.rb +28 -348
- data/lib/mongo_mapper/finder_options.rb +15 -33
- data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +28 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +23 -0
- data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +49 -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 +66 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
- data/lib/mongo_mapper/plugins/associations.rb +104 -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 +11 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +66 -0
- data/lib/mongo_mapper/plugins/inspect.rb +14 -0
- data/lib/mongo_mapper/plugins/keys.rb +295 -0
- data/lib/mongo_mapper/plugins/logger.rb +17 -0
- data/lib/mongo_mapper/plugins/pagination.rb +85 -0
- data/lib/mongo_mapper/plugins/rails.rb +45 -0
- data/lib/mongo_mapper/plugins/serialization.rb +109 -0
- data/lib/mongo_mapper/plugins/validations.rb +48 -0
- data/lib/mongo_mapper/plugins.rb +19 -0
- data/lib/mongo_mapper/support.rb +36 -15
- data/lib/mongo_mapper.rb +23 -22
- data/performance/read_write.rb +52 -0
- data/specs.watchr +23 -2
- data/test/functional/associations/test_belongs_to_proxy.rb +1 -1
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +58 -39
- data/test/functional/associations/test_many_embedded_proxy.rb +103 -69
- data/test/functional/test_dirty.rb +1 -1
- data/test/functional/test_document.rb +25 -25
- data/test/functional/test_embedded_document.rb +66 -63
- data/test/functional/test_identity_map.rb +233 -0
- data/test/functional/test_modifiers.rb +14 -0
- data/test/functional/test_string_id_compatibility.rb +4 -4
- data/test/functional/test_validations.rb +13 -0
- data/test/models.rb +0 -39
- data/test/test_helper.rb +8 -2
- data/test/unit/associations/test_base.rb +1 -1
- data/test/unit/associations/test_proxy.rb +3 -3
- data/test/unit/test_descendant_appends.rb +71 -0
- data/test/unit/test_document.rb +35 -46
- data/test/unit/test_embedded_document.rb +218 -271
- data/test/unit/{test_key.rb → test_keys.rb} +0 -0
- data/test/unit/test_pagination.rb +10 -2
- data/test/unit/test_plugins.rb +42 -0
- data/test/unit/test_rails.rb +123 -0
- data/test/unit/{test_serializations.rb → test_serialization.rb} +0 -0
- data/test/unit/test_support.rb +10 -6
- data/test/unit/test_time_zones.rb +2 -2
- metadata +44 -31
- 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/associations.rb +0 -78
- data/lib/mongo_mapper/callbacks.rb +0 -61
- data/lib/mongo_mapper/dirty.rb +0 -117
- 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
@@ -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
|
-
|
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
|
-
@
|
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 = @
|
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 = @
|
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 = @
|
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 = @
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
16
|
-
key :foo, Address
|
17
|
-
end
|
25
|
+
@klass.key :foo, @address_class
|
18
26
|
|
19
|
-
@address =
|
20
|
-
@doc = @
|
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
|
-
@
|
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 =
|
52
|
-
doc = @
|
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 =
|
58
|
-
doc = @
|
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 =
|
65
|
-
doc = @
|
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
|
-
|
74
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
should
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
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
|
@@ -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
|