Enh Dependency getHasChanged (#12928)

* - rename getHasChanged() to isChanged()
- updated docs
- added tests for Dependency
- added useful helpers for inaccessible properties to TestCase
This commit is contained in:
Boudewijn Vahrmeijer
2016-11-09 10:05:06 +01:00
committed by GitHub
parent 5f8ec360ca
commit b641c1f41b
8 changed files with 143 additions and 18 deletions

View File

@ -6,6 +6,7 @@ Yii Framework 2 Change Log
- Bug #4113: Error page stacktrace was generating links to private methods which are not part of the API docs (samdark)
- Bug #9796: Initialization of not existing `yii\grid\ActionColumn` default buttons (arogachev)
- Enh #12798: Changed `yii\cache\Dependency::getHasChanged()` (deprecated, to be removed in 2.1) to `yii\cache\Dependency::isChanged()` (dynasource)
- Bug #12791: Fixed `yii\behaviors\AttributeTypecastBehavior` unable to automatically detect `attributeTypes`, triggering PHP Fatal Error (klimov-paul)
- Bug #12803, #12921: Fixed BC break in `yii.activeForm.js` introduced in #11999. Reverted commit 3ba72da (silverfire)
- Bug #12810: Fixed `yii\rbac\DbManager::getChildRoles()` and `yii\rbac\PhpManager::getChildRoles()` throws an exception when role has no child roles (mysterydragon)

View File

@ -112,7 +112,7 @@ abstract class Cache extends Component implements \ArrayAccess
} else {
$value = call_user_func($this->serializer[1], $value);
}
if (is_array($value) && !($value[1] instanceof Dependency && $value[1]->getHasChanged($this))) {
if (is_array($value) && !($value[1] instanceof Dependency && $value[1]->isChanged($this))) {
return $value[0];
} else {
return false;
@ -184,7 +184,7 @@ abstract class Cache extends Component implements \ArrayAccess
$value = $this->serializer === null ? unserialize($values[$newKey])
: call_user_func($this->serializer[1], $values[$newKey]);
if (is_array($value) && !($value[1] instanceof Dependency && $value[1]->getHasChanged($this))) {
if (is_array($value) && !($value[1] instanceof Dependency && $value[1]->isChanged($this))) {
$results[$key] = $value[0];
}
}

View File

@ -58,22 +58,17 @@ class ChainedDependency extends Dependency
}
/**
* Performs the actual dependency checking.
* This method returns true if any of the dependency objects
* reports a dependency change.
* @param Cache $cache the cache component that is currently evaluating this dependency
* @return bool whether the dependency is changed or not.
* @inheritdoc
*/
public function getHasChanged($cache)
public function isChanged($cache)
{
foreach ($this->dependencies as $dependency) {
if ($this->dependOnAll && $dependency->getHasChanged($cache)) {
if ($this->dependOnAll && $dependency->isChanged($cache)) {
return true;
} elseif (!$this->dependOnAll && !$dependency->getHasChanged($cache)) {
} elseif (!$this->dependOnAll && !$dependency->isChanged($cache)) {
return false;
}
}
return !$this->dependOnAll;
}
}

View File

@ -58,11 +58,19 @@ abstract class Dependency extends \yii\base\Object
}
/**
* Returns a value indicating whether the dependency has changed.
* @deprecated since version 2.0.11. Will be removed in version 2.1
*/
public function getHasChanged($cache)
{
return $this->isChanged($cache);
}
/**
* Checks whether the dependency is changed
* @param Cache $cache the cache component that is currently evaluating this dependency
* @return bool whether the dependency has changed.
*/
public function getHasChanged($cache)
public function isChanged($cache)
{
if ($this->reusable) {
$hash = $this->generateReusableHash();
@ -99,7 +107,7 @@ abstract class Dependency extends \yii\base\Object
}
/**
* Generates the data needed to determine if dependency has been changed.
* Generates the data needed to determine if dependency is changed.
* Derived classes should override this method to generate the actual dependency data.
* @param Cache $cache the cache component that is currently evaluating this dependency
* @return mixed the data needed to determine if dependency has been changed.

View File

@ -58,11 +58,9 @@ class TagDependency extends Dependency
}
/**
* Performs the actual dependency checking.
* @param Cache $cache the cache component that is currently evaluating this dependency
* @return bool whether the dependency is changed or not.
* @inheritdoc
*/
public function getHasChanged($cache)
public function isChanged($cache)
{
$timestamps = $this->getTimestamps($cache, (array) $this->tags);
return $timestamps !== $this->data;

View File

@ -100,6 +100,14 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, $actual);
}
/**
* Invokes a inaccessible method
* @param $object
* @param $method
* @param array $args
* @return mixed
* @since 2.0.11
*/
protected function invokeMethod($object, $method, $args = [])
{
$reflection = new \ReflectionClass($object->className());
@ -108,5 +116,48 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
return $method->invokeArgs($object, $args);
}
/**
* Sets an inaccessible object property to a designated value
* @param $object
* @param $propertyName
* @param $value
* @param bool $revoke
* @since 2.0.11
*/
protected function setInaccessibleProperty($object, $propertyName, $value, $revoke = true)
{
$class = new \ReflectionClass($object);
while (!$class->hasProperty($propertyName)) {
$class = $class->getParentClass();
}
$property = $class->getProperty($propertyName);
$property->setAccessible(true);
$property->setValue($value);
if($revoke){
$property->setAccessible(false);
}
}
/**
* Gets an inaccessible object property
* @param $object
* @param $propertyName
* @return mixed
*/
protected function getInaccessibleProperty($object, $propertyName)
{
$class = new \ReflectionClass($object);
while (!$class->hasProperty($propertyName)) {
$class = $class->getParentClass();
}
$property = $class->getProperty($propertyName);
$property->setAccessible(true);
return $property->getValue($object);
}
}

20
tests/data/cache/MockDependency.php vendored Normal file
View File

@ -0,0 +1,20 @@
<?php
namespace yiiunit\data\cache;
use yii\caching\Dependency;
/**
* Class MockDependency
* @package tests\data\cache
*
* @author Boudewijn Vahrmeijer <vahrmeijer@gmail.com>
* @since 2.0.11
*/
class MockDependency extends Dependency
{
protected function generateDependencyData($cache)
{
return $this->data;
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace yiiunit\framework\caching;
use yii\caching\Cache;
use yii\caching\Dependency;
use yiiunit\data\cache\MockDependency;
use yiiunit\TestCase;
/**
* Dependency (abstract) tests
* @group caching
* @author Boudewijn Vahrmeijer <vahrmeijer@gmail.com>
* @since 2.0.11
*/
class DependencyTest extends TestCase
{
public function testResetReusableData()
{
$value = ['dummy'];
$dependency = new MockDependency();
$this->setInaccessibleProperty($dependency, '_reusableData', $value, false);
$this->assertEquals($value, $this->getInaccessibleProperty($dependency, '_reusableData'));
$dependency->resetReusableData();
$this->assertEquals([], $this->getInaccessibleProperty($dependency, '_reusableData'));
}
public function testGenerateReusableHash()
{
$dependency = $this->getMockForAbstractClass(Dependency::className());
$dependency->data = 'dummy';
$result = $this->invokeMethod($dependency, 'generateReusableHash');
$this->assertEquals(5, strlen($dependency->data));
$this->assertEquals(40, strlen($result));
}
public function testisChanged()
{
$dependency = $this->getMockForAbstractClass(Dependency::className());
$cache = $this->getMockForAbstractClass(Cache::className());
$result = $dependency->isChanged($cache);
$this->assertFalse($result);
$dependency->data = 'changed';
$result = $dependency->isChanged($cache);
$this->assertTrue($result);
}
}