Merge branch '5.2' into 5.x

* 5.2:
  harden test to not depend on the actual time
  [ProxyManager] fix tests
  actually compare the order of entries when any sorting is applied
  Dump abstract arguments
This commit is contained in:
Christian Flothmann 2021-01-04 13:42:27 +01:00
commit 4e42149fa8
15 changed files with 163 additions and 73 deletions

View File

@ -18,7 +18,7 @@
"require": { "require": {
"php": ">=7.2.5", "php": ">=7.2.5",
"ext-xml": "*", "ext-xml": "*",
"friendsofphp/proxy-manager-lts": "^1.0", "friendsofphp/proxy-manager-lts": "^1.0.2",
"doctrine/event-manager": "~1.0", "doctrine/event-manager": "~1.0",
"doctrine/persistence": "^2", "doctrine/persistence": "^2",
"twig/twig": "^2.10|^3.0", "twig/twig": "^2.10|^3.0",

View File

@ -11,7 +11,7 @@
namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper; namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper;
use ProxyManager\Generator\ClassGenerator; use Laminas\Code\Generator\ClassGenerator;
use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy; use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy;
use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;

View File

@ -48,7 +48,7 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S
static $reflection; static $reflection;
$reflection = $reflection ?? new \ReflectionClass(__CLASS__); $reflection = $reflection ?? new \ReflectionClass(__CLASS__);
$instance%w= $reflection->newInstanceWithoutConstructor(); $instance = $reflection->newInstanceWithoutConstructor();
$instance->initializer%s = $initializer; $instance->initializer%s = $initializer;
@ -73,13 +73,16 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S
return $this->valueHolder%s->$name; return $this->valueHolder%s->$name;
} }
$realInstanceReflection = new \ReflectionClass(__CLASS__);
if (! $realInstanceReflection->hasProperty($name)) {
$targetObject = $this->valueHolder%s; $targetObject = $this->valueHolder%s;
$backtrace = debug_backtrace(false%S); $backtrace = debug_backtrace(false, 1);
trigger_error( trigger_error(
sprintf( sprintf(
'Undefined property: %s::$%s in %s on line %s', 'Undefined property: %%s::$%%s in %%s on line %%s',
__CLASS__, $realInstanceReflection->getName(),
$name, $name,
$backtrace[0]['file'], $backtrace[0]['file'],
$backtrace[0]['line'] $backtrace[0]['line']
@ -89,32 +92,95 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S
return $targetObject->$name; return $targetObject->$name;
} }
$targetObject = $this->valueHolder%s;
$accessor = function & () use ($targetObject, $name) {
return $targetObject->$name;
};
$backtrace = debug_backtrace(true, 2);
$scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub();
$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));
$returnValue = & $accessor();
return $returnValue;
}
public function __set($name, $value) public function __set($name, $value)
{ {
$this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__set', array('name' => $name, 'value' => $value), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__set', array('name' => $name, 'value' => $value), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s;
$realInstanceReflection = new \ReflectionClass(__CLASS__);
if (! $realInstanceReflection->hasProperty($name)) {
$targetObject = $this->valueHolder%s; $targetObject = $this->valueHolder%s;
$targetObject->$name = $value;%wreturn $targetObject->$name; $targetObject->$name = $value;
return $targetObject->$name;
}
$targetObject = $this->valueHolder%s;
$accessor = function & () use ($targetObject, $name, $value) {
$targetObject->$name = $value;
return $targetObject->$name;
};
$backtrace = debug_backtrace(true, 2);
$scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub();
$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));
$returnValue = & $accessor();
return $returnValue;
} }
public function __isset($name) public function __isset($name)
{ {
$this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__isset', array('name' => $name), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__isset', array('name' => $name), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s;
$realInstanceReflection = new \ReflectionClass(__CLASS__);
if (! $realInstanceReflection->hasProperty($name)) {
$targetObject = $this->valueHolder%s; $targetObject = $this->valueHolder%s;
return isset($targetObject->$name); return isset($targetObject->$name);
} }
$targetObject = $this->valueHolder%s;
$accessor = function () use ($targetObject, $name) {
return isset($targetObject->$name);
};
$backtrace = debug_backtrace(true, 2);
$scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub();
$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));
$returnValue = $accessor();
return $returnValue;
}
public function __unset($name) public function __unset($name)
{ {
$this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__unset', array('name' => $name), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__unset', array('name' => $name), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s;
$realInstanceReflection = new \ReflectionClass(__CLASS__);
if (! $realInstanceReflection->hasProperty($name)) {
$targetObject = $this->valueHolder%s; $targetObject = $this->valueHolder%s;
unset($targetObject->$name); unset($targetObject->$name);
%a }
return;
}
$targetObject = $this->valueHolder%s;
$accessor = function () use ($targetObject, $name) {
unset($targetObject->$name);
return;
};
$backtrace = debug_backtrace(true, 2);
$scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub();
$accessor = $accessor->bindTo($scopeObject, get_class($scopeObject));
$accessor();
}
public function __clone() public function __clone()
{ {

View File

@ -18,7 +18,7 @@
"require": { "require": {
"php": ">=7.2.5", "php": ">=7.2.5",
"composer/package-versions-deprecated": "^1.8", "composer/package-versions-deprecated": "^1.8",
"friendsofphp/proxy-manager-lts": "^1.0", "friendsofphp/proxy-manager-lts": "^1.0.2",
"symfony/dependency-injection": "^5.0" "symfony/dependency-injection": "^5.0"
}, },
"require-dev": { "require-dev": {

View File

@ -14,6 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
use Symfony\Component\Console\Exception\LogicException; use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -394,6 +395,10 @@ class JsonDescriptor extends Descriptor
]; ];
} }
if ($value instanceof AbstractArgument) {
return ['type' => 'abstract', 'text' => $value->getText()];
}
if ($value instanceof ArgumentInterface) { if ($value instanceof ArgumentInterface) {
return $this->describeValue($value->getValues(), $omitTags, $showArguments); return $this->describeValue($value->getValues(), $omitTags, $showArguments);
} }

