123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- <?php
- use PHPUnit\Framework\TestCase;
- use PHPUnit\Framework\TestResult;
- use PHPUnit\Framework\AssertionFailedError;
- require_once(__DIR__ . '/../lib/RssBridge.php');
- Bridge::setDir(__DIR__ . '/../bridges/');
- /**
- * This class checks bridges for implementation details:
- *
- * - A bridge must not implement public functions other than the ones specified
- * by the bridge interfaces. Custom functions must be defined in private or
- * protected scope.
- * - getName() must return a valid string (non-empty)
- * - getURI() must return a valid URI
- * - A bridge must define constants for NAME, URI, DESCRIPTION and MAINTAINER,
- * CACHE_TIMEOUT and PARAMETERS are optional
- */
- final class BridgeImplementationTest extends TestCase {
- private function CheckBridgePublicFunctions($bridgeName){
- $parent_methods = array();
- if(in_array('BridgeInterface', class_parents($bridgeName))) {
- $parent_methods = array_merge($parent_methods, get_class_methods('BridgeInterface'));
- }
- if(in_array('BridgeAbstract', class_parents($bridgeName))) {
- $parent_methods = array_merge($parent_methods, get_class_methods('BridgeAbstract'));
- }
- if(in_array('FeedExpander', class_parents($bridgeName))) {
- $parent_methods = array_merge($parent_methods, get_class_methods('FeedExpander'));
- }
- // Receive all non abstract methods
- $methods = array_diff(get_class_methods($bridgeName), $parent_methods);
- $method_names = implode(', ', $methods);
- $errmsg = $bridgeName
- . ' implements additional public method(s): '
- . $method_names
- . '! Custom functions must be defined in private or protected scope!';
- $this->assertEmpty($method_names, $errmsg);
- }
- private function CheckBridgeGetNameDefaultValue($bridgeName){
- if(in_array('BridgeAbstract', class_parents($bridgeName))) { // Is bridge
- if(!$this->isFunctionMemberOf($bridgeName, 'getName'))
- return;
- $bridge = new $bridgeName();
- $abstract = new BridgeAbstractTest();
- $message = $bridgeName . ': \'getName\' must return a valid name!';
- $this->assertNotEmpty(trim($bridge->getName()), $message);
- }
- }
- // Checks whether the getURI function returns empty or default values
- private function CheckBridgeGetURIDefaultValue($bridgeName){
- if(in_array('BridgeAbstract', class_parents($bridgeName))) { // Is bridge
- if(!$this->isFunctionMemberOf($bridgeName, 'getURI'))
- return;
- $bridge = new $bridgeName();
- $abstract = new BridgeAbstractTest();
- $message = $bridgeName . ': \'getURI\' must return a valid URI!';
- $this->assertNotEmpty(trim($bridge->getURI()), $message);
- }
- }
- private function CheckBridgePublicConstants($bridgeName){
- // Assertion only works for BridgeAbstract!
- if(in_array('BridgeAbstract', class_parents($bridgeName))) {
- $ref = new ReflectionClass($bridgeName);
- $constants = $ref->getConstants();
- $ref = new ReflectionClass('BridgeAbstract');
- $parent_constants = $ref->getConstants();
- foreach($parent_constants as $key => $value) {
- $this->assertArrayHasKey($key, $constants, 'Constant ' . $key . ' missing in ' . $bridgeName);
- // Skip optional constants
- if($key !== 'PARAMETERS' && $key !== 'CACHE_TIMEOUT') {
- $this->assertNotEquals($value, $constants[$key], 'Constant ' . $key . ' missing in ' . $bridgeName);
- }
- }
- }
- }
- private function isFunctionMemberOf($bridgeName, $functionName){
- $bridgeReflector = new ReflectionClass($bridgeName);
- $bridgeMethods = $bridgeReflector->GetMethods();
- $bridgeHasMethod = false;
- foreach($bridgeMethods as $method) {
- if($method->name === $functionName && $method->class === $bridgeReflector->name) {
- return true;
- }
- }
- return false;
- }
- public function testBridgeImplementation($bridgeName){
- require_once('bridges/' . $bridgeName . '.php');
- $this->CheckBridgePublicFunctions($bridgeName);
- $this->CheckBridgePublicConstants($bridgeName);
- $this->CheckBridgeGetNameDefaultValue($bridgeName);
- $this->CheckBridgeGetURIDefaultValue($bridgeName);
- }
- public function count() {
- return count(Bridge::listBridges());
- }
- public function run(TestResult $result = null) {
- if ($result === null) {
- $result = new TestResult;
- }
- foreach (Bridge::listBridges() as $bridge) {
- $bridge .= 'Bridge';
- $result->startTest($this);
- PHP_Timer::start();
- $stopTime = null;
- try {
- $this->testBridgeImplementation($bridge);
- } catch (AssertionFailedError $e) {
- $stopTime = PHP_Timer::stop();
- $result->addFailure($this, $e, $stopTime);
- } catch (Exception $e) {
- $stopTime = PHP_Timer::stop();
- $result->addError($this, $e, $stopTime);
- }
- if ($stopTime === null) {
- $stopTime = PHP_Timer::stop();
- }
- $result->endTest($this, $stopTime);
- }
- return $result;
- }
- }
- class BridgeAbstractTest extends BridgeAbstract {
- public function collectData(){}
- }
|