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:
Nicolas Grekas 2021-03-16 10:10:13 +01:00
commit ca06651235
13 changed files with 220 additions and 16 deletions

View File

@ -134,9 +134,15 @@
{% endblock %}
{% block form_widget_simple -%}
{% 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}) -%}
{% endif %}
{%- if type is not defined or type != 'hidden' -%}
{%- set className = ' form-control' -%}
{%- 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') %}
{# Attribute "required" is not supported #}
{%- set required = false -%}
@ -144,12 +150,12 @@
{{- parent() -}}
{%- endblock form_widget_simple %}
{%- block widget_attributes -%}
{%- if not valid %}
{% block widget_attributes -%}
{%- if not valid -%}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' is-invalid')|trim}) %}
{% endif -%}
{%- endif -%}
{{ parent() }}
{%- endblock widget_attributes -%}
{%- endblock widget_attributes %}
{% block button_widget -%}
{%- set attr = attr|merge({class: (attr.class|default('btn-secondary') ~ ' btn')|trim}) -%}

View File

@ -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\PercentType;
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\FormError;
@ -1227,6 +1228,41 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
[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"]
'
);
}

View File

@ -113,7 +113,9 @@ EOT
} else {
$size = 0;
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS | \RecursiveDirectoryIterator::FOLLOW_SYMLINKS)) as $file) {
$size += $file->getSize();
if ($file->isReadable()) {
$size += $file->getSize();
}
}
}

View File

@ -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'));
}
}

View File

@ -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)
{
}
}

View File

@ -1696,7 +1696,7 @@ abstract class FrameworkExtensionTest extends TestCase
$container->getCompilerPassConfig()->setAfterRemovingPasses([]);
}
$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()]);
if (!$compile) {

View File

@ -105,6 +105,7 @@
.sf-toolbar-block > a:hover {
display: block;
text-decoration: none;
background-color: transparent;
color: inherit;
}
@ -243,6 +244,7 @@ div.sf-toolbar .sf-toolbar-block a:hover {
padding: 0 10px;
}
.sf-toolbar-block-request .sf-toolbar-info-piece a {
background-color: transparent;
text-decoration: none;
}
.sf-toolbar-block-request .sf-toolbar-info-piece a:hover {

View File

@ -9,7 +9,7 @@
* 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 Symfony\Component\Cache\Adapter\TraceableAdapter;

View File

@ -462,7 +462,7 @@ final class ProgressBar
if ($this->overwrite) {
if (null !== $this->previousMessage) {
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);
} else {
if ($this->formatLineCount > 0) {

View File

@ -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()
{
$sections = [];

View File

@ -18,7 +18,7 @@ use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Translation\DependencyInjection\TranslatorPass;
class TranslationPassTest extends TestCase
class TranslatorPassTest extends TestCase
{
public function testValidCollector()
{
@ -35,7 +35,7 @@ class TranslationPassTest extends TestCase
$container->setDefinition('translation.reader', $reader);
$container->setDefinition('translation.xliff_loader', $loader);
$pass = new TranslatorPass('translator.default', 'translation.reader');
$pass = new TranslatorPass();
$pass->process($container);
$expectedReader = (new Definition())
@ -72,7 +72,7 @@ class TranslationPassTest extends TestCase
;
$container->setParameter('twig.default_path', 'templates');
$pass = new TranslatorPass('translator.default');
$pass = new TranslatorPass();
$pass->process($container);
$expectedViewPaths = ['other/templates', 'tpl'];
@ -113,7 +113,7 @@ class TranslationPassTest extends TestCase
;
$container->setParameter('twig.default_path', 'templates');
$pass = new TranslatorPass('translator.default');
$pass = new TranslatorPass();
$pass->process($container);
$this->assertSame('templates', $debugCommand->getArgument(4));

View File

@ -47,7 +47,7 @@ interface ServiceSubscriberInterface
* * ['?Psr\Log\LoggerInterface'] is a shortcut for
* * ['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();
}

View File

@ -24,6 +24,9 @@ trait ServiceSubscriberTrait
/** @var ContainerInterface */
protected $container;
/**
* {@inheritdoc}
*/
public static function getSubscribedServices(): array
{
static $services;