mongo-lyon 1.2.4

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