From 21b94015570d9c791a99a5dde6731764a3203f9b Mon Sep 17 00:00:00 2001 From: Henrique Moody Date: Wed, 3 Sep 2014 13:57:50 -0300 Subject: [PATCH] Create `OneOf` filter --- README.md | 3 +- src/Criteria.php | 7 ++++ src/Filter/OneOf.php | 38 +++++++++++++++++ tests/CriteriaTest.php | 11 +++++ tests/Filter/OneOfTest.php | 85 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/Filter/OneOf.php create mode 100644 tests/Filter/OneOfTest.php diff --git a/README.md b/README.md index 2ece062..fdfbacf 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,8 @@ $criteria->foo->equalTo(2) ->corge->between(array(1, 42)) ->grault->lessThan(1000) ->garply->greaterThan(0) - ->waldo->notEqualTo(false); + ->waldo->notEqualTo(false) + ->fred->greaterThanOrEqualTo(13); $storage->users->find($criteria); ``` diff --git a/src/Criteria.php b/src/Criteria.php index 28fd8dc..899b92f 100644 --- a/src/Criteria.php +++ b/src/Criteria.php @@ -69,6 +69,13 @@ public function __call($methodName, array $arguments = array()) if (0 === strpos($methodName, 'not')) { $shortName = substr($methodName, 3); $filter = new Not($this->newFilterInstance($shortName, $arguments)); + } elseif (false !== strpos($methodName, 'Or')) { + $pieces = explode('Or', $methodName); + $filters = array(); + foreach ($pieces as $shortName) { + $filters[] = $this->newFilterInstance($shortName, $arguments); + } + $filter = new OneOf($filters); } else { $filter = $this->newFilterInstance($methodName, $arguments); } diff --git a/src/Filter/OneOf.php b/src/Filter/OneOf.php new file mode 100644 index 0000000..8a43302 --- /dev/null +++ b/src/Filter/OneOf.php @@ -0,0 +1,38 @@ +filters[] = $filter; + } + } + + public function getFilters() + { + return $this->filters; + } + + public function isValid($input) + { + foreach ($this->getFilters() as $filter) { + if (! $filter->isValid($input)) { + continue; + } + + return true; + } + + return false; + } +} diff --git a/tests/CriteriaTest.php b/tests/CriteriaTest.php index e29f1f2..4ec4d4f 100644 --- a/tests/CriteriaTest.php +++ b/tests/CriteriaTest.php @@ -120,4 +120,15 @@ public function testShouldUseNotFilterWhenUsingTheWordNotInTheFilterName() $this->assertFalse($criteria->isValid($record)); } + + public function testShouldUseOneOfFilterWhenUsingTheWordOrInTheFilterName() + { + $criteria = new Criteria(); + $criteria->foo->greaterThanOrEqualTo(42); + + $record = new Record(); + $record->foo = 42; + + $this->assertTrue($criteria->isValid($record)); + } } diff --git a/tests/Filter/OneOfTest.php b/tests/Filter/OneOfTest.php new file mode 100644 index 0000000..35cb4d8 --- /dev/null +++ b/tests/Filter/OneOfTest.php @@ -0,0 +1,85 @@ +getMock('PHPFluent\ArrayStorage\Filter\Filter'); + } + + public function testShouldAcceptFiltersOnConstructor() + { + $filters = array( + $this->filter(), + $this->filter(), + ); + $filter = new OneOf($filters); + + $this->assertSame($filters, $filter->getFilters()); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Filter is not valid + */ + public function testShouldThrowsExceptionWhenFilterIsNotValid() + { + $filters = array( + $this->filter(), + 'foo', + ); + $filter = new OneOf($filters); + } + + public function testShouldReturnFalseIfAllFiltersAreInvalid() + { + $filter1 = $this->filter(); + $filter1 + ->expects($this->once()) + ->method('isValid') + ->will($this->returnValue(false)); + + $filter2 = $this->filter(); + $filter2 + ->expects($this->once()) + ->method('isValid') + ->will($this->returnValue(false)); + + $filters = array( + $filter1, + $filter2, + ); + + $filter = new OneOf($filters); + + $this->assertFalse($filter->isValid('Value')); + } + + public function testShouldReturnTrueIfAtLeastOneFilterIsValid() + { + $filter1 = $this->filter(); + $filter1 + ->expects($this->once()) + ->method('isValid') + ->will($this->returnValue(true)); + + $filter2 = $this->filter(); + $filter2 + ->expects($this->never()) + ->method('isValid'); + + $filters = array( + $filter1, + $filter2, + ); + + $filter = new OneOf($filters); + + $this->assertTrue($filter->isValid('Value')); + } +}