Add a `oneOf` assertion
Taluu opened this issue · comments
As we have all*
assertions, having oneOf*
assertions could be useful, as in detecting if one element in the collection can be asserted to the given assert.
WDYT ? I'd be glad to make a PR for that.
IMHO I think this should be implemented, yes. I've been working the last couple of weeks on a small project where - unfortunately - I need to handle some validation/checks where (due to some processes that are beyond my source code) might return 2 or 3 potential values, so implement a method like oneOf
could simplify these checks.
Seems to be already implemented:
https://github.com/webmozart/assert/blob/master/src/Assert.php#L595
The already implemented Assert::oneOf($value, $values);
asserts in_array($value, $values, true)
, which is not similar to the all*
mechanism (implemented with magic __callStatic
) like the README example Assert::allIsInstanceOf($employees, 'Acme\Employee');
(basically equivalent to Assert::isIterable($employees); foreach ($employees as $employee) { Assert::isInstanceOf($employee, 'Acme\Employee'); }
).
I guess you rather want an any*
mechanism (implemented similar to all*
), which would let you test for example Assert::anyIsInstanceOf($objects, 'Acme\Employee');
. Something like (inserted here):
if ('any' === substr($name, 0, 3)) {
static::isIterable($arguments[0]);
$method = lcfirst(substr($name, 3));
$args = $arguments;
$hasAtLeastOneElement = false;
$invalidArgumentException = null;
foreach ($arguments[0] as $entry) {
$args[0] = $entry;
$hasAtLeastOneElement = true;
try {
call_user_func_array(array('static', $method), $args);
return;
} catch (InvalidArgumentException $e) {
$invalidArgumentException = $e;
}
}
if (!$hasAtLeastOneElement ) {
static::reportInvalidArgument('Expected at least one element.');
}
throw $invalidArgumentException;
}
I think this is too much of a niche for this library.
However, it is possible to extend the Assert
class, and override __callStatic
, and add somemething like @guilliamxavier suggested.