Create "ContainsAny" rule

Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Kirill Dlussky 2018-12-12 15:12:45 +01:00 committed by Henrique Moody
parent 8fd18d9b72
commit 81d71749b7
No known key found for this signature in database
GPG key ID: 221E9281655813A6
11 changed files with 231 additions and 0 deletions

View file

@ -86,6 +86,7 @@
- [Cntrl](rules/Cntrl.md)
- [Consonant](rules/Consonant.md)
- [Contains](rules/Contains.md)
- [ContainsAny](rules/ContainsAny.md)
- [Digit](rules/Digit.md)
- [EndsWith](rules/EndsWith.md)
- [Graph](rules/Graph.md)
@ -112,6 +113,7 @@
- [ArrayVal](rules/ArrayVal.md)
- [ArrayType](rules/ArrayType.md)
- [Contains](rules/Contains.md)
- [ContainsAny](rules/ContainsAny.md)
- [Each](rules/Each.md)
- [EndsWith](rules/EndsWith.md)
- [In](rules/In.md)
@ -240,6 +242,7 @@
- [Cntrl](rules/Cntrl.md)
- [Consonant](rules/Consonant.md)
- [Contains](rules/Contains.md)
- [ContainsAny](rules/ContainsAny.md)
- [Countable](rules/Countable.md)
- [CountryCode](rules/CountryCode.md)
- [Cpf](rules/Cpf.md)

View file

@ -24,6 +24,7 @@ Version | Description
See also:
- [AllOf](AllOf.md)
- [ContainsAny](ContainsAny.md)
- [NoneOf](NoneOf.md)
- [OneOf](OneOf.md)
- [When](When.md)

View file

@ -31,6 +31,7 @@ Version | Description
***
See also:
- [ContainsAny](ContainsAny.md)
- [EndsWith](EndsWith.md)
- [Equals](Equals.md)
- [Equivalent](Equivalent.md)

37
docs/rules/ContainsAny.md Normal file
View file

@ -0,0 +1,37 @@
# ContainsAny
- `ContainsAny(array $needles)`
- `ContainsAny(array $needles, bool $identical)`
Validates if the input contains at least one of defined values
For strings (comparing is case insensitive):
```php
v::containsAny(['lorem', 'dolor'])->validate('lorem ipsum'); // true
```
For arrays (comparing is case sensitive to respect "contains" behavior):
```php
v::containsAny(['lorem', 'dolor'])->validate(['ipsum', 'lorem']); // true
```
A second parameter may be passed for identical comparison instead
of equal comparison for arrays.
Message template for this validator includes `{{needles}}`.
## Changelog
Version | Description
--------|-------------
2.0.0 | Created
***
See also:
- [AnyOf](AnyOf.md)
- [Contains](Contains.md)
- [Equivalent](Equivalent.md)
- [In](In.md)

View file

@ -25,5 +25,6 @@ Version | Description
See also:
- [Contains](Contains.md)
- [ContainsAny](ContainsAny.md)
- [Equals](Equals.md)
- [Identical](Identical.md)

View file

@ -32,6 +32,7 @@ Version | Description
See also:
- [Contains](Contains.md)
- [ContainsAny](ContainsAny.md)
- [EndsWith](EndsWith.md)
- [Roman](Roman.md)
- [StartsWith](StartsWith.md)

View file

@ -0,0 +1,32 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Respect\Validation\Exceptions;
/**
* @author Kirill Dlussky <kirill@dlussky.ru>
*/
final class ContainsAnyException extends ValidationException
{
/**
* {@inheritdoc}
*/
public static $defaultTemplates = [
self::MODE_DEFAULT => [
self::STANDARD => '{{name}} must contain at least one of the values {{needles}}',
],
self::MODE_NEGATIVE => [
self::STANDARD => '{{name}} must not contain any of the values {{needles}}',
],
];
}

View file

@ -0,0 +1,49 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Respect\Validation\Rules;
use function array_map;
/**
* Validates if the input contains at least one of defined values
*
* @author Henrique Moody <henriquemoody@gmail.com>
* @author Kirill Dlussky <kirill@dlussky.ru>
*/
final class ContainsAny extends AbstractEnvelope
{
/**
* Initializes the rule.
*
* @param array $needles At least one of the values provided must be found in input string or array
* @param bool $identical Defines whether the value should be compared strictly, when validating array
*/
public function __construct(array $needles, bool $identical = false)
{
parent::__construct(
new AnyOf(...$this->getRules($needles, $identical)),
['needles' => $needles]
);
}
private function getRules(array $needles, bool $identical): array
{
return array_map(
function ($needle) use ($identical): Contains {
return new Contains($needle, $identical);
},
$needles
);
}
}

View file

@ -47,6 +47,7 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
* @method static Validator cntrl(string ...$additionalChars)
* @method static Validator consonant(string ...$additionalChars)
* @method static Validator contains($containsValue, bool $identical = false)
* @method static Validator containsAny(array $needles, bool $strictCompareArray = false)
* @method static Validator countable()
* @method static Validator countryCode(string $set = null)
* @method static Validator currencyCode()

View file

@ -0,0 +1,40 @@
--CREDITS--
Henrique Moody <henriquemoody@gmail.com>
--FILE--
<?php
require 'vendor/autoload.php';
use Respect\Validation\Exceptions\ContainsAnyException;
use Respect\Validation\Exceptions\NestedValidationException;
use Respect\Validation\Validator as v;
try {
v::containsAny(['foo', 'bar'])->check('baz');
} catch (ContainsAnyException $exception) {
echo $exception->getMessage().PHP_EOL;
}
try {
v::not(v::containsAny(['foo', 'bar']))->check('fool');
} catch (ContainsAnyException $exception) {
echo $exception->getMessage().PHP_EOL;
}
try {
v::containsAny(['foo', 'bar'])->assert(['baz']);
} catch (NestedValidationException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
try {
v::not(v::containsAny(['foo', 'bar'], true))->assert(['bar', 'foo']);
} catch (NestedValidationException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
?>
--EXPECT--
"baz" must contain at least one of the values `{ "foo", "bar" }`
"fool" must not contain any of the values `{ "foo", "bar" }`
- `{ "baz" }` must contain at least one of the values `{ "foo", "bar" }`
- `{ "bar", "foo" }` must not contain any of the values `{ "foo", "bar" }`

View file

@ -0,0 +1,65 @@
<?php
/*
* This file is part of Respect/Validation.
*
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
*
* For the full copyright and license information, please view the "LICENSE.md"
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Respect\Validation\Rules;
use Respect\Validation\Test\RuleTestCase;
/**
* @group rule
*
* @covers \Respect\Validation\Rules\ContainsAny
*
* @author Henrique Moody <henriquemoody@gmail.com>
* @author Kirill Dlussky <kirill@dlussky.ru>
*/
final class ContainsAnyTest extends RuleTestCase
{
/**
* {@inheritdoc}
*/
public function providerForValidInput(): array
{
return [
[new ContainsAny(['Something', 'Else']), 'something else'],
[new ContainsAny([true]), [1, 2, 3]],
[new ContainsAny([true], true), [true]],
[new ContainsAny(['1']), [1, 2, 3]],
[new ContainsAny([1], true), [1, 2, 3]],
[new ContainsAny(['word', '@', '/']), 'lorem ipsum @ word'],
[new ContainsAny(['foo', 'qux']), 'foobarbaz'],
[new ContainsAny(['1']), ['foo', 1]],
[new ContainsAny(['foo', true]), ['foo', 'bar']],
];
}
/**
* {@inheritdoc}
*/
public function providerForInvalidInput(): array
{
return [
[new ContainsAny(['foo']), ['bar', 'baz']],
[new ContainsAny(['foo', 'bar']), ['baz', 'qux']],
[new ContainsAny(['foo', 'bar']), ['FOO', 'BAR']],
[new ContainsAny(['foo'], true), ['bar', 'baz']],
[new ContainsAny(['foo', 'bar'], true), ['FOO', 'BAR']],
[new ContainsAny(['whatever']), ''],
[new ContainsAny(['']), 'whatever'],
[new ContainsAny([false]), ''],
[new ContainsAny(['foo', 'qux']), 'barbaz'],
[new ContainsAny([1, 2, 3], true), ['1', '2', '3']],
[new ContainsAny(['word', '@', '/']), 'lorem ipsum'],
];
}
}