PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/test/System.Json.Test.Unit/Extensions/JsonValueExtensionsTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 476 lines | 397 code | 75 blank | 4 comment | 4 complexity | ad385ea75b183735f4a20a5c19356a6e MD5 | raw file
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Runtime.Serialization;
  5. using System.Runtime.Serialization.Json;
  6. using Xunit;
  7. using Xunit.Extensions;
  8. namespace System.Json
  9. {
  10. public class JsonValueExtensionsTest
  11. {
  12. const string DynamicPropertyNotDefined = "'{0}' does not contain a definition for property '{1}'.";
  13. const string OperationNotSupportedOnJsonTypeMsgFormat = "Operation not supported on JsonValue instance of 'JsonType.{0}' type.";
  14. [Fact]
  15. public void CreateFromTypeTest()
  16. {
  17. JsonValue[] values =
  18. {
  19. AnyInstance.AnyJsonObject,
  20. AnyInstance.AnyJsonArray,
  21. AnyInstance.AnyJsonPrimitive,
  22. AnyInstance.DefaultJsonValue
  23. };
  24. foreach (JsonValue value in values)
  25. {
  26. Assert.Same(value, JsonValueExtensions.CreateFrom(value));
  27. }
  28. }
  29. public static IEnumerable<object[]> PrimitiveTestData
  30. {
  31. get
  32. {
  33. yield return new object[] { AnyInstance.AnyBool };
  34. yield return new object[] { AnyInstance.AnyByte };
  35. yield return new object[] { AnyInstance.AnyChar };
  36. yield return new object[] { AnyInstance.AnyDateTime };
  37. yield return new object[] { AnyInstance.AnyDateTimeOffset };
  38. yield return new object[] { AnyInstance.AnyDecimal };
  39. yield return new object[] { AnyInstance.AnyDouble };
  40. yield return new object[] { AnyInstance.AnyFloat };
  41. yield return new object[] { AnyInstance.AnyGuid };
  42. yield return new object[] { AnyInstance.AnyLong };
  43. yield return new object[] { AnyInstance.AnySByte };
  44. yield return new object[] { AnyInstance.AnyShort };
  45. yield return new object[] { AnyInstance.AnyUInt };
  46. yield return new object[] { AnyInstance.AnyULong };
  47. yield return new object[] { AnyInstance.AnyUri };
  48. yield return new object[] { AnyInstance.AnyUShort };
  49. yield return new object[] { AnyInstance.AnyInt };
  50. yield return new object[] { AnyInstance.AnyString };
  51. }
  52. }
  53. [Theory]
  54. [PropertyData("PrimitiveTestData")]
  55. public void CreateFromPrimitiveTest(object value)
  56. {
  57. Type valueType = value.GetType();
  58. Assert.Equal(value, JsonValueExtensions.CreateFrom(value).ReadAs(valueType));
  59. }
  60. [Fact]
  61. public void CreateFromComplexTest()
  62. {
  63. JsonValue target = JsonValueExtensions.CreateFrom(AnyInstance.AnyPerson);
  64. Assert.Equal(AnyInstance.AnyPerson.Name, (string)target["Name"]);
  65. Assert.Equal(AnyInstance.AnyPerson.Age, (int)target["Age"]);
  66. Assert.Equal(AnyInstance.AnyPerson.Address.City, (string)target.ValueOrDefault("Address", "City"));
  67. }
  68. [Fact]
  69. public void CreateFromDynamicSimpleTest()
  70. {
  71. JsonValue target;
  72. target = JsonValueExtensions.CreateFrom(AnyInstance.AnyDynamic);
  73. Assert.NotNull(target);
  74. string expected = "{\"Name\":\"Bill Gates\",\"Age\":21,\"Grades\":[\"F\",\"B-\",\"C\"]}";
  75. dynamic obj = new TestDynamicObject();
  76. obj.Name = "Bill Gates";
  77. obj.Age = 21;
  78. obj.Grades = new[] { "F", "B-", "C" };
  79. target = JsonValueExtensions.CreateFrom(obj);
  80. Assert.Equal<string>(expected, target.ToString());
  81. target = JsonValueExtensions.CreateFrom(new TestDynamicObject());
  82. Assert.Equal<string>("{}", target.ToString());
  83. }
  84. [Fact]
  85. public void CreateFromDynamicComplextTest()
  86. {
  87. JsonValue target;
  88. Person person = AnyInstance.AnyPerson;
  89. dynamic dyn = TestDynamicObject.CreatePersonAsDynamic(person);
  90. dyn.TestProperty = AnyInstance.AnyString;
  91. target = JsonValueExtensions.CreateFrom(dyn);
  92. Assert.NotNull(target);
  93. Assert.Equal<string>(AnyInstance.AnyString, dyn.TestProperty);
  94. Person jvPerson = target.ReadAsType<Person>();
  95. Assert.Equal(person.ToString(), jvPerson.ToString());
  96. Person p1 = Person.CreateSample();
  97. Person p2 = Person.CreateSample();
  98. p2.Name += "__2";
  99. p2.Age += 10;
  100. p2.Address.City += "__2";
  101. Person[] friends = new Person[] { p1, p2 };
  102. target = JsonValueExtensions.CreateFrom(friends);
  103. Person[] personArr = target.ReadAsType<Person[]>();
  104. Assert.Equal<int>(friends.Length, personArr.Length);
  105. Assert.Equal<string>(friends[0].ToString(), personArr[0].ToString());
  106. Assert.Equal<string>(friends[1].ToString(), personArr[1].ToString());
  107. }
  108. [Fact]
  109. public void CreateFromDynamicBinderFallbackTest()
  110. {
  111. JsonValue target;
  112. Person person = AnyInstance.AnyPerson;
  113. dynamic dyn = new TestDynamicObject();
  114. dyn.Name = AnyInstance.AnyString;
  115. dyn.UseFallbackMethod = true;
  116. string expectedMessage = String.Format(DynamicPropertyNotDefined, dyn.GetType().FullName, "Name");
  117. ExceptionHelper.Throws<InvalidOperationException>(() => target = JsonValueExtensions.CreateFrom(dyn), expectedMessage);
  118. dyn.UseErrorSuggestion = true;
  119. ExceptionHelper.Throws<TestDynamicObject.TestDynamicObjectException>(() => target = JsonValueExtensions.CreateFrom(dyn));
  120. }
  121. [Fact]
  122. public void CreateFromNestedDynamicTest()
  123. {
  124. JsonValue target;
  125. string expected = "{\"Name\":\"Root\",\"Level1\":{\"Name\":\"Level1\",\"Level2\":{\"Name\":\"Level2\"}}}";
  126. dynamic dyn = new TestDynamicObject();
  127. dyn.Name = "Root";
  128. dyn.Level1 = new TestDynamicObject();
  129. dyn.Level1.Name = "Level1";
  130. dyn.Level1.Level2 = new TestDynamicObject();
  131. dyn.Level1.Level2.Name = "Level2";
  132. target = JsonValueExtensions.CreateFrom(dyn);
  133. Assert.NotNull(target);
  134. Assert.Equal<string>(expected, target.ToString());
  135. }
  136. [Fact]
  137. public void CreateFromDynamicWithJsonValueChildrenTest()
  138. {
  139. JsonValue target;
  140. string level3 = "{\"Name\":\"Level3\",\"Null\":null}";
  141. string level2 = "{\"Name\":\"Level2\",\"JsonObject\":" + AnyInstance.AnyJsonObject.ToString() + ",\"JsonArray\":" + AnyInstance.AnyJsonArray.ToString() + ",\"Level3\":" + level3 + "}";
  142. string level1 = "{\"Name\":\"Level1\",\"JsonPrimitive\":" + AnyInstance.AnyJsonPrimitive.ToString() + ",\"Level2\":" + level2 + "}";
  143. string expected = "{\"Name\":\"Root\",\"Level1\":" + level1 + "}";
  144. dynamic dyn = new TestDynamicObject();
  145. dyn.Name = "Root";
  146. dyn.Level1 = new TestDynamicObject();
  147. dyn.Level1.Name = "Level1";
  148. dyn.Level1.JsonPrimitive = AnyInstance.AnyJsonPrimitive;
  149. dyn.Level1.Level2 = new TestDynamicObject();
  150. dyn.Level1.Level2.Name = "Level2";
  151. dyn.Level1.Level2.JsonObject = AnyInstance.AnyJsonObject;
  152. dyn.Level1.Level2.JsonArray = AnyInstance.AnyJsonArray;
  153. dyn.Level1.Level2.Level3 = new TestDynamicObject();
  154. dyn.Level1.Level2.Level3.Name = "Level3";
  155. dyn.Level1.Level2.Level3.Null = null;
  156. target = JsonValueExtensions.CreateFrom(dyn);
  157. Assert.Equal<string>(expected, target.ToString());
  158. }
  159. [Fact]
  160. public void CreateFromDynamicJVTest()
  161. {
  162. JsonValue target;
  163. dynamic[] values = new dynamic[]
  164. {
  165. AnyInstance.AnyJsonArray,
  166. AnyInstance.AnyJsonObject,
  167. AnyInstance.AnyJsonPrimitive,
  168. AnyInstance.DefaultJsonValue
  169. };
  170. foreach (dynamic dyn in values)
  171. {
  172. target = JsonValueExtensions.CreateFrom(dyn);
  173. Assert.Same(dyn, target);
  174. }
  175. }
  176. [Fact]
  177. public void ReadAsTypeFallbackTest()
  178. {
  179. JsonValue jv = AnyInstance.AnyInt;
  180. Person personFallback = Person.CreateSample();
  181. Person personResult = jv.ReadAsType<Person>(personFallback);
  182. Assert.Same(personFallback, personResult);
  183. int intFallback = 45;
  184. int intValue = jv.ReadAsType<int>(intFallback);
  185. Assert.Equal<int>(AnyInstance.AnyInt, intValue);
  186. }
  187. [Fact(Skip = "See bug #228569 in CSDMain")]
  188. public void ReadAsTypeCollectionTest()
  189. {
  190. JsonValue jsonValue;
  191. jsonValue = JsonValue.Parse("[1,2,3]");
  192. List<object> list = jsonValue.ReadAsType<List<object>>();
  193. Array array = jsonValue.ReadAsType<Array>();
  194. object[] objArr = jsonValue.ReadAsType<object[]>();
  195. IList[] collections =
  196. {
  197. list, array, objArr
  198. };
  199. foreach (IList collection in collections)
  200. {
  201. Assert.Equal<int>(jsonValue.Count, collection.Count);
  202. for (int i = 0; i < jsonValue.Count; i++)
  203. {
  204. Assert.Equal<int>((int)jsonValue[i], (int)collection[i]);
  205. }
  206. }
  207. jsonValue = JsonValue.Parse("{\"A\":1,\"B\":2,\"C\":3}");
  208. Dictionary<string, object> dictionary = jsonValue.ReadAsType<Dictionary<string, object>>();
  209. Assert.Equal<int>(jsonValue.Count, dictionary.Count);
  210. foreach (KeyValuePair<string, JsonValue> pair in jsonValue)
  211. {
  212. Assert.Equal((int)jsonValue[pair.Key], (int)dictionary[pair.Key]);
  213. }
  214. }
  215. [Fact]
  216. public void TryReadAsInvalidCollectionTest()
  217. {
  218. JsonValue jo = AnyInstance.AnyJsonObject;
  219. JsonValue ja = AnyInstance.AnyJsonArray;
  220. JsonValue jp = AnyInstance.AnyJsonPrimitive;
  221. JsonValue jd = AnyInstance.DefaultJsonValue;
  222. JsonValue[] invalidArrays =
  223. {
  224. jo, jp, jd
  225. };
  226. JsonValue[] invalidDictionaries =
  227. {
  228. ja, jp, jd
  229. };
  230. bool success;
  231. object[] array;
  232. Dictionary<string, object> dictionary;
  233. foreach (JsonValue value in invalidArrays)
  234. {
  235. success = value.TryReadAsType<object[]>(out array);
  236. Console.WriteLine("Try reading {0} as object[]; success = {1}", value.ToString(), success);
  237. Assert.False(success);
  238. Assert.Null(array);
  239. }
  240. foreach (JsonValue value in invalidDictionaries)
  241. {
  242. success = value.TryReadAsType<Dictionary<string, object>>(out dictionary);
  243. Console.WriteLine("Try reading {0} as Dictionary<string, object>; success = {1}", value.ToString(), success);
  244. Assert.False(success);
  245. Assert.Null(dictionary);
  246. }
  247. }
  248. [Fact]
  249. public void ReadAsExtensionsOnDynamicTest()
  250. {
  251. dynamic jv = JsonValueExtensions.CreateFrom(AnyInstance.AnyPerson);
  252. bool success;
  253. object obj;
  254. success = jv.TryReadAsType(typeof(Person), out obj);
  255. Assert.True(success);
  256. Assert.NotNull(obj);
  257. Assert.Equal<string>(AnyInstance.AnyPerson.ToString(), obj.ToString());
  258. obj = jv.ReadAsType(typeof(Person));
  259. Assert.NotNull(obj);
  260. Assert.Equal<string>(AnyInstance.AnyPerson.ToString(), obj.ToString());
  261. }
  262. #if CODEPLEX
  263. [Fact]
  264. public void ToCollectionTest()
  265. {
  266. JsonValue target;
  267. object[] array;
  268. target = AnyInstance.AnyJsonArray;
  269. array = target.ToObjectArray();
  270. Assert.Equal(target.Count, array.Length);
  271. for (int i = 0; i < target.Count; i++)
  272. {
  273. Assert.Equal(array[i], target[i].ReadAs(array[i].GetType()));
  274. }
  275. target = AnyInstance.AnyJsonObject;
  276. IDictionary<string, object> dictionary = target.ToDictionary();
  277. Assert.Equal(target.Count, dictionary.Count);
  278. foreach (KeyValuePair<string, JsonValue> pair in target)
  279. {
  280. Assert.True(dictionary.ContainsKey(pair.Key));
  281. Assert.Equal<string>(target[pair.Key].ToString(), dictionary[pair.Key].ToString());
  282. }
  283. }
  284. [Fact]
  285. public void ToCollectionsNestedTest()
  286. {
  287. JsonArray ja = JsonValue.Parse("[1, {\"A\":[1,2,3]}, 5]") as JsonArray;
  288. JsonObject jo = JsonValue.Parse("{\"A\":1,\"B\":[1,2,3]}") as JsonObject;
  289. object[] objArray = ja.ToObjectArray();
  290. Assert.NotNull(objArray);
  291. Assert.Equal<int>(ja.Count, objArray.Length);
  292. Assert.Equal((int)ja[0], (int)objArray[0]);
  293. Assert.Equal((int)ja[2], (int)objArray[2]);
  294. IDictionary<string, object> dict = objArray[1] as IDictionary<string, object>;
  295. Assert.NotNull(dict);
  296. objArray = dict["A"] as object[];
  297. Assert.NotNull(objArray);
  298. for (int i = 0; i < 3; i++)
  299. {
  300. Assert.Equal(i + 1, (int)objArray[i]);
  301. }
  302. dict = jo.ToDictionary();
  303. Assert.NotNull(dict);
  304. Assert.Equal<int>(jo.Count, dict.Count);
  305. Assert.Equal<int>(1, (int)dict["A"]);
  306. objArray = dict["B"] as object[];
  307. Assert.NotNull(objArray);
  308. for (int i = 1; i < 3; i++)
  309. {
  310. Assert.Equal(i + 1, (int)objArray[i]);
  311. }
  312. }
  313. [Fact]
  314. public void ToCollectionsInvalidTest()
  315. {
  316. JsonValue jo = AnyInstance.AnyJsonObject;
  317. JsonValue ja = AnyInstance.AnyJsonArray;
  318. JsonValue jp = AnyInstance.AnyJsonPrimitive;
  319. JsonValue jd = AnyInstance.DefaultJsonValue;
  320. ExceptionTestHelper.ExpectException<NotSupportedException>(delegate { var ret = jd.ToObjectArray(); }, String.Format(OperationNotSupportedOnJsonTypeMsgFormat, jd.JsonType));
  321. ExceptionTestHelper.ExpectException<NotSupportedException>(delegate { var ret = jd.ToDictionary(); }, String.Format(OperationNotSupportedOnJsonTypeMsgFormat, jd.JsonType));
  322. ExceptionTestHelper.ExpectException<NotSupportedException>(delegate { var ret = jp.ToObjectArray(); }, String.Format(OperationNotSupportedOnJsonTypeMsgFormat, jp.JsonType));
  323. ExceptionTestHelper.ExpectException<NotSupportedException>(delegate { var ret = jp.ToDictionary(); }, String.Format(OperationNotSupportedOnJsonTypeMsgFormat, jp.JsonType));
  324. ExceptionTestHelper.ExpectException<NotSupportedException>(delegate { var ret = jo.ToObjectArray(); }, String.Format(OperationNotSupportedOnJsonTypeMsgFormat, jo.JsonType));
  325. ExceptionTestHelper.ExpectException<NotSupportedException>(delegate { var ret = ja.ToDictionary(); }, String.Format(OperationNotSupportedOnJsonTypeMsgFormat, ja.JsonType));
  326. }
  327. // 195843 JsonValue to support generic extension methods defined in JsonValueExtensions.
  328. // 195867 Consider creating extension point for allowing new extension methods to be callable via dynamic interface
  329. //[Fact] This requires knowledge of the C# binder to be able to get the generic call parameters.
  330. public void ReadAsGenericExtensionsOnDynamicTest()
  331. {
  332. dynamic jv = JsonValueExtensions.CreateFrom(AnyInstance.AnyPerson);
  333. Person person;
  334. bool success;
  335. person = jv.ReadAsType<Person>();
  336. Assert.NotNull(person);
  337. Assert.Equal<string>(AnyInstance.AnyPerson.ToString(), person.ToString());
  338. success = jv.TryReadAsType<Person>(out person);
  339. Assert.True(success);
  340. Assert.NotNull(person);
  341. Assert.Equal<string>(AnyInstance.AnyPerson.ToString(), person.ToString());
  342. }
  343. #else
  344. [Fact(Skip = "See bug #228569 in CSDMain")]
  345. public void TestDataContractJsonSerializerSettings()
  346. {
  347. TestTypeForSerializerSettings instance = new TestTypeForSerializerSettings
  348. {
  349. BaseRef = new DerivedType(),
  350. Date = AnyInstance.AnyDateTime,
  351. Dict = new Dictionary<string, object>
  352. {
  353. { "one", 1 },
  354. { "two", 2 },
  355. { "two point five", 2.5 },
  356. }
  357. };
  358. JsonObject dict = new JsonObject
  359. {
  360. { "one", 1 },
  361. { "two", 2 },
  362. { "two point five", 2.5 },
  363. };
  364. JsonObject equivalentJsonObject = new JsonObject
  365. {
  366. { "BaseRef", new JsonObject { { "__type", "DerivedType:NS" } } },
  367. { "Date", AnyInstance.AnyDateTime },
  368. { "Dict", dict },
  369. };
  370. JsonObject createdFromType = JsonValueExtensions.CreateFrom(instance) as JsonObject;
  371. Assert.Equal(equivalentJsonObject.ToString(), createdFromType.ToString());
  372. TestTypeForSerializerSettings newInstance = equivalentJsonObject.ReadAsType<TestTypeForSerializerSettings>();
  373. // DISABLED, 198487 - Assert.Equal(instance.Date, newInstance.Date);
  374. Assert.Equal(instance.BaseRef.GetType().FullName, newInstance.BaseRef.GetType().FullName);
  375. Assert.Equal(3, newInstance.Dict.Count);
  376. Assert.Equal(1, newInstance.Dict["one"]);
  377. Assert.Equal(2, newInstance.Dict["two"]);
  378. Assert.Equal(2.5, Convert.ToDouble(newInstance.Dict["two point five"], CultureInfo.InvariantCulture));
  379. }
  380. [DataContract]
  381. public class TestTypeForSerializerSettings
  382. {
  383. [DataMember]
  384. public BaseType BaseRef { get; set; }
  385. [DataMember]
  386. public DateTime Date { get; set; }
  387. [DataMember]
  388. public Dictionary<string, object> Dict { get; set; }
  389. }
  390. [DataContract(Name = "BaseType", Namespace = "NS")]
  391. [KnownType(typeof(DerivedType))]
  392. public class BaseType
  393. {
  394. }
  395. [DataContract(Name = "DerivedType", Namespace = "NS")]
  396. public class DerivedType : BaseType
  397. {
  398. }
  399. #endif
  400. }
  401. }