Browse files

Merge branch '2.0' into 2.1

  • Loading branch information...
2 parents 497ada8 + 5934a7a commit 254357e9c9430e4f4d27ec7972caa51113c99d28 @markstory markstory committed Nov 12, 2011
Showing with 468 additions and 313 deletions.
  1. +2 −2 app/Config/core.php
  2. +3 −3 app/Config/database.php.default
  3. +1 −1 lib/Cake/Console/Command/AclShell.php
  4. +1 −1 lib/Cake/Console/Command/Task/ControllerTask.php
  5. +5 −5 lib/Cake/Console/Command/Task/DbConfigTask.php
  6. +5 −1 lib/Cake/Console/Command/Task/ViewTask.php
  7. +1 −1 lib/Cake/Console/Command/TestsuiteShell.php
  8. +45 −1 lib/Cake/Console/Command/UpgradeShell.php
  9. +2 −5 lib/Cake/Console/Shell.php
  10. +2 −2 lib/Cake/Console/Templates/skel/Config/core.php
  11. +3 −3 lib/Cake/Console/Templates/skel/Config/database.php.default
  12. +1 −2 lib/Cake/Model/Datasource/CakeSession.php
  13. +1 −1 lib/Cake/Model/Datasource/Database/Sqlite.php
  14. +26 −4 lib/Cake/Model/Datasource/DboSource.php
  15. +2 −1 lib/Cake/Network/CakeResponse.php
  16. +1 −1 lib/Cake/Network/Http/HttpResponse.php
  17. +2 −5 lib/Cake/Routing/Router.php
  18. +1 −1 lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php
  19. +11 −2 lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php
  20. +37 −0 lib/Cake/Test/Case/Network/CakeResponseTest.php
  21. +9 −0 lib/Cake/Test/Case/Network/Http/HttpResponseTest.php
  22. +126 −232 lib/Cake/Test/Case/Routing/DispatcherTest.php
  23. +15 −0 lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php
  24. +49 −0 lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php
  25. +2 −2 lib/Cake/Test/Case/Utility/DebuggerTest.php
  26. +18 −0 lib/Cake/Test/Case/View/Helper/FormHelperTest.php
  27. +6 −3 lib/Cake/Test/Case/View/Helper/TimeHelperTest.php
  28. +23 −7 lib/Cake/Test/Case/View/HelperTest.php
  29. +1 −1 lib/Cake/Test/Fixture/CounterCachePostFixture.php
  30. +1 −0 lib/Cake/Test/test_app/Console/Templates/test/views/admin_edit.ctp
  31. +5 −0 lib/Cake/Test/test_app/Controller/TestsAppsPostsController.php
  32. +21 −9 lib/Cake/TestSuite/ControllerTestCase.php
  33. +8 −3 lib/Cake/TestSuite/Coverage/BaseCoverageReport.php
  34. +11 −5 lib/Cake/TestSuite/Coverage/HtmlCoverageReport.php
  35. +2 −1 lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php
  36. +8 −2 lib/Cake/View/Helper.php
  37. +11 −6 lib/Cake/View/Helper/TimeHelper.php
