Add more `ModelMetadata` and HTML helper tests
- add `CachedDataAnnotationsMetadataAttributesTest` - add `CachedDataAnnotationsModelMetadataTest` - confirm more default property values in `ModelMetadataTest` - confirm use of `DisplayName` in `ModelMetadataTest` - add `HtmlHelperDisplayNameExtensionsTest` - add `HtmlHelperLabelExtensionsTest` - add `HtmlHelperNameExtensionsTest`
This commit is contained in:
parent
48085eea08
commit
3746e44dc3
|
|
@ -70,7 +70,10 @@
|
||||||
<Compile Include="Rendering\DefaultTemplatesUtilities.cs" />
|
<Compile Include="Rendering\DefaultTemplatesUtilities.cs" />
|
||||||
<Compile Include="Rendering\DefaultDisplayTemplatesTests.cs" />
|
<Compile Include="Rendering\DefaultDisplayTemplatesTests.cs" />
|
||||||
<Compile Include="Rendering\DefaultEditorTemplatesTests.cs" />
|
<Compile Include="Rendering\DefaultEditorTemplatesTests.cs" />
|
||||||
|
<Compile Include="Rendering\HtmlHelperDisplayNameExtensionsTest.cs" />
|
||||||
<Compile Include="Rendering\HtmlAttributePropertyHelperTest.cs" />
|
<Compile Include="Rendering\HtmlAttributePropertyHelperTest.cs" />
|
||||||
|
<Compile Include="Rendering\HtmlHelperLabelExtensionsTest.cs" />
|
||||||
|
<Compile Include="Rendering\HtmlHelperNameExtensionsTest.cs" />
|
||||||
<Compile Include="Rendering\ViewContextTests.cs" />
|
<Compile Include="Rendering\ViewContextTests.cs" />
|
||||||
<Compile Include="Rendering\ViewDataOfTTest.cs" />
|
<Compile Include="Rendering\ViewDataOfTTest.cs" />
|
||||||
<Compile Include="KnownRouteValueConstraintTests.cs" />
|
<Compile Include="KnownRouteValueConstraintTests.cs" />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,326 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Test the <see cref="HtmlHelperDisplayNameExtensions" /> class.
|
||||||
|
/// </summary>
|
||||||
|
public class HtmlHelperDisplayNameExtensionsTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void DisplayNameHelpers_ReturnEmptyForModel()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
var enumerableHelper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<DefaultTemplatesUtilities.ObjectTemplateModel>>(null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var displayNameResult = helper.DisplayName("");
|
||||||
|
var displayNameNullResult = helper.DisplayName(expression: null); // null is another alias for current model
|
||||||
|
var displayNameForResult = helper.DisplayNameFor(m => m);
|
||||||
|
var displayNameForEnumerableModelResult = enumerableHelper.DisplayNameFor(m => m);
|
||||||
|
var displayNameForModelResult = helper.DisplayNameForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(displayNameResult.ToString());
|
||||||
|
Assert.Empty(displayNameNullResult.ToString());
|
||||||
|
Assert.Empty(displayNameForResult.ToString());
|
||||||
|
Assert.Empty(displayNameForEnumerableModelResult.ToString());
|
||||||
|
Assert.Empty(displayNameForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DisplayNameHelpers_ReturnPropertyName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
var enumerableHelper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<DefaultTemplatesUtilities.ObjectTemplateModel>>(null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var displayNameResult = helper.DisplayName("Property1");
|
||||||
|
var displayNameForResult = helper.DisplayNameFor(m => m.Property1);
|
||||||
|
var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("Property1", displayNameResult.ToString());
|
||||||
|
Assert.Equal("Property1", displayNameForResult.ToString());
|
||||||
|
Assert.Equal("Property1", displayNameForEnumerableResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DisplayNameHelpers_ReturnPropertyName_ForNestedProperty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper<OuterClass>(model: null);
|
||||||
|
var enumerableHelper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<OuterClass>>(model: null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var displayNameResult = helper.DisplayName("Inner.Id");
|
||||||
|
var displayNameForResult = helper.DisplayNameFor(m => m.Inner.Id);
|
||||||
|
var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m.Inner.Id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("Id", displayNameResult.ToString());
|
||||||
|
Assert.Equal("Id", displayNameForResult.ToString());
|
||||||
|
Assert.Equal("Id", displayNameForEnumerableResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData("Custom property name from metadata")]
|
||||||
|
public void DisplayNameHelpers_ReturnMetadataPropertyName_IfOverridden(string propertyName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadata = new ModelMetadata(
|
||||||
|
new DataAnnotationsModelMetadataProvider(),
|
||||||
|
containerType: null,
|
||||||
|
modelAccessor: null,
|
||||||
|
modelType: typeof(object),
|
||||||
|
propertyName: propertyName);
|
||||||
|
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelMetadata = metadata;
|
||||||
|
var enumerableHelper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<DefaultTemplatesUtilities.ObjectTemplateModel>>(null);
|
||||||
|
enumerableHelper.ViewData.ModelMetadata = metadata;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var displayNameResult = helper.DisplayName("");
|
||||||
|
var displayNameForResult = helper.DisplayNameFor(m => m);
|
||||||
|
var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m);
|
||||||
|
var displayNameForModelResult = helper.DisplayNameForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(propertyName, displayNameResult.ToString());
|
||||||
|
Assert.Equal(propertyName, displayNameForResult.ToString());
|
||||||
|
Assert.Equal(propertyName, displayNameForEnumerableResult.ToString());
|
||||||
|
Assert.Equal(propertyName, displayNameForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData("Custom property name from metadata")]
|
||||||
|
public void DisplayNameHelpers_ReturnMetadataPropertyNameForProperty_IfOverridden(string propertyName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataHelper = new MetadataHelper();
|
||||||
|
var metadata = new ModelMetadata(
|
||||||
|
metadataHelper.MetadataProvider.Object,
|
||||||
|
containerType: null,
|
||||||
|
modelAccessor: null,
|
||||||
|
modelType: typeof(object),
|
||||||
|
propertyName: propertyName);
|
||||||
|
metadataHelper.MetadataProvider
|
||||||
|
.Setup(provider => provider.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), "Property1"))
|
||||||
|
.Returns(metadata);
|
||||||
|
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
var enumerableHelper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<DefaultTemplatesUtilities.ObjectTemplateModel>>(
|
||||||
|
model: null,
|
||||||
|
provider: metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var displayNameForResult = helper.DisplayNameFor(m => m.Property1);
|
||||||
|
var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(propertyName, displayNameForResult.ToString());
|
||||||
|
Assert.Equal(propertyName, displayNameForEnumerableResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")] // Empty display name wins over non-empty property name.
|
||||||
|
[InlineData("Custom display name from metadata")]
|
||||||
|
public void DisplayNameHelpers_ReturnDisplayName_IfNonNull(string displayName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelMetadata.DisplayName = displayName;
|
||||||
|
var enumerableHelper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<DefaultTemplatesUtilities.ObjectTemplateModel>>(null);
|
||||||
|
enumerableHelper.ViewData.ModelMetadata.DisplayName = displayName;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var displayNameResult = helper.DisplayName("");
|
||||||
|
var displayNameForResult = helper.DisplayNameFor(m => m);
|
||||||
|
var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m);
|
||||||
|
var displayNameForModelResult = helper.DisplayNameForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(displayName, displayNameResult.ToString());
|
||||||
|
Assert.Equal(displayName, displayNameForResult.ToString());
|
||||||
|
Assert.Equal(displayName, displayNameForEnumerableResult.ToString());
|
||||||
|
Assert.Equal(displayName, displayNameForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData("Custom display name from metadata")]
|
||||||
|
public void DisplayNameHelpers_ReturnDisplayNameForProperty_IfNonNull(string displayName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataHelper = new MetadataHelper(); // All properties will use the same metadata.
|
||||||
|
metadataHelper.Metadata
|
||||||
|
.Setup(metadata => metadata.DisplayName)
|
||||||
|
.Returns(displayName);
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
var enumerableHelper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<DefaultTemplatesUtilities.ObjectTemplateModel>>(
|
||||||
|
model: null,
|
||||||
|
provider: metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var displayNameResult = helper.DisplayName("Property1");
|
||||||
|
var displayNameForResult = helper.DisplayNameFor(m => m.Property1);
|
||||||
|
var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(displayName, displayNameResult.ToString());
|
||||||
|
Assert.Equal(displayName, displayNameForResult.ToString());
|
||||||
|
Assert.Equal(displayName, displayNameForEnumerableResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("A", "A")]
|
||||||
|
[InlineData("A[23]", "A[23]")]
|
||||||
|
[InlineData("A[0].B", "B")]
|
||||||
|
[InlineData("A.B.C.D", "D")]
|
||||||
|
public void DisplayName_ReturnsRightmostExpressionSegment_IfPropertiesNotFound(
|
||||||
|
string expression,
|
||||||
|
string expectedResult)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataHelper = new MetadataHelper();
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = helper.DisplayName(expression);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// DisplayName() falls back to expression name when DisplayName and PropertyName are null.
|
||||||
|
Assert.Equal(expectedResult, result.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DisplayNameFor_ConsultsMetadataProviderForMetadataAboutProperty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var modelType = typeof(DefaultTemplatesUtilities.ObjectTemplateModel);
|
||||||
|
var metadataHelper = new MetadataHelper();
|
||||||
|
metadataHelper.MetadataProvider
|
||||||
|
.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), modelType, "Property1"))
|
||||||
|
.Returns(metadataHelper.Metadata.Object)
|
||||||
|
.Verifiable();
|
||||||
|
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = helper.DisplayNameFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
metadataHelper.MetadataProvider.Verify();
|
||||||
|
|
||||||
|
// DisplayNameFor() falls back to expression name when DisplayName and PropertyName are null.
|
||||||
|
Assert.Equal("Property1", result.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DisplayNameFor_ThrowsInvalidOperation_IfExpressionUnsupported()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<InvalidOperationException>(
|
||||||
|
() => helper.DisplayNameFor(model => new { foo = "Bar" }));
|
||||||
|
Assert.Equal(
|
||||||
|
"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.",
|
||||||
|
exception.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnumerableDisplayNameFor_ThrowsInvalidOperation_IfExpressionUnsupported()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<DefaultTemplatesUtilities.ObjectTemplateModel>>(null);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<InvalidOperationException>(
|
||||||
|
() => helper.DisplayNameFor(model => new { foo = "Bar" }));
|
||||||
|
Assert.Equal(
|
||||||
|
"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.",
|
||||||
|
exception.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DisplayNameFor_ReturnsVariableName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var unknownKey = "this is a dummy parameter value";
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = helper.DisplayNameFor(model => unknownKey);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("unknownKey", result.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnumerableDisplayNameFor_ReturnsVariableName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var unknownKey = "this is a dummy parameter value";
|
||||||
|
var helper =
|
||||||
|
DefaultTemplatesUtilities.GetHtmlHelper<IEnumerable<DefaultTemplatesUtilities.ObjectTemplateModel>>(null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = helper.DisplayNameFor(model => unknownKey);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("unknownKey", result.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class InnerClass
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class OuterClass
|
||||||
|
{
|
||||||
|
public InnerClass Inner { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class MetadataHelper
|
||||||
|
{
|
||||||
|
public Mock<ModelMetadata> Metadata { get; set; }
|
||||||
|
public Mock<IModelMetadataProvider> MetadataProvider { get; set; }
|
||||||
|
|
||||||
|
public MetadataHelper()
|
||||||
|
{
|
||||||
|
MetadataProvider = new Mock<IModelMetadataProvider>();
|
||||||
|
Metadata = new Mock<ModelMetadata>(MetadataProvider.Object, null, null, typeof(object), null);
|
||||||
|
|
||||||
|
MetadataProvider.Setup(p => p.GetMetadataForProperties(It.IsAny<object>(), It.IsAny<Type>()))
|
||||||
|
.Returns(new ModelMetadata[0]);
|
||||||
|
MetadataProvider.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), It.IsAny<string>()))
|
||||||
|
.Returns(Metadata.Object);
|
||||||
|
MetadataProvider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
|
||||||
|
.Returns(Metadata.Object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,332 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Test the <see cref="HtmlHelperLabelExtensions" /> class.
|
||||||
|
/// </summary>
|
||||||
|
public class HtmlHelperLabelExtensionsTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void LabelHelpers_ReturnEmptyForModel()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("");
|
||||||
|
var labelNullResult = helper.Label(expression: null); // null is another alias for current model
|
||||||
|
var labelForResult = helper.LabelFor(m => m);
|
||||||
|
var labelForModelResult = helper.LabelForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(labelResult.ToString());
|
||||||
|
Assert.Empty(labelNullResult.ToString());
|
||||||
|
Assert.Empty(labelForResult.ToString());
|
||||||
|
Assert.Empty(labelForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabelHelpers_DisplayPropertyName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("Property1");
|
||||||
|
var labelForResult = helper.LabelFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("<label for=\"Property1\">Property1</label>", labelResult.ToString());
|
||||||
|
Assert.Equal("<label for=\"Property1\">Property1</label>", labelForResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabelHelpers_DisplayPropertyName_ForNestedProperty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper<OuterClass>(model: null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("Inner.Id");
|
||||||
|
var labelForResult = helper.LabelFor(m => m.Inner.Id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("<label for=\"Inner.Id\">Id</label>", labelResult.ToString());
|
||||||
|
Assert.Equal("<label for=\"Inner.Id\">Id</label>", labelForResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabelHelpers_ReturnEmptyForModel_IfMetadataPropertyNameEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadata = new ModelMetadata(
|
||||||
|
new DataAnnotationsModelMetadataProvider(),
|
||||||
|
containerType: null,
|
||||||
|
modelAccessor: null,
|
||||||
|
modelType: typeof(object),
|
||||||
|
propertyName: string.Empty);
|
||||||
|
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelMetadata = metadata;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("");
|
||||||
|
var labelNullResult = helper.Label(expression: null); // null is another alias for current model
|
||||||
|
var labelForResult = helper.LabelFor(m => m);
|
||||||
|
var labelForModelResult = helper.LabelForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(labelResult.ToString());
|
||||||
|
Assert.Empty(labelNullResult.ToString());
|
||||||
|
Assert.Empty(labelForResult.ToString());
|
||||||
|
Assert.Empty(labelForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("MyProperty")]
|
||||||
|
[InlineData("Custom property name from metadata")]
|
||||||
|
public void LabelHelpers_DisplayMetadataPropertyName_IfOverridden(string propertyName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadata = new ModelMetadata(
|
||||||
|
new DataAnnotationsModelMetadataProvider(),
|
||||||
|
containerType: null,
|
||||||
|
modelAccessor: null,
|
||||||
|
modelType: typeof(object),
|
||||||
|
propertyName: propertyName);
|
||||||
|
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelMetadata = metadata;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("");
|
||||||
|
var labelForResult = helper.LabelFor(m => m);
|
||||||
|
var labelForModelResult = helper.LabelForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("<label for=\"\">" + propertyName + "</label>", labelResult.ToString());
|
||||||
|
Assert.Equal("<label for=\"\">" + propertyName + "</label>", labelForResult.ToString());
|
||||||
|
Assert.Equal("<label for=\"\">" + propertyName + "</label>", labelForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("MyProperty")]
|
||||||
|
[InlineData("Custom property name from metadata")]
|
||||||
|
public void LabelHelpers_DisplayMetadataPropertyNameForProperty_IfOverridden(string propertyName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataHelper = new MetadataHelper();
|
||||||
|
var metadata = new ModelMetadata(
|
||||||
|
metadataHelper.MetadataProvider.Object,
|
||||||
|
containerType: null,
|
||||||
|
modelAccessor: null,
|
||||||
|
modelType: typeof(object),
|
||||||
|
propertyName: propertyName);
|
||||||
|
metadataHelper.MetadataProvider
|
||||||
|
.Setup(provider => provider.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), "Property1"))
|
||||||
|
.Returns(metadata);
|
||||||
|
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelForResult = helper.LabelFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("<label for=\"Property1\">" + propertyName + "</label>", labelForResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabelHelpers_ReturnEmptyForModel_IfDisplayNameEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelMetadata.DisplayName = string.Empty;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("");
|
||||||
|
var labelNullResult = helper.Label(expression: null); // null is another alias for current model
|
||||||
|
var labelForResult = helper.LabelFor(m => m);
|
||||||
|
var labelForModelResult = helper.LabelForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(labelResult.ToString());
|
||||||
|
Assert.Empty(labelNullResult.ToString());
|
||||||
|
Assert.Empty(labelForResult.ToString());
|
||||||
|
Assert.Empty(labelForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("DisplayName")]
|
||||||
|
[InlineData("Custom display name from metadata")]
|
||||||
|
public void LabelHelpers_DisplayDisplayName_IfNonNull(string displayName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.ModelMetadata.DisplayName = displayName;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("");
|
||||||
|
var labelForResult = helper.LabelFor(m => m);
|
||||||
|
var labelForModelResult = helper.LabelForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("<label for=\"\">" + displayName + "</label>", labelResult.ToString());
|
||||||
|
Assert.Equal("<label for=\"\">" + displayName + "</label>", labelForResult.ToString());
|
||||||
|
Assert.Equal("<label for=\"\">" + displayName + "</label>", labelForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabelHelpers_ReturnEmptyForProperty_IfDisplayNameEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataHelper = new MetadataHelper(); // All properties will use the same metadata.
|
||||||
|
metadataHelper.Metadata
|
||||||
|
.Setup(metadata => metadata.DisplayName)
|
||||||
|
.Returns(string.Empty);
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("");
|
||||||
|
var labelNullResult = helper.Label(expression: null); // null is another alias for current model
|
||||||
|
var labelForResult = helper.LabelFor(m => m);
|
||||||
|
var labelForModelResult = helper.LabelForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(labelResult.ToString());
|
||||||
|
Assert.Empty(labelNullResult.ToString());
|
||||||
|
Assert.Empty(labelForResult.ToString());
|
||||||
|
Assert.Empty(labelForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("DisplayName")]
|
||||||
|
[InlineData("Custom display name from metadata")]
|
||||||
|
public void LabelHelpers_DisplayDisplayNameForProperty_IfNonNull(string displayName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataHelper = new MetadataHelper(); // All properties will use the same metadata.
|
||||||
|
metadataHelper.Metadata
|
||||||
|
.Setup(metadata => metadata.DisplayName)
|
||||||
|
.Returns(displayName);
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var labelResult = helper.Label("Property1");
|
||||||
|
var labelForResult = helper.LabelFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("<label for=\"Property1\">" + displayName + "</label>", labelResult.ToString());
|
||||||
|
Assert.Equal("<label for=\"Property1\">" + displayName + "</label>", labelForResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("A", "A")]
|
||||||
|
[InlineData("A[23]", "A[23]")]
|
||||||
|
[InlineData("A[0].B", "B")]
|
||||||
|
[InlineData("A.B.C.D", "D")]
|
||||||
|
public void Label_DisplaysRightmostExpressionSegment_IfPropertiesNotFound(
|
||||||
|
string expression,
|
||||||
|
string expectedResult)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var metadataHelper = new MetadataHelper();
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = helper.Label(expression);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// Label() falls back to expression name when DisplayName and PropertyName are null.
|
||||||
|
Assert.Equal("<label for=\"" + expression + "\">" + expectedResult + "</label>", result.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabelFor_ConsultsMetadataProviderForMetadataAboutProperty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var modelType = typeof(DefaultTemplatesUtilities.ObjectTemplateModel);
|
||||||
|
var metadataHelper = new MetadataHelper();
|
||||||
|
metadataHelper.MetadataProvider
|
||||||
|
.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), modelType, "Property1"))
|
||||||
|
.Returns(metadataHelper.Metadata.Object)
|
||||||
|
.Verifiable();
|
||||||
|
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(metadataHelper.MetadataProvider.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = helper.LabelFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
metadataHelper.MetadataProvider.Verify();
|
||||||
|
|
||||||
|
// LabelFor() falls back to expression name when DisplayName and PropertyName are null.
|
||||||
|
Assert.Equal("<label for=\"Property1\">Property1</label>", result.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabelFor_ThrowsInvalidOperation_IfExpressionUnsupported()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<InvalidOperationException>(
|
||||||
|
() => helper.LabelFor(model => new { foo = "Bar" }));
|
||||||
|
Assert.Equal(
|
||||||
|
"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.",
|
||||||
|
exception.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabelFor_DisplaysVariableName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var unknownKey = "this is a dummy parameter value";
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = helper.LabelFor(model => unknownKey);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("<label for=\"unknownKey\">unknownKey</label>", result.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class InnerClass
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class OuterClass
|
||||||
|
{
|
||||||
|
public InnerClass Inner { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class MetadataHelper
|
||||||
|
{
|
||||||
|
public Mock<ModelMetadata> Metadata { get; set; }
|
||||||
|
public Mock<IModelMetadataProvider> MetadataProvider { get; set; }
|
||||||
|
|
||||||
|
public MetadataHelper()
|
||||||
|
{
|
||||||
|
MetadataProvider = new Mock<IModelMetadataProvider>();
|
||||||
|
Metadata = new Mock<ModelMetadata>(MetadataProvider.Object, null, null, typeof(object), null);
|
||||||
|
|
||||||
|
MetadataProvider.Setup(p => p.GetMetadataForProperties(It.IsAny<object>(), It.IsAny<Type>()))
|
||||||
|
.Returns(new ModelMetadata[0]);
|
||||||
|
MetadataProvider.Setup(p => p.GetMetadataForProperty(It.IsAny<Func<object>>(), It.IsAny<Type>(), It.IsAny<string>()))
|
||||||
|
.Returns(Metadata.Object);
|
||||||
|
MetadataProvider.Setup(p => p.GetMetadataForType(It.IsAny<Func<object>>(), It.IsAny<Type>()))
|
||||||
|
.Returns(Metadata.Object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,255 @@
|
||||||
|
// 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 System;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Test the <see cref="HtmlHelperNameExtensions" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// TODO #704: When that bug is fixed and Id() behaves differently than Name(), will need to break some
|
||||||
|
/// test methods below in two.
|
||||||
|
/// </remarks>
|
||||||
|
public class HtmlHelperNameExtensionsTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void IdAndNameHelpers_ReturnEmptyForModel()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var idResult = helper.Id("");
|
||||||
|
var idNullResult = helper.Id(name: null); // null is another alias for current model
|
||||||
|
var idForResult = helper.IdFor(m => m);
|
||||||
|
var idForModelResult = helper.IdForModel();
|
||||||
|
var nameResult = helper.Name("");
|
||||||
|
var nameNullResult = helper.Name(name: null);
|
||||||
|
var nameForResult = helper.NameFor(m => m);
|
||||||
|
var nameForModelResult = helper.NameForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(idResult.ToString());
|
||||||
|
Assert.Empty(idNullResult.ToString());
|
||||||
|
Assert.Empty(idForResult.ToString());
|
||||||
|
Assert.Empty(idForModelResult.ToString());
|
||||||
|
Assert.Empty(nameResult.ToString());
|
||||||
|
Assert.Empty(nameNullResult.ToString());
|
||||||
|
Assert.Empty(nameForResult.ToString());
|
||||||
|
Assert.Empty(nameForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData("A")]
|
||||||
|
[InlineData("A[23]")]
|
||||||
|
[InlineData("A[0].B")]
|
||||||
|
[InlineData("A.B.C.D")]
|
||||||
|
public void IdAndNameHelpers_ReturnPrefixForModel(string prefix)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
helper.ViewData.TemplateInfo.HtmlFieldPrefix = prefix;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var idResult = helper.Id("");
|
||||||
|
var idForResult = helper.IdFor(m => m);
|
||||||
|
var idForModelResult = helper.IdForModel();
|
||||||
|
var nameResult = helper.Name("");
|
||||||
|
var nameForResult = helper.NameFor(m => m);
|
||||||
|
var nameForModelResult = helper.NameForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(prefix, idResult.ToString());
|
||||||
|
Assert.Equal(prefix, idForResult.ToString());
|
||||||
|
Assert.Equal(prefix, idForModelResult.ToString());
|
||||||
|
Assert.Equal(prefix, nameResult.ToString());
|
||||||
|
Assert.Equal(prefix, nameForResult.ToString());
|
||||||
|
Assert.Equal(prefix, nameForModelResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IdAndNameHelpers_ReturnPropertyName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var idResult = helper.Id("Property1");
|
||||||
|
var idForResult = helper.IdFor(m => m.Property1);
|
||||||
|
var nameResult = helper.Name("Property1");
|
||||||
|
var nameForResult = helper.NameFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("Property1", idResult.ToString());
|
||||||
|
Assert.Equal("Property1", idForResult.ToString());
|
||||||
|
Assert.Equal("Property1", nameResult.ToString());
|
||||||
|
Assert.Equal("Property1", nameForResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null, "Property1")]
|
||||||
|
[InlineData("", "Property1")]
|
||||||
|
[InlineData("A", "A.Property1")]
|
||||||
|
[InlineData("A[23]", "A[23].Property1")]
|
||||||
|
[InlineData("A[0].B", "A[0].B.Property1")]
|
||||||
|
[InlineData("A.B.C.D", "A.B.C.D.Property1")]
|
||||||
|
public void IdAndNameHelpers_ReturnPrefixAndPropertyName(string prefix, string expectedResult)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var idResult = helper.Id("Property1");
|
||||||
|
var idForResult = helper.IdFor(m => m.Property1);
|
||||||
|
var nameResult = helper.Name("Property1");
|
||||||
|
var nameForResult = helper.NameFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("Property1", idResult.ToString());
|
||||||
|
Assert.Equal("Property1", idForResult.ToString());
|
||||||
|
Assert.Equal("Property1", nameResult.ToString());
|
||||||
|
Assert.Equal("Property1", nameForResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IdAndNameHelpers_ReturnPropertyPath_ForNestedProperty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper<OuterClass>(model: null);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var idResult = helper.Id("Inner.Id");
|
||||||
|
var idForResult = helper.IdFor(m => m.Inner.Id);
|
||||||
|
var nameResult = helper.Name("Inner.Id");
|
||||||
|
var nameForResult = helper.NameFor(m => m.Inner.Id);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("Inner.Id", idResult.ToString());
|
||||||
|
Assert.Equal("Inner.Id", idForResult.ToString());
|
||||||
|
Assert.Equal("Inner.Id", nameResult.ToString());
|
||||||
|
Assert.Equal("Inner.Id", nameForResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IdAndNameHelpers_DoNotConsultMetadataOrMetadataProvider()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var provider = new Mock<IModelMetadataProvider>(MockBehavior.Strict);
|
||||||
|
var metadata =
|
||||||
|
new Mock<ModelMetadata>(MockBehavior.Strict, provider.Object, null, null, typeof(object), null);
|
||||||
|
provider
|
||||||
|
.Setup(m => m.GetMetadataForType(
|
||||||
|
It.IsAny<Func<object>>(),
|
||||||
|
typeof(DefaultTemplatesUtilities.ObjectTemplateModel)))
|
||||||
|
.Returns(metadata.Object);
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(provider.Object);
|
||||||
|
|
||||||
|
// Act (do not throw)
|
||||||
|
var idResult = helper.Id("");
|
||||||
|
var idForResult = helper.IdFor(m => m);
|
||||||
|
var idForModelResult = helper.IdForModel();
|
||||||
|
var nameResult = helper.Name("");
|
||||||
|
var nameForResult = helper.NameFor(m => m);
|
||||||
|
var nameForModelResult = helper.NameForModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// Only the ViewDataDictionary should do anything with metadata.
|
||||||
|
provider.Verify(
|
||||||
|
m => m.GetMetadataForType(It.IsAny<Func<object>>(), typeof(DefaultTemplatesUtilities.ObjectTemplateModel)),
|
||||||
|
Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IdAndNameHelpers_DoNotConsultMetadataOrMetadataProvider_ForProperty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var provider = new Mock<IModelMetadataProvider>(MockBehavior.Strict);
|
||||||
|
var metadata =
|
||||||
|
new Mock<ModelMetadata>(MockBehavior.Strict, provider.Object, null, null, typeof(object), null);
|
||||||
|
provider
|
||||||
|
.Setup(m => m.GetMetadataForType(
|
||||||
|
It.IsAny<Func<object>>(),
|
||||||
|
typeof(DefaultTemplatesUtilities.ObjectTemplateModel)))
|
||||||
|
.Returns(metadata.Object);
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper(provider.Object);
|
||||||
|
|
||||||
|
// Act (do not throw)
|
||||||
|
var idResult = helper.Id("Property1");
|
||||||
|
var idForResult = helper.IdFor(m => m.Property1);
|
||||||
|
var nameResult = helper.Name("Property1");
|
||||||
|
var nameForResult = helper.NameFor(m => m.Property1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// Only the ViewDataDictionary should do anything with metadata.
|
||||||
|
provider.Verify(
|
||||||
|
m => m.GetMetadataForType(It.IsAny<Func<object>>(), typeof(DefaultTemplatesUtilities.ObjectTemplateModel)),
|
||||||
|
Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("A")]
|
||||||
|
[InlineData("A[0].B")]
|
||||||
|
[InlineData("A.B.C.D")]
|
||||||
|
public void IdAndName_ReturnExpression_EvenIfExpressionNotFound(string expression)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var idResult = helper.Id(expression);
|
||||||
|
var nameResult = helper.Name(expression);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expression, idResult.ToString());
|
||||||
|
Assert.Equal(expression, nameResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IdForAndNameFor_ReturnEmpty_IfExpressionUnsupported()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var idResult = helper.IdFor(model => new { foo = "Bar" });
|
||||||
|
var nameResult = helper.NameFor(model => new { foo = "Bar" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(idResult.ToString());
|
||||||
|
Assert.Empty(nameResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IdForAndNameFor_ReturnVariableName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var unknownKey = "this is a dummy parameter value";
|
||||||
|
var helper = DefaultTemplatesUtilities.GetHtmlHelper();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var idResult = helper.IdFor(model => unknownKey);
|
||||||
|
var nameResult = helper.NameFor(model => unknownKey);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("unknownKey", idResult.ToString());
|
||||||
|
Assert.Equal("unknownKey", nameResult.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class InnerClass
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class OuterClass
|
||||||
|
{
|
||||||
|
public InnerClass Inner { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Test the <see cref="CachedDataAnnotationsMetadataAttributes" /> class.
|
||||||
|
/// </summary>
|
||||||
|
public class CachedDataAnnotationsMetadataAttributesTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Constructor_DefaultsAllPropertiesToNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var attributes = Enumerable.Empty<Attribute>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var cache = new CachedDataAnnotationsMetadataAttributes(attributes);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Null(cache.Display);
|
||||||
|
Assert.Null(cache.DisplayColumn);
|
||||||
|
Assert.Null(cache.DisplayFormat);
|
||||||
|
Assert.Null(cache.Editable);
|
||||||
|
Assert.Null(cache.Required);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TheoryData<Attribute, Func<CachedDataAnnotationsMetadataAttributes, Attribute>>
|
||||||
|
ExpectedAttributeData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new TheoryData<Attribute, Func<CachedDataAnnotationsMetadataAttributes, Attribute>>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new DisplayAttribute(),
|
||||||
|
(CachedDataAnnotationsMetadataAttributes cache) => cache.Display
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new DisplayColumnAttribute("Property"),
|
||||||
|
(CachedDataAnnotationsMetadataAttributes cache) => cache.DisplayColumn
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new DisplayFormatAttribute(),
|
||||||
|
(CachedDataAnnotationsMetadataAttributes cache) => cache.DisplayFormat
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new EditableAttribute(allowEdit: false),
|
||||||
|
(CachedDataAnnotationsMetadataAttributes cache) => cache.Editable
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new RequiredAttribute(),
|
||||||
|
(CachedDataAnnotationsMetadataAttributes cache) => cache.Required
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData("ExpectedAttributeData")]
|
||||||
|
public void Constructor_FindsExpectedAttribute(
|
||||||
|
Attribute attribute,
|
||||||
|
Func<CachedDataAnnotationsMetadataAttributes, Attribute> accessor)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var attributes = new[] { attribute };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var cache = new CachedDataAnnotationsMetadataAttributes(attributes);
|
||||||
|
var result = accessor(cache);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Same(attribute, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Test the <see cref="CachedDataAnnotationsModelMetadata" /> class.
|
||||||
|
/// </summary>
|
||||||
|
public class CachedDataAnnotationsModelMetadataTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Constructor_DefersDefaultsToBaseModelMetadata()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var attributes = Enumerable.Empty<Attribute>();
|
||||||
|
var provider = new DataAnnotationsModelMetadataProvider();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var metadata = new CachedDataAnnotationsModelMetadata(
|
||||||
|
provider,
|
||||||
|
containerType: null,
|
||||||
|
modelType: typeof(object),
|
||||||
|
propertyName: null,
|
||||||
|
attributes: attributes);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(metadata.ConvertEmptyStringToNull);
|
||||||
|
Assert.False(metadata.IsReadOnly);
|
||||||
|
Assert.False(metadata.IsRequired);
|
||||||
|
|
||||||
|
Assert.Null(metadata.Description);
|
||||||
|
Assert.Null(metadata.DisplayName);
|
||||||
|
Assert.Null(metadata.NullDisplayText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TheoryData<Attribute, Func<ModelMetadata, string>> ExpectedAttributeDataStrings
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new TheoryData<Attribute, Func<ModelMetadata, string>>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new DisplayAttribute { Description = "value" },
|
||||||
|
(ModelMetadata metadata) => metadata.Description
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new DisplayAttribute { Name = "value" },
|
||||||
|
(ModelMetadata metadata) => metadata.DisplayName
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new DisplayColumnAttribute("Property"),
|
||||||
|
(ModelMetadata metadata) => metadata.SimpleDisplayText
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new DisplayFormatAttribute { NullDisplayText = "value" },
|
||||||
|
(ModelMetadata metadata) => metadata.NullDisplayText
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData("ExpectedAttributeDataStrings")]
|
||||||
|
public void AttributesOverrideMetadataStrings(Attribute attribute, Func<ModelMetadata, string> accessor)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var attributes = new[] { attribute };
|
||||||
|
var provider = new DataAnnotationsModelMetadataProvider();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var metadata = new CachedDataAnnotationsModelMetadata(
|
||||||
|
provider,
|
||||||
|
containerType: null,
|
||||||
|
modelType: typeof(ClassWithDisplayableColumn),
|
||||||
|
propertyName: null,
|
||||||
|
attributes: attributes)
|
||||||
|
{
|
||||||
|
Model = new ClassWithDisplayableColumn { Property = "value" },
|
||||||
|
};
|
||||||
|
var result = accessor(metadata);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("value", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TheoryData<Attribute, Func<ModelMetadata, bool>, bool> ExpectedAttributeDataBooleans
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new TheoryData<Attribute, Func<ModelMetadata, bool>, bool>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new DisplayFormatAttribute { ConvertEmptyStringToNull = false },
|
||||||
|
(ModelMetadata metadata) => metadata.ConvertEmptyStringToNull,
|
||||||
|
false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new DisplayFormatAttribute { ConvertEmptyStringToNull = true },
|
||||||
|
(ModelMetadata metadata) => metadata.ConvertEmptyStringToNull,
|
||||||
|
true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new EditableAttribute(allowEdit: false),
|
||||||
|
(ModelMetadata metadata) => metadata.IsReadOnly,
|
||||||
|
true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new EditableAttribute(allowEdit: true),
|
||||||
|
(ModelMetadata metadata) => metadata.IsReadOnly,
|
||||||
|
false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new RequiredAttribute(),
|
||||||
|
(ModelMetadata metadata) => metadata.IsRequired,
|
||||||
|
true
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData("ExpectedAttributeDataBooleans")]
|
||||||
|
public void AttributesOverrideMetadataBooleans(
|
||||||
|
Attribute attribute,
|
||||||
|
Func<ModelMetadata, bool> accessor,
|
||||||
|
bool expectedResult)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var attributes = new[] { attribute };
|
||||||
|
var provider = new DataAnnotationsModelMetadataProvider();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var metadata = new CachedDataAnnotationsModelMetadata(
|
||||||
|
provider,
|
||||||
|
containerType: null,
|
||||||
|
modelType: typeof(object),
|
||||||
|
propertyName: null,
|
||||||
|
attributes: attributes);
|
||||||
|
var result = accessor(metadata);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ClassWithDisplayableColumn
|
||||||
|
{
|
||||||
|
public string Property { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,12 +28,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(typeof(Exception), metadata.ContainerType);
|
Assert.Equal(typeof(Exception), metadata.ContainerType);
|
||||||
Assert.True(metadata.ConvertEmptyStringToNull);
|
Assert.True(metadata.ConvertEmptyStringToNull);
|
||||||
Assert.Null(metadata.NullDisplayText);
|
Assert.False(metadata.IsComplexType);
|
||||||
|
Assert.False(metadata.IsReadOnly);
|
||||||
|
Assert.False(metadata.IsRequired);
|
||||||
|
|
||||||
Assert.Null(metadata.Description);
|
Assert.Null(metadata.Description);
|
||||||
|
Assert.Null(metadata.DisplayFormatString);
|
||||||
|
Assert.Null(metadata.DisplayName);
|
||||||
|
Assert.Null(metadata.EditFormatString);
|
||||||
|
Assert.Null(metadata.NullDisplayText);
|
||||||
|
Assert.Null(metadata.TemplateHint);
|
||||||
|
|
||||||
Assert.Equal("model", metadata.Model);
|
Assert.Equal("model", metadata.Model);
|
||||||
|
Assert.Equal("model", metadata.SimpleDisplayText);
|
||||||
Assert.Equal(typeof(string), metadata.ModelType);
|
Assert.Equal(typeof(string), metadata.ModelType);
|
||||||
Assert.Equal("propertyName", metadata.PropertyName);
|
Assert.Equal("propertyName", metadata.PropertyName);
|
||||||
Assert.False(metadata.IsReadOnly);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -195,6 +204,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
// GetDisplayName()
|
// GetDisplayName()
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetDisplayName_ReturnsDisplayName_IfSet()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var provider = new EmptyModelMetadataProvider();
|
||||||
|
var metadata = new ModelMetadata(provider, null, () => null, typeof(object), "unusedName")
|
||||||
|
{
|
||||||
|
DisplayName = "displayName",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = metadata.GetDisplayName();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal("displayName", result);
|
||||||
|
}
|
||||||
|
|
||||||
#if NET45
|
#if NET45
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ReturnsPropertyNameWhenSetAndDisplayNameIsNull()
|
public void ReturnsPropertyNameWhenSetAndDisplayNameIsNull()
|
||||||
|
|
@ -224,6 +250,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
Assert.Equal("Object", result);
|
Assert.Equal("Object", result);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SimpleDisplayText
|
// SimpleDisplayText
|
||||||
|
|
||||||
public static IEnumerable<object[]> SimpleDisplayTextData
|
public static IEnumerable<object[]> SimpleDisplayTextData
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,9 @@
|
||||||
<Compile Include="Formatters\JsonInputFormatterTest.cs" />
|
<Compile Include="Formatters\JsonInputFormatterTest.cs" />
|
||||||
<Compile Include="Internal\TypeExtensionTests.cs" />
|
<Compile Include="Internal\TypeExtensionTests.cs" />
|
||||||
<Compile Include="Metadata\AssociatedMetadataProviderTest.cs" />
|
<Compile Include="Metadata\AssociatedMetadataProviderTest.cs" />
|
||||||
|
<Compile Include="Metadata\CachedDataAnnotationsMetadataAttributesTest.cs" />
|
||||||
<Compile Include="Metadata\CachedDataAnnotationsModelMetadataProviderTest.cs" />
|
<Compile Include="Metadata\CachedDataAnnotationsModelMetadataProviderTest.cs" />
|
||||||
|
<Compile Include="Metadata\CachedDataAnnotationsModelMetadataTest.cs" />
|
||||||
<Compile Include="Metadata\ModelMetadataTest.cs" />
|
<Compile Include="Metadata\ModelMetadataTest.cs" />
|
||||||
<Compile Include="ModelBindingContextTest.cs" />
|
<Compile Include="ModelBindingContextTest.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs" />
|
<Compile Include="Properties\Resources.Designer.cs" />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue