From b4f4fe25b9e0e235a7ea59a6be6a0fd2a9615e22 Mon Sep 17 00:00:00 2001 From: Matias Navarro Carter Date: Fri, 20 Nov 2020 11:51:33 +0000 Subject: [PATCH] [BC] New Version This version simplifies the api a lot, eliminating unnecesary complexity and reducing the library to a few classes only. --- .github/workflows/pr.yml | 122 +++++++++ .gitignore | 2 +- .gitlab-ci.yml | 26 -- .php_cs.dist | 35 +-- CHANGELOG.md | 18 -- LICENSE | 2 +- Makefile | 8 - README.md | 236 +++++------------- composer.json | 21 +- phpunit.xml.dist | 29 +-- psalm.xml.dist | 54 ++++ src/Bridge/Symfony/Form/RutType.php | 75 ------ src/Bridge/Symfony/Validator/IsValidRut.php | 21 -- .../Symfony/Validator/IsValidRutValidator.php | 65 ----- src/Doctrine/NumericRutType.php | 74 ++++++ .../DBAL/Types => Doctrine}/RutType.php | 42 ++-- src/Exception/InvalidRutException.php | 49 ---- src/FormattedRut.php | 87 +++++++ src/InvalidRut.php | 35 +++ src/Rut.php | 226 +++++++---------- src/Util/CorrelativeUtils.php | 81 ------ src/Validator/ChainRutValidator.php | 52 ---- src/Validator/Module11RutValidator.php | 37 --- src/Validator/RutValidator.php | 43 ---- tests/Bridge/Symfony/Form/RutTypeTest.php | 41 --- tests/Doctrine/NumericRutTypeTest.php | 51 ++++ tests/Doctrine/RutTypeTest.php | 59 +++++ tests/FormattedRutTest.php | 54 ++++ tests/Rut/RutTest.php | 82 ------ tests/RutTest.php | 86 +++++++ tests/Validator/ChainRutValidatorTest.php | 56 ----- tests/Validator/SimpleRutValidatorTest.php | 39 --- 32 files changed, 847 insertions(+), 1061 deletions(-) create mode 100644 .github/workflows/pr.yml delete mode 100644 .gitlab-ci.yml delete mode 100644 CHANGELOG.md delete mode 100644 Makefile create mode 100644 psalm.xml.dist delete mode 100644 src/Bridge/Symfony/Form/RutType.php delete mode 100644 src/Bridge/Symfony/Validator/IsValidRut.php delete mode 100644 src/Bridge/Symfony/Validator/IsValidRutValidator.php create mode 100644 src/Doctrine/NumericRutType.php rename src/{Bridge/Doctrine/DBAL/Types => Doctrine}/RutType.php (53%) delete mode 100644 src/Exception/InvalidRutException.php create mode 100644 src/FormattedRut.php create mode 100644 src/InvalidRut.php delete mode 100644 src/Util/CorrelativeUtils.php delete mode 100644 src/Validator/ChainRutValidator.php delete mode 100644 src/Validator/Module11RutValidator.php delete mode 100644 src/Validator/RutValidator.php delete mode 100644 tests/Bridge/Symfony/Form/RutTypeTest.php create mode 100644 tests/Doctrine/NumericRutTypeTest.php create mode 100644 tests/Doctrine/RutTypeTest.php create mode 100644 tests/FormattedRutTest.php delete mode 100644 tests/Rut/RutTest.php create mode 100644 tests/RutTest.php delete mode 100644 tests/Validator/ChainRutValidatorTest.php delete mode 100644 tests/Validator/SimpleRutValidatorTest.php diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..bb8c5a0 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,122 @@ +name: "Review PR" + +on: + pull_request: + + +env: + COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --no-suggest --prefer-dist" + +jobs: + + # This job ensures the coding standard is followed + coding-standards: + name: "Coding Standards" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + php-version: + - "7.4" + operating-system: + - "ubuntu-latest" + steps: + - name: "Checkout Code" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + tools: composer:v2 + - name: Get Composer Cache Directory + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: "composer-cache" + restore-keys: "composer-cache" + - name: "Install dependencies" + run: "composer install ${{ env.COMPOSER_FLAGS }}" + - name: "Coding Standard" + run: "vendor/bin/php-cs-fixer fix --dry-run -vvv" + + type-analysis: + name: "Type Coverage" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + php-version: + - "7.4" + operating-system: + - "ubuntu-latest" + steps: + - name: "Checkout Code" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + tools: composer:v2 + - name: Get Composer Cache Directory + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: "composer-cache" + restore-keys: "composer-cache" + - name: "Install dependencies" + run: "composer install ${{ env.COMPOSER_FLAGS }}" + - name: "Run Psalm" + run: "vendor/bin/psalm --output-format=github --shepherd --stats" + continue-on-error: true + + unit-test: + name: "Unit Testing" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + dependencies: + - "lowest" + - "highest" + php-version: + - "7.4" + - "8.0" + operating-system: + - "ubuntu-latest" + steps: + - name: "Checkout Code" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + tools: composer:v2 + - name: Get Composer Cache Directory + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: "composer-cache" + restore-keys: "composer-cache" + - name: "Install lowest dependencies" + if: ${{ matrix.dependencies == 'lowest' }} + run: "composer update ${{ env.COMPOSER_FLAGS }} --prefer-lowest --ignore-platform-reqs" + - name: "Install highest dependencies" + if: ${{ matrix.dependencies == 'highest' }} + run: "composer install ${{ env.COMPOSER_FLAGS }} --ignore-platform-reqs" + - name: "Run PHPUnit" + run: "vendor/bin/phpunit --testdox --coverage-text" diff --git a/.gitignore b/.gitignore index 5dd6157..1f3bcce 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ vendor composer.lock .idea .php_cs.cache -build \ No newline at end of file +.phpunit.result.cache \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 8aac6f1..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,26 +0,0 @@ -image: alpine:3.8 - -# This configures the whole environment -before_script: - # Install git, make, zip and php + extensions - - ping -c 3 alpinelinux.org - - apk add --no-cache git curl make gcc unzip php7 php7-mcrypt php7-intl php7-gettext php7-ctype php7-curl php7-dom php7-fileinfo php7-ftp php7-iconv php7-json php7-mbstring php7-mysqlnd php7-openssl php7-pdo php7-pdo_sqlite php7-pear php7-phar php7-posix php7-session php7-simplexml php7-sqlite3 php7-tokenizer php7-xml php7-xmlreader php7-xmlwriter php7-zlib php7-xdebug - # Enable xDebug for coverage report - - echo "zend_extension=/usr/lib/php7/modules/xdebug.so" >> /etc/php7/php.ini - - echo "xdebug.coverage_enable=1" >> /etc/php7/php.ini - # Display php version - - php -v - # Install and run composer - - curl --location --output /usr/local/bin/composer https://getcomposer.org/download/1.7.3/composer.phar - - chmod +x /usr/local/bin/composer - - composer install --ansi - -test: - cache: - key: ${CI_COMMIT_REF_SLUG} - paths: - - vendor/ - script: - - php vendor/bin/phpunit --coverage-text --colors=never - only: - - branches diff --git a/.php_cs.dist b/.php_cs.dist index 3ad427d..2ed7627 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -1,32 +1,35 @@ For the full copyright and license information, please view the LICENSE file that was distributed with this source code. EOF; return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) ->setRules([ '@Symfony' => true, 'array_syntax' => ['syntax' => 'short'], - 'combine_consecutive_unsets' => true, - 'header_comment' => ['header' => $header], - 'linebreak_after_opening_tag' => true, - 'no_php4_constructor' => true, - 'no_useless_else' => true, - 'ordered_class_elements' => true, - 'ordered_imports' => true, - 'php_unit_construct' => true, - 'php_unit_strict' => true, - 'phpdoc_no_empty_return' => false, + 'declare_strict_types' => true, + 'strict_comparison' => true, + 'phpdoc_no_empty_return' => true, + 'header_comment' => ['header' => $header, 'comment_type' => 'PHPDoc'], + 'yoda_style' => [ + 'equal' => false, + 'identical' => false, + 'less_and_greater' => false, + 'always_move_variable' => true + ], ]) - ->setUsingCache(true) - ->setRiskyAllowed(true) ->setFinder( PhpCsFixer\Finder::create() - ->in(__DIR__) + ->in(__DIR__.'/src') ) -; +; \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index a3dacd9..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,18 +0,0 @@ -# CHANGELOG - -## v1.0.0 (08.08.2018) -- Create Initial Classes (Rut, Validator, ChainRutValidator) -- Tested Rut -- Tested SimpleRutValidator -- Tested Symfony Form Type - -## v2.0.0 (12.10.2018) -This is a major version because api changes and class renaming took place. -Also, all features were properly tested with CI/CD pipelines. - -- Changed ChainRutValidator constructor signature. Now uses argument spreading. -- Added tests for ChainRutValidator -- SimpleRutValidator renamed to Module11RutValidator -- Now class Rut always validates itself with the SimpleRutValidator if no validator -is passed. This ensures object consistency. -- Added test coverage reports, code quality and CI testing \ No newline at end of file diff --git a/LICENSE b/LICENSE index a228932..18d00fd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018 Matías Navarro Carter +Copyright (c) 2020 Matías Navarro Carter Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile deleted file mode 100644 index 22f84c1..0000000 --- a/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -coverage: - vendor/bin/phpunit --coverage-text - -cs: - vendor/bin/php-cs-fixer fix --diff --verbose - -commit: cs coverage - git add . && git commit \ No newline at end of file diff --git a/README.md b/README.md index d2f02ea..8180895 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,9 @@ Rut Chileno =========== -Esta librería implementa una clase Rut como un *value object* inmutable, incluyendo -una api de validación flexible y extendible. +Esta librería implementa una clase Rut como un sencillo *value object* inmutable. -Además, posee un validador para `symfony/validator`, un *form type* para `symfony/form` -y un *type* para `doctrine/dbal`. - -Sólo es compatible con PHP 7.1 o superior. +Además, posee dos *types* para `doctrine/dbal`. ## Instalación @@ -18,195 +14,101 @@ composer require mnavarrocarter/chilean-rut ``` ## Uso -Simplemente instancia una nueva clase con un rut en cualquier formato: + +### Parseando un Rut + +La clase Rut es capaz de parsear cualquier tipo de rut sin importar el formato usando +el método `Rut::parse()`. Confiadamente puedes poner el valor directamente de un +formulario web y `parse` se encargara de sanitizar el string y ver si el RUT es valido. + +```php + TLDR: Un objeto `Rut` siempre será valido. + +Si tu RUT no es valido, el método `parse` lanzara una excepción de tipo +`MNC\ChileanRut\InvalidRut`. Esto es para seguir buenos principios de *objects +calisthenics*: un objeto de valor siempre se crea en un estado valido, y se mantiene +valido a través de todo su ciclo de vida. No se permiten mutaciones que dejen el +objeto en un estado invalido. + +Por esta razón el objecto `$rut` es completamente inmutable. Esto quiere decir +que una vez creado no puedes cambiar su estado interno: solo puedes leer información. +Estos son los unicos métodos que puedes usar: ```php getNumber(); // (int) 23546565 +$rut->getVerifier(); // (string) 4 ``` -Por defecto, la clase Rut se valida usando el `Module11RutValidator` si no se pasa -un validador personalizado al momento de instanciación. Esto es para asegurar la -integridad del objeto. +### Formateando el Rut -Si quieres, por alguna extraña razón, deshacerte de esa validación, puedes crear -un `AlwaysValidRutValidator` implementando la interfaz `RutValidator`. El método -validate estaría en blanco, lo que haría pasar la validación sin problema. - -```php -rutChecker = $rutChecker; - } - - /** - * @param Rut $rut - */ - public function validate(Rut $rut) : void - { - // Por debajo, esta clase ficticia haría una llamada a un web service preguntando - // si el Rut existe. - if ($this->rutChecker->doesRutExist($rut->format())) { - return; - } - throw new InvalidRutException($rut, 'This rut does not exist'); - } -} - -``` - -> NOTA: La implementación de cualquier validador DEBE arrojar un InvalidRutException cuando -el Rut no es válido. De lo contrario, el Rut se toma como válido. - -### Usando múltiples validadores -Proveemos un `ChainRutValidator` que puedes usar para validar un rut contra múltiples -validadores. Esto permite ejecutar cadenas de validación, como ver primero si un rut es -válido algorítmicamente antes de verificarlo contra un web service. - -Usarlo es simple: - -```php -validate($rut); -``` - -### Formateando Ruts a String - -Una vez creado el objeto Rut, puedes formatearlo a string en el formato que tu quieras. -Esto se hace a través del método format y cómo parámetro acepta el valor -de una de las constantes `FORMAT_` de la clase Rut. +Existen muchas formas distintas de formatear un rut y esta librería soporta muchas +de ellas. El método format devuelve un objeto al cual puedes encadenar llamadas para +formatear el rut y luego castearlo a un string. La interfaz es encadenable para que +puedas combinar las opciones de formato como quieras. ```php format(Rut::FORMAT_CLEAR); // Va a imprimir 342442234 -echo $rut->format(Rut::FORMAT_READABLE); // Va a imprimir 34.244.223-4 -echo $rut->format(Rut::FORMAT_HYPHENED); // Va a imprimir 34244223-4 -echo $rut->format(Rut::FORMAT_HIDDEN); // Va a imprimir 34.***.***-4 +echo $rut->format()->hyphened(); // 23546565-4 +echo $rut->format()->dotted()->hyphened(); // 23.546.565-2 +echo $rut->format()->dotted()->hyphened()->obfuscated(); // **.***.565-2 +echo $rut->format()->obfuscated()->hyphened(); // *****565-2 +echo $rut->format()->obfuscated(); // *****5652 ``` -### Utilidades -Esta librería provee una clase llamada `CorrelativeUtils` que tiene algunas utilidades -interesantes. Posee tres métodos: - -```php - - - + + + + ./src + + ./tests - - - - ./src - - - - \ No newline at end of file + diff --git a/psalm.xml.dist b/psalm.xml.dist new file mode 100644 index 0000000..7da42dd --- /dev/null +++ b/psalm.xml.dist @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Bridge/Symfony/Form/RutType.php b/src/Bridge/Symfony/Form/RutType.php deleted file mode 100644 index d5ab58c..0000000 --- a/src/Bridge/Symfony/Form/RutType.php +++ /dev/null @@ -1,75 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Bridge\Symfony\Form; - -use MNC\ChileanRut\Rut; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\DataTransformerInterface; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class RutType. - * - * @author Matías Navarro Carter - */ -class RutType extends AbstractType implements DataTransformerInterface -{ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $builder->addModelTransformer($this); - } - - /** - * @param OptionsResolver $resolver - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([ - 'compound' => false, - 'data_class' => Rut::class, - 'empty_data' => function (FormInterface $form) { - return new Rut($form->getData()); - }, - ]); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix(): ?string - { - return 'rut'; - } - - /** - * @param mixed $value - * - * @return mixed|string - */ - public function transform($value) - { - if ($value instanceof Rut) { - return $value->format(Rut::FORMAT_READABLE); - } - } - - /** - * @param mixed $value - * - * @return mixed|Rut - */ - public function reverseTransform($value) - { - return new Rut((string) $value); - } -} diff --git a/src/Bridge/Symfony/Validator/IsValidRut.php b/src/Bridge/Symfony/Validator/IsValidRut.php deleted file mode 100644 index 2df942d..0000000 --- a/src/Bridge/Symfony/Validator/IsValidRut.php +++ /dev/null @@ -1,21 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Bridge\Symfony\Validator; - -use Symfony\Component\Validator\Constraint; - -/** - * @Annotation - */ -class IsValidRut extends Constraint -{ - public $message = '"{{value}}" is not a valid Rut.'; -} diff --git a/src/Bridge/Symfony/Validator/IsValidRutValidator.php b/src/Bridge/Symfony/Validator/IsValidRutValidator.php deleted file mode 100644 index 85c4fb2..0000000 --- a/src/Bridge/Symfony/Validator/IsValidRutValidator.php +++ /dev/null @@ -1,65 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Bridge\Symfony\Validator; - -use MNC\ChileanRut\Exception\InvalidRutException; -use MNC\ChileanRut\Rut; -use MNC\ChileanRut\Validator\Module11RutValidator; -use MNC\ChileanRut\Validator\RutValidator; -use Symfony\Component\Form\Exception\UnexpectedTypeException; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; - -/** - * Class IsValidRutValidator. - * - * @author Matías Navarro Carter - */ -class IsValidRutValidator extends ConstraintValidator -{ - /** - * @var RutValidator - */ - private $validator; - - /** - * IsValidRutValidator constructor. - * - * @param RutValidator|null $validator - */ - public function __construct(RutValidator $validator = null) - { - $this->validator = $validator ?? new Module11RutValidator(); - } - - /** - * @param mixed $value - * @param Constraint $constraint - */ - public function validate($value, Constraint $constraint): void - { - if (null === $value || '' === $value) { - return; - } - - if (!$value instanceof Rut) { - throw new UnexpectedTypeException($value, Rut::class); - } - - try { - $this->validator->validate($value); - } catch (InvalidRutException $exception) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $value->format(Rut::FORMAT_CLEAR)) - ->addViolation(); - } - } -} diff --git a/src/Doctrine/NumericRutType.php b/src/Doctrine/NumericRutType.php new file mode 100644 index 0000000..5e4c6ab --- /dev/null +++ b/src/Doctrine/NumericRutType.php @@ -0,0 +1,74 @@ +getNumber(); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', Rut::class]); + } + + /** + * @param mixed $value + * + * @return mixed + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + $value = parent::convertToPHPValue($value, $platform); + + if ($value === null) { + return $value; + } + + return Rut::create($value); + } +} diff --git a/src/Bridge/Doctrine/DBAL/Types/RutType.php b/src/Doctrine/RutType.php similarity index 53% rename from src/Bridge/Doctrine/DBAL/Types/RutType.php rename to src/Doctrine/RutType.php index bc0e0e3..3409325 100644 --- a/src/Bridge/Doctrine/DBAL/Types/RutType.php +++ b/src/Doctrine/RutType.php @@ -1,14 +1,20 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace MNC\ChileanRut\Bridge\Doctrine\DBAL\Types; +namespace MNC\ChileanRut\Doctrine; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\ConversionException; @@ -16,25 +22,22 @@ use Doctrine\DBAL\Types\StringType; use MNC\ChileanRut\Rut; /** - * Class RutType. + * Class RutTextType. * - * @author Matías Navarro Carter + * This type maps the rut to a string and stores it with the verifier number, + * including dots and the hyphen. */ class RutType extends StringType { public const NAME = 'rut'; - /** - * @return string - */ public function getName(): string { return self::NAME; } /** - * @param mixed $value - * @param AbstractPlatform $platform + * @param mixed $value * * @return mixed * @@ -42,29 +45,34 @@ class RutType extends StringType */ public function convertToDatabaseValue($value, AbstractPlatform $platform) { - if (null === $value) { + if ($value === null) { return $value; } if ($value instanceof Rut) { - return $value->format(Rut::FORMAT_HYPHENED); + return (string) $value->format()->hyphened()->dotted(); } throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', Rut::class]); } /** - * @param mixed $value - * @param AbstractPlatform $platform + * @param mixed $value * * @return mixed + * + * @throws ConversionException */ public function convertToPHPValue($value, AbstractPlatform $platform) { - if (null === $value || $value instanceof Rut) { + if ($value === null) { return $value; } - return new Rut($value); + if (is_string($value)) { + return Rut::parse($value); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'string']); } } diff --git a/src/Exception/InvalidRutException.php b/src/Exception/InvalidRutException.php deleted file mode 100644 index 8a2f2dc..0000000 --- a/src/Exception/InvalidRutException.php +++ /dev/null @@ -1,49 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Exception; - -use MNC\ChileanRut\Rut; - -/** - * Class InvalidRutException. - * - * @author Matías Navarro Carter - */ -class InvalidRutException extends \LogicException -{ - /** - * @var Rut - */ - private $rut; - - /** - * InvalidRutException constructor. - * - * @param Rut $rut - * @param string|null $message - */ - public function __construct(Rut $rut, string $message = null) - { - if (null === $message) { - $message = sprintf('Rut %s is not a valid rut.', $rut->format(Rut::FORMAT_READABLE)); - } - $this->rut = $rut; - parent::__construct($message); - } - - /** - * @return Rut - */ - public function getRut(): Rut - { - return $this->rut; - } -} diff --git a/src/FormattedRut.php b/src/FormattedRut.php new file mode 100644 index 0000000..026f7c0 --- /dev/null +++ b/src/FormattedRut.php @@ -0,0 +1,87 @@ +rut = $rut; + $this->flags = 0; + } + + public function hyphened(): FormattedRut + { + return $this->add(self::HYPHENED); + } + + public function dotted(): FormattedRut + { + return $this->add(self::DOTTED); + } + + public function obfuscated(): FormattedRut + { + return $this->add(self::OBFUSCATED); + } + + private function add(int $flag): FormattedRut + { + $clone = clone $this; + $clone->flags += $flag; + + return $clone; + } + + public function __toString(): string + { + $number = (string) $this->rut->getNumber(); + $verifier = $this->rut->getVerifier(); + if ($this->has(self::OBFUSCATED)) { + $replace = str_repeat('*', strlen($number) - 3); + $number = substr_replace($number, $replace, 0, -3); + } + + if ($this->has(self::DOTTED)) { + $number = substr_replace($number, '.', -3, 0); + $number = substr_replace($number, '.', -7, 0); + } + if ($this->has(self::HYPHENED)) { + return $number.'-'.$verifier; + } + + return $number.$verifier; + } + + private function has(int $flag): bool + { + return ($this->flags & $flag) !== 0; + } +} diff --git a/src/InvalidRut.php b/src/InvalidRut.php new file mode 100644 index 0000000..f89b048 --- /dev/null +++ b/src/InvalidRut.php @@ -0,0 +1,35 @@ + * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace MNC\ChileanRut; -use MNC\ChileanRut\Validator\Module11RutValidator; -use MNC\ChileanRut\Validator\RutValidator; - /** * Rut represents a the Chilean National ID Number. * - * All residents of Chile are uniquely identified by one of these. - * - * @author Matías Navarro Carter + * All residents of Chile are uniquely identified by one of these and it is + * mainly used for tax purposes. */ class Rut { - public const FORMAT_HYPHENED = 0; // 14533535-5 - public const FORMAT_CLEAR = 1; // 145335355 - public const FORMAT_READABLE = 2; // 14.533.535-5 - public const FORMAT_HIDDEN = 3; // 17.***.***-5 + private const VALID_VERIFIERS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'K']; /** - * @var string + * The actual RUT number. */ - private $value; + private int $number; /** - * @var string + * The RUT verifier digit. */ - private $dv; + private string $verifier; + + public static function parse(string $rut): Rut + { + // Remove space, dots and hyphens + $rut = str_replace([' ', '.', '-'], '', $rut); + + return new self( + (int) substr($rut, 0, -1), + substr($rut, -1) + ); + } + + /** + * Creates a valid rut out of a number. + */ + public static function create(int $number): Rut + { + $verifier = self::calculateVerifier($number); + + return new Rut($number, $verifier); + } /** * Rut constructor. * - * @param string $rut - * @param RutValidator|null $validator if provided validates the Rut + * @throws InvalidRut if the verifier digit is invalid */ - public function __construct(string $rut, RutValidator $validator = null) + public function __construct(int $number, string $verifier) { - $sanitized = $this->sanitize($rut); - $this->value = substr($sanitized, 0, -1); - $this->dv = $sanitized[\strlen($sanitized) - 1]; - - if (!$validator instanceof RutValidator) { - $validator = new Module11RutValidator(); - } - $validator->validate($this); + $this->number = $number; + $this->verifier = strtoupper($verifier); + $this->guard(); } - /** - * Casts the Rut object into a string. - * - * @return string - */ - public function __toString(): string + public function getNumber(): int { - return $this->format(self::FORMAT_READABLE); + return $this->number; } - /** - * Creates a new Rut instance from the correlative and the verifier digit. - * - * @param string $correlative - * @param string $verifierDigit - * @param RutValidator|null $validator - * - * @return Rut - */ - public static function fromParts(string $correlative, string $verifierDigit, RutValidator $validator = null): Rut + public function getVerifier(): string { - return new self($correlative.$verifierDigit, $validator); - } - - /** - * Creates a new instance of Rut from a string. - * - * @param string $rut - * @param RutValidator|null $validator - * - * @return Rut - */ - public static function fromString(string $rut, RutValidator $validator = null): Rut - { - return new self($rut, $validator); + return $this->verifier; } /** * Compares whether a Rut is equal to another or not. - * - * @param Rut $rut - * - * @return bool */ - public function isEqualTo(Rut $rut): bool + public function equals(Rut $rut): bool { - return $this->format() === $rut->format(); + return $this->number === $rut->number; } /** * Formats a Rut to a string. - * - * @param int $format one of the FORMAT_ constants - * - * @return string */ - public function format(int $format = 0): string + public function format(): FormattedRut { - switch ($format) { - case self::FORMAT_HYPHENED: - return $this->value.'-'.$this->dv; - break; - case self::FORMAT_CLEAR: - return $this->value.$this->dv; - break; - case self::FORMAT_READABLE: - return $this->formatReadable(); - break; - case self::FORMAT_HIDDEN: - return $this->formatHidden(); - break; - default: - throw new \InvalidArgumentException( - sprintf( - 'Argument provided for %s method of class %s is invalid.', - __METHOD__, - __CLASS__ - ) - ); + return new FormattedRut($this); + } + + private function guard(): void + { + // Check if rut is between zero and 999.999.999 + if ($this->number < 0 || $this->number > 999_999_999) { + throw InvalidRut::number(); + } + // Check if the verifier digit is in the range of valid ones + if (!in_array($this->verifier, self::VALID_VERIFIERS, true)) { + throw InvalidRut::digit($this->verifier); + } + // Check the verifier is algorithmically correct + if ($this->verifier !== self::calculateVerifier($this->number)) { + throw InvalidRut::digit($this->verifier); } } /** - * Returns the correlative number of the Rut. - * - * @return string + * Calculates a verifier digit from a number. */ - public function getCorrelative(): string + private static function calculateVerifier(int $number): string { - return $this->value; - } + /** @var list $sequence */ + $sequence = array_filter(array_reverse(str_split((string) $number)), 'intval'); + $x = 2; + $s = 0; + foreach ($sequence as $digit) { + if ($x > 7) { + $x = 2; + } + $s += $digit * $x; + ++$x; + } + $dv = 11 - ($s % 11); + if ($dv === 10) { + $dv = 'K'; + } + if ($dv === 11) { + $dv = '0'; + } - /** - * Returns the verifier digit of the Rut. - * - * @return string - */ - public function getVerifierDigit(): string - { - return $this->dv; - } - - /** - * Sanitizes a Rut string. - * - * @param string $value - * - * @return string - */ - private function sanitize(string $value): string - { - return str_replace(['.', ',', '-'], '', strtoupper(trim($value))); - } - - /** - * Helper to format the Rut as FORMAT_READABLE. - * - * @return string - */ - private function formatReadable(): string - { - return sprintf('%s-%s', number_format($this->value, 0, '', '.'), $this->dv); - } - - /** - * Helper to format the Rut as FORMAT_HIDDEN. - * - * @return string - */ - private function formatHidden(): string - { - $readable = $this->formatReadable(); - $exploded = explode('.', $readable); - - return sprintf('%s.***.***-%s', $exploded[0], $this->dv); + return (string) $dv; } } diff --git a/src/Util/CorrelativeUtils.php b/src/Util/CorrelativeUtils.php deleted file mode 100644 index 3395d60..0000000 --- a/src/Util/CorrelativeUtils.php +++ /dev/null @@ -1,81 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Util; - -use MNC\ChileanRut\Rut; - -/** - * This class provides utils for a Rut correlative. - * - * @author Matías Navarro Carter - */ -class CorrelativeUtils -{ - /** - * Finds the verifier digit of a correlative. - * - * @param string $correlative - * - * @return string - */ - public static function findVerifierDigit(string $correlative): string - { - $x = 2; - $s = 0; - - for ($i = \strlen($correlative) - 1; $i >= 0; --$i) { - if ($x > 7) { - $x = 2; - } - $s += $correlative[$i] * $x; - ++$x; - } - - $dv = 11 - ($s % 11); - - if (10 === $dv) { - $dv = 'K'; - } - - if (11 === $dv) { - $dv = '0'; - } - - return (string) $dv; - } - - /** - * Instantiates a valid Rut object just providing a correlative. - * - * @param string $correlative - * - * @return Rut - */ - public static function createValidRutOnlyFromCorrelative(string $correlative): Rut - { - return Rut::fromParts($correlative, static::findVerifierDigit($correlative)); - } - - /** - * Auto-generates an algorithmically valid Rut, because why not. - * - * @noinspection PhpDocMissingThrowsInspection - * - * @return Rut - */ - public static function autoGenerateValidRut(): Rut - { - /** @noinspection PhpUnhandledExceptionInspection */ - $correlative = \random_int(1000000, 40000000); - - return static::createValidRutOnlyFromCorrelative($correlative); - } -} diff --git a/src/Validator/ChainRutValidator.php b/src/Validator/ChainRutValidator.php deleted file mode 100644 index a8e8d0e..0000000 --- a/src/Validator/ChainRutValidator.php +++ /dev/null @@ -1,52 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Validator; - -use MNC\ChileanRut\Exception\InvalidRutException; -use MNC\ChileanRut\Rut; - -/** - * A ChainRutValidator. - * - * Use this implementation when you want to validate a Rut against multiple - * validators. Add the validators in order by calling addValidator(). - * - * @author Matías Navarro Carter - */ -class ChainRutValidator implements RutValidator -{ - /** - * @var RutValidator[] - */ - private $validators; - - /** - * ChainRutValidator constructor. - * - * @param RutValidator[] $validators - */ - public function __construct(RutValidator ...$validators) - { - $this->validators = $validators; - } - - /** - * @param Rut $rut - * - * @throws InvalidRutException on invalid Rut - */ - public function validate(Rut $rut): void - { - foreach ($this->validators as $validator) { - $validator->validate($rut); - } - } -} diff --git a/src/Validator/Module11RutValidator.php b/src/Validator/Module11RutValidator.php deleted file mode 100644 index fc2c745..0000000 --- a/src/Validator/Module11RutValidator.php +++ /dev/null @@ -1,37 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Validator; - -use MNC\ChileanRut\Exception\InvalidRutException; -use MNC\ChileanRut\Rut; -use MNC\ChileanRut\Util\CorrelativeUtils; - -/** - * Validates the Rut using the Module 11 algorithm. - * - * @author Matías Navarro Carter - */ -class Module11RutValidator implements RutValidator -{ - /** - * @param Rut $rut - * - * @throws InvalidRutException - */ - public function validate(Rut $rut): void - { - $digit = CorrelativeUtils::findVerifierDigit($rut->getCorrelative()); - - if ($digit !== $rut->getVerifierDigit()) { - throw new InvalidRutException($rut); - } - } -} diff --git a/src/Validator/RutValidator.php b/src/Validator/RutValidator.php deleted file mode 100644 index 5615089..0000000 --- a/src/Validator/RutValidator.php +++ /dev/null @@ -1,43 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Validator; - -use MNC\ChileanRut\Exception\InvalidRutException; -use MNC\ChileanRut\Rut; - -/** - * This is the base contract for a Rut validator. - * - * You can implement any logic here that you can use to validate a Rut. - * For example, the Module11RutValidator only validates that a Rut is algorithmically - * correct, but not that it actually exists. - * - * You could create a HTTPRutValidator that performs a request to validate that a - * Rut exists against a Rest Api or a third party service. - * - * @author Matías Navarro Carter - */ -interface RutValidator -{ - /** - * Validates a Rut. - * - * The implementation MUST throw an InvalidRutException if validation fails. - * - * The different clients CAN catch that exception and handle the validation - * error according to their business rules. - * - * @param Rut $rut - * - * @throws InvalidRutException on invalid Rut - */ - public function validate(Rut $rut): void; -} diff --git a/tests/Bridge/Symfony/Form/RutTypeTest.php b/tests/Bridge/Symfony/Form/RutTypeTest.php deleted file mode 100644 index b8beec3..0000000 --- a/tests/Bridge/Symfony/Form/RutTypeTest.php +++ /dev/null @@ -1,41 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Tests\Bridge\Symfony\Form; - -use MNC\ChileanRut\Bridge\Symfony\Form\RutType; -use MNC\ChileanRut\Rut; -use Symfony\Component\Form\Test\TypeTestCase; - -class RutTypeTest extends TypeTestCase -{ - public function testSubmitValidData() - { - $objectToCompare = new Rut('16.894.365-2'); - - // $objectToCompare will retrieve data from the form submission; pass it as the second argument - $form = $this->factory->create(RutType::class); - - // submit the data to the form directly - $form->submit('16.894.365-2'); - - $this->assertTrue($form->isSynchronized()); - - $formData = $form->getData(); - - // check that $objectToCompare was modified as expected when the form was submitted - $this->assertInstanceOf(Rut::class, $formData); - $this->assertTrue($formData->isEqualTo($objectToCompare)); - - $view = $form->createView(); - - $this->assertSame('16.894.365-2', $view->vars['value']); - } -} diff --git a/tests/Doctrine/NumericRutTypeTest.php b/tests/Doctrine/NumericRutTypeTest.php new file mode 100644 index 0000000..a4b687b --- /dev/null +++ b/tests/Doctrine/NumericRutTypeTest.php @@ -0,0 +1,51 @@ +createMock(AbstractPlatform::class); + $type = new NumericRutType(); + $result = $type->convertToPHPValue(null, $platform); + self::assertNull($result); + } + + public function testItConvertsStringFromDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new NumericRutType(); + $result = $type->convertToPHPValue(16894365, $platform); + self::assertInstanceOf(Rut::class, $result); + } + + public function testItConvertsNullToDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new NumericRutType(); + $result = $type->convertToDatabaseValue(null, $platform); + self::assertNull($result); + } + + public function testItConvertsRutToDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new NumericRutType(); + $result = $type->convertToDatabaseValue(Rut::parse('168943652'), $platform); + self::assertSame('16894365', $result); + } + + public function testItCannotConvertToDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new NumericRutType(); + $this->expectException(ConversionException::class); + $type->convertToDatabaseValue(new \DateTime(), $platform); + } +} diff --git a/tests/Doctrine/RutTypeTest.php b/tests/Doctrine/RutTypeTest.php new file mode 100644 index 0000000..1a87215 --- /dev/null +++ b/tests/Doctrine/RutTypeTest.php @@ -0,0 +1,59 @@ +createMock(AbstractPlatform::class); + $type = new RutType(); + $result = $type->convertToPHPValue(null, $platform); + self::assertNull($result); + } + + public function testItConvertsStringFromDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new RutType(); + $result = $type->convertToPHPValue('16.894.365-2', $platform); + self::assertInstanceOf(Rut::class, $result); + } + + public function testItCannotConvertFromDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new RutType(); + $this->expectException(ConversionException::class); + $type->convertToPHPValue(true, $platform); + } + + public function testItConvertsNullToDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new RutType(); + $result = $type->convertToDatabaseValue(null, $platform); + self::assertNull($result); + } + + public function testItConvertsRutToDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new RutType(); + $result = $type->convertToDatabaseValue(Rut::parse('168943652'), $platform); + self::assertSame('16.894.365-2', $result); + } + + public function testItCannotConvertToDatabaseValue(): void + { + $platform = $this->createMock(AbstractPlatform::class); + $type = new RutType(); + $this->expectException(ConversionException::class); + $type->convertToDatabaseValue(new \DateTime(), $platform); + } +} diff --git a/tests/FormattedRutTest.php b/tests/FormattedRutTest.php new file mode 100644 index 0000000..402095f --- /dev/null +++ b/tests/FormattedRutTest.php @@ -0,0 +1,54 @@ +format()->hyphened(); + self::assertSame('16894365-2', $formatted); + } + + public function testItFormatsDotted(): void + { + $formatted = (string) Rut::parse('168943652')->format()->dotted(); + self::assertSame('16.894.3652', $formatted); + } + + public function testItFormatsHyphenedAndDotted(): void + { + $formatted = (string) Rut::parse('168943652')->format()->hyphened()->dotted(); + self::assertSame('16.894.365-2', $formatted); + } + + public function testItFormatsObfuscated(): void + { + $formatted = (string) Rut::parse('168943652')->format()->obfuscated(); + self::assertSame('*****3652', $formatted); + } + + public function testItFormatsObfuscatedAndHyphened(): void + { + $formatted = (string) Rut::parse('168943652')->format()->hyphened()->obfuscated(); + self::assertSame('*****365-2', $formatted); + } + + public function testItFormatsObfuscatedAndDotted(): void + { + $formatted = (string) Rut::parse('168943652')->format()->obfuscated()->dotted(); + self::assertSame('**.***.3652', $formatted); + } + + public function testItFormatsWithAll(): void + { + $formatted = (string) Rut::parse('168943652')->format()->hyphened()->dotted()->obfuscated(); + self::assertSame('**.***.365-2', $formatted); + } +} diff --git a/tests/Rut/RutTest.php b/tests/Rut/RutTest.php deleted file mode 100644 index fe61d84..0000000 --- a/tests/Rut/RutTest.php +++ /dev/null @@ -1,82 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Tests\Rut; - -use MNC\ChileanRut\Exception\InvalidRutException; -use MNC\ChileanRut\Rut; -use MNC\ChileanRut\Validator\Module11RutValidator; -use PHPUnit\Framework\TestCase; - -class RutTest extends TestCase -{ - public function testThatRutIsSanitizedProperlyOnInstantiation() - { - $rut = Rut::fromString('16.894.365-2'); - - $this->assertSame('16894365', $rut->getCorrelative()); - $this->assertSame('2', $rut->getVerifierDigit()); - } - - public function testThatRutsInstantiatedDifferentFormatButWithEqualValueAreIndeedEqual() - { - $rut1 = new Rut('16.894.365-2'); - $rut2 = new Rut('16894365-2'); - $this->assertTrue($rut1->isEqualTo($rut2)); - } - - public function testThatFormatClearWorks() - { - $rut = new Rut('16.894.365-2'); - $this->assertSame('168943652', $rut->format(Rut::FORMAT_CLEAR)); - } - - public function testThatFormatWithHyphenWorks() - { - $rut = new Rut('16.894.365-2'); - $this->assertSame('16894365-2', $rut->format(Rut::FORMAT_HYPHENED)); - } - - public function testThatFormatReadableWorks() - { - $rut = new Rut('168943652'); - $this->assertSame('16.894.365-2', $rut->format(Rut::FORMAT_READABLE)); - } - - public function testThatFormatHiddenWorks() - { - $rut = new Rut('168943652'); - $this->assertSame('16.***.***-2', $rut->format(Rut::FORMAT_HIDDEN)); - } - - public function testThatIntegratedValidationThrowsExceptionOnInvalidRut() - { - $this->expectException(InvalidRutException::class); - - $validator = new Module11RutValidator(); - $rut = new Rut('4444444-2', $validator); - } - - public function testThatIntegratedValidationDoesNotThrowExceptionOnValidRut() - { - $validator = new Module11RutValidator(); - $rut = new Rut('16.894.365-2', $validator); - - $this->assertInstanceOf(Rut::class, $rut); - } - - public function testInvalidFormatValueRaisesException() - { - $rut = new Rut('16.894.365-2'); - - $this->expectException(\InvalidArgumentException::class); - $rut->format(23); - } -} diff --git a/tests/RutTest.php b/tests/RutTest.php new file mode 100644 index 0000000..0cf8f28 --- /dev/null +++ b/tests/RutTest.php @@ -0,0 +1,86 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MNC\ChileanRut; + +use PHPUnit\Framework\TestCase; + +/** + * Class RutTest + * @package MNC\ChileanRut\Tests\Rut + */ +class RutTest extends TestCase +{ + /** + * @dataProvider getRutDataset + * @param string $raw + * @param int $expectedNumber + * @param string $expectedVerifier + */ + public function testItParsesRuts(string $raw, int $expectedNumber, string $expectedVerifier): void + { + $rut = Rut::parse($raw); + self::assertSame($expectedNumber, $rut->getNumber()); + self::assertSame($expectedVerifier, $rut->getVerifier()); + } + + public function testItDetectsOutOfRangeVerifier(): void + { + $this->expectException(InvalidRut::class); + Rut::parse('16894365F'); + } + + public function testItDetectsInvalidVerifier(): void + { + $this->expectException(InvalidRut::class); + Rut::parse('16894365K'); + } + + public function testItDetectsRutTooBig(): void + { + $this->expectException(InvalidRut::class); + Rut::create(3_355_535_353); + } + + public function testItComparesToEqual(): void + { + $rut1 = Rut::parse('168943652'); + $rut2 = Rut::parse('16.894.365-2'); + $rut3 = Rut::create(22_224_525); + self::assertTrue($rut1->equals($rut2)); + self::assertFalse($rut1->equals($rut3)); + } + + public static function testItCreatesARut(): void + { + $rut = Rut::create(22_457_309); + self::assertSame(22_457_309, $rut->getNumber()); + } + + public static function testItCanFormatRut(): void + { + $rut = (string) Rut::create(22_457_309)->format(); + self::assertSame('22457309K', $rut); + } + + /** + * @return array[] + */ + public function getRutDataset(): array + { + return [ + ['16.894.365-2', 16_894_365, '2'], + ['24 736.7322', 24_736_732, '2'], + [' 24 232.. 442 -- 0', 24_232_442, '0'], + ['35323325', 3_532_332, '5'], + ['22.457.309K', 22_457_309, 'K'] + ]; + } +} diff --git a/tests/Validator/ChainRutValidatorTest.php b/tests/Validator/ChainRutValidatorTest.php deleted file mode 100644 index 106976d..0000000 --- a/tests/Validator/ChainRutValidatorTest.php +++ /dev/null @@ -1,56 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Tests\Validator; - -use MNC\ChileanRut\Exception\InvalidRutException; -use MNC\ChileanRut\Util\CorrelativeUtils; -use MNC\ChileanRut\Validator\ChainRutValidator; -use MNC\ChileanRut\Validator\Module11RutValidator; -use MNC\ChileanRut\Validator\RutValidator; -use PHPUnit\Framework\TestCase; - -/** - * Class ChainRutValidatorTest. - */ -class ChainRutValidatorTest extends TestCase -{ - public function testThatChainValidatorFails(): void - { - $rut = CorrelativeUtils::autoGenerateValidRut(); - - $normalValidator = new Module11RutValidator(); - $mockValidator = $this->createMock(RutValidator::class); - $mockValidator->expects($this->once()) - ->method('validate') - ->willThrowException(new InvalidRutException($rut)); - - $chainValidator = new ChainRutValidator($normalValidator, $mockValidator); - - $this->expectException(InvalidRutException::class); - $chainValidator->validate($rut); - } - - public function testThatChainValidatorPasses(): void - { - $rut = CorrelativeUtils::autoGenerateValidRut(); - - $normalValidator = new Module11RutValidator(); - $mockValidator = $this->createMock(RutValidator::class); - $mockValidator->expects($this->once()) - ->method('validate') - ->willReturn(null); - - $chainValidator = new ChainRutValidator($normalValidator, $mockValidator); - - $chainValidator->validate($rut); - $this->assertTrue(true); - } -} diff --git a/tests/Validator/SimpleRutValidatorTest.php b/tests/Validator/SimpleRutValidatorTest.php deleted file mode 100644 index ad2de9b..0000000 --- a/tests/Validator/SimpleRutValidatorTest.php +++ /dev/null @@ -1,39 +0,0 @@ - - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MNC\ChileanRut\Tests\Validator; - -use MNC\ChileanRut\Exception\InvalidRutException; -use MNC\ChileanRut\Rut; -use MNC\ChileanRut\Validator\Module11RutValidator; -use PHPUnit\Framework\TestCase; - -class SimpleRutValidatorTest extends TestCase -{ - public function testValidationPassesOnValidRut() - { - $rut = new Rut('16.894.365-2'); - $validator = new Module11RutValidator(); - - $validator->validate($rut); - - $this->assertInstanceOf(Rut::class, $rut); - } - - public function testValidationFailsOnInvalidRut() - { - $this->expectException(InvalidRutException::class); - - $rut = new Rut('34.4534.353-1'); - $validator = new Module11RutValidator(); - - $validator->validate($rut); - } -}