2011-04-24 12 views
8

Tengo un método que toma un argumento StringComparison, y realmente necesita una prueba unitaria para demostrar que está realizando el tipo de comparación correcto.C#: Prueba unitaria para diferenciar CurrentCulture de InvariantCulture

Esto es básicamente lo que tengo hasta ahora. Diferencia a Ordinal del resto al comparar "oe" y "œ" (ver System.String). Sin embargo, no he encontrado una manera de diferenciar CurrentCulture de 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; 
      } 
     } 
    } 
} 

Consideré utilizando el problema de Turquía mediante la comparación de "i" e "I", pero sólo funciona para las comparaciones entre mayúsculas y minúsculas.

He mirado alrededor y no he podido encontrar un caso donde InvariantCulture difiera de otras culturas en una prueba de igualdad de cadenas (solo orden y análisis/serialización). Por ejemplo, dependiendo de la cultura, "ô" y "o" se ordenarán de forma diferente, pero todas las culturas devuelven el mismo resultado en las pruebas de igualdad.

¿Existe una prueba de igualdad para diferenciar a InvariantCulture de cualquier otra cultura?

EDIT: El alemán "ß" y "ss" dan el mismo resultado para todas las culturas, por lo que no funcionarán.

EDITAR: Realmente, todo lo que se necesita es dos cadenas consideradas iguales en una cultura y desiguales en otra.

Respuesta

2

Gracias a blackSphere, yo era capaz de encontrar algunas diferencias entre algunas culturas y la InvariantCulture, como se muestra en el siguiente código:

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); 
} 

Por desgracia, no parece el método string.Compare para mostrar estas diferencias De todos modos, mi método de prueba se ve así ahora:

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); 
} 
1

Pruebe coté y côte con fr-FR como su cultura actual.

O use this MSDN resource para buscar otros ejemplos.

He mirado alrededor y no he podido encontrar un caso donde InvariantCulture difiera de otras culturas por comparación de cadenas (solo orden y análisis/serialización).

No entiendo este comentario, seguramente el orden de clasificación utiliza un StringComparison.

+0

é y ô ordenan de forma diferente dependiendo de la cultura, pero no parecen afectar las pruebas de igualdad, que es lo que necesito. Actualicé la pregunta para intentar ser más claro. Gracias – drifter

+0

@drifter - ¿Has mirado el ejemplo en la documentación de String.IndexOf: http://msdn.microsoft.com/en-us/library/ms224425.aspx. Compara cadenas con \ u00c5 y \ u0061 \ u030a. Tal vez le dará lo que está buscando. – Joe

+0

Ese ejemplo tiene los mismos resultados para CurrentCulture e InvariantCulture. Probé variaciones en otras culturas, pero no tuve suerte. – drifter

3

La muestra de MSDN en CultureInfo tiene un ejemplo con diferentes órdenes de clasificación según cultura. Creo que esa es la apuesta más probable para un lugar de inicio. Sin embargo, es posible que pueda aprovechar parte de la información a continuación si eso no funciona.

Parece que se está realizando un conjunto similar de pruebas en la página String.Compare de MSDN. Sin embargo, en este ejemplo, está en la cultura en-US.

Si mira la página CultureInfo.InvarientCulture, observará que InvarientCulture está basado en inglés, pero sin codificación regional o de país. Y la página StringComparison menciona que los guiones tienen específicamente un peso diferente, según el idioma. Puede aprovechar eso al encontrar un idioma que pondera los guiones de forma diferente al inglés.

Wikipedia tiene algunas notas interesantes sobre la clasificación en el artículo collation, que también pueden ser útiles. Mire específicamente por orden, alfabético, y luego mire las notas en español.

Por ejemplo, el alfabeto 29 letras de golosinas españolas N como una carta básica siguiente n, y se trató anteriormente ch y LL como letras básicas siguientes c y l, respectivamente. Ch y ll son todavía se consideran letras, pero ahora están alfabetizadas como combinaciones de dos letras .

No estoy seguro de lo útil que será esto, pero puede llevarte a una respuesta.

+1

¡Gracias! Ch y ll devuelven resultados diferentes en algunas culturas en comparación con la cultura invariante. Curiosamente, sin embargo, no en la cultura española. Publiqué una respuesta que demuestra estas diferencias que actualmente tengo que marcar como la respuesta aceptada, pero está basada en la tuya. – drifter

Cuestiones relacionadas