mongo 1.10.2 → 1.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +43 -9
  5. data/VERSION +1 -1
  6. data/lib/mongo.rb +1 -0
  7. data/lib/mongo/collection.rb +36 -21
  8. data/lib/mongo/connection/pool.rb +14 -22
  9. data/lib/mongo/cursor.rb +13 -0
  10. data/lib/mongo/db.rb +18 -13
  11. data/lib/mongo/functional.rb +0 -2
  12. data/lib/mongo/functional/authentication.rb +35 -25
  13. data/lib/mongo/legacy.rb +4 -4
  14. data/mongo.gemspec +0 -5
  15. data/test/functional/authentication_test.rb +3 -2
  16. data/test/functional/bulk_write_collection_view_test.rb +9 -14
  17. data/test/functional/client_test.rb +42 -43
  18. data/test/functional/collection_test.rb +1073 -995
  19. data/test/functional/collection_writer_test.rb +1 -1
  20. data/test/functional/cursor_fail_test.rb +3 -9
  21. data/test/functional/cursor_message_test.rb +14 -15
  22. data/test/functional/cursor_test.rb +224 -166
  23. data/test/functional/db_api_test.rb +262 -261
  24. data/test/functional/db_connection_test.rb +1 -3
  25. data/test/functional/db_test.rb +116 -115
  26. data/test/functional/grid_file_system_test.rb +108 -108
  27. data/test/functional/pool_test.rb +73 -0
  28. data/test/functional/timeout_test.rb +2 -0
  29. data/test/helpers/test_unit.rb +146 -11
  30. data/test/replica_set/authentication_test.rb +4 -2
  31. data/test/replica_set/basic_test.rb +5 -13
  32. data/test/replica_set/client_test.rb +8 -6
  33. data/test/replica_set/complex_connect_test.rb +3 -0
  34. data/test/replica_set/count_test.rb +2 -0
  35. data/test/replica_set/cursor_test.rb +5 -0
  36. data/test/replica_set/insert_test.rb +1 -1
  37. data/test/replica_set/max_values_test.rb +1 -1
  38. data/test/replica_set/pinning_test.rb +1 -1
  39. data/test/replica_set/query_test.rb +1 -1
  40. data/test/replica_set/read_preference_test.rb +7 -1
  41. data/test/replica_set/refresh_test.rb +11 -8
  42. data/test/replica_set/replication_ack_test.rb +2 -1
  43. data/test/sharded_cluster/basic_test.rb +17 -11
  44. data/test/shared/authentication/basic_auth_shared.rb +59 -98
  45. data/test/shared/authentication/bulk_api_auth_shared.rb +11 -21
  46. data/test/shared/authentication/gssapi_shared.rb +28 -21
  47. data/test/test_helper.rb +5 -0
  48. data/test/tools/mongo_config.rb +96 -11
  49. metadata +4 -5
  50. metadata.gz.sig +0 -0
  51. data/lib/mongo/functional/sasl_java.rb +0 -48
@@ -87,14 +87,14 @@ module Mongo
87
87
  class MongoClient
88
88
  # @deprecated This method is no longer in use and never needs to be called
89
89
  # directly. Support will be removed after v2.0
90
+ # Authentication of sockets is handled upon checkout and checkin.
90
91
  def authenticate_pools
91
- @primary_pool.authenticate_existing
92
92
  end
93
93
 
94
94
  # @deprecated This method is no longer in use and never needs to be called
95
95
  # directly. Support will be removed after v2.0
96
+ # Authentication of sockets is handled upon checkout and checkin.
96
97
  def logout_pools(database)
97
- @primary_pool.logout_existing(database)
98
98
  end
99
99
 
100
100
  # @deprecated This method is no longer in use and never needs to be called
@@ -107,14 +107,14 @@ module Mongo
107
107
  class MongoReplicaSetClient
108
108
  # @deprecated This method is no longer in use and never needs to be called
109
109
  # directly. Support will be removed after v2.0
110
+ # Authentication of sockets is handled upon checkout and checkin.
110
111
  def authenticate_pools
111
- @manager.pools.each { |pool| pool.authenticate_existing }
112
112
  end
113
113
 
114
114
  # @deprecated This method is no longer in use and never needs to be called
115
115
  # directly. Support will be removed after v2.0
116
+ # Authentication of sockets is handled upon checkout and checkin.
116
117
  def logout_pools(database)
117
- @manager.pools.each { |pool| pool.logout_existing(database) }
118
118
  end
119
119
  end
120
120
 
@@ -22,11 +22,6 @@ Gem::Specification.new do |s|
22
22
  s.files += ['README.md', 'Rakefile', 'bin/mongo_console']
23
23
  s.files += ['lib/mongo.rb'] + Dir['lib/mongo/**/*.rb']
24
24
 
25
- if RUBY_PLATFORM =~ /java/
26
- s.platform = 'java'
27
- s.files << 'ext/jsasl/target/jsasl.jar'
28
- end
29
-
30
25
  s.test_files = Dir['test/**/*.rb'] - Dir['test/bson/*']
31
26
  s.executables = ['mongo_console']
32
27
  s.require_paths = ['lib']
@@ -27,9 +27,10 @@ class AuthenticationTest < Test::Unit::TestCase
27
27
  include GSSAPITests
28
28
 
29
29
  def setup
30
- @client = MongoClient.new(TEST_HOST, TEST_PORT)
30
+ @client = standard_connection
31
+ @admin = @client['admin']
31
32
  @version = @client.server_version
32
- @db = @client[TEST_DB]
33
+ @db = @client['ruby-test']
33
34
  @host_info = host_port
34
35
  end
35
36
  end
@@ -52,12 +52,6 @@ module BSON
52
52
  end
53
53
 
54
54
  class BulkWriteCollectionViewTest < Test::Unit::TestCase
55
- @@client ||= standard_connection(:op_timeout => 10)
56
- @@db = @@client.db(TEST_DB)
57
- @@test = @@db.collection("test")
58
- @@version = @@client.server_version
59
-
60
- DATABASE_NAME = 'ruby_test_bulk_write_collection_view'
61
55
  COLLECTION_NAME = 'test'
62
56
  DUPLICATE_KEY_ERROR_CODE_SET = [11000, 11001, 12582, 16460].to_set
63
57
 
@@ -78,8 +72,9 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
78
72
  end
79
73
 
80
74
  def default_setup
81
- @client = MongoClient.new
82
- @db = @client[DATABASE_NAME]
75
+ @client = standard_connection
76
+ @version = @client.server_version
77
+ @db = @client[TEST_DB]
83
78
  @collection = @db[COLLECTION_NAME]
84
79
  @collection.drop
85
80
  @bulk = @collection.initialize_ordered_bulk_op
@@ -339,7 +334,7 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
339
334
  end
340
335
  end
341
336
 
342
- # ----- REPLACE -----
337
+ # ----- REPLACE -----
343
338
 
344
339
  should "raise an error when we attempt to use replace" do
345
340
  assert_raise NoMethodError do
@@ -858,10 +853,10 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
858
853
  should "handle error for serialization with offset" do
859
854
  with_write_commands_and_operations(@db.connection) do |wire_version|
860
855
  @collection.remove
861
- assert_equal 16777216, @@client.max_bson_size
856
+ assert_equal 16777216, @client.max_bson_size
862
857
  @bulk.find({:a => 1}).update_one({"$inc" => {:x => 1}})
863
858
  @bulk.insert({:_id => 1, :a => 1})
864
- @bulk.insert(generate_sized_doc(@@client.max_message_size + 1))
859
+ @bulk.insert(generate_sized_doc(@client.max_message_size + 1))
865
860
  @bulk.insert({:_id => 3, :a => 3})
866
861
  ex = assert_raise BulkWriteError do
867
862
  @bulk.execute
@@ -999,7 +994,7 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
999
994
  @bulk.execute(write_concern)
1000
995
  end
1001
996
  result = ex.result
1002
- if @@version >= "2.5.5"
997
+ if @version >= "2.5.5"
1003
998
  assert_match_document(
1004
999
  {
1005
1000
  "ok" => 0,
@@ -1098,7 +1093,7 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
1098
1093
  @bulk = @collection.initialize_unordered_bulk_op
1099
1094
  @bulk.insert({:_id => 1, :a => 1})
1100
1095
  @bulk.insert({:_id => 1, :a => 2})
1101
- @bulk.insert(generate_sized_doc(@@client.max_message_size + 1))
1096
+ @bulk.insert(generate_sized_doc(@client.max_message_size + 1))
1102
1097
  @bulk.insert({:_id => 3, :a => 3})
1103
1098
  @bulk.find({:a => 4}).upsert.replace_one({:x => 3})
1104
1099
  ex = assert_raise BulkWriteError do
@@ -1127,7 +1122,7 @@ class BulkWriteCollectionViewTest < Test::Unit::TestCase
1127
1122
  @bulk.execute(write_concern)
1128
1123
  end
1129
1124
  result = ex.result
1130
- if @@version >= "2.5.5"
1125
+ if @version >= "2.5.5"
1131
1126
  assert_match_document(
1132
1127
  {
1133
1128
  "ok" => 0,
@@ -145,7 +145,7 @@ class ClientTest < Test::Unit::TestCase
145
145
  end
146
146
 
147
147
  def test_from_uri_write_concern
148
- con = MongoClient.from_uri("mongodb://#{host_port}")
148
+ con = MongoClient.from_uri(TEST_URI)
149
149
  db = con.db
150
150
  coll = db.collection('from-uri-test')
151
151
  assert_equal BSON::ObjectId, coll.insert({'a' => 1}).class
@@ -182,33 +182,36 @@ class ClientTest < Test::Unit::TestCase
182
182
  end
183
183
 
184
184
  def test_database_info
185
- @client.drop_database(TEST_DB)
186
- @client.db(TEST_DB).collection('info-test').insert('a' => 1)
185
+ db_name = 'ruby_test'
186
+ @client.drop_database(db_name)
187
+ @client.db(db_name).collection('info-test').insert('a' => 1)
187
188
 
188
189
  info = @client.database_info
189
190
  assert_not_nil info
190
191
  assert_kind_of Hash, info
191
- assert_not_nil info[TEST_DB]
192
- assert info[TEST_DB] > 0
192
+ assert_not_nil info[db_name]
193
+ assert info[db_name] > 0
193
194
 
194
- @client.drop_database(TEST_DB)
195
+ @client.drop_database(db_name)
195
196
  end
196
197
 
197
198
  def test_copy_database
198
- old_name = TEST_DB + '_old'
199
- new_name = TEST_DB + '_new'
200
-
201
- @client.drop_database(new_name)
202
- @client.db(old_name).collection('copy-test').insert('a' => 1)
203
- @client.copy_database(old_name, new_name, host_port)
199
+ return unless @client.server_version >= '2.5' ||
200
+ @client.server_version < '2.4'
201
+ old_db = @client['ruby-test-old']
202
+ new_db = @client['ruby-test-new']
203
+ coll = 'copy-test'
204
204
 
205
- old_object = @client.db(old_name).collection('copy-test').find.next_document
206
- new_object = @client.db(new_name).collection('copy-test').find.next_document
207
- assert_equal old_object, new_object
205
+ old_db[coll].insert('a' => 1)
206
+ @client.drop_database(new_db.name)
207
+ silently { old_db.add_user('chevy', 'chase') }
208
+ @client.copy_database(old_db.name, new_db.name, host_port, 'chevy', 'chase')
209
+ old_db.remove_user('chevy')
210
+ assert_equal old_db[coll].find_one, new_db[coll].find_one
208
211
  end
209
212
 
210
213
  def test_database_names
211
- @client.drop_database(TEST_DB)
214
+ @client.db(TEST_DB).collection('info-test').remove({})
212
215
  @client.db(TEST_DB).collection('info-test').insert('a' => 1)
213
216
 
214
217
  names = @client.database_names
@@ -429,44 +432,40 @@ class ClientTest < Test::Unit::TestCase
429
432
 
430
433
  context "Saved authentications" do
431
434
  setup do
432
- @client = standard_connection
435
+ @client = Mongo::MongoClient.new
433
436
 
434
437
  @auth = {
435
- :db_name => TEST_DB,
436
- :username => 'bob',
437
- :password => 'secret',
438
- :source => TEST_DB,
439
- :mechanism => 'MONGODB-CR'
438
+ :db_name => TEST_DB,
439
+ :username => TEST_USER,
440
+ :password => TEST_USER_PWD,
441
+ :source => TEST_DB,
442
+ :mechanism => 'MONGODB-CR'
440
443
  }
441
444
 
442
445
  @client.auths << @auth
443
446
  end
444
447
 
445
- teardown do
446
- @client.clear_auths
447
- end
448
-
449
448
  should "save and validate the authentication" do
450
449
  assert_equal Authentication.validate_credentials(@auth), @client.auths.first
451
450
  end
452
451
 
453
452
  should "not allow multiple authentications for the same db" do
454
- auth = {
455
- :db_name => TEST_DB,
456
- :username => 'mickey',
457
- :password => 'm0u53',
458
- :source => nil,
459
- :mechanism => nil
460
- }
461
-
462
- assert_raise Mongo::MongoArgumentError do
463
- @client.add_auth(
464
- auth[:db_name],
465
- auth[:username],
466
- auth[:password],
467
- auth[:source],
468
- auth[:mechanism])
469
- end
453
+ auth = {
454
+ :db_name => TEST_DB,
455
+ :username => TEST_USER,
456
+ :password => TEST_USER_PWD,
457
+ :source => TEST_DB,
458
+ :mechanism => nil
459
+ }
460
+
461
+ assert_raise Mongo::MongoArgumentError do
462
+ @client.add_auth(
463
+ auth[:db_name],
464
+ auth[:username],
465
+ auth[:password],
466
+ auth[:source],
467
+ auth[:mechanism])
468
+ end
470
469
  end
471
470
 
472
471
  should "remove auths by database" do
@@ -523,7 +522,7 @@ class ClientTest < Test::Unit::TestCase
523
522
 
524
523
  context "Connection exceptions" do
525
524
  setup do
526
- @con = standard_connection(:pool_size => 10, :pool_timeout => 10)
525
+ @con = MongoClient.new(TEST_HOST, TEST_PORT, :pool_size => 10, :pool_timeout => 10)
527
526
  @coll = @con[TEST_DB]['test-connection-exceptions']
528
527
  end
529
528
 
@@ -16,10 +16,6 @@ require 'rbconfig'
16
16
  require 'test_helper'
17
17
 
18
18
  class CollectionTest < Test::Unit::TestCase
19
- @@client ||= standard_connection(:op_timeout => 10)
20
- @@db = @@client.db(TEST_DB)
21
- @@test = @@db.collection("test")
22
- @@version = @@client.server_version
23
19
 
24
20
  LIMITED_MAX_BSON_SIZE = 1024
25
21
  LIMITED_MAX_MESSAGE_SIZE = 3 * LIMITED_MAX_BSON_SIZE
@@ -28,7 +24,11 @@ class CollectionTest < Test::Unit::TestCase
28
24
  LIMITED_INVALID_VALUE_SIZE = LIMITED_MAX_BSON_SIZE + Mongo::MongoClient::COMMAND_HEADROOM + 1
29
25
 
30
26
  def setup
31
- @@test.remove
27
+ @client ||= standard_connection(:op_timeout => 10)
28
+ @db = @client.db(TEST_DB)
29
+ @test = @db.collection("test")
30
+ @version = @client.server_version
31
+ @test.remove
32
32
  end
33
33
 
34
34
  @@wv0 = Mongo::MongoClient::RELEASE_2_4_AND_BEFORE
@@ -36,26 +36,34 @@ class CollectionTest < Test::Unit::TestCase
36
36
  @@a_h = Mongo::MongoClient::APPEND_HEADROOM
37
37
  @@s_h = Mongo::MongoClient::SERIALIZE_HEADROOM
38
38
 
39
- MAX_SIZE_EXCEPTION_TEST = [
40
- #[@@wv0, @@client.max_bson_size, nil, /xyzzy/], # succeeds standalone, fails whole suite
41
- ]
42
- MAX_SIZE_EXCEPTION_CRUBY_TEST = [
43
- [@@wv0, @@client.max_bson_size + 1, BSON::InvalidDocument, /Document.* too large/]
44
- ]
45
- MAX_SIZE_EXCEPTION_JRUBY_TEST = [
46
- [@@wv0, @@client.max_bson_size + 1, Mongo::OperationFailure, /object to insert too large/]
47
- ]
48
- MAX_SIZE_EXCEPTION_COMMANDS_TEST = [
49
- #[@@wv2, @@client.max_bson_size, nil, /xyzzy/], # succeeds standalone, fails whole suite
50
- [@@wv2, @@client.max_bson_size + 1, Mongo::OperationFailure, /object to insert too large/],
51
- [@@wv2, @@client.max_bson_size + @@s_h, Mongo::OperationFailure, /object to insert too large/],
52
- [@@wv2, @@client.max_bson_size + @@a_h, BSON::InvalidDocument, /Document.* too large/]
53
- ]
54
-
55
- @@max_size_exception_test = MAX_SIZE_EXCEPTION_TEST
56
- @@max_size_exception_test += MAX_SIZE_EXCEPTION_CRUBY_TEST unless RUBY_PLATFORM == 'java'
57
- #@@max_size_exception_test += MAX_SIZE_EXCEPTION_JRUBY_TEST if RUBY_PLATFORM == 'java'
58
- @@max_size_exception_test += MAX_SIZE_EXCEPTION_COMMANDS_TEST if @@version >= "2.5.2"
39
+ def max_size_exception_test(client)
40
+ base = [
41
+ #[@@wv0, client.max_bson_size, nil, /xyzzy/], # succeeds standalone, fails whole suite
42
+ ]
43
+ base += max_size_exception_cruby_test(client) unless RUBY_PLATFORM == 'java'
44
+ #base += max_size_exception_jruby_test if RUBY_PLATFORM == 'java'
45
+ base += max_size_exception_commands_test(client) if @version >= '2.5.2'
46
+ base
47
+ end
48
+
49
+ def max_size_exception_cruby_test(client)
50
+ [
51
+ [@@wv0, client.max_bson_size + 1, BSON::InvalidDocument, /Document.* too large/]
52
+ ]
53
+ end
54
+
55
+ def max_size_exception_jruby_test(client)
56
+ [@@wv0, client.max_bson_size + 1, Mongo::OperationFailure, /object to insert too large/]
57
+ end
58
+
59
+ def max_size_exception_commands_test(client)
60
+ [
61
+ #[@@wv2, client.max_bson_size, nil, /xyzzy/], # succeeds standalone, fails whole suite
62
+ [@@wv2, client.max_bson_size + 1, Mongo::OperationFailure, /object to insert too large/],
63
+ [@@wv2, client.max_bson_size + @@s_h, Mongo::OperationFailure, /object to insert too large/],
64
+ [@@wv2, client.max_bson_size + @@a_h, BSON::InvalidDocument, /Document.* too large/]
65
+ ]
66
+ end
59
67
 
60
68
  def generate_sized_doc(size)
61
69
  doc = {"_id" => BSON::ObjectId.new, "x" => "y"}
@@ -81,334 +89,349 @@ class CollectionTest < Test::Unit::TestCase
81
89
  end
82
90
 
83
91
  def test_insert_batch_max_sizes
84
- @@max_size_exception_test.each do |wire_version, size, exc, regexp|
85
- with_max_wire_version(@@client, wire_version) do
86
- @@test.remove
92
+ max_size_exception_test(@client).each do |wire_version, size, exc, regexp|
93
+ with_max_wire_version(@client, wire_version) do
94
+ @test.remove
87
95
  doc = generate_sized_doc(size)
88
96
  begin
89
- @@test.insert([doc.dup])
97
+ @test.insert([doc.dup])
90
98
  assert_equal nil, exc
91
99
  rescue => e
92
- assert_equal exc, e.class, "wire_version:#{wire_version}, size:#{size}, exc:#{exc} e:#{e.message.inspect} @@version:#{@@version}"
100
+ assert_equal exc, e.class, "wire_version:#{wire_version}, size:#{size}, exc:#{exc} e:#{e.message.inspect} @version:#{@version}"
93
101
  assert_match regexp, e.message
94
102
  end
95
103
  end
96
104
  end
97
105
  end
98
106
 
99
- if @@version >= '2.5.4'
100
-
101
- def test_single_delete_write_command
102
- @@test.drop
103
- @@test.insert([{ :a => 1 }, { :a => 1 }])
107
+ def test_single_delete_write_command
108
+ return unless @version >= '2.5.4'
109
+ @test.drop
110
+ @test.insert([{ :a => 1 }, { :a => 1 }])
104
111
 
105
- command = BSON::OrderedHash['delete', @@test.name,
106
- :deletes, [{ :q => { :a => 1 }, :limit => 1 }],
107
- :writeConcern, { :w => 1 },
108
- :ordered, false]
112
+ command = BSON::OrderedHash['delete', @test.name,
113
+ :deletes, [{ :q => { :a => 1 }, :limit => 1 }],
114
+ :writeConcern, { :w => 1 },
115
+ :ordered, false]
109
116
 
110
- result = @@db.command(command)
111
- assert_equal 1, result['n']
112
- assert_equal 1, result['ok']
113
- assert_equal 1, @@test.count
114
- end
117
+ result = @db.command(command)
118
+ assert_equal 1, result['n']
119
+ assert_equal 1, result['ok']
120
+ assert_equal 1, @test.count
121
+ end
115
122
 
116
- def test_multi_ordered_delete_write_command
117
- @@test.drop
118
- @@test.insert([{ :a => 1 }, { :a => 1 }])
123
+ def test_multi_ordered_delete_write_command
124
+ return unless @version >= '2.5.4'
125
+ @test.drop
126
+ @test.insert([{ :a => 1 }, { :a => 1 }])
119
127
 
120
- command = BSON::OrderedHash['delete', @@test.name,
121
- :deletes, [{ :q => { :a => 1 }, :limit => 0 }],
122
- :writeConcern, { :w => 1 },
123
- :ordered, true]
128
+ command = BSON::OrderedHash['delete', @test.name,
129
+ :deletes, [{ :q => { :a => 1 }, :limit => 0 }],
130
+ :writeConcern, { :w => 1 },
131
+ :ordered, true]
124
132
 
125
- result = @@db.command(command)
126
- assert_equal 2, result['n']
127
- assert_equal 1, result['ok']
128
- assert_equal 0, @@test.count
129
- end
133
+ result = @db.command(command)
134
+ assert_equal 2, result['n']
135
+ assert_equal 1, result['ok']
136
+ assert_equal 0, @test.count
137
+ end
130
138
 
131
- def test_multi_unordered_delete_write_command
132
- @@test.drop
133
- @@test.insert([{ :a => 1 }, { :a => 1 }])
139
+ def test_multi_unordered_delete_write_command
140
+ return unless @version >= '2.5.4'
141
+ @test.drop
142
+ @test.insert([{ :a => 1 }, { :a => 1 }])
134
143
 
135
- command = BSON::OrderedHash['delete', @@test.name,
136
- :deletes, [{ :q => { :a => 1 }, :limit => 0 }],
137
- :writeConcern, { :w => 1 },
138
- :ordered, false]
144
+ command = BSON::OrderedHash['delete', @test.name,
145
+ :deletes, [{ :q => { :a => 1 }, :limit => 0 }],
146
+ :writeConcern, { :w => 1 },
147
+ :ordered, false]
139
148
 
140
- result = @@db.command(command)
141
- assert_equal 2, result['n']
142
- assert_equal 1, result['ok']
143
- assert_equal 0, @@test.count
144
- end
149
+ result = @db.command(command)
150
+ assert_equal 2, result['n']
151
+ assert_equal 1, result['ok']
152
+ assert_equal 0, @test.count
153
+ end
145
154
 
146
- def test_delete_write_command_with_no_concern
147
- @@test.drop
148
- @@test.insert([{ :a => 1 }, { :a => 1 }])
155
+ def test_delete_write_command_with_no_concern
156
+ return unless @version >= '2.5.4'
157
+ @test.drop
158
+ @test.insert([{ :a => 1 }, { :a => 1 }])
149
159
 
150
- command = BSON::OrderedHash['delete', @@test.name,
151
- :deletes, [{ :q => { :a => 1 }, :limit => 0 }],
152
- :ordered, false]
160
+ command = BSON::OrderedHash['delete', @test.name,
161
+ :deletes, [{ :q => { :a => 1 }, :limit => 0 }],
162
+ :ordered, false]
153
163
 
154
- result = @@db.command(command)
155
- assert_equal 2, result['n']
156
- assert_equal 1, result['ok']
157
- assert_equal 0, @@test.count
158
- end
164
+ result = @db.command(command)
165
+ assert_equal 2, result['n']
166
+ assert_equal 1, result['ok']
167
+ assert_equal 0, @test.count
168
+ end
159
169
 
160
- def test_delete_write_command_with_error
161
- @@test.drop
162
- @@test.insert([{ :a => 1 }, { :a => 1 }])
170
+ def test_delete_write_command_with_error
171
+ return unless @version >= '2.5.4'
172
+ @test.drop
173
+ @test.insert([{ :a => 1 }, { :a => 1 }])
163
174
 
164
- command = BSON::OrderedHash['delete', @@test.name,
165
- :deletes, [{ :q => { '$set' => { :a => 1 }}, :limit => 0 }],
166
- :writeConcern, { :w => 1 },
167
- :ordered, false]
175
+ command = BSON::OrderedHash['delete', @test.name,
176
+ :deletes, [{ :q => { '$set' => { :a => 1 }}, :limit => 0 }],
177
+ :writeConcern, { :w => 1 },
178
+ :ordered, false]
168
179
 
169
- assert_raise Mongo::OperationFailure do
170
- @@db.command(command)
171
- end
180
+ assert_raise Mongo::OperationFailure do
181
+ @db.command(command)
172
182
  end
183
+ end
173
184
 
174
- def test_single_insert_write_command
175
- @@test.drop
185
+ def test_single_insert_write_command
186
+ return unless @version >= '2.5.4'
187
+ @test.drop
176
188
 
177
- command = BSON::OrderedHash['insert', @@test.name,
178
- :documents, [{ :a => 1 }],
179
- :writeConcern, { :w => 1 },
180
- :ordered, false]
189
+ command = BSON::OrderedHash['insert', @test.name,
190
+ :documents, [{ :a => 1 }],
191
+ :writeConcern, { :w => 1 },
192
+ :ordered, false]
181
193
 
182
- result = @@db.command(command)
183
- assert_equal 1, result['ok']
184
- assert_equal 1, @@test.count
185
- end
194
+ result = @db.command(command)
195
+ assert_equal 1, result['ok']
196
+ assert_equal 1, @test.count
197
+ end
186
198
 
187
- def test_multi_ordered_insert_write_command
188
- @@test.drop
199
+ def test_multi_ordered_insert_write_command
200
+ return unless @version >= '2.5.4'
201
+ @test.drop
189
202
 
190
- command = BSON::OrderedHash['insert', @@test.name,
191
- :documents, [{ :a => 1 }, { :a => 2 }],
192
- :writeConcern, { :w => 1 },
193
- :ordered, true]
203
+ command = BSON::OrderedHash['insert', @test.name,
204
+ :documents, [{ :a => 1 }, { :a => 2 }],
205
+ :writeConcern, { :w => 1 },
206
+ :ordered, true]
194
207
 
195
- result = @@db.command(command)
196
- assert_equal 1, result['ok']
197
- assert_equal 2, @@test.count
198
- end
208
+ result = @db.command(command)
209
+ assert_equal 1, result['ok']
210
+ assert_equal 2, @test.count
211
+ end
199
212
 
200
- def test_multi_unordered_insert_write_command
201
- @@test.drop
213
+ def test_multi_unordered_insert_write_command
214
+ return unless @version >= '2.5.4'
215
+ @test.drop
202
216
 
203
- command = BSON::OrderedHash['insert', @@test.name,
204
- :documents, [{ :a => 1 }, { :a => 2 }],
205
- :writeConcern, { :w => 1 },
206
- :ordered, false]
217
+ command = BSON::OrderedHash['insert', @test.name,
218
+ :documents, [{ :a => 1 }, { :a => 2 }],
219
+ :writeConcern, { :w => 1 },
220
+ :ordered, false]
207
221
 
208
- result = @@db.command(command)
209
- assert_equal 1, result['ok']
210
- assert_equal 2, @@test.count
211
- end
222
+ result = @db.command(command)
223
+ assert_equal 1, result['ok']
224
+ assert_equal 2, @test.count
225
+ end
212
226
 
213
- def test_insert_write_command_with_no_concern
214
- @@test.drop
227
+ def test_insert_write_command_with_no_concern
228
+ return unless @version >= '2.5.4'
229
+ @test.drop
215
230
 
216
- command = BSON::OrderedHash['insert', @@test.name,
217
- :documents, [{ :a => 1 }, { :a => 2 }],
218
- :ordered, false]
231
+ command = BSON::OrderedHash['insert', @test.name,
232
+ :documents, [{ :a => 1 }, { :a => 2 }],
233
+ :ordered, false]
219
234
 
220
- result = @@db.command(command)
221
- assert_equal 1, result['ok']
222
- assert_equal 2, @@test.count
223
- end
235
+ result = @db.command(command)
236
+ assert_equal 1, result['ok']
237
+ assert_equal 2, @test.count
238
+ end
224
239
 
225
- def test_insert_write_command_with_error
226
- @@test.drop
227
- @@test.ensure_index([[:a, 1]], { :unique => true })
240
+ def test_insert_write_command_with_error
241
+ return unless @version >= '2.5.4'
242
+ @test.drop
243
+ @test.ensure_index([[:a, 1]], { :unique => true })
228
244
 
229
- command = BSON::OrderedHash['insert', @@test.name,
230
- :documents, [{ :a => 1 }, { :a => 1 }],
231
- :writeConcern, { :w => 1 },
232
- :ordered, false]
245
+ command = BSON::OrderedHash['insert', @test.name,
246
+ :documents, [{ :a => 1 }, { :a => 1 }],
247
+ :writeConcern, { :w => 1 },
248
+ :ordered, false]
233
249
 
234
- assert_raise Mongo::OperationFailure do
235
- @@db.command(command)
236
- end
250
+ assert_raise Mongo::OperationFailure do
251
+ @db.command(command)
237
252
  end
253
+ end
238
254
 
239
- def test_single_update_write_command
240
- @@test.drop
241
- @@test.insert([{ :a => 1 }, { :a => 2 }])
255
+ def test_single_update_write_command
256
+ return unless @version >= '2.5.4'
257
+ @test.drop
258
+ @test.insert([{ :a => 1 }, { :a => 2 }])
242
259
 
243
- command = BSON::OrderedHash['update', @@test.name,
244
- :updates, [{ :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}}],
245
- :writeConcern, { :w => 1 }]
260
+ command = BSON::OrderedHash['update', @test.name,
261
+ :updates, [{ :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}}],
262
+ :writeConcern, { :w => 1 }]
246
263
 
247
- result = @@db.command(command)
248
- assert_equal 1, result['ok']
249
- assert_equal 1, result['n']
250
- assert_equal 2, @@test.find({ :a => 2 }).count
251
- end
264
+ result = @db.command(command)
265
+ assert_equal 1, result['ok']
266
+ assert_equal 1, result['n']
267
+ assert_equal 2, @test.find({ :a => 2 }).count
268
+ end
252
269
 
253
- def test_multi_ordered_update_write_command
254
- @@test.drop
255
- @@test.insert([{ :a => 1 }, { :a => 3 }])
270
+ def test_multi_ordered_update_write_command
271
+ return unless @version >= '2.5.4'
272
+ @test.drop
273
+ @test.insert([{ :a => 1 }, { :a => 3 }])
256
274
 
257
- command = BSON::OrderedHash['update', @@test.name,
258
- :updates, [
259
- { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
260
- { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
261
- ],
262
- :writeConcern, { :w => 1 },
263
- :ordered, true]
275
+ command = BSON::OrderedHash['update', @test.name,
276
+ :updates, [
277
+ { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
278
+ { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
279
+ ],
280
+ :writeConcern, { :w => 1 },
281
+ :ordered, true]
264
282
 
265
- result = @@db.command(command)
266
- assert_equal 1, result['ok']
267
- assert_equal 2, result['n']
268
- assert_equal 1, @@test.find({ :a => 2 }).count
269
- assert_equal 1, @@test.find({ :a => 4 }).count
270
- end
283
+ result = @db.command(command)
284
+ assert_equal 1, result['ok']
285
+ assert_equal 2, result['n']
286
+ assert_equal 1, @test.find({ :a => 2 }).count
287
+ assert_equal 1, @test.find({ :a => 4 }).count
288
+ end
271
289
 
272
- def test_multi_unordered_update_write_command
273
- @@test.drop
274
- @@test.insert([{ :a => 1 }, { :a => 3 }])
290
+ def test_multi_unordered_update_write_command
291
+ return unless @version >= '2.5.4'
292
+ @test.drop
293
+ @test.insert([{ :a => 1 }, { :a => 3 }])
275
294
 
276
- command = BSON::OrderedHash['update', @@test.name,
277
- :updates, [
278
- { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
279
- { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
280
- ],
281
- :writeConcern, { :w => 1 },
282
- :ordered, false]
295
+ command = BSON::OrderedHash['update', @test.name,
296
+ :updates, [
297
+ { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
298
+ { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
299
+ ],
300
+ :writeConcern, { :w => 1 },
301
+ :ordered, false]
283
302
 
284
- result = @@db.command(command)
285
- assert_equal 1, result['ok']
286
- assert_equal 2, result['n']
287
- assert_equal 1, @@test.find({ :a => 2 }).count
288
- assert_equal 1, @@test.find({ :a => 4 }).count
289
- end
303
+ result = @db.command(command)
304
+ assert_equal 1, result['ok']
305
+ assert_equal 2, result['n']
306
+ assert_equal 1, @test.find({ :a => 2 }).count
307
+ assert_equal 1, @test.find({ :a => 4 }).count
308
+ end
290
309
 
291
- def test_update_write_command_with_no_concern
292
- @@test.drop
293
- @@test.insert([{ :a => 1 }, { :a => 3 }])
310
+ def test_update_write_command_with_no_concern
311
+ return unless @version >= '2.5.4'
312
+ @test.drop
313
+ @test.insert([{ :a => 1 }, { :a => 3 }])
294
314
 
295
- command = BSON::OrderedHash['update', @@test.name,
296
- :updates, [
297
- { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
298
- { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
299
- ],
300
- :ordered, false]
315
+ command = BSON::OrderedHash['update', @test.name,
316
+ :updates, [
317
+ { :q => { :a => 1 }, :u => { '$set' => { :a => 2 }}},
318
+ { :q => { :a => 3 }, :u => { '$set' => { :a => 4 }}}
319
+ ],
320
+ :ordered, false]
301
321
 
302
- result = @@db.command(command)
303
- assert_equal 1, result['ok']
304
- assert_equal 2, result['n']
305
- assert_equal 1, @@test.find({ :a => 2 }).count
306
- assert_equal 1, @@test.find({ :a => 4 }).count
307
- end
322
+ result = @db.command(command)
323
+ assert_equal 1, result['ok']
324
+ assert_equal 2, result['n']
325
+ assert_equal 1, @test.find({ :a => 2 }).count
326
+ assert_equal 1, @test.find({ :a => 4 }).count
327
+ end
308
328
 
309
- def test_update_write_command_with_error
310
- @@test.drop
311
- @@test.ensure_index([[:a, 1]], { :unique => true })
312
- @@test.insert([{ :a => 1 }, { :a => 2 }])
329
+ def test_update_write_command_with_error
330
+ return unless @version >= '2.5.4'
331
+ @test.drop
332
+ @test.ensure_index([[:a, 1]], { :unique => true })
333
+ @test.insert([{ :a => 1 }, { :a => 2 }])
313
334
 
314
- command = BSON::OrderedHash['update', @@test.name,
315
- :updates, [
316
- { :q => { :a => 2 }, :u => { '$set' => { :a => 1 }}}
317
- ],
318
- :ordered, false]
335
+ command = BSON::OrderedHash['update', @test.name,
336
+ :updates, [
337
+ { :q => { :a => 2 }, :u => { '$set' => { :a => 1 }}}
338
+ ],
339
+ :ordered, false]
319
340
 
320
- assert_raise Mongo::OperationFailure do
321
- @@db.command(command)
322
- end
341
+ assert_raise Mongo::OperationFailure do
342
+ @db.command(command)
323
343
  end
324
344
  end
325
345
 
326
- if @@version >= '2.5.1'
327
-
328
- def test_aggregation_cursor
329
- [10, 1000].each do |size|
330
- @@test.drop
331
- size.times {|i| @@test.insert({ :_id => i }) }
332
- expected_sum = size.times.reduce(:+)
346
+ def test_aggregation_cursor
347
+ return unless @version >= '2.5.1'
348
+ [10, 1000].each do |size|
349
+ @test.drop
350
+ size.times {|i| @test.insert({ :_id => i }) }
351
+ expected_sum = size.times.reduce(:+)
333
352
 
334
- cursor = @@test.aggregate(
353
+ cursor = @test.aggregate(
335
354
  [{ :$project => {:_id => '$_id'}} ],
336
355
  :cursor => {}
337
- )
338
-
339
- assert_equal Mongo::Cursor, cursor.class
356
+ )
340
357
 
341
- cursor_sum = cursor.reduce(0) do |sum, doc|
342
- sum += doc['_id']
343
- end
358
+ assert_equal Mongo::Cursor, cursor.class
344
359
 
345
- assert_equal expected_sum, cursor_sum
360
+ cursor_sum = cursor.reduce(0) do |sum, doc|
361
+ sum += doc['_id']
346
362
  end
347
- @@test.drop
363
+
364
+ assert_equal expected_sum, cursor_sum
348
365
  end
366
+ @test.drop
367
+ end
349
368
 
350
- def test_aggregation_array
351
- @@test.drop
352
- 100.times {|i| @@test.insert({ :_id => i }) }
353
- agg = @@test.aggregate([{ :$project => {:_id => '$_id'}} ])
369
+ def test_aggregation_array
370
+ return unless @version >= '2.5.1'
371
+ @test.drop
372
+ 100.times {|i| @test.insert({ :_id => i }) }
373
+ agg = @test.aggregate([{ :$project => {:_id => '$_id'}} ])
354
374
 
355
- assert agg.kind_of?(Array)
375
+ assert agg.kind_of?(Array)
356
376
 
357
- @@test.drop
358
- end
377
+ @test.drop
378
+ end
359
379
 
360
- def test_aggregation_cursor_invalid_ops
361
- cursor = @@test.aggregate([], :cursor => {})
362
- assert_raise(Mongo::InvalidOperation) { cursor.rewind! }
363
- assert_raise(Mongo::InvalidOperation) { cursor.explain }
364
- assert_raise(Mongo::InvalidOperation) { cursor.count }
365
- end
380
+ def test_aggregation_cursor_invalid_ops
381
+ return unless @version >= '2.5.1'
382
+ cursor = @test.aggregate([], :cursor => {})
383
+ assert_raise(Mongo::InvalidOperation) { cursor.rewind! }
384
+ assert_raise(Mongo::InvalidOperation) { cursor.explain }
385
+ assert_raise(Mongo::InvalidOperation) { cursor.count }
366
386
  end
367
387
 
368
388
  def test_aggregation_invalid_read_pref
369
389
  assert_raise Mongo::MongoArgumentError do
370
- @@test.aggregate([], :read => :invalid_read_pref)
390
+ @test.aggregate([], :read => :invalid_read_pref)
371
391
  end
372
392
  end
373
393
 
374
- if @@version >= '2.5.3'
375
- def test_aggregation_supports_explain
376
- @@db.expects(:command).with do |selector, opts|
377
- opts[:explain] == true
378
- end.returns({ 'ok' => 1 })
379
- @@test.aggregate([], :explain => true)
380
- end
394
+ def test_aggregation_supports_explain
395
+ return unless @version >= '2.5.3'
396
+ @db.expects(:command).with do |selector, opts|
397
+ opts[:explain] == true
398
+ end.returns({ 'ok' => 1 })
399
+ @test.aggregate([], :explain => true)
400
+ end
381
401
 
382
- def test_aggregation_explain_returns_raw_result
383
- response = @@test.aggregate([], :explain => true)
384
- assert response['stages']
385
- end
402
+ def test_aggregation_explain_returns_raw_result
403
+ return unless @version >= '2.5.3'
404
+ response = @test.aggregate([], :explain => true)
405
+ assert response['stages']
386
406
  end
387
407
 
388
408
  def test_capped_method
389
- @@db.create_collection('normal')
390
- assert !@@db['normal'].capped?
391
- @@db.drop_collection('normal')
409
+ @db.create_collection('normal')
410
+ assert !@db['normal'].capped?
411
+ @db.drop_collection('normal')
392
412
 
393
- @@db.create_collection('c', :capped => true, :size => 100_000)
394
- assert @@db['c'].capped?
395
- @@db.drop_collection('c')
413
+ @db.create_collection('c', :capped => true, :size => 100_000)
414
+ assert @db['c'].capped?
415
+ @db.drop_collection('c')
396
416
  end
397
417
 
398
418
  def test_optional_pk_factory
399
- @coll_default_pk = @@db.collection('stuff')
419
+ @coll_default_pk = @db.collection('stuff')
400
420
  assert_equal BSON::ObjectId, @coll_default_pk.pk_factory
401
- @coll_default_pk = @@db.create_collection('more-stuff')
421
+ @coll_default_pk = @db.create_collection('more-stuff')
402
422
  assert_equal BSON::ObjectId, @coll_default_pk.pk_factory
403
423
 
404
424
  # Create a db with a pk_factory.
405
- @db = MongoClient.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
406
- ENV['MONGO_RUBY_DRIVER_PORT'] || MongoClient::DEFAULT_PORT).db(TEST_DB, :pk => Object.new)
407
- @coll = @db.collection('coll-with-pk')
408
- assert @coll.pk_factory.is_a?(Object)
425
+ client = MongoClient.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
426
+ ENV['MONGO_RUBY_DRIVER_PORT'] || MongoClient::DEFAULT_PORT)
427
+ client[TEST_DB].authenticate(TEST_USER, TEST_USER_PWD)
428
+ db = client.db(TEST_DB, :pk => Object.new)
429
+
430
+ coll = db.collection('coll-with-pk')
431
+ assert coll.pk_factory.is_a?(Object)
409
432
 
410
- @coll = @db.create_collection('created_coll_with_pk')
411
- assert @coll.pk_factory.is_a?(Object)
433
+ coll = db.create_collection('created_coll_with_pk')
434
+ assert coll.pk_factory.is_a?(Object)
412
435
  end
413
436
 
414
437
  class PKTest
@@ -418,46 +441,46 @@ class CollectionTest < Test::Unit::TestCase
418
441
 
419
442
  def test_pk_factory_on_collection
420
443
  silently do
421
- @coll = Collection.new('foo', @@db, PKTest)
444
+ @coll = Collection.new('foo', @db, PKTest)
422
445
  assert_equal PKTest, @coll.pk_factory
423
446
  end
424
447
 
425
- @coll2 = Collection.new('foo', @@db, :pk => PKTest)
448
+ @coll2 = Collection.new('foo', @db, :pk => PKTest)
426
449
  assert_equal PKTest, @coll2.pk_factory
427
450
  end
428
451
 
429
452
  def test_valid_names
430
453
  assert_raise Mongo::InvalidNSName do
431
- @@db["te$t"]
454
+ @db["te$t"]
432
455
  end
433
456
 
434
457
  assert_raise Mongo::InvalidNSName do
435
- @@db['$main']
458
+ @db['$main']
436
459
  end
437
460
 
438
- assert @@db['$cmd']
439
- assert @@db['oplog.$main']
461
+ assert @db['$cmd']
462
+ assert @db['oplog.$main']
440
463
  end
441
464
 
442
465
  def test_collection
443
- assert_kind_of Collection, @@db["test"]
444
- assert_equal @@db["test"].name(), @@db.collection("test").name()
445
- assert_equal @@db["test"].name(), @@db[:test].name()
466
+ assert_kind_of Collection, @db["test"]
467
+ assert_equal @db["test"].name(), @db.collection("test").name()
468
+ assert_equal @db["test"].name(), @db[:test].name()
446
469
 
447
- assert_kind_of Collection, @@db["test"]["foo"]
448
- assert_equal @@db["test"]["foo"].name(), @@db.collection("test.foo").name()
449
- assert_equal @@db["test"]["foo"].name(), @@db["test.foo"].name()
470
+ assert_kind_of Collection, @db["test"]["foo"]
471
+ assert_equal @db["test"]["foo"].name(), @db.collection("test.foo").name()
472
+ assert_equal @db["test"]["foo"].name(), @db["test.foo"].name()
450
473
 
451
- @@db["test"]["foo"].remove
452
- @@db["test"]["foo"].insert("x" => 5)
453
- assert_equal 5, @@db.collection("test.foo").find_one()["x"]
474
+ @db["test"]["foo"].remove
475
+ @db["test"]["foo"].insert("x" => 5)
476
+ assert_equal 5, @db.collection("test.foo").find_one()["x"]
454
477
  end
455
478
 
456
479
  def test_rename_collection
457
- @@db.drop_collection('foo1')
458
- @@db.drop_collection('bar1')
480
+ @db.drop_collection('foo1')
481
+ @db.drop_collection('bar1')
459
482
 
460
- @col = @@db.create_collection('foo1')
483
+ @col = @db.create_collection('foo1')
461
484
  assert_equal 'foo1', @col.name
462
485
 
463
486
  @col.rename('bar1')
@@ -465,69 +488,69 @@ class CollectionTest < Test::Unit::TestCase
465
488
  end
466
489
 
467
490
  def test_nil_id
468
- assert_equal 5, @@test.insert({"_id" => 5, "foo" => "bar"})
469
- assert_equal 5, @@test.save({"_id" => 5, "foo" => "baz"})
470
- assert_equal nil, @@test.find_one("foo" => "bar")
471
- assert_equal "baz", @@test.find_one(:_id => 5)["foo"]
491
+ assert_equal 5, @test.insert({"_id" => 5, "foo" => "bar"})
492
+ assert_equal 5, @test.save({"_id" => 5, "foo" => "baz"})
493
+ assert_equal nil, @test.find_one("foo" => "bar")
494
+ assert_equal "baz", @test.find_one(:_id => 5)["foo"]
472
495
  assert_raise OperationFailure do
473
- @@test.insert({"_id" => 5, "foo" => "bar"})
496
+ @test.insert({"_id" => 5, "foo" => "bar"})
474
497
  end
475
498
 
476
- assert_equal nil, @@test.insert({"_id" => nil, "foo" => "bar"})
477
- assert_equal nil, @@test.save({"_id" => nil, "foo" => "baz"})
478
- assert_equal nil, @@test.find_one("foo" => "bar")
479
- assert_equal "baz", @@test.find_one(:_id => nil)["foo"]
499
+ assert_equal nil, @test.insert({"_id" => nil, "foo" => "bar"})
500
+ assert_equal nil, @test.save({"_id" => nil, "foo" => "baz"})
501
+ assert_equal nil, @test.find_one("foo" => "bar")
502
+ assert_equal "baz", @test.find_one(:_id => nil)["foo"]
480
503
  assert_raise OperationFailure do
481
- @@test.insert({"_id" => nil, "foo" => "bar"})
504
+ @test.insert({"_id" => nil, "foo" => "bar"})
482
505
  end
483
506
  assert_raise OperationFailure do
484
- @@test.insert({:_id => nil, "foo" => "bar"})
507
+ @test.insert({:_id => nil, "foo" => "bar"})
485
508
  end
486
509
  end
487
510
 
488
- if @@version > "1.1"
489
- def setup_for_distinct
490
- @@test.remove
491
- @@test.insert([{:a => 0, :b => {:c => "a"}},
492
- {:a => 1, :b => {:c => "b"}},
493
- {:a => 1, :b => {:c => "c"}},
494
- {:a => 2, :b => {:c => "a"}},
495
- {:a => 3},
496
- {:a => 3}])
497
- end
511
+ def setup_for_distinct
512
+ return unless @version > "1.1"
513
+ @test.remove
514
+ @test.insert([{:a => 0, :b => {:c => "a"}},
515
+ {:a => 1, :b => {:c => "b"}},
516
+ {:a => 1, :b => {:c => "c"}},
517
+ {:a => 2, :b => {:c => "a"}},
518
+ {:a => 3},
519
+ {:a => 3}])
520
+ end
498
521
 
499
- def test_distinct_queries
500
- setup_for_distinct
501
- assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
502
- assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
503
- end
522
+ def test_distinct_queries
523
+ return unless @version > "1.1"
524
+ setup_for_distinct
525
+ assert_equal [0, 1, 2, 3], @test.distinct(:a).sort
526
+ assert_equal ["a", "b", "c"], @test.distinct("b.c").sort
527
+ end
504
528
 
505
- if @@version >= "1.2"
506
- def test_filter_collection_with_query
507
- setup_for_distinct
508
- assert_equal [2, 3], @@test.distinct(:a, {:a => {"$gt" => 1}}).sort
509
- end
529
+ def test_filter_collection_with_query
530
+ return unless @version >= "1.2"
531
+ setup_for_distinct
532
+ assert_equal [2, 3], @test.distinct(:a, {:a => {"$gt" => 1}}).sort
533
+ end
510
534
 
511
- def test_filter_nested_objects
512
- setup_for_distinct
513
- assert_equal ["a", "b"], @@test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
514
- end
515
- end
535
+ def test_filter_nested_objects
536
+ return unless @version >= "1.2"
537
+ setup_for_distinct
538
+ assert_equal ["a", "b"], @test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
516
539
  end
517
540
 
518
541
  def test_safe_insert
519
- @@test.create_index("hello", :unique => true)
542
+ @test.create_index("hello", :unique => true)
520
543
  begin
521
544
  a = {"hello" => "world"}
522
- @@test.insert(a)
523
- @@test.insert(a, :w => 0)
524
- assert(@@db.get_last_error['err'].include?("11000"))
545
+ @test.insert(a)
546
+ @test.insert(a, :w => 0)
547
+ assert(@db.get_last_error['err'].include?("11000"))
525
548
 
526
549
  assert_raise OperationFailure do
527
- @@test.insert(a)
550
+ @test.insert(a)
528
551
  end
529
552
  ensure
530
- @@test.drop_indexes
553
+ @test.drop_indexes
531
554
  end
532
555
  end
533
556
 
@@ -536,15 +559,15 @@ class CollectionTest < Test::Unit::TestCase
536
559
  docs << {:foo => 1}
537
560
  docs << {:foo => 2}
538
561
  docs << {:foo => 3}
539
- response = @@test.insert(docs)
562
+ response = @test.insert(docs)
540
563
  assert_equal 3, response.length
541
564
  assert response.all? {|id| id.is_a?(BSON::ObjectId)}
542
- assert_equal 3, @@test.count
565
+ assert_equal 3, @test.count
543
566
  end
544
567
 
545
568
  def test_bulk_insert_with_continue_on_error
546
- if @@version >= "2.0"
547
- @@test.create_index([["foo", 1]], :unique => true)
569
+ if @version >= "2.0"
570
+ @test.create_index([["foo", 1]], :unique => true)
548
571
  begin
549
572
  docs = []
550
573
  docs << {:foo => 1}
@@ -552,10 +575,10 @@ class CollectionTest < Test::Unit::TestCase
552
575
  docs << {:foo => 2}
553
576
  docs << {:foo => 3}
554
577
  assert_raise OperationFailure do
555
- @@test.insert(docs)
578
+ @test.insert(docs)
556
579
  end
557
- assert_equal 1, @@test.count
558
- @@test.remove
580
+ assert_equal 1, @test.count
581
+ @test.remove
559
582
 
560
583
  docs = []
561
584
  docs << {:foo => 1}
@@ -563,13 +586,13 @@ class CollectionTest < Test::Unit::TestCase
563
586
  docs << {:foo => 2}
564
587
  docs << {:foo => 3}
565
588
  assert_raise OperationFailure do
566
- @@test.insert(docs, :continue_on_error => true)
589
+ @test.insert(docs, :continue_on_error => true)
567
590
  end
568
- assert_equal 3, @@test.count
591
+ assert_equal 3, @test.count
569
592
 
570
- @@test.remove
593
+ @test.remove
571
594
  ensure
572
- @@test.drop_index("foo_1")
595
+ @test.drop_index("foo_1")
573
596
  end
574
597
  end
575
598
  end
@@ -578,8 +601,8 @@ class CollectionTest < Test::Unit::TestCase
578
601
  docs = []
579
602
  docs << {:foo => 1}
580
603
  docs << {:bar => 1}
581
- doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
582
- assert_equal 2, @@test.count
604
+ doc_ids, error_docs = @test.insert(docs, :collect_on_error => true)
605
+ assert_equal 2, @test.count
583
606
  assert_equal 2, doc_ids.count
584
607
  assert_equal error_docs, []
585
608
  end
@@ -593,12 +616,12 @@ class CollectionTest < Test::Unit::TestCase
593
616
  invalid_docs << {'invalid.key' => 1}
594
617
  docs += invalid_docs
595
618
  assert_raise BSON::InvalidKeyName do
596
- @@test.insert(docs, :collect_on_error => false)
619
+ @test.insert(docs, :collect_on_error => false)
597
620
  end
598
- assert_equal 2, @@test.count
621
+ assert_equal 2, @test.count
599
622
 
600
- doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
601
- assert_equal 2, @@test.count
623
+ doc_ids, error_docs = @test.insert(docs, :collect_on_error => true)
624
+ assert_equal 2, @test.count
602
625
  assert_equal 2, doc_ids.count
603
626
  assert_equal error_docs, invalid_docs
604
627
  end
@@ -614,12 +637,12 @@ class CollectionTest < Test::Unit::TestCase
614
637
  docs += invalid_docs
615
638
 
616
639
  assert_raise BSON::InvalidStringEncoding do
617
- @@test.insert(docs, :collect_on_error => false)
640
+ @test.insert(docs, :collect_on_error => false)
618
641
  end
619
- assert_equal 2, @@test.count
642
+ assert_equal 2, @test.count
620
643
 
621
- doc_ids, error_docs = @@test.insert(docs, :collect_on_error => true)
622
- assert_equal 2, @@test.count
644
+ doc_ids, error_docs = @test.insert(docs, :collect_on_error => true)
645
+ assert_equal 2, @test.count
623
646
  assert_equal 2, doc_ids.count
624
647
  assert_equal error_docs, invalid_docs
625
648
  end
@@ -627,20 +650,20 @@ class CollectionTest < Test::Unit::TestCase
627
650
  def test_insert_one_error_doc_with_collect_on_error
628
651
  invalid_doc = {'$invalid-key' => 1}
629
652
  invalid_docs = [invalid_doc]
630
- doc_ids, error_docs = @@test.insert(invalid_docs, :collect_on_error => true)
653
+ doc_ids, error_docs = @test.insert(invalid_docs, :collect_on_error => true)
631
654
  assert_equal [], doc_ids
632
655
  assert_equal [invalid_doc], error_docs
633
656
  end
634
657
 
635
658
  def test_insert_empty_docs_raises_exception
636
659
  assert_raise OperationFailure do
637
- @@test.insert([])
660
+ @test.insert([])
638
661
  end
639
662
  end
640
663
 
641
664
  def test_insert_empty_docs_with_collect_on_error_raises_exception
642
665
  assert_raise OperationFailure do
643
- @@test.insert([], :collect_on_error => true)
666
+ @test.insert([], :collect_on_error => true)
644
667
  end
645
668
  end
646
669
 
@@ -648,11 +671,11 @@ class CollectionTest < Test::Unit::TestCase
648
671
  conn = standard_connection(:connect => false)
649
672
  admin_db = Object.new
650
673
  admin_db.expects(:command).returns({
651
- 'ok' => 1,
652
- 'ismaster' => 1,
653
- 'maxBsonObjectSize' => LIMITED_MAX_BSON_SIZE,
654
- 'maxMessageSizeBytes' => LIMITED_MAX_MESSAGE_SIZE
655
- })
674
+ 'ok' => 1,
675
+ 'ismaster' => 1,
676
+ 'maxBsonObjectSize' => LIMITED_MAX_BSON_SIZE,
677
+ 'maxMessageSizeBytes' => LIMITED_MAX_MESSAGE_SIZE
678
+ })
656
679
  conn.expects(:[]).with('admin').returns(admin_db)
657
680
  conn.connect
658
681
  return conn.db(TEST_DB)["test"]
@@ -671,13 +694,13 @@ class CollectionTest < Test::Unit::TestCase
671
694
  end
672
695
 
673
696
  def test_chunking_batch_insert
674
- docs = []
675
- 10.times do
676
- docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
677
- end
678
- limited_collection.insert(docs)
679
- assert_equal 10, limited_collection.count
680
- end
697
+ docs = []
698
+ 10.times do
699
+ docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
700
+ end
701
+ limited_collection.insert(docs)
702
+ assert_equal 10, limited_collection.count
703
+ end
681
704
 
682
705
  def test_chunking_batch_insert_without_collect_on_error
683
706
  docs = []
@@ -696,8 +719,8 @@ class CollectionTest < Test::Unit::TestCase
696
719
  end
697
720
 
698
721
  def test_chunking_batch_insert_with_collect_on_error
699
- # Broken for current JRuby
700
- if RUBY_PLATFORM == 'java' then return end
722
+ # Broken for current JRuby
723
+ if RUBY_PLATFORM == 'java' then return end
701
724
  docs = []
702
725
  4.times do
703
726
  docs << {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
@@ -797,17 +820,17 @@ class CollectionTest < Test::Unit::TestCase
797
820
  end
798
821
 
799
822
  assert limited_collection.update(
800
- {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE},
801
- {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
802
- )
823
+ {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE},
824
+ {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}
825
+ )
803
826
  end
804
827
 
805
828
  def test_maximum_query_size
806
829
  assert limited_collection.find({'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}).to_a
807
830
  assert limited_collection.find(
808
- {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE},
809
- {:fields => {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}}
810
- ).to_a
831
+ {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE},
832
+ {:fields => {'foo' => 'a' * LIMITED_VALID_VALUE_SIZE}}
833
+ ).to_a
811
834
 
812
835
  assert_raise InvalidDocument do
813
836
  limited_collection.find({'foo' => 'a' * LIMITED_INVALID_VALUE_SIZE}).to_a
@@ -821,138 +844,120 @@ class CollectionTest < Test::Unit::TestCase
821
844
  end
822
845
  end
823
846
 
824
- #if @@version >= "1.5.1"
847
+ #if @version >= "1.5.1"
825
848
  # def test_safe_mode_with_advanced_safe_with_invalid_options
826
849
  # assert_raise_error ArgumentError, "Unknown key(s): wtime" do
827
- # @@test.insert({:foo => 1}, :w => 2, :wtime => 1, :fsync => true)
850
+ # @test.insert({:foo => 1}, :w => 2, :wtime => 1, :fsync => true)
828
851
  # end
829
852
  # assert_raise_error ArgumentError, "Unknown key(s): wtime" do
830
- # @@test.update({:foo => 1}, {:foo => 2}, :w => 2, :wtime => 1, :fsync => true)
853
+ # @test.update({:foo => 1}, {:foo => 2}, :w => 2, :wtime => 1, :fsync => true)
831
854
  # end
832
855
  #
833
856
  # assert_raise_error ArgumentError, "Unknown key(s): wtime" do
834
- # @@test.remove({:foo => 2}, :w => 2, :wtime => 1, :fsync => true)
857
+ # @test.remove({:foo => 2}, :w => 2, :wtime => 1, :fsync => true)
835
858
  # end
836
859
  # end
837
860
  #end
838
861
 
839
862
  def test_safe_mode_with_journal_commit_option
840
- with_default_journaling(@@client) do
841
- @@test.insert({:foo => 1}, :j => true)
842
- @@test.update({:foo => 1}, {:foo => 2}, :j => true)
843
- @@test.remove({:foo => 2}, :j => true)
863
+ with_default_journaling(@client) do
864
+ @test.insert({:foo => 1}, :j => true)
865
+ @test.update({:foo => 1}, {:foo => 2}, :j => true)
866
+ @test.remove({:foo => 2}, :j => true)
844
867
  end
845
868
  end
846
869
 
847
- if @@version < "2.5.3"
848
- def test_jnote_raises_exception
849
- with_no_journaling(@@client) do
850
- ex = assert_raise Mongo::WriteConcernError do
851
- @@test.insert({:foo => 1}, :j => true)
852
- end
853
- result = ex.result
854
- assert_true result.has_key?("jnote")
855
- end
856
- end
857
-
858
- def test_wnote_raises_exception_with_err_not_nil
870
+ def test_jnote_raises_exception
871
+ return unless @version < "2.5.3"
872
+ with_no_journaling(@client) do
859
873
  ex = assert_raise Mongo::WriteConcernError do
860
- @@test.insert({:foo => 1}, :w => 2)
874
+ @test.insert({:foo => 1}, :j => true)
861
875
  end
862
876
  result = ex.result
863
- assert_not_nil result["err"]
864
- assert_true result.has_key?("wnote")
877
+ assert_true result.has_key?("jnote")
865
878
  end
866
879
  end
867
880
 
881
+ def test_wnote_raises_exception_with_err_not_nil
882
+ return unless @version < "2.5.3"
883
+ ex = assert_raise Mongo::WriteConcernError do
884
+ @test.insert({:foo => 1}, :w => 2)
885
+ end
886
+ result = ex.result
887
+ assert_not_nil result["err"]
888
+ assert_true result.has_key?("wnote")
889
+ end
890
+
868
891
  def test_update
869
- id1 = @@test.save("x" => 5)
870
- @@test.update({}, {"$inc" => {"x" => 1}})
871
- assert_equal 1, @@test.count()
872
- assert_equal 6, @@test.find_one(:_id => id1)["x"]
892
+ id1 = @test.save("x" => 5)
893
+ @test.update({}, {"$inc" => {"x" => 1}})
894
+ assert_equal 1, @test.count()
895
+ assert_equal 6, @test.find_one(:_id => id1)["x"]
873
896
 
874
- id2 = @@test.save("x" => 1)
875
- @@test.update({"x" => 6}, {"$inc" => {"x" => 1}})
876
- assert_equal 7, @@test.find_one(:_id => id1)["x"]
877
- assert_equal 1, @@test.find_one(:_id => id2)["x"]
897
+ id2 = @test.save("x" => 1)
898
+ @test.update({"x" => 6}, {"$inc" => {"x" => 1}})
899
+ assert_equal 7, @test.find_one(:_id => id1)["x"]
900
+ assert_equal 1, @test.find_one(:_id => id2)["x"]
878
901
  end
879
902
 
880
- if @@version < "2.5.3"
881
- def test_update_check_keys
882
- @@test.save("x" => 1)
883
- @@test.update({"x" => 1}, {"$set" => {"a.b" => 2}})
884
- assert_equal 2, @@test.find_one("x" => 1)["a"]["b"]
903
+ def test_update_check_keys
904
+ return unless @version < "2.5.3"
905
+ @test.save("x" => 1)
906
+ @test.update({"x" => 1}, {"$set" => {"a.b" => 2}})
907
+ assert_equal 2, @test.find_one("x" => 1)["a"]["b"]
885
908
 
886
- assert_raise_error BSON::InvalidKeyName do
887
- @@test.update({"x" => 1}, {"a.b" => 3})
888
- end
909
+ assert_raise_error BSON::InvalidKeyName do
910
+ @test.update({"x" => 1}, {"a.b" => 3})
889
911
  end
890
912
  end
891
913
 
892
- if @@version >= "1.1.3"
893
- def test_multi_update
894
- @@test.save("num" => 10)
895
- @@test.save("num" => 10)
896
- @@test.save("num" => 10)
897
- assert_equal 3, @@test.count
914
+ def test_multi_update
915
+ return unless @version >= "1.1.3"
916
+ @test.save("num" => 10)
917
+ @test.save("num" => 10)
918
+ @test.save("num" => 10)
919
+ assert_equal 3, @test.count
898
920
 
899
- @@test.update({"num" => 10}, {"$set" => {"num" => 100}}, :multi => true)
900
- @@test.find.each do |doc|
901
- assert_equal 100, doc["num"]
902
- end
921
+ @test.update({"num" => 10}, {"$set" => {"num" => 100}}, :multi => true)
922
+ @test.find.each do |doc|
923
+ assert_equal 100, doc["num"]
903
924
  end
904
925
  end
905
926
 
906
927
  def test_upsert
907
- @@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
908
- @@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
928
+ @test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
929
+ @test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
909
930
 
910
- assert_equal 1, @@test.count()
911
- assert_equal 2, @@test.find_one()["count"]
931
+ assert_equal 1, @test.count()
932
+ assert_equal 2, @test.find_one()["count"]
912
933
  end
913
934
 
914
- if @@version < "1.1.3"
915
- def test_safe_update
916
- @@test.create_index("x")
917
- @@test.insert("x" => 5)
918
-
919
- @@test.update({}, {"$inc" => {"x" => 1}})
920
- assert @@db.error?
921
-
922
- # Can't change an index.
923
- assert_raise OperationFailure do
924
- @@test.update({}, {"$inc" => {"x" => 1}})
925
- end
926
- @@test.drop
927
- end
928
- else
929
- def test_safe_update
930
- @@test.create_index("x", :unique => true)
931
- @@test.insert("x" => 5)
932
- @@test.insert("x" => 10)
935
+ def test_safe_update
936
+ @test.create_index("x", :unique => true)
937
+ @test.insert("x" => 5)
938
+ @test.insert("x" => 10)
933
939
 
934
- # Can update an indexed collection.
935
- @@test.update({}, {"$inc" => {"x" => 1}})
936
- assert !@@db.error?
940
+ # Can update an indexed collection.
941
+ @test.update({}, {"$inc" => {"x" => 1}})
942
+ assert !@db.error?
937
943
 
938
- # Can't duplicate an index.
939
- assert_raise OperationFailure do
940
- @@test.update({}, {"x" => 10})
941
- end
942
- @@test.drop
944
+ # Can't duplicate an index.
945
+ assert_raise OperationFailure do
946
+ @test.update({}, {"x" => 10})
943
947
  end
948
+ @test.drop
944
949
  end
945
950
 
946
951
  def test_safe_save
947
- @@test.create_index("hello", :unique => true)
952
+ @test.create_index("hello", :unique => true)
948
953
 
949
- @@test.save("hello" => "world")
950
- @@test.save({"hello" => "world"}, :w => 0)
954
+ @test.save("hello" => "world")
955
+ @test.save({"hello" => "world"}, :w => 0)
951
956
 
952
957
  assert_raise OperationFailure do
953
- @@test.save({"hello" => "world"})
958
+ @test.save({"hello" => "world"})
954
959
  end
955
- @@test.drop
960
+ @test.drop
956
961
  end
957
962
 
958
963
  def test_mocked_safe_remove
@@ -979,161 +984,216 @@ class CollectionTest < Test::Unit::TestCase
979
984
  end
980
985
 
981
986
  def test_remove_return_value
982
- assert_equal true, @@test.remove({}, :w => 0)
987
+ assert_equal true, @test.remove({}, :w => 0)
983
988
  end
984
989
 
985
990
  def test_remove_with_limit
986
- @@test.insert([{:n => 1},{:n => 2},{:n => 3}])
987
- @@test.remove({}, :limit => 1)
988
- assert_equal 2, @@test.count
989
- @@test.remove({}, :limit => 0)
990
- assert_equal 0, @@test.count
991
+ @test.insert([{:n => 1},{:n => 2},{:n => 3}])
992
+ @test.remove({}, :limit => 1)
993
+ assert_equal 2, @test.count
994
+ @test.remove({}, :limit => 0)
995
+ assert_equal 0, @test.count
991
996
  end
992
997
 
993
998
  def test_count
994
- @@test.drop
999
+ @test.drop
1000
+
1001
+ assert_equal 0, @test.count
1002
+ @test.save(:x => 1)
1003
+ @test.save(:x => 2)
1004
+ assert_equal 2, @test.count
1005
+
1006
+ assert_equal 1, @test.count(:query => {:x => 1})
1007
+ assert_equal 1, @test.count(:limit => 1)
1008
+ assert_equal 0, @test.count(:skip => 2)
1009
+ end
1010
+
1011
+ def test_count_with_hint
1012
+ @test.drop
1013
+ @test.save(:i => 1)
1014
+ @test.save(:i => 2)
1015
+ assert_equal 2, @test.count
1016
+
1017
+ @test.ensure_index(BSON::OrderedHash[:i, Mongo::ASCENDING])
1018
+
1019
+ # Check that a named_hint can be specified
1020
+ assert_equal 1, @test.count(:query => { :i => 1 }, :named_hint => '_id_')
1021
+ assert_equal 2, @test.count(:query => { }, :named_hint => '_id_')
1022
+
1023
+ # Verify that the hint is being sent to the server by providing a bad hint
1024
+ if @version > '2.6'
1025
+ assert_raise Mongo::OperationFailure do
1026
+ @test.count(:query => { :i => 1 }, :hint => 'bad_hint')
1027
+ end
1028
+ else
1029
+ assert_equal 1, @test.count(:query => { :i => 1 }, :hint => 'bad_hint')
1030
+ end
1031
+
1032
+ # Verify that the named_hint is being sent to the server by providing a bad hint
1033
+ if @version > '2.6'
1034
+ assert_raise Mongo::OperationFailure do
1035
+ @test.count(:query => { :i => 1 }, :named_hint => 'bad_hint')
1036
+ end
1037
+ else
1038
+ assert_equal 1, @test.count(:query => { :i => 1 }, :named_hint => 'bad_hint')
1039
+ end
1040
+
1041
+ @test.ensure_index(BSON::OrderedHash[:x, Mongo::ASCENDING], :sparse => true)
995
1042
 
996
- assert_equal 0, @@test.count
997
- @@test.save(:x => 1)
998
- @@test.save(:x => 2)
999
- assert_equal 2, @@test.count
1043
+ # The sparse index won't have any entries.
1044
+ # Check that count returns 0 when using the hint.
1045
+ expected = @version > '2.6' ? 0 : 1
1046
+ assert_equal expected, @test.count(:query => { :i => 1 }, :hint => { 'x' => 1 })
1047
+ assert_equal expected, @test.count(:query => { :i => 1 }, :hint => 'x')
1048
+ assert_equal expected, @test.count(:query => { :i => 1 }, :named_hint => 'x_1')
1000
1049
 
1001
- assert_equal 1, @@test.count(:query => {:x => 1})
1002
- assert_equal 1, @@test.count(:limit => 1)
1003
- assert_equal 0, @@test.count(:skip => 2)
1050
+ # Verify that the hint / named hint set on the collection is used.
1051
+ @test.hint = { 'x' => 1 }
1052
+ assert_equal expected, @test.count(:query => { :i => 1 })
1053
+
1054
+ @test.hint = 'x'
1055
+ assert_equal expected, @test.count(:query => { :i => 1 })
1056
+
1057
+ # The driver should allow x_1, but the code sets named_hint to @hint without
1058
+ # normalizing.
1059
+ @test.named_hint = 'x'
1060
+ assert_equal expected, @test.count(:query => { :i => 1 })
1061
+
1062
+ assert_equal 2, @test.count(:query => { }, :hint => 'x')
1063
+ assert_equal 2, @test.count(:query => { }, :named_hint => 'x_1')
1004
1064
  end
1005
1065
 
1006
1066
  # Note: #size is just an alias for #count.
1007
1067
  def test_size
1008
- @@test.drop
1068
+ @test.drop
1009
1069
 
1010
- assert_equal 0, @@test.count
1011
- assert_equal @@test.size, @@test.count
1012
- @@test.save("x" => 1)
1013
- @@test.save("x" => 2)
1014
- assert_equal @@test.size, @@test.count
1070
+ assert_equal 0, @test.count
1071
+ assert_equal @test.size, @test.count
1072
+ @test.save("x" => 1)
1073
+ @test.save("x" => 2)
1074
+ assert_equal @test.size, @test.count
1015
1075
  end
1016
1076
 
1017
1077
  def test_no_timeout_option
1018
- @@test.drop
1078
+ @test.drop
1019
1079
 
1020
1080
  assert_raise ArgumentError, "Timeout can be set to false only when #find is invoked with a block." do
1021
- @@test.find({}, :timeout => false)
1081
+ @test.find({}, :timeout => false)
1022
1082
  end
1023
1083
 
1024
- @@test.find({}, :timeout => false) do |cursor|
1084
+ @test.find({}, :timeout => false) do |cursor|
1025
1085
  assert_equal 0, cursor.count
1026
1086
  end
1027
1087
 
1028
- @@test.save("x" => 1)
1029
- @@test.save("x" => 2)
1030
- @@test.find({}, :timeout => false) do |cursor|
1088
+ @test.save("x" => 1)
1089
+ @test.save("x" => 2)
1090
+ @test.find({}, :timeout => false) do |cursor|
1031
1091
  assert_equal 2, cursor.count
1032
1092
  end
1033
1093
  end
1034
1094
 
1035
1095
  def test_default_timeout
1036
- cursor = @@test.find
1096
+ cursor = @test.find
1037
1097
  assert_equal true, cursor.timeout
1038
1098
  end
1039
1099
 
1040
1100
  def test_fields_as_hash
1041
- @@test.save(:a => 1, :b => 1, :c => 1)
1101
+ @test.save(:a => 1, :b => 1, :c => 1)
1042
1102
 
1043
- doc = @@test.find_one({:a => 1}, :fields => {:b => 0})
1103
+ doc = @test.find_one({:a => 1}, :fields => {:b => 0})
1044
1104
  assert_nil doc['b']
1045
1105
  assert doc['a']
1046
1106
  assert doc['c']
1047
1107
 
1048
- doc = @@test.find_one({:a => 1}, :fields => {:a => 1, :b => 1})
1108
+ doc = @test.find_one({:a => 1}, :fields => {:a => 1, :b => 1})
1049
1109
  assert_nil doc['c']
1050
1110
  assert doc['a']
1051
1111
  assert doc['b']
1052
1112
 
1053
1113
 
1054
1114
  assert_raise Mongo::OperationFailure do
1055
- @@test.find_one({:a => 1}, :fields => {:a => 1, :b => 0})
1115
+ @test.find_one({:a => 1}, :fields => {:a => 1, :b => 0})
1056
1116
  end
1057
1117
  end
1058
1118
 
1059
- if @@version >= '2.5.5'
1060
- def test_meta_field_projection
1061
- @@test.save({ :t => 'spam eggs and spam'})
1062
- @@test.save({ :t => 'spam'})
1063
- @@test.save({ :t => 'egg sausage and bacon'})
1064
1119
 
1065
- @@test.ensure_index([[:t, 'text']])
1066
- assert @@test.find_one({ :$text => { :$search => 'spam' }},
1067
- { :fields => [:t, { :score => { :$meta => 'textScore' } }] })
1068
- end
1120
+ def test_meta_field_projection
1121
+ return unless @version >= '2.5.5'
1122
+ @test.save({ :t => 'spam eggs and spam'})
1123
+ @test.save({ :t => 'spam'})
1124
+ @test.save({ :t => 'egg sausage and bacon'})
1069
1125
 
1070
- def test_sort_by_meta
1071
- @@test.save({ :t => 'spam eggs and spam'})
1072
- @@test.save({ :t => 'spam'})
1073
- @@test.save({ :t => 'egg sausage and bacon'})
1126
+ @test.ensure_index([[:t, 'text']])
1127
+ assert @test.find_one({ :$text => { :$search => 'spam' }},
1128
+ { :fields => [:t, { :score => { :$meta => 'textScore' } }] })
1129
+ end
1074
1130
 
1075
- @@test.ensure_index([[:t, 'text']])
1076
- assert @@test.find({ :$text => { :$search => 'spam' }}).sort([:score, { '$meta' => 'textScore' }])
1077
- assert @@test.find({ :$text => { :$search => 'spam' }}).sort(:score => { '$meta' =>'textScore' })
1078
- end
1131
+ def test_sort_by_meta
1132
+ return unless @version >= '2.5.5'
1133
+ @test.save({ :t => 'spam eggs and spam'})
1134
+ @test.save({ :t => 'spam'})
1135
+ @test.save({ :t => 'egg sausage and bacon'})
1136
+
1137
+ @test.ensure_index([[:t, 'text']])
1138
+ assert @test.find({ :$text => { :$search => 'spam' }}).sort([:score, { '$meta' => 'textScore' }])
1139
+ assert @test.find({ :$text => { :$search => 'spam' }}).sort(:score => { '$meta' =>'textScore' })
1079
1140
  end
1080
1141
 
1081
- if @@version >= "1.5.1"
1082
- def test_fields_with_slice
1083
- @@test.save({:foo => [1, 2, 3, 4, 5, 6], :test => 'slice'})
1142
+ def test_fields_with_slice
1143
+ return unless @version >= "1.5.1"
1144
+ @test.save({:foo => [1, 2, 3, 4, 5, 6], :test => 'slice'})
1084
1145
 
1085
- doc = @@test.find_one({:test => 'slice'}, :fields => {'foo' => {'$slice' => [0, 3]}})
1086
- assert_equal [1, 2, 3], doc['foo']
1087
- @@test.remove
1088
- end
1146
+ doc = @test.find_one({:test => 'slice'}, :fields => {'foo' => {'$slice' => [0, 3]}})
1147
+ assert_equal [1, 2, 3], doc['foo']
1148
+ @test.remove
1089
1149
  end
1090
1150
 
1091
1151
  def test_find_one
1092
- id = @@test.save("hello" => "world", "foo" => "bar")
1152
+ id = @test.save("hello" => "world", "foo" => "bar")
1093
1153
 
1094
- assert_equal "world", @@test.find_one()["hello"]
1095
- assert_equal @@test.find_one(id), @@test.find_one()
1096
- assert_equal @@test.find_one(nil), @@test.find_one()
1097
- assert_equal @@test.find_one({}), @@test.find_one()
1098
- assert_equal @@test.find_one("hello" => "world"), @@test.find_one()
1099
- assert_equal @@test.find_one(BSON::OrderedHash["hello", "world"]), @@test.find_one()
1154
+ assert_equal "world", @test.find_one()["hello"]
1155
+ assert_equal @test.find_one(id), @test.find_one()
1156
+ assert_equal @test.find_one(nil), @test.find_one()
1157
+ assert_equal @test.find_one({}), @test.find_one()
1158
+ assert_equal @test.find_one("hello" => "world"), @test.find_one()
1159
+ assert_equal @test.find_one(BSON::OrderedHash["hello", "world"]), @test.find_one()
1100
1160
 
1101
- assert @@test.find_one(nil, :fields => ["hello"]).include?("hello")
1102
- assert !@@test.find_one(nil, :fields => ["foo"]).include?("hello")
1103
- assert_equal ["_id"], @@test.find_one(nil, :fields => []).keys()
1161
+ assert @test.find_one(nil, :fields => ["hello"]).include?("hello")
1162
+ assert !@test.find_one(nil, :fields => ["foo"]).include?("hello")
1163
+ assert_equal ["_id"], @test.find_one(nil, :fields => []).keys()
1104
1164
 
1105
- assert_equal nil, @@test.find_one("hello" => "foo")
1106
- assert_equal nil, @@test.find_one(BSON::OrderedHash["hello", "foo"])
1107
- assert_equal nil, @@test.find_one(ObjectId.new)
1165
+ assert_equal nil, @test.find_one("hello" => "foo")
1166
+ assert_equal nil, @test.find_one(BSON::OrderedHash["hello", "foo"])
1167
+ assert_equal nil, @test.find_one(ObjectId.new)
1108
1168
 
1109
1169
  assert_raise TypeError do
1110
- @@test.find_one(6)
1170
+ @test.find_one(6)
1111
1171
  end
1112
1172
  end
1113
1173
 
1114
1174
  def test_find_one_with_max_time_ms
1115
- with_forced_timeout(@@client) do
1175
+ with_forced_timeout(@client) do
1116
1176
  assert_raise ExecutionTimeout do
1117
- @@test.find_one({}, { :max_time_ms => 100 })
1177
+ @test.find_one({}, { :max_time_ms => 100 })
1118
1178
  end
1119
1179
  end
1120
1180
  end
1121
1181
 
1122
1182
  def test_find_one_with_compile_regex_option
1123
1183
  regex = /.*/
1124
- @@test.insert('r' => /.*/)
1125
- assert_kind_of Regexp, @@test.find_one({})['r']
1126
- assert_kind_of Regexp, @@test.find_one({}, :compile_regex => true)['r']
1127
- assert_equal BSON::Regex, @@test.find_one({}, :compile_regex => false)['r'].class
1184
+ @test.insert('r' => /.*/)
1185
+ assert_kind_of Regexp, @test.find_one({})['r']
1186
+ assert_kind_of Regexp, @test.find_one({}, :compile_regex => true)['r']
1187
+ assert_equal BSON::Regex, @test.find_one({}, :compile_regex => false)['r'].class
1128
1188
  end
1129
1189
 
1130
1190
  def test_insert_adds_id
1131
1191
  doc = {"hello" => "world"}
1132
- @@test.insert(doc)
1192
+ @test.insert(doc)
1133
1193
  assert(doc.include?(:_id))
1134
1194
 
1135
1195
  docs = [{"hello" => "world"}, {"hello" => "world"}]
1136
- @@test.insert(docs)
1196
+ @test.insert(docs)
1137
1197
  docs.each do |d|
1138
1198
  assert(d.include?(:_id))
1139
1199
  end
@@ -1141,23 +1201,23 @@ class CollectionTest < Test::Unit::TestCase
1141
1201
 
1142
1202
  def test_save_adds_id
1143
1203
  doc = {"hello" => "world"}
1144
- @@test.save(doc)
1204
+ @test.save(doc)
1145
1205
  assert(doc.include?(:_id))
1146
1206
  end
1147
1207
 
1148
1208
  def test_optional_find_block
1149
1209
  10.times do |i|
1150
- @@test.save("i" => i)
1210
+ @test.save("i" => i)
1151
1211
  end
1152
1212
 
1153
1213
  x = nil
1154
- @@test.find("i" => 2) { |cursor|
1214
+ @test.find("i" => 2) { |cursor|
1155
1215
  x = cursor.count()
1156
1216
  }
1157
1217
  assert_equal 1, x
1158
1218
 
1159
1219
  i = 0
1160
- @@test.find({}, :skip => 5) do |cursor|
1220
+ @test.find({}, :skip => 5) do |cursor|
1161
1221
  cursor.each do |doc|
1162
1222
  i = i + 1
1163
1223
  end
@@ -1165,7 +1225,7 @@ class CollectionTest < Test::Unit::TestCase
1165
1225
  assert_equal 5, i
1166
1226
 
1167
1227
  c = nil
1168
- @@test.find() do |cursor|
1228
+ @test.find() do |cursor|
1169
1229
  c = cursor
1170
1230
  end
1171
1231
  assert c.closed?
@@ -1173,396 +1233,408 @@ class CollectionTest < Test::Unit::TestCase
1173
1233
 
1174
1234
  def setup_aggregate_data
1175
1235
  # save some data
1176
- @@test.save( {
1177
- "_id" => 1,
1178
- "title" => "this is my title",
1179
- "author" => "bob",
1180
- "posted" => Time.utc(2000),
1181
- "pageViews" => 5 ,
1182
- "tags" => [ "fun" , "good" , "fun" ],
1183
- "comments" => [
1184
- { "author" => "joe", "text" => "this is cool" },
1185
- { "author" => "sam", "text" => "this is bad" }
1186
- ],
1187
- "other" => { "foo" => 5 }
1188
- } )
1189
-
1190
- @@test.save( {
1191
- "_id" => 2,
1192
- "title" => "this is your title",
1193
- "author" => "dave",
1194
- "posted" => Time.utc(2001),
1195
- "pageViews" => 7,
1196
- "tags" => [ "fun" , "nasty" ],
1197
- "comments" => [
1236
+ @test.save( {
1237
+ "_id" => 1,
1238
+ "title" => "this is my title",
1239
+ "author" => "bob",
1240
+ "posted" => Time.utc(2000),
1241
+ "pageViews" => 5 ,
1242
+ "tags" => [ "fun" , "good" , "fun" ],
1243
+ "comments" => [
1244
+ { "author" => "joe", "text" => "this is cool" },
1245
+ { "author" => "sam", "text" => "this is bad" }
1246
+ ],
1247
+ "other" => { "foo" => 5 }
1248
+ } )
1249
+
1250
+ @test.save( {
1251
+ "_id" => 2,
1252
+ "title" => "this is your title",
1253
+ "author" => "dave",
1254
+ "posted" => Time.utc(2001),
1255
+ "pageViews" => 7,
1256
+ "tags" => [ "fun" , "nasty" ],
1257
+ "comments" => [
1198
1258
  { "author" => "barbara" , "text" => "this is interesting" },
1199
1259
  { "author" => "jenny", "text" => "i like to play pinball", "votes" => 10 }
1200
- ],
1201
- "other" => { "bar" => 14 }
1202
- })
1260
+ ],
1261
+ "other" => { "bar" => 14 }
1262
+ })
1203
1263
 
1204
- @@test.save( {
1205
- "_id" => 3,
1206
- "title" => "this is some other title",
1207
- "author" => "jane",
1208
- "posted" => Time.utc(2002),
1209
- "pageViews" => 6 ,
1210
- "tags" => [ "nasty", "filthy" ],
1211
- "comments" => [
1212
- { "author" => "will" , "text" => "i don't like the color" } ,
1213
- { "author" => "jenny" , "text" => "can i get that in green?" }
1214
- ],
1215
- "other" => { "bar" => 14 }
1216
- })
1264
+ @test.save( {
1265
+ "_id" => 3,
1266
+ "title" => "this is some other title",
1267
+ "author" => "jane",
1268
+ "posted" => Time.utc(2002),
1269
+ "pageViews" => 6 ,
1270
+ "tags" => [ "nasty", "filthy" ],
1271
+ "comments" => [
1272
+ { "author" => "will" , "text" => "i don't like the color" } ,
1273
+ { "author" => "jenny" , "text" => "can i get that in green?" }
1274
+ ],
1275
+ "other" => { "bar" => 14 }
1276
+ })
1217
1277
 
1218
1278
  end
1219
1279
 
1220
- if @@version > '2.1.1'
1221
- def test_reponds_to_aggregate
1222
- assert_respond_to @@test, :aggregate
1223
- end
1224
-
1225
- def test_aggregate_requires_arguments
1226
- assert_raise MongoArgumentError do
1227
- @@test.aggregate()
1228
- end
1229
- end
1230
-
1231
- def test_aggregate_requires_valid_arguments
1232
- assert_raise MongoArgumentError do
1233
- @@test.aggregate({})
1234
- end
1235
- end
1236
-
1237
- def test_aggregate_pipeline_operator_format
1238
- assert_raise Mongo::OperationFailure do
1239
- @@test.aggregate([{"$project" => "_id"}])
1240
- end
1241
- end
1242
-
1243
- def test_aggregate_pipeline_operators_using_strings
1244
- setup_aggregate_data
1245
- desired_results = [ {"_id"=>1, "pageViews"=>5, "tags"=>["fun", "good", "fun"]},
1246
- {"_id"=>2, "pageViews"=>7, "tags"=>["fun", "nasty"]},
1247
- {"_id"=>3, "pageViews"=>6, "tags"=>["nasty", "filthy"]} ]
1248
- results = @@test.aggregate([{"$project" => {"tags" => 1, "pageViews" => 1}}])
1249
- assert_equal desired_results, results
1250
- end
1251
-
1252
- def test_aggregate_pipeline_operators_using_symbols
1253
- setup_aggregate_data
1254
- desired_results = [ {"_id"=>1, "pageViews"=>5, "tags"=>["fun", "good", "fun"]},
1255
- {"_id"=>2, "pageViews"=>7, "tags"=>["fun", "nasty"]},
1256
- {"_id"=>3, "pageViews"=>6, "tags"=>["nasty", "filthy"]} ]
1257
- results = @@test.aggregate([{"$project" => {:tags => 1, :pageViews => 1}}])
1258
- assert_equal desired_results, results
1259
- end
1260
-
1261
- def test_aggregate_pipeline_multiple_operators
1262
- setup_aggregate_data
1263
- results = @@test.aggregate([{"$project" => {"tags" => 1, "pageViews" => 1}}, {"$match" => {"pageViews" => 7}}])
1264
- assert_equal 1, results.length
1265
- end
1266
-
1267
- def test_aggregate_pipeline_unwind
1268
- setup_aggregate_data
1269
- desired_results = [ {"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
1270
- "pageViews"=>5, "tags"=>"fun", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
1271
- {"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
1272
- {"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
1273
- "pageViews"=>5, "tags"=>"good", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
1274
- {"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
1275
- {"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
1276
- "pageViews"=>5, "tags"=>"fun", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
1277
- {"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
1278
- {"_id"=>2, "title"=>"this is your title", "author"=>"dave", "posted"=>Time.utc(2001),
1279
- "pageViews"=>7, "tags"=>"fun", "comments"=>[{"author"=>"barbara", "text"=>"this is interesting"},
1280
- {"author"=>"jenny", "text"=>"i like to play pinball", "votes"=>10 }], "other"=>{"bar"=>14 } },
1281
- {"_id"=>2, "title"=>"this is your title", "author"=>"dave", "posted"=>Time.utc(2001),
1282
- "pageViews"=>7, "tags"=>"nasty", "comments"=>[{"author"=>"barbara", "text"=>"this is interesting"},
1283
- {"author"=>"jenny", "text"=>"i like to play pinball", "votes"=>10 }], "other"=>{"bar"=>14 } },
1284
- {"_id"=>3, "title"=>"this is some other title", "author"=>"jane", "posted"=>Time.utc(2002),
1285
- "pageViews"=>6, "tags"=>"nasty", "comments"=>[{"author"=>"will", "text"=>"i don't like the color"},
1286
- {"author"=>"jenny", "text"=>"can i get that in green?"}], "other"=>{"bar"=>14 } },
1287
- {"_id"=>3, "title"=>"this is some other title", "author"=>"jane", "posted"=>Time.utc(2002),
1288
- "pageViews"=>6, "tags"=>"filthy", "comments"=>[{"author"=>"will", "text"=>"i don't like the color"},
1289
- {"author"=>"jenny", "text"=>"can i get that in green?"}], "other"=>{"bar"=>14 } }
1290
- ]
1291
- results = @@test.aggregate([{"$unwind"=> "$tags"}])
1292
- assert_equal desired_results, results
1293
- end
1294
-
1295
- def test_aggregate_with_compile_regex_option
1296
- # see SERVER-6470
1297
- return unless @@version >= '2.3.2'
1298
- @@test.insert({ 'r' => /.*/ })
1299
- result1 = @@test.aggregate([])
1300
- assert_kind_of Regexp, result1.first['r']
1301
-
1302
- result2 = @@test.aggregate([], :compile_regex => false)
1303
- assert_kind_of BSON::Regex, result2.first['r']
1304
-
1305
- return unless @@version >= '2.5.1'
1306
- result = @@test.aggregate([], :compile_regex => false, :cursor => {})
1307
- assert_kind_of BSON::Regex, result.first['r']
1308
- end
1309
- end
1310
-
1311
- if @@version >= "2.5.2"
1312
- def test_out_aggregate
1313
- out_collection = 'test_out'
1314
- @@db.drop_collection(out_collection)
1315
- setup_aggregate_data
1316
- docs = @@test.find.to_a
1317
- pipeline = [{:$out => out_collection}]
1318
- @@test.aggregate(pipeline)
1319
- assert_equal docs, @@db.collection(out_collection).find.to_a
1320
- end
1321
-
1322
- def test_out_aggregate_nonprimary_sym_warns
1323
- ReadPreference::expects(:warn).with(regexp_matches(/rerouted to primary/))
1324
- pipeline = [{:$out => 'test_out'}]
1325
- @@test.aggregate(pipeline, :read => :secondary)
1326
- end
1327
-
1328
- def test_out_aggregate_nonprimary_string_warns
1329
- ReadPreference::expects(:warn).with(regexp_matches(/rerouted to primary/))
1330
- pipeline = [{'$out' => 'test_out'}]
1331
- @@test.aggregate(pipeline, :read => :secondary)
1332
- end
1333
-
1334
- def test_out_aggregate_string_returns_raw_response
1335
- pipeline = [{'$out' => 'test_out'}]
1336
- response = @@test.aggregate(pipeline)
1337
- assert response.respond_to?(:keys)
1338
- end
1339
-
1340
- def test_out_aggregate_sym_returns_raw_response
1341
- pipeline = [{:$out => 'test_out'}]
1342
- response = @@test.aggregate(pipeline)
1343
- assert response.respond_to?(:keys)
1344
- end
1345
- end
1346
-
1347
- if @@version > "1.1.1"
1348
- def test_map_reduce
1349
- @@test << { "user_id" => 1 }
1350
- @@test << { "user_id" => 2 }
1351
-
1352
- m = "function() { emit(this.user_id, 1); }"
1353
- r = "function(k,vals) { return 1; }"
1354
- res = @@test.map_reduce(m, r, :out => 'foo')
1355
- assert res.find_one({"_id" => 1})
1356
- assert res.find_one({"_id" => 2})
1357
- end
1358
-
1359
- def test_map_reduce_with_code_objects
1360
- @@test << { "user_id" => 1 }
1361
- @@test << { "user_id" => 2 }
1362
-
1363
- m = Code.new("function() { emit(this.user_id, 1); }")
1364
- r = Code.new("function(k,vals) { return 1; }")
1365
- res = @@test.map_reduce(m, r, :out => 'foo')
1366
- assert res.find_one({"_id" => 1})
1367
- assert res.find_one({"_id" => 2})
1368
- end
1369
-
1370
- def test_map_reduce_with_options
1371
- @@test.remove
1372
- @@test << { "user_id" => 1 }
1373
- @@test << { "user_id" => 2 }
1374
- @@test << { "user_id" => 3 }
1375
-
1376
- m = Code.new("function() { emit(this.user_id, 1); }")
1377
- r = Code.new("function(k,vals) { return 1; }")
1378
- res = @@test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}}, :out => 'foo')
1379
- assert_equal 2, res.count
1380
- assert res.find_one({"_id" => 2})
1381
- assert res.find_one({"_id" => 3})
1382
- end
1383
-
1384
- def test_map_reduce_with_raw_response
1385
- m = Code.new("function() { emit(this.user_id, 1); }")
1386
- r = Code.new("function(k,vals) { return 1; }")
1387
- res = @@test.map_reduce(m, r, :raw => true, :out => 'foo')
1388
- assert res["result"]
1389
- assert res["counts"]
1390
- assert res["timeMillis"]
1391
- end
1392
-
1393
- def test_map_reduce_with_output_collection
1394
- output_collection = "test-map-coll"
1395
- m = Code.new("function() { emit(this.user_id, 1); }")
1396
- r = Code.new("function(k,vals) { return 1; }")
1397
- res = @@test.map_reduce(m, r, :raw => true, :out => output_collection)
1398
- assert_equal output_collection, res["result"]
1399
- assert res["counts"]
1400
- assert res["timeMillis"]
1401
- end
1280
+ def test_reponds_to_aggregate
1281
+ return unless @version > '2.1.1'
1282
+ assert_respond_to @test, :aggregate
1283
+ end
1402
1284
 
1403
- def test_map_reduce_nonprimary_output_collection_reroutes
1404
- output_collection = "test-map-coll"
1405
- m = Code.new("function() { emit(this.user_id, 1); }")
1406
- r = Code.new("function(k,vals) { return 1; }")
1407
- Mongo::ReadPreference.expects(:warn).with(regexp_matches(/rerouted to primary/))
1408
- res = @@test.map_reduce(m, r, :raw => true, :out => output_collection, :read => :secondary)
1285
+ def test_aggregate_requires_arguments
1286
+ return unless @version > '2.1.1'
1287
+ assert_raise MongoArgumentError do
1288
+ @test.aggregate()
1409
1289
  end
1290
+ end
1410
1291
 
1411
- if @@version >= "1.8.0"
1412
- def test_map_reduce_with_collection_merge
1413
- @@test << {:user_id => 1}
1414
- @@test << {:user_id => 2}
1415
- output_collection = "test-map-coll"
1416
- m = Code.new("function() { emit(this.user_id, {count: 1}); }")
1417
- r = Code.new("function(k,vals) { var sum = 0;" +
1418
- " vals.forEach(function(v) { sum += v.count;} ); return {count: sum}; }")
1419
- res = @@test.map_reduce(m, r, :out => output_collection)
1420
-
1421
- @@test.remove
1422
- @@test << {:user_id => 3}
1423
- res = @@test.map_reduce(m, r, :out => {:merge => output_collection})
1424
- assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 1}
1425
-
1426
- @@test.remove
1427
- @@test << {:user_id => 3}
1428
- res = @@test.map_reduce(m, r, :out => {:reduce => output_collection})
1429
- assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 2}
1430
-
1431
- assert_raise ArgumentError do
1432
- @@test.map_reduce(m, r, :out => {:inline => 1})
1433
- end
1434
-
1435
- @@test.map_reduce(m, r, :raw => true, :out => {:inline => 1})
1436
- assert res["results"]
1437
- end
1438
-
1439
- def test_map_reduce_with_collection_output_to_other_db
1440
- @@test << {:user_id => 1}
1441
- @@test << {:user_id => 2}
1442
-
1443
- m = Code.new("function() { emit(this.user_id, 1); }")
1444
- r = Code.new("function(k,vals) { return 1; }")
1445
- oh = BSON::OrderedHash.new
1446
- oh[:replace] = 'foo'
1447
- oh[:db] = TEST_DB
1448
- res = @@test.map_reduce(m, r, :out => (oh))
1449
- assert res["result"]
1450
- assert res["counts"]
1451
- assert res["timeMillis"]
1452
- assert res.find.to_a.any? {|doc| doc["_id"] == 2 && doc["value"] == 1}
1453
- end
1292
+ def test_aggregate_requires_valid_arguments
1293
+ return unless @version > '2.1.1'
1294
+ assert_raise MongoArgumentError do
1295
+ @test.aggregate({})
1454
1296
  end
1455
1297
  end
1456
1298
 
1457
- if @@version >= '2.5.5'
1458
- def test_aggregation_allow_disk_use
1459
- @@db.expects(:command).with do |selector, opts|
1460
- opts[:allowDiskUse] == true
1461
- end.returns({ 'ok' => 1 })
1462
- @@test.aggregate([], :allowDiskUse => true)
1463
- end
1299
+ def test_aggregate_pipeline_operator_format
1300
+ return unless @version > '2.1.1'
1301
+ assert_raise Mongo::OperationFailure do
1302
+ @test.aggregate([{"$project" => "_id"}])
1303
+ end
1304
+ end
1305
+
1306
+ def test_aggregate_pipeline_operators_using_strings
1307
+ return unless @version > '2.1.1'
1308
+ setup_aggregate_data
1309
+ desired_results = [ {"_id"=>1, "pageViews"=>5, "tags"=>["fun", "good", "fun"]},
1310
+ {"_id"=>2, "pageViews"=>7, "tags"=>["fun", "nasty"]},
1311
+ {"_id"=>3, "pageViews"=>6, "tags"=>["nasty", "filthy"]} ]
1312
+ results = @test.aggregate([{"$project" => {"tags" => 1, "pageViews" => 1}}])
1313
+ assert_equal desired_results, results
1314
+ end
1315
+
1316
+ def test_aggregate_pipeline_operators_using_symbols
1317
+ return unless @version > '2.1.1'
1318
+ setup_aggregate_data
1319
+ desired_results = [ {"_id"=>1, "pageViews"=>5, "tags"=>["fun", "good", "fun"]},
1320
+ {"_id"=>2, "pageViews"=>7, "tags"=>["fun", "nasty"]},
1321
+ {"_id"=>3, "pageViews"=>6, "tags"=>["nasty", "filthy"]} ]
1322
+ results = @test.aggregate([{"$project" => {:tags => 1, :pageViews => 1}}])
1323
+ assert_equal desired_results, results
1324
+ end
1325
+
1326
+ def test_aggregate_pipeline_multiple_operators
1327
+ return unless @version > '2.1.1'
1328
+ setup_aggregate_data
1329
+ results = @test.aggregate([{"$project" => {"tags" => 1, "pageViews" => 1}}, {"$match" => {"pageViews" => 7}}])
1330
+ assert_equal 1, results.length
1331
+ end
1332
+
1333
+ def test_aggregate_pipeline_unwind
1334
+ return unless @version > '2.1.1'
1335
+ setup_aggregate_data
1336
+ desired_results = [ {"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
1337
+ "pageViews"=>5, "tags"=>"fun", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
1338
+ {"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
1339
+ {"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
1340
+ "pageViews"=>5, "tags"=>"good", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
1341
+ {"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
1342
+ {"_id"=>1, "title"=>"this is my title", "author"=>"bob", "posted"=>Time.utc(2000),
1343
+ "pageViews"=>5, "tags"=>"fun", "comments"=>[{"author"=>"joe", "text"=>"this is cool"},
1344
+ {"author"=>"sam", "text"=>"this is bad"}], "other"=>{"foo"=>5 } },
1345
+ {"_id"=>2, "title"=>"this is your title", "author"=>"dave", "posted"=>Time.utc(2001),
1346
+ "pageViews"=>7, "tags"=>"fun", "comments"=>[{"author"=>"barbara", "text"=>"this is interesting"},
1347
+ {"author"=>"jenny", "text"=>"i like to play pinball", "votes"=>10 }], "other"=>{"bar"=>14 } },
1348
+ {"_id"=>2, "title"=>"this is your title", "author"=>"dave", "posted"=>Time.utc(2001),
1349
+ "pageViews"=>7, "tags"=>"nasty", "comments"=>[{"author"=>"barbara", "text"=>"this is interesting"},
1350
+ {"author"=>"jenny", "text"=>"i like to play pinball", "votes"=>10 }], "other"=>{"bar"=>14 } },
1351
+ {"_id"=>3, "title"=>"this is some other title", "author"=>"jane", "posted"=>Time.utc(2002),
1352
+ "pageViews"=>6, "tags"=>"nasty", "comments"=>[{"author"=>"will", "text"=>"i don't like the color"},
1353
+ {"author"=>"jenny", "text"=>"can i get that in green?"}], "other"=>{"bar"=>14 } },
1354
+ {"_id"=>3, "title"=>"this is some other title", "author"=>"jane", "posted"=>Time.utc(2002),
1355
+ "pageViews"=>6, "tags"=>"filthy", "comments"=>[{"author"=>"will", "text"=>"i don't like the color"},
1356
+ {"author"=>"jenny", "text"=>"can i get that in green?"}], "other"=>{"bar"=>14 } }
1357
+ ]
1358
+ results = @test.aggregate([{"$unwind"=> "$tags"}])
1359
+ assert_equal desired_results, results
1360
+ end
1361
+
1362
+ def test_aggregate_with_compile_regex_option
1363
+ return unless @version > '2.1.1'
1364
+ # see SERVER-6470
1365
+ return unless @version >= '2.3.2'
1366
+ @test.insert({ 'r' => /.*/ })
1367
+ result1 = @test.aggregate([])
1368
+ assert_kind_of Regexp, result1.first['r']
1369
+
1370
+ result2 = @test.aggregate([], :compile_regex => false)
1371
+ assert_kind_of BSON::Regex, result2.first['r']
1372
+
1373
+ return unless @version >= '2.5.1'
1374
+ result = @test.aggregate([], :compile_regex => false, :cursor => {})
1375
+ assert_kind_of BSON::Regex, result.first['r']
1376
+ end
1377
+
1378
+ def test_out_aggregate
1379
+ return unless @version >= "2.5.2"
1380
+ out_collection = 'test_out'
1381
+ @db.drop_collection(out_collection)
1382
+ setup_aggregate_data
1383
+ docs = @test.find.to_a
1384
+ pipeline = [{:$out => out_collection}]
1385
+ @test.aggregate(pipeline)
1386
+ assert_equal docs, @db.collection(out_collection).find.to_a
1387
+ end
1388
+
1389
+ def test_out_aggregate_nonprimary_sym_warns
1390
+ return unless @version >= "2.5.2"
1391
+ ReadPreference::expects(:warn).with(regexp_matches(/rerouted to primary/))
1392
+ pipeline = [{:$out => 'test_out'}]
1393
+ @test.aggregate(pipeline, :read => :secondary)
1394
+ end
1395
+
1396
+ def test_out_aggregate_nonprimary_string_warns
1397
+ return unless @version >= "2.5.2"
1398
+ ReadPreference::expects(:warn).with(regexp_matches(/rerouted to primary/))
1399
+ pipeline = [{'$out' => 'test_out'}]
1400
+ @test.aggregate(pipeline, :read => :secondary)
1401
+ end
1402
+
1403
+ def test_out_aggregate_string_returns_raw_response
1404
+ return unless @version >= "2.5.2"
1405
+ pipeline = [{'$out' => 'test_out'}]
1406
+ response = @test.aggregate(pipeline)
1407
+ assert response.respond_to?(:keys)
1408
+ end
1409
+
1410
+ def test_out_aggregate_sym_returns_raw_response
1411
+ return unless @version >= "2.5.2"
1412
+ pipeline = [{:$out => 'test_out'}]
1413
+ response = @test.aggregate(pipeline)
1414
+ assert response.respond_to?(:keys)
1415
+ end
1416
+
1417
+ def test_map_reduce
1418
+ return unless @version > "1.1.1"
1419
+ @test << { "user_id" => 1 }
1420
+ @test << { "user_id" => 2 }
1421
+
1422
+ m = "function() { emit(this.user_id, 1); }"
1423
+ r = "function(k,vals) { return 1; }"
1424
+ res = @test.map_reduce(m, r, :out => 'foo')
1425
+ assert res.find_one({"_id" => 1})
1426
+ assert res.find_one({"_id" => 2})
1427
+ end
1428
+
1429
+ def test_map_reduce_with_code_objects
1430
+ return unless @version > "1.1.1"
1431
+ @test << { "user_id" => 1 }
1432
+ @test << { "user_id" => 2 }
1433
+
1434
+ m = Code.new("function() { emit(this.user_id, 1); }")
1435
+ r = Code.new("function(k,vals) { return 1; }")
1436
+ res = @test.map_reduce(m, r, :out => 'foo')
1437
+ assert res.find_one({"_id" => 1})
1438
+ assert res.find_one({"_id" => 2})
1439
+ end
1440
+
1441
+ def test_map_reduce_with_options
1442
+ return unless @version > "1.1.1"
1443
+ @test.remove
1444
+ @test << { "user_id" => 1 }
1445
+ @test << { "user_id" => 2 }
1446
+ @test << { "user_id" => 3 }
1447
+
1448
+ m = Code.new("function() { emit(this.user_id, 1); }")
1449
+ r = Code.new("function(k,vals) { return 1; }")
1450
+ res = @test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}}, :out => 'foo')
1451
+ assert_equal 2, res.count
1452
+ assert res.find_one({"_id" => 2})
1453
+ assert res.find_one({"_id" => 3})
1454
+ end
1455
+
1456
+ def test_map_reduce_with_raw_response
1457
+ return unless @version > "1.1.1"
1458
+ m = Code.new("function() { emit(this.user_id, 1); }")
1459
+ r = Code.new("function(k,vals) { return 1; }")
1460
+ res = @test.map_reduce(m, r, :raw => true, :out => 'foo')
1461
+ assert res["result"]
1462
+ assert res["counts"]
1463
+ assert res["timeMillis"]
1464
+ end
1465
+
1466
+ def test_map_reduce_with_output_collection
1467
+ return unless @version > "1.1.1"
1468
+ output_collection = "test-map-coll"
1469
+ m = Code.new("function() { emit(this.user_id, 1); }")
1470
+ r = Code.new("function(k,vals) { return 1; }")
1471
+ res = @test.map_reduce(m, r, :raw => true, :out => output_collection)
1472
+ assert_equal output_collection, res["result"]
1473
+ assert res["counts"]
1474
+ assert res["timeMillis"]
1475
+ end
1476
+
1477
+ def test_map_reduce_nonprimary_output_collection_reroutes
1478
+ return unless @version > "1.1.1"
1479
+ output_collection = "test-map-coll"
1480
+ m = Code.new("function() { emit(this.user_id, 1); }")
1481
+ r = Code.new("function(k,vals) { return 1; }")
1482
+ Mongo::ReadPreference.expects(:warn).with(regexp_matches(/rerouted to primary/))
1483
+ res = @test.map_reduce(m, r, :raw => true, :out => output_collection, :read => :secondary)
1484
+ end
1485
+
1486
+ def test_map_reduce_with_collection_merge
1487
+ return unless @version >= "1.8.0"
1488
+ @test << {:user_id => 1}
1489
+ @test << {:user_id => 2}
1490
+ output_collection = "test-map-coll"
1491
+ m = Code.new("function() { emit(this.user_id, {count: 1}); }")
1492
+ r = Code.new("function(k,vals) { var sum = 0;" +
1493
+ " vals.forEach(function(v) { sum += v.count;} ); return {count: sum}; }")
1494
+ res = @test.map_reduce(m, r, :out => output_collection)
1464
1495
 
1465
- def test_parallel_scan
1466
- 8000.times { |i| @@test.insert({ :_id => i }) }
1496
+ @test.remove
1497
+ @test << {:user_id => 3}
1498
+ res = @test.map_reduce(m, r, :out => {:merge => output_collection})
1499
+ assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 1}
1467
1500
 
1468
- lock = Mutex.new
1469
- doc_ids = Set.new
1470
- threads = []
1471
- cursors = @@test.parallel_scan(3)
1472
- cursors.each_with_index do |cursor, i|
1473
- threads << Thread.new do
1474
- docs = cursor.to_a
1475
- lock.synchronize do
1476
- docs.each do |doc|
1477
- doc_ids << doc['_id']
1478
- end
1501
+ @test.remove
1502
+ @test << {:user_id => 3}
1503
+ res = @test.map_reduce(m, r, :out => {:reduce => output_collection})
1504
+ assert res.find.to_a.any? {|doc| doc["_id"] == 3 && doc["value"]["count"] == 2}
1505
+
1506
+ assert_raise ArgumentError do
1507
+ @test.map_reduce(m, r, :out => {:inline => 1})
1508
+ end
1509
+
1510
+ @test.map_reduce(m, r, :raw => true, :out => {:inline => 1})
1511
+ assert res["results"]
1512
+ end
1513
+
1514
+ def test_map_reduce_with_collection_output_to_other_db
1515
+ return unless @version > "1.1.1"
1516
+ @test << {:user_id => 1}
1517
+ @test << {:user_id => 2}
1518
+
1519
+ m = Code.new("function() { emit(this.user_id, 1); }")
1520
+ r = Code.new("function(k,vals) { return 1; }")
1521
+ oh = BSON::OrderedHash.new
1522
+ oh[:replace] = 'foo'
1523
+ oh[:db] = TEST_DB
1524
+ res = @test.map_reduce(m, r, :out => (oh))
1525
+ assert res["result"]
1526
+ assert res["counts"]
1527
+ assert res["timeMillis"]
1528
+ assert res.find.to_a.any? {|doc| doc["_id"] == 2 && doc["value"] == 1}
1529
+ end
1530
+
1531
+ def test_aggregation_allow_disk_use
1532
+ return unless @version >= '2.5.5'
1533
+ @db.expects(:command).with do |selector, opts|
1534
+ opts[:allowDiskUse] == true
1535
+ end.returns({ 'ok' => 1 })
1536
+ @test.aggregate([], :allowDiskUse => true)
1537
+ end
1538
+
1539
+ def test_parallel_scan
1540
+ return unless @version >= '2.5.5'
1541
+ 8000.times { |i| @test.insert({ :_id => i }) }
1542
+
1543
+ lock = Mutex.new
1544
+ doc_ids = Set.new
1545
+ threads = []
1546
+ cursors = @test.parallel_scan(3)
1547
+ cursors.each_with_index do |cursor, i|
1548
+ threads << Thread.new do
1549
+ docs = cursor.to_a
1550
+ lock.synchronize do
1551
+ docs.each do |doc|
1552
+ doc_ids << doc['_id']
1479
1553
  end
1480
1554
  end
1481
1555
  end
1482
- threads.each(&:join)
1483
- assert_equal 8000, doc_ids.count
1484
1556
  end
1557
+ threads.each(&:join)
1558
+ assert_equal 8000, doc_ids.count
1485
1559
  end
1486
1560
 
1487
- if @@version > "1.3.0"
1488
- def test_find_and_modify
1489
- @@test << { :a => 1, :processed => false }
1490
- @@test << { :a => 2, :processed => false }
1491
- @@test << { :a => 3, :processed => false }
1561
+ def test_find_and_modify
1562
+ return unless @version > "1.3.0"
1563
+ @test << { :a => 1, :processed => false }
1564
+ @test << { :a => 2, :processed => false }
1565
+ @test << { :a => 3, :processed => false }
1492
1566
 
1493
- @@test.find_and_modify(:query => {},
1494
- :sort => [['a', -1]],
1495
- :update => {"$set" => {:processed => true}})
1567
+ @test.find_and_modify(:query => {},
1568
+ :sort => [['a', -1]],
1569
+ :update => {"$set" => {:processed => true}})
1496
1570
 
1497
- assert @@test.find_one({:a => 3})['processed']
1498
- end
1571
+ assert @test.find_one({:a => 3})['processed']
1572
+ end
1499
1573
 
1500
- def test_find_and_modify_with_invalid_options
1501
- @@test << { :a => 1, :processed => false }
1502
- @@test << { :a => 2, :processed => false }
1503
- @@test << { :a => 3, :processed => false }
1574
+ def test_find_and_modify_with_invalid_options
1575
+ @test << { :a => 1, :processed => false }
1576
+ @test << { :a => 2, :processed => false }
1577
+ @test << { :a => 3, :processed => false }
1504
1578
 
1505
- assert_raise Mongo::OperationFailure do
1506
- @@test.find_and_modify(:blimey => {})
1507
- end
1579
+ assert_raise Mongo::OperationFailure do
1580
+ @test.find_and_modify(:blimey => {})
1508
1581
  end
1582
+ end
1509
1583
 
1510
- def test_find_and_modify_with_full_response
1511
- @@test << { :a => 1, :processed => false }
1512
- @@test << { :a => 2, :processed => false }
1513
- @@test << { :a => 3, :processed => false }
1584
+ def test_find_and_modify_with_full_response
1585
+ @test << { :a => 1, :processed => false }
1586
+ @test << { :a => 2, :processed => false }
1587
+ @test << { :a => 3, :processed => false }
1514
1588
 
1515
- doc = @@test.find_and_modify(:query => {},
1516
- :sort => [['a', -1]],
1517
- :update => {"$set" => {:processed => true}},
1518
- :full_response => true,
1519
- :new => true)
1589
+ doc = @test.find_and_modify(:query => {},
1590
+ :sort => [['a', -1]],
1591
+ :update => {"$set" => {:processed => true}},
1592
+ :full_response => true,
1593
+ :new => true)
1520
1594
 
1521
- assert doc['value']['processed']
1522
- assert ['ok', 'value', 'lastErrorObject'].all? { |key| doc.key?(key) }
1523
- end
1595
+ assert doc['value']['processed']
1596
+ assert ['ok', 'value', 'lastErrorObject'].all? { |key| doc.key?(key) }
1524
1597
  end
1525
1598
 
1526
- if @@version >= "1.3.5"
1527
- def test_coll_stats
1528
- @@test << {:n => 1}
1529
- @@test.create_index("n")
1599
+ def test_coll_stats
1600
+ return unless @version >= "1.3.5"
1601
+ @test << {:n => 1}
1602
+ @test.create_index("n")
1530
1603
 
1531
- assert_equal "#{TEST_DB}.test", @@test.stats['ns']
1532
- @@test.drop
1533
- end
1604
+ assert_equal "#{TEST_DB}.test", @test.stats['ns']
1605
+ @test.drop
1534
1606
  end
1535
1607
 
1536
1608
  def test_saving_dates_pre_epoch
1537
1609
  if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ then return true end
1538
1610
  begin
1539
- @@test.save({'date' => Time.utc(1600)})
1540
- assert_in_delta Time.utc(1600), @@test.find_one()["date"], 2
1611
+ @test.save({'date' => Time.utc(1600)})
1612
+ assert_in_delta Time.utc(1600), @test.find_one()["date"], 2
1541
1613
  rescue ArgumentError
1542
1614
  # See note in test_date_before_epoch (BSONTest)
1543
1615
  end
1544
1616
  end
1545
1617
 
1546
1618
  def test_save_symbol_find_string
1547
- @@test.save(:foo => :mike)
1619
+ @test.save(:foo => :mike)
1548
1620
 
1549
- assert_equal :mike, @@test.find_one(:foo => :mike)["foo"]
1550
- assert_equal :mike, @@test.find_one("foo" => :mike)["foo"]
1621
+ assert_equal :mike, @test.find_one(:foo => :mike)["foo"]
1622
+ assert_equal :mike, @test.find_one("foo" => :mike)["foo"]
1551
1623
 
1552
1624
  # TODO enable these tests conditionally based on server version (if >1.0)
1553
- # assert_equal :mike, @@test.find_one(:foo => "mike")["foo"]
1554
- # assert_equal :mike, @@test.find_one("foo" => "mike")["foo"]
1625
+ # assert_equal :mike, @test.find_one(:foo => "mike")["foo"]
1626
+ # assert_equal :mike, @test.find_one("foo" => "mike")["foo"]
1555
1627
  end
1556
1628
 
1557
1629
  def test_batch_size
1558
1630
  n_docs = 6
1559
1631
  batch_size = n_docs/2
1560
1632
  n_docs.times do |i|
1561
- @@test.save(:foo => i)
1633
+ @test.save(:foo => i)
1562
1634
  end
1563
1635
 
1564
1636
  doc_count = 0
1565
- cursor = @@test.find({}, :batch_size => batch_size)
1637
+ cursor = @test.find({}, :batch_size => batch_size)
1566
1638
  cursor.next
1567
1639
  assert_equal batch_size, cursor.instance_variable_get(:@returned)
1568
1640
  doc_count += batch_size
@@ -1576,10 +1648,10 @@ class CollectionTest < Test::Unit::TestCase
1576
1648
  n_docs = 6
1577
1649
  batch_size = n_docs/2
1578
1650
  n_docs.times do |i|
1579
- @@test.insert(:foo => i)
1651
+ @test.insert(:foo => i)
1580
1652
  end
1581
1653
 
1582
- cursor = @@test.find({}, :batch_size => batch_size, :limit => 2)
1654
+ cursor = @test.find({}, :batch_size => batch_size, :limit => 2)
1583
1655
  cursor.next
1584
1656
  assert_equal 2, cursor.instance_variable_get(:@returned)
1585
1657
  end
@@ -1588,11 +1660,11 @@ class CollectionTest < Test::Unit::TestCase
1588
1660
  n_docs = 6
1589
1661
  batch_size = n_docs/2
1590
1662
  n_docs.times do |i|
1591
- @@test.insert(:foo => i)
1663
+ @test.insert(:foo => i)
1592
1664
  end
1593
1665
 
1594
1666
  doc_count = 0
1595
- cursor = @@test.find({}, :batch_size => batch_size, :limit => n_docs + 5)
1667
+ cursor = @test.find({}, :batch_size => batch_size, :limit => n_docs + 5)
1596
1668
  cursor.next
1597
1669
  assert_equal batch_size, cursor.instance_variable_get(:@returned)
1598
1670
  doc_count += batch_size
@@ -1600,44 +1672,44 @@ class CollectionTest < Test::Unit::TestCase
1600
1672
  assert_equal doc_count + batch_size, cursor.instance_variable_get(:@returned)
1601
1673
  doc_count += batch_size
1602
1674
  assert_equal n_docs, doc_count
1603
- end
1675
+ end
1604
1676
 
1605
1677
  def test_batch_size_with_negative_limit
1606
1678
  n_docs = 6
1607
1679
  batch_size = n_docs/2
1608
1680
  n_docs.times do |i|
1609
- @@test.insert(:foo => i)
1681
+ @test.insert(:foo => i)
1610
1682
  end
1611
1683
 
1612
- cursor = @@test.find({}, :batch_size => batch_size, :limit => -7)
1684
+ cursor = @test.find({}, :batch_size => batch_size, :limit => -7)
1613
1685
  cursor.next
1614
1686
  assert_equal n_docs, cursor.instance_variable_get(:@returned)
1615
1687
  end
1616
1688
 
1617
1689
  def test_limit_and_skip
1618
1690
  10.times do |i|
1619
- @@test.save(:foo => i)
1691
+ @test.save(:foo => i)
1620
1692
  end
1621
1693
 
1622
- assert_equal 5, @@test.find({}, :skip => 5).next_document()["foo"]
1623
- assert_equal nil, @@test.find({}, :skip => 10).next_document()
1694
+ assert_equal 5, @test.find({}, :skip => 5).next_document()["foo"]
1695
+ assert_equal nil, @test.find({}, :skip => 10).next_document()
1624
1696
 
1625
- assert_equal 5, @@test.find({}, :limit => 5).to_a.length
1697
+ assert_equal 5, @test.find({}, :limit => 5).to_a.length
1626
1698
 
1627
- assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_document()["foo"]
1628
- assert_equal 5, @@test.find({}, :skip => 3, :limit => 5).to_a.length
1699
+ assert_equal 3, @test.find({}, :skip => 3, :limit => 5).next_document()["foo"]
1700
+ assert_equal 5, @test.find({}, :skip => 3, :limit => 5).to_a.length
1629
1701
  end
1630
1702
 
1631
1703
  def test_large_limit
1632
1704
  2000.times do |i|
1633
- @@test.insert("x" => i, "y" => "mongomongo" * 1000)
1705
+ @test.insert("x" => i, "y" => "mongomongo" * 1000)
1634
1706
  end
1635
1707
 
1636
- assert_equal 2000, @@test.count
1708
+ assert_equal 2000, @test.count
1637
1709
 
1638
1710
  i = 0
1639
1711
  y = 0
1640
- @@test.find({}, :limit => 1900).each do |doc|
1712
+ @test.find({}, :limit => 1900).each do |doc|
1641
1713
  i += 1
1642
1714
  y += doc["x"]
1643
1715
  end
@@ -1647,13 +1719,13 @@ end
1647
1719
  end
1648
1720
 
1649
1721
  def test_small_limit
1650
- @@test.insert("x" => "hello world")
1651
- @@test.insert("x" => "goodbye world")
1722
+ @test.insert("x" => "hello world")
1723
+ @test.insert("x" => "goodbye world")
1652
1724
 
1653
- assert_equal 2, @@test.count
1725
+ assert_equal 2, @test.count
1654
1726
 
1655
1727
  x = 0
1656
- @@test.find({}, :limit => 1).each do |doc|
1728
+ @test.find({}, :limit => 1).each do |doc|
1657
1729
  x += 1
1658
1730
  assert_equal "hello world", doc["x"]
1659
1731
  end
@@ -1664,56 +1736,56 @@ end
1664
1736
  def test_find_with_transformer
1665
1737
  klass = Struct.new(:id, :a)
1666
1738
  transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
1667
- cursor = @@test.find({}, :transformer => transformer)
1739
+ cursor = @test.find({}, :transformer => transformer)
1668
1740
  assert_equal(transformer, cursor.transformer)
1669
1741
  end
1670
1742
 
1671
1743
  def test_find_one_with_transformer
1672
1744
  klass = Struct.new(:id, :a)
1673
1745
  transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
1674
- id = @@test.insert('a' => 1)
1675
- doc = @@test.find_one(id, :transformer => transformer)
1746
+ id = @test.insert('a' => 1)
1747
+ doc = @test.find_one(id, :transformer => transformer)
1676
1748
  assert_instance_of(klass, doc)
1677
1749
  end
1678
1750
 
1679
1751
  def test_ensure_index
1680
- @@test.drop_indexes
1681
- @@test.insert("x" => "hello world")
1682
- assert_equal 1, @@test.index_information.keys.count #default index
1752
+ @test.drop_indexes
1753
+ @test.insert("x" => "hello world")
1754
+ assert_equal 1, @test.index_information.keys.count #default index
1683
1755
 
1684
- @@test.ensure_index([["x", Mongo::DESCENDING]], {})
1685
- assert_equal 2, @@test.index_information.keys.count
1686
- assert @@test.index_information.keys.include?("x_-1")
1756
+ @test.ensure_index([["x", Mongo::DESCENDING]], {})
1757
+ assert_equal 2, @test.index_information.keys.count
1758
+ assert @test.index_information.keys.include?("x_-1")
1687
1759
 
1688
- @@test.ensure_index([["x", Mongo::ASCENDING]])
1689
- assert @@test.index_information.keys.include?("x_1")
1760
+ @test.ensure_index([["x", Mongo::ASCENDING]])
1761
+ assert @test.index_information.keys.include?("x_1")
1690
1762
 
1691
- @@test.ensure_index([["type", 1], ["date", -1]])
1692
- assert @@test.index_information.keys.include?("type_1_date_-1")
1763
+ @test.ensure_index([["type", 1], ["date", -1]])
1764
+ assert @test.index_information.keys.include?("type_1_date_-1")
1693
1765
 
1694
- @@test.drop_index("x_1")
1695
- assert_equal 3, @@test.index_information.keys.count
1696
- @@test.drop_index("x_-1")
1697
- assert_equal 2, @@test.index_information.keys.count
1766
+ @test.drop_index("x_1")
1767
+ assert_equal 3, @test.index_information.keys.count
1768
+ @test.drop_index("x_-1")
1769
+ assert_equal 2, @test.index_information.keys.count
1698
1770
 
1699
- @@test.ensure_index([["x", Mongo::DESCENDING]], {})
1700
- assert_equal 3, @@test.index_information.keys.count
1701
- assert @@test.index_information.keys.include?("x_-1")
1771
+ @test.ensure_index([["x", Mongo::DESCENDING]], {})
1772
+ assert_equal 3, @test.index_information.keys.count
1773
+ assert @test.index_information.keys.include?("x_-1")
1702
1774
 
1703
1775
  # Make sure that drop_index expires cache properly
1704
- @@test.ensure_index([['a', 1]])
1705
- assert @@test.index_information.keys.include?("a_1")
1706
- @@test.drop_index("a_1")
1707
- assert !@@test.index_information.keys.include?("a_1")
1708
- @@test.ensure_index([['a', 1]])
1709
- assert @@test.index_information.keys.include?("a_1")
1710
- @@test.drop_index("a_1")
1711
- @@test.drop_indexes
1776
+ @test.ensure_index([['a', 1]])
1777
+ assert @test.index_information.keys.include?("a_1")
1778
+ @test.drop_index("a_1")
1779
+ assert !@test.index_information.keys.include?("a_1")
1780
+ @test.ensure_index([['a', 1]])
1781
+ assert @test.index_information.keys.include?("a_1")
1782
+ @test.drop_index("a_1")
1783
+ @test.drop_indexes
1712
1784
  end
1713
1785
 
1714
1786
  def test_ensure_index_timeout
1715
- @@db.cache_time = 1
1716
- coll = @@db['ensure_test']
1787
+ @db.cache_time = 1
1788
+ coll = @db['ensure_test']
1717
1789
  coll.expects(:generate_indexes).twice
1718
1790
  coll.ensure_index([['a', 1]])
1719
1791
 
@@ -1729,101 +1801,101 @@ end
1729
1801
  coll.drop
1730
1802
  end
1731
1803
 
1732
- if @@version > '2.0.0'
1733
- def test_show_disk_loc
1734
- @@test.save({:a => 1})
1735
- @@test.save({:a => 2})
1736
- assert @@test.find({:a => 1}, :show_disk_loc => true).show_disk_loc
1737
- assert @@test.find({:a => 1}, :show_disk_loc => true).next['$diskLoc']
1738
- @@test.remove
1739
- end
1804
+ def test_show_disk_loc
1805
+ return unless @version > '2.0.0'
1806
+ @test.save({:a => 1})
1807
+ @test.save({:a => 2})
1808
+ assert @test.find({:a => 1}, :show_disk_loc => true).show_disk_loc
1809
+ assert @test.find({:a => 1}, :show_disk_loc => true).next['$diskLoc']
1810
+ @test.remove
1811
+ end
1740
1812
 
1741
- def test_max_scan
1742
- @@test.drop
1743
- n = 100
1744
- n.times do |i|
1745
- @@test.save({:_id => i, :x => i % 10})
1746
- end
1747
- assert_equal(n, @@test.find.to_a.size)
1748
- assert_equal(50, @@test.find({}, :max_scan => 50).to_a.size)
1749
- assert_equal(10, @@test.find({:x => 2}).to_a.size)
1750
- assert_equal(5, @@test.find({:x => 2}, :max_scan => 50).to_a.size)
1751
- @@test.ensure_index([[:x, 1]])
1752
- assert_equal(10, @@test.find({:x => 2}, :max_scan => n).to_a.size)
1753
- @@test.drop
1754
- end
1813
+ def test_max_scan
1814
+ return unless @version > '2.0.0'
1815
+ @test.drop
1816
+ n = 100
1817
+ n.times do |i|
1818
+ @test.save({:_id => i, :x => i % 10})
1819
+ end
1820
+ assert_equal(n, @test.find.to_a.size)
1821
+ assert_equal(50, @test.find({}, :max_scan => 50).to_a.size)
1822
+ assert_equal(10, @test.find({:x => 2}).to_a.size)
1823
+ assert_equal(5, @test.find({:x => 2}, :max_scan => 50).to_a.size)
1824
+ @test.ensure_index([[:x, 1]])
1825
+ assert_equal(10, @test.find({:x => 2}, :max_scan => n).to_a.size)
1826
+ @test.drop
1755
1827
  end
1756
1828
 
1757
1829
  context "Grouping" do
1758
1830
  setup do
1759
- @@test.remove
1760
- @@test.save("a" => 1)
1761
- @@test.save("b" => 1)
1831
+ @test.remove
1832
+ @test.save("a" => 1)
1833
+ @test.save("b" => 1)
1762
1834
  @initial = {"count" => 0}
1763
1835
  @reduce_function = "function (obj, prev) { prev.count += inc_value; }"
1764
1836
  end
1765
1837
 
1766
1838
  should "fail if missing required options" do
1767
1839
  assert_raise MongoArgumentError do
1768
- @@test.group(:initial => {})
1840
+ @test.group(:initial => {})
1769
1841
  end
1770
1842
 
1771
1843
  assert_raise MongoArgumentError do
1772
- @@test.group(:reduce => "foo")
1844
+ @test.group(:reduce => "foo")
1773
1845
  end
1774
1846
  end
1775
1847
 
1776
1848
  should "group results using eval form" do
1777
- assert_equal 1, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 0.5}))[0]["count"]
1778
- assert_equal 2, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}))[0]["count"]
1779
- assert_equal 4, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
1849
+ assert_equal 1, @test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 0.5}))[0]["count"]
1850
+ assert_equal 2, @test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}))[0]["count"]
1851
+ assert_equal 4, @test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
1780
1852
  end
