diff --git a/Dockerfile b/Dockerfile index 339fc04..fb4aa70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.0-cli-alpine3.13 +FROM php:8.4-cli-alpine3.22 RUN apk update && \ apk add --no-cache \ diff --git a/composer.json b/composer.json index 7d6f5ef..5c51902 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ } }, "require": { - "php": "^8.0", + "php": "^8.4", "ext-json": "*", "ramsey/uuid": "^4.2" }, diff --git a/src/Domain/Model/ValueObject/CollectionValueObject.php b/src/Domain/Model/ValueObject/CollectionValueObject.php index 58c92a7..0e01c35 100644 --- a/src/Domain/Model/ValueObject/CollectionValueObject.php +++ b/src/Domain/Model/ValueObject/CollectionValueObject.php @@ -52,6 +52,11 @@ public function walk(callable $func): void \array_walk($this->items, $func); } + public function findOne(callable $func) + { + return \array_find($this->items, $func); + } + public function filter(callable $func): static { return static::from(\array_values(\array_filter($this->items, $func))); diff --git a/src/Domain/Model/ValueObject/DateTimeRangeValeObject.php b/src/Domain/Model/ValueObject/DateTimeRangeValeObject.php deleted file mode 100644 index a63d825..0000000 --- a/src/Domain/Model/ValueObject/DateTimeRangeValeObject.php +++ /dev/null @@ -1,9 +0,0 @@ -setTimezone($timeZone)); } - final public static function fromFormat(string $format, string $str): static|false + final public static function fromFormat(string $format, string $str): static { return static::createFromFormat($format, $str, new \DateTimeZone(self::TIME_ZONE)); } final public static function createFromTimestamp(float|int $timestamp): static { - $dateTime = self::fromFormat('U.u', \number_format((float) $timestamp, 6, '.', '')); - - \assert(false !== $dateTime, 'Unexpected error on create date time from timestamp'); - - return $dateTime; + return self::fromFormat('U.u', \number_format((float) $timestamp, 6, '.', '')); } final public static function fromTimestamp(int|float $timestamp): static diff --git a/src/Domain/Model/ValueObject/DateValueObject.php b/src/Domain/Model/ValueObject/DateValueObject.php index eeb7244..54ed6f8 100644 --- a/src/Domain/Model/ValueObject/DateValueObject.php +++ b/src/Domain/Model/ValueObject/DateValueObject.php @@ -18,7 +18,7 @@ public static function from(string $str): static { $timeZone = new \DateTimeZone(self::TIME_ZONE); - return (new static($str, $timeZone))->setTimezone($timeZone); + return (new static($str, $timeZone))->setTimezone($timeZone)->setTime(0, 0, 0, 0); } final public static function now(): static @@ -40,11 +40,11 @@ final public static function createFromFormat( string $format, string $datetime, ?\DateTimeZone $timezone = null - ): static|false { + ): static { $datetime = parent::createFromFormat($format, $datetime, $timezone); if (false === $datetime) { - return false; + throw new \InvalidArgumentException('Invalid date format'); } $timeZone = new \DateTimeZone(self::TIME_ZONE); @@ -52,18 +52,14 @@ final public static function createFromFormat( return static::createFromInterface($datetime->setTimezone($timeZone)); } - final public static function fromFormat(string $format, string $str): static|false + final public static function fromFormat(string $format, string $str): static { return static::createFromFormat($format, $str, new \DateTimeZone(self::TIME_ZONE)); } final public static function createFromTimestamp(float|int $timestamp): static { - $dateTime = self::fromFormat('U.u', \number_format((float) $timestamp, 6, '.', '')); - - \assert(false !== $dateTime, 'Unexpected error on create date time from timestamp'); - - return $dateTime; + return self::fromFormat('U.u', \number_format((float) $timestamp, 6, '.', '')); } final public static function fromTimestamp(int|float $timestamp): static diff --git a/src/Domain/Model/ValueObject/UniqueId.php b/src/Domain/Model/ValueObject/UniqueId.php index 7a05fbd..84864ac 100644 --- a/src/Domain/Model/ValueObject/UniqueId.php +++ b/src/Domain/Model/ValueObject/UniqueId.php @@ -5,10 +5,30 @@ class UniqueId extends StringValueObject { + private const VALID_PATTERN = '/^[A-Z0-9]{10}$/'; + + public static function from(string $value): static + { + if (false === self::isValid($value)) { + throw new \InvalidArgumentException('Invalid UniqueId.'); + } + + return parent::from($value); + } + public static function create(): static { + $value = \base_convert(\uniqid(), 16, 36); + $value = \str_pad($value, 10, '0', \STR_PAD_LEFT); + $value = \substr($value, -10); + return self::from( - \strtoupper(\base_convert(\uniqid(), 16, 36)), + \strtoupper($value), ); } + + public static function isValid(string $value): bool + { + return 1 === \preg_match(self::VALID_PATTERN, $value); + } } diff --git a/tests/Domain/Model/ValueObject/DateTimeRangeValeObjectTest.php b/tests/Domain/Model/ValueObject/DateTimeRangeValeObjectTest.php deleted file mode 100644 index e373604..0000000 --- a/tests/Domain/Model/ValueObject/DateTimeRangeValeObjectTest.php +++ /dev/null @@ -1,116 +0,0 @@ -assertEquals(DateTimeValueObject::from('2000-01-01 00:00:00'), $range->start()); - $this->assertEquals(DateTimeValueObject::from('2019-12-31 23:59:59'), $range->end()); - } - - /** @test */ - public function given_invalid_range_when_creating_range_then_throw_exception(): void - { - $this->expectException(\InvalidArgumentException::class); - - DateTimeRangeValeObject::from( - DateTimeValueObject::from('2019-12-31 23:59:59'), - DateTimeValueObject::from('2000-01-01 00:00:00'), - ); - } - - /** @test */ - public function given_equal_dates_when_creating_range_then_throw_exception(): void - { - $this->expectException(\InvalidArgumentException::class); - - DateTimeRangeValeObject::from( - DateTimeValueObject::from('2000-01-01 00:00:00'), - DateTimeValueObject::from('2000-01-01 00:00:00'), - ); - } - - /** @test */ - public function given_expired_range_when_ask_if_expired_then_return_expected_info(): void - { - $range = DateTimeRangeValeObject::from( - DateTimeValueObject::from('2000-01-01 00:00:00'), - DateTimeValueObject::from('2001-12-31 23:59:59'), - ); - - $this->assertFalse($range->isInDate()); - $this->assertTrue($range->isExpired()); - $this->assertFalse($range->isNotStarted()); - } - - /** @test */ - public function given_in_date_range_when_ask_if_in_date_then_return_expected_info(): void - { - $range = DateTimeRangeValeObject::from( - DateTimeValueObject::from('2020-01-01 00:00:00'), - DateTimeValueObject::from('2100-12-31 23:59:59'), - ); - - $this->assertTrue($range->isInDate()); - $this->assertFalse($range->isExpired()); - $this->assertFalse($range->isNotStarted()); - } - - /** @test */ - public function given_not_started_range_when_ask_if_not_started_then_return_expected_info(): void - { - $range = DateTimeRangeValeObject::from( - DateTimeValueObject::from('2050-01-01 00:00:00'), - DateTimeValueObject::from('2100-12-31 23:59:59'), - ); - - $this->assertFalse($range->isInDate()); - $this->assertFalse($range->isExpired()); - $this->assertTrue($range->isNotStarted()); - } - - /** @test */ - public function given_two_equal_ranges_when_ask_to_check_equality_then_return_true(): void - { - $range = DateTimeRangeValeObject::from( - DateTimeValueObject::from('2000-01-01 00:00:00'), - DateTimeValueObject::from('2019-12-31 23:59:59'), - ); - - $other = DateTimeRangeValeObject::from( - DateTimeValueObject::from('2000-01-01 00:00:00'), - DateTimeValueObject::from('2019-12-31 23:59:59'), - ); - - $this->assertTrue($range->equalTo($other)); - } - - /** @test */ - public function given_two_different_ranges_when_ask_to_check_equality_then_return_false(): void - { - $range = DateTimeRangeValeObject::from( - DateTimeValueObject::from('2000-01-01 00:00:00'), - DateTimeValueObject::from('2019-12-31 23:59:59'), - ); - - $other = DateTimeRangeValeObject::from( - DateTimeValueObject::from('2000-01-01 00:00:01'), - DateTimeValueObject::from('2019-12-31 23:59:59'), - ); - - $this->assertFalse($range->equalTo($other)); - } -} diff --git a/tests/Domain/Model/ValueObject/UniqueIdTest.php b/tests/Domain/Model/ValueObject/UniqueIdTest.php index ac186a5..5d16cc3 100644 --- a/tests/Domain/Model/ValueObject/UniqueIdTest.php +++ b/tests/Domain/Model/ValueObject/UniqueIdTest.php @@ -28,7 +28,7 @@ public function given_uid_class_when_ask_to_generate_an_uid_then_return_uid_inst { $uid = UniqueId::create(); $this->assertInstanceOf(UniqueId::class, $uid); - $this->assertMatchesRegularExpression('/^[0-9A-Z]{10}$/i', $uid->value()); + $this->assertTrue(UniqueId::isValid($uid->value())); } /** @@ -53,4 +53,29 @@ public function given_two_different_uids_when_ask_to_check_equality_then_return_ $this->assertFalse($str->equalTo($other)); } + + /** + * @test + */ + public function given_invalid_uid_value_when_construct_then_fail() + { + $this->expectException(\InvalidArgumentException::class); + UniqueId::from('12345'); + } + + /** + * @test + */ + public function given_invalid_uid_value_when_ask_is_valid_then_return_false() + { + self::assertFalse(UniqueId::isValid('12345')); + } + + /** + * @test + */ + public function given_valid_uid_value_when_ask_is_valid_then_return_true() + { + self::assertTrue(UniqueId::isValid('H7HVQ2U72X')); + } }