mongo 0.18.1 → 0.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,7 +25,7 @@ module Mongo
25
25
  # Implements comparable.
26
26
  def <=>(new)
27
27
  local, new = self.to_a, to_array(new)
28
- for n in 0...local.size do
28
+ for n in 0...local.size do
29
29
  break if elements_include_mods?(local[n], new[n])
30
30
  if local[n] < new[n].to_i
31
31
  result = -1
@@ -52,10 +52,10 @@ module Mongo
52
52
 
53
53
  # Returns true if any elements include mod symbols (-, +)
54
54
  def elements_include_mods?(*elements)
55
- elements.any? { |n| n =~ /[\-\+]/ }
55
+ elements.any? { |n| n =~ /[\-\+]/ }
56
56
  end
57
57
 
58
- # Converts argument to an array of integers,
58
+ # Converts argument to an array of integers,
59
59
  # appending any mods as the final element.
60
60
  def to_array(version)
61
61
  array = version.split(".").map {|n| (n =~ /^\d+$/) ? n.to_i : n }
@@ -6,8 +6,8 @@ require 'test/test_helper'
6
6
  # NOTE: this test should be run only if a replica pair is running.
7
7
  class ReplicaPairCountTest < Test::Unit::TestCase
8
8
  include Mongo
9
-
10
- def setup
9
+
10
+ def setup
11
11
  @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
12
  @db = @conn.db('mongo-ruby-test')
13
13
  @db.drop_collection("test-pairs")
@@ -24,7 +24,7 @@ class ReplicaPairCountTest < Test::Unit::TestCase
24
24
  puts "Please disconnect the current master."
25
25
  gets
26
26
 
27
- rescue_connection_failure do
27
+ rescue_connection_failure do
28
28
  @coll.insert({:a => 30}, :safe => true)
29
29
  end
30
30
  @coll.insert({:a => 40}, :safe => true)
@@ -6,8 +6,8 @@ require 'test/test_helper'
6
6
  # NOTE: this test should be run only if a replica pair is running.
7
7
  class ReplicaPairInsertTest < Test::Unit::TestCase
8
8
  include Mongo
9
-
10
- def setup
9
+
10
+ def setup
11
11
  @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
12
  @db = @conn.db('mongo-ruby-test')
13
13
  @db.drop_collection("test-pairs")
@@ -19,7 +19,7 @@ class ReplicaPairInsertTest < Test::Unit::TestCase
19
19
  puts "Please disconnect the current master."
20
20
  gets
21
21
 
22
- rescue_connection_failure do
22
+ rescue_connection_failure do
23
23
  @coll.save({:a => 30}, :safe => true)
24
24
  end
25
25
 
@@ -28,12 +28,12 @@ class ReplicaPairInsertTest < Test::Unit::TestCase
28
28
  @coll.save({:a => 60}, :safe => true)
29
29
  @coll.save({:a => 70}, :safe => true)
30
30
 
31
- puts "Please reconnect the old master to make sure that the new master " +
31
+ puts "Please reconnect the old master to make sure that the new master " +
32
32
  "has synced with the previous master. Note: this may have happened already."
33
33
  gets
34
34
  results = []
35
-
36
- rescue_connection_failure do
35
+
36
+ rescue_connection_failure do
37
37
  @coll.find.each {|r| results << r}
38
38
  [20, 30, 40, 50, 60, 70].each do |a|
39
39
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
@@ -6,8 +6,8 @@ require 'test/test_helper'
6
6
  # NOTE: this test should be run only if a replica pair is running.
7
7
  class ReplicaPairPooledInsertTest < Test::Unit::TestCase
8
8
  include Mongo
9
-
10
- def setup
9
+
10
+ def setup
11
11
  @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil, :pool_size => 10, :timeout => 5)
12
12
  @db = @conn.db('mongo-ruby-test')
13
13
  @db.drop_collection("test-pairs")
@@ -22,22 +22,22 @@ class ReplicaPairPooledInsertTest < Test::Unit::TestCase
22
22
 
