mongo-lyon 1.2.4

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 (87) hide show
  1. data/LICENSE.txt +190 -0
  2. data/README.md +344 -0
  3. data/Rakefile +202 -0
  4. data/bin/mongo_console +34 -0
  5. data/docs/1.0_UPGRADE.md +21 -0
  6. data/docs/CREDITS.md +123 -0
  7. data/docs/FAQ.md +116 -0
  8. data/docs/GridFS.md +158 -0
  9. data/docs/HISTORY.md +225 -0
  10. data/docs/REPLICA_SETS.md +72 -0
  11. data/docs/TUTORIAL.md +247 -0
  12. data/docs/WRITE_CONCERN.md +28 -0
  13. data/lib/mongo.rb +77 -0
  14. data/lib/mongo/collection.rb +872 -0
  15. data/lib/mongo/connection.rb +875 -0
  16. data/lib/mongo/cursor.rb +449 -0
  17. data/lib/mongo/db.rb +607 -0
  18. data/lib/mongo/exceptions.rb +68 -0
  19. data/lib/mongo/gridfs/grid.rb +106 -0
  20. data/lib/mongo/gridfs/grid_ext.rb +57 -0
  21. data/lib/mongo/gridfs/grid_file_system.rb +145 -0
  22. data/lib/mongo/gridfs/grid_io.rb +394 -0
  23. data/lib/mongo/gridfs/grid_io_fix.rb +38 -0
  24. data/lib/mongo/repl_set_connection.rb +342 -0
  25. data/lib/mongo/util/conversions.rb +89 -0
  26. data/lib/mongo/util/core_ext.rb +60 -0
  27. data/lib/mongo/util/pool.rb +185 -0
  28. data/lib/mongo/util/server_version.rb +71 -0
  29. data/lib/mongo/util/support.rb +82 -0
  30. data/lib/mongo/util/uri_parser.rb +181 -0
  31. data/lib/mongo/version.rb +3 -0
  32. data/mongo.gemspec +34 -0
  33. data/test/auxillary/1.4_features.rb +166 -0
  34. data/test/auxillary/authentication_test.rb +68 -0
  35. data/test/auxillary/autoreconnect_test.rb +41 -0
  36. data/test/auxillary/repl_set_auth_test.rb +58 -0
  37. data/test/auxillary/slave_connection_test.rb +36 -0
  38. data/test/auxillary/threaded_authentication_test.rb +101 -0
  39. data/test/bson/binary_test.rb +15 -0
  40. data/test/bson/bson_test.rb +614 -0
  41. data/test/bson/byte_buffer_test.rb +190 -0
  42. data/test/bson/hash_with_indifferent_access_test.rb +38 -0
  43. data/test/bson/json_test.rb +17 -0
  44. data/test/bson/object_id_test.rb +154 -0
  45. data/test/bson/ordered_hash_test.rb +197 -0
  46. data/test/collection_test.rb +893 -0
  47. data/test/connection_test.rb +303 -0
  48. data/test/conversions_test.rb +120 -0
  49. data/test/cursor_fail_test.rb +75 -0
  50. data/test/cursor_message_test.rb +43 -0
  51. data/test/cursor_test.rb +457 -0
  52. data/test/db_api_test.rb +715 -0
  53. data/test/db_connection_test.rb +15 -0
  54. data/test/db_test.rb +287 -0
  55. data/test/grid_file_system_test.rb +244 -0
  56. data/test/grid_io_test.rb +120 -0
  57. data/test/grid_test.rb +200 -0
  58. data/test/load/thin/load.rb +24 -0
  59. data/test/load/unicorn/load.rb +23 -0
  60. data/test/replica_sets/connect_test.rb +86 -0
  61. data/test/replica_sets/connection_string_test.rb +32 -0
  62. data/test/replica_sets/count_test.rb +35 -0
  63. data/test/replica_sets/insert_test.rb +53 -0
  64. data/test/replica_sets/pooled_insert_test.rb +55 -0
  65. data/test/replica_sets/query_secondaries.rb +96 -0
  66. data/test/replica_sets/query_test.rb +51 -0
  67. data/test/replica_sets/replication_ack_test.rb +66 -0
  68. data/test/replica_sets/rs_test_helper.rb +27 -0
  69. data/test/safe_test.rb +68 -0
  70. data/test/support/hash_with_indifferent_access.rb +199 -0
  71. data/test/support/keys.rb +45 -0
  72. data/test/support_test.rb +19 -0
  73. data/test/test_helper.rb +83 -0
  74. data/test/threading/threading_with_large_pool_test.rb +90 -0
  75. data/test/threading_test.rb +87 -0
  76. data/test/tools/auth_repl_set_manager.rb +14 -0
  77. data/test/tools/repl_set_manager.rb +266 -0
  78. data/test/unit/collection_test.rb +130 -0
  79. data/test/unit/connection_test.rb +98 -0
  80. data/test/unit/cursor_test.rb +99 -0
  81. data/test/unit/db_test.rb +96 -0
  82. data/test/unit/grid_test.rb +49 -0
  83. data/test/unit/pool_test.rb +9 -0
  84. data/test/unit/repl_set_connection_test.rb +72 -0
  85. data/test/unit/safe_test.rb +125 -0
  86. data/test/uri_test.rb +91 -0
  87. metadata +202 -0
