jmongo 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +43 -0
  3. data/Rakefile +72 -0
  4. data/jmongo.gemspec +84 -6
  5. data/lib/jmongo.rb +6 -14
  6. data/lib/jmongo/collection.rb +196 -114
  7. data/lib/jmongo/connection.rb +39 -13
  8. data/lib/jmongo/cursor.rb +161 -63
  9. data/lib/jmongo/db.rb +119 -30
  10. data/lib/jmongo/exceptions.rb +39 -0
  11. data/lib/jmongo/mongo-2.6.5.gb1.jar +0 -0
  12. data/lib/jmongo/mongo/bson.rb +130 -0
  13. data/lib/jmongo/mongo/collection.rb +185 -0
  14. data/lib/jmongo/mongo/connection.rb +45 -0
  15. data/lib/jmongo/mongo/db.rb +31 -0
  16. data/lib/jmongo/mongo/jmongo.rb +44 -0
  17. data/lib/jmongo/mongo/mongo.rb +98 -0
  18. data/lib/jmongo/mongo/ruby_ext.rb +38 -0
  19. data/lib/jmongo/mongo/utils.rb +136 -0
  20. data/lib/jmongo/version.rb +1 -1
  21. data/test-results.txt +98 -0
  22. data/test/auxillary/1.4_features.rb +166 -0
  23. data/test/auxillary/authentication_test.rb +68 -0
  24. data/test/auxillary/autoreconnect_test.rb +41 -0
  25. data/test/auxillary/fork_test.rb +30 -0
  26. data/test/auxillary/repl_set_auth_test.rb +58 -0
  27. data/test/auxillary/slave_connection_test.rb +36 -0
  28. data/test/auxillary/threaded_authentication_test.rb +101 -0
  29. data/test/bson/binary_test.rb +15 -0
  30. data/test/bson/bson_test.rb +657 -0
  31. data/test/bson/byte_buffer_test.rb +208 -0
  32. data/test/bson/hash_with_indifferent_access_test.rb +38 -0
  33. data/test/bson/json_test.rb +17 -0
  34. data/test/bson/object_id_test.rb +138 -0
  35. data/test/bson/ordered_hash_test.rb +245 -0
  36. data/test/bson/test_helper.rb +46 -0
  37. data/test/bson/timestamp_test.rb +46 -0
  38. data/test/collection_test.rb +933 -0
  39. data/test/connection_test.rb +325 -0
  40. data/test/conversions_test.rb +121 -0
  41. data/test/cursor_fail_test.rb +75 -0
  42. data/test/cursor_message_test.rb +43 -0
  43. data/test/cursor_test.rb +547 -0
  44. data/test/data/empty_data +0 -0
  45. data/test/data/sample_data +0 -0
  46. data/test/data/sample_file.pdf +0 -0
  47. data/test/data/small_data.txt +1 -0
  48. data/test/db_api_test.rb +739 -0
  49. data/test/db_connection_test.rb +15 -0
  50. data/test/db_test.rb +325 -0
  51. data/test/grid_file_system_test.rb +260 -0
  52. data/test/grid_io_test.rb +210 -0
  53. data/test/grid_test.rb +259 -0
  54. data/test/load/thin/config.ru +6 -0
  55. data/test/load/thin/config.yml.template +6 -0
  56. data/test/load/thin/load.rb +24 -0
  57. data/test/load/unicorn/config.ru +6 -0
  58. data/test/load/unicorn/load.rb +23 -0
  59. data/test/load/unicorn/unicorn.rb.template +29 -0
  60. data/test/replica_sets/connect_test.rb +111 -0
  61. data/test/replica_sets/connection_string_test.rb +29 -0
  62. data/test/replica_sets/count_test.rb +36 -0
  63. data/test/replica_sets/insert_test.rb +54 -0
  64. data/test/replica_sets/pooled_insert_test.rb +58 -0
  65. data/test/replica_sets/query_secondaries.rb +109 -0
  66. data/test/replica_sets/query_test.rb +52 -0
  67. data/test/replica_sets/read_preference_test.rb +43 -0
  68. data/test/replica_sets/refresh_test.rb +123 -0
  69. data/test/replica_sets/replication_ack_test.rb +71 -0
  70. data/test/replica_sets/rs_test_helper.rb +27 -0
  71. data/test/safe_test.rb +68 -0
  72. data/test/support/hash_with_indifferent_access.rb +186 -0
  73. data/test/support/keys.rb +45 -0
  74. data/test/support_test.rb +19 -0
  75. data/test/test_helper.rb +111 -0
  76. data/test/threading/threading_with_large_pool_test.rb +90 -0
  77. data/test/threading_test.rb +88 -0
  78. data/test/tools/auth_repl_set_manager.rb +14 -0
  79. data/test/tools/keyfile.txt +1 -0
  80. data/test/tools/repl_set_manager.rb +377 -0
  81. data/test/unit/collection_test.rb +128 -0
  82. data/test/unit/connection_test.rb +85 -0
  83. data/test/unit/cursor_test.rb +127 -0
  84. data/test/unit/db_test.rb +96 -0
  85. data/test/unit/grid_test.rb +51 -0
  86. data/test/unit/node_test.rb +73 -0
  87. data/test/unit/pool_manager_test.rb +47 -0
  88. data/test/unit/pool_test.rb +9 -0
  89. data/test/unit/read_test.rb +101 -0
  90. data/test/unit/safe_test.rb +125 -0
  91. data/test/uri_test.rb +92 -0
  92. metadata +170 -99
  93. data/lib/jmongo/ajrb.rb +0 -189
  94. data/lib/jmongo/jmongo_jext.rb +0 -302
  95. data/lib/jmongo/mongo-2.6.3.jar +0 -0
  96. data/lib/jmongo/utils.rb +0 -61
