diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerActivatorTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerActivatorTest.cs index 87fcb9f93b..3c2846117b 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerActivatorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerActivatorTest.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test services.Setup(s => s.GetService(typeof(IUrlHelper))) .Returns(Mock.Of()); services.Setup(s => s.GetService(typeof(IModelMetadataProvider))) - .Returns(Mock.Of()); + .Returns(new EmptyModelMetadataProvider()); var httpRequest = Mock.Of(); var httpContext = new Mock(); @@ -53,7 +53,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test // Arrange var services = new Mock(); services.Setup(s => s.GetService(typeof(IModelMetadataProvider))) - .Returns(Mock.Of()); + .Returns(new EmptyModelMetadataProvider()); services.Setup(s => s.GetService(typeof(ICompositeViewEngine))) .Returns(Mock.Of()); services.Setup(s => s.GetService(typeof(IUrlHelper))) @@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test services.Setup(s => s.GetService(typeof(IUrlHelper))) .Returns(urlHelper); services.Setup(s => s.GetService(typeof(IModelMetadataProvider))) - .Returns(Mock.Of()); + .Returns(new EmptyModelMetadataProvider()); var httpContext = new Mock(); httpContext.SetupGet(c => c.RequestServices) @@ -114,7 +114,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test services.Setup(s => s.GetService(typeof(IUrlHelper))) .Returns(Mock.Of()); services.Setup(s => s.GetService(typeof(IModelMetadataProvider))) - .Returns(Mock.Of()); + .Returns(new EmptyModelMetadataProvider()); var httpContext = new Mock(); httpContext.SetupGet(c => c.Response) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultViewComponentActivatorTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultViewComponentActivatorTests.cs index 50a2bc9789..fbfdae17fb 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultViewComponentActivatorTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultViewComponentActivatorTests.cs @@ -105,7 +105,7 @@ namespace Microsoft.AspNet.Mvc var actionContext = new ActionContext(routeContext, new ActionDescriptor()); return new ViewContext(actionContext, Mock.Of(), - new ViewDataDictionary(Mock.Of()), + new ViewDataDictionary(new EmptyModelMetadataProvider()), TextWriter.Null); } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperDisplayNameExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperDisplayNameExtensionsTest.cs index a8d6ce154b..40f969ca07 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperDisplayNameExtensionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperDisplayNameExtensionsTest.cs @@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Mvc.Core new DataAnnotationsModelMetadataProvider(), containerType: null, modelAccessor: null, - modelType: typeof(object), + modelType: typeof(string), // Ensure FromStringExpression() doesn't ignore the ModelMetadata. propertyName: propertyName); var helper = DefaultTemplatesUtilities.GetHtmlHelper(); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperLabelExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperLabelExtensionsTest.cs index 4860ab1bd6..24d934a855 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperLabelExtensionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperLabelExtensionsTest.cs @@ -101,7 +101,7 @@ namespace Microsoft.AspNet.Mvc.Core new DataAnnotationsModelMetadataProvider(), containerType: null, modelAccessor: null, - modelType: typeof(object), + modelType: typeof(string), // Ensure FromStringExpression() doesn't ignore the ModelMetadata. propertyName: propertyName); var helper = DefaultTemplatesUtilities.GetHtmlHelper(); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperNameExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperNameExtensionsTest.cs index 8bc953561f..5633484214 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperNameExtensionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperNameExtensionsTest.cs @@ -164,7 +164,7 @@ namespace Microsoft.AspNet.Mvc.Core // Only the ViewDataDictionary should do anything with metadata. provider.Verify( m => m.GetMetadataForType(It.IsAny>(), typeof(DefaultTemplatesUtilities.ObjectTemplateModel)), - Times.Once); + Times.Exactly(2)); } [Fact] @@ -191,7 +191,7 @@ namespace Microsoft.AspNet.Mvc.Core // Only the ViewDataDictionary should do anything with metadata. provider.Verify( m => m.GetMetadataForType(It.IsAny>(), typeof(DefaultTemplatesUtilities.ObjectTemplateModel)), - Times.Once); + Times.Exactly(2)); } [Theory] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewContextTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewContextTests.cs index af31fdd291..72cacee7af 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewContextTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewContextTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNet.Mvc.ModelBinding; using Xunit; namespace Microsoft.AspNet.Mvc.Rendering @@ -12,8 +13,8 @@ namespace Microsoft.AspNet.Mvc.Rendering { // Arrange (eventually passing null to these consturctors will throw) var context = new ViewContext(new ActionContext(null, null, null), view: null, viewData: null, writer: null); - var originalViewData = context.ViewData = new ViewDataDictionary(metadataProvider: null); - var replacementViewData = new ViewDataDictionary(metadataProvider: null); + var originalViewData = context.ViewData = new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider()); + var replacementViewData = new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider()); // Act context.ViewBag.Hello = "goodbye"; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs index 9cbb7b14a6..df8a502b7e 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Mvc // Arrange var viewComponent = new TestViewComponent() { - ViewData = new ViewDataDictionary(metadataProvider: null), + ViewData = new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider()), }; // Act @@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc // Arrange var viewComponent = new TestViewComponent() { - ViewData = new ViewDataDictionary(metadataProvider: null), + ViewData = new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider()), }; // Act diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewDataDictionaryTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewDataDictionaryTest.cs index c7472c4fd1..61cb0fef38 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewDataDictionaryTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewDataDictionaryTest.cs @@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Mvc.Core Assert.NotNull(viewData.ModelState); Assert.NotNull(viewData.TemplateInfo); Assert.Null(viewData.Model); - Assert.Null(viewData.ModelMetadata); + Assert.NotNull(viewData.ModelMetadata); Assert.Equal(0, viewData.Count); } @@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc.Core Assert.Same(modelState, viewData.ModelState); Assert.NotNull(viewData.TemplateInfo); Assert.Null(viewData.Model); - Assert.Null(viewData.ModelMetadata); + Assert.NotNull(viewData.ModelMetadata); Assert.Equal(0, viewData.Count); } @@ -53,9 +53,14 @@ namespace Microsoft.AspNet.Mvc.Core { // Arrange var metadataProvider = new Mock(); - metadataProvider.Setup(m => m.GetMetadataForType(It.IsAny>(), typeof(TestModel))) - .Returns(new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(TestModel))) - .Verifiable(); + metadataProvider + .Setup(m => m.GetMetadataForType(It.IsAny>(), typeof(object))) + .Returns(new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(object))) + .Verifiable(); + metadataProvider + .Setup(m => m.GetMetadataForType(It.IsAny>(), typeof(TestModel))) + .Returns(new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(TestModel))) + .Verifiable(); var modelState = new ModelStateDictionary(); var viewData = new TestViewDataDictionary(metadataProvider.Object, modelState); var model = new TestModel(); @@ -134,7 +139,7 @@ namespace Microsoft.AspNet.Mvc.Core Assert.NotNull(viewData.ModelState); Assert.NotNull(viewData.TemplateInfo); Assert.Null(viewData.Model); - Assert.Null(viewData.ModelMetadata); + Assert.NotNull(viewData.ModelMetadata); Assert.Equal("value1", viewData["key1"]); Assert.IsType>(viewData.Data); } @@ -148,45 +153,56 @@ namespace Microsoft.AspNet.Mvc.Core source["key1"] = "value1"; // Act - var viewData = new ViewDataDictionary(source, null); + var viewData = new ViewDataDictionary(source, model: null); // Assert Assert.NotNull(viewData.ModelState); Assert.NotNull(viewData.TemplateInfo); - Assert.Throws(() => viewData.Model); + Assert.Equal(0, viewData.Model); Assert.NotNull(viewData.ModelMetadata); Assert.Equal("value1", viewData["key1"]); Assert.IsType>(viewData.Data); } + public static TheoryData CopyModelMetadataData + { + get + { + // Instances in this data set must have exactly the same type as the corresponding Type. Otherwise + // the copy constructor ignores the source ModelMetadata. + return new TheoryData + { + { typeof(int), 23 }, + { typeof(string), "hello" }, + { typeof(List), new List() }, + { typeof(string[]), new string[0] }, + { typeof(Dictionary), new Dictionary() }, + }; + } + } + [Theory] - [InlineData(typeof(int))] - [InlineData(typeof(string))] - [InlineData(typeof(IEnumerable))] - [InlineData(typeof(List))] - [InlineData(typeof(string[]))] - [InlineData(typeof(Dictionary))] - public void CopyConstructors_CopyModelMetadata(Type type) + [MemberData(nameof(CopyModelMetadataData))] + public void CopyConstructors_CopyModelMetadata(Type type, object instance) { // Arrange var metadataProvider = new EmptyModelMetadataProvider(); - var metadata = metadataProvider.GetMetadataForType(() => null, type); var source = new ViewDataDictionary(metadataProvider) { - ModelMetadata = metadata, + Model = instance, }; // Act var viewData1 = new ViewDataDictionary(source); - var viewData2 = new ViewDataDictionary(source, model: null); + var viewData2 = new ViewDataDictionary(source, model: instance); // Assert - Assert.Same(metadata, viewData1.ModelMetadata); - Assert.Same(metadata, viewData2.ModelMetadata); + Assert.Same(source.ModelMetadata, viewData1.ModelMetadata); + Assert.Same(source.ModelMetadata, viewData2.ModelMetadata); } [Fact] - public void CopyConstructors_IgnoreModelMetadata_IfForTypeObject() + public void CopyConstructors_CopyModelMetadata_ForTypeObject() { // Arrange var metadataProvider = new EmptyModelMetadataProvider(); @@ -201,8 +217,8 @@ namespace Microsoft.AspNet.Mvc.Core var viewData2 = new ViewDataDictionary(source, model: null); // Assert - Assert.Null(viewData1.ModelMetadata); - Assert.Null(viewData2.ModelMetadata); + Assert.Same(metadata, viewData1.ModelMetadata); + Assert.Same(metadata, viewData2.ModelMetadata); } [Theory] @@ -240,6 +256,28 @@ namespace Microsoft.AspNet.Mvc.Core Assert.Equal(expectedType, viewData2.ModelMetadata.RealModelType); } + [Fact] + public void CopyConstructors_OverrideSourceMetadata_IfDeclaredTypeChanged() + { + // Arrange + var expectedType = typeof(string); + var metadataProvider = new EmptyModelMetadataProvider(); + var source = new ViewDataDictionary(metadataProvider); + + // Act + var viewData1 = new ViewDataDictionary(source); + var viewData2 = new ViewDataDictionary(source, model: null); + + // Assert + Assert.NotNull(viewData1.ModelMetadata); + Assert.Equal(expectedType, viewData1.ModelMetadata.ModelType); + Assert.Equal(expectedType, viewData1.ModelMetadata.RealModelType); + + Assert.NotNull(viewData2.ModelMetadata); + Assert.Equal(expectedType, viewData2.ModelMetadata.ModelType); + Assert.Equal(expectedType, viewData2.ModelMetadata.RealModelType); + } + public static TheoryData Eval_EvaluatesExpressionsData { get diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs index 0dd6989741..a95b2ff0f0 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs @@ -38,7 +38,7 @@ namespace Microsoft.AspNet.Mvc.Razor var actionContext = new ActionContext(routeContext, new ActionDescriptor()); var viewContext = new ViewContext(actionContext, Mock.Of(), - new ViewDataDictionary(Mock.Of()), + new ViewDataDictionary(new EmptyModelMetadataProvider()), TextWriter.Null); // Act @@ -68,7 +68,7 @@ namespace Microsoft.AspNet.Mvc.Razor var actionContext = new ActionContext(routeContext, new ActionDescriptor()); var viewContext = new ViewContext(actionContext, Mock.Of(), - new ViewDataDictionary(Mock.Of()), + new ViewDataDictionary(new EmptyModelMetadataProvider()), TextWriter.Null); // Act and Assert @@ -101,7 +101,7 @@ namespace Microsoft.AspNet.Mvc.Razor .Returns(serviceProvider.Object); var routeContext = new RouteContext(httpContext.Object); var actionContext = new ActionContext(routeContext, new ActionDescriptor()); - var viewData = new ViewDataDictionary(Mock.Of()) + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()) { Model = new MyModel() }; @@ -136,7 +136,7 @@ namespace Microsoft.AspNet.Mvc.Razor .Returns(serviceProvider.Object); var routeContext = new RouteContext(httpContext.Object); var actionContext = new ActionContext(routeContext, new ActionDescriptor()); - var viewData = new ViewDataDictionary(Mock.Of()) + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()) { Model = new MyModel() }; @@ -171,7 +171,7 @@ namespace Microsoft.AspNet.Mvc.Razor .Returns(serviceProvider.Object); var routeContext = new RouteContext(httpContext.Object); var actionContext = new ActionContext(routeContext, new ActionDescriptor()); - var viewData = new ViewDataDictionary(Mock.Of()); + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var viewContext = new ViewContext(actionContext, Mock.Of(), viewData, diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs index fa608d20cd..3ef689bf45 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs @@ -88,7 +88,7 @@ namespace Microsoft.AspNet.Mvc.Razor .Returns(serviceProvider.Object); var routeContext = new RouteContext(httpContext.Object); var actionContext = new ActionContext(routeContext, new ActionDescriptor()); - var viewData = new ViewDataDictionary(Mock.Of()); + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var viewContext = new ViewContext(actionContext, Mock.Of(), viewData, diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs index be538c97f7..fb732b415d 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs @@ -64,7 +64,7 @@ namespace Microsoft.AspNet.Mvc.Razor public async Task RenderAsync_AsPartial_ActivatesViews_WithThePassedInViewContext() { // Arrange - var viewData = new ViewDataDictionary(Mock.Of()); + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var page = new TestableRazorPage(v => { // viewData is assigned to ViewContext by the activator @@ -867,7 +867,7 @@ section-content-2"; return new ViewContext( actionContext, view, - new ViewDataDictionary(Mock.Of()), + new ViewDataDictionary(new EmptyModelMetadataProvider()), new StringWriter()); }