Iconv возвращает неправильную строку в phpunit - PullRequest
0 голосов
/ 20 мая 2018

У меня есть проект в SF4 и я использую phpunit 6.5.8.Я протестировал сервис, который использует iconv:

iconv('UTF-8', 'ASCII//TRANSLIT', $string)

Когда я использую этот сервис в приложении и когда $ string имеет значение: «ąbć», возвращается «abc», но когда тот же сервис запущен в phpunit, возвращается«? b?».

Я не понимаю, почему он не работает ... Конечно, тест отрицательный, но в приложении он работает хорошо.

Ответы [ 2 ]

0 голосов
/ 22 августа 2018

Я создал один класс для работы со строками, а один из методов использовал iconv.

При использовании phpunit в Windows iconv не транслитерирует проблемы локали.Даже используя setlocale () в коде, результаты всегда являются неудачными при тестировании с использованием кода ниже

/**
 * @param $str Convert string to lowercase and replace special chars to equivalents ou remove its
 * @return string
 */
public static function slugify($str)
{
    $str = self::toUtf8($str); // Convert from any encoding to UTF-8
    $str = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $str); // transliterate
    $str = strtolower($str); // lowercase
    return $str;
}

Unit Test

public function testSlugfy()
{
    // Basic String
    $str = StringUtils::slugify($this->basicstring);
    $this->assertEquals(strtolower($this->basicstring), $str, 'Basic String cannot be slugfied');

    // Latin String
    $str = StringUtils::slugify($this->latinstring);
    $this->assertEquals(strtolower($this->basicstring), $str, 'Latin1 String cannot be slugfied');

    // UTF-8 String
    $str = StringUtils::slugify($str);
    $this->assertEquals(strtolower($this->basicstring), $str, 'UTF8 String cannot be slugfied');

}

В моем приложении нет проблем, кромеСбой PHPUnit Test с кодом выше.

Итак, чтобы пройти тест, я изменяю функцию на

/**
 * @param $str Convert string to lowercase and replace special chars to equivalents ou remove its
 * @return string
 */
public static function slugify($str)
{
    $string = self::toUtf8($str);
    $string = iconv('UTF-8', 'ASCII//TRANSLIT', $string);

    if ($string != htmlentities($str, ENT_QUOTES, 'UTF-8')) { // iconv fails
        $string = htmlentities($str, ENT_QUOTES, 'UTF-8');
        $string = preg_replace('#&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);#i', '$1', $string);
// If need to leave only 0-9, a-z and A-Z
//            $string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');
//            $string = preg_replace(array('#[^0-9a-z]#i', '#[ -]+#'), ' ', $string);
        $string = trim($string, ' -');
    }

    // lowercase
    $str = strtolower($string);

    return $str;
}

И в конструкторе класса Unit Test я создаю строки с другим подходом, чтобы избежать проблемс файловой кодировкой и проблемами локали.

private $basicstring;
private $latinstring;
private $utf8string;

public function __construct()
{
    // ASCII string
    $this->basicstring = 'aeioucAEIOUC';

    // To avoid troubles using command line in different locales
    // the string used to create different charset is a plain HTML entities
    // Using html_entity_decode to convert the
    // string ãéìôüçÃÉìÔÜÇ
    // into ãéìôüçÃÉìÔÜÇ in different charsets
    $html_chars = 'ãéìôüçÃÉìÔÜÇ';
    $this->utf8string = html_entity_decode($html_chars, ENT_HTML5, 'UTF-8');
    $this->latinstring = html_entity_decode($html_chars, ENT_HTML5, 'ISO-8859-1');
    parent::__construct();
}

Я также использую Symfony 4

0 голосов
/ 09 июня 2018

Хорошо, я решил проблему.Php в CLI не устанавливает локаль.Поэтому мы должны установить его перед тестами.

1.Проверьте местоположение в вашей системе:

locale -a

Например:

$ locale -a
C
C.UTF-8
en_US.utf8

2.В тестах добавьте:

setlocale(LC_CTYPE, 'en_US.utf8');

3.Пример:

    public static function setUpBeforeClass()
    {
        setlocale(LC_CTYPE, 'en_US.utf8');
    }

источник:

...