Merge branch '3.4' into 4.3

* 3.4:
  [Twig] Remove dead code
  Add gitignore file for Symfony 3.4
  [Inflector] Add .gitignore file
  [Security] Removed unused argument in Test
  [Console] Get dimensions from stty on windows if possible
  [Inflector] add support 'see' to 'ee' for singularize 'fees' to 'fee'
This commit is contained in:
Fabien Potencier 2019-09-17 13:12:06 +02:00
commit 9072ba8b58
14 changed files with 103 additions and 76 deletions

View File

@ -34,9 +34,7 @@ class FormThemeTokenParserTest extends TestCase
$stream = $env->tokenize($source); $stream = $env->tokenize($source);
$parser = new Parser($env); $parser = new Parser($env);
if (method_exists($expected, 'setSourceContext')) { $expected->setSourceContext($source);
$expected->setSourceContext($source);
}
$this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)); $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0));
} }

View File

@ -112,13 +112,10 @@ class TwigExtractorTest extends TestCase
try { try {
$extractor->extract($resources, new MessageCatalogue('en')); $extractor->extract($resources, new MessageCatalogue('en'));
} catch (Error $e) { } catch (Error $e) {
if (method_exists($e, 'getSourceContext')) { $this->assertSame(\dirname(__DIR__).strtr('/Fixtures/extractor/syntax_error.twig', '/', \DIRECTORY_SEPARATOR), $e->getFile());
$this->assertSame(\dirname(__DIR__).strtr('/Fixtures/extractor/syntax_error.twig', '/', \DIRECTORY_SEPARATOR), $e->getFile()); $this->assertSame(1, $e->getLine());
$this->assertSame(1, $e->getLine()); $this->assertSame('Unclosed "block".', $e->getMessage());
$this->assertSame('Unclosed "block".', $e->getMessage());
} else {
$this->expectExceptionMessageRegExp('/Unclosed "block" in ".*extractor(\\/|\\\\)syntax_error\\.twig" at line 1/');
}
throw $e; throw $e;
} }
} }

View File

@ -61,11 +61,7 @@ class TwigExtractor extends AbstractFileExtractor implements ExtractorInterface
if ($file instanceof \SplFileInfo) { if ($file instanceof \SplFileInfo) {
$path = $file->getRealPath() ?: $file->getPathname(); $path = $file->getRealPath() ?: $file->getPathname();
$name = $file instanceof SplFileInfo ? $file->getRelativePathname() : $path; $name = $file instanceof SplFileInfo ? $file->getRelativePathname() : $path;
if (method_exists($e, 'setSourceContext')) { $e->setSourceContext(new Source('', $name, $path));
$e->setSourceContext(new Source('', $name, $path));
} else {
$e->setTemplateName($name);
}
} }
throw $e; throw $e;

View File

@ -15,7 +15,6 @@ namespace Symfony\Bundle\TwigBundle;
use Symfony\Bridge\Twig\TwigEngine as BaseEngine; use Symfony\Bridge\Twig\TwigEngine as BaseEngine;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
use Symfony\Component\Config\FileLocatorInterface; use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Templating\TemplateNameParserInterface; use Symfony\Component\Templating\TemplateNameParserInterface;
@ -40,28 +39,6 @@ class TwigEngine extends BaseEngine implements EngineInterface
$this->locator = $locator; $this->locator = $locator;
} }
/**
* {@inheritdoc}
*/
public function render($name, array $parameters = [])
{
try {
return parent::render($name, $parameters);
} catch (Error $e) {
if ($name instanceof TemplateReference && !method_exists($e, 'setSourceContext')) {
try {
// try to get the real name of the template where the error occurred
$name = $e->getTemplateName();
$path = (string) $this->locator->locate($this->parser->parse($name));
$e->setTemplateName($path);
} catch (\Exception $e2) {
}
}
throw $e;
}
}
/** /**
* {@inheritdoc} * {@inheritdoc}
* *

View File

@ -21,6 +21,7 @@ use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Terminal;
/** /**
* The QuestionHelper class provides helpers to interact with the user. * The QuestionHelper class provides helpers to interact with the user.
@ -117,7 +118,7 @@ class QuestionHelper extends Helper
$inputStream = $this->inputStream ?: STDIN; $inputStream = $this->inputStream ?: STDIN;
$autocomplete = $question->getAutocompleterCallback(); $autocomplete = $question->getAutocompleterCallback();
if (null === $autocomplete || !$this->hasSttyAvailable()) { if (null === $autocomplete || !Terminal::hasSttyAvailable()) {
$ret = false; $ret = false;
if ($question->isHidden()) { if ($question->isHidden()) {
try { try {
@ -376,7 +377,7 @@ class QuestionHelper extends Helper
return $value; return $value;
} }
if ($this->hasSttyAvailable()) { if (Terminal::hasSttyAvailable()) {
$sttyMode = shell_exec('stty -g'); $sttyMode = shell_exec('stty -g');
shell_exec('stty -echo'); shell_exec('stty -echo');
@ -462,18 +463,4 @@ class QuestionHelper extends Helper
return self::$shell; return self::$shell;
} }
/**
* Returns whether Stty is available or not.
*/
private function hasSttyAvailable(): bool
{
if (null !== self::$stty) {
return self::$stty;
}
exec('stty 2>&1', $output, $exitcode);
return self::$stty = 0 === $exitcode;
}
} }

View File

@ -15,6 +15,7 @@ class Terminal
{ {
private static $width; private static $width;
private static $height; private static $height;
private static $stty;
/** /**
* Gets the terminal width. * Gets the terminal width.
@ -54,6 +55,22 @@ class Terminal
return self::$height ?: 50; return self::$height ?: 50;
} }
/**
* @internal
*
* @return bool
*/
public static function hasSttyAvailable()
{
if (null !== self::$stty) {
return self::$stty;
}
exec('stty 2>&1', $output, $exitcode);
return self::$stty = 0 === $exitcode;
}
private static function initDimensions() private static function initDimensions()
{ {
if ('\\' === \DIRECTORY_SEPARATOR) { if ('\\' === \DIRECTORY_SEPARATOR) {
@ -62,12 +79,21 @@ class Terminal
// or [w, h] from "wxh" // or [w, h] from "wxh"
self::$width = (int) $matches[1]; self::$width = (int) $matches[1];
self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2]; self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
} elseif (self::hasSttyAvailable()) {
self::initDimensionsUsingStty();
} elseif (null !== $dimensions = self::getConsoleMode()) { } elseif (null !== $dimensions = self::getConsoleMode()) {
// extract [w, h] from "wxh" // extract [w, h] from "wxh"
self::$width = (int) $dimensions[0]; self::$width = (int) $dimensions[0];
self::$height = (int) $dimensions[1]; self::$height = (int) $dimensions[1];
} }
} elseif ($sttyString = self::getSttyColumns()) { } else {
self::initDimensionsUsingStty();
}
}
private static function initDimensionsUsingStty()
{
if ($sttyString = self::getSttyColumns()) {
if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) { if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
// extract [w, h] from "rows h; columns w;" // extract [w, h] from "rows h; columns w;"
self::$width = (int) $matches[2]; self::$width = (int) $matches[2];

View File

@ -19,6 +19,7 @@ use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Terminal;
/** /**
* @group tty * @group tty
@ -167,7 +168,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
public function testAskWithAutocomplete() public function testAskWithAutocomplete()
{ {
if (!$this->hasSttyAvailable()) { if (!Terminal::hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality'); $this->markTestSkipped('`stty` is required to test autocomplete functionality');
} }
@ -243,7 +244,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
public function testAskWithAutocompleteWithNonSequentialKeys() public function testAskWithAutocompleteWithNonSequentialKeys()
{ {
if (!$this->hasSttyAvailable()) { if (!Terminal::hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality'); $this->markTestSkipped('`stty` is required to test autocomplete functionality');
} }
@ -262,7 +263,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
public function testAskWithAutocompleteWithExactMatch() public function testAskWithAutocompleteWithExactMatch()
{ {
if (!$this->hasSttyAvailable()) { if (!Terminal::hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality'); $this->markTestSkipped('`stty` is required to test autocomplete functionality');
} }
@ -298,7 +299,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
*/ */
public function testAskWithAutocompleteWithMultiByteCharacter($character) public function testAskWithAutocompleteWithMultiByteCharacter($character)
{ {
if (!$this->hasSttyAvailable()) { if (!Terminal::hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality'); $this->markTestSkipped('`stty` is required to test autocomplete functionality');
} }
@ -322,7 +323,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
public function testAutocompleteWithTrailingBackslash() public function testAutocompleteWithTrailingBackslash()
{ {
if (!$this->hasSttyAvailable()) { if (!Terminal::hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality'); $this->markTestSkipped('`stty` is required to test autocomplete functionality');
} }
@ -669,7 +670,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
public function testTraversableAutocomplete() public function testTraversableAutocomplete()
{ {
if (!$this->hasSttyAvailable()) { if (!Terminal::hasSttyAvailable()) {
$this->markTestSkipped('`stty` is required to test autocomplete functionality'); $this->markTestSkipped('`stty` is required to test autocomplete functionality');
} }
@ -754,13 +755,6 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
return $mock; return $mock;
} }
private function hasSttyAvailable()
{
exec('stty 2>&1', $output, $exitcode);
return 0 === $exitcode;
}
} }
class AutocompleteValues implements \IteratorAggregate class AutocompleteValues implements \IteratorAggregate

View File

@ -18,17 +18,31 @@ class TerminalTest extends TestCase
{ {
private $colSize; private $colSize;
private $lineSize; private $lineSize;
private $ansiCon;
protected function setUp(): void protected function setUp(): void
{ {
$this->colSize = getenv('COLUMNS'); $this->colSize = getenv('COLUMNS');
$this->lineSize = getenv('LINES'); $this->lineSize = getenv('LINES');
$this->ansiCon = getenv('ANSICON');
$this->resetStatics();
} }
protected function tearDown(): void protected function tearDown(): void
{ {
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS'); putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
putenv($this->lineSize ? 'LINES' : 'LINES='.$this->lineSize); putenv($this->lineSize ? 'LINES' : 'LINES='.$this->lineSize);
putenv($this->ansiCon ? 'ANSICON='.$this->ansiCon : 'ANSICON');
$this->resetStatics();
}
private function resetStatics()
{
foreach (['height', 'width', 'stty'] as $name) {
$property = new \ReflectionProperty(Terminal::class, $name);
$property->setAccessible(true);
$property->setValue(null);
}
} }
public function test() public function test()
@ -56,4 +70,28 @@ class TerminalTest extends TestCase
$this->assertSame(0, $terminal->getWidth()); $this->assertSame(0, $terminal->getWidth());
$this->assertSame(0, $terminal->getHeight()); $this->assertSame(0, $terminal->getHeight());
} }
public function testSttyOnWindows()
{
if ('\\' !== \DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Must be on windows');
}
$sttyString = exec('(stty -a | grep columns) 2>&1', $output, $exitcode);
if (0 !== $exitcode) {
$this->markTestSkipped('Must have stty support');
}
$matches = [];
if (0 === preg_match('/columns.(\d+)/i', $sttyString, $matches)) {
$this->fail('Could not determine existing stty columns');
}
putenv('COLUMNS');
putenv('LINES');
putenv('ANSICON');
$terminal = new Terminal();
$this->assertSame((int) $matches[1], $terminal->getWidth());
}
} }

View File

@ -0,0 +1,3 @@
vendor/
composer.lock
phpunit.xml

View File

@ -120,6 +120,9 @@ final class Inflector
// bureaus (bureau) // bureaus (bureau)
['suae', 4, false, true, 'eau'], ['suae', 4, false, true, 'eau'],
// fees (fee), trees (tree), employees (employee)
['see', 3, true, true, 'ee'],
// roses (rose), garages (garage), cassettes (cassette), // roses (rose), garages (garage), cassettes (cassette),
// waltzes (waltz), heroes (hero), bushes (bush), arches (arch), // waltzes (waltz), heroes (hero), bushes (bush), arches (arch),
// shoes (shoe) // shoes (shoe)

View File

@ -38,7 +38,7 @@ class InflectorTest extends TestCase
['bases', ['bas', 'base', 'basis']], ['bases', ['bas', 'base', 'basis']],
['batches', ['batch', 'batche']], ['batches', ['batch', 'batche']],
['beaux', 'beau'], ['beaux', 'beau'],
['bees', ['be', 'bee']], ['bees', 'bee'],
['boxes', 'box'], ['boxes', 'box'],
['boys', 'boy'], ['boys', 'boy'],
['bureaus', 'bureau'], ['bureaus', 'bureau'],
@ -68,7 +68,9 @@ class InflectorTest extends TestCase
['echoes', ['echo', 'echoe']], ['echoes', ['echo', 'echoe']],
['elves', ['elf', 'elve', 'elff']], ['elves', ['elf', 'elve', 'elff']],
['emphases', ['emphas', 'emphase', 'emphasis']], ['emphases', ['emphas', 'emphase', 'emphasis']],
['employees', 'employee'],
['faxes', 'fax'], ['faxes', 'fax'],
['fees', 'fee'],
['feet', 'foot'], ['feet', 'foot'],
['feedback', 'feedback'], ['feedback', 'feedback'],
['foci', 'focus'], ['foci', 'focus'],
@ -143,14 +145,14 @@ class InflectorTest extends TestCase
['theses', ['thes', 'these', 'thesis']], ['theses', ['thes', 'these', 'thesis']],
['thieves', ['thief', 'thieve', 'thieff']], ['thieves', ['thief', 'thieve', 'thieff']],
['treasons', 'treason'], ['treasons', 'treason'],
['trees', ['tre', 'tree']], ['trees', 'tree'],
['waltzes', ['waltz', 'waltze']], ['waltzes', ['waltz', 'waltze']],
['wives', 'wife'], ['wives', 'wife'],
// test casing: if the first letter was uppercase, it should remain so // test casing: if the first letter was uppercase, it should remain so
['Men', 'Man'], ['Men', 'Man'],
['GrandChildren', 'GrandChild'], ['GrandChildren', 'GrandChild'],
['SubTrees', ['SubTre', 'SubTree']], ['SubTrees', 'SubTree'],
// Known issues // Known issues
//['insignia', 'insigne'], //['insignia', 'insigne'],

View File

@ -0,0 +1,3 @@
vendor/
composer.lock
phpunit.xml

View File

@ -87,7 +87,7 @@ class GuardAuthenticatorHandlerTest extends TestCase
/** /**
* @dataProvider getTokenClearingTests * @dataProvider getTokenClearingTests
*/ */
public function testHandleAuthenticationClearsToken($tokenClass, $tokenProviderKey, $actualProviderKey) public function testHandleAuthenticationClearsToken($tokenProviderKey, $actualProviderKey)
{ {
$this->tokenStorage->expects($this->never()) $this->tokenStorage->expects($this->never())
->method('setToken') ->method('setToken')
@ -108,10 +108,10 @@ class GuardAuthenticatorHandlerTest extends TestCase
public function getTokenClearingTests() public function getTokenClearingTests()
{ {
$tests = []; $tests = [];
// correct token class and matching firewall => clear the token // matching firewall => clear the token
$tests[] = ['Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'the_firewall_key']; $tests[] = ['the_firewall_key', 'the_firewall_key'];
$tests[] = ['Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken', 'the_firewall_key', 'different_key']; $tests[] = ['the_firewall_key', 'different_key'];
$tests[] = ['Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', 'the_firewall_key', 'the_firewall_key']; $tests[] = ['the_firewall_key', 'the_firewall_key'];
return $tests; return $tests;
} }

View File

@ -0,0 +1,3 @@
vendor/
composer.lock
phpunit.xml