Browse Source

Implemented DictionaryGenericSerializer.

pull/27/head
rstam 15 years ago
parent
commit
d2b72a19c9
  1. 3
      Bson/Bson.csproj
  2. 3
      Bson/DefaultSerializer/Serializers/CollectionGenericSerializers.cs
  3. 158
      Bson/DefaultSerializer/Serializers/DictionaryGenericSerializer.cs
  4. 48
      Bson/DefaultSerializer/Serializers/DictionarySerializer.cs
  5. 1
      BsonUnitTests/BsonUnitTests.csproj
  6. 546
      BsonUnitTests/DefaultSerializer/Serializers/DictionaryGenericSerializerTests.cs

3
Bson/Bson.csproj

@ -87,8 +87,9 @@
<Compile Include="DefaultSerializer\Conventions\ElementNameConventions.cs" />
<Compile Include="DefaultSerializer\Conventions\IdMemberConventions.cs" />
<Compile Include="DefaultSerializer\Conventions\IgnoreExtraElementsConventions.cs" />
<Compile Include="DefaultSerializer\Serializers\CollectionSerializersGeneric.cs" />
<Compile Include="DefaultSerializer\Serializers\CollectionGenericSerializers.cs" />
<Compile Include="DefaultSerializer\Serializers\CollectionSerializers.cs" />
<Compile Include="DefaultSerializer\Serializers\DictionaryGenericSerializer.cs" />
<Compile Include="DefaultSerializer\Serializers\DictionarySerializer.cs" />
<Compile Include="DefaultSerializer\Serializers\NullableTypeSerializer.cs" />
<Compile Include="DefaultSerializer\Serializers\ObjectSerializer.cs" />

3
Bson/DefaultSerializer/Serializers/CollectionSerializersGeneric.cs → Bson/DefaultSerializer/Serializers/CollectionGenericSerializers.cs

