New tests for Ruby-to-BSON-to-Ruby.
This commit is contained in:
parent
3158d50879
commit
926a3ad3b9
BIN
tests/data/empty.bson
Normal file
BIN
tests/data/empty.bson
Normal file
Binary file not shown.
5
tests/data/empty.xml
Normal file
5
tests/data/empty.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<twonk>
|
||||
<meta/>
|
||||
<doc>
|
||||
</doc>
|
||||
</twonk>
|
BIN
tests/data/smorgasbord.bson
Normal file
BIN
tests/data/smorgasbord.bson
Normal file
Binary file not shown.
29
tests/data/smorgasbord.xml
Normal file
29
tests/data/smorgasbord.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<twonk>
|
||||
<meta/>
|
||||
<doc>
|
||||
<oid name="_id">4ea067497065180748000000</oid>
|
||||
<int name="an_int">42</int>
|
||||
<string name="a_string">foo</string>
|
||||
<boolean name="truthiness">true</boolean>
|
||||
<number name="a_float">42.12345</number>
|
||||
<array name="an_array">
|
||||
<string name="0">x</string>
|
||||
<string name="1">y</string>
|
||||
<string name="2">z</string>
|
||||
<doc name="3">
|
||||
<string name="subobject">yup</string>
|
||||
</doc>
|
||||
</array>
|
||||
<date name="now">1231515664416</date>
|
||||
<ref name="dbref">
|
||||
<ns>namespace</ns>
|
||||
<oid>4ea067497065180748010000</oid>
|
||||
</ref>
|
||||
<regex name="regex">
|
||||
<pattern>foobar</pattern>
|
||||
<options></options>
|
||||
</regex>
|
||||
<null name="a_null_value"></null>
|
||||
<code name="$where">this is code</code>
|
||||
</doc>
|
||||
</twonk>
|
137
tests/test_round_trip.rb
Normal file
137
tests/test_round_trip.rb
Normal file
@ -0,0 +1,137 @@
|
||||
HERE = File.dirname(__FILE__)
|
||||
$LOAD_PATH[0,0] = File.join(HERE, '..', 'lib')
|
||||
require 'mongo'
|
||||
require 'rexml/document'
|
||||
require 'test/unit'
|
||||
|
||||
# For each xml/bson file in the data subdirectory, we turn the XML into an
|
||||
# OrderedHash and then test both Ruby-to-BSON and BSON-to-Ruby translations.
|
||||
class RoundTripTest < Test::Unit::TestCase
|
||||
|
||||
include XGen::Mongo::Driver
|
||||
|
||||
@@ruby = nil
|
||||
|
||||
def setup
|
||||
unless @@ruby
|
||||
names = Dir[File.join(HERE, 'data', '*.xml')].collect {|f| File.basename(f).sub(/\.xml$/, '') }
|
||||
@@ruby = {}
|
||||
names.each { |name| @@ruby[name] = xml_to_ruby(name) }
|
||||
end
|
||||
end
|
||||
|
||||
def xml_to_ruby(name)
|
||||
File.open(File.join(HERE, 'data', "#{name}.xml")) { |f|
|
||||
doc = REXML::Document.new(f)
|
||||
doc_to_ruby(doc.root.elements['doc'])
|
||||
}
|
||||
end
|
||||
|
||||
def element_to_ruby(e)
|
||||
type = e.name
|
||||
child = e.elements[1]
|
||||
case type
|
||||
when 'oid'
|
||||
ObjectID.from_string(e.text)
|
||||
when 'ref'
|
||||
dbref_to_ruby(e.elements)
|
||||
when 'int'
|
||||
e.text.to_i
|
||||
when 'number'
|
||||
e.text.to_f
|
||||
when 'string', 'code'
|
||||
e.text.to_s
|
||||
when 'boolean'
|
||||
e.text.to_s == 'true'
|
||||
when 'array'
|
||||
array_to_ruby(e.elements)
|
||||
when 'date'
|
||||
Time.at(e.text.to_f / 1000.0)
|
||||
when 'regex'
|
||||
regex_to_ruby(e.elements)
|
||||
when 'null'
|
||||
nil
|
||||
when 'doc'
|
||||
doc_to_ruby(e)
|
||||
else
|
||||
raise "Unknown type #{type} in element with name #{e.attributes['name']}"
|
||||
end
|
||||
end
|
||||
|
||||
def doc_to_ruby(element)
|
||||
oh = OrderedHash.new
|
||||
element.elements.each { |e| oh[e.attributes['name']] = element_to_ruby(e) }
|
||||
oh
|
||||
end
|
||||
|
||||
def array_to_ruby(elements)
|
||||
a = []
|
||||
elements.each { |e|
|
||||
index_str = e.attributes['name']
|
||||
a[index_str.to_i] = element_to_ruby(e)
|
||||
}
|
||||
a
|
||||
end
|
||||
|
||||
def regex_to_ruby(elements)
|
||||
pattern = elements['pattern'].text
|
||||
options_str = elements['options'].text || ''
|
||||
|
||||
options = 0
|
||||
options |= Regexp::IGNORECASE if options_str.include?('i')
|
||||
options |= Regexp::MULTILINE if options_str.include?('m')
|
||||
options |= Regexp::EXTENDED if options_str.include?('x')
|
||||
Regexp.new(pattern, options)
|
||||
end
|
||||
|
||||
def dbref_to_ruby(elements)
|
||||
ns = elements['ns'].text
|
||||
oid_str = elements['oid'].text
|
||||
DBRef.new(nil, nil, nil, ns, ObjectID.from_string(oid_str))
|
||||
end
|
||||
|
||||
# DEBUG
|
||||
# def test_foo
|
||||
# $stderr.puts "#{@@ruby['smorgasbord'].class.name}" # DEBUG
|
||||
# $stderr.puts "@@ruby['smorgasbord'] = #{@@ruby['smorgasbord'].inspect.gsub(/, /, ",\n")}" # DEBUG
|
||||
# end
|
||||
|
||||
# Round-trip comparisons of Ruby-to-BSON and back.
|
||||
# * Take the objects that were read from XML
|
||||
# * Turn them into BSON bytes
|
||||
# * Compare that with the BSON files we have
|
||||
# * Turn those BSON bytes back in to Ruby objects
|
||||
# * Turn them back into BSON bytes
|
||||
# * Compare that with the BSON files we have (or the bytes that were already
|
||||
# generated)
|
||||
def test_round_trip
|
||||
@@ruby.each { |name, obj|
|
||||
File.open(File.join(HERE, 'data', "#{name}.bson"), 'r') { |f|
|
||||
# Read the BSON from the file
|
||||
bson = f.read
|
||||
bson = if RUBY_VERSION >= '1.9'
|
||||
bson.bytes
|
||||
else
|
||||
bson.split(//).collect { |c| c[0] }
|
||||
end
|
||||
|
||||
# Turn the Ruby object into BSON bytes and compare with the BSON bytes
|
||||
# from the file.
|
||||
bson_from_ruby = BSON.new.serialize(obj).to_a
|
||||
assert_equal bson.length, bson_from_ruby.length
|
||||
assert_equal bson, bson_from_ruby
|
||||
|
||||
# Turn those BSON bytes back into a Ruby object
|
||||
obj_from_bson = BSON.new.deserialize(ByteBuffer.new(bson_from_ruby))
|
||||
assert_kind_of OrderedHash, obj_from_bson
|
||||
|
||||
# Turn that Ruby object into BSON and compare it to the original BSON
|
||||
# bytes.
|
||||
bson_from_ruby = BSON.new.serialize(obj_from_bson).to_a
|
||||
assert_equal bson.length, bson_from_ruby.length
|
||||
assert_equal bson, bson_from_ruby
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user