JRuby Test fixes

This commit is contained in:
Kyle Banker 2010-10-12 15:39:28 -04:00
parent b0f2911170
commit df0377c3d4
13 changed files with 140 additions and 51 deletions

View File

@ -26,8 +26,8 @@ namespace :build do
jar_dir = File.join(java_dir, 'jar') jar_dir = File.join(java_dir, 'jar')
jruby_jar = File.join(jar_dir, 'jruby.jar') jruby_jar = File.join(jar_dir, 'jruby.jar')
mongo_jar = File.join(jar_dir, 'mongo.jar') mongo_jar = File.join(jar_dir, 'mongo-2.2.jar')
bson_jar = File.join(jar_dir, 'bson.jar') bson_jar = File.join(jar_dir, 'bson-2.2.jar')
src_base = File.join(java_dir, 'src') src_base = File.join(java_dir, 'src')
@ -65,7 +65,7 @@ namespace :test do
Rake::Task['test:pooled_threading'].invoke Rake::Task['test:pooled_threading'].invoke
Rake::Task['test:drop_databases'].invoke Rake::Task['test:drop_databases'].invoke
end end
Rake::TestTask.new(:unit) do |t| Rake::TestTask.new(:unit) do |t|
t.test_files = FileList['test/unit/*_test.rb'] t.test_files = FileList['test/unit/*_test.rb']
t.verbose = true t.verbose = true
@ -142,7 +142,7 @@ namespace :test do
end end
Rake::TestTask.new(:bson) do |t| Rake::TestTask.new(:bson) do |t|
t.test_files = FileList['test/mongo_bson/*_test.rb'] t.test_files = FileList['test/bson/*_test.rb']
t.verbose = true t.verbose = true
end end