View
4 app/Config/core.php
@@ -225,8 +225,8 @@
Configure::write('Acl.database', 'default');
/**
- * If you are on PHP 5.3 uncomment this line and correct your server timezone
- * to fix the date & time related errors.
+ * Uncomment this line and correct your server timezone to fix
+ * any date & time related errors.
*/
//date_default_timezone_set('UTC');
View
6 app/Config/database.php.default
@@ -27,14 +27,14 @@
* Database configuration class.
* You can specify multiple configurations for production, development and testing.
*
- * driver => The name of a supported driver; valid options are as follows:
+ * datasource => The name of a supported datasource; valid options are as follows:
* Database/Mysql - MySQL 4 & 5,
* Database/Sqlite - SQLite (PHP5 only),
* Database/Postgres - PostgreSQL 7 and higher,
* Database/Sqlserver - Microsoft SQL Server 2005 and higher
*
- * You can add custom database drivers (or override existing drivers) by adding the
- * appropriate file to app/Model/Datasource/Database. Drivers should be named 'MyDriver.php',
+ * You can add custom database datasources (or override existing datasources) by adding the
+ * appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php',
*
*
* persistent => true / false
View
2 lib/Cake/Console/Command/AclShell.php
@@ -485,7 +485,7 @@ public function getOptionParser() {
)
)
))->addSubcommand('initdb', array(
- 'help' => __d('cake_console', 'Initialize the DbAcl tables. Uses this command : cake schema run create DbAcl')
+ 'help' => __d('cake_console', 'Initialize the DbAcl tables. Uses this command : cake schema create DbAcl')
))->epilog(
array(
'Node and parent arguments can be in one of the following formats:',
View
2 lib/Cake/Console/Command/Task/ControllerTask.php
@@ -219,7 +219,7 @@ public function confirmController($controllerName, $useDynamicScaffold, $helpers
$this->out(__d('cake_console', "Controller Name:\n\t%s", $controllerName));
if (strtolower($useDynamicScaffold) == 'y') {
- $this->out("var \$scaffold;");
+ $this->out("public \$scaffold;");
}
$properties = array(
View
10 lib/Cake/Console/Command/Task/DbConfigTask.php
@@ -104,7 +104,7 @@ protected function _interactive() {
}
}
- $driver = $this->in(__d('cake_console', 'Driver:'), array('Mysql', 'Postgres', 'Sqlite', 'Sqlserver'), 'Mysql');
+ $datasource = $this->in(__d('cake_console', 'Datasource:'), array('Mysql', 'Postgres', 'Sqlite', 'Sqlserver'), 'Mysql');
$persistent = $this->in(__d('cake_console', 'Persistent Connection?'), array('y', 'n'), 'n');
if (strtolower($persistent) == 'n') {
@@ -167,7 +167,7 @@ protected function _interactive() {
}
$schema = '';
- if ($driver == 'postgres') {
+ if ($datasource == 'postgres') {
while ($schema == '') {
$schema = $this->in(__d('cake_console', 'Table schema?'), null, 'n');
}
@@ -176,7 +176,7 @@ protected function _interactive() {
$schema = null;
}
- $config = compact('name', 'driver', 'persistent', 'host', 'login', 'password', 'database', 'prefix', 'encoding', 'port', 'schema');
+ $config = compact('name', 'datasource', 'persistent', 'host', 'login', 'password', 'database', 'prefix', 'encoding', 'port', 'schema');
while ($this->_verify($config) == false) {
$this->_interactive();
@@ -209,7 +209,7 @@ protected function _verify($config) {
$this->out(__d('cake_console', 'The following database configuration will be created:'));
$this->hr();
$this->out(__d('cake_console', "Name: %s", $name));
- $this->out(__d('cake_console', "Driver: %s", $driver));
+ $this->out(__d('cake_console', "Datasource: %s", $datasource));
$this->out(__d('cake_console', "Persistent: %s", $persistent));
$this->out(__d('cake_console', "Host: %s", $host));
@@ -314,7 +314,7 @@ public function bake($configs) {
extract($config);
$out .= "\tpublic \${$name} = array(\n";
- $out .= "\t\t'datasource' => 'Database/{$driver}',\n";
+ $out .= "\t\t'datasource' => 'Database/{$datasource}',\n";
$out .= "\t\t'persistent' => {$persistent},\n";
$out .= "\t\t'host' => '{$host}',\n";
View
6 lib/Cake/Console/Command/Task/ViewTask.php
@@ -143,7 +143,7 @@ protected function _methodsToBake() {
}
$adminRoute = $this->Project->getPrefix();
foreach ($methods as $i => $method) {
- if ($adminRoute && isset($this->params['admin'])) {
+ if ($adminRoute && !empty($this->params['admin'])) {
if ($scaffoldActions) {
$methods[$i] = $adminRoute . $method;
continue;
@@ -393,6 +393,10 @@ public function getTemplate($action) {
if (!empty($this->template) && $action != $this->template) {
return $this->template;
}
+ $themePath = $this->Template->getThemePath();
+ if (file_exists($themePath . 'views' . DS . $action . '.ctp')) {
+ return $action;
+ }
$template = $action;
$prefixes = Configure::read('Routing.prefixes');
foreach ((array)$prefixes as $prefix) {
View
2 lib/Cake/Console/Command/TestsuiteShell.php
@@ -148,7 +148,7 @@ public function getOptionParser() {
))->addOption('fixture', array(
'help' => __d('cake_console', 'Choose a custom fixture manager.'),
))->addOption('debug', array(
- 'help' => __d('cake_console', 'More verbose output.'),
+ 'help' => __d('cake_console', 'Enable full output of testsuite. (supported in PHPUnit 3.6.0 and greater)'),
));
return $parser;
View
46 lib/Cake/Console/Command/UpgradeShell.php
@@ -214,6 +214,9 @@ public function helpers() {
}
$patterns = array();
+ App::build(array(
+ 'View/Helper' => App::core('View/Helper'),
+ ), App::APPEND);
$helpers = App::objects('helper');
$plugins = App::objects('plugin');
$pluginHelpers = array();
@@ -514,6 +517,43 @@ public function components() {
}
/**
+ * Replace cakeError with built-in exceptions.
+ * NOTE: this ignores calls where you've passed your own secondary parameters to cakeError().
+ * @return void
+ */
+ public function exceptions() {
+ $controllers = array_diff(App::path('controllers'), App::core('controllers'), array(APP));
+ $components = array_diff(App::path('components'), App::core('components'));
+
+ $this->_paths = array_merge($controllers, $components);
+
+ if (!empty($this->params['plugin'])) {
+ $pluginPath = App::pluginPath($this->params['plugin']);
+ $this->_paths = array(
+ $pluginPath . 'controllers' . DS,
+ $pluginPath . 'controllers' . DS . 'components' .DS,
+ );
+ }
+ $patterns = array(
+ array(
+ '$this->cakeError("error400") -> throw new BadRequestException()',
+ '/(\$this->cakeError\(["\']error400["\']\));/',
+ 'throw new BadRequestException();'
+ ),
+ array(
+ '$this->cakeError("error404") -> throw new NotFoundException()',
+ '/(\$this->cakeError\(["\']error404["\']\));/',
+ 'throw new NotFoundException();'
+ ),
+ array(
+ '$this->cakeError("error500") -> throw new InternalErrorException()',
+ '/(\$this->cakeError\(["\']error500["\']\));/',
+ 'throw new InternalErrorException();'
+ ),
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+/**
* Move application views files to where they now should be
*
* Find all view files in the folder and determine where cake expects the file to be
@@ -662,11 +702,11 @@ protected function _filesRegexpUpdate($patterns) {
* @return void
*/
protected function _findFiles($extensions = '') {
+ $this->_files = array();
foreach ($this->_paths as $path) {
if (!is_dir($path)) {
continue;
}
- $this->_files = array();
$Iterator = new RegexIterator(
new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)),
'/^.+\.(' . $extensions . ')$/i',
@@ -773,6 +813,10 @@ public function getOptionParser() {
->addSubcommand('components', array(
'help' => __d('cake_console', 'Update components to extend Component class.'),
'parser' => $subcommandParser
+ ))
+ ->addSubcommand('exceptions', array(
+ 'help' => __d('cake_console', 'Replace use of cakeError with exceptions.'),
+ 'parser' => $subcommandParser
));
}
}
View
7 lib/Cake/Console/Shell.php
@@ -273,15 +273,12 @@ public function hasTask($task) {
* @return boolean
*/
public function hasMethod($name) {
- if (empty($this->_reflection)) {
- $this->_reflection = new ReflectionClass($this);
- }
try {
- $method = $this->_reflection->getMethod($name);
+ $method = new ReflectionMethod($this, $name);
if (!$method->isPublic() || substr($name, 0, 1) === '_') {
return false;
}
- if ($method->getDeclaringClass() != $this->_reflection) {
+ if ($method->getDeclaringClass()->name == 'Shell') {
return false;
}
return true;
View
4 lib/Cake/Console/Templates/skel/Config/core.php
@@ -225,8 +225,8 @@
Configure::write('Acl.database', 'default');
/**
- * If you are on PHP 5.3 uncomment this line and correct your server timezone
- * to fix the date & time related errors.
+ * Uncomment this line and correct your server timezone to fix
+ * any date & time related errors.
*/
//date_default_timezone_set('UTC');
View
6 lib/Cake/Console/Templates/skel/Config/database.php.default
@@ -27,14 +27,14 @@
* Database configuration class.
* You can specify multiple configurations for production, development and testing.
*
- * driver => The name of a supported driver; valid options are as follows:
+ * datasource => The name of a supported datasource; valid options are as follows:
* Database/Mysql - MySQL 4 & 5,
* Database/Sqlite - SQLite (PHP5 only),
* Database/Postgres - PostgreSQL 7 and higher,
* Database/Sqlserver - Microsoft SQL Server 2005 and higher
*
- * You can add custom database drivers (or override existing drivers) by adding the
- * appropriate file to app/Model/Datasource/Database. Drivers should be named 'MyDriver.php',
+ * You can add custom database datasources (or override existing datasources) by adding the
+ * appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php',
*
*
* persistent => true / false
View
3 lib/Cake/Model/Datasource/CakeSession.php
@@ -539,8 +539,7 @@ protected static function _defaultConfig($name) {
'cookieTimeout' => 240,
'ini' => array(
'session.use_trans_sid' => 0,
- 'session.cookie_path' => self::$path,
- 'session.save_handler' => 'files'
+ 'session.cookie_path' => self::$path
)
),
'cake' => array(
View
2 lib/Cake/Model/Datasource/Database/Sqlite.php
@@ -250,7 +250,7 @@ public function column($real) {
if (in_array($col, array('text', 'integer', 'float', 'boolean', 'timestamp', 'date', 'datetime', 'time'))) {
return $col;
}
- if (strpos($col, 'varchar') !== false || strpos($col, 'char') !== false) {
+ if (strpos($col, 'char') !== false) {
return 'string';
}
if (in_array($col, array('blob', 'clob'))) {
View
30 lib/Cake/Model/Datasource/DboSource.php
@@ -2734,22 +2734,44 @@ public function boolean($data, $quote = false) {
/**
* Inserts multiple values into a table
*
- * @param string $table
- * @param string $fields
- * @param array $values
+ * @param string $table The table being inserted into.
+ * @param array $fields The array of field/column names being inserted.
+ * @param array $values The array of values to insert. The values should
+ * be an array of rows. Each row should have values keyed by the column name.
+ * Each row must have the values in the same order as $fields.
* @return boolean
*/
public function insertMulti($table, $fields, $values) {
$table = $this->fullTableName($table);
$holder = implode(',', array_fill(0, count($fields), '?'));
$fields = implode(', ', array_map(array(&$this, 'name'), $fields));
+ $pdoMap = array(
+ 'integer' => PDO::PARAM_INT,
+ 'float' => PDO::PARAM_STR,
+ 'boolean' => PDO::PARAM_BOOL,
+ 'string' => PDO::PARAM_STR,
+ 'text' => PDO::PARAM_STR
+ );
+ $columnMap = array();
+
$count = count($values);
$sql = "INSERT INTO {$table} ({$fields}) VALUES ({$holder})";
$statement = $this->_connection->prepare($sql);
$this->begin();
+
+ foreach ($values[0] as $key => $val) {
+ $type = $this->introspectType($val);
+ $columnMap[$key] = $pdoMap[$type];
+ }
+
for ($x = 0; $x < $count; $x++) {
- $statement->execute($values[$x]);
+ $i = 1;
+ foreach ($values[$x] as $key => $val) {
+ $statement->bindValue($i, $val, $columnMap[$key]);
+ $i += 1;
+ }
+ $statement->execute();
$statement->closeCursor();
}
return $this->commit();
View
3 lib/Cake/Network/CakeResponse.php
@@ -669,7 +669,8 @@ public function compress() {
* @return boolean
*/
public function outputCompressed() {
- return ini_get("zlib.output_compression") === '1' || in_array('ob_gzhandler', ob_list_handlers());
+ return strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false
+ && (ini_get("zlib.output_compression") === '1' || in_array('ob_gzhandler', ob_list_handlers()));
}
/**
View
2 lib/Cake/Network/Http/HttpResponse.php
@@ -213,7 +213,7 @@ protected function _decodeChunkedBody($body) {
$chunkLength = null;
while ($chunkLength !== 0) {
- if (!preg_match("/^([0-9a-f]+) *(?:;(.+)=(.+))?\r\n/iU", $body, $match)) {
+ if (!preg_match('/^([0-9a-f]+) *(?:;(.+)=(.+))?(?:\r\n|\n)/iU', $body, $match)) {
throw new SocketException(__d('cake_dev', 'HttpSocket::_decodeChunkedBody - Could not parse malformed chunk.'));
}
View
7 lib/Cake/Routing/Router.php
@@ -820,7 +820,7 @@ public static function url($url = null, $full = false) {
* @see Router::url()
*/
protected static function _handleNoRoute($url) {
- $named = $args = $query = array();
+ $named = $args = array();
$skip = array_merge(
array('bare', 'action', 'controller', 'plugin', 'prefix'),
self::$_prefixes
@@ -847,7 +847,7 @@ protected static function _handleNoRoute($url) {
}
}
- if (empty($named) && empty($args) && empty($query) && (!isset($url['action']) || $url['action'] === 'index')) {
+ if (empty($named) && empty($args) && (!isset($url['action']) || $url['action'] === 'index')) {
$url['action'] = null;
}
@@ -881,9 +881,6 @@ protected static function _handleNoRoute($url) {
}
}
}
- if (!empty($query)) {
- $output .= Router::queryString($query);
- }
return $output;
}
View
2 lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php
@@ -115,7 +115,7 @@ public function testExecuteIntoInteractive() {
->with(array(
array(
'name' => 'default',
- 'driver' => 'mysql',
+ 'datasource' => 'mysql',
'persistent' => 'false',
'host' => 'localhost',
'login' => 'root',
View
13 lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php
@@ -230,6 +230,7 @@ public function setUp() {
$this->Task->path = TMP;
$this->Task->Template->params['theme'] = 'default';
+ $this->Task->Template->templatePaths = array('default' => CAKE . 'Console' . DS . 'Templates' . DS . 'default' .DS);
}
/**
@@ -563,7 +564,7 @@ public function testExecuteWithControllerVariations($name) {
}
/**
- * test `cake bake view $controller -admin`
+ * test `cake bake view $controller --admin`
* Which only bakes admin methods, not non-admin methods.
*
* @return void
@@ -701,7 +702,7 @@ public function testExecuteInteractiveWithAdmin() {
}
/**
- * test getting templates, make sure noTemplateActions works
+ * test getting templates, make sure noTemplateActions works and prefixed template is used before generic one.
*
* @return void
*/
@@ -716,6 +717,14 @@ public function testGetTemplate() {
$result = $this->Task->getTemplate('admin_add');
$this->assertEqual($result, 'form');
+
+ $this->Task->Template->templatePaths = array(
+ 'test' => CAKE . 'Test' . DS . 'test_app' . DS . 'Console' . DS . 'Templates' . DS . 'test' .DS
+ );
+ $this->Task->Template->params['theme'] = 'test';
+
+ $result = $this->Task->getTemplate('admin_edit');
+ $this->assertEqual($result, 'admin_edit');
}
}
View
37 lib/Cake/Test/Case/Network/CakeResponseTest.php
@@ -390,6 +390,43 @@ public function testMapType() {
}
/**
+* Tests the outputCompressed method
+*
+*/
+ public function testOutputCompressed() {
+ $response = new CakeResponse();
+
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip';
+ $result = $response->outputCompressed();
+ $this->assertFalse($result);
+
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = '';
+ $result = $response->outputCompressed();
+ $this->assertFalse($result);
+
+ if (!extension_loaded("zlib")) {
+ $this->markTestSkipped('Skipping further tests for outputCompressed as zlib extension is not loaded');
+ }
+ if (php_sapi_name() !== 'cli') {
+ $this->markTestSkipped('Testing outputCompressed method with compression enabled done only in cli');
+ }
+
+ if (ini_get("zlib.output_compression") !== '1') {
+ ob_start('ob_gzhandler');
+ }
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip';
+ $result = $response->outputCompressed();
+ $this->assertTrue($result);
+
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = '';
+ $result = $response->outputCompressed();
+ $this->assertFalse($result);
+ if (ini_get("zlib.output_compression") !== '1') {
+ ob_get_clean();
+ }
+ }
+
+/**
* Tests the send and setting of Content-Length
*
*/
View
9 lib/Cake/Test/Case/Network/Http/HttpResponseTest.php
@@ -356,6 +356,15 @@ public function testDecodeBody() {
$r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
$this->assertEquals($r, $sample['decoded']);
+
+ $encoding = 'chunked';
+ $sample = array(
+ 'encoded' => "19\nThis is a chunked message\r\n0\n",
+ 'decoded' => array('body' => "This is a chunked message", 'header' => false)
+ );
+
+ $r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
+ $this->assertEquals($r, $sample['decoded'], 'Inconsistent line terminators should be tolerated.');
}
/**
View
358 lib/Cake/Test/Case/Routing/DispatcherTest.php
@@ -1191,113 +1191,117 @@ public function testAssets() {
} catch (MissingControllerException $e) {
$this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
}
+ }
- ob_start();
- $Dispatcher->dispatch(new CakeRequest('theme/test_theme/flash/theme_test.swf'), $response);
- $result = ob_get_clean();
-
- $file = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'webroot' . DS . 'flash' . DS . 'theme_test.swf');
- $this->assertEqual($file, $result);
- $this->assertEqual('this is just a test to load swf file from the theme.', $result);
-
- ob_start();
- $Dispatcher->dispatch(new CakeRequest('theme/test_theme/pdfs/theme_test.pdf'), $response);
- $result = ob_get_clean();
- $file = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'webroot' . DS . 'pdfs' . DS . 'theme_test.pdf');
- $this->assertEqual($file, $result);
- $this->assertEqual('this is just a test to load pdf file from the theme.', $result);
-
- ob_start();
- $Dispatcher->dispatch(new CakeRequest('theme/test_theme/img/test.jpg'), $response);
- $result = ob_get_clean();
- $file = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'webroot' . DS . 'img' . DS . 'test.jpg');
- $this->assertEqual($file, $result);
-
- ob_start();
- $Dispatcher->asset('theme/test_theme/css/test_asset.css', $response);
- $result = ob_get_clean();
- $this->assertEqual('this is the test asset css file', $result);
-
- ob_start();
- $Dispatcher->asset('theme/test_theme/js/theme.js', $response);
- $result = ob_get_clean();
- $this->assertEqual('root theme js file', $result);
-
- ob_start();
- $Dispatcher->asset('theme/test_theme/js/one/theme_one.js', $response);
- $result = ob_get_clean();
- $this->assertEqual('nested theme js file', $result);
-
- ob_start();
- $Dispatcher->asset('test_plugin/root.js', $response);
- $result = ob_get_clean();
- $expected = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'webroot' . DS . 'root.js');
- $this->assertEqual($expected, $result);
-
- ob_start();
- $Dispatcher->dispatch(new CakeRequest('test_plugin/flash/plugin_test.swf'), $response);
- $result = ob_get_clean();
- $file = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'webroot' . DS . 'flash' . DS . 'plugin_test.swf');
- $this->assertEqual($file, $result);
- $this->assertEqual('this is just a test to load swf file from the plugin.', $result);
-
- ob_start();
- $Dispatcher->dispatch(new CakeRequest('test_plugin/pdfs/plugin_test.pdf'), $response);
- $result = ob_get_clean();
- $file = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'webroot' . DS . 'pdfs' . DS . 'plugin_test.pdf');
- $this->assertEqual($file, $result);
- $this->assertEqual('this is just a test to load pdf file from the plugin.', $result);
-
- ob_start();
- $Dispatcher->asset('test_plugin/js/test_plugin/test.js', $response);
- $result = ob_get_clean();
- $this->assertEqual('alert("Test App");', $result);
-
- ob_start();
- $Dispatcher->asset('test_plugin/js/test_plugin/test.js', $response);
- $result = ob_get_clean();
- $this->assertEqual('alert("Test App");', $result);
-
- ob_start();
- $Dispatcher->asset('test_plugin/css/test_plugin_asset.css', $response);
- $result = ob_get_clean();
- $this->assertEqual('this is the test plugin asset css file', $result);
+/**
+ * Data provider for asset()
+ *
+ * - theme assets.
+ * - plugin assets.
+ * - plugin assets in sub directories.
+ * - unknown plugin assets.
+ *
+ * @return array
+ */
+ public static function assetProvider() {
+ return array(
+ array(
+ 'theme/test_theme/flash/theme_test.swf',
+ 'View/Themed/TestTheme/webroot/flash/theme_test.swf'
+ ),
+ array(
+ 'theme/test_theme/pdfs/theme_test.pdf',
+ 'View/Themed/TestTheme/webroot/pdfs/theme_test.pdf'
+ ),
+ array(
+ 'theme/test_theme/img/test.jpg',
+ 'View/Themed/TestTheme/webroot/img/test.jpg'
+ ),
+ array(
+ 'theme/test_theme/css/test_asset.css',
+ 'View/Themed/TestTheme/webroot/css/test_asset.css'
+ ),
+ array(
+ 'theme/test_theme/js/theme.js',
+ 'View/Themed/TestTheme/webroot/js/theme.js'
+ ),
+ array(
+ 'theme/test_theme/js/one/theme_one.js',
+ 'View/Themed/TestTheme/webroot/js/one/theme_one.js'
+ ),
+ array(
+ 'test_plugin/root.js',
+ 'Plugin/TestPlugin/webroot/root.js'
+ ),
+ array(
+ 'test_plugin/flash/plugin_test.swf',
+ 'Plugin/TestPlugin/webroot/flash/plugin_test.swf'
+ ),
+ array(
+ 'test_plugin/pdfs/plugin_test.pdf',
+ 'Plugin/TestPlugin/webroot/pdfs/plugin_test.pdf'
+ ),
+ array(
+ 'test_plugin/js/test_plugin/test.js',
+ 'Plugin/TestPlugin/webroot/js/test_plugin/test.js'
+ ),
+ array(
+ 'test_plugin/css/test_plugin_asset.css',
+ 'Plugin/TestPlugin/webroot/css/test_plugin_asset.css'
+ ),
+ array(
+ 'test_plugin/img/cake.icon.gif',
+ 'Plugin/TestPlugin/webroot/img/cake.icon.gif'
+ ),
+ array(
+ 'plugin_js/js/plugin_js.js',
+ 'Plugin/PluginJs/webroot/js/plugin_js.js'
+ ),
+ array(
+ 'plugin_js/js/one/plugin_one.js',
+ 'Plugin/PluginJs/webroot/js/one/plugin_one.js'
+ ),
+ array(
+ 'test_plugin/css/unknown.extension',
+ 'Plugin/TestPlugin/webroot/css/unknown.extension'
+ ),
+ array(
+ 'test_plugin/css/theme_one.htc',
+ 'Plugin/TestPlugin/webroot/css/theme_one.htc'
+ ),
+ );
+ }
- ob_start();
- $Dispatcher->asset('test_plugin/img/cake.icon.gif', $response);
- $result = ob_get_clean();
- $file = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' .DS . 'webroot' . DS . 'img' . DS . 'cake.icon.gif');
- $this->assertEqual($file, $result);
+/**
+ * Test assets
+ *
+ * @dataProvider assetProvider
+ * @outputBuffering enabled
+ * @return void
+ */
+ public function testAsset($url, $file) {
+ Router::reload();
- ob_start();
- $Dispatcher->asset('plugin_js/js/plugin_js.js', $response);
- $result = ob_get_clean();
- $expected = "alert('win sauce');";
- $this->assertEqual($expected, $result);
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'Vendor' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor'. DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View'. DS)
+ ));
+ CakePlugin::loadAll();
- ob_start();
- $Dispatcher->asset('plugin_js/js/one/plugin_one.js', $response);
- $result = ob_get_clean();
- $expected = "alert('plugin one nested js file');";
- $this->assertEqual($expected, $result);
+ $Dispatcher = new TestDispatcher();
+ $response = $this->getMock('CakeResponse', array('_sendHeader'));
- ob_start();
- $Dispatcher->asset('test_plugin/css/unknown.extension', $response);
+ $Dispatcher->dispatch(new CakeRequest($url), $response);
$result = ob_get_clean();
- $this->assertEqual('Testing a file with unknown extension to mime mapping.', $result);
- ob_start();
- $Dispatcher->asset('test_plugin/css/theme_one.htc', $response);
- $result = ob_get_clean();
- $this->assertEqual('htc file', $result);
+ $path = CAKE. 'Test' . DS . 'test_app' . DS . str_replace('/', DS, $file);
+ $file = file_get_contents($path);
+ $this->assertEquals($file, $result);
- $response = $this->getMock('CakeResponse', array('_sendHeader'));
- ob_start();
- $Dispatcher->asset('test_plugin/css/unknown.extension', $response);
- ob_end_clean();
- $expected = filesize(CakePlugin::path('TestPlugin') . 'webroot' . DS . 'css' . DS . 'unknown.extension');
+ $expected = filesize($path);
$headers = $response->header();
- $this->assertEqual($expected, $headers['Content-Length']);
+ $this->assertEquals($expected, $headers['Content-Length']);
}
/**
@@ -1342,161 +1346,51 @@ public function testAssetFilterForThemeAndPlugins() {
$this->assertFalse($Dispatcher->asset('js/cjs/debug_kit.js', $response));
}
+
/**
- * testFullPageCachingDispatch method
+ * Data provider for cached actions.
*
- * @return void
+ * - Test simple views
+ * - Test views with nocache tags
+ * - Test requests with named + passed params.
+ * - Test themed views.
+ *
+ * @return array
*/
- public function testFullPageCachingDispatch() {
- Configure::write('Cache.disable', false);
- Configure::write('Cache.check', true);
- Configure::write('debug', 2);
-
-
- Router::reload();
- Router::connect('/', array('controller' => 'test_cached_pages', 'action' => 'index'));
- Router::connect('/:controller/:action/*');
-
- App::build(array(
- 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
- ), true);
-
- $dispatcher = new TestDispatcher();
- $request = new CakeRequest('/');
- $response = new CakeResponse();
-
- ob_start();
- $dispatcher->dispatch($request, $response);
- $out = ob_get_clean();
-
- ob_start();
- $dispatcher->cached($request->here);
- $cached = ob_get_clean();
-
- $result = str_replace(array("\t", "\r\n", "\n"), "", $out);
- $cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
- $expected = str_replace(array("\t", "\r\n", "\n"), "", $cached);
-
- $this->assertEqual($expected, $result);
-
- $filename = $this->__cachePath($request->here);
- unlink($filename);
-
- $request = new CakeRequest('test_cached_pages/index');
- $_POST = array(
- 'slasher' => "Up in your's grill \ '"
+ public static function cacheActionProvider() {
+ return array(
+ array('/'),
+ array('test_cached_pages/index'),
+ array('TestCachedPages/index'),
+ array('test_cached_pages/test_nocache_tags'),
+ array('TestCachedPages/test_nocache_tags'),
+ array('test_cached_pages/view/param/param'),
+ array('test_cached_pages/view/foo:bar/value:goo'),
+ array('test_cached_pages/themed'),
);
-
- ob_start();
- $dispatcher->dispatch($request, $response);
- $out = ob_get_clean();
-
- ob_start();
- $dispatcher->cached($request->here);
- $cached = ob_get_clean();
-
- $result = str_replace(array("\t", "\r\n", "\n"), "", $out);
- $cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
- $expected = str_replace(array("\t", "\r\n", "\n"), "", $cached);
-
- $this->assertEqual($expected, $result);
- $filename = $this->__cachePath($request->here);
- unlink($filename);
-
- $request = new CakeRequest('TestCachedPages/index');
-
- ob_start();
- $dispatcher->dispatch($request, $response);
- $out = ob_get_clean();
-
- ob_start();
- $dispatcher->cached($request->here);
- $cached = ob_get_clean();
-
- $result = str_replace(array("\t", "\r\n", "\n"), "", $out);
- $cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
- $expected = str_replace(array("\t", "\r\n", "\n"), "", $cached);
-
- $this->assertEqual($expected, $result);
- $filename = $this->__cachePath($request->here);
- unlink($filename);
-
- $request = new CakeRequest('TestCachedPages/test_nocache_tags');
-
- ob_start();
- $dispatcher->dispatch($request, $response);
- $out = ob_get_clean();
-
- ob_start();
- $dispatcher->cached($request->here);
- $cached = ob_get_clean();
-
- $result = str_replace(array("\t", "\r\n", "\n"), "", $out);
- $cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
- $expected = str_replace(array("\t", "\r\n", "\n"), "", $cached);
-
- $this->assertEqual($expected, $result);
- $filename = $this->__cachePath($request->here);
- unlink($filename);
-
- $request = new CakeRequest('test_cached_pages/view/param/param');
-
- ob_start();
- $dispatcher->dispatch($request, $response);
- $out = ob_get_clean();
-
- ob_start();
- $dispatcher->cached($request->here);
- $cached = ob_get_clean();
-
- $result = str_replace(array("\t", "\r\n", "\n"), "", $out);
- $cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
- $expected = str_replace(array("\t", "\r\n", "\n"), "", $cached);
-
- $this->assertEqual($expected, $result);
- $filename = $this->__cachePath($request->here);
- unlink($filename);
-
- $request = new CakeRequest('test_cached_pages/view/foo:bar/value:goo');
-
- ob_start();
- $dispatcher->dispatch($request, $response);
- $out = ob_get_clean();
-
- ob_start();
- $dispatcher->cached($request->here);
- $cached = ob_get_clean();
-
- $result = str_replace(array("\t", "\r\n", "\n"), "", $out);
- $cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
- $expected = str_replace(array("\t", "\r\n", "\n"), "", $cached);
-
- $this->assertEqual($expected, $result);
- $filename = $this->__cachePath($request->here);
- $this->assertTrue(file_exists($filename));
-
- unlink($filename);
}
-
+
/**
- * Test full page caching with themes.
+ * testFullPageCachingDispatch method
*
+ * @dataProvider cacheActionProvider
* @return void
*/
- public function testFullPageCachingWithThemes() {
+ public function testFullPageCachingDispatch($url) {
Configure::write('Cache.disable', false);
Configure::write('Cache.check', true);
Configure::write('debug', 2);
Router::reload();
+ Router::connect('/', array('controller' => 'test_cached_pages', 'action' => 'index'));
Router::connect('/:controller/:action/*');
App::build(array(
'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
), true);
$dispatcher = new TestDispatcher();
- $request = new CakeRequest('/test_cached_pages/themed');
+ $request = new CakeRequest($url);
$response = new CakeResponse();
ob_start();
View
15 lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php
@@ -426,6 +426,21 @@ public function testTestActionGetData() {
}
/**
+ * Test that REST actions with XML/JSON input work.
+ *
+ * @return void
+ */
+ public function testTestActionJsonData() {
+ $result = $this->Case->testAction('/tests_apps_posts/input_data', array(
+ 'return' => 'vars',
+ 'method' => 'post',
+ 'data' => '{"key":"value","json":true}'
+ ));
+ $this->assertEquals('value', $result['data']['key']);
+ $this->assertTrue($result['data']['json']);
+ }
+
+/**
* Tests autoMock ability
*/
public function testAutoMock() {
View
49 lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php
@@ -127,6 +127,55 @@ public function testGenerateDiff() {
}
}
+
+/**
+ * Test that coverage works with phpunit 3.6 as the data formats from coverage are totally different.
+ *
+ * @return void
+ */
+ public function testPhpunit36Compatibility() {
+ $file = array(
+ 'line 1',
+ 'line 2',
+ 'line 3',
+ 'line 4',
+ 'line 5',
+ 'line 6',
+ 'line 7',
+ 'line 8',
+ 'line 9',
+ 'line 10',
+ );
+ $coverage = array(
+ 1 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 2 => null,
+ 3 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 4 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 5 => array(),
+ 6 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 7 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 8 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 9 => array(),
+ 10 => array('HtmlCoverageReportTest::testSomething', 'HtmlCoverageReportTest::testGenerateDiff')
+ );
+
+ $result = $this->Coverage->generateDiff('myfile.php', $file, $coverage);
+ $this->assertRegExp('/myfile\.php Code coverage\: \d+\.?\d*\%/', $result);
+ $this->assertRegExp('/<div class="code-coverage-results" id\="coverage\-myfile\.php"/', $result);
+ $this->assertRegExp('/<pre>/', $result);
+ foreach ($file as $i => $line) {
+ $this->assertTrue(strpos($line, $result) !== 0, 'Content is missing ' . $i);
+ $class = 'covered';
+ if (in_array($i + 1, array(5, 9, 2))) {
+ $class = 'uncovered';
+ }
+ if ($i + 1 == 2) {
+ $class .= ' dead';
+ }
+ $this->assertTrue(strpos($class, $result) !== 0, 'Class name is wrong ' . $i);
+ }
+ }
+
/**
* test that covering methods show up as title attributes for lines.
*
View
4 lib/Cake/Test/Case/Utility/DebuggerTest.php
@@ -425,7 +425,7 @@ public function testGetInstance() {
*/
public function testNoDbCredentials() {
$config = array(
- 'driver' => 'mysql',
+ 'datasource' => 'mysql',
'persistent' => false,
'host' => 'void.cakephp.org',
'login' => 'cakephp-user',
@@ -437,7 +437,7 @@ public function testNoDbCredentials() {
$output = Debugger::exportVar($config);
$expectedArray = array(
- 'driver' => 'mysql',
+ 'datasource' => 'mysql',
'persistent' => false,
'host' => '*****',
'login' => '*****',
View
18 lib/Cake/Test/Case/View/Helper/FormHelperTest.php
@@ -1925,6 +1925,24 @@ public function testInput() {
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.field', array(
+ 'type' => 'text', 'error' => array('attributes' => array('class' => 'error'))
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text error'),
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field]',
+ 'id' => 'ContactField', 'class' => 'form-error'
+ ),
+ array('div' => array('class' => 'error')),
+ 'Badness!',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.field', array(
'div' => array('tag' => 'span'), 'error' => array('attributes' => array('wrap' => false))
));
$expected = array(
View
9 lib/Cake/Test/Case/View/Helper/TimeHelperTest.php
@@ -515,7 +515,8 @@ public function testIsThisYear() {
$result = $this->Time->isThisYear(mktime(0, 0, 0, mt_rand(1, 12), mt_rand(1, 28), date('Y')));
$this->assertTrue($result);
}
- /**
+
+/**
* testWasYesterday method
*
* @return void
@@ -534,7 +535,8 @@ public function testWasYesterday() {
$result = $this->Time->wasYesterday('-2 days');
$this->assertFalse($result);
}
- /**
+
+/**
* testIsTomorrow method
*
* @return void
@@ -594,7 +596,8 @@ public function testWasWithinLast() {
$this->assertTrue($this->Time->wasWithinLast('1 ', '-1 minute'));
$this->assertTrue($this->Time->wasWithinLast('1 ', '-23 hours -59 minutes -59 seconds'));
}
- /**
+
+/**
* testUserOffset method
*
* @return void
View
30 lib/Cake/Test/Case/View/HelperTest.php
@@ -220,32 +220,48 @@ public static function entityProvider() {
return array(
array(
'HelperTestPost.id',
- array('HelperTestPost', 'id')
+ array('HelperTestPost', 'id'),
+ 'HelperTestPost',
+ 'id'
),
array(
'HelperTestComment.body',
- array('HelperTestComment', 'body')
+ array('HelperTestComment', 'body'),
+ 'HelperTestComment',
+ 'body'
),
array(
'HelperTest.1.Comment.body',
- array('HelperTest', '1', 'Comment', 'body')
+ array('HelperTest', '1', 'Comment', 'body'),
+ 'Comment',
+ 'body'
),
array(
'HelperTestComment.BigField',
- array('HelperTestComment', 'BigField')
+ array('HelperTestComment', 'BigField'),
+ 'HelperTestComment',
+ 'BigField'
+ ),
+ array(
+ 'HelperTestComment.min',
+ array('HelperTestComment', 'min'),
+ 'HelperTestComment',
+ 'min'
)
);
}
/**
- * testFormFieldNameParsing method
+ * Test setting an entity and retriving the entity, model and field.
*
* @dataProvider entityProvider
* @return void
*/
- public function testSetEntity($entity, $expected) {
+ public function testSetEntity($entity, $expected, $modelKey, $fieldKey) {
$this->Helper->setEntity($entity);
$this->assertEquals($expected, $this->Helper->entity());
+ $this->assertEquals($modelKey, $this->Helper->model());
+ $this->assertEquals($fieldKey, $this->Helper->field());
}
/**
@@ -255,7 +271,7 @@ public function testSetEntity($entity, $expected) {
*/
public function testSetEntityScoped() {
$this->Helper->setEntity('HelperTestPost', true);
- $this->assertEquals(array('HelperTestPost'), $this->Helper->entity());
+ $this->assertEquals(array('HelperTestPost'), $this->Helper->entity());
$this->Helper->setEntity('id');
$expected = array('HelperTestPost', 'id');
View
2 lib/Cake/Test/Fixture/CounterCachePostFixture.php
@@ -34,7 +34,7 @@ class CounterCachePostFixture extends CakeTestFixture {
);
public $records = array(
- array('id' => 1, 'title' => 'Rock and Roll', 'user_id' => 66, 'published' => 0),
+ array('id' => 1, 'title' => 'Rock and Roll', 'user_id' => 66, 'published' => false),
array('id' => 2, 'title' => 'Music', 'user_id' => 66, 'published' => true),
array('id' => 3, 'title' => 'Food', 'user_id' => 301, 'published' => true),
);
View
1 lib/Cake/Test/test_app/Console/Templates/test/views/admin_edit.ctp
@@ -0,0 +1 @@
+admin_edit template
View
5 lib/Cake/Test/test_app/Controller/TestsAppsPostsController.php
@@ -53,6 +53,11 @@ public function post_var() {
$this->render('index');
}
+ public function input_data() {
+ $this->set('data', $this->request->input('json_decode', true));
+ $this->render('index');
+ }
+
/**
* Fixturized action for testAction()
*
View
30 lib/Cake/TestSuite/ControllerTestCase.php
@@ -187,11 +187,14 @@ public function __call($name, $arguments) {
}
/**
- * Tests a controller action.
+ * Lets you do functional tests of a controller action.
*
* ### Options:
*
- * - `data` POST or GET data to pass. Depends on the method.
+ * - `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:
* - `vars` Get the set view variables.
@@ -213,14 +216,23 @@ protected function _testAction($url = '', $options = array()) {
), $options);
$_SERVER['REQUEST_METHOD'] = strtoupper($options['method']);
- if (strtoupper($options['method']) == 'GET') {
- $_GET = $options['data'];
- $_POST = array();
- } else {
- $_POST = $options['data'];
- $_GET = array();
+ if (is_array($options['data'])) {
+ if (strtoupper($options['method']) == 'GET') {
+ $_GET = $options['data'];
+ $_POST = array();
+ } else {
+ $_POST = $options['data'];
+ $_GET = array();
+ }
+ }
+ $request = $this->getMock('CakeRequest', array('_readInput'), array($url));
+
+ if (is_string($options['data'])) {
+ $request->expects($this->any())
+ ->method('_readInput')
+ ->will($this->returnValue($options['data']));
}
- $request = new CakeRequest($url);
+
$Dispatch = new ControllerTestDispatcher();
foreach (Router::$routes as $route) {
if ($route instanceof RedirectRoute) {
View
11 lib/Cake/TestSuite/Coverage/BaseCoverageReport.php
@@ -120,7 +120,12 @@ public function filterCoverageDataByPath($path) {
}
/**
- * Calculates how many lines are covered and what the total number of executable lines is
+ * Calculates how many lines are covered and what the total number of executable lines is.
+ *
+ * Handles both PHPUnit3.5 and 3.6 formats.
+ *
+ * 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
@@ -137,10 +142,10 @@ protected function _calculateCoveredLines($fileLines, $coverageData) {
if (!isset($coverageData[$lineno])) {
continue;
}
- if (is_array($coverageData[$lineno])) {
+ if (is_array($coverageData[$lineno]) && !empty($coverageData[$lineno])) {
$covered++;
$total++;
- } else if ($coverageData[$lineno] === -1) {
+ } else if ($coverageData[$lineno] === -1 || $coverageData[$lineno] === array()) {
$total++;
}
}
View
16 lib/Cake/TestSuite/Coverage/HtmlCoverageReport.php
@@ -47,6 +47,11 @@ public function report() {
/**
* Generates an HTML diff for $file based on $coverageData.
*
+ * Handles both PHPUnit3.5 and 3.6 formats.
+ *
+ * 3.5 uses -1 for uncovered, and -2 for dead.
+ * 3.6 uses array() for uncovered and null for dead.
+ *
* @param string $filename Name of the file having coverage generated
* @param array $fileLines File data as an array. See file() for how to get one of these.
* @param array $coverageData Array of coverage data to use to generate HTML diffs with
@@ -65,17 +70,18 @@ public function generateDiff($filename, $fileLines, $coverageData) {
foreach ($fileLines as $lineno => $line) {
$class = 'ignored';
$coveringTests = array();
- if (isset($coverageData[$lineno]) && is_array($coverageData[$lineno])) {
+ if (!empty($coverageData[$lineno]) && is_array($coverageData[$lineno])) {
$coveringTests = array();
foreach ($coverageData[$lineno] as $test) {
- $testReflection = new ReflectionClass(current(explode('::', $test['id'])));
+ $class = (is_array($test) && isset($test['id'])) ? $test['id'] : $test;
+ $testReflection = new ReflectionClass(current(explode('::', $class)));
$this->_testNames[] = $this->_guessSubjectName($testReflection);
- $coveringTests[] = $test['id'];
+ $coveringTests[] = $class;
}
$class = 'covered';
- } elseif (isset($coverageData[$lineno]) && $coverageData[$lineno] === -1) {
+ } elseif (isset($coverageData[$lineno]) && ($coverageData[$lineno] === -1 || $coverageData[$lineno] === array())) {
$class = 'uncovered';
- } elseif (isset($coverageData[$lineno]) && $coverageData[$lineno] === -2) {
+ } elseif (array_key_exists($lineno, $coverageData) && ($coverageData[$lineno] === -2 || $coverageData[$lineno] === null)) {
$class .= ' dead';
}
$diff[] = $this->_paintLine($line, $lineno, $class, $coveringTests);
View
3 lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php
@@ -148,7 +148,7 @@ public function paintFooter($result) {
}
if (method_exists($coverage, 'getData')) {
$report = $coverage->getData();
- echo '<div class="cake-error">' . __('Coverage generation is not supported with PHPUnit 3.6 at this time.') . '</div>';
+ echo $this->paintCoverage($report);
}
}
$this->paintDocumentEnd();
@@ -161,6 +161,7 @@ public function paintFooter($result) {
*/
public function paintCoverage(array $coverage) {
App::uses('HtmlCoverageReport', 'TestSuite/Coverage');
+
$reporter = new HtmlCoverageReport($coverage, $this);
echo $reporter->report();
}
View
10 lib/Cake/View/Helper.php
@@ -446,7 +446,11 @@ public function setEntity($entity, $setScope = false) {
// 0.name, 0.created.month style inputs. Excludes inputs with the modelScope in them.
if (
- $count >= 2 && is_numeric($parts[0]) && !is_numeric($parts[1]) && $this->_modelScope && strpos($entity, $this->_modelScope) === false
+ $count >= 2 &&
+ is_numeric($parts[0]) &&
+ !is_numeric($parts[1]) &&
+ $this->_modelScope &&
+ strpos($entity, $this->_modelScope) === false
) {
$entity = $this->_modelScope . '.' . $entity;
}
@@ -500,14 +504,16 @@ public function model() {
/**
* Gets the currently-used model field of the rendering context.
+ * Strips off fieldsuffixes such as year, month, day, hour, min, meridian
+ * when the current entity is longer than 2 elements.
*
* @return string
*/
public function field() {
$entity = $this->entity();
$count = count($entity);
$last = $entity[$count - 1];
- if (in_array($last, $this->_fieldSuffixes)) {
+ if ($count > 2 && in_array($last, $this->_fieldSuffixes)) {
$last = isset($entity[$count - 2]) ? $entity[$count - 2] : null;
}
return $last;
View
17 lib/Cake/View/Helper/TimeHelper.php
@@ -61,6 +61,7 @@ public function __construct(View $View, $settings = array()) {
* Accepts the special specifier %S which mimics th modifier S for date()
* @param string $time UNIX timestamp
* @return string windows safe and date() function compatible format for strftime
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
*/
public function convertSpecifiers($format, $time = null) {
if (!$time) {
@@ -172,7 +173,8 @@ protected function _translateSpecifier($specifier) {
*
* @param string $serverTime UNIX timestamp
* @param integer $userOffset User's offset from GMT (in hours)
- * @return string UNIX timestamp
+ * @return integer UNIX timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
*/
public function convert($serverTime, $userOffset) {
$serverOffset = $this->serverOffset();
@@ -185,6 +187,7 @@ public function convert($serverTime, $userOffset) {
* Returns server's offset from GMT in seconds.
*
* @return integer Offset
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
*/
public function serverOffset() {
return date('Z', time());
@@ -311,6 +314,7 @@ public function dayAsSql($dateString, $fieldName, $userOffset = null) {
* @param string $dateString Datetime string or Unix timestamp
* @param integer $userOffset User's offset from GMT (in hours)
* @return boolean True if datetime string is today
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
*/
public function isToday($dateString, $userOffset = null) {
$date = $this->fromString($dateString, $userOffset);
@@ -387,7 +391,7 @@ public function isTomorrow($dateString, $userOffset = null) {
*
* @param string $dateString
* @param boolean $range if true returns a range in Y-m-d format
- * @return boolean True if datetime string is within current week
+ * @return mixed 1, 2, 3, or 4 quarter of year or array if $range true
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
*/
public function toQuarter($dateString, $range = false) {
@@ -676,10 +680,10 @@ public function wasWithinLast($timeInterval, $dateString, $userOffset = null) {
}
/**
- * Returns gmt, given either a UNIX timestamp or a valid strtotime() date string.
+ * Returns gmt as a UNIX timestamp.
*
- * @param string $string Datetime string
- * @return string Formatted date string
+ * @param string $string UNIX timestamp or a valid strtotime() date string
+ * @return integer UNIX timestamp
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
*/
public function gmt($string = null) {
@@ -688,7 +692,6 @@ public function gmt($string = null) {
} else {
$string = time();
}
- $string = $this->fromString($string);
$hour = intval(date("G", $string));
$minute = intval(date("i", $string));
$second = intval(date("s", $string));
@@ -709,6 +712,7 @@ public function gmt($string = null) {
* @param boolean $invalid flag to ignore results of fromString == false
* @param integer $userOffset User's offset from GMT (in hours)
* @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
*/
public function format($format, $date = null, $invalid = false, $userOffset = null) {
$time = $this->fromString($date, $userOffset);
@@ -733,6 +737,7 @@ public function format($format, $date = null, $invalid = false, $userOffset = nu
* @param boolean $invalid flag to ignore results of fromString == false
* @param integer $userOffset User's offset from GMT (in hours)
* @return string Formatted and translated date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
*/
public function i18nFormat($date, $format = null, $invalid = false, $userOffset = null) {
$date = $this->fromString($date, $userOffset);

0 comments on commit 254357e

Please sign in to comment.