9 * This source file is subject to the new BSD license that is bundled
10 * with this package in the file LICENSE.
11 * It is also available through the world-wide-web at this URL:
12 * http://phergie.org/license
15 * @package Phergie_Tests
16 * @author Phergie Development Team <team@phergie.org>
17 * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
18 * @license http://phergie.org/license New BSD License
19 * @link http://pear.phergie.org/package/Phergie_Tests
23 * Unit test suite for Pherge_Plugin_Karma.
26 * @package Phergie_Tests
27 * @author Phergie Development Team <team@phergie.org>
28 * @license http://phergie.org/license New BSD License
29 * @link http://pear.phergie.org/package/Phergie_Tests
31 class Phergie_Plugin_KarmaTest extends Phergie_Plugin_TestCase
34 * Skips tests if the SQLite PDO driver is not available.
38 public function setUp()
40 if (!extension_loaded('PDO') || !extension_loaded('pdo_sqlite')) {
41 $this->markTestSkipped('PDO or pdo_sqlite extension is required');
48 * Configures the plugin to use a temporary copy of the database.
50 * @return PDO Connection to the temporary database
52 private function createMockDatabase()
54 $dbPath = $this->getPluginsPath('Karma/karma.db');
55 $db = $this->getMockDatabase($dbPath);
56 $this->plugin->setDb($db);
61 * Tests the requirement of the Command plugin.
65 public function testRequiresCommandPlugin()
67 $this->assertRequiresPlugin('Command');
68 $this->plugin->onLoad();
72 * Initiates a karma event with a specified term.
74 * @param string $term Karma term
76 * @return Phergie_Event_Request Initiated mock event
78 private function initiateKarmaEvent($term)
81 'receiver' => $this->source,
82 'text' => 'karma ' . $term
84 $event = $this->getMockEvent('privmsg', $args);
85 $this->plugin->setEvent($event);
90 * Checks for an expected karma response.
92 * @param Phergie_Event_Request $event Event containing the karma
94 * @param string $term Karma term
95 * @param string $response Portion of the response
96 * message following the term
97 * from the original event
101 private function checkForKarmaResponse($event, $term, $response)
103 $text = $event->getNick() . ': ' . $response;
104 $this->assertEmitsEvent('privmsg', array($event->getSource(), $text));
105 $this->plugin->onCommandKarma($term);
109 * Tests that a default database is used when none is specified.
113 public function testGetDb()
115 $db = $this->plugin->getDb();
116 $this->assertType('PDO', $db);
120 * Tests specifying a custom database for the plugin to use.
124 public function testSetDb()
126 $db = $this->createMockDatabase();
127 $this->assertSame($db, $this->plugin->getDb());
131 * Tests that issuing the karma command with an unknown term returns a
136 public function testKarmaCommandOnUnknownTerm()
139 $this->createMockDatabase();
140 $event = $this->initiateKarmaEvent($term);
141 $this->checkForKarmaResponse($event, $term, $term . ' has neutral karma.');
145 * Tests that issuing the karma command with the term "me" returns the
146 * the karma rating for the initiating user.
150 public function testKarmaCommandOnUser()
153 $this->createMockDatabase();
154 $event = $this->initiateKarmaEvent($term);
155 $this->checkForKarmaResponse($event, $term, 'You have neutral karma.');
159 * Tests that issuing the karma command with a term that has a fixed
160 * karma rating results in that rating being returned.
164 public function testKarmaCommandWithFixedKarmaTerm()
167 $this->createMockDatabase();
168 $event = $this->initiateKarmaEvent($term);
169 $this->checkForKarmaResponse($event, $term, 'phergie has karma of awesome.');
173 * Supporting method that tests the result of a karma term rating change.
175 * @param string $term Karma term for which the rating is being
177 * @param string $operation ++ or --
178 * @param int $karma Expected karma rating after the change is
181 private function checkForKarmaRatingChange($term, $operation, $karma)
184 'receiver' => $this->source,
185 'text' => $term . $operation
187 $event = $this->getMockEvent('privmsg', $args);
188 $this->plugin->setEvent($event);
189 $this->plugin->onPrivmsg();
190 $event = $this->initiateKarmaEvent($term);
191 $this->checkForKarmaResponse($event, $term, $term . ' has karma of ' . $karma . '.');
195 * Tests incrementing the karma rating of a new term.
199 public function testIncrementingKarmaRating()
201 $this->createMockDatabase();
202 $this->checkForKarmaRatingChange('foo', '++', 1);
206 * Tests decrementing the karma rating of a new term.
210 public function testDecrementingKarmaRating()
212 $this->createMockDatabase();
213 $this->checkForKarmaRatingChange('foo', '--', -1);
217 * Tests modifying the karma rating of an existing term.
221 public function testChangingExistingKarmaRating()
224 $this->createMockDatabase();
225 $this->checkForKarmaRatingChange($term, '++', 1);
226 $this->checkForKarmaRatingChange($term, '++', 2);
230 * Tests resetting the karma rating of an existing term to 0.
234 public function testResettingExistingKarmaRating()
237 $this->createMockDatabase();
238 $this->checkForKarmaRatingChange($term, '++', 1);
239 $this->plugin->onCommandReincarnate($term);
240 $event = $this->initiateKarmaEvent($term);
241 $this->checkForKarmaResponse($event, $term, $term . ' has neutral karma.');
245 * Data provider for testKarmaComparisons().
247 * @return array Enumerated array of enumerated arrays each containing a
248 * set of parameter values for a single call to
249 * testKarmaComparisons()
251 public function dataProviderTestKarmaComparisons()
256 $positive = 'True that.';
257 $negative = 'No sir, not at all.';
260 array($term1, $term2, 1, 0, '>', $positive),
261 array($term1, $term2, 0, 1, '>', $negative),
262 array($term1, $term2, 1, 1, '>', $negative),
263 array($term1, $term2, 1, 0, '<', $negative),
264 array($term1, $term2, 0, 1, '<', $positive),
265 array($term1, $term2, 1, 1, '<', $negative),
266 array($term1, 'phergie', 1, 0, '>', $positive),
267 array('phergie', $term2, 0, 1, '<', $positive),
268 array($term1, 'everything', 0, 0, '>', $positive),
269 array('everything', $term2, 0, 0, '>', $positive),
274 * Tests comparing the karma ratings of two terms.
276 * @param string $term1 First term
277 * @param string $term2 Second term
278 * @param int $karma1 Karma rating of the first time, 0 or 1
279 * @param int $karma2 Karma rating of the second term, 0 or 1
280 * @param string $operator Comparison operator, > or <
281 * @param string $response Response to check for
284 * @dataProvider dataProviderTestKarmaComparisons
286 public function testKarmaComparisons($term1, $term2, $karma1, $karma2,
289 $db = $this->createMockDatabase();
291 // Reduce answer tables to expected response
292 $stmt = $db->prepare('DELETE FROM positive_answers WHERE answer != ?');
293 $stmt->execute(array($response));
294 $stmt = $db->prepare('DELETE FROM negative_answers WHERE answer != ?');
295 $stmt->execute(array($response));
298 $this->checkForKarmaRatingChange($term1, '++', 1);
302 $this->checkForKarmaRatingChange($term2, '++', 1);
306 'receiver' => $this->source,
307 'text' => $term1 . ' ' . $operator . ' ' . $term2
309 $event = $this->getMockEvent('privmsg', $args);
310 $this->plugin->setEvent($event);
312 // Test lack of a response for terms with fixed karma ratings
313 if ($term1 == 'phergie' || $term2 == 'phergie') {
314 $callback = 'assertDoesNotEmitEvent';
316 $callback = 'assertEmitsEvent';
319 $this->$callback('privmsg', array($event->getSource(), $response));
320 $this->plugin->onPrivmsg();
322 // Test for karma changes when one term is "everything"
323 if ($term1 == 'everything' || $term2 == 'everything') {
324 if ($term1 == 'everything') {
326 $karma = ($operator == '>') ? -1 : 1;
329 $karma = ($operator == '>') ? 1 : -1;
331 $event = $this->initiateKarmaEvent($term);
332 $this->checkForKarmaResponse($event, $term, $term . ' has karma of ' . $karma . '.');