BIN
ext/java/jar/bson-2.2.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -165,6 +165,13 @@ public class RubyBSONEncoder extends BSONEncoder {
if ( temp instanceof RubyArray ) if ( temp instanceof RubyArray )
transientFields = (RubyArray)temp; transientFields = (RubyArray)temp;
} }
else {
if ( _rbHashHasKey( (RubyHash)o, "_id" ) && _rbHashHasKey( (RubyHash)o, _idAsSym ) ) {
((RubyHash)o).fastDelete(_idAsSym);
}
}
// Not sure we should invoke this way. Depends on if we can access the OrderedHash. // Not sure we should invoke this way. Depends on if we can access the OrderedHash.
RubyArray keys = (RubyArray)JavaEmbedUtils.invokeMethod( _runtime, o , "keys" , new Object[] {} RubyArray keys = (RubyArray)JavaEmbedUtils.invokeMethod( _runtime, o , "keys" , new Object[] {}
@ -383,9 +390,9 @@ public class RubyBSONEncoder extends BSONEncoder {
String klass = JavaEmbedUtils.invokeMethod(_runtime, val, String klass = JavaEmbedUtils.invokeMethod(_runtime, val,
"class", new Object[] {}, Object.class).toString(); "class", new Object[] {}, Object.class).toString();
_rbRaise( (RubyClass)_rbclsInvalidDocument, _rbRaise( (RubyClass)_rbclsInvalidDocument,
"Cannot serialize " + klass + " as a BSON type; " + "Cannot serialize " + klass + " as a BSON type; " +
"it either isn't supported or won't translate to BSON."); "it either isn't supported or won't translate to BSON.");
} }
} }
@ -436,8 +443,30 @@ public class RubyBSONEncoder extends BSONEncoder {
final int sizePos = _buf.getPosition(); final int sizePos = _buf.getPosition();
_buf.writeInt( 0 ); _buf.writeInt( 0 );
for ( Map.Entry entry : (Set<Map.Entry>)m.entrySet() ) RubyArray keys = (RubyArray)JavaEmbedUtils.invokeMethod( _runtime, m , "keys" , new Object[] {} , Object.class);
_putObjectField( entry.getKey().toString() , entry.getValue() );
for (Iterator<RubyObject> i = keys.iterator(); i.hasNext(); ) {
Object hashKey = i.next();
// Convert the key into a Java String
String str = "";
if( hashKey instanceof String) {
str = hashKey.toString();
}
else if (hashKey instanceof RubyString) {
str = ((RubyString)hashKey).asJavaString();
}
else if (hashKey instanceof RubySymbol) {
str = ((RubySymbol)hashKey).asJavaString();
}
RubyObject val = (RubyObject)_rbHashGet( (RubyHash)m, hashKey );
_putObjectField( str , (Object)val );
}
//for ( Map.Entry entry : (Set<Map.Entry>)m.entrySet() )
// _putObjectField( entry.getKey().toString() , entry.getValue() );
_buf.write( EOO ); _buf.write( EOO );
_buf.writeInt( sizePos , _buf.getPosition() - sizePos ); _buf.writeInt( sizePos , _buf.getPosition() - sizePos );

View File

@ -34,8 +34,8 @@ end
if RUBY_PLATFORM =~ /java/ if RUBY_PLATFORM =~ /java/
jar_dir = File.join(File.dirname(__FILE__), '..', 'ext', 'java', 'jar') jar_dir = File.join(File.dirname(__FILE__), '..', 'ext', 'java', 'jar')
require File.join(jar_dir, 'mongo.jar') require File.join(jar_dir, 'mongo-2.2.jar')
require File.join(jar_dir, 'bson.jar') require File.join(jar_dir, 'bson-2.2.jar')
require File.join(jar_dir, 'jbson.jar') require File.join(jar_dir, 'jbson.jar')
require 'bson/bson_java' require 'bson/bson_java'
module BSON module BSON

View File

@ -23,23 +23,19 @@ class BSONTest < Test::Unit::TestCase
include BSON include BSON
# This setup allows us to change the decoders for
# cross-coder compatibility testing
def setup def setup
@encoder = BSON::BSON_CODER @encoder = BSON::BSON_CODER
@decoder = @encoder
end end
def assert_doc_pass(doc, options={}) def assert_doc_pass(doc, options={})
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
if options[:debug] if options[:debug]
puts "DEBUGGIN DOC:" puts "DEBUGGING DOC:"
p bson.to_a p bson.to_a
puts "DESERIALIZES TO:" puts "DESERIALIZES TO:"
p @decoder.deserialize(bson)
end end
assert_equal @decoder.serialize(doc).to_a, bson.to_a assert_equal @encoder.serialize(doc).to_a, bson.to_a
assert_equal doc, @decoder.deserialize(bson) assert_equal doc, @encoder.deserialize(bson)
end end
def test_require_hash def test_require_hash
@ -81,20 +77,23 @@ class BSONTest < Test::Unit::TestCase
# In 1.8 we test that other string encodings raise an exception. # In 1.8 we test that other string encodings raise an exception.
# In 1.9 we test that they get auto-converted. # In 1.9 we test that they get auto-converted.
if RUBY_VERSION < '1.9' if RUBY_VERSION < '1.9'
require 'iconv' if ! RUBY_PLATFORM =~ /java/
def test_invalid_string require 'iconv'
string = Iconv.conv('iso-8859-1', 'utf-8', 'aé') def test_non_utf8_string
doc = {'doc' => string} string = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
assert_raise InvalidStringEncoding do doc = {'doc' => string}
@encoder.serialize(doc) assert_doc_pass(doc)
assert_raise InvalidStringEncoding do
@encoder.serialize(doc)
end
end end
end
def test_invalid_key def test_non_utf8_key
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
@encoder.serialize(doc) @encoder.serialize(doc)
end
end end
end end
else else
@ -176,6 +175,14 @@ class BSONTest < Test::Unit::TestCase
assert_doc_pass(doc) assert_doc_pass(doc)
end end
def test_embedded_document_with_date
doc = {'doc' => {'age' => 42, 'date' => Time.now.utc, 'shoe_size' => 9.5}}
bson = @encoder.serialize(doc)
p doc
p doc['doc']['date'].class
assert_doc_pass(doc)
end
def test_oid def test_oid
doc = {'doc' => ObjectId.new} doc = {'doc' => ObjectId.new}
assert_doc_pass(doc) assert_doc_pass(doc)
@ -199,7 +206,7 @@ class BSONTest < Test::Unit::TestCase
def test_date def test_date
doc = {'date' => Time.now} doc = {'date' => Time.now}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.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
@ -207,7 +214,7 @@ class BSONTest < Test::Unit::TestCase
def test_date_returns_as_utc def test_date_returns_as_utc
doc = {'date' => Time.now} doc = {'date' => Time.now}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.deserialize(bson)
assert doc2['date'].utc? assert doc2['date'].utc?
end end
@ -215,7 +222,7 @@ class BSONTest < Test::Unit::TestCase
begin begin
doc = {'date' => Time.utc(1600)} doc = {'date' => Time.utc(1600)}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.deserialize(bson)
# Mongo only stores up to the millisecond # Mongo only stores up to the millisecond
assert_in_delta doc['date'], doc2['date'], 2 assert_in_delta doc['date'], doc2['date'], 2
rescue ArgumentError rescue ArgumentError
@ -246,7 +253,7 @@ class BSONTest < Test::Unit::TestCase
doc = {} doc = {}
doc['dbref'] = DBRef.new('namespace', oid) doc['dbref'] = DBRef.new('namespace', oid)
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.deserialize(bson)
# Java doesn't deserialize to DBRefs # Java doesn't deserialize to DBRefs
if RUBY_PLATFORM =~ /java/ if RUBY_PLATFORM =~ /java/
@ -261,7 +268,7 @@ class BSONTest < Test::Unit::TestCase
def test_symbol def test_symbol
doc = {'sym' => :foo} doc = {'sym' => :foo}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.deserialize(bson)
assert_equal :foo, doc2['sym'] assert_equal :foo, doc2['sym']
end end
@ -271,7 +278,7 @@ class BSONTest < Test::Unit::TestCase
doc = {'bin' => bin} doc = {'bin' => bin}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.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
@ -282,7 +289,7 @@ class BSONTest < Test::Unit::TestCase
b = Binary.new('somebinarystring') b = Binary.new('somebinarystring')
doc = {'bin' => b} doc = {'bin' => b}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.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
@ -294,7 +301,7 @@ class BSONTest < Test::Unit::TestCase
doc = {'bin' => bin} doc = {'bin' => bin}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.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
@ -308,7 +315,7 @@ class BSONTest < Test::Unit::TestCase
doc = {'bin' => bin} doc = {'bin' => bin}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.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
@ -322,7 +329,7 @@ class BSONTest < Test::Unit::TestCase
doc = {'bin' => bb} doc = {'bin' => bb}
bson = @encoder.serialize(doc) bson = @encoder.serialize(doc)
doc2 = @decoder.deserialize(bson) doc2 = @encoder.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
@ -333,12 +340,12 @@ 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 = @decoder.deserialize(@encoder.serialize(val, false, true).to_s) roundtrip = @encoder.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 = @decoder.deserialize(@encoder.serialize(val, false, true).to_s) roundtrip = @encoder.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
@ -351,7 +358,7 @@ class BSONTest < Test::Unit::TestCase
if !(RUBY_PLATFORM =~ /java/) if !(RUBY_PLATFORM =~ /java/)
def test_timestamp def test_timestamp
val = {"test" => [4, 20]} val = {"test" => [4, 20]}
assert_equal val, @decoder.deserialize([0x13, 0x00, 0x00, 0x00, assert_equal val, @encoder.deserialize([0x13, 0x00, 0x00, 0x00,
0x11, 0x74, 0x65, 0x73, 0x11, 0x74, 0x65, 0x73,
0x74, 0x00, 0x04, 0x00, 0x74, 0x00, 0x04, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00,
@ -430,6 +437,14 @@ class BSONTest < Test::Unit::TestCase
assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a
end end
def test_duplicate_keys
dup = {"_foo" => "foo", :_foo => "foo"}
one = {"_foo" => "foo"}
assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a
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"}

View File

@ -1,6 +1,6 @@
# encoding:utf-8 # encoding:utf-8
require './test/test_helper' require './test/test_helper'
require './test/support/hash_with_indifferent_access' #require './test/support/hash_with_indifferent_access'
class HashWithIndifferentAccessTest < Test::Unit::TestCase class HashWithIndifferentAccessTest < Test::Unit::TestCase
include BSON include BSON

View File

@ -4,13 +4,12 @@ require 'json'
class JSONTest < Test::Unit::TestCase class JSONTest < Test::Unit::TestCase
include Mongo
include BSON
def test_object_id_as_json def test_object_id_as_json
id = ObjectId.new id = BSON::ObjectId.new
p id.to_json
obj = {'_id' => id} obj = {'_id' => id}
assert_equal "{\"_id\":{\"$oid\": \"#{id.to_s}\"}}", obj.to_json assert_equal "{\"_id\":#{id.to_json}}", obj.to_json
end end
end end

View File

@ -1,12 +1,58 @@
# Note: HashWithIndifferentAccess is so commonly used # Note: HashWithIndifferentAccess is so commonly used
# that we always need to make sure that the driver works # that we always need to make sure that the driver works
# with it. # with it.
require File.join(File.dirname(__FILE__), 'keys.rb') #require File.join(File.dirname(__FILE__), 'keys.rb')
# This class has dubious semantics and we only have it so that # This class has dubious semantics and we only have it so that
# people can write params[:key] instead of params['key'] # people can write params[:key] instead of params['key']
# and they get the same value for both keys. # and they get the same value for both keys.
class Hash
# Return a new hash with all keys converted to strings.
def stringify_keys
dup.stringify_keys!
end
# Destructively convert all keys to strings.
def stringify_keys!
keys.each do |key|
self[key.to_s] = delete(key)
end
self
end
# Return a new hash with all keys converted to symbols, as long as
# they respond to +to_sym+.
def symbolize_keys
dup.symbolize_keys!
end
# Destructively convert all keys to symbols, as long as they respond
# to +to_sym+.
def symbolize_keys!
keys.each do |key|
self[(key.to_sym rescue key) || key] = delete(key)
end
self
end
alias_method :to_options, :symbolize_keys
#alias_method :to_options!, :symbolize_keys!
# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
# Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols
# as keys, this will fail.
#
# ==== Examples
# { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
# { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age"
# { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
def assert_valid_keys(*valid_keys)
unknown_keys = keys - [valid_keys].flatten
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
end
end
module ActiveSupport module ActiveSupport
class HashWithIndifferentAccess < Hash class HashWithIndifferentAccess < Hash
def extractable_options? def extractable_options?

View File

@ -28,7 +28,7 @@ class Hash
end end
alias_method :to_options, :symbolize_keys alias_method :to_options, :symbolize_keys
alias_method :to_options!, :symbolize_keys! #alias_method :to_options!, :symbolize_keys!
# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch. # Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
# Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols