Merge branch '4.1'

* 4.1:
  Remove Process::escapeArgument argument type hint
  [Console] fix test using deprecated code
  [travis] build libsodium only if it's not already enabled
  Add a test case for stringifying of Process arguments
  Add a missing English translation
  [Console] Fixes multiselect choice question in interactive mode with default values
  [Validator] Add a missing Polish translation
  Allow integers as default console option value
  Setting missing default paths under BC layer
  Changed "epost-adress" to "e-postadress"
  Fix for race condition in console output stream write
  reverse transform RFC 3339 formatted dates
This commit is contained in:
Nicolas Grekas 2018-10-14 13:50:41 -07:00
commit 3db3ad21d0
11 changed files with 109 additions and 23 deletions

View File

@ -153,13 +153,15 @@ before_install:
wget http://ftp.debian.org/debian/pool/main/libr/librabbitmq/librabbitmq1_0.5.2-2_amd64.deb
sudo dpkg -i librabbitmq1_0.5.2-2_amd64.deb librabbitmq-dev_0.5.2-2_amd64.deb
# install libsodium
sudo add-apt-repository ppa:ondrej/php -y
sudo apt-get update -q
sudo apt-get install libsodium-dev -y
if ! php --ri sodium > /dev/null; then
# install libsodium
sudo add-apt-repository ppa:ondrej/php -y
sudo apt-get update -q
sudo apt-get install libsodium-dev -y
tfold ext.libsodium tpecl libsodium sodium.so $INI
fi
tfold ext.apcu tpecl apcu-5.1.6 apcu.so $INI
tfold ext.libsodium tpecl libsodium sodium.so $INI
tfold ext.mongodb tpecl mongodb-1.5.0 mongodb.so $INI
tfold ext.amqp tpecl amqp-1.9.3 amqp.so $INI
tfold ext.igbinary tpecl igbinary-2.0.6 igbinary.so $INI

View File

