X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FIrc%2Fextlib%2Fphergie%2FTests%2FPhergie%2FPlugin%2FTestCase.php;h=941e7cb41078f83a7937279d2dbcf844df9e8584;hb=9df856e667a12cd217576263efbc72fff12692d9;hp=36b81d6fae307450491c4bb80a7954c7983bbfbc;hpb=0b2bbd20aa015f5d9d48c4264f56e13324346b4a;p=quix0rs-gnu-social.git diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php index 36b81d6fae..941e7cb410 100644 --- a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php @@ -20,7 +20,7 @@ */ /** - * Unit test suite for Pherge_Plugin classes + * Unit test suite for plugin classes. * * @category Phergie * @package Phergie_Tests @@ -31,177 +31,405 @@ abstract class Phergie_Plugin_TestCase extends PHPUnit_Framework_TestCase { /** - * @var Phergie_Event_Handler + * Mock configuration + * + * @var Phergie_Config + */ + protected $config; + + /** + * Associative array for configuration setting values, accessed by the + * mock configuration object using a callback + * + * @var array */ - protected $handler; + protected $settings = array(); /** + * Mock connection + * * @var Phergie_Connection */ protected $connection; /** - * @var array + * Mock event handler + * + * @var Phergie_Event_Handler */ - protected $eventArgs; + protected $events; /** + * Mock plugin handler + * + * @var Phergie_Plugin_Handler + */ + protected $plugins; + + /** + * Plugin instance being tested + * * @var Phergie_Plugin_Abstract */ protected $plugin; /** - * @var array + * Full name of the plugin class being tested, may be explicitly + * specified in subclasses but is otherwise automatically derived from + * the test case class name + * + * @var string + */ + protected $pluginClass; + + /** + * User nick used in any events requiring one + * + * @var string + */ + protected $nick = 'nick'; + + /** + * Event source used in any events requiring one + * + * @var string */ - protected $config = array(); + protected $source = '#channel'; /** - * Constructs a test case with the given name. + * Initializes instance properties. * - * @param string $name - * @param array $data - * @param string $dataName + * @return void */ - public function __construct($name = NULL, array $data = array(), $dataName = '') + public function setUp() { - parent::__construct($name, $data, $dataName); - $this->connection = new Phergie_Connection(); - $this->handler = new Phergie_Event_Handler(); + if (empty($this->pluginClass)) { + $this->pluginClass = preg_replace('/Test$/', '', get_class($this)); + } + + if (empty($this->plugin)) { + $this->plugin = new $this->pluginClass; + } + + $this->plugin->setConfig($this->getMockConfig()); + $this->plugin->setConnection($this->getMockConnection()); + $this->plugin->setEventHandler($this->getMockEventHandler()); + $this->plugin->setPluginHandler($this->getMockPluginHandler()); } /** - * Assert that a given event type exists in the event handler - * @param string $event - * @param string $message + * Destroys all initialized instance properties. + * + * @return void */ - public function assertHasEvent($event, $message = null) + public function tearDown() { - self::assertTrue($this->handler->hasEventOfType($event), $message); + unset( + $this->plugins, + $this->events, + $this->connection, + $this->config, + $this->plugin + ); } /** - * Assert that a given event type DOES NOT exist in the event handler - * @param string $event - * @param string $message + * Returns a mock configuration object. + * + * @return Phergie_Config */ - public function assertDoesNotHaveEvent($event, $message = null) + protected function getMockConfig() { - self::assertFalse($this->handler->hasEventOfType($event), $message); + if (empty($this->config)) { + $this->config = $this->getMock('Phergie_Config', array('offsetExists', 'offsetGet')); + $this->config + ->expects($this->any()) + ->method('offsetExists') + ->will($this->returnCallback(array($this, 'configOffsetExists'))); + $this->config + ->expects($this->any()) + ->method('offsetGet') + ->will($this->returnCallback(array($this, 'configOffsetGet'))); + } + return $this->config; } /** - * Assert that the emitter of the given command event was the given - * plugin + * Returns whether a specific configuration setting has a value. Only + * intended for use by this class, but must be public for PHPUnit to + * call them. + * + * @param string $name Name of the setting * - * @param Phergie_Event_Command $event - * @param Phergie_Plugin_Abstract $plugin - * @param string $message + * @return boolean TRUE if the setting has a value, FALSE otherwise */ - public function assertEventEmitter(Phergie_Event_Command $event, - Phergie_Plugin_Abstract $plugin, - $message = null) + public function configOffsetExists($name) { - $this->assertSame($plugin, $event->getPlugin(), $message); + return isset($this->settings[$name]); } /** - * Gets the events added to the handler by the plugin - * @param string $type - * @return array | null + * Returns the value of a specific configuration setting. Only intended + * for use by this class, but must be public for PHPUnit to call them. + * + * @param string $name Name of the setting + * + * @return mixed Value of the setting */ - public function getResponseEvents($type = null) + public function configOffsetGet($name) { - if (is_string($type) && strlen($type) > 0) { - return $this->handler->getEventsOfType($type); - } - return $this->handler->getEvents(); + return $this->settings[$name]; } /** - * Sets the event for the test - * @param array $event - * @param array $eventArgs + * Returns a mock connection object. + * + * @return Phergie_Connection */ - public function setEvent(array $event, array $eventArgs = null) + protected function getMockConnection() { - $eventClass = 'Phergie_Event_Request'; - if (is_array($event)) { - $eventClass = $event[0]; - $eventType = $event[1]; - } else { - throw new InvalidArgumentException("Invalid value for \$event"); + if (empty($this->connection)) { + $this->connection = $this->getMock('Phergie_Connection'); + $this->connection + ->expects($this->any()) + ->method('getNick') + ->will($this->returnValue($this->nick)); } - $event = new $eventClass(); - $event->setType($eventType); - $event->setArguments($eventArgs); - $this->plugin->setEvent($event); - $this->eventArgs = $eventArgs; + return $this->connection; } /** - * Sets the plugin to be tested - * If a plugin requries config for testing, an array placed in - * $this->config will be parsed into a Phergie_Config object and - * attached to the plugin + * Returns a mock event handler object. + * + * @return Phergie_Event_Handler */ - protected function setPlugin(Phergie_Plugin_Abstract $plugin) + protected function getMockEventHandler() { - $this->plugin = $plugin; - $this->plugin->setEventHandler($this->handler); - $this->plugin->setConnection($this->connection); - $this->connection->setNick('test'); - if (!empty($this->config)) { - $config = new Phergie_Config(); - foreach ($this->config as $configKey => $configValue) { - $config[$configKey] = $configValue; - } - $plugin->setConfig($config); + if (empty($this->events)) { + $this->events = $this->getMock('Phergie_Event_Handler', array('addEvent')); } + return $this->events; } /** - * Overrides the runTest method to add additional annotations - * @return PHPUnit_Framework_TestResult + * Returns a mock plugin handler object. + * + * @return Phergie_Plugin_Handler */ - protected function runTest() + protected function getMockPluginHandler() { - if (null === $this->plugin) { - throw new RuntimeException( - 'Tests cannot be run before plugin is set' + if (empty($this->plugins)) { + $config = $this->getMockConfig(); + $events = $this->getMockEventHandler(); + $this->plugins = $this->getMock( + 'Phergie_Plugin_Handler', + array(), // mock everything + array($config, $events) ); } - - // Clean the event handler... important! - $this->handler->clearEvents(); - - $info = $this->getAnnotations(); - $event = null; - $eventArgs = array(); - if (isset($info['method']['event']) && isset($info['method']['event'][0])) { - if (!is_string($info['method']['event'][0])) { - throw new InvalidArgumentException( - 'Only one event may be specified' - ); - } - $event = $info['method']['event'][0]; + return $this->plugins; + } - if (stristr($event, '::')) { - $event = explode('::', $event); + /** + * Returns a mock event object. + * + * @param string $type Event type + * @param array $args Optional associative array of event arguments + * @param string $nick Optional user nick to associate with the event + * @param string $source Optional user nick or channel name to associate + * with the event as its source + * + * @return Phergie_Event_Request + */ + protected function getMockEvent($type, array $args = array(), + $nick = null, $source = null + ) { + $methods = array('getNick', 'getSource'); + foreach (array_keys($args) as $arg) { + if (is_int($arg) || ctype_digit($arg)) { + $methods[] = 'getArgument'; + } else { + $methods[] = 'get' . ucfirst($arg); } } - if (isset($info['method']['eventArg'])) { - $eventArgs = $info['method']['eventArg']; + + $event = $this->getMock( + 'Phergie_Event_Request', + $methods + ); + + $nick = $nick ? $nick : $this->nick; + $event + ->expects($this->any()) + ->method('getNick') + ->will($this->returnValue($nick)); + + $source = $source ? $source : $this->source; + $event + ->expects($this->any()) + ->method('getSource') + ->will($this->returnValue($source)); + + foreach ($args as $key => $value) { + if (is_int($key) || ctype_digit($key)) { + $event + ->expects($this->any()) + ->method('getArgument') + ->with($key) + ->will($this->returnValue($value)); + } else { + $event + ->expects($this->any()) + ->method('get' . ucfirst($key)) + ->will($this->returnValue($value)); + } } - if (null !== $event) { - $this->setEvent($event, $eventArgs); + + return $event; + } + + /** + * Sets the value of a configuration setting. + * + * @param string $setting Name of the setting + * @param mixed $value Value for the setting + * + * @return void + */ + protected function setConfig($setting, $value) + { + $this->settings[$setting] = $value; + } + + /** + * Returns the absolute path to the Phergie/Plugin directory. Useful in + * conjunction with getMockDatabase(). + * + * @param string $subpath Optional path to append to the directory path + * + * @return string Directory path + */ + protected function getPluginsPath($subpath = null) + { + $path = realpath(dirname(__FILE__) . '/../../../Phergie/Plugin'); + if (!empty($subpath)) { + $path .= '/' . ltrim($subpath, '/'); } + return $path; + } + + /** + * Modifies the event handler to include an expectation of an event + * being added by the plugin being tested. Note that this must be called + * BEFORE executing the plugin code intended to initiate the event. + * + * @param string $type Event type + * @param array $args Optional enumerated array of event arguments + * + * @return void + */ + protected function assertEmitsEvent($type, array $args = array()) + { + $this->events + ->expects($this->at(0)) + ->method('addEvent') + ->with($this->plugin, $type, $args); + } - $testResult = parent::runTest(); + /** + * Modifies the event handler to include an expectation of an event NOT + * being added by the plugin being tested. Note that this must be called + * BEFORE executing plugin code that may initiate the event. + * + * @param string $type Event type + * @param array $args Optional enumerated array of event arguments + * + * @return void + */ + protected function assertDoesNotEmitEvent($type, array $args = array()) + { + // Ugly hack to get around an issue in PHPUnit + // @link http://github.com/sebastianbergmann/phpunit-mock-objects/issues/issue/5#issue/5/comment/343524 + $callback = create_function( + '$plugin, $type, $args', + 'if (get_class($plugin) == "' . $this->pluginClass . '" + && $type == "' . $type . '" + && $args == "' . var_export($args, true) . '") { + trigger_error("Instance of ' . $this->pluginClass + . ' unexpectedly emitted event of type ' . $type + . '", E_USER_ERROR); + }' + ); - // Clean the event handler again... just incase this time. - $this->handler->clearEvents(); + $this->events + ->expects($this->any()) + ->method('addEvent') + ->will($this->returnCallback($callback)); + } - return $testResult; + /** + * Modifies the plugin handler to include an expectation of a plugin + * being retrieved, indicating a dependency. Note that this must be + * called BEFORE executing the plugin code that may load that plugin + * dependency, which is usually located in onLoad(). + * + * @param string $name Short name of the plugin required as a dependency + * + * @return void + */ + public function assertRequiresPlugin($name) + { + $this->plugins + ->expects($this->atLeastOnce()) + ->method('getPlugin') + ->with($name); } + /** + * Creates an in-memory copy of a specified SQLite database file and + * returns a connection to it. + * + * @param string $path Path to the SQLite file to copy + * + * @return PDO Connection to the database copy + */ + public function getMockDatabase($path) + { + $original = new PDO('sqlite:' . $path); + $copy = new PDO('sqlite::memory:'); + + $result = $original->query('SELECT sql FROM sqlite_master'); + while ($sql = $result->fetchColumn()) { + $copy->exec($sql); + } + + $tables = array(); + $result = $original->query('SELECT name FROM sqlite_master WHERE type = "table"'); + while ($table = $result->fetchColumn()) { + $tables[] = $table; + } + + foreach ($tables as $table) { + $result = $original->query('SELECT * FROM ' . $table); + $insert = null; + $copy->beginTransaction(); + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { + $columns = array_keys($row); + if (empty($insert)) { + $insert = $copy->prepare( + 'INSERT INTO "' . $table . '" (' . + '"' . implode('", "', $columns) . '"' . + ') VALUES (' . + ':' . implode(', :', $columns) . + ')' + ); + } + $insert->execute($row); + } + $copy->commit(); + unset($insert); + } + + return $copy; + } }