Merge branch '3.4'
* 3.4: [Console] Fix descriptor tests Change wording from object to subject add changelog entry for Stopwatch::reset() Add DateCaster [Dotenv] parse concatenated variable values [Yaml] deprecate the !str tag Add filter in VarDumperTestTrait Support for parsing PHP constants in yaml loader
This commit is contained in:
commit
1437cafa1b
@ -61,5 +61,7 @@ Validator
|
||||
Yaml
|
||||
----
|
||||
|
||||
* Support for the `!str` tag is deprecated, use the `!!str` tag instead.
|
||||
|
||||
* Using the non-specific tag `!` is deprecated and will have a different
|
||||
behavior in 4.0. Use a plain integer or `!!float` instead.
|
||||
|
@ -569,6 +569,39 @@ Validator
|
||||
changed to `true` as of 4.0. If you need the previous behaviour ensure to
|
||||
set the option to `false`.
|
||||
|
||||
VarDumper
|
||||
---------
|
||||
|
||||
* The `VarDumperTestTrait::assertDumpEquals()` method expects a 3rd `$context = null`
|
||||
argument and moves `$message = ''` argument at 4th position.
|
||||
|
||||
Before:
|
||||
|
||||
```php
|
||||
VarDumperTestTrait::assertDumpEquals($dump, $data, $message = '');
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```php
|
||||
VarDumperTestTrait::assertDumpEquals($dump, $data, $filter = 0, $message = '');
|
||||
```
|
||||
|
||||
* The `VarDumperTestTrait::assertDumpMatchesFormat()` method expects a 3rd `$context = null`
|
||||
argument and moves `$message = ''` argument at 4th position.
|
||||
|
||||
Before:
|
||||
|
||||
```php
|
||||
VarDumperTestTrait::assertDumpMatchesFormat($dump, $data, $message = '');
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```php
|
||||
VarDumperTestTrait::assertDumpMatchesFormat($dump, $data, $filter = 0, $message = '');
|
||||
```
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
@ -577,6 +610,8 @@ Workflow
|
||||
Yaml
|
||||
----
|
||||
|
||||
* Support for the `!str` tag was removed, use the `!!str` tag instead.
|
||||
|
||||
* Starting an unquoted string with a question mark followed by a space
|
||||
throws a `ParseException`.
|
||||
|
||||
|
@ -159,40 +159,40 @@ trait ControllerTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the attributes are granted against the current authentication token and optionally supplied object.
|
||||
* Checks if the attributes are granted against the current authentication token and optionally supplied subject.
|
||||
*
|
||||
* @param mixed $attributes The attributes
|
||||
* @param mixed $object The object
|
||||
* @param mixed $subject The subject
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
protected function isGranted($attributes, $object = null)
|
||||
protected function isGranted($attributes, $subject = null)
|
||||
{
|
||||
if (!$this->container->has('security.authorization_checker')) {
|
||||
throw new \LogicException('The SecurityBundle is not registered in your application.');
|
||||
}
|
||||
|
||||
return $this->container->get('security.authorization_checker')->isGranted($attributes, $object);
|
||||
return $this->container->get('security.authorization_checker')->isGranted($attributes, $subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception unless the attributes are granted against the current authentication token and optionally
|
||||
* supplied object.
|
||||
* supplied subject.
|
||||
*
|
||||
* @param mixed $attributes The attributes
|
||||
* @param mixed $object The object
|
||||
* @param mixed $subject The subject
|
||||
* @param string $message The message passed to the exception
|
||||
*
|
||||
* @throws AccessDeniedException
|
||||
*/
|
||||
protected function denyAccessUnlessGranted($attributes, $object = null, $message = 'Access Denied.')
|
||||
protected function denyAccessUnlessGranted($attributes, $subject = null, $message = 'Access Denied.')
|
||||
{
|
||||
if (!$this->isGranted($attributes, $object)) {
|
||||
if (!$this->isGranted($attributes, $subject)) {
|
||||
$exception = $this->createAccessDeniedException($message);
|
||||
$exception->setAttributes($attributes);
|
||||
$exception->setSubject($object);
|
||||
$exception->setSubject($subject);
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
**argument_name:**
|
||||
#### `argument_name`
|
||||
|
||||
argument description
|
||||
|
||||
* Name: argument_name
|
||||
* Is required: no
|
||||
* Is array: no
|
||||
* Description: argument description
|
||||
* Default: `INF`
|
||||
|
@ -1,9 +1,8 @@
|
||||
**option_name:**
|
||||
#### `--option_name|-o`
|
||||
|
||||
option description
|
||||
|
||||
* Name: `--option_name`
|
||||
* Shortcut: `-o`
|
||||
* Accept value: yes
|
||||
* Is value required: no
|
||||
* Is multiple: no
|
||||
* Description: option description
|
||||
* Default: `INF`
|
||||
|
@ -169,73 +169,110 @@ final class Dotenv
|
||||
throw $this->createFormatException('Whitespace are not supported before the value');
|
||||
}
|
||||
|
||||
$value = '';
|
||||
$singleQuoted = false;
|
||||
$notQuoted = false;
|
||||
if ("'" === $this->data[$this->cursor]) {
|
||||
$singleQuoted = true;
|
||||
++$this->cursor;
|
||||
while ("\n" !== $this->data[$this->cursor]) {
|
||||
if ("'" === $this->data[$this->cursor]) {
|
||||
if ($this->cursor + 1 === $this->end) {
|
||||
$v = '';
|
||||
|
||||
do {
|
||||
if ("'" === $this->data[$this->cursor]) {
|
||||
$value = '';
|
||||
++$this->cursor;
|
||||
|
||||
while ("\n" !== $this->data[$this->cursor]) {
|
||||
if ("'" === $this->data[$this->cursor]) {
|
||||
break;
|
||||
}
|
||||
if ("'" !== $this->data[$this->cursor + 1]) {
|
||||
break;
|
||||
$value .= $this->data[$this->cursor];
|
||||
++$this->cursor;
|
||||
|
||||
if ($this->cursor === $this->end) {
|
||||
throw $this->createFormatException('Missing quote to end the value');
|
||||
}
|
||||
}
|
||||
if ("\n" === $this->data[$this->cursor]) {
|
||||
throw $this->createFormatException('Missing quote to end the value');
|
||||
}
|
||||
++$this->cursor;
|
||||
$v .= $value;
|
||||
} elseif ('"' === $this->data[$this->cursor]) {
|
||||
$value = '';
|
||||
++$this->cursor;
|
||||
|
||||
while ('"' !== $this->data[$this->cursor] || ('\\' === $this->data[$this->cursor - 1] && '\\' !== $this->data[$this->cursor - 2])) {
|
||||
$value .= $this->data[$this->cursor];
|
||||
++$this->cursor;
|
||||
|
||||
if ($this->cursor === $this->end) {
|
||||
throw $this->createFormatException('Missing quote to end the value');
|
||||
}
|
||||
}
|
||||
if ("\n" === $this->data[$this->cursor]) {
|
||||
throw $this->createFormatException('Missing quote to end the value');
|
||||
}
|
||||
++$this->cursor;
|
||||
$value = str_replace(array('\\\\', '\\"', '\r', '\n'), array('\\', '"', "\r", "\n"), $value);
|
||||
$resolvedValue = $value;
|
||||
$resolvedValue = $this->resolveVariables($resolvedValue);
|
||||
$resolvedValue = $this->resolveCommands($resolvedValue);
|
||||
$v .= $resolvedValue;
|
||||
} else {
|
||||
$value = '';
|
||||
$prevChr = $this->data[$this->cursor - 1];
|
||||
while ($this->cursor < $this->end && !in_array($this->data[$this->cursor], array("\n", '"', "'"), true) && !((' ' === $prevChr || "\t" === $prevChr) && '#' === $this->data[$this->cursor])) {
|
||||
if ('\\' === $this->data[$this->cursor] && isset($this->data[$this->cursor + 1]) && ('"' === $this->data[$this->cursor + 1] || "'" === $this->data[$this->cursor + 1])) {
|
||||
++$this->cursor;
|
||||
}
|
||||
|
||||
$value .= $prevChr = $this->data[$this->cursor];
|
||||
|
||||
if ('$' === $this->data[$this->cursor] && isset($this->data[$this->cursor + 1]) && '(' === $this->data[$this->cursor + 1]) {
|
||||
++$this->cursor;
|
||||
$value .= '('.$this->lexNestedExpression().')';
|
||||
}
|
||||
|
||||
++$this->cursor;
|
||||
}
|
||||
$value .= $this->data[$this->cursor];
|
||||
++$this->cursor;
|
||||
$value = rtrim($value);
|
||||
$resolvedValue = $value;
|
||||
$resolvedValue = $this->resolveVariables($resolvedValue);
|
||||
$resolvedValue = $this->resolveCommands($resolvedValue);
|
||||
|
||||
if ($this->cursor === $this->end) {
|
||||
throw $this->createFormatException('Missing quote to end the value');
|
||||
}
|
||||
}
|
||||
if ("\n" === $this->data[$this->cursor]) {
|
||||
throw $this->createFormatException('Missing quote to end the value');
|
||||
}
|
||||
++$this->cursor;
|
||||
} elseif ('"' === $this->data[$this->cursor]) {
|
||||
++$this->cursor;
|
||||
while ('"' !== $this->data[$this->cursor] || ('\\' === $this->data[$this->cursor - 1] && '\\' !== $this->data[$this->cursor - 2])) {
|
||||
$value .= $this->data[$this->cursor];
|
||||
++$this->cursor;
|
||||
|
||||
if ($this->cursor === $this->end) {
|
||||
throw $this->createFormatException('Missing quote to end the value');
|
||||
}
|
||||
}
|
||||
if ("\n" === $this->data[$this->cursor]) {
|
||||
throw $this->createFormatException('Missing quote to end the value');
|
||||
}
|
||||
++$this->cursor;
|
||||
$value = str_replace(array('\\\\', '\\"', '\r', '\n'), array('\\', '"', "\r", "\n"), $value);
|
||||
} else {
|
||||
$notQuoted = true;
|
||||
$prevChr = $this->data[$this->cursor - 1];
|
||||
while ($this->cursor < $this->end && "\n" !== $this->data[$this->cursor] && !((' ' === $prevChr || "\t" === $prevChr) && '#' === $this->data[$this->cursor])) {
|
||||
if ('\\' === $this->data[$this->cursor] && isset($this->data[$this->cursor + 1]) && ('"' === $this->data[$this->cursor + 1] || "'" === $this->data[$this->cursor + 1])) {
|
||||
++$this->cursor;
|
||||
if ($resolvedValue === $value && preg_match('/\s+/', $value)) {
|
||||
throw $this->createFormatException('A value containing spaces must be surrounded by quotes');
|
||||
}
|
||||
|
||||
$value .= $prevChr = $this->data[$this->cursor];
|
||||
++$this->cursor;
|
||||
$v .= $resolvedValue;
|
||||
|
||||
if ($this->cursor < $this->end && '#' === $this->data[$this->cursor]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$value = rtrim($value);
|
||||
}
|
||||
} while ($this->cursor < $this->end && "\n" !== $this->data[$this->cursor]);
|
||||
|
||||
$this->skipEmptyLines();
|
||||
|
||||
$currentValue = $value;
|
||||
if (!$singleQuoted) {
|
||||
$value = $this->resolveVariables($value);
|
||||
$value = $this->resolveCommands($value);
|
||||
return $v;
|
||||
}
|
||||
|
||||
private function lexNestedExpression()
|
||||
{
|
||||
++$this->cursor;
|
||||
$value = '';
|
||||
|
||||
while ("\n" !== $this->data[$this->cursor] && ')' !== $this->data[$this->cursor]) {
|
||||
$value .= $this->data[$this->cursor];
|
||||
|
||||
if ('(' === $this->data[$this->cursor]) {
|
||||
$value .= $this->lexNestedExpression().')';
|
||||
}
|
||||
|
||||
++$this->cursor;
|
||||
|
||||
if ($this->cursor === $this->end) {
|
||||
throw $this->createFormatException('Missing closing parenthesis.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($notQuoted && $currentValue == $value && preg_match('/\s+/', $value)) {
|
||||
throw $this->createFormatException('A value containing spaces must be surrounded by quotes');
|
||||
if ("\n" === $this->data[$this->cursor]) {
|
||||
throw $this->createFormatException('Missing closing parenthesis.');
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
@ -85,7 +85,6 @@ class DotenvTest extends TestCase
|
||||
array("FOO='bar'\n", array('FOO' => 'bar')),
|
||||
array("FOO='bar\"foo'\n", array('FOO' => 'bar"foo')),
|
||||
array("FOO=\"bar\\\"foo\"\n", array('FOO' => 'bar"foo')),
|
||||
array("FOO='bar''foo'\n", array('FOO' => 'bar\'foo')),
|
||||
array('FOO="bar\nfoo"', array('FOO' => "bar\nfoo")),
|
||||
array('FOO="bar\rfoo"', array('FOO' => "bar\rfoo")),
|
||||
array('FOO=\'bar\nfoo\'', array('FOO' => 'bar\nfoo')),
|
||||
@ -99,6 +98,10 @@ class DotenvTest extends TestCase
|
||||
array('FOO=\\"BAR', array('FOO' => '"BAR')),
|
||||
|
||||
// concatenated values
|
||||
array("FOO='bar''foo'\n", array('FOO' => 'barfoo')),
|
||||
array("FOO='bar '' baz'", array('FOO' => 'bar baz')),
|
||||
array("FOO=bar\nBAR='baz'\"\$FOO\"", array('FOO' => 'bar', 'BAR' => 'bazbar')),
|
||||
array("FOO='bar '\\'' baz'", array('FOO' => "bar ' baz")),
|
||||
|
||||
// comments
|
||||
array("#FOO=bar\nBAR=foo", array('BAR' => 'foo')),
|
||||
|
@ -51,7 +51,7 @@ class AuthorizationChecker implements AuthorizationCheckerInterface
|
||||
*
|
||||
* @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token.
|
||||
*/
|
||||
final public function isGranted($attributes, $object = null)
|
||||
final public function isGranted($attributes, $subject = null)
|
||||
{
|
||||
if (null === ($token = $this->tokenStorage->getToken())) {
|
||||
throw new AuthenticationCredentialsNotFoundException('The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.');
|
||||
@ -65,6 +65,6 @@ class AuthorizationChecker implements AuthorizationCheckerInterface
|
||||
$attributes = array($attributes);
|
||||
}
|
||||
|
||||
return $this->accessDecisionManager->decide($token, $attributes, $object);
|
||||
return $this->accessDecisionManager->decide($token, $attributes, $subject);
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ namespace Symfony\Component\Security\Core\Authorization;
|
||||
interface AuthorizationCheckerInterface
|
||||
{
|
||||
/**
|
||||
* Checks if the attributes are granted against the current authentication token and optionally supplied object.
|
||||
* Checks if the attributes are granted against the current authentication token and optionally supplied subject.
|
||||
*
|
||||
* @param mixed $attributes
|
||||
* @param mixed $object
|
||||
* @param mixed $subject
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isGranted($attributes, $object = null);
|
||||
public function isGranted($attributes, $subject = null);
|
||||
}
|
||||
|
7
src/Symfony/Component/Stopwatch/CHANGELOG.md
Normal file
7
src/Symfony/Component/Stopwatch/CHANGELOG.md
Normal file
@ -0,0 +1,7 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* added the `Stopwatch::reset()` method
|
@ -27,6 +27,7 @@ CHANGELOG
|
||||
-----
|
||||
|
||||
* deprecated `Tests\Constraints\AbstractContraintValidatorTest` in favor of `Test\ConstraintValidatorTestCase`
|
||||
* added support for PHP constants in YAML configuration files
|
||||
|
||||
3.1.0
|
||||
-----
|
||||
|
@ -116,7 +116,7 @@ class YamlFileLoader extends FileLoader
|
||||
private function parseFile($path)
|
||||
{
|
||||
try {
|
||||
$classes = $this->yamlParser->parse(file_get_contents($path), Yaml::PARSE_KEYS_AS_STRINGS);
|
||||
$classes = $this->yamlParser->parse(file_get_contents($path), Yaml::PARSE_KEYS_AS_STRINGS | Yaml::PARSE_CONSTANT);
|
||||
} catch (ParseException $e) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e);
|
||||
}
|
||||
|
@ -124,6 +124,19 @@ class YamlFileLoaderTest extends TestCase
|
||||
$this->assertEquals($expected, $metadata);
|
||||
}
|
||||
|
||||
public function testLoadClassMetadataWithConstants()
|
||||
{
|
||||
$loader = new YamlFileLoader(__DIR__.'/mapping-with-constants.yml');
|
||||
$metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
|
||||
|
||||
$loader->loadClassMetadata($metadata);
|
||||
|
||||
$expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
|
||||
$expected->addPropertyConstraint('firstName', new Range(array('max' => PHP_INT_MAX)));
|
||||
|
||||
$this->assertEquals($expected, $metadata);
|
||||
}
|
||||
|
||||
public function testLoadGroupSequenceProvider()
|
||||
{
|
||||
$loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
|
||||
|
@ -0,0 +1,8 @@
|
||||
namespaces:
|
||||
custom: Symfony\Component\Validator\Tests\Fixtures\
|
||||
|
||||
Symfony\Component\Validator\Tests\Fixtures\Entity:
|
||||
properties:
|
||||
firstName:
|
||||
- Range:
|
||||
max: !php/const:PHP_INT_MAX
|
41
src/Symfony/Component/VarDumper/Caster/DateCaster.php
Normal file
41
src/Symfony/Component/VarDumper/Caster/DateCaster.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Casts DateTimeInterface related classes to array representation.
|
||||
*
|
||||
* @author Dany Maillard <danymaillard93b@gmail.com>
|
||||
*/
|
||||
class DateCaster
|
||||
{
|
||||
public static function castDateTime(\DateTimeInterface $d, array $a, Stub $stub, $isNested, $filter)
|
||||
{
|
||||
$prefix = Caster::PREFIX_VIRTUAL;
|
||||
$location = $d->getTimezone()->getLocation();
|
||||
$fromNow = (new \DateTime())->diff($d);
|
||||
|
||||
$title = $d->format('l, F j, Y')
|
||||
."\n".$fromNow->format('%R').(ltrim($fromNow->format('%yy %mm %dd %H:%I:%Ss'), ' 0ymd:s') ?: '0s').' from now'
|
||||
.($location ? ($d->format('I') ? "\nDST On" : "\nDST Off") : '')
|
||||
;
|
||||
|
||||
$a = array();
|
||||
$a[$prefix.'date'] = new ConstStub($d->format('Y-m-d H:i:s.u '.($location ? 'e (P)' : 'P')), $title);
|
||||
|
||||
$stub->class .= $d->format(' @U');
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
@ -109,6 +109,8 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'Redis' => array('Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedis'),
|
||||
'RedisArray' => array('Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisArray'),
|
||||
|
||||
'DateTimeInterface' => array('Symfony\Component\VarDumper\Caster\DateCaster', 'castDateTime'),
|
||||
|
||||
':curl' => array('Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'),
|
||||
':dba' => array('Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'),
|
||||
':dba persistent' => array('Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'),
|
||||
|
@ -19,17 +19,29 @@ use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
*/
|
||||
trait VarDumperTestTrait
|
||||
{
|
||||
public function assertDumpEquals($dump, $data, $message = '')
|
||||
public function assertDumpEquals($dump, $data, $filter = 0, $message = '')
|
||||
{
|
||||
$this->assertSame(rtrim($dump), $this->getDump($data), $message);
|
||||
if (is_string($filter)) {
|
||||
@trigger_error(sprintf('The $message argument of the "%s()" method at 3rd position is deprecated since version 3.4 and will be moved at 4th position in 4.0.', __METHOD__), E_USER_DEPRECATED);
|
||||
$message = $filter;
|
||||
$filter = 0;
|
||||
}
|
||||
|
||||
$this->assertSame(rtrim($dump), $this->getDump($data, null, $filter), $message);
|
||||
}
|
||||
|
||||
public function assertDumpMatchesFormat($dump, $data, $message = '')
|
||||
public function assertDumpMatchesFormat($dump, $data, $filter = 0, $message = '')
|
||||
{
|
||||
$this->assertStringMatchesFormat(rtrim($dump), $this->getDump($data), $message);
|
||||
if (is_string($filter)) {
|
||||
@trigger_error(sprintf('The $message argument of the "%s()" method at 3rd position is deprecated since version 3.4 and will be moved at 4th position in 4.0.', __METHOD__), E_USER_DEPRECATED);
|
||||
$message = $filter;
|
||||
$filter = 0;
|
||||
}
|
||||
|
||||
$this->assertStringMatchesFormat(rtrim($dump), $this->getDump($data, null, $filter), $message);
|
||||
}
|
||||
|
||||
protected function getDump($data, $key = null)
|
||||
protected function getDump($data, $key = null, $filter = 0)
|
||||
{
|
||||
$flags = getenv('DUMP_LIGHT_ARRAY') ? CliDumper::DUMP_LIGHT_ARRAY : 0;
|
||||
$flags |= getenv('DUMP_STRING_LENGTH') ? CliDumper::DUMP_STRING_LENGTH : 0;
|
||||
@ -38,7 +50,7 @@ trait VarDumperTestTrait
|
||||
$cloner->setMaxItems(-1);
|
||||
$dumper = new CliDumper(null, null, $flags);
|
||||
$dumper->setColors(false);
|
||||
$data = $cloner->cloneVar($data)->withRefHandles(false);
|
||||
$data = $cloner->cloneVar($data, $filter)->withRefHandles(false);
|
||||
if (null !== $key && null === $data = $data->seek($key)) {
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
<?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\Component\VarDumper\Tests\Caster;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\VarDumper\Caster\DateCaster;
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
|
||||
|
||||
/**
|
||||
* @author Dany Maillard <danymaillard93b@gmail.com>
|
||||
*/
|
||||
class DateCasterTest extends TestCase
|
||||
{
|
||||
use VarDumperTestTrait;
|
||||
|
||||
/**
|
||||
* @dataProvider provideDateTimes
|
||||
*/
|
||||
public function testDumpDateTime($time, $timezone, $expected)
|
||||
{
|
||||
if ((defined('HHVM_VERSION_ID') || PHP_VERSION_ID <= 50509) && preg_match('/[-+]\d{2}:\d{2}/', $timezone)) {
|
||||
$this->markTestSkipped('DateTimeZone GMT offsets are supported since 5.5.10. See https://github.com/facebook/hhvm/issues/5875 for HHVM.');
|
||||
}
|
||||
|
||||
$date = new \DateTime($time, new \DateTimeZone($timezone));
|
||||
|
||||
$xDump = <<<EODUMP
|
||||
DateTime @1493503200 {
|
||||
date: $expected
|
||||
}
|
||||
EODUMP;
|
||||
|
||||
$this->assertDumpMatchesFormat($xDump, $date);
|
||||
}
|
||||
|
||||
public function testCastDateTime()
|
||||
{
|
||||
$stub = new Stub();
|
||||
$date = new \DateTime('2017-08-30 00:00:00.000000', new \DateTimeZone('Europe/Zurich'));
|
||||
$cast = DateCaster::castDateTime($date, array('foo' => 'bar'), $stub, false, 0);
|
||||
|
||||
$xDump = <<<'EODUMP'
|
||||
array:1 [
|
||||
"\x00~\x00date" => 2017-08-30 00:00:00.000000 Europe/Zurich (+02:00)
|
||||
]
|
||||
EODUMP;
|
||||
|
||||
$this->assertDumpMatchesFormat($xDump, $cast);
|
||||
|
||||
$xDump = <<<'EODUMP'
|
||||
Symfony\Component\VarDumper\Caster\ConstStub {
|
||||
+type: "ref"
|
||||
+class: "2017-08-30 00:00:00.000000 Europe/Zurich (+02:00)"
|
||||
+value: """
|
||||
Wednesday, August 30, 2017\n
|
||||
+%a from now\n
|
||||
DST On
|
||||
"""
|
||||
+cut: 0
|
||||
+handle: 0
|
||||
+refCount: 0
|
||||
+position: 0
|
||||
+attr: []
|
||||
}
|
||||
EODUMP;
|
||||
|
||||
$this->assertDumpMatchesFormat($xDump, $cast["\0~\0date"]);
|
||||
}
|
||||
|
||||
public function provideDateTimes()
|
||||
{
|
||||
return array(
|
||||
array('2017-04-30 00:00:00.000000', 'Europe/Zurich', '2017-04-30 00:00:00.000000 Europe/Zurich (+02:00)'),
|
||||
array('2017-04-30 00:00:00.000000', '+02:00', '2017-04-30 00:00:00.000000 +02:00'),
|
||||
);
|
||||
}
|
||||
}
|
@ -27,6 +27,8 @@ CHANGELOG
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* Support for the `!str` tag is deprecated, use the `!!str` tag instead.
|
||||
|
||||
* Deprecated using the non-specific tag `!` as its behavior will change in 4.0.
|
||||
It will force non-evaluating your values in 4.0. Use plain integers or `!!float` instead.
|
||||
|
||||
|
@ -551,7 +551,11 @@ class Inline
|
||||
case $scalar[0] === '!':
|
||||
switch (true) {
|
||||
case 0 === strpos($scalar, '!str'):
|
||||
@trigger_error('Support for the !str tag is deprecated since version 3.4. Use the !!str tag instead.', E_USER_DEPRECATED);
|
||||
|
||||
return (string) substr($scalar, 5);
|
||||
case 0 === strpos($scalar, '!!str '):
|
||||
return (string) substr($scalar, 6);
|
||||
case 0 === strpos($scalar, '! '):
|
||||
return substr($scalar, 2);
|
||||
case 0 === strpos($scalar, '!php/object:'):
|
||||
|
@ -572,7 +572,7 @@ test: Various explicit families
|
||||
todo: true
|
||||
spec: 2.23
|
||||
yaml: |
|
||||
not-date: !str 2002-04-28
|
||||
not-date: !!str 2002-04-28
|
||||
picture: !binary |
|
||||
R0lGODlhDAAMAIQAAP//9/X
|
||||
17unp5WZmZgAAAOfn515eXv
|
||||
@ -911,7 +911,7 @@ test: Explicit typing
|
||||
yaml: |
|
||||
integer: 12
|
||||
no int: ! 12
|
||||
string: !str 12
|
||||
string: !!str 12
|
||||
php: |
|
||||
array( 'integer' => 12, 'no int' => '12', 'string' => '12' )
|
||||
---
|
||||
@ -943,7 +943,7 @@ documents: 2
|
||||
test: Type family under yaml.org
|
||||
yaml: |
|
||||
# The URI is 'tag:yaml.org,2002:str'
|
||||
- !str a Unicode string
|
||||
- !!str a Unicode string
|
||||
php: |
|
||||
array( 'a Unicode string' )
|
||||
---
|
||||
@ -1330,7 +1330,7 @@ yaml: |
|
||||
|
||||
second: 12 ## This is an integer.
|
||||
|
||||
third: !str 12 ## This is a string.
|
||||
third: !!str 12 ## This is a string.
|
||||
|
||||
span: this contains
|
||||
six spaces
|
||||
@ -1399,7 +1399,7 @@ yaml: |
|
||||
# The following scalars
|
||||
# are loaded to the
|
||||
# string value '1' '2'.
|
||||
- !str 12
|
||||
- !!str 12
|
||||
- '12'
|
||||
- "12"
|
||||
- "\
|
||||
|
@ -52,10 +52,10 @@ php: |
|
||||
test: Forcing Strings
|
||||
brief: >
|
||||
Any YAML type can be forced into a string using the
|
||||
explicit !str method.
|
||||
explicit !!str method.
|
||||
yaml: |
|
||||
date string: !str 2001-08-01
|
||||
number string: !str 192
|
||||
date string: !!str 2001-08-01
|
||||
number string: !!str 192
|
||||
php: |
|
||||
array(
|
||||
'date string' => '2001-08-01',
|
||||
|
@ -703,4 +703,13 @@ class InlineTest extends TestCase
|
||||
'float' => array('{0.25: "foo"}', array('0.25' => 'foo')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation Support for the !str tag is deprecated since version 3.4. Use the !!str tag instead.
|
||||
*/
|
||||
public function testDeprecatedStrTag()
|
||||
{
|
||||
$this->assertSame(array('foo' => 'bar'), Inline::parse('{ foo: !str bar }'));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user