From a14bee719bea2e519031dd1caceed8f550c4f585 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 14 Oct 2020 02:06:56 +0200 Subject: [PATCH] Allow options to be marked as deprecated [Closes #27] --- readme.md | 14 ++++++++++++++ src/Schema/Elements/Base.php | 20 +++++++++++++++++++- src/Schema/Message.php | 3 +++ tests/Schema/Expect.anyOf.phpt | 15 +++++++++++++++ tests/Schema/Expect.structure.phpt | 28 ++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 096ec9f..822729f 100644 --- a/readme.md +++ b/readme.md @@ -257,6 +257,20 @@ $processor->process($schema, ['additional' => 1]); // OK $processor->process($schema, ['additional' => true]); // ERROR ``` +Deprecations +------------ + +You can deprecate property using the `deprecated([string $message])` method. Deprecation notices are returned by `$processor->getWarnings()`. + +```php +$schema = Expect::structure([ + 'old' => Expect::int()->deprecated('The option %path% is deprecated'), +]); + +$processor->process($schema, ['old' => 1]); // OK +$processor->getWarnings(); // ["The option 'old' is deprecated"] +``` + Ranges: min() max() ------------------- diff --git a/src/Schema/Elements/Base.php b/src/Schema/Elements/Base.php index 1be7fad..f690680 100644 --- a/src/Schema/Elements/Base.php +++ b/src/Schema/Elements/Base.php @@ -33,6 +33,9 @@ trait Base /** @var string|null */ private $castTo; + /** @var string|null */ + private $deprecated; + public function default($value): self { @@ -69,6 +72,14 @@ public function assert(callable $handler, string $description = null): self } + /** Marks option as deprecated */ + public function deprecated(string $message = 'Option %path% is deprecated.'): self + { + $this->deprecated = $message; + return $this; + } + + public function completeDefault(Context $context) { if ($this->required) { @@ -95,7 +106,6 @@ private function doValidate($value, string $expected, Context $context): bool { try { Nette\Utils\Validators::assert($value, $expected, 'option %path%'); - return true; } catch (Nette\Utils\AssertionException $e) { $context->addError( $e->getMessage(), @@ -104,6 +114,14 @@ private function doValidate($value, string $expected, Context $context): bool ); return false; } + + if ($this->deprecated !== null) { + $context->addWarning( + $this->deprecated, + Nette\Schema\Message::DEPRECATED + ); + } + return true; } diff --git a/src/Schema/Message.php b/src/Schema/Message.php index 4159a10..4051f36 100644 --- a/src/Schema/Message.php +++ b/src/Schema/Message.php @@ -31,6 +31,9 @@ final class Message /** variables: {hint: string} */ public const UNEXPECTED_KEY = 'schema.unexpectedKey'; + /** no variables */ + public const DEPRECATED = 'schema.deprecated'; + /** @var string */ public $message; diff --git a/tests/Schema/Expect.anyOf.phpt b/tests/Schema/Expect.anyOf.phpt index 379e1d8..f66462e 100644 --- a/tests/Schema/Expect.anyOf.phpt +++ b/tests/Schema/Expect.anyOf.phpt @@ -159,6 +159,21 @@ test('required & nullable', function () { }); +test('deprecated item', function () { + $schema = Expect::anyOf('one', true, Expect::int()->deprecated()); + + $processor = new Processor; + Assert::same('one', $processor->process($schema, 'one')); + Assert::same([], $processor->getWarnings()); + + Assert::same(true, $processor->process($schema, true)); + Assert::same([], $processor->getWarnings()); + + Assert::same(123, $processor->process($schema, 123)); + Assert::same(['Option is deprecated.'], $processor->getWarnings()); +}); + + test('nullable anyOf', function () { $schema = Expect::anyOf(Expect::string(), true)->nullable(); diff --git a/tests/Schema/Expect.structure.phpt b/tests/Schema/Expect.structure.phpt index 93a81f5..2424f52 100644 --- a/tests/Schema/Expect.structure.phpt +++ b/tests/Schema/Expect.structure.phpt @@ -426,3 +426,31 @@ test('processing without default values', function () { $processor->process($schema, ['d' => 'newval']) ); }); + + +test('deprecated item', function () { + $schema = Expect::structure([ + 'b' => Expect::string()->deprecated('depr %path%'), + ]); + + $processor = new Processor; + Assert::equal( + (object) ['b' => 'val'], + $processor->process($schema, ['b' => 'val']) + ); + Assert::same(["depr 'b'"], $processor->getWarnings()); +}); + + +test('deprecated other items', function () { + $schema = Expect::structure([ + 'key' => Expect::string(), + ])->otherItems(Expect::string()->deprecated()); + + $processor = new Processor; + Assert::equal((object) ['key' => null], $processor->process($schema, [])); + Assert::same([], $processor->getWarnings()); + + Assert::equal((object) ['key' => null, 'other' => 'foo'], $processor->process($schema, ['other' => 'foo'])); + Assert::same(["Option 'other' is deprecated."], $processor->getWarnings()); +});