@@ -1819,11 +1819,84 @@ public async Task ProcessAsync_CallsGenerateTextBox_InputTypeDateTime_RendersAsD
1819
1819
Assert . Equal ( expectedTagName , output . TagName ) ;
1820
1820
}
1821
1821
1822
+ [ Fact ]
1823
+ public async Task ProcessAsync_CallsGenerateTextBox_InputTypeDateOnly_RendersAsDate ( )
1824
+ {
1825
+ // Arrange
1826
+ var expectedAttributes = new TagHelperAttributeList
1827
+ {
1828
+ { "type" , "date" } , // Calculated; not passed to HtmlGenerator.
1829
+ } ;
1830
+ var expectedTagName = "not-input" ;
1831
+
1832
+ var context = new TagHelperContext (
1833
+ tagName : "input" ,
1834
+ allAttributes : new TagHelperAttributeList ( )
1835
+ {
1836
+ { "type" , "date" }
1837
+ } ,
1838
+ items : new Dictionary < object , object > ( ) ,
1839
+ uniqueId : "test" ) ;
1840
+
1841
+ var output = new TagHelperOutput (
1842
+ expectedTagName ,
1843
+ attributes : new TagHelperAttributeList ( ) ,
1844
+ getChildContentAsync : ( useCachedResult , encoder ) => Task . FromResult < TagHelperContent > (
1845
+ new DefaultTagHelperContent ( ) ) )
1846
+ {
1847
+ TagMode = TagMode . SelfClosing ,
1848
+ } ;
1849
+
1850
+ var htmlAttributes = new Dictionary < string , object >
1851
+ {
1852
+ { "type" , "date" }
1853
+ } ;
1854
+
1855
+ var metadataProvider = TestModelMetadataProvider . CreateDefaultProvider ( ) ;
1856
+
1857
+ var htmlGenerator = new Mock < IHtmlGenerator > ( MockBehavior . Strict ) ;
1858
+ var tagHelper = GetTagHelper (
1859
+ htmlGenerator . Object ,
1860
+ model : null ,
1861
+ propertyName : "DateOnly" ,
1862
+ metadataProvider : metadataProvider ) ;
1863
+ tagHelper . ViewContext . Html5DateRenderingMode = Html5DateRenderingMode . Rfc3339 ;
1864
+ tagHelper . InputTypeName = "date" ;
1865
+ var tagBuilder = new TagBuilder ( "input" ) ;
1866
+ htmlGenerator
1867
+ . Setup ( mock => mock . GenerateTextBox (
1868
+ tagHelper . ViewContext ,
1869
+ tagHelper . For . ModelExplorer ,
1870
+ tagHelper . For . Name ,
1871
+ null , // value
1872
+ @"{0:yyyy-MM-dd}" ,
1873
+ htmlAttributes ) ) // htmlAttributes
1874
+ . Returns ( tagBuilder )
1875
+ . Verifiable ( ) ;
1876
+
1877
+ // Act
1878
+ await tagHelper . ProcessAsync ( context , output ) ;
1879
+
1880
+ // Assert
1881
+ htmlGenerator . Verify ( ) ;
1882
+
1883
+ Assert . Equal ( TagMode . SelfClosing , output . TagMode ) ;
1884
+ Assert . Equal ( expectedAttributes , output . Attributes ) ;
1885
+ Assert . Empty ( output . PreContent . GetContent ( ) ) ;
1886
+ Assert . Equal ( string . Empty , output . Content . GetContent ( ) ) ;
1887
+ Assert . Empty ( output . PostContent . GetContent ( ) ) ;
1888
+ Assert . Equal ( expectedTagName , output . TagName ) ;
1889
+ }
1890
+
1822
1891
[ Theory ]
1823
1892
[ InlineData ( "Date" , Html5DateRenderingMode . CurrentCulture , "{0:d}" , "date" ) ] // Format from [DataType].
1824
1893
[ InlineData ( "Date" , Html5DateRenderingMode . Rfc3339 , "{0:yyyy-MM-dd}" , "date" ) ]
1825
1894
[ InlineData ( "DateTime" , Html5DateRenderingMode . CurrentCulture , null , "datetime-local" ) ]
1826
1895
[ InlineData ( "DateTime" , Html5DateRenderingMode . Rfc3339 , @"{0:yyyy-MM-ddTHH\:mm\:ss.fff}" , "datetime-local" ) ]
1896
+ [ InlineData ( "DateOnlyDate" , Html5DateRenderingMode . CurrentCulture , "{0:d}" , "date" ) ] // Format from [DataType].
1897
+ [ InlineData ( "DateOnlyDate" , Html5DateRenderingMode . Rfc3339 , "{0:yyyy-MM-dd}" , "date" ) ]
1898
+ [ InlineData ( "DateOnly" , Html5DateRenderingMode . CurrentCulture , null , "text" ) ] // Format from [DataType].
1899
+ [ InlineData ( "DateOnly" , Html5DateRenderingMode . Rfc3339 , null , "text" ) ]
1827
1900
[ InlineData ( "DateTimeOffset" , Html5DateRenderingMode . CurrentCulture , null , "text" ) ]
1828
1901
[ InlineData ( "DateTimeOffset" , Html5DateRenderingMode . Rfc3339 , @"{0:yyyy-MM-ddTHH\:mm\:ss.fffK}" , "text" ) ]
1829
1902
[ InlineData ( "DateTimeLocal" , Html5DateRenderingMode . CurrentCulture , null , "datetime-local" ) ]
@@ -1836,6 +1909,8 @@ public async Task ProcessAsync_CallsGenerateTextBox_InputTypeDateTime_RendersAsD
1836
1909
[ InlineData ( "Week" , Html5DateRenderingMode . Rfc3339 , null , "week" ) ]
1837
1910
[ InlineData ( "NullableDate" , Html5DateRenderingMode . Rfc3339 , "{0:yyyy-MM-dd}" , "date" ) ]
1838
1911
[ InlineData ( "NullableDateTime" , Html5DateRenderingMode . Rfc3339 , @"{0:yyyy-MM-ddTHH\:mm\:ss.fff}" , "datetime-local" ) ]
1912
+ [ InlineData ( "NullableDateOnlyDate" , Html5DateRenderingMode . Rfc3339 , "{0:yyyy-MM-dd}" , "date" ) ]
1913
+ [ InlineData ( "NullableDateOnly" , Html5DateRenderingMode . Rfc3339 , null , "text" ) ]
1839
1914
[ InlineData ( "NullableDateTimeOffset" , Html5DateRenderingMode . Rfc3339 , @"{0:yyyy-MM-ddTHH\:mm\:ss.fffK}" , "text" ) ]
1840
1915
public async Task ProcessAsync_CallsGenerateTextBox_AddsExpectedAttributesForRfc3339 (
1841
1916
string propertyName ,
@@ -1973,6 +2048,63 @@ public async Task ProcessAsync_CallsGenerateTextBox_ProducesExpectedValue_ForDat
1973
2048
Assert . Equal ( expectedType , output . TagName ) ;
1974
2049
}
1975
2050
2051
+ // Html5DateRenderingMode.Rfc3339 is enabled by default.
2052
+ [ Theory ]
2053
+ [ InlineData ( "DateOnlyDate" , "2000-01-02" , "date" ) ]
2054
+ [ InlineData ( "DateOnly" , "02/01/2000" , "text" ) ]
2055
+ [ ReplaceCulture ]
2056
+ public async Task ProcessAsync_CallsGenerateTextBox_ProducesExpectedValue_ForDateOnly (
2057
+ string propertyName ,
2058
+ string expectedValue ,
2059
+ string expectedType )
2060
+ {
2061
+ // Arrange
2062
+ var expectedAttributes = new TagHelperAttributeList
2063
+ {
2064
+ { "type" , expectedType } ,
2065
+ { "id" , propertyName } ,
2066
+ { "name" , propertyName } ,
2067
+ { "value" , expectedValue } ,
2068
+ } ;
2069
+
2070
+ var context = new TagHelperContext (
2071
+ tagName : "input" ,
2072
+ allAttributes : new TagHelperAttributeList (
2073
+ Enumerable . Empty < TagHelperAttribute > ( ) ) ,
2074
+ items : new Dictionary < object , object > ( ) ,
2075
+ uniqueId : "test" ) ;
2076
+
2077
+ var output = new TagHelperOutput (
2078
+ expectedType ,
2079
+ attributes : new TagHelperAttributeList ( ) ,
2080
+ getChildContentAsync : ( useCachedResult , encoder ) => Task . FromResult < TagHelperContent > (
2081
+ new DefaultTagHelperContent ( ) ) )
2082
+ {
2083
+ TagMode = TagMode . SelfClosing ,
2084
+ } ;
2085
+
2086
+ var metadataProvider = TestModelMetadataProvider . CreateDefaultProvider ( ) ;
2087
+ var model = new DateOnly (
2088
+ year : 2000 ,
2089
+ month : 1 ,
2090
+ day : 2 ) ;
2091
+
2092
+ var htmlGenerator = HtmlGeneratorUtilities . GetHtmlGenerator ( metadataProvider ) ;
2093
+ var tagHelper = GetTagHelper (
2094
+ htmlGenerator ,
2095
+ model : model ,
2096
+ propertyName : propertyName ,
2097
+ metadataProvider : metadataProvider ) ;
2098
+ tagHelper . ViewContext . Html5DateRenderingMode = Html5DateRenderingMode . Rfc3339 ;
2099
+
2100
+ // Act
2101
+ await tagHelper . ProcessAsync ( context , output ) ;
2102
+
2103
+ // Assert
2104
+ Assert . Equal ( expectedAttributes , output . Attributes ) ;
2105
+ Assert . Equal ( expectedType , output . TagName ) ;
2106
+ }
2107
+
1976
2108
// Html5DateRenderingMode.Rfc3339 can be disabled.
1977
2109
[ Theory ]
1978
2110
[ InlineData ( "Date" , null , "02/01/2000" , "date" ) ]
@@ -2048,6 +2180,67 @@ public async Task ProcessAsync_CallsGenerateTextBox_ProducesExpectedValue_ForDat
2048
2180
Assert . Equal ( expectedType , output . TagName ) ;
2049
2181
}
2050
2182
2183
+ // Html5DateRenderingMode.Rfc3339 can be disabled.
2184
+ [ Theory ]
2185
+ [ InlineData ( "DateOnlyDate" , null , "02/01/2000" , "date" ) ]
2186
+ [ InlineData ( "DateOnlyDate" , "{0:d}" , "02/01/2000" , "date" ) ]
2187
+ [ InlineData ( "DateOnly" , null , "02/01/2000" , "text" ) ]
2188
+ [ ReplaceCulture ]
2189
+ public async Task ProcessAsync_CallsGenerateTextBox_ProducesExpectedValue_ForDateOnlyNotRfc3339 (
2190
+ string propertyName ,
2191
+ string editFormatString ,
2192
+ string expectedValue ,
2193
+ string expectedType )
2194
+ {
2195
+ // Arrange
2196
+ var expectedAttributes = new TagHelperAttributeList
2197
+ {
2198
+ { "type" , expectedType } ,
2199
+ { "id" , propertyName } ,
2200
+ { "name" , propertyName } ,
2201
+ { "value" , expectedValue } ,
2202
+ } ;
2203
+
2204
+ var context = new TagHelperContext (
2205
+ tagName : "input" ,
2206
+ allAttributes : new TagHelperAttributeList (
2207
+ Enumerable . Empty < TagHelperAttribute > ( ) ) ,
2208
+ items : new Dictionary < object , object > ( ) ,
2209
+ uniqueId : "test" ) ;
2210
+
2211
+ var output = new TagHelperOutput (
2212
+ expectedType ,
2213
+ attributes : new TagHelperAttributeList ( ) ,
2214
+ getChildContentAsync : ( useCachedResult , encoder ) => Task . FromResult < TagHelperContent > (
2215
+ new DefaultTagHelperContent ( ) ) )
2216
+ {
2217
+ TagMode = TagMode . SelfClosing ,
2218
+ } ;
2219
+
2220
+ var metadataProvider = TestModelMetadataProvider . CreateDefaultProvider ( ) ;
2221
+
2222
+ var model = new DateOnly (
2223
+ year : 2000 ,
2224
+ month : 1 ,
2225
+ day : 2 ) ;
2226
+
2227
+ var htmlGenerator = HtmlGeneratorUtilities . GetHtmlGenerator ( metadataProvider ) ;
2228
+ var tagHelper = GetTagHelper (
2229
+ htmlGenerator ,
2230
+ model : model ,
2231
+ propertyName : propertyName ,
2232
+ metadataProvider : metadataProvider ) ;
2233
+ tagHelper . ViewContext . Html5DateRenderingMode = Html5DateRenderingMode . CurrentCulture ;
2234
+ tagHelper . Format = editFormatString ;
2235
+
2236
+ // Act
2237
+ await tagHelper . ProcessAsync ( context , output ) ;
2238
+
2239
+ // Assert
2240
+ Assert . Equal ( expectedAttributes , output . Attributes ) ;
2241
+ Assert . Equal ( expectedType , output . TagName ) ;
2242
+ }
2243
+
2051
2244
// Html5DateRenderingMode.Rfc3339 can be disabled.
2052
2245
[ Theory ]
2053
2246
[ InlineData ( "Month" , "month" ) ]
@@ -2184,13 +2377,23 @@ private class Model
2184
2377
2185
2378
public DateTime DateTime { get ; set ; }
2186
2379
2380
+ [ DataType ( DataType . Date ) ]
2381
+ public DateOnly DateOnlyDate { get ; set ; }
2382
+
2383
+ public DateOnly DateOnly { get ; set ; }
2384
+
2187
2385
public DateTimeOffset DateTimeOffset { get ; set ; }
2188
2386
2189
2387
[ DataType ( DataType . Date ) ]
2190
2388
public DateTime ? NullableDate { get ; set ; }
2191
2389
2192
2390
public DateTime ? NullableDateTime { get ; set ; }
2193
2391
2392
+ [ DataType ( DataType . Date ) ]
2393
+ public DateOnly ? NullableDateOnlyDate { get ; set ; }
2394
+
2395
+ public DateOnly ? NullableDateOnly { get ; set ; }
2396
+
2194
2397
public DateTimeOffset ? NullableDateTimeOffset { get ; set ; }
2195
2398
2196
2399
[ DataType ( "datetime-local" ) ]
0 commit comments