From 9891a4be62be2a7472ba0a366d7851a990071371 Mon Sep 17 00:00:00 2001 From: Steve B Date: Thu, 28 Nov 2013 14:05:26 +0000 Subject: [PATCH] force plugin factory to only build plugins matching interface. --- PHPCI/Plugin/Util/Factory.php | 9 +++++++ Tests/PHPCI/Plugin/Util/ExamplePlugins.php | 31 ++++++++++++++++++---- Tests/PHPCI/Plugin/Util/FactoryTest.php | 6 +++++ bootstrap.php | 28 ------------------- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/PHPCI/Plugin/Util/Factory.php b/PHPCI/Plugin/Util/Factory.php index 4e6065e6..c0234374 100644 --- a/PHPCI/Plugin/Util/Factory.php +++ b/PHPCI/Plugin/Util/Factory.php @@ -9,6 +9,8 @@ class Factory { const TYPE_ARRAY = "array"; const TYPE_CALLABLE = "callable"; + const INTERFACE_PHPCI_PLUGIN = '\PHPCI\Plugin'; + private $currentPluginOptions; /** @@ -45,6 +47,7 @@ class Factory { * * @param $className * @param array $options + * @throws \InvalidArgumentException if $className doesn't represent a valid plugin * @return \PHPCI\Plugin */ public function buildPlugin($className, array $options = array()) @@ -53,6 +56,12 @@ class Factory { $reflectedPlugin = new \ReflectionClass($className); + if (!$reflectedPlugin->implementsInterface(self::INTERFACE_PHPCI_PLUGIN)) { + throw new \InvalidArgumentException( + "Requested class must implement " . self:: INTERFACE_PHPCI_PLUGIN + ); + } + $constructor = $reflectedPlugin->getConstructor(); if ($constructor) { diff --git a/Tests/PHPCI/Plugin/Util/ExamplePlugins.php b/Tests/PHPCI/Plugin/Util/ExamplePlugins.php index 9b5067a7..bc67bd3f 100644 --- a/Tests/PHPCI/Plugin/Util/ExamplePlugins.php +++ b/Tests/PHPCI/Plugin/Util/ExamplePlugins.php @@ -5,18 +5,28 @@ use PHPCI\Builder; use PHPCI\Model\Build; use PHPCI\Plugin; -class ExamplePluginWithNoConstructorArgs { - +class ExamplePluginWithNoConstructorArgs implements Plugin +{ + public function execute() + { + } } -class ExamplePluginWithSingleOptionalArg { +class ExamplePluginWithSingleOptionalArg implements Plugin +{ function __construct($optional = null) { } + + public function execute() + { + + } } -class ExamplePluginWithSingleRequiredArg { +class ExamplePluginWithSingleRequiredArg implements Plugin +{ public $RequiredArgument; @@ -24,9 +34,15 @@ class ExamplePluginWithSingleRequiredArg { { $this->RequiredArgument = $requiredArgument; } + + public function execute() + { + + } } -class ExamplePluginWithSingleTypedRequiredArg { +class ExamplePluginWithSingleTypedRequiredArg implements Plugin +{ public $RequiredArgument; @@ -34,6 +50,11 @@ class ExamplePluginWithSingleTypedRequiredArg { { $this->RequiredArgument = $requiredArgument; } + + public function execute() + { + + } } class ExamplePluginFull implements Plugin { diff --git a/Tests/PHPCI/Plugin/Util/FactoryTest.php b/Tests/PHPCI/Plugin/Util/FactoryTest.php index fb2794c8..be5c5f6f 100644 --- a/Tests/PHPCI/Plugin/Util/FactoryTest.php +++ b/Tests/PHPCI/Plugin/Util/FactoryTest.php @@ -49,6 +49,12 @@ class FactoryTest extends \PHPUnit_Framework_TestCase { $this->assertInstanceOf($expectedPluginClass, $plugin); } + public function testBuildPluginFailsForNonPluginClasses() + { + $this->setExpectedException('InvalidArgumentException', 'Requested class must implement \PHPCI\Plugin'); + $plugin = $this->testedFactory->buildPlugin("stdClass"); + } + public function testBuildPluginWorksWithSingleOptionalArgConstructor() { $namespace = '\\PHPCI\\Plugin\\Tests\\Util\\'; diff --git a/bootstrap.php b/bootstrap.php index 17aaf608..afb67c31 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,14 +1,5 @@ loadYaml(dirname(__FILE__) . '/PHPCI/config.yml'); - -require_once(dirname(__FILE__) . '/vars.php');