bug #10687 [Validator] Fixed string conversion in constraint violations (eagleoneraptor, webmozart)

This PR was merged into the 2.3 branch.

Discussion
----------

[Validator] Fixed string conversion in constraint violations

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #10675
| License       | MIT
| Doc PR        | -

Commits
-------

32ae95b [Validator] Added more detailed inline documentation
08ea6d3 [Validator] Removed information from the violation output if the value is an array, object or resource
d6a783f [Validator] Renamed valueToString() to formatValue(); added missing formatValue() calls
71897d7 [Validator] Fixed CS
cea4155 [Validator] Fixed date-to-string conversion tests to match ICU 51
5aa7e6d [Validator] Added "{{ value }}" parameters where they were missing
f329552 [Validator] Simplified and explained the LuhnValidator
bff09f2 [Validator] Simplified IssnValidator
224e70f [Validator] Fixed and simplified IsbnValidator
fd58870 [Validator] Simplified IBAN validation algorithm
97243bc [Validator] Fixed value-to-string conversion in constraint violations
75e8815 [Validator] Fix constraint violation message parameterization
This commit is contained in:
Bernhard Schussek 2014-07-30 14:38:50 +02:00
commit 7d7b5c724f
59 changed files with 546 additions and 279 deletions

View File

@ -32,4 +32,110 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface
{
$this->context = $context;
}
/**
* Returns a string representation of the type of the value.
*
* This method should be used if you pass the type of a value as
* message parameter to a constraint violation. Note that such
* parameters should usually not be included in messages aimed at
* non-technical people.
*
* @param mixed $value The value to return the type of
*
* @return string The type of the value
*/
protected function formatTypeOf($value)
{
return is_object($value) ? get_class($value) : gettype($value);
}
/**
* Returns a string representation of the value.
*
* This method returns the equivalent PHP tokens for most scalar types
* (i.e. "false" for false, "1" for 1 etc.). Strings are always wrapped
* in double quotes ("). Objects, arrays and resources are formatted as
* "object", "array" and "resource". If the parameter $prettyDateTime
* is set to true, {@link \DateTime} objects will be formatted as
* RFC-3339 dates ("Y-m-d H:i:s").
*
* Be careful when passing message parameters to a constraint violation
* that (may) contain objects, arrays or resources. These parameters
* should only be displayed for technical users. Non-technical users
* won't know what an "object", "array" or "resource" is and will be
* confused by the violation message.
*
* @param mixed $value The value to format as string
* @param bool $prettyDateTime Whether to format {@link \DateTime}
* objects as RFC-3339 dates ("Y-m-d H:i:s")
*
* @return string The string representation of the passed value
*/
protected function formatValue($value, $prettyDateTime = false)
{
if ($prettyDateTime && $value instanceof \DateTime) {
if (class_exists('IntlDateFormatter')) {
$locale = \Locale::getDefault();
$formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT);
return $formatter->format($value);
}
return $value->format('Y-m-d H:i:s');
}
if (is_object($value)) {
return 'object';
}
if (is_array($value)) {
return 'array';
}
if (is_string($value)) {
return '"'.$value.'"';
}
if (is_resource($value)) {
return 'resource';
}
if (null === $value) {
return 'null';
}
if (false === $value) {
return 'false';
}
if (true === $value) {
return 'true';
}
return (string) $value;
}
/**
* Returns a string representation of a list of values.
*
* Each of the values is converted to a string using
* {@link formatValue()}. The values are then concatenated with commas.
*
* @param array $values A list of values
* @param bool $prettyDateTime Whether to format {@link \DateTime}
* objects as RFC-3339 dates ("Y-m-d H:i:s")
*
* @return string The string representation of the value list
*
* @see formatValue()
*/
protected function formatValues(array $values, $prettyDateTime = false)
{
foreach ($values as $key => $value) {
$values[$key] = $this->formatValue($value, $prettyDateTime);
}
return implode(', ', $values);
}
}

View File

@ -96,9 +96,9 @@ class ConstraintViolation implements ConstraintViolationInterface
public function __toString()
{
if (is_object($this->root)) {
$class = get_class($this->root);
$class = 'Object('.get_class($this->root).')';
} elseif (is_array($this->root)) {
$class = "Array";
$class = 'Array';
} else {
$class = (string) $this->root;
}

View File

@ -32,41 +32,13 @@ abstract class AbstractComparisonValidator extends ConstraintValidator
if (!$this->compareValues($value, $constraint->value)) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->valueToString($constraint->value),
'{{ compared_value }}' => $this->valueToString($constraint->value),
'{{ compared_value_type }}' => $this->valueToType($constraint->value)
'{{ value }}' => $this->formatValue($value, true),
'{{ compared_value }}' => $this->formatValue($constraint->value, true),
'{{ compared_value_type }}' => $this->formatTypeOf($constraint->value)
));
}
}
/**
* Returns a string representation of the type of the value.
*
* @param mixed $value
*
* @return string
*/
private function valueToType($value)
{
return is_object($value) ? get_class($value) : gettype($value);
}
/**
* Returns a string representation of the value.
*
* @param mixed $value
*
* @return string
*/
private function valueToString($value)
{
if ($value instanceof \DateTime) {
return $value->format('Y-m-d H:i:s');
}
return var_export($value, true);
}
/**
* Compares the two given values to find if their relationship is valid
*

View File

@ -27,7 +27,9 @@ class BlankValidator extends ConstraintValidator
public function validate($value, Constraint $constraint)
{
if ('' !== $value && null !== $value) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value)
));
}
}
}

View File

@ -108,7 +108,9 @@ class CardSchemeValidator extends ConstraintValidator
}
if (!is_numeric($value)) {
$this->context->addViolation($constraint->message);
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
return;
}
@ -124,6 +126,8 @@ class CardSchemeValidator extends ConstraintValidator
}
}
$this->context->addViolation($constraint->message);
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}

View File

@ -59,25 +59,33 @@ class ChoiceValidator extends ConstraintValidator
if ($constraint->multiple) {
foreach ($value as $_value) {
if (!in_array($_value, $choices, $constraint->strict)) {
$this->context->addViolation($constraint->multipleMessage, array('{{ value }}' => $_value));
$this->context->addViolation($constraint->multipleMessage, array(
'{{ value }}' => $this->formatValue($_value),
));
}
}
$count = count($value);
if ($constraint->min !== null && $count < $constraint->min) {
$this->context->addViolation($constraint->minMessage, array('{{ limit }}' => $constraint->min), null, (int) $constraint->min);
$this->context->addViolation($constraint->minMessage, array(
'{{ limit }}' => $constraint->min
), null, (int) $constraint->min);
return;
}
if ($constraint->max !== null && $count > $constraint->max) {
$this->context->addViolation($constraint->maxMessage, array('{{ limit }}' => $constraint->max), null, (int) $constraint->max);
$this->context->addViolation($constraint->maxMessage, array(
'{{ limit }}' => $constraint->max
), null, (int) $constraint->max);
return;
}
} elseif (!in_array($value, $choices, $constraint->strict)) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value)
));
}
}
}

View File

@ -48,7 +48,7 @@ class CollectionValidator extends ConstraintValidator
}
} elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) {
$this->context->addViolationAt('['.$field.']', $constraint->missingFieldsMessage, array(
'{{ field }}' => $field
'{{ field }}' => $this->formatValue($field)
), null);
}
}
@ -57,7 +57,7 @@ class CollectionValidator extends ConstraintValidator
foreach ($value as $field => $fieldValue) {
if (!isset($constraint->fields[$field])) {
$this->context->addViolationAt('['.$field.']', $constraint->extraFieldsMessage, array(
'{{ field }}' => $field
'{{ field }}' => $this->formatValue($field)
), $fieldValue);
}
}

View File

@ -42,7 +42,9 @@ class CountryValidator extends ConstraintValidator
$countries = Intl::getRegionBundle()->getCountryNames();
if (!isset($countries[$value])) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -42,7 +42,9 @@ class CurrencyValidator extends ConstraintValidator
$currencies = Intl::getCurrencyBundle()->getCurrencyNames();
if (!isset($currencies[$value])) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -40,7 +40,9 @@ class DateValidator extends ConstraintValidator
$value = (string) $value;
if (!preg_match(static::PATTERN, $value, $matches) || !checkdate($matches[2], $matches[3], $matches[1])) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -50,7 +50,9 @@ class EmailValidator extends ConstraintValidator
}
if (!$valid) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}

View File

@ -30,6 +30,8 @@ class FalseValidator extends ConstraintValidator
return;
}
$this->context->addViolation($constraint->message);
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}

View File

@ -96,13 +96,17 @@ class FileValidator extends ConstraintValidator
$path = $value instanceof FileObject ? $value->getPathname() : (string) $value;
if (!is_file($path)) {
$this->context->addViolation($constraint->notFoundMessage, array('{{ file }}' => $path));
$this->context->addViolation($constraint->notFoundMessage, array(
'{{ file }}' => $this->formatValue($path)
));
return;
}
if (!is_readable($path)) {
$this->context->addViolation($constraint->notReadableMessage, array('{{ file }}' => $path));
$this->context->addViolation($constraint->notReadableMessage, array(
'{{ file }}' => $this->formatValue($path)
));
return;
}
@ -126,10 +130,10 @@ class FileValidator extends ConstraintValidator
if ($size > $limit) {
$this->context->addViolation($constraint->maxSizeMessage, array(
'{{ size }}' => $size,
'{{ limit }}' => $limit,
'{{ suffix }}' => $suffix,
'{{ file }}' => $path,
'{{ size }}' => $size,
'{{ limit }}' => $limit,
'{{ suffix }}' => $suffix,
'{{ file }}' => $this->formatValue($path),
));
return;
@ -161,9 +165,9 @@ class FileValidator extends ConstraintValidator
if (false === $valid) {
$this->context->addViolation($constraint->mimeTypesMessage, array(
'{{ type }}' => '"'.$mime.'"',
'{{ types }}' => '"'.implode('", "', $mimeTypes) .'"',
'{{ file }}' => $path,
'{{ type }}' => $this->formatValue($mime),
'{{ types }}' => $this->formatValues($mimeTypes),
'{{ file }}' => $this->formatValue($path),
));
}
}

View File

@ -13,10 +13,12 @@ namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
* @author Manuel Reinhard <manu@sprain.ch>
* @author Michael Schummel
* @author Bernhard Schussek <bschussek@gmail.com>
* @link http://www.michael-schummel.de/2007/10/05/iban-prufung-mit-php/
*/
class IbanValidator extends ConstraintValidator
@ -30,41 +32,100 @@ class IbanValidator extends ConstraintValidator
return;
}
// An IBAN without a country code is not an IBAN.
if (0 === preg_match('/[A-Z]/', $value)) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}
$value = (string) $value;
// Remove spaces
$canonicalized = str_replace(' ', '', $value);
if (strlen($canonicalized) < 4) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
return;
}
$teststring = preg_replace('/\s+/', '', $value);
if (strlen($teststring) < 4) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
// The IBAN must have at least 4 characters, start with a country
// code and contain only digits and (uppercase) characters
if (strlen($canonicalized) < 4 || !ctype_upper($canonicalized{0})
|| !ctype_upper($canonicalized{1}) || !ctype_alnum($canonicalized)) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
return;
}
$teststring = substr($teststring, 4)
.strval(ord($teststring{0}) - 55)
.strval(ord($teststring{1}) - 55)
.substr($teststring, 2, 2);
// Move the first four characters to the end
// e.g. CH93 0076 2011 6238 5295 7
// -> 0076 2011 6238 5295 7 CH93
$canonicalized = substr($canonicalized, 4).substr($canonicalized, 0, 4);
$teststring = preg_replace_callback('/[A-Z]/', function ($letter) {
return intval(ord(strtolower($letter[0])) - 87);
}, $teststring);
// Convert all remaining letters to their ordinals
// The result is an integer, which is too large for PHP's int
// data type, so we store it in a string instead.
// e.g. 0076 2011 6238 5295 7 CH93
// -> 0076 2011 6238 5295 7 121893
$checkSum = $this->toBigInt($canonicalized);
$rest = 0;
$strlen = strlen($teststring);
for ($pos = 0; $pos < $strlen; $pos += 7) {
$part = strval($rest).substr($teststring, $pos, 7);
$rest = intval($part) % 97;
if (false === $checkSum) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
return;
}
if ($rest != 1) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
// Do a modulo-97 operation on the large integer
// We cannot use PHP's modulo operator, so we calculate the
// modulo step-wisely instead
if (1 !== $this->bigModulo97($checkSum)) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
return;
}
}
private function toBigInt($string)
{
$chars = str_split($string);
$bigInt = '';
foreach ($chars as $char) {
// Convert uppercase characters to ordinals, starting with 10 for "A"
if (ctype_upper($char)) {
$bigInt .= (ord($char) - 55);
continue;
}
// Disallow lowercase characters
if (ctype_lower($char)) {
return false;
}
// Simply append digits
$bigInt .= $char;
}
return $bigInt;
}
private function bigModulo97($bigInt)
{
$parts = str_split($bigInt, 7);
$rest = 0;
foreach ($parts as $part) {
$rest = ($rest.$part) % 97;
}
return $rest;
}
}

View File

@ -91,7 +91,9 @@ class IpValidator extends ConstraintValidator
}
if (!filter_var($value, FILTER_VALIDATE_IP, $flag)) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -42,5 +42,8 @@ class Isbn extends Constraint
if (null === $this->isbn10 && null === $this->isbn13) {
throw new MissingOptionsException(sprintf('Either option "isbn10" or "isbn13" must be given for constraint "%s".', __CLASS__), array('isbn10', 'isbn13'));
}
$this->isbn10 = (bool) $this->isbn10;
$this->isbn13 = (bool) $this->isbn13;
}
}

View File

@ -19,6 +19,7 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
* Validates whether the value is a valid ISBN-10 or ISBN-13.
*
* @author The Whole Life To Learn <thewholelifetolearn@gmail.com>
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @see https://en.wikipedia.org/wiki/Isbn
*/
@ -37,53 +38,71 @@ class IsbnValidator extends ConstraintValidator
throw new UnexpectedTypeException($value, 'string');
}
if (!is_numeric($value)) {
$value = str_replace('-', '', $value);
$value = (string) $value;
$canonical = strtoupper(str_replace('-', '', $value));
if ($constraint->isbn10 && $this->isValidIsbn10($canonical)) {
return;
}
$validation = 0;
$value = strtoupper($value);
$valueLength = strlen($value);
if ($constraint->isbn13 && $this->isValidIsbn13($canonical)) {
return;
}
if (10 === $valueLength && null !== $constraint->isbn10) {
for ($i = 0; $i < 10; $i++) {
if ($value[$i] == 'X') {
$validation += 10 * intval(10 - $i);
} else {
$validation += intval($value[$i]) * intval(10 - $i);
}
}
if ($validation % 11 != 0) {
if (null !== $constraint->isbn13) {
$this->context->addViolation($constraint->bothIsbnMessage);
} else {
$this->context->addViolation($constraint->isbn10Message);
}
}
} elseif (13 === $valueLength && null !== $constraint->isbn13) {
for ($i = 0; $i < 13; $i += 2) {
$validation += intval($value[$i]);
}
for ($i = 1; $i < 12; $i += 2) {
$validation += intval($value[$i]) * 3;
}
if ($validation % 10 != 0) {
if (null !== $constraint->isbn10) {
$this->context->addViolation($constraint->bothIsbnMessage);
} else {
$this->context->addViolation($constraint->isbn13Message);
}
}
if ($constraint->isbn10 && $constraint->isbn13) {
$this->context->addViolation($constraint->bothIsbnMessage, array(
'{{ value }}' => $this->formatValue($value),
));
} elseif ($constraint->isbn10) {
$this->context->addViolation($constraint->isbn10Message, array(
'{{ value }}' => $this->formatValue($value),
));
} else {
if (null !== $constraint->isbn10 && null !== $constraint->isbn13) {
$this->context->addViolation($constraint->bothIsbnMessage);
} elseif (null !== $constraint->isbn10) {
$this->context->addViolation($constraint->isbn10Message);
} else {
$this->context->addViolation($constraint->isbn13Message);
}
$this->context->addViolation($constraint->isbn13Message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
private function isValidIsbn10($isbn)
{
if (10 !== strlen($isbn)) {
return false;
}
$checkSum = 0;
for ($i = 0; $i < 10; ++$i) {
if ('X' === $isbn{$i}) {
$digit = 10;
} elseif (ctype_digit($isbn{$i})) {
$digit = $isbn{$i};
} else {
return false;
}
$checkSum += $digit * intval(10 - $i);
}
return 0 === $checkSum % 11;
}
private function isValidIsbn13($isbn)
{
if (13 !== strlen($isbn) || !ctype_digit($isbn)) {
return false;
}
$checkSum = 0;
for ($i = 0; $i < 13; $i += 2) {
$checkSum += $isbn{$i};
}
for ($i = 1; $i < 12; $i += 2) {
$checkSum += $isbn{$i} * 3;
}
return 0 === $checkSum % 10;
}
}

View File

@ -37,26 +37,35 @@ class IssnValidator extends ConstraintValidator
throw new UnexpectedTypeException($value, 'string');
}
$value = (string) $value;
// Compose regex pattern
$digitsPattern = $constraint->requireHyphen ? '\d{4}-\d{3}' : '\d{4}-?\d{3}';
$checksumPattern = $constraint->caseSensitive ? '[\d|X]' : '[\d|X|x]';
$pattern = "/^".$digitsPattern.$checksumPattern."$/";
$checkSumPattern = $constraint->caseSensitive ? '[\d|X]' : '[\d|X|x]';
$pattern = "/^".$digitsPattern.$checkSumPattern."$/";
if (!preg_match($pattern, $value)) {
$this->context->addViolation($constraint->message);
} else {
$digits = str_split(strtoupper(str_replace('-', '', $value)));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
$sum = 0;
for ($i = 8; $i > 1; $i--) {
$sum += $i * (int) array_shift($digits);
}
return;
}
$checksum = 'X' == reset($digits) ? 10 : (int) reset($digits);
$canonical = strtoupper(str_replace('-', '', $value));
if (0 != ($sum + $checksum) % 11) {
$this->context->addViolation($constraint->message);
}
// Calculate a checksum. "X" equals 10.
$checkSum = 'X' === $canonical{7} ? 10 : $canonical{7};
for ($i = 0; $i < 7; ++$i) {
// Multiply the first digit by 8, the second by 7, etc.
$checkSum += (8-$i) * $canonical{$i};
}
if (0 !== $checkSum % 11) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -42,7 +42,9 @@ class LanguageValidator extends ConstraintValidator
$languages = Intl::getLanguageBundle()->getLanguageNames();
if (!isset($languages[$value])) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -45,7 +45,7 @@ class LengthValidator extends ConstraintValidator
if ($constraint->min == $constraint->max && $length != $constraint->min) {
$this->context->addViolation($constraint->exactMessage, array(
'{{ value }}' => $stringValue,
'{{ value }}' => $this->formatValue($stringValue),
'{{ limit }}' => $constraint->min,
), $value, (int) $constraint->min);
@ -54,7 +54,7 @@ class LengthValidator extends ConstraintValidator
if (null !== $constraint->max && $length > $constraint->max) {
$this->context->addViolation($constraint->maxMessage, array(
'{{ value }}' => $stringValue,
'{{ value }}' => $this->formatValue($stringValue),
'{{ limit }}' => $constraint->max,
), $value, (int) $constraint->max);
@ -63,7 +63,7 @@ class LengthValidator extends ConstraintValidator
if (null !== $constraint->min && $length < $constraint->min) {
$this->context->addViolation($constraint->minMessage, array(
'{{ value }}' => $stringValue,
'{{ value }}' => $this->formatValue($stringValue),
'{{ limit }}' => $constraint->min,
), $value, (int) $constraint->min);
}

View File

@ -42,7 +42,9 @@ class LocaleValidator extends ConstraintValidator
$locales = Intl::getLocaleBundle()->getLocaleNames();
if (!isset($locales[$value])) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -24,11 +24,12 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
* @see http://en.wikipedia.org/wiki/Luhn_algorithm
* @author Tim Nagel <t.nagel@infinite.net.au>
* @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class LuhnValidator extends ConstraintValidator
{
/**
* Validates a creditcard number with the Luhn algorithm.
* Validates a credit card number with the Luhn algorithm.
*
* @param mixed $value
* @param Constraint $constraint
@ -39,28 +40,48 @@ class LuhnValidator extends ConstraintValidator
return;
}
/**
* need to work with strings only because long numbers are treated as floats and don't work with strlen
*/
if (!is_string($value)) {
// Work with strings only, because long numbers are represented as floats
// internally and don't work with strlen()
if (!is_string($value) && !(is_object($value) && method_exists($value, '__toString'))) {
throw new UnexpectedTypeException($value, 'string');
}
if (!is_numeric($value)) {
$this->context->addViolation($constraint->message);
$value = (string) $value;
if (!ctype_digit($value)) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
return;
}
$checkSum = 0;
$length = strlen($value);
$oddLength = $length % 2;
for ($sum = 0, $i = $length - 1; $i >= 0; $i--) {
$digit = (int) $value[$i];
$sum += (($i % 2) === $oddLength) ? array_sum(str_split($digit * 2)) : $digit;
// Starting with the last digit and walking left, add every second
// digit to the check sum
// e.g. 7 9 9 2 7 3 9 8 7 1 3
// ^ ^ ^ ^ ^ ^
// = 7 + 9 + 7 + 9 + 7 + 3
for ($i = $length - 1; $i >= 0; $i -= 2) {
$checkSum += $value{$i};
}
if ($sum === 0 || ($sum % 10) !== 0) {
$this->context->addViolation($constraint->message);
// Starting with the second last digit and walking left, double every
// second digit and add it to the check sum
// For doubles greater than 9, sum the individual digits
// e.g. 7 9 9 2 7 3 9 8 7 1 3
// ^ ^ ^ ^ ^
// = 1+8 + 4 + 6 + 1+6 + 2
for ($i = $length - 2; $i >= 0; $i -= 2) {
$checkSum += array_sum(str_split($value{$i} * 2));
}
if (0 === $checkSum || 0 !== $checkSum % 10) {
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -27,7 +27,9 @@ class NotBlankValidator extends ConstraintValidator
public function validate($value, Constraint $constraint)
{
if (false === $value || (empty($value) && '0' != $value)) {
$this->context->addViolation($constraint->message);
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -27,13 +27,9 @@ class NullValidator extends ConstraintValidator
public function validate($value, Constraint $constraint)
{
if (null !== $value) {
if (is_object($value)) {
$value = get_class($value);
} elseif (is_array($value)) {
$value = 'Array';
}
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -30,7 +30,7 @@ class RangeValidator extends ConstraintValidator
if (!is_numeric($value)) {
$this->context->addViolation($constraint->invalidMessage, array(
'{{ value }}' => $value,
'{{ value }}' => $this->formatValue($value),
));
return;

View File

@ -41,7 +41,9 @@ class RegexValidator extends ConstraintValidator
$value = (string) $value;
if ($constraint->match xor preg_match($constraint->pattern, $value)) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -40,7 +40,9 @@ class TimeValidator extends ConstraintValidator
$value = (string) $value;
if (!preg_match(static::PATTERN, $value)) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -31,7 +31,9 @@ class TrueValidator extends ConstraintValidator
}
if (true !== $value && 1 !== $value && '1' !== $value) {
$this->context->addViolation($constraint->message);
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -44,7 +44,7 @@ class TypeValidator extends ConstraintValidator
}
$this->context->addViolation($constraint->message, array(
'{{ value }}' => is_object($value) ? get_class($value) : (is_array($value) ? 'Array' : (string) $value),
'{{ value }}' => $this->formatValue($value),
'{{ type }}' => $constraint->type,
));
}

View File

@ -51,11 +51,12 @@ class UrlValidator extends ConstraintValidator
}
$value = (string) $value;
$pattern = sprintf(static::PATTERN, implode('|', $constraint->protocols));
if (!preg_match($pattern, $value)) {
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $this->formatValue($value),
));
}
}
}

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\Validator\Tests\Constraints;
use Symfony\Component\Intl\Util\IntlTestHelper;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\AbstractComparisonValidator;
@ -29,6 +30,8 @@ abstract class AbstractComparisonValidatorTestCase extends \PHPUnit_Framework_Te
->disableOriginalConstructor()
->getMock();
$this->validator->initialize($this->context);
\Locale::setDefault('en');
}
/**
@ -71,12 +74,19 @@ abstract class AbstractComparisonValidatorTestCase extends \PHPUnit_Framework_Te
/**
* @dataProvider provideInvalidComparisons
* @param mixed $dirtyValue
* @param mixed $dirtyValueAsString
* @param mixed $comparedValue
* @param mixed $comparedValueString
* @param string $comparedValueType
*/
public function testInvalidComparisonToValue($dirtyValue, $comparedValue, $comparedValueString, $comparedValueType)
public function testInvalidComparisonToValue($dirtyValue, $dirtyValueAsString, $comparedValue, $comparedValueString, $comparedValueType)
{
// Conversion of dates to string differs between ICU versions
// Make sure we have the correct version loaded
if ($dirtyValue instanceof \DateTime) {
IntlTestHelper::requireIntl($this);
}
$constraint = $this->createConstraint(array('value' => $comparedValue));
$constraint->message = 'Constraint Message';
@ -87,7 +97,7 @@ abstract class AbstractComparisonValidatorTestCase extends \PHPUnit_Framework_Te
$this->context->expects($this->once())
->method('addViolation')
->with('Constraint Message', array(
'{{ value }}' => $comparedValueString,
'{{ value }}' => $dirtyValueAsString,
'{{ compared_value }}' => $comparedValueString,
'{{ compared_value_type }}' => $comparedValueType
));

View File

@ -51,7 +51,7 @@ class BlankValidatorTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider getInvalidValues
*/
public function testInvalidValues($value)
public function testInvalidValues($value, $valueAsString)
{
$constraint = new Blank(array(
'message' => 'myMessage'
@ -60,7 +60,7 @@ class BlankValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $value,
'{{ value }}' => $valueAsString,
));
$this->validator->validate($value, $constraint);
@ -69,10 +69,10 @@ class BlankValidatorTest extends \PHPUnit_Framework_TestCase
public function getInvalidValues()
{
return array(
array('foobar'),
array(0),
array(false),
array(1234),
array('foobar', '"foobar"'),
array(0, '0'),
array(false, 'false'),
array(1234, '1234'),
);
}
}

View File

@ -158,7 +158,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => 'baz',
'{{ value }}' => '"baz"',
), null, null);
$this->validator->validate('baz', $constraint);
@ -175,7 +175,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => 'baz',
'{{ value }}' => '"baz"',
));
$this->validator->validate(array('foo', 'baz'), $constraint);
@ -255,7 +255,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => '2',
'{{ value }}' => '"2"',
));
$this->validator->validate('2', $constraint);
@ -287,7 +287,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => '3',
'{{ value }}' => '"3"',
));
$this->validator->validate(array(2, '3'), $constraint);

