Allow to validate ArrayObject in key-related values

Because of that, I also updated some data providers to distinguish
between "values" and "types", similar to some of the rules we already
have.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2024-03-07 18:28:25 +01:00
parent 7ded68c550
commit fe68eab37d
No known key found for this signature in database
GPG key ID: 221E9281655813A6
10 changed files with 55 additions and 37 deletions

View file

@ -9,6 +9,7 @@ declare(strict_types=1);
namespace Respect\Validation\Rules;
use ArrayAccess;
use Respect\Validation\Message\Template;
use Respect\Validation\Result;
use Respect\Validation\Rules\Core\Standard;
@ -34,6 +35,14 @@ final class KeyExists extends Standard
private function hasKey(mixed $input): bool
{
return is_array($input) && array_key_exists($this->key, $input);
if (is_array($input)) {
return array_key_exists($this->key, $input);
}
if ($input instanceof ArrayAccess) {
return $input->offsetExists($this->key);
}
return false;
}
}

View file

@ -76,14 +76,14 @@ abstract class TestCase extends PHPUnitTestCase
public static function providerForAnyValues(): array
{
return array_merge(
self::providerForStringValues(),
self::providerForStringTypes(),
self::providerForNonScalarValues(),
self::providerForEmptyIterableValues(),
self::providerForNonEmptyIterableValues(),
self::providerForNonIterableValues(),
self::providerForIntegerValues(),
self::providerForBooleanValues(),
self::providerForFloatValues(),
self::providerForNonIterableTypes(),
self::providerForIntegerTypes(),
self::providerForBooleanTypes(),
self::providerForFloatTypes(),
);
}
@ -91,10 +91,10 @@ abstract class TestCase extends PHPUnitTestCase
public static function providerForScalarValues(): array
{
return array_merge(
self::providerForStringValues(),
self::providerForIntegerValues(),
self::providerForBooleanValues(),
self::providerForFloatValues(),
self::providerForStringTypes(),
self::providerForIntegerTypes(),
self::providerForBooleanTypes(),
self::providerForFloatTypes(),
);
}
@ -119,7 +119,7 @@ abstract class TestCase extends PHPUnitTestCase
}
/** @return array<array{mixed}> */
public static function providerForNonIterableValues(): array
public static function providerForNonIterableTypes(): array
{
return array_merge(
self::providerForScalarValues(),
@ -133,7 +133,7 @@ abstract class TestCase extends PHPUnitTestCase
}
/** @return array<array{iterable<mixed>}> */
public static function providerForIterableValues(): array
public static function providerForIterableTypes(): array
{
return array_merge(
self::providerForNonEmptyIterableValues(),
@ -162,7 +162,7 @@ abstract class TestCase extends PHPUnitTestCase
}
/** @return array<array{string}> */
public static function providerForStringValues(): array
public static function providerForStringTypes(): array
{
return [
'string' => ['string'],
@ -174,27 +174,27 @@ abstract class TestCase extends PHPUnitTestCase
}
/** @return array<array{string}> */
public static function providerForNonEmptyStringValues(): array
public static function providerForNonEmptyStringTypes(): array
{
$dataProvider = self::providerForStringValues();
$dataProvider = self::providerForStringTypes();
unset($dataProvider['empty string']);
return $dataProvider;
}
/** @return array<array{mixed}> */
public static function providerForNonStringValues(): array
public static function providerForNonStringTypes(): array
{
return array_merge(
self::providerForNonScalarValues(),
self::providerForIntegerValues(),
self::providerForBooleanValues(),
self::providerForFloatValues(),
self::providerForIntegerTypes(),
self::providerForBooleanTypes(),
self::providerForFloatTypes(),
);
}
/** @return array<array{int}> */
public static function providerForIntegerValues(): array
public static function providerForIntegerTypes(): array
{
return [
'zero integer' => [0],
@ -204,7 +204,7 @@ abstract class TestCase extends PHPUnitTestCase
}
/** @return array<array{bool}> */
public static function providerForBooleanValues(): array
public static function providerForBooleanTypes(): array
{
return [
'true' => [true],
@ -213,7 +213,7 @@ abstract class TestCase extends PHPUnitTestCase
}
/** @return array<array{float}> */
public static function providerForFloatValues(): array
public static function providerForFloatTypes(): array
{
return [
'zero float' => [0.0],
@ -223,20 +223,29 @@ abstract class TestCase extends PHPUnitTestCase
}
/** @return array<array{mixed}> */
public static function providerForNonArrayValues(): array
public static function providerForNonArrayTypes(): array
{
$scalarValues = self::providerForNonScalarValues();
unset($scalarValues['array']);
return array_merge(
self::providerForIntegerValues(),
self::providerForBooleanValues(),
self::providerForFloatValues(),
self::providerForStringValues(),
self::providerForIntegerTypes(),
self::providerForBooleanTypes(),
self::providerForFloatTypes(),
self::providerForStringTypes(),
$scalarValues,
);
}
/** @return array<array{mixed}> */
public static function providerForNonArrayValues(): array
{
$arrayTypes = self::providerForNonArrayTypes();
unset($arrayTypes['ArrayObject']);
return $arrayTypes;
}
/** @return array<string, array{string|int, array<mixed>}> */
public static function providerForArrayWithMissingKeys(): array
{

View file

@ -22,7 +22,7 @@ final class StringifyTest extends TestCase
public const DEFAULT_NAME = 'not_name';
#[Test]
#[DataProvider('providerForStringValues')]
#[DataProvider('providerForStringTypes')]
public function itShouldNotStringifyValueWhenNameIsNameAndValueIsString(string $value): void
{
$stringify = new Stringify();

View file

@ -21,7 +21,7 @@ final class TransTest extends TestCase
public const DEFAULT_NAME = 'foo';
#[Test]
#[DataProvider('providerForStringValues')]
#[DataProvider('providerForStringTypes')]
public function itShouldReturnTranslatedValueWhenModifierIsTransAndInputIsString(string $value): void
{
$translation = 'translated';
@ -33,7 +33,7 @@ final class TransTest extends TestCase
}
#[Test]
#[DataProvider('providerForNonStringValues')]
#[DataProvider('providerForNonStringTypes')]
public function itShouldUseNextProcessorWhenModifierIsTransButInputIsNotString(mixed $value): void
{
$next = new TestingProcessor();

View file

@ -22,7 +22,7 @@ use Respect\Validation\Test\TestCase;
final class FilteredNonEmptyArrayTest extends TestCase
{
#[Test]
#[DataProvider('providerForNonIterableValues')]
#[DataProvider('providerForNonIterableTypes')]
public function itShouldInvalidateNonIterableValues(mixed $input): void
{
$sut = new ConcreteFilteredNonEmptyArray(Stub::daze());

View file

@ -87,7 +87,7 @@ final class FilteredStringTest extends TestCase
}
#[Test]
#[DataProvider('providerForNonEmptyStringValues')]
#[DataProvider('providerForNonEmptyStringTypes')]
public function itShouldFilterNothingWhenHasNoAdditionalCharacters(string $input): void
{
$rule = new ConcreteFilteredString();

View file

@ -34,7 +34,7 @@ final class DomainTest extends TestCase
}
#[Test]
#[DataProvider('providerForNonStringValues')]
#[DataProvider('providerForNonStringTypes')]
public function itShouldInvalidWhenInputIsNotString(mixed $input): void
{
self::assertInvalidInput(new Domain(), $input);

View file

@ -21,7 +21,7 @@ final class IterableTypeTest extends TestCase
{
/** @param iterable<mixed> $input */
#[Test]
#[DataProvider('providerForIterableValues')]
#[DataProvider('providerForIterableTypes')]
public function itShouldValidateIterableTypes(iterable $input): void
{
$rule = new IterableType();
@ -30,7 +30,7 @@ final class IterableTypeTest extends TestCase
}
#[Test]
#[DataProvider('providerForNonIterableValues')]
#[DataProvider('providerForNonIterableTypes')]
public function itShouldInvalidateNonIterableTypes(mixed $input): void
{
$rule = new IterableType();

View file

@ -22,7 +22,7 @@ use Respect\Validation\Test\TestCase;
final class MaxTest extends TestCase
{
#[Test]
#[DataProvider('providerForNonIterableValues')]
#[DataProvider('providerForNonIterableTypes')]
public function itShouldInvalidateNonIterableValues(mixed $input): void
{
$rule = new Max(Stub::daze());

View file

@ -22,7 +22,7 @@ use Respect\Validation\Test\TestCase;
final class MinTest extends TestCase
{
#[Test]
#[DataProvider('providerForNonIterableValues')]
#[DataProvider('providerForNonIterableTypes')]
public function itShouldInvalidateNonIterableValues(mixed $input): void
{
$rule = new Min(Stub::daze());