Commit c8c1ae11 authored by alexpott's avatar alexpott

Issue #2051467 by jhedstrom, dawehner, amateescu, Berdir, herom, Mile23:...

Issue #2051467 by jhedstrom, dawehner, amateescu, Berdir, herom, Mile23: Expand and convert to phpunit tests for \Drupal\Component\Transliteration
parent af1ea7bf
......@@ -936,6 +936,7 @@ services:
arguments: ['@csrf_token']
transliteration:
class: Drupal\Core\Transliteration\PhpTransliteration
arguments: [null, '@module_handler']
flood:
class: Drupal\Core\Flood\DatabaseBackend
arguments: ['@database', '@request_stack']
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Transliteration;
use Drupal\Component\Transliteration\PhpTransliteration as BaseTransliteration;
use Drupal\Core\Extension\ModuleHandlerInterface;
/**
* Enhances PhpTransliteration with an alter hook.
......@@ -17,6 +18,29 @@
*/
class PhpTransliteration extends BaseTransliteration {
/**
* The module handler to execute the transliteration_overrides alter hook.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Constructs a PhpTransliteration object.
*
* @param string $data_directory
* (optional) The directory where data files reside. If omitted, defaults
* to subdirectory 'data' underneath the directory where the class's PHP
* file resides.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler to execute the transliteration_overrides alter hook.
*/
public function __construct($data_directory = NULL, ModuleHandlerInterface $module_handler) {
parent::__construct($data_directory);
$this->moduleHandler = $module_handler;
}
/**
* Overrides \Drupal\Component\Transliteration\PhpTransliteration::readLanguageOverrides().
*
......@@ -27,7 +51,7 @@ protected function readLanguageOverrides($langcode) {
parent::readLanguageOverrides($langcode);
// Let modules alter the language-specific overrides.
\Drupal::moduleHandler()->alter('transliteration_overrides', $this->languageOverrides[$langcode], $langcode);
$this->moduleHandler->alter('transliteration_overrides', $this->languageOverrides[$langcode], $langcode);
}
}
name: 'Transliteration test'
type: module
description: 'Helper module for Transliteration system tests.'
package: Testing
version: VERSION
core: 8.x
<?php
/**
* @file
* Test module for Transliteration system.
*/
/**
* Implements hook_transliteration_overrides_alter().
*/
function transliterate_test_transliteration_overrides_alter(&$overrides, $langcode) {
if ($langcode == 'zz') {
// The default transliteration of Ä is A, but change it to Z for testing.
$overrides[0xC4] = 'Z';
// Also provide transliterations of two 5-byte characters from
// http://en.wikipedia.org/wiki/Gothic_alphabet.
$overrides[0x10330] = 'A';
$overrides[0x10338] = 'Th';
}
}
......@@ -2,32 +2,59 @@
/**
* @file
* Definition of Drupal\system\Tests\Transliteration\TransliterationTest.
* Contains \Drupal\Tests\Component\Transliteration\PhpTransliterationTest.
*/
namespace Drupal\system\Tests\Transliteration;
namespace Drupal\Tests\Component\Transliteration;
use Drupal\Core\Transliteration\PhpTransliteration;
use Drupal\simpletest\KernelTestBase;
use Drupal\Component\Transliteration\PhpTransliteration;
use Drupal\Component\Utility\Random;
use Drupal\Tests\UnitTestCase;
/**
* Tests Transliteration component functionality.
*
* @group Transliteration
*
* @coversClass \Drupal\Component\Transliteration\PhpTransliteration
*/
class TransliterationTest extends KernelTestBase {
class PhpTransliterationTest extends UnitTestCase {
/**
* Modules to enable.
* Tests the PhpTransliteration class.
*
* @param string $langcode
* The language code to test.
* @param string $original
* The original string.
* @param string $expected
* The expected return from PhpTransliteration::transliterate().
* @param string $unknown_character
* (optional) The character to substitute for characters in $string without
* transliterated equivalents. Defaults to '?'.
* @param int $max_length
* (optional) If provided, return at most this many characters, ensuring
* that the transliteration does not split in the middle of an input
* character's transliteration.
*
* @var array
* @dataProvider providerTestPhpTransliteration
*/
public static $modules = array('transliterate_test');
public function testPhpTransliteration($langcode, $original, $expected, $unknown_character = '?', $max_length = NULL) {
$transliterator_class = new PhpTransliteration();
$actual = $transliterator_class->transliterate($original, $langcode, $unknown_character, $max_length);
$this->assertSame($expected, $actual);
}
/**
* Tests the PhpTransliteration class.
* Provides data for self::testPhpTransliteration().
*
* @return array
* An array of arrays, each containing the parameters for
* self::testPhpTransliteration().
*/
public function testPhpTransliteration() {
$random = $this->randomMachineName(10);
public function providerTestPhpTransliteration() {
$random_generator = new Random();
$random = $random_generator->string(10);
// Make some strings with two, three, and four-byte characters for testing.
// Note that the 3-byte character is overridden by the 'kg' language.
$two_byte = 'Ä Ö Ü Å Ø äöüåøhello';
......@@ -41,10 +68,8 @@ public function testPhpTransliteration() {
// http://en.wikipedia.org/wiki/Gothic_alphabet
// They are not in our tables, but should at least give us '?' (unknown).
$five_byte = html_entity_decode('&#x10330;&#x10338;', ENT_NOQUOTES, 'UTF-8');
// Five-byte characters do not work in MySQL, so make a printable version.
$five_byte_printable = '&#x10330;&#x10338;';
$cases = array(
return array(
// Each test case is (language code, input, output).
// Test ASCII in English.
array('en', $random, $random),
......@@ -57,7 +82,7 @@ public function testPhpTransliteration() {
array('fr', $three_byte, 'c'),
array('fr', $four_byte, 'wii'),
// Test 5-byte characters.
array('en', $five_byte, '??', $five_byte_printable),
array('en', $five_byte, '??'),
// Test a language with no overrides.
array('en', $two_byte, 'A O U A O aouaohello'),
// Test language overrides provided by core.
......@@ -66,47 +91,29 @@ public function testPhpTransliteration() {
array('dk', $two_byte, 'A O U Aa Oe aouaaoehello'),
array('dk', $random, $random),
array('kg', $three_byte, 'ts'),
// Test the language override hook in the test module, which changes
// the transliteration of Ä to Z and provides for the 5-byte characters.
array('zz', $two_byte, 'Z O U A O aouaohello'),
array('zz', $random, $random),
array('zz', $five_byte, 'ATh', $five_byte_printable),
// Test strings in some other languages.
// Turkish, provided by drupal.org user Kartagis.
array('tr', 'Abayı serdiler bize. Söyleyeceğim yüzlerine. Sanırım hepimiz aynı şeyi düşünüyoruz.', 'Abayi serdiler bize. Soyleyecegim yuzlerine. Sanirim hepimiz ayni seyi dusunuyoruz.'),
// Illegal/unknown unicode.
array('en', chr(0xF8) . chr(0x80) . chr(0x80) . chr(0x80) . chr(0x80), '?'),
// Max length.
array('de', $two_byte, 'Ae Oe', '?', 5),
);
}
// Test each case both with a new instance of the transliteration class,
// and with one that builds as it goes.
$transliterator_service = $this->container->get('transliteration');
foreach($cases as $case) {
list($langcode, $original, $expected) = $case;
$printable = (isset($case[3])) ? $case[3] : $original;
$transliterator_class = new PhpTransliteration();
$actual = $transliterator_class->transliterate($original, $langcode);
$this->assertIdentical($actual, $expected, format_string('@original transliteration to @actual is identical to @expected for language @langcode in new class instance.', array(
'@original' => $printable,
'@langcode' => $langcode,
'@expected' => $expected,
'@actual' => $actual,
)));
$actual = $transliterator_service->transliterate($original, $langcode);
$this->assertIdentical($actual, $expected, format_string('@original transliteration to @actual is identical to @expected for language @langcode in service instance.', array(
'@original' => $printable,
'@langcode' => $langcode,
'@expected' => $expected,
'@actual' => $actual,
)));
}
/**
* Tests the transliteration with max length.
*/
public function testTransliterationWithMaxLength() {
$transliteration = new PhpTransliteration();
// Test with max length, using German. It should never split up the
// transliteration of a single character.
$input = 'Ä Ö Ü Å Ø äöüåøhello';
$trunc_output = 'Ae Oe Ue A O aeoe';
$this->assertIdentical($trunc_output, $transliterator_service->transliterate($input, 'de', '?', 17), 'Truncating to 17 characters works');
$this->assertIdentical($trunc_output, $transliterator_service->transliterate($input, 'de', '?', 18), 'Truncating to 18 characters works');
$this->assertSame($trunc_output, $transliteration->transliterate($input, 'de', '?', 17), 'Truncating to 17 characters works');
$this->assertSame($trunc_output, $transliteration->transliterate($input, 'de', '?', 18), 'Truncating to 18 characters works');
}
}
......@@ -22,8 +22,9 @@ class BlockBaseTest extends UnitTestCase {
* @see \Drupal\Core\Block\BlockBase::getMachineNameSuggestion().
*/
public function testGetMachineNameSuggestion() {
$module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$transliteration = $this->getMockBuilder('Drupal\Core\Transliteration\PhpTransliteration')
// @todo Inject the module handler into PhpTransliteration.
->setConstructorArgs(array(NULL, $module_handler))
->setMethods(array('readLanguageOverrides'))
->getMock();
......
<?php
/**
* @file
* Contains \Drupal\Tests\Core\Transliteration\PhpTransliterationTest.
*/
namespace Drupal\Tests\Core\Transliteration;
use Drupal\Component\Utility\Random;
use Drupal\Component\Utility\String;
use Drupal\Core\Transliteration\PhpTransliteration;
use Drupal\Tests\UnitTestCase;
/**
* Tests Transliteration component functionality.
*
* @group Transliteration
*
* @coversClass \Drupal\Core\Transliteration\PhpTransliteration
*/
class PhpTransliterationTest extends UnitTestCase {
/**
* Tests the PhpTransliteration with an alter hook.
*
* @param string $langcode
* The langcode of the string.
* @param string $original
* The string which was not transliterated yet.
* @param string $expected
* The string expected after the transliteration.
* @param string|NULL $printable
* (optional) An alternative version of the original string which is
* printable in the output.
*
* @dataProvider providerTestPhpTransliterationWithAlter
*/
public function testPhpTransliterationWithAlter($langcode, $original, $expected, $printable = NULL) {
if ($printable === NULL) {
$printable = $original;
}
// Test each case both with a new instance of the transliteration class,
// and with one that builds as it goes.
$module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$module_handler->expects($this->any())
->method('alter')
->will($this->returnCallback(function($hook, &$overrides, $langcode) {
if ($langcode == 'zz') {
// The default transliteration of Ä is A, but change it to Z for testing.
$overrides[0xC4] = 'Z';
// Also provide transliterations of two 5-byte characters from
// http://en.wikipedia.org/wiki/Gothic_alphabet.
$overrides[0x10330] = 'A';
$overrides[0x10338] = 'Th';
}
}));
$transliteration = new PhpTransliteration(NULL, $module_handler);
$actual = $transliteration->transliterate($original, $langcode);
$this->assertSame($expected, $actual, String::format('@original transliteration to @actual is identical to @expected for language @langcode in service instance.', array(
'@original' => $printable,
'@langcode' => $langcode,
'@expected' => $expected,
'@actual' => $actual,
)));
}
/**
* Provides test data for testPhpTransliterationWithAlter.
*
* @return array
*/
public function providerTestPhpTransliterationWithAlter() {
$random_generator = new Random();
$random = $random_generator->string(10);
// Make some strings with two, three, and four-byte characters for testing.
// Note that the 3-byte character is overridden by the 'kg' language.
$two_byte = 'Ä Ö Ü Å Ø äöüåøhello';
// These are two Gothic alphabet letters. See
// http://en.wikipedia.org/wiki/Gothic_alphabet
// They are not in our tables, but should at least give us '?' (unknown).
$five_byte = html_entity_decode('&#x10330;&#x10338;', ENT_NOQUOTES, 'UTF-8');
// Five-byte characters do not work in MySQL, so make a printable version.
$five_byte_printable = '&#x10330;&#x10338;';
$cases = array(
// Test the language override hook in the test module, which changes
// the transliteration of Ä to Z and provides for the 5-byte characters.
array('zz', $two_byte, 'Z O U A O aouaohello'),
array('zz', $random, $random),
array('zz', $five_byte, 'ATh', $five_byte_printable),
);
return $cases;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment