c#:区分当前文化和不变文化的单元测试

本文关键字:文化 单元测试 | 更新日期: 2023-09-27 17:52:33

我有一个方法,它接受StringComparison参数,它确实需要一个单元测试来证明它正在执行正确的比较类型。

这基本上是我目前所拥有的。它通过比较"oe"answers" æ "来区分Ordinal和其他类型(参见System.String)。然而,我还没有找到一种方法来区分CurrentCulture和InvariantCulture。

using System;
using NUnit.Framework;
using System.Threading;
using System.Globalization;
namespace NUnitTests
{
    [TestFixture]
    public class IndexOfTests
    {
        [Test]
        public void IndexOf_uses_specified_comparison_type()
        {
            StringComparison comparisonTypePerformed;
            result = TestComparisonType(StringComparison.CurrentCulture);
            Assert.AreEqual(StringComparison.CurrentCulture, comparisonTypePerformed);
            result = TestComparisonType(StringComparison.InvariantCulture);
            Assert.AreEqual(StringComparison.CurrentCulture, comparisonTypePerformed);
            result = TestComparisonType(StringComparison.Ordinal);
            Assert.AreEqual(StringComparison.CurrentCulture, comparisonTypePerformed);
        }
        bool TestComparisonType(StringComparison comparisonType)
        {
            int result;
            // Ensure the current culture is consistent for test
            var prevCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", false);
            try
            {
                result = IndexOf("oe", "œ", comparisonType);
                if (result == 0)
                {
                    // The comparison type performed was either CurrentCulture,
                    // InvariantCulture, or one of the case-insensitive variants.
                    // TODO: Add test to differentiate between CurrentCulture and InvariantCulture
                    throw new NotImplementedException();
                    result = IndexOf("???????", "???????", StringComparison.CurrentCulture);
                    //...
                }
                else // result == -1
                {
                    // The comparison type performed was either Ordinal or OrdinalIgnoreCase
                    result = IndexOf("a", "A", StringComparison.CurrentCulture);
                    if (result)
                        Console.WriteLine("Comparison type was OrdinalIgnoreCase");
                    else
                        Console.WriteLine("Comparison type was Ordinal");
                }
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = prevCulture;
            }
        }
    }
}

我考虑过通过比较"I"answers"I"来使用土耳其问题,但它只适用于不区分大小写的比较。

我环顾四周,找不到在字符串相等测试中InvariantCulture与其他文化不同的情况(只有排序顺序和解析/序列化)。例如,根据区域性,"ô"answers"o"将以不同的方式排序,但所有区域性在相等性测试中返回相同的结果。

是否有一个相等性检验来区分InvariantCulture和其他文化?

编辑:德语的"ß"answers"ss"对所有文化都给出相同的结果,因此它们不起作用。

编辑:实际上,所需要的只是两个字符串在一种文化中被认为是相等的,而在另一种文化中被认为是不相等的。

c#:区分当前文化和不变文化的单元测试

CultureInfo上的MSDN Sample有一个根据区域性不同排序顺序的示例。我觉得这是你最可能的起点。然而,如果这不起作用,你可以利用下面的一些信息。

看起来在String上执行了一组类似的测试。比较MSDN页面。在这个例子中,它是在en-US文化中。

如果你看一下CultureInfo。您会注意到,该InvarientCulture基于英语,但没有任何地区或国家编码。StringComparison页面提到,根据语言的不同,连字符有不同的权重。你可以利用这一点,找到一种连字符的权重不同于英语的语言。

维基百科在排序文章中有一些有趣的关于排序的注释,可能也很有用。具体看一下排序,按字母顺序,然后看一下西班牙语笔记。

例如,有29个字母的西班牙语把ñ当作一个基本字母在n之后,以前处理chl是c后面的基本字母和l。我和我都是仍然考虑信件,但现在按字母顺序排列的组合。

我不确定这有多大帮助,但它可能会让你找到答案。

多亏了blackSphere,我能够找到一些文化和InvariantCulture之间的差异,如下面的代码所示:

