<?php
/**
* Copyright (c) 2009, Laurent Laville <pear@laurent-laville.org>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the authors nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* PHP version 5
*
* @category PEAR
* @package PEAR_TestListener
* @author Laurent Laville <pear@laurent-laville.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version CVS: $Id:$
* @link http://pear.laurent-laville.org/pepr/PEAR_TestListener
* @since File available since Release 0.1.0
*/
require_once 'PHPUnit/Framework/TestListener.php';
require_once 'Log.php';
require_once 'Event/Dispatcher.php';
/**
* The base Listener for test log/progress launched through the PEAR Test Runner
*
* @category PEAR
* @package PEAR_TestListener
* @author Laurent Laville <pear@laurent-laville.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version Release: @package_version@
* @link http://pear.laurent-laville.org/pepr/PEAR_TestListener
* @since Class available since Release 0.1.0
*/
class PEAR_TestListener implements PHPUnit_Framework_TestListener
{
/**
* @var object Instance of PEAR::Log
*/
protected $logger;
/**
* @var integer test suite assertions count
*/
protected $numAssertions = 0;
/**
* PEAR_TestListener ZE2 class constructor
*
* @param object $logger An instance of PEAR::Log_composite
* @param object $dispatcher (optional) An instance of PEAR::Event_Dispatcher
*/
public function __construct(Log_composite $logger,
Event_Dispatcher $dispatcher = null
) {
$this->logger = $logger;
if (!isset($dispatcher)) {
$dispatcher = Event_Dispatcher::getInstance();
}
$dispatcher->addObserver(array($this, 'update'));
}
/**
* Logs an error occurred.
*
* @param PHPUnit_Framework_Test $test Current test case
* @param Exception $e Exception thrown by test
* @param float $time Time elapsed
*
* @return void
*/
public function addError(PHPUnit_Framework_Test $test,
Exception $e,
$time
) {
$this->logger->log(
sprintf(
"Error while running test '%s'. %s",
$test->getName(), $e->getMessage()
),
PEAR_LOG_ERR
);
}
/**
* Logs a failure occurred.
*
* @param PHPUnit_Framework_Test $test Current test case
* @param PHPUnit_Framework_AssertionFailedError $e Exception thrown by test
* @param float $time Time elapsed
*
* @return void
*/
public function addFailure(PHPUnit_Framework_Test $test,
PHPUnit_Framework_AssertionFailedError $e,
$time
) {
$this->logger->log(
sprintf(
"Test '%s' failed. %s",
$test->getName(), $e->getMessage()
),
PEAR_LOG_CRIT
);
}
/**
* Logs an incomplete test.
*
* @param PHPUnit_Framework_Test $test Current test case
* @param Exception $e Exception thrown by test
* @param float $time Time elapsed
*
* @return void
*/
public function addIncompleteTest(PHPUnit_Framework_Test $test,
Exception $e,
$time
) {
$this->logger->log(
sprintf(
"Test '%s' is incomplete. %s",
$test->getName(), $e->getMessage()
),
PEAR_LOG_WARNING
);
}
/**
* Logs a skipped test.
*
* @param PHPUnit_Framework_Test $test Current test case
* @param Exception $e Exception thrown by test
* @param float $time Time elapsed
*
* @return void
*/
public function addSkippedTest(PHPUnit_Framework_Test $test,
Exception $e,
$time
) {
$this->logger->log(
sprintf(
"Test '%s' has been skipped. %s",
$test->getName(), $e->getMessage()
),
PEAR_LOG_WARNING
);
}
/**
* Logs a test suite started.
*
* @param PHPUnit_Framework_TestSuite $suite Test suite
*
* @return void
*/
public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
{
$this->logger->log(
sprintf(
"TestSuite '%s' started.", $suite->getName()
),
PEAR_LOG_INFO
);
}
/**
* Logs a test suite ended.
*
* @param PHPUnit_Framework_TestSuite $suite Test suite
*
* @return void
*/
public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
{
$this->logger->log(
sprintf(
"TestSuite '%s' ended.", $suite->getName()
),
PEAR_LOG_INFO
);
}
/**
* Logs a test started.
*
* @param PHPUnit_Framework_Test $test Test case
*
* @return void
*/
public function startTest(PHPUnit_Framework_Test $test)
{
$this->logger->log(
sprintf(
"Test '%s' started.", $test->getName()
),
PEAR_LOG_INFO
);
}
/**
* Logs a test ended.
*
* @param PHPUnit_Framework_Test $test Test case
* @param float $time Time elapsed
*
* @return void
*/
public function endTest(PHPUnit_Framework_Test $test, $time)
{
if (method_exists($test, 'getNumAssertions')) {
$this->numAssertions += $test->getNumAssertions();
}
$this->logger->log(
sprintf(
"Test '%s' ended.", $test->getName()
),
PEAR_LOG_INFO
);
}
/**
* Implements the SplObserver interface
*
* Called when a subject notify us of an event.
*
* @param mixed $subject SplSubject or Event_Dispatcher object
* that send us notification
*
* @return void
*/
public function update($subject)
{
try {
list($notifyName, $notifyInfo, $notifyObj)
= $this->splSubjectAdapter($subject);
}
catch (InvalidArgumentException $e) {
return;
}
switch ($notifyName) {
case 'endTestSuite':
$result = $notifyObj;
$preamble = 'TestSuite'
. ' was ' . ($result->wasSuccessful() ? '' : 'not ')
. 'successful.';
$run = sprintf(
"%s%s%s%s%s%s.",
$this->getCountString($result->count(), 'Test'),
$this->getCountString($this->numAssertions, 'Assertion'),
$this->getCountString($result->failureCount(), 'Failure'),
$this->getCountString($result->errorCount(), 'Error'),
$this->getCountString(
$result->notImplementedCount(), 'Incomplete', false
),
$this->getCountString($result->skippedCount(), 'Skipped', false)
);
$this->logger->log($preamble . ltrim($run, ','), PEAR_LOG_NOTICE);
break;
}
}
/**
* Adapter to translate either a SplSubject or Event_Dispatcher instance
* into a common array data type
*
* @param mixed $subject SplSubject or Event_Dispatcher object
* that send us notification
*
* @return array Data hash that contains
* first the event name, second the subject additionnal data,
* and third instance of subject itself
* @throws InvalidArgumentException If $subject is invalid object instance
*/
protected function splSubjectAdapter($subject)
{
if ($subject instanceof Event_Notification) {
$notifyName = $subject->getNotificationName();
$notifyInfo = $subject->getNotificationInfo();
$notifyObj = $subject->getNotificationObject();
} elseif ($subject instanceof SplSubject) {
if (method_exists($subject, 'getNotification')) {
$event = $subject->getNotification();
$notifyName = (isset($event['name'])) ? $event['name'] : null;
$notifyInfo = (isset($event['info'])) ? $event['info'] : null;
$notifyObj = $subject;
}
}
if (!isset($notifyName) || !isset($notifyInfo)) {
throw new InvalidArgumentException(
'No observer event name or event info data found.'
);
}
return array($notifyName, $notifyInfo, $notifyObj);
}
/**
* Print categorize formatted result of test suite
*
* CREDITS to PHPUnit3 (PHPUnit/TextUI/ResultPrinter.php)
*
* @param int $count Number of result in category
* @param string $name Name of the result category
* @param bool $plural (optional) If string can have plural or not
*
* @return string
*/
protected function getCountString($count, $name, $plural = true)
{
if ($count > 0) {
$string = sprintf(
', %s: %d',
$name . ($plural ? (($count == 1) ? '' : 's') : ''),
$count
);
} else {
$string = '';
}
return $string;
}
}
?>