PageRenderTime 206ms CodeModel.GetById 6ms RepoModel.GetById 1ms app.codeStats 0ms

/test/System.Json.Test.Unit/JsonValueDynamicTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 468 lines | 397 code | 69 blank | 2 comment | 34 complexity | eced4d98d0f6f20ecffe4a4160196108 MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.Dynamic;
  3. using System.Runtime.Serialization.Json;
  4. using Xunit;
  5. namespace System.Json
  6. {
  7. public class JsonValueDynamicTest
  8. {
  9. const string InvalidIndexType = "Invalid '{0}' index type; only 'System.String' and non-negative 'System.Int32' types are supported.";
  10. const string NonSingleNonNullIndexNotSupported = "Null index or multidimensional indexing is not supported by this indexer; use 'System.Int32' or 'System.String' for array and object indexing respectively.";
  11. [Fact]
  12. public void SettingDifferentValueTypes()
  13. {
  14. dynamic dyn = new JsonObject();
  15. dyn.boolean = AnyInstance.AnyBool;
  16. dyn.int16 = AnyInstance.AnyShort;
  17. dyn.int32 = AnyInstance.AnyInt;
  18. dyn.int64 = AnyInstance.AnyLong;
  19. dyn.uint16 = AnyInstance.AnyUShort;
  20. dyn.uint32 = AnyInstance.AnyUInt;
  21. dyn.uint64 = AnyInstance.AnyULong;
  22. dyn.@char = AnyInstance.AnyChar;
  23. dyn.dbl = AnyInstance.AnyDouble;
  24. dyn.flt = AnyInstance.AnyFloat;
  25. dyn.dec = AnyInstance.AnyDecimal;
  26. dyn.str = AnyInstance.AnyString;
  27. dyn.uri = AnyInstance.AnyUri;
  28. dyn.@byte = AnyInstance.AnyByte;
  29. dyn.@sbyte = AnyInstance.AnySByte;
  30. dyn.guid = AnyInstance.AnyGuid;
  31. dyn.dateTime = AnyInstance.AnyDateTime;
  32. dyn.dateTimeOffset = AnyInstance.AnyDateTimeOffset;
  33. dyn.JsonArray = AnyInstance.AnyJsonArray;
  34. dyn.JsonPrimitive = AnyInstance.AnyJsonPrimitive;
  35. dyn.JsonObject = AnyInstance.AnyJsonObject;
  36. JsonObject jo = (JsonObject)dyn;
  37. Assert.Equal(AnyInstance.AnyBool, (bool)jo["boolean"]);
  38. Assert.Equal(AnyInstance.AnyShort, (short)jo["int16"]);
  39. Assert.Equal(AnyInstance.AnyUShort, (ushort)jo["uint16"]);
  40. Assert.Equal(AnyInstance.AnyInt, (int)jo["int32"]);
  41. Assert.Equal(AnyInstance.AnyUInt, (uint)jo["uint32"]);
  42. Assert.Equal(AnyInstance.AnyLong, (long)jo["int64"]);
  43. Assert.Equal(AnyInstance.AnyULong, (ulong)jo["uint64"]);
  44. Assert.Equal(AnyInstance.AnySByte, (sbyte)jo["sbyte"]);
  45. Assert.Equal(AnyInstance.AnyByte, (byte)jo["byte"]);
  46. Assert.Equal(AnyInstance.AnyChar, (char)jo["char"]);
  47. Assert.Equal(AnyInstance.AnyDouble, (double)jo["dbl"]);
  48. Assert.Equal(AnyInstance.AnyFloat, (float)jo["flt"]);
  49. Assert.Equal(AnyInstance.AnyDecimal, (decimal)jo["dec"]);
  50. Assert.Equal(AnyInstance.AnyString, (string)jo["str"]);
  51. Assert.Equal(AnyInstance.AnyUri, (Uri)jo["uri"]);
  52. Assert.Equal(AnyInstance.AnyGuid, (Guid)jo["guid"]);
  53. Assert.Equal(AnyInstance.AnyDateTime, (DateTime)jo["dateTime"]);
  54. Assert.Equal(AnyInstance.AnyDateTimeOffset, (DateTimeOffset)jo["dateTimeOffset"]);
  55. Assert.Same(AnyInstance.AnyJsonArray, jo["JsonArray"]);
  56. Assert.Equal(AnyInstance.AnyJsonPrimitive, jo["JsonPrimitive"]);
  57. Assert.Same(AnyInstance.AnyJsonObject, jo["JsonObject"]);
  58. Assert.Equal(AnyInstance.AnyBool, (bool)dyn.boolean);
  59. Assert.Equal(AnyInstance.AnyShort, (short)dyn.int16);
  60. Assert.Equal(AnyInstance.AnyUShort, (ushort)dyn.uint16);
  61. Assert.Equal(AnyInstance.AnyInt, (int)dyn.int32);
  62. Assert.Equal(AnyInstance.AnyUInt, (uint)dyn.uint32);
  63. Assert.Equal(AnyInstance.AnyLong, (long)dyn.int64);
  64. Assert.Equal(AnyInstance.AnyULong, (ulong)dyn.uint64);
  65. Assert.Equal(AnyInstance.AnySByte, (sbyte)dyn.@sbyte);
  66. Assert.Equal(AnyInstance.AnyByte, (byte)dyn.@byte);
  67. Assert.Equal(AnyInstance.AnyChar, (char)dyn.@char);
  68. Assert.Equal(AnyInstance.AnyDouble, (double)dyn.dbl);
  69. Assert.Equal(AnyInstance.AnyFloat, (float)dyn.flt);
  70. Assert.Equal(AnyInstance.AnyDecimal, (decimal)dyn.dec);
  71. Assert.Equal(AnyInstance.AnyString, (string)dyn.str);
  72. Assert.Equal(AnyInstance.AnyUri, (Uri)dyn.uri);
  73. Assert.Equal(AnyInstance.AnyGuid, (Guid)dyn.guid);
  74. Assert.Equal(AnyInstance.AnyDateTime, (DateTime)dyn.dateTime);
  75. Assert.Equal(AnyInstance.AnyDateTimeOffset, (DateTimeOffset)dyn.dateTimeOffset);
  76. Assert.Same(AnyInstance.AnyJsonArray, dyn.JsonArray);
  77. Assert.Equal(AnyInstance.AnyJsonPrimitive, dyn.JsonPrimitive);
  78. Assert.Same(AnyInstance.AnyJsonObject, dyn.JsonObject);
  79. ExceptionHelper.Throws<ArgumentException>(delegate { dyn.other = Console.Out; });
  80. ExceptionHelper.Throws<ArgumentException>(delegate { dyn.other = dyn.NonExistentProp; });
  81. }
  82. [Fact]
  83. public void NullTests()
  84. {
  85. dynamic dyn = new JsonObject();
  86. JsonObject jo = (JsonObject)dyn;
  87. dyn.@null = null;
  88. Assert.Same(dyn.@null, AnyInstance.DefaultJsonValue);
  89. jo["@null"] = null;
  90. Assert.Null(jo["@null"]);
  91. }
  92. [Fact]
  93. public void DynamicNotationTest()
  94. {
  95. bool boolValue;
  96. JsonValue jsonValue;
  97. Person person = Person.CreateSample();
  98. dynamic jo = JsonValueExtensions.CreateFrom(person);
  99. dynamic target = jo;
  100. Assert.Equal<int>(person.Age, target.Age.ReadAs<int>()); // JsonPrimitive
  101. Assert.Equal<string>(person.Address.ToString(), ((JsonObject)target.Address).ReadAsType<Address>().ToString()); // JsonObject
  102. target = jo.Address.City; // JsonPrimitive
  103. Assert.NotNull(target);
  104. Assert.Equal<string>(target.ReadAs<string>(), person.Address.City);
  105. target = jo.Friends; // JsonArray
  106. Assert.NotNull(target);
  107. jsonValue = target as JsonValue;
  108. Assert.Equal<int>(person.Friends.Count, jsonValue.ReadAsType<List<Person>>().Count);
  109. target = jo.Friends[1].Address.City;
  110. Assert.NotNull(target);
  111. Assert.Equal<string>(target.ReadAs<string>(), person.Address.City);
  112. target = jo.Address.NonExistentProp.NonExistentProp2; // JsonObject (default)
  113. Assert.NotNull(target);
  114. Assert.True(jo is JsonObject);
  115. Assert.False(target.TryReadAs<bool>(out boolValue));
  116. Assert.True(target.TryReadAs<JsonValue>(out jsonValue));
  117. Assert.Same(target, jsonValue);
  118. Assert.Same(jo.Address.NonExistent, AnyInstance.DefaultJsonValue);
  119. Assert.Same(jo.Friends[1000], AnyInstance.DefaultJsonValue);
  120. Assert.Same(jo.Age.NonExistentProp, AnyInstance.DefaultJsonValue);
  121. Assert.Same(jo.Friends.NonExistentProp, AnyInstance.DefaultJsonValue);
  122. }
  123. [Fact]
  124. public void PropertyAccessTest()
  125. {
  126. Person p = AnyInstance.AnyPerson;
  127. JsonObject jo = JsonValueExtensions.CreateFrom(p) as JsonObject;
  128. JsonArray ja = JsonValueExtensions.CreateFrom(p.Friends) as JsonArray;
  129. JsonPrimitive jp = AnyInstance.AnyJsonPrimitive;
  130. JsonValue jv = AnyInstance.DefaultJsonValue;
  131. dynamic jod = jo;
  132. dynamic jad = ja;
  133. dynamic jpd = jp;
  134. dynamic jvd = jv;
  135. Assert.Equal(jo.Count, jod.Count);
  136. Assert.Equal(jo.JsonType, jod.JsonType);
  137. Assert.Equal(jo.Keys.Count, jod.Keys.Count);
  138. Assert.Equal(jo.Values.Count, jod.Values.Count);
  139. Assert.Equal(p.Age, (int)jod.Age);
  140. Assert.Equal(p.Age, (int)jod["Age"]);
  141. Assert.Equal(p.Age, (int)jo["Age"]);
  142. Assert.Equal(p.Address.City, (string)jo["Address"]["City"]);
  143. Assert.Equal(p.Address.City, (string)jod["Address"]["City"]);
  144. Assert.Equal(p.Address.City, (string)jod.Address.City);
  145. Assert.Equal(p.Friends.Count, ja.Count);
  146. Assert.Equal(ja.Count, jad.Count);
  147. Assert.Equal(ja.IsReadOnly, jad.IsReadOnly);
  148. Assert.Equal(ja.JsonType, jad.JsonType);
  149. Assert.Equal(p.Friends[0].Age, (int)ja[0]["Age"]);
  150. Assert.Equal(p.Friends[0].Age, (int)jad[0].Age);
  151. Assert.Equal(jp.JsonType, jpd.JsonType);
  152. }
  153. [Fact]
  154. public void ConcatDynamicAssignmentTest()
  155. {
  156. string value = "MyValue";
  157. dynamic dynArray = JsonValue.Parse(AnyInstance.AnyJsonArray.ToString());
  158. dynamic dynObj = JsonValue.Parse(AnyInstance.AnyJsonObject.ToString());
  159. JsonValue target;
  160. target = dynArray[0] = dynArray[1] = dynArray[2] = value;
  161. Assert.Equal((string)target, value);
  162. Assert.Equal((string)dynArray[0], value);
  163. Assert.Equal((string)dynArray[1], value);
  164. Assert.Equal((string)dynArray[2], value);
  165. target = dynObj["key0"] = dynObj["key1"] = dynObj["key2"] = value;
  166. Assert.Equal((string)target, value);
  167. Assert.Equal((string)dynObj["key0"], value);
  168. Assert.Equal((string)dynObj["key1"], value);
  169. Assert.Equal((string)dynObj["key2"], value);
  170. foreach (KeyValuePair<string, JsonValue> pair in AnyInstance.AnyJsonObject)
  171. {
  172. Assert.Equal<string>(AnyInstance.AnyJsonObject[pair.Key].ToString(), dynObj[pair.Key].ToString());
  173. }
  174. }
  175. [Fact]
  176. public void IndexConversionTest()
  177. {
  178. dynamic target = AnyInstance.AnyJsonArray;
  179. dynamic expected = AnyInstance.AnyJsonArray[0];
  180. dynamic result;
  181. dynamic[] zero_indexes =
  182. {
  183. (short)0,
  184. (ushort)0,
  185. (byte)0,
  186. (sbyte)0,
  187. (char)0,
  188. (int)0
  189. };
  190. result = target[(short)0];
  191. Assert.Same(expected, result);
  192. result = target[(ushort)0];
  193. Assert.Same(expected, result);
  194. result = target[(byte)0];
  195. Assert.Same(expected, result);
  196. result = target[(sbyte)0];
  197. Assert.Same(expected, result);
  198. result = target[(char)0];
  199. Assert.Same(expected, result);
  200. foreach (dynamic zero_index in zero_indexes)
  201. {
  202. result = target[zero_index];
  203. Assert.Same(expected, result);
  204. }
  205. }
  206. [Fact]
  207. public void InvalidIndexTest()
  208. {
  209. object index1 = new object();
  210. bool index2 = true;
  211. Person index3 = AnyInstance.AnyPerson;
  212. JsonObject jo = AnyInstance.AnyJsonObject;
  213. dynamic target;
  214. object ret;
  215. JsonValue[] values = { AnyInstance.AnyJsonObject, AnyInstance.AnyJsonArray };
  216. foreach (JsonValue value in values)
  217. {
  218. target = value;
  219. ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[index1]; }, String.Format(InvalidIndexType, index1.GetType().FullName));
  220. ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[index2]; }, String.Format(InvalidIndexType, index2.GetType().FullName));
  221. ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[index3]; }, String.Format(InvalidIndexType, index3.GetType().FullName));
  222. ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[null]; }, NonSingleNonNullIndexNotSupported);
  223. ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[0, 1]; }, NonSingleNonNullIndexNotSupported);
  224. ExceptionHelper.Throws<ArgumentException>(delegate { ret = target["key1", "key2"]; }, NonSingleNonNullIndexNotSupported);
  225. ExceptionHelper.Throws<ArgumentException>(delegate { ret = target[true]; }, String.Format(InvalidIndexType, true.GetType().FullName));
  226. ExceptionHelper.Throws<ArgumentException>(delegate { target[index1] = jo; }, String.Format(InvalidIndexType, index1.GetType().FullName));
  227. ExceptionHelper.Throws<ArgumentException>(delegate { target[index2] = jo; }, String.Format(InvalidIndexType, index2.GetType().FullName));
  228. ExceptionHelper.Throws<ArgumentException>(delegate { target[index3] = jo; }, String.Format(InvalidIndexType, index3.GetType().FullName));
  229. ExceptionHelper.Throws<ArgumentException>(delegate { target[null] = jo; }, NonSingleNonNullIndexNotSupported);
  230. ExceptionHelper.Throws<ArgumentException>(delegate { target[0, 1] = jo; }, NonSingleNonNullIndexNotSupported);
  231. ExceptionHelper.Throws<ArgumentException>(delegate { target["key1", "key2"] = jo; }, NonSingleNonNullIndexNotSupported);
  232. ExceptionHelper.Throws<ArgumentException>(delegate { target[true] = jo; }, String.Format(InvalidIndexType, true.GetType().FullName));
  233. }
  234. }
  235. [Fact]
  236. public void InvalidCastingTests()
  237. {
  238. dynamic dyn;
  239. string value = "NameValue";
  240. dyn = AnyInstance.AnyJsonPrimitive;
  241. ExceptionHelper.Throws<InvalidOperationException>(delegate { dyn.name = value; });
  242. dyn = AnyInstance.AnyJsonArray;
  243. ExceptionHelper.Throws<InvalidOperationException>(delegate { dyn.name = value; });
  244. dyn = new JsonObject(AnyInstance.AnyJsonObject);
  245. dyn.name = value;
  246. Assert.Equal((string)dyn.name, value);
  247. dyn = AnyInstance.DefaultJsonValue;
  248. ExceptionHelper.Throws<InvalidOperationException>(delegate { dyn.name = value; });
  249. }
  250. [Fact]
  251. public void CastTests()
  252. {
  253. dynamic dyn = JsonValueExtensions.CreateFrom(AnyInstance.AnyPerson) as JsonObject;
  254. string city = dyn.Address.City;
  255. Assert.Equal<string>(AnyInstance.AnyPerson.Address.City, dyn.Address.City.ReadAs<string>());
  256. Assert.Equal<string>(AnyInstance.AnyPerson.Address.City, city);
  257. JsonValue[] values =
  258. {
  259. AnyInstance.AnyInt,
  260. AnyInstance.AnyString,
  261. AnyInstance.AnyDateTime,
  262. AnyInstance.AnyJsonObject,
  263. AnyInstance.AnyJsonArray,
  264. AnyInstance.DefaultJsonValue
  265. };
  266. int loopCount = 2;
  267. bool explicitCast = true;
  268. while (loopCount > 0)
  269. {
  270. loopCount--;
  271. foreach (JsonValue jv in values)
  272. {
  273. EvaluateNoExceptions<JsonValue>(null, explicitCast);
  274. EvaluateNoExceptions<JsonValue>(jv, explicitCast);
  275. EvaluateNoExceptions<object>(jv, explicitCast);
  276. EvaluateNoExceptions<IDynamicMetaObjectProvider>(jv, explicitCast);
  277. EvaluateNoExceptions<IEnumerable<KeyValuePair<string, JsonValue>>>(jv, explicitCast);
  278. EvaluateNoExceptions<string>(null, explicitCast);
  279. EvaluateExpectExceptions<int>(null, explicitCast);
  280. EvaluateExpectExceptions<Person>(jv, explicitCast);
  281. EvaluateExpectExceptions<Exception>(jv, explicitCast);
  282. EvaluateIgnoreExceptions<JsonObject>(jv, explicitCast);
  283. EvaluateIgnoreExceptions<int>(jv, explicitCast);
  284. EvaluateIgnoreExceptions<string>(jv, explicitCast);
  285. EvaluateIgnoreExceptions<DateTime>(jv, explicitCast);
  286. EvaluateIgnoreExceptions<JsonArray>(jv, explicitCast);
  287. EvaluateIgnoreExceptions<JsonPrimitive>(jv, explicitCast);
  288. }
  289. explicitCast = false;
  290. }
  291. EvaluateNoExceptions<IDictionary<string, JsonValue>>(AnyInstance.AnyJsonObject, false);
  292. EvaluateNoExceptions<IList<JsonValue>>(AnyInstance.AnyJsonArray, false);
  293. }
  294. static void EvaluateNoExceptions<T>(JsonValue value, bool cast)
  295. {
  296. Evaluate<T>(value, cast, false, true);
  297. }
  298. static void EvaluateExpectExceptions<T>(JsonValue value, bool cast)
  299. {
  300. Evaluate<T>(value, cast, true, true);
  301. }
  302. static void EvaluateIgnoreExceptions<T>(JsonValue value, bool cast)
  303. {
  304. Evaluate<T>(value, cast, true, false);
  305. }
  306. static void Evaluate<T>(JsonValue value, bool cast, bool throwExpected, bool assertExceptions)
  307. {
  308. T ret2;
  309. object obj = null;
  310. bool exceptionThrown = false;
  311. string retstr2, retstr1;
  312. Console.WriteLine("Test info: expected:[{0}], explicitCast type:[{1}]", value, typeof(T));
  313. try
  314. {
  315. if (typeof(int) == typeof(T))
  316. {
  317. obj = ((int)value);
  318. }
  319. else if (typeof(string) == typeof(T))
  320. {
  321. obj = ((string)value);
  322. }
  323. else if (typeof(DateTime) == typeof(T))
  324. {
  325. obj = ((DateTime)value);
  326. }
  327. else if (typeof(IList<JsonValue>) == typeof(T))
  328. {
  329. obj = (IList<JsonValue>)value;
  330. }
  331. else if (typeof(IDictionary<string, JsonValue>) == typeof(T))
  332. {
  333. obj = (IDictionary<string, JsonValue>)value;
  334. }
  335. else if (typeof(JsonValue) == typeof(T))
  336. {
  337. obj = (JsonValue)value;
  338. }
  339. else if (typeof(JsonObject) == typeof(T))
  340. {
  341. obj = (JsonObject)value;
  342. }
  343. else if (typeof(JsonArray) == typeof(T))
  344. {
  345. obj = (JsonArray)value;
  346. }
  347. else if (typeof(JsonPrimitive) == typeof(T))
  348. {
  349. obj = (JsonPrimitive)value;
  350. }
  351. else
  352. {
  353. obj = (T)(object)value;
  354. }
  355. retstr1 = obj == null ? "null" : obj.ToString();
  356. }
  357. catch (Exception ex)
  358. {
  359. exceptionThrown = true;
  360. retstr1 = ex.Message;
  361. }
  362. if (assertExceptions)
  363. {
  364. Assert.Equal<bool>(throwExpected, exceptionThrown);
  365. }
  366. exceptionThrown = false;
  367. try
  368. {
  369. dynamic dyn = value as dynamic;
  370. if (cast)
  371. {
  372. ret2 = (T)dyn;
  373. }
  374. else
  375. {
  376. ret2 = dyn;
  377. }
  378. retstr2 = ret2 != null ? ret2.ToString() : "null";
  379. }
  380. catch (Exception ex)
  381. {
  382. exceptionThrown = true;
  383. retstr2 = ex.Message;
  384. }
  385. if (assertExceptions)
  386. {
  387. Assert.Equal<bool>(throwExpected, exceptionThrown);
  388. }
  389. // fixup string
  390. retstr1 = retstr1.Replace("\'Person\'", String.Format("\'{0}\'", typeof(Person).FullName));
  391. if (retstr1.EndsWith(".")) retstr1 = retstr1.Substring(0, retstr1.Length - 1);
  392. // fixup string
  393. retstr2 = retstr2.Replace("\'string\'", String.Format("\'{0}\'", typeof(string).FullName));
  394. retstr2 = retstr2.Replace("\'int\'", String.Format("\'{0}\'", typeof(int).FullName));
  395. if (retstr2.EndsWith(".")) retstr2 = retstr2.Substring(0, retstr2.Length - 1);
  396. Assert.Equal<string>(retstr1, retstr2);
  397. }
  398. }
  399. }