From 926a3ad3b9bac453d6b93bc61b07ebac0ba2b79d Mon Sep 17 00:00:00 2001 From: Jim Menard Date: Fri, 9 Jan 2009 14:43:12 -0500 Subject: [PATCH] New tests for Ruby-to-BSON-to-Ruby. --- tests/data/empty.bson | Bin 0 -> 5 bytes tests/data/empty.xml | 5 ++ tests/data/smorgasbord.bson | Bin 0 -> 247 bytes tests/data/smorgasbord.xml | 29 ++++++++ tests/test_round_trip.rb | 137 ++++++++++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 tests/data/empty.bson create mode 100644 tests/data/empty.xml create mode 100644 tests/data/smorgasbord.bson create mode 100644 tests/data/smorgasbord.xml create mode 100644 tests/test_round_trip.rb diff --git a/tests/data/empty.bson b/tests/data/empty.bson new file mode 100644 index 0000000000000000000000000000000000000000..a536906cf24d95fb478a76c9652a2f538f1da79f GIT binary patch literal 5 KcmZQ&00IC29smXa literal 0 HcmV?d00001 diff --git a/tests/data/empty.xml b/tests/data/empty.xml new file mode 100644 index 0000000..fee7568 --- /dev/null +++ b/tests/data/empty.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/data/smorgasbord.bson b/tests/data/smorgasbord.bson new file mode 100644 index 0000000000000000000000000000000000000000..bbd7700d5f4ebc9f7846c73240b6554381338d09 GIT binary patch literal 247 zcmYLDyH3ME5F9&^@&F6UR8fjlsdy+=8X6>MsMDR+_S!Krch)^{%-2xz5fuCY-;*|L zH<4DF+1Z`lIRTicD#zP*`P%Se@*=`5X;o>DjqsS1^S06@#?lqWVCrq~hf1?^h$2!& zZOEhB|7`zno}b3zC2Og}u6N%d7C0ilA4rGzVIW@^Jz~*sxR9Fkoijf?=t3jnOq&*~ zzvOor0oQqIxqzk*b`52Gi7LY@%OxNCTq#*#PD+QmR-aS{MzU@XYz5_{Bz7yQ%;XH5 E0W1|g&Hw-a literal 0 HcmV?d00001 diff --git a/tests/data/smorgasbord.xml b/tests/data/smorgasbord.xml new file mode 100644 index 0000000..b543c2d --- /dev/null +++ b/tests/data/smorgasbord.xml @@ -0,0 +1,29 @@ + + + + 4ea067497065180748000000 + 42 + foo + true + 42.12345 + + x + y + z + + yup + + + 1231515664416 + + namespace + 4ea067497065180748010000 + + + foobar + + + + this is code + + diff --git a/tests/test_round_trip.rb b/tests/test_round_trip.rb new file mode 100644 index 0000000..0670222 --- /dev/null +++ b/tests/test_round_trip.rb @@ -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