1781
1853
 
1782
1854
  should "finalize grouped results" do
1783
1855
  @finalize = "function(doc) {doc.f = doc.count + 200; }"
1784
- assert_equal 202, @@test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}), :finalize => @finalize)[0]["f"]
1856
+ assert_equal 202, @test.group(:initial => @initial, :reduce => Code.new(@reduce_function, {"inc_value" => 1}), :finalize => @finalize)[0]["f"]
1785
1857
  end
1786
1858
  end
1787
1859
 
1788
1860
  context "Grouping with key" do
1789
1861
  setup do
1790
- @@test.remove
1791
- @@test.save("a" => 1, "pop" => 100)
1792
- @@test.save("a" => 1, "pop" => 100)
1793
- @@test.save("a" => 2, "pop" => 100)
1794
- @@test.save("a" => 2, "pop" => 100)
1862
+ @test.remove
1863
+ @test.save("a" => 1, "pop" => 100)
1864
+ @test.save("a" => 1, "pop" => 100)
1865
+ @test.save("a" => 2, "pop" => 100)
1866
+ @test.save("a" => 2, "pop" => 100)
1795
1867
  @initial = {"count" => 0, "foo" => 1}
1796
1868
  @reduce_function = "function (obj, prev) { prev.count += obj.pop; }"