View File

@ -147,7 +147,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolationAt')
->with('[baz]', 'myMessage', array(
'{{ field }}' => 'baz'
'{{ field }}' => '"baz"'
));
$this->validator->validate($data, new Collection(array(
@ -211,7 +211,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolationAt')
->with('[foo]', 'myMessage', array(
'{{ field }}' => 'foo',
'{{ field }}' => '"foo"',
));
$this->validator->validate($data, $constraint);
@ -331,7 +331,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolationAt')
->with('[foo]', 'myMessage', array(
'{{ field }}' => 'foo',
'{{ field }}' => '"foo"',
));
$this->validator->validate($data, new Collection(array(

View File

@ -96,7 +96,7 @@ class DateTimeValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $dateTime,
'{{ value }}' => '"'.$dateTime.'"',
));
$this->validator->validate($dateTime, $constraint);

View File

@ -96,7 +96,7 @@ class DateValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $date,
'{{ value }}' => '"'.$date.'"',
));
$this->validator->validate($date, $constraint);

View File

@ -88,7 +88,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $email,
'{{ value }}' => '"'.$email.'"',
));
$this->validator->validate($email, $constraint);

View File

@ -49,9 +49,9 @@ class EqualToValidatorTest extends AbstractComparisonValidatorTestCase
public function provideInvalidComparisons()
{
return array(
array(1, 2, '2', 'integer'),
array('22', '333', "'333'", 'string'),
array(new \DateTime('2001-01-01'), new \DateTime('2000-01-01'), '2000-01-01 00:00:00', 'DateTime')
array(1, '1', 2, '2', 'integer'),
array('22', '"22"', '333', '"333"', 'string'),
array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime')
);
}
}

View File

@ -56,7 +56,7 @@ class FalseValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array());
->with('myMessage', array('{{ value }}' => 'true'));
$this->validator->validate(true, $constraint);
}

View File

@ -29,7 +29,7 @@ class FileValidatorPathTest extends FileValidatorTest
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ file }}' => 'foobar',
'{{ file }}' => '"foobar"',
));
$this->validator->validate('foobar', $constraint);

View File

@ -101,7 +101,7 @@ abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase
'{{ limit }}' => '10',
'{{ size }}' => '11',
'{{ suffix }}' => 'bytes',
'{{ file }}' => $this->path,
'{{ file }}' => '"'.$this->path.'"',
));
$this->validator->validate($this->getFile($this->path), $constraint);
@ -122,7 +122,7 @@ abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase
'{{ limit }}' => '1',
'{{ size }}' => '1.4',
'{{ suffix }}' => 'kB',
'{{ file }}' => $this->path,
'{{ file }}' => '"'.$this->path.'"',
));
$this->validator->validate($this->getFile($this->path), $constraint);
@ -143,7 +143,7 @@ abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase
'{{ limit }}' => '1',
'{{ size }}' => '1.4',
'{{ suffix }}' => 'MB',
'{{ file }}' => $this->path,
'{{ file }}' => '"'.$this->path.'"',
));
$this->validator->validate($this->getFile($this->path), $constraint);
@ -245,7 +245,7 @@ abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase
->with('myMessage', array(
'{{ type }}' => '"application/pdf"',
'{{ types }}' => '"image/png", "image/jpg"',
'{{ file }}' => $this->path,
'{{ file }}' => '"'.$this->path.'"',
));
$this->validator->validate($file, $constraint);
@ -279,7 +279,7 @@ abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase
->with('myMessage', array(
'{{ type }}' => '"application/pdf"',
'{{ types }}' => '"image/*", "image/jpg"',
'{{ file }}' => $this->path,
'{{ file }}' => '"'.$this->path.'"',
));
$this->validator->validate($file, $constraint);

