diff options
Diffstat (limited to 'plugins/Irc/extlib/phergie/Tests')
13 files changed, 2687 insertions, 0 deletions
diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/ConnectionTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/ConnectionTest.php new file mode 100644 index 000000000..ba94cd0ea --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/ConnectionTest.php @@ -0,0 +1,262 @@ +<?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 Pherge_Connection. + * + * @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 + */ +class Phergie_ConnectionTest extends PHPUnit_Framework_TestCase +{ + /** + * Associative array containing an option-to-value mapping + * + * @var array + */ + private $options = array( + 'host' => 'example.com', + 'port' => 4080, + 'transport' => 'udp', + 'encoding' => 'ASCII', + 'nick' => 'MyNick', + 'username' => 'MyUsername', + 'realname' => 'MyRealName', + 'password' => 'MyPassword', + ); + + /** + * Data provider for testGetOptionReturnsDefault(). + * + * @return array Enumerated array of enumerated arrays each containing a + * set of parameters for a single call to + * testGetOptionReturnsDefault() + */ + public function dataProviderTestGetOptionReturnsDefault() + { + return array( + array('transport', 'tcp'), + array('encoding', 'ISO-8859-1'), + array('port', 6667), + array('password', null), + ); + } + + /** + * Tests that a default values are used for some options. + * + * @param string $option Name of the option with a default value + * @param mixed $value Default value of the option + * + * @return void + * @dataProvider dataProviderTestGetOptionReturnsDefault + */ + public function testGetOptionReturnsDefault($option, $value) + { + $connection = new Phergie_Connection; + $this->assertEquals($value, $connection->{'get' . ucfirst($option)}()); + } + + /** + * Tests that a default encoding is used if one isn't specified. + * + * @return void + */ + public function testGetEncodingReturnsDefault() + { + $connection = new Phergie_Connection; + $this->assertEquals('ISO-8859-1', $connection->getEncoding()); + } + + /** + * Tests that options can be set via the constructor. + * + * @return void + */ + public function testSetOptionsViaConstructor() + { + $connection = new Phergie_Connection($this->options); + foreach ($this->options as $key => $value) { + $this->assertEquals($value, $connection->{'get' . ucfirst($key)}()); + } + } + + /** + * Data provider for testGetHostmaskMissingDataGeneratesException(). + * + * @return array Enumerated array of enumerated arrays each containing a + * set of parameters for a single call to + * testGetHostmaskMissingDataGeneratesException() + */ + public function dataProviderTestGetHostmaskMissingDataGeneratesException() + { + return array( + array(null, $this->options['username'], $this->options['host']), + array($this->options['nick'], null, $this->options['host']), + array($this->options['nick'], $this->options['username'], null), + ); + } + + /** + * Tests that attempting to retrieve a hostmask without option values + * for all of its constituents generates an exception. + * + * @param string $nick Bot nick + * @param string $username Bot username + * @param string $host Server hostname + * + * @return void + * @dataProvider dataProviderTestGetHostmaskMissingDataGeneratesException + */ + public function testGetHostmaskMissingDataGeneratesException($nick, $username, $host) + { + $options = array( + 'nick' => $nick, + 'username' => $username, + 'host' => $host, + ); + + $connection = new Phergie_Connection($options); + + try { + $hostmask = $connection->getHostmask(); + $this->fail('Expected exception was not thrown'); + } catch (Phergie_Connection_Exception $e) { + return; + } catch (Exception $e) { + $this->fail('Unexpected exception was thrown'); + } + } + + /** + * Tests that attempting to retrieve a hostmask with all required + * options is successful. + * + * @return void + */ + public function testGetHostmaskWithValidData() + { + $options = array( + 'nick' => 'MyNick', + 'username' => 'MyUsername', + 'host' => 'example.com' + ); + + $connection = new Phergie_Connection($options); + $hostmask = $connection->getHostmask(); + $this->assertType('Phergie_Hostmask', $hostmask); + } + + /** + * Data provider for testGetRequiredOptionsWithoutValuesSet(). + * + * @return array Enumerated array of enumerated arrays each containing a + * set of parameters for a single call to + * testGetRequiredOptionsWithoutValuesSet() + */ + public function dataProviderTestGetRequiredOptionsWithoutValuesSet() + { + return array( + array('host'), + array('nick'), + array('username'), + array('realname'), + ); + } + + /** + * Tests that attempting to retrieve values of required options when no + * values are set results in an exception. + * + * @param string $option Option name + * + * @return void + * @dataProvider dataProviderTestGetRequiredOptionsWithoutValuesSet + */ + public function testGetRequiredOptionsWithoutValuesSet($option) + { + try { + $connection = new Phergie_Connection; + $value = $connection->{'get' . ucfirst($option)}(); + $this->fail('Expected exception was not thrown'); + } catch (Phergie_Connection_Exception $e) { + return; + } catch (Exception $e) { + $this->fail('Unexpected exception was thrown'); + } + } + + /** + * Tests that attempting to set an invalid value for the transport + * results in an exception. + * + * @return void + */ + public function testSetTransportWithInvalidValue() + { + $connection = new Phergie_Connection; + try { + $connection->setTransport('blah'); + $this->fail('Expected exception was not thrown'); + } catch (Phergie_Connection_Exception $e) { + return; + } catch (Exception $e) { + $this->fail('Unexpected exception was thrown'); + } + } + + /** + * Tests that attempting to set an invalid value for the encoding + * results in an exception. + * + * @return void + */ + public function testSetEncodingWithInvalidValue() + { + $connection = new Phergie_Connection; + try { + $connection->setEncoding('blah'); + $this->fail('Expected exception was not thrown'); + } catch (Phergie_Connection_Exception $e) { + return; + } catch (Exception $e) { + $this->fail('Unexpected exception was thrown'); + } + } + + /** + * Tests that options can be set collectively after the connection is + * instantiated. + * + * @return void + */ + public function testSetOptions() + { + $connection = new Phergie_Connection; + $connection->setOptions($this->options); + foreach ($this->options as $key => $value) { + $this->assertEquals($value, $connection->{'get' . ucfirst($key)}()); + } + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/HandlerTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/HandlerTest.php new file mode 100644 index 000000000..9ecdd327a --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/HandlerTest.php @@ -0,0 +1,837 @@ +<?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 Pherge_Plugin_Handler. + * + * @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 + */ +class Phergie_Plugin_HandlerTest extends PHPUnit_Framework_TestCase +{ + /** + * Plugin handler instance being tested + * + * @var Phergie_Plugin_Handler + */ + protected $handler; + + /** + * Mock Phergie_Config instance passed to the plugin handler constructor + * + * @var Phergie_Config + */ + protected $config; + + /** + * Mock Phergie_Event_Handler instance passed to the plugin handler + * constructor + * + * @var Phergie_Event_Handler + */ + protected $events; + + /** + * Returns a mock plugin instance. + * + * @param string $name Optional short name for the mock plugin, defaults + * to 'TestPlugin' + * @param array $methods Optional list of methods to override + * + * @return Phergie_Plugin_Abstract + */ + protected function getMockPlugin($name = 'TestPlugin', array $methods = array()) + { + $methods[] = 'getName'; + $plugin = $this->getMock('Phergie_Plugin_Abstract', $methods); + $plugin + ->expects($this->any()) + ->method('getName') + ->will($this->returnValue($name)); + return $plugin; + } + + /** + * Sets up a new handler instance before each test. + * + * @return void + */ + public function setUp() + { + $this->config = $this->getMock('Phergie_Config'); + $this->events = $this->getMock('Phergie_Event_Handler'); + $this->handler = new Phergie_Plugin_Handler( + $this->config, + $this->events + ); + } + + /** + * Tests iterability of the plugin handler. + * + * @return void + */ + public function testImplementsIteratorAggregate() + { + $reflection = new ReflectionObject($this->handler); + + $this->assertTrue( + $reflection->implementsInterface('IteratorAggregate'), + 'Handler does not implement IteratorAggregate' + ); + + $this->assertType( + 'Iterator', + $this->handler->getIterator(), + 'getIterator() must return an iterator' + ); + } + + /** + * Tests that a default iterator is returned if none is explicitly set. + * + * @return void + */ + public function testGetIteratorReturnsDefault() + { + $this->assertType( + 'Phergie_Plugin_Iterator', + $this->handler->getIterator() + ); + } + + /** + * Tests the ability to change the handler's iterator class when a valid + * class is specified. + * + * @return void + */ + public function testSetIteratorClassWithValidClass() + { + eval(' + class DummyIterator extends FilterIterator { + public function accept() { + return true; + } + } + '); + + $this->handler->setIteratorClass('DummyIterator'); + + $this->assertType( + 'DummyIterator', + $this->handler->getIterator() + ); + } + + /** + * Tests that a failure occurs when a nonexistent iterator class is + * specified. + * + * @return void + */ + public function testSetIteratorClassWithNonexistentClass() + { + try { + $this->handler->setIteratorClass('FooIterator'); + $this->fail('Expected exception was not thrown'); + } catch (Phergie_Plugin_Exception $e) { + return; + } + $this->fail('Unexpected exception was thrown'); + } + + /** + * Tests that a failure occurs when a class that is not a subclass of + * FilterIterator is specified. + * + * @return void + */ + public function testSetIteratorClassWithNonFilterIteratorClass() + { + try { + $this->handler->setIteratorClass('ArrayIterator'); + $this->fail('Expected exception was not thrown'); + } catch (Phergie_Plugin_Exception $e) { + return; + } + $this->fail('Unexpected exception was thrown'); + } + + /** + * Tests countability of the plugin handler. + * + * @return void + */ + public function testImplementsCountable() + { + $reflection = new ReflectionObject($this->handler); + + $this->assertTrue( + $reflection->implementsInterface('Countable'), + 'Handler does not implement Countable' + ); + + $this->assertType( + 'int', + count($this->handler), + 'count() must return an integer' + ); + } + + /** + * Tests the plugin handler exposing added plugins as instance + * properties of the handler via isset(). + * + * @return void + */ + public function testImplementsIsset() + { + $pluginName = 'TestPlugin'; + $this->assertFalse(isset($this->handler->{$pluginName})); + $plugin = $this->getMockPlugin($pluginName); + $this->handler->addPlugin($plugin); + $this->assertTrue(isset($this->handler->{$pluginName})); + } + + /** + * Tests the plugin handler exposing added plugins as instance + * properties of the handler. + * + * @depends testImplementsIsset + * @return void + */ + public function testImplementsGet() + { + $plugin = $this->getMockPlugin(); + $this->handler->addPlugin($plugin); + $name = $plugin->getName(); + $getPlugin = $this->handler->getPlugin($name); + $this->assertTrue(isset($this->handler->$name)); + $get = $this->handler->$name; + $this->assertSame($getPlugin, $get); + } + + /** + * Tests the plugin handler allowing for plugin removal via unset(). + * + * @depends testImplementsGet + * @return void + */ + public function testImplementsUnset() + { + $plugin = $this->getMockPlugin(); + $this->handler->addPlugin($plugin); + unset($this->handler->{$plugin->getName()}); + $this->assertFalse($this->handler->hasPlugin($plugin->getName())); + } + + /** + * Tests the plugin handler executing a callback on all contained + * plugins. + * + * @return void + */ + public function testImplementsCall() + { + foreach (range(1, 2) as $index) { + $plugin = $this->getMockPlugin('TestPlugin' . $index, array('callback')); + $plugin + ->expects($this->once()) + ->method('callback'); + $this->handler->addPlugin($plugin); + } + + $this->assertTrue($this->handler->callback()); + } + + /** + * Tests a newly instantiated handler not having plugins associated with + * it. + * + * @depends testImplementsCountable + * @return void + */ + public function testEmptyHandlerHasNoPlugins() + { + $this->assertEquals(0, count($this->handler)); + } + + /** + * Tests a newly instantiated handler not having autoloading enabled by + * default. + * + * @return void + */ + public function testGetAutoloadDefaultsToNotAutoload() + { + $this->assertFalse($this->handler->getAutoload()); + } + + /** + * Tests setAutoload(). + * + * @depends testGetAutoloadDefaultsToNotAutoload + * @return void + */ + public function testSetAutoload() + { + $this->assertSame( + $this->handler->setAutoload(true), + $this->handler, + 'setAutoload() does not provide a fluent interface' + ); + + $this->assertTrue( + $this->handler->getAutoload(), + 'setAutoload() had no effect on getAutoload()' + ); + } + + /** + * Tests addPath() providing a fluent interface. + * + * @return void + */ + public function testAddPathProvidesFluentInterface() + { + $handler = $this->handler->addPath(dirname(__FILE__)); + $this->assertSame($this->handler, $handler); + } + + /** + * Tests addPath() throwing an exception when it cannot read the + * directory. + * + * @return void + */ + public function testAddPathThrowsExceptionOnUnreadableDirectory() + { + try { + $this->handler->addPath('/an/unreadable/directory/path'); + } catch(Phergie_Plugin_Exception $e) { + $this->assertEquals( + Phergie_Plugin_Exception::ERR_DIRECTORY_NOT_READABLE, + $e->getCode() + ); + return; + } + + $this->fail('An expected exception has not been raised'); + } + + /** + * Tests adding a path to the plugin handler. + * + * @return void + */ + public function testAddPath() + { + $pluginName = 'Mock'; + + try { + $this->handler->addPlugin($pluginName); + } catch(Phergie_Plugin_Exception $e) { + $this->assertEquals( + Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND, + $e->getCode() + ); + } + + if (!isset($e)) { + $this->fail('Plugin loaded, path was already present'); + } + + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + + try { + $this->handler->addPlugin($pluginName); + } catch(Phergie_Plugin_Exception $e) { + $this->fail('Added path, plugin still not found'); + } + } + + /** + * Tests addPlugin() returning an added plugin instance. + * + * @return void + */ + public function testAddPluginByInstanceReturnsPluginInstance() + { + $plugin = $this->getMockPlugin(); + $returnedPlugin = $this->handler->addPlugin($plugin); + $this->assertSame( + $returnedPlugin, + $plugin, + 'addPlugin() does not return the instance passed to it' + ); + } + + /** + * Tests adding a plugin to the handler using the plugin's short name. + * + * @return void + */ + public function testAddPluginByShortName() + { + $pluginName = 'Mock'; + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + + $returnedPlugin = $this->handler->addPlugin($pluginName); + $this->assertTrue($this->handler->hasPlugin($pluginName)); + + $this->assertType( + 'Phergie_Plugin_Mock', + $this->handler->getPlugin($pluginName) + ); + + $this->assertSame( + $this->handler->getPlugin($pluginName), + $returnedPlugin, + 'Handler does not contain added plugin' + ); + } + + + /** + * Tests adding a plugin instance to the handler. + * + * @return void + */ + public function testAddPluginByInstance() + { + $plugin = $this->getMockPlugin(); + $returnedPlugin = $this->handler->addPlugin($plugin); + $this->assertTrue($this->handler->hasPlugin('TestPlugin')); + + $this->assertSame( + $plugin, + $returnedPlugin, + 'addPlugin() does not return added plugin instance' + ); + + $this->assertSame( + $plugin, + $this->handler->getPlugin('TestPlugin'), + 'getPlugin() does not return added plugin instance' + ); + } + + /** + * Tests addPlugin() throwing an exception when the plugin class file + * can't be found. + * + * @return void + */ + public function testAddPluginThrowsExceptionWhenPluginFileNotFound() + { + try { + $this->handler->addPlugin('TestPlugin'); + } catch(Phergie_Plugin_Exception $e) { + $this->assertEquals( + Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND, + $e->getCode() + ); + return; + } + + $this->fail('An expected exception has not been raised'); + } + + /** + * Recursively removes all files and subdirectories in a directory. + * + * @param string $path Directory path + * @return void + */ + private function removeDirectory($path) + { + if (file_exists($path)) { + $it = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path), + RecursiveIteratorIterator::CHILD_FIRST + ); + foreach ($it as $entry) { + if ($it->isDot()) { + continue; + } + if ($entry->isDir()) { + rmdir($entry->getPathname()); + } else { + unlink($entry->getPathname()); + } + } + } + } + + /** + * Tests addPlugin() throwing an exception when the plugin class file is + * found, but does not contain the plugin class as expected. + * + * @return void + */ + public function testAddPluginThrowsExceptionWhenPluginClassNotFound() + { + $path = sys_get_temp_dir() . '/Phergie/Plugin'; + $this->removeDirectory(dirname($path)); + mkdir($path, 0777, true); + touch($path . '/TestPlugin.php'); + $this->handler->addPath($path, 'Phergie_Plugin_'); + + try { + $this->handler->addPlugin('TestPlugin'); + } catch(Phergie_Plugin_Exception $e) { } + + if (isset($e)) { + $this->assertEquals( + Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND, + $e->getCode() + ); + } else { + $this->fail('An expected exception has not been raised'); + } + + $this->removeDirectory(dirname($path)); + } + + /** + * Tests addPlugin() throwing an exception when trying to instantiate a + * class that doesn't extend Phergie_Plugin_Abstract. + * + * @return void + */ + public function testAddPluginThrowsExceptionIfRequestingNonPlugin() + { + try { + $this->handler->addPlugin('Handler'); + } catch(Phergie_Plugin_Exception $e) { + $this->assertEquals( + Phergie_Plugin_Exception::ERR_INCORRECT_BASE_CLASS, + $e->getCode() + ); + return; + } + + $this->fail('An expected exception has not been raised'); + } + + /** + * Tests addPlugin() throwing an exception when trying to instantiate a + * class that can't be instantiated. + * + * @return void + */ + public function testAddPluginThrowsExceptionIfPluginNotInstantiable() + { + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + try { + $this->handler->addPlugin('TestNonInstantiablePluginFromFile'); + } catch(Phergie_Plugin_Exception $e) { + $this->assertEquals( + Phergie_Plugin_Exception::ERR_CLASS_NOT_INSTANTIABLE, + $e->getCode() + ); + return; + } + + $this->fail('An expected exception has not been raised'); + } + + /** + * Tests adding a plugin by its short name with arguments passed to the + * plugin constructor. + * + * @return void + */ + public function testAddPluginShortNamePassesArgsToConstructor() + { + $pluginName = 'Mock'; + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + + $arguments = array('a', 'b', 'c'); + $plugin = $this->handler->addPlugin($pluginName, $arguments); + + $this->assertAttributeSame( + $arguments, + 'arguments', + $plugin, + 'Arguments do not match' + ); + } + + /** + * Tests addPlugin() passing Phergie_Config to an instantiated plugin. + * + * @return void + */ + public function testAddPluginPassesConstructorArguments() + { + $pluginName = 'Mock'; + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + $plugin = $this->handler->addPlugin($pluginName); + + $this->assertSame( + $this->config, + $plugin->getConfig(), + 'Phergie_Config instances do not match' + ); + + $this->assertSame( + $this->events, + $plugin->getEventHandler(), + 'Phergie_Event_Handler instances do not match' + ); + } + + /** + * Tests addPlugin() calling onLoad() on an instantiated plugin. + * + * @return void + */ + public function testAddPluginCallsOnLoadOnInstantiatedPlugin() + { + $plugin = $this->getMockPlugin(null, array('onLoad')); + $plugin + ->expects($this->once()) + ->method('onLoad'); + $this->handler->addPlugin($plugin); + } + + /** + * Tests addPlugin() returning the same plugin when called twice. + * + * @return void + */ + public function testAddPluginReturnsSamePluginWhenAskedTwice() + { + $pluginName = 'Mock'; + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + $plugin1 = $this->handler->addPlugin($pluginName); + $plugin2 = $this->handler->addPlugin($pluginName); + $this->assertSame($plugin1, $plugin2); + } + + /** + * Tests getPlugin() throwing an exception when trying to get an + * unloaded plugin with autoload disabled. + * + * @depends testGetAutoloadDefaultsToNotAutoload + * @return void + */ + public function testExceptionThrownWhenLoadingPluginWithoutAutoload() + { + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + + try { + $this->handler->getPlugin('Mock'); + } catch (Phergie_Plugin_Exception $expected) { + $this->assertEquals( + Phergie_Plugin_Exception::ERR_PLUGIN_NOT_LOADED, + $expected->getCode() + ); + return; + } + + $this->fail('An expected exception has not been raised'); + } + + /** + * Tests addPlugins() with a plugin short name and no plugin constructor + * arguments. + * + * @depends testAddPluginByShortName + * @depends testAddPluginByInstance + * @return void + */ + public function testAddPluginsWithoutArguments() + { + $prefix = 'Phergie_Plugin_'; + $this->handler->addPath(dirname(__FILE__), $prefix); + + $plugin = 'Mock'; + $this->handler->addPlugins(array($plugin)); + $returnedPlugin = $this->handler->getPlugin($plugin); + $this->assertContains( + get_class($returnedPlugin), + $prefix . $plugin, + 'Short name plugin not of expected class' + ); + } + + /** + * Tests addPlugins() with a plugin short name and plugin constructor + * arguments. + * + * @depends testAddPluginByShortName + * @depends testAddPluginByInstance + * @return void + */ + public function testAddPluginsWithArguments() + { + $prefix = 'Phergie_Plugin_'; + $this->handler->addPath(dirname(__FILE__), $prefix); + + $arguments = array(1, 2, 3); + $plugin = array('Mock', $arguments); + $this->handler->addPlugins(array($plugin)); + $returnedPlugin = $this->handler->getPlugin('Mock'); + $this->assertEquals( + $arguments, + $returnedPlugin->getArguments(), + 'Constructor arguments for instance plugin do not match' + ); + } + + /** + * Tests removePlugin() with a plugin instance. + * + * @depends testAddPluginByInstance + * @return void + */ + public function testRemovePluginByInstance() + { + $plugin = $this->getMockPlugin(); + $this->handler->addPlugin($plugin); + $this->handler->removePlugin($plugin); + $this->assertFalse( + $this->handler->hasPlugin($plugin->getName()), + 'Plugin was not removed' + ); + } + + /** + * Tests removePlugin() with a plugin short name. + * + * @depends testAddPluginByShortName + * @return void + */ + public function testRemovePluginByShortName() + { + $plugin = 'Mock'; + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + + $this->handler->addPlugin($plugin); + $this->handler->removePlugin($plugin); + $this->assertFalse( + $this->handler->hasPlugin($plugin), + 'Plugin was not removed' + ); + } + + /** + * Tests getPlugin() when the plugin is not already loaded and + * autoloading is disabled. + * + * @depends testSetAutoload + * @return void + */ + public function testGetPluginWithAutoloadEnabled() + { + $this->handler->setAutoload(true); + $this->handler->addPath(dirname(__FILE__), 'Phergie_Plugin_'); + $plugin = $this->handler->getPlugin('Mock'); + $this->assertType( + 'Phergie_Plugin_Mock', + $plugin, + 'Retrieved plugin not of expected class' + ); + } + + /** + * Tests getPlugins(). + * + * @depends testGetPluginWithAutoloadEnabled + * @return void + */ + public function testGetPlugins() + { + $plugin1 = $this->getMockPlugin('TestPlugin1'); + $this->handler->addPlugin($plugin1); + + $plugin2 = $this->getMockPlugin('TestPlugin2'); + $this->handler->addPlugin($plugin2); + + $expected = array( + 'testplugin1' => $plugin1, + 'testplugin2' => $plugin2, + ); + + $actual = $this->handler->getPlugins(); + $this->assertEquals($expected, $actual); + + $actual = $this->handler->getPlugins(array('testplugin1', 'testplugin2')); + $this->assertEquals($expected, $actual); + } + + /** + * Tests that multiple plugin iterators can be used concurrently. + * + * @return void + */ + public function testUseMultiplePluginIteratorsConcurrently() + { + $plugin1 = $this->getMockPlugin('TestPlugin1'); + $this->handler->addPlugin($plugin1); + + $plugin2 = $this->getMockPlugin('TestPlugin2'); + $this->handler->addPlugin($plugin2); + + $iterator1 = $this->handler->getIterator(); + $iterator1->next(); + $this->assertSame($plugin2, $iterator1->current()); + + $iterator2 = $this->handler->getIterator(); + $this->assertSame($plugin1, $iterator2->current()); + } + + /** + * Tests adding plugin paths via configuration. + * + * @return void + */ + public function testAddPluginPathsViaConfiguration() + { + $dir = dirname(__FILE__); + $prefix = 'Phergie_Plugin_'; + $paths = array($dir => $prefix); + $this->config + ->expects($this->any()) + ->method('offsetExists') + ->will($this->returnValue(true)); + $this->config + ->expects($this->any()) + ->method('offsetGet') + ->will($this->returnValue($paths)); + + // Reinitialize the handler so the configuration change takes effect + // within the constructor + $this->handler = new Phergie_Plugin_Handler( + $this->config, + $this->events + ); + + $this->handler->setAutoload(true); + $this->handler->getPlugin('Mock'); + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/IteratorTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/IteratorTest.php new file mode 100644 index 000000000..336b25d35 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/IteratorTest.php @@ -0,0 +1,151 @@ +<?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 Pherge_Plugin_Iterator. + * + * @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 + */ +class Phergie_Plugin_IteratorTest extends PHPUnit_Framework_TestCase +{ + /** + * Iterator instance being tested + * + * @var Phergie_Plugin_Iterator + */ + protected $iterator; + + /** + * List of mock plugin instances to be iterated + * + * @var array + */ + protected $plugins; + + /** + * Initializes the iterator instance being tested. + * + * @return void + */ + public function setUp() + { + $this->plugins = array(); + foreach (range(0, 4) as $index) { + $plugin = $this->getMock('Phergie_Plugin_Abstract'); + $plugin + ->expects($this->any()) + ->method('getName') + ->will($this->returnValue($index)); + $this->plugins[] = $plugin; + } + + $this->iterator = new Phergie_Plugin_Iterator( + new ArrayIterator($this->plugins) + ); + } + + /** + * Tests that all plugins are iterated when no filters are applied. + */ + public function testIteratesAllPluginsWithNoFilters() + { + $expected = range(0, 4); + $actual = array(); + foreach ($this->iterator as $plugin) { + $actual[] = $plugin->getName(); + } + $this->assertEquals($expected, $actual); + } + + /** + * Tests that appropriate plugins are iterated when plugin name filters + * are applied. + */ + public function testIteratesPluginsWithNameFilters() + { + // Test acceptance of strings and fluent interface implementation + $returned = $this->iterator->addPluginFilter('0'); + $this->assertSame($this->iterator, $returned); + + // Test acceptance of arrays + $this->iterator->addPluginFilter(array('1', '3')); + + // Test application of filters to iteration + $expected = array('2', '4'); + $actual = array(); + foreach ($this->iterator as $plugin) { + $actual[] = $plugin->getName(); + } + $this->assertEquals($expected, $actual); + } + + /** + * Tests that appropriate plugins are iterated when method name filters + * are applied. + * + * The same method name is used in all cases here because mocked methods + * of mock objects do not appear to be detected by method_exists() or + * ReflectionClass, so filtering by a method defined in the base plugin + * class seems the easiest way to test that method filtering really + * works. + */ + public function testIteratesPluginsWithMethodFilters() + { + // Tests acceptance of strings and fluent interface implementation + $returned = $this->iterator->addMethodFilter('getName'); + $this->assertSame($this->iterator, $returned); + + // Test acceptance of arrays + $this->iterator->addMethodFilter(array('getName', 'getName')); + + // Test application of filters to iteration + $expected = array(); + $actual = array(); + foreach ($this->iterator as $plugin) { + $actual[] = $plugin->getName(); + } + $this->assertEquals($expected, $actual); + } + + /** + * Tests that all plugins are iterated after filters are cleared. + * + * @depends testIteratesPluginsWithNameFilters + * @depends testIteratesPluginsWithMethodFilters + */ + public function testIteratesPluginsAfterClearingFilters() + { + $this->iterator->addPluginFilter('0'); + $this->iterator->addMethodFilter('method1'); + $this->iterator->clearFilters(); + + $expected = range(0, 4); + $actual = array(); + foreach ($this->iterator as $plugin) { + $actual[] = $plugin->getName(); + } + $this->assertEquals($expected, $actual); + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/KarmaTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/KarmaTest.php new file mode 100644 index 000000000..6b7231674 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/KarmaTest.php @@ -0,0 +1,335 @@ +<?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 Pherge_Plugin_Karma. + * + * @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 + */ +class Phergie_Plugin_KarmaTest extends Phergie_Plugin_TestCase +{ + /** + * Skips tests if the SQLite PDO driver is not available. + * + * @return void + */ + public function setUp() + { + if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) { + $this->markTestSkipped('PDO or pdo_sqlite extension is required'); + } + + parent::setUp(); + } + + /** + * Configures the plugin to use a temporary copy of the database. + * + * @return PDO Connection to the temporary database + */ + private function createMockDatabase() + { + $dbPath = $this->getPluginsPath('Karma/karma.db'); + $db = $this->getMockDatabase($dbPath); + $this->plugin->setDb($db); + return $db; + } + + /** + * Tests the requirement of the Command plugin. + * + * @return void + */ + public function testRequiresCommandPlugin() + { + $this->assertRequiresPlugin('Command'); + $this->plugin->onLoad(); + } + + /** + * Initiates a karma event with a specified term. + * + * @param string $term Karma term + * + * @return Phergie_Event_Request Initiated mock event + */ + private function initiateKarmaEvent($term) + { + $args = array( + 'receiver' => $this->source, + 'text' => 'karma ' . $term + ); + $event = $this->getMockEvent('privmsg', $args); + $this->plugin->setEvent($event); + return $event; + } + + /** + * Checks for an expected karma response. + * + * @param Phergie_Event_Request $event Event containing the karma + * request + * @param string $term Karma term + * @param string $response Portion of the response + * message following the term + * from the original event + * + * @return void + */ + private function checkForKarmaResponse($event, $term, $response) + { + $text = $event->getNick() . ': ' . $response; + $this->assertEmitsEvent('privmsg', array($event->getSource(), $text)); + $this->plugin->onCommandKarma($term); + } + + /** + * Tests that a default database is used when none is specified. + * + * @return void + */ + public function testGetDb() + { + $db = $this->plugin->getDb(); + $this->assertType('PDO', $db); + } + + /** + * Tests specifying a custom database for the plugin to use. + * + * @return void + */ + public function testSetDb() + { + $db = $this->createMockDatabase(); + $this->assertSame($db, $this->plugin->getDb()); + } + + /** + * Tests that issuing the karma command with an unknown term returns a + * neutral rating. + * + * @return void + */ + public function testKarmaCommandOnUnknownTerm() + { + $term = 'foo'; + $this->createMockDatabase(); + $event = $this->initiateKarmaEvent($term); + $this->checkForKarmaResponse($event, $term, $term . ' has neutral karma.'); + } + + /** + * Tests that issuing the karma command with the term "me" returns the + * the karma rating for the initiating user. + * + * @return void + */ + public function testKarmaCommandOnUser() + { + $term = 'me'; + $this->createMockDatabase(); + $event = $this->initiateKarmaEvent($term); + $this->checkForKarmaResponse($event, $term, 'You have neutral karma.'); + } + + /** + * Tests that issuing the karma command with a term that has a fixed + * karma rating results in that rating being returned. + * + * @return void + */ + public function testKarmaCommandWithFixedKarmaTerm() + { + $term = 'phergie'; + $this->createMockDatabase(); + $event = $this->initiateKarmaEvent($term); + $this->checkForKarmaResponse($event, $term, 'phergie has karma of awesome.'); + } + + /** + * Supporting method that tests the result of a karma term rating change. + * + * @param string $term Karma term for which the rating is being + * changed + * @param string $operation ++ or -- + * @param int $karma Expected karma rating after the change is + * applied + */ + private function checkForKarmaRatingChange($term, $operation, $karma) + { + $args = array( + 'receiver' => $this->source, + 'text' => $term . $operation + ); + $event = $this->getMockEvent('privmsg', $args); + $this->plugin->setEvent($event); + $this->plugin->onPrivmsg(); + $event = $this->initiateKarmaEvent($term); + $this->checkForKarmaResponse($event, $term, $term . ' has karma of ' . $karma . '.'); + } + + /** + * Tests incrementing the karma rating of a new term. + * + * @return void + */ + public function testIncrementingKarmaRating() + { + $this->createMockDatabase(); + $this->checkForKarmaRatingChange('foo', '++', 1); + } + + /** + * Tests decrementing the karma rating of a new term. + * + * @return void + */ + public function testDecrementingKarmaRating() + { + $this->createMockDatabase(); + $this->checkForKarmaRatingChange('foo', '--', -1); + } + + /** + * Tests modifying the karma rating of an existing term. + * + * @return void + */ + public function testChangingExistingKarmaRating() + { + $term = 'foo'; + $this->createMockDatabase(); + $this->checkForKarmaRatingChange($term, '++', 1); + $this->checkForKarmaRatingChange($term, '++', 2); + } + + /** + * Tests resetting the karma rating of an existing term to 0. + * + * @return void + */ + public function testResettingExistingKarmaRating() + { + $term = 'foo'; + $this->createMockDatabase(); + $this->checkForKarmaRatingChange($term, '++', 1); + $this->plugin->onCommandReincarnate($term); + $event = $this->initiateKarmaEvent($term); + $this->checkForKarmaResponse($event, $term, $term . ' has neutral karma.'); + } + + /** + * Data provider for testKarmaComparisons(). + * + * @return array Enumerated array of enumerated arrays each containing a + * set of parameter values for a single call to + * testKarmaComparisons() + */ + public function dataProviderTestKarmaComparisons() + { + $term1 = 'foo'; + $term2 = 'bar'; + + $positive = 'True that.'; + $negative = 'No sir, not at all.'; + + return array( + array($term1, $term2, 1, 0, '>', $positive), + array($term1, $term2, 0, 1, '>', $negative), + array($term1, $term2, 1, 1, '>', $negative), + array($term1, $term2, 1, 0, '<', $negative), + array($term1, $term2, 0, 1, '<', $positive), + array($term1, $term2, 1, 1, '<', $negative), + array($term1, 'phergie', 1, 0, '>', $positive), + array('phergie', $term2, 0, 1, '<', $positive), + array($term1, 'everything', 0, 0, '>', $positive), + array('everything', $term2, 0, 0, '>', $positive), + ); + } + + /** + * Tests comparing the karma ratings of two terms. + * + * @param string $term1 First term + * @param string $term2 Second term + * @param int $karma1 Karma rating of the first time, 0 or 1 + * @param int $karma2 Karma rating of the second term, 0 or 1 + * @param string $operator Comparison operator, > or < + * @param string $response Response to check for + * + * @return void + * @dataProvider dataProviderTestKarmaComparisons + */ + public function testKarmaComparisons($term1, $term2, $karma1, $karma2, + $operator, $response + ) { + $db = $this->createMockDatabase(); + + // Reduce answer tables to expected response + $stmt = $db->prepare('DELETE FROM positive_answers WHERE answer != ?'); + $stmt->execute(array($response)); + $stmt = $db->prepare('DELETE FROM negative_answers WHERE answer != ?'); + $stmt->execute(array($response)); + + if ($karma1) { + $this->checkForKarmaRatingChange($term1, '++', 1); + } + + if ($karma2) { + $this->checkForKarmaRatingChange($term2, '++', 1); + } + + $args = array( + 'receiver' => $this->source, + 'text' => $term1 . ' ' . $operator . ' ' . $term2 + ); + $event = $this->getMockEvent('privmsg', $args); + $this->plugin->setEvent($event); + + // Test lack of a response for terms with fixed karma ratings + if ($term1 == 'phergie' || $term2 == 'phergie') { + $callback = 'assertDoesNotEmitEvent'; + } else { + $callback = 'assertEmitsEvent'; + } + + $this->$callback('privmsg', array($event->getSource(), $response)); + $this->plugin->onPrivmsg(); + + // Test for karma changes when one term is "everything" + if ($term1 == 'everything' || $term2 == 'everything') { + if ($term1 == 'everything') { + $term = $term2; + $karma = ($operator == '>') ? -1 : 1; + } else { + $term = $term1; + $karma = ($operator == '>') ? 1 : -1; + } + $event = $this->initiateKarmaEvent($term); + $this->checkForKarmaResponse($event, $term, $term . ' has karma of ' . $karma . '.'); + } + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/Mock.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/Mock.php new file mode 100755 index 000000000..44a5d11c7 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/Mock.php @@ -0,0 +1,61 @@ +<?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 + */ + +/** + * Creates a plugin on the filesystem that can be used by + * Phergie_Plugin_Handler::addPath() to be located and loaded. + * + * @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 + */ +class Phergie_Plugin_Mock extends Phergie_Plugin_Abstract +{ + /** + * Arguments passed to the constructor + * + * @var array + */ + protected $arguments; + + /** + * Stores all arguments for later use. + * + * @return void + */ + public function __construct() + { + $this->arguments = func_get_args(); + } + + /** + * Returns all constructor arguments. + * + * @return array Enumerated array containing the arguments passed to the + * constructor in order + */ + public function getArguments() + { + return $this->arguments; + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/PingTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/PingTest.php new file mode 100644 index 000000000..ac30d46ff --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/PingTest.php @@ -0,0 +1,164 @@ +<?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 Pherge_Plugin_Ping. + * + * @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 + */ +class Phergie_Plugin_PingTest extends Phergie_Plugin_TestCase +{ + /** + * Tests that the last ping and event are initialized on connection to + * the server. + * + * @return void + */ + public function testOnConnect() + { + $this->plugin->onConnect(); + + $expected = time(); + $actual = $this->plugin->getLastEvent(); + $this->assertEquals($expected, $actual); + + $expected = null; + $actual = $this->plugin->getLastPing(); + $this->assertEquals($expected, $actual); + } + + /** + * Tests that the last event is reset when an event occurs. + * + * @return void + */ + public function testPreEvent() + { + $this->plugin->preEvent(); + + $expected = time(); + $actual = $this->plugin->getLastEvent(); + $this->assertEquals($expected, $actual); + } + + /** + * Tests that the last ping is reset when a ping is received. + * + * @return void + */ + public function testOnPingResponse() + { + $this->plugin->onPingResponse(); + + $expected = null; + $actual = $this->plugin->getLastPing(); + $this->assertEquals($expected, $actual); + } + + /** + * Tests that the test suite is able to manipulate the value of the last + * event. + * + * @return void + */ + public function testSetLastEvent() + { + $expected = time() + 1; + $this->plugin->setLastEvent($expected); + $actual = $this->plugin->getLastEvent(); + $this->assertEquals($expected, $actual); + + $this->plugin->setLastEvent(); + $expected = time(); + $actual = $this->plugin->getLastEvent(); + $this->assertEquals($expected, $actual); + + try { + $this->plugin->setLastEvent('foo'); + $this->fail('Expected exception was not thrown'); + } catch (Exception $e) { } + } + + /** + * Tests that the test suite is able to manipulate the value of the last + * ping. + * + * @return void + */ + public function testSetLastPing() + { + $expected = time() + 1; + $this->plugin->setLastPing($expected); + $actual = $this->plugin->getLastPing(); + $this->assertEquals($expected, $actual); + + $this->plugin->setLastPing(); + $expected = time(); + $actual = $this->plugin->getLastPing(); + $this->assertEquals($expected, $actual); + + try { + $this->plugin->setLastPing('foo'); + $this->fail('Expected exception was not thrown'); + } catch (Exception $e) { } + } + + /** + * Tests that a ping event is sent after the appropriate time period has + * lapsed since receiving an event. + * + * @depends testSetLastEvent + * @return void + */ + public function testPing() + { + $pingEvent = 10; + $this->setConfig('ping.event', $pingEvent); + $lastEvent = time() - ($pingEvent + 1); + $this->plugin->setLastEvent($lastEvent); + $expected = time(); + $this->assertEmitsEvent('ping', array($this->nick, $expected)); + $this->plugin->onTick(); + $actual = $this->plugin->getLastPing(); + $this->assertEquals($expected, $actual); + } + + /** + * Tests that a quit event is sent after the appropriate time period has + * lapsed since sending a ping event. + * + * @depends testPing + * @return void + */ + public function testQuit() + { + $pingPing = 10; + $this->setConfig('ping.ping', $pingPing); + $lastPing = time() - ($pingPing + 1); + $this->plugin->setLastPing($lastPing); + $this->assertEmitsEvent('quit'); + $this->plugin->onTick(); + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/PongTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/PongTest.php new file mode 100644 index 000000000..e8351fef2 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/PongTest.php @@ -0,0 +1,46 @@ +<?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 Pherge_Plugin_Pong. + * + * @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 + */ +class Phergie_Plugin_PongTest extends Phergie_Plugin_TestCase +{ + /** + * Test that a pong event is sent when a ping event is received. + * + * @return void + */ + public function testPong() + { + $expected = 'irc.freenode.net'; + $event = $this->getMockEvent('ping', array($expected)); + $this->plugin->setEvent($event); + $this->assertEmitsEvent('pong', array($expected)); + $this->plugin->onPing(); + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/SpellCheckTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/SpellCheckTest.php new file mode 100644 index 000000000..369a0c644 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/SpellCheckTest.php @@ -0,0 +1,166 @@ +<?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 Pherge_Plugin_SpellCheck. + * + * @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 + */ +class Phergie_Plugin_SpellCheckTest extends Phergie_Plugin_TestCase +{ + /** + * Checks for the pspell extension. + * + * @return void + */ + public function setUp() + { + parent::setUp(); + + if (!extension_loaded('pspell')) { + $this->markTestSkipped('pspell extension not available'); + } + } + + /** + * Tests for the plugin failing to load when the language setting is not + * specified. + * + * @return void + */ + public function testLanguageSettingNotSet() + { + try { + $this->plugin->onLoad(); + $this->fail('Expected exception was not thrown'); + } catch (Phergie_Plugin_Exception $e) { + return; + } + $this->fail('Unexpected exception was thrown'); + } + + /** + * Tests for the plugin requiring the Command plugin as a dependency. + * + * @return void + */ + public function testRequiresCommandPlugin() + { + $this->setConfig('spellcheck.lang', 'en'); + $this->assertRequiresPlugin('Command'); + $this->plugin->onLoad(); + } + + /** + * Tests for the plugin failing to load because of a dictionary error. + * + * @return void + */ + public function testLoadDictionaryError() + { + $this->setConfig('spellcheck.lang', 'foo'); + try { + $this->plugin->onLoad(); + $this->fail('Expected exception not thrown'); + } catch (Phergie_Plugin_Exception $e) { + return; + } + $this->fail('Unexpected exception was thrown'); + } + + /** + * Initializes a spell check event. + * + * @param string $word Word to be checked + * + * @return void + */ + private function initializeSpellCheckEvent($word) + { + $this->setConfig('spellcheck.lang', 'en'); + $this->plugin->onLoad(); + $args = array( + 'receiver' => $this->source, + 'text' => 'spell ' . $word + ); + $event = $this->getMockEvent('privmsg', $args); + $this->plugin->setEvent($event); + } + + /** + * Checks for a specified response to a spell check event. + * + * @param string $word Work being checked + * @param string $response Expected response + * + * @return void + */ + private function checkForSpellCheckResponse($word, $response) + { + $this->assertEmitsEvent('privmsg', array($this->source, $response)); + $this->plugin->onCommandSpell($word); + } + + /** + * Tests for the plugin returning a response for a correctly spelled word. + * + * @return void + */ + public function testRespondsForCorrectlySpelledWord() + { + $word = 'test'; + $this->initializeSpellCheckEvent($word); + $response = $this->nick . ': The word "' . $word . '" seems to be spelled correctly.'; + $this->checkForSpellCheckResponse($word, $response); + } + + /** + * Tests for the plugin returning a response when it can't find any + * suggestions for a word. + * + * @return void + */ + public function testRespondsWithoutSuggestions() + { + $word = 'kjlfljlkjljkljlj'; + $this->initializeSpellCheckEvent($word); + $response = $this->nick . ': I could not find any suggestions for "' . $word . '".'; + $this->checkForSpellCheckResponse($word, $response); + } + + /** + * Tests for the plugin returning a response when it is able to find + * suggestions for a word. + * + * @return void + */ + public function testRespondsWithSuggestions() + { + $word = 'teh'; + $this->initializeSpellCheckEvent($word); + $response = $this->nick . ': Suggestions for "' . $word . '": the, Te, tech, Th, eh.'; + $this->checkForSpellCheckResponse($word, $response); + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TerryChayTest.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TerryChayTest.php new file mode 100644 index 000000000..e58ac6f29 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TerryChayTest.php @@ -0,0 +1,135 @@ +<?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 Pherge_Plugin_TerryChay. + * + * @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 + */ +class Phergie_Plugin_TerryChayTest extends Phergie_Plugin_TestCase +{ + /** + * Chayism used as a consistent response when related events are + * triggered + * + * @var string + */ + private $chayism = 'Terry Chay doesn\'t need a framework; he already knows everyone\'s code'; + + /** + * Configures the mock plugin handler to return a mock Http plugin with + * a mock response object populated with predetermined content. + * + * @return void + */ + public function setUpHttpClient() + { + $response = $this->getMock('Phergie_Plugin_Http_Response'); + $response + ->expects($this->any()) + ->method('getContent') + ->will($this->returnValue($this->chayism)); + + $plugin = $this->getMock('Phergie_Plugin_Http'); + $plugin + ->expects($this->any()) + ->method('get') + ->will($this->returnValue($response)); + + $this->getMockPluginHandler() + ->expects($this->any()) + ->method('getPlugin') + ->with('Http') + ->will($this->returnValue($plugin)); + } + + /** + * Tests that the plugin requires the Http plugin as a dependency. + * + * @return void + */ + public function testRequiresHttpPlugin() + { + $this->assertRequiresPlugin('Http'); + $this->plugin->onLoad(); + } + + /** + * Data provider for testPrivmsgTriggerReturnsChayism(). + * + * @return array Enumerated array of enumerated arrays each containing + * a set of parameters for a single call to + * testPrivmsgTriggerReturnsChayism() + */ + public function dataProviderTestPrivmsgTriggerReturnsChayism() + { + return array( + array('terry chay'), + array('terry chay'), + array('tychay'), + array('!tychay'), + array('! tychay'), + array('foo tychay bar'), + ); + } + + /** + * Tests that appropriate triggers result in a response with a Chayism. + * + * @return void + * @dataProvider dataProviderTestPrivmsgTriggerReturnsChayism + */ + public function testPrivmsgTriggerReturnsChayism($trigger) + { + $this->setConfig('command.prefix', '!'); + $this->setUpHttpClient(); + $args = array( + 'receiver' => $this->source, + 'text' => $trigger + ); + $event = $this->getMockEvent('privmsg', $args); + $this->plugin->setEvent($event); + $this->assertEmitsEvent('privmsg', array($this->source, 'Fact: ' . $this->chayism)); + $this->plugin->onPrivmsg(); + } + + /** + * Tests that lack of an appropriate trigger results in no response with + * a Chayism. + * + * @return void + */ + public function testNoPrivmsgTriggerDoesNotReturnChayism() + { + $args = array( + 'receiver' => $this->source, + 'text' => 'foo bar baz' + ); + $event = $this->getMockEvent('privmsg', $args); + $this->plugin->setEvent($event); + $this->assertDoesNotEmitEvent('privmsg', array($this->source, 'Fact: ' . $this->chayism)); + $this->plugin->onPrivmsg(); + } +} 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; + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestNonInstantiablePluginFromFile.php b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestNonInstantiablePluginFromFile.php new file mode 100755 index 000000000..f9bddd151 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/TestNonInstantiablePluginFromFile.php @@ -0,0 +1,43 @@ +<?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 + */ + +/** + * Creates a plugin on the filesystem that can be used by + * Phergie_Plugin_Handler's addPath utility to be located and loaded. + * + * @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 + */ +class Phergie_Plugin_TestNonInstantiablePluginFromFile +extends Phergie_Plugin_Abstract +{ + /** + * Private constructor to ensure that this class is not instantiable. + * + * @return void + */ + private function __construct() + { + } +} diff --git a/plugins/Irc/extlib/phergie/Tests/TestHelper.php b/plugins/Irc/extlib/phergie/Tests/TestHelper.php new file mode 100644 index 000000000..e70af4456 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/TestHelper.php @@ -0,0 +1,26 @@ +<?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 + */ + +error_reporting(E_ALL | E_STRICT); + +// Phergie components require Phergie_Autoload to function correctly. +require_once dirname(__FILE__) . '/../Phergie/Autoload.php'; +Phergie_Autoload::registerAutoloader(); diff --git a/plugins/Irc/extlib/phergie/Tests/phpunit.xml b/plugins/Irc/extlib/phergie/Tests/phpunit.xml new file mode 100644 index 000000000..b96589e4a --- /dev/null +++ b/plugins/Irc/extlib/phergie/Tests/phpunit.xml @@ -0,0 +1,26 @@ +<!-- +/** + * 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 + */ +--> +<phpunit colors="true" bootstrap="./TestHelper.php"> + <testsuite name="Phergie Test Suite"> + <directory>./</directory> + </testsuite> +</phpunit> |