Added Kohana v3.0.8
This commit is contained in:
359
includes/kohana/modules/unittest/classes/controller/unittest.php
Normal file
359
includes/kohana/modules/unittest/classes/controller/unittest.php
Normal file
@@ -0,0 +1,359 @@
|
||||
<?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 Kohana_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 ( ! Kohana_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
|
||||
Kohana_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(Kohana_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 = Kohana_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::base(FALSE, TRUE).$folder.'index.html');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = Kohana_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('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))
|
||||
{
|
||||
Kohana_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
|
Reference in New Issue
Block a user