Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 782ffe2

Browse files
Merge branch '4.0'
* 4.0: [HttpKernel] Make ServiceValueResolver work if controller namespace starts with a backslash in routing Add d-block to bootstrap 4 alerts [Console] Don't go past exact matches when autocompleting [DI] Improve error message for non-autowirable scalar argument Disable autoloader call on interface_exists check [Validator] Fix LazyLoadingMetadataFactory with PSR6Cache for non classname if tested values isn't an existing class [HttpKernel] Dont create mock cookie for new sessions in tests
2 parents ce5b3e7 + 594925a commit 782ffe2

File tree

14 files changed

+108
-16
lines changed

14 files changed

+108
-16
lines changed

src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@
283283

284284
{% block form_errors -%}
285285
{%- if errors|length > 0 -%}
286-
<span class="{% if form is not rootform %}invalid-feedback d-block{% else %}alert alert-danger{% endif %}">
286+
<span class="{% if form is not rootform %}invalid-feedback{% else %}alert alert-danger{% endif %} d-block">
287287
{%- for error in errors -%}
288288
<span class="mb-0 d-block">
289289
<span class="initialism form-error-icon badge badge-danger">{{ 'Error'|trans({}, 'validators') }}</span> <span class="form-error-message">{{ error.message }}</span>

src/Symfony/Component/Console/Helper/QuestionHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
261261

262262
foreach ($autocomplete as $value) {
263263
// If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
264-
if (0 === strpos($value, $ret) && $i !== strlen($value)) {
264+
if (0 === strpos($value, $ret)) {
265265
$matches[$numMatches++] = $value;
266266
}
267267
}

src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,29 @@ public function testAskWithAutocompleteWithNonSequentialKeys()
157157
$this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
158158
}
159159

160+
public function testAskWithAutocompleteWithExactMatch()
161+
{
162+
if (!$this->hasSttyAvailable()) {
163+
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
164+
}
165+
166+
$inputStream = $this->getInputStream("b\n");
167+
168+
$possibleChoices = array(
169+
'a' => 'berlin',
170+
'b' => 'copenhagen',
171+
'c' => 'amsterdam',
172+
);
173+
174+
$dialog = new QuestionHelper();
175+
$dialog->setHelperSet(new HelperSet(array(new FormatterHelper())));
176+
177+
$question = new ChoiceQuestion('Please select a city', $possibleChoices);
178+
$question->setMaxAttempts(1);
179+
180+
$this->assertSame('b', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
181+
}
182+
160183
public function testAutocompleteWithTrailingBackslash()
161184
{
162185
if (!$this->hasSttyAvailable()) {

src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,10 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
207207
if ($parameter->isOptional()) {
208208
continue;
209209
}
210-
throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" must have a type-hint or be given a value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method));
210+
$type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, false);
211+
$type = $type ? sprintf('is type-hinted "%s"', $type) : 'has no type-hint';
212+
213+
throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" %s, you should configure its value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method, $type));
211214
}
212215

213216
// specifically pass the default value

src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ public function testSomeSpecificArgumentsAreSet()
377377
// args are: A, Foo, Dunglas
378378
->setArguments(array(
379379
1 => new Reference('foo'),
380+
3 => array('bar'),
380381
));
381382

382383
(new ResolveClassPass())->process($container);
@@ -388,19 +389,38 @@ public function testSomeSpecificArgumentsAreSet()
388389
new TypedReference(A::class, A::class),
389390
new Reference('foo'),
390391
new TypedReference(Dunglas::class, Dunglas::class),
392+
array('bar'),
391393
),
392394
$definition->getArguments()
393395
);
394396
}
395397

396398
/**
397399
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
398-
* @expectedExceptionMessage Cannot autowire service "arg_no_type_hint": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" must have a type-hint or be given a value explicitly.
400+
* @expectedExceptionMessage Cannot autowire service "arg_no_type_hint": argument "$bar" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" is type-hinted "array", you should configure its value explicitly.
399401
*/
400402
public function testScalarArgsCannotBeAutowired()
401403
{
402404
$container = new ContainerBuilder();
403405

406+
$container->register(A::class);
407+
$container->register(Dunglas::class);
408+
$container->register('arg_no_type_hint', __NAMESPACE__.'\MultipleArguments')
409+
->setArguments(array(1 => 'foo'))
410+
->setAutowired(true);
411+
412+
(new ResolveClassPass())->process($container);
413+
(new AutowirePass())->process($container);
414+
}
415+
416+
/**
417+
* @expectedException \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
418+
* @expectedExceptionMessage Cannot autowire service "arg_no_type_hint": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" has no type-hint, you should configure its value explicitly.
419+
*/
420+
public function testNoTypeArgsCannotBeAutowired()
421+
{
422+
$container = new ContainerBuilder();
423+
404424
$container->register(A::class);
405425
$container->register(Dunglas::class);
406426
$container->register('arg_no_type_hint', __NAMESPACE__.'\MultipleArguments')

src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public function __construct(A $k)
183183
}
184184
class MultipleArguments
185185
{
186-
public function __construct(A $k, $foo, Dunglas $dunglas)
186+
public function __construct(A $k, $foo, Dunglas $dunglas, array $bar)
187187
{
188188
}
189189
}

src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function testRow()
3232
[
3333
./label[@for="name"]
3434
[
35-
./span[@class="alert alert-danger"]
35+
./span[@class="alert alert-danger d-block"]
3636
[./span[@class="mb-0 d-block"]
3737
[./span[.="[trans]Error[/trans]"]]
3838
[./span[.="[trans]Error![/trans]"]]

src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function testRow()
3232
[
3333
./label[@for="name"]
3434
[
35-
./span[@class="alert alert-danger"]
35+
./span[@class="alert alert-danger d-block"]
3636
[./span[@class="mb-0 d-block"]
3737
[./span[.="[trans]Error[/trans]"]]
3838
[./span[.="[trans]Error![/trans]"]]
@@ -178,7 +178,7 @@ public function testErrors()
178178

179179
$this->assertMatchesXpath($html,
180180
'/span
181-
[@class="alert alert-danger"]
181+
[@class="alert alert-danger d-block"]
182182
[
183183
./span[@class="mb-0 d-block"]
184184
[./span[.="[trans]Error[/trans]"]]

src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,15 @@ public function supports(Request $request, ArgumentMetadata $argument)
4040

4141
if (\is_array($controller) && \is_callable($controller, true) && \is_string($controller[0])) {
4242
$controller = $controller[0].'::'.$controller[1];
43+
} elseif (!\is_string($controller) || '' === $controller) {
44+
return false;
4345
}
4446

45-
return \is_string($controller) && $this->container->has($controller) && $this->container->get($controller)->has($argument->getName());
47+
if ('\\' === $controller[0]) {
48+
$controller = ltrim($controller, '\\');
49+
}
50+
51+
return $this->container->has($controller) && $this->container->get($controller)->has($argument->getName());
4652
}
4753

4854
/**
@@ -54,6 +60,10 @@ public function resolve(Request $request, ArgumentMetadata $argument)
5460
$controller = $controller[0].'::'.$controller[1];
5561
}
5662

63+
if ('\\' === $controller[0]) {
64+
$controller = ltrim($controller, '\\');
65+
}
66+
5767
try {
5868
yield $this->container->get($controller)->get($argument->getName());
5969
} catch (RuntimeException $e) {

src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public function onKernelResponse(FilterResponseEvent $event)
6969
$session->save();
7070
}
7171

72-
if ($session instanceof Session ? !$session->isEmpty() || $session->getId() !== $this->sessionId : $wasStarted) {
72+
if ($session instanceof Session ? !$session->isEmpty() || (null !== $this->sessionId && $session->getId() !== $this->sessionId) : $wasStarted) {
7373
$params = session_get_cookie_params();
7474
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
7575
$this->sessionId = $session->getId();

src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,25 @@ public function testExistingController()
4747
$this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument));
4848
}
4949

50+
public function testExistingControllerWithATrailingBackSlash()
51+
{
52+
$resolver = new ServiceValueResolver(new ServiceLocator(array(
53+
'App\\Controller\\Mine::method' => function () {
54+
return new ServiceLocator(array(
55+
'dummy' => function () {
56+
return new DummyService();
57+
},
58+
));
59+
},
60+
)));
61+
62+
$request = $this->requestWithAttributes(array('_controller' => '\\App\\Controller\\Mine::method'));
63+
$argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
64+
65+
$this->assertTrue($resolver->supports($request, $argument));
66+
$this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument));
67+
}
68+
5069
public function testControllerNameIsAnArray()
5170
{
5271
$resolver = new ServiceValueResolver(new ServiceLocator(array(

src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
16-
use Symfony\Component\HttpFoundation\Cookie;
1716
use Symfony\Component\HttpFoundation\Response;
1817
use Symfony\Component\HttpFoundation\Request;
1918
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -46,6 +45,9 @@ protected function setUp()
4645
{
4746
$this->listener = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\EventListener\AbstractTestSessionListener');
4847
$this->session = $this->getSession();
48+
$this->listener->expects($this->any())
49+
->method('getSession')
50+
->will($this->returnValue($this->session));
4951
}
5052

5153
public function testShouldSaveMasterRequestSession()
@@ -95,7 +97,7 @@ public function testEmptySessionWithNewSessionIdDoesSendCookie()
9597
$this->fixSessionId('456');
9698

9799
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
98-
$request = Request::create('/', 'GET', array(), array(new Cookie('MOCKSESSID', '123')));
100+
$request = Request::create('/', 'GET', array(), array('MOCKSESSID' => '123'));
99101
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
100102
$this->listener->onKernelRequest($event);
101103

src/Symfony/Component/Validator/Mapping/Factory/LazyLoadingMetadataFactory.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,17 @@ public function getMetadataFor($value)
8888
return $this->loadedClasses[$class];
8989
}
9090

91+
if (!class_exists($class) && !interface_exists($class, false)) {
92+
throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class));
93+
}
94+
9195
if (null !== $this->cache && false !== ($metadata = $this->cache->read($class))) {
9296
// Include constraints from the parent class
9397
$this->mergeConstraints($metadata);
9498

9599
return $this->loadedClasses[$class] = $metadata;
96100
}
97101

98-
if (!class_exists($class) && !interface_exists($class)) {
99-
throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class));
100-
}
101-
102102
$metadata = new ClassMetadata($class);
103103

104104
if (null !== $this->loader) {

src/Symfony/Component/Validator/Tests/Mapping/Factory/LazyLoadingMetadataFactoryTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,21 @@ public function testReadMetadataFromCache()
149149
$this->assertEquals($metadata, $factory->getMetadataFor(self::PARENT_CLASS));
150150
}
151151

152+
/**
153+
* @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
154+
*/
155+
public function testNonClassNameStringValues()
156+
{
157+
$testedValue = '[email protected]';
158+
$loader = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock();
159+
$cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock();
160+
$factory = new LazyLoadingMetadataFactory($loader, $cache);
161+
$cache
162+
->expects($this->never())
163+
->method('read');
164+
$factory->getMetadataFor($testedValue);
165+
}
166+
152167
public function testMetadataCacheWithRuntimeConstraint()
153168
{
154169
$cache = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Cache\CacheInterface')->getMock();

0 commit comments

Comments
 (0)