File without changes
Binary file
Binary file
@@ -0,0 +1 @@
1
+ This is pretty small data
@@ -0,0 +1,739 @@
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
+ info = @@coll.index_information
301
+ assert_equal info.length, 1
302
+ apr info, 'test_index_create_with_symbol INFO'
303
+ name = @@coll.create_index([['a', 1]])
304
+ info = @@db.index_information(@@coll.name)
305
+ assert_equal name, "a_1"
306
+ assert_equal @@coll.index_information, info
307
+ assert_equal 2, info.length
308
+
309
+ assert info.has_key?(name)
310
+ assert_equal info[name]['key'], {"a" => 1}
311
+ ensure
312
+ @@db.drop_index(@@coll.name, name)
313
+ end
314
+
315
+ def test_multiple_index_cols
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_multiple_index_cols_with_symbols
328
+ name = @@coll.create_index([[:a, DESCENDING], [:b, ASCENDING], [:c, DESCENDING]])
329
+ info = @@db.index_information(@@coll.name)
330
+ assert_equal 2, info.length
331
+
332
+ assert_equal name, 'a_-1_b_1_c_-1'
333
+ assert info.has_key?(name)
334
+ assert_equal info[name]['key'], {"a" => -1, "b" => 1, "c" => -1}
335
+ ensure
336
+ @@db.drop_index(@@coll.name, name)
337
+ end
338
+
339
+ def test_unique_index
340
+ @@db.drop_collection("blah")
341
+ test = @@db.collection("blah")
342
+ test.create_index("hello")
343
+
344
+ test.insert("hello" => "world")
345
+ test.insert("hello" => "mike")
346
+ test.insert("hello" => "world")
347
+ assert !@@db.error?
348
+
349
+ @@db.drop_collection("blah")
350
+ test = @@db.collection("blah")
351
+ test.create_index("hello", :unique => true)
352
+
353
+ test.insert("hello" => "world")
354
+ test.insert("hello" => "mike")
355
+ test.insert("hello" => "world")
356
+ assert @@db.error?
357
+ end
358
+
359
+ def test_index_on_subfield
360
+ @@db.drop_collection("blah")
361
+ test = @@db.collection("blah")
362
+
363
+ test.insert("hello" => {"a" => 4, "b" => 5})
364
+ test.insert("hello" => {"a" => 7, "b" => 2})
365
+ test.insert("hello" => {"a" => 4, "b" => 10})
366
+ assert !@@db.error?
367
+
368
+ @@db.drop_collection("blah")
369
+ test = @@db.collection("blah")
370
+ test.create_index("hello.a", :unique => true)
371
+
372
+ test.insert("hello" => {"a" => 4, "b" => 5})
373
+ test.insert("hello" => {"a" => 7, "b" => 2})
374
+ test.insert("hello" => {"a" => 4, "b" => 10})
375
+ assert @@db.error?
376
+ end
377
+
378
+ def test_array
379
+ @@coll.remove
380
+ @@coll.insert({'b' => [1, 2, 3]})
381
+ @@coll.insert({'b' => [1, 2, 3]})
382
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
383
+ assert_equal 2, rows.length
384
+ assert_equal [1, 2, 3], rows[1]['b']
385
+ end
386
+
387
+ def test_regex
388
+ regex = /foobar/i
389
+ @@coll << {'b' => regex}
390
+ rows = @@coll.find({}, {:fields => ['b']}).to_a
391
+ if @@version < "1.1.3"
392
+ assert_equal 1, rows.length
393
+ assert_equal regex, rows[0]['b']
394
+ else
395
+ assert_equal 2, rows.length
396
+ assert_equal regex, rows[1]['b']
397
+ end
398
+ end
399
+
400
+ def test_regex_multi_line
401
+ if @@version >= "1.9.1"
402
+ doc = <<HERE
403
+ the lazy brown
404
+ fox
405
+ HERE
406
+ @@coll.save({:doc => doc})
407
+ assert @@coll.find_one({:doc => /n.*x/m})
408
+ @@coll.remove
409
+ end
410
+ end
411
+
412
+ def test_non_oid_id
413
+ # Note: can't use Time.new because that will include fractional seconds,
414
+ # which Mongo does not store.
415
+ t = Time.at(1234567890)
416
+ @@coll << {'_id' => t}
417
+ rows = @@coll.find({'_id' => t}).to_a
418
+ assert_equal 1, rows.length
419
+ assert_equal t, rows[0]['_id']
420
+ end
421
+
422
+ def test_strict
423
+ assert !@@db.strict?
424
+ @@db.strict = true
425
+ assert @@db.strict?
426
+ ensure
427
+ @@db.strict = false
428
+ end
429
+
430
+ def test_strict_access_collection
431
+ @@db.strict = true
432
+ begin
433
+ @@db.collection('does-not-exist')
434
+ fail "expected exception"
435
+ rescue => ex
436
+ assert_equal Mongo::MongoDBError, ex.class
437
+ assert_equal "Collection does-not-exist doesn't exist. Currently in strict mode.", ex.to_s
438
+ ensure
439
+ @@db.strict = false
440
+ @@db.drop_collection('does-not-exist')
441
+ end
442
+ end
443
+
444
+ def test_strict_create_collection
445
+ @@db.drop_collection('foobar')
446
+ @@db.strict = true
447
+
448
+ begin
449
+ @@db.create_collection('foobar')
450
+ assert true
451
+ rescue => ex
452
+ fail "did not expect exception \"#{ex}\""
453
+ end
454
+
455
+ # Now the collection exists. This time we should see an exception.
456
+ assert_raise Mongo::MongoDBError do
457
+ @@db.create_collection('foobar')
458
+ end
459
+ @@db.strict = false
460
+ @@db.drop_collection('foobar')
461
+
462
+ # Now we're not in strict mode - should succeed
463
+ @@db.create_collection('foobar')
464
+ @@db.create_collection('foobar')
465
+ @@db.drop_collection('foobar')
466
+ end
467
+
468
+ def test_where
469
+ @@coll.insert('a' => 2)
470
+ @@coll.insert('a' => 3)
471
+
472
+ assert_equal 3, @@coll.count
473
+ assert_equal 1, @@coll.find('$where' => BSON::Code.new('this.a > 2')).count()
474
+ assert_equal 2, @@coll.find('$where' => BSON::Code.new('this.a > i', {'i' => 1})).count()
475
+ end
476
+
477
+ def test_eval
478
+ assert_equal 3, @@db.eval('function (x) {return x;}', 3)
479
+
480
+ assert_equal nil, @@db.eval("function (x) {db.test_eval.save({y:x});}", 5)
481
+ assert_equal 5, @@db.collection('test_eval').find_one['y']
482
+
483
+ assert_equal 5, @@db.eval("function (x, y) {return x + y;}", 2, 3)
484
+ assert_equal 5, @@db.eval("function () {return 5;}")
485
+ assert_equal 5, @@db.eval("2 + 3;")
486
+
487
+ assert_equal 5, @@db.eval(Code.new("2 + 3;"))
488
+ assert_equal 2, @@db.eval(Code.new("return i;", {"i" => 2}))
489
+ assert_equal 5, @@db.eval(Code.new("i + 3;", {"i" => 2}))
490
+
491
+ assert_raise OperationFailure do
492
+ @@db.eval("5 ++ 5;")
493
+ end
494
+ end
495
+
496
+ def test_hint
497
+ name = @@coll.create_index('a')
498
+ begin
499
+ assert_nil @@coll.hint
500
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => 'a').to_a.size
501
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => ['a']).to_a.size
502
+ assert_equal 1, @@coll.find({'a' => 1}, :hint => {'a' => 1}).to_a.size
503
+
504
+ @@coll.hint = 'a'
505
+ assert_equal({'a' => 1}, @@coll.hint)
506
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
507
+
508
+ @@coll.hint = ['a']
509
+ assert_equal({'a' => 1}, @@coll.hint)
510
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
511
+
512
+ @@coll.hint = {'a' => 1}
513
+ assert_equal({'a' => 1}, @@coll.hint)
514
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
515
+
516
+ @@coll.hint = nil
517
+ assert_nil @@coll.hint
518
+ assert_equal 1, @@coll.find('a' => 1).to_a.size
519
+ ensure
520
+ @@coll.drop_index(name)
521
+ end
522
+ end
523
+
524
+ def test_hash_default_value_id
525
+ val = Hash.new(0)
526
+ val["x"] = 5
527
+ @@coll.insert val
528
+ id = @@coll.find_one("x" => 5)["_id"]
529
+ assert id != 0
530
+ end
531
+
532
+ def test_group
533
+ @@db.drop_collection("test")
534
+ test = @@db.collection("test")
535
+
536
+ assert_equal [], test.group(:initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")
537
+ assert_equal [], test.group(:initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")
538
+
539
+ test.insert("a" => 2)
540
+ test.insert("b" => 5)
541
+ test.insert("a" => 1)
542
+
543
+ assert_equal 3, test.group(:initial => {"count" => 0},
544
+ :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
545
+ assert_equal 3, test.group(:initial => {"count" => 0},
546
+ :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
547
+ assert_equal 1, test.group(:cond => {"a" => {"$gt" => 1}},
548
+ :initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
549
+ assert_equal 1, test.group(:cond => {"a" => {"$gt" => 1}},
550
+ :initial => {"count" => 0}, :reduce => "function (obj, prev) { prev.count++; }")[0]["count"]
551
+
552
+ finalize = "function (obj) { obj.f = obj.count - 1; }"
553
+ assert_equal 2, test.group(:initial => {"count" => 0},
554
+ :reduce => "function (obj, prev) { prev.count++; }", :finalize => 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(:key => ["a"], :initial => {"count" => 0},
561
+ :reduce => "function (obj, prev) { prev.count++; }")
562
+ assert_equal expected, test.group(:key => :a, :initial => {"count" => 0},
563
+ :reduce => "function (obj, prev) { prev.count++; }")
564
+
565
+ assert_raise OperationFailure do
566
+ test.group(:initial => {}, :reduce => "5 ++ 5")
567
+ end
568
+ end
569
+
570
+ def test_deref
571
+ @@coll.remove
572
+
573
+ assert_equal nil, @@db.dereference(DBRef.new("test", ObjectId.new))
574
+ @@coll.insert({"x" => "hello"})
575
+ key = @@coll.find_one()["_id"]
576
+ assert_equal "hello", @@db.dereference(DBRef.new("test", key))["x"]
577
+
578
+ assert_equal nil, @@db.dereference(DBRef.new("test", 4))
579
+ obj = {"_id" => 4}
580
+ @@coll.insert(obj)
581
+ assert_equal obj, @@db.dereference(DBRef.new("test", 4))
582
+
583
+ @@coll.remove
584
+ @@coll.insert({"x" => "hello"})
585
+ assert_equal nil, @@db.dereference(DBRef.new("test", nil))
586
+ end
587
+
588
+ def test_save
589
+ @@coll.remove
590
+
591
+ a = {"hello" => "world"}
592
+
593
+ id = @@coll.save(a)
594
+ assert_kind_of ObjectId, id
595
+ assert_equal 1, @@coll.count
596
+
597
+ assert_equal id, @@coll.save(a)
598
+ assert_equal 1, @@coll.count
599
+
600
+ assert_equal "world", @@coll.find_one()["hello"]
601
+
602
+ a["hello"] = "mike"
603
+ @@coll.save(a)
604
+ assert_equal 1, @@coll.count
605
+
606
+ assert_equal "mike", @@coll.find_one()["hello"]
607
+
608
+ @@coll.save({"hello" => "world"})
609
+ assert_equal 2, @@coll.count
610
+ end
611
+
612
+ def test_save_long
613
+ @@coll.remove
614
+ @@coll.insert("x" => 9223372036854775807)
615
+ assert_equal 9223372036854775807, @@coll.find_one()["x"]
616
+ end
617
+
618
+ def test_find_by_oid
619
+ @@coll.remove
620
+
621
+ @@coll.save("hello" => "mike")
622
+ id = @@coll.save("hello" => "world")
623
+ assert_kind_of ObjectId, id
624
+
625
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
626
+ @@coll.find(:_id => id).to_a.each do |doc|
627
+ assert_equal "world", doc["hello"]
628
+ end
629
+
630
+ id = ObjectId.from_string(id.to_s)
631
+ assert_equal "world", @@coll.find_one(:_id => id)["hello"]
632
+ end
633
+
634
+ def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
635
+ @@coll.remove
636
+
637
+ a = {'_id' => '1', 'hello' => 'world'}
638
+ @@coll.save(a)
639
+ assert_equal(1, @@coll.count)
640
+ assert_equal("world", @@coll.find_one()["hello"])
641
+
642
+ a["hello"] = "mike"
643
+ @@coll.save(a)
644
+ assert_equal(1, @@coll.count)
645
+ assert_equal("mike", @@coll.find_one()["hello"])
646
+ end
647
+
648
+ def test_collection_names_errors
649
+ assert_raise TypeError do
650
+ @@db.collection(5)
651
+ end
652
+ assert_raise Mongo::InvalidNSName do
653
+ @@db.collection("")
654
+ end
655
+ assert_raise Mongo::InvalidNSName do
656
+ @@db.collection("te$t")
657
+ end
658
+ assert_raise Mongo::InvalidNSName do
659
+ @@db.collection(".test")
660
+ end
661
+ assert_raise Mongo::InvalidNSName do
662
+ @@db.collection("test.")
663
+ end
664
+ assert_raise Mongo::InvalidNSName do
665
+ @@db.collection("tes..t")
666
+ end
667
+ end
668
+
669
+ def test_rename_collection
670
+ @@db.drop_collection("foo")
671
+ @@db.drop_collection("bar")
672
+ a = @@db.collection("foo")
673
+ b = @@db.collection("bar")
674
+
675
+ assert_raise TypeError do
676
+ a.rename(5)
677
+ end
678
+ assert_raise Mongo::InvalidNSName do
679
+ a.rename("")
680
+ end
681
+ assert_raise Mongo::InvalidNSName do
682
+ a.rename("te$t")
683
+ end
684
+ assert_raise Mongo::InvalidNSName do
685
+ a.rename(".test")
686
+ end
687
+ assert_raise Mongo::InvalidNSName do
688
+ a.rename("test.")
689
+ end
690
+ assert_raise Mongo::InvalidNSName do
691
+ a.rename("tes..t")
692
+ end
693
+
694
+ assert_equal 0, a.count()
695
+ assert_equal 0, b.count()
696
+
697
+ a.insert("x" => 1)
698
+ a.insert("x" => 2)
699
+
700
+ assert_equal 2, a.count()
701
+
702
+ a.rename("bar")
703
+
704
+ assert_equal 2, a.count()
705
+ end
706
+
707
+ # doesn't really test functionality, just that the option is set correctly
708
+ def test_snapshot
709
+ @@db.collection("test").find({}, :snapshot => true).to_a
710
+ assert_raise OperationFailure do
711
+ @@db.collection("test").find({}, :snapshot => true, :sort => 'a').to_a
712
+ end
713
+ end
714
+
715
+ def test_encodings
716
+ if RUBY_VERSION >= '1.9'
717
+ ascii = "hello world"
718
+ utf8 = "hello world".encode("UTF-8")
719
+ iso8859 = "hello world".encode("ISO-8859-1")
720
+
721
+ if RUBY_PLATFORM =~ /jruby/
722
+ assert_equal "ASCII-8BIT", ascii.encoding.name
723
+ else
724
+ assert_equal "US-ASCII", ascii.encoding.name
725
+ end
726
+
727
+ assert_equal "UTF-8", utf8.encoding.name
728
+ assert_equal "ISO-8859-1", iso8859.encoding.name
729
+
730
+ @@coll.remove
731
+ @@coll.save("ascii" => ascii, "utf8" => utf8, "iso8859" => iso8859)
732
+ doc = @@coll.find_one()
733
+
734
+ assert_equal "UTF-8", doc["ascii"].encoding.name
735
+ assert_equal "UTF-8", doc["utf8"].encoding.name
736
+ assert_equal "UTF-8", doc["iso8859"].encoding.name
737
+ end
738
+ end
739
+ end