Skip to content

Commit

Permalink
Update filters to be reset-able
Browse files Browse the repository at this point in the history
This is mainly for testing/mocking purposes. For instance I was Mocking how the static class `Session` worked. In each test I was setting `Session::read` to return specific data. This worked great for a single test, however the filters are executed in insert order so the filter in my second test was called last.
  • Loading branch information
Blaine Schmeisser committed Jan 13, 2013
1 parent 56074bb commit 378cb15
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 11 deletions.
17 changes: 13 additions & 4 deletions core/Object.php
Expand Up @@ -137,16 +137,24 @@ protected function _init() {
* @see lithium\core\Object::_filter()
* @see lithium\util\collection\Filters
* @param mixed $method The name of the method to apply the closure to. Can either be a single
* method name as a string, or an array of method names.
* @param closure $filter The closure that is used to filter the method(s).
* method name as a string, or an array of method names. Can also be false to remove
* all filters on the current object.
* @param closure $filter The closure that is used to filter the method(s), can also be false
* to remove all the current filters for the given method.
* @return void
*/
public function applyFilter($method, $filter = null) {
if ($method === false) {
$this->_methodFilters = array();
return;
}
foreach ((array) $method as $m) {
if (!isset($this->_methodFilters[$m])) {
if (!isset($this->_methodFilters[$m]) || $filter === false) {
$this->_methodFilters[$m] = array();
}
$this->_methodFilters[$m][] = $filter;
if ($filter !== false) {
$this->_methodFilters[$m][] = $filter;
}
}
}

Expand Down Expand Up @@ -266,6 +274,7 @@ protected static function _parents() {
protected function _stop($status = 0) {
exit($status);
}

}

?>
17 changes: 13 additions & 4 deletions core/StaticObject.php
Expand Up @@ -40,17 +40,25 @@ class StaticObject {
* @see lithium\core\StaticObject::_filter()
* @see lithium\util\collection\Filters
* @param mixed $method The name of the method to apply the closure to. Can either be a single
* method name as a string, or an array of method names.
* @param closure $filter The closure that is used to filter the method.
* method name as a string, or an array of method names. Can also be false to remove
* all filters on the current object.
* @param closure $filter The closure that is used to filter the method(s), can also be false
* to remove all the current filters for the given method.
* @return void
*/
public static function applyFilter($method, $filter = null) {
$class = get_called_class();
if ($method === false) {
static::$_methodFilters[$class] = array();
return;
}
foreach ((array) $method as $m) {
if (!isset(static::$_methodFilters[$class][$m])) {
if (!isset(static::$_methodFilters[$class][$m]) || $filter === false) {
static::$_methodFilters[$class][$m] = array();
}
static::$_methodFilters[$class][$m][] = $filter;
if ($filter !== false) {
static::$_methodFilters[$class][$m][] = $filter;
}
}
}

Expand Down Expand Up @@ -149,6 +157,7 @@ protected static function _parents() {
protected static function _stop($status = 0) {
exit($status);
}

}

?>
47 changes: 47 additions & 0 deletions tests/cases/core/ObjectTest.php
Expand Up @@ -213,6 +213,53 @@ public function testInstanceFalse() {
$this->expectException('/^Invalid class lookup/');
$object->instance(false);
}

public function testResetMethodFilter() {
$obj = new MockMethodFiltering();
$obj->applyFilter(false);
$obj->applyFilter('method2', function($self, $params, $chain) {
return false;
});

$this->assertIdentical(false, $obj->method2());

$obj->applyFilter('method2', false);

$this->assertTrue($obj->method2() !== false);
}

public function testResetMultipleFilters() {
$obj = new MockMethodFiltering();
$obj->applyFilter(false);
$obj->applyFilter(array('method2', 'manual'), function($self, $params, $chain) {
return false;
});

$this->assertIdentical(false, $obj->method2());
$this->assertIdentical(false, $obj->manual(array()));

$obj->applyFilter('method2', false);

$this->assertTrue($obj->method2() !== false);
$this->assertIdentical(false, $obj->manual(array()));
}

public function testResetClass() {
$obj = new MockMethodFiltering();
$obj->applyFilter(false);
$obj->applyFilter(array('method2', 'manual'), function($self, $params, $chain) {
return false;
});

$this->assertIdentical(false, $obj->method2());
$this->assertIdentical(false, $obj->manual(array()));

$obj->applyFilter(false);

$this->assertTrue($obj->method2() !== false);
$this->assertTrue($obj->manual(array()) !== false);
}

}

?>
47 changes: 47 additions & 0 deletions tests/cases/core/StaticObjectTest.php
Expand Up @@ -162,6 +162,53 @@ public function testInstanceFalse() {
$this->expectException('/^Invalid class lookup/');
MockStaticInstantiator::instance(false);
}

public function testResetMethodFilter() {
$class = 'lithium\tests\mocks\core\MockStaticMethodFiltering';
$class::applyFilter(false);
$class::applyFilter('method2', function($self, $params, $chain) {
return false;
});

$this->assertIdentical(false, $class::method2());

$class::applyFilter('method2', false);

$this->assertTrue($class::method2() !== false);
}

public function testResetMultipleFilters() {
$class = 'lithium\tests\mocks\core\MockStaticMethodFiltering';
$class::applyFilter(false);
$class::applyFilter(array('method2', 'manual'), function($self, $params, $chain) {
return false;
});

$this->assertIdentical(false, $class::method2());
$this->assertIdentical(false, $class::manual(array()));

$class::applyFilter('method2', false);

$this->assertTrue($class::method2() !== false);
$this->assertIdentical(false, $class::manual(array()));
}

public function testResetClass() {
$class = 'lithium\tests\mocks\core\MockStaticMethodFiltering';
$class::applyFilter(false);
$class::applyFilter(array('method2', 'manual'), function($self, $params, $chain) {
return false;
});

$this->assertIdentical(false, $class::method2());
$this->assertIdentical(false, $class::manual(array()));

$class::applyFilter(false);

$this->assertTrue($class::method2() !== false);
$this->assertTrue($class::manual(array()) !== false);
}

}

?>
6 changes: 3 additions & 3 deletions tests/cases/test/filter/ComplexityTest.php
Expand Up @@ -36,7 +36,7 @@ class ComplexityTest extends \lithium\test\Unit {
protected $_metrics = array(
'invokeMethod' => 8,
'_filter' => 3,
'applyFilter' => 3,
'applyFilter' => 5,
'_parents' => 2,
'_instance' => 2,
'_stop' => 1
Expand Down Expand Up @@ -86,12 +86,12 @@ public function testAnalyze() {
Complexity::apply($this->report, $group->tests());

$results = Complexity::analyze($this->report);
$expected = array('class' => array($testClass => 3));
$expected = array('class' => array($testClass => 3.5));
foreach ($this->_metrics as $method => $metric) {
$expected['max'][$testClass . '::' . $method . '()'] = $metric;
}
$this->assertEqual($expected['max'], $results['max']);
$this->assertEqual($expected['class'][$testClass], round($results['class'][$testClass]));
$this->assertIdentical($expected['class'][$testClass], $results['class'][$testClass]);
}

/**
Expand Down
8 changes: 8 additions & 0 deletions tests/mocks/core/MockMethodFiltering.php
Expand Up @@ -27,6 +27,14 @@ public function method2() {
};
return $this->_filter(__METHOD__, array(), $method);
}

public function manual($filters) {
$method = function($self, $params, $chain) {
return "Working";
};
return $this->_filter(__METHOD__, array(), $method, $filters);
}

}

?>

0 comments on commit 378cb15

Please sign in to comment.