
6 changed files with 734 additions and 25 deletions
-
3Bson/Bson.csproj
-
3Bson/DefaultSerializer/Serializers/CollectionGenericSerializers.cs
-
158Bson/DefaultSerializer/Serializers/DictionaryGenericSerializer.cs
-
48Bson/DefaultSerializer/Serializers/DictionarySerializer.cs
-
1BsonUnitTests/BsonUnitTests.csproj
-
546BsonUnitTests/DefaultSerializer/Serializers/DictionaryGenericSerializerTests.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
|
|||
} |
|||
} |
@ -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(); |
|||
} |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue