diff --git a/src/macros/output/Hyperf/Collection/Arr.php b/src/macros/output/Hyperf/Collection/Arr.php index b1b4c8060..68b19631c 100644 --- a/src/macros/output/Hyperf/Collection/Arr.php +++ b/src/macros/output/Hyperf/Collection/Arr.php @@ -11,8 +11,56 @@ namespace Hyperf\Collection; +use ArrayAccess; +use InvalidArgumentException; + class Arr { + /** + * Get an array item from an array using "dot" notation. + * @return array + * @throws InvalidArgumentException + */ + public static function array(ArrayAccess|array $array, string|int|null $key, ?array $default = null) + { + } + + /** + * Get a boolean item from an array using "dot" notation. + * @return bool + * @throws InvalidArgumentException + */ + public static function boolean(ArrayAccess|array $array, string|int|null $key, ?bool $default = null) + { + } + + /** + * Get a float item from an array using "dot" notation. + * @return float + * @throws InvalidArgumentException + */ + public static function float(ArrayAccess|array $array, string|int|null $key, ?float $default = null) + { + } + + /** + * Get an integer item from an array using "dot" notation. + * @return int + * @throws InvalidArgumentException + */ + public static function integer(ArrayAccess|array $array, string|int|null $key, ?int $default = null) + { + } + + /** + * Get a string item from an array using "dot" notation. + * @return string + * @throws InvalidArgumentException + */ + public static function string(ArrayAccess|array $array, string|int|null $key, ?string $default = null) + { + } + /** * Sort given array by many properties. * diff --git a/src/macros/src/ArrMixin.php b/src/macros/src/ArrMixin.php index 2f48894a5..af17b4c25 100644 --- a/src/macros/src/ArrMixin.php +++ b/src/macros/src/ArrMixin.php @@ -11,13 +11,102 @@ namespace FriendsOfHyperf\Macros; +use ArrayAccess; use Hyperf\Collection\Arr; +use InvalidArgumentException; /** * @mixin Arr */ class ArrMixin { + public static function array() + { + return function (ArrayAccess|array $array, string|int|null $key, ?array $default = null) { + $value = Arr::get($array, $key, $default); + + if (! is_array($value)) { + throw new InvalidArgumentException( + sprintf('Array value for key [%s] must be an array, %s found.', $key, gettype($value)) + ); + } + + return $value; + }; + } + + /** + * Get a boolean item from an array using "dot" notation. + */ + public static function boolean() + { + return function (ArrayAccess|array $array, string|int|null $key, ?bool $default = null) { + $value = Arr::get($array, $key, $default); + + if (! is_bool($value)) { + throw new InvalidArgumentException( + sprintf('Array value for key [%s] must be a boolean, %s found.', $key, gettype($value)) + ); + } + + return $value; + }; + } + + /** + * Get a float item from an array using "dot" notation. + */ + public static function float() + { + return function (ArrayAccess|array $array, string|int|null $key, ?float $default = null) { + $value = Arr::get($array, $key, $default); + + if (! is_float($value)) { + throw new InvalidArgumentException( + sprintf('Array value for key [%s] must be a float, %s found.', $key, gettype($value)) + ); + } + + return $value; + }; + } + + /** + * Get an integer item from an array using "dot" notation. + */ + public static function integer() + { + return function (ArrayAccess|array $array, string|int|null $key, ?int $default = null) { + $value = Arr::get($array, $key, $default); + + if (! is_integer($value)) { + throw new InvalidArgumentException( + sprintf('Array value for key [%s] must be an integer, %s found.', $key, gettype($value)) + ); + } + + return $value; + }; + } + + /** + * Get a string item from an array using "dot" notation. + */ + public static function string() + { + return function (ArrayAccess|array $array, string|int|null $key, ?string $default = null) { + $value = Arr::get($array, $key, $default); + + if (! is_string($value)) { + throw new InvalidArgumentException( + sprintf('Array value for key [%s] must be a string, %s found.', $key, gettype($value)) + ); + } + + return $value; + }; + } + public function sortByMany() { return function ($array, $comparisons = []) { diff --git a/tests/Macros/ArrTest.php b/tests/Macros/ArrTest.php index e2badb707..040e89227 100644 --- a/tests/Macros/ArrTest.php +++ b/tests/Macros/ArrTest.php @@ -10,6 +10,111 @@ */ use Hyperf\Collection\Arr; +test('test getsAString', function () { + $test_array = ['string' => 'foo bar', 'integer' => 1234]; + + // Test string values are returned as strings + $this->assertSame( + 'foo bar', + Arr::string($test_array, 'string') + ); + + // Test that default string values are returned for missing keys + $this->assertSame( + 'default', + Arr::string($test_array, 'missing_key', 'default') + ); + + // Test that an exception is raised if the value is not a string + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageMatches('#^Array value for key \[integer\] must be a string, (.*) found.#'); + Arr::string($test_array, 'integer'); +}); + +test('test getsAnInteger', function () { + $test_array = ['string' => 'foo bar', 'integer' => 1234]; + + // Test integer values are returned as integers + $this->assertSame( + 1234, + Arr::integer($test_array, 'integer') + ); + + // Test that default integer values are returned for missing keys + $this->assertSame( + 999, + Arr::integer($test_array, 'missing_key', 999) + ); + + // Test that an exception is raised if the value is not an integer + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageMatches('#^Array value for key \[string\] must be an integer, (.*) found.#'); + Arr::integer($test_array, 'string'); +}); + +test('test getsAFloat', function () { + $test_array = ['string' => 'foo bar', 'float' => 12.34]; + + // Test float values are returned as floats + $this->assertSame( + 12.34, + Arr::float($test_array, 'float') + ); + + // Test that default float values are returned for missing keys + $this->assertSame( + 56.78, + Arr::float($test_array, 'missing_key', 56.78) + ); + + // Test that an exception is raised if the value is not a float + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageMatches('#^Array value for key \[string\] must be a float, (.*) found.#'); + Arr::float($test_array, 'string'); +}); + +test('test getsABoolean', function () { + $test_array = ['string' => 'foo bar', 'boolean' => true]; + + // Test boolean values are returned as booleans + $this->assertSame( + true, + Arr::boolean($test_array, 'boolean') + ); + + // Test that default boolean values are returned for missing keys + $this->assertSame( + true, + Arr::boolean($test_array, 'missing_key', true) + ); + + // Test that an exception is raised if the value is not a boolean + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageMatches('#^Array value for key \[string\] must be a boolean, (.*) found.#'); + Arr::boolean($test_array, 'string'); +}); + +test('test getsAnArray', function () { + $test_array = ['string' => 'foo bar', 'array' => ['foo', 'bar']]; + + // Test array values are returned as arrays + $this->assertSame( + ['foo', 'bar'], + Arr::array($test_array, 'array') + ); + + // Test that default array values are returned for missing keys + $this->assertSame( + [1, 'two'], + Arr::array($test_array, 'missing_key', [1, 'two']) + ); + + // Test that an exception is raised if the value is not an array + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageMatches('#^Array value for key \[string\] must be an array, (.*) found.#'); + Arr::array($test_array, 'string'); +}); + test('test sortByMany', function () { $unsorted = [ ['name' => 'John', 'age' => 8, 'meta' => ['key' => 3]], diff --git a/tests/Support/SleepTest.php b/tests/Support/SleepTest.php index b64394668..8d300b283 100644 --- a/tests/Support/SleepTest.php +++ b/tests/Support/SleepTest.php @@ -16,6 +16,7 @@ use Exception; use FriendsOfHyperf\Support\Sleep; use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Attributes\RequiresPhp; use PHPUnit\Framework\TestCase; use RuntimeException; @@ -26,6 +27,7 @@ * @coversNothing */ #[\PHPUnit\Framework\Attributes\Group('support')] +#[RequiresPhp('!= 8.3.20')] class SleepTest extends TestCase { protected function tearDown(): void diff --git a/tests/ValidatedDTO/Unit/CarbonCastTest.php b/tests/ValidatedDTO/Unit/CarbonCastTest.php index ac24dcd29..207bcc179 100644 --- a/tests/ValidatedDTO/Unit/CarbonCastTest.php +++ b/tests/ValidatedDTO/Unit/CarbonCastTest.php @@ -14,6 +14,8 @@ use FriendsOfHyperf\ValidatedDTO\Casting\CarbonImmutableCast; use FriendsOfHyperf\ValidatedDTO\Exception\CastException; +beforeEach(function () {})->skipOnPhp('8.3.20'); + it('casts to carbon', function () { $castable = new CarbonCast();