Make KeySet impossible to wrap in not(), fix structure message

The use case for negating a keyset is very confusing, and can
lead to validators that don't do what they expect.

This commit introduces NonNegatable rules, which will throw
a Component exception if you try to wrap them in `Not`.

This change was necessary to ensure proper message reporting
when extra keys exist on the keyset.

This fixes #1349
This commit is contained in:
Alexandre Gomes Gaigalas 2023-02-18 15:12:19 -03:00
commit fc8230acef
6 changed files with 81 additions and 6 deletions

View file

@ -17,6 +17,7 @@ use function count;
final class KeySetException extends GroupedValidationException implements NonOmissibleException
{
public const STRUCTURE = 'structure';
public const STRUCTURE_EXTRA = 'structure_extra';
/**
* {@inheritDoc}
@ -26,11 +27,7 @@ final class KeySetException extends GroupedValidationException implements NonOmi
self::NONE => 'All of the required rules must pass for {{name}}',
self::SOME => 'These rules must pass for {{name}}',
self::STRUCTURE => 'Must have keys {{keys}}',
],
self::MODE_NEGATIVE => [
self::NONE => 'None of these rules must pass for {{name}}',
self::SOME => 'These rules must not pass for {{name}}',
self::STRUCTURE => 'Must not have keys {{keys}}',
self::STRUCTURE_EXTRA => 'Must not have keys {{extraKeys}}',
],
];
@ -39,6 +36,10 @@ final class KeySetException extends GroupedValidationException implements NonOmi
*/
protected function chooseTemplate(): string
{
if (count($this->getParam('extraKeys'))) {
return self::STRUCTURE_EXTRA;
}
if (count($this->getChildren()) === 0) {
return self::STRUCTURE;
}