23
23
  threads = []
24
24
  10.times do |i|
25
- threads[i] = Thread.new do
26
- rescue_connection_failure do
25
+ threads[i] = Thread.new do
26
+ rescue_connection_failure do
27
27
  @coll.save({:a => i}, :safe => true)
28
28
  end
29
29
  end
30
30
  end
31
31
 
32
- puts "Please reconnect the old master to make sure that the new master " +
33
- "has synced with the previous master. Note: this may have happened already." +
32
+ puts "Please reconnect the old master to make sure that the new master " +
33
+ "has synced with the previous master. Note: this may have happened already." +
34
34
  "Note also that when connection with multiple threads, you may need to wait a few seconds" +
35
35
  "after restarting the old master so that all the data has had a chance to sync." +
36
36
  "This is a case of eventual consistency."
37
37
  gets
38
38
  results = []
39
-
40
- rescue_connection_failure do
39
+
40
+ rescue_connection_failure do
41
41
  @coll.find.each {|r| results << r}
42
42
  expected_results.each do |a|
43
43
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
@@ -6,8 +6,8 @@ require 'test/test_helper'
6
6
  # NOTE: this test should be run only if a replica pair is running.
7
7
  class ReplicaPairQueryTest < Test::Unit::TestCase
8
8
  include Mongo
9
-
10
- def setup
9
+
10
+ def setup
11
11
  @conn = Mongo::Connection.new({:left => ["localhost", 27017], :right => ["localhost", 27018]}, nil)
12
12
  @db = @conn.db('mongo-ruby-test')
13
13
  @db.drop_collection("test-pairs")
@@ -28,7 +28,7 @@ class ReplicaPairQueryTest < Test::Unit::TestCase
28
28
  gets
29
29
 
30
30
  results = []
31
- rescue_connection_failure do
31
+ rescue_connection_failure do
32
32
  @coll.find.each {|r| results << r}
33
33
  [20, 30, 40].each do |a|
34
34
  assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
data/test/test_bson.rb CHANGED
@@ -23,6 +23,13 @@ class BSONTest < Test::Unit::TestCase
23
23
  assert_equal doc, BSON.deserialize(bson)
24
24
  end
25
25
 
26
+ def test_document_length
27
+ doc = {'name' => 'a' * 5 * 1024 * 1024}
28
+ assert_raise InvalidDocument do
29
+ assert BSON.serialize(doc)
30
+ end
31
+ end
32
+
26
33
  # In 1.8 we test that other string encodings raise an exception.
27
34
  # In 1.9 we test that they get auto-converted.
28
35
  if RUBY_VERSION < '1.9'
@@ -314,4 +321,29 @@ class BSONTest < Test::Unit::TestCase
314
321
  assert_equal BSON.serialize(one).to_a, BSON.serialize(dup).to_a
315
322
  end
316
323
 
324
+ def test_null_character
325
+ doc = {"a" => "\x00"}
326
+
327
+ assert_equal doc, BSON.deserialize(BSON.serialize(doc).to_a)
328
+
329
+ assert_raise InvalidDocument do
330
+ BSON.serialize({"\x00" => "a"})
331
+ end
332
+
333
+ assert_raise InvalidDocument do
334
+ BSON.serialize({"a" => (Regexp.compile "ab\x00c")})
335
+ end
336
+ end
337
+
338
+ def test_invalid_object
339
+ o = Object.new
340
+ assert_raise InvalidDocument do
341
+ BSON.serialize({:foo => o})
342
+ end
343
+
344
+ assert_raise InvalidDocument do
345
+ BSON.serialize({:foo => Date.today})
346
+ end
347
+ end
348
+
317
349
  end
@@ -53,18 +53,55 @@ class TestCollection < Test::Unit::TestCase
53
53
  assert_equal 5, @@db.collection("test.foo").find_one()["x"]
54
54
  end
55
55
 
56
+ def test_nil_id
57
+ assert_equal 5, @@test.insert({"_id" => 5, "foo" => "bar"}, {:safe => true})
58
+ assert_equal 5, @@test.save({"_id" => 5, "foo" => "baz"}, {:safe => true})
59
+ assert_equal nil, @@test.find_one("foo" => "bar")
60
+ assert_equal "baz", @@test.find_one(:_id => 5)["foo"]
61
+ assert_raise OperationFailure do
62
+ @@test.insert({"_id" => 5, "foo" => "bar"}, {:safe => true})
63
+ end
64
+
65
+ assert_equal nil, @@test.insert({"_id" => nil, "foo" => "bar"}, {:safe => true})
66
+ assert_equal nil, @@test.save({"_id" => nil, "foo" => "baz"}, {:safe => true})
67
+ assert_equal nil, @@test.find_one("foo" => "bar")
68
+ assert_equal "baz", @@test.find_one(:_id => nil)["foo"]
69
+ assert_raise OperationFailure do
70
+ @@test.insert({"_id" => nil, "foo" => "bar"}, {:safe => true})
71
+ end
72
+ assert_raise OperationFailure do
73
+ @@test.insert({:_id => nil, "foo" => "bar"}, {:safe => true})
74
+ end
75
+ end
76
+
56
77
  if @@version > "1.1"
57
- def test_distinct
58
- @@test.remove
59
- @@test.insert([{:a => 0, :b => {:c => "a"}},
60
- {:a => 1, :b => {:c => "b"}},
61
- {:a => 1, :b => {:c => "c"}},
62
- {:a => 2, :b => {:c => "a"}},
63
- {:a => 3},
64
- {:a => 3}])
78
+ context "distinct queries" do
79
+ setup do
80
+ @@test.remove
81
+ @@test.insert([{:a => 0, :b => {:c => "a"}},
82
+ {:a => 1, :b => {:c => "b"}},
83
+ {:a => 1, :b => {:c => "c"}},
84
+ {:a => 2, :b => {:c => "a"}},
85
+ {:a => 3},
86
+ {:a => 3}])
87
+ end
88
+
89
+ should "return distinct values" do
90
+ assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
91
+ assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
92
+ end
93
+
94
+ if @@version >= "1.2"
95
+
96
+ should "filter collection with query" do
97
+ assert_equal [2, 3], @@test.distinct(:a, {:a => {"$gt" => 1}}).sort
98
+ end
65
99
 
66
- assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
67
- assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
100
+ should "filter nested objects" do
101
+ assert_equal ["a", "b"], @@test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
102
+ end
103
+
104
+ end
68
105
  end
69
106
  end
70
107
 
@@ -259,26 +296,42 @@ class TestCollection < Test::Unit::TestCase
259
296
  assert c.closed?
260
297
  end
261
298
 
262
- def test_mapreduce
263
- @@test << { "user_id" => 1 }
264
- @@test << { "user_id" => 2 }
299
+ if @@version < "1.1.1"
300
+ def test_map_reduce
301
+ @@test << { "user_id" => 1 }
302
+ @@test << { "user_id" => 2 }
265
303
 
266
- m = "function() { emit(this.user_id, 1); }"
267
- r = "function(k,vals) { return 1; }"
268
- res = @@test.map_reduce(m, r);
269
- assert res.find_one({"_id" => 1})
270
- assert res.find_one({"_id" => 2})
271
- end
304
+ m = "function() { emit(this.user_id, 1); }"
305
+ r = "function(k,vals) { return 1; }"
306
+ res = @@test.map_reduce(m, r);
307
+ assert res.find_one({"_id" => 1})
308
+ assert res.find_one({"_id" => 2})
309
+ end
272
310
 
273
- def test_mapreduce_with_code_objects
274
- @@test << { "user_id" => 1 }
275
- @@test << { "user_id" => 2 }
311
+ def test_map_reduce_with_code_objects
312
+ @@test << { "user_id" => 1 }
313
+ @@test << { "user_id" => 2 }
276
314
 
