PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/mdavid/aspnetwebstack
C# | 892 lines | 623 code | 142 blank | 127 comment | 0 complexity | 7ff1127278047cfeb472a58de8b76088 MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.ComponentModel.DataAnnotations;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using Moq;
  6. using Xunit;
  7. using Assert = Microsoft.TestCommon.AssertEx;
  8. namespace System.Web.Mvc.Test
  9. {
  10. public class ModelMetadataTest
  11. {
  12. // Guard clauses
  13. [Fact]
  14. public void NullProviderThrows()
  15. {
  16. // Act & Assert
  17. Assert.ThrowsArgumentNull(
  18. () => new ModelMetadata(null /* provider */, null /* containerType */, null /* model */, typeof(object), null /* propertyName */),
  19. "provider");
  20. }
  21. [Fact]
  22. public void NullTypeThrows()
  23. {
  24. // Arrange
  25. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  26. // Act & Assert
  27. Assert.ThrowsArgumentNull(
  28. () => new ModelMetadata(provider.Object, null /* containerType */, null /* model */, null /* modelType */, null /* propertyName */),
  29. "modelType");
  30. }
  31. // Constructor
  32. [Fact]
  33. public void DefaultValues()
  34. {
  35. // Arrange
  36. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  37. // Act
  38. ModelMetadata metadata = new ModelMetadata(provider.Object, typeof(Exception), () => "model", typeof(string), "propertyName");
  39. // Assert
  40. Assert.Equal(typeof(Exception), metadata.ContainerType);
  41. Assert.True(metadata.ConvertEmptyStringToNull);
  42. Assert.Null(metadata.DataTypeName);
  43. Assert.Null(metadata.Description);
  44. Assert.Null(metadata.DisplayFormatString);
  45. Assert.Null(metadata.DisplayName);
  46. Assert.Null(metadata.EditFormatString);
  47. Assert.False(metadata.HideSurroundingHtml);
  48. Assert.Equal("model", metadata.Model);
  49. Assert.Equal(typeof(string), metadata.ModelType);
  50. Assert.Null(metadata.NullDisplayText);
  51. Assert.Equal(10000, metadata.Order);
  52. Assert.Equal("propertyName", metadata.PropertyName);
  53. Assert.False(metadata.IsReadOnly);
  54. Assert.True(metadata.RequestValidationEnabled);
  55. Assert.Null(metadata.ShortDisplayName);
  56. Assert.True(metadata.ShowForDisplay);
  57. Assert.True(metadata.ShowForEdit);
  58. Assert.Null(metadata.TemplateHint);
  59. Assert.Null(metadata.Watermark);
  60. }
  61. // IsComplexType
  62. struct IsComplexTypeModel
  63. {
  64. }
  65. [Fact]
  66. public void IsComplexTypeTests()
  67. {
  68. // Arrange
  69. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  70. // Act & Assert
  71. Assert.True(new ModelMetadata(provider.Object, null, null, typeof(Object), null).IsComplexType);
  72. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(string), null).IsComplexType);
  73. Assert.True(new ModelMetadata(provider.Object, null, null, typeof(IDisposable), null).IsComplexType);
  74. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(Nullable<int>), null).IsComplexType);
  75. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(int), null).IsComplexType);
  76. Assert.True(new ModelMetadata(provider.Object, null, null, typeof(IsComplexTypeModel), null).IsComplexType);
  77. Assert.True(new ModelMetadata(provider.Object, null, null, typeof(Nullable<IsComplexTypeModel>), null).IsComplexType);
  78. }
  79. // IsNullableValueType
  80. [Fact]
  81. public void IsNullableValueTypeTests()
  82. {
  83. // Arrange
  84. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  85. // Act & Assert
  86. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(string), null).IsNullableValueType);
  87. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(IDisposable), null).IsNullableValueType);
  88. Assert.True(new ModelMetadata(provider.Object, null, null, typeof(Nullable<int>), null).IsNullableValueType);
  89. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(int), null).IsNullableValueType);
  90. }
  91. // IsRequired
  92. [Fact]
  93. public void IsRequiredTests()
  94. {
  95. // Arrange
  96. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  97. // Act & Assert
  98. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(string), null).IsRequired); // Reference type not required
  99. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(IDisposable), null).IsRequired); // Interface not required
  100. Assert.False(new ModelMetadata(provider.Object, null, null, typeof(Nullable<int>), null).IsRequired); // Nullable value type not required
  101. Assert.True(new ModelMetadata(provider.Object, null, null, typeof(int), null).IsRequired); // Value type required
  102. Assert.True(new ModelMetadata(provider.Object, null, null, typeof(DayOfWeek), null).IsRequired); // Enum (implicit value type) is required
  103. }
  104. // Properties
  105. [Fact]
  106. public void PropertiesCallsProvider()
  107. {
  108. // Arrange
  109. Type modelType = typeof(string);
  110. List<ModelMetadata> propertyMetadata = new List<ModelMetadata>();
  111. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  112. ModelMetadata metadata = new ModelMetadata(provider.Object, null, null, modelType, null);
  113. provider.Setup(p => p.GetMetadataForProperties(null, modelType))
  114. .Returns(propertyMetadata)
  115. .Verifiable();
  116. // Act
  117. IEnumerable<ModelMetadata> result = metadata.Properties;
  118. // Assert
  119. Assert.Equal(propertyMetadata, result.ToList());
  120. provider.Verify();
  121. }
  122. [Fact]
  123. public void PropertiesUsesRealModelTypeRatherThanPassedModelType()
  124. {
  125. // Arrange
  126. string model = "String Value";
  127. Expression<Func<object, object>> accessor = _ => model;
  128. ModelMetadata metadata = ModelMetadata.FromLambdaExpression(accessor, new ViewDataDictionary<object>());
  129. // Act
  130. IEnumerable<ModelMetadata> result = metadata.Properties;
  131. // Assert
  132. Assert.Equal("Length", result.Single().PropertyName);
  133. }
  134. [Fact]
  135. public void PropertiesAreSortedByOrder()
  136. {
  137. // Arrange
  138. Type modelType = typeof(string);
  139. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  140. List<ModelMetadata> propertyMetadata = new List<ModelMetadata>
  141. {
  142. new ModelMetadata(provider.Object, null, () => 1, typeof(int), null) { Order = 20 },
  143. new ModelMetadata(provider.Object, null, () => 2, typeof(int), null) { Order = 30 },
  144. new ModelMetadata(provider.Object, null, () => 3, typeof(int), null) { Order = 10 },
  145. };
  146. ModelMetadata metadata = new ModelMetadata(provider.Object, null, null, modelType, null);
  147. provider.Setup(p => p.GetMetadataForProperties(null, modelType))
  148. .Returns(propertyMetadata)
  149. .Verifiable();
  150. // Act
  151. List<ModelMetadata> result = metadata.Properties.ToList();
  152. // Assert
  153. Assert.Equal(3, result.Count);
  154. Assert.Equal(3, result[0].Model);
  155. Assert.Equal(1, result[1].Model);
  156. Assert.Equal(2, result[2].Model);
  157. }
  158. [Fact]
  159. public void PropertiesListGetsResetWhenModelGetsReset()
  160. { // Dev10 Bug #923263
  161. // Arrange
  162. var provider = new DataAnnotationsModelMetadataProvider();
  163. var metadata = new ModelMetadata(provider, null, () => new Class1(), typeof(Class1), null);
  164. // Act
  165. ModelMetadata[] originalProps = metadata.Properties.ToArray();
  166. metadata.Model = new Class2();
  167. ModelMetadata[] newProps = metadata.Properties.ToArray();
  168. // Assert
  169. ModelMetadata originalProp = Assert.Single(originalProps);
  170. Assert.Equal(typeof(string), originalProp.ModelType);
  171. Assert.Equal("Prop1", originalProp.PropertyName);
  172. ModelMetadata newProp = Assert.Single(newProps);
  173. Assert.Equal(typeof(int), newProp.ModelType);
  174. Assert.Equal("Prop2", newProp.PropertyName);
  175. }
  176. class Class1
  177. {
  178. public string Prop1 { get; set; }
  179. }
  180. class Class2
  181. {
  182. public int Prop2 { get; set; }
  183. }
  184. // SimpleDisplayText
  185. [Fact]
  186. public void SimpleDisplayTextReturnsNullDisplayTextForNullModel()
  187. {
  188. // Arrange
  189. string nullText = "(null)";
  190. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  191. ModelMetadata metadata = new ModelMetadata(provider.Object, null, null, typeof(object), null) { NullDisplayText = nullText };
  192. // Act
  193. string result = metadata.SimpleDisplayText;
  194. // Assert
  195. Assert.Equal(nullText, result);
  196. }
  197. private class SimpleDisplayTextModelWithToString
  198. {
  199. public override string ToString()
  200. {
  201. return "Custom ToString Value";
  202. }
  203. }
  204. [Fact]
  205. public void SimpleDisplayTextReturnsToStringValueWhenOverridden()
  206. {
  207. // Arrange
  208. SimpleDisplayTextModelWithToString model = new SimpleDisplayTextModelWithToString();
  209. EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider();
  210. ModelMetadata metadata = new ModelMetadata(provider, null, () => model, typeof(SimpleDisplayTextModelWithToString), null);
  211. // Act
  212. string result = metadata.SimpleDisplayText;
  213. // Assert
  214. Assert.Equal(model.ToString(), result);
  215. }
  216. private class SimpleDisplayTextModelWithoutToString
  217. {
  218. public string FirstProperty { get; set; }
  219. public int SecondProperty { get; set; }
  220. }
  221. [Fact]
  222. public void SimpleDisplayTextReturnsFirstPropertyValueForNonNullModel()
  223. {
  224. // Arrange
  225. SimpleDisplayTextModelWithoutToString model = new SimpleDisplayTextModelWithoutToString
  226. {
  227. FirstProperty = "First Property Value"
  228. };
  229. EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider();
  230. ModelMetadata metadata = new ModelMetadata(provider, null, () => model, typeof(SimpleDisplayTextModelWithoutToString), null);
  231. // Act
  232. string result = metadata.SimpleDisplayText;
  233. // Assert
  234. Assert.Equal(model.FirstProperty, result);
  235. }
  236. [Fact]
  237. public void SimpleDisplayTextReturnsFirstPropertyNullDisplayTextForNonNullModelWithNullDisplayColumnPropertyValue()
  238. {
  239. // Arrange
  240. SimpleDisplayTextModelWithoutToString model = new SimpleDisplayTextModelWithoutToString();
  241. EmptyModelMetadataProvider propertyProvider = new EmptyModelMetadataProvider();
  242. ModelMetadata propertyMetadata = propertyProvider.GetMetadataForProperty(() => model.FirstProperty, typeof(SimpleDisplayTextModelWithoutToString), "FirstProperty");
  243. propertyMetadata.NullDisplayText = "Null Display Text";
  244. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  245. provider.Setup(p => p.GetMetadataForProperties(model, typeof(SimpleDisplayTextModelWithoutToString)))
  246. .Returns(new[] { propertyMetadata });
  247. ModelMetadata metadata = new ModelMetadata(provider.Object, null, () => model, typeof(SimpleDisplayTextModelWithoutToString), null);
  248. // Act
  249. string result = metadata.SimpleDisplayText;
  250. // Assert
  251. Assert.Equal(propertyMetadata.NullDisplayText, result);
  252. }
  253. private class SimpleDisplayTextModelWithNoProperties
  254. {
  255. }
  256. [Fact]
  257. public void SimpleDisplayTextReturnsEmptyStringForNonNullModelWithNoVisibleProperties()
  258. {
  259. // Arrange
  260. SimpleDisplayTextModelWithNoProperties model = new SimpleDisplayTextModelWithNoProperties();
  261. EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider();
  262. ModelMetadata metadata = new ModelMetadata(provider, null, () => model, typeof(SimpleDisplayTextModelWithNoProperties), null);
  263. // Act
  264. string result = metadata.SimpleDisplayText;
  265. // Assert
  266. Assert.Equal(String.Empty, result);
  267. }
  268. private class ObjectWithToStringOverride
  269. {
  270. private string _toStringValue;
  271. public ObjectWithToStringOverride(string toStringValue)
  272. {
  273. _toStringValue = toStringValue;
  274. }
  275. public override string ToString()
  276. {
  277. return _toStringValue;
  278. }
  279. }
  280. [Fact]
  281. public void SimpleDisplayTextReturnsToStringOfModelForNonNullModel()
  282. {
  283. // Arrange
  284. string toStringText = "text from ToString()";
  285. ObjectWithToStringOverride model = new ObjectWithToStringOverride(toStringText);
  286. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  287. ModelMetadata metadata = new ModelMetadata(provider.Object, null, () => model, typeof(ObjectWithToStringOverride), null);
  288. // Act
  289. string result = metadata.SimpleDisplayText;
  290. // Assert
  291. Assert.Equal(toStringText, result);
  292. }
  293. [Fact]
  294. public void SimpleDisplayTextReturnsEmptyStringForNonNullModelWithToStringNull()
  295. {
  296. // Arrange
  297. string toStringText = null;
  298. ObjectWithToStringOverride model = new ObjectWithToStringOverride(toStringText);
  299. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  300. ModelMetadata metadata = new ModelMetadata(provider.Object, null, () => model, typeof(ObjectWithToStringOverride), null);
  301. // Act
  302. string result = metadata.SimpleDisplayText;
  303. // Assert
  304. Assert.Equal(String.Empty, result);
  305. }
  306. // FromStringExpression()
  307. [Fact]
  308. public void FromStringExpressionGuardClauses()
  309. {
  310. // Null expression throws
  311. Assert.ThrowsArgumentNull(
  312. () => ModelMetadata.FromStringExpression(null, new ViewDataDictionary()),
  313. "expression");
  314. // Null view data dictionary throws
  315. Assert.ThrowsArgumentNull(
  316. () => ModelMetadata.FromStringExpression("expression", null),
  317. "viewData");
  318. }
  319. [Fact]
  320. public void FromStringExpressionEmptyExpressionReturnsExistingModelMetadata()
  321. {
  322. // Arrange
  323. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  324. ModelMetadata metadata = new ModelMetadata(provider.Object, null, null, typeof(object), null);
  325. ViewDataDictionary viewData = new ViewDataDictionary();
  326. viewData.ModelMetadata = metadata;
  327. // Act
  328. ModelMetadata result = ModelMetadata.FromStringExpression(String.Empty, viewData, provider.Object);
  329. // Assert
  330. Assert.Same(metadata, result);
  331. }
  332. [Fact]
  333. public void FromStringExpressionItemNotFoundInViewData()
  334. {
  335. // Arrange
  336. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  337. ViewDataDictionary viewData = new ViewDataDictionary();
  338. provider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
  339. .Callback<Func<object>, Type>((accessor, type) =>
  340. {
  341. Assert.Null(accessor);
  342. Assert.Equal(typeof(string), type); // Don't know the type, must fall back on string
  343. })
  344. .Returns(() => null)
  345. .Verifiable();
  346. // Act
  347. ModelMetadata.FromStringExpression("UnknownObject", viewData, provider.Object);
  348. // Assert
  349. provider.Verify();
  350. }
  351. [Fact]
  352. public void FromStringExpressionNullItemFoundAtRootOfViewData()
  353. {
  354. // Arrange
  355. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  356. ViewDataDictionary viewData = new ViewDataDictionary();
  357. viewData["Object"] = null;
  358. provider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
  359. .Callback<Func<object>, Type>((accessor, type) =>
  360. {
  361. Assert.Null(accessor());
  362. Assert.Equal(typeof(string), type); // Don't know the type, must fall back on string
  363. })
  364. .Returns(() => null)
  365. .Verifiable();
  366. // Act
  367. ModelMetadata.FromStringExpression("Object", viewData, provider.Object);
  368. // Assert
  369. provider.Verify();
  370. }
  371. [Fact]
  372. public void FromStringExpressionNonNullItemFoundAtRootOfViewData()
  373. {
  374. // Arrange
  375. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  376. object model = new object();
  377. ViewDataDictionary viewData = new ViewDataDictionary();
  378. viewData["Object"] = model;
  379. provider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
  380. .Callback<Func<object>, Type>((accessor, type) =>
  381. {
  382. Assert.Same(model, accessor());
  383. Assert.Equal(typeof(object), type);
  384. })
  385. .Returns(() => null)
  386. .Verifiable();
  387. // Act
  388. ModelMetadata.FromStringExpression("Object", viewData, provider.Object);
  389. // Assert
  390. provider.Verify();
  391. }
  392. [Fact]
  393. public void FromStringExpressionNullItemFoundOnPropertyOfItemInViewData()
  394. {
  395. // Arrange
  396. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  397. DummyModelContainer model = new DummyModelContainer();
  398. ViewDataDictionary viewData = new ViewDataDictionary();
  399. viewData["Object"] = model;
  400. provider.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), It.IsAny<string>()))
  401. .Callback<Func<object>, Type, string>((accessor, type, propertyName) =>
  402. {
  403. Assert.Null(accessor());
  404. Assert.Equal(typeof(DummyModelContainer), type);
  405. Assert.Equal("Model", propertyName);
  406. })
  407. .Returns(() => null)
  408. .Verifiable();
  409. // Act
  410. ModelMetadata.FromStringExpression("Object.Model", viewData, provider.Object);
  411. // Assert
  412. provider.Verify();
  413. }
  414. [Fact]
  415. public void FromStringExpressionNonNullItemFoundOnPropertyOfItemInViewData()
  416. {
  417. // Arrange
  418. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  419. DummyModelContainer model = new DummyModelContainer { Model = new DummyContactModel() };
  420. ViewDataDictionary viewData = new ViewDataDictionary();
  421. viewData["Object"] = model;
  422. provider.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), It.IsAny<string>()))
  423. .Callback<Func<object>, Type, string>((accessor, type, propertyName) =>
  424. {
  425. Assert.Same(model.Model, accessor());
  426. Assert.Equal(typeof(DummyModelContainer), type);
  427. Assert.Equal("Model", propertyName);
  428. })
  429. .Returns(() => null)
  430. .Verifiable();
  431. // Act
  432. ModelMetadata.FromStringExpression("Object.Model", viewData, provider.Object);
  433. // Assert
  434. provider.Verify();
  435. }
  436. [Fact]
  437. public void FromStringExpressionWithNullModelButValidModelMetadataShouldReturnProperPropertyMetadata()
  438. {
  439. // Arrange
  440. ViewDataDictionary viewData = new ViewDataDictionary();
  441. viewData.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(DummyContactModel));
  442. // Act
  443. ModelMetadata result = ModelMetadata.FromStringExpression("NullableIntValue", viewData);
  444. // Assert
  445. Assert.Null(result.Model);
  446. Assert.Equal(typeof(Nullable<int>), result.ModelType);
  447. Assert.Equal("NullableIntValue", result.PropertyName);
  448. Assert.Equal(typeof(DummyContactModel), result.ContainerType);
  449. }
  450. [Fact]
  451. public void FromStringExpressionValueInModelProperty()
  452. {
  453. // Arrange
  454. DummyContactModel model = new DummyContactModel { FirstName = "John" };
  455. ViewDataDictionary viewData = new ViewDataDictionary(model);
  456. // Act
  457. ModelMetadata metadata = ModelMetadata.FromStringExpression("FirstName", viewData);
  458. // Assert
  459. Assert.Equal("John", metadata.Model);
  460. }
  461. [Fact]
  462. public void FromStringExpressionValueInViewDataOverridesValueFromModelProperty()
  463. {
  464. // Arrange
  465. DummyContactModel model = new DummyContactModel { FirstName = "John" };
  466. ViewDataDictionary viewData = new ViewDataDictionary(model);
  467. viewData["FirstName"] = "Jim";
  468. // Act
  469. ModelMetadata metadata = ModelMetadata.FromStringExpression("FirstName", viewData);
  470. // Assert
  471. Assert.Equal("Jim", metadata.Model);
  472. }
  473. // FromLambdaExpression()
  474. [Fact]
  475. public void FromLambdaExpressionGuardClauseTests()
  476. {
  477. // Null expression throws
  478. Assert.ThrowsArgumentNull(
  479. () => ModelMetadata.FromLambdaExpression<string, object>(null, new ViewDataDictionary<string>()),
  480. "expression");
  481. // Null view data throws
  482. Assert.ThrowsArgumentNull(
  483. () => ModelMetadata.FromLambdaExpression<string, object>(m => m, null),
  484. "viewData");
  485. // Unsupported expression type throws
  486. Assert.Throws<InvalidOperationException>(
  487. () => ModelMetadata.FromLambdaExpression<string, object>(m => new Object(), new ViewDataDictionary<string>()),
  488. "Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.");
  489. }
  490. [Fact]
  491. public void FromLambdaExpressionModelIdentityExpressionReturnsExistingModelMetadata()
  492. {
  493. // Arrange
  494. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  495. ModelMetadata metadata = new ModelMetadata(provider.Object, null, null, typeof(object), null);
  496. ViewDataDictionary<object> viewData = new ViewDataDictionary<object>();
  497. viewData.ModelMetadata = metadata;
  498. // Act
  499. ModelMetadata result = ModelMetadata.FromLambdaExpression<object, object>(m => m, viewData, provider.Object);
  500. // Assert
  501. Assert.Same(metadata, result);
  502. }
  503. [Fact]
  504. public void FromLambdaExpressionPropertyExpressionFromParameter()
  505. {
  506. // Arrange
  507. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  508. DummyContactModel model = new DummyContactModel { FirstName = "Test" };
  509. ViewDataDictionary<DummyContactModel> viewData = new ViewDataDictionary<DummyContactModel>(model);
  510. provider.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), It.IsAny<string>()))
  511. .Callback<Func<object>, Type, string>((accessor, type, propertyName) =>
  512. {
  513. Assert.Equal("Test", accessor());
  514. Assert.Equal(typeof(DummyContactModel), type);
  515. Assert.Equal("FirstName", propertyName);
  516. })
  517. .Returns(() => null)
  518. .Verifiable();
  519. // Act
  520. ModelMetadata.FromLambdaExpression<DummyContactModel, string>(m => m.FirstName, viewData, provider.Object);
  521. // Assert
  522. provider.Verify();
  523. }
  524. [Fact]
  525. public void FromLambdaExpressionPropertyExpressionFromClosureValue()
  526. {
  527. // Arrange
  528. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  529. DummyContactModel model = new DummyContactModel { FirstName = "Test" };
  530. ViewDataDictionary<object> viewData = new ViewDataDictionary<object>();
  531. provider.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), It.IsAny<string>()))
  532. .Callback<Func<object>, Type, string>((accessor, type, propertyName) =>
  533. {
  534. Assert.Equal("Test", accessor());
  535. Assert.Equal(typeof(DummyContactModel), type);
  536. Assert.Equal("FirstName", propertyName);
  537. })
  538. .Returns(() => null)
  539. .Verifiable();
  540. // Act
  541. ModelMetadata.FromLambdaExpression<object, string>(m => model.FirstName, viewData, provider.Object);
  542. // Assert
  543. provider.Verify();
  544. }
  545. [Fact]
  546. public void FromLambdaExpressionFieldExpressionFromParameter()
  547. {
  548. // Arrange
  549. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  550. DummyContactModel model = new DummyContactModel { IntField = 42 };
  551. ViewDataDictionary<DummyContactModel> viewData = new ViewDataDictionary<DummyContactModel>(model);
  552. provider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
  553. .Callback<Func<object>, Type>((accessor, type) =>
  554. {
  555. Assert.Equal(42, accessor());
  556. Assert.Equal(typeof(int), type);
  557. })
  558. .Returns(() => null)
  559. .Verifiable();
  560. // Act
  561. ModelMetadata.FromLambdaExpression<DummyContactModel, int>(m => m.IntField, viewData, provider.Object);
  562. // Assert
  563. provider.Verify();
  564. }
  565. [Fact]
  566. public void FromLambdaExpressionFieldExpressionFromFieldOfClosureValue()
  567. {
  568. // Arrange
  569. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  570. DummyContactModel model = new DummyContactModel { IntField = 42 };
  571. ViewDataDictionary<object> viewData = new ViewDataDictionary<object>();
  572. provider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
  573. .Callback<Func<object>, Type>((accessor, type) =>
  574. {
  575. Assert.Equal(42, accessor());
  576. Assert.Equal(typeof(int), type);
  577. })
  578. .Returns(() => null)
  579. .Verifiable();
  580. // Act
  581. ModelMetadata.FromLambdaExpression<object, int>(m => model.IntField, viewData, provider.Object);
  582. // Assert
  583. provider.Verify();
  584. }
  585. [Fact]
  586. public void FromLambdaExpressionFieldExpressionFromClosureValue()
  587. {
  588. // Arrange
  589. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  590. DummyContactModel model = new DummyContactModel();
  591. ViewDataDictionary<object> viewData = new ViewDataDictionary<object>();
  592. provider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
  593. .Callback<Func<object>, Type>((accessor, type) =>
  594. {
  595. Assert.Same(model, accessor());
  596. Assert.Equal(typeof(DummyContactModel), type);
  597. })
  598. .Returns(() => null)
  599. .Verifiable();
  600. // Act
  601. ModelMetadata.FromLambdaExpression<object, DummyContactModel>(m => model, viewData, provider.Object);
  602. // Assert
  603. provider.Verify();
  604. }
  605. [Fact]
  606. public void FromLambdaExpressionSingleParameterClassIndexer()
  607. {
  608. // Arrange
  609. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  610. DummyContactModel model = new DummyContactModel();
  611. ViewDataDictionary<DummyContactModel> viewData = new ViewDataDictionary<DummyContactModel>(model);
  612. provider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
  613. .Callback<Func<object>, Type>((accessor, type) =>
  614. {
  615. Assert.Equal("Indexed into 42", accessor());
  616. Assert.Equal(typeof(string), type);
  617. })
  618. .Returns(() => null)
  619. .Verifiable();
  620. // Act
  621. ModelMetadata.FromLambdaExpression<DummyContactModel, string>(m => m[42], viewData, provider.Object);
  622. // Assert
  623. provider.Verify();
  624. }
  625. [Fact]
  626. public void FromLambdaExpressionSingleDimensionArrayIndex()
  627. {
  628. // Arrange
  629. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  630. DummyContactModel model = new DummyContactModel { Array = new[] { 4, 8, 15, 16, 23, 42 } };
  631. ViewDataDictionary<DummyContactModel> viewData = new ViewDataDictionary<DummyContactModel>(model);
  632. provider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
  633. .Callback<Func<object>, Type>((accessor, type) =>
  634. {
  635. Assert.Equal(16, accessor());
  636. Assert.Equal(typeof(int), type);
  637. })
  638. .Returns(() => null)
  639. .Verifiable();
  640. // Act
  641. ModelMetadata.FromLambdaExpression<DummyContactModel, int>(m => m.Array[3], viewData, provider.Object);
  642. // Assert
  643. provider.Verify();
  644. }
  645. [Fact]
  646. public void FromLambdaExpressionNullReferenceExceptionsInPropertyExpressionPreserveAllExpressionInformation()
  647. {
  648. // Arrange
  649. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  650. ViewDataDictionary<DummyContactModel> viewData = new ViewDataDictionary<DummyContactModel>();
  651. provider.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), It.IsAny<string>()))
  652. .Callback<Func<object>, Type, string>((accessor, type, propertyName) =>
  653. {
  654. Assert.Null(accessor());
  655. Assert.Equal(typeof(DummyContactModel), type);
  656. Assert.Equal("FirstName", propertyName);
  657. })
  658. .Returns(() => null)
  659. .Verifiable();
  660. // Act
  661. ModelMetadata.FromLambdaExpression<DummyContactModel, string>(m => m.FirstName, viewData, provider.Object);
  662. // Assert
  663. provider.Verify();
  664. }
  665. [Fact]
  666. public void FromLambdaExpressionSetsContainerTypeToDerivedMostType()
  667. { // Dev10 Bug #868619
  668. // Arrange
  669. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  670. ViewDataDictionary<DerivedModel> viewData = new ViewDataDictionary<DerivedModel>();
  671. provider.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), It.IsAny<string>()))
  672. .Callback<Func<object>, Type, string>((accessor, type, propertyName) =>
  673. {
  674. Assert.Null(accessor());
  675. Assert.Equal(typeof(DerivedModel), type);
  676. Assert.Equal("MyProperty", propertyName);
  677. })
  678. .Returns(() => null)
  679. .Verifiable();
  680. // Act
  681. ModelMetadata.FromLambdaExpression<DerivedModel, string>(m => m.MyProperty, viewData, provider.Object);
  682. // Assert
  683. provider.Verify();
  684. }
  685. private class BaseModel
  686. {
  687. public virtual string MyProperty { get; set; }
  688. }
  689. private class DerivedModel : BaseModel
  690. {
  691. [Required]
  692. public override string MyProperty
  693. {
  694. get { return base.MyProperty; }
  695. set { base.MyProperty = value; }
  696. }
  697. }
  698. // GetDisplayName()
  699. [Fact]
  700. public void ReturnsDisplayNameWhenSet()
  701. {
  702. // Arrange
  703. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  704. ModelMetadata metadata = new ModelMetadata(provider.Object, null, null, typeof(object), "PropertyName") { DisplayName = "Display Name" };
  705. // Act
  706. string result = metadata.GetDisplayName();
  707. // Assert
  708. Assert.Equal("Display Name", result);
  709. }
  710. [Fact]
  711. public void ReturnsPropertyNameWhenSetAndDisplayNameIsNull()
  712. {
  713. // Arrange
  714. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  715. ModelMetadata metadata = new ModelMetadata(provider.Object, null, null, typeof(object), "PropertyName");
  716. // Act
  717. string result = metadata.GetDisplayName();
  718. // Assert
  719. Assert.Equal("PropertyName", result);
  720. }
  721. [Fact]
  722. public void ReturnsTypeNameWhenPropertyNameAndDisplayNameAreNull()
  723. {
  724. // Arrange
  725. Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>();
  726. ModelMetadata metadata = new ModelMetadata(provider.Object, null, null, typeof(object), null);
  727. // Act
  728. string result = metadata.GetDisplayName();
  729. // Assert
  730. Assert.Equal("Object", result);
  731. }
  732. // Helpers
  733. private class DummyContactModel
  734. {
  735. public int IntField = 0;
  736. public string FirstName { get; set; }
  737. public string LastName { get; set; }
  738. public Nullable<int> NullableIntValue { get; set; }
  739. public int[] Array { get; set; }
  740. public string this[int index]
  741. {
  742. get { return "Indexed into " + index; }
  743. }
  744. }
  745. private class DummyModelContainer
  746. {
  747. public DummyContactModel Model { get; set; }
  748. }
  749. }
  750. }