diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index fba3dd4285..063b9359c7 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -129,11 +129,15 @@ abstract class AbstractDoctrineExtension extends Extension */ protected function setMappingDriverConfig(array $mappingConfig, $mappingName) { - if (!is_dir($mappingConfig['dir'])) { + $mappingDirectory = $mappingConfig['dir']; + if (!is_dir($mappingDirectory)) { throw new \InvalidArgumentException(sprintf('Invalid Doctrine mapping path given. Cannot load Doctrine mapping/bundle named "%s".', $mappingName)); } - $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = realpath($mappingConfig['dir']); + if (substr($mappingDirectory, 0, 7) !== 'phar://') { + $mappingDirectory = realpath($mappingDirectory); + } + $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = $mappingDirectory; } /** diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index 6e16240d29..fe0ad19367 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -14,7 +14,7 @@ namespace Symfony\Bridge\Doctrine\Form\ChoiceList; use Symfony\Component\Form\Exception\UnexpectedTypeException; use Doctrine\ORM\QueryBuilder; use Doctrine\DBAL\Connection; -use Doctrine\ORM\EntityManager; +use Doctrine\Common\Persistence\ObjectManager; /** * Loads entities using a {@link QueryBuilder} instance. @@ -43,7 +43,7 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface * deprecated and will not be * supported anymore as of * Symfony 3.0. - * @param EntityManager $manager Deprecated. + * @param ObjectManager $manager Deprecated. * @param string $class Deprecated. * * @throws UnexpectedTypeException @@ -59,8 +59,8 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface if ($queryBuilder instanceof \Closure) { @trigger_error('Passing a QueryBuilder closure to '.__CLASS__.'::__construct() is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED); - if (!$manager instanceof EntityManager) { - throw new UnexpectedTypeException($manager, 'Doctrine\ORM\EntityManager'); + if (!$manager instanceof ObjectManager) { + throw new UnexpectedTypeException($manager, 'Doctrine\Common\Persistence\ObjectManager'); } @trigger_error('Passing an EntityManager to '.__CLASS__.'::__construct() is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED); diff --git a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php index a4c19cdb6a..592584ffa4 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php @@ -120,7 +120,12 @@ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscribe */ public function onCommand(ConsoleCommandEvent $event) { - $this->setOutput($event->getOutput()); + $output = $event->getOutput(); + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + + $this->setOutput($output); } /** @@ -149,11 +154,7 @@ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscribe */ protected function write(array $record) { - if ($record['level'] >= Logger::ERROR && $this->output instanceof ConsoleOutputInterface) { - $this->output->getErrorOutput()->write((string) $record['formatted']); - } else { - $this->output->write((string) $record['formatted']); - } + $this->output->write((string) $record['formatted']); } /** diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index 65f259693b..6cb315967e 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -110,7 +110,7 @@ class ConsoleHandlerTest extends \PHPUnit_Framework_TestCase public function testWritingAndFormatting() { - $output = $this->getMock('Symfony\Component\Console\Output\ConsoleOutputInterface'); + $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); $output ->expects($this->any()) ->method('getVerbosity') @@ -122,19 +122,6 @@ class ConsoleHandlerTest extends \PHPUnit_Framework_TestCase ->with('[2013-05-29 16:21:54] app.INFO: My info message '."\n") ; - $errorOutput = $this->getMock('Symfony\Component\Console\Output\OutputInterface'); - $errorOutput - ->expects($this->once()) - ->method('write') - ->with('[2013-05-29 16:21:54] app.ERROR: My error message '."\n") - ; - - $output - ->expects($this->any()) - ->method('getErrorOutput') - ->will($this->returnValue($errorOutput)) - ; - $handler = new ConsoleHandler(null, false); $handler->setOutput($output); @@ -149,18 +136,6 @@ class ConsoleHandlerTest extends \PHPUnit_Framework_TestCase ); $this->assertTrue($handler->handle($infoRecord), 'The handler finished handling the log as bubble is false.'); - - $errorRecord = array( - 'message' => 'My error message', - 'context' => array(), - 'level' => Logger::ERROR, - 'level_name' => Logger::getLevelName(Logger::ERROR), - 'channel' => 'app', - 'datetime' => new \DateTime('2013-05-29 16:21:54'), - 'extra' => array(), - ); - - $this->assertTrue($handler->handle($errorRecord), 'The handler finished handling the log as bubble is false.'); } public function testLogsFromListeners() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php new file mode 100644 index 0000000000..a04a0cccad --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/TranslationUpdateCommandTest.php @@ -0,0 +1,141 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Command; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Bundle\FrameworkBundle\Command\TranslationUpdateCommand; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\DependencyInjection; +use Symfony\Component\HttpKernel; + +class TranslationUpdateCommandTest extends \PHPUnit_Framework_TestCase +{ + private $fs; + private $translationDir; + + public function testDumpMessagesAndClean() + { + $tester = $this->createCommandTester($this->getContainer(array('foo' => 'foo'))); + $tester->execute(array('command' => 'translation:update', 'locale' => 'en', 'bundle' => 'foo', '--dump-messages' => true, '--clean' => true)); + $this->assertRegExp('/foo/', $tester->getDisplay()); + } + + protected function setUp() + { + $this->fs = new Filesystem(); + $this->translationDir = sys_get_temp_dir().'/'.uniqid('sf2_translation', true); + $this->fs->mkdir($this->translationDir.'/Resources/translations'); + $this->fs->mkdir($this->translationDir.'/Resources/views'); + } + + protected function tearDown() + { + $this->fs->remove($this->translationDir); + } + + /** + * @return CommandTester + */ + private function createCommandTester(DependencyInjection\ContainerInterface $container) + { + $command = new TranslationUpdateCommand(); + $command->setContainer($container); + + $application = new Application(); + $application->add($command); + + return new CommandTester($application->find('translation:update')); + } + + private function getContainer($extractedMessages = array(), $loadedMessages = array(), HttpKernel\KernelInterface $kernel = null) + { + $translator = $this->getMockBuilder('Symfony\Component\Translation\Translator') + ->disableOriginalConstructor() + ->getMock(); + + $translator + ->expects($this->any()) + ->method('getFallbackLocales') + ->will($this->returnValue(array('en'))); + + $extractor = $this->getMock('Symfony\Component\Translation\Extractor\ExtractorInterface'); + $extractor + ->expects($this->any()) + ->method('extract') + ->will( + $this->returnCallback(function ($path, $catalogue) use ($extractedMessages) { + $catalogue->add($extractedMessages); + }) + ); + + $loader = $this->getMock('Symfony\Bundle\FrameworkBundle\Translation\TranslationLoader'); + $loader + ->expects($this->any()) + ->method('loadMessages') + ->will( + $this->returnCallback(function ($path, $catalogue) use ($loadedMessages) { + $catalogue->add($loadedMessages); + }) + ); + + $writer = $this->getMock('Symfony\Component\Translation\Writer\TranslationWriter'); + $writer + ->expects($this->any()) + ->method('getFormats') + ->will( + $this->returnValue(array('xlf', 'yml')) + ); + + if (null === $kernel) { + $kernel = $this->getMock('Symfony\Component\HttpKernel\KernelInterface'); + $kernel + ->expects($this->any()) + ->method('getBundle') + ->will($this->returnValueMap(array( + array('foo', true, $this->getBundle($this->translationDir)), + array('test', true, $this->getBundle('test')), + ))); + } + + $kernel + ->expects($this->any()) + ->method('getRootDir') + ->will($this->returnValue($this->translationDir)); + + $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $container + ->expects($this->any()) + ->method('get') + ->will($this->returnValueMap(array( + array('translation.extractor', 1, $extractor), + array('translation.loader', 1, $loader), + array('translation.writer', 1, $writer), + array('translator', 1, $translator), + array('kernel', 1, $kernel), + ))); + + return $container; + } + + private function getBundle($path) + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\BundleInterface'); + $bundle + ->expects($this->any()) + ->method('getPath') + ->will($this->returnValue($path)) + ; + + return $bundle; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index c7b61cb881..043cd11518 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -273,7 +273,7 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase // prime the cache $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles), 'yml'); - $translator->setLocale('fr'); + $translator->setFallbackLocales(array('fr')); $translator->warmup($this->tmpDir); $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface'); @@ -283,6 +283,7 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase $translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles), 'yml'); $translator->setLocale('fr'); + $translator->setFallbackLocales(array('fr')); $this->assertEquals('répertoire', $translator->trans('folder')); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index 9cc92f9c2d..fba6d70d69 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -82,7 +82,13 @@ class Translator extends BaseTranslator implements WarmableInterface return; } - foreach ($this->resourceLocales as $locale) { + $locales = array_merge($this->getFallbackLocales(), array($this->getLocale()), $this->resourceLocales); + foreach (array_unique($locales) as $locale) { + // reset catalogue in case it's already loaded during the dump of the other locales. + if (isset($this->catalogues[$locale])) { + unset($this->catalogues[$locale]); + } + $this->loadCatalogue($locale); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index d191b010e7..eafa086d4f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -52,6 +52,7 @@ "symfony/console": "For using the console commands", "symfony/finder": "For using the translation loader and cache warmer", "symfony/form": "For using forms", + "symfony/serializer": "For using the serializer service", "symfony/validator": "For using validation", "symfony/yaml": "For using the debug:config and lint:yaml commands", "doctrine/cache": "For using alternative cache drivers" diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig index e4fea4b00b..53ca5591d3 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig @@ -1,7 +1,7 @@ {% if 'normal' != position %}
- getFileName(); @@ -289,7 +303,7 @@ class DebugClassLoader if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true) && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false) ) { - throw new \RuntimeException(sprintf('Case mismatch between class and source file names: %s vs %s', $class, $real)); + throw new \RuntimeException(sprintf('Case mismatch between class and real file names: %s vs %s in %s', substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1))); } } diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index a368a7d257..1516dbedf9 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -136,7 +136,7 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase /** * @expectedException \RuntimeException - * @expectedExceptionMessage Case mismatch between class and source file names + * @expectedExceptionMessage Case mismatch between class and real file names */ public function testFileCaseMismatch() { diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index ee2b26200b..74a7ed4f1a 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -328,7 +328,7 @@ class YamlFileLoader extends FileLoader try { $configuration = $this->yamlParser->parse(file_get_contents($file)); } catch (ParseException $e) { - throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $file), 0, $e); + throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $file), 0, $e); } return $this->validate($configuration, $file); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/bad_format.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/bad_format.yml new file mode 100644 index 0000000000..1f58cac6ac --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/bad_format.yml @@ -0,0 +1,2 @@ +parameters: + FOO: bar diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index 45f1cb496d..2d1b0b6956 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -88,6 +88,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase array('bad_services'), array('bad_service'), array('bad_calls'), + array('bad_format'), ); } diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index 0ab6b98221..80a83b6e89 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -790,7 +790,7 @@ class Crawler extends \SplObjectStorage throw new \InvalidArgumentException('The current node list is empty.'); } - $form = new Form($this->getNode(0), $this->uri, $method); + $form = new Form($this->getNode(0), $this->uri, $method, $this->baseHref); if (null !== $values) { $form->setValues($values); diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index bf7ce5d554..d95fb07ffc 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -33,20 +33,27 @@ class Form extends Link implements \ArrayAccess */ private $fields; + /** + * @var string + */ + private $baseHref; + /** * Constructor. * * @param \DOMElement $node A \DOMElement instance * @param string $currentUri The URI of the page where the form is embedded * @param string $method The method to use for the link (if null, it defaults to the method defined by the form) + * @param string $baseHref The URI of the used for relative links, but not for empty action * * @throws \LogicException if the node is not a button inside a form tag * * @api */ - public function __construct(\DOMElement $node, $currentUri, $method = null) + public function __construct(\DOMElement $node, $currentUri, $method = null, $baseHref = null) { parent::__construct($node, $currentUri, $method); + $this->baseHref = $baseHref; $this->initialize(); } @@ -458,6 +465,10 @@ class Form extends Link implements \ArrayAccess $this->addField($node); } } + + if ($this->baseHref && '' !== $this->node->getAttribute('action')) { + $this->currentUri = $this->baseHref; + } } private function addField(\DOMElement $node) diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php index 9560d06999..4cfd06f5c5 100755 --- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php @@ -982,9 +982,12 @@ HTML; public function getBaseTagWithFormData() { return array( + array('https://base.com/', 'link/', 'https://base.com/link/', 'https://base.com/link/', ' tag does work with a path and relative form action'), array('/basepath', '/registration', 'http://domain.com/registration', 'http://domain.com/registration', ' tag does work with a path and form action'), array('/basepath', '', 'http://domain.com/registration', 'http://domain.com/registration', ' tag does work with a path and empty form action'), + array('http://base.com/', '/registration', 'http://base.com/registration', 'http://domain.com/registration', ' tag does work with a URL and form action'), array('http://base.com', '', 'http://domain.com/path/form', 'http://domain.com/path/form', ' tag does work with a URL and an empty form action'), + array('http://base.com/path', '/registration', 'http://base.com/registration', 'http://domain.com/path/form', ' tag does work with a URL and form action'), ); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/ClockMock.php b/src/Symfony/Component/HttpFoundation/Tests/ClockMock.php index 04a842d9b5..c74605fe95 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ClockMock.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ClockMock.php @@ -18,7 +18,22 @@ function time($asFloat = false) namespace Symfony\Component\HttpFoundation\Tests; +function with_clock_mock($enable = null) +{ + static $enabled; + + if (null === $enable) { + return $enabled; + } + + $enabled = $enable; +} + function time() { + if (!with_clock_mock()) { + return \time(); + } + return $_SERVER['REQUEST_TIME']; } diff --git a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php index b8474db15f..9d794c3d6f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php @@ -23,6 +23,18 @@ require_once __DIR__.'/ClockMock.php'; */ class CookieTest extends \PHPUnit_Framework_TestCase { + public function setUp() + { + with_clock_mock(true); + parent::setUp(); + } + + public function tearDown() + { + with_clock_mock(false); + parent::tearDown(); + } + public function invalidNames() { return array( diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php index 0fa198e098..a4a22139f8 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php @@ -18,6 +18,18 @@ require_once __DIR__.'/ClockMock.php'; class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase { + public function setUp() + { + with_clock_mock(true); + parent::setUp(); + } + + public function tearDown() + { + with_clock_mock(false); + parent::tearDown(); + } + /** * @covers Symfony\Component\HttpFoundation\ResponseHeaderBag::allPreserveCase * @dataProvider provideAllPreserveCase diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php index efb0bb3e6e..e0d7d50f6b 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -98,9 +98,9 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof \Twig_Template) { $info = $trace[$i]['object']; $name = $info->getTemplateName(); - $src = $info->getEnvironment()->getLoader()->getSource($name); + $src = method_exists($info, 'getSource') ? $info->getSource() : $info->getEnvironment()->getLoader()->getSource($name); $info = $info->getDebugInfo(); - if (isset($info[$trace[$i - 1]['line']])) { + if (null !== $src && isset($info[$trace[$i - 1]['line']])) { $file = false; $line = $info[$trace[$i - 1]['line']]; $src = explode("\n", $src); diff --git a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php index e4e0a4be6f..e40ba0269c 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/Esi.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/Esi.php @@ -213,8 +213,8 @@ class Esi implements SurrogateInterface // we don't use a proper XML parser here as we can have ESI tags in a plain text response $content = $response->getContent(); - $content = preg_replace('#.*?#', '', $content); - $content = preg_replace('#]*(?:/|#', '', $content); + $content = preg_replace('#.*?#s', '', $content); + $content = preg_replace('#]+>#s', '', $content); $chunks = preg_split('##', $content, -1, PREG_SPLIT_DELIM_CAPTURE); $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]); diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php index 00a9367600..0d52ce89db 100644 --- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/EsiTest.php @@ -92,6 +92,28 @@ class EsiTest extends \PHPUnit_Framework_TestCase $this->assertFalse($response->headers->has('x-body-eval')); } + public function testMultilineEsiRemoveTagsAreRemoved() + { + $esi = new Esi(); + + $request = Request::create('/'); + $response = new Response(' www.example.com Keep this'."\n www.example.com And this"); + $esi->process($request, $response); + + $this->assertEquals(' Keep this And this', $response->getContent()); + } + + public function testCommentTagsAreRemoved() + { + $esi = new Esi(); + + $request = Request::create('/'); + $response = new Response(' Keep this'); + $esi->process($request, $response); + + $this->assertEquals(' Keep this', $response->getContent()); + } + public function testProcess() { $esi = new Esi(); diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/bad_format.yml b/src/Symfony/Component/Routing/Tests/Fixtures/bad_format.yml new file mode 100644 index 0000000000..8ba50e2e42 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/Fixtures/bad_format.yml @@ -0,0 +1,3 @@ +blog_show: + path: /blog/{slug} + defaults: { _controller: "MyBundle:Blog:show" } diff --git a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php index 17e07dab19..de1542040b 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php @@ -51,7 +51,15 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase public function getPathsToInvalidFiles() { - return array(array('nonvalid.yml'), array('nonvalid2.yml'), array('incomplete.yml'), array('nonvalidkeys.yml'), array('nonesense_resource_plus_path.yml'), array('nonesense_type_without_resource.yml')); + return array( + array('nonvalid.yml'), + array('nonvalid2.yml'), + array('incomplete.yml'), + array('nonvalidkeys.yml'), + array('nonesense_resource_plus_path.yml'), + array('nonesense_type_without_resource.yml'), + array('bad_format.yml'), + ); } public function testLoadSpecialRouteName() diff --git a/src/Symfony/Component/Stopwatch/Tests/ClockMock.php b/src/Symfony/Component/Stopwatch/Tests/ClockMock.php index 5bbe6b1db8..718296cc5b 100644 --- a/src/Symfony/Component/Stopwatch/Tests/ClockMock.php +++ b/src/Symfony/Component/Stopwatch/Tests/ClockMock.php @@ -18,10 +18,27 @@ function microtime($asFloat = false) namespace Symfony\Component\Stopwatch\Tests; +function with_clock_mock($enable = null) +{ + static $enabled; + + if (null === $enable) { + return $enabled; + } + + $enabled = $enable; +} + function usleep($us) { static $now; + if (!with_clock_mock()) { + \usleep($us); + + return; + } + if (null === $now) { $now = \microtime(true); } @@ -31,6 +48,10 @@ function usleep($us) function microtime($asFloat = false) { + if (!with_clock_mock()) { + return \microtime($asFloat); + } + if (!$asFloat) { return \microtime(false); } diff --git a/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php b/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php index 4386d94fca..ce69d305c8 100644 --- a/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php +++ b/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php @@ -24,6 +24,18 @@ class StopwatchEventTest extends \PHPUnit_Framework_TestCase { const DELTA = 37; + public function setUp() + { + with_clock_mock(true); + parent::setUp(); + } + + public function tearDown() + { + with_clock_mock(false); + parent::tearDown(); + } + public function testGetOrigin() { $event = new StopwatchEvent(12); diff --git a/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php b/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php index 0d05e8f800..b83a502e33 100644 --- a/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php +++ b/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php @@ -24,6 +24,18 @@ class StopwatchTest extends \PHPUnit_Framework_TestCase { const DELTA = 20; + public function setUp() + { + with_clock_mock(true); + parent::setUp(); + } + + public function tearDown() + { + with_clock_mock(false); + parent::tearDown(); + } + public function testStart() { $stopwatch = new Stopwatch(); diff --git a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php index ea4e2641a6..cf6dd92dca 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php @@ -121,7 +121,7 @@ class YamlFileLoader extends FileLoader try { $classes = $this->yamlParser->parse(file_get_contents($path)); } catch (ParseException $e) { - throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid.', $path), 0, $e); + throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e); } // empty file diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php index 407e36958e..2ca64122aa 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php @@ -33,15 +33,26 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase $this->assertFalse($loader->loadClassMetadata($metadata)); } - public function testLoadClassMetadataThrowsExceptionIfNotAnArray() + /** + * @dataProvider provideInvalidYamlFiles + * @expectedException \InvalidArgumentException + */ + public function testInvalidYamlFiles($path) { - $loader = new YamlFileLoader(__DIR__.'/nonvalid-mapping.yml'); + $loader = new YamlFileLoader(__DIR__.'/'.$path); $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'); - $this->setExpectedException('\InvalidArgumentException'); $loader->loadClassMetadata($metadata); } + public function provideInvalidYamlFiles() + { + return array( + array('nonvalid-mapping.yml'), + array('bad-format.yml'), + ); + } + /** * @see https://github.com/symfony/symfony/pull/12158 */ diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml new file mode 100644 index 0000000000..d2b4ad2654 --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/bad-format.yml @@ -0,0 +1,9 @@ +namespaces: + custom: Symfony\Component\Validator\Tests\Fixtures\ + +Symfony\Component\Validator\Tests\Fixtures\Entity: + constraints: + # Custom constraint + - Symfony\Component\Validator\Tests\Fixtures\ConstraintA: ~ + # Custom constraint with namespaces prefix + - "custom:ConstraintB": ~ diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index ad7ae498ff..651c017049 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -135,6 +135,11 @@ class Parser throw $e; } + // Convert float keys to strings, to avoid being converted to integers by PHP + if (is_float($key)) { + $key = (string) $key; + } + if ('<<' === $key) { $mergeNode = true; $allowOverwrite = true; diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index f434d5585d..08ef43faa5 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -747,6 +747,24 @@ bar: 2 EOF; $this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml)); } + + public function testFloatKeys() + { + $yaml = << array( + '1.2' => 'bar', + '1.3' => 'baz', + ), + ); + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } } class B