Merge pull request #681 from munkie/fix-view-cache

Fix CachingApiDocExtractor caches only first accessed view
This commit is contained in:
William Durand 2015-07-29 11:00:30 +02:00
commit 4351ca66d3
3 changed files with 125 additions and 9 deletions

View File

@ -28,12 +28,26 @@ use Symfony\Component\Routing\RouterInterface;
class CachingApiDocExtractor extends ApiDocExtractor
{
/**
* @var \Symfony\Component\Config\ConfigCache
* @var string
*/
protected $cache;
private $cacheFile;
protected $cacheFile;
/**
* @var bool
*/
private $debug;
/**
* @param ContainerInterface $container
* @param RouterInterface $router
* @param Reader $reader
* @param DocCommentExtractor $commentExtractor
* @param ControllerNameParser $controllerNameParser
* @param array $handlers
* @param array $annotationsProviders
* @param string $cacheFile
* @param bool|false $debug
*/
public function __construct(
ContainerInterface $container,
RouterInterface $router,
@ -46,13 +60,20 @@ class CachingApiDocExtractor extends ApiDocExtractor
$debug = false
) {
parent::__construct($container, $router, $reader, $commentExtractor, $controllerNameParser, $handlers, $annotationsProviders);
$this->cacheFile = $cacheFile;
$this->cache = new ConfigCache($this->cacheFile, $debug);
$this->debug = $debug;
}
/**
* @param string $view View name
* @return array|mixed
*/
public function all($view = ApiDoc::DEFAULT_VIEW)
{
if ($this->cache->isFresh() === false) {
$cache = $this->getViewCache($view);
if ($cache->isFresh() === false) {
$resources = array();
@ -67,12 +88,23 @@ class CachingApiDocExtractor extends ApiDocExtractor
$resources = array_merge($resources, $this->router->getRouteCollection()->getResources());
$data = parent::all($view);
$this->cache->write(serialize($data), $resources);
$cache->write(serialize($data), $resources);
return $data;
}
return unserialize(file_get_contents($this->cacheFile));
return unserialize(file_get_contents($cache));
}
/**
* @param string $view
* @return ConfigCache
*/
private function getViewCache($view)
{
return new ConfigCache($this->cacheFile.'.'.$view, $this->debug);
}
}

View File

@ -47,9 +47,9 @@ class ApiDocExtractorTest extends WebTestCase
$this->assertTrue(is_array($data));
$this->assertCount(self::$ROUTES_QUANTITY_DEFAULT, $data);
$cacheFile = $container->getParameter('kernel.cache_dir') . '/api-doc.cache';
$cacheFile = $container->getParameter('kernel.cache_dir') . '/api-doc.cache.' . ApiDoc::DEFAULT_VIEW;
$this->assertFileExists($cacheFile);
$this->assertEquals(file_get_contents($cacheFile), serialize($data));
$this->assertStringEqualsFile($cacheFile, serialize($data));
foreach ($data as $key => $d) {
$this->assertTrue(is_array($d));

View File

@ -0,0 +1,84 @@
<?php
namespace Nelmio\ApiDocBundle\Tests\Extractor;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Nelmio\ApiDocBundle\Extractor\CachingApiDocExtractor;
use Nelmio\ApiDocBundle\Tests\WebTestCase;
class CachingApiDocExtractorTest extends WebTestCase
{
/**
* @return array
*/
public static function viewsWithoutDefaultProvider()
{
$data = ApiDocExtractorTest::dataProviderForViews();
// remove default view data from provider
array_shift($data);
return $data;
}
/**
* Test that every view cache is saved in its own cache file
*
* @dataProvider viewsWithoutDefaultProvider
* @param string $view View name
*/
public function testDifferentCacheFilesAreCreatedForDifferentViews($view)
{
$container = $this->getContainer();
/* @var CachingApiDocExtractor $extractor */
$extractor = $container->get('nelmio_api_doc.extractor.api_doc_extractor');
$this->assertInstanceOf('\Nelmio\ApiDocBundle\Extractor\CachingApiDocExtractor', $extractor);
set_error_handler(array($this, 'handleDeprecation'));
$defaultData = $extractor->all(ApiDoc::DEFAULT_VIEW);
$data = $extractor->all($view);
restore_error_handler();
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $data);
$this->assertNotSameSize($defaultData, $data);
$this->assertNotEquals($defaultData, $data);
$cacheFile = $container->getParameter('kernel.cache_dir').'/api-doc.cache';
$expectedDefaultViewCacheFile = $cacheFile.'.'.ApiDoc::DEFAULT_VIEW;
$expectedViewCacheFile = $cacheFile.'.'.$view;
$this->assertFileExists($expectedDefaultViewCacheFile);
$this->assertFileExists($expectedViewCacheFile);
$this->assertFileNotEquals($expectedDefaultViewCacheFile, $expectedViewCacheFile);
}
/**
* @dataProvider \Nelmio\ApiDocBundle\Tests\Extractor\ApiDocExtractorTest::dataProviderForViews
* @param string $view View name to test
*/
public function testCachedResultSameAsGenerated($view)
{
$container = $this->getContainer();
/* @var CachingApiDocExtractor $extractor */
$extractor = $container->get('nelmio_api_doc.extractor.api_doc_extractor');
$this->assertInstanceOf('\Nelmio\ApiDocBundle\Extractor\CachingApiDocExtractor', $extractor);
$cacheFile = $container->getParameter('kernel.cache_dir').'/api-doc.cache';
$expectedViewCacheFile = $cacheFile.'.'.$view;
$this->assertFileNotExists($expectedViewCacheFile);
set_error_handler(array($this, 'handleDeprecation'));
$data = $extractor->all($view);
$this->assertFileExists($expectedViewCacheFile);
$cachedData = $extractor->all($view);
restore_error_handler();
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $data);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $cachedData);
$this->assertSameSize($data, $cachedData);
$this->assertEquals($data, $cachedData);
}
}