Replaced gettext translation with package
This allows to check if no translation is available
This commit is contained in:
parent
f90ab26fee
commit
508695efb2
|
@ -14,7 +14,6 @@ To report bugs use [engelsystem/issues](https://github.com/engelsystem/engelsyst
|
|||
* PHP >= 7.1
|
||||
* Required modules:
|
||||
* dom
|
||||
* gettext
|
||||
* json
|
||||
* mbstring
|
||||
* PDO
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
],
|
||||
"require": {
|
||||
"php": ">=7.1.0",
|
||||
"ext-gettext": "*",
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
|
@ -24,6 +23,7 @@
|
|||
"ext-xml": "*",
|
||||
"doctrine/dbal": "^2.9",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"gettext/gettext": "^4.6",
|
||||
"illuminate/container": "5.8.*",
|
||||
"illuminate/database": "5.8.*",
|
||||
"illuminate/support": "5.8.*",
|
||||
|
|
|
@ -134,12 +134,12 @@ return [
|
|||
|
||||
// Available locales in /locale/
|
||||
'locales' => [
|
||||
'de_DE.UTF-8' => 'Deutsch',
|
||||
'en_US.UTF-8' => 'English',
|
||||
'de_DE' => 'Deutsch',
|
||||
'en_US' => 'English',
|
||||
],
|
||||
|
||||
// The default locale to use
|
||||
'default_locale' => env('DEFAULT_LOCALE', 'en_US.UTF-8'),
|
||||
'default_locale' => env('DEFAULT_LOCALE', 'en_US'),
|
||||
|
||||
// Available T-Shirt sizes, set value to null if not available
|
||||
'tshirt_sizes' => [
|
||||
|
|
|
@ -35,8 +35,8 @@ RUN rm -f /app/import/* /app/config/config.php
|
|||
# Build the PHP container
|
||||
FROM php:7-fpm-alpine
|
||||
WORKDIR /var/www
|
||||
RUN apk add --no-cache icu-dev gettext-dev && \
|
||||
docker-php-ext-install intl gettext pdo_mysql
|
||||
RUN apk add --no-cache icu-dev && \
|
||||
docker-php-ext-install intl pdo_mysql
|
||||
COPY --from=data /app/ /var/www
|
||||
RUN chown -R www-data:www-data /var/www/import/ /var/www/storage/ && \
|
||||
rm -r /var/www/html
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Migrations;
|
||||
|
||||
use Engelsystem\Database\Migration\Migration;
|
||||
|
||||
class FixUserLanguages extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$connection = $this->schema->getConnection();
|
||||
$connection
|
||||
->table('users_settings')
|
||||
->update([
|
||||
'language' => $connection->raw('REPLACE(language, ".UTF-8", "")')
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
$connection = $this->schema->getConnection();
|
||||
$connection
|
||||
->table('users_settings')
|
||||
->update([
|
||||
'language' => $connection->raw('CONCAT(language, ".UTF-8")')
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.11\n"
|
||||
"X-Poedit-KeywordsList: __;_e;translate;translatePlural;gettext;gettext_noop\n"
|
||||
"X-Poedit-KeywordsList: __;_e;translate;translatePlural\n"
|
||||
"X-Poedit-Basepath: ../../../..\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Helpers\Translation;
|
||||
|
||||
use Gettext\Translator;
|
||||
|
||||
class GettextTranslator extends Translator
|
||||
{
|
||||
/**
|
||||
* @param string $domain
|
||||
* @param string $context
|
||||
* @param string $original
|
||||
* @return string
|
||||
* @throws TranslationNotFound
|
||||
*/
|
||||
public function dpgettext($domain, $context, $original)
|
||||
{
|
||||
$this->assertHasTranslation($domain, $context, $original);
|
||||
|
||||
return parent::dpgettext($domain, $context, $original);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $domain
|
||||
* @param string $context
|
||||
* @param string $original
|
||||
* @param string $plural
|
||||
* @param string $value
|
||||
* @return string
|
||||
* @throws TranslationNotFound
|
||||
*/
|
||||
public function dnpgettext($domain, $context, $original, $plural, $value)
|
||||
{
|
||||
$this->assertHasTranslation($domain, $context, $original);
|
||||
|
||||
return parent::dnpgettext($domain, $context, $original, $plural, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $domain
|
||||
* @param string $context
|
||||
* @param string $original
|
||||
* @throws TranslationNotFound
|
||||
*/
|
||||
protected function assertHasTranslation($domain, $context, $original)
|
||||
{
|
||||
if ($this->getTranslation($domain, $context, $original)) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new TranslationNotFound(implode('/', [$domain, $context, $original]));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Helpers\Translation;
|
||||
|
||||
use Exception;
|
||||
|
||||
class TranslationNotFound extends Exception
|
||||
{
|
||||
}
|
|
@ -4,11 +4,15 @@ namespace Engelsystem\Helpers\Translation;
|
|||
|
||||
use Engelsystem\Config\Config;
|
||||
use Engelsystem\Container\ServiceProvider;
|
||||
use Gettext\Translations;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
|
||||
class TranslationServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register()
|
||||
/** @var GettextTranslator */
|
||||
protected $translators = [];
|
||||
|
||||
public function register(): void
|
||||
{
|
||||
/** @var Config $config */
|
||||
$config = $this->app->get('config');
|
||||
|
@ -17,41 +21,36 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
|
||||
$locales = $config->get('locales');
|
||||
$locale = $config->get('default_locale');
|
||||
$fallbackLocale = $config->get('fallback_locale', 'en_US');
|
||||
|
||||
$sessionLocale = $session->get('locale', $locale);
|
||||
if (isset($locales[$sessionLocale])) {
|
||||
$locale = $sessionLocale;
|
||||
}
|
||||
|
||||
$this->initGettext();
|
||||
$session->set('locale', $locale);
|
||||
|
||||
$translator = $this->app->make(
|
||||
Translator::class,
|
||||
['locale' => $locale, 'locales' => $locales, 'localeChangeCallback' => [$this, 'setLocale']]
|
||||
[
|
||||
'locale' => $locale,
|
||||
'locales' => $locales,
|
||||
'fallbackLocale' => $fallbackLocale,
|
||||
'getTranslatorCallback' => [$this, 'getTranslator'],
|
||||
'localeChangeCallback' => [$this, 'setLocale'],
|
||||
]
|
||||
);
|
||||
$this->app->instance(Translator::class, $translator);
|
||||
$this->app->instance('translator', $translator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $textDomain
|
||||
* @param string $encoding
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function initGettext($textDomain = 'default', $encoding = 'UTF-8')
|
||||
{
|
||||
bindtextdomain($textDomain, $this->app->get('path.lang'));
|
||||
bind_textdomain_codeset($textDomain, $encoding);
|
||||
textdomain($textDomain);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $locale
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function setLocale($locale)
|
||||
public function setLocale(string $locale): void
|
||||
{
|
||||
$locale .= '.UTF-8';
|
||||
// Set the users locale
|
||||
putenv('LC_ALL=' . $locale);
|
||||
setlocale(LC_ALL, $locale);
|
||||
|
@ -60,4 +59,28 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
putenv('LC_NUMERIC=C');
|
||||
setlocale(LC_NUMERIC, 'C');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $locale
|
||||
* @return GettextTranslator
|
||||
*/
|
||||
public function getTranslator(string $locale): GettextTranslator
|
||||
{
|
||||
if (!isset($this->translators[$locale])) {
|
||||
$file = $this->app->get('path.lang') . '/' . $locale . '/default.mo';
|
||||
|
||||
/** @var GettextTranslator $translator */
|
||||
$translator = $this->app->make(GettextTranslator::class);
|
||||
|
||||
/** @var Translations $translations */
|
||||
$translations = $this->app->make(Translations::class);
|
||||
$translations->addFromMoFile($file);
|
||||
|
||||
$translator->loadTranslations($translations);
|
||||
|
||||
$this->translators[$locale] = $translator;
|
||||
}
|
||||
|
||||
return $this->translators[$locale];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@ class Translator
|
|||
/** @var string */
|
||||
protected $locale;
|
||||
|
||||
/** @var string */
|
||||
protected $fallbackLocale;
|
||||
|
||||
/** @var callable */
|
||||
protected $getTranslatorCallback;
|
||||
|
||||
/** @var callable */
|
||||
protected $localeChangeCallback;
|
||||
|
||||
|
@ -17,15 +23,24 @@ class Translator
|
|||
* Translator constructor.
|
||||
*
|
||||
* @param string $locale
|
||||
* @param string $fallbackLocale
|
||||
* @param callable $getTranslatorCallback
|
||||
* @param string[] $locales
|
||||
* @param callable $localeChangeCallback
|
||||
*/
|
||||
public function __construct(string $locale, array $locales = [], callable $localeChangeCallback = null)
|
||||
{
|
||||
public function __construct(
|
||||
string $locale,
|
||||
string $fallbackLocale,
|
||||
callable $getTranslatorCallback,
|
||||
array $locales = [],
|
||||
callable $localeChangeCallback = null
|
||||
) {
|
||||
$this->localeChangeCallback = $localeChangeCallback;
|
||||
$this->getTranslatorCallback = $getTranslatorCallback;
|
||||
|
||||
$this->setLocale($locale);
|
||||
$this->setLocales($locales);
|
||||
$this->fallbackLocale = $fallbackLocale;
|
||||
$this->locales = $locales;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,9 +52,7 @@ class Translator
|
|||
*/
|
||||
public function translate(string $key, array $replace = []): string
|
||||
{
|
||||
$translated = $this->translateGettext($key);
|
||||
|
||||
return $this->replaceText($translated, $replace);
|
||||
return $this->translateText('gettext', [$key], $replace);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,7 +66,29 @@ class Translator
|
|||
*/
|
||||
public function translatePlural(string $key, string $pluralKey, int $number, array $replace = []): string
|
||||
{
|
||||
$translated = $this->translateGettextPlural($key, $pluralKey, $number);
|
||||
return $this->translateText('ngettext', [$key, $pluralKey, $number], $replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param array $parameters
|
||||
* @param array $replace
|
||||
* @return mixed|string
|
||||
*/
|
||||
protected function translateText(string $type, array $parameters, array $replace = [])
|
||||
{
|
||||
$translated = $parameters[0];
|
||||
|
||||
foreach ([$this->locale, $this->fallbackLocale] as $lang) {
|
||||
/** @var GettextTranslator $translator */
|
||||
$translator = call_user_func($this->getTranslatorCallback, $lang);
|
||||
|
||||
try {
|
||||
$translated = call_user_func_array([$translator, $type], $parameters);
|
||||
break;
|
||||
} catch (TranslationNotFound $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return $this->replaceText($translated, $replace);
|
||||
}
|
||||
|
@ -74,32 +109,6 @@ class Translator
|
|||
return call_user_func_array('sprintf', array_merge([$key], $replace));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the key via gettext
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function translateGettext(string $key): string
|
||||
{
|
||||
return gettext($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the key via gettext
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $keyPlural
|
||||
* @param int $number
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function translateGettextPlural(string $key, string $keyPlural, int $number): string
|
||||
{
|
||||
return ngettext($key, $keyPlural, $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
# Testing content
|
||||
msgid "foo.bar"
|
||||
msgstr "Foo Bar!"
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace Engelsystem\Test\Unit\Helpers\Translation;
|
||||
|
||||
use Engelsystem\Helpers\Translation\GettextTranslator;
|
||||
use Engelsystem\Helpers\Translation\TranslationNotFound;
|
||||
use Engelsystem\Test\Unit\ServiceProviderTest;
|
||||
use Gettext\Translation;
|
||||
use Gettext\Translations;
|
||||
|
||||
class GettextTranslatorTest extends ServiceProviderTest
|
||||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Helpers\Translation\GettextTranslator::assertHasTranslation()
|
||||
*/
|
||||
public function testNoTranslation()
|
||||
{
|
||||
$translations = $this->getTranslations();
|
||||
|
||||
$translator = new GettextTranslator();
|
||||
$translator->loadTranslations($translations);
|
||||
|
||||
$this->assertEquals('Translation!', $translator->gettext('test.value'));
|
||||
|
||||
$this->expectException(TranslationNotFound::class);
|
||||
$this->expectExceptionMessage('//foo.bar');
|
||||
|
||||
$translator->gettext('foo.bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Helpers\Translation\GettextTranslator::dpgettext()
|
||||
*/
|
||||
public function testDpgettext()
|
||||
{
|
||||
$translations = $this->getTranslations();
|
||||
|
||||
$translator = new GettextTranslator();
|
||||
$translator->loadTranslations($translations);
|
||||
|
||||
$this->assertEquals('Translation!', $translator->dpgettext(null, null, 'test.value'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Helpers\Translation\GettextTranslator::dnpgettext()
|
||||
*/
|
||||
public function testDnpgettext()
|
||||
{
|
||||
$translations = $this->getTranslations();
|
||||
|
||||
$translator = new GettextTranslator();
|
||||
$translator->loadTranslations($translations);
|
||||
|
||||
$this->assertEquals('Translations!', $translator->dnpgettext(null, null, 'test.value', 'test.values', 2));
|
||||
}
|
||||
|
||||
protected function getTranslations(): Translations
|
||||
{
|
||||
$translations = new Translations();
|
||||
$translations[] =
|
||||
(new Translation(null, 'test.value', 'test.values'))
|
||||
->setTranslation('Translation!')
|
||||
->setPluralTranslations(['Translations!']);
|
||||
|
||||
return $translations;
|
||||
}
|
||||
}
|
|
@ -14,11 +14,14 @@ class TranslationServiceProviderTest extends ServiceProviderTest
|
|||
/**
|
||||
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::register()
|
||||
*/
|
||||
public function testRegister()
|
||||
public function testRegister(): void
|
||||
{
|
||||
$defaultLocale = 'fo_OO';
|
||||
$locale = 'te_ST.WTF-9';
|
||||
$locales = ['fo_OO' => 'Foo', 'fo_OO.BAR' => 'Foo (Bar)', 'te_ST.WTF-9' => 'WTF\'s Testing?'];
|
||||
$config = new Config(['locales' => $locales, 'default_locale' => $defaultLocale]);
|
||||
|
||||
$app = $this->getApp(['make', 'instance', 'get']);
|
||||
/** @var Config|MockObject $config */
|
||||
$config = $this->createMock(Config::class);
|
||||
/** @var Session|MockObject $session */
|
||||
$session = $this->createMock(Session::class);
|
||||
/** @var Translator|MockObject $translator */
|
||||
|
@ -27,31 +30,14 @@ class TranslationServiceProviderTest extends ServiceProviderTest
|
|||
/** @var TranslationServiceProvider|MockObject $serviceProvider */
|
||||
$serviceProvider = $this->getMockBuilder(TranslationServiceProvider::class)
|
||||
->setConstructorArgs([$app])
|
||||
->setMethods(['initGettext', 'setLocale'])
|
||||
->setMethods(['setLocale'])
|
||||
->getMock();
|
||||
|
||||
$serviceProvider->expects($this->once())
|
||||
->method('initGettext');
|
||||
|
||||
$app->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->withConsecutive(['config'], ['session'])
|
||||
->willReturnOnConsecutiveCalls($config, $session);
|
||||
|
||||
$defaultLocale = 'fo_OO';
|
||||
$locale = 'te_ST.WTF-9';
|
||||
$locales = ['fo_OO' => 'Foo', 'fo_OO.BAR' => 'Foo (Bar)', 'te_ST.WTF-9' => 'WTF\'s Testing?'];
|
||||
$config->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->withConsecutive(
|
||||
['locales'],
|
||||
['default_locale']
|
||||
)
|
||||
->willReturnOnConsecutiveCalls(
|
||||
$locales,
|
||||
$defaultLocale
|
||||
);
|
||||
|
||||
$session->expects($this->once())
|
||||
->method('get')
|
||||
->with('locale', $defaultLocale)
|
||||
|
@ -65,9 +51,11 @@ class TranslationServiceProviderTest extends ServiceProviderTest
|
|||
->with(
|
||||
Translator::class,
|
||||
[
|
||||
'locale' => $locale,
|
||||
'locales' => $locales,
|
||||
'localeChangeCallback' => [$serviceProvider, 'setLocale'],
|
||||
'locale' => $locale,
|
||||
'locales' => $locales,
|
||||
'fallbackLocale' => 'en_US',
|
||||
'getTranslatorCallback' => [$serviceProvider, 'getTranslator'],
|
||||
'localeChangeCallback' => [$serviceProvider, 'setLocale'],
|
||||
]
|
||||
)
|
||||
->willReturn($translator);
|
||||
|
@ -81,4 +69,22 @@ class TranslationServiceProviderTest extends ServiceProviderTest
|
|||
|
||||
$serviceProvider->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator()
|
||||
*/
|
||||
public function testGetTranslator(): void
|
||||
{
|
||||
$app = $this->getApp(['get']);
|
||||
$serviceProvider = new TranslationServiceProvider($app);
|
||||
|
||||
$this->setExpects($app, 'get', ['path.lang'], __DIR__ . '/Assets');
|
||||
|
||||
// Get translator
|
||||
$translator = $serviceProvider->getTranslator('fo_OO');
|
||||
$this->assertEquals('Foo Bar!', $translator->gettext('foo.bar'));
|
||||
|
||||
// Retry from cache
|
||||
$serviceProvider->getTranslator('fo_OO');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Engelsystem\Test\Unit\Helpers\Translation;
|
||||
|
||||
use Engelsystem\Helpers\Translation\GettextTranslator;
|
||||
use Engelsystem\Helpers\Translation\TranslationNotFound;
|
||||
use Engelsystem\Helpers\Translation\Translator;
|
||||
use Engelsystem\Test\Unit\ServiceProviderTest;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
@ -19,18 +21,18 @@ class TranslatorTest extends ServiceProviderTest
|
|||
*/
|
||||
public function testInit()
|
||||
{
|
||||
$locales = ['te_ST.ER-01' => 'Tests', 'fo_OO' => 'SomeFOO'];
|
||||
$locale = 'te_ST.ER-01';
|
||||
$locales = ['te_ST' => 'Tests', 'fo_OO' => 'SomeFOO'];
|
||||
$locale = 'te_ST';
|
||||
|
||||
/** @var callable|MockObject $callable */
|
||||
$callable = $this->getMockBuilder(stdClass::class)
|
||||
/** @var callable|MockObject $localeChange */
|
||||
$localeChange = $this->getMockBuilder(stdClass::class)
|
||||
->setMethods(['__invoke'])
|
||||
->getMock();
|
||||
$callable->expects($this->exactly(2))
|
||||
$localeChange->expects($this->exactly(2))
|
||||
->method('__invoke')
|
||||
->withConsecutive(['te_ST.ER-01'], ['fo_OO']);
|
||||
->withConsecutive(['te_ST'], ['fo_OO']);
|
||||
|
||||
$translator = new Translator($locale, $locales, $callable);
|
||||
$translator = new Translator($locale, 'fo_OO', function () { }, $locales, $localeChange);
|
||||
|
||||
$this->assertEquals($locales, $translator->getLocales());
|
||||
$this->assertEquals($locale, $translator->getLocale());
|
||||
|
@ -43,24 +45,23 @@ class TranslatorTest extends ServiceProviderTest
|
|||
$this->assertEquals($newLocales, $translator->getLocales());
|
||||
|
||||
$this->assertTrue($translator->hasLocale('ip_SU-M'));
|
||||
$this->assertFalse($translator->hasLocale('te_ST.ER-01'));
|
||||
$this->assertFalse($translator->hasLocale('te_ST'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Helpers\Translation\Translator::replaceText
|
||||
* @covers \Engelsystem\Helpers\Translation\Translator::translate
|
||||
*/
|
||||
public function testTranslate()
|
||||
{
|
||||
/** @var Translator|MockObject $translator */
|
||||
$translator = $this->getMockBuilder(Translator::class)
|
||||
->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']])
|
||||
->setMethods(['translateGettext'])
|
||||
->setConstructorArgs(['de_DE', 'en_US', function () { }, ['de_DE' => 'Deutsch']])
|
||||
->setMethods(['translateText'])
|
||||
->getMock();
|
||||
$translator->expects($this->exactly(2))
|
||||
->method('translateGettext')
|
||||
->withConsecutive(['Hello!'], ['My favourite number is %u!'])
|
||||
->willReturnOnConsecutiveCalls('Hallo!', 'Meine Lieblingszahl ist die %u!');
|
||||
->method('translateText')
|
||||
->withConsecutive(['gettext', ['Hello!'], []], ['gettext', ['My favourite number is %u!'], [3]])
|
||||
->willReturnOnConsecutiveCalls('Hallo!', 'Meine Lieblingszahl ist die 3!');
|
||||
|
||||
$return = $translator->translate('Hello!');
|
||||
$this->assertEquals('Hallo!', $return);
|
||||
|
@ -76,15 +77,58 @@ class TranslatorTest extends ServiceProviderTest
|
|||
{
|
||||
/** @var Translator|MockObject $translator */
|
||||
$translator = $this->getMockBuilder(Translator::class)
|
||||
->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']])
|
||||
->setMethods(['translateGettextPlural'])
|
||||
->setConstructorArgs(['de_DE', 'en_US', function () { }, ['de_DE' => 'Deutsch']])
|
||||
->setMethods(['translateText'])
|
||||
->getMock();
|
||||
$translator->expects($this->once())
|
||||
->method('translateGettextPlural')
|
||||
->with('%s apple', '%s apples', 2)
|
||||
->method('translateText')
|
||||
->with('ngettext', ['%s apple', '%s apples', 2], [2])
|
||||
->willReturn('2 Äpfel');
|
||||
|
||||
$return = $translator->translatePlural('%s apple', '%s apples', 2, [2]);
|
||||
$this->assertEquals('2 Äpfel', $return);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Helpers\Translation\Translator::translatePlural
|
||||
* @covers \Engelsystem\Helpers\Translation\Translator::translateText
|
||||
* @covers \Engelsystem\Helpers\Translation\Translator::replaceText
|
||||
*/
|
||||
public function testReplaceText()
|
||||
{
|
||||
/** @var GettextTranslator|MockObject $gtt */
|
||||
$gtt = $this->createMock(GettextTranslator::class);
|
||||
/** @var callable|MockObject $getTranslator */
|
||||
$getTranslator = $this->getMockBuilder(stdClass::class)
|
||||
->setMethods(['__invoke'])
|
||||
->getMock();
|
||||
$getTranslator->expects($this->exactly(5))
|
||||
->method('__invoke')
|
||||
->withConsecutive(['te_ST'], ['fo_OO'], ['te_ST'], ['fo_OO'], ['te_ST'])
|
||||
->willReturn($gtt);
|
||||
|
||||
$i = 0;
|
||||
$gtt->expects($this->exactly(4))
|
||||
->method('gettext')
|
||||
->willReturnCallback(function () use (&$i) {
|
||||
$i++;
|
||||
if ($i != 4) {
|
||||
throw new TranslationNotFound();
|
||||
}
|
||||
|
||||
return 'Lorem %s???';
|
||||
});
|
||||
$this->setExpects($gtt, 'ngettext', ['foo.barf'], 'Lorem %s!');
|
||||
|
||||
$translator = new Translator('te_ST', 'fo_OO', $getTranslator, ['te_ST' => 'Test', 'fo_OO' => 'Foo']);
|
||||
|
||||
// No translation
|
||||
$this->assertEquals('foo.bar', $translator->translate('foo.bar'));
|
||||
|
||||
// Fallback translation
|
||||
$this->assertEquals('Lorem test2???', $translator->translate('foo.batz', ['test2']));
|
||||
|
||||
// Successful translation
|
||||
$this->assertEquals('Lorem test3!', $translator->translatePlural('foo.barf', 'foo.bar2', 3, ['test3']));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue