Merge branch '2.7' into 2.8
* 2.7: [DomCrawler] Invalid uri created from forms if base tag present [Console] update param type phpdoc for StreamOutput [Console] fix typo in OutputInterface Use stderr by default when a specific output is not injected [Debug] Fix case mismatch detection [HttpKernel] fix broken multiline <esi:remove> [DoctrineBridge] Fixed #14840 [FrameworkBundle] add a suggest for the serializer component [Yaml] Fix the parsing of float keys [Console] Ensure the console output is only detected as decorated when both stderr and stdout support colors [HttpKernel] fix DumpDataCollector compat with Twig 2.0 Improve exception messages. Fix that two DirectoryResources with different patterns would be deduplicated Tests fix clockmock [WebProfilerBundle] Added tabindex="-1" to not interfer with normal UX missing "YAML" in the exception message. [Translator][warmup][fallback locales] fixed missing cache file generation. [framework-bundle] Add Test for TranslationUpdateCommand Use ObjectManager interface instead of EntityManager
This commit is contained in:
commit
6393ec3169
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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('<info>[2013-05-29 16:21:54] app.INFO:</info> My info message '."\n")
|
||||
;
|
||||
|
||||
$errorOutput = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
|
||||
$errorOutput
|
||||
->expects($this->once())
|
||||
->method('write')
|
||||
->with('<error>[2013-05-29 16:21:54] app.ERROR:</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()
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -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'));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!-- START of Symfony Web Debug Toolbar -->
|
||||
{% if 'normal' != position %}
|
||||
<div id="sfMiniToolbar-{{ token }}" class="sf-minitoolbar" data-no-turbolink>
|
||||
<a href="javascript:void(0);" title="Show Symfony toolbar" onclick="
|
||||
<a href="javascript:void(0);" title="Show Symfony toolbar" tabindex="-1" accesskey="D" onclick="
|
||||
var elem = this.parentNode;
|
||||
if (elem.style.display == 'none') {
|
||||
document.getElementById('sfToolbarMainContent-{{ token }}').style.display = 'none';
|
||||
|
@ -37,7 +37,7 @@
|
|||
{% endfor %}
|
||||
|
||||
{% if 'normal' != position %}
|
||||
<a class="hide-button" title="Close Toolbar" onclick="
|
||||
<a class="hide-button" title="Close Toolbar" tabindex="-1" accesskey="D" onclick="
|
||||
var p = this.parentNode;
|
||||
p.style.display = 'none';
|
||||
(p.previousElementSibling || p.previousSibling).style.display = 'none';
|
||||
|
|
|
@ -38,7 +38,7 @@ class DirectoryResource implements ResourceInterface, \Serializable
|
|||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->resource;
|
||||
return md5(serialize(array($this->resource, $this->pattern)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -54,7 +54,6 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
$resource = new DirectoryResource($this->directory);
|
||||
$this->assertSame($this->directory, $resource->getResource(), '->getResource() returns the path to the resource');
|
||||
$this->assertSame($this->directory, (string) $resource, '->__toString() returns the path to the resource');
|
||||
}
|
||||
|
||||
public function testGetPattern()
|
||||
|
@ -87,6 +86,13 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file is added');
|
||||
}
|
||||
|
||||
public function testIsFreshNewFileWithDifferentPattern()
|
||||
{
|
||||
$resource = new DirectoryResource($this->directory, '/.xml$/');
|
||||
touch($this->directory.'/new.yaml', time() + 20);
|
||||
$this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file with a non-matching pattern is added');
|
||||
}
|
||||
|
||||
public function testIsFreshDeleteFile()
|
||||
{
|
||||
$resource = new DirectoryResource($this->directory);
|
||||
|
@ -149,4 +155,12 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertSame($this->directory, $resource->getResource());
|
||||
$this->assertSame('/\.(foo|xml)$/', $resource->getPattern());
|
||||
}
|
||||
|
||||
public function testResourcesWithDifferentPatternsAreDifferent()
|
||||
{
|
||||
$resourceA = new DirectoryResource($this->directory, '/.xml$/');
|
||||
$resourceB = new DirectoryResource($this->directory, '/.yaml$/');
|
||||
|
||||
$this->assertEquals(2, count(array_unique(array($resourceA, $resourceB))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,12 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
|||
{
|
||||
parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
|
||||
|
||||
$actualDecorated = $this->isDecorated();
|
||||
$this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());
|
||||
|
||||
if (null === $decorated) {
|
||||
$this->setDecorated($actualDecorated && $this->stderr->isDecorated());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,7 +35,7 @@ class StreamOutput extends Output
|
|||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param mixed $stream A stream resource
|
||||
* @param resource $stream A stream resource
|
||||
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
|
||||
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
|
||||
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
|
||||
|
|
|
@ -221,8 +221,22 @@ class DebugClassLoader
|
|||
|
||||
throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
|
||||
}
|
||||
if (self::$caseCheck && preg_match('#(?:[/\\\\][a-zA-Z_\x7F-\xFF][a-zA-Z0-9_\x7F-\xFF]*+)++\.(?:php|hh)$#D', $file, $tail)) {
|
||||
$tail = $tail[0];
|
||||
if (self::$caseCheck) {
|
||||
$real = explode('\\', $class.strrchr($file, '.'));
|
||||
$tail = explode(DIRECTORY_SEPARATOR, str_replace('/', DIRECTORY_SEPARATOR, $file));
|
||||
|
||||
$i = count($tail) - 1;
|
||||
$j = count($real) - 1;
|
||||
|
||||
while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
|
||||
--$i;
|
||||
--$j;
|
||||
}
|
||||
|
||||
array_splice($tail, 0, $i + 1);
|
||||
}
|
||||
if (self::$caseCheck && $tail) {
|
||||
$tail = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $tail);
|
||||
$tailLen = strlen($tail);
|
||||
$real = $refl->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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
parameters:
|
||||
FOO: bar
|
|
@ -88,6 +88,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||
array('bad_services'),
|
||||
array('bad_service'),
|
||||
array('bad_calls'),
|
||||
array('bad_format'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 <base> 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)
|
||||
|
|
|
@ -982,9 +982,12 @@ HTML;
|
|||
public function getBaseTagWithFormData()
|
||||
{
|
||||
return array(
|
||||
array('https://base.com/', 'link/', 'https://base.com/link/', 'https://base.com/link/', '<base> tag does work with a path and relative form action'),
|
||||
array('/basepath', '/registration', 'http://domain.com/registration', 'http://domain.com/registration', '<base> tag does work with a path and form action'),
|
||||
array('/basepath', '', 'http://domain.com/registration', 'http://domain.com/registration', '<base> tag does work with a path and empty form action'),
|
||||
array('http://base.com/', '/registration', 'http://base.com/registration', 'http://domain.com/registration', '<base> tag does work with a URL and form action'),
|
||||
array('http://base.com', '', 'http://domain.com/path/form', 'http://domain.com/path/form', '<base> 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', '<base> tag does work with a URL and form action'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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'];
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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('#<esi\:remove>.*?</esi\:remove>#', '', $content);
|
||||
$content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content);
|
||||
$content = preg_replace('#<esi\:remove>.*?</esi\:remove>#s', '', $content);
|
||||
$content = preg_replace('#<esi\:comment[^>]+>#s', '', $content);
|
||||
|
||||
$chunks = preg_split('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]);
|
||||
|
|
|
@ -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('<esi:remove> <a href="http://www.example.com">www.example.com</a> </esi:remove> Keep this'."<esi:remove>\n <a>www.example.com</a> </esi:remove> 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('<esi:comment text="some comment >" /> Keep this');
|
||||
$esi->process($request, $response);
|
||||
|
||||
$this->assertEquals(' Keep this', $response->getContent());
|
||||
}
|
||||
|
||||
public function testProcess()
|
||||
{
|
||||
$esi = new Esi();
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
blog_show:
|
||||
path: /blog/{slug}
|
||||
defaults: { _controller: "MyBundle:Blog:show" }
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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": ~
|
|
@ -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;
|
||||
|
|
|
@ -747,6 +747,24 @@ bar: 2
|
|||
EOF;
|
||||
$this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml));
|
||||
}
|
||||
|
||||
public function testFloatKeys()
|
||||
{
|
||||
$yaml = <<<EOF
|
||||
foo:
|
||||
1.2: "bar"
|
||||
1.3: "baz"
|
||||
EOF;
|
||||
|
||||
$expected = array(
|
||||
'foo' => array(
|
||||
'1.2' => 'bar',
|
||||
'1.3' => 'baz',
|
||||
),
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->parser->parse($yaml));
|
||||
}
|
||||
}
|
||||
|
||||
class B
|
||||
|
|
Reference in New Issue