kbaum-mongo 0.18.3p

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/LICENSE.txt +202 -0
  2. data/README.rdoc +339 -0
  3. data/Rakefile +138 -0
  4. data/bin/bson_benchmark.rb +59 -0
  5. data/bin/fail_if_no_c.rb +11 -0
  6. data/examples/admin.rb +42 -0
  7. data/examples/capped.rb +22 -0
  8. data/examples/cursor.rb +48 -0
  9. data/examples/gridfs.rb +88 -0
  10. data/examples/index_test.rb +126 -0
  11. data/examples/info.rb +31 -0
  12. data/examples/queries.rb +70 -0
  13. data/examples/simple.rb +24 -0
  14. data/examples/strict.rb +35 -0
  15. data/examples/types.rb +36 -0
  16. data/lib/mongo/collection.rb +609 -0
  17. data/lib/mongo/connection.rb +672 -0
  18. data/lib/mongo/cursor.rb +403 -0
  19. data/lib/mongo/db.rb +555 -0
  20. data/lib/mongo/exceptions.rb +66 -0
  21. data/lib/mongo/gridfs/chunk.rb +91 -0
  22. data/lib/mongo/gridfs/grid.rb +79 -0
  23. data/lib/mongo/gridfs/grid_file_system.rb +101 -0
  24. data/lib/mongo/gridfs/grid_io.rb +338 -0
  25. data/lib/mongo/gridfs/grid_store.rb +580 -0
  26. data/lib/mongo/gridfs.rb +25 -0
  27. data/lib/mongo/types/binary.rb +52 -0
  28. data/lib/mongo/types/code.rb +36 -0
  29. data/lib/mongo/types/dbref.rb +40 -0
  30. data/lib/mongo/types/min_max_keys.rb +58 -0
  31. data/lib/mongo/types/objectid.rb +180 -0
  32. data/lib/mongo/types/regexp_of_holding.rb +45 -0
  33. data/lib/mongo/util/bson_c.rb +18 -0
  34. data/lib/mongo/util/bson_ruby.rb +606 -0
  35. data/lib/mongo/util/byte_buffer.rb +222 -0
  36. data/lib/mongo/util/conversions.rb +87 -0
  37. data/lib/mongo/util/ordered_hash.rb +140 -0
  38. data/lib/mongo/util/server_version.rb +69 -0
  39. data/lib/mongo/util/support.rb +26 -0
  40. data/lib/mongo.rb +63 -0
  41. data/mongo-ruby-driver.gemspec +28 -0
  42. data/test/auxillary/autoreconnect_test.rb +42 -0
  43. data/test/binary_test.rb +15 -0
  44. data/test/bson_test.rb +427 -0
  45. data/test/byte_buffer_test.rb +81 -0
  46. data/test/chunk_test.rb +82 -0
  47. data/test/collection_test.rb +515 -0
  48. data/test/connection_test.rb +160 -0
  49. data/test/conversions_test.rb +120 -0
  50. data/test/cursor_test.rb +379 -0
  51. data/test/db_api_test.rb +780 -0
  52. data/test/db_connection_test.rb +16 -0
  53. data/test/db_test.rb +272 -0
  54. data/test/grid_file_system_test.rb +210 -0
  55. data/test/grid_io_test.rb +78 -0
  56. data/test/grid_store_test.rb +334 -0
  57. data/test/grid_test.rb +87 -0
  58. data/test/objectid_test.rb +125 -0
  59. data/test/ordered_hash_test.rb +172 -0
  60. data/test/replica/count_test.rb +34 -0
  61. data/test/replica/insert_test.rb +50 -0
  62. data/test/replica/pooled_insert_test.rb +54 -0
  63. data/test/replica/query_test.rb +39 -0
  64. data/test/slave_connection_test.rb +36 -0
  65. data/test/test_helper.rb +42 -0
  66. data/test/threading/test_threading_large_pool.rb +90 -0
  67. data/test/threading_test.rb +87 -0
  68. data/test/unit/collection_test.rb +61 -0
  69. data/test/unit/connection_test.rb +117 -0
  70. data/test/unit/cursor_test.rb +93 -0
  71. data/test/unit/db_test.rb +98 -0
  72. metadata +127 -0