1797
1869
  end
1798
1870
 
1799
1871
  should "group" do
1800
- result = @@test.group(:key => :a, :initial => @initial, :reduce => @reduce_function)
1872
+ result = @test.group(:key => :a, :initial => @initial, :reduce => @reduce_function)
1801
1873
  assert result.all? { |r| r['count'] == 200 }
1802
1874
  end
1803
1875
  end
1804
1876
 
1805
1877
  context "Grouping with a key function" do
1806
1878
  setup do
1807
- @@test.remove
1808
- @@test.save("a" => 1)
1809
- @@test.save("a" => 2)
1810
- @@test.save("a" => 3)
1811
- @@test.save("a" => 4)
1812
- @@test.save("a" => 5)
1879
+ @test.remove
1880
+ @test.save("a" => 1)
1881
+ @test.save("a" => 2)
1882
+ @test.save("a" => 3)
1883
+ @test.save("a" => 4)
1884
+ @test.save("a" => 5)
1813
1885
  @initial = {"count" => 0}
1814
1886
  @keyf = "function (doc) { if(doc.a % 2 == 0) { return {even: true}; } else {return {odd: true}} };"
1815
1887
  @reduce = "function (obj, prev) { prev.count += 1; }"
1816
1888
  end
1817
1889
 
1818
1890
  should "group results" do
