jonbell-mongo 1.3.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/LICENSE.txt +190 -0
  2. data/README.md +333 -0
  3. data/Rakefile +215 -0
  4. data/bin/mongo_console +21 -0
  5. data/docs/CREDITS.md +123 -0
  6. data/docs/FAQ.md +116 -0
  7. data/docs/GridFS.md +158 -0
  8. data/docs/HISTORY.md +263 -0
  9. data/docs/RELEASES.md +33 -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 +97 -0
  14. data/lib/mongo/collection.rb +895 -0
  15. data/lib/mongo/connection.rb +926 -0
  16. data/lib/mongo/cursor.rb +474 -0
  17. data/lib/mongo/db.rb +617 -0
  18. data/lib/mongo/exceptions.rb +71 -0
  19. data/lib/mongo/gridfs/grid.rb +107 -0
  20. data/lib/mongo/gridfs/grid_ext.rb +57 -0
  21. data/lib/mongo/gridfs/grid_file_system.rb +146 -0
  22. data/lib/mongo/gridfs/grid_io.rb +485 -0
  23. data/lib/mongo/gridfs/grid_io_fix.rb +38 -0
  24. data/lib/mongo/repl_set_connection.rb +356 -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 +177 -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 +185 -0
  31. data/mongo.gemspec +34 -0
  32. data/test/auxillary/1.4_features.rb +166 -0
  33. data/test/auxillary/authentication_test.rb +68 -0
  34. data/test/auxillary/autoreconnect_test.rb +41 -0
  35. data/test/auxillary/fork_test.rb +30 -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 +654 -0
  41. data/test/bson/byte_buffer_test.rb +208 -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 +210 -0
  46. data/test/bson/timestamp_test.rb +24 -0
  47. data/test/collection_test.rb +910 -0
  48. data/test/connection_test.rb +324 -0
  49. data/test/conversions_test.rb +119 -0
  50. data/test/cursor_fail_test.rb +75 -0
  51. data/test/cursor_message_test.rb +43 -0
  52. data/test/cursor_test.rb +483 -0
  53. data/test/db_api_test.rb +738 -0
  54. data/test/db_connection_test.rb +15 -0
  55. data/test/db_test.rb +315 -0
  56. data/test/grid_file_system_test.rb +259 -0
  57. data/test/grid_io_test.rb +209 -0
  58. data/test/grid_test.rb +258 -0
  59. data/test/load/thin/load.rb +24 -0
  60. data/test/load/unicorn/load.rb +23 -0
  61. data/test/replica_sets/connect_test.rb +112 -0
  62. data/test/replica_sets/connection_string_test.rb +32 -0
  63. data/test/replica_sets/count_test.rb +35 -0
  64. data/test/replica_sets/insert_test.rb +53 -0
  65. data/test/replica_sets/pooled_insert_test.rb +55 -0
  66. data/test/replica_sets/query_secondaries.rb +108 -0
  67. data/test/replica_sets/query_test.rb +51 -0
  68. data/test/replica_sets/replication_ack_test.rb +66 -0
  69. data/test/replica_sets/rs_test_helper.rb +27 -0
  70. data/test/safe_test.rb +68 -0
  71. data/test/support/hash_with_indifferent_access.rb +186 -0
  72. data/test/support/keys.rb +45 -0
  73. data/test/support_test.rb +18 -0
  74. data/test/test_helper.rb +102 -0
  75. data/test/threading/threading_with_large_pool_test.rb +90 -0
  76. data/test/threading_test.rb +87 -0
  77. data/test/tools/auth_repl_set_manager.rb +14 -0
  78. data/test/tools/repl_set_manager.rb +266 -0
  79. data/test/unit/collection_test.rb +130 -0
  80. data/test/unit/connection_test.rb +85 -0
  81. data/test/unit/cursor_test.rb +109 -0
  82. data/test/unit/db_test.rb +94 -0
  83. data/test/unit/grid_test.rb +49 -0
  84. data/test/unit/pool_test.rb +9 -0
  85. data/test/unit/repl_set_connection_test.rb +59 -0
  86. data/test/unit/safe_test.rb +125 -0
  87. data/test/uri_test.rb +91 -0
  88. metadata +224 -0
