Encoder number handling cleanup

This commit is contained in:
Kyle Banker 2010-10-01 16:29:31 -04:00
parent 694f011087
commit 3b5aac6de6
4 changed files with 162 additions and 180 deletions

Binary file not shown.

View File

@ -207,7 +207,7 @@ public class RubyBSONEncoder extends BSONEncoder {
return _buf.getPosition() - start; return _buf.getPosition() - start;
} }
protected void _putObjectField( String name , Object val ){ protected void _putObjectField( String name , Object val ) {
if ( name.equals( "_transientFields" ) ) if ( name.equals( "_transientFields" ) )
return; return;
@ -217,7 +217,7 @@ public class RubyBSONEncoder extends BSONEncoder {
System.out.println( "\t class : " + val.getClass().getName() ); System.out.println( "\t class : " + val.getClass().getName() );
} }
if ( name.equals( "$where") && val instanceof String ){ if ( name.equals( "$where") && val instanceof String ) {
_put( CODE , name ); _put( CODE , name );
_putValueString( val.toString() ); _putValueString( val.toString() );
return; return;
@ -227,10 +227,21 @@ public class RubyBSONEncoder extends BSONEncoder {
putString(name, val.toString() ); putString(name, val.toString() );
else if ( val instanceof Number ) { else if ( val instanceof Number ) {
if (((Number)val).longValue() >= Integer.MIN_VALUE && ((Number)val).longValue() <= Integer.MAX_VALUE) if ( ( val instanceof Float ) || ( val instanceof Double ) ) {
putNumber(name, ((Number)val).intValue() ); _put( NUMBER , name );
else _buf.writeDouble( ((Number)val).doubleValue() );
putNumber(name, (Number)val ); }
else {
long longVal = ((Number)val).longValue();
if (longVal >= Integer.MIN_VALUE && longVal <= Integer.MAX_VALUE) {
_put( NUMBER_INT , name );
_buf.writeInt( (int)longVal );
}
else {
_put( NUMBER_LONG , name );
_buf.writeLong( longVal );
}
}
} }
else if ( val instanceof Boolean ) else if ( val instanceof Boolean )
@ -260,16 +271,22 @@ public class RubyBSONEncoder extends BSONEncoder {
else if ( val instanceof RubyFixnum ) { else if ( val instanceof RubyFixnum ) {
long jval = ((RubyFixnum)val).getLongValue(); long jval = ((RubyFixnum)val).getLongValue();
if (jval >= Integer.MIN_VALUE && jval <= Integer.MAX_VALUE) { if (jval >= Integer.MIN_VALUE && jval <= Integer.MAX_VALUE) {
putNumber(name, (int)jval ); _put( NUMBER_INT , name );
_buf.writeInt( (int)jval );
}
else {
_put( NUMBER_LONG , name );
_buf.writeLong( jval );
} }
else
putNumber(name, (Number)jval );
} }
else if ( val instanceof RubyFloat ) { else if ( val instanceof RubyFloat ) {
double jval = ((RubyFloat)val).getValue(); double doubleValue = ((RubyFloat)val).getValue();
putNumber(name, (Number)jval );
_put( NUMBER , name );
_buf.writeDouble( doubleValue );
} }
else if ( val instanceof JavaProxy ) { else if ( val instanceof JavaProxy ) {
@ -286,9 +303,8 @@ public class RubyBSONEncoder extends BSONEncoder {
else if ( val instanceof RubyNil ) else if ( val instanceof RubyNil )
putNull(name); putNull(name);
else if ( val instanceof RubyTime ) { else if ( val instanceof RubyTime )
putDate( name , ((RubyTime)val).getDateTime().getMillis() ); putDate( name , ((RubyTime)val).getDateTime().getMillis() );
}
else if ( val instanceof RubyBoolean ) else if ( val instanceof RubyBoolean )
putBoolean(name, (Boolean)((RubyBoolean)val).toJava(Boolean.class)); putBoolean(name, (Boolean)((RubyBoolean)val).toJava(Boolean.class));
@ -303,7 +319,7 @@ public class RubyBSONEncoder extends BSONEncoder {
} }
else { else {
long jval = big.longValue(); long jval = big.longValue();
putNumber(name, (Number)jval ); putLong(name, (Number)jval );
} }
} }
@ -446,25 +462,6 @@ public class RubyBSONEncoder extends BSONEncoder {
_buf.writeLong( millis ); _buf.writeLong( millis );
} }
protected void putNumber( String name , Number n ){
if ( n instanceof Integer ||
n instanceof Short ||
n instanceof Byte ||
n instanceof AtomicInteger ){
_put( NUMBER_INT , name );
_buf.writeInt( n.intValue() );
}
else if ( n instanceof Long ||
n instanceof AtomicLong ) {
_put( NUMBER_LONG , name );
_buf.writeLong( n.longValue() );
}
else {
_put( NUMBER , name );
_buf.writeDouble( n.doubleValue() );
}
}
private void putRubyBinary( String name , RubyObject binary ) { private void putRubyBinary( String name , RubyObject binary ) {
RubyArray rarray = (RubyArray)JavaEmbedUtils.invokeMethod(_runtime, RubyArray rarray = (RubyArray)JavaEmbedUtils.invokeMethod(_runtime,
binary, "to_a", new Object[] {}, Object.class); binary, "to_a", new Object[] {}, Object.class);

View File

@ -21,6 +21,25 @@ class BSONTest < Test::Unit::TestCase
include BSON include BSON
# This setup allows us to change the decoders for
# cross-coder compatibility testing
def setup
@encoder = BSON::BSON_CODER
@decoder = @encoder
end
def assert_doc_pass(doc, options={})
bson = @encoder.serialize(doc)
if options[:debug]
puts "DEBUGGIN DOC:"
p bson.to_a
puts "DESERIALIZES TO:"
p @decoder.deserialize(bson)
end
assert_equal @decoder.serialize(doc).to_a, bson.to_a
assert_equal doc, @decoder.deserialize(bson)
end
def test_require_hash def test_require_hash
assert_raise_error InvalidDocument, "takes a Hash" do assert_raise_error InvalidDocument, "takes a Hash" do
BSON.serialize('foo') BSON.serialize('foo')
@ -35,56 +54,25 @@ class BSONTest < Test::Unit::TestCase
end end
end end
def test_read_bson_io_document
doc = {'doc' => 'hello, world'}
bson = BSON.serialize(doc)
io = StringIO.new
io.write(bson.to_s)
io.rewind
assert_equal BSON.deserialize(bson), BSON.read_bson_document(io)
end
def test_serialize_returns_byte_buffer
doc = {'doc' => 'hello, world'}
bson = BSON.serialize(doc)
assert bson.is_a?(ByteBuffer)
end
def test_deserialize_from_string
doc = {'doc' => 'hello, world'}
bson = BSON.serialize(doc)
string = bson.to_s
assert_equal doc, BSON.deserialize(string)
end
def test_deprecated_bson_module
doc = {'doc' => 'hello, world'}
bson = BSON.serialize(doc)
assert_equal doc, BSON.deserialize(bson)
end
def test_string def test_string
doc = {'doc' => 'hello, world'} doc = {'doc' => 'hello, world'}
bson = bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_valid_utf8_string def test_valid_utf8_string
doc = {'doc' => 'aé'} doc = {'doc' => 'aé'}
bson = bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_valid_utf8_key def test_valid_utf8_key
doc = {'aé' => 'hello'} doc = {'aé' => 'hello'}
bson = bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_document_length def test_document_length
doc = {'name' => 'a' * 5 * 1024 * 1024} doc = {'name' => 'a' * 5 * 1024 * 1024}
assert_raise InvalidDocument do assert_raise InvalidDocument do
assert BSON::BSON_CODER.serialize(doc) assert @encoder.serialize(doc)
end end
end end
@ -96,7 +84,7 @@ class BSONTest < Test::Unit::TestCase
string = Iconv.conv('iso-8859-1', 'utf-8', 'aé') string = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
doc = {'doc' => string} doc = {'doc' => string}
assert_raise InvalidStringEncoding do assert_raise InvalidStringEncoding do
BSON::BSON_CODER.serialize(doc) @encoder.serialize(doc)
end end
end end
@ -104,7 +92,7 @@ class BSONTest < Test::Unit::TestCase
key = Iconv.conv('iso-8859-1', 'utf-8', 'aé') key = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
doc = {key => 'hello'} doc = {key => 'hello'}
assert_raise InvalidStringEncoding do assert_raise InvalidStringEncoding do
BSON::BSON_CODER.serialize(doc) @encoder.serialize(doc)
end end
end end
else else
@ -140,38 +128,31 @@ class BSONTest < Test::Unit::TestCase
def test_code def test_code
doc = {'$where' => Code.new('this.a.b < this.b')} doc = {'$where' => Code.new('this.a.b < this.b')}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_code_with_scope def test_code_with_scope
doc = {'$where' => Code.new('this.a.b < this.b', {'foo' => 1})} doc = {'$where' => Code.new('this.a.b < this.b', {'foo' => 1})}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_number def test_double
doc = {'doc' => 41.99} doc = {'doc' => 41.25}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson) end
end
def test_int def test_int
doc = {'doc' => 42} doc = {'doc' => 42}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
doc = {"doc" => -5600} doc = {"doc" => -5600}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
doc = {"doc" => 2147483647} doc = {"doc" => 2147483647}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
doc = {"doc" => -2147483648} doc = {"doc" => -2147483648}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_ordered_hash def test_ordered_hash
@ -180,72 +161,57 @@ class BSONTest < Test::Unit::TestCase
doc["a"] = 2 doc["a"] = 2
doc["c"] = 3 doc["c"] = 3
doc["d"] = 4 doc["d"] = 4
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_object def test_object
doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}} doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
assert_doc_pass(doc)
bson = BSON::BSON_CODER.serialize(doc) bson = BSON::BSON_CODER.serialize(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_oid def test_oid
doc = {'doc' => ObjectId.new} doc = {'doc' => ObjectId.new}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_array def test_array
doc = {'doc' => [1, 2, 'a', 'b']} doc = {'doc' => [1, 2, 'a', 'b']}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_regex def test_regex
doc = {'doc' => /foobar/i} doc = {'doc' => /foobar/i}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
doc2 = BSON::BSON_CODER.deserialize(bson)
assert_equal doc, doc2
r = doc2['doc']
assert_kind_of Regexp, r
doc = {'doc' => r}
bson_doc = BSON::BSON_CODER.serialize(doc)
doc2 = nil
doc2 = BSON::BSON_CODER.deserialize(bson_doc)
assert_equal doc, doc2
end end
def test_boolean def test_boolean
doc = {'doc' => true} doc = {'doc' => true}
bson = BSON::BSON_CODER.serialize(doc) assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(bson)
end end
def test_date def test_date
doc = {'date' => Time.now} doc = {'date' => Time.now}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
# Mongo only stores up to the millisecond # Mongo only stores up to the millisecond
assert_in_delta doc['date'], doc2['date'], 0.001 assert_in_delta doc['date'], doc2['date'], 0.001
end end
def test_date_returns_as_utc def test_date_returns_as_utc
doc = {'date' => Time.now} doc = {'date' => Time.now}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
assert doc2['date'].utc? assert doc2['date'].utc?
end end
def test_date_before_epoch def test_date_before_epoch
begin begin
doc = {'date' => Time.utc(1600)} doc = {'date' => Time.utc(1600)}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
# Mongo only stores up to the millisecond # Mongo only stores up to the millisecond
assert_in_delta doc['date'], doc2['date'], 0.001 assert_in_delta doc['date'], doc2['date'], 2
rescue ArgumentError rescue ArgumentError
# some versions of Ruby won't let you create pre-epoch Time instances # some versions of Ruby won't let you create pre-epoch Time instances
# #
@ -273,16 +239,23 @@ class BSONTest < Test::Unit::TestCase
oid = ObjectId.new oid = ObjectId.new
doc = {} doc = {}
doc['dbref'] = DBRef.new('namespace', oid) doc['dbref'] = DBRef.new('namespace', oid)
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
assert_equal 'namespace', doc2['dbref'].namespace
assert_equal oid, doc2['dbref'].object_id # Java doesn't deserialize to DBRefs
if RUBY_PLATFORM =~ /java/
assert_equal 'namespace', doc2['dbref']['$ns']
assert_equal oid, doc2['dbref']['$id']
else
assert_equal 'namespace', doc2['dbref'].namespace
assert_equal oid, doc2['dbref'].object_id
end
end end
def test_symbol def test_symbol
doc = {'sym' => :foo} doc = {'sym' => :foo}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
assert_equal :foo, doc2['sym'] assert_equal :foo, doc2['sym']
end end
@ -291,8 +264,8 @@ class BSONTest < Test::Unit::TestCase
'binstring'.each_byte { |b| bin.put(b) } 'binstring'.each_byte { |b| bin.put(b) }
doc = {'bin' => bin} doc = {'bin' => bin}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
bin2 = doc2['bin'] bin2 = doc2['bin']
assert_kind_of Binary, bin2 assert_kind_of Binary, bin2
assert_equal 'binstring', bin2.to_s assert_equal 'binstring', bin2.to_s
@ -302,8 +275,8 @@ class BSONTest < Test::Unit::TestCase
def test_binary_with_string def test_binary_with_string
b = Binary.new('somebinarystring') b = Binary.new('somebinarystring')
doc = {'bin' => b} doc = {'bin' => b}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
bin2 = doc2['bin'] bin2 = doc2['bin']
assert_kind_of Binary, bin2 assert_kind_of Binary, bin2
assert_equal 'somebinarystring', bin2.to_s assert_equal 'somebinarystring', bin2.to_s
@ -314,24 +287,27 @@ class BSONTest < Test::Unit::TestCase
bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_USER_DEFINED) bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_USER_DEFINED)
doc = {'bin' => bin} doc = {'bin' => bin}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
bin2 = doc2['bin'] bin2 = doc2['bin']
assert_kind_of Binary, bin2 assert_kind_of Binary, bin2
assert_equal [1, 2, 3, 4, 5], bin2.to_a assert_equal [1, 2, 3, 4, 5], bin2.to_a
assert_equal Binary::SUBTYPE_USER_DEFINED, bin2.subtype assert_equal Binary::SUBTYPE_USER_DEFINED, bin2.subtype
end end
def test_binary_subtype_0 # Java doesn't support binary subtype 0 yet
bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_SIMPLE) if !(RUBY_PLATFORM =~ /java/)
def test_binary_subtype_0
bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_SIMPLE)
doc = {'bin' => bin} doc = {'bin' => bin}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
bin2 = doc2['bin'] bin2 = doc2['bin']
assert_kind_of Binary, bin2 assert_kind_of Binary, bin2
assert_equal [1, 2, 3, 4, 5], bin2.to_a assert_equal [1, 2, 3, 4, 5], bin2.to_a
assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
end
end end
def test_binary_byte_buffer def test_binary_byte_buffer
@ -339,8 +315,8 @@ class BSONTest < Test::Unit::TestCase
5.times { |i| bb.put(i + 1) } 5.times { |i| bb.put(i + 1) }
doc = {'bin' => bb} doc = {'bin' => bb}
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
doc2 = BSON::BSON_CODER.deserialize(bson) doc2 = @decoder.deserialize(bson)
bin2 = doc2['bin'] bin2 = doc2['bin']
assert_kind_of Binary, bin2 assert_kind_of Binary, bin2
assert_equal [1, 2, 3, 4, 5], bin2.to_a assert_equal [1, 2, 3, 4, 5], bin2.to_a
@ -351,52 +327,55 @@ class BSONTest < Test::Unit::TestCase
val = BSON::OrderedHash.new val = BSON::OrderedHash.new
val['not_id'] = 1 val['not_id'] = 1
val['_id'] = 2 val['_id'] = 2
roundtrip = BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(val, false, true).to_a) roundtrip = @decoder.deserialize(@encoder.serialize(val, false, true).to_s)
assert_kind_of BSON::OrderedHash, roundtrip assert_kind_of BSON::OrderedHash, roundtrip
assert_equal '_id', roundtrip.keys.first assert_equal '_id', roundtrip.keys.first
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'} val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
roundtrip = BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(val, false, true).to_a) roundtrip = @decoder.deserialize(@encoder.serialize(val, false, true).to_s)
assert_kind_of BSON::OrderedHash, roundtrip assert_kind_of BSON::OrderedHash, roundtrip
assert_equal '_id', roundtrip.keys.first assert_equal '_id', roundtrip.keys.first
end end
def test_nil_id def test_nil_id
doc = {"_id" => nil} doc = {"_id" => nil}
assert_equal doc, BSON::BSON_CODER.deserialize(bson = BSON::BSON_CODER.serialize(doc, false, true).to_a) assert_doc_pass(doc)
end end
def test_timestamp if !(RUBY_PLATFORM =~ /java/)
val = {"test" => [4, 20]} def test_timestamp
assert_equal val, BSON::BSON_CODER.deserialize([0x13, 0x00, 0x00, 0x00, val = {"test" => [4, 20]}
0x11, 0x74, 0x65, 0x73, assert_equal val, @decoder.deserialize([0x13, 0x00, 0x00, 0x00,
0x74, 0x00, 0x04, 0x00, 0x11, 0x74, 0x65, 0x73,
0x00, 0x00, 0x14, 0x00, 0x74, 0x00, 0x04, 0x00,
0x00, 0x00, 0x00]) 0x00, 0x00, 0x14, 0x00,
0x00, 0x00, 0x00])
end
end end
def test_overflow def test_overflow
doc = {"x" => 2**75} doc = {"x" => 2**75}
assert_raise RangeError do assert_raise RangeError do
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
end end
doc = {"x" => 9223372036854775} doc = {"x" => 9223372036854775}
assert_equal doc, BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(doc).to_a) assert_doc_pass(doc)
doc = {"x" => 9223372036854775807} doc = {"x" => 9223372036854775807}
assert_equal doc, BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(doc).to_a) assert_doc_pass(doc)
doc["x"] = doc["x"] + 1 doc["x"] = doc["x"] + 1
assert_raise RangeError do assert_raise RangeError do
bson = BSON::BSON_CODER.serialize(doc) bson = @encoder.serialize(doc)
end end
doc = {"x" => -9223372036854775} doc = {"x" => -9223372036854775}
assert_equal doc, BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(doc).to_a) assert_doc_pass(doc)
doc = {"x" => -9223372036854775808} doc = {"x" => -9223372036854775808}
assert_equal doc, BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(doc).to_a) assert_doc_pass(doc)
doc["x"] = doc["x"] - 1 doc["x"] = doc["x"] - 1
assert_raise RangeError do assert_raise RangeError do
@ -408,7 +387,7 @@ class BSONTest < Test::Unit::TestCase
[BigDecimal.new("1.0"), Complex(0, 1), Rational(2, 3)].each do |type| [BigDecimal.new("1.0"), Complex(0, 1), Rational(2, 3)].each do |type|
doc = {"x" => type} doc = {"x" => type}
begin begin
BSON::BSON_CODER.serialize(doc) @encoder.serialize(doc)
rescue => e rescue => e
ensure ensure
assert_equal InvalidDocument, e.class assert_equal InvalidDocument, e.class
@ -422,12 +401,12 @@ class BSONTest < Test::Unit::TestCase
val['not_id'] = 1 val['not_id'] = 1
val['_id'] = 2 val['_id'] = 2
assert val.keys.include?('_id') assert val.keys.include?('_id')
BSON::BSON_CODER.serialize(val) @encoder.serialize(val)
assert val.keys.include?('_id') assert val.keys.include?('_id')
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'} val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
assert val.keys.include?(:_id) assert val.keys.include?(:_id)
BSON::BSON_CODER.serialize(val) @encoder.serialize(val)
assert val.keys.include?(:_id) assert val.keys.include?(:_id)
end end
@ -442,50 +421,48 @@ class BSONTest < Test::Unit::TestCase
dup = {"_id" => "foo", :_id => "foo"} dup = {"_id" => "foo", :_id => "foo"}
one = {"_id" => "foo"} one = {"_id" => "foo"}
assert_equal BSON::BSON_CODER.serialize(one).to_a, BSON::BSON_CODER.serialize(dup).to_a assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a
end end
def test_no_duplicate_id_when_moving_id def test_no_duplicate_id_when_moving_id
dup = {"_id" => "foo", :_id => "foo"} dup = {"_id" => "foo", :_id => "foo"}
one = {:_id => "foo"} one = {:_id => "foo"}
assert_equal BSON::BSON_CODER.serialize(one, false, true).to_s, BSON::BSON_CODER.serialize(dup, false, true).to_s assert_equal @encoder.serialize(one, false, true).to_s, @encoder.serialize(dup, false, true).to_s
end end
def test_null_character def test_null_character
doc = {"a" => "\x00"} doc = {"a" => "\x00"}
assert_equal doc, BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(doc).to_a) assert_doc_pass(doc)
assert_raise InvalidDocument do assert_raise InvalidDocument do
BSON::BSON_CODER.serialize({"\x00" => "a"}) @encoder.serialize({"\x00" => "a"})
end end
assert_raise InvalidDocument do assert_raise InvalidDocument do
BSON::BSON_CODER.serialize({"a" => (Regexp.compile "ab\x00c")}) @encoder.serialize({"a" => (Regexp.compile "ab\x00c")})
end end
end end
def test_max_key def test_max_key
doc = {"a" => MaxKey.new} doc = {"a" => MaxKey.new}
assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(doc).to_a)
end end
def test_min_key def test_min_key
doc = {"a" => MinKey.new} doc = {"a" => MinKey.new}
assert_doc_pass(doc)
assert_equal doc, BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(doc).to_a)
end end
def test_invalid_object def test_invalid_object
o = Object.new o = Object.new
assert_raise InvalidDocument do assert_raise InvalidDocument do
BSON::BSON_CODER.serialize({:foo => o}) @encoder.serialize({:foo => o})
end end
assert_raise InvalidDocument do assert_raise InvalidDocument do
BSON::BSON_CODER.serialize({:foo => Date.today}) @encoder.serialize({:foo => Date.today})
end end
end end
@ -498,10 +475,14 @@ class BSONTest < Test::Unit::TestCase
assert_equal ")\000\000\000\020_id\000\001\000\000\000\002text" + assert_equal ")\000\000\000\020_id\000\001\000\000\000\002text" +
"\000\004\000\000\000abc\000\002key\000\004\000\000\000abc\000\000", "\000\004\000\000\000abc\000\002key\000\004\000\000\000abc\000\000",
BSON::BSON_CODER.serialize(a, false, true).to_s @encoder.serialize(a, false, true).to_s
assert_equal ")\000\000\000\002text\000\004\000\000\000abc\000\002key" +
"\000\004\000\000\000abc\000\020_id\000\001\000\000\000\000", # Java doesn't support this. Isn't actually necessary.
BSON::BSON_CODER.serialize(a, false, false).to_s if !(RUBY_PLATFORM =~ /java/)
assert_equal ")\000\000\000\002text\000\004\000\000\000abc\000\002key" +
"\000\004\000\000\000abc\000\020_id\000\001\000\000\000\000",
@encoder.serialize(a, false, false).to_s
end
end end
def test_move_id_with_nested_doc def test_move_id_with_nested_doc
@ -515,11 +496,15 @@ class BSONTest < Test::Unit::TestCase
assert_equal ">\000\000\000\020_id\000\003\000\000\000\002text" + assert_equal ">\000\000\000\020_id\000\003\000\000\000\002text" +
"\000\004\000\000\000abc\000\003hash\000\034\000\000" + "\000\004\000\000\000abc\000\003hash\000\034\000\000" +
"\000\002text\000\004\000\000\000abc\000\020_id\000\002\000\000\000\000\000", "\000\002text\000\004\000\000\000abc\000\020_id\000\002\000\000\000\000\000",
BSON::BSON_CODER.serialize(c, false, true).to_s @encoder.serialize(c, false, true).to_s
assert_equal ">\000\000\000\002text\000\004\000\000\000abc\000\003hash" +
"\000\034\000\000\000\002text\000\004\000\000\000abc\000\020_id" + # Java doesn't support this. Isn't actually necessary.
"\000\002\000\000\000\000\020_id\000\003\000\000\000\000", if !(RUBY_PLATFORM =~ /java/)
BSON::BSON_CODER.serialize(c, false, false).to_s assert_equal ">\000\000\000\002text\000\004\000\000\000abc\000\003hash" +
"\000\034\000\000\000\002text\000\004\000\000\000abc\000\020_id" +
"\000\002\000\000\000\000\020_id\000\003\000\000\000\000",
@encoder.serialize(c, false, false).to_s
end
end end
# Mocking this class for testing # Mocking this class for testing
@ -531,12 +516,12 @@ class BSONTest < Test::Unit::TestCase
embedded['_id'] = ObjectId.new embedded['_id'] = ObjectId.new
doc['_id'] = ObjectId.new doc['_id'] = ObjectId.new
doc['embedded'] = [embedded] doc['embedded'] = [embedded]
BSON::BSON_CODER.serialize(doc, false, true).to_a @encoder.serialize(doc, false, true).to_a
assert doc.has_key?("_id") assert doc.has_key?("_id")
assert doc['embedded'][0].has_key?("_id") assert doc['embedded'][0].has_key?("_id")
doc['_id'] = ObjectId.new doc['_id'] = ObjectId.new
BSON::BSON_CODER.serialize(doc, false, true).to_a @encoder.serialize(doc, false, true).to_a
assert doc.has_key?("_id") assert doc.has_key?("_id")
end end