kbaum-mongo 0.18.3p
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.
- data/LICENSE.txt +202 -0
- data/README.rdoc +339 -0
- data/Rakefile +138 -0
- data/bin/bson_benchmark.rb +59 -0
- data/bin/fail_if_no_c.rb +11 -0
- data/examples/admin.rb +42 -0
- data/examples/capped.rb +22 -0
- data/examples/cursor.rb +48 -0
- data/examples/gridfs.rb +88 -0
- data/examples/index_test.rb +126 -0
- data/examples/info.rb +31 -0
- data/examples/queries.rb +70 -0
- data/examples/simple.rb +24 -0
- data/examples/strict.rb +35 -0
- data/examples/types.rb +36 -0
- data/lib/mongo/collection.rb +609 -0
- data/lib/mongo/connection.rb +672 -0
- data/lib/mongo/cursor.rb +403 -0
- data/lib/mongo/db.rb +555 -0
- data/lib/mongo/exceptions.rb +66 -0
- data/lib/mongo/gridfs/chunk.rb +91 -0
- data/lib/mongo/gridfs/grid.rb +79 -0
- data/lib/mongo/gridfs/grid_file_system.rb +101 -0
- data/lib/mongo/gridfs/grid_io.rb +338 -0
- data/lib/mongo/gridfs/grid_store.rb +580 -0
- data/lib/mongo/gridfs.rb +25 -0
- data/lib/mongo/types/binary.rb +52 -0
- data/lib/mongo/types/code.rb +36 -0
- data/lib/mongo/types/dbref.rb +40 -0
- data/lib/mongo/types/min_max_keys.rb +58 -0
- data/lib/mongo/types/objectid.rb +180 -0
- data/lib/mongo/types/regexp_of_holding.rb +45 -0
- data/lib/mongo/util/bson_c.rb +18 -0
- data/lib/mongo/util/bson_ruby.rb +606 -0
- data/lib/mongo/util/byte_buffer.rb +222 -0
- data/lib/mongo/util/conversions.rb +87 -0
- data/lib/mongo/util/ordered_hash.rb +140 -0
- data/lib/mongo/util/server_version.rb +69 -0
- data/lib/mongo/util/support.rb +26 -0
- data/lib/mongo.rb +63 -0
- data/mongo-ruby-driver.gemspec +28 -0
- data/test/auxillary/autoreconnect_test.rb +42 -0
- data/test/binary_test.rb +15 -0
- data/test/bson_test.rb +427 -0
- data/test/byte_buffer_test.rb +81 -0
- data/test/chunk_test.rb +82 -0
- data/test/collection_test.rb +515 -0
- data/test/connection_test.rb +160 -0
- data/test/conversions_test.rb +120 -0
- data/test/cursor_test.rb +379 -0
- data/test/db_api_test.rb +780 -0
- data/test/db_connection_test.rb +16 -0
- data/test/db_test.rb +272 -0
- data/test/grid_file_system_test.rb +210 -0
- data/test/grid_io_test.rb +78 -0
- data/test/grid_store_test.rb +334 -0
- data/test/grid_test.rb +87 -0
- data/test/objectid_test.rb +125 -0
- data/test/ordered_hash_test.rb +172 -0
- data/test/replica/count_test.rb +34 -0
- data/test/replica/insert_test.rb +50 -0
- data/test/replica/pooled_insert_test.rb +54 -0
- data/test/replica/query_test.rb +39 -0
- data/test/slave_connection_test.rb +36 -0
- data/test/test_helper.rb +42 -0
- data/test/threading/test_threading_large_pool.rb +90 -0
- data/test/threading_test.rb +87 -0
- data/test/unit/collection_test.rb +61 -0
- data/test/unit/connection_test.rb +117 -0
- data/test/unit/cursor_test.rb +93 -0
- data/test/unit/db_test.rb +98 -0
- metadata +127 -0
@@ -0,0 +1,515 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class TestCollection < Test::Unit::TestCase
|
4
|
+
@@connection ||= Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost', ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
|
5
|
+
@@db = @@connection.db('ruby-mongo-test')
|
6
|
+
@@test = @@db.collection("test")
|
7
|
+
@@version = @@connection.server_version
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@@test.drop()
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_optional_pk_factory
|
14
|
+
@coll_default_pk = @@db.collection('stuff')
|
15
|
+
assert_equal Mongo::ObjectID, @coll_default_pk.pk_factory
|
16
|
+
@coll_default_pk = @@db.create_collection('more-stuff')
|
17
|
+
assert_equal Mongo::ObjectID, @coll_default_pk.pk_factory
|
18
|
+
|
19
|
+
# Create a db with a pk_factory.
|
20
|
+
@db = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
21
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT).db('ruby-mongo-test', :pk => Object.new)
|
22
|
+
@coll = @db.collection('coll-with-pk')
|
23
|
+
assert @coll.pk_factory.is_a?(Object)
|
24
|
+
|
25
|
+
@coll = @db.create_collection('created_coll_with_pk')
|
26
|
+
assert @coll.pk_factory.is_a?(Object)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_valid_names
|
30
|
+
assert_raise InvalidName do
|
31
|
+
@@db["te$t"]
|
32
|
+
end
|
33
|
+
|
34
|
+
assert_raise InvalidName do
|
35
|
+
@@db['$main']
|
36
|
+
end
|
37
|
+
|
38
|
+
assert @@db['$cmd']
|
39
|
+
assert @@db['oplog.$main']
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_collection
|
43
|
+
assert_kind_of Collection, @@db["test"]
|
44
|
+
assert_equal @@db["test"].name(), @@db.collection("test").name()
|
45
|
+
assert_equal @@db["test"].name(), @@db[:test].name()
|
46
|
+
|
47
|
+
assert_kind_of Collection, @@db["test"]["foo"]
|
48
|
+
assert_equal @@db["test"]["foo"].name(), @@db.collection("test.foo").name()
|
49
|
+
assert_equal @@db["test"]["foo"].name(), @@db["test.foo"].name()
|
50
|
+
|
51
|
+
@@db["test"]["foo"].remove
|
52
|
+
@@db["test"]["foo"].insert("x" => 5)
|
53
|
+
assert_equal 5, @@db.collection("test.foo").find_one()["x"]
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_nil_id
|
57
|
+
assert_equal 5, @@test.insert({"_id" => 5, "foo" => "bar"}, {:safe => true})
|
58
|
+
assert_equal 5, @@test.save({"_id" => 5, "foo" => "baz"}, {:safe => true})
|
59
|
+
assert_equal nil, @@test.find_one("foo" => "bar")
|
60
|
+
assert_equal "baz", @@test.find_one(:_id => 5)["foo"]
|
61
|
+
assert_raise OperationFailure do
|
62
|
+
@@test.insert({"_id" => 5, "foo" => "bar"}, {:safe => true})
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_equal nil, @@test.insert({"_id" => nil, "foo" => "bar"}, {:safe => true})
|
66
|
+
assert_equal nil, @@test.save({"_id" => nil, "foo" => "baz"}, {:safe => true})
|
67
|
+
assert_equal nil, @@test.find_one("foo" => "bar")
|
68
|
+
assert_equal "baz", @@test.find_one(:_id => nil)["foo"]
|
69
|
+
assert_raise OperationFailure do
|
70
|
+
@@test.insert({"_id" => nil, "foo" => "bar"}, {:safe => true})
|
71
|
+
end
|
72
|
+
assert_raise OperationFailure do
|
73
|
+
@@test.insert({:_id => nil, "foo" => "bar"}, {:safe => true})
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if @@version > "1.1"
|
78
|
+
def setup_for_distinct
|
79
|
+
@@test.remove
|
80
|
+
@@test.insert([{:a => 0, :b => {:c => "a"}},
|
81
|
+
{:a => 1, :b => {:c => "b"}},
|
82
|
+
{:a => 1, :b => {:c => "c"}},
|
83
|
+
{:a => 2, :b => {:c => "a"}},
|
84
|
+
{:a => 3},
|
85
|
+
{:a => 3}])
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_distinct_queries
|
89
|
+
setup_for_distinct
|
90
|
+
assert_equal [0, 1, 2, 3], @@test.distinct(:a).sort
|
91
|
+
assert_equal ["a", "b", "c"], @@test.distinct("b.c").sort
|
92
|
+
end
|
93
|
+
|
94
|
+
if @@version >= "1.2"
|
95
|
+
def test_filter_collection_with_query
|
96
|
+
setup_for_distinct
|
97
|
+
assert_equal [2, 3], @@test.distinct(:a, {:a => {"$gt" => 1}}).sort
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_filter_nested_objects
|
101
|
+
setup_for_distinct
|
102
|
+
assert_equal ["a", "b"], @@test.distinct("b.c", {"b.c" => {"$ne" => "c"}}).sort
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_safe_insert
|
108
|
+
a = {"hello" => "world"}
|
109
|
+
@@test.insert(a)
|
110
|
+
@@test.insert(a)
|
111
|
+
assert(@@db.error.include?("E11000"))
|
112
|
+
|
113
|
+
assert_raise OperationFailure do
|
114
|
+
@@test.insert(a, :safe => true)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_update
|
119
|
+
id1 = @@test.save("x" => 5)
|
120
|
+
@@test.update({}, {"$inc" => {"x" => 1}})
|
121
|
+
assert_equal 1, @@test.count()
|
122
|
+
assert_equal 6, @@test.find_one(:_id => id1)["x"]
|
123
|
+
|
124
|
+
id2 = @@test.save("x" => 1)
|
125
|
+
@@test.update({"x" => 6}, {"$inc" => {"x" => 1}})
|
126
|
+
assert_equal 7, @@test.find_one(:_id => id1)["x"]
|
127
|
+
assert_equal 1, @@test.find_one(:_id => id2)["x"]
|
128
|
+
end
|
129
|
+
|
130
|
+
if @@version >= "1.1.3"
|
131
|
+
def test_multi_update
|
132
|
+
@@test.save("num" => 10)
|
133
|
+
@@test.save("num" => 10)
|
134
|
+
@@test.save("num" => 10)
|
135
|
+
assert_equal 3, @@test.count
|
136
|
+
|
137
|
+
@@test.update({"num" => 10}, {"$set" => {"num" => 100}}, :multi => true)
|
138
|
+
@@test.find.each do |doc|
|
139
|
+
assert_equal 100, doc["num"]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_upsert
|
145
|
+
@@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
146
|
+
@@test.update({"page" => "/"}, {"$inc" => {"count" => 1}}, :upsert => true)
|
147
|
+
|
148
|
+
assert_equal 1, @@test.count()
|
149
|
+
assert_equal 2, @@test.find_one()["count"]
|
150
|
+
end
|
151
|
+
|
152
|
+
if @@version < "1.1.3"
|
153
|
+
def test_safe_update
|
154
|
+
@@test.create_index("x")
|
155
|
+
@@test.insert("x" => 5)
|
156
|
+
|
157
|
+
@@test.update({}, {"$inc" => {"x" => 1}})
|
158
|
+
assert @@db.error?
|
159
|
+
|
160
|
+
# Can't change an index.
|
161
|
+
assert_raise OperationFailure do
|
162
|
+
@@test.update({}, {"$inc" => {"x" => 1}}, :safe => true)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
else
|
166
|
+
def test_safe_update
|
167
|
+
@@test.create_index("x", true)
|
168
|
+
@@test.insert("x" => 5)
|
169
|
+
@@test.insert("x" => 10)
|
170
|
+
|
171
|
+
# Can update an indexed collection.
|
172
|
+
@@test.update({}, {"$inc" => {"x" => 1}})
|
173
|
+
assert !@@db.error?
|
174
|
+
|
175
|
+
# Can't duplicate an index.
|
176
|
+
assert_raise OperationFailure do
|
177
|
+
@@test.update({}, {"x" => 10}, :safe => true)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_safe_save
|
183
|
+
@@test.create_index("hello", true)
|
184
|
+
|
185
|
+
@@test.save("hello" => "world")
|
186
|
+
@@test.save("hello" => "world")
|
187
|
+
|
188
|
+
assert_raise OperationFailure do
|
189
|
+
@@test.save({"hello" => "world"}, :safe => true)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_mocked_safe_remove
|
194
|
+
@conn = Connection.new
|
195
|
+
@db = @conn['mongo-ruby-test']
|
196
|
+
@test = @db['test-safe-remove']
|
197
|
+
@test.save({:a => 20})
|
198
|
+
@conn.stubs(:receive).returns([[{'ok' => 0, 'err' => 'failed'}], 1, 0])
|
199
|
+
|
200
|
+
assert_raise OperationFailure do
|
201
|
+
@test.remove({}, :safe => true)
|
202
|
+
end
|
203
|
+
@test.drop
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_safe_remove
|
207
|
+
@conn = Connection.new
|
208
|
+
@db = @conn['mongo-ruby-test']
|
209
|
+
@test = @db['test-safe-remove']
|
210
|
+
@test.save({:a => 50})
|
211
|
+
@test.remove({}, :safe => true)
|
212
|
+
@test.drop
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_count
|
216
|
+
@@test.drop
|
217
|
+
|
218
|
+
assert_equal 0, @@test.count
|
219
|
+
@@test.save("x" => 1)
|
220
|
+
@@test.save("x" => 2)
|
221
|
+
assert_equal 2, @@test.count
|
222
|
+
end
|
223
|
+
|
224
|
+
# Note: #size is just an alias for #count.
|
225
|
+
def test_size
|
226
|
+
@@test.drop
|
227
|
+
|
228
|
+
assert_equal 0, @@test.count
|
229
|
+
assert_equal @@test.size, @@test.count
|
230
|
+
@@test.save("x" => 1)
|
231
|
+
@@test.save("x" => 2)
|
232
|
+
assert_equal @@test.size, @@test.count
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_no_timeout_option
|
236
|
+
@@test.drop
|
237
|
+
|
238
|
+
assert_raise ArgumentError, "Timeout can be set to false only when #find is invoked with a block." do
|
239
|
+
@@test.find({}, :timeout => false)
|
240
|
+
end
|
241
|
+
|
242
|
+
@@test.find({}, :timeout => false) do |cursor|
|
243
|
+
assert_equal 0, cursor.count
|
244
|
+
end
|
245
|
+
|
246
|
+
@@test.save("x" => 1)
|
247
|
+
@@test.save("x" => 2)
|
248
|
+
@@test.find({}, :timeout => false) do |cursor|
|
249
|
+
assert_equal 2, cursor.count
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_find_one
|
254
|
+
id = @@test.save("hello" => "world", "foo" => "bar")
|
255
|
+
|
256
|
+
assert_equal "world", @@test.find_one()["hello"]
|
257
|
+
assert_equal @@test.find_one(id), @@test.find_one()
|
258
|
+
assert_equal @@test.find_one(nil), @@test.find_one()
|
259
|
+
assert_equal @@test.find_one({}), @@test.find_one()
|
260
|
+
assert_equal @@test.find_one("hello" => "world"), @@test.find_one()
|
261
|
+
assert_equal @@test.find_one(OrderedHash["hello", "world"]), @@test.find_one()
|
262
|
+
|
263
|
+
assert @@test.find_one(nil, :fields => ["hello"]).include?("hello")
|
264
|
+
assert !@@test.find_one(nil, :fields => ["foo"]).include?("hello")
|
265
|
+
assert_equal ["_id"], @@test.find_one(nil, :fields => []).keys()
|
266
|
+
|
267
|
+
assert_equal nil, @@test.find_one("hello" => "foo")
|
268
|
+
assert_equal nil, @@test.find_one(OrderedHash["hello", "foo"])
|
269
|
+
assert_equal nil, @@test.find_one(ObjectID.new)
|
270
|
+
|
271
|
+
assert_raise TypeError do
|
272
|
+
@@test.find_one(6)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_insert_adds_id
|
277
|
+
doc = {"hello" => "world"}
|
278
|
+
@@test.insert(doc)
|
279
|
+
assert(doc.include?(:_id))
|
280
|
+
|
281
|
+
docs = [{"hello" => "world"}, {"hello" => "world"}]
|
282
|
+
@@test.insert(docs)
|
283
|
+
docs.each do |doc|
|
284
|
+
assert(doc.include?(:_id))
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_save_adds_id
|
289
|
+
doc = {"hello" => "world"}
|
290
|
+
@@test.save(doc)
|
291
|
+
assert(doc.include?(:_id))
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_optional_find_block
|
295
|
+
10.times do |i|
|
296
|
+
@@test.save("i" => i)
|
297
|
+
end
|
298
|
+
|
299
|
+
x = nil
|
300
|
+
@@test.find("i" => 2) { |cursor|
|
301
|
+
x = cursor.count()
|
302
|
+
}
|
303
|
+
assert_equal 1, x
|
304
|
+
|
305
|
+
i = 0
|
306
|
+
@@test.find({}, :skip => 5) do |cursor|
|
307
|
+
cursor.each do |doc|
|
308
|
+
i = i + 1
|
309
|
+
end
|
310
|
+
end
|
311
|
+
assert_equal 5, i
|
312
|
+
|
313
|
+
c = nil
|
314
|
+
@@test.find() do |cursor|
|
315
|
+
c = cursor
|
316
|
+
end
|
317
|
+
assert c.closed?
|
318
|
+
end
|
319
|
+
|
320
|
+
if @@version < "1.1.1"
|
321
|
+
def test_map_reduce
|
322
|
+
@@test << { "user_id" => 1 }
|
323
|
+
@@test << { "user_id" => 2 }
|
324
|
+
|
325
|
+
m = "function() { emit(this.user_id, 1); }"
|
326
|
+
r = "function(k,vals) { return 1; }"
|
327
|
+
res = @@test.map_reduce(m, r);
|
328
|
+
assert res.find_one({"_id" => 1})
|
329
|
+
assert res.find_one({"_id" => 2})
|
330
|
+
end
|
331
|
+
|
332
|
+
def test_map_reduce_with_code_objects
|
333
|
+
@@test << { "user_id" => 1 }
|
334
|
+
@@test << { "user_id" => 2 }
|
335
|
+
|
336
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
337
|
+
r = Code.new("function(k,vals) { return 1; }")
|
338
|
+
res = @@test.map_reduce(m, r);
|
339
|
+
assert res.find_one({"_id" => 1})
|
340
|
+
assert res.find_one({"_id" => 2})
|
341
|
+
end
|
342
|
+
|
343
|
+
def test_map_reduce_with_options
|
344
|
+
@@test.remove
|
345
|
+
@@test << { "user_id" => 1 }
|
346
|
+
@@test << { "user_id" => 2 }
|
347
|
+
@@test << { "user_id" => 3 }
|
348
|
+
|
349
|
+
m = Code.new("function() { emit(this.user_id, 1); }")
|
350
|
+
r = Code.new("function(k,vals) { return 1; }")
|
351
|
+
res = @@test.map_reduce(m, r, :query => {"user_id" => {"$gt" => 1}});
|
352
|
+
assert_equal 2, res.count
|
353
|
+
assert res.find_one({"_id" => 2})
|
354
|
+
assert res.find_one({"_id" => 3})
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_saving_dates_pre_epoch
|
359
|
+
begin
|
360
|
+
@@test.save({'date' => Time.utc(1600)})
|
361
|
+
assert_in_delta Time.utc(1600), @@test.find_one()["date"], 0.001
|
362
|
+
rescue ArgumentError
|
363
|
+
# See note in test_date_before_epoch (BSONTest)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def test_save_symbol_find_string
|
368
|
+
@@test.save(:foo => :mike)
|
369
|
+
|
370
|
+
assert_equal :mike, @@test.find_one(:foo => :mike)["foo"]
|
371
|
+
assert_equal :mike, @@test.find_one("foo" => :mike)["foo"]
|
372
|
+
|
373
|
+
# TODO enable these tests conditionally based on server version (if >1.0)
|
374
|
+
# assert_equal :mike, @@test.find_one(:foo => "mike")["foo"]
|
375
|
+
# assert_equal :mike, @@test.find_one("foo" => "mike")["foo"]
|
376
|
+
end
|
377
|
+
|
378
|
+
def test_limit_and_skip
|
379
|
+
10.times do |i|
|
380
|
+
@@test.save(:foo => i)
|
381
|
+
end
|
382
|
+
|
383
|
+
assert_equal 5, @@test.find({}, :skip => 5).next_document()["foo"]
|
384
|
+
assert_equal nil, @@test.find({}, :skip => 10).next_document()
|
385
|
+
|
386
|
+
assert_equal 5, @@test.find({}, :limit => 5).to_a.length
|
387
|
+
|
388
|
+
assert_equal 3, @@test.find({}, :skip => 3, :limit => 5).next_document()["foo"]
|
389
|
+
assert_equal 5, @@test.find({}, :skip => 3, :limit => 5).to_a.length
|
390
|
+
end
|
391
|
+
|
392
|
+
def test_large_limit
|
393
|
+
2000.times do |i|
|
394
|
+
@@test.insert("x" => i, "y" => "mongomongo" * 1000)
|
395
|
+
end
|
396
|
+
|
397
|
+
assert_equal 2000, @@test.count
|
398
|
+
|
399
|
+
i = 0
|
400
|
+
y = 0
|
401
|
+
@@test.find({}, :limit => 1900).each do |doc|
|
402
|
+
i += 1
|
403
|
+
y += doc["x"]
|
404
|
+
end
|
405
|
+
|
406
|
+
assert_equal 1900, i
|
407
|
+
assert_equal 1804050, y
|
408
|
+
end
|
409
|
+
|
410
|
+
def test_small_limit
|
411
|
+
@@test.insert("x" => "hello world")
|
412
|
+
@@test.insert("x" => "goodbye world")
|
413
|
+
|
414
|
+
assert_equal 2, @@test.count
|
415
|
+
|
416
|
+
x = 0
|
417
|
+
@@test.find({}, :limit => 1).each do |doc|
|
418
|
+
x += 1
|
419
|
+
assert_equal "hello world", doc["x"]
|
420
|
+
end
|
421
|
+
|
422
|
+
assert_equal 1, x
|
423
|
+
end
|
424
|
+
|
425
|
+
context "Grouping" do
|
426
|
+
setup do
|
427
|
+
@@test.remove
|
428
|
+
@@test.save("a" => 1)
|
429
|
+
@@test.save("b" => 1)
|
430
|
+
@initial = {"count" => 0}
|
431
|
+
@reduce_function = "function (obj, prev) { prev.count += inc_value; }"
|
432
|
+
end
|
433
|
+
|
434
|
+
should "group results using eval form" do
|
435
|
+
assert_equal 1, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 0.5}))[0]["count"]
|
436
|
+
assert_equal 2, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}))[0]["count"]
|
437
|
+
assert_equal 4, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 2}))[0]["count"]
|
438
|
+
end
|
439
|
+
|
440
|
+
should "finalize grouped results" do
|
441
|
+
@finalize = "function(doc) {doc.f = doc.count + 200; }"
|
442
|
+
assert_equal 202, @@test.group([], {}, @initial, Code.new(@reduce_function, {"inc_value" => 1}), @finalize)[0]["f"]
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
context "Grouping with a key function" do
|
447
|
+
setup do
|
448
|
+
@@test.remove
|
449
|
+
@@test.save("a" => 1)
|
450
|
+
@@test.save("a" => 2)
|
451
|
+
@@test.save("a" => 3)
|
452
|
+
@@test.save("a" => 4)
|
453
|
+
@@test.save("a" => 5)
|
454
|
+
@initial = {"count" => 0}
|
455
|
+
@keyf = "function (doc) { if(doc.a % 2 == 0) { return {even: true}; } else {return {odd: true}} };"
|
456
|
+
@reduce = "function (obj, prev) { prev.count += 1; }"
|
457
|
+
end
|
458
|
+
|
459
|
+
should "group results" do
|
460
|
+
results = @@test.group(@keyf, {}, @initial, @reduce).sort {|a, b| a['count'] <=> b['count']}
|
461
|
+
assert results[0]['even'] && results[0]['count'] == 2.0
|
462
|
+
assert results[1]['odd'] && results[1]['count'] == 3.0
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
context "A collection with two records" do
|
467
|
+
setup do
|
468
|
+
@collection = @@db.collection('test-collection')
|
469
|
+
@collection.insert({:name => "Jones"})
|
470
|
+
@collection.insert({:name => "Smith"})
|
471
|
+
end
|
472
|
+
|
473
|
+
should "have two records" do
|
474
|
+
assert_equal 2, @collection.size
|
475
|
+
end
|
476
|
+
|
477
|
+
should "remove the two records" do
|
478
|
+
@collection.remove()
|
479
|
+
assert_equal 0, @collection.size
|
480
|
+
end
|
481
|
+
|
482
|
+
should "remove all records if an empty document is specified" do
|
483
|
+
@collection.remove({})
|
484
|
+
assert_equal 0, @collection.find.count
|
485
|
+
end
|
486
|
+
|
487
|
+
should "remove only matching records" do
|
488
|
+
@collection.remove({:name => "Jones"})
|
489
|
+
assert_equal 1, @collection.size
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
context "Creating indexes " do
|
494
|
+
setup do
|
495
|
+
@collection = @@db.collection('test-collection')
|
496
|
+
end
|
497
|
+
|
498
|
+
should "generate indexes in the proper order" do
|
499
|
+
@collection.expects(:insert_documents) do |sel, coll, safe|
|
500
|
+
assert_equal 'b_1_a_1', sel[:name]
|
501
|
+
end
|
502
|
+
@collection.create_index([['b', 1], ['a', 1]])
|
503
|
+
end
|
504
|
+
|
505
|
+
context "with an index created" do
|
506
|
+
setup do
|
507
|
+
@collection.create_index([['b', 1], ['a', 1]])
|
508
|
+
end
|
509
|
+
|
510
|
+
should "return properly ordered index information" do
|
511
|
+
assert_equal [['b', 1], ['a', 1]], @collection.index_information["b_1_a_1"]
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
require 'logger'
|
3
|
+
require 'stringio'
|
4
|
+
require 'thread'
|
5
|
+
|
6
|
+
# NOTE: assumes Mongo is running
|
7
|
+
class TestConnection < Test::Unit::TestCase
|
8
|
+
|
9
|
+
include Mongo
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
13
|
+
@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
|
14
|
+
@mongo = Connection.new(@host, @port)
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
@mongo.db('ruby-mongo-test').error
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_server_info
|
22
|
+
server_info = @mongo.server_info
|
23
|
+
assert server_info.keys.include?("version")
|
24
|
+
assert_equal 1.0, server_info["ok"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_server_version
|
28
|
+
assert_match /\d\.\d+(\.\d+)?/, @mongo.server_version.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_invalid_database_names
|
32
|
+
assert_raise TypeError do @mongo.db(4) end
|
33
|
+
|
34
|
+
assert_raise InvalidName do @mongo.db('') end
|
35
|
+
assert_raise InvalidName do @mongo.db('te$t') end
|
36
|
+
assert_raise InvalidName do @mongo.db('te.t') end
|
37
|
+
assert_raise InvalidName do @mongo.db('te\\t') end
|
38
|
+
assert_raise InvalidName do @mongo.db('te/t') end
|
39
|
+
assert_raise InvalidName do @mongo.db('te st') end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_database_info
|
43
|
+
@mongo.drop_database('ruby-mongo-info-test')
|
44
|
+
@mongo.db('ruby-mongo-info-test').collection('info-test').insert('a' => 1)
|
45
|
+
|
46
|
+
info = @mongo.database_info
|
47
|
+
assert_not_nil info
|
48
|
+
assert_kind_of Hash, info
|
49
|
+
assert_not_nil info['ruby-mongo-info-test']
|
50
|
+
assert info['ruby-mongo-info-test'] > 0
|
51
|
+
|
52
|
+
@mongo.drop_database('ruby-mongo-info-test')
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_copy_database
|
56
|
+
@mongo.db('old').collection('copy-test').insert('a' => 1)
|
57
|
+
@mongo.copy_database('old', 'new')
|
58
|
+
old_object = @mongo.db('old').collection('copy-test').find.next_document
|
59
|
+
new_object = @mongo.db('new').collection('copy-test').find.next_document
|
60
|
+
assert_equal old_object, new_object
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_database_names
|
64
|
+
@mongo.drop_database('ruby-mongo-info-test')
|
65
|
+
@mongo.db('ruby-mongo-info-test').collection('info-test').insert('a' => 1)
|
66
|
+
|
67
|
+
names = @mongo.database_names
|
68
|
+
assert_not_nil names
|
69
|
+
assert_kind_of Array, names
|
70
|
+
assert names.length >= 1
|
71
|
+
assert names.include?('ruby-mongo-info-test')
|
72
|
+
|
73
|
+
@mongo.drop_database('ruby-mongo-info-test')
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_logging
|
77
|
+
output = StringIO.new
|
78
|
+
logger = Logger.new(output)
|
79
|
+
logger.level = Logger::DEBUG
|
80
|
+
db = Connection.new(@host, @port, :logger => logger).db('ruby-mongo-test')
|
81
|
+
assert output.string.include?("admin.$cmd.find")
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_connection_logger
|
85
|
+
output = StringIO.new
|
86
|
+
logger = Logger.new(output)
|
87
|
+
logger.level = Logger::DEBUG
|
88
|
+
connection = Connection.new(@host, @port, :logger => logger)
|
89
|
+
assert_equal logger, connection.logger
|
90
|
+
|
91
|
+
connection.logger.debug 'testing'
|
92
|
+
assert output.string.include?('testing')
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_drop_database
|
96
|
+
db = @mongo.db('ruby-mongo-will-be-deleted')
|
97
|
+
coll = db.collection('temp')
|
98
|
+
coll.remove
|
99
|
+
coll.insert(:name => 'temp')
|
100
|
+
assert_equal 1, coll.count()
|
101
|
+
assert @mongo.database_names.include?('ruby-mongo-will-be-deleted')
|
102
|
+
|
103
|
+
@mongo.drop_database('ruby-mongo-will-be-deleted')
|
104
|
+
assert !@mongo.database_names.include?('ruby-mongo-will-be-deleted')
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_nodes
|
108
|
+
db = Connection.new({:left => ['foo', 123]}, nil, :connect => false)
|
109
|
+
nodes = db.nodes
|
110
|
+
assert_equal 2, db.nodes.length
|
111
|
+
assert_equal ['foo', 123], nodes[0]
|
112
|
+
assert_equal ['localhost', Connection::DEFAULT_PORT], nodes[1]
|
113
|
+
|
114
|
+
db = Connection.new({:right => 'bar'}, nil, :connect => false)
|
115
|
+
nodes = db.nodes
|
116
|
+
assert_equal 2, nodes.length
|
117
|
+
assert_equal ['localhost', Connection::DEFAULT_PORT], nodes[0]
|
118
|
+
assert_equal ['bar', Connection::DEFAULT_PORT], nodes[1]
|
119
|
+
|
120
|
+
db = Connection.new({:right => ['foo', 123], :left => 'bar'}, nil, :connect => false)
|
121
|
+
nodes = db.nodes
|
122
|
+
assert_equal 2, nodes.length
|
123
|
+
assert_equal ['bar', Connection::DEFAULT_PORT], nodes[0]
|
124
|
+
assert_equal ['foo', 123], nodes[1]
|
125
|
+
end
|
126
|
+
|
127
|
+
context "Connection exceptions" do
|
128
|
+
setup do
|
129
|
+
@conn = Mongo::Connection.new('localhost', 27017, :pool_size => 10, :timeout => 10)
|
130
|
+
@coll = @conn['mongo-ruby-test']['test-connection-exceptions']
|
131
|
+
end
|
132
|
+
|
133
|
+
should "release connection if an exception is raised on send_message" do
|
134
|
+
@conn.stubs(:send_message_on_socket).raises(ConnectionFailure)
|
135
|
+
assert_equal 0, @conn.checked_out.size
|
136
|
+
assert_raise ConnectionFailure do
|
137
|
+
@coll.insert({:test => "insert"})
|
138
|
+
end
|
139
|
+
assert_equal 0, @conn.checked_out.size
|
140
|
+
end
|
141
|
+
|
142
|
+
should "release connection if an exception is raised on send_with_safe_check" do
|
143
|
+
@conn.stubs(:receive).raises(ConnectionFailure)
|
144
|
+
assert_equal 0, @conn.checked_out.size
|
145
|
+
assert_raise ConnectionFailure do
|
146
|
+
@coll.insert({:test => "insert"}, :safe => true)
|
147
|
+
end
|
148
|
+
assert_equal 0, @conn.checked_out.size
|
149
|
+
end
|
150
|
+
|
151
|
+
should "release connection if an exception is raised on receive_message" do
|
152
|
+
@conn.stubs(:receive).raises(ConnectionFailure)
|
153
|
+
assert_equal 0, @conn.checked_out.size
|
154
|
+
assert_raise ConnectionFailure do
|
155
|
+
@coll.find.to_a
|
156
|
+
end
|
157
|
+
assert_equal 0, @conn.checked_out.size
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|