Skip to content

Commit

Permalink
[11.x] Use correct pluralization rules in trans_choice for fallback s…
Browse files Browse the repository at this point in the history
…trings (#52343)

* localeForChoice returns fallback if key doesn't exist

* Fix tests and test that choose uses correct callback

* Only check hasForLocale once in localeForChoice
  • Loading branch information
stefanvdlugt authored Aug 1, 2024
1 parent fd9e84e commit c034a2c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
9 changes: 6 additions & 3 deletions src/Illuminate/Translation/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,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($locale)
$key, $replace, $locale = $this->localeForChoice($key, $locale)
);

// If the given "number" is actually an array or countable we will simply count the
Expand All @@ -211,12 +211,15 @@ public function choice($key, $number, array $replace = [], $locale = null)
/**
* Get the proper locale for a choice operation.
*
* @param string $key
* @param string|null $locale
* @return string
*/
protected function localeForChoice($locale)
protected function localeForChoice($key, $locale)
{
return $locale ?: $this->locale ?: $this->fallback;
$locale = $locale ?: $this->locale;

return $this->hasForLocale($key, $locale) ? $locale : $this->fallback;
}

/**
Expand Down
21 changes: 18 additions & 3 deletions tests/Translation/TranslationTranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ public function testGetMethodProperlyLoadsAndRetrievesItemForGlobalNamespace()

public function testChoiceMethodProperlyLoadsAndRetrievesItemForAnInt()
{
$t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();
$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('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 @@ -135,8 +136,9 @@ public function testChoiceMethodProperlyLoadsAndRetrievesItemForAnInt()

public function testChoiceMethodProperlyLoadsAndRetrievesItemForAFloat()
{
$t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();
$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('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 @@ -145,8 +147,9 @@ public function testChoiceMethodProperlyLoadsAndRetrievesItemForAFloat()

public function testChoiceMethodProperlyCountsCollectionsAndLoadsAndRetrievesItem()
{
$t = $this->getMockBuilder(Translator::class)->onlyMethods(['get'])->setConstructorArgs([$this->getLoader(), 'en'])->getMock();
$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('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 @@ -157,6 +160,18 @@ public function testChoiceMethodProperlyCountsCollectionsAndLoadsAndRetrievesIte
$t->choice('foo', $values, ['replace']);
}

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('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');

$t->choice('foo', 10, ['replace']);
}

public function testGetJson()
{
$t = new Translator($this->getLoader(), 'en');
Expand Down

0 comments on commit c034a2c

Please sign in to comment.