mongo 1.10.2 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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