View File

@ -16,6 +16,7 @@ use Symfony\Component\Console\Helper\Dumper;
use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
@ -347,6 +348,8 @@ class TextDescriptor extends Descriptor
$argumentsInformation[] = sprintf('Service locator (%d element(s))', \count($argument->getValues())); $argumentsInformation[] = sprintf('Service locator (%d element(s))', \count($argument->getValues()));
} elseif ($argument instanceof Definition) { } elseif ($argument instanceof Definition) {
$argumentsInformation[] = 'Inlined Service'; $argumentsInformation[] = 'Inlined Service';
} elseif ($argument instanceof AbstractArgument) {
$argumentsInformation[] = sprintf('Abstract argument (%s)', $argument->getText());
} else { } else {
$argumentsInformation[] = \is_array($argument) ? sprintf('Array (%d element(s))', \count($argument)) : $argument; $argumentsInformation[] = \is_array($argument) ? sprintf('Array (%d element(s))', \count($argument)) : $argument;
} }

View File

@ -14,6 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
use Symfony\Component\Console\Exception\LogicException; use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
@ -409,6 +410,9 @@ class XmlDescriptor extends Descriptor
} }
} elseif ($argument instanceof Definition) { } elseif ($argument instanceof Definition) {
$argumentXML->appendChild($dom->importNode($this->getContainerDefinitionDocument($argument, null, false, true)->childNodes->item(0), true)); $argumentXML->appendChild($dom->importNode($this->getContainerDefinitionDocument($argument, null, false, true)->childNodes->item(0), true));
} elseif ($argument instanceof AbstractArgument) {
$argumentXML->setAttribute('type', 'abstract');
$argumentXML->appendChild(new \DOMText($argument->getText()));
} elseif (\is_array($argument)) { } elseif (\is_array($argument)) {
$argumentXML->setAttribute('type', 'collection'); $argumentXML->setAttribute('type', 'collection');

View File

@ -12,6 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor; namespace Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor;
use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Definition;
@ -146,6 +147,7 @@ class ObjectsProvider
new Reference('definition_1'), new Reference('definition_1'),
new Reference('.definition_2'), new Reference('.definition_2'),
])) ]))
->addArgument(new AbstractArgument('placeholder'))
->setFactory(['Full\\Qualified\\FactoryClass', 'get']), ->setFactory(['Full\\Qualified\\FactoryClass', 'get']),
'.definition_2' => $definition2 '.definition_2' => $definition2
->setPublic(false) ->setPublic(false)

View File

@ -60,7 +60,11 @@
"type": "service", "type": "service",
"id": ".definition_2" "id": ".definition_2"
} }
] ],
{
"type": "abstract",
"text": "placeholder"
}
], ],
"file": null, "file": null,
"factory_class": "Full\\Qualified\\FactoryClass", "factory_class": "Full\\Qualified\\FactoryClass",

View File

@ -22,6 +22,7 @@
<argument type="service" id="definition_1"/> <argument type="service" id="definition_1"/>
<argument type="service" id=".definition_2"/> <argument type="service" id=".definition_2"/>
</argument> </argument>
<argument type="abstract">placeholder</argument>
</definition> </definition>
<definition id="definition_without_class" class="" public="false" synthetic="false" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file=""/> <definition id="definition_without_class" class="" public="false" synthetic="false" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file=""/>
<definition id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file=""> <definition id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true" lazy="false" shared="true" abstract="false" autowired="false" autoconfigured="false" file="">

View File

@ -58,7 +58,11 @@
"type": "service", "type": "service",
"id": ".definition_2" "id": ".definition_2"
} }
] ],
{
"type": "abstract",
"text": "placeholder"
}
], ],
"file": null, "file": null,
"factory_class": "Full\\Qualified\\FactoryClass", "factory_class": "Full\\Qualified\\FactoryClass",

View File

@ -1,6 +1,6 @@
---------------- ----------------------------- ---------------- ---------------------------------
 Option   Value   Option   Value 
---------------- ----------------------------- ---------------- ---------------------------------
Service ID - Service ID -
Class Full\Qualified\Class1 Class Full\Qualified\Class1
Tags - Tags -
@ -19,6 +19,7 @@
 Array (3 element(s))   Array (3 element(s)) 
 Iterator (2 element(s))   Iterator (2 element(s)) 
 - Service(definition_1)   - Service(definition_1) 
 - Service(.definition_2)  - Service(.definition_2) 
---------------- -----------------------------  Abstract argument (placeholder)
---------------- ---------------------------------

View File

@ -20,4 +20,5 @@
<argument type="service" id="definition_1"/> <argument type="service" id="definition_1"/>
<argument type="service" id=".definition_2"/> <argument type="service" id=".definition_2"/>
</argument> </argument>
<argument type="abstract">placeholder</argument>
</definition> </definition>

View File

@ -631,7 +631,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
{ {
$finder = $this->buildFinder(); $finder = $this->buildFinder();
$this->assertSame($finder, $finder->sortByName()); $this->assertSame($finder, $finder->sortByName());
$this->assertIterator($this->toAbsolute([ $this->assertOrderedIterator($this->toAbsolute([
'foo', 'foo',
'foo bar', 'foo bar',
'foo/bar.tmp', 'foo/bar.tmp',
@ -654,14 +654,12 @@ class FinderTest extends Iterator\RealIteratorTestCase
{ {
$finder = $this->buildFinder(); $finder = $this->buildFinder();
$this->assertSame($finder, $finder->sortByType()); $this->assertSame($finder, $finder->sortByType());
$this->assertIterator($this->toAbsolute([ $this->assertOrderedIterator($this->toAbsolute([
'foo', 'foo',
'foo bar',
'toto',
'foo/bar.tmp',
'test.php',
'test.py',
'qux', 'qux',
'toto',
'foo bar',
'foo/bar.tmp',
'qux/baz_100_1.py', 'qux/baz_100_1.py',
'qux/baz_1_2.py', 'qux/baz_1_2.py',
'qux_0_1.php', 'qux_0_1.php',
@ -670,6 +668,8 @@ class FinderTest extends Iterator\RealIteratorTestCase
'qux_10_2.php', 'qux_10_2.php',
'qux_12_0.php', 'qux_12_0.php',
'qux_2_0.php', 'qux_2_0.php',
'test.php',
'test.py',
]), $finder->in(self::$tmpDir)->getIterator()); ]), $finder->in(self::$tmpDir)->getIterator());
} }
@ -770,19 +770,19 @@ class FinderTest extends Iterator\RealIteratorTestCase
{ {
$finder = $this->buildFinder(); $finder = $this->buildFinder();
$this->assertSame($finder, $finder->sortByName(true)); $this->assertSame($finder, $finder->sortByName(true));
$this->assertIterator($this->toAbsolute([ $this->assertOrderedIterator($this->toAbsolute([
'foo', 'foo',
'foo bar',
'foo/bar.tmp', 'foo/bar.tmp',
'foo bar',
'qux', 'qux',
'qux/baz_100_1.py',
'qux/baz_1_2.py', 'qux/baz_1_2.py',
'qux/baz_100_1.py',
'qux_0_1.php', 'qux_0_1.php',
'qux_1000_1.php', 'qux_2_0.php',
'qux_1002_0.php',
'qux_10_2.php', 'qux_10_2.php',
'qux_12_0.php', 'qux_12_0.php',
'qux_2_0.php', 'qux_1000_1.php',
'qux_1002_0.php',
'test.php', 'test.php',
'test.py', 'test.py',
'toto', 'toto',
@ -790,7 +790,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
$finder = $this->buildFinder(); $finder = $this->buildFinder();
$this->assertSame($finder, $finder->sortByName(false)); $this->assertSame($finder, $finder->sortByName(false));
$this->assertIterator($this->toAbsolute([ $this->assertOrderedIterator($this->toAbsolute([
'foo', 'foo',
'foo bar', 'foo bar',
'foo/bar.tmp', 'foo/bar.tmp',
@ -813,13 +813,10 @@ class FinderTest extends Iterator\RealIteratorTestCase
{ {
$finder = $this->buildFinder(); $finder = $this->buildFinder();
$this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); })); $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); }));
$this->assertIterator($this->toAbsolute([ $this->assertOrderedIterator($this->toAbsolute([
'foo', 'foo',
'foo bar', 'foo bar',
'foo/bar.tmp', 'foo/bar.tmp',
'test.php',
'test.py',
'toto',
'qux', 'qux',
'qux/baz_100_1.py', 'qux/baz_100_1.py',
'qux/baz_1_2.py', 'qux/baz_1_2.py',
@ -829,6 +826,9 @@ class FinderTest extends Iterator\RealIteratorTestCase
'qux_10_2.php', 'qux_10_2.php',
'qux_12_0.php', 'qux_12_0.php',
'qux_2_0.php', 'qux_2_0.php',
'test.php',
'test.py',
'toto',
]), $finder->in(self::$tmpDir)->getIterator()); ]), $finder->in(self::$tmpDir)->getIterator());
} }

View File

@ -213,26 +213,25 @@ class FileProfilerStorageTest extends TestCase
public function testStoreTime() public function testStoreTime()
{ {
$dt = new \DateTime('now'); $start = $now = time();
$start = $dt->getTimestamp();
for ($i = 0; $i < 3; ++$i) { for ($i = 0; $i < 3; ++$i) {
$dt->modify('+1 minute'); $now += 60;
$profile = new Profile('time_'.$i); $profile = new Profile('time_'.$i);
$profile->setIp('127.0.0.1'); $profile->setIp('127.0.0.1');
$profile->setUrl('http://foo.bar'); $profile->setUrl('http://foo.bar');
$profile->setTime($dt->getTimestamp()); $profile->setTime($now);
$profile->setMethod('GET'); $profile->setMethod('GET');
$this->storage->write($profile); $this->storage->write($profile);
} }
$records = $this->storage->find('', '', 3, 'GET', $start, time() + 3 * 60); $records = $this->storage->find('', '', 3, 'GET', $start, $start + 3 * 60);
$this->assertCount(3, $records, '->find() returns all previously added records'); $this->assertCount(3, $records, '->find() returns all previously added records');
$this->assertEquals('time_2', $records[0]['token'], '->find() returns records ordered by time in descendant order'); $this->assertEquals('time_2', $records[0]['token'], '->find() returns records ordered by time in descendant order');
$this->assertEquals('time_1', $records[1]['token'], '->find() returns records ordered by time in descendant order'); $this->assertEquals('time_1', $records[1]['token'], '->find() returns records ordered by time in descendant order');
$this->assertEquals('time_0', $records[2]['token'], '->find() returns records ordered by time in descendant order'); $this->assertEquals('time_0', $records[2]['token'], '->find() returns records ordered by time in descendant order');
$records = $this->storage->find('', '', 3, 'GET', $start, time() + 2 * 60); $records = $this->storage->find('', '', 3, 'GET', $start, $start + 2 * 60);
$this->assertCount(2, $records, '->find() should return only first two of the previously added records'); $this->assertCount(2, $records, '->find() should return only first two of the previously added records');
} }