2008-12-16 12:20:20 +00:00
|
|
|
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
|
|
|
require 'mongo'
|
2009-03-05 19:58:34 +00:00
|
|
|
require 'mongo/util/ordered_hash'
|
2008-12-16 12:20:20 +00:00
|
|
|
require 'test/unit'
|
|
|
|
|
|
|
|
class BSONTest < Test::Unit::TestCase
|
|
|
|
|
2008-12-19 02:57:20 +00:00
|
|
|
include XGen::Mongo::Driver
|
|
|
|
|
2008-12-16 12:20:20 +00:00
|
|
|
def setup
|
2009-01-09 20:22:10 +00:00
|
|
|
# We don't pass a DB to the constructor, even though we are about to test
|
|
|
|
# deserialization. This means that when we deserialize, any DBRefs will
|
|
|
|
# have nil @db ivars. That's fine for now.
|
2008-12-16 12:20:20 +00:00
|
|
|
@b = BSON.new
|
|
|
|
end
|
|
|
|
|
2008-12-16 12:33:39 +00:00
|
|
|
def test_string
|
|
|
|
doc = {'doc' => 'hello, world'}
|
2008-12-16 12:23:22 +00:00
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
end
|
|
|
|
|
2008-12-16 12:33:39 +00:00
|
|
|
def test_code
|
2009-03-12 19:34:15 +00:00
|
|
|
doc = {'$where' => Code.new('this.a.b < this.b')}
|
2008-12-16 12:20:20 +00:00
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
end
|
2008-12-16 12:33:39 +00:00
|
|
|
|
|
|
|
def test_number
|
|
|
|
doc = {'doc' => 41.99}
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_int
|
|
|
|
doc = {'doc' => 42}
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
2009-05-15 15:19:13 +00:00
|
|
|
|
|
|
|
doc = {"doc" => -5600}
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
|
|
|
|
doc = {"doc" => 2147483647}
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
|
|
|
|
doc = {"doc" => -2147483648}
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
2008-12-16 12:33:39 +00:00
|
|
|
end
|
|
|
|
|
2009-03-05 19:58:34 +00:00
|
|
|
def test_ordered_hash
|
|
|
|
doc = OrderedHash.new
|
|
|
|
doc["b"] = 1
|
|
|
|
doc["a"] = 2
|
|
|
|
doc["c"] = 3
|
|
|
|
doc["d"] = 4
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
end
|
|
|
|
|
2008-12-16 12:33:39 +00:00
|
|
|
def test_object
|
|
|
|
doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_oid
|
2008-12-19 02:57:20 +00:00
|
|
|
doc = {'doc' => ObjectID.new}
|
2008-12-16 12:33:39 +00:00
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_array
|
|
|
|
doc = {'doc' => [1, 2, 'a', 'b']}
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_regex
|
|
|
|
doc = {'doc' => /foobar/i}
|
|
|
|
@b.serialize(doc)
|
2009-01-13 14:12:13 +00:00
|
|
|
doc2 = @b.deserialize
|
|
|
|
assert_equal doc, doc2
|
|
|
|
|
|
|
|
r = doc2['doc']
|
|
|
|
assert_kind_of XGen::Mongo::Driver::RegexpOfHolding, r
|
|
|
|
assert_equal '', r.extra_options_str
|
|
|
|
|
|
|
|
r.extra_options_str << 'zywcab'
|
|
|
|
assert_equal 'zywcab', r.extra_options_str
|
|
|
|
|
|
|
|
b = BSON.new
|
|
|
|
doc = {'doc' => r}
|
|
|
|
b.serialize(doc)
|
|
|
|
doc2 = nil
|
|
|
|
doc2 = b.deserialize
|
|
|
|
assert_equal doc, doc2
|
|
|
|
|
|
|
|
r = doc2['doc']
|
|
|
|
assert_kind_of XGen::Mongo::Driver::RegexpOfHolding, r
|
|
|
|
assert_equal 'abcwyz', r.extra_options_str # must be sorted
|
2008-12-16 12:33:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_boolean
|
|
|
|
doc = {'doc' => true}
|
|
|
|
@b.serialize(doc)
|
|
|
|
assert_equal doc, @b.deserialize
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_date
|
|
|
|
doc = {'date' => Time.now}
|
|
|
|
@b.serialize(doc)
|
|
|
|
doc2 = @b.deserialize
|
2009-02-27 16:27:07 +00:00
|
|
|
# Mongo only stores up to the millisecond
|
|
|
|
assert_in_delta doc['date'], doc2['date'], 0.001
|
2008-12-16 12:33:39 +00:00
|
|
|
end
|
|
|
|
|
2009-07-16 20:02:57 +00:00
|
|
|
def test_date_returns_as_utc
|
|
|
|
doc = {'date' => Time.now}
|
|
|
|
@b.serialize(doc)
|
|
|
|
doc2 = @b.deserialize
|
2009-07-16 20:32:57 +00:00
|
|
|
assert doc2['date'].utc?
|
2009-07-16 20:02:57 +00:00
|
|
|
end
|
|
|
|
|
2009-01-08 19:43:30 +00:00
|
|
|
def test_dbref
|
|
|
|
oid = ObjectID.new
|
2009-01-09 20:22:10 +00:00
|
|
|
doc = {}
|
2009-03-10 18:17:01 +00:00
|
|
|
doc['dbref'] = DBRef.new('namespace', oid)
|
2009-01-08 19:43:30 +00:00
|
|
|
@b.serialize(doc)
|
|
|
|
doc2 = @b.deserialize
|
|
|
|
assert_equal 'namespace', doc2['dbref'].namespace
|
|
|
|
assert_equal oid, doc2['dbref'].object_id
|
|
|
|
end
|
|
|
|
|
2009-01-09 23:20:53 +00:00
|
|
|
def test_symbol
|
|
|
|
doc = {'sym' => :foo}
|
|
|
|
@b.serialize(doc)
|
|
|
|
doc2 = @b.deserialize
|
|
|
|
assert_equal :foo, doc2['sym']
|
|
|
|
end
|
|
|
|
|
2009-01-10 00:58:53 +00:00
|
|
|
def test_binary
|
2009-02-02 15:07:01 +00:00
|
|
|
bin = Binary.new
|
|
|
|
'binstring'.each_byte { |b| bin.put(b) }
|
2009-01-10 00:58:53 +00:00
|
|
|
|
|
|
|
doc = {'bin' => bin}
|
|
|
|
@b.serialize(doc)
|
|
|
|
doc2 = @b.deserialize
|
2009-02-02 15:07:01 +00:00
|
|
|
bin2 = doc2['bin']
|
|
|
|
assert_kind_of Binary, bin2
|
|
|
|
assert_equal 'binstring', bin2.to_s
|
2009-02-27 16:27:07 +00:00
|
|
|
assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
|
2009-02-02 15:07:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_binary_type
|
|
|
|
bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_USER_DEFINED)
|
|
|
|
|
|
|
|
doc = {'bin' => bin}
|
|
|
|
@b.serialize(doc)
|
|
|
|
doc2 = @b.deserialize
|
|
|
|
bin2 = doc2['bin']
|
|
|
|
assert_kind_of Binary, bin2
|
2009-03-05 15:27:19 +00:00
|
|
|
assert_equal [1, 2, 3, 4, 5], bin2.to_a
|
2009-02-02 15:07:01 +00:00
|
|
|
assert_equal Binary::SUBTYPE_USER_DEFINED, bin2.subtype
|
2009-01-10 00:58:53 +00:00
|
|
|
end
|
|
|
|
|
2009-01-27 21:26:42 +00:00
|
|
|
def test_binary_byte_buffer
|
|
|
|
bb = ByteBuffer.new
|
2009-02-02 15:07:01 +00:00
|
|
|
5.times { |i| bb.put(i + 1) }
|
|
|
|
|
2009-01-27 21:26:42 +00:00
|
|
|
doc = {'bin' => bb}
|
|
|
|
@b.serialize(doc)
|
|
|
|
doc2 = @b.deserialize
|
2009-02-02 15:07:01 +00:00
|
|
|
bin2 = doc2['bin']
|
|
|
|
assert_kind_of Binary, bin2
|
|
|
|
assert_equal [1, 2, 3, 4, 5], bin2.to_a
|
|
|
|
assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
|
2009-01-27 21:26:42 +00:00
|
|
|
end
|
2009-01-26 18:52:11 +00:00
|
|
|
|
2009-01-12 17:08:02 +00:00
|
|
|
def test_undefined
|
|
|
|
doc = {'undef' => Undefined.new}
|
|
|
|
@b.serialize(doc)
|
|
|
|
doc2 = @b.deserialize
|
2009-08-19 19:18:02 +00:00
|
|
|
assert_equal nil, doc2['undef']
|
2009-01-12 17:08:02 +00:00
|
|
|
end
|
|
|
|
|
2009-01-26 14:02:18 +00:00
|
|
|
def test_put_id_first
|
|
|
|
val = OrderedHash.new
|
|
|
|
val['not_id'] = 1
|
|
|
|
val['_id'] = 2
|
2009-01-27 21:26:42 +00:00
|
|
|
roundtrip = @b.deserialize(@b.serialize(val).to_a)
|
|
|
|
assert_kind_of OrderedHash, roundtrip
|
|
|
|
assert_equal '_id', roundtrip.keys.first
|
2009-01-26 14:02:18 +00:00
|
|
|
|
|
|
|
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
|
2009-01-27 21:26:42 +00:00
|
|
|
roundtrip = @b.deserialize(@b.serialize(val).to_a)
|
|
|
|
assert_kind_of OrderedHash, roundtrip
|
|
|
|
assert_equal '_id', roundtrip.keys.first
|
2009-01-26 14:02:18 +00:00
|
|
|
end
|
|
|
|
|
2009-05-12 18:21:17 +00:00
|
|
|
def test_nil_id
|
|
|
|
doc = {"_id" => nil}
|
|
|
|
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
|
|
|
end
|
|
|
|
|
2009-04-22 17:49:56 +00:00
|
|
|
def test_timestamp
|
|
|
|
val = {"test" => [4, 20]}
|
|
|
|
assert_equal val, @b.deserialize([0x13, 0x00, 0x00, 0x00,
|
|
|
|
0x11, 0x74, 0x65, 0x73,
|
|
|
|
0x74, 0x00, 0x04, 0x00,
|
|
|
|
0x00, 0x00, 0x14, 0x00,
|
|
|
|
0x00, 0x00, 0x00])
|
|
|
|
end
|
|
|
|
|
2009-05-15 15:19:13 +00:00
|
|
|
def test_overflow
|
2009-08-03 21:57:44 +00:00
|
|
|
doc = {"x" => 2**75}
|
2009-05-15 15:19:13 +00:00
|
|
|
assert_raise RangeError do
|
|
|
|
@b.serialize(doc)
|
|
|
|
end
|
|
|
|
|
2009-08-03 21:57:44 +00:00
|
|
|
doc = {"x" => 9223372036854775}
|
|
|
|
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
|
|
|
|
|
|
|
doc = {"x" => 9223372036854775807}
|
2009-05-15 15:19:13 +00:00
|
|
|
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
|
|
|
|
|
|
|
doc["x"] = doc["x"] + 1
|
|
|
|
assert_raise RangeError do
|
|
|
|
@b.serialize(doc)
|
|
|
|
end
|
2009-08-03 21:57:44 +00:00
|
|
|
|
|
|
|
doc = {"x" => -9223372036854775}
|
|
|
|
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
|
|
|
|
|
|
|
doc = {"x" => -9223372036854775808}
|
|
|
|
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
|
|
|
|
|
|
|
doc["x"] = doc["x"] - 1
|
|
|
|
assert_raise RangeError do
|
|
|
|
@b.serialize(doc)
|
|
|
|
end
|
2009-05-15 15:19:13 +00:00
|
|
|
end
|
|
|
|
|
2009-01-28 20:38:31 +00:00
|
|
|
def test_do_not_change_original_object
|
|
|
|
val = OrderedHash.new
|
|
|
|
val['not_id'] = 1
|
|
|
|
val['_id'] = 2
|
|
|
|
assert val.keys.include?('_id')
|
|
|
|
@b.serialize(val)
|
|
|
|
assert val.keys.include?('_id')
|
|
|
|
|
|
|
|
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
|
|
|
|
assert val.keys.include?(:_id)
|
|
|
|
@b.serialize(val)
|
|
|
|
assert val.keys.include?(:_id)
|
|
|
|
end
|
|
|
|
|
2008-12-16 12:20:20 +00:00
|
|
|
end
|