@@ -0,0 +1,738 @@
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?('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_collection_options_are_passed_to_the_existing_ones
274
+ @@db.drop_collection('foobar')
275
+
276
+ @@db.create_collection('foobar')
277
+
278
+ opts = {:safe => true}
279
+ coll = @@db.create_collection('foobar', opts)
280
+ assert_equal true, coll.safe
281
+ end
282
+
283
+
284
+ def test_index_information
285
+ assert_equal @@coll.index_information.length, 1
286
+
287
+ name = @@coll.create_index('a')
288
+ info = @@db.index_information(@@coll.name)
289
+ assert_equal name, "a_1"
290
+ assert_equal @@coll.index_information, info
291
+ assert_equal 2, info.length
292
+
293
+ assert info.has_key?(name)
294
+ assert_equal info[name]["key"], {"a" => 1}
295
+ ensure
296
+ @@db.drop_index(@@coll.name, name)
297
+ end
298
+
299
+ def test_index_create_with_symbol
300
+ assert_equal @@coll.index_information.length, 1
301
+
302
+ name = @@coll.create_index([['a', 1]])
303
+ info = @@db.index_information(@@coll.name)
304
+ assert_equal name, "a_1"
305
+ assert_equal @@coll.index_information, info
306
+ assert_equal 2, info.length
307
+
308
+ assert info.has_key?(name)
309
+ assert_equal info[name]['key'], {"a" => 1}
310
+ ensure
311
+ @@db.drop_index(@@coll.name, name)
312
+ end
313
+
314
+ def test_multiple_index_cols
315
+ name = @@coll.create_index([['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]])
316
+ info = @@db.index_information(@@coll.name)
317
+ assert_equal 2, info.length
318
+
319
+ assert_equal name, 'a_-1_b_1_c_-1'
320
+ assert info.has_key?(name)
321
+ assert_equal info[name]['key'], {"a" => -1, "b" => 1, "c" => -1}
322
+ ensure
323
+ @@db.drop_index(@@coll.name, name)
324
+ end
325
+
326
+ def test_multiple_index_cols_with_symbols
327
+ name = @@coll.create_index([[:a, DESCENDING], [:b, ASCENDING], [:c, DESCENDING]])
328
+ info = @@db.index_information(@@coll.name)
329
+ assert_equal 2, info.length
330
+
331
+ assert_equal name, 'a_-1_b_1_c_-1'
332
+ assert info.has_key?(name)
333
+ assert_equal info[name]['key'], {"a" => -1, "b" => 1, "c" => -1}
334
+ ensure
335
+ @@db.drop_index(@@coll.name, name)
336
+ end
337
+
338
+ def test_unique_index
339
+ @@db.drop_collection("blah")
340
+ test = @@db.collection("blah")
341
+ test.create_index("hello")
342
+
343
+ test.insert("hello" => "world")
344
+ test.insert("hello" => "mike")
345
+ test.insert("hello" => "world")
346
+ assert !@@db.error?
347
+
348
+ @@db.drop_collection("blah")
349
+ test = @@db.collection("blah")
350
+ test.create_index("hello", :unique => true)
351
+
352
+ test.insert("hello" => "world")
353
+ test.insert("hello" => "mike")
354
+ test.insert("hello" => "world")
355
+ assert @@db.error?
356
+ end
357
+
358
+ def test_index_on_subfield
359
+ @@db.drop_collection("blah")
360
+ test = @@db.collection("blah")
361
+
362
+ test.insert("hello" => {"a" => 4, "b" => 5})
363
+ test.insert("hello" => {"a" => 7, "b" => 2})
364
+ test.insert("hello" => {"a" => 4, "b" => 10})
365
+ assert !@@db.error?
366
+
367
+ @@db.drop_collection("blah")
368
+ test = @@db.collection("blah")
369
+ test.create_index("hello.a", :unique => true)
370
+
371
+ test.insert("hello" => {"a" => 4, "b" => 5})
372
+ test.insert("hello" => {"a" => 7, "b" => 2})
373
+ test.insert("hello" => {"a" => 4, "b" => 10})
374
+ assert @@db.error?
375
+ end
376
+
377
+ def test_array
378
+ @@coll.remove
379
+ @@coll.insert({'b' => [1, 2, 3]})
380
+ @@coll.insert({'b' => [1, 2, 3]})
381
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
382
+ assert_equal 2, rows.length
383
+ assert_equal [1, 2, 3], rows[1]['b']
384
+ end
385
+
386
+ def test_regex
387
+ regex = /foobar/i
388
+ @@coll << {'b' => regex}
389
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
390
+ if @@version < "1.1.3"
391
+ assert_equal 1, rows.length
392
+ assert_equal regex, rows[0]['b']
393
+ else
394
+ assert_equal 2, rows.length
395
+ assert_equal regex, rows[1]['b']
396
+ end
397
+ end
398
+
399
+ def test_regex_multi_line
400
+ if @@version >= "1.9.1"
401
+ doc = <<HERE
402
+ the lazy brown
403
+ fox
404
+ HERE
405
+ @@coll.save({:doc => doc})
406
+ assert @@coll.find_one({:doc => /n.*x/m})
407
+ @@coll.remove
408
+ end
409
+ end
410
+
411
+ def test_non_oid_id
412
+ # Note: can't use Time.new because that will include fractional seconds,
413
+ # which Mongo does not store.
414
+ t = Time.at(1234567890)
415
+ @@coll << {'_id' => t}
416
+ rows = @@coll.find({'_id' => t}).to_a
417
+ assert_equal 1, rows.length
418
+ assert_equal t, rows[0]['_id']
419
+ end
420
+
421
+ def test_strict
422
+ assert !@@db.strict?
423
+ @@db.strict = true
424
+ assert @@db.strict?
425
+ ensure
426
+ @@db.strict = false
427
+ end
428
+
429
+ def test_strict_access_collection
430
+ @@db.strict = true
431
+ begin
432
+ @@db.collection('does-not-exist')
433
+ fail "expected exception"
434
+ rescue => ex
435
+ assert_equal Mongo::MongoDBError, ex.class
436
+ assert_equal "Collection does-not-exist doesn't exist. Currently in strict mode.", ex.to_s
437
+ ensure
438
+ @@db.strict = false
439
+ @@db.drop_collection('does-not-exist')
440
+ end
441
+ end
442
+
443
+ def test_strict_create_collection
444
+ @@db.drop_collection('foobar')
445
+ @@db.strict = true
446
+
447
+ begin
448
+ @@db.create_collection('foobar')
449
+ assert true
450
+ rescue => ex
451
+ fail "did not expect exception \"#{ex}\""
452
+ end
453
+
454
+ # Now the collection exists. This time we should see an exception.
455
+ assert_raise Mongo::MongoDBError do
456
+ @@db.create_collection('foobar')
457
+ end
458
+ @@db.strict = false
459
+ @@db.drop_collection('foobar')
460
+
461
+ # Now we're not in strict mode - should succeed
462
+ @@db.create_collection('foobar')
463
+ @@db.create_collection('foobar')
464
+ @@db.drop_collection('foobar')
465
+ end
466
+
467
+ def test_where
468
+ @@coll.insert('a' => 2)
469
+ @@coll.insert('a' => 3)
470
+
471
+ assert_equal 3, @@coll.count
472
+ assert_equal 1, @@coll.find('$where' => BSON::Code.new('this.a > 2')).count()
473
+ assert_equal 2, @@coll.find('$where' => BSON::Code.new('this.a > i', {'i' => 1})).count()
474
+ end
475
+
476
+ def test_eval
477
+ assert_equal 3, @@db.eval('function (x) {return x;}', 3)
478
+
479
+ assert_equal nil, @@db.eval("function (x) {db.test_eval.save({y:x});}", 5)
480
+ assert_equal 5, @@db.collection('test_eval').find_one['y']
481
+
482
+ assert_equal 5, @@db.eval("function (x, y) {return x + y;}", 2, 3)
483
+ assert_equal 5, @@db.eval("function () {return 5;}")
484
+ assert_equal 5, @@db.eval("2 + 3;")
485
+
486
+ assert_equal 5, @@db.eval(Code.new("2 + 3;"))
487
+ assert_equal 2, @@db.eval(Code.new("return i;", {"i" => 2}))
488
+ assert_equal 5, @@db.eval(Code.new("i + 3;", {"i" => 2}))
489
+
490
+ assert_raise OperationFailure do
491
+ @@db.eval("5 ++ 5;")
492
+ end
493
+ end
494
+
495
+ def test_hint
496
+ name = @@coll.create_index('a')
497
+ begin
498
+ assert_nil @@coll.hint
499
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => 'a').to_a.size
500
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => ['a']).to_a.size
501
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => {'a' => 1}).to_a.size
502
+
503
+ @@coll.hint = 'a'
504
+ assert_equal({'a' => 1}, @@coll.hint)
505
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
506
+
507
+ @@coll.hint = ['a']
508
+ assert_equal({'a' => 1}, @@coll.hint)
509
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
510
+
511
+ @@coll.hint = {'a' => 1}
512
+ assert_equal({'a' => 1}, @@coll.hint)
513
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
514
+
515
+ @@coll.hint = nil
516
+ assert_nil @@coll.hint
517
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
518
+ ensure
519
+ @@coll.drop_index(name)
520
+ end
521
+ end
522
+
523
+ def test_hash_default_value_id
524
+ val = Hash.new(0)
525
+ val["x"] = 5
526
+ @@coll.insert val
527
+ id = @@coll.find_one("x" => 5)["_id"]
528
+ assert id != 0
529
+ end
530
+
531
+ def test_group
532
+ @@db.drop_collection("test")
533
+ test = @@db.collection("test")
534
+
535
+ assert_equal [], test.group(:initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")
536
+ assert_equal [], test.group(:initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")
537
+
538
+ test.insert("a" => 2)
539
+ test.insert("b" => 5)
540
+ test.insert("a" => 1)
541
+
542
+ assert_equal 3, test.group(:initial => {"count" => 0},
543
+ :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
544
+ assert_equal 3, test.group(:initial => {"count" => 0},
545
+ :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
546
+ assert_equal 1, test.group(:cond => {"a" => {"$gt" => 1}},
547
+ :initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
548
+ assert_equal 1, test.group(:cond => {"a" => {"$gt" => 1}},
549
+ :initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
550
+
551
+ finalize = "function (obj) { obj.f = obj.count - 1; }"
552
+ assert_equal 2, test.group(:initial => {"count" => 0},
553
+ :reduce => "function (obj, prev) { prev.count++; }", :finalize => finalize)[0]["f"]
554
+
555
+ test.insert("a" => 2, "b" => 3)
556
+ expected = [{"a" => 2, "count" => 2},
557
+ {"a" => nil, "count" => 1},
558
+ {"a" => 1, "count" => 1}]
559
+ assert_equal expected, test.group(:key => ["a"], :initial => {"count" => 0},
560
+ :reduce => "function (obj, prev) { prev.count++; }")
561
+ assert_equal expected, test.group(:key => :a, :initial => {"count" => 0},
562
+ :reduce => "function (obj, prev) { prev.count++; }")
563
+
564
+ assert_raise OperationFailure do
565
+ test.group(:initial => {}, :reduce => "5 ++ 5")
566
+ end
567
+ end
568
+
569
+ def test_deref
570
+ @@coll.remove
571
+
572
+ assert_equal nil, @@db.dereference(DBRef.new("test", ObjectId.new))
573
+ @@coll.insert({"x" => "hello"})
574
+ key = @@coll.find_one()["_id"]
575
+ assert_equal "hello", @@db.dereference(DBRef.new("test", key))["x"]
576
+
577
+ assert_equal nil, @@db.dereference(DBRef.new("test", 4))
578
+ obj = {"_id" => 4}
579
+ @@coll.insert(obj)
580
+ assert_equal obj, @@db.dereference(DBRef.new("test", 4))
581
+
582
+ @@coll.remove
583
+ @@coll.insert({"x" => "hello"})
584
+ assert_equal nil, @@db.dereference(DBRef.new("test", nil))
585
+ end
586
+
587
+ def test_save
588
+ @@coll.remove
589
+
590
+ a = {"hello" => "world"}
591
+
592
+ id = @@coll.save(a)
593
+ assert_kind_of ObjectId, id
594
+ assert_equal 1, @@coll.count
595
+
596
+ assert_equal id, @@coll.save(a)
597
+ assert_equal 1, @@coll.count
598
+
599
+ assert_equal "world", @@coll.find_one()["hello"]
600
+
601
+ a["hello"] = "mike"
602
+ @@coll.save(a)
603
+ assert_equal 1, @@coll.count
604
+
605
+ assert_equal "mike", @@coll.find_one()["hello"]
606
+
607
+ @@coll.save({"hello" => "world"})
608
+ assert_equal 2, @@coll.count
609
+ end
610
+
611
+ def test_save_long
612
+ @@coll.remove
613
+ @@coll.insert("x" => 9223372036854775807)
614
+ assert_equal 9223372036854775807, @@coll.find_one()["x"]
615
+ end
616
+
617
+ def test_find_by_oid
618
+ @@coll.remove
619
+
620
+ @@coll.save("hello" => "mike")
621
+ id = @@coll.save("hello" => "world")
622
+ assert_kind_of ObjectId, id
623
+
624
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
625
+ @@coll.find(:_id => id).to_a.each do |doc|
626
+ assert_equal "world", doc["hello"]
627
+ end
628
+
629
+ id = ObjectId.from_string(id.to_s)
630
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
631
+ end
632
+
633
+ def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
634
+ @@coll.remove
635
+
636
+ a = {'_id' => '1', 'hello' => 'world'}
637
+ @@coll.save(a)
638
+ assert_equal(1, @@coll.count)
639
+ assert_equal("world", @@coll.find_one()["hello"])
640
+
641
+ a["hello"] = "mike"
642
+ @@coll.save(a)
643
+ assert_equal(1, @@coll.count)
644
+ assert_equal("mike", @@coll.find_one()["hello"])
645
+ end
646
+
647
+ def test_collection_names_errors
648
+ assert_raise TypeError do
649
+ @@db.collection(5)
650
+ end
651
+ assert_raise Mongo::InvalidNSName do
652
+ @@db.collection("")
653
+ end
654
+ assert_raise Mongo::InvalidNSName do
655
+ @@db.collection("te$t")
656
+ end
657
+ assert_raise Mongo::InvalidNSName do
658
+ @@db.collection(".test")
659
+ end
660
+ assert_raise Mongo::InvalidNSName do
661
+ @@db.collection("test.")
662
+ end
663
+ assert_raise Mongo::InvalidNSName do
664
+ @@db.collection("tes..t")
665
+ end
666
+ end
667
+
668
+ def test_rename_collection
669
+ @@db.drop_collection("foo")
670
+ @@db.drop_collection("bar")
671
+ a = @@db.collection("foo")
672
+ b = @@db.collection("bar")
673
+
674
+ assert_raise TypeError do
675
+ a.rename(5)
676
+ end
677
+ assert_raise Mongo::InvalidNSName do
678
+ a.rename("")
679
+ end
680
+ assert_raise Mongo::InvalidNSName do
681
+ a.rename("te$t")
682
+ end
683
+ assert_raise Mongo::InvalidNSName do
684
+ a.rename(".test")
685
+ end
686
+ assert_raise Mongo::InvalidNSName do
687
+ a.rename("test.")
688
+ end
689
+ assert_raise Mongo::InvalidNSName do
690
+ a.rename("tes..t")
691
+ end
692
+
693
+ assert_equal 0, a.count()
694
+ assert_equal 0, b.count()
695
+
696
+ a.insert("x" => 1)
697
+ a.insert("x" => 2)
698
+
699
+ assert_equal 2, a.count()
700
+
701
+ a.rename("bar")
702
+
703
+ assert_equal 2, a.count()
704
+ end
705
+
706
+ # doesn't really test functionality, just that the option is set correctly
707
+ def test_snapshot
708
+ @@db.collection("test").find({}, :snapshot => true).to_a
709
+ assert_raise OperationFailure do
710
+ @@db.collection("test").find({}, :snapshot => true, :sort => 'a').to_a
711
+ end
712
+ end
713
+
714
+ def test_encodings
715
+ if RUBY_VERSION >= '1.9'
716
+ ascii = "hello world"
717
+ utf8 = "hello world".encode("UTF-8")
718
+ iso8859 = "hello world".encode("ISO-8859-1")
719
+
720
+ if RUBY_PLATFORM =~ /jruby/
721
+ assert_equal "ASCII-8BIT", ascii.encoding.name
722
+ else
723
+ assert_equal "US-ASCII", ascii.encoding.name
724
+ end
725
+
726
+ assert_equal "UTF-8", utf8.encoding.name
727
+ assert_equal "ISO-8859-1", iso8859.encoding.name
728
+
729
+ @@coll.remove
730
+ @@coll.save("ascii" => ascii, "utf8" => utf8, "iso8859" => iso8859)
731
+ doc = @@coll.find_one()
732
+
733
+ assert_equal "UTF-8", doc["ascii"].encoding.name
734
+ assert_equal "UTF-8", doc["utf8"].encoding.name
735
+ assert_equal "UTF-8", doc["iso8859"].encoding.name
736
+ end
737
+ end
738
+ end