mongo-lyon 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
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