[OptionsResolver] Improve the deprecation feature by handling package + version

This commit is contained in:
Ahmed TAILOULOUTE 2020-04-04 21:42:42 +02:00
parent bfe6b6fb41
commit c3f5e2c1c8
15 changed files with 192 additions and 51 deletions

View File

@ -7,6 +7,7 @@ Config
* The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`. * The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`.
* The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecation(string $package, string $version, string $message)`. * The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecation(string $package, string $version, string $message)`.
* Passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node is deprecated * Passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node is deprecated
* Deprecated `BaseNode::getDeprecationMessage()`, use `BaseNode::getDeprecation()` instead
Console Console
------- -------
@ -21,6 +22,8 @@ DependencyInjection
* The signature of method `DeprecateTrait::deprecate()` has been updated to `DeprecateTrait::deprecation(string $package, string $version, string $message)`. * The signature of method `DeprecateTrait::deprecate()` has been updated to `DeprecateTrait::deprecation(string $package, string $version, string $message)`.
* Deprecated the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service, * Deprecated the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service,
configure them explicitly instead. configure them explicitly instead.
* Deprecated `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead.
* Deprecated `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead.
Dotenv Dotenv
------ ------
@ -86,6 +89,12 @@ Notifier
* [BC BREAK] The `EmailMessage::fromNotification()` and `SmsMessage::fromNotification()` * [BC BREAK] The `EmailMessage::fromNotification()` and `SmsMessage::fromNotification()`
methods' `$transport` argument was removed. methods' `$transport` argument was removed.
OptionsResolver
---------------
* The signature of method `OptionsResolver::setDeprecated()` has been updated to `OptionsResolver::setDeprecated(string $option, string $package, string $version, $message)`.
* Deprecated `OptionsResolverIntrospector::getDeprecationMessage()`, use `OptionsResolverIntrospector::getDeprecation()` instead.
PhpUnitBridge PhpUnitBridge
------------- -------------

View File

@ -7,6 +7,7 @@ Config
* The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`. * The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`.
* The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecation(string $package, string $version, string $message)`. * The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecation(string $package, string $version, string $message)`.
* Passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node is not supported anymore. * Passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node is not supported anymore.
* Removed `BaseNode::getDeprecationMessage()`, use `BaseNode::getDeprecation()` instead.
Console Console
------- -------
@ -21,6 +22,8 @@ DependencyInjection
* The signature of method `DeprecateTrait::deprecate()` has been updated to `DeprecateTrait::deprecation(string $package, string $version, string $message)`. * The signature of method `DeprecateTrait::deprecate()` has been updated to `DeprecateTrait::deprecation(string $package, string $version, string $message)`.
* Removed the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service, * Removed the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service,
configure them explicitly instead. configure them explicitly instead.
* Removed `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead.
* Removed `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead.
Dotenv Dotenv
------ ------
@ -69,6 +72,12 @@ Messenger
* The signature of method `RetryStrategyInterface::isRetryable()` has been updated to `RetryStrategyInterface::isRetryable(Envelope $message, \Throwable $throwable = null)`. * The signature of method `RetryStrategyInterface::isRetryable()` has been updated to `RetryStrategyInterface::isRetryable(Envelope $message, \Throwable $throwable = null)`.
* The signature of method `RetryStrategyInterface::getWaitingTime()` has been updated to `RetryStrategyInterface::getWaitingTime(Envelope $message, \Throwable $throwable = null)`. * The signature of method `RetryStrategyInterface::getWaitingTime()` has been updated to `RetryStrategyInterface::getWaitingTime(Envelope $message, \Throwable $throwable = null)`.
OptionsResolver
---------------
* The signature of method `OptionsResolver::setDeprecated()` has been updated to `OptionsResolver::setDeprecated(string $option, string $package, string $version, $message)`.
* Removed `OptionsResolverIntrospector::getDeprecationMessage()`, use `OptionsResolverIntrospector::getDeprecation()` instead.
PhpUnitBridge PhpUnitBridge
------------- -------------

View File