277
- m = Code.new("function() { emit(this.user_id, 1); }")
278
- r = Code.new("function(k,vals) { return 1; }")
279
- res = @@test.map_reduce(m, r);
280
- assert res.find_one({"_id" => 1})
281
- assert res.find_one({"_id" => 2})
315
+ m = Code.new("function() { emit(this.user_id, 1); }")
316
+ r = Code.new("function(k,vals) { return 1; }")
317
+ res = @@test.map_reduce(m, r);
318
+ assert res.find_one({"_id" => 1})
319
+ assert res.find_one({"_id" => 2})
320
+ end
321
+
322
+ def test_map_reduce_with_options
323
+ @@test.remove
324
+ @@test << { "user_id" => 1 }
325
+ @@test << { "user_id" => 2 }
326
+ @@test << { "user_id" => 3 }
327
+
328
+ m = Code.new("function() { emit(this.user_id, 1); }")
329
+ r = Code.new("function(k,vals) { return 1; }")
330
+ res = @@test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}});
331
+ assert_equal 2, res.count
332
+ assert res.find_one({"_id" => 2})
333
+ assert res.find_one({"_id" => 3})
334
+ end
282
335
  end
283
336
 
284
337
  def test_saving_dates_pre_epoch
@@ -306,12 +359,12 @@ class TestCollection < Test::Unit::TestCase
306
359
  @@test.save(:foo => i)
307
360
  end
308
361
 
309
- assert_equal 5, @@test.find({}, :skip => 5).next_object()["foo"]
310
- assert_equal nil, @@test.find({}, :skip => 10).next_object()
362
+ assert_equal 5, @@test.find({}, :skip => 5).next_document()["foo"]
363
+ assert_equal nil, @@test.find({}, :skip => 10).next_document()
311
364
 
312
365
  assert_equal 5, @@test.find({}, :limit => 5).to_a.length
313
366
 
314
- assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_object()["foo"]
367
+ assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_document()["foo"]
315
368
  assert_equal 5, @@test.find({}, :skip => 3, :limit => 5).to_a.length
316
369
  end
317
370
 
@@ -348,82 +401,104 @@ class TestCollection < Test::Unit::TestCase
348
401
  assert_equal 1, x
349
402
  end
350
403
 
351
- def test_group_with_scope
352
- @@test.save("a" => 1)
353
- @@test.save("b" => 1)
404
+ context "Grouping" do
405
+ setup do
406
+ @@test.remove
407
+ @@test.save("a" => 1)
408
+ @@test.save("b" => 1)
409
+ @initial = {"count" => 0}
410
+ @reduce_function = "function (obj, prev) { prev.count += inc_value; }"
411
+ end
354
412
 
355
- reduce_function = "function (obj, prev) { prev.count += inc_value; }"
413
+ should "group results using eval form" do
414
+ assert_equal 1, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 0.5}))[0]["count"]
415
+ assert_equal 2, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}))[0]["count"]
416
+ assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
417
+ end
356
418
 
357
- assert_equal 2, @@test.group([], {}, {"count" => 0},
358
- Code.new(reduce_function,
359
- {"inc_value" => 1}))[0]["count"]
419
+ should "group results using command form" do
420
+ assert_equal 1, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 0.5}), true)[0]["count"]
421
+ assert_equal 2, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), true)[0]["count"]
422
+ assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}), true)[0]["count"]
423
+ end
360
424
 
361
- # TODO enable these tests when SERVER-262 is fixed
425
+ should "finalize grouped results" do
426
+ @finalize = "function(doc) {doc.f = doc.count + 200; }"
427
+ assert_equal 202, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), true, @finalize)[0]["f"]
428
+ end
429
+ end
362
430
 
