Merge pull request #222 from misantron/validators-patch

Array subset and uniqueElements validators
This commit is contained in:
Willem Wollebrants 2018-09-23 21:46:36 +02:00 committed by GitHub
commit e3b3eb31a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 365 additions and 226 deletions

View File

@ -149,6 +149,8 @@ V::lang('ar');
* `dateBefore` - Field is a valid date and is before the given date * `dateBefore` - Field is a valid date and is before the given date
* `dateAfter` - Field is a valid date and is after the given date * `dateAfter` - Field is a valid date and is after the given date
* `contains` - Field is a string and contains the given string * `contains` - Field is a string and contains the given string
* `subset` - Field is an array or a scalar and all elements are contained in the given array
* `containsUnique` - Field is an array and contains unique values
* `creditCard` - Field is a valid credit card number * `creditCard` - Field is a valid credit card number
* `instanceOf` - Field contains an instance of the given class * `instanceOf` - Field contains an instance of the given class
* `optional` - Value does not need to be included in data array. If it is however, it must pass validation. * `optional` - Value does not need to be included in data array. If it is however, it must pass validation.

View File

@ -4,8 +4,8 @@
"description": "Simple, elegant, stand-alone validation library with NO dependencies", "description": "Simple, elegant, stand-alone validation library with NO dependencies",
"keywords": ["validation", "validator", "valid"], "keywords": ["validation", "validator", "valid"],
"homepage": "http://github.com/vlucas/valitron", "homepage": "http://github.com/vlucas/valitron",
"license" : "BSD-3-Clause", "license": "BSD-3-Clause",
"authors" : [ "authors": [
{ {
"name": "Vance Lucas", "name": "Vance Lucas",
"email": "vance@vancelucas.com", "email": "vance@vancelucas.com",

View File

@ -13,6 +13,8 @@ return array(
'in' => "contains invalid value", 'in' => "contains invalid value",
'notIn' => "contains invalid value", 'notIn' => "contains invalid value",
'ip' => "is not a valid IP address", 'ip' => "is not a valid IP address",
'ipv4' => "is not a valid IPv4 address",
'ipv6' => "is not a valid IPv6 address",
'email' => "is not a valid email address", 'email' => "is not a valid email address",
'url' => "is not a valid URL", 'url' => "is not a valid URL",
'urlActive' => "must be an active domain", 'urlActive' => "must be an active domain",
@ -30,5 +32,7 @@ return array(
'creditCard' => "must be a valid credit card number", 'creditCard' => "must be a valid credit card number",
'lengthMin' => "must be at least %d characters long", 'lengthMin' => "must be at least %d characters long",
'lengthMax' => "must not exceed %d characters", 'lengthMax' => "must not exceed %d characters",
'instanceOf' => "must be an instance of '%s'" 'instanceOf' => "must be an instance of '%s'",
'containsUnique' => "must contain unique elements only",
'subset' => "contains an item that is not in the list",
); );

View File

@ -2,17 +2,19 @@
return array( return array(
'required' => "обязательно для заполнения", 'required' => "обязательно для заполнения",
'equals' => "должно содержать '%s'", 'equals' => "должно совпадать со значением '%s'",
'different' => "должно отличаться от '%s'", 'different' => "должно отличаться от '%s'",
'accepted' => "должно быть указано", 'accepted' => "должно быть указано",
'numeric' => "должно содержать числовое значение", 'numeric' => "должно содержать числовое значение",
'integer' => "должно быть числом", 'integer' => "должно быть числом",
'length' => "должно быть длиннее, чем %d", 'length' => "должно быть длиннее, чем %d",
'min' => "должно быть больше, чем %s", 'min' => "должно быть не менее, чем %s",
'max' => "должно быть меньше, чем %s", 'max' => "должно быть не более, чем %s",
'in' => "содержит неверное значение", 'in' => "содержит неверное значение",
'notIn' => "содержит неверное значение", 'notIn' => "содержит неверное значение",
'ip' => "не является валидным IP адресом", 'ip' => "не является валидным IP адресом",
'ipv4' => "не является валидным IPv4 адресом",
'ipv6' => "не является валидным IPv6 адресом",
'email' => "не является валидным email адресом", 'email' => "не является валидным email адресом",
'url' => "не является валидной ссылкой", 'url' => "не является валидной ссылкой",
'urlActive' => "содержит не активную ссылку", 'urlActive' => "содержит не активную ссылку",
@ -30,5 +32,7 @@ return array(
'creditCard' => "должно быть номером кредитной карты", 'creditCard' => "должно быть номером кредитной карты",
'lengthMin' => "должно содержать более %d символов", 'lengthMin' => "должно содержать более %d символов",
'lengthMax' => "должно содержать менее %d символов", 'lengthMax' => "должно содержать менее %d символов",
'instanceOf' => "должно быть объектом класса '%s'" 'instanceOf' => "должно быть объектом класса '%s'",
'containsUnique' => "должно содержать только уникальные элементы",
'subset' => "содержит элемент, не указанный в списке",
); );

View File

@ -174,7 +174,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateEquals($field, $value, array $params) protected function validateEquals($field, $value, array $params)
@ -190,7 +189,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateDifferent($field, $value, array $params) protected function validateDifferent($field, $value, array $params)
@ -264,7 +262,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateLength($field, $value, $params) protected function validateLength($field, $value, $params)
@ -284,7 +281,7 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @return boolean * @return bool
*/ */
protected function validateLengthBetween($field, $value, $params) protected function validateLengthBetween($field, $value, $params)
{ {
@ -300,7 +297,7 @@ class Validator
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* *
* @return boolean * @return bool
*/ */
protected function validateLengthMin($field, $value, $params) protected function validateLengthMin($field, $value, $params)
{ {
@ -316,7 +313,7 @@ class Validator
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* *
* @return boolean * @return bool
*/ */
protected function validateLengthMax($field, $value, $params) protected function validateLengthMax($field, $value, $params)
{ {
@ -348,7 +345,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateMin($field, $value, $params) protected function validateMin($field, $value, $params)
@ -368,7 +364,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateMax($field, $value, $params) protected function validateMax($field, $value, $params)
@ -410,7 +405,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateIn($field, $value, $params) protected function validateIn($field, $value, $params)
@ -434,7 +428,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateNotIn($field, $value, $params) protected function validateNotIn($field, $value, $params)
@ -446,7 +439,7 @@ class Validator
* Validate a field contains a given string * Validate a field contains a given string
* *
* @param string $field * @param string $field
* @param mixed $value * @param string $value
* @param array $params * @param array $params
* @return bool * @return bool
*/ */
@ -464,7 +457,6 @@ class Validator
$strict = (bool)$params[1]; $strict = (bool)$params[1];
} }
$isContains = false;
if ($strict) { if ($strict) {
if (function_exists('mb_strpos')) { if (function_exists('mb_strpos')) {
$isContains = mb_strpos($value, $params[0]) !== false; $isContains = mb_strpos($value, $params[0]) !== false;
@ -481,6 +473,46 @@ class Validator
return $isContains; return $isContains;
} }
/**
* Validate that all field values contains a given array
*
* @param string $field
* @param array $value
* @param array $params
* @return bool
*/
protected function validateSubset($field, $value, $params)
{
if (!isset($params[0])) {
return false;
}
if (!is_array($params[0])) {
$params[0] = array($params[0]);
}
if (is_scalar($value)) {
return $this->validateIn($field, $value, $params);
}
$intersect = array_intersect($value, $params[0]);
return array_diff($value, $intersect) === array_diff($intersect, $value);
}
/**
* Validate that field array has only unique values
*
* @param string $field
* @param array $value
* @return bool
*/
protected function validateContainsUnique($field, $value)
{
if (!is_array($value)) {
return false;
}
return $value === array_unique($value, SORT_REGULAR);
}
/** /**
* Validate that a field is a valid IP address * Validate that a field is a valid IP address
* *
@ -682,7 +714,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateDateFormat($field, $value, $params) protected function validateDateFormat($field, $value, $params)
@ -698,7 +729,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateDateBefore($field, $value, $params) protected function validateDateBefore($field, $value, $params)
@ -715,7 +745,6 @@ class Validator
* @param string $field * @param string $field
* @param mixed $value * @param mixed $value
* @param array $params * @param array $params
* @internal param array $fields
* @return bool * @return bool
*/ */
protected function validateDateAfter($field, $value, $params) protected function validateDateAfter($field, $value, $params)
@ -868,7 +897,14 @@ class Validator
return $isInstanceOf; return $isInstanceOf;
} }
//Validate optional field /**
* Validate optional field
*
* @param $field
* @param $value
* @param $params
* @return bool
*/
protected function validateOptional($field, $value, $params) protected function validateOptional($field, $value, $params)
{ {
//Always return true //Always return true
@ -904,12 +940,12 @@ class Validator
* Add an error to error messages array * Add an error to error messages array
* *
* @param string $field * @param string $field
* @param string $msg * @param string $message
* @param array $params * @param array $params
*/ */
public function error($field, $msg, array $params = array()) public function error($field, $message, array $params = array())
{ {
$msg = $this->checkAndSetLabel($field, $msg, $params); $message = $this->checkAndSetLabel($field, $message, $params);
$values = array(); $values = array();
// Printed values need to be in string format // Printed values need to be in string format
@ -933,18 +969,18 @@ class Validator
$values[] = $param; $values[] = $param;
} }
$this->_errors[$field][] = vsprintf($msg, $values); $this->_errors[$field][] = vsprintf($message, $values);
} }
/** /**
* Specify validation message to use for error for the last validation rule * Specify validation message to use for error for the last validation rule
* *
* @param string $msg * @param string $message
* @return $this * @return Validator
*/ */
public function message($msg) public function message($message)
{ {
$this->_validations[count($this->_validations) - 1]['message'] = $msg; $this->_validations[count($this->_validations) - 1]['message'] = $message;
return $this; return $this;
} }
@ -968,7 +1004,7 @@ class Validator
} }
// Catches the case where the data isn't an array or object // Catches the case where the data isn't an array or object
if (is_scalar($data)) { if (is_scalar($data)) {
return array(NULL, false); return array(null, false);
} }
$identifier = array_shift($identifiers); $identifier = array_shift($identifiers);
// Glob match // Glob match
@ -984,8 +1020,8 @@ class Validator
} }
return array($values, true); return array($values, true);
} // Dead end, abort } // Dead end, abort
elseif ($identifier === NULL || !isset($data[$identifier])) { elseif ($identifier === null || ! isset($data[$identifier])) {
if ($allow_empty) { if ($allow_empty){
//when empty values are allowed, we only care if the key exists //when empty values are allowed, we only care if the key exists
return array(null, array_key_exists($identifier, $data)); return array(null, array_key_exists($identifier, $data));
} }
@ -1006,7 +1042,7 @@ class Validator
/** /**
* Run validations and return boolean result * Run validations and return boolean result
* *
* @return boolean * @return bool
*/ */
public function validate() public function validate()
{ {
@ -1053,7 +1089,9 @@ class Validator
} }
} }
} }
if ($set_to_break) break; if ($set_to_break) {
break;
}
} }
return count($this->errors()) === 0; return count($this->errors()) === 0;
@ -1093,9 +1131,8 @@ class Validator
* *
* @param string $name The name of the rule * @param string $name The name of the rule
* @param string $field The name of the field * @param string $field The name of the field
* @return boolean * @return bool
*/ */
protected function hasRule($name, $field) protected function hasRule($name, $field)
{ {
foreach ($this->_validations as $validation) { foreach ($this->_validations as $validation) {
@ -1112,11 +1149,12 @@ class Validator
protected static function assertRuleCallback($callback) protected static function assertRuleCallback($callback)
{ {
if (!is_callable($callback)) { if (!is_callable($callback)) {
throw new \InvalidArgumentException('Second argument must be a valid callback. Given argument was not callable.'); throw new \InvalidArgumentException(
'Second argument must be a valid callback. Given argument was not callable.'
);
} }
} }
/** /**
* Adds a new validation rule callback that is tied to the current * Adds a new validation rule callback that is tied to the current
* instance only. * instance only.
@ -1154,6 +1192,10 @@ class Validator
static::$_ruleMessages[$name] = $message; static::$_ruleMessages[$name] = $message;
} }
/**
* @param mixed $fields
* @return string
*/
public function getUniqueRuleName($fields) public function getUniqueRuleName($fields)
{ {
if (is_array($fields)) { if (is_array($fields)) {
@ -1187,9 +1229,9 @@ class Validator
/** /**
* Convenience method to add a single validation rule * Convenience method to add a single validation rule
* *
* @param string|callable $rule * @param string|callback $rule
* @param array|string $fields * @param array|string $fields
* @return $this * @return Validator
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function rule($rule, $fields) public function rule($rule, $fields)
@ -1200,8 +1242,8 @@ class Validator
if (is_callable($rule) if (is_callable($rule)
&& !(is_string($rule) && $this->hasValidator($rule))) { && !(is_string($rule) && $this->hasValidator($rule))) {
$name = $this->getUniqueRuleName($fields); $name = $this->getUniqueRuleName($fields);
$msg = isset($params[0]) ? $params[0] : null; $message = isset($params[0]) ? $params[0] : null;
$this->addInstanceRule($name, $rule, $msg); $this->addInstanceRule($name, $rule, $message);
$rule = $name; $rule = $name;
} }
@ -1209,13 +1251,15 @@ class Validator
if (!isset($errors[$rule])) { if (!isset($errors[$rule])) {
$ruleMethod = 'validate' . ucfirst($rule); $ruleMethod = 'validate' . ucfirst($rule);
if (!method_exists($this, $ruleMethod)) { if (!method_exists($this, $ruleMethod)) {
throw new \InvalidArgumentException("Rule '" . $rule . "' has not been registered with " . __CLASS__ . "::addRule()."); throw new \InvalidArgumentException(
"Rule '" . $rule . "' has not been registered with " . get_called_class() . "::addRule()."
);
} }
} }
// Ensure rule has an accompanying message // Ensure rule has an accompanying message
$msgs = $this->getRuleMessages(); $messages = $this->getRuleMessages();
$message = isset($msgs[$rule]) ? $msgs[$rule] : self::ERROR_DEFAULT; $message = isset($messages[$rule]) ? $messages[$rule] : self::ERROR_DEFAULT;
// Ensure message contains field label // Ensure message contains field label
if (function_exists('mb_strpos')) { if (function_exists('mb_strpos')) {
@ -1241,8 +1285,7 @@ class Validator
* Add label to rule * Add label to rule
* *
* @param string $value * @param string $value
* @internal param array $labels * @return Validator
* @return $this
*/ */
public function label($value) public function label($value)
{ {
@ -1256,7 +1299,7 @@ class Validator
* Add labels to rules * Add labels to rules
* *
* @param array $labels * @param array $labels
* @return $this * @return Validator
*/ */
public function labels($labels = array()) public function labels($labels = array())
{ {
@ -1267,29 +1310,29 @@ class Validator
/** /**
* @param string $field * @param string $field
* @param string $msg * @param string $message
* @param array $params * @param array $params
* @return array * @return array
*/ */
protected function checkAndSetLabel($field, $msg, $params) protected function checkAndSetLabel($field, $message, $params)
{ {
if (isset($this->_labels[$field])) { if (isset($this->_labels[$field])) {
$msg = str_replace('{field}', $this->_labels[$field], $msg); $message = str_replace('{field}', $this->_labels[$field], $message);
if (is_array($params)) { if (is_array($params)) {
$i = 1; $i = 1;
foreach ($params as $k => $v) { foreach ($params as $k => $v) {
$tag = '{field' . $i . '}'; $tag = '{field' . $i . '}';
$label = isset($params[$k]) && (is_numeric($params[$k]) || is_string($params[$k])) && isset($this->_labels[$params[$k]]) ? $this->_labels[$params[$k]] : $tag; $label = isset($params[$k]) && (is_numeric($params[$k]) || is_string($params[$k])) && isset($this->_labels[$params[$k]]) ? $this->_labels[$params[$k]] : $tag;
$msg = str_replace($tag, $label, $msg); $message = str_replace($tag, $label, $message);
$i++; $i++;
} }
} }
} else { } else {
$msg = str_replace('{field}', ucwords(str_replace('_', ' ', $field)), $msg); $message = str_replace('{field}', ucwords(str_replace('_', ' ', $field)), $message);
} }
return $msg; return $message;
} }
/** /**
@ -1319,7 +1362,7 @@ class Validator
* *
* @param array $data * @param array $data
* @param array $fields * @param array $fields
* @return \Valitron\Validator * @return Validator
*/ */
public function withData($data, $fields = array()) public function withData($data, $fields = array())
{ {
@ -1332,20 +1375,20 @@ class Validator
/** /**
* Convenience method to add validation rule(s) by field * Convenience method to add validation rule(s) by field
* *
* @param string field_name * @param string $field
* @param array $rules * @param array $rules
*/ */
public function mapFieldRules($field_name, $rules) public function mapFieldRules($field, $rules)
{ {
$me = $this; $me = $this;
array_map(function ($rule) use ($field_name, $me) { array_map(function ($rule) use ($field, $me) {
//rule must be an array //rule must be an array
$rule = (array)$rule; $rule = (array)$rule;
//First element is the name of the rule //First element is the name of the rule
$rule_name = array_shift($rule); $ruleName = array_shift($rule);
//find a custom message, if any //find a custom message, if any
$message = null; $message = null;
@ -1354,7 +1397,7 @@ class Validator
unset($rule['message']); unset($rule['message']);
} }
//Add the field and additional parameters to the rule //Add the field and additional parameters to the rule
$added = call_user_func_array(array($me, 'rule'), array_merge(array($rule_name, $field_name), $rule)); $added = call_user_func_array(array($me, 'rule'), array_merge(array($ruleName, $field), $rule));
if (!empty($message)) { if (!empty($message)) {
$added->message($message); $added->message($message);
} }
@ -1369,8 +1412,8 @@ class Validator
public function mapFieldsRules($rules) public function mapFieldsRules($rules)
{ {
$me = $this; $me = $this;
array_map(function ($field_name) use ($rules, $me) { array_map(function ($field) use ($rules, $me) {
$me->mapFieldRules($field_name, $rules[$field_name]); $me->mapFieldRules($field, $rules[$field]);
}, array_keys($rules)); }, array_keys($rules));
} }
} }

View File

@ -18,7 +18,7 @@ class BaseTestCase extends TestCase
protected function resetProperty($name, $value = null) protected function resetProperty($name, $value = null)
{ {
$prop = new ReflectionProperty('Valitron\Validator', $name); $prop = new \ReflectionProperty('Valitron\Validator', $name);
$prop->setAccessible(true); $prop->setAccessible(true);
$prop->setValue($value); $prop->setValue($value);
$prop->setAccessible(false); $prop->setAccessible(false);

View File

@ -1,4 +1,5 @@
<?php <?php
use Valitron\Validator; use Valitron\Validator;
class ErrorMessagesTest extends BaseTestCase class ErrorMessagesTest extends BaseTestCase
@ -60,17 +61,18 @@ class ErrorMessagesTest extends BaseTestCase
public function testMessageWithFieldSet() public function testMessageWithFieldSet()
{ {
$v = new Validator(array('name'=>''), array(), 'en', __DIR__ . '/../lang'); $v = new Validator(array('name' => ''), array(), 'en', __DIR__ . '/../lang');
$v->rule('required', 'name'); $v->rule('required', 'name');
$v->validate(); $v->validate();
$this->assertEquals( $v->errors('name'), array('A value is required for Name')); $this->assertEquals($v->errors('name'), array('A value is required for Name'));
} }
public function testMessageWithFieldAndLabelSet(){ public function testMessageWithFieldAndLabelSet()
$v = new Validator(array('name'=>''), array(), 'en', __DIR__ . '/../lang'); {
$v = new Validator(array('name' => ''), array(), 'en', __DIR__ . '/../lang');
$v->rule('required', 'name')->label('my name'); $v->rule('required', 'name')->label('my name');
$v->validate(); $v->validate();
$this->assertEquals( $v->errors('name'), array('A value is required for my name')); $this->assertEquals($v->errors('name'), array('A value is required for my name'));
} }
} }

View File

@ -9,7 +9,7 @@ class LangTest extends BaseTestCase
} }
/** /**
* Lang defined statically should not be overrided by constructor default * Lang defined statically should not be override by constructor default
*/ */
public function testLangDefinedStatically() public function testLangDefinedStatically()
{ {
@ -20,7 +20,7 @@ class LangTest extends BaseTestCase
} }
/** /**
* LangDir defined statically should not be overrided by constructor default * LangDir defined statically should not be override by constructor default
*/ */
public function testLangDirDefinedStatically() public function testLangDirDefinedStatically()
{ {

View File

@ -1,12 +1,11 @@
<?php <?php
use Valitron\Validator;
use Valitron\Validator;
class MapRulesTest extends BaseTestCase class MapRulesTest extends BaseTestCase
{ {
public function testMapSingleFieldRules() public function testMapSingleFieldRules()
{ {
$rules = array( $rules = array(
'required', 'required',
array('lengthMin', 4) array('lengthMin', 4)
@ -24,7 +23,6 @@ class MapRulesTest extends BaseTestCase
public function testSingleFieldDot() public function testSingleFieldDot()
{ {
$v = new Valitron\Validator(array( $v = new Valitron\Validator(array(
'settings' => array( 'settings' => array(
array('threshold' => 50), array('threshold' => 50),
@ -36,7 +34,6 @@ class MapRulesTest extends BaseTestCase
)); ));
$this->assertFalse($v->validate()); $this->assertFalse($v->validate());
} }
public function testMapMultipleFieldsRules() public function testMapMultipleFieldsRules()
@ -60,7 +57,6 @@ class MapRulesTest extends BaseTestCase
$this->assertFalse($v->validate()); $this->assertFalse($v->validate());
$this->assertFalse($v->errors('myField1')); $this->assertFalse($v->errors('myField1'));
$this->assertEquals(2, sizeof($v->errors('myField2'))); $this->assertEquals(2, sizeof($v->errors('myField2')));
} }
public function testCustomMessageSingleField() public function testCustomMessageSingleField()
@ -82,10 +78,10 @@ class MapRulesTest extends BaseTestCase
{ {
$rules = array( $rules = array(
'myField1' => array( 'myField1' => array(
array('lengthMin', 14, 'message'=>'My Custom Error 1') array('lengthMin', 14, 'message' => 'My Custom Error 1')
), ),
'myField2' => array( 'myField2' => array(
array('lengthMin', 14, 'message'=>'My Custom Error 2') array('lengthMin', 14, 'message' => 'My Custom Error 2')
) )
); );
@ -100,8 +96,6 @@ class MapRulesTest extends BaseTestCase
$errors1 = $v->errors('myField1'); $errors1 = $v->errors('myField1');
$this->assertEquals('My Custom Error 1', $errors1[0]); $this->assertEquals('My Custom Error 1', $errors1[0]);
$errors2 = $v->errors('myField2'); $errors2 = $v->errors('myField2');
$this->assertEquals('My Custom Error 2', $errors2[0]); $this->assertEquals('My Custom Error 2', $errors2[0]);
} }

View File

@ -7,8 +7,9 @@ class StaticVsInstanceTest extends BaseTestCase
{ {
Validator::lang('ar'); Validator::lang('ar');
new Validator(array(), array(), 'en'); new Validator(array(), array(), 'en');
$this->assertEquals('ar', Validator::lang(), $this->assertEquals(
'instance defined lang should not replace static global lang'); 'ar', Validator::lang(), 'instance defined lang should not replace static global lang'
);
} }
/** /**

View File

@ -1,13 +1,14 @@
<?php <?php
use Valitron\Validator; use Valitron\Validator;
class StopOnFirstFail extends BaseTestCase
class StopOnFirstFail extends BaseTestCase { {
public function testStopOnFirstFail()
public function testStopOnFirstFail() { {
$rules = array( $rules = array(
'myField1' => array( 'myField1' => array(
array('lengthMin', 5, 'message'=>'myField1 must be 5 characters minimum'), array('lengthMin', 5, 'message' => 'myField1 must be 5 characters minimum'),
array('url', 'message' => 'myField1 is not a valid url'), array('url', 'message' => 'myField1 is not a valid url'),
array('urlActive', 'message' => 'myField1 is not an active url') array('urlActive', 'message' => 'myField1 is not an active url')
) )
@ -24,5 +25,4 @@ class StopOnFirstFail extends BaseTestCase {
$errors = $v->errors(); $errors = $v->errors();
$this->assertCount(1, $errors['myField1']); $this->assertCount(1, $errors['myField1']);
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
use Valitron\Validator; use Valitron\Validator;
function callbackTestFunction($item, $value) function callbackTestFunction($item, $value)
@ -8,14 +9,15 @@ function callbackTestFunction($item, $value)
class ValidateAddInstanceRuleTest extends BaseTestCase class ValidateAddInstanceRuleTest extends BaseTestCase
{ {
/**
* @param Validator $v
*/
protected function assertValid($v) protected function assertValid($v)
{ {
$msg = "\tErrors:\n"; $msg = "\tErrors:\n";
$status = $v->validate(); $status = $v->validate();
foreach ($v->errors() as $label => $messages) foreach ($v->errors() as $label => $messages) {
{ foreach ($messages as $theMessage) {
foreach ($messages as $theMessage)
{
$msg .= "\n\t{$label}: {$theMessage}"; $msg .= "\n\t{$label}: {$theMessage}";
} }
} }
@ -30,13 +32,11 @@ class ValidateAddInstanceRuleTest extends BaseTestCase
"fuzz" => "bazz", "fuzz" => "bazz",
)); ));
$v->addInstanceRule("fooRule", function($field, $value) $v->addInstanceRule("fooRule", function ($field, $value) {
{
return $field !== "foo" || $value !== "barz"; return $field !== "foo" || $value !== "barz";
}); });
Validator::addRule("fuzzerRule", function($field, $value) Validator::addRule("fuzzerRule", function ($field, $value) {
{
return $field !== "fuzz" || $value === "bazz"; return $field !== "fuzz" || $value === "bazz";
}); });
@ -50,8 +50,7 @@ class ValidateAddInstanceRuleTest extends BaseTestCase
public function testAddInstanceRuleFail() public function testAddInstanceRuleFail()
{ {
$v = new Validator(array("foo" => "bar")); $v = new Validator(array("foo" => "bar"));
$v->addInstanceRule("fooRule", function($field) $v->addInstanceRule("fooRule", function ($field) {
{
return $field === "for"; return $field === "for";
}); });
$v->rule("fooRule", "foo"); $v->rule("fooRule", "foo");
@ -61,7 +60,7 @@ class ValidateAddInstanceRuleTest extends BaseTestCase
public function testAddAddRuleWithCallback() public function testAddAddRuleWithCallback()
{ {
$v = new Validator(array("foo" => "bar")); $v = new Validator(array("foo" => "bar"));
$v->rule(function($field, $value) { $v->rule(function ($field, $value) {
return $field === "foo" && $value === "bar"; return $field === "foo" && $value === "bar";
}, "foo"); }, "foo");
@ -71,7 +70,7 @@ class ValidateAddInstanceRuleTest extends BaseTestCase
public function testAddAddRuleWithCallbackFail() public function testAddAddRuleWithCallbackFail()
{ {
$v = new Validator(array("foo" => "baz")); $v = new Validator(array("foo" => "baz"));
$v->rule(function($field, $value) { $v->rule(function ($field, $value) {
return $field === "foo" && $value === "bar"; return $field === "foo" && $value === "bar";
}, "foo"); }, "foo");
@ -81,7 +80,7 @@ class ValidateAddInstanceRuleTest extends BaseTestCase
public function testAddAddRuleWithCallbackFailMessage() public function testAddAddRuleWithCallbackFailMessage()
{ {
$v = new Validator(array("foo" => "baz")); $v = new Validator(array("foo" => "baz"));
$v->rule(function($field, $value) { $v->rule(function ($field, $value) {
return $field === "foo" && $value === "bar"; return $field === "foo" && $value === "bar";
}, "foo", "test error message"); }, "foo", "test error message");
@ -113,7 +112,8 @@ class ValidateAddInstanceRuleTest extends BaseTestCase
$this->assertEquals("foo_bar_rule", $v->getUniqueRuleName($args)); $this->assertEquals("foo_bar_rule", $v->getUniqueRuleName($args));
$this->assertEquals("foo_rule", $v->getUniqueRuleName("foo")); $this->assertEquals("foo_rule", $v->getUniqueRuleName("foo"));
$v->addInstanceRule("foo_rule", function() {}); $v->addInstanceRule("foo_rule", function () {
});
$u = $v->getUniqueRuleName("foo"); $u = $v->getUniqueRuleName("foo");
$this->assertRegExp("/^foo_rule_[0-9]{1,5}$/", $u); $this->assertRegExp("/^foo_rule_[0-9]{1,5}$/", $u);
} }

View File

@ -913,14 +913,14 @@ class ValidateTest extends BaseTestCase
$this->assertTrue($v->validate()); $this->assertTrue($v->validate());
} }
public function testContainsNotFound() public function testContainsInvalid()
{ {
$v = new Validator(array('test_string' => 'this is a test')); $v = new Validator(array('test_string' => 'this is a test'));
$v->rule('contains', 'test_string', 'foobar'); $v->rule('contains', 'test_string', 'foobar');
$this->assertFalse($v->validate()); $this->assertFalse($v->validate());
} }
public function testContainsStrictNotFound() public function testContainsStrictInvalid()
{ {
$v = new Validator(array('test_string' => 'this is a Test')); $v = new Validator(array('test_string' => 'this is a Test'));
$v->rule('contains', 'test_string', 'test'); $v->rule('contains', 'test_string', 'test');
@ -928,9 +928,98 @@ class ValidateTest extends BaseTestCase
} }
public function testContainsInvalidValue() public function testContainsInvalidValue()
{
$v = new Validator(array('test_string' => false));
$v->rule('contains', 'test_string', 'foobar');
$this->assertFalse($v->validate());
}
public function testContainsInvalidRule()
{ {
$v = new Validator(array('test_string' => 'this is a test')); $v = new Validator(array('test_string' => 'this is a test'));
$v->rule('contains', 'test_string', array('test')); $v->rule('contains', 'test_string', null);
$this->assertFalse($v->validate());
}
public function testSubsetValid()
{
// numeric values
$v = new Validator(array('test_field' => array(81, 3, 15)));
$v->rule('subset', 'test_field', array(45, 15, 3, 7, 28, 81));
$this->assertTrue($v->validate());
// string values
$v = new Validator(array('test_field' => array('white', 'green', 'blue')));
$v->rule('subset', 'test_field', array('green', 'orange', 'blue', 'yellow', 'white', 'brown'));
$this->assertTrue($v->validate());
// mixed values
$v = new Validator(array('test_field' => array(81, false, 'orange')));
$v->rule('subset', 'test_field', array(45, 'green', true, 'orange', null, 81, false));
$this->assertTrue($v->validate());
// string value and validation target cast to array
$v = new Validator(array('test_field' => 'blue'));
$v->rule('subset', 'test_field', 'blue');
$this->assertTrue($v->validate());
}
public function testSubsetInvalid()
{
$v = new Validator(array('test_field' => array(81, false, 'orange')));
$v->rule('subset', 'test_field', array(45, 'green', true, 'orange', null, false, 7));
$this->assertFalse($v->validate());
}
public function testSubsetInvalidValue()
{
$v = new Validator(array('test_field' => 'black 45'));
$v->rule('subset', 'test_field', array('black', 45));
$this->assertFalse($v->validate());
}
public function testSubsetInvalidRule()
{
// rule value has invalid type
$v = new Validator(array('test_field' => array('black', 45)));
$v->rule('subset', 'test_field', 'black 45');
$this->assertFalse($v->validate());
// rule value not specified
$v = new Validator(array('test_field' => array('black', 45)));
$v->rule('subset', 'test_field');
$this->assertFalse($v->validate());
}
public function testContainsUniqueValid()
{
// numeric values
$v = new Validator(array('test_field' => array(81, 3, 15)));
$v->rule('containsUnique', 'test_field');
$this->assertTrue($v->validate());
// string values
$v = new Validator(array('test_field' => array('white', 'green', 'blue')));
$v->rule('containsUnique', 'test_field');
$this->assertTrue($v->validate());
// mixed values
$v = new Validator(array('test_field' => array(81, false, 'orange')));
$v->rule('containsUnique', 'test_field');
$this->assertTrue($v->validate());
}
public function testContainsUniqueInvalid()
{
$v = new Validator(array('test_field' => array(81, false, 'orange', false)));
$v->rule('containsUnique', 'test_field');
$this->assertFalse($v->validate());
}
public function testContainsUniqueInvalidValue()
{
$v = new Validator(array('test_field' => 'lorem ipsum'));
$v->rule('containsUnique', 'test_field');
$this->assertFalse($v->validate()); $this->assertFalse($v->validate());
} }
@ -1213,7 +1302,7 @@ class ValidateTest extends BaseTestCase
public function testFalseStillTriggersValidation() public function testFalseStillTriggersValidation()
{ {
$v = new Validator(array('test' => FALSE)); $v = new Validator(array('test' => false));
$v->rule('min', 'test', 5); $v->rule('min', 'test', 5);
$this->assertFalse($v->validate()); $this->assertFalse($v->validate());
} }