mirror of
https://github.com/Respect/Validation.git
synced 2024-06-04 23:02:16 +02:00
Issue #260: Now using Respect\Validation exceptions only
* `ExceptionInterface`: all Respect\Validation\Exceptions implement through inheritance * `ValidatorExceptionInterface`: implemented only by AllOfException. This allows the end users to know when there has been a Validator exception rather than just any of our exceptions. Fixed formatting issues Created two new exception types * Created ValidationExceptionInterface * Created NestedValidationExceptionInterface which extends ValidationExceptionInterface * Renamed from ValidatorExceptionInterface * ValidationException implements ValidationExceptionInterface and ValidationExceptionTest checks for the implementation. * AbstractNestedException implements NestedValidationExceptionInterface and AbstractNestedExceptionTest checks for the implementation. * CheckExceptionsTest now checks all Rule exceptions to make sure they implement ValidationExceptionInterface * ValidatorTest now contains test that shows that only ValidationExceptionInterface can be used reliably with `::check()` * Updated documentation for new exception types * Reworked examples to show how to catch the exception interfaces Minor changes in readme.md and ExceptionInterfaces * Removed `import` statements (hahaha) * Renamed `$e` to `$exception` * `ValidationExceptionInterface` now extends `ExceptionInterface`. Changed `ValidationException` to match
This commit is contained in:
parent
116be2bbef
commit
ab65035181
32
README.md
32
README.md
|
@ -108,16 +108,30 @@ $usernameValidator->validate('alexandre gaigalas'); //false
|
|||
$usernameValidator->validate('#$%'); //false
|
||||
```
|
||||
|
||||
### Exception Types
|
||||
|
||||
* `Respect\Validation\Exceptions\NestedValidationExceptionInterface`:
|
||||
* Use when calling `assert()`.
|
||||
* Interface has three methods: `getFullMessage()`, `findMessages()`, and `getMainMessage()`.
|
||||
* `Respect\Validation\Exceptions\ValidationExceptionInterface`:
|
||||
* Use when calling `::check()`.
|
||||
* All `Respect\Validation` validation exceptions implement this interface.
|
||||
* Interface has one method: `getMainMessage()`;
|
||||
* `Repect\Validation\Exceptions\ExceptionInterface`:
|
||||
* All `Respect\Validation\Exceptions` implement this interface.
|
||||
|
||||
### Informative Exceptions
|
||||
|
||||
When something goes wrong, Validation can tell you exactly what's going on. For this,
|
||||
we use the `assert()` method instead of `validate()`:
|
||||
|
||||
```php
|
||||
use Respect\Validation\Exceptions\NestedValidationExceptionInterface
|
||||
|
||||
try {
|
||||
$usernameValidator->assert('really messed up screen#name');
|
||||
} catch(DomainException $e) {
|
||||
echo $e->getFullMessage();
|
||||
} catch(NestedValidationExceptionInterface $exception) {
|
||||
echo $exception->getFullMessage();
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -134,10 +148,12 @@ The text tree is fine, but unusable on a HTML form or something more custom. You
|
|||
`findMessages()` for that:
|
||||
|
||||
```php
|
||||
use Respect\Validation\Exceptions\NestedValidationExceptionInterface
|
||||
|
||||
try {
|
||||
$usernameValidator->assert('really messed up screen#name');
|
||||
} catch(\InvalidArgumentException $e) {
|
||||
var_dump($e->findMessages(array('alnum', 'length', 'noWhitespace')));
|
||||
} catch(NestedValidationExceptionInterface $exception) {
|
||||
var_dump($exception->findMessages(array('alnum', 'length', 'noWhitespace')));
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -149,7 +165,7 @@ Getting messages as an array is fine, but sometimes you need to customize them i
|
|||
to present them to the user. This is possible using the `findMessages()` method as well:
|
||||
|
||||
```php
|
||||
$errors = $e->findMessages(array(
|
||||
$errors = $exception->findMessages(array(
|
||||
'alnum' => '{{name}} must contain only letters and digits',
|
||||
'length' => '{{name}} must not have more than 15 chars',
|
||||
'noWhitespace' => '{{name}} cannot contain spaces'
|
||||
|
@ -183,10 +199,12 @@ validation report. There is also a `check()` method that returns an Exception
|
|||
only with the first error found:
|
||||
|
||||
```php
|
||||
use Respect\Validation\Exceptions\ValidationExceptionInterface
|
||||
|
||||
try {
|
||||
$usernameValidator->check('really messed up screen#name');
|
||||
} catch(\InvalidArgumentException $e) {
|
||||
echo $e->getMainMessage();
|
||||
} catch(ValidationExceptionInterface $exception) {
|
||||
echo $exception->getMainMessage();
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use RecursiveIteratorIterator;
|
|||
use RecursiveTreeIterator;
|
||||
use Respect\Validation\ExceptionIterator;
|
||||
|
||||
class AbstractNestedException extends ValidationException
|
||||
class AbstractNestedException extends ValidationException implements NestedValidationExceptionInterface
|
||||
{
|
||||
const ITERATE_TREE = 1;
|
||||
const ITERATE_ALL = 2;
|
||||
|
|
|
@ -3,6 +3,6 @@ namespace Respect\Validation\Exceptions;
|
|||
|
||||
use Exception;
|
||||
|
||||
class ComponentException extends Exception
|
||||
class ComponentException extends Exception implements ExceptionInterface
|
||||
{
|
||||
}
|
||||
|
|
6
library/Exceptions/ExceptionInterface.php
Normal file
6
library/Exceptions/ExceptionInterface.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
namespace Respect\Validation\Exceptions;
|
||||
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
namespace Respect\Validation\Exceptions;
|
||||
|
||||
interface NestedValidationExceptionInterface extends ValidationExceptionInterface
|
||||
{
|
||||
public function findMessages(array $paths);
|
||||
public function getFullMessage();
|
||||
}
|
|
@ -2,10 +2,9 @@
|
|||
namespace Respect\Validation\Exceptions;
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class ValidationException extends InvalidArgumentException
|
||||
class ValidationException extends InvalidArgumentException implements ValidationExceptionInterface
|
||||
{
|
||||
const MODE_DEFAULT = 1;
|
||||
const MODE_NEGATIVE = 2;
|
||||
|
|
7
library/Exceptions/ValidationExceptionInterface.php
Normal file
7
library/Exceptions/ValidationExceptionInterface.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
namespace Respect\Validation\Exceptions;
|
||||
|
||||
interface ValidationExceptionInterface extends ExceptionInterface
|
||||
{
|
||||
public function getMainMessage();
|
||||
}
|
|
@ -5,6 +5,13 @@ use Respect\Validation\Validator as v;
|
|||
|
||||
class AbstractNestedExceptionTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testItImplementsNestedValidationExceptionInterface()
|
||||
{
|
||||
$abstractNestedException = $this->getMock('Respect\Validation\Exceptions\AbstractNestedException');
|
||||
$this->assertInstanceOf('Respect\Validation\Exceptions\NestedValidationExceptionInterface',
|
||||
$abstractNestedException);
|
||||
}
|
||||
|
||||
public function testGetRelatedShouldReturnExceptionAddedByAddRelated()
|
||||
{
|
||||
$composite = new AttributeException;
|
||||
|
@ -75,7 +82,7 @@ class AbstractNestedExceptionTest extends \PHPUnit_Framework_TestCase
|
|||
'security_question' => null,
|
||||
)
|
||||
);
|
||||
} catch (ValidationException $e) {
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$messages = $e->findMessages(
|
||||
array('allOf', 'first_name.length')
|
||||
);
|
||||
|
@ -114,7 +121,7 @@ class AbstractNestedExceptionTest extends \PHPUnit_Framework_TestCase
|
|||
'security_question' => null,
|
||||
)
|
||||
);
|
||||
} catch (ValidationException $e) {
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$messages = $e->findMessages(
|
||||
array(
|
||||
'allOf' => 'Invalid {{name}}',
|
||||
|
@ -127,4 +134,3 @@ class AbstractNestedExceptionTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class CheckExceptionsTest extends \PHPUnit_Framework_TestCase
|
|||
$missingExceptions = array();
|
||||
|
||||
foreach ($this->getAllRuleNames() as $ruleName) {
|
||||
$exceptionClass = 'Respect\\Validation\\Exceptions\\'.$ruleName.'Exception';
|
||||
$exceptionClass = $this->buildExceptionClass($ruleName);
|
||||
if (class_exists($exceptionClass)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -55,6 +55,44 @@ class CheckExceptionsTest extends \PHPUnit_Framework_TestCase
|
|||
$missingExceptions[] = $ruleName;
|
||||
}
|
||||
|
||||
$this->assertEmpty($missingExceptions, 'No exceptions for: '.implode(', ', $missingExceptions));
|
||||
$this->assertEmpty($missingExceptions, 'No exceptions for: ' . $this->formatArrayAsString($missingExceptions));
|
||||
}
|
||||
|
||||
public function testEveryRuleExceptionImplementsValidationExceptionInterface()
|
||||
{
|
||||
$exceptionsNotImplementingInterface = array();
|
||||
|
||||
foreach ($this->getAllRuleNames() as $ruleName) {
|
||||
$exceptionClass = $this->buildExceptionClass($ruleName);
|
||||
$exceptionClassMock = $this->getMock($exceptionClass);
|
||||
if ($exceptionClassMock instanceof ValidationExceptionInterface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$exceptionsNotImplementingInterface[] = $ruleName;
|
||||
}
|
||||
|
||||
$this->assertEmpty($exceptionsNotImplementingInterface,
|
||||
'ValidationExceptionInterface not implemented in: ' .
|
||||
$this->formatArrayAsString($exceptionsNotImplementingInterface));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ruleName
|
||||
* @return string
|
||||
*/
|
||||
private function buildExceptionClass($ruleName)
|
||||
{
|
||||
$exceptionClass = 'Respect\\Validation\\Exceptions\\' . $ruleName . 'Exception';
|
||||
return $exceptionClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @return string
|
||||
*/
|
||||
private function formatArrayAsString(array $array)
|
||||
{
|
||||
return implode(', ', $array);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,19 @@ namespace Respect\Validation\Exceptions;
|
|||
|
||||
class ValidationExceptionTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testItImplementsValidationExceptionInterface()
|
||||
{
|
||||
$validationException = new ValidationException();
|
||||
$this->assertInstanceOf('Respect\Validation\Exceptions\ValidationExceptionInterface', $validationException);
|
||||
}
|
||||
|
||||
public function testItDoesNotImplementNestedValidationExceptionInterface()
|
||||
{
|
||||
$validationException = new ValidationException();
|
||||
$this->assertNotInstanceOf('Respect\Validation\Exceptions\NestedValidationExceptionInterface',
|
||||
$validationException);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerForFormat
|
||||
*/
|
||||
|
@ -98,4 +111,3 @@ class ValidationExceptionTest extends \PHPUnit_Framework_TestCase
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<?php
|
||||
namespace Respect\Validation;
|
||||
|
||||
use Respect\Validation\Exceptions\NestedValidationExceptionInterface;
|
||||
use Respect\Validation\Exceptions\ValidationExceptionInterface;
|
||||
|
||||
class ValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testStaticCreateShouldReturnNewValidator()
|
||||
|
@ -17,7 +20,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
try {
|
||||
Validator::callback('is_int')->setTemplate('{{name}} is not tasty')->assert('something');
|
||||
} catch (\Exception $e) {
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$this->assertEquals('"something" is not tasty', $e->getMainMessage());
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +28,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
try {
|
||||
Validator::callback('is_int')->between(1,2)->setTemplate('{{name}} is not tasty')->assert('something');
|
||||
} catch (\Exception $e) {
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$this->assertEquals('"something" is not tasty', $e->getMainMessage());
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +36,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
try {
|
||||
Validator::callback('is_string')->between(1,2)->setTemplate('{{name}} is not tasty')->assert('something');
|
||||
} catch (\Exception $e) {
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$this->assertEquals('\-"something" is not tasty
|
||||
\-"something" must be greater than 1', $e->getFullMessage());
|
||||
}
|
||||
|
@ -42,7 +45,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
try {
|
||||
Validator::string()->length(1,15)->assert('');
|
||||
} catch (\Exception $e) {
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$this->assertEquals('\-These rules must pass for ""
|
||||
\-"" must have a length between 1 and 15', $e->getFullMessage());
|
||||
}
|
||||
|
@ -70,7 +73,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
$usernameValidator = Validator::alnum('_')->length(1,15)->noWhitespace();
|
||||
try {
|
||||
$usernameValidator->assert('really messed up screen#name');
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$e->findMessages(array('alnum', 'length', 'noWhitespace'));
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +85,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
->key('birthdate', Validator::date())
|
||||
->setName("User Subscription Form")
|
||||
->assert(array('username' => '', 'birthdate' => ''));
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$this->assertEquals('\-These rules must pass for User Subscription Form
|
||||
|-Key username must be valid
|
||||
| \-"" must have a length between 1 and 32
|
||||
|
@ -110,4 +113,16 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$this->assertSame($validator, $validator->not($validator->notEmpty()));
|
||||
}
|
||||
|
||||
public function testDoNotRelyOnNestedValidationExceptionInterfaceForCheck()
|
||||
{
|
||||
$usernameValidator = Validator::alnum('_')->length(1, 15)->noWhitespace();
|
||||
try {
|
||||
$usernameValidator->check('really messed up screen#name');
|
||||
} catch (NestedValidationExceptionInterface $e) {
|
||||
$this->fail('Check used NestedValidationException');
|
||||
} catch (ValidationExceptionInterface $e) {
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue