From 826d8c48ef086e323863d4191ee9dd262ede5bf2 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Fri, 21 Aug 2015 20:53:05 +0200 Subject: [PATCH 01/22] Consolidate tests for InputFilterInterface (add/has/get/remove/count methods) --- test/BaseInputFilterTest.php | 126 ++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 11 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 0aa42d1e..712ce895 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -186,6 +186,50 @@ public function testGetUnknownThrowExceptionIfDataWasNotSetYet() $inputFilter->getUnknown(); } + /** + * Verify the state of the input filter is the desired after change it using the method `add()` + * + * @dataProvider addMethodArgumentsProvider + */ + public function testAddHasGet($input, $name, $expectedInputName, $expectedInput) + { + $inputFilter = $this->getInputFilter(); + $this->assertFalse( + $inputFilter->has($expectedInputName), + "InputFilter shouldn't have an input with the name $expectedInputName yet" + ); + $currentNumberOfFilters = count($inputFilter); + + $return = $inputFilter->add($input, $name); + $this->assertSame($inputFilter, $return, "add() must return it self"); + + // **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'); + + $returnInput = $inputFilter->get($expectedInputName); + $this->assertEquals($expectedInput, $returnInput, 'get() does not match the expected input'); + } + + /** + * Verify the state of the input filter is the desired after change it using the method `add()` and `remove()` + * + * @dataProvider addMethodArgumentsProvider + */ + public function testAddRemove($input, $name, $expectedInputName) + { + $inputFilter = $this->getInputFilter(); + + $inputFilter->add($input, $name); + $currentNumberOfFilters = count($inputFilter); + + $return = $inputFilter->remove($expectedInputName); + $this->assertSame($inputFilter, $return, 'remove() must return it self'); + + $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 testAddingInputsIncreasesCountOfFilter() { $filter = new InputFilter(); @@ -199,12 +243,14 @@ public function testAddingInputsIncreasesCountOfFilter() public function testAddingInputWithNameDoesNotInjectNameInInput() { - $filter = new InputFilter(); - $foo = new Input('foo'); - $filter->add($foo, 'bar'); - $test = $filter->get('bar'); - $this->assertSame($foo, $test); - $this->assertEquals('foo', $foo->getName()); + $inputFilter = $this->getInputFilter(); + + $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'); } public function testCanAddInputFilterAsInput() @@ -606,7 +652,7 @@ public function testValidationContext($data, $customContext, $expectedContext) { $filter = new InputFilter(); - $input = $this->createInputInterfaceMock(true, true, $expectedContext); + $input = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext); $filter->add($input, 'fooInput'); $filter->setData($data); @@ -623,7 +669,7 @@ public function testBuildValidationContextUsingInputGetRawValue() $expectedContext = ['fooInput' => 'fooRawValue']; $filter = new InputFilter(); - $input = $this->createInputInterfaceMock(true, true, $expectedContext, 'fooRawValue'); + $input = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext, 'fooRawValue'); $filter->add($input, 'fooInput'); $filter->setData($data); @@ -643,8 +689,8 @@ public function testContextIsTheSameWhenARequiredInputIsGivenAndOptionalInputIsM 'inputRequired' => 'inputRequiredValue', 'inputOptional' => null, ]; - $inputRequired = $this->createInputInterfaceMock(true, true, $expectedContext); - $inputOptional = $this->createInputInterfaceMock(false); + $inputRequired = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext); + $inputOptional = $this->createInputInterfaceMock('fooInput', false); $filter = new InputFilter(); $filter->add($inputRequired, 'inputRequired'); @@ -1194,17 +1240,75 @@ public function testAllowsValidatingArrayAccessData() $this->assertTrue($filter->isValid()); } + public function addMethodArgumentsProvider() + { + // Description => [$input argument, $name argument, $expectedName, $expectedInput] + $tests = []; + $inputTypes = $this->inputProvider(); + + // Default $name argument (null) + foreach ($inputTypes as $inputTypeDescription => $inputTypeData) { + $description = $inputTypeDescription . ' - null'; + + $tests[$description] = [$inputTypeData[0], null, $inputTypeData[1], $inputTypeData[2]]; + } + + // Custom $name argument + foreach ($inputTypes as $inputTypeDescription => $inputTypeData) { + static $customInputName = 'custom_name'; + + $description = $inputTypeDescription . ' - ' . $customInputName; + + $tests[$description] = [$inputTypeData[0], $customInputName, $customInputName, $inputTypeData[2]]; + } + + return $tests; + } + + public function inputProvider() + { + $input = $this->createInputInterfaceMock('fooInput', null); + $inputFilter = $this->createInputFilterInterfaceMock(); + + return [ + // Description => [input, name, expected name, $expectedReturnInput] + 'InputInterface' => [$input, 'fooInput', $input], + 'InputFilterInterface' => [$inputFilter, null, $inputFilter], + ]; + } + + /** + * @return MockObject|InputFilterInterface + */ + protected function createInputFilterInterfaceMock() + { + /** @var InputFilterInterface|MockObject $inputFilter */ + $inputFilter = $this->getMock(InputFilterInterface::class); + + return $inputFilter; + } + /** + * @param string $name + * @param bool $isRequired * @param null|bool $isValid * @param mixed $expectedContext * @param mixed $getRawValue * * @return MockObject|InputInterface */ - protected function createInputInterfaceMock($isRequired, $isValid = null, $expectedContext = 'not-set', $getRawValue = 'not-set') + protected function createInputInterfaceMock( + $name, + $isRequired, + $isValid = null, + $expectedContext = 'not-set', + $getRawValue = 'not-set') { /** @var InputInterface|MockObject $input */ $input = $this->getMock(InputInterface::class); + $input->method('getName') + ->willReturn($name) + ; $input->method('isRequired') ->willReturn($isRequired) ; From 161aef7764d80d0fb0668255808c0f122da681ff Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 08:34:02 +0200 Subject: [PATCH 02/22] Remove legacy tests --- test/BaseInputFilterTest.php | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 712ce895..e3563583 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -230,17 +230,6 @@ public function testAddRemove($input, $name, $expectedInputName) $this->assertCount($currentNumberOfFilters - 1, $inputFilter, 'Number of filters must be decreased by 1'); } - public function testAddingInputsIncreasesCountOfFilter() - { - $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)); - } - public function testAddingInputWithNameDoesNotInjectNameInInput() { $inputFilter = $this->getInputFilter(); @@ -253,26 +242,6 @@ public function testAddingInputWithNameDoesNotInjectNameInInput() $this->assertEquals('foo', $foo->getName(), 'Input name should not change'); } - public function testCanAddInputFilterAsInput() - { - $parent = new InputFilter(); - $child = new InputFilter(); - $parent->add($child, 'child'); - $this->assertEquals(1, count($parent)); - $this->assertSame($child, $parent->get('child')); - } - - 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)); - } - public function getInputFilter() { $filter = new InputFilter(); From 6f1bba6bd3ebddc65a2a97c7f276051479c6eb3b Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 17 Aug 2015 10:23:45 +0200 Subject: [PATCH 03/22] Test for BaseInputFilter replace --- test/BaseInputFilterTest.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index e3563583..7c8d14ec 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -242,6 +242,26 @@ public function testAddingInputWithNameDoesNotInjectNameInInput() $this->assertEquals('foo', $foo->getName(), 'Input name should not change'); } + /** + * @dataProvider inputProvider + */ + public function testReplace($input, $inputName, $expectedInput) + { + $inputFilter = new InputFilter(); + $nameToReplace = 'replace_me'; + $inputToReplace = new Input($nameToReplace); + + $inputFilter->add($inputToReplace); + $currentNumberOfFilters = count($inputFilter); + + $return = $inputFilter->replace($input, $nameToReplace); + $this->assertSame($inputFilter, $return, 'replace() must return it self'); + $this->assertCount($currentNumberOfFilters, $inputFilter, "Number of filters shouldn't change"); + + $returnInput = $inputFilter->get($nameToReplace); + $this->assertEquals($expectedInput, $returnInput, 'get() does not match the expected input'); + } + public function getInputFilter() { $filter = new InputFilter(); From 70bb6764db4387537396900e46f141494344792b Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 08:51:29 +0200 Subject: [PATCH 04/22] Improve readibility of test data provider --- test/BaseInputFilterTest.php | 44 ++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 7c8d14ec..95e5abc2 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -1231,27 +1231,41 @@ public function testAllowsValidatingArrayAccessData() public function addMethodArgumentsProvider() { - // Description => [$input argument, $name argument, $expectedName, $expectedInput] - $tests = []; $inputTypes = $this->inputProvider(); - // Default $name argument (null) - foreach ($inputTypes as $inputTypeDescription => $inputTypeData) { - $description = $inputTypeDescription . ' - null'; - - $tests[$description] = [$inputTypeData[0], null, $inputTypeData[1], $inputTypeData[2]]; - } + $inputName = function ($inputTypeData) { + return $inputTypeData[1]; + }; - // Custom $name argument - foreach ($inputTypes as $inputTypeDescription => $inputTypeData) { - static $customInputName = 'custom_name'; + $sameInput = function ($inputTypeData) { + return $inputTypeData[2]; + }; - $description = $inputTypeDescription . ' - ' . $customInputName; + // @codingStandardsIgnoreStart + $dataTemplates=[ + // Description => [[$input argument], $name argument, $expectedName, $expectedInput] + 'null' => [$inputTypes, null , $inputName , $sameInput], + 'custom_name' => [$inputTypes, 'custom_name', 'custom_name', $sameInput], + ]; + // @codingStandardsIgnoreEnd - $tests[$description] = [$inputTypeData[0], $customInputName, $customInputName, $inputTypeData[2]]; + // Expand data template matrix for each possible input type. + // Description => [$input argument, $name argument, $expectedName, $expectedInput] + $dataSets = []; + 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; + } } - return $tests; + return $dataSets; } public function inputProvider() @@ -1260,7 +1274,7 @@ public function inputProvider() $inputFilter = $this->createInputFilterInterfaceMock(); return [ - // Description => [input, name, expected name, $expectedReturnInput] + // Description => [input, expected name, $expectedReturnInput] 'InputInterface' => [$input, 'fooInput', $input], 'InputFilterInterface' => [$inputFilter, null, $inputFilter], ]; From fa4db2cd87d1a64c1d53a6a86704f50c448c60a9 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 09:20:59 +0200 Subject: [PATCH 05/22] CS: Remove BaseInputFilter alias and use setUp --- test/BaseInputFilterTest.php | 102 +++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 95e5abc2..550c4925 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -15,7 +15,7 @@ use stdClass; use Zend\Filter; use Zend\InputFilter\ArrayInput; -use Zend\InputFilter\BaseInputFilter as InputFilter; +use Zend\InputFilter\BaseInputFilter; use Zend\InputFilter\Exception\InvalidArgumentException; use Zend\InputFilter\Exception\RuntimeException; use Zend\InputFilter\FileInput; @@ -29,15 +29,25 @@ */ class BaseInputFilterTest extends TestCase { + /** + * @var BaseInputFilter + */ + protected $inputFilter; + + public function setUp() + { + $this->inputFilter = new BaseInputFilter(); + } + public function testInputFilterIsEmptyByDefault() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $this->assertEquals(0, count($filter)); } public function testAddWithInvalidInputTypeThrowsInvalidArgumentException() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( InvalidArgumentException::class, @@ -50,7 +60,7 @@ public function testAddWithInvalidInputTypeThrowsInvalidArgumentException() public function testGetThrowExceptionIfInputDoesNotExists() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( InvalidArgumentException::class, @@ -61,7 +71,7 @@ public function testGetThrowExceptionIfInputDoesNotExists() public function testReplaceWithInvalidInputTypeThrowsInvalidArgumentException() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $inputFilter->add(new Input('foo'), 'replace_me'); $this->setExpectedException( @@ -75,7 +85,7 @@ public function testReplaceWithInvalidInputTypeThrowsInvalidArgumentException() public function testReplaceThrowExceptionIfInputToReplaceDoesNotExists() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( InvalidArgumentException::class, @@ -86,7 +96,7 @@ public function testReplaceThrowExceptionIfInputToReplaceDoesNotExists() public function testGetValueThrowExceptionIfInputDoesNotExists() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( InvalidArgumentException::class, @@ -97,7 +107,7 @@ public function testGetValueThrowExceptionIfInputDoesNotExists() public function testGetRawValueThrowExceptionIfInputDoesNotExists() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( InvalidArgumentException::class, @@ -108,7 +118,7 @@ public function testGetRawValueThrowExceptionIfInputDoesNotExists() public function testSetDataWithInvalidDataTypeThrowsInvalidArgumentException() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( InvalidArgumentException::class, @@ -120,7 +130,7 @@ public function testSetDataWithInvalidDataTypeThrowsInvalidArgumentException() public function testIsValidThrowExceptionIfDataWasNotSetYet() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( RuntimeException::class, @@ -131,7 +141,7 @@ public function testIsValidThrowExceptionIfDataWasNotSetYet() public function testSetValidationGroupThrowExceptionIfInputIsNotAnInputFilter() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; /** @var InputInterface|MockObject $nestedInput */ $nestedInput = $this->getMock(InputInterface::class); @@ -146,7 +156,7 @@ public function testSetValidationGroupThrowExceptionIfInputIsNotAnInputFilter() public function testSetValidationGroupThrowExceptionIfInputFilterNotExists() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( InvalidArgumentException::class, @@ -157,7 +167,7 @@ public function testSetValidationGroupThrowExceptionIfInputFilterNotExists() public function testSetValidationGroupThrowExceptionIfInputFilterInArgumentListNotExists() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( InvalidArgumentException::class, @@ -168,7 +178,7 @@ public function testSetValidationGroupThrowExceptionIfInputFilterInArgumentListN public function testHasUnknownThrowExceptionIfDataWasNotSetYet() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( RuntimeException::class @@ -178,7 +188,7 @@ public function testHasUnknownThrowExceptionIfDataWasNotSetYet() public function testGetUnknownThrowExceptionIfDataWasNotSetYet() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->setExpectedException( RuntimeException::class @@ -193,7 +203,7 @@ public function testGetUnknownThrowExceptionIfDataWasNotSetYet() */ public function testAddHasGet($input, $name, $expectedInputName, $expectedInput) { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $this->assertFalse( $inputFilter->has($expectedInputName), "InputFilter shouldn't have an input with the name $expectedInputName yet" @@ -218,7 +228,7 @@ public function testAddHasGet($input, $name, $expectedInputName, $expectedInput) */ public function testAddRemove($input, $name, $expectedInputName) { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $inputFilter->add($input, $name); $currentNumberOfFilters = count($inputFilter); @@ -232,7 +242,7 @@ public function testAddRemove($input, $name, $expectedInputName) public function testAddingInputWithNameDoesNotInjectNameInInput() { - $inputFilter = $this->getInputFilter(); + $inputFilter = $this->inputFilter; $foo = new Input('foo'); $inputFilter->add($foo, 'bas'); @@ -247,7 +257,7 @@ public function testAddingInputWithNameDoesNotInjectNameInInput() */ public function testReplace($input, $inputName, $expectedInput) { - $inputFilter = new InputFilter(); + $inputFilter = $this->inputFilter; $nameToReplace = 'replace_me'; $inputToReplace = new Input($nameToReplace); @@ -264,7 +274,7 @@ public function testReplace($input, $inputName, $expectedInput) public function getInputFilter() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new Input(); $foo->getFilterChain()->attachByName('stringtrim') @@ -296,7 +306,7 @@ public function getInputFilter() public function getChildInputFilter() { - $filter = new InputFilter(); + $filter = new BaseInputFilter(); $foo = new Input(); $foo->getFilterChain()->attachByName('stringtrim') @@ -428,16 +438,16 @@ public function testResetEmptyValidationGroupRecursively() 'deep-input2' => 'deep-foo2', ] ]; - $filter = new InputFilter; + $filter = $this->inputFilter; $filter->add(new Input, 'flat'); - $deepInputFilter = new InputFilter; + $deepInputFilter = new BaseInputFilter; $deepInputFilter->add(new Input, 'deep-input1'); $deepInputFilter->add(new Input, 'deep-input2'); $filter->add($deepInputFilter, 'deep'); $filter->setData($data); $filter->setValidationGroup(['deep' => 'deep-input1']); // reset validation group - $filter->setValidationGroup(InputFilter::VALIDATE_ALL); + $filter->setValidationGroup(InputFilterInterface::VALIDATE_ALL); $this->assertEquals($data, $filter->getValues()); } @@ -639,7 +649,7 @@ public function contextProvider() */ public function testValidationContext($data, $customContext, $expectedContext) { - $filter = new InputFilter(); + $filter = $this->inputFilter; $input = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext); $filter->add($input, 'fooInput'); @@ -656,7 +666,7 @@ public function testBuildValidationContextUsingInputGetRawValue() { $data = []; $expectedContext = ['fooInput' => 'fooRawValue']; - $filter = new InputFilter(); + $filter = $this->inputFilter; $input = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext, 'fooRawValue'); $filter->add($input, 'fooInput'); @@ -681,7 +691,7 @@ public function testContextIsTheSameWhenARequiredInputIsGivenAndOptionalInputIsM $inputRequired = $this->createInputInterfaceMock('fooInput', true, true, $expectedContext); $inputOptional = $this->createInputInterfaceMock('fooInput', false); - $filter = new InputFilter(); + $filter = $this->inputFilter; $filter->add($inputRequired, 'inputRequired'); $filter->add($inputOptional, 'inputOptional'); @@ -699,7 +709,7 @@ public function testContextIsTheSameWhenARequiredInputIsGivenAndOptionalInputIsM */ public function testInputBreakOnFailureFlagIsHonoredWhenValidating() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $store = new stdClass; $foo = new Input(); @@ -726,7 +736,7 @@ public function testInputBreakOnFailureFlagIsHonoredWhenValidating() public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $optionalInputName = 'fooOptionalInput'; /** @var InputInterface|MockObject $optionalInput */ @@ -758,7 +768,7 @@ public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent() public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoFileDataIsPresent() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new FileInput(); $foo->getValidatorChain()->attach(new Validator\File\UploadFile()); @@ -786,7 +796,7 @@ public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoFileDataIsPr public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoMultiFileDataIsPresent() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new FileInput(); $foo->setRequired(false); $filter->add($foo, 'foo'); @@ -811,7 +821,7 @@ public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoMultiFileDat public function testValidationAllowsEmptyValuesToRequiredInputWhenAllowEmptyFlagIsTrue() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new Input('foo'); $foo->getValidatorChain()->attach(new Validator\StringLength(3, 5)); @@ -838,7 +848,7 @@ public function testValidationAllowsEmptyValuesToRequiredInputWhenAllowEmptyFlag public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFalse() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new Input(); $foo->getValidatorChain()->attach(new Validator\StringLength(3, 5)); @@ -900,7 +910,7 @@ public function testCanRetrieveUnvalidatedButFilteredInputValue() public function testGetRequiredNotEmptyValidationMessages() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new Input(); $foo->setRequired(true); @@ -975,7 +985,7 @@ public function testGetUknown() public function testValidateUseExplodeAndInstanceOf() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $input = new Input(); $input->setRequired(true); @@ -1006,7 +1016,7 @@ public function testValidateUseExplodeAndInstanceOf() public function testGetInputs() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new Input('foo'); $bar = new Input('bar'); @@ -1026,7 +1036,7 @@ public function testGetInputs() */ public function testAddingExistingInputWillMergeIntoExisting() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo1 = new Input('foo'); $foo1->setRequired(true); @@ -1045,7 +1055,7 @@ public function testAddingExistingInputWillMergeIntoExisting() */ public function testIsValidWhenValuesSetOnFilters() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new Input(); $foo->getFilterChain()->attachByName('stringtrim') @@ -1085,7 +1095,7 @@ public function testPopulateSupportsArrayInputEvenIfDataMissing() ->method('setValue') ->with([]); - $filter = new InputFilter(); + $filter = $this->inputFilter; $filter->add($arrayInput, 'arrayInput'); $filter->setData(['foo' => 'bar']); } @@ -1095,8 +1105,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'); @@ -1129,7 +1139,7 @@ public function testAllowEmptyTestsFilteredValueAndOverrulesValidatorChain() return false; })); - $filter = new InputFilter(); + $filter = $this->inputFilter; $filter->add($input) ->setData(['foo' => 'nonempty']); @@ -1151,7 +1161,7 @@ public function testAllowEmptyTestsFilteredValueAndContinuesIfEmpty() return false; })); - $filter = new InputFilter(); + $filter = $this->inputFilter; $filter->add($input) ->setData(['foo' => 'nonempty']); @@ -1171,7 +1181,7 @@ public function testMissingRequiredAllowedEmptyValueShouldMarkInputFilterInvalid $bar->setRequired(true); $bar->setAllowEmpty(true); - $filter = new InputFilter(); + $filter = $this->inputFilter; $filter->add($foo); $filter->add($bar); @@ -1201,7 +1211,7 @@ public function testEmptyValuePassedForRequiredButAllowedEmptyInputShouldMarkInp $bar->setRequired(true); $bar->setAllowEmpty(true); - $filter = new InputFilter(); + $filter = $this->inputFilter; $filter->add($foo); $filter->add($bar); @@ -1217,7 +1227,7 @@ public function testEmptyValuePassedForRequiredButAllowedEmptyInputShouldMarkInp */ public function testAllowsValidatingArrayAccessData() { - $filter = new InputFilter(); + $filter = $this->inputFilter; $foo = new Input(); $foo->getFilterChain()->attachByName('stringtrim') ->attachByName('alpha'); From 75913bbae1052a770ad8c834155bfdde755ae7bb Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 09:21:26 +0200 Subject: [PATCH 06/22] CS: Data set table --- test/BaseInputFilterTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 550c4925..d812df5b 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -1283,11 +1283,13 @@ public function inputProvider() $input = $this->createInputInterfaceMock('fooInput', null); $inputFilter = $this->createInputFilterInterfaceMock(); + // @codingStandardsIgnoreStart return [ // Description => [input, expected name, $expectedReturnInput] - 'InputInterface' => [$input, 'fooInput', $input], - 'InputFilterInterface' => [$inputFilter, null, $inputFilter], + 'InputInterface' => [$input , 'fooInput', $input], + 'InputFilterInterface' => [$inputFilter, null , $inputFilter], ]; + // @codingStandardsIgnoreEnd } /** From b5b2c68214e5b8826d1edef5ef8953d0f4e2c975 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 09:24:00 +0200 Subject: [PATCH 07/22] Make InputFilterTest extend from BaseInputFilterTest Also clean the test from old test (context is already consolidate), use mocks and data provider --- test/InputFilterTest.php | 81 ++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/test/InputFilterTest.php b/test/InputFilterTest.php index bda69a06..0deb5f37 100644 --- a/test/InputFilterTest.php +++ b/test/InputFilterTest.php @@ -9,50 +9,39 @@ namespace ZendTest\InputFilter; +use ArrayIterator; use PHPUnit_Framework_MockObject_MockObject as MockObject; -use PHPUnit_Framework_TestCase as TestCase; use Zend\InputFilter\CollectionInputFilter; use Zend\InputFilter\Factory; use Zend\InputFilter\Input; use Zend\InputFilter\InputFilter; -use Zend\InputFilter\InputInterface; /** * @covers Zend\InputFilter\InputFilter */ -class InputFilterTest extends TestCase +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(Factory::class, $factory); } public function testCanComposeAFactory() { - $factory = new Factory(); - $this->filter->setFactory($factory); - $this->assertSame($factory, $this->filter->getFactory()); - } - - public function testCanAddUsingSpecification() - { - $this->filter->add([ - 'name' => 'foo', - ]); - $this->assertTrue($this->filter->has('foo')); - $foo = $this->filter->get('foo'); - $this->assertInstanceOf(InputInterface::class, $foo); + $factory = $this->createFactoryMock(); + $this->inputFilter->setFactory($factory); + $this->assertSame($factory, $this->inputFilter->getFactory()); } /** @@ -65,7 +54,7 @@ public function testGetValueReturnsArrayIfNestedInputFilters() $inputFilter = new InputFilter(); $inputFilter->add(new Input(), 'name'); - $this->filter->add($inputFilter, 'people'); + $this->inputFilter->add($inputFilter, 'people'); $data = [ 'people' => [ @@ -73,10 +62,10 @@ public function testGetValueReturnsArrayIfNestedInputFilters() ] ]; - $this->filter->setData($data); - $this->assertTrue($this->filter->isValid()); + $this->inputFilter->setData($data); + $this->assertTrue($this->inputFilter->isValid()); - $this->assertInternalType('array', $this->filter->getValue('people')); + $this->assertInternalType('array', $this->inputFilter->getValue('people')); } /** @@ -91,7 +80,7 @@ public function testCountZeroValidateInternalInputWithCollectionInputFilter() $collection->setInputFilter($inputFilter); $collection->setCount(0); - $this->filter->add($collection, 'people'); + $this->inputFilter->add($collection, 'people'); $data = [ 'people' => [ @@ -100,24 +89,44 @@ public function testCountZeroValidateInternalInputWithCollectionInputFilter() ], ], ]; - $this->filter->setData($data); + $this->inputFilter->setData($data); - $this->assertTrue($this->filter->isvalid()); - $this->assertSame($data, $this->filter->getValues()); + $this->assertTrue($this->inputFilter->isvalid()); + $this->assertSame($data, $this->inputFilter->getValues()); } - public function testCanUseContextPassedToInputFilter() + public function inputProvider() { - $context = new \stdClass(); + $dataSets = parent::inputProvider(); - /** @var InputInterface|MockObject $input */ - $input = $this->getMock(InputInterface::class); - $input->expects($this->once())->method('isValid')->with($context)->will($this->returnValue(true)); - $input->expects($this->any())->method('getRawValue')->will($this->returnValue('Mwop')); + $inputSpecificationAsArray = [ + 'name' => 'inputFoo', + ]; + $inputSpecificationAsTraversable = new ArrayIterator($inputSpecificationAsArray); + + $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 - $this->filter->add($input, 'username'); - $this->filter->setData(['username' => 'Mwop']); + // @codingStandardsIgnoreStart + $dataSets = array_merge($dataSets, [ + // Description => [input, expected name, $expectedReturnInput] + 'array' => [$inputSpecificationAsArray , 'inputFoo', $inputSpecificationResult], + 'Traversable' => [$inputSpecificationAsTraversable , 'inputFoo', $inputSpecificationResult], + ]); + // @codingStandardsIgnoreEnd + + return $dataSets; + } + + /** + * @return Factory|MockObject + */ + protected function createFactoryMock() + { + /** @var Factory|MockObject $factory */ + $factory = $this->getMock(Factory::class); - $this->filter->isValid($context); + return $factory; } } From 11dff965c0f7252ad3fc688446e2ae9f87226c17 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 09:25:34 +0200 Subject: [PATCH 08/22] Fix exception name --- src/InputFilterInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InputFilterInterface.php b/src/InputFilterInterface.php index f2850315..40550169 100644 --- a/src/InputFilterInterface.php +++ b/src/InputFilterInterface.php @@ -24,7 +24,7 @@ interface InputFilterInterface extends Countable * raise an exception for any they cannot process. * @param null|string $name Name used to retrieve this input * @return InputFilterInterface - * @throws Exception\InvalidArgumentInterface if unable to handle the input type. + * @throws Exception\InvalidArgumentException if unable to handle the input type. */ public function add($input, $name = null); From 97bc9a43006e9caa4248da367c07e3ed7357b722 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 09:27:47 +0200 Subject: [PATCH 09/22] Feature: Allow replace input with the same types allowed in add method InputFilter allow more types of inputs (specification arrays) and have sense to allow it too in replace method --- src/BaseInputFilter.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 550245c9..0abf377c 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -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 * @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__, - InputInterface::class, - InputFilterInterface::class, - (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; } From 8fda1dc32cf9036bf4a8aa64067feaa86ac76982 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 09:28:09 +0200 Subject: [PATCH 10/22] Improve exception description --- src/BaseInputFilter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 0abf377c..c409d38d 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -108,7 +108,7 @@ public function add($input, $name = null) * * @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) From 858918395c6367ffbf410ff0c1ba1e2b3579b43d Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 09:30:09 +0200 Subject: [PATCH 11/22] CS Fix --- test/InputFilterTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/InputFilterTest.php b/test/InputFilterTest.php index 0deb5f37..9bcc75fc 100644 --- a/test/InputFilterTest.php +++ b/test/InputFilterTest.php @@ -109,12 +109,13 @@ public function inputProvider() $inputSpecificationResult->getValidatorChain(); // Fill input with a default chain just for make the test pass // @codingStandardsIgnoreStart - $dataSets = array_merge($dataSets, [ + $inputFilterDataSets = [ // Description => [input, expected name, $expectedReturnInput] 'array' => [$inputSpecificationAsArray , 'inputFoo', $inputSpecificationResult], 'Traversable' => [$inputSpecificationAsTraversable , 'inputFoo', $inputSpecificationResult], - ]); + ]; // @codingStandardsIgnoreEnd + $dataSets = array_merge($dataSets, $inputFilterDataSets); return $dataSets; } From f8057ce71129eb248aff07fbdb96cb21924b0995 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 11:34:27 +0200 Subject: [PATCH 12/22] CS --- test/InputFilterTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/InputFilterTest.php b/test/InputFilterTest.php index 9bcc75fc..c69c9d6a 100644 --- a/test/InputFilterTest.php +++ b/test/InputFilterTest.php @@ -111,8 +111,8 @@ public function inputProvider() // @codingStandardsIgnoreStart $inputFilterDataSets = [ // Description => [input, expected name, $expectedReturnInput] - 'array' => [$inputSpecificationAsArray , 'inputFoo', $inputSpecificationResult], - 'Traversable' => [$inputSpecificationAsTraversable , 'inputFoo', $inputSpecificationResult], + 'array' => [$inputSpecificationAsArray , 'inputFoo', $inputSpecificationResult], + 'Traversable' => [$inputSpecificationAsTraversable, 'inputFoo', $inputSpecificationResult], ]; // @codingStandardsIgnoreEnd $dataSets = array_merge($dataSets, $inputFilterDataSets); From e3f4c384da50abe4f2589f5e64f2152b4b1b7a93 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 11:29:54 +0200 Subject: [PATCH 13/22] Move test to the correct class --- test/CollectionInputFilterTest.php | 4 ++++ test/InputFilterTest.php | 28 ---------------------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/test/CollectionInputFilterTest.php b/test/CollectionInputFilterTest.php index ad4ebd1e..e1e08674 100644 --- a/test/CollectionInputFilterTest.php +++ b/test/CollectionInputFilterTest.php @@ -723,6 +723,10 @@ public function dataNestingCollection() 'count' => null, 'isValid' => true ], + 'count=0' => [ + 'count' => 0, + 'isValid' => true + ], 'count = 1' => [ 'count' => 1, 'isValid' => true diff --git a/test/InputFilterTest.php b/test/InputFilterTest.php index c69c9d6a..1b4df9a5 100644 --- a/test/InputFilterTest.php +++ b/test/InputFilterTest.php @@ -11,7 +11,6 @@ use ArrayIterator; use PHPUnit_Framework_MockObject_MockObject as MockObject; -use Zend\InputFilter\CollectionInputFilter; use Zend\InputFilter\Factory; use Zend\InputFilter\Input; use Zend\InputFilter\InputFilter; @@ -68,33 +67,6 @@ public function testGetValueReturnsArrayIfNestedInputFilters() $this->assertInternalType('array', $this->inputFilter->getValue('people')); } - /** - * @group ZF2-5648 - */ - public function testCountZeroValidateInternalInputWithCollectionInputFilter() - { - $inputFilter = new InputFilter(); - $inputFilter->add(new Input(), 'name'); - - $collection = new CollectionInputFilter(); - $collection->setInputFilter($inputFilter); - $collection->setCount(0); - - $this->inputFilter->add($collection, 'people'); - - $data = [ - 'people' => [ - [ - 'name' => 'Wanderson', - ], - ], - ]; - $this->inputFilter->setData($data); - - $this->assertTrue($this->inputFilter->isvalid()); - $this->assertSame($data, $this->inputFilter->getValues()); - } - public function inputProvider() { $dataSets = parent::inputProvider(); From 4cafeed0e3673766ac65dd52e348fbd1288311bc Mon Sep 17 00:00:00 2001 From: Maks3w Date: Sun, 16 Aug 2015 11:15:09 +0200 Subject: [PATCH 14/22] Consolidate tests for InputFilterInterface (isValid, getXValues, getMessages, getXInputs) --- test/BaseInputFilterTest.php | 246 +++++++++++++++++++++++++++++++++-- 1 file changed, 232 insertions(+), 14 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index d812df5b..c18f92a7 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -9,7 +9,9 @@ namespace ZendTest\InputFilter; +use ArrayIterator; use ArrayObject; +use FilterIterator; use PHPUnit_Framework_MockObject_MockObject as MockObject; use PHPUnit_Framework_TestCase as TestCase; use stdClass; @@ -272,6 +274,104 @@ public function testReplace($input, $inputName, $expectedInput) $this->assertEquals($expectedInput, $returnInput, 'get() does not match the expected input'); } + /** + * @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 + ); + } + + $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 + ); + } + + // ** 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'); + } + + /** + * @dataProvider setDataArgumentsProvider + */ + public function testSetArrayAccessDataAndGetRawValueGetValue( + $inputs, + $data, + $expectedRawValues, + $expectedValues, + $expectedIsValid, + $expectedInvalidInputs, + $expectedValidInputs, + $expectedMessages + ) { + $dataTypes = $this->dataTypes(); + $this->testSetDataAndGetRawValueGetValue( + $inputs, + $dataTypes['ArrayAccess']($data), + $expectedRawValues, + $expectedValues, + $expectedIsValid, + $expectedInvalidInputs, + $expectedValidInputs, + $expectedMessages + ); + } + + /** + * @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 + ); + } + public function getInputFilter() { $filter = $this->inputFilter; @@ -1278,6 +1378,86 @@ public function addMethodArgumentsProvider() return $dataSets; } + public function setDataArgumentsProvider() + { + $iAName = 'InputA'; + $iBName = 'InputB'; + $vRaw = 'rawValue'; + $vFiltered = 'filteredValue'; + + $dARaw = [$iAName => $vRaw]; + $dBRaw = [$iBName => $vRaw]; + $d2Raw = array_merge($dARaw, $dBRaw); + $dAFiltered = [$iAName => $vFiltered]; + $dBFiltered = [$iBName => $vFiltered]; + $d2Filtered = array_merge($dAFiltered, $dBFiltered); + + $required = true; + $valid = true; + $bOnFail = true; + + $input = function ($iName, $required, $bOnFail, $isValid, $msg = []) use ($vRaw, $vFiltered) { + // @codingStandardsIgnoreStart + return function ($context) use ($iName, $required, $bOnFail, $isValid, $vRaw, $vFiltered, $msg) { + return $this->createInputInterfaceMock($iName, $required, $isValid, $context, $vRaw, $vFiltered, $msg, $bOnFail); + }; + // @codingStandardsIgnoreEnd + }; + + // @codingStandardsIgnoreStart + $iAri = [$iAName => $input($iAName, $required, !$bOnFail, !$valid, ['Invalid ' . $iAName])]; + $iAriX = [$iAName => $input($iAName, $required, $bOnFail, !$valid, ['Invalid ' . $iAName])]; + $iArvX = [$iAName => $input($iAName, $required, $bOnFail, $valid, [])]; + $iBri = [$iBName => $input($iBName, $required, !$bOnFail, !$valid, ['Invalid ' . $iBName])]; + $iBriX = [$iBName => $input($iBName, $required, $bOnFail, !$valid, ['Invalid ' . $iBName])]; + $iBrvX = [$iBName => $input($iBName, $required, $bOnFail, $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); + + $msgAInv = [$iAName => ['Invalid InputA']]; + $msgBInv = [$iBName => ['Invalid InputB']]; + $msg2Inv = array_merge($msgAInv, $msgBInv); + + $dataSets = [ + // Description => [$inputs, $data argument, $expectedRawValues, $expectedValues, $expectedIsValid, + // $expectedInvalidInputs, $expectedValidInputs, $expectedMessages] + 'invalid Break invalid' => [$iAriXBriX, $d2Raw, $d2Raw, $d2Filtered, false, $iAri , [] , $msgAInv], + 'invalid Break valid' => [$iAriXBrvX, $d2Raw, $d2Raw, $d2Filtered, false, $iAri , [] , $msgAInv], + 'valid Break invalid' => [$iArvXBriX, $d2Raw, $d2Raw, $d2Filtered, false, $iBri , $iAri , $msgBInv], + 'valid Break valid' => [$iArvXBrvX, $d2Raw, $d2Raw, $d2Filtered, true , [] , $iArvXBrvX, []], + 'valid invalid' => [$iArvXBir , $d2Raw, $d2Raw, $d2Filtered, false, $iBri , $iArvX , $msgBInv], + 'invalid valid' => [$iAriBrvX , $d2Raw, $d2Raw, $d2Filtered, false, $iAri , $iBrvX , $msgAInv], + 'invalid invalid' => [$iAriBri , $d2Raw, $d2Raw, $d2Filtered, false, $iAriBri , [] , $msg2Inv], + 'invalid valid/NotSet' => [$iAriBri , $dARaw, $d2Raw, $d2Filtered, false, $iAriBrvX, [] , $msg2Inv], + ]; + // @codingStandardsIgnoreEnd + + array_walk( + $dataSets, + function (&$set) { + // Create unique mock input instances for each set + foreach ($set[0] as $name => $createMock) { + $input = $createMock($set[2]); + + $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; + } + } + } + ); + + return $dataSets; + } + public function inputProvider() { $input = $this->createInputInterfaceMock('fooInput', null); @@ -1307,8 +1487,11 @@ protected function createInputFilterInterfaceMock() * @param string $name * @param bool $isRequired * @param null|bool $isValid - * @param mixed $expectedContext + * @param mixed $context * @param mixed $getRawValue + * @param mixed $getValue + * @param string[] $getMessages + * @param bool $breakOnFailure * * @return MockObject|InputInterface */ @@ -1316,9 +1499,12 @@ protected function createInputInterfaceMock( $name, $isRequired, $isValid = null, - $expectedContext = 'not-set', - $getRawValue = 'not-set') - { + $context = null, + $getRawValue = null, + $getValue = null, + $getMessages = [], + $breakOnFailure = false + ) { /** @var InputInterface|MockObject $input */ $input = $this->getMock(InputInterface::class); $input->method('getName') @@ -1327,21 +1513,53 @@ protected function createInputInterfaceMock( $input->method('isRequired') ->willReturn($isRequired) ; - if ($getRawValue !== 'not-set') { - $input->method('getRawValue') - ->willReturn($getRawValue) - ; - } - if ($isValid !== null) { - $mockMethod = $input->expects($this->once()) + $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) ; - if ($expectedContext !== 'not-set') { - $mockMethod->with($expectedContext); - } + } else { + $input->expects($this->never()) + ->method('isValid') + ->with($context) + ; } + $input->method('getMessages') + ->willReturn($getMessages) + ; return $input; } + + /** + * @return callable[] + */ + protected function dataTypes() + { + return [ + // Description => callable + 'array' => function ($data) { + return $data; + }, + 'ArrayAccess' => function ($data) { + return new ArrayIterator($data); + }, + 'Traversable' => function ($data) { + return $this->getMockBuilder(FilterIterator::class) + ->setConstructorArgs([new ArrayIterator($data)]) + ->getMock() + ; + }, + ]; + } } From 1d88c702be5ebde15a222bc048ca3e703f0b5166 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 17:37:19 +0200 Subject: [PATCH 15/22] Remove legacy tests --- test/BaseInputFilterTest.php | 613 ----------------------------------- 1 file changed, 613 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index c18f92a7..0e39f86c 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -20,7 +20,6 @@ use Zend\InputFilter\BaseInputFilter; use Zend\InputFilter\Exception\InvalidArgumentException; use Zend\InputFilter\Exception\RuntimeException; -use Zend\InputFilter\FileInput; use Zend\InputFilter\Input; use Zend\InputFilter\InputFilterInterface; use Zend\InputFilter\InputInterface; @@ -428,107 +427,6 @@ public function getChildInputFilter() return $filter; } - public function dataSets() - { - return [ - 'valid-with-empty-and-null' => [ - [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'baz' => null, - 'qux' => '', - 'nest' => [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'baz' => null, - ], - ], - true, - ], - 'valid-with-empty' => [ - [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'qux' => '', - 'nest' => [ - 'foo' => ' bazbat ', - 'bar' => '12345', - ], - ], - true, - ], - 'invalid-with-empty-and-missing' => [ - [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'baz' => 'thisistoolong', - 'nest' => [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'baz' => 'thisistoolong', - ], - ], - false, - ], - 'invalid-with-empty' => [ - [ - 'foo' => ' baz bat ', - 'bar' => 'abc45', - 'baz' => ' ', - 'qux' => ' ', - 'nest' => [ - 'foo' => ' baz bat ', - 'bar' => '123ab', - 'baz' => ' ', - ], - ], - false, - ], - ]; - } - - /** - * @dataProvider dataSets - * @group fmlife - */ - public function testCanValidateEntireDataset($dataset, $expected) - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $filter->setData($dataset); - $this->assertSame($expected, $filter->isValid()); - } - - public function testCanValidatePartialDataset() - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $validData = [ - 'foo' => ' bazbat ', - 'bar' => '12345', - ]; - $filter->setValidationGroup('foo', 'bar'); - $filter->setData($validData); - $this->assertTrue($filter->isValid()); - - $invalidData = [ - 'bar' => 'abc45', - 'nest' => [ - 'foo' => ' 123bat ', - 'bar' => '123ab', - ], - ]; - $filter->setValidationGroup('bar', 'nest'); - $filter->setData($invalidData); - $this->assertFalse($filter->isValid()); - } - public function testResetEmptyValidationGroupRecursively() { $data = [ @@ -551,180 +449,6 @@ public function testResetEmptyValidationGroupRecursively() $this->assertEquals($data, $filter->getValues()); } - public function testCanRetrieveInvalidInputsOnFailedValidation() - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $invalidData = [ - 'foo' => ' bazbat ', - 'bar' => 'abc45', - 'nest' => [ - 'foo' => ' baz bat boo ', - 'bar' => '12345', - ], - ]; - $filter->setData($invalidData); - $this->assertFalse($filter->isValid()); - $invalidInputs = $filter->getInvalidInput(); - $this->assertArrayNotHasKey('foo', $invalidInputs); - $this->assertArrayHasKey('bar', $invalidInputs); - $this->assertInstanceOf(Input::class, $invalidInputs['bar']); - $this->assertArrayHasKey('nest', $invalidInputs/*, var_export($invalidInputs, 1)*/); - $this->assertInstanceOf(InputFilterInterface::class, $invalidInputs['nest']); - $nestInvalids = $invalidInputs['nest']->getInvalidInput(); - $this->assertArrayHasKey('foo', $nestInvalids); - $this->assertInstanceOf(Input::class, $nestInvalids['foo']); - $this->assertArrayNotHasKey('bar', $nestInvalids); - } - - public function testCanRetrieveValidInputsOnFailedValidation() - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $invalidData = [ - 'foo' => ' bazbat ', - 'bar' => 'abc45', - 'nest' => [ - 'foo' => ' baz bat ', - 'bar' => '12345', - ], - ]; - $filter->setData($invalidData); - $this->assertFalse($filter->isValid()); - $validInputs = $filter->getValidInput(); - $this->assertArrayHasKey('foo', $validInputs); - $this->assertInstanceOf(Input::class, $validInputs['foo']); - $this->assertArrayNotHasKey('bar', $validInputs); - $this->assertArrayHasKey('nest', $validInputs); - $this->assertInstanceOf(InputFilterInterface::class, $validInputs['nest']); - $nestValids = $validInputs['nest']->getValidInput(); - $this->assertArrayHasKey('foo', $nestValids); - $this->assertInstanceOf(Input::class, $nestValids['foo']); - $this->assertArrayHasKey('bar', $nestValids); - $this->assertInstanceOf(Input::class, $nestValids['bar']); - } - - public function testValuesRetrievedAreFiltered() - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $validData = [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'qux' => '', - 'nest' => [ - 'foo' => ' bazbat ', - 'bar' => '12345', - ], - ]; - $filter->setData($validData); - $this->assertTrue($filter->isValid()); - $expected = [ - 'foo' => 'bazbat', - 'bar' => '12345', - 'baz' => null, - 'qux' => '', - 'nest' => [ - 'foo' => 'bazbat', - 'bar' => '12345', - 'baz' => null, - ], - ]; - $this->assertEquals($expected, $filter->getValues()); - } - - public function testCanGetRawInputValues() - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $validData = [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'baz' => null, - 'qux' => '', - 'nest' => [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'baz' => null, - ], - ]; - $filter->setData($validData); - $this->assertTrue($filter->isValid()); - $this->assertEquals($validData, $filter->getRawValues()); - } - - public function testCanGetValidationMessages() - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $filter->get('baz')->setRequired(true); - $filter->get('nest')->get('baz')->setRequired(true); - $invalidData = [ - 'foo' => ' bazbat boo ', - 'bar' => 'abc45', - 'baz' => '', - 'nest' => [ - 'foo' => ' baz bat boo ', - 'bar' => '123yz', - 'baz' => '', - ], - ]; - $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)); - } - } - } - /* * 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. @@ -803,37 +527,6 @@ public function testContextIsTheSameWhenARequiredInputIsGivenAndOptionalInputIsM ); } - /** - * 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. - */ - public function testInputBreakOnFailureFlagIsHonoredWhenValidating() - { - $filter = $this->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()); - $bar->setBreakOnFailure(true); - - $filter->add($bar, 'bar') // adding bar first, as we want it to validate first and break the chain - ->add($foo, 'foo'); - - $data = ['bar' => 'bar', 'foo' => 'foo']; - $filter->setData($data); - - $this->assertFalse($filter->isValid()); - $this->assertObjectNotHasAttribute('value', $store); - $this->assertObjectNotHasAttribute('context', $store); - } - public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent() { $filter = $this->inputFilter; @@ -866,167 +559,6 @@ public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent() ); } - public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoFileDataIsPresent() - { - $filter = $this->inputFilter; - - $foo = new FileInput(); - $foo->getValidatorChain()->attach(new Validator\File\UploadFile()); - $foo->setRequired(false); - - $filter->add($foo, 'foo'); - - $data = [ - 'foo' => [ - 'tmp_name' => '/tmp/barfile', - 'name' => 'barfile', - 'type' => 'text', - 'size' => 0, - 'error' => 4, // UPLOAD_ERR_NO_FILE - ] - ]; - $filter->setData($data); - $this->assertTrue($filter->isValid()); - - // Negative test - $foo->setRequired(true); - $filter->setData($data); - $this->assertFalse($filter->isValid()); - } - - public function testValidationSkipsFileInputsMarkedNotRequiredWhenNoMultiFileDataIsPresent() - { - $filter = $this->inputFilter; - $foo = new FileInput(); - $foo->setRequired(false); - $filter->add($foo, 'foo'); - - $data = [ - 'foo' => [[ - 'tmp_name' => '/tmp/barfile', - 'name' => 'barfile', - 'type' => 'text', - 'size' => 0, - 'error' => 4, // UPLOAD_ERR_NO_FILE - ]], - ]; - $filter->setData($data); - $this->assertTrue($filter->isValid()); - - // Negative test - $foo->setRequired(true); - $filter->setData($data); - $this->assertFalse($filter->isValid()); - } - - public function testValidationAllowsEmptyValuesToRequiredInputWhenAllowEmptyFlagIsTrue() - { - $filter = $this->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 = [ - 'bar' => 124, - 'foo' => '', - ]; - - $filter->setData($data); - - $this->assertTrue($filter->isValid()); - $this->assertEquals('', $filter->getValue('foo')); - } - - public function testValidationMarksInputInvalidWhenRequiredAndAllowEmptyFlagIsFalse() - { - $filter = $this->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 = ['bar' => 124]; - $filter->setData($data); - - $this->assertFalse($filter->isValid()); - } - - public function testCanRetrieveRawValuesIndividuallyWithoutValidating() - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $data = [ - 'foo' => ' bazbat ', - 'bar' => '12345', - 'nest' => [ - 'foo' => ' bazbat ', - 'bar' => '12345', - ], - ]; - $filter->setData($data); - $test = $filter->getRawValue('foo'); - $this->assertSame($data['foo'], $test); - } - - public function testCanRetrieveUnvalidatedButFilteredInputValue() - { - if (!extension_loaded('intl')) { - $this->markTestSkipped('ext/intl not enabled'); - } - - $filter = $this->getInputFilter(); - $data = [ - 'foo' => ' baz 2 bat ', - 'bar' => '12345', - 'nest' => [ - 'foo' => ' bazbat ', - 'bar' => '12345', - ], - ]; - $filter->setData($data); - $test = $filter->getValue('foo'); - $this->assertSame('bazbat', $test); - } - - public function testGetRequiredNotEmptyValidationMessages() - { - $filter = $this->inputFilter; - - $foo = new Input(); - $foo->setRequired(true); - $foo->setAllowEmpty(false); - - $filter->add($foo, 'foo'); - - $data = ['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')) { @@ -1083,37 +615,6 @@ public function testGetUknown() $this->assertEquals(0, count($unknown)); } - public function testValidateUseExplodeAndInstanceOf() - { - $filter = $this->inputFilter; - - $input = new Input(); - $input->setRequired(true); - - $input->getValidatorChain()->attach( - new Validator\Explode( - [ - 'validator' => new Validator\IsInstanceOf( - [ - 'className' => Input::class - ] - ) - ] - ) - ); - - $filter->add($input, 'example'); - - $data = [ - 'example' => [ - $input - ] - ]; - - $filter->setData($data); - $this->assertTrue($filter->isValid()); - } - public function testGetInputs() { $filter = $this->inputFilter; @@ -1225,120 +726,6 @@ public function testMerge() ); } - public function testAllowEmptyTestsFilteredValueAndOverrulesValidatorChain() - { - $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 = $this->inputFilter; - $filter->add($input) - ->setData(['foo' => 'nonempty']); - - $this->assertTrue($filter->isValid()); - $this->assertEquals(['foo' => ''], $filter->getValues()); - } - - 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 = $this->inputFilter; - $filter->add($input) - ->setData(['foo' => 'nonempty']); - - $this->assertFalse($filter->isValid()); - } - - /** - * @group 7 - */ - public function testMissingRequiredAllowedEmptyValueShouldMarkInputFilterInvalid() - { - $foo = new Input('foo'); - $foo->setRequired(true); - $foo->setAllowEmpty(false); - - $bar = new Input('bar'); - $bar->setRequired(true); - $bar->setAllowEmpty(true); - - $filter = $this->inputFilter; - $filter->add($foo); - $filter->add($bar); - - $filter->setData(['foo' => 'xyz']); - $this->assertFalse($filter->isValid(), 'Missing required value should mark input filter as invalid'); - } - - public function emptyValuesForValidation() - { - return [ - 'null' => [null], - 'empty-string' => [''], - ]; - } - - /** - * @group 7 - * @dataProvider emptyValuesForValidation - */ - public function testEmptyValuePassedForRequiredButAllowedEmptyInputShouldMarkInputFilterValid($value) - { - $foo = new Input('foo'); - $foo->setRequired(true); - $foo->setAllowEmpty(false); - - $bar = new Input('bar'); - $bar->setRequired(true); - $bar->setAllowEmpty(true); - - $filter = $this->inputFilter; - $filter->add($foo); - $filter->add($bar); - - $filter->setData([ - 'foo' => 'xyz', - 'bar' => $value, - ]); - $this->assertTrue($filter->isValid(), 'Empty value should mark input filter as valid'); - } - - /** - * @group 15 - */ - public function testAllowsValidatingArrayAccessData() - { - $filter = $this->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(['foo' => ' valid ']); - $filter->setData($data); - $this->assertTrue($filter->isValid()); - } - public function addMethodArgumentsProvider() { $inputTypes = $this->inputProvider(); From 2d18e153c2548c516ea35625b39f576f2aff0e54 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 17:50:12 +0200 Subject: [PATCH 16/22] Add asserts for unknown fields --- test/BaseInputFilterTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 0e39f86c..5853154c 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -317,6 +317,10 @@ public function testSetDataAndGetRawValueGetValue( $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'); + + // ** Check unknown fields ** + $this->assertFalse($inputFilter->hasUnknown(), 'hasUnknown() value not match'); + $this->assertEmpty($inputFilter->getUnknown(), 'getUnknown() value not match'); } /** From bf952c4a2d8945f86354a10f6410e60f9a571b5f Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 18:04:50 +0200 Subject: [PATCH 17/22] Fix $this->data:ArrayAccess fail when hasUnknown/getUnknown --- src/BaseInputFilter.php | 11 +++++------ test/BaseInputFilterTest.php | 33 ++------------------------------- 2 files changed, 7 insertions(+), 37 deletions(-) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index c409d38d..83bda45e 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -9,7 +9,6 @@ namespace Zend\InputFilter; -use ArrayAccess; use Traversable; use Zend\Stdlib\ArrayUtils; use Zend\Stdlib\InitializableInterface; @@ -21,7 +20,7 @@ class BaseInputFilter implements ReplaceableInputInterface { /** - * @var null|array|ArrayAccess + * @var null|array */ protected $data; @@ -178,16 +177,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; diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 5853154c..8b5fbdc1 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -323,32 +323,6 @@ public function testSetDataAndGetRawValueGetValue( $this->assertEmpty($inputFilter->getUnknown(), 'getUnknown() value not match'); } - /** - * @dataProvider setDataArgumentsProvider - */ - public function testSetArrayAccessDataAndGetRawValueGetValue( - $inputs, - $data, - $expectedRawValues, - $expectedValues, - $expectedIsValid, - $expectedInvalidInputs, - $expectedValidInputs, - $expectedMessages - ) { - $dataTypes = $this->dataTypes(); - $this->testSetDataAndGetRawValueGetValue( - $inputs, - $dataTypes['ArrayAccess']($data), - $expectedRawValues, - $expectedValues, - $expectedIsValid, - $expectedInvalidInputs, - $expectedValidInputs, - $expectedMessages - ); - } - /** * @dataProvider setDataArgumentsProvider */ @@ -461,13 +435,13 @@ public function testResetEmptyValidationGroupRecursively() public function contextProvider() { $data = ['fooInput' => 'fooValue']; - $arrayAccessData = new ArrayObject(['fooInput' => 'fooValue']); + $traversableData = new ArrayObject(['fooInput' => 'fooValue']); $expectedFromData = ['fooInput' => 'fooValue']; return [ // Description => [$data, $customContext, $expectedContext] 'by default get context from data (array)' => [$data, null, $expectedFromData], - 'by default get context from data (ArrayAccess)' => [$arrayAccessData, null, $expectedFromData], + 'by default get context from data (Traversable)' => [$traversableData, null, $expectedFromData], 'use custom context' => [[], 'fooContext', 'fooContext'], ]; } @@ -942,9 +916,6 @@ protected function dataTypes() 'array' => function ($data) { return $data; }, - 'ArrayAccess' => function ($data) { - return new ArrayIterator($data); - }, 'Traversable' => function ($data) { return $this->getMockBuilder(FilterIterator::class) ->setConstructorArgs([new ArrayIterator($data)]) From 7938d79988bea797fed0a25dc13e002bdc998b21 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 18:07:04 +0200 Subject: [PATCH 18/22] CS fix --- test/BaseInputFilterTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 8b5fbdc1..1a7395c0 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -776,9 +776,9 @@ public function setDataArgumentsProvider() $iBri = [$iBName => $input($iBName, $required, !$bOnFail, !$valid, ['Invalid ' . $iBName])]; $iBriX = [$iBName => $input($iBName, $required, $bOnFail, !$valid, ['Invalid ' . $iBName])]; $iBrvX = [$iBName => $input($iBName, $required, $bOnFail, $valid, [])]; - $iAriBri = array_merge($iAri , $iBri); + $iAriBri = array_merge($iAri, $iBri); $iArvXBrvX = array_merge($iArvX, $iBrvX); - $iAriBrvX = array_merge($iAri , $iBrvX); + $iAriBrvX = array_merge($iAri, $iBrvX); $iArvXBir = array_merge($iArvX, $iBri); $iAriXBrvX = array_merge($iAriX, $iBrvX); $iArvXBriX = array_merge($iArvX, $iBriX); From 2dac20e3f04c518f1a70aa192dd93b2b4f2319e5 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 18:37:56 +0200 Subject: [PATCH 19/22] Restore use. Used in validateInputs docblock --- src/BaseInputFilter.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 83bda45e..37e0a13a 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -9,6 +9,7 @@ namespace Zend\InputFilter; +use ArrayAccess; use Traversable; use Zend\Stdlib\ArrayUtils; use Zend\Stdlib\InitializableInterface; From d7087e24b10670d40c9e318b9ef5fb6dbc7cca02 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 18:52:00 +0200 Subject: [PATCH 20/22] Add cases for nested InputFilter objects --- src/BaseInputFilter.php | 3 ++ test/BaseInputFilterTest.php | 76 +++++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/BaseInputFilter.php b/src/BaseInputFilter.php index 37e0a13a..1fea9709 100644 --- a/src/BaseInputFilter.php +++ b/src/BaseInputFilter.php @@ -425,6 +425,9 @@ public function getRawValue($name) )); } $input = $this->inputs[$name]; + if ($input instanceof InputFilterInterface) { + return $input->getRawValues(); + } return $input->getRawValue(); } diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 1a7395c0..31106602 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -752,10 +752,14 @@ public function setDataArgumentsProvider() $dARaw = [$iAName => $vRaw]; $dBRaw = [$iBName => $vRaw]; + $dAfRaw = [$iAName => ['fooInput' => $vRaw]]; $d2Raw = array_merge($dARaw, $dBRaw); + $dAfBRaw = array_merge($dAfRaw, $dBRaw); $dAFiltered = [$iAName => $vFiltered]; $dBFiltered = [$iBName => $vFiltered]; + $dAfFiltered = [$iAName => ['fooInput' => $vFiltered]]; $d2Filtered = array_merge($dAFiltered, $dBFiltered); + $dAfBFiltered = array_merge($dAfFiltered, $dBFiltered); $required = true; $valid = true; @@ -769,6 +773,16 @@ public function setDataArgumentsProvider() // @codingStandardsIgnoreEnd }; + $inputFilter = function ($isValid, $msg = []) use ($vRaw, $vFiltered) { + // @codingStandardsIgnoreStart + return function ($context) use ($isValid, $vRaw, $vFiltered, $msg) { + $vRaw = ['fooInput' => $vRaw]; + $vFiltered = ['fooInput' => $vFiltered]; + return $this->createInputFilterInterfaceMock($isValid, $context, $vRaw, $vFiltered, $msg); + }; + // @codingStandardsIgnoreEnd + }; + // @codingStandardsIgnoreStart $iAri = [$iAName => $input($iAName, $required, !$bOnFail, !$valid, ['Invalid ' . $iAName])]; $iAriX = [$iAName => $input($iAName, $required, $bOnFail, !$valid, ['Invalid ' . $iAName])]; @@ -776,6 +790,8 @@ public function setDataArgumentsProvider() $iBri = [$iBName => $input($iBName, $required, !$bOnFail, !$valid, ['Invalid ' . $iBName])]; $iBriX = [$iBName => $input($iBName, $required, $bOnFail, !$valid, ['Invalid ' . $iBName])]; $iBrvX = [$iBName => $input($iBName, $required, $bOnFail, $valid, [])]; + $ifAi = [$iAName => $inputFilter(!$valid, ['fooInput' => ['Invalid ' . $iAName]])]; + $ifAv = [$iAName => $inputFilter($valid)]; $iAriBri = array_merge($iAri, $iBri); $iArvXBrvX = array_merge($iArvX, $iBrvX); $iAriBrvX = array_merge($iAri, $iBrvX); @@ -783,22 +799,32 @@ public function setDataArgumentsProvider() $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 = [$iAName => ['Invalid InputA']]; $msgBInv = [$iBName => ['Invalid InputB']]; + $msgAfInv = [$iAName => ['fooInput' => ['Invalid InputA']]]; $msg2Inv = array_merge($msgAInv, $msgBInv); + $msgAfBInv = array_merge($msgAfInv, $msgBInv); $dataSets = [ // Description => [$inputs, $data argument, $expectedRawValues, $expectedValues, $expectedIsValid, // $expectedInvalidInputs, $expectedValidInputs, $expectedMessages] - 'invalid Break invalid' => [$iAriXBriX, $d2Raw, $d2Raw, $d2Filtered, false, $iAri , [] , $msgAInv], - 'invalid Break valid' => [$iAriXBrvX, $d2Raw, $d2Raw, $d2Filtered, false, $iAri , [] , $msgAInv], - 'valid Break invalid' => [$iArvXBriX, $d2Raw, $d2Raw, $d2Filtered, false, $iBri , $iAri , $msgBInv], - 'valid Break valid' => [$iArvXBrvX, $d2Raw, $d2Raw, $d2Filtered, true , [] , $iArvXBrvX, []], - 'valid invalid' => [$iArvXBir , $d2Raw, $d2Raw, $d2Filtered, false, $iBri , $iArvX , $msgBInv], - 'invalid valid' => [$iAriBrvX , $d2Raw, $d2Raw, $d2Filtered, false, $iAri , $iBrvX , $msgAInv], - 'invalid invalid' => [$iAriBri , $d2Raw, $d2Raw, $d2Filtered, false, $iAriBri , [] , $msg2Inv], - 'invalid valid/NotSet' => [$iAriBri , $dARaw, $d2Raw, $d2Filtered, false, $iAriBrvX, [] , $msg2Inv], + 'invalid Break invalid' => [$iAriXBriX, $d2Raw, $d2Raw, $d2Filtered, false, $iAri , [] , $msgAInv], + 'invalid Break valid' => [$iAriXBrvX, $d2Raw, $d2Raw, $d2Filtered, false, $iAri , [] , $msgAInv], + 'valid Break invalid' => [$iArvXBriX, $d2Raw, $d2Raw, $d2Filtered, false, $iBri , $iAri , $msgBInv], + 'valid Break valid' => [$iArvXBrvX, $d2Raw, $d2Raw, $d2Filtered, true , [] , $iArvXBrvX, []], + 'valid invalid' => [$iArvXBir , $d2Raw, $d2Raw, $d2Filtered, false, $iBri , $iArvX , $msgBInv], + 'IInvalid IValid' => [$iAriBrvX , $d2Raw, $d2Raw, $d2Filtered, false, $iAri , $iBrvX , $msgAInv], + 'IInvalid IInvalid' => [$iAriBri , $d2Raw, $d2Raw, $d2Filtered, false, $iAriBri , [] , $msg2Inv], + 'IInvalid IValid / Partial' => [$iAriBri , $dARaw, $d2Raw, $d2Filtered, false, $iAriBrvX, [] , $msg2Inv], + 'IFInvalid IValid' => [$ifAiBrvX , $dAfBRaw, $dAfBRaw, $dAfBFiltered, false, $ifAi , $iBrvX , $msgAfInv], + 'IFInvalid IInvalid' => [$ifAiBri , $dAfBRaw, $dAfBRaw, $dAfBFiltered, false, $ifAiBri, [] , $msgAfBInv], + 'IFValid IInvalid' => [$ifAvBri , $dAfBRaw, $dAfBRaw, $dAfBFiltered, false, $iBri , $ifAv , $msgBInv], + 'IFValid IValid' => [$ifAvBrv , $dAfBRaw, $dAfBRaw, $dAfBFiltered, true , [] , $ifAvBrv, []], ]; // @codingStandardsIgnoreEnd @@ -838,12 +864,42 @@ public function inputProvider() } /** + * @param null|bool $isValid + * @param mixed $context + * @param mixed[] $getRawValues + * @param mixed[] $getValues + * @param string[] $getMessages + * * @return MockObject|InputFilterInterface */ - protected function createInputFilterInterfaceMock() - { + protected function createInputFilterInterfaceMock( + $isValid = null, + $context = null, + $getRawValues = [], + $getValues = [], + $getMessages = [] + ) { /** @var InputFilterInterface|MockObject $inputFilter */ $inputFilter = $this->getMock(InputFilterInterface::class); + $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) + ; return $inputFilter; } From da2bd8e841ce1850d135a354649ca22cde2b0f03 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 19:06:05 +0200 Subject: [PATCH 21/22] Fix CollectionInputFilter::setData must return $this Following interface contract --- src/CollectionInputFilter.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CollectionInputFilter.php b/src/CollectionInputFilter.php index 4e062679..fb687430 100644 --- a/src/CollectionInputFilter.php +++ b/src/CollectionInputFilter.php @@ -140,6 +140,8 @@ public function getCount() public function setData($data) { $this->data = $data; + + return $this; } /** From ed43e423645acfd9a7c3f7525978329e5f7639d7 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 3 Sep 2015 19:55:29 +0200 Subject: [PATCH 22/22] Print useful error messages for isValid assertions --- test/ArrayInputTest.php | 10 ++++++++-- test/BaseInputFilterTest.php | 24 ++++++++++++++++++++---- test/CollectionInputFilterTest.php | 30 ++++++++++++++++++++++++------ test/FileInputTest.php | 30 ++++++++++++++++++++++++------ test/InputFilterTest.php | 5 ++++- test/InputTest.php | 10 ++++++++-- 6 files changed, 88 insertions(+), 21 deletions(-) diff --git a/test/ArrayInputTest.php b/test/ArrayInputTest.php index bdba8db3..d3e90bad 100644 --- a/test/ArrayInputTest.php +++ b/test/ArrayInputTest.php @@ -74,7 +74,10 @@ public function testValidationOperatesOnFilteredValue() $this->input->getFilterChain()->attach($filter); $validator = new Validator\Digits(); $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()) + ); } public function testSpecifyingMessagesToInputReturnsThoseOnFailedValidation() @@ -162,7 +165,10 @@ public function testNotAllowEmptyWithFilterConvertsEmptyToNonEmptyIsValid() ->getFilterChain()->attach(new Filter\Callback(function () { return 'nonempty'; })); - $this->assertTrue($this->input->isValid()); + $this->assertTrue( + $this->input->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages()) + ); } public function testMerge($sourceRawValue = 'bazRawValue') diff --git a/test/BaseInputFilterTest.php b/test/BaseInputFilterTest.php index 31106602..f2f39567 100644 --- a/test/BaseInputFilterTest.php +++ b/test/BaseInputFilterTest.php @@ -524,7 +524,10 @@ public function testValidationSkipsFieldsMarkedNotRequiredWhenNoDataPresent() $filter->setData($data); - $this->assertTrue($filter->isValid(), json_encode($filter->getMessages())); + $this->assertTrue( + $filter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($filter->getMessages()) + ); $this->assertArrayNotHasKey( $optionalInputName, $filter->getValidInput(), @@ -649,7 +652,10 @@ public function testIsValidWhenValuesSetOnFilters() //test invalid with setData $filter->setData(['foo' => 'thisisavalidstring']); - $this->assertTrue($filter->isValid()); + $this->assertTrue( + $filter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($filter->getMessages()) + ); //test invalid when setting data on actual filter $filter->get('foo')->setValue('invalid'); @@ -658,8 +664,18 @@ public function testIsValidWhenValuesSetOnFilters() //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'); + $this->assertTrue( + $filter->get('foo') + ->isValid(), + 'Filtered value is not valid. Detail . ' . json_encode( + $filter->get('foo') + ->getMessages() + ) + ); + $this->assertTrue( + $filter->isValid(), + 'Input filter did return value from filter. Detail . ' . json_encode($filter->getMessages()) + ); } /** diff --git a/test/CollectionInputFilterTest.php b/test/CollectionInputFilterTest.php index e1e08674..c6db938a 100644 --- a/test/CollectionInputFilterTest.php +++ b/test/CollectionInputFilterTest.php @@ -195,7 +195,10 @@ public function testCanValidateValidData() $this->filter->setInputFilter($this->getBaseInputFilter()); $this->filter->setData($this->getValidCollectionData()); - $this->assertTrue($this->filter->isValid()); + $this->assertTrue( + $this->filter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->filter->getMessages()) + ); } public function testCanValidateValidDataWithNonConsecutiveKeys() @@ -209,7 +212,10 @@ public function testCanValidateValidDataWithNonConsecutiveKeys() unset($collectionData[0]); $this->filter->setInputFilter($this->getBaseInputFilter()); $this->filter->setData($collectionData); - $this->assertTrue($this->filter->isValid()); + $this->assertTrue( + $this->filter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->filter->getMessages()) + ); } public function testInvalidDataReturnsFalse() @@ -293,7 +299,10 @@ public function testGetValues() $this->filter->setInputFilter($this->getBaseInputFilter()); $this->filter->setData($this->getValidCollectionData()); - $this->assertTrue($this->filter->isValid()); + $this->assertTrue( + $this->filter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->filter->getMessages()) + ); $this->assertEquals($expectedData, $this->filter->getValues()); $this->assertCount(2, $this->filter->getValidInput()); @@ -334,7 +343,10 @@ public function testGetRawValues() $this->filter->setInputFilter($this->getBaseInputFilter()); $this->filter->setData($this->getValidCollectionData()); - $this->assertTrue($this->filter->isValid()); + $this->assertTrue( + $this->filter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->filter->getMessages()) + ); $this->assertEquals($expectedData, $this->filter->getRawValues()); } @@ -440,7 +452,10 @@ public function testSetValidationGroupUsingFormStyle() $this->filter->setData($data); $this->filter->setValidationGroup($formValidationGroup); - $this->assertTrue($this->filter->isValid()); + $this->assertTrue( + $this->filter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->filter->getMessages()) + ); } public function testEmptyCollectionIsValidByDefault() @@ -454,7 +469,10 @@ public function testEmptyCollectionIsValidByDefault() $this->filter->setInputFilter($this->getBaseInputFilter()); $this->filter->setData($data); - $this->assertTrue($this->filter->isValid()); + $this->assertTrue( + $this->filter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->filter->getMessages()) + ); } public function testEmptyCollectionIsNotValidIfRequired() diff --git a/test/FileInputTest.php b/test/FileInputTest.php index 401bf14c..b4684717 100644 --- a/test/FileInputTest.php +++ b/test/FileInputTest.php @@ -65,7 +65,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()); } @@ -97,7 +100,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( [$newValue, $newValue, $newValue], $this->input->getValue() @@ -158,7 +164,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()); } @@ -195,7 +204,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'; @@ -249,7 +261,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())); } @@ -268,7 +283,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)); diff --git a/test/InputFilterTest.php b/test/InputFilterTest.php index 1b4df9a5..30d84c8b 100644 --- a/test/InputFilterTest.php +++ b/test/InputFilterTest.php @@ -62,7 +62,10 @@ public function testGetValueReturnsArrayIfNestedInputFilters() ]; $this->inputFilter->setData($data); - $this->assertTrue($this->inputFilter->isValid()); + $this->assertTrue( + $this->inputFilter->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->inputFilter->getMessages()) + ); $this->assertInternalType('array', $this->inputFilter->getValue('people')); } diff --git a/test/InputTest.php b/test/InputTest.php index 2ba67a1f..9d0c8baf 100644 --- a/test/InputTest.php +++ b/test/InputTest.php @@ -239,7 +239,10 @@ public function testValidationOperatesOnFilteredValue() $this->input->getFilterChain()->attach($filter); $validator = new Validator\Digits(); $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()) + ); } public function testSpecifyingMessagesToInputReturnsThoseOnFailedValidation() @@ -317,7 +320,10 @@ public function testNotAllowEmptyWithFilterConvertsEmptyToNonEmptyIsValid() ->getFilterChain()->attach(new Filter\Callback(function () { return 'nonempty'; })); - $this->assertTrue($this->input->isValid()); + $this->assertTrue( + $this->input->isValid(), + 'isValid() value not match. Detail . ' . json_encode($this->input->getMessages()) + ); } public function testDoNotInjectNotEmptyValidatorIfAnywhereInChain()