Merge commit 'lorenzo/2.0-phpunit' into 2.0-phpunit

Conflicts:
	cake/tests/lib/reporter/cake_html_reporter.php
	cake/tests/lib/test_manager.php
This commit is contained in:
José Lorenzo Rodríguez 2010-05-12 23:58:56 -04:30
commit 8c3df122eb
19 changed files with 1139 additions and 1059 deletions

View file

@ -91,8 +91,9 @@ class PaginatorHelper extends AppHelper {
$ajaxProvider = isset($config['ajax']) ? $config['ajax'] : 'Js'; $ajaxProvider = isset($config['ajax']) ? $config['ajax'] : 'Js';
$this->helpers[] = $ajaxProvider; $this->helpers[] = $ajaxProvider;
$this->_ajaxHelperClass = $ajaxProvider; $this->_ajaxHelperClass = $ajaxProvider;
if (!class_exists($ajaxProvider . 'Helper')) {
App::import('Helper', $ajaxProvider); App::import('Helper', $ajaxProvider);
}
$classname = $ajaxProvider . 'Helper'; $classname = $ajaxProvider . 'Helper';
if (!method_exists($classname, 'link')) { if (!method_exists($classname, 'link')) {
throw new Exception(sprintf( throw new Exception(sprintf(

View file

@ -69,20 +69,20 @@ class CakeLogTest extends CakeTestCase {
/** /**
* test all the errors from failed logger imports * test all the errors from failed logger imports
* *
* @expectedException Exception
* @return void * @return void
*/ */
function testImportingLoggerFailure() { function testImportingLoggerFailure() {
$this->expectException();
CakeLog::config('fail', array()); CakeLog::config('fail', array());
} }
/** /**
* test that loggers have to implement the correct interface. * test that loggers have to implement the correct interface.
* *
* @expectedException Exception
* @return void * @return void
*/ */
function testNotImplementingInterface() { function testNotImplementingInterface() {
$this->expectException();
CakeLog::config('fail', array('engine' => 'stdClass')); CakeLog::config('fail', array('engine' => 'stdClass'));
} }

View file

@ -4,7 +4,7 @@
* *
* Test Case for CakeTestCase class * Test Case for CakeTestCase class
* *
* PHP versions 4 and 5 * PHP version 5
* *
* CakePHP : Rapid Development Framework (http://cakephp.org) * CakePHP : Rapid Development Framework (http://cakephp.org)
* Copyright 2006-2010, Cake Software Foundation, Inc. * Copyright 2006-2010, Cake Software Foundation, Inc.
@ -19,7 +19,6 @@
* @since CakePHP v 1.2.0.4487 * @since CakePHP v 1.2.0.4487
* @license MIT License (http://www.opensource.org/licenses/mit-license.php) * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/ */
App::import('Core', 'CakeTestCase');
if (!class_exists('AppController')) { if (!class_exists('AppController')) {
require_once LIBS . 'controller' . DS . 'app_controller.php'; require_once LIBS . 'controller' . DS . 'app_controller.php';
@ -27,41 +26,6 @@ if (!class_exists('AppController')) {
define('APP_CONTROLLER_EXISTS', true); define('APP_CONTROLLER_EXISTS', true);
} }
Mock::generate('CakeHtmlReporter');
Mock::generate('CakeTestCase', 'CakeDispatcherMockTestCase');
SimpleTest::ignore('SubjectCakeTestCase');
SimpleTest::ignore('CakeDispatcherMockTestCase');
/**
* SubjectCakeTestCase
*
* @package cake
* @subpackage cake.tests.cases.libs
*/
class SubjectCakeTestCase extends CakeTestCase {
/**
* Feed a Mocked Reporter to the subject case
* prevents its pass/fails from affecting the real test
*
* @param string $reporter
* @access public
* @return void
*/
function setReporter(&$reporter) {
$this->_reporter = &$reporter;
}
/**
* testDummy method
*
* @return void
*/
public function testDummy() {
}
}
/** /**
* CakeTestCaseTest * CakeTestCaseTest
* *
@ -70,6 +34,11 @@ class SubjectCakeTestCase extends CakeTestCase {
*/ */
class CakeTestCaseTest extends CakeTestCase { class CakeTestCaseTest extends CakeTestCase {
public static function setUpBeforeClass() {
require_once TEST_CAKE_CORE_INCLUDE_PATH . DS . 'tests' . DS . 'fixtures' . DS . 'assert_tags_test_case.php';
require_once TEST_CAKE_CORE_INCLUDE_PATH . DS . 'tests' . DS . 'fixtures' . DS . 'fixturized_test_case.php';
}
/** /**
* setUp * setUp
* *
@ -78,10 +47,7 @@ class CakeTestCaseTest extends CakeTestCase {
*/ */
function setUp() { function setUp() {
$this->_debug = Configure::read('debug'); $this->_debug = Configure::read('debug');
$this->Case =& new SubjectCakeTestCase(); $this->Reporter = $this->getMock('CakeHtmlReporter');
$reporter =& new MockCakeHtmlReporter();
$this->Case->setReporter($reporter);
$this->Reporter = $reporter;
} }
/** /**
@ -93,104 +59,22 @@ class CakeTestCaseTest extends CakeTestCase {
function tearDown() { function tearDown() {
Configure::write('debug', $this->_debug); Configure::write('debug', $this->_debug);
unset($this->Case); unset($this->Case);
unset($this->Result);
unset($this->Reporter); unset($this->Reporter);
} }
/**
* endTest
*
* @access public
* @return void
*/
function endTest() {
App::build();
}
/** /**
* testAssertGoodTags * testAssertGoodTags
* *
* @access public * @access public
* @return void * @return void
*/
function testAssertGoodTags() {
$this->Reporter->expectAtLeastOnce('paintPass');
$this->Reporter->expectNever('paintFail');
$input = '<p>Text</p>';
$pattern = array(
'<p',
'Text',
'/p',
);
$this->assertTrue($this->Case->assertTags($input, $pattern));
$input = '<a href="/test.html" class="active">My link</a>';
$pattern = array(
'a' => array('href' => '/test.html', 'class' => 'active'),
'My link',
'/a'
);
$this->assertTrue($this->Case->assertTags($input, $pattern));
$pattern = array(
'a' => array('class' => 'active', 'href' => '/test.html'),
'My link',
'/a'
);
$this->assertTrue($this->Case->assertTags($input, $pattern), 'Attributes in wrong order. %s');
$input = "<a href=\"/test.html\"\t\n\tclass=\"active\"\tid=\"primary\">\t<span>My link</span></a>";
$pattern = array(
'a' => array('id' => 'primary', 'href' => '/test.html', 'class' => 'active'),
'<span',
'My link',
'/span',
'/a'
);
$this->assertTrue($this->Case->assertTags($input, $pattern), 'Whitespace consumption %s');
$input = '<p class="info"><a href="/test.html" class="active"><strong onClick="alert(\'hey\');">My link</strong></a></p>';
$pattern = array(
'p' => array('class' => 'info'),
'a' => array('class' => 'active', 'href' => '/test.html' ),
'strong' => array('onClick' => 'alert(\'hey\');'),
'My link',
'/strong',
'/a',
'/p'
);
$this->assertTrue($this->Case->assertTags($input, $pattern));
}
/**
* test that assertTags knows how to handle correct quoting.
*
* @return void
*/ */
function testAssertTagsQuotes() { function testAssertTagsQuotes() {
$input = '<a href="/test.html" class="active">My link</a>'; $test = new AssertTagsTestCase('testAssertTagsQuotes');
$pattern = array( $result = $test->run();
'a' => array('href' => '/test.html', 'class' => 'active'), $this->assertEquals(0, $result->errorCount());
'My link', $this->assertTrue($result->wasSuccessful());
'/a' $this->assertEquals(0, $result->failureCount());
);
$this->assertTrue($this->Case->assertTags($input, $pattern), 'Double quoted attributes %s');
$input = "<a href='/test.html' class='active'>My link</a>";
$pattern = array(
'a' => array('href' => '/test.html', 'class' => 'active'),
'My link',
'/a'
);
$this->assertTrue($this->Case->assertTags($input, $pattern), 'Single quoted attributes %s');
$input = "<a href='/test.html' class='active'>My link</a>";
$pattern = array(
'a' => array('href' => 'preg:/.*\.html/', 'class' => 'active'),
'My link',
'/a'
);
$this->assertTrue($this->Case->assertTags($input, $pattern), 'Single quoted attributes %s');
} }
/** /**
@ -200,109 +84,31 @@ class CakeTestCaseTest extends CakeTestCase {
* @return void * @return void
*/ */
function testNumericValuesInExpectationForAssertTags() { function testNumericValuesInExpectationForAssertTags() {
$value = 220985; $test = new AssertTagsTestCase('testNumericValuesInExpectationForAssertTags');
$result = $test->run();
$input = '<p><strong>' . $value . '</strong></p>'; $this->assertEquals(0, $result->errorCount());
$pattern = array( $this->assertTrue($result->wasSuccessful());
'<p', $this->assertEquals(0, $result->failureCount());
'<strong',
$value,
'/strong',
'/p'
);
$this->assertTrue($this->Case->assertTags($input, $pattern));
$input = '<p><strong>' . $value . '</strong></p><p><strong>' . $value . '</strong></p>';
$pattern = array(
'<p',
'<strong',
$value,
'/strong',
'/p',
'<p',
'<strong',
$value,
'/strong',
'/p',
);
$this->assertTrue($this->Case->assertTags($input, $pattern));
$input = '<p><strong>' . $value . '</strong></p><p id="' . $value . '"><strong>' . $value . '</strong></p>';
$pattern = array(
'<p',
'<strong',
$value,
'/strong',
'/p',
'p' => array('id' => $value),
'<strong',
$value,
'/strong',
'/p',
);
$this->assertTrue($this->Case->assertTags($input, $pattern));
} }
/** /**
* testBadAssertTags * testBadAssertTags
* *
* @access public * @access public
* @return void * @return void
*/ */
function testBadAssertTags() { function testBadAssertTags() {
$this->Reporter->expectAtLeastOnce('paintFail'); $test = new AssertTagsTestCase('testBadAssertTags');
$this->Reporter->expectNever('paintPass'); $result = $test->run();
$this->assertEquals(0, $result->errorCount());
$this->assertFalse($result->wasSuccessful());
$this->assertEquals(1, $result->failureCount());
$input = '<a href="/test.html" class="active">My link</a>'; $test = new AssertTagsTestCase('testBadAssertTags2');
$pattern = array( $result = $test->run();
'a' => array('hRef' => '/test.html', 'clAss' => 'active'), $this->assertEquals(0, $result->errorCount());
'My link', $this->assertFalse($result->wasSuccessful());
'/a' $this->assertEquals(1, $result->failureCount());
);
$this->assertFalse($this->Case->assertTags($input, $pattern));
$input = '<a href="/test.html" class="active">My link</a>';
$pattern = array(
'<a' => array('href' => '/test.html', 'class' => 'active'),
'My link',
'/a'
);
$this->assertFalse($this->Case->assertTags($input, $pattern));
}
/**
* testBefore
*
* @access public
* @return void
*/
function testBefore() {
$this->Case->before('testDummy');
$this->assertFalse(isset($this->Case->db));
$this->Case->fixtures = array('core.post');
$this->Case->before('start');
$this->assertTrue(isset($this->Case->db));
$this->assertTrue(isset($this->Case->_fixtures['core.post']));
$this->assertTrue(is_a($this->Case->_fixtures['core.post'], 'CakeTestFixture'));
$this->assertEqual($this->Case->_fixtureClassMap['Post'], 'core.post');
}
/**
* testAfter
*
* @access public
* @return void
*/
function testAfter() {
$this->Case->after('testDummy');
$this->assertFalse($this->Case->getTruncated());
$this->Case->fixtures = array('core.post');
$this->Case->before('start');
$this->Case->start();
$this->Case->after('testDummy');
$this->assertTrue($this->Case->getTruncated());
} }
/** /**
@ -312,154 +118,33 @@ class CakeTestCaseTest extends CakeTestCase {
* @return void * @return void
*/ */
function testLoadFixtures() { function testLoadFixtures() {
$this->Case->fixtures = array('core.post'); $test = new FixturizedTestCase('testFixturePresent');
$this->Case->autoFixtures = false; $manager = $this->getMock('CakeFixtureManager');
$this->Case->before('start'); $manager->fixturize($test);
$this->expectError(); $test->sharedFixture = $manager;
$this->Case->loadFixtures('Wrong!'); $manager->expects($this->once())->method('load');
$this->Case->end(); $manager->expects($this->once())->method('unload');
$result = $test->run();
$this->assertEquals(0, $result->errorCount());
$this->assertTrue($result->wasSuccessful());
$this->assertEquals(0, $result->failureCount());
} }
/** /**
* testGetTests Method * testLoadFixturesOnDemand
*
* @return void
*/
public function testGetTests() {
$result = $this->Case->getTests();
$this->assertEqual(array_slice($result, 0, 2), array('start', 'startCase'));
$this->assertEqual(array_slice($result, -2), array('endCase', 'end'));
}
/**
* TestTestAction
* *
* @access public * @access public
* @return void * @return void
*/ */
function testTestAction() { function testLoadFixturesOnDemand() {
App::build(array( $test = new FixturizedTestCase('testFixtureLoadOnDemand');
'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS), $test->autoFixtures = false;
'models' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'models' . DS), $manager = $this->getMock('CakeFixtureManager');
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS), $manager->fixturize($test);
'controllers' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'controllers' . DS) $test->sharedFixture = $manager;
), true); $manager->expects($this->once())->method('loadSingle');
$result = $test->run();
$result = $this->Case->testAction('/tests_apps/index', array('return' => 'view')); $this->assertEquals(0, $result->errorCount());
$this->assertPattern('/This is the TestsAppsController index view/', $result);
$result = $this->Case->testAction('/tests_apps/index', array('return' => 'contents'));
$this->assertPattern('/This is the TestsAppsController index view/', $result);
$this->assertPattern('/<html/', $result);
$this->assertPattern('/<\/html>/', $result);
$result = $this->Case->testAction('/tests_apps/some_method', array('return' => 'result'));
$this->assertEqual($result, 5);
$result = $this->Case->testAction('/tests_apps/set_action', array('return' => 'vars'));
$this->assertEqual($result, array('var' => 'string'));
$db =& ConnectionManager::getDataSource('test_suite');
$fixture =& new PostFixture();
$fixture->create($db);
$result = $this->Case->testAction('/tests_apps_posts/add', array('return' => 'vars'));
$this->assertTrue(array_key_exists('posts', $result));
$this->assertEqual(count($result['posts']), 1);
$result = $this->Case->testAction('/tests_apps_posts/url_var/var1:value1/var2:val2', array(
'return' => 'vars',
'method' => 'get',
));
$this->assertTrue(isset($result['params']['url']['url']));
$this->assertEqual(array_keys($result['params']['named']), array('var1', 'var2'));
$result = $this->Case->testAction('/tests_apps_posts/url_var/gogo/val2', array(
'return' => 'vars',
'method' => 'get',
));
$this->assertEqual($result['params']['pass'], array('gogo', 'val2'));
$result = $this->Case->testAction('/tests_apps_posts/url_var', array(
'return' => 'vars',
'method' => 'get',
'data' => array(
'red' => 'health',
'blue' => 'mana'
)
));
$this->assertTrue(isset($result['params']['url']['red']));
$this->assertTrue(isset($result['params']['url']['blue']));
$this->assertTrue(isset($result['params']['url']['url']));
$result = $this->Case->testAction('/tests_apps_posts/post_var', array(
'return' => 'vars',
'method' => 'post',
'data' => array(
'name' => 'is jonas',
'pork' => 'and beans',
)
));
$this->assertEqual(array_keys($result['data']), array('name', 'pork'));
$fixture->drop($db);
$db =& ConnectionManager::getDataSource('test_suite');
$_backPrefix = $db->config['prefix'];
$db->config['prefix'] = 'cake_testaction_test_suite_';
$config = $db->config;
$config['prefix'] = 'cake_testcase_test_';
ConnectionManager::create('cake_test_case', $config);
$db2 =& ConnectionManager::getDataSource('cake_test_case');
$fixture =& new PostFixture($db2);
$fixture->create($db2);
$fixture->insert($db2);
$result = $this->Case->testAction('/tests_apps_posts/fixtured', array(
'return' => 'vars',
'fixturize' => true,
'connection' => 'cake_test_case',
));
$this->assertTrue(isset($result['posts']));
$this->assertEqual(count($result['posts']), 3);
$tables = $db2->listSources();
$this->assertFalse(in_array('cake_testaction_test_suite_posts', $tables));
$fixture->drop($db2);
$db =& ConnectionManager::getDataSource('test_suite');
//test that drop tables behaves as exepected with testAction
$db =& ConnectionManager::getDataSource('test_suite');
$_backPrefix = $db->config['prefix'];
$db->config['prefix'] = 'cake_testaction_test_suite_';
$config = $db->config;
$config['prefix'] = 'cake_testcase_test_';
ConnectionManager::create('cake_test_case', $config);
$db =& ConnectionManager::getDataSource('cake_test_case');
$fixture =& new PostFixture($db);
$fixture->create($db);
$fixture->insert($db);
$this->Case->dropTables = false;
$result = $this->Case->testAction('/tests_apps_posts/fixtured', array(
'return' => 'vars',
'fixturize' => true,
'connection' => 'cake_test_case',
));
$tables = $db->listSources();
$this->assertTrue(in_array('cake_testaction_test_suite_posts', $tables));
$fixture->drop($db);
$db =& ConnectionManager::getDataSource('test_suite');
$db->config['prefix'] = $_backPrefix;
$fixture->drop($db);
} }
/** /**
@ -468,33 +153,12 @@ class CakeTestCaseTest extends CakeTestCase {
* @return void * @return void
*/ */
function testSkipIf() { function testSkipIf() {
$this->assertTrue($this->Case->skipIf(true)); $test = new FixturizedTestCase('testSkipIfTrue');
$this->assertFalse($this->Case->skipIf(false)); $result = $test->run();
} $this->assertEquals(1, $result->skippedCount());
/** $test = new FixturizedTestCase('testSkipIfFalse');
* testTestDispatcher $result = $test->run();
* $this->assertEquals(0, $result->skippedCount());
* @access public
* @return void
*/
function testTestDispatcher() {
App::build(array(
'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS),
'models' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'models' . DS),
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS),
'controllers' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'controllers' . DS)
), true);
$Dispatcher =& new CakeTestDispatcher();
$Case =& new CakeDispatcherMockTestCase();
$Case->expectOnce('startController');
$Case->expectOnce('endController');
$Dispatcher->testCase($Case);
$this->assertTrue(isset($Dispatcher->testCase));
$return = $Dispatcher->dispatch('/tests_apps/index', array('autoRender' => 0, 'return' => 1, 'requested' => 1));
} }
} }

View file

@ -20,6 +20,13 @@
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/ */
class TestTestManager extends TestManager {
public function setTestSuite($testSuite) {
$this->_testSuite = $testSuite;
}
}
/** /**
* TestManagerTest class * TestManagerTest class
* *
@ -28,14 +35,56 @@
*/ */
class TestManagerTest extends CakeTestCase { class TestManagerTest extends CakeTestCase {
/**
* Number of times the funcion PHPUnit_Framework_TestSuite::addTestFile() has been called
*
* @var integer
*/
protected $_countFiles = 0;
/** /**
* setUp method * setUp method
* *
* @return void * @return void
*/ */
public function setUp() { public function setUp() {
$this->TestManager = new TestManager(); $this->_countFiles = 0;
$this->Reporter = new CakeHtmlReporter(); $this->TestManager = new TestTestManager();
$this->testSuiteStub = $this->getMock('PHPUnit_Framework_TestSuite');
$this->testSuiteStub
->expects($this->any())
->method('addTestFile')
->will($this->returnCallback(array(&$this, '_countIncludedTestFiles')));
$this->testSuiteStub
->expects($this->any())
->method('addTestSuite')
->will($this->returnCallback(array(&$this, '_countIncludedTestFiles')));
$this->TestManager->setTestSuite($this->testSuiteStub);
$this->Reporter = $this->getMock('CakeHtmlReporter');
}
/**
* Helper method to count the number of times the
* function PHPUnit_Framework_TestSuite::addTestFile() has been called
* @return void
*/
public function _countIncludedTestFiles() {
$this->_countFiles++;
}
protected function _getAllTestFiles($directory = CORE_TEST_CASES, $type = 'test') {
$folder = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
$extension = str_replace('.', '\.', $this->TestManager->getExtension($type));
$out = new RegexIterator($folder, '#^.+'.$extension.'$#i', RecursiveRegexIterator::GET_MATCH);
$files = array();
foreach ($out as $testFile) {
$files[] = $testFile[0];
}
return $files;
} }
/** /**
@ -44,14 +93,20 @@ class TestManagerTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testRunAllTests() { public function testRunAllTests() {
$folder = new Folder(CORE_TEST_CASES); $files = $this->_getAllTestFiles();
$extension = str_replace('.', '\.', $this->TestManager->getExtension('test')); $result = $this->TestManager->runAllTests($this->Reporter, true);
$out = $folder->findRecursive('.*' . $extension);
$reporter = new CakeHtmlReporter(); $this->assertEquals(count($files), $this->_countFiles);
$list = $this->TestManager->runAllTests($reporter, true); $this->assertType('PHPUnit_Framework_TestResult', $result);
}
$this->assertEqual(count($out), count($list)); /**
* Tests that trying to run an unexistent file throws an exception
* @expectedException InvalidArgumentException
*/
public function testRunUnexistentCase() {
$file = md5(time());
$result = $this->TestManager->runTestCase($file, $this->Reporter);
} }
/** /**
@ -60,14 +115,10 @@ class TestManagerTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testRunTestCase() { public function testRunTestCase() {
$file = md5(time());
$result = $this->TestManager->runTestCase($file, $this->Reporter);
$this->assertError('Test case ' . $file . ' cannot be found');
$this->assertFalse($result);
$file = str_replace(CORE_TEST_CASES, '', __FILE__); $file = str_replace(CORE_TEST_CASES, '', __FILE__);
$result = $this->TestManager->runTestCase($file, $this->Reporter, true); $result = $this->TestManager->runTestCase($file, $this->Reporter, true);
$this->assertTrue($result); $this->assertEquals(1, $this->_countFiles);
$this->assertType('PHPUnit_Framework_TestResult', $result);
} }
/** /**
@ -76,6 +127,15 @@ class TestManagerTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testRunGroupTest() { public function testRunGroupTest() {
$groups = $this->_getAllTestFiles(CORE_TEST_GROUPS, 'group');
if (empty($groups)) {
$this->markTestSkipped('No test group files');
return;
}
list($groupFile,) = explode('.', array_pop($groups), 2);
$result = $this->TestManager->runGroupTest(basename($groupFile), $this->Reporter);
$this->assertGreaterThan(0, $this->_countFiles);
$this->assertType('PHPUnit_Framework_TestResult', $result);
} }
/** /**
@ -84,6 +144,8 @@ class TestManagerTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testAddTestCasesFromDirectory() { public function testAddTestCasesFromDirectory() {
$this->TestManager->addTestCasesFromDirectory($this->testSuiteStub, CORE_TEST_CASES);
$this->assertEquals(count($this->_getAllTestFiles()), $this->_countFiles);
} }
/** /**
@ -92,6 +154,9 @@ class TestManagerTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testAddTestFile() { public function testAddTestFile() {
$file = str_replace(CORE_TEST_CASES, '', __FILE__);
$this->TestManager->addTestFile($this->testSuiteStub, $file);
$this->assertEquals(1, $this->_countFiles);
} }
/** /**

View file

@ -28,7 +28,7 @@ App::import('Helper', 'Xml');
* @package cake * @package cake
* @subpackage cake.tests.cases.libs.view.helpers * @subpackage cake.tests.cases.libs.view.helpers
*/ */
class TestXml extends Object { class TestXmlHelper extends Object {
/** /**
* content property * content property

View file

@ -294,7 +294,6 @@ class ThemeViewTest extends CakeTestCase {
/** /**
* testMissingLayout method * testMissingLayout method
*
* @access public * @access public
* @return void * @return void
*/ */
@ -305,12 +304,10 @@ class ThemeViewTest extends CakeTestCase {
$this->Controller->layout = 'whatever'; $this->Controller->layout = 'whatever';
$this->Controller->theme = 'my_theme'; $this->Controller->theme = 'my_theme';
restore_error_handler();
$View =& new TestThemeView($this->Controller); $View =& new TestThemeView($this->Controller);
ob_start(); ob_start();
$result = $View->getLayoutFileName(); $result = $View->getLayoutFileName();
$expected = str_replace(array("\t", "\r\n", "\n"), "", ob_get_clean()); $expected = str_replace(array("\t", "\r\n", "\n"), "", ob_get_clean());
set_error_handler('simpleTestErrorHandler');
$this->assertPattern("/Missing Layout/", $expected); $this->assertPattern("/Missing Layout/", $expected);
$this->assertPattern("/views(\/|\\\)themed(\/|\\\)my_theme(\/|\\\)layouts(\/|\\\)whatever.ctp/", $expected); $this->assertPattern("/views(\/|\\\)themed(\/|\\\)my_theme(\/|\\\)layouts(\/|\\\)whatever.ctp/", $expected);
} }
@ -338,6 +335,6 @@ class ThemeViewTest extends CakeTestCase {
$View->element('test_element'); $View->element('test_element');
} }
$end = memory_get_usage(); $end = memory_get_usage();
$this->assertWithinMargin($start, $end, 3500); $this->assertLessThanOrEqual($start + 3500, $end);
} }
} }

View file

@ -20,9 +20,6 @@
App::import('Core', array('View', 'Controller')); App::import('Core', array('View', 'Controller'));
App::import('Helper', 'Cache'); App::import('Helper', 'Cache');
Mock::generate('Helper', 'CallbackMockHelper');
Mock::generate('CacheHelper', 'ViewTestMockCacheHelper');
if (!class_exists('ErrorHandler')) { if (!class_exists('ErrorHandler')) {
App::import('Core', array('Error')); App::import('Core', array('Error'));
} }
@ -608,14 +605,15 @@ class ViewTest extends CakeTestCase {
* @return void * @return void
*/ */
function testHelperCallbackTriggering() { function testHelperCallbackTriggering() {
$mockHelper = $this->getMock('Helper', array(), array(), 'CallbackMockHelper');
$this->PostsController->helpers = array('Session', 'Html', 'CallbackMock'); $this->PostsController->helpers = array('Session', 'Html', 'CallbackMock');
$View = new TestView($this->PostsController); $View = new TestView($this->PostsController);
$loaded = array(); $loaded = array();
$View->loaded = $View->loadHelpers($loaded, $this->PostsController->helpers); $View->loaded = $View->loadHelpers($loaded, $this->PostsController->helpers);
$View->loaded['CallbackMock']->expectOnce('beforeRender'); $View->loaded['CallbackMock']->expects($this->once())->method('beforeRender');
$View->loaded['CallbackMock']->expectOnce('afterRender'); $View->loaded['CallbackMock']->expects($this->once())->method('afterRender');
$View->loaded['CallbackMock']->expectOnce('beforeLayout'); $View->loaded['CallbackMock']->expects($this->once())->method('beforeLayout');
$View->loaded['CallbackMock']->expectOnce('afterLayout'); $View->loaded['CallbackMock']->expects($this->once())->method('afterLayout');
$View->render('index'); $View->render('index');
} }
@ -745,8 +743,8 @@ class ViewTest extends CakeTestCase {
$Controller = new ViewPostsController(); $Controller = new ViewPostsController();
$Controller->cacheAction = '1 day'; $Controller->cacheAction = '1 day';
$View = new View($Controller); $View = new View($Controller);
$View->loaded['cache'] = new ViewTestMockCacheHelper(); $View->loaded['cache'] = $this->getMock('CacheHelper');
$View->loaded['cache']->expectCallCount('cache', 2); $View->loaded['cache']->expects($this->exactly(2))->method('cache');
$result = $View->render('index'); $result = $View->render('index');
$this->assertPattern('/posts index/', $result); $this->assertPattern('/posts index/', $result);

View file

@ -1340,7 +1340,6 @@ class XmlTest extends CakeTestCase {
$parentNode->append($string); $parentNode->append($string);
$last =& $parentNode->last(); $last =& $parentNode->last();
$this->assertEqual($last->name, 'ourChildNode'); $this->assertEqual($last->name, 'ourChildNode');
$this->expectError(); $this->expectError();
$parentNode->append($parentNode); $parentNode->append($parentNode);
} }

View file

@ -0,0 +1,125 @@
<?php
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
/**
* This class helpes in indirectly testing the functionaliteies of CakeTestCase::assertTags
*
* @package cake
* @subpackage cake.tests.fixtures
*/
class AssertTagsTestCase extends CakeTestCase {
/**
* test that assertTags knows how to handle correct quoting.
*
* @return void
*/
function testAssertTagsQuotes() {
$input = '<a href="/test.html" class="active">My link</a>';
$pattern = array(
'a' => array('href' => '/test.html', 'class' => 'active'),
'My link',
'/a'
);
$this->assertTags($input, $pattern);
$input = "<a href='/test.html' class='active'>My link</a>";
$pattern = array(
'a' => array('href' => '/test.html', 'class' => 'active'),
'My link',
'/a'
);
$this->assertTags($input, $pattern);
$input = "<a href='/test.html' class='active'>My link</a>";
$pattern = array(
'a' => array('href' => 'preg:/.*\.html/', 'class' => 'active'),
'My link',
'/a'
);
$this->assertTags($input, $pattern);
}
/**
* testNumericValuesInExpectationForAssertTags
*
* @access public
* @return void
*/
function testNumericValuesInExpectationForAssertTags() {
$value = 220985;
$input = '<p><strong>' . $value . '</strong></p>';
$pattern = array(
'<p',
'<strong',
$value,
'/strong',
'/p'
);
$this->assertTags($input, $pattern);
$input = '<p><strong>' . $value . '</strong></p><p><strong>' . $value . '</strong></p>';
$pattern = array(
'<p',
'<strong',
$value,
'/strong',
'/p',
'<p',
'<strong',
$value,
'/strong',
'/p',
);
$this->assertTags($input, $pattern);
$input = '<p><strong>' . $value . '</strong></p><p id="' . $value . '"><strong>' . $value . '</strong></p>';
$pattern = array(
'<p',
'<strong',
$value,
'/strong',
'/p',
'p' => array('id' => $value),
'<strong',
$value,
'/strong',
'/p',
);
$this->assertTags($input, $pattern);
}
/**
* testBadAssertTags
*
* @access public
* @return void
*/
function testBadAssertTags() {
$input = '<a href="/test.html" class="active">My link</a>';
$pattern = array(
'a' => array('hRef' => '/test.html', 'clAss' => 'active'),
'My link2',
'/a'
);
$this->assertTags($input, $pattern);
}
/**
* testBadAssertTags
*
* @access public
* @return void
*/
function testBadAssertTags2() {
$input = '<a href="/test.html" class="active">My link</a>';
$pattern = array(
'<a' => array('href' => '/test.html', 'class' => 'active'),
'My link',
'/a'
);
$this->assertTags($input, $pattern);
}
}

View file

@ -0,0 +1,54 @@
<?php
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
/**
* This class helps in testing the life-cycle of fixtures inside a CakeTestCase
*
* @package cake
* @subpackage cake.tests.fixtures
*/
class FixturizedTestCase extends CakeTestCase {
/**
* Fixtures to use in this thes
* @var array
*/
public $fixtures = array('core.category');
/**
* test that the shared fixture is correctly set
*
* @return void
*/
public function testFixturePresent() {
$this->assertType('CakeFixtureManager', $this->sharedFixture);
}
/**
* test that it is possible to load fixtures on demand
*
* @return void
*/
public function testFixtureLoadOnDemand() {
$this->loadFixtures('Category');
}
/**
* test that a test is marked as skipped using skipIf and its first parameter evaluates to true
*
* @return void
*/
public function testSkipIfTrue() {
$this->skipIf(true);
}
/**
* test that a test is not marked as skipped using skipIf and its first parameter evaluates to false
*
* @return void
*/
public function testSkipIfFalse() {
$this->skipIf(false);
}
}

View file

@ -26,7 +26,7 @@
* @package cake * @package cake
* @subpackage cake.tests.groups * @subpackage cake.tests.groups
*/ */
class XmlGroupTest extends TestSuite { class XmlGroupTest extends PHPUnit_Framework_TestSuite {
/** /**
* label property * label property
@ -37,12 +37,12 @@ class XmlGroupTest extends TestSuite {
public $label = 'Xml based classes (Xml, XmlHelper and RssHelper)'; public $label = 'Xml based classes (Xml, XmlHelper and RssHelper)';
/** /**
* XmlGroupTest method * __construct method
* *
* @access public * @access public
* @return void * @return void
*/ */
function XmlGroupTest() { function __construct() {
TestManager::addTestFile($this, CORE_TEST_CASES . DS . 'libs' . DS . 'xml'); TestManager::addTestFile($this, CORE_TEST_CASES . DS . 'libs' . DS . 'xml');
TestManager::addTestFile($this, CORE_TEST_CASES . DS . 'libs' . DS . 'view' . DS . 'helpers' . DS .'rss'); TestManager::addTestFile($this, CORE_TEST_CASES . DS . 'libs' . DS . 'view' . DS . 'helpers' . DS .'rss');
TestManager::addTestFile($this, CORE_TEST_CASES . DS . 'libs' . DS . 'view' . DS . 'helpers' . DS .'xml'); TestManager::addTestFile($this, CORE_TEST_CASES . DS . 'libs' . DS . 'view' . DS . 'helpers' . DS .'xml');

View file

@ -0,0 +1,282 @@
<?php
/**
* A factory class to manage the life cycle of test fixtures
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.tests.libs
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
class CakeFixtureManager {
/**
* Was this class already initialized?
*
* @var boolean
*/
protected $_initialized = false;
/**
* Default datasource to use
*
* @var DataSource
*/
protected $_db = null;
/**
* Holds the fixture classes that where instantiated
*
* @var array
*/
protected $_loaded = array();
/**
* Holds the fixture classes that where instantiated indexed by class name
*
* @var array
*/
protected $_fixtureMap = array();
/**
* Inspects the test to look for unloaded fixtures and loads them
*
* @param CakeTestCase $test the test case to inspect
* @return void
*/
public function fixturize(CakeTestCase $test) {
if (empty($test->fixtures) || !empty($this->_processed[get_class($test)])) {
$test->db = $this->_db;
return;
}
$this->_initDb();
$test->db = $this->_db;
if (!is_array($test->fixtures)) {
$test->fixtures = array_map('trim', explode(',', $test->fixtures));
}
if (isset($test->fixtures)) {
$this->_loadFixtures($test->fixtures);
}
$this->_processed[get_class($test)] = true;
}
/**
* Initializes this class with a DataSource object to use as default for all fixtures
*
* @return void
*/
protected function _initDb() {
if ($this->_initialized) {
return;
}
$testDbAvailable = in_array('test', array_keys(ConnectionManager::enumConnectionObjects()));
$_prefix = null;
if ($testDbAvailable) {
// Try for test DB
@$db = ConnectionManager::getDataSource('test');
$testDbAvailable = $db->isConnected();
}
// Try for default DB
if (!$testDbAvailable) {
$db = ConnectionManager::getDataSource('default');
$_prefix = $db->config['prefix'];
$db->config['prefix'] = 'test_suite_';
}
ConnectionManager::create('test_suite', $db->config);
$db->config['prefix'] = $_prefix;
// Get db connection
$this->_db = ConnectionManager::getDataSource('test_suite');
$this->_db->cacheSources = false;
ClassRegistry::config(array('ds' => 'test_suite'));
$this->_initialized = true;
}
/**
* Looks for fixture files and instantiates the classes accordingly
*
* @param array $fixtures the fixture names to load using the notation {type}.{name}
* @return void
*/
protected function _loadFixtures($fixtures) {
foreach ($fixtures as $index => $fixture) {
$fixtureFile = null;
$fixtureIndex = $fixture;
if (isset($this->_loaded[$fixture])) {
continue;
}
if (strpos($fixture, 'core.') === 0) {
$fixture = substr($fixture, strlen('core.'));
foreach (App::core('cake') as $key => $path) {
$fixturePaths[] = $path . 'tests' . DS . 'fixtures';
}
} elseif (strpos($fixture, 'app.') === 0) {
$fixture = substr($fixture, strlen('app.'));
$fixturePaths = array(
TESTS . 'fixtures',
VENDORS . 'tests' . DS . 'fixtures'
);
} elseif (strpos($fixture, 'plugin.') === 0) {
$parts = explode('.', $fixture, 3);
$pluginName = $parts[1];
$fixture = $parts[2];
$fixturePaths = array(
App::pluginPath($pluginName) . 'tests' . DS . 'fixtures',
TESTS . 'fixtures',
VENDORS . 'tests' . DS . 'fixtures'
);
} else {
$fixturePaths = array(
TESTS . 'fixtures',
VENDORS . 'tests' . DS . 'fixtures',
TEST_CAKE_CORE_INCLUDE_PATH . DS . 'cake' . DS . 'tests' . DS . 'fixtures'
);
}
foreach ($fixturePaths as $path) {
if (is_readable($path . DS . $fixture . '_fixture.php')) {
$fixtureFile = $path . DS . $fixture . '_fixture.php';
break;
}
}
if (isset($fixtureFile)) {
require_once($fixtureFile);
$fixtureClass = Inflector::camelize($fixture) . 'Fixture';
$this->_loaded[$fixtureIndex] = new $fixtureClass($this->_db);
$this->_fixtureMap[$fixtureClass] = $this->_loaded[$fixtureIndex];
}
}
}
/**
* Runs the drop and create commands on the fixtures if necessary
*
* @param CakeTestFixture $fixture the fixture object to create
* @param DataSource $db the datasource instance to use
* @param boolean $drop whether drop the fixture if it is already created or not
* @return void
*/
protected function _setupTable($fixture, $db = null, $drop = true) {
if (!empty($fixture->created)) {
return;
}
if (!$db) {
$db = $this->_db;
}
$cacheSources = $db->cacheSources;
$db->cacheSources = false;
$db->cacheSources = $cacheSources;
$sources = $db->listSources();
$table = $db->config['prefix'] . $fixture->table;
if ($drop && in_array($table, $sources)) {
$fixture->drop($db);
$fixture->create($db);
$fixture->created = true;
} elseif (!in_array($table, $sources)) {
$fixture->create($db);
$fixture->created = true;
}
}
/**
* Crates the fixtures tables and inserts data on them
*
* @param CakeTestCase $test the test to inspect for fixture loading
* @return void
*/
public function load(CakeTestCase $test) {
if (empty($test->fixtures)) {
return;
}
$fixtures = $test->fixtures;
if (empty($fixtures) || $test->autoFixtures == false) {
return;
}
foreach ($fixtures as $f) {
if (!empty($this->_loaded[$f])) {
$fixture = $this->_loaded[$f];
$this->_setupTable($fixture, $test->db, $test->dropTables);
$fixture->insert($test->db);
}
}
}
/**
* Trucantes the fixtures tables
*
* @param CakeTestCase $test the test to inspect for fixture unloading
* @return void
*/
public function unload(CakeTestCase $test) {
if (empty($test->fixtures)) {
return;
}
$fixtures = $test->fixtures;
if (empty($fixtures)) {
return;
}
foreach ($fixtures as $f) {
if (isset($this->_loaded[$f])) {
$fixture = $this->_loaded[$f];
if (!empty($fixture->created)) {
$fixture->truncate($test->db);
}
}
}
}
/**
* Trucantes the fixtures tables
*
* @param CakeTestCase $test the test to inspect for fixture unloading
* @return void
* @throws UnexpectedValueException if $name is not a previously loaded class
*/
public function loadSingle($name, $db = null) {
$name .= 'Fixture';
if (isset($this->_fixtureMap[$name])) {
if (!$db) {
$db = $this->_db;
}
$fixture = $this->_fixtureMap[$name];
$fixture->truncate($db);
$fixture->insert($db);
} else {
throw new UnexpectedValueException(sprintf(__('Referenced fixture class %s not found'), $name));
}
}
/**
* Drop all fixture tables loaded by this class
*
* @return void
*/
public function shutDown() {
foreach ($this->_loaded as $fixture) {
if (!empty($fixture->created)) {
$fixture->drop($this->_db);
}
}
}
}

View file

@ -17,64 +17,12 @@
* @since CakePHP(tm) v 1.2.0.4667 * @since CakePHP(tm) v 1.2.0.4667
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/ */
if (!class_exists('dispatcher')) {
require CAKE . 'dispatcher.php'; PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
}
require_once CAKE_TESTS_LIB . 'cake_fixture_manager.php';
require_once CAKE_TESTS_LIB . 'cake_test_model.php'; require_once CAKE_TESTS_LIB . 'cake_test_model.php';
require_once CAKE_TESTS_LIB . 'cake_test_fixture.php'; require_once CAKE_TESTS_LIB . 'cake_test_fixture.php';
App::import('Vendor', 'simpletest' . DS . 'unit_tester');
/**
* CakeTestDispatcher
*
* @package cake
* @subpackage cake.cake.tests.lib
*/
class CakeTestDispatcher extends Dispatcher {
/**
* controller property
*
* @var Controller
* @access public
*/
public $controller;
public $testCase;
/**
* testCase method
*
* @param CakeTestCase $testCase
* @return void
*/
public function testCase(&$testCase) {
$this->testCase =& $testCase;
}
/**
* invoke method
*
* @param Controller $controller
* @param array $params
* @param boolean $missingAction
* @return Controller
*/
protected function _invoke(&$controller, $params, $missingAction = false) {
$this->controller =& $controller;
if (isset($this->testCase) && method_exists($this->testCase, 'startController')) {
$this->testCase->startController($this->controller, $params);
}
$result = parent::_invoke($this->controller, $params, $missingAction);
if (isset($this->testCase) && method_exists($this->testCase, 'endController')) {
$this->testCase->endController($this->controller, $params);
}
return $result;
}
}
/** /**
* CakeTestCase class * CakeTestCase class
@ -82,7 +30,7 @@ class CakeTestDispatcher extends Dispatcher {
* @package cake * @package cake
* @subpackage cake.cake.tests.lib * @subpackage cake.cake.tests.lib
*/ */
class CakeTestCase extends UnitTestCase { class CakeTestCase extends PHPUnit_Framework_TestCase {
/** /**
* Methods used internally. * Methods used internally.
@ -109,22 +57,6 @@ class CakeTestCase extends UnitTestCase {
*/ */
public $dropTables = true; public $dropTables = true;
/**
* Maps fixture class names to fixture identifiers as included in CakeTestCase::$fixtures
*
* @var array
* @access protected
*/
protected $_fixtureClassMap = array();
/**
* truncated property
*
* @var boolean
* @access private
*/
private $__truncated = true;
/** /**
* savedGetData property * savedGetData property
* *
@ -169,21 +101,6 @@ class CakeTestCase extends UnitTestCase {
public function endTest($method) { public function endTest($method) {
} }
/**
* Overrides SimpleTestCase::assert to enable calling of skipIf() from within tests
*
* @param Expectation $expectation
* @param mixed $compare
* @param string $message
* @return boolean|null
*/
public function assert(&$expectation, $compare, $message = '%s') {
if ($this->_should_skip) {
return;
}
return parent::assert($expectation, $compare, $message);
}
/** /**
* Overrides SimpleTestCase::skipIf to provide a boolean return value * Overrides SimpleTestCase::skipIf to provide a boolean return value
* *
@ -191,250 +108,26 @@ class CakeTestCase extends UnitTestCase {
* @param string $message * @param string $message
* @return boolean * @return boolean
*/ */
public function skipIf($shouldSkip, $message = '%s') { public function skipIf($shouldSkip, $message = '') {
parent::skipIf($shouldSkip, $message); if ($shouldSkip) {
$this->markTestSkipped($message);
}
return $shouldSkip; return $shouldSkip;
} }
/**
* Callback issued when a controller's action is about to be invoked through testAction().
*
* @param Controller $controller Controller that's about to be invoked.
* @param array $params Additional parameters as sent by testAction().
* @return void
*/
public function startController(&$controller, $params = array()) {
if (isset($params['fixturize']) && ((is_array($params['fixturize']) && !empty($params['fixturize'])) || $params['fixturize'] === true)) {
if (!isset($this->db)) {
$this->_initDb();
}
if ($controller->uses === false) {
$list = array($controller->modelClass);
} else {
$list = is_array($controller->uses) ? $controller->uses : array($controller->uses);
}
$models = array();
ClassRegistry::config(array('ds' => $params['connection']));
foreach ($list as $name) {
if ((is_array($params['fixturize']) && in_array($name, $params['fixturize'])) || $params['fixturize'] === true) {
if (class_exists($name) || App::import('Model', $name)) {
$object =& ClassRegistry::init($name);
//switch back to specified datasource.
$object->setDataSource($params['connection']);
$db =& ConnectionManager::getDataSource($object->useDbConfig);
$db->cacheSources = false;
$models[$object->alias] = array(
'table' => $object->table,
'model' => $object->alias,
'key' => strtolower($name),
);
}
}
}
ClassRegistry::config(array('ds' => 'test_suite'));
if (!empty($models) && isset($this->db)) {
$this->_actionFixtures = array();
foreach ($models as $model) {
$fixture =& new CakeTestFixture($this->db);
$fixture->name = $model['model'] . 'Test';
$fixture->table = $model['table'];
$fixture->import = array('model' => $model['model'], 'records' => true);
$fixture->init();
$fixture->create($this->db);
$fixture->insert($this->db);
$this->_actionFixtures[] =& $fixture;
}
foreach ($models as $model) {
$object =& ClassRegistry::getObject($model['key']);
if ($object !== false) {
$object->setDataSource('test_suite');
$object->cacheSources = false;
}
}
}
}
}
/**
* Callback issued when a controller's action has been invoked through testAction().
*
* @param Controller $controller Controller that has been invoked.
* @param array $params Additional parameters as sent by testAction().
* @return void
*/
public function endController(&$controller, $params = array()) {
if (isset($this->db) && isset($this->_actionFixtures) && !empty($this->_actionFixtures) && $this->dropTables) {
foreach ($this->_actionFixtures as $fixture) {
$fixture->drop($this->db);
}
}
}
/**
* Executes a Cake URL, and can get (depending on the $params['return'] value):
*
* Params:
* - 'return' has several possible values:
* 1. 'result': Whatever the action returns (and also specifies $this->params['requested'] for controller)
* 2. 'view': The rendered view, without the layout
* 3. 'contents': The rendered view, within the layout.
* 4. 'vars': the view vars
*
* - 'fixturize' - Set to true if you want to copy model data from 'connection' to the test_suite connection
* - 'data' - The data you want to insert into $this->data in the controller.
* - 'connection' - Which connection to use in conjunction with fixturize (defaults to 'default')
* - 'method' - What type of HTTP method to simulate (defaults to post)
*
* @param string $url Cake URL to execute (e.g: /articles/view/455)
* @param mixed $params Parameters (see above), or simply a string of what to return
* @return mixed Whatever is returned depending of requested result
*/
public function testAction($url, $params = array()) {
$default = array(
'return' => 'result',
'fixturize' => false,
'data' => array(),
'method' => 'post',
'connection' => 'default'
);
if (is_string($params)) {
$params = array('return' => $params);
}
$params = array_merge($default, $params);
$toSave = array(
'case' => null,
'group' => null,
'app' => null,
'output' => null,
'show' => null,
'plugin' => null
);
$this->__savedGetData = (empty($this->__savedGetData))
? array_intersect_key($_GET, $toSave)
: $this->__savedGetData;
$data = (!empty($params['data'])) ? $params['data'] : array();
if (strtolower($params['method']) == 'get') {
$_GET = array_merge($this->__savedGetData, $data);
$_POST = array();
} else {
$_POST = array('data' => $data);
$_GET = $this->__savedGetData;
}
$return = $params['return'];
$params = array_diff_key($params, array('data' => null, 'method' => null, 'return' => null));
$dispatcher =& new CakeTestDispatcher();
$dispatcher->testCase($this);
if ($return != 'result') {
if ($return != 'contents') {
$params['layout'] = false;
}
ob_start();
@$dispatcher->dispatch($url, $params);
$result = ob_get_clean();
if ($return == 'vars') {
$view =& ClassRegistry::getObject('view');
$viewVars = $view->getVars();
$result = array();
foreach ($viewVars as $var) {
$result[$var] = $view->getVar($var);
}
if (!empty($view->pageTitle)) {
$result = array_merge($result, array('title' => $view->pageTitle));
}
}
} else {
$params['return'] = 1;
$params['bare'] = 1;
$params['requested'] = 1;
$result = @$dispatcher->dispatch($url, $params);
}
if (isset($this->_actionFixtures)) {
unset($this->_actionFixtures);
}
ClassRegistry::flush();
return $result;
}
/** /**
* Announces the start of a test. * Announces the start of a test.
* *
* @param string $method Test method just started. * @param string $method Test method just started.
* @return void * @return void
*/ */
public function before($method) { protected function assertPreConditions() {
parent::before($method); parent::assertPreConditions();
if (!empty($this->sharedFixture)) {
if (isset($this->fixtures) && (!is_array($this->fixtures) || empty($this->fixtures))) { $this->sharedFixture->load($this);
unset($this->fixtures);
} }
if (!in_array(strtolower($this->getName()), $this->methods)) {
// Set up DB connection $this->startTest($this->getName());
if (isset($this->fixtures) && strtolower($method) == 'start') {
$this->_initDb();
$this->_loadFixtures();
}
// Create records
if (isset($this->_fixtures) && isset($this->db) && !in_array(strtolower($method), array('start', 'end')) && $this->__truncated && $this->autoFixtures == true) {
foreach ($this->_fixtures as $fixture) {
$inserts = $fixture->insert($this->db);
}
}
if (!in_array(strtolower($method), $this->methods)) {
$this->startTest($method);
}
}
/**
* Runs as first test to create tables.
*
* @return void
*/
public function start() {
if (isset($this->_fixtures) && isset($this->db)) {
Configure::write('Cache.disable', true);
$cacheSources = $this->db->cacheSources;
$this->db->cacheSources = false;
$sources = $this->db->listSources();
$this->db->cacheSources = $cacheSources;
if (!$this->dropTables) {
return;
}
foreach ($this->_fixtures as $fixture) {
$table = $this->db->config['prefix'] . $fixture->table;
if (in_array($table, $sources)) {
$fixture->drop($this->db);
$fixture->create($this->db);
} elseif (!in_array($table, $sources)) {
$fixture->create($this->db);
}
}
} }
} }
@ -465,24 +158,14 @@ class CakeTestCase extends UnitTestCase {
* @param string $method Test method just finished. * @param string $method Test method just finished.
* @return void * @return void
*/ */
public function after($method) { protected function assertPostConditions() {
$isTestMethod = !in_array(strtolower($method), array('start', 'end')); parent::assertPostConditions();
if (!empty($this->sharedFixture)) {
if (isset($this->_fixtures) && isset($this->db) && $isTestMethod) { $this->sharedFixture->unload($this);
foreach ($this->_fixtures as $fixture) {
$fixture->truncate($this->db);
}
$this->__truncated = true;
} else {
$this->__truncated = false;
} }
if (!in_array(strtolower($this->getName()), $this->methods)) {
if (!in_array(strtolower($method), $this->methods)) { $this->endTest($this->getName());
$this->endTest($method);
} }
$this->_should_skip = false;
parent::after($method);
} }
/** /**
@ -499,14 +182,6 @@ class CakeTestCase extends UnitTestCase {
); );
} }
/**
* Accessor for checking whether or not fixtures were truncated
*
* @return void
*/
public function getTruncated() {
return $this->__truncated;
}
/** /**
* Chooses which fixtures to load for a given test * Chooses which fixtures to load for a given test
* *
@ -517,16 +192,12 @@ class CakeTestCase extends UnitTestCase {
* @see CakeTestCase::$autoFixtures * @see CakeTestCase::$autoFixtures
*/ */
function loadFixtures() { function loadFixtures() {
if (empty($this->sharedFixture)) {
throw new Exception(__('No fixture manager to load the test fixture'));
}
$args = func_get_args(); $args = func_get_args();
foreach ($args as $class) { foreach ($args as $class) {
if (isset($this->_fixtureClassMap[$class])) { $this->sharedFixture->loadSingle($class);
$fixture = $this->_fixtures[$this->_fixtureClassMap[$class]];
$fixture->truncate($this->db);
$fixture->insert($this->db);
} else {
trigger_error(sprintf(__('Referenced fixture class %s not found', true), $class), E_USER_WARNING);
}
} }
} }
@ -677,7 +348,7 @@ class CakeTestCase extends UnitTestCase {
} }
} }
if (!$matches) { if (!$matches) {
$this->assert(new TrueExpectation(), false, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description)); $this->assertTrue(false, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description));
if ($fullDebug) { if ($fullDebug) {
debug($string, true); debug($string, true);
debug($regex, true); debug($regex, true);
@ -685,109 +356,9 @@ class CakeTestCase extends UnitTestCase {
return false; return false;
} }
} }
return $this->assert(new TrueExpectation(), true, '%s');
}
/** $this->assertTrue(true, '%s');
* Initialize DB connection. return true;
*
* @return void
*/
protected function _initDb() {
$testDbAvailable = in_array('test', array_keys(ConnectionManager::enumConnectionObjects()));
$_prefix = null;
if ($testDbAvailable) {
// Try for test DB
restore_error_handler();
@$db = ConnectionManager::getDataSource('test');
set_error_handler('simpleTestErrorHandler');
$testDbAvailable = $db->isConnected();
}
// Try for default DB
if (!$testDbAvailable) {
$db = ConnectionManager::getDataSource('default');
$_prefix = $db->config['prefix'];
$db->config['prefix'] = 'test_suite_';
}
ConnectionManager::create('test_suite', $db->config);
$db->config['prefix'] = $_prefix;
// Get db connection
$this->db = ConnectionManager::getDataSource('test_suite');
$this->db->cacheSources = false;
ClassRegistry::config(array('ds' => 'test_suite'));
}
/**
* Load fixtures specified in public $fixtures.
*
* @return void
*/
protected function _loadFixtures() {
if (!isset($this->fixtures) || empty($this->fixtures)) {
return;
}
if (!is_array($this->fixtures)) {
$this->fixtures = array_map('trim', explode(',', $this->fixtures));
}
$this->_fixtures = array();
foreach ($this->fixtures as $index => $fixture) {
$fixtureFile = null;
if (strpos($fixture, 'core.') === 0) {
$fixture = substr($fixture, strlen('core.'));
foreach (App::core('cake') as $key => $path) {
$fixturePaths[] = $path . 'tests' . DS . 'fixtures';
}
} elseif (strpos($fixture, 'app.') === 0) {
$fixture = substr($fixture, strlen('app.'));
$fixturePaths = array(
TESTS . 'fixtures',
VENDORS . 'tests' . DS . 'fixtures'
);
} elseif (strpos($fixture, 'plugin.') === 0) {
$parts = explode('.', $fixture, 3);
$pluginName = $parts[1];
$fixture = $parts[2];
$fixturePaths = array(
App::pluginPath($pluginName) . 'tests' . DS . 'fixtures',
TESTS . 'fixtures',
VENDORS . 'tests' . DS . 'fixtures'
);
} else {
$fixturePaths = array(
TESTS . 'fixtures',
VENDORS . 'tests' . DS . 'fixtures',
TEST_CAKE_CORE_INCLUDE_PATH . DS . 'cake' . DS . 'tests' . DS . 'fixtures'
);
}
foreach ($fixturePaths as $path) {
if (is_readable($path . DS . $fixture . '_fixture.php')) {
$fixtureFile = $path . DS . $fixture . '_fixture.php';
break;
}
}
if (isset($fixtureFile)) {
require_once($fixtureFile);
$fixtureClass = Inflector::camelize($fixture) . 'Fixture';
$this->_fixtures[$this->fixtures[$index]] =& new $fixtureClass($this->db);
$this->_fixtureClassMap[Inflector::camelize($fixture)] = $this->fixtures[$index];
}
}
if (empty($this->_fixtures)) {
unset($this->_fixtures);
}
} }
/** /**
@ -817,4 +388,110 @@ class CakeTestCase extends UnitTestCase {
return $permuted; return $permuted;
} }
} }
/**
* Compatibility wrapper function for assertEquals
* @param mixed $a
* @param mixed $b
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertEqual($a, $b, $message = '') {
return $this->assertEquals($a, $b, $message);
}
/**
* Compatibility wrapper function for assertNotEquals
* @param mixed $a
* @param mixed $b
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertNotEqual($a, $b, $message = '') {
return $this->assertNotEquals($a, $b, $message);
}
/**
* Compatibility wrapper function for assertRegexp
* @param mixed $pattern a regular expression
* @param string $string the text to be matched
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertPattern($pattern, $string, $message = '') {
return $this->assertRegExp($pattern, $string, $message);
}
/**
* Compatibility wrapper function for assertSame
* @param mixed $expected
* @param mixed $actual
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertIdentical($expected, $actual, $message = '') {
return $this->assertSame($expected, $actual, $message);
}
/**
* Compatibility wrapper function for assertNotRegExp
* @param mixed $pattern a regular expression
* @param string $string the text to be matched
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertNoPattern($pattern, $string, $message = '') {
return $this->assertNotRegExp($pattern, $string, $message);
}
protected function assertNoErrors() {
}
/**
* Compatibility wrapper function for setExpectedException
* @param mixed $expected the name of the Exception or error
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function expectError($expected = false, $message = '') {
if (!$expected) {
$expected = 'Exception';
}
$this->setExpectedException($expected, $message);
}
/**
* Compatibility wrapper function for setExpectedException
* @param mixed $expected the name of the Exception
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function expectException($name = 'Exception', $message = '') {
$this->setExpectedException($name, $message);
}
/**
* Compatibility wrapper function for assertSame
* @param mixed $expected
* @param mixed $actual
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertReference(&$first, &$second, $message = '') {
return $this->assertSame($first, $second, $message);
}
/**
* Compatibility function to test if value is between an acceptable range
* @param mixed $value
* @param mixed $expected
* @param mixed $margin the rage of acceptation
* @param string $message the text to display if the assertion is not correct
* @return void
*/
protected function assertWithinMargin($value, $expected, $margin, $message = '') {
$upper = $value + $margin;
$lower = $value - $margin;
$this->assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
}
} }

View file

@ -18,6 +18,8 @@
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/ */
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
/** /**
* Short description for class. * Short description for class.
* *

View file

@ -0,0 +1,69 @@
<?php
/**
* A class to contain test cases and run them with shered fixtures
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.tests.libs
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class CakeTestSuite extends PHPUnit_Framework_TestSuite {
/**
* Instance of a fixture manager
* @var CakeFixtureManager
*/
protected $_fixtureManager = null;
/**
* Sets the intances for the fixture manager that will be used by this class
* @param CakeFixtureManager $manager the instance of the manager class
* @return void
* @access public
*/
public function setFixtureManager(CakeFixtureManager $manager) {
$this->_fixtureManager = $manager;
}
/**
* Method that is called before the tests of this test suite are run.
* It will load fixtures accordingly for each test
* @return void
* @access protected
*/
protected function setUp() {
parent::setUp();
restore_error_handler();
restore_error_handler();
if (!$this->_fixtureManager) {
return;
}
$classes = array();
foreach ($this->getIterator() as $test) {
$this->_fixtureManager->fixturize($test);
}
$this->sharedFixture = $this->_fixtureManager;
}
/**
* Method that is called after all the tests of this test suite are run.
* @return void
* @access protected
*/
protected function tearDown() {
parent::tearDown();
$this->_fixtureManager->shutDown();
$this->_fixtureManager = null;
$this->sharedFixture = null;
}
}

