From c5df587dd9428e682f283c867e04669c0c785129 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 17:45:37 +0000 Subject: [PATCH 001/193] feat: Add new directories to gitignore file --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 739db1a..4f108ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ +ci/ vendor/ .buildpath .project composer.lock phpunit.xml +.phpunit.result.cache From 523ad3a47f73ebe0a30e8ca639ec5091c10451a1 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 17:46:50 +0000 Subject: [PATCH 002/193] build: Update PHPUnit and min PHP version to 74 --- composer.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 208714b..70ed8c0 100755 --- a/composer.json +++ b/composer.json @@ -22,10 +22,10 @@ "mutable objects" ], "require": { - "php": "^7.2" + "php": "^7.4" }, "require-dev": { - "phpunit/phpunit": "^7.5", + "phpunit/phpunit": "^9.0", "squizlabs/php_codesniffer": "^3.0@dev" }, "autoload": { @@ -37,5 +37,10 @@ "psr-4": { "Hradigital\\Tests\\Datatypes\\": "tests/" } + }, + "scripts": { + "test-code" : "./vendor/bin/phpunit --coverage-clover ci/coverage-report.xml --coverage-html ci/coverage-report --log-junit ci/tests-results.xml", + "test-cs" : "./vendor/bin/phpcs -p --colors --no-cache --report=full --standard=PSR2 src/", + "test-all" : "composer run test-code && composer run test-cs" } } From 8e0445beec6bfdfeff661cd079eb099b5dc2e2a5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 17:47:06 +0000 Subject: [PATCH 003/193] build: Update minimum PHP version to 74 --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5e68e91..615b49d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,7 +4,7 @@ orbs: jobs: build: docker: - - image: circleci/php:7.2 + - image: circleci/php:7.4 working_directory: ~/php-datatypes steps: # GIT @@ -38,4 +38,4 @@ jobs: path: ~/build/coverage-report - codecov/upload: file: ~/build/coverage-report - + From 9535271334f464fb3ce34c0e71a7848dba21eb73 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 17:48:33 +0000 Subject: [PATCH 004/193] refactor: Remove deprecated classes for v2 --- src/Scalar/AbstractReadBoolean.php | 71 ------------ src/Scalar/AbstractReadFloat.php | 173 ---------------------------- src/Scalar/AbstractReadInteger.php | 167 --------------------------- src/Scalar/AbstractWriteFloat.php | 68 ----------- src/Scalar/AbstractWriteInteger.php | 68 ----------- src/Scalar/ImmutableFloat.php | 164 -------------------------- src/Scalar/ImmutableInteger.php | 164 -------------------------- src/Scalar/MutableFloat.php | 166 -------------------------- src/Scalar/MutableInteger.php | 166 -------------------------- src/Scalar/ReadonlyBoolean.php | 91 --------------- src/Scalar/ReadonlyFloat.php | 125 -------------------- src/Scalar/ReadonlyInteger.php | 108 ----------------- 12 files changed, 1531 deletions(-) delete mode 100644 src/Scalar/AbstractReadBoolean.php delete mode 100644 src/Scalar/AbstractReadFloat.php delete mode 100644 src/Scalar/AbstractReadInteger.php delete mode 100644 src/Scalar/AbstractWriteFloat.php delete mode 100644 src/Scalar/AbstractWriteInteger.php delete mode 100644 src/Scalar/ImmutableFloat.php delete mode 100644 src/Scalar/ImmutableInteger.php delete mode 100644 src/Scalar/MutableFloat.php delete mode 100644 src/Scalar/MutableInteger.php delete mode 100644 src/Scalar/ReadonlyBoolean.php delete mode 100644 src/Scalar/ReadonlyFloat.php delete mode 100644 src/Scalar/ReadonlyInteger.php diff --git a/src/Scalar/AbstractReadBoolean.php b/src/Scalar/AbstractReadBoolean.php deleted file mode 100644 index 65bdbdd..0000000 --- a/src/Scalar/AbstractReadBoolean.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -abstract class AbstractReadBoolean -{ - /** - * @var boolean $value - Internal boolean value for the instance. - */ - protected $value = true; - - /** - * Initializes a new instance of a Boolean. - * - * @param bool $value - Initial boolean value. - * - * @since 1.0.0 - * @return void - */ - protected function __construct(bool $value) - { - $this->value = $value; - } - - /** - * Magic method that will print out the native string representation of the instance. - * - * @since 1.0.0 - * @return string - */ - public function __toString(): string - { - return ($this->value ? 'true' : 'false'); - } - - /** - * Compares two Boolean instances, and return TRUE if supplied instance is equal. - * - * @param AbstractReadBoolean $compare - Boolean instance to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function equals(AbstractReadBoolean $compare): bool - { - return $compare->equalsNative($this->value); - } - - /** - * Compares instance's value, with the supplied native value, and returns TRUE if equal. - * - * @param bool $value - Boolean native value to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function equalsNative(bool $value): bool - { - return ($value === $this->value); - } -} diff --git a/src/Scalar/AbstractReadFloat.php b/src/Scalar/AbstractReadFloat.php deleted file mode 100644 index cc31e18..0000000 --- a/src/Scalar/AbstractReadFloat.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -abstract class AbstractReadFloat -{ - /** - * Returns the maximum float allowed in the system. - * - * @since 1.0.0 - * @return float - */ - public static function max(): float - { - return PHP_FLOAT_MAX; - } - - /** - * Returns the minimum float allowed in the system. - * - * @since 1.0.0 - * @return float - */ - public static function min(): float - { - return PHP_FLOAT_MIN; - } - - /** - * @var float $value - Internal float value for the instance. - */ - protected $value = 0.0; - - /** - * Initializes a new instance of a Float. - * - * @param float $value - Initial float value. - * - * @since 1.0.0 - * @return void - */ - protected function __construct(float $value) - { - $this->value = $value; - } - - /** - * Magic method that will print out the native string representation of the instance. - * - * @since 1.0.0 - * @return string - */ - public function __toString(): string - { - return $this->value; - } - - /** - * Returns the native value of the instance. - * - * @since 1.0.0 - * @return float - */ - public function value(): float - { - return $this->value; - } - - /** - * Compares two Float instances, and return TRUE if supplied instance is bigger. - * - * @param AbstractReadFloat $compare - Float instance to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function isBigger(AbstractReadFloat $compare): bool - { - return ( - $compare->isSmallerNative($this->value) || - $compare->equalsNative($this->value) - ); - } - - /** - * Compares instance's value, with the supplied native value, and returns TRUE if instance is bigger. - * - * @param float $value - Float native value to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function isBiggerNative(float $value): bool - { - return ($this->value > $value); - } - - /** - * Compares two Float instances, and return TRUE if supplied instance is smaller. - * - * @param AbstractReadFloat $compare - Float instance to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function isSmaller(AbstractReadFloat $compare): bool - { - return ( - $compare->isBiggerNative($this->value) || - $compare->equalsNative($this->value) - ); - } - - /** - * Compares instance's value, with the supplied native value, and returns TRUE if instance is smaller. - * - * @param float $value - Float native value to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function isSmallerNative(float $value): bool - { - return ($this->value < $value); - } - - /** - * Compares two Float instances, and return TRUE if supplied instance is equal. - * - * @param AbstractReadFloat $compare - Float instance to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function equals(AbstractReadFloat $compare): bool - { - return $compare->equalsNative($this->value); - } - - /** - * Compares instance's value, with the supplied native value, and returns TRUE if equal. - * - * @param float $value - Float native value to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function equalsNative(float $value): bool - { - return ($this->value === $value); - } - - /** - * Returns TRUE if instance contains a negative value. - * - * @since 1.0.0 - * @return bool - */ - public function isNegative(): bool - { - return ($this->value < 0.0); - } -} diff --git a/src/Scalar/AbstractReadInteger.php b/src/Scalar/AbstractReadInteger.php deleted file mode 100644 index c312fd5..0000000 --- a/src/Scalar/AbstractReadInteger.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -abstract class AbstractReadInteger -{ - /** - * Returns the maximum integer allowed in the system. - * - * @since 1.0.0 - * @return int - */ - public static function max(): int - { - return PHP_INT_MAX; - } - - /** - * Returns the minimum integer allowed in the system. - * - * @since 1.0.0 - * @return int - */ - public static function min(): int - { - return PHP_INT_MIN; - } - - /** - * @var integer $value - Internal integer value for the instance. - */ - protected $value = 0; - - /** - * Initializes a new instance of an Integer. - * - * @param integer $value - Initial integer value. - * - * @since 1.0.0 - * @return void - */ - protected function __construct(int $value) - { - $this->value = $value; - } - - /** - * Magic method that will print out the native string representation of the instance. - * - * @since 1.0.0 - * @return string - */ - public function __toString(): string - { - return $this->value; - } - - /** - * Returns the native value of the instance. - * - * @since 1.0.0 - * @return int - */ - public function value(): int - { - return $this->value; - } - - /** - * Compares two Integer instances, and return TRUE if supplied instance is bigger. - * - * @param AbstractReadInteger $compare - Integer instance to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function isBigger(AbstractReadInteger $compare): bool - { - return $this->isBiggerNative($compare->value()); - } - - /** - * Compares instance's value, with the supplied native value, and returns TRUE if instance is bigger. - * - * @param int $value - Integer native value to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function isBiggerNative(int $value): bool - { - return ($this->value > $value); - } - - /** - * Compares two Integer instances, and return TRUE if supplied instance is smaller. - * - * @param AbstractReadInteger $compare - Integer instance to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function isSmaller(AbstractReadInteger $compare): bool - { - return $this->isSmallerNative($compare->value()); - } - - /** - * Compares instance's value, with the supplied native value, and returns TRUE if instance is smaller. - * - * @param int $value - Integer native value to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function isSmallerNative(int $value): bool - { - return ($this->value < $value); - } - - /** - * Returns TRUE if instance contains a negative value. - * - * @since 1.0.0 - * @return bool - */ - public function isNegative(): bool - { - return ($this->value < 0); - } - - /** - * Compares two Integer instances, and return TRUE if supplied instance is equal. - * - * @param AbstractReadInteger $compare - Integer instance to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function equals(AbstractReadInteger $compare): bool - { - return $this->equalsNative($compare->value()); - } - - /** - * Compares instance's value, with the supplied native value, and returns TRUE if equal. - * - * @param int $value - Integer native value to compare to. - * - * @since 1.0.0 - * @return bool - */ - public function equalsNative(int $value): bool - { - return ($value === $this->value); - } -} diff --git a/src/Scalar/AbstractWriteFloat.php b/src/Scalar/AbstractWriteFloat.php deleted file mode 100644 index 92714fd..0000000 --- a/src/Scalar/AbstractWriteFloat.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -abstract class AbstractWriteFloat extends AbstractReadFloat -{ - /** - * Adds an external value to the instance's internal value. - * - * @param float $value - Value to add to the instance. - * - * @since 1.0.0 - * @return float - */ - protected function doAdd(float $value): float - { - return ($this->value + $value); - } - - /** - * Subtracts an external value from the instance's internal value. - * - * @param float $value - Value to subtract from the instance. - * - * @since 1.0.0 - * @return float - */ - protected function doSubtract(float $value): float - { - return ($this->value - $value); - } - - /** - * Multiply an external value to the instance's internal value. - * - * @param float $value - Value to multiply to the instance. - * - * @since 1.0.0 - * @return float - */ - protected function doMultiply(float $value): float - { - return ($this->value * $value); - } - - /** - * Divides the instance's internal value by an external value. - * - * @param float $value - Value used to divide the instance. - * - * @since 1.0.0 - * @return float - */ - protected function doDivide(float $value): float - { - return ($this->value / $value); - } -} diff --git a/src/Scalar/AbstractWriteInteger.php b/src/Scalar/AbstractWriteInteger.php deleted file mode 100644 index 9d3fca6..0000000 --- a/src/Scalar/AbstractWriteInteger.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -abstract class AbstractWriteInteger extends AbstractReadInteger -{ - /** - * Adds an external value to the instance's internal value. - * - * @param int $value - Value to add to the instance. - * - * @since 1.0.0 - * @return int - */ - protected function doAdd(int $value): int - { - return ($this->value + $value); - } - - /** - * Subtracts an external value from the instance's internal value. - * - * @param int $value - Value to subtract from the instance. - * - * @since 1.0.0 - * @return int - */ - protected function doSubtract(int $value): int - { - return ($this->value - $value); - } - - /** - * Multiply an external value to the instance's internal value. - * - * @param int $value - Value to multiply to the instance. - * - * @since 1.0.0 - * @return int - */ - protected function doMultiply(int $value): int - { - return ($this->value * $value); - } - - /** - * Divides the instance's internal value by an external value. - * - * @param int $value - Value used to divide the instance. - * - * @since 1.0.0 - * @return int - */ - protected function doDivide(int $value): int - { - return ((int) ($this->value / $value)); - } -} diff --git a/src/Scalar/ImmutableFloat.php b/src/Scalar/ImmutableFloat.php deleted file mode 100644 index 440a16a..0000000 --- a/src/Scalar/ImmutableFloat.php +++ /dev/null @@ -1,164 +0,0 @@ -Value Object, in a DDD project. - * - * Method chaning is not supported by any mutators. A new instance will be returned instead. - * - * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ImmutableFloat extends AbstractWriteFloat -{ - /** - * Creates a new instance of ImmutableFloat based on a string value. - * - * @param string $number - Number as a string value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - public static function fromString(string $number): ImmutableFloat - { - // Valiates supplied parameter. - if (\strlen(\trim($number)) === 0) { - throw new \InvalidArgumentException("Supplied string must be a non empty string."); - } - - return new ImmutableFloat( - \floatval($number) - ); - } - - /** - * Creates a new instance of ImmutableFloat based on a float value. - * - * @param float $number - Number as a float value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - public static function fromFloat(float $number): ImmutableFloat - { - return new ImmutableFloat($number); - } - - /** - * Returns instance to a Mutable Float instance. - * - * @since 1.0.0 - * @return MutableFloat - */ - public function toMutable(): MutableFloat - { - return MutableFloat::fromFloat($this->value); - } - - /** - * Adds an external value to the instance's internal value. - * - * @param AbstractReadFloat $value - Value to add to the instance. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - public function add(AbstractReadFloat $value): ImmutableFloat - { - return new ImmutableFloat( - parent::doAdd($value->value()) - ); - } - - /** - * Subtracts an external value from the instance's internal value. - * - * @param AbstractReadFloat $value - Value to subtract from the instance. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - public function subtract(AbstractReadFloat $value): ImmutableFloat - { - return new ImmutableFloat( - parent::doSubtract($value->value()) - ); - } - - /** - * Multiply an external value to the instance's internal value. - * - * @param AbstractReadFloat $value - Value to multiply with the instance. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - public function multiply(AbstractReadFloat $value): ImmutableFloat - { - return new ImmutableFloat( - parent::doMultiply($value->value()) - ); - } - - /** - * Divides the instance's internal value by an external value. - * - * @param AbstractReadFloat $value - Value to divide the instance with. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - public function divide(AbstractReadFloat $value): ImmutableFloat - { - return new ImmutableFloat( - parent::doDivide($value->value()) - ); - } - - /** - * Formats the Float as a formatted string. - * - * @param \NumberFormatter $formatter - Format that should be used in the returned string. - * - * @since 1.0.0 - * @return ImmutableString - */ - public function format(\NumberFormatter $formatter): ImmutableString - { - return ImmutableString::fromString( - $formatter->format($this->value, \NumberFormatter::TYPE_DOUBLE) - ); - } - - /** - * Converts float's instance to an equivalent string instance. - * - * @since 1.0.0 - * @return ImmutableString - */ - public function toString(): ImmutableString - { - return ImmutableString::fromString($this->__toString()); - } - - /** - * Converts float's instance to an equivalent integer instance. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - public function toInteger(): ImmutableInteger - { - return ImmutableInteger::fromString($this->__toString()); - } -} diff --git a/src/Scalar/ImmutableInteger.php b/src/Scalar/ImmutableInteger.php deleted file mode 100644 index a871cc2..0000000 --- a/src/Scalar/ImmutableInteger.php +++ /dev/null @@ -1,164 +0,0 @@ -Value Object, in a DDD project. - * - * Method chaning is not supported by any mutators. A new instance will be returned instead. - * - * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ImmutableInteger extends AbstractWriteInteger -{ - /** - * Creates a new instance of ImmutableInteger based on a string value. - * - * @param string $number - Number as a string value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - public static function fromString(string $number): ImmutableInteger - { - // Valiates supplied parameter. - if (\strlen(\trim($number)) === 0) { - throw new \InvalidArgumentException("Supplied string must be a non empty string."); - } - - return new ImmutableInteger( - ((int) $number) - ); - } - - /** - * Creates a new instance of ImmutableInteger based on an integer value. - * - * @param int $number - Number as an integer value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - public static function fromInteger(int $number): ImmutableInteger - { - return new ImmutableInteger($number); - } - - /** - * Converts instance to a Mutable Integer instance. - * - * @since 1.0.0 - * @return MutableInteger - */ - public function toMutable(): MutableInteger - { - return new MutableInteger($this->value); - } - - /** - * Adds an external value to the instance's internal value. - * - * @param AbstractReadInteger $value - Value to add to the instance. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - public function add(AbstractReadInteger $value): ImmutableInteger - { - return new ImmutableInteger( - parent::doAdd($value->value()) - ); - } - - /** - * Subtracts an external value from the instance's internal value. - * - * @param AbstractReadInteger $value - Value to subtract from the instance. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - public function subtract(AbstractReadInteger $value): ImmutableInteger - { - return new ImmutableInteger( - parent::doSubtract($value->value()) - ); - } - - /** - * Multiply an external value to the instance's internal value. - * - * @param AbstractReadInteger $value - Value to multiply with the instance. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - public function multiply(AbstractReadInteger $value): ImmutableInteger - { - return new ImmutableInteger( - parent::doMultiply($value->value()) - ); - } - - /** - * Divides the instance's internal value by an external value. - * - * @param AbstractReadInteger $value - Value to divide with the instance. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - public function divide(AbstractReadInteger $value): ImmutableInteger - { - return new ImmutableInteger( - parent::doDivide($value->value()) - ); - } - - /** - * Formats the Integer as a formatted string. - * - * @param \NumberFormatter $formatter - Format that should be used in the returned string. - * - * @since 1.0.0 - * @return ImmutableString - */ - public function format(\NumberFormatter $formatter): ImmutableString - { - return ImmutableString::fromString( - $formatter->format($this->value, \NumberFormatter::TYPE_INT64) - ); - } - - /** - * Converts integer's instance to an equivalent string instance. - * - * @since 1.0.0 - * @return ImmutableString - */ - public function toString(): ImmutableString - { - return ImmutableString::fromString($this->__toString()); - } - - /** - * Converts integer's instance to an equivalent float instance. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - public function toFloat(): ImmutableFloat - { - return ImmutableFloat::fromString($this->__toString()); - } -} diff --git a/src/Scalar/MutableFloat.php b/src/Scalar/MutableFloat.php deleted file mode 100644 index 3f2b258..0000000 --- a/src/Scalar/MutableFloat.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class MutableFloat extends AbstractWriteFloat -{ - /** - * Creates a new instance of MutableFloat based on a string value. - * - * @param string $number - Number as a string value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return MutableFloat - */ - public static function fromString(string $number): MutableFloat - { - // Valiates supplied parameter. - if (\strlen(\trim($number)) === 0) { - throw new \InvalidArgumentException("Supplied string must be a non empty string."); - } - - return new MutableFloat( - \floatval($number) - ); - } - - /** - * Creates a new instance of MutableFloat based on a float value. - * - * @param float $number - Number as a float value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return MutableInteger - */ - public static function fromFloat(float $number): MutableFloat - { - return new MutableFloat($number); - } - - /** - * Returns instance to an Immutable Float instance. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - public function toImmutable(): ImmutableFloat - { - return ImmutableFloat::fromFloat($this->value); - } - - /** - * Adds an external value to the instance's internal value. - * - * @param AbstractReadFloat $value - Value to add to the instance. - * - * @since 1.0.0 - * @return MutableFloat - */ - public function add(AbstractReadFloat $value): MutableFloat - { - $this->value = parent::doAdd($value->value()); - - return $this; - } - - /** - * Subtracts an external value from the instance's internal value. - * - * @param AbstractReadFloat $value - Value to add to the instance. - * - * @since 1.0.0 - * @return MutableFloat - */ - public function subtract(AbstractReadFloat $value): MutableFloat - { - $this->value = parent::doSubtract($value->value()); - - return $this; - } - - /** - * Multiply an external value to the instance's internal value. - * - * @param AbstractReadFloat $value - Value to add to the instance. - * - * @since 1.0.0 - * @return MutableFloat - */ - public function multiply(AbstractReadFloat $value): MutableFloat - { - $this->value = parent::doMultiply($value->value()); - - return $this; - } - - /** - * Divides the instance's internal value by an external value. - * - * @param AbstractReadFloat $value - Value to add to the instance. - * - * @since 1.0.0 - * @return MutableFloat - */ - public function divide(AbstractReadFloat $value): MutableFloat - { - $this->value = parent::doDivide($value->value()); - - return $this; - } - - /** - * Formats the Float as a formatted string. - * - * @param \NumberFormatter $formatter - Format that should be used in the returned string. - * - * @since 1.0.0 - * @return MutableString - */ - public function format(\NumberFormatter $formatter): MutableString - { - return MutableString::fromString( - $formatter->format($this->value, \NumberFormatter::TYPE_DOUBLE) - ); - } - - /** - * Converts Float's instance to an equivalent string instance. - * - * @since 1.0.0 - * @return MutableString - */ - public function toString(): MutableString - { - return MutableString::fromString($this->__toString()); - } - - /** - * Converts Float's instance to an equivalent integer instance. - * - * @since 1.0.0 - * @return MutableInteger - */ - public function toInteger(): MutableInteger - { - return MutableInteger::fromString($this->__toString()); - } -} diff --git a/src/Scalar/MutableInteger.php b/src/Scalar/MutableInteger.php deleted file mode 100644 index fdce060..0000000 --- a/src/Scalar/MutableInteger.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class MutableInteger extends AbstractWriteInteger -{ - /** - * Creates a new instance of MutableInteger based on a string value. - * - * @param string $number - Number as a string value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return MutableInteger - */ - public static function fromString(string $number): MutableInteger - { - // Valiates supplied parameter. - if (\strlen(\trim($number)) === 0) { - throw new \InvalidArgumentException("Supplied string must be a non empty string."); - } - - return new MutableInteger( - ((int) $number) - ); - } - - /** - * Creates a new instance of MutableInteger based on an integer value. - * - * @param int $number - Number as an integer value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return MutableInteger - */ - public static function fromInteger(int $number): MutableInteger - { - return new MutableInteger($number); - } - - /** - * Adds an external value to the instance's internal value. - * - * @param AbstractReadInteger $value - Value to add to the instance. - * - * @since 1.0.0 - * @return MutableInteger - */ - public function add(AbstractReadInteger $value): MutableInteger - { - $this->value = parent::doAdd($value->value()); - - return $this; - } - - /** - * Subtracts an external value from the instance's internal value. - * - * @param AbstractReadInteger $value - Value to add to the instance. - * - * @since 1.0.0 - * @return MutableInteger - */ - public function subtract(AbstractReadInteger $value): MutableInteger - { - $this->value = parent::doSubtract($value->value()); - - return $this; - } - - /** - * Multiply an external value to the instance's internal value. - * - * @param AbstractReadInteger $value - Value to add to the instance. - * - * @since 1.0.0 - * @return MutableInteger - */ - public function multiply(AbstractReadInteger $value): MutableInteger - { - $this->value = parent::doMultiply($value->value()); - - return $this; - } - - /** - * Divides the instance's internal value by an external value. - * - * @param AbstractReadInteger $value - Value to add to the instance. - * - * @since 1.0.0 - * @return MutableInteger - */ - public function divide(AbstractReadInteger $value): MutableInteger - { - $this->value = parent::doDivide($value->value()); - - return $this; - } - - /** - * Formats the Integer as a formatted string. - * - * @param \NumberFormatter $formatter - Format that should be used in the returned string. - * - * @since 1.0.0 - * @return MutableString - */ - public function format(\NumberFormatter $formatter): MutableString - { - return MutableString::fromString( - $formatter->format($this->value, \NumberFormatter::TYPE_INT64) - ); - } - - /** - * Converts integer's instance to an equivalent string instance. - * - * @since 1.0.0 - * @return MutableString - */ - public function toString(): MutableString - { - return MutableString::fromString($this->__toString()); - } - - /** - * Converts the integer's instance to an Immutable Integer. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - public function toImmutable(): ImmutableInteger - { - return ImmutableInteger::fromInteger($this->value); - } - - /** - * Converts integer's instance to an equivalent float instance. - * - * @since 1.0.0 - * @return MutableFloat - */ - public function toFloat(): MutableFloat - { - return MutableFloat::fromString($this->__toString()); - } -} diff --git a/src/Scalar/ReadonlyBoolean.php b/src/Scalar/ReadonlyBoolean.php deleted file mode 100644 index 489cdd3..0000000 --- a/src/Scalar/ReadonlyBoolean.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ReadonlyBoolean extends AbstractReadBoolean -{ - /** - * Creates a new instance of ReadonlyBoolean based on a string value. - * - * @param string $string - Boolean as a string value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ReadonlyBoolean - */ - public static function fromString(string $string): ReadonlyBoolean - { - // Valiates supplied parameter. - if (\strlen(\trim($string)) === 0) { - throw new \InvalidArgumentException("Supplied string must be a non empty string."); - } - - return new ReadonlyBoolean( - \in_array(\strtolower($string), ['1', 'true', 'yes']) - ); - } - - /** - * Creates a new instance of ReadonlyBoolean based on a string value. - * - * @param int $number - Number as an integer value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ReadonlyBoolean - */ - public static function fromInteger(int $number): ReadonlyBoolean - { - return new ReadonlyBoolean($number > 0); - } - - /** - * Creates a new instance of ReadonlyBoolean based on a string value. - * - * @param float $number - Number as a float value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ReadonlyBoolean - */ - public static function fromFloat(float $number): ReadonlyBoolean - { - return new ReadonlyBoolean($number > 0); - } - - /** - * Converts boolean's instance to an equivalent string instance. - * - * @since 1.0.0 - * @return ReadonlyString - */ - public function toString(): ReadonlyString - { - return ReadonlyString::fromString($this->value ? 'True' : 'False'); - } - - /** - * Converts boolean's instance to an equivalent integer's instance. - * - * @since 1.0.0 - * @return ReadonlyInteger - */ - public function toInteger(): ReadonlyInteger - { - return ReadonlyInteger::fromInteger($this->value ? 1 : 0); - } -} diff --git a/src/Scalar/ReadonlyFloat.php b/src/Scalar/ReadonlyFloat.php deleted file mode 100644 index f2acb0b..0000000 --- a/src/Scalar/ReadonlyFloat.php +++ /dev/null @@ -1,125 +0,0 @@ -MutableFloat datatype, as well as for - * ImmutableFloat. - * - * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ReadonlyFloat extends AbstractReadFloat -{ - /** - * Creates a new instance of ReadonlyFloat based on a string value. - * - * @param string $number - Number as a string value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ReadonlyFloat - */ - public static function fromString(string $number): ReadonlyFloat - { - // Valiates supplied parameter. - if (\strlen(\trim($number)) === 0) { - throw new \InvalidArgumentException("Supplied string must be a non empty string."); - } - - return new ReadonlyFloat( - \floatval($number) - ); - } - - /** - * Creates a new instance of ReadonlyFloat based on a string value. - * - * @param int $number - Number as an integer value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ReadonlyFloat - */ - public static function fromInteger(int $number): ReadonlyFloat - { - return new ReadonlyFloat( - \floatval($number) - ); - } - - /** - * Creates a new instance of ReadonlyFloat based on a string value. - * - * @param float $number - Number as a float value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ReadonlyFloat - */ - public static function fromFloat(float $number): ReadonlyFloat - { - return new ReadonlyFloat($number); - } - - /** - * Formats the Float number as a formatted string. - * - * @param \NumberFormatter $formatter - Format that should be used in the returned string. - * - * @since 1.0.0 - * @return ReadonlyString - */ - public function format(\NumberFormatter $formatter): ReadonlyString - { - return ReadonlyString::fromString( - $formatter->format($this->value, \NumberFormatter::TYPE_DOUBLE) - ); - } - - /** - * Converts float's instance to an equivalent string instance. - * - * @since 1.0.0 - * @return ReadonlyString - */ - public function toString(): ReadonlyString - { - return ReadonlyString::fromString($this->__toString()); - } - - /** - * Converts float's instance to an equivalent integer's instance. - * - * @since 1.0.0 - * @return ReadonlyInteger - */ - public function toInteger(): ReadonlyInteger - { - return ReadonlyInteger::fromString($this->__toString()); - } - - /** - * Converts float's instance to an equivalent boolean instance. - * - * A ReadonlyBoolean will be returned, as Booleans don't require Immutable and Mutable - * distinctions. - * - * @since 1.0.0 - * @return ReadonlyBoolean - */ - public function toBoolean(): ReadonlyBoolean - { - return ReadonlyBoolean::fromFloat($this->value); - } -} diff --git a/src/Scalar/ReadonlyInteger.php b/src/Scalar/ReadonlyInteger.php deleted file mode 100644 index c9c769a..0000000 --- a/src/Scalar/ReadonlyInteger.php +++ /dev/null @@ -1,108 +0,0 @@ -MutableInteger datatype, as well as for - * ImmutableInteger. - * - * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ReadonlyInteger extends AbstractReadInteger -{ - /** - * Creates a new instance of ReadonlyInteger based on a string value. - * - * @param string $number - Number as a string value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ReadonlyInteger - */ - public static function fromString(string $number): ReadonlyInteger - { - // Valiates supplied parameter. - if (\strlen(\trim($number)) === 0) { - throw new \InvalidArgumentException("Supplied string must be a non empty string."); - } - - return new ReadonlyInteger( - ((int) $number) - ); - } - - /** - * Creates a new instance of ReadonlyInteger based on a string value. - * - * @param int $number - Number as an integer value. - * - * @throws \InvalidArgumentException - If supplied argument is empty. - * - * @since 1.0.0 - * @return ReadonlyInteger - */ - public static function fromInteger(int $number): ReadonlyInteger - { - return new ReadonlyInteger($number); - } - - /** - * Formats the Integer as a formatted string. - * - * @param \NumberFormatter $formatter - Format that should be used in the returned string. - * - * @since 1.0.0 - * @return ReadonlyString - */ - public function format(\NumberFormatter $formatter): ReadonlyString - { - return ReadonlyString::fromString( - $formatter->format($this->value, \NumberFormatter::TYPE_INT64) - ); - } - - /** - * Converts integer's instance to an equivalent string instance. - * - * @since 1.0.0 - * @return ReadonlyString - */ - public function toString(): ReadonlyString - { - return ReadonlyString::fromString($this->__toString()); - } - - /** - * Converts integer's instance to an equivalent float's instance. - * - * @since 1.0.0 - * @return ReadonlyFloat - */ - public function toFloat(): ReadonlyFloat - { - return ReadonlyFloat::fromInteger($this->value); - } - - /** - * Converts integer's instance to an equivalent boolean instance. - * - * A ReadonlyBoolean will be returned, as Booleans don't require Immutable and Mutable - * distinctions. - * - * @since 1.0.0 - * @return ReadonlyBoolean - */ - public function toBoolean(): ReadonlyBoolean - { - return ReadonlyBoolean::fromInteger($this->value); - } -} From 0595e67577622e657b389e9425a7c49702c35e6e Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 18:09:27 +0000 Subject: [PATCH 005/193] refactor: Remove deprecated tests --- tests/Unit/Scalar/ImmutableFloatTest.php | 392 ---------------- tests/Unit/Scalar/ImmutableIntegerTest.php | 392 ---------------- tests/Unit/Scalar/MutableFloatTest.php | 226 --------- tests/Unit/Scalar/MutableIntegerTest.php | 226 --------- tests/Unit/Scalar/ReadonlyBooleanTest.php | 333 -------------- tests/Unit/Scalar/ReadonlyFloatTest.php | 509 --------------------- tests/Unit/Scalar/ReadonlyIntegerTest.php | 507 -------------------- 7 files changed, 2585 deletions(-) delete mode 100644 tests/Unit/Scalar/ImmutableFloatTest.php delete mode 100644 tests/Unit/Scalar/ImmutableIntegerTest.php delete mode 100644 tests/Unit/Scalar/MutableFloatTest.php delete mode 100644 tests/Unit/Scalar/MutableIntegerTest.php delete mode 100644 tests/Unit/Scalar/ReadonlyBooleanTest.php delete mode 100644 tests/Unit/Scalar/ReadonlyFloatTest.php delete mode 100644 tests/Unit/Scalar/ReadonlyIntegerTest.php diff --git a/tests/Unit/Scalar/ImmutableFloatTest.php b/tests/Unit/Scalar/ImmutableFloatTest.php deleted file mode 100644 index 29a5fd8..0000000 --- a/tests/Unit/Scalar/ImmutableFloatTest.php +++ /dev/null @@ -1,392 +0,0 @@ -ImmutableFloat and MutableFloat classes have similar behavior, therefore, - * you should extend this test case for the other type of String, overriding only the necessary - * tests, which shouldn't be too many. - * - * This way, we can test both types of objects, without repeating the same code/tests. - * - * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ImmutableFloatTest extends AbstractBaseTestCase -{ - /** - * Asserts that 2 integer instances do not match. - * - * @param AbstractReadFloat $original - Original Float instance. - * @param AbstractReadFloat $other - Second instance for comparison. - * - * @since 1.0.0 - * @return void - */ - protected function checkInstances(AbstractReadFloat $original, AbstractReadFloat $other): void - { - $this->assertFalse( - ($original === $other), - 'Instances are not meant to match.' - ); - } - - /** - * Asserts that the supplied instance, is from the correct type. - * - * @param AbstractReadFloat $instance - Instance to be validated. - * - * @since 1.0.0 - * @return void - */ - protected function checkCorrectInstanceType(AbstractReadFloat $instance): void - { - $this->assertInstanceOf( - ImmutableFloat::class, - $instance, - 'Instance type, does not match ImmutableFloat.' - ); - } - - /** - * Initializes and returns a new instance for testing. - * - * This method has no return value, due to inheritance overriding. - * - * @param string $initialValue - Instance's initial value. - * - * @since 1.0.0 - * @return ImmutableFloat - */ - protected function initializeInstance(string $initialValue) - { - return ImmutableFloat::fromString($initialValue); - } - - /** - * Checks instance can be cloned. - * - * @since 1.0.0 - * @return void - */ - public function testCanCloneObject(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $other = $original->toMutable(); - - // Performs assertions. - $this->assertInstanceOf( - MutableFloat::class, - $other, - 'Instance type, does not match MutableFloat.' - ); - $this->assertEquals( - $original->value(), - $other->value(), - 'Instance values do not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests that the instance can be converted to an Integer. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToInteger(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $integer = $original->toInteger(); - - // Performs assertions. - $this->assertInstanceOf( - ImmutableInteger::class, - $integer, - 'Instance type, does not match ImmutableInteger.' - ); - } - - /** - * Tests that the instance can be converted to a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToString(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $string = $original->toString(); - - // Performs assertions. - $this->assertInstanceOf( - ImmutableString::class, - $string, - 'Instance type, does not match ImmutableString.' - ); - } - - /** - * Tests that trying to create a new Instance from an empty string breaks. - * - * @since 1.0.0 - * @return void - */ - public function testCreatingNewInstanceFromStringBreaksWithEmptyString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - ImmutableFloat::fromString(''); - } - - /** - * Test that an instance can be created from a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanCreateNewInstanceFromString(): void - { - // Performs test. - $instance = ImmutableFloat::fromString('123.0'); - - // Performs assertions. - $this->assertEquals( - 123.0, - $instance->value(), - 'Instance value does not match.' - ); - } - - /** - * Test that an instance can be created from a Float. - * - * @since 1.0.0 - * @return void - */ - public function testCanCreateNewInstanceFromFloat(): void - { - // Performs test. - $instance = ImmutableFloat::fromFloat(123.0); - - // Performs assertions. - $this->assertEquals( - 123.0, - $instance->value(), - 'Instance value does not match.' - ); - } - - /** - * Tests a value can be added to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanAddPositiveValue(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $other = $original->add($this->initializeInstance(2.0)); - - // Performs assertions. - $this->assertEquals( - 125.0, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be added to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanAddNegativeValue(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $other = $original->add($this->initializeInstance(-3.0)); - - // Performs assertions. - $this->assertEquals( - 120.0, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be subtracted to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanSubtractPositiveValue(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $other = $original->subtract($this->initializeInstance(3.0)); - - // Performs assertions. - $this->assertEquals( - 120.0, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be subtracted to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanSubtractNegativeValue(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $other = $original->subtract($this->initializeInstance(-2.0)); - - // Performs assertions. - $this->assertEquals( - 125.0, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be multiply to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanMultiplyPositiveValue(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $other = $original->multiply($this->initializeInstance(2.0)); - - // Performs assertions. - $this->assertEquals( - 246.0, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be multiply to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanMultiplyNegativeValue(): void - { - // Performs test. - $original = $this->initializeInstance(123.0); - $other = $original->multiply($this->initializeInstance(-2.0)); - - // Performs assertions. - $this->assertEquals( - -246.0, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be divide to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanDividePositiveValue(): void - { - // Performs test. - $original = $this->initializeInstance(40.0); - $other = $original->divide($this->initializeInstance(2.0)); - - // Performs assertions. - $this->assertEquals( - 20.0, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be divide to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanDivideNegativeValue(): void - { - // Performs test. - $original = $this->initializeInstance(40.0); - $other = $original->divide($this->initializeInstance(-2.0)); - - // Performs assertions. - $this->assertEquals( - -20.0, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests that the number can be formatted correctly. - * - * @since 1.0.0 - * @return void - */ - public function testCanFormatTheInstance(): void - { - // Performs test. - $original = $this->initializeInstance(4000.1); - $formated = $original->format( - \NumberFormatter::create('en_US', \NumberFormatter::DECIMAL) - ); - - // Performs assertions. - $this->assertEquals( - '4,000.1', - $formated->__toString(), - 'Formatted number does not seam to match.' - ); - $this->assertInstanceOf( - ImmutableString::class, - $formated, - 'Instance type, does not match ImmutableString.' - ); - } -} diff --git a/tests/Unit/Scalar/ImmutableIntegerTest.php b/tests/Unit/Scalar/ImmutableIntegerTest.php deleted file mode 100644 index 63e8da1..0000000 --- a/tests/Unit/Scalar/ImmutableIntegerTest.php +++ /dev/null @@ -1,392 +0,0 @@ -ImmutableInteger and MutableInteger classes have similar behavior, therefore, - * you should extend this test case for the other type of String, overriding only the necessary - * tests, which shouldn't be too many. - * - * This way, we can test both types of objects, without repeating the same code/tests. - * - * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ImmutableIntegerTest extends AbstractBaseTestCase -{ - /** - * Asserts that 2 integer instances do not match. - * - * @param AbstractReadInteger $original - Original Integer instance. - * @param AbstractReadInteger $other - Second instance for comparison. - * - * @since 1.0.0 - * @return void - */ - protected function checkInstances(AbstractReadInteger $original, AbstractReadInteger $other): void - { - $this->assertFalse( - ($original === $other), - 'Instances are not meant to match.' - ); - } - - /** - * Asserts that the supplied instance, is from the correct type. - * - * @param AbstractReadInteger $instance - Instance to be validated. - * - * @since 1.0.0 - * @return void - */ - protected function checkCorrectInstanceType(AbstractReadInteger $instance): void - { - $this->assertInstanceOf( - ImmutableInteger::class, - $instance, - 'Instance type, does not match ImmutableInteger.' - ); - } - - /** - * Initializes and returns a new instance for testing. - * - * This method has no return value, due to inheritance overriding. - * - * @param string $initialValue - Instance's initial value. - * - * @since 1.0.0 - * @return ImmutableInteger - */ - protected function initializeInstance(string $initialValue) - { - return ImmutableInteger::fromString($initialValue); - } - - /** - * Checks instance can be cloned. - * - * @since 1.0.0 - * @return void - */ - public function testCanCloneObject(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->toMutable(); - - // Performs assertions. - $this->assertInstanceOf( - MutableInteger::class, - $other, - 'Instance type, does not match MutableInteger.' - ); - $this->assertEquals( - $original->value(), - $other->value(), - 'Instance values do not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests that the instance can be converted to a Float. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToFloat(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $float = $original->toFloat(); - - // Performs assertions. - $this->assertInstanceOf( - ImmutableFloat::class, - $float, - 'Instance type, does not match ImmutableFloat.' - ); - } - - /** - * Tests that the instance can be converted to a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToString(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $string = $original->toString(); - - // Performs assertions. - $this->assertInstanceOf( - ImmutableString::class, - $string, - 'Instance type, does not match ImmutableString.' - ); - } - - /** - * Tests that trying to create a new Instance from an empty string breaks. - * - * @since 1.0.0 - * @return void - */ - public function testCreatingNewInstanceFromStringBreaksWithEmptyString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - ImmutableInteger::fromString(''); - } - - /** - * Test that an instance can be created from a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanCreateNewInstanceFromString(): void - { - // Performs test. - $instance = ImmutableInteger::fromString('123'); - - // Performs assertions. - $this->assertEquals( - 123, - $instance->value(), - 'Instance value does not match.' - ); - } - - /** - * Test that an instance can be created from an Integer. - * - * @since 1.0.0 - * @return void - */ - public function testCanCreateNewInstanceFromInteger(): void - { - // Performs test. - $instance = ImmutableInteger::fromInteger(123); - - // Performs assertions. - $this->assertEquals( - 123, - $instance->value(), - 'Instance value does not match.' - ); - } - - /** - * Tests a value can be added to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanAddPositiveValue(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->add($this->initializeInstance(2)); - - // Performs assertions. - $this->assertEquals( - 125, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be added to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanAddNegativeValue(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->add($this->initializeInstance(-3)); - - // Performs assertions. - $this->assertEquals( - 120, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be subtracted to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanSubtractPositiveValue(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->subtract($this->initializeInstance(3)); - - // Performs assertions. - $this->assertEquals( - 120, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be subtracted to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanSubtractNegativeValue(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->subtract($this->initializeInstance(-2)); - - // Performs assertions. - $this->assertEquals( - 125, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be multiply to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanMultiplyPositiveValue(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->multiply($this->initializeInstance(2)); - - // Performs assertions. - $this->assertEquals( - 246, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be multiply to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanMultiplyNegativeValue(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->multiply($this->initializeInstance(-2)); - - // Performs assertions. - $this->assertEquals( - -246, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be divide to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanDividePositiveValue(): void - { - // Performs test. - $original = $this->initializeInstance(40); - $other = $original->divide($this->initializeInstance(2)); - - // Performs assertions. - $this->assertEquals( - 20, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests a value can be divide to the instance. - * - * @since 1.0.0 - * @return void - */ - public function testCanDivideNegativeValue(): void - { - // Performs test. - $original = $this->initializeInstance(40); - $other = $original->divide($this->initializeInstance(-2)); - - // Performs assertions. - $this->assertEquals( - -20, - $other->value(), - 'Instance value does not match.' - ); - $this->checkInstances($original, $other); - } - - /** - * Tests that the number can be formatted correctly. - * - * @since 1.0.0 - * @return void - */ - public function testCanFormatTheInstance(): void - { - // Performs test. - $original = $this->initializeInstance(4000); - $formated = $original->format( - \NumberFormatter::create('en_US', \NumberFormatter::DEFAULT_STYLE) - ); - - // Performs assertions. - $this->assertEquals( - '4,000', - $formated->__toString(), - 'Formatted number does not seam to match.' - ); - $this->assertInstanceOf( - ImmutableString::class, - $formated, - 'Instance type, does not match ImmutableString.' - ); - } -} diff --git a/tests/Unit/Scalar/MutableFloatTest.php b/tests/Unit/Scalar/MutableFloatTest.php deleted file mode 100644 index 0473e74..0000000 --- a/tests/Unit/Scalar/MutableFloatTest.php +++ /dev/null @@ -1,226 +0,0 @@ -ImmutableFloat and MutableFloat classes have similar behavior, therefore, - * you should extend this test case for the other type of String, overriding only the necessary - * tests, which shouldn't be too many. - * - * This way, we can test both types of objects, without repeating the same code/tests. - * - * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class MutableFloatTest extends ImmutableFloatTest -{ - /** - * Asserts that 2 integer instances do not match. - * - * @param AbstractReadFloat $original - Original Float instance. - * @param AbstractReadFloat $other - Second instance for comparison. - * - * @since 1.0.0 - * @return void - */ - protected function checkInstances(AbstractReadFloat $original, AbstractReadFloat $other): void - { - $this->assertTrue( - ($original === $other), - 'Instances are meant to match.' - ); - } - - /** - * Asserts that the supplied instance, is from the correct type. - * - * @param AbstractReadFloat $instance - Instance to be validated. - * - * @since 1.0.0 - * @return void - */ - protected function checkCorrectInstanceType(AbstractReadFloat $instance): void - { - $this->assertInstanceOf( - MutableFloat::class, - $instance, - 'Instance type, does not match MutableFloat.' - ); - } - - /** - * Initializes and returns a new instance for testing. - * - * This method has no return value, due to inheritance overriding. - * - * @param string $initialValue - Instance's initial value. - * - * @since 1.0.0 - * @return MutableInteger - */ - protected function initializeInstance(string $initialValue) - { - return MutableFloat::fromString($initialValue); - } - - /** - * Checks instance can be cloned. - * - * @since 1.0.0 - * @return void - */ - public function testCanCloneObject(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->toImmutable(); - - // Performs assertions. - $this->assertInstanceOf( - ImmutableFloat::class, - $other, - 'Instance type, does not match ImmutableFloat.' - ); - $this->assertEquals( - $original->value(), - $other->value(), - 'Instance values do not match.' - ); - $this->assertFalse( - ($original === $other), - 'Instances are not meant to match.' - ); - } - - /** - * Tests that the instance can be converted to an Integer. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToInteger(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $integer = $original->toInteger(); - - // Performs assertions. - $this->assertInstanceOf( - MutableInteger::class, - $integer, - 'Instance type, does not match MutableInteger.' - ); - } - - /** - * Tests that the instance can be converted to a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToString(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $string = $original->toString(); - - // Performs assertions. - $this->assertInstanceOf( - MutableString::class, - $string, - 'Instance type, does not match MutableString.' - ); - } - - /** - * Tests that trying to create a new Instance from an empty string breaks. - * - * @since 1.0.0 - * @return void - */ - public function testCreatingNewInstanceFromStringBreaksWithEmptyString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - MutableFloat::fromString(''); - } - - /** - * Test that an instance can be created from a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanCreateNewInstanceFromString(): void - { - // Performs test. - $instance = MutableFloat::fromString('123.1'); - - // Performs assertions. - $this->assertEquals( - 123.1, - $instance->value(), - 'Instance value does not match.' - ); - } - - /** - * Test that an instance can be created from a Float. - * - * @since 1.0.0 - * @return void - */ - public function testCanCreateNewInstanceFromFloat(): void - { - // Performs test. - $instance = MutableFloat::fromFloat(123); - - // Performs assertions. - $this->assertEquals( - 123, - $instance->value(), - 'Instance value does not match.' - ); - } - - /** - * Tests that the number can be formatted correctly. - * - * @since 1.0.0 - * @return void - */ - public function testCanFormatTheInstance(): void - { - // Performs test. - $original = $this->initializeInstance(4000.1); - $formated = $original->format( - \NumberFormatter::create('en_US', \NumberFormatter::DECIMAL) - ); - - // Performs assertions. - $this->assertEquals( - '4,000.1', - $formated->__toString(), - 'Formatted number does not seam to match.' - ); - $this->assertInstanceOf( - MutableString::class, - $formated, - 'Instance type, does not match MutableString.' - ); - } -} diff --git a/tests/Unit/Scalar/MutableIntegerTest.php b/tests/Unit/Scalar/MutableIntegerTest.php deleted file mode 100644 index 2e0d453..0000000 --- a/tests/Unit/Scalar/MutableIntegerTest.php +++ /dev/null @@ -1,226 +0,0 @@ -ImmutableInteger and MutableInteger classes have similar behavior, therefore, - * you should extend this test case for the other type of String, overriding only the necessary - * tests, which shouldn't be too many. - * - * This way, we can test both types of objects, without repeating the same code/tests. - * - * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class MutableIntegerTest extends ImmutableIntegerTest -{ - /** - * Asserts that 2 integer instances do not match. - * - * @param AbstractReadInteger $original - Original Integer instance. - * @param AbstractReadInteger $other - Second instance for comparison. - * - * @since 1.0.0 - * @return void - */ - protected function checkInstances(AbstractReadInteger $original, AbstractReadInteger $other): void - { - $this->assertTrue( - ($original === $other), - 'Instances are meant to match.' - ); - } - - /** - * Asserts that the supplied instance, is from the correct type. - * - * @param AbstractReadInteger $instance - Instance to be validated. - * - * @since 1.0.0 - * @return void - */ - protected function checkCorrectInstanceType(AbstractReadInteger $instance): void - { - $this->assertInstanceOf( - MutableInteger::class, - $instance, - 'Instance type, does not match MutableInteger.' - ); - } - - /** - * Initializes and returns a new instance for testing. - * - * This method has no return value, due to inheritance overriding. - * - * @param string $initialValue - Instance's initial value. - * - * @since 1.0.0 - * @return MutableInteger - */ - protected function initializeInstance(string $initialValue) - { - return MutableInteger::fromString($initialValue); - } - - /** - * Checks instance can be cloned. - * - * @since 1.0.0 - * @return void - */ - public function testCanCloneObject(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $other = $original->toImmutable(); - - // Performs assertions. - $this->assertInstanceOf( - ImmutableInteger::class, - $other, - 'Instance type, does not match ImmutableInteger.' - ); - $this->assertEquals( - $original->value(), - $other->value(), - 'Instance values do not match.' - ); - $this->assertFalse( - ($original === $other), - 'Instances are not meant to match.' - ); - } - - /** - * Tests that the instance can be converted to a Float. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToFloat(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $float = $original->toFloat(); - - // Performs assertions. - $this->assertInstanceOf( - MutableFloat::class, - $float, - 'Instance type, does not match MutableFloat.' - ); - } - - /** - * Tests that the instance can be converted to a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToString(): void - { - // Performs test. - $original = $this->initializeInstance(123); - $string = $original->toString(); - - // Performs assertions. - $this->assertInstanceOf( - MutableString::class, - $string, - 'Instance type, does not match MutableString.' - ); - } - - /** - * Tests that trying to create a new Instance from an empty string breaks. - * - * @since 1.0.0 - * @return void - */ - public function testCreatingNewInstanceFromStringBreaksWithEmptyString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - MutableInteger::fromString(''); - } - - /** - * Test that an instance can be created from a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanCreateNewInstanceFromString(): void - { - // Performs test. - $instance = MutableInteger::fromString('123'); - - // Performs assertions. - $this->assertEquals( - 123, - $instance->value(), - 'Instance value does not match.' - ); - } - - /** - * Test that an instance can be created from an Integer. - * - * @since 1.0.0 - * @return void - */ - public function testCanCreateNewInstanceFromInteger(): void - { - // Performs test. - $instance = MutableInteger::fromInteger(123); - - // Performs assertions. - $this->assertEquals( - 123, - $instance->value(), - 'Instance value does not match.' - ); - } - - /** - * Tests that the number can be formatted correctly. - * - * @since 1.0.0 - * @return void - */ - public function testCanFormatTheInstance(): void - { - // Performs test. - $original = $this->initializeInstance(4000); - $formated = $original->format( - \NumberFormatter::create('en_US', \NumberFormatter::DEFAULT_STYLE) - ); - - // Performs assertions. - $this->assertEquals( - '4,000', - $formated->__toString(), - 'Formatted number does not seam to match.' - ); - $this->assertInstanceOf( - MutableString::class, - $formated, - 'Instance type, does not match MutableString.' - ); - } -} diff --git a/tests/Unit/Scalar/ReadonlyBooleanTest.php b/tests/Unit/Scalar/ReadonlyBooleanTest.php deleted file mode 100644 index 4c03dfd..0000000 --- a/tests/Unit/Scalar/ReadonlyBooleanTest.php +++ /dev/null @@ -1,333 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ReadonlyBooleanTest extends AbstractBaseTestCase -{ - /** - * Performs various shared instance's tests. - * - * @param AbstractReadBoolean $instance - Instance to perform tests on. - * - * @since 1.0.0 - * @return void - */ - protected function instanceChecks(AbstractReadBoolean $instance): void - { - $this->assertInstanceOf( - ReadonlyBoolean::class, - $instance, - "Loaded instance doesn't seam to be from a ReadonlyBoolean type." - ); - } - - /** - * Tests loading from an empty string breaks. - * - * @since 1.0.0 - * @return void - */ - public function testBreaksIfLoadedWithEmptyString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - ReadonlyBoolean::fromString(''); - } - - /** - * Tests that a filled boolean can be loaded successfully. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadPositiveFloat(): void - { - // Performs test. - $value = ReadonlyBoolean::fromFloat(1.0); - - // Performs assertions. - $this->assertEquals( - 'True', - $value->toString(), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($value); - } - - /** - * Tests that a filled boolean can be loaded successfully. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadNegativeFloat(): void - { - // Performs test. - $test = -1; - $value = ReadonlyBoolean::fromFloat($test); - - // Performs assertions. - $this->assertEquals( - 'False', - $value->toString(), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($value); - } - - /** - * Tests that Yes/No strings can be loaded as booleans. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadYesNoString(): void - { - // Perform test. - $yes = ReadonlyBoolean::fromString('Yes'); - $no = ReadonlyBoolean::fromString('No'); - - // Performs assertions. - $this->assertEquals( - 'True', - $yes->toString(), - 'Boolean value does not seam to match.' - ); - $this->assertEquals( - 'False', - $no->toString(), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($yes); - $this->instanceChecks($no); - } - - /** - * Tests that True/False strings can be loaded as booleans. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadTrueFalseString(): void - { - // Perform test. - $true = ReadonlyBoolean::fromString('True'); - $false = ReadonlyBoolean::fromString('False'); - - // Performs assertions. - $this->assertEquals( - 'True', - $true->toString(), - 'Boolean value does not seam to match.' - ); - $this->assertEquals( - 'False', - $false->toString(), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($true); - $this->instanceChecks($false); - } - - /** - * Tests that 1/0 strings can be loaded as booleans. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadOneZeroStrings(): void - { - // Perform test. - $one = ReadonlyBoolean::fromString('1'); - $zero = ReadonlyBoolean::fromString('0'); - - // Performs assertions. - $this->assertEquals( - 'True', - $one->toString(), - 'Boolean value does not seam to match.' - ); - $this->assertEquals( - 'False', - $zero->toString(), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($one); - $this->instanceChecks($zero); - } - - /** - * Tests that 1/0 integers can be loaded as booleans. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadOneZeroIntegers(): void - { - // Perform test. - $one = ReadonlyBoolean::fromInteger(1); - $zero = ReadonlyBoolean::fromInteger(0); - - // Performs assertions. - $this->assertEquals( - 'True', - $one->toString(), - 'Boolean value does not seam to match.' - ); - $this->assertEquals( - 'False', - $zero->toString(), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($one); - $this->instanceChecks($zero); - } - - /** - * Tests the integer can be converted to a float. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertToInteger(): void - { - // Perform test. - $one = ReadonlyBoolean::fromString('1'); - $zero = ReadonlyBoolean::fromString('0'); - - // Performs assertions. - $this->assertEquals( - '1', - $one->toInteger()->toString(), - 'Boolean value does not seam to match.' - ); - $this->assertEquals( - '0', - $zero->toInteger()->toString(), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($one); - $this->instanceChecks($zero); - } - - /** - * Tests that can be successfully converted to a String. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyEchoToString(): void - { - // Perform test. - $true = ReadonlyBoolean::fromString('True'); - - // Performs assertions. - $this->assertEquals( - 'True', - $true->toString(), - 'Boolean value does not seam to match.' - ); - $this->assertEquals( - 'true', - $true->__toString(), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($true); - } - - /** - * Tests that instances can be compared. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareEqualInstances(): void - { - // Perform test. - $string = ReadonlyBoolean::fromString('True'); - $number = ReadonlyBoolean::fromString('1'); - - // Performs assertions. - $this->assertTrue( - $string->equals($number), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($string); - $this->instanceChecks($number); - } - - /** - * Tests that instances can be compared. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareUnequalInstances(): void - { - // Perform test. - $string = ReadonlyBoolean::fromString('True'); - $number = ReadonlyBoolean::fromString('False'); - - // Performs assertions. - $this->assertFalse( - $string->equals($number), - 'Boolean values seam to match.' - ); - $this->instanceChecks($string); - $this->instanceChecks($number); - } - - /** - * Tests that instances can be compared. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareEqualNatives(): void - { - // Perform test. - $string = ReadonlyBoolean::fromString('True'); - $native = true; - - // Performs assertions. - $this->assertTrue( - $string->equalsNative($native), - 'Boolean value does not seam to match.' - ); - $this->instanceChecks($string); - } - - /** - * Tests that instances can be compared. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareUnequalNatives(): void - { - // Perform test. - $string = ReadonlyBoolean::fromString('True'); - $native = false; - - // Performs assertions. - $this->assertFalse( - $string->equalsNative($native), - 'Boolean values seam to match.' - ); - $this->instanceChecks($string); - } -} diff --git a/tests/Unit/Scalar/ReadonlyFloatTest.php b/tests/Unit/Scalar/ReadonlyFloatTest.php deleted file mode 100644 index 225c078..0000000 --- a/tests/Unit/Scalar/ReadonlyFloatTest.php +++ /dev/null @@ -1,509 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ReadonlyFloatTest extends AbstractBaseTestCase -{ - /** - * Performs various shared instance's tests. - * - * @param AbstractReadFloat $instance - Instance to perform tests on. - * - * @since 1.0.0 - * @return void - */ - protected function instanceChecks(AbstractReadFloat $instance): void - { - $this->assertInstanceOf( - ReadonlyFloat::class, - $instance, - "Loaded instance doesn't seam to be from a ReadonlyFloat type." - ); - } - - /** - * Assert can collect maximum and minimum values. - * - * @since 1.0.0 - * @return void - */ - public function testCanRetrieveMaximumAndMinimumAllowedValues(): void - { - $this->assertEquals( - PHP_FLOAT_MAX, - ReadonlyFloat::max(), - 'Values do not match.' - ); - $this->assertEquals( - PHP_FLOAT_MIN, - ReadonlyFloat::min(), - 'Values do not match.' - ); - } - - /** - * Tests that a filled float can be loaded successfully. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadFilledFloat(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertEquals( - $test, - \intval($value->__toString()), - 'Float value does not seam to match.' - ); - $this->instanceChecks($value); - } - - /** - * Tests that a filled string can be loaded successfully. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadFilledString(): void - { - // Performs test. - $test = "123.1"; - $value = ReadonlyFloat::fromString($test); - - // Performs assertions. - $this->assertEquals( - $test, - $value->__toString(), - 'Float value does not seam to match.' - ); - $this->instanceChecks($value); - } - - /** - * Tests that an empty string cannot be loaded successfully. - * - * @since 1.0.0 - * @return void - */ - public function testCanNotLoadSuccessfullyEmptyString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - ReadonlyFloat::fromString(""); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareTwoEqualInstances(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertTrue( - $value->equals(ReadonlyFloat::fromFloat($test)), - 'Float values should have been equal.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareTwoUnequalInstances(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertFalse( - $value->equals(ReadonlyFloat::fromFloat(++$test)), - 'Float values should be unequal.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareTwoEqualValues(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertTrue( - $value->equalsNative($test), - 'Float values should have been equal.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareTwoUnequalValues(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertFalse( - $value->equalsNative(++$test), - 'Float values should be unequal.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsBiggerInstance(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertTrue( - $value->isBigger(ReadonlyFloat::fromFloat(--$test)), - 'Float should have been bigger.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsBiggerValue(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertTrue( - $value->isBiggerNative(--$test), - 'Float should have been bigger.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsNotBiggerInstance(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertFalse( - $value->isBigger(ReadonlyFloat::fromFloat(++$test)), - 'Float should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsNotBiggerValue(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertFalse( - $value->isBiggerNative($test), - 'Float should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsSmallerInstance(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertTrue( - $value->isSmaller(ReadonlyFloat::fromFloat(++$test)), - 'Float should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsSmallerValue(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertTrue( - $value->isSmallerNative(++$test), - 'Float should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsNotSmallerInstance(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertFalse( - $value->isSmaller(ReadonlyFloat::fromFloat(--$test)), - 'Float should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsNotSmallerValue(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertFalse( - $value->isSmallerNative($test), - 'Float should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can identify positive and negative integers. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateNegativeValue(): void - { - // Performs test. - $test = -123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertTrue( - $value->isNegative(), - 'Float should have been negative.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can identify positive and negative integers. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidatePositiveValue(): void - { - // Performs test. - $test = 123.0; - $value = ReadonlyFloat::fromFloat($test); - - // Performs assertions. - $this->assertFalse( - $value->isNegative(), - 'Float should have been positive.' - ); - $this->instanceChecks($value); - } - - /** - * Tests the integer can be correctly formatted. - * - * @since 1.0.0 - * @return void - */ - public function testCanFormatFloat(): void - { - // Performs test. - $value = ReadonlyFloat::fromString("1234560.1"); - $text = $value->format( - \NumberFormatter::create('en_US', \NumberFormatter::DECIMAL) - ); - - // Performs assertions. - $this->assertEquals( - "1,234,560.1", - $text->__toString(), - "The float wasn't formatted correctly." - ); - $this->assertInstanceOf( - ReadonlyString::class, - $text, - "Returned instance should have been of type ReadonlyString." - ); - } - - /** - * Tests the integer can be converted to a string. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertToString(): void - { - // Performs test. - $value = ReadonlyFloat::fromString("123456.1"); - $string = $value->toString(); - - // Performs assertions. - $this->assertEquals( - "123456.1", - $string->__toString(), - "The float wasn't converted to string correctly." - ); - $this->assertInstanceOf( - ReadonlyString::class, - $string, - "Returned instance should have been of type ReadonlyString." - ); - } - - /** - * Tests the integer can be converted to a float. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertToInteger(): void - { - // Performs test. - $value = ReadonlyFloat::fromString("123456.0"); - $integer = $value->toInteger(); - - // Performs assertions. - $this->assertEquals( - "123456", - $integer->__toString(), - "The float wasn't converted to integer correctly." - ); - $this->assertInstanceOf( - ReadonlyInteger::class, - $integer, - "Returned instance should have been of type ReadonlyInteger." - ); - } - - /** - * Tests that the instance can be converted to a Boolean. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToBoolean(): void - { - // Performs test. - $true = ReadonlyFloat::fromFloat(123.0); - $false = ReadonlyFloat::fromFloat(0.0); - $trueBoolean = $true->toBoolean(); - $falseBoolean = $false->toBoolean(); - - // Performs assertions. - $this->assertInstanceOf( - ReadonlyBoolean::class, - $trueBoolean, - 'Instance type, does not match ReadonlyBoolean.' - ); - $this->assertEquals( - 'True', - $trueBoolean->toString(), - 'Instance value is not correct.' - ); - $this->assertInstanceOf( - ReadonlyBoolean::class, - $falseBoolean, - 'Instance type, does not match ReadonlyBoolean.' - ); - $this->assertEquals( - 'False', - $falseBoolean->toString(), - 'Instance value is not correct.' - ); - } -} diff --git a/tests/Unit/Scalar/ReadonlyIntegerTest.php b/tests/Unit/Scalar/ReadonlyIntegerTest.php deleted file mode 100644 index 208da00..0000000 --- a/tests/Unit/Scalar/ReadonlyIntegerTest.php +++ /dev/null @@ -1,507 +0,0 @@ - - * @author Hugo Rafael Azevedo - * @license MIT - * @since 1.0.0 - */ -class ReadonlyIntegerTest extends AbstractBaseTestCase -{ - /** - * Performs various shared instance's tests. - * - * @param AbstractReadInteger $instance - Instance to perform tests on. - * - * @since 1.0.0 - * @return void - */ - protected function instanceChecks(AbstractReadInteger $instance): void - { - $this->assertInstanceOf( - ReadonlyInteger::class, - $instance, - "Loaded instance doesn't seam to be from a ReadonlyInteger type." - ); - } - - /** - * Assert can collect maximum and minimum values. - * - * @since 1.0.0 - * @return void - */ - public function testCanRetrieveMaximumAndMinimumAllowedValues(): void - { - $this->assertEquals( - PHP_INT_MAX, - ReadonlyInteger::max(), - 'Values do not match.' - ); - $this->assertEquals( - PHP_INT_MIN, - ReadonlyInteger::min(), - 'Values do not match.' - ); - } - - /** - * Tests that a filled integer can be loaded successfully. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadFilledInteger(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertEquals( - $test, - \intval($value->__toString()), - 'Integer value does not seam to match.' - ); - $this->instanceChecks($value); - } - - /** - * Tests that a filled string can be loaded successfully. - * - * @since 1.0.0 - * @return void - */ - public function testCanSuccessfullyLoadFilledString(): void - { - // Performs test. - $test = "123"; - $value = ReadonlyInteger::fromString($test); - - // Performs assertions. - $this->assertEquals( - $test, - $value->__toString(), - 'Integer value does not seam to match.' - ); - $this->instanceChecks($value); - } - - /** - * Tests that an empty string cannot be loaded successfully. - * - * @since 1.0.0 - * @return void - */ - public function testCanNotLoadSuccessfullyEmptyString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - ReadonlyInteger::fromString(""); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareTwoEqualInstances(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertTrue( - $value->equals(ReadonlyInteger::fromInteger($test)), - 'Integer values should have been equal.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareTwoUnequalInstances(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertFalse( - $value->equals(ReadonlyInteger::fromInteger(++$test)), - 'Integer values should be unequal.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareTwoEqualValues(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertTrue( - $value->equalsNative($test), - 'Integer values should have been equal.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanCompareTwoUnequalValues(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertFalse( - $value->equalsNative(++$test), - 'Integer values should be unequal.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsBiggerInstance(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertTrue( - $value->isBigger(ReadonlyInteger::fromInteger(--$test)), - 'Integer should have been bigger.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsBiggerValue(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertTrue( - $value->isBiggerNative(--$test), - 'Integer should have been bigger.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsNotBiggerInstance(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertFalse( - $value->isBigger(ReadonlyInteger::fromInteger(++$test)), - 'Integer should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsNotBiggerValue(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertFalse( - $value->isBiggerNative($test), - 'Integer should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsSmallerInstance(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertTrue( - $value->isSmaller(ReadonlyInteger::fromInteger(++$test)), - 'Integer should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsSmallerValue(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertTrue( - $value->isSmallerNative(++$test), - 'Integer should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsNotSmallerInstance(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertFalse( - $value->isSmaller(ReadonlyInteger::fromInteger(--$test)), - 'Integer should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can perform comparisons. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateIsNotSmallerValue(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertFalse( - $value->isSmallerNative($test), - 'Integer should have been smaller.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can identify positive and negative integers. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidateNegativeValue(): void - { - // Performs test. - $test = -123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertTrue( - $value->isNegative(), - 'Integer should have been negative.' - ); - $this->instanceChecks($value); - } - - /** - * Tests can identify positive and negative integers. - * - * @since 1.0.0 - * @return void - */ - public function testCanValidatePositiveValue(): void - { - // Performs test. - $test = 123; - $value = ReadonlyInteger::fromInteger($test); - - // Performs assertions. - $this->assertFalse( - $value->isNegative(), - 'Integer should have been positive.' - ); - $this->instanceChecks($value); - } - - /** - * Tests the integer can be correctly formatted. - * - * @since 1.0.0 - * @return void - */ - public function testCanFormatAnInteger(): void - { - // Performs test. - $value = ReadonlyInteger::fromString("123456"); - $text = $value->format(\NumberFormatter::create('en_US', \NumberFormatter::DEFAULT_STYLE)); - - // Performs assertions. - $this->assertEquals( - "123,456", - $text->__toString(), - "The integer wasn't formatted correctly." - ); - $this->assertInstanceOf( - ReadonlyString::class, - $text, - "Returned instance should have been of type ReadonlyString." - ); - } - - /** - * Tests the integer can be converted to a string. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertToString(): void - { - // Performs test. - $value = ReadonlyInteger::fromString("123456"); - $string = $value->toString(); - - // Performs assertions. - $this->assertEquals( - "123456", - $string->__toString(), - "The integer wasn't converted to string correctly." - ); - $this->assertInstanceOf( - ReadonlyString::class, - $string, - "Returned instance should have been of type ReadonlyString." - ); - } - - /** - * Tests the integer can be converted to a float. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertToFloat(): void - { - // Performs test. - $value = ReadonlyInteger::fromString("123456"); - $float = $value->toFloat(); - - // Performs assertions. - $this->assertEquals( - 123456.0, - $float->value(), - "The integer wasn't converted to float correctly." - ); - $this->assertInstanceOf( - ReadonlyFloat::class, - $float, - "Returned instance should have been of type ReadonlyFloat." - ); - } - - /** - * Tests that the instance can be converted to a Boolean. - * - * @since 1.0.0 - * @return void - */ - public function testCanConvertInstanceToBoolean(): void - { - // Performs test. - $true = ReadonlyInteger::fromInteger(123); - $false = ReadonlyInteger::fromInteger(0); - $trueBoolean = $true->toBoolean(); - $falseBoolean = $false->toBoolean(); - - // Performs assertions. - $this->assertInstanceOf( - ReadonlyBoolean::class, - $trueBoolean, - 'Instance type, does not match ReadonlyBoolean.' - ); - $this->assertEquals( - 'True', - $trueBoolean->toString(), - 'Instance value is not correct.' - ); - $this->assertInstanceOf( - ReadonlyBoolean::class, - $falseBoolean, - 'Instance type, does not match ReadonlyBoolean.' - ); - $this->assertEquals( - 'False', - $falseBoolean->toString(), - 'Instance value is not correct.' - ); - } -} From 315a870066c1147e141e510df687a5b1b44d4d11 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 18:16:00 +0000 Subject: [PATCH 006/193] refactor: Prepare code for v2 --- src/Scalar/AbstractReadString.php | 78 ++++------ src/Scalar/AbstractWriteString.php | 167 +++++++++----------- src/Scalar/ImmutableString.php | 155 ++++++++----------- src/Scalar/MutableString.php | 150 +++++++----------- src/Scalar/ReadonlyString.php | 13 +- src/Web/EmailAddress.php | 179 ++++++++++++++++++++++ tests/AbstractBaseTestCase.php | 7 +- tests/Unit/Scalar/ImmutableStringTest.php | 55 +------ tests/Unit/Scalar/MutableStringTest.php | 12 +- tests/Unit/Scalar/ReadonlyStringTest.php | 26 +--- tests/bootstrap.php | 3 - 11 files changed, 411 insertions(+), 434 deletions(-) create mode 100644 src/Web/EmailAddress.php diff --git a/src/Scalar/AbstractReadString.php b/src/Scalar/AbstractReadString.php index b3a21a2..607c8a2 100644 --- a/src/Scalar/AbstractReadString.php +++ b/src/Scalar/AbstractReadString.php @@ -1,4 +1,5 @@ -ReadOnlyString, MutableString datatype, - * as well as for ImmutableString. + * This class is also used as a base, for both ReadOnlyString, MutableString datatype, + * as well as for ImmutableString. * * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ abstract class AbstractReadString { /** * @var string $value - Internal string value for the instance. */ - protected $value = ''; + protected string $value = ''; /** - * Initializes a new instance of a String. + * Initializes a new instance of a String. * * @param string $value - Initial string value. - * - * @since 1.0.0 * @return void */ protected function __construct(string $value) @@ -37,10 +33,9 @@ protected function __construct(string $value) } /** - * Use this method to copy a child instance to a ReadonlyString instance, or just to clone a - * ReadonlyString. + * Use this method to copy a child instance to a ReadonlyString instance, or just to clone a + * ReadonlyString. * - * @since 1.0.0 * @return ReadonlyString */ public function toReadonly(): ReadonlyString @@ -53,7 +48,6 @@ public function toReadonly(): ReadonlyString /** * Magic method that will print out the native string representation of the instance. * - * @since 1.0.0 * @return string */ public function __toString(): string @@ -64,11 +58,10 @@ public function __toString(): string /** * Compares the values of 2 separate instances. * - * Returns TRUE if the 2 instance's values match. FALSE otherwise. + * Returns TRUE if the 2 instance's values match. FALSE otherwise. * * @param ReadOnlyString $string - Another String instance to compare to. * - * @since 1.0.0 * @return bool */ public function equals(ReadOnlyString $string): bool @@ -79,7 +72,6 @@ public function equals(ReadOnlyString $string): bool /** * Returns the instance's value character length. * - * @since 1.0.0 * @return int */ public function length(): int @@ -88,21 +80,19 @@ public function length(): int } /** - * Searches and returns the index in the instance, of the $search string. + * Searches and returns the index in the instance, of the $search string. * - * If a $start is specified, search will start this number of characters counted from - * the beginning of the string. If $start is negative, the search will start this number + * If a $start is specified, search will start this number of characters counted from + * the beginning of the string. If $start is negative, the search will start this number * of characters counted from the end of the string. * - * If the $search is not found inthe instance's value, NULL is returned. + * If the $search is not found inthe instance's value, NULL is returned. * * @param string $search - String to search for in the instance. - * @param int $start - Search offset start. Defaults to NULL. + * @param int $start - Search offset start. Defaults to NULL. * - * @throws \InvalidArgumentException - If $search value is an empty string. - * @throws \OutOfRangeException - If the $start is either too small, or too long. - * - * @since 1.0.0 + * @throws \InvalidArgumentException - If $search value is an empty string. + * @throws \OutOfRangeException - If the $start is either too small, or too long. * @return int|NULL */ public function indexOf(string $search, int $start = null): ?int @@ -127,15 +117,13 @@ public function indexOf(string $search, int $start = null): ?int } /** - * Checks if the instance contains the supplied $search value. + * Checks if the instance contains the supplied $search value. * - * Returns TRUE if found. FALSE otherwise. + * Returns TRUE if found. FALSE otherwise. * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. - * - * @since 1.0.0 + * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ public function contains(string $search): bool @@ -149,13 +137,11 @@ public function contains(string $search): bool } /** - * Checks if the instance's value starts with the supplied string. + * Checks if the instance's value starts with the supplied string. * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. - * - * @since 1.0.0 + * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ public function startsWith(string $search): bool @@ -169,13 +155,11 @@ public function startsWith(string $search): bool } /** - * Checks if the instance's value ends with the supplied string. + * Checks if the instance's value ends with the supplied string. * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. - * - * @since 1.0.0 + * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ public function endsWith(string $search): bool @@ -193,12 +177,10 @@ public function endsWith(string $search): bool * * @param string $search - Non empty string to search for in the instance. * @param int $start - The sub-string's offset/start. - * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. + * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. * - * @throws \InvalidArgumentException - If supplied $search is empty. - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * - * @since 1.0.0 + * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ public function count(string $search, int $start = 0, int $length = null): int @@ -220,14 +202,12 @@ public function count(string $search, int $start = 0, int $length = null): int } /** - * Validates a character $length, based on the instance value's length, and supplied $start. + * Validates a character $length, based on the instance value's length, and supplied $start. * * @param int $start - The sub-string's offset/start. - * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. - * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. * - * @since 1.0.0 + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return void */ protected function validateStartAndLength(int $start, ?int $length): void diff --git a/src/Scalar/AbstractWriteString.php b/src/Scalar/AbstractWriteString.php index 4110e3e..64ac966 100644 --- a/src/Scalar/AbstractWriteString.php +++ b/src/Scalar/AbstractWriteString.php @@ -1,26 +1,23 @@ -ImmutableString and - * MutableString objects, as both perform the same operations, but return different outcomes. + * The purpose of this class is to center writing operations for both ImmutableString and + * MutableString objects, as both perform the same operations, but return different outcomes. * - * This class will perform every writing operation, for internal use only. + * This class will perform every writing operation, for internal use only. * * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ abstract class AbstractWriteString extends AbstractReadString { /** * Trims instance's value, and returns a new instance of the object. * - * @since 1.0.0 * @return string */ protected function doTrim(): string @@ -31,7 +28,6 @@ protected function doTrim(): string /** * Left trims instance's value, and returns a new instance of the object. * - * @since 1.0.0 * @return string */ protected function doTrimLeft(): string @@ -42,7 +38,6 @@ protected function doTrimLeft(): string /** * Right trims instance's value, and returns a new instance of the object. * - * @since 1.0.0 * @return string */ protected function doTrimRight(): string @@ -51,9 +46,8 @@ protected function doTrimRight(): string } /** - * Converts the instance's value to Upper Case, and returns a new instance of the object. + * Converts the instance's value to Upper Case, and returns a new instance of the object. * - * @since 1.0.0 * @return string */ protected function doToUpper(): string @@ -62,10 +56,9 @@ protected function doToUpper(): string } /** - * Converts the instance's value first character to Upper Case, and returns a new instance + * Converts the instance's value first character to Upper Case, and returns a new instance * of the object. * - * @since 1.0.0 * @return string */ protected function doToUpperFirst(): string @@ -74,12 +67,11 @@ protected function doToUpperFirst(): string } /** - * Converts the instance's value first character of each word to Upper Case, and returns a new instance + * Converts the instance's value first character of each word to Upper Case, and returns a new instance * of the object. * * @param string $delimiters - The optional delimiters contains the word separator characters. * - * @since 1.0.0 * @return string */ protected function doToUpperWords(string $delimiters = " \t\r\n\f\v"): string @@ -88,9 +80,8 @@ protected function doToUpperWords(string $delimiters = " \t\r\n\f\v"): string } /** - * Converts the instance's value to Lower Case, and returns a new instance of the object. + * Converts the instance's value to Lower Case, and returns a new instance of the object. * - * @since 1.0.0 * @return string */ protected function doToLower(): string @@ -99,10 +90,9 @@ protected function doToLower(): string } /** - * Converts the instance's value first character to Lower Case, and returns a new instance + * Converts the instance's value first character to Lower Case, and returns a new instance * of the object * - * @since 1.0.0 * @return string */ protected function doToLowerFirst(): string @@ -111,156 +101,144 @@ protected function doToLowerFirst(): string } /** - * This method returns a new instance padded on the left to the specified padding length minus + * This method returns a new instance padded on the LEFT to the specified padding length minus * the length of the instance's value. * * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will * only be padded by the value of 2. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padString up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padString's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return string */ - protected function doPadLeft(int $length, string $padString = " "): string + protected function doPadLeft(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { throw new \InvalidArgumentException("Supplied Length must be a positive integer."); } - if (\strlen($padString) === 0) { + if (\strlen($padding) === 0) { throw new \InvalidArgumentException("Supplied padding must be a non empty string."); } - return \str_pad($this->value, $length, $padString, STR_PAD_LEFT); + return \str_pad($this->value, $length, $padding, STR_PAD_LEFT); } /** - * This method returns a new instance padded on the left, exactly to the specified padding length. + * This method returns a new instance padded on the LEFT, exactly to the specified padding length. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return string */ - protected function doPadLeftExtra(int $length, string $padString = " "): string + protected function doPadLeftExtra(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { throw new \InvalidArgumentException("Supplied Length must be a positive integer."); } - if (\strlen($padString) === 0) { + if (\strlen($padding) === 0) { throw new \InvalidArgumentException("Supplied padding must be a non empty string."); } - return \str_pad($this->value, ($this->length() + $length), $padString, STR_PAD_LEFT); + return \str_pad($this->value, ($this->length() + $length), $padding, STR_PAD_LEFT); } /** - * This method returns a new instance padded on the right to the specified padding length minus + * This method returns a new instance padded on the RIGHT to the specified padding length minus * the length of the instance's value. * * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will * only be padded by the value of 2. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return string */ - protected function doPadRight(int $length, string $padString = " "): string + protected function doPadRight(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { throw new \InvalidArgumentException("Supplied Length must be a positive integer."); } - if (\strlen($padString) === 0) { + if (\strlen($padding) === 0) { throw new \InvalidArgumentException("Supplied padding must be a non empty string."); } - return \str_pad($this->value, $length, $padString, STR_PAD_RIGHT); + return \str_pad($this->value, $length, $padding, STR_PAD_RIGHT); } /** - * This method returns a new instance padded on the right, exactly to the specified padding length. + * This method returns a new instance padded on the RIGHT, exactly to the specified padding length. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return string */ - protected function doPadRightExtra(int $length, string $padString = " "): string + protected function doPadRightExtra(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { throw new \InvalidArgumentException("Supplied Length must be a positive integer."); } - if (\strlen($padString) === 0) { + if (\strlen($padding) === 0) { throw new \InvalidArgumentException("Supplied padding must be a non empty string."); } - return \str_pad($this->value, ($this->length() + $length), $padString, STR_PAD_RIGHT); + return \str_pad($this->value, ($this->length() + $length), $padding, STR_PAD_RIGHT); } /** * This method returns a new instance with a portion of the original instance's value, specified by the - * $start and $length parameters. + * $start and $length parameters. * - * $start parameter: - *
    - *
  • If $start is non-negative, the returned an instance will start at the $start'th position in + * $start parameter: + * - If $start is non-negative, the returned an instance will start at the $start'th position in * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the - * character at position 2 is 'c', and so forth.
  • - *
  • If $start is negative, the returned string will start at the $start'th character from the end - * of string.
  • - *
  • If the absolute value of $start is higher than the instance's length, an - * exception is thrown.
  • - *
- * - * $length parameter: - *
    - *
  • If $length is given and is positive, the string returned will contain at most length characters - * beginning from $start (depending on the length of string).
  • - *
  • If $length is given and is negative, then that many characters will be omitted from the end of string - * (after the start position has been calculated when a start is negative).
  • - *
  • If $length exceeds the remaining number of characters, after the $start calculation, an - * Exception will be raised.
  • - *
+ * character at position 2 is 'c', and so forth. + * - If $start is negative, the returned string will start at the $start'th character from the end + * of string. + * - If the absolute value of $start is higher than the instance's length, an + * exception is thrown. + * + * + * $length parameter: + * - If $length is given and is positive, the string returned will contain at most length characters + * beginning from $start (depending on the length of string). + * - If $length is given and is negative, then that many characters will be omitted from the end of string + * (after the start position has been calculated when a start is negative). + * - If $length exceeds the remaining number of characters, after the $start calculation, an + * Exception will be raised. + * * * @param int $start - Start of the sub-string. Can be negative. * @param int $length - Length of the sub-string. Can be negative. * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * - * @since 1.0.0 + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return string */ protected function doSubString(int $start, int $length = null): string @@ -280,15 +258,13 @@ protected function doSubString(int $start, int $length = null): string /** * This method returns a new instance with a portion of the original instance's value, starting at the beginning - * of the value, with the number of characters specified in the $length parameter. + * of the value, with the number of characters specified in the $length parameter. * - * Same rules as ImmutableString::subString() are applied. + * Same rules as ImmutableString::subString() are applied. * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * - * @since 1.0.0 * @return string */ protected function doSubLeft(int $length): string @@ -303,15 +279,13 @@ protected function doSubLeft(int $length): string /** * This method returns a new instance with a portion of the original instance's value, couting from the end - * of the value, with the number of characters specified in the $length parameter. + * of the value, with the number of characters specified in the $length parameter. * - * Same rules as ImmutableString::subString() are applied. + * Same rules as ImmutableString::subString() are applied. * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * - * @since 1.0.0 * @return string */ protected function doSubRight(int $length): string @@ -327,7 +301,6 @@ protected function doSubRight(int $length): string /** * This method returns a new instance with the reversed value of the original instance. * - * @since 1.0.0 * @return string */ protected function doReverse(): string @@ -342,8 +315,6 @@ protected function doReverse(): string * @param string $replace - The search's replacement. * * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. - * - * @since 1.0.0 * @return string */ protected function doReplace(string $search, string $replace): string diff --git a/src/Scalar/ImmutableString.php b/src/Scalar/ImmutableString.php index 145f956..58c25d3 100644 --- a/src/Scalar/ImmutableString.php +++ b/src/Scalar/ImmutableString.php @@ -1,28 +1,24 @@ -Value Object, in a DDD project. + * you're using it as a Value Object, in a DDD project. * * Method chaning is not supported by any mutators. A new instance will be returned instead. * * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ class ImmutableString extends AbstractWriteString { /** - * Creates a new instance of ImmutableString based on a string value. + * Creates a new instance of ImmutableString based on a string value. * * @param string $value - Instance's initial value. - * - * @since 1.0.0 * @return ImmutableString */ public static function fromString(string $value): ImmutableString @@ -31,9 +27,8 @@ public static function fromString(string $value): ImmutableString } /** - * Clones this ImmutableString instance, into a MutableString one. + * Clones this ImmutableString instance, into a MutableString one. * - * @since 1.0.0 * @return MutableString */ public function toMutable(): MutableString @@ -46,7 +41,6 @@ public function toMutable(): MutableString /** * Trims instance's value, and returns a new instance of the object. * - * @since 1.0.0 * @return ImmutableString */ public function trim(): ImmutableString @@ -59,7 +53,6 @@ public function trim(): ImmutableString /** * Left trims instance's value, and returns a new instance of the object. * - * @since 1.0.0 * @return ImmutableString */ public function trimLeft(): ImmutableString @@ -72,7 +65,6 @@ public function trimLeft(): ImmutableString /** * Right trims instance's value, and returns a new instance of the object. * - * @since 1.0.0 * @return ImmutableString */ public function trimRight(): ImmutableString @@ -83,9 +75,8 @@ public function trimRight(): ImmutableString } /** - * Converts the instance's value to Upper Case, and returns a new instance of the object. + * Converts the instance's value to Upper Case, and returns a new instance of the object. * - * @since 1.0.0 * @return ImmutableString */ public function toUpper(): ImmutableString @@ -96,10 +87,9 @@ public function toUpper(): ImmutableString } /** - * Converts the instance's value first character to Upper Case, and returns a new instance + * Converts the instance's value first character to Upper Case, and returns a new instance * of the object. * - * @since 1.0.0 * @return ImmutableString */ public function toUpperFirst(): ImmutableString @@ -110,12 +100,11 @@ public function toUpperFirst(): ImmutableString } /** - * Converts the instance's value first character of each word to Upper Case, and returns a new instance + * Converts the instance's value first character of each word to Upper Case, and returns a new instance * of the object. * * @param string $delimiters - The optional delimiters contains the word separator characters. * - * @since 1.0.0 * @return ImmutableString */ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): ImmutableString @@ -126,9 +115,8 @@ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): ImmutableStrin } /** - * Converts the instance's value to Lower Case, and returns a new instance of the object. + * Converts the instance's value to Lower Case, and returns a new instance of the object. * - * @since 1.0.0 * @return ImmutableString */ public function toLower(): ImmutableString @@ -139,10 +127,9 @@ public function toLower(): ImmutableString } /** - * Converts the instance's value first character to Lower Case, and returns a new instance + * Converts the instance's value first character to Lower Case, and returns a new instance * of the object * - * @since 1.0.0 * @return ImmutableString */ public function toLowerFirst(): ImmutableString @@ -153,128 +140,115 @@ public function toLowerFirst(): ImmutableString } /** - * This method returns a new instance padded on the left to the specified padding length minus + * This method returns a new instance padded on the left to the specified padding length minus * the length of the instance's value. * * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will * only be padded by the value of 2. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return ImmutableString */ - public function padLeft(int $length, string $padString = " "): ImmutableString + public function padLeft(int $length, string $padding = " "): ImmutableString { return new ImmutableString( - parent::doPadLeft($length, $padString) + parent::doPadLeft($length, $padding) ); } /** - * This method returns a new instance padded on the left, exactly to the specified padding length. + * This method returns a new instance padded on the left, exactly to the specified padding length. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return ImmutableString */ - public function padLeftExtra(int $length, string $padString = " "): ImmutableString + public function padLeftExtra(int $length, string $padding = " "): ImmutableString { return new ImmutableString( - parent::doPadLeftExtra($length, $padString) + parent::doPadLeftExtra($length, $padding) ); } /** - * This method returns a new instance padded on the right to the specified padding length minus + * This method returns a new instance padded on the right to the specified padding length minus * the length of the instance's value. * * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will * only be padded by the value of 2. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return ImmutableString */ - public function padRight(int $length, string $padString = " "): ImmutableString + public function padRight(int $length, string $padding = " "): ImmutableString { return new ImmutableString( - parent::doPadRight($length, $padString) + parent::doPadRight($length, $padding) ); } /** - * This method returns a new instance padded on the right, exactly to the specified padding length. + * This method returns a new instance padded on the right, exactly to the specified padding length. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return ImmutableString */ - public function padRightExtra(int $length, string $padString = " "): ImmutableString + public function padRightExtra(int $length, string $padding = " "): ImmutableString { return new ImmutableString( - parent::doPadRightExtra($length, $padString) + parent::doPadRightExtra($length, $padding) ); } /** * This method returns a new instance with a portion of the original instance's value, specified by the - * $start and $length parameters. + * $start and $length parameters. * - * $start parameter: - *
    - *
  • If $start is non-negative, the returned an instance will start at the $start'th position in + * $start parameter: + * -If $start is non-negative, the returned an instance will start at the $start'th position in * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the - * character at position 2 is 'c', and so forth.
  • - *
  • If $start is negative, the returned string will start at the $start'th character from the end - * of string.
  • - *
  • If the absolute value of $start is higher than the instance's length, an - * exception is thrown.
  • - *
- * - * $length parameter: - *
    - *
  • If $length is given and is positive, the string returned will contain at most length characters - * beginning from $start (depending on the length of string).
  • - *
  • If $length is given and is negative, then that many characters will be omitted from the end of string - * (after the start position has been calculated when a start is negative).
  • - *
  • If $length exceeds the remaining number of characters, after the $start calculation, an - * Exception will be raised.
  • - *
+ * character at position 2 is 'c', and so forth. + * - If $start is negative, the returned string will start at the $start'th character from the end + * of string. + * - If the absolute value of $start is higher than the instance's length, an + * exception is thrown. + * + * + * $length parameter: + * - If $length is given and is positive, the string returned will contain at most length characters + * beginning from $start (depending on the length of string). + * - If $length is given and is negative, then that many characters will be omitted from the end of string + * (after the start position has been calculated when a start is negative). + * - If $length exceeds the remaining number of characters, after the $start calculation, an + * Exception will be raised. * * @param int $start - Start of the sub-string. Can be negative. * @param int $length - Length of the sub-string. Can be negative. * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * - * @since 1.0.0 + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return ImmutableString */ public function subString(int $start, int $length = null): ImmutableString @@ -286,15 +260,13 @@ public function subString(int $start, int $length = null): ImmutableString /** * This method returns a new instance with a portion of the original instance's value, starting at the beginning - * of the value, with the number of characters specified in the $length parameter. + * of the value, with the number of characters specified in the $length parameter. * - * Same rules as ImmutableString::subString() are applied. + * Same rules as ImmutableString::subString() are applied. * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * - * @since 1.0.0 * @return ImmutableString */ public function subLeft(int $length): ImmutableString @@ -306,15 +278,13 @@ public function subLeft(int $length): ImmutableString /** * This method returns a new instance with a portion of the original instance's value, couting from the end - * of the value, with the number of characters specified in the $length parameter. + * of the value, with the number of characters specified in the $length parameter. * - * Same rules as ImmutableString::subString() are applied. + * Same rules as ImmutableString::subString() are applied. * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * - * @since 1.0.0 * @return ImmutableString */ public function subRight(int $length): ImmutableString @@ -327,7 +297,6 @@ public function subRight(int $length): ImmutableString /** * This method returns a new instance with the reversed value of the original instance. * - * @since 1.0.0 * @return ImmutableString */ public function reverse(): ImmutableString @@ -344,8 +313,6 @@ public function reverse(): ImmutableString * @param string $replace - The search's replacement. * * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. - * - * @since 1.0.0 * @return ImmutableString */ public function replace(string $search, string $replace): ImmutableString diff --git a/src/Scalar/MutableString.php b/src/Scalar/MutableString.php index 225e88c..1539825 100644 --- a/src/Scalar/MutableString.php +++ b/src/Scalar/MutableString.php @@ -1,4 +1,5 @@ - - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ class MutableString extends AbstractWriteString { /** - * Creates a new instance of MutableString based on a string value. + * Creates a new instance of MutableString based on a string value. * * @param string $value - Instance's initial value. - * - * @since 1.0.0 * @return MutableString */ public static function fromString(string $value): MutableString @@ -33,9 +29,8 @@ public static function fromString(string $value): MutableString } /** - * Clones this MutableString instance, into a ImmutableString one. + * Clones this MutableString instance, into a ImmutableString one. * - * @since 1.0.0 * @return ImmutableString */ public function toImmutable(): ImmutableString @@ -50,7 +45,6 @@ public function toImmutable(): ImmutableString * * This method supports chaning. * - * @since 1.0.0 * @return MutableString */ public function trim(): MutableString @@ -65,7 +59,6 @@ public function trim(): MutableString * * This method supports chaning. * - * @since 1.0.0 * @return MutableString */ public function trimLeft(): MutableString @@ -80,7 +73,6 @@ public function trimLeft(): MutableString * * This method supports chaning. * - * @since 1.0.0 * @return MutableString */ public function trimRight(): MutableString @@ -91,11 +83,10 @@ public function trimRight(): MutableString } /** - * Converts the instance's value to Upper Case. + * Converts the instance's value to Upper Case. * * This method supports chaning. * - * @since 1.0.0 * @return MutableString */ public function toUpper(): MutableString @@ -109,9 +100,6 @@ public function toUpper(): MutableString * Make a string's first character uppercase. * * @return MutableString - * - * @since 1.0.0 - * @return MutableString */ public function toUpperFirst(): MutableString { @@ -121,11 +109,10 @@ public function toUpperFirst(): MutableString } /** - * Makes the string's first character of each word to Upper Case. + * Makes the string's first character of each word to Upper Case. * * @param string $delimiters - The optional delimiters contains the word separator characters. * - * @since 1.0.0 * @return MutableString */ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): MutableString @@ -136,11 +123,10 @@ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): MutableString } /** - * Converts the instance's value to Lower Case. + * Converts the instance's value to Lower Case. * * This method supports chaning. * - * @since 1.0.0 * @return MutableString */ public function toLower(): MutableString @@ -153,7 +139,6 @@ public function toLower(): MutableString /** * Make a string's first character lowercase. * - * @since 1.0.0 * @return MutableString */ public function toLowerFirst(): MutableString @@ -164,136 +149,124 @@ public function toLowerFirst(): MutableString } /** - * This method returns a new instance padded on the left to the specified padding length minus + * This method returns a new instance padded on the left to the specified padding length minus * the length of the instance's value. * * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will * only be padded by the value of 2. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * * This method supports chaning. * * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return MutableString */ - public function padLeft(int $length, string $padString = " "): MutableString + public function padLeft(int $length, string $padding = " "): MutableString { - $this->value = parent::doPadLeft($length, $padString); + $this->value = parent::doPadLeft($length, $padding); return $this; } /** - * This method returns a new instance padded on the left, exactly to the specified padding length. + * This method returns a new instance padded on the left, exactly to the specified padding length. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return MutableString */ - public function padLeftExtra(int $length, string $padString = " "): MutableString + public function padLeftExtra(int $length, string $padding = " "): MutableString { - $this->value = parent::doPadLeftExtra($length, $padString); + $this->value = parent::doPadLeftExtra($length, $padding); return $this; } /** - * This method returns a new instance padded on the right to the specified padding length minus + * This method returns a new instance padded on the right to the specified padding length minus * the length of the instance's value. * * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will * only be padded by the value of 2. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * * This method supports chaning. * * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return MutableString */ - public function padRight(int $length, string $padString = " "): MutableString + public function padRight(int $length, string $padding = " "): MutableString { - $this->value = parent::doPadRight($length, $padString); + $this->value = parent::doPadRight($length, $padding); return $this; } /** - * This method returns a new instance padded on the right, exactly to the specified padding length. + * This method returns a new instance padded on the right, exactly to the specified padding length. * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. * * @param int $length - Length of the padded value. - * @param string $padString - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * - * @since 1.0.0 * @return MutableString */ - public function padRightExtra(int $length, string $padString = " "): MutableString + public function padRightExtra(int $length, string $padding = " "): MutableString { - $this->value = parent::doPadRightExtra($length, $padString); + $this->value = parent::doPadRightExtra($length, $padding); return $this; } /** * This method mutates the instance's value with a portion of the original value, specified by the - * $start and $length parameters. + * $start and $length parameters. * - * $start parameter: - *
    - *
  • If $start is non-negative, the returned an instance will start at the $start'th position in + * $start parameter: + * - If $start is non-negative, the returned an instance will start at the $start'th position in * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the - * character at position 2 is 'c', and so forth.
  • - *
  • If $start is negative, the returned string will start at the $start'th character from the end - * of string.
  • - *
  • If the absolute value of $start is higher than the instance's length, an - * exception is thrown.
  • - *
- * - * $length parameter: - *
    - *
  • If $length is given and is positive, the string returned will contain at most length characters - * beginning from $start (depending on the length of string).
  • - *
  • If $length is given and is negative, then that many characters will be omitted from the end of string - * (after the start position has been calculated when a start is negative).
  • - *
  • If $length exceeds the remaining number of characters, after the $start calculation, an - * Exception will be raised.
  • - *
+ * character at position 2 is 'c', and so forth. + * - If $start is negative, the returned string will start at the $start'th character from the end + * of string. + * - If the absolute value of $start is higher than the instance's length, an + * exception is thrown. + * + * + * $length parameter: + * - If $length is given and is positive, the string returned will contain at most length characters + * beginning from $start (depending on the length of string). + * - If $length is given and is negative, then that many characters will be omitted from the end of string + * (after the start position has been calculated when a start is negative). + * - If $length exceeds the remaining number of characters, after the $start calculation, an + * Exception will be raised. + * * * @param int $start - Start of the sub-string. Can be negative. * @param int $length - Length of the sub-string. Can be negative. * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * - * @since 1.0.0 + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return MutableString */ public function subString(int $start, int $length = null): MutableString @@ -305,15 +278,13 @@ public function subString(int $start, int $length = null): MutableString /** * This method mutates the instance's value with a portion of the original instance's value, starting at the - * beginning of the value, with the number of characters specified in the $length parameter. + * beginning of the value, with the number of characters specified in the $length parameter. * - * Same rules as MutableString::subString() are applied. + * Same rules as MutableString::subString() are applied. * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * - * @since 1.0.0 * @return MutableString */ public function subLeft(int $length): MutableString @@ -325,15 +296,13 @@ public function subLeft(int $length): MutableString /** * This method mutates the instance's value with a portion of the original instance's value, couting from the - * end of the value, with the number of characters specified in the $length parameter. + * end of the value, with the number of characters specified in the $length parameter. * - * Same rules as MutableString::subString() are applied. + * Same rules as MutableString::subString() are applied. * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * - * @since 1.0.0 * @return MutableString */ public function subRight(int $length): MutableString @@ -346,7 +315,6 @@ public function subRight(int $length): MutableString /** * This method reverses value of the instance. * - * @since 1.0.0 * @return MutableString */ public function reverse(): MutableString @@ -363,8 +331,6 @@ public function reverse(): MutableString * @param string $replace - The search's replacement. * * @throws \InvalidArgumentException - If $search is empty. - * - * @since 1.0.0 * @return MutableString */ public function replace(string $search, string $replace): MutableString diff --git a/src/Scalar/ReadonlyString.php b/src/Scalar/ReadonlyString.php index b061f45..c4244e6 100644 --- a/src/Scalar/ReadonlyString.php +++ b/src/Scalar/ReadonlyString.php @@ -1,4 +1,5 @@ -MutableString datatype, as well as for - * ImmutableString. + * This class is also used as a base, for both the MutableString datatype, as well as for + * ImmutableString. * * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ class ReadonlyString extends AbstractReadString { /** - * Creates a new instance of ReadonlyString based on a string value. + * Creates a new instance of ReadonlyString based on a string value. * * @param string $value - Instance's initial value. * - * @since 1.0.0 * @return ReadonlyString */ public static function fromString(string $value): ReadonlyString diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php new file mode 100644 index 0000000..1b7a26f --- /dev/null +++ b/src/Web/EmailAddress.php @@ -0,0 +1,179 @@ + + * @author Hugo Rafael Azevedo + * @license MIT + * @since 1.0.0 + */ +class EmailAddress implements \Serializable +{ + /** + * Loads a new EmailAddress instance from a native string. + * + * @param string $email - E-mail address used to initialize instance. + * + * @since 1.0.0 + * @return EmailAddress + */ + public function fromString(string $email): EmailAddress + { + return new EmailAddress($email); + } + + /** + * @var string $username - Holds the Username's part of the E-mail address. + */ + protected $username = null; + + /** + * @var string $domain - Holds the Domain part of the E-mail address. + */ + protected $domain = null; + + /** + * @var string $tld - Holds the Top Level Domain part of the E-mail address. + */ + protected $tld = null; + + /** + * Initializes a new instance of an E-mail address. + * + * @param string $email - String representation of the e-mail address. + * + * @throws \InvalidArgumentException - If the supplied email address is empty or invalid. + * + * @since 1.0.0 + * @return void + */ + protected function __construct(string $email) + { + // Loads data into class. + $this->loadEmail($email); + } + + /** + * Loads supplied $email address string representation into the class. + * + * @param string $email - String representation of the e-mail. + * + * @throws \InvalidArgumentException - If the supplied email address is empty or invalid. + * + * @since 1.0.0 + * @return void + */ + private function loadEmail(string $email): void + { + // Validate supplied parameter. + if (\strlen(\trim($email)) === 0) { + throw new \InvalidArgumentException("Supplied e-mail address must be a non empty string."); + } + if (!\filter_var($email, FILTER_VALIDATE_EMAIL)) { + throw new \InvalidArgumentException("Provided e-mail field does not seam to be a valid e-mail address."); + } + + // Sanitizes and processes supplied e-mail address. + $email = \strtolower(\trim($email)); + $parts = \explode('@', $email); + $this->username = $parts[0]; + + // Processes the right side of the e-mail address. + $domain = \explode('.', $parts[1]); + $this->tld = \array_pop($domain); + $this->domain = \implode('.', $domain); + } + + /** + * Serializes the contents of the class. + * + * @since 1.0.0 + * @return string + * + * {@inheritDoc} + * @see \Serializable::serialize() + */ + public function serialize() + { + return \serialize($this->address()); + } + + /** + * Unserializes back the contents of the class. + * + * @since 1.0.0 + * @return void + * + * {@inheritDoc} + * @see \Serializable::unserialize() + */ + public function unserialize($serialized) + { + // Loads unserialized data back to the class. + $this->loadEmail( + \unserialize($serialized) + ); + } + + /** + * Returns the String representation of the object. + * + * @since 1.0.0 + * + * @return string + */ + public function __toString(): string + { + return $this->address(); + } + + /** + * Returns a string representation for the Email address. + * + * @since 1.0.0 + * @return string + */ + public function address(): string + { + return ($this->username . '@' . $this->domain . '.' . $this->tld); + } + + /** + * Return the Username part for the e-mail address. + * + * @since 1.0.0 + * @return string + */ + public function username(): string + { + return $this->username; + } + + /** + * Return the Domain part for the e-mail address. + * + * @since 1.0.0 + * @return string + */ + public function domain(): string + { + return $this->domain; + } + + /** + * Return the Top Level Domain part for the e-mail address. + * + * @since 1.0.0 + * @return string + */ + public function tld(): string + { + return $this->tld; + } +} diff --git a/tests/AbstractBaseTestCase.php b/tests/AbstractBaseTestCase.php index 9ef22bd..3d96bda 100644 --- a/tests/AbstractBaseTestCase.php +++ b/tests/AbstractBaseTestCase.php @@ -1,4 +1,5 @@ - - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ abstract class AbstractBaseTestCase extends TestCase { diff --git a/tests/Unit/Scalar/ImmutableStringTest.php b/tests/Unit/Scalar/ImmutableStringTest.php index 6339f6c..5ba77f3 100644 --- a/tests/Unit/Scalar/ImmutableStringTest.php +++ b/tests/Unit/Scalar/ImmutableStringTest.php @@ -1,4 +1,5 @@ -ImmutableString and MutableString classes have similar behavior, therefore, + * ImmutableString and MutableString classes have similar behavior, therefore, * you should extend this test case for the other type of String, overriding only the necessary * tests, which shouldn't be too many. * * This way, we can test both types of objects, without repeating the same code/tests. * * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ class ImmutableStringTest extends AbstractBaseTestCase { @@ -31,7 +29,6 @@ class ImmutableStringTest extends AbstractBaseTestCase * @param AbstractReadString $original - Original String instance. * @param AbstractReadString $other - Second instance for comparison. * - * @since 1.0.0 * @return void */ protected function checkInstances(AbstractReadString $original, AbstractReadString $other): void @@ -47,7 +44,6 @@ protected function checkInstances(AbstractReadString $original, AbstractReadStri * * @param AbstractReadString $instance - Instance to be validated. * - * @since 1.0.0 * @return void */ protected function checkCorrectInstanceType(AbstractReadString $instance): void @@ -66,7 +62,6 @@ protected function checkCorrectInstanceType(AbstractReadString $instance): void * * @param string $initialValue - Instance's initial value. * - * @since 1.0.0 * @return ImmutableString */ protected function initializeInstance(string $initialValue) @@ -77,7 +72,6 @@ protected function initializeInstance(string $initialValue) /** * Checks instance can be cloned. * - * @since 1.0.0 * @return void */ public function testCanCloneObject(): void @@ -103,7 +97,6 @@ public function testCanCloneObject(): void /** * Tests that a string can be trimmed. * - * @since 1.0.0 * @return void */ public function testCanTrimString(): void @@ -125,7 +118,6 @@ public function testCanTrimString(): void /** * Tests that a string can be trimmed only on the left. * - * @since 1.0.0 * @return void */ public function testCanLeftTrimString(): void @@ -147,7 +139,6 @@ public function testCanLeftTrimString(): void /** * Tests that a string can be trimmed only on the right. * - * @since 1.0.0 * @return void */ public function testCanRightTrimString(): void @@ -169,7 +160,6 @@ public function testCanRightTrimString(): void /** * Tests that a string can be converted to UPPER case. * - * @since 1.0.0 * @return void */ public function testCanUpperCaseString(): void @@ -191,7 +181,6 @@ public function testCanUpperCaseString(): void /** * Tests that a string can be converted to UPPER case. * - * @since 1.0.0 * @return void */ public function testCanUpperCaseFirst(): void @@ -213,7 +202,6 @@ public function testCanUpperCaseFirst(): void /** * Tests that a string can be convert to UPPER case, all words. * - * @since 1.0.0 * @return void */ public function testCanUpperCaseWords(): void @@ -235,7 +223,6 @@ public function testCanUpperCaseWords(): void /** * Tests that a string can be converted to LOWER case. * - * @since 1.0.0 * @return void */ public function testCanLowerCaseString(): void @@ -257,7 +244,6 @@ public function testCanLowerCaseString(): void /** * Tests that a string can be converted to LOWER case. * - * @since 1.0.0 * @return void */ public function testCanLowerCaseFirst(): void @@ -279,7 +265,6 @@ public function testCanLowerCaseFirst(): void /** * Tests that a string can be padded on the left. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheLeft(): void @@ -302,7 +287,6 @@ public function testCanPadOnTheLeft(): void /** * Tests that a string is not padded on the left, when the padding length is less than the string's length. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheLeftWithoutResult(): void @@ -325,7 +309,6 @@ public function testCanPadOnTheLeftWithoutResult(): void /** * Tests that a string can be padded on the left. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheLeftExtra(): void @@ -348,7 +331,6 @@ public function testCanPadOnTheLeftExtra(): void /** * Tests that padding breaks. * - * @since 1.0.0 * @return void */ public function testCanPaddingOnTheLeftBreaksWithInvalidLength(): void @@ -364,7 +346,6 @@ public function testCanPaddingOnTheLeftBreaksWithInvalidLength(): void /** * Tests that padding breaks. * - * @since 1.0.0 * @return void */ public function testCanPaddingOnTheLeftBreaksWithInvalidPadString(): void @@ -380,7 +361,6 @@ public function testCanPaddingOnTheLeftBreaksWithInvalidPadString(): void /** * Tests that padding breaks. * - * @since 1.0.0 * @return void */ public function testCanPaddingOnTheLeftExtraBreaksWithInvalidLength(): void @@ -396,7 +376,6 @@ public function testCanPaddingOnTheLeftExtraBreaksWithInvalidLength(): void /** * Tests that padding breaks. * - * @since 1.0.0 * @return void */ public function testCanPaddingOnTheLeftExtraBreaksWithInvalidPadString(): void @@ -412,7 +391,6 @@ public function testCanPaddingOnTheLeftExtraBreaksWithInvalidPadString(): void /** * Tests that a string can be padded on the left. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheLeftWidthCharacter(): void @@ -435,7 +413,6 @@ public function testCanPadOnTheLeftWidthCharacter(): void /** * Tests that a string can be padded on the left. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheLeftExtraWidthCharacter(): void @@ -458,7 +435,6 @@ public function testCanPadOnTheLeftExtraWidthCharacter(): void /** * Tests that a string can be padded on the right. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheRight(): void @@ -481,7 +457,6 @@ public function testCanPadOnTheRight(): void /** * Tests that a string can be padded on the right. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheRightExtra(): void @@ -504,7 +479,6 @@ public function testCanPadOnTheRightExtra(): void /** * Tests that padding breaks. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheRightBreaksWithInvalidLength(): void @@ -520,7 +494,6 @@ public function testCanPadOnTheRightBreaksWithInvalidLength(): void /** * Tests that padding breaks. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheRightBreaksWithInvalidPadString(): void @@ -536,7 +509,6 @@ public function testCanPadOnTheRightBreaksWithInvalidPadString(): void /** * Tests that padding breaks. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheRightExtraBreaksWithInvalidLength(): void @@ -552,7 +524,6 @@ public function testCanPadOnTheRightExtraBreaksWithInvalidLength(): void /** * Tests that padding breaks. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheRightExtraBreaksWithInvalidPadString(): void @@ -568,7 +539,6 @@ public function testCanPadOnTheRightExtraBreaksWithInvalidPadString(): void /** * Tests that a string can be padded on the right. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheRightWidthCharacter(): void @@ -591,7 +561,6 @@ public function testCanPadOnTheRightWidthCharacter(): void /** * Tests that a string can be padded on the right. * - * @since 1.0.0 * @return void */ public function testCanPadOnTheRightExtraWidthCharacter(): void @@ -614,7 +583,6 @@ public function testCanPadOnTheRightExtraWidthCharacter(): void /** * Tests that a simple substring can be retrieved. * - * @since 1.0.0 * @return void */ public function testSubStringCanBeRetrieved(): void @@ -636,7 +604,6 @@ public function testSubStringCanBeRetrieved(): void /** * Tests that a simple substring can be retrieved. * - * @since 1.0.0 * @return void */ public function testSubStringCanBeRetrievedWithNegativeStart(): void @@ -658,7 +625,6 @@ public function testSubStringCanBeRetrievedWithNegativeStart(): void /** * Tests that a simple substring can be retrieved. * - * @since 1.0.0 * @return void */ public function testSubStringCanBeRetrievedWithLength(): void @@ -680,7 +646,6 @@ public function testSubStringCanBeRetrievedWithLength(): void /** * Tests that a simple substring can be retrieved. * - * @since 1.0.0 * @return void */ public function testSubStringCanBeRetrievedWithNegativeLength(): void @@ -702,7 +667,6 @@ public function testSubStringCanBeRetrievedWithNegativeLength(): void /** * Tests that substring breaks. * - * @since 1.0.0 * @return void */ public function testSubStringBreaksWithShortStart(): void @@ -718,7 +682,6 @@ public function testSubStringBreaksWithShortStart(): void /** * Tests that substring breaks. * - * @since 1.0.0 * @return void */ public function testSubStringBreaksWithLongStart(): void @@ -734,7 +697,6 @@ public function testSubStringBreaksWithLongStart(): void /** * Tests that substring breaks. * - * @since 1.0.0 * @return void */ public function testSubStringBreaksWithShortLength(): void @@ -750,7 +712,6 @@ public function testSubStringBreaksWithShortLength(): void /** * Tests that substring breaks. * - * @since 1.0.0 * @return void */ public function testSubStringBreaksWithLongLength(): void @@ -766,7 +727,6 @@ public function testSubStringBreaksWithLongLength(): void /** * Tests that a simple subLeft can be retrieved. * - * @since 1.0.0 * @return void */ public function testSubStringLeftCanBeRetrieved(): void @@ -788,7 +748,6 @@ public function testSubStringLeftCanBeRetrieved(): void /** * Tests that subLeft() breaks. * - * @since 1.0.0 * @return void */ public function testSubStringLeftBreaksWithShortLength(): void @@ -804,7 +763,6 @@ public function testSubStringLeftBreaksWithShortLength(): void /** * Tests that subLeft() breaks. * - * @since 1.0.0 * @return void */ public function testSubStringLeftBreaksWithLongLength(): void @@ -820,7 +778,6 @@ public function testSubStringLeftBreaksWithLongLength(): void /** * Tests that a simple subRight() can be retrieved. * - * @since 1.0.0 * @return void */ public function testSubStringRightCanBeRetrieved(): void @@ -842,7 +799,6 @@ public function testSubStringRightCanBeRetrieved(): void /** * Tests that subRight() breaks. * - * @since 1.0.0 * @return void */ public function testSubStringRightBreaksWithShortLength(): void @@ -858,7 +814,6 @@ public function testSubStringRightBreaksWithShortLength(): void /** * Tests that subRight() breaks. * - * @since 1.0.0 * @return void */ public function testSubStringRightBreaksWithLongLength(): void @@ -874,7 +829,6 @@ public function testSubStringRightBreaksWithLongLength(): void /** * Tests that a string can be reversed. * - * @since 1.0.0 * @return void */ public function testStringCanBeReversed(): void @@ -896,7 +850,6 @@ public function testStringCanBeReversed(): void /** * Tests that text can be replaced in the String. * - * @since 1.0.0 * @return void */ public function testTextCanBeReplacedInString(): void @@ -918,7 +871,6 @@ public function testTextCanBeReplacedInString(): void /** * Tests that text is not replaced if search is not found. * - * @since 1.0.0 * @return void */ public function testTextIsNotReplacedIfSearchNotFound(): void @@ -940,7 +892,6 @@ public function testTextIsNotReplacedIfSearchNotFound(): void /** * Tests that text replace breaks. * - * @since 1.0.0 * @return void */ public function testTextReplaceBreaksIfSearchIsEmpty(): void diff --git a/tests/Unit/Scalar/MutableStringTest.php b/tests/Unit/Scalar/MutableStringTest.php index 38203ca..01fa378 100644 --- a/tests/Unit/Scalar/MutableStringTest.php +++ b/tests/Unit/Scalar/MutableStringTest.php @@ -1,4 +1,5 @@ -ImmutableString and MutableString classes have similar behavior, therefore, + * ImmutableString and MutableString classes have similar behavior, therefore, * this test case extends the parent for the other type of String, overriding only the necessary * tests, which shouldn't be too many. * * This way, we can testboth types of objects, without repeating the same code/tests. * * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ class MutableStringTest extends ImmutableStringTest { @@ -30,7 +28,6 @@ class MutableStringTest extends ImmutableStringTest * @param AbstractReadString $original - Original String instance. * @param AbstractReadString $other - Second instance for comparison. * - * @since 1.0.0 * @return void */ protected function checkInstances(AbstractReadString $original, AbstractReadString $other): void @@ -46,7 +43,6 @@ protected function checkInstances(AbstractReadString $original, AbstractReadStri * * @param AbstractReadString $instance - Instance to be validated. * - * @since 1.0.0 * @return void */ protected function checkCorrectInstanceType(AbstractReadString $instance): void @@ -65,7 +61,6 @@ protected function checkCorrectInstanceType(AbstractReadString $instance): void * * @param string $initialValue - Instance's initial value. * - * @since 1.0.0 * @return MutableString */ protected function initializeInstance(string $initialValue) @@ -76,7 +71,6 @@ protected function initializeInstance(string $initialValue) /** * Checks instance can be cloned. * - * @since 1.0.0 * @return void */ public function testCanCloneObject(): void diff --git a/tests/Unit/Scalar/ReadonlyStringTest.php b/tests/Unit/Scalar/ReadonlyStringTest.php index 3f46bbd..5027c79 100644 --- a/tests/Unit/Scalar/ReadonlyStringTest.php +++ b/tests/Unit/Scalar/ReadonlyStringTest.php @@ -1,4 +1,5 @@ - - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ class ReadonlyStringTest extends AbstractBaseTestCase { /** * Tests that a filled string can be loaded successfully. * - * @since 1.0.0 * @return void */ public function testCanSuccessfullyLoadFilledString(): void @@ -43,7 +40,6 @@ public function testCanSuccessfullyLoadFilledString(): void /** * Tests that an empty string can be loaded successfully. * - * @since 1.0.0 * @return void */ public function testCanSuccessfullyLoadEmptyString(): void @@ -67,7 +63,6 @@ public function testCanSuccessfullyLoadEmptyString(): void /** * Tests instance can be cloned. * - * @since 1.0.0 * @return void */ public function testCanCopyInstance(): void @@ -91,7 +86,6 @@ public function testCanCopyInstance(): void /** * Tests that equal strings are marked as equal. * - * @since 1.0.0 * @return void */ public function testCanCompareTwoStringsWithSameValue(): void @@ -111,7 +105,6 @@ public function testCanCompareTwoStringsWithSameValue(): void /** * Tests that different strings are not marked as equal. * - * @since 1.0.0 * @return void */ public function testCanCompareTwoStringsWithDifferentValue(): void @@ -131,7 +124,6 @@ public function testCanCompareTwoStringsWithDifferentValue(): void /** * Tests that the indexOf of a string works properly. * - * @since 1.0.0 * @return void */ public function testIndexOfStringRelatedFunctionality(): void @@ -189,7 +181,6 @@ public function testIndexOfStringRelatedFunctionality(): void /** * Tests that indexOf doesn't accept an empty search. * - * @since 1.0.0 * @return void */ public function testIndexOfBreaksWithEmptySearch(): void @@ -205,7 +196,6 @@ public function testIndexOfBreaksWithEmptySearch(): void /** * Tests that indexOf doesn't accept an illegal starting search. * - * @since 1.0.0 * @return void */ public function testIndexOfBreaksWithInvalidPositiveStart(): void @@ -221,7 +211,6 @@ public function testIndexOfBreaksWithInvalidPositiveStart(): void /** * Tests that indexOf doesn't accept an illegal starting search. * - * @since 1.0.0 * @return void */ public function testIndexOfBreaksWithInvalidNegativeStart(): void @@ -237,7 +226,6 @@ public function testIndexOfBreaksWithInvalidNegativeStart(): void /** * Tests that contains() breaks with an empty Search value. * - * @since 1.0.0 * @return void */ public function testContainsBreakWithEmptySearch(): void @@ -253,7 +241,6 @@ public function testContainsBreakWithEmptySearch(): void /** * Tests that startsWith() breaks with an empty Search value. * - * @since 1.0.0 * @return void */ public function testStartsWithBreakWithEmptySearch(): void @@ -269,7 +256,6 @@ public function testStartsWithBreakWithEmptySearch(): void /** * Tests that endsWith() breaks with an empty Search value. * - * @since 1.0.0 * @return void */ public function testEndsWithBreakWithEmptySearch(): void @@ -285,7 +271,6 @@ public function testEndsWithBreakWithEmptySearch(): void /** * Tests that the number of occurrences of a search, can be counted within the string. * - * @since 1.0.0 * @return void */ public function testCanCountNumberOfOccurrencesWithinString(): void @@ -340,7 +325,6 @@ public function testCanCountNumberOfOccurrencesWithinString(): void /** * Tests that count() breaks with an empty Search value. * - * @since 1.0.0 * @return void */ public function testCountBreakWithEmptySearch(): void @@ -356,7 +340,6 @@ public function testCountBreakWithEmptySearch(): void /** * Tests that count() breaks with long Start value. * - * @since 1.0.0 * @return void */ public function testCountBreaksWithLongStart(): void @@ -373,7 +356,6 @@ public function testCountBreaksWithLongStart(): void /** * Tests that count() breaks with long negative Start value. * - * @since 1.0.0 * @return void */ public function testCountBreaksWithLongNegativeStart(): void @@ -390,7 +372,6 @@ public function testCountBreaksWithLongNegativeStart(): void /** * Tests that count() breaks with long Length value. * - * @since 1.0.0 * @return void */ public function testCountBreaksWithLongLength(): void @@ -407,7 +388,6 @@ public function testCountBreaksWithLongLength(): void /** * Tests that count() breaks with long negative Length value. * - * @since 1.0.0 * @return void */ public function testCountBreaksWithLongNegativeLength(): void @@ -424,7 +404,6 @@ public function testCountBreaksWithLongNegativeLength(): void /** * Tests that count() breaks with out of scope Length value. * - * @since 1.0.0 * @return void */ public function testCountBreaksWithOutOfScopeLength(): void @@ -441,7 +420,6 @@ public function testCountBreaksWithOutOfScopeLength(): void /** * Tests that count() breaks with out of scope negative Length value. * - * @since 1.0.0 * @return void */ public function testCountBreaksWithOutOfScopeNegativeLength(): void diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2e46a13..8b2347b 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -5,10 +5,7 @@ * For Unit testing only, please link PHPUnit to this file. This file will autoload Composer's dependencies. * * @package Hradigital\Datatypes - * @copyright Hugo Rafael Azevedo - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ // Autoload Composer's dependencies, and Aesir-Base's namespace. From 2ba952bced482ce0e552cbaa6f456206a9a079d7 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 18:40:39 +0000 Subject: [PATCH 007/193] refactor: Remove deprecated production code --- src/Scalar/AbstractReadString.php | 240 ------------- src/Scalar/AbstractWriteString.php | 329 ----------------- src/Scalar/ReadonlyString.php | 30 -- tests/Unit/Scalar/ReadonlyStringTest.php | 435 ----------------------- 4 files changed, 1034 deletions(-) delete mode 100644 src/Scalar/AbstractReadString.php delete mode 100644 src/Scalar/AbstractWriteString.php delete mode 100644 src/Scalar/ReadonlyString.php delete mode 100644 tests/Unit/Scalar/ReadonlyStringTest.php diff --git a/src/Scalar/AbstractReadString.php b/src/Scalar/AbstractReadString.php deleted file mode 100644 index 607c8a2..0000000 --- a/src/Scalar/AbstractReadString.php +++ /dev/null @@ -1,240 +0,0 @@ -value = $value; - } - - /** - * Use this method to copy a child instance to a ReadonlyString instance, or just to clone a - * ReadonlyString. - * - * @return ReadonlyString - */ - public function toReadonly(): ReadonlyString - { - return new ReadonlyString( - $this->value - ); - } - - /** - * Magic method that will print out the native string representation of the instance. - * - * @return string - */ - public function __toString(): string - { - return $this->value; - } - - /** - * Compares the values of 2 separate instances. - * - * Returns TRUE if the 2 instance's values match. FALSE otherwise. - * - * @param ReadOnlyString $string - Another String instance to compare to. - * - * @return bool - */ - public function equals(ReadOnlyString $string): bool - { - return ($this->__toString() === $string->__toString()); - } - - /** - * Returns the instance's value character length. - * - * @return int - */ - public function length(): int - { - return \strlen($this->value); - } - - /** - * Searches and returns the index in the instance, of the $search string. - * - * If a $start is specified, search will start this number of characters counted from - * the beginning of the string. If $start is negative, the search will start this number - * of characters counted from the end of the string. - * - * If the $search is not found inthe instance's value, NULL is returned. - * - * @param string $search - String to search for in the instance. - * @param int $start - Search offset start. Defaults to NULL. - * - * @throws \InvalidArgumentException - If $search value is an empty string. - * @throws \OutOfRangeException - If the $start is either too small, or too long. - * @return int|NULL - */ - public function indexOf(string $search, int $start = null): ?int - { - // Validates supplied parameters. - if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); - } - if ($start) { - $this->validateStartAndLength($start, null); - } - - // Collects the string position. - $index = \strpos($this->value, $search, $start); - - // If false is returned, no index was found, and therefore NULL is returned. - if ($index === false) { - return null; - } - - return $index; - } - - /** - * Checks if the instance contains the supplied $search value. - * - * Returns TRUE if found. FALSE otherwise. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws \InvalidArgumentException - If supplied $search is empty. - * @return bool - */ - public function contains(string $search): bool - { - // Validates supplied parameter. - if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); - } - - return ($this->indexOf($search) !== null); - } - - /** - * Checks if the instance's value starts with the supplied string. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws \InvalidArgumentException - If supplied $search is empty. - * @return bool - */ - public function startsWith(string $search): bool - { - // Validates supplied parameter. - if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); - } - - return ($this->indexOf($search) === 0); - } - - /** - * Checks if the instance's value ends with the supplied string. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws \InvalidArgumentException - If supplied $search is empty. - * @return bool - */ - public function endsWith(string $search): bool - { - // Validates supplied parameter. - if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); - } - - return (\substr($this->value, (0 - \strlen($search))) === $search); - } - - /** - * Counts the number of substring occurrences in the instance's value. - * - * @param string $search - Non empty string to search for in the instance. - * @param int $start - The sub-string's offset/start. - * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. - * - * @throws \InvalidArgumentException - If supplied $search is empty. - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return int - */ - public function count(string $search, int $start = 0, int $length = null): int - { - // Validates supplied $search parameter. - if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); - } - - // Validates supplied $start and $length. - $this->validateStartAndLength($start, $length); - - // Checks if $length was defined. - if ($length) { - return \substr_count($this->value, $search, $start, $length); - } - - return \substr_count($this->value, $search, $start); - } - - /** - * Validates a character $length, based on the instance value's length, and supplied $start. - * - * @param int $start - The sub-string's offset/start. - * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. - * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return void - */ - protected function validateStartAndLength(int $start, ?int $length): void - { - // Calculates the absolute values for validations. - $absStart = (int) \abs($start); - $absLength = (int) \abs($length); - - // Validates the starting value. - if ($absStart > $this->length()) { - throw new \OutOfRangeException( - "The Start's absolute value must be less than the total number of characters in the string." - ); - } - - // If supplied $length is NULL, no further validations are required. - if ($length === null) { - return; - } - - // Checks if the supplied $length, doesn't exceed the available number of characters. - if (($start >= 0 && ($this->length() - $start < $absLength)) || - ($start < 0 && $absLength > $absStart)) { - - throw new \OutOfRangeException( - "The Length's absolute value cannot be higher than the number of available characters." - ); - } - } -} diff --git a/src/Scalar/AbstractWriteString.php b/src/Scalar/AbstractWriteString.php deleted file mode 100644 index 64ac966..0000000 --- a/src/Scalar/AbstractWriteString.php +++ /dev/null @@ -1,329 +0,0 @@ -value); - } - - /** - * Left trims instance's value, and returns a new instance of the object. - * - * @return string - */ - protected function doTrimLeft(): string - { - return \ltrim($this->value); - } - - /** - * Right trims instance's value, and returns a new instance of the object. - * - * @return string - */ - protected function doTrimRight(): string - { - return \rtrim($this->value); - } - - /** - * Converts the instance's value to Upper Case, and returns a new instance of the object. - * - * @return string - */ - protected function doToUpper(): string - { - return \mb_strtoupper($this->value); - } - - /** - * Converts the instance's value first character to Upper Case, and returns a new instance - * of the object. - * - * @return string - */ - protected function doToUpperFirst(): string - { - return \ucfirst($this->value); - } - - /** - * Converts the instance's value first character of each word to Upper Case, and returns a new instance - * of the object. - * - * @param string $delimiters - The optional delimiters contains the word separator characters. - * - * @return string - */ - protected function doToUpperWords(string $delimiters = " \t\r\n\f\v"): string - { - return \ucwords($this->value, $delimiters); - } - - /** - * Converts the instance's value to Lower Case, and returns a new instance of the object. - * - * @return string - */ - protected function doToLower(): string - { - return \mb_strtolower($this->value); - } - - /** - * Converts the instance's value first character to Lower Case, and returns a new instance - * of the object - * - * @return string - */ - protected function doToLowerFirst(): string - { - return \lcfirst($this->value); - } - - /** - * This method returns a new instance padded on the LEFT to the specified padding length minus - * the length of the instance's value. - * - * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will - * only be padded by the value of 2. - * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. - * - * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return string - */ - protected function doPadLeft(int $length, string $padding = " "): string - { - // Validates supplied parameters. - if ($length < 1) { - throw new \InvalidArgumentException("Supplied Length must be a positive integer."); - } - if (\strlen($padding) === 0) { - throw new \InvalidArgumentException("Supplied padding must be a non empty string."); - } - - return \str_pad($this->value, $length, $padding, STR_PAD_LEFT); - } - - /** - * This method returns a new instance padded on the LEFT, exactly to the specified padding length. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return string - */ - protected function doPadLeftExtra(int $length, string $padding = " "): string - { - // Validates supplied parameters. - if ($length < 1) { - throw new \InvalidArgumentException("Supplied Length must be a positive integer."); - } - if (\strlen($padding) === 0) { - throw new \InvalidArgumentException("Supplied padding must be a non empty string."); - } - - return \str_pad($this->value, ($this->length() + $length), $padding, STR_PAD_LEFT); - } - - /** - * This method returns a new instance padded on the RIGHT to the specified padding length minus - * the length of the instance's value. - * - * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will - * only be padded by the value of 2. - * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return string - */ - protected function doPadRight(int $length, string $padding = " "): string - { - // Validates supplied parameters. - if ($length < 1) { - throw new \InvalidArgumentException("Supplied Length must be a positive integer."); - } - if (\strlen($padding) === 0) { - throw new \InvalidArgumentException("Supplied padding must be a non empty string."); - } - - return \str_pad($this->value, $length, $padding, STR_PAD_RIGHT); - } - - /** - * This method returns a new instance padded on the RIGHT, exactly to the specified padding length. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return string - */ - protected function doPadRightExtra(int $length, string $padding = " "): string - { - // Validates supplied parameters. - if ($length < 1) { - throw new \InvalidArgumentException("Supplied Length must be a positive integer."); - } - if (\strlen($padding) === 0) { - throw new \InvalidArgumentException("Supplied padding must be a non empty string."); - } - - return \str_pad($this->value, ($this->length() + $length), $padding, STR_PAD_RIGHT); - } - - /** - * This method returns a new instance with a portion of the original instance's value, specified by the - * $start and $length parameters. - * - * $start parameter: - * - If $start is non-negative, the returned an instance will start at the $start'th position in - * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the - * character at position 2 is 'c', and so forth. - * - If $start is negative, the returned string will start at the $start'th character from the end - * of string. - * - If the absolute value of $start is higher than the instance's length, an - * exception is thrown. - * - * - * $length parameter: - * - If $length is given and is positive, the string returned will contain at most length characters - * beginning from $start (depending on the length of string). - * - If $length is given and is negative, then that many characters will be omitted from the end of string - * (after the start position has been calculated when a start is negative). - * - If $length exceeds the remaining number of characters, after the $start calculation, an - * Exception will be raised. - * - * - * @param int $start - Start of the sub-string. Can be negative. - * @param int $length - Length of the sub-string. Can be negative. - * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return string - */ - protected function doSubString(int $start, int $length = null): string - { - // Validates supplied $start and $length. - $this->validateStartAndLength($start, $length); - - // Processes the substring. - if ($length !== null) { - $value = \substr($this->value, $start, $length); - } else { - $value = \substr($this->value, $start); - } - - return ($value ?? ''); - } - - /** - * This method returns a new instance with a portion of the original instance's value, starting at the beginning - * of the value, with the number of characters specified in the $length parameter. - * - * Same rules as ImmutableString::subString() are applied. - * - * @param int $length - Length of the sub-string. Must be positive. - * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * @return string - */ - protected function doSubLeft(int $length): string - { - // Validates parameter. - if ($length < 1) { - throw new \InvalidArgumentException("Supplied length must be a positive integer."); - } - - return $this->doSubString(0, $length); - } - - /** - * This method returns a new instance with a portion of the original instance's value, couting from the end - * of the value, with the number of characters specified in the $length parameter. - * - * Same rules as ImmutableString::subString() are applied. - * - * @param int $length - Length of the sub-string. Must be positive. - * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * @return string - */ - protected function doSubRight(int $length): string - { - // Validates parameter. - if ($length < 1) { - throw new \InvalidArgumentException("Supplied length must be a positive integer."); - } - - return $this->doSubString(0 - $length); - } - - /** - * This method returns a new instance with the reversed value of the original instance. - * - * @return string - */ - protected function doReverse(): string - { - return \strrev($this->value); - } - - /** - * This method replaces a string's occurance by another, and returns a new instance with the new value. - * - * @param string $search - The string to search for. - * @param string $replace - The search's replacement. - * - * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. - * @return string - */ - protected function doReplace(string $search, string $replace): string - { - // Validates supplied parameters. - if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); - } - - return \str_replace($search, $replace, $this->value); - } -} diff --git a/src/Scalar/ReadonlyString.php b/src/Scalar/ReadonlyString.php deleted file mode 100644 index c4244e6..0000000 --- a/src/Scalar/ReadonlyString.php +++ /dev/null @@ -1,30 +0,0 @@ -assertEquals( - $test, - $value->__toString(), - 'String value does not seam to match.' - ); - $this->assertEquals( - \strlen($test), - $value->length(), - 'String length does not seam to match.' - ); - } - - /** - * Tests that an empty string can be loaded successfully. - * - * @return void - */ - public function testCanSuccessfullyLoadEmptyString(): void - { - // Performs test. - $value = ReadonlyString::fromString(""); - - // Performs assertions. - $this->assertEquals( - "", - $value->__toString(), - 'String value does not seam to match.' - ); - $this->assertEquals( - 0, - $value->length(), - 'String length does not seam to match.' - ); - } - - /** - * Tests instance can be cloned. - * - * @return void - */ - public function testCanCopyInstance(): void - { - // Performs test. - $test = "This is a Testing String"; - $value1 = ReadonlyString::fromString($test); - $value2 = $value1->toReadonly(); - - // Performs assertions. - $this->assertTrue( - ($value1->__toString() === $value2->__toString()), - "Instance's values should have been equal." - ); - $this->assertFalse( - ($value1 === $value2), - "Instances should not have been the same." - ); - } - - /** - * Tests that equal strings are marked as equal. - * - * @return void - */ - public function testCanCompareTwoStringsWithSameValue(): void - { - // Performs test. - $text = "This is a dummy string."; - $value1 = ReadonlyString::fromString($text); - $value2 = ReadonlyString::fromString($text); - - // Performs assertions. - $this->assertTrue( - $value1->equals($value2), - 'Both strings should have matched.' - ); - } - - /** - * Tests that different strings are not marked as equal. - * - * @return void - */ - public function testCanCompareTwoStringsWithDifferentValue(): void - { - // Performs test. - $text = "This is a dummy string."; - $value1 = ReadonlyString::fromString($text); - $value2 = ReadonlyString::fromString($text . $text); - - // Performs assertions. - $this->assertFalse( - $value1->equals($value2), - 'Strings should not have matched.' - ); - } - - /** - * Tests that the indexOf of a string works properly. - * - * @return void - */ - public function testIndexOfStringRelatedFunctionality(): void - { - // Performs test. - $text = "This is a dummy string."; - $value = ReadonlyString::fromString($text); - - // Performs assertions. - $this->assertEquals( - 10, - $value->indexOf("dummy"), - 'String index does not match.' - ); - $this->assertEquals( - 10, - $value->indexOf("dummy", -14), - 'String index does not match.' - ); - $this->assertEquals( - 5, - $value->indexOf("is", 4), - 'String index does not match.' - ); - $this->assertNull( - $value->indexOf("another"), - 'indexOf should have returned NULL.' - ); - $this->assertTrue( - $value->contains("is"), - 'String should have contained search.' - ); - $this->assertFalse( - $value->contains("another"), - 'String should not have contained search.' - ); - $this->assertTrue( - $value->startsWith("This"), - 'String should have started with search.' - ); - $this->assertFalse( - $value->startsWith("is"), - 'String should not have started with search.' - ); - $this->assertTrue( - $value->endsWith("string."), - 'String should have ended with search.' - ); - $this->assertFalse( - $value->endsWith("dummy"), - 'String should not have ended with search.' - ); - } - - /** - * Tests that indexOf doesn't accept an empty search. - * - * @return void - */ - public function testIndexOfBreaksWithEmptySearch(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $value = ReadonlyString::fromString("This is a dummy string."); - $value->indexOf(""); - } - - /** - * Tests that indexOf doesn't accept an illegal starting search. - * - * @return void - */ - public function testIndexOfBreaksWithInvalidPositiveStart(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $value = ReadonlyString::fromString("This is a dummy string."); - $value->indexOf("dummy", 30); - } - - /** - * Tests that indexOf doesn't accept an illegal starting search. - * - * @return void - */ - public function testIndexOfBreaksWithInvalidNegativeStart(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $value = ReadonlyString::fromString("This is a dummy string."); - $value->indexOf("dummy", -30); - } - - /** - * Tests that contains() breaks with an empty Search value. - * - * @return void - */ - public function testContainsBreakWithEmptySearch(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $value = ReadonlyString::fromString("This is a dummy string."); - $value->contains(""); - } - - /** - * Tests that startsWith() breaks with an empty Search value. - * - * @return void - */ - public function testStartsWithBreakWithEmptySearch(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $value = ReadonlyString::fromString("This is a dummy string."); - $value->startsWith(""); - } - - /** - * Tests that endsWith() breaks with an empty Search value. - * - * @return void - */ - public function testEndsWithBreakWithEmptySearch(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $value = ReadonlyString::fromString("This is a dummy string."); - $value->endsWith(""); - } - - /** - * Tests that the number of occurrences of a search, can be counted within the string. - * - * @return void - */ - public function testCanCountNumberOfOccurrencesWithinString(): void - { - // Performs test. - $text = "This is a dummy string."; - $value = ReadonlyString::fromString($text); - - // Performs assertions. - $this->assertEquals( - 0, - $value->count("none"), - "String count for 'none' does not match." - ); - $this->assertEquals( - 1, - $value->count("dummy"), - "String count for 'dummy' does not match." - ); - $this->assertEquals( - 2, - $value->count("is"), - "String count for 'is' does not match." - ); - $this->assertEquals( - 1, - $value->count("is", 4), - "String count for 'is' does not match." - ); - $this->assertEquals( - 0, - $value->count("This", 4, 5), - "String count for 'This' does not match." - ); - $this->assertEquals( - 1, - $value->count("string", -8), - "String count for 'string' does not match." - ); - $this->assertEquals( - 1, - $value->count("dummy", -14, 6), - "String count for 'dummy' does not match." - ); - $this->assertEquals( - 1, - $value->count("dummy", -14, -2), - "String count for 'dummy' does not match." - ); - } - - /** - * Tests that count() breaks with an empty Search value. - * - * @return void - */ - public function testCountBreakWithEmptySearch(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $value = ReadonlyString::fromString("This is a dummy string."); - $value->count(""); - } - - /** - * Tests that count() breaks with long Start value. - * - * @return void - */ - public function testCountBreaksWithLongStart(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $text = "This is a dummy string."; - $value = ReadonlyString::fromString($text); - $value->count("search", (\strlen($text) + 1)); - } - - /** - * Tests that count() breaks with long negative Start value. - * - * @return void - */ - public function testCountBreaksWithLongNegativeStart(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $text = "This is a dummy string."; - $value = ReadonlyString::fromString($text); - $value->count("search", (0 - \strlen($text) - 1)); - } - - /** - * Tests that count() breaks with long Length value. - * - * @return void - */ - public function testCountBreaksWithLongLength(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $text = "This is a dummy string."; - $value = ReadonlyString::fromString($text); - $value->count("search", 0, (\strlen($text) + 1)); - } - - /** - * Tests that count() breaks with long negative Length value. - * - * @return void - */ - public function testCountBreaksWithLongNegativeLength(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $text = "This is a dummy string."; - $value = ReadonlyString::fromString($text); - $value->count("search", 0, (0 - \strlen($text) - 1)); - } - - /** - * Tests that count() breaks with out of scope Length value. - * - * @return void - */ - public function testCountBreaksWithOutOfScopeLength(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $text = "This is a dummy string."; - $value = ReadonlyString::fromString($text); - $value->count("search", -5, 6); - } - - /** - * Tests that count() breaks with out of scope negative Length value. - * - * @return void - */ - public function testCountBreaksWithOutOfScopeNegativeLength(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $text = "This is a dummy string."; - $value = ReadonlyString::fromString($text); - $value->count("search", -5, -6); - } -} From 597645c5ccfa87b315b95d8dbeef1d6d90c80baa Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 18:41:10 +0000 Subject: [PATCH 008/193] feat: Add new String Base class --- src/Scalar/AbstractBaseString.php | 557 ++++++++++++++++++++++++++++++ 1 file changed, 557 insertions(+) create mode 100644 src/Scalar/AbstractBaseString.php diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php new file mode 100644 index 0000000..2f55f09 --- /dev/null +++ b/src/Scalar/AbstractBaseString.php @@ -0,0 +1,557 @@ +value = $value; + } + + /** + * Magic method that will print out the native string representation of the instance. + * + * @return string + */ + public function __toString(): string + { + return $this->value; + } + + /** + * Compares the values of 2 separate instances. + * + * Returns TRUE if the 2 instance's values match. FALSE otherwise. + * + * @param AbstractBaseString $string - Another String instance to compare to. + * + * @return bool + */ + public function equals(AbstractBaseString $string): bool + { + return ($this->__toString() === $string->__toString()); + } + + /** + * Checks if the instance contains the supplied $search value. + * + * Returns TRUE if found. FALSE otherwise. + * + * @param string $search - Non empty string to search for in the instance. + * + * @throws \InvalidArgumentException - If supplied $search is empty. + * @return bool + */ + public function contains(string $search): bool + { + // Validates supplied parameter. + if (\strlen($search) === 0) { + throw new \InvalidArgumentException("Supplied search must be a non empty string."); + } + + return ($this->indexOf($search) !== null); + } + + /** + * Returns the instance's value character length. + * + * @return int + */ + public function length(): int + { + return \strlen($this->value); + } + + /** + * Searches and returns the index in the instance, of the $search string. + * + * If a $start is specified, search will start this number of characters counted from + * the beginning of the string. If $start is negative, the search will start this number + * of characters counted from the end of the string. + * + * If the $search is not found inthe instance's value, NULL is returned. + * + * @param string $search - String to search for in the instance. + * @param int $start - Search offset start. Defaults to NULL. + * + * @throws \InvalidArgumentException - If $search value is an empty string. + * @throws \OutOfRangeException - If the $start is either too small, or too long. + * @return int|NULL + */ + public function indexOf(string $search, int $start = null): ?int + { + // Validates supplied parameters. + if (\strlen($search) === 0) { + throw new \InvalidArgumentException("Supplied search must be a non empty string."); + } + if ($start) { + $this->validateStartAndLength($start, null); + } + + // Collects the string position. + $index = \strpos($this->value, $search, $start); + + // If false is returned, no index was found, and therefore NULL is returned. + if ($index === false) { + return null; + } + + return $index; + } + + /** + * Checks if the instance's value starts with the supplied string. + * + * @param string $search - Non empty string to search for in the instance. + * + * @throws \InvalidArgumentException - If supplied $search is empty. + * @return bool + */ + public function startsWith(string $search): bool + { + // Validates supplied parameter. + if (\strlen($search) === 0) { + throw new \InvalidArgumentException("Supplied search must be a non empty string."); + } + + return ($this->indexOf($search) === 0); + } + + /** + * Checks if the instance's value ends with the supplied string. + * + * @param string $search - Non empty string to search for in the instance. + * + * @throws \InvalidArgumentException - If supplied $search is empty. + * @return bool + */ + public function endsWith(string $search): bool + { + // Validates supplied parameter. + if (\strlen($search) === 0) { + throw new \InvalidArgumentException("Supplied search must be a non empty string."); + } + + return (\substr($this->value, (0 - \strlen($search))) === $search); + } + + /** + * Counts the number of substring occurrences in the instance's value. + * + * @param string $search - Non empty string to search for in the instance. + * @param int $start - The sub-string's offset/start. + * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. + * + * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @return int + */ + public function count(string $search, int $start = 0, int $length = null): int + { + // Validates supplied $search parameter. + if (\strlen($search) === 0) { + throw new \InvalidArgumentException("Supplied search must be a non empty string."); + } + + // Validates supplied $start and $length. + $this->validateStartAndLength($start, $length); + + // Checks if $length was defined. + if ($length) { + return \substr_count($this->value, $search, $start, $length); + } + + return \substr_count($this->value, $search, $start); + } + + /** + * Validates a character $length, based on the instance value's length, and supplied $start. + * + * @param int $start - The sub-string's offset/start. + * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. + * + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @return void + */ + private function validateStartAndLength(int $start, ?int $length): void + { + // Calculates the absolute values for validations. + $absStart = (int) \abs($start); + $absLength = (int) \abs($length); + + // Validates the starting value. + if ($absStart > $this->length()) { + throw new \OutOfRangeException( + "The Start's absolute value must be less than the total number of characters in the string." + ); + } + + // If supplied $length is NULL, no further validations are required. + if ($length === null) { + return; + } + + // Checks if the supplied $length, doesn't exceed the available number of characters. + if (($start >= 0 && ($this->length() - $start < $absLength)) || + ($start < 0 && $absLength > $absStart)) { + + throw new \OutOfRangeException( + "The Length's absolute value cannot be higher than the number of available characters." + ); + } + } + + /** + * Trims instance's value, and returns a new instance of the object. + * + * @param string $value - String value to perform the operation on. + * + * @return string + */ + protected function doTrim(string $value): string + { + return \trim($value); + } + + /** + * Left trims instance's value, and returns a new instance of the object. + * + * @param string $value - String value to perform the operation on. + * + * @return string + */ + protected function doTrimLeft(string $value): string + { + return \ltrim($value); + } + + /** + * Right trims instance's value, and returns a new instance of the object. + * + * @param string $value - String value to perform the operation on. + * + * @return string + */ + protected function doTrimRight(string $value): string + { + return \rtrim($value); + } + + /** + * Converts the instance's value to Upper Case, and returns a new instance of the object. + * + * @param string $value - String value to perform the operation on. + * + * @return string + */ + protected function doToUpper(string $value): string + { + return \mb_strtoupper($value); + } + + /** + * Converts the instance's value first character to Upper Case, and returns a new instance + * of the object. + * + * @param string $value - String value to perform the operation on. + * + * @return string + */ + protected function doToUpperFirst(string $value): string + { + return \ucfirst($value); + } + + /** + * Converts the instance's value first character of each word to Upper Case, and returns a new instance + * of the object. + * + * @param string $value - String value to perform the operation on. + * @param string $delimiters - The optional delimiters contains the word separator characters. + * + * @return string + */ + protected function doToUpperWords(string $value, string $delimiters = " \t\r\n\f\v"): string + { + return \ucwords($value, $delimiters); + } + + /** + * Converts the instance's value to Lower Case, and returns a new instance of the object. + * + * @param string $value - String value to perform the operation on. + * + * @return string + */ + protected function doToLower(string $value): string + { + return \mb_strtolower($value); + } + + /** + * Converts the instance's value first character to Lower Case, and returns a new instance + * of the object + * + * @param string $value - String value to perform the operation on. + * + * @return string + */ + protected function doToLowerFirst(string $value): string + { + return \lcfirst($value); + } + + /** + * This method returns a new instance padded on the LEFT to the specified padding length minus + * the length of the instance's value. + * + * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will + * only be padded by the value of 2. + * + * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padString up to the limit. + * + * @param string $value - String value to perform the operation on. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padString's length. + * + * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @return string + */ + protected function doPadLeft(string $value, int $length, string $padding = " "): string + { + // Validates supplied parameters. + if ($length < 1) { + throw new \InvalidArgumentException("Supplied Length must be a positive integer."); + } + if (\strlen($padding) === 0) { + throw new \InvalidArgumentException("Supplied padding must be a non empty string."); + } + + return \str_pad($value, $length, $padding, STR_PAD_LEFT); + } + + /** + * This method returns a new instance padded on the LEFT, exactly to the specified padding length. + * + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. + * + * @param string $value - String value to perform the operation on. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. + * + * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @return string + */ + protected function doPadLeftExtra(string $value, int $length, string $padding = " "): string + { + // Validates supplied parameters. + if ($length < 1) { + throw new \InvalidArgumentException("Supplied Length must be a positive integer."); + } + if (\strlen($padding) === 0) { + throw new \InvalidArgumentException("Supplied padding must be a non empty string."); + } + + return \str_pad($value, (\strlen($value) + $length), $padding, STR_PAD_LEFT); + } + + /** + * This method returns a new instance padded on the RIGHT to the specified padding length minus + * the length of the instance's value. + * + * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will + * only be padded by the value of 2. + * + * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. + * + * @param string $value - String value to perform the operation on. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. + * + * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @return string + */ + protected function doPadRight(string $value, int $length, string $padding = " "): string + { + // Validates supplied parameters. + if ($length < 1) { + throw new \InvalidArgumentException("Supplied Length must be a positive integer."); + } + if (\strlen($padding) === 0) { + throw new \InvalidArgumentException("Supplied padding must be a non empty string."); + } + + return \str_pad($value, $length, $padding, STR_PAD_RIGHT); + } + + /** + * This method returns a new instance padded on the RIGHT, exactly to the specified padding length. + * + * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padding up to the limit. + * + * @param string $value - String value to perform the operation on. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. + * + * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @return string + */ + protected function doPadRightExtra(string $value, int $length, string $padding = " "): string + { + // Validates supplied parameters. + if ($length < 1) { + throw new \InvalidArgumentException("Supplied Length must be a positive integer."); + } + if (\strlen($padding) === 0) { + throw new \InvalidArgumentException("Supplied padding must be a non empty string."); + } + + return \str_pad($value, (\strlen($value) + $length), $padding, STR_PAD_RIGHT); + } + + /** + * This method returns a new instance with a portion of the original instance's value, specified by the + * $start and $length parameters. + * + * $start parameter: + * - If $start is non-negative, the returned an instance will start at the $start'th position in + * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the + * character at position 2 is 'c', and so forth. + * - If $start is negative, the returned string will start at the $start'th character from the end + * of string. + * - If the absolute value of $start is higher than the instance's length, an + * exception is thrown. + * + * + * $length parameter: + * - If $length is given and is positive, the string returned will contain at most length characters + * beginning from $start (depending on the length of string). + * - If $length is given and is negative, then that many characters will be omitted from the end of string + * (after the start position has been calculated when a start is negative). + * - If $length exceeds the remaining number of characters, after the $start calculation, an + * Exception will be raised. + * + * @param string $value - String value to perform the operation on. + * @param int $start - Start of the sub-string. Can be negative. + * @param int $length - Length of the sub-string. Can be negative. + * + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @return string + */ + protected function doSubString(string $value, int $start, int $length = null): string + { + // Validates supplied $start and $length. + $this->validateStartAndLength($start, $length); + + // Processes the substring. + if ($length !== null) { + $value = \substr($value, $start, $length); + } else { + $value = \substr($value, $start); + } + + return ($value ?? ''); + } + + /** + * This method returns a new instance with a portion of the original instance's value, starting at the beginning + * of the value, with the number of characters specified in the $length parameter. + * + * Same rules as ImmutableString::subString() are applied. + * + * @param string $value - String value to perform the operation on. + * @param int $length - Length of the sub-string. Must be positive. + * + * @throws \InvalidArgumentException - If supplied Length is not a positive integer. + * @return string + */ + protected function doSubLeft(string $value, int $length): string + { + // Validates parameter. + if ($length < 1) { + throw new \InvalidArgumentException("Supplied length must be a positive integer."); + } + + return $this->doSubString($value, 0, $length); + } + + /** + * This method returns a new instance with a portion of the original instance's value, couting from the end + * of the value, with the number of characters specified in the $length parameter. + * + * Same rules as ImmutableString::subString() are applied. + * + * @param string $value - String value to perform the operation on. + * @param int $length - Length of the sub-string. Must be positive. + * + * @throws \InvalidArgumentException - If supplied Length is not a positive integer. + * @return string + */ + protected function doSubRight($value, int $length): string + { + // Validates parameter. + if ($length < 1) { + throw new \InvalidArgumentException("Supplied length must be a positive integer."); + } + + return $this->doSubString($value, 0 - $length); + } + + /** + * This method returns a new instance with the reversed value of the original instance. + * + * @param string $value - String value to perform the operation on. + * + * @return string + */ + protected function doReverse(string $value): string + { + return \strrev($value); + } + + /** + * This method replaces a string's occurance by another, and returns a new instance with the new value. + * + * @param string $value - String value to perform the operation on. + * @param string $search - The string to search for. + * @param string $replace - The search's replacement. + * + * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. + * @return string + */ + protected function doReplace(string $value, string $search, string $replace): string + { + // Validates supplied parameters. + if (\strlen($search) === 0) { + throw new \InvalidArgumentException("Supplied search must be a non empty string."); + } + + return \str_replace($search, $replace, $value); + } +} From 9efb366cde583fa6241f5794cd1332c5962493d5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 1 Mar 2021 18:41:27 +0000 Subject: [PATCH 009/193] refactor: Adapted existing String classes --- src/Scalar/ImmutableString.php | 56 +++++++++++++--------------------- src/Scalar/MutableString.php | 39 ++++++++++++----------- 2 files changed, 41 insertions(+), 54 deletions(-) diff --git a/src/Scalar/ImmutableString.php b/src/Scalar/ImmutableString.php index 58c25d3..b882888 100644 --- a/src/Scalar/ImmutableString.php +++ b/src/Scalar/ImmutableString.php @@ -5,15 +5,15 @@ /** * Immutable String's Scalar Object class. * - * Instanciate this class, if you want the initial instance's value to be preserved, for example, if - * you're using it as a Value Object, in a DDD project. + * Instanciate this class, if you want the initial instance's value to be preserved. * - * Method chaning is not supported by any mutators. A new instance will be returned instead. + * Fluent interface (chaning) is not supported by any mutators. + * A new instance will be returned instead. * * @package Hradigital\Datatypes * @license MIT */ -class ImmutableString extends AbstractWriteString +class ImmutableString extends AbstractBaseString { /** * Creates a new instance of ImmutableString based on a string value. @@ -26,18 +26,6 @@ public static function fromString(string $value): ImmutableString return new ImmutableString($value); } - /** - * Clones this ImmutableString instance, into a MutableString one. - * - * @return MutableString - */ - public function toMutable(): MutableString - { - return MutableString::fromString( - $this->value - ); - } - /** * Trims instance's value, and returns a new instance of the object. * @@ -46,7 +34,7 @@ public function toMutable(): MutableString public function trim(): ImmutableString { return new ImmutableString( - parent::doTrim() + parent::doTrim($this->value) ); } @@ -58,7 +46,7 @@ public function trim(): ImmutableString public function trimLeft(): ImmutableString { return new ImmutableString( - parent::doTrimLeft() + parent::doTrimLeft($this->value) ); } @@ -70,7 +58,7 @@ public function trimLeft(): ImmutableString public function trimRight(): ImmutableString { return new ImmutableString( - parent::doTrimRight() + parent::doTrimRight($this->value) ); } @@ -82,7 +70,7 @@ public function trimRight(): ImmutableString public function toUpper(): ImmutableString { return new ImmutableString( - parent::doToUpper() + parent::doToUpper($this->value) ); } @@ -95,7 +83,7 @@ public function toUpper(): ImmutableString public function toUpperFirst(): ImmutableString { return new ImmutableString( - parent::doToUpperFirst() + parent::doToUpperFirst($this->value) ); } @@ -110,7 +98,7 @@ public function toUpperFirst(): ImmutableString public function toUpperWords(string $delimiters = " \t\r\n\f\v"): ImmutableString { return new ImmutableString( - parent::doToUpperWords($delimiters) + parent::doToUpperWords($this->value, $delimiters) ); } @@ -122,7 +110,7 @@ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): ImmutableStrin public function toLower(): ImmutableString { return new ImmutableString( - parent::doToLower() + parent::doToLower($this->value) ); } @@ -135,7 +123,7 @@ public function toLower(): ImmutableString public function toLowerFirst(): ImmutableString { return new ImmutableString( - parent::doToLowerFirst() + parent::doToLowerFirst($this->value) ); } @@ -155,7 +143,7 @@ public function toLowerFirst(): ImmutableString public function padLeft(int $length, string $padding = " "): ImmutableString { return new ImmutableString( - parent::doPadLeft($length, $padding) + parent::doPadLeft($this->value, $length, $padding) ); } @@ -175,7 +163,7 @@ public function padLeft(int $length, string $padding = " "): ImmutableString public function padLeftExtra(int $length, string $padding = " "): ImmutableString { return new ImmutableString( - parent::doPadLeftExtra($length, $padding) + parent::doPadLeftExtra($this->value, $length, $padding) ); } @@ -199,7 +187,7 @@ public function padLeftExtra(int $length, string $padding = " "): ImmutableStrin public function padRight(int $length, string $padding = " "): ImmutableString { return new ImmutableString( - parent::doPadRight($length, $padding) + parent::doPadRight($this->value, $length, $padding) ); } @@ -219,7 +207,7 @@ public function padRight(int $length, string $padding = " "): ImmutableString public function padRightExtra(int $length, string $padding = " "): ImmutableString { return new ImmutableString( - parent::doPadRightExtra($length, $padding) + parent::doPadRightExtra($this->value, $length, $padding) ); } @@ -228,7 +216,7 @@ public function padRightExtra(int $length, string $padding = " "): ImmutableStri * $start and $length parameters. * * $start parameter: - * -If $start is non-negative, the returned an instance will start at the $start'th position in + * - If $start is non-negative, the returned an instance will start at the $start'th position in * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the * character at position 2 is 'c', and so forth. * - If $start is negative, the returned string will start at the $start'th character from the end @@ -254,7 +242,7 @@ public function padRightExtra(int $length, string $padding = " "): ImmutableStri public function subString(int $start, int $length = null): ImmutableString { return new ImmutableString( - parent::doSubString($start, $length) + parent::doSubString($this->value, $start, $length) ); } @@ -272,7 +260,7 @@ public function subString(int $start, int $length = null): ImmutableString public function subLeft(int $length): ImmutableString { return new ImmutableString( - parent::doSubLeft($length) + parent::doSubLeft($this->value, $length) ); } @@ -290,7 +278,7 @@ public function subLeft(int $length): ImmutableString public function subRight(int $length): ImmutableString { return new ImmutableString( - parent::doSubRight($length) + parent::doSubRight($this->value, $length) ); } @@ -302,7 +290,7 @@ public function subRight(int $length): ImmutableString public function reverse(): ImmutableString { return new ImmutableString( - parent::doReverse() + parent::doReverse($this->value) ); } @@ -318,7 +306,7 @@ public function reverse(): ImmutableString public function replace(string $search, string $replace): ImmutableString { return new ImmutableString( - parent::doReplace($search, $replace) + parent::doReplace($this->value, $search, $replace) ); } } diff --git a/src/Scalar/MutableString.php b/src/Scalar/MutableString.php index 1539825..27c2c4d 100644 --- a/src/Scalar/MutableString.php +++ b/src/Scalar/MutableString.php @@ -9,13 +9,12 @@ * mutates during the instance's life. * * Any mutator call, will transform the instances internal value. Initial value will no longer be available. - * - * All mutator/setter methods in this class, support chaning. + * All mutator/setter methods in this class, have a fluent interface (method chaning). * * @package Hradigital\Datatypes * @license MIT */ -class MutableString extends AbstractWriteString +class MutableString extends AbstractBaseString { /** * Creates a new instance of MutableString based on a string value. @@ -49,7 +48,7 @@ public function toImmutable(): ImmutableString */ public function trim(): MutableString { - $this->value = parent::doTrim(); + $this->value = parent::doTrim($this->value); return $this; } @@ -63,7 +62,7 @@ public function trim(): MutableString */ public function trimLeft(): MutableString { - $this->value = parent::doTrimLeft(); + $this->value = parent::doTrimLeft($this->value); return $this; } @@ -77,7 +76,7 @@ public function trimLeft(): MutableString */ public function trimRight(): MutableString { - $this->value = parent::doTrimRight(); + $this->value = parent::doTrimRight($this->value); return $this; } @@ -91,7 +90,7 @@ public function trimRight(): MutableString */ public function toUpper(): MutableString { - $this->value = parent::doToUpper(); + $this->value = parent::doToUpper($this->value); return $this; } @@ -103,7 +102,7 @@ public function toUpper(): MutableString */ public function toUpperFirst(): MutableString { - $this->value = parent::doToUpperFirst(); + $this->value = parent::doToUpperFirst($this->value); return $this; } @@ -117,7 +116,7 @@ public function toUpperFirst(): MutableString */ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): MutableString { - $this->value = parent::doToUpperWords($delimiters); + $this->value = parent::doToUpperWords($this->value, $delimiters); return $this; } @@ -131,7 +130,7 @@ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): MutableString */ public function toLower(): MutableString { - $this->value = parent::doToLower(); + $this->value = parent::doToLower($this->value); return $this; } @@ -143,7 +142,7 @@ public function toLower(): MutableString */ public function toLowerFirst(): MutableString { - $this->value = parent::doToLowerFirst(); + $this->value = parent::doToLowerFirst($this->value); return $this; } @@ -169,7 +168,7 @@ public function toLowerFirst(): MutableString */ public function padLeft(int $length, string $padding = " "): MutableString { - $this->value = parent::doPadLeft($length, $padding); + $this->value = parent::doPadLeft($this->value, $length, $padding); return $this; } @@ -189,7 +188,7 @@ public function padLeft(int $length, string $padding = " "): MutableString */ public function padLeftExtra(int $length, string $padding = " "): MutableString { - $this->value = parent::doPadLeftExtra($length, $padding); + $this->value = parent::doPadLeftExtra($this->value, $length, $padding); return $this; } @@ -215,7 +214,7 @@ public function padLeftExtra(int $length, string $padding = " "): MutableString */ public function padRight(int $length, string $padding = " "): MutableString { - $this->value = parent::doPadRight($length, $padding); + $this->value = parent::doPadRight($this->value, $length, $padding); return $this; } @@ -235,7 +234,7 @@ public function padRight(int $length, string $padding = " "): MutableString */ public function padRightExtra(int $length, string $padding = " "): MutableString { - $this->value = parent::doPadRightExtra($length, $padding); + $this->value = parent::doPadRightExtra($this->value, $length, $padding); return $this; } @@ -271,7 +270,7 @@ public function padRightExtra(int $length, string $padding = " "): MutableString */ public function subString(int $start, int $length = null): MutableString { - $this->value = parent::doSubString($start, $length); + $this->value = parent::doSubString($this->value, $start, $length); return $this; } @@ -289,7 +288,7 @@ public function subString(int $start, int $length = null): MutableString */ public function subLeft(int $length): MutableString { - $this->value = parent::doSubLeft($length); + $this->value = parent::doSubLeft($this->value, $length); return $this; } @@ -307,7 +306,7 @@ public function subLeft(int $length): MutableString */ public function subRight(int $length): MutableString { - $this->value = parent::doSubRight($length); + $this->value = parent::doSubRight($this->value, $length); return $this; } @@ -319,7 +318,7 @@ public function subRight(int $length): MutableString */ public function reverse(): MutableString { - $this->value = parent::doReverse(); + $this->value = parent::doReverse($this->value); return $this; } @@ -335,7 +334,7 @@ public function reverse(): MutableString */ public function replace(string $search, string $replace): MutableString { - $this->value = parent::doReplace($search, $replace); + $this->value = parent::doReplace($this->value, $search, $replace); return $this; } From 022bf5faa2bb3b1bd663a166d594548e61443456 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 2 Mar 2021 12:49:01 +0000 Subject: [PATCH 010/193] feat: Add temporary development directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4f108ba..4b1abee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ ci/ vendor/ +notyetdeveloped/ .buildpath .project composer.lock From c1c332343368acec6ab29f2fe1fd1da5b266b6b5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 2 Mar 2021 12:49:33 +0000 Subject: [PATCH 011/193] build: Migrate PHPUnit's configuration to v9 --- phpunit.xml.dist | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c8fb2d6..968be3b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,24 +1,27 @@ - + + - - - tests/Unit - - + + + src + + - - - src - - + + + tests/Unit + + From 8e7630ae8dd6863b75cc9299bc2453cc3b8cf75e Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 17:33:14 +0000 Subject: [PATCH 012/193] refactor: Change default parameter value to Zero --- src/Scalar/AbstractBaseString.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 2f55f09..610afeb 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -90,13 +90,13 @@ public function length(): int * If the $search is not found inthe instance's value, NULL is returned. * * @param string $search - String to search for in the instance. - * @param int $start - Search offset start. Defaults to NULL. + * @param int $start - Search offset start. Defaults to ZERO. * * @throws \InvalidArgumentException - If $search value is an empty string. * @throws \OutOfRangeException - If the $start is either too small, or too long. * @return int|NULL */ - public function indexOf(string $search, int $start = null): ?int + public function indexOf(string $search, int $start = 0): ?int { // Validates supplied parameters. if (\strlen($search) === 0) { @@ -185,13 +185,13 @@ public function count(string $search, int $start = 0, int $length = null): int /** * Validates a character $length, based on the instance value's length, and supplied $start. * - * @param int $start - The sub-string's offset/start. - * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. + * @param int $start - The sub-string's offset/start. + * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. * * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return void */ - private function validateStartAndLength(int $start, ?int $length): void + protected function validateStartAndLength(int $start, ?int $length): void { // Calculates the absolute values for validations. $absStart = (int) \abs($start); From 79d431a52606e4d77f7f1d36b9489c9883de3d9d Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 17:33:49 +0000 Subject: [PATCH 013/193] tests: Adapt tests for String testing --- tests/Unit/Scalar/ImmutableStringTest.php | 157 +++++++++++++--------- tests/Unit/Scalar/MutableStringTest.php | 18 +-- 2 files changed, 102 insertions(+), 73 deletions(-) diff --git a/tests/Unit/Scalar/ImmutableStringTest.php b/tests/Unit/Scalar/ImmutableStringTest.php index 5ba77f3..350bd71 100644 --- a/tests/Unit/Scalar/ImmutableStringTest.php +++ b/tests/Unit/Scalar/ImmutableStringTest.php @@ -2,9 +2,8 @@ namespace Hradigital\Tests\Datatypes\Unit\Scalar; -use Hradigital\Datatypes\Scalar\AbstractReadString; +use Hradigital\Datatypes\Scalar\AbstractBaseString; use Hradigital\Datatypes\Scalar\ImmutableString; -use Hradigital\Datatypes\Scalar\MutableString; use Hradigital\Tests\Datatypes\AbstractBaseTestCase; /** @@ -26,12 +25,12 @@ class ImmutableStringTest extends AbstractBaseTestCase /** * Asserts that 2 string instances do not match. * - * @param AbstractReadString $original - Original String instance. - * @param AbstractReadString $other - Second instance for comparison. + * @param AbstractBaseString $original - Original String instance. + * @param AbstractBaseString $other - Second instance for comparison. * * @return void */ - protected function checkInstances(AbstractReadString $original, AbstractReadString $other): void + protected function checkInstances(AbstractBaseString $original, AbstractBaseString $other): void { $this->assertFalse( ($original === $other), @@ -42,11 +41,11 @@ protected function checkInstances(AbstractReadString $original, AbstractReadStri /** * Asserts that the supplied instance, is from the correct type. * - * @param AbstractReadString $instance - Instance to be validated. + * @param AbstractBaseString $instance - Instance to be validated. * * @return void */ - protected function checkCorrectInstanceType(AbstractReadString $instance): void + protected function checkCorrectInstanceType(AbstractBaseString $instance): void { $this->assertInstanceOf( ImmutableString::class, @@ -62,36 +61,66 @@ protected function checkCorrectInstanceType(AbstractReadString $instance): void * * @param string $initialValue - Instance's initial value. * - * @return ImmutableString + * @return AbstractBaseString */ - protected function initializeInstance(string $initialValue) + protected function getInstance(string $initialValue): AbstractBaseString { return ImmutableString::fromString($initialValue); } /** - * Checks instance can be cloned. + * Checks Equality of two distinct strings. * * @return void */ - public function testCanCloneObject(): void + public function testCanCheckEquality(): void { // Performs test. - $original = $this->initializeInstance("Immutable string."); - $other = $original->toMutable(); + $original = $this->getInstance(" Immutable string. "); + $other = $this->getInstance(" Immutable string. "); // Performs assertions. - $this->assertInstanceOf( - MutableString::class, - $other, - 'Instance type, does not match ImmutableString.' + $this->assertTrue( + $original->equals($other), + 'Instance values do not match.' ); - $this->assertEquals( - $original->__toString(), - $other->__toString(), + $this->checkCorrectInstanceType($original); + $this->checkCorrectInstanceType($other); + } + + /** + * Tests that we can check of String contains a text portion. + * + * @return void + */ + public function testCanCheckIfStringContainsPortion(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + + // Performs assertions. + $this->assertTrue( + $original->contains('muta'), 'Instance values do not match.' ); - $this->checkInstances($original, $other); + $this->checkCorrectInstanceType($original); + } + + /** + * Tests that method breaks if invalid parameters are passed. + * + * @return void + */ + public function testBreaksWhileCheckingIfStringContainsPortion(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + + // Create expectations. + $this->expectException(\InvalidArgumentException::class); + + // Performs test. + $original->contains(''); } /** @@ -102,7 +131,7 @@ public function testCanCloneObject(): void public function testCanTrimString(): void { // Performs test. - $original = $this->initializeInstance(" Immutable string. "); + $original = $this->getInstance(" Immutable string. "); $other = $original->trim(); // Performs assertions. @@ -123,7 +152,7 @@ public function testCanTrimString(): void public function testCanLeftTrimString(): void { // Performs test. - $original = $this->initializeInstance(" Immutable string. "); + $original = $this->getInstance(" Immutable string. "); $other = $original->trimLeft(); // Performs assertions. @@ -144,7 +173,7 @@ public function testCanLeftTrimString(): void public function testCanRightTrimString(): void { // Performs test. - $original = $this->initializeInstance(" Immutable string. "); + $original = $this->getInstance(" Immutable string. "); $other = $original->trimRight(); // Performs assertions. @@ -165,7 +194,7 @@ public function testCanRightTrimString(): void public function testCanUpperCaseString(): void { // Performs test. - $original = $this->initializeInstance("Immutable string."); + $original = $this->getInstance("Immutable string."); $other = $original->toUpper(); // Performs assertions. @@ -186,7 +215,7 @@ public function testCanUpperCaseString(): void public function testCanUpperCaseFirst(): void { // Performs test. - $original = $this->initializeInstance("immutable string."); + $original = $this->getInstance("immutable string."); $other = $original->toUpperFirst(); // Performs assertions. @@ -207,7 +236,7 @@ public function testCanUpperCaseFirst(): void public function testCanUpperCaseWords(): void { // Performs test. - $original = $this->initializeInstance("immutable string."); + $original = $this->getInstance("immutable string."); $other = $original->toUpperWords(); // Performs assertions. @@ -228,7 +257,7 @@ public function testCanUpperCaseWords(): void public function testCanLowerCaseString(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->toLower(); // Performs assertions. @@ -249,7 +278,7 @@ public function testCanLowerCaseString(): void public function testCanLowerCaseFirst(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->toLowerFirst(); // Performs assertions. @@ -271,7 +300,7 @@ public function testCanPadOnTheLeft(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padLeft(\strlen($string) + 2); // Performs assertions. @@ -293,7 +322,7 @@ public function testCanPadOnTheLeftWithoutResult(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padLeft(2); // Performs assertions. @@ -315,7 +344,7 @@ public function testCanPadOnTheLeftExtra(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padLeftExtra(2); // Performs assertions. @@ -339,7 +368,7 @@ public function testCanPaddingOnTheLeftBreaksWithInvalidLength(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->padLeft(0); } @@ -354,7 +383,7 @@ public function testCanPaddingOnTheLeftBreaksWithInvalidPadString(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->padLeft(2, ''); } @@ -369,7 +398,7 @@ public function testCanPaddingOnTheLeftExtraBreaksWithInvalidLength(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->padLeftExtra(0); } @@ -384,7 +413,7 @@ public function testCanPaddingOnTheLeftExtraBreaksWithInvalidPadString(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->padLeftExtra(2, ''); } @@ -397,7 +426,7 @@ public function testCanPadOnTheLeftWidthCharacter(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padLeft(\strlen($string) + 2, '_'); // Performs assertions. @@ -419,7 +448,7 @@ public function testCanPadOnTheLeftExtraWidthCharacter(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padLeftExtra(2, '_'); // Performs assertions. @@ -441,7 +470,7 @@ public function testCanPadOnTheRight(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padRight(\strlen($string) + 2); // Performs assertions. @@ -463,7 +492,7 @@ public function testCanPadOnTheRightExtra(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padRightExtra(2); // Performs assertions. @@ -487,7 +516,7 @@ public function testCanPadOnTheRightBreaksWithInvalidLength(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->padRight(0); } @@ -502,7 +531,7 @@ public function testCanPadOnTheRightBreaksWithInvalidPadString(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->padRight(2, ''); } @@ -517,7 +546,7 @@ public function testCanPadOnTheRightExtraBreaksWithInvalidLength(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->padRightExtra(0); } @@ -532,7 +561,7 @@ public function testCanPadOnTheRightExtraBreaksWithInvalidPadString(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->padRightExtra(2, ''); } @@ -545,7 +574,7 @@ public function testCanPadOnTheRightWidthCharacter(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padRight(\strlen($string) + 2, '_'); // Performs assertions. @@ -567,7 +596,7 @@ public function testCanPadOnTheRightExtraWidthCharacter(): void { // Performs test. $string = "Immutable String."; - $original = $this->initializeInstance($string); + $original = $this->getInstance($string); $other = $original->padRightExtra(2, '_'); // Performs assertions. @@ -588,7 +617,7 @@ public function testCanPadOnTheRightExtraWidthCharacter(): void public function testSubStringCanBeRetrieved(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->subString(10); // Performs assertions. @@ -609,7 +638,7 @@ public function testSubStringCanBeRetrieved(): void public function testSubStringCanBeRetrievedWithNegativeStart(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->subString(-7); // Performs assertions. @@ -630,7 +659,7 @@ public function testSubStringCanBeRetrievedWithNegativeStart(): void public function testSubStringCanBeRetrievedWithLength(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->subString(2, 7); // Performs assertions. @@ -651,7 +680,7 @@ public function testSubStringCanBeRetrievedWithLength(): void public function testSubStringCanBeRetrievedWithNegativeLength(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->subString(2, -8); // Performs assertions. @@ -675,7 +704,7 @@ public function testSubStringBreaksWithShortStart(): void $this->expectException(\OutOfRangeException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->subString(-30); } @@ -690,7 +719,7 @@ public function testSubStringBreaksWithLongStart(): void $this->expectException(\OutOfRangeException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->subString(30); } @@ -705,7 +734,7 @@ public function testSubStringBreaksWithShortLength(): void $this->expectException(\OutOfRangeException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->subString(0, -30); } @@ -720,7 +749,7 @@ public function testSubStringBreaksWithLongLength(): void $this->expectException(\OutOfRangeException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->subString(0, 30); } @@ -732,7 +761,7 @@ public function testSubStringBreaksWithLongLength(): void public function testSubStringLeftCanBeRetrieved(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->subLeft(10); // Performs assertions. @@ -756,7 +785,7 @@ public function testSubStringLeftBreaksWithShortLength(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->subLeft(-1); } @@ -771,7 +800,7 @@ public function testSubStringLeftBreaksWithLongLength(): void $this->expectException(\OutOfRangeException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->subLeft(30); } @@ -783,7 +812,7 @@ public function testSubStringLeftBreaksWithLongLength(): void public function testSubStringRightCanBeRetrieved(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->subRight(10); // Performs assertions. @@ -807,7 +836,7 @@ public function testSubStringRightBreaksWithShortLength(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->subRight(-1); } @@ -822,7 +851,7 @@ public function testSubStringRightBreaksWithLongLength(): void $this->expectException(\OutOfRangeException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->subRight(30); } @@ -834,7 +863,7 @@ public function testSubStringRightBreaksWithLongLength(): void public function testStringCanBeReversed(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->reverse(); // Performs assertions. @@ -855,7 +884,7 @@ public function testStringCanBeReversed(): void public function testTextCanBeReplacedInString(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->replace('String', 'Object'); // Performs assertions. @@ -876,7 +905,7 @@ public function testTextCanBeReplacedInString(): void public function testTextIsNotReplacedIfSearchNotFound(): void { // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $other = $original->replace('None', 'Object'); // Performs assertions. @@ -900,7 +929,7 @@ public function testTextReplaceBreaksIfSearchIsEmpty(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - $original = $this->initializeInstance("Immutable String."); + $original = $this->getInstance("Immutable String."); $original->replace('', 'Object'); } } diff --git a/tests/Unit/Scalar/MutableStringTest.php b/tests/Unit/Scalar/MutableStringTest.php index 01fa378..5663484 100644 --- a/tests/Unit/Scalar/MutableStringTest.php +++ b/tests/Unit/Scalar/MutableStringTest.php @@ -2,7 +2,7 @@ namespace Hradigital\Tests\Datatypes\Unit\Scalar; -use Hradigital\Datatypes\Scalar\AbstractReadString; +use Hradigital\Datatypes\Scalar\AbstractBaseString; use Hradigital\Datatypes\Scalar\ImmutableString; use Hradigital\Datatypes\Scalar\MutableString; @@ -25,12 +25,12 @@ class MutableStringTest extends ImmutableStringTest /** * Asserts that 2 string instances match. * - * @param AbstractReadString $original - Original String instance. - * @param AbstractReadString $other - Second instance for comparison. + * @param AbstractBaseString $original - Original String instance. + * @param AbstractBaseString $other - Second instance for comparison. * * @return void */ - protected function checkInstances(AbstractReadString $original, AbstractReadString $other): void + protected function checkInstances(AbstractBaseString $original, AbstractBaseString $other): void { $this->assertTrue( ($original === $other), @@ -41,11 +41,11 @@ protected function checkInstances(AbstractReadString $original, AbstractReadStri /** * Asserts that the supplied instance, is from the correct type. * - * @param AbstractReadString $instance - Instance to be validated. + * @param AbstractBaseString $instance - Instance to be validated. * * @return void */ - protected function checkCorrectInstanceType(AbstractReadString $instance): void + protected function checkCorrectInstanceType(AbstractBaseString $instance): void { $this->assertInstanceOf( MutableString::class, @@ -61,9 +61,9 @@ protected function checkCorrectInstanceType(AbstractReadString $instance): void * * @param string $initialValue - Instance's initial value. * - * @return MutableString + * @return AbstractBaseString */ - protected function initializeInstance(string $initialValue) + protected function getInstance(string $initialValue): AbstractBaseString { return MutableString::fromString($initialValue); } @@ -76,7 +76,7 @@ protected function initializeInstance(string $initialValue) public function testCanCloneObject(): void { // Performs test. - $original = $this->initializeInstance("Immutable string."); + $original = $this->getInstance("Immutable string."); $other = $original->toImmutable(); // Performs assertions. From cbe1cfe09b661842a3897f951d7572a19ec5c059 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 17:35:16 +0000 Subject: [PATCH 014/193] refactor: Adapt class to package's v2 --- src/Web/EmailAddress.php | 59 ++++++++++------------------------------ 1 file changed, 14 insertions(+), 45 deletions(-) diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 1b7a26f..49ffdeb 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -1,4 +1,5 @@ - - * @author Hugo Rafael Azevedo * @license MIT - * @since 1.0.0 */ class EmailAddress implements \Serializable { + /** @var string $username - Holds the Username's part of the E-mail address. */ + protected string $username; + + /** @var string $domain - Holds the Domain part of the E-mail address. */ + protected string $domain; + + /** @var string $tld - Holds the Top Level Domain part of the E-mail address. */ + protected string $tld; + /** * Loads a new EmailAddress instance from a native string. * * @param string $email - E-mail address used to initialize instance. * - * @since 1.0.0 * @return EmailAddress */ public function fromString(string $email): EmailAddress @@ -28,35 +34,17 @@ public function fromString(string $email): EmailAddress return new EmailAddress($email); } - /** - * @var string $username - Holds the Username's part of the E-mail address. - */ - protected $username = null; - - /** - * @var string $domain - Holds the Domain part of the E-mail address. - */ - protected $domain = null; - - /** - * @var string $tld - Holds the Top Level Domain part of the E-mail address. - */ - protected $tld = null; - /** * Initializes a new instance of an E-mail address. * * @param string $email - String representation of the e-mail address. * * @throws \InvalidArgumentException - If the supplied email address is empty or invalid. - * - * @since 1.0.0 * @return void */ protected function __construct(string $email) { - // Loads data into class. - $this->loadEmail($email); + $this->loadInitialState($email); } /** @@ -65,11 +53,9 @@ protected function __construct(string $email) * @param string $email - String representation of the e-mail. * * @throws \InvalidArgumentException - If the supplied email address is empty or invalid. - * - * @since 1.0.0 * @return void */ - private function loadEmail(string $email): void + private function loadInitialState(string $email): void { // Validate supplied parameter. if (\strlen(\trim($email)) === 0) { @@ -91,11 +77,6 @@ private function loadEmail(string $email): void } /** - * Serializes the contents of the class. - * - * @since 1.0.0 - * @return string - * * {@inheritDoc} * @see \Serializable::serialize() */ @@ -105,18 +86,12 @@ public function serialize() } /** - * Unserializes back the contents of the class. - * - * @since 1.0.0 - * @return void - * * {@inheritDoc} * @see \Serializable::unserialize() */ public function unserialize($serialized) { - // Loads unserialized data back to the class. - $this->loadEmail( + $this->loadInitialState( \unserialize($serialized) ); } @@ -124,8 +99,6 @@ public function unserialize($serialized) /** * Returns the String representation of the object. * - * @since 1.0.0 - * * @return string */ public function __toString(): string @@ -136,7 +109,6 @@ public function __toString(): string /** * Returns a string representation for the Email address. * - * @since 1.0.0 * @return string */ public function address(): string @@ -147,7 +119,6 @@ public function address(): string /** * Return the Username part for the e-mail address. * - * @since 1.0.0 * @return string */ public function username(): string @@ -158,7 +129,6 @@ public function username(): string /** * Return the Domain part for the e-mail address. * - * @since 1.0.0 * @return string */ public function domain(): string @@ -169,7 +139,6 @@ public function domain(): string /** * Return the Top Level Domain part for the e-mail address. * - * @since 1.0.0 * @return string */ public function tld(): string From b74ed6fdd56042e0add6d005bf65d8bb9491b197 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 17:45:16 +0000 Subject: [PATCH 015/193] fix: Change public method fromString() to static --- src/Web/EmailAddress.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 49ffdeb..4b861a8 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -29,7 +29,7 @@ class EmailAddress implements \Serializable * * @return EmailAddress */ - public function fromString(string $email): EmailAddress + public static function fromString(string $email): EmailAddress { return new EmailAddress($email); } From 093d0244e394dada62c938cee21e5285772d2f0c Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 18:02:16 +0000 Subject: [PATCH 016/193] test: Add test and code coverage for EmailAddress --- tests/Unit/Web/EmailAddressTest.php | 143 ++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 tests/Unit/Web/EmailAddressTest.php diff --git a/tests/Unit/Web/EmailAddressTest.php b/tests/Unit/Web/EmailAddressTest.php new file mode 100644 index 0000000..81e60f3 --- /dev/null +++ b/tests/Unit/Web/EmailAddressTest.php @@ -0,0 +1,143 @@ +assertInstanceOf( + EmailAddress::class, + $email, + 'Returned instance is not of type EmailAddress.' + ); + $this->assertEquals( + $emailString, + $email->__toString(), + 'Loaded state does not match inital value.' + ); + $this->assertEquals( + $emailString, + $email->address(), + 'Addresses do not match.' + ); + $this->assertEquals( + 'user', + $email->username(), + 'Usernames do not match.' + ); + $this->assertEquals( + 'domain', + $email->domain(), + 'Domains do not match.' + ); + $this->assertEquals( + 'tld', + $email->tld(), + 'TLDs do not match.' + ); + } + + /** + * Tests supplied e-mail address is converted to lower case. + * + * @return void + */ + public function testConvertsToLowerCase(): void + { + // Performs test. + $emailString = 'User@DoMaiN.Tld'; + $email = EmailAddress::fromString($emailString); + + // Performs assertions. + $this->assertEquals( + \strtolower(\trim($emailString)), + $email->__toString(), + 'Trimmed and lower cased strings do not match.' + ); + } + + /** + * Tests breaks instantiation, if invalid data is supplied. + * + * @return void + */ + public function testBreaksIfEmptyAddressSupplied(): void + { + // Creates expectation. + $this->expectException(\InvalidArgumentException::class); + + // Performs test. + EmailAddress::fromString(''); + } + + /** + * Tests breaks instantiation, if invalid data is supplied. + * + * @return void + */ + public function testBreaksIfInvalidAddressSupplied(): void + { + // Creates expectation. + $this->expectException(\InvalidArgumentException::class); + + // Performs test. + EmailAddress::fromString('This is not an email address'); + } + + /** + * Tests instance can be serialized and deserialized correctly. + * + * @return void + */ + public function testSerializesAndDeserializesCorrectly(): void + { + // Performs test. + $emailString = 'user@domain.tld'; + $email1 = EmailAddress::fromString($emailString); + + $serialized = \serialize($email1); + $email2 = \unserialize($serialized); + + // Performs assertions. + $this->assertInstanceOf( + EmailAddress::class, + $email1, + 'Returned instance is not of type EmailAddress.' + ); + $this->assertInstanceOf( + EmailAddress::class, + $email2, + 'Returned instance is not of type EmailAddress.' + ); + $this->assertEquals( + $email1->__toString(), + $email2->__toString(), + 'Addresses do not match.' + ); + $this->assertNotEquals( + $serialized, + $email2->__toString(), + 'Addresses do not match.' + ); + } +} From 9dacd1a6683e4d538f8083bbb4baa5cb9a1fe573 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 18:25:22 +0000 Subject: [PATCH 017/193] fix: Change type hinting in count() --- src/Scalar/AbstractBaseString.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 610afeb..32c4fba 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -164,7 +164,7 @@ public function endsWith(string $search): bool * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ - public function count(string $search, int $start = 0, int $length = null): int + public function count(string $search, int $start = 0, ?int $length = null): int { // Validates supplied $search parameter. if (\strlen($search) === 0) { From ce589ae49ac580f4640629f7a2863f4dd15b75ff Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 18:31:30 +0000 Subject: [PATCH 018/193] tests: Increase code coverage --- tests/Unit/Scalar/ImmutableStringTest.php | 229 +++++++++++++++++++++- 1 file changed, 228 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Scalar/ImmutableStringTest.php b/tests/Unit/Scalar/ImmutableStringTest.php index 350bd71..a777b8b 100644 --- a/tests/Unit/Scalar/ImmutableStringTest.php +++ b/tests/Unit/Scalar/ImmutableStringTest.php @@ -111,7 +111,7 @@ public function testCanCheckIfStringContainsPortion(): void * * @return void */ - public function testBreaksWhileCheckingIfStringContainsPortion(): void + public function testBreaksCheckingIfStringContainsPortionWithEmptyText(): void { // Performs test. $original = $this->getInstance("Immutable string."); @@ -123,6 +123,233 @@ public function testBreaksWhileCheckingIfStringContainsPortion(): void $original->contains(''); } + /** + * Tests can retrieve string's length. + * + * @return void + */ + public function testCanRetrieveLength(): void + { + // Performs test. + $original = "Immutable string."; + $instance = $this->getInstance($original); + + // Performs assertions. + $this->assertEquals( + \strlen($original), + $instance->length(), + 'Length values do not match.' + ); + $this->checkCorrectInstanceType($instance); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testCanRetrieveIndexOf(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $indexOf = $instance->indexOf('string'); + + // Performs assertions. + $this->assertEquals( + 10, + $indexOf, + 'Retrieved index is incorrect.' + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testCanRetrieveIndexOfWithStart(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $indexOf = $instance->indexOf('string', 15); + + // Performs assertions. + $this->assertEquals( + 37, + $indexOf, + 'Retrieved index is incorrect.' + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testIndexOfReturnsNullIfNotFound(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $indexOf = $instance->indexOf('another'); + + // Performs assertions. + $this->assertNull( + $indexOf, + 'Retrieved index should have been NULL.' + ); + } + + /** + * Test indexOf() breaks with illegal parameters. + * + * @return void + */ + public function testBreaksIndexOfIfEmptySearch(): void + { + // Creates expectation. + $this->expectException(\InvalidArgumentException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->indexOf(''); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testCanCheckIfStringStartsWithText(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $true = $instance->startsWith("Immu"); + $false = $instance->startsWith("string"); + + // Performs assertions. + $this->assertTrue($true); + $this->assertFalse($false); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testBreaksCheckingIfStringStartsWithText(): void + { + // Creates expectation. + $this->expectException(\InvalidArgumentException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->startsWith(''); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testCanCheckIfStringEndsWithText(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $true = $instance->endsWith("string."); + $false = $instance->endsWith("Immu"); + + // Performs assertions. + $this->assertTrue($true); + $this->assertFalse($false); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testBreaksCheckingIfStringEndsWithText(): void + { + // Creates expectation. + $this->expectException(\InvalidArgumentException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->endsWith(''); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInString(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count('string'); + + // Performs assertions. + $this->assertEquals( + 2, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInStringWithStartAndLength(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count('string', 15, 29); + + // Performs assertions. + $this->assertEquals( + 1, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInStringIfNoneIsFound(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count('string', 38, 4); + + // Performs assertions. + $this->assertEquals( + 0, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() breaks if empty search is supplied. + * + * @return void + */ + public function testBreaksCountNumberOccurencesInStringIfSerachIsEmpty(): void + { + // Creates expectation. + $this->expectException(\InvalidArgumentException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $instance->count(''); + } + /** * Tests that a string can be trimmed. * From a5b60eae22417bf459e5ae210b7e75fd9f276fe2 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 18:50:15 +0000 Subject: [PATCH 019/193] docs: Improve documentation --- README.md | 7 ++- src/README.md | 69 ++++++---------------------- src/Scalar/README.md | 89 +++++++++++++++++++++++++++++++++++++ src/Web/README.md | 1 + tests/Unit/Scalar/README.md | 1 + tests/Unit/Web/README.md | 1 + 6 files changed, 112 insertions(+), 56 deletions(-) create mode 100644 src/Scalar/README.md create mode 100644 src/Web/README.md create mode 100644 tests/Unit/Scalar/README.md create mode 100644 tests/Unit/Web/README.md diff --git a/README.md b/README.md index 29c1c5c..f4e1dfd 100755 --- a/README.md +++ b/README.md @@ -28,6 +28,11 @@ and `boolean`. There will also be wrapping classes around **Complex Datatypes** such as `Datetime`, `Email`, `Color`, `UrlAddress`, ..., and both _Linear_ and _Associative_ **Collections** such as `Queues`, `Stacks` and `Sets`/`Stores`. +### Data Transfer Objects (ValueObjects, Entities, etc...) + +Lastly, **PHP Datatypes** will also provide basic functionality for [DTOs](https://en.wikipedia.org/wiki/Data_transfer_object), +in case you'll want to quickly centralize/isolate record validation and sanitation, in a strongly typed/system agnostic object. + ## Installation In order to install this package, just add it to your **composer**, by executing `composer require hradigital/php-datatypes`. @@ -35,7 +40,7 @@ In order to install this package, just add it to your **composer**, by executing ## Usage For more information about how to to use these Datatypes, please see the project's **usage notes** and some implementation examples -in [here](https://github.com/HRADigital/php-datatypes/tree/master/src/). +in [here](src/). ## Contributing diff --git a/src/README.md b/src/README.md index 2626170..5f93644 100755 --- a/src/README.md +++ b/src/README.md @@ -1,61 +1,20 @@ # PHP Datatypes -You can build up to **3 types** of objects per datatype. A `Readonly`, an `Immutable` object and a `Mutable` object. +PHP Datatypes is an Utility package, meant to provide base/system-wide record and field centralized processing. -## Readonly vs. Immutable vs. Mutable +When developing bigger projects, you might find yourself validating **fields**, **records** and/or **collections** +of **fields/records** in more than one place. -`Mutable` and `Immutable` datatypes will inherit functionality from the `Readonly` datatypes. `Readonly` instances provide -**accessor** methods to retrieve any information from within the instance. The other two datatypes will provide **mutators** -that can manipulate the internal state of the instance. +This packages is meant to supply base classes for most commonly used types of fields, and base functionality that +can facilitate the creation of strongly typed records. -Both `Mutable` and `Immutable` instances have _fluent interfaces_, and therefore you can chain mutator methods, and make -several changes in the same line of code. The main difference between the two, is that `Mutable` instances will return the -same instance everytime, and therefore, will change the internal state as you call its _mutators_. `Immutable` instances -will instead return a new instance of the same type, with the processed value. Here are two examples: +For more information about each type of available object, please read dedicated information: -```php -// Example of an Immutable string. -$string1 = ImmutableString::fromString(" This Is A String "); -$string2 = $string1->trim(); -$string3 = $string2->toLower(); - -if ($string1 === $string2 || $string1 === $string3 || $string2 === $string3) { - echo "This will never print, as all are different instances."; -} - -echo "{$string1} still has the value ' This Is A String '."; -echo "{$string2} has the value 'This Is A String'."; -echo "{$string3} has the value 'this is a string'."; -``` - -```php -// Example of a Mutable string. -$string1 = MutableString::fromString(" This Is A String "); -$string2 = $string1->trim(); -$string3 = $string2->toLower(); - -if ($string1 === $string2 && $string1 === $string3 && $string2 === $string3) { - echo "This will print, as all are the same instance."; -} - -echo "All variables have the same 'this is a string' value."; -``` - -### Method chaning - -You can also do the previous processing, by channing the methods, independently of what type of datatype it is. - -```php -// Example of chaning methods. -$string1 = ImmutableString::fromString(" This Is A String "); -$string2 = MutableString::fromString(" This Is A String "); - -// Both will print out 'this is a string'. -echo $string1->trim()->toLower(); -echo $string2->trim()->toLower(); -``` - -## Domain Driven Design - -These datatypes are great if your implementing **Domain Driven Design** methodology to your project, as you can return -`Immutable` datatypes as **Value Objects** in your _Entities_. +- [Aggregates](Aggregates/) +- [Collections](Collections/) +- [Entities](Entities/) +- [Exceptions](Exceptions/) +- [Scalar](Scalar/) +- [Traits](Traits/) +- [ValueObjects](ValueObjects/) +- [Web](Web/) diff --git a/src/Scalar/README.md b/src/Scalar/README.md new file mode 100644 index 0000000..83c4dc5 --- /dev/null +++ b/src/Scalar/README.md @@ -0,0 +1,89 @@ +# PHP Scalar Datatypes + +Currently, this package supports only **Scalar Strings**. You can choose between `Immutable` and `Mutable` string objects. + +**Scalar Strings** are wrapper objects around primitive `strings`, which encapsulate all string related funcionality into +a single instance. + +## Immutable vs. Mutable + +`Mutable` and `Immutable` string datatypes will have the exact same functionality, but will have different instance management. +Both types inherit commonly used `protected` functionality from parent `AbstractBaseString` class. Parent methods will map to +native procedural string manipulation functions. + +Both types of classes implement `__toString()` method, which means you can directly print their result: + +```php +// Example of an Immutable string. +$string = ImmutableString::fromString(" This Is A String "); + +echo $string; // Prints ' This Is A String ' +``` + +Use **accessor** methods to retrieve any information from within the instance. **Mutators** methods will manipulate the +value of the instance. + +Both `Mutable` and `Immutable` instances have _fluent interfaces_, and therefore you can chain mutator methods, and make +several changes in the same line of code. The main difference between the two types, is that `Mutable` instances will return +the same instance everytime, and therefore, will change the internal state as you call its _mutators_. `Immutable` instances +will instead return a new instance of the same type, with the processed value. + +Here are two examples: + +```php +// Example of an Immutable string. +$string1 = ImmutableString::fromString(" This Is A String "); +$string2 = $string1->trim(); +$string3 = $string2->toLower(); + +if ($string1 === $string2 || $string1 === $string3 || $string2 === $string3) { + echo "This will never print, as all are different instances."; +} + +if ($string1->equals($string2)) { + echo "This will print, as both instances contain the same value."; +} + +echo "{$string1} still has the value ' This Is A String '."; +echo "{$string2} has the value 'This Is A String'."; +echo "{$string3} has the value 'this is a string'."; +``` + +```php +// Example of a Mutable string. +$string1 = MutableString::fromString(" This Is A String "); +$string2 = $string1->trim(); +$string3 = $string2->toLower(); + +if ($string1 === $string2 && $string1 === $string3 && $string2 === $string3) { + echo "This will print, as all are the same instance."; +} + +echo "All variables have the same 'this is a string' value."; +``` + +### Fluent Interfaces + +You can also do the previous processing, by channing the methods, independently of what type of datatype it is. + +```php +// Example of chaning methods. +$immutable = ImmutableString::fromString(" This Is A String "); +$mutable = MutableString::fromString(" This Is A String "); + +// Both will print out 'this is a string'. +echo $immutable->trim()->toLower(); +echo $mutable->trim()->toLower(); +``` + +### Class usage + +You can easily import, use and manipulate primitive native data in the following way: + +```php +use Hradigital\Datatypes\Scalar\MutableString as Str; + +// ... + +$string = Str::fromString(' This is the string I am trying to manipulate. '); +``` diff --git a/src/Web/README.md b/src/Web/README.md new file mode 100644 index 0000000..fbb6f00 --- /dev/null +++ b/src/Web/README.md @@ -0,0 +1 @@ +# PHP Web Datatypes diff --git a/tests/Unit/Scalar/README.md b/tests/Unit/Scalar/README.md new file mode 100644 index 0000000..d1a9493 --- /dev/null +++ b/tests/Unit/Scalar/README.md @@ -0,0 +1 @@ +# Scalar related Unit tests diff --git a/tests/Unit/Web/README.md b/tests/Unit/Web/README.md new file mode 100644 index 0000000..accad97 --- /dev/null +++ b/tests/Unit/Web/README.md @@ -0,0 +1 @@ +# Web related Unit tests From 992ef4db5858202a740153cba28fb716da473537 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 3 Mar 2021 18:56:44 +0000 Subject: [PATCH 020/193] feat: Add new AbstractBaseAggregate --- src/Aggregates/AbstractBaseAggregate.php | 46 ++++++++++++++++++++++++ src/Aggregates/README.md | 33 +++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/Aggregates/AbstractBaseAggregate.php create mode 100755 src/Aggregates/README.md diff --git a/src/Aggregates/AbstractBaseAggregate.php b/src/Aggregates/AbstractBaseAggregate.php new file mode 100644 index 0000000..07dcffb --- /dev/null +++ b/src/Aggregates/AbstractBaseAggregate.php @@ -0,0 +1,46 @@ + $value) { + + // If the Attribute's value is json serializable itself, + // serialize and add it to the returning array. + // Otherwize, return its holding value. + if ($value instanceof \JsonSerializable) { + $json[$name] = $value->jsonSerialize(); + } elseif (\method_exists($value, '__toString')) { + $json[$name] = $value->__toString(); + } else { + $json[$name] = $value; + } + } + + return $json; + } +} diff --git a/src/Aggregates/README.md b/src/Aggregates/README.md new file mode 100755 index 0000000..83e7c01 --- /dev/null +++ b/src/Aggregates/README.md @@ -0,0 +1,33 @@ +# Domain Aggregates + +_Domain Aggregates_ are not meant to be the same as _DDD's Aggregates_. + +`Aggregates` are meant to **aggregate returned types** together, in order to **minimize** communication with the **Domain**. + +As [Martin Fowler](https://martinfowler.com/) puts it, _**Aggregates are the basic element of transfer of data** +**storage - you request to load and save whole aggregates**_. + +For more information please [read Martin Fowler's blog](https://martinfowler.com/bliki/DDD_Aggregate.html). + +## When to use Aggregates + +When communicating in the **Domain**, we might only need an _Entity_ or a _Collection_ returned, but in some other +cases, we might need that initial _Entity_, but also some other object (eg:. _Collection_). + +In these cases, we would need to perform multiple calls to the **Domain**, and in some cases, we would need to hold +state in between calls. + +**Aggregates** are objects that will encapsulate/aggregate several other objects that are meant to be **returned as a group**. +This way, we will only make one call to the **Domain**, and will only require the state to hold on that call's execution. + +## How to structure an Aggregate + +An **Aggregate** is a simple native object, that doesn't require to extend any base class, and should not contain any +_Business Logic_ inside. + +It is a _Value Object_ whose main purposes are providing a _strong return type_, and a way to group other objects together. + +The basic structure for an **Aggregate** comprises of a _construct_ with all the objects that we're trying to aggregate together, +and class attributes to hold them in state. + +We should then provide *accessors* (`getters()`) for each attribute in the **Aggregate** From 312a9ddab07bbf51785bb16d726198aff0c8b747 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Thu, 4 Mar 2021 17:34:34 +0000 Subject: [PATCH 021/193] build: Add xdebug development dependency --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 70ed8c0..c896d31 100755 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "php": "^7.4" }, "require-dev": { + "ext-xdebug": "*", "phpunit/phpunit": "^9.0", "squizlabs/php_codesniffer": "^3.0@dev" }, From d83a3ffe617d105ba346079305022bb3a3fa6335 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 25 May 2021 12:49:12 +0100 Subject: [PATCH 022/193] feat: Initial Exception's package collection --- src/Exceptions/AbstractBaseException.php | 51 +++++++++++++++++++ src/Exceptions/ConflictException.php | 39 ++++++++++++++ .../Datatypes/InvalidEmailException.php | 20 ++++++++ .../InvalidStringLengthException.php | 20 ++++++++ .../Datatypes/NonEmptyStringException.php | 20 ++++++++ .../Datatypes/NonNegativeNumberException.php | 22 ++++++++ .../Datatypes/PositiveIntegerException.php | 20 ++++++++ src/Exceptions/Datatypes/README.md | 1 + src/Exceptions/DeniedAccessException.php | 41 +++++++++++++++ src/Exceptions/Entities/README.md | 1 + .../RequiredEntityValueMissingException.php | 26 ++++++++++ .../UnexpectedEntityValueException.php | 20 ++++++++ src/Exceptions/ExpectationFailedException.php | 39 ++++++++++++++ src/Exceptions/FailedDependencyException.php | 39 ++++++++++++++ src/Exceptions/ForbiddenException.php | 41 +++++++++++++++ src/Exceptions/GoneException.php | 43 ++++++++++++++++ src/Exceptions/MethodNotAllowedException.php | 41 +++++++++++++++ src/Exceptions/NotAcceptableException.php | 39 ++++++++++++++ src/Exceptions/NotFoundException.php | 43 ++++++++++++++++ .../PreconditionFailedException.php | 39 ++++++++++++++ .../PreconditionRequiredException.php | 34 +++++++++++++ src/Exceptions/README.md | 30 +++++++++++ .../RequestedRangeNotSatisfiableException.php | 40 +++++++++++++++ src/Exceptions/TooManyRequestsException.php | 39 ++++++++++++++ .../UnprocessableEntityException.php | 46 +++++++++++++++++ .../UnsupportedMediaTypeException.php | 45 ++++++++++++++++ 26 files changed, 839 insertions(+) create mode 100755 src/Exceptions/AbstractBaseException.php create mode 100755 src/Exceptions/ConflictException.php create mode 100644 src/Exceptions/Datatypes/InvalidEmailException.php create mode 100644 src/Exceptions/Datatypes/InvalidStringLengthException.php create mode 100644 src/Exceptions/Datatypes/NonEmptyStringException.php create mode 100644 src/Exceptions/Datatypes/NonNegativeNumberException.php create mode 100644 src/Exceptions/Datatypes/PositiveIntegerException.php create mode 100644 src/Exceptions/Datatypes/README.md create mode 100644 src/Exceptions/DeniedAccessException.php create mode 100644 src/Exceptions/Entities/README.md create mode 100644 src/Exceptions/Entities/RequiredEntityValueMissingException.php create mode 100644 src/Exceptions/Entities/UnexpectedEntityValueException.php create mode 100644 src/Exceptions/ExpectationFailedException.php create mode 100755 src/Exceptions/FailedDependencyException.php create mode 100644 src/Exceptions/ForbiddenException.php create mode 100755 src/Exceptions/GoneException.php create mode 100755 src/Exceptions/MethodNotAllowedException.php create mode 100644 src/Exceptions/NotAcceptableException.php create mode 100755 src/Exceptions/NotFoundException.php create mode 100755 src/Exceptions/PreconditionFailedException.php create mode 100644 src/Exceptions/PreconditionRequiredException.php create mode 100755 src/Exceptions/README.md create mode 100644 src/Exceptions/RequestedRangeNotSatisfiableException.php create mode 100755 src/Exceptions/TooManyRequestsException.php create mode 100644 src/Exceptions/UnprocessableEntityException.php create mode 100755 src/Exceptions/UnsupportedMediaTypeException.php diff --git a/src/Exceptions/AbstractBaseException.php b/src/Exceptions/AbstractBaseException.php new file mode 100755 index 0000000..1dc9454 --- /dev/null +++ b/src/Exceptions/AbstractBaseException.php @@ -0,0 +1,51 @@ +message; + } + $code = $this->code; + + // Calls parent construct() with default code. + parent::__construct($message, $code, $inner); + } +} diff --git a/src/Exceptions/ConflictException.php b/src/Exceptions/ConflictException.php new file mode 100755 index 0000000..fb3f07a --- /dev/null +++ b/src/Exceptions/ConflictException.php @@ -0,0 +1,39 @@ +messageWithId, $id) : $this->message), + $inner + ); + } +} diff --git a/src/Exceptions/MethodNotAllowedException.php b/src/Exceptions/MethodNotAllowedException.php new file mode 100755 index 0000000..4c192cb --- /dev/null +++ b/src/Exceptions/MethodNotAllowedException.php @@ -0,0 +1,41 @@ +messageWithId, $id) : $this->message), + $inner + ); + } +} diff --git a/src/Exceptions/PreconditionFailedException.php b/src/Exceptions/PreconditionFailedException.php new file mode 100755 index 0000000..1329cfa --- /dev/null +++ b/src/Exceptions/PreconditionFailedException.php @@ -0,0 +1,39 @@ +json(['error' => $e->getMessage()], $e->getCode()); +} +``` + +All Domain Exception's also extend `AbstractBaseException` class, and therefore, the application layer can easily identify a Domain raised exception from another one. + +```php +try { + // ... raised a domain exception +} catch (AbstractBaseException $e) { + // ... have some behavior. +} catch (\Throwable $e) { + // ... have some OTHER behavior. +} +``` + +By creating and using Domain Exceptions, the application not only pinpoints what type of error occured, but also reduces the number of exceptions raised, while abstracting from any 3rd party dependency. + +If in a given context, a User record is required but not found, an `UserNotFoundException` can be raised, independently of the persistence layer's type (_DB, REST API, ..._). +This Exception, will already have a predefined eror message and code, that can be used in the application layer, either for an API response, or just for logging. diff --git a/src/Exceptions/RequestedRangeNotSatisfiableException.php b/src/Exceptions/RequestedRangeNotSatisfiableException.php new file mode 100644 index 0000000..1cb12c0 --- /dev/null +++ b/src/Exceptions/RequestedRangeNotSatisfiableException.php @@ -0,0 +1,40 @@ +messageWithName, $name) : $this->message), + $inner + ); + } +} diff --git a/src/Exceptions/UnsupportedMediaTypeException.php b/src/Exceptions/UnsupportedMediaTypeException.php new file mode 100755 index 0000000..4bcfeb4 --- /dev/null +++ b/src/Exceptions/UnsupportedMediaTypeException.php @@ -0,0 +1,45 @@ +messageWithName, $name) : $this->message), + $inner + ); + } +} From 3bd80e97f6eaef10c40b9529befdcad5908f1791 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Thu, 27 May 2021 15:18:28 +0100 Subject: [PATCH 023/193] refactor: Rename ImmutableString class --- .../{ImmutableString.php => IString.php} | 116 +++++++++--------- ...mmutableStringTest.php => IStringTest.php} | 12 +- 2 files changed, 64 insertions(+), 64 deletions(-) rename src/Scalar/{ImmutableString.php => IString.php} (79%) rename tests/Unit/Scalar/{ImmutableStringTest.php => IStringTest.php} (98%) diff --git a/src/Scalar/ImmutableString.php b/src/Scalar/IString.php similarity index 79% rename from src/Scalar/ImmutableString.php rename to src/Scalar/IString.php index b882888..2ead86e 100644 --- a/src/Scalar/ImmutableString.php +++ b/src/Scalar/IString.php @@ -13,27 +13,27 @@ * @package Hradigital\Datatypes * @license MIT */ -class ImmutableString extends AbstractBaseString +class IString extends AbstractBaseString { /** - * Creates a new instance of ImmutableString based on a string value. + * Creates a new instance of IString based on a string value. * * @param string $value - Instance's initial value. - * @return ImmutableString + * @return IString */ - public static function fromString(string $value): ImmutableString + public static function create(string $value): IString { - return new ImmutableString($value); + return new IString($value); } /** * Trims instance's value, and returns a new instance of the object. * - * @return ImmutableString + * @return IString */ - public function trim(): ImmutableString + public function trim(): IString { - return new ImmutableString( + return new IString( parent::doTrim($this->value) ); } @@ -41,11 +41,11 @@ public function trim(): ImmutableString /** * Left trims instance's value, and returns a new instance of the object. * - * @return ImmutableString + * @return IString */ - public function trimLeft(): ImmutableString + public function trimLeft(): IString { - return new ImmutableString( + return new IString( parent::doTrimLeft($this->value) ); } @@ -53,11 +53,11 @@ public function trimLeft(): ImmutableString /** * Right trims instance's value, and returns a new instance of the object. * - * @return ImmutableString + * @return IString */ - public function trimRight(): ImmutableString + public function trimRight(): IString { - return new ImmutableString( + return new IString( parent::doTrimRight($this->value) ); } @@ -65,11 +65,11 @@ public function trimRight(): ImmutableString /** * Converts the instance's value to Upper Case, and returns a new instance of the object. * - * @return ImmutableString + * @return IString */ - public function toUpper(): ImmutableString + public function toUpper(): IString { - return new ImmutableString( + return new IString( parent::doToUpper($this->value) ); } @@ -78,11 +78,11 @@ public function toUpper(): ImmutableString * Converts the instance's value first character to Upper Case, and returns a new instance * of the object. * - * @return ImmutableString + * @return IString */ - public function toUpperFirst(): ImmutableString + public function toUpperFirst(): IString { - return new ImmutableString( + return new IString( parent::doToUpperFirst($this->value) ); } @@ -93,11 +93,11 @@ public function toUpperFirst(): ImmutableString * * @param string $delimiters - The optional delimiters contains the word separator characters. * - * @return ImmutableString + * @return IString */ - public function toUpperWords(string $delimiters = " \t\r\n\f\v"): ImmutableString + public function toUpperWords(string $delimiters = " \t\r\n\f\v"): IString { - return new ImmutableString( + return new IString( parent::doToUpperWords($this->value, $delimiters) ); } @@ -105,11 +105,11 @@ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): ImmutableStrin /** * Converts the instance's value to Lower Case, and returns a new instance of the object. * - * @return ImmutableString + * @return IString */ - public function toLower(): ImmutableString + public function toLower(): IString { - return new ImmutableString( + return new IString( parent::doToLower($this->value) ); } @@ -118,11 +118,11 @@ public function toLower(): ImmutableString * Converts the instance's value first character to Lower Case, and returns a new instance * of the object * - * @return ImmutableString + * @return IString */ - public function toLowerFirst(): ImmutableString + public function toLowerFirst(): IString { - return new ImmutableString( + return new IString( parent::doToLowerFirst($this->value) ); } @@ -138,11 +138,11 @@ public function toLowerFirst(): ImmutableString * it is padded with characters from $padding up to the limit. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return ImmutableString + * @return IString */ - public function padLeft(int $length, string $padding = " "): ImmutableString + public function padLeft(int $length, string $padding = " "): IString { - return new ImmutableString( + return new IString( parent::doPadLeft($this->value, $length, $padding) ); } @@ -158,11 +158,11 @@ public function padLeft(int $length, string $padding = " "): ImmutableString * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return ImmutableString + * @return IString */ - public function padLeftExtra(int $length, string $padding = " "): ImmutableString + public function padLeftExtra(int $length, string $padding = " "): IString { - return new ImmutableString( + return new IString( parent::doPadLeftExtra($this->value, $length, $padding) ); } @@ -182,11 +182,11 @@ public function padLeftExtra(int $length, string $padding = " "): ImmutableStrin * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return ImmutableString + * @return IString */ - public function padRight(int $length, string $padding = " "): ImmutableString + public function padRight(int $length, string $padding = " "): IString { - return new ImmutableString( + return new IString( parent::doPadRight($this->value, $length, $padding) ); } @@ -202,11 +202,11 @@ public function padRight(int $length, string $padding = " "): ImmutableString * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return ImmutableString + * @return IString */ - public function padRightExtra(int $length, string $padding = " "): ImmutableString + public function padRightExtra(int $length, string $padding = " "): IString { - return new ImmutableString( + return new IString( parent::doPadRightExtra($this->value, $length, $padding) ); } @@ -237,11 +237,11 @@ public function padRightExtra(int $length, string $padding = " "): ImmutableStri * @param int $length - Length of the sub-string. Can be negative. * * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return ImmutableString + * @return IString */ - public function subString(int $start, int $length = null): ImmutableString + public function subString(int $start, int $length = null): IString { - return new ImmutableString( + return new IString( parent::doSubString($this->value, $start, $length) ); } @@ -250,16 +250,16 @@ public function subString(int $start, int $length = null): ImmutableString * This method returns a new instance with a portion of the original instance's value, starting at the beginning * of the value, with the number of characters specified in the $length parameter. * - * Same rules as ImmutableString::subString() are applied. + * Same rules as IString::subString() are applied. * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * @return ImmutableString + * @return IString */ - public function subLeft(int $length): ImmutableString + public function subLeft(int $length): IString { - return new ImmutableString( + return new IString( parent::doSubLeft($this->value, $length) ); } @@ -268,16 +268,16 @@ public function subLeft(int $length): ImmutableString * This method returns a new instance with a portion of the original instance's value, couting from the end * of the value, with the number of characters specified in the $length parameter. * - * Same rules as ImmutableString::subString() are applied. + * Same rules as IString::subString() are applied. * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * @return ImmutableString + * @return IString */ - public function subRight(int $length): ImmutableString + public function subRight(int $length): IString { - return new ImmutableString( + return new IString( parent::doSubRight($this->value, $length) ); } @@ -285,11 +285,11 @@ public function subRight(int $length): ImmutableString /** * This method returns a new instance with the reversed value of the original instance. * - * @return ImmutableString + * @return IString */ - public function reverse(): ImmutableString + public function reverse(): IString { - return new ImmutableString( + return new IString( parent::doReverse($this->value) ); } @@ -301,11 +301,11 @@ public function reverse(): ImmutableString * @param string $replace - The search's replacement. * * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. - * @return ImmutableString + * @return IString */ - public function replace(string $search, string $replace): ImmutableString + public function replace(string $search, string $replace): IString { - return new ImmutableString( + return new IString( parent::doReplace($this->value, $search, $replace) ); } diff --git a/tests/Unit/Scalar/ImmutableStringTest.php b/tests/Unit/Scalar/IStringTest.php similarity index 98% rename from tests/Unit/Scalar/ImmutableStringTest.php rename to tests/Unit/Scalar/IStringTest.php index a777b8b..2eb54ed 100644 --- a/tests/Unit/Scalar/ImmutableStringTest.php +++ b/tests/Unit/Scalar/IStringTest.php @@ -3,7 +3,7 @@ namespace Hradigital\Tests\Datatypes\Unit\Scalar; use Hradigital\Datatypes\Scalar\AbstractBaseString; -use Hradigital\Datatypes\Scalar\ImmutableString; +use Hradigital\Datatypes\Scalar\IString; use Hradigital\Tests\Datatypes\AbstractBaseTestCase; /** @@ -11,7 +11,7 @@ * * Protected method in this class, are available for override in child classes. * - * ImmutableString and MutableString classes have similar behavior, therefore, + * IString and MutableString classes have similar behavior, therefore, * you should extend this test case for the other type of String, overriding only the necessary * tests, which shouldn't be too many. * @@ -20,7 +20,7 @@ * @package Hradigital\Datatypes * @license MIT */ -class ImmutableStringTest extends AbstractBaseTestCase +class IStringTest extends AbstractBaseTestCase { /** * Asserts that 2 string instances do not match. @@ -48,9 +48,9 @@ protected function checkInstances(AbstractBaseString $original, AbstractBaseStri protected function checkCorrectInstanceType(AbstractBaseString $instance): void { $this->assertInstanceOf( - ImmutableString::class, + IString::class, $instance, - 'Instance type, does not match ImmutableString.' + 'Instance type, does not match IString.' ); } @@ -65,7 +65,7 @@ protected function checkCorrectInstanceType(AbstractBaseString $instance): void */ protected function getInstance(string $initialValue): AbstractBaseString { - return ImmutableString::fromString($initialValue); + return IString::create($initialValue); } /** From 85d73b9164419194fa0a35a0b18a03db990c997a Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Thu, 27 May 2021 15:19:21 +0100 Subject: [PATCH 024/193] refcator: Change __toString() call to type casting --- src/Aggregates/AbstractBaseAggregate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aggregates/AbstractBaseAggregate.php b/src/Aggregates/AbstractBaseAggregate.php index 07dcffb..15fcfde 100644 --- a/src/Aggregates/AbstractBaseAggregate.php +++ b/src/Aggregates/AbstractBaseAggregate.php @@ -35,7 +35,7 @@ public function jsonSerialize(): array if ($value instanceof \JsonSerializable) { $json[$name] = $value->jsonSerialize(); } elseif (\method_exists($value, '__toString')) { - $json[$name] = $value->__toString(); + $json[$name] = (string) $value; } else { $json[$name] = $value; } From 95494fea2a9c3c7e650cf9fef269199e63f1cd78 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Thu, 27 May 2021 15:33:31 +0100 Subject: [PATCH 025/193] feat: Add Colleciton's namespace --- src/Collections/Associative/README.md | 24 ++ src/Collections/Associative/Store.php | 239 +++++++++++++++ src/Collections/Linear/AbstractListArray.php | 126 ++++++++ src/Collections/Linear/EntityCollection.php | 271 ++++++++++++++++++ .../Linear/PaginatedCollection.php | 265 +++++++++++++++++ src/Collections/Linear/Queue.php | 115 ++++++++ src/Collections/Linear/README.md | 31 ++ src/Collections/Linear/Stack.php | 117 ++++++++ src/Collections/README.md | 73 +++++ 9 files changed, 1261 insertions(+) create mode 100644 src/Collections/Associative/README.md create mode 100644 src/Collections/Associative/Store.php create mode 100644 src/Collections/Linear/AbstractListArray.php create mode 100644 src/Collections/Linear/EntityCollection.php create mode 100644 src/Collections/Linear/PaginatedCollection.php create mode 100644 src/Collections/Linear/Queue.php create mode 100644 src/Collections/Linear/README.md create mode 100644 src/Collections/Linear/Stack.php create mode 100644 src/Collections/README.md diff --git a/src/Collections/Associative/README.md b/src/Collections/Associative/README.md new file mode 100644 index 0000000..154ed20 --- /dev/null +++ b/src/Collections/Associative/README.md @@ -0,0 +1,24 @@ +# Associative Collections + +## Store / Set + +In a **Set**, the order of data items does not matter (or is undefined) but duplicate data items are not permitted. +Examples of operations on **Sets** are the addition and removal of data items and searching for a data item in the +**Set**. + +Some languages support **Sets** directly. In others, **Sets** can be implemented by a hash table with dummy values; +only the keys are used in representing the **Set**. + +## Multisets / Bag + +In a **Multiset** (or _**Bag**_), like in a **Set**, the order of data items does not matter, but in this case +duplicate data items are permitted. Examples of operations on **Multisets** are the addition and removal of data items +and determining how many duplicates of a particular data item are present in the **Multiset**. + +**Multisets** can be transformed into **Lists** by the action of sorting. + +## Associative arrays / Map / Dictionary / Lookup Table / Hash + +In an **Associative Array** (or **Map**, **Dictionary**, **Lookup table**), like in a **Dictionary**, a _lookup_ on +a key (like a word) provides a value (like a definition). The value might be a reference to a compound data structure. +A _Hash Table_ is usually an efficient implementation, and thus this data type is often known as a "_hash_". diff --git a/src/Collections/Associative/Store.php b/src/Collections/Associative/Store.php new file mode 100644 index 0000000..838b5f4 --- /dev/null +++ b/src/Collections/Associative/Store.php @@ -0,0 +1,239 @@ +context = $context; + } + + /** + * Retrieves all existing Values from the Store. + * + * @return array + */ + public function getValues(): array + { + return $this->store; + } + + /** + * Retrieves a value from the Store. + * + * If the value is not found, the supplied $default value will be returned. + * + * @param string $name - Name of the Value to be retrieved. + * @param string|NULL $default - Default returned value, of not found. + * + * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @return string|NULL + */ + public function get(string $name, ?string $default = null): ?string + { + // Sanitize provided $name/key. + $name = $this->sanitizeName($name); + + // Validate if the provided key is available in the "store". + if ($this->has($name)) { + return $this->store[$this->name($name)]; + } + + return $default; + } + + /** + * Returns TRUE of the value exists in the store. + * FALSE otherwise. + * + * @param string $name - Name of the Value to be searched. + * + * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @return bool + */ + public function has(string $name): bool + { + // Sanitize provided $name/key. + $name = $this->sanitizeName($name); + + return \array_key_exists($this->name($name), $this->store); + } + + /** + * Sets a value in the Store. + * + * @param string $name - Name of the Value to be set. + * @param string $value - Value to be set. + * + * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @return bool + */ + public function set(string $name, string $value): bool + { + // Sanitize provided $name/key. + $name = $this->sanitizeName($name); + + // Sets the value in the store. + $this->store[$this->name($name)] = $value; + + return true; + } + + /** + * Adds a non existing value in the Store. + * + * @param string $name - Name of the Value to be added. + * @param string $value - Value to be added. + * + * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @return bool + */ + public function add(string $name, string $value): bool + { + // Sanitize provided $name/key. + $name = $this->sanitizeName($name); + + // Validate if the provided key is available in the "store". + if ($this->has($name)) { + return false; + } + + // Sets the value in the store. + return $this->set($name, $value); + } + + /** + * Edits an existing value in the Store. + * + * @param string $name - Name of the Value to be edited. + * @param string $value - Value to be edited. + * + * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @return bool + */ + public function edit(string $name, string $value): bool + { + // Sanitize provided $name/key. + $name = $this->sanitizeName($name); + + // Validate if the provided key is available in the "store". + if (! $this->has($name)) { + return false; + } + + // Sets the value in the store. + return $this->set($name, $value); + } + + /** + * Removes a given value from the Store. + * + * @param string $name - Name of the value to be removed from the store. + * + * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @return bool + */ + public function delete(string $name): bool + { + // Sanitize provided $name/key. + $name = $this->sanitizeName($name); + + // Validate if the provided key is available in the "store". + if (! $this->has($name)) { + return false; + } + + // Removes value from Store. + unset($this->store[$this->name($name)]); + + return true; + } + + /** + * Returns sanitized $name/key. + * + * @param string $name - Name to be sanitized. + * + * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @return string + */ + protected function sanitizeName(string $name): string + { + // Validates provided parameters. + if (\strlen(\trim($name)) === 0) { + throw new \InvalidArgumentException('Supplied name must be a non empty string.'); + } + + // Returns sanitized $name/key. + return \strtolower(\trim($name)); + } + + /** + * Returns full name, with namespace included if necessary. + * + * @param string $name - Sanitized name. + * + * @return string + */ + protected function name(string $name): string + { + // Returns sanitized $name/key. + if ($this->context === null) { + return $name; + } else { + return ($this->context . '.' . $name); + } + } + + /** + * {@inheritDoc} + * @see \JsonSerializable::jsonSerialize() + */ + public function jsonSerialize(): array + { + return $this->getValues(); + } +} diff --git a/src/Collections/Linear/AbstractListArray.php b/src/Collections/Linear/AbstractListArray.php new file mode 100644 index 0000000..49b53fd --- /dev/null +++ b/src/Collections/Linear/AbstractListArray.php @@ -0,0 +1,126 @@ +list); + } + + /** + * Returns the array List of values. + * + * @return array + */ + public function toArray(): array + { + return $this->list; + } + + /** + * Clears the List of values. + * + * @return void + */ + public function clear(): void + { + $this->list = []; + } + + /** + * Returns TRUE if the List is empty. + * + * @return bool + */ + public function isEmpty(): bool + { + return ($this->count() === 0); + } + + /** + * Returns the total capacity allowed by the List. + * + * If the capacity is set to -1, it means the List has no capacity limit. + * + * @return int + */ + public function capacity(): int + { + return $this->capacity; + } + + /** + * Allocates a capacity limit to the List. + * + * @param int $capacity - Capacity limit to set in the List. + * + * @throws \InvalidArgumentException - If provided capacity is not a positive integer. + * @throws \OutOfRangeException - The the supplied capacity is less than the current List's value count. + * @return void + */ + public function allocate(int $capacity): void + { + // Validates provided parameter. + if ($capacity < 1) { + throw new \InvalidArgumentException("Supplied capacity must be a positive integer."); + } + if ($capacity < $this->count()) { + throw new \OutOfRangeException("Supplied capacity cannot be less than the current list's capacity."); + } + + // Sets the capacity in the List. + $this->capacity = $capacity; + } + + /** + * Serializes the List into a JSON string. + * + * @return string + */ + public function jsonSerialize(): string + { + return \json_encode($this->list); + } +} diff --git a/src/Collections/Linear/EntityCollection.php b/src/Collections/Linear/EntityCollection.php new file mode 100644 index 0000000..abab9e7 --- /dev/null +++ b/src/Collections/Linear/EntityCollection.php @@ -0,0 +1,271 @@ +collection); + } + + /** + * Returns TRUE if an Entity with the supplied ID exists in the collection. + * + * @param int $id - Entity's ID to search for. + * + * @throws \OutOfRangeException - If the supplied ID is not a positive integer. + * @return bool + */ + public function has(int $id): bool + { + // Validates supplied ID. + if ($id <= 0) { + throw new \OutOfRangeException("Supplied ID should be a positive integer."); + } + + // Returns the existence of the Entity in the Collection. + return \array_key_exists($id, $this->collection); + } + + /** + * Retrieves the Collection's Entity with the supplied ID. + * + * @param int $id - Entity's ID to search for. + * + * @throws \OutOfRangeException - If the supplied ID is not a positive integer. + * @throws \OutOfBoundsException - If the supplied ID was not present in the Collection. + * @return AbstractEntity + */ + public function get(int $id): AbstractEntity + { + // Validates supplied ID. + if ($id <= 0) { + throw new \OutOfRangeException("Supplied ID should be a positive integer."); + } + if (!\array_key_exists($id, $this->collection)) { + throw new \OutOfBoundsException("The Entity you are trying to retrieve does not exist in the Collection."); + } + + // Returns the Entity. + return $this->collection[$id]; + } + + /** + * Counts the number of elements the Collection contains. + * + * @return int + */ + public function count(): int + { + return \count($this->collection); + } + + /** + * Clear the Entity Collection from the object. + * + * This method supports chaining. + * + * @return self + */ + public function clear(): self + { + // Clears Collection's array. + $this->collection = []; + $this->rewind(); + + // Returns instance. + return $this; + } + + /** + * Returns the list of Entity's IDs loaded in the Collection + * + * @return array + */ + public function ids(): array + { + return \array_keys($this->collection); + } + + /** + * Adds a new Entity to the Collection. + * + * This method supports chaining. + * + * @param AbstractEntity $entity - Entity to add to the collection. + * + * @throws \OverflowException - If you're trying to add a repeated Entity to the Collection. + * @return self + */ + public function add(AbstractEntity $entity): self + { + // Validates if the given Entity already exists in the Collection. + if (\array_key_exists($entity->id(), $this->collection)) { + throw new \OverflowException("The Entity you are trying to add to the Collection already exists."); + } + + // Adds an Entity to the collection. + $this->collection[$entity->id()] = $entity; + + // Returns this instance. + return $this; + } + + /** + * Removes an Entity, identified by the supplied ID, from the Collection. + * + * Returns TRUE on success, FALSE otherwise. + * + * @param int $id - Entity's ID to search for. + * + * @throws \OutOfRangeException - If the supplied ID is not a positive integer. + * @throws \OutOfBoundsException - If the Entity with the supplied ID doesn't exist in the Collection. + * @return bool + */ + public function remove(int $id): bool + { + // Validates supplied ID. + if ($id <= 0) { + throw new \OutOfRangeException("Supplied ID should be a positive integer."); + } + if (!\array_key_exists($id, $this->collection)) { + throw new \OutOfBoundsException("The Entity you are trying to delete does not exist in the Collection."); + } + + // Removes element and rewinds + unset($this->collection[$id]); + $this->previous(); + + // Returns success. + return true; + } + + /** + * Rewinds the cursor in the Collection, and returns the first Element for the + * Collection. + * + * {@inheritDoc} + * @see \Iterator::rewind() + */ + public function rewind(): ?AbstractEntity + { + // Rewinds the cursor and returns the first Element. + if (($element = \reset($this->collection)) !== false) { + return $element; + } + + return null; + } + + /** + * Retrieves the current Element for the Collection + * + * {@inheritDoc} + * @see \Iterator::current() + */ + public function current(): ?AbstractEntity + { + // If retrieving the current element fails, we'll still try to rewind the + // pointer and return the first element. + if (($current = \current($this->collection)) === false) { + return $this->rewind(); + } + + return $current; + } + + /** + * Retrieves the current Collection's Element key. + * + * {@inheritDoc} + * @see \Iterator::key() + */ + public function key(): ?int + { + // First, we'll collect the key. + $key = \key($this->collection); + + // Then, we'll uniform the returned value. + if ($key !== null && $key !== false) { + return ((int) $key); + } else { + return null; + } + } + + /** + * Gets next cursor element in the Collection. + * + * {@inheritDoc} + * @see \Iterator::next() + */ + public function next(): void + { + \next($this->collection); + } + + /** + * Gets the previous cursor element in the Collection. + * + * Although this method is not actually part of the \Iterator interface, this was added + * as an add on for consistency with the next() method. + * + * @return void + */ + public function previous(): void + { + \prev($this->collection); + } + + /** + * Validates if the cursor in the Collection points to a valid element. + * + * {@inheritDoc} + * @see \Iterator::valid() + */ + public function valid(): bool + { + return ($this->key() !== null); + } + + /** + * Returns an array containing all its item's serialized data. + * + * Allows the Collection to be serialized directly by the json_encode() function. + * + * {@inheritDoc} + * @link http://www.php.net/manual/en/jsonserializable.jsonserialize.php + * @see \JsonSerializable::jsonSerialize() + */ + public function jsonSerialize(): array + { + // Declares and fills a return array. + $array = []; + foreach ($this->collection as $entity) { + + /** @var AbstractEntity $entity - Type casts record */ + $entity = $entity; + $array[] = $entity->jsonSerialize(); + } + + return $array; + } +} diff --git a/src/Collections/Linear/PaginatedCollection.php b/src/Collections/Linear/PaginatedCollection.php new file mode 100644 index 0000000..cb78484 --- /dev/null +++ b/src/Collections/Linear/PaginatedCollection.php @@ -0,0 +1,265 @@ +collection = $collection; + $this->sortInfo = $sortInfo; + + // Sets the counters. + $this->total = $total; + $this->perPage = $perPage; + + // Sets the Page information. + $this->currentPage = $currentPage; + $this->lastPage = $lastPage; + $this->firstId = $from; + $this->lastId = $to; + } + + /** + * Collection of items being paginated. + * + * Pagination counters will be calculated at start, and will remain immutable + * until the object is destroyed. + * + * Please note that, adding/removing elements to or from the Collection will + * not reflect on the Pagination counters being updated. + * + * @return EntityCollection + */ + public function collection(): EntityCollection + { + return $this->collection; + } + + /** + * Retrieves the sorting information for the Pagination. + * + * @return SortInfo + */ + public function sortInfo(): SortInfo + { + return $this->sortInfo; + } + + /** + * Number of the first record being displayed in the Paginated results. + * + * Please note that, the returned integer is not the record's ID. It represents + * the record's global displaying order if the the records weren't being paginated. + * + * @return int + */ + public function fromRecord(): int + { + return (($this->currentPage - 1) * $this->perPage); + } + + /** + * Number of the last record being displayed in the Paginated results. + * + * Please note that, the returned integer is not the record's ID. It represents + * the record's global displaying order if the the records weren't being paginated. + * + * @return int + */ + public function toRecord(): int + { + if ($this->collection->count() < $this->perPage) { + return ($this->fromRecord() + $this->collection->count()); + } else { + return ($this->fromRecord() + $this->perPage); + } + } + + /** + * Number of the first record's ID being displayed in the Paginated results. + * + * If the record Collection is empty, this will return NULL, as + * there isn't any first or last records. + * + * @return int|NULL + */ + public function firstId(): ?int + { + return $this->firstId; + } + + /** + * Number of the last record's ID being displayed in the Paginated results. + * + * If the record Collection is empty, this will return NULL, as + * there isn't any first or last records. + * + * @return int|NULL + */ + public function lastId(): ?int + { + return $this->lastId; + } + + /** + * Total number of records in source. + * + * Returns the total number of records from the source dataset, from which the pagination was produced. + * + * @return int + */ + public function totalRecords(): int + { + return $this->total; + } + + /** + * Total number of available records for Pagination. + * + * Returns the total number of records in the selected Page. + * + * @return int + */ + public function total(): int + { + return $this->collection->count(); + } + + /** + * Number of the current Page for the paginated records. + * + * @return int + */ + public function currentPage(): int + { + return $this->currentPage; + } + + /** + * Number of the calculated last Page for the paginated records. + * + * @return int + */ + public function lastPage(): int + { + return $this->lastPage; + } + + /** + * Number of records being displayed by Page. + * + * @return int + */ + public function perPage(): int + { + return $this->perPage; + } + + /** + * Returns an Array representation of the Paginated Collection's object. + * + * @return array + */ + public function toArray(): array + { + return [ + 'collection' => $this->collection, + 'sortinfo' => $this->sortInfo, + 'fromRecord' => $this->fromRecord(), + 'toRecord' => $this->toRecord(), + 'totalRecords' => $this->totalRecords(), + 'currentPage' => $this->currentPage(), + 'lastPage' => $this->lastPage(), + 'perPage' => $this->perPage(), + ]; + } + + /** + * Returns an array containing all its item's serialized data. + * + * Allows the Collection to be serialized directly by the json_encode() function. + * + * {@inheritDoc} + * @link http://www.php.net/manual/en/jsonserializable.jsonserialize.php + * @see \JsonSerializable::jsonSerialize() + */ + public function jsonSerialize(): array + { + return [ + 'collection' => $this->collection->jsonSerialize(), + 'sortinfo' => $this->sortInfo->jsonSerialize(), + 'fromRecord' => $this->fromRecord(), + 'toRecord' => $this->toRecord(), + 'totalRecords' => $this->totalRecords(), + 'currentPage' => $this->currentPage(), + 'lastPage' => $this->lastPage(), + 'perPage' => $this->perPage(), + ]; + } +} diff --git a/src/Collections/Linear/Queue.php b/src/Collections/Linear/Queue.php new file mode 100644 index 0000000..ee39ead --- /dev/null +++ b/src/Collections/Linear/Queue.php @@ -0,0 +1,115 @@ +push($element); + } + } + } + + /** + * Returns a copy of the current Queue object. + * + * @return Queue + */ + public function copy(): self + { + return new Queue($this->toArray()); + } + + /** + * Returns the next element in the Queue, without removing it. + * + * If the Queue has no elements, it will return NULL. + * + * @return string|NULL + */ + public function peek(): ?string + { + // Validates the Queue has elements. + if ($this->count() === 0) { + return null; + } + + return $this->list[0]; + } + + /** + * Returns the next element in the Queue, while removing it. + * + * If the Queue has no elements, it will return NULL. + * + * @return string|NULL + */ + public function pop(): ?string + { + return \array_shift($this->list); + } + + /** + * Adds a new element to the Queue. + * + * @param string $element - Element to be added to the Queue. + * + * @throws \InvalidArgumentException - If supplied element is not a non empty string. + * @return void + */ + public function push(string $element): void + { + // Validates provided parameter. + if (\strlen(\trim($element)) === 0) { + throw new \InvalidArgumentException("Supplied element must be a non empty string."); + } + + // Adds element to the Queue. + $this->list[] = $element; + } +} diff --git a/src/Collections/Linear/README.md b/src/Collections/Linear/README.md new file mode 100644 index 0000000..bc9ee0e --- /dev/null +++ b/src/Collections/Linear/README.md @@ -0,0 +1,31 @@ +# Linear Collections + +## Lists + +In a **List**, the order of data items is significant. Duplicate data items are permitted. Examples of +operations on lists are searching for a data item in the list and determining its location (if it is present), +removing a data item from the list, adding a data item to the list at a specific location, etc. If the +principal operations on the list are to be the addition of data items at one end and the removal of data items +at the other, it will generally be called a queue or **FIFO**. If the principal operations are the addition and +removal of data items at just one end, it will be called a stack or **LIFO**. In both cases, data items are maintained +within the collection in the same order (unless they are removed and re-inserted somewhere else) and so these +are special cases of the list Collection. Other specialized operations on lists include sorting, where, again, +the order of data items is of great importance. + +## Stacks + +A **Stack** is a **LIFO** data structure with two principal operations: +- **push**, which adds an element to the "top" of the Collection. +- **pop**, which removes the top element. + +## Queues + +A **Queue** is a **LIFO** data structure with two principal operations: +- **push**, which adds an element to the "top" of the Collection. +- **pop**, which removes the first element in the Collection. + +## Priority queues + +In a **Priority Queue**, the tracks of the minimum or maximum data item in the collection are kept, according to +some ordering criterion, and the order of the other data items does not matter. One may think of a **Priority Queue** +as a list that always keeps the minimum or maximum at the head, while the remaining elements are kept in a _bag_. diff --git a/src/Collections/Linear/Stack.php b/src/Collections/Linear/Stack.php new file mode 100644 index 0000000..705a48f --- /dev/null +++ b/src/Collections/Linear/Stack.php @@ -0,0 +1,117 @@ +push($element); + } + } + } + + /** + * Returns a copy of the current Stack object. + * + * @return Stack + */ + public function copy(): self + { + return new Stack( + $this->toArray() + ); + } + + /** + * Returns the next element in the Stack, without removing it. + * + * If the Stack has no elements, it will return NULL. + * + * @return string|NULL + */ + public function peek(): ?string + { + // Validates the Stack has elements. + if ($this->count() === 0) { + return null; + } + + return $this->list[$this->count() - 1]; + } + + /** + * Returns the next element in the Stack, while removing it. + * + * If the Stack has no elements, it will return NULL. + * + * @return string|NULL + */ + public function pop(): ?string + { + return \array_pop($this->list); + } + + /** + * Adds a new element to the Stack. + * + * @param string $element - Element to be added to the Stack. + * + * @throws \InvalidArgumentException - If supplied element is not a non empty string. + * @return void + */ + public function push(string $element): void + { + // Validates provided parameter. + if (\strlen(\trim($element)) === 0) { + throw new \InvalidArgumentException("Supplied element must be a non empty string."); + } + + // Adds element to the Stack. + $this->list[] = $element; + } +} diff --git a/src/Collections/README.md b/src/Collections/README.md new file mode 100644 index 0000000..d9969fd --- /dev/null +++ b/src/Collections/README.md @@ -0,0 +1,73 @@ +# Collection (abstract data type) + +In computer science, a **Collection** or container is a grouping of some variable number of data items +(possibly zero) that have some shared significance to the problem being solved and need to be operated +upon together in some controlled fashion. Generally, the data items will be of the same type or, in +languages supporting inheritance, derived from some common ancestor type. A **Collection** is a concept +applicable to abstract data types, and does not prescribe a specific implementation as a concrete data +structure, though often there is a conventional choice. + +Examples of collections include lists, sets, multisets, trees and graphs. + +Fixed-size arrays (or tables) are usually not considered a collection because they hold a fixed number +of data items, although they commonly play a role in the implementation of collections. Variable-size +arrays are generally considered collections. + +More information about this ([here](https://en.wikipedia.org/wiki/Collection_(abstract_data_type))) + +## Linear Collections + +### Lists + +In a **List**, the order of data items is significant. Duplicate data items are permitted. Examples of +operations on lists are searching for a data item in the list and determining its location (if it is present), +removing a data item from the list, adding a data item to the list at a specific location, etc. If the +principal operations on the list are to be the addition of data items at one end and the removal of data items +at the other, it will generally be called a queue or **FIFO**. If the principal operations are the addition and +removal of data items at just one end, it will be called a stack or **LIFO**. In both cases, data items are maintained +within the collection in the same order (unless they are removed and re-inserted somewhere else) and so these +are special cases of the list Collection. Other specialized operations on lists include sorting, where, again, +the order of data items is of great importance. + +### Stacks + +A **Stack** is a **LIFO** data structure with two principal operations: +- **push**, which adds an element to the "top" of the Collection. +- **pop**, which removes the top element. + +### Queues + +A **Queue** is a **LIFO** data structure with two principal operations: +- **push**, which adds an element to the "top" of the Collection. +- **pop**, which removes the first element in the Collection. + +### Priority queues + +In a **Priority Queue**, the tracks of the minimum or maximum data item in the collection are kept, according to +some ordering criterion, and the order of the other data items does not matter. One may think of a **Priority Queue** +as a list that always keeps the minimum or maximum at the head, while the remaining elements are kept in a _bag_. + +## Associative Collections + +### Store / Set + +In a **Set**, the order of data items does not matter (or is undefined) but duplicate data items are not permitted. +Examples of operations on **Sets** are the addition and removal of data items and searching for a data item in the +**Set**. + +Some languages support **Sets** directly. In others, **Sets** can be implemented by a hash table with dummy values; +only the keys are used in representing the **Set**. + +### Multisets / Bag + +In a **Multiset** (or _**Bag**_), like in a **Set**, the order of data items does not matter, but in this case +duplicate data items are permitted. Examples of operations on **Multisets** are the addition and removal of data items +and determining how many duplicates of a particular data item are present in the **Multiset**. + +**Multisets** can be transformed into **Lists** by the action of sorting. + +### Associative arrays / Map / Dictionary / Lookup Table / Hash + +In an **Associative Array** (or **Map**, **Dictionary**, **Lookup table**), like in a **Dictionary**, a _lookup_ on +a key (like a word) provides a value (like a definition). The value might be a reference to a compound data structure. +A _Hash Table_ is usually an efficient implementation, and thus this data type is often known as a "_hash_". From d908f48431954f45032c343a50e3cf59e293d436 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Thu, 27 May 2021 15:39:19 +0100 Subject: [PATCH 026/193] feat: Add initial Trait namespace --- .../Datetime/CanAddAndSubtractPartsTrait.php | 311 ++++++++++++++++++ .../Datetime/CanFormatOutputTrait.php | 214 ++++++++++++ .../Datetime/CanRetrievePartsTrait.php | 140 ++++++++ .../Datatypes/Datetime/CanSetPartsTrait.php | 164 +++++++++ .../Datetime/HasStaticMethodsTrait.php | 122 +++++++ .../CanLoadAndSerializeDataTrait.php | 97 ++++++ .../HasStaticFactoryMethodsTrait.php | 29 ++ .../String/HasManipulationMethodsTrait .php | 146 ++++++++ .../String/HasReportingMethodsTrait.php | 49 +++ .../String/HasStaticMethodsTrait.php | 27 ++ .../Entities/General/HasActiveTrait.php | 37 +++ src/Traits/Entities/General/HasAliasTrait.php | 52 +++ .../Entities/General/HasCreatedAtTrait.php | 39 +++ .../Entities/General/HasDeletedAtTrait.php | 51 +++ src/Traits/Entities/General/HasEmailTrait.php | 39 +++ .../Entities/General/HasFeatureTrait.php | 37 +++ src/Traits/Entities/General/HasHitsTrait.php | 47 +++ src/Traits/Entities/General/HasNameTrait.php | 46 +++ .../Entities/General/HasOrderingTrait.php | 47 +++ .../General/HasPublishedTimestampsTrait.php | 18 + .../Entities/General/HasPublishedTrait.php | 37 +++ .../Entities/General/HasSeoFieldsTrait.php | 143 ++++++++ .../Entities/General/HasTimestampsTrait.php | 18 + .../Entities/General/HasUpdatedAtTrait.php | 39 +++ src/Traits/Entities/General/HasUuidTrait.php | 37 +++ src/Traits/Entities/General/README.md | 1 + .../Entities/Location/HasAddressTrait.php | 37 +++ src/Traits/Entities/Location/HasCityTrait.php | 37 +++ .../Entities/Location/HasCountryTrait.php | 37 +++ .../Entities/Location/HasPostalCodeTrait.php | 37 +++ .../Location/HasStreetAdditionalTrait.php | 37 +++ .../Location/HasStreetNumberTrait.php | 37 +++ .../Entities/Location/HasStreetTrait.php | 37 +++ src/Traits/Entities/Location/README.md | 1 + .../Personal/HasCountryOfBirthTrait.php | 43 +++ .../Entities/Personal/HasDateOfBirthTrait.php | 39 +++ .../Entities/Personal/HasGenderTrait.php | 45 +++ .../Entities/Personal/HasSurnameTrait.php | 46 +++ src/Traits/Entities/Personal/README.md | 1 + src/Traits/README.md | 1 + .../HasConversionToPrimitiveValuesTrait.php | 44 +++ .../ValueObjects/HasFieldCastingTrait.php | 72 ++++ .../ValueObjects/HasGuardedFieldsTrait.php | 37 +++ .../ValueObjects/HasMappedFieldsTrait.php | 61 ++++ .../ValueObjects/HasRequiredFieldsTrait.php | 44 +++ .../ValueObjects/HasRuleProcessingTrait.php | 54 +++ src/Traits/ValueObjects/README.md | 1 + 47 files changed, 2735 insertions(+) create mode 100644 src/Traits/Datatypes/Datetime/CanAddAndSubtractPartsTrait.php create mode 100644 src/Traits/Datatypes/Datetime/CanFormatOutputTrait.php create mode 100644 src/Traits/Datatypes/Datetime/CanRetrievePartsTrait.php create mode 100644 src/Traits/Datatypes/Datetime/CanSetPartsTrait.php create mode 100644 src/Traits/Datatypes/Datetime/HasStaticMethodsTrait.php create mode 100644 src/Traits/Datatypes/EmailAddress/CanLoadAndSerializeDataTrait.php create mode 100644 src/Traits/Datatypes/EmailAddress/HasStaticFactoryMethodsTrait.php create mode 100644 src/Traits/Datatypes/String/HasManipulationMethodsTrait .php create mode 100644 src/Traits/Datatypes/String/HasReportingMethodsTrait.php create mode 100644 src/Traits/Datatypes/String/HasStaticMethodsTrait.php create mode 100755 src/Traits/Entities/General/HasActiveTrait.php create mode 100755 src/Traits/Entities/General/HasAliasTrait.php create mode 100644 src/Traits/Entities/General/HasCreatedAtTrait.php create mode 100644 src/Traits/Entities/General/HasDeletedAtTrait.php create mode 100644 src/Traits/Entities/General/HasEmailTrait.php create mode 100755 src/Traits/Entities/General/HasFeatureTrait.php create mode 100755 src/Traits/Entities/General/HasHitsTrait.php create mode 100755 src/Traits/Entities/General/HasNameTrait.php create mode 100755 src/Traits/Entities/General/HasOrderingTrait.php create mode 100755 src/Traits/Entities/General/HasPublishedTimestampsTrait.php create mode 100755 src/Traits/Entities/General/HasPublishedTrait.php create mode 100755 src/Traits/Entities/General/HasSeoFieldsTrait.php create mode 100755 src/Traits/Entities/General/HasTimestampsTrait.php create mode 100644 src/Traits/Entities/General/HasUpdatedAtTrait.php create mode 100644 src/Traits/Entities/General/HasUuidTrait.php create mode 100644 src/Traits/Entities/General/README.md create mode 100644 src/Traits/Entities/Location/HasAddressTrait.php create mode 100644 src/Traits/Entities/Location/HasCityTrait.php create mode 100644 src/Traits/Entities/Location/HasCountryTrait.php create mode 100644 src/Traits/Entities/Location/HasPostalCodeTrait.php create mode 100644 src/Traits/Entities/Location/HasStreetAdditionalTrait.php create mode 100644 src/Traits/Entities/Location/HasStreetNumberTrait.php create mode 100644 src/Traits/Entities/Location/HasStreetTrait.php create mode 100644 src/Traits/Entities/Location/README.md create mode 100644 src/Traits/Entities/Personal/HasCountryOfBirthTrait.php create mode 100644 src/Traits/Entities/Personal/HasDateOfBirthTrait.php create mode 100644 src/Traits/Entities/Personal/HasGenderTrait.php create mode 100755 src/Traits/Entities/Personal/HasSurnameTrait.php create mode 100644 src/Traits/Entities/Personal/README.md create mode 100755 src/Traits/README.md create mode 100644 src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php create mode 100644 src/Traits/ValueObjects/HasFieldCastingTrait.php create mode 100644 src/Traits/ValueObjects/HasGuardedFieldsTrait.php create mode 100644 src/Traits/ValueObjects/HasMappedFieldsTrait.php create mode 100644 src/Traits/ValueObjects/HasRequiredFieldsTrait.php create mode 100644 src/Traits/ValueObjects/HasRuleProcessingTrait.php create mode 100755 src/Traits/ValueObjects/README.md diff --git a/src/Traits/Datatypes/Datetime/CanAddAndSubtractPartsTrait.php b/src/Traits/Datatypes/Datetime/CanAddAndSubtractPartsTrait.php new file mode 100644 index 0000000..4ffc31d --- /dev/null +++ b/src/Traits/Datatypes/Datetime/CanAddAndSubtractPartsTrait.php @@ -0,0 +1,311 @@ +addYears(1); + + return $this; + } + + /** + * Add the supplied number of Years to the instance. + * + * Supports chaining. + * + * @param int $years - Number of years to add to instance. Supports negative numbers for subtraction. + * + * @return self + */ + public function addYears(int $years): self + { + $this->carbon->addYears($years); + + return $this; + } + + /** + * Returns the different between the current instance an the provided one, in Years. + * + * @param self $dt - instance to compare with. + * @param bool $absolute - Gets the absolute of the difference. + * + * @return int + */ + public function differenceInYears(self $dt, bool $absolute = true): int + { + return $this->carbon->diffInYears( + Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), + $absolute + ); + } + + /** + * Add a single Month to the instance. + * + * Supports chaining. + * + * @return self + */ + public function addMonth(): self + { + $this->addMonths(1); + + return $this; + } + + /** + * Add the supplied number of Months to the instance. + * + * Supports chaining. + * + * @param int $months - Number of Months to add to instance. Supports negative numbers for subtraction. + * + * @return self + */ + public function addMonths(int $months): self + { + $this->carbon->addMonths($months); + + return $this; + } + + /** + * Returns the different between the current instance an the provided one, in Months. + * + * @param self $dt - instance to compare with. + * @param bool $absolute - Gets the absolute of the difference. + * + * @return int + */ + public function differenceInMonths(self $dt, bool $absolute = true): int + { + return $this->carbon->diffInMonths( + Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), + $absolute + ); + } + + /** + * Returns the different between the current instance an the provided one, in Weeks. + * + * @param self $dt - instance to compare with. + * @param bool $absolute - Gets the absolute of the difference. + * + * @return int + */ + public function differenceInWeeks(self $dt, bool $absolute = true): int + { + return $this->carbon->diffInWeeks( + Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), + $absolute + ); + } + + /** + * Add a single Day to the instance. + * + * Supports chaining. + * + * @return self + */ + public function addDay(): self + { + $this->addDays(1); + + return $this; + } + + /** + * Add the supplied number of Days to the instance. + * + * Supports chaining. + * + * @param int $days - Number of Days to add to instance. Supports negative numbers for subtraction. + * + * @return self + */ + public function addDays(int $days): self + { + $this->carbon->addDays($days); + + return $this; + } + + /** + * Returns the different between the current instance an the provided one, in Days. + * + * @param self $dt - instance to compare with. + * @param bool $absolute - Gets the absolute of the difference. + * + * @return int + */ + public function differenceInDays(self $dt, bool $absolute = true): int + { + return $this->carbon->diffInDays( + Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), + $absolute + ); + } + + /** + * Add a single Hour to the instance. + * + * Supports chaining. + * + * @return self + */ + public function addHour(): self + { + $this->addHours(1); + + return $this; + } + + /** + * Add the supplied number of Hours to the instance. + * + * Supports chaining. + * + * @param int $hours - Number of Hours to add to instance. Supports negative numbers for subtraction. + * + * @return self + */ + public function addHours(int $hours): self + { + $this->carbon->addHours($hours); + + return $this; + } + + /** + * Returns the different between the current instance an the provided one, in Hours. + * + * @param self $dt - instance to compare with. + * @param bool $absolute - Gets the absolute of the difference. + * + * @return int + */ + public function differenceInHours(self $dt, bool $absolute = true): int + { + return $this->carbon->diffInHours( + Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), + $absolute + ); + } + + /** + * Add a single Minute to the instance. + * + * Supports chaining. + * + * @return self + */ + public function addMinute(): self + { + $this->addMinutes(1); + + return $this; + } + + /** + * Add the supplied number of Minutes to the instance. + * + * Supports chaining. + * + * @param int $minutes - Number of Minutes to add to instance. Supports negative numbers for subtraction. + * + * @return self + */ + public function addMinutes(int $minutes): self + { + $this->carbon->addMinutes($minutes); + + return $this; + } + + /** + * Returns the different between the current instance an the provided one, in Minutes. + * + * @param self $dt - instance to compare with. + * @param bool $absolute - Gets the absolute of the difference. + * + * @return int + */ + public function differenceInMinutes(self $dt, bool $absolute = true): int + { + return $this->carbon->diffInMinutes( + Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), + $absolute + ); + } + + /** + * Add a single Second to the instance. + * + * Supports chaining. + * + * @return self + */ + public function addSecond(): self + { + $this->addSeconds(1); + + return $this; + } + + /** + * Add the supplied number of Seconds to the instance. + * + * Supports chaining. + * + * @param int $seconds - Number of Seconds to add to instance. Supports negative numbers for subtraction. + * + * @return self + */ + public function addSeconds(int $seconds): self + { + $this->carbon->addSeconds($seconds); + + return $this; + } + + /** + * Returns the different between the current instance an the provided one, in Seconds. + * + * @param self $dt - instance to compare with. + * @param bool $absolute - Gets the absolute of the difference. + * + * @return int + */ + public function differenceInSeconds(self $dt, bool $absolute = true): int + { + return $this->carbon->diffInSeconds( + Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), + $absolute + ); + } +} diff --git a/src/Traits/Datatypes/Datetime/CanFormatOutputTrait.php b/src/Traits/Datatypes/Datetime/CanFormatOutputTrait.php new file mode 100644 index 0000000..e53f2a9 --- /dev/null +++ b/src/Traits/Datatypes/Datetime/CanFormatOutputTrait.php @@ -0,0 +1,214 @@ +carbon->format($format); + } + + /** + * Retrieves the Timestamp representation from the instance. + * + * @return integer + */ + public function toTimestamp(): int + { + return $this->carbon->timestamp; + } + + /** + * Format the instance as Date. + * + * @return string + */ + public function toDateString(): string + { + return $this->carbon->toDateString(); + } + + /** + * Format the instance as a readable Date. + * + * @return string + */ + public function toFormattedDateString(): string + { + return $this->carbon->toFormattedDateString(); + } + + /** + * Format the instance as Time. + * + * @return string + */ + public function toTimeString(): string + { + return $this->carbon->toTimeString(); + } + + /** + * Format the instance as Date and Time. + * + * @return string + */ + public function toDateTimeString(): string + { + return $this->carbon->toDateTimeString(); + } + + /** + * Format the instance as ATOM + * + * @return string + */ + public function toAtomString(): string + { + return $this->carbon->toAtomString(); + } + + /** + * Format the instance as COOKIE. + * + * @return string + */ + public function toCookieString(): string + { + return $this->carbon->toCookieString(); + } + + /** + * Format the instance as ISO8601. + * + * @return string + */ + public function toIso8601String(): string + { + return $this->carbon->toIso8601String(); + } + + /** + * Format the instance as RFC822. + * + * @return string + */ + public function toRfc822String(): string + { + return $this->carbon->toRfc822String(); + } + + /** + * Format the instance as RFC850. + * + * @return string + */ + public function toRfc850String(): string + { + return $this->carbon->toRfc850String(); + } + + /** + * Format the instance as RFC1036. + * + * @return string + */ + public function toRfc1036String(): string + { + return $this->carbon->toRfc1036String(); + } + + /** + * Format the instance as RFC1123. + * + * @return string + */ + public function toRfc1123String(): string + { + return $this->carbon->toRfc1123String(); + } + + /** + * Format the instance as RFC2822. + * + * @return string + */ + public function toRfc2822String(): string + { + return $this->carbon->toRfc2822String(); + } + + /** + * Format the instance as RFC3339. + * + * @return string + */ + public function toRfc3339String(): string + { + return $this->carbon->toRfc3339String(); + } + + /** + * Format the instance as RSS. + * + * @return string + */ + public function toRssString(): string + { + return $this->carbon->toRssString(); + } + + /** + * Format the instance as W3C. + * + * @return string + */ + public function toW3cString(): string + { + return $this->carbon->toW3cString(); + } + + /** + * Format the instance to a valid DatetimeBox's value string. + * + * @return string + */ + public function toDatetimeBoxString(): string + { + return $this->carbon->format('Y-m-d\TH:i:s'); + } + + /** + * Retrieves the String representation of the Datatype. + * + * @return string + */ + public function __toString(): string + { + return $this->toDateTimeString(); + } +} diff --git a/src/Traits/Datatypes/Datetime/CanRetrievePartsTrait.php b/src/Traits/Datatypes/Datetime/CanRetrievePartsTrait.php new file mode 100644 index 0000000..3139a17 --- /dev/null +++ b/src/Traits/Datatypes/Datetime/CanRetrievePartsTrait.php @@ -0,0 +1,140 @@ +carbon->year; + } + + /** + * Returns the Month part of the Datetime instance. + * + * @return int + */ + public function partMonth(): int + { + return $this->carbon->month; + } + + /** + * Returns the Day part of the Datetime instance. + * + * @return int + */ + public function partDay(): int + { + return $this->carbon->day; + } + + /** + * Returns the Hour part of the Datetime instance. + * + * @return int + */ + public function partHour(): int + { + return $this->carbon->hour; + } + + /** + * Returns the Minute part of the Datetime instance. + * + * @return int + */ + public function partMinute(): int + { + return $this->carbon->minute; + } + + /** + * Returns the Second part of the Datetime instance. + * + * @return int + */ + public function partSecond(): int + { + return $this->carbon->second; + } + + /** + * Returns the Week number in the given Month. + * + * 1 through 5. + * + * @return int + */ + public function weekOfMonth(): int + { + return $this->carbon->weekOfMonth; + } + + /** + * Returns the Week number in the given Year. + * + * ISO-8601 week number of year, weeks starting on Monday. + * + * @return int + */ + public function weekOfYear(): int + { + return $this->carbon->weekOfYear; + } + + /** + * Returns the Day of the Week for the Datetime instance. + * + * 0 (for Sunday) through 6 (for Saturday) + * + * @return int + */ + public function dayOfWeek(): int + { + return $this->carbon->dayOfWeek; + } + + /** + * Returns the Day of the Year. + * + * 0 through 365. + * + * @return int + */ + public function dayOfYear(): int + { + return $this->carbon->dayOfYear; + } + + /** + * Returns the total number of Days for the Month set in the Datetime instance. + * + * @return int + */ + public function daysInMonth(): int + { + return $this->carbon->daysInMonth; + } +} diff --git a/src/Traits/Datatypes/Datetime/CanSetPartsTrait.php b/src/Traits/Datatypes/Datetime/CanSetPartsTrait.php new file mode 100644 index 0000000..89d207e --- /dev/null +++ b/src/Traits/Datatypes/Datetime/CanSetPartsTrait.php @@ -0,0 +1,164 @@ +carbon->year($year); + + return $this; + } + + /** + * Sets the Month part of the instance. + * + * Supports chaining. + * + * @param int $month - Month to be set on the instance. + * + * @throws PositiveIntegerException - If a negative parameter was supplied. + * + * @return self + */ + public function setMonth(int $month): self + { + // Validates provided parameter. + if ($month <= 0) { + throw new PositiveIntegerException(); + } + + // Sets the month on the carbon's instance. + $this->carbon->month($month); + + return $this; + } + + /** + * Sets the Day part of the instance. + * + * Supports chaining. + * + * @param int $day - Day to be set on the instance. + * + * @throws PositiveIntegerException - If a negative parameter was supplied. + * + * @return self + */ + public function setDay(int $day): self + { + // Validates provided parameter. + if ($day <= 0) { + throw new PositiveIntegerException(); + } + + // Sets the day on the carbon's instance. + $this->carbon->day($day); + + return $this; + } + + /** + * Sets the Hour part of the instance. + * + * Supports chaining. + * + * @param int $hour - Hour to be set on the instance. + * + * @throws PositiveIntegerException - If a negative parameter was supplied. + * + * @return self + */ + public function setHour(int $hour): self + { + // Validates provided parameter. + if ($hour < 0) { + throw new PositiveIntegerException(); + } + + // Sets the hour on the carbon's instance. + $this->carbon->hour($hour); + + return $this; + } + + /** + * Sets the Minute part of the instance. + * + * Supports chaining. + * + * @param int $minute - Minute to be set on the instance. + * + * @throws PositiveIntegerException - If a negative parameter was supplied. + * + * @return self + */ + public function setMinute(int $minute): self + { + // Validates provided parameter. + if ($minute < 0) { + throw new PositiveIntegerException(); + } + + // Sets the minute on the carbon's instance. + $this->carbon->minute($minute); + + return $this; + } + + /** + * Sets the Second part of the instance. + * + * Supports chaining. + * + * @param int $second - Second to be set on the instance. + * + * @throws PositiveIntegerException - If a negative parameter was supplied. + * + * @return self + */ + public function setSecond(int $second): self + { + // Validates provided parameter. + if ($second < 0) { + throw new PositiveIntegerException(); + } + + // Sets the second on the carbon's instance. + $this->carbon->second($second); + + return $this; + } +} diff --git a/src/Traits/Datatypes/Datetime/HasStaticMethodsTrait.php b/src/Traits/Datatypes/Datetime/HasStaticMethodsTrait.php new file mode 100644 index 0000000..d6f0cbd --- /dev/null +++ b/src/Traits/Datatypes/Datetime/HasStaticMethodsTrait.php @@ -0,0 +1,122 @@ +username = $parts[0]; + + // Processes the right side of the e-mail address. + $host = \explode('.', $parts[1]); + $this->tld = \array_pop($host); + $this->domain = \implode('.', $host); + } + + /** + * Serializes the contents of the class. + * + * @return string + * + * {@inheritDoc} + * @see \Serializable::serialize() + */ + public function serialize() + { + return \serialize($this->__toString()); + } + + /** + * Unserializes back the contents of the class. + * + * @return void + * + * {@inheritDoc} + * @see \Serializable::unserialize() + */ + public function unserialize($serialized) + { + $this->loadEmail( + \unserialize($serialized) + ); + } + + /** + * Returns the String representation of the object. + * + * @return string + */ + public function __toString(): string + { + return ($this->username . '@' . $this->domain . '.' . $this->tld); + } +} diff --git a/src/Traits/Datatypes/EmailAddress/HasStaticFactoryMethodsTrait.php b/src/Traits/Datatypes/EmailAddress/HasStaticFactoryMethodsTrait.php new file mode 100644 index 0000000..96d0a12 --- /dev/null +++ b/src/Traits/Datatypes/EmailAddress/HasStaticFactoryMethodsTrait.php @@ -0,0 +1,29 @@ +value) + ); + } + + /** + * Right Trims the String's value. + * + * This method will return a new instance of Str. + * + * @return Str + */ + public function trimRight(): Str + { + return new Str( + \rtrim($this->value) + ); + } + + /** + * Left Trims the String's value. + * + * This method will return a new instance of Str. + * + * @return Str + */ + public function trimLeft(): Str + { + return new Str( + \ltrim($this->value) + ); + } + + /** + * Lower Cases String's value. + * + * This method will return a new instance of Str. + * + * @return Str + */ + public function lowercase(): Str + { + return new Str( + \strtolower($this->value) + ); + } + + /** + * Upper Cases String's value. + * + * This method will return a new instance of Str. + * + * @return Str + */ + public function uppercase(): Str + { + return new Str( + \strtoupper($this->value) + ); + } + + /** + * Lower Cases first character of the String's value. + * + * This method will return a new instance of Str. + * + * @return Str + */ + public function lowercaseFirst(): Str + { + return new Str( + \lcfirst($this->value) + ); + } + + /** + * Upper Cases first character of the String's value. + * + * This method will return a new instance of Str. + * + * @return Str + */ + public function uppercaseFirst(): Str + { + return new Str( + \ucfirst($this->value) + ); + } + + /** + * Upper Cases all words of the String's value. + * + * This method will return a new instance of Str. + * + * @return Str + */ + public function uppercaseWords(): Str + { + return new Str( + \ucwords($this->value) + ); + } + + /** + * Replaces a given portion of the String for another. + * + * This method will return a new instance of Str. + * + * @param string $search - String to search for. + * @param string $replace - String replacement. + * @return Str + */ + public function replace(string $search, string $replace): Str + { + return new Str( + \str_replace($search, $replace, $this->value) + ); + } +} diff --git a/src/Traits/Datatypes/String/HasReportingMethodsTrait.php b/src/Traits/Datatypes/String/HasReportingMethodsTrait.php new file mode 100644 index 0000000..7a351c1 --- /dev/null +++ b/src/Traits/Datatypes/String/HasReportingMethodsTrait.php @@ -0,0 +1,49 @@ +value); + } + + /** + * Searches the String for a given sub-string's position. + * + * @param string $search - String to search for. + * @return int + */ + public function position(string $search): int + { + return \strpos($this->value, $search); + } + + /** + * Counts the number of words in the String. + * + * @return int + */ + public function wordCount(): int + { + return \str_word_count($this->value); + } +} diff --git a/src/Traits/Datatypes/String/HasStaticMethodsTrait.php b/src/Traits/Datatypes/String/HasStaticMethodsTrait.php new file mode 100644 index 0000000..0044972 --- /dev/null +++ b/src/Traits/Datatypes/String/HasStaticMethodsTrait.php @@ -0,0 +1,27 @@ +active = $active; + } + + /** + * Returns TRUE if the record is marked as ACTIVE in the system. + * + * @return bool + */ + public function active(): bool + { + return $this->active; + } +} diff --git a/src/Traits/Entities/General/HasAliasTrait.php b/src/Traits/Entities/General/HasAliasTrait.php new file mode 100755 index 0000000..abcfea6 --- /dev/null +++ b/src/Traits/Entities/General/HasAliasTrait.php @@ -0,0 +1,52 @@ +alias = $alias; + } + + /** + * Returns the Entity's alias. + * + * @return string + */ + public function alias(): string + { + return $this->alias; + } +} diff --git a/src/Traits/Entities/General/HasCreatedAtTrait.php b/src/Traits/Entities/General/HasCreatedAtTrait.php new file mode 100644 index 0000000..803b6cb --- /dev/null +++ b/src/Traits/Entities/General/HasCreatedAtTrait.php @@ -0,0 +1,39 @@ +created_at = Datetime::fromString($timestamp); + } + + /** + * Returns a Datetime representation from the instant the record was last updated. + * + * @return Datetime + */ + public function createdAt(): Datetime + { + return $this->created_at; + } +} diff --git a/src/Traits/Entities/General/HasDeletedAtTrait.php b/src/Traits/Entities/General/HasDeletedAtTrait.php new file mode 100644 index 0000000..fefa540 --- /dev/null +++ b/src/Traits/Entities/General/HasDeletedAtTrait.php @@ -0,0 +1,51 @@ +deleted_at = ($timestamp ? Datetime::fromString($timestamp) : null); + } + + /** + * Returns a Datetime representation from the instant the record was marked as deleted. + * + * @return Datetime|null + */ + public function deletedAt(): ?Datetime + { + return $this->deleted_at; + } + + /** + * Returns TRUE if the record is marked as deleted in the system. + * + * @return boolean + */ + public function isDeleted(): bool + { + return ($this->deleted_at !== null); + } +} diff --git a/src/Traits/Entities/General/HasEmailTrait.php b/src/Traits/Entities/General/HasEmailTrait.php new file mode 100644 index 0000000..d232899 --- /dev/null +++ b/src/Traits/Entities/General/HasEmailTrait.php @@ -0,0 +1,39 @@ +email = EmailAddress::fromString($email); + } + + /** + * Returns an EmailAddress representation for the record's E-mail Address. + * + * @return EmailAddress|null + */ + public function email(): ?EmailAddress + { + return $this->email; + } +} diff --git a/src/Traits/Entities/General/HasFeatureTrait.php b/src/Traits/Entities/General/HasFeatureTrait.php new file mode 100755 index 0000000..e19e62e --- /dev/null +++ b/src/Traits/Entities/General/HasFeatureTrait.php @@ -0,0 +1,37 @@ +Featured
in the system. */ + protected bool $featured = false; + + /** + * Sets the FEATURED value of an Entity. + * + * @param bool $featured - New featured value. + * @return void + */ + protected function castFeatured(bool $featured): void + { + $this->featured = $featured; + } + + /** + * Returns TRUE if the record is marked as FEATURED in the system. + * + * @return bool + */ + public function featured(): bool + { + return $this->featured; + } +} diff --git a/src/Traits/Entities/General/HasHitsTrait.php b/src/Traits/Entities/General/HasHitsTrait.php new file mode 100755 index 0000000..b57a302 --- /dev/null +++ b/src/Traits/Entities/General/HasHitsTrait.php @@ -0,0 +1,47 @@ +hits = $hits; + } + + /** + * Returns the number of Hits. + * + * @return int + */ + public function hits(): int + { + return $this->hits; + } +} diff --git a/src/Traits/Entities/General/HasNameTrait.php b/src/Traits/Entities/General/HasNameTrait.php new file mode 100755 index 0000000..cd31b79 --- /dev/null +++ b/src/Traits/Entities/General/HasNameTrait.php @@ -0,0 +1,46 @@ +name = $name; + } + + /** + * Returns the Instance's name. + * + * @return string + */ + public function name(): string + { + return $this->name; + } +} diff --git a/src/Traits/Entities/General/HasOrderingTrait.php b/src/Traits/Entities/General/HasOrderingTrait.php new file mode 100755 index 0000000..c7fc9b4 --- /dev/null +++ b/src/Traits/Entities/General/HasOrderingTrait.php @@ -0,0 +1,47 @@ +ordering = $order; + } + + /** + * The ordering of this record, in a parent container's context. + * + * @return int + */ + public function ordering(): int + { + return $this->ordering; + } +} diff --git a/src/Traits/Entities/General/HasPublishedTimestampsTrait.php b/src/Traits/Entities/General/HasPublishedTimestampsTrait.php new file mode 100755 index 0000000..444dbfa --- /dev/null +++ b/src/Traits/Entities/General/HasPublishedTimestampsTrait.php @@ -0,0 +1,18 @@ +published = $published; + } + + /** + * Returns TRUE if the record is marked as PUBLISHED for the frontend. + * + * @return bool + */ + public function published(): bool + { + return $this->published; + } +} diff --git a/src/Traits/Entities/General/HasSeoFieldsTrait.php b/src/Traits/Entities/General/HasSeoFieldsTrait.php new file mode 100755 index 0000000..7c1817d --- /dev/null +++ b/src/Traits/Entities/General/HasSeoFieldsTrait.php @@ -0,0 +1,143 @@ +. + * Setting the value. + * + * @param string|null $title - New value to be set on Attribute. + * + * @throws InvalidStringLengthException - Supplied Seo Title must be a non empty string. + * + * @link https://seopressor.com/blog/google-title-meta-descriptions-length + * @return void + */ + protected function castSeoTitle(?string $title = null): void + { + // Setting the max length for Seo description. + if ($title !== null && \strlen(\trim($title)) > 70) { + throw new InvalidStringLengthException("Supplied Seo title must have length up to 70 characters."); + } + + $this->seo_title = $this->seoSanitize($title); + } + + /** + * Checking the character limitations of the . + * Setting the value. + * + * @param string|null $description - New value to be set on Attribute. + * + * @throws InvalidStringLengthException - Supplied Seo Description must be a non empty string. + * + * @link https://seopressor.com/blog/google-title-meta-descriptions-length + * @return void + */ + protected function castSeoDescription(?string $description = null): void + { + // Setting the max length for Seo description. + if ($description !== null && \strlen(\trim($description)) > 160) { + throw new InvalidStringLengthException("Supplied Seo description must have length up to 160 characters."); + } + + $this->seo_description = $this->seoSanitize($description); + } + + /** + * Checking the character limitations of the . + * Setting the value. + * + * @param string|null $keywords - New value to be set on Attribute. + * + * @throws InvalidStringLengthException - Supplied Seo Keywords must be a non empty string. + * + * @link https://www.quora.com/What-is-the-minimum-length-of-a-meta-keyword-in-on-page-SEO + * @return void + */ + protected function castSeoKeywords(string $keywords = null): void + { + // Setting the max length for Seo keywords. + if ($keywords !== null && \strlen(\trim($keywords)) > 255) { + throw new InvalidStringLengthException("Supplied Seo keywords must have length up to 255 characters."); + } + + $this->seo_keywords = $this->seoSanitize($keywords); + } + + /** + * Returns the Entity's seo title. + * + * @return string|null + */ + public function seoTitle(): ?string + { + // If the Seo title is not set it is set to name property. + if ($this->seo_title === null || \strlen(\trim($this->seo_title)) === 0) { + return ( \property_exists($this, 'name') ? $this->{'name'} : null ); + } + + return $this->seo_title; + } + + /** + * Returns the Entity's seo description. + * + * @return string|null + */ + public function seoDescription(): ?string + { + return $this->seo_description; + } + + /** + * Returns the Entity's seo keywords. + * + * @return string|null + */ + public function seoKeywords(): ?string + { + return $this->seo_keywords; + } + + /** + * Sanitizes the individual Seo field in the Entity. + * + * @param string|null $seoField - New Hit's value. + * @return string|null + */ + private function seoSanitize(?string $seoField = null): ?string + { + // Checking if the value is an empty string or a string made of spaces. + if ($seoField !== null && \strlen(\trim($seoField)) === 0) { + $seoField = null; + } + + // If there is a valid string trimming the spaces form the beginning and the end. + if ($seoField !== null) { + $seoField = \trim($seoField); + } + + return $seoField; + } +} diff --git a/src/Traits/Entities/General/HasTimestampsTrait.php b/src/Traits/Entities/General/HasTimestampsTrait.php new file mode 100755 index 0000000..bd152c4 --- /dev/null +++ b/src/Traits/Entities/General/HasTimestampsTrait.php @@ -0,0 +1,18 @@ +updated_at = ($timestamp ? Datetime::fromString($timestamp) : null); + } + + /** + * Returns a Datetime representation from the instant the record was last updated. + * + * @return Datetime|null + */ + public function updatedAt(): ?Datetime + { + return $this->updated_at; + } +} diff --git a/src/Traits/Entities/General/HasUuidTrait.php b/src/Traits/Entities/General/HasUuidTrait.php new file mode 100644 index 0000000..60bcc39 --- /dev/null +++ b/src/Traits/Entities/General/HasUuidTrait.php @@ -0,0 +1,37 @@ +uuid = $uuid; + } + + /** + * Returns the Universal Unique Identifier. + * + * @return string + */ + public function uuid(): string + { + return $this->uuid; + } +} diff --git a/src/Traits/Entities/General/README.md b/src/Traits/Entities/General/README.md new file mode 100644 index 0000000..3e3fe64 --- /dev/null +++ b/src/Traits/Entities/General/README.md @@ -0,0 +1 @@ +# Entity related General Pourpose Traits diff --git a/src/Traits/Entities/Location/HasAddressTrait.php b/src/Traits/Entities/Location/HasAddressTrait.php new file mode 100644 index 0000000..033c96c --- /dev/null +++ b/src/Traits/Entities/Location/HasAddressTrait.php @@ -0,0 +1,37 @@ +address = \trim($address); + } + + /** + * Returns the Entity's Address. + * + * @return string + */ + public function address(): string + { + return $this->address; + } +} diff --git a/src/Traits/Entities/Location/HasCityTrait.php b/src/Traits/Entities/Location/HasCityTrait.php new file mode 100644 index 0000000..9932d10 --- /dev/null +++ b/src/Traits/Entities/Location/HasCityTrait.php @@ -0,0 +1,37 @@ +city = \trim($city); + } + + /** + * Returns the Entity's City. + * + * @return string + */ + public function city(): string + { + return $this->city; + } +} diff --git a/src/Traits/Entities/Location/HasCountryTrait.php b/src/Traits/Entities/Location/HasCountryTrait.php new file mode 100644 index 0000000..f0480db --- /dev/null +++ b/src/Traits/Entities/Location/HasCountryTrait.php @@ -0,0 +1,37 @@ +country = \trim($country); + } + + /** + * Returns the Entity's Country. + * + * @return string + */ + public function country(): string + { + return $this->country; + } +} diff --git a/src/Traits/Entities/Location/HasPostalCodeTrait.php b/src/Traits/Entities/Location/HasPostalCodeTrait.php new file mode 100644 index 0000000..d1bfb2b --- /dev/null +++ b/src/Traits/Entities/Location/HasPostalCodeTrait.php @@ -0,0 +1,37 @@ +postal_code = \trim($postalCode); + } + + /** + * Returns the Entity's Postal Code. + * + * @return string + */ + public function postalCode(): string + { + return $this->postal_code; + } +} diff --git a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php new file mode 100644 index 0000000..0b02ac4 --- /dev/null +++ b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php @@ -0,0 +1,37 @@ +street_additional = \trim($street); + } + + /** + * Returns the Entity's Street Additional. + * + * @return string + */ + public function streetAdditional(): string + { + return $this->street_additional; + } +} diff --git a/src/Traits/Entities/Location/HasStreetNumberTrait.php b/src/Traits/Entities/Location/HasStreetNumberTrait.php new file mode 100644 index 0000000..533812d --- /dev/null +++ b/src/Traits/Entities/Location/HasStreetNumberTrait.php @@ -0,0 +1,37 @@ +street_no = \trim($number); + } + + /** + * Returns the Entity's Street Number. + * + * @return string + */ + public function streetNumber(): string + { + return $this->street_no; + } +} diff --git a/src/Traits/Entities/Location/HasStreetTrait.php b/src/Traits/Entities/Location/HasStreetTrait.php new file mode 100644 index 0000000..b82ccd8 --- /dev/null +++ b/src/Traits/Entities/Location/HasStreetTrait.php @@ -0,0 +1,37 @@ +street = \trim($street); + } + + /** + * Returns the Entity's Street. + * + * @return string + */ + public function street(): string + { + return $this->street; + } +} diff --git a/src/Traits/Entities/Location/README.md b/src/Traits/Entities/Location/README.md new file mode 100644 index 0000000..673ecf8 --- /dev/null +++ b/src/Traits/Entities/Location/README.md @@ -0,0 +1 @@ +# Entity related Location Traits diff --git a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php new file mode 100644 index 0000000..8455ab5 --- /dev/null +++ b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php @@ -0,0 +1,43 @@ +country_of_birth = \trim($country); + } + + /** + * Returns the Entity's Country of Birth. + * + * @return string + */ + public function countryOfBirth(): string + { + return $this->country_of_birth; + } +} diff --git a/src/Traits/Entities/Personal/HasDateOfBirthTrait.php b/src/Traits/Entities/Personal/HasDateOfBirthTrait.php new file mode 100644 index 0000000..4b42614 --- /dev/null +++ b/src/Traits/Entities/Personal/HasDateOfBirthTrait.php @@ -0,0 +1,39 @@ +dob = Datetime::fromString($dob); + } + + /** + * Returns a Datetime representation for the Entity's Date of Birth. + * + * @return Datetime|null + */ + public function dateOfBirth(): ?Datetime + { + return $this->dob; + } +} diff --git a/src/Traits/Entities/Personal/HasGenderTrait.php b/src/Traits/Entities/Personal/HasGenderTrait.php new file mode 100644 index 0000000..459edf5 --- /dev/null +++ b/src/Traits/Entities/Personal/HasGenderTrait.php @@ -0,0 +1,45 @@ +sex = $sex; + } + + /** + * Returns the Entity's Gender. + * + * @return string + */ + public function gender(): string + { + return $this->sex; + } +} diff --git a/src/Traits/Entities/Personal/HasSurnameTrait.php b/src/Traits/Entities/Personal/HasSurnameTrait.php new file mode 100755 index 0000000..78e81dc --- /dev/null +++ b/src/Traits/Entities/Personal/HasSurnameTrait.php @@ -0,0 +1,46 @@ +surname = $surname; + } + + /** + * Returns the Instance's Surname. + * + * @return string + */ + public function surname(): string + { + return $this->surname; + } +} diff --git a/src/Traits/Entities/Personal/README.md b/src/Traits/Entities/Personal/README.md new file mode 100644 index 0000000..7945b58 --- /dev/null +++ b/src/Traits/Entities/Personal/README.md @@ -0,0 +1 @@ +# Entity related Personal Traits diff --git a/src/Traits/README.md b/src/Traits/README.md new file mode 100755 index 0000000..276ea70 --- /dev/null +++ b/src/Traits/README.md @@ -0,0 +1 @@ +# Entity related Traits diff --git a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php new file mode 100644 index 0000000..89630a5 --- /dev/null +++ b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php @@ -0,0 +1,44 @@ + $value) { + + // Returns the string representation of the object, or tries to convert array or object to JSON. + // If is not an Object not an Array, returns the actual value of the Field. + if ($value instanceof AbstractValueObject || $value instanceof EntityCollection) { + $converted[$field] = $value->jsonSerialize(); + } elseif (\method_exists($value, '__toString')) { + $converted[$field] = (string) $value; + } elseif (\is_array($value) || \is_object($value)) { + $converted[$field] = \json_encode($value); + } else { + $converted[$field] = $value; + } + } + + return $converted; + } +} diff --git a/src/Traits/ValueObjects/HasFieldCastingTrait.php b/src/Traits/ValueObjects/HasFieldCastingTrait.php new file mode 100644 index 0000000..e2ef24d --- /dev/null +++ b/src/Traits/ValueObjects/HasFieldCastingTrait.php @@ -0,0 +1,72 @@ + $value) { + + // Builds up the Mutator's name. + $mutator = $this->createMutatorName(self::$CASTPREFIX, $field); + + // Checks if the mutator exists in the instance, and if so, loads the value into it. + if (\array_search($mutator, $this->castList) !== false) { + $this->{$mutator}($value); + } + } + } + + /** + * Creates and returns a mutator's method name, based on the supplied Prefix and Field's name. + * + * @param string $prefix - Prefix used in mutator's name. + * @param string $field - Name of the Field used as reference for the Mutator's name creation. + * @return string + */ + final protected function createMutatorName(string $prefix, string $field): string + { + return ($prefix . \str_replace('_', '', \ucwords($field, '_'))); + } + + /** + * Loads a list of casting mutator methods, available within the Instance for processing. + * + * @return void + */ + private function loadAttributeCastingList(): void + { + // Loops through all the class' methods, and loads the necessary ones in + // the corresponding containers. + foreach (\get_class_methods($this) as $method) { + + // Loads casting mutators. + if (\strpos($method, self::$CASTPREFIX) === 0 && \strlen($method) > \strlen(self::$CASTPREFIX)) { + $this->castList[] = $method; + } + } + } +} diff --git a/src/Traits/ValueObjects/HasGuardedFieldsTrait.php b/src/Traits/ValueObjects/HasGuardedFieldsTrait.php new file mode 100644 index 0000000..fa24f13 --- /dev/null +++ b/src/Traits/ValueObjects/HasGuardedFieldsTrait.php @@ -0,0 +1,37 @@ +guarded as $guarded) { + if (\array_key_exists($guarded, $original)) { + unset($original[$guarded]); + } + } + + return $original; + } +} diff --git a/src/Traits/ValueObjects/HasMappedFieldsTrait.php b/src/Traits/ValueObjects/HasMappedFieldsTrait.php new file mode 100644 index 0000000..138226f --- /dev/null +++ b/src/Traits/ValueObjects/HasMappedFieldsTrait.php @@ -0,0 +1,61 @@ + $value) { + + /** + * The priority is to check if the field was loaded with the native name. + * If that's the case, we'll just set the value. + * + * Otherwise, we'll check if the field is mapped to another. + * In that case, we'll load the value into the mapped field. + * + * The default behavior, is just to keep the field=>value pair as initially + * supplied. + * Although the behavior is the same as in the initial condition, we are + * assigning in the else block, so that we keep the priorities in order. + */ + if (\array_search($field, $attributes) !== false) { + $sanitized[$field] = $value; + } elseif (\array_key_exists($field, $this->maps)) { + $sanitized[$this->maps[$field]] = $value; + } else { + $sanitized[$field] = $value; + } + } + + return $sanitized; + } +} diff --git a/src/Traits/ValueObjects/HasRequiredFieldsTrait.php b/src/Traits/ValueObjects/HasRequiredFieldsTrait.php new file mode 100644 index 0000000..11b0107 --- /dev/null +++ b/src/Traits/ValueObjects/HasRequiredFieldsTrait.php @@ -0,0 +1,44 @@ +required as $required) { + + // First, we'll need to assess if the field already exists NATIVELY in the class. + // If not, we'll need to assess it is mapped. + if (! \array_key_exists($required, $fields)) { + throw new RequiredEntityValueMissingException( + "Required field '{$required}' was not supplied as a parameter." + ); + } + } + } +} diff --git a/src/Traits/ValueObjects/HasRuleProcessingTrait.php b/src/Traits/ValueObjects/HasRuleProcessingTrait.php new file mode 100644 index 0000000..63261bb --- /dev/null +++ b/src/Traits/ValueObjects/HasRuleProcessingTrait.php @@ -0,0 +1,54 @@ +ruleList as $method) { + $fields = $this->$method($fields); + } + + return $fields; + } + + /** + * Loads a list of rules and mutator methods, available within the Value Object for processing. + * + * @return void + */ + private function loadAttributeRuleList(): void + { + // Loops through all the class' methods, and loads the necessary ones in + // the corresponding containers. + foreach (\get_class_methods($this) as $method) { + + // Loads mutators/setters and rules. + if (\strpos($method, self::$RULEPREFIX) === 0 && \strlen($method) > \strlen(self::$RULEPREFIX)) { + $this->ruleList[] = $method; + } + } + } +} diff --git a/src/Traits/ValueObjects/README.md b/src/Traits/ValueObjects/README.md new file mode 100755 index 0000000..94da8ac --- /dev/null +++ b/src/Traits/ValueObjects/README.md @@ -0,0 +1 @@ +# Value Object's related Traits From a7964d903004e474601434a8c2613d1b6739fb37 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Thu, 27 May 2021 15:40:57 +0100 Subject: [PATCH 027/193] feat: Add initial ValueObject's namespace --- src/ValueObjects/AbstractValueObject.php | 175 +++++++++++++++++++++ src/ValueObjects/README.md | 188 +++++++++++++++++++++++ 2 files changed, 363 insertions(+) create mode 100644 src/ValueObjects/AbstractValueObject.php create mode 100755 src/ValueObjects/README.md diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php new file mode 100644 index 0000000..b300b83 --- /dev/null +++ b/src/ValueObjects/AbstractValueObject.php @@ -0,0 +1,175 @@ +loadInstance($fields); + } + + /** + * Loads instance's state, either on instanciation, or de-serialization. + * + * @param array $fields - List of fields to be loaded into the class. + * + * @throws RequiredEntityValueMissingException - If any of the required fields are missing. + * @throws UnexpectedEntityValueException - If some of the supplied fields are invalid. + * @return void + */ + protected function loadInstance(array $fields): void + { + // Configures Value Object's instance. + $this->loadUsableFields(); + $this->loadAttributeCastingList(); + $this->loadAttributeRuleList(); + + // Translates supplied fields, into existing ones. + $mapped = $this->translateToMappedFields($fields); + + // Validates and loads supplied data into class. + $mapped = $this->processRules($mapped); + $this->validateRequired($mapped); + $this->castAttributesInitialValues($mapped); + } + + /** + * Loads a list of usable attributes, that can hold state in the Value Object. + * + * @return void + */ + private function loadUsableFields(): void + { + $this->attributeList = $this->filterFields( + \get_object_vars($this) + ); + } + + /** + * Filters system fields from supplied array, and returns it. + * + * @param array $attrs - Array of fields to be filtered. + * @return array + */ + private function filterFields(array $attrs): array + { + unset( + $attrs['maps'], + $attrs['guarded'], + $attrs['required'], + $attrs['ruleList'], + $attrs['castList'], + $attrs['attributeList'] + ); + + return $attrs; + } + + /** + * Retrieves a list containing all Value Object's fields. + * + * Returns an associative array containing all the fields from the Value Object. + * + * Arrays will be returned as JSON. + * + * Other objects will either be returned as their string representation, or they will + * be serialized. + * + * Primitive types, or unserializable objects, will be returned in their current form. + * + * @return array + */ + public function getAttributes(): array + { + // Collects a list of usable Attributes from the Value Object. + $fields = $this->filterFields( + \get_object_vars($this) + ); + + // Converts all objects into primitives. + return $this->convertIntoPrimitiveValues($fields); + } + + /** @inheritDoc */ + public function serialize(): string + { + return \serialize( + $this->getAttributes() + ); + } + + /** @inheritDoc */ + public function unserialize($serialized): void + { + $this->loadInstance( + \unserialize($serialized) + ); + } + + /** + * {@inheritDoc} + * + * @link http://www.php.net/manual/en/jsonserializable.jsonserialize.php + * @see \JsonSerializable::jsonSerialize() + */ + public function jsonSerialize(): \stdClass + { + return (object) $this->removeGuardedFields( + $this->getAttributes() + ); + } +} diff --git a/src/ValueObjects/README.md b/src/ValueObjects/README.md new file mode 100755 index 0000000..f2dae9b --- /dev/null +++ b/src/ValueObjects/README.md @@ -0,0 +1,188 @@ +# Domain Value Objects + +**Value Object** are objects used to transport data **from** and **to** the **Domain**, but also play an important part +in validating data integrity on a record. + +3rd party objects, or _loosely typed_ values should be avoided at all costs. + +**Value Objects** are also used to enforce data consistency within a record, and validate internal rules. + +## Building a new Value Object + +The first thing you should assess, is the context of the **Value Object** you're trying to model. + +Similar contexted **Value Objects**, will be placed near each other in the filesystem/namespace. + +All **Value Objects** should be located in the `Hradigital\Basetypes\ValueObjects` namespace, followed by the same segments +present in the file system, up to the class definition. + +### Value Objects are immutable + +Value Objects should be treated as immutable, and therefore, once data is loaded into them, it should not be changed. + +In order to change the values on a Value Object, a new one whould be created, opposite to Entities that can change state. + +### Declaring Value Object's fields/attributes + +You should declare as `protected`, all the **Value Object** fields you'll want loaded into the class, with the same +name they have in the **persistence layer**, when applicable. + +Whenever possible, use **Traits** for commonly used attributes. This will facilitate reusing fields in different +attributes across the application. + +If we're talking about a Database as a **persistence layer**, and a given datatable has the _fields_ **name**, +**surname** and **date_of_birth**, the **Value Object** should have the following `protected` _attributes_: + +```php +class MyValueObject extends AbstractValueObject +{ + protected $name = ''; + protected $surname = ''; + protected $date_of_birth = null; +} +``` + +### Declaring Accessor methods for the Attributes you want visible + +For each attribute that you want to make available from outside the Value Object, you should declare an accessor/getter. +These method's names can be whatever you want, they should be declared `public`, and should return the required value. + +For an attribute called `$name`, a good accessor method's signature would be `public function name(): string;`. + +### Casting and/or Sanitizing values into the Value Object's state + +Each attribute should have a `protected` mutator starting with **cast** followed by the capitalized attribute name, without +the underscores. Eg:. An Attribute called `$user_id` would have a `protected` mutator/sanitizing method called +`castUserId(int $id)`. This mutator will be called internally, and will sanitize the attribute's value before setting it. + +### Rules for multiple attributes + +Sometimes, your Value Object might have more than one attributes which are dependent on each other. When this happens, +your should declare a **rule** in your **Value Object**. + +**Rules** are just special methods, which take the initial data array as reference, and perform operations on it, breaking it +if required. You can have as many rules as required, and they should be declared in the Value Object for which they exist. + +In order to declare a **rule**, you'll just need to declare a `protected` method, which takes an array of fields as reference. +Eg:. `protected function ruleMySpecialRule(array $fields): array;`. + +### Setting Attributes as Required + +Required attributes, are attributes that will need to be present when first loading the Value Object. If not present, +Value Object loading functionality will raise an Exception, and Value Object will not be instantiated. These are usually +fields that don't have a default value in the persistence layer. + +In order to set attributes as required, you'll just need to list them in the `protected` array named `$required`. +Eg:. `protected $required = ['name', 'surname'];` + +### Mapping different names to Attributes + +You may wish to hide internal Attribute's names, or just have them load data when providing different names in the loading array. +One possible example is, if the fields in the Client's request, are different from the ones used internally in the Value Object. +You can do this by mapping those field names in the `protected $maps = [];` array. + +As a **key**, you'll set the mapping attribute name, and in the **value**, you'll set the native Entity's attribute name. + +```php +protected $maps = [ + 'first' => 'name', + 'last' => 'surname', +]; +``` + +## Using the Value Object + +### Example Value Object with Required attributes only + +```php +class Person extends AbstractvalueObject +{ + protected $name = ''; + protected $surname = ''; + + protected $required = ['name', 'surname']; +} +``` + +### Example Value Object, where we add casting/sanitizing methods + +```php +class Person extends AbstractValueObject +{ + // ... Previous content. + + protected function castName(string $name): void + { + $this->name = trim($name); + } + + protected function castSurname(string $surname): void + { + $this->surname = trim($surname); + } +} +``` + +### Example Value Object, where we add accessor methods + +```php +class Person extends AbstractValueObject +{ + // ... Previous content. + + public function name(): string + { + return $this->name; + } + + public function surname(): string + { + return $this->surname; + } +} +``` + +### Using our Value Object, from within our application + +```php +$person = new Person([ + 'name' => 'John', + 'surname' => 'Doe', +]); + +// Echoing all the 'properties'. +echo $person->name(); // Echoes 'John' +echo $person->surname(); // Echoes 'Doe' + +// The following code will break, because both $name and $surname are required. +$breaks = new Person([ + 'name' => 'John', +]); +``` + +### Mapping different names to our attributes + +Mapping definition: + +```php +class Person extends AbstractValueObject +{ + // ... Previous content. + + protected $maps = [ + 'first' => 'name', + 'last' => 'surname', + ]; +} +``` + +```php +$person = new Person([ + 'first' => 'John', + 'last' => 'Doe', +]); + +// Echoing all the 'properties'. +echo $person->name(); // Echoes 'John' +echo $person->surname(); // Echoes 'Doe' +``` From 4fcbc92d6b0d4eafe6b9308218e3d11e9e3a450d Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 16:05:35 +0100 Subject: [PATCH 028/193] style: Small code improvements --- src/Web/EmailAddress.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 4b861a8..97d7fdd 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -26,10 +26,9 @@ class EmailAddress implements \Serializable * Loads a new EmailAddress instance from a native string. * * @param string $email - E-mail address used to initialize instance. - * * @return EmailAddress */ - public static function fromString(string $email): EmailAddress + public static function create(string $email): EmailAddress { return new EmailAddress($email); } @@ -44,7 +43,7 @@ public static function fromString(string $email): EmailAddress */ protected function __construct(string $email) { - $this->loadInitialState($email); + $this->loadFromPrimitive($email); } /** @@ -55,7 +54,7 @@ protected function __construct(string $email) * @throws \InvalidArgumentException - If the supplied email address is empty or invalid. * @return void */ - private function loadInitialState(string $email): void + protected function loadFromPrimitive(string $email): void { // Validate supplied parameter. if (\strlen(\trim($email)) === 0) { @@ -91,7 +90,7 @@ public function serialize() */ public function unserialize($serialized) { - $this->loadInitialState( + $this->loadFromPrimitive( \unserialize($serialized) ); } From cc4bd983866248876f1fc39f7bf9c967091a9b97 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 16:08:18 +0100 Subject: [PATCH 029/193] style: Rename internal method --- src/ValueObjects/AbstractValueObject.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php index b300b83..4e4babd 100644 --- a/src/ValueObjects/AbstractValueObject.php +++ b/src/ValueObjects/AbstractValueObject.php @@ -94,7 +94,7 @@ protected function loadInstance(array $fields): void */ private function loadUsableFields(): void { - $this->attributeList = $this->filterFields( + $this->attributeList = $this->filterSystemControlFields( \get_object_vars($this) ); } @@ -105,7 +105,7 @@ private function loadUsableFields(): void * @param array $attrs - Array of fields to be filtered. * @return array */ - private function filterFields(array $attrs): array + private function filterSystemControlFields(array $attrs): array { unset( $attrs['maps'], @@ -136,7 +136,7 @@ private function filterFields(array $attrs): array public function getAttributes(): array { // Collects a list of usable Attributes from the Value Object. - $fields = $this->filterFields( + $fields = $this->filterSystemControlFields( \get_object_vars($this) ); From 2aaa3a1ecd9911ede3229118e8999429e9c25aa4 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 22:22:52 +0100 Subject: [PATCH 030/193] refactor: Improve class funcitonality for inheritance --- src/Scalar/AbstractBaseString.php | 203 ++++++++++++------------------ 1 file changed, 79 insertions(+), 124 deletions(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 32c4fba..8280537 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -5,9 +5,11 @@ /** * Abstract Base String's Scalar Object class. * - * This class is used as a base, for both MutableString datatype as well as for ImmutableString. + * In this package, this class is used as a base, for both VoString Value Object datatype + * as well as for NatString native datatype. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ abstract class AbstractBaseString @@ -16,9 +18,9 @@ abstract class AbstractBaseString protected string $value = ''; /** - * Initializes a new instance of a String. + * Instantiates an AbstractBaseString child class. * - * @param string $value - Initial string value. + * @param string $value - Initial instance's value. * @return void */ protected function __construct(string $value) @@ -37,21 +39,30 @@ public function __toString(): string } /** - * Compares the values of 2 separate instances. + * Returns the Instance's value character length. * - * Returns TRUE if the 2 instance's values match. FALSE otherwise. + * @return int + */ + public function length(): int + { + return \strlen($this->value); + } + + /** + * Compares the instance's value, with the supplied native string. * - * @param AbstractBaseString $string - Another String instance to compare to. + * Returns TRUE if the 2 values match. FALSE otherwise. * + * @param string $string - Another string to compare with. * @return bool */ - public function equals(AbstractBaseString $string): bool + protected function doEquals(string $string): bool { - return ($this->__toString() === $string->__toString()); + return ($this->value === $string); } /** - * Checks if the instance contains the supplied $search value. + * Checks if the instance's value contains the supplied $search string. * * Returns TRUE if found. FALSE otherwise. * @@ -60,43 +71,33 @@ public function equals(AbstractBaseString $string): bool * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ - public function contains(string $search): bool + protected function doContains(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { throw new \InvalidArgumentException("Supplied search must be a non empty string."); } - return ($this->indexOf($search) !== null); + return ($this->doIndexOf($search) !== null); } /** - * Returns the instance's value character length. - * - * @return int - */ - public function length(): int - { - return \strlen($this->value); - } - - /** - * Searches and returns the index in the instance, of the $search string. + * Searches and returns the character index in the instance, of the $search string. * * If a $start is specified, search will start this number of characters counted from * the beginning of the string. If $start is negative, the search will start this number * of characters counted from the end of the string. * - * If the $search is not found inthe instance's value, NULL is returned. + * If the $search is not found in the instance's value, NULL is returned. * * @param string $search - String to search for in the instance. * @param int $start - Search offset start. Defaults to ZERO. * * @throws \InvalidArgumentException - If $search value is an empty string. * @throws \OutOfRangeException - If the $start is either too small, or too long. - * @return int|NULL + * @return int|null */ - public function indexOf(string $search, int $start = 0): ?int + protected function doIndexOf(string $search, int $start = 0): ?int { // Validates supplied parameters. if (\strlen($search) === 0) { @@ -125,14 +126,14 @@ public function indexOf(string $search, int $start = 0): ?int * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ - public function startsWith(string $search): bool + protected function doStartsWith(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { throw new \InvalidArgumentException("Supplied search must be a non empty string."); } - return ($this->indexOf($search) === 0); + return ($this->doIndexOf($search) === 0); } /** @@ -143,14 +144,14 @@ public function startsWith(string $search): bool * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ - public function endsWith(string $search): bool + protected function doEndsWith(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { throw new \InvalidArgumentException("Supplied search must be a non empty string."); } - return (\substr($this->value, (0 - \strlen($search))) === $search); + return ($this->doSubString((0 - \strlen($search))) === $search); } /** @@ -164,7 +165,7 @@ public function endsWith(string $search): bool * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ - public function count(string $search, int $start = 0, ?int $length = null): int + protected function doCount(string $search, int $start = 0, ?int $length = null): int { // Validates supplied $search parameter. if (\strlen($search) === 0) { @@ -191,7 +192,7 @@ public function count(string $search, int $start = 0, ?int $length = null): int * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return void */ - protected function validateStartAndLength(int $start, ?int $length): void + private function validateStartAndLength(int $start, ?int $length): void { // Calculates the absolute values for validations. $absStart = (int) \abs($start); @@ -220,103 +221,84 @@ protected function validateStartAndLength(int $start, ?int $length): void } /** - * Trims instance's value, and returns a new instance of the object. - * - * @param string $value - String value to perform the operation on. + * Trims instance's value * * @return string */ - protected function doTrim(string $value): string + protected function doTrim(): string { - return \trim($value); + return \trim($this->value); } /** - * Left trims instance's value, and returns a new instance of the object. - * - * @param string $value - String value to perform the operation on. + * Left trims instance's value. * * @return string */ - protected function doTrimLeft(string $value): string + protected function doTrimLeft(): string { - return \ltrim($value); + return \ltrim($this->value); } /** - * Right trims instance's value, and returns a new instance of the object. - * - * @param string $value - String value to perform the operation on. + * Right trims instance's value. * * @return string */ - protected function doTrimRight(string $value): string + protected function doTrimRight(): string { - return \rtrim($value); + return \rtrim($this->value); } /** - * Converts the instance's value to Upper Case, and returns a new instance of the object. - * - * @param string $value - String value to perform the operation on. + * Converts the instance's value to Uppercase. * * @return string */ - protected function doToUpper(string $value): string + protected function doToUpper(): string { - return \mb_strtoupper($value); + return \mb_strtoupper($this->value); } /** - * Converts the instance's value first character to Upper Case, and returns a new instance - * of the object. - * - * @param string $value - String value to perform the operation on. + * Converts the instance's value first character to Uppercase. * * @return string */ - protected function doToUpperFirst(string $value): string + protected function doToUpperFirst(): string { - return \ucfirst($value); + return \ucfirst($this->value); } /** - * Converts the instance's value first character of each word to Upper Case, and returns a new instance - * of the object. + * Converts the instance's value first character of each word to Upper Case. * - * @param string $value - String value to perform the operation on. * @param string $delimiters - The optional delimiters contains the word separator characters. - * * @return string */ - protected function doToUpperWords(string $value, string $delimiters = " \t\r\n\f\v"): string + protected function doToUpperWords(string $delimiters = " \t\r\n\f\v"): string { - return \ucwords($value, $delimiters); + return \ucwords($this->value, $delimiters); } /** - * Converts the instance's value to Lower Case, and returns a new instance of the object. - * - * @param string $value - String value to perform the operation on. + * Converts the instance's value to Lowercase. * * @return string */ - protected function doToLower(string $value): string + protected function doToLower(): string { - return \mb_strtolower($value); + return \mb_strtolower($this->value); } /** - * Converts the instance's value first character to Lower Case, and returns a new instance - * of the object - * - * @param string $value - String value to perform the operation on. + * Converts the instance's value first character to Lowercase. * * @return string */ - protected function doToLowerFirst(string $value): string + protected function doToLowerFirst(): string { - return \lcfirst($value); + return \lcfirst($this->value); } /** @@ -329,7 +311,6 @@ protected function doToLowerFirst(string $value): string * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padString up to the limit. * - * @param string $value - String value to perform the operation on. * @param int $length - Length of the padded value. * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padString's length. @@ -337,7 +318,7 @@ protected function doToLowerFirst(string $value): string * @throws \InvalidArgumentException - If any of the parameters is invalid. * @return string */ - protected function doPadLeft(string $value, int $length, string $padding = " "): string + protected function doPadLeft(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { @@ -347,7 +328,7 @@ protected function doPadLeft(string $value, int $length, string $padding = " "): throw new \InvalidArgumentException("Supplied padding must be a non empty string."); } - return \str_pad($value, $length, $padding, STR_PAD_LEFT); + return \str_pad($this->value, $length, $padding, STR_PAD_LEFT); } /** @@ -356,7 +337,6 @@ protected function doPadLeft(string $value, int $length, string $padding = " "): * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param string $value - String value to perform the operation on. * @param int $length - Length of the padded value. * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. @@ -364,17 +344,9 @@ protected function doPadLeft(string $value, int $length, string $padding = " "): * @throws \InvalidArgumentException - If any of the parameters is invalid. * @return string */ - protected function doPadLeftExtra(string $value, int $length, string $padding = " "): string + protected function doPadLeftExtra(int $length, string $padding = " "): string { - // Validates supplied parameters. - if ($length < 1) { - throw new \InvalidArgumentException("Supplied Length must be a positive integer."); - } - if (\strlen($padding) === 0) { - throw new \InvalidArgumentException("Supplied padding must be a non empty string."); - } - - return \str_pad($value, (\strlen($value) + $length), $padding, STR_PAD_LEFT); + return $this->doPadLeft(($this->length() + $length), $padding); } /** @@ -387,7 +359,6 @@ protected function doPadLeftExtra(string $value, int $length, string $padding = * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param string $value - String value to perform the operation on. * @param int $length - Length of the padded value. * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. @@ -395,7 +366,7 @@ protected function doPadLeftExtra(string $value, int $length, string $padding = * @throws \InvalidArgumentException - If any of the parameters is invalid. * @return string */ - protected function doPadRight(string $value, int $length, string $padding = " "): string + protected function doPadRight(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { @@ -405,7 +376,7 @@ protected function doPadRight(string $value, int $length, string $padding = " ") throw new \InvalidArgumentException("Supplied padding must be a non empty string."); } - return \str_pad($value, $length, $padding, STR_PAD_RIGHT); + return \str_pad($this->value, $length, $padding, STR_PAD_RIGHT); } /** @@ -414,7 +385,6 @@ protected function doPadRight(string $value, int $length, string $padding = " ") * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param string $value - String value to perform the operation on. * @param int $length - Length of the padded value. * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. @@ -422,17 +392,9 @@ protected function doPadRight(string $value, int $length, string $padding = " ") * @throws \InvalidArgumentException - If any of the parameters is invalid. * @return string */ - protected function doPadRightExtra(string $value, int $length, string $padding = " "): string + protected function doPadRightExtra(int $length, string $padding = " "): string { - // Validates supplied parameters. - if ($length < 1) { - throw new \InvalidArgumentException("Supplied Length must be a positive integer."); - } - if (\strlen($padding) === 0) { - throw new \InvalidArgumentException("Supplied padding must be a non empty string."); - } - - return \str_pad($value, (\strlen($value) + $length), $padding, STR_PAD_RIGHT); + return $this->doPadRight(($this->length() + $length), $padding); } /** @@ -457,23 +419,22 @@ protected function doPadRightExtra(string $value, int $length, string $padding = * - If $length exceeds the remaining number of characters, after the $start calculation, an * Exception will be raised. * - * @param string $value - String value to perform the operation on. * @param int $start - Start of the sub-string. Can be negative. * @param int $length - Length of the sub-string. Can be negative. * * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return string */ - protected function doSubString(string $value, int $start, int $length = null): string + protected function doSubString(int $start, int $length = null): string { // Validates supplied $start and $length. $this->validateStartAndLength($start, $length); // Processes the substring. if ($length !== null) { - $value = \substr($value, $start, $length); + $value = \substr($this->value, $start, $length); } else { - $value = \substr($value, $start); + $value = \substr($this->value, $start); } return ($value ?? ''); @@ -483,75 +444,69 @@ protected function doSubString(string $value, int $start, int $length = null): s * This method returns a new instance with a portion of the original instance's value, starting at the beginning * of the value, with the number of characters specified in the $length parameter. * - * Same rules as ImmutableString::subString() are applied. - * - * @param string $value - String value to perform the operation on. * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. * @return string */ - protected function doSubLeft(string $value, int $length): string + protected function doSubLeft(int $length): string { // Validates parameter. if ($length < 1) { throw new \InvalidArgumentException("Supplied length must be a positive integer."); } - return $this->doSubString($value, 0, $length); + return $this->doSubString(0, $length); } /** * This method returns a new instance with a portion of the original instance's value, couting from the end * of the value, with the number of characters specified in the $length parameter. * - * Same rules as ImmutableString::subString() are applied. - * - * @param string $value - String value to perform the operation on. * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. * @return string */ - protected function doSubRight($value, int $length): string + protected function doSubRight(int $length): string { // Validates parameter. if ($length < 1) { throw new \InvalidArgumentException("Supplied length must be a positive integer."); } - return $this->doSubString($value, 0 - $length); + return $this->doSubString(0 - $length); } /** - * This method returns a new instance with the reversed value of the original instance. - * - * @param string $value - String value to perform the operation on. + * This method returns the reversed value of the instance. * * @return string */ - protected function doReverse(string $value): string + protected function doReverse(): string { - return \strrev($value); + return \strrev($this->value); } /** * This method replaces a string's occurance by another, and returns a new instance with the new value. * - * @param string $value - String value to perform the operation on. * @param string $search - The string to search for. * @param string $replace - The search's replacement. * * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. * @return string */ - protected function doReplace(string $value, string $search, string $replace): string + protected function doReplace(string $search, string $replace): string { // Validates supplied parameters. if (\strlen($search) === 0) { throw new \InvalidArgumentException("Supplied search must be a non empty string."); } + if (\strlen($replace) === 0) { + throw new \InvalidArgumentException("Supplied replace must be a non empty string."); + } - return \str_replace($search, $replace, $value); + return \str_replace($search, $replace, $this->value); } } From b48288c3635f13c03d10ad61a6bddcdd54010235 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 22:25:27 +0100 Subject: [PATCH 031/193] refactor: Improve public functionality for IString --- src/Scalar/IString.php | 177 ++++++++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 47 deletions(-) diff --git a/src/Scalar/IString.php b/src/Scalar/IString.php index 2ead86e..fceb737 100644 --- a/src/Scalar/IString.php +++ b/src/Scalar/IString.php @@ -3,14 +3,15 @@ namespace Hradigital\Datatypes\Scalar; /** - * Immutable String's Scalar Object class. + * String's Scalar Value Object class. * * Instanciate this class, if you want the initial instance's value to be preserved. * - * Fluent interface (chaning) is not supported by any mutators. - * A new instance will be returned instead. + * Fluent interface (chaning) is supported by mutators, but a new instance will be returned. + * Original internal value will be immutable. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class IString extends AbstractBaseString @@ -27,14 +28,100 @@ public static function create(string $value): IString } /** - * Trims instance's value, and returns a new instance of the object. + * Compares the values of 2 separate instances. * - * @return IString + * Returns TRUE if the 2 instance's values match. FALSE otherwise. + * + * @param IString $string - Another IString instance to compare to. + * @return bool + */ + public function equals(IString $string): bool + { + return parent::doEquals((string) $string); + } + + /** + * Checks if the instance contains the supplied $search value. + * + * Returns TRUE if found. FALSE otherwise. + * + * @param IString $search - Non empty string to search for in the instance. + * + * @throws \InvalidArgumentException - If supplied $search is empty. + * @return bool */ + public function contains(IString $search): bool + { + return parent::doEquals((string) $search); + } + + /** + * Searches and returns the index in the instance, of the $search string. + * + * If a $start is specified, search will start this number of characters counted from + * the beginning of the string. If $start is negative, the search will start this number + * of characters counted from the end of the string. + * + * If the $search is not found inthe instance's value, NULL is returned. + * + * @param IString $search - String to search for in the instance. + * @param int $start - Search offset start. Defaults to ZERO. + * + * @throws \InvalidArgumentException - If $search value is an empty string. + * @throws \OutOfRangeException - If the $start is either too small, or too long. + * @return int|NULL + */ + public function indexOf(IString $search, int $start = 0): ?int + { + return parent::doIndexOf((string) $search, $start); + } + + /** + * Checks if the instance's value starts with the supplied string. + * + * @param IString $search - Non empty string to search for in the instance. + * + * @throws \InvalidArgumentException - If supplied $search is empty. + * @return bool + */ + public function startsWith(IString $search): bool + { + return parent::doStartsWith((string) $search); + } + + /** + * Checks if the instance's value ends with the supplied string. + * + * @param IString $search - Non empty string to search for in the instance. + * + * @throws \InvalidArgumentException - If supplied $search is empty. + * @return bool + */ + public function endsWith(IString $search): bool + { + return parent::doEndsWith((string) $search); + } + + /** + * Counts the number of substring occurrences in the instance's value. + * + * @param IString $search - Non empty string to search for in the instance. + * @param int $start - The sub-string's offset/start. + * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. + * + * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @return int + */ + public function count(IString $search, int $start = 0, ?int $length = null): int + { + return parent::doCount((string) $search, $start, $length); + } + public function trim(): IString { - return new IString( - parent::doTrim($this->value) + return IString::create( + parent::doTrim() ); } @@ -45,8 +132,8 @@ public function trim(): IString */ public function trimLeft(): IString { - return new IString( - parent::doTrimLeft($this->value) + return IString::create( + parent::doTrimLeft() ); } @@ -57,8 +144,8 @@ public function trimLeft(): IString */ public function trimRight(): IString { - return new IString( - parent::doTrimRight($this->value) + return IString::create( + parent::doTrimRight() ); } @@ -69,8 +156,8 @@ public function trimRight(): IString */ public function toUpper(): IString { - return new IString( - parent::doToUpper($this->value) + return IString::create( + parent::doToUpper() ); } @@ -82,8 +169,8 @@ public function toUpper(): IString */ public function toUpperFirst(): IString { - return new IString( - parent::doToUpperFirst($this->value) + return IString::create( + parent::doToUpperFirst() ); } @@ -97,8 +184,8 @@ public function toUpperFirst(): IString */ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): IString { - return new IString( - parent::doToUpperWords($this->value, $delimiters) + return IString::create( + parent::doToUpperWords($delimiters) ); } @@ -109,8 +196,8 @@ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): IString */ public function toLower(): IString { - return new IString( - parent::doToLower($this->value) + return IString::create( + parent::doToLower() ); } @@ -122,8 +209,8 @@ public function toLower(): IString */ public function toLowerFirst(): IString { - return new IString( - parent::doToLowerFirst($this->value) + return IString::create( + parent::doToLowerFirst() ); } @@ -142,8 +229,8 @@ public function toLowerFirst(): IString */ public function padLeft(int $length, string $padding = " "): IString { - return new IString( - parent::doPadLeft($this->value, $length, $padding) + return IString::create( + parent::doPadLeft($length, $padding) ); } @@ -162,8 +249,8 @@ public function padLeft(int $length, string $padding = " "): IString */ public function padLeftExtra(int $length, string $padding = " "): IString { - return new IString( - parent::doPadLeftExtra($this->value, $length, $padding) + return IString::create( + parent::doPadLeftExtra($length, $padding) ); } @@ -186,8 +273,8 @@ public function padLeftExtra(int $length, string $padding = " "): IString */ public function padRight(int $length, string $padding = " "): IString { - return new IString( - parent::doPadRight($this->value, $length, $padding) + return IString::create( + parent::doPadRight($length, $padding) ); } @@ -206,8 +293,8 @@ public function padRight(int $length, string $padding = " "): IString */ public function padRightExtra(int $length, string $padding = " "): IString { - return new IString( - parent::doPadRightExtra($this->value, $length, $padding) + return IString::create( + parent::doPadRightExtra($length, $padding) ); } @@ -241,8 +328,8 @@ public function padRightExtra(int $length, string $padding = " "): IString */ public function subString(int $start, int $length = null): IString { - return new IString( - parent::doSubString($this->value, $start, $length) + return IString::create( + parent::doSubString($start, $length) ); } @@ -250,8 +337,6 @@ public function subString(int $start, int $length = null): IString * This method returns a new instance with a portion of the original instance's value, starting at the beginning * of the value, with the number of characters specified in the $length parameter. * - * Same rules as IString::subString() are applied. - * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. @@ -259,8 +344,8 @@ public function subString(int $start, int $length = null): IString */ public function subLeft(int $length): IString { - return new IString( - parent::doSubLeft($this->value, $length) + return IString::create( + parent::doSubLeft($length) ); } @@ -268,8 +353,6 @@ public function subLeft(int $length): IString * This method returns a new instance with a portion of the original instance's value, couting from the end * of the value, with the number of characters specified in the $length parameter. * - * Same rules as IString::subString() are applied. - * * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. @@ -277,36 +360,36 @@ public function subLeft(int $length): IString */ public function subRight(int $length): IString { - return new IString( - parent::doSubRight($this->value, $length) + return IString::create( + parent::doSubRight($length) ); } /** - * This method returns a new instance with the reversed value of the original instance. + * This method returns the reversed value of the instance. * * @return IString */ public function reverse(): IString { - return new IString( - parent::doReverse($this->value) + return IString::create( + parent::doReverse() ); } /** * This method replaces a string's occurance by another, and returns a new instance with the new value. * - * @param string $search - The string to search for. - * @param string $replace - The search's replacement. + * @param IString $search - The string to search for. + * @param IString $replace - The search's replacement. * * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. * @return IString */ - public function replace(string $search, string $replace): IString + public function replace(IString $search, IString $replace): IString { - return new IString( - parent::doReplace($this->value, $search, $replace) + return IString::create( + parent::doReplace((string) $search, (string) $replace) ); } } From a3bb2e148839f35fb380fa592099210119074ec5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 22:26:17 +0100 Subject: [PATCH 032/193] refactor: Rename Value Object String class --- src/Scalar/{IString.php => VoString.php} | 138 +++++++++++------------ 1 file changed, 69 insertions(+), 69 deletions(-) rename src/Scalar/{IString.php => VoString.php} (79%) diff --git a/src/Scalar/IString.php b/src/Scalar/VoString.php similarity index 79% rename from src/Scalar/IString.php rename to src/Scalar/VoString.php index fceb737..0e0ab57 100644 --- a/src/Scalar/IString.php +++ b/src/Scalar/VoString.php @@ -14,17 +14,17 @@ * @copyright Hradigital\Datatypes * @license MIT */ -class IString extends AbstractBaseString +class VoString extends AbstractBaseString { /** - * Creates a new instance of IString based on a string value. + * Creates a new instance of VoString based on a string value. * * @param string $value - Instance's initial value. - * @return IString + * @return VoString */ - public static function create(string $value): IString + public static function create(string $value): VoString { - return new IString($value); + return new VoString($value); } /** @@ -32,10 +32,10 @@ public static function create(string $value): IString * * Returns TRUE if the 2 instance's values match. FALSE otherwise. * - * @param IString $string - Another IString instance to compare to. + * @param VoString $string - Another VoString instance to compare to. * @return bool */ - public function equals(IString $string): bool + public function equals(VoString $string): bool { return parent::doEquals((string) $string); } @@ -45,12 +45,12 @@ public function equals(IString $string): bool * * Returns TRUE if found. FALSE otherwise. * - * @param IString $search - Non empty string to search for in the instance. + * @param VoString $search - Non empty string to search for in the instance. * * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ - public function contains(IString $search): bool + public function contains(VoString $search): bool { return parent::doEquals((string) $search); } @@ -64,14 +64,14 @@ public function contains(IString $search): bool * * If the $search is not found inthe instance's value, NULL is returned. * - * @param IString $search - String to search for in the instance. + * @param VoString $search - String to search for in the instance. * @param int $start - Search offset start. Defaults to ZERO. * * @throws \InvalidArgumentException - If $search value is an empty string. * @throws \OutOfRangeException - If the $start is either too small, or too long. * @return int|NULL */ - public function indexOf(IString $search, int $start = 0): ?int + public function indexOf(VoString $search, int $start = 0): ?int { return parent::doIndexOf((string) $search, $start); } @@ -79,12 +79,12 @@ public function indexOf(IString $search, int $start = 0): ?int /** * Checks if the instance's value starts with the supplied string. * - * @param IString $search - Non empty string to search for in the instance. + * @param VoString $search - Non empty string to search for in the instance. * * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ - public function startsWith(IString $search): bool + public function startsWith(VoString $search): bool { return parent::doStartsWith((string) $search); } @@ -92,12 +92,12 @@ public function startsWith(IString $search): bool /** * Checks if the instance's value ends with the supplied string. * - * @param IString $search - Non empty string to search for in the instance. + * @param VoString $search - Non empty string to search for in the instance. * * @throws \InvalidArgumentException - If supplied $search is empty. * @return bool */ - public function endsWith(IString $search): bool + public function endsWith(VoString $search): bool { return parent::doEndsWith((string) $search); } @@ -105,7 +105,7 @@ public function endsWith(IString $search): bool /** * Counts the number of substring occurrences in the instance's value. * - * @param IString $search - Non empty string to search for in the instance. + * @param VoString $search - Non empty string to search for in the instance. * @param int $start - The sub-string's offset/start. * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. * @@ -113,14 +113,14 @@ public function endsWith(IString $search): bool * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ - public function count(IString $search, int $start = 0, ?int $length = null): int + public function count(VoString $search, int $start = 0, ?int $length = null): int { return parent::doCount((string) $search, $start, $length); } - public function trim(): IString + public function trim(): VoString { - return IString::create( + return VoString::create( parent::doTrim() ); } @@ -128,11 +128,11 @@ public function trim(): IString /** * Left trims instance's value, and returns a new instance of the object. * - * @return IString + * @return VoString */ - public function trimLeft(): IString + public function trimLeft(): VoString { - return IString::create( + return VoString::create( parent::doTrimLeft() ); } @@ -140,11 +140,11 @@ public function trimLeft(): IString /** * Right trims instance's value, and returns a new instance of the object. * - * @return IString + * @return VoString */ - public function trimRight(): IString + public function trimRight(): VoString { - return IString::create( + return VoString::create( parent::doTrimRight() ); } @@ -152,11 +152,11 @@ public function trimRight(): IString /** * Converts the instance's value to Upper Case, and returns a new instance of the object. * - * @return IString + * @return VoString */ - public function toUpper(): IString + public function toUpper(): VoString { - return IString::create( + return VoString::create( parent::doToUpper() ); } @@ -165,11 +165,11 @@ public function toUpper(): IString * Converts the instance's value first character to Upper Case, and returns a new instance * of the object. * - * @return IString + * @return VoString */ - public function toUpperFirst(): IString + public function toUpperFirst(): VoString { - return IString::create( + return VoString::create( parent::doToUpperFirst() ); } @@ -180,11 +180,11 @@ public function toUpperFirst(): IString * * @param string $delimiters - The optional delimiters contains the word separator characters. * - * @return IString + * @return VoString */ - public function toUpperWords(string $delimiters = " \t\r\n\f\v"): IString + public function toUpperWords(string $delimiters = " \t\r\n\f\v"): VoString { - return IString::create( + return VoString::create( parent::doToUpperWords($delimiters) ); } @@ -192,11 +192,11 @@ public function toUpperWords(string $delimiters = " \t\r\n\f\v"): IString /** * Converts the instance's value to Lower Case, and returns a new instance of the object. * - * @return IString + * @return VoString */ - public function toLower(): IString + public function toLower(): VoString { - return IString::create( + return VoString::create( parent::doToLower() ); } @@ -205,11 +205,11 @@ public function toLower(): IString * Converts the instance's value first character to Lower Case, and returns a new instance * of the object * - * @return IString + * @return VoString */ - public function toLowerFirst(): IString + public function toLowerFirst(): VoString { - return IString::create( + return VoString::create( parent::doToLowerFirst() ); } @@ -225,11 +225,11 @@ public function toLowerFirst(): IString * it is padded with characters from $padding up to the limit. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return IString + * @return VoString */ - public function padLeft(int $length, string $padding = " "): IString + public function padLeft(int $length, string $padding = " "): VoString { - return IString::create( + return VoString::create( parent::doPadLeft($length, $padding) ); } @@ -245,11 +245,11 @@ public function padLeft(int $length, string $padding = " "): IString * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return IString + * @return VoString */ - public function padLeftExtra(int $length, string $padding = " "): IString + public function padLeftExtra(int $length, string $padding = " "): VoString { - return IString::create( + return VoString::create( parent::doPadLeftExtra($length, $padding) ); } @@ -269,11 +269,11 @@ public function padLeftExtra(int $length, string $padding = " "): IString * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return IString + * @return VoString */ - public function padRight(int $length, string $padding = " "): IString + public function padRight(int $length, string $padding = " "): VoString { - return IString::create( + return VoString::create( parent::doPadRight($length, $padding) ); } @@ -289,11 +289,11 @@ public function padRight(int $length, string $padding = " "): IString * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return IString + * @return VoString */ - public function padRightExtra(int $length, string $padding = " "): IString + public function padRightExtra(int $length, string $padding = " "): VoString { - return IString::create( + return VoString::create( parent::doPadRightExtra($length, $padding) ); } @@ -324,11 +324,11 @@ public function padRightExtra(int $length, string $padding = " "): IString * @param int $length - Length of the sub-string. Can be negative. * * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return IString + * @return VoString */ - public function subString(int $start, int $length = null): IString + public function subString(int $start, int $length = null): VoString { - return IString::create( + return VoString::create( parent::doSubString($start, $length) ); } @@ -340,11 +340,11 @@ public function subString(int $start, int $length = null): IString * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * @return IString + * @return VoString */ - public function subLeft(int $length): IString + public function subLeft(int $length): VoString { - return IString::create( + return VoString::create( parent::doSubLeft($length) ); } @@ -356,11 +356,11 @@ public function subLeft(int $length): IString * @param int $length - Length of the sub-string. Must be positive. * * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * @return IString + * @return VoString */ - public function subRight(int $length): IString + public function subRight(int $length): VoString { - return IString::create( + return VoString::create( parent::doSubRight($length) ); } @@ -368,11 +368,11 @@ public function subRight(int $length): IString /** * This method returns the reversed value of the instance. * - * @return IString + * @return VoString */ - public function reverse(): IString + public function reverse(): VoString { - return IString::create( + return VoString::create( parent::doReverse() ); } @@ -380,15 +380,15 @@ public function reverse(): IString /** * This method replaces a string's occurance by another, and returns a new instance with the new value. * - * @param IString $search - The string to search for. - * @param IString $replace - The search's replacement. + * @param VoString $search - The string to search for. + * @param VoString $replace - The search's replacement. * * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. - * @return IString + * @return VoString */ - public function replace(IString $search, IString $replace): IString + public function replace(VoString $search, VoString $replace): VoString { - return IString::create( + return VoString::create( parent::doReplace((string) $search, (string) $replace) ); } From ac94bba2e60d5ad21fbfecfc2b8cefacacea9837 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 22:33:06 +0100 Subject: [PATCH 033/193] refactor: Completely remove any native string reference from the class' public interface --- src/Scalar/VoString.php | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index 0e0ab57..0a729dc 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -178,14 +178,14 @@ public function toUpperFirst(): VoString * Converts the instance's value first character of each word to Upper Case, and returns a new instance * of the object. * - * @param string $delimiters - The optional delimiters contains the word separator characters. + * @param VoString|null $delimiters - The optional delimiters contains the word separator characters. * * @return VoString */ - public function toUpperWords(string $delimiters = " \t\r\n\f\v"): VoString + public function toUpperWords(?VoString $delimiters = null): VoString { return VoString::create( - parent::doToUpperWords($delimiters) + parent::doToUpperWords($delimiters ?? " \t\r\n\f\v") ); } @@ -224,13 +224,17 @@ public function toLowerFirst(): VoString * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * + * @param int $length - Length of the padded value. + * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. + * * @throws \InvalidArgumentException - If any of the parameters is invalid. * @return VoString */ - public function padLeft(int $length, string $padding = " "): VoString + public function padLeft(int $length, ?VoString $padding = null): VoString { return VoString::create( - parent::doPadLeft($length, $padding) + parent::doPadLeft($length, ((string) $padding ?: " ")) ); } @@ -240,17 +244,17 @@ public function padLeft(int $length, string $padding = " "): VoString * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters + * @param int $length - Length of the padded value. + * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. * @return VoString */ - public function padLeftExtra(int $length, string $padding = " "): VoString + public function padLeftExtra(int $length, ?VoString $padding = null): VoString { return VoString::create( - parent::doPadLeftExtra($length, $padding) + parent::doPadLeftExtra($length, ((string) $padding ?: " ")) ); } @@ -264,17 +268,17 @@ public function padLeftExtra(int $length, string $padding = " "): VoString * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters + * @param int $length - Length of the padded value. + * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. * @return VoString */ - public function padRight(int $length, string $padding = " "): VoString + public function padRight(int $length, ?VoString $padding = null): VoString { return VoString::create( - parent::doPadRight($length, $padding) + parent::doPadRight($length, ((string) $padding ?: " ")) ); } @@ -284,17 +288,17 @@ public function padRight(int $length, string $padding = " "): VoString * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters + * @param int $length - Length of the padded value. + * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * * @throws \InvalidArgumentException - If any of the parameters is invalid. * @return VoString */ - public function padRightExtra(int $length, string $padding = " "): VoString + public function padRightExtra(int $length, ?VoString $padding = null): VoString { return VoString::create( - parent::doPadRightExtra($length, $padding) + parent::doPadRightExtra($length, ((string) $padding ?: " ")) ); } From 914a963a9387a7fa67364fb8058e0ea67c1b1cea Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 22:35:24 +0100 Subject: [PATCH 034/193] refactor: Remove deprecated String class --- src/Scalar/MutableString.php | 341 ----------------------------------- 1 file changed, 341 deletions(-) delete mode 100644 src/Scalar/MutableString.php diff --git a/src/Scalar/MutableString.php b/src/Scalar/MutableString.php deleted file mode 100644 index 27c2c4d..0000000 --- a/src/Scalar/MutableString.php +++ /dev/null @@ -1,341 +0,0 @@ -value - ); - } - - /** - * Trims the instance's value. - * - * This method supports chaning. - * - * @return MutableString - */ - public function trim(): MutableString - { - $this->value = parent::doTrim($this->value); - - return $this; - } - - /** - * Left trims the instance's value. - * - * This method supports chaning. - * - * @return MutableString - */ - public function trimLeft(): MutableString - { - $this->value = parent::doTrimLeft($this->value); - - return $this; - } - - /** - * Right trims the instance's value. - * - * This method supports chaning. - * - * @return MutableString - */ - public function trimRight(): MutableString - { - $this->value = parent::doTrimRight($this->value); - - return $this; - } - - /** - * Converts the instance's value to Upper Case. - * - * This method supports chaning. - * - * @return MutableString - */ - public function toUpper(): MutableString - { - $this->value = parent::doToUpper($this->value); - - return $this; - } - - /** - * Make a string's first character uppercase. - * - * @return MutableString - */ - public function toUpperFirst(): MutableString - { - $this->value = parent::doToUpperFirst($this->value); - - return $this; - } - - /** - * Makes the string's first character of each word to Upper Case. - * - * @param string $delimiters - The optional delimiters contains the word separator characters. - * - * @return MutableString - */ - public function toUpperWords(string $delimiters = " \t\r\n\f\v"): MutableString - { - $this->value = parent::doToUpperWords($this->value, $delimiters); - - return $this; - } - - /** - * Converts the instance's value to Lower Case. - * - * This method supports chaning. - * - * @return MutableString - */ - public function toLower(): MutableString - { - $this->value = parent::doToLower($this->value); - - return $this; - } - - /** - * Make a string's first character lowercase. - * - * @return MutableString - */ - public function toLowerFirst(): MutableString - { - $this->value = parent::doToLowerFirst($this->value); - - return $this; - } - - /** - * This method returns a new instance padded on the left to the specified padding length minus - * the length of the instance's value. - * - * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will - * only be padded by the value of 2. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * This method supports chaning. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return MutableString - */ - public function padLeft(int $length, string $padding = " "): MutableString - { - $this->value = parent::doPadLeft($this->value, $length, $padding); - - return $this; - } - - /** - * This method returns a new instance padded on the left, exactly to the specified padding length. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return MutableString - */ - public function padLeftExtra(int $length, string $padding = " "): MutableString - { - $this->value = parent::doPadLeftExtra($this->value, $length, $padding); - - return $this; - } - - /** - * This method returns a new instance padded on the right to the specified padding length minus - * the length of the instance's value. - * - * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will - * only be padded by the value of 2. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * This method supports chaning. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return MutableString - */ - public function padRight(int $length, string $padding = " "): MutableString - { - $this->value = parent::doPadRight($this->value, $length, $padding); - - return $this; - } - - /** - * This method returns a new instance padded on the right, exactly to the specified padding length. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws \InvalidArgumentException - If any of the parameters is invalid. - * @return MutableString - */ - public function padRightExtra(int $length, string $padding = " "): MutableString - { - $this->value = parent::doPadRightExtra($this->value, $length, $padding); - - return $this; - } - - /** - * This method mutates the instance's value with a portion of the original value, specified by the - * $start and $length parameters. - * - * $start parameter: - * - If $start is non-negative, the returned an instance will start at the $start'th position in - * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the - * character at position 2 is 'c', and so forth. - * - If $start is negative, the returned string will start at the $start'th character from the end - * of string. - * - If the absolute value of $start is higher than the instance's length, an - * exception is thrown. - * - * - * $length parameter: - * - If $length is given and is positive, the string returned will contain at most length characters - * beginning from $start (depending on the length of string). - * - If $length is given and is negative, then that many characters will be omitted from the end of string - * (after the start position has been calculated when a start is negative). - * - If $length exceeds the remaining number of characters, after the $start calculation, an - * Exception will be raised. - * - * - * @param int $start - Start of the sub-string. Can be negative. - * @param int $length - Length of the sub-string. Can be negative. - * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return MutableString - */ - public function subString(int $start, int $length = null): MutableString - { - $this->value = parent::doSubString($this->value, $start, $length); - - return $this; - } - - /** - * This method mutates the instance's value with a portion of the original instance's value, starting at the - * beginning of the value, with the number of characters specified in the $length parameter. - * - * Same rules as MutableString::subString() are applied. - * - * @param int $length - Length of the sub-string. Must be positive. - * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * @return MutableString - */ - public function subLeft(int $length): MutableString - { - $this->value = parent::doSubLeft($this->value, $length); - - return $this; - } - - /** - * This method mutates the instance's value with a portion of the original instance's value, couting from the - * end of the value, with the number of characters specified in the $length parameter. - * - * Same rules as MutableString::subString() are applied. - * - * @param int $length - Length of the sub-string. Must be positive. - * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. - * @return MutableString - */ - public function subRight(int $length): MutableString - { - $this->value = parent::doSubRight($this->value, $length); - - return $this; - } - - /** - * This method reverses value of the instance. - * - * @return MutableString - */ - public function reverse(): MutableString - { - $this->value = parent::doReverse($this->value); - - return $this; - } - - /** - * This method replaces a string's occurance by another. - * - * @param string $search - The string to search for. - * @param string $replace - The search's replacement. - * - * @throws \InvalidArgumentException - If $search is empty. - * @return MutableString - */ - public function replace(string $search, string $replace): MutableString - { - $this->value = parent::doReplace($this->value, $search, $replace); - - return $this; - } -} From 63bec2f1238ff83f9469eaf1c12cc27720532019 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 22:52:20 +0100 Subject: [PATCH 035/193] docs: Improve documentation --- src/Scalar/AbstractBaseString.php | 6 +++--- src/Scalar/VoString.php | 21 +++++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 8280537..a47b2b0 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -221,7 +221,7 @@ private function validateStartAndLength(int $start, ?int $length): void } /** - * Trims instance's value + * Trims instance's value on both ends. * * @return string */ @@ -231,7 +231,7 @@ protected function doTrim(): string } /** - * Left trims instance's value. + * Trims instance's value only on the left. * * @return string */ @@ -241,7 +241,7 @@ protected function doTrimLeft(): string } /** - * Right trims instance's value. + * Trims instance's value only on the right. * * @return string */ diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index 0a729dc..0ab49bc 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -69,7 +69,7 @@ public function contains(VoString $search): bool * * @throws \InvalidArgumentException - If $search value is an empty string. * @throws \OutOfRangeException - If the $start is either too small, or too long. - * @return int|NULL + * @return int|null */ public function indexOf(VoString $search, int $start = 0): ?int { @@ -107,7 +107,7 @@ public function endsWith(VoString $search): bool * * @param VoString $search - Non empty string to search for in the instance. * @param int $start - The sub-string's offset/start. - * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. + * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. * * @throws \InvalidArgumentException - If supplied $search is empty. * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. @@ -118,6 +118,11 @@ public function count(VoString $search, int $start = 0, ?int $length = null): in return parent::doCount((string) $search, $start, $length); } + /** + * Trims instance's value on both ends. + * + * @return VoString + */ public function trim(): VoString { return VoString::create( @@ -126,7 +131,7 @@ public function trim(): VoString } /** - * Left trims instance's value, and returns a new instance of the object. + * Trims instance's value only on the left. * * @return VoString */ @@ -138,7 +143,7 @@ public function trimLeft(): VoString } /** - * Right trims instance's value, and returns a new instance of the object. + * Trims instance's value only on the right. * * @return VoString */ @@ -150,7 +155,7 @@ public function trimRight(): VoString } /** - * Converts the instance's value to Upper Case, and returns a new instance of the object. + * Converts the instance's value to Uppercase, and returns a new instance of the object. * * @return VoString */ @@ -162,7 +167,7 @@ public function toUpper(): VoString } /** - * Converts the instance's value first character to Upper Case, and returns a new instance + * Converts the instance's value first character to Uppercase, and returns a new instance * of the object. * * @return VoString @@ -190,7 +195,7 @@ public function toUpperWords(?VoString $delimiters = null): VoString } /** - * Converts the instance's value to Lower Case, and returns a new instance of the object. + * Converts the instance's value to Lowercase, and returns a new instance of the object. * * @return VoString */ @@ -202,7 +207,7 @@ public function toLower(): VoString } /** - * Converts the instance's value first character to Lower Case, and returns a new instance + * Converts the instance's value first character to Lowercase, and returns a new instance * of the object * * @return VoString From 3685165cd001b350c413a9e2395e7192051396f6 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 22:52:56 +0100 Subject: [PATCH 036/193] feat: Add String's Value Object with native string handling interface --- src/Scalar/NString.php | 404 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 src/Scalar/NString.php diff --git a/src/Scalar/NString.php b/src/Scalar/NString.php new file mode 100644 index 0000000..ad6970c --- /dev/null +++ b/src/Scalar/NString.php @@ -0,0 +1,404 @@ + Date: Tue, 1 Jun 2021 22:55:19 +0100 Subject: [PATCH 037/193] feat: Add conversion methods for String datatypes --- src/Scalar/NString.php | 10 ++++++++++ src/Scalar/VoString.php | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Scalar/NString.php b/src/Scalar/NString.php index ad6970c..01205ff 100644 --- a/src/Scalar/NString.php +++ b/src/Scalar/NString.php @@ -27,6 +27,16 @@ public static function create(string $value): NString return new NString($value); } + /** + * Returns a VoString object, containing this instance's value. + * + * @return VoString + */ + public function toVoString(): VoString + { + return VoString::create($this->value); + } + /** * Compares the values of 2 separate strings. * diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index 0ab49bc..34954f6 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -27,6 +27,16 @@ public static function create(string $value): VoString return new VoString($value); } + /** + * Returns a NString object, containing this instance's value. + * + * @return NString + */ + public function toNString(): NString + { + return NString::create($this->value); + } + /** * Compares the values of 2 separate instances. * From b5ef94924bc69178383efa39b8d73c593688d03a Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 1 Jun 2021 22:56:38 +0100 Subject: [PATCH 038/193] fix: Change returned type for replace() --- src/Scalar/NString.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Scalar/NString.php b/src/Scalar/NString.php index 01205ff..55dcbcf 100644 --- a/src/Scalar/NString.php +++ b/src/Scalar/NString.php @@ -403,11 +403,11 @@ public function reverse(): NString * @param string $replace - The search's replacement. * * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. - * @return VoString + * @return NString */ - public function replace(string $search, string $replace): VoString + public function replace(string $search, string $replace): NString { - return VoString::create( + return NString::create( parent::doReplace($search, $replace) ); } From 727b1ac222ef181ab25b4801df9f652cfd501683 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 12:28:36 +0100 Subject: [PATCH 039/193] docs: Improve namespace's documentation --- src/Scalar/AbstractBaseString.php | 13 +++-- src/Scalar/NString.php | 5 +- src/Scalar/README.md | 97 ++++++++++++++++++++++--------- src/Scalar/VoString.php | 5 +- 4 files changed, 83 insertions(+), 37 deletions(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index a47b2b0..b153f03 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -5,8 +5,11 @@ /** * Abstract Base String's Scalar Object class. * - * In this package, this class is used as a base, for both VoString Value Object datatype - * as well as for NatString native datatype. + * In this package, this class is used as a base, for all Value Object and/or Primitive based + * child classes. + * + * All native processing should be done/wrapped in this class, but the state should never + * change directly. * * @package Hradigital\Datatypes * @copyright Hradigital\Datatypes @@ -20,7 +23,9 @@ abstract class AbstractBaseString /** * Instantiates an AbstractBaseString child class. * - * @param string $value - Initial instance's value. + * Constructor should be kept protected, to allow child class manipulation, if required. + * + * @param string $value - Instance's initial state value. * @return void */ protected function __construct(string $value) @@ -39,7 +44,7 @@ public function __toString(): string } /** - * Returns the Instance's value character length. + * Returns the Instance's character length. * * @return int */ diff --git a/src/Scalar/NString.php b/src/Scalar/NString.php index 55dcbcf..2d3ae48 100644 --- a/src/Scalar/NString.php +++ b/src/Scalar/NString.php @@ -5,9 +5,10 @@ /** * String's Scalar Native/Primitive Object class. * - * Instanciate this class, if you want the initial instance's value to be preserved. + * Instanciate this class, if you want to be able to manipulate the Instance's value using + * a primitive interface (strings). * - * Fluent interface (chaning) is supported by mutators, but a new instance will be returned. + * Fluent interface (chaning) is supported by mutators, but a new instance will always be returned. * Original internal value will be immutable. * * @package Hradigital\Datatypes diff --git a/src/Scalar/README.md b/src/Scalar/README.md index 83c4dc5..3a787ac 100644 --- a/src/Scalar/README.md +++ b/src/Scalar/README.md @@ -1,38 +1,46 @@ # PHP Scalar Datatypes -Currently, this package supports only **Scalar Strings**. You can choose between `Immutable` and `Mutable` string objects. +Currently, this package supports only **Scalar Strings**. You can choose between `VoString` and `NString` string objects. **Scalar Strings** are wrapper objects around primitive `strings`, which encapsulate all string related funcionality into a single instance. -## Immutable vs. Mutable +## VoString vs. NString -`Mutable` and `Immutable` string datatypes will have the exact same functionality, but will have different instance management. +`VoString` and `NString` string datatypes will have the exact same functionality, but will have different instance management. Both types inherit commonly used `protected` functionality from parent `AbstractBaseString` class. Parent methods will map to native procedural string manipulation functions. Both types of classes implement `__toString()` method, which means you can directly print their result: ```php -// Example of an Immutable string. -$string = ImmutableString::fromString(" This Is A String "); +// Example of a VoString. +$voString = VoString::create(" This Is A String "); -echo $string; // Prints ' This Is A String ' +echo $voString; // Prints ' This Is A String ' ``` Use **accessor** methods to retrieve any information from within the instance. **Mutators** methods will manipulate the -value of the instance. +value of the instance. Both classes are immutable Value Objects, which means that, they will always return a new +instance of themselves when changing internal value, which should remain immutable in original instance. -Both `Mutable` and `Immutable` instances have _fluent interfaces_, and therefore you can chain mutator methods, and make -several changes in the same line of code. The main difference between the two types, is that `Mutable` instances will return -the same instance everytime, and therefore, will change the internal state as you call its _mutators_. `Immutable` instances -will instead return a new instance of the same type, with the processed value. +Both `VoString` and `NString` instances have _fluent interfaces_, and therefore you can chain mutator methods, and make +several changes in the same line of code. The main difference between the two types, is that `VoString` instances will +force all mutator's interfaces/methods to always use other `VoString` as parameters, and never primitive `strings`. Here are two examples: ```php -// Example of an Immutable string. -$string1 = ImmutableString::fromString(" This Is A String "); +// Example of a VoString string. +$string1 = VoString::create(" This Is A String "); + +// Overrite initial variable with returned instance. +// Notice that we use other VoString as parameters. +$search = VoString::create("This"); +$replace = VoString::create("That"); +$string1 = $string1->replace($search, $replace); + +// Perform operations on instance, and assign result to different variables. $string2 = $string1->trim(); $string3 = $string2->toLower(); @@ -44,22 +52,32 @@ if ($string1->equals($string2)) { echo "This will print, as both instances contain the same value."; } -echo "{$string1} still has the value ' This Is A String '."; -echo "{$string2} has the value 'This Is A String'."; -echo "{$string3} has the value 'this is a string'."; +echo "{$string1} still has the value ' That Is A String '."; +echo "{$string2} has the value 'That Is A String'."; +echo "{$string3} has the value 'that is a string'."; ``` ```php -// Example of a Mutable string. -$string1 = MutableString::fromString(" This Is A String "); +// Example of a NString string. +$string1 = NString::create(" This Is A String "); + +// Overrite initial variable with returned instance. +// Notice that we use primitive strings as parameters. +$search = "This"; +$replace = "That"; +$string1 = $string1->replace($search, $replace); + +// Perform operations on instance, and assign result to different variables. $string2 = $string1->trim(); $string3 = $string2->toLower(); if ($string1 === $string2 && $string1 === $string3 && $string2 === $string3) { - echo "This will print, as all are the same instance."; + echo "This will never print, as all are different instances."; } -echo "All variables have the same 'this is a string' value."; +echo "{$string1} still has the value ' That Is A String '."; +echo "{$string2} has the value 'That Is A String'."; +echo "{$string3} has the value 'that is a string'."; ``` ### Fluent Interfaces @@ -67,13 +85,14 @@ echo "All variables have the same 'this is a string' value."; You can also do the previous processing, by channing the methods, independently of what type of datatype it is. ```php -// Example of chaning methods. -$immutable = ImmutableString::fromString(" This Is A String "); -$mutable = MutableString::fromString(" This Is A String "); - -// Both will print out 'this is a string'. -echo $immutable->trim()->toLower(); -echo $mutable->trim()->toLower(); +// Example of the instance's fluent interface usage. +$string = NString::create(" This Is A String ") + ->replace("This", "That") + ->replace("String", "Great Feature") + ->trim() + ->toLower(); + +echo "{$string} has the value 'that is a great feature'"; ``` ### Class usage @@ -81,9 +100,29 @@ echo $mutable->trim()->toLower(); You can easily import, use and manipulate primitive native data in the following way: ```php -use Hradigital\Datatypes\Scalar\MutableString as Str; +use Hradigital\Datatypes\Scalar\VoString; // ... -$string = Str::fromString(' This is the string I am trying to manipulate. '); +$string = VoString::create(' This is the string I am trying to manipulate. '); +``` + +### Class conversion + +You can also convert from one type of string to the other. + +```php +// Originally creates an Instance of NString. +$string = NString::create('This is originally a NString.') + ->replace(' is ', ' was ') + ->toVoString(); + +echo get_class($string); // Should echo \Hradigital\Datatypes\Scalar\VoString +echo $string; // This was originally a NString. + +// Converts to original type. +$string = $string->replace(VoString::create(' was '), VoString::create(' is '))->toNString(); + +echo get_class($string); // Should echo \Hradigital\Datatypes\Scalar\NString +echo $string; // This is originally a NString. ``` diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index 34954f6..c5924e5 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -5,9 +5,10 @@ /** * String's Scalar Value Object class. * - * Instanciate this class, if you want the initial instance's value to be preserved. + * Instanciate this class, if you want to be able to manipulate the Instance's value always using + * Value Objects as interface. * - * Fluent interface (chaning) is supported by mutators, but a new instance will be returned. + * Fluent interface (chaning) is supported by mutators, but a new instance will always be returned. * Original internal value will be immutable. * * @package Hradigital\Datatypes From b9f06dc96c6f1cfc7a36ae1e355af9cde8a826cb Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 12:29:46 +0100 Subject: [PATCH 040/193] docs: Add missing word --- src/Scalar/AbstractBaseString.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index b153f03..3fde6cd 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -8,7 +8,7 @@ * In this package, this class is used as a base, for all Value Object and/or Primitive based * child classes. * - * All native processing should be done/wrapped in this class, but the state should never + * All native processing should be done/wrapped in this class, but the internal state should never * change directly. * * @package Hradigital\Datatypes From f3d43c851b22d32b5afed34c6355156fd12fe5bf Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 12:49:09 +0100 Subject: [PATCH 041/193] feat: Add new ParameterOutOfRangeException --- .../ParameterOutOfRangeException.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/Exceptions/Datatypes/ParameterOutOfRangeException.php diff --git a/src/Exceptions/Datatypes/ParameterOutOfRangeException.php b/src/Exceptions/Datatypes/ParameterOutOfRangeException.php new file mode 100644 index 0000000..73c6361 --- /dev/null +++ b/src/Exceptions/Datatypes/ParameterOutOfRangeException.php @@ -0,0 +1,20 @@ + Date: Wed, 2 Jun 2021 13:02:01 +0100 Subject: [PATCH 042/193] refactor: Replace native exceptions with package's domain ones --- src/Scalar/AbstractBaseString.php | 73 ++++++++++++++++--------------- src/Scalar/NString.php | 37 +++++++++------- src/Scalar/VoString.php | 37 +++++++++------- 3 files changed, 82 insertions(+), 65 deletions(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 3fde6cd..0892574 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -2,6 +2,9 @@ namespace Hradigital\Datatypes\Scalar; +use Hradigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use Hradigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; + /** * Abstract Base String's Scalar Object class. * @@ -73,14 +76,14 @@ protected function doEquals(string $string): bool * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ protected function doContains(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); + throw new NonEmptyStringException('$search'); } return ($this->doIndexOf($search) !== null); @@ -98,15 +101,15 @@ protected function doContains(string $search): bool * @param string $search - String to search for in the instance. * @param int $start - Search offset start. Defaults to ZERO. * - * @throws \InvalidArgumentException - If $search value is an empty string. - * @throws \OutOfRangeException - If the $start is either too small, or too long. + * @throws NonEmptyStringException - If $search value is an empty string. + * @throws ParameterOutOfRangeException - If the $start is either too small, or too long. * @return int|null */ protected function doIndexOf(string $search, int $start = 0): ?int { // Validates supplied parameters. if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); + throw new NonEmptyStringException('$search'); } if ($start) { $this->validateStartAndLength($start, null); @@ -128,14 +131,14 @@ protected function doIndexOf(string $search, int $start = 0): ?int * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ protected function doStartsWith(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); + throw new NonEmptyStringException('$search'); } return ($this->doIndexOf($search) === 0); @@ -146,14 +149,14 @@ protected function doStartsWith(string $search): bool * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ protected function doEndsWith(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); + throw new NonEmptyStringException('$search'); } return ($this->doSubString((0 - \strlen($search))) === $search); @@ -166,15 +169,15 @@ protected function doEndsWith(string $search): bool * @param int $start - The sub-string's offset/start. * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. * - * @throws \InvalidArgumentException - If supplied $search is empty. - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @throws NonEmptyStringException - If supplied $search is empty. + * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ protected function doCount(string $search, int $start = 0, ?int $length = null): int { // Validates supplied $search parameter. if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); + throw new NonEmptyStringException('$search'); } // Validates supplied $start and $length. @@ -194,7 +197,7 @@ protected function doCount(string $search, int $start = 0, ?int $length = null): * @param int $start - The sub-string's offset/start. * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return void */ private function validateStartAndLength(int $start, ?int $length): void @@ -205,9 +208,7 @@ private function validateStartAndLength(int $start, ?int $length): void // Validates the starting value. if ($absStart > $this->length()) { - throw new \OutOfRangeException( - "The Start's absolute value must be less than the total number of characters in the string." - ); + throw new ParameterOutOfRangeException('$start'); } // If supplied $length is NULL, no further validations are required. @@ -219,9 +220,7 @@ private function validateStartAndLength(int $start, ?int $length): void if (($start >= 0 && ($this->length() - $start < $absLength)) || ($start < 0 && $absLength > $absStart)) { - throw new \OutOfRangeException( - "The Length's absolute value cannot be higher than the number of available characters." - ); + throw new ParameterOutOfRangeException('$length'); } } @@ -320,17 +319,18 @@ protected function doToLowerFirst(): string * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padString's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return string */ protected function doPadLeft(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { - throw new \InvalidArgumentException("Supplied Length must be a positive integer."); + throw new ParameterOutOfRangeException('$length'); } if (\strlen($padding) === 0) { - throw new \InvalidArgumentException("Supplied padding must be a non empty string."); + throw new NonEmptyStringException('$padding'); } return \str_pad($this->value, $length, $padding, STR_PAD_LEFT); @@ -346,7 +346,8 @@ protected function doPadLeft(int $length, string $padding = " "): string * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return string */ protected function doPadLeftExtra(int $length, string $padding = " "): string @@ -368,17 +369,18 @@ protected function doPadLeftExtra(int $length, string $padding = " "): string * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return string */ protected function doPadRight(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { - throw new \InvalidArgumentException("Supplied Length must be a positive integer."); + throw new ParameterOutOfRangeException('$length'); } if (\strlen($padding) === 0) { - throw new \InvalidArgumentException("Supplied padding must be a non empty string."); + throw new NonEmptyStringException('$padding'); } return \str_pad($this->value, $length, $padding, STR_PAD_RIGHT); @@ -394,7 +396,8 @@ protected function doPadRight(int $length, string $padding = " "): string * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return string */ protected function doPadRightExtra(int $length, string $padding = " "): string @@ -427,7 +430,7 @@ protected function doPadRightExtra(int $length, string $padding = " "): string * @param int $start - Start of the sub-string. Can be negative. * @param int $length - Length of the sub-string. Can be negative. * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return string */ protected function doSubString(int $start, int $length = null): string @@ -451,14 +454,14 @@ protected function doSubString(int $start, int $length = null): string * * @param int $length - Length of the sub-string. Must be positive. * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. + * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. * @return string */ protected function doSubLeft(int $length): string { // Validates parameter. if ($length < 1) { - throw new \InvalidArgumentException("Supplied length must be a positive integer."); + throw new ParameterOutOfRangeException('$length'); } return $this->doSubString(0, $length); @@ -470,14 +473,14 @@ protected function doSubLeft(int $length): string * * @param int $length - Length of the sub-string. Must be positive. * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. + * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. * @return string */ protected function doSubRight(int $length): string { // Validates parameter. if ($length < 1) { - throw new \InvalidArgumentException("Supplied length must be a positive integer."); + throw new ParameterOutOfRangeException('$length'); } return $this->doSubString(0 - $length); @@ -499,17 +502,17 @@ protected function doReverse(): string * @param string $search - The string to search for. * @param string $replace - The search's replacement. * - * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. + * @throws NonEmptyStringException - If either $search or $replace are empty. * @return string */ protected function doReplace(string $search, string $replace): string { // Validates supplied parameters. if (\strlen($search) === 0) { - throw new \InvalidArgumentException("Supplied search must be a non empty string."); + throw new NonEmptyStringException('$search'); } if (\strlen($replace) === 0) { - throw new \InvalidArgumentException("Supplied replace must be a non empty string."); + throw new NonEmptyStringException('$replace'); } return \str_replace($search, $replace, $this->value); diff --git a/src/Scalar/NString.php b/src/Scalar/NString.php index 2d3ae48..92127cf 100644 --- a/src/Scalar/NString.php +++ b/src/Scalar/NString.php @@ -2,6 +2,9 @@ namespace Hradigital\Datatypes\Scalar; +use Hradigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use Hradigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; + /** * String's Scalar Native/Primitive Object class. * @@ -58,7 +61,7 @@ public function equals(string $string): bool * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ public function contains(string $search): bool @@ -78,8 +81,8 @@ public function contains(string $search): bool * @param string $search - String to search for in the instance. * @param int $start - Search offset start. Defaults to ZERO. * - * @throws \InvalidArgumentException - If $search value is an empty string. - * @throws \OutOfRangeException - If the $start is either too small, or too long. + * @throws NonEmptyStringException - If $search value is an empty string. + * @throws ParameterOutOfRangeException - If the $start is either too small, or too long. * @return int|null */ public function indexOf(string $search, int $start = 0): ?int @@ -92,7 +95,7 @@ public function indexOf(string $search, int $start = 0): ?int * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ public function startsWith(string $search): bool @@ -105,7 +108,7 @@ public function startsWith(string $search): bool * * @param string $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ public function endsWith(string $search): bool @@ -120,8 +123,8 @@ public function endsWith(string $search): bool * @param int $start - The sub-string's offset/start. * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. * - * @throws \InvalidArgumentException - If supplied $search is empty. - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @throws NonEmptyStringException - If supplied $search is empty. + * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ public function count(string $search, int $start = 0, ?int $length = null): int @@ -244,7 +247,8 @@ public function toLowerFirst(): NString * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return NString */ public function padLeft(int $length, string $padding = " "): NString @@ -264,7 +268,8 @@ public function padLeft(int $length, string $padding = " "): NString * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return NString */ public function padLeftExtra(int $length, string $padding = " "): NString @@ -288,7 +293,8 @@ public function padLeftExtra(int $length, string $padding = " "): NString * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return NString */ public function padRight(int $length, string $padding = " "): NString @@ -308,7 +314,8 @@ public function padRight(int $length, string $padding = " "): NString * @param string $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return NString */ public function padRightExtra(int $length, string $padding = " "): NString @@ -343,7 +350,7 @@ public function padRightExtra(int $length, string $padding = " "): NString * @param int $start - Start of the sub-string. Can be negative. * @param int $length - Length of the sub-string. Can be negative. * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return NString */ public function subString(int $start, int $length = null): NString @@ -359,7 +366,7 @@ public function subString(int $start, int $length = null): NString * * @param int $length - Length of the sub-string. Must be positive. * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. + * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. * @return NString */ public function subLeft(int $length): NString @@ -375,7 +382,7 @@ public function subLeft(int $length): NString * * @param int $length - Length of the sub-string. Must be positive. * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. + * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. * @return NString */ public function subRight(int $length): NString @@ -403,7 +410,7 @@ public function reverse(): NString * @param string $search - The string to search for. * @param string $replace - The search's replacement. * - * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. + * @throws NonEmptyStringException - If either $search or $replace are empty. * @return NString */ public function replace(string $search, string $replace): NString diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index c5924e5..4da2a4f 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -2,6 +2,9 @@ namespace Hradigital\Datatypes\Scalar; +use Hradigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use Hradigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; + /** * String's Scalar Value Object class. * @@ -58,7 +61,7 @@ public function equals(VoString $string): bool * * @param VoString $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ public function contains(VoString $search): bool @@ -78,8 +81,8 @@ public function contains(VoString $search): bool * @param VoString $search - String to search for in the instance. * @param int $start - Search offset start. Defaults to ZERO. * - * @throws \InvalidArgumentException - If $search value is an empty string. - * @throws \OutOfRangeException - If the $start is either too small, or too long. + * @throws NonEmptyStringException - If $search value is an empty string. + * @throws ParameterOutOfRangeException - If the $start is either too small, or too long. * @return int|null */ public function indexOf(VoString $search, int $start = 0): ?int @@ -92,7 +95,7 @@ public function indexOf(VoString $search, int $start = 0): ?int * * @param VoString $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ public function startsWith(VoString $search): bool @@ -105,7 +108,7 @@ public function startsWith(VoString $search): bool * * @param VoString $search - Non empty string to search for in the instance. * - * @throws \InvalidArgumentException - If supplied $search is empty. + * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ public function endsWith(VoString $search): bool @@ -120,8 +123,8 @@ public function endsWith(VoString $search): bool * @param int $start - The sub-string's offset/start. * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. * - * @throws \InvalidArgumentException - If supplied $search is empty. - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @throws NonEmptyStringException - If supplied $search is empty. + * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ public function count(VoString $search, int $start = 0, ?int $length = null): int @@ -244,7 +247,8 @@ public function toLowerFirst(): VoString * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return VoString */ public function padLeft(int $length, ?VoString $padding = null): VoString @@ -264,7 +268,8 @@ public function padLeft(int $length, ?VoString $padding = null): VoString * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return VoString */ public function padLeftExtra(int $length, ?VoString $padding = null): VoString @@ -288,7 +293,8 @@ public function padLeftExtra(int $length, ?VoString $padding = null): VoString * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return VoString */ public function padRight(int $length, ?VoString $padding = null): VoString @@ -308,7 +314,8 @@ public function padRight(int $length, ?VoString $padding = null): VoString * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * - * @throws \InvalidArgumentException - If any of the parameters is invalid. + * @throws NonEmptyStringException - If supplied $padding is empty. + * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. * @return VoString */ public function padRightExtra(int $length, ?VoString $padding = null): VoString @@ -343,7 +350,7 @@ public function padRightExtra(int $length, ?VoString $padding = null): VoString * @param int $start - Start of the sub-string. Can be negative. * @param int $length - Length of the sub-string. Can be negative. * - * @throws \OutOfRangeException - If the $start and/or $length is either too small, or too long. + * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return VoString */ public function subString(int $start, int $length = null): VoString @@ -359,7 +366,7 @@ public function subString(int $start, int $length = null): VoString * * @param int $length - Length of the sub-string. Must be positive. * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. + * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. * @return VoString */ public function subLeft(int $length): VoString @@ -375,7 +382,7 @@ public function subLeft(int $length): VoString * * @param int $length - Length of the sub-string. Must be positive. * - * @throws \InvalidArgumentException - If supplied Length is not a positive integer. + * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. * @return VoString */ public function subRight(int $length): VoString @@ -403,7 +410,7 @@ public function reverse(): VoString * @param VoString $search - The string to search for. * @param VoString $replace - The search's replacement. * - * @throws \InvalidArgumentException - If $search is empty, or count is a not a positive integer. + * @throws NonEmptyStringException - If either $search or $replace are empty. * @return VoString */ public function replace(VoString $search, VoString $replace): VoString From 575495342b413253d24a0d43d1fbfdc8ffa7ac5b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 13:50:51 +0100 Subject: [PATCH 043/193] tests: Remove deprecated test --- tests/Unit/Scalar/MutableStringTest.php | 98 ------------------------- 1 file changed, 98 deletions(-) delete mode 100644 tests/Unit/Scalar/MutableStringTest.php diff --git a/tests/Unit/Scalar/MutableStringTest.php b/tests/Unit/Scalar/MutableStringTest.php deleted file mode 100644 index 5663484..0000000 --- a/tests/Unit/Scalar/MutableStringTest.php +++ /dev/null @@ -1,98 +0,0 @@ -assertTrue( - ($original === $other), - 'Instances are meant to match.' - ); - } - - /** - * Asserts that the supplied instance, is from the correct type. - * - * @param AbstractBaseString $instance - Instance to be validated. - * - * @return void - */ - protected function checkCorrectInstanceType(AbstractBaseString $instance): void - { - $this->assertInstanceOf( - MutableString::class, - $instance, - 'Instance type, does not match MutableString.' - ); - } - - /** - * Initializes and returns a new instance for testing. - * - * This method has no return value, due to inheritance overriding. - * - * @param string $initialValue - Instance's initial value. - * - * @return AbstractBaseString - */ - protected function getInstance(string $initialValue): AbstractBaseString - { - return MutableString::fromString($initialValue); - } - - /** - * Checks instance can be cloned. - * - * @return void - */ - public function testCanCloneObject(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - $other = $original->toImmutable(); - - // Performs assertions. - $this->assertInstanceOf( - ImmutableString::class, - $other, - 'Instance type, does not match ImmutableString.' - ); - $this->assertEquals( - $original->__toString(), - $other->__toString(), - 'Instance values do not match.' - ); - $this->assertFalse( - ($original === $other), - 'Instances are meant to match.' - ); - } -} From e3456f270dcd6b30e55481bbe2f60de1d4d75d4e Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 15:52:15 +0100 Subject: [PATCH 044/193] refactor: Remove type hinting from inherited class attributes --- src/Exceptions/AbstractBaseException.php | 4 ++-- src/Exceptions/ConflictException.php | 4 ++-- src/Exceptions/Datatypes/InvalidEmailException.php | 2 +- src/Exceptions/Datatypes/InvalidStringLengthException.php | 2 +- src/Exceptions/Datatypes/NonEmptyStringException.php | 2 +- src/Exceptions/Datatypes/NonNegativeNumberException.php | 2 +- src/Exceptions/Datatypes/ParameterOutOfRangeException.php | 2 +- src/Exceptions/Datatypes/PositiveIntegerException.php | 2 +- src/Exceptions/DeniedAccessException.php | 4 ++-- .../Entities/RequiredEntityValueMissingException.php | 2 +- src/Exceptions/Entities/UnexpectedEntityValueException.php | 2 +- src/Exceptions/ExpectationFailedException.php | 4 ++-- src/Exceptions/FailedDependencyException.php | 4 ++-- src/Exceptions/ForbiddenException.php | 4 ++-- src/Exceptions/GoneException.php | 4 ++-- src/Exceptions/MethodNotAllowedException.php | 4 ++-- src/Exceptions/NotAcceptableException.php | 4 ++-- src/Exceptions/NotFoundException.php | 4 ++-- src/Exceptions/PreconditionFailedException.php | 4 ++-- src/Exceptions/PreconditionRequiredException.php | 4 ++-- src/Exceptions/RequestedRangeNotSatisfiableException.php | 4 ++-- src/Exceptions/TooManyRequestsException.php | 4 ++-- src/Exceptions/UnprocessableEntityException.php | 4 ++-- src/Exceptions/UnsupportedMediaTypeException.php | 4 ++-- 24 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/Exceptions/AbstractBaseException.php b/src/Exceptions/AbstractBaseException.php index 1dc9454..eb81cd6 100755 --- a/src/Exceptions/AbstractBaseException.php +++ b/src/Exceptions/AbstractBaseException.php @@ -21,10 +21,10 @@ abstract class AbstractBaseException extends \Exception { /** @var string $message - Exception's error message. */ - protected string $message = "An unspecified error occurred on the server."; + protected $message = "An unspecified error occurred on the server."; /** @var int $code - Exception's error code. */ - protected int $code = 500; + protected $code = 500; /** * Initializes the Base Exception. diff --git a/src/Exceptions/ConflictException.php b/src/Exceptions/ConflictException.php index fb3f07a..52c1c9c 100755 --- a/src/Exceptions/ConflictException.php +++ b/src/Exceptions/ConflictException.php @@ -18,10 +18,10 @@ class ConflictException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The action failed due to a conflict in the provided request."; + protected $message = "The action failed due to a conflict in the provided request."; /** @var int $code - Exception's error code. */ - protected int $code = 409; + protected $code = 409; /** * Initializes Base Conflist Exception. diff --git a/src/Exceptions/Datatypes/InvalidEmailException.php b/src/Exceptions/Datatypes/InvalidEmailException.php index bd2c168..bf9af38 100644 --- a/src/Exceptions/Datatypes/InvalidEmailException.php +++ b/src/Exceptions/Datatypes/InvalidEmailException.php @@ -13,7 +13,7 @@ class InvalidEmailException extends UnprocessableEntityException { /** @var string $message - Exception's error message. */ - protected string $message = "Provided e-mail field does not seam to be a valid e-mail address."; + protected $message = "Provided e-mail field does not seam to be a valid e-mail address."; /** @var string $messageWithName - Exception's error message when an attribute name is supplied. */ protected string $messageWithName = "Provided e-mail '%s' does not seam to be a valid e-mail address."; diff --git a/src/Exceptions/Datatypes/InvalidStringLengthException.php b/src/Exceptions/Datatypes/InvalidStringLengthException.php index e9b300b..1930a14 100644 --- a/src/Exceptions/Datatypes/InvalidStringLengthException.php +++ b/src/Exceptions/Datatypes/InvalidStringLengthException.php @@ -13,7 +13,7 @@ class InvalidStringLengthException extends UnprocessableEntityException { /** @var string $message - Exception's error message. */ - protected string $message = "Supplied field doesn't have required character length."; + protected $message = "Supplied field doesn't have required character length."; /** @var string $message - Exception's error message with field's name. */ protected string $messageWithName = "Field '%s' doesn't have required character length."; diff --git a/src/Exceptions/Datatypes/NonEmptyStringException.php b/src/Exceptions/Datatypes/NonEmptyStringException.php index 7dca7db..bb5e420 100644 --- a/src/Exceptions/Datatypes/NonEmptyStringException.php +++ b/src/Exceptions/Datatypes/NonEmptyStringException.php @@ -13,7 +13,7 @@ class NonEmptyStringException extends UnprocessableEntityException { /** @var string $message - Exception's error message. */ - protected string $message = "Supplied parameter must be non empty string."; + protected $message = "Supplied parameter must be non empty string."; /** @var string $message - Exception's error message with field's name. */ protected string $messageWithName = "Parameter '%s' must be a non empty string."; diff --git a/src/Exceptions/Datatypes/NonNegativeNumberException.php b/src/Exceptions/Datatypes/NonNegativeNumberException.php index 011639f..2959585 100644 --- a/src/Exceptions/Datatypes/NonNegativeNumberException.php +++ b/src/Exceptions/Datatypes/NonNegativeNumberException.php @@ -15,7 +15,7 @@ class NonNegativeNumberException extends UnprocessableEntityException { /** @var string $message - Exception's error message. */ - protected string $message = "Supplied parameter must be a non negative number."; + protected $message = "Supplied parameter must be a non negative number."; /** @var string $message - Exception's error message with field's name. */ protected string $messageWithName = "Parameter '%s' must be a non negative number."; diff --git a/src/Exceptions/Datatypes/ParameterOutOfRangeException.php b/src/Exceptions/Datatypes/ParameterOutOfRangeException.php index 73c6361..7b9bc54 100644 --- a/src/Exceptions/Datatypes/ParameterOutOfRangeException.php +++ b/src/Exceptions/Datatypes/ParameterOutOfRangeException.php @@ -13,7 +13,7 @@ class ParameterOutOfRangeException extends UnprocessableEntityException { /** @var string $message - Exception's error message. */ - protected string $message = "Supplied parameter is out of range."; + protected $message = "Supplied parameter is out of range."; /** @var string $message - Exception's error message with field's name. */ protected string $messageWithName = "Parameter '%s' is out of expected range."; diff --git a/src/Exceptions/Datatypes/PositiveIntegerException.php b/src/Exceptions/Datatypes/PositiveIntegerException.php index b79a672..d8d7ec6 100644 --- a/src/Exceptions/Datatypes/PositiveIntegerException.php +++ b/src/Exceptions/Datatypes/PositiveIntegerException.php @@ -13,7 +13,7 @@ class PositiveIntegerException extends UnprocessableEntityException { /** @var string $message - Exception's error message. */ - protected string $message = "Supplied parameter must be a positive integer."; + protected $message = "Supplied parameter must be a positive integer."; /** @var string $message - Exception's error message with field's name. */ protected string $messageWithName = "Parameter '%s' must be a positive integer."; diff --git a/src/Exceptions/DeniedAccessException.php b/src/Exceptions/DeniedAccessException.php index d483c9f..11e2e01 100644 --- a/src/Exceptions/DeniedAccessException.php +++ b/src/Exceptions/DeniedAccessException.php @@ -20,10 +20,10 @@ class DeniedAccessException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "You don't have access to the resource you are looking for."; + protected $message = "You don't have access to the resource you are looking for."; /** @var int $code - Exception's error code. */ - protected int $code = 401; + protected $code = 401; /** * Initializes Base Denied Access Exception. diff --git a/src/Exceptions/Entities/RequiredEntityValueMissingException.php b/src/Exceptions/Entities/RequiredEntityValueMissingException.php index 62f63ce..8acc4aa 100644 --- a/src/Exceptions/Entities/RequiredEntityValueMissingException.php +++ b/src/Exceptions/Entities/RequiredEntityValueMissingException.php @@ -19,7 +19,7 @@ class RequiredEntityValueMissingException extends UnprocessableEntityException { /** @var string $message - Exception's error message. */ - protected string $message = "A Required Entity field was missing, while loading."; + protected $message = "A Required Entity field was missing, while loading."; /** @var string $message - Exception's error message with field's name. */ protected string $messageWithName = "Entity field '%s' was missing, while loading."; diff --git a/src/Exceptions/Entities/UnexpectedEntityValueException.php b/src/Exceptions/Entities/UnexpectedEntityValueException.php index 7fbae0a..e65ec28 100644 --- a/src/Exceptions/Entities/UnexpectedEntityValueException.php +++ b/src/Exceptions/Entities/UnexpectedEntityValueException.php @@ -13,7 +13,7 @@ class UnexpectedEntityValueException extends UnprocessableEntityException { /** @var string $message - Exception's error message. */ - protected string $message = "Application tried to load one or more unexpected values into the Entity."; + protected $message = "Application tried to load one or more unexpected values into the Entity."; /** @var string $message - Exception's error message. */ protected string $messageWithName = "Field '%s' had an unexpected value, while loading into an Entity."; diff --git a/src/Exceptions/ExpectationFailedException.php b/src/Exceptions/ExpectationFailedException.php index 2e3948e..123db39 100644 --- a/src/Exceptions/ExpectationFailedException.php +++ b/src/Exceptions/ExpectationFailedException.php @@ -18,10 +18,10 @@ class ExpectationFailedException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The operation failed due to a previous Expectation not being met."; + protected $message = "The operation failed due to a previous Expectation not being met."; /** @var int $code - Exception's error code. */ - protected int $code = 417; + protected $code = 417; /** * Initializes Base Expectation Failed Exception. diff --git a/src/Exceptions/FailedDependencyException.php b/src/Exceptions/FailedDependencyException.php index bf031c5..491d8f0 100755 --- a/src/Exceptions/FailedDependencyException.php +++ b/src/Exceptions/FailedDependencyException.php @@ -18,10 +18,10 @@ class FailedDependencyException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The action failed due to failure of a previous action."; + protected $message = "The action failed due to failure of a previous action."; /** @var int $code - Exception's error code. */ - protected int $code = 424; + protected $code = 424; /** * Initializes Base Conflist Exception. diff --git a/src/Exceptions/ForbiddenException.php b/src/Exceptions/ForbiddenException.php index 3c5305a..31e1bc0 100644 --- a/src/Exceptions/ForbiddenException.php +++ b/src/Exceptions/ForbiddenException.php @@ -20,10 +20,10 @@ class ForbiddenException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "You were forbidden to access the resource you were looking for."; + protected $message = "You were forbidden to access the resource you were looking for."; /** @var int $code - Exception's error code. */ - protected int $code = 403; + protected $code = 403; /** * Initializes Base Forbidden Exception. diff --git a/src/Exceptions/GoneException.php b/src/Exceptions/GoneException.php index d91e791..625014f 100755 --- a/src/Exceptions/GoneException.php +++ b/src/Exceptions/GoneException.php @@ -16,13 +16,13 @@ class GoneException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The resource you are looking for, is no longer available in the system."; + protected $message = "The resource you are looking for, is no longer available in the system."; /** @var string $message - Exception's error message when a record ID is specified. */ protected string $messageWithId = "The resource with the ID %d no longer exists in the system."; /** @var int $code - Exception's error code. */ - protected int $code = 410; + protected $code = 410; /** * Initializes Base Record Gone Exception. diff --git a/src/Exceptions/MethodNotAllowedException.php b/src/Exceptions/MethodNotAllowedException.php index 4c192cb..98cb41d 100755 --- a/src/Exceptions/MethodNotAllowedException.php +++ b/src/Exceptions/MethodNotAllowedException.php @@ -20,10 +20,10 @@ class MethodNotAllowedException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The action failed due using a request method not supported by that resource."; + protected $message = "The action failed due using a request method not supported by that resource."; /** @var int $code - Exception's error code. */ - protected int $code = 405; + protected $code = 405; /** * Initializes Base Method not Allowed Exception. diff --git a/src/Exceptions/NotAcceptableException.php b/src/Exceptions/NotAcceptableException.php index cdc577f..565bac6 100644 --- a/src/Exceptions/NotAcceptableException.php +++ b/src/Exceptions/NotAcceptableException.php @@ -18,10 +18,10 @@ class NotAcceptableException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The operation you're trying to perform, is not acceptable."; + protected $message = "The operation you're trying to perform, is not acceptable."; /** @var int $code - Exception's error code. */ - protected int $code = 406; + protected $code = 406; /** * Initializes Base Not Acceptable Exception. diff --git a/src/Exceptions/NotFoundException.php b/src/Exceptions/NotFoundException.php index f28b587..94baad8 100755 --- a/src/Exceptions/NotFoundException.php +++ b/src/Exceptions/NotFoundException.php @@ -16,13 +16,13 @@ class NotFoundException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The resource you are looking for, was not found in the system."; + protected $message = "The resource you are looking for, was not found in the system."; /** @var string $message - Exception's error message when a record ID is specified. */ protected string $messageWithId = "The resource with the ID %d you are looking for, was not found in the system."; /** @var int $code - Exception's error code. */ - protected int $code = 404; + protected $code = 404; /** * Initializes Base NotFound Exception. diff --git a/src/Exceptions/PreconditionFailedException.php b/src/Exceptions/PreconditionFailedException.php index 1329cfa..53a5d89 100755 --- a/src/Exceptions/PreconditionFailedException.php +++ b/src/Exceptions/PreconditionFailedException.php @@ -18,10 +18,10 @@ class PreconditionFailedException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "A given precondition evaluated to false on the system."; + protected $message = "A given precondition evaluated to false on the system."; /** @var int $code - Exception's error code. */ - protected int $code = 412; + protected $code = 412; /** * Initializes Base Precondition Failed Exception. diff --git a/src/Exceptions/PreconditionRequiredException.php b/src/Exceptions/PreconditionRequiredException.php index 2fe7f09..ccf4941 100644 --- a/src/Exceptions/PreconditionRequiredException.php +++ b/src/Exceptions/PreconditionRequiredException.php @@ -13,10 +13,10 @@ class PreconditionRequiredException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "A given required precondition evaluated to false on the system."; + protected $message = "A given required precondition evaluated to false on the system."; /** @var int $code - Exception's error code. */ - protected int $code = 428; + protected $code = 428; /** * Initializes Base Precondition Required Exception. diff --git a/src/Exceptions/RequestedRangeNotSatisfiableException.php b/src/Exceptions/RequestedRangeNotSatisfiableException.php index 1cb12c0..d63cf15 100644 --- a/src/Exceptions/RequestedRangeNotSatisfiableException.php +++ b/src/Exceptions/RequestedRangeNotSatisfiableException.php @@ -19,10 +19,10 @@ class RequestedRangeNotSatisfiableException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The requested range for the operation you're trying to perform, is not satisfiable."; + protected $message = "The requested range for the operation you're trying to perform, is not satisfiable."; /** @var int $code - Exception's error code. */ - protected int $code = 416; + protected $code = 416; /** * Initializes Base Requested Range is Not Satisfiable Exception. diff --git a/src/Exceptions/TooManyRequestsException.php b/src/Exceptions/TooManyRequestsException.php index fd8696e..7523e5f 100755 --- a/src/Exceptions/TooManyRequestsException.php +++ b/src/Exceptions/TooManyRequestsException.php @@ -18,10 +18,10 @@ class TooManyRequestsException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "Too many requests have been made to the system."; + protected $message = "Too many requests have been made to the system."; /** @var int $code - Exception's error code. */ - protected int $code = 429; + protected $code = 429; /** * Initializes Base Too Many Requests Exception. diff --git a/src/Exceptions/UnprocessableEntityException.php b/src/Exceptions/UnprocessableEntityException.php index d1a528f..7610d70 100644 --- a/src/Exceptions/UnprocessableEntityException.php +++ b/src/Exceptions/UnprocessableEntityException.php @@ -19,13 +19,13 @@ class UnprocessableEntityException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The request was well-formed but was unable to be followed due to semantic errors."; + protected $message = "The request was well-formed but was unable to be followed due to semantic errors."; /** @var string $messageWithName - Exception's error message when an attribute name is supplied. */ protected string $messageWithName = "The request was well-formed but was unable to be followed due to field '%s'."; /** @var int $code - Exception's error code. */ - protected int $code = 422; + protected $code = 422; /** * Initializes Base Unprocessable Entity Exception. diff --git a/src/Exceptions/UnsupportedMediaTypeException.php b/src/Exceptions/UnsupportedMediaTypeException.php index 4bcfeb4..2dca1aa 100755 --- a/src/Exceptions/UnsupportedMediaTypeException.php +++ b/src/Exceptions/UnsupportedMediaTypeException.php @@ -18,13 +18,13 @@ class UnsupportedMediaTypeException extends AbstractBaseException { /** @var string $message - Exception's error message. */ - protected string $message = "The supplied MediaType is not supported by the system."; + protected $message = "The supplied MediaType is not supported by the system."; /** @var string $message - Exception's error message when Media Type is supplied. */ protected string $messageWithName = "MediaType '%s' is not supported by the system."; /** @var int $code - Exception's error code. */ - protected int $code = 415; + protected $code = 415; /** * Initializes Base Unsupported Media Type Exception. From ab3d8df3a54c508eeb2f7e9428da55739a8fd782 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 15:53:20 +0100 Subject: [PATCH 045/193] fix: Changed parent method's call --- src/Scalar/NString.php | 2 +- src/Scalar/VoString.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Scalar/NString.php b/src/Scalar/NString.php index 92127cf..eb875be 100644 --- a/src/Scalar/NString.php +++ b/src/Scalar/NString.php @@ -66,7 +66,7 @@ public function equals(string $string): bool */ public function contains(string $search): bool { - return parent::doEquals($search); + return parent::doContains($search); } /** diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index 4da2a4f..afbcf29 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -66,7 +66,7 @@ public function equals(VoString $string): bool */ public function contains(VoString $search): bool { - return parent::doEquals((string) $search); + return parent::doContains((string) $search); } /** From 3eef7a1a47c41833bdd8f572173f6af4b3f2fc80 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 16:26:46 +0100 Subject: [PATCH 046/193] fix: Improve padding mutators --- src/Scalar/VoString.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index afbcf29..1873b9c 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -253,6 +253,10 @@ public function toLowerFirst(): VoString */ public function padLeft(int $length, ?VoString $padding = null): VoString { + if ($padding !== null && $padding->length() === 0) { + $padding = null; + } + return VoString::create( parent::doPadLeft($length, ((string) $padding ?: " ")) ); @@ -274,6 +278,10 @@ public function padLeft(int $length, ?VoString $padding = null): VoString */ public function padLeftExtra(int $length, ?VoString $padding = null): VoString { + if ($padding !== null && $padding->length() === 0) { + $padding = null; + } + return VoString::create( parent::doPadLeftExtra($length, ((string) $padding ?: " ")) ); @@ -299,6 +307,10 @@ public function padLeftExtra(int $length, ?VoString $padding = null): VoString */ public function padRight(int $length, ?VoString $padding = null): VoString { + if ($padding !== null && $padding->length() === 0) { + $padding = null; + } + return VoString::create( parent::doPadRight($length, ((string) $padding ?: " ")) ); @@ -320,6 +332,10 @@ public function padRight(int $length, ?VoString $padding = null): VoString */ public function padRightExtra(int $length, ?VoString $padding = null): VoString { + if ($padding !== null && $padding->length() === 0) { + $padding = null; + } + return VoString::create( parent::doPadRightExtra($length, ((string) $padding ?: " ")) ); From b124a7c3d92611fe9f39b2f48d1e733430caa764 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 16:31:16 +0100 Subject: [PATCH 047/193] fix: Improve padding mutators --- src/Scalar/VoString.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index 1873b9c..85ae203 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -253,12 +253,12 @@ public function toLowerFirst(): VoString */ public function padLeft(int $length, ?VoString $padding = null): VoString { - if ($padding !== null && $padding->length() === 0) { - $padding = null; + if ($padding === null) { + $padding = VoString::create(" "); } return VoString::create( - parent::doPadLeft($length, ((string) $padding ?: " ")) + parent::doPadLeft($length, ((string) $padding ?? " ")) ); } @@ -278,12 +278,12 @@ public function padLeft(int $length, ?VoString $padding = null): VoString */ public function padLeftExtra(int $length, ?VoString $padding = null): VoString { - if ($padding !== null && $padding->length() === 0) { - $padding = null; + if ($padding === null) { + $padding = VoString::create(" "); } return VoString::create( - parent::doPadLeftExtra($length, ((string) $padding ?: " ")) + parent::doPadLeftExtra($length, ((string) $padding ?? " ")) ); } @@ -307,12 +307,12 @@ public function padLeftExtra(int $length, ?VoString $padding = null): VoString */ public function padRight(int $length, ?VoString $padding = null): VoString { - if ($padding !== null && $padding->length() === 0) { - $padding = null; + if ($padding === null) { + $padding = VoString::create(" "); } return VoString::create( - parent::doPadRight($length, ((string) $padding ?: " ")) + parent::doPadRight($length, ((string) $padding ?? " ")) ); } @@ -332,12 +332,12 @@ public function padRight(int $length, ?VoString $padding = null): VoString */ public function padRightExtra(int $length, ?VoString $padding = null): VoString { - if ($padding !== null && $padding->length() === 0) { - $padding = null; + if ($padding === null) { + $padding = VoString::create(" "); } return VoString::create( - parent::doPadRightExtra($length, ((string) $padding ?: " ")) + parent::doPadRightExtra($length, ((string) $padding ?? " ")) ); } From 840799373a1dcdeacc49263f9d9fd1ff4500a282 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 16:32:31 +0100 Subject: [PATCH 048/193] fix: Change factory method for tested class --- tests/Unit/Web/EmailAddressTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Unit/Web/EmailAddressTest.php b/tests/Unit/Web/EmailAddressTest.php index 81e60f3..17a79d1 100644 --- a/tests/Unit/Web/EmailAddressTest.php +++ b/tests/Unit/Web/EmailAddressTest.php @@ -22,7 +22,7 @@ public function testLoadsSuccessfully(): void { // Performs test. $emailString = 'user@domain.tld'; - $email = EmailAddress::fromString($emailString); + $email = EmailAddress::create($emailString); // Performs assertions. $this->assertInstanceOf( @@ -66,7 +66,7 @@ public function testConvertsToLowerCase(): void { // Performs test. $emailString = 'User@DoMaiN.Tld'; - $email = EmailAddress::fromString($emailString); + $email = EmailAddress::create($emailString); // Performs assertions. $this->assertEquals( @@ -87,7 +87,7 @@ public function testBreaksIfEmptyAddressSupplied(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - EmailAddress::fromString(''); + EmailAddress::create(''); } /** @@ -101,7 +101,7 @@ public function testBreaksIfInvalidAddressSupplied(): void $this->expectException(\InvalidArgumentException::class); // Performs test. - EmailAddress::fromString('This is not an email address'); + EmailAddress::create('This is not an email address'); } /** @@ -113,7 +113,7 @@ public function testSerializesAndDeserializesCorrectly(): void { // Performs test. $emailString = 'user@domain.tld'; - $email1 = EmailAddress::fromString($emailString); + $email1 = EmailAddress::create($emailString); $serialized = \serialize($email1); $email2 = \unserialize($serialized); From 4543bd9c95f5ca507307a75ec96c9ff895d3a476 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 16:32:58 +0100 Subject: [PATCH 049/193] tests: Adapt tests for Scalar Value Objects --- tests/Unit/Scalar/IStringTest.php | 1162 ---------------------------- tests/Unit/Scalar/NStringTest.php | 508 ++++++++++++ tests/Unit/Scalar/README.md | 2 + tests/Unit/Scalar/VoStringTest.php | 538 +++++++++++++ 4 files changed, 1048 insertions(+), 1162 deletions(-) delete mode 100644 tests/Unit/Scalar/IStringTest.php create mode 100644 tests/Unit/Scalar/NStringTest.php create mode 100644 tests/Unit/Scalar/VoStringTest.php diff --git a/tests/Unit/Scalar/IStringTest.php b/tests/Unit/Scalar/IStringTest.php deleted file mode 100644 index 2eb54ed..0000000 --- a/tests/Unit/Scalar/IStringTest.php +++ /dev/null @@ -1,1162 +0,0 @@ -assertFalse( - ($original === $other), - 'Instances are not meant to match.' - ); - } - - /** - * Asserts that the supplied instance, is from the correct type. - * - * @param AbstractBaseString $instance - Instance to be validated. - * - * @return void - */ - protected function checkCorrectInstanceType(AbstractBaseString $instance): void - { - $this->assertInstanceOf( - IString::class, - $instance, - 'Instance type, does not match IString.' - ); - } - - /** - * Initializes and returns a new instance for testing. - * - * This method has no return value, due to inheritance overriding. - * - * @param string $initialValue - Instance's initial value. - * - * @return AbstractBaseString - */ - protected function getInstance(string $initialValue): AbstractBaseString - { - return IString::create($initialValue); - } - - /** - * Checks Equality of two distinct strings. - * - * @return void - */ - public function testCanCheckEquality(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = $this->getInstance(" Immutable string. "); - - // Performs assertions. - $this->assertTrue( - $original->equals($other), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($original); - $this->checkCorrectInstanceType($other); - } - - /** - * Tests that we can check of String contains a text portion. - * - * @return void - */ - public function testCanCheckIfStringContainsPortion(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - - // Performs assertions. - $this->assertTrue( - $original->contains('muta'), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($original); - } - - /** - * Tests that method breaks if invalid parameters are passed. - * - * @return void - */ - public function testBreaksCheckingIfStringContainsPortionWithEmptyText(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - - // Create expectations. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original->contains(''); - } - - /** - * Tests can retrieve string's length. - * - * @return void - */ - public function testCanRetrieveLength(): void - { - // Performs test. - $original = "Immutable string."; - $instance = $this->getInstance($original); - - // Performs assertions. - $this->assertEquals( - \strlen($original), - $instance->length(), - 'Length values do not match.' - ); - $this->checkCorrectInstanceType($instance); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testCanRetrieveIndexOf(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $indexOf = $instance->indexOf('string'); - - // Performs assertions. - $this->assertEquals( - 10, - $indexOf, - 'Retrieved index is incorrect.' - ); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testCanRetrieveIndexOfWithStart(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $indexOf = $instance->indexOf('string', 15); - - // Performs assertions. - $this->assertEquals( - 37, - $indexOf, - 'Retrieved index is incorrect.' - ); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testIndexOfReturnsNullIfNotFound(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $indexOf = $instance->indexOf('another'); - - // Performs assertions. - $this->assertNull( - $indexOf, - 'Retrieved index should have been NULL.' - ); - } - - /** - * Test indexOf() breaks with illegal parameters. - * - * @return void - */ - public function testBreaksIndexOfIfEmptySearch(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->indexOf(''); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testCanCheckIfStringStartsWithText(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $true = $instance->startsWith("Immu"); - $false = $instance->startsWith("string"); - - // Performs assertions. - $this->assertTrue($true); - $this->assertFalse($false); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testBreaksCheckingIfStringStartsWithText(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->startsWith(''); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testCanCheckIfStringEndsWithText(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $true = $instance->endsWith("string."); - $false = $instance->endsWith("Immu"); - - // Performs assertions. - $this->assertTrue($true); - $this->assertFalse($false); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testBreaksCheckingIfStringEndsWithText(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->endsWith(''); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInString(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count('string'); - - // Performs assertions. - $this->assertEquals( - 2, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInStringWithStartAndLength(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count('string', 15, 29); - - // Performs assertions. - $this->assertEquals( - 1, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInStringIfNoneIsFound(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count('string', 38, 4); - - // Performs assertions. - $this->assertEquals( - 0, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() breaks if empty search is supplied. - * - * @return void - */ - public function testBreaksCountNumberOccurencesInStringIfSerachIsEmpty(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $instance->count(''); - } - - /** - * Tests that a string can be trimmed. - * - * @return void - */ - public function testCanTrimString(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = $original->trim(); - - // Performs assertions. - $this->assertEquals( - 'Immutable string.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be trimmed only on the left. - * - * @return void - */ - public function testCanLeftTrimString(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = $original->trimLeft(); - - // Performs assertions. - $this->assertEquals( - 'Immutable string. ', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be trimmed only on the right. - * - * @return void - */ - public function testCanRightTrimString(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = $original->trimRight(); - - // Performs assertions. - $this->assertEquals( - ' Immutable string.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be converted to UPPER case. - * - * @return void - */ - public function testCanUpperCaseString(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - $other = $original->toUpper(); - - // Performs assertions. - $this->assertEquals( - 'IMMUTABLE STRING.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be converted to UPPER case. - * - * @return void - */ - public function testCanUpperCaseFirst(): void - { - // Performs test. - $original = $this->getInstance("immutable string."); - $other = $original->toUpperFirst(); - - // Performs assertions. - $this->assertEquals( - 'Immutable string.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be convert to UPPER case, all words. - * - * @return void - */ - public function testCanUpperCaseWords(): void - { - // Performs test. - $original = $this->getInstance("immutable string."); - $other = $original->toUpperWords(); - - // Performs assertions. - $this->assertEquals( - 'Immutable String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be converted to LOWER case. - * - * @return void - */ - public function testCanLowerCaseString(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->toLower(); - - // Performs assertions. - $this->assertEquals( - 'immutable string.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be converted to LOWER case. - * - * @return void - */ - public function testCanLowerCaseFirst(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->toLowerFirst(); - - // Performs assertions. - $this->assertEquals( - 'immutable String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeft(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeft(\strlen($string) + 2); - - // Performs assertions. - $this->assertEquals( - ' Immutable String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string is not padded on the left, when the padding length is less than the string's length. - * - * @return void - */ - public function testCanPadOnTheLeftWithoutResult(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeft(2); - - // Performs assertions. - $this->assertEquals( - $string, - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeftExtra(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeftExtra(2); - - // Performs assertions. - $this->assertEquals( - ' Immutable String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPaddingOnTheLeftBreaksWithInvalidLength(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeft(0); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPaddingOnTheLeftBreaksWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeft(2, ''); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPaddingOnTheLeftExtraBreaksWithInvalidLength(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeftExtra(0); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPaddingOnTheLeftExtraBreaksWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeftExtra(2, ''); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeftWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeft(\strlen($string) + 2, '_'); - - // Performs assertions. - $this->assertEquals( - '__Immutable String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeftExtraWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeftExtra(2, '_'); - - // Performs assertions. - $this->assertEquals( - '__Immutable String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRight(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRight(\strlen($string) + 2); - - // Performs assertions. - $this->assertEquals( - 'Immutable String. ', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRightExtra(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRightExtra(2); - - // Performs assertions. - $this->assertEquals( - 'Immutable String. ', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPadOnTheRightBreaksWithInvalidLength(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRight(0); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPadOnTheRightBreaksWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRight(2, ''); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPadOnTheRightExtraBreaksWithInvalidLength(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRightExtra(0); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPadOnTheRightExtraBreaksWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRightExtra(2, ''); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRightWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRight(\strlen($string) + 2, '_'); - - // Performs assertions. - $this->assertEquals( - 'Immutable String.__', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRightExtraWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRightExtra(2, '_'); - - // Performs assertions. - $this->assertEquals( - 'Immutable String.__', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a simple substring can be retrieved. - * - * @return void - */ - public function testSubStringCanBeRetrieved(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subString(10); - - // Performs assertions. - $this->assertEquals( - 'String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a simple substring can be retrieved. - * - * @return void - */ - public function testSubStringCanBeRetrievedWithNegativeStart(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subString(-7); - - // Performs assertions. - $this->assertEquals( - 'String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a simple substring can be retrieved. - * - * @return void - */ - public function testSubStringCanBeRetrievedWithLength(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subString(2, 7); - - // Performs assertions. - $this->assertEquals( - 'mutable', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that a simple substring can be retrieved. - * - * @return void - */ - public function testSubStringCanBeRetrievedWithNegativeLength(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subString(2, -8); - - // Performs assertions. - $this->assertEquals( - 'mutable', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that substring breaks. - * - * @return void - */ - public function testSubStringBreaksWithShortStart(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subString(-30); - } - - /** - * Tests that substring breaks. - * - * @return void - */ - public function testSubStringBreaksWithLongStart(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subString(30); - } - - /** - * Tests that substring breaks. - * - * @return void - */ - public function testSubStringBreaksWithShortLength(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subString(0, -30); - } - - /** - * Tests that substring breaks. - * - * @return void - */ - public function testSubStringBreaksWithLongLength(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subString(0, 30); - } - - /** - * Tests that a simple subLeft can be retrieved. - * - * @return void - */ - public function testSubStringLeftCanBeRetrieved(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subLeft(10); - - // Performs assertions. - $this->assertEquals( - 'Immutable ', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that subLeft() breaks. - * - * @return void - */ - public function testSubStringLeftBreaksWithShortLength(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subLeft(-1); - } - - /** - * Tests that subLeft() breaks. - * - * @return void - */ - public function testSubStringLeftBreaksWithLongLength(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subLeft(30); - } - - /** - * Tests that a simple subRight() can be retrieved. - * - * @return void - */ - public function testSubStringRightCanBeRetrieved(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subRight(10); - - // Performs assertions. - $this->assertEquals( - 'le String.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that subRight() breaks. - * - * @return void - */ - public function testSubStringRightBreaksWithShortLength(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subRight(-1); - } - - /** - * Tests that subRight() breaks. - * - * @return void - */ - public function testSubStringRightBreaksWithLongLength(): void - { - // Creates expectation. - $this->expectException(\OutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subRight(30); - } - - /** - * Tests that a string can be reversed. - * - * @return void - */ - public function testStringCanBeReversed(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->reverse(); - - // Performs assertions. - $this->assertEquals( - '.gnirtS elbatummI', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that text can be replaced in the String. - * - * @return void - */ - public function testTextCanBeReplacedInString(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->replace('String', 'Object'); - - // Performs assertions. - $this->assertEquals( - 'Immutable Object.', - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that text is not replaced if search is not found. - * - * @return void - */ - public function testTextIsNotReplacedIfSearchNotFound(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->replace('None', 'Object'); - - // Performs assertions. - $this->assertEquals( - $original->__toString(), - $other->__toString(), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkInstances($original, $other); - } - - /** - * Tests that text replace breaks. - * - * @return void - */ - public function testTextReplaceBreaksIfSearchIsEmpty(): void - { - // Creates expectation. - $this->expectException(\InvalidArgumentException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->replace('', 'Object'); - } -} diff --git a/tests/Unit/Scalar/NStringTest.php b/tests/Unit/Scalar/NStringTest.php new file mode 100644 index 0000000..798e233 --- /dev/null +++ b/tests/Unit/Scalar/NStringTest.php @@ -0,0 +1,508 @@ +assertFalse( + ($original === $other), + 'Instances are not meant to match.' + ); + } + + /** @inheritDoc */ + protected function checkCorrectInstanceType(AbstractBaseString $instance): void + { + $this->assertInstanceOf( + NString::class, + $instance, + 'Instance type, does not match NString.' + ); + } + + /** + * Checks Equality of two distinct strings. + * + * @return void + */ + public function testCanCheckEquality(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = " Immutable string. "; + + // Performs assertions. + $this->assertTrue( + $original->equals($other), + 'Instance values do not match.' + ); + } + + /** + * Tests that we can check of String contains a text portion. + * + * @return void + */ + public function testCanCheckIfStringContainsPortion(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + + // Performs assertions. + $this->assertTrue( + $original->contains('muta'), + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($original); + } + + /** + * Tests that method breaks if invalid parameters are passed. + * + * @return void + */ + public function testBreaksCheckingIfStringContainsPortionWithEmptyText(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + + // Create expectations. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original->contains(''); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testCanRetrieveIndexOf(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $indexOf = $instance->indexOf('string'); + + // Performs assertions. + $this->assertEquals( + 10, + $indexOf, + 'Retrieved index is incorrect.' + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testCanRetrieveIndexOfWithStart(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $indexOf = $instance->indexOf('string', 15); + + // Performs assertions. + $this->assertEquals( + 37, + $indexOf, + 'Retrieved index is incorrect.' + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testIndexOfReturnsNullIfNotFound(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $indexOf = $instance->indexOf('another'); + + // Performs assertions. + $this->assertNull( + $indexOf, + 'Retrieved index should have been NULL.' + ); + } + + /** + * Test indexOf() breaks with illegal parameters. + * + * @return void + */ + public function testBreaksIndexOfIfEmptySearch(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->indexOf(''); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testCanCheckIfStringStartsWithText(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $true = $instance->startsWith("Immu"); + $false = $instance->startsWith("string"); + + // Performs assertions. + $this->assertTrue($true, 'String should have started with searched text.'); + $this->assertFalse($false, 'String should not have started with searched text.'); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testBreaksCheckingIfStringStartsWithText(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->startsWith(''); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testCanCheckIfStringEndsWithText(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $true = $instance->endsWith("string."); + $false = $instance->endsWith("Immu"); + + // Performs assertions. + $this->assertTrue($true, 'String should have ended with searched text.'); + $this->assertFalse($false, 'String should not have ended with searched text.'); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testBreaksCheckingIfStringEndsWithText(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->endsWith(''); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInString(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count('string'); + + // Performs assertions. + $this->assertEquals( + 2, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInStringWithStartAndLength(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count('string', 15, 29); + + // Performs assertions. + $this->assertEquals( + 1, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInStringIfNoneIsFound(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count('string', 38, 4); + + // Performs assertions. + $this->assertEquals( + 0, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() breaks if empty search is supplied. + * + * @return void + */ + public function testBreaksCountNumberOccurencesInStringIfSerachIsEmpty(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $instance->count(''); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksPaddingOnTheLeftWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padLeft(2, ''); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPaddingOnTheLeftExtraWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padLeftExtra(2, ''); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeftWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeft(\strlen($string) + 2, '_'); + + // Performs assertions. + $this->assertEquals( + '__Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeftExtraWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeftExtra(2, '_'); + + // Performs assertions. + $this->assertEquals( + '__Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPadOnTheRightWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padRight(2, ''); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPadOnTheRightExtraWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padRightExtra(2, ''); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRightWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRight(\strlen($string) + 2, '_'); + + // Performs assertions. + $this->assertEquals( + 'Immutable String.__', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRightExtraWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRightExtra(2, '_'); + + // Performs assertions. + $this->assertEquals( + 'Immutable String.__', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text can be replaced in the String. + * + * @return void + */ + public function testTextCanBeReplacedInString(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->replace('String', 'Object'); + + // Performs assertions. + $this->assertEquals( + 'Immutable Object.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text is not replaced if search is not found. + * + * @return void + */ + public function testTextIsNotReplacedIfSearchNotFound(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->replace('None', 'Object'); + + // Performs assertions. + $this->assertEquals( + (string) $original, + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text replace breaks. + * + * @return void + */ + public function testBreaksTextReplaceIfSearchIsEmpty(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->replace('', 'Object'); + } +} diff --git a/tests/Unit/Scalar/README.md b/tests/Unit/Scalar/README.md index d1a9493..192ec14 100644 --- a/tests/Unit/Scalar/README.md +++ b/tests/Unit/Scalar/README.md @@ -1 +1,3 @@ # Scalar related Unit tests + +String related Unit tests should extend `AbstractBaseStringTestBase` for shared functionality. diff --git a/tests/Unit/Scalar/VoStringTest.php b/tests/Unit/Scalar/VoStringTest.php new file mode 100644 index 0000000..ba3d115 --- /dev/null +++ b/tests/Unit/Scalar/VoStringTest.php @@ -0,0 +1,538 @@ +assertFalse( + ($original === $other), + 'Instances are not meant to match.' + ); + } + + /** @inheritDoc */ + protected function checkCorrectInstanceType(AbstractBaseString $instance): void + { + $this->assertInstanceOf( + VoString::class, + $instance, + 'Instance type, does not match VoString.' + ); + } + + /** + * Checks Equality of two distinct strings. + * + * @return void + */ + public function testCanCheckEquality(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $this->getInstance(" Immutable string. "); + + // Performs assertions. + $this->assertTrue( + $original->equals($other), + 'Instance values do not match.' + ); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that we can check of String contains a text portion. + * + * @return void + */ + public function testCanCheckIfStringContainsPortion(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + $search = $this->getInstance('muta'); + + // Performs assertions. + $this->assertTrue( + $original->contains($search), + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($original); + $this->checkDifferentInstances($original, $search); + } + + /** + * Tests that method breaks if invalid parameters are passed. + * + * @return void + */ + public function testBreaksCheckingIfStringContainsPortionWithEmptyText(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + + // Create expectations. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original->contains( + $this->getInstance('') + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testCanRetrieveIndexOf(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $search = $this->getInstance('string'); + $indexOf = $instance->indexOf($search); + + // Performs assertions. + $this->assertEquals( + 10, + $indexOf, + 'Retrieved index is incorrect.' + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testCanRetrieveIndexOfWithStart(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $search = $this->getInstance('string'); + $indexOf = $instance->indexOf($search, 15); + + // Performs assertions. + $this->assertEquals( + 37, + $indexOf, + 'Retrieved index is incorrect.' + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testIndexOfReturnsNullIfNotFound(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $search = $this->getInstance('another'); + $indexOf = $instance->indexOf($search); + + // Performs assertions. + $this->assertNull( + $indexOf, + 'Retrieved index should have been NULL.' + ); + } + + /** + * Test indexOf() breaks with illegal parameters. + * + * @return void + */ + public function testBreaksIndexOfIfEmptySearch(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->indexOf( + $this->getInstance('') + ); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testCanCheckIfStringStartsWithText(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $true = $instance->startsWith( + $this->getInstance("Immu") + ); + $false = $instance->startsWith( + $this->getInstance("string") + ); + + // Performs assertions. + $this->assertTrue($true, 'String should have started with searched text.'); + $this->assertFalse($false, 'String should not have started with searched text.'); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testBreaksCheckingIfStringStartsWithText(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->startsWith( + $this->getInstance('') + ); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testCanCheckIfStringEndsWithText(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $true = $instance->endsWith($this->getInstance("string.")); + $false = $instance->endsWith($this->getInstance("Immu")); + + // Performs assertions. + $this->assertTrue($true, 'String should have ended with searched text.'); + $this->assertFalse($false, 'String should not have ended with searched text.'); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testBreaksCheckingIfStringEndsWithText(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->endsWith( + $this->getInstance('') + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInString(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count( + $this->getInstance('string') + ); + + // Performs assertions. + $this->assertEquals( + 2, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInStringWithStartAndLength(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $search = $this->getInstance('another'); + $count = $instance->count($search, 15, 29); + + // Performs assertions. + $this->assertEquals( + 1, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInStringIfNoneIsFound(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $search = $this->getInstance('another'); + $count = $instance->count($search, 38, 4); + + // Performs assertions. + $this->assertEquals( + 0, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() breaks if empty search is supplied. + * + * @return void + */ + public function testBreaksCountNumberOccurencesInStringIfSerachIsEmpty(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $instance->count( + $this->getInstance('') + ); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksPaddingOnTheLeftWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padLeft(2, $this->getInstance('')); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPaddingOnTheLeftExtraWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padLeftExtra(2, $this->getInstance('')); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeftWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeft(\strlen($string) + 2, $this->getInstance('_')); + + // Performs assertions. + $this->assertEquals( + '__Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeftExtraWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeftExtra(2, $this->getInstance('_')); + + // Performs assertions. + $this->assertEquals( + '__Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPadOnTheRightWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padRight(2, $this->getInstance('')); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPadOnTheRightExtraWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padRightExtra(2, $this->getInstance('')); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRightWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRight(\strlen($string) + 2, $this->getInstance('_')); + + // Performs assertions. + $this->assertEquals( + 'Immutable String.__', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRightExtraWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRightExtra(2, $this->getInstance('_')); + + // Performs assertions. + $this->assertEquals( + 'Immutable String.__', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text can be replaced in the String. + * + * @return void + */ + public function testTextCanBeReplacedInString(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $search = $this->getInstance('String'); + $replace = $this->getInstance('Object'); + $other = $original->replace($search, $replace); + + // Performs assertions. + $this->assertEquals( + 'Immutable Object.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text is not replaced if search is not found. + * + * @return void + */ + public function testTextIsNotReplacedIfSearchNotFound(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $search = $this->getInstance('None'); + $replace = $this->getInstance('Object'); + $other = $original->replace($search, $replace); + + // Performs assertions. + $this->assertEquals( + (string) $original, + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text replace breaks. + * + * @return void + */ + public function testBreaksTextReplaceIfSearchIsEmpty(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $search = $this->getInstance(''); + $replace = $this->getInstance('Object'); + $original->replace($search, $replace); + } +} From eb9b4cf7c3a670acdfd2313c78f0540d3977e68e Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 16:33:50 +0100 Subject: [PATCH 050/193] tests: Add missing AbstractBaseStringTestBase --- .../Scalar/AbstractBaseStringTestBase.php | 662 ++++++++++++++++++ 1 file changed, 662 insertions(+) create mode 100644 tests/Unit/Scalar/AbstractBaseStringTestBase.php diff --git a/tests/Unit/Scalar/AbstractBaseStringTestBase.php b/tests/Unit/Scalar/AbstractBaseStringTestBase.php new file mode 100644 index 0000000..b08b5be --- /dev/null +++ b/tests/Unit/Scalar/AbstractBaseStringTestBase.php @@ -0,0 +1,662 @@ +getInstance($string); + + // Performs assertions. + $this->assertEquals( + $string, + (string) $instance, + 'Instance value does not seam to match.' + ); + $this->checkCorrectInstanceType($instance); + } + + /** + * Checks that String's length retrieval works. + * + * @return void + */ + public function testCanRetrieveLengthCorrectly(): void + { + // Performs test. + $string = " Immutable string. "; + $instance = $this->getInstance($string); + + // Performs assertions. + $this->assertEquals( + \strlen($string), + $instance->length(), + 'Instance character length does not seam to match.' + ); + } + + /** + * Tests that a string can be trimmed. + * + * @return void + */ + public function testCanTrimString(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $original->trim(); + + // Performs assertions. + $this->assertEquals( + 'Immutable string.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be trimmed only on the left. + * + * @return void + */ + public function testCanLeftTrimString(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $original->trimLeft(); + + // Performs assertions. + $this->assertEquals( + 'Immutable string. ', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be trimmed only on the right. + * + * @return void + */ + public function testCanRightTrimString(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $original->trimRight(); + + // Performs assertions. + $this->assertEquals( + ' Immutable string.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be converted to UPPER case. + * + * @return void + */ + public function testCanUpperCaseString(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + $other = $original->toUpper(); + + // Performs assertions. + $this->assertEquals( + 'IMMUTABLE STRING.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be converted to UPPER case. + * + * @return void + */ + public function testCanUpperCaseFirst(): void + { + // Performs test. + $original = $this->getInstance("immutable string."); + $other = $original->toUpperFirst(); + + // Performs assertions. + $this->assertEquals( + 'Immutable string.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be convert to UPPER case, all words. + * + * @return void + */ + public function testCanUpperCaseWords(): void + { + // Performs test. + $original = $this->getInstance("immutable string."); + $other = $original->toUpperWords(); + + // Performs assertions. + $this->assertEquals( + 'Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be converted to LOWER case. + * + * @return void + */ + public function testCanLowerCaseString(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->toLower(); + + // Performs assertions. + $this->assertEquals( + 'immutable string.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be converted to LOWER case. + * + * @return void + */ + public function testCanLowerCaseFirst(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->toLowerFirst(); + + // Performs assertions. + $this->assertEquals( + 'immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeft(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeft(\strlen($string) + 2); + + // Performs assertions. + $this->assertEquals( + ' Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string is not padded on the left, when the padding length is less than the string's length. + * + * @return void + */ + public function testCanPadOnTheLeftWithoutResult(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeft(2); + + // Performs assertions. + $this->assertEquals( + $string, + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeftExtra(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeftExtra(2); + + // Performs assertions. + $this->assertEquals( + ' Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksPaddingOnTheLeftWithInvalidLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padLeft(0); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRight(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRight(\strlen($string) + 2); + + // Performs assertions. + $this->assertEquals( + 'Immutable String. ', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRightExtra(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRightExtra(2); + + // Performs assertions. + $this->assertEquals( + 'Immutable String. ', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testCanPadOnTheRightBreaksWithInvalidLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padRight(0); + } + + /** + * Tests that a simple substring can be retrieved. + * + * @return void + */ + public function testSubStringCanBeRetrieved(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subString(10); + + // Performs assertions. + $this->assertEquals( + 'String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a simple substring can be retrieved. + * + * @return void + */ + public function testSubStringCanBeRetrievedWithNegativeStart(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subString(-7); + + // Performs assertions. + $this->assertEquals( + 'String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a simple substring can be retrieved. + * + * @return void + */ + public function testSubStringCanBeRetrievedWithLength(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subString(2, 7); + + // Performs assertions. + $this->assertEquals( + 'mutable', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a simple substring can be retrieved. + * + * @return void + */ + public function testSubStringCanBeRetrievedWithNegativeLength(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subString(2, -8); + + // Performs assertions. + $this->assertEquals( + 'mutable', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that substring breaks. + * + * @return void + */ + public function testBreaksSubStringWithShortStart(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subString(-30); + } + + /** + * Tests that substring breaks. + * + * @return void + */ + public function testBreaksSubStringWithLongStart(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subString(30); + } + + /** + * Tests that substring breaks. + * + * @return void + */ + public function testBreaksSubStringWithShortLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subString(0, -30); + } + + /** + * Tests that substring breaks. + * + * @return void + */ + public function testBreaksSubStringWithLongLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subString(0, 30); + } + + /** + * Tests that a simple subLeft can be retrieved. + * + * @return void + */ + public function testSubStringLeftCanBeRetrieved(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subLeft(10); + + // Performs assertions. + $this->assertEquals( + 'Immutable ', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that subLeft() breaks. + * + * @return void + */ + public function testBreaksSubStringLeftWithShortLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subLeft(-1); + } + + /** + * Tests that subLeft() breaks. + * + * @return void + */ + public function testBreaksSubStringLeftWithLongLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subLeft(30); + } + + /** + * Tests that a simple subRight() can be retrieved. + * + * @return void + */ + public function testSubStringRightCanBeRetrieved(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subRight(10); + + // Performs assertions. + $this->assertEquals( + 'le String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that subRight() breaks. + * + * @return void + */ + public function testBreaksSubStringRightWithShortLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subRight(-1); + } + + /** + * Tests that subRight() breaks. + * + * @return void + */ + public function testBreaksSubStringRightWithLongLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subRight(30); + } + + /** + * Tests that a string can be reversed. + * + * @return void + */ + public function testStringCanBeReversed(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->reverse(); + + // Performs assertions. + $this->assertEquals( + '.gnirtS elbatummI', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } +} From c69e9c0cb161a3eb8aff14dbd140f6e130431173 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 16:48:01 +0100 Subject: [PATCH 051/193] refactor: Convert internal data and exceptions to package domain objects --- src/Web/EmailAddress.php | 59 +++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 97d7fdd..abdb5ce 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -2,6 +2,10 @@ namespace Hradigital\Datatypes\Web; +use Hradigital\Datatypes\Exceptions\Datatypes\InvalidEmailException; +use Hradigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use Hradigital\Datatypes\Scalar\VoString; + /** * E-mail address datatype. * @@ -13,14 +17,14 @@ */ class EmailAddress implements \Serializable { - /** @var string $username - Holds the Username's part of the E-mail address. */ - protected string $username; + /** @var VoString $username - Holds the Username's part of the E-mail address. */ + protected VoString $username; - /** @var string $domain - Holds the Domain part of the E-mail address. */ - protected string $domain; + /** @var VoString $domain - Holds the Domain part of the E-mail address. */ + protected VoString $domain; - /** @var string $tld - Holds the Top Level Domain part of the E-mail address. */ - protected string $tld; + /** @var VoString $tld - Holds the Top Level Domain part of the E-mail address. */ + protected VoString $tld; /** * Loads a new EmailAddress instance from a native string. @@ -56,23 +60,25 @@ protected function __construct(string $email) */ protected function loadFromPrimitive(string $email): void { + // Converts supplied primitive to VoString. + $voEmail = VoString::create($email)->trim()->toLower(); + // Validate supplied parameter. - if (\strlen(\trim($email)) === 0) { - throw new \InvalidArgumentException("Supplied e-mail address must be a non empty string."); + if ($voEmail->length() === 0) { + throw new NonEmptyStringException('$email'); } - if (!\filter_var($email, FILTER_VALIDATE_EMAIL)) { - throw new \InvalidArgumentException("Provided e-mail field does not seam to be a valid e-mail address."); + if (!\filter_var((string) $email, FILTER_VALIDATE_EMAIL)) { + throw new InvalidEmailException($email); } // Sanitizes and processes supplied e-mail address. - $email = \strtolower(\trim($email)); - $parts = \explode('@', $email); - $this->username = $parts[0]; + $parts = \explode('@', (string) $voEmail); + $this->username = VoString::create($parts[0]); // Processes the right side of the e-mail address. $domain = \explode('.', $parts[1]); - $this->tld = \array_pop($domain); - $this->domain = \implode('.', $domain); + $this->tld = VoString::create(\array_pop($domain)); + $this->domain = VoString::create(\implode('.', $domain)); } /** @@ -81,7 +87,9 @@ protected function loadFromPrimitive(string $email): void */ public function serialize() { - return \serialize($this->address()); + return \serialize( + (string) $this->address() + ); } /** @@ -102,7 +110,7 @@ public function unserialize($serialized) */ public function __toString(): string { - return $this->address(); + return (string) $this->address(); } /** @@ -110,9 +118,16 @@ public function __toString(): string * * @return string */ - public function address(): string + public function address(): VoString { - return ($this->username . '@' . $this->domain . '.' . $this->tld); + return VoString::create( + \sprintf( + "%s@%s.%s", + (string) $this->username, + (string) $this->domain, + (string) $this->tld + ) + ); } /** @@ -120,7 +135,7 @@ public function address(): string * * @return string */ - public function username(): string + public function username(): VoString { return $this->username; } @@ -130,7 +145,7 @@ public function username(): string * * @return string */ - public function domain(): string + public function domain(): VoString { return $this->domain; } @@ -140,7 +155,7 @@ public function domain(): string * * @return string */ - public function tld(): string + public function tld(): VoString { return $this->tld; } From c650ce047c749bd39691b5fcd336b06d59838c8e Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 16:48:15 +0100 Subject: [PATCH 052/193] tests: Adapt tests for EmailAddress --- tests/Unit/Web/EmailAddressTest.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/Unit/Web/EmailAddressTest.php b/tests/Unit/Web/EmailAddressTest.php index 17a79d1..29920fa 100644 --- a/tests/Unit/Web/EmailAddressTest.php +++ b/tests/Unit/Web/EmailAddressTest.php @@ -2,6 +2,8 @@ namespace Hradigital\Tests\Datatypes\Unit\Web; +use Hradigital\Datatypes\Exceptions\Datatypes\InvalidEmailException; +use Hradigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use Hradigital\Datatypes\Web\EmailAddress; use Hradigital\Tests\Datatypes\AbstractBaseTestCase; @@ -32,27 +34,27 @@ public function testLoadsSuccessfully(): void ); $this->assertEquals( $emailString, - $email->__toString(), + (string) $email, 'Loaded state does not match inital value.' ); $this->assertEquals( $emailString, - $email->address(), + (string) $email->address(), 'Addresses do not match.' ); $this->assertEquals( 'user', - $email->username(), + (string) $email->username(), 'Usernames do not match.' ); $this->assertEquals( 'domain', - $email->domain(), + (string) $email->domain(), 'Domains do not match.' ); $this->assertEquals( 'tld', - $email->tld(), + (string) $email->tld(), 'TLDs do not match.' ); } @@ -71,7 +73,7 @@ public function testConvertsToLowerCase(): void // Performs assertions. $this->assertEquals( \strtolower(\trim($emailString)), - $email->__toString(), + (string) $email, 'Trimmed and lower cased strings do not match.' ); } @@ -84,7 +86,7 @@ public function testConvertsToLowerCase(): void public function testBreaksIfEmptyAddressSupplied(): void { // Creates expectation. - $this->expectException(\InvalidArgumentException::class); + $this->expectException(NonEmptyStringException::class); // Performs test. EmailAddress::create(''); @@ -98,7 +100,7 @@ public function testBreaksIfEmptyAddressSupplied(): void public function testBreaksIfInvalidAddressSupplied(): void { // Creates expectation. - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidEmailException::class); // Performs test. EmailAddress::create('This is not an email address'); @@ -130,13 +132,13 @@ public function testSerializesAndDeserializesCorrectly(): void 'Returned instance is not of type EmailAddress.' ); $this->assertEquals( - $email1->__toString(), - $email2->__toString(), + (string) $email1, + (string) $email2, 'Addresses do not match.' ); $this->assertNotEquals( $serialized, - $email2->__toString(), + (string) $email2, 'Addresses do not match.' ); } From 042abdeb3543d11100919bf31cf0da953c253098 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 16:55:46 +0100 Subject: [PATCH 053/193] style: Fix coding standards --- tests/Unit/Scalar/NStringTest.php | 2 +- tests/Unit/Scalar/VoStringTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Scalar/NStringTest.php b/tests/Unit/Scalar/NStringTest.php index 798e233..4f0b86b 100644 --- a/tests/Unit/Scalar/NStringTest.php +++ b/tests/Unit/Scalar/NStringTest.php @@ -242,7 +242,7 @@ public function testCanCountNumberOccurencesInString(): void // Performs assertions. $this->assertEquals( - 2, + 2, $count, 'Retrieved count is incorrect.' ); diff --git a/tests/Unit/Scalar/VoStringTest.php b/tests/Unit/Scalar/VoStringTest.php index ba3d115..e071964 100644 --- a/tests/Unit/Scalar/VoStringTest.php +++ b/tests/Unit/Scalar/VoStringTest.php @@ -262,7 +262,7 @@ public function testCanCountNumberOccurencesInString(): void // Performs assertions. $this->assertEquals( - 2, + 2, $count, 'Retrieved count is incorrect.' ); From 1e69a583cac23ac4362d823fbd32a6c9144e968c Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 17:05:55 +0100 Subject: [PATCH 054/193] refactor: Remove deprecated Traits --- .../Datetime/CanAddAndSubtractPartsTrait.php | 311 ------------------ .../Datetime/CanFormatOutputTrait.php | 214 ------------ .../Datetime/CanRetrievePartsTrait.php | 140 -------- .../Datatypes/Datetime/CanSetPartsTrait.php | 164 --------- .../Datetime/HasStaticMethodsTrait.php | 122 ------- .../CanLoadAndSerializeDataTrait.php | 97 ------ .../HasStaticFactoryMethodsTrait.php | 29 -- .../String/HasManipulationMethodsTrait .php | 146 -------- .../String/HasReportingMethodsTrait.php | 49 --- .../String/HasStaticMethodsTrait.php | 27 -- 10 files changed, 1299 deletions(-) delete mode 100644 src/Traits/Datatypes/Datetime/CanAddAndSubtractPartsTrait.php delete mode 100644 src/Traits/Datatypes/Datetime/CanFormatOutputTrait.php delete mode 100644 src/Traits/Datatypes/Datetime/CanRetrievePartsTrait.php delete mode 100644 src/Traits/Datatypes/Datetime/CanSetPartsTrait.php delete mode 100644 src/Traits/Datatypes/Datetime/HasStaticMethodsTrait.php delete mode 100644 src/Traits/Datatypes/EmailAddress/CanLoadAndSerializeDataTrait.php delete mode 100644 src/Traits/Datatypes/EmailAddress/HasStaticFactoryMethodsTrait.php delete mode 100644 src/Traits/Datatypes/String/HasManipulationMethodsTrait .php delete mode 100644 src/Traits/Datatypes/String/HasReportingMethodsTrait.php delete mode 100644 src/Traits/Datatypes/String/HasStaticMethodsTrait.php diff --git a/src/Traits/Datatypes/Datetime/CanAddAndSubtractPartsTrait.php b/src/Traits/Datatypes/Datetime/CanAddAndSubtractPartsTrait.php deleted file mode 100644 index 4ffc31d..0000000 --- a/src/Traits/Datatypes/Datetime/CanAddAndSubtractPartsTrait.php +++ /dev/null @@ -1,311 +0,0 @@ -addYears(1); - - return $this; - } - - /** - * Add the supplied number of Years to the instance. - * - * Supports chaining. - * - * @param int $years - Number of years to add to instance. Supports negative numbers for subtraction. - * - * @return self - */ - public function addYears(int $years): self - { - $this->carbon->addYears($years); - - return $this; - } - - /** - * Returns the different between the current instance an the provided one, in Years. - * - * @param self $dt - instance to compare with. - * @param bool $absolute - Gets the absolute of the difference. - * - * @return int - */ - public function differenceInYears(self $dt, bool $absolute = true): int - { - return $this->carbon->diffInYears( - Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), - $absolute - ); - } - - /** - * Add a single Month to the instance. - * - * Supports chaining. - * - * @return self - */ - public function addMonth(): self - { - $this->addMonths(1); - - return $this; - } - - /** - * Add the supplied number of Months to the instance. - * - * Supports chaining. - * - * @param int $months - Number of Months to add to instance. Supports negative numbers for subtraction. - * - * @return self - */ - public function addMonths(int $months): self - { - $this->carbon->addMonths($months); - - return $this; - } - - /** - * Returns the different between the current instance an the provided one, in Months. - * - * @param self $dt - instance to compare with. - * @param bool $absolute - Gets the absolute of the difference. - * - * @return int - */ - public function differenceInMonths(self $dt, bool $absolute = true): int - { - return $this->carbon->diffInMonths( - Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), - $absolute - ); - } - - /** - * Returns the different between the current instance an the provided one, in Weeks. - * - * @param self $dt - instance to compare with. - * @param bool $absolute - Gets the absolute of the difference. - * - * @return int - */ - public function differenceInWeeks(self $dt, bool $absolute = true): int - { - return $this->carbon->diffInWeeks( - Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), - $absolute - ); - } - - /** - * Add a single Day to the instance. - * - * Supports chaining. - * - * @return self - */ - public function addDay(): self - { - $this->addDays(1); - - return $this; - } - - /** - * Add the supplied number of Days to the instance. - * - * Supports chaining. - * - * @param int $days - Number of Days to add to instance. Supports negative numbers for subtraction. - * - * @return self - */ - public function addDays(int $days): self - { - $this->carbon->addDays($days); - - return $this; - } - - /** - * Returns the different between the current instance an the provided one, in Days. - * - * @param self $dt - instance to compare with. - * @param bool $absolute - Gets the absolute of the difference. - * - * @return int - */ - public function differenceInDays(self $dt, bool $absolute = true): int - { - return $this->carbon->diffInDays( - Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), - $absolute - ); - } - - /** - * Add a single Hour to the instance. - * - * Supports chaining. - * - * @return self - */ - public function addHour(): self - { - $this->addHours(1); - - return $this; - } - - /** - * Add the supplied number of Hours to the instance. - * - * Supports chaining. - * - * @param int $hours - Number of Hours to add to instance. Supports negative numbers for subtraction. - * - * @return self - */ - public function addHours(int $hours): self - { - $this->carbon->addHours($hours); - - return $this; - } - - /** - * Returns the different between the current instance an the provided one, in Hours. - * - * @param self $dt - instance to compare with. - * @param bool $absolute - Gets the absolute of the difference. - * - * @return int - */ - public function differenceInHours(self $dt, bool $absolute = true): int - { - return $this->carbon->diffInHours( - Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), - $absolute - ); - } - - /** - * Add a single Minute to the instance. - * - * Supports chaining. - * - * @return self - */ - public function addMinute(): self - { - $this->addMinutes(1); - - return $this; - } - - /** - * Add the supplied number of Minutes to the instance. - * - * Supports chaining. - * - * @param int $minutes - Number of Minutes to add to instance. Supports negative numbers for subtraction. - * - * @return self - */ - public function addMinutes(int $minutes): self - { - $this->carbon->addMinutes($minutes); - - return $this; - } - - /** - * Returns the different between the current instance an the provided one, in Minutes. - * - * @param self $dt - instance to compare with. - * @param bool $absolute - Gets the absolute of the difference. - * - * @return int - */ - public function differenceInMinutes(self $dt, bool $absolute = true): int - { - return $this->carbon->diffInMinutes( - Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), - $absolute - ); - } - - /** - * Add a single Second to the instance. - * - * Supports chaining. - * - * @return self - */ - public function addSecond(): self - { - $this->addSeconds(1); - - return $this; - } - - /** - * Add the supplied number of Seconds to the instance. - * - * Supports chaining. - * - * @param int $seconds - Number of Seconds to add to instance. Supports negative numbers for subtraction. - * - * @return self - */ - public function addSeconds(int $seconds): self - { - $this->carbon->addSeconds($seconds); - - return $this; - } - - /** - * Returns the different between the current instance an the provided one, in Seconds. - * - * @param self $dt - instance to compare with. - * @param bool $absolute - Gets the absolute of the difference. - * - * @return int - */ - public function differenceInSeconds(self $dt, bool $absolute = true): int - { - return $this->carbon->diffInSeconds( - Carbon::createFromTimestamp($dt->getTimestamp(), $dt->getTimezone()), - $absolute - ); - } -} diff --git a/src/Traits/Datatypes/Datetime/CanFormatOutputTrait.php b/src/Traits/Datatypes/Datetime/CanFormatOutputTrait.php deleted file mode 100644 index e53f2a9..0000000 --- a/src/Traits/Datatypes/Datetime/CanFormatOutputTrait.php +++ /dev/null @@ -1,214 +0,0 @@ -carbon->format($format); - } - - /** - * Retrieves the Timestamp representation from the instance. - * - * @return integer - */ - public function toTimestamp(): int - { - return $this->carbon->timestamp; - } - - /** - * Format the instance as Date. - * - * @return string - */ - public function toDateString(): string - { - return $this->carbon->toDateString(); - } - - /** - * Format the instance as a readable Date. - * - * @return string - */ - public function toFormattedDateString(): string - { - return $this->carbon->toFormattedDateString(); - } - - /** - * Format the instance as Time. - * - * @return string - */ - public function toTimeString(): string - { - return $this->carbon->toTimeString(); - } - - /** - * Format the instance as Date and Time. - * - * @return string - */ - public function toDateTimeString(): string - { - return $this->carbon->toDateTimeString(); - } - - /** - * Format the instance as ATOM - * - * @return string - */ - public function toAtomString(): string - { - return $this->carbon->toAtomString(); - } - - /** - * Format the instance as COOKIE. - * - * @return string - */ - public function toCookieString(): string - { - return $this->carbon->toCookieString(); - } - - /** - * Format the instance as ISO8601. - * - * @return string - */ - public function toIso8601String(): string - { - return $this->carbon->toIso8601String(); - } - - /** - * Format the instance as RFC822. - * - * @return string - */ - public function toRfc822String(): string - { - return $this->carbon->toRfc822String(); - } - - /** - * Format the instance as RFC850. - * - * @return string - */ - public function toRfc850String(): string - { - return $this->carbon->toRfc850String(); - } - - /** - * Format the instance as RFC1036. - * - * @return string - */ - public function toRfc1036String(): string - { - return $this->carbon->toRfc1036String(); - } - - /** - * Format the instance as RFC1123. - * - * @return string - */ - public function toRfc1123String(): string - { - return $this->carbon->toRfc1123String(); - } - - /** - * Format the instance as RFC2822. - * - * @return string - */ - public function toRfc2822String(): string - { - return $this->carbon->toRfc2822String(); - } - - /** - * Format the instance as RFC3339. - * - * @return string - */ - public function toRfc3339String(): string - { - return $this->carbon->toRfc3339String(); - } - - /** - * Format the instance as RSS. - * - * @return string - */ - public function toRssString(): string - { - return $this->carbon->toRssString(); - } - - /** - * Format the instance as W3C. - * - * @return string - */ - public function toW3cString(): string - { - return $this->carbon->toW3cString(); - } - - /** - * Format the instance to a valid DatetimeBox's value string. - * - * @return string - */ - public function toDatetimeBoxString(): string - { - return $this->carbon->format('Y-m-d\TH:i:s'); - } - - /** - * Retrieves the String representation of the Datatype. - * - * @return string - */ - public function __toString(): string - { - return $this->toDateTimeString(); - } -} diff --git a/src/Traits/Datatypes/Datetime/CanRetrievePartsTrait.php b/src/Traits/Datatypes/Datetime/CanRetrievePartsTrait.php deleted file mode 100644 index 3139a17..0000000 --- a/src/Traits/Datatypes/Datetime/CanRetrievePartsTrait.php +++ /dev/null @@ -1,140 +0,0 @@ -carbon->year; - } - - /** - * Returns the Month part of the Datetime instance. - * - * @return int - */ - public function partMonth(): int - { - return $this->carbon->month; - } - - /** - * Returns the Day part of the Datetime instance. - * - * @return int - */ - public function partDay(): int - { - return $this->carbon->day; - } - - /** - * Returns the Hour part of the Datetime instance. - * - * @return int - */ - public function partHour(): int - { - return $this->carbon->hour; - } - - /** - * Returns the Minute part of the Datetime instance. - * - * @return int - */ - public function partMinute(): int - { - return $this->carbon->minute; - } - - /** - * Returns the Second part of the Datetime instance. - * - * @return int - */ - public function partSecond(): int - { - return $this->carbon->second; - } - - /** - * Returns the Week number in the given Month. - * - * 1 through 5. - * - * @return int - */ - public function weekOfMonth(): int - { - return $this->carbon->weekOfMonth; - } - - /** - * Returns the Week number in the given Year. - * - * ISO-8601 week number of year, weeks starting on Monday. - * - * @return int - */ - public function weekOfYear(): int - { - return $this->carbon->weekOfYear; - } - - /** - * Returns the Day of the Week for the Datetime instance. - * - * 0 (for Sunday) through 6 (for Saturday) - * - * @return int - */ - public function dayOfWeek(): int - { - return $this->carbon->dayOfWeek; - } - - /** - * Returns the Day of the Year. - * - * 0 through 365. - * - * @return int - */ - public function dayOfYear(): int - { - return $this->carbon->dayOfYear; - } - - /** - * Returns the total number of Days for the Month set in the Datetime instance. - * - * @return int - */ - public function daysInMonth(): int - { - return $this->carbon->daysInMonth; - } -} diff --git a/src/Traits/Datatypes/Datetime/CanSetPartsTrait.php b/src/Traits/Datatypes/Datetime/CanSetPartsTrait.php deleted file mode 100644 index 89d207e..0000000 --- a/src/Traits/Datatypes/Datetime/CanSetPartsTrait.php +++ /dev/null @@ -1,164 +0,0 @@ -carbon->year($year); - - return $this; - } - - /** - * Sets the Month part of the instance. - * - * Supports chaining. - * - * @param int $month - Month to be set on the instance. - * - * @throws PositiveIntegerException - If a negative parameter was supplied. - * - * @return self - */ - public function setMonth(int $month): self - { - // Validates provided parameter. - if ($month <= 0) { - throw new PositiveIntegerException(); - } - - // Sets the month on the carbon's instance. - $this->carbon->month($month); - - return $this; - } - - /** - * Sets the Day part of the instance. - * - * Supports chaining. - * - * @param int $day - Day to be set on the instance. - * - * @throws PositiveIntegerException - If a negative parameter was supplied. - * - * @return self - */ - public function setDay(int $day): self - { - // Validates provided parameter. - if ($day <= 0) { - throw new PositiveIntegerException(); - } - - // Sets the day on the carbon's instance. - $this->carbon->day($day); - - return $this; - } - - /** - * Sets the Hour part of the instance. - * - * Supports chaining. - * - * @param int $hour - Hour to be set on the instance. - * - * @throws PositiveIntegerException - If a negative parameter was supplied. - * - * @return self - */ - public function setHour(int $hour): self - { - // Validates provided parameter. - if ($hour < 0) { - throw new PositiveIntegerException(); - } - - // Sets the hour on the carbon's instance. - $this->carbon->hour($hour); - - return $this; - } - - /** - * Sets the Minute part of the instance. - * - * Supports chaining. - * - * @param int $minute - Minute to be set on the instance. - * - * @throws PositiveIntegerException - If a negative parameter was supplied. - * - * @return self - */ - public function setMinute(int $minute): self - { - // Validates provided parameter. - if ($minute < 0) { - throw new PositiveIntegerException(); - } - - // Sets the minute on the carbon's instance. - $this->carbon->minute($minute); - - return $this; - } - - /** - * Sets the Second part of the instance. - * - * Supports chaining. - * - * @param int $second - Second to be set on the instance. - * - * @throws PositiveIntegerException - If a negative parameter was supplied. - * - * @return self - */ - public function setSecond(int $second): self - { - // Validates provided parameter. - if ($second < 0) { - throw new PositiveIntegerException(); - } - - // Sets the second on the carbon's instance. - $this->carbon->second($second); - - return $this; - } -} diff --git a/src/Traits/Datatypes/Datetime/HasStaticMethodsTrait.php b/src/Traits/Datatypes/Datetime/HasStaticMethodsTrait.php deleted file mode 100644 index d6f0cbd..0000000 --- a/src/Traits/Datatypes/Datetime/HasStaticMethodsTrait.php +++ /dev/null @@ -1,122 +0,0 @@ -username = $parts[0]; - - // Processes the right side of the e-mail address. - $host = \explode('.', $parts[1]); - $this->tld = \array_pop($host); - $this->domain = \implode('.', $host); - } - - /** - * Serializes the contents of the class. - * - * @return string - * - * {@inheritDoc} - * @see \Serializable::serialize() - */ - public function serialize() - { - return \serialize($this->__toString()); - } - - /** - * Unserializes back the contents of the class. - * - * @return void - * - * {@inheritDoc} - * @see \Serializable::unserialize() - */ - public function unserialize($serialized) - { - $this->loadEmail( - \unserialize($serialized) - ); - } - - /** - * Returns the String representation of the object. - * - * @return string - */ - public function __toString(): string - { - return ($this->username . '@' . $this->domain . '.' . $this->tld); - } -} diff --git a/src/Traits/Datatypes/EmailAddress/HasStaticFactoryMethodsTrait.php b/src/Traits/Datatypes/EmailAddress/HasStaticFactoryMethodsTrait.php deleted file mode 100644 index 96d0a12..0000000 --- a/src/Traits/Datatypes/EmailAddress/HasStaticFactoryMethodsTrait.php +++ /dev/null @@ -1,29 +0,0 @@ -value) - ); - } - - /** - * Right Trims the String's value. - * - * This method will return a new instance of Str. - * - * @return Str - */ - public function trimRight(): Str - { - return new Str( - \rtrim($this->value) - ); - } - - /** - * Left Trims the String's value. - * - * This method will return a new instance of Str. - * - * @return Str - */ - public function trimLeft(): Str - { - return new Str( - \ltrim($this->value) - ); - } - - /** - * Lower Cases String's value. - * - * This method will return a new instance of Str. - * - * @return Str - */ - public function lowercase(): Str - { - return new Str( - \strtolower($this->value) - ); - } - - /** - * Upper Cases String's value. - * - * This method will return a new instance of Str. - * - * @return Str - */ - public function uppercase(): Str - { - return new Str( - \strtoupper($this->value) - ); - } - - /** - * Lower Cases first character of the String's value. - * - * This method will return a new instance of Str. - * - * @return Str - */ - public function lowercaseFirst(): Str - { - return new Str( - \lcfirst($this->value) - ); - } - - /** - * Upper Cases first character of the String's value. - * - * This method will return a new instance of Str. - * - * @return Str - */ - public function uppercaseFirst(): Str - { - return new Str( - \ucfirst($this->value) - ); - } - - /** - * Upper Cases all words of the String's value. - * - * This method will return a new instance of Str. - * - * @return Str - */ - public function uppercaseWords(): Str - { - return new Str( - \ucwords($this->value) - ); - } - - /** - * Replaces a given portion of the String for another. - * - * This method will return a new instance of Str. - * - * @param string $search - String to search for. - * @param string $replace - String replacement. - * @return Str - */ - public function replace(string $search, string $replace): Str - { - return new Str( - \str_replace($search, $replace, $this->value) - ); - } -} diff --git a/src/Traits/Datatypes/String/HasReportingMethodsTrait.php b/src/Traits/Datatypes/String/HasReportingMethodsTrait.php deleted file mode 100644 index 7a351c1..0000000 --- a/src/Traits/Datatypes/String/HasReportingMethodsTrait.php +++ /dev/null @@ -1,49 +0,0 @@ -value); - } - - /** - * Searches the String for a given sub-string's position. - * - * @param string $search - String to search for. - * @return int - */ - public function position(string $search): int - { - return \strpos($this->value, $search); - } - - /** - * Counts the number of words in the String. - * - * @return int - */ - public function wordCount(): int - { - return \str_word_count($this->value); - } -} diff --git a/src/Traits/Datatypes/String/HasStaticMethodsTrait.php b/src/Traits/Datatypes/String/HasStaticMethodsTrait.php deleted file mode 100644 index 0044972..0000000 --- a/src/Traits/Datatypes/String/HasStaticMethodsTrait.php +++ /dev/null @@ -1,27 +0,0 @@ - Date: Wed, 2 Jun 2021 17:07:53 +0100 Subject: [PATCH 055/193] feat: Add wordCount() accessor method --- src/Scalar/AbstractBaseString.php | 10 ++++++++++ .../Scalar/AbstractBaseStringTestBase.php | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 0892574..63b6053 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -56,6 +56,16 @@ public function length(): int return \strlen($this->value); } + /** + * Counts the number of words in the String. + * + * @return int + */ + public function wordCount(): int + { + return \str_word_count($this->value); + } + /** * Compares the instance's value, with the supplied native string. * diff --git a/tests/Unit/Scalar/AbstractBaseStringTestBase.php b/tests/Unit/Scalar/AbstractBaseStringTestBase.php index b08b5be..a179507 100644 --- a/tests/Unit/Scalar/AbstractBaseStringTestBase.php +++ b/tests/Unit/Scalar/AbstractBaseStringTestBase.php @@ -85,6 +85,25 @@ public function testCanRetrieveLengthCorrectly(): void ); } + /** + * Checks that String's word count retrieval works. + * + * @return void + */ + public function testCanRetrieveWordCountCorrectly(): void + { + // Performs test. + $string = "This is my immutable string."; + $instance = $this->getInstance($string); + + // Performs assertions. + $this->assertEquals( + 5, + $instance->wordCount(), + 'Instance word count does not seam to match.' + ); + } + /** * Tests that a string can be trimmed. * From 5cb589cf811dbcd8d1bfcaecae4024b34ffb2330 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 17:17:47 +0100 Subject: [PATCH 056/193] docs: Add missing Copyright tag in docBlocks --- src/Aggregates/AbstractBaseAggregate.php | 1 + src/Collections/Associative/Store.php | 1 + src/Collections/Linear/AbstractListArray.php | 1 + src/Collections/Linear/EntityCollection.php | 3 ++- src/Collections/Linear/PaginatedCollection.php | 1 + src/Collections/Linear/Queue.php | 1 + src/Collections/Linear/Stack.php | 1 + src/Exceptions/AbstractBaseException.php | 1 + src/Exceptions/ConflictException.php | 1 + src/Exceptions/Datatypes/InvalidEmailException.php | 1 + src/Exceptions/Datatypes/InvalidStringLengthException.php | 1 + src/Exceptions/Datatypes/NonEmptyStringException.php | 1 + src/Exceptions/Datatypes/NonNegativeNumberException.php | 1 + src/Exceptions/Datatypes/ParameterOutOfRangeException.php | 1 + src/Exceptions/Datatypes/PositiveIntegerException.php | 1 + src/Exceptions/DeniedAccessException.php | 1 + .../Entities/RequiredEntityValueMissingException.php | 1 + src/Exceptions/Entities/UnexpectedEntityValueException.php | 1 + src/Exceptions/ExpectationFailedException.php | 1 + src/Exceptions/FailedDependencyException.php | 1 + src/Exceptions/ForbiddenException.php | 1 + src/Exceptions/GoneException.php | 1 + src/Exceptions/MethodNotAllowedException.php | 1 + src/Exceptions/NotAcceptableException.php | 1 + src/Exceptions/NotFoundException.php | 1 + src/Exceptions/PreconditionFailedException.php | 1 + src/Exceptions/PreconditionRequiredException.php | 1 + src/Exceptions/RequestedRangeNotSatisfiableException.php | 1 + src/Exceptions/TooManyRequestsException.php | 1 + src/Exceptions/UnprocessableEntityException.php | 1 + src/Exceptions/UnsupportedMediaTypeException.php | 1 + src/Web/EmailAddress.php | 1 + tests/AbstractBaseTestCase.php | 1 + tests/Unit/Scalar/NStringTest.php | 1 + tests/Unit/Scalar/VoStringTest.php | 1 + tests/Unit/Web/EmailAddressTest.php | 1 + tests/bootstrap.php | 1 + 37 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Aggregates/AbstractBaseAggregate.php b/src/Aggregates/AbstractBaseAggregate.php index 15fcfde..96cccb1 100644 --- a/src/Aggregates/AbstractBaseAggregate.php +++ b/src/Aggregates/AbstractBaseAggregate.php @@ -10,6 +10,7 @@ * This will add shared common functionality to all Aggregates, without code repetition. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ abstract class AbstractBaseAggregate implements \JsonSerializable diff --git a/src/Collections/Associative/Store.php b/src/Collections/Associative/Store.php index 838b5f4..5870c3d 100644 --- a/src/Collections/Associative/Store.php +++ b/src/Collections/Associative/Store.php @@ -21,6 +21,7 @@ * from the set. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT * @link https://en.wikipedia.org/wiki/Set_(abstract_data_type) */ diff --git a/src/Collections/Linear/AbstractListArray.php b/src/Collections/Linear/AbstractListArray.php index 49b53fd..51b129a 100644 --- a/src/Collections/Linear/AbstractListArray.php +++ b/src/Collections/Linear/AbstractListArray.php @@ -27,6 +27,7 @@ * of great importance. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT * @link http://php.net/manual/en/class.ds-collection.php * @link https://en.wikipedia.org/wiki/Collection_(abstract_data_type)#Lists diff --git a/src/Collections/Linear/EntityCollection.php b/src/Collections/Linear/EntityCollection.php index abab9e7..9c3151a 100644 --- a/src/Collections/Linear/EntityCollection.php +++ b/src/Collections/Linear/EntityCollection.php @@ -8,7 +8,8 @@ * This class will hold, process, encapsulate and group Entity objects together. * * @package Hradigital\Datatypes - * @license MIT + * @copyright Hradigital\Datatypes + * @license MIT1 * @link https://github.com/opsbears/foundation/tree/master/src/Complex */ class EntityCollection implements \Countable, \Iterator, \JsonSerializable diff --git a/src/Collections/Linear/PaginatedCollection.php b/src/Collections/Linear/PaginatedCollection.php index cb78484..c2d93a9 100644 --- a/src/Collections/Linear/PaginatedCollection.php +++ b/src/Collections/Linear/PaginatedCollection.php @@ -17,6 +17,7 @@ * If no pagination information is required, please use regular Collection object. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT * @see EntityCollection */ diff --git a/src/Collections/Linear/Queue.php b/src/Collections/Linear/Queue.php index ee39ead..c62244d 100644 --- a/src/Collections/Linear/Queue.php +++ b/src/Collections/Linear/Queue.php @@ -24,6 +24,7 @@ * example of a linear data structure, or more abstractly a sequential Collection. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT * @link http://php.net/manual/en/class.ds-queue.php * @link https://en.wikipedia.org/wiki/Queue_(abstract_data_type) diff --git a/src/Collections/Linear/Stack.php b/src/Collections/Linear/Stack.php index 705a48f..c391154 100644 --- a/src/Collections/Linear/Stack.php +++ b/src/Collections/Linear/Stack.php @@ -24,6 +24,7 @@ * an item deeper in the stack may require taking off multiple other items first. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT * @link http://php.net/manual/en/class.ds-stack.php * @link https://en.wikipedia.org/wiki/Stack_(abstract_data_type) diff --git a/src/Exceptions/AbstractBaseException.php b/src/Exceptions/AbstractBaseException.php index eb81cd6..228e4a1 100755 --- a/src/Exceptions/AbstractBaseException.php +++ b/src/Exceptions/AbstractBaseException.php @@ -15,6 +15,7 @@ * HTTP status codes. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT * @link https://httpstatuses.com/ */ diff --git a/src/Exceptions/ConflictException.php b/src/Exceptions/ConflictException.php index 52c1c9c..fab2cf6 100755 --- a/src/Exceptions/ConflictException.php +++ b/src/Exceptions/ConflictException.php @@ -13,6 +13,7 @@ * of examples. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class ConflictException extends AbstractBaseException diff --git a/src/Exceptions/Datatypes/InvalidEmailException.php b/src/Exceptions/Datatypes/InvalidEmailException.php index bf9af38..886bec9 100644 --- a/src/Exceptions/Datatypes/InvalidEmailException.php +++ b/src/Exceptions/Datatypes/InvalidEmailException.php @@ -8,6 +8,7 @@ * Invalid E-mail Datatype Exception. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class InvalidEmailException extends UnprocessableEntityException diff --git a/src/Exceptions/Datatypes/InvalidStringLengthException.php b/src/Exceptions/Datatypes/InvalidStringLengthException.php index 1930a14..194ecef 100644 --- a/src/Exceptions/Datatypes/InvalidStringLengthException.php +++ b/src/Exceptions/Datatypes/InvalidStringLengthException.php @@ -8,6 +8,7 @@ * Invalid String's Length Datatype Exception. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class InvalidStringLengthException extends UnprocessableEntityException diff --git a/src/Exceptions/Datatypes/NonEmptyStringException.php b/src/Exceptions/Datatypes/NonEmptyStringException.php index bb5e420..26e5cf6 100644 --- a/src/Exceptions/Datatypes/NonEmptyStringException.php +++ b/src/Exceptions/Datatypes/NonEmptyStringException.php @@ -8,6 +8,7 @@ * Non empty String Datatype Exception. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class NonEmptyStringException extends UnprocessableEntityException diff --git a/src/Exceptions/Datatypes/NonNegativeNumberException.php b/src/Exceptions/Datatypes/NonNegativeNumberException.php index 2959585..67a183a 100644 --- a/src/Exceptions/Datatypes/NonNegativeNumberException.php +++ b/src/Exceptions/Datatypes/NonNegativeNumberException.php @@ -10,6 +10,7 @@ * Only Zero or more should be allowed. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class NonNegativeNumberException extends UnprocessableEntityException diff --git a/src/Exceptions/Datatypes/ParameterOutOfRangeException.php b/src/Exceptions/Datatypes/ParameterOutOfRangeException.php index 7b9bc54..2c29c30 100644 --- a/src/Exceptions/Datatypes/ParameterOutOfRangeException.php +++ b/src/Exceptions/Datatypes/ParameterOutOfRangeException.php @@ -8,6 +8,7 @@ * Out of Range value Datatype Exception. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class ParameterOutOfRangeException extends UnprocessableEntityException diff --git a/src/Exceptions/Datatypes/PositiveIntegerException.php b/src/Exceptions/Datatypes/PositiveIntegerException.php index d8d7ec6..f8ac73c 100644 --- a/src/Exceptions/Datatypes/PositiveIntegerException.php +++ b/src/Exceptions/Datatypes/PositiveIntegerException.php @@ -8,6 +8,7 @@ * Must be a Positive Integer Datatype Exception. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class PositiveIntegerException extends UnprocessableEntityException diff --git a/src/Exceptions/DeniedAccessException.php b/src/Exceptions/DeniedAccessException.php index 11e2e01..13d3cd5 100644 --- a/src/Exceptions/DeniedAccessException.php +++ b/src/Exceptions/DeniedAccessException.php @@ -15,6 +15,7 @@ * credentials for the target resource. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class DeniedAccessException extends AbstractBaseException diff --git a/src/Exceptions/Entities/RequiredEntityValueMissingException.php b/src/Exceptions/Entities/RequiredEntityValueMissingException.php index 8acc4aa..fc046e6 100644 --- a/src/Exceptions/Entities/RequiredEntityValueMissingException.php +++ b/src/Exceptions/Entities/RequiredEntityValueMissingException.php @@ -14,6 +14,7 @@ * in error message. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class RequiredEntityValueMissingException extends UnprocessableEntityException diff --git a/src/Exceptions/Entities/UnexpectedEntityValueException.php b/src/Exceptions/Entities/UnexpectedEntityValueException.php index e65ec28..4bf422d 100644 --- a/src/Exceptions/Entities/UnexpectedEntityValueException.php +++ b/src/Exceptions/Entities/UnexpectedEntityValueException.php @@ -8,6 +8,7 @@ * Unexpected value Entity Exception. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class UnexpectedEntityValueException extends UnprocessableEntityException diff --git a/src/Exceptions/ExpectationFailedException.php b/src/Exceptions/ExpectationFailedException.php index 123db39..bdcfe9b 100644 --- a/src/Exceptions/ExpectationFailedException.php +++ b/src/Exceptions/ExpectationFailedException.php @@ -13,6 +13,7 @@ * total technical sense. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class ExpectationFailedException extends AbstractBaseException diff --git a/src/Exceptions/FailedDependencyException.php b/src/Exceptions/FailedDependencyException.php index 491d8f0..b201482 100755 --- a/src/Exceptions/FailedDependencyException.php +++ b/src/Exceptions/FailedDependencyException.php @@ -13,6 +13,7 @@ * the rest of the commands will also fail with 424 (Failed Dependency). * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class FailedDependencyException extends AbstractBaseException diff --git a/src/Exceptions/ForbiddenException.php b/src/Exceptions/ForbiddenException.php index 31e1bc0..f3e3cb0 100644 --- a/src/Exceptions/ForbiddenException.php +++ b/src/Exceptions/ForbiddenException.php @@ -15,6 +15,7 @@ * The request should not be repeated. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class ForbiddenException extends AbstractBaseException diff --git a/src/Exceptions/GoneException.php b/src/Exceptions/GoneException.php index 625014f..b996f4a 100755 --- a/src/Exceptions/GoneException.php +++ b/src/Exceptions/GoneException.php @@ -11,6 +11,7 @@ * Used when the requested resource is gone already. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class GoneException extends AbstractBaseException diff --git a/src/Exceptions/MethodNotAllowedException.php b/src/Exceptions/MethodNotAllowedException.php index 98cb41d..be5dc69 100755 --- a/src/Exceptions/MethodNotAllowedException.php +++ b/src/Exceptions/MethodNotAllowedException.php @@ -15,6 +15,7 @@ * containing a list of valid methods for the requested resource. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class MethodNotAllowedException extends AbstractBaseException diff --git a/src/Exceptions/NotAcceptableException.php b/src/Exceptions/NotAcceptableException.php index 565bac6..222f0f9 100644 --- a/src/Exceptions/NotAcceptableException.php +++ b/src/Exceptions/NotAcceptableException.php @@ -13,6 +13,7 @@ * total technical sense. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class NotAcceptableException extends AbstractBaseException diff --git a/src/Exceptions/NotFoundException.php b/src/Exceptions/NotFoundException.php index 94baad8..4eb6c15 100755 --- a/src/Exceptions/NotFoundException.php +++ b/src/Exceptions/NotFoundException.php @@ -11,6 +11,7 @@ * Used when the requested resource is not found/doesn't exist. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class NotFoundException extends AbstractBaseException diff --git a/src/Exceptions/PreconditionFailedException.php b/src/Exceptions/PreconditionFailedException.php index 53a5d89..b121b49 100755 --- a/src/Exceptions/PreconditionFailedException.php +++ b/src/Exceptions/PreconditionFailedException.php @@ -13,6 +13,7 @@ * method from being applied to a resource other than the one intended. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class PreconditionFailedException extends AbstractBaseException diff --git a/src/Exceptions/PreconditionRequiredException.php b/src/Exceptions/PreconditionRequiredException.php index ccf4941..44297b4 100644 --- a/src/Exceptions/PreconditionRequiredException.php +++ b/src/Exceptions/PreconditionRequiredException.php @@ -8,6 +8,7 @@ * Responses using this status code SHOULD explain how to resubmit the request successfully. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class PreconditionRequiredException extends AbstractBaseException diff --git a/src/Exceptions/RequestedRangeNotSatisfiableException.php b/src/Exceptions/RequestedRangeNotSatisfiableException.php index d63cf15..63b0af3 100644 --- a/src/Exceptions/RequestedRangeNotSatisfiableException.php +++ b/src/Exceptions/RequestedRangeNotSatisfiableException.php @@ -14,6 +14,7 @@ * total technical sense. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class RequestedRangeNotSatisfiableException extends AbstractBaseException diff --git a/src/Exceptions/TooManyRequestsException.php b/src/Exceptions/TooManyRequestsException.php index 7523e5f..cdd8c2b 100755 --- a/src/Exceptions/TooManyRequestsException.php +++ b/src/Exceptions/TooManyRequestsException.php @@ -13,6 +13,7 @@ * a new request. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class TooManyRequestsException extends AbstractBaseException diff --git a/src/Exceptions/UnprocessableEntityException.php b/src/Exceptions/UnprocessableEntityException.php index 7610d70..5a003bd 100644 --- a/src/Exceptions/UnprocessableEntityException.php +++ b/src/Exceptions/UnprocessableEntityException.php @@ -14,6 +14,7 @@ * (i.e., syntactically correct), but semantically erroneous, XML instructions. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class UnprocessableEntityException extends AbstractBaseException diff --git a/src/Exceptions/UnsupportedMediaTypeException.php b/src/Exceptions/UnsupportedMediaTypeException.php index 2dca1aa..973fae1 100755 --- a/src/Exceptions/UnsupportedMediaTypeException.php +++ b/src/Exceptions/UnsupportedMediaTypeException.php @@ -13,6 +13,7 @@ * that images use a different format. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class UnsupportedMediaTypeException extends AbstractBaseException diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index abdb5ce..895d666 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -13,6 +13,7 @@ * an E-mail address is a complex field, with a very specific set of rules. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class EmailAddress implements \Serializable diff --git a/tests/AbstractBaseTestCase.php b/tests/AbstractBaseTestCase.php index 3d96bda..c41019c 100644 --- a/tests/AbstractBaseTestCase.php +++ b/tests/AbstractBaseTestCase.php @@ -11,6 +11,7 @@ * All shared testing functionality and/or configuration should be added to this file. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ abstract class AbstractBaseTestCase extends TestCase diff --git a/tests/Unit/Scalar/NStringTest.php b/tests/Unit/Scalar/NStringTest.php index 4f0b86b..81c3f45 100644 --- a/tests/Unit/Scalar/NStringTest.php +++ b/tests/Unit/Scalar/NStringTest.php @@ -12,6 +12,7 @@ * String's Scalar Native/Primitive Object Unit testing. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class NStringTest extends AbstractBaseStringTestBase diff --git a/tests/Unit/Scalar/VoStringTest.php b/tests/Unit/Scalar/VoStringTest.php index e071964..9ee3847 100644 --- a/tests/Unit/Scalar/VoStringTest.php +++ b/tests/Unit/Scalar/VoStringTest.php @@ -12,6 +12,7 @@ * String's Scalar Value Object Unit testing. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class VoStringTest extends AbstractBaseStringTestBase diff --git a/tests/Unit/Web/EmailAddressTest.php b/tests/Unit/Web/EmailAddressTest.php index 29920fa..2e5e3ff 100644 --- a/tests/Unit/Web/EmailAddressTest.php +++ b/tests/Unit/Web/EmailAddressTest.php @@ -11,6 +11,7 @@ * Email Address Unit testing. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ class EmailAddressTest extends AbstractBaseTestCase diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8b2347b..fbef505 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -5,6 +5,7 @@ * For Unit testing only, please link PHPUnit to this file. This file will autoload Composer's dependencies. * * @package Hradigital\Datatypes + * @copyright Hradigital\Datatypes * @license MIT */ From a29071519f8a228c3e0417865d20146ac3274c14 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Jun 2021 17:38:48 +0100 Subject: [PATCH 057/193] docs: Update Quality badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f4e1dfd..80d8214 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Master branch build status [![Build](https://img.shields.io/circleci/build/github/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) [![Coverage](https://img.shields.io/codecov/c/github/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) -[![Quality](https://api.codacy.com/project/badge/Grade/3be6c231eea84329878a59a66af49e2f)](https://github.com/HRADigital/php-datatypes) +[![Quality](https://app.codacy.com/project/badge/Grade/de03155208c64196899848458c2ced8a)](https://github.com/HRADigital/php-datatypes) [![Downloads](https://img.shields.io/github/downloads/HRADigital/php-datatypes/total.svg)](https://github.com/HRADigital/php-datatypes) [![Licence](https://img.shields.io/github/license/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) [![Version](https://img.shields.io/github/release/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) From d8a6f8685f27953a219dfeacd3c608b825e89266 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 14 Jun 2021 22:44:33 +0100 Subject: [PATCH 058/193] style: Fix typo --- src/Traits/ValueObjects/HasRequiredFieldsTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/ValueObjects/HasRequiredFieldsTrait.php b/src/Traits/ValueObjects/HasRequiredFieldsTrait.php index 11b0107..5b221f9 100644 --- a/src/Traits/ValueObjects/HasRequiredFieldsTrait.php +++ b/src/Traits/ValueObjects/HasRequiredFieldsTrait.php @@ -15,7 +15,7 @@ */ trait HasRequiredFieldsTrait { - /** @var array $required - List of required native class attributes. */ + /** @var array $required - List of required native class attributes. */ protected array $required = []; /** From a1692193a6df8e23bf537ff37f41e4da6fd3c64f Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 15 Jun 2021 18:30:06 +0100 Subject: [PATCH 059/193] docs: Fix typo --- src/Exceptions/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Exceptions/README.md b/src/Exceptions/README.md index 71ebded..4ee0cbe 100755 --- a/src/Exceptions/README.md +++ b/src/Exceptions/README.md @@ -1,4 +1,4 @@ -# Domain Exception's namespace +# Exception's namespace Domain Exceptions are predefined Exceptions that can/should be raised from within the product. From 4277b473fa2e459636f63e2b2b91009b9256d669 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 7 Jul 2021 18:14:49 +0100 Subject: [PATCH 060/193] docs: Fix comment --- tests/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index fbef505..bc6dee6 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -9,5 +9,5 @@ * @license MIT */ -// Autoload Composer's dependencies, and Aesir-Base's namespace. +// Autoload Composer's dependencies. require __DIR__ . '/../vendor/autoload.php'; From aebc64861fc7d4e349c6435daf65cdcf32189669 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 24 Aug 2021 15:21:07 +0100 Subject: [PATCH 061/193] Improve main README file --- README.md | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 80d8214..17cc2f7 100755 --- a/README.md +++ b/README.md @@ -11,31 +11,44 @@ ## About -**PHP Datatypes** is a project is based and inspired on many other projects around, and is mainly meant to bring support -for **Scalar objects** and other common **Complex datatypes** into PHP, while native support isn't around. +**PHP Datatypes** is a project meant to conviniently aggregate commonly used **Scalar objects**, other **datatypes** and +**Data Transfer Object**'s base classes into a single package. Some of the projects that inspired this one, are mainly [Nikita Popov's Scalar Objects](https://github.com/nikic/scalar_objects), but also [Martin Helmich's Scalar Classes](https://github.com/martin-helmich/php-scalarclasses/) and [Michael Hall's Datatypes](https://github.com/themichaelhall/datatypes/). -### Scalar objects +## Requirements -**PHP Datatypes** will initially wrap common functionality to PHP's native datatypes, such as `string`, `integer`, `float` -and `boolean`. +- PHP >= 7.4 -### Complex datatypes +## Installation -There will also be wrapping classes around **Complex Datatypes** such as `Datetime`, `Email`, `Color`, `UrlAddress`, ..., -and both _Linear_ and _Associative_ **Collections** such as `Queues`, `Stacks` and `Sets`/`Stores`. +``` bash +$ composer require hradigital/php-datatypes +``` -### Data Transfer Objects (ValueObjects, Entities, etc...) +### Project's purpose/mission -Lastly, **PHP Datatypes** will also provide basic functionality for [DTOs](https://en.wikipedia.org/wiki/Data_transfer_object), -in case you'll want to quickly centralize/isolate record validation and sanitation, in a strongly typed/system agnostic object. +The project's mission is based on the following 4 principles: -## Installation +- Deliver the biggest amount of datatypes on a single project, that can serve as base code for many different projects. +- Be a self reliant project, without extra dependencies, that only depends on PHP's version and/or native code. +- Provide reliable code, which is fully tested/coverade. +- Provide fully documented code. + +### When not to use this project + +**PHP Datatypes** provides easily used, simple class interfaces, and each of the supplied datatypes is not meant to fully +provide all code combinations and/or functionality. It's code created for developer's convinience. + +If you need a more comprehensive handling of each datatype, there are other alternatives online. Here are a few: -In order to install this package, just add it to your **composer**, by executing `composer require hradigital/php-datatypes`. +- `nesbot/carbon` for Datetime's processing +- `symfony/string` for String's processing +- `moneyphp/money` for currency's processing +- `egulias/email-validator` for e-mail's processing +- ... ## Usage From 9599a2f49bd06643ef7dcf62f017d64b7bb4e27d Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 24 Aug 2021 15:21:07 +0100 Subject: [PATCH 062/193] docs: Improve main README file --- README.md | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 80d8214..17cc2f7 100755 --- a/README.md +++ b/README.md @@ -11,31 +11,44 @@ ## About -**PHP Datatypes** is a project is based and inspired on many other projects around, and is mainly meant to bring support -for **Scalar objects** and other common **Complex datatypes** into PHP, while native support isn't around. +**PHP Datatypes** is a project meant to conviniently aggregate commonly used **Scalar objects**, other **datatypes** and +**Data Transfer Object**'s base classes into a single package. Some of the projects that inspired this one, are mainly [Nikita Popov's Scalar Objects](https://github.com/nikic/scalar_objects), but also [Martin Helmich's Scalar Classes](https://github.com/martin-helmich/php-scalarclasses/) and [Michael Hall's Datatypes](https://github.com/themichaelhall/datatypes/). -### Scalar objects +## Requirements -**PHP Datatypes** will initially wrap common functionality to PHP's native datatypes, such as `string`, `integer`, `float` -and `boolean`. +- PHP >= 7.4 -### Complex datatypes +## Installation -There will also be wrapping classes around **Complex Datatypes** such as `Datetime`, `Email`, `Color`, `UrlAddress`, ..., -and both _Linear_ and _Associative_ **Collections** such as `Queues`, `Stacks` and `Sets`/`Stores`. +``` bash +$ composer require hradigital/php-datatypes +``` -### Data Transfer Objects (ValueObjects, Entities, etc...) +### Project's purpose/mission -Lastly, **PHP Datatypes** will also provide basic functionality for [DTOs](https://en.wikipedia.org/wiki/Data_transfer_object), -in case you'll want to quickly centralize/isolate record validation and sanitation, in a strongly typed/system agnostic object. +The project's mission is based on the following 4 principles: -## Installation +- Deliver the biggest amount of datatypes on a single project, that can serve as base code for many different projects. +- Be a self reliant project, without extra dependencies, that only depends on PHP's version and/or native code. +- Provide reliable code, which is fully tested/coverade. +- Provide fully documented code. + +### When not to use this project + +**PHP Datatypes** provides easily used, simple class interfaces, and each of the supplied datatypes is not meant to fully +provide all code combinations and/or functionality. It's code created for developer's convinience. + +If you need a more comprehensive handling of each datatype, there are other alternatives online. Here are a few: -In order to install this package, just add it to your **composer**, by executing `composer require hradigital/php-datatypes`. +- `nesbot/carbon` for Datetime's processing +- `symfony/string` for String's processing +- `moneyphp/money` for currency's processing +- `egulias/email-validator` for e-mail's processing +- ... ## Usage From 61bc67823f63a7f13faed06f054ff4a5b542b23c Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 11:49:36 +0000 Subject: [PATCH 063/193] Add support for PHP8 --- composer.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index c896d31..2a9f5ff 100755 --- a/composer.json +++ b/composer.json @@ -22,21 +22,22 @@ "mutable objects" ], "require": { - "php": "^7.4" + "php": "^7.4|^8.0" }, "require-dev": { "ext-xdebug": "*", "phpunit/phpunit": "^9.0", - "squizlabs/php_codesniffer": "^3.0@dev" + "squizlabs/php_codesniffer": "^3.0@dev", + "nesbot/carbon": "^2.0@dev" }, "autoload": { "psr-4": { - "Hradigital\\Datatypes\\": "src/" + "HraDigital\\Datatypes\\": "src/" } }, "autoload-dev": { "psr-4": { - "Hradigital\\Tests\\Datatypes\\": "tests/" + "HraDigital\\Tests\\Datatypes\\": "tests/" } }, "scripts": { From 23bf4f4df2a481c09d94c2daa8abc8be7d2dc2f3 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 11:50:36 +0000 Subject: [PATCH 064/193] Add Domain related Exceptions --- src/Exceptions/AbstractBaseException.php | 10 ++++++---- src/Exceptions/ConflictException.php | 10 ++++++---- src/Exceptions/Datatypes/InvalidEmailException.php | 12 +++++++----- .../Datatypes/InvalidStringLengthException.php | 12 +++++++----- src/Exceptions/Datatypes/NonEmptyStringException.php | 12 +++++++----- .../Datatypes/NonNegativeNumberException.php | 12 +++++++----- .../Datatypes/ParameterOutOfRangeException.php | 12 +++++++----- .../Datatypes/PositiveIntegerException.php | 12 +++++++----- src/Exceptions/DeniedAccessException.php | 10 ++++++---- .../Entities/RequiredEntityValueMissingException.php | 12 +++++++----- .../Entities/UnexpectedEntityValueException.php | 12 +++++++----- src/Exceptions/ExpectationFailedException.php | 10 ++++++---- src/Exceptions/FailedDependencyException.php | 10 ++++++---- src/Exceptions/ForbiddenException.php | 10 ++++++---- src/Exceptions/GoneException.php | 10 ++++++---- src/Exceptions/MethodNotAllowedException.php | 10 ++++++---- src/Exceptions/NotAcceptableException.php | 10 ++++++---- src/Exceptions/NotFoundException.php | 10 ++++++---- src/Exceptions/PreconditionFailedException.php | 10 ++++++---- src/Exceptions/PreconditionRequiredException.php | 10 ++++++---- .../RequestedRangeNotSatisfiableException.php | 10 ++++++---- src/Exceptions/TooManyRequestsException.php | 10 ++++++---- src/Exceptions/UnprocessableEntityException.php | 10 ++++++---- src/Exceptions/UnsupportedMediaTypeException.php | 10 ++++++---- 24 files changed, 152 insertions(+), 104 deletions(-) diff --git a/src/Exceptions/AbstractBaseException.php b/src/Exceptions/AbstractBaseException.php index 228e4a1..5859ab8 100755 --- a/src/Exceptions/AbstractBaseException.php +++ b/src/Exceptions/AbstractBaseException.php @@ -1,6 +1,8 @@ - Date: Tue, 9 Nov 2021 11:50:55 +0000 Subject: [PATCH 065/193] Refactor and uniform code --- src/Aggregates/AbstractBaseAggregate.php | 12 +- src/Aggregates/README.md | 4 +- src/Collections/Associative/Store.php | 10 +- src/Collections/Linear/AbstractListArray.php | 10 +- src/Collections/Linear/EntityCollection.php | 10 +- .../Linear/PaginatedCollection.php | 10 +- src/Collections/Linear/Queue.php | 10 +- src/Collections/Linear/Stack.php | 10 +- src/Datetime/DateInterval.php | 162 ++++++ src/Datetime/DateTimeInterface.php | 39 ++ src/Datetime/DateTimeZone.php | 19 + src/Datetime/Datetime.php | 472 ++++++++++++++++++ src/Datetime/DatetimeInheritance.php | 281 +++++++++++ src/Scalar/AbstractBaseString.php | 10 +- src/Scalar/NString.php | 10 +- src/Scalar/README.md | 6 +- src/Scalar/VoString.php | 12 +- .../Datetime/HasStaticFactoryMethodsTrait.php | 70 +++ .../Entities/CanProcessEntityStateTrait.php | 121 +++++ .../CanProcessOnUpdateEventsTrait.php | 45 ++ .../Entities/General/HasActiveTrait.php | 12 +- src/Traits/Entities/General/HasAliasTrait.php | 20 +- .../Entities/General/HasCreatedAtTrait.php | 17 +- .../Entities/General/HasDeletedAtTrait.php | 16 +- src/Traits/Entities/General/HasEmailTrait.php | 16 +- .../Entities/General/HasFeatureTrait.php | 16 +- src/Traits/Entities/General/HasHitsTrait.php | 14 +- src/Traits/Entities/General/HasNameTrait.php | 16 +- .../Entities/General/HasOrderingTrait.php | 14 +- .../Entities/General/HasPasswordTrait.php | 39 ++ .../General/HasPositiveIntegerIDTrait.php | 57 +++ .../General/HasPublishedTimestampsTrait.php | 10 +- .../Entities/General/HasPublishedTrait.php | 18 +- .../Entities/General/HasSeoFieldsTrait.php | 29 +- .../Entities/General/HasTimestampsTrait.php | 10 +- .../General/HasUpdatableUpdatedAtTrait.php | 32 ++ .../Entities/General/HasUpdatedAtTrait.php | 17 +- src/Traits/Entities/General/HasUuidTrait.php | 12 +- .../Entities/Location/HasAddressTrait.php | 12 +- src/Traits/Entities/Location/HasCityTrait.php | 12 +- .../Entities/Location/HasCountryCodeTrait.php | 41 ++ .../Entities/Location/HasCountryTrait.php | 12 +- .../Entities/Location/HasLatitudeTrait.php | 39 ++ .../Entities/Location/HasLongitudeTrait.php | 39 ++ .../Entities/Location/HasPostalCodeTrait.php | 12 +- .../Location/HasStreetAdditionalTrait.php | 12 +- .../Location/HasStreetNumberTrait.php | 12 +- .../Entities/Location/HasStreetTrait.php | 12 +- .../Personal/HasCountryOfBirthTrait.php | 14 +- .../Entities/Personal/HasDateOfBirthTrait.php | 14 +- .../Entities/Personal/HasGenderTrait.php | 14 +- .../Entities/Personal/HasPhotoTrait.php | 58 +++ .../Entities/Personal/HasSurnameTrait.php | 16 +- .../Professional/HasOccupationTrait.php | 58 +++ src/Traits/Entities/Professional/README.md | 1 + .../SocialMedia/HasFacebookProfileTrait.php | 49 ++ .../SocialMedia/HasInstagramProfileTrait.php | 49 ++ .../SocialMedia/HasLinkedinProfileTrait.php | 49 ++ .../SocialMedia/HasTwitterProfileTrait.php | 49 ++ src/Traits/Entities/SocialMedia/README.md | 1 + .../Entities/Timezone/HasTimestampTrait.php | 39 ++ src/Traits/Entities/Timezone/README.md | 1 + .../CanProcessOnLoadEventsTrait.php | 45 ++ .../HasConversionToPrimitiveValuesTrait.php | 16 +- .../ValueObjects/HasFieldCastingTrait.php | 10 +- .../ValueObjects/HasGuardedFieldsTrait.php | 10 +- .../ValueObjects/HasMappedFieldsTrait.php | 10 +- .../ValueObjects/HasRequiredFieldsTrait.php | 12 +- .../ValueObjects/HasRuleProcessingTrait.php | 10 +- src/ValueObjects/AbstractValueObject.php | 32 +- src/ValueObjects/README.md | 22 +- src/ValueObjects/Timezone/Identifier.php | 15 + src/ValueObjects/Timezone/Location.php | 43 ++ src/ValueObjects/Timezone/README.md | 1 + src/ValueObjects/Timezone/Transition.php | 86 ++++ src/Web/EmailAddress.php | 12 +- 76 files changed, 2356 insertions(+), 271 deletions(-) create mode 100644 src/Datetime/DateInterval.php create mode 100644 src/Datetime/DateTimeInterface.php create mode 100644 src/Datetime/DateTimeZone.php create mode 100644 src/Datetime/Datetime.php create mode 100644 src/Datetime/DatetimeInheritance.php create mode 100644 src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php create mode 100644 src/Traits/Entities/CanProcessEntityStateTrait.php create mode 100644 src/Traits/Entities/CanProcessOnUpdateEventsTrait.php create mode 100755 src/Traits/Entities/General/HasPasswordTrait.php create mode 100644 src/Traits/Entities/General/HasPositiveIntegerIDTrait.php create mode 100644 src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php create mode 100644 src/Traits/Entities/Location/HasCountryCodeTrait.php create mode 100644 src/Traits/Entities/Location/HasLatitudeTrait.php create mode 100644 src/Traits/Entities/Location/HasLongitudeTrait.php create mode 100755 src/Traits/Entities/Personal/HasPhotoTrait.php create mode 100755 src/Traits/Entities/Professional/HasOccupationTrait.php create mode 100644 src/Traits/Entities/Professional/README.md create mode 100755 src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php create mode 100755 src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php create mode 100755 src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php create mode 100755 src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php create mode 100644 src/Traits/Entities/SocialMedia/README.md create mode 100755 src/Traits/Entities/Timezone/HasTimestampTrait.php create mode 100644 src/Traits/Entities/Timezone/README.md create mode 100644 src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php create mode 100644 src/ValueObjects/Timezone/Identifier.php create mode 100644 src/ValueObjects/Timezone/Location.php create mode 100755 src/ValueObjects/Timezone/README.md create mode 100644 src/ValueObjects/Timezone/Transition.php diff --git a/src/Aggregates/AbstractBaseAggregate.php b/src/Aggregates/AbstractBaseAggregate.php index 96cccb1..e6e338d 100644 --- a/src/Aggregates/AbstractBaseAggregate.php +++ b/src/Aggregates/AbstractBaseAggregate.php @@ -1,6 +1,8 @@ -jsonSerialize(); - } elseif (\method_exists($value, '__toString')) { + } elseif (\is_object($value) && \method_exists($value, '__toString')) { $json[$name] = (string) $value; } else { $json[$name] = $value; diff --git a/src/Aggregates/README.md b/src/Aggregates/README.md index 83e7c01..6080b15 100755 --- a/src/Aggregates/README.md +++ b/src/Aggregates/README.md @@ -1,6 +1,6 @@ -# Domain Aggregates +# Aggregates -_Domain Aggregates_ are not meant to be the same as _DDD's Aggregates_. +_Aggregates_ are not meant to be the same as _DDD's Root Aggregates_. `Aggregates` are meant to **aggregate returned types** together, in order to **minimize** communication with the **Domain**. diff --git a/src/Collections/Associative/Store.php b/src/Collections/Associative/Store.php index 5870c3d..5bd2aa1 100644 --- a/src/Collections/Associative/Store.php +++ b/src/Collections/Associative/Store.php @@ -1,6 +1,8 @@ -interval = new \DateInterval($duration); + $this->interval->invert = (int) $inverted; + } + + public function __toString(): string + { + return (string) $this->toDatetimeString(); + } + + protected function invertValue(int $value, int $invert): int + { + return $invert ? (0 - $value) : $value; + } + + public function inYears(): int + { + return $this->invertValue($this->interval->y, $this->interval->invert); + } + + public function inMonths(): int + { + return $this->invertValue($this->interval->m, $this->interval->invert); + } + + public function inDays(): int + { + return $this->invertValue($this->interval->d, $this->interval->invert); + } + + public function inHours(): int + { + return $this->invertValue($this->interval->h, $this->interval->invert); + } + + public function inMinutes(): int + { + return $this->invertValue($this->interval->i, $this->interval->invert); + } + + public function inSeconds(): int + { + return $this->invertValue($this->interval->s, $this->interval->invert); + } + + public function inMicroSeconds(): float + { + return $this->interval->invert ? (0 - $this->interval->f) : $this->interval->f; + } + + protected function toFormatInternal(string $format): VoString + { + return VoString::create( + $this->interval->format($format) + ); + } + + /** + * Returns VoString instance with value in format "Y-m-d H:i:s". + * + * @return VoString + */ + public function toDatetimeString(): VoString + { + return $this->toFormatInternal('Y-m-d H:i:s'); + } + + public function toFormat(VoString $format): VoString + { + return $this->toFormatInternal((string) $format); + } + + public function toDuration(): VoString + { + return VoString::create( + \sprintf( + 'P%dY%dM%dDT%dH%dM%dS', + $this->interval->y, + $this->interval->m, + $this->interval->d, + $this->interval->h, + $this->interval->i, + $this->interval->s + ) + ); + } +} diff --git a/src/Datetime/DateTimeInterface.php b/src/Datetime/DateTimeInterface.php new file mode 100644 index 0000000..82740ae --- /dev/null +++ b/src/Datetime/DateTimeInterface.php @@ -0,0 +1,39 @@ +dateTime = new \DateTimeImmutable($datetime, $timezone); + } + + /** + * Magic method for instance printing. + * + * @return string + */ + public function __toString(): string + { + return (string) $this->toDatetimeString(); + } + + /** @inheritDoc */ + public function jsonSerialize(): string + { + return (string) $this; + } + + /** + * Returns the Timestamp of the Datetime instance. + * + * Number of seconds since the Unix Epoch. + * + * @return int + */ + public function timestamp(): int + { + return $this->dateTime->getTimestamp(); + } + + /** + * Returns the timezone's offset. + * + * @return int + */ + public function offset(): int + { + return $this->dateTime->getOffset(); + } + + /** + * Get Year part of the instance. + * + * @return int + */ + public function year(): int + { + return (int) ((string) $this->toFormat(VoString::create('Y'))); + } + + /** + * Get Month part of the instance. + * + * @return int + */ + public function month(): int + { + return (int) ((string) $this->toFormat(VoString::create('m'))); + } + + /** + * Get Day part of the instance. + * + * @return int + */ + public function day(): int + { + return (int) ((string) $this->toFormat(VoString::create('d'))); + } + + /** + * Get Hour part of the instance. + * + * @return int + */ + public function hour(): int + { + return (int) ((string) $this->toFormat(VoString::create('H'))); + } + + /** + * Get Minute part of the instance. + * + * @return int + */ + public function minute(): int + { + return (int) ((string) $this->toFormat(VoString::create('i'))); + } + + /** + * Get Second part of the instance. + * + * @return int + */ + public function second(): int + { + return (int) ((string) $this->toFormat(VoString::create('s'))); + } + + /** + * Internal method for DateInterval addition and subtraction. + * + * @param string $duration - Duration string + * @param int $value + * @return Datetime + */ + protected function addDateIntervalValue(string $duration, int $value): Datetime + { + $isNegative = ($value < 0); + $value = (int) \abs($value); + + $dateInterval = new \DateInterval( + \sprintf($duration, $value) + ); + + if ($isNegative) { + $dateInterval->invert = 1; + } + + return new Datetime( + $this->dateTime + ->add($dateInterval) + ->format(self::START_FORMAT) + ); + } + + /** + * Add the supplied number of Seconds to the Datetime instance. + * + * Supports chaining. + * + * @param int $seconds - Number of Seconds to add to instance. Supports negative numbers for subtraction. + * @return Datetime + */ + public function addSeconds(int $seconds): Datetime + { + return $this->addDateIntervalValue("PT%dS", $seconds); + } + + /** + * Add the supplied number of Minutes to the Datetime instance. + * + * Supports chaining. + * + * @param int $minutes - Number of Minutes to add to instance. Supports negative numbers for subtraction. + * @return Datetime + */ + public function addMinutes(int $minutes): Datetime + { + return $this->addDateIntervalValue("PT%dM", $minutes); + } + + /** + * Add the supplied number of Hours to the Datetime instance. + * + * Supports chaining. + * + * @param int $hours - Number of Hours to add to instance. Supports negative numbers for subtraction. + * @return Datetime + */ + public function addHours(int $hours): Datetime + { + return $this->addDateIntervalValue("PT%dH", $hours); + } + + /** + * Add the supplied number of Days to the Datetime instance. + * + * Supports chaining. + * + * @param int $days - Number of Days to add to instance. Supports negative numbers for subtraction. + * @return Datetime + */ + public function addDays(int $days): Datetime + { + return $this->addDateIntervalValue("P%dD", $days); + } + + /** + * Add the supplied number of Months to the Datetime instance. + * + * Supports chaining. + * + * @param int $months - Number of Months to add to instance. Supports negative numbers for subtraction. + * @return Datetime + */ + public function addMonths(int $months): Datetime + { + return $this->addDateIntervalValue("P%dM", $months); + } + + /** + * Add the supplied number of Years to the Datetime instance. + * + * Supports chaining. + * + * @param int $years - Number of Years to add to instance. Supports negative numbers for subtraction. + * @return Datetime + */ + public function addYears(int $years): Datetime + { + return $this->addDateIntervalValue("P%dY", $years); + } + + public function difference(Datetime $datetime, bool $absolute = false): DateInterval + { + $dateInterval = $this->dateTime->diff( + new \DateTime((string) $datetime), + $absolute + ); + + return DateInterval::fromDuration( + VoString::create( + \sprintf( + 'P%dY%dM%dDT%dH%dM%dS', + $dateInterval->y, + $dateInterval->m, + $dateInterval->d, + $dateInterval->h, + $dateInterval->i, + $dateInterval->s + ) + ), + $dateInterval->invert === 1 + ); + } + + public function startOfDay(): Datetime + { + return new Datetime( + $this->dateTime->format('Y-m-d 00:00:00') + ); + } + + public function endOfDay(): Datetime + { + return new Datetime( + $this->dateTime->format('Y-m-d 23:59:59') + ); + } + + protected function toFormatInternal(string $format): VoString + { + return VoString::create( + $this->dateTime->format($format) + ); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * + * @return VoString + */ + public function toATOM(): VoString + { + return $this->toFormatInternal(\Datetime::ATOM); + } + + /** + * Returns VoString instance with value in format "l, d-M-Y H:i:s T". + * + * @return VoString + */ + public function toCookie(): VoString + { + return $this->toFormatInternal(\Datetime::COOKIE); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:sO". + * + * @return VoString + */ + public function toISO8601(): VoString + { + return $this->toFormatInternal(\Datetime::ISO8601); + } + + /** + * Returns VoString instance with value in format "D, d M y H:i:s O". + * + * @return VoString + */ + public function toRFC822(): VoString + { + return $this->toFormatInternal(\Datetime::RFC822); + } + + /** + * Returns VoString instance with value in format "l, d-M-y H:i:s T". + * + * @return VoString + */ + public function toRFC850(): VoString + { + return $this->toFormatInternal(\Datetime::RFC850); + } + + /** + * Returns VoString instance with value in format "D, d M y H:i:s O". + * + * @return VoString + */ + public function toRFC1036(): VoString + { + return $this->toFormatInternal(\Datetime::RFC1036); + } + + /** + * Returns VoString instance with value in format "D, d M Y H:i:s O". + * + * @return VoString + */ + public function toRFC1123(): VoString + { + return $this->toFormatInternal(\Datetime::RFC1123); + } + + /** + * Returns VoString instance with value in format "D, d M Y H:i:s \G\M\T". + * + * @return VoString + */ + public function toRFC7231(): VoString + { + return $this->toFormatInternal(\Datetime::RFC7231); + } + + /** + * Returns VoString instance with value in format "D, d M Y H:i:s O". + * + * @return VoString + */ + public function toRFC2822(): VoString + { + return $this->toFormatInternal(\Datetime::RFC2822); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * + * @return VoString + */ + public function toRFC3339(): VoString + { + return $this->toFormatInternal(\Datetime::RFC3339); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:s.vP". + * + * @return VoString + */ + public function toRFC3339Extended(): VoString + { + return $this->toFormatInternal(\Datetime::RFC3339_EXTENDED); + } + + /** + * Returns VoString instance with value in format "D, d M Y H:i:s O". + * + * @return VoString + */ + public function toRSS(): VoString + { + return $this->toFormatInternal(\Datetime::RSS); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * + * @return VoString + */ + public function toW3C(): VoString + { + return $this->toFormatInternal(\Datetime::W3C); + } + + /** + * Returns VoString instance with value in format "Y-m-d H:i:s". + * + * @return VoString + */ + public function toDatetimeString(): VoString + { + return $this->toFormatInternal('Y-m-d H:i:s'); + } + + /** + * Returns VoString instance with value in format "H:i:s". + * + * @return VoString + */ + public function toTimeString(): VoString + { + return $this->toFormatInternal('H:i:s'); + } + + /** + * Returns VoString instance with value in specified format. + * + * @param VoString $format - VoString instance containing desired Datetime format. + * @return VoString + */ + public function toFormat(VoString $format): VoString + { + return $this->toFormatInternal((string) $format); + } + + /** + * Returns the Timezone set on the Datetime's instance. + * + * @return \DateTimeZone + */ + public function getTimezone(): \DateTimeZone + { + return new \DateTimeZone("Europe/London"); + } + + /** + * Returns the Timezone set on the Datetime's instance, in string format. + * + * @return string + */ + public function getTimezoneName(): string + { + return $this->carbon->timezoneName; + } +} diff --git a/src/Datetime/DatetimeInheritance.php b/src/Datetime/DatetimeInheritance.php new file mode 100644 index 0000000..af130d5 --- /dev/null +++ b/src/Datetime/DatetimeInheritance.php @@ -0,0 +1,281 @@ +toDatetimeString(); + } + + /** @inheritDoc */ + public function jsonSerialize(): string + { + return (string) $this; + } + + protected function toFormatInternal(string $format): VoString + { + return VoString::create( + $this->format($format) + ); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * + * @return VoString + */ + public function toATOM(): VoString + { + return $this->toFormatInternal(\Datetime::ATOM); + } + + /** + * Returns VoString instance with value in format "l, d-M-Y H:i:s T". + * + * @return VoString + */ + public function toCookie(): VoString + { + return $this->toFormatInternal(\Datetime::COOKIE); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:sO". + * + * @return VoString + */ + public function toISO8601(): VoString + { + return $this->toFormatInternal(\Datetime::ISO8601); + } + + /** + * Returns VoString instance with value in format "D, d M y H:i:s O". + * + * @return VoString + */ + public function toRFC822(): VoString + { + return $this->toFormatInternal(\Datetime::RFC822); + } + + /** + * Returns VoString instance with value in format "l, d-M-y H:i:s T". + * + * @return VoString + */ + public function toRFC850(): VoString + { + return $this->toFormatInternal(\Datetime::RFC850); + } + + /** + * Returns VoString instance with value in format "D, d M y H:i:s O". + * + * @return VoString + */ + public function toRFC1036(): VoString + { + return $this->toFormatInternal(\Datetime::RFC1036); + } + + /** + * Returns VoString instance with value in format "D, d M Y H:i:s O". + * + * @return VoString + */ + public function toRFC1123(): VoString + { + return $this->toFormatInternal(\Datetime::RFC1123); + } + + /** + * Returns VoString instance with value in format "D, d M Y H:i:s \G\M\T". + * + * @return VoString + */ + public function toRFC7231(): VoString + { + return $this->toFormatInternal(\Datetime::RFC7231); + } + + /** + * Returns VoString instance with value in format "D, d M Y H:i:s O". + * + * @return VoString + */ + public function toRFC2822(): VoString + { + return $this->toFormatInternal(\Datetime::RFC2822); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * + * @return VoString + */ + public function toRFC3339(): VoString + { + return $this->toFormatInternal(\Datetime::RFC3339); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:s.vP". + * + * @return VoString + */ + public function toRFC3339Extended(): VoString + { + return $this->toFormatInternal(\Datetime::RFC3339_EXTENDED); + } + + /** + * Returns VoString instance with value in format "D, d M Y H:i:s O". + * + * @return VoString + */ + public function toRSS(): VoString + { + return $this->toFormatInternal(\Datetime::RSS); + } + + /** + * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * + * @return VoString + */ + public function toW3C(): VoString + { + return $this->toFormatInternal(\Datetime::W3C); + } + + /** + * Returns VoString instance with value in format "Y-m-d H:i:s". + * + * @return VoString + */ + public function toDatetimeString(): VoString + { + return $this->toFormatInternal('Y-m-d H:i:s'); + } + + /** + * Returns VoString instance with value in format "H:i:s". + * + * @return VoString + */ + public function toTimeString(): VoString + { + return $this->toFormatInternal('H:i:s'); + } + + /** + * Returns VoString instance with value in specified format. + * + * @param VoString $format - VoString instance containing desired Datetime format. + * @return VoString + */ + public function toFormat(VoString $format): VoString + { + return $this->toFormatInternal((string) $format); + } + + /** + * Get Year part of the instance. + * + * @return int + */ + public function getYear(): int + { + return (int) ((string) $this->toFormatInternal('Y')); + } + + /** + * Get Month part of the instance. + * + * @return int + */ + public function getMonth(): int + { + return (int) ((string) $this->toFormatInternal('m')); + } + + /** + * Get Day part of the instance. + * + * @return int + */ + public function getDay(): int + { + return (int) ((string) $this->toFormatInternal('d')); + } + + /** + * Get Hour part of the instance. + * + * @return int + */ + public function getHour(): int + { + return (int) ((string) $this->toFormatInternal('H')); + } + + /** + * Get Minute part of the instance. + * + * @return int + */ + public function getMinute(): int + { + return (int) ((string) $this->toFormatInternal('i')); + } + + /** + * Get Second part of the instance. + * + * @return int + */ + public function getSecond(): int + { + return (int) ((string) $this->toFormatInternal('s')); + } +} diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 63b6053..7a76e16 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -1,9 +1,9 @@ replace(' is ', ' was ') ->toVoString(); -echo get_class($string); // Should echo \Hradigital\Datatypes\Scalar\VoString +echo get_class($string); // Should echo \HraDigital\Datatypes\Scalar\VoString echo $string; // This was originally a NString. // Converts to original type. $string = $string->replace(VoString::create(' was '), VoString::create(' is '))->toNString(); -echo get_class($string); // Should echo \Hradigital\Datatypes\Scalar\NString +echo get_class($string); // Should echo \HraDigital\Datatypes\Scalar\NString echo $string; // This is originally a NString. ``` diff --git a/src/Scalar/VoString.php b/src/Scalar/VoString.php index 85ae203..3cdbf73 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/VoString.php @@ -1,9 +1,9 @@ value === $string); } /** diff --git a/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php b/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php new file mode 100644 index 0000000..f5249d7 --- /dev/null +++ b/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php @@ -0,0 +1,70 @@ +setTimestamp($timestamp); + + return new Datetime( + $dt->format(\Datetime::W3C) + ); + } + + public static function fromUnits( + int $years, + int $months, + int $days, + int $hours = 0, + int $minutes = 0, + int $seconds = 0, + ?DateTimeZone $timezone = null + ): Datetime { + return new Datetime( + \sprintf( + "%d-%d-%dT%d:%d:%d%s", + $years, + $months, + $days, + $hours, + $minutes, + $seconds, + ((string) $timezone ?? '+00:00') + ) + ); + } +} diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php new file mode 100644 index 0000000..d387688 --- /dev/null +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -0,0 +1,121 @@ +initialState = $this->getAttributes(); + } + + /** + * Validates if there are any Dirty class attributes. + * + * Returns TRUE if at least one attribute has changed, since the class + * was initially loaded. + * + * @return bool + */ + final public function isDirty(): bool + { + return (\count($this->getDirty()) > 0); + } + + /** + * Returns a list of attributes that have changed value. + * + * If the Entity is not marked as dirty, this will return an empty array. + * + * @return array + */ + final public function getDirty(): array + { + // Loops through all the class' attributes, and validates if any has changed. + $dirty = []; + foreach ($this->getAttributes() as $field => $value) { + + // Is the current value different from the initial one? + // Is the Entity NEW, and the field a required one? + // If so, add it to the $dirty return array. + if ( + $value !== $this->initialState[$field] || + ($this->isNew() && \array_search($field, $this->required) !== false) + ) { + $dirty[$field] = $value; + } + } + + // Returns all dirty attributes. + return $dirty; + } + + /** + * Returns a list of attributes, with their original values. + * + * When the Entity's attributes change, it becomes Dirty. This method will return the + * list of attributes, with their original values prior to that change. + * + * @return array + */ + final public function getOriginal(): array + { + return $this->initialState; + } + + /** + * Sets new values to a set of class attributes, all at once. + * + * @param array $fields - Associative array, where the keys are the class attribute's names. + * + * @throws \UnderflowException - If supplied array is empty. + * @throws \UnexpectedValueException - If supplied array is not a string-key only associative array. + * @throws \InvalidArgumentException - If supplied attribute's names are not non empty strings. + * @throws \BadMethodCallException - If any setter method doesn't exist for a chosen attribute. + * + * @return void + */ + final public function setAttributes(array $fields): void + { + // Validates the supplied array is a non empty associative one. + $count = \count($fields); + if ($count === 0) { + throw new \UnderflowException('Supplied parameter should be a non empty Array.'); + } + + // Validates that all the indexes are of String type. + if (\count(\array_filter(\array_keys($fields), 'is_string')) !== $count) { + throw new \UnexpectedValueException('Supplied parameter should have been an Associative Array.'); + } + + // Process supplied fields. + $mapped = $this->translateToMappedFields($fields); + $this->processRules($mapped); + $this->loadAttributes($mapped); + + if (\method_exists($this, 'triggerOnUpdate')) { + $this->{'triggerOnUpdate'}(); + } + } +} diff --git a/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php b/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php new file mode 100644 index 0000000..637ceb4 --- /dev/null +++ b/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php @@ -0,0 +1,45 @@ +onUpdate(function() { $this->someCall() }); + * + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes + * @license Proprietary + */ +trait CanProcessOnUpdateEventsTrait +{ + /** @var array $onUpdateEvents - List of onUpdate event handlers, defined as closures. */ + private array $onUpdateEvents = []; + + /** + * Triggers all onUpdate pre-declared events. + * + * @return void + */ + protected function triggerOnUpdate(): void + { + foreach ($this->onUpdateEvents as $onUpdate) { + $onUpdate(); + } + } + + /** + * Adds a new onUpdate event handler to the class. + * + * @param Closure $handler - Closure that will be triggered onUpdate. + * @return void + */ + protected function onUpdate(Closure $handler): void + { + $this->onUpdateEvents[] = $handler; + } +} diff --git a/src/Traits/Entities/General/HasActiveTrait.php b/src/Traits/Entities/General/HasActiveTrait.php index cdae680..376ada7 100755 --- a/src/Traits/Entities/General/HasActiveTrait.php +++ b/src/Traits/Entities/General/HasActiveTrait.php @@ -1,12 +1,14 @@ -active; } diff --git a/src/Traits/Entities/General/HasAliasTrait.php b/src/Traits/Entities/General/HasAliasTrait.php index abcfea6..d637b78 100755 --- a/src/Traits/Entities/General/HasAliasTrait.php +++ b/src/Traits/Entities/General/HasAliasTrait.php @@ -1,19 +1,21 @@ -alias; } diff --git a/src/Traits/Entities/General/HasCreatedAtTrait.php b/src/Traits/Entities/General/HasCreatedAtTrait.php index 803b6cb..efab99f 100644 --- a/src/Traits/Entities/General/HasCreatedAtTrait.php +++ b/src/Traits/Entities/General/HasCreatedAtTrait.php @@ -1,14 +1,17 @@ -created_at = Datetime::fromString($timestamp); + $this->created_at = Datetime::fromString(VoString::create($timestamp)); } /** @@ -32,7 +35,7 @@ protected function castCreatedAt(string $timestamp): void * * @return Datetime */ - public function createdAt(): Datetime + public function getCreatedAt(): Datetime { return $this->created_at; } diff --git a/src/Traits/Entities/General/HasDeletedAtTrait.php b/src/Traits/Entities/General/HasDeletedAtTrait.php index fefa540..12819f4 100644 --- a/src/Traits/Entities/General/HasDeletedAtTrait.php +++ b/src/Traits/Entities/General/HasDeletedAtTrait.php @@ -1,16 +1,18 @@ -deleted_at = ($timestamp ? Datetime::fromString($timestamp) : null); + $this->deleted_at = ($timestamp ? Datetime::fromString(VoString::create($timestamp)) : null); } /** @@ -34,7 +36,7 @@ protected function castDeletedAt(?string $timestamp): void * * @return Datetime|null */ - public function deletedAt(): ?Datetime + public function getDeletedAt(): ?Datetime { return $this->deleted_at; } diff --git a/src/Traits/Entities/General/HasEmailTrait.php b/src/Traits/Entities/General/HasEmailTrait.php index d232899..3a9733a 100644 --- a/src/Traits/Entities/General/HasEmailTrait.php +++ b/src/Traits/Entities/General/HasEmailTrait.php @@ -1,14 +1,16 @@ -email = EmailAddress::fromString($email); + $this->email = EmailAddress::create($email); } /** @@ -32,7 +34,7 @@ protected function castEmail(string $email): void * * @return EmailAddress|null */ - public function email(): ?EmailAddress + public function getEmail(): ?EmailAddress { return $this->email; } diff --git a/src/Traits/Entities/General/HasFeatureTrait.php b/src/Traits/Entities/General/HasFeatureTrait.php index e19e62e..c70b26e 100755 --- a/src/Traits/Entities/General/HasFeatureTrait.php +++ b/src/Traits/Entities/General/HasFeatureTrait.php @@ -1,18 +1,20 @@ -Featured
in the system. */ - protected bool $featured = false; + /** @var bool $is_featured - If the record is marked as Featured in the system. */ + protected bool $is_featured = false; /** * Sets the FEATURED value of an Entity. @@ -30,7 +32,7 @@ protected function castFeatured(bool $featured): void * * @return bool */ - public function featured(): bool + public function isFeatured(): bool { return $this->featured; } diff --git a/src/Traits/Entities/General/HasHitsTrait.php b/src/Traits/Entities/General/HasHitsTrait.php index b57a302..c63953d 100755 --- a/src/Traits/Entities/General/HasHitsTrait.php +++ b/src/Traits/Entities/General/HasHitsTrait.php @@ -1,14 +1,16 @@ -hits; } diff --git a/src/Traits/Entities/General/HasNameTrait.php b/src/Traits/Entities/General/HasNameTrait.php index cd31b79..98e57af 100755 --- a/src/Traits/Entities/General/HasNameTrait.php +++ b/src/Traits/Entities/General/HasNameTrait.php @@ -1,14 +1,16 @@ -name = $name; @@ -39,7 +41,7 @@ protected function castName(string $name): void * * @return string */ - public function name(): string + public function getName(): string { return $this->name; } diff --git a/src/Traits/Entities/General/HasOrderingTrait.php b/src/Traits/Entities/General/HasOrderingTrait.php index c7fc9b4..d6ea08c 100755 --- a/src/Traits/Entities/General/HasOrderingTrait.php +++ b/src/Traits/Entities/General/HasOrderingTrait.php @@ -1,14 +1,16 @@ -ordering; } diff --git a/src/Traits/Entities/General/HasPasswordTrait.php b/src/Traits/Entities/General/HasPasswordTrait.php new file mode 100755 index 0000000..83fe7ec --- /dev/null +++ b/src/Traits/Entities/General/HasPasswordTrait.php @@ -0,0 +1,39 @@ +password = $password; + } + + /** + * Returns record's Password value. + * + * @return string + */ + public function getPassword(): string + { + return $this->password; + } +} diff --git a/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php b/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php new file mode 100644 index 0000000..e22c36b --- /dev/null +++ b/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php @@ -0,0 +1,57 @@ +id = $id; + } + + /** + * Returns the Positive Integer ID + * + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * If record is a new record. Not returned from DB. + * + * Validates if the VO/Entity has an ID set. + * + * @return bool + */ + public function isNew(): bool + { + return ($this->id === null); + } +} diff --git a/src/Traits/Entities/General/HasPublishedTimestampsTrait.php b/src/Traits/Entities/General/HasPublishedTimestampsTrait.php index 444dbfa..94c1bd4 100755 --- a/src/Traits/Entities/General/HasPublishedTimestampsTrait.php +++ b/src/Traits/Entities/General/HasPublishedTimestampsTrait.php @@ -1,12 +1,14 @@ -published = $published; + $this->is_published = $published; } /** @@ -30,8 +32,8 @@ protected function castPublished(bool $published): void * * @return bool */ - public function published(): bool + public function isPublished(): bool { - return $this->published; + return $this->is_published; } } diff --git a/src/Traits/Entities/General/HasSeoFieldsTrait.php b/src/Traits/Entities/General/HasSeoFieldsTrait.php index 7c1817d..e682d07 100755 --- a/src/Traits/Entities/General/HasSeoFieldsTrait.php +++ b/src/Traits/Entities/General/HasSeoFieldsTrait.php @@ -1,14 +1,17 @@ - 70) { - throw new InvalidStringLengthException("Supplied Seo title must have length up to 70 characters."); + throw new NonEmptyStringException("Supplied Seo title must have length up to 70 characters."); } $this->seo_title = $this->seoSanitize($title); @@ -49,7 +52,7 @@ protected function castSeoTitle(?string $title = null): void * * @param string|null $description - New value to be set on Attribute. * - * @throws InvalidStringLengthException - Supplied Seo Description must be a non empty string. + * @throws NonEmptyStringException - Supplied Seo Description must be a non empty string. * * @link https://seopressor.com/blog/google-title-meta-descriptions-length * @return void @@ -58,7 +61,7 @@ protected function castSeoDescription(?string $description = null): void { // Setting the max length for Seo description. if ($description !== null && \strlen(\trim($description)) > 160) { - throw new InvalidStringLengthException("Supplied Seo description must have length up to 160 characters."); + throw new NonEmptyStringException("Supplied Seo description must have length up to 160 characters."); } $this->seo_description = $this->seoSanitize($description); @@ -70,7 +73,7 @@ protected function castSeoDescription(?string $description = null): void * * @param string|null $keywords - New value to be set on Attribute. * - * @throws InvalidStringLengthException - Supplied Seo Keywords must be a non empty string. + * @throws NonEmptyStringException - Supplied Seo Keywords must be a non empty string. * * @link https://www.quora.com/What-is-the-minimum-length-of-a-meta-keyword-in-on-page-SEO * @return void @@ -79,7 +82,7 @@ protected function castSeoKeywords(string $keywords = null): void { // Setting the max length for Seo keywords. if ($keywords !== null && \strlen(\trim($keywords)) > 255) { - throw new InvalidStringLengthException("Supplied Seo keywords must have length up to 255 characters."); + throw new NonEmptyStringException("Supplied Seo keywords must have length up to 255 characters."); } $this->seo_keywords = $this->seoSanitize($keywords); @@ -90,7 +93,7 @@ protected function castSeoKeywords(string $keywords = null): void * * @return string|null */ - public function seoTitle(): ?string + public function getSeoTitle(): ?string { // If the Seo title is not set it is set to name property. if ($this->seo_title === null || \strlen(\trim($this->seo_title)) === 0) { @@ -105,7 +108,7 @@ public function seoTitle(): ?string * * @return string|null */ - public function seoDescription(): ?string + public function getSeoDescription(): ?string { return $this->seo_description; } @@ -115,7 +118,7 @@ public function seoDescription(): ?string * * @return string|null */ - public function seoKeywords(): ?string + public function getSeoKeywords(): ?string { return $this->seo_keywords; } diff --git a/src/Traits/Entities/General/HasTimestampsTrait.php b/src/Traits/Entities/General/HasTimestampsTrait.php index bd152c4..53b4710 100755 --- a/src/Traits/Entities/General/HasTimestampsTrait.php +++ b/src/Traits/Entities/General/HasTimestampsTrait.php @@ -1,14 +1,16 @@ -updated_at = Datetime::now(); + } +} diff --git a/src/Traits/Entities/General/HasUpdatedAtTrait.php b/src/Traits/Entities/General/HasUpdatedAtTrait.php index c8795b9..1ffcbb2 100644 --- a/src/Traits/Entities/General/HasUpdatedAtTrait.php +++ b/src/Traits/Entities/General/HasUpdatedAtTrait.php @@ -1,14 +1,17 @@ -updated_at = ($timestamp ? Datetime::fromString($timestamp) : null); + $this->updated_at = ($timestamp ? Datetime::fromString(VoString::create($timestamp)) : null); } /** @@ -32,7 +35,7 @@ protected function castUpdatedAt(?string $timestamp): void * * @return Datetime|null */ - public function updatedAt(): ?Datetime + public function getUpdatedAt(): ?Datetime { return $this->updated_at; } diff --git a/src/Traits/Entities/General/HasUuidTrait.php b/src/Traits/Entities/General/HasUuidTrait.php index 60bcc39..3df82ab 100644 --- a/src/Traits/Entities/General/HasUuidTrait.php +++ b/src/Traits/Entities/General/HasUuidTrait.php @@ -1,12 +1,14 @@ -uuid; } diff --git a/src/Traits/Entities/Location/HasAddressTrait.php b/src/Traits/Entities/Location/HasAddressTrait.php index 033c96c..edfc62a 100644 --- a/src/Traits/Entities/Location/HasAddressTrait.php +++ b/src/Traits/Entities/Location/HasAddressTrait.php @@ -1,12 +1,14 @@ -address; } diff --git a/src/Traits/Entities/Location/HasCityTrait.php b/src/Traits/Entities/Location/HasCityTrait.php index 9932d10..cc325e3 100644 --- a/src/Traits/Entities/Location/HasCityTrait.php +++ b/src/Traits/Entities/Location/HasCityTrait.php @@ -1,12 +1,14 @@ -city; } diff --git a/src/Traits/Entities/Location/HasCountryCodeTrait.php b/src/Traits/Entities/Location/HasCountryCodeTrait.php new file mode 100644 index 0000000..5667e40 --- /dev/null +++ b/src/Traits/Entities/Location/HasCountryCodeTrait.php @@ -0,0 +1,41 @@ +country_code = VoString::create($countryCode); + } + + /** + * Returns the Entity's Country Code. + * + * @return VoString + */ + public function getCountryCode(): VoString + { + return $this->country_code; + } +} diff --git a/src/Traits/Entities/Location/HasCountryTrait.php b/src/Traits/Entities/Location/HasCountryTrait.php index f0480db..f577ae2 100644 --- a/src/Traits/Entities/Location/HasCountryTrait.php +++ b/src/Traits/Entities/Location/HasCountryTrait.php @@ -1,12 +1,14 @@ -country; } diff --git a/src/Traits/Entities/Location/HasLatitudeTrait.php b/src/Traits/Entities/Location/HasLatitudeTrait.php new file mode 100644 index 0000000..055e777 --- /dev/null +++ b/src/Traits/Entities/Location/HasLatitudeTrait.php @@ -0,0 +1,39 @@ +latitude = $latitude; + } + + /** + * Returns the Entity's Latitude. + * + * @return float + */ + public function getLatitude(): float + { + return $this->latitude; + } +} diff --git a/src/Traits/Entities/Location/HasLongitudeTrait.php b/src/Traits/Entities/Location/HasLongitudeTrait.php new file mode 100644 index 0000000..ce98c42 --- /dev/null +++ b/src/Traits/Entities/Location/HasLongitudeTrait.php @@ -0,0 +1,39 @@ +longitude = $longitude; + } + + /** + * Returns the Entity's Longitude. + * + * @return float + */ + public function getLongitude(): float + { + return $this->longitude; + } +} diff --git a/src/Traits/Entities/Location/HasPostalCodeTrait.php b/src/Traits/Entities/Location/HasPostalCodeTrait.php index d1bfb2b..fcbf988 100644 --- a/src/Traits/Entities/Location/HasPostalCodeTrait.php +++ b/src/Traits/Entities/Location/HasPostalCodeTrait.php @@ -1,12 +1,14 @@ -postal_code; } diff --git a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php index 0b02ac4..721585f 100644 --- a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php +++ b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php @@ -1,12 +1,14 @@ -street_additional; } diff --git a/src/Traits/Entities/Location/HasStreetNumberTrait.php b/src/Traits/Entities/Location/HasStreetNumberTrait.php index 533812d..3426dd8 100644 --- a/src/Traits/Entities/Location/HasStreetNumberTrait.php +++ b/src/Traits/Entities/Location/HasStreetNumberTrait.php @@ -1,12 +1,14 @@ -street_no; } diff --git a/src/Traits/Entities/Location/HasStreetTrait.php b/src/Traits/Entities/Location/HasStreetTrait.php index b82ccd8..a12c1ee 100644 --- a/src/Traits/Entities/Location/HasStreetTrait.php +++ b/src/Traits/Entities/Location/HasStreetTrait.php @@ -1,12 +1,14 @@ -street; } diff --git a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php index 8455ab5..a528ea5 100644 --- a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php +++ b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php @@ -1,14 +1,16 @@ -country_of_birth; } diff --git a/src/Traits/Entities/Personal/HasDateOfBirthTrait.php b/src/Traits/Entities/Personal/HasDateOfBirthTrait.php index 4b42614..300c49a 100644 --- a/src/Traits/Entities/Personal/HasDateOfBirthTrait.php +++ b/src/Traits/Entities/Personal/HasDateOfBirthTrait.php @@ -1,14 +1,16 @@ -dob; } diff --git a/src/Traits/Entities/Personal/HasGenderTrait.php b/src/Traits/Entities/Personal/HasGenderTrait.php index 459edf5..2443261 100644 --- a/src/Traits/Entities/Personal/HasGenderTrait.php +++ b/src/Traits/Entities/Personal/HasGenderTrait.php @@ -1,14 +1,16 @@ -sex; } diff --git a/src/Traits/Entities/Personal/HasPhotoTrait.php b/src/Traits/Entities/Personal/HasPhotoTrait.php new file mode 100755 index 0000000..31e6b09 --- /dev/null +++ b/src/Traits/Entities/Personal/HasPhotoTrait.php @@ -0,0 +1,58 @@ +photo = $photo; + } + + /** + * Returns the Instance's Profile's Photo. + * + * @return string|null + */ + public function getPhoto(): ?string + { + return $this->photo; + } + + /** + * If record has Profile's Photo. + * + * @return bool + */ + public function hasPhoto(): bool + { + return ($this->photo !== null); + } +} diff --git a/src/Traits/Entities/Personal/HasSurnameTrait.php b/src/Traits/Entities/Personal/HasSurnameTrait.php index 78e81dc..1cd0567 100755 --- a/src/Traits/Entities/Personal/HasSurnameTrait.php +++ b/src/Traits/Entities/Personal/HasSurnameTrait.php @@ -1,14 +1,16 @@ -surname = $surname; @@ -39,7 +41,7 @@ protected function castSurname(string $surname): void * * @return string */ - public function surname(): string + public function getSurname(): string { return $this->surname; } diff --git a/src/Traits/Entities/Professional/HasOccupationTrait.php b/src/Traits/Entities/Professional/HasOccupationTrait.php new file mode 100755 index 0000000..f58b716 --- /dev/null +++ b/src/Traits/Entities/Professional/HasOccupationTrait.php @@ -0,0 +1,58 @@ +occupation = $occupation; + } + + /** + * Returns the Instance's Profile's Occupation. + * + * @return string|null + */ + public function getOccupation(): ?string + { + return $this->occupation; + } + + /** + * If record has Profile's Occupation. + * + * @return bool + */ + public function hasOccupation(): bool + { + return ($this->occupation !== null); + } +} diff --git a/src/Traits/Entities/Professional/README.md b/src/Traits/Entities/Professional/README.md new file mode 100644 index 0000000..f40d577 --- /dev/null +++ b/src/Traits/Entities/Professional/README.md @@ -0,0 +1 @@ +# Entity related Timezone Traits diff --git a/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php b/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php new file mode 100755 index 0000000..8491fca --- /dev/null +++ b/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php @@ -0,0 +1,49 @@ +facebook = $facebook; + } + + /** + * Retrieves record's Social Media account's URL. + * + * @return string|null + */ + public function getFacebookUrl(): ?string + { + return $this->facebook; + } + + /** + * Is Facebook's Social Media account URL is set. + * + * @return bool + */ + public function hasFacebookProfileUrl(): bool + { + return ($this->facebook !== null); + } +} diff --git a/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php b/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php new file mode 100755 index 0000000..ca09c8e --- /dev/null +++ b/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php @@ -0,0 +1,49 @@ +instagram = $instagram; + } + + /** + * Retrieves record's Social Media account's URL. + * + * @return string|null + */ + public function getInstagramUrl(): ?string + { + return $this->instagram; + } + + /** + * Is Instagram's Social Media account URL is set. + * + * @return bool + */ + public function hasInstagramProfileUrl(): bool + { + return ($this->instagram !== null); + } +} diff --git a/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php b/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php new file mode 100755 index 0000000..098fe54 --- /dev/null +++ b/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php @@ -0,0 +1,49 @@ +linkedin = $linkedin; + } + + /** + * Retrieves record's Social Media account's URL. + * + * @return string|null + */ + public function getLinkedinUrl(): ?string + { + return $this->linkedin; + } + + /** + * Is Linkedin's Social Media account URL is set. + * + * @return bool + */ + public function hasLinkedinProfileUrl(): bool + { + return ($this->linkedin !== null); + } +} diff --git a/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php b/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php new file mode 100755 index 0000000..82363e1 --- /dev/null +++ b/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php @@ -0,0 +1,49 @@ +twitter = $twitter; + } + + /** + * Retrieves record's Social Media account's URL. + * + * @return string|null + */ + public function getTwitterUrl(): ?string + { + return $this->twitter; + } + + /** + * Is Twitter's Social Media account URL is set. + * + * @return bool + */ + public function hasTwitterProfileUrl(): bool + { + return ($this->twitter !== null); + } +} diff --git a/src/Traits/Entities/SocialMedia/README.md b/src/Traits/Entities/SocialMedia/README.md new file mode 100644 index 0000000..64d26e6 --- /dev/null +++ b/src/Traits/Entities/SocialMedia/README.md @@ -0,0 +1 @@ +# Entity related Social Media Traits diff --git a/src/Traits/Entities/Timezone/HasTimestampTrait.php b/src/Traits/Entities/Timezone/HasTimestampTrait.php new file mode 100755 index 0000000..78a9cf5 --- /dev/null +++ b/src/Traits/Entities/Timezone/HasTimestampTrait.php @@ -0,0 +1,39 @@ +timestamp = $timestamp; + } + + /** + * Returns the Instance's Unix timestamp. + * + * @return int + */ + public function getTimestamp(): int + { + return $this->timestamp; + } +} diff --git a/src/Traits/Entities/Timezone/README.md b/src/Traits/Entities/Timezone/README.md new file mode 100644 index 0000000..f40d577 --- /dev/null +++ b/src/Traits/Entities/Timezone/README.md @@ -0,0 +1 @@ +# Entity related Timezone Traits diff --git a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php new file mode 100644 index 0000000..016f1c1 --- /dev/null +++ b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php @@ -0,0 +1,45 @@ +onLoad(function() { $this->someCall() }); + * + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes + * @license Proprietary + */ +trait CanProcessOnLoadEventsTrait +{ + /** @var array $onLoadEvents - List of onLoad event handlers, defined as closures. */ + private array $onLoadEvents = []; + + /** + * Triggers all onLoad pre-declared events. + * + * @return void + */ + protected function triggerOnLoad(): void + { + foreach ($this->onLoadEvents as $onLoad) { + $onLoad(); + } + } + + /** + * Adds a new onLoad event handler to the class. + * + * @param Closure $handler - Closure that will be triggered onLoad. + * @return void + */ + protected function onLoad(Closure $handler): void + { + $this->onLoadEvents[] = $handler; + } +} diff --git a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php index 89630a5..b2c6e86 100644 --- a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php +++ b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php @@ -1,15 +1,17 @@ -jsonSerialize(); - } elseif (\method_exists($value, '__toString')) { + } elseif (\is_object($value) && \method_exists($value, '__toString')) { $converted[$field] = (string) $value; } elseif (\is_array($value) || \is_object($value)) { $converted[$field] = \json_encode($value); diff --git a/src/Traits/ValueObjects/HasFieldCastingTrait.php b/src/Traits/ValueObjects/HasFieldCastingTrait.php index e2ef24d..0c7a8be 100644 --- a/src/Traits/ValueObjects/HasFieldCastingTrait.php +++ b/src/Traits/ValueObjects/HasFieldCastingTrait.php @@ -1,14 +1,16 @@ -loadInstance($fields); + $this->triggerOnLoad(); } /** @@ -113,7 +116,8 @@ private function filterSystemControlFields(array $attrs): array $attrs['required'], $attrs['ruleList'], $attrs['castList'], - $attrs['attributeList'] + $attrs['attributeList'], + $attrs['onLoadEvents'] ); return $attrs; diff --git a/src/ValueObjects/README.md b/src/ValueObjects/README.md index f2dae9b..15e4780 100755 --- a/src/ValueObjects/README.md +++ b/src/ValueObjects/README.md @@ -13,7 +13,7 @@ The first thing you should assess, is the context of the **Value Object** you're Similar contexted **Value Objects**, will be placed near each other in the filesystem/namespace. -All **Value Objects** should be located in the `Hradigital\Basetypes\ValueObjects` namespace, followed by the same segments +All **Value Objects** should be located in the `HraDigital\Basetypes\ValueObjects` namespace, followed by the same segments present in the file system, up to the class definition. ### Value Objects are immutable @@ -36,9 +36,9 @@ If we're talking about a Database as a **persistence layer**, and a given datata ```php class MyValueObject extends AbstractValueObject { - protected $name = ''; - protected $surname = ''; - protected $date_of_birth = null; + protected VoString $name; + protected VoString $surname; + protected Datetime $date_of_birth; } ``` @@ -97,10 +97,10 @@ protected $maps = [ ```php class Person extends AbstractvalueObject { - protected $name = ''; - protected $surname = ''; + protected VoString $name; + protected VoString $surname; - protected $required = ['name', 'surname']; + protected array $required = ['name', 'surname']; } ``` @@ -113,12 +113,12 @@ class Person extends AbstractValueObject protected function castName(string $name): void { - $this->name = trim($name); + $this->name = VoString::create($name)->trim(); } protected function castSurname(string $surname): void { - $this->surname = trim($surname); + $this->surname = VoString::create($surname)->trim(); } } ``` @@ -130,12 +130,12 @@ class Person extends AbstractValueObject { // ... Previous content. - public function name(): string + public function name(): VoString { return $this->name; } - public function surname(): string + public function surname(): VoString { return $this->surname; } diff --git a/src/ValueObjects/Timezone/Identifier.php b/src/ValueObjects/Timezone/Identifier.php new file mode 100644 index 0000000..ed973d3 --- /dev/null +++ b/src/ValueObjects/Timezone/Identifier.php @@ -0,0 +1,15 @@ +comments = ($comments ? VoString::create($comments) : null); + } + + public function comments(): ?VoString + { + return $this->comments; + } +} diff --git a/src/ValueObjects/Timezone/README.md b/src/ValueObjects/Timezone/README.md new file mode 100755 index 0000000..9295305 --- /dev/null +++ b/src/ValueObjects/Timezone/README.md @@ -0,0 +1 @@ +# Timezone related Value Objects diff --git a/src/ValueObjects/Timezone/Transition.php b/src/ValueObjects/Timezone/Transition.php new file mode 100644 index 0000000..e088cb2 --- /dev/null +++ b/src/ValueObjects/Timezone/Transition.php @@ -0,0 +1,86 @@ + 'timestamp', + 'time' => 'dateTime', + 'offSet' => 'offset', + 'isdst' => 'isDayLightSavingActive', + 'abbr' => 'abbreviation', + ]; + + protected function castDateTime(string $time): void + { + $this->dateTime = Datetime::fromString( + VoString::create($time) + ); + } + + protected function castOffset(int $offset): void + { + $this->offset = $offset; + } + + protected function castIsDayLightSavingActive(int $isActive): void + { + $this->isDayLightSavingActive = (bool) $isActive; + } + + protected function castAbbreviation(string $abbreviation): void + { + $this->abbreviation = VoString::create($abbreviation); + } + + public function dateTime(): Datetime + { + return $this->dateTime; + } + + public function offset(): int + { + return $this->offset; + } + + public function isDayLightSavingActive(): bool + { + return $this->isDayLightSavingActive; + } + + public function abbreviation(): VoString + { + return $this->abbreviation; + } +} diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 895d666..e2b5a00 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -1,10 +1,10 @@ Date: Tue, 9 Nov 2021 11:52:31 +0000 Subject: [PATCH 066/193] Change License specification in class docBlocks --- src/Traits/Entities/CanProcessEntityStateTrait.php | 2 +- src/Traits/Entities/CanProcessOnUpdateEventsTrait.php | 2 +- src/Traits/Entities/General/HasActiveTrait.php | 2 +- src/Traits/Entities/General/HasAliasTrait.php | 2 +- src/Traits/Entities/General/HasCreatedAtTrait.php | 2 +- src/Traits/Entities/General/HasDeletedAtTrait.php | 2 +- src/Traits/Entities/General/HasEmailTrait.php | 2 +- src/Traits/Entities/General/HasFeatureTrait.php | 2 +- src/Traits/Entities/General/HasHitsTrait.php | 2 +- src/Traits/Entities/General/HasNameTrait.php | 2 +- src/Traits/Entities/General/HasOrderingTrait.php | 2 +- src/Traits/Entities/General/HasPasswordTrait.php | 2 +- src/Traits/Entities/General/HasPositiveIntegerIDTrait.php | 2 +- src/Traits/Entities/General/HasPublishedTimestampsTrait.php | 2 +- src/Traits/Entities/General/HasPublishedTrait.php | 2 +- src/Traits/Entities/General/HasSeoFieldsTrait.php | 2 +- src/Traits/Entities/General/HasTimestampsTrait.php | 2 +- src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php | 2 +- src/Traits/Entities/General/HasUpdatedAtTrait.php | 2 +- src/Traits/Entities/General/HasUuidTrait.php | 2 +- src/Traits/Entities/Location/HasAddressTrait.php | 2 +- src/Traits/Entities/Location/HasCityTrait.php | 2 +- src/Traits/Entities/Location/HasCountryCodeTrait.php | 2 +- src/Traits/Entities/Location/HasCountryTrait.php | 2 +- src/Traits/Entities/Location/HasLatitudeTrait.php | 2 +- src/Traits/Entities/Location/HasLongitudeTrait.php | 2 +- src/Traits/Entities/Location/HasPostalCodeTrait.php | 2 +- src/Traits/Entities/Location/HasStreetAdditionalTrait.php | 2 +- src/Traits/Entities/Location/HasStreetNumberTrait.php | 2 +- src/Traits/Entities/Location/HasStreetTrait.php | 2 +- src/Traits/Entities/Personal/HasCountryOfBirthTrait.php | 2 +- src/Traits/Entities/Personal/HasDateOfBirthTrait.php | 2 +- src/Traits/Entities/Personal/HasGenderTrait.php | 2 +- src/Traits/Entities/Personal/HasPhotoTrait.php | 2 +- src/Traits/Entities/Personal/HasSurnameTrait.php | 2 +- src/Traits/Entities/Professional/HasOccupationTrait.php | 2 +- src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php | 2 +- src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php | 2 +- src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php | 2 +- src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php | 2 +- src/Traits/Entities/Timezone/HasTimestampTrait.php | 2 +- src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php | 2 +- src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php | 2 +- src/Traits/ValueObjects/HasFieldCastingTrait.php | 2 +- src/Traits/ValueObjects/HasGuardedFieldsTrait.php | 2 +- src/Traits/ValueObjects/HasMappedFieldsTrait.php | 2 +- src/Traits/ValueObjects/HasRequiredFieldsTrait.php | 2 +- src/Traits/ValueObjects/HasRuleProcessingTrait.php | 2 +- src/ValueObjects/AbstractValueObject.php | 2 +- 49 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index d387688..7ff9e33 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait CanProcessEntityStateTrait { diff --git a/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php b/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php index 637ceb4..33ba54e 100644 --- a/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php +++ b/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php @@ -13,7 +13,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait CanProcessOnUpdateEventsTrait { diff --git a/src/Traits/Entities/General/HasActiveTrait.php b/src/Traits/Entities/General/HasActiveTrait.php index 376ada7..429d8a1 100755 --- a/src/Traits/Entities/General/HasActiveTrait.php +++ b/src/Traits/Entities/General/HasActiveTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasActiveTrait { diff --git a/src/Traits/Entities/General/HasAliasTrait.php b/src/Traits/Entities/General/HasAliasTrait.php index d637b78..0f19feb 100755 --- a/src/Traits/Entities/General/HasAliasTrait.php +++ b/src/Traits/Entities/General/HasAliasTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasAliasTrait { diff --git a/src/Traits/Entities/General/HasCreatedAtTrait.php b/src/Traits/Entities/General/HasCreatedAtTrait.php index efab99f..99ee560 100644 --- a/src/Traits/Entities/General/HasCreatedAtTrait.php +++ b/src/Traits/Entities/General/HasCreatedAtTrait.php @@ -12,7 +12,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasCreatedAtTrait { diff --git a/src/Traits/Entities/General/HasDeletedAtTrait.php b/src/Traits/Entities/General/HasDeletedAtTrait.php index 12819f4..8d8688d 100644 --- a/src/Traits/Entities/General/HasDeletedAtTrait.php +++ b/src/Traits/Entities/General/HasDeletedAtTrait.php @@ -13,7 +13,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasDeletedAtTrait { diff --git a/src/Traits/Entities/General/HasEmailTrait.php b/src/Traits/Entities/General/HasEmailTrait.php index 3a9733a..27d644b 100644 --- a/src/Traits/Entities/General/HasEmailTrait.php +++ b/src/Traits/Entities/General/HasEmailTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasEmailTrait { diff --git a/src/Traits/Entities/General/HasFeatureTrait.php b/src/Traits/Entities/General/HasFeatureTrait.php index c70b26e..e2d823f 100755 --- a/src/Traits/Entities/General/HasFeatureTrait.php +++ b/src/Traits/Entities/General/HasFeatureTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasFeatureTrait { diff --git a/src/Traits/Entities/General/HasHitsTrait.php b/src/Traits/Entities/General/HasHitsTrait.php index c63953d..b30211c 100755 --- a/src/Traits/Entities/General/HasHitsTrait.php +++ b/src/Traits/Entities/General/HasHitsTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasHitsTrait { diff --git a/src/Traits/Entities/General/HasNameTrait.php b/src/Traits/Entities/General/HasNameTrait.php index 98e57af..467e780 100755 --- a/src/Traits/Entities/General/HasNameTrait.php +++ b/src/Traits/Entities/General/HasNameTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasNameTrait { diff --git a/src/Traits/Entities/General/HasOrderingTrait.php b/src/Traits/Entities/General/HasOrderingTrait.php index d6ea08c..066113c 100755 --- a/src/Traits/Entities/General/HasOrderingTrait.php +++ b/src/Traits/Entities/General/HasOrderingTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasOrderingTrait { diff --git a/src/Traits/Entities/General/HasPasswordTrait.php b/src/Traits/Entities/General/HasPasswordTrait.php index 83fe7ec..f8ea376 100755 --- a/src/Traits/Entities/General/HasPasswordTrait.php +++ b/src/Traits/Entities/General/HasPasswordTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasPasswordTrait { diff --git a/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php b/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php index e22c36b..d1fcc0c 100644 --- a/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php +++ b/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasPositiveIntegerIDTrait { diff --git a/src/Traits/Entities/General/HasPublishedTimestampsTrait.php b/src/Traits/Entities/General/HasPublishedTimestampsTrait.php index 94c1bd4..370eb60 100755 --- a/src/Traits/Entities/General/HasPublishedTimestampsTrait.php +++ b/src/Traits/Entities/General/HasPublishedTimestampsTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT * @todo Finish up Trait, when Datetime datatype is finished. */ trait HasPublishedTimestampsTrait diff --git a/src/Traits/Entities/General/HasPublishedTrait.php b/src/Traits/Entities/General/HasPublishedTrait.php index 33ae1b3..b4c2649 100755 --- a/src/Traits/Entities/General/HasPublishedTrait.php +++ b/src/Traits/Entities/General/HasPublishedTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasPublishedTrait { diff --git a/src/Traits/Entities/General/HasSeoFieldsTrait.php b/src/Traits/Entities/General/HasSeoFieldsTrait.php index e682d07..9308649 100755 --- a/src/Traits/Entities/General/HasSeoFieldsTrait.php +++ b/src/Traits/Entities/General/HasSeoFieldsTrait.php @@ -12,7 +12,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasSeoFieldsTrait { diff --git a/src/Traits/Entities/General/HasTimestampsTrait.php b/src/Traits/Entities/General/HasTimestampsTrait.php index 53b4710..78a0924 100755 --- a/src/Traits/Entities/General/HasTimestampsTrait.php +++ b/src/Traits/Entities/General/HasTimestampsTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasTimestampsTrait { diff --git a/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php b/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php index 6e56594..8e73690 100644 --- a/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php +++ b/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php @@ -14,7 +14,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasUpdatableUpdatedAtTrait { diff --git a/src/Traits/Entities/General/HasUpdatedAtTrait.php b/src/Traits/Entities/General/HasUpdatedAtTrait.php index 1ffcbb2..27510b9 100644 --- a/src/Traits/Entities/General/HasUpdatedAtTrait.php +++ b/src/Traits/Entities/General/HasUpdatedAtTrait.php @@ -12,7 +12,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasUpdatedAtTrait { diff --git a/src/Traits/Entities/General/HasUuidTrait.php b/src/Traits/Entities/General/HasUuidTrait.php index 3df82ab..952f17d 100644 --- a/src/Traits/Entities/General/HasUuidTrait.php +++ b/src/Traits/Entities/General/HasUuidTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasUuidTrait { diff --git a/src/Traits/Entities/Location/HasAddressTrait.php b/src/Traits/Entities/Location/HasAddressTrait.php index edfc62a..df1786e 100644 --- a/src/Traits/Entities/Location/HasAddressTrait.php +++ b/src/Traits/Entities/Location/HasAddressTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasAddressTrait { diff --git a/src/Traits/Entities/Location/HasCityTrait.php b/src/Traits/Entities/Location/HasCityTrait.php index cc325e3..6b1df33 100644 --- a/src/Traits/Entities/Location/HasCityTrait.php +++ b/src/Traits/Entities/Location/HasCityTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasCityTrait { diff --git a/src/Traits/Entities/Location/HasCountryCodeTrait.php b/src/Traits/Entities/Location/HasCountryCodeTrait.php index 5667e40..73602ee 100644 --- a/src/Traits/Entities/Location/HasCountryCodeTrait.php +++ b/src/Traits/Entities/Location/HasCountryCodeTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasCountryCodeTrait { diff --git a/src/Traits/Entities/Location/HasCountryTrait.php b/src/Traits/Entities/Location/HasCountryTrait.php index f577ae2..ce366c7 100644 --- a/src/Traits/Entities/Location/HasCountryTrait.php +++ b/src/Traits/Entities/Location/HasCountryTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasCountryTrait { diff --git a/src/Traits/Entities/Location/HasLatitudeTrait.php b/src/Traits/Entities/Location/HasLatitudeTrait.php index 055e777..d420947 100644 --- a/src/Traits/Entities/Location/HasLatitudeTrait.php +++ b/src/Traits/Entities/Location/HasLatitudeTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasLatitudeTrait { diff --git a/src/Traits/Entities/Location/HasLongitudeTrait.php b/src/Traits/Entities/Location/HasLongitudeTrait.php index ce98c42..bf5cc48 100644 --- a/src/Traits/Entities/Location/HasLongitudeTrait.php +++ b/src/Traits/Entities/Location/HasLongitudeTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasLongitudeTrait { diff --git a/src/Traits/Entities/Location/HasPostalCodeTrait.php b/src/Traits/Entities/Location/HasPostalCodeTrait.php index fcbf988..8206639 100644 --- a/src/Traits/Entities/Location/HasPostalCodeTrait.php +++ b/src/Traits/Entities/Location/HasPostalCodeTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasPostalCodeTrait { diff --git a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php index 721585f..a75419d 100644 --- a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php +++ b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasStreetAdditionalTrait { diff --git a/src/Traits/Entities/Location/HasStreetNumberTrait.php b/src/Traits/Entities/Location/HasStreetNumberTrait.php index 3426dd8..2ff81cb 100644 --- a/src/Traits/Entities/Location/HasStreetNumberTrait.php +++ b/src/Traits/Entities/Location/HasStreetNumberTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasStreetNumberTrait { diff --git a/src/Traits/Entities/Location/HasStreetTrait.php b/src/Traits/Entities/Location/HasStreetTrait.php index a12c1ee..b0f347a 100644 --- a/src/Traits/Entities/Location/HasStreetTrait.php +++ b/src/Traits/Entities/Location/HasStreetTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasStreetTrait { diff --git a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php index a528ea5..2491f32 100644 --- a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php +++ b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasCountryOfBirthTrait { diff --git a/src/Traits/Entities/Personal/HasDateOfBirthTrait.php b/src/Traits/Entities/Personal/HasDateOfBirthTrait.php index 300c49a..ede1773 100644 --- a/src/Traits/Entities/Personal/HasDateOfBirthTrait.php +++ b/src/Traits/Entities/Personal/HasDateOfBirthTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasDateOfBirthTrait { diff --git a/src/Traits/Entities/Personal/HasGenderTrait.php b/src/Traits/Entities/Personal/HasGenderTrait.php index 2443261..31ad845 100644 --- a/src/Traits/Entities/Personal/HasGenderTrait.php +++ b/src/Traits/Entities/Personal/HasGenderTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasGenderTrait { diff --git a/src/Traits/Entities/Personal/HasPhotoTrait.php b/src/Traits/Entities/Personal/HasPhotoTrait.php index 31e6b09..c75b0a1 100755 --- a/src/Traits/Entities/Personal/HasPhotoTrait.php +++ b/src/Traits/Entities/Personal/HasPhotoTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasPhotoTrait { diff --git a/src/Traits/Entities/Personal/HasSurnameTrait.php b/src/Traits/Entities/Personal/HasSurnameTrait.php index 1cd0567..eff2375 100755 --- a/src/Traits/Entities/Personal/HasSurnameTrait.php +++ b/src/Traits/Entities/Personal/HasSurnameTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasSurnameTrait { diff --git a/src/Traits/Entities/Professional/HasOccupationTrait.php b/src/Traits/Entities/Professional/HasOccupationTrait.php index f58b716..21096f7 100755 --- a/src/Traits/Entities/Professional/HasOccupationTrait.php +++ b/src/Traits/Entities/Professional/HasOccupationTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasOccupationTrait { diff --git a/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php b/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php index 8491fca..fae2d0a 100755 --- a/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php +++ b/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasFacebookProfileTrait { diff --git a/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php b/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php index ca09c8e..07b6d27 100755 --- a/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php +++ b/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasInstagramProfileTrait { diff --git a/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php b/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php index 098fe54..7f6dc36 100755 --- a/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php +++ b/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasLinkedinProfileTrait { diff --git a/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php b/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php index 82363e1..8d04bf6 100755 --- a/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php +++ b/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasTwitterProfileTrait { diff --git a/src/Traits/Entities/Timezone/HasTimestampTrait.php b/src/Traits/Entities/Timezone/HasTimestampTrait.php index 78a9cf5..9cca458 100755 --- a/src/Traits/Entities/Timezone/HasTimestampTrait.php +++ b/src/Traits/Entities/Timezone/HasTimestampTrait.php @@ -9,7 +9,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasTimestampTrait { diff --git a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php index 016f1c1..1bc74ec 100644 --- a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php +++ b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php @@ -13,7 +13,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait CanProcessOnLoadEventsTrait { diff --git a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php index b2c6e86..41032d7 100644 --- a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php +++ b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php @@ -12,7 +12,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasConversionToPrimitiveValuesTrait { diff --git a/src/Traits/ValueObjects/HasFieldCastingTrait.php b/src/Traits/ValueObjects/HasFieldCastingTrait.php index 0c7a8be..287f11e 100644 --- a/src/Traits/ValueObjects/HasFieldCastingTrait.php +++ b/src/Traits/ValueObjects/HasFieldCastingTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasFieldCastingTrait { diff --git a/src/Traits/ValueObjects/HasGuardedFieldsTrait.php b/src/Traits/ValueObjects/HasGuardedFieldsTrait.php index 70bf38b..502c555 100644 --- a/src/Traits/ValueObjects/HasGuardedFieldsTrait.php +++ b/src/Traits/ValueObjects/HasGuardedFieldsTrait.php @@ -12,7 +12,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasGuardedFieldsTrait { diff --git a/src/Traits/ValueObjects/HasMappedFieldsTrait.php b/src/Traits/ValueObjects/HasMappedFieldsTrait.php index efaa72f..700783a 100644 --- a/src/Traits/ValueObjects/HasMappedFieldsTrait.php +++ b/src/Traits/ValueObjects/HasMappedFieldsTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasMappedFieldsTrait { diff --git a/src/Traits/ValueObjects/HasRequiredFieldsTrait.php b/src/Traits/ValueObjects/HasRequiredFieldsTrait.php index 3d51cc0..8d829d9 100644 --- a/src/Traits/ValueObjects/HasRequiredFieldsTrait.php +++ b/src/Traits/ValueObjects/HasRequiredFieldsTrait.php @@ -13,7 +13,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasRequiredFieldsTrait { diff --git a/src/Traits/ValueObjects/HasRuleProcessingTrait.php b/src/Traits/ValueObjects/HasRuleProcessingTrait.php index ff03f98..d7ead2f 100644 --- a/src/Traits/ValueObjects/HasRuleProcessingTrait.php +++ b/src/Traits/ValueObjects/HasRuleProcessingTrait.php @@ -11,7 +11,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ trait HasRuleProcessingTrait { diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php index bd736fd..7077bb0 100644 --- a/src/ValueObjects/AbstractValueObject.php +++ b/src/ValueObjects/AbstractValueObject.php @@ -31,7 +31,7 @@ * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes - * @license Proprietary + * @license MIT */ abstract class AbstractValueObject implements \JsonSerializable, Serializable { From c980f13eb032c82fc15f4181210d5a09fcde06c3 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 11:56:11 +0000 Subject: [PATCH 067/193] Reverted static factory string parameters to primitives --- .../Datetime/Datetime/HasStaticFactoryMethodsTrait.php | 3 +-- src/Traits/Entities/General/HasCreatedAtTrait.php | 3 +-- src/Traits/Entities/General/HasDeletedAtTrait.php | 2 +- src/Traits/Entities/General/HasUpdatedAtTrait.php | 3 +-- src/ValueObjects/Timezone/Transition.php | 8 ++++---- src/Web/EmailAddress.php | 4 +++- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php b/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php index f5249d7..6205126 100644 --- a/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php +++ b/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php @@ -6,7 +6,6 @@ use HraDigital\Datatypes\Datetime\Datetime; use HraDigital\Datatypes\Datetime\DateTimeZone; -use HraDigital\Datatypes\Scalar\VoString; trait HasStaticFactoryMethodsTrait { @@ -30,7 +29,7 @@ public static function yesterday(): Datetime return new Datetime("yesterday"); } - public static function fromString(?VoString $datetime = null, ?DateTimeZone $timezone = null): Datetime + public static function fromString(?string $datetime = null, ?DateTimeZone $timezone = null): Datetime { return new Datetime((string) $datetime ?? "now", $timezone); } diff --git a/src/Traits/Entities/General/HasCreatedAtTrait.php b/src/Traits/Entities/General/HasCreatedAtTrait.php index 99ee560..8d4e09c 100644 --- a/src/Traits/Entities/General/HasCreatedAtTrait.php +++ b/src/Traits/Entities/General/HasCreatedAtTrait.php @@ -5,7 +5,6 @@ namespace HraDigital\Datatypes\Traits\Entities\General; use HraDigital\Datatypes\Datetime\Datetime; -use HraDigital\Datatypes\Scalar\VoString; /** * Trait for a Record CreatedAt attribute. @@ -27,7 +26,7 @@ trait HasCreatedAtTrait */ protected function castCreatedAt(string $timestamp): void { - $this->created_at = Datetime::fromString(VoString::create($timestamp)); + $this->created_at = Datetime::fromString($timestamp); } /** diff --git a/src/Traits/Entities/General/HasDeletedAtTrait.php b/src/Traits/Entities/General/HasDeletedAtTrait.php index 8d8688d..81cf130 100644 --- a/src/Traits/Entities/General/HasDeletedAtTrait.php +++ b/src/Traits/Entities/General/HasDeletedAtTrait.php @@ -28,7 +28,7 @@ trait HasDeletedAtTrait */ protected function castDeletedAt(?string $timestamp): void { - $this->deleted_at = ($timestamp ? Datetime::fromString(VoString::create($timestamp)) : null); + $this->deleted_at = ($timestamp ? Datetime::fromString($timestamp) : null); } /** diff --git a/src/Traits/Entities/General/HasUpdatedAtTrait.php b/src/Traits/Entities/General/HasUpdatedAtTrait.php index 27510b9..d47311d 100644 --- a/src/Traits/Entities/General/HasUpdatedAtTrait.php +++ b/src/Traits/Entities/General/HasUpdatedAtTrait.php @@ -5,7 +5,6 @@ namespace HraDigital\Datatypes\Traits\Entities\General; use HraDigital\Datatypes\Datetime\Datetime; -use HraDigital\Datatypes\Scalar\VoString; /** * Trait for a Record UpdatedAt attribute. @@ -27,7 +26,7 @@ trait HasUpdatedAtTrait */ protected function castUpdatedAt(?string $timestamp): void { - $this->updated_at = ($timestamp ? Datetime::fromString(VoString::create($timestamp)) : null); + $this->updated_at = ($timestamp ? Datetime::fromString($timestamp) : null); } /** diff --git a/src/ValueObjects/Timezone/Transition.php b/src/ValueObjects/Timezone/Transition.php index e088cb2..f1f1924 100644 --- a/src/ValueObjects/Timezone/Transition.php +++ b/src/ValueObjects/Timezone/Transition.php @@ -1,4 +1,6 @@ -dateTime = Datetime::fromString( - VoString::create($time) - ); + $this->dateTime = Datetime::fromString($time); } protected function castOffset(int $offset): void diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index e2b5a00..0b5e33e 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -1,4 +1,6 @@ - Date: Tue, 9 Nov 2021 11:57:36 +0000 Subject: [PATCH 068/193] Rename VoString class to Str --- src/Datetime/DateInterval.php | 20 +-- src/Datetime/Datetime.php | 118 ++++++------- src/Datetime/DatetimeInheritance.php | 104 +++++------ src/Scalar/NString.php | 8 +- src/Scalar/README.md | 38 ++-- src/Scalar/{VoString.php => Str.php} | 162 +++++++++--------- .../General/HasUpdatableUpdatedAtTrait.php | 2 +- .../Entities/Location/HasCountryCodeTrait.php | 12 +- src/ValueObjects/README.md | 16 +- src/ValueObjects/Timezone/Location.php | 8 +- src/ValueObjects/Timezone/Transition.php | 8 +- src/Web/EmailAddress.php | 34 ++-- 12 files changed, 266 insertions(+), 264 deletions(-) rename src/Scalar/{VoString.php => Str.php} (73%) diff --git a/src/Datetime/DateInterval.php b/src/Datetime/DateInterval.php index 94190db..89e2221 100644 --- a/src/Datetime/DateInterval.php +++ b/src/Datetime/DateInterval.php @@ -4,7 +4,7 @@ namespace HraDigital\Datatypes\Datetime; -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; /** * DateInterval utility class. @@ -19,7 +19,7 @@ class DateInterval { protected \DateInterval $interval; - public static function fromDuration(VoString $duration, bool $inverted = false): DateInterval + public static function fromDuration(Str $duration, bool $inverted = false): DateInterval { return new DateInterval((string) $duration, $inverted); } @@ -123,31 +123,31 @@ public function inMicroSeconds(): float return $this->interval->invert ? (0 - $this->interval->f) : $this->interval->f; } - protected function toFormatInternal(string $format): VoString + protected function toFormatInternal(string $format): Str { - return VoString::create( + return Str::create( $this->interval->format($format) ); } /** - * Returns VoString instance with value in format "Y-m-d H:i:s". + * Returns Str instance with value in format "Y-m-d H:i:s". * - * @return VoString + * @return Str */ - public function toDatetimeString(): VoString + public function toDatetimeString(): Str { return $this->toFormatInternal('Y-m-d H:i:s'); } - public function toFormat(VoString $format): VoString + public function toFormat(Str $format): Str { return $this->toFormatInternal((string) $format); } - public function toDuration(): VoString + public function toDuration(): Str { - return VoString::create( + return Str::create( \sprintf( 'P%dY%dM%dDT%dH%dM%dS', $this->interval->y, diff --git a/src/Datetime/Datetime.php b/src/Datetime/Datetime.php index ce33f03..b6817be 100644 --- a/src/Datetime/Datetime.php +++ b/src/Datetime/Datetime.php @@ -4,7 +4,7 @@ namespace HraDigital\Datatypes\Datetime; -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; use HraDigital\Datatypes\Traits\Datetime\Datetime\HasStaticFactoryMethodsTrait; /** @@ -87,7 +87,7 @@ public function offset(): int */ public function year(): int { - return (int) ((string) $this->toFormat(VoString::create('Y'))); + return (int) ((string) $this->toFormat(Str::create('Y'))); } /** @@ -97,7 +97,7 @@ public function year(): int */ public function month(): int { - return (int) ((string) $this->toFormat(VoString::create('m'))); + return (int) ((string) $this->toFormat(Str::create('m'))); } /** @@ -107,7 +107,7 @@ public function month(): int */ public function day(): int { - return (int) ((string) $this->toFormat(VoString::create('d'))); + return (int) ((string) $this->toFormat(Str::create('d'))); } /** @@ -117,7 +117,7 @@ public function day(): int */ public function hour(): int { - return (int) ((string) $this->toFormat(VoString::create('H'))); + return (int) ((string) $this->toFormat(Str::create('H'))); } /** @@ -127,7 +127,7 @@ public function hour(): int */ public function minute(): int { - return (int) ((string) $this->toFormat(VoString::create('i'))); + return (int) ((string) $this->toFormat(Str::create('i'))); } /** @@ -137,7 +137,7 @@ public function minute(): int */ public function second(): int { - return (int) ((string) $this->toFormat(VoString::create('s'))); + return (int) ((string) $this->toFormat(Str::create('s'))); } /** @@ -253,7 +253,7 @@ public function difference(Datetime $datetime, bool $absolute = false): DateInte ); return DateInterval::fromDuration( - VoString::create( + Str::create( \sprintf( 'P%dY%dM%dDT%dH%dM%dS', $dateInterval->y, @@ -282,170 +282,170 @@ public function endOfDay(): Datetime ); } - protected function toFormatInternal(string $format): VoString + protected function toFormatInternal(string $format): Str { - return VoString::create( + return Str::create( $this->dateTime->format($format) ); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * Returns Str instance with value in format "Y-m-d\TH:i:sP". * - * @return VoString + * @return Str */ - public function toATOM(): VoString + public function toATOM(): Str { return $this->toFormatInternal(\Datetime::ATOM); } /** - * Returns VoString instance with value in format "l, d-M-Y H:i:s T". + * Returns Str instance with value in format "l, d-M-Y H:i:s T". * - * @return VoString + * @return Str */ - public function toCookie(): VoString + public function toCookie(): Str { return $this->toFormatInternal(\Datetime::COOKIE); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:sO". + * Returns Str instance with value in format "Y-m-d\TH:i:sO". * - * @return VoString + * @return Str */ - public function toISO8601(): VoString + public function toISO8601(): Str { return $this->toFormatInternal(\Datetime::ISO8601); } /** - * Returns VoString instance with value in format "D, d M y H:i:s O". + * Returns Str instance with value in format "D, d M y H:i:s O". * - * @return VoString + * @return Str */ - public function toRFC822(): VoString + public function toRFC822(): Str { return $this->toFormatInternal(\Datetime::RFC822); } /** - * Returns VoString instance with value in format "l, d-M-y H:i:s T". + * Returns Str instance with value in format "l, d-M-y H:i:s T". * - * @return VoString + * @return Str */ - public function toRFC850(): VoString + public function toRFC850(): Str { return $this->toFormatInternal(\Datetime::RFC850); } /** - * Returns VoString instance with value in format "D, d M y H:i:s O". + * Returns Str instance with value in format "D, d M y H:i:s O". * - * @return VoString + * @return Str */ - public function toRFC1036(): VoString + public function toRFC1036(): Str { return $this->toFormatInternal(\Datetime::RFC1036); } /** - * Returns VoString instance with value in format "D, d M Y H:i:s O". + * Returns Str instance with value in format "D, d M Y H:i:s O". * - * @return VoString + * @return Str */ - public function toRFC1123(): VoString + public function toRFC1123(): Str { return $this->toFormatInternal(\Datetime::RFC1123); } /** - * Returns VoString instance with value in format "D, d M Y H:i:s \G\M\T". + * Returns Str instance with value in format "D, d M Y H:i:s \G\M\T". * - * @return VoString + * @return Str */ - public function toRFC7231(): VoString + public function toRFC7231(): Str { return $this->toFormatInternal(\Datetime::RFC7231); } /** - * Returns VoString instance with value in format "D, d M Y H:i:s O". + * Returns Str instance with value in format "D, d M Y H:i:s O". * - * @return VoString + * @return Str */ - public function toRFC2822(): VoString + public function toRFC2822(): Str { return $this->toFormatInternal(\Datetime::RFC2822); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * Returns Str instance with value in format "Y-m-d\TH:i:sP". * - * @return VoString + * @return Str */ - public function toRFC3339(): VoString + public function toRFC3339(): Str { return $this->toFormatInternal(\Datetime::RFC3339); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:s.vP". + * Returns Str instance with value in format "Y-m-d\TH:i:s.vP". * - * @return VoString + * @return Str */ - public function toRFC3339Extended(): VoString + public function toRFC3339Extended(): Str { return $this->toFormatInternal(\Datetime::RFC3339_EXTENDED); } /** - * Returns VoString instance with value in format "D, d M Y H:i:s O". + * Returns Str instance with value in format "D, d M Y H:i:s O". * - * @return VoString + * @return Str */ - public function toRSS(): VoString + public function toRSS(): Str { return $this->toFormatInternal(\Datetime::RSS); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * Returns Str instance with value in format "Y-m-d\TH:i:sP". * - * @return VoString + * @return Str */ - public function toW3C(): VoString + public function toW3C(): Str { return $this->toFormatInternal(\Datetime::W3C); } /** - * Returns VoString instance with value in format "Y-m-d H:i:s". + * Returns Str instance with value in format "Y-m-d H:i:s". * - * @return VoString + * @return Str */ - public function toDatetimeString(): VoString + public function toDatetimeString(): Str { return $this->toFormatInternal('Y-m-d H:i:s'); } /** - * Returns VoString instance with value in format "H:i:s". + * Returns Str instance with value in format "H:i:s". * - * @return VoString + * @return Str */ - public function toTimeString(): VoString + public function toTimeString(): Str { return $this->toFormatInternal('H:i:s'); } /** - * Returns VoString instance with value in specified format. + * Returns Str instance with value in specified format. * - * @param VoString $format - VoString instance containing desired Datetime format. - * @return VoString + * @param Str $format - Str instance containing desired Datetime format. + * @return Str */ - public function toFormat(VoString $format): VoString + public function toFormat(Str $format): Str { return $this->toFormatInternal((string) $format); } diff --git a/src/Datetime/DatetimeInheritance.php b/src/Datetime/DatetimeInheritance.php index af130d5..d127fbe 100644 --- a/src/Datetime/DatetimeInheritance.php +++ b/src/Datetime/DatetimeInheritance.php @@ -5,7 +5,7 @@ namespace HraDigital\Datatypes\Datetime; use DateTimeImmutable; -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; use HraDigital\Datatypes\Traits\Datetime\Datetime\HasStaticFactoryMethodsTrait; /** @@ -51,170 +51,170 @@ public function jsonSerialize(): string return (string) $this; } - protected function toFormatInternal(string $format): VoString + protected function toFormatInternal(string $format): Str { - return VoString::create( + return Str::create( $this->format($format) ); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * Returns Str instance with value in format "Y-m-d\TH:i:sP". * - * @return VoString + * @return Str */ - public function toATOM(): VoString + public function toATOM(): Str { return $this->toFormatInternal(\Datetime::ATOM); } /** - * Returns VoString instance with value in format "l, d-M-Y H:i:s T". + * Returns Str instance with value in format "l, d-M-Y H:i:s T". * - * @return VoString + * @return Str */ - public function toCookie(): VoString + public function toCookie(): Str { return $this->toFormatInternal(\Datetime::COOKIE); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:sO". + * Returns Str instance with value in format "Y-m-d\TH:i:sO". * - * @return VoString + * @return Str */ - public function toISO8601(): VoString + public function toISO8601(): Str { return $this->toFormatInternal(\Datetime::ISO8601); } /** - * Returns VoString instance with value in format "D, d M y H:i:s O". + * Returns Str instance with value in format "D, d M y H:i:s O". * - * @return VoString + * @return Str */ - public function toRFC822(): VoString + public function toRFC822(): Str { return $this->toFormatInternal(\Datetime::RFC822); } /** - * Returns VoString instance with value in format "l, d-M-y H:i:s T". + * Returns Str instance with value in format "l, d-M-y H:i:s T". * - * @return VoString + * @return Str */ - public function toRFC850(): VoString + public function toRFC850(): Str { return $this->toFormatInternal(\Datetime::RFC850); } /** - * Returns VoString instance with value in format "D, d M y H:i:s O". + * Returns Str instance with value in format "D, d M y H:i:s O". * - * @return VoString + * @return Str */ - public function toRFC1036(): VoString + public function toRFC1036(): Str { return $this->toFormatInternal(\Datetime::RFC1036); } /** - * Returns VoString instance with value in format "D, d M Y H:i:s O". + * Returns Str instance with value in format "D, d M Y H:i:s O". * - * @return VoString + * @return Str */ - public function toRFC1123(): VoString + public function toRFC1123(): Str { return $this->toFormatInternal(\Datetime::RFC1123); } /** - * Returns VoString instance with value in format "D, d M Y H:i:s \G\M\T". + * Returns Str instance with value in format "D, d M Y H:i:s \G\M\T". * - * @return VoString + * @return Str */ - public function toRFC7231(): VoString + public function toRFC7231(): Str { return $this->toFormatInternal(\Datetime::RFC7231); } /** - * Returns VoString instance with value in format "D, d M Y H:i:s O". + * Returns Str instance with value in format "D, d M Y H:i:s O". * - * @return VoString + * @return Str */ - public function toRFC2822(): VoString + public function toRFC2822(): Str { return $this->toFormatInternal(\Datetime::RFC2822); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * Returns Str instance with value in format "Y-m-d\TH:i:sP". * - * @return VoString + * @return Str */ - public function toRFC3339(): VoString + public function toRFC3339(): Str { return $this->toFormatInternal(\Datetime::RFC3339); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:s.vP". + * Returns Str instance with value in format "Y-m-d\TH:i:s.vP". * - * @return VoString + * @return Str */ - public function toRFC3339Extended(): VoString + public function toRFC3339Extended(): Str { return $this->toFormatInternal(\Datetime::RFC3339_EXTENDED); } /** - * Returns VoString instance with value in format "D, d M Y H:i:s O". + * Returns Str instance with value in format "D, d M Y H:i:s O". * - * @return VoString + * @return Str */ - public function toRSS(): VoString + public function toRSS(): Str { return $this->toFormatInternal(\Datetime::RSS); } /** - * Returns VoString instance with value in format "Y-m-d\TH:i:sP". + * Returns Str instance with value in format "Y-m-d\TH:i:sP". * - * @return VoString + * @return Str */ - public function toW3C(): VoString + public function toW3C(): Str { return $this->toFormatInternal(\Datetime::W3C); } /** - * Returns VoString instance with value in format "Y-m-d H:i:s". + * Returns Str instance with value in format "Y-m-d H:i:s". * - * @return VoString + * @return Str */ - public function toDatetimeString(): VoString + public function toDatetimeString(): Str { return $this->toFormatInternal('Y-m-d H:i:s'); } /** - * Returns VoString instance with value in format "H:i:s". + * Returns Str instance with value in format "H:i:s". * - * @return VoString + * @return Str */ - public function toTimeString(): VoString + public function toTimeString(): Str { return $this->toFormatInternal('H:i:s'); } /** - * Returns VoString instance with value in specified format. + * Returns Str instance with value in specified format. * - * @param VoString $format - VoString instance containing desired Datetime format. - * @return VoString + * @param Str $format - Str instance containing desired Datetime format. + * @return Str */ - public function toFormat(VoString $format): VoString + public function toFormat(Str $format): Str { return $this->toFormatInternal((string) $format); } diff --git a/src/Scalar/NString.php b/src/Scalar/NString.php index 4ca789d..1c484cd 100644 --- a/src/Scalar/NString.php +++ b/src/Scalar/NString.php @@ -32,13 +32,13 @@ public static function create(string $value): NString } /** - * Returns a VoString object, containing this instance's value. + * Returns a Str object, containing this instance's value. * - * @return VoString + * @return Str */ - public function toVoString(): VoString + public function toStr(): Str { - return VoString::create($this->value); + return Str::create($this->value); } /** diff --git a/src/Scalar/README.md b/src/Scalar/README.md index 794c169..a5e9550 100644 --- a/src/Scalar/README.md +++ b/src/Scalar/README.md @@ -1,43 +1,43 @@ # PHP Scalar Datatypes -Currently, this package supports only **Scalar Strings**. You can choose between `VoString` and `NString` string objects. +Currently, this package supports only **Scalar Strings**. You can choose between `Str` and `NString` string objects. **Scalar Strings** are wrapper objects around primitive `strings`, which encapsulate all string related funcionality into a single instance. -## VoString vs. NString +## Str vs. NString -`VoString` and `NString` string datatypes will have the exact same functionality, but will have different instance management. +`Str` and `NString` string datatypes will have the exact same functionality, but will have different instance management. Both types inherit commonly used `protected` functionality from parent `AbstractBaseString` class. Parent methods will map to native procedural string manipulation functions. Both types of classes implement `__toString()` method, which means you can directly print their result: ```php -// Example of a VoString. -$voString = VoString::create(" This Is A String "); +// Example of a Str. +$Str = Str::create(" This Is A String "); -echo $voString; // Prints ' This Is A String ' +echo $Str; // Prints ' This Is A String ' ``` Use **accessor** methods to retrieve any information from within the instance. **Mutators** methods will manipulate the value of the instance. Both classes are immutable Value Objects, which means that, they will always return a new instance of themselves when changing internal value, which should remain immutable in original instance. -Both `VoString` and `NString` instances have _fluent interfaces_, and therefore you can chain mutator methods, and make -several changes in the same line of code. The main difference between the two types, is that `VoString` instances will -force all mutator's interfaces/methods to always use other `VoString` as parameters, and never primitive `strings`. +Both `Str` and `NString` instances have _fluent interfaces_, and therefore you can chain mutator methods, and make +several changes in the same line of code. The main difference between the two types, is that `Str` instances will +force all mutator's interfaces/methods to always use other `Str` as parameters, and never primitive `strings`. Here are two examples: ```php -// Example of a VoString string. -$string1 = VoString::create(" This Is A String "); +// Example of a Str string. +$string1 = Str::create(" This Is A String "); // Overrite initial variable with returned instance. -// Notice that we use other VoString as parameters. -$search = VoString::create("This"); -$replace = VoString::create("That"); +// Notice that we use other Str as parameters. +$search = Str::create("This"); +$replace = Str::create("That"); $string1 = $string1->replace($search, $replace); // Perform operations on instance, and assign result to different variables. @@ -100,11 +100,11 @@ echo "{$string} has the value 'that is a great feature'"; You can easily import, use and manipulate primitive native data in the following way: ```php -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; // ... -$string = VoString::create(' This is the string I am trying to manipulate. '); +$string = Str::create(' This is the string I am trying to manipulate. '); ``` ### Class conversion @@ -115,13 +115,13 @@ You can also convert from one type of string to the other. // Originally creates an Instance of NString. $string = NString::create('This is originally a NString.') ->replace(' is ', ' was ') - ->toVoString(); + ->toStr(); -echo get_class($string); // Should echo \HraDigital\Datatypes\Scalar\VoString +echo get_class($string); // Should echo \HraDigital\Datatypes\Scalar\Str echo $string; // This was originally a NString. // Converts to original type. -$string = $string->replace(VoString::create(' was '), VoString::create(' is '))->toNString(); +$string = $string->replace(Str::create(' was '), Str::create(' is '))->toNString(); echo get_class($string); // Should echo \HraDigital\Datatypes\Scalar\NString echo $string; // This is originally a NString. diff --git a/src/Scalar/VoString.php b/src/Scalar/Str.php similarity index 73% rename from src/Scalar/VoString.php rename to src/Scalar/Str.php index 3cdbf73..cdd274b 100644 --- a/src/Scalar/VoString.php +++ b/src/Scalar/Str.php @@ -1,4 +1,6 @@ -value === $string); } @@ -59,12 +61,12 @@ public function equals(VoString $string): bool * * Returns TRUE if found. FALSE otherwise. * - * @param VoString $search - Non empty string to search for in the instance. + * @param Str $search - Non empty string to search for in the instance. * * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ - public function contains(VoString $search): bool + public function contains(Str $search): bool { return parent::doContains((string) $search); } @@ -78,14 +80,14 @@ public function contains(VoString $search): bool * * If the $search is not found inthe instance's value, NULL is returned. * - * @param VoString $search - String to search for in the instance. + * @param Str $search - String to search for in the instance. * @param int $start - Search offset start. Defaults to ZERO. * * @throws NonEmptyStringException - If $search value is an empty string. * @throws ParameterOutOfRangeException - If the $start is either too small, or too long. * @return int|null */ - public function indexOf(VoString $search, int $start = 0): ?int + public function indexOf(Str $search, int $start = 0): ?int { return parent::doIndexOf((string) $search, $start); } @@ -93,12 +95,12 @@ public function indexOf(VoString $search, int $start = 0): ?int /** * Checks if the instance's value starts with the supplied string. * - * @param VoString $search - Non empty string to search for in the instance. + * @param Str $search - Non empty string to search for in the instance. * * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ - public function startsWith(VoString $search): bool + public function startsWith(Str $search): bool { return parent::doStartsWith((string) $search); } @@ -106,12 +108,12 @@ public function startsWith(VoString $search): bool /** * Checks if the instance's value ends with the supplied string. * - * @param VoString $search - Non empty string to search for in the instance. + * @param Str $search - Non empty string to search for in the instance. * * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ - public function endsWith(VoString $search): bool + public function endsWith(Str $search): bool { return parent::doEndsWith((string) $search); } @@ -119,7 +121,7 @@ public function endsWith(VoString $search): bool /** * Counts the number of substring occurrences in the instance's value. * - * @param VoString $search - Non empty string to search for in the instance. + * @param Str $search - Non empty string to search for in the instance. * @param int $start - The sub-string's offset/start. * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. * @@ -127,7 +129,7 @@ public function endsWith(VoString $search): bool * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ - public function count(VoString $search, int $start = 0, ?int $length = null): int + public function count(Str $search, int $start = 0, ?int $length = null): int { return parent::doCount((string) $search, $start, $length); } @@ -135,11 +137,11 @@ public function count(VoString $search, int $start = 0, ?int $length = null): in /** * Trims instance's value on both ends. * - * @return VoString + * @return Str */ - public function trim(): VoString + public function trim(): Str { - return VoString::create( + return Str::create( parent::doTrim() ); } @@ -147,11 +149,11 @@ public function trim(): VoString /** * Trims instance's value only on the left. * - * @return VoString + * @return Str */ - public function trimLeft(): VoString + public function trimLeft(): Str { - return VoString::create( + return Str::create( parent::doTrimLeft() ); } @@ -159,11 +161,11 @@ public function trimLeft(): VoString /** * Trims instance's value only on the right. * - * @return VoString + * @return Str */ - public function trimRight(): VoString + public function trimRight(): Str { - return VoString::create( + return Str::create( parent::doTrimRight() ); } @@ -171,11 +173,11 @@ public function trimRight(): VoString /** * Converts the instance's value to Uppercase, and returns a new instance of the object. * - * @return VoString + * @return Str */ - public function toUpper(): VoString + public function toUpper(): Str { - return VoString::create( + return Str::create( parent::doToUpper() ); } @@ -184,11 +186,11 @@ public function toUpper(): VoString * Converts the instance's value first character to Uppercase, and returns a new instance * of the object. * - * @return VoString + * @return Str */ - public function toUpperFirst(): VoString + public function toUpperFirst(): Str { - return VoString::create( + return Str::create( parent::doToUpperFirst() ); } @@ -197,13 +199,13 @@ public function toUpperFirst(): VoString * Converts the instance's value first character of each word to Upper Case, and returns a new instance * of the object. * - * @param VoString|null $delimiters - The optional delimiters contains the word separator characters. + * @param Str|null $delimiters - The optional delimiters contains the word separator characters. * - * @return VoString + * @return Str */ - public function toUpperWords(?VoString $delimiters = null): VoString + public function toUpperWords(?Str $delimiters = null): Str { - return VoString::create( + return Str::create( parent::doToUpperWords($delimiters ?? " \t\r\n\f\v") ); } @@ -211,11 +213,11 @@ public function toUpperWords(?VoString $delimiters = null): VoString /** * Converts the instance's value to Lowercase, and returns a new instance of the object. * - * @return VoString + * @return Str */ - public function toLower(): VoString + public function toLower(): Str { - return VoString::create( + return Str::create( parent::doToLower() ); } @@ -224,11 +226,11 @@ public function toLower(): VoString * Converts the instance's value first character to Lowercase, and returns a new instance * of the object * - * @return VoString + * @return Str */ - public function toLowerFirst(): VoString + public function toLowerFirst(): Str { - return VoString::create( + return Str::create( parent::doToLowerFirst() ); } @@ -244,20 +246,20 @@ public function toLowerFirst(): VoString * it is padded with characters from $padding up to the limit. * * @param int $length - Length of the padded value. - * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters + * @param Str|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * * @throws NonEmptyStringException - If supplied $padding is empty. * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return VoString + * @return Str */ - public function padLeft(int $length, ?VoString $padding = null): VoString + public function padLeft(int $length, ?Str $padding = null): Str { if ($padding === null) { - $padding = VoString::create(" "); + $padding = Str::create(" "); } - return VoString::create( + return Str::create( parent::doPadLeft($length, ((string) $padding ?? " ")) ); } @@ -269,20 +271,20 @@ public function padLeft(int $length, ?VoString $padding = null): VoString * it is padded with characters from $padding up to the limit. * * @param int $length - Length of the padded value. - * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters + * @param Str|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * * @throws NonEmptyStringException - If supplied $padding is empty. * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return VoString + * @return Str */ - public function padLeftExtra(int $length, ?VoString $padding = null): VoString + public function padLeftExtra(int $length, ?Str $padding = null): Str { if ($padding === null) { - $padding = VoString::create(" "); + $padding = Str::create(" "); } - return VoString::create( + return Str::create( parent::doPadLeftExtra($length, ((string) $padding ?? " ")) ); } @@ -298,20 +300,20 @@ public function padLeftExtra(int $length, ?VoString $padding = null): VoString * it is padded with characters from $padding up to the limit. * * @param int $length - Length of the padded value. - * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters + * @param Str|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * * @throws NonEmptyStringException - If supplied $padding is empty. * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return VoString + * @return Str */ - public function padRight(int $length, ?VoString $padding = null): VoString + public function padRight(int $length, ?Str $padding = null): Str { if ($padding === null) { - $padding = VoString::create(" "); + $padding = Str::create(" "); } - return VoString::create( + return Str::create( parent::doPadRight($length, ((string) $padding ?? " ")) ); } @@ -323,20 +325,20 @@ public function padRight(int $length, ?VoString $padding = null): VoString * it is padded with characters from $padding up to the limit. * * @param int $length - Length of the padded value. - * @param VoString|null $padding - The pad_string may be truncated if the required number of padding characters + * @param Str|null $padding - The pad_string may be truncated if the required number of padding characters * can't be evenly divided by the $padding's length. * * @throws NonEmptyStringException - If supplied $padding is empty. * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return VoString + * @return Str */ - public function padRightExtra(int $length, ?VoString $padding = null): VoString + public function padRightExtra(int $length, ?Str $padding = null): Str { if ($padding === null) { - $padding = VoString::create(" "); + $padding = Str::create(" "); } - return VoString::create( + return Str::create( parent::doPadRightExtra($length, ((string) $padding ?? " ")) ); } @@ -367,11 +369,11 @@ public function padRightExtra(int $length, ?VoString $padding = null): VoString * @param int $length - Length of the sub-string. Can be negative. * * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return VoString + * @return Str */ - public function subString(int $start, int $length = null): VoString + public function subString(int $start, int $length = null): Str { - return VoString::create( + return Str::create( parent::doSubString($start, $length) ); } @@ -383,11 +385,11 @@ public function subString(int $start, int $length = null): VoString * @param int $length - Length of the sub-string. Must be positive. * * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. - * @return VoString + * @return Str */ - public function subLeft(int $length): VoString + public function subLeft(int $length): Str { - return VoString::create( + return Str::create( parent::doSubLeft($length) ); } @@ -399,11 +401,11 @@ public function subLeft(int $length): VoString * @param int $length - Length of the sub-string. Must be positive. * * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. - * @return VoString + * @return Str */ - public function subRight(int $length): VoString + public function subRight(int $length): Str { - return VoString::create( + return Str::create( parent::doSubRight($length) ); } @@ -411,11 +413,11 @@ public function subRight(int $length): VoString /** * This method returns the reversed value of the instance. * - * @return VoString + * @return Str */ - public function reverse(): VoString + public function reverse(): Str { - return VoString::create( + return Str::create( parent::doReverse() ); } @@ -423,15 +425,15 @@ public function reverse(): VoString /** * This method replaces a string's occurance by another, and returns a new instance with the new value. * - * @param VoString $search - The string to search for. - * @param VoString $replace - The search's replacement. + * @param Str $search - The string to search for. + * @param Str $replace - The search's replacement. * * @throws NonEmptyStringException - If either $search or $replace are empty. - * @return VoString + * @return Str */ - public function replace(VoString $search, VoString $replace): VoString + public function replace(Str $search, Str $replace): Str { - return VoString::create( + return Str::create( parent::doReplace((string) $search, (string) $replace) ); } diff --git a/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php b/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php index 8e73690..0a0eb49 100644 --- a/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php +++ b/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php @@ -5,7 +5,7 @@ namespace HraDigital\Datatypes\Traits\Entities\General; use HraDigital\Datatypes\Datetime\Datetime; -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; /** * Trait for an Updatable Record UpdatedAt attribute. diff --git a/src/Traits/Entities/Location/HasCountryCodeTrait.php b/src/Traits/Entities/Location/HasCountryCodeTrait.php index 73602ee..d2bda00 100644 --- a/src/Traits/Entities/Location/HasCountryCodeTrait.php +++ b/src/Traits/Entities/Location/HasCountryCodeTrait.php @@ -4,7 +4,7 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; /** * Trait for an Entity's Country Code attribute. @@ -15,8 +15,8 @@ */ trait HasCountryCodeTrait { - /** @var VoString $countryCode - Country Code */ - protected VoString $country_code; + /** @var Str $countryCode - Country Code */ + protected Str $country_code; /** * Mutator method for setting the value into the Attribute. @@ -26,15 +26,15 @@ trait HasCountryCodeTrait */ protected function castCountryCode(string $countryCode): void { - $this->country_code = VoString::create($countryCode); + $this->country_code = Str::create($countryCode); } /** * Returns the Entity's Country Code. * - * @return VoString + * @return Str */ - public function getCountryCode(): VoString + public function getCountryCode(): Str { return $this->country_code; } diff --git a/src/ValueObjects/README.md b/src/ValueObjects/README.md index 15e4780..eff9dab 100755 --- a/src/ValueObjects/README.md +++ b/src/ValueObjects/README.md @@ -36,8 +36,8 @@ If we're talking about a Database as a **persistence layer**, and a given datata ```php class MyValueObject extends AbstractValueObject { - protected VoString $name; - protected VoString $surname; + protected Str $name; + protected Str $surname; protected Datetime $date_of_birth; } ``` @@ -97,8 +97,8 @@ protected $maps = [ ```php class Person extends AbstractvalueObject { - protected VoString $name; - protected VoString $surname; + protected Str $name; + protected Str $surname; protected array $required = ['name', 'surname']; } @@ -113,12 +113,12 @@ class Person extends AbstractValueObject protected function castName(string $name): void { - $this->name = VoString::create($name)->trim(); + $this->name = Str::create($name)->trim(); } protected function castSurname(string $surname): void { - $this->surname = VoString::create($surname)->trim(); + $this->surname = Str::create($surname)->trim(); } } ``` @@ -130,12 +130,12 @@ class Person extends AbstractValueObject { // ... Previous content. - public function name(): VoString + public function name(): Str { return $this->name; } - public function surname(): VoString + public function surname(): Str { return $this->surname; } diff --git a/src/ValueObjects/Timezone/Location.php b/src/ValueObjects/Timezone/Location.php index a0c9570..d975c8e 100644 --- a/src/ValueObjects/Timezone/Location.php +++ b/src/ValueObjects/Timezone/Location.php @@ -2,7 +2,7 @@ namespace HraDigital\Datatypes\ValueObjects\Timezone; -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; use HraDigital\Datatypes\Traits\Entities\Location\HasCountryCodeTrait; use HraDigital\Datatypes\Traits\Entities\Location\HasLatitudeTrait; use HraDigital\Datatypes\Traits\Entities\Location\HasLongitudeTrait; @@ -22,7 +22,7 @@ class Location extends AbstractValueObject HasLatitudeTrait, HasLongitudeTrait; - protected ?VoString $comments = null; + protected ?Str $comments = null; /** @inheritDoc */ protected array $required = [ @@ -33,10 +33,10 @@ class Location extends AbstractValueObject protected function castComments(?string $comments): void { - $this->comments = ($comments ? VoString::create($comments) : null); + $this->comments = ($comments ? Str::create($comments) : null); } - public function comments(): ?VoString + public function comments(): ?Str { return $this->comments; } diff --git a/src/ValueObjects/Timezone/Transition.php b/src/ValueObjects/Timezone/Transition.php index f1f1924..3f2dc56 100644 --- a/src/ValueObjects/Timezone/Transition.php +++ b/src/ValueObjects/Timezone/Transition.php @@ -5,7 +5,7 @@ namespace HraDigital\Datatypes\ValueObjects\Timezone; use HraDigital\Datatypes\Datetime\Datetime; -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; use HraDigital\Datatypes\Traits\Entities\Timezone\HasTimestampTrait; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; @@ -24,7 +24,7 @@ class Transition extends AbstractValueObject protected Datetime $dateTime; protected int $offset; protected bool $isDayLightSavingActive; - protected VoString $abbreviation; + protected Str $abbreviation; /** @inheritDoc */ protected array $required = [ @@ -61,7 +61,7 @@ protected function castIsDayLightSavingActive(int $isActive): void protected function castAbbreviation(string $abbreviation): void { - $this->abbreviation = VoString::create($abbreviation); + $this->abbreviation = Str::create($abbreviation); } public function dateTime(): Datetime @@ -79,7 +79,7 @@ public function isDayLightSavingActive(): bool return $this->isDayLightSavingActive; } - public function abbreviation(): VoString + public function abbreviation(): Str { return $this->abbreviation; } diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 0b5e33e..a77cea3 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -6,7 +6,7 @@ use HraDigital\Datatypes\Exceptions\Datatypes\InvalidEmailException; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; -use HraDigital\Datatypes\Scalar\VoString; +use HraDigital\Datatypes\Scalar\Str; /** * E-mail address datatype. @@ -20,14 +20,14 @@ */ class EmailAddress implements \Serializable { - /** @var VoString $username - Holds the Username's part of the E-mail address. */ - protected VoString $username; + /** @var Str $username - Holds the Username's part of the E-mail address. */ + protected Str $username; - /** @var VoString $domain - Holds the Domain part of the E-mail address. */ - protected VoString $domain; + /** @var Str $domain - Holds the Domain part of the E-mail address. */ + protected Str $domain; - /** @var VoString $tld - Holds the Top Level Domain part of the E-mail address. */ - protected VoString $tld; + /** @var Str $tld - Holds the Top Level Domain part of the E-mail address. */ + protected Str $tld; /** * Loads a new EmailAddress instance from a native string. @@ -63,8 +63,8 @@ protected function __construct(string $email) */ protected function loadFromPrimitive(string $email): void { - // Converts supplied primitive to VoString. - $voEmail = VoString::create($email)->trim()->toLower(); + // Converts supplied primitive to Str. + $voEmail = Str::create($email)->trim()->toLower(); // Validate supplied parameter. if ($voEmail->length() === 0) { @@ -76,12 +76,12 @@ protected function loadFromPrimitive(string $email): void // Sanitizes and processes supplied e-mail address. $parts = \explode('@', (string) $voEmail); - $this->username = VoString::create($parts[0]); + $this->username = Str::create($parts[0]); // Processes the right side of the e-mail address. $domain = \explode('.', $parts[1]); - $this->tld = VoString::create(\array_pop($domain)); - $this->domain = VoString::create(\implode('.', $domain)); + $this->tld = Str::create(\array_pop($domain)); + $this->domain = Str::create(\implode('.', $domain)); } /** @@ -121,9 +121,9 @@ public function __toString(): string * * @return string */ - public function address(): VoString + public function address(): Str { - return VoString::create( + return Str::create( \sprintf( "%s@%s.%s", (string) $this->username, @@ -138,7 +138,7 @@ public function address(): VoString * * @return string */ - public function username(): VoString + public function username(): Str { return $this->username; } @@ -148,7 +148,7 @@ public function username(): VoString * * @return string */ - public function domain(): VoString + public function domain(): Str { return $this->domain; } @@ -158,7 +158,7 @@ public function domain(): VoString * * @return string */ - public function tld(): VoString + public function tld(): Str { return $this->tld; } From 27d067aefee36438efed110e2932c7ce2d437951 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 12:04:37 +0000 Subject: [PATCH 069/193] Add get prefix to accessors --- src/Scalar/AbstractBaseString.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 7a76e16..095b65a 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -1,4 +1,6 @@ -value); } @@ -61,7 +63,7 @@ public function length(): int * * @return int */ - public function wordCount(): int + public function getWordCount(): int { return \str_word_count($this->value); } From 1d909415c53f8b0b6876589e25581b01db76871b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 12:04:47 +0000 Subject: [PATCH 070/193] Remove conversion method --- src/Scalar/Str.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Scalar/Str.php b/src/Scalar/Str.php index cdd274b..b232219 100644 --- a/src/Scalar/Str.php +++ b/src/Scalar/Str.php @@ -33,16 +33,6 @@ public static function create(string $value): Str return new Str($value); } - /** - * Returns a NString object, containing this instance's value. - * - * @return NString - */ - public function toNString(): NString - { - return NString::create($this->value); - } - /** * Compares the values of 2 separate instances. * From 21251d1f297d60478390a7974f232f625ee8b626 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 12:05:10 +0000 Subject: [PATCH 071/193] Minor code cleanup --- src/Datetime/DatetimeInheritance.php | 1 - src/ValueObjects/Timezone/Location.php | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Datetime/DatetimeInheritance.php b/src/Datetime/DatetimeInheritance.php index d127fbe..00a53bc 100644 --- a/src/Datetime/DatetimeInheritance.php +++ b/src/Datetime/DatetimeInheritance.php @@ -6,7 +6,6 @@ use DateTimeImmutable; use HraDigital\Datatypes\Scalar\Str; -use HraDigital\Datatypes\Traits\Datetime\Datetime\HasStaticFactoryMethodsTrait; /** * Datetime utility class. diff --git a/src/ValueObjects/Timezone/Location.php b/src/ValueObjects/Timezone/Location.php index d975c8e..43d594b 100644 --- a/src/ValueObjects/Timezone/Location.php +++ b/src/ValueObjects/Timezone/Location.php @@ -1,4 +1,6 @@ - Date: Tue, 9 Nov 2021 12:45:08 +0000 Subject: [PATCH 072/193] Add get prefix to accessors --- src/Datetime/Datetime.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Datetime/Datetime.php b/src/Datetime/Datetime.php index b6817be..0ce400e 100644 --- a/src/Datetime/Datetime.php +++ b/src/Datetime/Datetime.php @@ -65,7 +65,7 @@ public function jsonSerialize(): string * * @return int */ - public function timestamp(): int + public function getTimestamp(): int { return $this->dateTime->getTimestamp(); } @@ -75,7 +75,7 @@ public function timestamp(): int * * @return int */ - public function offset(): int + public function getOffset(): int { return $this->dateTime->getOffset(); } @@ -85,7 +85,7 @@ public function offset(): int * * @return int */ - public function year(): int + public function getYear(): int { return (int) ((string) $this->toFormat(Str::create('Y'))); } @@ -95,7 +95,7 @@ public function year(): int * * @return int */ - public function month(): int + public function getMonth(): int { return (int) ((string) $this->toFormat(Str::create('m'))); } @@ -105,7 +105,7 @@ public function month(): int * * @return int */ - public function day(): int + public function getDay(): int { return (int) ((string) $this->toFormat(Str::create('d'))); } @@ -115,7 +115,7 @@ public function day(): int * * @return int */ - public function hour(): int + public function getHour(): int { return (int) ((string) $this->toFormat(Str::create('H'))); } @@ -125,7 +125,7 @@ public function hour(): int * * @return int */ - public function minute(): int + public function getMinute(): int { return (int) ((string) $this->toFormat(Str::create('i'))); } @@ -135,7 +135,7 @@ public function minute(): int * * @return int */ - public function second(): int + public function getSecond(): int { return (int) ((string) $this->toFormat(Str::create('s'))); } @@ -268,14 +268,14 @@ public function difference(Datetime $datetime, bool $absolute = false): DateInte ); } - public function startOfDay(): Datetime + public function getStartOfDay(): Datetime { return new Datetime( $this->dateTime->format('Y-m-d 00:00:00') ); } - public function endOfDay(): Datetime + public function getEndOfDay(): Datetime { return new Datetime( $this->dateTime->format('Y-m-d 23:59:59') From 3a308923c1a4a105182040ae227a4b49b217187b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 12:46:17 +0000 Subject: [PATCH 073/193] Refactor replace() method --- src/Scalar/Str.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Scalar/Str.php b/src/Scalar/Str.php index b232219..4c0d742 100644 --- a/src/Scalar/Str.php +++ b/src/Scalar/Str.php @@ -415,13 +415,13 @@ public function reverse(): Str /** * This method replaces a string's occurance by another, and returns a new instance with the new value. * - * @param Str $search - The string to search for. - * @param Str $replace - The search's replacement. + * @param string $search - The string to search for. + * @param string $replace - The search's replacement. * * @throws NonEmptyStringException - If either $search or $replace are empty. * @return Str */ - public function replace(Str $search, Str $replace): Str + public function replace(string $search, string $replace): Str { return Str::create( parent::doReplace((string) $search, (string) $replace) From 572ee55477b4f3fdb3aa008c302cca100fc73e1b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 12:46:33 +0000 Subject: [PATCH 074/193] Clean up static factory method --- src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php b/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php index 6205126..0cbb9bb 100644 --- a/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php +++ b/src/Traits/Datetime/Datetime/HasStaticFactoryMethodsTrait.php @@ -31,7 +31,7 @@ public static function yesterday(): Datetime public static function fromString(?string $datetime = null, ?DateTimeZone $timezone = null): Datetime { - return new Datetime((string) $datetime ?? "now", $timezone); + return new Datetime($datetime ?? "now", $timezone); } public static function fromTimestamp(int $timestamp): Datetime From acf29a00bea5e7134a093054a326db68b69eb8c0 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 12:46:54 +0000 Subject: [PATCH 075/193] Convert all string primitive into Str ValueObject --- src/Traits/Entities/General/HasAliasTrait.php | 16 +++--- .../Entities/General/HasDeletedAtTrait.php | 2 +- .../Entities/General/HasFeatureTrait.php | 4 +- src/Traits/Entities/General/HasHitsTrait.php | 2 +- src/Traits/Entities/General/HasNameTrait.php | 12 ++-- .../Entities/General/HasOrderingTrait.php | 2 +- .../Entities/General/HasPasswordTrait.php | 12 ++-- .../General/HasPositiveIntegerIDTrait.php | 2 +- .../Entities/General/HasSeoFieldsTrait.php | 55 +++++++++++-------- .../General/HasUpdatableUpdatedAtTrait.php | 1 - src/Traits/Entities/General/HasUuidTrait.php | 12 ++-- .../Entities/Location/HasAddressTrait.php | 12 ++-- src/Traits/Entities/Location/HasCityTrait.php | 12 ++-- .../Entities/Location/HasCountryTrait.php | 12 ++-- .../Entities/Location/HasPostalCodeTrait.php | 12 ++-- .../Location/HasStreetAdditionalTrait.php | 12 ++-- .../Location/HasStreetNumberTrait.php | 12 ++-- .../Entities/Location/HasStreetTrait.php | 12 ++-- .../Personal/HasCountryOfBirthTrait.php | 19 ++++--- .../Entities/Personal/HasGenderTrait.php | 16 +++--- .../Entities/Personal/HasPhotoTrait.php | 15 +++-- .../Entities/Personal/HasSurnameTrait.php | 15 +++-- .../Professional/HasOccupationTrait.php | 15 +++-- .../SocialMedia/HasFacebookProfileTrait.php | 12 ++-- .../SocialMedia/HasInstagramProfileTrait.php | 12 ++-- .../SocialMedia/HasLinkedinProfileTrait.php | 12 ++-- .../SocialMedia/HasTwitterProfileTrait.php | 12 ++-- 27 files changed, 190 insertions(+), 142 deletions(-) diff --git a/src/Traits/Entities/General/HasAliasTrait.php b/src/Traits/Entities/General/HasAliasTrait.php index 0f19feb..b604044 100755 --- a/src/Traits/Entities/General/HasAliasTrait.php +++ b/src/Traits/Entities/General/HasAliasTrait.php @@ -5,6 +5,7 @@ namespace HraDigital\Datatypes\Traits\Entities\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Scalar\Str; /** * Gives Alias information capabilities to an Entity/Value Object. @@ -15,8 +16,8 @@ */ trait HasAliasTrait { - /** @var string $alias - Instances's Alias. */ - protected string $alias = ''; + /** @var Str $alias - Instances's Alias. */ + protected Str $alias = Str::create(''); /** * Setter method for alias. @@ -29,25 +30,24 @@ trait HasAliasTrait protected function castAlias(string $alias): void { // Sanitizes supplied parameter. - $alias = \strtolower(\trim($alias)); - $alias = \str_replace(' ', '_', $alias); + $aliasValue = Str::create($alias)->trim()->toLower()->replace(' ', '_'); // Validates if alias is filled. - if (\strlen($alias) === 0) { + if ($aliasValue->getLength() === 0) { throw new NonEmptyStringException('$alias'); } // We'll set the alias value on the attribute, but use the sanitizeAlias() method // to sanitize its value. - $this->alias = $alias; + $this->alias = $aliasValue; } /** * Returns the Entity's alias. * - * @return string + * @return Str */ - public function getAlias(): string + public function getAlias(): Str { return $this->alias; } diff --git a/src/Traits/Entities/General/HasDeletedAtTrait.php b/src/Traits/Entities/General/HasDeletedAtTrait.php index 81cf130..b147f24 100644 --- a/src/Traits/Entities/General/HasDeletedAtTrait.php +++ b/src/Traits/Entities/General/HasDeletedAtTrait.php @@ -44,7 +44,7 @@ public function getDeletedAt(): ?Datetime /** * Returns TRUE if the record is marked as deleted in the system. * - * @return boolean + * @return bool */ public function isDeleted(): bool { diff --git a/src/Traits/Entities/General/HasFeatureTrait.php b/src/Traits/Entities/General/HasFeatureTrait.php index e2d823f..3112c6b 100755 --- a/src/Traits/Entities/General/HasFeatureTrait.php +++ b/src/Traits/Entities/General/HasFeatureTrait.php @@ -24,7 +24,7 @@ trait HasFeatureTrait */ protected function castFeatured(bool $featured): void { - $this->featured = $featured; + $this->is_featured = $featured; } /** @@ -34,6 +34,6 @@ protected function castFeatured(bool $featured): void */ public function isFeatured(): bool { - return $this->featured; + return $this->is_featured; } } diff --git a/src/Traits/Entities/General/HasHitsTrait.php b/src/Traits/Entities/General/HasHitsTrait.php index b30211c..40f80bf 100755 --- a/src/Traits/Entities/General/HasHitsTrait.php +++ b/src/Traits/Entities/General/HasHitsTrait.php @@ -30,7 +30,7 @@ protected function castHits(int $hits): void { // Validates supplied $hits value. if ($hits < 0) { - throw new NonNegativeNumberException("Supplid hits counter cannot be a negative integer."); + throw new NonNegativeNumberException('$hits'); } // Sets value in class' attribute. diff --git a/src/Traits/Entities/General/HasNameTrait.php b/src/Traits/Entities/General/HasNameTrait.php index 467e780..2a13194 100755 --- a/src/Traits/Entities/General/HasNameTrait.php +++ b/src/Traits/Entities/General/HasNameTrait.php @@ -5,6 +5,7 @@ namespace HraDigital\Datatypes\Traits\Entities\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Scalar\Str; /** * Gives Name information capabilities to an Entity/Value Object. @@ -15,8 +16,8 @@ */ trait HasNameTrait { - /** @var string $name - Instance's Name. */ - protected string $name = ''; + /** @var Str $name - Instance's Name. */ + protected Str $name = Str::create(''); /** * Setter method for name. @@ -29,7 +30,8 @@ trait HasNameTrait protected function castName(string $name): void { // Validates supplied parameter. - if (\strlen(\trim($name)) === 0) { + $nameValue = Str::create($name)->trim(); + if ($nameValue->getLength() === 0) { throw new NonEmptyStringException('$name'); } @@ -39,9 +41,9 @@ protected function castName(string $name): void /** * Returns the Instance's name. * - * @return string + * @return Str */ - public function getName(): string + public function getName(): Str { return $this->name; } diff --git a/src/Traits/Entities/General/HasOrderingTrait.php b/src/Traits/Entities/General/HasOrderingTrait.php index 066113c..d2353cc 100755 --- a/src/Traits/Entities/General/HasOrderingTrait.php +++ b/src/Traits/Entities/General/HasOrderingTrait.php @@ -30,7 +30,7 @@ protected function castOrdering(int $order): void { // Validates supplied parameter. if ($order < 0) { - throw new NonNegativeNumberException("Supplied Order must be a non negative integer."); + throw new NonNegativeNumberException('$ordering'); } // Sets the value in the class. diff --git a/src/Traits/Entities/General/HasPasswordTrait.php b/src/Traits/Entities/General/HasPasswordTrait.php index f8ea376..8d7c03b 100755 --- a/src/Traits/Entities/General/HasPasswordTrait.php +++ b/src/Traits/Entities/General/HasPasswordTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\General; +use HraDigital\Datatypes\Scalar\Str; + /** * Gives Password capabilities to an Entity/Value Object. * @@ -13,8 +15,8 @@ */ trait HasPasswordTrait { - /** @var string|null $password - Record's password value. */ - protected ?string $password = null; + /** @var Str|null $password - Record's password value. */ + protected ?Str $password = null; /** * Sets the password value of an Entity/Value Object. @@ -24,15 +26,15 @@ trait HasPasswordTrait */ protected function castPassword(string $password): void { - $this->password = $password; + $this->password = ($password ? Str::create($password) : null); } /** * Returns record's Password value. * - * @return string + * @return Str|null */ - public function getPassword(): string + public function getPassword(): ?Str { return $this->password; } diff --git a/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php b/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php index d1fcc0c..9217731 100644 --- a/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php +++ b/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php @@ -27,7 +27,7 @@ trait HasPositiveIntegerIDTrait protected function castId(int $id): void { if ($id < 1) { - throw new PositiveIntegerException('id'); + throw new PositiveIntegerException('$id'); } $this->id = $id; diff --git a/src/Traits/Entities/General/HasSeoFieldsTrait.php b/src/Traits/Entities/General/HasSeoFieldsTrait.php index 9308649..7bf52ee 100755 --- a/src/Traits/Entities/General/HasSeoFieldsTrait.php +++ b/src/Traits/Entities/General/HasSeoFieldsTrait.php @@ -6,6 +6,7 @@ use HraDigital\Datatypes\Exceptions\Datatypes\InvalidStringLengthException; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Scalar\Str; /** * Gives Seo Title, Seo Description and Seo Keywords information capabilities to an Entity/Value Object. @@ -16,14 +17,14 @@ */ trait HasSeoFieldsTrait { - /** @var string|null $seo_title - Record's Seo title option. */ - protected ?string $seo_title = null; + /** @var Str|null $seo_title - Record's Seo title option. */ + protected ?Str $seo_title = null; - /** @var string|null $seo_description - Record's Seo description option. */ - protected ?string $seo_description = null; + /** @var Str|null $seo_description - Record's Seo description option. */ + protected ?Str $seo_description = null; - /** @var string|null $seo_keywords - Record's Seo keywords option. */ - protected ?string $seo_keywords = null; + /** @var Str|null $seo_keywords - Record's Seo keywords option. */ + protected ?Str $seo_keywords = null; /** * Checking the character limitations of the . @@ -39,11 +40,13 @@ trait HasSeoFieldsTrait protected function castSeoTitle(?string $title = null): void { // Setting the max length for Seo description. - if ($title !== null && \strlen(\trim($title)) > 70) { + $titleValue = ($title ? Str::create($title)->trim() ? null); + + if ($titleValue !== null && $titleValue->getLength() > 70) { throw new NonEmptyStringException("Supplied Seo title must have length up to 70 characters."); } - $this->seo_title = $this->seoSanitize($title); + $this->seo_title = $this->seoSanitize($titleValue); } /** @@ -60,11 +63,13 @@ protected function castSeoTitle(?string $title = null): void protected function castSeoDescription(?string $description = null): void { // Setting the max length for Seo description. - if ($description !== null && \strlen(\trim($description)) > 160) { + $descriptionValue = ($description ? Str::create($description) : null); + + if ($descriptionValue !== null && $descriptionValue->trim()->getLength() > 160) { throw new NonEmptyStringException("Supplied Seo description must have length up to 160 characters."); } - $this->seo_description = $this->seoSanitize($description); + $this->seo_description = $this->seoSanitize($descriptionValue); } /** @@ -81,22 +86,24 @@ protected function castSeoDescription(?string $description = null): void protected function castSeoKeywords(string $keywords = null): void { // Setting the max length for Seo keywords. - if ($keywords !== null && \strlen(\trim($keywords)) > 255) { + $keywordsValue = ($keywords ? Str::create($keywords) : null); + + if ($keywordsValue !== null && $keywordsValue->trim()->getLength() > 255) { throw new NonEmptyStringException("Supplied Seo keywords must have length up to 255 characters."); } - $this->seo_keywords = $this->seoSanitize($keywords); + $this->seo_keywords = $this->seoSanitize($keywordsValue); } /** * Returns the Entity's seo title. * - * @return string|null + * @return Str|null */ - public function getSeoTitle(): ?string + public function getSeoTitle(): ?Str { // If the Seo title is not set it is set to name property. - if ($this->seo_title === null || \strlen(\trim($this->seo_title)) === 0) { + if ($this->seo_title === null || $this->seo_title->trim()->getLength() === 0) { return ( \property_exists($this, 'name') ? $this->{'name'} : null ); } @@ -106,9 +113,9 @@ public function getSeoTitle(): ?string /** * Returns the Entity's seo description. * - * @return string|null + * @return Str|null */ - public function getSeoDescription(): ?string + public function getSeoDescription(): ?Str { return $this->seo_description; } @@ -116,9 +123,9 @@ public function getSeoDescription(): ?string /** * Returns the Entity's seo keywords. * - * @return string|null + * @return Str|null */ - public function getSeoKeywords(): ?string + public function getSeoKeywords(): ?Str { return $this->seo_keywords; } @@ -126,19 +133,19 @@ public function getSeoKeywords(): ?string /** * Sanitizes the individual Seo field in the Entity. * - * @param string|null $seoField - New Hit's value. - * @return string|null + * @param Str|null $seoField - New Hit's value. + * @return Str|null */ - private function seoSanitize(?string $seoField = null): ?string + private function seoSanitize(?Str $seoField = null): ?Str { // Checking if the value is an empty string or a string made of spaces. - if ($seoField !== null && \strlen(\trim($seoField)) === 0) { + if ($seoField !== null && $seoField->trim()->getLength() === 0) { $seoField = null; } // If there is a valid string trimming the spaces form the beginning and the end. if ($seoField !== null) { - $seoField = \trim($seoField); + $seoField = $seoField->trim(); } return $seoField; diff --git a/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php b/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php index 0a0eb49..0611d8c 100644 --- a/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php +++ b/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php @@ -5,7 +5,6 @@ namespace HraDigital\Datatypes\Traits\Entities\General; use HraDigital\Datatypes\Datetime\Datetime; -use HraDigital\Datatypes\Scalar\Str; /** * Trait for an Updatable Record UpdatedAt attribute. diff --git a/src/Traits/Entities/General/HasUuidTrait.php b/src/Traits/Entities/General/HasUuidTrait.php index 952f17d..cdf858c 100644 --- a/src/Traits/Entities/General/HasUuidTrait.php +++ b/src/Traits/Entities/General/HasUuidTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\General; +use HraDigital\Datatypes\Scalar\Str; + /** * Trait for a Record's UUID (Universal Unique Identifier) attribute. * @@ -13,8 +15,8 @@ */ trait HasUuidTrait { - /** @var string $uuid - Universal Unique Identifier */ - protected string $uuid; + /** @var Str $uuid - Universal Unique Identifier */ + protected Str $uuid; /** * Mutator method for setting the value into the Attribute. @@ -24,15 +26,15 @@ trait HasUuidTrait */ protected function castUuid(string $uuid): void { - $this->uuid = $uuid; + $this->uuid = Str::create($uuid); } /** * Returns the Universal Unique Identifier. * - * @return string + * @return Str */ - public function getUuid(): string + public function getUuid(): Str { return $this->uuid; } diff --git a/src/Traits/Entities/Location/HasAddressTrait.php b/src/Traits/Entities/Location/HasAddressTrait.php index df1786e..d117a6d 100644 --- a/src/Traits/Entities/Location/HasAddressTrait.php +++ b/src/Traits/Entities/Location/HasAddressTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; +use HraDigital\Datatypes\Scalar\Str; + /** * Trait for an Entity's Address attribute. * @@ -13,8 +15,8 @@ */ trait HasAddressTrait { - /** @var string $address - Address */ - protected string $address = ''; + /** @var Str $address - Address */ + protected Str $address = Str::create(''); /** * Mutator method for setting the value into the Attribute. @@ -24,15 +26,15 @@ trait HasAddressTrait */ protected function castAddress(string $address): void { - $this->address = \trim($address); + $this->address = Str::create($address)->trim(); } /** * Returns the Entity's Address. * - * @return string + * @return Str */ - public function getAddress(): string + public function getAddress(): Str { return $this->address; } diff --git a/src/Traits/Entities/Location/HasCityTrait.php b/src/Traits/Entities/Location/HasCityTrait.php index 6b1df33..b8d2e2a 100644 --- a/src/Traits/Entities/Location/HasCityTrait.php +++ b/src/Traits/Entities/Location/HasCityTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; +use HraDigital\Datatypes\Scalar\Str; + /** * Trait for an Entity's City attribute. * @@ -13,8 +15,8 @@ */ trait HasCityTrait { - /** @var string $city - City */ - protected string $city = ''; + /** @var Str $city - City */ + protected Str $city = Str::create(''); /** * Mutator method for setting the value into the Attribute. @@ -24,15 +26,15 @@ trait HasCityTrait */ protected function castCity(string $city): void { - $this->city = \trim($city); + $this->city = Str::create($city)->trim(); } /** * Returns the Entity's City. * - * @return string + * @return Str */ - public function getCity(): string + public function getCity(): Str { return $this->city; } diff --git a/src/Traits/Entities/Location/HasCountryTrait.php b/src/Traits/Entities/Location/HasCountryTrait.php index ce366c7..52fcc60 100644 --- a/src/Traits/Entities/Location/HasCountryTrait.php +++ b/src/Traits/Entities/Location/HasCountryTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; +use HraDigital\Datatypes\Scalar\Str; + /** * Trait for an Entity's Country attribute. * @@ -13,8 +15,8 @@ */ trait HasCountryTrait { - /** @var string $country - Country */ - protected string $country = ''; + /** @var Str $country - Country */ + protected Str $country = Str::create(''); /** * Mutator method for setting the value into the Attribute. @@ -24,15 +26,15 @@ trait HasCountryTrait */ protected function castCountry(string $country): void { - $this->country = \trim($country); + $this->country = Str::create($country)->trim(); } /** * Returns the Entity's Country. * - * @return string + * @return Str */ - public function getCountry(): string + public function getCountry(): Str { return $this->country; } diff --git a/src/Traits/Entities/Location/HasPostalCodeTrait.php b/src/Traits/Entities/Location/HasPostalCodeTrait.php index 8206639..57e27e6 100644 --- a/src/Traits/Entities/Location/HasPostalCodeTrait.php +++ b/src/Traits/Entities/Location/HasPostalCodeTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; +use HraDigital\Datatypes\Scalar\Str; + /** * Trait for an Entity's Postal Code attribute. * @@ -13,8 +15,8 @@ */ trait HasPostalCodeTrait { - /** @var string $postal_code - Postal Code */ - protected string $postal_code = ''; + /** @var Str $postal_code - Postal Code */ + protected Str $postal_code = Str::create(''); /** * Mutator method for setting the value into the Attribute. @@ -24,15 +26,15 @@ trait HasPostalCodeTrait */ protected function castPostalCode(string $postalCode): void { - $this->postal_code = \trim($postalCode); + $this->postal_code = Str::create($postalCode)->trim(); } /** * Returns the Entity's Postal Code. * - * @return string + * @return Str */ - public function getPostalCode(): string + public function getPostalCode(): Str { return $this->postal_code; } diff --git a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php index a75419d..1e493fa 100644 --- a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php +++ b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; +use HraDigital\Datatypes\Scalar\Str; + /** * Trait for an Entity's Street Aditional attribute. * @@ -13,8 +15,8 @@ */ trait HasStreetAdditionalTrait { - /** @var string $street_additional - Street Additional */ - protected string $street_additional = ''; + /** @var Str $street_additional - Street Additional */ + protected Str $street_additional = Str::create(''); /** * Mutator method for setting the value into the Attribute. @@ -24,15 +26,15 @@ trait HasStreetAdditionalTrait */ protected function castStreetAdditional(string $street): void { - $this->street_additional = \trim($street); + $this->street_additional = Str::create($street)->trim(); } /** * Returns the Entity's Street Additional. * - * @return string + * @return Str */ - public function getStreetAdditional(): string + public function getStreetAdditional(): Str { return $this->street_additional; } diff --git a/src/Traits/Entities/Location/HasStreetNumberTrait.php b/src/Traits/Entities/Location/HasStreetNumberTrait.php index 2ff81cb..1e8a491 100644 --- a/src/Traits/Entities/Location/HasStreetNumberTrait.php +++ b/src/Traits/Entities/Location/HasStreetNumberTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; +use HraDigital\Datatypes\Scalar\Str; + /** * Trait for an Entity's Street Number attribute. * @@ -13,8 +15,8 @@ */ trait HasStreetNumberTrait { - /** @var string $street_adicional - Street Number */ - protected string $street_no = ''; + /** @var Str $street_adicional - Street Number */ + protected Str $street_no = Str::create(''); /** * Mutator method for setting the value into the Attribute. @@ -24,15 +26,15 @@ trait HasStreetNumberTrait */ protected function castStreetNo(string $number): void { - $this->street_no = \trim($number); + $this->street_no = Str::create($number)->trim(); } /** * Returns the Entity's Street Number. * - * @return string + * @return Str */ - public function getStreetNumber(): string + public function getStreetNumber(): Str { return $this->street_no; } diff --git a/src/Traits/Entities/Location/HasStreetTrait.php b/src/Traits/Entities/Location/HasStreetTrait.php index b0f347a..4cb3c4e 100644 --- a/src/Traits/Entities/Location/HasStreetTrait.php +++ b/src/Traits/Entities/Location/HasStreetTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; +use HraDigital\Datatypes\Scalar\Str; + /** * Trait for an Entity's Street attribute. * @@ -13,8 +15,8 @@ */ trait HasStreetTrait { - /** @var string $street - Street */ - protected string $street = ''; + /** @var Str $street - Street */ + protected Str $street = Str::create(''); /** * Mutator method for setting the value into the Attribute. @@ -24,15 +26,15 @@ trait HasStreetTrait */ protected function castStreet(string $street): void { - $this->street = \trim($street); + $this->street = Str::create($street)->trim(); } /** * Returns the Entity's Street. * - * @return string + * @return Str */ - public function getStreet(): string + public function getStreet(): Str { return $this->street; } diff --git a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php index 2491f32..cef49b9 100644 --- a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php +++ b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php @@ -4,7 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\Personal; -use HraDigital\Datatypes\Exceptions\Entities\UnexpectedEntityValueException; +use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Scalar\Str; /** * Trait for an Entity's Country of Birth attribute. @@ -15,8 +16,8 @@ */ trait HasCountryOfBirthTrait { - /** @var string $country_of_birth - Country of Birth */ - protected string $country_of_birth = ''; + /** @var Str $country_of_birth - Country of Birth */ + protected Str $country_of_birth = Str::create(''); /** * Mutator method for setting the value into the Attribute. @@ -26,19 +27,21 @@ trait HasCountryOfBirthTrait */ protected function castCountryOfBirth(string $country): void { - if (\strlen(\trim($country)) === 0) { - throw new UnexpectedEntityValueException('Supplied Country of Birth must be a non empty string.'); + $countryValue = Str::create($country)->trim(); + + if ($countryValue->getLength() === 0) { + throw new NonEmptyStringException('$country_of_birth'); } - $this->country_of_birth = \trim($country); + $this->country_of_birth = $countryValue; } /** * Returns the Entity's Country of Birth. * - * @return string + * @return Str */ - public function getCountryOfBirth(): string + public function getCountryOfBirth(): Str { return $this->country_of_birth; } diff --git a/src/Traits/Entities/Personal/HasGenderTrait.php b/src/Traits/Entities/Personal/HasGenderTrait.php index 31ad845..1356bbf 100644 --- a/src/Traits/Entities/Personal/HasGenderTrait.php +++ b/src/Traits/Entities/Personal/HasGenderTrait.php @@ -5,6 +5,7 @@ namespace HraDigital\Datatypes\Traits\Entities\Personal; use HraDigital\Datatypes\Exceptions\Entities\UnexpectedEntityValueException; +use HraDigital\Datatypes\Scalar\Str; /** * Trait for an Entity's Gender attribute. @@ -15,8 +16,8 @@ */ trait HasGenderTrait { - /** @var string $sex - Gender */ - protected string $sex = 'Male'; + /** @var Str $sex - Gender */ + protected Str $sex = Str::create('Male'); /** * Mutator method for setting the value into the Attribute. @@ -27,9 +28,10 @@ trait HasGenderTrait protected function castSex(string $sex): void { // Sanitizes and checks supplied value. - $sex = \ucfirst(\strtolower($sex)); - if ($sex !== 'Male' && $sex !== 'Female') { - throw new UnexpectedEntityValueException("Specified gender '{$sex}' is not valid."); + $sexValue = Str::create($sex)->toLower()->toUpperFirst(); + + if (!$sexValue->equals(Str::create('Male')) && !$sexValue->equals(Str::create('Female'))) { + throw new UnexpectedEntityValueException('$sex'); } $this->sex = $sex; @@ -38,9 +40,9 @@ protected function castSex(string $sex): void /** * Returns the Entity's Gender. * - * @return string + * @return Str */ - public function getGender(): string + public function getGender(): Str { return $this->sex; } diff --git a/src/Traits/Entities/Personal/HasPhotoTrait.php b/src/Traits/Entities/Personal/HasPhotoTrait.php index c75b0a1..2756511 100755 --- a/src/Traits/Entities/Personal/HasPhotoTrait.php +++ b/src/Traits/Entities/Personal/HasPhotoTrait.php @@ -5,6 +5,7 @@ namespace HraDigital\Datatypes\Traits\Entities\Personal; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Scalar\Str; /** * Gives Photo information capabilities to an Entity/Value Object. @@ -15,8 +16,8 @@ */ trait HasPhotoTrait { - /** @var string|null $photo - Profile's Photo file */ - protected ?string $photo = null; + /** @var Str|null $photo - Profile's Photo file */ + protected ?Str $photo = null; /** * Sets the Profile's Photo value of an Entity. @@ -29,19 +30,21 @@ trait HasPhotoTrait protected function castPhoto(?string $photo): void { // Validates supplied parameter. - if (\strlen(\trim($photo)) === 0) { + $photoValue = Str::create($photo)->trim(); + + if ($photoValue->getLength() === 0) { throw new NonEmptyStringException('$photo'); } - $this->photo = $photo; + $this->photo = $photoValue; } /** * Returns the Instance's Profile's Photo. * - * @return string|null + * @return Str|null */ - public function getPhoto(): ?string + public function getPhoto(): ?Str { return $this->photo; } diff --git a/src/Traits/Entities/Personal/HasSurnameTrait.php b/src/Traits/Entities/Personal/HasSurnameTrait.php index eff2375..c5da6cb 100755 --- a/src/Traits/Entities/Personal/HasSurnameTrait.php +++ b/src/Traits/Entities/Personal/HasSurnameTrait.php @@ -5,6 +5,7 @@ namespace HraDigital\Datatypes\Traits\Entities\Personal; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Scalar\Str; /** * Gives Surname information capabilities to an Entity/Value Object. @@ -15,8 +16,8 @@ */ trait HasSurnameTrait { - /** @var string $surname - Instance's Surname. */ - protected string $surname = ''; + /** @var Str $surname - Instance's Surname. */ + protected Str $surname = Str::create(''); /** * Setter method for Surname. @@ -29,19 +30,21 @@ trait HasSurnameTrait protected function castSurname(string $surname): void { // Validates supplied parameter. - if (\strlen(\trim($surname)) === 0) { + $surnameValue = Str::create($surname)->trim(); + + if ($surnameValue->getLength() === 0) { throw new NonEmptyStringException('$surname'); } - $this->surname = $surname; + $this->surname = $surnameValue; } /** * Returns the Instance's Surname. * - * @return string + * @return Str */ - public function getSurname(): string + public function getSurname(): Str { return $this->surname; } diff --git a/src/Traits/Entities/Professional/HasOccupationTrait.php b/src/Traits/Entities/Professional/HasOccupationTrait.php index 21096f7..5c91564 100755 --- a/src/Traits/Entities/Professional/HasOccupationTrait.php +++ b/src/Traits/Entities/Professional/HasOccupationTrait.php @@ -5,6 +5,7 @@ namespace HraDigital\Datatypes\Traits\Entities\Professional; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Scalar\Str; /** * Gives Professional Occupation information capabilities to an Entity/Value Object. @@ -15,8 +16,8 @@ */ trait HasOccupationTrait { - /** @var string|null $occupation - Profile's Professional Occupation */ - protected ?string $occupation = null; + /** @var Str|null $occupation - Profile's Professional Occupation */ + protected ?Str $occupation = null; /** * Sets the Profile's Professional Occupation value of an Entity. @@ -29,19 +30,21 @@ trait HasOccupationTrait protected function castOccupation(?string $occupation): void { // Validates supplied parameter. - if ($occupation !== null && \strlen(\trim($occupation)) === 0) { + $occupationValue = $occupation ? Str::create($occupation)->trim() : null; + + if ($occupationValue !== null && $occupationValue->getLength() === 0) { throw new NonEmptyStringException('$occupation'); } - $this->occupation = $occupation; + $this->occupation = $occupationValue; } /** * Returns the Instance's Profile's Occupation. * - * @return string|null + * @return Str|null */ - public function getOccupation(): ?string + public function getOccupation(): ?Str { return $this->occupation; } diff --git a/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php b/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php index fae2d0a..76d1d94 100755 --- a/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php +++ b/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\SocialMedia; +use HraDigital\Datatypes\Scalar\Str; + /** * Adds Facebook's Social Media account URL field. * @@ -13,8 +15,8 @@ */ trait HasFacebookProfileTrait { - /** @var string|null $facebook - Social Media account's URL. */ - protected ?string $facebook = null; + /** @var Str|null $facebook - Social Media account's URL. */ + protected ?Str $facebook = null; /** * Sets the Social Media account URL value of an Entity. @@ -24,15 +26,15 @@ trait HasFacebookProfileTrait */ protected function castFacebook(?string $facebook): void { - $this->facebook = $facebook; + $this->facebook = $facebook ? Str::create($facebook)->trim() : null; } /** * Retrieves record's Social Media account's URL. * - * @return string|null + * @return Str|null */ - public function getFacebookUrl(): ?string + public function getFacebookUrl(): ?Str { return $this->facebook; } diff --git a/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php b/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php index 07b6d27..df0e352 100755 --- a/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php +++ b/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\SocialMedia; +use HraDigital\Datatypes\Scalar\Str; + /** * Adds Instagram's Social Media account URL field. * @@ -13,8 +15,8 @@ */ trait HasInstagramProfileTrait { - /** @var string|null $instagram - Social Media account's URL. */ - protected ?string $instagram = null; + /** @var Str|null $instagram - Social Media account's URL. */ + protected ?Str $instagram = null; /** * Sets the Social Media account URL value of an Entity. @@ -24,15 +26,15 @@ trait HasInstagramProfileTrait */ protected function castInstagram(?string $instagram): void { - $this->instagram = $instagram; + $this->instagram = $instagram ? Str::create($instagram)->trim() : null; } /** * Retrieves record's Social Media account's URL. * - * @return string|null + * @return Str|null */ - public function getInstagramUrl(): ?string + public function getInstagramUrl(): ?Str { return $this->instagram; } diff --git a/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php b/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php index 7f6dc36..578e719 100755 --- a/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php +++ b/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\SocialMedia; +use HraDigital\Datatypes\Scalar\Str; + /** * Adds Linkedin's Social Media account URL field. * @@ -13,8 +15,8 @@ */ trait HasLinkedinProfileTrait { - /** @var string|null $linkedin - Social Media account's URL. */ - protected ?string $linkedin = null; + /** @var Str|null $linkedin - Social Media account's URL. */ + protected ?Str $linkedin = null; /** * Sets the Social Media account URL value of an Entity. @@ -24,15 +26,15 @@ trait HasLinkedinProfileTrait */ protected function castLinkedin(?string $linkedin): void { - $this->linkedin = $linkedin; + $this->linkedin = $linkedin ? Str::create($linkedin)->trim() : null; } /** * Retrieves record's Social Media account's URL. * - * @return string|null + * @return Str|null */ - public function getLinkedinUrl(): ?string + public function getLinkedinUrl(): ?Str { return $this->linkedin; } diff --git a/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php b/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php index 8d04bf6..57423ff 100755 --- a/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php +++ b/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities\SocialMedia; +use HraDigital\Datatypes\Scalar\Str; + /** * Adds Twitters's Social Media account URL field. * @@ -13,8 +15,8 @@ */ trait HasTwitterProfileTrait { - /** @var string|null $twitter - Social Media account's URL. */ - protected ?string $twitter = null; + /** @var Str|null $twitter - Social Media account's URL. */ + protected ?Str $twitter = null; /** * Sets the Social Media account URL value of an Entity. @@ -24,15 +26,15 @@ trait HasTwitterProfileTrait */ protected function castTwitter(?string $twitter): void { - $this->twitter = $twitter; + $this->twitter = $twitter ? Str::create($twitter)->trim() : null; } /** * Retrieves record's Social Media account's URL. * - * @return string|null + * @return Str|null */ - public function getTwitterUrl(): ?string + public function getTwitterUrl(): ?Str { return $this->twitter; } From 42a491b73d61501f8887a82f33ed0e162db800e7 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 9 Nov 2021 12:52:16 +0000 Subject: [PATCH 076/193] Remove default values for attributes of type Str --- src/Traits/Entities/General/HasAliasTrait.php | 2 +- src/Traits/Entities/General/HasNameTrait.php | 4 ++-- src/Traits/Entities/Location/HasAddressTrait.php | 2 +- src/Traits/Entities/Location/HasCityTrait.php | 2 +- src/Traits/Entities/Location/HasCountryTrait.php | 2 +- src/Traits/Entities/Location/HasPostalCodeTrait.php | 2 +- src/Traits/Entities/Location/HasStreetAdditionalTrait.php | 2 +- src/Traits/Entities/Location/HasStreetNumberTrait.php | 2 +- src/Traits/Entities/Location/HasStreetTrait.php | 2 +- src/Traits/Entities/Personal/HasCountryOfBirthTrait.php | 2 +- src/Traits/Entities/Personal/HasGenderTrait.php | 2 +- src/Traits/Entities/Personal/HasSurnameTrait.php | 2 +- src/Web/EmailAddress.php | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Traits/Entities/General/HasAliasTrait.php b/src/Traits/Entities/General/HasAliasTrait.php index b604044..b53393b 100755 --- a/src/Traits/Entities/General/HasAliasTrait.php +++ b/src/Traits/Entities/General/HasAliasTrait.php @@ -17,7 +17,7 @@ trait HasAliasTrait { /** @var Str $alias - Instances's Alias. */ - protected Str $alias = Str::create(''); + protected Str $alias; /** * Setter method for alias. diff --git a/src/Traits/Entities/General/HasNameTrait.php b/src/Traits/Entities/General/HasNameTrait.php index 2a13194..a8256ed 100755 --- a/src/Traits/Entities/General/HasNameTrait.php +++ b/src/Traits/Entities/General/HasNameTrait.php @@ -17,7 +17,7 @@ trait HasNameTrait { /** @var Str $name - Instance's Name. */ - protected Str $name = Str::create(''); + protected Str $name; /** * Setter method for name. @@ -35,7 +35,7 @@ protected function castName(string $name): void throw new NonEmptyStringException('$name'); } - $this->name = $name; + $this->name = $nameValue; } /** diff --git a/src/Traits/Entities/Location/HasAddressTrait.php b/src/Traits/Entities/Location/HasAddressTrait.php index d117a6d..1c573f7 100644 --- a/src/Traits/Entities/Location/HasAddressTrait.php +++ b/src/Traits/Entities/Location/HasAddressTrait.php @@ -16,7 +16,7 @@ trait HasAddressTrait { /** @var Str $address - Address */ - protected Str $address = Str::create(''); + protected Str $address; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Location/HasCityTrait.php b/src/Traits/Entities/Location/HasCityTrait.php index b8d2e2a..e0d8f35 100644 --- a/src/Traits/Entities/Location/HasCityTrait.php +++ b/src/Traits/Entities/Location/HasCityTrait.php @@ -16,7 +16,7 @@ trait HasCityTrait { /** @var Str $city - City */ - protected Str $city = Str::create(''); + protected Str $city; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Location/HasCountryTrait.php b/src/Traits/Entities/Location/HasCountryTrait.php index 52fcc60..bf1d0bf 100644 --- a/src/Traits/Entities/Location/HasCountryTrait.php +++ b/src/Traits/Entities/Location/HasCountryTrait.php @@ -16,7 +16,7 @@ trait HasCountryTrait { /** @var Str $country - Country */ - protected Str $country = Str::create(''); + protected Str $country; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Location/HasPostalCodeTrait.php b/src/Traits/Entities/Location/HasPostalCodeTrait.php index 57e27e6..ef26abb 100644 --- a/src/Traits/Entities/Location/HasPostalCodeTrait.php +++ b/src/Traits/Entities/Location/HasPostalCodeTrait.php @@ -16,7 +16,7 @@ trait HasPostalCodeTrait { /** @var Str $postal_code - Postal Code */ - protected Str $postal_code = Str::create(''); + protected Str $postal_code; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php index 1e493fa..9876d96 100644 --- a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php +++ b/src/Traits/Entities/Location/HasStreetAdditionalTrait.php @@ -16,7 +16,7 @@ trait HasStreetAdditionalTrait { /** @var Str $street_additional - Street Additional */ - protected Str $street_additional = Str::create(''); + protected Str $street_additional; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Location/HasStreetNumberTrait.php b/src/Traits/Entities/Location/HasStreetNumberTrait.php index 1e8a491..1cb3ddf 100644 --- a/src/Traits/Entities/Location/HasStreetNumberTrait.php +++ b/src/Traits/Entities/Location/HasStreetNumberTrait.php @@ -16,7 +16,7 @@ trait HasStreetNumberTrait { /** @var Str $street_adicional - Street Number */ - protected Str $street_no = Str::create(''); + protected Str $street_no; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Location/HasStreetTrait.php b/src/Traits/Entities/Location/HasStreetTrait.php index 4cb3c4e..710b018 100644 --- a/src/Traits/Entities/Location/HasStreetTrait.php +++ b/src/Traits/Entities/Location/HasStreetTrait.php @@ -16,7 +16,7 @@ trait HasStreetTrait { /** @var Str $street - Street */ - protected Str $street = Str::create(''); + protected Str $street; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php index cef49b9..8a2e6f6 100644 --- a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php +++ b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php @@ -17,7 +17,7 @@ trait HasCountryOfBirthTrait { /** @var Str $country_of_birth - Country of Birth */ - protected Str $country_of_birth = Str::create(''); + protected Str $country_of_birth; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Personal/HasGenderTrait.php b/src/Traits/Entities/Personal/HasGenderTrait.php index 1356bbf..27fc1dc 100644 --- a/src/Traits/Entities/Personal/HasGenderTrait.php +++ b/src/Traits/Entities/Personal/HasGenderTrait.php @@ -17,7 +17,7 @@ trait HasGenderTrait { /** @var Str $sex - Gender */ - protected Str $sex = Str::create('Male'); + protected Str $sex; /** * Mutator method for setting the value into the Attribute. diff --git a/src/Traits/Entities/Personal/HasSurnameTrait.php b/src/Traits/Entities/Personal/HasSurnameTrait.php index c5da6cb..ea18f67 100755 --- a/src/Traits/Entities/Personal/HasSurnameTrait.php +++ b/src/Traits/Entities/Personal/HasSurnameTrait.php @@ -17,7 +17,7 @@ trait HasSurnameTrait { /** @var Str $surname - Instance's Surname. */ - protected Str $surname = Str::create(''); + protected Str $surname; /** * Setter method for Surname. diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index a77cea3..311eb69 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -67,7 +67,7 @@ protected function loadFromPrimitive(string $email): void $voEmail = Str::create($email)->trim()->toLower(); // Validate supplied parameter. - if ($voEmail->length() === 0) { + if ($voEmail->getLength() === 0) { throw new NonEmptyStringException('$email'); } if (!\filter_var((string) $email, FILTER_VALIDATE_EMAIL)) { From 7132627e7eda46b4d9e972a7af6a393161787a84 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 28 Feb 2022 17:43:37 +0000 Subject: [PATCH 077/193] refactor: Remove deprecated classes --- src/Aggregates/AbstractBaseAggregate.php | 49 --- src/Aggregates/README.md | 33 -- src/Scalar/NString.php | 422 ------------------ tests/Unit/Scalar/NStringTest.php | 509 --------------------- tests/Unit/Scalar/VoStringTest.php | 539 ----------------------- 5 files changed, 1552 deletions(-) delete mode 100644 src/Aggregates/AbstractBaseAggregate.php delete mode 100755 src/Aggregates/README.md delete mode 100644 src/Scalar/NString.php delete mode 100644 tests/Unit/Scalar/NStringTest.php delete mode 100644 tests/Unit/Scalar/VoStringTest.php diff --git a/src/Aggregates/AbstractBaseAggregate.php b/src/Aggregates/AbstractBaseAggregate.php deleted file mode 100644 index e6e338d..0000000 --- a/src/Aggregates/AbstractBaseAggregate.php +++ /dev/null @@ -1,49 +0,0 @@ - $value) { - - // If the Attribute's value is json serializable itself, - // serialize and add it to the returning array. - // Otherwize, return its holding value. - if ($value instanceof \JsonSerializable) { - $json[$name] = $value->jsonSerialize(); - } elseif (\is_object($value) && \method_exists($value, '__toString')) { - $json[$name] = (string) $value; - } else { - $json[$name] = $value; - } - } - - return $json; - } -} diff --git a/src/Aggregates/README.md b/src/Aggregates/README.md deleted file mode 100755 index 6080b15..0000000 --- a/src/Aggregates/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Aggregates - -_Aggregates_ are not meant to be the same as _DDD's Root Aggregates_. - -`Aggregates` are meant to **aggregate returned types** together, in order to **minimize** communication with the **Domain**. - -As [Martin Fowler](https://martinfowler.com/) puts it, _**Aggregates are the basic element of transfer of data** -**storage - you request to load and save whole aggregates**_. - -For more information please [read Martin Fowler's blog](https://martinfowler.com/bliki/DDD_Aggregate.html). - -## When to use Aggregates - -When communicating in the **Domain**, we might only need an _Entity_ or a _Collection_ returned, but in some other -cases, we might need that initial _Entity_, but also some other object (eg:. _Collection_). - -In these cases, we would need to perform multiple calls to the **Domain**, and in some cases, we would need to hold -state in between calls. - -**Aggregates** are objects that will encapsulate/aggregate several other objects that are meant to be **returned as a group**. -This way, we will only make one call to the **Domain**, and will only require the state to hold on that call's execution. - -## How to structure an Aggregate - -An **Aggregate** is a simple native object, that doesn't require to extend any base class, and should not contain any -_Business Logic_ inside. - -It is a _Value Object_ whose main purposes are providing a _strong return type_, and a way to group other objects together. - -The basic structure for an **Aggregate** comprises of a _construct_ with all the objects that we're trying to aggregate together, -and class attributes to hold them in state. - -We should then provide *accessors* (`getters()`) for each attribute in the **Aggregate** diff --git a/src/Scalar/NString.php b/src/Scalar/NString.php deleted file mode 100644 index 1c484cd..0000000 --- a/src/Scalar/NString.php +++ /dev/null @@ -1,422 +0,0 @@ -value); - } - - /** - * Compares the values of 2 separate strings. - * - * Returns TRUE if the 2 values match. FALSE otherwise. - * - * @param string $string - Another string instance to compare to. - * @return bool - */ - public function equals(string $string): bool - { - return parent::doEquals($string); - } - - /** - * Checks if the instance contains the supplied $search value. - * - * Returns TRUE if found. FALSE otherwise. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws NonEmptyStringException - If supplied $search is empty. - * @return bool - */ - public function contains(string $search): bool - { - return parent::doContains($search); - } - - /** - * Searches and returns the index in the instance, of the $search string. - * - * If a $start is specified, search will start this number of characters counted from - * the beginning of the string. If $start is negative, the search will start this number - * of characters counted from the end of the string. - * - * If the $search is not found inthe instance's value, NULL is returned. - * - * @param string $search - String to search for in the instance. - * @param int $start - Search offset start. Defaults to ZERO. - * - * @throws NonEmptyStringException - If $search value is an empty string. - * @throws ParameterOutOfRangeException - If the $start is either too small, or too long. - * @return int|null - */ - public function indexOf(string $search, int $start = 0): ?int - { - return parent::doIndexOf($search, $start); - } - - /** - * Checks if the instance's value starts with the supplied string. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws NonEmptyStringException - If supplied $search is empty. - * @return bool - */ - public function startsWith(string $search): bool - { - return parent::doStartsWith($search); - } - - /** - * Checks if the instance's value ends with the supplied string. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws NonEmptyStringException - If supplied $search is empty. - * @return bool - */ - public function endsWith(string $search): bool - { - return parent::doEndsWith($search); - } - - /** - * Counts the number of substring occurrences in the instance's value. - * - * @param string $search - Non empty string to search for in the instance. - * @param int $start - The sub-string's offset/start. - * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. - * - * @throws NonEmptyStringException - If supplied $search is empty. - * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return int - */ - public function count(string $search, int $start = 0, ?int $length = null): int - { - return parent::doCount($search, $start, $length); - } - - /** - * Trims instance's value on both ends. - * - * @return NString - */ - public function trim(): NString - { - return NString::create( - parent::doTrim() - ); - } - - /** - * Trims instance's value only on the left. - * - * @return NString - */ - public function trimLeft(): NString - { - return NString::create( - parent::doTrimLeft() - ); - } - - /** - * Trims instance's value only on the right. - * - * @return NString - */ - public function trimRight(): NString - { - return NString::create( - parent::doTrimRight() - ); - } - - /** - * Converts the instance's value to Uppecase. - * - * @return NString - */ - public function toUpper(): NString - { - return NString::create( - parent::doToUpper() - ); - } - - /** - * Converts the instance's value first character to Uppercase, and returns a new instance - * of the object. - * - * @return NString - */ - public function toUpperFirst(): NString - { - return NString::create( - parent::doToUpperFirst() - ); - } - - /** - * Converts the instance's value first character of each word to Upper Case, and returns a new instance - * of the object. - * - * @param string $delimiters - The optional delimiters contains the word separator characters. - * - * @return NString - */ - public function toUpperWords(string $delimiters = " \t\r\n\f\v"): NString - { - return NString::create( - parent::doToUpperWords($delimiters) - ); - } - - /** - * Converts the instance's value to Lowercase, and returns a new instance of the object. - * - * @return NString - */ - public function toLower(): NString - { - return NString::create( - parent::doToLower() - ); - } - - /** - * Converts the instance's value first character to Lowercase, and returns a new instance - * of the object - * - * @return NString - */ - public function toLowerFirst(): NString - { - return NString::create( - parent::doToLowerFirst() - ); - } - - /** - * This method returns a new instance padded on the left to the specified padding length minus - * the length of the instance's value. - * - * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will - * only be padded by the value of 2. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws NonEmptyStringException - If supplied $padding is empty. - * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return NString - */ - public function padLeft(int $length, string $padding = " "): NString - { - return NString::create( - parent::doPadLeft($length, $padding) - ); - } - - /** - * This method returns a new instance padded on the left, exactly to the specified padding length. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws NonEmptyStringException - If supplied $padding is empty. - * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return NString - */ - public function padLeftExtra(int $length, string $padding = " "): NString - { - return NString::create( - parent::doPadLeftExtra($length, $padding) - ); - } - - /** - * This method returns a new instance padded on the right to the specified padding length minus - * the length of the instance's value. - * - * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will - * only be padded by the value of 2. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws NonEmptyStringException - If supplied $padding is empty. - * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return NString - */ - public function padRight(int $length, string $padding = " "): NString - { - return NString::create( - parent::doPadRight($length, $padding) - ); - } - - /** - * This method returns a new instance padded on the right, exactly to the specified padding length. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws NonEmptyStringException - If supplied $padding is empty. - * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return NString - */ - public function padRightExtra(int $length, string $padding = " "): NString - { - return NString::create( - parent::doPadRightExtra($length, $padding) - ); - } - - /** - * This method returns a new instance with a portion of the original instance's value, specified by the - * $start and $length parameters. - * - * $start parameter: - * - If $start is non-negative, the returned an instance will start at the $start'th position in - * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the - * character at position 2 is 'c', and so forth. - * - If $start is negative, the returned string will start at the $start'th character from the end - * of string. - * - If the absolute value of $start is higher than the instance's length, an - * exception is thrown. - * - * - * $length parameter: - * - If $length is given and is positive, the string returned will contain at most length characters - * beginning from $start (depending on the length of string). - * - If $length is given and is negative, then that many characters will be omitted from the end of string - * (after the start position has been calculated when a start is negative). - * - If $length exceeds the remaining number of characters, after the $start calculation, an - * Exception will be raised. - * - * @param int $start - Start of the sub-string. Can be negative. - * @param int $length - Length of the sub-string. Can be negative. - * - * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return NString - */ - public function subString(int $start, int $length = null): NString - { - return NString::create( - parent::doSubString($start, $length) - ); - } - - /** - * This method returns a new instance with a portion of the original instance's value, starting at the beginning - * of the value, with the number of characters specified in the $length parameter. - * - * @param int $length - Length of the sub-string. Must be positive. - * - * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. - * @return NString - */ - public function subLeft(int $length): NString - { - return NString::create( - parent::doSubLeft($length) - ); - } - - /** - * This method returns a new instance with a portion of the original instance's value, couting from the end - * of the value, with the number of characters specified in the $length parameter. - * - * @param int $length - Length of the sub-string. Must be positive. - * - * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. - * @return NString - */ - public function subRight(int $length): NString - { - return NString::create( - parent::doSubRight($length) - ); - } - - /** - * This method returns the reversed value of the instance. - * - * @return NString - */ - public function reverse(): NString - { - return NString::create( - parent::doReverse() - ); - } - - /** - * This method replaces a string's occurance by another, and returns a new instance with the new value. - * - * @param string $search - The string to search for. - * @param string $replace - The search's replacement. - * - * @throws NonEmptyStringException - If either $search or $replace are empty. - * @return NString - */ - public function replace(string $search, string $replace): NString - { - return NString::create( - parent::doReplace($search, $replace) - ); - } -} diff --git a/tests/Unit/Scalar/NStringTest.php b/tests/Unit/Scalar/NStringTest.php deleted file mode 100644 index 81c3f45..0000000 --- a/tests/Unit/Scalar/NStringTest.php +++ /dev/null @@ -1,509 +0,0 @@ -assertFalse( - ($original === $other), - 'Instances are not meant to match.' - ); - } - - /** @inheritDoc */ - protected function checkCorrectInstanceType(AbstractBaseString $instance): void - { - $this->assertInstanceOf( - NString::class, - $instance, - 'Instance type, does not match NString.' - ); - } - - /** - * Checks Equality of two distinct strings. - * - * @return void - */ - public function testCanCheckEquality(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = " Immutable string. "; - - // Performs assertions. - $this->assertTrue( - $original->equals($other), - 'Instance values do not match.' - ); - } - - /** - * Tests that we can check of String contains a text portion. - * - * @return void - */ - public function testCanCheckIfStringContainsPortion(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - - // Performs assertions. - $this->assertTrue( - $original->contains('muta'), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($original); - } - - /** - * Tests that method breaks if invalid parameters are passed. - * - * @return void - */ - public function testBreaksCheckingIfStringContainsPortionWithEmptyText(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - - // Create expectations. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original->contains(''); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testCanRetrieveIndexOf(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $indexOf = $instance->indexOf('string'); - - // Performs assertions. - $this->assertEquals( - 10, - $indexOf, - 'Retrieved index is incorrect.' - ); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testCanRetrieveIndexOfWithStart(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $indexOf = $instance->indexOf('string', 15); - - // Performs assertions. - $this->assertEquals( - 37, - $indexOf, - 'Retrieved index is incorrect.' - ); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testIndexOfReturnsNullIfNotFound(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $indexOf = $instance->indexOf('another'); - - // Performs assertions. - $this->assertNull( - $indexOf, - 'Retrieved index should have been NULL.' - ); - } - - /** - * Test indexOf() breaks with illegal parameters. - * - * @return void - */ - public function testBreaksIndexOfIfEmptySearch(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->indexOf(''); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testCanCheckIfStringStartsWithText(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $true = $instance->startsWith("Immu"); - $false = $instance->startsWith("string"); - - // Performs assertions. - $this->assertTrue($true, 'String should have started with searched text.'); - $this->assertFalse($false, 'String should not have started with searched text.'); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testBreaksCheckingIfStringStartsWithText(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->startsWith(''); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testCanCheckIfStringEndsWithText(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $true = $instance->endsWith("string."); - $false = $instance->endsWith("Immu"); - - // Performs assertions. - $this->assertTrue($true, 'String should have ended with searched text.'); - $this->assertFalse($false, 'String should not have ended with searched text.'); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testBreaksCheckingIfStringEndsWithText(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->endsWith(''); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInString(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count('string'); - - // Performs assertions. - $this->assertEquals( - 2, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInStringWithStartAndLength(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count('string', 15, 29); - - // Performs assertions. - $this->assertEquals( - 1, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInStringIfNoneIsFound(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count('string', 38, 4); - - // Performs assertions. - $this->assertEquals( - 0, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() breaks if empty search is supplied. - * - * @return void - */ - public function testBreaksCountNumberOccurencesInStringIfSerachIsEmpty(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $instance->count(''); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksPaddingOnTheLeftWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeft(2, ''); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksCanPaddingOnTheLeftExtraWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeftExtra(2, ''); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeftWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeft(\strlen($string) + 2, '_'); - - // Performs assertions. - $this->assertEquals( - '__Immutable String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeftExtraWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeftExtra(2, '_'); - - // Performs assertions. - $this->assertEquals( - '__Immutable String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksCanPadOnTheRightWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRight(2, ''); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksCanPadOnTheRightExtraWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRightExtra(2, ''); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRightWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRight(\strlen($string) + 2, '_'); - - // Performs assertions. - $this->assertEquals( - 'Immutable String.__', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRightExtraWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRightExtra(2, '_'); - - // Performs assertions. - $this->assertEquals( - 'Immutable String.__', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that text can be replaced in the String. - * - * @return void - */ - public function testTextCanBeReplacedInString(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->replace('String', 'Object'); - - // Performs assertions. - $this->assertEquals( - 'Immutable Object.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that text is not replaced if search is not found. - * - * @return void - */ - public function testTextIsNotReplacedIfSearchNotFound(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->replace('None', 'Object'); - - // Performs assertions. - $this->assertEquals( - (string) $original, - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that text replace breaks. - * - * @return void - */ - public function testBreaksTextReplaceIfSearchIsEmpty(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->replace('', 'Object'); - } -} diff --git a/tests/Unit/Scalar/VoStringTest.php b/tests/Unit/Scalar/VoStringTest.php deleted file mode 100644 index 9ee3847..0000000 --- a/tests/Unit/Scalar/VoStringTest.php +++ /dev/null @@ -1,539 +0,0 @@ -assertFalse( - ($original === $other), - 'Instances are not meant to match.' - ); - } - - /** @inheritDoc */ - protected function checkCorrectInstanceType(AbstractBaseString $instance): void - { - $this->assertInstanceOf( - VoString::class, - $instance, - 'Instance type, does not match VoString.' - ); - } - - /** - * Checks Equality of two distinct strings. - * - * @return void - */ - public function testCanCheckEquality(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = $this->getInstance(" Immutable string. "); - - // Performs assertions. - $this->assertTrue( - $original->equals($other), - 'Instance values do not match.' - ); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that we can check of String contains a text portion. - * - * @return void - */ - public function testCanCheckIfStringContainsPortion(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - $search = $this->getInstance('muta'); - - // Performs assertions. - $this->assertTrue( - $original->contains($search), - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($original); - $this->checkDifferentInstances($original, $search); - } - - /** - * Tests that method breaks if invalid parameters are passed. - * - * @return void - */ - public function testBreaksCheckingIfStringContainsPortionWithEmptyText(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - - // Create expectations. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original->contains( - $this->getInstance('') - ); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testCanRetrieveIndexOf(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $search = $this->getInstance('string'); - $indexOf = $instance->indexOf($search); - - // Performs assertions. - $this->assertEquals( - 10, - $indexOf, - 'Retrieved index is incorrect.' - ); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testCanRetrieveIndexOfWithStart(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $search = $this->getInstance('string'); - $indexOf = $instance->indexOf($search, 15); - - // Performs assertions. - $this->assertEquals( - 37, - $indexOf, - 'Retrieved index is incorrect.' - ); - } - - /** - * Test indexOf() method. - * - * @return void - */ - public function testIndexOfReturnsNullIfNotFound(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $search = $this->getInstance('another'); - $indexOf = $instance->indexOf($search); - - // Performs assertions. - $this->assertNull( - $indexOf, - 'Retrieved index should have been NULL.' - ); - } - - /** - * Test indexOf() breaks with illegal parameters. - * - * @return void - */ - public function testBreaksIndexOfIfEmptySearch(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->indexOf( - $this->getInstance('') - ); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testCanCheckIfStringStartsWithText(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $true = $instance->startsWith( - $this->getInstance("Immu") - ); - $false = $instance->startsWith( - $this->getInstance("string") - ); - - // Performs assertions. - $this->assertTrue($true, 'String should have started with searched text.'); - $this->assertFalse($false, 'String should not have started with searched text.'); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testBreaksCheckingIfStringStartsWithText(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->startsWith( - $this->getInstance('') - ); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testCanCheckIfStringEndsWithText(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string."); - $true = $instance->endsWith($this->getInstance("string.")); - $false = $instance->endsWith($this->getInstance("Immu")); - - // Performs assertions. - $this->assertTrue($true, 'String should have ended with searched text.'); - $this->assertFalse($false, 'String should not have ended with searched text.'); - } - - /** - * Tests that we can check is a string begins with a given text. - * - * @return void - */ - public function testBreaksCheckingIfStringEndsWithText(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string."); - $instance->endsWith( - $this->getInstance('') - ); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInString(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count( - $this->getInstance('string') - ); - - // Performs assertions. - $this->assertEquals( - 2, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInStringWithStartAndLength(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $search = $this->getInstance('another'); - $count = $instance->count($search, 15, 29); - - // Performs assertions. - $this->assertEquals( - 1, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() method. - * - * @return void - */ - public function testCanCountNumberOccurencesInStringIfNoneIsFound(): void - { - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $search = $this->getInstance('another'); - $count = $instance->count($search, 38, 4); - - // Performs assertions. - $this->assertEquals( - 0, - $count, - 'Retrieved count is incorrect.' - ); - } - - /** - * Tests count() breaks if empty search is supplied. - * - * @return void - */ - public function testBreaksCountNumberOccurencesInStringIfSerachIsEmpty(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $instance = $this->getInstance("Immutable string, or part of another string."); - $instance->count( - $this->getInstance('') - ); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksPaddingOnTheLeftWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeft(2, $this->getInstance('')); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksCanPaddingOnTheLeftExtraWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeftExtra(2, $this->getInstance('')); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeftWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeft(\strlen($string) + 2, $this->getInstance('_')); - - // Performs assertions. - $this->assertEquals( - '__Immutable String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeftExtraWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeftExtra(2, $this->getInstance('_')); - - // Performs assertions. - $this->assertEquals( - '__Immutable String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksCanPadOnTheRightWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRight(2, $this->getInstance('')); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksCanPadOnTheRightExtraWithInvalidPadString(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRightExtra(2, $this->getInstance('')); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRightWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRight(\strlen($string) + 2, $this->getInstance('_')); - - // Performs assertions. - $this->assertEquals( - 'Immutable String.__', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRightExtraWidthCharacter(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRightExtra(2, $this->getInstance('_')); - - // Performs assertions. - $this->assertEquals( - 'Immutable String.__', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that text can be replaced in the String. - * - * @return void - */ - public function testTextCanBeReplacedInString(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $search = $this->getInstance('String'); - $replace = $this->getInstance('Object'); - $other = $original->replace($search, $replace); - - // Performs assertions. - $this->assertEquals( - 'Immutable Object.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that text is not replaced if search is not found. - * - * @return void - */ - public function testTextIsNotReplacedIfSearchNotFound(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $search = $this->getInstance('None'); - $replace = $this->getInstance('Object'); - $other = $original->replace($search, $replace); - - // Performs assertions. - $this->assertEquals( - (string) $original, - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that text replace breaks. - * - * @return void - */ - public function testBreaksTextReplaceIfSearchIsEmpty(): void - { - // Creates expectation. - $this->expectException(NonEmptyStringException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $search = $this->getInstance(''); - $replace = $this->getInstance('Object'); - $original->replace($search, $replace); - } -} From 39e7e77d188f3aa7945e4226650e4d1e64e8f7a8 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 28 Feb 2022 17:44:15 +0000 Subject: [PATCH 078/193] feat: Add explode() method --- src/Scalar/Str.php | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Scalar/Str.php b/src/Scalar/Str.php index 4c0d742..e551732 100644 --- a/src/Scalar/Str.php +++ b/src/Scalar/Str.php @@ -43,7 +43,7 @@ public static function create(string $value): Str */ public function equals(Str $string): bool { - return ($this->value === $string); + return ($this->value === $string->value); } /** @@ -415,16 +415,45 @@ public function reverse(): Str /** * This method replaces a string's occurance by another, and returns a new instance with the new value. * - * @param string $search - The string to search for. - * @param string $replace - The search's replacement. + * @param Str $search - The string to search for. + * @param Str $replace - The search's replacement. * * @throws NonEmptyStringException - If either $search or $replace are empty. * @return Str */ - public function replace(string $search, string $replace): Str + public function replace(Str $search, Str $replace): Str { return Str::create( parent::doReplace((string) $search, (string) $replace) ); } + + /** + * Returns an array of strings, each of which is a substring of string formed + * by splitting it on boundaries formed by the string separator. + * + * If limit is set and positive, the returned array will contain a maximum of limit + * elements with the last element containing the rest of string. + * + * If the limit parameter is negative, all components except the last -limit are returned. + * + * If the limit parameter is zero, then this is treated as 1. + * + * @param string $separator - The boundary string. + * @param int|null $limit - The limit of returned segments. + * + * @throws NonEmptyStringException - If $separator is an empty string. + * @return array|Str[] + */ + public function explode(string $separator, ?int $limit = null): array + { + $segments = parent::doExplode($separator, $limit); + $exploded = []; + + foreach ($segments as $segment) { + $exploded[] = Str::create($segment); + } + + return $exploded; + } } From cb6815c147558161012940bccbc146647ef96e8b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 28 Feb 2022 17:46:11 +0000 Subject: [PATCH 079/193] feat: Add base Traits for AbstractValueObject --- .../CanProcessOnLoadEventsTrait.php | 29 ++++++++++--------- .../HasConversionToPrimitiveValuesTrait.php | 5 ++-- .../ValueObjects/HasFieldCastingTrait.php | 4 +-- .../ValueObjects/HasMappedFieldsTrait.php | 6 +--- .../ValueObjects/HasRuleProcessingTrait.php | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php index 1bc74ec..3b58bde 100644 --- a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php +++ b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php @@ -4,12 +4,12 @@ namespace HraDigital\Datatypes\Traits\ValueObjects; -use Closure; - /** * Gives onLoad event handling capabilities to class. * - * To register an new handler for the onLoad event, use $this->onLoad(function() { $this->someCall() }); + * To register an new handler for the onLoad event, declare a protected method starting with "onLoad". + * + * onLoad() methods should only be called when instance is created by instantiation. * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes @@ -17,6 +17,9 @@ */ trait CanProcessOnLoadEventsTrait { + /** Sets the onLoad Mutator method's prefix. */ + private static $ONLOADPREFIX = 'onLoad'; + /** @var array $onLoadEvents - List of onLoad event handlers, defined as closures. */ private array $onLoadEvents = []; @@ -25,21 +28,21 @@ trait CanProcessOnLoadEventsTrait * * @return void */ - protected function triggerOnLoad(): void + private function triggerOnLoad(): void { foreach ($this->onLoadEvents as $onLoad) { - $onLoad(); + $this->$onLoad(); } } - /** - * Adds a new onLoad event handler to the class. - * - * @param Closure $handler - Closure that will be triggered onLoad. - * @return void - */ - protected function onLoad(Closure $handler): void + private function registerOnLoadEvents(): void { - $this->onLoadEvents[] = $handler; + // Loops through all the class' methods, and loads the necessary ones in + // the corresponding containers. + foreach (\get_class_methods($this) as $method) { + if (\strpos($method, self::$ONLOADPREFIX) === 0 && \strlen($method) > \strlen(self::$ONLOADPREFIX)) { + $this->onLoadEvents[] = $method; + } + } } } diff --git a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php index 41032d7..354a1c6 100644 --- a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php +++ b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php @@ -20,9 +20,10 @@ trait HasConversionToPrimitiveValuesTrait * Converts all values into primitives, and retiurns the processed array. * * @param array $fields - List of Fields to be converted. + * @param bool $objectAsJson - If set to true, will use jsonSerialize(). Otherwise will use toArray() * @return array */ - private function convertIntoPrimitiveValues(array $fields): array + private function convertIntoPrimitiveValues(array $fields, bool $objectAsJson = false): array { // Loops through all the supplied Fields, and converts their values into primitives. $converted = []; @@ -31,7 +32,7 @@ private function convertIntoPrimitiveValues(array $fields): array // Returns the string representation of the object, or tries to convert array or object to JSON. // If is not an Object not an Array, returns the actual value of the Field. if ($value instanceof AbstractValueObject || $value instanceof EntityCollection) { - $converted[$field] = $value->jsonSerialize(); + $converted[$field] = $objectAsJson ? $value->jsonSerialize() : $value->toArray(); } elseif (\is_object($value) && \method_exists($value, '__toString')) { $converted[$field] = (string) $value; } elseif (\is_array($value) || \is_object($value)) { diff --git a/src/Traits/ValueObjects/HasFieldCastingTrait.php b/src/Traits/ValueObjects/HasFieldCastingTrait.php index 287f11e..0eaf937 100644 --- a/src/Traits/ValueObjects/HasFieldCastingTrait.php +++ b/src/Traits/ValueObjects/HasFieldCastingTrait.php @@ -27,7 +27,7 @@ trait HasFieldCastingTrait * @param array $fields - List of mapped Fields to be loaded. * @return void */ - private function castAttributesInitialValues(array $fields): void + protected function castAttributes(array $fields): void { // Loops through all the supplied Field's list. foreach ($fields as $field => $value) { @@ -59,7 +59,7 @@ final protected function createMutatorName(string $prefix, string $field): strin * * @return void */ - private function loadAttributeCastingList(): void + private function registerAttributeCastingList(): void { // Loops through all the class' methods, and loads the necessary ones in // the corresponding containers. diff --git a/src/Traits/ValueObjects/HasMappedFieldsTrait.php b/src/Traits/ValueObjects/HasMappedFieldsTrait.php index 700783a..c2c2b5a 100644 --- a/src/Traits/ValueObjects/HasMappedFieldsTrait.php +++ b/src/Traits/ValueObjects/HasMappedFieldsTrait.php @@ -15,11 +15,7 @@ */ trait HasMappedFieldsTrait { - /** - * @var array $maps - Attribute mapping array. - * - * Set your overrides as keys, and the attribute they're supposed to map as values for the array. - */ + /** @var array $maps - Set your overrides as keys, and the attribute they're supposed to map as values. */ protected array $maps = []; /** diff --git a/src/Traits/ValueObjects/HasRuleProcessingTrait.php b/src/Traits/ValueObjects/HasRuleProcessingTrait.php index d7ead2f..ec43a23 100644 --- a/src/Traits/ValueObjects/HasRuleProcessingTrait.php +++ b/src/Traits/ValueObjects/HasRuleProcessingTrait.php @@ -41,7 +41,7 @@ final protected function processRules(array $fields): array * * @return void */ - private function loadAttributeRuleList(): void + private function registerAttributeRuleList(): void { // Loops through all the class' methods, and loads the necessary ones in // the corresponding containers. From 665f1f0968cb4b48372e524b816064496a451ce1 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 28 Feb 2022 17:46:53 +0000 Subject: [PATCH 080/193] refactor: Refactor AbstractValueObject --- src/ValueObjects/AbstractValueObject.php | 71 ++++++++++++++++++------ 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php index 7077bb0..174ce1e 100644 --- a/src/ValueObjects/AbstractValueObject.php +++ b/src/ValueObjects/AbstractValueObject.php @@ -1,7 +1,10 @@ loadUsableFields(); - $this->loadAttributeCastingList(); - $this->loadAttributeRuleList(); + $this->registerUsableFields(); + $this->registerAttributeCastingList(); + $this->registerAttributeRuleList(); + $this->registerOnLoadEvents(); // Translates supplied fields, into existing ones. $mapped = $this->translateToMappedFields($fields); @@ -87,7 +88,7 @@ protected function loadInstance(array $fields): void // Validates and loads supplied data into class. $mapped = $this->processRules($mapped); $this->validateRequired($mapped); - $this->castAttributesInitialValues($mapped); + $this->castAttributes($mapped); } /** @@ -95,7 +96,7 @@ protected function loadInstance(array $fields): void * * @return void */ - private function loadUsableFields(): void + private function registerUsableFields(): void { $this->attributeList = $this->filterSystemControlFields( \get_object_vars($this) @@ -127,13 +128,28 @@ private function filterSystemControlFields(array $attrs): array * Retrieves a list containing all Value Object's fields. * * Returns an associative array containing all the fields from the Value Object. + * Nested Value Objects (records) will be included as a nested associative array. + * Datatype Value Objects will be converted to their primitive representation. * - * Arrays will be returned as JSON. - * - * Other objects will either be returned as their string representation, or they will - * be serialized. + * @return array + */ + public function toArray(): array + { + // Collects a list of usable Attributes from the Value Object. + $fields = $this->filterSystemControlFields( + \get_object_vars($this) + ); + + // Converts all objects into primitives. + return $this->convertIntoPrimitiveValues($fields); + } + + /** + * Retrieves a list containing all Value Object's fields. * - * Primitive types, or unserializable objects, will be returned in their current form. + * Returns an associative array only containing fields which belong directly to record. + * Nested Value Objects will not be returned. + * Datatype Value Objects will be converted to their primitive representation. * * @return array */ @@ -144,6 +160,12 @@ public function getAttributes(): array \get_object_vars($this) ); + foreach ($fields as $name => $value) { + if ($value instanceof AbstractValueObject || $value instanceof EntityCollection) { + unset($fields[$name]); + } + } + // Converts all objects into primitives. return $this->convertIntoPrimitiveValues($fields); } @@ -152,10 +174,15 @@ public function getAttributes(): array public function serialize(): string { return \serialize( - $this->getAttributes() + $this->toArray() ); } + public function __serialize(): array + { + return $this->toArray(); + } + /** @inheritDoc */ public function unserialize($serialized): void { @@ -164,6 +191,11 @@ public function unserialize($serialized): void ); } + public function __unserialize(array $data): void + { + $this->loadInstance($data); + } + /** * {@inheritDoc} * @@ -172,8 +204,13 @@ public function unserialize($serialized): void */ public function jsonSerialize(): \stdClass { + // Collects a list of usable Attributes from the Value Object. + $fields = $this->filterSystemControlFields( + \get_object_vars($this) + ); + return (object) $this->removeGuardedFields( - $this->getAttributes() + $this->convertIntoPrimitiveValues($fields, true) ); } } From aa10178394d4a960ea8d3c140195523c064f657e Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 28 Feb 2022 17:48:55 +0000 Subject: [PATCH 081/193] feat: Add State processing Traits --- .../Entities/CanProcessEntityStateTrait.php | 24 +++++++++++--- .../CanProcessOnUpdateEventsTrait.php | 31 ++++++++++++------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index 7ff9e33..abdf0f3 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -19,13 +19,11 @@ trait CanProcessEntityStateTrait /** * Event handler that will create a snapshot of object's current state. * - * eg:. This can be used as an handler for onLoad or onUpdate handlers. - * * Needs to be registered in the Entity's Constructor, before calling parent Constructor. * * @return void */ - private function onEventSnapshotState(): void + protected function onLoadSnapshotState(): void { $this->initialState = $this->getAttributes(); } @@ -48,9 +46,10 @@ final public function isDirty(): bool * * If the Entity is not marked as dirty, this will return an empty array. * + * @param bool $withTimestamps - In case dirty attributes include timestamps. Defaults to FALSE. * @return array */ - final public function getDirty(): array + final public function getDirty(bool $withTimestamps = false): array { // Loops through all the class' attributes, and validates if any has changed. $dirty = []; @@ -67,6 +66,11 @@ final public function getDirty(): array } } + /// Removes timestamps in case they exist, and they were not requested. + if (!$withTimestamps) { + unset($dirty['created_at'], $dirty['updated_at'], $dirty['deleted_at']); + } + // Returns all dirty attributes. return $dirty; } @@ -84,6 +88,16 @@ final public function getOriginal(): array return $this->initialState; } + /** + * Resets the instance's state, cleaning up "Dirty" attributes, and reset tracking. + * + * @return void + */ + final public function resetState(): void + { + $this->initialState = $this->getAttributes(); + } + /** * Sets new values to a set of class attributes, all at once. * @@ -112,7 +126,7 @@ final public function setAttributes(array $fields): void // Process supplied fields. $mapped = $this->translateToMappedFields($fields); $this->processRules($mapped); - $this->loadAttributes($mapped); + $this->castAttributes($mapped); if (\method_exists($this, 'triggerOnUpdate')) { $this->{'triggerOnUpdate'}(); diff --git a/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php b/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php index 33ba54e..689e754 100644 --- a/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php +++ b/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php @@ -4,12 +4,13 @@ namespace HraDigital\Datatypes\Traits\Entities; -use Closure; - /** * Gives onUpdate event handling capabilities to class. * - * To register an new handler for the onUpdate event, use $this->onUpdate(function() { $this->someCall() }); + * To register an new handler for the onUpdate event, declare a protected method starting with "onUpdate". + * + * When you Update the state of your object, you should also call triggerOnUpdate(), so that other fields + * can react to the change. * * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes @@ -17,29 +18,37 @@ */ trait CanProcessOnUpdateEventsTrait { + /** Sets the onUpdate Mutator method's prefix. */ + private static $ONUPDATEPREFIX = 'onUpdate'; + /** @var array $onUpdateEvents - List of onUpdate event handlers, defined as closures. */ private array $onUpdateEvents = []; /** - * Triggers all onUpdate pre-declared events. + * Uses an onLoad() event handler, to load any onUpdate() methods available in the class. * * @return void */ - protected function triggerOnUpdate(): void + protected function onLoadRegisterOnUpdateEvents(): void { - foreach ($this->onUpdateEvents as $onUpdate) { - $onUpdate(); + // Loops through all the class' methods, and loads the necessary ones in + // the corresponding containers. + foreach (\get_class_methods($this) as $method) { + if (\strpos($method, self::$ONUPDATEPREFIX) === 0 && \strlen($method) > \strlen(self::$ONUPDATEPREFIX)) { + $this->onUpdateEvents[] = $method; + } } } /** - * Adds a new onUpdate event handler to the class. + * Triggers all onUpdate pre-declared events. * - * @param Closure $handler - Closure that will be triggered onUpdate. * @return void */ - protected function onUpdate(Closure $handler): void + protected function triggerOnUpdate(): void { - $this->onUpdateEvents[] = $handler; + foreach ($this->onUpdateEvents as $onUpdate) { + $onUpdate(); + } } } From afd3b075c03b6820db8df01601e723731fea0e30 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 28 Feb 2022 17:49:55 +0000 Subject: [PATCH 082/193] feat: Add more generic Traits --- .../Entities/General/HasPublishedTrait.php | 2 +- .../Entities/General/HasSeoFieldsTrait.php | 2 +- src/Traits/Entities/General/HasTitleTrait.php | 50 ++++++++++++++++++ src/Traits/Entities/Location/HasCityTrait.php | 23 ++++++--- .../Entities/Location/HasDistrictTrait.php | 50 ++++++++++++++++++ .../Entities/Location/HasParishTrait.php | 50 ++++++++++++++++++ .../Entities/Personal/HasGenderTrait.php | 24 +++++---- .../Entities/Personal/HasNationalityTrait.php | 48 +++++++++++++++++ .../Professional/HasIndustryTrait.php | 51 +++++++++++++++++++ 9 files changed, 281 insertions(+), 19 deletions(-) create mode 100755 src/Traits/Entities/General/HasTitleTrait.php create mode 100644 src/Traits/Entities/Location/HasDistrictTrait.php create mode 100644 src/Traits/Entities/Location/HasParishTrait.php create mode 100644 src/Traits/Entities/Personal/HasNationalityTrait.php create mode 100755 src/Traits/Entities/Professional/HasIndustryTrait.php diff --git a/src/Traits/Entities/General/HasPublishedTrait.php b/src/Traits/Entities/General/HasPublishedTrait.php index b4c2649..8087f7b 100755 --- a/src/Traits/Entities/General/HasPublishedTrait.php +++ b/src/Traits/Entities/General/HasPublishedTrait.php @@ -22,7 +22,7 @@ trait HasPublishedTrait * @param bool $published - New published value. * @return void */ - protected function castPublished(bool $published): void + protected function castIsPublished(bool $published): void { $this->is_published = $published; } diff --git a/src/Traits/Entities/General/HasSeoFieldsTrait.php b/src/Traits/Entities/General/HasSeoFieldsTrait.php index 7bf52ee..753cc8b 100755 --- a/src/Traits/Entities/General/HasSeoFieldsTrait.php +++ b/src/Traits/Entities/General/HasSeoFieldsTrait.php @@ -40,7 +40,7 @@ trait HasSeoFieldsTrait protected function castSeoTitle(?string $title = null): void { // Setting the max length for Seo description. - $titleValue = ($title ? Str::create($title)->trim() ? null); + $titleValue = ($title ? Str::create($title)->trim() : null); if ($titleValue !== null && $titleValue->getLength() > 70) { throw new NonEmptyStringException("Supplied Seo title must have length up to 70 characters."); diff --git a/src/Traits/Entities/General/HasTitleTrait.php b/src/Traits/Entities/General/HasTitleTrait.php new file mode 100755 index 0000000..eafdffe --- /dev/null +++ b/src/Traits/Entities/General/HasTitleTrait.php @@ -0,0 +1,50 @@ +trim(); + if ($titleValue->getLength() === 0) { + throw new NonEmptyStringException('$title'); + } + + $this->title = $titleValue; + } + + /** + * Returns the Instance's Title. + * + * @return Str + */ + public function getTitle(): Str + { + return $this->title; + } +} diff --git a/src/Traits/Entities/Location/HasCityTrait.php b/src/Traits/Entities/Location/HasCityTrait.php index e0d8f35..52f6744 100644 --- a/src/Traits/Entities/Location/HasCityTrait.php +++ b/src/Traits/Entities/Location/HasCityTrait.php @@ -4,6 +4,7 @@ namespace HraDigital\Datatypes\Traits\Entities\Location; +use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; /** @@ -15,26 +16,34 @@ */ trait HasCityTrait { - /** @var Str $city - City */ - protected Str $city; + /** @var Str|null $city - City */ + protected ?Str $city; /** * Mutator method for setting the value into the Attribute. * - * @param string $city - City. + * @param string|null $city - City. + * + * @throws NonEmptyStringException - If supplied value is not a non empty string. * @return void */ - protected function castCity(string $city): void + protected function castCity(?string $city): void { - $this->city = Str::create($city)->trim(); + $cityValue = $city ? Str::create($city)->trim() : null; + + if ($cityValue !== null && $cityValue->getLength() === 0) { + throw new NonEmptyStringException('$city'); + } + + $this->city = $cityValue; } /** * Returns the Entity's City. * - * @return Str + * @return Str|null */ - public function getCity(): Str + public function getCity(): ?Str { return $this->city; } diff --git a/src/Traits/Entities/Location/HasDistrictTrait.php b/src/Traits/Entities/Location/HasDistrictTrait.php new file mode 100644 index 0000000..377f5ce --- /dev/null +++ b/src/Traits/Entities/Location/HasDistrictTrait.php @@ -0,0 +1,50 @@ +trim() : null; + + if ($districtValue !== null && $districtValue->getLength() === 0) { + throw new NonEmptyStringException('$district'); + } + + $this->district = $districtValue; + } + + /** + * Returns the Entity's District. + * + * @return Str|null + */ + public function getDistrict(): ?Str + { + return $this->district; + } +} diff --git a/src/Traits/Entities/Location/HasParishTrait.php b/src/Traits/Entities/Location/HasParishTrait.php new file mode 100644 index 0000000..e3f5254 --- /dev/null +++ b/src/Traits/Entities/Location/HasParishTrait.php @@ -0,0 +1,50 @@ +trim() : null; + + if ($parishValue !== null && $parishValue->getLength() === 0) { + throw new NonEmptyStringException('$parish'); + } + + $this->parish = $parishValue; + } + + /** + * Returns the Entity's Parish. + * + * @return Str|null + */ + public function getParish(): ?Str + { + return $this->parish; + } +} diff --git a/src/Traits/Entities/Personal/HasGenderTrait.php b/src/Traits/Entities/Personal/HasGenderTrait.php index 27fc1dc..a745270 100644 --- a/src/Traits/Entities/Personal/HasGenderTrait.php +++ b/src/Traits/Entities/Personal/HasGenderTrait.php @@ -16,25 +16,29 @@ */ trait HasGenderTrait { - /** @var Str $sex - Gender */ - protected Str $sex; + /** @var Str $gender - Gender */ + protected Str $gender; /** * Mutator method for setting the value into the Attribute. * - * @param string $sex - Gender. + * @param string $gender - Gender. * @return void */ - protected function castSex(string $sex): void + protected function castGender(string $gender): void { // Sanitizes and checks supplied value. - $sexValue = Str::create($sex)->toLower()->toUpperFirst(); - - if (!$sexValue->equals(Str::create('Male')) && !$sexValue->equals(Str::create('Female'))) { - throw new UnexpectedEntityValueException('$sex'); + $genderValue = Str::create($gender)->toLower()->toUpperFirst(); + + if (!( + $genderValue->equals(Str::create('Male')) || + $genderValue->equals(Str::create('Female')) || + $genderValue->equals(Str::create('Other')) + )) { + throw new UnexpectedEntityValueException('$gender'); } - $this->sex = $sex; + $this->gender = $genderValue; } /** @@ -44,6 +48,6 @@ protected function castSex(string $sex): void */ public function getGender(): Str { - return $this->sex; + return $this->gender; } } diff --git a/src/Traits/Entities/Personal/HasNationalityTrait.php b/src/Traits/Entities/Personal/HasNationalityTrait.php new file mode 100644 index 0000000..fe97da0 --- /dev/null +++ b/src/Traits/Entities/Personal/HasNationalityTrait.php @@ -0,0 +1,48 @@ +trim() : null; + + if ($nationalityValue !== null && $nationalityValue->getLength() === 0) { + throw new NonEmptyStringException('$nationality'); + } + + $this->nationality = $nationalityValue; + } + + /** + * Returns the Entity's Nationality. + * + * @return Str|null + */ + public function getNationality(): ?Str + { + return $this->nationality; + } +} diff --git a/src/Traits/Entities/Professional/HasIndustryTrait.php b/src/Traits/Entities/Professional/HasIndustryTrait.php new file mode 100755 index 0000000..a426f34 --- /dev/null +++ b/src/Traits/Entities/Professional/HasIndustryTrait.php @@ -0,0 +1,51 @@ +trim() : null; + + if ($industryValue !== null && $industryValue->getLength() === 0) { + throw new NonEmptyStringException('$occupation'); + } + + $this->industry = $industryValue; + } + + /** + * Returns the Instance's Profile's Industry. + * + * @return Str|null + */ + public function getIndustry(): ?Str + { + return $this->industry; + } +} From 52e1ef3c28711c1f4c1250e66ae588a8a44ac745 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 28 Feb 2022 17:50:42 +0000 Subject: [PATCH 083/193] fix: Fix namespace --- tests/AbstractBaseTestCase.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/AbstractBaseTestCase.php b/tests/AbstractBaseTestCase.php index c41019c..ce7450a 100644 --- a/tests/AbstractBaseTestCase.php +++ b/tests/AbstractBaseTestCase.php @@ -1,6 +1,8 @@ - Date: Mon, 28 Feb 2022 17:51:11 +0000 Subject: [PATCH 084/193] tests: Add Unit test for Str --- tests/Unit/Scalar/StrTest.php | 528 ++++++++++++++++++++++++++++++++++ 1 file changed, 528 insertions(+) create mode 100644 tests/Unit/Scalar/StrTest.php diff --git a/tests/Unit/Scalar/StrTest.php b/tests/Unit/Scalar/StrTest.php new file mode 100644 index 0000000..0a8af53 --- /dev/null +++ b/tests/Unit/Scalar/StrTest.php @@ -0,0 +1,528 @@ +assertFalse( + ($original === $other), + 'Instances are not meant to match.' + ); + } + + /** @inheritDoc */ + protected function checkCorrectInstanceType(AbstractBaseString $instance): void + { + $this->assertInstanceOf( + Str::class, + $instance, + 'Instance type, does not match Str.' + ); + } + + /** + * Checks Equality of two distinct strings. + * + * @return void + */ + public function testCanCheckEquality(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $this->getInstance(" Immutable string. "); + + // Performs assertions. + $this->assertTrue( + $original->equals($other), + 'Instance values do not match.' + ); + } + + /** + * Tests that we can check of String contains a text portion. + * + * @return void + */ + public function testCanCheckIfStringContainsPortion(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + + // Performs assertions. + $this->assertTrue( + $original->contains( + $this->getInstance('muta') + ), + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($original); + } + + /** + * Tests that method breaks if invalid parameters are passed. + * + * @return void + */ + public function testBreaksCheckingIfStringContainsPortionWithEmptyText(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + + // Create expectations. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original->contains( + $this->getInstance('') + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testCanRetrieveIndexOf(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $indexOf = $instance->indexOf( + $this->getInstance('string') + ); + + // Performs assertions. + $this->assertEquals( + 10, + $indexOf, + 'Retrieved index is incorrect.' + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testCanRetrieveIndexOfWithStart(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $indexOf = $instance->indexOf( + $this->getInstance('string'), + 15 + ); + + // Performs assertions. + $this->assertEquals( + 37, + $indexOf, + 'Retrieved index is incorrect.' + ); + } + + /** + * Test indexOf() method. + * + * @return void + */ + public function testIndexOfReturnsNullIfNotFound(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $indexOf = $instance->indexOf( + $this->getInstance('another') + ); + + // Performs assertions. + $this->assertNull( + $indexOf, + 'Retrieved index should have been NULL.' + ); + } + + /** + * Test indexOf() breaks with illegal parameters. + * + * @return void + */ + public function testBreaksIndexOfIfEmptySearch(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->indexOf($this->getInstance('')); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testCanCheckIfStringStartsWithText(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $true = $instance->startsWith($this->getInstance("Immu")); + $false = $instance->startsWith($this->getInstance("string")); + + // Performs assertions. + $this->assertTrue($true, 'String should have started with searched text.'); + $this->assertFalse($false, 'String should not have started with searched text.'); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testBreaksCheckingIfStringStartsWithText(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->startsWith($this->getInstance('')); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testCanCheckIfStringEndsWithText(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string."); + $true = $instance->endsWith($this->getInstance("string.")); + $false = $instance->endsWith($this->getInstance("Immu")); + + // Performs assertions. + $this->assertTrue($true, 'String should have ended with searched text.'); + $this->assertFalse($false, 'String should not have ended with searched text.'); + } + + /** + * Tests that we can check is a string begins with a given text. + * + * @return void + */ + public function testBreaksCheckingIfStringEndsWithText(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string."); + $instance->endsWith($this->getInstance('')); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInString(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count($this->getInstance('string')); + + // Performs assertions. + $this->assertEquals( + 2, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInStringWithStartAndLength(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count($this->getInstance('string'), 15, 29); + + // Performs assertions. + $this->assertEquals( + 1, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() method. + * + * @return void + */ + public function testCanCountNumberOccurencesInStringIfNoneIsFound(): void + { + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $count = $instance->count($this->getInstance('string'), 38, 4); + + // Performs assertions. + $this->assertEquals( + 0, + $count, + 'Retrieved count is incorrect.' + ); + } + + /** + * Tests count() breaks if empty search is supplied. + * + * @return void + */ + public function testBreaksCountNumberOccurencesInStringIfSerachIsEmpty(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $instance = $this->getInstance("Immutable string, or part of another string."); + $instance->count($this->getInstance('')); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksPaddingOnTheLeftWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padLeft(2, $this->getInstance('')); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPaddingOnTheLeftExtraWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padLeftExtra(2, $this->getInstance('')); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeftWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeft(\strlen($string) + 2, $this->getInstance('_')); + + // Performs assertions. + $this->assertEquals( + '__Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeftExtraWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeftExtra(2, $this->getInstance('_')); + + // Performs assertions. + $this->assertEquals( + '__Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPadOnTheRightWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padRight(2, $this->getInstance('')); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksCanPadOnTheRightExtraWithInvalidPadString(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padRightExtra(2, $this->getInstance('')); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRightWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRight(\strlen($string) + 2, $this->getInstance('_')); + + // Performs assertions. + $this->assertEquals( + 'Immutable String.__', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRightExtraWidthCharacter(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRightExtra(2, $this->getInstance('_')); + + // Performs assertions. + $this->assertEquals( + 'Immutable String.__', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text can be replaced in the String. + * + * @return void + */ + public function testTextCanBeReplacedInString(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->replace( + $this->getInstance('String'), + $this->getInstance('Object') + ); + + // Performs assertions. + $this->assertEquals( + 'Immutable Object.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text is not replaced if search is not found. + * + * @return void + */ + public function testTextIsNotReplacedIfSearchNotFound(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->replace( + $this->getInstance('None'), + $this->getInstance('Object') + ); + + // Performs assertions. + $this->assertEquals( + (string) $original, + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that text replace breaks. + * + * @return void + */ + public function testBreaksTextReplaceIfSearchIsEmpty(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->replace($this->getInstance(''), $this->getInstance('Object')); + } +} From 7572a0bb233b966355cc2b6ef46e25c385768a63 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 28 Feb 2022 17:51:35 +0000 Subject: [PATCH 085/193] tests: Add Unit tests for AbstractValueObject --- .../ValueObjects/AbstractValueObjectTest.php | 118 ++++++++++++++++++ .../ValueObjects/TestingNestedValueObject.php | 26 ++++ .../Unit/ValueObjects/TestingValueObject.php | 83 ++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 tests/Unit/ValueObjects/AbstractValueObjectTest.php create mode 100644 tests/Unit/ValueObjects/TestingNestedValueObject.php create mode 100644 tests/Unit/ValueObjects/TestingValueObject.php diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php new file mode 100644 index 0000000..10074ab --- /dev/null +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -0,0 +1,118 @@ +assertFalse(TestingValueObject::DATA['is_active']); + $this->assertTrue($valueObject->isActive()); + + // Test Rule's processing works. + $this->assertEquals( + 'MY OUTTER TITLE', + (string) $valueObject->getTitle()->toUpper() + ); + + // Test field casting works. + $this->assertInstanceOf(Str::class, $valueObject->getTitle()); + } + + public function testBreaksIfRequiredFieldIsMissing(): void + { + $data = TestingValueObject::DATA; + unset($data['is_active']); + + $this->expectException(RequiredEntityValueMissingException::class); + + new TestingValueObject($data); + } + + public function testCanRetrieveFirstLevelAttributes(): void + { + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + $attributes = $valueObject->getAttributes(); + + $this->assertArrayHasKey('active', $attributes); + $this->assertArrayHasKey('email', $attributes); + $this->assertArrayHasKey('title', $attributes); + $this->assertArrayNotHasKey('inner', $attributes); + } + + public function testCanConvertToJsonWhileGuardingCertainAttributes(): void + { + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + $json = \json_decode( + \json_encode($valueObject), + true + ); + + $this->assertArrayHasKey('active', $json); + $this->assertArrayNotHasKey('email', $json); + $this->assertArrayHasKey('title', $json); + $this->assertArrayHasKey('inner', $json); + + $this->assertArrayHasKey('title', $json['inner']); + $this->assertArrayNotHasKey('active', $json['inner']); + } + + public function testCanConvertToArray(): void + { + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + $array = $valueObject->toArray(); + + $this->assertArrayHasKey('active', $array); + $this->assertArrayHasKey('email', $array); + $this->assertArrayHasKey('title', $array); + $this->assertArrayHasKey('inner', $array); + + $this->assertArrayHasKey('title', $array['inner']); + $this->assertArrayHasKey('active', $array['inner']); + } + + public function testCanSerializeAndUnserialize(): void + { + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + + $serialized = \serialize($valueObject); + $unserialized = \unserialize($serialized); + + $this->assertInstanceOf(TestingValueObject::class, $valueObject); + $this->assertInstanceOf(TestingValueObject::class, $unserialized); + $this->assertEquals( + $valueObject->isActive(), + $unserialized->isActive() + ); + $this->assertEquals( + (string) $valueObject->getTitle(), + (string) $unserialized->getTitle() + ); + } +} diff --git a/tests/Unit/ValueObjects/TestingNestedValueObject.php b/tests/Unit/ValueObjects/TestingNestedValueObject.php new file mode 100644 index 0000000..494264f --- /dev/null +++ b/tests/Unit/ValueObjects/TestingNestedValueObject.php @@ -0,0 +1,26 @@ + false, + 'address' => 'user@domain.tld', + 'title' => 'my title', + 'inner' => [ + 'active' => true, + 'title' => 'My Inner Title', + ], + ]; + + use HasActiveTrait, + HasEmailTrait, + HasTitleTrait; + + /** @var array $guarded - List of fields that should not be serializable into JSON. */ + protected array $guarded = ['email']; + + protected array $maps = [ + 'is_active' => 'active', + 'address' => 'email', + ]; + + protected array $required = [ + 'active', + 'email', + 'title', + ]; + + protected TestingNestedValueObject $inner; + + protected function castInner(array $inner): void + { + $this->inner = new TestingNestedValueObject($inner); + } + + protected function getInner(): TestingNestedValueObject + { + return $this->inner; + } + + /** + * Initial Rule's testing method. + * + * @param array $fields - Original fields being loaded into the Value Object. + * @return array + */ + protected function ruleTestingMethod(array $fields): array + { + $fields['title'] = 'My Outter Title'; + + return $fields; + } + + /** + * onLoad's testing handler. + * + * @return void + */ + protected function onLoadActivateValueObjectHandler(): void + { + $this->active = true; + } +} From 389e211f0c3f841d5e95d0131fb0e08b6607109c Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Mar 2022 17:24:25 +0000 Subject: [PATCH 086/193] feat: Add doExplode() --- src/Scalar/AbstractBaseString.php | 41 +++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 095b65a..6f171bf 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -216,10 +216,10 @@ private function validateStartAndLength(int $start, ?int $length): void { // Calculates the absolute values for validations. $absStart = (int) \abs($start); - $absLength = (int) \abs($length); + $absLength = $length ? (int) \abs($length) : null; // Validates the starting value. - if ($absStart > $this->length()) { + if ($absStart > $this->getLength()) { throw new ParameterOutOfRangeException('$start'); } @@ -229,7 +229,7 @@ private function validateStartAndLength(int $start, ?int $length): void } // Checks if the supplied $length, doesn't exceed the available number of characters. - if (($start >= 0 && ($this->length() - $start < $absLength)) || + if (($start >= 0 && ($this->getLength() - $start < $absLength)) || ($start < 0 && $absLength > $absStart)) { throw new ParameterOutOfRangeException('$length'); @@ -364,7 +364,7 @@ protected function doPadLeft(int $length, string $padding = " "): string */ protected function doPadLeftExtra(int $length, string $padding = " "): string { - return $this->doPadLeft(($this->length() + $length), $padding); + return $this->doPadLeft(($this->getLength() + $length), $padding); } /** @@ -414,7 +414,7 @@ protected function doPadRight(int $length, string $padding = " "): string */ protected function doPadRightExtra(int $length, string $padding = " "): string { - return $this->doPadRight(($this->length() + $length), $padding); + return $this->doPadRight(($this->getLength() + $length), $padding); } /** @@ -529,4 +529,35 @@ protected function doReplace(string $search, string $replace): string return \str_replace($search, $replace, $this->value); } + + /** + * Returns an array of strings, each of which is a substring of string formed + * by splitting it on boundaries formed by the string separator. + * + * If limit is set and positive, the returned array will contain a maximum of limit + * elements with the last element containing the rest of string. + * + * If the limit parameter is negative, all components except the last -limit are returned. + * + * If the limit parameter is zero, then this is treated as 1. + * + * @param string $separator - The boundary string. + * @param int|null $limit - The limit of returned segments. + * + * @throws NonEmptyStringException - If $separator is an empty string. + * @return array|Str[] + */ + protected function doExplode(string $separator, ?int $limit): array + { + // Validates supplied parameters. + if (\strlen($separator) === 0) { + throw new NonEmptyStringException('$separator'); + } + + if ($limit === null) { + return \explode($separator, $this->value); + } + + return \explode($separator, $this->value, $limit); + } } From 3bbdaf2992c4d46d2f2b2aaab4926a65b258fb22 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 2 Mar 2022 17:24:55 +0000 Subject: [PATCH 087/193] tests: Fix namespaces --- .../Scalar/AbstractBaseStringTestBase.php | 20 ++++++++++--------- tests/Unit/Web/EmailAddressTest.php | 10 +++++----- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/Unit/Scalar/AbstractBaseStringTestBase.php b/tests/Unit/Scalar/AbstractBaseStringTestBase.php index a179507..649c4bb 100644 --- a/tests/Unit/Scalar/AbstractBaseStringTestBase.php +++ b/tests/Unit/Scalar/AbstractBaseStringTestBase.php @@ -1,12 +1,14 @@ -assertEquals( \strlen($string), - $instance->length(), + $instance->getLength(), 'Instance character length does not seam to match.' ); } @@ -99,7 +101,7 @@ public function testCanRetrieveWordCountCorrectly(): void // Performs assertions. $this->assertEquals( 5, - $instance->wordCount(), + $instance->getWordCount(), 'Instance word count does not seam to match.' ); } diff --git a/tests/Unit/Web/EmailAddressTest.php b/tests/Unit/Web/EmailAddressTest.php index 2e5e3ff..0cb7c71 100644 --- a/tests/Unit/Web/EmailAddressTest.php +++ b/tests/Unit/Web/EmailAddressTest.php @@ -1,11 +1,11 @@ Date: Wed, 2 Mar 2022 17:37:00 +0000 Subject: [PATCH 088/193] refactor: Replace AbstractEntity for AbstractValueObject --- src/Collections/Linear/EntityCollection.php | 29 +++++++++++---------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Collections/Linear/EntityCollection.php b/src/Collections/Linear/EntityCollection.php index e7773e0..74725ac 100644 --- a/src/Collections/Linear/EntityCollection.php +++ b/src/Collections/Linear/EntityCollection.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Collections\Linear; +use HraDigital\Datatypes\ValueObjects\AbstractValueObject; + /** * Entity Collection class. * @@ -55,9 +57,9 @@ public function has(int $id): bool * * @throws \OutOfRangeException - If the supplied ID is not a positive integer. * @throws \OutOfBoundsException - If the supplied ID was not present in the Collection. - * @return AbstractEntity + * @return AbstractValueObject */ - public function get(int $id): AbstractEntity + public function get(int $id): AbstractValueObject { // Validates supplied ID. if ($id <= 0) { @@ -109,24 +111,24 @@ public function ids(): array } /** - * Adds a new Entity to the Collection. + * Adds a new Value Object to the Collection. * * This method supports chaining. * - * @param AbstractEntity $entity - Entity to add to the collection. + * @param AbstractValueObject $valueObject - Entity to add to the collection. * * @throws \OverflowException - If you're trying to add a repeated Entity to the Collection. * @return self */ - public function add(AbstractEntity $entity): self + public function add(AbstractValueObject $valueObject): self { // Validates if the given Entity already exists in the Collection. - if (\array_key_exists($entity->id(), $this->collection)) { - throw new \OverflowException("The Entity you are trying to add to the Collection already exists."); + if (\array_key_exists($valueObject->{'getId'}(), $this->collection)) { + throw new \OverflowException("The Value Object you are trying to add to the Collection already exists."); } // Adds an Entity to the collection. - $this->collection[$entity->id()] = $entity; + $this->collection[$valueObject->{'getId'}()] = $valueObject; // Returns this instance. return $this; @@ -168,7 +170,7 @@ public function remove(int $id): bool * {@inheritDoc} * @see \Iterator::rewind() */ - public function rewind(): ?AbstractEntity + public function rewind(): ?AbstractValueObject { // Rewinds the cursor and returns the first Element. if (($element = \reset($this->collection)) !== false) { @@ -184,7 +186,7 @@ public function rewind(): ?AbstractEntity * {@inheritDoc} * @see \Iterator::current() */ - public function current(): ?AbstractEntity + public function current(): ?AbstractValueObject { // If retrieving the current element fails, we'll still try to rewind the // pointer and return the first element. @@ -262,11 +264,10 @@ public function jsonSerialize(): array { // Declares and fills a return array. $array = []; - foreach ($this->collection as $entity) { + foreach ($this->collection as $valueObject) { - /** @var AbstractEntity $entity - Type casts record */ - $entity = $entity; - $array[] = $entity->jsonSerialize(); + /** @var AbstractValueObject $valueObject - Type casts record */ + $array[] = $valueObject->jsonSerialize(); } return $array; From 73b65264e9b314ac8ff79e00a9ba9d2357c75654 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Thu, 3 Mar 2022 17:38:07 +0000 Subject: [PATCH 089/193] refactor: Refactor Exception's instantiations --- src/Exceptions/ConflictException.php | 2 -- .../InvalidDateIntervalException.php | 27 ++++++++++++++++ .../Datatypes/InvalidEmailException.php | 10 ++++-- .../InvalidStringLengthException.php | 10 ++++-- .../Datatypes/NonEmptyStringException.php | 10 ++++-- .../Datatypes/NonNegativeNumberException.php | 10 ++++-- .../ParameterOutOfRangeException.php | 10 ++++-- .../Datatypes/PositiveIntegerException.php | 10 ++++-- src/Exceptions/DeniedAccessException.php | 3 -- .../RequiredEntityValueMissingException.php | 10 ++++-- .../UnexpectedEntityValueException.php | 10 ++++-- src/Exceptions/ExpectationFailedException.php | 3 -- src/Exceptions/FailedDependencyException.php | 3 -- src/Exceptions/ForbiddenException.php | 3 -- src/Exceptions/GoneException.php | 15 ++++----- src/Exceptions/MethodNotAllowedException.php | 3 -- src/Exceptions/NotAcceptableException.php | 3 -- src/Exceptions/NotFoundException.php | 17 ++++------ .../PreconditionFailedException.php | 3 -- .../PreconditionRequiredException.php | 3 -- .../RequestedRangeNotSatisfiableException.php | 3 -- src/Exceptions/TooManyRequestsException.php | 3 -- .../UnprocessableEntityException.php | 16 +++------- .../UnsupportedMediaTypeException.php | 16 +++------- src/Scalar/AbstractBaseString.php | 32 +++++++++---------- src/Traits/Entities/General/HasAliasTrait.php | 2 +- src/Traits/Entities/General/HasHitsTrait.php | 2 +- src/Traits/Entities/General/HasNameTrait.php | 2 +- .../Entities/General/HasOrderingTrait.php | 2 +- .../Entities/General/HasSeoFieldsTrait.php | 10 +++--- src/Traits/Entities/General/HasTitleTrait.php | 2 +- src/Traits/Entities/Location/HasCityTrait.php | 2 +- .../Entities/Location/HasDistrictTrait.php | 2 +- .../Entities/Location/HasParishTrait.php | 2 +- .../Personal/HasCountryOfBirthTrait.php | 2 +- .../Entities/Personal/HasNationalityTrait.php | 2 +- .../Entities/Personal/HasPhotoTrait.php | 2 +- .../Entities/Personal/HasSurnameTrait.php | 2 +- .../Professional/HasIndustryTrait.php | 2 +- .../Professional/HasOccupationTrait.php | 2 +- src/Web/EmailAddress.php | 4 +-- 41 files changed, 143 insertions(+), 134 deletions(-) create mode 100644 src/Exceptions/Datatypes/InvalidDateIntervalException.php diff --git a/src/Exceptions/ConflictException.php b/src/Exceptions/ConflictException.php index 01f1274..03907f0 100755 --- a/src/Exceptions/ConflictException.php +++ b/src/Exceptions/ConflictException.php @@ -20,10 +20,8 @@ */ class ConflictException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "The action failed due to a conflict in the provided request."; - /** @var int $code - Exception's error code. */ protected $code = 409; /** diff --git a/src/Exceptions/Datatypes/InvalidDateIntervalException.php b/src/Exceptions/Datatypes/InvalidDateIntervalException.php new file mode 100644 index 0000000..71cfc1b --- /dev/null +++ b/src/Exceptions/Datatypes/InvalidDateIntervalException.php @@ -0,0 +1,27 @@ +messageWithId, $id) : $this->message), + return new self( + \sprintf("The resource with the ID %d no longer exists in the system.", $id), $inner ); } diff --git a/src/Exceptions/MethodNotAllowedException.php b/src/Exceptions/MethodNotAllowedException.php index f33ca7c..cd102e9 100755 --- a/src/Exceptions/MethodNotAllowedException.php +++ b/src/Exceptions/MethodNotAllowedException.php @@ -22,10 +22,7 @@ */ class MethodNotAllowedException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "The action failed due using a request method not supported by that resource."; - - /** @var int $code - Exception's error code. */ protected $code = 405; /** diff --git a/src/Exceptions/NotAcceptableException.php b/src/Exceptions/NotAcceptableException.php index 551ad58..2a2cd0a 100644 --- a/src/Exceptions/NotAcceptableException.php +++ b/src/Exceptions/NotAcceptableException.php @@ -20,10 +20,7 @@ */ class NotAcceptableException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "The operation you're trying to perform, is not acceptable."; - - /** @var int $code - Exception's error code. */ protected $code = 406; /** diff --git a/src/Exceptions/NotFoundException.php b/src/Exceptions/NotFoundException.php index b0c54d7..0e46ba9 100755 --- a/src/Exceptions/NotFoundException.php +++ b/src/Exceptions/NotFoundException.php @@ -21,25 +21,22 @@ class NotFoundException extends AbstractBaseException /** @var string $message - Exception's error message. */ protected $message = "The resource you are looking for, was not found in the system."; - /** @var string $message - Exception's error message when a record ID is specified. */ - protected string $messageWithId = "The resource with the ID %d you are looking for, was not found in the system."; - /** @var int $code - Exception's error code. */ protected $code = 404; /** - * Initializes Base NotFound Exception. + * Initializes Base Record Not Found Exception. * * Code value will be collected from defined class attribute. * - * @param int|null $id - Optional record ID that was not found in the system. - * @param \Exception|null $inner - Optional previous Exception in the stack, for Exception's nesting. - * @return void + * @param int $id + * @param \Exception|null $inner + * @return self */ - public function __construct(?int $id = null, ?\Exception $inner = null) + public static function withId(int $id, ?\Exception $inner = null): self { - parent::__construct( - ($id !== null ? \sprintf($this->messageWithId, $id) : $this->message), + return new self( + \sprintf("The resource with the ID %d you are looking for, was not found in the system.", $id), $inner ); } diff --git a/src/Exceptions/PreconditionFailedException.php b/src/Exceptions/PreconditionFailedException.php index 96c73d1..2b90f85 100755 --- a/src/Exceptions/PreconditionFailedException.php +++ b/src/Exceptions/PreconditionFailedException.php @@ -20,10 +20,7 @@ */ class PreconditionFailedException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "A given precondition evaluated to false on the system."; - - /** @var int $code - Exception's error code. */ protected $code = 412; /** diff --git a/src/Exceptions/PreconditionRequiredException.php b/src/Exceptions/PreconditionRequiredException.php index f2e05a7..c4461e6 100644 --- a/src/Exceptions/PreconditionRequiredException.php +++ b/src/Exceptions/PreconditionRequiredException.php @@ -15,10 +15,7 @@ */ class PreconditionRequiredException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "A given required precondition evaluated to false on the system."; - - /** @var int $code - Exception's error code. */ protected $code = 428; /** diff --git a/src/Exceptions/RequestedRangeNotSatisfiableException.php b/src/Exceptions/RequestedRangeNotSatisfiableException.php index 420ec5a..d421b86 100644 --- a/src/Exceptions/RequestedRangeNotSatisfiableException.php +++ b/src/Exceptions/RequestedRangeNotSatisfiableException.php @@ -21,10 +21,7 @@ */ class RequestedRangeNotSatisfiableException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "The requested range for the operation you're trying to perform, is not satisfiable."; - - /** @var int $code - Exception's error code. */ protected $code = 416; /** diff --git a/src/Exceptions/TooManyRequestsException.php b/src/Exceptions/TooManyRequestsException.php index 1069eeb..e23b94f 100755 --- a/src/Exceptions/TooManyRequestsException.php +++ b/src/Exceptions/TooManyRequestsException.php @@ -20,10 +20,7 @@ */ class TooManyRequestsException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "Too many requests have been made to the system."; - - /** @var int $code - Exception's error code. */ protected $code = 429; /** diff --git a/src/Exceptions/UnprocessableEntityException.php b/src/Exceptions/UnprocessableEntityException.php index 1104dae..ed134f9 100644 --- a/src/Exceptions/UnprocessableEntityException.php +++ b/src/Exceptions/UnprocessableEntityException.php @@ -21,13 +21,7 @@ */ class UnprocessableEntityException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "The request was well-formed but was unable to be followed due to semantic errors."; - - /** @var string $messageWithName - Exception's error message when an attribute name is supplied. */ - protected string $messageWithName = "The request was well-formed but was unable to be followed due to field '%s'."; - - /** @var int $code - Exception's error code. */ protected $code = 422; /** @@ -35,14 +29,14 @@ class UnprocessableEntityException extends AbstractBaseException * * Code value will be collected from defined class attribute. * - * @param string|null $name - Optional attribute name that could't be processed. + * @param string $name - Attribute's name that could't be processed. * @param \Exception|null $inner - Optional previous Exception in the stack, for Exception's nesting. - * @return void + * @return self */ - public function __construct(?string $name = null, ?\Exception $inner = null) + public static function withName(string $name, ?\Exception $inner = null): self { - parent::__construct( - ($name !== null ? \sprintf($this->messageWithName, $name) : $this->message), + return new self( + \sprintf("The request was well-formed but was unable to be followed due to field '%s'.", $name), $inner ); } diff --git a/src/Exceptions/UnsupportedMediaTypeException.php b/src/Exceptions/UnsupportedMediaTypeException.php index d604736..3fa019d 100755 --- a/src/Exceptions/UnsupportedMediaTypeException.php +++ b/src/Exceptions/UnsupportedMediaTypeException.php @@ -20,13 +20,7 @@ */ class UnsupportedMediaTypeException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "The supplied MediaType is not supported by the system."; - - /** @var string $message - Exception's error message when Media Type is supplied. */ - protected string $messageWithName = "MediaType '%s' is not supported by the system."; - - /** @var int $code - Exception's error code. */ protected $code = 415; /** @@ -34,14 +28,14 @@ class UnsupportedMediaTypeException extends AbstractBaseException * * Code value will be collected from defined class attribute. * - * @param string|null $name - Optional media type name that is not supported. + * @param string $name - Media type name that is not supported. * @param \Exception|null $inner - Optional previous Exception in the stack, for Exception's nesting. - * @return void + * @return self */ - public function __construct(?string $name = null, ?\Exception $inner = null) + public static function withName(string $name, ?\Exception $inner = null): self { - parent::__construct( - ($name !== null ? \sprintf($this->messageWithName, $name) : $this->message), + return new self( + \sprintf("MediaType '%s' is not supported by the system.", $name), $inner ); } diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 6f171bf..68fe5d9 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -95,7 +95,7 @@ protected function doContains(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { - throw new NonEmptyStringException('$search'); + throw NonEmptyStringException::withName('$search'); } return ($this->doIndexOf($search) !== null); @@ -121,7 +121,7 @@ protected function doIndexOf(string $search, int $start = 0): ?int { // Validates supplied parameters. if (\strlen($search) === 0) { - throw new NonEmptyStringException('$search'); + throw NonEmptyStringException::withName('$search'); } if ($start) { $this->validateStartAndLength($start, null); @@ -150,7 +150,7 @@ protected function doStartsWith(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { - throw new NonEmptyStringException('$search'); + throw NonEmptyStringException::withName('$search'); } return ($this->doIndexOf($search) === 0); @@ -168,7 +168,7 @@ protected function doEndsWith(string $search): bool { // Validates supplied parameter. if (\strlen($search) === 0) { - throw new NonEmptyStringException('$search'); + throw NonEmptyStringException::withName('$search'); } return ($this->doSubString((0 - \strlen($search))) === $search); @@ -189,7 +189,7 @@ protected function doCount(string $search, int $start = 0, ?int $length = null): { // Validates supplied $search parameter. if (\strlen($search) === 0) { - throw new NonEmptyStringException('$search'); + throw NonEmptyStringException::withName('$search'); } // Validates supplied $start and $length. @@ -220,7 +220,7 @@ private function validateStartAndLength(int $start, ?int $length): void // Validates the starting value. if ($absStart > $this->getLength()) { - throw new ParameterOutOfRangeException('$start'); + throw ParameterOutOfRangeException::withName('$start'); } // If supplied $length is NULL, no further validations are required. @@ -232,7 +232,7 @@ private function validateStartAndLength(int $start, ?int $length): void if (($start >= 0 && ($this->getLength() - $start < $absLength)) || ($start < 0 && $absLength > $absStart)) { - throw new ParameterOutOfRangeException('$length'); + throw ParameterOutOfRangeException::withName('$length'); } } @@ -339,10 +339,10 @@ protected function doPadLeft(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { - throw new ParameterOutOfRangeException('$length'); + throw ParameterOutOfRangeException::withName('$length'); } if (\strlen($padding) === 0) { - throw new NonEmptyStringException('$padding'); + throw NonEmptyStringException::withName('$padding'); } return \str_pad($this->value, $length, $padding, STR_PAD_LEFT); @@ -389,10 +389,10 @@ protected function doPadRight(int $length, string $padding = " "): string { // Validates supplied parameters. if ($length < 1) { - throw new ParameterOutOfRangeException('$length'); + throw ParameterOutOfRangeException::withName('$length'); } if (\strlen($padding) === 0) { - throw new NonEmptyStringException('$padding'); + throw NonEmptyStringException::withName('$padding'); } return \str_pad($this->value, $length, $padding, STR_PAD_RIGHT); @@ -473,7 +473,7 @@ protected function doSubLeft(int $length): string { // Validates parameter. if ($length < 1) { - throw new ParameterOutOfRangeException('$length'); + throw ParameterOutOfRangeException::withName('$length'); } return $this->doSubString(0, $length); @@ -492,7 +492,7 @@ protected function doSubRight(int $length): string { // Validates parameter. if ($length < 1) { - throw new ParameterOutOfRangeException('$length'); + throw ParameterOutOfRangeException::withName('$length'); } return $this->doSubString(0 - $length); @@ -521,10 +521,10 @@ protected function doReplace(string $search, string $replace): string { // Validates supplied parameters. if (\strlen($search) === 0) { - throw new NonEmptyStringException('$search'); + throw NonEmptyStringException::withName('$search'); } if (\strlen($replace) === 0) { - throw new NonEmptyStringException('$replace'); + throw NonEmptyStringException::withName('$replace'); } return \str_replace($search, $replace, $this->value); @@ -551,7 +551,7 @@ protected function doExplode(string $separator, ?int $limit): array { // Validates supplied parameters. if (\strlen($separator) === 0) { - throw new NonEmptyStringException('$separator'); + throw NonEmptyStringException::withName('$separator'); } if ($limit === null) { diff --git a/src/Traits/Entities/General/HasAliasTrait.php b/src/Traits/Entities/General/HasAliasTrait.php index b53393b..49e472f 100755 --- a/src/Traits/Entities/General/HasAliasTrait.php +++ b/src/Traits/Entities/General/HasAliasTrait.php @@ -34,7 +34,7 @@ protected function castAlias(string $alias): void // Validates if alias is filled. if ($aliasValue->getLength() === 0) { - throw new NonEmptyStringException('$alias'); + throw NonEmptyStringException::withName('$alias'); } // We'll set the alias value on the attribute, but use the sanitizeAlias() method diff --git a/src/Traits/Entities/General/HasHitsTrait.php b/src/Traits/Entities/General/HasHitsTrait.php index 40f80bf..f3b7626 100755 --- a/src/Traits/Entities/General/HasHitsTrait.php +++ b/src/Traits/Entities/General/HasHitsTrait.php @@ -30,7 +30,7 @@ protected function castHits(int $hits): void { // Validates supplied $hits value. if ($hits < 0) { - throw new NonNegativeNumberException('$hits'); + throw NonNegativeNumberException::withName('$hits'); } // Sets value in class' attribute. diff --git a/src/Traits/Entities/General/HasNameTrait.php b/src/Traits/Entities/General/HasNameTrait.php index a8256ed..d29f976 100755 --- a/src/Traits/Entities/General/HasNameTrait.php +++ b/src/Traits/Entities/General/HasNameTrait.php @@ -32,7 +32,7 @@ protected function castName(string $name): void // Validates supplied parameter. $nameValue = Str::create($name)->trim(); if ($nameValue->getLength() === 0) { - throw new NonEmptyStringException('$name'); + throw NonEmptyStringException::withName('$name'); } $this->name = $nameValue; diff --git a/src/Traits/Entities/General/HasOrderingTrait.php b/src/Traits/Entities/General/HasOrderingTrait.php index d2353cc..3ebac0d 100755 --- a/src/Traits/Entities/General/HasOrderingTrait.php +++ b/src/Traits/Entities/General/HasOrderingTrait.php @@ -30,7 +30,7 @@ protected function castOrdering(int $order): void { // Validates supplied parameter. if ($order < 0) { - throw new NonNegativeNumberException('$ordering'); + throw NonNegativeNumberException::withName('$ordering'); } // Sets the value in the class. diff --git a/src/Traits/Entities/General/HasSeoFieldsTrait.php b/src/Traits/Entities/General/HasSeoFieldsTrait.php index 753cc8b..427a58f 100755 --- a/src/Traits/Entities/General/HasSeoFieldsTrait.php +++ b/src/Traits/Entities/General/HasSeoFieldsTrait.php @@ -43,7 +43,7 @@ protected function castSeoTitle(?string $title = null): void $titleValue = ($title ? Str::create($title)->trim() : null); if ($titleValue !== null && $titleValue->getLength() > 70) { - throw new NonEmptyStringException("Supplied Seo title must have length up to 70 characters."); + throw InvalidStringLengthException::withNameAndLength("Seo title", 70); } $this->seo_title = $this->seoSanitize($titleValue); @@ -55,7 +55,7 @@ protected function castSeoTitle(?string $title = null): void * * @param string|null $description - New value to be set on Attribute. * - * @throws NonEmptyStringException - Supplied Seo Description must be a non empty string. + * @throws InvalidStringLengthException - Supplied Seo Description must be a non empty string. * * @link https://seopressor.com/blog/google-title-meta-descriptions-length * @return void @@ -66,7 +66,7 @@ protected function castSeoDescription(?string $description = null): void $descriptionValue = ($description ? Str::create($description) : null); if ($descriptionValue !== null && $descriptionValue->trim()->getLength() > 160) { - throw new NonEmptyStringException("Supplied Seo description must have length up to 160 characters."); + throw InvalidStringLengthException::withNameAndLength("Seo description", 160); } $this->seo_description = $this->seoSanitize($descriptionValue); @@ -78,7 +78,7 @@ protected function castSeoDescription(?string $description = null): void * * @param string|null $keywords - New value to be set on Attribute. * - * @throws NonEmptyStringException - Supplied Seo Keywords must be a non empty string. + * @throws InvalidStringLengthException - Supplied Seo Keywords must be a non empty string. * * @link https://www.quora.com/What-is-the-minimum-length-of-a-meta-keyword-in-on-page-SEO * @return void @@ -89,7 +89,7 @@ protected function castSeoKeywords(string $keywords = null): void $keywordsValue = ($keywords ? Str::create($keywords) : null); if ($keywordsValue !== null && $keywordsValue->trim()->getLength() > 255) { - throw new NonEmptyStringException("Supplied Seo keywords must have length up to 255 characters."); + throw InvalidStringLengthException::withNameAndLength("Seo keywords", 255); } $this->seo_keywords = $this->seoSanitize($keywordsValue); diff --git a/src/Traits/Entities/General/HasTitleTrait.php b/src/Traits/Entities/General/HasTitleTrait.php index eafdffe..c37fb28 100755 --- a/src/Traits/Entities/General/HasTitleTrait.php +++ b/src/Traits/Entities/General/HasTitleTrait.php @@ -32,7 +32,7 @@ protected function castTitle(string $title): void // Validates supplied parameter. $titleValue = Str::create($title)->trim(); if ($titleValue->getLength() === 0) { - throw new NonEmptyStringException('$title'); + throw NonEmptyStringException::withName('$title'); } $this->title = $titleValue; diff --git a/src/Traits/Entities/Location/HasCityTrait.php b/src/Traits/Entities/Location/HasCityTrait.php index 52f6744..285c6eb 100644 --- a/src/Traits/Entities/Location/HasCityTrait.php +++ b/src/Traits/Entities/Location/HasCityTrait.php @@ -32,7 +32,7 @@ protected function castCity(?string $city): void $cityValue = $city ? Str::create($city)->trim() : null; if ($cityValue !== null && $cityValue->getLength() === 0) { - throw new NonEmptyStringException('$city'); + throw NonEmptyStringException::withName('$city'); } $this->city = $cityValue; diff --git a/src/Traits/Entities/Location/HasDistrictTrait.php b/src/Traits/Entities/Location/HasDistrictTrait.php index 377f5ce..1575258 100644 --- a/src/Traits/Entities/Location/HasDistrictTrait.php +++ b/src/Traits/Entities/Location/HasDistrictTrait.php @@ -32,7 +32,7 @@ protected function castDistrict(?string $district): void $districtValue = $district ? Str::create($district)->trim() : null; if ($districtValue !== null && $districtValue->getLength() === 0) { - throw new NonEmptyStringException('$district'); + throw NonEmptyStringException::withName('$district'); } $this->district = $districtValue; diff --git a/src/Traits/Entities/Location/HasParishTrait.php b/src/Traits/Entities/Location/HasParishTrait.php index e3f5254..17102f1 100644 --- a/src/Traits/Entities/Location/HasParishTrait.php +++ b/src/Traits/Entities/Location/HasParishTrait.php @@ -32,7 +32,7 @@ protected function castParish(?string $parish): void $parishValue = $parish ? Str::create($parish)->trim() : null; if ($parishValue !== null && $parishValue->getLength() === 0) { - throw new NonEmptyStringException('$parish'); + throw NonEmptyStringException::withName('$parish'); } $this->parish = $parishValue; diff --git a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php index 8a2e6f6..ccbc773 100644 --- a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php +++ b/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php @@ -30,7 +30,7 @@ protected function castCountryOfBirth(string $country): void $countryValue = Str::create($country)->trim(); if ($countryValue->getLength() === 0) { - throw new NonEmptyStringException('$country_of_birth'); + throw NonEmptyStringException::withName('$country_of_birth'); } $this->country_of_birth = $countryValue; diff --git a/src/Traits/Entities/Personal/HasNationalityTrait.php b/src/Traits/Entities/Personal/HasNationalityTrait.php index fe97da0..bfe33a7 100644 --- a/src/Traits/Entities/Personal/HasNationalityTrait.php +++ b/src/Traits/Entities/Personal/HasNationalityTrait.php @@ -30,7 +30,7 @@ protected function castNationality(?string $nationality): void $nationalityValue = $nationality ? Str::create($nationality)->trim() : null; if ($nationalityValue !== null && $nationalityValue->getLength() === 0) { - throw new NonEmptyStringException('$nationality'); + throw NonEmptyStringException::withName('$nationality'); } $this->nationality = $nationalityValue; diff --git a/src/Traits/Entities/Personal/HasPhotoTrait.php b/src/Traits/Entities/Personal/HasPhotoTrait.php index 2756511..3c397bd 100755 --- a/src/Traits/Entities/Personal/HasPhotoTrait.php +++ b/src/Traits/Entities/Personal/HasPhotoTrait.php @@ -33,7 +33,7 @@ protected function castPhoto(?string $photo): void $photoValue = Str::create($photo)->trim(); if ($photoValue->getLength() === 0) { - throw new NonEmptyStringException('$photo'); + throw NonEmptyStringException::withName('$photo'); } $this->photo = $photoValue; diff --git a/src/Traits/Entities/Personal/HasSurnameTrait.php b/src/Traits/Entities/Personal/HasSurnameTrait.php index ea18f67..2e91881 100755 --- a/src/Traits/Entities/Personal/HasSurnameTrait.php +++ b/src/Traits/Entities/Personal/HasSurnameTrait.php @@ -33,7 +33,7 @@ protected function castSurname(string $surname): void $surnameValue = Str::create($surname)->trim(); if ($surnameValue->getLength() === 0) { - throw new NonEmptyStringException('$surname'); + throw NonEmptyStringException::withName('$surname'); } $this->surname = $surnameValue; diff --git a/src/Traits/Entities/Professional/HasIndustryTrait.php b/src/Traits/Entities/Professional/HasIndustryTrait.php index a426f34..5612ea4 100755 --- a/src/Traits/Entities/Professional/HasIndustryTrait.php +++ b/src/Traits/Entities/Professional/HasIndustryTrait.php @@ -33,7 +33,7 @@ protected function castIndustry(?string $industry): void $industryValue = $industry ? Str::create($industry)->trim() : null; if ($industryValue !== null && $industryValue->getLength() === 0) { - throw new NonEmptyStringException('$occupation'); + throw NonEmptyStringException::withName('$occupation'); } $this->industry = $industryValue; diff --git a/src/Traits/Entities/Professional/HasOccupationTrait.php b/src/Traits/Entities/Professional/HasOccupationTrait.php index 5c91564..fac0a76 100755 --- a/src/Traits/Entities/Professional/HasOccupationTrait.php +++ b/src/Traits/Entities/Professional/HasOccupationTrait.php @@ -33,7 +33,7 @@ protected function castOccupation(?string $occupation): void $occupationValue = $occupation ? Str::create($occupation)->trim() : null; if ($occupationValue !== null && $occupationValue->getLength() === 0) { - throw new NonEmptyStringException('$occupation'); + throw NonEmptyStringException::withName('$occupation'); } $this->occupation = $occupationValue; diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 311eb69..2d2c3c6 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -68,10 +68,10 @@ protected function loadFromPrimitive(string $email): void // Validate supplied parameter. if ($voEmail->getLength() === 0) { - throw new NonEmptyStringException('$email'); + throw NonEmptyStringException::withName('$email'); } if (!\filter_var((string) $email, FILTER_VALIDATE_EMAIL)) { - throw new InvalidEmailException($email); + throw InvalidEmailException::withName($email); } // Sanitizes and processes supplied e-mail address. From 50910f592e9346a39ee2ae93f6e8f627247d7f82 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 4 Mar 2022 11:14:49 +0000 Subject: [PATCH 090/193] fix: Change constraint to double pipe --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2a9f5ff..c62bf60 100755 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "mutable objects" ], "require": { - "php": "^7.4|^8.0" + "php": "^7.4||^8.0" }, "require-dev": { "ext-xdebug": "*", From b16ee7733b02341cf1055326768d6a51ac4cf111 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 13:22:51 +0000 Subject: [PATCH 091/193] refactor: Call parent method in equals() --- src/Scalar/Str.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Scalar/Str.php b/src/Scalar/Str.php index e551732..a4e0914 100644 --- a/src/Scalar/Str.php +++ b/src/Scalar/Str.php @@ -43,7 +43,7 @@ public static function create(string $value): Str */ public function equals(Str $string): bool { - return ($this->value === $string->value); + return parent::doEquals((string) $string); } /** From 18ed0226fe0714197549c79571a5d5220e3dc87f Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 13:25:34 +0000 Subject: [PATCH 092/193] refactor: Call replacement methods for serializing --- src/ValueObjects/AbstractValueObject.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php index 174ce1e..1ff8f4c 100644 --- a/src/ValueObjects/AbstractValueObject.php +++ b/src/ValueObjects/AbstractValueObject.php @@ -174,7 +174,7 @@ public function getAttributes(): array public function serialize(): string { return \serialize( - $this->toArray() + $this->__serialize() ); } @@ -186,7 +186,7 @@ public function __serialize(): array /** @inheritDoc */ public function unserialize($serialized): void { - $this->loadInstance( + $this->__unserialize( \unserialize($serialized) ); } From f0dd8c8f24318cee8e73d478e7b7b90c0c9c79cf Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 13:30:07 +0000 Subject: [PATCH 093/193] refactor: Remove Serializable implementation --- src/ValueObjects/AbstractValueObject.php | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php index 1ff8f4c..7291729 100644 --- a/src/ValueObjects/AbstractValueObject.php +++ b/src/ValueObjects/AbstractValueObject.php @@ -14,7 +14,6 @@ use HraDigital\Datatypes\Traits\ValueObjects\HasMappedFieldsTrait; use HraDigital\Datatypes\Traits\ValueObjects\HasRequiredFieldsTrait; use HraDigital\Datatypes\Traits\ValueObjects\HasRuleProcessingTrait; -use Serializable; /** * Abstract Base Value Object class for all Domain Entities/Value Objects. @@ -33,7 +32,7 @@ * @copyright HraDigital\Datatypes * @license MIT */ -abstract class AbstractValueObject implements \JsonSerializable, Serializable +abstract class AbstractValueObject implements \JsonSerializable { use HasMappedFieldsTrait, HasRuleProcessingTrait, @@ -170,27 +169,11 @@ public function getAttributes(): array return $this->convertIntoPrimitiveValues($fields); } - /** @inheritDoc */ - public function serialize(): string - { - return \serialize( - $this->__serialize() - ); - } - public function __serialize(): array { return $this->toArray(); } - /** @inheritDoc */ - public function unserialize($serialized): void - { - $this->__unserialize( - \unserialize($serialized) - ); - } - public function __unserialize(array $data): void { $this->loadInstance($data); From 9b1df43d91766d42fd53022d742293d939d50c6b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 14:00:19 +0000 Subject: [PATCH 094/193] feat: Add __debugInfo() magic method --- src/ValueObjects/AbstractValueObject.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php index 7291729..0ea54f6 100644 --- a/src/ValueObjects/AbstractValueObject.php +++ b/src/ValueObjects/AbstractValueObject.php @@ -196,4 +196,19 @@ public function jsonSerialize(): \stdClass $this->convertIntoPrimitiveValues($fields, true) ); } + + /** + * This method is called by var_dump() when dumping an object to get the properties that should be shown. + * + * If the method isn't defined on an object, then all public, protected and private properties will be shown. + * + * Note: Might not work with xDebug. + * + * @link https://www.php.net/manual/en/language.oop5.magic.php#object.debuginfo + * @return array + */ + public function __debugInfo(): array + { + return $this->toArray(); + } } From 2c875b57b4147670feb0e9961854064b5172b779 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 14:28:15 +0000 Subject: [PATCH 095/193] style: Improve class formating --- src/Exceptions/ConflictException.php | 1 - src/Exceptions/GoneException.php | 3 --- src/Exceptions/NotFoundException.php | 3 --- 3 files changed, 7 deletions(-) diff --git a/src/Exceptions/ConflictException.php b/src/Exceptions/ConflictException.php index 03907f0..9c0d0e7 100755 --- a/src/Exceptions/ConflictException.php +++ b/src/Exceptions/ConflictException.php @@ -21,7 +21,6 @@ class ConflictException extends AbstractBaseException { protected $message = "The action failed due to a conflict in the provided request."; - protected $code = 409; /** diff --git a/src/Exceptions/GoneException.php b/src/Exceptions/GoneException.php index 0a9ae81..95009a0 100755 --- a/src/Exceptions/GoneException.php +++ b/src/Exceptions/GoneException.php @@ -18,10 +18,7 @@ */ class GoneException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "The resource you are looking for, is no longer available in the system."; - - /** @var int $code - Exception's error code. */ protected $code = 410; /** diff --git a/src/Exceptions/NotFoundException.php b/src/Exceptions/NotFoundException.php index 0e46ba9..0c11aec 100755 --- a/src/Exceptions/NotFoundException.php +++ b/src/Exceptions/NotFoundException.php @@ -18,10 +18,7 @@ */ class NotFoundException extends AbstractBaseException { - /** @var string $message - Exception's error message. */ protected $message = "The resource you are looking for, was not found in the system."; - - /** @var int $code - Exception's error code. */ protected $code = 404; /** From e3ce1686f8983e0d3de47ae3c566b91951ab6928 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 14:56:54 +0000 Subject: [PATCH 096/193] tests: Increase test coverage --- tests/Unit/Datetime/README.md | 1 + tests/Unit/Exceptions/CoreExceptionsTest.php | 168 ++++++++++++++++++ .../Datatypes/DatatypeExceptionsTest.php | 114 ++++++++++++ tests/Unit/Exceptions/Datatypes/README.md | 1 + .../Entities/EntitiesExceptionsTest.php | 43 +++++ tests/Unit/Exceptions/Entities/README.md | 1 + tests/Unit/Exceptions/README.md | 1 + tests/Unit/Scalar/StrTest.php | 62 +++++++ .../ValueObjects/AbstractValueObjectTest.php | 16 ++ 9 files changed, 407 insertions(+) create mode 100644 tests/Unit/Datetime/README.md create mode 100644 tests/Unit/Exceptions/CoreExceptionsTest.php create mode 100644 tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php create mode 100644 tests/Unit/Exceptions/Datatypes/README.md create mode 100644 tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php create mode 100644 tests/Unit/Exceptions/Entities/README.md create mode 100644 tests/Unit/Exceptions/README.md diff --git a/tests/Unit/Datetime/README.md b/tests/Unit/Datetime/README.md new file mode 100644 index 0000000..d6b0f97 --- /dev/null +++ b/tests/Unit/Datetime/README.md @@ -0,0 +1 @@ +# Datetime related Unit tests diff --git a/tests/Unit/Exceptions/CoreExceptionsTest.php b/tests/Unit/Exceptions/CoreExceptionsTest.php new file mode 100644 index 0000000..cd192b5 --- /dev/null +++ b/tests/Unit/Exceptions/CoreExceptionsTest.php @@ -0,0 +1,168 @@ +assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(409, $exception->getCode()); + } + + public function testDeniedAccessExceptionIsProperlyInitialized(): void + { + $exception = new DeniedAccessException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(401, $exception->getCode()); + } + + public function testExpectationFailedExceptionIsProperlyInitialized(): void + { + $exception = new ExpectationFailedException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(417, $exception->getCode()); + } + + public function testFailedDependencyExceptionIsProperlyInitialized(): void + { + $exception = new FailedDependencyException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(424, $exception->getCode()); + } + + public function testForbiddenExceptionIsProperlyInitialized(): void + { + $exception = new ForbiddenException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(403, $exception->getCode()); + } + + public function testGoneExceptionIsProperlyInitialized(): void + { + $exception = new GoneException(); + $static = GoneException::withId(123); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(410, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('123', $static->getMessage()); + } + + public function testMethodNotAllowedExceptionIsProperlyInitialized(): void + { + $exception = new MethodNotAllowedException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(405, $exception->getCode()); + } + + public function testNotAcceptableExceptionIsProperlyInitialized(): void + { + $exception = new NotAcceptableException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(406, $exception->getCode()); + } + + public function testNotFoundExceptionIsProperlyInitialized(): void + { + $exception = new NotFoundException(); + $static = NotFoundException::withId(12345); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(404, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('12345', $static->getMessage()); + } + + public function testPreconditionFailedExceptionIsProperlyInitialized(): void + { + $exception = new PreconditionFailedException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(412, $exception->getCode()); + } + + public function testPreconditionRequiredExceptionIsProperlyInitialized(): void + { + $exception = new PreconditionRequiredException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(428, $exception->getCode()); + } + + public function testRequestedRangeNotSatisfiableExceptionIsProperlyInitialized(): void + { + $exception = new RequestedRangeNotSatisfiableException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(416, $exception->getCode()); + } + + public function testTooManyRequestsExceptionIsProperlyInitialized(): void + { + $exception = new TooManyRequestsException(); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertEquals(429, $exception->getCode()); + } + + public function testUnprocessableEntityExceptionIsProperlyInitialized(): void + { + $exception = new UnprocessableEntityException(); + $static = UnprocessableEntityException::withName('SomeField'); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } + + public function testUnsupportedMediaTypeExceptionIsProperlyInitialized(): void + { + $exception = new UnsupportedMediaTypeException(); + $static = UnsupportedMediaTypeException::withName('MediaType'); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(415, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('MediaType', $static->getMessage()); + } +} diff --git a/tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php b/tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php new file mode 100644 index 0000000..4ded76f --- /dev/null +++ b/tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php @@ -0,0 +1,114 @@ +assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } + + public function testInvalidEmailExceptionIsProperlyInitialized(): void + { + $exception = new InvalidEmailException(); + $static = InvalidEmailException::withName('SomeField'); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } + + public function testInvalidStringLengthExceptionIsProperlyInitialized(): void + { + $exception = new InvalidStringLengthException(); + $static = InvalidStringLengthException::withName('SomeField'); + $staticWithLength = InvalidStringLengthException::withNameAndLength('SomeField', 150); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertGreaterThan(0, \strlen($staticWithLength->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertNotEquals($exception->getMessage(), $staticWithLength->getMessage()); + $this->assertNotEquals($static->getMessage(), $staticWithLength->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + $this->assertStringContainsString('SomeField', $staticWithLength->getMessage()); + $this->assertStringContainsString('150', $staticWithLength->getMessage()); + } + + public function testNonEmptyStringExceptionIsProperlyInitialized(): void + { + $exception = new NonEmptyStringException(); + $static = NonEmptyStringException::withName('SomeField'); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } + + public function testNonNegativeNumberExceptionIsProperlyInitialized(): void + { + $exception = new NonNegativeNumberException(); + $static = NonNegativeNumberException::withName('SomeField'); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } + + public function testParameterOutOfRangeExceptionIsProperlyInitialized(): void + { + $exception = new ParameterOutOfRangeException(); + $static = ParameterOutOfRangeException::withName('SomeField'); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } + + public function testPositiveIntegerExceptionIsProperlyInitialized(): void + { + $exception = new PositiveIntegerException(); + $static = PositiveIntegerException::withName('SomeField'); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } +} diff --git a/tests/Unit/Exceptions/Datatypes/README.md b/tests/Unit/Exceptions/Datatypes/README.md new file mode 100644 index 0000000..fb46103 --- /dev/null +++ b/tests/Unit/Exceptions/Datatypes/README.md @@ -0,0 +1 @@ +# Datatype Exception's related Unit tests diff --git a/tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php b/tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php new file mode 100644 index 0000000..df4ae91 --- /dev/null +++ b/tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php @@ -0,0 +1,43 @@ +assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } + + public function testUnexpectedEntityValueExceptionIsProperlyInitialized(): void + { + $exception = new UnexpectedEntityValueException(); + $static = UnexpectedEntityValueException::withName('SomeField'); + + $this->assertGreaterThan(0, \strlen($exception->getMessage())); + $this->assertGreaterThan(0, \strlen($static->getMessage())); + $this->assertEquals(422, $exception->getCode()); + $this->assertNotEquals($exception->getMessage(), $static->getMessage()); + $this->assertStringContainsString('SomeField', $static->getMessage()); + } +} diff --git a/tests/Unit/Exceptions/Entities/README.md b/tests/Unit/Exceptions/Entities/README.md new file mode 100644 index 0000000..65db58b --- /dev/null +++ b/tests/Unit/Exceptions/Entities/README.md @@ -0,0 +1 @@ +# Entity's Exception related Unit tests diff --git a/tests/Unit/Exceptions/README.md b/tests/Unit/Exceptions/README.md new file mode 100644 index 0000000..0af26bc --- /dev/null +++ b/tests/Unit/Exceptions/README.md @@ -0,0 +1 @@ +# Exception's related Unit tests diff --git a/tests/Unit/Scalar/StrTest.php b/tests/Unit/Scalar/StrTest.php index 0a8af53..6c2620f 100644 --- a/tests/Unit/Scalar/StrTest.php +++ b/tests/Unit/Scalar/StrTest.php @@ -525,4 +525,66 @@ public function testBreaksTextReplaceIfSearchIsEmpty(): void $original = $this->getInstance("Immutable String."); $original->replace($this->getInstance(''), $this->getInstance('Object')); } + + /** + * Tests that text replace breaks. + * + * @return void + */ + public function testBreaksTextReplaceIfReplaceIsEmpty(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->replace($this->getInstance('Object'), $this->getInstance('')); + } + + /** + * Tests that text can be exploded into an array. + * + * @return void + */ + public function testTextCanBeExplodedIntoAnArray(): void + { + // Performs test. + $original = $this->getInstance("This is an immutable String."); + $array = $original->explode(' '); + + // Performs assertions. + $this->assertIsArray($array); + $this->assertCount(5, $array); + } + + /** + * Tests that text can be exploded into an array. + * + * @return void + */ + public function testTextCanBeExplodedIntoAnArrayWithLimit(): void + { + // Performs test. + $original = $this->getInstance("This is an immutable String."); + $array = $original->explode(' ', 3); + + // Performs assertions. + $this->assertIsArray($array); + $this->assertCount(3, $array); + } + + /** + * Tests that text is not replaced if search is not found. + * + * @return void + */ + public function testBreaksIfReplacementIsEmpty(): void + { + // Creates expectation. + $this->expectException(NonEmptyStringException::class); + + // Performs test. + $original = $this->getInstance("This is an immutable String."); + $original->explode(''); + } } diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php index 10074ab..810d4c9 100644 --- a/tests/Unit/ValueObjects/AbstractValueObjectTest.php +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -115,4 +115,20 @@ public function testCanSerializeAndUnserialize(): void (string) $unserialized->getTitle() ); } + + public function testCanCallDebugInfoInValueObject(): void + { + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + $array = $valueObject->__debugInfo(); + + $this->assertArrayHasKey('active', $array); + $this->assertArrayHasKey('email', $array); + $this->assertArrayHasKey('title', $array); + $this->assertArrayHasKey('inner', $array); + + $this->assertArrayHasKey('title', $array['inner']); + $this->assertArrayHasKey('active', $array['inner']); + } } From cb57724bee5a9f9d4c1b76c1e690eb0216900f5c Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:20:50 +0000 Subject: [PATCH 097/193] style: Improve coding standards --- src/Collections/Linear/Queue.php | 1 - src/Collections/Linear/Stack.php | 1 - src/Scalar/AbstractBaseString.php | 5 +++-- src/Traits/Entities/CanProcessEntityStateTrait.php | 9 ++++----- .../ValueObjects/HasConversionToPrimitiveValuesTrait.php | 1 - src/Traits/ValueObjects/HasFieldCastingTrait.php | 2 -- src/Traits/ValueObjects/HasRequiredFieldsTrait.php | 1 - src/Traits/ValueObjects/HasRuleProcessingTrait.php | 1 - 8 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/Collections/Linear/Queue.php b/src/Collections/Linear/Queue.php index 5ec2b87..b505ac3 100644 --- a/src/Collections/Linear/Queue.php +++ b/src/Collections/Linear/Queue.php @@ -45,7 +45,6 @@ public function __construct(?array $initial = null) { // Checks initially provided list of elements. if ($initial !== null) { - // Validates supplied parameter. if (\count($initial) === 0) { throw new \InvalidArgumentException("Supplied array should be a list of string elements."); diff --git a/src/Collections/Linear/Stack.php b/src/Collections/Linear/Stack.php index 152608c..a5644a2 100644 --- a/src/Collections/Linear/Stack.php +++ b/src/Collections/Linear/Stack.php @@ -45,7 +45,6 @@ public function __construct(?array $initial = null) { // Checks initially provided list of elements. if ($initial !== null) { - // Validates supplied parameter. if (\count($initial) === 0) { throw new \InvalidArgumentException("Supplied array should be a list of string elements."); diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php index 68fe5d9..8cdec69 100644 --- a/src/Scalar/AbstractBaseString.php +++ b/src/Scalar/AbstractBaseString.php @@ -229,9 +229,10 @@ private function validateStartAndLength(int $start, ?int $length): void } // Checks if the supplied $length, doesn't exceed the available number of characters. - if (($start >= 0 && ($this->getLength() - $start < $absLength)) || - ($start < 0 && $absLength > $absStart)) { + $startTooBig = ($start >= 0 && ($this->getLength() - $start < $absLength)); + $startTooSmall = ($start < 0 && $absLength > $absStart); + if ($startTooBig || $startTooSmall) { throw ParameterOutOfRangeException::withName('$length'); } } diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index abdf0f3..573780d 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -54,14 +54,13 @@ final public function getDirty(bool $withTimestamps = false): array // Loops through all the class' attributes, and validates if any has changed. $dirty = []; foreach ($this->getAttributes() as $field => $value) { - // Is the current value different from the initial one? // Is the Entity NEW, and the field a required one? // If so, add it to the $dirty return array. - if ( - $value !== $this->initialState[$field] || - ($this->isNew() && \array_search($field, $this->required) !== false) - ) { + $hasChanged = ($value !== $this->initialState[$field]); + $isNewOrRequired = ($this->isNew() && \array_search($field, $this->required)); + + if ($hasChanged || $isNewOrRequired) { $dirty[$field] = $value; } } diff --git a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php index 354a1c6..4263fe8 100644 --- a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php +++ b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php @@ -28,7 +28,6 @@ private function convertIntoPrimitiveValues(array $fields, bool $objectAsJson = // Loops through all the supplied Fields, and converts their values into primitives. $converted = []; foreach ($fields as $field => $value) { - // Returns the string representation of the object, or tries to convert array or object to JSON. // If is not an Object not an Array, returns the actual value of the Field. if ($value instanceof AbstractValueObject || $value instanceof EntityCollection) { diff --git a/src/Traits/ValueObjects/HasFieldCastingTrait.php b/src/Traits/ValueObjects/HasFieldCastingTrait.php index 0eaf937..72f1b80 100644 --- a/src/Traits/ValueObjects/HasFieldCastingTrait.php +++ b/src/Traits/ValueObjects/HasFieldCastingTrait.php @@ -31,7 +31,6 @@ protected function castAttributes(array $fields): void { // Loops through all the supplied Field's list. foreach ($fields as $field => $value) { - // Builds up the Mutator's name. $mutator = $this->createMutatorName(self::$CASTPREFIX, $field); @@ -64,7 +63,6 @@ private function registerAttributeCastingList(): void // Loops through all the class' methods, and loads the necessary ones in // the corresponding containers. foreach (\get_class_methods($this) as $method) { - // Loads casting mutators. if (\strpos($method, self::$CASTPREFIX) === 0 && \strlen($method) > \strlen(self::$CASTPREFIX)) { $this->castList[] = $method; diff --git a/src/Traits/ValueObjects/HasRequiredFieldsTrait.php b/src/Traits/ValueObjects/HasRequiredFieldsTrait.php index 8d829d9..f7e739a 100644 --- a/src/Traits/ValueObjects/HasRequiredFieldsTrait.php +++ b/src/Traits/ValueObjects/HasRequiredFieldsTrait.php @@ -33,7 +33,6 @@ private function validateRequired(array $fields): void { // Checks that all required fields were supplied. foreach ($this->required as $required) { - // First, we'll need to assess if the field already exists NATIVELY in the class. // If not, we'll need to assess it is mapped. if (! \array_key_exists($required, $fields)) { diff --git a/src/Traits/ValueObjects/HasRuleProcessingTrait.php b/src/Traits/ValueObjects/HasRuleProcessingTrait.php index ec43a23..73397ff 100644 --- a/src/Traits/ValueObjects/HasRuleProcessingTrait.php +++ b/src/Traits/ValueObjects/HasRuleProcessingTrait.php @@ -46,7 +46,6 @@ private function registerAttributeRuleList(): void // Loops through all the class' methods, and loads the necessary ones in // the corresponding containers. foreach (\get_class_methods($this) as $method) { - // Loads mutators/setters and rules. if (\strpos($method, self::$RULEPREFIX) === 0 && \strlen($method) > \strlen(self::$RULEPREFIX)) { $this->ruleList[] = $method; From f1919591c20cd54d4c0e26d0779800b305c13d4f Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:24:47 +0000 Subject: [PATCH 098/193] refactor: Improve test-cs script definition --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c62bf60..0298bfb 100755 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ }, "scripts": { "test-code" : "./vendor/bin/phpunit --coverage-clover ci/coverage-report.xml --coverage-html ci/coverage-report --log-junit ci/tests-results.xml", - "test-cs" : "./vendor/bin/phpcs -p --colors --no-cache --report=full --standard=PSR2 src/", + "test-cs" : "./vendor/bin/phpcs -p --colors --no-cache --report=full --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing src/", "test-all" : "composer run test-code && composer run test-cs" } } From f3e2b8d089c6ce71a3ddfc027a2dc8bee3b5a667 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:28:22 +0000 Subject: [PATCH 099/193] build: Change CircleCI definition --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 615b49d..98d6f2f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,7 +15,7 @@ jobs: command: sudo apt-get update - run: name: Install CLOC - command: sudo apt-get -y install cloc + command: sudo apt-get -y install cloc php-xdebug # COMPOSER - run: name: Install Composer Dependencies @@ -27,7 +27,7 @@ jobs: # TESTS - run: name: Run Tests - command: phpdbg -qrr vendor/bin/phpunit --coverage-clover ~/build/coverage-report + command: phpdbg -qrr vendor/bin/phpunit --coverage-clover build/coverage-report - run: name: Check coding standards in /src command: vendor/bin/phpcs --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing src @@ -35,7 +35,7 @@ jobs: name: Check coding standards in /tests command: vendor/bin/phpcs --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing tests - store_artifacts: - path: ~/build/coverage-report + path: build/coverage-report - codecov/upload: - file: ~/build/coverage-report + file: build/coverage-report From f43e5676ee3e4065b5684b9b38849aabe616620d Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:29:37 +0000 Subject: [PATCH 100/193] build: Remove xDebug install --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 98d6f2f..7ec1495 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,7 +15,7 @@ jobs: command: sudo apt-get update - run: name: Install CLOC - command: sudo apt-get -y install cloc php-xdebug + command: sudo apt-get -y install cloc # COMPOSER - run: name: Install Composer Dependencies From 5808fa434ceb35d3ac31780287296079eb3464b4 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:36:22 +0000 Subject: [PATCH 101/193] build: Change composer install to update --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ec1495..015699c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: # COMPOSER - run: name: Install Composer Dependencies - command: composer install + command: composer update # STATISTICS - run: name: Project's Statistics From d91eae1627aa41850bba04fb8d6c7af75e86e457 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:38:47 +0000 Subject: [PATCH 102/193] build: Add store_test_results to CircleCI cofig --- .circleci/config.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 015699c..8115f84 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,7 +27,7 @@ jobs: # TESTS - run: name: Run Tests - command: phpdbg -qrr vendor/bin/phpunit --coverage-clover build/coverage-report + command: phpdbg -qrr vendor/bin/phpunit --coverage-clover ~/build/coverage-report - run: name: Check coding standards in /src command: vendor/bin/phpcs --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing src @@ -35,7 +35,9 @@ jobs: name: Check coding standards in /tests command: vendor/bin/phpcs --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing tests - store_artifacts: - path: build/coverage-report + path: ~/build/coverage-report + - store_test_results: + path: ~/build/test-results - codecov/upload: - file: build/coverage-report + file: ~/build/coverage-report From 8dd6f7bdde87adf8580459a7ca49ba3a986a4086 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:39:51 +0000 Subject: [PATCH 103/193] vuild: Change path for stored tests results --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8115f84..4688f2b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -37,7 +37,7 @@ jobs: - store_artifacts: path: ~/build/coverage-report - store_test_results: - path: ~/build/test-results + path: ~/build/coverage-report - codecov/upload: file: ~/build/coverage-report From 9822acc62a1f9eefbaf89c96256cbcc3d2e94ab1 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:41:38 +0000 Subject: [PATCH 104/193] build: change composer update back to install --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4688f2b..2348368 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,7 @@ jobs: # COMPOSER - run: name: Install Composer Dependencies - command: composer update + command: composer install # STATISTICS - run: name: Project's Statistics From 065e8acfd8219743d86423eb2a3bb45e8732f88f Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:45:42 +0000 Subject: [PATCH 105/193] build: Update PHPUnit's configuration --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 968be3b..28b7aab 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -20,7 +20,7 @@ - tests/Unit + tests/Unit From 5d8277e51a09f5b25e0155e90ef18ed51749f260 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:47:04 +0000 Subject: [PATCH 106/193] build: Change PHP version to 8.0 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2348368..272e0f6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,7 +4,7 @@ orbs: jobs: build: docker: - - image: circleci/php:7.4 + - image: circleci/php:8.0 working_directory: ~/php-datatypes steps: # GIT From 511d4293f528add253fe9ae1b0243606759a20b1 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:49:09 +0000 Subject: [PATCH 107/193] build: Change docker image --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 272e0f6..f9a69aa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,7 +4,7 @@ orbs: jobs: build: docker: - - image: circleci/php:8.0 + - image: php:7.4-cli working_directory: ~/php-datatypes steps: # GIT From 46188d681406422129b89fec97e0891f21cf5f0a Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:52:57 +0000 Subject: [PATCH 108/193] build: Restore CircleCi definition --- .circleci/config.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f9a69aa..02aa212 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,16 +4,15 @@ orbs: jobs: build: docker: - - image: php:7.4-cli + - image: circleci/php:7.4 working_directory: ~/php-datatypes steps: # GIT - checkout # SYSTEM - run: - name: Install System Packages + name: Update System command: sudo apt-get update - - run: name: Install CLOC command: sudo apt-get -y install cloc # COMPOSER From eafe11ce6b13de31d79900aee79f4c05a2be58f1 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 15:53:54 +0000 Subject: [PATCH 109/193] build: Fix config --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 02aa212..1f081c1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,6 +13,7 @@ jobs: - run: name: Update System command: sudo apt-get update + - run: name: Install CLOC command: sudo apt-get -y install cloc # COMPOSER From 8fa0f81996f87f3c01ccdc158ffe57e20e7546f8 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 18:53:52 +0000 Subject: [PATCH 110/193] refactor: Remove type hinting --- src/Datetime/DateTimeInterface.php | 35 +++++++++++------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/Datetime/DateTimeInterface.php b/src/Datetime/DateTimeInterface.php index 82740ae..90a08ea 100644 --- a/src/Datetime/DateTimeInterface.php +++ b/src/Datetime/DateTimeInterface.php @@ -14,26 +14,17 @@ */ interface DateTimeInterface { - const string ATOM = \DateTimeInterface::ATOM; - const string COOKIE = \DateTimeInterface::COOKIE; - const string ISO8601 = \DateTimeInterface::ISO8601; - const string RFC822 = \DateTimeInterface::RFC822; - const string RFC850 = \DateTimeInterface::RFC850; - const string RFC1036 = \DateTimeInterface::RFC1036; - const string RFC1123 = \DateTimeInterface::RFC1123; - const string RFC7231 = \DateTimeInterface::RFC7231; - const string RFC2822 = \DateTimeInterface::RFC2822; - const string RFC3339 = \DateTimeInterface::RFC3339; - const string RFC3339_EXTENDED = \DateTimeInterface::RFC3339_EXTENDED; - const string RSS = \DateTimeInterface::RSS; - const string W3C = \DateTimeInterface::W3C; - - /* Methods - public diff ( DateTimeInterface $targetObject , bool $absolute = false ) : DateInterval - public format ( string $format ) : string - public getOffset ( ) : int - public getTimestamp ( ) : int - public getTimezone ( ) : DateTimeZone|false - public __wakeup ( ) : void - */ + const ATOM = \DateTimeInterface::ATOM; + const COOKIE = \DateTimeInterface::COOKIE; + const ISO8601 = \DateTimeInterface::ISO8601; + const RFC822 = \DateTimeInterface::RFC822; + const RFC850 = \DateTimeInterface::RFC850; + const RFC1036 = \DateTimeInterface::RFC1036; + const RFC1123 = \DateTimeInterface::RFC1123; + const RFC7231 = \DateTimeInterface::RFC7231; + const RFC2822 = \DateTimeInterface::RFC2822; + const RFC3339 = \DateTimeInterface::RFC3339; + const RFC3339_EXTENDED = \DateTimeInterface::RFC3339_EXTENDED; + const RSS = \DateTimeInterface::RSS; + const W3C = \DateTimeInterface::W3C; } From eb717baebfad9aa603bd1ab399e4473969a62caf Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 18:54:15 +0000 Subject: [PATCH 111/193] build: Refactor and clean CircleCI config --- .circleci/config.yml | 88 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1f081c1..a834c21 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,43 +1,97 @@ version: 2.1 + orbs: codecov: codecov/codecov@1.0.4 + jobs: - build: + php-statistics: docker: - - image: circleci/php:7.4 + - image: cimg/php:7.4 working_directory: ~/php-datatypes steps: - # GIT - checkout - # SYSTEM - run: name: Update System command: sudo apt-get update - run: name: Install CLOC command: sudo apt-get -y install cloc - # COMPOSER - run: - name: Install Composer Dependencies - command: composer install - # STATISTICS + name: PHP Version + command: php -v - run: name: Project's Statistics command: git ls-files | xargs cloc - # TESTS + + php-cs: + docker: + - image: cimg/php:7.4 + working_directory: ~/php-datatypes + steps: + - checkout - run: - name: Run Tests - command: phpdbg -qrr vendor/bin/phpunit --coverage-clover ~/build/coverage-report + name: Composer Install + command: composer install - run: - name: Check coding standards in /src - command: vendor/bin/phpcs --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing src + name: Check Coding Standards for PHPv7.4 + command: | + vendor/bin/phpcs --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing src + vendor/bin/phpcs --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing tests + + php-74: + docker: + - image: cimg/php:7.4 + working_directory: ~/php-datatypes + steps: + - checkout + - run: + name: Composer Install + command: composer install - run: - name: Check coding standards in /tests - command: vendor/bin/phpcs --standard=PSR2 --exclude=Squiz.WhiteSpace.ControlStructureSpacing tests + name: Run Tests for PHPv7.4 + command: phpdbg -qrr vendor/bin/phpunit --coverage-clover ~/build/coverage-report - store_artifacts: path: ~/build/coverage-report - - store_test_results: - path: ~/build/coverage-report - codecov/upload: file: ~/build/coverage-report + php-80: + docker: + - image: cimg/php:8.0 + working_directory: ~/php-datatypes + steps: + - checkout + - run: + name: Composer Install + command: composer install + - run: + name: Run Tests for PHPv8.0 + command: phpdbg -qrr vendor/bin/phpunit + + php-81: + docker: + - image: cimg/php:8.1 + working_directory: ~/php-datatypes + steps: + - checkout + - run: + name: Composer Install + command: composer install + - run: + name: Run Tests for PHPv8.1 + command: phpdbg -qrr vendor/bin/phpunit + +workflows: + ci-flow: + jobs: + - php-statistics + - php-cs + - php-74: + requires: + - php-cs + - php-80: + requires: + - php-cs + - php-81: + requires: + - php-cs From 90f28780ebc7c1edecb5a96e4e9ce006ab49e01b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 18:55:09 +0000 Subject: [PATCH 112/193] Build: Remove unnecessary dev dependency --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 0298bfb..09c5382 100755 --- a/composer.json +++ b/composer.json @@ -25,7 +25,6 @@ "php": "^7.4||^8.0" }, "require-dev": { - "ext-xdebug": "*", "phpunit/phpunit": "^9.0", "squizlabs/php_codesniffer": "^3.0@dev", "nesbot/carbon": "^2.0@dev" From ad660b4793a28bc8fe5ca0d17a1be2e07bc57b5f Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 20:02:19 +0000 Subject: [PATCH 113/193] build: Remove redundant CircleCI configuration --- .circleci/config.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a834c21..00740ff 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,7 +4,7 @@ orbs: codecov: codecov/codecov@1.0.4 jobs: - php-statistics: + php-cs: docker: - image: cimg/php:7.4 working_directory: ~/php-datatypes @@ -22,13 +22,6 @@ jobs: - run: name: Project's Statistics command: git ls-files | xargs cloc - - php-cs: - docker: - - image: cimg/php:7.4 - working_directory: ~/php-datatypes - steps: - - checkout - run: name: Composer Install command: composer install @@ -84,7 +77,6 @@ jobs: workflows: ci-flow: jobs: - - php-statistics - php-cs - php-74: requires: From 855e2e0080ea77134c1a2621a2f7f42f864443fd Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 20:02:53 +0000 Subject: [PATCH 114/193] docs: Add initial documentation for CircleCI configuration --- .circleci/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .circleci/README.md diff --git a/.circleci/README.md b/.circleci/README.md new file mode 100644 index 0000000..d2adead --- /dev/null +++ b/.circleci/README.md @@ -0,0 +1,23 @@ +# CircleCI Continuous Integration + +PHP-Datatypes uses CircleCI for code testing and coverage. + +The project currently supports version `7.4`, `8.0` & `8.1` of PHP. + +## Installation + +In order to validate CircleCI configuration, you'll need to install locally `circleci` cli utility: + +```bash +sudo snap install circlec +``` + +After installation of `circleci` utility, you can assess Cding Standards and Testing in multiple supported PHP versions. + +## Coding Standards + +Run `circleci local execute --job php-cs` from the route of the project in order to test Coding Standards. + +## Testing + +Run `circleci local execute --job php-74` to test `v7.4`, or replace `74` with `80` or `81`, for versions v`8.0` and `v8.1`. From 71dff433e58a52f0d6396e329e95199687c46f95 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 20:04:27 +0000 Subject: [PATCH 115/193] docs: Add missing validation documentation --- .circleci/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/README.md b/.circleci/README.md index d2adead..bae5177 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -14,6 +14,8 @@ sudo snap install circlec After installation of `circleci` utility, you can assess Cding Standards and Testing in multiple supported PHP versions. +In order to test CircleCI configiuration file, you can run `circleci config validate`. + ## Coding Standards Run `circleci local execute --job php-cs` from the route of the project in order to test Coding Standards. From 1ae5e3f822ed2312e4e9927721649ee4c1ad2882 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 20:08:25 +0000 Subject: [PATCH 116/193] docs: Improve CS documentation --- .circleci/README.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.circleci/README.md b/.circleci/README.md index bae5177..e074b34 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -12,13 +12,38 @@ In order to validate CircleCI configuration, you'll need to install locally `cir sudo snap install circlec ``` -After installation of `circleci` utility, you can assess Cding Standards and Testing in multiple supported PHP versions. +After installation of `circleci` utility, you can assess Coding Standards and Testing in multiple supported PHP versions. In order to test CircleCI configiuration file, you can run `circleci config validate`. ## Coding Standards -Run `circleci local execute --job php-cs` from the route of the project in order to test Coding Standards. +Run `circleci local execute --job php-cs` from the root of the project in order to test Coding Standards. + +Coding standards' job will also give you information about the environment and project it's running on: + +### PHP Version + +```bash +PHP 7.4.26 (cli) (built: Nov 23 2021 21:06:06) ( NTS ) +Copyright (c) The PHP Group +Zend Engine v3.4.0, Copyright (c) Zend Technologies +``` + +### Project's Statistics + +```bash +------------------------------------------------------------------------------- +Language files blank comment code +------------------------------------------------------------------------------- +PHP 108 1129 4016 4139 +Markdown 27 171 0 431 +YAML 1 6 0 83 +JSON 1 0 0 47 +------------------------------------------------------------------------------- +SUM: 137 1306 4016 4700 +------------------------------------------------------------------------------- +``` ## Testing From 642abc332aa6bab80573bb12de23af7ea915fe12 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 20:09:22 +0000 Subject: [PATCH 117/193] docs: Fix typo --- .circleci/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/README.md b/.circleci/README.md index e074b34..959b936 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -9,7 +9,7 @@ The project currently supports version `7.4`, `8.0` & `8.1` of PHP. In order to validate CircleCI configuration, you'll need to install locally `circleci` cli utility: ```bash -sudo snap install circlec +sudo snap install circleci ``` After installation of `circleci` utility, you can assess Coding Standards and Testing in multiple supported PHP versions. From 303e5d468aeea11b7698d222579405eb7c5bef74 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 20:53:23 +0000 Subject: [PATCH 118/193] docs: Add CircleCI & CodeCov links for project --- .circleci/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.circleci/README.md b/.circleci/README.md index 959b936..0bdbceb 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -45,6 +45,14 @@ SUM: 137 1306 4016 4700 ------------------------------------------------------------------------------- ``` +In order to access Code Coverage reports, please go to [CodeDov](https://app.codecov.io/gh/HRADigital/php-datatypes). + ## Testing -Run `circleci local execute --job php-74` to test `v7.4`, or replace `74` with `80` or `81`, for versions v`8.0` and `v8.1`. +Run `circleci local execute --job php-74` to test `v7.4`, or replace `74` with `80` or `81`, for versions `v8.0` & `v8.1`: + +- `circleci local execute --job php-74` +- `circleci local execute --job php-80` +- `circleci local execute --job php-81` + +In order to access CI reports, please got to [CircleCI](https://app.circleci.com/pipelines/github/HRADigital/php-datatypes?filter=all). From 52df25d9eceeecb2ffa8f0f436cb4679a8d4a6da Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 5 Mar 2022 21:10:14 +0000 Subject: [PATCH 119/193] docs: Add Codacy documentation --- .circleci/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.circleci/README.md b/.circleci/README.md index 0bdbceb..6f3c233 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -16,6 +16,12 @@ After installation of `circleci` utility, you can assess Coding Standards and Te In order to test CircleCI configiuration file, you can run `circleci config validate`. +## Quick links + +- [CodeDov](https://app.codecov.io/gh/HRADigital/php-datatypes) +- [Codacy](https://app.codacy.com/gh/HRADigital/php-datatypes/dashboard) +- [CircleCI](https://app.circleci.com/pipelines/github/HRADigital/php-datatypes?filter=all) + ## Coding Standards Run `circleci local execute --job php-cs` from the root of the project in order to test Coding Standards. @@ -47,6 +53,8 @@ SUM: 137 1306 4016 4700 In order to access Code Coverage reports, please go to [CodeDov](https://app.codecov.io/gh/HRADigital/php-datatypes). +In order to access Code Quality reports, please go to [Codacy](https://app.codacy.com/gh/HRADigital/php-datatypes/dashboard). + ## Testing Run `circleci local execute --job php-74` to test `v7.4`, or replace `74` with `80` or `81`, for versions `v8.0` & `v8.1`: From bd5ee3bb3cfdb66252a2bcd9d657708c0cf6ab36 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 13:47:30 +0000 Subject: [PATCH 120/193] docs: Improve main documentation and ValueObject's tutorial --- README.md | 55 +++--- src/ValueObjects/README.md | 336 +++++++++++++++++++++++++------------ 2 files changed, 253 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index 17cc2f7..bec3f36 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Master branch build status [![Build](https://img.shields.io/circleci/build/github/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) [![Coverage](https://img.shields.io/codecov/c/github/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) -[![Quality](https://app.codacy.com/project/badge/Grade/de03155208c64196899848458c2ced8a)](https://github.com/HRADigital/php-datatypes) +[![Quality](https://app.codacy.com/project/badge/Grade/de03155208c64196899848458c2ced8a)](https://www.codacy.com/gh/HRADigital/php-datatypes/dashboard?utm_source=github.com&utm_medium=referral&utm_content=HRADigital/php-datatypes&utm_campaign=Badge_Grade) [![Downloads](https://img.shields.io/github/downloads/HRADigital/php-datatypes/total.svg)](https://github.com/HRADigital/php-datatypes) [![Licence](https://img.shields.io/github/license/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) [![Version](https://img.shields.io/github/release/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) @@ -11,44 +11,45 @@ ## About -**PHP Datatypes** is a project meant to conviniently aggregate commonly used **Scalar objects**, other **datatypes** and -**Data Transfer Object**'s base classes into a single package. +**PHP Datatypes** is meant to provide an easy way to create your Value Objects/Entities, in a fast and platform agnostic way, +that promotes: -Some of the projects that inspired this one, are mainly [Nikita Popov's Scalar Objects](https://github.com/nikic/scalar_objects), -but also [Martin Helmich's Scalar Classes](https://github.com/martin-helmich/php-scalarclasses/) and -[Michael Hall's Datatypes](https://github.com/themichaelhall/datatypes/). +- Code reusability +- Data normalization +- Type hint enforcement +- Full data serializing +- No 3rd party dependency apart from PHP. Clean/Self reliant project. -## Requirements +An Entity/ValueObject that extends [AbstractValueObject](/HRADigital/php-datatypes/blob/master/src/ValueObjects/AbstractValueObject.php) +will be built using predefined/tested [Traits](/HRADigital/php-datatypes/tree/master/src/Traits/Entities) for each of the class attributes, +leaving your class definition cleaned/free for your business logic implementation. -- PHP >= 7.4 +This will also allow you to reuse/load your objects with data that can come from a Database, Webservice, Event payload, etc... -## Installation +Getters/Accessors for class attributes will return ValueObjects instead of primitive types, as much as possible. All these datatypes will +also be included in the package, as it doesn't have any dependencies apart from, PHP itself. -``` bash -$ composer require hradigital/php-datatypes -``` +To learn how to use this package, please go to [AbstractValueObject](/HRADigital/php-datatypes/blob/master/src/ValueObjects/) documentation. -### Project's purpose/mission +### Inspiration -The project's mission is based on the following 4 principles: +Some of the projects that inspired this one, are mainly [Nikita Popov's Scalar Objects](/nikic/scalar_objects), +but also [Martin Helmich's Scalar Classes](/martin-helmich/php-scalarclasses/) and +[Michael Hall's Datatypes](/themichaelhall/datatypes/). -- Deliver the biggest amount of datatypes on a single project, that can serve as base code for many different projects. -- Be a self reliant project, without extra dependencies, that only depends on PHP's version and/or native code. -- Provide reliable code, which is fully tested/coverade. -- Provide fully documented code. +Due to the "_No 3rd party dependency_" rule, this package will use some simplified versions of more popular datatypes. Some examples are: -### When not to use this project +- [synfony/string](/symfony/string), for String related manipulations. +- [nesbot/carbon](/briannesbitt/Carbon), for DateTime manipulations. +- ... -**PHP Datatypes** provides easily used, simple class interfaces, and each of the supplied datatypes is not meant to fully -provide all code combinations and/or functionality. It's code created for developer's convinience. +## Requirements & Installation -If you need a more comprehensive handling of each datatype, there are other alternatives online. Here are a few: +- PHP >= 7.4||8.* -- `nesbot/carbon` for Datetime's processing -- `symfony/string` for String's processing -- `moneyphp/money` for currency's processing -- `egulias/email-validator` for e-mail's processing -- ... +```bash +composer require hradigital/php-datatypes +``` ## Usage diff --git a/src/ValueObjects/README.md b/src/ValueObjects/README.md index eff9dab..a0a4254 100755 --- a/src/ValueObjects/README.md +++ b/src/ValueObjects/README.md @@ -1,4 +1,4 @@ -# Domain Value Objects +# Value Objects & Entities **Value Object** are objects used to transport data **from** and **to** the **Domain**, but also play an important part in validating data integrity on a record. @@ -9,180 +9,294 @@ in validating data integrity on a record. ## Building a new Value Object -The first thing you should assess, is the context of the **Value Object** you're trying to model. +To start building your ValueObjects/Entities with this package, you'll need to create your class extending `AbstractValueObject`. +Afterwards, you should include the corresponding `Traits` for each one of the fields your object will have. -Similar contexted **Value Objects**, will be placed near each other in the filesystem/namespace. +### Loading data into Value Object -All **Value Objects** should be located in the `HraDigital\Basetypes\ValueObjects` namespace, followed by the same segments -present in the file system, up to the class definition. +After you define your ValueObject/Entity structure, you can load data into it by passing an associative array to its Constructor. -### Value Objects are immutable +If the attribute is not set in the class through Attribute Traits, it will not be loaded into the object's state. -Value Objects should be treated as immutable, and therefore, once data is loaded into them, it should not be changed. - -In order to change the values on a Value Object, a new one whould be created, opposite to Entities that can change state. +```php +$user = new UserEntity([ + 'id' => 123, + 'active' => true, + 'name' => ' John Doe ', +]); -### Declaring Value Object's fields/attributes +echo $user->getName(); // Prints ' John Doe ' +echo $user->getName()->trim()->toUpper()->replace(' ', '-'); // Prints 'JOHN-DOE' +echo $user->getName(); // Prints ' John Doe ' again, as Attribute is immutable. +``` -You should declare as `protected`, all the **Value Object** fields you'll want loaded into the class, with the same -name they have in the **persistence layer**, when applicable. +### Field Traits -Whenever possible, use **Traits** for commonly used attributes. This will facilitate reusing fields in different -attributes across the application. +Each Field Trait will have 3 required class members: -If we're talking about a Database as a **persistence layer**, and a given datatable has the _fields_ **name**, -**surname** and **date_of_birth**, the **Value Object** should have the following `protected` _attributes_: +- Attribute (`protected`) - Holds field's state. +- Casting method (`protected`) - Casts primite value to strongly typed object (eg:. `"SomeString"` => `Str::class`). +- Getter (`public`) - Provides a way to access the field's value. ```php -class MyValueObject extends AbstractValueObject +trait HasEmailTrait { - protected Str $name; - protected Str $surname; - protected Datetime $date_of_birth; + protected ?EmailAddress $email = null; + + protected function castEmail(string $email): void + { + $this->email = EmailAddress::create($email); + } + + public function getEmail(): ?EmailAddress + { + return $this->email; + } } ``` -### Declaring Accessor methods for the Attributes you want visible +You can build whole objects using these `Traits`. -For each attribute that you want to make available from outside the Value Object, you should declare an accessor/getter. -These method's names can be whatever you want, they should be declared `public`, and should return the required value. +By default, when adding these `Traits`, your object will be immutable. +If you're creating a mutable Entity, you'll need to define state mutation logic within your class. -For an attribute called `$name`, a good accessor method's signature would be `public function name(): string;`. +```php +class MyEntity extends AbstractValueObject +{ + use HasPositiveIntegerIDTrait, + HasActiveTrait, + HasNameTrait, + HasEmailTrait, + HasCreatedAtTrait, + HasUpdatedAtTrait; +} +``` -### Casting and/or Sanitizing values into the Value Object's state +### Field Mapping & Requirement -Each attribute should have a `protected` mutator starting with **cast** followed by the capitalized attribute name, without -the underscores. Eg:. An Attribute called `$user_id` would have a `protected` mutator/sanitizing method called -`castUserId(int $id)`. This mutator will be called internally, and will sanitize the attribute's value before setting it. +As these ValueObjects/Entities are meant to be platform agnostic, they might be loaded into your application from different sources. +Eg:. Database, Webservice, WebRequests, Events, ... -### Rules for multiple attributes +Therefore, and because the same information might be represented with slight structural changes, `AbstractValueObject` provides you +with field mapping when loading data into it. Mapping will occour before state is loaded into the object. -Sometimes, your Value Object might have more than one attributes which are dependent on each other. When this happens, -your should declare a **rule** in your **Value Object**. +You should define which fields names are mapped to which fields, in your class definition. -**Rules** are just special methods, which take the initial data array as reference, and perform operations on it, breaking it -if required. You can have as many rules as required, and they should be declared in the Value Object for which they exist. +You can also define which fields are necessary on object's instantiation, by adding them to a `$required` array. +If these fields are not present while loading the class, and Exception will be raised. -In order to declare a **rule**, you'll just need to declare a `protected` method, which takes an array of fields as reference. -Eg:. `protected function ruleMySpecialRule(array $fields): array;`. +In the following example, the names `full_name`, `fullname`, `fullName` will all be mapped to `name`, and we'll set `name` & `active` +as required fields for the class: -### Setting Attributes as Required +```php +class MyEntity extends AbstractValueObject +{ + use HasPositiveIntegerIDTrait, + HasActiveTrait, + HasNameTrait; + + protected array $maps = [ + 'full_name' => 'name', + 'fullname' => 'name', + 'fullName' => 'name', + ]; -Required attributes, are attributes that will need to be present when first loading the Value Object. If not present, -Value Object loading functionality will raise an Exception, and Value Object will not be instantiated. These are usually -fields that don't have a default value in the persistence layer. + protected array $required = [ + 'active', + 'name', + ]; +} +``` -In order to set attributes as required, you'll just need to list them in the `protected` array named `$required`. -Eg:. `protected $required = ['name', 'surname'];` +### Field Rules & onLoad Event Handlers -### Mapping different names to Attributes +You can define rules for the object, which will manipulate the loaded data bafore it is set on the object's state. You can also +add `onLoad` event handlers to manipulate data after class state is loaded, but before the object's instanciation is finalized. -You may wish to hide internal Attribute's names, or just have them load data when providing different names in the loading array. -One possible example is, if the fields in the Client's request, are different from the ones used internally in the Value Object. -You can do this by mapping those field names in the `protected $maps = [];` array. +For rules, define a as many `protected` methods as you'd like, with a prefix `rule`, that will take a `$fields` array, +and return it after mmanipulation. -As a **key**, you'll set the mapping attribute name, and in the **value**, you'll set the native Entity's attribute name. +For the `onLoad` event handlers, define as many as you'de like with a prefix `onLoad`, and no parameters nor returned type. +These handlers will get called, after the object's state is alreayd loaded. ```php -protected $maps = [ - 'first' => 'name', - 'last' => 'surname', -]; +class UserEntity extends AbstractValueObject +{ + use HasPositiveIntegerIDTrait, + HasNameTrait; + + protected function ruleConcatenateFirstAndLastNames(array $fields): array + { + if (isset($fields['first']) && isset($fields['last'])) { + $fields['name'] = $fields['first'] . ' ' . $fields['last']; + } + + return fields; + } + + protected function onLoadConvertNameToUpperCase(): void + { + $this->name = $this->name->toUpper(); + } +} + +$user = new UserEntity([ + 'id' => 123, + 'first' => 'John', + 'last' => 'Doe', +]); + +echo $user->getName(); // Prints 'JOHN DOE' ``` -## Using the Value Object +## Accessing & Serializing data + +By default, your ValueObject's/Entity's attributes can be accessed by Getters available in the different `Traits`, but you might +want to retrieve the full record in your application. +`AbstractValueObject` provides you with two methods for this: -### Example Value Object with Required attributes only +- `getAttributes()` will get you the attributes, for the first level record only. +- `toArray()` will return a full representation of record, including nested ValueObjects/Entities in it (eg:. _Aggregate Roots_). + +You can also easily serialize and unserialize objects that extend `AbstractValueObject`: ```php -class Person extends AbstractvalueObject -{ - protected Str $name; - protected Str $surname; +$oldUser = new UserEntity([ + 'id' => 123, + 'name' => 'John Doe', +]); - protected array $required = ['name', 'surname']; -} +$serialized = serialize($oldUser); +$newUser = unserialize($serialized); + +echo $newUser->getName(); // Prints 'John Doe' ``` -### Example Value Object, where we add casting/sanitizing methods +### JSON Serializing + +Apart from easy serializing, classes extending `AbstractValueObject` can also easily be converted to JSON, if you which to output +them, for example, in an API Response. + +On top of this, and because you might want to protect certain fields, you can also define which fields won't be serializable into +JSON, by filling in a `$guarded` internal array. ```php -class Person extends AbstractValueObject +class MyEntity extends AbstractValueObject { - // ... Previous content. + use HasPositiveIntegerIDTrait, + HasNameTrait, + HasEmailTrait, + HasPasswordTrait, + HasCreatedAtTrait; + + protected array $guarded = [ + 'email', + 'password', + ]; +} - protected function castName(string $name): void - { - $this->name = Str::create($name)->trim(); - } +$user = new UserEntity([ + 'id' => 123, + 'name' => 'John Doe', + 'email' => 'john.doe@domain.tld', + 'password' => 'poiouashfiahsifuahpsdfphapsdfpoasopasyeytnracsyntaynetyaoeya', + 'created_at' => '2022-02-02 12:30:00', +]); - protected function castSurname(string $surname): void - { - $this->surname = Str::create($surname)->trim(); - } +$json = json_encode($user); +echo $json; // NO EMAIL OR PASSWORD + +/* +{ + "id": 123, + "name": "John Doe", + "created_at": "2022-02-02 12:30:00" } +*/ ``` -### Example Value Object, where we add accessor methods +## Manipulating State + +If you want to keep track of the object's state, you can include the Trait `CanProcessEntityStateTrait` in your class. + +This `Trait` can provide you information, about attributes that have been changed since load. ```php -class Person extends AbstractValueObject +class UserEntity extends AbstractValueObject { - // ... Previous content. + use HasPositiveIntegerIDTrait, + HasActiveTrait, + HasNameTrait, + CanProcessEntityStateTrait; - public function name(): Str + public function activate(): void { - return $this->name; - } - - public function surname(): Str - { - return $this->surname; + $this->active = true; } } -``` - -### Using our Value Object, from within our application -```php -$person = new Person([ - 'name' => 'John', - 'surname' => 'Doe', +$user = new UserEntity([ + 'id' => 123, + 'active' => false, + 'name' => 'John Doe', ]); -// Echoing all the 'properties'. -echo $person->name(); // Echoes 'John' -echo $person->surname(); // Echoes 'Doe' +$user->isDirty(); // FALSE +$user->activate(); +$user->isDirty(); // TRUE -// The following code will break, because both $name and $surname are required. -$breaks = new Person([ - 'name' => 'John', -]); +/* +$user->getDirty(); + +OUTPUTS +[ + 'active' => true, +] +*/ ``` -### Mapping different names to our attributes +### Reacting to State changes + +You can react to state changes, by adding a second Trait `CanProcessOnUpdateEventsTrait` to your class. + +Afterwards, and at this point, your class will need to call `$this->triggerOnUpdate();` inside your Mutators/Setters, +in order to trigger all "_onUpdate_" event handlers. This is not done automatically, at this point. -Mapping definition: +If you need to react to this event, you can declare as many `protected` methods as you which, with the prefix `onUpdate`, +without any parameters or returned type. ```php -class Person extends AbstractValueObject +class UserEntity extends AbstractValueObject { - // ... Previous content. + use HasPositiveIntegerIDTrait, + HasActiveTrait, + HasNameTrait, + HasCreatedAtTrait, + CanProcessEntityStateTrait, + CanProcessOnUpdateEventsTrait; + + public function activate(): void + { + $this->active = true; + $this->triggerOnUpdate(); + } - protected $maps = [ - 'first' => 'name', - 'last' => 'surname', - ]; -} -``` + public function rename(Str $newName): void + { + $this->name = $newName; + $this->triggerOnUpdate(); + } -```php -$person = new Person([ - 'first' => 'John', - 'last' => 'Doe', -]); + protected function onUpdateChangeUpdatedAtField(): void + { + $this->updated_at = DateTime::now(); + } +} -// Echoing all the 'properties'. -echo $person->name(); // Echoes 'John' -echo $person->surname(); // Echoes 'Doe' +$user->getUpdatedAt(); // Initially loaded DateTime. +$user->activate(); +$user->rename( + Str::create('John Smith') +); +$user->getUpdatedAt(); // Updated DateTime. ``` From 119b6fa4d1b0a280d07f7b4737101e1d725d2ca5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 13:54:29 +0000 Subject: [PATCH 121/193] docs: Fix typos --- src/ValueObjects/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ValueObjects/README.md b/src/ValueObjects/README.md index a0a4254..8ca5ac3 100755 --- a/src/ValueObjects/README.md +++ b/src/ValueObjects/README.md @@ -82,8 +82,8 @@ with field mapping when loading data into it. Mapping will occour before state i You should define which fields names are mapped to which fields, in your class definition. -You can also define which fields are necessary on object's instantiation, by adding them to a `$required` array. -If these fields are not present while loading the class, and Exception will be raised. +You can also define which fields are required on object's instantiation, by adding them to a `$required` array. +If these fields are not present while loading the class, an Exception will be raised. In the following example, the names `full_name`, `fullname`, `fullName` will all be mapped to `name`, and we'll set `name` & `active` as required fields for the class: @@ -113,11 +113,11 @@ class MyEntity extends AbstractValueObject You can define rules for the object, which will manipulate the loaded data bafore it is set on the object's state. You can also add `onLoad` event handlers to manipulate data after class state is loaded, but before the object's instanciation is finalized. -For rules, define a as many `protected` methods as you'd like, with a prefix `rule`, that will take a `$fields` array, -and return it after mmanipulation. +For rules, define as many `protected` methods as you'd like, with a prefix `rule`, that will take a `$fields` array, +and return it after manipulation. -For the `onLoad` event handlers, define as many as you'de like with a prefix `onLoad`, and no parameters nor returned type. -These handlers will get called, after the object's state is alreayd loaded. +For the `onLoad` event handlers, define as many as you'de like with a prefix `onLoad`, with no parameters or returned type. +These handlers will get called, after the object's state is already loaded. ```php class UserEntity extends AbstractValueObject From e5f9ebe92039de890db61be19ed4e019265d5ffb Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 17:06:45 +0000 Subject: [PATCH 122/193] refactor: Small improvement on primitive conversion --- .../ValueObjects/HasConversionToPrimitiveValuesTrait.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php index 4263fe8..b5df150 100644 --- a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php +++ b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php @@ -32,10 +32,10 @@ private function convertIntoPrimitiveValues(array $fields, bool $objectAsJson = // If is not an Object not an Array, returns the actual value of the Field. if ($value instanceof AbstractValueObject || $value instanceof EntityCollection) { $converted[$field] = $objectAsJson ? $value->jsonSerialize() : $value->toArray(); - } elseif (\is_object($value) && \method_exists($value, '__toString')) { + } elseif (\method_exists($value, '__toString')) { $converted[$field] = (string) $value; - } elseif (\is_array($value) || \is_object($value)) { - $converted[$field] = \json_encode($value); + } elseif (\is_object($value)) { + $converted[$field] = (array) $value; } else { $converted[$field] = $value; } From 225d7f22398daca21e19744f66562c155d68b9bb Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 17:08:56 +0000 Subject: [PATCH 123/193] refactor: Remove unnecessary registerOnLoadEvents --- src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php | 9 +-------- src/ValueObjects/AbstractValueObject.php | 1 - 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php index 3b58bde..e3ebe36 100644 --- a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php +++ b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php @@ -29,19 +29,12 @@ trait CanProcessOnLoadEventsTrait * @return void */ private function triggerOnLoad(): void - { - foreach ($this->onLoadEvents as $onLoad) { - $this->$onLoad(); - } - } - - private function registerOnLoadEvents(): void { // Loops through all the class' methods, and loads the necessary ones in // the corresponding containers. foreach (\get_class_methods($this) as $method) { if (\strpos($method, self::$ONLOADPREFIX) === 0 && \strlen($method) > \strlen(self::$ONLOADPREFIX)) { - $this->onLoadEvents[] = $method; + $this->$method(); } } } diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php index 0ea54f6..79ac7f8 100644 --- a/src/ValueObjects/AbstractValueObject.php +++ b/src/ValueObjects/AbstractValueObject.php @@ -79,7 +79,6 @@ private function loadInstance(array $fields): void $this->registerUsableFields(); $this->registerAttributeCastingList(); $this->registerAttributeRuleList(); - $this->registerOnLoadEvents(); // Translates supplied fields, into existing ones. $mapped = $this->translateToMappedFields($fields); From 39d45e051e8fcafec1b669ff6e12424a5ea5cb40 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 18:36:52 +0000 Subject: [PATCH 124/193] refactor: Make Str a standalone class --- src/Scalar/Str.php | 452 ++++++++++++++------- tests/Unit/Scalar/StrTest.php | 735 +++++++++++++++++++++++++++++++--- 2 files changed, 992 insertions(+), 195 deletions(-) diff --git a/src/Scalar/Str.php b/src/Scalar/Str.php index a4e0914..9ebbf24 100644 --- a/src/Scalar/Str.php +++ b/src/Scalar/Str.php @@ -20,8 +20,11 @@ * @copyright HraDigital\Datatypes * @license MIT */ -class Str extends AbstractBaseString +class Str { + /** @var string $value - Internal string value for the instance. */ + protected string $value = ''; + /** * Creates a new instance of Str based on a string value. * @@ -33,6 +36,29 @@ public static function create(string $value): Str return new Str($value); } + /** + * Instantiates an AbstractBaseString child class. + * + * Constructor should be kept protected, to allow child class manipulation, if required. + * + * @param string $value - Instance's initial state value. + * @return void + */ + protected function __construct(string $value) + { + $this->value = $value; + } + + /** + * Magic method that will print out the native string representation of the instance. + * + * @return string + */ + public function __toString(): string + { + return $this->value; + } + /** * Compares the values of 2 separate instances. * @@ -41,296 +67,401 @@ public static function create(string $value): Str * @param Str $string - Another Str instance to compare to. * @return bool */ - public function equals(Str $string): bool + public function match(Str $string): bool + { + return $this->equals((string) $string); + } + + /** + * Compares the instance's value, with the supplied native string. + * + * Returns TRUE if the 2 values match. FALSE otherwise. + * + * @param string $string - Another string to compare with. + * @return bool + */ + public function equals(string $string): bool + { + return ($this->value === $string); + } + + /** + * Returns the Instance's character length. + * + * @return int + */ + public function getLength(): int { - return parent::doEquals((string) $string); + return \strlen($this->value); } /** - * Checks if the instance contains the supplied $search value. + * Counts the number of words in the String. + * + * @return int + */ + public function getWordCount(): int + { + return \str_word_count($this->value); + } + + /** + * Checks if the instance's value contains the supplied $search string. * * Returns TRUE if found. FALSE otherwise. * - * @param Str $search - Non empty string to search for in the instance. + * @param string $search - Non empty string to search for in the instance. * * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ - public function contains(Str $search): bool + public function contains(string $search): bool { - return parent::doContains((string) $search); + // Validates supplied parameter. + if (\strlen($search) === 0) { + throw NonEmptyStringException::withName('$search'); + } + + return ($this->indexOf($search) !== null); } /** - * Searches and returns the index in the instance, of the $search string. + * Searches and returns the character index in the instance, of the $search string. * * If a $start is specified, search will start this number of characters counted from * the beginning of the string. If $start is negative, the search will start this number * of characters counted from the end of the string. * - * If the $search is not found inthe instance's value, NULL is returned. + * If the $search is not found in the instance's value, NULL is returned. * - * @param Str $search - String to search for in the instance. - * @param int $start - Search offset start. Defaults to ZERO. + * @param string $search - String to search for in the instance. + * @param int $start - Search offset start. Defaults to ZERO. * * @throws NonEmptyStringException - If $search value is an empty string. * @throws ParameterOutOfRangeException - If the $start is either too small, or too long. * @return int|null */ - public function indexOf(Str $search, int $start = 0): ?int + public function indexOf(string $search, int $start = 0): ?int { - return parent::doIndexOf((string) $search, $start); + // Validates supplied parameters. + if (\strlen($search) === 0) { + throw NonEmptyStringException::withName('$search'); + } + if ($start) { + $this->validateStartAndLength($start, null); + } + + // Collects the string position. + $index = \strpos($this->value, $search, $start); + + // If false is returned, no index was found, and therefore NULL is returned. + if ($index === false) { + return null; + } + + return $index; } /** * Checks if the instance's value starts with the supplied string. * - * @param Str $search - Non empty string to search for in the instance. + * @param string $search - Non empty string to search for in the instance. * * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ - public function startsWith(Str $search): bool + public function startsWith(string $search): bool { - return parent::doStartsWith((string) $search); + // Validates supplied parameter. + if (\strlen($search) === 0) { + throw NonEmptyStringException::withName('$search'); + } + + return ($this->indexOf($search) === 0); } /** * Checks if the instance's value ends with the supplied string. * - * @param Str $search - Non empty string to search for in the instance. + * @param string $search - Non empty string to search for in the instance. * * @throws NonEmptyStringException - If supplied $search is empty. * @return bool */ - public function endsWith(Str $search): bool + public function endsWith(string $search): bool { - return parent::doEndsWith((string) $search); + // Validates supplied parameter. + if (\strlen($search) === 0) { + throw NonEmptyStringException::withName('$search'); + } + + return ( + ((string) $this->subString((0 - \strlen($search)))) === $search + ); } /** * Counts the number of substring occurrences in the instance's value. * - * @param Str $search - Non empty string to search for in the instance. + * @param string $search - Non empty string to search for in the instance. * @param int $start - The sub-string's offset/start. - * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. + * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. * * @throws NonEmptyStringException - If supplied $search is empty. * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. * @return int */ - public function count(Str $search, int $start = 0, ?int $length = null): int + public function count(string $search, int $start = 0, ?int $length = null): int + { + // Validates supplied $search parameter. + if (\strlen($search) === 0) { + throw NonEmptyStringException::withName('$search'); + } + + // Validates supplied $start and $length. + $this->validateStartAndLength($start, $length); + + // Checks if $length was defined. + if ($length) { + return \substr_count($this->value, $search, $start, $length); + } + + return \substr_count($this->value, $search, $start); + } + + /** + * Validates a character $length, based on the instance value's length, and supplied $start. + * + * @param int $start - The sub-string's offset/start. + * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. + * + * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. + * @return void + */ + private function validateStartAndLength(int $start, ?int $length): void { - return parent::doCount((string) $search, $start, $length); + // Calculates the absolute values for validations. + $absStart = (int) \abs($start); + $absLength = $length ? (int) \abs($length) : null; + + // Validates the starting value. + if ($absStart > $this->getLength()) { + throw ParameterOutOfRangeException::withName('$start'); + } + + // If supplied $length is NULL, no further validations are required. + if ($length === null) { + return; + } + + // Checks if the supplied $length, doesn't exceed the available number of characters. + $startTooBig = ($start >= 0 && ($this->getLength() - $start < $absLength)); + $startTooSmall = ($start < 0 && $absLength > $absStart); + + if ($startTooBig || $startTooSmall) { + throw ParameterOutOfRangeException::withName('$length'); + } } /** * Trims instance's value on both ends. * - * @return Str + * @return self */ - public function trim(): Str + public function trim(): self { - return Str::create( - parent::doTrim() + return new self( + \trim($this->value) ); } /** * Trims instance's value only on the left. * - * @return Str + * @return self */ - public function trimLeft(): Str + public function trimLeft(): self { - return Str::create( - parent::doTrimLeft() + return new self( + \ltrim($this->value) ); } /** * Trims instance's value only on the right. * - * @return Str + * @return self */ - public function trimRight(): Str + public function trimRight(): self { - return Str::create( - parent::doTrimRight() + return new self( + \rtrim($this->value) ); } /** - * Converts the instance's value to Uppercase, and returns a new instance of the object. + * Converts the instance's value to Uppercase. * - * @return Str + * @return self */ - public function toUpper(): Str + public function toUpper(): self { - return Str::create( - parent::doToUpper() + return new self( + \mb_strtoupper($this->value) ); } /** - * Converts the instance's value first character to Uppercase, and returns a new instance - * of the object. + * Converts the instance's value first character to Uppercase. * - * @return Str + * @return self */ - public function toUpperFirst(): Str + public function toUpperFirst(): self { - return Str::create( - parent::doToUpperFirst() + return new self( + \ucfirst($this->value) ); } /** - * Converts the instance's value first character of each word to Upper Case, and returns a new instance - * of the object. + * Converts the instance's value first character of each word to Upper Case. * - * @param Str|null $delimiters - The optional delimiters contains the word separator characters. - * - * @return Str + * @param string $delimiters - The optional delimiters contains the word separator characters. + * @return self */ - public function toUpperWords(?Str $delimiters = null): Str + public function toUpperWords(string $delimiters = " \t\r\n\f\v"): self { - return Str::create( - parent::doToUpperWords($delimiters ?? " \t\r\n\f\v") + return new self( + \ucwords($this->value, $delimiters) ); } /** - * Converts the instance's value to Lowercase, and returns a new instance of the object. + * Converts the instance's value to Lowercase. * - * @return Str + * @return self */ - public function toLower(): Str + public function toLower(): self { - return Str::create( - parent::doToLower() + return new self( + \mb_strtolower($this->value) ); } /** - * Converts the instance's value first character to Lowercase, and returns a new instance - * of the object + * Converts the instance's value first character to Lowercase. * - * @return Str + * @return self */ - public function toLowerFirst(): Str + public function toLowerFirst(): self { - return Str::create( - parent::doToLowerFirst() + return new self( + \lcfirst($this->value) ); } /** - * This method returns a new instance padded on the left to the specified padding length minus + * This method returns a new instance padded on the LEFT to the specified padding length minus * the length of the instance's value. * * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will * only be padded by the value of 2. * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. + * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise + * it is padded with characters from $padString up to the limit. * - * @param int $length - Length of the padded value. - * @param Str|null $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padString's length. * * @throws NonEmptyStringException - If supplied $padding is empty. * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return Str + * @return self */ - public function padLeft(int $length, ?Str $padding = null): Str + public function padLeft(int $length, string $padding = " "): self { - if ($padding === null) { - $padding = Str::create(" "); + // Validates supplied parameters. + if ($length < 1) { + throw ParameterOutOfRangeException::withName('$length'); + } + if (\strlen($padding) === 0) { + throw NonEmptyStringException::withName('$padding'); } - return Str::create( - parent::doPadLeft($length, ((string) $padding ?? " ")) + return new self( + \str_pad($this->value, $length, $padding, STR_PAD_LEFT) ); } /** - * This method returns a new instance padded on the left, exactly to the specified padding length. + * This method returns a new instance padded on the LEFT, exactly to the specified padding length. * * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param Str|null $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws NonEmptyStringException - If supplied $padding is empty. * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return Str + * @return self */ - public function padLeftExtra(int $length, ?Str $padding = null): Str + public function padLeftExtra(int $length, string $padding = " "): self { - if ($padding === null) { - $padding = Str::create(" "); - } - - return Str::create( - parent::doPadLeftExtra($length, ((string) $padding ?? " ")) - ); + return $this->padLeft(($this->getLength() + $length), $padding); } /** - * This method returns a new instance padded on the right to the specified padding length minus + * This method returns a new instance padded on the RIGHT to the specified padding length minus * the length of the instance's value. * * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will * only be padded by the value of 2. * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise + * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param Str|null $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws NonEmptyStringException - If supplied $padding is empty. * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return Str + * @return self */ - public function padRight(int $length, ?Str $padding = null): Str + public function padRight(int $length, string $padding = " "): self { - if ($padding === null) { - $padding = Str::create(" "); + // Validates supplied parameters. + if ($length < 1) { + throw ParameterOutOfRangeException::withName('$length'); + } + if (\strlen($padding) === 0) { + throw NonEmptyStringException::withName('$padding'); } - return Str::create( - parent::doPadRight($length, ((string) $padding ?? " ")) + return new self( + \str_pad($this->value, $length, $padding, STR_PAD_RIGHT) ); } /** - * This method returns a new instance padded on the right, exactly to the specified padding length. + * This method returns a new instance padded on the RIGHT, exactly to the specified padding length. * * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise * it is padded with characters from $padding up to the limit. * - * @param int $length - Length of the padded value. - * @param Str|null $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. + * @param int $length - Length of the padded value. + * @param string $padding - The pad_string may be truncated if the required number of padding characters + * can't be evenly divided by the $padding's length. * * @throws NonEmptyStringException - If supplied $padding is empty. * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return Str + * @return self */ - public function padRightExtra(int $length, ?Str $padding = null): Str + public function padRightExtra(int $length, string $padding = " "): self { - if ($padding === null) { - $padding = Str::create(" "); - } - - return Str::create( - parent::doPadRightExtra($length, ((string) $padding ?? " ")) - ); + return $this->padRight(($this->getLength() + $length), $padding); } /** @@ -355,16 +486,26 @@ public function padRightExtra(int $length, ?Str $padding = null): Str * - If $length exceeds the remaining number of characters, after the $start calculation, an * Exception will be raised. * - * @param int $start - Start of the sub-string. Can be negative. - * @param int $length - Length of the sub-string. Can be negative. + * @param int $start - Start of the sub-string. Can be negative. + * @param int $length - Length of the sub-string. Can be negative. * * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return Str + * @return self */ - public function subString(int $start, int $length = null): Str + public function subString(int $start, int $length = null): self { - return Str::create( - parent::doSubString($start, $length) + // Validates supplied $start and $length. + $this->validateStartAndLength($start, $length); + + // Processes the substring. + if ($length !== null) { + $value = \substr($this->value, $start, $length); + } else { + $value = \substr($this->value, $start); + } + + return new self( + ($value ?? '') ); } @@ -372,59 +513,73 @@ public function subString(int $start, int $length = null): Str * This method returns a new instance with a portion of the original instance's value, starting at the beginning * of the value, with the number of characters specified in the $length parameter. * - * @param int $length - Length of the sub-string. Must be positive. + * @param int $length - Length of the sub-string. Must be positive. * * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. - * @return Str + * @return self */ - public function subLeft(int $length): Str + public function subLeft(int $length): self { - return Str::create( - parent::doSubLeft($length) - ); + // Validates parameter. + if ($length < 1) { + throw ParameterOutOfRangeException::withName('$length'); + } + + return $this->subString(0, $length); } /** * This method returns a new instance with a portion of the original instance's value, couting from the end * of the value, with the number of characters specified in the $length parameter. * - * @param int $length - Length of the sub-string. Must be positive. + * @param int $length - Length of the sub-string. Must be positive. * * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. - * @return Str + * @return self */ - public function subRight(int $length): Str + public function subRight(int $length): self { - return Str::create( - parent::doSubRight($length) - ); + // Validates parameter. + if ($length < 1) { + throw ParameterOutOfRangeException::withName('$length'); + } + + return $this->subString(0 - $length); } /** * This method returns the reversed value of the instance. * - * @return Str + * @return self */ - public function reverse(): Str + public function reverse(): self { - return Str::create( - parent::doReverse() + return new self( + \strrev($this->value) ); } /** * This method replaces a string's occurance by another, and returns a new instance with the new value. * - * @param Str $search - The string to search for. - * @param Str $replace - The search's replacement. + * @param string $search - The string to search for. + * @param string $replace - The search's replacement. * * @throws NonEmptyStringException - If either $search or $replace are empty. - * @return Str + * @return self */ - public function replace(Str $search, Str $replace): Str + public function replace(string $search, string $replace): self { - return Str::create( - parent::doReplace((string) $search, (string) $replace) + // Validates supplied parameters. + if (\strlen($search) === 0) { + throw NonEmptyStringException::withName('$search'); + } + if (\strlen($replace) === 0) { + throw NonEmptyStringException::withName('$replace'); + } + + return new self( + \str_replace($search, $replace, $this->value) ); } @@ -447,9 +602,18 @@ public function replace(Str $search, Str $replace): Str */ public function explode(string $separator, ?int $limit = null): array { - $segments = parent::doExplode($separator, $limit); - $exploded = []; + // Validates supplied parameters. + if (\strlen($separator) === 0) { + throw NonEmptyStringException::withName('$separator'); + } + if ($limit === null) { + $segments = \explode($separator, $this->value); + } else { + $segments = \explode($separator, $this->value, $limit); + } + + $exploded = []; foreach ($segments as $segment) { $exploded[] = Str::create($segment); } diff --git a/tests/Unit/Scalar/StrTest.php b/tests/Unit/Scalar/StrTest.php index 6c2620f..3396faf 100644 --- a/tests/Unit/Scalar/StrTest.php +++ b/tests/Unit/Scalar/StrTest.php @@ -17,16 +17,16 @@ * @copyright Hradigital\Datatypes * @license MIT */ -class StrTest extends AbstractBaseStringTestBase +class StrTest extends AbstractBaseTestCase { /** @inheritDoc */ - protected function getInstance(string $initialValue): AbstractBaseString + protected function getInstance(string $initialValue): Str { return Str::create($initialValue); } /** @inheritDoc */ - protected function checkDifferentInstances(AbstractBaseString $original, AbstractBaseString $other): void + protected function checkDifferentInstances(Str $original, Str $other): void { $this->assertFalse( ($original === $other), @@ -35,7 +35,7 @@ protected function checkDifferentInstances(AbstractBaseString $original, Abstrac } /** @inheritDoc */ - protected function checkCorrectInstanceType(AbstractBaseString $instance): void + protected function checkCorrectInstanceType(Str $instance): void { $this->assertInstanceOf( Str::class, @@ -44,6 +44,657 @@ protected function checkCorrectInstanceType(AbstractBaseString $instance): void ); } + /** + * Checks that Instance loads and holds value correctly. + * + * @return void + */ + public function checkLoadsDataCorrectly(): void + { + // Performs test. + $string = " Immutable string. "; + $instance = $this->getInstance($string); + + // Performs assertions. + $this->assertEquals( + $string, + (string) $instance, + 'Instance value does not seam to match.' + ); + $this->checkCorrectInstanceType($instance); + } + + /** + * Checks that String's length retrieval works. + * + * @return void + */ + public function testCanRetrieveLengthCorrectly(): void + { + // Performs test. + $string = " Immutable string. "; + $instance = $this->getInstance($string); + + // Performs assertions. + $this->assertEquals( + \strlen($string), + $instance->getLength(), + 'Instance character length does not seam to match.' + ); + } + + /** + * Checks that String's word count retrieval works. + * + * @return void + */ + public function testCanRetrieveWordCountCorrectly(): void + { + // Performs test. + $string = "This is my immutable string."; + $instance = $this->getInstance($string); + + // Performs assertions. + $this->assertEquals( + 5, + $instance->getWordCount(), + 'Instance word count does not seam to match.' + ); + } + + /** + * Tests that a string can be trimmed. + * + * @return void + */ + public function testCanTrimString(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $original->trim(); + + // Performs assertions. + $this->assertEquals( + 'Immutable string.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be trimmed only on the left. + * + * @return void + */ + public function testCanLeftTrimString(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $original->trimLeft(); + + // Performs assertions. + $this->assertEquals( + 'Immutable string. ', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be trimmed only on the right. + * + * @return void + */ + public function testCanRightTrimString(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $original->trimRight(); + + // Performs assertions. + $this->assertEquals( + ' Immutable string.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be converted to UPPER case. + * + * @return void + */ + public function testCanUpperCaseString(): void + { + // Performs test. + $original = $this->getInstance("Immutable string."); + $other = $original->toUpper(); + + // Performs assertions. + $this->assertEquals( + 'IMMUTABLE STRING.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be converted to UPPER case. + * + * @return void + */ + public function testCanUpperCaseFirst(): void + { + // Performs test. + $original = $this->getInstance("immutable string."); + $other = $original->toUpperFirst(); + + // Performs assertions. + $this->assertEquals( + 'Immutable string.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be convert to UPPER case, all words. + * + * @return void + */ + public function testCanUpperCaseWords(): void + { + // Performs test. + $original = $this->getInstance("immutable string."); + $other = $original->toUpperWords(); + + // Performs assertions. + $this->assertEquals( + 'Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be converted to LOWER case. + * + * @return void + */ + public function testCanLowerCaseString(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->toLower(); + + // Performs assertions. + $this->assertEquals( + 'immutable string.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be converted to LOWER case. + * + * @return void + */ + public function testCanLowerCaseFirst(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->toLowerFirst(); + + // Performs assertions. + $this->assertEquals( + 'immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeft(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeft(\strlen($string) + 2); + + // Performs assertions. + $this->assertEquals( + ' Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string is not padded on the left, when the padding length is less than the string's length. + * + * @return void + */ + public function testCanPadOnTheLeftWithoutResult(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeft(2); + + // Performs assertions. + $this->assertEquals( + $string, + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the left. + * + * @return void + */ + public function testCanPadOnTheLeftExtra(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padLeftExtra(2); + + // Performs assertions. + $this->assertEquals( + ' Immutable String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testBreaksPaddingOnTheLeftWithInvalidLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padLeft(0); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRight(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRight(\strlen($string) + 2); + + // Performs assertions. + $this->assertEquals( + 'Immutable String. ', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a string can be padded on the right. + * + * @return void + */ + public function testCanPadOnTheRightExtra(): void + { + // Performs test. + $string = "Immutable String."; + $original = $this->getInstance($string); + $other = $original->padRightExtra(2); + + // Performs assertions. + $this->assertEquals( + 'Immutable String. ', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that padding breaks. + * + * @return void + */ + public function testCanPadOnTheRightBreaksWithInvalidLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->padRight(0); + } + + /** + * Tests that a simple substring can be retrieved. + * + * @return void + */ + public function testSubStringCanBeRetrieved(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subString(10); + + // Performs assertions. + $this->assertEquals( + 'String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a simple substring can be retrieved. + * + * @return void + */ + public function testSubStringCanBeRetrievedWithNegativeStart(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subString(-7); + + // Performs assertions. + $this->assertEquals( + 'String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a simple substring can be retrieved. + * + * @return void + */ + public function testSubStringCanBeRetrievedWithLength(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subString(2, 7); + + // Performs assertions. + $this->assertEquals( + 'mutable', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that a simple substring can be retrieved. + * + * @return void + */ + public function testSubStringCanBeRetrievedWithNegativeLength(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subString(2, -8); + + // Performs assertions. + $this->assertEquals( + 'mutable', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that substring breaks. + * + * @return void + */ + public function testBreaksSubStringWithShortStart(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subString(-30); + } + + /** + * Tests that substring breaks. + * + * @return void + */ + public function testBreaksSubStringWithLongStart(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subString(30); + } + + /** + * Tests that substring breaks. + * + * @return void + */ + public function testBreaksSubStringWithShortLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subString(0, -30); + } + + /** + * Tests that substring breaks. + * + * @return void + */ + public function testBreaksSubStringWithLongLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subString(0, 30); + } + + /** + * Tests that a simple subLeft can be retrieved. + * + * @return void + */ + public function testSubStringLeftCanBeRetrieved(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subLeft(10); + + // Performs assertions. + $this->assertEquals( + 'Immutable ', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that subLeft() breaks. + * + * @return void + */ + public function testBreaksSubStringLeftWithShortLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subLeft(-1); + } + + /** + * Tests that subLeft() breaks. + * + * @return void + */ + public function testBreaksSubStringLeftWithLongLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subLeft(30); + } + + /** + * Tests that a simple subRight() can be retrieved. + * + * @return void + */ + public function testSubStringRightCanBeRetrieved(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->subRight(10); + + // Performs assertions. + $this->assertEquals( + 'le String.', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Tests that subRight() breaks. + * + * @return void + */ + public function testBreaksSubStringRightWithShortLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subRight(-1); + } + + /** + * Tests that subRight() breaks. + * + * @return void + */ + public function testBreaksSubStringRightWithLongLength(): void + { + // Creates expectation. + $this->expectException(ParameterOutOfRangeException::class); + + // Performs test. + $original = $this->getInstance("Immutable String."); + $original->subRight(30); + } + + /** + * Tests that a string can be reversed. + * + * @return void + */ + public function testStringCanBeReversed(): void + { + // Performs test. + $original = $this->getInstance("Immutable String."); + $other = $original->reverse(); + + // Performs assertions. + $this->assertEquals( + '.gnirtS elbatummI', + (string) $other, + 'Instance values do not match.' + ); + $this->checkCorrectInstanceType($other); + $this->checkDifferentInstances($original, $other); + } + + /** + * Checks Matching between two distinct strings. + * + * @return void + */ + public function testCanCheckMatching(): void + { + // Performs test. + $original = $this->getInstance(" Immutable string. "); + $other = $this->getInstance(" Immutable string. "); + + // Performs assertions. + $this->assertTrue( + $original->match($other), + 'Instance values do not match.' + ); + } + /** * Checks Equality of two distinct strings. * @@ -53,11 +704,10 @@ public function testCanCheckEquality(): void { // Performs test. $original = $this->getInstance(" Immutable string. "); - $other = $this->getInstance(" Immutable string. "); // Performs assertions. $this->assertTrue( - $original->equals($other), + $original->equals(" Immutable string. "), 'Instance values do not match.' ); } @@ -74,9 +724,7 @@ public function testCanCheckIfStringContainsPortion(): void // Performs assertions. $this->assertTrue( - $original->contains( - $this->getInstance('muta') - ), + $original->contains('muta'), 'Instance values do not match.' ); $this->checkCorrectInstanceType($original); @@ -96,9 +744,7 @@ public function testBreaksCheckingIfStringContainsPortionWithEmptyText(): void $this->expectException(NonEmptyStringException::class); // Performs test. - $original->contains( - $this->getInstance('') - ); + $original->contains(''); } /** @@ -110,9 +756,7 @@ public function testCanRetrieveIndexOf(): void { // Performs test. $instance = $this->getInstance("Immutable string."); - $indexOf = $instance->indexOf( - $this->getInstance('string') - ); + $indexOf = $instance->indexOf('string'); // Performs assertions. $this->assertEquals( @@ -131,10 +775,7 @@ public function testCanRetrieveIndexOfWithStart(): void { // Performs test. $instance = $this->getInstance("Immutable string, or part of another string."); - $indexOf = $instance->indexOf( - $this->getInstance('string'), - 15 - ); + $indexOf = $instance->indexOf('string', 15); // Performs assertions. $this->assertEquals( @@ -153,9 +794,7 @@ public function testIndexOfReturnsNullIfNotFound(): void { // Performs test. $instance = $this->getInstance("Immutable string."); - $indexOf = $instance->indexOf( - $this->getInstance('another') - ); + $indexOf = $instance->indexOf('another'); // Performs assertions. $this->assertNull( @@ -176,7 +815,7 @@ public function testBreaksIndexOfIfEmptySearch(): void // Performs test. $instance = $this->getInstance("Immutable string."); - $instance->indexOf($this->getInstance('')); + $instance->indexOf(''); } /** @@ -188,8 +827,8 @@ public function testCanCheckIfStringStartsWithText(): void { // Performs test. $instance = $this->getInstance("Immutable string."); - $true = $instance->startsWith($this->getInstance("Immu")); - $false = $instance->startsWith($this->getInstance("string")); + $true = $instance->startsWith("Immu"); + $false = $instance->startsWith("string"); // Performs assertions. $this->assertTrue($true, 'String should have started with searched text.'); @@ -208,7 +847,7 @@ public function testBreaksCheckingIfStringStartsWithText(): void // Performs test. $instance = $this->getInstance("Immutable string."); - $instance->startsWith($this->getInstance('')); + $instance->startsWith(''); } /** @@ -220,8 +859,8 @@ public function testCanCheckIfStringEndsWithText(): void { // Performs test. $instance = $this->getInstance("Immutable string."); - $true = $instance->endsWith($this->getInstance("string.")); - $false = $instance->endsWith($this->getInstance("Immu")); + $true = $instance->endsWith("string."); + $false = $instance->endsWith("Immu"); // Performs assertions. $this->assertTrue($true, 'String should have ended with searched text.'); @@ -240,7 +879,7 @@ public function testBreaksCheckingIfStringEndsWithText(): void // Performs test. $instance = $this->getInstance("Immutable string."); - $instance->endsWith($this->getInstance('')); + $instance->endsWith(''); } /** @@ -252,7 +891,7 @@ public function testCanCountNumberOccurencesInString(): void { // Performs test. $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count($this->getInstance('string')); + $count = $instance->count('string'); // Performs assertions. $this->assertEquals( @@ -271,7 +910,7 @@ public function testCanCountNumberOccurencesInStringWithStartAndLength(): void { // Performs test. $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count($this->getInstance('string'), 15, 29); + $count = $instance->count('string', 15, 29); // Performs assertions. $this->assertEquals( @@ -290,7 +929,7 @@ public function testCanCountNumberOccurencesInStringIfNoneIsFound(): void { // Performs test. $instance = $this->getInstance("Immutable string, or part of another string."); - $count = $instance->count($this->getInstance('string'), 38, 4); + $count = $instance->count('string', 38, 4); // Performs assertions. $this->assertEquals( @@ -312,7 +951,7 @@ public function testBreaksCountNumberOccurencesInStringIfSerachIsEmpty(): void // Performs test. $instance = $this->getInstance("Immutable string, or part of another string."); - $instance->count($this->getInstance('')); + $instance->count(''); } /** @@ -327,7 +966,7 @@ public function testBreaksPaddingOnTheLeftWithInvalidPadString(): void // Performs test. $original = $this->getInstance("Immutable String."); - $original->padLeft(2, $this->getInstance('')); + $original->padLeft(2, ''); } /** @@ -342,7 +981,7 @@ public function testBreaksCanPaddingOnTheLeftExtraWithInvalidPadString(): void // Performs test. $original = $this->getInstance("Immutable String."); - $original->padLeftExtra(2, $this->getInstance('')); + $original->padLeftExtra(2, ''); } /** @@ -355,7 +994,7 @@ public function testCanPadOnTheLeftWidthCharacter(): void // Performs test. $string = "Immutable String."; $original = $this->getInstance($string); - $other = $original->padLeft(\strlen($string) + 2, $this->getInstance('_')); + $other = $original->padLeft(\strlen($string) + 2, '_'); // Performs assertions. $this->assertEquals( @@ -377,7 +1016,7 @@ public function testCanPadOnTheLeftExtraWidthCharacter(): void // Performs test. $string = "Immutable String."; $original = $this->getInstance($string); - $other = $original->padLeftExtra(2, $this->getInstance('_')); + $other = $original->padLeftExtra(2, '_'); // Performs assertions. $this->assertEquals( @@ -401,7 +1040,7 @@ public function testBreaksCanPadOnTheRightWithInvalidPadString(): void // Performs test. $original = $this->getInstance("Immutable String."); - $original->padRight(2, $this->getInstance('')); + $original->padRight(2, ''); } /** @@ -416,7 +1055,7 @@ public function testBreaksCanPadOnTheRightExtraWithInvalidPadString(): void // Performs test. $original = $this->getInstance("Immutable String."); - $original->padRightExtra(2, $this->getInstance('')); + $original->padRightExtra(2, ''); } /** @@ -429,7 +1068,7 @@ public function testCanPadOnTheRightWidthCharacter(): void // Performs test. $string = "Immutable String."; $original = $this->getInstance($string); - $other = $original->padRight(\strlen($string) + 2, $this->getInstance('_')); + $other = $original->padRight(\strlen($string) + 2, '_'); // Performs assertions. $this->assertEquals( @@ -451,7 +1090,7 @@ public function testCanPadOnTheRightExtraWidthCharacter(): void // Performs test. $string = "Immutable String."; $original = $this->getInstance($string); - $other = $original->padRightExtra(2, $this->getInstance('_')); + $other = $original->padRightExtra(2, '_'); // Performs assertions. $this->assertEquals( @@ -472,10 +1111,7 @@ public function testTextCanBeReplacedInString(): void { // Performs test. $original = $this->getInstance("Immutable String."); - $other = $original->replace( - $this->getInstance('String'), - $this->getInstance('Object') - ); + $other = $original->replace('String', 'Object'); // Performs assertions. $this->assertEquals( @@ -496,10 +1132,7 @@ public function testTextIsNotReplacedIfSearchNotFound(): void { // Performs test. $original = $this->getInstance("Immutable String."); - $other = $original->replace( - $this->getInstance('None'), - $this->getInstance('Object') - ); + $other = $original->replace('None', 'Object'); // Performs assertions. $this->assertEquals( @@ -523,7 +1156,7 @@ public function testBreaksTextReplaceIfSearchIsEmpty(): void // Performs test. $original = $this->getInstance("Immutable String."); - $original->replace($this->getInstance(''), $this->getInstance('Object')); + $original->replace('', 'Object'); } /** @@ -538,7 +1171,7 @@ public function testBreaksTextReplaceIfReplaceIsEmpty(): void // Performs test. $original = $this->getInstance("Immutable String."); - $original->replace($this->getInstance('Object'), $this->getInstance('')); + $original->replace('Object', ''); } /** From fc103f47393b5ae768d9edba03a3368ad39bc3ec Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 18:38:20 +0000 Subject: [PATCH 125/193] refactor: Remove obsolete AbstractBaseString class --- src/Scalar/AbstractBaseString.php | 564 --------------- src/Scalar/README.md | 128 ---- .../Scalar/AbstractBaseStringTestBase.php | 683 ------------------ tests/Unit/Scalar/README.md | 3 - 4 files changed, 1378 deletions(-) delete mode 100644 src/Scalar/AbstractBaseString.php delete mode 100644 src/Scalar/README.md delete mode 100644 tests/Unit/Scalar/AbstractBaseStringTestBase.php delete mode 100644 tests/Unit/Scalar/README.md diff --git a/src/Scalar/AbstractBaseString.php b/src/Scalar/AbstractBaseString.php deleted file mode 100644 index 8cdec69..0000000 --- a/src/Scalar/AbstractBaseString.php +++ /dev/null @@ -1,564 +0,0 @@ -value = $value; - } - - /** - * Magic method that will print out the native string representation of the instance. - * - * @return string - */ - public function __toString(): string - { - return $this->value; - } - - /** - * Returns the Instance's character length. - * - * @return int - */ - public function getLength(): int - { - return \strlen($this->value); - } - - /** - * Counts the number of words in the String. - * - * @return int - */ - public function getWordCount(): int - { - return \str_word_count($this->value); - } - - /** - * Compares the instance's value, with the supplied native string. - * - * Returns TRUE if the 2 values match. FALSE otherwise. - * - * @param string $string - Another string to compare with. - * @return bool - */ - protected function doEquals(string $string): bool - { - return ($this->value === $string); - } - - /** - * Checks if the instance's value contains the supplied $search string. - * - * Returns TRUE if found. FALSE otherwise. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws NonEmptyStringException - If supplied $search is empty. - * @return bool - */ - protected function doContains(string $search): bool - { - // Validates supplied parameter. - if (\strlen($search) === 0) { - throw NonEmptyStringException::withName('$search'); - } - - return ($this->doIndexOf($search) !== null); - } - - /** - * Searches and returns the character index in the instance, of the $search string. - * - * If a $start is specified, search will start this number of characters counted from - * the beginning of the string. If $start is negative, the search will start this number - * of characters counted from the end of the string. - * - * If the $search is not found in the instance's value, NULL is returned. - * - * @param string $search - String to search for in the instance. - * @param int $start - Search offset start. Defaults to ZERO. - * - * @throws NonEmptyStringException - If $search value is an empty string. - * @throws ParameterOutOfRangeException - If the $start is either too small, or too long. - * @return int|null - */ - protected function doIndexOf(string $search, int $start = 0): ?int - { - // Validates supplied parameters. - if (\strlen($search) === 0) { - throw NonEmptyStringException::withName('$search'); - } - if ($start) { - $this->validateStartAndLength($start, null); - } - - // Collects the string position. - $index = \strpos($this->value, $search, $start); - - // If false is returned, no index was found, and therefore NULL is returned. - if ($index === false) { - return null; - } - - return $index; - } - - /** - * Checks if the instance's value starts with the supplied string. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws NonEmptyStringException - If supplied $search is empty. - * @return bool - */ - protected function doStartsWith(string $search): bool - { - // Validates supplied parameter. - if (\strlen($search) === 0) { - throw NonEmptyStringException::withName('$search'); - } - - return ($this->doIndexOf($search) === 0); - } - - /** - * Checks if the instance's value ends with the supplied string. - * - * @param string $search - Non empty string to search for in the instance. - * - * @throws NonEmptyStringException - If supplied $search is empty. - * @return bool - */ - protected function doEndsWith(string $search): bool - { - // Validates supplied parameter. - if (\strlen($search) === 0) { - throw NonEmptyStringException::withName('$search'); - } - - return ($this->doSubString((0 - \strlen($search))) === $search); - } - - /** - * Counts the number of substring occurrences in the instance's value. - * - * @param string $search - Non empty string to search for in the instance. - * @param int $start - The sub-string's offset/start. - * @param int|NULL $length - Length value. Can be NULL, in which case, it won't be validated. - * - * @throws NonEmptyStringException - If supplied $search is empty. - * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return int - */ - protected function doCount(string $search, int $start = 0, ?int $length = null): int - { - // Validates supplied $search parameter. - if (\strlen($search) === 0) { - throw NonEmptyStringException::withName('$search'); - } - - // Validates supplied $start and $length. - $this->validateStartAndLength($start, $length); - - // Checks if $length was defined. - if ($length) { - return \substr_count($this->value, $search, $start, $length); - } - - return \substr_count($this->value, $search, $start); - } - - /** - * Validates a character $length, based on the instance value's length, and supplied $start. - * - * @param int $start - The sub-string's offset/start. - * @param int|null $length - Length value. Can be NULL, in which case, it won't be validated. - * - * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return void - */ - private function validateStartAndLength(int $start, ?int $length): void - { - // Calculates the absolute values for validations. - $absStart = (int) \abs($start); - $absLength = $length ? (int) \abs($length) : null; - - // Validates the starting value. - if ($absStart > $this->getLength()) { - throw ParameterOutOfRangeException::withName('$start'); - } - - // If supplied $length is NULL, no further validations are required. - if ($length === null) { - return; - } - - // Checks if the supplied $length, doesn't exceed the available number of characters. - $startTooBig = ($start >= 0 && ($this->getLength() - $start < $absLength)); - $startTooSmall = ($start < 0 && $absLength > $absStart); - - if ($startTooBig || $startTooSmall) { - throw ParameterOutOfRangeException::withName('$length'); - } - } - - /** - * Trims instance's value on both ends. - * - * @return string - */ - protected function doTrim(): string - { - return \trim($this->value); - } - - /** - * Trims instance's value only on the left. - * - * @return string - */ - protected function doTrimLeft(): string - { - return \ltrim($this->value); - } - - /** - * Trims instance's value only on the right. - * - * @return string - */ - protected function doTrimRight(): string - { - return \rtrim($this->value); - } - - /** - * Converts the instance's value to Uppercase. - * - * @return string - */ - protected function doToUpper(): string - { - return \mb_strtoupper($this->value); - } - - /** - * Converts the instance's value first character to Uppercase. - * - * @return string - */ - protected function doToUpperFirst(): string - { - return \ucfirst($this->value); - } - - /** - * Converts the instance's value first character of each word to Upper Case. - * - * @param string $delimiters - The optional delimiters contains the word separator characters. - * @return string - */ - protected function doToUpperWords(string $delimiters = " \t\r\n\f\v"): string - { - return \ucwords($this->value, $delimiters); - } - - /** - * Converts the instance's value to Lowercase. - * - * @return string - */ - protected function doToLower(): string - { - return \mb_strtolower($this->value); - } - - /** - * Converts the instance's value first character to Lowercase. - * - * @return string - */ - protected function doToLowerFirst(): string - { - return \lcfirst($this->value); - } - - /** - * This method returns a new instance padded on the LEFT to the specified padding length minus - * the length of the instance's value. - * - * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will - * only be padded by the value of 2. - * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padString up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padString's length. - * - * @throws NonEmptyStringException - If supplied $padding is empty. - * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return string - */ - protected function doPadLeft(int $length, string $padding = " "): string - { - // Validates supplied parameters. - if ($length < 1) { - throw ParameterOutOfRangeException::withName('$length'); - } - if (\strlen($padding) === 0) { - throw NonEmptyStringException::withName('$padding'); - } - - return \str_pad($this->value, $length, $padding, STR_PAD_LEFT); - } - - /** - * This method returns a new instance padded on the LEFT, exactly to the specified padding length. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws NonEmptyStringException - If supplied $padding is empty. - * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return string - */ - protected function doPadLeftExtra(int $length, string $padding = " "): string - { - return $this->doPadLeft(($this->getLength() + $length), $padding); - } - - /** - * This method returns a new instance padded on the RIGHT to the specified padding length minus - * the length of the instance's value. - * - * Eg:. if the padding length is 12, and the instance's value is only 10 characters long, the value will - * only be padded by the value of 2. - * - * If the optional argument $padString is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws NonEmptyStringException - If supplied $padding is empty. - * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return string - */ - protected function doPadRight(int $length, string $padding = " "): string - { - // Validates supplied parameters. - if ($length < 1) { - throw ParameterOutOfRangeException::withName('$length'); - } - if (\strlen($padding) === 0) { - throw NonEmptyStringException::withName('$padding'); - } - - return \str_pad($this->value, $length, $padding, STR_PAD_RIGHT); - } - - /** - * This method returns a new instance padded on the RIGHT, exactly to the specified padding length. - * - * If the optional argument $padding is not supplied, the input is padded with spaces, otherwise - * it is padded with characters from $padding up to the limit. - * - * @param int $length - Length of the padded value. - * @param string $padding - The pad_string may be truncated if the required number of padding characters - * can't be evenly divided by the $padding's length. - * - * @throws NonEmptyStringException - If supplied $padding is empty. - * @throws ParameterOutOfRangeException - If the $length is either too small, or too long. - * @return string - */ - protected function doPadRightExtra(int $length, string $padding = " "): string - { - return $this->doPadRight(($this->getLength() + $length), $padding); - } - - /** - * This method returns a new instance with a portion of the original instance's value, specified by the - * $start and $length parameters. - * - * $start parameter: - * - If $start is non-negative, the returned an instance will start at the $start'th position in - * string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the - * character at position 2 is 'c', and so forth. - * - If $start is negative, the returned string will start at the $start'th character from the end - * of string. - * - If the absolute value of $start is higher than the instance's length, an - * exception is thrown. - * - * - * $length parameter: - * - If $length is given and is positive, the string returned will contain at most length characters - * beginning from $start (depending on the length of string). - * - If $length is given and is negative, then that many characters will be omitted from the end of string - * (after the start position has been calculated when a start is negative). - * - If $length exceeds the remaining number of characters, after the $start calculation, an - * Exception will be raised. - * - * @param int $start - Start of the sub-string. Can be negative. - * @param int $length - Length of the sub-string. Can be negative. - * - * @throws ParameterOutOfRangeException - If the $start and/or $length is either too small, or too long. - * @return string - */ - protected function doSubString(int $start, int $length = null): string - { - // Validates supplied $start and $length. - $this->validateStartAndLength($start, $length); - - // Processes the substring. - if ($length !== null) { - $value = \substr($this->value, $start, $length); - } else { - $value = \substr($this->value, $start); - } - - return ($value ?? ''); - } - - /** - * This method returns a new instance with a portion of the original instance's value, starting at the beginning - * of the value, with the number of characters specified in the $length parameter. - * - * @param int $length - Length of the sub-string. Must be positive. - * - * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. - * @return string - */ - protected function doSubLeft(int $length): string - { - // Validates parameter. - if ($length < 1) { - throw ParameterOutOfRangeException::withName('$length'); - } - - return $this->doSubString(0, $length); - } - - /** - * This method returns a new instance with a portion of the original instance's value, couting from the end - * of the value, with the number of characters specified in the $length parameter. - * - * @param int $length - Length of the sub-string. Must be positive. - * - * @throws ParameterOutOfRangeException - If supplied Length is not a positive integer. - * @return string - */ - protected function doSubRight(int $length): string - { - // Validates parameter. - if ($length < 1) { - throw ParameterOutOfRangeException::withName('$length'); - } - - return $this->doSubString(0 - $length); - } - - /** - * This method returns the reversed value of the instance. - * - * @return string - */ - protected function doReverse(): string - { - return \strrev($this->value); - } - - /** - * This method replaces a string's occurance by another, and returns a new instance with the new value. - * - * @param string $search - The string to search for. - * @param string $replace - The search's replacement. - * - * @throws NonEmptyStringException - If either $search or $replace are empty. - * @return string - */ - protected function doReplace(string $search, string $replace): string - { - // Validates supplied parameters. - if (\strlen($search) === 0) { - throw NonEmptyStringException::withName('$search'); - } - if (\strlen($replace) === 0) { - throw NonEmptyStringException::withName('$replace'); - } - - return \str_replace($search, $replace, $this->value); - } - - /** - * Returns an array of strings, each of which is a substring of string formed - * by splitting it on boundaries formed by the string separator. - * - * If limit is set and positive, the returned array will contain a maximum of limit - * elements with the last element containing the rest of string. - * - * If the limit parameter is negative, all components except the last -limit are returned. - * - * If the limit parameter is zero, then this is treated as 1. - * - * @param string $separator - The boundary string. - * @param int|null $limit - The limit of returned segments. - * - * @throws NonEmptyStringException - If $separator is an empty string. - * @return array|Str[] - */ - protected function doExplode(string $separator, ?int $limit): array - { - // Validates supplied parameters. - if (\strlen($separator) === 0) { - throw NonEmptyStringException::withName('$separator'); - } - - if ($limit === null) { - return \explode($separator, $this->value); - } - - return \explode($separator, $this->value, $limit); - } -} diff --git a/src/Scalar/README.md b/src/Scalar/README.md deleted file mode 100644 index a5e9550..0000000 --- a/src/Scalar/README.md +++ /dev/null @@ -1,128 +0,0 @@ -# PHP Scalar Datatypes - -Currently, this package supports only **Scalar Strings**. You can choose between `Str` and `NString` string objects. - -**Scalar Strings** are wrapper objects around primitive `strings`, which encapsulate all string related funcionality into -a single instance. - -## Str vs. NString - -`Str` and `NString` string datatypes will have the exact same functionality, but will have different instance management. -Both types inherit commonly used `protected` functionality from parent `AbstractBaseString` class. Parent methods will map to -native procedural string manipulation functions. - -Both types of classes implement `__toString()` method, which means you can directly print their result: - -```php -// Example of a Str. -$Str = Str::create(" This Is A String "); - -echo $Str; // Prints ' This Is A String ' -``` - -Use **accessor** methods to retrieve any information from within the instance. **Mutators** methods will manipulate the -value of the instance. Both classes are immutable Value Objects, which means that, they will always return a new -instance of themselves when changing internal value, which should remain immutable in original instance. - -Both `Str` and `NString` instances have _fluent interfaces_, and therefore you can chain mutator methods, and make -several changes in the same line of code. The main difference between the two types, is that `Str` instances will -force all mutator's interfaces/methods to always use other `Str` as parameters, and never primitive `strings`. - -Here are two examples: - -```php -// Example of a Str string. -$string1 = Str::create(" This Is A String "); - -// Overrite initial variable with returned instance. -// Notice that we use other Str as parameters. -$search = Str::create("This"); -$replace = Str::create("That"); -$string1 = $string1->replace($search, $replace); - -// Perform operations on instance, and assign result to different variables. -$string2 = $string1->trim(); -$string3 = $string2->toLower(); - -if ($string1 === $string2 || $string1 === $string3 || $string2 === $string3) { - echo "This will never print, as all are different instances."; -} - -if ($string1->equals($string2)) { - echo "This will print, as both instances contain the same value."; -} - -echo "{$string1} still has the value ' That Is A String '."; -echo "{$string2} has the value 'That Is A String'."; -echo "{$string3} has the value 'that is a string'."; -``` - -```php -// Example of a NString string. -$string1 = NString::create(" This Is A String "); - -// Overrite initial variable with returned instance. -// Notice that we use primitive strings as parameters. -$search = "This"; -$replace = "That"; -$string1 = $string1->replace($search, $replace); - -// Perform operations on instance, and assign result to different variables. -$string2 = $string1->trim(); -$string3 = $string2->toLower(); - -if ($string1 === $string2 && $string1 === $string3 && $string2 === $string3) { - echo "This will never print, as all are different instances."; -} - -echo "{$string1} still has the value ' That Is A String '."; -echo "{$string2} has the value 'That Is A String'."; -echo "{$string3} has the value 'that is a string'."; -``` - -### Fluent Interfaces - -You can also do the previous processing, by channing the methods, independently of what type of datatype it is. - -```php -// Example of the instance's fluent interface usage. -$string = NString::create(" This Is A String ") - ->replace("This", "That") - ->replace("String", "Great Feature") - ->trim() - ->toLower(); - -echo "{$string} has the value 'that is a great feature'"; -``` - -### Class usage - -You can easily import, use and manipulate primitive native data in the following way: - -```php -use HraDigital\Datatypes\Scalar\Str; - -// ... - -$string = Str::create(' This is the string I am trying to manipulate. '); -``` - -### Class conversion - -You can also convert from one type of string to the other. - -```php -// Originally creates an Instance of NString. -$string = NString::create('This is originally a NString.') - ->replace(' is ', ' was ') - ->toStr(); - -echo get_class($string); // Should echo \HraDigital\Datatypes\Scalar\Str -echo $string; // This was originally a NString. - -// Converts to original type. -$string = $string->replace(Str::create(' was '), Str::create(' is '))->toNString(); - -echo get_class($string); // Should echo \HraDigital\Datatypes\Scalar\NString -echo $string; // This is originally a NString. -``` diff --git a/tests/Unit/Scalar/AbstractBaseStringTestBase.php b/tests/Unit/Scalar/AbstractBaseStringTestBase.php deleted file mode 100644 index 649c4bb..0000000 --- a/tests/Unit/Scalar/AbstractBaseStringTestBase.php +++ /dev/null @@ -1,683 +0,0 @@ -getInstance($string); - - // Performs assertions. - $this->assertEquals( - $string, - (string) $instance, - 'Instance value does not seam to match.' - ); - $this->checkCorrectInstanceType($instance); - } - - /** - * Checks that String's length retrieval works. - * - * @return void - */ - public function testCanRetrieveLengthCorrectly(): void - { - // Performs test. - $string = " Immutable string. "; - $instance = $this->getInstance($string); - - // Performs assertions. - $this->assertEquals( - \strlen($string), - $instance->getLength(), - 'Instance character length does not seam to match.' - ); - } - - /** - * Checks that String's word count retrieval works. - * - * @return void - */ - public function testCanRetrieveWordCountCorrectly(): void - { - // Performs test. - $string = "This is my immutable string."; - $instance = $this->getInstance($string); - - // Performs assertions. - $this->assertEquals( - 5, - $instance->getWordCount(), - 'Instance word count does not seam to match.' - ); - } - - /** - * Tests that a string can be trimmed. - * - * @return void - */ - public function testCanTrimString(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = $original->trim(); - - // Performs assertions. - $this->assertEquals( - 'Immutable string.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be trimmed only on the left. - * - * @return void - */ - public function testCanLeftTrimString(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = $original->trimLeft(); - - // Performs assertions. - $this->assertEquals( - 'Immutable string. ', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be trimmed only on the right. - * - * @return void - */ - public function testCanRightTrimString(): void - { - // Performs test. - $original = $this->getInstance(" Immutable string. "); - $other = $original->trimRight(); - - // Performs assertions. - $this->assertEquals( - ' Immutable string.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be converted to UPPER case. - * - * @return void - */ - public function testCanUpperCaseString(): void - { - // Performs test. - $original = $this->getInstance("Immutable string."); - $other = $original->toUpper(); - - // Performs assertions. - $this->assertEquals( - 'IMMUTABLE STRING.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be converted to UPPER case. - * - * @return void - */ - public function testCanUpperCaseFirst(): void - { - // Performs test. - $original = $this->getInstance("immutable string."); - $other = $original->toUpperFirst(); - - // Performs assertions. - $this->assertEquals( - 'Immutable string.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be convert to UPPER case, all words. - * - * @return void - */ - public function testCanUpperCaseWords(): void - { - // Performs test. - $original = $this->getInstance("immutable string."); - $other = $original->toUpperWords(); - - // Performs assertions. - $this->assertEquals( - 'Immutable String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be converted to LOWER case. - * - * @return void - */ - public function testCanLowerCaseString(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->toLower(); - - // Performs assertions. - $this->assertEquals( - 'immutable string.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be converted to LOWER case. - * - * @return void - */ - public function testCanLowerCaseFirst(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->toLowerFirst(); - - // Performs assertions. - $this->assertEquals( - 'immutable String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeft(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeft(\strlen($string) + 2); - - // Performs assertions. - $this->assertEquals( - ' Immutable String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string is not padded on the left, when the padding length is less than the string's length. - * - * @return void - */ - public function testCanPadOnTheLeftWithoutResult(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeft(2); - - // Performs assertions. - $this->assertEquals( - $string, - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be padded on the left. - * - * @return void - */ - public function testCanPadOnTheLeftExtra(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padLeftExtra(2); - - // Performs assertions. - $this->assertEquals( - ' Immutable String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testBreaksPaddingOnTheLeftWithInvalidLength(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padLeft(0); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRight(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRight(\strlen($string) + 2); - - // Performs assertions. - $this->assertEquals( - 'Immutable String. ', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a string can be padded on the right. - * - * @return void - */ - public function testCanPadOnTheRightExtra(): void - { - // Performs test. - $string = "Immutable String."; - $original = $this->getInstance($string); - $other = $original->padRightExtra(2); - - // Performs assertions. - $this->assertEquals( - 'Immutable String. ', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that padding breaks. - * - * @return void - */ - public function testCanPadOnTheRightBreaksWithInvalidLength(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->padRight(0); - } - - /** - * Tests that a simple substring can be retrieved. - * - * @return void - */ - public function testSubStringCanBeRetrieved(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subString(10); - - // Performs assertions. - $this->assertEquals( - 'String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a simple substring can be retrieved. - * - * @return void - */ - public function testSubStringCanBeRetrievedWithNegativeStart(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subString(-7); - - // Performs assertions. - $this->assertEquals( - 'String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a simple substring can be retrieved. - * - * @return void - */ - public function testSubStringCanBeRetrievedWithLength(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subString(2, 7); - - // Performs assertions. - $this->assertEquals( - 'mutable', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that a simple substring can be retrieved. - * - * @return void - */ - public function testSubStringCanBeRetrievedWithNegativeLength(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subString(2, -8); - - // Performs assertions. - $this->assertEquals( - 'mutable', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that substring breaks. - * - * @return void - */ - public function testBreaksSubStringWithShortStart(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subString(-30); - } - - /** - * Tests that substring breaks. - * - * @return void - */ - public function testBreaksSubStringWithLongStart(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subString(30); - } - - /** - * Tests that substring breaks. - * - * @return void - */ - public function testBreaksSubStringWithShortLength(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subString(0, -30); - } - - /** - * Tests that substring breaks. - * - * @return void - */ - public function testBreaksSubStringWithLongLength(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subString(0, 30); - } - - /** - * Tests that a simple subLeft can be retrieved. - * - * @return void - */ - public function testSubStringLeftCanBeRetrieved(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subLeft(10); - - // Performs assertions. - $this->assertEquals( - 'Immutable ', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that subLeft() breaks. - * - * @return void - */ - public function testBreaksSubStringLeftWithShortLength(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subLeft(-1); - } - - /** - * Tests that subLeft() breaks. - * - * @return void - */ - public function testBreaksSubStringLeftWithLongLength(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subLeft(30); - } - - /** - * Tests that a simple subRight() can be retrieved. - * - * @return void - */ - public function testSubStringRightCanBeRetrieved(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->subRight(10); - - // Performs assertions. - $this->assertEquals( - 'le String.', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } - - /** - * Tests that subRight() breaks. - * - * @return void - */ - public function testBreaksSubStringRightWithShortLength(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subRight(-1); - } - - /** - * Tests that subRight() breaks. - * - * @return void - */ - public function testBreaksSubStringRightWithLongLength(): void - { - // Creates expectation. - $this->expectException(ParameterOutOfRangeException::class); - - // Performs test. - $original = $this->getInstance("Immutable String."); - $original->subRight(30); - } - - /** - * Tests that a string can be reversed. - * - * @return void - */ - public function testStringCanBeReversed(): void - { - // Performs test. - $original = $this->getInstance("Immutable String."); - $other = $original->reverse(); - - // Performs assertions. - $this->assertEquals( - '.gnirtS elbatummI', - (string) $other, - 'Instance values do not match.' - ); - $this->checkCorrectInstanceType($other); - $this->checkDifferentInstances($original, $other); - } -} diff --git a/tests/Unit/Scalar/README.md b/tests/Unit/Scalar/README.md deleted file mode 100644 index 192ec14..0000000 --- a/tests/Unit/Scalar/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Scalar related Unit tests - -String related Unit tests should extend `AbstractBaseStringTestBase` for shared functionality. From 760ab42a78d5d125dc729aa1c5276c691d24dce6 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 19:25:41 +0000 Subject: [PATCH 126/193] fix: Rename casting method --- src/Traits/Entities/General/HasFeatureTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/Entities/General/HasFeatureTrait.php b/src/Traits/Entities/General/HasFeatureTrait.php index 3112c6b..e231c77 100755 --- a/src/Traits/Entities/General/HasFeatureTrait.php +++ b/src/Traits/Entities/General/HasFeatureTrait.php @@ -22,7 +22,7 @@ trait HasFeatureTrait * @param bool $featured - New featured value. * @return void */ - protected function castFeatured(bool $featured): void + protected function castIsFeatured(bool $featured): void { $this->is_featured = $featured; } From 468ff259c60c382f657938cf472c7b4c4784e86b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 19:34:17 +0000 Subject: [PATCH 127/193] fix: Fix onUpdate Handler call --- src/Traits/Entities/CanProcessOnUpdateEventsTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php b/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php index 689e754..db99dcf 100644 --- a/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php +++ b/src/Traits/Entities/CanProcessOnUpdateEventsTrait.php @@ -48,7 +48,7 @@ protected function onLoadRegisterOnUpdateEvents(): void protected function triggerOnUpdate(): void { foreach ($this->onUpdateEvents as $onUpdate) { - $onUpdate(); + $this->$onUpdate(); } } } From 9642f8fa33053d05b04bbd2fd6136a1a5e8af3da Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 19:34:52 +0000 Subject: [PATCH 128/193] refactor: Remove deprecated Seo Title retrieval --- src/Traits/Entities/General/HasSeoFieldsTrait.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Traits/Entities/General/HasSeoFieldsTrait.php b/src/Traits/Entities/General/HasSeoFieldsTrait.php index 427a58f..a307618 100755 --- a/src/Traits/Entities/General/HasSeoFieldsTrait.php +++ b/src/Traits/Entities/General/HasSeoFieldsTrait.php @@ -102,11 +102,6 @@ protected function castSeoKeywords(string $keywords = null): void */ public function getSeoTitle(): ?Str { - // If the Seo title is not set it is set to name property. - if ($this->seo_title === null || $this->seo_title->trim()->getLength() === 0) { - return ( \property_exists($this, 'name') ? $this->{'name'} : null ); - } - return $this->seo_title; } From 4bb13c4c7c5ec19c73ba533e9f9dd4ef3081b6e6 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 19:36:20 +0000 Subject: [PATCH 129/193] tests: Add tests for General Entity Traits --- .../Unit/Traits/Entities/GeneralTraitsVO.php | 57 +++++ .../Traits/Entities/GeneralTraitsVOTest.php | 238 ++++++++++++++++++ 2 files changed, 295 insertions(+) create mode 100644 tests/Unit/Traits/Entities/GeneralTraitsVO.php create mode 100644 tests/Unit/Traits/Entities/GeneralTraitsVOTest.php diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVO.php b/tests/Unit/Traits/Entities/GeneralTraitsVO.php new file mode 100644 index 0000000..5079418 --- /dev/null +++ b/tests/Unit/Traits/Entities/GeneralTraitsVO.php @@ -0,0 +1,57 @@ +triggerOnUpdate(); + } +} diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php new file mode 100644 index 0000000..86f13e4 --- /dev/null +++ b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php @@ -0,0 +1,238 @@ + 54321, + 'active' => true, + 'is_featured' => true, + 'is_published' => true, + 'alias' => 'some_alias', + 'created_at' => '2022-01-20 12:30:00', + 'deleted_at' => null, + 'email' => 'user@domain.tld', + 'hits' => 1999, + 'name' => 'Name of Record', + 'ordering' => 2, + 'password' => 'usdhciucyneoyhnoerytos8ryt8svyeero8tyvwo8ryt8wryvutt89weysr8ncseryngngc8yeroiyncweryc8f', + 'seo_title' => 'My SEO Title', + 'seo_description' => 'This is a SEO description for the record', + 'seo_keywords' => 'word1, word2, word3', + 'title' => 'Title for the Record', + 'updated_at' => '2022-02-22 12:30:00', + 'deleted_at' => '2022-02-22 12:30:00', + 'uuid' => '123e4567-e89b-12d3-a456-426614174000', + ]; + + public function testLoadsSuccessfully(): void + { + $object = new GeneralTraitsVO(self::DATA); + + $this->assertFalse($object->isNew()); + $this->assertTrue($object->isActive()); + $this->assertTrue($object->isFeatured()); + $this->assertTrue($object->isPublished()); + $this->assertTrue($object->isDeleted()); + + $this->assertEquals(self::DATA['id'], (string) $object->getId()); + $this->assertEquals(self::DATA['uuid'], (string) $object->getUuid()); + $this->assertEquals(self::DATA['alias'], (string) $object->getAlias()); + $this->assertEquals(self::DATA['email'], (string) $object->getEmail()); + $this->assertEquals(self::DATA['name'], (string) $object->getName()); + $this->assertEquals(self::DATA['title'], (string) $object->getTitle()); + $this->assertEquals(self::DATA['password'], (string) $object->getPassword()); + + $this->assertEquals(self::DATA['hits'], (string) $object->getHits()); + $this->assertEquals(self::DATA['ordering'], (string) $object->getOrdering()); + + $this->assertEquals(self::DATA['seo_title'], (string) $object->getSeoTitle()); + $this->assertEquals(self::DATA['seo_description'], (string) $object->getSeoDescription()); + $this->assertEquals(self::DATA['seo_keywords'], (string) $object->getSeoKeywords()); + + $this->assertEquals(self::DATA['created_at'], $object->getCreatedAt()->toDatetimeString()); + $this->assertEquals(self::DATA['updated_at'], $object->getUpdatedAt()->toDatetimeString()); + $this->assertEquals(self::DATA['updated_at'], $object->getDeletedAt()->toDatetimeString()); + } + + public function testLoadsDefaultsSuccessfully(): void + { + $data = self::DATA; + unset( + $data['id'], + $data['ordering'], + $data['hits'], + $data['is_featured'], + $data['is_published'], + $data['active'], + $data['updated_at'], + $data['deleted_at'], + $data['email'] + ); + + $object = new GeneralTraitsVO($data); + + $this->assertTrue($object->isNew()); + $this->assertFalse($object->isActive()); + $this->assertFalse($object->isFeatured()); + $this->assertFalse($object->isPublished()); + + $this->assertNull($object->getEmail()); + + $this->assertEquals(0, $object->getHits()); + $this->assertEquals(0, $object->getOrdering()); + + $this->assertFalse($object->isDeleted()); + $this->assertNull($object->getDeletedAt()); + $this->assertNull($object->getUpdatedAt()); + } + + public function testBreaksIfIdIsNegative(): void + { + $this->expectException(PositiveIntegerException::class); + + $data = self::DATA; + $data['id'] = -1; + + $object = new GeneralTraitsVO($data); + } + + public function testBreaksIfTitleIsEmpty(): void + { + $this->expectException(NonEmptyStringException::class); + + $data = self::DATA; + $data['title'] = ''; + + $object = new GeneralTraitsVO($data); + } + + public function testBreaksIfNameIsEmpty(): void + { + $this->expectException(NonEmptyStringException::class); + + $data = self::DATA; + $data['name'] = ''; + + $object = new GeneralTraitsVO($data); + } + + public function testBreaksIfAliasIsEmpty(): void + { + $this->expectException(NonEmptyStringException::class); + + $data = self::DATA; + $data['alias'] = ''; + + $object = new GeneralTraitsVO($data); + } + + public function testBreaksIfHitsIsNegative(): void + { + $this->expectException(NonNegativeNumberException::class); + + $data = self::DATA; + $data['hits'] = -1; + + $object = new GeneralTraitsVO($data); + } + + public function testBreaksIfOrderingIsNegative(): void + { + $this->expectException(NonNegativeNumberException::class); + + $data = self::DATA; + $data['ordering'] = -1; + + $object = new GeneralTraitsVO($data); + } + + public function testBreaksIfSeoTitleTooLong(): void + { + $this->expectException(InvalidStringLengthException::class); + + $data = self::DATA; + $tenCharacterString = 'sodhgfsodh'; + $data['seo_title'] = str_repeat($tenCharacterString, 7) . 'a'; + + $object = new GeneralTraitsVO($data); + } + + public function testBreaksIfSeoDescriptionTooLong(): void + { + $this->expectException(InvalidStringLengthException::class); + + $data = self::DATA; + $tenCharacterString = 'sodhgfsodh'; + $data['seo_description'] = str_repeat($tenCharacterString, 16) . 'a'; + + $object = new GeneralTraitsVO($data); + } + + public function testBreaksIfSeoKeywordsTooLong(): void + { + $this->expectException(InvalidStringLengthException::class); + + $data = self::DATA; + $tenCharacterString = 'sodhgfsodh'; + $data['seo_keywords'] = str_repeat($tenCharacterString, 25) . 'hgfdsa'; + + $object = new GeneralTraitsVO($data); + } + + public function testLoadsNullValueIfSeoFieldEmptyString(): void + { + $data = self::DATA; + $data['seo_title'] = ' '; + $data['seo_description'] = ' '; + $data['seo_keywords'] = ' '; + + $object = new GeneralTraitsVO($data); + + $this->assertNull($object->getSeoTitle()); + $this->assertNull($object->getSeoDescription()); + $this->assertNull($object->getSeoKeywords()); + } + + public function testUpdateDateTimeOnUpdateTrigger(): void + { + $object = new GeneralTraitsVO(self::DATA); + + $this->assertEquals(self::DATA['updated_at'], $object->getUpdatedAt()->toDatetimeString()); + $object->simulateUpdate(); + $this->assertNotEquals(self::DATA['updated_at'], $object->getUpdatedAt()->toDatetimeString()); + } +} From 7c91d2e8e8c98afd9bc35a6b6897d0abbbd05d53 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 19:41:44 +0000 Subject: [PATCH 130/193] fix: Fix condition for __toString() existence --- src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php index b5df150..71a567a 100644 --- a/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php +++ b/src/Traits/ValueObjects/HasConversionToPrimitiveValuesTrait.php @@ -32,7 +32,7 @@ private function convertIntoPrimitiveValues(array $fields, bool $objectAsJson = // If is not an Object not an Array, returns the actual value of the Field. if ($value instanceof AbstractValueObject || $value instanceof EntityCollection) { $converted[$field] = $objectAsJson ? $value->jsonSerialize() : $value->toArray(); - } elseif (\method_exists($value, '__toString')) { + } elseif (\is_object($value) && \method_exists($value, '__toString')) { $converted[$field] = (string) $value; } elseif (\is_object($value)) { $converted[$field] = (array) $value; From 3b92f1a0c0af634f187415e7f79965127f7b4ba7 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 7 Mar 2022 19:47:05 +0000 Subject: [PATCH 131/193] refactor: Stop implementing Serializable interface --- src/Web/EmailAddress.php | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 2d2c3c6..741c8df 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -18,7 +18,7 @@ * @copyright HraDigital\Datatypes * @license MIT */ -class EmailAddress implements \Serializable +class EmailAddress { /** @var Str $username - Holds the Username's part of the E-mail address. */ protected Str $username; @@ -84,25 +84,17 @@ protected function loadFromPrimitive(string $email): void $this->domain = Str::create(\implode('.', $domain)); } - /** - * {@inheritDoc} - * @see \Serializable::serialize() - */ - public function serialize() + public function __serialize(): array { - return \serialize( - (string) $this->address() - ); + return [ + 'email'=> (string) $this, + ]; } - /** - * {@inheritDoc} - * @see \Serializable::unserialize() - */ - public function unserialize($serialized) + public function __unserialize(array $data): void { $this->loadFromPrimitive( - \unserialize($serialized) + $data['email'] ); } From fba98b22653abab95572e41a4e07bf274d318705 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 8 Mar 2022 10:38:14 +0000 Subject: [PATCH 132/193] docs: Improve Value Object's documentation --- src/ValueObjects/README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/ValueObjects/README.md b/src/ValueObjects/README.md index 8ca5ac3..7199687 100755 --- a/src/ValueObjects/README.md +++ b/src/ValueObjects/README.md @@ -55,6 +55,22 @@ trait HasEmailTrait } ``` +Attributes are usually defined using "_snake-case_", and in order to more easily handling persisted data, usually map directly +to the names of the corresponding fields in the persistence layer. This also helps out, when serializing the record to JSON, +as it "_usually_" uses the same casing. + +Casting methods should be set as `protected`, and have `cast` prefix followed by the name of the existing attribute (_CamelCase_) +without any underscores. Eg: + +- `$email` would have the casting method `protected function castEmail()`. +- `$user_name` would have the casting method `protected function castUserName()`. +- `$date_of_birth` would have the casting method `protected function castDateOfBirth()`. + +Usually, each Attribute and Casting method should be accompanied by a Getter. Getter methods should account for the possibility of +an Attribute not being handed a value while instantiating, therefore, it's good policy to assign it a default one. + +### Using Field's Traits + You can build whole objects using these `Traits`. By default, when adding these `Traits`, your object will be immutable. @@ -300,3 +316,14 @@ $user->rename( ); $user->getUpdatedAt(); // Updated DateTime. ``` + +## Loading Execution Order + +When instantiating a new ValueObject/Entity that extends `AbstractValueObject`, the order of events is as follows: + +- Register instance's structure (_available attributes, casting methods, rule methods, ..._) +- Map supplied fields to instance's attributes (_rename supplied keys using `$maps` as reference_) +- Processes Rules for supplied fields (_all `protected` methods with `rule` prefix_) +- Validates if all required fields were supplied (_compares supplied field's keys with `$required` array_) +- Load/cast supplied data into existing attributes (_loads supplied fields using all `protected` methods with `cast` prefix_) +- Trigger onLoad handlers (_calls all `protected` methods with `onLoad` prefix_) From 83ac95e63c6b2b4793e75cce5c5a7bc97f08a3e5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 16:24:01 +0000 Subject: [PATCH 133/193] refactor: Refactor getDirty() method --- .../Entities/CanProcessEntityStateTrait.php | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index 573780d..fabf4a4 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Traits\Entities; +use HraDigital\Datatypes\ValueObjects\AbstractValueObject; + /** * Will handle state changes on an Entity. * @@ -25,7 +27,7 @@ trait CanProcessEntityStateTrait */ protected function onLoadSnapshotState(): void { - $this->initialState = $this->getAttributes(); + $this->initialState = $this->toArray(); } /** @@ -53,15 +55,30 @@ final public function getDirty(bool $withTimestamps = false): array { // Loops through all the class' attributes, and validates if any has changed. $dirty = []; - foreach ($this->getAttributes() as $field => $value) { - // Is the current value different from the initial one? - // Is the Entity NEW, and the field a required one? - // If so, add it to the $dirty return array. - $hasChanged = ($value !== $this->initialState[$field]); - $isNewOrRequired = ($this->isNew() && \array_search($field, $this->required)); + foreach ($this->initialState as $field => $value) { + + $isNewOrRequired = ( + (\method_exists($this, 'isNew') && $this->isNew()) || + \array_search($field, $this->required) + ); + + if ($this->{$field} instanceof AbstractValueObject) { + + if ($isNewOrRequired || (\method_exists($this->{$field}, 'isDirty') && $this->{$field}->isDirty())) { + $dirty[$field] = $this->{$field}->getDirty($withTimestamps); + } + + continue; + } + + if (\method_exists($this->{$field}, '__toString')) { + $hasChanged = ((string) $value) !== ((string) $this->{$field}); + } else { + $hasChanged = $value !== $this->{$field}; + } if ($hasChanged || $isNewOrRequired) { - $dirty[$field] = $value; + $dirty[$field] = $this->{$field}; } } @@ -94,7 +111,7 @@ final public function getOriginal(): array */ final public function resetState(): void { - $this->initialState = $this->getAttributes(); + $this->initialState = $this->toArray(); } /** From f58232886b5799fa751f1550feb2edc2eaa1e04d Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 16:24:28 +0000 Subject: [PATCH 134/193] tests: Adapt AbstractValueObject's tests --- .../ValueObjects/AbstractValueObjectTest.php | 47 ++++++++++++++++++- .../ValueObjects/TestingNestedValueObject.php | 31 +++++++++++- .../Unit/ValueObjects/TestingValueObject.php | 39 ++++++++++----- 3 files changed, 102 insertions(+), 15 deletions(-) diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php index 810d4c9..7067e73 100644 --- a/tests/Unit/ValueObjects/AbstractValueObjectTest.php +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -29,7 +29,7 @@ public function testLoadsSuccessfully(): void // Test Rule's processing works. $this->assertEquals( - 'MY OUTTER TITLE', + 'MY TITLE', (string) $valueObject->getTitle()->toUpper() ); @@ -131,4 +131,49 @@ public function testCanCallDebugInfoInValueObject(): void $this->assertArrayHasKey('title', $array['inner']); $this->assertArrayHasKey('active', $array['inner']); } + + /** + * @group hugo + */ + public function testCanChangeAndTrackState(): void + { + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + + // Checks initially loaded state. + $this->assertFalse($valueObject->isActive()); + $this->assertFalse($valueObject->getInner()->isActive()); + $mainUpdatedAt = $valueObject->getUpdatedAt(); + $innerUpdatedAt = $valueObject->getInner()->getUpdatedAt(); + + // Perform state change operations on Aggregate. + $valueObject->activate(); + $valueObject->changeTitle(Str::create('Main Title')); + + // Checks it's now marked as Dirty + $this->assertTrue($valueObject->isActive()); + $this->assertFalse($valueObject->getInner()->isActive()); + $this->assertTrue($valueObject->isDirty()); + $dirty = $valueObject->getDirty(true); + + // Checks Dirty array contains only fields that have changed. + $this->assertArrayHasKey('active', $dirty); + $this->assertArrayNotHasKey('email', $dirty); + $this->assertArrayHasKey('title', $dirty); + $this->assertArrayHasKey('inner', $dirty); + + $this->assertArrayHasKey('title', $dirty['inner']); + $this->assertArrayNotHasKey('active', $dirty['inner']); + + // Asserts that UpdatedAt DateTimes have updated with calls. + $this->assertNotEquals( + (string) $mainUpdatedAt->toDatetimeString(), + (string) $valueObject->getUpdatedAt()->toDatetimeString() + ); + $this->assertNotEquals( + (string) $innerUpdatedAt->toDatetimeString(), + (string) $valueObject->getInner()->getUpdatedAt()->toDatetimeString() + ); + } } diff --git a/tests/Unit/ValueObjects/TestingNestedValueObject.php b/tests/Unit/ValueObjects/TestingNestedValueObject.php index 494264f..b5dbd1d 100644 --- a/tests/Unit/ValueObjects/TestingNestedValueObject.php +++ b/tests/Unit/ValueObjects/TestingNestedValueObject.php @@ -4,9 +4,14 @@ namespace HraDigital\Tests\Datatypes\Unit\ValueObjects; +use HraDigital\Datatypes\Datetime\Datetime; +use HraDigital\Datatypes\Scalar\Str; +use HraDigital\Datatypes\Traits\Entities\CanProcessEntityStateTrait; +use HraDigital\Datatypes\Traits\Entities\CanProcessOnUpdateEventsTrait; use HraDigital\Datatypes\Traits\Entities\General\HasActiveTrait; use HraDigital\Datatypes\Traits\Entities\General\HasEmailTrait; use HraDigital\Datatypes\Traits\Entities\General\HasTitleTrait; +use HraDigital\Datatypes\Traits\Entities\General\HasUpdatableUpdatedAtTrait; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; /** @@ -19,8 +24,32 @@ class TestingNestedValueObject extends AbstractValueObject { use HasActiveTrait, - HasTitleTrait; + HasTitleTrait, + HasUpdatableUpdatedAtTrait, + CanProcessEntityStateTrait, + CanProcessOnUpdateEventsTrait; /** @var array $guarded - List of fields that should not be serializable into JSON. */ protected array $guarded = ['active']; + + protected function ruleSetUpdatedAtIfMissing(array $fields): array + { + if (!isset($fields['updated_at'])) { + $fields['updated_at'] = (string) Datetime::now()->addHours(-1); + } + + return $fields; + } + + public function activate(): void + { + $this->active = true; + $this->triggerOnUpdate(); + } + + public function changeTitle(Str $title): void + { + $this->title = $title; + $this->triggerOnUpdate(); + } } diff --git a/tests/Unit/ValueObjects/TestingValueObject.php b/tests/Unit/ValueObjects/TestingValueObject.php index c60841f..4e4b5c1 100644 --- a/tests/Unit/ValueObjects/TestingValueObject.php +++ b/tests/Unit/ValueObjects/TestingValueObject.php @@ -4,9 +4,14 @@ namespace HraDigital\Tests\Datatypes\Unit\ValueObjects; +use HraDigital\Datatypes\Datetime\Datetime; +use HraDigital\Datatypes\Scalar\Str; +use HraDigital\Datatypes\Traits\Entities\CanProcessEntityStateTrait; +use HraDigital\Datatypes\Traits\Entities\CanProcessOnUpdateEventsTrait; use HraDigital\Datatypes\Traits\Entities\General\HasActiveTrait; use HraDigital\Datatypes\Traits\Entities\General\HasEmailTrait; use HraDigital\Datatypes\Traits\Entities\General\HasTitleTrait; +use HraDigital\Datatypes\Traits\Entities\General\HasUpdatableUpdatedAtTrait; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; /** @@ -23,14 +28,17 @@ class TestingValueObject extends AbstractValueObject 'address' => 'user@domain.tld', 'title' => 'my title', 'inner' => [ - 'active' => true, + 'active' => false, 'title' => 'My Inner Title', ], ]; use HasActiveTrait, HasEmailTrait, - HasTitleTrait; + HasTitleTrait, + HasUpdatableUpdatedAtTrait, + CanProcessEntityStateTrait, + CanProcessOnUpdateEventsTrait; /** @var array $guarded - List of fields that should not be serializable into JSON. */ protected array $guarded = ['email']; @@ -42,8 +50,6 @@ class TestingValueObject extends AbstractValueObject protected array $required = [ 'active', - 'email', - 'title', ]; protected TestingNestedValueObject $inner; @@ -53,7 +59,7 @@ protected function castInner(array $inner): void $this->inner = new TestingNestedValueObject($inner); } - protected function getInner(): TestingNestedValueObject + public function getInner(): TestingNestedValueObject { return $this->inner; } @@ -64,20 +70,27 @@ protected function getInner(): TestingNestedValueObject * @param array $fields - Original fields being loaded into the Value Object. * @return array */ - protected function ruleTestingMethod(array $fields): array + protected function ruleSetUpdatedAtIfMissing(array $fields): array { - $fields['title'] = 'My Outter Title'; + if (!isset($fields['updated_at'])) { + $fields['updated_at'] = (string) Datetime::now()->addHours(-1); + } return $fields; } - /** - * onLoad's testing handler. - * - * @return void - */ - protected function onLoadActivateValueObjectHandler(): void + public function activate(): void { $this->active = true; + + $this->triggerOnUpdate(); + } + + public function changeTitle(Str $title): void + { + $this->title = Str::create('My ' . (string) $title); + $this->inner->changeTitle($this->title->replace('My ', 'My Other ')); + + $this->triggerOnUpdate(); } } From 8db692ff64bee3978734e181de2cf849632dcad8 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 16:25:44 +0000 Subject: [PATCH 135/193] fix: Remove debugging flag --- tests/Unit/ValueObjects/AbstractValueObjectTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php index 7067e73..59cbd00 100644 --- a/tests/Unit/ValueObjects/AbstractValueObjectTest.php +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -132,9 +132,6 @@ public function testCanCallDebugInfoInValueObject(): void $this->assertArrayHasKey('active', $array['inner']); } - /** - * @group hugo - */ public function testCanChangeAndTrackState(): void { $valueObject = new TestingValueObject( From 2a34cf215f41915c5bcbdb40c20191d90acf3019 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 16:27:01 +0000 Subject: [PATCH 136/193] tests: Fix test --- tests/Unit/ValueObjects/AbstractValueObjectTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php index 59cbd00..b8c6435 100644 --- a/tests/Unit/ValueObjects/AbstractValueObjectTest.php +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -25,7 +25,7 @@ public function testLoadsSuccessfully(): void // Tests field mapping and onLoad events work. $this->assertFalse(TestingValueObject::DATA['is_active']); - $this->assertTrue($valueObject->isActive()); + $this->assertFalse($valueObject->isActive()); // Test Rule's processing works. $this->assertEquals( From df5f2eb45a002b8548d913c5a3bf28bdcc4f9020 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 16:56:49 +0000 Subject: [PATCH 137/193] refactor: Extract setAttributes to dedicated Trait --- .../Entities/CanMassAssignStateTrait.php | 62 +++++++++++++++++++ .../Entities/CanProcessEntityStateTrait.php | 35 ----------- 2 files changed, 62 insertions(+), 35 deletions(-) create mode 100644 src/Traits/Entities/CanMassAssignStateTrait.php diff --git a/src/Traits/Entities/CanMassAssignStateTrait.php b/src/Traits/Entities/CanMassAssignStateTrait.php new file mode 100644 index 0000000..6834458 --- /dev/null +++ b/src/Traits/Entities/CanMassAssignStateTrait.php @@ -0,0 +1,62 @@ +translateToMappedFields($fields); + $this->processRules($mapped); + + $fields = []; + foreach ($mapped as $field => $value) { + if ($this->{$field} instanceof AbstractValueObject && \method_exists($this->{$field}, 'setAttributes')) { + $this->{$field}->setAttributes($value); + } else { + $fields[$field] = $value; + } + } + + $this->castAttributes($fields); + + if (\method_exists($this, 'triggerOnUpdate')) { + $this->{'triggerOnUpdate'}(); + } + } +} diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index fabf4a4..b9cde89 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -113,39 +113,4 @@ final public function resetState(): void { $this->initialState = $this->toArray(); } - - /** - * Sets new values to a set of class attributes, all at once. - * - * @param array $fields - Associative array, where the keys are the class attribute's names. - * - * @throws \UnderflowException - If supplied array is empty. - * @throws \UnexpectedValueException - If supplied array is not a string-key only associative array. - * @throws \InvalidArgumentException - If supplied attribute's names are not non empty strings. - * @throws \BadMethodCallException - If any setter method doesn't exist for a chosen attribute. - * - * @return void - */ - final public function setAttributes(array $fields): void - { - // Validates the supplied array is a non empty associative one. - $count = \count($fields); - if ($count === 0) { - throw new \UnderflowException('Supplied parameter should be a non empty Array.'); - } - - // Validates that all the indexes are of String type. - if (\count(\array_filter(\array_keys($fields), 'is_string')) !== $count) { - throw new \UnexpectedValueException('Supplied parameter should have been an Associative Array.'); - } - - // Process supplied fields. - $mapped = $this->translateToMappedFields($fields); - $this->processRules($mapped); - $this->castAttributes($mapped); - - if (\method_exists($this, 'triggerOnUpdate')) { - $this->{'triggerOnUpdate'}(); - } - } } From f2778d8a363b617956ed1275140430c10d7e85b6 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 16:57:28 +0000 Subject: [PATCH 138/193] tests: Adapt tests for AbstractValueObject --- .../ValueObjects/AbstractValueObjectTest.php | 48 +++++++++++++++++++ .../ValueObjects/TestingNestedValueObject.php | 8 ++-- .../Unit/ValueObjects/TestingValueObject.php | 8 ++-- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php index b8c6435..ee4633a 100644 --- a/tests/Unit/ValueObjects/AbstractValueObjectTest.php +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -172,5 +172,53 @@ public function testCanChangeAndTrackState(): void (string) $innerUpdatedAt->toDatetimeString(), (string) $valueObject->getInner()->getUpdatedAt()->toDatetimeString() ); + + // Asserts that Original UpdatedAt DateTimes were kept. + $original = $valueObject->getOriginal(); + $this->assertEquals( + (string) $mainUpdatedAt->toDatetimeString(), + (string) $original['updated_at'] + ); + $this->assertEquals( + (string) $innerUpdatedAt->toDatetimeString(), + (string) $original['inner']['updated_at'] + ); + } + + public function testCanMassAssignValues(): void + { + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + $mainUpdatedAt = $valueObject->getUpdatedAt(); + $innerUpdatedAt = $valueObject->getInner()->getUpdatedAt(); + + $valueObject->setAttributes([ + 'title' => 'Mass assigned Title', + 'inner' => [ + 'active' => true, + ], + ]); + + $dirty = $valueObject->getDirty(true); + + // Checks Dirty array contains only fields that have changed. + $this->assertArrayNotHasKey('email', $dirty); + $this->assertArrayHasKey('title', $dirty); + $this->assertArrayHasKey('inner', $dirty); + + $this->assertArrayNotHasKey('title', $dirty['inner']); + $this->assertArrayHasKey('active', $dirty['inner']); + + // Asserts that Original UpdatedAt DateTimes were kept. + $original = $valueObject->getOriginal(); + $this->assertEquals( + (string) $mainUpdatedAt->toDatetimeString(), + (string) $original['updated_at'] + ); + $this->assertEquals( + (string) $innerUpdatedAt->toDatetimeString(), + (string) $original['inner']['updated_at'] + ); } } diff --git a/tests/Unit/ValueObjects/TestingNestedValueObject.php b/tests/Unit/ValueObjects/TestingNestedValueObject.php index b5dbd1d..9a0ec23 100644 --- a/tests/Unit/ValueObjects/TestingNestedValueObject.php +++ b/tests/Unit/ValueObjects/TestingNestedValueObject.php @@ -6,6 +6,7 @@ use HraDigital\Datatypes\Datetime\Datetime; use HraDigital\Datatypes\Scalar\Str; +use HraDigital\Datatypes\Traits\Entities\CanMassAssignStateTrait; use HraDigital\Datatypes\Traits\Entities\CanProcessEntityStateTrait; use HraDigital\Datatypes\Traits\Entities\CanProcessOnUpdateEventsTrait; use HraDigital\Datatypes\Traits\Entities\General\HasActiveTrait; @@ -24,10 +25,11 @@ class TestingNestedValueObject extends AbstractValueObject { use HasActiveTrait, - HasTitleTrait, - HasUpdatableUpdatedAtTrait, + CanMassAssignStateTrait, CanProcessEntityStateTrait, - CanProcessOnUpdateEventsTrait; + CanProcessOnUpdateEventsTrait, + HasTitleTrait, + HasUpdatableUpdatedAtTrait; /** @var array $guarded - List of fields that should not be serializable into JSON. */ protected array $guarded = ['active']; diff --git a/tests/Unit/ValueObjects/TestingValueObject.php b/tests/Unit/ValueObjects/TestingValueObject.php index 4e4b5c1..ceab2a8 100644 --- a/tests/Unit/ValueObjects/TestingValueObject.php +++ b/tests/Unit/ValueObjects/TestingValueObject.php @@ -6,6 +6,7 @@ use HraDigital\Datatypes\Datetime\Datetime; use HraDigital\Datatypes\Scalar\Str; +use HraDigital\Datatypes\Traits\Entities\CanMassAssignStateTrait; use HraDigital\Datatypes\Traits\Entities\CanProcessEntityStateTrait; use HraDigital\Datatypes\Traits\Entities\CanProcessOnUpdateEventsTrait; use HraDigital\Datatypes\Traits\Entities\General\HasActiveTrait; @@ -34,11 +35,12 @@ class TestingValueObject extends AbstractValueObject ]; use HasActiveTrait, + CanMassAssignStateTrait, + CanProcessEntityStateTrait, + CanProcessOnUpdateEventsTrait, HasEmailTrait, HasTitleTrait, - HasUpdatableUpdatedAtTrait, - CanProcessEntityStateTrait, - CanProcessOnUpdateEventsTrait; + HasUpdatableUpdatedAtTrait; /** @var array $guarded - List of fields that should not be serializable into JSON. */ protected array $guarded = ['email']; From 7359775fed6608b6c642b67988a42fa11f696af7 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 17:09:10 +0000 Subject: [PATCH 139/193] fix: Reset state of inner VOs as well --- src/Traits/Entities/CanProcessEntityStateTrait.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index b9cde89..39622a4 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -111,6 +111,12 @@ final public function getOriginal(): array */ final public function resetState(): void { + foreach ($this->initialState as $field => $value) { + if ($this->{$field} instanceof AbstractValueObject && \method_exists($this->{$field}, 'resetState')) { + $this->{$field}->resetState(); + } + } + $this->initialState = $this->toArray(); } } From 551880369f68121799fd9a5420490080f50a838a Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 17:28:39 +0000 Subject: [PATCH 140/193] refactor: Improve mass assignment setAttributes() method --- src/Traits/Entities/CanMassAssignStateTrait.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Traits/Entities/CanMassAssignStateTrait.php b/src/Traits/Entities/CanMassAssignStateTrait.php index 6834458..8ceacd1 100644 --- a/src/Traits/Entities/CanMassAssignStateTrait.php +++ b/src/Traits/Entities/CanMassAssignStateTrait.php @@ -4,6 +4,7 @@ namespace HraDigital\Datatypes\Traits\Entities; +use HraDigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; /** @@ -20,11 +21,7 @@ trait CanMassAssignStateTrait * * @param array $fields - Associative array, where the keys are the class attribute's names. * - * @throws \UnderflowException - If supplied array is empty. - * @throws \UnexpectedValueException - If supplied array is not a string-key only associative array. - * @throws \InvalidArgumentException - If supplied attribute's names are not non empty strings. - * @throws \BadMethodCallException - If any setter method doesn't exist for a chosen attribute. - * + * @throws ParameterOutOfRangeException - If supplied array is empty. * @return void */ final public function setAttributes(array $fields): void @@ -32,12 +29,7 @@ final public function setAttributes(array $fields): void // Validates the supplied array is a non empty associative one. $count = \count($fields); if ($count === 0) { - throw new \UnderflowException('Supplied parameter should be a non empty Array.'); - } - - // Validates that all the indexes are of String type. - if (\count(\array_filter(\array_keys($fields), 'is_string')) !== $count) { - throw new \UnexpectedValueException('Supplied parameter should have been an Associative Array.'); + throw ParameterOutOfRangeException::withName('$fields'); } // Process supplied fields. @@ -48,6 +40,8 @@ final public function setAttributes(array $fields): void foreach ($mapped as $field => $value) { if ($this->{$field} instanceof AbstractValueObject && \method_exists($this->{$field}, 'setAttributes')) { $this->{$field}->setAttributes($value); + } elseif (\method_exists($this->{$field}, '__toString')) { + $fields[$field] = (string) $value; } else { $fields[$field] = $value; } From fca511c8a0e490bbae23927c430f76b7de2ea585 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 17:28:59 +0000 Subject: [PATCH 141/193] tests: Increase test coverage --- .../ValueObjects/AbstractValueObjectTest.php | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php index ee4633a..321997f 100644 --- a/tests/Unit/ValueObjects/AbstractValueObjectTest.php +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -5,6 +5,9 @@ namespace HraDigital\Tests\Datatypes\Unit\ValueObjects; use HraDigital\Datatypes\Exceptions\Entities\RequiredEntityValueMissingException; +use HraDigital\Datatypes\Exceptions\Entities\UnexpectedEntityValueException; +use HraDigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; +use HraDigital\Datatypes\Datetime\Datetime; use HraDigital\Datatypes\Scalar\Str; use HraDigital\Tests\Datatypes\AbstractBaseTestCase; @@ -185,6 +188,38 @@ public function testCanChangeAndTrackState(): void ); } + public function testCanResetState(): void + { + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + + // Checks initially loaded state. + $this->assertFalse($valueObject->isActive()); + $this->assertFalse($valueObject->getInner()->isActive()); + $mainUpdatedAt = $valueObject->getUpdatedAt(); + $innerUpdatedAt = $valueObject->getInner()->getUpdatedAt(); + $array = $valueObject->toArray(); + + // Perform state change operations on Aggregate. + $valueObject->activate(); + $valueObject->changeTitle(Str::create('Main Title')); + $valueObject->resetState(); + + // Checks it's now marked as Dirty + $this->assertTrue($valueObject->isActive()); + $this->assertFalse($valueObject->getInner()->isActive()); + $this->assertFalse($valueObject->isDirty()); + $dirty = $valueObject->getDirty(true); + + // Checks Dirty array contains only fields that have changed. + $this->assertArrayNotHasKey('active', $dirty); + $this->assertArrayNotHasKey('email', $dirty); + $this->assertArrayNotHasKey('title', $dirty); + $this->assertArrayNotHasKey('inner', $dirty); + $this->assertCount(0, $dirty); + } + public function testCanMassAssignValues(): void { $valueObject = new TestingValueObject( @@ -221,4 +256,15 @@ public function testCanMassAssignValues(): void (string) $original['inner']['updated_at'] ); } + + public function testBreaksWhenMassAssignmentIsEmpty(): void + { + $this->expectException(ParameterOutOfRangeException::class); + + $valueObject = new TestingValueObject( + TestingValueObject::DATA + ); + + $valueObject->setAttributes([]); + } } From d19aa54a56cf856925bc2a5d5dfd7e001a29ffc5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Wed, 9 Mar 2022 17:34:25 +0000 Subject: [PATCH 142/193] fix: Improve __toString() implementation check --- src/Traits/Entities/CanMassAssignStateTrait.php | 2 +- src/Traits/Entities/CanProcessEntityStateTrait.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Traits/Entities/CanMassAssignStateTrait.php b/src/Traits/Entities/CanMassAssignStateTrait.php index 8ceacd1..6eb648a 100644 --- a/src/Traits/Entities/CanMassAssignStateTrait.php +++ b/src/Traits/Entities/CanMassAssignStateTrait.php @@ -40,7 +40,7 @@ final public function setAttributes(array $fields): void foreach ($mapped as $field => $value) { if ($this->{$field} instanceof AbstractValueObject && \method_exists($this->{$field}, 'setAttributes')) { $this->{$field}->setAttributes($value); - } elseif (\method_exists($this->{$field}, '__toString')) { + } elseif (\is_object($this->{$field}) && \method_exists($this->{$field}, '__toString')) { $fields[$field] = (string) $value; } else { $fields[$field] = $value; diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index 39622a4..4725d32 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -71,7 +71,7 @@ final public function getDirty(bool $withTimestamps = false): array continue; } - if (\method_exists($this->{$field}, '__toString')) { + if (\is_object($this->{$field}) && \method_exists($this->{$field}, '__toString')) { $hasChanged = ((string) $value) !== ((string) $this->{$field}); } else { $hasChanged = $value !== $this->{$field}; From 0331ca092bbd40a7dd0bcb8abac90962380fd847 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 09:46:50 +0000 Subject: [PATCH 143/193] tests: Add tests for Location Traits --- .../Unit/Traits/Entities/LocationTraitsVO.php | 44 ++++++++++++ .../Traits/Entities/LocationTraitsVOTest.php | 67 +++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 tests/Unit/Traits/Entities/LocationTraitsVO.php create mode 100644 tests/Unit/Traits/Entities/LocationTraitsVOTest.php diff --git a/tests/Unit/Traits/Entities/LocationTraitsVO.php b/tests/Unit/Traits/Entities/LocationTraitsVO.php new file mode 100644 index 0000000..c04b4b0 --- /dev/null +++ b/tests/Unit/Traits/Entities/LocationTraitsVO.php @@ -0,0 +1,44 @@ + 'Main Street', + 'city' => 'Gotham', + 'country_code' => '123', + 'country' => 'USA', + 'district' => 'Mid-West', + 'latitude' => 14.12345, + 'longitude' => 12.654231, + 'parish' => 'SoHo', + 'postal_code' => 'PS13456', + 'street_additional' => 'Wayne Lane', + 'street_no' => '456', + 'street' => 'Main Street', + ]; + + public function testLoadsSuccessfully(): void + { + $object = new LocationTraitsVO(self::DATA); + + $this->assertEquals(self::DATA['address'], (string) $object->getAddress()); + $this->assertEquals(self::DATA['city'], (string) $object->getCity()); + $this->assertEquals(self::DATA['country_code'], (string) $object->getCountryCode()); + $this->assertEquals(self::DATA['country'], (string) $object->getCountry()); + $this->assertEquals(self::DATA['district'], (string) $object->getDistrict()); + $this->assertEquals(self::DATA['latitude'], (string) $object->getLatitude()); + $this->assertEquals(self::DATA['longitude'], (string) $object->getLongitude()); + $this->assertEquals(self::DATA['parish'], (string) $object->getParish()); + $this->assertEquals(self::DATA['postal_code'], (string) $object->getPostalCode()); + $this->assertEquals(self::DATA['street_additional'], (string) $object->getStreetAdditional()); + $this->assertEquals(self::DATA['street_no'], (string) $object->getStreetNumber()); + $this->assertEquals(self::DATA['street'], (string) $object->getStreet()); + } +} From 1835c5ec3930a9f550e64cb915277c1f92b6c208 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 09:48:53 +0000 Subject: [PATCH 144/193] fix: Adapt matching methods --- src/Traits/Entities/Personal/HasGenderTrait.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Traits/Entities/Personal/HasGenderTrait.php b/src/Traits/Entities/Personal/HasGenderTrait.php index a745270..650b761 100644 --- a/src/Traits/Entities/Personal/HasGenderTrait.php +++ b/src/Traits/Entities/Personal/HasGenderTrait.php @@ -31,9 +31,9 @@ protected function castGender(string $gender): void $genderValue = Str::create($gender)->toLower()->toUpperFirst(); if (!( - $genderValue->equals(Str::create('Male')) || - $genderValue->equals(Str::create('Female')) || - $genderValue->equals(Str::create('Other')) + $genderValue->equals('Male') || + $genderValue->equals('Female') || + $genderValue->equals('Other') )) { throw new UnexpectedEntityValueException('$gender'); } From 0a1972e58725a5a8b24465314780f8f7959fe506 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 09:54:04 +0000 Subject: [PATCH 145/193] tests: Add missing Location tests --- .../Traits/Entities/LocationTraitsVOTest.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/Unit/Traits/Entities/LocationTraitsVOTest.php b/tests/Unit/Traits/Entities/LocationTraitsVOTest.php index 9884c1d..204165c 100644 --- a/tests/Unit/Traits/Entities/LocationTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/LocationTraitsVOTest.php @@ -64,4 +64,34 @@ public function testLoadsSuccessfully(): void $this->assertEquals(self::DATA['street_no'], (string) $object->getStreetNumber()); $this->assertEquals(self::DATA['street'], (string) $object->getStreet()); } + + public function testBreaksWithEmptyCity(): void + { + $data = self::DATA; + $data['city'] = ' '; + + $this->expectException(NonEmptyStringException::class); + + new LocationTraitsVO($data); + } + + public function testBreaksWithEmptyDistrict(): void + { + $data = self::DATA; + $data['district'] = ' '; + + $this->expectException(NonEmptyStringException::class); + + new LocationTraitsVO($data); + } + + public function testBreaksWithEmptyParish(): void + { + $data = self::DATA; + $data['parish'] = ' '; + + $this->expectException(NonEmptyStringException::class); + + new LocationTraitsVO($data); + } } From 218637474b764b7981237937a537ea0aeb47ccd6 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 10:15:27 +0000 Subject: [PATCH 146/193] BREAKING CHANGE: Moved Trait to correct namespace --- src/Traits/Entities/{Personal => General}/HasSurnameTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/Traits/Entities/{Personal => General}/HasSurnameTrait.php (95%) diff --git a/src/Traits/Entities/Personal/HasSurnameTrait.php b/src/Traits/Entities/General/HasSurnameTrait.php similarity index 95% rename from src/Traits/Entities/Personal/HasSurnameTrait.php rename to src/Traits/Entities/General/HasSurnameTrait.php index 2e91881..25348bf 100755 --- a/src/Traits/Entities/Personal/HasSurnameTrait.php +++ b/src/Traits/Entities/General/HasSurnameTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Personal; +namespace HraDigital\Datatypes\Traits\Entities\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; From 97727bfdd4ae842a3b05039d591c3a6d4cfec45c Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 13:57:05 +0000 Subject: [PATCH 147/193] test: move Surname's Trait namespace --- tests/Unit/Traits/Entities/GeneralTraitsVO.php | 2 ++ tests/Unit/Traits/Entities/GeneralTraitsVOTest.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVO.php b/tests/Unit/Traits/Entities/GeneralTraitsVO.php index 5079418..fd51338 100644 --- a/tests/Unit/Traits/Entities/GeneralTraitsVO.php +++ b/tests/Unit/Traits/Entities/GeneralTraitsVO.php @@ -21,6 +21,7 @@ use HraDigital\Datatypes\Traits\Entities\General\HasTitleTrait; use HraDigital\Datatypes\Traits\Entities\General\HasUpdatableUpdatedAtTrait; use HraDigital\Datatypes\Traits\Entities\General\HasUuidTrait; +use HraDigital\Datatypes\Traits\Entities\General\HasSurnameTrait; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; /** @@ -48,6 +49,7 @@ class GeneralTraitsVO extends AbstractValueObject HasTitleTrait, HasUpdatableUpdatedAtTrait, HasUuidTrait, + HasSurnameTrait, CanProcessOnUpdateEventsTrait; public function simulateUpdate(): void diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php index 86f13e4..7c8bd28 100644 --- a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php @@ -47,6 +47,7 @@ class GeneralTraitsVOTest extends AbstractBaseTestCase 'email' => 'user@domain.tld', 'hits' => 1999, 'name' => 'Name of Record', + 'surname' => 'Surname of Record', 'ordering' => 2, 'password' => 'usdhciucyneoyhnoerytos8ryt8svyeero8tyvwo8ryt8wryvutt89weysr8ncseryngngc8yeroiyncweryc8f', 'seo_title' => 'My SEO Title', @@ -73,6 +74,7 @@ public function testLoadsSuccessfully(): void $this->assertEquals(self::DATA['alias'], (string) $object->getAlias()); $this->assertEquals(self::DATA['email'], (string) $object->getEmail()); $this->assertEquals(self::DATA['name'], (string) $object->getName()); + $this->assertEquals(self::DATA['surname'], (string) $object->getSurname()); $this->assertEquals(self::DATA['title'], (string) $object->getTitle()); $this->assertEquals(self::DATA['password'], (string) $object->getPassword()); From 5da99e4b0456118355553e909d463561f10eee2b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 13:57:27 +0000 Subject: [PATCH 148/193] tests: remove unnused references --- tests/Unit/Traits/Entities/LocationTraitsVOTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Unit/Traits/Entities/LocationTraitsVOTest.php b/tests/Unit/Traits/Entities/LocationTraitsVOTest.php index 204165c..b12d281 100644 --- a/tests/Unit/Traits/Entities/LocationTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/LocationTraitsVOTest.php @@ -4,10 +4,7 @@ namespace HraDigital\Tests\Datatypes\Unit\Traits\Entities; -use HraDigital\Datatypes\Exceptions\Datatypes\InvalidStringLengthException; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; -use HraDigital\Datatypes\Exceptions\Datatypes\NonNegativeNumberException; -use HraDigital\Datatypes\Exceptions\Datatypes\PositiveIntegerException; use HraDigital\Datatypes\Traits\Entities\Location\HasAddressTrait; use HraDigital\Datatypes\Traits\Entities\Location\HasCityTrait; use HraDigital\Datatypes\Traits\Entities\Location\HasCountryCodeTrait; From 53a0233fca614e846536f0906f9f17cc26913b4e Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 13:57:58 +0000 Subject: [PATCH 149/193] tests: add initial tests for Personal Traits --- .../Unit/Traits/Entities/PersonalTraitsVO.php | 30 ++++++++ .../Traits/Entities/PersonalTraitsVOTest.php | 74 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 tests/Unit/Traits/Entities/PersonalTraitsVO.php create mode 100644 tests/Unit/Traits/Entities/PersonalTraitsVOTest.php diff --git a/tests/Unit/Traits/Entities/PersonalTraitsVO.php b/tests/Unit/Traits/Entities/PersonalTraitsVO.php new file mode 100644 index 0000000..d1c50a9 --- /dev/null +++ b/tests/Unit/Traits/Entities/PersonalTraitsVO.php @@ -0,0 +1,30 @@ + 'Ukraine', + 'dob' => '1980-02-05 00:00:00', + 'gender' => 'Male', + 'nationality' => 'Ukrainian', + 'photo' => '/path/to/some/photo.jpg', + ]; + + public function testLoadsSuccessfully(): void + { + $object = new PersonalTraitsVO(self::DATA); + + $this->assertEquals(self::DATA['country_of_birth'], (string) $object->getCountryOfBirth()); + $this->assertEquals(self::DATA['dob'], (string) $object->getDateOfBirth()); + $this->assertEquals(self::DATA['gender'], (string) $object->getGender()); + $this->assertEquals(self::DATA['nationality'], (string) $object->getNationality()); + $this->assertEquals(self::DATA['photo'], (string) $object->getPhoto()); + $this->assertTrue($object->hasPhoto()); + } + + public function testBreaksWithEmptyCoutryOfBirth(): void + { + $data = self::DATA; + $data['country_of_birth'] = ' '; + + $this->expectException(NonEmptyStringException::class); + + new PersonalTraitsVO($data); + } + + public function testBreaksWithEmptyNationality(): void + { + $data = self::DATA; + $data['nationality'] = ' '; + + $this->expectException(NonEmptyStringException::class); + + new PersonalTraitsVO($data); + } + + public function testBreaksWithEmptyPhoto(): void + { + $data = self::DATA; + $data['photo'] = ' '; + + $this->expectException(NonEmptyStringException::class); + + new PersonalTraitsVO($data); + } +} From 787ca1fac5138152c3240eb6c2716f2870016109 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 14:01:48 +0000 Subject: [PATCH 150/193] tests: improve tests for GeneralTraitsVO --- .../Traits/Entities/GeneralTraitsVOTest.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php index 7c8bd28..5b3ca26 100644 --- a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php @@ -129,7 +129,7 @@ public function testBreaksIfIdIsNegative(): void $data = self::DATA; $data['id'] = -1; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testBreaksIfTitleIsEmpty(): void @@ -139,7 +139,7 @@ public function testBreaksIfTitleIsEmpty(): void $data = self::DATA; $data['title'] = ''; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testBreaksIfNameIsEmpty(): void @@ -149,7 +149,7 @@ public function testBreaksIfNameIsEmpty(): void $data = self::DATA; $data['name'] = ''; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testBreaksIfAliasIsEmpty(): void @@ -159,7 +159,7 @@ public function testBreaksIfAliasIsEmpty(): void $data = self::DATA; $data['alias'] = ''; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testBreaksIfHitsIsNegative(): void @@ -169,7 +169,7 @@ public function testBreaksIfHitsIsNegative(): void $data = self::DATA; $data['hits'] = -1; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testBreaksIfOrderingIsNegative(): void @@ -179,7 +179,7 @@ public function testBreaksIfOrderingIsNegative(): void $data = self::DATA; $data['ordering'] = -1; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testBreaksIfSeoTitleTooLong(): void @@ -190,7 +190,7 @@ public function testBreaksIfSeoTitleTooLong(): void $tenCharacterString = 'sodhgfsodh'; $data['seo_title'] = str_repeat($tenCharacterString, 7) . 'a'; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testBreaksIfSeoDescriptionTooLong(): void @@ -201,7 +201,7 @@ public function testBreaksIfSeoDescriptionTooLong(): void $tenCharacterString = 'sodhgfsodh'; $data['seo_description'] = str_repeat($tenCharacterString, 16) . 'a'; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testBreaksIfSeoKeywordsTooLong(): void @@ -212,7 +212,7 @@ public function testBreaksIfSeoKeywordsTooLong(): void $tenCharacterString = 'sodhgfsodh'; $data['seo_keywords'] = str_repeat($tenCharacterString, 25) . 'hgfdsa'; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); } public function testLoadsNullValueIfSeoFieldEmptyString(): void @@ -222,7 +222,7 @@ public function testLoadsNullValueIfSeoFieldEmptyString(): void $data['seo_description'] = ' '; $data['seo_keywords'] = ' '; - $object = new GeneralTraitsVO($data); + new GeneralTraitsVO($data); $this->assertNull($object->getSeoTitle()); $this->assertNull($object->getSeoDescription()); From 2de5f04dcb5e73d51ea4ed8e72a28bb4d24bedf6 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 14:02:13 +0000 Subject: [PATCH 151/193] tests: fix test --- tests/Unit/Traits/Entities/GeneralTraitsVOTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php index 5b3ca26..c30a9f0 100644 --- a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php @@ -222,7 +222,7 @@ public function testLoadsNullValueIfSeoFieldEmptyString(): void $data['seo_description'] = ' '; $data['seo_keywords'] = ' '; - new GeneralTraitsVO($data); + $object = new GeneralTraitsVO($data); $this->assertNull($object->getSeoTitle()); $this->assertNull($object->getSeoDescription()); From a9acc365476ef1b8cebe61d2f986357dbbfbf7cd Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 14:03:53 +0000 Subject: [PATCH 152/193] tests: improve test for resetState() --- tests/Unit/ValueObjects/AbstractValueObjectTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php index 321997f..2d7302a 100644 --- a/tests/Unit/ValueObjects/AbstractValueObjectTest.php +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -197,9 +197,6 @@ public function testCanResetState(): void // Checks initially loaded state. $this->assertFalse($valueObject->isActive()); $this->assertFalse($valueObject->getInner()->isActive()); - $mainUpdatedAt = $valueObject->getUpdatedAt(); - $innerUpdatedAt = $valueObject->getInner()->getUpdatedAt(); - $array = $valueObject->toArray(); // Perform state change operations on Aggregate. $valueObject->activate(); From 96425dd33144678195b2edda145558ff6f3c76c0 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 14:06:53 +0000 Subject: [PATCH 153/193] refactor: improve resetState() --- src/Traits/Entities/CanProcessEntityStateTrait.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index 4725d32..15a2a73 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -111,7 +111,9 @@ final public function getOriginal(): array */ final public function resetState(): void { - foreach ($this->initialState as $field => $value) { + $fields = \array_keys($this->initialState); + + foreach ($fields as $field) { if ($this->{$field} instanceof AbstractValueObject && \method_exists($this->{$field}, 'resetState')) { $this->{$field}->resetState(); } From 9e6b32d8fefaff7c44ee8b5aa08d7a6905c9512d Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 16:01:35 +0000 Subject: [PATCH 154/193] tests: remove unnused references --- .../Traits/Entities/GeneralTraitsVOTest.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php index c30a9f0..b420813 100644 --- a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php @@ -8,23 +8,6 @@ use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Exceptions\Datatypes\NonNegativeNumberException; use HraDigital\Datatypes\Exceptions\Datatypes\PositiveIntegerException; -use HraDigital\Datatypes\Traits\Entities\General\HasActiveTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasAliasTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasCreatedAtTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasDeletedAtTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasEmailTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasFeatureTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasHitsTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasNameTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasOrderingTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasPasswordTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasPositiveIntegerIDTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasPublishedTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasSeoFieldsTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasTitleTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasUpdatableUpdatedAtTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasUuidTrait; -use HraDigital\Datatypes\ValueObjects\AbstractValueObject; use HraDigital\Tests\Datatypes\AbstractBaseTestCase; /** From b047d539fc9970c7874262094b63d10ce90f3bac Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 16:06:11 +0000 Subject: [PATCH 155/193] docs: fix typo in classes docblocks --- tests/Unit/Exceptions/CoreExceptionsTest.php | 4 ++-- tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php | 4 ++-- tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php | 4 ++-- tests/Unit/Scalar/StrTest.php | 4 ++-- tests/Unit/Traits/Entities/GeneralTraitsVO.php | 4 ++-- tests/Unit/Traits/Entities/GeneralTraitsVOTest.php | 4 ++-- tests/Unit/Traits/Entities/LocationTraitsVO.php | 4 ++-- tests/Unit/Traits/Entities/LocationTraitsVOTest.php | 4 ++-- tests/Unit/Traits/Entities/PersonalTraitsVO.php | 4 ++-- tests/Unit/Traits/Entities/PersonalTraitsVOTest.php | 4 ++-- tests/Unit/ValueObjects/AbstractValueObjectTest.php | 4 ++-- tests/Unit/ValueObjects/TestingNestedValueObject.php | 4 ++-- tests/Unit/ValueObjects/TestingValueObject.php | 4 ++-- tests/Unit/Web/EmailAddressTest.php | 4 ++-- tests/bootstrap.php | 4 ++-- 15 files changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/Unit/Exceptions/CoreExceptionsTest.php b/tests/Unit/Exceptions/CoreExceptionsTest.php index cd192b5..7d76870 100644 --- a/tests/Unit/Exceptions/CoreExceptionsTest.php +++ b/tests/Unit/Exceptions/CoreExceptionsTest.php @@ -24,8 +24,8 @@ /** * Unit testing for all base Exception's classes. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class CoreExceptionsTest extends AbstractBaseTestCase diff --git a/tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php b/tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php index 4ded76f..ca8f416 100644 --- a/tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php +++ b/tests/Unit/Exceptions/Datatypes/DatatypeExceptionsTest.php @@ -16,8 +16,8 @@ /** * Unit testing for all Datatype base Exception's classes. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class DatatypeExceptionsTest extends AbstractBaseTestCase diff --git a/tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php b/tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php index df4ae91..f05c475 100644 --- a/tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php +++ b/tests/Unit/Exceptions/Entities/EntitiesExceptionsTest.php @@ -11,8 +11,8 @@ /** * Unit testing for all Entity's base Exception classes. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class EntitiesExceptionsTest extends AbstractBaseTestCase diff --git a/tests/Unit/Scalar/StrTest.php b/tests/Unit/Scalar/StrTest.php index 3396faf..0d7cc11 100644 --- a/tests/Unit/Scalar/StrTest.php +++ b/tests/Unit/Scalar/StrTest.php @@ -13,8 +13,8 @@ /** * String's Scalar Native/Primitive Object Unit testing. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class StrTest extends AbstractBaseTestCase diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVO.php b/tests/Unit/Traits/Entities/GeneralTraitsVO.php index fd51338..8a96b27 100644 --- a/tests/Unit/Traits/Entities/GeneralTraitsVO.php +++ b/tests/Unit/Traits/Entities/GeneralTraitsVO.php @@ -27,8 +27,8 @@ /** * Testing Value Object for General Entity Traits. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class GeneralTraitsVO extends AbstractValueObject diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php index b420813..689b8da 100644 --- a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php @@ -13,8 +13,8 @@ /** * Testing Value Object for General Entity Traits. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class GeneralTraitsVOTest extends AbstractBaseTestCase diff --git a/tests/Unit/Traits/Entities/LocationTraitsVO.php b/tests/Unit/Traits/Entities/LocationTraitsVO.php index c04b4b0..a7ad917 100644 --- a/tests/Unit/Traits/Entities/LocationTraitsVO.php +++ b/tests/Unit/Traits/Entities/LocationTraitsVO.php @@ -22,8 +22,8 @@ /** * Testing Value Object for Location Entity Traits. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class LocationTraitsVO extends AbstractValueObject diff --git a/tests/Unit/Traits/Entities/LocationTraitsVOTest.php b/tests/Unit/Traits/Entities/LocationTraitsVOTest.php index b12d281..dc3506b 100644 --- a/tests/Unit/Traits/Entities/LocationTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/LocationTraitsVOTest.php @@ -23,8 +23,8 @@ /** * Testing Value Object for Location Entity Traits. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class LocationTraitsVOTest extends AbstractBaseTestCase diff --git a/tests/Unit/Traits/Entities/PersonalTraitsVO.php b/tests/Unit/Traits/Entities/PersonalTraitsVO.php index d1c50a9..aebb4d4 100644 --- a/tests/Unit/Traits/Entities/PersonalTraitsVO.php +++ b/tests/Unit/Traits/Entities/PersonalTraitsVO.php @@ -15,8 +15,8 @@ /** * Testing Value Object for Personal Entity Traits. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class PersonalTraitsVO extends AbstractValueObject diff --git a/tests/Unit/Traits/Entities/PersonalTraitsVOTest.php b/tests/Unit/Traits/Entities/PersonalTraitsVOTest.php index 479a78a..6031ae6 100644 --- a/tests/Unit/Traits/Entities/PersonalTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/PersonalTraitsVOTest.php @@ -16,8 +16,8 @@ /** * Testing Value Object for Personal Entity Traits. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class PersonalTraitsVOTest extends AbstractBaseTestCase diff --git a/tests/Unit/ValueObjects/AbstractValueObjectTest.php b/tests/Unit/ValueObjects/AbstractValueObjectTest.php index 2d7302a..34a1514 100644 --- a/tests/Unit/ValueObjects/AbstractValueObjectTest.php +++ b/tests/Unit/ValueObjects/AbstractValueObjectTest.php @@ -14,8 +14,8 @@ /** * Abstract Value Object Unit testing. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class AbstractValueObjectTest extends AbstractBaseTestCase diff --git a/tests/Unit/ValueObjects/TestingNestedValueObject.php b/tests/Unit/ValueObjects/TestingNestedValueObject.php index 9a0ec23..75fd247 100644 --- a/tests/Unit/ValueObjects/TestingNestedValueObject.php +++ b/tests/Unit/ValueObjects/TestingNestedValueObject.php @@ -18,8 +18,8 @@ /** * Nested Value Object for testing. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class TestingNestedValueObject extends AbstractValueObject diff --git a/tests/Unit/ValueObjects/TestingValueObject.php b/tests/Unit/ValueObjects/TestingValueObject.php index ceab2a8..c6cc001 100644 --- a/tests/Unit/ValueObjects/TestingValueObject.php +++ b/tests/Unit/ValueObjects/TestingValueObject.php @@ -18,8 +18,8 @@ /** * Abstract Base Value Object for testing. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class TestingValueObject extends AbstractValueObject diff --git a/tests/Unit/Web/EmailAddressTest.php b/tests/Unit/Web/EmailAddressTest.php index 0cb7c71..4916f60 100644 --- a/tests/Unit/Web/EmailAddressTest.php +++ b/tests/Unit/Web/EmailAddressTest.php @@ -10,8 +10,8 @@ /** * Email Address Unit testing. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ class EmailAddressTest extends AbstractBaseTestCase diff --git a/tests/bootstrap.php b/tests/bootstrap.php index bc6dee6..9155980 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -4,8 +4,8 @@ * * For Unit testing only, please link PHPUnit to this file. This file will autoload Composer's dependencies. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ From 14fec85ffc3918790fad35f0807b3925ef002b13 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 16:09:39 +0000 Subject: [PATCH 156/193] refactor: remove unnused references --- tests/Unit/Traits/Entities/PersonalTraitsVOTest.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/Unit/Traits/Entities/PersonalTraitsVOTest.php b/tests/Unit/Traits/Entities/PersonalTraitsVOTest.php index 6031ae6..c848c6c 100644 --- a/tests/Unit/Traits/Entities/PersonalTraitsVOTest.php +++ b/tests/Unit/Traits/Entities/PersonalTraitsVOTest.php @@ -5,12 +5,6 @@ namespace HraDigital\Tests\Datatypes\Unit\Traits\Entities; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; -use HraDigital\Datatypes\Traits\Entities\Personal\HasCountryOfBirthTrait; -use HraDigital\Datatypes\Traits\Entities\Personal\HasDateOfBirthTrait; -use HraDigital\Datatypes\Traits\Entities\Personal\HasGenderTrait; -use HraDigital\Datatypes\Traits\Entities\Personal\HasNationalityTrait; -use HraDigital\Datatypes\Traits\Entities\Personal\HasPhotoTrait; -use HraDigital\Datatypes\ValueObjects\AbstractValueObject; use HraDigital\Tests\Datatypes\AbstractBaseTestCase; /** From 1d46c343182608c82b874944ef5202432b0f8316 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 16:14:21 +0000 Subject: [PATCH 157/193] tests: add tests for Professional Traits --- .../Traits/Entities/ProfessionalTraitsVO.php | 22 ++++++++ .../Entities/ProfessionalTraitsVOTest.php | 52 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/Unit/Traits/Entities/ProfessionalTraitsVO.php create mode 100644 tests/Unit/Traits/Entities/ProfessionalTraitsVOTest.php diff --git a/tests/Unit/Traits/Entities/ProfessionalTraitsVO.php b/tests/Unit/Traits/Entities/ProfessionalTraitsVO.php new file mode 100644 index 0000000..e83e645 --- /dev/null +++ b/tests/Unit/Traits/Entities/ProfessionalTraitsVO.php @@ -0,0 +1,22 @@ + 'Information Technology', + 'occupation' => 'Developer', + ]; + + public function testLoadsSuccessfully(): void + { + $object = new ProfessionalTraitsVO(self::DATA); + + $this->assertEquals(self::DATA['industry'], (string) $object->getIndustry()); + $this->assertEquals(self::DATA['occupation'], (string) $object->getOccupation()); + $this->assertTrue($object->hasOccupation()); + } + + public function testBreaksWithEmptyIndustry(): void + { + $data = self::DATA; + $data['industry'] = ' '; + + $this->expectException(NonEmptyStringException::class); + + new ProfessionalTraitsVO($data); + } + + public function testBreaksWithEmptyOccupation(): void + { + $data = self::DATA; + $data['occupation'] = ' '; + + $this->expectException(NonEmptyStringException::class); + + new ProfessionalTraitsVO($data); + } +} From 71b14adec4ae4f56458e108d2396b5d4b3face7a Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 16:21:35 +0000 Subject: [PATCH 158/193] tests: add coverage for SocialMedia Traits --- .../Traits/Entities/SocialMediaTraitsVO.php | 26 ++++++++++ .../Entities/SocialMediaTraitsVOTest.php | 52 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/Unit/Traits/Entities/SocialMediaTraitsVO.php create mode 100644 tests/Unit/Traits/Entities/SocialMediaTraitsVOTest.php diff --git a/tests/Unit/Traits/Entities/SocialMediaTraitsVO.php b/tests/Unit/Traits/Entities/SocialMediaTraitsVO.php new file mode 100644 index 0000000..79cc301 --- /dev/null +++ b/tests/Unit/Traits/Entities/SocialMediaTraitsVO.php @@ -0,0 +1,26 @@ + 'https://facebook.com/aoihfoiahf', + 'instagram' => 'https://instagram.com/aoihfoiahf', + 'linkedin' => 'https://linkedin.com/aoihfoiahf', + 'twitter' => 'https://twitter.com/aoihfoiahf', + ]; + + public function testLoadsSuccessfully(): void + { + $object = new SocialMediaTraitsVO(self::DATA); + + $this->assertEquals(self::DATA['facebook'], (string) $object->getFacebookUrl()); + $this->assertEquals(self::DATA['instagram'], (string) $object->getInstagramUrl()); + $this->assertEquals(self::DATA['linkedin'], (string) $object->getLinkedinUrl()); + $this->assertEquals(self::DATA['twitter'], (string) $object->getTwitterUrl()); + $this->assertTrue($object->hasFacebookProfileUrl()); + $this->assertTrue($object->hasInstagramProfileUrl()); + $this->assertTrue($object->hasLinkedinProfileUrl()); + $this->assertTrue($object->hasTwitterProfileUrl()); + } + + public function testLoadsSuccessfullyWithNoValues(): void + { + $object = new SocialMediaTraitsVO([]); + + $this->assertNull($object->getFacebookUrl()); + $this->assertNull($object->getInstagramUrl()); + $this->assertNull($object->getLinkedinUrl()); + $this->assertNull($object->getTwitterUrl()); + $this->assertFalse($object->hasFacebookProfileUrl()); + $this->assertFalse($object->hasInstagramProfileUrl()); + $this->assertFalse($object->hasLinkedinProfileUrl()); + $this->assertFalse($object->hasTwitterProfileUrl()); + } +} From 987a3c297fb9176f192eee2a3272a67953bf4df9 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 16:25:15 +0000 Subject: [PATCH 159/193] docs: fix typo in docblocks --- tests/AbstractBaseTestCase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/AbstractBaseTestCase.php b/tests/AbstractBaseTestCase.php index ce7450a..b1fef2c 100644 --- a/tests/AbstractBaseTestCase.php +++ b/tests/AbstractBaseTestCase.php @@ -12,8 +12,8 @@ * All tests should extend from this base class. * All shared testing functionality and/or configuration should be added to this file. * - * @package Hradigital\Datatypes - * @copyright Hradigital\Datatypes + * @package HraDigital\Datatypes + * @copyright HraDigital\Datatypes * @license MIT */ abstract class AbstractBaseTestCase extends TestCase From feba44c11c7ba655b78ebf78f133871ec2683e91 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 16:25:48 +0000 Subject: [PATCH 160/193] tests: add Timezone related tests for Traits --- .../Unit/Traits/Entities/TimezoneTraitsVO.php | 20 +++++++++++++ .../Traits/Entities/TimezoneTraitsVOTest.php | 28 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/Unit/Traits/Entities/TimezoneTraitsVO.php create mode 100644 tests/Unit/Traits/Entities/TimezoneTraitsVOTest.php diff --git a/tests/Unit/Traits/Entities/TimezoneTraitsVO.php b/tests/Unit/Traits/Entities/TimezoneTraitsVO.php new file mode 100644 index 0000000..34985f5 --- /dev/null +++ b/tests/Unit/Traits/Entities/TimezoneTraitsVO.php @@ -0,0 +1,20 @@ + 123456789, + ]; + + public function testLoadsSuccessfully(): void + { + $object = new TimezoneTraitsVO(self::DATA); + + $this->assertEquals(self::DATA['timestamp'], (string) $object->getTimestamp()); + } +} From 6a529bd0d17a96cd771d21652a18715fdea98442 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 17:57:53 +0000 Subject: [PATCH 161/193] refactor: improve capacity related functionality --- src/Collections/Linear/AbstractListArray.php | 49 ++++++++++++-------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/Collections/Linear/AbstractListArray.php b/src/Collections/Linear/AbstractListArray.php index 4b44283..0041881 100644 --- a/src/Collections/Linear/AbstractListArray.php +++ b/src/Collections/Linear/AbstractListArray.php @@ -4,6 +4,9 @@ namespace HraDigital\Datatypes\Collections\Linear; +use HraDigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; +use HraDigital\Datatypes\Exceptions\Datatypes\PositiveIntegerException; + /** * List Abstract Linear Collection. * @@ -39,8 +42,8 @@ abstract class AbstractListArray implements \Countable, \JsonSerializable /** @var array $list - Holds the List's Elements. */ protected array $list = []; - /** @var int $capacity - Holds the maximum capacity for the List. -1 means "no limit". */ - protected int $capacity = -1; + /** @var int|NULL $capacity - Holds the maximum capacity for the List. NULL means "no limit". */ + protected ?int $capacity = null; /** * Returns the value count from the List. @@ -55,7 +58,7 @@ public function count(): int /** * Returns the array List of values. * - * @return array + * @return array|Str[] */ public function toArray(): array { @@ -87,43 +90,49 @@ public function isEmpty(): bool * * If the capacity is set to -1, it means the List has no capacity limit. * - * @return int + * @return int|NULL */ - public function capacity(): int + public function getCapacity(): ?int { return $this->capacity; } + /** + * If List has a Maximum Capacity set. + * + * @return boolean + */ + public function hasMaxCapacity(): bool + { + return ($this->capacity !== null); + } + /** * Allocates a capacity limit to the List. * - * @param int $capacity - Capacity limit to set in the List. + * @param int|NULL $capacity - Capacity limit to set in the List. If NULL, no capacity will be set. * - * @throws \InvalidArgumentException - If provided capacity is not a positive integer. - * @throws \OutOfRangeException - The the supplied capacity is less than the current List's value count. + * @throws PositiveIntegerException - If provided capacity is not a positive integer. + * @throws ParameterOutOfRangeException - The the supplied capacity is less than the current List's value count. * @return void */ - public function allocate(int $capacity): void + public function allocateCapacity(?int $capacity): void { // Validates provided parameter. - if ($capacity < 1) { - throw new \InvalidArgumentException("Supplied capacity must be a positive integer."); + if ($capacity !== null && $capacity < 1) { + throw PositiveIntegerException::withName('$capacity'); } - if ($capacity < $this->count()) { - throw new \OutOfRangeException("Supplied capacity cannot be less than the current list's capacity."); + if ($capacity !== null && $capacity < $this->count()) { + throw ParameterOutOfRangeException::withName('$capacity'); } // Sets the capacity in the List. $this->capacity = $capacity; } - /** - * Serializes the List into a JSON string. - * - * @return string - */ - public function jsonSerialize(): string + /** @inheritDoc */ + public function jsonSerialize(): array { - return \json_encode($this->list); + return $this->toArray(); } } From b8b510dccd1b427e5fb68cedebe9542c331fd03a Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 17:58:53 +0000 Subject: [PATCH 162/193] refactor: improve data handling in class --- src/Collections/Associative/Store.php | 47 +++++++++++++++++---------- src/Collections/Linear/Queue.php | 36 ++++++++------------ src/Collections/Linear/Stack.php | 41 ++++++++++------------- 3 files changed, 60 insertions(+), 64 deletions(-) diff --git a/src/Collections/Associative/Store.php b/src/Collections/Associative/Store.php index 5bd2aa1..176614d 100644 --- a/src/Collections/Associative/Store.php +++ b/src/Collections/Associative/Store.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Collections\Associative; +use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; + /** * Store Associative Collection. * @@ -40,20 +42,30 @@ class Store implements \JsonSerializable * * @param string|NULL $context - Value's context. Can be used as an inner store. * - * @throws \InvalidArgumentException - If supplied context is a not a non empty string. + * @throws NonEmptyStringException - If supplied context is a not a non empty string. * @return void */ public function __construct(?string $context = null) { // Validates provided parameters. if ($context !== null && \strlen(\trim($context)) === 0) { - throw new \InvalidArgumentException('Supplied context must be a non empty string.'); + throw NonEmptyStringException::withName('$context'); } // Sets the data context. $this->context = $context; } + /** + * Returns number of items in the Store. + * + * @return int + */ + public function count(): int + { + return \count($this->store); + } + /** * Retrieves all existing Values from the Store. * @@ -111,18 +123,16 @@ public function has(string $name): bool * @param string $name - Name of the Value to be set. * @param string $value - Value to be set. * - * @throws \InvalidArgumentException - If supplied name is a not a non empty string. - * @return bool + * @throws NonEmptyStringException - If supplied name is a not a non empty string. + * @return void */ - public function set(string $name, string $value): bool + public function set(string $name, string $value): void { // Sanitize provided $name/key. $name = $this->sanitizeName($name); // Sets the value in the store. $this->store[$this->name($name)] = $value; - - return true; } /** @@ -131,7 +141,7 @@ public function set(string $name, string $value): bool * @param string $name - Name of the Value to be added. * @param string $value - Value to be added. * - * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @throws NonEmptyStringException - If supplied name is a not a non empty string. * @return bool */ public function add(string $name, string $value): bool @@ -145,7 +155,9 @@ public function add(string $name, string $value): bool } // Sets the value in the store. - return $this->set($name, $value); + $this->set($name, $value); + + return true; } /** @@ -154,7 +166,7 @@ public function add(string $name, string $value): bool * @param string $name - Name of the Value to be edited. * @param string $value - Value to be edited. * - * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @throws NonEmptyStringException - If supplied name is a not a non empty string. * @return bool */ public function edit(string $name, string $value): bool @@ -168,7 +180,9 @@ public function edit(string $name, string $value): bool } // Sets the value in the store. - return $this->set($name, $value); + $this->set($name, $value); + + return true; } /** @@ -176,7 +190,7 @@ public function edit(string $name, string $value): bool * * @param string $name - Name of the value to be removed from the store. * - * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @throws NonEmptyStringException - If supplied name is a not a non empty string. * @return bool */ public function delete(string $name): bool @@ -200,14 +214,14 @@ public function delete(string $name): bool * * @param string $name - Name to be sanitized. * - * @throws \InvalidArgumentException - If supplied name is a not a non empty string. + * @throws NonEmptyStringException - If supplied name is a not a non empty string. * @return string */ protected function sanitizeName(string $name): string { // Validates provided parameters. if (\strlen(\trim($name)) === 0) { - throw new \InvalidArgumentException('Supplied name must be a non empty string.'); + throw NonEmptyStringException::withName('$name'); } // Returns sanitized $name/key. @@ -231,10 +245,7 @@ protected function name(string $name): string } } - /** - * {@inheritDoc} - * @see \JsonSerializable::jsonSerialize() - */ + /** {@inheritDoc} */ public function jsonSerialize(): array { return $this->getValues(); diff --git a/src/Collections/Linear/Queue.php b/src/Collections/Linear/Queue.php index b505ac3..650024e 100644 --- a/src/Collections/Linear/Queue.php +++ b/src/Collections/Linear/Queue.php @@ -4,6 +4,9 @@ namespace HraDigital\Datatypes\Collections\Linear; +use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Scalar\Str; + /** * Queue linear Collection. * @@ -36,24 +39,13 @@ class Queue extends AbstractListArray /** * Initializes an instance of a Queue. * - * @param array|NULL $initial - Initial element list for the Queue. Can be NULL. - * - * @throws \InvalidArgumentException - If supplied array is empty, although not NULL. + * @param array $initial - Initial element list for the Queue. Defaults to empty array. * @return void */ - public function __construct(?array $initial = null) + public function __construct(array $initial = []) { - // Checks initially provided list of elements. - if ($initial !== null) { - // Validates supplied parameter. - if (\count($initial) === 0) { - throw new \InvalidArgumentException("Supplied array should be a list of string elements."); - } - - // Fills in the Queue. - foreach ($initial as $element) { - $this->push($element); - } + foreach ($initial as $element) { + $this->push($element); } } @@ -62,7 +54,7 @@ public function __construct(?array $initial = null) * * @return Queue */ - public function copy(): self + public function clone(): Queue { return new Queue($this->toArray()); } @@ -72,9 +64,9 @@ public function copy(): self * * If the Queue has no elements, it will return NULL. * - * @return string|NULL + * @return Str|NULL */ - public function peek(): ?string + public function peek(): ?Str { // Validates the Queue has elements. if ($this->count() === 0) { @@ -89,9 +81,9 @@ public function peek(): ?string * * If the Queue has no elements, it will return NULL. * - * @return string|NULL + * @return Str|NULL */ - public function pop(): ?string + public function pop(): ?Str { return \array_shift($this->list); } @@ -108,10 +100,10 @@ public function push(string $element): void { // Validates provided parameter. if (\strlen(\trim($element)) === 0) { - throw new \InvalidArgumentException("Supplied element must be a non empty string."); + throw NonEmptyStringException::withName('$element'); } // Adds element to the Queue. - $this->list[] = $element; + $this->list[] = Str::create($element); } } diff --git a/src/Collections/Linear/Stack.php b/src/Collections/Linear/Stack.php index a5644a2..d6ddf0d 100644 --- a/src/Collections/Linear/Stack.php +++ b/src/Collections/Linear/Stack.php @@ -4,6 +4,10 @@ namespace HraDigital\Datatypes\Collections\Linear; +use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; +use HraDigital\Datatypes\Scalar\Str; + /** * Stack Linear Collection. * @@ -36,33 +40,22 @@ class Stack extends AbstractListArray /** * Initializes an instance of a Stack. * - * @param array|NULL $initial - Initial element list for the Stack. Can be NULL. - * - * @throws \InvalidArgumentException - If supplied array is empty, although not NULL. + * @param array $initial - Initial element list for the Stack. Defaults to empty array. * @return void */ - public function __construct(?array $initial = null) + public function __construct(array $initial = []) { - // Checks initially provided list of elements. - if ($initial !== null) { - // Validates supplied parameter. - if (\count($initial) === 0) { - throw new \InvalidArgumentException("Supplied array should be a list of string elements."); - } - - // Fills in the Stack. - foreach ($initial as $element) { - $this->push($element); - } + foreach ($initial as $element) { + $this->push($element); } } /** - * Returns a copy of the current Stack object. + * Returns a cloned copy of the current Stack object. * * @return Stack */ - public function copy(): self + public function clone(): Stack { return new Stack( $this->toArray() @@ -74,9 +67,9 @@ public function copy(): self * * If the Stack has no elements, it will return NULL. * - * @return string|NULL + * @return Str|NULL */ - public function peek(): ?string + public function peek(): ?Str { // Validates the Stack has elements. if ($this->count() === 0) { @@ -91,9 +84,9 @@ public function peek(): ?string * * If the Stack has no elements, it will return NULL. * - * @return string|NULL + * @return Str|NULL */ - public function pop(): ?string + public function pop(): ?Str { return \array_pop($this->list); } @@ -103,17 +96,17 @@ public function pop(): ?string * * @param string $element - Element to be added to the Stack. * - * @throws \InvalidArgumentException - If supplied element is not a non empty string. + * @throws NonEmptyStringException - If supplied element is not a non empty string. * @return void */ public function push(string $element): void { // Validates provided parameter. if (\strlen(\trim($element)) === 0) { - throw new \InvalidArgumentException("Supplied element must be a non empty string."); + throw NonEmptyStringException::withName('$element'); } // Adds element to the Stack. - $this->list[] = $element; + $this->list[] = Str::create($element); } } From 7747bdda26cbf567739895575fad757edb6c93b6 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 18:47:18 +0000 Subject: [PATCH 163/193] feat: add allocated capacity functionality --- src/Collections/Linear/Queue.php | 10 +++++++--- src/Collections/Linear/Stack.php | 7 +++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Collections/Linear/Queue.php b/src/Collections/Linear/Queue.php index 650024e..b43ca59 100644 --- a/src/Collections/Linear/Queue.php +++ b/src/Collections/Linear/Queue.php @@ -5,6 +5,7 @@ namespace HraDigital\Datatypes\Collections\Linear; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; +use HraDigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; use HraDigital\Datatypes\Scalar\Str; /** @@ -93,17 +94,20 @@ public function pop(): ?Str * * @param string $element - Element to be added to the Queue. * - * @throws \InvalidArgumentException - If supplied element is not a non empty string. + * @throws NonEmptyStringException - If supplied element is not a non empty string. + * @throws ParameterOutOfRangeException - If adding element will exceed list's capacity. * @return void */ public function push(string $element): void { - // Validates provided parameter. if (\strlen(\trim($element)) === 0) { throw NonEmptyStringException::withName('$element'); } - // Adds element to the Queue. + if ($this->hasMaxCapacity() && $this->getCapacity() === $this->count()) { + throw new ParameterOutOfRangeException(); + } + $this->list[] = Str::create($element); } } diff --git a/src/Collections/Linear/Stack.php b/src/Collections/Linear/Stack.php index d6ddf0d..13b8c21 100644 --- a/src/Collections/Linear/Stack.php +++ b/src/Collections/Linear/Stack.php @@ -97,16 +97,19 @@ public function pop(): ?Str * @param string $element - Element to be added to the Stack. * * @throws NonEmptyStringException - If supplied element is not a non empty string. + * @throws ParameterOutOfRangeException - If adding element will exceed list's capacity. * @return void */ public function push(string $element): void { - // Validates provided parameter. if (\strlen(\trim($element)) === 0) { throw NonEmptyStringException::withName('$element'); } - // Adds element to the Stack. + if ($this->hasMaxCapacity() && $this->getCapacity() === $this->count()) { + throw new ParameterOutOfRangeException(); + } + $this->list[] = Str::create($element); } } From e235b52f35c20402ac258ae6bf6765dadf542bb7 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 18:47:37 +0000 Subject: [PATCH 164/193] tests: increase test coverage --- .../Collections/Associative/StoreTest.php | 134 ++++++++++++++++++ tests/Unit/Collections/Linear/QueueTest.php | 126 ++++++++++++++++ tests/Unit/Collections/Linear/StackTest.php | 126 ++++++++++++++++ 3 files changed, 386 insertions(+) create mode 100644 tests/Unit/Collections/Associative/StoreTest.php create mode 100644 tests/Unit/Collections/Linear/QueueTest.php create mode 100644 tests/Unit/Collections/Linear/StackTest.php diff --git a/tests/Unit/Collections/Associative/StoreTest.php b/tests/Unit/Collections/Associative/StoreTest.php new file mode 100644 index 0000000..f9b3f7c --- /dev/null +++ b/tests/Unit/Collections/Associative/StoreTest.php @@ -0,0 +1,134 @@ +assertEquals(0, $store->count()); + } + + public function testCanSetAndGetValues(): void + { + $key = 'testKey'; + $value = 'TestValue'; + + $store = new Store(); + + // Tries aditing a value before setting it. + $editedBefore = $store->edit($key, 'New Value'); + $this->assertEquals(0, $store->count()); + $this->assertCount(0, $store->jsonSerialize()); + $this->assertFalse($editedBefore); + + // Sets value directly. + $store->set($key, $value); + $this->assertTrue($store->has($key)); + $this->assertEquals($value, $store->get($key)); + $this->assertEquals(1, $store->count()); + + // Now edits existing value. + $edited = $store->edit($key, 'New Value'); + $this->assertNotEquals($value, $store->get($key)); + $this->assertTrue($edited); + + // Unsuccessfully tries adding a value as a new. + $addedAfter = $store->add($key, 'Tries adding new Value to existing key'); + $this->assertFalse($addedAfter); + $this->assertEquals(1, $store->count()); + + // Forces/overrides setting value. + $store->set($key, $value); + $this->assertEquals($value, $store->get($key)); + $this->assertEquals(1, $store->count()); + $this->assertCount(1, $store->jsonSerialize()); + } + + public function testAddingValueAndThenDeletingIt(): void + { + $key = 'testKey'; + $value = 'TestValue'; + + $store = new Store('Context'); + $deletedBefore = $store->delete($key); + $this->assertFalse($deletedBefore); + $this->assertEquals(0, $store->count()); + $this->assertEquals('Unexisting', $store->get($key, 'Unexisting')); + + // First adds a new value to the Store. + $added = $store->add($key, $value); + $this->assertTrue($added); + $this->assertTrue($store->has($key)); + $this->assertEquals($value, $store->get($key, 'Unexisting')); + $this->assertEquals(1, $store->count()); + + // Now deletes the same value. + $deletedAfter = $store->delete($key); + $this->assertTrue($deletedAfter); + $this->assertFalse($store->has($key)); + $this->assertEquals(0, $store->count()); + } + + public function testBreaksIfContextIsEmpty(): void + { + $this->expectException(NonEmptyStringException::class); + + new Store(''); + } + + public function testBreaksIfTryingToSetEmptyKey(): void + { + $this->expectException(NonEmptyStringException::class); + + $store = new Store('Context'); + $store->set('', ''); + } + + public function testBreaksIfTryingToGetEmptyKey(): void + { + $this->expectException(NonEmptyStringException::class); + + $store = new Store('Context'); + $store->get(''); + } + + public function testBreaksIfTryingToAddEmptyKey(): void + { + $this->expectException(NonEmptyStringException::class); + + $store = new Store('Context'); + $store->add('', ''); + } + + public function testBreaksIfTryingToEditEmptyKey(): void + { + $this->expectException(NonEmptyStringException::class); + + $store = new Store('Context'); + $store->edit('', ''); + } + + public function testBreaksIfTryingToDeleteEmptyKey(): void + { + $this->expectException(NonEmptyStringException::class); + + $store = new Store('Context'); + $store->delete(''); + } +} diff --git a/tests/Unit/Collections/Linear/QueueTest.php b/tests/Unit/Collections/Linear/QueueTest.php new file mode 100644 index 0000000..e31bc43 --- /dev/null +++ b/tests/Unit/Collections/Linear/QueueTest.php @@ -0,0 +1,126 @@ +clone(); + + $this->assertEquals(0, $queue->count()); + $this->assertTrue($queue->isEmpty()); + + $this->assertEquals(0, $newQueue->count()); + $this->assertTrue($newQueue->isEmpty()); + + $this->assertFalse($queue === $newQueue); + $this->assertNull($queue->peek()); + $this->assertNull($queue->pop()); + $this->assertNull($queue->getCapacity()); + $this->assertFalse($queue->hasMaxCapacity()); + } + + public function testCanPushPeekAndPopElements(): void + { + $element1 = 'element1'; + $element2 = 'element2'; + $element3 = 'element3'; + + $queue = new Queue([ + $element1, + $element2, + ]); + + $this->assertEquals(2, $queue->count()); + $this->assertEquals($element1, (string) $queue->peek()); + $this->assertFalse($queue->isEmpty()); + + $queue->push($element3); + $this->assertEquals(3, $queue->count()); + $this->assertEquals($element1, (string) $queue->peek()); + + $popElement1 = $queue->pop(); + $this->assertEquals($element1, (string) $popElement1); + $popElement2 = $queue->pop(); + $this->assertEquals($element2, (string) $popElement2); + $this->assertEquals(1, $queue->count()); + $this->assertCount(1, $queue->jsonSerialize()); + } + + public function testBreaksIfEmptyStringIsPushed(): void + { + $this->expectException(NonEmptyStringException::class); + + $queue = new Queue(); + $queue->push(''); + } + + public function testCanClearQueue(): void + { + $queue = new Queue([ + 'element1', + 'element2', + 'element3', + ]); + + $this->assertEquals(3, $queue->count()); + $queue->clear(); + $this->assertEquals(0, $queue->count()); + } + + public function testAllocatedCapacityBehavior(): void + { + $queue = new Queue(); + $this->assertEquals(0, $queue->count()); + $this->assertNull($queue->getCapacity()); + $this->assertFalse($queue->hasMaxCapacity()); + + $queue->allocateCapacity(2); + $this->assertTrue($queue->hasMaxCapacity()); + $this->assertEquals(0, $queue->count()); + $this->assertEquals(2, $queue->getCapacity()); + + $this->expectException(ParameterOutOfRangeException::class); + + $queue->push('element1'); + $queue->push('element2'); + $queue->push('element3'); + } + + public function testBreaksIfAllocatedCapacityIsNotPositive(): void + { + $this->expectException(PositiveIntegerException::class); + + $queue = new Queue(); + $queue->allocateCapacity(-1); + } + + public function testBreaksIfAllocatedCapacityIsLessThenCount(): void + { + $this->expectException(ParameterOutOfRangeException::class); + + $queue = new Queue(); + $queue->push('element1'); + $queue->push('element2'); + $queue->push('element3'); + + $queue->allocateCapacity(2); + } +} diff --git a/tests/Unit/Collections/Linear/StackTest.php b/tests/Unit/Collections/Linear/StackTest.php new file mode 100644 index 0000000..8d939dd --- /dev/null +++ b/tests/Unit/Collections/Linear/StackTest.php @@ -0,0 +1,126 @@ +clone(); + + $this->assertEquals(0, $stack->count()); + $this->assertTrue($stack->isEmpty()); + + $this->assertEquals(0, $newStack->count()); + $this->assertTrue($newStack->isEmpty()); + + $this->assertFalse($stack === $newStack); + $this->assertNull($stack->peek()); + $this->assertNull($stack->pop()); + $this->assertNull($stack->getCapacity()); + $this->assertFalse($stack->hasMaxCapacity()); + } + + public function testCanPushPeekAndPopElements(): void + { + $element1 = 'element1'; + $element2 = 'element2'; + $element3 = 'element3'; + + $stack = new Stack([ + $element1, + $element2, + ]); + + $this->assertEquals(2, $stack->count()); + $this->assertEquals($element2, (string) $stack->peek()); + $this->assertFalse($stack->isEmpty()); + + $stack->push($element3); + $this->assertEquals(3, $stack->count()); + $this->assertEquals($element3, (string) $stack->peek()); + + $popElement3 = $stack->pop(); + $this->assertEquals($element3, (string) $popElement3); + $popElement2 = $stack->pop(); + $this->assertEquals($element2, (string) $popElement2); + $this->assertEquals(1, $stack->count()); + $this->assertCount(1, $stack->jsonSerialize()); + } + + public function testBreaksIfEmptyStringIsPushed(): void + { + $this->expectException(NonEmptyStringException::class); + + $stack = new Stack(); + $stack->push(''); + } + + public function testCanClearStack(): void + { + $stack = new Stack([ + 'element1', + 'element2', + 'element3', + ]); + + $this->assertEquals(3, $stack->count()); + $stack->clear(); + $this->assertEquals(0, $stack->count()); + } + + public function testAllocatedCapacityBehavior(): void + { + $stack = new Stack(); + $this->assertEquals(0, $stack->count()); + $this->assertNull($stack->getCapacity()); + $this->assertFalse($stack->hasMaxCapacity()); + + $stack->allocateCapacity(2); + $this->assertTrue($stack->hasMaxCapacity()); + $this->assertEquals(0, $stack->count()); + $this->assertEquals(2, $stack->getCapacity()); + + $this->expectException(ParameterOutOfRangeException::class); + + $stack->push('element1'); + $stack->push('element2'); + $stack->push('element3'); + } + + public function testBreaksIfAllocatedCapacityIsNotPositive(): void + { + $this->expectException(PositiveIntegerException::class); + + $queue = new Stack(); + $queue->allocateCapacity(-1); + } + + public function testBreaksIfAllocatedCapacityIsLessThenCount(): void + { + $this->expectException(ParameterOutOfRangeException::class); + + $queue = new Stack(); + $queue->push('element1'); + $queue->push('element2'); + $queue->push('element3'); + + $queue->allocateCapacity(2); + } +} From e0a94101a2a23596aa717e241f8b4b6b5ea0ff07 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 18:49:49 +0000 Subject: [PATCH 165/193] refactor: improve internal if condition --- src/Collections/Associative/Store.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Collections/Associative/Store.php b/src/Collections/Associative/Store.php index 176614d..505faf1 100644 --- a/src/Collections/Associative/Store.php +++ b/src/Collections/Associative/Store.php @@ -240,9 +240,9 @@ protected function name(string $name): string // Returns sanitized $name/key. if ($this->context === null) { return $name; - } else { - return ($this->context . '.' . $name); } + + return ($this->context . '.' . $name); } /** {@inheritDoc} */ From dc9aee9b6946b12f8410fe8bc9f5fcd5270b1442 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 18:53:11 +0000 Subject: [PATCH 166/193] refactor: improve $key processing in key() method --- src/Collections/Linear/EntityCollection.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Collections/Linear/EntityCollection.php b/src/Collections/Linear/EntityCollection.php index 74725ac..f497646 100644 --- a/src/Collections/Linear/EntityCollection.php +++ b/src/Collections/Linear/EntityCollection.php @@ -208,12 +208,11 @@ public function key(): ?int // First, we'll collect the key. $key = \key($this->collection); - // Then, we'll uniform the returned value. - if ($key !== null && $key !== false) { - return ((int) $key); - } else { + if ($key === null || $key === false) { return null; } + + return (int) $key; } /** From ac7127eb7c60fcf43767fefc617a669976f0ace9 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 18:57:42 +0000 Subject: [PATCH 167/193] refactor: minor improvement on subString() --- src/Scalar/Str.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Scalar/Str.php b/src/Scalar/Str.php index 9ebbf24..10b5477 100644 --- a/src/Scalar/Str.php +++ b/src/Scalar/Str.php @@ -497,15 +497,8 @@ public function subString(int $start, int $length = null): self // Validates supplied $start and $length. $this->validateStartAndLength($start, $length); - // Processes the substring. - if ($length !== null) { - $value = \substr($this->value, $start, $length); - } else { - $value = \substr($this->value, $start); - } - return new self( - ($value ?? '') + (\substr($this->value, $start, $length) ?? '') ); } From 3411e84ab1c7eda46f2569b881187bfcc077b194 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 11 Mar 2022 19:07:16 +0000 Subject: [PATCH 168/193] refactor: fix subString() for PHP7.4 --- src/Scalar/Str.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Scalar/Str.php b/src/Scalar/Str.php index 10b5477..0ad891f 100644 --- a/src/Scalar/Str.php +++ b/src/Scalar/Str.php @@ -497,9 +497,11 @@ public function subString(int $start, int $length = null): self // Validates supplied $start and $length. $this->validateStartAndLength($start, $length); - return new self( - (\substr($this->value, $start, $length) ?? '') - ); + if ($length === null) { + return new self(\substr($this->value, $start) ?? ''); + } + + return new self(\substr($this->value, $start, $length) ?? ''); } /** From 6f9ac6b3f87b282add3c988db74b1f6a9c97b26c Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 16:38:37 +0000 Subject: [PATCH 169/193] refactor: remove redundant attribute --- src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php index e3ebe36..56c0b51 100644 --- a/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php +++ b/src/Traits/ValueObjects/CanProcessOnLoadEventsTrait.php @@ -20,9 +20,6 @@ trait CanProcessOnLoadEventsTrait /** Sets the onLoad Mutator method's prefix. */ private static $ONLOADPREFIX = 'onLoad'; - /** @var array $onLoadEvents - List of onLoad event handlers, defined as closures. */ - private array $onLoadEvents = []; - /** * Triggers all onLoad pre-declared events. * @@ -32,7 +29,8 @@ private function triggerOnLoad(): void { // Loops through all the class' methods, and loads the necessary ones in // the corresponding containers. - foreach (\get_class_methods($this) as $method) { + $allMethods = \get_class_methods($this); + foreach ($allMethods as $method) { if (\strpos($method, self::$ONLOADPREFIX) === 0 && \strlen($method) > \strlen(self::$ONLOADPREFIX)) { $this->$method(); } From b11d1de28886f07f2d9c61f44fecf417cae7068b Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 16:38:59 +0000 Subject: [PATCH 170/193] refactor: remove redundant attribute from filter --- src/ValueObjects/AbstractValueObject.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ValueObjects/AbstractValueObject.php b/src/ValueObjects/AbstractValueObject.php index 79ac7f8..911034d 100644 --- a/src/ValueObjects/AbstractValueObject.php +++ b/src/ValueObjects/AbstractValueObject.php @@ -115,8 +115,7 @@ private function filterSystemControlFields(array $attrs): array $attrs['required'], $attrs['ruleList'], $attrs['castList'], - $attrs['attributeList'], - $attrs['onLoadEvents'] + $attrs['attributeList'] ); return $attrs; From f7a38124f99643e093e6773c3f02c8ab86a181b6 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 16:39:30 +0000 Subject: [PATCH 171/193] feat: add new generic JSON serializing Trait --- .../CanSerializeAllToJsonTrait.php | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/Traits/ValueObjects/CanSerializeAllToJsonTrait.php diff --git a/src/Traits/ValueObjects/CanSerializeAllToJsonTrait.php b/src/Traits/ValueObjects/CanSerializeAllToJsonTrait.php new file mode 100644 index 0000000..e0dd708 --- /dev/null +++ b/src/Traits/ValueObjects/CanSerializeAllToJsonTrait.php @@ -0,0 +1,45 @@ + $value) { + // If the Attribute's value is json serializable itself, + // serialize and add it to the returning array. + // Otherwize, return its holding value. + if ($value instanceof \JsonSerializable) { + $json[$name] = $value->jsonSerialize(); + } elseif (\is_object($value) && \method_exists($value, '__toString')) { + $json[$name] = (string) $value; + } else { + $json[$name] = $value; + } + } + + return (object) $json; + } +} From 869d64ef640e4203446666477568f32393a93b71 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 19:32:35 +0000 Subject: [PATCH 172/193] BREAKING CHANGE: remove unnused PaginatedColleciton --- .../Linear/PaginatedCollection.php | 268 ------------------ 1 file changed, 268 deletions(-) delete mode 100644 src/Collections/Linear/PaginatedCollection.php diff --git a/src/Collections/Linear/PaginatedCollection.php b/src/Collections/Linear/PaginatedCollection.php deleted file mode 100644 index a28ffc2..0000000 --- a/src/Collections/Linear/PaginatedCollection.php +++ /dev/null @@ -1,268 +0,0 @@ -collection = $collection; - $this->sortInfo = $sortInfo; - - // Sets the counters. - $this->total = $total; - $this->perPage = $perPage; - - // Sets the Page information. - $this->currentPage = $currentPage; - $this->lastPage = $lastPage; - $this->firstId = $from; - $this->lastId = $to; - } - - /** - * Collection of items being paginated. - * - * Pagination counters will be calculated at start, and will remain immutable - * until the object is destroyed. - * - * Please note that, adding/removing elements to or from the Collection will - * not reflect on the Pagination counters being updated. - * - * @return EntityCollection - */ - public function collection(): EntityCollection - { - return $this->collection; - } - - /** - * Retrieves the sorting information for the Pagination. - * - * @return SortInfo - */ - public function sortInfo(): SortInfo - { - return $this->sortInfo; - } - - /** - * Number of the first record being displayed in the Paginated results. - * - * Please note that, the returned integer is not the record's ID. It represents - * the record's global displaying order if the the records weren't being paginated. - * - * @return int - */ - public function fromRecord(): int - { - return (($this->currentPage - 1) * $this->perPage); - } - - /** - * Number of the last record being displayed in the Paginated results. - * - * Please note that, the returned integer is not the record's ID. It represents - * the record's global displaying order if the the records weren't being paginated. - * - * @return int - */ - public function toRecord(): int - { - if ($this->collection->count() < $this->perPage) { - return ($this->fromRecord() + $this->collection->count()); - } else { - return ($this->fromRecord() + $this->perPage); - } - } - - /** - * Number of the first record's ID being displayed in the Paginated results. - * - * If the record Collection is empty, this will return NULL, as - * there isn't any first or last records. - * - * @return int|NULL - */ - public function firstId(): ?int - { - return $this->firstId; - } - - /** - * Number of the last record's ID being displayed in the Paginated results. - * - * If the record Collection is empty, this will return NULL, as - * there isn't any first or last records. - * - * @return int|NULL - */ - public function lastId(): ?int - { - return $this->lastId; - } - - /** - * Total number of records in source. - * - * Returns the total number of records from the source dataset, from which the pagination was produced. - * - * @return int - */ - public function totalRecords(): int - { - return $this->total; - } - - /** - * Total number of available records for Pagination. - * - * Returns the total number of records in the selected Page. - * - * @return int - */ - public function total(): int - { - return $this->collection->count(); - } - - /** - * Number of the current Page for the paginated records. - * - * @return int - */ - public function currentPage(): int - { - return $this->currentPage; - } - - /** - * Number of the calculated last Page for the paginated records. - * - * @return int - */ - public function lastPage(): int - { - return $this->lastPage; - } - - /** - * Number of records being displayed by Page. - * - * @return int - */ - public function perPage(): int - { - return $this->perPage; - } - - /** - * Returns an Array representation of the Paginated Collection's object. - * - * @return array - */ - public function toArray(): array - { - return [ - 'collection' => $this->collection, - 'sortinfo' => $this->sortInfo, - 'fromRecord' => $this->fromRecord(), - 'toRecord' => $this->toRecord(), - 'totalRecords' => $this->totalRecords(), - 'currentPage' => $this->currentPage(), - 'lastPage' => $this->lastPage(), - 'perPage' => $this->perPage(), - ]; - } - - /** - * Returns an array containing all its item's serialized data. - * - * Allows the Collection to be serialized directly by the json_encode() function. - * - * {@inheritDoc} - * @link http://www.php.net/manual/en/jsonserializable.jsonserialize.php - * @see \JsonSerializable::jsonSerialize() - */ - public function jsonSerialize(): array - { - return [ - 'collection' => $this->collection->jsonSerialize(), - 'sortinfo' => $this->sortInfo->jsonSerialize(), - 'fromRecord' => $this->fromRecord(), - 'toRecord' => $this->toRecord(), - 'totalRecords' => $this->totalRecords(), - 'currentPage' => $this->currentPage(), - 'lastPage' => $this->lastPage(), - 'perPage' => $this->perPage(), - ]; - } -} From 7e3c3342fc57457d7d4a01e2503919ac24eb72a5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 19:46:54 +0000 Subject: [PATCH 173/193] BREAKING CHANGE: Remove unnused classes --- src/ValueObjects/Timezone/Identifier.php | 15 ----- src/ValueObjects/Timezone/Location.php | 45 ------------- src/ValueObjects/Timezone/README.md | 1 - src/ValueObjects/Timezone/Transition.php | 86 ------------------------ 4 files changed, 147 deletions(-) delete mode 100644 src/ValueObjects/Timezone/Identifier.php delete mode 100644 src/ValueObjects/Timezone/Location.php delete mode 100755 src/ValueObjects/Timezone/README.md delete mode 100644 src/ValueObjects/Timezone/Transition.php diff --git a/src/ValueObjects/Timezone/Identifier.php b/src/ValueObjects/Timezone/Identifier.php deleted file mode 100644 index ed973d3..0000000 --- a/src/ValueObjects/Timezone/Identifier.php +++ /dev/null @@ -1,15 +0,0 @@ -comments = ($comments ? Str::create($comments) : null); - } - - public function comments(): ?Str - { - return $this->comments; - } -} diff --git a/src/ValueObjects/Timezone/README.md b/src/ValueObjects/Timezone/README.md deleted file mode 100755 index 9295305..0000000 --- a/src/ValueObjects/Timezone/README.md +++ /dev/null @@ -1 +0,0 @@ -# Timezone related Value Objects diff --git a/src/ValueObjects/Timezone/Transition.php b/src/ValueObjects/Timezone/Transition.php deleted file mode 100644 index 3f2dc56..0000000 --- a/src/ValueObjects/Timezone/Transition.php +++ /dev/null @@ -1,86 +0,0 @@ - 'timestamp', - 'time' => 'dateTime', - 'offSet' => 'offset', - 'isdst' => 'isDayLightSavingActive', - 'abbr' => 'abbreviation', - ]; - - protected function castDateTime(string $time): void - { - $this->dateTime = Datetime::fromString($time); - } - - protected function castOffset(int $offset): void - { - $this->offset = $offset; - } - - protected function castIsDayLightSavingActive(int $isActive): void - { - $this->isDayLightSavingActive = (bool) $isActive; - } - - protected function castAbbreviation(string $abbreviation): void - { - $this->abbreviation = Str::create($abbreviation); - } - - public function dateTime(): Datetime - { - return $this->dateTime; - } - - public function offset(): int - { - return $this->offset; - } - - public function isDayLightSavingActive(): bool - { - return $this->isDayLightSavingActive; - } - - public function abbreviation(): Str - { - return $this->abbreviation; - } -} From 2acc39fdbf47d7e64b60a58cc71ff11c16f4b3be Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 19:47:36 +0000 Subject: [PATCH 174/193] tests: add tests for CanSerializeAllToJsonTrait --- tests/Unit/ValueObjects/TestingAggregate.php | 34 ++++++++++++++ .../ValueObjects/TestingAggregateTest.php | 44 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/Unit/ValueObjects/TestingAggregate.php create mode 100644 tests/Unit/ValueObjects/TestingAggregateTest.php diff --git a/tests/Unit/ValueObjects/TestingAggregate.php b/tests/Unit/ValueObjects/TestingAggregate.php new file mode 100644 index 0000000..469c2ff --- /dev/null +++ b/tests/Unit/ValueObjects/TestingAggregate.php @@ -0,0 +1,34 @@ +string = $string; + $this->datetime = $datetime; + $this->vo = $vo; + $this->boolean = $boolean; + } +} diff --git a/tests/Unit/ValueObjects/TestingAggregateTest.php b/tests/Unit/ValueObjects/TestingAggregateTest.php new file mode 100644 index 0000000..c29ddbf --- /dev/null +++ b/tests/Unit/ValueObjects/TestingAggregateTest.php @@ -0,0 +1,44 @@ +assertIsArray($array); + $this->assertArrayHasKey('string', $array); + $this->assertArrayHasKey('datetime', $array); + $this->assertArrayHasKey('vo', $array); + $this->assertArrayHasKey('boolean', $array); + } +} From cb5e7557da6238b75c761d571e6e206d7f550bc0 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 19:49:13 +0000 Subject: [PATCH 175/193] feat: add toDateString() --- src/Datetime/Datetime.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Datetime/Datetime.php b/src/Datetime/Datetime.php index 0ce400e..4e3f668 100644 --- a/src/Datetime/Datetime.php +++ b/src/Datetime/Datetime.php @@ -429,6 +429,16 @@ public function toDatetimeString(): Str return $this->toFormatInternal('Y-m-d H:i:s'); } + /** + * Returns Str instance with value in format "Y-m-d". + * + * @return Str + */ + public function toDateString(): Str + { + return $this->toFormatInternal('Y-m-d'); + } + /** * Returns Str instance with value in format "H:i:s". * From 4af1b05c60416745af69c5b086db31c6435ac2e4 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 19:49:46 +0000 Subject: [PATCH 176/193] fix: improve factory methods and refactor class --- src/Datetime/DateInterval.php | 91 ++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/src/Datetime/DateInterval.php b/src/Datetime/DateInterval.php index 89e2221..525fd1a 100644 --- a/src/Datetime/DateInterval.php +++ b/src/Datetime/DateInterval.php @@ -4,6 +4,8 @@ namespace HraDigital\Datatypes\Datetime; +use DateInterval as ParentDateInterval; +use HraDigital\Datatypes\Exceptions\Datatypes\InvalidDateIntervalException; use HraDigital\Datatypes\Scalar\Str; /** @@ -15,9 +17,21 @@ * @link http://php.net/manual/en/timezones.php * @link https://timezonedb.com/download */ -class DateInterval +class DateInterval extends ParentDateInterval { - protected \DateInterval $interval; + public static function createFromDateString($datetime) + { + $result = parent::createFromDateString($datetime); + + if ($result === false) { + throw new InvalidDateIntervalException(); + } + + return DateInterval::fromDuration( + Str::create(self::toDurationInternal($result)), + (bool) $result->invert + ); + } public static function fromDuration(Str $duration, bool $inverted = false): DateInterval { @@ -51,7 +65,7 @@ public static function fromDays(int $days): DateInterval public static function fromHours(int $hours): DateInterval { return new DateInterval( - \sprintf("P%dH", \abs($hours)), + \sprintf("PT%dH", \abs($hours)), ($hours < 0) ); } @@ -59,7 +73,7 @@ public static function fromHours(int $hours): DateInterval public static function fromMinutes(int $minutes): DateInterval { return new DateInterval( - \sprintf("P%dI", \abs($minutes)), + \sprintf("PT%dM", \abs($minutes)), ($minutes < 0) ); } @@ -67,15 +81,16 @@ public static function fromMinutes(int $minutes): DateInterval public static function fromSeconds(int $seconds): DateInterval { return new DateInterval( - \sprintf("P%dS", \abs($seconds)), + \sprintf("PT%dS", \abs($seconds)), ($seconds < 0) ); } - protected function __construct(string $duration, bool $inverted = false) + public function __construct(string $duration, bool $inverted = false) { - $this->interval = new \DateInterval($duration); - $this->interval->invert = (int) $inverted; + parent::__construct($duration); + + $this->invert = (int) $inverted; } public function __toString(): string @@ -88,45 +103,45 @@ protected function invertValue(int $value, int $invert): int return $invert ? (0 - $value) : $value; } - public function inYears(): int + public function getYears(): int { - return $this->invertValue($this->interval->y, $this->interval->invert); + return $this->invertValue($this->y, $this->invert); } - public function inMonths(): int + public function getMonths(): int { - return $this->invertValue($this->interval->m, $this->interval->invert); + return $this->invertValue($this->m, $this->invert); } - public function inDays(): int + public function getDays(): int { - return $this->invertValue($this->interval->d, $this->interval->invert); + return $this->invertValue($this->d, $this->invert); } - public function inHours(): int + public function getHours(): int { - return $this->invertValue($this->interval->h, $this->interval->invert); + return $this->invertValue($this->h, $this->invert); } - public function inMinutes(): int + public function getMinutes(): int { - return $this->invertValue($this->interval->i, $this->interval->invert); + return $this->invertValue($this->i, $this->invert); } - public function inSeconds(): int + public function getSeconds(): int { - return $this->invertValue($this->interval->s, $this->interval->invert); + return $this->invertValue($this->s, $this->invert); } - public function inMicroSeconds(): float + public function getMicroSeconds(): float { - return $this->interval->invert ? (0 - $this->interval->f) : $this->interval->f; + return $this->invert ? (0 - $this->f) : $this->f; } protected function toFormatInternal(string $format): Str { return Str::create( - $this->interval->format($format) + $this->format($format) ); } @@ -137,7 +152,7 @@ protected function toFormatInternal(string $format): Str */ public function toDatetimeString(): Str { - return $this->toFormatInternal('Y-m-d H:i:s'); + return $this->toFormatInternal('%r%Yy %Mm %Dd %H:%I:%S'); } public function toFormat(Str $format): Str @@ -145,18 +160,28 @@ public function toFormat(Str $format): Str return $this->toFormatInternal((string) $format); } + protected static function toDurationInternal(ParentDateInterval $interval): string + { + return \sprintf( + 'P%dY%dM%dDT%dH%dM%dS', + $interval->y, + $interval->m, + $interval->d, + $interval->h, + $interval->i, + $interval->s + ); + } + public function toDuration(): Str { return Str::create( - \sprintf( - 'P%dY%dM%dDT%dH%dM%dS', - $this->interval->y, - $this->interval->m, - $this->interval->d, - $this->interval->h, - $this->interval->i, - $this->interval->s - ) + self::toDurationInternal($this) ); } + + public function isNegative(): bool + { + return (bool) $this->invert; + } } From 8b33bbaa10f0226ed3f4f5c25b7a645954dad840 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 19:54:35 +0000 Subject: [PATCH 177/193] BREAKING CHANGE: remove unnused class --- src/Datetime/Datetime.php | 482 -------------------------------------- 1 file changed, 482 deletions(-) delete mode 100644 src/Datetime/Datetime.php diff --git a/src/Datetime/Datetime.php b/src/Datetime/Datetime.php deleted file mode 100644 index 4e3f668..0000000 --- a/src/Datetime/Datetime.php +++ /dev/null @@ -1,482 +0,0 @@ -dateTime = new \DateTimeImmutable($datetime, $timezone); - } - - /** - * Magic method for instance printing. - * - * @return string - */ - public function __toString(): string - { - return (string) $this->toDatetimeString(); - } - - /** @inheritDoc */ - public function jsonSerialize(): string - { - return (string) $this; - } - - /** - * Returns the Timestamp of the Datetime instance. - * - * Number of seconds since the Unix Epoch. - * - * @return int - */ - public function getTimestamp(): int - { - return $this->dateTime->getTimestamp(); - } - - /** - * Returns the timezone's offset. - * - * @return int - */ - public function getOffset(): int - { - return $this->dateTime->getOffset(); - } - - /** - * Get Year part of the instance. - * - * @return int - */ - public function getYear(): int - { - return (int) ((string) $this->toFormat(Str::create('Y'))); - } - - /** - * Get Month part of the instance. - * - * @return int - */ - public function getMonth(): int - { - return (int) ((string) $this->toFormat(Str::create('m'))); - } - - /** - * Get Day part of the instance. - * - * @return int - */ - public function getDay(): int - { - return (int) ((string) $this->toFormat(Str::create('d'))); - } - - /** - * Get Hour part of the instance. - * - * @return int - */ - public function getHour(): int - { - return (int) ((string) $this->toFormat(Str::create('H'))); - } - - /** - * Get Minute part of the instance. - * - * @return int - */ - public function getMinute(): int - { - return (int) ((string) $this->toFormat(Str::create('i'))); - } - - /** - * Get Second part of the instance. - * - * @return int - */ - public function getSecond(): int - { - return (int) ((string) $this->toFormat(Str::create('s'))); - } - - /** - * Internal method for DateInterval addition and subtraction. - * - * @param string $duration - Duration string - * @param int $value - * @return Datetime - */ - protected function addDateIntervalValue(string $duration, int $value): Datetime - { - $isNegative = ($value < 0); - $value = (int) \abs($value); - - $dateInterval = new \DateInterval( - \sprintf($duration, $value) - ); - - if ($isNegative) { - $dateInterval->invert = 1; - } - - return new Datetime( - $this->dateTime - ->add($dateInterval) - ->format(self::START_FORMAT) - ); - } - - /** - * Add the supplied number of Seconds to the Datetime instance. - * - * Supports chaining. - * - * @param int $seconds - Number of Seconds to add to instance. Supports negative numbers for subtraction. - * @return Datetime - */ - public function addSeconds(int $seconds): Datetime - { - return $this->addDateIntervalValue("PT%dS", $seconds); - } - - /** - * Add the supplied number of Minutes to the Datetime instance. - * - * Supports chaining. - * - * @param int $minutes - Number of Minutes to add to instance. Supports negative numbers for subtraction. - * @return Datetime - */ - public function addMinutes(int $minutes): Datetime - { - return $this->addDateIntervalValue("PT%dM", $minutes); - } - - /** - * Add the supplied number of Hours to the Datetime instance. - * - * Supports chaining. - * - * @param int $hours - Number of Hours to add to instance. Supports negative numbers for subtraction. - * @return Datetime - */ - public function addHours(int $hours): Datetime - { - return $this->addDateIntervalValue("PT%dH", $hours); - } - - /** - * Add the supplied number of Days to the Datetime instance. - * - * Supports chaining. - * - * @param int $days - Number of Days to add to instance. Supports negative numbers for subtraction. - * @return Datetime - */ - public function addDays(int $days): Datetime - { - return $this->addDateIntervalValue("P%dD", $days); - } - - /** - * Add the supplied number of Months to the Datetime instance. - * - * Supports chaining. - * - * @param int $months - Number of Months to add to instance. Supports negative numbers for subtraction. - * @return Datetime - */ - public function addMonths(int $months): Datetime - { - return $this->addDateIntervalValue("P%dM", $months); - } - - /** - * Add the supplied number of Years to the Datetime instance. - * - * Supports chaining. - * - * @param int $years - Number of Years to add to instance. Supports negative numbers for subtraction. - * @return Datetime - */ - public function addYears(int $years): Datetime - { - return $this->addDateIntervalValue("P%dY", $years); - } - - public function difference(Datetime $datetime, bool $absolute = false): DateInterval - { - $dateInterval = $this->dateTime->diff( - new \DateTime((string) $datetime), - $absolute - ); - - return DateInterval::fromDuration( - Str::create( - \sprintf( - 'P%dY%dM%dDT%dH%dM%dS', - $dateInterval->y, - $dateInterval->m, - $dateInterval->d, - $dateInterval->h, - $dateInterval->i, - $dateInterval->s - ) - ), - $dateInterval->invert === 1 - ); - } - - public function getStartOfDay(): Datetime - { - return new Datetime( - $this->dateTime->format('Y-m-d 00:00:00') - ); - } - - public function getEndOfDay(): Datetime - { - return new Datetime( - $this->dateTime->format('Y-m-d 23:59:59') - ); - } - - protected function toFormatInternal(string $format): Str - { - return Str::create( - $this->dateTime->format($format) - ); - } - - /** - * Returns Str instance with value in format "Y-m-d\TH:i:sP". - * - * @return Str - */ - public function toATOM(): Str - { - return $this->toFormatInternal(\Datetime::ATOM); - } - - /** - * Returns Str instance with value in format "l, d-M-Y H:i:s T". - * - * @return Str - */ - public function toCookie(): Str - { - return $this->toFormatInternal(\Datetime::COOKIE); - } - - /** - * Returns Str instance with value in format "Y-m-d\TH:i:sO". - * - * @return Str - */ - public function toISO8601(): Str - { - return $this->toFormatInternal(\Datetime::ISO8601); - } - - /** - * Returns Str instance with value in format "D, d M y H:i:s O". - * - * @return Str - */ - public function toRFC822(): Str - { - return $this->toFormatInternal(\Datetime::RFC822); - } - - /** - * Returns Str instance with value in format "l, d-M-y H:i:s T". - * - * @return Str - */ - public function toRFC850(): Str - { - return $this->toFormatInternal(\Datetime::RFC850); - } - - /** - * Returns Str instance with value in format "D, d M y H:i:s O". - * - * @return Str - */ - public function toRFC1036(): Str - { - return $this->toFormatInternal(\Datetime::RFC1036); - } - - /** - * Returns Str instance with value in format "D, d M Y H:i:s O". - * - * @return Str - */ - public function toRFC1123(): Str - { - return $this->toFormatInternal(\Datetime::RFC1123); - } - - /** - * Returns Str instance with value in format "D, d M Y H:i:s \G\M\T". - * - * @return Str - */ - public function toRFC7231(): Str - { - return $this->toFormatInternal(\Datetime::RFC7231); - } - - /** - * Returns Str instance with value in format "D, d M Y H:i:s O". - * - * @return Str - */ - public function toRFC2822(): Str - { - return $this->toFormatInternal(\Datetime::RFC2822); - } - - /** - * Returns Str instance with value in format "Y-m-d\TH:i:sP". - * - * @return Str - */ - public function toRFC3339(): Str - { - return $this->toFormatInternal(\Datetime::RFC3339); - } - - /** - * Returns Str instance with value in format "Y-m-d\TH:i:s.vP". - * - * @return Str - */ - public function toRFC3339Extended(): Str - { - return $this->toFormatInternal(\Datetime::RFC3339_EXTENDED); - } - - /** - * Returns Str instance with value in format "D, d M Y H:i:s O". - * - * @return Str - */ - public function toRSS(): Str - { - return $this->toFormatInternal(\Datetime::RSS); - } - - /** - * Returns Str instance with value in format "Y-m-d\TH:i:sP". - * - * @return Str - */ - public function toW3C(): Str - { - return $this->toFormatInternal(\Datetime::W3C); - } - - /** - * Returns Str instance with value in format "Y-m-d H:i:s". - * - * @return Str - */ - public function toDatetimeString(): Str - { - return $this->toFormatInternal('Y-m-d H:i:s'); - } - - /** - * Returns Str instance with value in format "Y-m-d". - * - * @return Str - */ - public function toDateString(): Str - { - return $this->toFormatInternal('Y-m-d'); - } - - /** - * Returns Str instance with value in format "H:i:s". - * - * @return Str - */ - public function toTimeString(): Str - { - return $this->toFormatInternal('H:i:s'); - } - - /** - * Returns Str instance with value in specified format. - * - * @param Str $format - Str instance containing desired Datetime format. - * @return Str - */ - public function toFormat(Str $format): Str - { - return $this->toFormatInternal((string) $format); - } - - /** - * Returns the Timezone set on the Datetime's instance. - * - * @return \DateTimeZone - */ - public function getTimezone(): \DateTimeZone - { - return new \DateTimeZone("Europe/London"); - } - - /** - * Returns the Timezone set on the Datetime's instance, in string format. - * - * @return string - */ - public function getTimezoneName(): string - { - return $this->carbon->timezoneName; - } -} From 91d1f6bcb27148fc3817e56488487264a919e7fb Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 20:12:12 +0000 Subject: [PATCH 178/193] BREAKING CHANGE: rename DatetimeImmutable class --- .../{DatetimeInheritance.php => Datetime.php} | 114 +++++++++++++++++- 1 file changed, 109 insertions(+), 5 deletions(-) rename src/Datetime/{DatetimeInheritance.php => Datetime.php} (66%) diff --git a/src/Datetime/DatetimeInheritance.php b/src/Datetime/Datetime.php similarity index 66% rename from src/Datetime/DatetimeInheritance.php rename to src/Datetime/Datetime.php index 00a53bc..1aa57e3 100644 --- a/src/Datetime/DatetimeInheritance.php +++ b/src/Datetime/Datetime.php @@ -6,6 +6,7 @@ use DateTimeImmutable; use HraDigital\Datatypes\Scalar\Str; +use HraDigital\Datatypes\Traits\Datetime\Datetime\HasStaticFactoryMethodsTrait; /** * Datetime utility class. @@ -27,12 +28,12 @@ * @link http://php.net/manual/en/timezones.php * @link https://timezonedb.com/download */ -class DatetimeInheritance extends DateTimeImmutable implements \JsonSerializable +class Datetime extends DateTimeImmutable implements \JsonSerializable { - public static function create(string $datetime): DatetimeInheritance - { - return new DatetimeInheritance($datetime); - } + use HasStaticFactoryMethodsTrait; + + /** Format used for internal object instantiation */ + const START_FORMAT = \DateTimeImmutable::W3C; /** * Magic method for instance printing. @@ -277,4 +278,107 @@ public function getSecond(): int { return (int) ((string) $this->toFormatInternal('s')); } + + /** + * Internal method for DateInterval addition and subtraction. + * + * @param string $duration - Duration string + * @param int $value + * @return self + */ + protected function addDateIntervalValue(string $duration, int $value): self + { + $isNegative = ($value < 0); + $value = (int) \abs($value); + + $dateInterval = new \DateInterval( + \sprintf($duration, $value) + ); + + if ($isNegative) { + $dateInterval->invert = 1; + } + + return new self( + $this->add($dateInterval)->format(self::START_FORMAT) + ); + } + + /** + * Add the supplied number of Seconds to the Datetime instance. + * + * Supports chaining. + * + * @param int $seconds - Number of Seconds to add to instance. Supports negative numbers for subtraction. + * @return self + */ + public function addSeconds(int $seconds): self + { + return $this->addDateIntervalValue("PT%dS", $seconds); + } + + /** + * Add the supplied number of Minutes to the Datetime instance. + * + * Supports chaining. + * + * @param int $minutes - Number of Minutes to add to instance. Supports negative numbers for subtraction. + * @return self + */ + public function addMinutes(int $minutes): self + { + return $this->addDateIntervalValue("PT%dM", $minutes); + } + + /** + * Add the supplied number of Hours to the Datetime instance. + * + * Supports chaining. + * + * @param int $hours - Number of Hours to add to instance. Supports negative numbers for subtraction. + * @return self + */ + public function addHours(int $hours): self + { + return $this->addDateIntervalValue("PT%dH", $hours); + } + + /** + * Add the supplied number of Days to the Datetime instance. + * + * Supports chaining. + * + * @param int $days - Number of Days to add to instance. Supports negative numbers for subtraction. + * @return self + */ + public function addDays(int $days): self + { + return $this->addDateIntervalValue("P%dD", $days); + } + + /** + * Add the supplied number of Months to the Datetime instance. + * + * Supports chaining. + * + * @param int $months - Number of Months to add to instance. Supports negative numbers for subtraction. + * @return self + */ + public function addMonths(int $months): self + { + return $this->addDateIntervalValue("P%dM", $months); + } + + /** + * Add the supplied number of Years to the Datetime instance. + * + * Supports chaining. + * + * @param int $years - Number of Years to add to instance. Supports negative numbers for subtraction. + * @return self + */ + public function addYears(int $years): self + { + return $this->addDateIntervalValue("P%dY", $years); + } } From 7ecad42aa42a20c58a9653d761d8aa92f0f27885 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 20:12:38 +0000 Subject: [PATCH 179/193] tests: increase tests for Datetime related classes --- tests/Unit/Datetime/DateIntervalTest.php | 209 ++++++++++++++++++++ tests/Unit/Datetime/DatetimeTest.php | 233 +++++++++++++++++++++++ 2 files changed, 442 insertions(+) create mode 100644 tests/Unit/Datetime/DateIntervalTest.php create mode 100644 tests/Unit/Datetime/DatetimeTest.php diff --git a/tests/Unit/Datetime/DateIntervalTest.php b/tests/Unit/Datetime/DateIntervalTest.php new file mode 100644 index 0000000..a5339a5 --- /dev/null +++ b/tests/Unit/Datetime/DateIntervalTest.php @@ -0,0 +1,209 @@ +assertEquals(6, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + + $di = DateInterval::fromYears(-6); + + $this->assertEquals(-6, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertTrue($di->isNegative()); + } + + public function testCanLoadSuccessfullyFromMonths(): void + { + $di = DateInterval::fromMonths(5); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(5, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + + $di = DateInterval::fromMonths(-5); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(-5, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertTrue($di->isNegative()); + } + + public function testCanLoadSuccessfullyFromDays(): void + { + $di = DateInterval::fromDays(4); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(4, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + + $di = DateInterval::fromDays(-4); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(-4, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertTrue($di->isNegative()); + } + + public function testCanLoadSuccessfullyFromHours(): void + { + $di = DateInterval::fromHours(3); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(3, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + + $di = DateInterval::fromHours(-3); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(-3, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertTrue($di->isNegative()); + } + + public function testCanLoadSuccessfullyFromMinutes(): void + { + $di = DateInterval::fromMinutes(2); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(2, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + + $di = DateInterval::fromMinutes(-2); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(-2, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertTrue($di->isNegative()); + } + + public function testCanLoadSuccessfullyFromSeconds(): void + { + $di = DateInterval::fromSeconds(1); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(1, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + + $di = DateInterval::fromSeconds(-1); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(0, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(-1, $di->getSeconds()); + $this->assertTrue($di->isNegative()); + } + + public function testCanLoadSuccessfullyFromDuration(): void + { + $strFormat = '%r%Yy %Mm %Dd %H:%I:%S'; + + $di = DateInterval::fromDuration(Str::create("P3Y6M4DT12H30M5S")); + + $this->assertEquals(3, $di->getYears()); + $this->assertEquals(6, $di->getMonths()); + $this->assertEquals(4, $di->getDays()); + $this->assertEquals(12, $di->getHours()); + $this->assertEquals(30, $di->getMinutes()); + $this->assertEquals(5, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + $this->assertEquals("03y 06m 04d 12:30:05", $di->toDatetimeString()); + $this->assertEquals("03y 06m 04d 12:30:05", $di->toFormat(Str::create($strFormat))); + $this->assertEquals("03y 06m 04d 12:30:05", $di->format($strFormat)); + + $di = DateInterval::fromDuration(Str::create("P3Y6M4DT12H30M5S"), true); + + $this->assertEquals(-3, $di->getYears()); + $this->assertEquals(-6, $di->getMonths()); + $this->assertEquals(-4, $di->getDays()); + $this->assertEquals(-12, $di->getHours()); + $this->assertEquals(-30, $di->getMinutes()); + $this->assertEquals(-5, $di->getSeconds()); + $this->assertTrue($di->isNegative()); + $this->assertEquals("-03y 06m 04d 12:30:05", $di->toDatetimeString()); + $this->assertEquals("-03y 06m 04d 12:30:05", $di->toFormat(Str::create($strFormat))); + $this->assertEquals("-03y 06m 04d 12:30:05", $di->format($strFormat)); + } + + public function testCanLoadSuccessfullyFromDateString(): void + { + $di = DateInterval::createFromDateString("2 year + 3 day"); + + $this->assertEquals(2, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(3, $di->getDays()); + $this->assertEquals(0, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + + $di = DateInterval::createFromDateString("1 day + 12 hours"); + + $this->assertEquals(0, $di->getYears()); + $this->assertEquals(0, $di->getMonths()); + $this->assertEquals(1, $di->getDays()); + $this->assertEquals(12, $di->getHours()); + $this->assertEquals(0, $di->getMinutes()); + $this->assertEquals(0, $di->getSeconds()); + $this->assertFalse($di->isNegative()); + } +} diff --git a/tests/Unit/Datetime/DatetimeTest.php b/tests/Unit/Datetime/DatetimeTest.php new file mode 100644 index 0000000..1589fb2 --- /dev/null +++ b/tests/Unit/Datetime/DatetimeTest.php @@ -0,0 +1,233 @@ +assertInstanceOf(Datetime::class, $dt); + $this->assertEquals($dt->getYear(), 2021); + $this->assertEquals($dt->getMonth(), 5); + $this->assertEquals($dt->getDay(), 6); + $this->assertEquals($dt->getHour(), 10); + $this->assertEquals($dt->getMinute(), 11); + $this->assertEquals($dt->getSecond(), 12); + $this->assertEquals((string) $dt, self::DATETIME); + $this->assertEquals($dt->jsonSerialize(), self::DATETIME); + } + + public function testCanAddInterval(): void + { + $dt = Datetime::fromString(self::DATETIME); + $interval = new \DateInterval('P1Y'); + + $result = $dt->add($interval); + + $this->assertInstanceOf(Datetime::class, $result); + $this->assertEquals($result->getYear(), 2022); + $this->assertFalse($dt === $result); + } + + private function assertOutputInFormat(string $datetime, string $format, Str $expected): void + { + $native = new \Datetime(self::DATETIME); + $result = $native->format($format); + + $this->assertEquals( + $result, + (string) $expected + ); + } + + public function testCanOutputInFormatATOM(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::ATOM, + Datetime::fromString(self::DATETIME)->toATOM() + ); + } + + public function testCanOutputInFormatCOOKIE(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::COOKIE, + Datetime::fromString(self::DATETIME)->toCookie() + ); + } + + public function testCanOutputInFormatISO8601(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::ISO8601, + Datetime::fromString(self::DATETIME)->toISO8601() + ); + } + + public function testCanOutputInFormatRFC822(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RFC822, + Datetime::fromString(self::DATETIME)->toRFC822() + ); + } + + public function testCanOutputInFormatRFC850(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RFC850, + Datetime::fromString(self::DATETIME)->toRFC850() + ); + } + + public function testCanOutputInFormatRFC1036(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RFC1036, + Datetime::fromString(self::DATETIME)->toRFC1036() + ); + } + + public function testCanOutputInFormatRFC1123(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RFC1123, + Datetime::fromString(self::DATETIME)->toRFC1123() + ); + } + + public function testCanOutputInFormatRFC7231(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RFC7231, + Datetime::fromString(self::DATETIME)->toRFC7231() + ); + } + + public function testCanOutputInFormatRFC2822(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RFC2822, + Datetime::fromString(self::DATETIME)->toRFC2822() + ); + } + + public function testCanOutputInFormatRFC3339(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RFC3339, + Datetime::fromString(self::DATETIME)->toRFC3339() + ); + } + + public function testCanOutputInFormatRFC3339Extended(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RFC3339_EXTENDED, + Datetime::fromString(self::DATETIME)->toRFC3339Extended() + ); + } + + public function testCanOutputInFormatRSS(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::RSS, + Datetime::fromString(self::DATETIME)->toRSS() + ); + } + + public function testCanOutputInFormatW3C(): void + { + $this->assertOutputInFormat( + self::DATETIME, + \Datetime::W3C, + Datetime::fromString(self::DATETIME)->toW3C() + ); + } + + public function testCanOutputInFormatDatetimeString(): void + { + $dt = new \Datetime(self::DATETIME); + + $this->assertOutputInFormat( + self::DATETIME, + $dt->format('Y-m-d H:i:s'), + Datetime::fromString(self::DATETIME)->toDatetimeString() + ); + } + + public function testCanOutputInFormatTimeString(): void + { + $dt = new \Datetime(self::DATETIME); + + $this->assertOutputInFormat( + self::DATETIME, + $dt->format('H:i:s'), + Datetime::fromString(self::DATETIME)->toTimeString() + ); + } + + public function testCanOutputInFormat(): void + { + $dt = new \Datetime(self::DATETIME); + + $this->assertOutputInFormat( + self::DATETIME, + $dt->format('Y-m-d H:i:s'), + Datetime::fromString(self::DATETIME)->toFormat(Str::create('Y-m-d H:i:s')) + ); + } + + public function testCanAddUnitsIndependently(): void + { + $original = Datetime::fromUnits(2022, 2, 2, 10, 11, 12); + $calculated = $original + ->addYears(1) + ->addMonths(1) + ->addDays(1) + ->addHours(1) + ->addMinutes(1) + ->addSeconds(1); + + $this->assertFalse($original === $calculated); + $this->assertNotEquals( + (string) $original->toDatetimeString(), + (string) $calculated->toDatetimeString() + ); + $this->assertEquals($original->getYear(), ($calculated->getYear() - 1)); + $this->assertEquals($original->getMonth(), ($calculated->getMonth() - 1)); + $this->assertEquals($original->getDay(), ($calculated->getDay() - 1)); + $this->assertEquals($original->getHour(), ($calculated->getHour() - 1)); + $this->assertEquals($original->getMinute(), ($calculated->getMinute() - 1)); + $this->assertEquals($original->getSecond(), ($calculated->getSecond() - 1)); + } +} From 25f3afc10b096434d2a9ddefbeb36c6344a7e2b9 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Sat, 12 Mar 2022 20:20:57 +0000 Subject: [PATCH 180/193] docs: add annotation for return type --- src/Datetime/DateInterval.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Datetime/DateInterval.php b/src/Datetime/DateInterval.php index 525fd1a..e473307 100644 --- a/src/Datetime/DateInterval.php +++ b/src/Datetime/DateInterval.php @@ -19,7 +19,8 @@ */ class DateInterval extends ParentDateInterval { - public static function createFromDateString($datetime) + #[\ReturnTypeWillChange] + public static function createFromDateString($datetime): DateInterval { $result = parent::createFromDateString($datetime); From ae9f8a9ae0470e034b6b0b5e776981346ef4b275 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 14 Mar 2022 08:15:52 +0000 Subject: [PATCH 181/193] build: remove unnecessary dependency --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 09c5382..5eaa4e8 100755 --- a/composer.json +++ b/composer.json @@ -26,8 +26,7 @@ }, "require-dev": { "phpunit/phpunit": "^9.0", - "squizlabs/php_codesniffer": "^3.0@dev", - "nesbot/carbon": "^2.0@dev" + "squizlabs/php_codesniffer": "^3.0@dev" }, "autoload": { "psr-4": { From 559069da8d8e0b00c1b7198e3112a2b9113b6957 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Mon, 14 Mar 2022 08:16:17 +0000 Subject: [PATCH 182/193] build: break up php-74 job into two --- .circleci/config.yml | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 00740ff..a356492 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,15 +38,11 @@ jobs: steps: - checkout - run: - name: Composer Install - command: composer install + name: Composer Update + command: composer update - run: name: Run Tests for PHPv7.4 - command: phpdbg -qrr vendor/bin/phpunit --coverage-clover ~/build/coverage-report - - store_artifacts: - path: ~/build/coverage-report - - codecov/upload: - file: ~/build/coverage-report + command: phpdbg -qrr vendor/bin/phpunit php-80: docker: @@ -55,8 +51,8 @@ jobs: steps: - checkout - run: - name: Composer Install - command: composer install + name: Composer Update + command: composer update - run: name: Run Tests for PHPv8.0 command: phpdbg -qrr vendor/bin/phpunit @@ -68,12 +64,29 @@ jobs: steps: - checkout - run: - name: Composer Install - command: composer install + name: Composer Update + command: composer update - run: name: Run Tests for PHPv8.1 command: phpdbg -qrr vendor/bin/phpunit + php-coverage: + docker: + - image: cimg/php:7.4 + working_directory: ~/php-datatypes + steps: + - checkout + - run: + name: Composer Install + command: composer install + - run: + name: Run Tests for PHPv7.4 + command: phpdbg -qrr vendor/bin/phpunit --coverage-clover ~/build/coverage-report + - store_artifacts: + path: ~/build/coverage-report + - codecov/upload: + file: ~/build/coverage-report + workflows: ci-flow: jobs: @@ -87,3 +100,8 @@ workflows: - php-81: requires: - php-cs + - php-coverage: + requires: + - php-74 + - php-80 + - php-81 From ef6ff6042e90a2c28420c8706fec347e4f68cee9 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Fri, 18 Mar 2022 18:10:04 +0000 Subject: [PATCH 183/193] fix: add small type casting improvement --- src/Traits/Entities/CanProcessEntityStateTrait.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Traits/Entities/CanProcessEntityStateTrait.php b/src/Traits/Entities/CanProcessEntityStateTrait.php index 15a2a73..0de1761 100644 --- a/src/Traits/Entities/CanProcessEntityStateTrait.php +++ b/src/Traits/Entities/CanProcessEntityStateTrait.php @@ -78,7 +78,11 @@ final public function getDirty(bool $withTimestamps = false): array } if ($hasChanged || $isNewOrRequired) { - $dirty[$field] = $this->{$field}; + if (\is_object($this->{$field}) && \method_exists($this->{$field}, '__toString')) { + $dirty[$field] = (string) $this->{$field}; + } else { + $dirty[$field] = $this->{$field}; + } } } From fa0f4e24d659f0821b8b3db55dee6212e9d654b5 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 22 Mar 2022 16:54:05 +0000 Subject: [PATCH 184/193] docs: small improvement --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bec3f36..b434a92 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## About -**PHP Datatypes** is meant to provide an easy way to create your Value Objects/Entities, in a fast and platform agnostic way, +**PHP Datatypes** is meant to provide an easy way to create your Value Objects/Entities/Aggregates, in a fast and platform agnostic way, that promotes: - Code reusability @@ -20,7 +20,7 @@ that promotes: - Full data serializing - No 3rd party dependency apart from PHP. Clean/Self reliant project. -An Entity/ValueObject that extends [AbstractValueObject](/HRADigital/php-datatypes/blob/master/src/ValueObjects/AbstractValueObject.php) +An Aggregate/Entity/ValueObject that extends [AbstractValueObject](/HRADigital/php-datatypes/blob/master/src/ValueObjects/AbstractValueObject.php) will be built using predefined/tested [Traits](/HRADigital/php-datatypes/tree/master/src/Traits/Entities) for each of the class attributes, leaving your class definition cleaned/free for your business logic implementation. From 02be03f69c86174b44e2a379e2584e90f81641c7 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 22 Mar 2022 17:03:06 +0000 Subject: [PATCH 185/193] docs: remove debugging flag --- tests/Unit/ValueObjects/TestingAggregateTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Unit/ValueObjects/TestingAggregateTest.php b/tests/Unit/ValueObjects/TestingAggregateTest.php index c29ddbf..2d047b2 100644 --- a/tests/Unit/ValueObjects/TestingAggregateTest.php +++ b/tests/Unit/ValueObjects/TestingAggregateTest.php @@ -14,7 +14,6 @@ * @package HraDigital\Datatypes * @copyright HraDigital\Datatypes * @license MIT - * @group hugo */ class TestingAggregateTest extends AbstractBaseTestCase { From 9d00f3525ef29d8c7823effa7c262e80c3c321a1 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 22 Mar 2022 17:47:10 +0000 Subject: [PATCH 186/193] feat: add new domain exception for collections --- .../Collections/DuplicatedEntryException.php | 27 +++++++++++++++++++ src/Exceptions/Collections/README.md | 1 + 2 files changed, 28 insertions(+) create mode 100644 src/Exceptions/Collections/DuplicatedEntryException.php create mode 100644 src/Exceptions/Collections/README.md diff --git a/src/Exceptions/Collections/DuplicatedEntryException.php b/src/Exceptions/Collections/DuplicatedEntryException.php new file mode 100644 index 0000000..e0b1aba --- /dev/null +++ b/src/Exceptions/Collections/DuplicatedEntryException.php @@ -0,0 +1,27 @@ + Date: Tue, 22 Mar 2022 17:47:46 +0000 Subject: [PATCH 187/193] BREAKING CHANGE: replace native exceptions with domain exceptions --- src/Collections/Linear/EntityCollection.php | 44 +++++++++++---------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/Collections/Linear/EntityCollection.php b/src/Collections/Linear/EntityCollection.php index f497646..796be33 100644 --- a/src/Collections/Linear/EntityCollection.php +++ b/src/Collections/Linear/EntityCollection.php @@ -4,6 +4,9 @@ namespace HraDigital\Datatypes\Collections\Linear; +use HraDigital\Datatypes\Exceptions\Collections\DuplicatedEntryException; +use HraDigital\Datatypes\Exceptions\Datatypes\ParameterOutOfRangeException; +use HraDigital\Datatypes\Exceptions\Datatypes\PositiveIntegerException; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; /** @@ -36,14 +39,14 @@ public function all(): array * * @param int $id - Entity's ID to search for. * - * @throws \OutOfRangeException - If the supplied ID is not a positive integer. + * @throws PositiveIntegerException - If the supplied ID is not a positive integer. * @return bool */ public function has(int $id): bool { // Validates supplied ID. if ($id <= 0) { - throw new \OutOfRangeException("Supplied ID should be a positive integer."); + throw PositiveIntegerException::withName('$id'); } // Returns the existence of the Entity in the Collection. @@ -55,18 +58,18 @@ public function has(int $id): bool * * @param int $id - Entity's ID to search for. * - * @throws \OutOfRangeException - If the supplied ID is not a positive integer. - * @throws \OutOfBoundsException - If the supplied ID was not present in the Collection. + * @throws PositiveIntegerException - If the supplied ID is not a positive integer. + * @throws ParameterOutOfRangeException - If the supplied ID was not present in the Collection. * @return AbstractValueObject */ public function get(int $id): AbstractValueObject { // Validates supplied ID. if ($id <= 0) { - throw new \OutOfRangeException("Supplied ID should be a positive integer."); + throw PositiveIntegerException::withName('$id'); } if (!\array_key_exists($id, $this->collection)) { - throw new \OutOfBoundsException("The Entity you are trying to retrieve does not exist in the Collection."); + throw ParameterOutOfRangeException::withName('$id'); } // Returns the Entity. @@ -117,20 +120,19 @@ public function ids(): array * * @param AbstractValueObject $valueObject - Entity to add to the collection. * - * @throws \OverflowException - If you're trying to add a repeated Entity to the Collection. + * @throws DuplicatedEntryException - If you're trying to add a repeated Entity to the Collection. * @return self */ - public function add(AbstractValueObject $valueObject): self + public function add(AbstractValueObject $object): self { - // Validates if the given Entity already exists in the Collection. - if (\array_key_exists($valueObject->{'getId'}(), $this->collection)) { - throw new \OverflowException("The Value Object you are trying to add to the Collection already exists."); + $id = $object->{'getId'}(); + + if (\array_key_exists($id, $this->collection)) { + throw DuplicatedEntryException::withId($id); } - // Adds an Entity to the collection. - $this->collection[$valueObject->{'getId'}()] = $valueObject; + $this->collection[$id] = $object; - // Returns this instance. return $this; } @@ -141,18 +143,18 @@ public function add(AbstractValueObject $valueObject): self * * @param int $id - Entity's ID to search for. * - * @throws \OutOfRangeException - If the supplied ID is not a positive integer. - * @throws \OutOfBoundsException - If the Entity with the supplied ID doesn't exist in the Collection. + * @throws PositiveIntegerException - If the supplied ID is not a positive integer. + * @throws ParameterOutOfRangeException - If the Entity with the supplied ID doesn't exist in the Collection. * @return bool */ public function remove(int $id): bool { // Validates supplied ID. if ($id <= 0) { - throw new \OutOfRangeException("Supplied ID should be a positive integer."); + throw PositiveIntegerException::withName('$id'); } if (!\array_key_exists($id, $this->collection)) { - throw new \OutOfBoundsException("The Entity you are trying to delete does not exist in the Collection."); + throw ParameterOutOfRangeException::withName('$id'); } // Removes element and rewinds @@ -170,6 +172,7 @@ public function remove(int $id): bool * {@inheritDoc} * @see \Iterator::rewind() */ + #[\ReturnTypeWillChange] public function rewind(): ?AbstractValueObject { // Rewinds the cursor and returns the first Element. @@ -261,11 +264,10 @@ public function valid(): bool */ public function jsonSerialize(): array { - // Declares and fills a return array. $array = []; - foreach ($this->collection as $valueObject) { - /** @var AbstractValueObject $valueObject - Type casts record */ + /** @var AbstractValueObject $valueObject - Type casts record */ + foreach ($this->collection as $valueObject) { $array[] = $valueObject->jsonSerialize(); } From 47bb2b62904ea3c168b72ecbbc4c3b24c5af4f31 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 22 Mar 2022 17:47:58 +0000 Subject: [PATCH 188/193] tests: increase test coverage --- .../Linear/EntityCollectionTest.php | 160 ++++++++++++++++++ tests/Unit/Datetime/DateIntervalTest.php | 3 + .../Unit/ValueObjects/TestingValueObject.php | 5 +- 3 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/Collections/Linear/EntityCollectionTest.php diff --git a/tests/Unit/Collections/Linear/EntityCollectionTest.php b/tests/Unit/Collections/Linear/EntityCollectionTest.php new file mode 100644 index 0000000..74af85a --- /dev/null +++ b/tests/Unit/Collections/Linear/EntityCollectionTest.php @@ -0,0 +1,160 @@ +assertEquals(0, $collection->count()); + + $data = TestingValueObject::DATA; + $data['id'] = 1; + $collection->add( + new TestingValueObject($data) + ); + $data['id'] = 2; + $collection->add( + new TestingValueObject($data) + ); + $data['id'] = 3; + $collection->add( + new TestingValueObject($data) + ); + + $array = $collection->all(); + $json = $collection->jsonSerialize(); + $ids = $collection->ids(); + + $this->assertEquals(3, $collection->count()); + + $this->assertCount(3, $array); + $this->assertCount(3, $json); + $this->assertCount(3, $ids); + + $this->assertContains(1, $ids); + $this->assertContains(2, $ids); + $this->assertContains(3, $ids); + + $entity = $collection->get(2); + $this->assertEquals(2, $entity->{'getId'}()); + } + + public function testCanManageEntriesInCollection(): void + { + $collection = new EntityCollection(); + $this->assertEquals(0, $collection->count()); + $this->assertFalse($collection->valid()); + $this->assertNull($collection->current()); + $this->assertNull($collection->key()); + + $data = TestingValueObject::DATA; + $data['id'] = 1; + $collection->add( + new TestingValueObject($data) + ); + $data['id'] = 2; + $collection->add( + new TestingValueObject($data) + ); + $data['id'] = 3; + $collection->add( + new TestingValueObject($data) + ); + + $this->assertEquals(3, $collection->count()); + $this->assertTrue($collection->valid()); + $this->assertTrue($collection->has(1)); + $this->assertTrue($collection->has(2)); + $this->assertTrue($collection->has(3)); + $this->assertNotNull($collection->current()); + + $this->assertEquals(1, $collection->key()); + $collection->next(); + $collection->next(); + $this->assertEquals(3, $collection->key()); + + $collection->remove(2); + $collection->rewind(); + $this->assertEquals(1, $collection->key()); + $this->assertEquals(2, $collection->count()); + $this->assertCount(2, $collection->ids()); + $this->assertCount(2, $collection->all()); + $this->assertTrue($collection->has(1)); + $this->assertFalse($collection->has(2)); + $this->assertTrue($collection->has(3)); + + $collection->clear(); + $this->assertEquals(0, $collection->count()); + } + + public function testBreaksIfCheckingHasNonPositiveId(): void + { + $this->expectException(PositiveIntegerException::class); + + $collection = new EntityCollection(); + $collection->has(0); + } + + public function testBreaksIfCheckingGetNonPositiveId(): void + { + $this->expectException(PositiveIntegerException::class); + + $collection = new EntityCollection(); + $collection->get(0); + } + + public function testBreaksIfCheckingGetUnexistingId(): void + { + $this->expectException(ParameterOutOfRangeException::class); + + $collection = new EntityCollection(); + $collection->get(1); + } + + public function testBreaksIfAttemptToAddTwoObjectsWithSameId(): void + { + $this->expectException(DuplicatedEntryException::class); + + $collection = new EntityCollection(); + $collection->add( + new TestingValueObject(TestingValueObject::DATA) + ); + $collection->add( + new TestingValueObject(TestingValueObject::DATA) + ); + } + + public function testBreaksIfAttemptsRemovingNonPositiveId(): void + { + $this->expectException(PositiveIntegerException::class); + + $collection = new EntityCollection(); + $collection->remove(0); + } + + public function testBreaksIfAttemptsRemovingUnexistingId(): void + { + $this->expectException(ParameterOutOfRangeException::class); + + $collection = new EntityCollection(); + $collection->remove(1); + } +} diff --git a/tests/Unit/Datetime/DateIntervalTest.php b/tests/Unit/Datetime/DateIntervalTest.php index a5339a5..03a264a 100644 --- a/tests/Unit/Datetime/DateIntervalTest.php +++ b/tests/Unit/Datetime/DateIntervalTest.php @@ -166,6 +166,7 @@ public function testCanLoadSuccessfullyFromDuration(): void $this->assertEquals(30, $di->getMinutes()); $this->assertEquals(5, $di->getSeconds()); $this->assertFalse($di->isNegative()); + $this->assertEquals((string) $di, $di->toDatetimeString()); $this->assertEquals("03y 06m 04d 12:30:05", $di->toDatetimeString()); $this->assertEquals("03y 06m 04d 12:30:05", $di->toFormat(Str::create($strFormat))); $this->assertEquals("03y 06m 04d 12:30:05", $di->format($strFormat)); @@ -179,9 +180,11 @@ public function testCanLoadSuccessfullyFromDuration(): void $this->assertEquals(-30, $di->getMinutes()); $this->assertEquals(-5, $di->getSeconds()); $this->assertTrue($di->isNegative()); + $this->assertEquals((string) $di, $di->toDatetimeString()); $this->assertEquals("-03y 06m 04d 12:30:05", $di->toDatetimeString()); $this->assertEquals("-03y 06m 04d 12:30:05", $di->toFormat(Str::create($strFormat))); $this->assertEquals("-03y 06m 04d 12:30:05", $di->format($strFormat)); + $this->assertEquals("-03y 06m 04d 12:30:05", $di->format($strFormat)); } public function testCanLoadSuccessfullyFromDateString(): void diff --git a/tests/Unit/ValueObjects/TestingValueObject.php b/tests/Unit/ValueObjects/TestingValueObject.php index c6cc001..71e4a71 100644 --- a/tests/Unit/ValueObjects/TestingValueObject.php +++ b/tests/Unit/ValueObjects/TestingValueObject.php @@ -11,6 +11,7 @@ use HraDigital\Datatypes\Traits\Entities\CanProcessOnUpdateEventsTrait; use HraDigital\Datatypes\Traits\Entities\General\HasActiveTrait; use HraDigital\Datatypes\Traits\Entities\General\HasEmailTrait; +use HraDigital\Datatypes\Traits\Entities\General\HasPositiveIntegerIDTrait; use HraDigital\Datatypes\Traits\Entities\General\HasTitleTrait; use HraDigital\Datatypes\Traits\Entities\General\HasUpdatableUpdatedAtTrait; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; @@ -25,6 +26,7 @@ class TestingValueObject extends AbstractValueObject { const DATA = [ + 'id' => 123, 'is_active' => false, 'address' => 'user@domain.tld', 'title' => 'my title', @@ -34,7 +36,8 @@ class TestingValueObject extends AbstractValueObject ], ]; - use HasActiveTrait, + use HasPositiveIntegerIDTrait, + HasActiveTrait, CanMassAssignStateTrait, CanProcessEntityStateTrait, CanProcessOnUpdateEventsTrait, From f298e2bd671ffa6d070a5be26771df562a3f5191 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 22 Mar 2022 18:00:28 +0000 Subject: [PATCH 189/193] BREAKING CHANGE: move attribute traits to dedicated namespace --- .../General/HasActiveTrait.php | 2 +- .../General/HasAliasTrait.php | 2 +- .../General/HasCreatedAtTrait.php | 2 +- .../General/HasDeletedAtTrait.php | 2 +- .../General/HasEmailTrait.php | 2 +- .../General/HasFeatureTrait.php | 2 +- .../General/HasHitsTrait.php | 2 +- .../General/HasNameTrait.php | 2 +- .../General/HasOrderingTrait.php | 2 +- .../General/HasPasswordTrait.php | 2 +- .../General/HasPositiveIntegerIDTrait.php | 2 +- .../General/HasPublishedTimestampsTrait.php | 2 +- .../General/HasPublishedTrait.php | 2 +- .../General/HasSeoFieldsTrait.php | 2 +- .../General/HasSurnameTrait.php | 2 +- .../General/HasTimestampsTrait.php | 2 +- .../General/HasTitleTrait.php | 2 +- .../General/HasUpdatableUpdatedAtTrait.php | 2 +- .../General/HasUpdatedAtTrait.php | 2 +- .../General/HasUuidTrait.php | 2 +- .../Entities => Attributes}/General/README.md | 0 .../Location/HasAddressTrait.php | 2 +- .../Location/HasCityTrait.php | 2 +- .../Location/HasCountryCodeTrait.php | 2 +- .../Location/HasCountryTrait.php | 2 +- .../Location/HasDistrictTrait.php | 2 +- .../Location/HasLatitudeTrait.php | 2 +- .../Location/HasLongitudeTrait.php | 2 +- .../Location/HasParishTrait.php | 2 +- .../Location/HasPostalCodeTrait.php | 2 +- .../Location/HasStreetAdditionalTrait.php | 2 +- .../Location/HasStreetNumberTrait.php | 2 +- .../Location/HasStreetTrait.php | 2 +- .../Location/README.md | 0 .../Personal/HasCountryOfBirthTrait.php | 2 +- .../Personal/HasDateOfBirthTrait.php | 2 +- .../Personal/HasGenderTrait.php | 2 +- .../Personal/HasNationalityTrait.php | 2 +- .../Personal/HasPhotoTrait.php | 2 +- .../Personal/README.md | 0 .../Professional/HasIndustryTrait.php | 2 +- .../Professional/HasOccupationTrait.php | 2 +- .../Professional/README.md | 0 .../SocialMedia/HasFacebookProfileTrait.php | 2 +- .../SocialMedia/HasInstagramProfileTrait.php | 2 +- .../SocialMedia/HasLinkedinProfileTrait.php | 2 +- .../SocialMedia/HasTwitterProfileTrait.php | 2 +- .../SocialMedia/README.md | 0 .../Timezone/HasTimestampTrait.php | 2 +- .../Timezone/README.md | 0 tests/Unit/Attributes/GeneralTraitsVO.php | 59 +++++++++++++++++++ .../GeneralTraitsVOTest.php | 2 +- tests/Unit/Attributes/LocationTraitsVO.php | 44 ++++++++++++++ .../LocationTraitsVOTest.php | 26 ++++---- .../PersonalTraitsVO.php | 12 ++-- .../PersonalTraitsVOTest.php | 2 +- .../ProfessionalTraitsVO.php | 6 +- .../ProfessionalTraitsVOTest.php | 2 +- .../SocialMediaTraitsVO.php | 10 ++-- .../SocialMediaTraitsVOTest.php | 2 +- .../TimezoneTraitsVO.php | 4 +- .../TimezoneTraitsVOTest.php | 2 +- .../Unit/Traits/Entities/GeneralTraitsVO.php | 59 ------------------- .../Unit/Traits/Entities/LocationTraitsVO.php | 44 -------------- 64 files changed, 181 insertions(+), 181 deletions(-) rename src/{Traits/Entities => Attributes}/General/HasActiveTrait.php (93%) rename src/{Traits/Entities => Attributes}/General/HasAliasTrait.php (95%) rename src/{Traits/Entities => Attributes}/General/HasCreatedAtTrait.php (94%) rename src/{Traits/Entities => Attributes}/General/HasDeletedAtTrait.php (95%) rename src/{Traits/Entities => Attributes}/General/HasEmailTrait.php (94%) rename src/{Traits/Entities => Attributes}/General/HasFeatureTrait.php (93%) rename src/{Traits/Entities => Attributes}/General/HasHitsTrait.php (94%) rename src/{Traits/Entities => Attributes}/General/HasNameTrait.php (95%) rename src/{Traits/Entities => Attributes}/General/HasOrderingTrait.php (95%) rename src/{Traits/Entities => Attributes}/General/HasPasswordTrait.php (93%) rename src/{Traits/Entities => Attributes}/General/HasPositiveIntegerIDTrait.php (95%) rename src/{Traits/Entities => Attributes}/General/HasPublishedTimestampsTrait.php (87%) rename src/{Traits/Entities => Attributes}/General/HasPublishedTrait.php (93%) rename src/{Traits/Entities => Attributes}/General/HasSeoFieldsTrait.php (98%) rename src/{Traits/Entities => Attributes}/General/HasSurnameTrait.php (95%) rename src/{Traits/Entities => Attributes}/General/HasTimestampsTrait.php (86%) rename src/{Traits/Entities => Attributes}/General/HasTitleTrait.php (95%) rename src/{Traits/Entities => Attributes}/General/HasUpdatableUpdatedAtTrait.php (91%) rename src/{Traits/Entities => Attributes}/General/HasUpdatedAtTrait.php (94%) rename src/{Traits/Entities => Attributes}/General/HasUuidTrait.php (93%) rename src/{Traits/Entities => Attributes}/General/README.md (100%) rename src/{Traits/Entities => Attributes}/Location/HasAddressTrait.php (92%) rename src/{Traits/Entities => Attributes}/Location/HasCityTrait.php (94%) rename src/{Traits/Entities => Attributes}/Location/HasCountryCodeTrait.php (93%) rename src/{Traits/Entities => Attributes}/Location/HasCountryTrait.php (92%) rename src/{Traits/Entities => Attributes}/Location/HasDistrictTrait.php (95%) rename src/{Traits/Entities => Attributes}/Location/HasLatitudeTrait.php (92%) rename src/{Traits/Entities => Attributes}/Location/HasLongitudeTrait.php (92%) rename src/{Traits/Entities => Attributes}/Location/HasParishTrait.php (95%) rename src/{Traits/Entities => Attributes}/Location/HasPostalCodeTrait.php (93%) rename src/{Traits/Entities => Attributes}/Location/HasStreetAdditionalTrait.php (93%) rename src/{Traits/Entities => Attributes}/Location/HasStreetNumberTrait.php (93%) rename src/{Traits/Entities => Attributes}/Location/HasStreetTrait.php (92%) rename src/{Traits/Entities => Attributes}/Location/README.md (100%) rename src/{Traits/Entities => Attributes}/Personal/HasCountryOfBirthTrait.php (94%) rename src/{Traits/Entities => Attributes}/Personal/HasDateOfBirthTrait.php (93%) rename src/{Traits/Entities => Attributes}/Personal/HasGenderTrait.php (95%) rename src/{Traits/Entities => Attributes}/Personal/HasNationalityTrait.php (95%) rename src/{Traits/Entities => Attributes}/Personal/HasPhotoTrait.php (95%) rename src/{Traits/Entities => Attributes}/Personal/README.md (100%) rename src/{Traits/Entities => Attributes}/Professional/HasIndustryTrait.php (95%) rename src/{Traits/Entities => Attributes}/Professional/HasOccupationTrait.php (96%) rename src/{Traits/Entities => Attributes}/Professional/README.md (100%) rename src/{Traits/Entities => Attributes}/SocialMedia/HasFacebookProfileTrait.php (94%) rename src/{Traits/Entities => Attributes}/SocialMedia/HasInstagramProfileTrait.php (94%) rename src/{Traits/Entities => Attributes}/SocialMedia/HasLinkedinProfileTrait.php (94%) rename src/{Traits/Entities => Attributes}/SocialMedia/HasTwitterProfileTrait.php (94%) rename src/{Traits/Entities => Attributes}/SocialMedia/README.md (100%) rename src/{Traits/Entities => Attributes}/Timezone/HasTimestampTrait.php (92%) rename src/{Traits/Entities => Attributes}/Timezone/README.md (100%) create mode 100644 tests/Unit/Attributes/GeneralTraitsVO.php rename tests/Unit/{Traits/Entities => Attributes}/GeneralTraitsVOTest.php (99%) create mode 100644 tests/Unit/Attributes/LocationTraitsVO.php rename tests/Unit/{Traits/Entities => Attributes}/LocationTraitsVOTest.php (75%) rename tests/Unit/{Traits/Entities => Attributes}/PersonalTraitsVO.php (57%) rename tests/Unit/{Traits/Entities => Attributes}/PersonalTraitsVOTest.php (96%) rename tests/Unit/{Traits/Entities => Attributes}/ProfessionalTraitsVO.php (63%) rename tests/Unit/{Traits/Entities => Attributes}/ProfessionalTraitsVOTest.php (95%) rename tests/Unit/{Traits/Entities => Attributes}/SocialMediaTraitsVO.php (54%) rename tests/Unit/{Traits/Entities => Attributes}/SocialMediaTraitsVOTest.php (96%) rename tests/Unit/{Traits/Entities => Attributes}/TimezoneTraitsVO.php (71%) rename tests/Unit/{Traits/Entities => Attributes}/TimezoneTraitsVOTest.php (90%) delete mode 100644 tests/Unit/Traits/Entities/GeneralTraitsVO.php delete mode 100644 tests/Unit/Traits/Entities/LocationTraitsVO.php diff --git a/src/Traits/Entities/General/HasActiveTrait.php b/src/Attributes/General/HasActiveTrait.php similarity index 93% rename from src/Traits/Entities/General/HasActiveTrait.php rename to src/Attributes/General/HasActiveTrait.php index 429d8a1..d62f898 100755 --- a/src/Traits/Entities/General/HasActiveTrait.php +++ b/src/Attributes/General/HasActiveTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; /** * Gives Activation information capabilities to an Entity/Value Object. diff --git a/src/Traits/Entities/General/HasAliasTrait.php b/src/Attributes/General/HasAliasTrait.php similarity index 95% rename from src/Traits/Entities/General/HasAliasTrait.php rename to src/Attributes/General/HasAliasTrait.php index 49e472f..863aa1a 100755 --- a/src/Traits/Entities/General/HasAliasTrait.php +++ b/src/Attributes/General/HasAliasTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/General/HasCreatedAtTrait.php b/src/Attributes/General/HasCreatedAtTrait.php similarity index 94% rename from src/Traits/Entities/General/HasCreatedAtTrait.php rename to src/Attributes/General/HasCreatedAtTrait.php index 8d4e09c..c0ad394 100644 --- a/src/Traits/Entities/General/HasCreatedAtTrait.php +++ b/src/Attributes/General/HasCreatedAtTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Datetime\Datetime; diff --git a/src/Traits/Entities/General/HasDeletedAtTrait.php b/src/Attributes/General/HasDeletedAtTrait.php similarity index 95% rename from src/Traits/Entities/General/HasDeletedAtTrait.php rename to src/Attributes/General/HasDeletedAtTrait.php index b147f24..ca10bd0 100644 --- a/src/Traits/Entities/General/HasDeletedAtTrait.php +++ b/src/Attributes/General/HasDeletedAtTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Datetime\Datetime; diff --git a/src/Traits/Entities/General/HasEmailTrait.php b/src/Attributes/General/HasEmailTrait.php similarity index 94% rename from src/Traits/Entities/General/HasEmailTrait.php rename to src/Attributes/General/HasEmailTrait.php index 27d644b..594a5f9 100644 --- a/src/Traits/Entities/General/HasEmailTrait.php +++ b/src/Attributes/General/HasEmailTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Web\EmailAddress; diff --git a/src/Traits/Entities/General/HasFeatureTrait.php b/src/Attributes/General/HasFeatureTrait.php similarity index 93% rename from src/Traits/Entities/General/HasFeatureTrait.php rename to src/Attributes/General/HasFeatureTrait.php index e231c77..c95b23c 100755 --- a/src/Traits/Entities/General/HasFeatureTrait.php +++ b/src/Attributes/General/HasFeatureTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; /** * Gives Featured information capabilities to an Entity/Value Object. diff --git a/src/Traits/Entities/General/HasHitsTrait.php b/src/Attributes/General/HasHitsTrait.php similarity index 94% rename from src/Traits/Entities/General/HasHitsTrait.php rename to src/Attributes/General/HasHitsTrait.php index f3b7626..0985782 100755 --- a/src/Traits/Entities/General/HasHitsTrait.php +++ b/src/Attributes/General/HasHitsTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonNegativeNumberException; diff --git a/src/Traits/Entities/General/HasNameTrait.php b/src/Attributes/General/HasNameTrait.php similarity index 95% rename from src/Traits/Entities/General/HasNameTrait.php rename to src/Attributes/General/HasNameTrait.php index d29f976..007c69f 100755 --- a/src/Traits/Entities/General/HasNameTrait.php +++ b/src/Attributes/General/HasNameTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/General/HasOrderingTrait.php b/src/Attributes/General/HasOrderingTrait.php similarity index 95% rename from src/Traits/Entities/General/HasOrderingTrait.php rename to src/Attributes/General/HasOrderingTrait.php index 3ebac0d..e758548 100755 --- a/src/Traits/Entities/General/HasOrderingTrait.php +++ b/src/Attributes/General/HasOrderingTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonNegativeNumberException; diff --git a/src/Traits/Entities/General/HasPasswordTrait.php b/src/Attributes/General/HasPasswordTrait.php similarity index 93% rename from src/Traits/Entities/General/HasPasswordTrait.php rename to src/Attributes/General/HasPasswordTrait.php index 8d7c03b..0fca223 100755 --- a/src/Traits/Entities/General/HasPasswordTrait.php +++ b/src/Attributes/General/HasPasswordTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php b/src/Attributes/General/HasPositiveIntegerIDTrait.php similarity index 95% rename from src/Traits/Entities/General/HasPositiveIntegerIDTrait.php rename to src/Attributes/General/HasPositiveIntegerIDTrait.php index 9217731..1bb5904 100644 --- a/src/Traits/Entities/General/HasPositiveIntegerIDTrait.php +++ b/src/Attributes/General/HasPositiveIntegerIDTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Exceptions\Datatypes\PositiveIntegerException; diff --git a/src/Traits/Entities/General/HasPublishedTimestampsTrait.php b/src/Attributes/General/HasPublishedTimestampsTrait.php similarity index 87% rename from src/Traits/Entities/General/HasPublishedTimestampsTrait.php rename to src/Attributes/General/HasPublishedTimestampsTrait.php index 370eb60..403c4a3 100755 --- a/src/Traits/Entities/General/HasPublishedTimestampsTrait.php +++ b/src/Attributes/General/HasPublishedTimestampsTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; /** * Gives Publishing with timestamps capabilities to an Entity. diff --git a/src/Traits/Entities/General/HasPublishedTrait.php b/src/Attributes/General/HasPublishedTrait.php similarity index 93% rename from src/Traits/Entities/General/HasPublishedTrait.php rename to src/Attributes/General/HasPublishedTrait.php index 8087f7b..4ac8291 100755 --- a/src/Traits/Entities/General/HasPublishedTrait.php +++ b/src/Attributes/General/HasPublishedTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; /** * Gives Publishing capabilities to an Entity/Value Object. diff --git a/src/Traits/Entities/General/HasSeoFieldsTrait.php b/src/Attributes/General/HasSeoFieldsTrait.php similarity index 98% rename from src/Traits/Entities/General/HasSeoFieldsTrait.php rename to src/Attributes/General/HasSeoFieldsTrait.php index a307618..6f39799 100755 --- a/src/Traits/Entities/General/HasSeoFieldsTrait.php +++ b/src/Attributes/General/HasSeoFieldsTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Exceptions\Datatypes\InvalidStringLengthException; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; diff --git a/src/Traits/Entities/General/HasSurnameTrait.php b/src/Attributes/General/HasSurnameTrait.php similarity index 95% rename from src/Traits/Entities/General/HasSurnameTrait.php rename to src/Attributes/General/HasSurnameTrait.php index 25348bf..f0fb65c 100755 --- a/src/Traits/Entities/General/HasSurnameTrait.php +++ b/src/Attributes/General/HasSurnameTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/General/HasTimestampsTrait.php b/src/Attributes/General/HasTimestampsTrait.php similarity index 86% rename from src/Traits/Entities/General/HasTimestampsTrait.php rename to src/Attributes/General/HasTimestampsTrait.php index 78a0924..43ecf2b 100755 --- a/src/Traits/Entities/General/HasTimestampsTrait.php +++ b/src/Attributes/General/HasTimestampsTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; /** * Gives Timestamp capabilities to a Record. diff --git a/src/Traits/Entities/General/HasTitleTrait.php b/src/Attributes/General/HasTitleTrait.php similarity index 95% rename from src/Traits/Entities/General/HasTitleTrait.php rename to src/Attributes/General/HasTitleTrait.php index c37fb28..c65b445 100755 --- a/src/Traits/Entities/General/HasTitleTrait.php +++ b/src/Attributes/General/HasTitleTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php b/src/Attributes/General/HasUpdatableUpdatedAtTrait.php similarity index 91% rename from src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php rename to src/Attributes/General/HasUpdatableUpdatedAtTrait.php index 0611d8c..b1d56f2 100644 --- a/src/Traits/Entities/General/HasUpdatableUpdatedAtTrait.php +++ b/src/Attributes/General/HasUpdatableUpdatedAtTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Datetime\Datetime; diff --git a/src/Traits/Entities/General/HasUpdatedAtTrait.php b/src/Attributes/General/HasUpdatedAtTrait.php similarity index 94% rename from src/Traits/Entities/General/HasUpdatedAtTrait.php rename to src/Attributes/General/HasUpdatedAtTrait.php index d47311d..b101a6f 100644 --- a/src/Traits/Entities/General/HasUpdatedAtTrait.php +++ b/src/Attributes/General/HasUpdatedAtTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Datetime\Datetime; diff --git a/src/Traits/Entities/General/HasUuidTrait.php b/src/Attributes/General/HasUuidTrait.php similarity index 93% rename from src/Traits/Entities/General/HasUuidTrait.php rename to src/Attributes/General/HasUuidTrait.php index cdf858c..34155c7 100644 --- a/src/Traits/Entities/General/HasUuidTrait.php +++ b/src/Attributes/General/HasUuidTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\General; +namespace HraDigital\Datatypes\Attributes\General; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/General/README.md b/src/Attributes/General/README.md similarity index 100% rename from src/Traits/Entities/General/README.md rename to src/Attributes/General/README.md diff --git a/src/Traits/Entities/Location/HasAddressTrait.php b/src/Attributes/Location/HasAddressTrait.php similarity index 92% rename from src/Traits/Entities/Location/HasAddressTrait.php rename to src/Attributes/Location/HasAddressTrait.php index 1c573f7..41c3aab 100644 --- a/src/Traits/Entities/Location/HasAddressTrait.php +++ b/src/Attributes/Location/HasAddressTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasCityTrait.php b/src/Attributes/Location/HasCityTrait.php similarity index 94% rename from src/Traits/Entities/Location/HasCityTrait.php rename to src/Attributes/Location/HasCityTrait.php index 285c6eb..6419bb2 100644 --- a/src/Traits/Entities/Location/HasCityTrait.php +++ b/src/Attributes/Location/HasCityTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasCountryCodeTrait.php b/src/Attributes/Location/HasCountryCodeTrait.php similarity index 93% rename from src/Traits/Entities/Location/HasCountryCodeTrait.php rename to src/Attributes/Location/HasCountryCodeTrait.php index d2bda00..0d213e5 100644 --- a/src/Traits/Entities/Location/HasCountryCodeTrait.php +++ b/src/Attributes/Location/HasCountryCodeTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasCountryTrait.php b/src/Attributes/Location/HasCountryTrait.php similarity index 92% rename from src/Traits/Entities/Location/HasCountryTrait.php rename to src/Attributes/Location/HasCountryTrait.php index bf1d0bf..002129b 100644 --- a/src/Traits/Entities/Location/HasCountryTrait.php +++ b/src/Attributes/Location/HasCountryTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasDistrictTrait.php b/src/Attributes/Location/HasDistrictTrait.php similarity index 95% rename from src/Traits/Entities/Location/HasDistrictTrait.php rename to src/Attributes/Location/HasDistrictTrait.php index 1575258..132925c 100644 --- a/src/Traits/Entities/Location/HasDistrictTrait.php +++ b/src/Attributes/Location/HasDistrictTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasLatitudeTrait.php b/src/Attributes/Location/HasLatitudeTrait.php similarity index 92% rename from src/Traits/Entities/Location/HasLatitudeTrait.php rename to src/Attributes/Location/HasLatitudeTrait.php index d420947..b0e8d60 100644 --- a/src/Traits/Entities/Location/HasLatitudeTrait.php +++ b/src/Attributes/Location/HasLatitudeTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; /** * Trait for an Entity's Latitude attribute. diff --git a/src/Traits/Entities/Location/HasLongitudeTrait.php b/src/Attributes/Location/HasLongitudeTrait.php similarity index 92% rename from src/Traits/Entities/Location/HasLongitudeTrait.php rename to src/Attributes/Location/HasLongitudeTrait.php index bf5cc48..99ba66f 100644 --- a/src/Traits/Entities/Location/HasLongitudeTrait.php +++ b/src/Attributes/Location/HasLongitudeTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; /** * Trait for an Entity's Longitude attribute. diff --git a/src/Traits/Entities/Location/HasParishTrait.php b/src/Attributes/Location/HasParishTrait.php similarity index 95% rename from src/Traits/Entities/Location/HasParishTrait.php rename to src/Attributes/Location/HasParishTrait.php index 17102f1..24a0ab4 100644 --- a/src/Traits/Entities/Location/HasParishTrait.php +++ b/src/Attributes/Location/HasParishTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasPostalCodeTrait.php b/src/Attributes/Location/HasPostalCodeTrait.php similarity index 93% rename from src/Traits/Entities/Location/HasPostalCodeTrait.php rename to src/Attributes/Location/HasPostalCodeTrait.php index ef26abb..b133b0a 100644 --- a/src/Traits/Entities/Location/HasPostalCodeTrait.php +++ b/src/Attributes/Location/HasPostalCodeTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php b/src/Attributes/Location/HasStreetAdditionalTrait.php similarity index 93% rename from src/Traits/Entities/Location/HasStreetAdditionalTrait.php rename to src/Attributes/Location/HasStreetAdditionalTrait.php index 9876d96..7ae2782 100644 --- a/src/Traits/Entities/Location/HasStreetAdditionalTrait.php +++ b/src/Attributes/Location/HasStreetAdditionalTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasStreetNumberTrait.php b/src/Attributes/Location/HasStreetNumberTrait.php similarity index 93% rename from src/Traits/Entities/Location/HasStreetNumberTrait.php rename to src/Attributes/Location/HasStreetNumberTrait.php index 1cb3ddf..a766a12 100644 --- a/src/Traits/Entities/Location/HasStreetNumberTrait.php +++ b/src/Attributes/Location/HasStreetNumberTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/HasStreetTrait.php b/src/Attributes/Location/HasStreetTrait.php similarity index 92% rename from src/Traits/Entities/Location/HasStreetTrait.php rename to src/Attributes/Location/HasStreetTrait.php index 710b018..943e673 100644 --- a/src/Traits/Entities/Location/HasStreetTrait.php +++ b/src/Attributes/Location/HasStreetTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Location; +namespace HraDigital\Datatypes\Attributes\Location; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Location/README.md b/src/Attributes/Location/README.md similarity index 100% rename from src/Traits/Entities/Location/README.md rename to src/Attributes/Location/README.md diff --git a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php b/src/Attributes/Personal/HasCountryOfBirthTrait.php similarity index 94% rename from src/Traits/Entities/Personal/HasCountryOfBirthTrait.php rename to src/Attributes/Personal/HasCountryOfBirthTrait.php index ccbc773..8071b24 100644 --- a/src/Traits/Entities/Personal/HasCountryOfBirthTrait.php +++ b/src/Attributes/Personal/HasCountryOfBirthTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Personal; +namespace HraDigital\Datatypes\Attributes\Personal; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Personal/HasDateOfBirthTrait.php b/src/Attributes/Personal/HasDateOfBirthTrait.php similarity index 93% rename from src/Traits/Entities/Personal/HasDateOfBirthTrait.php rename to src/Attributes/Personal/HasDateOfBirthTrait.php index ede1773..1d29e5f 100644 --- a/src/Traits/Entities/Personal/HasDateOfBirthTrait.php +++ b/src/Attributes/Personal/HasDateOfBirthTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Personal; +namespace HraDigital\Datatypes\Attributes\Personal; use HraDigital\Datatypes\Datetime\Datetime; diff --git a/src/Traits/Entities/Personal/HasGenderTrait.php b/src/Attributes/Personal/HasGenderTrait.php similarity index 95% rename from src/Traits/Entities/Personal/HasGenderTrait.php rename to src/Attributes/Personal/HasGenderTrait.php index 650b761..2fe3e17 100644 --- a/src/Traits/Entities/Personal/HasGenderTrait.php +++ b/src/Attributes/Personal/HasGenderTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Personal; +namespace HraDigital\Datatypes\Attributes\Personal; use HraDigital\Datatypes\Exceptions\Entities\UnexpectedEntityValueException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Personal/HasNationalityTrait.php b/src/Attributes/Personal/HasNationalityTrait.php similarity index 95% rename from src/Traits/Entities/Personal/HasNationalityTrait.php rename to src/Attributes/Personal/HasNationalityTrait.php index bfe33a7..58aefe0 100644 --- a/src/Traits/Entities/Personal/HasNationalityTrait.php +++ b/src/Attributes/Personal/HasNationalityTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Personal; +namespace HraDigital\Datatypes\Attributes\Personal; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Personal/HasPhotoTrait.php b/src/Attributes/Personal/HasPhotoTrait.php similarity index 95% rename from src/Traits/Entities/Personal/HasPhotoTrait.php rename to src/Attributes/Personal/HasPhotoTrait.php index 3c397bd..136f5ce 100755 --- a/src/Traits/Entities/Personal/HasPhotoTrait.php +++ b/src/Attributes/Personal/HasPhotoTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Personal; +namespace HraDigital\Datatypes\Attributes\Personal; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Personal/README.md b/src/Attributes/Personal/README.md similarity index 100% rename from src/Traits/Entities/Personal/README.md rename to src/Attributes/Personal/README.md diff --git a/src/Traits/Entities/Professional/HasIndustryTrait.php b/src/Attributes/Professional/HasIndustryTrait.php similarity index 95% rename from src/Traits/Entities/Professional/HasIndustryTrait.php rename to src/Attributes/Professional/HasIndustryTrait.php index 5612ea4..d031cf3 100755 --- a/src/Traits/Entities/Professional/HasIndustryTrait.php +++ b/src/Attributes/Professional/HasIndustryTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Professional; +namespace HraDigital\Datatypes\Attributes\Professional; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Professional/HasOccupationTrait.php b/src/Attributes/Professional/HasOccupationTrait.php similarity index 96% rename from src/Traits/Entities/Professional/HasOccupationTrait.php rename to src/Attributes/Professional/HasOccupationTrait.php index fac0a76..36f364c 100755 --- a/src/Traits/Entities/Professional/HasOccupationTrait.php +++ b/src/Attributes/Professional/HasOccupationTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Professional; +namespace HraDigital\Datatypes\Attributes\Professional; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/Professional/README.md b/src/Attributes/Professional/README.md similarity index 100% rename from src/Traits/Entities/Professional/README.md rename to src/Attributes/Professional/README.md diff --git a/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php b/src/Attributes/SocialMedia/HasFacebookProfileTrait.php similarity index 94% rename from src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php rename to src/Attributes/SocialMedia/HasFacebookProfileTrait.php index 76d1d94..dd17fb6 100755 --- a/src/Traits/Entities/SocialMedia/HasFacebookProfileTrait.php +++ b/src/Attributes/SocialMedia/HasFacebookProfileTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\SocialMedia; +namespace HraDigital\Datatypes\Attributes\SocialMedia; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php b/src/Attributes/SocialMedia/HasInstagramProfileTrait.php similarity index 94% rename from src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php rename to src/Attributes/SocialMedia/HasInstagramProfileTrait.php index df0e352..11379c5 100755 --- a/src/Traits/Entities/SocialMedia/HasInstagramProfileTrait.php +++ b/src/Attributes/SocialMedia/HasInstagramProfileTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\SocialMedia; +namespace HraDigital\Datatypes\Attributes\SocialMedia; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php b/src/Attributes/SocialMedia/HasLinkedinProfileTrait.php similarity index 94% rename from src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php rename to src/Attributes/SocialMedia/HasLinkedinProfileTrait.php index 578e719..49666aa 100755 --- a/src/Traits/Entities/SocialMedia/HasLinkedinProfileTrait.php +++ b/src/Attributes/SocialMedia/HasLinkedinProfileTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\SocialMedia; +namespace HraDigital\Datatypes\Attributes\SocialMedia; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php b/src/Attributes/SocialMedia/HasTwitterProfileTrait.php similarity index 94% rename from src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php rename to src/Attributes/SocialMedia/HasTwitterProfileTrait.php index 57423ff..bde4923 100755 --- a/src/Traits/Entities/SocialMedia/HasTwitterProfileTrait.php +++ b/src/Attributes/SocialMedia/HasTwitterProfileTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\SocialMedia; +namespace HraDigital\Datatypes\Attributes\SocialMedia; use HraDigital\Datatypes\Scalar\Str; diff --git a/src/Traits/Entities/SocialMedia/README.md b/src/Attributes/SocialMedia/README.md similarity index 100% rename from src/Traits/Entities/SocialMedia/README.md rename to src/Attributes/SocialMedia/README.md diff --git a/src/Traits/Entities/Timezone/HasTimestampTrait.php b/src/Attributes/Timezone/HasTimestampTrait.php similarity index 92% rename from src/Traits/Entities/Timezone/HasTimestampTrait.php rename to src/Attributes/Timezone/HasTimestampTrait.php index 9cca458..2d3645f 100755 --- a/src/Traits/Entities/Timezone/HasTimestampTrait.php +++ b/src/Attributes/Timezone/HasTimestampTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Datatypes\Traits\Entities\Timezone; +namespace HraDigital\Datatypes\Attributes\Timezone; /** * Trait for an Entity's Timestamp attribute. diff --git a/src/Traits/Entities/Timezone/README.md b/src/Attributes/Timezone/README.md similarity index 100% rename from src/Traits/Entities/Timezone/README.md rename to src/Attributes/Timezone/README.md diff --git a/tests/Unit/Attributes/GeneralTraitsVO.php b/tests/Unit/Attributes/GeneralTraitsVO.php new file mode 100644 index 0000000..feae6ff --- /dev/null +++ b/tests/Unit/Attributes/GeneralTraitsVO.php @@ -0,0 +1,59 @@ +triggerOnUpdate(); + } +} diff --git a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php b/tests/Unit/Attributes/GeneralTraitsVOTest.php similarity index 99% rename from tests/Unit/Traits/Entities/GeneralTraitsVOTest.php rename to tests/Unit/Attributes/GeneralTraitsVOTest.php index 689b8da..e7a2cc1 100644 --- a/tests/Unit/Traits/Entities/GeneralTraitsVOTest.php +++ b/tests/Unit/Attributes/GeneralTraitsVOTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace HraDigital\Tests\Datatypes\Unit\Traits\Entities; +namespace HraDigital\Tests\Datatypes\Unit\Attributes; use HraDigital\Datatypes\Exceptions\Datatypes\InvalidStringLengthException; use HraDigital\Datatypes\Exceptions\Datatypes\NonEmptyStringException; diff --git a/tests/Unit/Attributes/LocationTraitsVO.php b/tests/Unit/Attributes/LocationTraitsVO.php new file mode 100644 index 0000000..2bc9ec8 --- /dev/null +++ b/tests/Unit/Attributes/LocationTraitsVO.php @@ -0,0 +1,44 @@ +triggerOnUpdate(); - } -} diff --git a/tests/Unit/Traits/Entities/LocationTraitsVO.php b/tests/Unit/Traits/Entities/LocationTraitsVO.php deleted file mode 100644 index a7ad917..0000000 --- a/tests/Unit/Traits/Entities/LocationTraitsVO.php +++ /dev/null @@ -1,44 +0,0 @@ - Date: Tue, 22 Mar 2022 18:01:54 +0000 Subject: [PATCH 190/193] tests: update attribute's namespaces --- tests/Unit/ValueObjects/TestingNestedValueObject.php | 7 +++---- tests/Unit/ValueObjects/TestingValueObject.php | 10 +++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/Unit/ValueObjects/TestingNestedValueObject.php b/tests/Unit/ValueObjects/TestingNestedValueObject.php index 75fd247..e2b4d7a 100644 --- a/tests/Unit/ValueObjects/TestingNestedValueObject.php +++ b/tests/Unit/ValueObjects/TestingNestedValueObject.php @@ -9,10 +9,9 @@ use HraDigital\Datatypes\Traits\Entities\CanMassAssignStateTrait; use HraDigital\Datatypes\Traits\Entities\CanProcessEntityStateTrait; use HraDigital\Datatypes\Traits\Entities\CanProcessOnUpdateEventsTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasActiveTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasEmailTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasTitleTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasUpdatableUpdatedAtTrait; +use HraDigital\Datatypes\Attributes\General\HasActiveTrait; +use HraDigital\Datatypes\Attributes\General\HasTitleTrait; +use HraDigital\Datatypes\Attributes\General\HasUpdatableUpdatedAtTrait; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; /** diff --git a/tests/Unit/ValueObjects/TestingValueObject.php b/tests/Unit/ValueObjects/TestingValueObject.php index 71e4a71..8b9eedb 100644 --- a/tests/Unit/ValueObjects/TestingValueObject.php +++ b/tests/Unit/ValueObjects/TestingValueObject.php @@ -9,11 +9,11 @@ use HraDigital\Datatypes\Traits\Entities\CanMassAssignStateTrait; use HraDigital\Datatypes\Traits\Entities\CanProcessEntityStateTrait; use HraDigital\Datatypes\Traits\Entities\CanProcessOnUpdateEventsTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasActiveTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasEmailTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasPositiveIntegerIDTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasTitleTrait; -use HraDigital\Datatypes\Traits\Entities\General\HasUpdatableUpdatedAtTrait; +use HraDigital\Datatypes\Attributes\General\HasActiveTrait; +use HraDigital\Datatypes\Attributes\General\HasEmailTrait; +use HraDigital\Datatypes\Attributes\General\HasPositiveIntegerIDTrait; +use HraDigital\Datatypes\Attributes\General\HasTitleTrait; +use HraDigital\Datatypes\Attributes\General\HasUpdatableUpdatedAtTrait; use HraDigital\Datatypes\ValueObjects\AbstractValueObject; /** From 7e8e2393612ab9f18b40810f2555de3d32128c2c Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 22 Mar 2022 18:25:48 +0000 Subject: [PATCH 191/193] BREAKING CHANGE: rename getter methods for EmailAddress --- src/Web/EmailAddress.php | 10 +++++----- tests/Unit/Web/EmailAddressTest.php | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 741c8df..5e4876c 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -105,7 +105,7 @@ public function __unserialize(array $data): void */ public function __toString(): string { - return (string) $this->address(); + return (string) $this->getAddress(); } /** @@ -113,7 +113,7 @@ public function __toString(): string * * @return string */ - public function address(): Str + public function getAddress(): Str { return Str::create( \sprintf( @@ -130,7 +130,7 @@ public function address(): Str * * @return string */ - public function username(): Str + public function getUsername(): Str { return $this->username; } @@ -140,7 +140,7 @@ public function username(): Str * * @return string */ - public function domain(): Str + public function getDomain(): Str { return $this->domain; } @@ -150,7 +150,7 @@ public function domain(): Str * * @return string */ - public function tld(): Str + public function GetTld(): Str { return $this->tld; } diff --git a/tests/Unit/Web/EmailAddressTest.php b/tests/Unit/Web/EmailAddressTest.php index 4916f60..c5f0701 100644 --- a/tests/Unit/Web/EmailAddressTest.php +++ b/tests/Unit/Web/EmailAddressTest.php @@ -40,22 +40,22 @@ public function testLoadsSuccessfully(): void ); $this->assertEquals( $emailString, - (string) $email->address(), + (string) $email->getAddress(), 'Addresses do not match.' ); $this->assertEquals( 'user', - (string) $email->username(), + (string) $email->getUsername(), 'Usernames do not match.' ); $this->assertEquals( 'domain', - (string) $email->domain(), + (string) $email->getDomain(), 'Domains do not match.' ); $this->assertEquals( 'tld', - (string) $email->tld(), + (string) $email->GetTld(), 'TLDs do not match.' ); } From 4c7c059c77c6d3d8899471bdb9e9511cf57403ed Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 22 Mar 2022 18:29:26 +0000 Subject: [PATCH 192/193] docs: improve documentation and code examples --- README.md | 1 + src/Attributes/README.md | 35 +++++++++++++++++++++++++++++++ src/README.md | 4 ++-- src/Traits/Datetime/README.md | 1 + src/Traits/Entities/README.md | 1 + src/Traits/README.md | 4 +++- src/Traits/ValueObjects/README.md | 2 +- 7 files changed, 44 insertions(+), 4 deletions(-) create mode 100755 src/Attributes/README.md create mode 100755 src/Traits/Datetime/README.md create mode 100755 src/Traits/Entities/README.md diff --git a/README.md b/README.md index b434a92..bacc907 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # PHP Datatypes ## Master branch build status + [![Build](https://img.shields.io/circleci/build/github/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) [![Coverage](https://img.shields.io/codecov/c/github/HRADigital/php-datatypes.svg)](https://github.com/HRADigital/php-datatypes) [![Quality](https://app.codacy.com/project/badge/Grade/de03155208c64196899848458c2ced8a)](https://www.codacy.com/gh/HRADigital/php-datatypes/dashboard?utm_source=github.com&utm_medium=referral&utm_content=HRADigital/php-datatypes&utm_campaign=Badge_Grade) diff --git a/src/Attributes/README.md b/src/Attributes/README.md new file mode 100755 index 0000000..88ed938 --- /dev/null +++ b/src/Attributes/README.md @@ -0,0 +1,35 @@ +# Attribute's related Traits + +In this namespace, you'll several Traits for individual fields, that will help you build your Aggregates/Entities/Value Objects. + +Each individual Trait, contains minimum functionality for a specific field. + +When adding each of these Traits to your object, you'll automatically add minimum state handling for that specific field. + +## Attribute Loading + +On the following example, you can see an object with an e-mail address being created: + +```php +use HraDigital\Datatypes\Attributes\General\HasEmailTrait; +use HraDigital\Datatypes\ValueObjects\AbstractValueObject; + +class MyObject extends AbstractValueObject +{ + use HasEmailTrait; +} +``` + +## Attribute Accessing + +You can load and access the object's data in the following manner: + +```php +$object = new MyObject([ + 'email' => 'my.email.address@domain.tld', +]); + +echo $object->getEmail(); // my.email.address@domain.tld +echo $object->getEmail()->getUsername()->toUpper(); // MY.EMAIL.ADDRESS + +``` diff --git a/src/README.md b/src/README.md index 5f93644..d5add8d 100755 --- a/src/README.md +++ b/src/README.md @@ -10,9 +10,9 @@ can facilitate the creation of strongly typed records. For more information about each type of available object, please read dedicated information: -- [Aggregates](Aggregates/) +- [Attributes](Attributes/) - [Collections](Collections/) -- [Entities](Entities/) +- [Datetime](Datetime/) - [Exceptions](Exceptions/) - [Scalar](Scalar/) - [Traits](Traits/) diff --git a/src/Traits/Datetime/README.md b/src/Traits/Datetime/README.md new file mode 100755 index 0000000..72e2465 --- /dev/null +++ b/src/Traits/Datetime/README.md @@ -0,0 +1 @@ +# Datetime object's configuration Traits diff --git a/src/Traits/Entities/README.md b/src/Traits/Entities/README.md new file mode 100755 index 0000000..b83a7f1 --- /dev/null +++ b/src/Traits/Entities/README.md @@ -0,0 +1 @@ +# Entity's configuration Traits diff --git a/src/Traits/README.md b/src/Traits/README.md index 276ea70..13a3449 100755 --- a/src/Traits/README.md +++ b/src/Traits/README.md @@ -1 +1,3 @@ -# Entity related Traits +# Object building related Traits + +In this namespace, you'll find Traits that will help configure your objects. diff --git a/src/Traits/ValueObjects/README.md b/src/Traits/ValueObjects/README.md index 94da8ac..f1558dd 100755 --- a/src/Traits/ValueObjects/README.md +++ b/src/Traits/ValueObjects/README.md @@ -1 +1 @@ -# Value Object's related Traits +# Value Object's configuration Traits From 2c362b6984df553ef7fcc85eff4968ec4a3397f4 Mon Sep 17 00:00:00 2001 From: Hugo Rafael Azevedo Date: Tue, 22 Mar 2022 18:31:26 +0000 Subject: [PATCH 193/193] BREAKING CHANGE: fix getter method in EmailAddress --- src/Web/EmailAddress.php | 2 +- tests/Unit/Web/EmailAddressTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Web/EmailAddress.php b/src/Web/EmailAddress.php index 5e4876c..e91fe5f 100644 --- a/src/Web/EmailAddress.php +++ b/src/Web/EmailAddress.php @@ -150,7 +150,7 @@ public function getDomain(): Str * * @return string */ - public function GetTld(): Str + public function getTld(): Str { return $this->tld; } diff --git a/tests/Unit/Web/EmailAddressTest.php b/tests/Unit/Web/EmailAddressTest.php index c5f0701..e82eada 100644 --- a/tests/Unit/Web/EmailAddressTest.php +++ b/tests/Unit/Web/EmailAddressTest.php @@ -55,7 +55,7 @@ public function testLoadsSuccessfully(): void ); $this->assertEquals( 'tld', - (string) $email->GetTld(), + (string) $email->getTld(), 'TLDs do not match.' ); }