Merge branch '3.1'

* 3.1:
  [TwigBridge] removed Twig null nodes (deprecated as of Twig 1.25)
  Make redis host configurable in tests
  [Console] Fix empty optionnal options with = separator in argv
This commit is contained in:
Fabien Potencier 2016-09-19 13:29:03 -07:00
commit 84229f84fb
17 changed files with 108 additions and 37 deletions

View File

@ -15,6 +15,7 @@
<env name="DUMP_STRING_LENGTH" value="" />
<env name="LDAP_HOST" value="127.0.0.1" />
<env name="LDAP_PORT" value="3389" />
<env name="REDIS_HOST" value="localhost" />
</php>
<testsuites>

View File

@ -20,7 +20,12 @@ class DumpNode extends \Twig_Node
public function __construct($varPrefix, \Twig_Node $values = null, $lineno, $tag = null)
{
parent::__construct(array('values' => $values), array(), $lineno, $tag);
$nodes = array();
if (null !== $values) {
$nodes['values'] = $values;
}
parent::__construct($nodes, array(), $lineno, $tag);
$this->varPrefix = $varPrefix;
}
@ -33,9 +38,7 @@ class DumpNode extends \Twig_Node
->write("if (\$this->env->isDebug()) {\n")
->indent();
$values = $this->getNode('values');
if (null === $values) {
if (!$this->hasNode('values')) {
// remove embedded templates (macros) from the context
$compiler
->write(sprintf('$%svars = array();'."\n", $this->varPrefix))
@ -50,7 +53,7 @@ class DumpNode extends \Twig_Node
->write("}\n")
->addDebugInfo($this)
->write(sprintf('\Symfony\Component\VarDumper\VarDumper::dump($%svars);'."\n", $this->varPrefix));
} elseif (1 === $values->count()) {
} elseif (($values = $this->getNode('values')) && 1 === $values->count()) {
$compiler
->addDebugInfo($this)
->write('\Symfony\Component\VarDumper\VarDumper::dump(')

View File

@ -18,7 +18,7 @@ namespace Symfony\Bridge\Twig\Node;
*/
class StopwatchNode extends \Twig_Node
{
public function __construct(\Twig_Node $name, $body, \Twig_Node_Expression_AssignName $var, $lineno = 0, $tag = null)
public function __construct(\Twig_Node $name, \Twig_Node $body, \Twig_Node_Expression_AssignName $var, $lineno = 0, $tag = null)
{
parent::__construct(array('body' => $body, 'name' => $name, 'var' => $var), array(), $lineno, $tag);
}

View File

@ -18,7 +18,21 @@ class TransNode extends \Twig_Node
{
public function __construct(\Twig_Node $body, \Twig_Node $domain = null, \Twig_Node_Expression $count = null, \Twig_Node_Expression $vars = null, \Twig_Node_Expression $locale = null, $lineno = 0, $tag = null)
{
parent::__construct(array('count' => $count, 'body' => $body, 'domain' => $domain, 'vars' => $vars, 'locale' => $locale), array(), $lineno, $tag);
$nodes = array('body' => $body);
if (null !== $domain) {
$nodes['domain'] = $domain;
}
if (null !== $count) {
$nodes['count'] = $count;
}
if (null !== $vars) {
$nodes['vars'] = $vars;
}
if (null !== $locale) {
$nodes['locale'] = $locale;
}
parent::__construct($nodes, array(), $lineno, $tag);
}
/**
@ -30,15 +44,14 @@ class TransNode extends \Twig_Node
{
$compiler->addDebugInfo($this);
$vars = $this->getNode('vars');
$defaults = new \Twig_Node_Expression_Array(array(), -1);
if ($vars instanceof \Twig_Node_Expression_Array) {
if ($this->hasNode('vars') && ($vars = $this->getNode('vars')) instanceof \Twig_Node_Expression_Array) {
$defaults = $this->getNode('vars');
$vars = null;
}
list($msg, $defaults) = $this->compileString($this->getNode('body'), $defaults, (bool) $vars);
$method = null === $this->getNode('count') ? 'trans' : 'transChoice';
$method = !$this->hasNode('count') ? 'trans' : 'transChoice';
$compiler
->write('echo $this->env->getExtension(\'translator\')->getTranslator()->'.$method.'(')
@ -47,7 +60,7 @@ class TransNode extends \Twig_Node
$compiler->raw(', ');
if (null !== $this->getNode('count')) {
if ($this->hasNode('count')) {
$compiler
->subcompile($this->getNode('count'))
->raw(', ')
@ -68,13 +81,13 @@ class TransNode extends \Twig_Node
$compiler->raw(', ');
if (null === $this->getNode('domain')) {
if (!$this->hasNode('domain')) {
$compiler->repr('messages');
} else {
$compiler->subcompile($this->getNode('domain'));
}
if (null !== $this->getNode('locale')) {
if ($this->hasNode('locale')) {
$compiler
->raw(', ')
->subcompile($this->getNode('locale'))
@ -98,7 +111,7 @@ class TransNode extends \Twig_Node
foreach ($matches[1] as $var) {
$key = new \Twig_Node_Expression_Constant('%'.$var.'%', $body->getLine());
if (!$vars->hasElement($key)) {
if ('count' === $var && null !== $this->getNode('count')) {
if ('count' === $var && $this->hasNode('count')) {
$vars->addElement($this->getNode('count'), $key);
} else {
$varExpr = new \Twig_Node_Expression_Name($var, $body->getLine());

View File

@ -78,7 +78,7 @@ class TranslationDefaultDomainNodeVisitor extends \Twig_BaseNodeVisitor
}
}
} elseif ($node instanceof TransNode) {
if (null === $node->getNode('domain')) {
if (!$node->hasNode('domain')) {
$node->setNode('domain', $this->scope->get('domain'));
}
}

View File

@ -75,7 +75,7 @@ class TranslationNodeVisitor extends \Twig_BaseNodeVisitor
// extract trans nodes
$this->messages[] = array(
$node->getNode('body')->getAttribute('data'),
$this->getReadDomainFromNode($node->getNode('domain')),
$node->hasNode('domain') ? $this->getReadDomainFromNode($node->getNode('domain')) : null,
);
}
@ -122,12 +122,8 @@ class TranslationNodeVisitor extends \Twig_BaseNodeVisitor
*
* @return string|null
*/
private function getReadDomainFromNode(\Twig_Node $node = null)
private function getReadDomainFromNode(\Twig_Node $node)
{
if (null === $node) {
return;
}
if ($node instanceof \Twig_Node_Expression_Constant) {
return $node->getAttribute('value');
}

View File

@ -17,6 +17,16 @@ use Symfony\Component\Cache\Exception\InvalidArgumentException;
class CachePoolsTest extends WebTestCase
{
protected function setUp()
{
$_SERVER['SYMFONY__REDIS_HOST'] = getenv('REDIS_HOST');
}
protected function tearDown()
{
unset($_SERVER['SYMFONY__REDIS_HOST']);
}
public function testCachePools()
{
$this->doTestCachePools(array(), FilesystemAdapter::class);
@ -30,7 +40,7 @@ class CachePoolsTest extends WebTestCase
try {
$this->doTestCachePools(array('root_config' => 'redis_config.yml', 'environment' => 'redis_cache'), RedisAdapter::class);
} catch (\PHPUnit_Framework_Error_Warning $e) {
if (0 !== strpos($e->getMessage(), 'unable to connect to 127.0.0.1')) {
if (0 !== strpos($e->getMessage(), 'unable to connect to')) {
throw $e;
}
$this->markTestSkipped($e->getMessage());
@ -50,7 +60,7 @@ class CachePoolsTest extends WebTestCase
try {
$this->doTestCachePools(array('root_config' => 'redis_custom_config.yml', 'environment' => 'custom_redis_cache'), RedisAdapter::class);
} catch (\PHPUnit_Framework_Error_Warning $e) {
if (0 !== strpos($e->getMessage(), 'unable to connect to 127.0.0.1')) {
if (0 !== strpos($e->getMessage(), 'unable to connect to')) {
throw $e;
}
$this->markTestSkipped($e->getMessage());

View File

@ -4,6 +4,7 @@ imports:
framework:
cache:
app: cache.adapter.redis
default_redis_provider: "redis://%redis_host%"
pools:
cache.pool1:
public: true

View File

@ -6,7 +6,7 @@ services:
public: false
class: Redis
calls:
- [connect, [127.0.0.1]]
- [connect, ['%redis_host%']]
cache.app:
parent: cache.adapter.redis

View File

@ -8,6 +8,7 @@
>
<php>
<ini name="error_reporting" value="-1" />
<env name="REDIS_HOST" value="localhost" />
</php>
<testsuites>

View File

@ -33,7 +33,7 @@ abstract class AbstractRedisAdapterTest extends AdapterTestCase
if (!extension_loaded('redis')) {
self::markTestSkipped('Extension redis required.');
}
if (!@((new \Redis())->connect('127.0.0.1'))) {
if (!@((new \Redis())->connect(getenv('REDIS_HOST')))) {
$e = error_get_last();
self::markTestSkipped($e['message']);
}

View File

@ -19,12 +19,14 @@ class PredisAdapterTest extends AbstractRedisAdapterTest
public static function setupBeforeClass()
{
parent::setupBeforeClass();
self::$redis = new \Predis\Client();
self::$redis = new \Predis\Client(array('host' => getenv('REDIS_HOST')));
}
public function testCreateConnection()
{
$redis = RedisAdapter::createConnection('redis://localhost/1', array('class' => \Predis\Client::class, 'timeout' => 3));
$redisHost = getenv('REDIS_HOST');
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'/1', array('class' => \Predis\Client::class, 'timeout' => 3));
$this->assertInstanceOf(\Predis\Client::class, $redis);
$connection = $redis->getConnection();
@ -32,7 +34,7 @@ class PredisAdapterTest extends AbstractRedisAdapterTest
$params = array(
'scheme' => 'tcp',
'host' => 'localhost',
'host' => $redisHost,
'path' => '',
'dbindex' => '1',
'port' => 6379,

View File

@ -19,26 +19,28 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
{
parent::setupBeforeClass();
self::$redis = new \Redis();
self::$redis->connect('127.0.0.1');
self::$redis->connect(getenv('REDIS_HOST'));
}
public function testCreateConnection()
{
$redis = RedisAdapter::createConnection('redis://localhost');
$redisHost = getenv('REDIS_HOST');
$redis = RedisAdapter::createConnection('redis://'.$redisHost);
$this->assertInstanceOf(\Redis::class, $redis);
$this->assertTrue($redis->isConnected());
$this->assertSame(0, $redis->getDbNum());
$redis = RedisAdapter::createConnection('redis://localhost/2');
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2');
$this->assertSame(2, $redis->getDbNum());
$redis = RedisAdapter::createConnection('redis://localhost', array('timeout' => 3));
$redis = RedisAdapter::createConnection('redis://'.$redisHost, array('timeout' => 3));
$this->assertEquals(3, $redis->getTimeout());
$redis = RedisAdapter::createConnection('redis://localhost?timeout=4');
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4');
$this->assertEquals(4, $redis->getTimeout());
$redis = RedisAdapter::createConnection('redis://localhost', array('read_timeout' => 5));
$redis = RedisAdapter::createConnection('redis://'.$redisHost, array('read_timeout' => 5));
$this->assertEquals(5, $redis->getReadTimeout());
}

View File

@ -19,6 +19,6 @@ class RedisArrayAdapterTest extends AbstractRedisAdapterTest
if (!class_exists('RedisArray')) {
self::markTestSkipped('The RedisArray class is required.');
}
self::$redis = new \RedisArray(array('localhost'), array('lazy_connect' => true));
self::$redis = new \RedisArray(array(getenv('REDIS_HOST')), array('lazy_connect' => true));
}
}

View File

@ -8,6 +8,7 @@
>
<php>
<ini name="error_reporting" value="-1" />
<env name="REDIS_HOST" value="localhost" />
</php>
<testsuites>

View File

@ -147,7 +147,10 @@ class ArgvInput extends Input
$name = substr($token, 2);
if (false !== $pos = strpos($name, '=')) {
$this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
if (0 === strlen($value = substr($name, $pos + 1))) {
array_unshift($this->parsed, null);
}
$this->addLongOption(substr($name, 0, $pos), $value);
} else {
$this->addLongOption($name, null);
}
@ -234,7 +237,7 @@ class ArgvInput extends Input
if (isset($next[0]) && '-' !== $next[0]) {
$value = $next;
} elseif (empty($next)) {
$value = '';
$value = null;
} else {
array_unshift($this->parsed, $next);
}

View File

@ -71,6 +71,18 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
array('foo' => 'bar'),
'->parse() parses long options with a required value (with a space separator)',
),
array(
array('cli.php', '--foo='),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
array('foo' => null),
'->parse() parses long options with optional value which is empty (with a = separator) as null',
),
array(
array('cli.php', '--foo=', 'bar'),
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)),
array('foo' => null),
'->parse() parses long options with optional value which is empty (with a = separator) followed by an argument',
),
array(
array('cli.php', '-f'),
array(new InputOption('foo', 'f')),
@ -343,4 +355,30 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
$input->bind(new InputDefinition(array(new InputArgument('file'))));
$this->assertEquals(array('file' => '-'), $input->getArguments(), '->parse() parses single dash as an argument');
}
public function testParseOptionWithValueOptionalGivenEmptyAndRequiredArgument()
{
$input = new ArgvInput(array('cli.php', '--foo=', 'bar'));
$input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED))));
$this->assertEquals(array('foo' => null), $input->getOptions(), '->parse() parses optional options with empty value as null');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses required arguments');
$input = new ArgvInput(array('cli.php', '--foo=0', 'bar'));
$input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED))));
$this->assertEquals(array('foo' => '0'), $input->getOptions(), '->parse() parses optional options with empty value as null');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses required arguments');
}
public function testParseOptionWithValueOptionalGivenEmptyAndOptionalArgument()
{
$input = new ArgvInput(array('cli.php', '--foo=', 'bar'));
$input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::OPTIONAL))));
$this->assertEquals(array('foo' => null), $input->getOptions(), '->parse() parses optional options with empty value as null');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses optional arguments');
$input = new ArgvInput(array('cli.php', '--foo=0', 'bar'));
$input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::OPTIONAL))));
$this->assertEquals(array('foo' => '0'), $input->getOptions(), '->parse() parses optional options with empty value as null');
$this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses optional arguments');
}
}