@ -7,6 +7,7 @@ CHANGELOG
* updated the signature of method `NodeDefinition::setDeprecated()` to `NodeDefinition::setDeprecation(string $package, string $version, string $message)` * updated the signature of method `NodeDefinition::setDeprecated()` to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`
* updated the signature of method `BaseNode::setDeprecated()` to `BaseNode::setDeprecation(string $package, string $version, string $message)` * updated the signature of method `BaseNode::setDeprecated()` to `BaseNode::setDeprecation(string $package, string $version, string $message)`
* deprecated passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node * deprecated passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node
* deprecated `BaseNode::getDeprecationMessage()`, use `BaseNode::getDeprecation()` instead
5.0.0 5.0.0
----- -----

View File

@ -14,6 +14,8 @@ CHANGELOG
configure them explicitly instead configure them explicitly instead
* added class `Symfony\Component\DependencyInjection\Dumper\Preloader` to help with preloading on PHP 7.4+ * added class `Symfony\Component\DependencyInjection\Dumper\Preloader` to help with preloading on PHP 7.4+
* added tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload * added tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload
* deprecated `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead
* deprecated `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead
5.0.0 5.0.0
----- -----

View File

@ -129,7 +129,7 @@ abstract class Descriptor implements DescriptorInterface
'allowedTypes' => 'getAllowedTypes', 'allowedTypes' => 'getAllowedTypes',
'allowedValues' => 'getAllowedValues', 'allowedValues' => 'getAllowedValues',
'normalizers' => 'getNormalizers', 'normalizers' => 'getNormalizers',
'deprecationMessage' => 'getDeprecationMessage', 'deprecation' => 'getDeprecation',
]; ];
foreach ($map as $key => $method) { foreach ($map as $key => $method) {
@ -140,8 +140,10 @@ abstract class Descriptor implements DescriptorInterface
} }
} }
if (isset($definition['deprecationMessage']) && \is_string($definition['deprecationMessage'])) { if (isset($definition['deprecation']) && isset($definition['deprecation']['message']) && \is_string($definition['deprecation']['message'])) {
$definition['deprecationMessage'] = strtr($definition['deprecationMessage'], ['%name%' => $option]); $definition['deprecationMessage'] = strtr($definition['deprecation']['message'], ['%name%' => $option]);
$definition['deprecationPackage'] = $definition['deprecation']['package'];
$definition['deprecationVersion'] = $definition['deprecation']['version'];
} }
return $definition; return $definition;

View File

@ -110,6 +110,8 @@ class TextDescriptor extends Descriptor
if ($definition['deprecated']) { if ($definition['deprecated']) {
$map = [ $map = [
'Deprecated' => 'deprecated', 'Deprecated' => 'deprecated',
'Deprecation package' => 'deprecationPackage',
'Deprecation version' => 'deprecationVersion',
'Deprecation message' => 'deprecationMessage', 'Deprecation message' => 'deprecationMessage',
]; ];
} }

View File

@ -198,7 +198,7 @@ class FooType extends AbstractType
{ {
$resolver->setRequired('foo'); $resolver->setRequired('foo');
$resolver->setDefined('bar'); $resolver->setDefined('bar');
$resolver->setDeprecated('bar'); $resolver->setDeprecated('bar', 'vendor/package', '1.1');
$resolver->setDefault('empty_data', function (Options $options) { $resolver->setDefault('empty_data', function (Options $options) {
$foo = $options['foo']; $foo = $options['foo'];

View File

@ -150,7 +150,7 @@ class FooType extends AbstractType
{ {
$resolver->setRequired('foo'); $resolver->setRequired('foo');
$resolver->setDefined('bar'); $resolver->setDefined('bar');
$resolver->setDeprecated('bar'); $resolver->setDeprecated('bar', 'vendor/package', '1.1');
$resolver->setDefault('empty_data', function (Options $options, $value) { $resolver->setDefault('empty_data', function (Options $options, $value) {
$foo = $options['foo']; $foo = $options['foo'];

View File

@ -3,6 +3,10 @@ Symfony\Component\Form\Tests\Console\Descriptor\FooType (bar)
--------------------- ----------------------------------- --------------------- -----------------------------------
Deprecated true Deprecated true
--------------------- -----------------------------------
Deprecation package "vendor/package"
--------------------- -----------------------------------
Deprecation version "1.1"
--------------------- ----------------------------------- --------------------- -----------------------------------
Deprecation message "The option "bar" is deprecated." Deprecation message "The option "bar" is deprecated."
--------------------- ----------------------------------- --------------------- -----------------------------------

View File

@ -6,6 +6,8 @@ CHANGELOG
* added fluent configuration of options using `OptionResolver::define()` * added fluent configuration of options using `OptionResolver::define()`
* added `setInfo()` and `getInfo()` methods * added `setInfo()` and `getInfo()` methods
* updated the signature of method `OptionsResolver::setDeprecated()` to `OptionsResolver::setDeprecation(string $option, string $package, string $version, $message)`
* deprecated `OptionsResolverIntrospector::getDeprecationMessage()`, use `OptionsResolverIntrospector::getDeprecation()` instead
5.0.0 5.0.0
----- -----

View File

@ -100,8 +100,20 @@ class OptionsResolverIntrospector
* @return string|\Closure * @return string|\Closure
* *
* @throws NoConfigurationException on no configured deprecation * @throws NoConfigurationException on no configured deprecation
*
* @deprecated since Symfony 5.1, use "getDeprecation()" instead.
*/ */
public function getDeprecationMessage(string $option) public function getDeprecationMessage(string $option)
{
trigger_deprecation('symfony/options-resolver', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);
return $this->getDeprecation($option)['message'];
}
/**
* @throws NoConfigurationException on no configured deprecation
*/
public function getDeprecation(string $option): array
{ {
return ($this->get)('deprecated', $option, sprintf('No deprecation was set for the "%s" option.', $option)); return ($this->get)('deprecated', $option, sprintf('No deprecation was set for the "%s" option.', $option));
} }

View File

@ -84,13 +84,28 @@ final class OptionConfigurator
/** /**
* Marks this option as deprecated. * Marks this option as deprecated.
* *
* @return $this * @param string $package The name of the composer package that is triggering the deprecation
* @param string $version The version of the package that introduced the deprecation
* @param string|\Closure $message The deprecation message to use
* *
* @param string|\Closure $deprecationMessage * @return $this
*/ */
public function deprecated($deprecationMessage = 'The option "%name%" is deprecated.'): self public function deprecated(/*string $package, string $version, $message = 'The option "%name%" is deprecated.'*/): self
{ {
$this->resolver->setDeprecated($this->name, $deprecationMessage); $args = \func_get_args();
if (\func_num_args() < 2) {
trigger_deprecation('symfony/options-resolver', '5.1', 'The signature of method "%s()" requires 2 new arguments: "string $package, string $version", not defining them is deprecated.', __METHOD__);
$message = $args[0] ?? 'The option "%name%" is deprecated.';
$package = (string) $version = '';
} else {
$package = (string) $args[0];
$version = (string) $args[1];
$message = (string) ($args[2] ?? 'The option "%name%" is deprecated.');
}
$this->resolver->setDeprecated($this->name, $package, $version, $message);
return $this; return $this;
} }

View File

@ -421,9 +421,11 @@ class OptionsResolver implements Options
* passed to the closure is the value of the option after validating it * passed to the closure is the value of the option after validating it
* and before normalizing it. * and before normalizing it.
* *
* @param string|\Closure $deprecationMessage * @param string $package The name of the composer package that is triggering the deprecation
* @param string $version The version of the package that introduced the deprecation
* @param string|\Closure $message The deprecation message to use
*/ */
public function setDeprecated(string $option, $deprecationMessage = 'The option "%name%" is deprecated.'): self public function setDeprecated(string $option/*, string $package, string $version, $message = 'The option "%name%" is deprecated.' */): self
{ {
if ($this->locked) { if ($this->locked) {
throw new AccessException('Options cannot be deprecated from a lazy option or normalizer.'); throw new AccessException('Options cannot be deprecated from a lazy option or normalizer.');
@ -433,16 +435,33 @@ class OptionsResolver implements Options
throw new UndefinedOptionsException(sprintf('The option "%s" does not exist, defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined)))); throw new UndefinedOptionsException(sprintf('The option "%s" does not exist, defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
} }
if (!\is_string($deprecationMessage) && !$deprecationMessage instanceof \Closure) { $args = \func_get_args();
throw new InvalidArgumentException(sprintf('Invalid type for deprecation message argument, expected string or \Closure, but got "%s".', get_debug_type($deprecationMessage)));
if (\func_num_args() < 3) {
trigger_deprecation('symfony/options-resolver', '5.1', 'The signature of method "%s()" requires 2 new arguments: "string $package, string $version", not defining them is deprecated.', __METHOD__);
$message = $args[1] ?? 'The option "%name%" is deprecated.';
$package = $version = '';
} else {
$package = $args[1];
$version = $args[2];
$message = $args[3] ?? 'The option "%name%" is deprecated.';
}
if (!\is_string($message) && !$message instanceof \Closure) {
throw new InvalidArgumentException(sprintf('Invalid type for deprecation message argument, expected string or \Closure, but got "%s".', get_debug_type($message)));
} }
// ignore if empty string // ignore if empty string
if ('' === $deprecationMessage) { if ('' === $message) {
return $this; return $this;
} }
$this->deprecated[$option] = $deprecationMessage; $this->deprecated[$option] = [
'package' => $package,
'version' => $version,
'message' => $message,
];
// Make sure the option is processed // Make sure the option is processed
unset($this->resolved[$option]); unset($this->resolved[$option]);
@ -903,8 +922,8 @@ class OptionsResolver implements Options
// Shortcut for resolved options // Shortcut for resolved options
if (isset($this->resolved[$option]) || \array_key_exists($option, $this->resolved)) { if (isset($this->resolved[$option]) || \array_key_exists($option, $this->resolved)) {
if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || $this->calling) && \is_string($this->deprecated[$option])) { if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || $this->calling) && \is_string($this->deprecated[$option]['message'])) {
trigger_deprecation('', '', strtr($this->deprecated[$option], ['%name%' => $option])); trigger_deprecation($this->deprecated[$option]['package'], $this->deprecated[$option]['version'], strtr($this->deprecated[$option]['message'], ['%name%' => $option]));
} }
return $this->resolved[$option]; return $this->resolved[$option];
@ -1048,9 +1067,10 @@ class OptionsResolver implements Options
// Check whether the option is deprecated // Check whether the option is deprecated
// and it is provided by the user or is being called from a lazy evaluation // and it is provided by the user or is being called from a lazy evaluation
if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || ($this->calling && \is_string($this->deprecated[$option])))) { if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || ($this->calling && \is_string($this->deprecated[$option])))) {
$deprecationMessage = $this->deprecated[$option]; $deprecation = $this->deprecated[$option];
$message = $this->deprecated[$option]['message'];
if ($deprecationMessage instanceof \Closure) { if ($message instanceof \Closure) {
// If the closure is already being called, we have a cyclic dependency // If the closure is already being called, we have a cyclic dependency
if (isset($this->calling[$option])) { if (isset($this->calling[$option])) {
throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', $this->formatOptions(array_keys($this->calling)))); throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', $this->formatOptions(array_keys($this->calling))));
@ -1058,16 +1078,16 @@ class OptionsResolver implements Options
$this->calling[$option] = true; $this->calling[$option] = true;
try { try {
if (!\is_string($deprecationMessage = $deprecationMessage($this, $value))) { if (!\is_string($message = $message($this, $value))) {
throw new InvalidOptionsException(sprintf('Invalid type for deprecation message, expected string but got "%s", return an empty string to ignore.', get_debug_type($deprecationMessage))); throw new InvalidOptionsException(sprintf('Invalid type for deprecation message, expected string but got "%s", return an empty string to ignore.', get_debug_type($message)));
} }
} finally { } finally {
unset($this->calling[$option]); unset($this->calling[$option]);
} }
} }
if ('' !== $deprecationMessage) { if ('' !== $message) {
trigger_deprecation('', '', strtr($deprecationMessage, ['%name%' => $option])); trigger_deprecation($deprecation['package'], $deprecation['version'], strtr($message, ['%name%' => $option]));
} }
} }

View File

@ -213,6 +213,9 @@ class OptionsResolverIntrospectorTest extends TestCase
$debug->getNormalizers('foo'); $debug->getNormalizers('foo');
} }
/**
* @group legacy
*/
public function testGetDeprecationMessage() public function testGetDeprecationMessage()
{ {
$resolver = new OptionsResolver(); $resolver = new OptionsResolver();
@ -223,6 +226,9 @@ class OptionsResolverIntrospectorTest extends TestCase
$this->assertSame('The option "foo" is deprecated.', $debug->getDeprecationMessage('foo')); $this->assertSame('The option "foo" is deprecated.', $debug->getDeprecationMessage('foo'));
} }
/**
* @group legacy
*/
public function testGetClosureDeprecationMessage() public function testGetClosureDeprecationMessage()
{ {
$resolver = new OptionsResolver(); $resolver = new OptionsResolver();
@ -233,6 +239,34 @@ class OptionsResolverIntrospectorTest extends TestCase
$this->assertSame($closure, $debug->getDeprecationMessage('foo')); $this->assertSame($closure, $debug->getDeprecationMessage('foo'));
} }
public function testGetDeprecation()
{
$resolver = new OptionsResolver();
$resolver->setDefined('foo');
$resolver->setDeprecated('foo', 'vendor/package', '1.1', 'The option "foo" is deprecated.');
$debug = new OptionsResolverIntrospector($resolver);
$this->assertSame([
'package' => 'vendor/package',
'version' => '1.1',
'message' => 'The option "foo" is deprecated.',
], $debug->getDeprecation('foo'));
}
public function testGetClosureDeprecation()
{
$resolver = new OptionsResolver();
$resolver->setDefined('foo');
$resolver->setDeprecated('foo', 'vendor/package', '1.1', $closure = function (Options $options, $value) {});
$debug = new OptionsResolverIntrospector($resolver);
$this->assertSame([
'package' => 'vendor/package',
'version' => '1.1',
'message' => $closure,
], $debug->getDeprecation('foo'));
}
public function testGetDeprecationMessageThrowsOnNoConfiguredValue() public function testGetDeprecationMessageThrowsOnNoConfiguredValue()
{ {
$this->expectException('Symfony\Component\OptionsResolver\Exception\NoConfigurationException'); $this->expectException('Symfony\Component\OptionsResolver\Exception\NoConfigurationException');
@ -241,7 +275,7 @@ class OptionsResolverIntrospectorTest extends TestCase
$resolver->setDefined('foo'); $resolver->setDefined('foo');
$debug = new OptionsResolverIntrospector($resolver); $debug = new OptionsResolverIntrospector($resolver);
$this->assertSame('bar', $debug->getDeprecationMessage('foo')); $debug->getDeprecation('foo');
} }
public function testGetDeprecationMessageThrowsOnNotDefinedOption() public function testGetDeprecationMessageThrowsOnNotDefinedOption()
@ -251,6 +285,6 @@ class OptionsResolverIntrospectorTest extends TestCase
$resolver = new OptionsResolver(); $resolver = new OptionsResolver();
$debug = new OptionsResolverIntrospector($resolver); $debug = new OptionsResolverIntrospector($resolver);
$this->assertSame('bar', $debug->getDeprecationMessage('foo')); $debug->getDeprecation('foo');
} }
} }

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\OptionsResolver\Tests;
use PHPUnit\Framework\Assert; use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Component\OptionsResolver\Debug\OptionsResolverIntrospector; use Symfony\Component\OptionsResolver\Debug\OptionsResolverIntrospector;
use Symfony\Component\OptionsResolver\Exception\AccessException; use Symfony\Component\OptionsResolver\Exception\AccessException;
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
@ -22,6 +23,8 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class OptionsResolverTest extends TestCase class OptionsResolverTest extends TestCase
{ {
use ExpectDeprecationTrait;
/** /**
* @var OptionsResolver * @var OptionsResolver
*/ */
@ -463,7 +466,7 @@ class OptionsResolverTest extends TestCase
$this->expectExceptionMessage('Invalid type for deprecation message argument, expected string or \Closure, but got "bool".'); $this->expectExceptionMessage('Invalid type for deprecation message argument, expected string or \Closure, but got "bool".');
$this->resolver $this->resolver
->setDefined('foo') ->setDefined('foo')
->setDeprecated('foo', true) ->setDeprecated('foo', 'vendor/package', '1.1', true)
; ;
} }
@ -473,7 +476,7 @@ class OptionsResolverTest extends TestCase
$this->expectExceptionMessage('Invalid type for deprecation message, expected string but got "bool", return an empty string to ignore.'); $this->expectExceptionMessage('Invalid type for deprecation message, expected string but got "bool", return an empty string to ignore.');
$this->resolver $this->resolver
->setDefined('foo') ->setDefined('foo')
->setDeprecated('foo', function (Options $options, $value) { ->setDeprecated('foo', 'vendor/package', '1.1', function (Options $options, $value) {
return false; return false;
}) })
; ;
@ -486,10 +489,10 @@ class OptionsResolverTest extends TestCase
$this->expectExceptionMessage('The options "foo", "bar" have a cyclic dependency.'); $this->expectExceptionMessage('The options "foo", "bar" have a cyclic dependency.');
$this->resolver $this->resolver
->setDefined(['foo', 'bar']) ->setDefined(['foo', 'bar'])
->setDeprecated('foo', function (Options $options, $value) { ->setDeprecated('foo', 'vendor/package', '1.1', function (Options $options, $value) {
$options['bar']; $options['bar'];
}) })
->setDeprecated('bar', function (Options $options, $value) { ->setDeprecated('bar', 'vendor/package', '1.1', function (Options $options, $value) {
$options['foo']; $options['foo'];
}) })
; ;
@ -500,7 +503,7 @@ class OptionsResolverTest extends TestCase
{ {
$this->resolver $this->resolver
->setDefined('foo') ->setDefined('foo')
->setDeprecated('foo') ->setDeprecated('foo', 'vendor/package', '1.1')
; ;
$this->assertTrue($this->resolver->isDeprecated('foo')); $this->assertTrue($this->resolver->isDeprecated('foo'));
} }
@ -509,7 +512,7 @@ class OptionsResolverTest extends TestCase
{ {
$this->resolver $this->resolver
->setDefined('foo') ->setDefined('foo')
->setDeprecated('foo', '') ->setDeprecated('foo', 'vendor/package', '1.1', '')
; ;
$this->assertFalse($this->resolver->isDeprecated('foo')); $this->assertFalse($this->resolver->isDeprecated('foo'));
} }
@ -547,13 +550,13 @@ class OptionsResolverTest extends TestCase
function (OptionsResolver $resolver) { function (OptionsResolver $resolver) {
$resolver $resolver
->setDefined(['foo', 'bar']) ->setDefined(['foo', 'bar'])
->setDeprecated('foo') ->setDeprecated('foo', 'vendor/package', '1.1', 'The option "%name%" is deprecated.')
; ;
}, },
['foo' => 'baz'], ['foo' => 'baz'],
[ [
'type' => E_USER_DEPRECATED, 'type' => E_USER_DEPRECATED,
'message' => 'The option "foo" is deprecated.', 'message' => 'Since vendor/package 1.1: The option "foo" is deprecated.',
], ],
1, 1,
]; ];
@ -565,13 +568,13 @@ class OptionsResolverTest extends TestCase
->setDefault('bar', function (Options $options) { ->setDefault('bar', function (Options $options) {
return $options['foo']; return $options['foo'];
}) })
->setDeprecated('foo', 'The option "foo" is deprecated, use "bar" option instead.') ->setDeprecated('foo', 'vendor/package', '1.1', 'The option "foo" is deprecated, use "bar" option instead.')
; ;
}, },
['foo' => 'baz'], ['foo' => 'baz'],
[ [
'type' => E_USER_DEPRECATED, 'type' => E_USER_DEPRECATED,
'message' => 'The option "foo" is deprecated, use "bar" option instead.', 'message' => 'Since vendor/package 1.1: The option "foo" is deprecated, use "bar" option instead.',
], ],
2, 2,
]; ];
@ -581,7 +584,7 @@ class OptionsResolverTest extends TestCase
// defined by superclass // defined by superclass
$resolver $resolver
->setDefault('foo', null) ->setDefault('foo', null)
->setDeprecated('foo') ->setDeprecated('foo', 'vendor/package', '1.1', 'The option "%name%" is deprecated.')
; ;
// defined by subclass // defined by subclass
$resolver->setDefault('bar', function (Options $options) { $resolver->setDefault('bar', function (Options $options) {
@ -591,7 +594,7 @@ class OptionsResolverTest extends TestCase
[], [],
[ [
'type' => E_USER_DEPRECATED, 'type' => E_USER_DEPRECATED,
'message' => 'The option "foo" is deprecated.', 'message' => 'Since vendor/package 1.1: The option "foo" is deprecated.',
], ],
1, 1,
]; ];
@ -601,7 +604,7 @@ class OptionsResolverTest extends TestCase
$resolver $resolver
->setDefault('foo', null) ->setDefault('foo', null)
->setAllowedTypes('foo', ['null', 'string', \stdClass::class]) ->setAllowedTypes('foo', ['null', 'string', \stdClass::class])
->setDeprecated('foo', function (Options $options, $value) { ->setDeprecated('foo', 'vendor/package', '1.1', function (Options $options, $value) {
if ($value instanceof \stdClass) { if ($value instanceof \stdClass) {
return sprintf('Passing an instance of "%s" to option "foo" is deprecated, pass its FQCN instead.', \stdClass::class); return sprintf('Passing an instance of "%s" to option "foo" is deprecated, pass its FQCN instead.', \stdClass::class);
} }
@ -613,7 +616,7 @@ class OptionsResolverTest extends TestCase
['foo' => new \stdClass()], ['foo' => new \stdClass()],
[ [
'type' => E_USER_DEPRECATED, 'type' => E_USER_DEPRECATED,
'message' => 'Passing an instance of "stdClass" to option "foo" is deprecated, pass its FQCN instead.', 'message' => 'Since vendor/package 1.1: Passing an instance of "stdClass" to option "foo" is deprecated, pass its FQCN instead.',
], ],
1, 1,
]; ];
@ -623,7 +626,7 @@ class OptionsResolverTest extends TestCase
$resolver $resolver
->setDefined('foo') ->setDefined('foo')
->setAllowedTypes('foo', ['null', 'bool']) ->setAllowedTypes('foo', ['null', 'bool'])
->setDeprecated('foo', function (Options $options, $value) { ->setDeprecated('foo', 'vendor/package', '1.1', function (Options $options, $value) {
if (!\is_bool($value)) { if (!\is_bool($value)) {
return 'Passing a value different than true or false is deprecated.'; return 'Passing a value different than true or false is deprecated.';
} }
@ -632,7 +635,7 @@ class OptionsResolverTest extends TestCase
}) })
->setDefault('baz', null) ->setDefault('baz', null)
->setAllowedTypes('baz', ['null', 'int']) ->setAllowedTypes('baz', ['null', 'int'])
->setDeprecated('baz', function (Options $options, $value) { ->setDeprecated('baz', 'vendor/package', '1.1', function (Options $options, $value) {
if (!\is_int($value)) { if (!\is_int($value)) {
return 'Not passing an integer is deprecated.'; return 'Not passing an integer is deprecated.';
} }
@ -649,7 +652,7 @@ class OptionsResolverTest extends TestCase
['foo' => null], // It triggers a deprecation ['foo' => null], // It triggers a deprecation
[ [
'type' => E_USER_DEPRECATED, 'type' => E_USER_DEPRECATED,
'message' => 'Passing a value different than true or false is deprecated.', 'message' => 'Since vendor/package 1.1: Passing a value different than true or false is deprecated.',
], ],
1, 1,
]; ];
@ -658,7 +661,7 @@ class OptionsResolverTest extends TestCase
function (OptionsResolver $resolver) { function (OptionsResolver $resolver) {
$resolver $resolver
->setDefault('foo', null) ->setDefault('foo', null)
->setDeprecated('foo', function (Options $options, $value) { ->setDeprecated('foo', 'vendor/package', '1.1', function (Options $options, $value) {
return ''; return '';
}) })
; ;
@ -673,7 +676,7 @@ class OptionsResolverTest extends TestCase
$resolver $resolver
->setDefault('widget', null) ->setDefault('widget', null)
->setDefault('date_format', null) ->setDefault('date_format', null)
->setDeprecated('date_format', function (Options $options, $dateFormat) { ->setDeprecated('date_format', 'vendor/package', '1.1', function (Options $options, $dateFormat) {
if (null !== $dateFormat && 'single_text' === $options['widget']) { if (null !== $dateFormat && 'single_text' === $options['widget']) {
return 'Using the "date_format" option when the "widget" option is set to "single_text" is deprecated.'; return 'Using the "date_format" option when the "widget" option is set to "single_text" is deprecated.';
} }
@ -685,7 +688,7 @@ class OptionsResolverTest extends TestCase
['widget' => 'single_text', 'date_format' => 2], ['widget' => 'single_text', 'date_format' => 2],
[ [
'type' => E_USER_DEPRECATED, 'type' => E_USER_DEPRECATED,
'message' => 'Using the "date_format" option when the "widget" option is set to "single_text" is deprecated.', 'message' => 'Since vendor/package 1.1: Using the "date_format" option when the "widget" option is set to "single_text" is deprecated.',
], ],
1, 1,
]; ];
@ -695,7 +698,7 @@ class OptionsResolverTest extends TestCase
$resolver $resolver
// defined by superclass // defined by superclass
->setDefined('foo') ->setDefined('foo')
->setDeprecated('foo') ->setDeprecated('foo', 'vendor/package', '1.1', 'The option "%name%" is deprecated.')
// defined by subclass // defined by subclass
->setDefault('bar', function (Options $options) { ->setDefault('bar', function (Options $options) {
return $options['foo']; // It triggers a deprecation return $options['foo']; // It triggers a deprecation
@ -711,7 +714,7 @@ class OptionsResolverTest extends TestCase
['foo' => 'baz'], // It triggers a deprecation ['foo' => 'baz'], // It triggers a deprecation
[ [
'type' => E_USER_DEPRECATED, 'type' => E_USER_DEPRECATED,
'message' => 'The option "foo" is deprecated.', 'message' => 'Since vendor/package 1.1: The option "foo" is deprecated.',
], ],
4, 4,
]; ];
@ -721,8 +724,8 @@ class OptionsResolverTest extends TestCase
$resolver $resolver
->setDefined('foo') ->setDefined('foo')
->setDefault('bar', null) ->setDefault('bar', null)
->setDeprecated('foo') ->setDeprecated('foo', 'vendor/package', '1.1', 'The option "%name%" is deprecated.')
->setDeprecated('bar') ->setDeprecated('bar', 'vendor/package', '1.1', 'The option "%name%" is deprecated.')
; ;
}, },
[], [],
@ -737,7 +740,7 @@ class OptionsResolverTest extends TestCase
return $options->offsetGet('foo', false); return $options->offsetGet('foo', false);
}) })
->setDefault('foo', null) ->setDefault('foo', null)
->setDeprecated('foo') ->setDeprecated('foo', 'vendor/package', '1.1', 'The option "%name%" is deprecated.')
->setDefault('bar', function (Options $options) { ->setDefault('bar', function (Options $options) {
return $options->offsetGet('foo', false); return $options->offsetGet('foo', false);
}) })
@ -2390,11 +2393,24 @@ class OptionsResolverTest extends TestCase
$this->resolver->define('foo'); $this->resolver->define('foo');
} }
/**
* @group legacy
*/
public function testDeprecatedByOptionConfiguratorWithoutPackageAndVersion()
{
$this->expectDeprecation('Since symfony/options-resolver 5.1: The signature of method "Symfony\Component\OptionsResolver\OptionConfigurator::deprecated()" requires 2 new arguments: "string $package, string $version", not defining them is deprecated.');
$this->resolver
->define('foo')
->deprecated()
;
}
public function testResolveOptionsDefinedByOptionConfigurator() public function testResolveOptionsDefinedByOptionConfigurator()
{ {
$this->resolver->define('foo') $this->resolver->define('foo')
->required() ->required()
->deprecated() ->deprecated('vendor/package', '1.1')
->default('bar') ->default('bar')
->allowedTypes('string', 'bool') ->allowedTypes('string', 'bool')
->allowedValues('bar', 'zab') ->allowedValues('bar', 'zab')
@ -2471,4 +2487,17 @@ class OptionsResolverTest extends TestCase
$this->resolver->resolve(['expires' => new \DateTime('-1 hour')]); $this->resolver->resolve(['expires' => new \DateTime('-1 hour')]);
} }
/**
* @group legacy
*/
public function testSetDeprecatedWithoutPackageAndVersion()
{
$this->expectDeprecation('Since symfony/options-resolver 5.1: The signature of method "Symfony\Component\OptionsResolver\OptionsResolver::setDeprecated()" requires 2 new arguments: "string $package, string $version", not defining them is deprecated.');
$this->resolver
->setDefined('foo')
->setDeprecated('foo')
;
}
} }