View file

@ -17,7 +17,6 @@
* @since CakePHP(tm) v 1.3 * @since CakePHP(tm) v 1.3
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/ */
require_once CAKE_TESTS_LIB . 'test_manager.php';
/** /**
* CakeTestSuiteDispatcher handles web requests to the test suite and runs the correct action. * CakeTestSuiteDispatcher handles web requests to the test suite and runs the correct action.
@ -93,7 +92,7 @@ class CakeTestSuiteDispatcher {
* @return void * @return void
*/ */
function dispatch() { function dispatch() {
$this->_checkSimpleTest(); $this->_checkPHPUnit();
$this->_parseParams(); $this->_parseParams();
if ($this->params['group']) { if ($this->params['group']) {
@ -111,16 +110,36 @@ class CakeTestSuiteDispatcher {
} }
/** /**
* Checks that simpleTest is installed. Will exit if it doesn't * Checks that PHPUnit is installed. Will exit if it doesn't
* *
* @return void * @return void
*/ */
function _checkSimpleTest() { function _checkPHPUnit() {
if (!App::import('Vendor', 'simpletest/reporter')) { $found = $path = null;
if (@include 'PHPUnit' . DS . 'Framework.php') {
$found = true;
}
if (!$found) {
foreach (App::path('vendors') as $vendor) {
if (is_dir($vendor . 'PHPUnit')) {
$path = $vendor;
}
}
if ($path && ini_set('include_path', $path . PATH_SEPARATOR . ini_get('include_path'))) {
$found = include 'PHPUnit' . DS . 'Framework.php';
}
}
if (!$found) {
$baseDir = $this->_baseDir; $baseDir = $this->_baseDir;
include CAKE_TESTS_LIB . 'templates/simpletest.php'; include CAKE_TESTS_LIB . 'templates/simpletest.php';
exit(); exit();
} }
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
} }
/** /**
@ -171,6 +190,7 @@ class CakeTestSuiteDispatcher {
*/ */
function &getManager() { function &getManager() {
if (empty($this->Manager)) { if (empty($this->Manager)) {
require_once CAKE_TESTS_LIB . 'test_manager.php';
$this->Manager = new $this->_managerClass(); $this->Manager = new $this->_managerClass();
} }
return $this->Manager; return $this->Manager;
@ -215,8 +235,8 @@ class CakeTestSuiteDispatcher {
} }
if (isset($_GET['code_coverage'])) { if (isset($_GET['code_coverage'])) {
$this->params['codeCoverage'] = true; $this->params['codeCoverage'] = true;
require_once CAKE_TESTS_LIB . 'code_coverage_manager.php';
$this->_checkXdebug(); $this->_checkXdebug();
require_once CAKE_TESTS_LIB . 'code_coverage_manager.php';
} }
$this->params['baseUrl'] = $this->_baseUrl; $this->params['baseUrl'] = $this->_baseUrl;
$this->params['baseDir'] = $this->_baseDir; $this->params['baseDir'] = $this->_baseDir;
@ -236,7 +256,7 @@ class CakeTestSuiteDispatcher {
if ('all' == $this->params['group']) { if ('all' == $this->params['group']) {
$this->Manager->runAllTests($Reporter); $this->Manager->runAllTests($Reporter);
} else { } else {
$this->Manager->runGroupTest(ucfirst($this->params['group']), $Reporter); $this->Manager->runGroupTest(ucfirst($this->params['group']), $Reporter, $this->params['codeCoverage']);
} }
} }
@ -250,6 +270,6 @@ class CakeTestSuiteDispatcher {
if ($this->params['codeCoverage']) { if ($this->params['codeCoverage']) {
CodeCoverageManager::init($this->params['case'], $Reporter); CodeCoverageManager::init($this->params['case'], $Reporter);
} }
$this->Manager->runTestCase($this->params['case'], $Reporter); $this->Manager->runTestCase($this->params['case'], $Reporter, $this->params['codeCoverage']);
} }
} }

