Сравнение результатов PHP NumberFormatter::formatCurrency

У меня проблемы с модульным тестированием библиотеки, которая использует NumberFormatter::formatCurrency. После некоторых проб и ошибок я сузил проблему до этого контрольного примера:

/**
 * @dataProvider getLocales()
 */
public function test($locale, $expected)
{
    $number_formatter = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
    $actual = $number_formatter->formatCurrency(3000.05, 'EUR');
    $this->assertEquals($expected, $actual, $locale.' failed');
}

public function getLocales()
{
    return array(
        array('en_US', '€3,000.05'),
        array('fr_FR', '3 000,05 €'),
        array('de_DE', '3.000,05 €'),
    );
}

Результаты:

fr_FR failed
Failed asserting that two strings are equal.
Expected :3 000,05 €
Actual   :3 000,05 €


de_DE failed
Failed asserting that two strings are equal.
Expected :3.000,05 €
Actual   :3.000,05 €

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

Я пробовал сравнивать с strcoll, задавать локаль перед сравнением и другие комбинации без удачи.

Я думаю, это связано с разными кодами utf-8 на каждом языке. Но как тогда сравнить эти строки?

2 ответа

Решение

Я нашел решение. NumberFormatter в PHP вставляет специальный пробел, так называемый пробел без пробелов (может быть, вы знаете,  ).

если вы конвертируете прочитанное значение

str_replace("\xc2\xa0", " ", $actual);

все будет отлично.

Возможно, это зависит от локали или версии, но в ходе тестирования я обнаружил, что дело не в символе, а в самом персонаже.

  • NBSP:NO-BRAKE-SPACE, UTF-80xC2 0xA0или UTF-160x00A0
  • NNBSP:NARROW NO-BRAKE-SPACE, UTF-80xE2 0x80 0xAFили UTF-160x202F

Удалить можно так:

      str_replace("\u{202F}", "", $string);
Другие вопросы по тегам