363
- # assert_equal 2, @@test.group([], {}, {"count" => 0},
364
- # Code.new(reduce_function,
365
- # {"inc_value" => 1}), true)[0]["count"]
431
+ context "Grouping with a key function" do
432
+ setup do
433
+ @@test.remove
434
+ @@test.save("a" => 1)
435
+ @@test.save("a" => 2)
436
+ @@test.save("a" => 3)
437
+ @@test.save("a" => 4)
438
+ @@test.save("a" => 5)
439
+ @initial = {"count" => 0}
440
+ @keyf = "function (doc) { if(doc.a % 2 == 0) { return {even: true}; } else {return {odd: true}} };"
441
+ @reduce = "function (obj, prev) { prev.count += 1; }"
442
+ end
366
443
 
367
- assert_equal 4, @@test.group([], {}, {"count" => 0},
368
- Code.new(reduce_function,
369
- {"inc_value" => 2}))[0]["count"]
370
- # assert_equal 4, @@test.group([], {}, {"count" => 0},
371
- # Code.new(reduce_function,
372
- # {"inc_value" => 2}), true)[0]["count"]
444
+ should "group results" do
445
+ results = @@test.group(@keyf, {}, @initial, @reduce, true).sort {|a, b| a['count'] <=> b['count']}
446
+ assert results[0]['even'] && results[0]['count'] == 2.0
447
+ assert results[1]['odd'] && results[1]['count'] == 3.0
448
+ end
373
449
 
374
- assert_equal 1, @@test.group([], {}, {"count" => 0},
375
- Code.new(reduce_function,
376
- {"inc_value" => 0.5}))[0]["count"]
377
- # assert_equal 1, @@test.group([], {}, {"count" => 0},
378
- # Code.new(reduce_function,
379
- # {"inc_value" => 0.5}), true)[0]["count"]
450
+ should "raise an error if trying to use keyf as a group eval" do
451
+ assert_raise OperationFailure do
452
+ @@test.group(@keyf, {}, @initial, @reduce)
453
+ end
380
454
  end
455
+ end
381
456
 
382
- context "A collection with two records" do
383
- setup do
457
+ context "A collection with two records" do
458
+ setup do
384
459
  @collection = @@db.collection('test-collection')
385
460
  @collection.insert({:name => "Jones"})
386
461
  @collection.insert({:name => "Smith"})
387
462
  end
388
463
 
389
- should "have two records" do
464
+ should "have two records" do
390
465
  assert_equal 2, @collection.size
391
466
  end
392
467
 
393
- should "remove the two records" do
468
+ should "remove the two records" do
394
469
  @collection.remove()
395
470
  assert_equal 0, @collection.size
396
471
  end
397
472
 
398
- should "remove all records if an empty document is specified" do
473
+ should "remove all records if an empty document is specified" do
399
474
  @collection.remove({})
400
475
  assert_equal 0, @collection.find.count
401
476
  end
402
477
 
403
- should "remove only matching records" do
478
+ should "remove only matching records" do
404
479
  @collection.remove({:name => "Jones"})
405
480
  assert_equal 1, @collection.size
406
481
  end
407
482
  end
408
483
 
409
- context "Creating indexes " do
410
- setup do
484
+ context "Creating indexes " do
485
+ setup do
411
486
  @collection = @@db.collection('test-collection')
412
487
  end
413
488
 
414
- should "generate indexes in the proper order" do
489
+ should "generate indexes in the proper order" do
415
490
  @collection.expects(:insert_documents) do |sel, coll, safe|
416
491
  assert_equal 'b_1_a_1', sel[:name]
417
492
  end
418
493
  @collection.create_index([['b', 1], ['a', 1]])
419
494
  end
420
495
 
421
- context "with an index created" do
422
- setup do
496
+ context "with an index created" do
497
+ setup do
423
498
  @collection.create_index([['b', 1], ['a', 1]])
424
499
  end
425
500
 
426
- should "return properly ordered index information" do
501
+ should "return properly ordered index information" do
427
502
  assert_equal [['b', 1], ['a', 1]], @collection.index_information["b_1_a_1"]
428
503
  end
429
504
  end