@ -39,6 +39,9 @@ namespace MongoDB.Bson.DefaultSerializer {
public class EnumerableSerializer<T> : BsonBaseSerializer {
#region constructors
public EnumerableSerializer() {
}
public EnumerableSerializer(
object serializationOptions
) {

158
Bson/DefaultSerializer/Serializers/DictionaryGenericSerializer.cs

@ -0,0 +1,158 @@
/* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
namespace MongoDB.Bson.DefaultSerializer {
public static class DictionarySerializerRegistration {
#region public static methods
public static void RegisterGenericSerializerDefinitions() {
BsonSerializer.RegisterGenericSerializerDefinition(typeof(Dictionary<,>), typeof(DictionarySerializer<,>));
BsonSerializer.RegisterGenericSerializerDefinition(typeof(IDictionary<,>), typeof(DictionarySerializer<,>));
BsonSerializer.RegisterGenericSerializerDefinition(typeof(SortedDictionary<,>), typeof(DictionarySerializer<,>));
BsonSerializer.RegisterGenericSerializerDefinition(typeof(SortedList<,>), typeof(DictionarySerializer<,>));
}
#endregion
}
public class DictionarySerializer<TKey, TValue> : BsonBaseSerializer {
#region constructors
public DictionarySerializer() {
}
public DictionarySerializer(
object serializationOptions
) {
}
#endregion
#region public methods
public override object Deserialize(
BsonReader bsonReader,
Type nominalType
) {
var bsonType = bsonReader.CurrentBsonType;
if (bsonType == BsonType.Null) {
bsonReader.ReadNull();
return null;
} else if (bsonType == BsonType.Document) {
var dictionary = CreateInstance(nominalType);
bsonReader.ReadStartDocument();
var valueDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TValue));
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
var key = (TKey) (object) bsonReader.ReadName();
var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue));
var valueSerializer = BsonSerializer.LookupSerializer(valueType);
var value = (TValue) valueSerializer.Deserialize(bsonReader, typeof(TValue));
dictionary.Add(key, value);
}
bsonReader.ReadEndDocument();
return dictionary;
} else if (bsonType == BsonType.Array) {
var dictionary = CreateInstance(nominalType);
bsonReader.ReadStartArray();
var keyDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TKey));
var valueDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TValue));
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
bsonReader.SkipName();
bsonReader.ReadStartArray();
bsonReader.ReadBsonType();
bsonReader.SkipName();
var keyType = keyDiscriminatorConvention.GetActualType(bsonReader, typeof(TKey));
var keySerializer = BsonSerializer.LookupSerializer(keyType);
var key = (TKey) keySerializer.Deserialize(bsonReader, typeof(TKey));
bsonReader.ReadBsonType();
bsonReader.SkipName();
var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue));
var valueSerializer = BsonSerializer.LookupSerializer(valueType);
var value = (TValue) valueSerializer.Deserialize(bsonReader, typeof(TValue));
bsonReader.ReadEndArray();
dictionary.Add(key, value);
}
bsonReader.ReadEndArray();
return dictionary;
} else {
var message = string.Format("Can't deserialize a {0} from BsonType {1}", nominalType.FullName, bsonType);
throw new FileFormatException(message);
}
}
public override void Serialize(
BsonWriter bsonWriter,
Type nominalType,
object value,
bool serializeIdFirst
) {
if (value == null) {
bsonWriter.WriteNull();
} else {
var dictionary = (IDictionary<TKey, TValue>) value;
if (
typeof(TKey) == typeof(string) ||
(typeof(TKey) == typeof(object) && dictionary.Keys.All(o => o.GetType() == typeof(string)))
) {
bsonWriter.WriteStartDocument();
int index = 0;
foreach (KeyValuePair<TKey, TValue> entry in dictionary) {
bsonWriter.WriteName((string) (object) entry.Key);
BsonSerializer.Serialize(bsonWriter, typeof(TValue), entry.Value);
index++;
}
bsonWriter.WriteEndDocument();
} else {
bsonWriter.WriteStartArray();
int index = 0;
foreach (KeyValuePair<TKey, TValue> entry in dictionary) {
bsonWriter.WriteStartArray(index.ToString());
bsonWriter.WriteName("0");
BsonSerializer.Serialize(bsonWriter, typeof(object), entry.Key);
bsonWriter.WriteName("1");
BsonSerializer.Serialize(bsonWriter, typeof(object), entry.Value);
bsonWriter.WriteEndArray();
index++;
}
bsonWriter.WriteEndArray();
}
}
}
#endregion
#region private methods
private IDictionary<TKey, TValue> CreateInstance(
Type nominalType
) {
if (nominalType == typeof(Dictionary<TKey, TValue>)) {
return new Dictionary<TKey, TValue>();
} else if (nominalType == typeof(IDictionary<TKey, TValue>)) {
return new Dictionary<TKey, TValue>();
} else if (nominalType == typeof(SortedDictionary<TKey, TValue>)) {
return new SortedDictionary<TKey, TValue>();
} else if (nominalType == typeof(SortedList<TKey, TValue>)) {
return new SortedList<TKey, TValue>();
} else {
var message = string.Format("Invalid nominalType for DictionarySerializer<{0}, {1}>: {2}", typeof(TKey).FullName, typeof(TValue).FullName, nominalType.FullName);
throw new BsonSerializationException(message);
}
}
#endregion
}
}

48
Bson/DefaultSerializer/Serializers/DictionarySerializer.cs

@ -59,6 +59,19 @@ namespace MongoDB.Bson.DefaultSerializer {
if (bsonType == BsonType.Null) {
bsonReader.ReadNull();
return null;
} else if (bsonType == BsonType.Document) {
var dictionary = CreateInstance(nominalType);
bsonReader.ReadStartDocument();
var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
var key = bsonReader.ReadName();
var valueType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
var valueSerializer = BsonSerializer.LookupSerializer(valueType);
var value = valueSerializer.Deserialize(bsonReader, typeof(object));
dictionary.Add(key, value);
}
bsonReader.ReadEndDocument();
return dictionary;
} else if (bsonType == BsonType.Array) {
var dictionary = CreateInstance(nominalType);
bsonReader.ReadStartArray();
@ -81,19 +94,6 @@ namespace MongoDB.Bson.DefaultSerializer {
}
bsonReader.ReadEndArray();
return dictionary;
} else if (bsonType == BsonType.Document) {
var dictionary = CreateInstance(nominalType);
bsonReader.ReadStartDocument();
var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
var key = bsonReader.ReadName();
var valueType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
var valueSerializer = BsonSerializer.LookupSerializer(valueType);
var value = valueSerializer.Deserialize(bsonReader, typeof(object));
dictionary.Add(key, value);
}
bsonReader.ReadEndDocument();
return dictionary;
} else {
var message = string.Format("Can't deserialize a {0} from BsonType {1}", nominalType.FullName, bsonType);
throw new FileFormatException(message);
@ -110,7 +110,16 @@ namespace MongoDB.Bson.DefaultSerializer {
bsonWriter.WriteNull();
} else {
var dictionary = (IDictionary) value;
if (dictionary.Keys.Cast<object>().Any(o => o.GetType() != typeof(string))) {
if (dictionary.Keys.Cast<object>().All(o => o.GetType() == typeof(string))) {
bsonWriter.WriteStartDocument();
int index = 0;
foreach (DictionaryEntry entry in dictionary) {
bsonWriter.WriteName((string) entry.Key);
BsonSerializer.Serialize(bsonWriter, typeof(object), entry.Value);
index++;
}
bsonWriter.WriteEndDocument();
} else {
bsonWriter.WriteStartArray();
int index = 0;
foreach (DictionaryEntry entry in dictionary) {
@ -123,16 +132,7 @@ namespace MongoDB.Bson.DefaultSerializer {
index++;
}
bsonWriter.WriteEndArray();
} else {
bsonWriter.WriteStartDocument();
int index = 0;
foreach (DictionaryEntry entry in dictionary) {
bsonWriter.WriteName((string) entry.Key);
BsonSerializer.Serialize(bsonWriter, typeof(object), entry.Value);
index++;
}
bsonWriter.WriteEndDocument();
}
}
}
}
#endregion

1
BsonUnitTests/BsonUnitTests.csproj

@ -85,6 +85,7 @@
<Compile Include="DefaultSerializer\Serializers\DateTimeSerializerTests.cs" />
<Compile Include="DefaultSerializer\Serializers\CollectionSerializerGenericTests.cs" />
<Compile Include="DefaultSerializer\Serializers\CollectionSerializerTests.cs" />
<Compile Include="DefaultSerializer\Serializers\DictionaryGenericSerializerTests.cs" />
<Compile Include="DefaultSerializer\Serializers\DictionarySerializerTests.cs" />
<Compile Include="DefaultSerializer\Serializers\KnownTypesTests.cs" />
<Compile Include="DefaultSerializer\Serializers\NullableTypeSerializerTests.cs" />

546
BsonUnitTests/DefaultSerializer/Serializers/DictionaryGenericSerializerTests.cs

@ -0,0 +1,546 @@
/* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using MongoDB.Bson;
using MongoDB.Bson.DefaultSerializer;
using MongoDB.Bson.Serialization;
namespace MongoDB.BsonUnitTests.DefaultSerializer.DictionaryGenericSerializers {
[BsonDiscriminator("DictionaryGenericSerializers.C")] // "C" is an ambiguous discriminator when nominalType is System.Object
public class C {
public string P { get; set; }
}
[TestFixture]
public class DictionaryGenericSerializerTests {
public class T {
public Dictionary<object, object> D { get; set; }
public IDictionary<object, object> ID { get; set; }
public SortedDictionary<object, object> SD { get; set; }
public SortedList<object, object> SL { get; set; }
}
[Test]
public void TestNull() {
var obj = new T { D = null, ID = null, SD = null, SL = null };
var json = obj.ToJson();
var rep = "null";
var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsNull(rehydrated.D);
Assert.IsNull(rehydrated.ID);
Assert.IsNull(rehydrated.SD);
Assert.IsNull(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestEmpty() {
var d = new Dictionary<object, object>();
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var rep = "{ }";
var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestOneC() {
var d = new Dictionary<object, object> { { "A", new C { P = "x" } } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var rep = "{ 'A' : { '_t' : 'DictionaryGenericSerializers.C', 'P' : 'x' } }";
var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestOneInt() {
var d = new Dictionary<object, object> { { "A", 1 } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var rep = "{ 'A' : 1 }";
var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestOneIntWithIntKey() {
var d = new Dictionary<object, object> { { 1, 2 } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var rep = "[[1, 2]]";
var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestOneString() {
var d = new Dictionary<object, object> { { "A", "x" } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var rep = "{ 'A' : 'x' }";
var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestOneStringWithIntKey() {
var d = new Dictionary<object, object> { { 1, "x" } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var rep = "[[1, 'x']]";
var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestTwoCs() {
var d = new Dictionary<object, object> { { "A", new C { P = "x" } }, { "B", new C { P = "y" } } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ "A", "{ '_t' : 'DictionaryGenericSerializers.C', 'P' : 'x' }"},
{ "B", "{ '_t' : 'DictionaryGenericSerializers.C', 'P' : 'y' }"}
};
var htRep = GetDocumentRepresentationInKeyOrder(d, reps);
var sdRep = GetDocumentRepresentationInKeyOrder(sd, reps);
var slRep = GetDocumentRepresentationInKeyOrder(sl, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("#SD", sdRep);
expected = expected.Replace("#SL", slRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestTwoCsWithIntKeys() {
var d = new Dictionary<object, object> { { 1, new C { P = "x" } }, { 2, new C { P = "y" } } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ 1, "[1, { '_t' : 'DictionaryGenericSerializers.C', 'P' : 'x' }]"},
{ 2, "[2, { '_t' : 'DictionaryGenericSerializers.C', 'P' : 'y' }]"}
};
var htRep = GetArrayRepresentationInKeyOrder(d, reps);
var sdRep = GetArrayRepresentationInKeyOrder(sd, reps);
var slRep = GetArrayRepresentationInKeyOrder(sl, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("#SD", sdRep);
expected = expected.Replace("#SL", slRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestTwoInts() {
var d = new Dictionary<object, object> { { "A", 1 }, { "B", 2 } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ "A", "1"},
{ "B", "2"}
};
var htRep = GetDocumentRepresentationInKeyOrder(d, reps);
var sdRep = GetDocumentRepresentationInKeyOrder(sd, reps);
var slRep = GetDocumentRepresentationInKeyOrder(sl, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("#SD", sdRep);
expected = expected.Replace("#SL", slRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestTwoIntsWithIntKeys() {
var d = new Dictionary<object, object> { { 1, 2 }, { 3, 4 } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ 1, "[1, 2]"},
{ 3, "[3, 4]"}
};
var htRep = GetArrayRepresentationInKeyOrder(d, reps);
var sdRep = GetArrayRepresentationInKeyOrder(sd, reps);
var slRep = GetArrayRepresentationInKeyOrder(sl, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("#SD", sdRep);
expected = expected.Replace("#SL", slRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestTwoStrings() {
var d = new Dictionary<object, object> { { "A", "x" }, { "B", "y" } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ "A", "'x'"},
{ "B", "'y'"}
};
var htRep = GetDocumentRepresentationInKeyOrder(d, reps);
var sdRep = GetDocumentRepresentationInKeyOrder(sd, reps);
var slRep = GetDocumentRepresentationInKeyOrder(sl, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("#SD", sdRep);
expected = expected.Replace("#SL", slRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestTwoStringsWithIntKeys() {
var d = new Dictionary<object, object> { { 1, "x" }, { 2, "y" } };
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ 1, "[1, 'x']"},
{ 2, "[2, 'y']"}
};
var htRep = GetArrayRepresentationInKeyOrder(d, reps);
var sdRep = GetArrayRepresentationInKeyOrder(sd, reps);
var slRep = GetArrayRepresentationInKeyOrder(sl, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("#SD", sdRep);
expected = expected.Replace("#SL", slRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestMixedPrimitiveTypes() {
var dateTime = DateTime.SpecifyKind(new DateTime(2010, 1, 1, 11, 22, 33), DateTimeKind.Utc);
var millis = (long) ((dateTime - BsonConstants.UnixEpoch).TotalMilliseconds);
var guid = Guid.Empty;
var objectId = ObjectId.Empty;
var d = new Dictionary<object, object> {
{ "A", true },
{ "B", dateTime },
{ "C", 1.5 },
{ "D", 1 },
{ "E", 2L },
{ "F", guid },
{ "G", objectId },
{ "H", "x" }
};
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ "A", "true" },
{ "B", "{ '$date' : #ms }".Replace("#ms", millis.ToString()) },
{ "C", "1.5" },
{ "D", "1" },
{ "E", "2" },
{ "F", "{ '$binary' : 'AAAAAAAAAAAAAAAAAAAAAA==', '$type' : '03' }" },
{ "G", "{ '$oid' : '000000000000000000000000' }" },
{ "H", "'x'" }
};
var htRep = GetDocumentRepresentationInKeyOrder(d, reps);
var sdRep = GetDocumentRepresentationInKeyOrder(sd, reps);
var slRep = GetDocumentRepresentationInKeyOrder(sl, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("#SD", sdRep);
expected = expected.Replace("#SL", slRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestMixedPrimitiveTypesWithIntKeys() {
var dateTime = DateTime.SpecifyKind(new DateTime(2010, 1, 1, 11, 22, 33), DateTimeKind.Utc);
var millis = (long) ((dateTime - BsonConstants.UnixEpoch).TotalMilliseconds);
var guid = Guid.Empty;
var objectId = ObjectId.Empty;
var d = new Dictionary<object, object> {
{ 1, true },
{ 2, dateTime },
{ 3, 1.5 },
{ 4, 1 },
{ 5, 2L },
{ 6, guid },
{ 7, objectId },
{ 8, "x" }
};
var sd = CreateSortedDictionary(d);
var sl = CreateSortedList(d);
var obj = new T { D = d, ID = d, SD = sd, SL = sl };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ 1, "[1, true]" },
{ 2, "[2, { '$date' : #ms }]".Replace("#ms", millis.ToString()) },
{ 3, "[3, 1.5]" },
{ 4, "[4, 1]" },
{ 5, "[5, 2]" },
{ 6, "[6, { '$binary' : 'AAAAAAAAAAAAAAAAAAAAAA==', '$type' : '03' }]" },
{ 7, "[7, { '$oid' : '000000000000000000000000' }]" },
{ 8, "[8, 'x']" }
};
var htRep = GetArrayRepresentationInKeyOrder(d, reps);
var sdRep = GetArrayRepresentationInKeyOrder(sd, reps);
var slRep = GetArrayRepresentationInKeyOrder(sl, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("#SD", sdRep);
expected = expected.Replace("#SL", slRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
[Test]
public void TestMixedPrimitiveTypesWithMixedKeys() {
// note: no SortedDictionary or SortedList in this test because you can't sort a set of keys that have mixed types
var dateTime = DateTime.SpecifyKind(new DateTime(2010, 1, 1, 11, 22, 33), DateTimeKind.Utc);
var millis = (long) ((dateTime - BsonConstants.UnixEpoch).TotalMilliseconds);
var guid = Guid.Empty;
var objectId = ObjectId.Empty;
var d = new Dictionary<object, object> {
{ "A", true },
{ "B", dateTime },
{ "C", 1.5 },
{ "D", 1 },
{ 4, 2L },
{ 5.0, guid },
{ true, objectId },
{ false, "x" }
};
var obj = new T { D = d, ID = d, SD = null, SL = null };
var json = obj.ToJson();
var reps = new Dictionary<object, object> {
{ "A", "['A', true]" },
{ "B", "['B', { '$date' : #ms }]".Replace("#ms", millis.ToString()) },
{ "C", "['C', 1.5]" },
{ "D", "['D', 1]" },
{ 4, "[4, 2]" },
{ 5.0, "[5, { '$binary' : 'AAAAAAAAAAAAAAAAAAAAAA==', '$type' : '03' }]" },
{ true, "[true, { '$oid' : '000000000000000000000000' }]" },
{ false, "[false, 'x']" }
};
var htRep = GetArrayRepresentationInKeyOrder(d, reps);
var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : null, 'SL' : null }";
expected = expected.Replace("#D", htRep);
expected = expected.Replace("'", "\"");
Assert.AreEqual(expected, json);
var bson = obj.ToBson();
var rehydrated = BsonSerializer.Deserialize<T>(bson);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
Assert.IsNull(rehydrated.SD);
Assert.IsNull(rehydrated.SL);
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
}
private SortedDictionary<object, object> CreateSortedDictionary(
Dictionary<object, object> d
) {
var sd = new SortedDictionary<object, object>();
foreach (KeyValuePair<object, object> entry in d) {
sd.Add(entry.Key, entry.Value);
}
return sd;
}
private SortedList<object, object> CreateSortedList(
Dictionary<object, object> d
) {
var sl = new SortedList<object, object>();
foreach (KeyValuePair<object, object> entry in d) {
sl.Add(entry.Key, entry.Value);
}
return sl;
}
private string GetArrayRepresentationInKeyOrder(
IDictionary<object, object> dictionary,
IDictionary<object, object> representations
) {
var sb = new StringBuilder();
foreach (var key in dictionary.Keys) {
sb.Append((sb.Length == 0) ? "[" : ", ");
sb.Append(representations[key]);
}
sb.Append("]");
return sb.ToString();
}
private string GetDocumentRepresentationInKeyOrder(
IDictionary<object, object> dictionary,
IDictionary<object, object> representations
) {
var sb = new StringBuilder();
foreach (var key in dictionary.Keys) {
sb.Append((sb.Length == 0) ? "{ " : ", ");
sb.AppendFormat("'{0}' : {1}", key, representations[key]);
}
sb.Append(" }");
return sb.ToString();
}
}
}
Loading…
Cancel
Save