Support more primitive type converters (#70057)
authorTarek Mahmoud Sayed <tarekms@microsoft.com>
Thu, 2 Jun 2022 00:41:31 +0000 (17:41 -0700)
committerGitHub <noreply@github.com>
Thu, 2 Jun 2022 00:41:31 +0000 (17:41 -0700)
17 files changed:
src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs
src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj
src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateOnlyConverter.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/HalfConverter.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Int128Converter.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs
src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TimeOnlyConverter.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/UInt128Converter.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/tests/DateOnlyConverterTests.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/tests/HalfConverterTests.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/tests/Int128ConverterTests.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj
src/libraries/System.ComponentModel.TypeConverter/tests/TimeOnlyConverterTests.cs [new file with mode: 0644]
src/libraries/System.ComponentModel.TypeConverter/tests/TrimmingTests/TypeConverterTest.cs
src/libraries/System.ComponentModel.TypeConverter/tests/TypeConverterTests.cs
src/libraries/System.ComponentModel.TypeConverter/tests/TypeDescriptorTests.cs
src/libraries/System.ComponentModel.TypeConverter/tests/UInt128ConverterTests.cs [new file with mode: 0644]

index 375cc5f..41cc105 100644 (file)
@@ -351,6 +351,14 @@ namespace System.ComponentModel
         Insert = 3,
         Delete = 4,
     }
+    public partial class DateOnlyConverter : System.ComponentModel.TypeConverter
+    {
+        public DateOnlyConverter() { }
+        public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type sourceType) { throw null; }
+        public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] System.Type? destinationType) { throw null; }
+        public override object? ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { throw null; }
+        public override object? ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type destinationType) { throw null; }
+    }
     public partial class DateTimeConverter : System.ComponentModel.TypeConverter
     {
         public DateTimeConverter() { }
@@ -510,6 +518,10 @@ namespace System.ComponentModel
         public override object? ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { throw null; }
         public override object? ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type destinationType) { throw null; }
     }
+    public partial class HalfConverter : System.ComponentModel.BaseNumberConverter
+    {
+        public HalfConverter() { }
+    }
     public partial class HandledEventArgs : System.EventArgs
     {
         public HandledEventArgs() { }
@@ -655,6 +667,10 @@ namespace System.ComponentModel
         public virtual string Text { get { throw null; } }
         public abstract object? CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Type instanceType);
     }
+    public partial class Int128Converter : System.ComponentModel.BaseNumberConverter
+    {
+        public Int128Converter() { }
+    }
     public partial class Int16Converter : System.ComponentModel.BaseNumberConverter
     {
         public Int16Converter() { }
@@ -1244,6 +1260,14 @@ namespace System.ComponentModel
         public static bool CheckPath(string value) { throw null; }
         public static bool CheckRootedPath(string value) { throw null; }
     }
+    public partial class TimeOnlyConverter : System.ComponentModel.TypeConverter
+    {
+        public TimeOnlyConverter() { }
+        public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type sourceType) { throw null; }
+        public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] System.Type? destinationType) { throw null; }
+        public override object? ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value) { throw null; }
+        public override object? ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type destinationType) { throw null; }
+    }
     public partial class TimeSpanConverter : System.ComponentModel.TypeConverter
     {
         public TimeSpanConverter() { }
@@ -1541,6 +1565,10 @@ namespace System.ComponentModel
     {
         public UInt64Converter() { }
     }
+    public partial class UInt128Converter : System.ComponentModel.BaseNumberConverter
+    {
+        public UInt128Converter() { }
+    }
     public partial class VersionConverter : System.ComponentModel.TypeConverter
     {
         public VersionConverter() { }
index d3ac144..bd04566 100644 (file)
     <Compile Include="System\ComponentModel\ByteConverter.cs" />
     <Compile Include="System\ComponentModel\CharConverter.cs" />
     <Compile Include="System\ComponentModel\CollectionConverter.cs" />
+    <Compile Include="System\ComponentModel\DateOnlyConverter.cs" />
     <Compile Include="System\ComponentModel\DateTimeConverter.cs" />
     <Compile Include="System\ComponentModel\DateTimeOffsetConverter.cs" />
     <Compile Include="System\ComponentModel\DecimalConverter.cs" />
     <Compile Include="System\ComponentModel\DoubleConverter.cs" />
     <Compile Include="System\ComponentModel\EnumConverter.cs" />
     <Compile Include="System\ComponentModel\GuidConverter.cs" />
+    <Compile Include="System\ComponentModel\HalfConverter.cs" />
     <Compile Include="System\ComponentModel\Int16Converter.cs" />
+    <Compile Include="System\ComponentModel\Int128Converter.cs" />
     <Compile Include="System\ComponentModel\Int32Converter.cs" />
     <Compile Include="System\ComponentModel\Int64Converter.cs" />
     <Compile Include="System\ComponentModel\ITypeDescriptorContext.cs" />
     <Compile Include="System\ComponentModel\SByteConverter.cs" />
     <Compile Include="System\ComponentModel\SingleConverter.cs" />
     <Compile Include="System\ComponentModel\StringConverter.cs" />
+    <Compile Include="System\ComponentModel\TimeOnlyConverter.cs" />
     <Compile Include="System\ComponentModel\TimeSpanConverter.cs" />
     <Compile Include="System\ComponentModel\TypeConverter.cs" />
     <Compile Include="System\ComponentModel\TypeListConverter.cs" />
+    <Compile Include="System\ComponentModel\UInt128Converter.cs" />
     <Compile Include="System\ComponentModel\UInt16Converter.cs" />
     <Compile Include="System\ComponentModel\UInt32Converter.cs" />
     <Compile Include="System\ComponentModel\UInt64Converter.cs" />
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateOnlyConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/DateOnlyConverter.cs
new file mode 100644 (file)
index 0000000..1a118c4
--- /dev/null
@@ -0,0 +1,115 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.ComponentModel.Design.Serialization;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
+
+namespace System.ComponentModel
+{
+    /// <summary>
+    /// Provides a type converter to convert <see cref='System.DateOnly'/>
+    /// objects to and from various other representations.
+    /// </summary>
+    public class DateOnlyConverter : TypeConverter
+    {
+        /// <summary>
+        /// Gets a value indicating whether this converter can convert an
+        /// object in the given source type to a <see cref='System.DateOnly'/>
+        /// object using the specified context.
+        /// </summary>
+        public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
+        {
+            return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether this converter can convert an object
+        /// to the given destination type using the context.
+        /// </summary>
+        public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen(true)] Type? destinationType)
+        {
+            return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType);
+        }
+
+        /// <summary>
+        /// Converts the given value object to a <see cref='System.DateOnly'/> object.
+        /// </summary>
+        public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
+        {
+            if (value is string text)
+            {
+                text = text.Trim();
+                if (text.Length == 0)
+                {
+                    return DateOnly.MinValue;
+                }
+
+                try
+                {
+                    // See if we have a culture info to parse with. If so, then use it.
+                    DateTimeFormatInfo? formatInfo = null;
+
+                    if (culture != null)
+                    {
+                        formatInfo = (DateTimeFormatInfo?)culture.GetFormat(typeof(DateTimeFormatInfo));
+                    }
+
+                    if (formatInfo != null)
+                    {
+                        return DateOnly.Parse(text, formatInfo);
+                    }
+                    else
+                    {
+                        return DateOnly.Parse(text, culture);
+                    }
+                }
+                catch (FormatException e)
+                {
+                    throw new FormatException(SR.Format(SR.ConvertInvalidPrimitive, (string)value, nameof(DateOnly)), e);
+                }
+            }
+
+            return base.ConvertFrom(context, culture, value);
+        }
+
+        /// <summary>
+        /// Converts the given value object to a <see cref='System.DateOnly'/>
+        /// object using the arguments.
+        /// </summary>
+        public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
+        {
+            if (destinationType == typeof(string) && value is DateOnly dateOnly)
+            {
+                if (dateOnly == DateOnly.MinValue)
+                {
+                    return string.Empty;
+                }
+
+                if (culture == null)
+                {
+                    culture = CultureInfo.CurrentCulture;
+                }
+
+                DateTimeFormatInfo? formatInfo = (DateTimeFormatInfo?)culture.GetFormat(typeof(DateTimeFormatInfo));
+
+                if (culture == CultureInfo.InvariantCulture)
+                {
+                    return dateOnly.ToString("yyyy-MM-dd", culture);
+                }
+
+                string format = formatInfo!.ShortDatePattern;
+
+                return dateOnly.ToString(format, CultureInfo.CurrentCulture);
+            }
+
+            if (destinationType == typeof(InstanceDescriptor) && value is DateOnly date)
+            {
+                return new InstanceDescriptor(typeof(DateOnly).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int) }), new object[] { date.Year, date.Month, date.Day });
+            }
+
+            return base.ConvertTo(context, culture, value, destinationType);
+        }
+    }
+}
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/HalfConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/HalfConverter.cs
new file mode 100644 (file)
index 0000000..c627816
--- /dev/null
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System.Globalization;
+
+namespace System.ComponentModel
+{
+    /// <summary>
+    /// Provides a type converter to convert half-precision, floating point number objects to and
+    /// from various other representations.
+    /// </summary>
+    public class HalfConverter : BaseNumberConverter
+    {
+        /// <summary>
+        /// Determines whether this editor will attempt to convert hex (0x or #) strings
+        /// </summary>
+        internal override bool AllowHex => false;
+
+        /// <summary>
+        /// The Type this converter is targeting (e.g. Int16, UInt32, etc.)
+        /// </summary>
+        internal override Type TargetType => typeof(Half);
+
+        /// <summary>
+        /// Convert the given value to a string using the given radix
+        /// </summary>
+        internal override object FromString(string value, int radix) => throw new NotImplementedException(); // This method shouldn't be called anyway for the Half type as it doesn't support hex formatting.
+
+        /// <summary>
+        /// Convert the given value to a string using the given formatInfo
+        /// </summary>
+        internal override object FromString(string value, NumberFormatInfo? formatInfo) => Half.Parse(value, formatInfo);
+
+        /// <summary>
+        /// Convert the given value from a string using the given formatInfo
+        /// </summary>
+        internal override string ToString(object value, NumberFormatInfo? formatInfo) =>
+            ((Half)value).ToString(formatInfo);
+    }
+}
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Int128Converter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Int128Converter.cs
new file mode 100644 (file)
index 0000000..e02f897
--- /dev/null
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System.Globalization;
+
+namespace System.ComponentModel
+{
+    /// <summary>
+    /// Provides a type converter to convert 128-bit signed integer objects to and
+    /// from various other representations.
+    /// </summary>
+    public class Int128Converter : BaseNumberConverter
+    {
+        /// <summary>
+        /// The Type this converter is targeting (e.g. Int16, UInt32, etc.)
+        /// </summary>
+        internal override Type TargetType => typeof(Int128);
+
+        /// <summary>
+        /// Convert the given value string to Int128 using the given radix
+        /// </summary>
+        internal override object FromString(string value, int radix)
+        {
+            Debug.Assert(radix == 16);
+            Debug.Assert(value is not null);
+
+            return Int128.Parse(value, NumberStyles.HexNumber);
+        }
+
+        /// <summary>
+        /// Convert the given value string to Int128 using given formatInfo
+        /// </summary>
+        internal override object FromString(string value, NumberFormatInfo? formatInfo) =>
+            Int128.Parse(value, formatInfo);
+
+        /// <summary>
+        /// Convert the given value from a string using the given formatInfo
+        /// </summary>
+        internal override string ToString(object value, NumberFormatInfo? formatInfo) =>
+            ((Int128)value).ToString(formatInfo);
+    }
+}
index ad13f79..00f8802 100644 (file)
@@ -164,17 +164,22 @@ namespace System.ComponentModel
                     [typeof(double)] = new IntrinsicTypeConverterData((type) => new DoubleConverter()),
                     [typeof(string)] = new IntrinsicTypeConverterData((type) => new StringConverter()),
                     [typeof(int)] = new IntrinsicTypeConverterData((type) => new Int32Converter()),
+                    [typeof(Int128)] = new IntrinsicTypeConverterData((type) => new Int128Converter()),
                     [typeof(short)] = new IntrinsicTypeConverterData((type) => new Int16Converter()),
                     [typeof(long)] = new IntrinsicTypeConverterData((type) => new Int64Converter()),
                     [typeof(float)] = new IntrinsicTypeConverterData((type) => new SingleConverter()),
+                    [typeof(Half)] = new IntrinsicTypeConverterData((type) => new HalfConverter()),
+                    [typeof(UInt128)] = new IntrinsicTypeConverterData((type) => new UInt128Converter()),
                     [typeof(ushort)] = new IntrinsicTypeConverterData((type) => new UInt16Converter()),
                     [typeof(uint)] = new IntrinsicTypeConverterData((type) => new UInt32Converter()),
                     [typeof(ulong)] = new IntrinsicTypeConverterData((type) => new UInt64Converter()),
                     [typeof(object)] = new IntrinsicTypeConverterData((type) => new TypeConverter()),
                     [typeof(CultureInfo)] = new IntrinsicTypeConverterData((type) => new CultureInfoConverter()),
+                    [typeof(DateOnly)] = new IntrinsicTypeConverterData((type) => new DateOnlyConverter()),
                     [typeof(DateTime)] = new IntrinsicTypeConverterData((type) => new DateTimeConverter()),
                     [typeof(DateTimeOffset)] = new IntrinsicTypeConverterData((type) => new DateTimeOffsetConverter()),
                     [typeof(decimal)] = new IntrinsicTypeConverterData((type) => new DecimalConverter()),
+                    [typeof(TimeOnly)] = new IntrinsicTypeConverterData((type) => new TimeOnlyConverter()),
                     [typeof(TimeSpan)] = new IntrinsicTypeConverterData((type) => new TimeSpanConverter()),
                     [typeof(Guid)] = new IntrinsicTypeConverterData((type) => new GuidConverter()),
                     [typeof(Uri)] = new IntrinsicTypeConverterData((type) => new UriTypeConverter()),
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TimeOnlyConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TimeOnlyConverter.cs
new file mode 100644 (file)
index 0000000..050bb59
--- /dev/null
@@ -0,0 +1,114 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.ComponentModel.Design.Serialization;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
+
+namespace System.ComponentModel
+{
+    /// <summary>
+    /// Provides a type converter to convert <see cref='System.TimeOnly'/>
+    /// objects to and from various other representations.
+    /// </summary>
+    public class TimeOnlyConverter : TypeConverter
+    {
+        /// <summary>
+        /// Gets a value indicating whether this converter can convert an
+        /// object in the given source type to a <see cref='System.TimeOnly'/>
+        /// object using the specified context.
+        /// </summary>
+        public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
+        {
+            return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether this converter can convert an object
+        /// to the given destination type using the context.
+        /// </summary>
+        public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen(true)] Type? destinationType)
+        {
+            return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType);
+        }
+
+        /// <summary>
+        /// Converts the given value object to a <see cref='System.TimeOnly'/> object.
+        /// </summary>
+        public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
+        {
+            if (value is string text)
+            {
+                text = text.Trim();
+                if (text.Length == 0)
+                {
+                    return TimeOnly.MinValue;
+                }
+
+                try
+                {
+                    // See if we have a culture info to parse with. If so, then use it.
+                    DateTimeFormatInfo? formatInfo = null;
+
+                    if (culture != null)
+                    {
+                        formatInfo = (DateTimeFormatInfo?)culture.GetFormat(typeof(DateTimeFormatInfo));
+                    }
+
+                    if (formatInfo != null)
+                    {
+                        return TimeOnly.Parse(text, formatInfo);
+                    }
+                    else
+                    {
+                        return TimeOnly.Parse(text, culture);
+                    }
+                }
+                catch (FormatException e)
+                {
+                    throw new FormatException(SR.Format(SR.ConvertInvalidPrimitive, (string)value, nameof(TimeOnly)), e);
+                }
+            }
+
+            return base.ConvertFrom(context, culture, value);
+        }
+
+        /// <summary>
+        /// Converts the given value object to a <see cref='System.TimeOnly'/>
+        /// object using the arguments.
+        /// </summary>
+        public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
+        {
+            if (destinationType == typeof(string) && value is TimeOnly timeOnly)
+            {
+                if (timeOnly == TimeOnly.MinValue)
+                {
+                    return string.Empty;
+                }
+
+                if (culture == null)
+                {
+                    culture = CultureInfo.CurrentCulture;
+                }
+
+                DateTimeFormatInfo? formatInfo = (DateTimeFormatInfo?)culture.GetFormat(typeof(DateTimeFormatInfo));
+
+                return timeOnly.ToString(formatInfo!.ShortTimePattern, CultureInfo.CurrentCulture);
+            }
+
+            if (destinationType == typeof(InstanceDescriptor) && value is TimeOnly time)
+            {
+                if (time.Ticks == 0)
+                {
+                    return new InstanceDescriptor(typeof(TimeOnly).GetConstructor(new Type[] { typeof(long) }), new object[] { time.Ticks });
+                }
+
+                return new InstanceDescriptor(typeof(TimeOnly).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }),
+                                                new object[] { time.Hour, time.Minute, time.Second, time.Millisecond, time.Microsecond});
+            }
+
+            return base.ConvertTo(context, culture, value, destinationType);
+        }
+    }
+}
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/UInt128Converter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/UInt128Converter.cs
new file mode 100644 (file)
index 0000000..de5d892
--- /dev/null
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System.Globalization;
+
+namespace System.ComponentModel
+{
+    /// <summary>
+    /// Provides a type converter to convert 128-bit unsigned integer objects to and
+    /// from various other representations.
+    /// </summary>
+    public class UInt128Converter : BaseNumberConverter
+    {
+        /// <summary>
+        /// The Type this converter is targeting (e.g. Int16, UInt64, etc.)
+        /// </summary>
+        internal override Type TargetType => typeof(UInt128);
+
+        /// <summary>
+        /// Convert the given value string to UInt128 using the given radix
+        /// </summary>
+        internal override object FromString(string value, int radix)
+        {
+            Debug.Assert(radix == 16);
+            Debug.Assert(value is not null);
+
+            return UInt128.Parse(value, NumberStyles.HexNumber);
+        }
+
+        /// <summary>
+        /// Convert the given value to a string using the given formatInfo
+        /// </summary>
+        internal override object FromString(string value, NumberFormatInfo? formatInfo) =>
+            UInt128.Parse(value, formatInfo);
+
+        /// <summary>
+        /// Convert the given value from a string using the given formatInfo
+        /// </summary>
+        internal override string ToString(object value, NumberFormatInfo? formatInfo) =>
+            ((UInt128)value).ToString(formatInfo);
+    }
+}
diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/DateOnlyConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/DateOnlyConverterTests.cs
new file mode 100644 (file)
index 0000000..8759db9
--- /dev/null
@@ -0,0 +1,65 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.ComponentModel.Design.Serialization;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.DotNet.RemoteExecutor;
+using Xunit;
+
+namespace System.ComponentModel.Tests
+{
+    public class DateOnlyConverterTests : TypeConverterTestBase
+    {
+        public override TypeConverter Converter => new DateOnlyConverter();
+
+        public override IEnumerable<ConvertTest> ConvertFromTestData()
+        {
+            DateOnly dateOnly = new DateOnly(1998, 12, 5);
+            yield return ConvertTest.Valid("", DateOnly.MinValue);
+            yield return ConvertTest.Valid("    ", DateOnly.MinValue);
+            yield return ConvertTest.Valid(dateOnly.ToString(), dateOnly);
+            yield return ConvertTest.Valid(dateOnly.ToString(CultureInfo.InvariantCulture.DateTimeFormat), dateOnly, CultureInfo.InvariantCulture);
+            yield return ConvertTest.Valid(" " + dateOnly.ToString(CultureInfo.InvariantCulture.DateTimeFormat) + " ", dateOnly, CultureInfo.InvariantCulture);
+
+            yield return ConvertTest.Throws<FormatException>("invalid");
+
+            yield return ConvertTest.CantConvertFrom(new object());
+            yield return ConvertTest.CantConvertFrom(1);
+        }
+
+        public override IEnumerable<ConvertTest> ConvertToTestData()
+        {
+            CultureInfo polandCulture = new CultureInfo("pl-PL");
+            DateTimeFormatInfo formatInfo = CultureInfo.CurrentCulture.DateTimeFormat;
+            DateOnly dateOnly = new DateOnly(1998, 12, 5);
+            yield return ConvertTest.Valid(dateOnly, dateOnly.ToString(formatInfo.ShortDatePattern));
+            yield return ConvertTest.Valid(dateOnly, dateOnly.ToString(polandCulture.DateTimeFormat.ShortDatePattern, polandCulture.DateTimeFormat))
+                .WithRemoteInvokeCulture(polandCulture);
+            yield return ConvertTest.Valid(dateOnly, "1998-12-05", CultureInfo.InvariantCulture)
+                .WithRemoteInvokeCulture(polandCulture);
+
+            yield return ConvertTest.Valid(DateOnly.MinValue, string.Empty);
+
+            yield return ConvertTest.Valid(
+                dateOnly,
+                new InstanceDescriptor(
+                    typeof(DateOnly).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int) }),
+                    new object[] { 1998, 12, 5 }
+                )
+            );
+
+            yield return ConvertTest.CantConvertTo(new DateOnly(), typeof(DateOnly));
+            yield return ConvertTest.CantConvertTo(new DateOnly(), typeof(int));
+        }
+
+        [Theory]
+        [InlineData(typeof(InstanceDescriptor))]
+        [InlineData(typeof(int))]
+        public void ConvertTo_InvalidValue_ThrowsNotSupportedException(Type destinationType)
+        {
+            Assert.Throws<NotSupportedException>(() => Converter.ConvertTo(new object(), destinationType));
+        }
+    }
+}
diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/HalfConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/HalfConverterTests.cs
new file mode 100644 (file)
index 0000000..7216cff
--- /dev/null
@@ -0,0 +1,48 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.ComponentModel.Design.Serialization;
+using System.Globalization;
+
+namespace System.ComponentModel.Tests
+{
+    public class HalfConverterTests : BaseNumberConverterTests
+    {
+        public override TypeConverter Converter => new HalfConverter();
+
+        public override IEnumerable<ConvertTest> ConvertToTestData()
+        {
+            yield return ConvertTest.Valid((Half)(-1), "-1");
+            yield return ConvertTest.Valid((Half)1.1, ((Half)1.1).ToString());
+
+            yield return ConvertTest.Valid((Half)(-1), "?1", new CustomPositiveSymbolCulture());
+
+            yield return ConvertTest.CantConvertTo((Half)3, typeof(InstanceDescriptor));
+            yield return ConvertTest.CantConvertTo((Half)3, typeof(object));
+        }
+
+        public override IEnumerable<ConvertTest> ConvertFromTestData()
+        {
+            yield return ConvertTest.Valid("1", (Half)1);
+            yield return ConvertTest.Valid(1.1.ToString(), (Half)1.1);
+            yield return ConvertTest.Valid(" -1 ", (Half)(-1));
+            yield return ConvertTest.Valid("+5", (Half)5);
+            yield return ConvertTest.Valid(" +5 ", (Half)5);
+
+            yield return ConvertTest.Throws<ArgumentException, Exception>("#2");
+            yield return ConvertTest.Throws<ArgumentException, Exception>(" #2 ");
+            yield return ConvertTest.Throws<ArgumentException, Exception>("0x3");
+            yield return ConvertTest.Throws<ArgumentException>("0X3");
+            yield return ConvertTest.Throws<ArgumentException>(" 0X3 ");
+            yield return ConvertTest.Throws<ArgumentException>("&h4");
+            yield return ConvertTest.Throws<ArgumentException>("&H4");
+            yield return ConvertTest.Throws<ArgumentException>(" &H4 ");
+
+            foreach (ConvertTest test in base.ConvertFromTestData())
+            {
+                yield return test;
+            }
+        }
+    }
+}
diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Int128ConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Int128ConverterTests.cs
new file mode 100644 (file)
index 0000000..848d0c4
--- /dev/null
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.ComponentModel.Design.Serialization;
+using System.Globalization;
+
+namespace System.ComponentModel.Tests
+{
+    public class Int128ConverterTests : BaseNumberConverterTests
+    {
+        public override TypeConverter Converter => new Int128Converter();
+
+        public override IEnumerable<ConvertTest> ConvertToTestData()
+        {
+            yield return ConvertTest.Valid((Int128)(-1), "-1");
+            yield return ConvertTest.Valid((Int128)(-1), "?1", new CustomPositiveSymbolCulture());
+
+            yield return ConvertTest.CantConvertTo((Int128)3, typeof(InstanceDescriptor));
+            yield return ConvertTest.CantConvertTo((Int128)3, typeof(object));
+        }
+
+        public override IEnumerable<ConvertTest> ConvertFromTestData()
+        {
+            yield return ConvertTest.Valid("1", (Int128)1);
+            yield return ConvertTest.Valid(" -1 ", (Int128)(-1));
+            yield return ConvertTest.Valid("#2", (Int128)2);
+            yield return ConvertTest.Valid(" #2 ", (Int128)2);
+            yield return ConvertTest.Valid("0x3", (Int128)3);
+            yield return ConvertTest.Valid("0X3", (Int128)3);
+            yield return ConvertTest.Valid(" 0X3 ", (Int128)3);
+            yield return ConvertTest.Valid("&h4", (Int128)4);
+            yield return ConvertTest.Valid("&H4", (Int128)4);
+            yield return ConvertTest.Valid(" &H4 ", (Int128)4);
+            yield return ConvertTest.Valid("+5", (Int128)5);
+            yield return ConvertTest.Valid(" +5 ", (Int128)5);
+
+            yield return ConvertTest.Throws<ArgumentException, Exception>("170141183460469231731687303715884105728");
+            yield return ConvertTest.Throws<ArgumentException, Exception>("-170141183460469231731687303715884105729");
+
+            foreach (ConvertTest test in base.ConvertFromTestData())
+            {
+                yield return test;
+            }
+        }
+    }
+}
index 96936f3..b5e7125 100644 (file)
@@ -65,6 +65,7 @@
     <Compile Include="DataObjectMethodAttributeTests.cs" />
     <Compile Include="DataObjectFieldAttributeTests.cs" />
     <Compile Include="DataObjectAttributeTests.cs" />
+    <Compile Include="DateOnlyConverterTests.cs" />
     <Compile Include="DateTimeConverterTests.cs" />
     <Compile Include="DateTimeOffsetConverterTests.cs" />
     <Compile Include="DecimalConverterTests.cs" />
@@ -94,6 +95,7 @@
     <Compile Include="EventDescriptorCollectionTests.cs" />
     <Compile Include="EventDescriptorTests.cs" />
     <Compile Include="GuidConverterTests.cs" />
+    <Compile Include="Int128ConverterTests.cs" />
     <Compile Include="Int16ConverterTests.cs" />
     <Compile Include="Int32ConverterTests.cs" />
     <Compile Include="Int64ConverterTests.cs" />
     <Compile Include="SampleClasses.cs" />
     <Compile Include="SByteConverterTests.cs" />
     <Compile Include="SingleConverterTests.cs" />
+    <Compile Include="HalfConverterTests.cs" />
     <Compile Include="StringConverterTests.cs" />
     <Compile Include="Timers\TimersDescriptionAttributeTests.cs" />
+    <Compile Include="TimeOnlyConverterTests.cs" />
     <Compile Include="TimeSpanConverterTests.cs" />
     <Compile Include="TypeConverterAttributeTests.cs" />
     <Compile Include="TypeConverterTests.cs" />
     <Compile Include="TypeDescriptionProviderAttributeTests.cs" />
     <Compile Include="TypeDescriptorTests.cs" />
     <Compile Include="TypeListConverterTests.cs" />