View file

@ -18,13 +18,15 @@
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/ */
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
/** /**
* CakeBaseReporter contains common reporting features used in the CakePHP Test suite * CakeBaseReporter contains common reporting features used in the CakePHP Test suite
* *
* @package cake * @package cake
* @subpackage cake.tests.lib * @subpackage cake.tests.lib
*/ */
class CakeBaseReporter extends SimpleReporter { class CakeBaseReporter {
/** /**
* Time the test runs started. * Time the test runs started.
@ -65,6 +67,10 @@ class CakeBaseReporter extends SimpleReporter {
*/ */
protected $_characterSet; protected $_characterSet;
/**
* The number of assertions done for a test suite
*/
protected $numAssertions = 0;
/** /**
* Does nothing yet. The first output will * Does nothing yet. The first output will
* be sent on the first test start. * be sent on the first test start.
@ -81,7 +87,6 @@ class CakeBaseReporter extends SimpleReporter {
* @param array $params Array of request parameters the reporter should use. See above. * @param array $params Array of request parameters the reporter should use. See above.
*/ */
function __construct($charset = 'utf-8', $params = array()) { function __construct($charset = 'utf-8', $params = array()) {
parent::__construct();
if (!$charset) { if (!$charset) {
$charset = 'utf-8'; $charset = 'utf-8';
} }

View file

@ -19,6 +19,8 @@
*/ */
include_once dirname(__FILE__) . DS . 'cake_base_reporter.php'; include_once dirname(__FILE__) . DS . 'cake_base_reporter.php';
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
/** /**
* CakeHtmlReporter Reports Results of TestSuites and Test Cases * CakeHtmlReporter Reports Results of TestSuites and Test Cases
* in an HTML format / context. * in an HTML format / context.
@ -26,30 +28,19 @@ include_once dirname(__FILE__) . DS . 'cake_base_reporter.php';
* @package cake * @package cake
* @subpackage cake.tests.lib * @subpackage cake.tests.lib
*/ */
class CakeHtmlReporter extends CakeBaseReporter {
/** class CakeHtmlReporter extends CakeBaseReporter implements PHPUnit_Framework_TestListener {
* Constructor
*
* @param string $charset
* @param string $params
* @return void
*/
function __construct($charset = 'utf-8', $params = array()) {
$params = array_map(array($this, '_htmlEntities'), $params);
parent::__construct($charset, $params);
}
/** /**
* Paints the top of the web page setting the * Paints the top of the web page setting the
* title to the name of the starting test. * title to the name of the starting test.
* *
* @param string $test_name Name class of test.
* @return void * @return void
*/ */
public function paintHeader($testName) { public function paintHeader() {
$this->sendNoCacheHeaders(); $this->sendNoCacheHeaders();
$this->paintDocumentStart(); $this->paintDocumentStart();
$this->paintTestMenu(); $this->paintTestMenu();
printf("<h2>%s</h2>\n", $this->_htmlEntities($testName));
echo "<ul class='tests'>\n"; echo "<ul class='tests'>\n";
} }
@ -165,31 +156,32 @@ class CakeHtmlReporter extends CakeBaseReporter {
* @param string $test_name Name class of test. * @param string $test_name Name class of test.
* @return void * @return void
*/ */
public function paintFooter($test_name) { public function paintFooter($result) {
$colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green"); $colour = ($result->failureCount() + $result->errorCount() > 0 ? "red" : "green");
echo "</ul>\n"; echo "</ul>\n";
echo "<div style=\""; echo "<div style=\"";
echo "padding: 8px; margin: 1em 0; background-color: $colour; color: white;"; echo "padding: 8px; margin: 1em 0; background-color: $colour; color: white;";
echo "\">"; echo "\">";
echo $this->getTestCaseProgress() . "/" . $this->getTestCaseCount(); echo $result->count() . "/" . $result->count() - $result->skippedCount();
echo " test cases complete:\n"; echo " test methods complete:\n";
echo "<strong>" . $this->getPassCount() . "</strong> passes, "; echo "<strong>" . count($result->passed()) . "</strong> passes, ";
echo "<strong>" . $this->getFailCount() . "</strong> fails and "; echo "<strong>" . $result->failureCount() . "</strong> fails, ";
echo "<strong>" . $this->getExceptionCount() . "</strong> exceptions."; echo "<strong>" . $this->numAssertions . "</strong> assertions and ";
echo "<strong>" . $result->errorCount() . "</strong> exceptions.";
echo "</div>\n"; echo "</div>\n";
echo '<div style="padding:0 0 5px;">'; echo '<div style="padding:0 0 5px;">';
echo '<p><strong>Time taken by tests (in seconds):</strong> ' . $this->_timeDuration . '</p>'; echo '<p><strong>Time taken by tests (in seconds):</strong> ' . $result->time() . '</p>';
if (function_exists('memory_get_peak_usage')) { if (function_exists('memory_get_peak_usage')) {
echo '<p><strong>Peak memory use: (in bytes):</strong> ' . number_format(memory_get_peak_usage()) . '</p>'; echo '<p><strong>Peak memory use: (in bytes):</strong> ' . number_format(memory_get_peak_usage()) . '</p>';
} }
echo $this->_paintLinks(); echo $this->_paintLinks();
echo '</div>'; echo '</div>';
if ( if (
isset($this->params['codeCoverage']) && isset($this->params['codeCoverage']) &&
$this->params['codeCoverage'] && $this->params['codeCoverage'] &&
class_exists('CodeCoverageManager') class_exists('CodeCoverageManager')
) { ) {
CodeCoverageManager::report(); //CodeCoverageManager::report();
} }
$this->paintDocumentEnd(); $this->paintDocumentEnd();
} }
@ -257,18 +249,24 @@ class CakeHtmlReporter extends CakeBaseReporter {
* trail of the nesting test suites below the * trail of the nesting test suites below the
* top level test. * top level test.
* *
* @param string $message Failure message displayed in * @param PHPUnit_Framework_AssertionFailedError $message Failure object displayed in
* the context of the other tests. * the context of the other tests.
* @return void * @return void
*/ */
public function paintFail($message) { public function paintFail($message) {
parent::paintFail($message); $context = $message->getTrace();
$realContext = $context[3];
$context = $context[2];
echo "<li class='fail'>\n"; echo "<li class='fail'>\n";
echo "<span>Failed</span>"; echo "<span>Failed</span>";
echo "<div class='msg'>" . $this->_htmlEntities($message) . "</div>\n"; echo "<div class='msg'><pre>" . $this->_htmlEntities($message->toString()) . "</pre></div>\n";
$breadcrumb = $this->getTestList(); echo "<div class='msg'>" . sprintf(__('File: %s'), $context['file']) . "</div>\n";
array_shift($breadcrumb); echo "<div class='msg'>" . sprintf(__('Method: %s'), $realContext['function']) . "</div>\n";
echo "<div>" . implode(" -&gt; ", $breadcrumb) . "</div>\n"; echo "<div class='msg'>" . sprintf(__('Line: %s'), $context['line']) . "</div>\n";
//$breadcrumb = $this->getTestList();
//array_shift($breadcrumb);
//echo "<div>" . implode(" -&gt; ", $breadcrumb) . "</div>\n";
echo "</li>\n"; echo "</li>\n";
} }
@ -277,19 +275,18 @@ class CakeHtmlReporter extends CakeBaseReporter {
* trail of the nesting test suites below the * trail of the nesting test suites below the
* top level test. * top level test.
* *
* @param string $message Pass message displayed in the context of the other tests. * @param PHPUnit_Framework_Test test method that just passed
* @param float $time time spent to run the test method
* @return void * @return void
*/ */
public function paintPass($message) { public function paintPass(PHPUnit_Framework_Test $test, $time = null) {
parent::paintPass($message);
if (isset($this->params['show_passes']) && $this->params['show_passes']) { if (isset($this->params['show_passes']) && $this->params['show_passes']) {
echo "<li class='pass'>\n"; echo "<li class='pass'>\n";
echo "<span>Passed</span> "; echo "<span>Passed</span> ";
$breadcrumb = $this->getTestList(); //$breadcrumb = $this->getTestList();
array_shift($breadcrumb); //array_shift($breadcrumb);
echo implode(" -&gt; ", $breadcrumb); //echo implode(" -&gt; ", $breadcrumb);
echo "<br />" . $this->_htmlEntities($message) . "\n"; echo "<br />" . $this->_htmlEntities($test->getName()) . " ($time seconds)\n";
echo "</li>\n"; echo "</li>\n";
} }
} }
@ -301,7 +298,6 @@ class CakeHtmlReporter extends CakeBaseReporter {
* @return void * @return void
*/ */
public function paintError($message) { public function paintError($message) {
parent::paintError($message);
echo "<li class='error'>\n"; echo "<li class='error'>\n";
echo "<span>Error</span>"; echo "<span>Error</span>";
echo "<div class='msg'>" . $this->_htmlEntities($message) . "</div>\n"; echo "<div class='msg'>" . $this->_htmlEntities($message) . "</div>\n";
@ -318,7 +314,6 @@ class CakeHtmlReporter extends CakeBaseReporter {
* @return void * @return void
*/ */
public function paintException($exception) { public function paintException($exception) {
parent::paintException($exception);
echo "<li class='fail'>\n"; echo "<li class='fail'>\n";
echo "<span>Exception</span>"; echo "<span>Exception</span>";
$message = 'Unexpected exception of type [' . get_class($exception) . $message = 'Unexpected exception of type [' . get_class($exception) .
@ -326,9 +321,9 @@ class CakeHtmlReporter extends CakeBaseReporter {
'] in ['. $exception->getFile() . '] in ['. $exception->getFile() .
' line ' . $exception->getLine() . ']'; ' line ' . $exception->getLine() . ']';
echo "<div class='msg'>" . $this->_htmlEntities($message) . "</div>\n"; echo "<div class='msg'>" . $this->_htmlEntities($message) . "</div>\n";
$breadcrumb = $this->getTestList(); //$breadcrumb = $this->getTestList();
array_shift($breadcrumb); //array_shift($breadcrumb);
echo "<div>" . implode(" -&gt; ", $breadcrumb) . "</div>\n"; //echo "<div>" . implode(" -&gt; ", $breadcrumb) . "</div>\n";
echo "</li>\n"; echo "</li>\n";
} }
@ -339,7 +334,6 @@ class CakeHtmlReporter extends CakeBaseReporter {
* @return void * @return void
*/ */
public function paintSkip($message) { public function paintSkip($message) {
parent::paintSkip($message);
echo "<li class='skipped'>\n"; echo "<li class='skipped'>\n";
echo "<span>Skipped</span> "; echo "<span>Skipped</span> ";
echo $this->_htmlEntities($message); echo $this->_htmlEntities($message);
@ -365,4 +359,104 @@ class CakeHtmlReporter extends CakeBaseReporter {
protected function _htmlEntities($message) { protected function _htmlEntities($message) {
return htmlentities($message, ENT_COMPAT, $this->_characterSet); return htmlentities($message, ENT_COMPAT, $this->_characterSet);
} }
public function paintResult(PHPUnit_Framework_TestResult $result) {
/*if ($result->errorCount() > 0) {
$this->printErrors($result);
}
if ($result->failureCount() > 0) {
$this->printFailures($result);
}
if ($result->skippedCount() > 0) {
$this->printIncompletes($result);
}
if ($result->skippedCount() > 0) {
$this->printSkipped($result);
}*/
$this->paintFooter($result);
}
/**
* An error occurred.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {
$this->paintException($e);
}
/**
* A failure occurred.
*
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_AssertionFailedError $e
* @param float $time
*/
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) {
$this->paintFail($e);
}
/**
* Incomplete test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
}
/**
* Skipped test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
}
/**
* A test suite started.
*
* @param PHPUnit_Framework_TestSuite $suite
*/
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
echo '<h2>' . sprintf(__('Running %s'), $suite->getName()) . '</h2>';
}
/**
* A test suite ended.
*
* @param PHPUnit_Framework_TestSuite $suite
*/
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {
}
/**
* A test started.
*
* @param PHPUnit_Framework_Test $test
*/
public function startTest(PHPUnit_Framework_Test $test) {
}
/**
* A test ended.
*
* @param PHPUnit_Framework_Test $test
* @param float $time
*/
public function endTest(PHPUnit_Framework_Test $test, $time) {
$this->numAssertions += $test->getNumAssertions();
$this->paintPass($test, $time);
}
} }

View file

@ -22,6 +22,9 @@ define('CORE_TEST_GROUPS', TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'groups'
define('APP_TEST_CASES', TESTS . 'cases'); define('APP_TEST_CASES', TESTS . 'cases');
define('APP_TEST_GROUPS', TESTS . 'groups'); define('APP_TEST_GROUPS', TESTS . 'groups');
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
require_once CAKE_TESTS_LIB . 'cake_test_suite.php';
/** /**
* TestManager is the base class that handles loading and initiating the running * TestManager is the base class that handles loading and initiating the running
* of TestCase and TestSuite classes that the user has selected. * of TestCase and TestSuite classes that the user has selected.
@ -35,14 +38,14 @@ class TestManager {
* *
* @var string * @var string
*/ */
protected $_testExtension = '.test.php'; protected static $_testExtension = '.test.php';
/** /**
* Extension suffix for group test case files. * Extension suffix for group test case files.
* *
* @var string * @var string
*/ */
protected $_groupExtension = '.group.php'; protected static $_groupExtension = '.group.php';
/** /**
* Is this test an AppTest? * Is this test an AppTest?
@ -58,13 +61,28 @@ class TestManager {
*/ */
public $pluginTest = false; public $pluginTest = false;
/**
* TestSuite container for single or grouped test files
*
* @var PHPUnit_Framework_TestSuite
*/
protected $_testSuit = null;
/**
* Object instance responsible for managing the test fixtures
*
* @var CakeFixtureManager
*/
protected $_fixtureManager = null;
/** /**
* Constructor for the TestManager class * Constructor for the TestManager class
* *
* @return void * @return void
*/ */
public function __construct() { public function __construct() {
$this->_installSimpleTest(); //require_once(CAKE_TESTS_LIB . 'cake_web_test_case.php');
require_once(CAKE_TESTS_LIB . 'cake_test_case.php');
if (isset($_GET['app'])) { if (isset($_GET['app'])) {
$this->appTest = true; $this->appTest = true;
} }
@ -73,107 +91,101 @@ class TestManager {
} }
} }
/**
* Includes the required simpletest files in order for the testsuite to run
*
* @return void
*/
public function _installSimpleTest() {
App::import('Vendor', array(
'simpletest' . DS . 'unit_tester',
'simpletest' . DS . 'mock_objects',
'simpletest' . DS . 'web_tester'
));
require_once(CAKE_TESTS_LIB . 'cake_web_test_case.php');
require_once(CAKE_TESTS_LIB . 'cake_test_case.php');
}
/** /**
* Runs all tests in the Application depending on the current appTest setting * Runs all tests in the Application depending on the current appTest setting
* *
* @param Object $reporter Reporter object for the tests being run. * @param PHPUnit_Framework_TestListener $reporter Reporter instance to attach to the test case.
* @param boolean $testing Are tests supposed to be auto run. Set to true to return testcase list.
* @return mixed * @return mixed
*/ */
public function runAllTests(&$reporter, $testing = false) { public function runAllTests(&$reporter) {
$testCases = $this->_getTestFileList($this->_getTestsPath()); $testCases = $this->_getTestFileList($this->_getTestsPath());
if ($this->appTest) {
$test = new TestSuite(__('All App Tests', true));
} else if ($this->pluginTest) {
$test = new TestSuite(sprintf(__('All %s Plugin Tests', true), Inflector::humanize($this->pluginTest)));
} else {
$test = new TestSuite(__('All Core Tests', true));
}
if ($testing) { if ($this->appTest) {
return $testCases; $test = $this->getTestSuite(__('All App Tests', true));
} else if ($this->pluginTest) {
$test = $this->getTestSuite(sprintf(__('All %s Plugin Tests', true), Inflector::humanize($this->pluginTest)));
} else {
$test = $this->getTestSuite(__('All Core Tests', true));
} }
foreach ($testCases as $testCase) { foreach ($testCases as $testCase) {
$test->addTestFile($testCase); $test->addTestFile($testCase);
} }
return $test->run($reporter); return $this->run($reporter);
} }
/** /**
* Runs a specific test case file * Runs a specific test case file
* *
* @param string $testCaseFile Filename of the test to be run. * @param string $testCaseFile Filename of the test to be run.
* @param Object $reporter Reporter instance to attach to the test case. * @param PHPUnit_Framework_TestListener $reporter Reporter instance to attach to the test case.
* @param boolean $testing Set to true if testing, otherwise test case will be run. * @throws InvalidArgumentException if the supplied $testCaseFile does not exists
* @return mixed Result of test case being run. * @return mixed Result of test case being run.
*/ */
public function runTestCase($testCaseFile, &$reporter, $testing = false) { public function runTestCase($testCaseFile, PHPUnit_Framework_TestListener $reporter, $codeCoverage = false) {
$testCaseFileWithPath = $this->_getTestsPath() . DS . $testCaseFile; $testCaseFileWithPath = $this->_getTestsPath() . DS . $testCaseFile;
if (!file_exists($testCaseFileWithPath) || strpos($testCaseFileWithPath, '..')) { if (!file_exists($testCaseFileWithPath) || strpos($testCaseFileWithPath, '..')) {
trigger_error( throw new InvalidArgumentException(sprintf(__('Unable to load test file %s'), htmlentities($testCaseFile));
sprintf(__("Test case %s cannot be found", true), htmlentities($testCaseFile)),
E_USER_ERROR
);
return false;
} }
if ($testing) { $testSuite = $this->getTestSuite(sprintf(__('Individual test case: %s', true), $testCaseFile));
return true; $testSuite->addTestFile($testCaseFileWithPath);
} return $this->run($reporter, $codeCoverage);
$test = new TestSuite(sprintf(__('Individual test case: %s', true), $testCaseFile));
$test->addTestFile($testCaseFileWithPath);
return $test->run($reporter);
} }
/** /**
* Runs a specific group test file * Runs a specific group test file
* *
* @param string $groupTestName GroupTest that you want to run. * @param string $groupTestName GroupTest that you want to run.
* @param Object $reporter Reporter instance to use with the group test being run. * @param PHPUnit_Framework_TestListener $reporter Reporter instance to use with the group test being run.
* @throws InvalidArgumentException if it was not possible to locate the filename for $groupTestName
* @return mixed Results of group test being run. * @return mixed Results of group test being run.
*/ */
public function runGroupTest($groupTestName, &$reporter) { public function runGroupTest($groupTestName, $reporter, $codeCoverage = false) {
$filePath = $this->_getTestsPath('groups') . DS . strtolower($groupTestName) . $this->_groupExtension; $filePath = $this->_getTestsPath('groups') . DS . strtolower($groupTestName) . $this->getExtension('group');
if (!file_exists($filePath) || strpos($filePath, '..')) { if (!file_exists($filePath) || strpos($filePath, '..')) {
trigger_error(sprintf( throw new InvalidArgumentException(sprintf(
__("Group test %s cannot be found at %s", true), __('Group test %s cannot be found at %s', true),
htmlentities($groupTestName), htmlentities($groupTestName),
htmlentities($filePath) htmlentities($filePath)
), )
E_USER_ERROR
); );
} }
require_once $filePath; require_once $filePath;
$test = new TestSuite(sprintf(__('%s group test', true), $groupTestName)); $suite = $this->getTestSuite(sprintf(__('%s group test', true), $groupTestName));
foreach ($this->_getGroupTestClassNames($filePath) as $groupTest) { $groupClassName = Inflector::classify($groupTestName) . 'GroupTest';
$testCase = new $groupTest(); $group = new $groupClassName();
$test->addTestCase($testCase); $suite->addTestSuite($group);
if (isset($testCase->label)) { if (isset($group->label)) {
$test->_label = $testCase->label; $suite->setName($group->label);
}
} }
return $test->run($reporter);
return $this->run($reporter, $codeCoverage);
}
/**
* Runs the main testSuite and attaches to it a reporter
*
* @param PHPUnit_Framework_TestListener $reporter Reporter instance to use with the group test being run.
* @return mixed Results of group test being run.
*/
protected function run($reporter, $codeCoverage = false) {
$result = new PHPUnit_Framework_TestResult;
$result->collectCodeCoverageInformation($codeCoverage);
$result->addListener($reporter);
$reporter->paintHeader();
$testSuite = $this->getTestSuite();
$testSuite->setFixtureManager($this->getFixtureManager());
$testSuite->run($result);
$reporter->paintResult($result);
// echo '<pre>';
// var_dump($result->getCodeCoverageInformation());
// echo '</pre>';
return $result;
} }
/** /**
@ -186,8 +198,7 @@ class TestManager {
* @static * @static
*/ */
public static function addTestCasesFromDirectory(&$groupTest, $directory = '.') { public static function addTestCasesFromDirectory(&$groupTest, $directory = '.') {
$manager = new TestManager(); $testCases = self::_getTestFileList($directory);
$testCases = $manager->_getTestFileList($directory);
foreach ($testCases as $testCase) { foreach ($testCases as $testCase) {
$groupTest->addTestFile($testCase); $groupTest->addTestFile($testCase);
} }
@ -203,12 +214,10 @@ class TestManager {
* @static * @static
*/ */
public static function addTestFile(&$groupTest, $file) { public static function addTestFile(&$groupTest, $file) {
$manager = new TestManager(); if (file_exists($file . self::$_testExtension)) {
$file .= self::$_testExtension;
if (file_exists($file . $manager->_testExtension)) { } elseif (file_exists($file . self::$_groupExtension)) {
$file .= $manager->_testExtension; $file .= self::$_groupExtension;
} elseif (file_exists($file . $manager->_groupExtension)) {
$file .= $manager->_groupExtension;
} }
$groupTest->addTestFile($file); $groupTest->addTestFile($file);
} }
@ -219,9 +228,8 @@ class TestManager {
* @access public * @access public
* @static * @static
*/ */
function &getTestCaseList() { public static function &getTestCaseList() {
$manager = new TestManager(); $return = self::_getTestCaseList(self::_getTestsPath());
$return = $manager->_getTestCaseList($manager->_getTestsPath());
return $return; return $return;
} }
@ -229,9 +237,10 @@ class TestManager {
* Builds the list of test cases from a given directory * Builds the list of test cases from a given directory
* *
* @param string $directory Directory to get test case list from. * @param string $directory Directory to get test case list from.
* @static
*/ */
protected function &_getTestCaseList($directory = '.') { protected static function &_getTestCaseList($directory = '.') {
$fileList = $this->_getTestFileList($directory); $fileList = self::_getTestFileList($directory);
$testCases = array(); $testCases = array();
foreach ($fileList as $testCaseFile) { foreach ($fileList as $testCaseFile) {
$testCases[$testCaseFile] = str_replace($directory . DS, '', $testCaseFile); $testCases[$testCaseFile] = str_replace($directory . DS, '', $testCaseFile);
@ -243,9 +252,10 @@ class TestManager {
* Returns a list of test files from a given directory * Returns a list of test files from a given directory
* *
* @param string $directory Directory to get test case files from. * @param string $directory Directory to get test case files from.
* @static
*/ */
protected function &_getTestFileList($directory = '.') { protected static function &_getTestFileList($directory = '.') {
$return = $this->_getRecursiveFileList($directory, array(&$this, '_isTestCaseFile')); $return = self::_getRecursiveFileList($directory, 'self::_isTestCaseFile');
return $return; return $return;
} }
@ -255,9 +265,8 @@ class TestManager {
* @access public * @access public
* @static * @static
*/ */
function &getGroupTestList() { public static function &getGroupTestList() {
$manager = new TestManager(); $return = self::_getTestGroupList(self::_getTestsPath('groups'));
$return = $manager->_getTestGroupList($manager->_getTestsPath('groups'));
return $return; return $return;
} }
@ -265,9 +274,10 @@ class TestManager {
* Returns a list of group test files from a given directory * Returns a list of group test files from a given directory
* *
* @param string $directory The directory to get group test files from. * @param string $directory The directory to get group test files from.
* @static
*/ */
protected function &_getTestGroupFileList($directory = '.') { protected static function &_getTestGroupFileList($directory = '.') {
$return = $this->_getRecursiveFileList($directory, array(&$this, '_isTestGroupFile')); $return = self::_getRecursiveFileList($directory, 'self::_isTestGroupFile');
return $return; return $return;
} }
@ -275,33 +285,19 @@ class TestManager {
* Returns a list of group test files from a given directory * Returns a list of group test files from a given directory
* *
* @param string $directory The directory to get group tests from. * @param string $directory The directory to get group tests from.
* @static
*/ */
protected function &_getTestGroupList($directory = '.') { protected static function &_getTestGroupList($directory = '.') {
$fileList = $this->_getTestGroupFileList($directory); $fileList = self::_getTestGroupFileList($directory);
$groupTests = array(); $groupTests = array();
foreach ($fileList as $groupTestFile) { foreach ($fileList as $groupTestFile) {
$groupTests[$groupTestFile] = str_replace($this->_groupExtension, '', basename($groupTestFile)); $groupTests[$groupTestFile] = str_replace(self::$_groupExtension, '', basename($groupTestFile));
} }
sort($groupTests); sort($groupTests);
return $groupTests; return $groupTests;
} }
/**
* Returns a list of class names from a group test file
*
* @param string $groupTestFile The groupTest file to scan for TestSuite classnames.
*/
protected function &_getGroupTestClassNames($groupTestFile) {
$file = implode("\n", file($groupTestFile));
preg_match("~lass\s+?(.*)\s+?extends TestSuite~", $file, $matches);
if (!empty($matches)) {
unset($matches[0]);
return $matches;
}
$matches = array();
return $matches;
}
/** /**
* Gets a recursive list of files from a given directory and matches then against * Gets a recursive list of files from a given directory and matches then against
@ -309,20 +305,23 @@ class TestManager {
* *
* @param string $directory The directory to scan for files. * @param string $directory The directory to scan for files.
* @param mixed $fileTestFunction * @param mixed $fileTestFunction
* @static
*/ */
protected function &_getRecursiveFileList($directory = '.', $fileTestFunction) { protected static function &_getRecursiveFileList($directory = '.', $fileTestFunction) {
$fileList = array(); $fileList = array();
if (!is_dir($directory)) { if (!is_dir($directory)) {
return $fileList; return $fileList;
} }
$files = glob($directory . DS . '*'); $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
$files = $files ? $files : array();
foreach ($files as $file) { foreach ($files as $file) {
if (is_dir($file)) { if (!$file->isFile()) {
$fileList = array_merge($fileList, $this->_getRecursiveFileList($file, $fileTestFunction)); continue;
} elseif ($fileTestFunction[0]->$fileTestFunction[1]($file)) { }
$file = $file->getRealPath();
if (call_user_func_array($fileTestFunction, array($file))) {
$fileList[] = $file; $fileList[] = $file;
} }
} }
@ -334,9 +333,10 @@ class TestManager {
* *
* @param string $file * @param string $file
* @return boolean Whether $file is a test case. * @return boolean Whether $file is a test case.
* @static
*/ */
protected function _isTestCaseFile($file) { protected static function _isTestCaseFile($file) {
return $this->_hasExpectedExtension($file, $this->_testExtension); return self::_hasExpectedExtension($file, self::$_testExtension);
} }
/** /**
@ -344,9 +344,10 @@ class TestManager {
* *
* @param string $file * @param string $file
* @return boolean Whether $file is a group * @return boolean Whether $file is a group
* @static
*/ */
protected function _isTestGroupFile($file) { protected static function _isTestGroupFile($file) {
return $this->_hasExpectedExtension($file, $this->_groupExtension); return static::_hasExpectedExtension($file, static::$_groupExtension);
} }
/** /**
@ -355,8 +356,9 @@ class TestManager {
* @param string $file * @param string $file
* @param string $extension * @param string $extension
* @return void * @return void
* @static
*/ */
protected function _hasExpectedExtension($file, $extension) { protected static function _hasExpectedExtension($file, $extension) {
return $extension == strtolower(substr($file, (0 - strlen($extension)))); return $extension == strtolower(substr($file, (0 - strlen($extension))));
} }
@ -365,17 +367,18 @@ class TestManager {
* *
* @param string $type either 'cases' or 'groups' * @param string $type either 'cases' or 'groups'
* @return string The path tests are located on * @return string The path tests are located on
* @static
*/ */
protected function _getTestsPath($type = 'cases') { protected static function _getTestsPath($type = 'cases') {
if (!empty($this->appTest)) { if (!empty(self::$appTest)) {
if ($type == 'cases') { if ($type == 'cases') {
$result = APP_TEST_CASES; $result = APP_TEST_CASES;
} else if ($type == 'groups') { } else if ($type == 'groups') {
$result = APP_TEST_GROUPS; $result = APP_TEST_GROUPS;
} }
} else if (!empty($this->pluginTest)) { } else if (!empty(self::$pluginTest)) {
$_pluginBasePath = APP . 'plugins/' . $this->pluginTest . '/tests'; $_pluginBasePath = APP . 'plugins/' . self::$pluginTest . '/tests';
$pluginPath = App::pluginPath($this->pluginTest); $pluginPath = App::pluginPath(self::$pluginTest);
if (file_exists($pluginPath . DS . 'tests')) { if (file_exists($pluginPath . DS . 'tests')) {
$_pluginBasePath = $pluginPath . DS . 'tests'; $_pluginBasePath = $pluginPath . DS . 'tests';
} }
@ -396,10 +399,35 @@ class TestManager {
* @param string $type Type of test to get, either 'test' or 'group' * @param string $type Type of test to get, either 'test' or 'group'
* @return string Extension suffix for test. * @return string Extension suffix for test.
*/ */
public function getExtension($type = 'test') { public static function getExtension($type = 'test') {
if ($type == 'test' || $type == 'case') { if ($type == 'test' || $type == 'case') {
return $this->_testExtension; return self::$_testExtension;
} }
return $this->_groupExtension; return self::$_groupExtension;
}
/**
* Get the container testSuite instance for this runner or creates a new one
*
* @param string $name The name for the container test suite
* @return PHPUnit_Framework_TestSuite container test suite
*/
protected function getTestSuite($name = '') {
if (!empty($this->_testSuite)) {
return $this->_testSuite;
}
return $this->_testSuite = new CakeTestSuite($name);
}
/**
* Get an instance of a Fixture manager to be used by the test cases
*
* @return CakeFixtureManager fixture manager
*/
protected function getFixtureManager() {
if (!empty($this->_fixtureManager)) {
return $this->_fixtureManager;
}
return $this->_fixtureManager = new CakeFixtureManager;
} }
} }