@@ -0,0 +1,15 @@
1
+ # encoding:utf-8
2
+ require './test/test_helper'
3
+
4
+ class BinaryTest < Test::Unit::TestCase
5
+ context "Inspecting" do
6
+ setup do
7
+ @data = ("THIS IS BINARY " * 50).unpack("c*")
8
+ end
9
+
10
+ should "not display actual data" do
11
+ binary = BSON::Binary.new(@data)
12
+ assert_equal "<BSON::Binary:#{binary.object_id}>", binary.inspect
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,614 @@
1
+ # encoding:utf-8
2
+ require './test/test_helper'
3
+ require 'complex'
4
+ require 'bigdecimal'
5
+ require 'rational'
6
+
7
+ begin
8
+ require 'active_support/core_ext'
9
+ Time.zone = "Pacific Time (US & Canada)"
10
+ Zone = Time.zone.now
11
+ rescue LoadError
12
+ warn 'Mocking time with zone'
13
+ module ActiveSupport
14
+ class TimeWithZone
15
+ def initialize(utc_time, zone)
16
+ end
17
+ end
18
+ end
19
+ Zone = ActiveSupport::TimeWithZone.new(Time.now.utc, 'EST')
20
+ end
21
+
22
+ class BSONTest < Test::Unit::TestCase
23
+
24
+ include BSON
25
+
26
+ def setup
27
+ @encoder = BSON::BSON_CODER
28
+ end
29
+
30
+ def assert_doc_pass(doc, options={})
31
+ bson = @encoder.serialize(doc)
32
+ if options[:debug]
33
+ puts "DEBUGGING DOC:"
34
+ p bson.to_a
35
+ puts "DESERIALIZES TO:"
36
+ end
37
+ assert_equal @encoder.serialize(doc).to_a, bson.to_a
38
+ assert_equal doc, @encoder.deserialize(bson)
39
+ end
40
+
41
+ def test_require_hash
42
+ assert_raise_error InvalidDocument, "takes a Hash" do
43
+ BSON.serialize('foo')
44
+ end
45
+
46
+ assert_raise_error InvalidDocument, "takes a Hash" do
47
+ BSON.serialize(Object.new)
48
+ end
49
+
50
+ assert_raise_error InvalidDocument, "takes a Hash" do
51
+ BSON.serialize(Set.new)
52
+ end
53
+ end
54
+
55
+ def test_string
56
+ doc = {'doc' => 'hello, world'}
57
+ assert_doc_pass(doc)
58
+ end
59
+
60
+ def test_valid_utf8_string
61
+ doc = {'doc' => 'aé'}
62
+ assert_doc_pass(doc)
63
+ end
64
+
65
+ def test_valid_utf8_key
66
+ doc = {'aé' => 'hello'}
67
+ assert_doc_pass(doc)
68
+ end
69
+
70
+ def test_limit_max_bson_size
71
+ doc = {'name' => 'a' * BSON_CODER.max_bson_size}
72
+ assert_raise InvalidDocument do
73
+ assert @encoder.serialize(doc)
74
+ end
75
+ end
76
+
77
+ def test_max_bson_size
78
+ assert BSON_CODER.max_bson_size >= BSON::DEFAULT_MAX_BSON_SIZE
79
+ end
80
+
81
+ def test_update_max_bson_size
82
+ require 'ostruct'
83
+ mock_conn = OpenStruct.new
84
+ size = 7 * 1024 * 1024
85
+ mock_conn.max_bson_size = size
86
+ assert_equal size, BSON_CODER.update_max_bson_size(mock_conn)
87
+ assert_equal size, BSON_CODER.max_bson_size
88
+ end
89
+
90
+ def test_round_trip
91
+ doc = {'doc' => 123}
92
+ @encoder.deserialize(@encoder.serialize(doc))
93
+ end
94
+
95
+ # In 1.8 we test that other string encodings raise an exception.
96
+ # In 1.9 we test that they get auto-converted.
97
+ if RUBY_VERSION < '1.9'
98
+ if ! RUBY_PLATFORM =~ /java/
99
+ require 'iconv'
100
+ def test_non_utf8_string
101
+ string = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
102
+ doc = {'doc' => string}
103
+ assert_doc_pass(doc)
104
+ assert_raise InvalidStringEncoding do
105
+ @encoder.serialize(doc)
106
+ end
107
+ end
108
+
109
+ def test_non_utf8_key
110
+ key = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
111
+ doc = {key => 'hello'}
112
+ assert_raise InvalidStringEncoding do
113
+ @encoder.serialize(doc)
114
+ end
115
+ end
116
+ end
117
+ else
118
+ def test_non_utf8_string
119
+ bson = BSON::BSON_CODER.serialize({'str' => 'aé'.encode('iso-8859-1')})
120
+ result = BSON::BSON_CODER.deserialize(bson)['str']
121
+ assert_equal 'aé', result
122
+ assert_equal 'UTF-8', result.encoding.name
123
+ end
124
+
125
+ def test_non_utf8_key
126
+ bson = BSON::BSON_CODER.serialize({'aé'.encode('iso-8859-1') => 'hello'})
127
+ assert_equal 'hello', BSON::BSON_CODER.deserialize(bson)['aé']
128
+ end
129
+
130
+ # Based on a test from sqlite3-ruby
131
+ def test_default_internal_is_honored
132
+ before_enc = Encoding.default_internal
133
+
134
+ str = "壁に耳あり、障子に目あり"
135
+ bson = BSON::BSON_CODER.serialize("x" => str)
136
+
137
+ Encoding.default_internal = 'EUC-JP'
138
+ out = BSON::BSON_CODER.deserialize(bson)["x"]
139
+
140
+ assert_equal Encoding.default_internal, out.encoding
141
+ assert_equal str.encode('EUC-JP'), out
142
+ assert_equal str, out.encode(str.encoding)
143
+ ensure
144
+ Encoding.default_internal = before_enc
145
+ end
146
+ end
147
+
148
+ def test_code
149
+ doc = {'$where' => Code.new('this.a.b < this.b')}
150
+ assert_doc_pass(doc)
151
+ end
152
+
153
+ def test_code_with_symbol
154
+ assert_raise_error ArgumentError, "BSON::Code must be in the form of a String" do
155
+ Code.new(:fubar)
156
+ end
157
+ end
158
+
159
+ def test_code_with_scope
160
+ doc = {'$where' => Code.new('this.a.b < this.b', {'foo' => 1})}
161
+ assert_doc_pass(doc)
162
+ end
163
+
164
+ def test_double
165
+ doc = {'doc' => 41.25}
166
+ assert_doc_pass(doc)
167
+ end
168
+
169
+ def test_int
170
+ doc = {'doc' => 42}
171
+ assert_doc_pass(doc)
172
+
173
+ doc = {"doc" => -5600}
174
+ assert_doc_pass(doc)
175
+
176
+ doc = {"doc" => 2147483647}
177
+ assert_doc_pass(doc)
178
+
179
+ doc = {"doc" => -2147483648}
180
+ assert_doc_pass(doc)
181
+ end
182
+
183
+ def test_ordered_hash
184
+ doc = BSON::OrderedHash.new
185
+ doc["b"] = 1
186
+ doc["a"] = 2
187
+ doc["c"] = 3
188
+ doc["d"] = 4
189
+ assert_doc_pass(doc)
190
+ end
191
+
192
+ def test_object
193
+ doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
194
+ assert_doc_pass(doc)
195
+ end
196
+
197
+ def test_embedded_document_with_nil
198
+ doc = {'doc' => {'age' => 42, 'name' => nil, 'shoe_size' => 9.5}}
199
+ assert_doc_pass(doc)
200
+ end
201
+
202
+ def test_embedded_document_with_date
203
+ doc = {'doc' => {'age' => 42, 'date' => Time.now.utc, 'shoe_size' => 9.5}}
204
+ bson = @encoder.serialize(doc)
205
+ doc2 = @encoder.deserialize(bson)
206
+ assert doc['doc']
207
+ assert_equal 42, doc['doc']['age']
208
+ assert_equal 9.5, doc['doc']['shoe_size']
209
+ assert_in_delta Time.now, doc['doc']['date'], 1
210
+ end
211
+
212
+ def test_oid
213
+ doc = {'doc' => ObjectId.new}
214
+ assert_doc_pass(doc)
215
+ end
216
+
217
+ def test_array
218
+ doc = {'doc' => [1, 2, 'a', 'b']}
219
+ assert_doc_pass(doc)
220
+ end
221
+
222
+ def test_array_keys
223
+ doc = {'doc' => [1, 2, 'a', 'b']}
224
+ bson = @encoder.serialize(doc).to_a
225
+ assert_equal 48, bson[14]
226
+ assert_equal 49, bson[21]
227
+ assert_equal 50, bson[28]
228
+ assert_equal 51, bson[37]
229
+ end
230
+
231
+ def test_regex
232
+ doc = {'doc' => /foobar/i}
233
+ assert_doc_pass(doc)
234
+ end
235
+
236
+ def test_boolean
237
+ doc = {'doc' => true}
238
+ assert_doc_pass(doc)
239
+ end
240
+
241
+ def test_date
242
+ doc = {'date' => Time.now}
243
+ bson = @encoder.serialize(doc)
244
+ doc2 = @encoder.deserialize(bson)
245
+ # Mongo only stores up to the millisecond
246
+ assert_in_delta doc['date'], doc2['date'], 0.001
247
+ end
248
+
249
+ def test_date_in_array
250
+ doc = {'date' => [Time.now.utc]}
251
+ bson = @encoder.serialize(doc)
252
+ doc2 = @encoder.deserialize(bson)
253
+ end
254
+
255
+ def test_date_returns_as_utc
256
+ doc = {'date' => Time.now.utc}
257
+ bson = @encoder.serialize(doc)
258
+ doc2 = @encoder.deserialize(bson)
259
+ assert doc2['date'].utc?
260
+ end
261
+
262
+ def test_date_before_epoch
263
+ begin
264
+ doc = {'date' => Time.utc(1600)}
265
+ bson = @encoder.serialize(doc)
266
+ doc2 = @encoder.deserialize(bson)
267
+ # Mongo only stores up to the millisecond
268
+ assert_in_delta doc['date'], doc2['date'], 2
269
+ rescue ArgumentError
270
+ # some versions of Ruby won't let you create pre-epoch Time instances
271
+ #
272
+ # TODO figure out how that will work if somebady has saved data
273
+ # w/ early dates already and is just querying for it.
274
+ end
275
+ end
276
+
277
+ def test_exeption_on_using_unsupported_date_class
278
+ [DateTime.now, Date.today, Zone].each do |invalid_date|
279
+ doc = {:date => invalid_date}
280
+ begin
281
+ bson = BSON::BSON_CODER.serialize(doc)
282
+ rescue => e
283
+ ensure
284
+ if !invalid_date.is_a? Time
285
+ assert_equal InvalidDocument, e.class
286
+ assert_match /UTC Time/, e.message
287
+ end
288
+ end
289
+ end
290
+ end
291
+
292
+ def test_dbref
293
+ oid = ObjectId.new
294
+ doc = {}
295
+ doc['dbref'] = DBRef.new('namespace', oid)
296
+ bson = @encoder.serialize(doc)
297
+ doc2 = @encoder.deserialize(bson)
298
+
299
+ # Java doesn't deserialize to DBRefs
300
+ if RUBY_PLATFORM =~ /java/
301
+ assert_equal 'namespace', doc2['dbref']['$ns']
302
+ assert_equal oid, doc2['dbref']['$id']
303
+ else
304
+ assert_equal 'namespace', doc2['dbref'].namespace
305
+ assert_equal oid, doc2['dbref'].object_id
306
+ end
307
+ end
308
+
309
+ def test_symbol
310
+ doc = {'sym' => :foo}
311
+ bson = @encoder.serialize(doc)
312
+ doc2 = @encoder.deserialize(bson)
313
+ assert_equal :foo, doc2['sym']
314
+ end
315
+
316
+ def test_binary
317
+ bin = Binary.new
318
+ 'binstring'.each_byte { |b| bin.put(b) }
319
+
320
+ doc = {'bin' => bin}
321
+ bson = @encoder.serialize(doc)
322
+ doc2 = @encoder.deserialize(bson)
323
+ bin2 = doc2['bin']
324
+ assert_kind_of Binary, bin2
325
+ assert_equal 'binstring', bin2.to_s
326
+ assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
327
+ end
328
+
329
+ def test_binary_with_string
330
+ b = Binary.new('somebinarystring')
331
+ doc = {'bin' => b}
332
+ bson = @encoder.serialize(doc)
333
+ doc2 = @encoder.deserialize(bson)
334
+ bin2 = doc2['bin']
335
+ assert_kind_of Binary, bin2
336
+ assert_equal 'somebinarystring', bin2.to_s
337
+ assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
338
+ end
339
+
340
+ def test_binary_type
341
+ bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_USER_DEFINED)
342
+
343
+ doc = {'bin' => bin}
344
+ bson = @encoder.serialize(doc)
345
+ doc2 = @encoder.deserialize(bson)
346
+ bin2 = doc2['bin']
347
+ assert_kind_of Binary, bin2
348
+ assert_equal [1, 2, 3, 4, 5], bin2.to_a
349
+ assert_equal Binary::SUBTYPE_USER_DEFINED, bin2.subtype
350
+ end
351
+
352
+ # Java doesn't support binary subtype 0 yet
353
+ if !(RUBY_PLATFORM =~ /java/)
354
+ def test_binary_subtype_0
355
+ bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_SIMPLE)
356
+
357
+ doc = {'bin' => bin}
358
+ bson = @encoder.serialize(doc)
359
+ doc2 = @encoder.deserialize(bson)
360
+ bin2 = doc2['bin']
361
+ assert_kind_of Binary, bin2
362
+ assert_equal [1, 2, 3, 4, 5], bin2.to_a
363
+ assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
364
+ end
365
+ end
366
+
367
+ def test_binary_byte_buffer
368
+ bb = Binary.new
369
+ 5.times { |i| bb.put(i + 1) }
370
+
371
+ doc = {'bin' => bb}
372
+ bson = @encoder.serialize(doc)
373
+ doc2 = @encoder.deserialize(bson)
374
+ bin2 = doc2['bin']
375
+ assert_kind_of Binary, bin2
376
+ assert_equal [1, 2, 3, 4, 5], bin2.to_a
377
+ assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
378
+ end
379
+
380
+ def test_put_id_first
381
+ val = BSON::OrderedHash.new
382
+ val['not_id'] = 1
383
+ val['_id'] = 2
384
+ roundtrip = @encoder.deserialize(@encoder.serialize(val, false, true).to_s)
385
+ assert_kind_of BSON::OrderedHash, roundtrip
386
+ assert_equal '_id', roundtrip.keys.first
387
+
388
+ val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
389
+ roundtrip = @encoder.deserialize(@encoder.serialize(val, false, true).to_s)
390
+ assert_kind_of BSON::OrderedHash, roundtrip
391
+ assert_equal '_id', roundtrip.keys.first
392
+ end
393
+
394
+ def test_nil_id
395
+ doc = {"_id" => nil}
396
+ assert_doc_pass(doc)
397
+ end
398
+
399
+ if !(RUBY_PLATFORM =~ /java/)
400
+ def test_timestamp
401
+ val = {"test" => [4, 20]}
402
+ assert_equal val, @encoder.deserialize([0x13, 0x00, 0x00, 0x00,
403
+ 0x11, 0x74, 0x65, 0x73,
404
+ 0x74, 0x00, 0x04, 0x00,
405
+ 0x00, 0x00, 0x14, 0x00,
406
+ 0x00, 0x00, 0x00])
407
+
408
+ end
409
+ end
410
+
411
+ def test_overflow
412
+ doc = {"x" => 2**75}
413
+ assert_raise RangeError do
414
+ bson = @encoder.serialize(doc)
415
+ end
416
+
417
+ doc = {"x" => 9223372036854775}
418
+ assert_doc_pass(doc)
419
+
420
+ doc = {"x" => 9223372036854775807}
421
+ assert_doc_pass(doc)
422
+
423
+ doc["x"] = doc["x"] + 1
424
+ assert_raise RangeError do
425
+ bson = @encoder.serialize(doc)
426
+ end
427
+
428
+ doc = {"x" => -9223372036854775}
429
+ assert_doc_pass(doc)
430
+
431
+ doc = {"x" => -9223372036854775808}
432
+ assert_doc_pass(doc)
433
+
434
+ doc["x"] = doc["x"] - 1
435
+ assert_raise RangeError do
436
+ bson = BSON::BSON_CODER.serialize(doc)
437
+ end
438
+ end
439
+
440
+ def test_invalid_numeric_types
441
+ [BigDecimal.new("1.0"), Complex(0, 1), Rational(2, 3)].each do |type|
442
+ doc = {"x" => type}
443
+ begin
444
+ @encoder.serialize(doc)
445
+ rescue => e
446
+ ensure
447
+ assert_equal InvalidDocument, e.class
448
+ assert_match /Cannot serialize/, e.message
449
+ end
450
+ end
451
+ end
452
+
453
+ def test_do_not_change_original_object
454
+ val = BSON::OrderedHash.new
455
+ val['not_id'] = 1
456
+ val['_id'] = 2
457
+ assert val.keys.include?('_id')
458
+ @encoder.serialize(val)
459
+ assert val.keys.include?('_id')
460
+
461
+ val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
462
+ assert val.keys.include?(:_id)
463
+ @encoder.serialize(val)
464
+ assert val.keys.include?(:_id)
465
+ end
466
+
467
+ # note we only test for _id here because in the general case we will
468
+ # write duplicates for :key and "key". _id is a special case because
469
+ # we call has_key? to check for it's existence rather than just iterating
470
+ # over it like we do for the rest of the keys. thus, things like
471
+ # HashWithIndifferentAccess can cause problems for _id but not for other
472
+ # keys. rather than require rails to test with HWIA directly, we do this
473
+ # somewhat hacky test.
474
+ #
475
+ # Note that the driver only eliminates duplicate ids when move_id is true.
476
+ def test_no_duplicate_id
477
+ dup = {"_id" => "foo", :_id => "foo"}
478
+ one = {"_id" => "foo"}
479
+
480
+ assert_equal @encoder.serialize(one, false, true).to_a, @encoder.serialize(dup, false, true).to_a
481
+ end
482
+
483
+ def test_duplicate_keys
484
+ #dup = {"_foo" => "foo", :_foo => "foo"}
485
+ #one = {"_foo" => "foo"}
486
+
487
+ #assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a
488
+ warn "Pending test for duplicate keys"
489
+ end
490
+
491
+ def test_no_duplicate_id_when_moving_id
492
+ dup = {"_id" => "foo", :_id => "foo"}
493
+ one = {:_id => "foo"}
494
+
495
+ assert_equal @encoder.serialize(one, false, true).to_s, @encoder.serialize(dup, false, true).to_s
496
+ end
497
+
498
+ def test_null_character
499
+ doc = {"a" => "\x00"}
500
+
501
+ assert_doc_pass(doc)
502
+
503
+ assert_raise InvalidDocument do
504
+ @encoder.serialize({"\x00" => "a"})
505
+ end
506
+
507
+ assert_raise InvalidDocument do
508
+ @encoder.serialize({"a" => (Regexp.compile "ab\x00c")})
509
+ end
510
+ end
511
+
512
+ def test_max_key
513
+ doc = {"a" => MaxKey.new}
514
+ assert_doc_pass(doc)
515
+ end
516
+
517
+ def test_min_key
518
+ doc = {"a" => MinKey.new}
519
+ assert_doc_pass(doc)
520
+ end
521
+
522
+ def test_invalid_object
523
+ o = Object.new
524
+ assert_raise InvalidDocument do
525
+ @encoder.serialize({:foo => o})
526
+ end
527
+
528
+ assert_raise InvalidDocument do
529
+ @encoder.serialize({:foo => Date.today})
530
+ end
531
+ end
532
+
533
+ def test_move_id
534
+ a = BSON::OrderedHash.new
535
+ a['text'] = 'abc'
536
+ a['key'] = 'abc'
537
+ a['_id'] = 1
538
+
539
+
540
+ assert_equal ")\000\000\000\020_id\000\001\000\000\000\002text" +
541
+ "\000\004\000\000\000abc\000\002key\000\004\000\000\000abc\000\000",
542
+ @encoder.serialize(a, false, true).to_s
543
+
544
+ assert_equal ")\000\000\000\002text\000\004\000\000\000abc\000\002key" +
545
+ "\000\004\000\000\000abc\000\020_id\000\001\000\000\000\000",
546
+ @encoder.serialize(a, false, false).to_s
547
+ end
548
+
549
+ def test_move_id_with_nested_doc
550
+ b = BSON::OrderedHash.new
551
+ b['text'] = 'abc'
552
+ b['_id'] = 2
553
+ c = BSON::OrderedHash.new
554
+ c['text'] = 'abc'
555
+ c['hash'] = b
556
+ c['_id'] = 3
557
+ assert_equal ">\000\000\000\020_id\000\003\000\000\000\002text" +
558
+ "\000\004\000\000\000abc\000\003hash\000\034\000\000" +
559
+ "\000\002text\000\004\000\000\000abc\000\020_id\000\002\000\000\000\000\000",
560
+ @encoder.serialize(c, false, true).to_s
561
+
562
+ # Java doesn't support this. Isn't actually necessary.
563
+ if !(RUBY_PLATFORM =~ /java/)
564
+ assert_equal ">\000\000\000\002text\000\004\000\000\000abc\000\003hash" +
565
+ "\000\034\000\000\000\002text\000\004\000\000\000abc\000\020_id" +
566
+ "\000\002\000\000\000\000\020_id\000\003\000\000\000\000",
567
+ @encoder.serialize(c, false, false).to_s
568
+ end
569
+ end
570
+
571
+ def test_invalid_key_names
572
+ assert @encoder.serialize({"hello" => "world"}, true)
573
+ assert @encoder.serialize({"hello" => {"hello" => "world"}}, true)
574
+
575
+ assert @encoder.serialize({"he$llo" => "world"}, true)
576
+ assert @encoder.serialize({"hello" => {"hell$o" => "world"}}, true)
577
+
578
+ assert_raise BSON::InvalidDocument do
579
+ @encoder.serialize({"he\0llo" => "world"}, true)
580
+ end
581
+
582
+ assert_raise BSON::InvalidKeyName do
583
+ @encoder.serialize({"$hello" => "world"}, true)
584
+ end
585
+
586
+ assert_raise BSON::InvalidKeyName do
587
+ @encoder.serialize({"hello" => {"$hello" => "world"}}, true)
588
+ end
589
+
590
+ assert_raise BSON::InvalidKeyName do
591
+ @encoder.serialize({".hello" => "world"}, true)
592
+ end
593
+
594
+ assert_raise BSON::InvalidKeyName do
595
+ @encoder.serialize({"hello" => {".hello" => "world"}}, true)
596
+ end
597
+
598
+ assert_raise BSON::InvalidKeyName do
599
+ @encoder.serialize({"hello." => "world"}, true)
600
+ end
601
+
602
+ assert_raise BSON::InvalidKeyName do
603
+ @encoder.serialize({"hello" => {"hello." => "world"}}, true)
604
+ end
605
+
606
+ assert_raise BSON::InvalidKeyName do
607
+ @encoder.serialize({"hel.lo" => "world"}, true)
608
+ end
609
+
610
+ assert_raise BSON::InvalidKeyName do
611
+ @encoder.serialize({"hello" => {"hel.lo" => "world"}}, true)
612
+ end
613
+ end
614
+ end