diff options
Diffstat (limited to 'plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php')
-rw-r--r-- | plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php new file mode 100644 index 000000000..941e7cb41 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestCase.php @@ -0,0 +1,435 @@ +<?php +/** + * Phergie + * + * PHP version 5 + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE. + * It is also available through the world-wide-web at this URL: + * http://phergie.org/license + * + * @category Phergie + * @package Phergie_Tests + * @author Phergie Development Team <team@phergie.org> + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie_Tests + */ + +/** + * Unit test suite for plugin classes. + * + * @category Phergie + * @package Phergie_Tests + * @author Phergie Development Team <team@phergie.org> + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie_Tests + */ +abstract class Phergie_Plugin_TestCase extends PHPUnit_Framework_TestCase +{ + /** + * 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 $settings = array(); + + /** + * Mock connection + * + * @var Phergie_Connection + */ + protected $connection; + + /** + * Mock event handler + * + * @var Phergie_Event_Handler + */ + protected $events; + + /** + * Mock plugin handler + * + * @var Phergie_Plugin_Handler + */ + protected $plugins; + + /** + * Plugin instance being tested + * + * @var Phergie_Plugin_Abstract + */ + protected $plugin; + + /** + * 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 $source = '#channel'; + + /** + * Initializes instance properties. + * + * @return void + */ + public function setUp() + { + 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()); + } + + /** + * Destroys all initialized instance properties. + * + * @return void + */ + public function tearDown() + { + unset( + $this->plugins, + $this->events, + $this->connection, + $this->config, + $this->plugin + ); + } + + /** + * Returns a mock configuration object. + * + * @return Phergie_Config + */ + protected function getMockConfig() + { + 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; + } + + /** + * 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 + * + * @return boolean TRUE if the setting has a value, FALSE otherwise + */ + public function configOffsetExists($name) + { + return isset($this->settings[$name]); + } + + /** + * 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 configOffsetGet($name) + { + return $this->settings[$name]; + } + + /** + * Returns a mock connection object. + * + * @return Phergie_Connection + */ + protected function getMockConnection() + { + if (empty($this->connection)) { + $this->connection = $this->getMock('Phergie_Connection'); + $this->connection + ->expects($this->any()) + ->method('getNick') + ->will($this->returnValue($this->nick)); + } + return $this->connection; + } + + /** + * Returns a mock event handler object. + * + * @return Phergie_Event_Handler + */ + protected function getMockEventHandler() + { + if (empty($this->events)) { + $this->events = $this->getMock('Phergie_Event_Handler', array('addEvent')); + } + return $this->events; + } + + /** + * Returns a mock plugin handler object. + * + * @return Phergie_Plugin_Handler + */ + protected function getMockPluginHandler() + { + if (empty($this->plugins)) { + $config = $this->getMockConfig(); + $events = $this->getMockEventHandler(); + $this->plugins = $this->getMock( + 'Phergie_Plugin_Handler', + array(), // mock everything + array($config, $events) + ); + } + return $this->plugins; + } + + /** + * 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); + } + } + + $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)); + } + } + + 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); + } + + /** + * 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); + }' + ); + + $this->events + ->expects($this->any()) + ->method('addEvent') + ->will($this->returnCallback($callback)); + } + + /** + * 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; + } +} |