1
0
Fork 0

Code tweaks, refs #4124

pull/4813/merge
Jordi Boggiano 2016-01-22 19:09:44 +00:00
parent ddd140fd1c
commit 837fa805ec
2 changed files with 39 additions and 24 deletions

View File

@ -306,7 +306,7 @@ class PluginManager
/** /**
* @param PluginInterface $plugin * @param PluginInterface $plugin
* @param string $capability * @param string $capability
* @return null|string The fully qualified class of the implementation or null if Plugin is not of Capable type * @return null|string The fully qualified class of the implementation or null if Plugin is not of Capable type or does not provide it
* @throws \RuntimeException On empty or non-string implementation class name value * @throws \RuntimeException On empty or non-string implementation class name value
*/ */
protected function getCapabilityImplementationClassName(PluginInterface $plugin, $capability) protected function getCapabilityImplementationClassName(PluginInterface $plugin, $capability)
@ -317,21 +317,22 @@ class PluginManager
$capabilities = (array) $plugin->getCapabilities(); $capabilities = (array) $plugin->getCapabilities();
if (!empty($capabilities[$capability]) && is_string($capabilities[$capability])) { if (!empty($capabilities[$capability]) && is_string($capabilities[$capability]) && trim($capabilities[$capability])) {
$capabilities[$capability] = trim($capabilities[$capability]); return trim($capabilities[$capability]);
} }
if (empty($capabilities[$capability]) || !is_string($capabilities[$capability])) { if (
throw new \RuntimeException('Plugin provided invalid capability class name(s)'); array_key_exists($capability, $capabilities)
&& (empty($capabilities[$capability]) || !is_string($capabilities[$capability]) || !trim($capabilities[$capability]))
) {
throw new \UnexpectedValueException('Plugin '.get_class($plugin).' provided invalid capability class name(s), got '.var_export($capabilities[$capability], 1));
} }
return $capabilities[$capability];
} }
/** /**
* @param PluginInterface $plugin * @param PluginInterface $plugin
* @param string $capabilityClassName The fully qualified name of the API interface which the plugin may provide * @param string $capabilityClassName The fully qualified name of the API interface which the plugin may provide
* an implementation. * an implementation of.
* @param array $ctorArgs Arguments passed to Capability's constructor. * @param array $ctorArgs Arguments passed to Capability's constructor.
* Keeping it an array will allow future values to be passed w\o changing the signature. * Keeping it an array will allow future values to be passed w\o changing the signature.
* @return null|Capability * @return null|Capability
@ -339,22 +340,20 @@ class PluginManager
public function getPluginCapability(PluginInterface $plugin, $capabilityClassName, array $ctorArgs = array()) public function getPluginCapability(PluginInterface $plugin, $capabilityClassName, array $ctorArgs = array())
{ {
if ($capabilityClass = $this->getCapabilityImplementationClassName($plugin, $capabilityClassName)) { if ($capabilityClass = $this->getCapabilityImplementationClassName($plugin, $capabilityClassName)) {
if (class_exists($capabilityClass)) { if (!class_exists($capabilityClass)) {
$capabilityObj = new $capabilityClass($ctorArgs); throw new \RuntimeException("Cannot instantiate Capability, as class $capabilityClass from plugin ".get_class($plugin)." does not exist.");
if ($capabilityObj instanceof Capability &&
$capabilityObj instanceof $capabilityClassName
) {
return $capabilityObj;
} else {
throw new \RuntimeException(
'Class ' . $capabilityClass . ' must be of both \Composer\Plugin\Capability\Capability and '.
$capabilityClassName . ' types.'
);
}
} else {
throw new \RuntimeException("Cannot instantiate Capability, as class $capabilityClass does not exist.");
} }
$capabilityObj = new $capabilityClass($ctorArgs);
// FIXME these could use is_a and do the check *before* instantiating once drop support for php<5.3.9
if (!$capabilityObj instanceof Capability || !$capabilityObj instanceof $capabilityClassName) {
throw new \RuntimeException(
'Class ' . $capabilityClass . ' must implement both Composer\Plugin\Capability\Capability and '. $capabilityClassName . '.'
);
}
return $capabilityObj;
} }
return null;
} }
} }

View File

@ -350,7 +350,7 @@ class PluginInstallerTest extends TestCase
/** /**
* @dataProvider invalidImplementationClassNames * @dataProvider invalidImplementationClassNames
* @expectedException \RuntimeException * @expectedException \UnexpectedValueException
*/ */
public function testQueryingWithInvalidCapabilityClassNameThrows($invalidImplementationClassNames) public function testQueryingWithInvalidCapabilityClassNameThrows($invalidImplementationClassNames)
{ {
@ -368,6 +368,22 @@ class PluginInstallerTest extends TestCase
$this->pm->getPluginCapability($plugin, $capabilityApi); $this->pm->getPluginCapability($plugin, $capabilityApi);
} }
public function testQueryingNonProvidedCapabilityReturnsNullSafely()
{
$capabilityApi = 'Composer\Plugin\Capability\MadeUpCapability';
$plugin = $this->getMockBuilder('Composer\Test\Plugin\Mock\CapablePluginInterface')
->getMock();
$plugin->expects($this->once())
->method('getCapabilities')
->will($this->returnCallback(function() {
return array();
}));
$this->assertNull($this->pm->getPluginCapability($plugin, $capabilityApi));
}
/** /**
* @dataProvider nonExistingOrInvalidImplementationClassTypes * @dataProvider nonExistingOrInvalidImplementationClassTypes
* @expectedException \RuntimeException * @expectedException \RuntimeException