1819
- results = @@test.group(:keyf => @keyf, :initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
1891
+ results = @test.group(:keyf => @keyf, :initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
1820
1892
  assert results[0]['even'] && results[0]['count'] == 2.0
1821
1893
  assert results[1]['odd'] && results[1]['count'] == 3.0
1822
1894
  end
1823
1895
 
1824
1896
  should "group filtered results" do
1825
- results = @@test.group(:keyf => @keyf, :cond => {:a => {'$ne' => 2}},
1826
- :initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
1897
+ results = @test.group(:keyf => @keyf, :cond => {:a => {'$ne' => 2}},
1898
+ :initial => @initial, :reduce => @reduce).sort {|a, b| a['count'] <=> b['count']}
1827
1899
  assert results[0]['even'] && results[0]['count'] == 1.0
1828
1900
  assert results[1]['odd'] && results[1]['count'] == 3.0
1829
1901
  end
@@ -1831,7 +1903,7 @@ end
1831
1903
 
1832
1904
  context "A collection with two records" do
1833
1905
  setup do
1834
- @collection = @@db.collection('test-collection')
1906
+ @collection = @db.collection('test-collection')
1835
1907
  @collection.remove
1836
1908
  @collection.insert({:name => "Jones"})
1837
1909
  @collection.insert({:name => "Smith"})
@@ -1859,8 +1931,8 @@ end
1859
1931
 
1860
1932
  context "Drop index " do
1861
1933
  setup do
1862
- @@db.drop_collection('test-collection')
1863
- @collection = @@db.collection('test-collection')
1934
+ @db.drop_collection('test-collection')
1935
+ @collection = @db.collection('test-collection')
1864
1936
  end
1865
1937
 
1866
1938
  should "drop an index" do
@@ -1894,10 +1966,10 @@ end
1894
1966
 
1895
1967
  context "Creating indexes " do
1896
1968
  setup do
1897
- @@db.drop_collection('geo')
1898
- @@db.drop_collection('test-collection')
1899
- @collection = @@db.collection('test-collection')
1900
- @geo = @@db.collection('geo')
1969
+ @db.drop_collection('geo')
1970
+ @db.drop_collection('test-collection')
1971
+ @collection = @db.collection('test-collection')
1972
+ @geo = @db.collection('geo')
1901
1973
  end
1902
1974
 
1903
1975
  should "create index using symbols" do
@@ -1947,31 +2019,37 @@ end
1947
2019
  end
1948
2020
 
1949
2021
  should "drop duplicates" do
1950
- @collection.insert({:a => 1})
1951
- @collection.insert({:a => 1})
1952
- assert_equal 2, @collection.find({:a => 1}).count
1953
- @collection.create_index([['a', Mongo::ASCENDING]], :unique => true, :dropDups => true)
1954
- assert_equal 1, @collection.find({:a => 1}).count
2022
+ if @version < '2.7'
2023
+ @collection.insert({:a => 1})
2024
+ @collection.insert({:a => 1})
2025
+ assert_equal 2, @collection.find({:a => 1}).count
2026
+ @collection.create_index([['a', Mongo::ASCENDING]], :unique => true, :dropDups => true)
2027
+ assert_equal 1, @collection.find({:a => 1}).count
2028
+ end
1955
2029
  end
1956
2030
 
1957
2031
  should "drop duplicates with ruby-like drop_dups key" do
1958
- @collection.insert({:a => 1})
1959
- @collection.insert({:a => 1})
1960
- assert_equal 2, @collection.find({:a => 1}).count
1961
- @collection.create_index([['a', Mongo::ASCENDING]], :unique => true, :drop_dups => true)
1962
- assert_equal 1, @collection.find({:a => 1}).count
2032
+ if @version < '2.7'
2033
+ @collection.insert({:a => 1})
2034
+ @collection.insert({:a => 1})
2035
+ assert_equal 2, @collection.find({:a => 1}).count
2036
+ @collection.create_index([['a', Mongo::ASCENDING]], :unique => true, :drop_dups => true)
2037
+ assert_equal 1, @collection.find({:a => 1}).count
2038
+ end
1963
2039
  end
1964
2040
 
1965
2041
  should "drop duplicates with ensure_index and drop_dups key" do
1966
- @collection.insert({:a => 1})
1967
- @collection.insert({:a => 1})
1968
- assert_equal 2, @collection.find({:a => 1}).count
1969
- @collection.ensure_index([['a', Mongo::ASCENDING]], :unique => true, :drop_dups => true)
1970
- assert_equal 1, @collection.find({:a => 1}).count
2042
+ if @version < '2.7'
2043
+ @collection.insert({:a => 1})
2044
+ @collection.insert({:a => 1})
2045
+ assert_equal 2, @collection.find({:a => 1}).count
2046
+ @collection.ensure_index([['a', Mongo::ASCENDING]], :unique => true, :drop_dups => true)
2047
+ assert_equal 1, @collection.find({:a => 1}).count
2048
+ end
1971
2049
  end
1972
2050
 
1973
2051
  should "create an index in the background" do
1974
- if @@version > '1.3.1'
2052
+ if @version > '1.3.1'
1975
2053
  @collection.create_index([['b', Mongo::ASCENDING]], :background => true)
1976
2054
  assert @collection.index_information['b_1']['background'] == true
1977
2055
  else
@@ -1994,19 +2072,19 @@ end
1994
2072
  should "raise an error if index name is greater than 128" do
1995
2073
  assert_raise Mongo::OperationFailure do
1996
2074
  @collection.create_index([['a' * 25, 1], ['b' * 25, 1],
1997
- ['c' * 25, 1], ['d' * 25, 1], ['e' * 25, 1]])
2075
+ ['c' * 25, 1], ['d' * 25, 1], ['e' * 25, 1]])
1998
2076
  end
1999
2077
  end
2000
2078
 
2001
2079
  should "allow for an alternate name to be specified" do
2002
2080
  @collection.create_index([['a' * 25, 1], ['b' * 25, 1],
2003
- ['c' * 25, 1], ['d' * 25, 1], ['e' * 25, 1]], :name => 'foo_index')
2081
+ ['c' * 25, 1], ['d' * 25, 1], ['e' * 25, 1]], :name => 'foo_index')
2004
2082
  assert @collection.index_information['foo_index']
