diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/CachedDataAnnotationsMetadataAttributesTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/CachedDataAnnotationsMetadataAttributesTest.cs index 9c65f93877..f4e5682efe 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/CachedDataAnnotationsMetadataAttributesTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/CachedDataAnnotationsMetadataAttributesTest.cs @@ -23,12 +23,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var cache = new CachedDataAnnotationsMetadataAttributes(attributes); // Assert + Assert.Null(cache.DataType); Assert.Null(cache.Display); Assert.Null(cache.DisplayColumn); Assert.Null(cache.DisplayFormat); Assert.Null(cache.Editable); Assert.Null(cache.HiddenInput); Assert.Null(cache.Required); + Assert.Null(cache.ScaffoldColumn); } public static TheoryData> @@ -38,12 +40,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { return new TheoryData> { + { new DataTypeAttribute(DataType.Duration), cache => cache.DataType }, { new DisplayAttribute(), cache => cache.Display }, { new DisplayColumnAttribute("Property"), cache => cache.DisplayColumn }, { new DisplayFormatAttribute(), cache => cache.DisplayFormat }, { new EditableAttribute(allowEdit: false), cache => cache.Editable }, { new HiddenInputAttribute(), cache => cache.HiddenInput }, { new RequiredAttribute(), cache => cache.Required }, + { new ScaffoldColumnAttribute(scaffold: false), cache => cache.ScaffoldColumn }, }; } } @@ -64,5 +68,37 @@ namespace Microsoft.AspNet.Mvc.ModelBinding // Assert Assert.Same(attribute, result); } + + [Fact] + public void Constructor_FindsDisplayFormat_FromDataType() + { + // Arrange + var dataType = new DataTypeAttribute(DataType.Currency); + var displayFormat = dataType.DisplayFormat; // Non-null for DataType.Currency. + var attributes = new[] { dataType, }; + + // Act + var cache = new CachedDataAnnotationsMetadataAttributes(attributes); + var result = cache.DisplayFormat; + + // Assert + Assert.Same(displayFormat, result); + } + + [Fact] + public void Constructor_FindsDisplayFormat_OverridingDataType() + { + // Arrange + var dataType = new DataTypeAttribute(DataType.Time); // Has a non-null DisplayFormat. + var displayFormat = new DisplayFormatAttribute(); + var attributes = new Attribute[] { dataType, displayFormat, }; + + // Act + var cache = new CachedDataAnnotationsMetadataAttributes(attributes); + var result = cache.DisplayFormat; + + // Assert + Assert.Same(displayFormat, result); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/CachedDataAnnotationsModelMetadataTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/CachedDataAnnotationsModelMetadataTest.cs index c484df8b49..75598577d1 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/CachedDataAnnotationsModelMetadataTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/CachedDataAnnotationsModelMetadataTest.cs @@ -30,6 +30,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding // Assert Assert.True(metadata.ConvertEmptyStringToNull); + Assert.False(metadata.HasNonDefaultEditFormat); Assert.False(metadata.HideSurroundingHtml); Assert.True(metadata.IsComplexType); Assert.False(metadata.IsReadOnly); @@ -55,6 +56,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { return new TheoryData> { + { + new DataTypeWithCustomDisplayFormat(), metadata => metadata.DisplayFormatString + }, + { + new DataTypeWithCustomEditFormat(), metadata => metadata.EditFormatString + }, { new DisplayAttribute { Description = "value" }, metadata => metadata.Description }, @@ -64,6 +71,19 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { new DisplayColumnAttribute("Property"), metadata => metadata.SimpleDisplayText }, + { + new DisplayFormatAttribute { DataFormatString = "value" }, + metadata => metadata.DisplayFormatString + }, + { + // DisplayFormatString does not ignore [DisplayFormat] if ApplyFormatInEditMode==true. + new DisplayFormatAttribute { ApplyFormatInEditMode = true, DataFormatString = "value" }, + metadata => metadata.DisplayFormatString + }, + { + new DisplayFormatAttribute { ApplyFormatInEditMode = true, DataFormatString = "value" }, + metadata => metadata.EditFormatString + }, { new DisplayFormatAttribute { NullDisplayText = "value" }, metadata => metadata.NullDisplayText }, @@ -101,6 +121,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { return new TheoryData, bool> { + { + // Edit formats from [DataType] subclass affect HasNonDefaultEditFormat. + new DataTypeWithCustomEditFormat(), + metadata => metadata.HasNonDefaultEditFormat, + true + }, + { + // Edit formats from [DataType] do not affect HasNonDefaultEditFormat. + new DataTypeAttribute(DataType.Date), + metadata => metadata.HasNonDefaultEditFormat, + false + }, { new DisplayFormatAttribute { ConvertEmptyStringToNull = false }, metadata => metadata.ConvertEmptyStringToNull, @@ -111,6 +143,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding metadata => metadata.ConvertEmptyStringToNull, true }, + { + // Changes only to DisplayFormatString do not affect HasNonDefaultEditFormat. + new DisplayFormatAttribute { DataFormatString = "value" }, + metadata => metadata.HasNonDefaultEditFormat, + false + }, + { + new DisplayFormatAttribute { ApplyFormatInEditMode = true, DataFormatString = "value" }, + metadata => metadata.HasNonDefaultEditFormat, + true + }, { new EditableAttribute(allowEdit: false), metadata => metadata.IsReadOnly, @@ -164,6 +207,77 @@ namespace Microsoft.AspNet.Mvc.ModelBinding Assert.Equal(expectedResult, result); } + [Fact] + public void DisplayFormatString_AttributesHaveExpectedPrecedence() + { + // Arrange + var expected = "custom format"; + var dataType = new DataTypeAttribute(DataType.Currency); + var displayFormat = new DisplayFormatAttribute { DataFormatString = expected, }; + var provider = new DataAnnotationsModelMetadataProvider(); + var metadata = new CachedDataAnnotationsModelMetadata( + provider, + containerType: null, + modelType: typeof(object), + propertyName: null, + attributes: new Attribute[] { dataType, displayFormat, }); + + // Act + var result = metadata.DisplayFormatString; + + // Assert + Assert.Equal(expected, result); + } + + [Fact] + public void EditFormatString_AttributesHaveExpectedPrecedence() + { + // Arrange + var expected = "custom format"; + var dataType = new DataTypeAttribute(DataType.Currency); + var displayFormat = new DisplayFormatAttribute + { + ApplyFormatInEditMode = true, + DataFormatString = expected, + }; + var provider = new DataAnnotationsModelMetadataProvider(); + var metadata = new CachedDataAnnotationsModelMetadata( + provider, + containerType: null, + modelType: typeof(object), + propertyName: null, + attributes: new Attribute[] { dataType, displayFormat, }); + + // Act + var result = metadata.EditFormatString; + + // Assert + Assert.Equal(expected, result); + } + + private class DataTypeWithCustomDisplayFormat : DataTypeAttribute + { + public DataTypeWithCustomDisplayFormat() : base("Custom datatype") + { + DisplayFormat = new DisplayFormatAttribute + { + DataFormatString = "value", + }; + } + } + + private class DataTypeWithCustomEditFormat : DataTypeAttribute + { + public DataTypeWithCustomEditFormat() : base("Custom datatype") + { + DisplayFormat = new DisplayFormatAttribute + { + ApplyFormatInEditMode = true, + DataFormatString = "value", + }; + } + } + private class ClassWithDisplayableColumn { public string Property { get; set; } diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs index 25ea719d90..b754641ccb 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs @@ -20,6 +20,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding return new TheoryData, Func, object> { { m => m.ConvertEmptyStringToNull = false, m => m.ConvertEmptyStringToNull, false }, + { m => m.HasNonDefaultEditFormat = true, m => m.HasNonDefaultEditFormat, true }, { m => m.HideSurroundingHtml = true, m => m.HideSurroundingHtml, true }, { m => m.IsReadOnly = true, m => m.IsReadOnly, true }, { m => m.IsRequired = true, m => m.IsRequired, true }, @@ -56,6 +57,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding Assert.Equal(typeof(Exception), metadata.ContainerType); Assert.True(metadata.ConvertEmptyStringToNull); + Assert.False(metadata.HasNonDefaultEditFormat); Assert.False(metadata.HideSurroundingHtml); Assert.False(metadata.IsComplexType); Assert.False(metadata.IsNullableValueType);