Fix wrong behavior with nested exceptions

Use the same condition to not include child exception into the iterator
to also not show the message of the main exception when using
"getFullMessage()".

The method created to validate that condition should probably be in the
"ValidationException" itself, but this commit is meant to be a bug fix,
which will be released in a PATH version, and creating this public
method would imply that a MINOR version should be released.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2018-06-29 00:14:35 +01:00
parent f5ca4a298a
commit 4fdd2da19e
No known key found for this signature in database
GPG key ID: 221E9281655813A6
2 changed files with 46 additions and 12 deletions

View file

@ -122,6 +122,13 @@ class NestedValidationException extends ValidationException implements IteratorA
return $recursiveIteratorIterator;
}
private function isSkippable(ValidationException $exception)
{
return $exception instanceof self
&& 1 === $exception->getRelated()->count()
&& false === $exception->hasCustomTemplate();
}
/**
* @return SplObjectStorage
*/
@ -136,9 +143,7 @@ class NestedValidationException extends ValidationException implements IteratorA
$lastDepthOriginal = 0;
$knownDepths = [];
foreach ($recursiveIteratorIterator as $childException) {
if ($childException instanceof self
&& $childException->getRelated()->count() > 0
&& $childException->getRelated()->count() < 2) {
if ($this->isSkippable($childException)) {
continue;
}
@ -147,8 +152,7 @@ class NestedValidationException extends ValidationException implements IteratorA
if (isset($knownDepths[$currentDepthOriginal])) {
$currentDepth = $knownDepths[$currentDepthOriginal];
} elseif ($currentDepthOriginal > $lastDepthOriginal
&& ($this->hasCustomTemplate() || $exceptionIterator->count() != 1)) {
} elseif ($currentDepthOriginal > $lastDepthOriginal) {
++$currentDepth;
}
@ -195,18 +199,21 @@ class NestedValidationException extends ValidationException implements IteratorA
*/
public function getFullMessage()
{
$marker = '-';
$messages = [];
$exceptions = $this->getIterator();
$leveler = 1;
if ($this->hasCustomTemplate() || count($exceptions) != 1) {
$messages[] = sprintf('%s %s', $marker, $this->getMessage());
if (!$this->isSkippable($this)) {
$leveler = 0;
$messages[] = sprintf('- %s', $this->getMessage());
}
$exceptions = $this->getIterator();
foreach ($exceptions as $exception) {
$depth = $exceptions[$exception]['depth'];
$prefix = str_repeat(' ', $depth * 2);
$messages[] = sprintf('%s%s %s', $prefix, $marker, $exception->getMessage());
$messages[] = sprintf(
'%s- %s',
str_repeat(' ', ($exceptions[$exception]['depth'] - $leveler) * 2),
$exception->getMessage()
);
}
return implode(PHP_EOL, $messages);

View file

@ -0,0 +1,27 @@
--DESCRIPTION--
The previous output was:
- All of the required rules must pass for `{ "A", "B", "B" }`
- Each item in `{ "A", "B", "B" }` must be valid
- "A" must equal 1
- "B" must equal 1
- "B" must equal 1
--FILE--
<?php
require 'vendor/autoload.php';
use Respect\Validation\Exceptions\AllOfException;
use Respect\Validation\Validator as v;
try {
v::each(v::equals(1))->assert(['A', 'B', 'B']);
} catch (AllOfException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
?>
--EXPECTF--
- Each item in { "A", "B", "B" } must be valid
- "A" must be equals 1
- "B" must be equals 1
- "B" must be equals 1