Move CultureInfoConverter to the new test base and fix NRE (dotnet/corefx#38980)
authorHugh Bellamy <hughbellars@gmail.com>
Wed, 3 Jul 2019 15:38:51 +0000 (16:38 +0100)
committerMaryam Ariyan <maryam.ariyan@microsoft.com>
Wed, 3 Jul 2019 15:38:51 +0000 (08:38 -0700)
Commit migrated from https://github.com/dotnet/corefx/commit/a9594f72540034902e2bcb2a5187fcdba584cf36

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CultureInfoConverter.cs
src/libraries/System.ComponentModel.TypeConverter/tests/CultureInfoConverterTests.cs

index 7e4f5a7..7d55acb 100644 (file)
@@ -23,12 +23,21 @@ namespace System.ComponentModel
         /// Retrieves the "default" name for our culture.
         /// </summary>
         private string DefaultCultureString => SR.CultureInfoConverterDefaultCultureString;
-        const string DefaultInvariantCultureString = "(Default)";
+
+        private const string DefaultInvariantCultureString = "(Default)";
 
         /// <summary>
         /// Retrieves the Name for a input CultureInfo.
         /// </summary>
-        protected virtual string GetCultureName(CultureInfo culture) => culture.Name;
+        protected virtual string GetCultureName(CultureInfo culture)
+        {
+            if (culture == null)
+            {
+                throw new ArgumentNullException(nameof(culture));
+            }
+
+            return culture.Name;
+        }
 
         /// <summary>
         /// Gets a value indicating whether this converter can convert an object in the given
@@ -36,10 +45,6 @@ namespace System.ComponentModel
         /// </summary>
         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
         {
-            if (sourceType == typeof(string))
-            {
-                return true;
-            }
             return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
         }
 
@@ -63,11 +68,10 @@ namespace System.ComponentModel
             // Otherwise, we just keep the value unchanged.
             if (value is string text)
             {
-                if (GetCultureName(CultureInfo.InvariantCulture).Equals(""))
+                if (GetCultureName(CultureInfo.InvariantCulture).Equals(string.Empty))
                 {
                     text = CultureInfoMapper.GetCultureInfoName((string)value);
                 }
-                CultureInfo retVal = null;
 
                 string defaultCultureString = DefaultCultureString;
                 if (culture != null && culture.Equals(CultureInfo.InvariantCulture))
@@ -76,6 +80,7 @@ namespace System.ComponentModel
                 }
 
                 // Look for the default culture info.
+                CultureInfo retVal = null;
                 if (string.IsNullOrEmpty(text) || string.Equals(text, defaultCultureString, StringComparison.Ordinal))
                 {
                     retVal = CultureInfo.InvariantCulture;
@@ -101,29 +106,30 @@ namespace System.ComponentModel
                     {
                         retVal = new CultureInfo(text);
                     }
-                    catch { }
+                    catch
+                    {
+                    }
                 }
 
                 // Finally, try to find a partial match.
                 if (retVal == null)
                 {
-                    text = text.ToLower(CultureInfo.CurrentCulture);
                     foreach (CultureInfo info in _values)
                     {
-                        if (info != null && GetCultureName(info).ToLower(CultureInfo.CurrentCulture).StartsWith(text))
+                        if (info != null && GetCultureName(info).StartsWith(text, StringComparison.CurrentCulture))
                         {
                             retVal = info;
                             break;
                         }
                     }
-
                 }
 
                 // No good. We can't support it.
                 if (retVal == null)
                 {
-                    throw new ArgumentException(SR.Format(SR.CultureInfoConverterInvalidCulture, (string)value));
+                    throw new ArgumentException(SR.Format(SR.CultureInfoConverterInvalidCulture, (string)value), nameof(value));
                 }
+
                 return retVal;
             }
 
@@ -135,14 +141,8 @@ namespace System.ComponentModel
         /// </summary>
         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
         {
-            if (destinationType == null)
-            {
-                throw new ArgumentNullException(nameof(destinationType));
-            }
-
             if (destinationType == typeof(string))
             {
-                string retVal;
                 string defaultCultureString = DefaultCultureString;
                 if (culture != null && culture.Equals(CultureInfo.InvariantCulture))
                 {
@@ -151,23 +151,19 @@ namespace System.ComponentModel
 
                 if (value == null || value == CultureInfo.InvariantCulture)
                 {
-                    retVal = defaultCultureString;
+                    return defaultCultureString;
                 }
-                else
+                if (value is CultureInfo c)
                 {
-                    retVal = GetCultureName(((CultureInfo)value));
+                    return GetCultureName(c);
                 }
-
-                return retVal;
             }
-            if (destinationType == typeof(InstanceDescriptor) && value is CultureInfo)
+            if (destinationType == typeof(InstanceDescriptor) && value is CultureInfo cultureValue)
             {
-                CultureInfo c = (CultureInfo)value;
-                ConstructorInfo ctor = typeof(CultureInfo).GetConstructor(new Type[] { typeof(string) });
-                if (ctor != null)
-                {
-                    return new InstanceDescriptor(ctor, new object[] { c.Name });
-                }
+                return new InstanceDescriptor(
+                    typeof(CultureInfo).GetConstructor(new Type[] { typeof(string) }),
+                    new object[] { cultureValue.Name }
+                );
             }
 
             return base.ConvertTo(context, culture, value, destinationType);
@@ -273,10 +269,11 @@ namespace System.ComponentModel
             /// This is to workaround an issue with CultureInfoConverter that serializes DisplayName (fixing it would introduce breaking changes).
             private static readonly Dictionary<string, string> s_cultureInfoNameMap = CreateMap();
 
-            private static Dictionary<string,string> CreateMap()
+            private static Dictionary<string, string> CreateMap()
             {
                 const int Count = 274;
-                var result = new Dictionary<string, string>(Count) {
+                var result = new Dictionary<string, string>(Count)
+                {
                     {"Afrikaans", "af"},
                     {"Afrikaans (South Africa)", "af-ZA"},
                     {"Albanian", "sq"},
@@ -566,4 +563,3 @@ namespace System.ComponentModel
         }
     }
 }
-
index 2f0fce1..13f05b8 100644 (file)
 // Licensed to the .NET Foundation under one or more agreements.
 // See the LICENSE file in the project root for more information. 
 
-//
-// System.ComponentModel.CultureInfoConverter test cases
-//
-// Authors:
-//     Gert Driesen (drieseng@users.sourceforge.net)
-//
-// (c) 2008 Gert Driesen
-//
-
+using System.Collections.Generic;
 using System.ComponentModel.Design.Serialization;
-using System.Diagnostics;
 using System.Globalization;
-using System.Runtime.InteropServices;
-using Microsoft.DotNet.RemoteExecutor;
+using System.Linq;
+using System.Reflection;
 using Xunit;
 
 namespace System.ComponentModel.Tests
 {
-    public class CultureInfoConverterTest
+    public class CultureInfoConverterTests : TypeConverterTestBase
     {
-        private CultureInfoConverter converter => new CultureInfoConverter();
+        public override TypeConverter Converter => new CultureInfoConverter();
 
-        [Fact]
-        public void CanConvertFrom()
+        public override bool StandardValuesSupported => true;
+
+        public override IEnumerable<ConvertTest> ConvertFromTestData()
         {
-            Assert.True(converter.CanConvertFrom(typeof(string)));
-            Assert.False(converter.CanConvertFrom(typeof(CultureInfo)));
-            Assert.False(converter.CanConvertFrom(typeof(object)));
-            Assert.False(converter.CanConvertFrom(typeof(int)));
+            yield return ConvertTest.Valid(string.Empty, CultureInfo.InvariantCulture, CultureInfo.InvariantCulture);
+            yield return ConvertTest.Valid("nl-BE", new CultureInfo("nl-BE"), CultureInfo.InvariantCulture);
+            yield return ConvertTest.Valid("(Default)", CultureInfo.InvariantCulture, CultureInfo.InvariantCulture);
+            CultureInfo culture = null;
+            try
+            {
+                culture = new CultureInfo("nl--B");
+            }
+            catch { }
+
+            if (culture != null)
+            {
+                yield return ConvertTest.Valid("nl-B", new CultureInfo("nl--B"), CultureInfo.InvariantCulture);
+                yield return ConvertTest.Valid("nl-B", new CultureInfo("nl--B"), new CultureInfo("en-US"));
+            }
+
+            yield return ConvertTest.Valid("Afrikaans", new CultureInfo("af"));
+
+            yield return ConvertTest.CantConvertFrom(CultureInfo.CurrentCulture);
+            yield return ConvertTest.CantConvertFrom(1);
+            yield return ConvertTest.CantConvertFrom(new object());
         }
 
-        [Fact]
-        public void CanConvertTo()
+        public override IEnumerable<ConvertTest> ConvertToTestData()
         {
-            Assert.True(converter.CanConvertTo(typeof(string)));
-            Assert.False(converter.CanConvertTo(typeof(object)));
-            Assert.False(converter.CanConvertTo(typeof(CultureInfo)));
-            Assert.False(converter.CanConvertTo(typeof(int)));
-            Assert.True(converter.CanConvertTo(typeof(InstanceDescriptor)));
+            yield return ConvertTest.Valid(new CustomCultureInfo(), "nl-BE");
+            yield return ConvertTest.Valid(null, "(Default)");
+            yield return ConvertTest.Valid(CultureInfo.InvariantCulture, "(Default)");
+            yield return ConvertTest.Valid(CultureInfo.InvariantCulture, "(Default)", CultureInfo.InvariantCulture);
+            yield return ConvertTest.Valid(new CultureInfo("nl-BE"), "nl-BE");
+            yield return ConvertTest.Valid(1, "1");
+
+            yield return ConvertTest.CantConvertTo(CultureInfo.InvariantCulture, typeof(object));
+            yield return ConvertTest.CantConvertTo(CultureInfo.InvariantCulture, typeof(CultureInfo));
+            yield return ConvertTest.CantConvertTo(CultureInfo.InvariantCulture, typeof(int));
         }
 
-        [Fact]
-        public void ConvertFrom_String()
+        [Theory]
+        [InlineData("Dutch (Bel")]
+        [InlineData("(default)")]
+        [InlineData(" ")]
+        [InlineData("\r\n")]
+        public void ConvertFrom_String_InvalidCulture(string cultureName)
         {
-            CultureInfo c;
-
-            c = (CultureInfo)converter.ConvertFrom(null, CultureInfo.InvariantCulture,
-                string.Empty);
-            Assert.Equal(CultureInfo.InvariantCulture, c);
-
-            c = (CultureInfo)converter.ConvertFrom(null, CultureInfo.InvariantCulture,
-                "nl-BE");
-            Assert.Equal(new CultureInfo("nl-BE"), c);
-
             try
             {
-                // Linux can create such cultures
-                var cul = new CultureInfo("Dutch (Bel");
+                // Linux may be able to create these cultures.
+                new CultureInfo(cultureName);
             }
             catch (CultureNotFoundException)
             {
-                // if we cannot create the cultures we should get exception from the Converter too
-                AssertExtensions.Throws<ArgumentException>(null, () => c = (CultureInfo)converter.ConvertFrom(null, CultureInfo.InvariantCulture, "Dutch (Bel"));
-                AssertExtensions.Throws<ArgumentException>(null, () => c = (CultureInfo)converter.ConvertFrom(null, CultureInfo.InvariantCulture, "duTcH (Bel"));
+                // If we cannot create the cultures we should get exception from the Converter too.
+                AssertExtensions.Throws<ArgumentException>("value", () => Converter.ConvertFrom(null, CultureInfo.InvariantCulture, cultureName));
             }
-
-            c = (CultureInfo)converter.ConvertFrom(null, CultureInfo.InvariantCulture, "(Default)");
-            Assert.Equal(CultureInfo.InvariantCulture, c);
         }
 
         [Fact]
-        public void ConvertFrom_String_IncompleteName()
+        public void ConvertTo_InstanceDescriptor_ReturnsExpected()
         {
-            converter.ConvertFrom(null, CultureInfo.InvariantCulture,
-                "nl-B");
+            var culture = new CultureInfo("en-US");
+            Assert.True(Converter.CanConvertTo(typeof(InstanceDescriptor)));
+
+            InstanceDescriptor instanceDescriptor = Assert.IsType<InstanceDescriptor>(Converter.ConvertTo(culture, typeof(InstanceDescriptor)));
+            Assert.Equal(new Type[] { typeof(string) }, Assert.IsAssignableFrom<ConstructorInfo>(instanceDescriptor.MemberInfo).GetParameters().Select(p => p.ParameterType));
+            Assert.Equal(new object[] { culture.Name }, instanceDescriptor.Arguments);
         }
 
-        [Fact]
-        public void ConvertFrom_String_InvalidCulture()
+        [Theory]
+        [InlineData(typeof(InstanceDescriptor))]
+        [InlineData(typeof(int))]
+        public void ConvertTo_InvalidValue_ThrowsNotSupportedException(Type destinationType)
         {
-            ArgumentException ex;
+            Assert.Throws<NotSupportedException>(() => Converter.ConvertTo(new object(), destinationType));
+        }
 
-            try
-            {
-                // Linux can create such cultures
-                var cul = new CultureInfo("(default)");
-            }
-            catch (CultureNotFoundException)
-            {
-                // if we cannot create the cultures we should get exception from the Converter too
-                ex = AssertExtensions.Throws<ArgumentException>(null, () => converter.ConvertFrom(null, CultureInfo.InvariantCulture, "(default)"));
-                // The (default) culture cannot be converted to
-                // a CultureInfo object on this computer
-                Assert.Equal(typeof(ArgumentException), ex.GetType());
-                Assert.Null(ex.InnerException);
-                Assert.NotNull(ex.Message);
-                Assert.True(ex.Message.IndexOf(typeof(CultureInfo).Name) != -1);
-                Assert.True(ex.Message.IndexOf("(default)") != -1);
-                Assert.Null(ex.ParamName);
-            }
+        [Theory]
+        [InlineData(typeof(InstanceDescriptor))]
+        [InlineData(typeof(int))]
+        public void ConvertTo_InstanceAndNullCulture_ThrowsNotSupportedException(Type destinationType)
+        {
+            Assert.Throws<NotSupportedException>(() => Converter.ConvertTo(null, destinationType));
+        }
 
-            try
-            {
-                // Linux can create such cultures
-                var cul = new CultureInfo(" ");
-            }
-            catch (CultureNotFoundException)
-            {
-                ex = AssertExtensions.Throws<ArgumentException>(null, () => converter.ConvertFrom(null, CultureInfo.InvariantCulture, " "));
-                // The   culture cannot be converted to
-                // a CultureInfo object on this computer
-                Assert.Equal(typeof(ArgumentException), ex.GetType());
-                Assert.Null(ex.InnerException);
-                Assert.NotNull(ex.Message);
-                Assert.True(ex.Message.IndexOf(typeof(CultureInfo).Name) != -1);
-                Assert.True(ex.Message.IndexOf("   ") != -1);
-                Assert.Null(ex.ParamName);
-            }
+        public static IEnumerable<object[]> GetCultureName_TestData()
+        {
+            yield return new object[] { new CultureInfo("fr-FR"), new CultureInfo("fr-FR").Name };
+            yield return new object[] { new CultureInfo("es-MX"), new CultureInfo("es-MX").Name };
+        }
 
-            try
-            {
-                // Linux can create such cultures
-                var cul = new CultureInfo("\r\n");
-            }
-            catch (CultureNotFoundException)
-            {
-                ex = AssertExtensions.Throws<ArgumentException>(null, () => converter.ConvertFrom(null, CultureInfo.InvariantCulture, "\r\n"));
-                // The \r\n culture cannot be converted to
-                // a CultureInfo object on this computer
-                Assert.Equal(typeof(ArgumentException), ex.GetType());
-                Assert.Null(ex.InnerException);
-                Assert.NotNull(ex.Message);
-                Assert.True(ex.Message.IndexOf(typeof(CultureInfo).Name) != -1);
-                Assert.True(ex.Message.IndexOf("\r\n") != -1);
-                Assert.Null(ex.ParamName);
-            }
+        [Theory]
+        [MemberData(nameof(GetCultureName_TestData))]
+        public void GetCultureName_Invoke_ReturnsExpected(CultureInfo culture, string expected)
+        {
+            var converter = new SubCultureInfoConverter();
+            Assert.Equal(expected, converter.GetCultureName(culture));
         }
 
         [Fact]
-        public void ConvertFrom_Value_Null()
+        public void GetCultureName_NullCulture_ThrowsArgumentNullException()
         {
-            RemoteExecutor.Invoke(() =>
-            {
-                CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture;
-
-                NotSupportedException ex = Assert.Throws<NotSupportedException>(() => converter.ConvertFrom(null, CultureInfo.InvariantCulture, (string)null));
-                // CultureInfoConverter cannot convert from (null)
-                Assert.Equal(typeof(NotSupportedException), ex.GetType());
-                Assert.Null(ex.InnerException);
-                Assert.NotNull(ex.Message);
-                Assert.True(ex.Message.IndexOf(typeof(CultureInfoConverter).Name) != -1);
-                Assert.True(ex.Message.IndexOf("(null)") != -1);
-            }).Dispose();
+            var converter = new SubCultureInfoConverter();
+            Assert.Throws<ArgumentNullException>("culture", () => converter.GetCultureName(null));
         }
 
-        [Fact]
-        public void ConvertToString()
+        public static IEnumerable<object[]> ConvertFrom_OverridenGetCultureName_TestData()
         {
-            Assert.Equal("nl-BE", converter.ConvertToString(null, CultureInfo.InvariantCulture, new MyCultureInfo()));
-            Assert.Equal("(Default)", converter.ConvertToString(null, CultureInfo.InvariantCulture, null));
-            Assert.Equal("(Default)", converter.ConvertToString(null, CultureInfo.InvariantCulture, CultureInfo.InvariantCulture));
-            Assert.Equal("nl-BE", converter.ConvertToString(null, CultureInfo.InvariantCulture, new CultureInfo("nl-BE")));
+            yield return new object[] { "Fixed", "Fixed", CultureInfo.InvariantCulture };
+            yield return new object[] { "None", "en-US", new CultureInfo("en-US") };
         }
 
-        [Serializable]
-        private sealed class MyCultureInfo : CultureInfo
+        [Theory]
+        [MemberData(nameof(ConvertFrom_OverridenGetCultureName_TestData))]
+        public void ConvertFrom_OverridenGetCultureName_ReturnsExpected(string fixedValue, string text, CultureInfo expected)
         {
-            internal MyCultureInfo() : base("nl-BE")
+            var converter = new FixedCultureInfoConverter
             {
-            }
+                FixedValue = fixedValue
+            };
+            Assert.Equal(expected, converter.ConvertFromString(text));
+        }
 
-            public override string DisplayName
+        [Fact]
+        public void GetCultureName_Overriden_ConversionsReturnsExpected()
+        {
+            var converter = new FixedCultureInfoConverter
             {
-                get { return "display"; }
-            }
+                FixedValue = "Fixed"
+            };
+            Assert.Equal("(Default)", converter.ConvertTo(CultureInfo.InvariantCulture, typeof(string)));
+            Assert.Equal("Fixed", converter.ConvertTo(new CultureInfo("en-US"), typeof(string)));
+        }
 
-            public override string EnglishName
+        private class SubCultureInfoConverter : CultureInfoConverter
+        {
+            public new string GetCultureName(CultureInfo culture)
             {
-                get { return "english"; }
+                return base.GetCultureName(culture);
             }
         }
 
-        [Fact]
-        public void GetCultureName()
+        private class FixedCultureInfoConverter : CultureInfoConverter
         {
-            CustomCultureInfoConverter custom_converter = new CustomCultureInfoConverter();
-
-            CultureInfo fr_culture = CultureInfo.GetCultureInfo("fr-FR");
-            Assert.Equal(fr_culture.Name, custom_converter.GetCultureName(fr_culture));
+            public string FixedValue { get; set; }
 
-            CultureInfo es_culture = CultureInfo.GetCultureInfo("es-MX");
-            Assert.Equal(es_culture.Name, custom_converter.GetCultureName(es_culture));
+            protected override string GetCultureName(CultureInfo culture) => FixedValue;
         }
 
-        private class CustomCultureInfoConverter : CultureInfoConverter
+        [Serializable]
+        private sealed class CustomCultureInfo : CultureInfo
         {
-            public new string GetCultureName(CultureInfo culture)
+            public CustomCultureInfo() : base("nl-BE")
             {
-                return base.GetCultureName(culture);
             }
+
+            public override string DisplayName => "display";
+
+            public override string EnglishName => "english";
         }
     }
 }