diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..cca0805b
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,24 @@
+root = true
+
+[*]
+indent_style = space
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+
+[**.php]
+indent_size = 4
+continuation_indent_size = 4
+insert_final_newline = true
+
+[**.xml]
+indent_size = 4
+
+[**.yml]
+indent_size = 2
+
+[composer.json]
+indent_size = 4
+
+[package.json]
+indent_size = 2
diff --git a/.gitattributes b/.gitattributes
index 85dc9a8c..7325c690 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,6 +1,8 @@
/test export-ignore
/vendor export-ignore
+.coveralls.yml export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.travis.yml export-ignore
.php_cs export-ignore
+phpunit.xml.dist export-ignore
diff --git a/.gitignore b/.gitignore
index 4cac0a21..a7fc91d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ nbproject
tmp/
clover.xml
+composer.lock
coveralls-upload.json
phpunit.xml
vendor
diff --git a/.php_cs b/.php_cs
index bf4b799f..569ffe52 100644
--- a/.php_cs
+++ b/.php_cs
@@ -1,5 +1,7 @@
in('src')
+ ->in('test')
->notPath('TestAsset')
->notPath('_files')
->filter(function (SplFileInfo $file) {
@@ -28,9 +30,10 @@ $config->fixers(
'multiple_use',
'method_argument_space',
'object_operator',
+ 'ordered_use',
'php_closing_tag',
- 'psr0',
'remove_lines_between_uses',
+ 'long_array_syntax',
'short_tag',
'standardize_not_equal',
'trailing_spaces',
diff --git a/.travis.yml b/.travis.yml
index fe909ecb..989ddc78 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,16 +2,28 @@ sudo: false
language: php
+branches:
+ except:
+ - /^release-.*$/
+ - /^ghgfk-.*$/
+
+cache:
+ directories:
+ - $HOME/.composer/cache
+
matrix:
fast_finish: true
include:
+ - php: 5.3
+ - php: 5.4
- php: 5.5
+ env:
+ - EXECUTE_CS_CHECK=true
- php: 5.6
env:
- EXECUTE_TEST_COVERALLS=true
- - EXECUTE_CS_CHECK=true
- php: 7
- - php: hhvm
+ - php: hhvm
allow_failures:
- php: 7
- php: hhvm
@@ -22,14 +34,16 @@ notifications:
before_install:
- if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi
+ - composer self-update
+ - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then composer require --dev --no-update satooshi/php-coveralls ; fi
install:
- - composer install --no-interaction --prefer-source
+ - travis_retry composer install --no-interaction --ignore-platform-reqs
script:
- - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/phpunit -c phpunit.xml.travis --coverage-clover clover.xml ; fi
- - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then ./vendor/bin/phpunit -c phpunit.xml.travis ; fi
- - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/php-cs-fixer fix -v --diff --dry-run --config-file=.php_cs ; fi
+ - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/phpunit --coverage-clover clover.xml ; fi
+ - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then ./vendor/bin/phpunit ; fi
+ - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/php-cs-fixer fix -v --diff --dry-run ; fi
after_script:
- if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/coveralls ; fi
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fca9f311..cf3e8fe6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,67 @@
All notable changes to this project will be documented in this file, in reverse chronological order by release.
+## 2.4.8 - TBD
+
+### Added
+
+- Nothing.
+
+### Deprecated
+
+- [#26](https://github.com/zendframework/zend-inputfilter/pull/26) Deprecate magic logic for auto attach a NonEmpty
+ validator with breakChainOnFailure = true. Instead append NonEmpty validator when desired.
+
+ ```php
+ $input = new Zend\InputFilter\Input();
+ $input->setContinueIfEmpty(true);
+ $input->setAllowEmpty(true);
+ $input->getValidatorChain()->attach(new Zend\Validator\NotEmpty(), /* break chain on failure */ true);
+ ```
+### Removed
+
+- Nothing.
+
+### Fixed
+
+- [#22](https://github.com/zendframework/zend-inputfilter/pull/22) adds tests to
+ verify two conditions around inputs with fallback values:
+ - If the input was not in the data set, it should not be represented in either
+ the list of valid *or* invalid inputs.
+ - If the input *was* in the data set, but empty, it should be represented in
+ the list of valid inputs.
+- [#31](https://github.com/zendframework/zend-inputfilter/pull/31) updates the
+ `InputFilterInterface::add()` docblock to match existing, shipped implementations.
+- [#25](https://github.com/zendframework/zend-inputfilter/pull/25) Fix missing optional fields to be required.
+ BC Break since 2.3.9.
+ For completely fix this you need to setup your inputs as follow.
+
+ ```php
+ $input = new Input();
+ $input->setAllowEmpty(true); // Disable BC Break logic related to treat `null` values as valid empty value instead *not set*.
+ $input->setContinueIfEmpty(true); // Disable BC Break logic related to treat `null` values as valid empty value instead *not set*.
+ $input->getValidatorChain()->attach(
+ new Zend\Validator\NotEmpty(),
+ true // break chain on failure
+ );
+ ```
+
+ ```php
+ $inputSpecification = array(
+ 'allow_empty' => true,
+ 'continue_if_empty' => true,
+ 'validators' => array(
+ array(
+ 'break_chain_on_failure' => true,
+ 'name' => 'Zend\\Validator\\NotEmpty',
+ ),
+ ),
+ );
+ ```
+- [Numerous fixes](https://github.com/zendframework/zend-inputfilter/milestones/2.4.8)
+ aimed at bringing the functionality back to the pre-2.4 code, and improving
+ quality overall of the component via increased testing and test coverage.
+
## 2.4.7 - 2015-08-11
### Added
diff --git a/README.md b/README.md
index 68d7faff..13861a74 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
# zend-inputfilter
+[![Build Status](https://secure.travis-ci.org/zendframework/zend-inputfilter.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-inputfilter)
+[![Coverage Status](https://coveralls.io/repos/zendframework/zend-inputfilter/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-inputfilter?branch=master)
+
The `Zend\InputFilter` component can be used to filter and validate generic sets
of input data. For instance, you could use it to filter `$_GET` or `$_POST`
values, CLI arguments, etc.
diff --git a/composer.json b/composer.json
index b618c816..e6bac4ce 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,7 @@
"zf2",
"inputfilter"
],
- "homepage": "https://github.com/zendframework/zend-input-filter",
+ "homepage": "https://github.com/zendframework/zend-inputfilter",
"autoload": {
"psr-4": {
"Zend\\InputFilter\\": "src/"
@@ -14,19 +14,20 @@
},
"require": {
"php": ">=5.3.23",
- "zendframework/zend-filter": "self.version",
- "zendframework/zend-validator": "self.version",
- "zendframework/zend-stdlib": "self.version"
+ "zendframework/zend-filter": "~2.4.0",
+ "zendframework/zend-validator": "~2.4.8",
+ "zendframework/zend-stdlib": "~2.4.0"
},
"require-dev": {
- "zendframework/zend-servicemanager": "self.version",
+ "zendframework/zend-servicemanager": "~2.4.0",
"fabpot/php-cs-fixer": "1.7.*",
- "satooshi/php-coveralls": "dev-master",
- "phpunit/PHPUnit": "~4.0"
+ "phpunit/PHPUnit": "^4.5"
},
"suggest": {
"zendframework/zend-servicemanager": "To support plugin manager support"
},
+ "minimum-stability": "dev",
+ "prefer-stable": true,
"extra": {
"branch-alias": {
"dev-master": "2.4-dev",
@@ -38,4 +39,4 @@
"ZendTest\\InputFilter\\": "test/"
}
}
-}
\ No newline at end of file
+}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index ee25b409..493e8228 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -28,7 +28,7 @@
functionality works as expected. Such tests include those for
Zend\Soap and Zend\Session, which require that headers not be sent
in order to work. -->
-
+
diff --git a/phpunit.xml.travis b/phpunit.xml.travis
deleted file mode 100644
index ee25b409..00000000
--- a/phpunit.xml.travis
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
- ./test/
-
-
-
-
-
- disable
-
-
-
-
-
- ./src
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ArrayInput.php b/src/ArrayInput.php
index 08876f91..102d6fb1 100644
--- a/src/ArrayInput.php
+++ b/src/ArrayInput.php
@@ -31,6 +31,16 @@ public function setValue($value)
return parent::setValue($value);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function resetValue()
+ {
+ $this->value = array();
+ $this->hasValue = false;
+ return $this;
+ }
+
/**
* @return array
*/
@@ -50,6 +60,22 @@ public function getValue()
*/
public function isValid($context = null)
{
+ $hasValue = $this->hasValue();
+ $required = $this->isRequired();
+ $hasFallback = $this->hasFallback();
+
+ if (! $hasValue && $hasFallback) {
+ $this->setValue($this->getFallbackValue());
+ return true;
+ }
+
+ if (! $hasValue && $required) {
+ if ($this->errorMessage === null) {
+ $this->errorMessage = $this->prepareRequiredValidationFailureMessage();
+ }
+ return false;
+ }
+
if (!$this->continueIfEmpty() && !$this->allowEmpty()) {
$this->injectNotEmptyValidator();
}
@@ -58,15 +84,19 @@ public function isValid($context = null)
$result = true;
foreach ($values as $value) {
$empty = ($value === null || $value === '' || $value === array());
+ if ($empty && !$this->isRequired() && !$this->continueIfEmpty()) {
+ $result = true;
+ continue;
+ }
if ($empty && $this->allowEmpty() && !$this->continueIfEmpty()) {
$result = true;
continue;
}
$result = $validator->isValid($value, $context);
if (!$result) {
- if ($this->hasFallback()) {
+ if ($hasFallback) {
$this->setValue($this->getFallbackValue());
- $result = true;
+ return true;
}
break;
}
diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php
index 74e69859..0b2d1bd8 100644
--- a/src/BaseInputFilter.php
+++ b/src/BaseInputFilter.php
@@ -21,7 +21,7 @@ class BaseInputFilter implements
ReplaceableInputInterface
{
/**
- * @var array
+ * @var null|array
*/
protected $data;
@@ -36,7 +36,7 @@ class BaseInputFilter implements
protected $invalidInputs;
/**
- * @var array
+ * @var null|string[] Input names
*/
protected $validationGroup;
@@ -106,23 +106,13 @@ public function add($input, $name = null)
/**
* Replace a named input
*
- * @param InputInterface|InputFilterInterface $input
+ * @param mixed $input Any of the input types allowed on add() method.
* @param string $name Name of the input to replace
- * @throws Exception\InvalidArgumentException
+ * @throws Exception\InvalidArgumentException If input to replace not exists.
* @return self
*/
public function replace($input, $name)
{
- if (!$input instanceof InputInterface && !$input instanceof InputFilterInterface) {
- throw new Exception\InvalidArgumentException(sprintf(
- '%s expects an instance of %s or %s as its first argument; received "%s"',
- __METHOD__,
- 'Zend\InputFilter\InputInterface',
- 'Zend\InputFilter\InputFilterInterface',
- (is_object($input) ? get_class($input) : gettype($input))
- ));
- }
-
if (!array_key_exists($name, $this->inputs)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s: no input found matching "%s"',
@@ -131,7 +121,9 @@ public function replace($input, $name)
));
}
- $this->inputs[$name] = $input;
+ $this->remove($name);
+ $this->add($input, $name);
+
return $this;
}
@@ -186,16 +178,16 @@ public function remove($name)
*/
public function setData($data)
{
- if (!is_array($data) && !$data instanceof Traversable) {
+ if ($data instanceof Traversable) {
+ $data = ArrayUtils::iteratorToArray($data);
+ }
+ if (!is_array($data)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable argument; received %s',
__METHOD__,
(is_object($data) ? get_class($data) : gettype($data))
));
}
- if (is_object($data) && !$data instanceof ArrayAccess) {
- $data = ArrayUtils::iteratorToArray($data);
- }
$this->data = $data;
$this->populate();
return $this;
@@ -224,17 +216,14 @@ public function isValid($context = null)
/**
* Validate a set of inputs against the current data
*
- * @param array $inputs
+ * @param string[] $inputs Array of input names.
* @param array|ArrayAccess $data
* @param mixed|null $context
* @return bool
*/
protected function validateInputs(array $inputs, $data = array(), $context = null)
{
- // backwards compatibility
- if (empty($data)) {
- $data = $this->getRawValues();
- }
+ $inputContext = $context ?: (array_merge($this->getRawValues(), (array) $data));
$this->validInputs = array();
$this->invalidInputs = array();
@@ -242,42 +231,6 @@ protected function validateInputs(array $inputs, $data = array(), $context = nul
foreach ($inputs as $name) {
$input = $this->inputs[$name];
- $hasFallback = ($input instanceof Input && $input->hasFallback());
-
- // If the value is required, not present in the data set, and
- // has no fallback, validation fails.
- if (!array_key_exists($name, $data)
- && $input instanceof InputInterface
- && $input->isRequired()
- && !$hasFallback
- ) {
- $input->setErrorMessage('Value is required');
- $this->invalidInputs[$name] = $input;
-
- if ($input->breakOnFailure()) {
- return false;
- }
-
- $valid = false;
- continue;
- }
-
- // If the value is required, not present in the data set, and
- // has a fallback, validation passes, and we set the input
- // value to the fallback.
- if (!array_key_exists($name, $data)
- && $input instanceof InputInterface
- && $input->isRequired()
- && $hasFallback
- ) {
- $input->setValue($input->getFallbackValue());
- continue;
- }
-
- // Make sure we have a value (empty) for validation of context
- if (!array_key_exists($name, $data)) {
- $data[$name] = null;
- }
// Validate an input filter
if ($input instanceof InputFilterInterface) {
@@ -290,23 +243,30 @@ protected function validateInputs(array $inputs, $data = array(), $context = nul
continue;
}
- // Validate an input
- if ($input instanceof InputInterface) {
- $inputContext = $context ?: $data;
+ // If input is not InputInterface then silently continue (BC safe)
+ if (!$input instanceof InputInterface) {
+ continue;
+ }
- if (!$input->isValid($inputContext)) {
- // Validation failure
- $this->invalidInputs[$name] = $input;
- $valid = false;
+ // If input is optional (not required), and value is not set, then ignore.
+ if (!array_key_exists($name, $data)
+ && !$input->isRequired()
+ ) {
+ continue;
+ }
- if ($input->breakOnFailure()) {
- return false;
- }
- continue;
+ // Validate an input
+ if (!$input->isValid($inputContext)) {
+ // Validation failure
+ $this->invalidInputs[$name] = $input;
+ $valid = false;
+
+ if ($input->breakOnFailure()) {
+ return false;
}
- $this->validInputs[$name] = $input;
continue;
}
+ $this->validInputs[$name] = $input;
}
return $valid;
@@ -465,6 +425,9 @@ public function getRawValue($name)
));
}
$input = $this->inputs[$name];
+ if ($input instanceof InputFilterInterface) {
+ return $input->getRawValues();
+ }
return $input->getRawValue();
}
@@ -511,7 +474,7 @@ public function getMessages()
/**
* Ensure all names of a validation group exist as input in the filter
*
- * @param array $inputs
+ * @param string[] $inputs Input names
* @return void
* @throws Exception\InvalidArgumentException
*/
@@ -542,7 +505,7 @@ protected function populate()
$input->clearRawValues();
}
- if (!isset($this->data[$name])) {
+ if (!array_key_exists($name, $this->data)) {
// No value; clear value in this input
if ($input instanceof InputFilterInterface) {
$input->setData(array());
@@ -554,6 +517,11 @@ protected function populate()
continue;
}
+ if ($input instanceof Input) {
+ $input->resetValue();
+ continue;
+ }
+
$input->setValue(null);
continue;
}
@@ -627,7 +595,7 @@ public function getUnknown()
/**
* Get an array of all inputs
*
- * @return array
+ * @return InputInterface[]|InputFilterInterface[]
*/
public function getInputs()
{
diff --git a/src/CollectionInputFilter.php b/src/CollectionInputFilter.php
index c4cc348a..6d34c7c1 100644
--- a/src/CollectionInputFilter.php
+++ b/src/CollectionInputFilter.php
@@ -13,27 +13,27 @@
class CollectionInputFilter extends InputFilter
{
- /*
+ /**
* @var bool
*/
protected $isRequired = false;
- /*
+ /**
* @var int
*/
protected $count = null;
- /*
- * @var array
+ /**
+ * @var array[]
*/
protected $collectionValues = array();
- /*
- * @var array
+ /**
+ * @var array[]
*/
protected $collectionRawValues = array();
- /*
+ /**
* @var array
*/
protected $collectionMessages = array();
@@ -140,6 +140,8 @@ public function getCount()
public function setData($data)
{
$this->data = $data;
+
+ return $this;
}
/**
@@ -226,7 +228,7 @@ public function getRawValues()
/**
* Clear collectionValues
*
- * @access public
+ * @return array[]
*/
public function clearValues()
{
@@ -236,7 +238,7 @@ public function clearValues()
/**
* Clear collectionRawValues
*
- * @access public
+ * @return array[]
*/
public function clearRawValues()
{
diff --git a/src/EmptyContextInterface.php b/src/EmptyContextInterface.php
index 62e2e225..fd049db1 100644
--- a/src/EmptyContextInterface.php
+++ b/src/EmptyContextInterface.php
@@ -9,15 +9,22 @@
namespace Zend\InputFilter;
+/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain.
+ */
interface EmptyContextInterface
{
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain and set this to `true`.
+ *
* @param bool $continueIfEmpty
* @return self
*/
public function setContinueIfEmpty($continueIfEmpty);
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain. Should always return `true`.
+ *
* @return bool
*/
public function continueIfEmpty();
diff --git a/src/Factory.php b/src/Factory.php
index 244233ec..d07ecc6b 100644
--- a/src/Factory.php
+++ b/src/Factory.php
@@ -10,12 +10,11 @@
namespace Zend\InputFilter;
use Traversable;
-use Zend\Filter\Exception;
use Zend\Filter\FilterChain;
+use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Stdlib\ArrayUtils;
-use Zend\Validator\ValidatorInterface;
use Zend\Validator\ValidatorChain;
-use Zend\ServiceManager\ServiceLocatorInterface;
+use Zend\Validator\ValidatorInterface;
class Factory
{
@@ -171,19 +170,20 @@ public function createInput($inputSpecification)
if (isset($inputSpecification['type'])) {
$class = $inputSpecification['type'];
+ }
- if ($this->getInputFilterManager()->has($class)) {
- return $this->createInputFilter($inputSpecification);
- }
-
- if (!class_exists($class)) {
- throw new Exception\RuntimeException(sprintf(
- 'Input factory expects the "type" to be a valid class; received "%s"',
- $class
- ));
- }
+ $managerInstance = null;
+ if ($this->getInputFilterManager()->has($class)) {
+ $managerInstance = $this->getInputFilterManager()->get($class);
+ }
+ if (! $managerInstance && ! class_exists($class)) {
+ throw new Exception\RuntimeException(sprintf(
+ 'Input factory expects the "type" to be a valid class or a plugin name; received "%s"',
+ $class
+ ));
}
- $input = new $class();
+
+ $input = $managerInstance ?: new $class;
if ($input instanceof InputFilterInterface) {
return $this->createInputFilter($inputSpecification);
@@ -211,9 +211,6 @@ public function createInput($inputSpecification)
break;
case 'required':
$input->setRequired($value);
- if (isset($inputSpecification['allow_empty'])) {
- $input->setAllowEmpty($inputSpecification['allow_empty']);
- }
break;
case 'allow_empty':
$input->setAllowEmpty($value);
@@ -222,12 +219,26 @@ public function createInput($inputSpecification)
}
break;
case 'continue_if_empty':
+ if (!$input instanceof Input) {
+ throw new Exception\RuntimeException(sprintf(
+ '%s "continue_if_empty" can only set to inputs of type "%s"',
+ __METHOD__,
+ 'Zend\InputFilter\Input'
+ ));
+ }
$input->setContinueIfEmpty($inputSpecification['continue_if_empty']);
break;
case 'error_message':
$input->setErrorMessage($value);
break;
case 'fallback_value':
+ if (!$input instanceof Input) {
+ throw new Exception\RuntimeException(sprintf(
+ '%s "fallback_value" can only set to inputs of type "%s"',
+ __METHOD__,
+ 'Zend\InputFilter\Input'
+ ));
+ }
$input->setFallbackValue($value);
break;
case 'break_on_failure':
@@ -375,7 +386,7 @@ protected function populateFilters(FilterChain $chain, $filters)
/**
* @param ValidatorChain $chain
- * @param array|Traversable $validators
+ * @param string[]|ValidatorInterface[] $validators
* @throws Exception\RuntimeException
* @return void
*/
diff --git a/src/FileInput.php b/src/FileInput.php
index 3e0ac77d..ed59091a 100644
--- a/src/FileInput.php
+++ b/src/FileInput.php
@@ -113,16 +113,28 @@ public function isEmptyFile($rawValue)
public function isValid($context = null)
{
$rawValue = $this->getRawValue();
+ $hasValue = $this->hasValue();
$empty = $this->isEmptyFile($rawValue);
$required = $this->isRequired();
$allowEmpty = $this->allowEmpty();
$continueIfEmpty = $this->continueIfEmpty();
+ if (! $hasValue && ! $required) {
+ return true;
+ }
+
+ if (! $hasValue && $required && ! $this->hasFallback()) {
+ if ($this->errorMessage === null) {
+ $this->errorMessage = $this->prepareRequiredValidationFailureMessage();
+ }
+ return false;
+ }
+
if ($empty && ! $required && ! $continueIfEmpty) {
return true;
}
- if ($empty && $required && $allowEmpty && ! $continueIfEmpty) {
+ if ($empty && $allowEmpty && ! $continueIfEmpty) {
return true;
}
@@ -181,6 +193,8 @@ protected function injectUploadValidator()
}
/**
+ * @deprecated 2.4.8 See note on parent class. Removal does not affect this class.
+ *
* No-op, NotEmpty validator does not apply for FileInputs.
* See also: BaseInputFilter::isValid()
*
diff --git a/src/Input.php b/src/Input.php
index fe2395bc..cf51ba02 100644
--- a/src/Input.php
+++ b/src/Input.php
@@ -18,11 +18,15 @@ class Input implements
EmptyContextInterface
{
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain.
+ *
* @var bool
*/
protected $allowEmpty = false;
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain.
+ *
* @var bool
*/
protected $continueIfEmpty = false;
@@ -48,6 +52,8 @@ class Input implements
protected $name;
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain.
+ *
* @var bool
*/
protected $notEmptyValidator = false;
@@ -67,6 +73,13 @@ class Input implements
*/
protected $value;
+ /**
+ * Flag for distinguish when $value contains the value previously set or the default one.
+ *
+ * @var bool
+ */
+ protected $hasValue = false;
+
/**
* @var mixed
*/
@@ -83,6 +96,8 @@ public function __construct($name = null)
}
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain and set this to `true`.
+ *
* @param bool $allowEmpty
* @return Input
*/
@@ -103,6 +118,8 @@ public function setBreakOnFailure($breakOnFailure)
}
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain and set this to `true`.
+ *
* @param bool $continueIfEmpty
* @return Input
*/
@@ -163,12 +180,36 @@ public function setValidatorChain(ValidatorChain $validatorChain)
}
/**
+ * Set the input value.
+ *
+ * If you want to remove/unset the current value use {@link Input::resetValue()}.
+ *
+ * @see Input::getValue() For retrieve the input value.
+ * @see Input::hasValue() For to know if input value was set.
+ * @see Input::resetValue() For reset the input value to the default state.
+ *
* @param mixed $value
* @return Input
*/
public function setValue($value)
{
$this->value = $value;
+ $this->hasValue = true;
+ return $this;
+ }
+
+ /**
+ * Reset input value to the default state.
+ *
+ * @see Input::hasValue() For to know if input value was set.
+ * @see Input::setValue() For set a new value.
+ *
+ * @return Input
+ */
+ public function resetValue()
+ {
+ $this->value = null;
+ $this->hasValue = false;
return $this;
}
@@ -184,6 +225,8 @@ public function setFallbackValue($value)
}
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain.
+ *
* @return bool
*/
public function allowEmpty()
@@ -200,6 +243,8 @@ public function breakOnFailure()
}
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain. Should always return `true`.
+ *
* @return bool
*/
public function continueIfEmpty()
@@ -270,6 +315,22 @@ public function getValue()
return $filter->filter($this->value);
}
+ /**
+ * Flag for inform if input value was set.
+ *
+ * This flag used for distinguish when {@link Input::getValue()} will return the value previously set or the default.
+ *
+ * @see Input::getValue() For retrieve the input value.
+ * @see Input::setValue() For set a new value.
+ * @see Input::resetValue() For reset the input value to the default state.
+ *
+ * @return bool
+ */
+ public function hasValue()
+ {
+ return $this->hasValue;
+ }
+
/**
* @return mixed
*/
@@ -299,12 +360,16 @@ public function clearFallbackValue()
public function merge(InputInterface $input)
{
$this->setBreakOnFailure($input->breakOnFailure());
- $this->setContinueIfEmpty($input->continueIfEmpty());
+ if ($input instanceof Input) {
+ $this->setContinueIfEmpty($input->continueIfEmpty());
+ }
$this->setErrorMessage($input->getErrorMessage());
$this->setName($input->getName());
$this->setRequired($input->isRequired());
$this->setAllowEmpty($input->allowEmpty());
- $this->setValue($input->getRawValue());
+ if (!($input instanceof Input) || $input->hasValue()) {
+ $this->setValue($input->getRawValue());
+ }
$filterChain = $input->getFilterChain();
$this->getFilterChain()->merge($filterChain);
@@ -321,16 +386,33 @@ public function merge(InputInterface $input)
public function isValid($context = null)
{
$value = $this->getValue();
+ $hasValue = $this->hasValue();
$empty = ($value === null || $value === '' || $value === array());
$required = $this->isRequired();
$allowEmpty = $this->allowEmpty();
$continueIfEmpty = $this->continueIfEmpty();
+ if (! $hasValue && $this->hasFallback()) {
+ $this->setValue($this->getFallbackValue());
+ return true;
+ }
+
+ if (! $hasValue && ! $required) {
+ return true;
+ }
+
+ if (! $hasValue && $required) {
+ if ($this->errorMessage === null) {
+ $this->errorMessage = $this->prepareRequiredValidationFailureMessage();
+ }
+ return false;
+ }
+
if ($empty && ! $required && ! $continueIfEmpty) {
return true;
}
- if ($empty && $required && $allowEmpty && ! $continueIfEmpty) {
+ if ($empty && $allowEmpty && ! $continueIfEmpty) {
return true;
}
@@ -353,7 +435,7 @@ public function isValid($context = null)
}
/**
- * @return array
+ * @return string[]
*/
public function getMessages()
{
@@ -370,6 +452,8 @@ public function getMessages()
}
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain.
+ *
* @return void
*/
protected function injectNotEmptyValidator()
@@ -398,4 +482,18 @@ protected function injectNotEmptyValidator()
$chain->prependValidator(new NotEmpty(), true);
}
+
+ /**
+ * Create and return the validation failure message for required input.
+ *
+ * @return string[]
+ */
+ protected function prepareRequiredValidationFailureMessage()
+ {
+ $notEmpty = new NotEmpty();
+ $templates = $notEmpty->getOption('messageTemplates');
+ return array(
+ NotEmpty::IS_EMPTY => $templates[NotEmpty::IS_EMPTY],
+ );
+ }
}
diff --git a/src/InputFilterAbstractServiceFactory.php b/src/InputFilterAbstractServiceFactory.php
index 19a53b7f..5d8c5506 100644
--- a/src/InputFilterAbstractServiceFactory.php
+++ b/src/InputFilterAbstractServiceFactory.php
@@ -50,7 +50,7 @@ public function canCreateServiceWithName(ServiceLocatorInterface $inputFilters,
* @param ServiceLocatorInterface $inputFilters
* @param string $cName
* @param string $rName
- * @return \Zend\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
public function createServiceWithName(ServiceLocatorInterface $inputFilters, $cName, $rName)
{
diff --git a/src/InputFilterInterface.php b/src/InputFilterInterface.php
index d1df0615..40550169 100644
--- a/src/InputFilterInterface.php
+++ b/src/InputFilterInterface.php
@@ -19,9 +19,12 @@ interface InputFilterInterface extends Countable
/**
* Add an input to the input filter
*
- * @param InputInterface|InputFilterInterface|array $input
+ * @param InputInterface|InputFilterInterface|array|Traversable $input
+ * Implementations MUST handle at least one of the specified types, and
+ * raise an exception for any they cannot process.
* @param null|string $name Name used to retrieve this input
* @return InputFilterInterface
+ * @throws Exception\InvalidArgumentException if unable to handle the input type.
*/
public function add($input, $name = null);
@@ -142,7 +145,7 @@ public function getRawValues();
* Should return an associative array of named input/message list pairs.
* Pairs should only be returned for inputs that failed validation.
*
- * @return array
+ * @return string[]
*/
public function getMessages();
}
diff --git a/src/InputFilterPluginManager.php b/src/InputFilterPluginManager.php
index bb5bccc3..c7460588 100644
--- a/src/InputFilterPluginManager.php
+++ b/src/InputFilterPluginManager.php
@@ -24,7 +24,7 @@ class InputFilterPluginManager extends AbstractPluginManager
/**
* Default set of plugins
*
- * @var array
+ * @var string[]
*/
protected $invokableClasses = array(
'inputfilter' => 'Zend\InputFilter\InputFilter',
@@ -83,8 +83,10 @@ public function validatePlugin($plugin)
}
throw new Exception\RuntimeException(sprintf(
- 'Plugin of type %s is invalid; must implement Zend\InputFilter\InputFilterInterface',
- (is_object($plugin) ? get_class($plugin) : gettype($plugin))
+ 'Plugin of type %s is invalid; must implement %s or %s',
+ (is_object($plugin) ? get_class($plugin) : gettype($plugin)),
+ 'Zend\InputFilter\InputFilterInterface',
+ 'Zend\InputFilter\InputInterface'
));
}
}
diff --git a/src/InputInterface.php b/src/InputInterface.php
index 14b0529a..cde375fa 100644
--- a/src/InputInterface.php
+++ b/src/InputInterface.php
@@ -15,6 +15,8 @@
interface InputInterface
{
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain and set this to `true`.
+ *
* @param bool $allowEmpty
* @return self
*/
@@ -69,6 +71,8 @@ public function setValue($value);
public function merge(InputInterface $input);
/**
+ * @deprecated 2.4.8 Add Zend\Validator\NotEmpty validator to the ValidatorChain.
+ *
* @return bool
*/
public function allowEmpty();
@@ -119,7 +123,7 @@ public function getValue();
public function isValid();
/**
- * @return array
+ * @return string[]
*/
public function getMessages();
}
diff --git a/test/ArrayInputTest.php b/test/ArrayInputTest.php
index 7268d677..84e24343 100644
--- a/test/ArrayInputTest.php
+++ b/test/ArrayInputTest.php
@@ -10,9 +10,10 @@
namespace ZendTest\InputFilter;
use Zend\InputFilter\ArrayInput;
-use Zend\Filter;
-use Zend\Validator;
+/**
+ * @covers Zend\InputFilter\ArrayInput
+ */
class ArrayInputTest extends InputTest
{
public function setUp()
@@ -20,230 +21,88 @@ public function setUp()
$this->input = new ArrayInput('foo');
}
- public function testValueIsNullByDefault()
- {
- $this->markTestSkipped('Test is not enabled in ArrayInputTest');
- }
-
- public function testValueIsEmptyArrayByDefault()
+ public function testDefaultGetValue()
{
$this->assertCount(0, $this->input->getValue());
}
- public function testNotArrayValueCannotBeInjected()
+ public function testSetValueWithInvalidInputTypeThrowsInvalidArgumentException()
{
- $this->setExpectedException('Zend\InputFilter\Exception\InvalidArgumentException');
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'Value must be an array, string given'
+ );
$this->input->setValue('bar');
}
- public function testValueMayBeInjected()
+ public function fallbackValueVsIsValidProvider()
{
- $this->input->setValue(array('bar'));
- $this->assertEquals(array('bar'), $this->input->getValue());
- }
+ $dataSets = parent::fallbackValueVsIsValidProvider();
+ array_walk($dataSets, function (&$set) {
+ $set[1] = array($set[1]); // Wrap fallback value into an array.
+ $set[2] = array($set[2]); // Wrap value into an array.
+ $set[4] = array($set[4]); // Wrap expected value into an array.
+ });
- public function testRetrievingValueFiltersTheValue()
- {
- $this->input->setValue(array('bar'));
- $filter = new Filter\StringToUpper();
- $this->input->getFilterChain()->attach($filter);
- $this->assertEquals(array('BAR'), $this->input->getValue());
- }
-
- public function testCanRetrieveRawValue()
- {
- $this->input->setValue(array('bar'));
- $filter = new Filter\StringToUpper();
- $this->input->getFilterChain()->attach($filter);
- $this->assertEquals(array('bar'), $this->input->getRawValue());
- }
-
- public function testIsValidReturnsFalseIfValidationChainFails()
- {
- $this->input->setValue(array('123', 'bar'));
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertFalse($this->input->isValid());
- }
-
- public function testIsValidReturnsTrueIfValidationChainSucceeds()
- {
- $this->input->setValue(array('123', '123'));
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertTrue($this->input->isValid());
+ return $dataSets;
}
- public function testValidationOperatesOnFilteredValue()
+ public function emptyValueProvider()
{
- $this->input->setValue(array(' 123 ', ' 123'));
- $filter = new Filter\StringTrim();
- $this->input->getFilterChain()->attach($filter);
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertTrue($this->input->isValid());
- }
+ $dataSets = parent::emptyValueProvider();
+ array_walk($dataSets, function (&$set) {
+ $set['raw'] = array($set['raw']); // Wrap value into an array.
+ });
- public function testGetMessagesReturnsValidationMessages()
- {
- $this->input->setValue(array('bar'));
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertFalse($this->input->isValid());
- $messages = $this->input->getMessages();
- $this->assertArrayHasKey(Validator\Digits::NOT_DIGITS, $messages);
+ return $dataSets;
}
- public function testSpecifyingMessagesToInputReturnsThoseOnFailedValidation()
+ public function mixedValueProvider()
{
- $this->input->setValue(array('bar'));
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->input->setErrorMessage('Please enter only digits');
- $this->assertFalse($this->input->isValid());
- $messages = $this->input->getMessages();
- $this->assertArrayNotHasKey(Validator\Digits::NOT_DIGITS, $messages);
- $this->assertContains('Please enter only digits', $messages);
- }
+ $dataSets = parent::mixedValueProvider();
+ array_walk($dataSets, function (&$set) {
+ $set['raw'] = array($set['raw']); // Wrap value into an array.
+ });
- public function testNotEmptyValidatorAddedWhenIsValidIsCalled()
- {
- $this->assertTrue($this->input->isRequired());
- $this->input->setValue(array('bar', ''));
- $validatorChain = $this->input->getValidatorChain();
- $this->assertEquals(0, count($validatorChain->getValidators()));
-
- $this->assertFalse($this->input->isValid());
- $messages = $this->input->getMessages();
- $this->assertArrayHasKey('isEmpty', $messages);
- $this->assertEquals(1, count($validatorChain->getValidators()));
-
- // Assert that NotEmpty validator wasn't added again
- $this->assertFalse($this->input->isValid());
- $this->assertEquals(1, count($validatorChain->getValidators()));
+ return $dataSets;
}
- public function testRequiredNotEmptyValidatorNotAddedWhenOneExists()
+ public function createFilterChainMock($valueRaw = null, $valueFiltered = null)
{
- $this->assertTrue($this->input->isRequired());
- $this->input->setValue(array('bar', ''));
-
- $notEmptyMock = $this->getMock('Zend\Validator\NotEmpty', array('isValid'));
- $notEmptyMock->expects($this->exactly(1))
- ->method('isValid')
- ->will($this->returnValue(false));
+ // ArrayInput filters per each array value
+ if (is_array($valueRaw)) {
+ $valueRaw = current($valueRaw);
+ }
- $validatorChain = $this->input->getValidatorChain();
- $validatorChain->prependValidator($notEmptyMock);
- $this->assertFalse($this->input->isValid());
+ if (is_array($valueFiltered)) {
+ $valueFiltered = current($valueFiltered);
+ }
- $validators = $validatorChain->getValidators();
- $this->assertEquals(1, count($validators));
- $this->assertEquals($notEmptyMock, $validators[0]['instance']);
+ return parent::createFilterChainMock($valueRaw, $valueFiltered);
}
- public function testMerge()
+ public function createValidatorChainMock($isValid = null, $value = null, $context = null, $messages = array())
{
- $input = new ArrayInput('foo');
- $input->setValue(array(' 123 '));
- $filter = new Filter\StringTrim();
- $input->getFilterChain()->attach($filter);
- $validator = new Validator\Digits();
- $input->getValidatorChain()->attach($validator);
-
- $input2 = new ArrayInput('bar');
- $input2->merge($input);
- $validatorChain = $input->getValidatorChain();
- $filterChain = $input->getFilterChain();
-
- $this->assertEquals(array(' 123 '), $input2->getRawValue());
- $this->assertEquals(1, $validatorChain->count());
- $this->assertEquals(1, $filterChain->count());
-
- $validators = $validatorChain->getValidators();
- $this->assertInstanceOf('Zend\Validator\Digits', $validators[0]['instance']);
-
- $filters = $filterChain->getFilters()->toArray();
- $this->assertInstanceOf('Zend\Filter\StringTrim', $filters[0]);
- }
+ // ArrayInput validates per each array value
+ if (is_array($value)) {
+ $value = current($value);
+ }
- public function testDoNotInjectNotEmptyValidatorIfAnywhereInChain()
- {
- $this->assertTrue($this->input->isRequired());
- $this->input->setValue(array('bar', ''));
-
- $notEmptyMock = $this->getMock('Zend\Validator\NotEmpty', array('isValid'));
- $notEmptyMock->expects($this->exactly(1))
- ->method('isValid')
- ->will($this->returnValue(false));
-
- $validatorChain = $this->input->getValidatorChain();
- $validatorChain->attach(new Validator\Digits());
- $validatorChain->attach($notEmptyMock);
- $this->assertFalse($this->input->isValid());
-
- $validators = $validatorChain->getValidators();
- $this->assertEquals(2, count($validators));
- $this->assertEquals($notEmptyMock, $validators[1]['instance']);
+ return parent::createValidatorChainMock($isValid, $value, $context, $messages);
}
- public function dataFallbackValue()
+ public function createNonEmptyValidatorMock($isValid, $value, $context = null)
{
- return array(
- array(
- 'fallbackValue' => array()
- ),
- array(
- 'fallbackValue' => array(''),
- ),
- array(
- 'fallbackValue' => array(null),
- ),
- array(
- 'fallbackValue' => array('some value'),
- ),
- );
- }
+ // ArrayInput validates per each array value
+ if (is_array($value)) {
+ $value = current($value);
+ }
- /**
- * @dataProvider dataFallbackValue
- */
- public function testFallbackValue($fallbackValue)
- {
- $this->input->setFallbackValue($fallbackValue);
- $validator = new Validator\Date();
- $this->input->getValidatorChain()->attach($validator);
- $this->input->setValue(array('123')); // not a date
-
- $this->assertTrue($this->input->isValid());
- $this->assertEmpty($this->input->getMessages());
- $this->assertSame($fallbackValue, $this->input->getValue());
- }
-
- public function emptyValuesProvider()
- {
- return array(
- array(array(null)),
- array(array('')),
- array(array(array())),
- );
- }
-
- public function testNotAllowEmptyWithFilterConvertsNonemptyToEmptyIsNotValid()
- {
- $this->input->setValue(array('nonempty'))
- ->getFilterChain()->attach(new Filter\Callback(function () {
- return '';
- }));
- $this->assertFalse($this->input->isValid());
+ return parent::createNonEmptyValidatorMock($isValid, $value, $context);
}
- public function testNotAllowEmptyWithFilterConvertsEmptyToNonEmptyIsValid()
+ public function getDummyValue($raw = true)
{
- $this->input->setValue(array(''))
- ->getFilterChain()->attach(new Filter\Callback(function () {
- return 'nonempty';
- }));
- $this->assertTrue($this->input->isValid());
+ return array(parent::getDummyValue($raw));
}
}
diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php
index 3a8664d1..d11eb890 100644
--- a/test/BaseInputFilterTest.php
+++ b/test/BaseInputFilterTest.php
@@ -9,815 +9,519 @@
namespace ZendTest\InputFilter;
+use ArrayIterator;
use ArrayObject;
+use FilterIterator;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
use PHPUnit_Framework_TestCase as TestCase;
use stdClass;
+use Zend\InputFilter\ArrayInput;
+use Zend\InputFilter\BaseInputFilter;
use Zend\InputFilter\Input;
-use Zend\InputFilter\FileInput;
-use Zend\InputFilter\BaseInputFilter as InputFilter;
-use Zend\Filter;
-use Zend\Validator;
+use Zend\InputFilter\InputFilterInterface;
+use Zend\InputFilter\InputInterface;
+/**
+ * @covers Zend\InputFilter\BaseInputFilter
+ */
class BaseInputFilterTest extends TestCase
{
- public function testInputFilterIsEmptyByDefault()
- {
- $filter = new InputFilter();
- $this->assertEquals(0, count($filter));
- }
+ /**
+ * @var BaseInputFilter
+ */
+ protected $inputFilter;
- public function testAddingInputsIncreasesCountOfFilter()
+ public function setUp()
{
- $filter = new InputFilter();
- $foo = new Input('foo');
- $filter->add($foo);
- $this->assertEquals(1, count($filter));
- $bar = new Input('bar');
- $filter->add($bar);
- $this->assertEquals(2, count($filter));
+ $this->inputFilter = new BaseInputFilter();
}
- public function testAddingInputWithNameDoesNotInjectNameInInput()
+ public function testInputFilterIsEmptyByDefault()
{
- $filter = new InputFilter();
- $foo = new Input('foo');
- $filter->add($foo, 'bar');
- $test = $filter->get('bar');
- $this->assertSame($foo, $test);
- $this->assertEquals('foo', $foo->getName());
+ $filter = $this->inputFilter;
+ $this->assertEquals(0, count($filter));
}
- public function testCanAddInputFilterAsInput()
+ public function testAddWithInvalidInputTypeThrowsInvalidArgumentException()
{
- $parent = new InputFilter();
- $child = new InputFilter();
- $parent->add($child, 'child');
- $this->assertEquals(1, count($parent));
- $this->assertSame($child, $parent->get('child'));
- }
+ $inputFilter = $this->inputFilter;
- public function testCanRemoveInputFilter()
- {
- $parent = new InputFilter();
- $child = new InputFilter();
- $parent->add($child, 'child');
- $this->assertEquals(1, count($parent));
- $this->assertSame($child, $parent->get('child'));
- $parent->remove('child');
- $this->assertEquals(0, count($parent));
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'expects an instance of Zend\InputFilter\InputInterface or Zend\InputFilter\InputFilterInterface ' .
+ 'as its first argument; received "stdClass"'
+ );
+ /** @noinspection PhpParamsInspection */
+ $inputFilter->add(new stdClass());
}
- public function getInputFilter()
+ public function testGetThrowExceptionIfInputDoesNotExists()
{
- $filter = new InputFilter();
-
- $foo = new Input();
- $foo->getFilterChain()->attachByName('stringtrim')
- ->attachByName('alpha');
- $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6));
-
- $bar = new Input();
- $bar->getFilterChain()->attachByName('stringtrim');
- $bar->getValidatorChain()->attach(new Validator\Digits());
-
- $baz = new Input();
- $baz->setRequired(false);
- $baz->getFilterChain()->attachByName('stringtrim');
- $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6));
-
- $qux = new Input();
- $qux->setAllowEmpty(true);
- $qux->getFilterChain()->attachByName('stringtrim');
- $qux->getValidatorChain()->attach(new Validator\StringLength(5, 6));
-
- $filter->add($foo, 'foo')
- ->add($bar, 'bar')
- ->add($baz, 'baz')
- ->add($qux, 'qux')
- ->add($this->getChildInputFilter(), 'nest');
-
- return $filter;
- }
+ $inputFilter = $this->inputFilter;
- public function getChildInputFilter()
- {
- $filter = new InputFilter();
-
- $foo = new Input();
- $foo->getFilterChain()->attachByName('stringtrim')
- ->attachByName('alpha');
- $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6));
-
- $bar = new Input();
- $bar->getFilterChain()->attachByName('stringtrim');
- $bar->getValidatorChain()->attach(new Validator\Digits());
-
- $baz = new Input();
- $baz->setRequired(false);
- $baz->getFilterChain()->attachByName('stringtrim');
- $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6));
-
- $filter->add($foo, 'foo')
- ->add($bar, 'bar')
- ->add($baz, 'baz');
- return $filter;
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'no input found matching "not exists"'
+ );
+ $inputFilter->get('not exists');
}
- public function dataSets()
+ public function testReplaceWithInvalidInputTypeThrowsInvalidArgumentException()
{
- return array(
- 'valid-with-empty-and-null' => array(
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => null,
- 'qux' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => null,
- ),
- ),
- true,
- ),
- 'valid-with-empty' => array(
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'qux' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- ),
- ),
- true,
- ),
- 'invalid-with-empty-and-missing' => array(
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => 'thisistoolong',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => 'thisistoolong',
- ),
- ),
- false,
- ),
- 'invalid-with-empty' => array(
- array(
- 'foo' => ' baz bat ',
- 'bar' => 'abc45',
- 'baz' => ' ',
- 'qux' => ' ',
- 'nest' => array(
- 'foo' => ' baz bat ',
- 'bar' => '123ab',
- 'baz' => ' ',
- ),
- ),
- false,
- ),
+ $inputFilter = $this->inputFilter;
+ $inputFilter->add(new Input('foo'), 'replace_me');
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'expects an instance of Zend\InputFilter\InputInterface or Zend\InputFilter\InputFilterInterface '
+ . 'as its first argument; received "stdClass"'
);
+ /** @noinspection PhpParamsInspection */
+ $inputFilter->replace(new stdClass(), 'replace_me');
}
- /**
- * @dataProvider dataSets
- * @group fmlife
- */
- public function testCanValidateEntireDataset($dataset, $expected)
+ public function testReplaceThrowExceptionIfInputToReplaceDoesNotExists()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
+ $inputFilter = $this->inputFilter;
- $filter = $this->getInputFilter();
- $filter->setData($dataset);
- $this->assertSame($expected, $filter->isValid());
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'no input found matching "not exists"'
+ );
+ $inputFilter->replace(new Input('foo'), 'not exists');
}
- public function testCanValidatePartialDataset()
+ public function testGetValueThrowExceptionIfInputDoesNotExists()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
+ $inputFilter = $this->inputFilter;
- $filter = $this->getInputFilter();
- $validData = array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- );
- $filter->setValidationGroup('foo', 'bar');
- $filter->setData($validData);
- $this->assertTrue($filter->isValid());
-
- $invalidData = array(
- 'bar' => 'abc45',
- 'nest' => array(
- 'foo' => ' 123bat ',
- 'bar' => '123ab',
- ),
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ '"not exists" was not found in the filter'
);
- $filter->setValidationGroup('bar', 'nest');
- $filter->setData($invalidData);
- $this->assertFalse($filter->isValid());
+ $inputFilter->getValue('not exists');
}
- public function testResetEmptyValidationGroupRecursively()
+ public function testGetRawValueThrowExceptionIfInputDoesNotExists()
{
- $data = array(
- 'flat' => 'foo',
- 'deep' => array(
- 'deep-input1' => 'deep-foo1',
- 'deep-input2' => 'deep-foo2',
- )
+ $inputFilter = $this->inputFilter;
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ '"not exists" was not found in the filter'
);
- $filter = new InputFilter;
- $filter->add(new Input, 'flat');
- $deepInputFilter = new InputFilter;
- $deepInputFilter->add(new Input, 'deep-input1');
- $deepInputFilter->add(new Input, 'deep-input2');
- $filter->add($deepInputFilter, 'deep');
- $filter->setData($data);
- $filter->setValidationGroup(array('deep' => 'deep-input1'));
- // reset validation group
- $filter->setValidationGroup(InputFilter::VALIDATE_ALL);
- $this->assertEquals($data, $filter->getValues());
+ $inputFilter->getRawValue('not exists');
}
- public function testSetDeepValidationGroupToNonInputFilterThrowsException()
+ public function testSetDataWithInvalidDataTypeThrowsInvalidArgumentException()
{
- $filter = $this->getInputFilter();
- $filter->add(new Input, 'flat');
- // we expect setValidationGroup to throw an exception when flat is treated
- // like an inputfilter which it actually isn't
+ $inputFilter = $this->inputFilter;
+
$this->setExpectedException(
'Zend\InputFilter\Exception\InvalidArgumentException',
- 'Input "flat" must implement InputFilterInterface'
+ 'expects an array or Traversable argument; received stdClass'
);
- $filter->setValidationGroup(array('flat' => 'foo'));
+ /** @noinspection PhpParamsInspection */
+ $inputFilter->setData(new stdClass());
}
- public function testCanRetrieveInvalidInputsOnFailedValidation()
+ public function testIsValidThrowExceptionIfDataWasNotSetYet()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
+ $inputFilter = $this->inputFilter;
- $filter = $this->getInputFilter();
- $invalidData = array(
- 'foo' => ' bazbat ',
- 'bar' => 'abc45',
- 'nest' => array(
- 'foo' => ' baz bat boo ',
- 'bar' => '12345',
- ),
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'no data present to validate'
);
- $filter->setData($invalidData);
- $this->assertFalse($filter->isValid());
- $invalidInputs = $filter->getInvalidInput();
- $this->assertArrayNotHasKey('foo', $invalidInputs);
- $this->assertArrayHasKey('bar', $invalidInputs);
- $this->assertInstanceOf('Zend\InputFilter\Input', $invalidInputs['bar']);
- $this->assertArrayHasKey('nest', $invalidInputs/*, var_export($invalidInputs, 1)*/);
- $this->assertInstanceOf('Zend\InputFilter\InputFilterInterface', $invalidInputs['nest']);
- $nestInvalids = $invalidInputs['nest']->getInvalidInput();
- $this->assertArrayHasKey('foo', $nestInvalids);
- $this->assertInstanceOf('Zend\InputFilter\Input', $nestInvalids['foo']);
- $this->assertArrayNotHasKey('bar', $nestInvalids);
+ $inputFilter->isValid();
}
- public function testCanRetrieveValidInputsOnFailedValidation()
+ public function testSetValidationGroupThrowExceptionIfInputIsNotAnInputFilter()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
+ $inputFilter = $this->inputFilter;
- $filter = $this->getInputFilter();
- $invalidData = array(
- 'foo' => ' bazbat ',
- 'bar' => 'abc45',
- 'nest' => array(
- 'foo' => ' baz bat ',
- 'bar' => '12345',
- ),
+ /** @var InputInterface|MockObject $nestedInput */
+ $nestedInput = $this->getMock('Zend\InputFilter\InputInterface');
+ $inputFilter->add($nestedInput, 'fooInput');
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'Input "fooInput" must implement InputFilterInterface'
);
- $filter->setData($invalidData);
- $this->assertFalse($filter->isValid());
- $validInputs = $filter->getValidInput();
- $this->assertArrayHasKey('foo', $validInputs);
- $this->assertInstanceOf('Zend\InputFilter\Input', $validInputs['foo']);
- $this->assertArrayNotHasKey('bar', $validInputs);
- $this->assertArrayHasKey('nest', $validInputs);
- $this->assertInstanceOf('Zend\InputFilter\InputFilterInterface', $validInputs['nest']);
- $nestValids = $validInputs['nest']->getValidInput();
- $this->assertArrayHasKey('foo', $nestValids);
- $this->assertInstanceOf('Zend\InputFilter\Input', $nestValids['foo']);
- $this->assertArrayHasKey('bar', $nestValids);
- $this->assertInstanceOf('Zend\InputFilter\Input', $nestValids['bar']);
+ $inputFilter->setValidationGroup(array('fooInput' => 'foo'));
}
- public function testValuesRetrievedAreFiltered()
+ public function testSetValidationGroupThrowExceptionIfInputFilterNotExists()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
+ $inputFilter = $this->inputFilter;
- $filter = $this->getInputFilter();
- $validData = array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'qux' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- ),
- );
- $filter->setData($validData);
- $this->assertTrue($filter->isValid());
- $expected = array(
- 'foo' => 'bazbat',
- 'bar' => '12345',
- 'baz' => null,
- 'qux' => '',
- 'nest' => array(
- 'foo' => 'bazbat',
- 'bar' => '12345',
- 'baz' => null,
- ),
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'expects a list of valid input names; "anotherNotExistsInputFilter" was not found'
);
- $this->assertEquals($expected, $filter->getValues());
+ $inputFilter->setValidationGroup(array('notExistInputFilter' => 'anotherNotExistsInputFilter'));
}
- public function testCanGetRawInputValues()
+ public function testSetValidationGroupThrowExceptionIfInputFilterInArgumentListNotExists()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
+ $inputFilter = $this->inputFilter;
- $filter = $this->getInputFilter();
- $validData = array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => null,
- 'qux' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => null,
- ),
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'expects a list of valid input names; "notExistInputFilter" was not found'
);
- $filter->setData($validData);
- $this->assertTrue($filter->isValid());
- $this->assertEquals($validData, $filter->getRawValues());
+ $inputFilter->setValidationGroup('notExistInputFilter');
}
- public function testCanGetValidationMessages()
+ public function testHasUnknownThrowExceptionIfDataWasNotSetYet()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
+ $inputFilter = $this->inputFilter;
- $filter = $this->getInputFilter();
- $filter->get('baz')->setRequired(true);
- $filter->get('nest')->get('baz')->setRequired(true);
- $invalidData = array(
- 'foo' => ' bazbat boo ',
- 'bar' => 'abc45',
- 'baz' => '',
- 'nest' => array(
- 'foo' => ' baz bat boo ',
- 'bar' => '123yz',
- 'baz' => '',
- ),
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException'
);
- $filter->setData($invalidData);
- $this->assertFalse($filter->isValid());
- $messages = $filter->getMessages();
- foreach ($invalidData as $key => $value) {
- $this->assertArrayHasKey($key, $messages);
- $currentMessages = $messages[$key];
- switch ($key) {
- case 'foo':
- $this->assertArrayHasKey(Validator\StringLength::TOO_LONG, $currentMessages);
- break;
- case 'bar':
- $this->assertArrayHasKey(Validator\Digits::NOT_DIGITS, $currentMessages);
- break;
- case 'baz':
- $this->assertArrayHasKey(Validator\NotEmpty::IS_EMPTY, $currentMessages);
- break;
- case 'nest':
- foreach ($value as $k => $v) {
- $this->assertArrayHasKey($k, $messages[$key]);
- $currentMessages = $messages[$key][$k];
- switch ($k) {
- case 'foo':
- $this->assertArrayHasKey(Validator\StringLength::TOO_LONG, $currentMessages);
- break;
- case 'bar':
- $this->assertArrayHasKey(Validator\Digits::NOT_DIGITS, $currentMessages);
- break;
- case 'baz':
- $this->assertArrayHasKey(Validator\NotEmpty::IS_EMPTY, $currentMessages);
- break;
- default:
- $this->fail(sprintf('Invalid key "%s" encountered in messages array', $k));
- }
- }
- break;
- default:
- $this->fail(sprintf('Invalid key "%s" encountered in messages array', $k));
- }
- }
+ $inputFilter->hasUnknown();
}
- /**
- * Idea for this one is that one input may only need to be validated if another input is present.
- *
- * Commenting out for now, as validation context may make this irrelevant, and unsure what API to expose.
- public function testCanConditionallyInvokeValidators()
+ public function testGetUnknownThrowExceptionIfDataWasNotSetYet()
{
- $this->markTestIncomplete();
+ $inputFilter = $this->inputFilter;
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException'
+ );
+ $inputFilter->getUnknown();
}
- */
/**
- * Idea for this one is that validation may need to rely on context -- e.g., a "password confirmation"
- * field may need to know what the original password entered was in order to compare.
+ * Verify the state of the input filter is the desired after change it using the method `add()`
+ *
+ * @dataProvider addMethodArgumentsProvider
*/
- public function testValidationCanUseContext()
+ public function testAddHasGet($input, $name, $expectedInputName, $expectedInput)
{
- $filter = new InputFilter();
-
- $store = new stdClass;
- $foo = new Input();
- $foo->getValidatorChain()->attach(new Validator\Callback(function ($value, $context) use ($store) {
- $store->value = $value;
- $store->context = $context;
- return true;
- }));
-
- $bar = new Input();
- $bar->getValidatorChain()->attach(new Validator\Digits());
+ $inputFilter = $this->inputFilter;
+ $this->assertFalse(
+ $inputFilter->has($expectedInputName),
+ "InputFilter shouldn't have an input with the name $expectedInputName yet"
+ );
+ $currentNumberOfFilters = count($inputFilter);
- $filter->add($foo, 'foo')
- ->add($bar, 'bar');
+ $return = $inputFilter->add($input, $name);
+ $this->assertSame($inputFilter, $return, "add() must return it self");
- $data = array('foo' => 'foo', 'bar' => 123);
- $filter->setData($data);
+ // **Check input collection state**
+ $this->assertTrue($inputFilter->has($expectedInputName), "There is no input with name $expectedInputName");
+ $this->assertCount($currentNumberOfFilters + 1, $inputFilter, 'Number of filters must be increased by 1');
- $this->assertTrue($filter->isValid());
- $this->assertEquals('foo', $store->value);
- $this->assertEquals($data, $store->context);
+ $returnInput = $inputFilter->get($expectedInputName);
+ $this->assertEquals($expectedInput, $returnInput, 'get() does not match the expected input');
}
/**
- * Idea here is that you can indicate that if validation for a particular input fails, we should not
- * attempt any further validation of any other inputs.
+ * Verify the state of the input filter is the desired after change it using the method `add()` and `remove()`
+ *
+ * @dataProvider addMethodArgumentsProvider
*/
- public function testInputBreakOnFailureFlagIsHonoredWhenValidating()
+ public function testAddRemove($input, $name, $expectedInputName)
{
- $filter = new InputFilter();
-
- $store = new stdClass;
- $foo = new Input();
- $foo->getValidatorChain()->attach(new Validator\Callback(function ($value, $context) use ($store) {
- $store->value = $value;
- $store->context = $context;
- return true;
- }));
+ $inputFilter = $this->inputFilter;
- $bar = new Input();
- $bar->getValidatorChain()->attach(new Validator\Digits());
- $bar->setBreakOnFailure(true);
+ $inputFilter->add($input, $name);
+ $currentNumberOfFilters = count($inputFilter);
- $filter->add($bar, 'bar') // adding bar first, as we want it to validate first and break the chain
- ->add($foo, 'foo');
+ $return = $inputFilter->remove($expectedInputName);
+ $this->assertSame($inputFilter, $return, 'remove() must return it self');
- $data = array('bar' => 'bar', 'foo' => 'foo');
- $filter->setData($data);
-
- $this->assertFalse($filter->isValid());
- $this->assertObjectNotHasAttribute('value', $store);
- $this->assertObjectNotHasAttribute('context', $store);
+ $this->assertFalse($inputFilter->has($expectedInputName), "There is no input with name $expectedInputName");
+ $this->assertCount($currentNumberOfFilters - 1, $inputFilter, 'Number of filters must be decreased by 1');
}
- public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent()
+ public function testAddingInputWithNameDoesNotInjectNameInInput()
{
- $filter = new InputFilter();
+ $inputFilter = $this->inputFilter;
- $foo = new Input();
- $foo->getValidatorChain()->attach(new Validator\StringLength(3, 5));
- $foo->setRequired(false);
+ $foo = new Input('foo');
+ $inputFilter->add($foo, 'bas');
+
+ $test = $inputFilter->get('bas');
+ $this->assertSame($foo, $test, 'get() does not match the input added');
+ $this->assertEquals('foo', $foo->getName(), 'Input name should not change');
+ }
- $bar = new Input();
- $bar->getValidatorChain()->attach(new Validator\Digits());
- $bar->setRequired(true);
+ /**
+ * @dataProvider inputProvider
+ */
+ public function testReplace($input, $inputName, $expectedInput)
+ {
+ $inputFilter = $this->inputFilter;
+ $nameToReplace = 'replace_me';
+ $inputToReplace = new Input($nameToReplace);
- $filter->add($foo, 'foo')
- ->add($bar, 'bar');
+ $inputFilter->add($inputToReplace);
+ $currentNumberOfFilters = count($inputFilter);
- $data = array('bar' => 124);
- $filter->setData($data);
+ $return = $inputFilter->replace($input, $nameToReplace);
+ $this->assertSame($inputFilter, $return, 'replace() must return it self');
+ $this->assertCount($currentNumberOfFilters, $inputFilter, "Number of filters shouldn't change");
- $this->assertTrue($filter->isValid());
+ $returnInput = $inputFilter->get($nameToReplace);
+ $this->assertEquals($expectedInput, $returnInput, 'get() does not match the expected input');
}
- public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoFileDataIsPresent()
- {
- $filter = new InputFilter();
-
- $foo = new FileInput();
- $foo->getValidatorChain()->attach(new Validator\File\UploadFile());
- $foo->setRequired(false);
+ /**
+ * @dataProvider setDataArgumentsProvider
+ */
+ public function testSetDataAndGetRawValueGetValue(
+ $inputs,
+ $data,
+ $expectedRawValues,
+ $expectedValues,
+ $expectedIsValid,
+ $expectedInvalidInputs,
+ $expectedValidInputs,
+ $expectedMessages
+ ) {
+ $inputFilter = $this->inputFilter;
+ foreach ($inputs as $inputName => $input) {
+ $inputFilter->add($input, $inputName);
+ }
+ $return = $inputFilter->setData($data);
+ $this->assertSame($inputFilter, $return, 'setData() must return it self');
+
+ // ** Check filter state **
+ $this->assertSame($expectedRawValues, $inputFilter->getRawValues(), 'getRawValues() value not match');
+ foreach ($expectedRawValues as $inputName => $expectedRawValue) {
+ $this->assertSame(
+ $expectedRawValue,
+ $inputFilter->getRawValue($inputName),
+ 'getRawValue() value not match for input ' . $inputName
+ );
+ }
- $filter->add($foo, 'foo');
+ $this->assertSame($expectedValues, $inputFilter->getValues(), 'getValues() value not match');
+ foreach ($expectedValues as $inputName => $expectedValue) {
+ $this->assertSame(
+ $expectedValue,
+ $inputFilter->getValue($inputName),
+ 'getValue() value not match for input ' . $inputName
+ );
+ }
- $data = array(
- 'foo' => array(
- 'tmp_name' => '/tmp/barfile',
- 'name' => 'barfile',
- 'type' => 'text',
- 'size' => 0,
- 'error' => 4, // UPLOAD_ERR_NO_FILE
- )
- );
- $filter->setData($data);
- $this->assertTrue($filter->isValid());
+ // ** Check validation state **
+ $this->assertEquals($expectedIsValid, $inputFilter->isValid(), 'isValid() value not match');
+ $this->assertEquals($expectedInvalidInputs, $inputFilter->getInvalidInput(), 'getInvalidInput() value not match');
+ $this->assertEquals($expectedValidInputs, $inputFilter->getValidInput(), 'getValidInput() value not match');
+ $this->assertEquals($expectedMessages, $inputFilter->getMessages(), 'getMessages() value not match');
- // Negative test
- $foo->setRequired(true);
- $filter->setData($data);
- $this->assertFalse($filter->isValid());
+ // ** Check unknown fields **
+ $this->assertFalse($inputFilter->hasUnknown(), 'hasUnknown() value not match');
+ $this->assertEmpty($inputFilter->getUnknown(), 'getUnknown() value not match');
}
- public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoMultiFileDataIsPresent()
- {
- $filter = new InputFilter();
- $foo = new FileInput();
- $foo->setRequired(false);
- $filter->add($foo, 'foo');
-
- $data = array(
- 'foo' => array(array(
- 'tmp_name' => '/tmp/barfile',
- 'name' => 'barfile',
- 'type' => 'text',
- 'size' => 0,
- 'error' => 4, // UPLOAD_ERR_NO_FILE
- )),
+ /**
+ * @dataProvider setDataArgumentsProvider
+ */
+ public function testSetTraversableDataAndGetRawValueGetValue(
+ $inputs,
+ $data,
+ $expectedRawValues,
+ $expectedValues,
+ $expectedIsValid,
+ $expectedInvalidInputs,
+ $expectedValidInputs,
+ $expectedMessages
+ ) {
+ $dataTypes = $this->dataTypes();
+ $this->testSetDataAndGetRawValueGetValue(
+ $inputs,
+ $dataTypes['Traversable']($data),
+ $expectedRawValues,
+ $expectedValues,
+ $expectedIsValid,
+ $expectedInvalidInputs,
+ $expectedValidInputs,
+ $expectedMessages
);
- $filter->setData($data);
- $this->assertTrue($filter->isValid());
-
- // Negative test
- $foo->setRequired(true);
- $filter->setData($data);
- $this->assertFalse($filter->isValid());
}
- public function testValidationAllowsEmptyValuesToRequiredInputWhenAllowEmptyFlagIsTrue()
+ public function testResetEmptyValidationGroupRecursively()
{
- $filter = new InputFilter();
-
- $foo = new Input('foo');
- $foo->getValidatorChain()->attach(new Validator\StringLength(3, 5));
- $foo->setRequired(true);
- $foo->setAllowEmpty(true);
-
- $bar = new Input();
- $bar->getValidatorChain()->attach(new Validator\Digits());
- $bar->setRequired(true);
-
- $filter->add($foo, '')
- ->add($bar, 'bar');
-
$data = array(
- 'bar' => 124,
- 'foo' => '',
+ 'flat' => 'foo',
+ 'deep' => array(
+ 'deep-input1' => 'deep-foo1',
+ 'deep-input2' => 'deep-foo2',
+ )
);
-
+ $expectedData = array_merge($data, array('notSet' => null));
+ /** @var Input|MockObject $resetInput */
+ $flatInput = $this->getMockBuilder('Zend\InputFilter\Input')
+ ->enableProxyingToOriginalMethods()
+ ->setConstructorArgs(array('flat'))
+ ->getMock()
+ ;
+ $flatInput->expects($this->once())
+ ->method('setValue')
+ ->with('foo')
+ ;
+ // Inputs without value must be reset for to have clean states when use different setData arguments
+ /** @var Input|MockObject $flatInput */
+ $resetInput = $this->getMockBuilder('Zend\InputFilter\Input')
+ ->enableProxyingToOriginalMethods()
+ ->setConstructorArgs(array('notSet'))
+ ->getMock()
+ ;
+ $resetInput->expects($this->once())
+ ->method('resetValue')
+ ;
+
+ $filter = $this->inputFilter;
+ $filter->add($flatInput);
+ $filter->add($resetInput);
+ $deepInputFilter = new BaseInputFilter;
+ $deepInputFilter->add(new Input, 'deep-input1');
+ $deepInputFilter->add(new Input, 'deep-input2');
+ $filter->add($deepInputFilter, 'deep');
$filter->setData($data);
-
- $this->assertTrue($filter->isValid());
- $this->assertEquals('', $filter->getValue('foo'));
+ $filter->setValidationGroup(array('deep' => 'deep-input1'));
+ // reset validation group
+ $filter->setValidationGroup(InputFilterInterface::VALIDATE_ALL);
+ $this->assertEquals($expectedData, $filter->getValues());
}
- public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFalse()
- {
- $filter = new InputFilter();
-
- $foo = new Input();
- $foo->getValidatorChain()->attach(new Validator\StringLength(3, 5));
- $foo->setRequired(true);
- $foo->setAllowEmpty(false);
-
- $bar = new Input();
- $bar->getValidatorChain()->attach(new Validator\Digits());
- $bar->setRequired(true);
-
- $filter->add($foo, '')
- ->add($bar, 'bar');
-
- $data = array('bar' => 124);
- $filter->setData($data);
-
- $this->assertFalse($filter->isValid());
- }
+ /*
+ * Idea for this one is that validation may need to rely on context -- e.g., a "password confirmation"
+ * field may need to know what the original password entered was in order to compare.
+ */
- public static function contextDataProvider()
+ public function contextProvider()
{
+ $data = array('fooInput' => 'fooValue');
+ $traversableData = new ArrayObject(array('fooInput' => 'fooValue'));
+ $expectedFromData = array('fooInput' => 'fooValue');
+
return array(
- array('', 'y', true),
- array('', 'n', false),
+ // Description => [$data, $customContext, $expectedContext]
+ 'by default get context from data (array)' => array($data, null, $expectedFromData),
+ 'by default get context from data (Traversable)' => array($traversableData, null, $expectedFromData),
+ 'use custom context' => array(array(), 'fooContext', 'fooContext'),
);
}
/**
- * Idea here is that an empty field may or may not be valid based on
- * context.
+ * @dataProvider contextProvider
*/
- /**
- * @dataProvider contextDataProvider()
- */
- // @codingStandardsIgnoreStart
- public function testValidationMarksInputValidWhenAllowEmptyFlagIsTrueAndContinueIfEmptyIsTrueAndContextValidatesEmptyField($allowEmpty, $blankIsValid, $valid)
+ public function testValidationContext($data, $customContext, $expectedContext)
{
- // @codingStandardsIgnoreEnd
- $filter = new InputFilter();
+ $filter = $this->inputFilter;
- $data = array(
- 'allowEmpty' => $allowEmpty,
- 'blankIsValid' => $blankIsValid,
- );
+ $input = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext);
+ $filter->add($input, 'fooInput');
- $allowEmpty = new Input();
- $allowEmpty->setAllowEmpty(true)
- ->setContinueIfEmpty(true);
-
- $blankIsValid = new Input();
- $blankIsValid->getValidatorChain()->attach(new Validator\Callback(function ($value, $context) {
- return ('y' === $value && empty($context['allowEmpty']));
- }));
-
- $filter->add($allowEmpty, 'allowEmpty')
- ->add($blankIsValid, 'blankIsValid');
$filter->setData($data);
- $this->assertSame($valid, $filter->isValid());
+ $this->assertTrue(
+ $filter->isValid($customContext),
+ 'isValid() value not match. Detail: ' . json_encode($filter->getMessages())
+ );
}
- public function testCanRetrieveRawValuesIndividuallyWithoutValidating()
+ public function testBuildValidationContextUsingInputGetRawValue()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
+ $data = array();
+ $expectedContext = array('fooInput' => 'fooRawValue');
+ $filter = $this->inputFilter;
+
+ $input = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext, 'fooRawValue');
+ $filter->add($input, 'fooInput');
- $filter = $this->getInputFilter();
- $data = array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- ),
- );
$filter->setData($data);
- $test = $filter->getRawValue('foo');
- $this->assertSame($data['foo'], $test);
+
+ $this->assertTrue(
+ $filter->isValid(),
+ 'isValid() value not match. Detail: ' . json_encode($filter->getMessages())
+ );
}
- public function testCanRetrieveUnvalidatedButFilteredInputValue()
+ public function testContextIsTheSameWhenARequiredInputIsGivenAndOptionalInputIsMissing()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $filter = $this->getInputFilter();
$data = array(
- 'foo' => ' baz 2 bat ',
- 'bar' => '12345',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- ),
+ 'inputRequired' => 'inputRequiredValue',
+ );
+ $expectedContext = array(
+ 'inputRequired' => 'inputRequiredValue',
+ 'inputOptional' => null,
);
+ $inputRequired = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext);
+ $inputOptional = $this->createInputInterfaceMock('fooInput', false);
+
+ $filter = $this->inputFilter;
+ $filter->add($inputRequired, 'inputRequired');
+ $filter->add($inputOptional, 'inputOptional');
+
$filter->setData($data);
- $test = $filter->getValue('foo');
- $this->assertSame('bazbat', $test);
+
+ $this->assertTrue(
+ $filter->isValid(),
+ 'isValid() value not match. Detail: ' . json_encode($filter->getMessages())
+ );
}
- public function testGetRequiredNotEmptyValidationMessages()
+ public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent()
{
- $filter = new InputFilter();
+ $filter = $this->inputFilter;
- $foo = new Input();
- $foo->setRequired(true);
- $foo->setAllowEmpty(false);
+ $optionalInputName = 'fooOptionalInput';
+ /** @var InputInterface|MockObject $optionalInput */
+ $optionalInput = $this->getMock('Zend\InputFilter\InputInterface');
+ $optionalInput->method('getName')
+ ->willReturn($optionalInputName)
+ ;
+ $optionalInput->expects($this->never())
+ ->method('isValid')
+ ;
+ $data = array();
- $filter->add($foo, 'foo');
+ $filter->add($optionalInput);
- $data = array('foo' => null);
$filter->setData($data);
- $this->assertFalse($filter->isValid());
- $messages = $filter->getMessages();
- $this->assertArrayHasKey('foo', $messages);
- $this->assertNotEmpty($messages['foo']);
- }
-
- public function testHasUnknown()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $filter = $this->getInputFilter();
- $validData = array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => ''
+ $this->assertTrue(
+ $filter->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($filter->getMessages())
);
- $filter->setData($validData);
- $this->assertFalse($filter->hasUnknown());
-
- $filter = $this->getInputFilter();
- $invalidData = array(
- 'bar' => '12345',
- 'baz' => '',
- 'gru' => '',
+ $this->assertArrayNotHasKey(
+ $optionalInputName,
+ $filter->getValidInput(),
+ 'Missing optional fields must not appear as valid input neither invalid input'
);
- $filter->setData($invalidData);
- $this->assertTrue($filter->hasUnknown());
- }
- public function testGetUknown()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $filter = $this->getInputFilter();
- $unknown = array(
- 'bar' => '12345',
- 'baz' => '',
- 'gru' => 10,
- 'test' => 'ok',
+ $this->assertArrayNotHasKey(
+ $optionalInputName,
+ $filter->getInvalidInput(),
+ 'Missing optional fields must not appear as valid input neither invalid input'
);
- $filter->setData($unknown);
- $unknown = $filter->getUnknown();
- $this->assertEquals(2, count($unknown));
- $this->assertArrayHasKey('gru', $unknown);
- $this->assertEquals(10, $unknown['gru']);
- $this->assertArrayHasKey('test', $unknown);
- $this->assertEquals('ok', $unknown['test']);
-
- $filter = $this->getInputFilter();
- $validData = array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => ''
- );
- $filter->setData($validData);
- $unknown = $filter->getUnknown();
- $this->assertEquals(0, count($unknown));
}
- public function testValidateUseExplodeAndInstanceOf()
+ /**
+ * @dataProvider unknownScenariosProvider
+ */
+ public function testUnknown($inputs, $data, $hasUnknown, $getUnknown)
{
- $filter = new InputFilter();
-
- $input = new Input();
- $input->setRequired(true);
-
- $input->getValidatorChain()->attach(
- new \Zend\Validator\Explode(
- array(
- 'validator' => new \Zend\Validator\IsInstanceOf(
- array(
- 'className' => 'Zend\InputFilter\Input'
- )
- )
- )
- )
- );
+ $inputFilter = $this->inputFilter;
+ foreach ($inputs as $name => $input) {
+ $inputFilter->add($input, $name);
+ }
- $filter->add($input, 'example');
+ $inputFilter->setData($data);
- $data = array(
- 'example' => array(
- $input
- )
- );
-
- $filter->setData($data);
- $this->assertTrue($filter->isValid());
+ $this->assertEquals($getUnknown, $inputFilter->getUnknown(), 'getUnknown() value not match');
+ $this->assertEquals($hasUnknown, $inputFilter->hasUnknown(), 'hasUnknown() value not match');
}
public function testGetInputs()
{
- $filter = new InputFilter();
+ $filter = $this->inputFilter;
$foo = new Input('foo');
$bar = new Input('bar');
@@ -837,7 +541,7 @@ public function testGetInputs()
*/
public function testAddingExistingInputWillMergeIntoExisting()
{
- $filter = new InputFilter();
+ $filter = $this->inputFilter;
$foo1 = new Input('foo');
$foo1->setRequired(true);
@@ -850,52 +554,19 @@ public function testAddingExistingInputWillMergeIntoExisting()
$this->assertFalse($filter->get('foo')->isRequired());
}
- /**
- * @group 5270
- * @requires extension intl
- */
- public function testIsValidWhenValuesSetOnFilters()
- {
- $filter = new InputFilter();
-
- $foo = new Input();
- $foo->getFilterChain()->attachByName('stringtrim')
- ->attachByName('alpha');
- $foo->getValidatorChain()->attach(new Validator\StringLength(15, 18));
-
- $filter->add($foo, 'foo');
-
- //test valid with setData
- $filter->setData(array('foo' => 'invalid'));
- $this->assertFalse($filter->isValid());
-
- //test invalid with setData
- $filter->setData(array('foo' => 'thisisavalidstring'));
- $this->assertTrue($filter->isValid());
-
- //test invalid when setting data on actual filter
- $filter->get('foo')->setValue('invalid');
- $this->assertFalse($filter->get('foo')->isValid(), 'Filtered value is valid, should be invalid');
- $this->assertFalse($filter->isValid(), 'Input filter did not return value from filter');
-
- //test valid when setting data on actual filter
- $filter->get('foo')->setValue('thisisavalidstring');
- $this->assertTrue($filter->get('foo')->isValid(), 'Filtered value is not valid');
- $this->assertTrue($filter->isValid(), 'Input filter did return value from filter');
- }
-
/**
* @group 5638
*/
public function testPopulateSupportsArrayInputEvenIfDataMissing()
{
+ /** @var ArrayInput|MockObject $arrayInput */
$arrayInput = $this->getMock('Zend\InputFilter\ArrayInput');
$arrayInput
->expects($this->once())
->method('setValue')
->with(array());
- $filter = new InputFilter();
+ $filter = $this->inputFilter;
$filter->add($arrayInput, 'arrayInput');
$filter->setData(array('foo' => 'bar'));
}
@@ -905,8 +576,8 @@ public function testPopulateSupportsArrayInputEvenIfDataMissing()
*/
public function testMerge()
{
- $inputFilter = new InputFilter();
- $originInputFilter = new InputFilter();
+ $inputFilter = $this->inputFilter;
+ $originInputFilter = new BaseInputFilter();
$inputFilter->add(new Input(), 'foo');
$inputFilter->add(new Input(), 'bar');
@@ -919,199 +590,308 @@ public function testMerge()
array(
'foo',
'bar',
- 'baz'
+ 'baz',
),
array_keys($inputFilter->getInputs())
);
}
- public function testAllowEmptyTestsFilteredValueAndOverrulesValidatorChain()
+ public function addMethodArgumentsProvider()
{
- $input = new Input('foo');
- $input->setAllowEmpty(true);
- $input->setContinueIfEmpty(false);
- // Filter chain produces empty value which should be evaluated instead of raw value
- $input->getFilterChain()->attach(new Filter\Callback(function () {
- return '';
- }));
- // Validator chain says "not valid", but should not be invoked at all
- $input->getValidatorChain()->attach(new Validator\Callback(function () {
- return false;
- }));
-
- $filter = new \Zend\InputFilter\InputFilter;
- $filter->add($input)
- ->setData(array('foo' => 'nonempty'));
-
- $this->assertTrue($filter->isValid());
- $this->assertEquals(array('foo' => ''), $filter->getValues());
- }
+ $inputTypes = $this->inputProvider();
- public function testAllowEmptyTestsFilteredValueAndContinuesIfEmpty()
- {
- $input = new Input('foo');
- $input->setAllowEmpty(true);
- $input->setContinueIfEmpty(true);
- // Filter chain produces empty value which should be evaluated instead of raw value
- $input->getFilterChain()->attach(new Filter\Callback(function () {
- return '';
- }));
- // Validator chain says "not valid", explicitly requested despite empty input
- $input->getValidatorChain()->attach(new Validator\Callback(function () {
- return false;
- }));
-
- $filter = new \Zend\InputFilter\InputFilter;
- $filter->add($input)
- ->setData(array('foo' => 'nonempty'));
-
- $this->assertFalse($filter->isValid());
- }
-
- /**
- * @group 7
- */
- public function testMissingRequiredAllowedEmptyValueShouldMarkInputFilterInvalid()
- {
- $foo = new Input('foo');
- $foo->setRequired(true);
- $foo->setAllowEmpty(false);
+ $inputName = function ($inputTypeData) {
+ return $inputTypeData[1];
+ };
- $bar = new Input('bar');
- $bar->setRequired(true);
- $bar->setAllowEmpty(true);
+ $sameInput = function ($inputTypeData) {
+ return $inputTypeData[2];
+ };
- $filter = new InputFilter();
- $filter->add($foo);
- $filter->add($bar);
+ // @codingStandardsIgnoreStart
+ $dataTemplates = array(
+ // Description => [[$input argument], $name argument, $expectedName, $expectedInput]
+ 'null' => array($inputTypes, null , $inputName , $sameInput),
+ 'custom_name' => array($inputTypes, 'custom_name', 'custom_name', $sameInput),
+ );
+ // @codingStandardsIgnoreEnd
- $filter->setData(array('foo' => 'xyz'));
- $this->assertFalse($filter->isValid(), 'Missing required value should mark input filter as invalid');
- }
+ // Expand data template matrix for each possible input type.
+ // Description => [$input argument, $name argument, $expectedName, $expectedInput]
+ $dataSets = array();
+ foreach ($dataTemplates as $dataTemplateDescription => $dataTemplate) {
+ foreach ($dataTemplate[0] as $inputTypeDescription => $inputTypeData) {
+ $tmpTemplate = $dataTemplate;
+ $tmpTemplate[0] = $inputTypeData[0]; // expand input
+ if (is_callable($dataTemplate[2])) {
+ $tmpTemplate[2] = $dataTemplate[2]($inputTypeData);
+ }
+ $tmpTemplate[3] = $dataTemplate[3]($inputTypeData);
+
+ $dataSets[$inputTypeDescription . ' / ' . $dataTemplateDescription] = $tmpTemplate;
+ }
+ }
- public function emptyValuesForValidation()
- {
- return array(
- 'null' => array(null),
- 'empty-string' => array(''),
+ return $dataSets;
+ }
+
+ public function setDataArgumentsProvider()
+ {
+ $iAName = 'InputA';
+ $iBName = 'InputB';
+ $vRaw = 'rawValue';
+ $vFiltered = 'filteredValue';
+
+ $dARaw = array($iAName => $vRaw);
+ $dBRaw = array($iBName => $vRaw);
+ $dAfRaw = array($iAName => array('fooInput' => $vRaw));
+ $d2Raw = array_merge($dARaw, $dBRaw);
+ $dAfBRaw = array_merge($dAfRaw, $dBRaw);
+ $dAFiltered = array($iAName => $vFiltered);
+ $dBFiltered = array($iBName => $vFiltered);
+ $dAfFiltered = array($iAName => array('fooInput' => $vFiltered));
+ $d2Filtered = array_merge($dAFiltered, $dBFiltered);
+ $dAfBFiltered = array_merge($dAfFiltered, $dBFiltered);
+
+ $required = true;
+ $valid = true;
+ $bOnFail = true;
+
+ $self = $this;
+ $input = function ($iName, $required, $bOnFail, $isValid, $msg = array()) use ($vRaw, $vFiltered, $self) {
+ // @codingStandardsIgnoreStart
+ return function ($context) use ($iName, $required, $bOnFail, $isValid, $vRaw, $vFiltered, $msg, $self) {
+ return $self->createInputInterfaceMock($iName, $required, $isValid, $context, $vRaw, $vFiltered, $msg, $bOnFail);
+ };
+ // @codingStandardsIgnoreEnd
+ };
+
+ $inputFilter = function ($isValid, $msg = array()) use ($vRaw, $vFiltered, $self) {
+ // @codingStandardsIgnoreStart
+ return function ($context) use ($isValid, $vRaw, $vFiltered, $msg, $self) {
+ $vRaw = array('fooInput' => $vRaw);
+ $vFiltered = array('fooInput' => $vFiltered);
+ return $self->createInputFilterInterfaceMock($isValid, $context, $vRaw, $vFiltered, $msg);
+ };
+ // @codingStandardsIgnoreEnd
+ };
+
+ // @codingStandardsIgnoreStart
+ $iAri = array($iAName => $input($iAName, $required, !$bOnFail, !$valid, array('Invalid ' . $iAName)));
+ $iAriX = array($iAName => $input($iAName, $required, $bOnFail, !$valid, array('Invalid ' . $iAName)));
+ $iArvX = array($iAName => $input($iAName, $required, $bOnFail, $valid, array()));
+ $iBri = array($iBName => $input($iBName, $required, !$bOnFail, !$valid, array('Invalid ' . $iBName)));
+ $iBriX = array($iBName => $input($iBName, $required, $bOnFail, !$valid, array('Invalid ' . $iBName)));
+ $iBrvX = array($iBName => $input($iBName, $required, $bOnFail, $valid, array()));
+ $ifAi = array($iAName => $inputFilter(!$valid, array('fooInput' => array('Invalid ' . $iAName))));
+ $ifAv = array($iAName => $inputFilter($valid));
+ $iAriBri = array_merge($iAri, $iBri);
+ $iArvXBrvX = array_merge($iArvX, $iBrvX);
+ $iAriBrvX = array_merge($iAri, $iBrvX);
+ $iArvXBir = array_merge($iArvX, $iBri);
+ $iAriXBrvX = array_merge($iAriX, $iBrvX);
+ $iArvXBriX = array_merge($iArvX, $iBriX);
+ $iAriXBriX = array_merge($iAriX, $iBriX);
+ $ifAiBri = array_merge($ifAi, $iBri);
+ $ifAiBrvX = array_merge($ifAi, $iBrvX);
+ $ifAvBri = array_merge($ifAv, $iBri);
+ $ifAvBrv = array_merge($ifAv, $iBrvX);
+
+ $msgAInv = array($iAName => array('Invalid InputA'));
+ $msgBInv = array($iBName => array('Invalid InputB'));
+ $msgAfInv = array($iAName => array('fooInput' => array('Invalid InputA')));
+ $msg2Inv = array_merge($msgAInv, $msgBInv);
+ $msgAfBInv = array_merge($msgAfInv, $msgBInv);
+
+ $dataSets = array(
+ // Description => [$inputs, $data argument, $expectedRawValues, $expectedValues, $expectedIsValid,
+ // $expectedInvalidInputs, $expectedValidInputs, $expectedMessages]
+ 'invalid Break invalid' => array($iAriXBriX, $d2Raw , $d2Raw , $d2Filtered , false, $iAri , array() , $msgAInv),
+ 'invalid Break valid' => array($iAriXBrvX, $d2Raw , $d2Raw , $d2Filtered , false, $iAri , array() , $msgAInv),
+ 'valid Break invalid' => array($iArvXBriX, $d2Raw , $d2Raw , $d2Filtered , false, $iBri , $iAri , $msgBInv),
+ 'valid Break valid' => array($iArvXBrvX, $d2Raw , $d2Raw , $d2Filtered , true , array() , $iArvXBrvX, array()),
+ 'valid invalid' => array($iArvXBir , $d2Raw , $d2Raw , $d2Filtered , false, $iBri , $iArvX , $msgBInv),
+ 'IInvalid IValid' => array($iAriBrvX , $d2Raw , $d2Raw , $d2Filtered , false, $iAri , $iBrvX , $msgAInv),
+ 'IInvalid IInvalid' => array($iAriBri , $d2Raw , $d2Raw , $d2Filtered , false, $iAriBri , array() , $msg2Inv),
+ 'IInvalid IValid / Partial' => array($iAriBri , $dARaw , $d2Raw , $d2Filtered , false, $iAriBrvX, array() , $msg2Inv),
+ 'IFInvalid IValid' => array($ifAiBrvX , $dAfBRaw, $dAfBRaw, $dAfBFiltered, false, $ifAi , $iBrvX , $msgAfInv),
+ 'IFInvalid IInvalid' => array($ifAiBri , $dAfBRaw, $dAfBRaw, $dAfBFiltered, false, $ifAiBri , array() , $msgAfBInv),
+ 'IFValid IInvalid' => array($ifAvBri , $dAfBRaw, $dAfBRaw, $dAfBFiltered, false, $iBri , $ifAv , $msgBInv),
+ 'IFValid IValid' => array($ifAvBrv , $dAfBRaw, $dAfBRaw, $dAfBFiltered, true , array() , $ifAvBrv , array()),
);
- }
-
- /**
- * @group 7
- * @dataProvider emptyValuesForValidation
- */
- public function testEmptyValuePassedForRequiredButAllowedEmptyInputShouldMarkInputFilterValid($value)
- {
- $foo = new Input('foo');
- $foo->setRequired(true);
- $foo->setAllowEmpty(false);
+ // @codingStandardsIgnoreEnd
- $bar = new Input('bar');
- $bar->setRequired(true);
- $bar->setAllowEmpty(true);
+ array_walk(
+ $dataSets,
+ function (&$set) {
+ // Create unique mock input instances for each set
+ foreach ($set[0] as $name => $createMock) {
+ $input = $createMock($set[2]);
- $filter = new InputFilter();
- $filter->add($foo);
- $filter->add($bar);
+ $set[0][$name] = $input;
+ if (in_array($name, array_keys($set[5]))) {
+ $set[5][$name] = $input;
+ }
+ if (in_array($name, array_keys($set[6]))) {
+ $set[6][$name] = $input;
+ }
+ }
+ }
+ );
- $filter->setData(array(
- 'foo' => 'xyz',
- 'bar' => $value,
- ));
- $this->assertTrue($filter->isValid(), 'Empty value should mark input filter as valid');
+ return $dataSets;
}
- /**
- * @group 10
- */
- public function testMissingRequiredWithFallbackShouldMarkInputValid()
+ public function unknownScenariosProvider()
{
- $foo = new Input('foo');
- $foo->setRequired(true);
- $foo->setAllowEmpty(false);
+ $inputA = $this->createInputInterfaceMock('inputA', true);
+ $dataA = array('inputA' => 'foo');
+ $dataUnknown = array('inputUnknown' => 'unknownValue');
+ $dataAAndUnknown = array_merge($dataA, $dataUnknown);
- $bar = new Input('bar');
- $bar->setRequired(true);
- $bar->setFallbackValue('baz');
+ // @codingStandardsIgnoreStart
+ return array(
+ // Description => [$inputs, $data, $hasUnknown, $getUnknown]
+ 'empty data and inputs' => array(array() , array() , false, array()),
+ 'empty data' => array(array($inputA), array() , false, array()),
+ 'data and fields match' => array(array($inputA), $dataA , false, array()),
+ 'data known and unknown' => array(array($inputA), $dataAAndUnknown, true , $dataUnknown),
+ 'data unknown' => array(array($inputA), $dataUnknown , true , $dataUnknown),
+ 'data unknown, no input' => array(array() , $dataUnknown , true , $dataUnknown),
+ );
+ // @codingStandardsIgnoreEnd
+ }
- $filter = new InputFilter();
- $filter->add($foo);
- $filter->add($bar);
+ public function inputProvider()
+ {
+ $input = $this->createInputInterfaceMock('fooInput', null);
+ $inputFilter = $this->createInputFilterInterfaceMock();
- $filter->setData(array('foo' => 'xyz'));
- $this->assertTrue($filter->isValid(), 'Missing input with fallback value should mark input filter as valid');
- $data = $filter->getValues();
- $this->assertArrayHasKey('bar', $data);
- $this->assertEquals($bar->getFallbackValue(), $data['bar']);
+ // @codingStandardsIgnoreStart
+ return array(
+ // Description => [input, expected name, $expectedReturnInput]
+ 'InputInterface' => array($input , 'fooInput', $input),
+ 'InputFilterInterface' => array($inputFilter, null , $inputFilter),
+ );
+ // @codingStandardsIgnoreEnd
}
/**
- * @group 10
+ * @param null|bool $isValid
+ * @param mixed $context
+ * @param mixed[] $getRawValues
+ * @param mixed[] $getValues
+ * @param string[] $getMessages
+ *
+ * @return MockObject|InputFilterInterface
*/
- public function testMissingRequiredThatAllowsEmptyWithFallbackShouldMarkInputValid()
- {
- $foo = new Input('foo');
- $foo->setRequired(true);
- $foo->setAllowEmpty(false);
-
- $bar = new Input('bar');
- $bar->setRequired(true);
- $bar->setAllowEmpty(true);
- $bar->setFallbackValue('baz');
-
- $filter = new InputFilter();
- $filter->add($foo);
- $filter->add($bar);
+ public function createInputFilterInterfaceMock(
+ $isValid = null,
+ $context = null,
+ $getRawValues = array(),
+ $getValues = array(),
+ $getMessages = array()
+ ) {
+ /** @var InputFilterInterface|MockObject $inputFilter */
+ $inputFilter = $this->getMock('Zend\InputFilter\InputFilterInterface');
+ $inputFilter->method('getRawValues')
+ ->willReturn($getRawValues)
+ ;
+ $inputFilter->method('getValues')
+ ->willReturn($getValues)
+ ;
+ if (($isValid === false) || ($isValid === true)) {
+ $inputFilter->expects($this->once())
+ ->method('isValid')
+ ->willReturn($isValid)
+ ;
+ } else {
+ $inputFilter->expects($this->never())
+ ->method('isValid')
+ ;
+ }
+ $inputFilter->method('getMessages')
+ ->willReturn($getMessages)
+ ;
- $filter->setData(array('foo' => 'xyz'));
- $this->assertTrue($filter->isValid(), 'Missing input with fallback value should mark input filter as valid');
- $data = $filter->getValues();
- $this->assertArrayHasKey('bar', $data);
- $this->assertEquals($bar->getFallbackValue(), $data['bar']);
+ return $inputFilter;
}
/**
- * @group 10
+ * @param string $name
+ * @param bool $isRequired
+ * @param null|bool $isValid
+ * @param mixed $context
+ * @param mixed $getRawValue
+ * @param mixed $getValue
+ * @param string[] $getMessages
+ * @param bool $breakOnFailure
+ *
+ * @return MockObject|InputInterface
*/
- public function testEmptyRequiredValueWithFallbackShouldMarkInputValid()
- {
- $foo = new Input('foo');
- $foo->setRequired(true);
- $foo->setAllowEmpty(false);
-
- $bar = new Input('bar');
- $bar->setRequired(true);
- $bar->setFallbackValue('baz');
-
- $filter = new InputFilter();
- $filter->add($foo);
- $filter->add($bar);
+ public function createInputInterfaceMock(
+ $name,
+ $isRequired,
+ $isValid = null,
+ $context = null,
+ $getRawValue = null,
+ $getValue = null,
+ $getMessages = array(),
+ $breakOnFailure = false
+ ) {
+ /** @var InputInterface|MockObject $input */
+ $input = $this->getMock('Zend\InputFilter\InputInterface');
+ $input->method('getName')
+ ->willReturn($name)
+ ;
+ $input->method('isRequired')
+ ->willReturn($isRequired)
+ ;
+ $input->method('getRawValue')
+ ->willReturn($getRawValue)
+ ;
+ $input->method('getValue')
+ ->willReturn($getValue)
+ ;
+ $input->method('breakOnFailure')
+ ->willReturn($breakOnFailure)
+ ;
+ if (($isValid === false) || ($isValid === true)) {
+ $input->expects($this->once())
+ ->method('isValid')
+ ->with($context)
+ ->willReturn($isValid)
+ ;
+ } else {
+ $input->expects($this->never())
+ ->method('isValid')
+ ->with($context)
+ ;
+ }
+ $input->method('getMessages')
+ ->willReturn($getMessages)
+ ;
- $filter->setData(array(
- 'foo' => 'xyz',
- 'bar' => null,
- ));
- $this->assertTrue($filter->isValid(), 'Empty input with fallback value should mark input filter as valid');
- $data = $filter->getValues();
- $this->assertArrayHasKey('bar', $data);
- $this->assertEquals($bar->getFallbackValue(), $data['bar']);
+ return $input;
}
/**
- * @group 15
+ * @return callable[]
*/
- public function testAllowsValidatingArrayAccessData()
+ protected function dataTypes()
{
- $filter = new InputFilter();
- $foo = new Input();
- $foo->getFilterChain()->attachByName('stringtrim')
- ->attachByName('alpha');
- $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6));
- $filter->add($foo, 'foo');
-
- $data = new ArrayObject(array('foo' => ' valid '));
- $filter->setData($data);
- $this->assertTrue($filter->isValid());
+ $self = $this;
+ return array(
+ // Description => callable
+ 'array' => function ($data) {
+ return $data;
+ },
+ 'Traversable' => function ($data) use ($self) {
+ return $self->getMockBuilder('FilterIterator')
+ ->setConstructorArgs(array(new ArrayIterator($data)))
+ ->getMock()
+ ;
+ },
+ );
}
}
diff --git a/test/CollectionInputFilterTest.php b/test/CollectionInputFilterTest.php
index 39156959..ee91a9f3 100644
--- a/test/CollectionInputFilterTest.php
+++ b/test/CollectionInputFilterTest.php
@@ -9,145 +9,80 @@
namespace ZendTest\InputFilter;
+use ArrayIterator;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
use PHPUnit_Framework_TestCase as TestCase;
+use stdClass;
use Zend\InputFilter\BaseInputFilter;
use Zend\InputFilter\CollectionInputFilter;
use Zend\InputFilter\Input;
use Zend\InputFilter\InputFilter;
-use Zend\Validator;
+/**
+ * @covers Zend\InputFilter\CollectionInputFilter
+ */
class CollectionInputFilterTest extends TestCase
{
/**
- * @var \Zend\InputFilter\CollectionInputFilter
+ * @var CollectionInputFilter
*/
- protected $filter;
+ protected $inputFilter;
public function setUp()
{
- $this->filter = new CollectionInputFilter();
- }
-
- public function getBaseInputFilter()
- {
- $filter = new BaseInputFilter();
-
- $foo = new Input();
- $foo->getFilterChain()->attachByName('stringtrim')
- ->attachByName('alpha');
- $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6));
-
- $bar = new Input();
- $bar->getFilterChain()->attachByName('stringtrim');
- $bar->getValidatorChain()->attach(new Validator\Digits());
-
- $baz = new Input();
- $baz->setRequired(false);
- $baz->getFilterChain()->attachByName('stringtrim');
- $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6));
-
- $filter->add($foo, 'foo')
- ->add($bar, 'bar')
- ->add($baz, 'baz')
- ->add($this->getChildInputFilter(), 'nest');
-
- return $filter;
+ $this->inputFilter = new CollectionInputFilter();
}
- public function getChildInputFilter()
+ public function testSetInputFilterWithInvalidTypeThrowsInvalidArgumentException()
{
- $filter = new BaseInputFilter();
-
- $foo = new Input();
- $foo->getFilterChain()->attachByName('stringtrim')
- ->attachByName('alpha');
- $foo->getValidatorChain()->attach(new Validator\StringLength(3, 6));
-
- $bar = new Input();
- $bar->getFilterChain()->attachByName('stringtrim');
- $bar->getValidatorChain()->attach(new Validator\Digits());
-
- $baz = new Input();
- $baz->setRequired(false);
- $baz->getFilterChain()->attachByName('stringtrim');
- $baz->getValidatorChain()->attach(new Validator\StringLength(1, 6));
-
- $filter->add($foo, 'foo')
- ->add($bar, 'bar')
- ->add($baz, 'baz');
- return $filter;
- }
+ $inputFilter = $this->inputFilter;
- public function getValidCollectionData()
- {
- return array(
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- ),
- ),
- array(
- 'foo' => ' batbaz ',
- 'bar' => '54321',
- 'baz' => '',
- 'nest' => array(
- 'foo' => ' batbaz ',
- 'bar' => '54321',
- 'baz' => '',
- ),
- )
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'expects an instance of Zend\InputFilter\BaseInputFilter; received "stdClass"'
);
+ /** @noinspection PhpParamsInspection */
+ $inputFilter->setInputFilter(new stdClass());
}
- public function testSetInputFilter()
- {
- $this->filter->setInputFilter(new BaseInputFilter());
- $this->assertInstanceOf('Zend\InputFilter\BaseInputFilter', $this->filter->getInputFilter());
- }
- public function testGetDefaultInputFilter()
+ /**
+ * @dataProvider inputFilterProvider
+ */
+ public function testSetInputFilter($inputFilter, $expectedType)
{
- $this->assertInstanceOf('Zend\InputFilter\BaseInputFilter', $this->filter->getInputFilter());
- }
+ $this->inputFilter->setInputFilter($inputFilter);
- public function testSetCount()
- {
- $this->filter->setCount(5);
- $this->assertEquals(5, $this->filter->getCount());
+ $this->assertInstanceOf($expectedType, $this->inputFilter->getInputFilter(), 'getInputFilter() type not match');
}
- public function testSetCountBelowZero()
+ public function testGetDefaultInputFilter()
{
- $this->filter->setCount(-1);
- $this->assertEquals(0, $this->filter->getCount());
+ $this->assertInstanceOf('Zend\InputFilter\BaseInputFilter', $this->inputFilter->getInputFilter());
}
- public function testGetCountUsesCountOfCollectionDataWhenNotSet()
+ /**
+ * @dataProvider isRequiredProvider
+ */
+ public function testSetRequired($value)
{
- $collectionData = array(
- array('foo' => 'bar'),
- array('foo' => 'baz')
- );
-
- $this->filter->setData($collectionData);
- $this->assertEquals(2, $this->filter->getCount());
+ $this->inputFilter->setIsRequired($value);
+ $this->assertEquals($value, $this->inputFilter->getIsRequired());
}
- public function testGetCountUsesSpecifiedCount()
+ /**
+ * @dataProvider countVsDataProvider
+ */
+ public function testSetCount($count, $data, $expectedCount)
{
- $collectionData = array(
- array('foo' => 'bar'),
- array('foo' => 'baz')
- );
+ if ($count !== null) {
+ $this->inputFilter->setCount($count);
+ }
+ if ($data !== null) {
+ $this->inputFilter->setData($data);
+ }
- $this->filter->setCount(3);
- $this->filter->setData($collectionData);
- $this->assertEquals(3, $this->filter->getCount());
+ $this->assertEquals($expectedCount, $this->inputFilter->getCount(), 'getCount() value not match');
}
/**
@@ -157,546 +92,140 @@ public function testGetCountReturnsRightCountOnConsecutiveCallsWithDifferentData
{
$collectionData1 = array(
array('foo' => 'bar'),
- array('foo' => 'baz')
+ array('foo' => 'baz'),
);
$collectionData2 = array(
- array('foo' => 'bar')
- );
-
- $this->filter->setData($collectionData1);
- $this->assertEquals(2, $this->filter->getCount());
- $this->filter->setData($collectionData2);
- $this->assertEquals(1, $this->filter->getCount());
- }
-
- public function testCanValidateValidData()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($this->getValidCollectionData());
- $this->assertTrue($this->filter->isValid());
- }
-
- public function testCanValidateValidDataWithNonConsecutiveKeys()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $collectionData = $this->getValidCollectionData();
- $collectionData[2] = $collectionData[0];
- unset($collectionData[0]);
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($collectionData);
- $this->assertTrue($this->filter->isValid());
- }
-
- public function testInvalidDataReturnsFalse()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $invalidCollectionData = array(
- array(
- 'foo' => ' bazbatlong ',
- 'bar' => '12345',
- 'baz' => '',
- ),
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- )
+ array('foo' => 'bar'),
);
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($invalidCollectionData);
- $this->assertFalse($this->filter->isValid());
+ $this->inputFilter->setData($collectionData1);
+ $this->assertEquals(2, $this->inputFilter->getCount());
+ $this->inputFilter->setData($collectionData2);
+ $this->assertEquals(1, $this->inputFilter->getCount());
}
- public function testDataLessThanCountIsInvalid()
+ public function testInvalidCollectionIsNotValid()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $invalidCollectionData = array(
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- ),
- ),
- );
+ $data = 1;
+ $this->inputFilter->setData($data);
- $this->filter->setCount(2);
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($invalidCollectionData);
- $this->assertFalse($this->filter->isValid());
+ $this->assertFalse($this->inputFilter->isValid());
}
- public function testGetValues()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
+ /**
+ * @dataProvider dataVsValidProvider
+ */
+ public function testDataVsValid(
+ $required,
+ $count,
+ $data,
+ $inputFilter,
+ $expectedRaw,
+ $expecteValues,
+ $expectedValid,
+ $expectedMessages
+ ) {
+ $this->inputFilter->setInputFilter($inputFilter);
+ $this->inputFilter->setData($data);
+ if ($count !== null) {
+ $this->inputFilter->setCount($count);
}
+ $this->inputFilter->setIsRequired($required);
- $expectedData = array(
- array(
- 'foo' => 'bazbat',
- 'bar' => '12345',
- 'baz' => '',
- 'nest' => array(
- 'foo' => 'bazbat',
- 'bar' => '12345',
- 'baz' => '',
- ),
- ),
- array(
- 'foo' => 'batbaz',
- 'bar' => '54321',
- 'baz' => '',
- 'nest' => array(
- 'foo' => 'batbaz',
- 'bar' => '54321',
- 'baz' => '',
- ),
- )
+ $this->assertEquals(
+ $expectedValid,
+ $this->inputFilter->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->inputFilter->getMessages())
);
-
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($this->getValidCollectionData());
-
- $this->assertTrue($this->filter->isValid());
- $this->assertEquals($expectedData, $this->filter->getValues());
-
- $this->assertCount(2, $this->filter->getValidInput());
- foreach ($this->filter->getValidInput() as $validInputs) {
- $this->assertCount(4, $validInputs);
- }
+ $this->assertEquals($expectedRaw, $this->inputFilter->getRawValues(), 'getRawValues() value not match');
+ $this->assertEquals($expecteValues, $this->inputFilter->getValues(), 'getValues() value not match');
+ $this->assertEquals($expectedMessages, $this->inputFilter->getMessages(), 'getMessages() value not match');
}
- public function testGetRawValues()
+ public function dataVsValidProvider()
{
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $expectedData = array(
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- ),
- ),
- array(
- 'foo' => ' batbaz ',
- 'bar' => '54321',
- 'baz' => '',
- 'nest' => array(
- 'foo' => ' batbaz ',
- 'bar' => '54321',
- 'baz' => '',
- ),
- )
+ $dataRaw = array(
+ 'fooInput' => 'fooRaw',
);
-
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($this->getValidCollectionData());
-
- $this->assertTrue($this->filter->isValid());
- $this->assertEquals($expectedData, $this->filter->getRawValues());
- }
-
- public function testGetMessagesForInvalidInputs()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $invalidCollectionData = array(
- array(
- 'foo' => ' bazbattoolong ',
- 'bar' => '12345',
- 'baz' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- ),
- ),
- array(
- 'foo' => ' bazbat ',
- 'bar' => 'notstring',
- 'baz' => '',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- ),
- ),
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- 'nest' => array(
- // missing 'foo' here
- 'bar' => '12345',
- 'baz' => '',
- ),
- ),
+ $dataFiltered = array(
+ 'fooInput' => 'fooFiltered',
);
-
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($invalidCollectionData);
-
- $this->assertFalse($this->filter->isValid());
-
- $this->assertCount(3, $this->filter->getInvalidInput());
- foreach ($this->filter->getInvalidInput() as $invalidInputs) {
- $this->assertCount(1, $invalidInputs);
- }
-
- $messages = $this->filter->getMessages();
-
- $this->assertCount(3, $messages);
- $this->assertArrayHasKey('foo', $messages[0]);
- $this->assertArrayHasKey('bar', $messages[1]);
- $this->assertArrayHasKey('nest', $messages[2]);
-
- $this->assertCount(1, $messages[0]['foo']);
- $this->assertCount(1, $messages[1]['bar']);
- $this->assertCount(1, $messages[2]['nest']);
- }
-
- public function testSetValidationGroupUsingFormStyle()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- // forms set an array of identical validation groups for each set of data
- $formValidationGroup = array(
- array(
- 'foo',
- 'bar',
- ),
- array(
- 'foo',
- 'bar',
- ),
- array(
- 'foo',
- 'bar',
- )
+ $colRaw = array($dataRaw);
+ $colFiltered = array($dataFiltered);
+ $errorMessage = array(
+ 'fooInput' => 'fooError',
);
-
- $data = array(
- array(
- 'foo' => ' bazbat ',
- 'bar' => '12345'
- ),
- array(
- 'foo' => ' batbaz ',
- 'bar' => '54321'
- ),
- array(
- 'foo' => ' batbaz ',
- 'bar' => '54321'
- )
+ $colMessages = array($errorMessage);
+
+ $self = $this;
+ $invalidIF = function () use ($dataRaw, $dataFiltered, $errorMessage, $self) {
+ return $self->createBaseInputFilterMock(false, $dataRaw, $dataFiltered, $errorMessage);
+ };
+ $validIF = function () use ($dataRaw, $dataFiltered, $self) {
+ return $self->createBaseInputFilterMock(true, $dataRaw, $dataFiltered);
+ };
+ $isRequired = true;
+
+ // @codingStandardsIgnoreStart
+ $dataSets = array(
+ // Description => [$required, $count, $data, $inputFilter, $expectedRaw, $expecteValues, $expectedValid, $expectedMessages]
+ 'Required: T, Count: N, Valid: T' => array( $isRequired, null, $colRaw, $validIF , $colRaw, $colFiltered, true , array()),
+ 'Required: T, Count: N, Valid: F' => array( $isRequired, null, $colRaw, $invalidIF, $colRaw, $colFiltered, false, $colMessages),
+ 'Required: T, Count: +1, Valid: F' => array( $isRequired, 2, $colRaw, $invalidIF, $colRaw, $colFiltered, false, $colMessages),
+ 'Required: F, Count: N, Valid: T' => array(!$isRequired, null, $colRaw, $validIF , $colRaw, $colFiltered, true , array()),
+ 'Required: F, Count: N, Valid: F' => array(!$isRequired, null, $colRaw, $invalidIF, $colRaw, $colFiltered, false, $colMessages),
+ 'Required: F, Count: +1, Valid: F' => array(!$isRequired, 2, $colRaw, $invalidIF, $colRaw, $colFiltered, false, $colMessages),
+ 'Required: T, Data: array(), Valid: X' => array( $isRequired, null, array(), $invalidIF, array(), array(), false, array()),
+ 'Required: F, Data: array(), Valid: X' => array(!$isRequired, null, array(), $invalidIF, array(), array(), true , array()),
);
-
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($data);
- $this->filter->setValidationGroup($formValidationGroup);
-
- $this->assertTrue($this->filter->isValid());
- }
-
- public function testEmptyCollectionIsValidByDefault()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $data = array();
-
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($data);
-
- $this->assertTrue($this->filter->isValid());
- }
-
- public function testEmptyCollectionIsNotValidIfRequired()
- {
- if (!extension_loaded('intl')) {
- $this->markTestSkipped('ext/intl not enabled');
- }
-
- $data = array();
-
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($data);
- $this->filter->setIsRequired(true);
-
- $this->assertFalse($this->filter->isValid());
- }
-
- public function testSetRequired()
- {
- $this->filter->setIsRequired(true);
- $this->assertEquals(true, $this->filter->getIsRequired());
- }
-
- public function testNonRequiredFieldsAreValidated()
- {
- $invalidCollectionData = array(
- array(
- 'foo' => ' bazbattoolong ',
- 'bar' => '12345',
- 'baz' => 'baztoolong',
- 'nest' => array(
- 'foo' => ' bazbat ',
- 'bar' => '12345',
- 'baz' => '',
- ),
- )
+ // @codingStandardsIgnoreEnd
+
+ array_walk(
+ $dataSets,
+ function (&$set) {
+ // Create unique mock input instances for each set
+ $inputFilter = $set[3]();
+ $set[3] = $inputFilter;
+ }
);
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($invalidCollectionData);
-
- $this->assertFalse($this->filter->isValid());
- $this->assertCount(2, current($this->filter->getInvalidInput()));
- $this->assertArrayHasKey('baz', current($this->filter->getMessages()));
+ return $dataSets;
}
- public function testNestedCollectionWithEmptyChild()
+ public function testSetValidationGroupUsingFormStyle()
{
- $items_inputfilter = new BaseInputFilter();
- $items_inputfilter->add(new Input(), 'id')
- ->add(new Input(), 'type');
- $items = new CollectionInputFilter();
- $items->setInputFilter($items_inputfilter);
-
- $groups_inputfilter = new BaseInputFilter();
- $groups_inputfilter->add(new Input(), 'group_class')
- ->add($items, 'items');
- $groups = new CollectionInputFilter();
- $groups->setInputFilter($groups_inputfilter);
-
- $inputFilter = new BaseInputFilter();
- $inputFilter->add($groups, 'groups');
-
- $preFilterdata = array(
- 'groups' => array(
- array(
- 'group_class' => 'bar',
- 'items' => array(
- array(
- 'id' => 100,
- 'type' => 'item-1',
- ),
- ),
- ),
- array(
- 'group_class' => 'bar',
- 'items' => array(
- array(
- 'id' => 200,
- 'type' => 'item-2',
- ),
- array(
- 'id' => 300,
- 'type' => 'item-3',
- ),
- array(
- 'id' => 400,
- 'type' => 'item-4',
- ),
- ),
- ),
- array(
- 'group_class' => 'biz',
- ),
- ),
+ $validationGroup = array(
+ 'fooGroup',
);
+ $colValidationGroup = array($validationGroup);
- $postFilterdata = array(
- 'groups' => array(
- array(
- 'group_class' => 'bar',
- 'items' => array(
- array(
- 'id' => 100,
- 'type' => 'item-1',
- ),
- ),
- ),
- array(
- 'group_class' => 'bar',
- 'items' => array(
- array(
- 'id' => 200,
- 'type' => 'item-2',
- ),
- array(
- 'id' => 300,
- 'type' => 'item-3',
- ),
- array(
- 'id' => 400,
- 'type' => 'item-4',
- ),
- ),
- ),
- array(
- 'group_class' => 'biz',
- 'items' => array(),
- ),
- ),
+ $dataRaw = array(
+ 'fooInput' => 'fooRaw',
);
- $inputFilter->setData($preFilterdata);
- $inputFilter->isValid();
- $values = $inputFilter->getValues();
- $this->assertEquals($postFilterdata, $values);
- }
-
- public function testNestedCollectionWithEmptyData()
- {
- $items_inputfilter = new BaseInputFilter();
- $items_inputfilter->add(new Input(), 'id')
- ->add(new Input(), 'type');
- $items = new CollectionInputFilter();
- $items->setInputFilter($items_inputfilter);
-
- $groups_inputfilter = new BaseInputFilter();
- $groups_inputfilter->add(new Input(), 'group_class')
- ->add($items, 'items');
- $groups = new CollectionInputFilter();
- $groups->setInputFilter($groups_inputfilter);
-
- $inputFilter = new BaseInputFilter();
- $inputFilter->add($groups, 'groups');
-
- $data = array(
- 'groups' => array(
- array(
- 'group_class' => 'bar',
- 'items' => array(
- array(
- 'id' => 100,
- 'type' => 'item-1',
- ),
- ),
- ),
- array(
- 'group_class' => 'biz',
- 'items' => array(),
- ),
- array(
- 'group_class' => 'bar',
- 'items' => array(
- array(
- 'id' => 200,
- 'type' => 'item-2',
- ),
- array(
- 'id' => 300,
- 'type' => 'item-3',
- ),
- array(
- 'id' => 400,
- 'type' => 'item-4',
- ),
- ),
- ),
- ),
+ $dataFiltered = array(
+ 'fooInput' => 'fooFiltered',
);
-
- $inputFilter->setData($data);
- $inputFilter->isValid();
- $values = $inputFilter->getValues();
- $this->assertEquals($data, $values);
- }
-
- /**
- * @group 6472
- */
- public function testNestedCollectionWhereChildDataIsNotOverwritten()
- {
- $items_inputfilter = new BaseInputFilter();
- $items_inputfilter->add(new Input(), 'id')
- ->add(new Input(), 'type');
- $items = new CollectionInputFilter();
- $items->setInputFilter($items_inputfilter);
-
- $groups_inputfilter = new BaseInputFilter();
- $groups_inputfilter->add(new Input(), 'group_class')
- ->add($items, 'items');
- $groups = new CollectionInputFilter();
- $groups->setInputFilter($groups_inputfilter);
-
- $inputFilter = new BaseInputFilter();
- $inputFilter->add($groups, 'groups');
-
- $data = array(
- 'groups' => array(
- array(
- 'group_class' => 'bar',
- 'items' => array(
- array(
- 'id' => 100,
- 'type' => 'item-100',
- ),
- array(
- 'id' => 101,
- 'type' => 'item-101',
- ),
- array(
- 'id' => 102,
- 'type' => 'item-102',
- ),
- array(
- 'id' => 103,
- 'type' => 'item-103',
- ),
- ),
- ),
- array(
- 'group_class' => 'foo',
- 'items' => array(
- array(
- 'id' => 200,
- 'type' => 'item-200',
- ),
- array(
- 'id' => 201,
- 'type' => 'item-201',
- ),
- ),
- ),
- ),
+ $colRaw = array($dataRaw);
+ $colFiltered = array($dataFiltered);
+ $baseInputFilter = $this->createBaseInputFilterMock(true, $dataRaw, $dataFiltered);
+ $baseInputFilter->expects($this->once())
+ ->method('setValidationGroup')
+ ->with($validationGroup)
+ ;
+
+ $this->inputFilter->setInputFilter($baseInputFilter);
+ $this->inputFilter->setData($colRaw);
+ $this->inputFilter->setValidationGroup($colValidationGroup);
+
+ $this->assertTrue(
+ $this->inputFilter->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->inputFilter->getMessages())
);
-
- $inputFilter->setData($data);
- $inputFilter->isValid();
- $values = $inputFilter->getValues();
- $this->assertEquals($data, $values);
+ $this->assertEquals($colRaw, $this->inputFilter->getRawValues(), 'getRawValues() value not match');
+ $this->assertEquals($colFiltered, $this->inputFilter->getValues(), 'getValues() value not match');
+ $this->assertEquals(array(), $this->inputFilter->getMessages(), 'getMessages() value not match');
}
public function dataNestingCollection()
@@ -704,20 +233,24 @@ public function dataNestingCollection()
return array(
'count not specified' => array(
'count' => null,
- 'isValid' => true
+ 'isValid' => true,
+ ),
+ 'count=0' => array(
+ 'count' => 0,
+ 'isValid' => true,
),
'count = 1' => array(
'count' => 1,
- 'isValid' => true
+ 'isValid' => true,
),
'count = 2' => array(
'count' => 2,
- 'isValid' => false
+ 'isValid' => false,
),
'count = 3' => array(
'count' => 3,
- 'isValid' => false
- )
+ 'isValid' => false,
+ ),
);
}
@@ -751,34 +284,116 @@ public function testNestingCollectionCountCached($count, $expectedIsValid)
array(
'second_collection' => array(
array(
- 'input' => 'some value'
+ 'input' => 'some value',
),
array(
- 'input' => 'some value'
- )
- )
+ 'input' => 'some value',
+ ),
+ ),
),
array(
'second_collection' => array(
array(
- 'input' => 'some value'
+ 'input' => 'some value',
),
- )
- )
- )
+ ),
+ ),
+ ),
);
$mainInputFilter->setData($data);
$this->assertSame($expectedIsValid, $mainInputFilter->isValid());
}
- public function testInvalidCollectionIsNotValid()
+ public function inputFilterProvider()
{
- $data = 1;
+ $baseInputFilter = new BaseInputFilter();
+
+ $inputFilterSpecificationAsArray = array();
+ $inputSpecificationAsTraversable = new ArrayIterator($inputFilterSpecificationAsArray);
- $this->filter->setInputFilter($this->getBaseInputFilter());
- $this->filter->setData($data);
+ $inputFilterSpecificationResult = new InputFilter();
+ $inputFilterSpecificationResult->getFactory()->getInputFilterManager();
+
+ $dataSets = array(
+ // Description => [inputFilter, $expectedType]
+ 'BaseInputFilter' => array($baseInputFilter, 'Zend\InputFilter\BaseInputFilter'),
+ 'array' => array($inputFilterSpecificationAsArray, 'Zend\InputFilter\InputFilter'),
+ 'Traversable' => array($inputSpecificationAsTraversable, 'Zend\InputFilter\InputFilter'),
+ );
+
+ return $dataSets;
+ }
+
+ public function countVsDataProvider()
+ {
+ $data0 = array();
+ $data1 = array('A' => 'a');
+ $data2 = array('A' => 'a', 'B' => 'b');
+
+ // @codingStandardsIgnoreStart
+ return array(
+ // Description => [$count, $data, $expectedCount]
+ 'C: -1, D: null' => array( -1, null , 0),
+ 'C: 0, D: null' => array( 0, null , 0),
+ 'C: 1, D: null' => array( 1, null , 1),
+ 'C: null, D: 0' => array(null, $data0, 0),
+ 'C: null, D: 1' => array(null, $data1, 1),
+ 'C: null, D: 2' => array(null, $data2, 2),
+ 'C: -1, D: 0' => array( -1, $data0, 0),
+ 'C: 0, D: 0' => array( 0, $data0, 0),
+ 'C: 1, D: 0' => array( 1, $data0, 1),
+ 'C: -1, D: 1' => array( -1, $data1, 0),
+ 'C: 0, D: 1' => array( 0, $data1, 0),
+ 'C: 1, D: 1' => array( 1, $data1, 1),
+ );
+ // @codingStandardsIgnoreEnd
+ }
+
+ public function isRequiredProvider()
+ {
+ return array(
+ 'enabled' => array(true),
+ 'disabled' => array(false),
+ );
+ }
+
+ /**
+ * @param null|bool $isValid
+ * @param mixed[] $getRawValues
+ * @param mixed[] $getValues
+ * @param string[] $getMessages
+ *
+ * @return MockObject|BaseInputFilter
+ */
+ public function createBaseInputFilterMock(
+ $isValid = null,
+ $getRawValues = array(),
+ $getValues = array(),
+ $getMessages = array()
+ ) {
+ /** @var BaseInputFilter|MockObject $inputFilter */
+ $inputFilter = $this->getMock('Zend\InputFilter\BaseInputFilter');
+ $inputFilter->method('getRawValues')
+ ->willReturn($getRawValues)
+ ;
+ $inputFilter->method('getValues')
+ ->willReturn($getValues)
+ ;
+ if (($isValid === false) || ($isValid === true)) {
+ $inputFilter->expects($this->once())
+ ->method('isValid')
+ ->willReturn($isValid)
+ ;
+ } else {
+ $inputFilter->expects($this->never())
+ ->method('isValid')
+ ;
+ }
+ $inputFilter->method('getMessages')
+ ->willReturn($getMessages)
+ ;
- $this->assertFalse($this->filter->isValid());
+ return $inputFilter;
}
}
diff --git a/test/FactoryTest.php b/test/FactoryTest.php
index 72f0427a..4ff44d9a 100644
--- a/test/FactoryTest.php
+++ b/test/FactoryTest.php
@@ -9,32 +9,261 @@
namespace ZendTest\InputFilter;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
use PHPUnit_Framework_TestCase as TestCase;
use Zend\Filter;
+use Zend\InputFilter\CollectionInputFilter;
use Zend\InputFilter\Factory;
use Zend\InputFilter\Input;
use Zend\InputFilter\InputFilter;
-use Zend\Validator;
use Zend\InputFilter\InputFilterPluginManager;
+use Zend\InputFilter\InputFilterProviderInterface;
+use Zend\InputFilter\InputProviderInterface;
use Zend\ServiceManager;
+use Zend\Validator;
+/**
+ * @covers Zend\InputFilter\Factory
+ */
class FactoryTest extends TestCase
{
+ public function testCreateInputWithInvalidDataTypeThrowsInvalidArgumentException()
+ {
+ $factory = $this->createDefaultFactory();
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'expects an array or Traversable; received "string"'
+ );
+ /** @noinspection PhpParamsInspection */
+ $factory->createInput('invalid_value');
+ }
+
+ public function testCreateInputWithTypeAsAnUnknownPluginAndNotExistsAsClassNameThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+ $type = 'foo';
+
+ /** @var InputFilterPluginManager|MockObject $pluginManager */
+ $pluginManager = $this->getMock('Zend\InputFilter\InputFilterPluginManager');
+ $pluginManager->expects($this->atLeastOnce())
+ ->method('has')
+ ->with($type)
+ ->willReturn(false)
+ ;
+ $factory->setInputFilterManager($pluginManager);
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'Input factory expects the "type" to be a valid class or a plugin name; received "foo"'
+ );
+ $factory->createInput(
+ array(
+ 'type' => $type,
+ )
+ );
+ }
+
+ public function testCreateInputWithTypeAsAnInvalidPluginInstanceThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+ $type = 'fooPlugin';
+ $pluginManager = $this->createInputFilterPluginManagerMockForPlugin($type, 'invalid_value');
+
+ $factory->setInputFilterManager($pluginManager);
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'Input factory expects the "type" to be a class implementing Zend\InputFilter\InputInterface; '
+ . 'received "fooPlugin"'
+ );
+ $factory->createInput(
+ array(
+ 'type' => $type,
+ )
+ );
+ }
+
+ public function testCreateInputWithTypeAsAnInvalidClassInstanceThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+ $type = 'stdClass';
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'Input factory expects the "type" to be a class implementing Zend\InputFilter\InputInterface; ' .
+ 'received "stdClass"'
+ );
+ $factory->createInput(
+ array(
+ 'type' => $type,
+ )
+ );
+ }
+
+ public function testCreateInputWithFiltersAsAnInvalidTypeThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'expects the value associated with "filters" to be an array/Traversable of filters or filter specifications,' .
+ ' or a FilterChain; received "string"'
+ );
+ $factory->createInput(
+ array(
+ 'filters' => 'invalid_value',
+ )
+ );
+ }
+
+ public function testCreateInputWithFiltersAsAnSpecificationWithMissingNameThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'Invalid filter specification provided; does not include "name" key'
+ );
+ $factory->createInput(
+ array(
+ 'filters' => array(
+ array(
+ // empty
+ )
+ ),
+ )
+ );
+ }
+
+ public function testCreateInputWithFiltersAsAnCollectionOfInvalidTypesThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'Invalid filter specification provided; was neither a filter instance nor an array specification'
+ );
+ $factory->createInput(
+ array(
+ 'filters' => array(
+ 'invalid value'
+ ),
+ )
+ );
+ }
+
+ public function testCreateInputWithValidatorsAsAnInvalidTypeThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'expects the value associated with "validators" to be an array/Traversable of validators or validator ' .
+ 'specifications, or a ValidatorChain; received "string"'
+ );
+ $factory->createInput(
+ array(
+ 'validators' => 'invalid_value',
+ )
+ );
+ }
+
+ public function testCreateInputWithValidatorsAsAnSpecificationWithMissingNameThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'Invalid validator specification provided; does not include "name" key'
+ );
+ $factory->createInput(
+ array(
+ 'validators' => array(
+ array(
+ // empty
+ )
+ ),
+ )
+ );
+ }
+
+ public function inputTypeSpecificationProvider()
+ {
+ return array(
+ // Description => [$specificationKey]
+ 'continue_if_empty' => array('continue_if_empty'),
+ 'fallback_value' => array('fallback_value'),
+ );
+ }
+
+ /**
+ * @dataProvider inputTypeSpecificationProvider
+ */
+ public function testCreateInputWithSpecificInputTypeSettingsThrowException($specificationKey)
+ {
+ $factory = $this->createDefaultFactory();
+ $type = 'pluginInputInterface';
+
+ $pluginManager = $this->createInputFilterPluginManagerMockForPlugin($type, $this->getMock('Zend\InputFilter\InputInterface'));
+ $factory->setInputFilterManager($pluginManager);
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ sprintf('"%s" can only set to inputs of type "Zend\InputFilter\Input"', $specificationKey)
+ );
+ $factory->createInput(
+ array(
+ 'type' => $type,
+ $specificationKey => true,
+ )
+ );
+ }
+
+ public function testCreateInputWithValidatorsAsAnCollectionOfInvalidTypesThrowException()
+ {
+ $factory = $this->createDefaultFactory();
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'Invalid validator specification provided; was neither a validator instance nor an array specification'
+ );
+ $factory->createInput(
+ array(
+ 'validators' => array(
+ 'invalid value'
+ ),
+ )
+ );
+ }
+
+ public function testCreateInputFilterWithInvalidDataTypeThrowsInvalidArgumentException()
+ {
+ $factory = $this->createDefaultFactory();
+
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\InvalidArgumentException',
+ 'expects an array or Traversable; received "string"'
+ );
+ /** @noinspection PhpParamsInspection */
+ $factory->createInputFilter('invalid_value');
+ }
+
public function testFactoryComposesFilterChainByDefault()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$this->assertInstanceOf('Zend\Filter\FilterChain', $factory->getDefaultFilterChain());
}
public function testFactoryComposesValidatorChainByDefault()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$this->assertInstanceOf('Zend\Validator\ValidatorChain', $factory->getDefaultValidatorChain());
}
public function testFactoryAllowsInjectingFilterChain()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$filterChain = new Filter\FilterChain();
$factory->setDefaultFilterChain($filterChain);
$this->assertSame($filterChain, $factory->getDefaultFilterChain());
@@ -42,7 +271,7 @@ public function testFactoryAllowsInjectingFilterChain()
public function testFactoryAllowsInjectingValidatorChain()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$validatorChain = new Validator\ValidatorChain();
$factory->setDefaultValidatorChain($validatorChain);
$this->assertSame($validatorChain, $factory->getDefaultValidatorChain());
@@ -50,7 +279,7 @@ public function testFactoryAllowsInjectingValidatorChain()
public function testFactoryUsesComposedFilterChainWhenCreatingNewInputObjects()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$filterChain = new Filter\FilterChain();
$pluginManager = new Filter\FilterPluginManager();
$filterChain->setPluginManager($pluginManager);
@@ -66,7 +295,7 @@ public function testFactoryUsesComposedFilterChainWhenCreatingNewInputObjects()
public function testFactoryUsesComposedValidatorChainWhenCreatingNewInputObjects()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$validatorChain = new Validator\ValidatorChain();
$validatorPlugins = new Validator\ValidatorPluginManager();
$validatorChain->setPluginManager($validatorPlugins);
@@ -82,7 +311,7 @@ public function testFactoryUsesComposedValidatorChainWhenCreatingNewInputObjects
public function testFactoryInjectsComposedFilterAndValidatorChainsIntoInputObjectsWhenCreatingNewInputFilterObjects()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$filterPlugins = new Filter\FilterPluginManager();
$validatorPlugins = new Validator\ValidatorPluginManager();
$filterChain = new Filter\FilterChain();
@@ -107,9 +336,12 @@ public function testFactoryInjectsComposedFilterAndValidatorChainsIntoInputObjec
$this->assertSame($validatorPlugins, $inputValidatorChain->getPluginManager());
}
+ /**
+ * @requires extension mbstring
+ */
public function testFactoryWillCreateInputWithSuggestedFilters()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$htmlEntities = new Filter\HtmlEntities();
$input = $factory->createInput(array(
'name' => 'foo',
@@ -151,7 +383,7 @@ public function testFactoryWillCreateInputWithSuggestedFilters()
public function testFactoryWillCreateInputWithSuggestedValidators()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$digits = new Validator\Digits();
$input = $factory->createInput(array(
'name' => 'foo',
@@ -195,7 +427,7 @@ public function testFactoryWillCreateInputWithSuggestedValidators()
public function testFactoryWillCreateInputWithSuggestedRequiredFlagAndAlternativeAllowEmptyFlag()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = $factory->createInput(array(
'name' => 'foo',
'required' => false,
@@ -208,7 +440,7 @@ public function testFactoryWillCreateInputWithSuggestedRequiredFlagAndAlternativ
public function testFactoryWillCreateInputWithSuggestedAllowEmptyFlagAndImpliesRequiredFlag()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = $factory->createInput(array(
'name' => 'foo',
'allow_empty' => true,
@@ -220,7 +452,7 @@ public function testFactoryWillCreateInputWithSuggestedAllowEmptyFlagAndImpliesR
public function testFactoryWillCreateInputWithSuggestedName()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = $factory->createInput(array(
'name' => 'foo',
));
@@ -230,7 +462,7 @@ public function testFactoryWillCreateInputWithSuggestedName()
public function testFactoryWillCreateInputWithContinueIfEmptyFlag()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = $factory->createInput(array(
'name' => 'foo',
'continue_if_empty' => true,
@@ -241,7 +473,7 @@ public function testFactoryWillCreateInputWithContinueIfEmptyFlag()
public function testFactoryAcceptsInputInterface()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = new Input();
$inputFilter = $factory->createInputFilter(array(
@@ -255,7 +487,7 @@ public function testFactoryAcceptsInputInterface()
public function testFactoryAcceptsInputFilterInterface()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = new InputFilter();
$inputFilter = $factory->createInputFilter(array(
@@ -269,7 +501,7 @@ public function testFactoryAcceptsInputFilterInterface()
public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfiguration()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$inputFilter = $factory->createInputFilter(array(
'foo' => array(
'name' => 'foo',
@@ -385,7 +617,7 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi
public function testFactoryWillCreateInputFilterMatchingInputNameWhenNotSpecified()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$inputFilter = $factory->createInputFilter(array(
array('name' => 'foo')
));
@@ -396,7 +628,7 @@ public function testFactoryWillCreateInputFilterMatchingInputNameWhenNotSpecifie
public function testFactoryAllowsPassingValidatorChainsInInputSpec()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$chain = new Validator\ValidatorChain();
$input = $factory->createInput(array(
'name' => 'foo',
@@ -409,7 +641,7 @@ public function testFactoryAllowsPassingValidatorChainsInInputSpec()
public function testFactoryAllowsPassingFilterChainsInInputSpec()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$chain = new Filter\FilterChain();
$input = $factory->createInput(array(
'name' => 'foo',
@@ -422,8 +654,9 @@ public function testFactoryAllowsPassingFilterChainsInInputSpec()
public function testFactoryAcceptsCollectionInputFilter()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
+ /** @var CollectionInputFilter $inputFilter */
$inputFilter = $factory->createInputFilter(array(
'type' => 'Zend\InputFilter\CollectionInputFilter',
'required' => true,
@@ -439,7 +672,7 @@ public function testFactoryAcceptsCollectionInputFilter()
public function testFactoryWillCreateInputWithErrorMessage()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = $factory->createInput(array(
'name' => 'foo',
'error_message' => 'My custom error message',
@@ -447,20 +680,23 @@ public function testFactoryWillCreateInputWithErrorMessage()
$this->assertEquals('My custom error message', $input->getErrorMessage());
}
+ /**
+ * @requires extension mbstring
+ */
public function testFactoryWillNotGetPrioritySetting()
{
//Reminder: Priority at which to enqueue filter; defaults to 1000 (higher executes earlier)
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = $factory->createInput(array(
'name' => 'foo',
'filters' => array(
array(
'name' => 'string_trim',
- 'priority' => \Zend\Filter\FilterChain::DEFAULT_PRIORITY - 1 // 999
+ 'priority' => Filter\FilterChain::DEFAULT_PRIORITY - 1 // 999
),
array(
'name' => 'string_to_upper',
- 'priority' => \Zend\Filter\FilterChain::DEFAULT_PRIORITY + 1 //1001
+ 'priority' => Filter\FilterChain::DEFAULT_PRIORITY + 1 //1001
),
array(
'name' => 'string_to_lower', // default priority 1000
@@ -492,7 +728,7 @@ public function testFactoryWillNotGetPrioritySetting()
public function testConflictNameWithInputFilterType()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$inputFilter = $factory->createInputFilter(
array(
@@ -509,6 +745,7 @@ public function testConflictNameWithInputFilterType()
public function testCustomFactoryInCollection()
{
$factory = new TestAsset\CustomFactory();
+ /** @var CollectionInputFilter $inputFilter */
$inputFilter = $factory->createInputFilter(array(
'type' => 'collection',
'input_filter' => new InputFilter(),
@@ -521,7 +758,7 @@ public function testCustomFactoryInCollection()
*/
public function testCanSetInputErrorMessage()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = $factory->createInput(array(
'name' => 'test',
'type' => 'Zend\InputFilter\Input',
@@ -537,7 +774,7 @@ public function testSetInputFilterManagerWithServiceManager()
$serviceManager->setService('ValidatorManager', new Validator\ValidatorPluginManager);
$serviceManager->setService('FilterManager', new Filter\FilterPluginManager);
$inputFilterManager->setServiceLocator($serviceManager);
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$factory->setInputFilterManager($inputFilterManager);
$this->assertInstanceOf(
'Zend\Validator\ValidatorPluginManager',
@@ -552,7 +789,7 @@ public function testSetInputFilterManagerWithServiceManager()
public function testSetInputFilterManagerWithoutServiceManager()
{
$inputFilterManager = new InputFilterPluginManager();
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$factory->setInputFilterManager($inputFilterManager);
$this->assertSame($inputFilterManager, $factory->getInputFilterManager());
}
@@ -571,7 +808,7 @@ public function testSetInputFilterManagerOnConstruct()
*/
public function testSetsBreakChainOnFailure()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$this->assertTrue($factory->createInput(array('break_on_failure' => true))->breakOnFailure());
@@ -580,7 +817,7 @@ public function testSetsBreakChainOnFailure()
public function testCanCreateInputFilterWithNullInputs()
{
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$inputFilter = $factory->createInputFilter(array(
'foo' => array(
@@ -604,7 +841,7 @@ public function testCanCreateInputFilterWithNullInputs()
*/
public function testCanCreateInputFromProvider()
{
- /* @group $provider \Zend\InputFilter\InputProviderInterface|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var InputProviderInterface|MockObject $provider */
$provider = $this->getMock('Zend\InputFilter\InputProviderInterface', array('getInputSpecification'));
$provider
@@ -612,7 +849,7 @@ public function testCanCreateInputFromProvider()
->method('getInputSpecification')
->will($this->returnValue(array('name' => 'foo')));
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$input = $factory->createInput($provider);
$this->assertInstanceOf('Zend\InputFilter\InputInterface', $input);
@@ -623,7 +860,7 @@ public function testCanCreateInputFromProvider()
*/
public function testCanCreateInputFilterFromProvider()
{
- /* @group $provider \Zend\InputFilter\InputFilterProviderInterface|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var InputFilterProviderInterface|MockObject $provider */
$provider = $this->getMock(
'Zend\InputFilter\InputFilterProviderInterface',
array('getInputFilterSpecification')
@@ -642,9 +879,72 @@ public function testCanCreateInputFilterFromProvider()
),
)));
- $factory = new Factory();
+ $factory = $this->createDefaultFactory();
$inputFilter = $factory->createInputFilter($provider);
$this->assertInstanceOf('Zend\InputFilter\InputFilterInterface', $inputFilter);
}
+
+ public function testSuggestedTypeMayBePluginNameInInputFilterPluginManager()
+ {
+ $factory = $this->createDefaultFactory();
+ $pluginManager = new InputFilterPluginManager();
+ $pluginManager->setService('bar', new Input('bar'));
+ $factory->setInputFilterManager($pluginManager);
+
+ $input = $factory->createInput(array(
+ 'type' => 'bar'
+ ));
+ $this->assertSame('bar', $input->getName());
+ }
+
+ public function testInputFromPluginManagerMayBeFurtherConfiguredWithSpec()
+ {
+ $factory = $this->createDefaultFactory();
+ $pluginManager = new InputFilterPluginManager();
+ $pluginManager->setService('bar', $barInput = new Input('bar'));
+ $this->assertTrue($barInput->isRequired());
+ $factory->setInputFilterManager($pluginManager);
+
+ $input = $factory->createInput(array(
+ 'type' => 'bar',
+ 'required' => false
+ ));
+
+ $this->assertFalse($input->isRequired());
+ $this->assertSame('bar', $input->getName());
+ }
+
+ /**
+ * @return Factory
+ */
+ protected function createDefaultFactory()
+ {
+ $factory = new Factory();
+
+ return $factory;
+ }
+
+ /**
+ * @param string $pluginName
+ * @param mixed $pluginValue
+ *
+ * @return MockObject|InputFilterPluginManager
+ */
+ protected function createInputFilterPluginManagerMockForPlugin($pluginName, $pluginValue)
+ {
+ /** @var InputFilterPluginManager|MockObject $pluginManager */
+ $pluginManager = $this->getMock('Zend\InputFilter\InputFilterPluginManager');
+ $pluginManager->expects($this->atLeastOnce())
+ ->method('has')
+ ->with($pluginName)
+ ->willReturn(true)
+ ;
+ $pluginManager->expects($this->atLeastOnce())
+ ->method('get')
+ ->with($pluginName)
+ ->willReturn($pluginValue)
+ ;
+ return $pluginManager;
+ }
}
diff --git a/test/FileInputTest.php b/test/FileInputTest.php
index 27888b4c..73e654ef 100644
--- a/test/FileInputTest.php
+++ b/test/FileInputTest.php
@@ -9,12 +9,19 @@
namespace ZendTest\InputFilter;
-use Zend\InputFilter\FileInput;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
use Zend\Filter;
+use Zend\InputFilter\FileInput;
use Zend\Validator;
+/**
+ * @covers Zend\InputFilter\FileInput
+ */
class FileInputTest extends InputTest
{
+ /** @var FileInput */
+ protected $input;
+
public function setUp()
{
$this->input = new FileInput('foo');
@@ -22,13 +29,6 @@ public function setUp()
$this->input->setAutoPrependUploadValidator(false);
}
- public function testValueMayBeInjected()
- {
- $value = array('tmp_name' => 'bar');
- $this->input->setValue($value);
- $this->assertEquals($value, $this->input->getValue());
- }
-
public function testRetrievingValueFiltersTheValue()
{
$this->markTestSkipped('Test are not enabled in FileInputTest');
@@ -40,6 +40,7 @@ public function testRetrievingValueFiltersTheValueOnlyAfterValidating()
$this->input->setValue($value);
$newValue = array('tmp_name' => 'foo');
+ /** @var Filter\File\Rename|MockObject $filterMock */
$filterMock = $this->getMockBuilder('Zend\Filter\File\Rename')
->disableOriginalConstructor()
->getMock();
@@ -57,7 +58,10 @@ function ($value) use ($filterMock) {
);
$this->assertEquals($value, $this->input->getValue());
- $this->assertTrue($this->input->isValid());
+ $this->assertTrue(
+ $this->input->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages())
+ );
$this->assertEquals($newValue, $this->input->getValue());
}
@@ -71,6 +75,7 @@ public function testCanFilterArrayOfMultiFileData()
$this->input->setValue($values);
$newValue = array('tmp_name' => 'new');
+ /** @var Filter\File\Rename|MockObject $filterMock */
$filterMock = $this->getMockBuilder('Zend\Filter\File\Rename')
->disableOriginalConstructor()
->getMock();
@@ -88,7 +93,10 @@ function ($value) use ($filterMock) {
);
$this->assertEquals($values, $this->input->getValue());
- $this->assertTrue($this->input->isValid());
+ $this->assertTrue(
+ $this->input->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages())
+ );
$this->assertEquals(
array($newValue, $newValue, $newValue),
$this->input->getValue()
@@ -104,22 +112,6 @@ public function testCanRetrieveRawValue()
$this->assertEquals($value, $this->input->getRawValue());
}
- public function testIsValidReturnsFalseIfValidationChainFails()
- {
- $this->input->setValue(array('tmp_name' => 'bar'));
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertFalse($this->input->isValid());
- }
-
- public function testIsValidReturnsTrueIfValidationChainSucceeds()
- {
- $this->input->setValue(array('tmp_name' => 'bar'));
- $validator = new Validator\NotEmpty();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertTrue($this->input->isValid());
- }
-
public function testValidationOperatesOnFilteredValue()
{
$this->markTestSkipped('Test is not enabled in FileInputTest');
@@ -136,6 +128,7 @@ public function testValidationOperatesBeforeFiltering()
$this->input->setValue($badValue);
$filteredValue = array('tmp_name' => 'new');
+ /** @var Filter\File\Rename|MockObject $filterMock */
$filterMock = $this->getMockBuilder('Zend\Filter\File\Rename')
->disableOriginalConstructor()
->getMock();
@@ -164,7 +157,10 @@ function ($value) use ($filterMock) {
'error' => 0,
);
$this->input->setValue($goodValue);
- $this->assertTrue($this->input->isValid());
+ $this->assertTrue(
+ $this->input->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages())
+ );
$this->assertEquals($filteredValue, $this->input->getValue());
}
@@ -201,7 +197,10 @@ public function testCanValidateArrayOfMultiFileData()
$this->input->setValue($values);
$validator = new Validator\File\Exists();
$this->input->getValidatorChain()->attach($validator);
- $this->assertTrue($this->input->isValid());
+ $this->assertTrue(
+ $this->input->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages())
+ );
// Negative test
$values[1]['tmp_name'] = 'file-not-found';
@@ -209,18 +208,6 @@ public function testCanValidateArrayOfMultiFileData()
$this->assertFalse($this->input->isValid());
}
- public function testSpecifyingMessagesToInputReturnsThoseOnFailedValidation()
- {
- $this->input->setValue(array('tmp_name' => 'bar'));
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->input->setErrorMessage('Please enter only digits');
- $this->assertFalse($this->input->isValid());
- $messages = $this->input->getMessages();
- $this->assertArrayNotHasKey(Validator\Digits::NOT_DIGITS, $messages);
- $this->assertContains('Please enter only digits', $messages);
- }
-
public function testAutoPrependUploadValidatorIsOnByDefault()
{
$input = new FileInput('foo');
@@ -255,7 +242,10 @@ public function testUploadValidatorIsNotAddedWhenIsValidIsCalled()
$validatorChain = $this->input->getValidatorChain();
$this->assertEquals(0, count($validatorChain->getValidators()));
- $this->assertTrue($this->input->isValid());
+ $this->assertTrue(
+ $this->input->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages())
+ );
$this->assertEquals(0, count($validatorChain->getValidators()));
}
@@ -266,6 +256,7 @@ public function testRequiredUploadValidatorValidatorNotAddedWhenOneExists()
$this->assertTrue($this->input->isRequired());
$this->input->setValue(array('tmp_name' => 'bar'));
+ /** @var Validator\File\UploadFile|MockObject $uploadMock */
$uploadMock = $this->getMock('Zend\Validator\File\UploadFile', array('isValid'));
$uploadMock->expects($this->exactly(1))
->method('isValid')
@@ -273,7 +264,10 @@ public function testRequiredUploadValidatorValidatorNotAddedWhenOneExists()
$validatorChain = $this->input->getValidatorChain();
$validatorChain->prependValidator($uploadMock);
- $this->assertTrue($this->input->isValid());
+ $this->assertTrue(
+ $this->input->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages())
+ );
$validators = $validatorChain->getValidators();
$this->assertEquals(1, count($validators));
@@ -287,6 +281,7 @@ public function testValidationsRunWithoutFileArrayDueToAjaxPost()
$this->assertTrue($this->input->isRequired());
$this->input->setValue('');
+ /** @var Validator\File\UploadFile|MockObject $uploadMock */
$uploadMock = $this->getMock('Zend\Validator\File\UploadFile', array('isValid'));
$uploadMock->expects($this->exactly(1))
->method('isValid')
@@ -301,48 +296,31 @@ public function testValidationsRunWithoutFileArrayDueToAjaxPost()
$this->assertEquals($uploadMock, $validators[0]['instance']);
}
- public function testNotEmptyValidatorAddedWhenIsValidIsCalled()
+ public function testNotEmptyValidatorAddedWhenIsValidIsCalled($value = null)
{
$this->markTestSkipped('Test is not enabled in FileInputTest');
}
- public function testRequiredNotEmptyValidatorNotAddedWhenOneExists()
+ public function testRequiredNotEmptyValidatorNotAddedWhenOneExists($value = null)
{
$this->markTestSkipped('Test is not enabled in FileInputTest');
}
- public function testMerge()
- {
- $value = array('tmp_name' => 'bar');
-
- $input = new FileInput('foo');
- $input->setAutoPrependUploadValidator(false);
- $input->setValue($value);
- $filter = new Filter\StringTrim();
- $input->getFilterChain()->attach($filter);
- $validator = new Validator\Digits();
- $input->getValidatorChain()->attach($validator);
-
- $input2 = new FileInput('bar');
- $input2->merge($input);
- $validatorChain = $input->getValidatorChain();
- $filterChain = $input->getFilterChain();
-
- $this->assertFalse($input2->getAutoPrependUploadValidator());
- $this->assertEquals($value, $input2->getRawValue());
- $this->assertEquals(1, $validatorChain->count());
- $this->assertEquals(1, $filterChain->count());
-
- $validators = $validatorChain->getValidators();
- $this->assertInstanceOf('Zend\Validator\Digits', $validators[0]['instance']);
-
- $filters = $filterChain->getFilters()->toArray();
- $this->assertInstanceOf('Zend\Filter\StringTrim', $filters[0]);
+ public function testFallbackValueVsIsValidRules(
+ $required = null,
+ $fallbackValue = null,
+ $originalValue = null,
+ $isValid = null,
+ $expectedValue = null
+ ) {
+ $this->markTestSkipped('Input::setFallbackValue is not implemented on FileInput');
}
- public function testFallbackValue($fallbackValue = null)
- {
- $this->markTestSkipped('Not use fallback value');
+ public function testFallbackValueVsIsValidRulesWhenValueNotSet(
+ $required = null,
+ $fallbackValue = null
+ ) {
+ $this->markTestSkipped('Input::setFallbackValue is not implemented on FileInput');
}
public function testIsEmptyFileNotArray()
@@ -393,58 +371,100 @@ public function testIsEmptyFileMultiFileOk()
$this->assertFalse($this->input->isEmptyFile($rawValue));
}
- public function emptyValuesProvider()
+ /**
+ * Specific FileInput::merge extras
+ */
+ public function testFileInputMerge()
{
- // Provide empty values specific for file input
- return array(
- array('file'),
- array(array(
- 'tmp_name' => '',
- 'error' => \UPLOAD_ERR_NO_FILE,
- )),
- array(array(array(
- 'tmp_name' => 'foo',
- 'error' => \UPLOAD_ERR_NO_FILE
- ))),
+ $source = new FileInput();
+ $source->setAutoPrependUploadValidator(true);
+
+ $target = $this->input;
+ $target->setAutoPrependUploadValidator(false);
+
+ $return = $target->merge($source);
+ $this->assertSame($target, $return, 'merge() must return it self');
+
+ $this->assertEquals(
+ true,
+ $target->getAutoPrependUploadValidator(),
+ 'getAutoPrependUploadValidator() value not match'
);
}
- /**
- * @dataProvider emptyValuesProvider
- */
- public function testAllowEmptyOptionSet($emptyValue)
+ public function isRequiredVsAllowEmptyVsContinueIfEmptyVsIsValidProvider()
{
- // UploadFile validator is disabled, pretend one
- $validator = new Validator\Callback(function () {
- return false; // This should never be called
- });
- $this->input->getValidatorChain()->attach($validator);
- parent::testAllowEmptyOptionSet($emptyValue);
+ $dataSets = parent::isRequiredVsAllowEmptyVsContinueIfEmptyVsIsValidProvider();
+
+ // FileInput do not use NotEmpty validator so the only validator present in the chain is the custom one.
+ unset($dataSets['Required: T; AEmpty: F; CIEmpty: F; Validator: X, Value: Empty / tmp_name']);
+ unset($dataSets['Required: T; AEmpty: F; CIEmpty: F; Validator: X, Value: Empty / single']);
+ unset($dataSets['Required: T; AEmpty: F; CIEmpty: F; Validator: X, Value: Empty / multi']);
+
+ return $dataSets;
}
- /**
- * @dataProvider emptyValuesProvider
- */
- public function testAllowEmptyOptionNotSet($emptyValue)
+ public function emptyValueProvider()
{
- // UploadFile validator is disabled, pretend one
- $message = 'pretend failing UploadFile validator';
- $validator = new Validator\Callback(function () {
- return false;
- });
- $validator->setMessage($message);
- $this->input->getValidatorChain()->attach($validator);
- parent::testAllowEmptyOptionNotSet($emptyValue);
- $this->assertEquals(array('callbackValue' => $message), $this->input->getMessages());
+ return array(
+ 'tmp_name' => array(
+ 'raw' => 'file',
+ 'filtered' => array(
+ 'tmp_name' => 'file',
+ 'name' => 'file',
+ 'size' => 0,
+ 'type' => '',
+ 'error' => UPLOAD_ERR_NO_FILE,
+ ),
+ ),
+ 'single' => array(
+ 'raw' => array(
+ 'tmp_name' => '',
+ 'error' => UPLOAD_ERR_NO_FILE,
+ ),
+ 'filtered' => array(
+ 'tmp_name' => '',
+ 'error' => UPLOAD_ERR_NO_FILE,
+ ),
+ ),
+ 'multi' => array(
+ 'raw' => array(
+ array(
+ 'tmp_name' => 'foo',
+ 'error' => UPLOAD_ERR_NO_FILE,
+ ),
+ ),
+ 'filtered' => array(
+ 'tmp_name' => 'foo',
+ 'error' => UPLOAD_ERR_NO_FILE,
+ ),
+ ),
+ );
}
- public function testNotAllowEmptyWithFilterConvertsNonemptyToEmptyIsNotValid()
+ public function mixedValueProvider()
{
- $this->markTestSkipped('does not apply to FileInput');
+ $fooUploadErrOk = array(
+ 'tmp_name' => 'foo',
+ 'error' => UPLOAD_ERR_OK,
+ );
+
+ return array(
+ 'single' => array(
+ 'raw' => $fooUploadErrOk,
+ 'filtered' => $fooUploadErrOk,
+ ),
+ 'multi' => array(
+ 'raw' => array(
+ $fooUploadErrOk,
+ ),
+ 'filtered' => $fooUploadErrOk,
+ ),
+ );
}
- public function testNotAllowEmptyWithFilterConvertsEmptyToNonEmptyIsValid()
+ public function getDummyValue($raw = true)
{
- $this->markTestSkipped('does not apply to FileInput');
+ return array('tmp_name' => 'bar');
}
}
diff --git a/test/InputFilterAbstractServiceFactoryTest.php b/test/InputFilterAbstractServiceFactoryTest.php
index 0646044d..9cc2c55d 100644
--- a/test/InputFilterAbstractServiceFactoryTest.php
+++ b/test/InputFilterAbstractServiceFactoryTest.php
@@ -9,15 +9,29 @@
namespace ZendTest\InputFilter;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
use PHPUnit_Framework_TestCase as TestCase;
use Zend\Filter\FilterPluginManager;
+use Zend\InputFilter\InputFilterAbstractServiceFactory;
use Zend\InputFilter\InputFilterPluginManager;
use Zend\ServiceManager\ServiceManager;
+use Zend\Validator\ValidatorInterface;
use Zend\Validator\ValidatorPluginManager;
-use Zend\InputFilter\InputFilterAbstractServiceFactory;
+/**
+ * @covers Zend\InputFilter\InputFilterAbstractServiceFactory
+ */
class InputFilterAbstractServiceFactoryTest extends TestCase
{
+ /** @var ServiceManager */
+ protected $services;
+
+ /** @var InputFilterPluginManager */
+ protected $filters;
+
+ /** @var InputFilterAbstractServiceFactory */
+ protected $factory;
+
public function setUp()
{
$this->services = new ServiceManager();
@@ -79,6 +93,7 @@ public function testUsesConfiguredValidationAndFilterManagerServicesWhenCreating
$filters->setService('foo', $filter);
$validators = new ValidatorPluginManager();
+ /** @var ValidatorInterface|MockObject $validator */
$validator = $this->getMock('Zend\Validator\ValidatorInterface');
$validators->setService('foo', $validator);
@@ -127,6 +142,7 @@ public function testRetrieveInputFilterFromInputFilterPluginManager()
$filters->setService('foo', $filter);
$validators = new ValidatorPluginManager();
+ /** @var ValidatorInterface|MockObject $validator */
$validator = $this->getMock('Zend\Validator\ValidatorInterface');
$validators->setService('foo', $validator);
diff --git a/test/InputFilterAwareTraitTest.php b/test/InputFilterAwareTraitTest.php
index d4cc35e1..25dc945d 100644
--- a/test/InputFilterAwareTraitTest.php
+++ b/test/InputFilterAwareTraitTest.php
@@ -14,6 +14,7 @@
/**
* @requires PHP 5.4
+ * @covers Zend\InputFilter\InputFilterAwareTrait
*/
class InputFilterAwareTraitTest extends TestCase
{
diff --git a/test/InputFilterManagerTest.php b/test/InputFilterManagerTest.php
deleted file mode 100644
index a602e534..00000000
--- a/test/InputFilterManagerTest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-manager = new InputFilterPluginManager();
- }
-
- public function testRegisteringInvalidElementRaisesException()
- {
- $this->setExpectedException('Zend\InputFilter\Exception\RuntimeException');
- $this->manager->setService('test', $this);
- }
-
- public function testLoadingInvalidElementRaisesException()
- {
- $this->manager->setInvokableClass('test', get_class($this));
- $this->setExpectedException('Zend\InputFilter\Exception\RuntimeException');
- $this->manager->get('test');
- }
-
- /**
- * @covers Zend\InputFilter\InputFilterPluginManager::validatePlugin
- */
- public function testAllowLoadingInstancesOfInputFilterInterface()
- {
- $inputFilter = $this->getMock('Zend\InputFilter\InputFilterInterface');
-
- $this->assertNull($this->manager->validatePlugin($inputFilter));
- }
-
- /**
- * @covers Zend\InputFilter\InputFilterPluginManager::validatePlugin
- */
- public function testAllowLoadingInstancesOfInputInterface()
- {
- $input = $this->getMock('Zend\InputFilter\InputInterface');
-
- $this->assertNull($this->manager->validatePlugin($input));
- }
-}
diff --git a/test/InputFilterPluginManagerTest.php b/test/InputFilterPluginManagerTest.php
new file mode 100644
index 00000000..996e5c36
--- /dev/null
+++ b/test/InputFilterPluginManagerTest.php
@@ -0,0 +1,208 @@
+manager = new InputFilterPluginManager();
+ }
+
+ public function testIsASubclassOfAbstractPluginManager()
+ {
+ $this->assertInstanceOf('Zend\ServiceManager\AbstractPluginManager', $this->manager);
+ }
+
+ public function testIsNotSharedByDefault()
+ {
+ $this->assertFalse($this->manager->shareByDefault());
+ }
+
+ public function testRegisteringInvalidElementRaisesException()
+ {
+ $this->setExpectedException(
+ 'Zend\InputFilter\Exception\RuntimeException',
+ 'must implement Zend\InputFilter\InputFilterInterface or Zend\InputFilter\InputInterface'
+ );
+ $this->manager->setService('test', $this);
+ }
+
+ public function testLoadingInvalidElementRaisesException()
+ {
+ $this->manager->setInvokableClass('test', get_class($this));
+ $this->setExpectedException('Zend\InputFilter\Exception\RuntimeException');
+ $this->manager->get('test');
+ }
+
+ public function defaultInvokableClassesProvider()
+ {
+ return array(
+ // Description => [$alias, $expectedInstance]
+ 'inputfilter' => array('inputfilter', 'Zend\InputFilter\InputFilter'),
+ 'collection' => array('collection', 'Zend\InputFilter\CollectionInputFilter'),
+ );
+ }
+
+ /**
+ * @dataProvider defaultInvokableClassesProvider
+ */
+ public function testDefaultInvokableClasses($alias, $expectedInstance)
+ {
+ $service = $this->manager->get($alias);
+
+ $this->assertInstanceOf($expectedInstance, $service, 'get() return type not match');
+ }
+
+ public function testInputFilterInvokableClassSMDependenciesArePopulatedWithoutServiceLocator()
+ {
+ $this->assertNull($this->manager->getServiceLocator(), 'Plugin manager is expected to no have a service locator');
+
+ /** @var InputFilter $service */
+ $service = $this->manager->get('inputfilter');
+
+ $factory = $service->getFactory();
+ $this->assertSame(
+ $this->manager,
+ $factory->getInputFilterManager(),
+ 'Factory::getInputFilterManager() is not populated with the expected plugin manager'
+ );
+ }
+
+ public function testInputFilterInvokableClassSMDependenciesArePopulatedWithServiceLocator()
+ {
+ $filterManager = $this->getMock('Zend\Filter\FilterPluginManager');
+ $validatorManager = $this->getMock('Zend\Validator\ValidatorPluginManager');
+
+ $serviceLocator = $this->createServiceLocatorInterfaceMock();
+ $serviceLocator->method('get')
+ ->willReturnMap(
+ array(
+ array('FilterManager', $filterManager),
+ array('ValidatorManager', $validatorManager),
+ )
+ )
+ ;
+
+ $this->manager->setServiceLocator($serviceLocator);
+ $this->assertSame($serviceLocator, $this->manager->getServiceLocator(), 'getServiceLocator() value not match');
+
+ /** @var InputFilter $service */
+ $service = $this->manager->get('inputfilter');
+
+ $factory = $service->getFactory();
+ $this->assertSame(
+ $this->manager,
+ $factory->getInputFilterManager(),
+ 'Factory::getInputFilterManager() is not populated with the expected plugin manager'
+ );
+
+ $defaultFilterChain = $factory->getDefaultFilterChain();
+ $this->assertSame(
+ $filterManager,
+ $defaultFilterChain->getPluginManager(),
+ 'Factory::getDefaultFilterChain() is not populated with the expected plugin manager'
+ );
+
+ $defaultValidatorChain = $factory->getDefaultValidatorChain();
+ $this->assertSame(
+ $validatorManager,
+ $defaultValidatorChain->getPluginManager(),
+ 'Factory::getDefaultValidatorChain() is not populated with the expected plugin manager'
+ );
+ }
+
+ public function serviceProvider()
+ {
+ $inputFilterInterfaceMock = $this->createInputFilterInterfaceMock();
+ $inputInterfaceMock = $this->createInputInterfaceMock();
+
+ // @formatter:off
+ return array(
+ // Description => [$serviceName, $service, $instanceOf]
+ 'InputFilterInterface' => array('inputFilterInterfaceService', $inputFilterInterfaceMock, 'Zend\InputFilter\InputFilterInterface'),
+ 'InputInterface' => array('inputInterfaceService', $inputInterfaceMock, 'Zend\InputFilter\InputInterface'),
+ );
+ // @formatter:on
+ }
+
+ /**
+ * @dataProvider serviceProvider
+ */
+ public function testGet($serviceName, $service)
+ {
+ $this->manager->setService($serviceName, $service);
+
+ $this->assertSame($service, $this->manager->get($serviceName), 'get() value not match');
+ }
+
+ /**
+ * @dataProvider serviceProvider
+ */
+ public function testServicesAreInitiatedIfImplementsInitializableInterface($serviceName, $service, $instanceOf)
+ {
+ $initializableProphecy = $this->prophesize($instanceOf)->willImplement('Zend\Stdlib\InitializableInterface');
+ $service = $initializableProphecy->reveal();
+
+ $this->manager->setService($serviceName, $service);
+ $this->assertSame($service, $this->manager->get($serviceName), 'get() value not match');
+
+ /** @noinspection PhpUndefinedMethodInspection */
+ $initializableProphecy->init()->shouldBeCalled();
+ }
+
+ /**
+ * @return MockObject|InputFilterInterface
+ */
+ protected function createInputFilterInterfaceMock()
+ {
+ /** @var InputFilterInterface|MockObject $inputFilter */
+ $inputFilter = $this->getMock('Zend\InputFilter\InputFilterInterface');
+
+ return $inputFilter;
+ }
+
+ /**
+ * @return MockObject|InputInterface
+ */
+ protected function createInputInterfaceMock()
+ {
+ /** @var InputInterface|MockObject $input */
+ $input = $this->getMock('Zend\InputFilter\InputInterface');
+
+ return $input;
+ }
+
+ /**
+ * @return MockObject|ServiceLocatorInterface
+ */
+ protected function createServiceLocatorInterfaceMock()
+ {
+ /** @var ServiceLocatorInterface|MockObject $serviceLocator */
+ $serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface');
+
+ return $serviceLocator;
+ }
+}
diff --git a/test/InputFilterTest.php b/test/InputFilterTest.php
index 99a16dec..6ee46229 100644
--- a/test/InputFilterTest.php
+++ b/test/InputFilterTest.php
@@ -9,110 +9,73 @@
namespace ZendTest\InputFilter;
-use PHPUnit_Framework_TestCase as TestCase;
-use Zend\Filter;
-use Zend\InputFilter\CollectionInputFilter;
+use ArrayIterator;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
use Zend\InputFilter\Factory;
use Zend\InputFilter\Input;
use Zend\InputFilter\InputFilter;
-class InputFilterTest extends TestCase
+/**
+ * @covers Zend\InputFilter\InputFilter
+ */
+class InputFilterTest extends BaseInputFilterTest
{
/**
* @var InputFilter
*/
- protected $filter;
+ protected $inputFilter;
public function setUp()
{
- $this->filter = new InputFilter();
+ $this->inputFilter = new InputFilter();
}
public function testLazilyComposesAFactoryByDefault()
{
- $factory = $this->filter->getFactory();
+ $factory = $this->inputFilter->getFactory();
$this->assertInstanceOf('Zend\InputFilter\Factory', $factory);
}
public function testCanComposeAFactory()
{
- $factory = new Factory();
- $this->filter->setFactory($factory);
- $this->assertSame($factory, $this->filter->getFactory());
+ $factory = $this->createFactoryMock();
+ $this->inputFilter->setFactory($factory);
+ $this->assertSame($factory, $this->inputFilter->getFactory());
}
- public function testCanAddUsingSpecification()
+ public function inputProvider()
{
- $this->filter->add(array(
- 'name' => 'foo',
- ));
- $this->assertTrue($this->filter->has('foo'));
- $foo = $this->filter->get('foo');
- $this->assertInstanceOf('Zend\InputFilter\InputInterface', $foo);
- }
+ $dataSets = parent::inputProvider();
- /**
- * @covers \Zend\InputFilter\BaseInputFilter::getValue
- *
- * @group 6028
- */
- public function testGetValueReturnsArrayIfNestedInputFilters()
- {
- $inputFilter = new InputFilter();
- $inputFilter->add(new Input(), 'name');
+ $inputSpecificationAsArray = array(
+ 'name' => 'inputFoo',
+ );
+ $inputSpecificationAsTraversable = new ArrayIterator($inputSpecificationAsArray);
- $this->filter->add($inputFilter, 'people');
+ $inputSpecificationResult = new Input('inputFoo');
+ $inputSpecificationResult->getFilterChain(); // Fill input with a default chain just for make the test pass
+ $inputSpecificationResult->getValidatorChain(); // Fill input with a default chain just for make the test pass
- $data = array(
- 'people' => array(
- 'name' => 'Wanderson'
- )
+ // @codingStandardsIgnoreStart
+ $inputFilterDataSets = array(
+ // Description => [input, expected name, $expectedReturnInput]
+ 'array' => array($inputSpecificationAsArray , 'inputFoo', $inputSpecificationResult),
+ 'Traversable' => array($inputSpecificationAsTraversable , 'inputFoo', $inputSpecificationResult),
);
+ // @codingStandardsIgnoreEnd
+ $dataSets = array_merge($dataSets, $inputFilterDataSets);
- $this->filter->setData($data);
- $this->assertTrue($this->filter->isValid());
-
- $this->assertInternalType('array', $this->filter->getValue('people'));
+ return $dataSets;
}
/**
- * @group ZF2-5648
+ * @return Factory|MockObject
*/
- public function testCountZeroValidateInternalInputWithCollectionInputFilter()
- {
- $inputFilter = new InputFilter();
- $inputFilter->add(new Input(), 'name');
-
- $collection = new CollectionInputFilter();
- $collection->setInputFilter($inputFilter);
- $collection->setCount(0);
-
- $this->filter->add($collection, 'people');
-
- $data = array(
- 'people' => array(
- array(
- 'name' => 'Wanderson',
- ),
- ),
- );
- $this->filter->setData($data);
-
- $this->assertTrue($this->filter->isvalid());
- $this->assertSame($data, $this->filter->getValues());
- }
-
- public function testCanUseContextPassedToInputFilter()
+ protected function createFactoryMock()
{
- $context = new \stdClass();
-
- $input = $this->getMock('Zend\InputFilter\InputInterface');
- $input->expects($this->once())->method('isValid')->with($context)->will($this->returnValue(true));
- $input->expects($this->any())->method('getRawValue')->will($this->returnValue('Mwop'));
-
- $this->filter->add($input, 'username');
- $this->filter->setData(array('username' => 'Mwop'));
+ /** @var Factory|MockObject $factory */
+ $factory = $this->getMock('Zend\InputFilter\Factory');
- $this->filter->isValid($context);
+ return $factory;
}
}
diff --git a/test/InputTest.php b/test/InputTest.php
index 9203912c..f21134c9 100644
--- a/test/InputTest.php
+++ b/test/InputTest.php
@@ -9,12 +9,19 @@
namespace ZendTest\InputFilter;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
use PHPUnit_Framework_TestCase as TestCase;
-use RuntimeException;
-use Zend\Filter;
+use stdClass;
+use Zend\Filter\FilterChain;
use Zend\InputFilter\Input;
-use Zend\Validator;
+use Zend\InputFilter\InputInterface;
+use Zend\Validator\NotEmpty as NotEmptyValidator;
+use Zend\Validator\ValidatorChain;
+use Zend\Validator\ValidatorInterface;
+/**
+ * @covers Zend\InputFilter\Input
+ */
class InputTest extends TestCase
{
/**
@@ -27,6 +34,21 @@ public function setUp()
$this->input = new Input('foo');
}
+ public function assertRequiredValidationErrorMessage(Input $input, $message = '')
+ {
+ $message = $message ?: 'Expected failure message for required input';
+ $message .= ';';
+
+ $messages = $input->getMessages();
+ $this->assertInternalType('array', $messages, $message . ' non-array messages array');
+
+ $notEmpty = new NotEmptyValidator();
+ $messageTemplates = $notEmpty->getOption('messageTemplates');
+ $this->assertSame(array(
+ NotEmptyValidator::IS_EMPTY => $messageTemplates[NotEmptyValidator::IS_EMPTY],
+ ), $messages, $message . ' missing NotEmpty::IS_EMPTY key and/or contains additional messages');
+ }
+
public function testConstructorRequiresAName()
{
$this->assertEquals('foo', $this->input->getName());
@@ -48,14 +70,14 @@ public function testInputHasEmptyValidatorChainByDefault()
public function testCanInjectFilterChain()
{
- $chain = new Filter\FilterChain();
+ $chain = $this->createFilterChainMock();
$this->input->setFilterChain($chain);
$this->assertSame($chain, $this->input->getFilterChain());
}
public function testCanInjectValidatorChain()
{
- $chain = new Validator\ValidatorChain();
+ $chain = $this->createValidatorChainMock();
$this->input->setValidatorChain($chain);
$this->assertSame($chain, $this->input->getValidatorChain());
}
@@ -84,101 +106,227 @@ public function testAllowEmptyFlagIsMutable()
public function testContinueIfEmptyFlagIsFalseByDefault()
{
- $input = new Input('foo');
+ $input = $this->input;
$this->assertFalse($input->continueIfEmpty());
}
public function testContinueIfEmptyFlagIsMutable()
{
- $input = new Input('foo');
+ $input = $this->input;
$input->setContinueIfEmpty(true);
$this->assertTrue($input->continueIfEmpty());
}
- public function testNotEmptyValidatorNotInjectedIfContinueIfEmptyIsTrue()
+ /**
+ * @dataProvider setValueProvider
+ */
+ public function testSetFallbackValue($fallbackValue)
+ {
+ $input = $this->input;
+
+ $return = $input->setFallbackValue($fallbackValue);
+ $this->assertSame($input, $return, 'setFallbackValue() must return it self');
+
+ $this->assertEquals($fallbackValue, $input->getFallbackValue(), 'getFallbackValue() value not match');
+ $this->assertEquals(true, $input->hasFallback(), 'hasFallback() value not match');
+ }
+
+ /**
+ * @dataProvider fallbackValueVsIsValidProvider
+ */
+ public function testFallbackValueVsIsValidRules($required, $fallbackValue, $originalValue, $isValid, $expectedValue)
+ {
+ $input = $this->input;
+ $input->setContinueIfEmpty(true);
+
+ $input->setRequired($required);
+ $input->setValidatorChain($this->createValidatorChainMock($isValid, $originalValue));
+ $input->setFallbackValue($fallbackValue);
+ $input->setValue($originalValue);
+
+ $this->assertTrue(
+ $input->isValid(),
+ 'isValid() should be return always true when fallback value is set. Detail: ' .
+ json_encode($input->getMessages())
+ );
+ $this->assertEquals(array(), $input->getMessages(), 'getMessages() should be empty because the input is valid');
+ $this->assertSame($expectedValue, $input->getRawValue(), 'getRawValue() value not match');
+ $this->assertSame($expectedValue, $input->getValue(), 'getValue() value not match');
+ }
+
+ /**
+ * @dataProvider fallbackValueVsIsValidProvider
+ */
+ public function testFallbackValueVsIsValidRulesWhenValueNotSet($required, $fallbackValue)
{
- $input = new Input('foo');
+ $expectedValue = $fallbackValue; // Should always return the fallback value
+
+ $input = $this->input;
$input->setContinueIfEmpty(true);
- $input->setValue('');
+
+ $input->setRequired($required);
+ $input->setValidatorChain($this->createValidatorChainMock(null));
+ $input->setFallbackValue($fallbackValue);
+
+ $this->assertTrue(
+ $input->isValid(),
+ 'isValid() should be return always true when fallback value is set. Detail: ' .
+ json_encode($input->getMessages())
+ );
+ $this->assertEquals(array(), $input->getMessages(), 'getMessages() should be empty because the input is valid');
+ $this->assertSame($expectedValue, $input->getRawValue(), 'getRawValue() value not match');
+ $this->assertSame($expectedValue, $input->getValue(), 'getValue() value not match');
+ }
+
+ public function testRequiredWithoutFallbackAndValueNotSetThenFail()
+ {
+ $input = $this->input;
+ $input->setRequired(true);
+
+ $this->assertFalse(
+ $input->isValid(),
+ 'isValid() should be return always false when no fallback value, is required, and not data is set.'
+ );
+ $this->assertRequiredValidationErrorMessage($input);
+ }
+
+ public function testRequiredWithoutFallbackAndValueNotSetThenFailReturnsCustomErrorMessageWhenSet()
+ {
+ $input = $this->input;
+ $input->setRequired(true);
+ $input->setErrorMessage('FAILED TO VALIDATE');
+
+ $this->assertFalse(
+ $input->isValid(),
+ 'isValid() should be return always false when no fallback value, is required, and not data is set.'
+ );
+ $this->assertSame(array('FAILED TO VALIDATE'), $input->getMessages());
+ }
+
+ /**
+ * @group 28
+ * @group 60
+ */
+ public function testRequiredWithoutFallbackAndValueNotSetProvidesNotEmptyValidatorIsEmptyErrorMessage()
+ {
+ $input = $this->input;
+ $input->setRequired(true);
+
+ $this->assertFalse(
+ $input->isValid(),
+ 'isValid() should always return false when no fallback value is present, '
+ . 'the input is required, and no data is set.'
+ );
+ $this->assertRequiredValidationErrorMessage($input);
+ }
+
+ /**
+ * @group 28
+ * @group 60
+ */
+ public function testRequiredWithoutFallbackAndValueNotSetProvidesCustomErrorMessageWhenSet()
+ {
+ $input = $this->input;
+ $input->setRequired(true);
+ $input->setErrorMessage('FAILED TO VALIDATE');
+
+ $this->assertFalse(
+ $input->isValid(),
+ 'isValid() should always return false when no fallback value is present, '
+ . 'the input is required, and no data is set.'
+ );
+ $this->assertSame(array('FAILED TO VALIDATE'), $input->getMessages());
+ }
+
+ public function testNotRequiredWithoutFallbackAndValueNotSetThenIsValid()
+ {
+ $input = $this->input;
+ $input->setRequired(false);
+ $input->setAllowEmpty(false);
+ $input->setContinueIfEmpty(true);
+
+ // Validator should not to be called
+ $input->getValidatorChain()
+ ->attach($this->createValidatorMock(null, null))
+ ;
+ $this->assertTrue(
+ $input->isValid(),
+ 'isValid() should be return always true when is not required, and no data is set. Detail: ' .
+ json_encode($input->getMessages())
+ );
+ $this->assertEquals(array(), $input->getMessages(), 'getMessages() should be empty because the input is valid');
+ }
+
+ /**
+ * @dataProvider emptyValueProvider
+ */
+ public function testNotEmptyValidatorNotInjectedIfContinueIfEmptyIsTrue($value)
+ {
+ $input = $this->input;
+ $input->setContinueIfEmpty(true);
+ $input->setValue($value);
$input->isValid();
$validators = $input->getValidatorChain()
->getValidators();
$this->assertEmpty($validators);
}
- public function testValueIsNullByDefault()
+ public function testDefaultGetValue()
{
$this->assertNull($this->input->getValue());
}
public function testValueMayBeInjected()
{
- $this->input->setValue('bar');
- $this->assertEquals('bar', $this->input->getValue());
+ $valueRaw = $this->getDummyValue();
+
+ $this->input->setValue($valueRaw);
+ $this->assertEquals($valueRaw, $this->input->getValue());
}
public function testRetrievingValueFiltersTheValue()
{
- $this->input->setValue('bar');
- $filter = new Filter\StringToUpper();
- $this->input->getFilterChain()->attach($filter);
- $this->assertEquals('BAR', $this->input->getValue());
+ $valueRaw = $this->getDummyValue();
+ $valueFiltered = $this->getDummyValue(false);
+
+ $filterChain = $this->createFilterChainMock($valueRaw, $valueFiltered);
+
+ $this->input->setFilterChain($filterChain);
+ $this->input->setValue($valueRaw);
+
+ $this->assertSame($valueFiltered, $this->input->getValue());
}
public function testCanRetrieveRawValue()
{
- $this->input->setValue('bar');
- $filter = new Filter\StringToUpper();
- $this->input->getFilterChain()->attach($filter);
- $this->assertEquals('bar', $this->input->getRawValue());
- }
+ $valueRaw = $this->getDummyValue();
- public function testIsValidReturnsFalseIfValidationChainFails()
- {
- $this->input->setValue('bar');
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertFalse($this->input->isValid());
- }
+ $filterChain = $this->createFilterChainMock();
- public function testIsValidReturnsTrueIfValidationChainSucceeds()
- {
- $this->input->setValue('123');
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertTrue($this->input->isValid());
+ $this->input->setFilterChain($filterChain);
+ $this->input->setValue($valueRaw);
+
+ $this->assertEquals($valueRaw, $this->input->getRawValue());
}
public function testValidationOperatesOnFilteredValue()
{
- $this->input->setValue(' 123 ');
- $filter = new Filter\StringTrim();
- $this->input->getFilterChain()->attach($filter);
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertTrue($this->input->isValid());
- }
+ $valueRaw = $this->getDummyValue();
+ $valueFiltered = $this->getDummyValue(false);
- public function testGetMessagesReturnsValidationMessages()
- {
- $this->input->setValue('bar');
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->assertFalse($this->input->isValid());
- $messages = $this->input->getMessages();
- $this->assertArrayHasKey(Validator\Digits::NOT_DIGITS, $messages);
- }
+ $filterChain = $this->createFilterChainMock($valueRaw, $valueFiltered);
- public function testSpecifyingMessagesToInputReturnsThoseOnFailedValidation()
- {
- $this->input->setValue('bar');
- $validator = new Validator\Digits();
- $this->input->getValidatorChain()->attach($validator);
- $this->input->setErrorMessage('Please enter only digits');
- $this->assertFalse($this->input->isValid());
- $messages = $this->input->getMessages();
- $this->assertArrayNotHasKey(Validator\Digits::NOT_DIGITS, $messages);
- $this->assertContains('Please enter only digits', $messages);
+ $validatorChain = $this->createValidatorChainMock(true, $valueFiltered);
+
+ $this->input->setAllowEmpty(true);
+ $this->input->setFilterChain($filterChain);
+ $this->input->setValidatorChain($validatorChain);
+ $this->input->setValue($valueRaw);
+
+ $this->assertTrue(
+ $this->input->isValid(),
+ 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages())
+ );
}
public function testBreakOnFailureFlagIsOffByDefault()
@@ -192,10 +340,13 @@ public function testBreakOnFailureFlagIsMutable()
$this->assertTrue($this->input->breakOnFailure());
}
- public function testNotEmptyValidatorAddedWhenIsValidIsCalled()
+ /**
+ * @dataProvider emptyValueProvider
+ */
+ public function testNotEmptyValidatorAddedWhenIsValidIsCalled($value)
{
$this->assertTrue($this->input->isRequired());
- $this->input->setValue('');
+ $this->input->setValue($value);
$validatorChain = $this->input->getValidatorChain();
$this->assertEquals(0, count($validatorChain->getValidators()));
@@ -209,15 +360,15 @@ public function testNotEmptyValidatorAddedWhenIsValidIsCalled()
$this->assertEquals(1, count($validatorChain->getValidators()));
}
- public function testRequiredNotEmptyValidatorNotAddedWhenOneExists()
+ /**
+ * @dataProvider emptyValueProvider
+ */
+ public function testRequiredNotEmptyValidatorNotAddedWhenOneExists($value)
{
- $this->assertTrue($this->input->isRequired());
- $this->input->setValue('');
+ $this->input->setRequired(true);
+ $this->input->setValue($value);
- $notEmptyMock = $this->getMock('Zend\Validator\NotEmpty', array('isValid'));
- $notEmptyMock->expects($this->exactly(1))
- ->method('isValid')
- ->will($this->returnValue(false));
+ $notEmptyMock = $this->createNonEmptyValidatorMock(false, $value);
$validatorChain = $this->input->getValidatorChain();
$validatorChain->prependValidator($notEmptyMock);
@@ -228,127 +379,23 @@ public function testRequiredNotEmptyValidatorNotAddedWhenOneExists()
$this->assertEquals($notEmptyMock, $validators[0]['instance']);
}
- public function emptyValuesProvider()
- {
- return array(
- array(null),
- array(''),
- array(array()),
- );
- }
-
- /**
- * @dataProvider emptyValuesProvider
- */
- public function testValidatorSkippedIfValueIsEmptyAndAllowedAndNotContinue($emptyValue)
- {
- $validator = function () {
- return false;
- };
- $this->input->setAllowEmpty(true)
- ->setContinueIfEmpty(false)
- ->setValue($emptyValue)
- ->getValidatorChain()->attach(new Validator\Callback($validator));
-
- $this->assertTrue($this->input->isValid());
- }
-
- /**
- * @dataProvider emptyValuesProvider
- */
- public function testAllowEmptyOptionSet($emptyValue)
- {
- $this->input->setAllowEmpty(true);
- $this->input->setValue($emptyValue);
- $this->assertTrue($this->input->isValid());
- }
-
/**
- * @dataProvider emptyValuesProvider
+ * @dataProvider emptyValueProvider
*/
- public function testAllowEmptyOptionNotSet($emptyValue)
+ public function testDoNotInjectNotEmptyValidatorIfAnywhereInChain($valueRaw, $valueFiltered)
{
- $this->input->setAllowEmpty(false);
- $this->input->setValue($emptyValue);
- $this->assertFalse($this->input->isValid());
- }
-
- /**
- * @dataProvider emptyValuesProvider
- */
- public function testValidatorInvokedIfValueIsEmptyAndAllowedAndContinue($emptyValue)
- {
- $message = 'failure by explicit validator';
- $validator = new Validator\Callback(function ($value) {
- return false;
- });
- $validator->setMessage($message);
- $this->input->setAllowEmpty(true)
- ->setContinueIfEmpty(true)
- ->setValue($emptyValue)
- ->getValidatorChain()->attach($validator);
- $this->assertFalse($this->input->isValid());
- // Test reason for validation failure; ensures that failure was not
- // caused by accidentally injected NotEmpty validator
- $this->assertEquals(array('callbackValue' => $message), $this->input->getMessages());
- }
-
- public function testNotAllowEmptyWithFilterConvertsNonemptyToEmptyIsNotValid()
- {
- $this->input->setValue('nonempty')
- ->getFilterChain()->attach(new Filter\Callback(function () {
- return '';
- }));
- $this->assertFalse($this->input->isValid());
- }
-
- public function testNotAllowEmptyWithFilterConvertsEmptyToNonEmptyIsValid()
- {
- $this->input->setValue('')
- ->getFilterChain()->attach(new Filter\Callback(function () {
- return 'nonempty';
- }));
- $this->assertTrue($this->input->isValid());
- }
-
- public function testMerge()
- {
- $input = new Input('foo');
- $input->setValue(' 123 ');
- $filter = new Filter\StringTrim();
- $input->getFilterChain()->attach($filter);
- $validator = new Validator\Digits();
- $input->getValidatorChain()->attach($validator);
-
- $input2 = new Input('bar');
- $input2->merge($input);
- $validatorChain = $input->getValidatorChain();
- $filterChain = $input->getFilterChain();
-
- $this->assertEquals(' 123 ', $input2->getRawValue());
- $this->assertEquals(1, $validatorChain->count());
- $this->assertEquals(1, $filterChain->count());
-
- $validators = $validatorChain->getValidators();
- $this->assertInstanceOf('Zend\Validator\Digits', $validators[0]['instance']);
+ $filterChain = $this->createFilterChainMock($valueRaw, $valueFiltered);
+ $validatorChain = $this->input->getValidatorChain();
- $filters = $filterChain->getFilters()->toArray();
- $this->assertInstanceOf('Zend\Filter\StringTrim', $filters[0]);
- }
+ $this->input->setRequired(true);
+ $this->input->setFilterChain($filterChain);
+ $this->input->setValue($valueRaw);
- public function testDoNotInjectNotEmptyValidatorIfAnywhereInChain()
- {
- $this->assertTrue($this->input->isRequired());
- $this->input->setValue('');
+ $notEmptyMock = $this->createNonEmptyValidatorMock(false, $valueFiltered);
- $notEmptyMock = $this->getMock('Zend\Validator\NotEmpty', array('isValid'));
- $notEmptyMock->expects($this->exactly(1))
- ->method('isValid')
- ->will($this->returnValue(false));
-
- $validatorChain = $this->input->getValidatorChain();
- $validatorChain->attach(new Validator\Digits());
+ $validatorChain->attach($this->createValidatorMock(true));
$validatorChain->attach($notEmptyMock);
+
$this->assertFalse($this->input->isValid());
$validators = $validatorChain->getValidators();
@@ -356,502 +403,480 @@ public function testDoNotInjectNotEmptyValidatorIfAnywhereInChain()
$this->assertEquals($notEmptyMock, $validators[1]['instance']);
}
- public function dataFallbackValue()
- {
- return array(
- array(
- 'fallbackValue' => null
- ),
- array(
- 'fallbackValue' => ''
- ),
- array(
- 'fallbackValue' => 'some value'
- ),
+ /**
+ * @group 7448
+ * @dataProvider isRequiredVsAllowEmptyVsContinueIfEmptyVsIsValidProvider
+ */
+ public function testIsRequiredVsAllowEmptyVsContinueIfEmptyVsIsValid(
+ $required,
+ $allowEmpty,
+ $continueIfEmpty,
+ $validator,
+ $value,
+ $expectedIsValid,
+ $expectedMessages
+ ) {
+ $this->input->setRequired($required);
+ $this->input->setAllowEmpty($allowEmpty);
+ $this->input->setContinueIfEmpty($continueIfEmpty);
+ $this->input->getValidatorChain()
+ ->attach($validator)
+ ;
+ $this->input->setValue($value);
+
+ $this->assertEquals(
+ $expectedIsValid,
+ $this->input->isValid(),
+ 'isValid() value not match. Detail: ' . json_encode($this->input->getMessages())
);
+ $this->assertEquals($expectedMessages, $this->input->getMessages(), 'getMessages() value not match');
+ $this->assertEquals($value, $this->input->getRawValue(), 'getRawValue() must return the value always');
+ $this->assertEquals($value, $this->input->getValue(), 'getValue() must return the filtered value always');
}
/**
- * @dataProvider dataFallbackValue
+ * @dataProvider setValueProvider
*/
- public function testFallbackValue($fallbackValue)
+ public function testSetValuePutInputInTheDesiredState($value)
{
- $this->input->setFallbackValue($fallbackValue);
- $validator = new Validator\Date();
- $this->input->getValidatorChain()->attach($validator);
- $this->input->setValue('123'); // not a date
+ $input = $this->input;
+ $this->assertFalse($input->hasValue(), 'Input should not have value by default');
- $this->assertTrue($this->input->isValid());
- $this->assertEmpty($this->input->getMessages());
- $this->assertSame($fallbackValue, $this->input->getValue());
+ $input->setValue($value);
+ $this->assertTrue($input->hasValue(), "hasValue() didn't return true when value was set");
}
- public function testMergeRetainsContinueIfEmptyFlag()
+ /**
+ * @dataProvider setValueProvider
+ */
+ public function testResetValueReturnsInputValueToDefaultValue($value)
{
- $input = new Input('foo');
- $input->setContinueIfEmpty(true);
+ $input = $this->input;
+ $originalInput = clone $input;
+ $this->assertFalse($input->hasValue(), 'Input should not have value by default');
+
+ $input->setValue($value);
+ $this->assertTrue($input->hasValue(), "hasValue() didn't return true when value was set");
- $input2 = new Input('bar');
- $input2->merge($input);
- $this->assertTrue($input2->continueIfEmpty());
+ $return = $input->resetValue();
+ $this->assertSame($input, $return, 'resetValue() must return itself');
+ $this->assertEquals($originalInput, $input, 'Input was not reset to the default value state');
}
- public function testMergeRetainsAllowEmptyFlag()
+ public function testMerge()
{
- $input = new Input('foo');
- $input->setRequired(true);
- $input->setAllowEmpty(true);
-
- $input2 = new Input('bar');
- $input2->setRequired(true);
- $input2->setAllowEmpty(false);
- $input2->merge($input);
-
- $this->assertTrue($input2->isRequired());
- $this->assertTrue($input2->allowEmpty());
+ $sourceRawValue = $this->getDummyValue();
+
+ $source = $this->createInputInterfaceMock();
+ $source->method('getName')->willReturn('bazInput');
+ $source->method('getErrorMessage')->willReturn('bazErrorMessage');
+ $source->method('breakOnFailure')->willReturn(true);
+ $source->method('isRequired')->willReturn(true);
+ $source->method('getRawValue')->willReturn($sourceRawValue);
+ $source->method('getFilterChain')->willReturn($this->createFilterChainMock());
+ $source->method('getValidatorChain')->willReturn($this->createValidatorChainMock());
+
+ $targetFilterChain = $this->createFilterChainMock();
+ $targetFilterChain->expects(TestCase::once())
+ ->method('merge')
+ ->with($source->getFilterChain())
+ ;
+
+ $targetValidatorChain = $this->createValidatorChainMock();
+ $targetValidatorChain->expects(TestCase::once())
+ ->method('merge')
+ ->with($source->getValidatorChain())
+ ;
+
+ $target = $this->input;
+ $target->setName('fooInput');
+ $target->setErrorMessage('fooErrorMessage');
+ $target->setBreakOnFailure(false);
+ $target->setRequired(false);
+ $target->setFilterChain($targetFilterChain);
+ $target->setValidatorChain($targetValidatorChain);
+
+ $return = $target->merge($source);
+ $this->assertSame($target, $return, 'merge() must return it self');
+
+ $this->assertEquals('bazInput', $target->getName(), 'getName() value not match');
+ $this->assertEquals('bazErrorMessage', $target->getErrorMessage(), 'getErrorMessage() value not match');
+ $this->assertEquals(true, $target->breakOnFailure(), 'breakOnFailure() value not match');
+ $this->assertEquals(true, $target->isRequired(), 'isRequired() value not match');
+ $this->assertEquals($sourceRawValue, $target->getRawValue(), 'getRawValue() value not match');
+ $this->assertTrue($target->hasValue(), 'hasValue() value not match');
}
/**
- * @group 7445
+ * Specific Input::merge extras
*/
- public function testInputIsValidWhenUsingSetRequiredAtStart()
+ public function testInputMergeWithoutValues()
{
- $input = new Input();
- $input->setName('foo')
- ->setRequired(false)
- ->setAllowEmpty(false)
- ->setContinueIfEmpty(false);
+ $source = new Input();
+ $source->setContinueIfEmpty(true);
+ $this->assertFalse($source->hasValue(), 'Source should not have a value');
- $this->assertTrue($input->isValid());
- }
+ $target = $this->input;
+ $target->setContinueIfEmpty(false);
+ $this->assertFalse($target->hasValue(), 'Target should not have a value');
- /**
- * @group 7445
- */
- public function testInputIsValidWhenUsingSetRequiredAtEnd()
- {
- $input = new Input();
- $input->setName('foo')
- ->setAllowEmpty(false)
- ->setContinueIfEmpty(false)
- ->setRequired(false);
+ $return = $target->merge($source);
+ $this->assertSame($target, $return, 'merge() must return it self');
- $this->assertTrue($input->isValid());
+ $this->assertEquals(true, $target->continueIfEmpty(), 'continueIfEmpty() value not match');
+ $this->assertFalse($target->hasValue(), 'hasValue() value not match');
}
- public function whenRequiredAndAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun()
+ /**
+ * Specific Input::merge extras
+ */
+ public function testInputMergeWithSourceValue()
{
- $validator = new Validator\Callback(function ($value) {
- throw new RuntimeException('Validator executed when it should not be');
- });
+ $source = new Input();
+ $source->setContinueIfEmpty(true);
+ $source->setValue(array('foo'));
- $requiredFirst = new Input('foo');
- $requiredFirst->setRequired(true)
- ->setAllowEmpty(true)
- ->setContinueIfEmpty(false)
- ->getValidatorChain()->attach($validator);
+ $target = $this->input;
+ $target->setContinueIfEmpty(false);
+ $this->assertFalse($target->hasValue(), 'Target should not have a value');
- $requiredLast = new Input('foo');
- $requiredLast->setAllowEmpty(true)
- ->setContinueIfEmpty(false)
- ->setRequired(true)
- ->getValidatorChain()->attach($validator);
+ $return = $target->merge($source);
+ $this->assertSame($target, $return, 'merge() must return it self');
- return array(
- 'required-first-null' => array($requiredFirst, null),
- 'required-last-null' => array($requiredLast, null),
- 'required-first-empty' => array($requiredFirst, ''),
- 'required-last-empty' => array($requiredLast, ''),
- 'required-first-array' => array($requiredFirst, array()),
- 'required-last-array' => array($requiredLast, array()),
- );
+ $this->assertEquals(true, $target->continueIfEmpty(), 'continueIfEmpty() value not match');
+ $this->assertEquals(array('foo'), $target->getRawValue(), 'getRawValue() value not match');
+ $this->assertTrue($target->hasValue(), 'hasValue() value not match');
}
/**
- * @group 7448
- * @dataProvider whenRequiredAndAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun
+ * Specific Input::merge extras
*/
- public function testWhenRequiredAndAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun($input, $value)
+ public function testInputMergeWithTargetValue()
{
- $input->setValue($value);
- $this->assertTrue($input->isValid());
- }
+ $source = new Input();
+ $source->setContinueIfEmpty(true);
+ $this->assertFalse($source->hasValue(), 'Source should not have a value');
- public function whenRequiredAndAllowEmptyAndContinueIfEmptyValidatorsAreRun()
- {
- $alwaysInvalid = new Validator\Callback(function ($value) {
- if (! empty($value)) {
- throw new RuntimeException('Unexpected non-empty value provided to validate');
- }
- return false;
- });
+ $target = $this->input;
+ $target->setContinueIfEmpty(false);
+ $target->setValue(array('foo'));
- $emptyIsValid = new Validator\Callback(function ($value) {
- if (! empty($value)) {
- throw new RuntimeException('Unexpected non-empty value provided to validate');
- }
- return true;
- });
-
- $requiredFirstInvalid = new Input('foo');
- $requiredFirstValid = new Input('foo');
- foreach (array($requiredFirstValid, $requiredFirstInvalid) as $input) {
- $input->setRequired(true)
- ->setAllowEmpty(true)
- ->setContinueIfEmpty(true);
- }
+ $return = $target->merge($source);
+ $this->assertSame($target, $return, 'merge() must return it self');
- $requiredLastInvalid = new Input('foo');
- $requiredLastValid = new Input('foo');
- foreach (array($requiredLastValid, $requiredLastInvalid) as $input) {
- $input->setAllowEmpty(true)
- ->setContinueIfEmpty(true)
- ->setRequired(true);
- }
+ $this->assertEquals(true, $target->continueIfEmpty(), 'continueIfEmpty() value not match');
+ $this->assertEquals(array('foo'), $target->getRawValue(), 'getRawValue() value not match');
+ $this->assertTrue($target->hasValue(), 'hasValue() value not match');
+ }
- foreach (array($requiredFirstValid, $requiredLastValid) as $input) {
- $input->getValidatorChain()->attach($emptyIsValid);
- }
+ public function fallbackValueVsIsValidProvider()
+ {
+ $required = true;
+ $isValid = true;
- foreach (array($requiredFirstInvalid, $requiredLastInvalid) as $input) {
- $input->getValidatorChain()->attach($alwaysInvalid);
- }
+ $originalValue = 'fooValue';
+ $fallbackValue = 'fooFallbackValue';
+ // @codingStandardsIgnoreStart
return array(
- 'required-first-null-valid' => array($requiredFirstValid, null, 'assertTrue'),
- 'required-first-null-invalid' => array($requiredFirstInvalid, null, 'assertFalse'),
- 'required-last-null-valid' => array($requiredLastValid, null, 'assertTrue'),
- 'required-last-null-invalid' => array($requiredLastInvalid, null, 'assertFalse'),
- 'required-first-empty-valid' => array($requiredFirstValid, '', 'assertTrue'),
- 'required-first-empty-invalid' => array($requiredFirstInvalid, '', 'assertFalse'),
- 'required-last-empty-valid' => array($requiredLastValid, '', 'assertTrue'),
- 'required-last-empty-invalid' => array($requiredLastInvalid, '', 'assertFalse'),
- 'required-first-array-valid' => array($requiredFirstValid, array(), 'assertTrue'),
- 'required-first-array-invalid' => array($requiredFirstInvalid, array(), 'assertFalse'),
- 'required-last-array-valid' => array($requiredLastValid, array(), 'assertTrue'),
- 'required-last-array-invalid' => array($requiredLastInvalid, array(), 'assertFalse'),
+ // Description => [$inputIsRequired, $fallbackValue, $originalValue, $isValid, $expectedValue]
+ 'Required: T, Input: Invalid. getValue: fallback' => array( $required, $fallbackValue, $originalValue, !$isValid, $fallbackValue),
+ 'Required: T, Input: Valid. getValue: original' => array( $required, $fallbackValue, $originalValue, $isValid, $originalValue),
+ 'Required: F, Input: Invalid. getValue: fallback' => array(!$required, $fallbackValue, $originalValue, !$isValid, $fallbackValue),
+ 'Required: F, Input: Valid. getValue: original' => array(!$required, $fallbackValue, $originalValue, $isValid, $originalValue),
);
+ // @codingStandardsIgnoreEnd
}
- /**
- * @group 7448
- * @dataProvider whenRequiredAndAllowEmptyAndContinueIfEmptyValidatorsAreRun
- */
- public function testWhenRequiredAndAllowEmptyAndContinueIfEmptyValidatorsAreRun($input, $value, $assertion)
- {
- $input->setValue($value);
- $this->{$assertion}($input->isValid());
- }
-
- public function whenRequiredAndNotAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun()
+ public function setValueProvider()
{
- $validator = new Validator\Callback(function ($value) {
- throw new RuntimeException('Validator executed when it should not be');
- });
+ $emptyValues = $this->emptyValueProvider();
+ $mixedValues = $this->mixedValueProvider();
- $requiredFirst = new Input('foo');
- $requiredFirst->setRequired(true)
- ->setAllowEmpty(false)
- ->setContinueIfEmpty(false)
- ->getValidatorChain()->attach($validator);
+ $values = array_merge($emptyValues, $mixedValues);
- $requiredLast = new Input('foo');
- $requiredLast->setAllowEmpty(false)
- ->setContinueIfEmpty(false)
- ->setRequired(true)
- ->getValidatorChain()->attach($validator);
-
- return array(
- 'required-first-null' => array($requiredFirst, null),
- 'required-last-null' => array($requiredLast, null),
- 'required-first-empty' => array($requiredFirst, ''),
- 'required-last-empty' => array($requiredLast, ''),
- 'required-first-array' => array($requiredFirst, array()),
- 'required-last-array' => array($requiredLast, array()),
- );
+ return $values;
}
- /**
- * @group 7448
- * @dataProvider whenRequiredAndNotAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun
- */
- public function testWhenRequiredAndNotAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun($input, $value)
+ public function isRequiredVsAllowEmptyVsContinueIfEmptyVsIsValidProvider()
{
- $input->setValue($value);
- $this->assertFalse($input->isValid());
- }
+ $allValues = $this->setValueProvider();
+ $emptyValues = $this->emptyValueProvider();
+ $nonEmptyValues = array_diff_key($allValues, $emptyValues);
- public function whenRequiredAndNotAllowEmptyAndContinueIfEmptyValidatorsAreRun()
- {
- $alwaysInvalid = new Validator\Callback(function ($value) {
- if (! empty($value)) {
- throw new RuntimeException('Unexpected non-empty value provided to validate');
- }
- return false;
- });
+ $isRequired = true;
+ $aEmpty = true;
+ $cIEmpty = true;
+ $isValid = true;
- $emptyIsValid = new Validator\Callback(function ($value) {
- if (! empty($value)) {
- throw new RuntimeException('Unexpected non-empty value provided to validate');
- }
- return true;
- });
-
- $requiredFirstInvalid = new Input('foo');
- $requiredFirstValid = new Input('foo');
- foreach (array($requiredFirstValid, $requiredFirstInvalid) as $input) {
- $input->setRequired(true)
- ->setAllowEmpty(false)
- ->setContinueIfEmpty(true);
- }
+ $validatorMsg = array('FooValidator' => 'Invalid Value');
+ $notEmptyMsg = array('isEmpty' => "Value is required and can't be empty");
- $requiredLastInvalid = new Input('foo');
- $requiredLastValid = new Input('foo');
- foreach (array($requiredLastValid, $requiredLastInvalid) as $input) {
- $input->setAllowEmpty(false)
- ->setContinueIfEmpty(true)
- ->setRequired(true);
- }
+ $self = $this;
+ $validatorNotCall = function ($value, $context = null) use ($self) {
+ return $self->createValidatorMock(null, $value, $context);
+ };
+ $validatorInvalid = function ($value, $context = null) use ($self, $validatorMsg) {
+ return $self->createValidatorMock(false, $value, $context, $validatorMsg);
+ };
+ $validatorValid = function ($value, $context = null) use ($self) {
+ return $self->createValidatorMock(true, $value, $context);
+ };
- foreach (array($requiredFirstValid, $requiredLastValid) as $input) {
- $input->getValidatorChain()->attach($emptyIsValid);
- }
+ // @codingStandardsIgnoreStart
+ $dataTemplates = array(
+ // Description => [$isRequired, $allowEmpty, $continueIfEmpty, $validator, [$values], $expectedIsValid, $expectedMessages]
+ 'Required: T; AEmpty: T; CIEmpty: T; Validator: T' => array( $isRequired, $aEmpty, $cIEmpty, $validatorValid , $allValues , $isValid, array()),
+ 'Required: T; AEmpty: T; CIEmpty: T; Validator: F' => array( $isRequired, $aEmpty, $cIEmpty, $validatorInvalid, $allValues , !$isValid, $validatorMsg),
- foreach (array($requiredFirstInvalid, $requiredLastInvalid) as $input) {
- $input->getValidatorChain()->attach($alwaysInvalid);
- }
+ 'Required: T; AEmpty: T; CIEmpty: F; Validator: X, Value: Empty' => array( $isRequired, $aEmpty, !$cIEmpty, $validatorNotCall, $emptyValues , $isValid, array()),
+ 'Required: T; AEmpty: T; CIEmpty: F; Validator: T, Value: Not Empty' => array( $isRequired, $aEmpty, !$cIEmpty, $validatorValid , $nonEmptyValues, $isValid, array()),
+ 'Required: T; AEmpty: T; CIEmpty: F; Validator: F, Value: Not Empty' => array( $isRequired, $aEmpty, !$cIEmpty, $validatorInvalid, $nonEmptyValues, !$isValid, $validatorMsg),
- return array(
- 'required-first-null-valid' => array($requiredFirstValid, null, 'assertTrue'),
- 'required-first-null-invalid' => array($requiredFirstInvalid, null, 'assertFalse'),
- 'required-last-null-valid' => array($requiredLastValid, null, 'assertTrue'),
- 'required-last-null-invalid' => array($requiredLastInvalid, null, 'assertFalse'),
- 'required-first-empty-valid' => array($requiredFirstValid, '', 'assertTrue'),
- 'required-first-empty-invalid' => array($requiredFirstInvalid, '', 'assertFalse'),
- 'required-last-empty-valid' => array($requiredLastValid, '', 'assertTrue'),
- 'required-last-empty-invalid' => array($requiredLastInvalid, '', 'assertFalse'),
- 'required-first-array-valid' => array($requiredFirstValid, array(), 'assertTrue'),
- 'required-first-array-invalid' => array($requiredFirstInvalid, array(), 'assertFalse'),
- 'required-last-array-valid' => array($requiredLastValid, array(), 'assertTrue'),
- 'required-last-array-invalid' => array($requiredLastInvalid, array(), 'assertFalse'),
- );
- }
+ 'Required: T; AEmpty: F; CIEmpty: T; Validator: T' => array( $isRequired, !$aEmpty, $cIEmpty, $validatorValid , $allValues , $isValid, array()),
+ 'Required: T; AEmpty: F; CIEmpty: T; Validator: F' => array( $isRequired, !$aEmpty, $cIEmpty, $validatorInvalid, $allValues , !$isValid, $validatorMsg),
- /**
- * @group 7448
- * @dataProvider whenRequiredAndNotAllowEmptyAndContinueIfEmptyValidatorsAreRun
- */
- public function testWhenRequiredAndNotAllowEmptyAndContinueIfEmptyValidatorsAreRun($input, $value, $assertion)
- {
- $input->setValue($value);
- $this->{$assertion}($input->isValid());
- }
+ 'Required: T; AEmpty: F; CIEmpty: F; Validator: X, Value: Empty' => array( $isRequired, !$aEmpty, !$cIEmpty, $validatorNotCall, $emptyValues , !$isValid, $notEmptyMsg),
+ 'Required: T; AEmpty: F; CIEmpty: F; Validator: T, Value: Not Empty' => array( $isRequired, !$aEmpty, !$cIEmpty, $validatorValid , $nonEmptyValues, $isValid, array()),
+ 'Required: T; AEmpty: F; CIEmpty: F; Validator: F, Value: Not Empty' => array( $isRequired, !$aEmpty, !$cIEmpty, $validatorInvalid, $nonEmptyValues, !$isValid, $validatorMsg),
- public function whenNotRequiredAndAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun()
- {
- $validator = new Validator\Callback(function ($value) {
- throw new RuntimeException('Validator executed when it should not be');
- });
+ 'Required: F; AEmpty: T; CIEmpty: T; Validator: T' => array(!$isRequired, $aEmpty, $cIEmpty, $validatorValid , $allValues , $isValid, array()),
+ 'Required: F; AEmpty: T; CIEmpty: T; Validator: F' => array(!$isRequired, $aEmpty, $cIEmpty, $validatorInvalid, $allValues , !$isValid, $validatorMsg),
- $requiredFirst = new Input('foo');
- $requiredFirst->setRequired(false)
- ->setAllowEmpty(true)
- ->setContinueIfEmpty(false)
- ->getValidatorChain()->attach($validator);
+ 'Required: F; AEmpty: T; CIEmpty: F; Validator: X, Value: Empty' => array(!$isRequired, $aEmpty, !$cIEmpty, $validatorNotCall, $emptyValues , $isValid, array()),
+ 'Required: F; AEmpty: T; CIEmpty: F; Validator: T, Value: Not Empty' => array(!$isRequired, $aEmpty, !$cIEmpty, $validatorValid , $nonEmptyValues, $isValid, array()),
+ 'Required: F; AEmpty: T; CIEmpty: F; Validator: F, Value: Not Empty' => array(!$isRequired, $aEmpty, !$cIEmpty, $validatorInvalid, $nonEmptyValues, !$isValid, $validatorMsg),
- $requiredLast = new Input('foo');
- $requiredLast->setAllowEmpty(true)
- ->setContinueIfEmpty(false)
- ->setRequired(false)
- ->getValidatorChain()->attach($validator);
+ 'Required: F; AEmpty: F; CIEmpty: T; Validator: T' => array(!$isRequired, !$aEmpty, $cIEmpty, $validatorValid , $allValues , $isValid, array()),
+ 'Required: F; AEmpty: F; CIEmpty: T; Validator: F' => array(!$isRequired, !$aEmpty, $cIEmpty, $validatorInvalid, $allValues , !$isValid, $validatorMsg),
- return array(
- 'required-first-null' => array($requiredFirst, null),
- 'required-last-null' => array($requiredLast, null),
- 'required-first-empty' => array($requiredFirst, ''),
- 'required-last-empty' => array($requiredLast, ''),
- 'required-first-array' => array($requiredFirst, array()),
- 'required-last-array' => array($requiredLast, array()),
+ 'Required: F; AEmpty: F; CIEmpty: F; Validator: X, Value: Empty' => array(!$isRequired, !$aEmpty, !$cIEmpty, $validatorNotCall, $emptyValues , $isValid, array()),
+ 'Required: F; AEmpty: F; CIEmpty: F; Validator: T, Value: Not Empty' => array(!$isRequired, !$aEmpty, !$cIEmpty, $validatorValid , $nonEmptyValues, $isValid, array()),
+ 'Required: F; AEmpty: F; CIEmpty: F; Validator: F, Value: Not Empty' => array(!$isRequired, !$aEmpty, !$cIEmpty, $validatorInvalid, $nonEmptyValues, !$isValid, $validatorMsg),
);
+ // @codingStandardsIgnoreEnd
+
+ // Expand data template matrix for each possible input value.
+ // Description => [$isRequired, $allowEmpty, $continueIfEmpty, $validator, $value, $expectedIsValid]
+ $dataSets = array();
+ foreach ($dataTemplates as $dataTemplateDescription => $dataTemplate) {
+ foreach ($dataTemplate[4] as $valueDescription => $value) {
+ $tmpTemplate = $dataTemplate;
+ $tmpTemplate[3] = $dataTemplate[3]($value['filtered']); // Get validator mock for each data set
+ $tmpTemplate[4] = $value['raw']; // expand value
+
+ $dataSets[$dataTemplateDescription . ' / ' . $valueDescription] = $tmpTemplate;
+ }
+ }
+
+ return $dataSets;
}
- /**
- * @group 7448
- * @dataProvider whenNotRequiredAndAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun
- */
- public function testWhenNotRequiredAndAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun($input, $value)
+ public function emptyValueProvider()
{
- $input->setValue($value);
- $this->assertTrue($input->isValid());
+ return array(
+ // Description => [$value]
+ 'null' => array(
+ 'raw' => null,
+ 'filtered' => null,
+ ),
+ '""' => array(
+ 'raw' => '',
+ 'filtered' => '',
+ ),
+// '"0"' => array('0'),
+// '0' => array(0),
+// '0.0' => array(0.0),
+// 'false' => array(false),
+ '[]' => array(
+ 'raw' => array(),
+ 'filtered' => array(),
+ ),
+ );
}
- public function whenNotRequiredAndNotAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun()
+ public function mixedValueProvider()
{
- $validator = new Validator\Callback(function ($value) {
- throw new RuntimeException('Validator executed when it should not be');
- });
-
- $requiredFirst = new Input('foo');
- $requiredFirst->setRequired(false)
- ->setAllowEmpty(false)
- ->setContinueIfEmpty(false)
- ->getValidatorChain()->attach($validator);
-
- $requiredLast = new Input('foo');
- $requiredLast->setAllowEmpty(false)
- ->setContinueIfEmpty(false)
- ->setRequired(false)
- ->getValidatorChain()->attach($validator);
-
return array(
- 'required-first-null' => array($requiredFirst, null),
- 'required-last-null' => array($requiredLast, null),
- 'required-first-empty' => array($requiredFirst, ''),
- 'required-last-empty' => array($requiredLast, ''),
- 'required-first-array' => array($requiredFirst, array()),
- 'required-last-array' => array($requiredLast, array()),
+ // Description => [$value]
+ '"0"' => array(
+ 'raw' => '0',
+ 'filtered' => '0',
+ ),
+ '0' => array(
+ 'raw' => 0,
+ 'filtered' => 0,
+ ),
+ '0.0' => array(
+ 'raw' => 0.0,
+ 'filtered' => 0.0,
+ ),
+// TODO enable me
+// 'false' => array(
+// 'raw' => false,
+// 'filtered' => false,
+// ),
+ 'php' => array(
+ 'raw' => 'php',
+ 'filtered' => 'php',
+ ),
+// TODO enable me
+// 'whitespace' => array(
+// 'raw' => ' ',
+// 'filtered' => ' ',
+// ),
+ '1' => array(
+ 'raw' => 1,
+ 'filtered' => 1,
+ ),
+ '1.0' => array(
+ 'raw' => 1.0,
+ 'filtered' => 1.0,
+ ),
+ 'true' => array(
+ 'raw' => true,
+ 'filtered' => true,
+ ),
+ '["php"]' => array(
+ 'raw' => array('php'),
+ 'filtered' => array('php'),
+ ),
+ 'object' => array(
+ 'raw' => new stdClass(),
+ 'filtered' => new stdClass(),
+ ),
+ // @codingStandardsIgnoreStart
+// TODO Skip HHVM failure enable me
+// 'callable' => array(
+// 'raw' => function () {},
+// 'filtered' => function () {},
+// ),
+ // @codingStandardsIgnoreEnd
);
}
/**
- * @group 7448
- * @dataProvider whenNotRequiredAndNotAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun
+ * @return InputInterface|MockObject
*/
- public function testWhenNotRequiredAndNotAllowEmptyAndNotContinueIfEmptyValidatorsAreNotRun($input, $value)
+ public function createInputInterfaceMock()
{
- $input->setValue($value);
- $this->assertTrue($input->isValid());
+ /** @var InputInterface|MockObject $source */
+ $source = $this->getMock('Zend\InputFilter\InputInterface');
+
+ return $source;
}
- public function whenNotRequiredAndAllowEmptyAndContinueIfEmptyValidatorsAreRun()
+ /**
+ * @param mixed $valueRaw
+ * @param mixed $valueFiltered
+ *
+ * @return FilterChain|MockObject
+ */
+ public function createFilterChainMock($valueRaw = null, $valueFiltered = null)
{
- $alwaysInvalid = new Validator\Callback(function ($value) {
- if (! empty($value)) {
- throw new RuntimeException('Unexpected non-empty value provided to validate');
- }
- return false;
- });
+ /** @var FilterChain|MockObject $filterChain */
+ $filterChain = $this->getMock('Zend\Filter\FilterChain');
- $emptyIsValid = new Validator\Callback(function ($value) {
- if (! empty($value)) {
- throw new RuntimeException('Unexpected non-empty value provided to validate');
- }
- return true;
- });
-
- $requiredFirstInvalid = new Input('foo');
- $requiredFirstValid = new Input('foo');
- foreach (array($requiredFirstValid, $requiredFirstInvalid) as $input) {
- $input->setRequired(false)
- ->setAllowEmpty(true)
- ->setContinueIfEmpty(true);
- }
+ $filterChain->method('filter')
+ ->with($valueRaw)
+ ->willReturn($valueFiltered)
+ ;
- $requiredLastInvalid = new Input('foo');
- $requiredLastValid = new Input('foo');
- foreach (array($requiredLastValid, $requiredLastInvalid) as $input) {
- $input->setAllowEmpty(true)
- ->setContinueIfEmpty(true)
- ->setRequired(false);
- }
+ return $filterChain;
+ }
- foreach (array($requiredFirstValid, $requiredLastValid) as $input) {
- $input->getValidatorChain()->attach($emptyIsValid);
+ /**
+ * @param null|bool $isValid If set stub isValid method for return the argument value.
+ * @param mixed $value
+ * @param mixed $context
+ * @param string[] $messages
+ *
+ * @return ValidatorChain|MockObject
+ */
+ public function createValidatorChainMock($isValid = null, $value = null, $context = null, $messages = array())
+ {
+ /** @var ValidatorChain|MockObject $validatorChain */
+ $validatorChain = $this->getMock('Zend\Validator\ValidatorChain');
+
+ if (($isValid === false) || ($isValid === true)) {
+ $validatorChain->expects($this->once())
+ ->method('isValid')
+ ->with($value, $context)
+ ->willReturn($isValid)
+ ;
+ } else {
+ $validatorChain->expects($this->never())
+ ->method('isValid')
+ ->with($value, $context)
+ ;
}
- foreach (array($requiredFirstInvalid, $requiredLastInvalid) as $input) {
- $input->getValidatorChain()->attach($alwaysInvalid);
- }
+ $validatorChain->method('getMessages')
+ ->willReturn($messages)
+ ;
- return array(
- 'required-first-null-valid' => array($requiredFirstValid, null, 'assertTrue'),
- 'required-first-null-invalid' => array($requiredFirstInvalid, null, 'assertFalse'),
- 'required-last-null-valid' => array($requiredLastValid, null, 'assertTrue'),
- 'required-last-null-invalid' => array($requiredLastInvalid, null, 'assertFalse'),
- 'required-first-empty-valid' => array($requiredFirstValid, '', 'assertTrue'),
- 'required-first-empty-invalid' => array($requiredFirstInvalid, '', 'assertFalse'),
- 'required-last-empty-valid' => array($requiredLastValid, '', 'assertTrue'),
- 'required-last-empty-invalid' => array($requiredLastInvalid, '', 'assertFalse'),
- 'required-first-array-valid' => array($requiredFirstValid, array(), 'assertTrue'),
- 'required-first-array-invalid' => array($requiredFirstInvalid, array(), 'assertFalse'),
- 'required-last-array-valid' => array($requiredLastValid, array(), 'assertTrue'),
- 'required-last-array-invalid' => array($requiredLastInvalid, array(), 'assertFalse'),
- );
+ return $validatorChain;
}
/**
- * @group 7448
- * @dataProvider whenNotRequiredAndAllowEmptyAndContinueIfEmptyValidatorsAreRun
+ * @param null|bool $isValid
+ * @param mixed $value
+ * @param mixed $context
+ * @param string[] $messages
+ *
+ * @return ValidatorInterface|MockObject
*/
- public function testWhenNotRequiredAndAllowEmptyAndContinueIfEmptyValidatorsAreRun($input, $value, $assertion)
- {
- $input->setValue($value);
- $this->{$assertion}($input->isValid());
- }
-
- public function whenNotRequiredAndNotAllowEmptyAndContinueIfEmptyValidatorsAreRun()
- {
- $alwaysInvalid = new Validator\Callback(function ($value) {
- if (! empty($value)) {
- throw new RuntimeException('Unexpected non-empty value provided to validate');
- }
- return false;
- });
-
- $emptyIsValid = new Validator\Callback(function ($value) {
- if (! empty($value)) {
- throw new RuntimeException('Unexpected non-empty value provided to validate');
- }
- return true;
- });
-
- $requiredFirstInvalid = new Input('foo');
- $requiredFirstValid = new Input('foo');
- foreach (array($requiredFirstValid, $requiredFirstInvalid) as $input) {
- $input->setRequired(false)
- ->setAllowEmpty(false)
- ->setContinueIfEmpty(true);
+ public function createValidatorMock($isValid, $value = 'not-set', $context = null, $messages = array())
+ {
+ /** @var ValidatorInterface|MockObject $validator */
+ $validator = $this->getMock('Zend\Validator\ValidatorInterface');
+
+ if (($isValid === false) || ($isValid === true)) {
+ $isValidMethod = $validator->expects($this->once())
+ ->method('isValid')
+ ->willReturn($isValid)
+ ;
+ } else {
+ $isValidMethod = $validator->expects($this->never())
+ ->method('isValid')
+ ;
}
-
- $requiredLastInvalid = new Input('foo');
- $requiredLastValid = new Input('foo');
- foreach (array($requiredLastValid, $requiredLastInvalid) as $input) {
- $input->setAllowEmpty(false)
- ->setContinueIfEmpty(true)
- ->setRequired(false);
+ if ($value !== 'not-set') {
+ $isValidMethod->with($value, $context);
}
- foreach (array($requiredFirstValid, $requiredLastValid) as $input) {
- $input->getValidatorChain()->attach($emptyIsValid);
- }
+ $validator->method('getMessages')
+ ->willReturn($messages)
+ ;
- foreach (array($requiredFirstInvalid, $requiredLastInvalid) as $input) {
- $input->getValidatorChain()->attach($alwaysInvalid);
- }
-
- return array(
- 'required-first-null-valid' => array($requiredFirstValid, null, 'assertTrue'),
- 'required-first-null-invalid' => array($requiredFirstInvalid, null, 'assertFalse'),
- 'required-last-null-valid' => array($requiredLastValid, null, 'assertTrue'),
- 'required-last-null-invalid' => array($requiredLastInvalid, null, 'assertFalse'),
- 'required-first-empty-valid' => array($requiredFirstValid, '', 'assertTrue'),
- 'required-first-empty-invalid' => array($requiredFirstInvalid, '', 'assertFalse'),
- 'required-last-empty-valid' => array($requiredLastValid, '', 'assertTrue'),
- 'required-last-empty-invalid' => array($requiredLastInvalid, '', 'assertFalse'),
- 'required-first-array-valid' => array($requiredFirstValid, array(), 'assertTrue'),
- 'required-first-array-invalid' => array($requiredFirstInvalid, array(), 'assertFalse'),
- 'required-last-array-valid' => array($requiredLastValid, array(), 'assertTrue'),
- 'required-last-array-invalid' => array($requiredLastInvalid, array(), 'assertFalse'),
- );
+ return $validator;
}
/**
- * @group 7448
- * @dataProvider whenNotRequiredAndNotAllowEmptyAndContinueIfEmptyValidatorsAreRun
+ * @param bool $isValid
+ * @param mixed $value
+ * @param mixed $context
+ *
+ * @return NotEmptyValidator|MockObject
*/
- public function testWhenNotRequiredAndNotAllowEmptyAndContinueIfEmptyValidatorsAreRun($input, $value, $assertion)
+ public function createNonEmptyValidatorMock($isValid, $value, $context = null)
{
- $input->setValue($value);
- $this->{$assertion}($input->isValid());
+ /** @var NotEmptyValidator|MockObject $notEmptyMock */
+ $notEmptyMock = $this->getMock('Zend\Validator\NotEmpty', array('isValid'));
+ $notEmptyMock->expects($this->once())
+ ->method('isValid')
+ ->with($value, $context)
+ ->willReturn($isValid)
+ ;
+
+ return $notEmptyMock;
+ }
+
+ public function getDummyValue($raw = true)
+ {
+ if ($raw) {
+ return 'foo';
+ }
+ return 'filtered';
}
}