Skip to content

Commit

Permalink
[11.x] Fix trans_choice() when translation replacement include |
Browse files Browse the repository at this point in the history
…separator (#53331)

* [11.x] Fix `trans_choice()` when translation replacement include `|`
separator

fixes #53289

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* Apply fixes from StyleCI

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

---------

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
Co-authored-by: StyleCI Bot <bot@styleci.io>
  • Loading branch information
crynobone and StyleCIBot authored Oct 29, 2024
1 parent 5527e72 commit 8a876b6
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/Illuminate/Translation/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public function get($key, array $replace = [], $locale = null, $fallback = true)
public function choice($key, $number, array $replace = [], $locale = null)
{
$line = $this->get(
$key, $replace, $locale = $this->localeForChoice($key, $locale)
$key, [], $locale = $this->localeForChoice($key, $locale)
);

// If the given "number" is actually an array or countable we will simply count the
Expand Down
40 changes: 40 additions & 0 deletions tests/Integration/Translation/TranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Tests\Integration\Translation;

use Orchestra\Testbench\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;

class TranslatorTest extends TestCase
{
Expand All @@ -14,6 +15,7 @@ class TranslatorTest extends TestCase
*/
protected function defineEnvironment($app)
{
$app['translator']->addNamespace('tests', __DIR__.'/lang');
$app['translator']->addJsonPath(__DIR__.'/lang');

parent::defineEnvironment($app);
Expand Down Expand Up @@ -96,4 +98,42 @@ public function testItReturnsCorrectLocaleForMissingKeys()

$this->app['translator']->handleMissingKeysUsing(null);
}

#[DataProvider('greetingChoiceDataProvider')]
public function testItCanHandleChoice(int $count, string $expected, ?string $locale = null)
{
if (! is_null($locale)) {
$this->app->setLocale($locale);
}

$name = 'Taylor';

$this->assertSame(
strtr($expected, [':name' => $name, ':count' => $count]),
$this->app['translator']->choice('tests::app.greeting', $count, ['name' => $name])
);
}

#[DataProvider('greetingChoiceDataProvider')]
public function testItCanHandleChoiceWithChoiceSeparatorInReplaceString(int $count, string $expected, ?string $locale = null)
{
if (! is_null($locale)) {
$this->app->setLocale($locale);
}

$name = 'Taylor | Laravel';

$this->assertSame(
strtr($expected, [':name' => $name, ':count' => $count]),
$this->app['translator']->choice('tests::app.greeting', $count, ['name' => $name])
);
}

public static function greetingChoiceDataProvider()
{
yield [0, 'Hello :name'];
yield [3, 'Hello :name, you have 3 unread messages'];
yield [0, 'Bonjour :name', 'fr'];
yield [3, 'Bonjour :name, vous avez :count messages non lus', 'fr'];
}
}
5 changes: 5 additions & 0 deletions tests/Integration/Translation/lang/en/app.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
'greeting' => '{0} Hello :name|[1,*] Hello :name, you have :count unread messages',
];
5 changes: 5 additions & 0 deletions tests/Integration/Translation/lang/fr/app.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
'greeting' => '{0} Bonjour :name|[1,*] Bonjour :name, vous avez :count messages non lus',
];
8 changes: 4 additions & 4 deletions tests/Translation/TranslationTranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public function testGetMethodProperlyLoadsAndRetrievesItemForGlobalNamespace()
public function testChoiceMethodProperlyLoadsAndRetrievesItemForAnInt()
{
$t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();
$t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo(['replace']), $this->equalTo('en'))->willReturn('line');
$t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line');
$t->expects($this->once())->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en');
$t->setSelector($selector = m::mock(MessageSelector::class));
$selector->shouldReceive('choose')->once()->with('line', 10, 'en')->andReturn('choiced');
Expand All @@ -137,7 +137,7 @@ public function testChoiceMethodProperlyLoadsAndRetrievesItemForAnInt()
public function testChoiceMethodProperlyLoadsAndRetrievesItemForAFloat()
{
$t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();
$t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo(['replace']), $this->equalTo('en'))->willReturn('line');
$t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line');
$t->expects($this->once())->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en');
$t->setSelector($selector = m::mock(MessageSelector::class));
$selector->shouldReceive('choose')->once()->with('line', 1.2, 'en')->andReturn('choiced');
Expand All @@ -148,7 +148,7 @@ public function testChoiceMethodProperlyLoadsAndRetrievesItemForAFloat()
public function testChoiceMethodProperlyCountsCollectionsAndLoadsAndRetrievesItem()
{
$t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'localeForChoice'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();
$t->expects($this->exactly(2))->method('get')->with($this->equalTo('foo'), $this->equalTo(['replace']), $this->equalTo('en'))->willReturn('line');
$t->expects($this->exactly(2))->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line');
$t->expects($this->exactly(2))->method('localeForChoice')->with($this->equalTo('foo'), $this->equalTo(null))->willReturn('en');
$t->setSelector($selector = m::mock(MessageSelector::class));
$selector->shouldReceive('choose')->twice()->with('line', 3, 'en')->andReturn('choiced');
Expand All @@ -164,7 +164,7 @@ public function testChoiceMethodProperlySelectsLocaleForChoose()
{
$t = $this->getMockBuilder(Translator::class)->onlyMethods(['get', 'hasForLocale'])->setConstructorArgs([$this->getLoader(), 'cs'])->getMock();
$t->setFallback('en');
$t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo(['replace']), $this->equalTo('en'))->willReturn('line');
$t->expects($this->once())->method('get')->with($this->equalTo('foo'), $this->equalTo([]), $this->equalTo('en'))->willReturn('line');
$t->expects($this->once())->method('hasForLocale')->with($this->equalTo('foo'), $this->equalTo('cs'))->willReturn(false);
$t->setSelector($selector = m::mock(MessageSelector::class));
$selector->shouldReceive('choose')->once()->with('line', 10, 'en')->andReturn('choiced');
Expand Down

0 comments on commit 8a876b6

Please sign in to comment.