forked from GNUsocial/gnu-social
Merge branch 'idle-irc-plugin' into irc-plugin
Conflicts: plugins/Irc/ircmanager.php
This commit is contained in:
commit
ed1ea2f086
@ -60,6 +60,7 @@ class IrcPlugin extends ImPlugin {
|
||||
public $channels = null;
|
||||
public $transporttype = null;
|
||||
public $encoding = null;
|
||||
public $pinginterval = null;
|
||||
|
||||
public $regcheck = null;
|
||||
public $unregregexp = null;
|
||||
@ -126,6 +127,7 @@ class IrcPlugin extends ImPlugin {
|
||||
include_once $dir . '/'.strtolower($cls).'.php';
|
||||
return false;
|
||||
case 'Fake_Irc':
|
||||
case 'Irc_waiting_message':
|
||||
case 'ChannelResponseChannel':
|
||||
include_once $dir . '/'. $cls .'.php';
|
||||
return false;
|
||||
@ -150,6 +152,26 @@ class IrcPlugin extends ImPlugin {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the database table is present
|
||||
*
|
||||
*/
|
||||
public function onCheckSchema() {
|
||||
$schema = Schema::get();
|
||||
|
||||
// For storing messages while sessions become ready
|
||||
$schema->ensureTable('irc_waiting_message',
|
||||
array(new ColumnDef('id', 'integer', null,
|
||||
false, 'PRI', null, null, true),
|
||||
new ColumnDef('data', 'blob', null, false),
|
||||
new ColumnDef('prioritise', 'tinyint', 1, false),
|
||||
new ColumnDef('attempts', 'integer', null, false),
|
||||
new ColumnDef('created', 'datetime', null, false),
|
||||
new ColumnDef('claimed', 'datetime')));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a microid URI for the given screenname
|
||||
*
|
||||
@ -171,7 +193,7 @@ class IrcPlugin extends ImPlugin {
|
||||
$lines = explode("\n", $body);
|
||||
foreach ($lines as $line) {
|
||||
$this->fake_irc->doPrivmsg($screenname, $line);
|
||||
$this->enqueue_outgoing_raw(array('type' => 'message', 'data' => $this->fake_irc->would_be_sent));
|
||||
$this->enqueue_outgoing_raw(array('type' => 'message', 'prioritise' => 0, 'data' => $this->fake_irc->would_be_sent));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -297,6 +319,7 @@ class IrcPlugin extends ImPlugin {
|
||||
$this->enqueue_outgoing_raw(
|
||||
array(
|
||||
'type' => 'nickcheck',
|
||||
'prioritise' => 1,
|
||||
'data' => $this->fake_irc->would_be_sent,
|
||||
'nickdata' =>
|
||||
array(
|
||||
@ -337,6 +360,9 @@ class IrcPlugin extends ImPlugin {
|
||||
if (!isset($this->encoding)) {
|
||||
$this->encoding = 'UTF-8';
|
||||
}
|
||||
if (!isset($this->pinginterval)) {
|
||||
$this->pinginterval = 120;
|
||||
}
|
||||
|
||||
if (!isset($this->regcheck)) {
|
||||
$this->regcheck = true;
|
||||
|
142
plugins/Irc/Irc_waiting_message.php
Normal file
142
plugins/Irc/Irc_waiting_message.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* Table Definition for irc_waiting_message
|
||||
*/
|
||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||
|
||||
class Irc_waiting_message extends Memcached_DataObject {
|
||||
|
||||
public $__table = 'irc_waiting_message'; // table name
|
||||
public $id; // int primary_key not_null auto_increment
|
||||
public $data; // blob not_null
|
||||
public $prioritise; // tinyint(1) not_null
|
||||
public $attempts; // int not_null
|
||||
public $created; // datetime() not_null
|
||||
public $claimed; // datetime()
|
||||
|
||||
/* Static get */
|
||||
public function staticGet($k, $v = null) {
|
||||
return Memcached_DataObject::staticGet('Irc_waiting_message', $k, $v);
|
||||
}
|
||||
|
||||
/**
|
||||
* return table definition for DB_DataObject
|
||||
*
|
||||
* DB_DataObject needs to know something about the table to manipulate
|
||||
* instances. This method provides all the DB_DataObject needs to know.
|
||||
*
|
||||
* @return array array of column definitions
|
||||
*/
|
||||
public function table() {
|
||||
return array('id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
||||
'data' => DB_DATAOBJECT_BLOB + DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
|
||||
'prioritise' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
|
||||
'created' => DB_DATAOBJECT_TIME + DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
|
||||
'claimed' => DB_DATAOBJECT_TIME + DB_DATAOBJECT_STR);
|
||||
}
|
||||
|
||||
/**
|
||||
* return key definitions for DB_DataObject
|
||||
*
|
||||
* DB_DataObject needs to know about keys that the table has, since it
|
||||
* won't appear in StatusNet's own keys list. In most cases, this will
|
||||
* simply reference your keyTypes() function.
|
||||
*
|
||||
* @return array list of key field names
|
||||
*/
|
||||
public function keys() {
|
||||
return array_keys($this->keyTypes());
|
||||
}
|
||||
|
||||
/**
|
||||
* return key definitions for Memcached_DataObject
|
||||
*
|
||||
* Our caching system uses the same key definitions, but uses a different
|
||||
* method to get them. This key information is used to store and clear
|
||||
* cached data, so be sure to list any key that will be used for static
|
||||
* lookups.
|
||||
*
|
||||
* @return array associative array of key definitions, field name to type:
|
||||
* 'K' for primary key: for compound keys, add an entry for each component;
|
||||
* 'U' for unique keys: compound keys are not well supported here.
|
||||
*/
|
||||
public function keyTypes() {
|
||||
return array('id' => 'K');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic formula for non-autoincrementing integer primary keys
|
||||
*
|
||||
* If a table has a single integer column as its primary key, DB_DataObject
|
||||
* assumes that the column is auto-incrementing and makes a sequence table
|
||||
* to do this incrementation. Since we don't need this for our class, we
|
||||
* overload this method and return the magic formula that DB_DataObject needs.
|
||||
*
|
||||
* @return array magic three-false array that stops auto-incrementing.
|
||||
*/
|
||||
public function sequenceKey() {
|
||||
return array(false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next item in the queue
|
||||
*
|
||||
* @return Irc_waiting_message Next message if there is one
|
||||
*/
|
||||
public static function top() {
|
||||
$wm = new Irc_waiting_message();
|
||||
|
||||
$wm->orderBy('prioritise DESC, created');
|
||||
$wm->whereAdd('claimed is null');
|
||||
|
||||
$wm->limit(1);
|
||||
|
||||
$cnt = $wm->find(true);
|
||||
|
||||
if ($cnt) {
|
||||
# XXX: potential race condition
|
||||
# can we force it to only update if claimed is still null
|
||||
# (or old)?
|
||||
common_log(LOG_INFO, 'claiming IRC waiting message id = ' . $wm->id);
|
||||
$orig = clone($wm);
|
||||
$wm->claimed = common_sql_now();
|
||||
$result = $wm->update($orig);
|
||||
if ($result) {
|
||||
common_log(LOG_INFO, 'claim succeeded.');
|
||||
return $wm;
|
||||
} else {
|
||||
common_log(LOG_INFO, 'claim failed.');
|
||||
}
|
||||
}
|
||||
$wm = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the attempts count
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function incAttempts() {
|
||||
$orig = clone($this);
|
||||
$this->attempts++;
|
||||
$result = $this->update($orig);
|
||||
|
||||
if (!$result) {
|
||||
throw Exception(sprintf(_m("Could not increment attempts count for %d"), $this->id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release a claimed item.
|
||||
*/
|
||||
public function releaseClaim() {
|
||||
// DB_DataObject doesn't let us save nulls right now
|
||||
$sql = sprintf("UPDATE irc_waiting_message SET claimed=NULL WHERE id=%d", $this->id);
|
||||
$this->query($sql);
|
||||
|
||||
$this->claimed = null;
|
||||
$this->encache();
|
||||
}
|
||||
}
|
@ -23,6 +23,8 @@ nickservidentifyregexp: Override existing regexp matching request for identifica
|
||||
channels: Channels for bot to idle in
|
||||
transporttype: Set to 'ssl' to enable SSL
|
||||
encoding: Set to change encoding
|
||||
pinginterval: Set to change the number of seconds between pings (helps keep the connection open)
|
||||
Defaults to 120 seconds
|
||||
regcheck: Check user's nicknames are registered, enabled by default, set to false to disable
|
||||
regregexp: Override existing regexp matching response from NickServ if nick checked is registered.
|
||||
Must contain a capturing group catching the nick
|
||||
|
@ -141,9 +141,9 @@ class Phergie_Connection
|
||||
{
|
||||
if (empty($this->hostmask)) {
|
||||
$this->hostmask = new Phergie_Hostmask(
|
||||
$this->nick,
|
||||
$this->username,
|
||||
$this->host
|
||||
$this->getNick(),
|
||||
$this->getUsername(),
|
||||
$this->getHost()
|
||||
);
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@ class Phergie_Connection
|
||||
if (!in_array($this->transport, stream_get_transports())) {
|
||||
throw new Phergie_Connection_Exception(
|
||||
'Transport ' . $this->transport . ' is not supported',
|
||||
Phergie_Connection_Exception::TRANSPORT_NOT_SUPPORTED
|
||||
Phergie_Connection_Exception::ERR_TRANSPORT_NOT_SUPPORTED
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ class Phergie_Plugin_Cron extends Phergie_Plugin_Abstract
|
||||
*/
|
||||
public function onTick()
|
||||
{
|
||||
$now = time();
|
||||
$time = time();
|
||||
foreach ($this->callbacks as $key => &$callback) {
|
||||
$callbackString = $this->getCallbackString($callback);
|
||||
|
||||
|
@ -98,6 +98,12 @@ class Phergie_Plugin_Handler implements IteratorAggregate, Countable
|
||||
$this->paths = array();
|
||||
$this->autoload = false;
|
||||
|
||||
if (!empty($config['plugins.paths'])) {
|
||||
foreach ($config['plugins.paths'] as $dir => $prefix) {
|
||||
$this->addPath($dir, $prefix);
|
||||
}
|
||||
}
|
||||
|
||||
$this->addPath(dirname(__FILE__), 'Phergie_Plugin_');
|
||||
}
|
||||
|
||||
@ -134,6 +140,7 @@ class Phergie_Plugin_Handler implements IteratorAggregate, Countable
|
||||
* Returns metadata corresponding to a specified plugin.
|
||||
*
|
||||
* @param string $plugin Short name of the plugin class
|
||||
*
|
||||
* @throws Phergie_Plugin_Exception Class file can't be found
|
||||
*
|
||||
* @return array|boolean Associative array containing the path to the
|
||||
@ -142,7 +149,7 @@ class Phergie_Plugin_Handler implements IteratorAggregate, Countable
|
||||
*/
|
||||
public function getPluginInfo($plugin)
|
||||
{
|
||||
foreach (array_reverse($this->paths) as $path) {
|
||||
foreach (array_reverse($this->paths) as $path) {
|
||||
$file = $path['path'] . $plugin . '.php';
|
||||
if (file_exists($file)) {
|
||||
$path = array(
|
||||
@ -444,15 +451,21 @@ class Phergie_Plugin_Handler implements IteratorAggregate, Countable
|
||||
$valid = true;
|
||||
|
||||
try {
|
||||
$error_reporting = error_reporting(0); // ignore autoloader errors
|
||||
$r = new ReflectionClass($class);
|
||||
$valid = $r->isSubclassOf('FilterIterator');
|
||||
error_reporting($error_reporting);
|
||||
if (!$r->isSubclassOf('FilterIterator')) {
|
||||
$message = 'Class ' . $class . ' is not a subclass of FilterIterator';
|
||||
$valid = false;
|
||||
}
|
||||
} catch (ReflectionException $e) {
|
||||
$message = $e->getMessage();
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (!$valid) {
|
||||
throw new Phergie_Plugin_Exception(
|
||||
$e->getMessage(),
|
||||
$message,
|
||||
Phergie_Plugin_Exception::ERR_INVALID_ITERATOR_CLASS
|
||||
);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
* @uses extension PDO
|
||||
* @uses extension pdo_sqlite
|
||||
* @uses Phergie_Plugin_Command pear.phergie.org
|
||||
* @uses Phergie_Plugin_Message pear.phergie.org
|
||||
*/
|
||||
class Phergie_Plugin_Karma extends Phergie_Plugin_Abstract
|
||||
{
|
||||
@ -94,11 +93,16 @@ class Phergie_Plugin_Karma extends Phergie_Plugin_Abstract
|
||||
{
|
||||
$plugins = $this->getPluginHandler();
|
||||
$plugins->getPlugin('Command');
|
||||
$plugins->getPlugin('Message');
|
||||
|
||||
$file = dirname(__FILE__) . '/Karma/karma.db';
|
||||
$this->db = new PDO('sqlite:' . $file);
|
||||
$this->getDb();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes prepared statements used by the plugin.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initializePreparedStatements()
|
||||
{
|
||||
$this->fetchKarma = $this->db->prepare('
|
||||
SELECT karma
|
||||
FROM karmas
|
||||
@ -139,6 +143,36 @@ class Phergie_Plugin_Karma extends Phergie_Plugin_Abstract
|
||||
');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a connection to the plugin database, initializing one if none
|
||||
* is explicitly set.
|
||||
*
|
||||
* @return PDO Database connection
|
||||
*/
|
||||
public function getDb()
|
||||
{
|
||||
if (empty($this->db)) {
|
||||
$this->db = new PDO('sqlite:' . dirname(__FILE__) . '/Karma/karma.db');
|
||||
$this->initializePreparedStatements();
|
||||
}
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the connection to the plugin database, mainly intended for unit
|
||||
* testing.
|
||||
*
|
||||
* @param PDO $db Database connection
|
||||
*
|
||||
* @return Phergie_Plugin_Karma Provides a fluent interface
|
||||
*/
|
||||
public function setDb(PDO $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->initializePreparedStatements();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the canonical form of a given term.
|
||||
*
|
||||
@ -228,15 +262,11 @@ REGEX;
|
||||
$source = $this->getEvent()->getSource();
|
||||
$nick = $this->getEvent()->getNick();
|
||||
|
||||
if (empty($term)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$canonicalTerm = $this->getCanonicalTerm($term);
|
||||
|
||||
$fixedKarma = $this->fetchFixedKarma($canonicalTerm);
|
||||
if ($fixedKarma) {
|
||||
$message = $nick . ': ' . $term . ' ' . $fixedKarma . '.';
|
||||
$message = $nick . ': ' . $term . ' ' . $fixedKarma;
|
||||
$this->doPrivmsg($source, $message);
|
||||
return;
|
||||
}
|
||||
@ -302,33 +332,29 @@ REGEX;
|
||||
$fixedKarma0 = $this->fetchFixedKarma($canonicalTerm0);
|
||||
$fixedKarma1 = $this->fetchFixedKarma($canonicalTerm1);
|
||||
|
||||
if ($fixedKarma0
|
||||
|| $fixedKarma1
|
||||
|| empty($canonicalTerm0)
|
||||
|| empty($canonicalTerm1)
|
||||
) {
|
||||
if ($fixedKarma0 || $fixedKarma1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($canonicalTerm0 == 'everything') {
|
||||
$change = $method == '<' ? '++' : '--';
|
||||
$this->modifyKarma($canonicalTerm1, $change);
|
||||
$karma0 = 0;
|
||||
$karma1 = $this->fetchKarma($canonicalTerm1);
|
||||
$karma1 = $this->modifyKarma($canonicalTerm1, $change);
|
||||
} elseif ($canonicalTerm1 == 'everything') {
|
||||
$change = $method == '<' ? '--' : '++';
|
||||
$this->modifyKarma($canonicalTerm0, $change);
|
||||
$karma0 = $this->fetchKarma($canonicalTerm1);
|
||||
$karma0 = $this->modifyKarma($canonicalTerm0, $change);
|
||||
$karma1 = 0;
|
||||
} else {
|
||||
$karma0 = $this->fetchKarma($canonicalTerm0);
|
||||
$karma1 = $this->fetchKarma($canonicalTerm1);
|
||||
}
|
||||
|
||||
if (($method == '<'
|
||||
&& $karma0 < $karma1)
|
||||
|| ($method == '>'
|
||||
&& $karma0 > $karma1)) {
|
||||
// Combining the first and second branches here causes an odd
|
||||
// single-line lapse in code coverage, but the lapse disappears if
|
||||
// they're separated
|
||||
if ($method == '<' && $karma0 < $karma1) {
|
||||
$replies = $this->fetchPositiveAnswer;
|
||||
} elseif ($method == '>' && $karma0 > $karma1) {
|
||||
$replies = $this->fetchPositiveAnswer;
|
||||
} else {
|
||||
$replies = $this->fetchNegativeAnswer;
|
||||
@ -356,14 +382,10 @@ REGEX;
|
||||
* @param string $term Term to modify
|
||||
* @param string $action Karma action (either ++ or --)
|
||||
*
|
||||
* @return void
|
||||
* @return int Modified karma rating
|
||||
*/
|
||||
protected function modifyKarma($term, $action)
|
||||
{
|
||||
if (empty($term)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$karma = $this->fetchKarma($term);
|
||||
if ($karma !== false) {
|
||||
$statement = $this->updateKarma;
|
||||
@ -378,6 +400,8 @@ REGEX;
|
||||
':karma' => $karma
|
||||
);
|
||||
$statement->execute($args);
|
||||
|
||||
return $karma;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,10 +54,27 @@ class Phergie_Plugin_Reload extends Phergie_Plugin_Abstract
|
||||
{
|
||||
$plugin = ucfirst($plugin);
|
||||
|
||||
$evalClass = true;
|
||||
if (strpos($plugin, ' ') !== false) {
|
||||
$args = explode(' ', $plugin);
|
||||
$plugin = $args[0];
|
||||
if (strtolower($args[1]) == 'force') {
|
||||
$evalClass = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->plugins->hasPlugin($plugin)) {
|
||||
echo 'DEBUG(Reload): ' . ucfirst($plugin) . ' is not loaded yet, loading', PHP_EOL;
|
||||
$this->plugins->getPlugin($plugin);
|
||||
$this->plugins->command->populateMethodCache();
|
||||
try {
|
||||
$this->plugins->getPlugin($plugin);
|
||||
$this->plugins->command->populateMethodCache();
|
||||
} catch (Phergie_Plugin_Exception $e) {
|
||||
if ($e->getCode() == Phergie_Plugin_Exception::ERR_CLASS_NOT_FOUND) {
|
||||
echo 'DEBUG(Reload): ', $e->getMessage(), PHP_EOL;
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -75,17 +92,19 @@ class Phergie_Plugin_Reload extends Phergie_Plugin_Abstract
|
||||
$newClass = $class . '_' . sha1($contents);
|
||||
|
||||
if (class_exists($newClass, false)) {
|
||||
echo 'DEBUG(Reload): Class ', $class, ' has not changed since last reload', PHP_EOL;
|
||||
return;
|
||||
if ($evalClass == true) {
|
||||
echo 'DEBUG(Reload): Class ', $class, ' has not changed since last reload', PHP_EOL;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$contents = preg_replace(
|
||||
array('/^<\?(?:php)?/', '/class\s+' . $class . '/i'),
|
||||
array('', 'class ' . $newClass),
|
||||
$contents
|
||||
);
|
||||
eval($contents);
|
||||
}
|
||||
|
||||
$contents = preg_replace(
|
||||
array('/^<\?(?:php)?/', '/class\s+' . $class . '/i'),
|
||||
array('', 'class ' . $newClass),
|
||||
$contents
|
||||
);
|
||||
eval($contents);
|
||||
|
||||
$instance = new $newClass;
|
||||
$instance->setName($plugin);
|
||||
$instance->setEvent($this->event);
|
||||
|
@ -34,7 +34,6 @@
|
||||
*/
|
||||
class Phergie_Plugin_SpellCheck extends Phergie_Plugin_Abstract
|
||||
{
|
||||
|
||||
/**
|
||||
* Spell check dictionary handler
|
||||
*
|
||||
@ -86,7 +85,7 @@ class Phergie_Plugin_SpellCheck extends Phergie_Plugin_Abstract
|
||||
$target = $this->event->getNick();
|
||||
|
||||
$message = $target . ': The word "' . $word;
|
||||
$message .= '" seems to be spelt correctly.';
|
||||
$message .= '" seems to be spelled correctly.';
|
||||
if (!pspell_check($this->pspell, $word)) {
|
||||
$suggestions = pspell_suggest($this->pspell, $word);
|
||||
|
||||
@ -116,5 +115,4 @@ class Phergie_Plugin_SpellCheck extends Phergie_Plugin_Abstract
|
||||
{
|
||||
$this->fail($errstr);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,6 +41,13 @@ class Phergie_Plugin_Statusnet extends Phergie_Plugin_Abstract {
|
||||
*/
|
||||
protected $regCallback;
|
||||
|
||||
/**
|
||||
* Connection established callback details
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $connectedCallback;
|
||||
|
||||
/**
|
||||
* Load callback from config
|
||||
*/
|
||||
@ -59,6 +66,13 @@ class Phergie_Plugin_Statusnet extends Phergie_Plugin_Abstract {
|
||||
$this->regCallback = NULL;
|
||||
}
|
||||
|
||||
$connectedCallback = $this->config['statusnet.connectedcallback'];
|
||||
if (is_callable($connectedCallback)) {
|
||||
$this->connectedCallback = $connectedCallback;
|
||||
} else {
|
||||
$this->connectedCallback = NULL;
|
||||
}
|
||||
|
||||
$this->unregRegexp = $this->getConfig('statusnet.unregregexp', '/\x02(.*?)\x02 (?:isn\'t|is not) registered/i');
|
||||
$this->regRegexp = $this->getConfig('statusnet.regregexp', '/(?:\A|\x02)(\w+?)\x02? (?:\(account|is \w+?\z)/i');
|
||||
}
|
||||
@ -110,4 +124,20 @@ class Phergie_Plugin_Statusnet extends Phergie_Plugin_Abstract {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Intercepts the end of the "message of the day" response and tells
|
||||
* StatusNet we're connected
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onResponse() {
|
||||
switch ($this->getEvent()->getCode()) {
|
||||
case Phergie_Event_Response::RPL_ENDOFMOTD:
|
||||
case Phergie_Event_Response::ERR_NOMOTD:
|
||||
if ($this->connectedCallback !== NULL) {
|
||||
call_user_func($this->connectedCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class Phergie_Plugin_TerryChay extends Phergie_Plugin_Abstract
|
||||
*/
|
||||
public function onLoad()
|
||||
{
|
||||
$this->http = $this->getPluginHandler()->getPlugin('Http');
|
||||
$this->getPluginHandler()->getPlugin('Http');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +63,11 @@ class Phergie_Plugin_TerryChay extends Phergie_Plugin_Abstract
|
||||
*/
|
||||
public function getChayism()
|
||||
{
|
||||
return $this->http->get(self::URL)->getContent();
|
||||
return $this
|
||||
->getPluginHandler()
|
||||
->getPlugin('Http')
|
||||
->get(self::URL)
|
||||
->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,29 +85,10 @@ class Phergie_Plugin_TerryChay extends Phergie_Plugin_Abstract
|
||||
= '{^(' . preg_quote($this->getConfig('command.prefix')) .
|
||||
'\s*)?.*(terry\s+chay|tychay)}ix';
|
||||
|
||||
if (preg_match($pattern, $message)
|
||||
&& $fact = $this->getChayism()
|
||||
) {
|
||||
$this->doPrivmsg($source, 'Fact: ' . $fact);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses incoming CTCP request for "Terry Chay" and related variations
|
||||
* and responds with a chayism.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onCtcp()
|
||||
{
|
||||
$event = $this->getEvent();
|
||||
$source = $event->getSource();
|
||||
$ctcp = $event->getArgument(1);
|
||||
|
||||
if (preg_match('({terry[\s_+-]*chay}|tychay)ix', $ctcp)
|
||||
&& $fact = $this->getChayism()
|
||||
) {
|
||||
$this->doCtcpReply($source, 'TERRYCHAY', $fact);
|
||||
if (preg_match($pattern, $message)) {
|
||||
if($fact = $this->getChayism()) {
|
||||
$this->doPrivmsg($source, 'Fact: ' . $fact);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
262
plugins/Irc/extlib/phergie/Tests/Phergie/ConnectionTest.php
Normal file
262
plugins/Irc/extlib/phergie/Tests/Phergie/ConnectionTest.php
Normal file
@ -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)}());
|
||||
}
|
||||
}
|
||||
}
|
@ -108,6 +108,77 @@ class Phergie_Plugin_HandlerTest extends PHPUnit_Framework_TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@ -714,23 +785,53 @@ class Phergie_Plugin_HandlerTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the plugin receiving and using a predefined iterator instance.
|
||||
* Tests that multiple plugin iterators can be used concurrently.
|
||||
*
|
||||
* @depends testGetPlugins
|
||||
* @return void
|
||||
*/
|
||||
public function testSetIterator()
|
||||
public function testUseMultiplePluginIteratorsConcurrently()
|
||||
{
|
||||
$plugin = $this->getMockPlugin('TestPlugin');
|
||||
$this->handler->addPlugin($plugin);
|
||||
$plugins = $this->handler->getPlugins();
|
||||
$iterator = new ArrayIterator($plugins);
|
||||
$this->handler->setIterator($iterator);
|
||||
$this->assertSame($this->handler->getIterator(), $iterator);
|
||||
$iterated = array();
|
||||
foreach ($this->handler as $plugin) {
|
||||
$iterated[strtolower($plugin->getName())] = $plugin;
|
||||
}
|
||||
$this->assertEquals($iterated, $plugins);
|
||||
$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');
|
||||
}
|
||||
}
|
||||
|
335
plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/KarmaTest.php
Normal file
335
plugins/Irc/extlib/phergie/Tests/Phergie/Plugin/KarmaTest.php
Normal file
@ -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 . '.');
|
||||
}
|
||||
}
|
||||
}
|
@ -12,15 +12,13 @@
|
||||
* http://phergie.org/license
|
||||
*
|
||||
* @category Phergie
|
||||
* @package 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
|
||||
* @link http://pear.phergie.org/package/Phergie_Tests
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/TestCase.php');
|
||||
|
||||
/**
|
||||
* Unit test suite for Pherge_Plugin_Ping.
|
||||
*
|
||||
@ -28,148 +26,139 @@ require_once(dirname(__FILE__) . '/TestCase.php');
|
||||
* @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
|
||||
* @link http://pear.phergie.org/package/Phergie_Tests
|
||||
*/
|
||||
class Phergie_Plugin_PingTest extends Phergie_Plugin_TestCase
|
||||
{
|
||||
protected $config = array('ping.ping' => 10,
|
||||
'ping.event' => 300);
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->setPlugin(new Phergie_Plugin_Ping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the lastEvent setter and getter
|
||||
*/
|
||||
public function testSetGetLastEvent()
|
||||
{
|
||||
$expected = rand(100000,200000);
|
||||
$this->plugin->setLastEvent($expected);
|
||||
$this->assertEquals($expected,
|
||||
$this->plugin->getLastEvent(),
|
||||
'Assert that the last event was set and gotten ' .
|
||||
'correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the lastPing setter and getter
|
||||
*/
|
||||
public function testSetGetLastPing()
|
||||
{
|
||||
|
||||
$expected = rand(100000,200000);
|
||||
$this->plugin->setLastPing($expected);
|
||||
$this->assertEquals($expected,
|
||||
$this->plugin->getLastPing(),
|
||||
'Assert that the last ping was set and gotten ' .
|
||||
'correctly');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the onConnect hook
|
||||
* Tests that the last ping and event are initialized on connection to
|
||||
* the server.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOnConnect()
|
||||
{
|
||||
$time = time() - 1;
|
||||
// We need to make sure time() is going to be creater next time it is called
|
||||
|
||||
$this->plugin->onConnect();
|
||||
$this->assertNull($this->plugin->getLastPing(),
|
||||
'onConnect should set last ping to null');
|
||||
$this->assertGreaterThan($time,
|
||||
$this->plugin->getLastEvent(),
|
||||
'onConnect should update lastEvent with the ' .
|
||||
'current timestamp');
|
||||
$this->assertLessThan($time + 2,
|
||||
$this->plugin->getLastEvent(),
|
||||
'onConnect should update lastEvent with the ' .
|
||||
'current timestamp');
|
||||
|
||||
$expected = time();
|
||||
$actual = $this->plugin->getLastEvent();
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
$expected = null;
|
||||
$actual = $this->plugin->getLastPing();
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the preEvent method updates the lastEvent with the current time
|
||||
* Tests that the last event is reset when an event occurs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPreEvent()
|
||||
{
|
||||
$time = time() -1;
|
||||
$this->plugin->preEvent();
|
||||
$this->assertGreaterThan($time,
|
||||
$this->plugin->getLastEvent(),
|
||||
'Last event time was set properly on preEvent');
|
||||
$this->assertLessThan($time +2,
|
||||
$this->plugin->getLastEvent(),
|
||||
'Last Event time was set properly on preEvent');
|
||||
|
||||
$expected = time();
|
||||
$actual = $this->plugin->getLastEvent();
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Implement testOnPingResponse().
|
||||
* Tests that the last ping is reset when a ping is received.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOnPingResponse()
|
||||
{
|
||||
$this->plugin->setLastPing(time());
|
||||
$this->plugin->onPingResponse();
|
||||
$this->assertNull($this->plugin->getLastPing(),
|
||||
'Last ping time should be null after onPingResponse');
|
||||
|
||||
$expected = null;
|
||||
$actual = $this->plugin->getLastPing();
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the plugin issues a quit when the ping threashold
|
||||
* has been exceeded
|
||||
* Tests that the test suite is able to manipulate the value of the last
|
||||
* event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOnTickExceededPingThresholdQuits()
|
||||
public function testSetLastEvent()
|
||||
{
|
||||
$this->plugin->setLastPing(1);
|
||||
$this->plugin->onTick();
|
||||
$this->assertHasEvent(Phergie_Event_Command::TYPE_QUIT);
|
||||
$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) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the plugin issues a quit when the ping threashold
|
||||
* has been exceeded
|
||||
* Tests that the test suite is able to manipulate the value of the last
|
||||
* ping.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOnTickPingWithinThresholdDoesNotQuits()
|
||||
public function testSetLastPing()
|
||||
{
|
||||
$this->plugin->setLastPing(time());
|
||||
$this->plugin->onTick();
|
||||
$this->assertDoesNotHaveEvent(Phergie_Event_Command::TYPE_QUIT);
|
||||
$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) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a ping is emitted when the event threashold is exceeded
|
||||
* Tests that a ping event is sent after the appropriate time period has
|
||||
* lapsed since receiving an event.
|
||||
*
|
||||
* @depends testSetLastEvent
|
||||
* @return void
|
||||
*/
|
||||
public function testPingEmittedAfterThresholdExceeded()
|
||||
public function testPing()
|
||||
{
|
||||
$this->plugin->setLastEvent(time() - $this->config['ping.event'] - 1);
|
||||
$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();
|
||||
$this->assertHasEvent(Phergie_Event_Command::TYPE_PING);
|
||||
$events = $this->getResponseEvents(Phergie_Event_Command::TYPE_PING);
|
||||
foreach ($events as $event) {
|
||||
$this->assertEventEmitter($event,
|
||||
$this->plugin,
|
||||
'Assert that the event was emitted by the tested plugin');
|
||||
}
|
||||
$actual = $this->plugin->getLastPing();
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that no ping is emitted when the event thresthold is not exceeded
|
||||
* 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 testNoPingEmittedWhenThresholdNotExceeded()
|
||||
public function testQuit()
|
||||
{
|
||||
$this->plugin->setLastEvent(time() - $this->config['ping.event'] +1);
|
||||
$pingPing = 10;
|
||||
$this->setConfig('ping.ping', $pingPing);
|
||||
$lastPing = time() - ($pingPing + 1);
|
||||
$this->plugin->setLastPing($lastPing);
|
||||
$this->assertEmitsEvent('quit');
|
||||
$this->plugin->onTick();
|
||||
$this->assertDoesNotHaveEvent(Phergie_Event_Command::TYPE_PING);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->handler->clearEvents();
|
||||
}
|
||||
|
||||
}
|
@ -12,15 +12,13 @@
|
||||
* http://phergie.org/license
|
||||
*
|
||||
* @category Phergie
|
||||
* @package 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
|
||||
* @link http://pear.phergie.org/package/Phergie_Tests
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/TestCase.php');
|
||||
|
||||
/**
|
||||
* Unit test suite for Pherge_Plugin_Pong.
|
||||
*
|
||||
@ -28,47 +26,21 @@ require_once(dirname(__FILE__) . '/TestCase.php');
|
||||
* @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
|
||||
* @link http://pear.phergie.org/package/Phergie_Tests
|
||||
*/
|
||||
class Phergie_Plugin_PongTest extends Phergie_Plugin_TestCase
|
||||
{
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->setPlugin(new Phergie_Plugin_Pong);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that when a ping is received, a Phergie_Event_Command::TYPE_PONG
|
||||
* is set to the handler
|
||||
* Test that a pong event is sent when a ping event is received.
|
||||
*
|
||||
* @event Phergie_Event_Command::TYPE_PING
|
||||
* @return void
|
||||
*/
|
||||
public function testOnPing()
|
||||
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();
|
||||
$this->assertHasEvent(Phergie_Event_Command::TYPE_PONG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that when a ping is received, a Phergie_Event_Command::TYPE_PONG
|
||||
* is set to the handler
|
||||
*
|
||||
* @event Phergie_Event_Command::TYPE_PING
|
||||
*/
|
||||
public function testOnPingResponseArguement()
|
||||
{
|
||||
$this->plugin->onPing();
|
||||
$this->assertHasEvent(Phergie_Event_Command::TYPE_PONG);
|
||||
$events = $this->getResponseEvents(Phergie_Event_Command::TYPE_PONG);
|
||||
$this->assertTrue(count($events) === 1, 'Assert that only one pong is emitted');
|
||||
$this->assertEventEmitter(current($events),
|
||||
$this->plugin,
|
||||
'Assert that the tested plugin emitted the event');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,15 +12,13 @@
|
||||
* http://phergie.org/license
|
||||
*
|
||||
* @category Phergie
|
||||
* @package 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
|
||||
* @link http://pear.phergie.org/package/Phergie_Tests
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/TestCase.php';
|
||||
|
||||
/**
|
||||
* Unit test suite for Pherge_Plugin_SpellCheck.
|
||||
*
|
||||
@ -28,178 +26,141 @@ require_once dirname(__FILE__) . '/TestCase.php';
|
||||
* @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
|
||||
* @link http://pear.phergie.org/package/Phergie_Tests
|
||||
*/
|
||||
class Phergie_Plugin_SpellCheckTest extends Phergie_Plugin_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Current SpellCheck plugin instance
|
||||
*
|
||||
* @var Phergie_Plugin_SpellCheck
|
||||
*/
|
||||
protected $spell;
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
* Checks for the pspell extension.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setUp()
|
||||
public function setUp()
|
||||
{
|
||||
$this->config = array('spellcheck.lang' => 'en');
|
||||
parent::setUp();
|
||||
|
||||
$this->spell = new Phergie_Plugin_SpellCheck();
|
||||
$this->setPlugin(new Phergie_Plugin_Command());
|
||||
|
||||
$config = $this->plugin->getConfig();
|
||||
|
||||
$handler = new Phergie_Plugin_Handler($config, $this->handler);
|
||||
$this->plugin->setPluginHandler($handler);
|
||||
|
||||
$handler->addPlugin($this->plugin);
|
||||
$handler->addPlugin($this->spell);
|
||||
|
||||
$this->spell->setEventHandler($this->handler);
|
||||
$this->spell->setConnection($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #zftalk
|
||||
* @eventArg spell
|
||||
*/
|
||||
public function testSpell()
|
||||
{
|
||||
$this->spell->onLoad();
|
||||
|
||||
$this->copyEvent();
|
||||
$this->plugin->onPrivMsg();
|
||||
$this->assertDoesNotHaveEvent(Phergie_Event_Command::TYPE_PRIVMSG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #phergie
|
||||
* @eventArg spell test
|
||||
*/
|
||||
public function testSpellTest()
|
||||
{
|
||||
$this->spell->onLoad();
|
||||
|
||||
$this->copyEvent();
|
||||
$this->plugin->onPrivMsg();
|
||||
|
||||
$events = $this->getResponseEvents(Phergie_Event_Command::TYPE_PRIVMSG);
|
||||
|
||||
$this->assertEquals(1, count($events));
|
||||
foreach ($events as $event) {
|
||||
$args = $event->getArguments();
|
||||
|
||||
$this->assertEquals('#phergie', $args[0]);
|
||||
|
||||
$this->assertContains('CheckSpellUser:', $args[1]);
|
||||
$this->assertContains('test', $args[1]);
|
||||
$this->assertContains('correct', $args[1]);
|
||||
if (!extension_loaded('pspell')) {
|
||||
$this->markTestSkipped('pspell extension not available');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #phergie
|
||||
* @eventArg spell testz
|
||||
*/
|
||||
public function testSpellTestz()
|
||||
{
|
||||
$this->spell->onLoad();
|
||||
|
||||
$this->copyEvent();
|
||||
$this->plugin->onPrivMsg();
|
||||
|
||||
$events = $this->getResponseEvents(Phergie_Event_Command::TYPE_PRIVMSG);
|
||||
|
||||
$this->assertEquals(1, count($events));
|
||||
foreach ($events as $event) {
|
||||
$args = $event->getArguments();
|
||||
|
||||
$this->assertEquals('#phergie', $args[0]);
|
||||
|
||||
$this->assertContains('CheckSpellUser:', $args[1]);
|
||||
$this->assertRegExp('/([a-z]+, ){4}/', $args[1]);
|
||||
$this->assertContains('testz', $args[1]);
|
||||
$this->assertContains('test,', $args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #phergie
|
||||
* @eventArg spell testz
|
||||
*/
|
||||
public function testSpellMoreSuggestions()
|
||||
{
|
||||
$config = $this->spell->getConfig();
|
||||
|
||||
$this->copyEvent();
|
||||
$config['spellcheck.limit'] = 6;
|
||||
|
||||
$this->spell->onLoad();
|
||||
$this->plugin->onPrivMsg();
|
||||
|
||||
$events = $this->getResponseEvents(Phergie_Event_Command::TYPE_PRIVMSG);
|
||||
|
||||
$this->assertEquals(1, count($events));
|
||||
foreach ($events as $event) {
|
||||
$args = $event->getArguments();
|
||||
|
||||
$this->assertEquals('#phergie', $args[0]);
|
||||
|
||||
$this->assertContains('CheckSpellUser:', $args[1]);
|
||||
$this->assertRegExp('/([a-z]+, ){5}/', $args[1]);
|
||||
$this->assertContains('testz', $args[1]);
|
||||
$this->assertContains('test,', $args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #phergie
|
||||
* @eventArg spell qwertyuiopasdfghjklzxcvbnm
|
||||
*/
|
||||
public function testSpellNoSuggestions()
|
||||
{
|
||||
$this->spell->onLoad();
|
||||
|
||||
$this->copyEvent();
|
||||
$this->plugin->onPrivMsg();
|
||||
|
||||
$events = $this->getResponseEvents(Phergie_Event_Command::TYPE_PRIVMSG);
|
||||
|
||||
$this->assertEquals(1, count($events));
|
||||
foreach ($events as $event) {
|
||||
$args = $event->getArguments();
|
||||
|
||||
$this->assertEquals('#phergie', $args[0]);
|
||||
|
||||
$this->assertContains('CheckSpellUser:', $args[1]);
|
||||
$this->assertContains('find any suggestions', $args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy event from command to spell plugin
|
||||
* Tests for the plugin failing to load when the language setting is not
|
||||
* specified.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function copyEvent()
|
||||
public function testLanguageSettingNotSet()
|
||||
{
|
||||
$hostmask = Phergie_Hostmask::fromString('CheckSpellUser!test@testing.org');
|
||||
|
||||
$event = $this->plugin->getEvent();
|
||||
$event->setHostmask($hostmask);
|
||||
|
||||
$this->spell->setEvent($event);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -12,15 +12,13 @@
|
||||
* http://phergie.org/license
|
||||
*
|
||||
* @category Phergie
|
||||
* @package 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
|
||||
* @link http://pear.phergie.org/package/Phergie_Tests
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/TestCase.php');
|
||||
|
||||
/**
|
||||
* Unit test suite for Pherge_Plugin_TerryChay.
|
||||
*
|
||||
@ -28,72 +26,110 @@ require_once(dirname(__FILE__) . '/TestCase.php');
|
||||
* @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
|
||||
* @link http://pear.phergie.org/package/Phergie_Tests
|
||||
*/
|
||||
class Phergie_Plugin_TerryChayTest extends Phergie_Plugin_TestCase
|
||||
{
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
* Chayism used as a consistent response when related events are
|
||||
* triggered
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected function setUp()
|
||||
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()
|
||||
{
|
||||
$this->setPlugin(new Phergie_Plugin_TerryChay());
|
||||
$config = new Phergie_Config();
|
||||
$handler = new Phergie_Plugin_Handler($config, $this->handler);
|
||||
$this->plugin->setPluginHandler($handler);
|
||||
$handler->addPlugin($this->plugin);
|
||||
$handler->addPlugin(new Phergie_Plugin_Http($config));
|
||||
$this->plugin->setConfig($config);
|
||||
$this->connection->setNick('phergie');
|
||||
$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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #zftalk
|
||||
* @eventArg tychay
|
||||
* 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 testWithTyChay()
|
||||
public function dataProviderTestPrivmsgTriggerReturnsChayism()
|
||||
{
|
||||
$this->plugin->onPrivMsg();
|
||||
$this->assertHasEvent(Phergie_Event_Command::TYPE_PRIVMSG);
|
||||
return array(
|
||||
array('terry chay'),
|
||||
array('terry chay'),
|
||||
array('tychay'),
|
||||
array('!tychay'),
|
||||
array('! tychay'),
|
||||
array('foo tychay bar'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #zftalk
|
||||
* @eventArg terrychay
|
||||
* Tests that appropriate triggers result in a response with a Chayism.
|
||||
*
|
||||
* @return void
|
||||
* @dataProvider dataProviderTestPrivmsgTriggerReturnsChayism
|
||||
*/
|
||||
public function testWithTerryChay()
|
||||
public function testPrivmsgTriggerReturnsChayism($trigger)
|
||||
{
|
||||
$this->plugin->onPrivMsg();
|
||||
$this->assertDoesNotHaveEvent(Phergie_Event_Command::TYPE_PRIVMSG,
|
||||
'string "terrychay" should not invoke a response');
|
||||
$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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #zftalk
|
||||
* @eventArg terry chay
|
||||
* Tests that lack of an appropriate trigger results in no response with
|
||||
* a Chayism.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testWithTerry_Chay()
|
||||
public function testNoPrivmsgTriggerDoesNotReturnChayism()
|
||||
{
|
||||
$this->plugin->onPrivMsg();
|
||||
$this->assertHasEvent(Phergie_Event_Command::TYPE_PRIVMSG,
|
||||
'string "terry chay" should invoke a response');
|
||||
}
|
||||
|
||||
/**
|
||||
* @event Phergie_Event_Request::privmsg
|
||||
* @eventArg #zftalk
|
||||
* @eventArg Elazar is not Mr. Chay
|
||||
*/
|
||||
public function testWithNoTyChay()
|
||||
{
|
||||
$this->plugin->onPrivMsg();
|
||||
$this->assertDoesNotHaveEvent(Phergie_Event_Command::TYPE_PRIVMSG,
|
||||
'Failed asserting that elazar is not ' .
|
||||
'tychay');
|
||||
$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();
|
||||
}
|
||||
}
|
@ -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 $handler;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
protected $config = array();
|
||||
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
* 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
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
* @var string
|
||||
*/
|
||||
public function __construct($name = NULL, array $data = array(), $dataName = '')
|
||||
{
|
||||
parent::__construct($name, $data, $dataName);
|
||||
$this->connection = new Phergie_Connection();
|
||||
$this->handler = new Phergie_Event_Handler();
|
||||
}
|
||||
protected $pluginClass;
|
||||
|
||||
/**
|
||||
* Assert that a given event type exists in the event handler
|
||||
* @param string $event
|
||||
* @param string $message
|
||||
*/
|
||||
public function assertHasEvent($event, $message = null)
|
||||
{
|
||||
self::assertTrue($this->handler->hasEventOfType($event), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that a given event type DOES NOT exist in the event handler
|
||||
* @param string $event
|
||||
* @param string $message
|
||||
*/
|
||||
public function assertDoesNotHaveEvent($event, $message = null)
|
||||
{
|
||||
self::assertFalse($this->handler->hasEventOfType($event), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the emitter of the given command event was the given
|
||||
* plugin
|
||||
* User nick used in any events requiring one
|
||||
*
|
||||
* @param Phergie_Event_Command $event
|
||||
* @param Phergie_Plugin_Abstract $plugin
|
||||
* @param string $message
|
||||
* @var string
|
||||
*/
|
||||
public function assertEventEmitter(Phergie_Event_Command $event,
|
||||
Phergie_Plugin_Abstract $plugin,
|
||||
$message = null)
|
||||
{
|
||||
$this->assertSame($plugin, $event->getPlugin(), $message);
|
||||
}
|
||||
protected $nick = 'nick';
|
||||
|
||||
/**
|
||||
* Gets the events added to the handler by the plugin
|
||||
* @param string $type
|
||||
* @return array | null
|
||||
* Event source used in any events requiring one
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public function getResponseEvents($type = null)
|
||||
protected $source = '#channel';
|
||||
|
||||
/**
|
||||
* Initializes instance properties.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
if (is_string($type) && strlen($type) > 0) {
|
||||
return $this->handler->getEventsOfType($type);
|
||||
if (empty($this->pluginClass)) {
|
||||
$this->pluginClass = preg_replace('/Test$/', '', get_class($this));
|
||||
}
|
||||
return $this->handler->getEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event for the test
|
||||
* @param array $event
|
||||
* @param array $eventArgs
|
||||
*/
|
||||
public function setEvent(array $event, array $eventArgs = null)
|
||||
{
|
||||
$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->plugin)) {
|
||||
$this->plugin = new $this->pluginClass;
|
||||
}
|
||||
$event = new $eventClass();
|
||||
$event->setType($eventType);
|
||||
$event->setArguments($eventArgs);
|
||||
$this->plugin->setEvent($event);
|
||||
$this->eventArgs = $eventArgs;
|
||||
|
||||
$this->plugin->setConfig($this->getMockConfig());
|
||||
$this->plugin->setConnection($this->getMockConnection());
|
||||
$this->plugin->setEventHandler($this->getMockEventHandler());
|
||||
$this->plugin->setPluginHandler($this->getMockPluginHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Destroys all initialized instance properties.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setPlugin(Phergie_Plugin_Abstract $plugin)
|
||||
public function tearDown()
|
||||
{
|
||||
$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);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the runTest method to add additional annotations
|
||||
* @return PHPUnit_Framework_TestResult
|
||||
* 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
|
||||
*/
|
||||
protected function runTest()
|
||||
public function configOffsetExists($name)
|
||||
{
|
||||
if (null === $this->plugin) {
|
||||
throw new RuntimeException(
|
||||
'Tests cannot be run before plugin is set'
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
// 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];
|
||||
|
||||
if (stristr($event, '::')) {
|
||||
$event = explode('::', $event);
|
||||
}
|
||||
}
|
||||
if (isset($info['method']['eventArg'])) {
|
||||
$eventArgs = $info['method']['eventArg'];
|
||||
}
|
||||
if (null !== $event) {
|
||||
$this->setEvent($event, $eventArgs);
|
||||
}
|
||||
|
||||
$testResult = parent::runTest();
|
||||
|
||||
// Clean the event handler again... just incase this time.
|
||||
$this->handler->clearEvents();
|
||||
|
||||
return $testResult;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -32,10 +32,14 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
class IrcManager extends ImManager {
|
||||
protected $conn = null;
|
||||
protected $lastPing = null;
|
||||
protected $messageWaiting = true;
|
||||
protected $lastMessage = null;
|
||||
|
||||
protected $regChecks = array();
|
||||
protected $regChecksLookup = array();
|
||||
|
||||
protected $connected = false;
|
||||
|
||||
/**
|
||||
* Initialize connection to server.
|
||||
*
|
||||
@ -65,16 +69,55 @@ class IrcManager extends ImManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a maximum timeout for listeners before the next idle period.
|
||||
*
|
||||
* @return integer Maximum timeout
|
||||
*/
|
||||
public function timeout() {
|
||||
if ($this->messageWaiting) {
|
||||
return 1;
|
||||
} else {
|
||||
return $this->plugin->pinginterval;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Idle processing for io manager's execution loop.
|
||||
* Send keepalive pings to server.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function idle() {
|
||||
if (empty($this->lastPing) || time() - $this->lastPing > 120) {
|
||||
// Send a ping if necessary
|
||||
if (empty($this->lastPing) || time() - $this->lastPing > $this->plugin->pinginterval) {
|
||||
$this->sendPing();
|
||||
}
|
||||
|
||||
if ($this->connected) {
|
||||
// Send a waiting message if appropriate
|
||||
if ($this->messageWaiting && time() - $this->lastMessage > 1) {
|
||||
$wm = Irc_waiting_message::top();
|
||||
if ($wm === NULL) {
|
||||
$this->messageWaiting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$data = unserialize($wm->data);
|
||||
$wm->incAttempts();
|
||||
|
||||
if ($this->send_raw_message($data)) {
|
||||
$wm->delete();
|
||||
} else {
|
||||
if ($wm->attempts <= common_config('queue', 'max_retries')) {
|
||||
// Try again next idle
|
||||
$wm->releaseClaim();
|
||||
} else {
|
||||
// Exceeded the maximum number of retries
|
||||
$wm->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,6 +133,7 @@ class IrcManager extends ImManager {
|
||||
try {
|
||||
$this->conn->handleEvents();
|
||||
} catch (Phergie_Driver_Exception $e) {
|
||||
$this->connected = false;
|
||||
$this->conn->reconnect();
|
||||
}
|
||||
}
|
||||
@ -133,6 +177,7 @@ class IrcManager extends ImManager {
|
||||
|
||||
'plugins.autoload' => true,
|
||||
|
||||
// Uncomment to enable debugging output
|
||||
//'ui.enabled' => true,
|
||||
|
||||
'nickserv.password' => $this->plugin->nickservpassword,
|
||||
@ -142,6 +187,7 @@ class IrcManager extends ImManager {
|
||||
|
||||
'statusnet.messagecallback' => array($this, 'handle_irc_message'),
|
||||
'statusnet.regcallback' => array($this, 'handle_reg_response'),
|
||||
'statusnet.connectedcallback' => array($this, 'handle_connected'),
|
||||
'statusnet.unregregexp' => $this->plugin->unregregexp,
|
||||
'statusnet.regregexp' => $this->plugin->regregexp
|
||||
)
|
||||
@ -150,6 +196,7 @@ class IrcManager extends ImManager {
|
||||
$this->conn->setConfig($config);
|
||||
$this->conn->connect();
|
||||
$this->lastPing = time();
|
||||
$this->lastMessage = time();
|
||||
}
|
||||
return $this->conn;
|
||||
}
|
||||
@ -211,6 +258,39 @@ class IrcManager extends ImManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the connection is established
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle_connected() {
|
||||
$this->connected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enters a message into the database for sending when ready
|
||||
*
|
||||
* @param string $command Command
|
||||
* @param array $args Arguments
|
||||
* @return boolean
|
||||
*/
|
||||
protected function enqueue_waiting_message($data) {
|
||||
$wm = new Irc_waiting_message();
|
||||
|
||||
$wm->data = serialize($data);
|
||||
$wm->prioritise = $data['prioritise'];
|
||||
$wm->attempts = 0;
|
||||
$wm->created = common_sql_now();
|
||||
$result = $wm->insert();
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($wm, 'INSERT', __FILE__);
|
||||
throw new ServerException('DB error inserting IRC waiting queue item');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message using the daemon
|
||||
*
|
||||
@ -223,28 +303,45 @@ class IrcManager extends ImManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data['type'] != 'message') {
|
||||
// Nick checking
|
||||
$nickdata = $data['nickdata'];
|
||||
$usernick = $nickdata['user']->nickname;
|
||||
$screenname = $nickdata['screenname'];
|
||||
if ($data['type'] != 'delayedmessage') {
|
||||
if ($data['type'] != 'message') {
|
||||
// Nick checking
|
||||
$nickdata = $data['nickdata'];
|
||||
$usernick = $nickdata['user']->nickname;
|
||||
$screenname = $nickdata['screenname'];
|
||||
|
||||
// Cancel any existing checks for this user
|
||||
if (isset($this->regChecksLookup[$usernick])) {
|
||||
unset($this->regChecks[$this->regChecksLookup[$usernick]]);
|
||||
// Cancel any existing checks for this user
|
||||
if (isset($this->regChecksLookup[$usernick])) {
|
||||
unset($this->regChecks[$this->regChecksLookup[$usernick]]);
|
||||
}
|
||||
|
||||
$this->regChecks[$screenname] = $nickdata;
|
||||
$this->regChecksLookup[$usernick] = $screenname;
|
||||
}
|
||||
|
||||
$this->regChecks[$screenname] = $nickdata;
|
||||
$this->regChecksLookup[$usernick] = $screenname;
|
||||
// If there is a backlog or we need to wait, queue the message
|
||||
if ($this->messageWaiting || time() - $this->lastMessage < 1) {
|
||||
$this->enqueue_waiting_message(
|
||||
array(
|
||||
'type' => 'delayedmessage',
|
||||
'prioritise' => $data['prioritise'],
|
||||
'data' => $data['data']
|
||||
)
|
||||
);
|
||||
$this->messageWaiting = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->conn->send($data['data']['command'], $data['data']['args']);
|
||||
} catch (Phergie_Driver_Exception $e) {
|
||||
$this->connected = false;
|
||||
$this->conn->reconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->lastMessage = time();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user