+    <Compile Include="UInt128ConverterTests.cs" />
     <Compile Include="UInt16ConverterTests.cs" />
     <Compile Include="UInt32ConverterTests.cs" />
     <Compile Include="UInt64ConverterTests.cs" />
diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/TimeOnlyConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/TimeOnlyConverterTests.cs
new file mode 100644 (file)
index 0000000..15cf43e
--- /dev/null
@@ -0,0 +1,79 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.ComponentModel.Design.Serialization;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.DotNet.RemoteExecutor;
+using Xunit;
+
+namespace System.ComponentModel.Tests
+{
+    public class TimeOnlyConverterTests : TypeConverterTestBase
+    {
+        public override TypeConverter Converter => new TimeOnlyConverter();
+
+        public override IEnumerable<ConvertTest> ConvertFromTestData()
+        {
+            TimeOnly timeOnly = new TimeOnly(10, 30, 50);
+            yield return ConvertTest.Valid("", TimeOnly.MinValue);
+
+            yield return ConvertTest.Valid("    ", TimeOnly.MinValue);
+
+            yield return ConvertTest.Valid(timeOnly.ToString(), TimeOnly.Parse(timeOnly.ToString()));
+
+            yield return ConvertTest.Valid(timeOnly.ToString(CultureInfo.InvariantCulture.DateTimeFormat),
+                                            TimeOnly.Parse(timeOnly.ToString(CultureInfo.InvariantCulture.DateTimeFormat)));
+
+            yield return ConvertTest.Valid(" " + timeOnly.ToString(CultureInfo.InvariantCulture.DateTimeFormat) + " ",
+                                            TimeOnly.Parse(timeOnly.ToString(CultureInfo.InvariantCulture.DateTimeFormat)));
+
+            yield return ConvertTest.Throws<FormatException>("invalid");
+
+            yield return ConvertTest.CantConvertFrom(new object());
+            yield return ConvertTest.CantConvertFrom(1);
+        }
+
+        public override IEnumerable<ConvertTest> ConvertToTestData()
+        {
+            CultureInfo polandCulture = new CultureInfo("pl-PL");
+            DateTimeFormatInfo formatInfo = CultureInfo.CurrentCulture.DateTimeFormat;
+            TimeOnly timeOnly = new TimeOnly(10, 30, 50);
+
+            yield return ConvertTest.Valid(timeOnly, timeOnly.ToString(formatInfo.ShortTimePattern));
+
+            yield return ConvertTest.Valid(timeOnly, timeOnly.ToString(polandCulture.DateTimeFormat.ShortTimePattern, polandCulture.DateTimeFormat))
+                .WithRemoteInvokeCulture(polandCulture);
+
+            yield return ConvertTest.Valid(timeOnly, "10:30", CultureInfo.InvariantCulture);
+
+
+            yield return ConvertTest.Valid(TimeOnly.MinValue, string.Empty);
+
+            yield return ConvertTest.Valid(
+                new TimeOnly(),
+                new InstanceDescriptor(typeof(TimeOnly).GetConstructor(new Type[] { typeof(long) }), new object[] { (long)0 })
+            );
+
+            yield return ConvertTest.Valid(
+                timeOnly,
+                new InstanceDescriptor(
+                    typeof(TimeOnly).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }),
+                    new object[] { 10, 30, 50, 0, 0 }
+                )
+            );
+
+            yield return ConvertTest.CantConvertTo(new TimeOnly(), typeof(TimeOnly));
+            yield return ConvertTest.CantConvertTo(new TimeOnly(), typeof(int));
+        }
+
+        [Theory]
+        [InlineData(typeof(InstanceDescriptor))]
+        [InlineData(typeof(int))]
+        public void ConvertTo_InvalidValue_ThrowsNotSupportedException(Type destinationType)
+        {
+            Assert.Throws<NotSupportedException>(() => Converter.ConvertTo(new object(), destinationType));
+        }
+    }
+}
index dca3536..91aad54 100644 (file)
@@ -43,6 +43,11 @@ class Program
             return -1;
         }
 
+        if (!RunTest(targetType: typeof(Int128), expectedConverterType: typeof(Int128Converter)))
+        {
+            return -1;
+        }
+
         if (!RunTest(targetType: typeof(short), expectedConverterType: typeof(Int16Converter)))
         {
             return -1;
@@ -63,6 +68,16 @@ class Program
             return -1;
         }
 
+        if (!RunTest(targetType: typeof(Half), expectedConverterType: typeof(HalfConverter)))
+        {
+            return -1;
+        }
+
+        if (!RunTest(targetType: typeof(UInt128), expectedConverterType: typeof(UInt128Converter)))
+        {
+            return -1;
+        }
+
         if (!RunTest(targetType: typeof(ushort), expectedConverterType: typeof(UInt16Converter)))
         {
             return -1;
@@ -83,6 +98,11 @@ class Program
             return -1;
         }
 
+        if (!RunTest(targetType: typeof(DateOnly), expectedConverterType: typeof(DateOnlyConverter)))
+        {
+            return -1;
+        }
+
         if (!RunTest(targetType: typeof(DateTime), expectedConverterType: typeof(DateTimeConverter)))
         {
             return -1;
@@ -98,6 +118,11 @@ class Program
             return -1;
         }
 
+        if (!RunTest(targetType: typeof(TimeOnly), expectedConverterType: typeof(TimeOnlyConverter)))
+        {
+            return -1;
+        }
+
         if (!RunTest(targetType: typeof(TimeSpan), expectedConverterType: typeof(TimeSpanConverter)))
         {
             return -1;
index b192fbc..0d7e195 100644 (file)
@@ -93,6 +93,74 @@ namespace System.ComponentModel.Tests
         }
 
         [Fact]
