PageRenderTime 33ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/test/System.Web.Mvc.Test/Test/ViewDataDictionaryTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 536 lines | 375 code | 98 blank | 63 comment | 0 complexity | 94f210946b3ec8cf4b8b4f3db4a97006 MD5 | raw file
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Web.TestUtil;
  5. using Xunit;
  6. using Assert = Microsoft.TestCommon.AssertEx;
  7. namespace System.Web.Mvc.Test
  8. {
  9. public class ViewDataDictionaryTest
  10. {
  11. [Fact]
  12. public void ConstructorThrowsIfDictionaryIsNull()
  13. {
  14. // Act & assert
  15. Assert.ThrowsArgumentNull(
  16. delegate { new ViewDataDictionary((ViewDataDictionary)null); }, "dictionary");
  17. }
  18. [Fact]
  19. public void ConstructorWithViewDataDictionaryCopiesModelAndModelState()
  20. {
  21. // Arrange
  22. ViewDataDictionary originalVdd = new ViewDataDictionary();
  23. object model = new object();
  24. originalVdd.Model = model;
  25. originalVdd["foo"] = "bar";
  26. originalVdd.ModelState.AddModelError("key", "error");
  27. // Act
  28. ViewDataDictionary newVdd = new ViewDataDictionary(originalVdd);
  29. // Assert
  30. Assert.Equal(model, newVdd.Model);
  31. Assert.True(newVdd.ModelState.ContainsKey("key"));
  32. Assert.Equal("error", newVdd.ModelState["key"].Errors[0].ErrorMessage);
  33. Assert.Equal("bar", newVdd["foo"]);
  34. }
  35. [Fact]
  36. public void DictionaryInterface()
  37. {
  38. // Arrange
  39. DictionaryHelper<string, object> helper = new DictionaryHelper<string, object>()
  40. {
  41. Creator = () => new ViewDataDictionary(),
  42. Comparer = StringComparer.OrdinalIgnoreCase,
  43. SampleKeys = new string[] { "foo", "bar", "baz", "quux", "QUUX" },
  44. SampleValues = new object[] { 42, "string value", new DateTime(2001, 1, 1), new object(), 32m },
  45. ThrowOnKeyNotFound = false
  46. };
  47. // Act & assert
  48. helper.Execute();
  49. }
  50. [Fact]
  51. public void EvalReturnsSimplePropertyValue()
  52. {
  53. var obj = new { Foo = "Bar" };
  54. ViewDataDictionary vdd = new ViewDataDictionary(obj);
  55. Assert.Equal("Bar", vdd.Eval("Foo"));
  56. }
  57. [Fact]
  58. public void EvalWithModelAndDictionaryPropertyEvaluatesDictionaryValue()
  59. {
  60. var obj = new { Foo = new Dictionary<string, object> { { "Bar", "Baz" } } };
  61. ViewDataDictionary vdd = new ViewDataDictionary(obj);
  62. Assert.Equal("Baz", vdd.Eval("Foo.Bar"));
  63. }
  64. [Fact]
  65. public void EvalEvaluatesDictionaryThenModel()
  66. {
  67. var obj = new { Foo = "NotBar" };
  68. ViewDataDictionary vdd = new ViewDataDictionary(obj);
  69. vdd.Add("Foo", "Bar");
  70. Assert.Equal("Bar", vdd.Eval("Foo"));
  71. }
  72. [Fact]
  73. public void EvalReturnsValueOfCompoundExpressionByFollowingObjectPath()
  74. {
  75. var obj = new { Foo = new { Bar = "Baz" } };
  76. ViewDataDictionary vdd = new ViewDataDictionary(obj);
  77. Assert.Equal("Baz", vdd.Eval("Foo.Bar"));
  78. }
  79. [Fact]
  80. public void EvalReturnsNullIfExpressionDoesNotMatch()
  81. {
  82. var obj = new { Foo = new { Biz = "Baz" } };
  83. ViewDataDictionary vdd = new ViewDataDictionary(obj);
  84. Assert.Equal(null, vdd.Eval("Foo.Bar"));
  85. }
  86. [Fact]
  87. public void EvalReturnsValueJustAdded()
  88. {
  89. ViewDataDictionary vdd = new ViewDataDictionary();
  90. vdd.Add("Foo", "Blah");
  91. Assert.Equal("Blah", vdd.Eval("Foo"));
  92. }
  93. [Fact]
  94. public void EvalWithCompoundExpressionReturnsIndexedValue()
  95. {
  96. ViewDataDictionary vdd = new ViewDataDictionary();
  97. vdd.Add("Foo.Bar", "Baz");
  98. Assert.Equal("Baz", vdd.Eval("Foo.Bar"));
  99. }
  100. [Fact]
  101. public void EvalWithCompoundExpressionReturnsPropertyOfAddedObject()
  102. {
  103. ViewDataDictionary vdd = new ViewDataDictionary();
  104. vdd.Add("Foo", new { Bar = "Baz" });
  105. Assert.Equal("Baz", vdd.Eval("Foo.Bar"));
  106. }
  107. [Fact]
  108. public void EvalWithCompoundIndexExpressionReturnsEval()
  109. {
  110. ViewDataDictionary vdd = new ViewDataDictionary();
  111. vdd.Add("Foo.Bar", new { Baz = "Quux" });
  112. Assert.Equal("Quux", vdd.Eval("Foo.Bar.Baz"));
  113. }
  114. [Fact]
  115. public void EvalWithCompoundIndexAndCompoundExpressionReturnsValue()
  116. {
  117. ViewDataDictionary vdd = new ViewDataDictionary();
  118. vdd.Add("Foo.Bar", new { Baz = new { Blah = "Quux" } });
  119. Assert.Equal("Quux", vdd.Eval("Foo.Bar.Baz.Blah"));
  120. }
  121. /// <summary>
  122. /// Make sure that dict["foo.bar"] gets chosen before dict["foo"]["bar"]
  123. /// </summary>
  124. [Fact]
  125. public void EvalChoosesValueInDictionaryOverOtherValue()
  126. {
  127. ViewDataDictionary vdd = new ViewDataDictionary();
  128. vdd.Add("Foo", new { Bar = "Not Baz" });
  129. vdd.Add("Foo.Bar", "Baz");
  130. Assert.Equal("Baz", vdd.Eval("Foo.Bar"));
  131. }
  132. /// <summary>
  133. /// Make sure that dict["foo.bar"]["baz"] gets chosen before dict["foo"]["bar"]["baz"]
  134. /// </summary>
  135. [Fact]
  136. public void EvalChoosesCompoundValueInDictionaryOverOtherValues()
  137. {
  138. ViewDataDictionary vdd = new ViewDataDictionary();
  139. vdd.Add("Foo", new { Bar = new { Baz = "Not Quux" } });
  140. vdd.Add("Foo.Bar", new { Baz = "Quux" });
  141. Assert.Equal("Quux", vdd.Eval("Foo.Bar.Baz"));
  142. }
  143. /// <summary>
  144. /// Make sure that dict["foo.bar"]["baz"] gets chosen before dict["foo"]["bar.baz"]
  145. /// </summary>
  146. [Fact]
  147. public void EvalChoosesCompoundValueInDictionaryOverOtherValuesWithCompoundProperty()
  148. {
  149. ViewDataDictionary vdd = new ViewDataDictionary();
  150. vdd.Add("Foo", new Person());
  151. vdd.Add("Foo.Bar", new { Baz = "Quux" });
  152. Assert.Equal("Quux", vdd.Eval("Foo.Bar.Baz"));
  153. }
  154. [Fact]
  155. public void EvalThrowsIfExpressionIsEmpty()
  156. {
  157. // Arrange
  158. ViewDataDictionary vdd = new ViewDataDictionary();
  159. // Act & Assert
  160. Assert.ThrowsArgumentNullOrEmpty(
  161. delegate { vdd.Eval(String.Empty); }, "expression");
  162. }
  163. [Fact]
  164. public void EvalThrowsIfExpressionIsNull()
  165. {
  166. // Arrange
  167. ViewDataDictionary vdd = new ViewDataDictionary();
  168. // Act & Assert
  169. Assert.ThrowsArgumentNullOrEmpty(
  170. delegate { vdd.Eval(null); }, "expression");
  171. }
  172. [Fact]
  173. public void EvalWithCompoundExpressionAndDictionarySubExpressionChoosesDictionaryValue()
  174. {
  175. ViewDataDictionary vdd = new ViewDataDictionary();
  176. vdd.Add("Foo", new Dictionary<string, object> { { "Bar", "Baz" } });
  177. Assert.Equal("Baz", vdd.Eval("Foo.Bar"));
  178. }
  179. [Fact]
  180. public void EvalWithDictionaryAndNoMatchReturnsNull()
  181. {
  182. ViewDataDictionary vdd = new ViewDataDictionary();
  183. vdd.Add("Foo", new Dictionary<string, object> { { "NotBar", "Baz" } });
  184. object result = vdd.Eval("Foo.Bar");
  185. Assert.Null(result);
  186. }
  187. [Fact]
  188. public void EvalWithNestedDictionariesEvalCorrectly()
  189. {
  190. ViewDataDictionary vdd = new ViewDataDictionary();
  191. vdd.Add("Foo", new Dictionary<string, object> { { "Bar", new Hashtable { { "Baz", "Quux" } } } });
  192. Assert.Equal("Quux", vdd.Eval("Foo.Bar.Baz"));
  193. }
  194. [Fact]
  195. public void EvalFormatWithNullValueReturnsEmptyString()
  196. {
  197. // Arrange
  198. ViewDataDictionary vdd = new ViewDataDictionary();
  199. // Act
  200. string formattedValue = vdd.Eval("foo", "for{0}mat");
  201. // Assert
  202. Assert.Equal(String.Empty, formattedValue);
  203. }
  204. [Fact]
  205. public void EvalFormatWithEmptyFormatReturnsViewData()
  206. {
  207. // Arrange
  208. ViewDataDictionary vdd = new ViewDataDictionary();
  209. vdd["foo"] = "value";
  210. // Act
  211. string formattedValue = vdd.Eval("foo", "");
  212. // Assert
  213. Assert.Equal("value", formattedValue);
  214. }
  215. [Fact]
  216. public void EvalFormatWithFormatReturnsFormattedViewData()
  217. {
  218. // Arrange
  219. ViewDataDictionary vdd = new ViewDataDictionary();
  220. vdd["foo"] = "value";
  221. // Act
  222. string formattedValue = vdd.Eval("foo", "for{0}mat");
  223. // Assert
  224. Assert.Equal("forvaluemat", formattedValue);
  225. }
  226. [Fact]
  227. public void EvalPropertyNamedModel()
  228. {
  229. // Arrange
  230. ViewDataDictionary vdd = new ViewDataDictionary();
  231. vdd["Title"] = "Home Page";
  232. vdd["Message"] = "Welcome to ASP.NET MVC!";
  233. vdd.Model = new TheQueryStringParam
  234. {
  235. Name = "The Name",
  236. Value = "The Value",
  237. Model = "The Model",
  238. };
  239. // Act
  240. object o = vdd.Eval("Model");
  241. // Assert
  242. Assert.Equal("The Model", o);
  243. }
  244. [Fact]
  245. public void EvalSubPropertyNamedValueInModel()
  246. {
  247. // Arrange
  248. ViewDataDictionary vdd = new ViewDataDictionary();
  249. vdd["Title"] = "Home Page";
  250. vdd["Message"] = "Welcome to ASP.NET MVC!";
  251. vdd.Model = new TheQueryStringParam
  252. {
  253. Name = "The Name",
  254. Value = "The Value",
  255. Model = "The Model",
  256. };
  257. // Act
  258. object o = vdd.Eval("Value");
  259. // Assert
  260. Assert.Equal("The Value", o);
  261. }
  262. [Fact]
  263. public void GetViewDataInfoFromDictionary()
  264. {
  265. // Arrange
  266. ViewDataDictionary fooVdd = new ViewDataDictionary()
  267. {
  268. { "Bar", "barValue" }
  269. };
  270. ViewDataDictionary vdd = new ViewDataDictionary()
  271. {
  272. { "Foo", fooVdd }
  273. };
  274. // Act
  275. ViewDataInfo info = vdd.GetViewDataInfo("foo.bar");
  276. // Assert
  277. Assert.NotNull(info);
  278. Assert.Equal(fooVdd, info.Container);
  279. Assert.Equal("barValue", info.Value);
  280. }
  281. [Fact]
  282. public void GetViewDataInfoFromDictionaryWithMissingEntry()
  283. {
  284. // Arrange
  285. ViewDataDictionary vdd = new ViewDataDictionary();
  286. // Act
  287. ViewDataInfo info = vdd.GetViewDataInfo("foo");
  288. // Assert
  289. Assert.Null(info);
  290. }
  291. [Fact]
  292. public void GetViewDataInfoFromDictionaryWithNullEntry()
  293. {
  294. // Arrange
  295. ViewDataDictionary vdd = new ViewDataDictionary()
  296. {
  297. { "Foo", null }
  298. };
  299. // Act
  300. ViewDataInfo info = vdd.GetViewDataInfo("foo");
  301. // Assert
  302. Assert.NotNull(info);
  303. Assert.Equal(vdd, info.Container);
  304. Assert.Null(info.Value);
  305. }
  306. [Fact]
  307. public void GetViewDataInfoFromModel()
  308. {
  309. // Arrange
  310. object model = new { foo = "fooValue" };
  311. ViewDataDictionary vdd = new ViewDataDictionary(model);
  312. PropertyDescriptor propDesc = TypeDescriptor.GetProperties(model).Find("foo", true /* ignoreCase */);
  313. // Act
  314. ViewDataInfo info = vdd.GetViewDataInfo("foo");
  315. // Assert
  316. Assert.NotNull(info);
  317. Assert.Equal(model, info.Container);
  318. Assert.Equal(propDesc, info.PropertyDescriptor);
  319. Assert.Equal("fooValue", info.Value);
  320. }
  321. [Fact]
  322. public void FabricatesModelMetadataFromModelWhenModelMetadataHasNotBeenSet()
  323. {
  324. // Arrange
  325. object model = new { foo = "fooValue", bar = "barValue" };
  326. ViewDataDictionary vdd = new ViewDataDictionary(model);
  327. // Act
  328. ModelMetadata metadata = vdd.ModelMetadata;
  329. // Assert
  330. Assert.NotNull(metadata);
  331. Assert.Equal(model.GetType(), metadata.ModelType);
  332. }
  333. [Fact]
  334. public void ReturnsExistingModelMetadata()
  335. {
  336. // Arrange
  337. object model = new { foo = "fooValue", bar = "barValue" };
  338. ModelMetadata originalMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
  339. ViewDataDictionary vdd = new ViewDataDictionary(model) { ModelMetadata = originalMetadata };
  340. // Act
  341. ModelMetadata metadata = vdd.ModelMetadata;
  342. // Assert
  343. Assert.Same(originalMetadata, metadata);
  344. }
  345. [Fact]
  346. public void ModelMetadataIsNullIfModelMetadataHasNotBeenSetAndModelIsNull()
  347. {
  348. // Arrange
  349. ViewDataDictionary vdd = new ViewDataDictionary();
  350. // Act
  351. ModelMetadata metadata = vdd.ModelMetadata;
  352. // Assert
  353. Assert.Null(metadata);
  354. }
  355. [Fact]
  356. public void ModelMetadataCanBeFabricatedWithNullModelAndGenericViewDataDictionary()
  357. {
  358. // Arrange
  359. ViewDataDictionary vdd = new ViewDataDictionary<Exception>();
  360. // Act
  361. ModelMetadata metadata = vdd.ModelMetadata;
  362. // Assert
  363. Assert.NotNull(metadata);
  364. Assert.Equal(typeof(Exception), metadata.ModelType);
  365. }
  366. [Fact]
  367. public void ModelSetterThrowsIfValueIsNullAndModelTypeIsNonNullable()
  368. {
  369. // Arrange
  370. ViewDataDictionary vdd = new ViewDataDictionary<int>();
  371. // Act & assert
  372. Assert.Throws<InvalidOperationException>(
  373. delegate { vdd.Model = null; },
  374. @"The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'System.Int32'.");
  375. }
  376. [Fact]
  377. public void ChangingModelReplacesModelMetadata()
  378. {
  379. // Arrange
  380. ViewDataDictionary vdd = new ViewDataDictionary(new Object());
  381. ModelMetadata originalMetadata = vdd.ModelMetadata;
  382. // Act
  383. vdd.Model = "New Model";
  384. // Assert
  385. Assert.NotSame(originalMetadata, vdd.ModelMetadata);
  386. }
  387. public class TheQueryStringParam
  388. {
  389. public string Name { get; set; }
  390. public string Value { get; set; }
  391. public string Model { get; set; }
  392. }
  393. public class Person : CustomTypeDescriptor
  394. {
  395. public override PropertyDescriptorCollection GetProperties()
  396. {
  397. return new PropertyDescriptorCollection(new PersonPropertyDescriptor[] { new PersonPropertyDescriptor() });
  398. }
  399. }
  400. public class PersonPropertyDescriptor : PropertyDescriptor
  401. {
  402. public PersonPropertyDescriptor()
  403. : base("Bar.Baz", null)
  404. {
  405. }
  406. public override object GetValue(object component)
  407. {
  408. return "Quux";
  409. }
  410. public override bool CanResetValue(object component)
  411. {
  412. return false;
  413. }
  414. public override Type ComponentType
  415. {
  416. get { return typeof(Person); }
  417. }
  418. public override bool IsReadOnly
  419. {
  420. get { return false; }
  421. }
  422. public override Type PropertyType
  423. {
  424. get { return typeof(string); }
  425. }
  426. public override void ResetValue(object component)
  427. {
  428. }
  429. public override void SetValue(object component, object value)
  430. {
  431. }
  432. public override bool ShouldSerializeValue(object component)
  433. {
  434. return true;
  435. }
  436. }
  437. }
  438. }