Updated to KH 3.3 and improved

This commit is contained in:
Deon George
2013-04-13 16:17:56 +10:00
parent 6f50463ec7
commit 6f7913d363
1551 changed files with 96188 additions and 29813 deletions

View File

@@ -9,28 +9,16 @@ I've chosen to do this because it's part of the PHPUnit coding conventions and i
* [PHPUnit](http://www.phpunit.de/) >= 3.4
### Optional extras
## Usage
* The [Archive module](http://github.com/BRMatt/kohana-archive) is required if you want to download code coverage reports from the web ui, however you can also view them without downloading.
$ phpunit --bootstrap=modules/unittest/bootstrap.php modules/unittest/tests.php
## Installation
Alternatively you can use a `phpunit.xml` to have a more fine grained control
over which tests are included and which files are whitelisted.
**Step 0**: Download this module!
Make sure you only whitelist the highest files in the cascading filesystem, else
you could end up with a lot of "class cannot be redefined" errors.
To get it from git execute the following command in the root of your project:
$ git submodule add git://github.com/kohana/unittest.git modules/unittest
And watch the gitorious magic...
Of course, you can always download the code from the [github project](http://github.com/kohana/unittest) as an archive.
## Running the tests
$ phpunit --bootstrap=modules/unittest/bootstrap.php {tests}
Where `{tests}` can either be a path to a folder of tests, or a path to the the `tests.php` (`modules/unittest/tests.php`)
Please see the guide pages for more info. An example of how we run the tests for the kohana project can be found in the [phing build script](https://github.com/kohana/kohana/blob/3.1/master/build.xml#L172).
If you're looking for more info on running the core kohana tests then please see our [dev wiki](https://github.com/kohana/kohana/wiki/Unit-Testing-Kohana)
If you use the `tests.php` testsuite loader then it will only whitelist the
highest files. see `config/unittest.php` for details on configuring the
`tests.php` whitelist.

View File

@@ -1,38 +1,50 @@
<?php
/**
* The directory in which your application specific resources are located.
* The application directory must contain the bootstrap.php file.
*
* @see http://kohanaframework.org/guide/about.install#application
* @link http://kohanaframework.org/guide/about.install#application
*/
$application = 'application';
/**
* The directory in which your modules are located.
*
* @see http://kohanaframework.org/guide/about.install#modules
* @link http://kohanaframework.org/guide/about.install#modules
*/
$modules = 'modules';
$sysmodules = 'includes/kohana/modules';
/**
* The directory in which the Kohana resources are located. The system
* directory must contain the classes/kohana.php file.
*
* @see http://kohanaframework.org/guide/about.install#system
* @link http://kohanaframework.org/guide/about.install#system
*/
$system = 'system';
$system = 'includes/kohana/system';
/**
* The default extension of resource files. If you change this, all resources
* must be renamed to use the new extension.
*
* @see http://kohanaframework.org/guide/about.install#ext
* @link http://kohanaframework.org/guide/about.install#ext
*/
define('EXT', '.php');
/**
* Set the path to the document root
*
* This assumes that this file is stored 2 levels below the DOCROOT, if you move
* this bootstrap file somewhere else then you'll need to modify this value to
* compensate.
*/
define('DOCROOT', realpath(dirname(__FILE__).'/../../').DIRECTORY_SEPARATOR);
/**
* Set the PHP error reporting level. If you set this in php.ini, you remove this.
* @see http://php.net/error_reporting
* @link http://www.php.net/manual/errorfunc.configuration#ini.error-reporting
*
* When developing your application, it is highly recommended to enable notices
* and strict warnings. Enable them by using: E_ALL | E_STRICT
@@ -49,12 +61,9 @@ error_reporting(E_ALL | E_STRICT);
* End of standard configuration! Changing any of the code below should only be
* attempted by those with a working knowledge of Kohana internals.
*
* @see http://kohanaframework.org/guide/using.configuration
* @link http://kohanaframework.org/guide/using.configuration
*/
// Set the full path to the docroot
define('DOCROOT', realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR);
// Make the application relative to the docroot
if ( ! is_dir($application) AND is_dir(DOCROOT.$application))
{
@@ -67,6 +76,12 @@ if ( ! is_dir($modules) AND is_dir(DOCROOT.$modules))
$modules = DOCROOT.$modules;
}
// Make the system relative to the docroot, for symlink'd index.php
if ( ! is_dir($sysmodules) AND is_dir(DOCROOT.$sysmodules))
{
$sysmodules = DOCROOT.$sysmodules;
}
// Make the system relative to the docroot
if ( ! is_dir($system) AND is_dir(DOCROOT.$system))
{
@@ -76,10 +91,11 @@ if ( ! is_dir($system) AND is_dir(DOCROOT.$system))
// Define the absolute paths for configured directories
define('APPPATH', realpath($application).DIRECTORY_SEPARATOR);
define('MODPATH', realpath($modules).DIRECTORY_SEPARATOR);
define('SMDPATH', realpath($sysmodules).DIRECTORY_SEPARATOR);
define('SYSPATH', realpath($system).DIRECTORY_SEPARATOR);
// Clean up the configuration vars
unset($application, $modules, $system);
unset($application, $modules, $sysmodules, $system);
/**
* Define the start time of the application, used for profiling.
@@ -97,8 +113,24 @@ if ( ! defined('KOHANA_START_MEMORY'))
define('KOHANA_START_MEMORY', memory_get_usage());
}
define('PHPUNITTEST','192.168.242.3');
// Bootstrap the application
require APPPATH.'bootstrap'.EXT;
// Disable output buffering
if (($ob_len = ob_get_length()) !== FALSE)
{
// flush_end on an empty buffer causes headers to be sent. Only flush if needed.
if ($ob_len > 0)
{
ob_end_flush();
}
else
{
ob_end_clean();
}
}
// Enable the unittest module
Kohana::modules(Kohana::modules() + array('unittest' => MODPATH.'unittest'));
Kohana::modules(Kohana::modules() + array('unittest' => SMDPATH.'unittest'));

View File

@@ -0,0 +1,20 @@
<?php
include_once('bootstrap.php');
// Enable all modules we can find
$modules_iterator = new DirectoryIterator(MODPATH);
$modules = array();
foreach ($modules_iterator as $module)
{
if ($module->isDir())
{
$modules[$module->getFilename()] = MODPATH.$module->getFilename();
}
}
Kohana::modules(Kohana::modules() + $modules);
unset ($modules_iterator, $modules, $module);

View File

@@ -8,8 +8,7 @@
* @copyright (c) 2008-2009 Kohana Team
* @license http://kohanaphp.com/license
*/
// @codingStandardsIgnoreFile
abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Database_TestCase {
abstract class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Database_TestCase {
/**
* Whether we should enable work arounds to make the tests compatible with phpunit 3.4
@@ -21,7 +20,7 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
* Make sure PHPUnit backs up globals
* @var boolean
*/
protected $backupGlobals = TRUE;
protected $backupGlobals = FALSE;
/**
* A set of unittest helpers that are shared between normal / database
@@ -36,6 +35,12 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
protected $environmentDefault = array();
/**
* The kohana database connection that PHPUnit should use for this test
* @var string
*/
protected $_database_connection = 'default';
/**
* Creates a predefined environment using the default environment
*
@@ -44,9 +49,9 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public function setUp()
{
if (self::$_assert_type_compatability === NULL)
if(self::$_assert_type_compatability === NULL)
{
if ( ! class_exists('PHPUnit_Runner_Version'))
if( ! class_exists('PHPUnit_Runner_Version'))
{
require_once 'PHPUnit/Runner/Version.php';
}
@@ -82,8 +87,7 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
public function getConnection()
{
// Get the unittesting db connection
$config = Kohana::config('database')
->{Kohana::config('unittest')->db_connection};
$config = Kohana::$config->load('database.'.$this->_database_connection);
if($config['type'] !== 'pdo')
{
@@ -101,15 +105,15 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
return $this->createDefaultDBConnection($pdo, $config['connection']['database']);
}
/**
* Gets a connection to the unittest database
*
* @return Kohana_Database The database connection
*/
public function getKohanaConnection()
{
return Database::instance(Kohana::config('unittest')->db_connection);
}
/**
* Gets a connection to the unittest database
*
* @return Kohana_Database The database connection
*/
public function getKohanaConnection()
{
return Database::instance(Kohana::$config->load('unittest')->db_connection);
}
/**
* Removes all kohana related cache files in the cache directory
@@ -167,8 +171,10 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public static function assertInstanceOf($expected, $actual, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertType($expected, $actual, $message);
}
return parent::assertInstanceOf($expected, $actual, $message);
}
@@ -184,8 +190,10 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public static function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertAttributeType($expected, $attributeName, $classOrObject, $message);
}
return parent::assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message);
}
@@ -200,8 +208,10 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public static function assertNotInstanceOf($expected, $actual, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertNotType($expected, $actual, $message);
}
return self::assertNotInstanceOf($expected, $actual, $message);
}
@@ -217,8 +227,10 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public static function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertAttributeNotType($expected, $attributeName, $classOrObject, $message);
}
return self::assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message);
}
@@ -233,8 +245,10 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public static function assertInternalType($expected, $actual, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertType($expected, $actual, $message);
}
return parent::assertInternalType($expected, $actual, $message);
}
@@ -250,8 +264,10 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public static function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertAttributeType($expected, $attributeName, $classOrObject, $message);
}
return self::assertAttributeInternalType($expected, $attributeName, $classOrObject, $message);
}
@@ -266,8 +282,10 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public static function assertNotInternalType($expected, $actual, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertNotType($expected, $actual, $message);
}
return self::assertNotInternalType($expected, $actual, $message);
}
@@ -283,8 +301,10 @@ abstract Class Kohana_Unittest_Database_TestCase extends PHPUnit_Extensions_Data
*/
public static function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertAttributeNotType($expected, $attributeName, $classOrObject, $message);
}
return self::assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message);
}

View File

@@ -132,7 +132,7 @@ class Kohana_Unittest_Helpers {
$class->setStaticPropertyValue($var, $value);
}
// If this is an environment variable
elseif (preg_match('/^[A-Z_-]+$/D', $option) OR isset($_SERVER[$option]))
elseif (preg_match('/^[A-Z_-]+$/', $option) OR isset($_SERVER[$option]))
{
if ($backup_needed)
{
@@ -146,12 +146,12 @@ class Kohana_Unittest_Helpers {
{
if ($backup_needed)
{
$this->_environment_backup[$option] = Kohana::config($option);
$this->_environment_backup[$option] = Kohana::$config->load($option);
}
list($group, $var) = explode('.', $option, 2);
Kohana::config($group)->set($var, $value);
Kohana::$config->load($group)->set($var, $value);
}
}
}

View File

@@ -4,7 +4,6 @@
* A version of the stock PHPUnit testcase that includes some extra helpers
* and default settings
*/
// @codingStandardsIgnoreFile
abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
/**
@@ -17,7 +16,7 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
* Make sure PHPUnit backs up globals
* @var boolean
*/
protected $backupGlobals = TRUE;
protected $backupGlobals = FALSE;
/**
* A set of unittest helpers that are shared between normal / database
@@ -40,9 +39,9 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public function setUp()
{
if (self::$_assert_type_compatability === NULL)
if(self::$_assert_type_compatability === NULL)
{
if ( ! class_exists('PHPUnit_Runner_Version'))
if( ! class_exists('PHPUnit_Runner_Version'))
{
require_once 'PHPUnit/Runner/Version.php';
}
@@ -122,8 +121,10 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public static function assertInstanceOf($expected, $actual, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertType($expected, $actual, $message);
}
return parent::assertInstanceOf($expected, $actual, $message);
}
@@ -139,8 +140,10 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public static function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertAttributeType($expected, $attributeName, $classOrObject, $message);
}
return parent::assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message);
}
@@ -155,8 +158,10 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public static function assertNotInstanceOf($expected, $actual, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertNotType($expected, $actual, $message);
}
return self::assertNotInstanceOf($expected, $actual, $message);
}
@@ -172,8 +177,10 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public static function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertAttributeNotType($expected, $attributeName, $classOrObject, $message);
}
return self::assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message);
}
@@ -188,8 +195,10 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public static function assertInternalType($expected, $actual, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertType($expected, $actual, $message);
}
return parent::assertInternalType($expected, $actual, $message);
}
@@ -205,8 +214,10 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public static function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertAttributeType($expected, $attributeName, $classOrObject, $message);
}
return self::assertAttributeInternalType($expected, $attributeName, $classOrObject, $message);
}
@@ -221,8 +232,10 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public static function assertNotInternalType($expected, $actual, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertNotType($expected, $actual, $message);
}
return self::assertNotInternalType($expected, $actual, $message);
}
@@ -238,8 +251,10 @@ abstract class Kohana_Unittest_TestCase extends PHPUnit_Framework_TestCase {
*/
public static function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
{
if (self::$_assert_type_compatability)
if(self::$_assert_type_compatability)
{
return self::assertAttributeNotType($expected, $attributeName, $classOrObject, $message);
}
return self::assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message);
}

View File

@@ -0,0 +1,80 @@
<?php defined('SYSPATH') or die('No direct script access.');
/**
* A version of the stock PHPUnit testsuite that supports whitelisting and
* blacklisting for code coverage filter
*/
abstract class Kohana_Unittest_TestSuite extends PHPUnit_Framework_TestSuite
{
/**
* Holds the details of files that should be white and blacklisted for
* code coverage
*
* @var array
*/
protected $_filter_calls = array(
'addFileToBlacklist' => array(),
'addDirectoryToBlacklist' => array(),
'addFileToWhitelist' => array());
/**
* Runs the tests and collects their result in a TestResult.
*
* @param PHPUnit_Framework_TestResult $result
* @param mixed $filter
* @param array $groups
* @param array $excludeGroups
* @param boolean $processIsolation
* @return PHPUnit_Framework_TestResult
* @throws InvalidArgumentException
*/
public function run(PHPUnit_Framework_TestResult $result = NULL, $filter = FALSE, array $groups = array(), array $excludeGroups = array(), $processIsolation = FALSE)
{
// Get the code coverage filter from the suite's result object
$coverage = $result->getCodeCoverage();
if ($coverage)
{
$coverage_filter = $coverage->filter();
// Apply the white and blacklisting
foreach ($this->_filter_calls as $method => $args)
{
foreach ($args as $arg)
{
$coverage_filter->$method($arg);
}
}
}
return parent::run($result, $filter, $groups, $excludeGroups, $processIsolation);
}
/**
* Queues a file to be added to the code coverage blacklist when the suite runs
* @param string $file
*/
public function addFileToBlacklist($file)
{
$this->_filter_calls['addFileToBlacklist'][] = $file;
}
/**
* Queues a directory to be added to the code coverage blacklist when the suite runs
* @param string $dir
*/
public function addDirectoryToBlacklist($dir)
{
$this->_filter_calls['addDirectoryToBlacklist'][] = $dir;
}
/**
* Queues a file to be added to the code coverage whitelist when the suite runs
* @param string $file
*/
public function addFileToWhitelist($file)
{
$this->_filter_calls['addFileToWhitelist'][] = $file;
}
}

View File

@@ -13,13 +13,6 @@
class Kohana_Unittest_Tests {
static protected $cache = array();
/**
* Flag to identify whether the installed version of phpunit
* is greater than or equal to 3.5
* @var boolean
*/
static protected $phpunit_v35 = FALSE;
/**
* Loads test files if they cannot be found by kohana
* @param <type> $class
@@ -45,65 +38,19 @@ class Kohana_Unittest_Tests {
*/
static public function configure_environment($do_whitelist = TRUE, $do_blacklist = TRUE)
{
// During a webui request we need to manually load PHPUnit
if ( ! class_exists('PHPUnit_Util_Filter', FALSE) AND ! function_exists('phpunit_autoload'))
{
try
{
include_once 'PHPUnit/Autoload.php';
}
catch (ErrorException $e)
{
include_once 'PHPUnit/Framework.php';
}
}
// Allow PHPUnit to handle exceptions and errors
if (Kohana::$is_cli)
{
restore_exception_handler();
restore_error_handler();
}
restore_exception_handler();
restore_error_handler();
spl_autoload_register(array('Unittest_tests', 'autoload'));
// As of PHPUnit v3.5 there are slight differences in the way files are black|whitelisted
self::$phpunit_v35 = function_exists('phpunit_autoload');
Unittest_tests::$cache = (($cache = Kohana::cache('unittest_whitelist_cache')) === NULL) ? array() : $cache;
$config = Kohana::config('unittest');
if ($do_whitelist AND $config->use_whitelist)
{
self::whitelist();
}
if ($do_blacklist AND count($config['blacklist']))
{
Unittest_tests::blacklist($config->blacklist);
}
}
/**
* Helper function to see if unittest is enabled in the config
*
* @return boolean
*/
static function enabled()
{
$p_environment = Kohana::config('unittest.environment');
$k_environment = Kohana::$environment;
return (is_array($p_environment) AND in_array($k_environment, $p_environment))
OR
($k_environment === $p_environment);
}
/**
* Creates the test suite for kohana
*
* @return PHPUnit_Framework_TestSuite
* @return Unittest_TestSuite
*/
static function suite()
{
@@ -114,10 +61,25 @@ class Kohana_Unittest_Tests {
return $suite;
}
Unittest_Tests::configure_environment();
$suite = new Unittest_TestSuite;
// Load the whitelist and blacklist for code coverage
$config = Kohana::$config->load('unittest');
if ($config->use_whitelist)
{
Unittest_Tests::whitelist(NULL, $suite);
}
if (count($config['blacklist']))
{
Unittest_Tests::blacklist($config->blacklist, $suite);
}
// Add tests
$files = Kohana::list_files('tests');
$suite = new PHPUnit_Framework_TestSuite;
self::addTests($suite, $files);
return $suite;
@@ -128,23 +90,20 @@ class Kohana_Unittest_Tests {
*
* Uses recursion to scan subdirectories
*
* @param PHPUnit_Framework_TestSuite $suite The test suite to add to
* @param Unittest_TestSuite $suite The test suite to add to
* @param array $files Array of files to test
*/
// @codingStandardsIgnoreStart
static function addTests(PHPUnit_Framework_TestSuite $suite, array $files)
// @codingStandardsIgnoreEnd
static function addTests(Unittest_TestSuite $suite, array $files)
{
if (self::$phpunit_v35)
{
$filter = PHP_CodeCoverage_Filter::getInstance();
}
foreach ($files as $file)
foreach ($files as $path => $file)
{
if (is_array($file))
{
self::addTests($suite, $file);
if ($path != 'tests'.DIRECTORY_SEPARATOR.'test_data')
{
self::addTests($suite, $file);
}
}
else
{
@@ -161,14 +120,7 @@ class Kohana_Unittest_Tests {
require_once($file);
}
if (isset($filter))
{
$filter->addFileToBlacklist($file);
}
else
{
PHPUnit_Util_Filter::addFileToFilter($file);
}
$suite->addFileToBlacklist($file);
}
}
}
@@ -177,38 +129,20 @@ class Kohana_Unittest_Tests {
/**
* Blacklist a set of files in PHPUnit code coverage
*
* @param array A set of files to blacklist
* @param array $blacklist_items A set of files to blacklist
* @param Unittest_TestSuite $suite The test suite
*/
static public function blacklist(array $blacklist_items)
static public function blacklist(array $blacklist_items, Unittest_TestSuite $suite = NULL)
{
if (self::$phpunit_v35)
foreach ($blacklist_items as $item)
{
$filter = PHP_CodeCoverage_Filter::getInstance();
foreach ($blacklist_items as $item)
if (is_dir($item))
{
if (is_dir($item))
{
$filter->addDirectoryToBlacklist($item);
}
else
{
$filter->addFileToBlacklist($item);
}
$suite->addDirectoryToBlacklist($item);
}
}
else
{
foreach ($blacklist_items as $item)
else
{
if (is_dir($item))
{
PHPUnit_Util_Filter::addDirectoryToFilter($item);
}
else
{
PHPUnit_Util_Filter::addFileToFilter($item);
}
$suite->addFileToBlacklist($item);
}
}
}
@@ -220,8 +154,9 @@ class Kohana_Unittest_Tests {
* set in the config file
*
* @param array $directories Optional directories to whitelist
* @param Unittest_Testsuite $suite Suite to load the whitelist into
*/
static public function whitelist(array $directories = NULL)
static public function whitelist(array $directories = NULL, Unittest_TestSuite $suite = NULL)
{
if (empty($directories))
{
@@ -236,7 +171,7 @@ class Kohana_Unittest_Tests {
}
// Only whitelist the "top" files in the cascading filesystem
self::set_whitelist(Kohana::list_files('classes', $directories));
self::set_whitelist(Kohana::list_files('classes', $directories), $suite);
}
}
@@ -248,7 +183,7 @@ class Kohana_Unittest_Tests {
*/
static protected function get_config_whitelist()
{
$config = Kohana::config('unittest');
$config = Kohana::$config->load('unittest');
$directories = array();
if ($config->whitelist['app'])
@@ -292,19 +227,16 @@ class Kohana_Unittest_Tests {
* Recursively whitelists an array of files
*
* @param array $files Array of files to whitelist
* @param Unittest_TestSuite $suite Suite to load the whitelist into
*/
static protected function set_whitelist($files)
static protected function set_whitelist($files, Unittest_TestSuite $suite = NULL)
{
if (self::$phpunit_v35)
{
$filter = PHP_CodeCoverage_Filter::getInstance();
}
foreach ($files as $file)
{
if (is_array($file))
{
self::set_whitelist($file);
self::set_whitelist($file, $suite);
}
else
{
@@ -320,9 +252,9 @@ class Kohana_Unittest_Tests {
if (Unittest_tests::$cache[$file])
{
if (isset($filter))
if (isset($suite))
{
$filter->addFileToWhitelist($file);
$suite->addFileToWhitelist($file);
}
else
{
@@ -332,5 +264,4 @@ class Kohana_Unittest_Tests {
}
}
}
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* Transparent extension for Kohana_Unittest_Database_TestCase
*
* Provides some unittest helpers and allows a kohana database connection to be
* used to connect to the database
*
* @package Kohana/UnitTest
* @author Kohana Team
* @copyright (c) 2008-2009 Kohana Team
* @license http://kohanaphp.com/license
*/
abstract class Unittest_Database_TestCase extends Kohana_Unittest_Database_TestCase
{
}

View File

@@ -0,0 +1,3 @@
<?php defined('SYSPATH') or die('No direct script access.');
abstract class Unittest_TestCase extends Kohana_Unittest_TestCase {}

View File

@@ -0,0 +1,3 @@
<?php defined('SYSPATH') OR die('No direct script access.');
class Unittest_TestSuite extends Kohana_Unittest_TestSuite {}

View File

@@ -1,352 +0,0 @@
<?php defined('SYSPATH') or die ('No direct script access.');
/**
* PHPUnit Kohana web based test runner
*
* @package Kohana/UnitTest
* @author Kohana Team
* @author BRMatt <matthew@sigswitch.com>
* @author Paul Banks
* @copyright (c) 2008-2009 Kohana Team
* @license http://kohanaphp.com/license
*/
class Controller_UnitTest extends Controller_Template
{
/**
* Whether the archive module is available
* @var boolean
*/
protected $cc_archive_available = FALSE;
/**
* Unittest config
* @var Config
*/
protected $config = NULL;
/**
* The uri by which the report uri will be executed
* @var string
*/
protected $report_uri = '';
/**
* The uri by which the run action will be executed
* @var string
*/
protected $run_uri = '';
/**
* Is the XDEBUG extension loaded?
* @var boolean
*/
protected $xdebug_loaded = FALSE;
/**
* Template
* @var string
*/
public $template = 'unittest/layout';
/**
* Loads test suite
*/
public function before()
{
parent::before();
if ( ! Unittest_tests::enabled())
{
// Pretend this is a normal 404 error...
$this->status = 404;
throw new Kohana_Request_Exception('Unable to find a route to match the URI: :uri',
array(':uri' => $this->request->uri()));
}
// Prevent the whitelist from being autoloaded, but allow the blacklist
// to be loaded
Unittest_Tests::configure_environment(FALSE);
$this->config = Kohana::config('unittest');
// This just stops some very very long lines
$route = Route::get('unittest');
$this->report_uri = $route->uri(array('action' => 'report'));
$this->run_uri = $route->uri(array('action' => 'run'));
// Switch used to disable cc settings
$this->xdebug_loaded = extension_loaded('xdebug');
$this->cc_archive_enabled = class_exists('Archive');
Kohana_View::set_global('xdebug_enabled', $this->xdebug_loaded);
Kohana_View::set_global('cc_archive_enabled', $this->cc_archive_enabled);
}
/**
* Handles index page for /unittest/ and /unittest/index/
*/
public function action_index()
{
$this->template->body = View::factory('unittest/index')
->set('run_uri', $this->run_uri)
->set('report_uri', $this->report_uri)
->set('whitelistable_items', $this->get_whitelistable_items())
->set('groups', $this->get_groups_list(Unittest_tests::suite()));
}
/**
* Handles report generation
*/
public function action_report()
{
// Fairly foolproof
if ( ! $this->config->cc_report_path AND ! class_exists('Archive'))
throw new Kohana_Exception('Cannot generate report');
// We don't want to use the HTML layout, we're sending the user 100111011100110010101100
$this->auto_render = FALSE;
$suite = Unittest_tests::suite();
$temp_path = rtrim($this->config->temp_path, '/').'/';
$group = (array) Arr::get($_GET, 'group', array());
// Stop unittest from interpretting "all groups" as "no groups"
if (empty($group) OR empty($group[0]))
{
$group = array();
}
if (Arr::get($_GET, 'use_whitelist', FALSE))
{
$this->whitelist(Arr::get($_GET, 'whitelist', array()));
}
$runner = new Kohana_Unittest_Runner($suite);
// If the user wants to download a report
if ($this->cc_archive_enabled AND Arr::get($_GET, 'archive') === '1')
{
// $report is the actual directory of the report,
// $folder is the name component of directory
list($report, $folder) = $runner->generate_report($group, $temp_path);
$archive = Archive::factory('zip');
// TODO: Include the test results?
$archive->add($report, 'report', TRUE);
$filename = $folder.'.zip';
$archive->save($temp_path.$filename);
// It'd be nice to clear up afterwards but by deleting the report dir we corrupt the archive
// And once the archive has been sent to the user Request stops the script so we can't delete anything
// It'll be up to the user to delete files periodically
$this->request->send_file($temp_path.$filename, $filename);
}
else
{
$folder = trim($this->config->cc_report_path, '/').'/';
$path = DOCROOT.$folder;
if ( ! file_exists($path))
throw new Kohana_Exception('Report directory :dir does not exist', array(':dir' => $path));
if ( ! is_writable($path))
throw new Kohana_Exception('Script doesn\'t have permission to write to report dir :dir ', array(':dir' => $path));
$runner->generate_report($group, $path, FALSE);
$this->request->redirect(URL::site($folder.'index.html', $this->request));
}
}
/**
* Handles test running interface
*/
public function action_run()
{
$this->template->body = View::factory('unittest/results');
// Get the test suite and work out which groups we're testing
$suite = Unittest_tests::suite();
$group = (array) Arr::get($_GET, 'group', array());
// Stop phpunit from interpretting "all groups" as "no groups"
if (empty($group) OR empty($group[0]))
{
$group = array();
}
// Only collect code coverage if the user asked for it
$collect_cc = (bool) Arr::get($_GET, 'collect_cc', FALSE);
if ($collect_cc AND Arr::get($_GET, 'use_whitelist', FALSE))
{
$whitelist = $this->whitelist(Arr::get($_GET, 'whitelist', array()));
}
$runner = new Kohana_Unittest_Runner($suite);
try
{
$runner->run($group, $collect_cc);
if ($collect_cc)
{
$this->template->body->set('coverage', $runner->calculate_cc_percentage());
}
if (isset($whitelist))
{
$this->template->body->set('coverage_explanation', $this->nice_whitelist_explanation($whitelist));
}
}
catch(Kohana_Exception $e)
{
// Code coverage is not allowed, possibly xdebug disabled?
// TODO: Tell the user this?
$runner->run($group);
}
// Show some results
$this->template->body
->set('results', $runner->results)
->set('totals', $runner->totals)
->set('time', $this->nice_time($runner->time))
// Sets group to the currently selected group, or default all groups
->set('group', Arr::get($this->get_groups_list($suite), reset($group), 'All groups'))
->set('groups', $this->get_groups_list($suite))
->set('run_uri', $this->request->uri())
->set('report_uri', $this->report_uri.url::query())
// Whitelist related stuff
->set('whitelistable_items', $this->get_whitelistable_items())
->set('whitelisted_items', isset($whitelist) ? array_keys($whitelist) : array())
->set('whitelist', ! empty($whitelist));
}
/**
* Get the list of groups from the test suite, sorted with 'All groups' prefixed
*
* @return array Array of groups in the test suite
*/
protected function get_groups_list($suite)
{
// Make groups aray suitable for drop down
$groups = $suite->getGroups();
if (count($groups) > 0)
{
sort($groups);
$groups = array_combine($groups, $groups);
}
return array('' => 'All Groups') + $groups;
}
/**
* Gets a list of items that are whitelistable
*
* @return array
*/
protected function get_whitelistable_items()
{
static $whitelist;
if (count($whitelist))
return $whitelist;
$whitelist = array();
$whitelist['k_app'] = 'Application';
$k_modules = array_keys(Kohana::modules());
$whitelist += array_map('ucfirst', array_combine($k_modules, $k_modules));
$whitelist['k_sys'] = 'Kohana Core';
return $whitelist;
}
/**
* Whitelists a specified set of modules specified by the user
*
* @param array $modules
*/
protected function whitelist(array $modules)
{
$k_modules = Kohana::modules();
$whitelist = array();
// Make sure our whitelist is valid
foreach ($modules as $item)
{
if (isset($k_modules[$item]))
{
$whitelist[$item] = $k_modules[$item];
}
elseif ($item === 'k_app')
{
$whitelist[$item] = APPPATH;
}
elseif ($item === 'k_sys')
{
$whitelist[$item] = SYSPATH;
}
}
if (count($whitelist))
{
Unittest_tests::whitelist($whitelist);
}
return $whitelist;
}
/**
* Prettifies the list of whitelisted modules
*
* @param array Array of whitelisted items
* @return string
*/
protected function nice_whitelist_explanation(array $whitelist)
{
$items = array_intersect_key($this->get_whitelistable_items(), $whitelist);
return implode(', ', $items);
}
protected function nice_time($time)
{
$parts = array();
if ($time > DATE::DAY)
{
$parts[] = floor($time/DATE::DAY).'d';
$time = $time % DATE::DAY;
}
if ($time > DATE::HOUR)
{
$parts[] = floor($time/DATE::HOUR).'h';
$time = $time % DATE::HOUR;
}
if ($time > DATE::MINUTE)
{
$parts[] = floor($time/DATE::MINUTE).'m';
$time = $time % DATE::MINUTE;
}
if ($time > 0)
{
$parts[] = round($time, 1).'s';
}
return implode(' ', $parts);
}
} // End Controller_PHPUnit

View File

@@ -1,313 +0,0 @@
<?php
/**
* PHPUnit test runner for kohana
*
* @package Kohana/UnitTest
* @author Kohana Team
* @author BRMatt <matthew@sigswitch.com>
* @author Paul Banks
* @copyright (c) 2008-2009 Kohana Team
* @license http://kohanaphp.com/license
*/
class Kohana_Unittest_Runner implements PHPUnit_Framework_TestListener {
/**
* Results
* @var array
*/
protected $results = array(
'errors' => array(),
'failures' => array(),
'skipped' => array(),
'incomplete' => array(),
);
/**
* Test result totals
* @var array
*/
protected $totals = array(
'tests' => 0,
'passed' => 0,
'errors' => 0,
'failures' => 0,
'skipped' => 0,
'incomplete' => 0,
'assertions' => 0,
);
/**
* Info about the current test running
* @var array
*/
protected $current = array();
/**
* Time for tests to run (seconds)
* @var float
*/
protected $time = 0;
/**
* Result collector
* @var PHPUnit_Framework_TestResult
*/
protected $result = NULL;
/**
* the test suite to run
* @var PHPUnit_Framework_TestSuite
*/
protected $suite = NULL;
/**
* Constructor
*
* @param PHPUnit_Framework_TestSuite $suite The suite to test
* @param PHPUnit_Framework_TestResult $result Optional result object to use
*/
function __construct(PHPUnit_Framework_TestSuite $suite, PHPUnit_Framework_TestResult $result = NULL)
{
if ($result === NULL)
{
$result = new PHPUnit_Framework_TestResult;
}
$result->addListener($this);
$this->suite = $suite;
$this->result = $result;
}
/**
* Magic getter to allow access to member variables
*
* @param string $var Variable to get
* @return mixed
*/
function __get($var)
{
return $this->$var;
}
/**
* Calcualtes stats for each file covered by the code testing
*
* Each member of the returned array is formatted like so:
*
* <code>
* array(
* 'coverage' => $coverage_percent_for_file,
* 'loc' => $lines_of_code,
* 'locExecutable' => $lines_of_executable_code,
* 'locExecuted' => $lines_of_code_executed
* );
* </code>
*
* @return array Statistics for code coverage of each file
*/
public function calculate_cc()
{
if ($this->result->getCollectCodeCoverageInformation())
{
$coverage = $this->result->getCodeCoverageInformation();
$coverage_summary = PHPUnit_Util_CodeCoverage::getSummary($coverage);
$stats = array();
foreach ($coverage_summary as $file => $_lines)
{
$stats[$file] = PHPUnit_Util_CodeCoverage::getStatistics($coverage_summary, $file);
}
return $stats;
}
return FALSE;
}
/**
* Calculates the percentage code coverage information
*
* @return boolean|float FALSE if cc is not enabled, float for coverage percent
*/
public function calculate_cc_percentage()
{
if ($stats = $this->calculate_cc())
{
$executable = 0;
$executed = 0;
foreach ($stats as $stat)
{
$executable += $stat['locExecutable'];
$executed += $stat['locExecuted'];
}
return ($executable > 0) ? ($executed * 100 / $executable) : 100;
}
return FALSE;
}
/**
* Generate a report using the specified $temp_path
*
* @param array $groups Groups to test
* @param string $temp_path Temporary path to use while generating report
*/
public function generate_report(array $groups, $temp_path, $create_sub_dir = TRUE)
{
if ( ! is_writable($temp_path))
throw new Kohana_Exception('Temp path :path does not exist or is not writable by the webserver', array(':path' => $temp_path));
$folder_path = $temp_path;
if ($create_sub_dir === TRUE)
{
// Icky, highly unlikely, but do it anyway
// Basically adds "(n)" to the end of the filename until there's a free file
$count = 0;
do
{
$folder_name = date('Y-m-d_H:i:s')
.(empty($groups) ? '' : ('['.implode(',', $groups).']'))
.(($count > 0) ? ('('.$count.')') : '');
++$count;
}
while (is_dir($folder_path.$folder_name));
$folder_path .= $folder_name;
mkdir($folder_path, 0777);
}
else
{
$folder_name = basename($folder_path);
}
$this->run($groups, TRUE);
require_once 'PHPUnit/Runner/Version.php';
require_once 'PHPUnit/Util/Report.php';
PHPUnit_Util_Report::render($this->result, $folder_path);
return array($folder_path, $folder_name);
}
/**
* Runs the test suite using the result specified in the constructor
*
* @param array $groups Optional array of groups to test
* @param bool $collect_cc Optional, Should code coverage be collected?
* @return Kohana_PHPUnit Instance of $this
*/
public function run(array $groups = array(), $collect_cc = FALSE)
{
if ($collect_cc AND ! extension_loaded('xdebug'))
throw new Kohana_Exception('Code coverage cannot be collected because the xdebug extension is not loaded');
$this->result->collectCodeCoverageInformation( (bool) $collect_cc);
// Run the tests.
$this->suite->run($this->result, FALSE, $groups);
return $this;
}
// @codingStandardsIgnoreStart
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
// @codingStandardsIgnoreEnd
{
$this->totals['errors']++;
$this->current['result'] = 'errors';
$this->current['message'] = $test->getStatusMessage();
}
// @codingStandardsIgnoreStart
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
// @codingStandardsIgnoreEnd
{
$this->totals['failures']++;
$this->current['result'] = 'failures';
$this->current['message'] = $test->getStatusMessage();
}
// @codingStandardsIgnoreStart
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
// @codingStandardsIgnoreEnd
{
$this->totals['incomplete']++;
$this->current['result'] = 'incomplete';
$this->current['message'] = $test->getStatusMessage();
}
// @codingStandardsIgnoreStart
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
// @codingStandardsIgnoreEnd
{
$this->totals['skipped']++;
$this->current['result'] = 'skipped';
$this->current['message'] = $test->getStatusMessage();
}
// @codingStandardsIgnoreStart
public function startTest(PHPUnit_Framework_Test $test)
// @codingStandardsIgnoreEnd
{
$this->current['name'] = $test->getName(FALSE);
$this->current['description'] = $test->toString();
$this->current['result'] = 'passed';
}
// @codingStandardsIgnoreStart
public function endTest(PHPUnit_Framework_Test $test, $time)
// @codingStandardsIgnoreEnd
{
// Add totals
$this->totals['tests']++;
$this->totals['assertions'] += $test->getNumAssertions();
// Handle passed tests
if ($this->current['result'] == 'passed')
{
// Add to total
$this->totals['passed']++;
}
else
{
// Add to results
$this->results[$this->current['result']][] = $this->current;
}
$this->current = array();
$this->time += $time;
}
// @codingStandardsIgnoreStart
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
// @codingStandardsIgnoreEnd
// @codingStandardsIgnoreStart
public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
// @codingStandardsIgnoreEnd
{
// Parse test descriptions to make them look nicer
foreach ($this->results as $case => $testresults)
{
foreach ($testresults as $type => $result)
{
preg_match('/^(?:([a-z0-9_]+?)::)?([a-z0-9_]+)(?: with data set (#\d+ \(.*?\)))?/i', $result['description'], $m);
$this->results[$case][$type] += array(
'class' => $m[1],
'test' => $m[2],
'data_set' => isset($m[3]) ? $m[3] : FALSE,
);
}
}
}
}

View File

@@ -1,3 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.');
class Unittest_Runner extends Kohana_Unittest_Runner {}

View File

@@ -1,3 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.');
class Unittest_TestCase extends Kohana_Unittest_TestCase {}

View File

@@ -2,26 +2,11 @@
return array(
// The only environment in which the web runner is allowed to run
// You can run tests from phpunit cli command regardless of this setting
// This can also be set to an array for multiple environments
'environment' => Kohana::DEVELOPMENT,
// This is the folder where we generate and zip all the reports for downloading
// Needs to be readable and writable
'temp_path' => Kohana::$cache_dir.'/unittest',
// Path from DOCROOT (i.e. http://yourdomain/) to the folder where HTML cc reports can be published.
// If you'd prefer not to allow users to do this then simply set the value to FALSE.
// Example value of 'cc_report_path' would allow devs to see report at http://yourdomain/report/
'cc_report_path' => 'report',
// If you don't use a whitelist then only files included during the request will be counted
// If you do, then only whitelisted items will be counted
'use_whitelist' => TRUE,
// Items to whitelist, only used in cli
// Web runner ui allows user to choose which items to whitelist
'whitelist' => array(
// Should the app be whitelisted?
@@ -46,8 +31,4 @@ return array(
// List of individual files/folders to blacklist
'blacklist' => array(
),
// A database connection that can be used when testing
// This doesn't overwrite anything, tests will have to use this value manually
'db_connection' => 'unittest',
);

View File

@@ -1,23 +1,13 @@
<?php defined('SYSPATH') or die('No direct script access.');
<?php defined('SYSPATH') OR die('No direct script access.');
return array(
// Leave this alone
return array
(
'modules' => array(
// This should be the path to this modules userguide pages, without the 'guide/'. Ex: '/guide/modulename/' would be 'modulename'
'unittest' => array(
// Whether this modules userguide pages should be shown
'enabled' => TRUE,
// The name that should show up on the userguide index page
'name' => 'Unittest',
// A short description of this module, shown on the index page
'description' => 'Kohana unit testing.',
// Copyright message, shown in the footer for this module
'copyright' => '&copy; 20082010 Kohana Team',
)
'description' => 'Unit testing module',
'copyright' => '&copy; 2009-2011 Kohana Team',
)
)
);

View File

@@ -1,2 +1,3 @@
# Unittest
# UnitTest
Unit tests for Kohana

View File

@@ -1,5 +1,5 @@
## [UnitTest]()
- [Testing](testing)
- [Mock Objects](mockobjects)
- [Troubleshooting](troubleshooting)
- [Testing workflows](testing_workflows)
- [Mock Objects](mockobjects)
- [Testing](testing)
- [Testing workflows](testing_workflows)
- [Troubleshooting](troubleshooting)

View File

@@ -1,12 +1,12 @@
### From the command line
# Usage
$ phpunit --bootstrap=index.php modules/unittest/tests.php
$ phpunit --bootstrap=modules/unittest/bootstrap.php modules/unittest/tests.php
Of course, you'll need to make sure the path to the tests.php file is correct. If you want you can copy it to a more accessible location
Alternatively you can use a phpunit.xml to have a more fine grained control over which tests are included and which files are whitelisted.
### From the web
Make sure you only whitelist the highest files in the cascading filesystem, else you could end up with a lot of "class cannot be redefined" errors.
Just navigate to http://example.com/unittest. You may need to use http://example.com/index.php/unittest if you have not enabled url rewriting in your .htaccess.
If you use the tests.php testsuite loader then it will only whitelist the highest files. see config/unittest.php for details on configuring the tests.php whitelist.
## Writing tests
@@ -103,13 +103,13 @@ This functionality can be used to record which bug reports a test is for:
To see all groups that are available in your code run:
$ phpunit --boostrap=index.php --list-groups modules/unittest/tests.php
$ phpunit --boostrap=modules/unittest/bootstrap.php --list-groups modules/unittest/tests.php
*Note:* the `--list-groups` switch should appear before the path to the test suite loader
You can also exclude groups while testing using the `--exclude-group` switch. This can be useful if you want to ignore all kohana tests:
$ phpunit --bootstrap=index.php --exclude-group=kohana modules/unittest/tests.php
$ phpunit --bootstrap=modules/unittest/bootstrap.php --exclude-group=kohana modules/unittest/tests.php
For more info see:

View File

@@ -2,16 +2,6 @@
Having unittests for your application is a nice idea, but unless you actually use them they're about as useful as a chocolate firegaurd. There are quite a few ways of getting tests "into" your development process and this guide aims to cover a few of them.
## Testing through the webui
The web ui is a fairly temporary solution, aimed at helping developers get into unittesting and code coverage. Eventually it's hoped that people migrate on to the termainl & CI servers.
To access it goto
http://example.com/unittest/
*Note:* Your site will need to be in the correct environment in order to use the webui. See the config file for more details. You may also need to use http://example.com/index.php/unittest/
## Integrating with IDEs
Modern IDEs have come a long way in the last couple of years and ones like netbeans have pretty decent PHP / PHPUnit support.

View File

@@ -1,16 +0,0 @@
<?php
// If we're on the CLI then PHPUnit will already be loaded
if (class_exists('PHPUnit_Util_Filter', FALSE) OR function_exists('phpunit_autoload'))
{
Unittest_Tests::configure_environment();
// Stop kohana from processing the request
define('SUPPRESS_REQUEST', TRUE);
}
Route::set('unittest', 'unittest(/<action>)')
->defaults(array(
'controller' => 'unittest',
'action' => 'index',
));

View File

@@ -5,16 +5,16 @@ if ( ! class_exists('Kohana'))
die('Please include the kohana bootstrap file (see README.markdown)');
}
if ($file = Kohana::find_file('classes', 'unittest/tests'))
if ($file = Kohana::find_file('classes', 'Unittest/Tests'))
{
require_once $file;
// PHPUnit requires a test suite class to be in this file,
// so we create a faux one that uses the kohana base
Class TestSuite extends Unittest_Tests
class TestSuite extends Unittest_Tests
{}
}
else
{
die('Could not include the test suite');
}
}

View File

@@ -1,66 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.') ?>
<div id="select">
<h1>PHPUnit for Kohana 3</h1>
<div id="groups">
<fieldset class="tests">
<legend>Run Tests</legend>
<?php echo Form::open($run_uri, array('method' => 'GET'));?>
<?php echo Form::label('run_group', __('Run a test group')) ?>
<?php echo Form::select('group', $groups, NULL, array('id' => 'run_group'));?>
<?php if ($xdebug_enabled): ?>
<?php echo Form::label('run_collect_cc', __('Calculate code coverage')) ?>
<?php echo Form::checkbox('collect_cc', 1, TRUE, array('id' => 'run_collect_cc')) ?>
<div depends_on="#run_collect_cc">
<?php echo Form::label('run_use_whitelist', __('Use code coverage whitelist'));?>
<?php echo Form::checkbox('use_whitelist', 1, TRUE, array('id' => 'run_use_whitelist')) ?>
<div depends_on="#run_use_whitelist">
<?php echo Form::label('run_whitelist', __('Only calculate coverage for files in selected modules')) ?>
<?php echo Form::select('whitelist[]', $whitelistable_items, array(), array('id' => 'run_whitelist', 'multiple' => 'multiple')) ?>
</div>
</div>
<?php endif ?>
<?php echo Form::submit('submit', 'Run');?>
<?php echo Form::close();?>
</fieldset>
<fieldset class="reports">
<legend>Code Coverage Reports</legend>
<?php if ( ! $xdebug_enabled): ?>
<p><?php echo __('Xdebug needs to be installed to generate reports') ?></p>
<?php else: ?>
<?php echo Form::open($report_uri, array('method' => 'GET')) ?>
<?php echo Form::label('cc_group', __('Generate report for')) ?>
<?php echo Form::select('group', $groups, NULL, array('id' => 'cc_group'));?>
<?php echo Form::label('report_archive', __('Download as archive?'));?>
<?php echo Form::checkbox('archive', 1, FALSE, array('id' => 'report_archive')) ?>
<?php echo Form::label('report_use_whitelist', __('Use code coverage whitelist'));?>
<?php echo Form::checkbox('use_whitelist', 1, TRUE, array('id' => 'report_use_whitelist')) ?>
<div depends_on="#report_use_whitelist">
<?php echo Form::label('run_whitelist', __('Only calculate coverage for files in selected modules')) ?>
<?php echo Form::select('whitelist[]', $whitelistable_items, array(), array('id' => 'run_whitelist', 'multiple' => 'multiple')) ?>
</div>
<?php echo Form::submit('submit', 'Run');?>
<?php echo Form::close();?>
<?php endif ?>
</fieldset>
</div>
<h2>Useful links</h2>
<ul>
<li><a href="http://www.phpunit.de/manual/current/en/">PHPUnit Manual</a></li>
<li><a href="http://github.com/kohana/unittest">Module README</a></li>
</ul>
</div>

View File

@@ -1,255 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>PHPUnit for Kohana</title>
<style type="text/css">
#select {
font-family: sans-serif;
border: 2px solid black;
padding: 20px;
margin: 40px 80px;
}
#select #groups {
overflow: auto;
margin-bottom: 25px;
}
#header {
background-color: #263038;
color: #fff;
padding: 20px;
font-family: sans-serif;
overflow: auto;
}
#header span {
display: block;
color: #83919C;
margin: 5px 0 0 0;
}
#header span b {
color: #ddd;
}
#header span.code_coverage .excellent {
color: #13CC1C;
}
#header span.code_coverage .ok {
color: #448BFD;
}
#header span.code_coverage .terrible {
color: #FF0A0A;
}
#header fieldset form label {
display: block;
}
#header a {
color: #4e7aa0;
}
li {
margin-bottom: 5px;
}
fieldset {
color: #000;
background: #E5EFF8;
border: 4px solid #4D6171;
padding: 20px 20px 0px;
font-size: 1.2em;
width: 43%;
display: block;
-moz-border-radius: 2px;
}
fieldset legend {
padding: 5px;
-moz-border-radius: 2px;
color: #FEFEFE;
background: #4D6171;
}
form {
display: inline;
}
fieldset form {
display: block;
}
fieldset#results-options {
width: 38%;
float:right;
}
fieldset form label {
display: block;
}
fieldset select {
width: 45%;
}
fieldset#results-options form label {
clear: left;
float: left;
width: 43%;
}
fieldset#results-options form input {
display: block;
float:left;
}
fieldset#results-options form input[type="submit"] {
float: none;
clear: both;
}
fieldset#results-options form select {
float: left;
}
fieldset.tests {
float: left;
}
fieldset.tests legend {
background: #4D6171;
}
fieldset.reports {
float: right;
background: #FC817B;
border-color: #D02820;
}
fieldset.reports legend {
background: #D02820;
}
fieldset form input[type="submit"] {
margin-top: 15px;
display: block;
}
#results {
font-family: sans-serif;
}
#results > div {
margin-top: 10px;
padding: 20px;
}
#results > div ol li{
font-size: 1.1em;
margin-bottom: 15px;
font-weight: bold;
}
h1, h2 {
margin: 0 0 15px;
}
div.failures-list {
background-color: #ffcccc;
}
div.errors-list {
background-color: #ffc;
}
span.test-case {
color: #83919C;
}
span.test-name {
color: #222;
}
span.test-data-set {
display: block;
color: #666;
font-weight: normal;
}
span.test-message {
display: block;
color: #444;
}
div.big-message {
font-size: 2em;
text-align: center;
}
div.all-pass {
background-color: #E0FFE0;
border: 3px solid #b0FFb0;
}
div.no-tests {
background-color: #FFFFE0;
border: 3px solid #FFFFb0;
}
span.show {
font-size: 0.7em;
font-weight: normal;
color:#4D6171;
}
.hidden {
display: none;
}
span[title]{
border-bottom: 1px dashed #83919C;
}
</style>
</head>
<body>
<?php echo $body ?>
<?php echo HTML::script('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js') ?>
<script type="text/javascript">
$(document).ready(function(){
// Using our own attribute is a little messy but gets the job done
// this isn't very important code anyway...
$('[depends_on]').each(function(){
var dependent = $(this);
var controller = $(dependent.attr('depends_on'));
// We do this in the loop so that it can access dependent
// Javascript scopes are slightly crazy
var toggler = function(){
if ($(this).attr('checked')){
dependent.show();
} else {
dependent.hide();
}
}
// Register the toggler
controller.change(toggler);
// And degrade nicely...
if ( ! controller.attr('checked')){
dependent.hide();
}
});
});
document.write('<style type="text/css"> .collapsed { display: none; } </style>');
function toggle(type)
{
var elem = document.getElementById(type+'-ol');
var plus = document.getElementById(type+'-show');
if (elem.style && elem.style['display'])
// Only works with the "style" attr
var disp = elem.style['display'];
else if (elem.currentStyle)
// For MSIE, naturally
var disp = elem.currentStyle['display'];
else if (window.getComputedStyle)
// For most other browsers
var disp = document.defaultView.getComputedStyle(elem, null).getPropertyValue('display');
// Toggle the state of the "display" style
elem.style.display = disp == 'block' ? 'none' : 'block';
plus.innerHTML = disp == 'block' ? '[<?php echo __('show') ?>]' : '[<?php echo __('hide') ?>]';
return false;
}
</script>
</body>
</html>

View File

@@ -1,83 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.') ?>
<div id="header" class="results">
<fieldset id="results-options">
<legend>Options</legend>
<?php echo Form::open($run_uri, array('method' => 'get'));?>
<?php echo Form::label('group', __('Switch Group')) ?>
<?php echo Form::select('group', $groups, $group, array('id' => 'group'));?>
<?php if ($xdebug_enabled): ?>
<?php echo Form::label('collect_cc', __('Collect Coverage')) ?>
<?php echo Form::checkbox('collect_cc', 1, isset($coverage), array('id' => 'collect_cc')) ?>
<div depends_on="#collect_cc">
<?php echo Form::label('use_whitelist', __('Use whitelist'));?>
<?php echo Form::checkbox('use_whitelist', 1, $whitelist, array('id' => 'use_whitelist')) ?>
<div depends_on="#use_whitelist">
<?php echo Form::label('whitelist', __('Whitelisted modules')) ?>
<?php echo Form::select('whitelist[]', $whitelistable_items, $whitelisted_items, array('id' => 'whitelist', 'multiple' => 'multiple')) ?>
</div>
</div>
<?php endif ?>
<?php echo Form::submit('run', 'Run');?>
<?php echo Form::close();?>
</fieldset>
<h1><?php echo is_null($group) ? __('All Groups') : (__('Group').': ') ?> <?php echo $group ?></h1>
<span class="time"><?php echo __('Time') ?>: <b><?php echo $time?></b></span>
<span class="summary">
<?php echo __('Tests') ?> <b><?php echo $totals['tests']?></b>,
<?php echo __('Assertions') ?> <b><?php echo $totals['assertions']?></b>,
<?php echo __('Failures') ?> <b><?php echo $totals['failures']?></b>,
<?php echo __('Skipped') ?> <b><?php echo $totals['skipped']?></b>,
<?php echo __('Errors') ?> <b><?php echo $totals['errors']?></b>.
</span>
<?php if ($xdebug_enabled AND isset($coverage)): ?>
<span class="code_coverage">
<?php $level_class = ($coverage > 75) ? 'excellent' : (($coverage > 35) ? 'ok' : 'terrible') ?>
<?php
echo __('Tests covered :percent of the :codebase',
array
(
':percent' => '<b class="'.$level_class.'">'.num::format($coverage, 2).'%</b>',
':codebase' => empty($coverage_explanation) ? 'codebase' : ('<span title="'.$coverage_explanation.'" style="display:inline;">modules</span>'),
)
);
?>,
<?php echo HTML::anchor($report_uri, 'View') ?>
or
<?php echo HTML::anchor($report_uri.'&archive=1', 'Download') ?>
the report
</span>
<?php endif ?>
</div>
<div id="results">
<?php if ($totals['tests'] == 0): ?>
<div class="big-message no-tests">No tests in group</div>
<?php elseif ($totals['tests'] === $totals['passed']): ?>
<div class="big-message all-pass"><?php echo $totals['tests']?> Tests Passed</div>
<?php else: ?>
<?php foreach ($results as $type => $tests):?>
<?php if (count($tests) < 1):
continue;
endif ?>
<?php $hide = ($type === 'skipped' OR $type === 'incomplete') ?>
<div class="<?php echo $type?>-list">
<h2 onclick="toggle('<?php echo $type?>');"><?php echo count($tests)?>
<?php echo __(ucfirst(Inflector::singular($type, count($tests))))?>
<span id="<?php echo $type?>-show" class="show">[<?php echo $hide ? __('show') : __('hide') ?>]</span></h2>
<ol id="<?php echo $type?>-ol" class="<?php echo $hide ? 'hidden' : '' ?>">
<?php foreach ($tests as $result): ?>
<li>
<span class="test-case"><?php echo $result['class']?>::</span><span class="test-name"><?php echo $result['test']?></span>
<?php if ($result['data_set']) : ?>
<span class="test-data-set"> <?php echo __('with data set')?> <span><?php echo $result['data_set']?></span></span>
<?php endif ?>
<span class="test-message"><?php echo htmlentities($result['message'])?></span>
</li>
<?php endforeach ?>
</ol>
</div>
<?php endforeach;?>
<?php endif ?>
</div>