+        public static void ConvertFrom_DateOnlyInstanceDescriptor()
+        {
+            using (new ThreadCultureChange("fr-FR"))
+            {
+                DateOnly testDateOnly = DateOnly.FromDateTime(DateTime.UtcNow);
+                ConstructorInfo ctor = typeof(DateOnly).GetConstructor(new Type[]
+                {
+                    typeof(int), typeof(int), typeof(int)
+                });
+
+                InstanceDescriptor descriptor = new InstanceDescriptor(ctor, new object[]
+                {
+                    testDateOnly.Year, testDateOnly.Month, testDateOnly.Day
+                });
+
+                const string format = "dd MMM yyyy";
+                object o = s_converter.ConvertFrom(descriptor);
+                Assert.Equal(testDateOnly.ToString(format), ((DateOnly)o).ToString(format));
+            }
+        }
+
+        [Fact]
+        public static void ConvertFrom_TimeOnlyInstanceDescriptor()
+        {
+            using (new ThreadCultureChange("fr-FR"))
+            {
+                TimeOnly testTimeOnly = TimeOnly.FromDateTime(DateTime.UtcNow);
+                ConstructorInfo ctor = typeof(TimeOnly).GetConstructor(new Type[]
+                {
+                    typeof(int), typeof(int), typeof(int), typeof(int), typeof(int)
+                });
+
+                InstanceDescriptor descriptor = new InstanceDescriptor(ctor, new object[]
+                {
+                    testTimeOnly.Hour, testTimeOnly.Minute, testTimeOnly.Second, testTimeOnly.Millisecond, testTimeOnly.Microsecond
+                });
+
+                const string format = "HH mm ss fff tt";
+                object o = s_converter.ConvertFrom(descriptor);
+                Assert.Equal(testTimeOnly.ToString(format), ((TimeOnly)o).ToString(format));
+            }
+        }
+
+        [Fact]
+        public static void TestConverters()
+        {
+            TypeConverter dateOnlyConverter = TypeDescriptor.GetConverter(typeof(DateOnly));
+            DateOnly? date = dateOnlyConverter.ConvertFromString("1940-10-09") as DateOnly?;
+            Assert.Equal(new DateOnly(1940, 10, 9), date);
+
+            TypeConverter timeOnlyConverter = TypeDescriptor.GetConverter(typeof(TimeOnly));
+            TimeOnly? time = timeOnlyConverter.ConvertFromString("20:30:50") as TimeOnly?;
+            Assert.Equal(new TimeOnly(20, 30, 50), time);
+
+            TypeConverter halfConverter = TypeDescriptor.GetConverter(typeof(Half));
+            Half? half = halfConverter.ConvertFromString(((Half)(-1.2)).ToString()) as Half?;
+            Assert.Equal((Half)(-1.2), half);
+
+            TypeConverter Int128Converter = TypeDescriptor.GetConverter(typeof(Int128));
+            Int128? int128 = Int128Converter.ConvertFromString("170141183460469231731687303715884105727") as Int128?;
+            Assert.Equal(Int128.MaxValue, int128);
+
+            TypeConverter UInt128Converter = TypeDescriptor.GetConverter(typeof(UInt128));
+            UInt128? uint128 = UInt128Converter.ConvertFromString("340282366920938463463374607431768211455") as UInt128?;
+            Assert.Equal(UInt128.MaxValue, uint128);
+        }
+
+        [Fact]
         public static void ConvertFromString_WithContext()
         {
             Assert.Throws<NotSupportedException>(
index c148582..37c6f5b 100644 (file)
@@ -13,7 +13,7 @@ namespace System.ComponentModel.Tests
     [Collection(nameof(DisableParallelization))] // manipulates cache
     public class TypeDescriptorTests
     {
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProvider_InvokeObject_GetProviderReturnsExpected()
         {
             var instance = new object();
@@ -47,7 +47,7 @@ namespace System.ComponentModel.Tests
             mockProvider2.Verify(p => p.IsSupportedType(typeof(int)), Times.Once());
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProvider_InvokeObjectMultipleTimes_Refreshes()
         {
             var instance = new object();
@@ -61,7 +61,7 @@ namespace System.ComponentModel.Tests
                 .Setup(p => p.GetCache(instance))
                 .Returns(new Dictionary<int, string>())
                 .Verifiable();
-            
+
             int callCount = 0;
             RefreshEventHandler handler = (e) =>
             {
@@ -96,7 +96,7 @@ namespace System.ComponentModel.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProvider_InvokeType_GetProviderReturnsExpected()
         {
             Type type = typeof(AddProvider_InvokeType_GetProviderReturnsExpectedType);
@@ -133,7 +133,7 @@ namespace System.ComponentModel.Tests
         private class AddProvider_InvokeType_GetProviderReturnsExpectedType { }
 
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProvider_InvokeTypeMultipleTimes_Refreshes()
         {
             var type = typeof(AddProvider_InvokeTypeMultipleTimes_RefreshesType);
@@ -147,7 +147,7 @@ namespace System.ComponentModel.Tests
                 .Setup(p => p.GetCache(type))
                 .Returns(new Dictionary<int, string>())
                 .Verifiable();
-            
+
             int callCount = 0;
             RefreshEventHandler handler = (e) =>
             {
@@ -184,28 +184,28 @@ namespace System.ComponentModel.Tests
 
         private class AddProvider_InvokeTypeMultipleTimes_RefreshesType { }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProvider_NullProvider_ThrowsArgumentNullException()
         {
             Assert.Throws<ArgumentNullException>("provider", () => TypeDescriptor.AddProvider(null, new object()));
             Assert.Throws<ArgumentNullException>("provider", () => TypeDescriptor.AddProvider(null, typeof(int)));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProvider_NullInstance_ThrowsArgumentNullException()
         {
             var mockProvider = new Mock<TypeDescriptionProvider>(MockBehavior.Strict);
             Assert.Throws<ArgumentNullException>("instance", () => TypeDescriptor.AddProvider(mockProvider.Object, (object)null));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProvider_NullType_ThrowsArgumentNullException()
         {
             var mockProvider = new Mock<TypeDescriptionProvider>(MockBehavior.Strict);
             Assert.Throws<ArgumentNullException>("type", () => TypeDescriptor.AddProvider(mockProvider.Object, null));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProviderTransparent_InvokeObject_GetProviderReturnsExpected()
         {
             var instance = new object();
@@ -239,7 +239,7 @@ namespace System.ComponentModel.Tests
             mockProvider2.Verify(p => p.IsSupportedType(typeof(int)), Times.Once());
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProviderTransparent_InvokeObjectMultipleTimes_Refreshes()
         {
             var instance = new object();
@@ -253,7 +253,7 @@ namespace System.ComponentModel.Tests
                 .Setup(p => p.GetCache(instance))
                 .Returns(new Dictionary<int, string>())
                 .Verifiable();
-            
+
             int callCount = 0;
             RefreshEventHandler handler = (e) =>
             {
@@ -288,7 +288,7 @@ namespace System.ComponentModel.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProviderTransparent_InvokeType_GetProviderReturnsExpected()
         {
             Type type = typeof(AddProviderTransparent_InvokeType_GetProviderReturnsExpectedType);
@@ -324,7 +324,7 @@ namespace System.ComponentModel.Tests
 
         private class AddProviderTransparent_InvokeType_GetProviderReturnsExpectedType { }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProviderTransparent_InvokeTypeMultipleTimes_Refreshes()
         {
             var type = typeof(AddProviderTransparent_InvokeTypeMultipleTimes_RefreshesType);
@@ -338,7 +338,7 @@ namespace System.ComponentModel.Tests
                 .Setup(p => p.GetCache(type))
                 .Returns(new Dictionary<int, string>())
                 .Verifiable();
-            
+
             int callCount = 0;
             RefreshEventHandler handler = (e) =>
             {
@@ -375,21 +375,21 @@ namespace System.ComponentModel.Tests
 
         private class AddProviderTransparent_InvokeTypeMultipleTimes_RefreshesType { }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProviderTransparent_NullProvider_ThrowsArgumentNullException()
         {
             Assert.Throws<ArgumentNullException>("provider", () => TypeDescriptor.AddProviderTransparent(null, new object()));
             Assert.Throws<ArgumentNullException>("provider", () => TypeDescriptor.AddProviderTransparent(null, typeof(int)));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProviderTransparent_NullInstance_ThrowsArgumentNullException()
         {
             var mockProvider = new Mock<TypeDescriptionProvider>(MockBehavior.Strict);
             Assert.Throws<ArgumentNullException>("instance", () => TypeDescriptor.AddProviderTransparent(mockProvider.Object, (object)null));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void AddProviderTransparent_NullType_ThrowsArgumentNullException()
         {
             var mockProvider = new Mock<TypeDescriptionProvider>(MockBehavior.Strict);
@@ -455,18 +455,23 @@ namespace System.ComponentModel.Tests
         [InlineData(typeof(char), typeof(CharConverter))]
         [InlineData(typeof(double), typeof(DoubleConverter))]
         [InlineData(typeof(string), typeof(StringConverter))]
+        [InlineData(typeof(Int128), typeof(Int128Converter))]
         [InlineData(typeof(short), typeof(Int16Converter))]
         [InlineData(typeof(int), typeof(Int32Converter))]
         [InlineData(typeof(long), typeof(Int64Converter))]
         [InlineData(typeof(float), typeof(SingleConverter))]
+        [InlineData(typeof(Half), typeof(HalfConverter))]
+        [InlineData(typeof(UInt128), typeof(UInt128Converter))]
         [InlineData(typeof(ushort), typeof(UInt16Converter))]
         [InlineData(typeof(uint), typeof(UInt32Converter))]
         [InlineData(typeof(ulong), typeof(UInt64Converter))]
         [InlineData(typeof(object), typeof(TypeConverter))]
         [InlineData(typeof(void), typeof(TypeConverter))]
+        [InlineData(typeof(DateOnly), typeof(DateOnlyConverter))]
         [InlineData(typeof(DateTime), typeof(DateTimeConverter))]
         [InlineData(typeof(DateTimeOffset), typeof(DateTimeOffsetConverter))]
         [InlineData(typeof(decimal), typeof(DecimalConverter))]
+        [InlineData(typeof(TimeOnly), typeof(TimeOnlyConverter))]
         [InlineData(typeof(TimeSpan), typeof(TimeSpanConverter))]
         [InlineData(typeof(Guid), typeof(GuidConverter))]
         [InlineData(typeof(Array), typeof(ArrayConverter))]
@@ -543,7 +548,7 @@ namespace System.ComponentModel.Tests
             Assert.Equal(1, properties.Count);
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProvider_InvokeObject_RemovesProvider()
         {
             var instance = new object();
@@ -598,7 +603,7 @@ namespace System.ComponentModel.Tests
             mockProvider3.Verify(p => p.IsSupportedType(typeof(int)), Times.Once());
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProvider_InvokeObjectWithProviders_Refreshes()
         {
             var instance = new object();
@@ -635,7 +640,7 @@ namespace System.ComponentModel.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProvider_InvokeObjectWithoutProviders_Refreshes()
         {
             var instance = new object();
@@ -660,7 +665,7 @@ namespace System.ComponentModel.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProvider_InvokeType_RemovesProvider()
         {
             Type type = typeof(RemoveProvider_InvokeType_RemovesProviderType);
@@ -717,7 +722,7 @@ namespace System.ComponentModel.Tests
 
         private class RemoveProvider_InvokeType_RemovesProviderType { }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProvider_InvokeTypeWithProviders_Refreshes()
         {
             Type type = typeof(RemoveProvider_InvokeObjectWithProviders_RefreshesType);
@@ -756,7 +761,7 @@ namespace System.ComponentModel.Tests
 
         private class RemoveProvider_InvokeObjectWithProviders_RefreshesType { }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProvider_InvokeTypeWithoutProviders_Refreshes()
         {
             Type type = typeof(RemoveProvider_InvokeTypeWithoutProviders_RefreshesType);
@@ -790,14 +795,14 @@ namespace System.ComponentModel.Tests
             Assert.Throws<ArgumentNullException>("provider", () => TypeDescriptor.RemoveProvider(null, typeof(int)));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProvider_NullInstance_ThrowsArgumentNullException()
         {
             var mockProvider = new Mock<TypeDescriptionProvider>(MockBehavior.Strict);
             Assert.Throws<ArgumentNullException>("instance", () => TypeDescriptor.RemoveProvider(mockProvider.Object, (object)null));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProvider_NullType_ThrowsArgumentNullException()
         {
             var mockProvider = new Mock<TypeDescriptionProvider>(MockBehavior.Strict);
@@ -805,7 +810,7 @@ namespace System.ComponentModel.Tests
         }
 
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProviderTransparent_InvokeObject_RemovesProvider()
         {
             var instance = new object();
@@ -860,7 +865,7 @@ namespace System.ComponentModel.Tests
             mockProvider3.Verify(p => p.IsSupportedType(typeof(int)), Times.Once());
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProviderTransparent_InvokeObjectWithProviders_Refreshes()
         {
             var instance = new object();
@@ -897,7 +902,7 @@ namespace System.ComponentModel.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProviderTransparent_InvokeObjectWithoutProviders_Refreshes()
         {
             var instance = new object();
@@ -922,7 +927,7 @@ namespace System.ComponentModel.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProviderTransparent_InvokeType_RemovesProvider()
         {
             Type type = typeof(RemoveProviderTransparent_InvokeType_RemovesProviderType);
@@ -979,7 +984,7 @@ namespace System.ComponentModel.Tests
 
         private class RemoveProviderTransparent_InvokeType_RemovesProviderType { }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProviderTransparent_InvokeTypeWithProviders_Refreshes()
         {
             Type type = typeof(RemoveProviderTransparent_InvokeObjectWithProviders_RefreshesType);
@@ -1018,7 +1023,7 @@ namespace System.ComponentModel.Tests
 
         private class RemoveProviderTransparent_InvokeObjectWithProviders_RefreshesType { }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProviderTransparent_InvokeTypeWithoutProviders_Refreshes()
         {
             Type type = typeof(RemoveProviderTransparent_InvokeTypeWithoutProviders_RefreshesType);
@@ -1052,14 +1057,14 @@ namespace System.ComponentModel.Tests
             Assert.Throws<ArgumentNullException>("provider", () => TypeDescriptor.RemoveProviderTransparent(null, typeof(int)));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProviderTransparent_NullInstance_ThrowsArgumentNullException()
         {
             var mockProvider = new Mock<TypeDescriptionProvider>(MockBehavior.Strict);
             Assert.Throws<ArgumentNullException>("instance", () => TypeDescriptor.RemoveProviderTransparent(mockProvider.Object, (object)null));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void RemoveProviderTransparent_NullType_ThrowsArgumentNullException()
         {
             var mockProvider = new Mock<TypeDescriptionProvider>(MockBehavior.Strict);
@@ -1106,7 +1111,7 @@ namespace System.ComponentModel.Tests
             Assert.NotEqual(firstAssociatedObject, firstAssociation);
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT 
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoAOT))] // Mock will try to JIT
         public void SortDescriptorArray_Invoke_ReturnsExpected()
         {
             var notADescriptor1 = new object();
diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/UInt128ConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/UInt128ConverterTests.cs
new file mode 100644 (file)
index 0000000..1b8bef9
--- /dev/null
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using System.ComponentModel.Design.Serialization;
+using System.Globalization;
+
+namespace System.ComponentModel.Tests
+{
+    public class UInt128ConverterTests : BaseNumberConverterTests
+    {
+        public override TypeConverter Converter => new UInt128Converter();
+
+        public override IEnumerable<ConvertTest> ConvertToTestData()
+        {
+            yield return ConvertTest.Valid((UInt128)1, "1");
+
+            yield return ConvertTest.CantConvertTo((UInt128)3, typeof(InstanceDescriptor));
+            yield return ConvertTest.CantConvertTo((UInt128)3, typeof(object));
+        }
+
+        public override IEnumerable<ConvertTest> ConvertFromTestData()
+        {
+            yield return ConvertTest.Valid("1", (UInt128)1);
+            yield return ConvertTest.Valid("#2", (UInt128)2);
+            yield return ConvertTest.Valid(" #2 ", (UInt128)2);
+            yield return ConvertTest.Valid("0x3", (UInt128)3);
+            yield return ConvertTest.Valid("0X3", (UInt128)3);
+            yield return ConvertTest.Valid(" 0X3 ", (UInt128)3);
+            yield return ConvertTest.Valid("&h4", (UInt128)4);
+            yield return ConvertTest.Valid("&H4", (UInt128)4);
+            yield return ConvertTest.Valid(" &H4 ", (UInt128)4);
+            yield return ConvertTest.Valid("+5", (UInt128)5);
+            yield return ConvertTest.Valid(" +5 ", (UInt128)5);
+
+            yield return ConvertTest.Valid("!1", (UInt128)1, new CustomPositiveSymbolCulture());
+
+            yield return ConvertTest.Throws<ArgumentException, Exception>("-1");
+            yield return ConvertTest.Throws<ArgumentException, Exception>("340282366920938463463374607431768211456");
+
+            foreach (ConvertTest test in base.ConvertFromTestData())
+            {
+                yield return test;
+            }
+        }
+    }
+}