Skip to content

Commit

Permalink
Remove Translator-related interfaces that were deprecated in Symfony …
Browse files Browse the repository at this point in the history
…^4.2 (#28)

After #29 (released as `0.8.0`) implemented the new interfaces from `symfony/translation-contracts` in addition to the deprecated ones, this PR drops support for the old `\Symfony\Component\Translation\TranslatorInterface`.
  • Loading branch information
mpdude authored Feb 1, 2022
1 parent f910c37 commit 5a7abb0
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 119 deletions.
76 changes: 18 additions & 58 deletions src/Translator/FormatterDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,36 @@

namespace Webfactory\IcuTranslationBundle\Translator;

use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
use Symfony\Contracts\Translation\LocaleAwareInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Webfactory\IcuTranslationBundle\Translator\Formatting\FormatterInterface;
use Webfactory\IcuTranslationBundle\Translator\Formatting\IntlFormatter;

/**
* Decorates a Symfony translator and adds support for message formatting.
*/
class FormatterDecorator implements LegacyTranslatorInterface, TranslatorInterface
class FormatterDecorator implements TranslatorInterface, LocaleAwareInterface
{
/**
* The inner translator.
*
* @var \Symfony\Component\Translation\TranslatorInterface
* @var TranslatorInterface
*/
protected $translator;

/**
* The formatter that is used to apply message transformations.
*
* @var \Webfactory\IcuTranslationBundle\Translator\Formatting\IntlFormatter
* @var IntlFormatter
*/
protected $formatter;

/**
* Creates a decorator for the provided translator.
*
* @param \Webfactory\IcuTranslationBundle\Translator\Formatting\FormatterInterface the formatter that is used
*/
public function __construct(LegacyTranslatorInterface $translator, FormatterInterface $formatter)
public function __construct(TranslatorInterface $translator, FormatterInterface $formatter)
{
if (!$translator instanceof LocaleAwareInterface) {
throw new \InvalidArgumentException(sprintf('The translator passed to "%s()" must implement "%s".', __METHOD__, LocaleAwareInterface::class));
}

$this->translator = $translator;
$this->formatter = $formatter;
}
Expand All @@ -43,34 +43,14 @@ public function __construct(LegacyTranslatorInterface $translator, FormatterInte
* @param array $parameters An array of parameters for the message
* @param string $domain The domain for the message
* @param string $locale The locale
*
* @return string The translated string
*/
public function trans($id, array $parameters = [], $domain = null, $locale = null)
public function trans($id, array $parameters = [], $domain = null, $locale = null): string
{
$message = $this->translator->trans($id, $parameters, $domain, $locale);

return $this->handleFormatting($id, $message, $parameters, $locale);
}

/**
* Translates the given choice message by choosing a translation according to a number.
*
* @param string $id The message id
* @param int $number The number to use to find the indice of the message
* @param array $parameters An array of parameters for the message
* @param string $domain The domain for the message
* @param string $locale The locale
*
* @return string The translated string
*/
public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null)
{
$message = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);

return $this->handleFormatting($id, $message, $parameters, $locale);
}

/**
* Sets the current locale.
*
Expand All @@ -81,35 +61,25 @@ public function setLocale($locale)
$this->translator->setLocale($locale);
}

/**
* Returns the current locale.
*
* @return string The locale
*/
public function getLocale()
public function getLocale(): string
{
return $this->translator->getLocale();
}

/**
* Formats the message if possible and throws a normalized exception in case of error.
*
* @param string $id the translation message ID
* @param string $message the message pattern that will be used for formatting
* @param array(mixed) $parameters
* @param string|null $locale
*
* @return string the formatted message
*
* @throws \Webfactory\IcuTranslationBundle\Translator\FormattingException if formatting fails
*/
protected function handleFormatting($id, $message, array $parameters, $locale)
protected function handleFormatting(string $id, string $message, array $parameters = [], string $locale = null): string
{
if (empty($message)) {
// No formatting needed.
return $message;
}

$locale = $this->toLocale($locale);

try {
return $this->format($message, $parameters, $locale);
} catch (\Exception $e) {
Expand All @@ -119,14 +89,8 @@ protected function handleFormatting($id, $message, array $parameters, $locale)

/**
* Applies Intl formatting on the provided message.
*
* @param string $message
* @param array(mixed) $parameters
* @param string $locale
*
* @return string
*/
protected function format($message, array $parameters, $locale)
protected function format(string $message, array $parameters = [], string $locale = null): string
{
return $this->formatter->format($locale, $message, $parameters);
}
Expand All @@ -136,13 +100,9 @@ protected function format($message, array $parameters, $locale)
*
* If a correct locale is provided that one is used.
* Otherwise, the default locale is returned.
*
* @param string|null $locale
*
* @return string
*/
protected function toLocale($locale = null)
protected function toLocale(string $locale = null): string
{
return (null === $locale) ? $this->getLocale() : $locale;
return $locale ?? $this->getLocale();
}
}
2 changes: 1 addition & 1 deletion src/Twig/IcuFormattingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Webfactory\IcuTranslationBundle\Twig;

use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Webfactory\IcuTranslationBundle\Translator\Formatting\FormatterInterface;
Expand Down
2 changes: 1 addition & 1 deletion tests/Functional/SymfonyIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Webfactory\TranslationBundle\Tests\Functional;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Webfactory\IcuTranslationBundle\Translator\FormatterDecorator;

class SymfonyIntegrationTest extends KernelTestCase
Expand Down
11 changes: 0 additions & 11 deletions tests/Functional/TranslationFormattingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,6 @@ public function translatorResolvesSelectExpressionCorrectly()
self::assertEquals('She is tested.', $this->translator->trans($message, ['%gender%' => 'female']));
}

/**
* Ensures that the translator formats messages that are returned by transChoice().
*
* @test
*/
public function translatorFormatsMessagesReturnedByTransChoice()
{
$message = 'We need {0,number,integer} tests.';
self::assertEquals('We need 42 tests.', $this->translator->transChoice($message, 7, ['%0%' => 42]));
}

/**
* Ensures that the translator resolves an expression as expected when the checked variable
* is not passed.
Expand Down
70 changes: 22 additions & 48 deletions tests/Translator/FormatterDecoratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

namespace Webfactory\IcuTranslationBundle\Tests\Translator;

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\Translation\LocaleAwareInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Webfactory\IcuTranslationBundle\Translator\FormatterDecorator;
use Webfactory\IcuTranslationBundle\Translator\Formatting\FormatterInterface;
use Webfactory\IcuTranslationBundle\Translator\FormattingException;

/**
Expand All @@ -14,21 +18,21 @@ class FormatterDecoratorTest extends TestCase
/**
* System under test.
*
* @var \Webfactory\IcuTranslationBundle\Translator\FormatterDecorator
* @var FormatterDecorator
*/
protected $decorator = null;

/**
* The simulated inner translator.
*
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $translator = null;

/**
* The mocked formatter that is used in the tests.
*
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $formatter = null;

Expand All @@ -38,33 +42,22 @@ class FormatterDecoratorTest extends TestCase
protected function setUp(): void
{
parent::setUp();
$this->translator = $this->createMock('Symfony\Component\Translation\TranslatorInterface');
$this->formatter = $this->createMock('Webfactory\IcuTranslationBundle\Translator\Formatting\FormatterInterface');
$this->translator = $this->createMock(LocaleAwareTranslator::class);
$this->formatter = $this->createMock(FormatterInterface::class);
$this->decorator = new FormatterDecorator(
$this->translator,
$this->formatter
);
}

/**
* Cleans up the test environment.
*/
protected function tearDown(): void
{
$this->decorator = null;
$this->formatter = null;
$this->translator = null;
parent::tearDown();
}

/**
* Checks if the decorator implements the Translator interface.
*
* @test
*/
public function implementsTranslatorInterface()
{
$this->assertInstanceOf('Symfony\Component\Translation\TranslatorInterface', $this->decorator);
$this->assertInstanceOf(TranslatorInterface::class, $this->decorator);
}

/**
Expand All @@ -76,37 +69,12 @@ public function decoratorForwardsTransCalls()
{
$this->translator->expects($this->once())
->method('trans')
->with('test', ['foo' => 'bar'], 'domain', 'locale')
->willReturn('test');

$this->decorator->trans('test');
}

/**
* Checks if the decorator forwards calls to transChoice() to the inner translator.
*
* @test
*/
public function decoratorForwardsTransChoiceCalls()
{
$this->translator->expects($this->once())
->method('transChoice')
->willReturn('test');

$this->decorator->transChoice('test', 42);
}
$this->formatter->method('format')->willReturn('some string');

/**
* Checks if the decorator forwards calls to setLocale() to the inner translator.
*
* @test
*/
public function decoratorForwardsSetLocaleCalls()
{
$this->translator->expects($this->once())
->method('setLocale')
->with('de_DE');

$this->decorator->setLocale('de_DE');
$this->decorator->trans('test', ['foo' => 'bar'], 'domain', 'locale');
}

/**
Expand All @@ -130,14 +98,16 @@ public function getLocaleReturnsLocaleFromInnerTranslator()
*/
public function decoratorPassesResultFromTranslatorToFormatter()
{
$this->translator->method('getLocale')->willReturn('some_locale');
$this->translator->expects($this->once())
->method('trans')
->willReturn('test message');
$this->formatter->expects($this->once())
->method('format')
->with($this->anything(), 'test message');
->with($this->anything(), 'test message')
->willReturn('some string');

$this->decorator->trans('message_id');
$this->decorator->trans('message_id', ['foo' => 'bar'], 'domain', 'locale');
}

/**
Expand All @@ -155,7 +125,7 @@ public function decoratorReturnsResultFromFormatter()
->method('format')
->willReturn('formatted message');

$translated = $this->decorator->trans('message_id');
$translated = $this->decorator->trans('message_id', ['foo' => 'bar'], 'domain', 'locale');

$this->assertEquals('formatted message', $translated);
}
Expand All @@ -178,3 +148,7 @@ public function decoratorNormalizesFormatterException()
$this->decorator->trans('test', ['test' => 'value'], 'messages', 'en');
}
}

interface LocaleAwareTranslator extends TranslatorInterface, LocaleAwareInterface
{
}

0 comments on commit 5a7abb0

Please sign in to comment.