Merge branch '4.4' into 5.2
* 4.4: [Console] ProgressBar clears too many lines on update [FrameworkBundle] Exclude unreadable files when executing About command [Bridge\Twig] Add 'form-control-range' for range input type Be explicit about transparent background color of links in toolbar [Translation] fix test case name [Cache] Fix wrong namespace in test [DependencyInjection] Fix return type
This commit is contained in:
commit
ca06651235
@ -134,9 +134,15 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block form_widget_simple -%}
|
{% block form_widget_simple -%}
|
||||||
{% if type is not defined or type != 'hidden' %}
|
{%- if type is not defined or type != 'hidden' -%}
|
||||||
{%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? ' custom-file-input' : ' form-control'))|trim}) -%}
|
{%- set className = ' form-control' -%}
|
||||||
{% endif %}
|
{%- if type|default('') == 'file' -%}
|
||||||
|
{%- set className = ' custom-file-input' -%}
|
||||||
|
{%- elseif type|default('') == 'range' -%}
|
||||||
|
{%- set className = ' form-control-range' -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- set attr = attr|merge({class: (attr.class|default('') ~ className)|trim}) -%}
|
||||||
|
{%- endif -%}
|
||||||
{%- if type is defined and (type == 'range' or type == 'color') %}
|
{%- if type is defined and (type == 'range' or type == 'color') %}
|
||||||
{# Attribute "required" is not supported #}
|
{# Attribute "required" is not supported #}
|
||||||
{%- set required = false -%}
|
{%- set required = false -%}
|
||||||
@ -144,12 +150,12 @@
|
|||||||
{{- parent() -}}
|
{{- parent() -}}
|
||||||
{%- endblock form_widget_simple %}
|
{%- endblock form_widget_simple %}
|
||||||
|
|
||||||
{%- block widget_attributes -%}
|
{% block widget_attributes -%}
|
||||||
{%- if not valid %}
|
{%- if not valid -%}
|
||||||
{% set attr = attr|merge({class: (attr.class|default('') ~ ' is-invalid')|trim}) %}
|
{% set attr = attr|merge({class: (attr.class|default('') ~ ' is-invalid')|trim}) %}
|
||||||
{% endif -%}
|
{%- endif -%}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
{%- endblock widget_attributes -%}
|
{%- endblock widget_attributes %}
|
||||||
|
|
||||||
{% block button_widget -%}
|
{% block button_widget -%}
|
||||||
{%- set attr = attr|merge({class: (attr.class|default('btn-secondary') ~ ' btn')|trim}) -%}
|
{%- set attr = attr|merge({class: (attr.class|default('btn-secondary') ~ ' btn')|trim}) -%}
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Form\Extension\Core\Type\FileType;
|
|||||||
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
|
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\PercentType;
|
use Symfony\Component\Form\Extension\Core\Type\PercentType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\RadioType;
|
use Symfony\Component\Form\Extension\Core\Type\RadioType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\RangeType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormError;
|
use Symfony\Component\Form\FormError;
|
||||||
|
|
||||||
@ -1227,6 +1228,41 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
|
|||||||
[contains(.., "‱")]
|
[contains(.., "‱")]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRange()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', RangeType::class, 42, ['attr' => ['min' => 5]]);
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath(
|
||||||
|
$form->createView(),
|
||||||
|
['attr' => ['class' => 'my&class']],
|
||||||
|
'/input
|
||||||
|
[@type="range"]
|
||||||
|
[@name="name"]
|
||||||
|
[@value="42"]
|
||||||
|
[@min="5"]
|
||||||
|
[@class="my&class form-control-range"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRangeWithMinMaxValues()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', RangeType::class, 42, ['attr' => ['min' => 5, 'max' => 57]]);
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath(
|
||||||
|
$form->createView(),
|
||||||
|
['attr' => ['class' => 'my&class']],
|
||||||
|
'/input
|
||||||
|
[@type="range"]
|
||||||
|
[@name="name"]
|
||||||
|
[@value="42"]
|
||||||
|
[@min="5"]
|
||||||
|
[@max="57"]
|
||||||
|
[@class="my&class form-control-range"]
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -113,9 +113,11 @@ EOT
|
|||||||
} else {
|
} else {
|
||||||
$size = 0;
|
$size = 0;
|
||||||
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS | \RecursiveDirectoryIterator::FOLLOW_SYMLINKS)) as $file) {
|
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS | \RecursiveDirectoryIterator::FOLLOW_SYMLINKS)) as $file) {
|
||||||
|
if ($file->isReadable()) {
|
||||||
$size += $file->getSize();
|
$size += $file->getSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Helper::formatMemory($size);
|
return Helper::formatMemory($size);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
<?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\AboutCommand;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Command\AboutCommand;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Tests\Command\AboutCommand\Fixture\TestAppKernel;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
|
||||||
|
use Symfony\Component\Console\Tester\CommandTester;
|
||||||
|
use Symfony\Component\Filesystem\Exception\IOException;
|
||||||
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
|
|
||||||
|
class AboutCommandTest extends TestCase
|
||||||
|
{
|
||||||
|
/** @var Filesystem */
|
||||||
|
private $fs;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->fs = new Filesystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAboutWithReadableFiles()
|
||||||
|
{
|
||||||
|
$kernel = new TestAppKernel('test', true);
|
||||||
|
$this->fs->mkdir($kernel->getProjectDir());
|
||||||
|
|
||||||
|
$this->fs->dumpFile($kernel->getCacheDir().'/readable_file', 'The file content.');
|
||||||
|
$this->fs->chmod($kernel->getCacheDir().'/readable_file', 0777);
|
||||||
|
|
||||||
|
$tester = $this->createCommandTester($kernel);
|
||||||
|
$ret = $tester->execute([]);
|
||||||
|
|
||||||
|
$this->assertSame(0, $ret);
|
||||||
|
$this->assertStringContainsString('Cache directory', $tester->getDisplay());
|
||||||
|
$this->assertStringContainsString('Log directory', $tester->getDisplay());
|
||||||
|
|
||||||
|
$this->fs->chmod($kernel->getCacheDir().'/readable_file', 0777);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->fs->remove($kernel->getProjectDir());
|
||||||
|
} catch (IOException $e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAboutWithUnreadableFiles()
|
||||||
|
{
|
||||||
|
$kernel = new TestAppKernel('test', true);
|
||||||
|
$this->fs->mkdir($kernel->getProjectDir());
|
||||||
|
|
||||||
|
// skip test on Windows; PHP can't easily set file as unreadable on Windows
|
||||||
|
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||||
|
$this->markTestSkipped('This test cannot run on Windows.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->fs->dumpFile($kernel->getCacheDir().'/unreadable_file', 'The file content.');
|
||||||
|
$this->fs->chmod($kernel->getCacheDir().'/unreadable_file', 0222);
|
||||||
|
|
||||||
|
$tester = $this->createCommandTester($kernel);
|
||||||
|
$ret = $tester->execute([]);
|
||||||
|
|
||||||
|
$this->assertSame(0, $ret);
|
||||||
|
$this->assertStringContainsString('Cache directory', $tester->getDisplay());
|
||||||
|
$this->assertStringContainsString('Log directory', $tester->getDisplay());
|
||||||
|
|
||||||
|
$this->fs->chmod($kernel->getCacheDir().'/unreadable_file', 0777);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->fs->remove($kernel->getProjectDir());
|
||||||
|
} catch (IOException $e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createCommandTester(TestAppKernel $kernel): CommandTester
|
||||||
|
{
|
||||||
|
$application = new Application($kernel);
|
||||||
|
$application->add(new AboutCommand());
|
||||||
|
|
||||||
|
return new CommandTester($application->find('about'));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
<?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\AboutCommand\Fixture;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
||||||
|
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\HttpKernel\Kernel;
|
||||||
|
|
||||||
|
class TestAppKernel extends Kernel
|
||||||
|
{
|
||||||
|
public function registerBundles(): iterable
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new FrameworkBundle(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProjectDir(): string
|
||||||
|
{
|
||||||
|
return __DIR__.'/test';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function build(ContainerBuilder $container)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -1696,7 +1696,7 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
$container->getCompilerPassConfig()->setAfterRemovingPasses([]);
|
$container->getCompilerPassConfig()->setAfterRemovingPasses([]);
|
||||||
}
|
}
|
||||||
$container->getCompilerPassConfig()->setBeforeOptimizationPasses([new LoggerPass()]);
|
$container->getCompilerPassConfig()->setBeforeOptimizationPasses([new LoggerPass()]);
|
||||||
$container->getCompilerPassConfig()->setBeforeRemovingPasses([new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader')]);
|
$container->getCompilerPassConfig()->setBeforeRemovingPasses([new AddConstraintValidatorsPass(), new TranslatorPass()]);
|
||||||
$container->getCompilerPassConfig()->setAfterRemovingPasses([new AddAnnotationsCachedReaderPass()]);
|
$container->getCompilerPassConfig()->setAfterRemovingPasses([new AddAnnotationsCachedReaderPass()]);
|
||||||
|
|
||||||
if (!$compile) {
|
if (!$compile) {
|
||||||
|
@ -105,6 +105,7 @@
|
|||||||
.sf-toolbar-block > a:hover {
|
.sf-toolbar-block > a:hover {
|
||||||
display: block;
|
display: block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
background-color: transparent;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +244,7 @@ div.sf-toolbar .sf-toolbar-block a:hover {
|
|||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
.sf-toolbar-block-request .sf-toolbar-info-piece a {
|
.sf-toolbar-block-request .sf-toolbar-info-piece a {
|
||||||
|
background-color: transparent;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.sf-toolbar-block-request .sf-toolbar-info-piece a:hover {
|
.sf-toolbar-block-request .sf-toolbar-info-piece a:hover {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Symfony\Component\Cache\Tests\Marshaller;
|
namespace Symfony\Component\Cache\Tests\DataCollector;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
||||||
|
@ -462,7 +462,7 @@ final class ProgressBar
|
|||||||
if ($this->overwrite) {
|
if ($this->overwrite) {
|
||||||
if (null !== $this->previousMessage) {
|
if (null !== $this->previousMessage) {
|
||||||
if ($this->output instanceof ConsoleSectionOutput) {
|
if ($this->output instanceof ConsoleSectionOutput) {
|
||||||
$lines = floor(Helper::strlen($message) / $this->terminal->getWidth()) + $this->formatLineCount + 1;
|
$lines = floor(Helper::strlenWithoutDecoration($this->output->getFormatter(), $message) / $this->terminal->getWidth()) + $this->formatLineCount + 1;
|
||||||
$this->output->clear($lines);
|
$this->output->clear($lines);
|
||||||
} else {
|
} else {
|
||||||
if ($this->formatLineCount > 0) {
|
if ($this->formatLineCount > 0) {
|
||||||
|
@ -343,6 +343,31 @@ class ProgressBarTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testOverwriteWithAnsiSectionOutput()
|
||||||
|
{
|
||||||
|
// output has 43 visible characters plus 2 invisible ANSI characters
|
||||||
|
putenv('COLUMNS=43');
|
||||||
|
$sections = [];
|
||||||
|
$stream = $this->getOutputStream(true);
|
||||||
|
$output = new ConsoleSectionOutput($stream->getStream(), $sections, $stream->getVerbosity(), $stream->isDecorated(), new OutputFormatter());
|
||||||
|
|
||||||
|
$bar = new ProgressBar($output, 50, 0);
|
||||||
|
$bar->setFormat(" \033[44;37m%current%/%max%\033[0m [%bar%] %percent:3s%%");
|
||||||
|
$bar->start();
|
||||||
|
$bar->display();
|
||||||
|
$bar->advance();
|
||||||
|
$bar->advance();
|
||||||
|
|
||||||
|
rewind($output->getStream());
|
||||||
|
$this->assertSame(
|
||||||
|
" \033[44;37m 0/50\033[0m [>---------------------------] 0%".\PHP_EOL.
|
||||||
|
"\x1b[1A\x1b[0J"." \033[44;37m 1/50\033[0m [>---------------------------] 2%".\PHP_EOL.
|
||||||
|
"\x1b[1A\x1b[0J"." \033[44;37m 2/50\033[0m [=>--------------------------] 4%".\PHP_EOL,
|
||||||
|
stream_get_contents($output->getStream())
|
||||||
|
);
|
||||||
|
putenv('COLUMNS=120');
|
||||||
|
}
|
||||||
|
|
||||||
public function testOverwriteMultipleProgressBarsWithSectionOutputs()
|
public function testOverwriteMultipleProgressBarsWithSectionOutputs()
|
||||||
{
|
{
|
||||||
$sections = [];
|
$sections = [];
|
||||||
|
@ -18,7 +18,7 @@ use Symfony\Component\DependencyInjection\Definition;
|
|||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
use Symfony\Component\Translation\DependencyInjection\TranslatorPass;
|
use Symfony\Component\Translation\DependencyInjection\TranslatorPass;
|
||||||
|
|
||||||
class TranslationPassTest extends TestCase
|
class TranslatorPassTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testValidCollector()
|
public function testValidCollector()
|
||||||
{
|
{
|
||||||
@ -35,7 +35,7 @@ class TranslationPassTest extends TestCase
|
|||||||
$container->setDefinition('translation.reader', $reader);
|
$container->setDefinition('translation.reader', $reader);
|
||||||
$container->setDefinition('translation.xliff_loader', $loader);
|
$container->setDefinition('translation.xliff_loader', $loader);
|
||||||
|
|
||||||
$pass = new TranslatorPass('translator.default', 'translation.reader');
|
$pass = new TranslatorPass();
|
||||||
$pass->process($container);
|
$pass->process($container);
|
||||||
|
|
||||||
$expectedReader = (new Definition())
|
$expectedReader = (new Definition())
|
||||||
@ -72,7 +72,7 @@ class TranslationPassTest extends TestCase
|
|||||||
;
|
;
|
||||||
$container->setParameter('twig.default_path', 'templates');
|
$container->setParameter('twig.default_path', 'templates');
|
||||||
|
|
||||||
$pass = new TranslatorPass('translator.default');
|
$pass = new TranslatorPass();
|
||||||
$pass->process($container);
|
$pass->process($container);
|
||||||
|
|
||||||
$expectedViewPaths = ['other/templates', 'tpl'];
|
$expectedViewPaths = ['other/templates', 'tpl'];
|
||||||
@ -113,7 +113,7 @@ class TranslationPassTest extends TestCase
|
|||||||
;
|
;
|
||||||
$container->setParameter('twig.default_path', 'templates');
|
$container->setParameter('twig.default_path', 'templates');
|
||||||
|
|
||||||
$pass = new TranslatorPass('translator.default');
|
$pass = new TranslatorPass();
|
||||||
$pass->process($container);
|
$pass->process($container);
|
||||||
|
|
||||||
$this->assertSame('templates', $debugCommand->getArgument(4));
|
$this->assertSame('templates', $debugCommand->getArgument(4));
|
@ -47,7 +47,7 @@ interface ServiceSubscriberInterface
|
|||||||
* * ['?Psr\Log\LoggerInterface'] is a shortcut for
|
* * ['?Psr\Log\LoggerInterface'] is a shortcut for
|
||||||
* * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface']
|
* * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface']
|
||||||
*
|
*
|
||||||
* @return array The required service types, optionally keyed by service names
|
* @return string[] The required service types, optionally keyed by service names
|
||||||
*/
|
*/
|
||||||
public static function getSubscribedServices();
|
public static function getSubscribedServices();
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,9 @@ trait ServiceSubscriberTrait
|
|||||||
/** @var ContainerInterface */
|
/** @var ContainerInterface */
|
||||||
protected $container;
|
protected $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
public static function getSubscribedServices(): array
|
public static function getSubscribedServices(): array
|
||||||
{
|
{
|
||||||
static $services;
|
static $services;
|
||||||
|
Reference in New Issue
Block a user