View File

@ -51,9 +51,9 @@ class GreaterThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCas
public function provideInvalidComparisons()
{
return array(
array(1, 2, '2', 'integer'),
array(new \DateTime('2000/01/01'), new \DateTime('2005/01/01'), '2005-01-01 00:00:00', 'DateTime'),
array('b', 'c', "'c'", 'string')
array(1, '1', 2, '2', 'integer'),
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'),
array('b', '"b"', 'c', '"c"', 'string')
);
}
}

View File

@ -48,12 +48,12 @@ class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase
public function provideInvalidComparisons()
{
return array(
array(1, 2, '2', 'integer'),
array(2, 2, '2', 'integer'),
array(new \DateTime('2000/01/01'), new \DateTime('2005/01/01'), '2005-01-01 00:00:00', 'DateTime'),
array(new \DateTime('2000/01/01'), new \DateTime('2000/01/01'), '2000-01-01 00:00:00', 'DateTime'),
array('22', '333', "'333'", 'string'),
array('22', '22', "'22'", 'string')
array(1, '1', 2, '2', 'integer'),
array(2, '2', 2, '2', 'integer'),
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2005/01/01'), 'Jan 1, 2005, 12:00 AM', 'DateTime'),
array(new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000/01/01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
array('22', '"22"', '333', '"333"', 'string'),
array('22', '"22"', '22', '"22"', 'string')
);
}
}

View File

@ -54,6 +54,7 @@ class IbanValidatorTest extends \PHPUnit_Framework_TestCase
{
return array(
array('CH9300762011623852957'), // Switzerland without spaces
array('CH93 0076 2011 6238 5295 7'), // Switzerland with multiple spaces
//Country list
//http://www.rbs.co.uk/corporate/international/g0/guide-to-international-business/regulatory-information/iban/iban-example.ashx
@ -163,7 +164,7 @@ class IbanValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $iban,
'{{ value }}' => '"'.$iban.'"',
));
$this->validator->validate($iban, $constraint);
@ -182,6 +183,7 @@ class IbanValidatorTest extends \PHPUnit_Framework_TestCase
array('foo'),
array('123'),
array('0750447346'),
array('CH930076201162385295]'),
//Ibans with lower case values are invalid
array('Ae260211000000230064016'),

View File

@ -50,11 +50,11 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
public function provideInvalidComparisons()
{
return array(
array(1, 2, '2', 'integer'),
array(2, '2', "'2'", 'string'),
array('22', '333', "'333'", 'string'),
array(new \DateTime('2001-01-01'), new \DateTime('2001-01-01'), '2001-01-01 00:00:00', 'DateTime'),
array(new \DateTime('2001-01-01'), new \DateTime('1999-01-01'), '1999-01-01 00:00:00', 'DateTime')
array(1, '1', 2, '2', 'integer'),
array(2, '2', '2', '"2"', 'string'),
array('22', '"22"', '333', '"333"', 'string'),
array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', 'DateTime'),
array(new \DateTime('2001-01-01'), 'Jan 1, 2001, 12:00 AM', new \DateTime('1999-01-01'), 'Jan 1, 1999, 12:00 AM', 'DateTime')
);
}
}

View File

@ -162,7 +162,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -196,7 +196,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -224,7 +224,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -252,7 +252,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -276,7 +276,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -314,7 +314,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -342,7 +342,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -369,7 +369,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -393,7 +393,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -417,7 +417,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -441,7 +441,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);
@ -465,7 +465,7 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $ip,
'{{ value }}' => '"'.$ip.'"',
));
$this->validator->validate($ip, $constraint);

View File

@ -58,6 +58,10 @@ class IsbnValidatorTest extends \PHPUnit_Framework_TestCase
array('0-4X19-92611'),
array('0_45122_5244'),
array('2870#971#648'),
array('1A34567890'),
// chr(1) evaluates to 0
// 2070546810 is valid
array('2'.chr(1).'70546810'),
);
}
@ -92,6 +96,10 @@ class IsbnValidatorTest extends \PHPUnit_Framework_TestCase
array('980-0474292319'),
array('978_0451225245'),
array('978#0471292319'),
array('978-272C442282'),
// chr(1) evaluates to 0
// 978-2070546817 is valid
array('978-2'.chr(1).'70546817'),
);
}

View File

@ -167,7 +167,7 @@ class LengthValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', $this->identicalTo(array(
'{{ value }}' => (string) $value,
'{{ value }}' => '"'.$value.'"',
'{{ limit }}' => 4,
)), $this->identicalTo($value), 4);
@ -191,7 +191,7 @@ class LengthValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', $this->identicalTo(array(
'{{ value }}' => (string) $value,
'{{ value }}' => '"'.$value.'"',
'{{ limit }}' => 4,
)), $this->identicalTo($value), 4);
@ -216,7 +216,7 @@ class LengthValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', $this->identicalTo(array(
'{{ value }}' => (string) $value,
'{{ value }}' => '"'.$value.'"',
'{{ limit }}' => 4,
)), $this->identicalTo($value), 4);

View File

@ -51,9 +51,9 @@ class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase
public function provideInvalidComparisons()
{
return array(
array(2, 1, '1', 'integer'),
array(new \DateTime('2010-01-01'), new \DateTime('2000-01-01'), '2000-01-01 00:00:00', 'DateTime'),
array('c', 'b', "'b'", 'string')
array(2, '2', 1, '1', 'integer'),
array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
array('c', '"c"', 'b', '"b"', 'string')
);
}
}

View File

@ -48,11 +48,11 @@ class LessThanValidatorTest extends AbstractComparisonValidatorTestCase
public function provideInvalidComparisons()
{
return array(
array(3, 2, '2', 'integer'),
array(2, 2, '2', 'integer'),
array(new \DateTime('2010-01-01'), new \DateTime('2000-01-01'), '2000-01-01 00:00:00', 'DateTime'),
array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01'), '2000-01-01 00:00:00', 'DateTime'),
array('333', '22', "'22'", 'string'),
array(3, '3', 2, '2', 'integer'),
array(2, '2', 2, '2', 'integer'),
array(new \DateTime('2010-01-01'), 'Jan 1, 2010, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime'),
array('333', '"333"', '22', '"22"', 'string'),
);
}
}

View File

@ -48,10 +48,10 @@ class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase
public function provideInvalidComparisons()
{
return array(
array(3, 3, '3', 'integer'),
array('2', 2, '2', 'integer'),
array('a', 'a', "'a'", 'string'),
array(new \DateTime('2000-01-01'), new \DateTime('2000-01-01'), '2000-01-01 00:00:00', 'DateTime')
array(3, '3', 3, '3', 'integer'),
array('2', '"2"', 2, '2', 'integer'),
array('a', '"a"', 'a', '"a"', 'string'),
array(new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', new \DateTime('2000-01-01'), 'Jan 1, 2000, 12:00 AM', 'DateTime')
);
}
}