@ -47,13 +47,23 @@ class QuestionHelper extends Helper
}
if (!$input->isInteractive()) {
if ($question instanceof ChoiceQuestion) {
$default = $question->getDefault();
if (null !== $default && $question instanceof ChoiceQuestion) {
$choices = $question->getChoices();
return $choices[$question->getDefault()];
if (!$question->isMultiselect()) {
return isset($choices[$default]) ? $choices[$default] : $default;
}
$default = explode(',', $default);
foreach ($default as $k => $v) {
$v = trim($v);
$default[$k] = isset($choices[$v]) ? $choices[$v] : $v;
}
}
return $question->getDefault();
return $default;
}
if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) {

View File

@ -33,11 +33,11 @@ class InputOption
private $description;
/**
* @param string $name The option name
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int|null $mode The option mode: One of the VALUE_* constants
* @param string $description A description text
* @param string|string[]|bool|null $default The default value (must be null for self::VALUE_NONE)
* @param string $name The option name
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int|null $mode The option mode: One of the VALUE_* constants
* @param string $description A description text
* @param string|string[]|int|bool|null $default The default value (must be null for self::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*/
@ -149,7 +149,7 @@ class InputOption
/**
* Sets the default value.
*
* @param string|string[]|bool|null $default The default value
* @param string|string[]|int|bool|null $default The default value
*
* @throws LogicException When incorrect default value is given
*/
@ -173,7 +173,7 @@ class InputOption
/**
* Returns the default value.
*
* @return string|string[]|bool|null The default value
* @return string|string[]|int|bool|null The default value
*/
public function getDefault()
{

View File

@ -70,7 +70,11 @@ class StreamOutput extends Output
*/
protected function doWrite($message, $newline)
{
if (false === @fwrite($this->stream, $message) || ($newline && (false === @fwrite($this->stream, PHP_EOL)))) {
if ($newline) {
$message .= PHP_EOL;
}
if (false === @fwrite($this->stream, $message)) {
// should never happen
throw new RuntimeException('Unable to write output.');
}

View File

@ -89,6 +89,63 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
$this->assertEquals('Superman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, true), $this->createOutputInterface(), $question));
}
public function testAskChoiceNonInteractive()
{
$questionHelper = new QuestionHelper();
$helperSet = new HelperSet(array(new FormatterHelper()));
$questionHelper->setHelperSet($helperSet);
$inputStream = $this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n");
$heroes = array('Superman', 'Batman', 'Spiderman');
$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0');
$this->assertSame('Superman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, 'Batman');
$this->assertSame('Batman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
$this->assertNull($questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0');
$question->setValidator(null);
$this->assertSame('Superman', $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
try {
$question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null);
$questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question);
} catch (\InvalidArgumentException $e) {
$this->assertSame('Value "" is invalid', $e->getMessage());
}
$question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '0, 1');
$question->setMultiselect(true);
$this->assertSame(array('Superman', 'Batman'), $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
$question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '0, 1');
$question->setMultiselect(true);
$question->setValidator(null);
$this->assertSame(array('Superman', 'Batman'), $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
$question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '0, Batman');
$question->setMultiselect(true);
$this->assertSame(array('Superman', 'Batman'), $questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
$question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, null);
$question->setMultiselect(true);
$this->assertNull($questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question));
try {
$question = new ChoiceQuestion('Who are your favorite superheros?', $heroes, '');
$question->setMultiselect(true);
$questionHelper->ask($this->createStreamableInputInterfaceMock($inputStream, false), $this->createOutputInterface(), $question);
} catch (\InvalidArgumentException $e) {
$this->assertSame('Value "" is invalid', $e->getMessage());
}
}
public function testAsk()
{
$dialog = new QuestionHelper();

View File

@ -81,7 +81,9 @@ class DateTimeToHtml5LocalDateTimeTransformer extends BaseDateTimeTransformer
return;
}
if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})[T ]\d{2}:\d{2}(?::\d{2})?$/', $dateTimeLocal, $matches)) {
// to maintain backwards compatibility we do not strictly validate the submitted date
// see https://github.com/symfony/symfony/issues/28699
if (!preg_match('/^(\d{4})-(\d{2})-(\d{2})[T ]\d{2}:\d{2}(?::\d{2})?/', $dateTimeLocal, $matches)) {
throw new TransformationFailedException(sprintf('The date "%s" is not a valid date.', $dateTimeLocal));
}

View File

@ -51,6 +51,10 @@ class DateTimeToHtml5LocalDateTimeTransformerTest extends TestCase
array('UTC', 'UTC', '2010-02-03 04:05:00 UTC', '2010-02-03T04:05'),
array('America/New_York', 'Asia/Hong_Kong', '2010-02-03 04:05:00 America/New_York', '2010-02-03T17:05'),
array('Europe/Amsterdam', 'Europe/Amsterdam', '2013-08-21 10:30:00 Europe/Amsterdam', '2013-08-21T10:30:00'),
array('UTC', 'UTC', '2018-09-15T10:00:00Z', '2018-09-15T10:00:00Z'),
array('Europe/Berlin', 'Europe/Berlin', '2018-09-15T10:00:00+02:00', '2018-09-15T10:00:00+02:00'),
array('Europe/Berlin', 'Europe/Berlin', '2018-09-15T10:00:00+0200', '2018-09-15T10:00:00+0200'),
array('UTC', 'UTC', '2018-10-03T10:00:00.000Z', '2018-10-03T10:00:00.000Z'),
);
}

View File

@ -1606,14 +1606,14 @@ class Process implements \IteratorAggregate
/**
* Escapes a string to be used as a shell argument.
*/
private function escapeArgument(string $argument): string
private function escapeArgument(?string $argument): string
{
if ('' === $argument || null === $argument) {
return '""';
}
if ('\\' !== \DIRECTORY_SEPARATOR) {
return "'".str_replace("'", "'\\''", $argument)."'";
}
if ('' === $argument = (string) $argument) {
return '""';
}
if (false !== strpos($argument, "\0")) {
$argument = str_replace("\0", '?', $argument);
}

View File

@ -1463,7 +1463,7 @@ class ProcessTest extends TestCase
$p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg));
$p->run();
$this->assertSame($arg, $p->getOutput());
$this->assertSame((string) $arg, $p->getOutput());
}
public function testRawCommandLine()
@ -1493,6 +1493,9 @@ EOTXT;
yield array("a!b\tc");
yield array('a\\\\"\\"');
yield array('éÉèÈàÀöä');
yield array(null);
yield array(1);
yield array(1.1);
}
public function testEnvArgument()

View File

@ -322,6 +322,10 @@
<source>This is not a valid UUID.</source>
<target>To nie jest poprawne UUID.</target>
</trans-unit>
<trans-unit id="84">
<source>This value should be a multiple of {{ compared_value }}.</source>
<target>Ta wartość powinna być wielokrotnością {{ compared_value }}.</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -52,7 +52,7 @@
</trans-unit>
<trans-unit id="13">
<source>This value is not a valid email address.</source>
<target>Värdet är inte en giltig epost-adress.</target>
<target>Värdet är inte en giltig e-postadress.</target>
</trans-unit>
<trans-unit id="14">
<source>The file could not be found.</source>