bson 1.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bson might be problematic. Click here for more details.

data/Rakefile CHANGED
@@ -26,8 +26,8 @@ namespace :build do
26
26
  jar_dir = File.join(java_dir, 'jar')
27
27
 
28
28
  jruby_jar = File.join(jar_dir, 'jruby.jar')
29
- mongo_jar = File.join(jar_dir, 'mongo.jar')
30
- bson_jar = File.join(jar_dir, 'bson.jar')
29
+ mongo_jar = File.join(jar_dir, 'mongo-2.2.jar')
30
+ bson_jar = File.join(jar_dir, 'bson-2.2.jar')
31
31
 
32
32
  src_base = File.join(java_dir, 'src')
33
33
 
@@ -65,7 +65,7 @@ namespace :test do
65
65
  Rake::Task['test:pooled_threading'].invoke
66
66
  Rake::Task['test:drop_databases'].invoke
67
67
  end
68
-
68
+
69
69
  Rake::TestTask.new(:unit) do |t|
70
70
  t.test_files = FileList['test/unit/*_test.rb']
71
71
  t.verbose = true
@@ -142,7 +142,7 @@ namespace :test do
142
142
  end
143
143
 
144
144
  Rake::TestTask.new(:bson) do |t|
145
- t.test_files = FileList['test/mongo_bson/*_test.rb']
145
+ t.test_files = FileList['test/bson/*_test.rb']
146
146
  t.verbose = true
147
147
  end
148
148
 
@@ -172,12 +172,6 @@ task :ydoc do
172
172
  system "yardoc lib/**/*.rb lib/mongo/**/*.rb lib/bson/**/*.rb -e docs/yard_ext.rb -p docs/templates -o #{out} --title MongoRuby-#{Mongo::VERSION}"
173
173
  end
174
174
 
175
- desc "Publish documentation to mongo.rubyforge.org"
176
- task :publish => [:rdoc] do
177
- # Assumes docs are in ./html
178
- Rake::RubyForgePublisher.new(GEM, RUBYFORGE_USER).upload
179
- end
180
-
181
175
  namespace :gem do
182
176
 
183
177
  desc "Install the gem locally"
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.files += ['lib/bson.rb'] + Dir['lib/bson/**/*.rb']
16
16
  s.files += ['bin/b2json', 'bin/j2bson']
17
17
  s.files += Dir['ext/java/jar/**/*.jar']
18
- s.test_files = Dir['test/mongo_bson/*.rb']
18
+ s.test_files = Dir['test/bson/*.rb']
19
19
 
20
20
  s.executables = ['b2json', 'j2bson']
21
21
 
Binary file
Binary file
@@ -2,10 +2,10 @@
2
2
 
3
3
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
4
 
5
- MINIMUM_BSON_EXT_VERSION = "1.1"
5
+ MINIMUM_BSON_EXT_VERSION = "1.1.1"
6
6
 
7
7
  module BSON
8
- VERSION = "1.1"
8
+ VERSION = "1.1.1"
9
9
  def self.serialize(obj, check_keys=false, move_id=false)
10
10
  BSON_CODER.serialize(obj, check_keys, move_id)
11
11
  end
@@ -34,8 +34,8 @@ end
34
34
 
35
35
  if RUBY_PLATFORM =~ /java/
36
36
  jar_dir = File.join(File.dirname(__FILE__), '..', 'ext', 'java', 'jar')
37
- require File.join(jar_dir, 'mongo.jar')
38
- require File.join(jar_dir, 'bson.jar')
37
+ require File.join(jar_dir, 'mongo-2.2.jar')
38
+ require File.join(jar_dir, 'bson-2.2.jar')
39
39
  require File.join(jar_dir, 'jbson.jar')
40
40
  require 'bson/bson_java'
41
41
  module BSON
@@ -6,7 +6,7 @@ module BSON
6
6
  # we don't create a new one on each call to #serialize.
