tpitale-mongo_mapper 0.6.9

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 (75) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +53 -0
  4. data/Rakefile +55 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +60 -0
  7. data/lib/mongo_mapper/associations/base.rb +110 -0
  8. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +26 -0
  9. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +21 -0
  10. data/lib/mongo_mapper/associations/collection.rb +19 -0
  11. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +26 -0
  12. data/lib/mongo_mapper/associations/many_documents_proxy.rb +115 -0
  13. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +31 -0
  14. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +54 -0
  15. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +11 -0
  16. data/lib/mongo_mapper/associations/proxy.rb +113 -0
  17. data/lib/mongo_mapper/associations.rb +70 -0
  18. data/lib/mongo_mapper/callbacks.rb +109 -0
  19. data/lib/mongo_mapper/dirty.rb +136 -0
  20. data/lib/mongo_mapper/document.rb +472 -0
  21. data/lib/mongo_mapper/dynamic_finder.rb +74 -0
  22. data/lib/mongo_mapper/embedded_document.rb +384 -0
  23. data/lib/mongo_mapper/finder_options.rb +133 -0
  24. data/lib/mongo_mapper/key.rb +36 -0
  25. data/lib/mongo_mapper/observing.rb +50 -0
  26. data/lib/mongo_mapper/pagination.rb +55 -0
  27. data/lib/mongo_mapper/rails_compatibility/document.rb +15 -0
  28. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +27 -0
  29. data/lib/mongo_mapper/serialization.rb +54 -0
  30. data/lib/mongo_mapper/serializers/json_serializer.rb +92 -0
  31. data/lib/mongo_mapper/support.rb +206 -0
  32. data/lib/mongo_mapper/validations.rb +41 -0
  33. data/lib/mongo_mapper.rb +120 -0
  34. data/mongo_mapper.gemspec +173 -0
  35. data/specs.watchr +32 -0
  36. data/test/NOTE_ON_TESTING +1 -0
  37. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +55 -0
  38. data/test/functional/associations/test_belongs_to_proxy.rb +48 -0
  39. data/test/functional/associations/test_many_documents_as_proxy.rb +246 -0
  40. data/test/functional/associations/test_many_documents_proxy.rb +387 -0
  41. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +156 -0
  42. data/test/functional/associations/test_many_embedded_proxy.rb +192 -0
  43. data/test/functional/associations/test_many_polymorphic_proxy.rb +339 -0
  44. data/test/functional/test_associations.rb +44 -0
  45. data/test/functional/test_binary.rb +18 -0
  46. data/test/functional/test_callbacks.rb +85 -0
  47. data/test/functional/test_dirty.rb +159 -0
  48. data/test/functional/test_document.rb +1235 -0
  49. data/test/functional/test_embedded_document.rb +135 -0
  50. data/test/functional/test_logger.rb +20 -0
  51. data/test/functional/test_pagination.rb +95 -0
  52. data/test/functional/test_rails_compatibility.rb +25 -0
  53. data/test/functional/test_string_id_compatibility.rb +72 -0
  54. data/test/functional/test_validations.rb +378 -0
  55. data/test/models.rb +271 -0
  56. data/test/support/custom_matchers.rb +55 -0
  57. data/test/support/timing.rb +16 -0
  58. data/test/test_helper.rb +27 -0
  59. data/test/unit/associations/test_base.rb +166 -0
  60. data/test/unit/associations/test_proxy.rb +91 -0
  61. data/test/unit/serializers/test_json_serializer.rb +189 -0
  62. data/test/unit/test_document.rb +204 -0
  63. data/test/unit/test_dynamic_finder.rb +125 -0
  64. data/test/unit/test_embedded_document.rb +718 -0
  65. data/test/unit/test_finder_options.rb +296 -0
  66. data/test/unit/test_key.rb +172 -0
  67. data/test/unit/test_mongo_mapper.rb +65 -0
  68. data/test/unit/test_observing.rb +101 -0
  69. data/test/unit/test_pagination.rb +113 -0
  70. data/test/unit/test_rails_compatibility.rb +49 -0
  71. data/test/unit/test_serializations.rb +52 -0
  72. data/test/unit/test_support.rb +342 -0
  73. data/test/unit/test_time_zones.rb +40 -0
  74. data/test/unit/test_validations.rb +503 -0
  75. metadata +235 -0