void Demonstration_For_LL()
{
    int foundPos;
    foundPos = "ll".IndexOf("l", StringComparison.InvariantCulture);
    Assert.AreEqual(0, foundPos);
    Thread.CurrentThread.CurrentCulture = new CultureInfo("sq", false);
    foundPos = "ll".IndexOf("l", StringComparison.CurrentCulture);
    Assert.AreEqual(-1, foundPos);
    Thread.CurrentThread.CurrentCulture = new CultureInfo("sq-AL", false);
    foundPos = "ll".IndexOf("l", StringComparison.CurrentCulture);
    Assert.AreEqual(-1, foundPos);
}
void Demonstration_For_CH()
{
    int foundPos;
    foundPos = "ch".IndexOf("c", StringComparison.InvariantCulture);
    Assert.AreEqual(0, foundPos);
    Thread.CurrentThread.CurrentCulture = new CultureInfo("cs", false);
    foundPos = "ch".IndexOf("c", StringComparison.InvariantCulture);
    Assert.AreEqual(-1, foundPos);
    Thread.CurrentThread.CurrentCulture = new CultureInfo("cs-CZ", false);
    foundPos = "ch".IndexOf("c", StringComparison.InvariantCulture);
    Assert.AreEqual(-1, foundPos);
    Thread.CurrentThread.CurrentCulture = new CultureInfo("sk", false);
    foundPos = "ch".IndexOf("c", StringComparison.InvariantCulture);
    Assert.AreEqual(-1, foundPos);
    Thread.CurrentThread.CurrentCulture = new CultureInfo("sk-SK", false);
    foundPos = "ch".IndexOf("c", StringComparison.InvariantCulture);
    Assert.AreEqual(-1, foundPos);
    Thread.CurrentThread.CurrentCulture = new CultureInfo("vi", false);
    foundPos = "ch".IndexOf("c", StringComparison.InvariantCulture);
    Assert.AreEqual(-1, foundPos);
    Thread.CurrentThread.CurrentCulture = new CultureInfo("vi-VN", false);
    foundPos = "ch".IndexOf("c", StringComparison.InvariantCulture);
    Assert.AreEqual(-1, foundPos);
}

不幸的是,字符串。比较方法似乎没有显示出这些差异。无论如何,我的测试方法现在看起来像这样:

class Example
{
    public static void Main()
    {
        var comparisonTypePerformed =
            GetComparisonTypePerformed(
                new TestedMethod(string.IndexOf));
        Console.WriteLine("Comparison type performed was: " + comparisonTypePerformed);
    }
    public static StringComparison GetComparisonTypePerformed(TestedMethod testedMethod)
    {
        StringComparison comparisonTypePerformed;
        var prevCulture = Thread.CurrentThread.CurrentCulture;
        try
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", false);
            // Check if method performs an Ordinal search
            int result = testedMethod("œ", "oe", 0, 1, comparisonType);
            if (result == StringHelper.NPOS)
            {
                // Check if method performs a case-sensitive search
                result = testedMethod("a", "A", 0, 1, comparisonType);
                if (result == StringHelper.NPOS)
                    comparisonTypePerformed = StringComparison.Ordinal;
                else
                    comparisonTypePerformed = StringComparison.OrdinalIgnoreCase;
            }
            else
            {
                Thread.CurrentThread.CurrentCulture = new CultureInfo("sq-AL", false);
                // Check if method uses CurrentCulture or InvariantCulture
                result = testedMethod("ll", new string[] { "l" }, 0, 2, comparisonType);
                if (result == StringHelper.NPOS)
                {
                    // Check if method performs a case-sensitive search
                    result = testedMethod("a", new string[] { "A" }, 0, 1, comparisonType);
                    if (result == StringHelper.NPOS)
                        comparisonTypePerformed = StringComparison.CurrentCulture;
                    else
                        comparisonTypePerformed = StringComparison.CurrentCultureIgnoreCase;
                }
                else
                {
                    // Check if method performs a case-sensitive search
                    result = testedMethod("a", new string[] { "A" }, 0, 1, comparisonType);
                    if (result == StringHelper.NPOS)
                        comparisonTypePerformed = StringComparison.InvariantCulture;
                    else
                        comparisonTypePerformed = StringComparison.InvariantCultureIgnoreCase;
                }
            }
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = prevCulture;
        }
        return comparisonTypePerformed;
    }
    delegate int TestedMethod(string source, string value, int startIndex, int count, StringComparison comparisonType);
}

尝试以fr-FR作为当前培养物的cot和côte。

或使用此MSDN资源查找其他示例。

我已经环顾四周,找不到一个情况下,不变性文化不同于其他文化的字符串比较(只有排序顺序和解析/序列化)。

我不明白这个注释——排序顺序肯定使用了StringComparison。