You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

546 lines
25 KiB

  1. /* Copyright 2010 10gen Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Text;
  19. using NUnit.Framework;
  20. using MongoDB.Bson;
  21. using MongoDB.Bson.DefaultSerializer;
  22. using MongoDB.Bson.Serialization;
  23. namespace MongoDB.BsonUnitTests.DefaultSerializer.DictionaryGenericSerializers {
  24. [BsonDiscriminator("DictionaryGenericSerializers.C")] // "C" is an ambiguous discriminator when nominalType is System.Object
  25. public class C {
  26. public string P { get; set; }
  27. }
  28. [TestFixture]
  29. public class DictionaryGenericSerializerTests {
  30. public class T {
  31. public Dictionary<object, object> D { get; set; }
  32. public IDictionary<object, object> ID { get; set; }
  33. public SortedDictionary<object, object> SD { get; set; }
  34. public SortedList<object, object> SL { get; set; }
  35. }
  36. [Test]
  37. public void TestNull() {
  38. var obj = new T { D = null, ID = null, SD = null, SL = null };
  39. var json = obj.ToJson();
  40. var rep = "null";
  41. var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
  42. Assert.AreEqual(expected, json);
  43. var bson = obj.ToBson();
  44. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  45. Assert.IsNull(rehydrated.D);
  46. Assert.IsNull(rehydrated.ID);
  47. Assert.IsNull(rehydrated.SD);
  48. Assert.IsNull(rehydrated.SL);
  49. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  50. }
  51. [Test]
  52. public void TestEmpty() {
  53. var d = new Dictionary<object, object>();
  54. var sd = CreateSortedDictionary(d);
  55. var sl = CreateSortedList(d);
  56. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  57. var json = obj.ToJson();
  58. var rep = "{ }";
  59. var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
  60. Assert.AreEqual(expected, json);
  61. var bson = obj.ToBson();
  62. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  63. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  64. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  65. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  66. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  67. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  68. }
  69. [Test]
  70. public void TestOneC() {
  71. var d = new Dictionary<object, object> { { "A", new C { P = "x" } } };
  72. var sd = CreateSortedDictionary(d);
  73. var sl = CreateSortedList(d);
  74. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  75. var json = obj.ToJson();
  76. var rep = "{ 'A' : { '_t' : 'DictionaryGenericSerializers.C', 'P' : 'x' } }";
  77. var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
  78. Assert.AreEqual(expected, json);
  79. var bson = obj.ToBson();
  80. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  81. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  82. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  83. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  84. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  85. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  86. }
  87. [Test]
  88. public void TestOneInt() {
  89. var d = new Dictionary<object, object> { { "A", 1 } };
  90. var sd = CreateSortedDictionary(d);
  91. var sl = CreateSortedList(d);
  92. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  93. var json = obj.ToJson();
  94. var rep = "{ 'A' : 1 }";
  95. var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
  96. Assert.AreEqual(expected, json);
  97. var bson = obj.ToBson();
  98. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  99. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  100. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  101. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  102. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  103. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  104. }
  105. [Test]
  106. public void TestOneIntWithIntKey() {
  107. var d = new Dictionary<object, object> { { 1, 2 } };
  108. var sd = CreateSortedDictionary(d);
  109. var sl = CreateSortedList(d);
  110. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  111. var json = obj.ToJson();
  112. var rep = "[[1, 2]]";
  113. var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
  114. Assert.AreEqual(expected, json);
  115. var bson = obj.ToBson();
  116. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  117. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  118. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  119. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  120. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  121. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  122. }
  123. [Test]
  124. public void TestOneString() {
  125. var d = new Dictionary<object, object> { { "A", "x" } };
  126. var sd = CreateSortedDictionary(d);
  127. var sl = CreateSortedList(d);
  128. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  129. var json = obj.ToJson();
  130. var rep = "{ 'A' : 'x' }";
  131. var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
  132. Assert.AreEqual(expected, json);
  133. var bson = obj.ToBson();
  134. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  135. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  136. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  137. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  138. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  139. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  140. }
  141. [Test]
  142. public void TestOneStringWithIntKey() {
  143. var d = new Dictionary<object, object> { { 1, "x" } };
  144. var sd = CreateSortedDictionary(d);
  145. var sl = CreateSortedList(d);
  146. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  147. var json = obj.ToJson();
  148. var rep = "[[1, 'x']]";
  149. var expected = "{ 'D' : #R, 'ID' : #R, 'SD' : #R, 'SL' : #R }".Replace("#R", rep).Replace("'", "\"");
  150. Assert.AreEqual(expected, json);
  151. var bson = obj.ToBson();
  152. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  153. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  154. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  155. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  156. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  157. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  158. }
  159. [Test]
  160. public void TestTwoCs() {
  161. var d = new Dictionary<object, object> { { "A", new C { P = "x" } }, { "B", new C { P = "y" } } };
  162. var sd = CreateSortedDictionary(d);
  163. var sl = CreateSortedList(d);
  164. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  165. var json = obj.ToJson();
  166. var reps = new Dictionary<object, object> {
  167. { "A", "{ '_t' : 'DictionaryGenericSerializers.C', 'P' : 'x' }"},
  168. { "B", "{ '_t' : 'DictionaryGenericSerializers.C', 'P' : 'y' }"}
  169. };
  170. var htRep = GetDocumentRepresentationInKeyOrder(d, reps);
  171. var sdRep = GetDocumentRepresentationInKeyOrder(sd, reps);
  172. var slRep = GetDocumentRepresentationInKeyOrder(sl, reps);
  173. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
  174. expected = expected.Replace("#D", htRep);
  175. expected = expected.Replace("#SD", sdRep);
  176. expected = expected.Replace("#SL", slRep);
  177. expected = expected.Replace("'", "\"");
  178. Assert.AreEqual(expected, json);
  179. var bson = obj.ToBson();
  180. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  181. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  182. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  183. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  184. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  185. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  186. }
  187. [Test]
  188. public void TestTwoCsWithIntKeys() {
  189. var d = new Dictionary<object, object> { { 1, new C { P = "x" } }, { 2, new C { P = "y" } } };
  190. var sd = CreateSortedDictionary(d);
  191. var sl = CreateSortedList(d);
  192. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  193. var json = obj.ToJson();
  194. var reps = new Dictionary<object, object> {
  195. { 1, "[1, { '_t' : 'DictionaryGenericSerializers.C', 'P' : 'x' }]"},
  196. { 2, "[2, { '_t' : 'DictionaryGenericSerializers.C', 'P' : 'y' }]"}
  197. };
  198. var htRep = GetArrayRepresentationInKeyOrder(d, reps);
  199. var sdRep = GetArrayRepresentationInKeyOrder(sd, reps);
  200. var slRep = GetArrayRepresentationInKeyOrder(sl, reps);
  201. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
  202. expected = expected.Replace("#D", htRep);
  203. expected = expected.Replace("#SD", sdRep);
  204. expected = expected.Replace("#SL", slRep);
  205. expected = expected.Replace("'", "\"");
  206. Assert.AreEqual(expected, json);
  207. var bson = obj.ToBson();
  208. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  209. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  210. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  211. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  212. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  213. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  214. }
  215. [Test]
  216. public void TestTwoInts() {
  217. var d = new Dictionary<object, object> { { "A", 1 }, { "B", 2 } };
  218. var sd = CreateSortedDictionary(d);
  219. var sl = CreateSortedList(d);
  220. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  221. var json = obj.ToJson();
  222. var reps = new Dictionary<object, object> {
  223. { "A", "1"},
  224. { "B", "2"}
  225. };
  226. var htRep = GetDocumentRepresentationInKeyOrder(d, reps);
  227. var sdRep = GetDocumentRepresentationInKeyOrder(sd, reps);
  228. var slRep = GetDocumentRepresentationInKeyOrder(sl, reps);
  229. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
  230. expected = expected.Replace("#D", htRep);
  231. expected = expected.Replace("#SD", sdRep);
  232. expected = expected.Replace("#SL", slRep);
  233. expected = expected.Replace("'", "\"");
  234. Assert.AreEqual(expected, json);
  235. var bson = obj.ToBson();
  236. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  237. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  238. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  239. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  240. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  241. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  242. }
  243. [Test]
  244. public void TestTwoIntsWithIntKeys() {
  245. var d = new Dictionary<object, object> { { 1, 2 }, { 3, 4 } };
  246. var sd = CreateSortedDictionary(d);
  247. var sl = CreateSortedList(d);
  248. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  249. var json = obj.ToJson();
  250. var reps = new Dictionary<object, object> {
  251. { 1, "[1, 2]"},
  252. { 3, "[3, 4]"}
  253. };
  254. var htRep = GetArrayRepresentationInKeyOrder(d, reps);
  255. var sdRep = GetArrayRepresentationInKeyOrder(sd, reps);
  256. var slRep = GetArrayRepresentationInKeyOrder(sl, reps);
  257. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
  258. expected = expected.Replace("#D", htRep);
  259. expected = expected.Replace("#SD", sdRep);
  260. expected = expected.Replace("#SL", slRep);
  261. expected = expected.Replace("'", "\"");
  262. Assert.AreEqual(expected, json);
  263. var bson = obj.ToBson();
  264. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  265. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  266. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  267. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  268. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  269. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  270. }
  271. [Test]
  272. public void TestTwoStrings() {
  273. var d = new Dictionary<object, object> { { "A", "x" }, { "B", "y" } };
  274. var sd = CreateSortedDictionary(d);
  275. var sl = CreateSortedList(d);
  276. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  277. var json = obj.ToJson();
  278. var reps = new Dictionary<object, object> {
  279. { "A", "'x'"},
  280. { "B", "'y'"}
  281. };
  282. var htRep = GetDocumentRepresentationInKeyOrder(d, reps);
  283. var sdRep = GetDocumentRepresentationInKeyOrder(sd, reps);
  284. var slRep = GetDocumentRepresentationInKeyOrder(sl, reps);
  285. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
  286. expected = expected.Replace("#D", htRep);
  287. expected = expected.Replace("#SD", sdRep);
  288. expected = expected.Replace("#SL", slRep);
  289. expected = expected.Replace("'", "\"");
  290. Assert.AreEqual(expected, json);
  291. var bson = obj.ToBson();
  292. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  293. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  294. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  295. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  296. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  297. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  298. }
  299. [Test]
  300. public void TestTwoStringsWithIntKeys() {
  301. var d = new Dictionary<object, object> { { 1, "x" }, { 2, "y" } };
  302. var sd = CreateSortedDictionary(d);
  303. var sl = CreateSortedList(d);
  304. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  305. var json = obj.ToJson();
  306. var reps = new Dictionary<object, object> {
  307. { 1, "[1, 'x']"},
  308. { 2, "[2, 'y']"}
  309. };
  310. var htRep = GetArrayRepresentationInKeyOrder(d, reps);
  311. var sdRep = GetArrayRepresentationInKeyOrder(sd, reps);
  312. var slRep = GetArrayRepresentationInKeyOrder(sl, reps);
  313. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
  314. expected = expected.Replace("#D", htRep);
  315. expected = expected.Replace("#SD", sdRep);
  316. expected = expected.Replace("#SL", slRep);
  317. expected = expected.Replace("'", "\"");
  318. Assert.AreEqual(expected, json);
  319. var bson = obj.ToBson();
  320. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  321. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  322. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  323. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  324. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  325. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  326. }
  327. [Test]
  328. public void TestMixedPrimitiveTypes() {
  329. var dateTime = DateTime.SpecifyKind(new DateTime(2010, 1, 1, 11, 22, 33), DateTimeKind.Utc);
  330. var millis = (long) ((dateTime - BsonConstants.UnixEpoch).TotalMilliseconds);
  331. var guid = Guid.Empty;
  332. var objectId = ObjectId.Empty;
  333. var d = new Dictionary<object, object> {
  334. { "A", true },
  335. { "B", dateTime },
  336. { "C", 1.5 },
  337. { "D", 1 },
  338. { "E", 2L },
  339. { "F", guid },
  340. { "G", objectId },
  341. { "H", "x" }
  342. };
  343. var sd = CreateSortedDictionary(d);
  344. var sl = CreateSortedList(d);
  345. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  346. var json = obj.ToJson();
  347. var reps = new Dictionary<object, object> {
  348. { "A", "true" },
  349. { "B", "{ '$date' : #ms }".Replace("#ms", millis.ToString()) },
  350. { "C", "1.5" },
  351. { "D", "1" },
  352. { "E", "2" },
  353. { "F", "{ '$binary' : 'AAAAAAAAAAAAAAAAAAAAAA==', '$type' : '03' }" },
  354. { "G", "{ '$oid' : '000000000000000000000000' }" },
  355. { "H", "'x'" }
  356. };
  357. var htRep = GetDocumentRepresentationInKeyOrder(d, reps);
  358. var sdRep = GetDocumentRepresentationInKeyOrder(sd, reps);
  359. var slRep = GetDocumentRepresentationInKeyOrder(sl, reps);
  360. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
  361. expected = expected.Replace("#D", htRep);
  362. expected = expected.Replace("#SD", sdRep);
  363. expected = expected.Replace("#SL", slRep);
  364. expected = expected.Replace("'", "\"");
  365. Assert.AreEqual(expected, json);
  366. var bson = obj.ToBson();
  367. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  368. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  369. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  370. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  371. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  372. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  373. }
  374. [Test]
  375. public void TestMixedPrimitiveTypesWithIntKeys() {
  376. var dateTime = DateTime.SpecifyKind(new DateTime(2010, 1, 1, 11, 22, 33), DateTimeKind.Utc);
  377. var millis = (long) ((dateTime - BsonConstants.UnixEpoch).TotalMilliseconds);
  378. var guid = Guid.Empty;
  379. var objectId = ObjectId.Empty;
  380. var d = new Dictionary<object, object> {
  381. { 1, true },
  382. { 2, dateTime },
  383. { 3, 1.5 },
  384. { 4, 1 },
  385. { 5, 2L },
  386. { 6, guid },
  387. { 7, objectId },
  388. { 8, "x" }
  389. };
  390. var sd = CreateSortedDictionary(d);
  391. var sl = CreateSortedList(d);
  392. var obj = new T { D = d, ID = d, SD = sd, SL = sl };
  393. var json = obj.ToJson();
  394. var reps = new Dictionary<object, object> {
  395. { 1, "[1, true]" },
  396. { 2, "[2, { '$date' : #ms }]".Replace("#ms", millis.ToString()) },
  397. { 3, "[3, 1.5]" },
  398. { 4, "[4, 1]" },
  399. { 5, "[5, 2]" },
  400. { 6, "[6, { '$binary' : 'AAAAAAAAAAAAAAAAAAAAAA==', '$type' : '03' }]" },
  401. { 7, "[7, { '$oid' : '000000000000000000000000' }]" },
  402. { 8, "[8, 'x']" }
  403. };
  404. var htRep = GetArrayRepresentationInKeyOrder(d, reps);
  405. var sdRep = GetArrayRepresentationInKeyOrder(sd, reps);
  406. var slRep = GetArrayRepresentationInKeyOrder(sl, reps);
  407. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : #SD, 'SL' : #SL }";
  408. expected = expected.Replace("#D", htRep);
  409. expected = expected.Replace("#SD", sdRep);
  410. expected = expected.Replace("#SL", slRep);
  411. expected = expected.Replace("'", "\"");
  412. Assert.AreEqual(expected, json);
  413. var bson = obj.ToBson();
  414. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  415. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  416. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  417. Assert.IsInstanceOf<SortedDictionary<object, object>>(rehydrated.SD);
  418. Assert.IsInstanceOf<SortedList<object, object>>(rehydrated.SL);
  419. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  420. }
  421. [Test]
  422. public void TestMixedPrimitiveTypesWithMixedKeys() {
  423. // note: no SortedDictionary or SortedList in this test because you can't sort a set of keys that have mixed types
  424. var dateTime = DateTime.SpecifyKind(new DateTime(2010, 1, 1, 11, 22, 33), DateTimeKind.Utc);
  425. var millis = (long) ((dateTime - BsonConstants.UnixEpoch).TotalMilliseconds);
  426. var guid = Guid.Empty;
  427. var objectId = ObjectId.Empty;
  428. var d = new Dictionary<object, object> {
  429. { "A", true },
  430. { "B", dateTime },
  431. { "C", 1.5 },
  432. { "D", 1 },
  433. { 4, 2L },
  434. { 5.0, guid },
  435. { true, objectId },
  436. { false, "x" }
  437. };
  438. var obj = new T { D = d, ID = d, SD = null, SL = null };
  439. var json = obj.ToJson();
  440. var reps = new Dictionary<object, object> {
  441. { "A", "['A', true]" },
  442. { "B", "['B', { '$date' : #ms }]".Replace("#ms", millis.ToString()) },
  443. { "C", "['C', 1.5]" },
  444. { "D", "['D', 1]" },
  445. { 4, "[4, 2]" },
  446. { 5.0, "[5, { '$binary' : 'AAAAAAAAAAAAAAAAAAAAAA==', '$type' : '03' }]" },
  447. { true, "[true, { '$oid' : '000000000000000000000000' }]" },
  448. { false, "[false, 'x']" }
  449. };
  450. var htRep = GetArrayRepresentationInKeyOrder(d, reps);
  451. var expected = "{ 'D' : #D, 'ID' : #D, 'SD' : null, 'SL' : null }";
  452. expected = expected.Replace("#D", htRep);
  453. expected = expected.Replace("'", "\"");
  454. Assert.AreEqual(expected, json);
  455. var bson = obj.ToBson();
  456. var rehydrated = BsonSerializer.Deserialize<T>(bson);
  457. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.D);
  458. Assert.IsInstanceOf<Dictionary<object, object>>(rehydrated.ID);
  459. Assert.IsNull(rehydrated.SD);
  460. Assert.IsNull(rehydrated.SL);
  461. Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
  462. }
  463. private SortedDictionary<object, object> CreateSortedDictionary(
  464. Dictionary<object, object> d
  465. ) {
  466. var sd = new SortedDictionary<object, object>();
  467. foreach (KeyValuePair<object, object> entry in d) {
  468. sd.Add(entry.Key, entry.Value);
  469. }
  470. return sd;
  471. }
  472. private SortedList<object, object> CreateSortedList(
  473. Dictionary<object, object> d
  474. ) {
  475. var sl = new SortedList<object, object>();
  476. foreach (KeyValuePair<object, object> entry in d) {
  477. sl.Add(entry.Key, entry.Value);
  478. }
  479. return sl;
  480. }
  481. private string GetArrayRepresentationInKeyOrder(
  482. IDictionary<object, object> dictionary,
  483. IDictionary<object, object> representations
  484. ) {
  485. var sb = new StringBuilder();
  486. foreach (var key in dictionary.Keys) {
  487. sb.Append((sb.Length == 0) ? "[" : ", ");
  488. sb.Append(representations[key]);
  489. }
  490. sb.Append("]");
  491. return sb.ToString();
  492. }
  493. private string GetDocumentRepresentationInKeyOrder(
  494. IDictionary<object, object> dictionary,
  495. IDictionary<object, object> representations
  496. ) {
  497. var sb = new StringBuilder();
  498. foreach (var key in dictionary.Keys) {
  499. sb.Append((sb.Length == 0) ? "{ " : ", ");
  500. sb.AppendFormat("'{0}' : {1}", key, representations[key]);
  501. }
  502. sb.Append(" }");
  503. return sb.ToString();
  504. }
  505. }
  506. }