@@ -0,0 +1,387 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyDocumentsProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Project.collection.remove
7
+ Status.collection.remove
8
+ end
9
+
10
+ should "default reader to empty array" do
11
+ project = Project.new
12
+ project.statuses.should == []
13
+ end
14
+
15
+ should "allow adding to association like it was an array" do
16
+ project = Project.new
17
+ project.statuses << Status.new(:name => 'Foo1!')
18
+ project.statuses.push Status.new(:name => 'Foo2!')
19
+ project.statuses.concat Status.new(:name => 'Foo3!')
20
+ project.statuses.size.should == 3
21
+ end
22
+
23
+ should "be able to replace the association" do
24
+ project = Project.new
25
+ project.statuses = [Status.new("name" => "ready")]
26
+ project.save.should be_true
27
+
28
+ project = project.reload
29
+ project.statuses.size.should == 1
30
+ project.statuses[0].name.should == "ready"
31
+ end
32
+
33
+ should "correctly assign foreign key when using <<, push and concat" do
34
+ project = Project.new
35
+ project.statuses << Status.new(:name => '<<')
36
+ project.statuses.push Status.new(:name => 'push')
37
+ project.statuses.concat Status.new(:name => 'concat')
38
+
39
+ project = project.reload
40
+ project.statuses[0].project_id.should == project.id
41
+ project.statuses[1].project_id.should == project.id
42
+ project.statuses[2].project_id.should == project.id
43
+ end
44
+
45
+ context "build" do
46
+ should "assign foreign key" do
47
+ project = Project.create
48
+ status = project.statuses.build
49
+ status.project_id.should == project.id
50
+ end
51
+
52
+ should "allow assigning attributes" do
53
+ project = Project.create
54
+ status = project.statuses.build(:name => 'Foo')
55
+ status.name.should == 'Foo'
56
+ end
57
+ end
58
+
59
+ context "create" do
60
+ should "assign foreign key" do
61
+ project = Project.create
62
+ status = project.statuses.create(:name => 'Foo!')
63
+ status.project_id.should == project.id
64
+ end
65
+
66
+ should "save record" do
67
+ project = Project.create
68
+ lambda {
69
+ project.statuses.create(:name => 'Foo!')
70
+ }.should change { Status.count }
71
+ end
72
+
73
+ should "allow passing attributes" do
74
+ project = Project.create
75
+ status = project.statuses.create(:name => 'Foo!')
76
+ status.name.should == 'Foo!'
77
+ end
78
+ end
79
+
80
+ context "create!" do
81
+ should "assign foreign key" do
82
+ project = Project.create
83
+ status = project.statuses.create!(:name => 'Foo!')
84
+ status.project_id.should == project.id
85
+ end
86
+
87
+ should "save record" do
88
+ project = Project.create
89
+ lambda {
90
+ project.statuses.create!(:name => 'Foo!')
91
+ }.should change { Status.count }
92
+ end
93
+
94
+ should "allow passing attributes" do
95
+ project = Project.create
96
+ status = project.statuses.create!(:name => 'Foo!')
97
+ status.name.should == 'Foo!'
98
+ end
99
+
100
+ should "raise exception if not valid" do
101
+ project = Project.create
102
+ lambda {
103
+ project.statuses.create!(:name => nil)
104
+ }.should raise_error(MongoMapper::DocumentNotValid)
105
+ end
106
+ end
107
+
108
+ context "count" do
109
+ should "work scoped to association" do
110
+ project = Project.create
111
+ 3.times { project.statuses.create(:name => 'Foo!') }
112
+
113
+ other_project = Project.create
114
+ 2.times { other_project.statuses.create(:name => 'Foo!') }
115
+
116
+ project.statuses.count.should == 3
117
+ other_project.statuses.count.should == 2
118
+ end
119
+
120
+ should "work with conditions" do
121
+ project = Project.create
122
+ project.statuses.create(:name => 'Foo')
123
+ project.statuses.create(:name => 'Other 1')
124
+ project.statuses.create(:name => 'Other 2')
125
+
126
+ project.statuses.count(:name => 'Foo').should == 1
127
+ end
128
+ end
129
+
130
+ context "Unassociating documents" do
131
+ setup do
132
+ @project = Project.create
133
+ @project.statuses << Status.create(:name => '1')
134
+ @project.statuses << Status.create(:name => '2')
135
+
136
+ @project2 = Project.create
137
+ @project2.statuses << Status.create(:name => '1')
138
+ @project2.statuses << Status.create(:name => '2')
139
+ end
140
+
141
+ should "work with destroy all" do
142
+ @project.statuses.count.should == 2
143
+ @project.statuses.destroy_all
144
+ @project.statuses.count.should == 0
145
+
146
+ @project2.statuses.count.should == 2
147
+ Status.count.should == 2
148
+ end
149
+
150
+ should "work with destroy all and conditions" do
151
+ @project.statuses.count.should == 2
152
+ @project.statuses.destroy_all(:name => '1')
153
+ @project.statuses.count.should == 1
154
+
155
+ @project2.statuses.count.should == 2
156
+ Status.count.should == 3
157
+ end
158
+
159
+ should "work with delete all" do
160
+ @project.statuses.count.should == 2
161
+ @project.statuses.delete_all
162
+ @project.statuses.count.should == 0
163
+
164
+ @project2.statuses.count.should == 2
165
+ Status.count.should == 2
166
+ end
167
+
168
+ should "work with delete all and conditions" do
169
+ @project.statuses.count.should == 2
170
+ @project.statuses.delete_all(:name => '1')
171
+ @project.statuses.count.should == 1
172
+
173
+ @project2.statuses.count.should == 2
174
+ Status.count.should == 3
175
+ end
176
+
177
+ should "work with nullify" do
178
+ @project.statuses.count.should == 2
179
+ @project.statuses.nullify
180
+ @project.statuses.count.should == 0
181
+
182
+ @project2.statuses.count.should == 2
183
+ Status.count.should == 4
184
+ Status.count(:name => '1').should == 2
185
+ Status.count(:name => '2').should == 2
186
+ end
187
+ end
188
+
189
+ context "Finding scoped to association" do
190
+ setup do
191
+ @project1 = Project.new(:name => 'Project 1')
192
+ @brand_new = Status.create(:name => 'New', :position => 1 )
193
+ @complete = Status.create(:name => 'Complete', :position => 2)
194
+ @project1.statuses = [@brand_new, @complete]
195
+ @project1.save
196
+
197
+ @project2 = Project.create(:name => 'Project 2')
198
+ @in_progress = Status.create(:name => 'In Progress')
199
+ @archived = Status.create(:name => 'Archived')
200
+ @another_complete = Status.create(:name => 'Complete')
201
+ @project2.statuses = [@in_progress, @archived, @another_complete]
202
+ @project2.save
203
+ end
204
+
205
+ context "dynamic finders" do
206
+ should "work with single key" do
207
+ @project1.statuses.find_by_name('New').should == @brand_new
208
+ @project1.statuses.find_by_name!('New').should == @brand_new
209
+ @project2.statuses.find_by_name('In Progress').should == @in_progress
210
+ @project2.statuses.find_by_name!('In Progress').should == @in_progress
211
+ end
212
+
213
+ should "work with multiple keys" do
214
+ @project1.statuses.find_by_name_and_position('New', 1).should == @brand_new
215
+ @project1.statuses.find_by_name_and_position!('New', 1).should == @brand_new
216
+ @project1.statuses.find_by_name_and_position('New', 2).should be_nil
217
+ end
218
+
219
+ should "raise error when using !" do
220
+ lambda {
221
+ @project1.statuses.find_by_name!('Fake')
222
+ }.should raise_error(MongoMapper::DocumentNotFound)
223
+ end
224
+
225
+ context "find_or_create_by" do
226
+ should "not create document if found" do
227
+ lambda {
228
+ status = @project1.statuses.find_or_create_by_name('New')
229
+ status.project.should == @project1
230
+ status.should == @brand_new
231
+ }.should_not change { Status.count }
232
+ end
233
+
234
+ should "create document if not found" do
235
+ lambda {
236
+ status = @project1.statuses.find_or_create_by_name('Delivered')
237
+ status.project.should == @project1
238
+ }.should change { Status.count }.by(1)
239
+ end
240
+ end
241
+ end
242
+
243
+ context "with :all" do
244
+ should "work" do
245
+ @project1.statuses.find(:all, :order => "position asc").should == [@brand_new, @complete]
246
+ end
247
+
248
+ should "work with conditions" do
249
+ statuses = @project1.statuses.find(:all, :name => 'Complete')
250
+ statuses.should == [@complete]
251
+ end
252
+
253
+ should "work with order" do
254
+ statuses = @project1.statuses.find(:all, :order => 'name asc')
255
+ statuses.should == [@complete, @brand_new]
256
+ end
257
+ end
258
+
259
+ context "with #all" do
260
+ should "work" do
261
+ @project1.statuses.all(:order => "position asc").should == [@brand_new, @complete]
262
+ end
263
+
264
+ should "work with conditions" do
265
+ statuses = @project1.statuses.all(:name => 'Complete')
266
+ statuses.should == [@complete]
267
+ end
268
+
269
+ should "work with order" do
270
+ statuses = @project1.statuses.all(:order => 'name asc')
271
+ statuses.should == [@complete, @brand_new]
272
+ end
273
+ end
274
+
275
+ context "with :first" do
276
+ should "work" do
277
+ @project1.statuses.find(:first, :order => 'name').should == @complete
278
+ end
279
+
280
+ should "work with conditions" do
281
+ status = @project1.statuses.find(:first, :name => 'Complete')
282
+ status.should == @complete
283
+ end
284
+ end
285
+
286
+ context "with #first" do
287
+ should "work" do
288
+ @project1.statuses.first(:order => 'name').should == @complete
289
+ end
290
+
291
+ should "work with conditions" do
292
+ status = @project1.statuses.first(:name => 'Complete')
293
+ status.should == @complete
294
+ end
295
+ end
296
+
297
+ context "with :last" do
298
+ should "work" do
299
+ @project1.statuses.find(:last, :order => "position asc").should == @complete
300
+ end
301
+
302
+ should "work with conditions" do
303
+ status = @project1.statuses.find(:last, :order => 'position', :name => 'New')
304
+ status.should == @brand_new
305
+ end
306
+ end
307
+
308
+ context "with #last" do
309
+ should "work" do
310
+ @project1.statuses.last(:order => "position asc").should == @complete
311
+ end
312
+
313
+ should "work with conditions" do
314
+ status = @project1.statuses.last(:order => 'position', :name => 'New')
315
+ status.should == @brand_new
316
+ end
317
+ end
318
+
319
+ context "with one id" do
320
+ should "work for id in association" do
321
+ @project1.statuses.find(@complete.id).should == @complete
322
+ end
323
+
324
+ should "not work for id not in association" do
325
+ lambda {
326
+ @project1.statuses.find!(@archived.id)
327
+ }.should raise_error(MongoMapper::DocumentNotFound)
328
+ end
329
+ end
330
+
331
+ context "with multiple ids" do
332
+ should "work for ids in association" do
333
+ statuses = @project1.statuses.find(@brand_new.id, @complete.id)
334
+ statuses.should == [@brand_new, @complete]
335
+ end
336
+
337
+ should "not work for ids not in association" do
338
+ lambda {
339
+ @project1.statuses.find!(@brand_new.id, @complete.id, @archived.id)
340
+ }.should raise_error(MongoMapper::DocumentNotFound)
341
+ end
342
+ end
343
+
344
+ context "with #paginate" do
345
+ setup do
346
+ @statuses = @project2.statuses.paginate(:per_page => 2, :page => 1, :order => 'name asc')
347
+ end
348
+
349
+ should "return total pages" do
350
+ @statuses.total_pages.should == 2
351
+ end
352
+
353
+ should "return total entries" do
354
+ @statuses.total_entries.should == 3
355
+ end
356
+
357
+ should "return the subject" do
358
+ @statuses.collect(&:name).should == %w(Archived Complete)
359
+ end
360
+ end
361
+ end
362
+
363
+ context "extending the association" do
364
+ should "work using a block passed to many" do
365
+ project = Project.new(:name => "Some Project")
366
+ status1 = Status.new(:name => "New")
367
+ status2 = Status.new(:name => "Assigned")
368
+ status3 = Status.new(:name => "Closed")
369
+ project.statuses = [status1, status2, status3]
370
+ project.save
371
+
372
+ open_statuses = project.statuses.open
373
+ open_statuses.should include(status1)
374
+ open_statuses.should include(status2)
375
+ open_statuses.should_not include(status3)
376
+ end
377
+
378
+ should "work using many's :extend option" do
379
+ project = Project.new(:name => "Some Project")
380
+ collaborator1 = Collaborator.new(:name => "zing")
381
+ collaborator2 = Collaborator.new(:name => "zang")
382
+ project.collaborators = [collaborator1, collaborator2]
383
+ project.save
384
+ project.collaborators.top.should == collaborator1
385
+ end
386
+ end
387
+ end
@@ -0,0 +1,156 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Catalog.collection.remove
7
+ TrModels::Fleet.collection.remove
8
+ end
9
+
10
+ should "default reader to empty array" do
11
+ catalog = Catalog.new
12
+ catalog.medias.should == []
13
+ end
14
+
15
+ should "allow adding to association like it was an array" do
16
+ catalog = Catalog.new
17
+ catalog.medias << Video.new
18
+ catalog.medias.push Video.new
19
+ catalog.medias.size.should == 2
20
+ end
21
+
22
+ should "be able to replace the association" do
23
+ catalog = Catalog.new
24
+ catalog.medias = [Video.new("file" => "video.mpg", "length" => 3600)]
25
+ catalog.save.should be_true
26
+
27
+ catalog = catalog.reload
28
+ catalog.medias.size.should == 1
29
+ catalog.medias[0].file.should == "video.mpg"
30
+ end
31
+
32
+ should "store different associations" do
33
+ catalog = Catalog.new
34
+ catalog.medias = [
35
+ Video.new("file" => "video.mpg", "length" => 3600),
36
+ Music.new("file" => "music.mp3", "bitrate" => "128kbps"),
37
+ Image.new("file" => "image.png", "width" => 800, "height" => 600)
38
+ ]
39
+ catalog.save.should be_true
40
+
41
+ catalog = catalog.reload
42
+ catalog.medias.size.should == 3
43
+ catalog.medias[0].file.should == "video.mpg"
44
+ catalog.medias[0].length.should == 3600
45
+ catalog.medias[1].file.should == "music.mp3"
46
+ catalog.medias[1].bitrate.should == "128kbps"
47
+ catalog.medias[2].file.should == "image.png"
48
+ catalog.medias[2].width.should == 800
49
+ catalog.medias[2].height.should == 600
50
+ end
51
+
52
+ context "With modularized models" do
53
+ should "set associations correctly" do
54
+ fleet_attributes = {
55
+ "name" => "My Fleet",
56
+ "transports" => [
57
+ {"_type" => "TrModels::Ambulance", "license_plate" => "GGG123", "icu" => true},
58
+ {"_type" => "TrModels::Car", "license_plate" => "ABC123", "model" => "VW Golf", "year" => 2001},
59
+ {"_type" => "TrModels::Car", "license_plate" => "DEF123", "model" => "Honda Accord", "year" => 2008},
60
+ ]
61
+ }
62
+
63
+ fleet = TrModels::Fleet.new(fleet_attributes)
64
+ fleet.transports.size.should == 3
65
+ fleet.transports[0].class.should == TrModels::Ambulance
66
+ fleet.transports[0].license_plate.should == "GGG123"
67
+ fleet.transports[0].icu.should be_true
68
+ fleet.transports[1].class.should == TrModels::Car
69
+ fleet.transports[1].license_plate.should == "ABC123"
70
+ fleet.transports[1].model.should == "VW Golf"
71
+ fleet.transports[1].year.should == 2001
72
+ fleet.transports[2].class.should == TrModels::Car
73
+ fleet.transports[2].license_plate.should == "DEF123"
74
+ fleet.transports[2].model.should == "Honda Accord"
75
+ fleet.transports[2].year.should == 2008
76
+ fleet.save.should be_true
77
+
78
+ fleet = fleet.reload
79
+ fleet.transports.size.should == 3
80
+ fleet.transports[0].license_plate.should == "GGG123"
81
+ fleet.transports[0].icu.should be_true
82
+ fleet.transports[1].license_plate.should == "ABC123"
83
+ fleet.transports[1].model.should == "VW Golf"
84
+ fleet.transports[1].year.should == 2001
85
+ fleet.transports[2].license_plate.should == "DEF123"
86
+ fleet.transports[2].model.should == "Honda Accord"
87
+ fleet.transports[2].year.should == 2008
88
+ end
89
+
90
+ should "default reader to empty array" do
91
+ fleet = TrModels::Fleet.new
92
+ fleet.transports.should == []
93
+ end
94
+
95
+ should "allow adding to association like it was an array" do
96
+ fleet = TrModels::Fleet.new
97
+ fleet.transports << TrModels::Car.new
98
+ fleet.transports.push TrModels::Bus.new
99
+ fleet.transports.size.should == 2
100
+ end
101
+
102
+ should "be able to replace the association" do
103
+ fleet = TrModels::Fleet.new
104
+ fleet.transports = [TrModels::Car.new("license_plate" => "DCU2013", "model" => "Honda Civic")]
105
+ fleet.save.should be_true
106
+
107
+ fleet = fleet.reload
108
+ fleet.transports.size.should == 1
109
+ fleet.transports[0].license_plate.should == "DCU2013"
110
+ end
111
+
112
+ should "store different associations" do
113
+ fleet = TrModels::Fleet.new
114
+ fleet.transports = [
115
+ TrModels::Car.new("license_plate" => "ABC1223", "model" => "Honda Civic", "year" => 2003),
116
+ TrModels::Bus.new("license_plate" => "XYZ9090", "max_passengers" => 51),
117
+ TrModels::Ambulance.new("license_plate" => "HDD3030", "icu" => true)
118
+ ]
119
+ fleet.save.should be_true
120
+
121
+ fleet = fleet.reload
122
+ fleet.transports.size.should == 3
123
+ fleet.transports[0].license_plate.should == "ABC1223"
124
+ fleet.transports[0].model.should == "Honda Civic"
125
+ fleet.transports[0].year.should == 2003
126
+ fleet.transports[1].license_plate.should == "XYZ9090"
127
+ fleet.transports[1].max_passengers.should == 51
128
+ fleet.transports[2].license_plate.should == "HDD3030"
129
+ fleet.transports[2].icu.should == true
130
+ end
131
+ end
132
+
133
+ context "extending the association" do
134
+ should "work using a block passed to many" do
135
+ catalog = Catalog.new
136
+ medias = catalog.medias = [
137
+ Video.new("file" => "video.mpg", "length" => 3600, :visible => true),
138
+ Music.new("file" => "music.mp3", "bitrate" => "128kbps", :visible => true),
139
+ Image.new("file" => "image.png", "width" => 800, "height" => 600, :visible => false)
140
+ ]
141
+ catalog.save
142
+ catalog.medias.visible.should == [medias[0], medias[1]]
143
+ end
144
+
145
+ should "work using many's :extend option" do
146
+ fleet = TrModels::Fleet.new
147
+ transports = fleet.transports = [
148
+ TrModels::Car.new("license_plate" => "ABC1223", "model" => "Honda Civic", "year" => 2003, :purchased_on => 2.years.ago.to_date),
149
+ TrModels::Bus.new("license_plate" => "XYZ9090", "max_passengers" => 51, :purchased_on => 3.years.ago.to_date),
150
+ TrModels::Ambulance.new("license_plate" => "HDD3030", "icu" => true, :purchased_on => 1.year.ago.to_date)
151
+ ]
152
+ fleet.save
153
+ fleet.transports.to_be_replaced.should == [transports[1]]
154
+ end
155
+ end
156
+ end