Upgrade CakePHP from 2.2.5 to 2.9.5

This commit is contained in:
Brm Ko 2017-02-26 15:29:44 +01:00
parent 5a580df460
commit 235a541597
793 changed files with 60746 additions and 23753 deletions

View file

@ -2,20 +2,20 @@
/**
* CakeTestCase file
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite
* @since CakePHP(tm) v 1.2.0.4667
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('CakeFixtureManager', 'TestSuite/Fixture');
App::uses('CakeTestFixture', 'TestSuite/Fixture');
@ -42,9 +42,13 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
public $autoFixtures = true;
/**
* Set this to false to avoid tables to be dropped if they already exist
* Control table create/drops on each test method.
*
* @var boolean
* Set this to false to avoid tables to be dropped if they already exist
* between each test method. Tables will still be dropped at the
* end of each test runner execution.
*
* @var bool
*/
public $dropTables = true;
@ -67,7 +71,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* If no TestResult object is passed a new one will be created.
* This method is run for each test method in this class
*
* @param PHPUnit_Framework_TestResult $result
* @param PHPUnit_Framework_TestResult $result The test result object
* @return PHPUnit_Framework_TestResult
* @throws InvalidArgumentException
*/
@ -103,9 +107,9 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
/**
* Overrides SimpleTestCase::skipIf to provide a boolean return value
*
* @param boolean $shouldSkip
* @param string $message
* @return boolean
* @param bool $shouldSkip Whether or not the test should be skipped.
* @param string $message The message to display.
* @return bool
*/
public function skipIf($shouldSkip, $message = '') {
if ($shouldSkip) {
@ -170,7 +174,6 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
/**
* Announces the start of a test.
*
* @param string $method Test method just started.
* @return void
*/
protected function assertPreConditions() {
@ -181,7 +184,6 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
/**
* Announces the end of a test.
*
* @param string $method Test method just finished.
* @return void
*/
protected function assertPostConditions() {
@ -194,8 +196,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
/**
* Chooses which fixtures to load for a given test
*
* @param string $fixture Each parameter is a model name that corresponds to a
* fixture, i.e. 'Post', 'Author', etc.
* Each parameter is a model name that corresponds to a fixture, i.e. 'Post', 'Author', etc.
*
* @return void
* @see CakeTestCase::$autoFixtures
* @throws Exception when no fixture manager is available.
@ -206,7 +208,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
}
$args = func_get_args();
foreach ($args as $class) {
$this->fixtureManager->loadSingle($class);
$this->fixtureManager->loadSingle($class, null, $this->dropTables);
}
}
@ -216,8 +218,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
*
* @param string $expected The expected value.
* @param string $result The actual value.
* @param message The message to use for failure.
* @return boolean
* @param string $message The message to use for failure.
* @return bool
*/
public function assertTextNotEquals($expected, $result, $message = '') {
$expected = str_replace(array("\r\n", "\r"), "\n", $expected);
@ -231,8 +233,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
*
* @param string $expected The expected value.
* @param string $result The actual value.
* @param message The message to use for failure.
* @return boolean
* @param string $message message The message to use for failure.
* @return bool
*/
public function assertTextEquals($expected, $result, $message = '') {
$expected = str_replace(array("\r\n", "\r"), "\n", $expected);
@ -244,10 +246,10 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* Asserts that a string starts with a given prefix, ignoring differences in newlines.
* Helpful for doing cross platform tests of blocks of text.
*
* @param string $prefix
* @param string $string
* @param string $message
* @return boolean
* @param string $prefix The prefix to check for.
* @param string $string The string to search in.
* @param string $message The message to use for failure.
* @return bool
*/
public function assertTextStartsWith($prefix, $string, $message = '') {
$prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
@ -259,10 +261,10 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* Asserts that a string starts not with a given prefix, ignoring differences in newlines.
* Helpful for doing cross platform tests of blocks of text.
*
* @param string $prefix
* @param string $string
* @param string $message
* @return boolean
* @param string $prefix The prefix to not find.
* @param string $string The string to search.
* @param string $message The message to use for failure.
* @return bool
*/
public function assertTextStartsNotWith($prefix, $string, $message = '') {
$prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
@ -274,10 +276,10 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* Asserts that a string ends with a given prefix, ignoring differences in newlines.
* Helpful for doing cross platform tests of blocks of text.
*
* @param string $suffix
* @param string $string
* @param string $message
* @return boolean
* @param string $suffix The suffix to find.
* @param string $string The string to search.
* @param string $message The message to use for failure.
* @return bool
*/
public function assertTextEndsWith($suffix, $string, $message = '') {
$suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
@ -289,10 +291,10 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* Asserts that a string ends not with a given prefix, ignoring differences in newlines.
* Helpful for doing cross platform tests of blocks of text.
*
* @param string $suffix
* @param string $string
* @param string $message
* @return boolean
* @param string $suffix The suffix to not find.
* @param string $string The string to search.
* @param string $message The message to use for failure.
* @return bool
*/
public function assertTextEndsNotWith($suffix, $string, $message = '') {
$suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
@ -304,11 +306,11 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* Assert that a string contains another string, ignoring differences in newlines.
* Helpful for doing cross platform tests of blocks of text.
*
* @param string $needle
* @param string $haystack
* @param string $message
* @param boolean $ignoreCase
* @return boolean
* @param string $needle The string to search for.
* @param string $haystack The string to search through.
* @param string $message The message to display on failure.
* @param bool $ignoreCase Whether or not the search should be case-sensitive.
* @return bool
*/
public function assertTextContains($needle, $haystack, $message = '', $ignoreCase = false) {
$needle = str_replace(array("\r\n", "\r"), "\n", $needle);
@ -320,11 +322,11 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* Assert that a text doesn't contain another text, ignoring differences in newlines.
* Helpful for doing cross platform tests of blocks of text.
*
* @param string $needle
* @param string $haystack
* @param string $message
* @param boolean $ignoreCase
* @return boolean
* @param string $needle The string to search for.
* @param string $haystack The string to search through.
* @param string $message The message to display on failure.
* @param bool $ignoreCase Whether or not the search should be case-sensitive.
* @return bool
*/
public function assertTextNotContains($needle, $haystack, $message = '', $ignoreCase = false) {
$needle = str_replace(array("\r\n", "\r"), "\n", $needle);
@ -338,32 +340,41 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
*
* Checks for an input tag with a name attribute (contains any non-empty value) and an id
* attribute that contains 'my-input':
* array('input' => array('name', 'id' => 'my-input'))
*
* ```
* array('input' => array('name', 'id' => 'my-input'))
* ```
*
* Checks for two p elements with some text in them:
* array(
* array('p' => true),
* 'textA',
* '/p',
* array('p' => true),
* 'textB',
* '/p'
* )
*
* ```
* array(
* array('p' => true),
* 'textA',
* '/p',
* array('p' => true),
* 'textB',
* '/p'
* )
* ```
*
* You can also specify a pattern expression as part of the attribute values, or the tag
* being defined, if you prepend the value with preg: and enclose it with slashes, like so:
* array(
* array('input' => array('name', 'id' => 'preg:/FieldName\d+/')),
* 'preg:/My\s+field/'
* )
*
* ```
* array(
* array('input' => array('name', 'id' => 'preg:/FieldName\d+/')),
* 'preg:/My\s+field/'
* )
* ```
*
* Important: This function is very forgiving about whitespace and also accepts any
* permutation of attribute order. It will also allow whitespace between specified tags.
*
* @param string $string An HTML/XHTML/XML string
* @param array $expected An array, see above
* @param string $message SimpleTest failure output string
* @return boolean
* @param string $fullDebug Whether or not more verbose output should be used.
* @return bool
*/
public function assertTags($string, $expected, $fullDebug = false) {
$regex = array();
@ -381,7 +392,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
$tags = (string)$tags;
}
$i++;
if (is_string($tags) && $tags{0} == '<') {
if (is_string($tags) && $tags{0} === '<') {
$tags = array(substr($tags, 1) => array());
} elseif (is_string($tags)) {
$tagsTrimmed = preg_replace('/\s+/m', '', $tags);
@ -389,12 +400,12 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
$prefix = array(null, null);
if ($match[0] == '*/') {
if ($match[0] === '*/') {
$prefix = array('Anything, ', '.*?');
}
$regex[] = array(
sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))),
sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))),
$i,
);
continue;
@ -437,8 +448,13 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
$val = '.+?';
$explanations[] = sprintf('Attribute "%s" present', $attr);
} elseif (!empty($val) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
$quotes = '["\']?';
$val = $matches[1];
$val = str_replace(
array('.*', '.+'),
array('.*?', '.+?'),
$matches[1]
);
$quotes = $val !== $matches[1] ? '["\']' : '["\']?';
$explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
} else {
$explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
@ -449,16 +465,9 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
$i++;
}
if ($attrs) {
$permutations = $this->_arrayPermute($attrs);
$permutationTokens = array();
foreach ($permutations as $permutation) {
$permutationTokens[] = implode('', $permutation);
}
$regex[] = array(
sprintf('%s', implode(', ', $explanations)),
$permutationTokens,
$i,
'explains' => $explanations,
'attrs' => $attrs,
);
}
$regex[] = array(
@ -468,9 +477,14 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
);
}
}
foreach ($regex as $i => $assertation) {
list($description, $expressions, $itemNum) = $assertation;
foreach ($regex as $i => $assertion) {
$matches = false;
if (isset($assertion['attrs'])) {
$string = $this->_assertAttributes($assertion, $string);
continue;
}
list($description, $expressions, $itemNum) = $assertion;
foreach ((array)$expressions as $expression) {
if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) {
$matches = true;
@ -493,30 +507,33 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
}
/**
* Generates all permutation of an array $items and returns them in a new array.
* Check the attributes as part of an assertTags() check.
*
* @param array $items An array of items
* @return array
* @param array $assertions Assertions to run.
* @param string $string The HTML string to check.
* @return void
*/
protected function _arrayPermute($items, $perms = array()) {
static $permuted;
if (empty($perms)) {
$permuted = array();
}
if (empty($items)) {
$permuted[] = $perms;
} else {
$numItems = count($items) - 1;
for ($i = $numItems; $i >= 0; --$i) {
$newItems = $items;
$newPerms = $perms;
list($tmp) = array_splice($newItems, $i, 1);
array_unshift($newPerms, $tmp);
$this->_arrayPermute($newItems, $newPerms);
protected function _assertAttributes($assertions, $string) {
$asserts = $assertions['attrs'];
$explains = $assertions['explains'];
$len = count($asserts);
do {
$matches = false;
foreach ($asserts as $j => $assert) {
if (preg_match(sprintf('/^%s/s', $assert), $string, $match)) {
$matches = true;
$string = substr($string, strlen($match[0]));
array_splice($asserts, $j, 1);
array_splice($explains, $j, 1);
break;
}
}
return $permuted;
}
if ($matches === false) {
$this->assertTrue(false, 'Attribute did not match. Was expecting ' . $explains[$j]);
}
$len = count($asserts);
} while ($len > 0);
return $string;
}
// @codingStandardsIgnoreStart
@ -524,14 +541,14 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
/**
* Compatibility wrapper function for assertEquals
*
*
* @param mixed $result
* @param mixed $expected
* @param string $message the text to display if the assertion is not correct
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected static function assertEqual($result, $expected, $message = '') {
return self::assertEquals($expected, $result, $message);
return static::assertEquals($expected, $result, $message);
}
/**
@ -540,10 +557,11 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param mixed $result
* @param mixed $expected
* @param string $message the text to display if the assertion is not correct
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected static function assertNotEqual($result, $expected, $message = '') {
return self::assertNotEquals($expected, $result, $message);
return static::assertNotEquals($expected, $result, $message);
}
/**
@ -552,10 +570,11 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @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
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected static function assertPattern($pattern, $string, $message = '') {
return self::assertRegExp($pattern, $string, $message);
return static::assertRegExp($pattern, $string, $message);
}
/**
@ -564,10 +583,11 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param mixed $actual
* @param mixed $expected
* @param string $message the text to display if the assertion is not correct
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected static function assertIdentical($actual, $expected, $message = '') {
return self::assertSame($expected, $actual, $message);
return static::assertSame($expected, $actual, $message);
}
/**
@ -576,10 +596,11 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param mixed $actual
* @param mixed $expected
* @param string $message the text to display if the assertion is not correct
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected static function assertNotIdentical($actual, $expected, $message = '') {
return self::assertNotSame($expected, $actual, $message);
return static::assertNotSame($expected, $actual, $message);
}
/**
@ -588,12 +609,19 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @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
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected static function assertNoPattern($pattern, $string, $message = '') {
return self::assertNotRegExp($pattern, $string, $message);
return static::assertNotRegExp($pattern, $string, $message);
}
/**
* assert no errors
*
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected function assertNoErrors() {
}
@ -602,6 +630,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
*
* @param mixed $expected the name of the Exception or error
* @param string $message the text to display if the assertion is not correct
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected function expectError($expected = false, $message = '') {
@ -614,8 +643,9 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
/**
* Compatibility wrapper function for setExpectedException
*
* @param mixed $expected the name of the Exception
* @param mixed $name The name of the expected Exception.
* @param string $message the text to display if the assertion is not correct
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0.
* @return void
*/
protected function expectException($name = 'Exception', $message = '') {
@ -628,10 +658,11 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param mixed $first
* @param mixed $second
* @param string $message the text to display if the assertion is not correct
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected static function assertReference(&$first, &$second, $message = '') {
return self::assertSame($first, $second, $message);
return static::assertSame($first, $second, $message);
}
/**
@ -640,10 +671,11 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
* @param string $object
* @param string $type
* @param string $message
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
* @return void
*/
protected static function assertIsA($object, $type, $message = '') {
return self::assertInstanceOf($type, $object, $message);
return static::assertInstanceOf($type, $object, $message);
}
/**
@ -658,15 +690,15 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
protected static function assertWithinMargin($result, $expected, $margin, $message = '') {
$upper = $result + $margin;
$lower = $result - $margin;
return self::assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
return static::assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
}
/**
* Compatibility function for skipping.
*
* @param boolean $condition Condition to trigger skipping
* @param bool $condition Condition to trigger skipping
* @param string $message Message for skip
* @return boolean
* @return bool
*/
protected function skipUnless($condition, $message = '') {
if (!$condition) {
@ -676,4 +708,41 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
}
// @codingStandardsIgnoreEnd
/**
* Mock a model, maintain fixtures and table association
*
* @param string $model The model to get a mock for.
* @param mixed $methods The list of methods to mock
* @param array $config The config data for the mock's constructor.
* @throws MissingModelException
* @return Model
*/
public function getMockForModel($model, $methods = array(), $config = array()) {
$defaults = ClassRegistry::config('Model');
unset($defaults['ds']);
list($plugin, $name) = pluginSplit($model, true);
App::uses($name, $plugin . 'Model');
$config = array_merge($defaults, (array)$config, array('name' => $name));
if (!class_exists($name)) {
throw new MissingModelException(array($model));
}
$mock = $this->getMock($name, $methods, array($config));
$availableDs = array_keys(ConnectionManager::enumConnectionObjects());
if ($mock->useDbConfig !== 'test' && in_array('test_' . $mock->useDbConfig, $availableDs)) {
$mock->setDataSource('test_' . $mock->useDbConfig);
} else {
$mock->useDbConfig = 'test';
$mock->setDataSource('test');
}
ClassRegistry::removeObject($name);
ClassRegistry::addObject($name, $mock);
return $mock;
}
}

View file

@ -4,18 +4,17 @@
*
* Turns partial paths used on the testsuite console and web UI into full file paths.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @package Cake.TestSuite
*/
@ -31,8 +30,8 @@ class CakeTestLoader extends PHPUnit_Runner_StandardTestSuiteLoader {
/**
* Load a file and find the first test case / suite in that file.
*
* @param string $filePath
* @param string $params
* @param string $filePath The file path to load
* @param string $params Additional parameters
* @return ReflectionClass
*/
public function load($filePath, $params = '') {
@ -41,9 +40,11 @@ class CakeTestLoader extends PHPUnit_Runner_StandardTestSuiteLoader {
}
/**
* Convert path fragments used by Cake's test runner to absolute paths that can be fed to PHPUnit.
* Convert path fragments used by CakePHP's test runner to absolute paths that can be fed to PHPUnit.
*
* @return void
* @param string $filePath The file path to load.
* @param string $params Additional parameters.
* @return string Converted path fragments.
*/
protected function _resolveTestFile($filePath, $params) {
$basePath = $this->_basePath($params) . DS . $filePath;
@ -54,7 +55,7 @@ class CakeTestLoader extends PHPUnit_Runner_StandardTestSuiteLoader {
/**
* Generates the base path to a set of tests based on the parameters.
*
* @param array $params
* @param array $params The path parameters.
* @return string The base path.
*/
protected static function _basePath($params) {
@ -80,11 +81,12 @@ class CakeTestLoader extends PHPUnit_Runner_StandardTestSuiteLoader {
/**
* Get the list of files for the test listing.
*
* @return void
* @param string $params Path parameters
* @return array
*/
public static function generateTestList($params) {
$directory = self::_basePath($params);
$fileList = self::_getRecursiveFileList($directory);
$directory = static::_basePath($params);
$fileList = static::_getRecursiveFileList($directory);
$testCases = array();
foreach ($fileList as $testCaseFile) {
@ -101,7 +103,7 @@ class CakeTestLoader extends PHPUnit_Runner_StandardTestSuiteLoader {
* a given fileTestFunction, like isTestCaseFile()
*
* @param string $directory The directory to scan for files.
* @param mixed $fileTestFunction
* @return array
*/
protected static function _getRecursiveFileList($directory = '.') {
$fileList = array();

View file

@ -2,34 +2,37 @@
/**
* TestRunner for CakePHP Test suite.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
require_once 'PHPUnit/TextUI/TestRunner.php';
if (!defined('__PHPUNIT_PHAR__')) {
require_once 'PHPUnit/TextUI/TestRunner.php';
}
App::uses('CakeFixtureManager', 'TestSuite/Fixture');
/**
* A custom test runner for Cake's use of PHPUnit.
* A custom test runner for CakePHP's use of PHPUnit.
*
* @package Cake.TestSuite
*/
class CakeTestRunner extends PHPUnit_TextUI_TestRunner {
/**
* Lets us pass in some options needed for cake's webrunner.
* Lets us pass in some options needed for CakePHP's webrunner.
*
* @return void
* @param mixed $loader The test suite loader
* @param array $params list of options to be used for this run
*/
public function __construct($loader, $params) {
parent::__construct($loader);
@ -37,15 +40,15 @@ class CakeTestRunner extends PHPUnit_TextUI_TestRunner {
}
/**
* Actually run a suite of tests. Cake initializes fixtures here using the chosen fixture manager
* Actually run a suite of tests. Cake initializes fixtures here using the chosen fixture manager
*
* @param PHPUnit_Framework_Test $suite
* @param array $arguments
* @param PHPUnit_Framework_Test $suite The test suite to run
* @param array $arguments The CLI arguments
* @return void
*/
public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array()) {
if (isset($arguments['printer'])) {
self::$versionStringPrinted = true;
static::$versionStringPrinted = true;
}
$fixture = $this->_getFixtureManager($arguments);
@ -84,7 +87,8 @@ class CakeTestRunner extends PHPUnit_TextUI_TestRunner {
/**
* Get the fixture manager class specified or use the default one.
*
* @return instance of a fixture manager.
* @param array $arguments The CLI arguments.
* @return mixed instance of a fixture manager.
* @throws RuntimeException When fixture manager class cannot be loaded.
*/
protected function _getFixtureManager($arguments) {

View file

@ -2,19 +2,18 @@
/**
* A class to contain test cases and run them with shared fixtures
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.TestSuite
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('Folder', 'Utility');
@ -34,7 +33,7 @@ class CakeTestSuite extends PHPUnit_Framework_TestSuite {
*/
public function addTestDirectory($directory = '.') {
$Folder = new Folder($directory);
list($dirs, $files) = $Folder->read(true, true, true);
list(, $files) = $Folder->read(true, true, true);
foreach ($files as $file) {
if (substr($file, -4) === '.php') {

View file

@ -2,22 +2,23 @@
/**
* TestRunner for CakePHP Test suite.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.TestSuite
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
require_once 'PHPUnit/TextUI/Command.php';
if (!defined('__PHPUNIT_PHAR__')) {
require_once 'PHPUnit/TextUI/Command.php';
}
App::uses('CakeTestRunner', 'TestSuite');
App::uses('CakeTestLoader', 'TestSuite');
@ -36,6 +37,7 @@ class CakeTestSuiteCommand extends PHPUnit_TextUI_Command {
/**
* Construct method
*
* @param mixed $loader The loader instance to use.
* @param array $params list of options to be used for this run
* @throws MissingTestLoaderException When a loader class could not be found.
*/
@ -53,10 +55,11 @@ class CakeTestSuiteCommand extends PHPUnit_TextUI_Command {
}
/**
* Ugly hack to get around PHPUnit having a hard coded classname for the Runner. :(
* Ugly hack to get around PHPUnit having a hard coded class name for the Runner. :(
*
* @param array $argv
* @param boolean $exit
* @param array $argv The command arguments
* @param bool $exit The exit mode.
* @return void
*/
public function run(array $argv, $exit = true) {
$this->handleArguments($argv);
@ -73,24 +76,6 @@ class CakeTestSuiteCommand extends PHPUnit_TextUI_Command {
);
}
if (count($suite) == 0) {
$skeleton = new PHPUnit_Util_Skeleton_Test(
$suite->getName(),
$this->arguments['testFile']
);
$result = $skeleton->generate(true);
if (!$result['incomplete']) {
//@codingStandardsIgnoreStart
eval(str_replace(array('<?php', '?>'), '', $result['code']));
//@codingStandardsIgnoreEnd
$suite = new PHPUnit_Framework_TestSuite(
$this->arguments['test'] . 'Test'
);
}
}
if ($this->arguments['listGroups']) {
PHPUnit_TextUI_TestRunner::printVersionString();
@ -120,20 +105,19 @@ class CakeTestSuiteCommand extends PHPUnit_TextUI_Command {
exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
} elseif (!isset($result) || $result->errorCount() > 0) {
exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
} else {
exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
}
exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
}
}
/**
* Create a runner for the command.
*
* @param $loader The loader to be used for the test run.
* @param mixed $loader The loader to be used for the test run.
* @return CakeTestRunner
*/
public function getRunner($loader) {
return new CakeTestRunner($loader, $this->_params);
return new CakeTestRunner($loader, $this->_params);
}
/**
@ -149,12 +133,12 @@ class CakeTestSuiteCommand extends PHPUnit_TextUI_Command {
/**
* Handles output flag used to change printing on webrunner.
*
* @param string $reporter The reporter class to use.
* @return void
*/
public function handleReporter($reporter) {
$object = null;
$type = strtolower($reporter);
$reporter = ucwords($reporter);
$coreClass = 'Cake' . $reporter . 'Reporter';
App::uses($coreClass, 'TestSuite/Reporter');

View file

@ -2,19 +2,18 @@
/**
* CakeTestSuiteDispatcher controls dispatching TestSuite web based requests.
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.TestSuite
* @since CakePHP(tm) v 1.3
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
define('CORE_TEST_CASES', CAKE . 'Test' . DS . 'Case');
@ -38,7 +37,7 @@ class CakeTestSuiteDispatcher {
'codeCoverage' => false,
'case' => null,
'core' => false,
'app' => true,
'app' => false,
'plugin' => null,
'output' => 'html',
'show' => 'groups',
@ -55,7 +54,7 @@ class CakeTestSuiteDispatcher {
protected $_baseUrl;
/**
* Base dir of the request. Used for accessing assets.
* Base dir of the request. Used for accessing assets.
*
* @var string
*/
@ -64,7 +63,7 @@ class CakeTestSuiteDispatcher {
/**
* boolean to set auto parsing of params.
*
* @var boolean
* @var bool
*/
protected $_paramsParsed = false;
@ -76,9 +75,7 @@ class CakeTestSuiteDispatcher {
protected static $_Reporter = null;
/**
* constructor
*
* @return void
* Constructor
*/
public function __construct() {
$this->_baseUrl = $_SERVER['PHP_SELF'];
@ -117,7 +114,7 @@ class CakeTestSuiteDispatcher {
}
/**
* Checks that PHPUnit is installed. Will exit if it doesn't
* Checks that PHPUnit is installed. Will exit if it doesn't
*
* @return void
*/
@ -133,17 +130,37 @@ class CakeTestSuiteDispatcher {
/**
* Checks for the existence of the test framework files
*
* @return boolean true if found, false otherwise
* @return bool true if found, false otherwise
*/
public function loadTestFramework() {
foreach (App::path('vendors') as $vendor) {
if (is_dir($vendor . 'PHPUnit')) {
if (class_exists('PHPUnit_Framework_TestCase')) {
return true;
}
$phpunitPath = 'phpunit' . DS . 'phpunit';
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
$composerGlobalDir[] = env('APPDATA') . DS . 'Composer' . DS . 'vendor' . DS;
} else {
$composerGlobalDir[] = env('HOME') . DS . '.composer' . DS . 'vendor' . DS;
}
$vendors = array_merge(App::path('vendors'), $composerGlobalDir);
foreach ($vendors as $vendor) {
$vendor = rtrim($vendor, DS);
if (is_dir($vendor . DS . $phpunitPath)) {
ini_set('include_path', $vendor . DS . $phpunitPath . PATH_SEPARATOR . ini_get('include_path'));
break;
} elseif (is_dir($vendor . DS . 'PHPUnit')) {
ini_set('include_path', $vendor . PATH_SEPARATOR . ini_get('include_path'));
break;
} elseif (is_file($vendor . DS . 'phpunit.phar')) {
$backup = $GLOBALS['_SERVER']['SCRIPT_NAME'];
$GLOBALS['_SERVER']['SCRIPT_NAME'] = '-';
$included = include_once $vendor . DS . 'phpunit.phar';
$GLOBALS['_SERVER']['SCRIPT_NAME'] = $backup;
return $included;
}
}
return include 'PHPUnit' . DS . 'Autoload.php';
include 'PHPUnit' . DS . 'Autoload.php';
return class_exists('PHPUnit_Framework_TestCase');
}
/**
@ -186,7 +203,7 @@ class CakeTestSuiteDispatcher {
}
/**
* Parse url params into a 'request'
* Parse URL params into a 'request'
*
* @return void
*/
@ -237,9 +254,9 @@ class CakeTestSuiteDispatcher {
restore_error_handler();
try {
self::time();
static::time();
$command = new CakeTestSuiteCommand('CakeTestLoader', $commandArgs);
$result = $command->run($options);
$command->run($options);
} catch (MissingConnectionException $exception) {
ob_end_clean();
$baseDir = $this->_baseDir;
@ -251,8 +268,8 @@ class CakeTestSuiteDispatcher {
/**
* Sets a static timestamp
*
* @param boolean $reset to set new static timestamp.
* @return integer timestamp
* @param bool $reset to set new static timestamp.
* @return int timestamp
*/
public static function time($reset = false) {
static $now;
@ -270,7 +287,7 @@ class CakeTestSuiteDispatcher {
* @return string formatted date
*/
public static function date($format) {
return date($format, self::time());
return date($format, static::time());
}
}

View file

@ -2,19 +2,18 @@
/**
* ControllerTestCase file
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('Dispatcher', 'Routing');
@ -42,13 +41,15 @@ class ControllerTestDispatcher extends Dispatcher {
/**
* Use custom routes during tests
*
* @var boolean
* @var bool
*/
public $loadRoutes = true;
/**
* Returns the test controller
*
* @param CakeRequest $request The request instance.
* @param CakeResponse $response The response instance.
* @return Controller
*/
protected function _getController($request, $response) {
@ -58,7 +59,7 @@ class ControllerTestDispatcher extends Dispatcher {
$this->testController->helpers = array_merge(array('InterceptContent'), $this->testController->helpers);
$this->testController->setRequest($request);
$this->testController->response = $this->response;
foreach ($this->testController->Components->attached() as $component) {
foreach ($this->testController->Components->loaded() as $component) {
$object = $this->testController->Components->{$component};
if (isset($object->response)) {
$object->response = $response;
@ -95,6 +96,7 @@ class InterceptContentHelper extends Helper {
* Intercepts and stores the contents of the view before the layout is rendered
*
* @param string $viewFile The view file
* @return void
*/
public function afterRender($viewFile) {
$this->_View->assign('__view_no_layout__', $this->_View->fetch('content'));
@ -107,6 +109,7 @@ class InterceptContentHelper extends Helper {
* ControllerTestCase class
*
* @package Cake.TestSuite
* @method mixed testAction() testAction($url, $options = array()) Lets you do functional tests of a controller action.
*/
abstract class ControllerTestCase extends CakeTestCase {
@ -120,14 +123,14 @@ abstract class ControllerTestCase extends CakeTestCase {
/**
* Automatically mock controllers that aren't mocked
*
* @var boolean
* @var bool
*/
public $autoMock = true;
/**
* Use custom routes during tests
*
* @var boolean
* @var bool
*/
public $loadRoutes = true;
@ -171,21 +174,28 @@ abstract class ControllerTestCase extends CakeTestCase {
* Once a test has been run on a controller it should be rebuilt
* to clean up properties.
*
* @var boolean
* @var bool
*/
protected $_dirtyController = false;
/**
* The class name to use for mocking the response object.
*
* @var string
*/
protected $_responseClass = 'CakeResponse';
/**
* Used to enable calling ControllerTestCase::testAction() without the testing
* framework thinking that it's a test case
*
* @param string $name The name of the function
* @param array $arguments Array of arguments
* @return the return of _testAction
* @return mixed The return of _testAction.
* @throws BadMethodCallException when you call methods that don't exist.
*/
public function __call($name, $arguments) {
if ($name == 'testAction') {
if ($name === 'testAction') {
return call_user_func_array(array($this, '_testAction'), $arguments);
}
throw new BadMethodCallException("Method '{$name}' does not exist.");
@ -196,35 +206,41 @@ abstract class ControllerTestCase extends CakeTestCase {
*
* ### Options:
*
* - `data` Will be used as the request data. If the `method` is GET,
* data will be used a GET params. If the `method` is POST, it will be used
* - `data` Will be used as the request data. If the `method` is GET,
* data will be used a GET params. If the `method` is POST, it will be used
* as POST data. By setting `$options['data']` to a string, you can simulate XML or JSON
* payloads to your controllers allowing you to test REST webservices.
* - `method` POST or GET. Defaults to POST.
* - `return` Specify the return type you want. Choose from:
* - `return` Specify the return type you want. Choose from:
* - `vars` Get the set view variables.
* - `view` Get the rendered view, without a layout.
* - `contents` Get the rendered view including the layout.
* - `result` Get the return value of the controller action. Useful
* - `result` Get the return value of the controller action. Useful
* for testing requestAction methods.
*
* @param string $url The url to test
* @param string|array $url The URL to test.
* @param array $options See options
* @return mixed The specified return type.
* @triggers ControllerTestCase $Dispatch, array('request' => $request)
*/
protected function _testAction($url = '', $options = array()) {
protected function _testAction($url, $options = array()) {
$this->vars = $this->result = $this->view = $this->contents = $this->headers = null;
$options = array_merge(array(
$options += array(
'data' => array(),
'method' => 'POST',
'return' => 'result'
), $options);
);
if (is_array($url)) {
$url = Router::url($url);
}
$restore = array('get' => $_GET, 'post' => $_POST);
$_SERVER['REQUEST_METHOD'] = strtoupper($options['method']);
if (is_array($options['data'])) {
if (strtoupper($options['method']) == 'GET') {
if (strtoupper($options['method']) === 'GET') {
$_GET = $options['data'];
$_POST = array();
} else {
@ -250,7 +266,7 @@ abstract class ControllerTestCase extends CakeTestCase {
$Dispatch->parseParams(new CakeEvent('ControllerTestCase', $Dispatch, array('request' => $request)));
if (!isset($request->params['controller']) && Router::currentRoute()) {
$this->headers = Router::currentRoute()->response->header();
return;
return null;
}
if ($this->_dirtyController) {
$this->controller = null;
@ -261,14 +277,20 @@ abstract class ControllerTestCase extends CakeTestCase {
$this->generate($plugin . Inflector::camelize($request->params['controller']));
}
$params = array();
if ($options['return'] == 'result') {
if ($options['return'] === 'result') {
$params['return'] = 1;
$params['bare'] = 1;
$params['requested'] = 1;
}
$Dispatch->testController = $this->controller;
$Dispatch->response = $this->getMock('CakeResponse', array('send'));
$Dispatch->response = $this->getMock($this->_responseClass, array('send', '_clearBuffer'));
$this->result = $Dispatch->dispatch($request, $Dispatch->response, $params);
// Clear out any stored requests.
while (Router::getRequest()) {
Router::popRequest();
}
$this->controller = $Dispatch->testController;
$this->vars = $this->controller->viewVars;
$this->contents = $this->controller->response->body();
@ -292,7 +314,7 @@ abstract class ControllerTestCase extends CakeTestCase {
* ### Mocks:
*
* - `methods` Methods to mock on the controller. `_stop()` is mocked by default
* - `models` Models to mock. Models are added to the ClassRegistry so they any
* - `models` Models to mock. Models are added to the ClassRegistry so any
* time they are instantiated the mock will be created. Pass as key value pairs
* with the value being specific methods on the model to mock. If `true` or
* no value is passed, the entire model will be mocked.
@ -327,11 +349,12 @@ abstract class ControllerTestCase extends CakeTestCase {
), (array)$mocks);
list($plugin, $name) = pluginSplit($controller);
$_controller = $this->getMock($name . 'Controller', $mocks['methods'], array(), '', false);
$_controller->name = $name;
$controllerObj = $this->getMock($name . 'Controller', $mocks['methods'], array(), '', false);
$controllerObj->name = $name;
$request = $this->getMock('CakeRequest');
$response = $this->getMock('CakeResponse', array('_sendHeader'));
$_controller->__construct($request, $response);
$response = $this->getMock($this->_responseClass, array('_sendHeader'));
$controllerObj->__construct($request, $response);
$controllerObj->Components->setController($controllerObj);
$config = ClassRegistry::config('Model');
foreach ($mocks['models'] as $model => $methods) {
@ -342,12 +365,7 @@ abstract class ControllerTestCase extends CakeTestCase {
if ($methods === true) {
$methods = array();
}
ClassRegistry::init($model);
list($plugin, $name) = pluginSplit($model);
$config = array_merge((array)$config, array('name' => $model));
$_model = $this->getMock($name, $methods, array($config));
ClassRegistry::removeObject($name);
ClassRegistry::addObject($name, $_model);
$this->getMockForModel($model, $methods, $config);
}
foreach ($mocks['components'] as $component => $methods) {
@ -366,14 +384,16 @@ abstract class ControllerTestCase extends CakeTestCase {
'class' => $componentClass
));
}
$_component = $this->getMock($componentClass, $methods, array(), '', false);
$_controller->Components->set($name, $_component);
$config = isset($controllerObj->components[$component]) ? $controllerObj->components[$component] : array();
$componentObj = $this->getMock($componentClass, $methods, array($controllerObj->Components, $config));
$controllerObj->Components->set($name, $componentObj);
$controllerObj->Components->enable($name);
}
$_controller->constructClasses();
$controllerObj->constructClasses();
$this->_dirtyController = false;
$this->controller = $_controller;
$this->controller = $controllerObj;
return $this->controller;
}

View file

@ -6,18 +6,22 @@
* PHP5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.TestSuite.Coverage
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('Inflector', 'Utility');
App::uses('CakePlugin', 'Core');
/**
* Abstract class for common CoverageReport methods.
* Provides several template methods for custom output.
@ -48,7 +52,7 @@ abstract class BaseCoverageReport {
public $pluginTest = false;
/**
* Array of test case file names. Used to do basename() matching with
* Array of test case file names. Used to do basename() matching with
* files that have coverage to decide which results to show on page load.
*
* @var array
@ -60,7 +64,6 @@ abstract class BaseCoverageReport {
*
* @param array $coverage Array of coverage data from PHPUnit_Test_Result
* @param CakeBaseReporter $reporter A reporter to use for the coverage report.
* @return void
*/
public function __construct($coverage, CakeBaseReporter $reporter) {
$this->_rawCoverage = $coverage;
@ -95,14 +98,14 @@ abstract class BaseCoverageReport {
/**
* Gets the base path that the files we are interested in live in.
*
* @return void
* @return string Path
*/
public function getPathFilter() {
$path = ROOT . DS;
if ($this->appTest) {
$path .= APP_DIR . DS;
} elseif ($this->pluginTest) {
$path = App::pluginPath($this->pluginTest);
$path = CakePlugin::path($this->pluginTest);
} else {
$path = CAKE;
}
@ -110,7 +113,7 @@ abstract class BaseCoverageReport {
}
/**
* Filters the coverage data by path. Files not in the provided path will be removed.
* Filters the coverage data by path. Files not in the provided path will be removed.
*
* @param string $path Path to filter files by.
* @return array Array of coverage data for files that match the given path.
@ -134,9 +137,9 @@ abstract class BaseCoverageReport {
* 3.5 uses -1 for uncovered, and -2 for dead.
* 3.6 uses array() for uncovered and null for dead.
*
* @param array $fileLines
* @param array $coverageData
* @return array. Array of covered, total lines.
* @param array $fileLines The lines in the file.
* @param array $coverageData The raw coverage data.
* @return array Array of covered, total lines.
*/
protected function _calculateCoveredLines($fileLines, $coverageData) {
$covered = $total = 0;

View file

@ -1,20 +1,19 @@
<?php
/**
* Generates code coverage reports in HTML from data obtained from PHPUnit
*
* PHP5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.TestSuite.Coverage
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('BaseCoverageReport', 'TestSuite/Coverage');
@ -27,9 +26,23 @@ App::uses('BaseCoverageReport', 'TestSuite/Coverage');
class HtmlCoverageReport extends BaseCoverageReport {
/**
* Generates report html to display.
* Holds the total number of processed rows.
*
* @return string compiled html report.
* @var int
*/
protected $_total = 0;
/**
* Holds the total number of covered rows.
*
* @var int
*/
protected $_covered = 0;
/**
* Generates report HTML to display.
*
* @return string Compiled HTML report.
*/
public function report() {
$pathFilter = $this->getPathFilter();
@ -47,6 +60,12 @@ HTML;
$fileData = file($file);
$output .= $this->generateDiff($file, $fileData, $coverageData);
}
$percentCovered = 100;
if ($this->_total > 0) {
$percentCovered = round(100 * $this->_covered / $this->_total, 2);
}
$output .= '<div class="total">Overall coverage: <span class="coverage">' . $percentCovered . '%</span></div>';
return $output;
}
@ -68,6 +87,8 @@ HTML;
$diff = array();
list($covered, $total) = $this->_calculateCoveredLines($fileLines, $coverageData);
$this->_covered += $covered;
$this->_total += $total;
//shift line numbers forward one;
array_unshift($fileLines, ' ');
@ -104,9 +125,9 @@ HTML;
}
/**
* Guess the classname the test was for based on the test case filename.
* Guess the class name the test was for based on the test case filename.
*
* @param ReflectionClass $testReflection.
* @param ReflectionClass $testReflection The class to reflect
* @return string Possible test subject name.
*/
protected function _guessSubjectName($testReflection) {
@ -120,9 +141,13 @@ HTML;
}
/**
* Renders the html for a single line in the html diff.
* Renders the HTML for a single line in the HTML diff.
*
* @return void
* @param string $line The line content.
* @param int $linenumber The line number
* @param string $class The classname to use.
* @param array $coveringTests The tests covering the line.
* @return string
*/
protected function _paintLine($line, $linenumber, $class, $coveringTests) {
$coveredBy = '';
@ -145,21 +170,21 @@ HTML;
/**
* generate some javascript for the coverage report.
*
* @return void
* @return string
*/
public function coverageScript() {
return <<<HTML
<script type="text/javascript">
function coverage_show_hide(selector) {
var element = document.getElementById(selector);
element.style.display = (element.style.display == 'none') ? '' : 'none';
element.style.display = (element.style.display === 'none') ? '' : 'none';
}
function coverage_toggle_all() {
var divs = document.querySelectorAll('div.coverage-container');
var i = divs.length;
while (i--) {
if (divs[i] && divs[i].className.indexOf('primary') == -1) {
divs[i].style.display = (divs[i].style.display == 'none') ? '' : 'none';
divs[i].style.display = (divs[i].style.display === 'none') ? '' : 'none';
}
}
}
@ -170,21 +195,24 @@ HTML;
/**
* Generate an HTML snippet for coverage headers
*
* @return void
* @param string $filename The file name being covered
* @param string $percent The percentage covered
* @return string
*/
public function coverageHeader($filename, $percent) {
$hash = md5($filename);
$filename = basename($filename);
list($file, $ext) = explode('.', $filename);
list($file) = explode('.', $filename);
$display = in_array($file, $this->_testNames) ? 'block' : 'none';
$primary = $display == 'block' ? 'primary' : '';
$primary = $display === 'block' ? 'primary' : '';
return <<<HTML
<div class="coverage-container $primary" style="display:$display;">
<h4>
<a href="#coverage-$filename" onclick="coverage_show_hide('coverage-$filename');">
<a href="#coverage-$filename-$hash" onclick="coverage_show_hide('coverage-$filename-$hash');">
$filename Code coverage: $percent%
</a>
</h4>
<div class="code-coverage-results" id="coverage-$filename" style="display:none;">
<div class="code-coverage-results" id="coverage-$filename-$hash" style="display:none;">
<pre>
HTML;
}

View file

@ -5,16 +5,17 @@
* PHP5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.TestSuite.Coverage
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('BaseCoverageReport', 'TestSuite/Coverage');

View file

@ -2,19 +2,18 @@
/**
* A factory class to manage the life cycle of test fixtures
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.TestSuite.Fixture
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('ConnectionManager', 'Model');
@ -30,7 +29,7 @@ class CakeFixtureManager {
/**
* Was this class already initialized?
*
* @var boolean
* @var bool
*/
protected $_initialized = false;
@ -96,6 +95,23 @@ class CakeFixtureManager {
$this->_initialized = true;
}
/**
* Parse the fixture path included in test cases, to get the fixture class name, and the
* real fixture path including sub-directories
*
* @param string $fixturePath the fixture path to parse
* @return array containing fixture class name and optional additional path
*/
protected function _parseFixturePath($fixturePath) {
$pathTokenArray = explode('/', $fixturePath);
$fixture = array_pop($pathTokenArray);
$additionalPath = '';
foreach ($pathTokenArray as $pathToken) {
$additionalPath .= DS . $pathToken;
}
return array('fixture' => $fixture, 'additionalPath' => $additionalPath);
}
/**
* Looks for fixture files and instantiates the classes accordingly
*
@ -104,7 +120,7 @@ class CakeFixtureManager {
* @throws UnexpectedValueException when a referenced fixture does not exist.
*/
protected function _loadFixtures($fixtures) {
foreach ($fixtures as $index => $fixture) {
foreach ($fixtures as $fixture) {
$fixtureFile = null;
$fixtureIndex = $fixture;
if (isset($this->_loaded[$fixture])) {
@ -115,17 +131,20 @@ class CakeFixtureManager {
$fixture = substr($fixture, strlen('core.'));
$fixturePaths[] = CAKE . 'Test' . DS . 'Fixture';
} elseif (strpos($fixture, 'app.') === 0) {
$fixture = substr($fixture, strlen('app.'));
$fixturePrefixLess = substr($fixture, strlen('app.'));
$fixtureParsedPath = $this->_parseFixturePath($fixturePrefixLess);
$fixture = $fixtureParsedPath['fixture'];
$fixturePaths = array(
TESTS . 'Fixture'
TESTS . 'Fixture' . $fixtureParsedPath['additionalPath']
);
} elseif (strpos($fixture, 'plugin.') === 0) {
$parts = explode('.', $fixture, 3);
$pluginName = $parts[1];
$fixture = $parts[2];
$explodedFixture = explode('.', $fixture, 3);
$pluginName = $explodedFixture[1];
$fixtureParsedPath = $this->_parseFixturePath($explodedFixture[2]);
$fixture = $fixtureParsedPath['fixture'];
$fixturePaths = array(
CakePlugin::path(Inflector::camelize($pluginName)) . 'Test' . DS . 'Fixture',
TESTS . 'Fixture'
CakePlugin::path(Inflector::camelize($pluginName)) . 'Test' . DS . 'Fixture' . $fixtureParsedPath['additionalPath'],
TESTS . 'Fixture' . $fixtureParsedPath['additionalPath']
);
} else {
$fixturePaths = array(
@ -160,7 +179,7 @@ class CakeFixtureManager {
*
* @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
* @param bool $drop whether drop the fixture if it is already created or not
* @return void
*/
protected function _setupTable($fixture, $db = null, $drop = true) {
@ -175,7 +194,7 @@ class CakeFixtureManager {
return;
}
$sources = $db->listSources();
$sources = (array)$db->listSources();
$table = $db->config['prefix'] . $fixture->table;
$exists = in_array($table, $sources);
@ -200,7 +219,7 @@ class CakeFixtureManager {
return;
}
$fixtures = $test->fixtures;
if (empty($fixtures) || $test->autoFixtures == false) {
if (empty($fixtures) || !$test->autoFixtures) {
return;
}
@ -210,6 +229,7 @@ class CakeFixtureManager {
$db = ConnectionManager::getDataSource($fixture->useDbConfig);
$db->begin();
$this->_setupTable($fixture, $db, $test->dropTables);
$fixture->truncate($db);
$fixture->insert($db);
$db->commit();
}
@ -242,17 +262,18 @@ class CakeFixtureManager {
*
* @param string $name of the fixture
* @param DataSource $db DataSource instance or leave null to get DataSource from the fixture
* @param bool $dropTables Whether or not tables should be dropped and re-created.
* @return void
* @throws UnexpectedValueException if $name is not a previously loaded class
*/
public function loadSingle($name, $db = null) {
public function loadSingle($name, $db = null, $dropTables = true) {
$name .= 'Fixture';
if (isset($this->_fixtureMap[$name])) {
$fixture = $this->_fixtureMap[$name];
if (!$db) {
$db = ConnectionManager::getDataSource($fixture->useDbConfig);
}
$this->_setupTable($fixture, $db);
$this->_setupTable($fixture, $db, $dropTables);
$fixture->truncate($db);
$fixture->insert($db);
} else {
@ -263,9 +284,15 @@ class CakeFixtureManager {
/**
* Drop all fixture tables loaded by this class
*
* This will also close the session, as failing to do so will cause
* fatal errors with database sessions.
*
* @return void
*/
public function shutDown() {
if (session_id()) {
session_write_close();
}
foreach ($this->_loaded as $fixture) {
if (!empty($fixture->created)) {
foreach ($fixture->created as $ds) {

View file

@ -1,16 +1,17 @@
<?php
/**
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite.Fixture
* @since CakePHP(tm) v 1.2.0.4667
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('CakeSchema', 'Model');
@ -31,7 +32,7 @@ class CakeTestFixture {
public $name = null;
/**
* Cake's DBO driver (e.g: DboMysql).
* CakePHP's DBO driver (e.g: DboMysql).
*
* @var object
*/
@ -58,6 +59,37 @@ class CakeTestFixture {
*/
public $created = array();
/**
* Fields / Schema for the fixture.
* This array should match the output of Model::schema()
*
* @var array
*/
public $fields = array();
/**
* Fixture records to be inserted.
*
* @var array
*/
public $records = array();
/**
* The primary key for the table this fixture represents.
*
* @var string
*/
public $primaryKey = null;
/**
* Fixture data can be stored in memory by default.
* When table is created for a fixture the MEMORY engine is used
* where possible. Set $canUseMemory to false if you don't want this.
*
* @var bool
*/
public $canUseMemory = true;
/**
* Instantiate the fixture.
*
@ -116,6 +148,7 @@ class CakeTestFixture {
$this->fields = $model->schema(true);
$this->fields[$model->primaryKey]['key'] = 'primary';
$this->table = $db->fullTableName($model, false, false);
$this->primaryKey = $model->primaryKey;
ClassRegistry::config(array('ds' => 'test'));
ClassRegistry::flush();
} elseif (isset($import['table'])) {
@ -127,6 +160,7 @@ class CakeTestFixture {
$model->table = $import['table'];
$model->tablePrefix = $db->config['prefix'];
$this->fields = $model->schema(true);
$this->primaryKey = $model->primaryKey;
ClassRegistry::flush();
}
@ -165,8 +199,8 @@ class CakeTestFixture {
/**
* Run before all tests execute, should return SQL statement to create table for this fixture could be executed successfully.
*
* @param object $db An instance of the database object used to create the fixture table
* @return boolean True on success, false on failure
* @param DboSource $db An instance of the database object used to create the fixture table
* @return bool True on success, false on failure
*/
public function create($db) {
if (!isset($this->fields) || empty($this->fields)) {
@ -174,8 +208,8 @@ class CakeTestFixture {
}
if (empty($this->fields['tableParameters']['engine'])) {
$canUseMemory = true;
foreach ($this->fields as $field => $args) {
$canUseMemory = $this->canUseMemory;
foreach ($this->fields as $args) {
if (is_string($args)) {
$type = $args;
@ -216,8 +250,8 @@ class CakeTestFixture {
/**
* Run after all tests executed, should return SQL statement to drop table for this fixture.
*
* @param object $db An instance of the database object used to create the fixture table
* @return boolean True on success, false on failure
* @param DboSource $db An instance of the database object used to create the fixture table
* @return bool True on success, false on failure
*/
public function drop($db) {
if (empty($this->fields)) {
@ -238,8 +272,9 @@ class CakeTestFixture {
* Run before each tests is executed, should return a set of SQL statements to insert records for the table
* of this fixture could be executed successfully.
*
* @param object $db An instance of the database into which the records will be inserted
* @return boolean on success or if there are no records to insert, or false on failure
* @param DboSource $db An instance of the database into which the records will be inserted
* @return bool on success or if there are no records to insert, or false on failure
* @throws CakeException if counts of values and fields do not match.
*/
public function insert($db) {
if (!isset($this->_insert)) {
@ -252,12 +287,30 @@ class CakeTestFixture {
$fields = array_unique($fields);
$default = array_fill_keys($fields, null);
foreach ($this->records as $record) {
$fields = array_keys($record);
$values[] = array_values(array_merge($default, $record));
$mergeData = array_merge($default, $record);
$merge = array_values($mergeData);
if (count($fields) !== count($merge)) {
$mergeFields = array_diff_key(array_keys($mergeData), $fields);
$message = 'Fixture invalid: Count of fields does not match count of values in ' . get_class($this) . "\n";
foreach ($mergeFields as $field) {
$message .= "The field '" . $field . "' is in the data fixture but not in the schema." . "\n";
}
throw new CakeException($message);
}
$values[] = $merge;
}
$nested = $db->useNestedTransactions;
$db->useNestedTransactions = false;
$result = $db->insertMulti($this->table, $fields, $values);
if ($this->primaryKey &&
isset($this->fields[$this->primaryKey]['type']) &&
in_array($this->fields[$this->primaryKey]['type'], array('integer', 'biginteger'))
) {
$db->resetSequence($this->table, $this->primaryKey);
}
$db->useNestedTransactions = $nested;
return $result;
}
@ -266,11 +319,11 @@ class CakeTestFixture {
}
/**
* Truncates the current fixture. Can be overwritten by classes extending CakeFixture to trigger other events before / after
* truncate.
* Truncates the current fixture. Can be overwritten by classes extending
* CakeFixture to trigger other events before / after truncate.
*
* @param object $db A reference to a db instance
* @return boolean
* @param DboSource $db A reference to a db instance
* @return bool
*/
public function truncate($db) {
$fullDebug = $db->fullDebug;

View file

@ -1,16 +1,17 @@
<?php
/**
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite.Fixture
* @since CakePHP(tm) v 1.2.0.4667
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('Model', 'Model');
@ -31,40 +32,27 @@ class CakeTestModel extends Model {
* incorrect order when no order has been defined in the finds.
* Postgres can return the results in any order it considers appropriate if none is specified
*
* @param array $queryData
* @return array $queryData
* @param int|string|array $id Set this ID for this model on startup, can also be an array of options, see above.
* @param string $table Name of database table to use.
* @param string $ds DataSource connection name.
*/
public function beforeFind($queryData) {
$pk = $this->primaryKey;
$aliasedPk = $this->alias . '.' . $this->primaryKey;
switch (true) {
case !$pk:
case !$this->useTable:
case !$this->schema('id'):
case !empty($queryData['order'][0]):
case !empty($queryData['group']):
case
(is_string($queryData['fields']) && !($queryData['fields'] == $pk || $queryData['fields'] == $aliasedPk)) ||
(is_array($queryData['fields']) && !(array_key_exists($pk, $queryData['fields']) || array_key_exists($aliasedPk, $queryData['fields']))):
break;
default:
$queryData['order'] = array($this->alias . '.' . $this->primaryKey => 'ASC');
break;
}
return $queryData;
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->order = array($this->alias . '.' . $this->primaryKey => 'ASC');
}
/**
* Overriding save() to set CakeTestSuiteDispatcher::date() as formatter for created, modified and updated fields
*
* @param array $data
* @param boolean|array $validate
* @param array $fieldList
* @param array $data Data to save
* @param bool|array $validate Validate or options.
* @param array $fieldList Whitelist of fields
* @return mixed
*/
public function save($data = null, $validate = true, $fieldList = array()) {
$db = $this->getDataSource();
$db->columns['datetime']['formatter'] = 'CakeTestSuiteDispatcher::date';
return parent::save($data, $validate, $fieldList);
}
}
}

View file

@ -2,20 +2,22 @@
/**
* CakeBaseReporter contains common functionality to all cake test suite reporters.
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 1.3
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
require_once 'PHPUnit/TextUI/ResultPrinter.php';
if (!defined('__PHPUNIT_PHAR__')) {
require_once 'PHPUnit/TextUI/ResultPrinter.php';
}
/**
* CakeBaseReporter contains common reporting features used in the CakePHP Test suite
@ -24,10 +26,15 @@ require_once 'PHPUnit/TextUI/ResultPrinter.php';
*/
class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* Headers sent
*
* @var bool
*/
protected $_headerSent = false;
/**
* Array of request parameters. Usually parsed GET params.
* Array of request parameters. Usually parsed GET params.
*
* @var array
*/
@ -104,7 +111,7 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* Get the baseUrl if one is available.
*
* @return string The base url for the request.
* @return string The base URL for the request.
*/
public function baseUrl() {
if (!empty($_SERVER['PHP_SELF'])) {
@ -113,10 +120,22 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
return '';
}
/**
* Print result
*
* @param PHPUnit_Framework_TestResult $result The result object
* @return void
*/
public function printResult(PHPUnit_Framework_TestResult $result) {
$this->paintFooter($result);
}
/**
* Paint result
*
* @param PHPUnit_Framework_TestResult $result The result object
* @return void
*/
public function paintResult(PHPUnit_Framework_TestResult $result) {
$this->paintFooter($result);
}
@ -124,9 +143,10 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* An error occurred.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @param PHPUnit_Framework_Test $test The test to add an error for.
* @param Exception $e The exception object to add.
* @param float $time The current time.
* @return void
*/
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {
$this->paintException($e, $test);
@ -135,9 +155,10 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* A failure occurred.
*
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_AssertionFailedError $e
* @param float $time
* @param PHPUnit_Framework_Test $test The test that failed
* @param PHPUnit_Framework_AssertionFailedError $e The assertion that failed.
* @param float $time The current time.
* @return void
*/
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) {
$this->paintFail($e, $test);
@ -146,9 +167,10 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* Incomplete test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @param PHPUnit_Framework_Test $test The test that was incomplete.
* @param Exception $e The incomplete exception
* @param float $time The current time.
* @return void
*/
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
$this->paintSkip($e, $test);
@ -157,9 +179,10 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* Skipped test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @param PHPUnit_Framework_Test $test The test that failed.
* @param Exception $e The skip object.
* @param float $time The current time.
* @return void
*/
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
$this->paintSkip($e, $test);
@ -168,7 +191,8 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* A test suite started.
*
* @param PHPUnit_Framework_TestSuite $suite
* @param PHPUnit_Framework_TestSuite $suite The suite to start
* @return void
*/
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
if (!$this->_headerSent) {
@ -180,7 +204,8 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* A test suite ended.
*
* @param PHPUnit_Framework_TestSuite $suite
* @param PHPUnit_Framework_TestSuite $suite The suite that ended.
* @return void
*/
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {
}
@ -188,7 +213,8 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* A test started.
*
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_Test $test The test that started.
* @return void
*/
public function startTest(PHPUnit_Framework_Test $test) {
}
@ -196,8 +222,9 @@ class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
/**
* A test ended.
*
* @param PHPUnit_Framework_Test $test
* @param float $time
* @param PHPUnit_Framework_Test $test The test that ended
* @param float $time The current time.
* @return void
*/
public function endTest(PHPUnit_Framework_Test $test, $time) {
$this->numAssertions += $test->getNumAssertions();

View file

@ -2,19 +2,19 @@
/**
* CakeHtmlReporter
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('CakeBaseReporter', 'TestSuite/Reporter');
/**
@ -95,11 +95,11 @@ class CakeHtmlReporter extends CakeBaseReporter {
$urlExtra = '&plugin=' . $plugin;
}
if (1 > count($testCases)) {
if (count($testCases) < 1) {
$buffer .= "<strong>EMPTY</strong>";
}
foreach ($testCases as $testCaseFile => $testCase) {
foreach ($testCases as $testCase) {
$title = explode(DS, str_replace('.test.php', '', $testCase));
$title[count($title) - 1] = Inflector::camelize($title[count($title) - 1]);
$title = implode(' / ', $title);
@ -169,6 +169,7 @@ class CakeHtmlReporter extends CakeBaseReporter {
/**
* Paints a code coverage report.
*
* @param array $coverage The coverage data
* @return void
*/
public function paintCoverage(array $coverage) {
@ -198,12 +199,12 @@ class CakeHtmlReporter extends CakeBaseReporter {
if (!empty($this->params['case'])) {
$query['case'] = $this->params['case'];
}
$show = $this->_queryString($show);
$query = $this->_queryString($query);
list($show, $query) = $this->_getQueryLink();
echo "<p><a href='" . $this->baseUrl() . $show . "'>Run more tests</a> | <a href='" . $this->baseUrl() . $query . "&amp;show_passes=1'>Show Passes</a> | \n";
echo "<a href='" . $this->baseUrl() . $query . "&amp;debug=1'>Enable Debug Output</a> | \n";
echo "<a href='" . $this->baseUrl() . $query . "&amp;code_coverage=true'>Analyze Code Coverage</a></p>\n";
echo "<a href='" . $this->baseUrl() . $query . "&amp;code_coverage=true'>Analyze Code Coverage</a> | \n";
echo "<a href='" . $this->baseUrl() . $query . "&amp;code_coverage=true&amp;show_passes=1&amp;debug=1'>All options enabled</a></p>\n";
}
/**
@ -242,17 +243,21 @@ class CakeHtmlReporter extends CakeBaseReporter {
*
* @param PHPUnit_Framework_AssertionFailedError $message Failure object displayed in
* the context of the other tests.
* @param mixed $test The test case to paint a failure for.
* @return void
*/
public function paintFail($message, $test) {
$trace = $this->_getStackTrace($message);
$testName = get_class($test) . '(' . $test->getName() . ')';
$className = get_class($test);
$testName = $className . '::' . $test->getName() . '()';
$actualMsg = $expectedMsg = null;
$failure = $message->getComparisonFailure();
if (is_object($failure)) {
$actualMsg = $message->getComparisonFailure()->getActualAsString();
$expectedMsg = $message->getComparisonFailure()->getExpectedAsString();
if (method_exists($message, 'getComparisonFailure')) {
$failure = $message->getComparisonFailure();
if (is_object($failure)) {
$actualMsg = $failure->getActualAsString();
$expectedMsg = $failure->getExpectedAsString();
}
}
echo "<li class='fail'>\n";
@ -260,11 +265,15 @@ class CakeHtmlReporter extends CakeBaseReporter {
echo "<div class='msg'><pre>" . $this->_htmlEntities($message->toString());
if ((is_string($actualMsg) && is_string($expectedMsg)) || (is_array($actualMsg) && is_array($expectedMsg))) {
echo "<br />" . PHPUnit_Util_Diff::diff($expectedMsg, $actualMsg);
echo "<br />" . $this->_htmlEntities(PHPUnit_Util_Diff::diff($expectedMsg, $actualMsg));
}
echo "</pre></div>\n";
echo "<div class='msg'>" . __d('cake_dev', 'Test case: %s', $testName) . "</div>\n";
if (strpos($className, "PHPUnit_") === false) {
list($show, $query) = $this->_getQueryLink();
echo "<div class='msg'><a href='" . $this->baseUrl() . $query . "&amp;filter=" . $test->getName() . "'>" . __d('cake_dev', 'Rerun only this test: %s', $testName) . "</a></div>\n";
}
echo "<div class='msg'>" . __d('cake_dev', 'Stack trace:') . '<br />' . $trace . "</div>\n";
echo "</li>\n";
}
@ -274,7 +283,7 @@ class CakeHtmlReporter extends CakeBaseReporter {
* trail of the nesting test suites below the
* top level test.
*
* @param PHPUnit_Framework_Test test method that just passed
* @param PHPUnit_Framework_Test $test Test method that just passed
* @param float $time time spent to run the test method
* @return void
*/
@ -291,7 +300,8 @@ class CakeHtmlReporter extends CakeBaseReporter {
/**
* Paints a PHP exception.
*
* @param Exception $exception Exception to display.
* @param Exception $message Exception to display.
* @param mixed $test The test that failed.
* @return void
*/
public function paintException($message, $test) {
@ -365,7 +375,8 @@ class CakeHtmlReporter extends CakeBaseReporter {
/**
* A test suite started.
*
* @param PHPUnit_Framework_TestSuite $suite
* @param PHPUnit_Framework_TestSuite $suite The test suite to start.
* @return void
*/
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
if (!$this->_headerSent) {
@ -374,4 +385,32 @@ class CakeHtmlReporter extends CakeBaseReporter {
echo '<h2>' . __d('cake_dev', 'Running %s', $suite->getName()) . '</h2>';
}
/**
* Returns the query string formatted for ouput in links
*
* @return string
*/
protected function _getQueryLink() {
$show = $query = array();
if (!empty($this->params['case'])) {
$show['show'] = 'cases';
}
if (!empty($this->params['core'])) {
$show['core'] = $query['core'] = 'true';
}
if (!empty($this->params['plugin'])) {
$show['plugin'] = $query['plugin'] = $this->params['plugin'];
}
if (!empty($this->params['case'])) {
$query['case'] = $this->params['case'];
}
if (!empty($this->params['filter'])) {
$query['filter'] = $this->params['filter'];
}
$show = $this->_queryString($show);
$query = $this->_queryString($query);
return array($show, $query);
}
}

View file

@ -2,19 +2,19 @@
/**
* CakeTextReporter contains reporting features used for plain text based output
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 1.3
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('CakeBaseReporter', 'TestSuite/Reporter');
App::uses('TextCoverageReport', 'TestSuite/Coverage');
@ -48,7 +48,7 @@ class CakeTextReporter extends CakeBaseReporter {
/**
* Paints a failing test.
*
* @param $message PHPUnit_Framework_AssertionFailedError $message Failure object displayed in
* @param PHPUnit_Framework_AssertionFailedError $message Failure object displayed in
* the context of the other tests.
* @return void
*/
@ -71,10 +71,10 @@ class CakeTextReporter extends CakeBaseReporter {
* @return void
*/
public function paintFooter($result) {
if ($result->failureCount() + $result->errorCount() == 0) {
echo "\nOK\n";
} else {
if ($result->failureCount() + $result->errorCount()) {
echo "FAILURES!!!\n";
} else {
echo "\nOK\n";
}
echo "Test cases run: " . $result->count() .
@ -95,7 +95,6 @@ class CakeTextReporter extends CakeBaseReporter {
/**
* Paints the title only.
*
* @param string $test_name Name class of test.
* @return void
*/
public function paintHeader() {
@ -140,7 +139,7 @@ class CakeTextReporter extends CakeBaseReporter {
/**
* Generate a test case list in plain text.
* Creates as series of url's for tests that can be run.
* Creates as series of URLs for tests that can be run.
* One case per line.
*
* @return void
@ -151,21 +150,18 @@ class CakeTextReporter extends CakeBaseReporter {
$plugin = $this->params['plugin'];
$buffer = "Core Test Cases:\n";
$urlExtra = '';
if ($app) {
$buffer = "App Test Cases:\n";
$urlExtra = '&app=true';
} elseif ($plugin) {
$buffer = Inflector::humanize($plugin) . " Test Cases:\n";
$urlExtra = '&plugin=' . $plugin;
}
if (1 > count($testCases)) {
$buffer .= "EMPTY";
if (count($testCases) < 1) {
$buffer .= 'EMPTY';
echo $buffer;
}
foreach ($testCases as $testCaseFile => $testCase) {
foreach ($testCases as $testCase) {
$buffer .= $_SERVER['SERVER_NAME'] . $this->baseUrl() . "?case=" . $testCase . "&output=text\n";
}
@ -177,7 +173,7 @@ class CakeTextReporter extends CakeBaseReporter {
* Generates a Text summary of the coverage data.
*
* @param array $coverage Array of coverage data.
* @return string
* @return void
*/
public function paintCoverage($coverage) {
$reporter = new TextCoverageReport($coverage, $this);

View file

@ -0,0 +1,89 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 2.8
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses("ConsoleOutput", "Console");
/**
* StubOutput makes testing shell commands/shell helpers easier.
*
* You can use this class by injecting it into a Helper instance:
*
* ```
* App::uses("ConsoleOutputStub", "TestSuite/Stub");
*
* $output = new ConsoleOutputStub();
* $helper = new ProgressHelper($output);
* ```
*/
class ConsoleOutputStub extends ConsoleOutput {
/**
* Buffered messages.
*
* @var array
*/
protected $_out = array();
/**
* The number of bytes written by last call to write
*
* @var int
*/
protected $_lastWritten = 0;
/**
* Write output to the buffer.
*
* @param string|array $message A string or an array of strings to output
* @param int $newlines Number of newlines to append
* @return void
*/
public function write($message, $newlines = 1) {
foreach ((array)$message as $line) {
$this->_out[] = $line;
$this->_lastWritten = strlen($line);
}
$newlines--;
while ($newlines > 0) {
$this->_out[] = '';
$this->_lastWritten = 0;
$newlines--;
}
}
/**
* Overwrite output already written to the buffer.
*
* @param array|string $message The message to output.
* @param int $newlines Number of newlines to append.
* @param int $size The number of bytes to overwrite. Defaults to the
* length of the last message output.
* @return void
*/
public function overwrite($message, $newlines = 1, $size = null) {
//insert an empty array to mock deletion of existing output
$this->_out[] = "";
//append new message to output
$this->write($message, $newlines);
}
/**
* Get the buffered output.
*
* @return array
*/
public function messages() {
return $this->_out;
}
}

View file

@ -2,29 +2,28 @@
/**
* Short description for file.
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite.templates
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?> </div>
</div>
<div id="footer">
<div id="footer">
<p>
<!--PLEASE USE ONE OF THE POWERED BY CAKEPHP LOGO-->
<a href="http://www.cakephp.org/" target="_blank">
<!--PLEASE USE ONE OF THE POWERED BY CAKEPHP LOGO-->
<a href="http://www.cakephp.org/" target="_blank">
<img src="<?php echo $baseDir; ?>img/cake.power.gif" alt="CakePHP(tm) :: Rapid Development Framework" /></a>
</p>
</div>
</div>
<?php
App::uses('View', 'View');
$null = null;
@ -33,4 +32,4 @@
?>
</div>
</body>
</html>
</html>

View file

@ -2,26 +2,25 @@
/**
* Short description for file.
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite.templates
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CakePHP Test Suite 2.2</title>
<title>CakePHP Test Suite <?php echo Configure::version(); ?></title>
<style type="text/css">
body h2 {color: #777;}
h3 {font-size: 170%; padding-top: 1em}
@ -107,7 +106,7 @@
div.code-coverage-results span.line-num strong { color:#666; }
div.code-coverage-results div.start {
border:1px solid #aaa;
border-width:1px 1px 0px 1px;
border-width:1px 1px 0 1px;
margin-top:30px;
padding-top:5px;
}
@ -127,7 +126,7 @@
div.code-coverage-results span.result-bad { color: #a00; }
div.code-coverage-results span.result-ok { color: #fa0; }
div.code-coverage-results span.result-good { color: #0a0; }
div#version {
padding-top: 2px;
float: right;
@ -143,4 +142,4 @@
<h1>CakePHP: the rapid development php framework</h1>
</div>
<div id="content">
<h2>CakePHP Test Suite 2.2</h2>
<h2>CakePHP Test Suite <?php echo Configure::version(); ?></h2>

View file

@ -3,19 +3,18 @@
/**
* Short description for file.
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite.templates
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?>
<div class="test-menu">

View file

@ -2,19 +2,18 @@
/**
* Missing Connection error page
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite.templates
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?>
<?php include dirname(__FILE__) . DS . 'header.php'; ?>

View file

@ -1,36 +1,29 @@
<?php
/**
* Missing PHPUnit
* error page.
*
* PHP 5
* Missing PHPUnit error page.
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite.templates
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?>
<?php include dirname(__FILE__) . DS . 'header.php'; ?>
<div id="content">
<h2>PHPUnit is not installed!</h2>
<p>You must install PHPUnit to use the CakePHP(tm) Test Suite.</p>
<p>PHPUnit can be installed with pear, using the pear installer.</p>
<p>To install with the PEAR installer run the following commands:</p>
<ul>
<li><code>pear config-set auto_discover 1</code></li>
<li><code>pear install pear.phpunit.de/PHPUnit</code></li>
</ul>
<p>PHPUnit can be installed with Composer, or downloaded as a phar archive.</p>
<p>Once PHPUnit is installed make sure its located on PHP's <code>include_path</code> by checking your php.ini</p>
<p>For full instructions on how to <a href="http://www.phpunit.de/manual/current/en/installation.html" target="_blank">install PHPUnit, see the PHPUnit installation guide</a>.</p>
<p><a href="http://github.com/sebastianbergmann/phpunit" target="_blank">Download PHPUnit</a></p>
<p><a href="https://github.com/sebastianbergmann/phpunit" target="_blank">Download PHPUnit</a></p>
</div>
<?php
include dirname(__FILE__) . DS . 'footer.php';

View file

@ -2,19 +2,18 @@
/**
* Xdebug error page
*
* PHP 5
*
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
* @package Cake.TestSuite.templates
* @since CakePHP(tm) v 1.2.0.4433
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?>
<?php include dirname(__FILE__) . DS . 'header.php'; ?>
@ -25,4 +24,3 @@
</div>
<?php
include dirname(__FILE__) . DS . 'footer.php';