CefValueDeserializationTests.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. using Moq;
  2. using NUnit.Framework;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7. using Xilium.CefGlue;
  8. using Xilium.CefGlue.Common.Shared.Serialization;
  9. using static Xilium.CefGlue.Common.Shared.Serialization.CefValueSerialization;
  10. namespace CefGlue.Tests.Serialization
  11. {
  12. [TestFixture]
  13. public class DeserializationTests
  14. {
  15. # region DeserializeCefValue
  16. private void AssertDeserialization<T>(dynamic value, CefValueType valueType, Expression<Func<CefValueWrapper, T>> getValue)
  17. {
  18. var cefValue = new Mock<CefValueWrapper>();
  19. cefValue.Setup(v => v.GetValueType()).Returns(valueType);
  20. if (getValue != null)
  21. {
  22. cefValue.Setup(getValue).Returns(value);
  23. }
  24. Assert.AreEqual(value, CefValueSerialization.DeserializeCefValue(cefValue.Object));
  25. }
  26. private Mock<CefValueWrapper> BootstrapDictionaryWrapperMock(CefValueType valueType)
  27. {
  28. var cefValue = new Mock<CefValueWrapper>();
  29. cefValue.Setup(v => v.GetValueType()).Returns(valueType);
  30. return cefValue;
  31. }
  32. private Mock<ICefDictionaryValue> SimpleDictionaryMock<T>(Dictionary<string, T> baseDictionary, CefValueType valueType, Func<string, Expression<Func<ICefDictionaryValue, T>>> getValue)
  33. {
  34. var cefDictionary = new Mock<ICefDictionaryValue>();
  35. cefDictionary.Setup(v => v.GetKeys()).Returns(baseDictionary.Keys.ToArray());
  36. foreach (string key in baseDictionary.Keys)
  37. {
  38. cefDictionary.Setup(v => v.GetValueType(key)).Returns(valueType);
  39. cefDictionary.Setup(getValue(key)).Returns(baseDictionary[key]);
  40. }
  41. return cefDictionary;
  42. }
  43. private Mock<ICefListValue> SimpleListMock<T>(List<T> baseList, CefValueType valueType, Func<int, Expression<Func<ICefListValue, T>>> getValue)
  44. {
  45. var cefList = new Mock<ICefListValue>();
  46. cefList.Setup(v => v.Count).Returns(baseList.Count);
  47. for (int i = 0; i < baseList.Count; i++)
  48. {
  49. cefList.Setup(v => v.GetValueType(i)).Returns(valueType);
  50. cefList.Setup(getValue(i)).Returns(baseList[i]);
  51. }
  52. return cefList;
  53. }
  54. private IDictionary<string, object> SerializeSimpleDictionary<T>(Dictionary<string, T> baseDictionary, CefValueType valueType, Func<string, Expression<Func<ICefDictionaryValue, T>>> getValue) {
  55. var cefValue = BootstrapDictionaryWrapperMock(CefValueType.Dictionary);
  56. cefValue.Setup(v => v.GetDictionary()).Returns(SimpleDictionaryMock<T>(baseDictionary, valueType, getValue).Object);
  57. return (IDictionary<string, object>)CefValueSerialization.DeserializeCefValue(cefValue.Object);
  58. }
  59. private IList<object> SerializeSimpleList<T>(List<T> baseList, CefValueType valueType, Func<int, Expression<Func<ICefListValue, T>>> getValue)
  60. {
  61. var cefValue = BootstrapDictionaryWrapperMock(CefValueType.List);
  62. cefValue.Setup(v => v.GetList()).Returns(SimpleListMock<T>(baseList, valueType, getValue).Object);
  63. return (IList<object>)CefValueSerialization.DeserializeCefValue(cefValue.Object);
  64. }
  65. [Test]
  66. public void DeserializeCefValue_HandlesIntegers()
  67. {
  68. var returnValue = 5;
  69. AssertDeserialization(returnValue, CefValueType.Int, c => c.GetInt());
  70. }
  71. [Test]
  72. public void DeserializeCefValue_HandlesStrings()
  73. {
  74. var returnValue = "this is a string";
  75. AssertDeserialization(returnValue, CefValueType.String, c => c.GetString());
  76. }
  77. [Test]
  78. public void DeserializeCefValue_HandlesDoubles()
  79. {
  80. var returnValue = 5d;
  81. AssertDeserialization(returnValue, CefValueType.Double, c => c.GetDouble());
  82. }
  83. [Test]
  84. public void DeserializeCefValue_HandlesDoublesWithDecimals()
  85. {
  86. var returnValue = 5.1d;
  87. AssertDeserialization(returnValue, CefValueType.Double, c => c.GetDouble());
  88. }
  89. [Test]
  90. public void DeserializeCefValue_HandlesBooleans()
  91. {
  92. var returnValue = false;
  93. AssertDeserialization(returnValue, CefValueType.Bool, c => c.GetBool());
  94. }
  95. [Test]
  96. public void DeserializeCefValue_HandlesNullStrings()
  97. {
  98. var returnValue = "";
  99. AssertDeserialization(returnValue, CefValueType.String, c => c.GetString());
  100. }
  101. [Test]
  102. public void DeserializeCefValue_HandlesNullObjects()
  103. {
  104. object returnValue = null;
  105. AssertDeserialization<object>(returnValue, CefValueType.Null, null);
  106. }
  107. [Test]
  108. public void DeserializeCefValue_HandlesBinaries()
  109. {
  110. var returnValue = new byte[] { 100, 150, 254 };
  111. var cefValue = new Mock<CefValueWrapper>();
  112. var byteArray = new Mock<ICefBinaryValue>();
  113. byteArray.Setup(c => c.ToArray()).Returns((new byte[] { 1 }.Concat(returnValue)).ToArray());
  114. cefValue.Setup(v => v.GetValueType()).Returns(CefValueType.Binary);
  115. cefValue.Setup(v => v.GetBinary()).Returns(byteArray.Object);
  116. Assert.AreEqual(returnValue, CefValueSerialization.DeserializeCefValue(cefValue.Object));
  117. }
  118. [Test]
  119. public void DeserializeCefValue_HandlesSimpleDictionaries()
  120. {
  121. var returnValue = new Dictionary<string, int>()
  122. {
  123. { "first", 1 },
  124. { "second", 2 },
  125. { "third", 3 }
  126. };
  127. CollectionAssert.AreEqual(returnValue, SerializeSimpleDictionary<int>(returnValue, CefValueType.Int, k => v => v.GetInt(k)));
  128. }
  129. [Test]
  130. public void DeserializeCefValue_HandlesNestedDictionaries()
  131. {
  132. var returnValue = new Dictionary<string, Dictionary<string, double>>()
  133. {
  134. { "first", new Dictionary<string, double>() {
  135. { "first_first", 1d },
  136. { "first_second", 2d },
  137. { "first_third", 3d },
  138. }},
  139. { "second", new Dictionary<string, double>() {
  140. { "second_first", 4d },
  141. { "second_second", 5d },
  142. { "second_third", 6d },
  143. }},
  144. { "third", new Dictionary<string, double>() {
  145. { "third_first", 7d },
  146. { "third_second", 8d },
  147. { "third_third", 9d },
  148. }}
  149. };
  150. var cefValue = BootstrapDictionaryWrapperMock(CefValueType.Dictionary);
  151. var cefOuterDictionary = new Mock<ICefDictionaryValue>();
  152. cefOuterDictionary.Setup(v => v.GetKeys()).Returns(returnValue.Keys.ToArray());
  153. foreach (string key in returnValue.Keys)
  154. {
  155. cefOuterDictionary.Setup(v => v.GetValueType(key)).Returns(CefValueType.Dictionary);
  156. cefOuterDictionary.Setup(v => v.GetDictionary(key))
  157. .Returns(SimpleDictionaryMock<double>(returnValue[key], CefValueType.Double, k => v => v.GetDouble(k)).Object);
  158. }
  159. cefValue.Setup(v => v.GetDictionary()).Returns(cefOuterDictionary.Object);
  160. CollectionAssert.AreEqual(returnValue, (IDictionary<string, object>)CefValueSerialization.DeserializeCefValue(cefValue.Object));
  161. }
  162. [Test]
  163. public void DeserializeCefValue_HandlesNestedComplexDictionaries()
  164. {
  165. var returnValue = new Dictionary<string, Dictionary<string, List<double>>>()
  166. {
  167. { "first", new Dictionary<string, List<double>>() {
  168. { "first_first", new List<double>() { 1d, 2d, 3d } },
  169. { "first_second", new List<double>() { } },
  170. { "first_third", new List<double>() { 4d, 5d, 6d, 7d } },
  171. }},
  172. { "second", new Dictionary<string, List<double>>() {
  173. { "second_first", new List<double>() { 8d, 9d } },
  174. { "second_second", new List<double>() { 10d } },
  175. { "second_third", new List<double>() { } },
  176. }},
  177. { "third", new Dictionary<string, List<double>>() {
  178. { "third_first", new List<double>() { 11.1d, 12.2d, 13.3d } },
  179. { "third_second", new List<double>() { } },
  180. { "third_third", new List<double>() { 14d, 15d, 16d } },
  181. }}
  182. };
  183. var cefValue = BootstrapDictionaryWrapperMock(CefValueType.Dictionary);
  184. var cefOuterDictionary = new Mock<ICefDictionaryValue>();
  185. cefOuterDictionary.Setup(v => v.GetKeys()).Returns(returnValue.Keys.ToArray());
  186. foreach (string key in returnValue.Keys)
  187. {
  188. cefOuterDictionary.Setup(v => v.GetValueType(key)).Returns(CefValueType.Dictionary);
  189. var cefInnerDictionary = new Mock<ICefDictionaryValue>();
  190. cefInnerDictionary.Setup(v => v.GetKeys()).Returns(returnValue[key].Keys.ToArray());
  191. foreach (string innerkey in returnValue[key].Keys)
  192. {
  193. cefInnerDictionary.Setup(v => v.GetValueType(innerkey)).Returns(CefValueType.List);
  194. cefInnerDictionary.Setup(v => v.GetList(innerkey))
  195. .Returns(SimpleListMock<double>(returnValue[key][innerkey], CefValueType.Double, i => v => v.GetDouble(i)).Object);
  196. }
  197. cefOuterDictionary.Setup(v => v.GetDictionary(key)).Returns(cefInnerDictionary.Object);
  198. }
  199. cefValue.Setup(v => v.GetDictionary()).Returns(cefOuterDictionary.Object);
  200. CollectionAssert.AreEqual(returnValue, (IDictionary<string, object>)CefValueSerialization.DeserializeCefValue(cefValue.Object));
  201. }
  202. [Test]
  203. public void DeserializeCefValue_HandlesSimpleLists()
  204. {
  205. var returnValue = new List<int>() { 1, 2, 3 };
  206. CollectionAssert.AreEqual(returnValue, SerializeSimpleList<int>(returnValue, CefValueType.Int, i => v => v.GetInt(i)));
  207. }
  208. [Test]
  209. public void DeserializeCefValue_HandlesNestedLists()
  210. {
  211. var returnValue = new List<List<double>>()
  212. {
  213. new List<double>() { 1d, 2d, 3d },
  214. new List<double>() { 4d, 5d, 6d, 7d },
  215. new List<double>() { 9d },
  216. };
  217. var cefValue = BootstrapDictionaryWrapperMock(CefValueType.List);
  218. var cefOuterList = new Mock<ICefListValue>();
  219. cefOuterList.Setup(v => v.Count).Returns(returnValue.Count);
  220. for (int i = 0; i < returnValue.Count; i++)
  221. {
  222. cefOuterList.Setup(v => v.GetValueType(i)).Returns(CefValueType.List);
  223. cefOuterList.Setup(v => v.GetList(i)).Returns(SimpleListMock<double>(returnValue[i], CefValueType.Double, j => v => v.GetDouble(j)).Object);
  224. }
  225. cefValue.Setup(v => v.GetList()).Returns(cefOuterList.Object);
  226. CollectionAssert.AreEqual(returnValue, (IList<object>)CefValueSerialization.DeserializeCefValue(cefValue.Object));
  227. }
  228. [Test]
  229. public void DeserializeCefValue_HandlesComplexNestedLists()
  230. {
  231. var returnValue = new List<List<Dictionary<string, string>>>()
  232. {
  233. new List<Dictionary<string, string>>() {
  234. new Dictionary<string, string>() {
  235. { "1st", "1st" },
  236. { "2nd", "2nd" },
  237. { "3rd", "3rd" },
  238. },
  239. new Dictionary<string, string>() {
  240. { "4th", "4th" },
  241. },
  242. },
  243. new List<Dictionary<string, string>>() {
  244. new Dictionary<string, string>() { }
  245. },
  246. new List<Dictionary<string, string>>() {
  247. new Dictionary<string, string>() {
  248. { "5th", "5th" },
  249. { "6th", "6th" },
  250. { "7th", "7th" },
  251. { "8th", "8th" },
  252. },
  253. new Dictionary<string, string>() {
  254. { "9th", "9th" },
  255. },
  256. new Dictionary<string, string>() { },
  257. new Dictionary<string, string> {
  258. { "10th", "10th" },
  259. { "11th", "11th" },
  260. },
  261. },
  262. };
  263. var cefValue = BootstrapDictionaryWrapperMock(CefValueType.List);
  264. var cefOuterList = new Mock<ICefListValue>();
  265. cefOuterList.Setup(v => v.Count).Returns(returnValue.Count);
  266. for (int i = 0; i < returnValue.Count; i++)
  267. {
  268. cefOuterList.Setup(v => v.GetValueType(i)).Returns(CefValueType.List);
  269. var cefInnerList = new Mock<ICefListValue>();
  270. cefInnerList.Setup(v => v.Count).Returns(returnValue[i].Count);
  271. for (int j = 0; j < returnValue[i].Count; j++)
  272. {
  273. cefInnerList.Setup(v => v.GetValueType(j)).Returns(CefValueType.Dictionary);
  274. cefInnerList.Setup(v => v.GetDictionary(j))
  275. .Returns(SimpleDictionaryMock<string>(returnValue[i][j], CefValueType.String, k => v => v.GetString(k)).Object);
  276. }
  277. cefOuterList.Setup(v => v.GetList(i)).Returns(cefInnerList.Object);
  278. }
  279. cefValue.Setup(v => v.GetList()).Returns(cefOuterList.Object);
  280. CollectionAssert.AreEqual(returnValue, (IList<object>)CefValueSerialization.DeserializeCefValue(cefValue.Object));
  281. }
  282. #endregion
  283. #region FromCefBinary
  284. [Test]
  285. public void FromCefBinary_HandlesEmptyByteArrays()
  286. {
  287. var returnValue = new byte[0];
  288. var byteArray = new Mock<ICefBinaryValue>();
  289. byteArray.Setup(c => c.ToArray()).Returns(returnValue);
  290. Assert.AreEqual(returnValue, CefValueSerialization.FromCefBinary(byteArray.Object, out var kind));
  291. Assert.AreEqual(BinaryMagicBytes.Binary, kind);
  292. }
  293. [Test]
  294. public void FromCefBinary_HandlesByteArrays()
  295. {
  296. var returnValue = new byte[] { 100, 150, 254 };
  297. var byteArray = new Mock<ICefBinaryValue>();
  298. byteArray.Setup(c => c.ToArray()).Returns((new byte[] { 1 }.Concat(returnValue)).ToArray());
  299. Assert.AreEqual(returnValue, CefValueSerialization.FromCefBinary(byteArray.Object, out var kind));
  300. Assert.AreEqual(BinaryMagicBytes.Binary, kind);
  301. }
  302. [Test]
  303. public void FromCefBinary_ThrowsExceptionOnUnknownByteTypes()
  304. {
  305. var returnValue = new byte[] { 10, 100, 150, 254 };
  306. var byteArray = new Mock<ICefBinaryValue>();
  307. byteArray.Setup(c => c.ToArray()).Returns(returnValue);
  308. Assert.Throws<InvalidOperationException>(() => CefValueSerialization.FromCefBinary(byteArray.Object, out var kind));
  309. }
  310. [Test]
  311. public void FromCefBinary_HandlesDateTimes()
  312. {
  313. var dateTime = DateTime.Now;
  314. var returnValue = BitConverter.GetBytes(dateTime.Ticks);
  315. var byteArray = new Mock<ICefBinaryValue>();
  316. byteArray.Setup(c => c.ToArray()).Returns((new byte[] { 0 }.Concat(returnValue)).ToArray());
  317. Assert.AreEqual(dateTime, CefValueSerialization.FromCefBinary(byteArray.Object, out var kind));
  318. Assert.AreEqual(BinaryMagicBytes.DateTime, kind);
  319. }
  320. #endregion
  321. }
  322. }