7
7
  def self.serialize(obj, check_keys=false, move_id=false)
8
8
  raise InvalidDocument, "BSON_JAVA.serialize takes a Hash" unless obj.is_a?(Hash)
9
- enc = Java::OrgJbson::RubyBSONEncoder.new(JRuby.runtime)
9
+ enc = Java::OrgJbson::RubyBSONEncoder.new(JRuby.runtime, check_keys, move_id)
10
10
  ByteBuffer.new(enc.encode(obj))
11
11
  end
12
12
 
@@ -23,15 +23,19 @@ module BSON
23
23
  attr_reader :order
24
24
 
25
25
  def initialize(initial_data="")
26
- if initial_data.is_a?(String)
27
- if initial_data.respond_to?(:force_encoding)
28
- @str = initial_data.force_encoding('binary')
26
+ @str = case initial_data
27
+ when String then
28
+ if initial_data.respond_to?(:force_encoding)
29
+ initial_data.force_encoding('binary')
30
+ else
31
+ initial_data
32
+ end
33
+ when BSON::ByteBuffer then
34
+ initial_data.to_a.pack('C*')
29
35
  else
30
- @str = initial_data
31
- end
32
- else
33
- @str = initial_data.pack('C*')
36
+ initial_data.pack('C*')
34
37
  end
38
+
35
39
  @cursor = @str.length
36
40
  @order = :little_endian
37
41
  @int_pack_order = 'V'
