From e540de2085fa19de773c8970ef90b97afafcdb6e Mon Sep 17 00:00:00 2001 From: Matias Navarro Carter Date: Fri, 12 Oct 2018 15:17:12 -0300 Subject: [PATCH] Version 2.0.0 --- .travis.yml | 16 ++ CHANGELOG.md | 18 ++ README.md | 14 +- composer.json | 4 + coverage.xml | 216 ++++++++++++++++++ phpunit.xml.dist | 4 + src/Bridge/Doctrine/DBAL/Types/RutType.php | 6 +- src/Bridge/Symfony/Validator/IsValidRut.php | 2 +- .../Symfony/Validator/IsValidRutValidator.php | 9 +- src/Rut.php | 43 ++-- src/Util/CorrelativeUtils.php | 2 - src/Validator/ChainRutValidator.php | 18 +- ...Validator.php => Module11RutValidator.php} | 2 +- src/Validator/RutValidator.php | 2 +- tests/Rut/RutTest.php | 6 +- tests/Validator/ChainRutValidatorTest.php | 56 +++++ tests/Validator/SimpleRutValidatorTest.php | 6 +- 17 files changed, 373 insertions(+), 51 deletions(-) create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 coverage.xml rename src/Validator/{SimpleRutValidator.php => Module11RutValidator.php} (94%) create mode 100644 tests/Validator/ChainRutValidatorTest.php diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b3e34a6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: php +dist: precise +php: + - '7.1' + - '7.2' + - nightly +sudo: false +cache: + directories: + - $HOME/.composer/cache + +before_script: + - travis_retry composer self-update + - travis_retry composer install --no-interaction --prefer-dist + +script: composer run test \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..78fa414 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,18 @@ +# 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/README.md b/README.md index 0929083..34cb4ef 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ Rut Chileno =========== +[![Build Status](https://travis-ci.org/mnavarrocarter/chilean-rut.svg?branch=master)](https://travis-ci.org/mnavarrocarter/chilean-rut) +[![Maintainability](https://api.codeclimate.com/v1/badges/c93bd4d894722c404cfd/maintainability)](https://codeclimate.com/github/mnavarrocarter/chilean-rut/maintainability) +[![Test Coverage](https://api.codeclimate.com/v1/badges/c93bd4d894722c404cfd/test_coverage)](https://codeclimate.com/github/mnavarrocarter/chilean-rut/test_coverage) + Esta librería implementa una clase Rut como un *value object* inmutable, incluyendo una api de validación flexible y extendible. @@ -48,7 +52,7 @@ $rut = new Rut('23.546.565-4', new SimpleRutValidator()); ``` ### Validación Personalizada de Rut -El `SimpleRutValidator` no es más que la implementación del validador clásico de Rut, +El `Module11RutValidator` no es más que la implementación del validador clásico de Rut, el algoritmo de módulo 11. Esto verifica que un Rut es algoritmicamente correcto, pero no valida que es real. @@ -114,10 +118,10 @@ use MNC\ChileanRut\Validator\ChainRutValidator; use MNC\ChileanRut\Validator\SimpleRutValidator; use App\Rut\DatabaseRutValidator; -$chainValidator = new ChainRutValidator(); -$chainValidator - ->append(new SimpleRutValidator()) - ->append(new DatabaseRutValidator()); +$chainValidator = new ChainRutValidator( + new SimpleRutValidator(), + new DatabaseRutValidator() +); $rut = new Rut('14.245.245-2'); diff --git a/composer.json b/composer.json index 79e19e3..f255878 100644 --- a/composer.json +++ b/composer.json @@ -30,5 +30,9 @@ "psr-4": { "MNC\\ChileanRut\\Tests\\": "tests" } + }, + "scripts": { + "test": "@php vendor/bin/phpunit --verbose", + "style": "@php vendor/bin/php-cs-fixer fix" } } diff --git a/coverage.xml b/coverage.xml new file mode 100644 index 0000000..d36b7c9 --- /dev/null +++ b/coverage.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d723ff0..add05c1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -16,6 +16,10 @@ + + + + ./src diff --git a/src/Bridge/Doctrine/DBAL/Types/RutType.php b/src/Bridge/Doctrine/DBAL/Types/RutType.php index 13b31de..bc0e0e3 100644 --- a/src/Bridge/Doctrine/DBAL/Types/RutType.php +++ b/src/Bridge/Doctrine/DBAL/Types/RutType.php @@ -47,10 +47,10 @@ class RutType extends StringType } if ($value instanceof Rut) { - return parent::convertToDatabaseValue($value->format(), $platform); + return $value->format(Rut::FORMAT_HYPHENED); } - throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'Rut']); + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', Rut::class]); } /** @@ -61,8 +61,6 @@ class RutType extends StringType */ public function convertToPHPValue($value, AbstractPlatform $platform) { - $value = parent::convertToPHPValue($value, $platform); - if (null === $value || $value instanceof Rut) { return $value; } diff --git a/src/Bridge/Symfony/Validator/IsValidRut.php b/src/Bridge/Symfony/Validator/IsValidRut.php index ede5f0e..2df942d 100644 --- a/src/Bridge/Symfony/Validator/IsValidRut.php +++ b/src/Bridge/Symfony/Validator/IsValidRut.php @@ -17,5 +17,5 @@ use Symfony\Component\Validator\Constraint; */ class IsValidRut extends Constraint { - public $message = 'The rut "{{value}}" is not valid.'; + public $message = '"{{value}}" is not a valid Rut.'; } diff --git a/src/Bridge/Symfony/Validator/IsValidRutValidator.php b/src/Bridge/Symfony/Validator/IsValidRutValidator.php index abd36e6..85c4fb2 100644 --- a/src/Bridge/Symfony/Validator/IsValidRutValidator.php +++ b/src/Bridge/Symfony/Validator/IsValidRutValidator.php @@ -12,8 +12,8 @@ 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 MNC\ChileanRut\Validator\SimpleRutValidator; use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; @@ -30,9 +30,14 @@ class IsValidRutValidator extends ConstraintValidator */ private $validator; + /** + * IsValidRutValidator constructor. + * + * @param RutValidator|null $validator + */ public function __construct(RutValidator $validator = null) { - $this->validator = $validator ?? new SimpleRutValidator(); + $this->validator = $validator ?? new Module11RutValidator(); } /** diff --git a/src/Rut.php b/src/Rut.php index 683d65c..12a2828 100644 --- a/src/Rut.php +++ b/src/Rut.php @@ -10,10 +10,13 @@ namespace MNC\ChileanRut; +use MNC\ChileanRut\Validator\Module11RutValidator; use MNC\ChileanRut\Validator\RutValidator; /** - * Class Rut. + * Rut represents a the Chilean National ID Number. + * + * All residents of Chile are uniquely identified by one of these. * * @author Matías Navarro Carter */ @@ -45,12 +48,15 @@ class Rut $this->value = substr($sanitized, 0, -1); $this->dv = $sanitized[\strlen($sanitized) - 1]; - if (null !== $validator) { - $validator->validate($this); + if (!$validator instanceof RutValidator) { + $validator = new Module11RutValidator(); } + $validator->validate($this); } /** + * Casts the Rut object into a string. + * * @return string */ public function __toString(): string @@ -59,27 +65,35 @@ class Rut } /** - * @param string $correlative - * @param string $verifierDigit + * 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): Rut + public static function fromParts(string $correlative, string $verifierDigit, RutValidator $validator = null): Rut { - return new self($correlative.$verifierDigit); + return new self($correlative.$verifierDigit, $validator); } /** - * @param string $rut + * Creates a new instance of Rut from a string. + * + * @param string $rut + * @param RutValidator|null $validator * * @return Rut */ - public static function fromString(string $rut): Rut + public static function fromString(string $rut, RutValidator $validator = null): Rut { - return new self($rut); + return new self($rut, $validator); } /** + * Compares whether a Rut is equal to another or not. + * * @param Rut $rut * * @return bool @@ -151,13 +165,12 @@ class Rut */ private function sanitize(string $value): string { - $value = trim($value); - $value = strtoupper($value); - - return str_replace(['.', ',', '-'], '', $value); + return str_replace(['.', ',', '-'], '', strtoupper(trim($value))); } /** + * Helper to format the Rut as FORMAT_READABLE. + * * @return string */ private function formatReadable(): string @@ -166,6 +179,8 @@ class Rut } /** + * Helper to format the Rut as FORMAT_HIDDEN. + * * @return string */ private function formatHidden(): string diff --git a/src/Util/CorrelativeUtils.php b/src/Util/CorrelativeUtils.php index 94a1dc5..47a8936 100644 --- a/src/Util/CorrelativeUtils.php +++ b/src/Util/CorrelativeUtils.php @@ -68,8 +68,6 @@ class CorrelativeUtils * Auto-generates an algorithmically valid Rut, because why not. * * @return Rut - * - * @throws \Exception on insufficient entropy on correlative generation */ public static function autoGenerateValidRut(): Rut { diff --git a/src/Validator/ChainRutValidator.php b/src/Validator/ChainRutValidator.php index 9f32096..a8e8d0e 100644 --- a/src/Validator/ChainRutValidator.php +++ b/src/Validator/ChainRutValidator.php @@ -30,24 +30,12 @@ class ChainRutValidator implements RutValidator /** * ChainRutValidator constructor. - */ - public function __construct() - { - $this->validators = []; - } - - /** - * Appends a RutValidator instance to the validation chain. * - * @param RutValidator $validator - * - * @return ChainRutValidator + * @param RutValidator[] $validators */ - public function append(RutValidator $validator): ChainRutValidator + public function __construct(RutValidator ...$validators) { - $this->validators[] = $validator; - - return $this; + $this->validators = $validators; } /** diff --git a/src/Validator/SimpleRutValidator.php b/src/Validator/Module11RutValidator.php similarity index 94% rename from src/Validator/SimpleRutValidator.php rename to src/Validator/Module11RutValidator.php index e87df3b..fc2c745 100644 --- a/src/Validator/SimpleRutValidator.php +++ b/src/Validator/Module11RutValidator.php @@ -19,7 +19,7 @@ use MNC\ChileanRut\Util\CorrelativeUtils; * * @author Matías Navarro Carter */ -class SimpleRutValidator implements RutValidator +class Module11RutValidator implements RutValidator { /** * @param Rut $rut diff --git a/src/Validator/RutValidator.php b/src/Validator/RutValidator.php index 85e98b3..5615089 100644 --- a/src/Validator/RutValidator.php +++ b/src/Validator/RutValidator.php @@ -17,7 +17,7 @@ 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 SimpleRutValidator only validates that a Rut is algorithmically + * 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 diff --git a/tests/Rut/RutTest.php b/tests/Rut/RutTest.php index 7471cac..fe61d84 100644 --- a/tests/Rut/RutTest.php +++ b/tests/Rut/RutTest.php @@ -12,7 +12,7 @@ namespace MNC\ChileanRut\Tests\Rut; use MNC\ChileanRut\Exception\InvalidRutException; use MNC\ChileanRut\Rut; -use MNC\ChileanRut\Validator\SimpleRutValidator; +use MNC\ChileanRut\Validator\Module11RutValidator; use PHPUnit\Framework\TestCase; class RutTest extends TestCase @@ -60,13 +60,13 @@ class RutTest extends TestCase { $this->expectException(InvalidRutException::class); - $validator = new SimpleRutValidator(); + $validator = new Module11RutValidator(); $rut = new Rut('4444444-2', $validator); } public function testThatIntegratedValidationDoesNotThrowExceptionOnValidRut() { - $validator = new SimpleRutValidator(); + $validator = new Module11RutValidator(); $rut = new Rut('16.894.365-2', $validator); $this->assertInstanceOf(Rut::class, $rut); diff --git a/tests/Validator/ChainRutValidatorTest.php b/tests/Validator/ChainRutValidatorTest.php new file mode 100644 index 0000000..106976d --- /dev/null +++ b/tests/Validator/ChainRutValidatorTest.php @@ -0,0 +1,56 @@ + + * 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 index 1a1dc27..ad2de9b 100644 --- a/tests/Validator/SimpleRutValidatorTest.php +++ b/tests/Validator/SimpleRutValidatorTest.php @@ -12,7 +12,7 @@ namespace MNC\ChileanRut\Tests\Validator; use MNC\ChileanRut\Exception\InvalidRutException; use MNC\ChileanRut\Rut; -use MNC\ChileanRut\Validator\SimpleRutValidator; +use MNC\ChileanRut\Validator\Module11RutValidator; use PHPUnit\Framework\TestCase; class SimpleRutValidatorTest extends TestCase @@ -20,7 +20,7 @@ class SimpleRutValidatorTest extends TestCase public function testValidationPassesOnValidRut() { $rut = new Rut('16.894.365-2'); - $validator = new SimpleRutValidator(); + $validator = new Module11RutValidator(); $validator->validate($rut); @@ -32,7 +32,7 @@ class SimpleRutValidatorTest extends TestCase $this->expectException(InvalidRutException::class); $rut = new Rut('34.4534.353-1'); - $validator = new SimpleRutValidator(); + $validator = new Module11RutValidator(); $validator->validate($rut); }