2005
2083
  end
2006
2084
 
2007
2085
  should "generate indexes in the proper order" do
2008
2086
  key = BSON::OrderedHash['b', 1, 'a', 1]
2009
- if @@version < '2.5.5'
2087
+ if @version < '2.5.5'
2010
2088
  @collection.expects(:send_write) do |type, selector, documents, check_keys, opts, collection_name|
2011
2089
  assert_equal key, selector[:key]
2012
2090
  end
@@ -2036,8 +2114,8 @@ end
2036
2114
 
2037
2115
  context "Capped collections" do
2038
2116
  setup do
2039
- @@db.drop_collection('log')
2040
- @capped = @@db.create_collection('log', :capped => true, :size => LIMITED_MAX_BSON_SIZE)
2117
+ @db.drop_collection('log')
2118
+ @capped = @db.create_collection('log', :capped => true, :size => LIMITED_MAX_BSON_SIZE)
2041
2119
 
2042
2120
  10.times { |n| @capped.insert({:n => n}) }
2043
2121
  end
@@ -2053,7 +2131,7 @@ end
2053
2131
  end
2054
2132
 
2055
2133
  should "fail tailable cursor on a non-capped collection" do
2056
- col = @@db['regular-collection']
2134
+ col = @db['regular-collection']
2057
2135
  col.insert({:a => 1000})
2058
2136
  tail = Cursor.new(col, :tailable => true, :order => [['$natural', 1]])
2059
2137
  assert_raise OperationFailure do