Skip to content

Commit

Permalink
Fixed fallback circular reference in CatalogueFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
fprochazka committed Jul 15, 2015
1 parent 9189f91 commit c414046
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -60,7 +60,8 @@
"tracy/tracy": "~2.3@dev",

"symfony/console": "~2.3",
"nette/tester": "~1.4"
"nette/tester": "~1.4",
"mockery/mockery": "~0.9"
},
"autoload": {
"psr-0": {
Expand Down
11 changes: 9 additions & 2 deletions src/Kdyby/Translation/CatalogueFactory.php
Expand Up @@ -95,13 +95,20 @@ public function createCatalogue(Translator $translator, array &$availableCatalog

$current = $availableCatalogues[$locale];

$chain = array($locale => TRUE);
foreach ($this->fallbackResolver->compute($translator, $locale) as $fallback) {
if (!isset($availableCatalogues[$fallback])) {
$this->doLoadCatalogue($availableCatalogues, $fallback);
}

$current->addFallbackCatalogue($availableCatalogues[$fallback]);
$current = $availableCatalogues[$fallback];
$newFallback = $availableCatalogues[$fallback];
if (($newFallbackFallback = $newFallback->getFallbackCatalogue()) && isset($chain[$newFallbackFallback->getLocale()])) {
break;
}

$current->addFallbackCatalogue($newFallback);
$current = $newFallback;
$chain[$fallback] = TRUE;
}

return $availableCatalogues[$locale];
Expand Down
75 changes: 75 additions & 0 deletions tests/KdybyTests/Translation/CatalogueFactory.phpt
@@ -0,0 +1,75 @@
<?php

/**
* Test: Kdyby\Translation\CatalogueFactory.
*
* @testCase KdybyTests\Translation\CatalogueFactoryTest
* @author Filip Procházka <filip@prochazka.su>
* @package Kdyby\Translation
*/

namespace KdybyTests\Translation;

use Kdyby;
use Kdyby\Translation\CatalogueFactory;
use Kdyby\Translation\FallbackResolver;
use Kdyby\Translation\TranslationLoader;
use Nette;
use Symfony;
use Tester;
use Tester\Assert;

require_once __DIR__ . '/../bootstrap.php';



/**
* @author Filip Procházka <filip@prochazka.su>
*/
class CatalogueFactoryTest extends TestCase
{

public function testCircularFallback()
{
$fallbacks = new FallbackResolver();
$fallbacks->setFallbackLocales(array('cs_CZ', 'cs'));

$loader = new TranslationLoader();
$loader->addLoader('neon', new Kdyby\Translation\Loader\NeonFileLoader());

/** @var \Kdyby\Translation\Translator|\Mockery\MockInterface $translator */
$translator = \Mockery::mock('Kdyby\Translation\Translator');
$translator->shouldReceive('getAvailableLocales')->andReturn(array('cs_CZ', 'en_US'));

$factory = new CatalogueFactory($fallbacks, $loader);
$factory->addResource('neon', __DIR__ . '/lang/front.cs_CZ.neon', 'cs_CZ', 'front');
$factory->addResource('neon', __DIR__ . '/lang/front.en_US.neon', 'en_US', 'front');

/** @var Symfony\Component\Translation\MessageCatalogueInterface[] $catalogues */
$catalogues = array();
$factory->createCatalogue($translator, $catalogues, 'cs');
Assert::truthy(isset($catalogues['cs']));
Assert::truthy(isset($catalogues['cs_CZ']));

Assert::same($catalogues['cs_CZ'], $catalogues['cs']->getFallbackCatalogue());
Assert::null($catalogues['cs_CZ']->getFallbackCatalogue());

$factory->createCatalogue($translator, $catalogues, 'en');

Assert::same($catalogues['en_US'], $catalogues['en']->getFallbackCatalogue());
Assert::same($catalogues['cs_CZ'], $catalogues['en_US']->getFallbackCatalogue());

Assert::same($catalogues['cs_CZ'], $catalogues['cs']->getFallbackCatalogue());
Assert::null($catalogues['cs_CZ']->getFallbackCatalogue());
}



protected function tearDown()
{
\Mockery::close();
}

}

\run(new CatalogueFactoryTest());

0 comments on commit c414046

Please sign in to comment.