mongodb-mongo_record 0.0.2

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.
@@ -0,0 +1,79 @@
1
+ # Copyright (C) 2008 10gen Inc.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify it
4
+ # under the terms of the GNU Affero General Public License, version 3, as
5
+ # published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful, but WITHOUT
8
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
10
+ # for more details.
11
+ #
12
+ # You should have received a copy of the GNU Affero General Public License
13
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
+
15
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '../lib')
16
+ require 'rubygems'
17
+ require 'test/unit'
18
+ require 'logger'
19
+ require 'mongo'
20
+ require 'mongo_record/log_device.rb'
21
+
22
+ class LoggerTest < Test::Unit::TestCase
23
+
24
+ MAX_RECS = 3
25
+
26
+ def setup
27
+ @db = XGen::Mongo::Driver::Mongo.new.db('mongorecord-test')
28
+ @db.drop_collection('testlogger') # can't remove recs from capped colls
29
+ MongoRecord::LogDevice.connection = @db
30
+ # Create a log device with a max of MAX_RECS records
31
+ @logger = Logger.new(MongoRecord::LogDevice.new('testlogger', :size => 1_000_000, :max => MAX_RECS))
32
+ end
33
+
34
+ def teardown
35
+ @db.drop_collection('testlogger') # can't remove recs from capped colls
36
+ end
37
+
38
+ # We really don't have to test much more than this. We can trust that Mongo
39
+ # works properly.
40
+ def test_max
41
+ assert_not_nil @db
42
+ assert_equal @db.name, MongoRecord::LogDevice.connection.name
43
+ collection = MongoRecord::LogDevice.connection.collection('testlogger')
44
+ MAX_RECS.times { |i|
45
+ @logger.debug("test message #{i+1}")
46
+ assert_equal i+1, collection.count()
47
+ }
48
+
49
+ MAX_RECS.times { |i|
50
+ @logger.debug("test message #{i+MAX_RECS+1}")
51
+ assert_equal MAX_RECS, collection.count()
52
+ }
53
+ end
54
+
55
+ def test_alternate_connection
56
+ old_db = @db
57
+ alt_db = XGen::Mongo::Driver::Mongo.new.db('mongorecord-test-log-device')
58
+ begin
59
+ @db = nil
60
+ MongoRecord::LogDevice.connection = alt_db
61
+
62
+ logger = Logger.new(MongoRecord::LogDevice.new('testlogger', :size => 1_000_000, :max => MAX_RECS))
63
+ logger.debug('test message')
64
+
65
+ coll = alt_db.collection('testlogger')
66
+ assert_equal 1, coll.count()
67
+ rec = coll.find({}, :limit => 1).next_object
68
+ assert_not_nil rec
69
+ assert_match /test message/, rec['msg']
70
+ rescue => ex
71
+ fail ex.to_s
72
+ ensure
73
+ @db = old_db
74
+ MongoRecord::LogDevice.connection = @db
75
+ alt_db.drop_collection('testlogger')
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,614 @@
1
+ # Copyright (C) 2008 10gen Inc.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify it
4
+ # under the terms of the GNU Affero General Public License, version 3, as
5
+ # published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful, but WITHOUT
8
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
10
+ # for more details.
11
+ #
12
+ # You should have received a copy of the GNU Affero General Public License
13
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
+
15
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '../lib')
16
+ require 'rubygems'
17
+ require 'test/unit'
18
+ require 'mongo_record'
19
+ require File.join(File.dirname(__FILE__), 'course')
20
+ require File.join(File.dirname(__FILE__), 'address')
21
+ require File.join(File.dirname(__FILE__), 'student')
22
+
23
+ class Track < MongoRecord::Base
24
+ collection_name :tracks
25
+ fields :artist, :album, :song, :track
26
+ def to_s
27
+ # Uses both accessor methods and ivars themselves
28
+ "artist: #{artist}, album: #{album}, song: #@song, track: #{@track ? @track.to_i : nil}"
29
+ end
30
+ end
31
+
32
+ # Same class, but this time class.name.downcase == collection name so we don't
33
+ # have to call collection_name.
34
+ class Rubytest < MongoRecord::Base
35
+ fields :artist, :album, :song, :track
36
+ def to_s
37
+ "artist: #{artist}, album: #{album}, song: #{song}, track: #{track ? track.to_i : nil}"
38
+ end
39
+ end
40
+
41
+ class MongoTest < Test::Unit::TestCase
42
+
43
+ def setup
44
+ super
45
+ @db = XGen::Mongo::Driver::Mongo.new.db('mongorecord-test')
46
+ MongoRecord::Base.connection = @db
47
+
48
+ @students = @db.collection('students')
49
+ @courses = @db.collection('courses')
50
+ @tracks = @db.collection('tracks')
51
+
52
+ @students.clear
53
+ @courses.clear
54
+ @tracks.clear
55
+
56
+ # Manually insert data without using MongoRecord::Base
57
+ @tracks.insert({:_id => XGen::Mongo::Driver::ObjectID.new, :artist => 'Thomas Dolby', :album => 'Aliens Ate My Buick', :song => 'The Ability to Swing'})
58
+ @tracks.insert({:_id => XGen::Mongo::Driver::ObjectID.new, :artist => 'Thomas Dolby', :album => 'Aliens Ate My Buick', :song => 'Budapest by Blimp'})
59
+ @tracks.insert({:_id => XGen::Mongo::Driver::ObjectID.new, :artist => 'Thomas Dolby', :album => 'The Golden Age of Wireless', :song => 'Europa and the Pirate Twins'})
60
+ @tracks.insert({:_id => XGen::Mongo::Driver::ObjectID.new, :artist => 'XTC', :album => 'Oranges & Lemons', :song => 'Garden Of Earthly Delights', :track => 1})
61
+ @mayor_id = XGen::Mongo::Driver::ObjectID.new
62
+ @tracks.insert({:_id => @mayor_id, :artist => 'XTC', :album => 'Oranges & Lemons', :song => 'The Mayor Of Simpleton', :track => 2})
63
+ @tracks.insert({:_id => XGen::Mongo::Driver::ObjectID.new, :artist => 'XTC', :album => 'Oranges & Lemons', :song => 'King For A Day', :track => 3})
64
+
65
+ @mayor_str = "artist: XTC, album: Oranges & Lemons, song: The Mayor Of Simpleton, track: 2"
66
+ @mayor_song = 'The Mayor Of Simpleton'
67
+
68
+ @spongebob_addr = Address.new(:street => "3 Pineapple Lane", :city => "Bikini Bottom", :state => "HI", :postal_code => "12345")
69
+ @bender_addr = Address.new(:street => "Planet Express", :city => "New New York", :state => "NY", :postal_code => "10001")
70
+ @course1 = Course.new(:name => 'Introductory Testing')
71
+ @course2 = Course.new(:name => 'Advanced Phlogiston Combuston Theory')
72
+ @score1 = Score.new(:for_course => @course1, :grade => 4.0)
73
+ @score2 = Score.new(:for_course => @course2, :grade => 3.5)
74
+ end
75
+
76
+ def teardown
77
+ # @students.clear
78
+ @courses.clear
79
+ @tracks.clear
80
+ super
81
+ end
82
+
83
+ def test_ivars_created
84
+ t = Track.new
85
+ %w(_id artist album song track).each { |iv|
86
+ assert t.instance_variable_defined?("@#{iv}")
87
+ }
88
+ end
89
+
90
+ def test_method_generation
91
+ x = Track.new({:artist => 1, :album => 2})
92
+
93
+ assert x.respond_to?(:_id)
94
+ assert x.respond_to?(:artist)
95
+ assert x.respond_to?(:album)
96
+ assert x.respond_to?(:song)
97
+ assert x.respond_to?(:track)
98
+ assert x.respond_to?(:_id=)
99
+ assert x.respond_to?(:artist=)
100
+ assert x.respond_to?(:album=)
101
+ assert x.respond_to?(:song=)
102
+ assert x.respond_to?(:track=)
103
+ assert x.respond_to?(:_id?)
104
+ assert x.respond_to?(:artist?)
105
+ assert x.respond_to?(:album?)
106
+ assert x.respond_to?(:song?)
107
+ assert x.respond_to?(:track?)
108
+
109
+ assert_equal(1, x.artist)
110
+ assert_equal(2, x.album)
111
+ assert_nil(x.song)
112
+ assert_nil(x.track)
113
+ end
114
+
115
+ def test_initialize_block
116
+ track = Track.new { |t|
117
+ t.artist = "Me'Shell Ndegeocello"
118
+ t.album = "Peace Beyond Passion"
119
+ t.song = "Bittersweet"
120
+ }
121
+ assert_equal "Me'Shell Ndegeocello", track.artist
122
+ assert_equal "Peace Beyond Passion", track.album
123
+ assert_equal "Bittersweet", track.song
124
+ assert !track.track?
125
+ end
126
+
127
+ def test_find_by_id
128
+ assert_equal(@mayor_str, Track.find_by_id(@mayor_id).to_s)
129
+ end
130
+
131
+ def test_find_by_song
132
+ assert_equal("artist: Thomas Dolby, album: Aliens Ate My Buick, song: Budapest by Blimp, track: ", Track.find_by_song('Budapest by Blimp').to_s)
133
+ end
134
+
135
+ def test_update
136
+ t = Track.find_by_track(2)
137
+ t.track = 99
138
+ t.save
139
+ str = @mayor_str.sub(/2/, '99')
140
+ assert_equal(str, t.to_s)
141
+ assert_equal(str, Track.find_by_track(99).to_s)
142
+ end
143
+
144
+ def test_find_all
145
+ assert_all_songs Track.find(:all).inject('') { |str, t| str + t.to_s }
146
+ end
147
+
148
+ def test_find_using_hash
149
+ str = Track.find(:all, :conditions => {:album => 'Aliens Ate My Buick'}).inject('') { |str, t| str + t.to_s }
150
+ assert_match(/song: The Ability to Swing/, str)
151
+ assert_match(/song: Budapest by Blimp/, str)
152
+ end
153
+
154
+ def test_find_first
155
+ t = Track.find(:first)
156
+ assert t.kind_of?(Track)
157
+ str = t.to_s
158
+ assert_match(/artist: [^,]+,/, str, "did not find non-empty artist name")
159
+ end
160
+
161
+ def test_find_first_with_search
162
+ t = Track.find(:first, :conditions => {:track => 3})
163
+ assert_not_nil t, "oops: nil track returned"
164
+ assert_equal "artist: XTC, album: Oranges & Lemons, song: King For A Day, track: 3", t.to_s
165
+ end
166
+
167
+ def test_find_first_returns_nil_if_not_found
168
+ assert_nil Track.find(:first, :conditions => {:track => 666})
169
+ end
170
+
171
+ def test_find_all_by
172
+ str = Track.find_all_by_album('Oranges & Lemons').inject('') { |str, t| str + t.to_s }
173
+ assert_match(/song: Garden Of Earthly Delights/, str)
174
+ assert_match(/song: The Mayor Of Simpleton/, str)
175
+ assert_match(/song: King For A Day/, str)
176
+ end
177
+
178
+ def test_find_using_hash_with_array_and_range
179
+ sorted_track_titles = ['Garden Of Earthly Delights', 'King For A Day', @mayor_song]
180
+
181
+ # Array
182
+ list = Track.find(:all, :conditions => {:track => [1,2,3]}).to_a
183
+ assert_equal 3, list.length
184
+ assert_equal sorted_track_titles, list.collect{|t| t.song}.sort
185
+
186
+ # Range
187
+ list = Track.find(:all, :conditions => {:track => 1..3}).to_a
188
+ assert_equal 3, list.length
189
+ assert_equal sorted_track_titles, list.collect{|t| t.song}.sort
190
+ end
191
+
192
+ def test_new_no_arg
193
+ assert_equal "artist: , album: , song: , track: ", Track.new.to_s
194
+ end
195
+
196
+ def test_new_by_hash
197
+ assert_equal("artist: Level 42, album: Standing In The Light, song: Micro-Kid, track: 1",
198
+ Track.new(:song => 'Micro-Kid', :album => 'Standing In The Light', :artist => 'Level 42', :track => 1).to_s)
199
+ end
200
+
201
+ def test_new_and_save
202
+ x = Track.new(:artist => 'Level 42', :album => 'Standing In The Light', :song => 'Micro-Kid', :track => 1)
203
+ assert_nil(x.id)
204
+ assert x.save, "x.save returned false; expected true"
205
+ assert_not_nil(x.id)
206
+ z = Track.find(x.id)
207
+ assert_equal(x.to_s, z.to_s)
208
+ assert_equal(x.id, z.id)
209
+ end
210
+
211
+ def test_find_or_create_but_already_exists
212
+ assert_equal("artist: Thomas Dolby, album: Aliens Ate My Buick, song: The Ability to Swing, track: ",
213
+ Track.find_or_create_by_song('The Ability to Swing', :artist => 'ignored because song found').to_s)
214
+ end
215
+
216
+ def test_find_or_create_new_created
217
+ assert_equal("artist: New Artist, album: New Album, song: New Song, track: ",
218
+ Track.find_or_create_by_song('New Song', :artist => 'New Artist', :album => 'New Album').to_s)
219
+ end
220
+
221
+ def test_cursor_methods
222
+ assert_equal 2, Track.find(:all, :limit => 2).to_a.length
223
+ end
224
+
225
+ def test_return_nil_if_no_match
226
+ assert_nil Track.find(:first, :conditions => {:song => 'Does Not Compute'})
227
+ end
228
+
229
+ def test_raise_error_if_bogus_id
230
+ Track.find("bogus_id")
231
+ fail 'expected "invalid ObjectID" exception'
232
+ rescue => ex
233
+ assert_match /illegal ObjectID format/, ex.to_s
234
+ end
235
+
236
+ def test_raise_error_if_first_and_bogus_id_in_hash
237
+ Track.find(:first, :conditions => {:_id => "bogus_id"})
238
+ fail 'expected "invalid ObjectID" exception'
239
+ rescue => ex
240
+ assert_match /invalid ObjectID/, ex.to_s
241
+ end
242
+
243
+ def test_find_options
244
+ assert_equal 2, Track.find(:all, :limit => 2).to_a.length
245
+ end
246
+
247
+ def test_order_options
248
+ tracks = Track.find(:all, :order => "song asc")
249
+ assert_not_nil tracks
250
+ assert_equal "Budapest by Blimp:Europa and the Pirate Twins:Garden Of Earthly Delights:King For A Day:The Ability to Swing:The Mayor Of Simpleton",
251
+ tracks.collect {|t| t.song }.join(':')
252
+
253
+ # TODO this should work, but the database does not yet sort this properly
254
+ # tracks = Track.find(:all, :order => "artist desc, song")
255
+ # assert_not_nil tracks
256
+ # assert_equal "Garden Of Earthly Delights:King For A Day:The Mayor Of Simpleton:Budapest by Blimp:Europa and the Pirate Twins:The Ability to Swing",
257
+ # tracks.collect {|t| t.song }.join(':')
258
+ end
259
+
260
+ def test_delete
261
+ Track.find(:first, :conditions => {:song => 'King For A Day'}).delete
262
+ str = Track.find(:all).inject('') { |str, t| str + t.to_s }
263
+ assert_match(/song: The Ability to Swing/, str)
264
+ assert_match(/song: Budapest by Blimp/, str)
265
+ assert_match(/song: Europa and the Pirate Twins/, str)
266
+ assert_match(/song: Garden Of Earthly Delights/, str)
267
+ assert_match(/song: The Mayor Of Simpleton/, str)
268
+ assert_no_match(/song: King For A Day/, str)
269
+ end
270
+
271
+ def test_class_delete
272
+ Track.delete(@mayor_id)
273
+ assert_no_match(/song: The Mayor Of Simpleton/, Track.find(:all).inject('') { |str, t| str + t.to_s })
274
+ end
275
+
276
+ def test_delete_all
277
+ Track.delete_all({:artist => 'XTC'})
278
+ assert_no_match(/artist: XTC/, Track.find(:all).inject('') { |str, t| str + t.to_s })
279
+
280
+ Track.delete_all(["song = ?", 'The Mayor Of Simpleton'])
281
+ assert_no_match(/song: The Mayor Of Simpleton/, Track.find(:all).inject('') { |str, t| str + t.to_s })
282
+
283
+ Track.delete_all("song = 'King For A Day'")
284
+ assert_no_match(/song: King For A Day/, Track.find(:all).inject('') { |str, t| str + t.to_s })
285
+
286
+ Track.delete_all()
287
+ assert_equal 0, Track.count
288
+ end
289
+
290
+ def test_find_by_mql_not_implemented
291
+ Track.find_by_mql("")
292
+ fail "should have raised a 'not implemented' exception"
293
+ rescue => ex
294
+ assert_equal("not implemented", ex.to_s)
295
+ end
296
+
297
+ def test_count
298
+ assert_equal 6, Track.count
299
+ assert_equal 3, Track.count(:conditions => {:artist => 'XTC'})
300
+ end
301
+
302
+ def test_select
303
+ str = Track.find(:all, :select => :album).inject('') { |str, t| str + t.to_s }
304
+ assert str.include?("artist: , album: Oranges & Lemons, song: , track:")
305
+ end
306
+
307
+ def test_find_using_id
308
+ t = Track.find_by_song('King For A Day')
309
+ tid = t._id
310
+ # first is string id, second is ObjectID
311
+ str = Track.find([@mayor_id, tid]).inject('') { |str, t| str + t.to_s }
312
+ assert str.include?(@mayor_str)
313
+ assert str.include?('King For A Day')
314
+ end
315
+
316
+ def test_find_one_using_id
317
+ t = Track.find(@mayor_id)
318
+ assert_not_nil t
319
+ assert_match /song: The Mayor Of Simpleton/, t.to_s
320
+ end
321
+
322
+ def test_select_find_by_id
323
+ t = Track.find(@mayor_id, :select => :album)
324
+ assert t.album?
325
+ assert !t.artist?
326
+ assert !t.song?
327
+ assert !t.track?
328
+ assert_equal "artist: , album: Oranges & Lemons, song: , track: ", t.to_s
329
+ end
330
+
331
+ def test_has_one_initialize
332
+ s = Student.new(:name => 'Spongebob Squarepants', :email => 'spongebob@example.com', :address => @spongebob_addr)
333
+
334
+ assert_not_nil s.address, "Address not set correctly in Student#initialize"
335
+ assert_equal '3 Pineapple Lane', s.address.street
336
+ end
337
+
338
+ def test_has_one_save_and_find
339
+ s = Student.new(:name => 'Spongebob Squarepants', :email => 'spongebob@example.com', :address => @spongebob_addr)
340
+ s.save
341
+
342
+ s2 = Student.find(:first)
343
+ assert_equal 'Spongebob Squarepants', s2.name
344
+ assert_equal 'spongebob@example.com', s2.email
345
+ a2 = s2.address
346
+ assert_not_nil a2
347
+ assert_kind_of Address, a2
348
+ assert_equal @spongebob_addr.street, a2.street
349
+ assert_equal @spongebob_addr.city, a2.city
350
+ assert_equal @spongebob_addr.state, a2.state
351
+ assert_equal @spongebob_addr.postal_code, a2.postal_code
352
+ end
353
+
354
+ def test_student_array_field
355
+ s = Student.new(:name => 'Spongebob Squarepants', :email => 'spongebob@example.com', :num_array => [100, 90, 80])
356
+ s.save
357
+
358
+ s2 = Student.find(:first)
359
+ assert_equal [100, 90, 80], s2.num_array
360
+ end
361
+
362
+ def test_has_many_initialize
363
+ s = Student.new(:name => 'Spongebob Squarepants', :email => 'spongebob@example.com', :scores => [@score1, @score2])
364
+ assert_not_nil s.scores
365
+ assert_equal 2, s.scores.length
366
+ assert_equal @score1, s.scores[0]
367
+ assert_equal @score2, s.scores[1]
368
+ end
369
+
370
+ def test_has_many_initialize_one_value
371
+ s = Student.new(:name => 'Spongebob Squarepants', :email => 'spongebob@example.com', :scores => @score1)
372
+ assert_not_nil s.scores
373
+ assert_equal 1, s.scores.length
374
+ assert_equal @score1, s.scores[0]
375
+ end
376
+
377
+ def test_has_many_save_and_find
378
+ s = Student.new(:name => 'Spongebob Squarepants', :email => 'spongebob@example.com', :scores => [@score1, @score2])
379
+ s.save!
380
+ assert_not_nil s.id
381
+
382
+ assert_equal 1, Student.count()
383
+ s2 = Student.find(:first)
384
+ assert_equal 'Spongebob Squarepants', s2.name
385
+ assert_equal 'spongebob@example.com', s2.email
386
+ list = s2.scores
387
+ assert_not_nil list
388
+ assert_equal 2, list.length
389
+ score = list.first
390
+ assert_not_nil score
391
+ assert_kind_of Score, score
392
+ assert (score.for_course.name == @score1.for_course.name && score.grade == @score1.grade), "oops: first score is wrong: #{score}"
393
+ end
394
+
395
+ def test_field_query_methods
396
+ s = Student.new(:name => 'Spongebob Squarepants', :email => 'spongebob@example.com', :scores => [@score1, @score2])
397
+ assert s.name?
398
+ assert s.email?
399
+ assert s.scores
400
+
401
+ s = Student.new(:name => 'Spongebob Squarepants')
402
+ assert s.name?
403
+ assert !s.email?
404
+ assert !s.scores?
405
+
406
+ s.email = ''
407
+ assert !s.email?
408
+ end
409
+
410
+ def test_new_record
411
+ t = Track.new
412
+ assert_nil t.id
413
+ assert t.new_record?
414
+ t.save
415
+ assert_not_nil t.id
416
+ assert !t.new_record?
417
+
418
+ t = Track.create(:artist => 'Level 42', :album => 'Standing In The Light', :song => 'Micro-Kid', :track => 1)
419
+ assert !t.new_record?
420
+
421
+ t = Track.find(:first)
422
+ assert !t.new_record?
423
+
424
+ t = Track.find_or_create_by_song('New Song', :artist => 'New Artist', :album => 'New Album')
425
+ assert !t.new_record?
426
+
427
+ t = Track.find_or_initialize_by_song('Newer Song', :artist => 'Newer Artist', :album => 'Newer Album')
428
+ assert t.new_record?
429
+ end
430
+
431
+ def test_sql_parsing
432
+ t = Track.find(:first, :conditions => "song = '#{@mayor_song}'")
433
+ assert_equal @mayor_str, t.to_s
434
+ end
435
+
436
+ def test_sql_substitution
437
+ s = @mayor_song
438
+ t = Track.find(:first, :conditions => ["song = ?", s])
439
+ assert_equal @mayor_str, t.to_s
440
+ end
441
+
442
+ def test_sql_named_substitution
443
+ t = Track.find(:first, :conditions => ["song = :song", {:song => @mayor_song}])
444
+ assert_equal @mayor_str, t.to_s
445
+ end
446
+
447
+ def test_sql_like
448
+ t = Track.find(:first, :conditions => "song like '%Simp%'")
449
+ assert_equal @mayor_str, t.to_s
450
+ end
451
+
452
+ def test_sql_in
453
+ str = Track.find(:all, :conditions => "song in ('#{@mayor_song}', 'King For A Day')").inject('') { |str, t| str + t.to_s }
454
+ assert str.include?(@mayor_song)
455
+ assert str.include?('King For A Day')
456
+
457
+ list = Track.find(:all, :conditions => "track in (1,2,3)").to_a
458
+ assert_equal 3, list.length
459
+ assert_equal ['Garden Of Earthly Delights', 'King For A Day', @mayor_song], list.collect{|t| t.song}.sort
460
+ end
461
+
462
+ def test_in_array
463
+ str = Track.find(:all, :conditions => ["song in (?)", [@mayor_song, 'King For A Day']]).inject('') { |str, t| str + t.to_s }
464
+ assert str.include?(@mayor_song)
465
+ assert str.include?('King For A Day')
466
+ end
467
+
468
+ def test_in_array_rails_syntax
469
+ str = Track.find(:all, :conditions => {:song => [@mayor_song, 'King For A Day']}).inject('') { |str, t| str + t.to_s }
470
+ assert str.include?(@mayor_song)
471
+ assert str.include?('King For A Day')
472
+ end
473
+
474
+ def test_in_named_array
475
+ str = Track.find(:all, :conditions => ["song in (:songs)", {:songs => [@mayor_song, 'King For A Day']}]).inject('') { |str, t| str + t.to_s }
476
+ assert str.include?(@mayor_song)
477
+ assert str.include?('King For A Day')
478
+ end
479
+
480
+ def test_where
481
+ # function
482
+ str = Track.find(:all, :where => "function() { return obj.song == '#{@mayor_song}'; }").inject('') { |str, t| str + t.to_s }
483
+ assert_equal @mayor_str, str
484
+
485
+ # expression
486
+ str = Track.find(:all, :where => "obj.song == '#{@mayor_song}'").inject('') { |str, t| str + t.to_s }
487
+ assert_equal @mayor_str, str
488
+ end
489
+
490
+ def test_destroy
491
+ Track.destroy(@mayor_id)
492
+ begin
493
+ Track.find(@mayor_id)
494
+ fail "expected exception about missing ID"
495
+ rescue => ex
496
+ assert_match /Couldn't find Track with ID=#@mayor_id/, ex.to_s # ' <= for Emacs font lock mode
497
+ end
498
+ end
499
+
500
+ # Potential bug: if this test runs at midnight, a create runs before midnight
501
+ # and the update runs after, then this test will fail.
502
+ def test_time_updates
503
+ s = Student.new(:name => 'Spongebob Squarepants')
504
+ assert s.instance_variable_defined?(:@created_at)
505
+
506
+ assert !s.created_at?
507
+ assert !s.created_on?
508
+ assert !s.updated_on?
509
+
510
+ s.save
511
+ assert s.created_at?
512
+ assert_kind_of Time, s.created_at
513
+ assert s.created_on?
514
+ assert_kind_of Time, s.created_on
515
+ assert !s.updated_on?
516
+ t = Time.now
517
+ assert_equal Time.local(t.year, t.month, t.day), s.created_on
518
+
519
+ s.save
520
+ assert s.created_at?
521
+ assert s.created_on?
522
+ assert s.updated_on?
523
+ assert_kind_of Time, s.created_at
524
+ assert_equal s.created_on, s.updated_on
525
+ end
526
+
527
+ # # TODO dbrefs are not yet implemented
528
+ # # This reproduces a bug where DBRefs weren't being created properly because
529
+ # # the MongoRecord::Base objects weren't storing the magic _ns, _update, and
530
+ # # other values set by the database.
531
+ # def test_db_ref
532
+ # s = Student.new(:name => 'Spongebob Squarepants', :address => @spongebob_addr)
533
+ # s.save
534
+
535
+ # @course1.save
536
+ # assert_not_nil @course1.id
537
+
538
+ # s.add_score(@course1.id, 3.5)
539
+ # s.save # This used to blow up
540
+
541
+ # score = s.scores.first
542
+ # assert_not_nil score
543
+ # assert_equal @course1.name, score.for_course.name
544
+
545
+ # # Now change the name of @course1 and see the student's score's course
546
+ # # name change.
547
+ # @course1.name = 'changed'
548
+ # @course1.save
549
+
550
+ # s = Student.find(:first, :conditions => "name = 'Spongebob Squarepants'")
551
+ # assert_not_nil s
552
+ # assert_equal 1, s.scores.length
553
+ # assert_equal 'changed', s.scores.first.for_course.name
554
+ # end
555
+
556
+ def test_subobjects_have_no_ids
557
+ @spongebob_addr.id
558
+ rescue => ex
559
+ assert_match /Subobjects don't have ids/, ex.to_s # ' <= for Emacs font-lock mode
560
+ end
561
+
562
+ def test_can_not_save_subobject
563
+ @spongebob_addr.save
564
+ fail "expected failed save of address"
565
+ rescue => ex
566
+ assert_match /Subobjects/, ex.to_s
567
+ end
568
+
569
+ def test_alternate_connection
570
+ old_db = MongoRecord::Base.connection
571
+ assert_equal @db, old_db
572
+ alt_db = XGen::Mongo::Driver::Mongo.new.db('mongorecord-test-alt-conn')
573
+ assert_not_equal old_db, alt_db
574
+ alt_db.drop_collection('students')
575
+ begin
576
+ @db = nil
577
+ MongoRecord::Base.connection = alt_db
578
+ assert_equal alt_db, MongoRecord::Base.connection
579
+
580
+ # Make sure collection exists
581
+ coll = alt_db.collection('students')
582
+ coll.insert('name' => 'foo')
583
+ coll.clear
584
+
585
+ assert_equal 0, coll.count()
586
+ s = Student.new(:name => 'Spongebob Squarepants', :address => @spongebob_addr)
587
+ assert s.save, "save failed"
588
+ assert_equal 1, coll.count()
589
+ ensure
590
+ @db = old_db
591
+ MongoRecord::Base.connection = @db
592
+ alt_db.drop_collection('students')
593
+ end
594
+ end
595
+
596
+ def test_method_missing
597
+ begin
598
+ Track.foobar
599
+ fail "expected 'undefined method' exception"
600
+ rescue => ex
601
+ assert_match /undefined method \`foobar\' for Track:Class/, ex.to_s
602
+ end
603
+ end
604
+
605
+ def assert_all_songs(str)
606
+ assert_match(/song: The Ability to Swing/, str)
607
+ assert_match(/song: Budapest by Blimp/, str)
608
+ assert_match(/song: Europa and the Pirate Twins/, str)
609
+ assert_match(/song: Garden Of Earthly Delights/, str)
610
+ assert_match(/song: The Mayor Of Simpleton/, str)
611
+ assert_match(/song: King For A Day/, str)
612
+ end
613
+
614
+ end