View File

@ -52,9 +52,9 @@ class NotIdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
$date = new \DateTime('2000-01-01');
return array(
array(3, 3, '3', 'integer'),
array('a', 'a', "'a'", 'string'),
array($date, $date, '2000-01-01 00:00:00', 'DateTime')
array(3, '3', 3, '3', 'integer'),
array('a', '"a"', 'a', '"a"', 'string'),
array($date, 'Jan 1, 2000, 12:00 AM', $date, 'Jan 1, 2000, 12:00 AM', 'DateTime')
);
}
}

View File

@ -43,7 +43,7 @@ class NullValidatorTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider getInvalidValues
*/
public function testInvalidValues($value, $readableValue)
public function testInvalidValues($value, $valueAsString)
{
$constraint = new Null(array(
'message' => 'myMessage'
@ -52,7 +52,7 @@ class NullValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $readableValue,
'{{ value }}' => $valueAsString,
));
$this->validator->validate($value, $constraint);
@ -61,13 +61,14 @@ class NullValidatorTest extends \PHPUnit_Framework_TestCase
public function getInvalidValues()
{
return array(
array(0, 0),
array(false, false),
array(true, true),
array('', ''),
array('foo bar', 'foo bar'),
array(new \DateTime(), 'DateTime'),
array(array(), 'Array'),
array(0, '0'),
array(false, 'false'),
array(true, 'true'),
array('', '""'),
array('foo bar', '"foo bar"'),
array(new \DateTime(), 'object'),
array(new \stdClass(), 'object'),
array(array(), 'array'),
);
}
}

View File

@ -234,4 +234,19 @@ class RangeValidatorTest extends \PHPUnit_Framework_TestCase
$this->validator->validate(21, $constraint);
}
public function testNonNumeric()
{
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => '"abcd"',
));
$this->validator->validate('abcd', new Range(array(
'min' => 10,
'max' => 20,
'invalidMessage' => 'myMessage',
)));
}
}

View File

@ -91,7 +91,7 @@ class RegexValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $value,
'{{ value }}' => '"'.$value.'"',
));
$this->validator->validate($value, $constraint);

View File

@ -96,7 +96,7 @@ class TimeValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $time,
'{{ value }}' => '"'.$time.'"',
));
$this->validator->validate($time, $constraint);

View File

@ -57,6 +57,7 @@ class TrueValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => 'false',
));
$this->validator->validate(false, $constraint);

View File

@ -134,34 +134,34 @@ class TypeValidatorTest extends \PHPUnit_Framework_TestCase
$file = $this->createFile();
return array(
array('foobar', 'numeric', 'foobar'),
array('foobar', 'boolean', 'foobar'),
array('0', 'integer', '0'),
array('1.5', 'float', '1.5'),
array('foobar', 'numeric', '"foobar"'),
array('foobar', 'boolean', '"foobar"'),
array('0', 'integer', '"0"'),
array('1.5', 'float', '"1.5"'),
array(12345, 'string', '12345'),
array($object, 'boolean', 'stdClass'),
array($object, 'numeric', 'stdClass'),
array($object, 'integer', 'stdClass'),
array($object, 'float', 'stdClass'),
array($object, 'string', 'stdClass'),
array($object, 'resource', 'stdClass'),
array($file, 'boolean', (string) $file),
array($file, 'numeric', (string) $file),
array($file, 'integer', (string) $file),
array($file, 'float', (string) $file),
array($file, 'string', (string) $file),
array($file, 'object', (string) $file),
array('12a34', 'digit', '12a34'),
array('1a#23', 'alnum', '1a#23'),
array('abcd1', 'alpha', 'abcd1'),
array("\nabc", 'cntrl', "\nabc"),
array("abc\n", 'graph', "abc\n"),
array('abCDE', 'lower', 'abCDE'),
array('ABcde', 'upper', 'ABcde'),
array("\nabc", 'print', "\nabc"),
array('abc&$!', 'punct', 'abc&$!'),
array("\nabc", 'space', "\nabc"),
array('AR1012', 'xdigit', 'AR1012'),
array($object, 'boolean', 'object'),
array($object, 'numeric', 'object'),
array($object, 'integer', 'object'),
array($object, 'float', 'object'),
array($object, 'string', 'object'),
array($object, 'resource', 'object'),
array($file, 'boolean', 'resource'),
array($file, 'numeric', 'resource'),
array($file, 'integer', 'resource'),
array($file, 'float', 'resource'),
array($file, 'string', 'resource'),
array($file, 'object', 'resource'),
array('12a34', 'digit', '"12a34"'),
array('1a#23', 'alnum', '"1a#23"'),
array('abcd1', 'alpha', '"abcd1"'),
array("\nabc", 'cntrl', "\"\nabc\""),
array("abc\n", 'graph', "\"abc\n\""),
array('abCDE', 'lower', '"abCDE"'),
array('ABcde', 'upper', '"ABcde"'),
array("\nabc", 'print', "\"\nabc\""),
array('abc&$!', 'punct', '"abc&$!"'),
array("\nabc", 'space', "\"\nabc\""),
array('AR1012', 'xdigit', '"AR1012"'),
);
}

View File

@ -131,7 +131,7 @@ class UrlValidatorTest extends \PHPUnit_Framework_TestCase
$this->context->expects($this->once())
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => $url,
'{{ value }}' => '"'.$url.'"',
));
$this->validator->validate($url, $constraint);