mongo 1.8.4 → 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +6 -14
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +2 -0
- data/VERSION +1 -1
- data/lib/mongo.rb +11 -9
- data/lib/mongo/collection.rb +26 -19
- data/lib/mongo/cursor.rb +7 -2
- data/lib/mongo/db.rb +1 -1
- data/lib/mongo/mongo_client.rb +1 -1
- data/lib/mongo/mongo_replica_set_client.rb +2 -3
- data/lib/mongo/mongo_sharded_client.rb +1 -2
- data/lib/mongo/util/node.rb +12 -14
- data/lib/mongo/util/pool.rb +1 -1
- data/lib/mongo/util/pool_manager.rb +13 -15
- data/lib/mongo/util/sharding_pool_manager.rb +5 -2
- data/lib/mongo/util/support.rb +14 -0
- data/mongo.gemspec +7 -3
- data/test/functional/authentication_test.rb +21 -0
- data/test/functional/collection_test.rb +0 -1
- data/test/functional/connection_test.rb +1 -1
- data/test/functional/db_test.rb +1 -56
- data/test/functional/support_test.rb +30 -0
- data/test/replica_set/authentication_test.rb +23 -0
- data/test/replica_set/max_values_test.rb +61 -0
- data/test/sharded_cluster/basic_test.rb +18 -0
- data/test/shared/authentication.rb +49 -0
- data/test/tools/mongo_config.rb +21 -26
- data/test/unit/node_test.rb +3 -0
- data/test/unit/pool_manager_test.rb +3 -1
- data/test/unit/read_test.rb +4 -0
- data/test/unit/sharding_pool_manager_test.rb +88 -0
- metadata +38 -69
- metadata.gz.sig +0 -0
- data/test/auxillary/1.4_feature_test.rb +0 -165
- data/test/auxillary/authentication_test.rb +0 -74
- data/test/auxillary/autoreconnect_test.rb +0 -39
- data/test/auxillary/fork_test.rb +0 -28
- data/test/auxillary/pool_reuse_test.rb +0 -65
- data/test/auxillary/repl_set_auth_test.rb +0 -69
- data/test/auxillary/slave_connection_test.rb +0 -37
- data/test/auxillary/threaded_authentication_test.rb +0 -99
- data/test/bson/binary_test.rb +0 -13
- data/test/bson/bson_test.rb +0 -762
- data/test/bson/byte_buffer_test.rb +0 -215
- data/test/bson/hash_with_indifferent_access_test.rb +0 -48
- data/test/bson/json_test.rb +0 -16
- data/test/bson/object_id_test.rb +0 -153
- data/test/bson/ordered_hash_test.rb +0 -247
- data/test/bson/timestamp_test.rb +0 -51
- data/test/tools/auth_repl_set_manager.rb +0 -14
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'mongo'
|
3
|
-
|
4
|
-
# NOTE: This test requires bouncing the server
|
5
|
-
class AutoreconnectTest < Test::Unit::TestCase
|
6
|
-
include Mongo
|
7
|
-
|
8
|
-
def setup
|
9
|
-
@client = MongoClient.new
|
10
|
-
@db = @client.db('mongo-ruby-test')
|
11
|
-
@db.drop_collection("test-connect")
|
12
|
-
@coll = @db.collection("test-connect")
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_query
|
16
|
-
@coll.save({:a => 20})
|
17
|
-
@coll.save({:a => 30})
|
18
|
-
@coll.save({:a => 40})
|
19
|
-
results = []
|
20
|
-
@coll.find.each {|r| results << r}
|
21
|
-
[20, 30, 40].each do |a|
|
22
|
-
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
23
|
-
end
|
24
|
-
|
25
|
-
puts "Please disconnect and then reconnect the current master."
|
26
|
-
gets
|
27
|
-
|
28
|
-
begin
|
29
|
-
@coll.find.to_a
|
30
|
-
rescue Mongo::ConnectionFailure
|
31
|
-
end
|
32
|
-
|
33
|
-
results = []
|
34
|
-
@coll.find.each {|r| results << r}
|
35
|
-
[20, 30, 40].each do |a|
|
36
|
-
assert results.any? {|r| r['a'] == a}, "Could not find record for a => #{a}"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/test/auxillary/fork_test.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'mongo'
|
3
|
-
|
4
|
-
class ForkTest < Test::Unit::TestCase
|
5
|
-
include Mongo
|
6
|
-
|
7
|
-
def setup
|
8
|
-
@client = standard_connection
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_fork
|
12
|
-
# Now insert some data
|
13
|
-
10.times do |n|
|
14
|
-
@client[MONGO_TEST_DB]['nums'].insert({:a => n})
|
15
|
-
end
|
16
|
-
|
17
|
-
# Now fork. You'll almost always see an exception here.
|
18
|
-
if !Kernel.fork
|
19
|
-
10.times do
|
20
|
-
assert @client[MONGO_TEST_DB]['nums'].find_one
|
21
|
-
end
|
22
|
-
else
|
23
|
-
10.times do
|
24
|
-
assert @client[MONGO_TEST_DB]['nums'].find_one
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'mongo'
|
3
|
-
|
4
|
-
class PoolReuseTest < Test::Unit::TestCase
|
5
|
-
include Mongo
|
6
|
-
|
7
|
-
def count_open_file_handles
|
8
|
-
@conn["admin"].command(:serverStatus => 1)["connections"]["current"]
|
9
|
-
end
|
10
|
-
|
11
|
-
def setup
|
12
|
-
ensure_cluster(:rs, :replicas => 2, :arbiters => 1)
|
13
|
-
connect
|
14
|
-
end
|
15
|
-
|
16
|
-
def teardown
|
17
|
-
@@cluster.stop if @@cluster
|
18
|
-
@conn.close if @conn
|
19
|
-
end
|
20
|
-
|
21
|
-
def connect
|
22
|
-
@conn.close if @conn
|
23
|
-
@conn = MongoReplicaSetClient.new(["%s:%s" % [@rs.primary.host, @rs.primary.port]])
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_pool_resources_are_reused
|
27
|
-
handles_before_refresh = count_open_file_handles
|
28
|
-
10.times do
|
29
|
-
@conn.hard_refresh!
|
30
|
-
end
|
31
|
-
assert_equal handles_before_refresh, count_open_file_handles
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_pool_connectability_after_cycling_members
|
35
|
-
db = @conn['sample-db']
|
36
|
-
|
37
|
-
assert_equal db.collection_names, []
|
38
|
-
old_primary = @@cluster.primary
|
39
|
-
@conn["admin"].command step_down_command rescue nil
|
40
|
-
old_primary.stop
|
41
|
-
|
42
|
-
rescue_connection_failure do
|
43
|
-
db.collection_names
|
44
|
-
end
|
45
|
-
|
46
|
-
# We should be reconnected to the new master now
|
47
|
-
assert_equal db.collection_names, []
|
48
|
-
|
49
|
-
# Start up the old primary
|
50
|
-
old_primary.start
|
51
|
-
|
52
|
-
# Stop the new primary
|
53
|
-
primary = @@cluster.primary
|
54
|
-
@conn["admin"].command step_down_command rescue nil
|
55
|
-
primary.stop
|
56
|
-
|
57
|
-
# Wait for primary failover
|
58
|
-
rescue_connection_failure do
|
59
|
-
db.collection_names
|
60
|
-
end
|
61
|
-
|
62
|
-
# Reconnect and verify that we can read again
|
63
|
-
assert_equal db.collection_names, []
|
64
|
-
end
|
65
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'mongo'
|
3
|
-
|
4
|
-
class AuthTest < Test::Unit::TestCase
|
5
|
-
include Mongo
|
6
|
-
|
7
|
-
def setup
|
8
|
-
@rs = AuthReplSetManager.new(:start_port => 40000)
|
9
|
-
@rs.start_set
|
10
|
-
end
|
11
|
-
|
12
|
-
def teardown
|
13
|
-
#@rs.cleanup_set
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_repl_set_auth
|
17
|
-
@client = MongoReplicaSetClient.new(build_seeds(3), :name => @rs.name)
|
18
|
-
|
19
|
-
# Add an admin user
|
20
|
-
@client['admin'].add_user("me", "secret")
|
21
|
-
|
22
|
-
# Ensure that insert fails
|
23
|
-
assert_raise_error Mongo::OperationFailure, "unauthorized" do
|
24
|
-
@client['foo']['stuff'].insert({:a => 2}, {:w => 2})
|
25
|
-
end
|
26
|
-
|
27
|
-
# Then authenticate
|
28
|
-
assert @client['admin'].authenticate("me", "secret")
|
29
|
-
|
30
|
-
# Insert should succeed now
|
31
|
-
assert @client['foo']['stuff'].insert({:a => 2}, {:w => 2})
|
32
|
-
|
33
|
-
# So should a query
|
34
|
-
assert @client['foo']['stuff'].find_one
|
35
|
-
|
36
|
-
# But not when we logout
|
37
|
-
@client['admin'].logout
|
38
|
-
|
39
|
-
assert_raise_error Mongo::OperationFailure, "unauthorized" do
|
40
|
-
@client['foo']['stuff'].find_one
|
41
|
-
end
|
42
|
-
|
43
|
-
# Same should apply to a random secondary
|
44
|
-
@slave1 = MongoClient.new(@client.secondary_pools[0].host,
|
45
|
-
@client.secondary_pools[0].port, :slave_ok => true)
|
46
|
-
|
47
|
-
# Find should fail
|
48
|
-
assert_raise_error Mongo::OperationFailure, "unauthorized" do
|
49
|
-
@slave1['foo']['stuff'].find_one
|
50
|
-
end
|
51
|
-
|
52
|
-
# But not when authenticated
|
53
|
-
assert @slave1['admin'].authenticate("me", "secret")
|
54
|
-
assert @slave1['foo']['stuff'].find_one
|
55
|
-
|
56
|
-
# Same should apply when using :secondary_only
|
57
|
-
@second_only = MongoReplicaSetClient.new(build_seeds(3),
|
58
|
-
:require_primary => false, :read => :secondary_only)
|
59
|
-
|
60
|
-
# Find should fail
|
61
|
-
assert_raise_error Mongo::OperationFailure, "unauthorized" do
|
62
|
-
@second_only['foo']['stuff'].find_one
|
63
|
-
end
|
64
|
-
|
65
|
-
# But not when authenticated
|
66
|
-
assert @second_only['admin'].authenticate("me", "secret")
|
67
|
-
assert @second_only['foo']['stuff'].find_one
|
68
|
-
end
|
69
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'mongo'
|
3
|
-
|
4
|
-
# NOTE: these tests are run only if we can connect to a single MongoDB in slave mode.
|
5
|
-
class SlaveConnectionTest < Test::Unit::TestCase
|
6
|
-
include Mongo
|
7
|
-
|
8
|
-
def self.connect_to_slave
|
9
|
-
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
10
|
-
@@port = ENV['MONGO_RUBY_DRIVER_PORT'] || MongoClient::DEFAULT_PORT
|
11
|
-
conn = MongoClient.new(@@host, @@port, :slave_ok => true)
|
12
|
-
response = conn['admin'].command(:ismaster => 1)
|
13
|
-
Mongo::Support.ok?(response) && response['ismaster'] != 1
|
14
|
-
end
|
15
|
-
|
16
|
-
if self.connect_to_slave
|
17
|
-
puts "Connected to slave; running slave tests."
|
18
|
-
|
19
|
-
def test_connect_to_slave
|
20
|
-
assert_raise Mongo::ConnectionFailure do
|
21
|
-
@db = MongoClient.new(@@host, @@port, :slave_ok => false).db('ruby-mongo-demo')
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_slave_ok_sent_to_queries
|
26
|
-
@con = MongoClient.new(@@host, @@port, :slave_ok => true)
|
27
|
-
assert_equal true, @con.slave_ok?
|
28
|
-
end
|
29
|
-
else
|
30
|
-
puts "Not connected to slave; skipping slave connection tests."
|
31
|
-
|
32
|
-
def test_slave_ok_false_on_queries
|
33
|
-
@client = MongoClient.new(@@host, @@port)
|
34
|
-
assert !@client.slave_ok?
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'mongo'
|
3
|
-
require 'thread'
|
4
|
-
|
5
|
-
# NOTE: This test requires bouncing the server.
|
6
|
-
# It also requires that a user exists on the admin database.
|
7
|
-
class AuthenticationTest < Test::Unit::TestCase
|
8
|
-
include Mongo
|
9
|
-
|
10
|
-
def setup
|
11
|
-
@client = standard_connection(:pool_size => 10)
|
12
|
-
@db1 = @client.db('mongo-ruby-test-auth1')
|
13
|
-
@db2 = @client.db('mongo-ruby-test-auth2')
|
14
|
-
@admin = @client.db('admin')
|
15
|
-
end
|
16
|
-
|
17
|
-
def teardown
|
18
|
-
@db1.authenticate('user1', 'secret')
|
19
|
-
@db2.authenticate('user2', 'secret')
|
20
|
-
@client.drop_database('mongo-ruby-test-auth1')
|
21
|
-
@client.drop_database('mongo-ruby-test-auth2')
|
22
|
-
end
|
23
|
-
|
24
|
-
def threaded_exec
|
25
|
-
threads = []
|
26
|
-
|
27
|
-
100.times do
|
28
|
-
threads << Thread.new do
|
29
|
-
yield
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
100.times do |n|
|
34
|
-
threads[n].join
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_authenticate
|
39
|
-
@admin.authenticate('bob', 'secret')
|
40
|
-
@db1.add_user('user1', 'secret')
|
41
|
-
@db2.add_user('user2', 'secret')
|
42
|
-
@admin.logout
|
43
|
-
|
44
|
-
threaded_exec do
|
45
|
-
assert_raise Mongo::OperationFailure do
|
46
|
-
@db1['stuff'].insert({:a => 2})
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
threaded_exec do
|
51
|
-
assert_raise Mongo::OperationFailure do
|
52
|
-
@db2['stuff'].insert({:a => 2})
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
@db1.authenticate('user1', 'secret')
|
57
|
-
@db2.authenticate('user2', 'secret')
|
58
|
-
|
59
|
-
threaded_exec do
|
60
|
-
assert @db1['stuff'].insert({:a => 2})
|
61
|
-
end
|
62
|
-
|
63
|
-
threaded_exec do
|
64
|
-
assert @db2['stuff'].insert({:a => 2})
|
65
|
-
end
|
66
|
-
|
67
|
-
puts "Please bounce the server."
|
68
|
-
gets
|
69
|
-
|
70
|
-
# Here we reconnect.
|
71
|
-
begin
|
72
|
-
@db1['stuff'].find.to_a
|
73
|
-
rescue Mongo::ConnectionFailure
|
74
|
-
end
|
75
|
-
|
76
|
-
threaded_exec do
|
77
|
-
assert @db1['stuff'].insert({:a => 2})
|
78
|
-
end
|
79
|
-
|
80
|
-
threaded_exec do
|
81
|
-
assert @db2['stuff'].insert({:a => 2})
|
82
|
-
end
|
83
|
-
|
84
|
-
@db1.logout
|
85
|
-
threaded_exec do
|
86
|
-
assert_raise Mongo::OperationFailure do
|
87
|
-
@db1['stuff'].insert({:a => 2})
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
@db2.logout
|
92
|
-
threaded_exec do
|
93
|
-
assert_raise Mongo::OperationFailure do
|
94
|
-
assert @db2['stuff'].insert({:a => 2})
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
data/test/bson/binary_test.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# encoding:utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
|
4
|
-
class BinaryTest < Test::Unit::TestCase
|
5
|
-
def setup
|
6
|
-
@data = ("THIS IS BINARY " * 50).unpack("c*")
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_do_not_display_binary_data
|
10
|
-
binary = BSON::Binary.new(@data)
|
11
|
-
assert_equal "<BSON::Binary:#{binary.object_id}>", binary.inspect
|
12
|
-
end
|
13
|
-
end
|
data/test/bson/bson_test.rb
DELETED
@@ -1,762 +0,0 @@
|
|
1
|
-
# encoding:utf-8
|
2
|
-
require 'test_helper'
|
3
|
-
require 'set'
|
4
|
-
|
5
|
-
if RUBY_VERSION < '1.9'
|
6
|
-
silently do
|
7
|
-
require 'complex'
|
8
|
-
require 'rational'
|
9
|
-
end
|
10
|
-
end
|
11
|
-
require 'bigdecimal'
|
12
|
-
|
13
|
-
begin
|
14
|
-
require 'date'
|
15
|
-
require 'tzinfo'
|
16
|
-
require 'active_support/timezone'
|
17
|
-
Time.zone = "Pacific Time (US & Canada)"
|
18
|
-
Zone = Time.zone.now
|
19
|
-
rescue LoadError
|
20
|
-
#warn 'Mocking time with zone'
|
21
|
-
module ActiveSupport
|
22
|
-
class TimeWithZone
|
23
|
-
def initialize(utc_time, zone)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
Zone = ActiveSupport::TimeWithZone.new(Time.now.utc, 'EST')
|
28
|
-
end
|
29
|
-
|
30
|
-
begin
|
31
|
-
require 'active_support/multibyte/chars'
|
32
|
-
rescue LoadError
|
33
|
-
warn 'Mocking ActiveSupport::Multibyte::Chars'
|
34
|
-
module ActiveSupport
|
35
|
-
module Multibyte
|
36
|
-
class Chars < String
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class BSONTest < Test::Unit::TestCase
|
43
|
-
|
44
|
-
include BSON
|
45
|
-
|
46
|
-
def setup
|
47
|
-
@encoder = BSON::BSON_CODER
|
48
|
-
end
|
49
|
-
|
50
|
-
def assert_doc_pass(doc, options={})
|
51
|
-
bson = @encoder.serialize(doc)
|
52
|
-
if options[:debug]
|
53
|
-
puts "DEBUGGING DOC:"
|
54
|
-
p bson.to_a
|
55
|
-
puts "DESERIALIZES TO:"
|
56
|
-
end
|
57
|
-
assert_equal @encoder.serialize(doc).to_a, bson.to_a
|
58
|
-
assert_equal doc, @encoder.deserialize(bson)
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_interface
|
62
|
-
doc = { 'a' => 1 }
|
63
|
-
bson = BSON.serialize(doc)
|
64
|
-
assert_equal doc, BSON.deserialize(bson)
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_read_bson_document
|
68
|
-
bson_file_data_h_star = ["21000000075f6964005115883c3d75c94d3aa18b63016100000000000000f03f00"]
|
69
|
-
strio = StringIO.new(bson_file_data_h_star.pack('H*'))
|
70
|
-
bson = BSON.read_bson_document(strio)
|
71
|
-
doc = {"_id"=>BSON::ObjectId('5115883c3d75c94d3aa18b63'), "a"=>1.0}
|
72
|
-
assert_equal doc, bson
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_bson_ruby_interface
|
76
|
-
doc = { 'a' => 1 }
|
77
|
-
buf = BSON_RUBY.serialize(doc)
|
78
|
-
bson = BSON::BSON_RUBY.new
|
79
|
-
bson.instance_variable_set(:@buf, buf)
|
80
|
-
assert_equal [12, 0, 0, 0, 16, 97, 0, 1, 0, 0, 0, 0], bson.to_a
|
81
|
-
assert_equal "\f\x00\x00\x00\x10a\x00\x01\x00\x00\x00\x00", bson.to_s
|
82
|
-
assert_equal [12, 0, 0, 0, 16, 97, 0, 1, 0, 0, 0, 0], bson.unpack
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_bson_ruby_hex_dump
|
86
|
-
doc = { 'a' => 1 }
|
87
|
-
buf = BSON_RUBY.serialize(doc)
|
88
|
-
bson = BSON_RUBY.new
|
89
|
-
bson.instance_variable_set(:@buf, buf)
|
90
|
-
doc_hex_dump = " 0: 0C 00 00 00 10 61 00 01\n 8: 00 00 00 00"
|
91
|
-
assert_equal doc_hex_dump, bson.hex_dump
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_bson_ruby_dbref_not_used
|
95
|
-
buf = BSON::ByteBuffer.new
|
96
|
-
val = ns = 'namespace'
|
97
|
-
|
98
|
-
# Make a hole for the length
|
99
|
-
len_pos = buf.position
|
100
|
-
buf.put_int(0)
|
101
|
-
|
102
|
-
# Save the string
|
103
|
-
start_pos = buf.position
|
104
|
-
BSON::BSON_RUBY.serialize_cstr(buf, val)
|
105
|
-
end_pos = buf.position
|
106
|
-
|
107
|
-
# Put the string size in front
|
108
|
-
buf.put_int(end_pos - start_pos, len_pos)
|
109
|
-
|
110
|
-
# Go back to where we were
|
111
|
-
buf.position = end_pos
|
112
|
-
|
113
|
-
oid = ObjectId.new
|
114
|
-
buf.put_array(oid.to_a)
|
115
|
-
buf.rewind
|
116
|
-
|
117
|
-
bson = BSON::BSON_RUBY.new
|
118
|
-
bson.instance_variable_set(:@buf, buf)
|
119
|
-
|
120
|
-
assert_equal DBRef.new(ns, oid).to_s, bson.deserialize_dbref_data(buf).to_s
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_require_hash
|
124
|
-
assert_raise_error InvalidDocument, "takes a Hash" do
|
125
|
-
BSON.serialize('foo')
|
126
|
-
end
|
127
|
-
|
128
|
-
assert_raise_error InvalidDocument, "takes a Hash" do
|
129
|
-
BSON.serialize(Object.new)
|
130
|
-
end
|
131
|
-
|
132
|
-
assert_raise_error InvalidDocument, "takes a Hash" do
|
133
|
-
BSON.serialize(Set.new)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def test_string
|
138
|
-
doc = {'doc' => 'hello, world'}
|
139
|
-
assert_doc_pass(doc)
|
140
|
-
end
|
141
|
-
|
142
|
-
def test_valid_utf8_string
|
143
|
-
doc = {'doc' => 'aé'}
|
144
|
-
assert_doc_pass(doc)
|
145
|
-
end
|
146
|
-
|
147
|
-
def test_valid_active_support_multibyte_chars
|
148
|
-
unless RUBY_PLATFORM =~ /java/
|
149
|
-
doc = {'doc' => ActiveSupport::Multibyte::Chars.new('aé')}
|
150
|
-
assert_doc_pass(doc)
|
151
|
-
|
152
|
-
bson = @encoder.serialize(doc)
|
153
|
-
doc = @encoder.deserialize(bson)
|
154
|
-
assert_equal doc['doc'], 'aé'
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def test_valid_utf8_key
|
159
|
-
doc = {'aé' => 'hello'}
|
160
|
-
assert_doc_pass(doc)
|
161
|
-
end
|
162
|
-
|
163
|
-
def test_limit_max_bson_size
|
164
|
-
doc = {'name' => 'a' * BSON::DEFAULT_MAX_BSON_SIZE}
|
165
|
-
assert_raise InvalidDocument do
|
166
|
-
assert @encoder.serialize(doc)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def test_update_max_bson_size
|
171
|
-
require 'ostruct'
|
172
|
-
mock_conn = OpenStruct.new
|
173
|
-
size = 7 * 1024 * 1024
|
174
|
-
mock_conn.max_bson_size = size
|
175
|
-
silently do
|
176
|
-
assert_equal size, BSON_CODER.update_max_bson_size(mock_conn)
|
177
|
-
assert_equal size, BSON_CODER.max_bson_size
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
def test_round_trip
|
182
|
-
doc = {'doc' => 123}
|
183
|
-
@encoder.deserialize(@encoder.serialize(doc))
|
184
|
-
end
|
185
|
-
|
186
|
-
# In 1.8 we test that other string encodings raise an exception.
|
187
|
-
# In 1.9 we test that they get auto-converted.
|
188
|
-
if RUBY_VERSION < '1.9'
|
189
|
-
unless RUBY_PLATFORM == 'java'
|
190
|
-
require 'iconv'
|
191
|
-
def test_non_utf8_string
|
192
|
-
string = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
|
193
|
-
doc = {'doc' => string}
|
194
|
-
assert_raise InvalidStringEncoding do
|
195
|
-
@encoder.serialize(doc)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def test_non_utf8_key
|
200
|
-
key = Iconv.conv('iso-8859-1', 'utf-8', 'aé')
|
201
|
-
doc = {key => 'hello'}
|
202
|
-
assert_raise InvalidStringEncoding do
|
203
|
-
@encoder.serialize(doc)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
else
|
208
|
-
unless RUBY_PLATFORM == 'java'
|
209
|
-
def test_non_utf8_string
|
210
|
-
assert_raise BSON::InvalidStringEncoding do
|
211
|
-
BSON::BSON_CODER.serialize({'str' => 'aé'.encode('iso-8859-1')})
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def test_invalid_utf8_string
|
216
|
-
str = "123\xD9"
|
217
|
-
assert !str.valid_encoding?
|
218
|
-
assert_raise BSON::InvalidStringEncoding do
|
219
|
-
BSON::BSON_CODER.serialize({'str' => str})
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def test_non_utf8_key
|
224
|
-
assert_raise BSON::InvalidStringEncoding do
|
225
|
-
BSON::BSON_CODER.serialize({'aé'.encode('iso-8859-1') => 'hello'})
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def test_forced_encoding_with_valid_utf8
|
230
|
-
doc = {'doc' => "\xC3\xB6".force_encoding("ISO-8859-1")}
|
231
|
-
serialized = @encoder.serialize(doc)
|
232
|
-
deserialized = @encoder.deserialize(serialized)
|
233
|
-
assert_equal(doc['doc'], deserialized['doc'].force_encoding("ISO-8859-1"))
|
234
|
-
end
|
235
|
-
|
236
|
-
# Based on a test from sqlite3-ruby
|
237
|
-
def test_default_internal_is_honored
|
238
|
-
before_enc = Encoding.default_internal
|
239
|
-
|
240
|
-
str = "壁に耳あり、障子に目あり"
|
241
|
-
bson = BSON::BSON_CODER.serialize("x" => str)
|
242
|
-
|
243
|
-
silently { Encoding.default_internal = 'EUC-JP' }
|
244
|
-
out = BSON::BSON_CODER.deserialize(bson)["x"]
|
245
|
-
|
246
|
-
assert_equal Encoding.default_internal, out.encoding
|
247
|
-
assert_equal str.encode('EUC-JP'), out
|
248
|
-
assert_equal str, out.encode(str.encoding)
|
249
|
-
ensure
|
250
|
-
silently { Encoding.default_internal = before_enc }
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
def test_code
|
256
|
-
code = Code.new('this.a.b < this.b')
|
257
|
-
assert_equal 17, code.length
|
258
|
-
assert_match /<BSON::Code:.*@data="this.a.b < this.b".*>/, code.inspect
|
259
|
-
doc = {'$where' => code}
|
260
|
-
assert_doc_pass(doc)
|
261
|
-
code = 'this.c.d < this.e'.to_bson_code # core_ext.rb
|
262
|
-
assert_equal BSON::Code, code.class
|
263
|
-
assert_equal code, code.to_bson_code
|
264
|
-
end
|
265
|
-
|
266
|
-
def test_code_with_symbol
|
267
|
-
assert_raise_error ArgumentError, "BSON::Code must be in the form of a String" do
|
268
|
-
Code.new(:fubar)
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
def test_code_with_scope
|
273
|
-
doc = {'$where' => Code.new('this.a.b < this.b', {'foo' => 1})}
|
274
|
-
assert_doc_pass(doc)
|
275
|
-
end
|
276
|
-
|
277
|
-
def test_double
|
278
|
-
doc = {'doc' => 41.25}
|
279
|
-
assert_doc_pass(doc)
|
280
|
-
end
|
281
|
-
|
282
|
-
def test_int
|
283
|
-
doc = {'doc' => 42}
|
284
|
-
assert_doc_pass(doc)
|
285
|
-
|
286
|
-
doc = {"doc" => -5600}
|
287
|
-
assert_doc_pass(doc)
|
288
|
-
|
289
|
-
doc = {"doc" => 2147483647}
|
290
|
-
assert_doc_pass(doc)
|
291
|
-
|
292
|
-
doc = {"doc" => -2147483648}
|
293
|
-
assert_doc_pass(doc)
|
294
|
-
end
|
295
|
-
|
296
|
-
def test_ordered_hash
|
297
|
-
doc = BSON::OrderedHash.new
|
298
|
-
doc["b"] = 1
|
299
|
-
doc["a"] = 2
|
300
|
-
doc["c"] = 3
|
301
|
-
doc["d"] = 4
|
302
|
-
assert_doc_pass(doc)
|
303
|
-
end
|
304
|
-
|
305
|
-
def test_object
|
306
|
-
doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
|
307
|
-
assert_doc_pass(doc)
|
308
|
-
end
|
309
|
-
|
310
|
-
def test_embedded_document_with_nil
|
311
|
-
doc = {'doc' => {'age' => 42, 'name' => nil, 'shoe_size' => 9.5}}
|
312
|
-
assert_doc_pass(doc)
|
313
|
-
end
|
314
|
-
|
315
|
-
def test_embedded_document_with_date
|
316
|
-
doc = {'doc' => {'age' => 42, 'date' => Time.now.utc, 'shoe_size' => 9.5}}
|
317
|
-
bson = @encoder.serialize(doc)
|
318
|
-
doc2 = @encoder.deserialize(bson)
|
319
|
-
assert doc2['doc']
|
320
|
-
assert_equal 42, doc2['doc']['age']
|
321
|
-
assert_equal 9.5, doc2['doc']['shoe_size']
|
322
|
-
assert_in_delta Time.now, doc2['doc']['date'], 1
|
323
|
-
end
|
324
|
-
|
325
|
-
def test_oid
|
326
|
-
doc = {'doc' => ObjectId.new}
|
327
|
-
assert_doc_pass(doc)
|
328
|
-
end
|
329
|
-
|
330
|
-
def test_array
|
331
|
-
doc = {'doc' => [1, 2, 'a', 'b']}
|
332
|
-
assert_doc_pass(doc)
|
333
|
-
end
|
334
|
-
|
335
|
-
def test_array_keys
|
336
|
-
doc = {'doc' => [1, 2, 'a', 'b']}
|
337
|
-
bson = @encoder.serialize(doc).to_a
|
338
|
-
assert_equal 48, bson[14]
|
339
|
-
assert_equal 49, bson[21]
|
340
|
-
assert_equal 50, bson[28]
|
341
|
-
assert_equal 51, bson[37]
|
342
|
-
end
|
343
|
-
|
344
|
-
def test_regex
|
345
|
-
doc = {'doc' => /foobar/i}
|
346
|
-
assert_doc_pass(doc)
|
347
|
-
end
|
348
|
-
|
349
|
-
def test_regex_multiline
|
350
|
-
doc = {'doc' => /foobar/m}
|
351
|
-
assert_doc_pass(doc)
|
352
|
-
end
|
353
|
-
|
354
|
-
def test_boolean
|
355
|
-
doc = {'doc' => true}
|
356
|
-
assert_doc_pass(doc)
|
357
|
-
end
|
358
|
-
|
359
|
-
def test_date
|
360
|
-
doc = {'date' => Time.now}
|
361
|
-
bson = @encoder.serialize(doc)
|
362
|
-
doc2 = @encoder.deserialize(bson)
|
363
|
-
# Mongo only stores up to the millisecond
|
364
|
-
assert_in_delta doc['date'], doc2['date'], 0.001
|
365
|
-
end
|
366
|
-
|
367
|
-
def test_date_in_array
|
368
|
-
doc = {'date' => [Time.now.utc]}
|
369
|
-
bson = @encoder.serialize(doc)
|
370
|
-
doc2 = @encoder.deserialize(bson)
|
371
|
-
assert doc2
|
372
|
-
end
|
373
|
-
|
374
|
-
def test_date_returns_as_utc
|
375
|
-
doc = {'date' => Time.now.utc}
|
376
|
-
bson = @encoder.serialize(doc)
|
377
|
-
doc2 = @encoder.deserialize(bson)
|
378
|
-
assert doc2['date'].utc?
|
379
|
-
end
|
380
|
-
|
381
|
-
def test_date_before_epoch
|
382
|
-
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ then return true end
|
383
|
-
begin
|
384
|
-
doc = {'date' => Time.utc(1600)}
|
385
|
-
bson = @encoder.serialize(doc)
|
386
|
-
doc2 = @encoder.deserialize(bson)
|
387
|
-
# Mongo only stores up to the millisecond
|
388
|
-
assert_in_delta doc['date'], doc2['date'], 2
|
389
|
-
rescue ArgumentError
|
390
|
-
# some versions of Ruby won't let you create pre-epoch Time instances
|
391
|
-
#
|
392
|
-
# TODO figure out how that will work if somebady has saved data
|
393
|
-
# w/ early dates already and is just querying for it.
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
def test_exeption_on_using_unsupported_date_class
|
398
|
-
[DateTime.now, Date.today, Zone].each do |invalid_date|
|
399
|
-
doc = {:date => invalid_date}
|
400
|
-
begin
|
401
|
-
BSON::BSON_CODER.serialize(doc)
|
402
|
-
rescue => e
|
403
|
-
ensure
|
404
|
-
if !invalid_date.is_a? Time
|
405
|
-
assert_equal InvalidDocument, e.class
|
406
|
-
assert_match(/UTC Time/, e.message)
|
407
|
-
end
|
408
|
-
end
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
def test_dbref
|
413
|
-
oid = ObjectId.new
|
414
|
-
ns = 'namespace'
|
415
|
-
doc = {}
|
416
|
-
dbref = DBRef.new(ns, oid)
|
417
|
-
assert_equal({"$id"=>oid, "$ns"=>ns}, dbref.to_hash)
|
418
|
-
doc['dbref'] = dbref
|
419
|
-
bson = @encoder.serialize(doc)
|
420
|
-
doc2 = @encoder.deserialize(bson)
|
421
|
-
|
422
|
-
# Java doesn't deserialize to DBRefs
|
423
|
-
if RUBY_PLATFORM =~ /java/ && BSON.extension?
|
424
|
-
assert_equal 'namespace', doc2['dbref']['$ns']
|
425
|
-
assert_equal oid, doc2['dbref']['$id']
|
426
|
-
else
|
427
|
-
assert_equal 'namespace', doc2['dbref'].namespace
|
428
|
-
assert_equal oid, doc2['dbref'].object_id
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
def test_symbol
|
433
|
-
doc = {'sym' => :foo}
|
434
|
-
bson = @encoder.serialize(doc)
|
435
|
-
doc2 = @encoder.deserialize(bson)
|
436
|
-
assert_equal :foo, doc2['sym']
|
437
|
-
end
|
438
|
-
|
439
|
-
def test_binary
|
440
|
-
bin = Binary.new
|
441
|
-
'binstring'.each_byte { |b| bin.put(b) }
|
442
|
-
|
443
|
-
doc = {'bin' => bin}
|
444
|
-
bson = @encoder.serialize(doc)
|
445
|
-
doc2 = @encoder.deserialize(bson)
|
446
|
-
bin2 = doc2['bin']
|
447
|
-
assert_kind_of Binary, bin2
|
448
|
-
assert_equal 'binstring', bin2.to_s
|
449
|
-
assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
|
450
|
-
end
|
451
|
-
|
452
|
-
def test_binary_with_deprecated_subtype
|
453
|
-
bin = Binary.new
|
454
|
-
'binstring'.each_byte { |b| bin.put(b) }
|
455
|
-
bin.subtype = Binary::SUBTYPE_BYTES
|
456
|
-
|
457
|
-
doc = {'bin' => bin}
|
458
|
-
bson = @encoder.serialize(doc)
|
459
|
-
doc2 = @encoder.deserialize(bson)
|
460
|
-
bin2 = doc2['bin']
|
461
|
-
assert_kind_of Binary, bin2
|
462
|
-
assert_equal 'binstring', bin2.to_s
|
463
|
-
assert_equal Binary::SUBTYPE_BYTES, bin2.subtype
|
464
|
-
end
|
465
|
-
|
466
|
-
def test_binary_with_string
|
467
|
-
b = Binary.new('somebinarystring')
|
468
|
-
doc = {'bin' => b}
|
469
|
-
bson = @encoder.serialize(doc)
|
470
|
-
doc2 = @encoder.deserialize(bson)
|
471
|
-
bin2 = doc2['bin']
|
472
|
-
assert_kind_of Binary, bin2
|
473
|
-
assert_equal 'somebinarystring', bin2.to_s
|
474
|
-
assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
|
475
|
-
end
|
476
|
-
|
477
|
-
def test_binary_type
|
478
|
-
bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_USER_DEFINED)
|
479
|
-
|
480
|
-
doc = {'bin' => bin}
|
481
|
-
bson = @encoder.serialize(doc)
|
482
|
-
doc2 = @encoder.deserialize(bson)
|
483
|
-
bin2 = doc2['bin']
|
484
|
-
assert_kind_of Binary, bin2
|
485
|
-
assert_equal [1, 2, 3, 4, 5], bin2.to_a
|
486
|
-
assert_equal Binary::SUBTYPE_USER_DEFINED, bin2.subtype
|
487
|
-
end
|
488
|
-
|
489
|
-
# Java doesn't support binary subtype 0 yet
|
490
|
-
if !(RUBY_PLATFORM =~ /java/)
|
491
|
-
def test_binary_subtype_0
|
492
|
-
bin = Binary.new([1, 2, 3, 4, 5], Binary::SUBTYPE_SIMPLE)
|
493
|
-
|
494
|
-
doc = {'bin' => bin}
|
495
|
-
bson = @encoder.serialize(doc)
|
496
|
-
doc2 = @encoder.deserialize(bson)
|
497
|
-
bin2 = doc2['bin']
|
498
|
-
assert_kind_of Binary, bin2
|
499
|
-
assert_equal [1, 2, 3, 4, 5], bin2.to_a
|
500
|
-
assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
def test_binary_byte_buffer
|
505
|
-
bb = Binary.new
|
506
|
-
5.times { |i| bb.put(i + 1) }
|
507
|
-
|
508
|
-
doc = {'bin' => bb}
|
509
|
-
bson = @encoder.serialize(doc)
|
510
|
-
doc2 = @encoder.deserialize(bson)
|
511
|
-
bin2 = doc2['bin']
|
512
|
-
assert_kind_of Binary, bin2
|
513
|
-
assert_equal [1, 2, 3, 4, 5], bin2.to_a
|
514
|
-
assert_equal Binary::SUBTYPE_SIMPLE, bin2.subtype
|
515
|
-
end
|
516
|
-
|
517
|
-
def test_put_id_first
|
518
|
-
val = BSON::OrderedHash.new
|
519
|
-
val['not_id'] = 1
|
520
|
-
val['_id'] = 2
|
521
|
-
roundtrip = @encoder.deserialize(@encoder.serialize(val, false, true).to_s)
|
522
|
-
assert_kind_of BSON::OrderedHash, roundtrip
|
523
|
-
assert_equal '_id', roundtrip.keys.first
|
524
|
-
|
525
|
-
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
|
526
|
-
roundtrip = @encoder.deserialize(@encoder.serialize(val, false, true).to_s)
|
527
|
-
assert_kind_of BSON::OrderedHash, roundtrip
|
528
|
-
assert_equal '_id', roundtrip.keys.first
|
529
|
-
end
|
530
|
-
|
531
|
-
def test_nil_id
|
532
|
-
doc = {"_id" => nil}
|
533
|
-
assert_doc_pass(doc)
|
534
|
-
end
|
535
|
-
|
536
|
-
if !(RUBY_PLATFORM =~ /java/)
|
537
|
-
def test_timestamp
|
538
|
-
# val = {"test" => [4, 20]}
|
539
|
-
result = @encoder.deserialize([0x13, 0x00, 0x00, 0x00,
|
540
|
-
0x11, 0x74, 0x65, 0x73,
|
541
|
-
0x74, 0x00, 0x04, 0x00,
|
542
|
-
0x00, 0x00, 0x14, 0x00,
|
543
|
-
0x00, 0x00, 0x00])
|
544
|
-
|
545
|
-
silently do
|
546
|
-
assert_equal 4, result["test"][0]
|
547
|
-
assert_equal 20, result["test"][1]
|
548
|
-
end
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
|
-
def test_timestamp_type
|
553
|
-
ts = Timestamp.new(5000, 100)
|
554
|
-
doc = {:ts => ts}
|
555
|
-
bson = @encoder.serialize(doc)
|
556
|
-
assert_equal ts, @encoder.deserialize(bson)["ts"]
|
557
|
-
end
|
558
|
-
|
559
|
-
def test_overflow
|
560
|
-
doc = {"x" => 2**75}
|
561
|
-
assert_raise RangeError do
|
562
|
-
@encoder.serialize(doc)
|
563
|
-
end
|
564
|
-
|
565
|
-
doc = {"x" => 9223372036854775}
|
566
|
-
assert_doc_pass(doc)
|
567
|
-
|
568
|
-
doc = {"x" => 9223372036854775807}
|
569
|
-
assert_doc_pass(doc)
|
570
|
-
|
571
|
-
doc["x"] = doc["x"] + 1
|
572
|
-
assert_raise RangeError do
|
573
|
-
@encoder.serialize(doc)
|
574
|
-
end
|
575
|
-
|
576
|
-
doc = {"x" => -9223372036854775}
|
577
|
-
assert_doc_pass(doc)
|
578
|
-
|
579
|
-
doc = {"x" => -9223372036854775808}
|
580
|
-
assert_doc_pass(doc)
|
581
|
-
|
582
|
-
doc["x"] = doc["x"] - 1
|
583
|
-
assert_raise RangeError do
|
584
|
-
BSON::BSON_CODER.serialize(doc)
|
585
|
-
end
|
586
|
-
end
|
587
|
-
|
588
|
-
def test_invalid_numeric_types
|
589
|
-
[BigDecimal.new("1.0"), Complex(0, 1), Rational(2, 3)].each do |type|
|
590
|
-
doc = {"x" => type}
|
591
|
-
begin
|
592
|
-
@encoder.serialize(doc)
|
593
|
-
rescue => e
|
594
|
-
ensure
|
595
|
-
assert_equal InvalidDocument, e.class
|
596
|
-
assert_match(/Cannot serialize/, e.message)
|
597
|
-
end
|
598
|
-
end
|
599
|
-
end
|
600
|
-
|
601
|
-
def test_do_not_change_original_object
|
602
|
-
val = BSON::OrderedHash.new
|
603
|
-
val['not_id'] = 1
|
604
|
-
val['_id'] = 2
|
605
|
-
assert val.keys.include?('_id')
|
606
|
-
@encoder.serialize(val)
|
607
|
-
assert val.keys.include?('_id')
|
608
|
-
|
609
|
-
val = {'a' => 'foo', 'b' => 'bar', :_id => 42, 'z' => 'hello'}
|
610
|
-
assert val.keys.include?(:_id)
|
611
|
-
@encoder.serialize(val)
|
612
|
-
assert val.keys.include?(:_id)
|
613
|
-
end
|
614
|
-
|
615
|
-
# note we only test for _id here because in the general case we will
|
616
|
-
# write duplicates for :key and "key". _id is a special case because
|
617
|
-
# we call has_key? to check for it's existence rather than just iterating
|
618
|
-
# over it like we do for the rest of the keys. thus, things like
|
619
|
-
# HashWithIndifferentAccess can cause problems for _id but not for other
|
620
|
-
# keys. rather than require rails to test with HWIA directly, we do this
|
621
|
-
# somewhat hacky test.
|
622
|
-
#
|
623
|
-
# Note that the driver only eliminates duplicate ids when move_id is true.
|
624
|
-
def test_no_duplicate_id
|
625
|
-
dup = {"_id" => "foo", :_id => "foo"}
|
626
|
-
one = {"_id" => "foo"}
|
627
|
-
|
628
|
-
assert_equal @encoder.serialize(one, false, true).to_a, @encoder.serialize(dup, false, true).to_a
|
629
|
-
end
|
630
|
-
|
631
|
-
def test_duplicate_keys
|
632
|
-
#dup = {"_foo" => "foo", :_foo => "foo"}
|
633
|
-
#one = {"_foo" => "foo"}
|
634
|
-
|
635
|
-
#assert_equal @encoder.serialize(one).to_a, @encoder.serialize(dup).to_a
|
636
|
-
#warn "Pending test for duplicate keys"
|
637
|
-
end
|
638
|
-
|
639
|
-
def test_no_duplicate_id_when_moving_id
|
640
|
-
dup = {"_id" => "foo", :_id => "foo"}
|
641
|
-
one = {:_id => "foo"}
|
642
|
-
|
643
|
-
assert_equal @encoder.serialize(one, false, true).to_s, @encoder.serialize(dup, false, true).to_s
|
644
|
-
end
|
645
|
-
|
646
|
-
def test_null_character
|
647
|
-
doc = {"a" => "\x00"}
|
648
|
-
|
649
|
-
assert_doc_pass(doc)
|
650
|
-
|
651
|
-
assert_raise InvalidDocument do
|
652
|
-
@encoder.serialize({"\x00" => "a"})
|
653
|
-
end
|
654
|
-
|
655
|
-
assert_raise InvalidDocument do
|
656
|
-
@encoder.serialize({"a" => (Regexp.compile "ab\x00c")})
|
657
|
-
end
|
658
|
-
end
|
659
|
-
|
660
|
-
def test_max_key
|
661
|
-
doc = {"a" => MaxKey.new}
|
662
|
-
assert_doc_pass(doc)
|
663
|
-
end
|
664
|
-
|
665
|
-
def test_min_key
|
666
|
-
doc = {"a" => MinKey.new}
|
667
|
-
assert_doc_pass(doc)
|
668
|
-
end
|
669
|
-
|
670
|
-
def test_invalid_object
|
671
|
-
o = Object.new
|
672
|
-
assert_raise InvalidDocument do
|
673
|
-
@encoder.serialize({:foo => o})
|
674
|
-
end
|
675
|
-
|
676
|
-
assert_raise InvalidDocument do
|
677
|
-
@encoder.serialize({:foo => Date.today})
|
678
|
-
end
|
679
|
-
end
|
680
|
-
|
681
|
-
def test_move_id
|
682
|
-
a = BSON::OrderedHash.new
|
683
|
-
a['text'] = 'abc'
|
684
|
-
a['key'] = 'abc'
|
685
|
-
a['_id'] = 1
|
686
|
-
|
687
|
-
|
688
|
-
assert_equal ")\000\000\000\020_id\000\001\000\000\000\002text" +
|
689
|
-
"\000\004\000\000\000abc\000\002key\000\004\000\000\000abc\000\000",
|
690
|
-
@encoder.serialize(a, false, true).to_s
|
691
|
-
|
692
|
-
assert_equal ")\000\000\000\002text\000\004\000\000\000abc\000\002key" +
|
693
|
-
"\000\004\000\000\000abc\000\020_id\000\001\000\000\000\000",
|
694
|
-
@encoder.serialize(a, false, false).to_s
|
695
|
-
end
|
696
|
-
|
697
|
-
def test_move_id_with_nested_doc
|
698
|
-
b = BSON::OrderedHash.new
|
699
|
-
b['text'] = 'abc'
|
700
|
-
b['_id'] = 2
|
701
|
-
c = BSON::OrderedHash.new
|
702
|
-
c['text'] = 'abc'
|
703
|
-
c['hash'] = b
|
704
|
-
c['_id'] = 3
|
705
|
-
assert_equal ">\000\000\000\020_id\000\003\000\000\000\002text" +
|
706
|
-
"\000\004\000\000\000abc\000\003hash\000\034\000\000" +
|
707
|
-
"\000\002text\000\004\000\000\000abc\000\020_id\000\002\000\000\000\000\000",
|
708
|
-
@encoder.serialize(c, false, true).to_s
|
709
|
-
|
710
|
-
# Java doesn't support this. Isn't actually necessary.
|
711
|
-
if !(RUBY_PLATFORM =~ /java/)
|
712
|
-
assert_equal ">\000\000\000\002text\000\004\000\000\000abc\000\003hash" +
|
713
|
-
"\000\034\000\000\000\002text\000\004\000\000\000abc\000\020_id" +
|
714
|
-
"\000\002\000\000\000\000\020_id\000\003\000\000\000\000",
|
715
|
-
@encoder.serialize(c, false, false).to_s
|
716
|
-
end
|
717
|
-
end
|
718
|
-
|
719
|
-
def test_invalid_key_names
|
720
|
-
assert @encoder.serialize({"hello" => "world"}, true)
|
721
|
-
assert @encoder.serialize({"hello" => {"hello" => "world"}}, true)
|
722
|
-
|
723
|
-
assert @encoder.serialize({"he$llo" => "world"}, true)
|
724
|
-
assert @encoder.serialize({"hello" => {"hell$o" => "world"}}, true)
|
725
|
-
|
726
|
-
assert_raise BSON::InvalidDocument do
|
727
|
-
@encoder.serialize({"he\0llo" => "world"}, true)
|
728
|
-
end
|
729
|
-
|
730
|
-
assert_raise BSON::InvalidKeyName do
|
731
|
-
@encoder.serialize({"$hello" => "world"}, true)
|
732
|
-
end
|
733
|
-
|
734
|
-
assert_raise BSON::InvalidKeyName do
|
735
|
-
@encoder.serialize({"hello" => {"$hello" => "world"}}, true)
|
736
|
-
end
|
737
|
-
|
738
|
-
assert_raise BSON::InvalidKeyName do
|
739
|
-
@encoder.serialize({".hello" => "world"}, true)
|
740
|
-
end
|
741
|
-
|
742
|
-
assert_raise BSON::InvalidKeyName do
|
743
|
-
@encoder.serialize({"hello" => {".hello" => "world"}}, true)
|
744
|
-
end
|
745
|
-
|
746
|
-
assert_raise BSON::InvalidKeyName do
|
747
|
-
@encoder.serialize({"hello." => "world"}, true)
|
748
|
-
end
|
749
|
-
|
750
|
-
assert_raise BSON::InvalidKeyName do
|
751
|
-
@encoder.serialize({"hello" => {"hello." => "world"}}, true)
|
752
|
-
end
|
753
|
-
|
754
|
-
assert_raise BSON::InvalidKeyName do
|
755
|
-
@encoder.serialize({"hel.lo" => "world"}, true)
|
756
|
-
end
|
757
|
-
|
758
|
-
assert_raise BSON::InvalidKeyName do
|
759
|
-
@encoder.serialize({"hello" => {"hel.lo" => "world"}}, true)
|
760
|
-
end
|
761
|
-
end
|
762
|
-
end
|