@@ -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,535 @@
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_document_length
71
+ doc = {'name' => 'a' * 5 * 1024 * 1024}
72
+ assert_raise InvalidDocument do
73
+ assert @encoder.serialize(doc)
74
+ end
75
+ end
76
+
77
+ def test_round_trip
78
+ doc = {'doc' => 123}
79
+ @encoder.deserialize(@encoder.serialize(doc))
80
+ end
81
+
82
+ # In 1.8 we test that other string encodings raise an exception.
83
+ # In 1.9 we test that they get auto-converted.
84
+ if RUBY_VERSION < '1.9'
85
+ if ! RUBY_PLATFORM =~ /java/
86
+ require 'iconv'
87
+ def test_non_utf8_string
88
+ string = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
89
+ doc = {'doc' => string}
90
+ assert_doc_pass(doc)
91
+ assert_raise InvalidStringEncoding do
92
+ @encoder.serialize(doc)
93
+ end
94
+ end
95
+
96
+ def test_non_utf8_key
97
+ key = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
98
+ doc = {key => 'hello'}
99
+ assert_raise InvalidStringEncoding do
100
+ @encoder.serialize(doc)
101
+ end
102
+ end
103
+ end
104
+ else
105
+ def test_non_utf8_string
106
+ bson = BSON::BSON_CODER.serialize({'str' => 'aé'.encode('iso-8859-1')})
107
+ result = BSON::BSON_CODER.deserialize(bson)['str']
108
+ assert_equal 'aé', result
109
+ assert_equal 'UTF-8', result.encoding.name
110
+ end
111
+
112
+ def test_non_utf8_key
113
+ bson = BSON::BSON_CODER.serialize({'aé'.encode('iso-8859-1') => 'hello'})
114
+ assert_equal 'hello', BSON::BSON_CODER.deserialize(bson)['aé']
115
+ end
116
+
117
+ # Based on a test from sqlite3-ruby
118
+ def test_default_internal_is_honored
119
+ before_enc = Encoding.default_internal
120
+
121
+ str = "壁に耳あり、障子に目あり"
122
+ bson = BSON::BSON_CODER.serialize("x" => str)
123
+
124
+ Encoding.default_internal = 'EUC-JP'
125
+ out = BSON::BSON_CODER.deserialize(bson)["x"]
126
+
127
+ assert_equal Encoding.default_internal, out.encoding
128
+ assert_equal str.encode('EUC-JP'), out
129
+ assert_equal str, out.encode(str.encoding)
130
+ ensure
131
+ Encoding.default_internal = before_enc
132
+ end
133
+ end
134
+
135
+ def test_code
136
+ doc = {'$where' => Code.new('this.a.b < this.b')}
137
+ assert_doc_pass(doc)
138
+ end
139
+
140
+ def test_code_with_scope
141
+ doc = {'$where' => Code.new('this.a.b < this.b', {'foo' => 1})}
142
+ assert_doc_pass(doc)
143
+ end
144
+
145
+ def test_double
146
+ doc = {'doc' => 41.25}
147
+ assert_doc_pass(doc)
148
+ end
149
+
150
+ def test_int
151
+ doc = {'doc' => 42}
152
+ assert_doc_pass(doc)
153
+
154
+ doc = {"doc" => -5600}
155
+ assert_doc_pass(doc)
156
+
157
+ doc = {"doc" => 2147483647}
158
+ assert_doc_pass(doc)
159
+
160
+ doc = {"doc" => -2147483648}
161
+ assert_doc_pass(doc)
162
+ end
163
+
164
+ def test_ordered_hash
165
+ doc = BSON::OrderedHash.new
166
+ doc["b"] = 1
167
+ doc["a"] = 2
168
+ doc["c"] = 3
169
+ doc["d"] = 4
170
+ assert_doc_pass(doc)
171
+ end
172
+
173
+ def test_object
174
+ doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
175
+ assert_doc_pass(doc)
176
+ end
177
+
178
+ def test_embedded_document_with_nil
179
+ doc = {'doc' => {'age' => 42, 'name' => nil, 'shoe_size' => 9.5}}
180
+ assert_doc_pass(doc)
181
+ end
182
+
183
+ def test_embedded_document_with_date
184
+ doc = {'doc' => {'age' => 42, 'date' => Time.now.utc, 'shoe_size' => 9.5}}
185
+ bson = @encoder.serialize(doc)
186
+ doc2 = @encoder.deserialize(bson)
187
+ assert doc['doc']
188
+ assert_equal 42, doc['doc']['age']
189
+ assert_equal 9.5, doc['doc']['shoe_size']
190
+ assert_in_delta Time.now, doc['doc']['date'], 1
191
+ end
192
+
193
+ def test_oid
194
+ doc = {'doc' => ObjectId.new}
195
+ assert_doc_pass(doc)
196
+ end
197
+
198
+ def test_array
199
+ doc = {'doc' => [1, 2, 'a', 'b']}
200
+ assert_doc_pass(doc)
201
+ end
202
+
203
+ def test_regex
204
+ doc = {'doc' => /foobar/i}
205
+ assert_doc_pass(doc)
206
+ end
207
+
208
+ def test_boolean
209
+ doc = {'doc' => true}
210
+ assert_doc_pass(doc)
211
+ end
212
+
213
+ def test_date
214
+ doc = {'date' => Time.now}
215
+ bson = @encoder.serialize(doc)
216
+ doc2 = @encoder.deserialize(bson)
217
+ # Mongo only stores up to the millisecond
218
+ assert_in_delta doc['date'], doc2['date'], 0.001
219
+ end
220
+
221
+ def test_date_returns_as_utc
222
+ doc = {'date' => Time.now}
223
+ bson = @encoder.serialize(doc)
224
+ doc2 = @encoder.deserialize(bson)
225
+ assert doc2['date'].utc?
226
+ end
227
+
228
+ def test_date_before_epoch
229
+ begin
230
+ doc = {'date' => Time.utc(1600)}
231
+ bson = @encoder.serialize(doc)
232
+ doc2 = @encoder.deserialize(bson)
233
+ # Mongo only stores up to the millisecond
234
+ assert_in_delta doc['date'], doc2['date'], 2
235
+ rescue ArgumentError
236
+ # some versions of Ruby won't let you create pre-epoch Time instances
237
+ #
238
+ # TODO figure out how that will work if somebady has saved data
239
+ # w/ early dates already and is just querying for it.
240
+ end
241
+ end
242
+
243
+ def test_exeption_on_using_unsupported_date_class
244
+ [DateTime.now, Date.today, Zone].each do |invalid_date|
245
+ doc = {:date => invalid_date}
246
+ begin
247
+ bson = BSON::BSON_CODER.serialize(doc)
248
+ rescue => e
249
+ ensure
250
+ if !invalid_date.is_a? Time
251
+ assert_equal InvalidDocument, e.class
252
+ assert_match /UTC Time/, e.message
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ def test_dbref
259
+ oid = ObjectId.new
260
+ doc = {}
261
+ doc['dbref'] = DBRef.new('namespace', oid)
262
+ bson = @encoder.serialize(doc)
263
+ doc2 = @encoder.deserialize(bson)
264
+
265
+ # Java doesn't deserialize to DBRefs
266
+ if RUBY_PLATFORM =~ /java/
267
+ assert_equal 'namespace', doc2['dbref']['$ns']
268
+ assert_equal oid, doc2['dbref']['$id']
269
+ else
270
+ assert_equal 'namespace', doc2['dbref'].namespace
271
+ assert_equal oid, doc2['dbref'].object_id
272
+ end
273
+ end
274
+
275
+ def test_symbol
276
+ doc = {'sym' => :foo}
277
+ bson = @encoder.serialize(doc)
278
+ doc2 = @encoder.deserialize(bson)
279
+ assert_equal :foo, doc2['sym']
280
+ end
281
+
282
+ def test_binary
283
+ bin = Binary.new
284
+ 'binstring'.each_byte { |b| bin.put(b) }
285
+
286
+ doc = {'bin' => bin}
287
+ bson = @encoder.serialize(doc)
288
+ doc2 = @encoder.deserialize(bson)
289
+ bin2 = doc2['bin']
290
+ assert_kind_of Binary, bin2
291
+ assert_equal 'binstring', bin2.to_s
292
+ assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
293
+ end
294
+
295
+ def test_binary_with_string
296
+ b = Binary.new('somebinarystring')
297
+ doc = {'bin' => b}
298
+ bson = @encoder.serialize(doc)
299
+ doc2 = @encoder.deserialize(bson)
300
+ bin2 = doc2['bin']
301
+ assert_kind_of Binary, bin2
302
+ assert_equal 'somebinarystring', bin2.to_s
303
+ assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
304
+ end
305
+
306
+ def test_binary_type
307
+ bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_USER_DEFINED)
308
+
309
+ doc = {'bin' => bin}
310
+ bson = @encoder.serialize(doc)
311
+ doc2 = @encoder.deserialize(bson)
312
+ bin2 = doc2['bin']
313
+ assert_kind_of Binary, bin2
314
+ assert_equal [1, 2, 3, 4, 5], bin2.to_a
315
+ assert_equal Binary::SUBTYPE_USER_DEFINED, bin2.subtype
316
+ end
317
+
318
+ # Java doesn't support binary subtype 0 yet
319
+ if !(RUBY_PLATFORM =~ /java/)
320
+ def test_binary_subtype_0
321
+ bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_SIMPLE)
322
+
323
+ doc = {'bin' => bin}
324
+ bson = @encoder.serialize(doc)
325
+ doc2 = @encoder.deserialize(bson)
326
+ bin2 = doc2['bin']
327
+ assert_kind_of Binary, bin2
328
+ assert_equal [1, 2, 3, 4, 5], bin2.to_a
329
+ assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
330
+ end
331
+ end
332
+
333
+ def test_binary_byte_buffer
334
+ bb = Binary.new
335
+ 5.times { |i| bb.put(i + 1) }
336
+
337
+ doc = {'bin' => bb}
338
+ bson = @encoder.serialize(doc)
339
+ doc2 = @encoder.deserialize(bson)
340
+ bin2 = doc2['bin']
341
+ assert_kind_of Binary, bin2
342
+ assert_equal [1, 2, 3, 4, 5], bin2.to_a
343
+ assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
344
+ end
345
+
346
+ def test_put_id_first
347
+ val = BSON::OrderedHash.new
348
+ val['not_id'] = 1
349
+ val['_id'] = 2
350
+ roundtrip = @encoder.deserialize(@encoder.serialize(val, false, true).to_s)
351
+ assert_kind_of BSON::OrderedHash, roundtrip
352
+ assert_equal '_id', roundtrip.keys.first
353
+
354
+ val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
355
+ roundtrip = @encoder.deserialize(@encoder.serialize(val, false, true).to_s)
356
+ assert_kind_of BSON::OrderedHash, roundtrip
357
+ assert_equal '_id', roundtrip.keys.first
358
+ end
359
+
360
+ def test_nil_id
361
+ doc = {"_id" => nil}
362
+ assert_doc_pass(doc)
363
+ end
364
+
365
+ if !(RUBY_PLATFORM =~ /java/)
366
+ def test_timestamp
367
+ val = {"test" => [4, 20]}
368
+ assert_equal val, @encoder.deserialize([0x13, 0x00, 0x00, 0x00,
369
+ 0x11, 0x74, 0x65, 0x73,
370
+ 0x74, 0x00, 0x04, 0x00,
371
+ 0x00, 0x00, 0x14, 0x00,
372
+ 0x00, 0x00, 0x00])
373
+
374
+ end
375
+ end
376
+
377
+ def test_overflow
378
+ doc = {"x" => 2**75}
379
+ assert_raise RangeError do
380
+ bson = @encoder.serialize(doc)
381
+ end
382
+
383
+ doc = {"x" => 9223372036854775}
384
+ assert_doc_pass(doc)
385
+
386
+ doc = {"x" => 9223372036854775807}
387
+ assert_doc_pass(doc)
388
+
389
+ doc["x"] = doc["x"] + 1
390
+ assert_raise RangeError do
391
+ bson = @encoder.serialize(doc)
392
+ end
393
+
394
+ doc = {"x" => -9223372036854775}
395
+ assert_doc_pass(doc)
396
+
397
+ doc = {"x" => -9223372036854775808}
398
+ assert_doc_pass(doc)
399
+
400
+ doc["x"] = doc["x"] - 1
401
+ assert_raise RangeError do
402
+ bson = BSON::BSON_CODER.serialize(doc)
403
+ end
404
+ end
405
+
406
+ def test_invalid_numeric_types
407
+ [BigDecimal.new("1.0"), Complex(0, 1), Rational(2, 3)].each do |type|
408
+ doc = {"x" => type}
409
+ begin
410
+ @encoder.serialize(doc)
411
+ rescue => e
412
+ ensure
413
+ assert_equal InvalidDocument, e.class
414
+ assert_match /Cannot serialize/, e.message
415
+ end
416
+ end
417
+ end
418
+
419
+ def test_do_not_change_original_object
420
+ val = BSON::OrderedHash.new
421
+ val['not_id'] = 1
422
+ val['_id'] = 2
423
+ assert val.keys.include?('_id')
424
+ @encoder.serialize(val)
425
+ assert val.keys.include?('_id')
426
+
427
+ val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
428
+ assert val.keys.include?(:_id)
429
+ @encoder.serialize(val)
430
+ assert val.keys.include?(:_id)
431
+ end
432
+
433
+ # note we only test for _id here because in the general case we will
434
+ # write duplicates for :key and "key". _id is a special case because
435
+ # we call has_key? to check for it's existence rather than just iterating
436
+ # over it like we do for the rest of the keys. thus, things like
437
+ # HashWithIndifferentAccess can cause problems for _id but not for other
438
+ # keys. rather than require rails to test with HWIA directly, we do this
439
+ # somewhat hacky test.
440
+ def test_no_duplicate_id
441
+ dup = {"_id" => "foo", :_id => "foo"}
442
+ one = {"_id" => "foo"}
443
+
444
+ assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a
445
+ end
446
+
447
+ def test_duplicate_keys
448
+ #dup = {"_foo" => "foo", :_foo => "foo"}
449
+ #one = {"_foo" => "foo"}
450
+
451
+ #assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a
452
+ warn "Pending test for duplicate keys"
453
+ end
454
+
455
+ def test_no_duplicate_id_when_moving_id
456
+ dup = {"_id" => "foo", :_id => "foo"}
457
+ one = {:_id => "foo"}
458
+
459
+ assert_equal @encoder.serialize(one, false, true).to_s, @encoder.serialize(dup, false, true).to_s
460
+ end
461
+
462
+ def test_null_character
463
+ doc = {"a" => "\x00"}
464
+
465
+ assert_doc_pass(doc)
466
+
467
+ assert_raise InvalidDocument do
468
+ @encoder.serialize({"\x00" => "a"})
469
+ end
470
+
471
+ assert_raise InvalidDocument do
472
+ @encoder.serialize({"a" => (Regexp.compile "ab\x00c")})
473
+ end
474
+ end
475
+
476
+ def test_max_key
477
+ doc = {"a" => MaxKey.new}
478
+ assert_doc_pass(doc)
479
+ end
480
+
481
+ def test_min_key
482
+ doc = {"a" => MinKey.new}
483
+ assert_doc_pass(doc)
484
+ end
485
+
486
+ def test_invalid_object
487
+ o = Object.new
488
+ assert_raise InvalidDocument do
489
+ @encoder.serialize({:foo => o})
490
+ end
491
+
492
+ assert_raise InvalidDocument do
493
+ @encoder.serialize({:foo => Date.today})
494
+ end
495
+ end
496
+
497
+ def test_move_id
498
+ a = BSON::OrderedHash.new
499
+ a['text'] = 'abc'
500
+ a['key'] = 'abc'
501
+ a['_id'] = 1
502
+
503
+
504
+ assert_equal ")\000\000\000\020_id\000\001\000\000\000\002text" +
505
+ "\000\004\000\000\000abc\000\002key\000\004\000\000\000abc\000\000",
506
+ @encoder.serialize(a, false, true).to_s
507
+
508
+ assert_equal ")\000\000\000\002text\000\004\000\000\000abc\000\002key" +
509
+ "\000\004\000\000\000abc\000\020_id\000\001\000\000\000\000",
510
+ @encoder.serialize(a, false, false).to_s
511
+ end
512
+
513
+ def test_move_id_with_nested_doc
514
+ b = BSON::OrderedHash.new
515
+ b['text'] = 'abc'
516
+ b['_id'] = 2
517
+ c = BSON::OrderedHash.new
518
+ c['text'] = 'abc'
519
+ c['hash'] = b
520
+ c['_id'] = 3
521
+ assert_equal ">\000\000\000\020_id\000\003\000\000\000\002text" +
522
+ "\000\004\000\000\000abc\000\003hash\000\034\000\000" +
523
+ "\000\002text\000\004\000\000\000abc\000\020_id\000\002\000\000\000\000\000",
524
+ @encoder.serialize(c, false, true).to_s
525
+
526
+ # Java doesn't support this. Isn't actually necessary.
527
+ if !(RUBY_PLATFORM =~ /java/)
528
+ assert_equal ">\000\000\000\002text\000\004\000\000\000abc\000\003hash" +
529
+ "\000\034\000\000\000\002text\000\004\000\000\000abc\000\020_id" +
530
+ "\000\002\000\000\000\000\020_id\000\003\000\000\000\000",
531
+ @encoder.serialize(c, false, false).to_s
532
+ end
533
+ end
534
+
535
+ end