@@ -0,0 +1,780 @@
1
+ require 'test/test_helper'
2
+
3
+ # NOTE: assumes Mongo is running
4
+ class DBAPITest < Test::Unit::TestCase
5
+ include Mongo
6
+
7
+ @@conn = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
8
+ ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
9
+ @@db = @@conn.db("ruby-mongo-test")
10
+ @@coll = @@db.collection('test')
11
+ @@version = @@conn.server_version
12
+
13
+ def setup
14
+ @@coll.remove
15
+ @r1 = {'a' => 1}
16
+ @@coll.insert(@r1) # collection not created until it's used
17
+ @@coll_full_name = 'ruby-mongo-test.test'
18
+ end
19
+
20
+ def teardown
21
+ @@coll.remove
22
+ @@db.error
23
+ end
24
+
25
+ def test_clear
26
+ assert_equal 1, @@coll.count
27
+ @@coll.remove
28
+ assert_equal 0, @@coll.count
29
+ end
30
+
31
+ def test_insert
32
+ assert_kind_of ObjectID, @@coll.insert('a' => 2)
33
+ assert_kind_of ObjectID, @@coll.insert('b' => 3)
34
+
35
+ assert_equal 3, @@coll.count
36
+ docs = @@coll.find().to_a
37
+ assert_equal 3, docs.length
38
+ assert docs.detect { |row| row['a'] == 1 }
39
+ assert docs.detect { |row| row['a'] == 2 }
40
+ assert docs.detect { |row| row['b'] == 3 }
41
+
42
+ @@coll << {'b' => 4}
43
+ docs = @@coll.find().to_a
44
+ assert_equal 4, docs.length
45
+ assert docs.detect { |row| row['b'] == 4 }
46
+ end
47
+
48
+ def test_save_ordered_hash
49
+ oh = OrderedHash.new
50
+ oh['a'] = -1
51
+ oh['b'] = 'foo'
52
+
53
+ oid = @@coll.save(oh)
54
+ assert_equal 'foo', @@coll.find_one(oid)['b']
55
+
56
+ oh = OrderedHash['a' => 1, 'b' => 'foo']
57
+ oid = @@coll.save(oh)
58
+ assert_equal 'foo', @@coll.find_one(oid)['b']
59
+ end
60
+
61
+ def test_insert_multiple
62
+ ids = @@coll.insert([{'a' => 2}, {'b' => 3}])
63
+
64
+ ids.each do |i|
65
+ assert_kind_of ObjectID, i
66
+ end
67
+
68
+ assert_equal 3, @@coll.count
69
+ docs = @@coll.find().to_a
70
+ assert_equal 3, docs.length
71
+ assert docs.detect { |row| row['a'] == 1 }
72
+ assert docs.detect { |row| row['a'] == 2 }
73
+ assert docs.detect { |row| row['b'] == 3 }
74
+ end
75
+
76
+ def test_count_on_nonexisting
77
+ @@db.drop_collection('foo')
78
+ assert_equal 0, @@db.collection('foo').count()
79
+ end
80
+
81
+ def test_find_simple
82
+ @r2 = @@coll.insert('a' => 2)
83
+ @r3 = @@coll.insert('b' => 3)
84
+ # Check sizes
85
+ docs = @@coll.find().to_a
86
+ assert_equal 3, docs.size
87
+ assert_equal 3, @@coll.count
88
+
89
+ # Find by other value
90
+ docs = @@coll.find('a' => @r1['a']).to_a
91
+ assert_equal 1, docs.size
92
+ doc = docs.first
93
+ # Can't compare _id values because at insert, an _id was added to @r1 by
94
+ # the database but we don't know what it is without re-reading the record
95
+ # (which is what we are doing right now).
96
+ # assert_equal doc['_id'], @r1['_id']
97
+ assert_equal doc['a'], @r1['a']
98
+ end
99
+
100
+ def test_find_advanced
101
+ @@coll.insert('a' => 2)
102
+ @@coll.insert('b' => 3)
103
+
104
+ # Find by advanced query (less than)
105
+ docs = @@coll.find('a' => { '$lt' => 10 }).to_a
106
+ assert_equal 2, docs.size
107
+ assert docs.detect { |row| row['a'] == 1 }
108
+ assert docs.detect { |row| row['a'] == 2 }
109
+
110
+ # Find by advanced query (greater than)
111
+ docs = @@coll.find('a' => { '$gt' => 1 }).to_a
112
+ assert_equal 1, docs.size
113
+ assert docs.detect { |row| row['a'] == 2 }
114
+
115
+ # Find by advanced query (less than or equal to)
116
+ docs = @@coll.find('a' => { '$lte' => 1 }).to_a
117
+ assert_equal 1, docs.size
118
+ assert docs.detect { |row| row['a'] == 1 }
119
+
120
+ # Find by advanced query (greater than or equal to)
121
+ docs = @@coll.find('a' => { '$gte' => 1 }).to_a
122
+ assert_equal 2, docs.size
123
+ assert docs.detect { |row| row['a'] == 1 }
124
+ assert docs.detect { |row| row['a'] == 2 }
125
+
126
+ # Find by advanced query (between)
127
+ docs = @@coll.find('a' => { '$gt' => 1, '$lt' => 3 }).to_a
128
+ assert_equal 1, docs.size
129
+ assert docs.detect { |row| row['a'] == 2 }
130
+
131
+ # Find by advanced query (in clause)
132
+ docs = @@coll.find('a' => {'$in' => [1,2]}).to_a
133
+ assert_equal 2, docs.size
134
+ assert docs.detect { |row| row['a'] == 1 }
135
+ assert docs.detect { |row| row['a'] == 2 }
136
+
137
+ # Find by advanced query (regexp)
138
+ docs = @@coll.find('a' => /[1|2]/).to_a
139
+ assert_equal 2, docs.size
140
+ assert docs.detect { |row| row['a'] == 1 }
141
+ assert docs.detect { |row| row['a'] == 2 }
142
+ end
143
+
144
+ def test_find_sorting
145
+ @@coll.remove
146
+ @@coll.insert('a' => 1, 'b' => 2)
147
+ @@coll.insert('a' => 2, 'b' => 1)
148
+ @@coll.insert('a' => 3, 'b' => 2)
149
+ @@coll.insert('a' => 4, 'b' => 1)
150
+
151
+ # Sorting (ascending)
152
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['a', 1]]).to_a
153
+ assert_equal 4, docs.size
154
+ assert_equal 1, docs[0]['a']
155
+ assert_equal 2, docs[1]['a']
156
+ assert_equal 3, docs[2]['a']
157
+ assert_equal 4, docs[3]['a']
158
+
159
+ # Sorting (descending)
160
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['a', -1]]).to_a
161
+ assert_equal 4, docs.size
162
+ assert_equal 4, docs[0]['a']
163
+ assert_equal 3, docs[1]['a']
164
+ assert_equal 2, docs[2]['a']
165
+ assert_equal 1, docs[3]['a']
166
+
167
+ # Sorting using array of names; assumes ascending order.
168
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
169
+ assert_equal 4, docs.size
170
+ assert_equal 1, docs[0]['a']
171
+ assert_equal 2, docs[1]['a']
172
+ assert_equal 3, docs[2]['a']
173
+ assert_equal 4, docs[3]['a']
174
+
175
+ # Sorting using single name; assumes ascending order.
176
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
177
+ assert_equal 4, docs.size
178
+ assert_equal 1, docs[0]['a']
179
+ assert_equal 2, docs[1]['a']
180
+ assert_equal 3, docs[2]['a']
181
+ assert_equal 4, docs[3]['a']
182
+
183
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [['b', 'asc'], ['a', 'asc']]).to_a
184
+ assert_equal 4, docs.size
185
+ assert_equal 2, docs[0]['a']
186
+ assert_equal 4, docs[1]['a']
187
+ assert_equal 1, docs[2]['a']
188
+ assert_equal 3, docs[3]['a']
189
+
190
+ # Sorting using empty array; no order guarantee should not blow up.
191
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => []).to_a
192
+ assert_equal 4, docs.size
193
+
194
+ # Sorting using ordered hash. You can use an unordered one, but then the
195
+ # order of the keys won't be guaranteed thus your sort won't make sense.
196
+ oh = OrderedHash.new
197
+ oh['a'] = -1
198
+ assert_raise InvalidSortValueError do
199
+ docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
200
+ end
201
+ end
202
+
203
+ def test_find_limits
204
+ @@coll.insert('b' => 2)
205
+ @@coll.insert('c' => 3)
206
+ @@coll.insert('d' => 4)
207
+
208
+ docs = @@coll.find({}, :limit => 1).to_a
209
+ assert_equal 1, docs.size
210
+ docs = @@coll.find({}, :limit => 2).to_a
211
+ assert_equal 2, docs.size
212
+ docs = @@coll.find({}, :limit => 3).to_a
213
+ assert_equal 3, docs.size
214
+ docs = @@coll.find({}, :limit => 4).to_a
215
+ assert_equal 4, docs.size
216
+ docs = @@coll.find({}).to_a
217
+ assert_equal 4, docs.size
218
+ docs = @@coll.find({}, :limit => 99).to_a
219
+ assert_equal 4, docs.size
220
+ end
221
+
222
+ def test_find_one_no_records
223
+ @@coll.remove
224
+ x = @@coll.find_one('a' => 1)
225
+ assert_nil x
226
+ end
227
+
228
+ def test_drop_collection
229
+ assert @@db.drop_collection(@@coll.name), "drop of collection #{@@coll.name} failed"
230
+ assert !@@db.collection_names.include?(@@coll.name)
231
+ end
232
+
233
+ def test_other_drop
234
+ assert @@db.collection_names.include?(@@coll.name)
235
+ @@coll.drop
236
+ assert !@@db.collection_names.include?(@@coll.name)
237
+ end
238
+
239
+ def test_collection_names
240
+ names = @@db.collection_names
241
+ assert names.length >= 1
242
+ assert names.include?(@@coll.name)
243
+
244
+ coll2 = @@db.collection('test2')
245
+ coll2.insert('a' => 1) # collection not created until it's used
246
+ names = @@db.collection_names
247
+ assert names.length >= 2
248
+ assert names.include?(@@coll.name)
249
+ assert names.include?('ruby-mongo-test.test2')
250
+ ensure
251
+ @@db.drop_collection('test2')
252
+ end
253
+
254
+ def test_collections_info
255
+ cursor = @@db.collections_info
256
+ rows = cursor.to_a
257
+ assert rows.length >= 1
258
+ row = rows.detect { |r| r['name'] == @@coll_full_name }
259
+ assert_not_nil row
260
+ end
261
+
262
+ def test_collection_options
263
+ @@db.drop_collection('foobar')
264
+ @@db.strict = true
265
+
266
+ begin
267
+ coll = @@db.create_collection('foobar', :capped => true, :size => 1024)
268
+ options = coll.options()
269
+ assert_equal 'foobar', options['create']
270
+ assert_equal true, options['capped']
271
+ assert_equal 1024, options['size']
272
+ rescue => ex
273
+ @@db.drop_collection('foobar')
274
+ fail "did not expect exception \"#{ex}\""
275
+ ensure
276
+ @@db.strict = false
277
+ end
278
+ end
279
+
280
+ def test_index_information
281
+ assert_equal @@coll.index_information.length, 1
282
+
283
+ name = @@db.create_index(@@coll.name, 'a')
284
+ info = @@db.index_information(@@coll.name)
285
+ assert_equal name, "a_1"
286
+ assert_equal @@coll.index_information, info
287
+ assert_equal 2, info.length
288
+
289
+ assert info.has_key?(name)
290
+ assert_equal info[name], [["a", ASCENDING]]
291
+ ensure
292
+ @@db.drop_index(@@coll.name, name)
293
+ end
294
+
295
+ def test_index_create_with_symbol
296
+ assert_equal @@coll.index_information.length, 1
297
+
298
+ name = @@db.create_index(@@coll.name, :a)
299
+ info = @@db.index_information(@@coll.name)
300
+ assert_equal name, "a_1"
301
+ assert_equal @@coll.index_information, info
302
+ assert_equal 2, info.length
303
+
304
+ assert info.has_key?(name)
305
+ assert_equal info[name], [["a", ASCENDING]]
306
+ ensure
307
+ @@db.drop_index(@@coll.name, name)
308
+ end
309
+
310
+ def test_multiple_index_cols
311
+ name = @@db.create_index(@@coll.name, [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]])
312
+ info = @@db.index_information(@@coll.name)
313
+ assert_equal 2, info.length
314
+
315
+ assert_equal name, 'a_-1_b_1_c_-1'
316
+ assert info.has_key?(name)
317
+ assert_equal [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]], info[name]
318
+ ensure
319
+ @@db.drop_index(@@coll.name, name)
320
+ end
321
+
322
+ def test_multiple_index_cols_with_symbols
323
+ name = @@db.create_index(@@coll.name, [[:a, DESCENDING], [:b, ASCENDING], [:c, DESCENDING]])
324
+ info = @@db.index_information(@@coll.name)
325
+ assert_equal 2, info.length
326
+
327
+ assert_equal name, 'a_-1_b_1_c_-1'
328
+ assert info.has_key?(name)
329
+ assert_equal [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]], info[name]
330
+ ensure
331
+ @@db.drop_index(@@coll.name, name)
332
+ end
333
+
334
+ def test_unique_index
335
+ @@db.drop_collection("blah")
336
+ test = @@db.collection("blah")
337
+ test.create_index("hello")
338
+
339
+ test.insert("hello" => "world")
340
+ test.insert("hello" => "mike")
341
+ test.insert("hello" => "world")
342
+ assert !@@db.error?
343
+
344
+ @@db.drop_collection("blah")
345
+ test = @@db.collection("blah")
346
+ test.create_index("hello", unique=true)
347
+
348
+ test.insert("hello" => "world")
349
+ test.insert("hello" => "mike")
350
+ test.insert("hello" => "world")
351
+ assert @@db.error?
352
+ end
353
+
354
+ def test_index_on_subfield
355
+ @@db.drop_collection("blah")
356
+ test = @@db.collection("blah")
357
+
358
+ test.insert("hello" => {"a" => 4, "b" => 5})
359
+ test.insert("hello" => {"a" => 7, "b" => 2})
360
+ test.insert("hello" => {"a" => 4, "b" => 10})
361
+ assert !@@db.error?
362
+
363
+ @@db.drop_collection("blah")
364
+ test = @@db.collection("blah")
365
+ test.create_index("hello.a", unique=true)
366
+
367
+ test.insert("hello" => {"a" => 4, "b" => 5})
368
+ test.insert("hello" => {"a" => 7, "b" => 2})
369
+ test.insert("hello" => {"a" => 4, "b" => 10})
370
+ assert @@db.error?
371
+ end
372
+
373
+ def test_array
374
+ @@coll << {'b' => [1, 2, 3]}
375
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
376
+ if @@version < "1.1.3"
377
+ assert_equal 1, rows.length
378
+ assert_equal [1, 2, 3], rows[0]['b']
379
+ else
380
+ assert_equal 2, rows.length
381
+ assert_equal [1, 2, 3], rows[1]['b']
382
+ end
383
+ end
384
+
385
+ def test_regex
386
+ regex = /foobar/i
387
+ @@coll << {'b' => regex}
388
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
389
+ if @@version < "1.1.3"
390
+ assert_equal 1, rows.length
391
+ assert_equal regex, rows[0]['b']
392
+ else
393
+ assert_equal 2, rows.length
394
+ assert_equal regex, rows[1]['b']
395
+ end
396
+ end
397
+
398
+ def test_non_oid_id
399
+ # Note: can't use Time.new because that will include fractional seconds,
400
+ # which Mongo does not store.
401
+ t = Time.at(1234567890)
402
+ @@coll << {'_id' => t}
403
+ rows = @@coll.find({'_id' => t}).to_a
404
+ assert_equal 1, rows.length
405
+ assert_equal t, rows[0]['_id']
406
+ end
407
+
408
+ def test_strict
409
+ assert !@@db.strict?
410
+ @@db.strict = true
411
+ assert @@db.strict?
412
+ ensure
413
+ @@db.strict = false
414
+ end
415
+
416
+ def test_strict_access_collection
417
+ @@db.strict = true
418
+ begin
419
+ @@db.collection('does-not-exist')
420
+ fail "expected exception"
421
+ rescue => ex
422
+ assert_equal MongoDBError, ex.class
423
+ assert_equal "Collection does-not-exist doesn't exist. Currently in strict mode.", ex.to_s
424
+ ensure
425
+ @@db.strict = false
426
+ @@db.drop_collection('does-not-exist')
427
+ end
428
+ end
429
+
430
+ def test_strict_create_collection
431
+ @@db.drop_collection('foobar')
432
+ @@db.strict = true
433
+
434
+ begin
435
+ @@db.create_collection('foobar')
436
+ assert true
437
+ rescue => ex
438
+ fail "did not expect exception \"#{ex}\""
439
+ end
440
+
441
+ # Now the collection exists. This time we should see an exception.
442
+ assert_raise MongoDBError do
443
+ @@db.create_collection('foobar')
444
+ end
445
+ @@db.strict = false
446
+ @@db.drop_collection('foobar')
447
+
448
+ # Now we're not in strict mode - should succeed
449
+ @@db.create_collection('foobar')
450
+ @@db.create_collection('foobar')
451
+ @@db.drop_collection('foobar')
452
+ end
453
+
454
+ def test_to_a
455
+ cursor = @@coll.find()
456
+ rows = cursor.to_a
457
+
458
+ assert_raise InvalidOperation do
459
+ cursor.to_a
460
+ end
461
+
462
+ cursor.each { |doc| fail "should be no docs in each now" }
463
+ end
464
+
465
+ def test_to_a_after_each
466
+ cursor = @@coll.find
467
+ cursor.each { |row| row }
468
+ assert_raise InvalidOperation do
469
+ cursor.to_a
470
+ end
471
+ end
472
+
473
+ def test_where
474
+ @@coll.insert('a' => 2)
475
+ @@coll.insert('a' => 3)
476
+
477
+ assert_equal 3, @@coll.count
478
+ assert_equal 1, @@coll.find('$where' => Code.new('this.a > 2')).count()
479
+ assert_equal 2, @@coll.find('$where' => Code.new('this.a > i', {'i' => 1})).count()
480
+ end
481
+
482
+ def test_eval
483
+ assert_equal 3, @@db.eval('function (x) {return x;}', 3)
484
+
485
+ assert_equal nil, @@db.eval("function (x) {db.test_eval.save({y:x});}", 5)
486
+ assert_equal 5, @@db.collection('test_eval').find_one['y']
487
+
488
+ assert_equal 5, @@db.eval("function (x, y) {return x + y;}", 2, 3)
489
+ assert_equal 5, @@db.eval("function () {return 5;}")
490
+ assert_equal 5, @@db.eval("2 + 3;")
491
+
492
+ assert_equal 5, @@db.eval(Code.new("2 + 3;"))
493
+ assert_equal 2, @@db.eval(Code.new("return i;", {"i" => 2}))
494
+ assert_equal 5, @@db.eval(Code.new("i + 3;", {"i" => 2}))
495
+
496
+ assert_raise OperationFailure do
497
+ @@db.eval("5 ++ 5;")
498
+ end
499
+ end
500
+
501
+ def test_hint
502
+ name = @@coll.create_index('a')
503
+ begin
504
+ assert_nil @@coll.hint
505
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => 'a').to_a.size
506
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => ['a']).to_a.size
507
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => {'a' => 1}).to_a.size
508
+
509
+ @@coll.hint = 'a'
510
+ assert_equal({'a' => 1}, @@coll.hint)
511
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
512
+
513
+ @@coll.hint = ['a']
514
+ assert_equal({'a' => 1}, @@coll.hint)
515
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
516
+
517
+ @@coll.hint = {'a' => 1}
518
+ assert_equal({'a' => 1}, @@coll.hint)
519
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
520
+
521
+ @@coll.hint = nil
522
+ assert_nil @@coll.hint
523
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
524
+ ensure
525
+ @@coll.drop_index(name)
526
+ end
527
+ end
528
+
529
+ def test_hash_default_value_id
530
+ val = Hash.new(0)
531
+ val["x"] = 5
532
+ @@coll.insert val
533
+ id = @@coll.find_one("x" => 5)["_id"]
534
+ assert id != 0
535
+ end
536
+
537
+ def test_group
538
+ @@db.drop_collection("test")
539
+ test = @@db.collection("test")
540
+
541
+ assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")
542
+ assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")
543
+
544
+ test.insert("a" => 2)
545
+ test.insert("b" => 5)
546
+ test.insert("a" => 1)
547
+
548
+ assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
549
+ assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
550
+ assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
551
+ assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
552
+
553
+ finalize = "function (obj) { obj.f = obj.count - 1; }"
554
+ assert_equal 2, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true, finalize)[0]["f"]
555
+
556
+ test.insert("a" => 2, "b" => 3)
557
+ expected = [{"a" => 2, "count" => 2},
558
+ {"a" => nil, "count" => 1},
559
+ {"a" => 1, "count" => 1}]
560
+ assert_equal expected, test.group(["a"], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")
561
+ assert_equal expected, test.group(["a"], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }", true)
562
+
563
+ assert_raise OperationFailure do
564
+ test.group([], {}, {}, "5 ++ 5")
565
+ end
566
+ assert_raise OperationFailure do
567
+ test.group([], {}, {}, "5 ++ 5", true)
568
+ end
569
+ end
570
+
571
+ def test_deref
572
+ @@coll.remove
573
+
574
+ assert_equal nil, @@db.dereference(DBRef.new("test", ObjectID.new))
575
+ @@coll.insert({"x" => "hello"})
576
+ key = @@coll.find_one()["_id"]
577
+ assert_equal "hello", @@db.dereference(DBRef.new("test", key))["x"]
578
+
579
+ assert_equal nil, @@db.dereference(DBRef.new("test", 4))
580
+ obj = {"_id" => 4}
581
+ @@coll.insert(obj)
582
+ assert_equal obj, @@db.dereference(DBRef.new("test", 4))
583
+
584
+ @@coll.remove
585
+ @@coll.insert({"x" => "hello"})
586
+ assert_equal nil, @@db.dereference(DBRef.new("test", nil))
587
+ end
588
+
589
+ def test_save
590
+ @@coll.remove
591
+
592
+ a = {"hello" => "world"}
593
+
594
+ id = @@coll.save(a)
595
+ assert_kind_of ObjectID, id
596
+ assert_equal 1, @@coll.count
597
+
598
+ assert_equal id, @@coll.save(a)
599
+ assert_equal 1, @@coll.count
600
+
601
+ assert_equal "world", @@coll.find_one()["hello"]
602
+
603
+ a["hello"] = "mike"
604
+ @@coll.save(a)
605
+ assert_equal 1, @@coll.count
606
+
607
+ assert_equal "mike", @@coll.find_one()["hello"]
608
+
609
+ @@coll.save({"hello" => "world"})
610
+ assert_equal 2, @@coll.count
611
+ end
612
+
613
+ def test_save_long
614
+ @@coll.remove
615
+ @@coll.insert("x" => 9223372036854775807)
616
+ assert_equal 9223372036854775807, @@coll.find_one()["x"]
617
+ end
618
+
619
+ def test_find_by_oid
620
+ @@coll.remove
621
+
622
+ @@coll.save("hello" => "mike")
623
+ id = @@coll.save("hello" => "world")
624
+ assert_kind_of ObjectID, id
625
+
626
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
627
+ @@coll.find(:_id => id).to_a.each do |doc|
628
+ assert_equal "world", doc["hello"]
629
+ end
630
+
631
+ id = ObjectID.from_string(id.to_s)
632
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
633
+ end
634
+
635
+ def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
636
+ @@coll.remove
637
+
638
+ a = {'_id' => '1', 'hello' => 'world'}
639
+ @@coll.save(a)
640
+ assert_equal(1, @@coll.count)
641
+ assert_equal("world", @@coll.find_one()["hello"])
642
+
643
+ a["hello"] = "mike"
644
+ @@coll.save(a)
645
+ assert_equal(1, @@coll.count)
646
+ assert_equal("mike", @@coll.find_one()["hello"])
647
+ end
648
+
649
+ def test_invalid_key_names
650
+ @@coll.remove
651
+
652
+ @@coll.insert({"hello" => "world"})
653
+ @@coll.insert({"hello" => {"hello" => "world"}})
654
+
655
+ assert_raise InvalidName do
656
+ @@coll.insert({"$hello" => "world"})
657
+ end
658
+ assert_raise InvalidName do
659
+ @@coll.insert({"hello" => {"$hello" => "world"}})
660
+ end
661
+
662
+ @@coll.insert({"he$llo" => "world"})
663
+ @@coll.insert({"hello" => {"hell$o" => "world"}})
664
+
665
+ assert_raise InvalidName do
666
+ @@coll.insert({".hello" => "world"})
667
+ end
668
+ assert_raise InvalidName do
669
+ @@coll.insert({"hello" => {".hello" => "world"}})
670
+ end
671
+ assert_raise InvalidName do
672
+ @@coll.insert({"hello." => "world"})
673
+ end
674
+ assert_raise InvalidName do
675
+ @@coll.insert({"hello" => {"hello." => "world"}})
676
+ end
677
+ assert_raise InvalidName do
678
+ @@coll.insert({"hel.lo" => "world"})
679
+ end
680
+ assert_raise InvalidName do
681
+ @@coll.insert({"hello" => {"hel.lo" => "world"}})
682
+ end
683
+ end
684
+
685
+ def test_collection_names
686
+ assert_raise TypeError do
687
+ @@db.collection(5)
688
+ end
689
+ assert_raise InvalidName do
690
+ @@db.collection("")
691
+ end
692
+ assert_raise InvalidName do
693
+ @@db.collection("te$t")
694
+ end
695
+ assert_raise InvalidName do
696
+ @@db.collection(".test")
697
+ end
698
+ assert_raise InvalidName do
699
+ @@db.collection("test.")
700
+ end
701
+ assert_raise InvalidName do
702
+ @@db.collection("tes..t")
703
+ end
704
+ end
705
+
706
+ def test_rename_collection
707
+ @@db.drop_collection("foo")
708
+ @@db.drop_collection("bar")
709
+ a = @@db.collection("foo")
710
+ b = @@db.collection("bar")
711
+
712
+ assert_raise TypeError do
713
+ a.rename(5)
714
+ end
715
+ assert_raise InvalidName do
716
+ a.rename("")
717
+ end
718
+ assert_raise InvalidName do
719
+ a.rename("te$t")
720
+ end
721
+ assert_raise InvalidName do
722
+ a.rename(".test")
723
+ end
724
+ assert_raise InvalidName do
725
+ a.rename("test.")
726
+ end
727
+ assert_raise InvalidName do
728
+ a.rename("tes..t")
729
+ end
730
+
731
+ assert_equal 0, a.count()
732
+ assert_equal 0, b.count()
733
+
734
+ a.insert("x" => 1)
735
+ a.insert("x" => 2)
736
+
737
+ assert_equal 2, a.count()
738
+
739
+ a.rename("bar")
740
+
741
+ assert_equal 0, a.count()
742
+ assert_equal 2, b.count()
743
+
744
+ assert_equal 1, b.find().to_a()[0]["x"]
745
+ assert_equal 2, b.find().to_a()[1]["x"]
746
+
747
+ b.rename(:foo)
748
+
749
+ assert_equal 2, a.count()
750
+ assert_equal 0, b.count()
751
+ end
752
+
753
+ # doesn't really test functionality, just that the option is set correctly
754
+ def test_snapshot
755
+ @@db.collection("test").find({}, :snapshot => true).to_a
756
+ assert_raise OperationFailure do
757
+ @@db.collection("test").find({}, :snapshot => true, :sort => 'a').to_a
758
+ end
759
+ end
760
+
761
+ def test_encodings
762
+ if RUBY_VERSION >= '1.9'
763
+ ascii = "hello world"
764
+ utf8 = "hello world".encode("UTF-8")
765
+ iso8859 = "hello world".encode("ISO-8859-1")
766
+
767
+ assert_equal "US-ASCII", ascii.encoding.name
768
+ assert_equal "UTF-8", utf8.encoding.name
769
+ assert_equal "ISO-8859-1", iso8859.encoding.name
770
+
771
+ @@coll.remove
772
+ @@coll.save("ascii" => ascii, "utf8" => utf8, "iso8859" => iso8859)
773
+ doc = @@coll.find_one()
774
+
775
+ assert_equal "UTF-8", doc["ascii"].encoding.name
776
+ assert_equal "UTF-8", doc["utf8"].encoding.name
777
+ assert_equal "UTF-8", doc["iso8859"].encoding.name
778
+ end
779
+ end
780
+ end