mongo_mapper-unstable 2010.1.6 → 2010.1.12
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/mongo_mapper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
# if Gem is defined i'll assume you are using rubygems and lock specific versions
|
2
4
|
# call me crazy but a plain old require will just get the latest version you have installed
|
3
5
|
# so i want to make sure that if you are using gems you do in fact have the correct versions
|
@@ -98,29 +100,28 @@ module MongoMapper
|
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
101
|
-
require 'mongo_mapper/support'
|
102
|
-
require 'mongo_mapper/callbacks'
|
103
103
|
require 'mongo_mapper/finder_options'
|
104
|
-
require 'mongo_mapper/
|
104
|
+
require 'mongo_mapper/support'
|
105
|
+
require 'mongo_mapper/descendant_appends'
|
106
|
+
|
105
107
|
require 'mongo_mapper/dynamic_finder'
|
106
108
|
require 'mongo_mapper/key'
|
107
|
-
|
108
|
-
require 'mongo_mapper/
|
109
|
-
require 'mongo_mapper/
|
110
|
-
require 'mongo_mapper/
|
111
|
-
require 'mongo_mapper/
|
109
|
+
|
110
|
+
require 'mongo_mapper/plugins'
|
111
|
+
require 'mongo_mapper/plugins/associations'
|
112
|
+
require 'mongo_mapper/plugins/callbacks'
|
113
|
+
require 'mongo_mapper/plugins/clone'
|
114
|
+
require 'mongo_mapper/plugins/descendants'
|
115
|
+
require 'mongo_mapper/plugins/dirty'
|
116
|
+
require 'mongo_mapper/plugins/equality'
|
117
|
+
require 'mongo_mapper/plugins/identity_map'
|
118
|
+
require 'mongo_mapper/plugins/inspect'
|
119
|
+
require 'mongo_mapper/plugins/keys'
|
120
|
+
require 'mongo_mapper/plugins/logger'
|
121
|
+
require 'mongo_mapper/plugins/pagination'
|
122
|
+
require 'mongo_mapper/plugins/rails'
|
123
|
+
require 'mongo_mapper/plugins/serialization'
|
124
|
+
require 'mongo_mapper/plugins/validations'
|
125
|
+
|
112
126
|
require 'mongo_mapper/embedded_document'
|
113
|
-
require 'mongo_mapper/document'
|
114
|
-
require 'mongo_mapper/associations'
|
115
|
-
require 'mongo_mapper/associations/base'
|
116
|
-
require 'mongo_mapper/associations/proxy'
|
117
|
-
require 'mongo_mapper/associations/collection'
|
118
|
-
require 'mongo_mapper/associations/many_documents_proxy'
|
119
|
-
require 'mongo_mapper/associations/belongs_to_proxy'
|
120
|
-
require 'mongo_mapper/associations/belongs_to_polymorphic_proxy'
|
121
|
-
require 'mongo_mapper/associations/many_polymorphic_proxy'
|
122
|
-
require 'mongo_mapper/associations/many_embedded_proxy'
|
123
|
-
require 'mongo_mapper/associations/many_embedded_polymorphic_proxy'
|
124
|
-
require 'mongo_mapper/associations/many_documents_as_proxy'
|
125
|
-
require 'mongo_mapper/associations/one_proxy'
|
126
|
-
require 'mongo_mapper/associations/in_array_proxy'
|
127
|
+
require 'mongo_mapper/document'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# The purpose of this is to check finding, initializing,
|
2
|
+
# and creating objects (typecasting times/dates and booleans).
|
3
|
+
|
4
|
+
require 'pp'
|
5
|
+
require 'benchmark'
|
6
|
+
require 'rubygems'
|
7
|
+
|
8
|
+
# to test with slow version just do this:
|
9
|
+
# gem 'mongo_mapper', '0.6.10'
|
10
|
+
# and comment out this:
|
11
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
12
|
+
|
13
|
+
require 'mongo_mapper'
|
14
|
+
|
15
|
+
MongoMapper.database = 'testing'
|
16
|
+
|
17
|
+
class Foo
|
18
|
+
include MongoMapper::Document
|
19
|
+
key :approved, Boolean
|
20
|
+
key :count, Integer
|
21
|
+
key :approved_at, Time
|
22
|
+
key :expire_on, Date
|
23
|
+
timestamps!
|
24
|
+
end
|
25
|
+
Foo.collection.remove
|
26
|
+
|
27
|
+
Benchmark.bm(5) do |x|
|
28
|
+
ids = []
|
29
|
+
x.report("write") do
|
30
|
+
1000.times { |i| ids << Foo.create(:count => 0, :approved => true, :approved_at => Time.now, :expire_on => Date.today).id }
|
31
|
+
end
|
32
|
+
|
33
|
+
x.report("read ") do
|
34
|
+
ids.each { |id| Foo.first(:id => id) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# I was get something like this on my puny macbook air:
|
39
|
+
# user system total real
|
40
|
+
# write 4.810000 0.090000 4.900000 ( 5.039949)
|
41
|
+
# read 2.730000 0.070000 2.800000 ( 2.990749)
|
42
|
+
#
|
43
|
+
#
|
44
|
+
# After these commits:
|
45
|
+
#
|
46
|
+
# * http://github.com/jnunemaker/mongomapper/commit/e5091fa140d5fae2721017b53027092233694ee5
|
47
|
+
# * http://github.com/jnunemaker/mongomapper/commit/c22bbde4fa1cfbc310d79cb0e50203310ffb03d1
|
48
|
+
#
|
49
|
+
# I'm now getting something like this:
|
50
|
+
# user system total real
|
51
|
+
# write 1.660000 0.050000 1.710000 ( 1.752676)
|
52
|
+
# read 1.060000 0.050000 1.110000 ( 1.263429)
|
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
|
@@ -72,7 +72,7 @@ class BelongsToProxyTest < Test::Unit::TestCase
|
|
72
72
|
setup do
|
73
73
|
Property.key :thing_id, ObjectId
|
74
74
|
Property.belongs_to :thing, :dependent => :destroy
|
75
|
-
Thing.
|
75
|
+
Thing.many :properties
|
76
76
|
|
77
77
|
@thing = Thing.create(:name => "Tree")
|
78
78
|
@property1 = Property.create
|
@@ -21,30 +21,49 @@ 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
30
|
end
|
31
|
-
|
31
|
+
|
32
|
+
context "count" do
|
33
|
+
should "default to 0" do
|
34
|
+
Catalog.new.medias.count.should == 0
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'return correct count if any are embedded' do
|
38
|
+
catalog = Catalog.new
|
39
|
+
catalog.medias = [
|
40
|
+
Video.new('file' => 'video.mpg', 'length' => 3600),
|
41
|
+
Music.new('file' => 'music.mp3', 'bitrate' => '128kbps'),
|
42
|
+
Image.new('file' => 'image.png', 'width' => 800, 'height' => 600)
|
43
|
+
]
|
44
|
+
catalog.medias.count.should == 3
|
45
|
+
catalog.save.should be_true
|
46
|
+
catalog.reload
|
47
|
+
catalog.medias.count.should == 3
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
32
51
|
should "store different associations" do
|
33
52
|
catalog = Catalog.new
|
34
53
|
catalog.medias = [
|
35
|
-
Video.new(
|
36
|
-
Music.new(
|
37
|
-
Image.new(
|
54
|
+
Video.new('file' => 'video.mpg', 'length' => 3600),
|
55
|
+
Music.new('file' => 'music.mp3', 'bitrate' => '128kbps'),
|
56
|
+
Image.new('file' => 'image.png', 'width' => 800, 'height' => 600)
|
38
57
|
]
|
39
58
|
catalog.save.should be_true
|
40
59
|
|
41
60
|
catalog = catalog.reload
|
42
61
|
catalog.medias.size.should == 3
|
43
|
-
catalog.medias[0].file.should ==
|
62
|
+
catalog.medias[0].file.should == 'video.mpg'
|
44
63
|
catalog.medias[0].length.should == 3600
|
45
|
-
catalog.medias[1].file.should ==
|
64
|
+
catalog.medias[1].file.should == 'music.mp3'
|
46
65
|
catalog.medias[1].bitrate.should == "128kbps"
|
47
|
-
catalog.medias[2].file.should ==
|
66
|
+
catalog.medias[2].file.should == 'image.png'
|
48
67
|
catalog.medias[2].width.should == 800
|
49
68
|
catalog.medias[2].height.should == 600
|
50
69
|
end
|
@@ -52,38 +71,38 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
52
71
|
context "With modularized models" do
|
53
72
|
should "set associations correctly" do
|
54
73
|
fleet_attributes = {
|
55
|
-
|
56
|
-
|
57
|
-
{
|
58
|
-
{
|
59
|
-
{
|
74
|
+
'name' => 'My Fleet',
|
75
|
+
'transports' => [
|
76
|
+
{'_type' => 'TrModels::Ambulance', 'license_plate' => 'GGG123', 'icu' => true},
|
77
|
+
{'_type' => 'TrModels::Car', 'license_plate' => 'ABC123', 'model' => 'VW Golf', 'year' => 2001},
|
78
|
+
{'_type' => 'TrModels::Car', 'license_plate' => 'DEF123', 'model' => 'Honda Accord', 'year' => 2008},
|
60
79
|
]
|
61
80
|
}
|
62
81
|
|
63
82
|
fleet = TrModels::Fleet.new(fleet_attributes)
|
64
83
|
fleet.transports.size.should == 3
|
65
84
|
fleet.transports[0].class.should == TrModels::Ambulance
|
66
|
-
fleet.transports[0].license_plate.should ==
|
85
|
+
fleet.transports[0].license_plate.should == 'GGG123'
|
67
86
|
fleet.transports[0].icu.should be_true
|
68
87
|
fleet.transports[1].class.should == TrModels::Car
|
69
|
-
fleet.transports[1].license_plate.should ==
|
70
|
-
fleet.transports[1].model.should ==
|
88
|
+
fleet.transports[1].license_plate.should == 'ABC123'
|
89
|
+
fleet.transports[1].model.should == 'VW Golf'
|
71
90
|
fleet.transports[1].year.should == 2001
|
72
91
|
fleet.transports[2].class.should == TrModels::Car
|
73
|
-
fleet.transports[2].license_plate.should ==
|
74
|
-
fleet.transports[2].model.should ==
|
92
|
+
fleet.transports[2].license_plate.should == 'DEF123'
|
93
|
+
fleet.transports[2].model.should == 'Honda Accord'
|
75
94
|
fleet.transports[2].year.should == 2008
|
76
95
|
fleet.save.should be_true
|
77
96
|
|
78
97
|
fleet = fleet.reload
|
79
98
|
fleet.transports.size.should == 3
|
80
|
-
fleet.transports[0].license_plate.should ==
|
99
|
+
fleet.transports[0].license_plate.should == 'GGG123'
|
81
100
|
fleet.transports[0].icu.should be_true
|
82
|
-
fleet.transports[1].license_plate.should ==
|
83
|
-
fleet.transports[1].model.should ==
|
101
|
+
fleet.transports[1].license_plate.should == 'ABC123'
|
102
|
+
fleet.transports[1].model.should == 'VW Golf'
|
84
103
|
fleet.transports[1].year.should == 2001
|
85
|
-
fleet.transports[2].license_plate.should ==
|
86
|
-
fleet.transports[2].model.should ==
|
104
|
+
fleet.transports[2].license_plate.should == 'DEF123'
|
105
|
+
fleet.transports[2].model.should == 'Honda Accord'
|
87
106
|
fleet.transports[2].year.should == 2008
|
88
107
|
end
|
89
108
|
|
@@ -101,31 +120,31 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
101
120
|
|
102
121
|
should "be able to replace the association" do
|
103
122
|
fleet = TrModels::Fleet.new
|
104
|
-
fleet.transports = [TrModels::Car.new(
|
123
|
+
fleet.transports = [TrModels::Car.new('license_plate' => 'DCU2013', 'model' => 'Honda Civic')]
|
105
124
|
fleet.save.should be_true
|
106
125
|
|
107
126
|
fleet = fleet.reload
|
108
127
|
fleet.transports.size.should == 1
|
109
|
-
fleet.transports[0].license_plate.should ==
|
128
|
+
fleet.transports[0].license_plate.should == 'DCU2013'
|
110
129
|
end
|
111
130
|
|
112
131
|
should "store different associations" do
|
113
132
|
fleet = TrModels::Fleet.new
|
114
133
|
fleet.transports = [
|
115
|
-
TrModels::Car.new(
|
116
|
-
TrModels::Bus.new(
|
117
|
-
TrModels::Ambulance.new(
|
134
|
+
TrModels::Car.new('license_plate' => 'ABC1223', 'model' => 'Honda Civic', 'year' => 2003),
|
135
|
+
TrModels::Bus.new('license_plate' => 'XYZ9090', 'max_passengers' => 51),
|
136
|
+
TrModels::Ambulance.new('license_plate' => 'HDD3030', 'icu' => true)
|
118
137
|
]
|
119
138
|
fleet.save.should be_true
|
120
139
|
|
121
140
|
fleet = fleet.reload
|
122
141
|
fleet.transports.size.should == 3
|
123
|
-
fleet.transports[0].license_plate.should ==
|
124
|
-
fleet.transports[0].model.should ==
|
142
|
+
fleet.transports[0].license_plate.should == 'ABC1223'
|
143
|
+
fleet.transports[0].model.should == 'Honda Civic'
|
125
144
|
fleet.transports[0].year.should == 2003
|
126
|
-
fleet.transports[1].license_plate.should ==
|
145
|
+
fleet.transports[1].license_plate.should == 'XYZ9090'
|
127
146
|
fleet.transports[1].max_passengers.should == 51
|
128
|
-
fleet.transports[2].license_plate.should ==
|
147
|
+
fleet.transports[2].license_plate.should == 'HDD3030'
|
129
148
|
fleet.transports[2].icu.should == true
|
130
149
|
end
|
131
150
|
end
|
@@ -134,9 +153,9 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
134
153
|
should "work using a block passed to many" do
|
135
154
|
catalog = Catalog.new
|
136
155
|
medias = catalog.medias = [
|
137
|
-
Video.new(
|
138
|
-
Music.new(
|
139
|
-
Image.new(
|
156
|
+
Video.new('file' => 'video.mpg', 'length' => 3600, :visible => true),
|
157
|
+
Music.new('file' => 'music.mp3', 'bitrate' => '128kbps', :visible => true),
|
158
|
+
Image.new('file' => 'image.png', 'width' => 800, 'height' => 600, :visible => false)
|
140
159
|
]
|
141
160
|
catalog.save
|
142
161
|
catalog.medias.visible.should == [medias[0], medias[1]]
|
@@ -145,9 +164,9 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
|
|
145
164
|
should "work using many's :extend option" do
|
146
165
|
fleet = TrModels::Fleet.new
|
147
166
|
transports = fleet.transports = [
|
148
|
-
TrModels::Car.new(
|
149
|
-
TrModels::Bus.new(
|
150
|
-
TrModels::Ambulance.new(
|
167
|
+
TrModels::Car.new('license_plate' => 'ABC1223', 'model' => 'Honda Civic', 'year' => 2003, :purchased_on => 2.years.ago.to_date),
|
168
|
+
TrModels::Bus.new('license_plate' => 'XYZ9090', 'max_passengers' => 51, :purchased_on => 3.years.ago.to_date),
|
169
|
+
TrModels::Ambulance.new('license_plate' => 'HDD3030', 'icu' => true, :purchased_on => 1.year.ago.to_date)
|
151
170
|
]
|
152
171
|
fleet.save
|
153
172
|
fleet.transports.to_be_replaced.should == [transports[1]]
|
@@ -3,120 +3,139 @@ 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
|
+
@person_class = EDoc do
|
19
|
+
key :name, String
|
20
|
+
end
|
21
|
+
@person_class.key :child, @person_class
|
22
|
+
@person_class.many :pets, :class => @pet_class
|
23
|
+
|
24
|
+
@owner_class = Doc do
|
25
|
+
key :name, String
|
26
|
+
end
|
27
|
+
@owner_class.many :pets, :class => @pet_class
|
8
28
|
end
|
9
29
|
|
10
30
|
should "default reader to empty array" do
|
11
|
-
|
31
|
+
@post_class.new.comments.should == []
|
12
32
|
end
|
13
33
|
|
14
34
|
should "allow adding to association like it was an array" do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
35
|
+
post = @post_class.new
|
36
|
+
post.comments << @comment_class.new
|
37
|
+
post.comments.push @comment_class.new
|
38
|
+
post.comments.size.should == 2
|
19
39
|
end
|
20
40
|
|
21
41
|
should "be embedded in document on save" do
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
42
|
+
frank = @comment_class.new(:name => 'Frank', :body => 'Hi!')
|
43
|
+
bill = @comment_class.new(:name => 'Bill', :body => 'Hi!')
|
44
|
+
post = @post_class.new
|
45
|
+
post.comments << frank
|
46
|
+
post.comments << bill
|
47
|
+
post.save
|
28
48
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
49
|
+
post.reload
|
50
|
+
post.comments.size.should == 2
|
51
|
+
post.comments[0].should == frank
|
52
|
+
post.comments[1].should == bill
|
33
53
|
end
|
34
54
|
|
35
55
|
should "allow embedding arbitrarily deep" do
|
36
|
-
@
|
37
|
-
|
38
|
-
end
|
56
|
+
@klass = Doc()
|
57
|
+
@klass.key :person, @person_class
|
39
58
|
|
40
|
-
meg
|
41
|
-
meg.child
|
42
|
-
meg.child.child =
|
59
|
+
meg = @person_class.new(:name => 'Meg')
|
60
|
+
meg.child = @person_class.new(:name => 'Steve')
|
61
|
+
meg.child.child = @person_class.new(:name => 'Linda')
|
43
62
|
|
44
|
-
doc = @
|
63
|
+
doc = @klass.new(:person => meg)
|
45
64
|
doc.save
|
46
|
-
|
47
65
|
doc.reload
|
66
|
+
|
48
67
|
doc.person.name.should == 'Meg'
|
49
68
|
doc.person.child.name.should == 'Steve'
|
50
69
|
doc.person.child.child.name.should == 'Linda'
|
51
70
|
end
|
52
71
|
|
53
|
-
should "allow assignment of
|
72
|
+
should "allow assignment of many embedded documents using a hash" do
|
54
73
|
person_attributes = {
|
55
|
-
|
56
|
-
|
57
|
-
{
|
58
|
-
{
|
74
|
+
'name' => 'Mr. Pet Lover',
|
75
|
+
'pets' => [
|
76
|
+
{'name' => 'Jimmy', 'species' => 'Cocker Spainel'},
|
77
|
+
{'name' => 'Sasha', 'species' => 'Siberian Husky'},
|
59
78
|
]
|
60
79
|
}
|
61
80
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
81
|
+
owner = @owner_class.new(person_attributes)
|
82
|
+
owner.name.should == 'Mr. Pet Lover'
|
83
|
+
owner.pets[0].name.should == 'Jimmy'
|
84
|
+
owner.pets[0].species.should == 'Cocker Spainel'
|
85
|
+
owner.pets[1].name.should == 'Sasha'
|
86
|
+
owner.pets[1].species.should == 'Siberian Husky'
|
87
|
+
|
88
|
+
owner.save.should be_true
|
89
|
+
owner.reload
|
90
|
+
|
91
|
+
owner.name.should == 'Mr. Pet Lover'
|
92
|
+
owner.pets[0].name.should == 'Jimmy'
|
93
|
+
owner.pets[0].species.should == 'Cocker Spainel'
|
94
|
+
owner.pets[1].name.should == 'Sasha'
|
95
|
+
owner.pets[1].species.should == 'Siberian Husky'
|
76
96
|
end
|
77
97
|
|
78
98
|
context "embedding many embedded documents" do
|
79
99
|
setup do
|
80
|
-
@
|
81
|
-
|
82
|
-
end
|
100
|
+
@klass = Doc()
|
101
|
+
@klass.many :people, :class => @person_class
|
83
102
|
end
|
84
103
|
|
85
104
|
should "persist all embedded documents" do
|
86
|
-
meg
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
meg.pets << koda
|
105
|
+
meg = @person_class.new(:name => 'Meg', :pets => [
|
106
|
+
@pet_class.new(:name => 'Sparky', :species => 'Dog'),
|
107
|
+
@pet_class.new(:name => 'Koda', :species => 'Dog')
|
108
|
+
])
|
109
|
+
|
110
|
+
doc = @klass.new
|
93
111
|
doc.people << meg
|
94
112
|
doc.save
|
95
|
-
|
96
113
|
doc.reload
|
97
|
-
|
114
|
+
|
115
|
+
doc.people.first.name.should == 'Meg'
|
98
116
|
doc.people.first.pets.should_not == []
|
99
|
-
doc.people.first.pets.first.name.should ==
|
100
|
-
doc.people.first.pets.first.species.should ==
|
101
|
-
doc.people.first.pets[1].name.should ==
|
102
|
-
doc.people.first.pets[1].species.should ==
|
117
|
+
doc.people.first.pets.first.name.should == 'Sparky'
|
118
|
+
doc.people.first.pets.first.species.should == 'Dog'
|
119
|
+
doc.people.first.pets[1].name.should == 'Koda'
|
120
|
+
doc.people.first.pets[1].species.should == 'Dog'
|
103
121
|
end
|
104
122
|
|
105
123
|
should "create a reference to the root document for all embedded documents before save" do
|
106
|
-
|
107
|
-
|
108
|
-
|
124
|
+
doc = @klass.new
|
125
|
+
meg = @person_class.new(:name => 'Meg')
|
126
|
+
pet = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
127
|
+
|
109
128
|
doc.people << meg
|
110
|
-
meg.pets <<
|
129
|
+
meg.pets << pet
|
111
130
|
|
112
131
|
doc.people.first._root_document.should == doc
|
113
132
|
doc.people.first.pets.first._root_document.should == doc
|
114
133
|
end
|
115
134
|
|
116
135
|
should "create a reference to the root document for all embedded documents" do
|
117
|
-
sparky =
|
118
|
-
meg =
|
119
|
-
doc = @
|
136
|
+
sparky = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
137
|
+
meg = @person_class.new(:name => 'Meg', :pets => [sparky])
|
138
|
+
doc = @klass.new
|
120
139
|
doc.people << meg
|
121
140
|
doc.save
|
122
141
|
|
@@ -127,13 +146,28 @@ class ManyEmbeddedProxyTest < Test::Unit::TestCase
|
|
127
146
|
end
|
128
147
|
|
129
148
|
should "allow finding by id" do
|
130
|
-
sparky =
|
131
|
-
meg =
|
149
|
+
sparky = @pet_class.new(:name => 'Sparky', :species => 'Dog')
|
150
|
+
meg = @owner_class.create(:name => 'Meg', :pets => [sparky])
|
132
151
|
|
133
152
|
meg.pets.find(sparky._id).should == sparky # oid
|
134
153
|
meg.pets.find(sparky.id.to_s).should == sparky # string
|
135
154
|
end
|
136
155
|
|
156
|
+
context "count" do
|
157
|
+
should "default to 0" do
|
158
|
+
@owner_class.new.pets.count.should == 0
|
159
|
+
end
|
160
|
+
|
161
|
+
should "return correct count if any are embedded" do
|
162
|
+
owner = @owner_class.new(:name => 'Meg')
|
163
|
+
owner.pets = [@pet_class.new, @pet_class.new]
|
164
|
+
owner.pets.count.should == 2
|
165
|
+
owner.save
|
166
|
+
owner.reload
|
167
|
+
owner.pets.count.should == 2
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
137
171
|
context "extending the association" do
|
138
172
|
setup do
|
139
173
|
@address_class = EDoc do
|
@@ -112,7 +112,7 @@ class DirtyTest < Test::Unit::TestCase
|
|
112
112
|
should "be hash of keys with values of changes if there are changes" do
|
113
113
|
doc = @document.new
|
114
114
|
doc.phrase = 'A penny saved is a penny earned.'
|
115
|
-
doc.changes.should ==
|
115
|
+
doc.changes['phrase'].should == [nil, 'A penny saved is a penny earned.']
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|