function LocalePluralFormatTest::testGetPluralFormat

Same name and namespace in other branches
  1. 7.x modules/locale/locale.test \LocalePluralFormatTest::testGetPluralFormat()
  2. 9 core/modules/locale/tests/src/Functional/LocalePluralFormatTest.php \Drupal\Tests\locale\Functional\LocalePluralFormatTest::testGetPluralFormat()
  3. 8.9.x core/modules/locale/tests/src/Functional/LocalePluralFormatTest.php \Drupal\Tests\locale\Functional\LocalePluralFormatTest::testGetPluralFormat()
  4. 10 core/modules/locale/tests/src/Functional/LocalePluralFormatTest.php \Drupal\Tests\locale\Functional\LocalePluralFormatTest::testGetPluralFormat()

Tests locale_get_plural() and \Drupal::translation()->formatPlural().

File

core/modules/locale/tests/src/Functional/LocalePluralFormatTest.php, line 57

Class

LocalePluralFormatTest
Tests plural handling for various languages.

Namespace

Drupal\Tests\locale\Functional

Code

public function testGetPluralFormat() : void {
    // Import some .po files with formulas to set up the environment.
    // These will also add the languages to the system.
    $this->importPoFile($this->getPoFileWithSimplePlural(), [
        'langcode' => 'fr',
    ]);
    $this->importPoFile($this->getPoFileWithComplexPlural(), [
        'langcode' => 'hr',
    ]);
    // Attempt to import some broken .po files as well to prove that these
    // will not overwrite the proper plural formula imported above.
    $this->importPoFile($this->getPoFileWithMissingPlural(), [
        'langcode' => 'fr',
        'overwrite_options[not_customized]' => TRUE,
    ]);
    $this->importPoFile($this->getPoFileWithBrokenPlural(), [
        'langcode' => 'hr',
        'overwrite_options[not_customized]' => TRUE,
    ]);
    // Reset static caches from locale_get_plural() to ensure we get fresh data.
    drupal_static_reset('locale_get_plural');
    drupal_static_reset('locale_get_plural:plurals');
    drupal_static_reset('locale');
    // Expected plural translation strings for each plural index.
    $plural_strings = [
        // English is not imported in this case, so we assume built-in text
        // and formulas.
'en' => [
            0 => '1 hour',
            1 => '@count hours',
        ],
        'fr' => [
            0 => '@count heure',
            1 => '@count heures',
        ],
        'hr' => [
            0 => '@count sat',
            1 => '@count sata',
            2 => '@count sati',
        ],
        // Hungarian is not imported, so it should assume the same text as
        // English, but it will always pick the plural form as per the built-in
        // logic, so only index -1 is relevant with the plural value.
'hu' => [
            0 => '1 hour',
            -1 => '@count hours',
        ],
    ];
    // Expected plural indexes precomputed base on the plural formulas with
    // given $count value.
    $plural_tests = [
        'en' => [
            1 => 0,
            0 => 1,
            5 => 1,
            123 => 1,
            235 => 1,
        ],
        'fr' => [
            1 => 0,
            0 => 0,
            5 => 1,
            123 => 1,
            235 => 1,
        ],
        'hr' => [
            1 => 0,
            21 => 0,
            0 => 2,
            2 => 1,
            8 => 2,
            123 => 1,
            235 => 2,
        ],
        'hu' => [
            1 => -1,
            21 => -1,
            0 => -1,
        ],
    ];
    foreach ($plural_tests as $langcode => $tests) {
        foreach ($tests as $count => $expected_plural_index) {
            // Assert that the we get the right plural index.
            $this->assertSame($expected_plural_index, locale_get_plural($count, $langcode), 'Computed plural index for ' . $langcode . ' for count ' . $count . ' is ' . $expected_plural_index);
            // Assert that the we get the right translation for that. Change the
            // expected index as per the logic for translation lookups.
            $expected_plural_index = $count == 1 ? 0 : $expected_plural_index;
            $expected_plural_string = str_replace('@count', (string) $count, $plural_strings[$langcode][$expected_plural_index]);
            $this->assertSame($expected_plural_string, \Drupal::translation()->formatPlural($count, '@count hour', '@count hours', [], [
                'langcode' => $langcode,
            ])
                ->render(), 'Plural translation of @count hour / @count hours for count ' . $count . ' in ' . $langcode . ' is ' . $expected_plural_string);
            // DO NOT use translation to pass translated strings into
            // PluralTranslatableMarkup::createFromTranslatedString() this way. It
            // is designed to be used with *already* translated text like settings
            // from configuration. We use PHP translation here just because we have
            // the expected result data in that format.
            $translated_string = \Drupal::translation()->translate('@count hour' . PoItem::DELIMITER . '@count hours', [], [
                'langcode' => $langcode,
            ]);
            $plural = PluralTranslatableMarkup::createFromTranslatedString($count, $translated_string, [], [
                'langcode' => $langcode,
            ]);
            $this->assertSame($expected_plural_string, $plural->render());
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.