Skip to content
This repository has been archived by the owner on Jan 16, 2019. It is now read-only.

Commit

Permalink
add stubbles\predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
mikey179 committed Jun 24, 2014
1 parent 4bb1799 commit a033ee9
Show file tree
Hide file tree
Showing 12 changed files with 513 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -91,6 +91,7 @@
* added `stubbles\streams\filter\CallableStreamFilter`
* both `stubbles\streams\filter\FilteredInputStream` and `stubbles\streams\filter\FilteredOutputStream` now also accept a callable as stream filter
* `net\stubbles\ioc\App::createModeBindingModule()` now accepts a callable as second parameter which returns a mode
* added `stubbles\predicate`


3.5.3 (2014-05-07)
Expand Down
1 change: 1 addition & 0 deletions nbproject/project.properties
@@ -1,3 +1,4 @@
auxiliary.org-netbeans-modules-html-editor-lib.default-html-public-id=-//W3C//DTD HTML 4.0 Transitional//EN
auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_create_2e_tests=false
auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_enabled=false
auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_path=vendor/autoload.php
Expand Down
30 changes: 30 additions & 0 deletions src/main/php/predicate/AndPredicate.php
@@ -0,0 +1,30 @@
<?php
/**
* This file is part of stubbles.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package stubbles
*/
namespace stubbles\predicate;
/**
* Predicate which tests that two other predicates are true.
*
* @since 4.0.0
*/
class AndPredicate extends Predicate
{
use CombinedPredicate;

/**
* evaluates predicate against given value
*
* @param mixed $value
* @return bool
*/
public function test($value)
{
return $this->predicate1->test($value) && $this->predicate2->test($value);
}
}
44 changes: 44 additions & 0 deletions src/main/php/predicate/CallablePredicate.php
@@ -0,0 +1,44 @@
<?php
/**
* This file is part of stubbles.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package stubbles
*/
namespace stubbles\predicate;
/**
* Wraps a predicate evaluation into a callable.
*
* @since 4.0.0
*/
class CallablePredicate extends Predicate
{
/**
* @type callable
*/
private $predicate;

/**
* constructor
*
* @param callable $predicate
*/
public function __construct(callable $predicate)
{
$this->predicate = $predicate;
}

/**
* evaluates predicate against given value
*
* @param mixed $value
* @return bool
*/
public function test($value)
{
$predicate = $this->predicate;
return $predicate($value);
}
}
38 changes: 38 additions & 0 deletions src/main/php/predicate/CombinedPredicate.php
@@ -0,0 +1,38 @@
<?php
/**
* This file is part of stubbles.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package stubbles
*/
namespace stubbles\predicate;
/**
* Common instance creation for predicates combining two other predicates.
*
* @since 4.0.0
*/
trait CombinedPredicate
{
/**
* @type Predicate
*/
private $predicate1;
/**
* @type Predicate
*/
private $predicate2;

/**
* constructor
*
* @param \stubbles\predicate\Predicate|callable $predicate1
* @param \stubbles\predicate\Predicate|callable $predicate2
*/
public function __construct($predicate1, $predicate2)
{
$this->predicate1 = Predicate::castFrom($predicate1);
$this->predicate2 = Predicate::castFrom($predicate2);
}
}
43 changes: 43 additions & 0 deletions src/main/php/predicate/NegatePredicate.php
@@ -0,0 +1,43 @@
<?php
/**
* This file is part of stubbles.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package stubbles
*/
namespace stubbles\predicate;
/**
* Negates evaluation of wrapped predicate.
*
* @since 4.0.0
*/
class NegatePredicate extends Predicate
{
/**
* @type Predicate
*/
private $predicate;

/**
* constructor
*
* @param \stubbles\predicate\Predicate|callable $predicate
*/
public function __construct($predicate)
{
$this->predicate = Predicate::castFrom($predicate);
}

/**
* evaluates predicate against given value
*
* @param mixed $value
* @return bool
*/
public function test($value)
{
return !$this->predicate->test($value);
}
}
30 changes: 30 additions & 0 deletions src/main/php/predicate/OrPredicate.php
@@ -0,0 +1,30 @@
<?php
/**
* This file is part of stubbles.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package stubbles
*/
namespace stubbles\predicate;
/**
* Predicate which tests that two other predicates are true.
*
* @since 4.0.0
*/
class OrPredicate extends Predicate
{
use CombinedPredicate;

/**
* evaluates predicate against given value
*
* @param mixed $value
* @return bool
*/
public function test($value)
{
return $this->predicate1->test($value) || $this->predicate2->test($value);
}
}
87 changes: 87 additions & 0 deletions src/main/php/predicate/Predicate.php
@@ -0,0 +1,87 @@
<?php
/**
* This file is part of stubbles.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package stubbles
*/
namespace stubbles\predicate;
use stubbles\lang\exception\IllegalArgumentException;
/**
* Evaluates if a given value fulfills a criteria.
*
* @since 4.0.0
*/
abstract class Predicate
{
/**
* casts given predicate to a predicate instance
*
* @param \stubbles\predicate\Predicate|callable $predicate
* @return \stubbles\predicate\Predicate
* @throws IllegalArgumentException
*/
public static function castFrom($predicate)
{
if ($predicate instanceof self) {
return $predicate;
} elseif (is_callable($predicate)) {
return new CallablePredicate($predicate);
}

throw new IllegalArgumentException('Given predicate is neither a callable nor an instance of ' . __CLASS__);
}

/**
* evaluates predicate against given value
*
* @param mixed $value
* @return bool
*/
public abstract function test($value);

/**
* evaluates predicate against given value
*
* @param mixed $value
* @return bool
*/
public function __invoke($value)
{
return $this->test($value);
}

/**
* combines this with another predicate to a predicate which requires both to be true
*
* @param \stubbles\predicate\Predicate|callable $other
* @return \stubbles\predicate\Predicate
*/
public function asWellAs($other)
{
return new AndPredicate($this, self::castFrom($other));
}

/**
* combines this with another predicate to a predicate which requires on of them to be true
*
* @param \stubbles\predicate\Predicate|callable $other
* @return \stubbles\predicate\Predicate
*/
public function orElse($other)
{
return new OrPredicate($this, self::castFrom($other));
}

/**
* returns a negated version of this predicate
*
* @return \stubbles\predicate\Predicate
*/
public function negate()
{
return new NegatePredicate($this);
}
}
52 changes: 52 additions & 0 deletions src/test/php/predicate/AndPredicateTest.php
@@ -0,0 +1,52 @@
<?php
/**
* This file is part of stubbles.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package stubbles
*/
namespace stubbles\predicate;
/**
* Test for stubbles\predicate\AndPredicate.
*
* @group predicate
* @since 4.0.0
*/
class AndPredicateTest extends \PHPUnit_Framework_TestCase
{
/**
* instance to test
*
* @type AndPredicate
*/
private $andPredicate;

/**
* set up test environment
*/
public function setUp()
{
$this->andPredicate = new AndPredicate(
function($value) { return 'foo' === $value; },
function($value) { return 'foo' === $value; }
);
}

/**
* @test
*/
public function returnsTrueWhenBothPredicatesReturnsTrue()
{
$this->assertTrue($this->andPredicate->test('foo'));
}

/**
* @test
*/
public function returnsFalseWhenOnePredicateReturnsFalse()
{
$this->assertFalse($this->andPredicate->test('baz'));
}
}
27 changes: 27 additions & 0 deletions src/test/php/predicate/NegatePredicateTest.php
@@ -0,0 +1,27 @@
<?php
/**
* This file is part of stubbles.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package stubbles
*/
namespace stubbles\predicate;
/**
* Test for stubbles\predicate\NegatePredicate.
*
* @group predicate
* @since 4.0.0
*/
class NegatePredicateTest extends \PHPUnit_Framework_TestCase
{
/**
* @test
*/
public function negatesWrappedPredicate()
{
$negatePredicate = new NegatePredicate(function($value) { return 'foo' === $value; });
$this->assertTrue($negatePredicate('bar'));
}
}

0 comments on commit a033ee9

Please sign in to comment.