/lib/Cake/Test/Case/Utility/DebuggerTest.php
PHP | 633 lines | 427 code | 71 blank | 135 comment | 5 complexity | 8d49b7bb56fd4e0449967280df0aaea6 MD5 | raw file
- <?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 Project
- * @since CakePHP(tm) v 1.2.0.5432
- * @license http://www.opensource.org/licenses/mit-license.php MIT License
- */
- App::uses('Debugger', 'Utility');
- /**
- * DebuggerTestCaseDebugger class
- *
- * @package Cake.Test.Case.Utility
- */
- class DebuggerTestCaseDebugger extends Debugger {
- }
- /**
- * DebuggerTest class
- *
- * !!! Be careful with changing code below as it may
- * !!! change line numbers which are used in the tests
- *
- * @package Cake.Test.Case.Utility
- */
- class DebuggerTest extends CakeTestCase {
- protected $_restoreError = false;
- /**
- * setUp method
- *
- * @return void
- */
- public function setUp() {
- parent::setUp();
- Configure::write('debug', 2);
- Configure::write('log', false);
- }
- /**
- * tearDown method
- *
- * @return void
- */
- public function tearDown() {
- parent::tearDown();
- Configure::write('log', true);
- if ($this->_restoreError) {
- restore_error_handler();
- }
- }
- /**
- * testDocRef method
- *
- * @return void
- */
- public function testDocRef() {
- ini_set('docref_root', '');
- $this->assertEquals(ini_get('docref_root'), '');
- new Debugger();
- $this->assertEquals(ini_get('docref_root'), 'http://php.net/');
- }
- /**
- * test Excerpt writing
- *
- * @return void
- */
- public function testExcerpt() {
- $result = Debugger::excerpt(__FILE__, __LINE__, 2);
- $this->assertTrue(is_array($result));
- $this->assertEquals(5, count($result));
- $this->assertRegExp('/function(.+)testExcerpt/', $result[1]);
- $result = Debugger::excerpt(__FILE__, 2, 2);
- $this->assertTrue(is_array($result));
- $this->assertEquals(4, count($result));
- $pattern = '/<code>.*?<span style\="color\: \#\d+">.*?<\?php/';
- $this->assertRegExp($pattern, $result[0]);
- $result = Debugger::excerpt(__FILE__, 11, 2);
- $this->assertEquals(5, count($result));
- $pattern = '/<span style\="color\: \#\d{6}">\*<\/span>/';
- $this->assertRegExp($pattern, $result[0]);
- $return = Debugger::excerpt('[internal]', 2, 2);
- $this->assertTrue(empty($return));
- }
- /**
- * testOutput method
- *
- * @return void
- */
- public function testOutput() {
- set_error_handler('Debugger::showError');
- $this->_restoreError = true;
- $result = Debugger::output(false);
- $this->assertEquals('', $result);
- $out .= '';
- $result = Debugger::output(true);
- $this->assertEquals('Notice', $result[0]['error']);
- $this->assertRegExp('/Undefined variable\:\s+out/', $result[0]['description']);
- $this->assertRegExp('/DebuggerTest::testOutput/i', $result[0]['trace']);
- ob_start();
- Debugger::output('txt');
- $other .= '';
- $result = ob_get_clean();
- $this->assertRegExp('/Undefined variable:\s+other/', $result);
- $this->assertRegExp('/Context:/', $result);
- $this->assertRegExp('/DebuggerTest::testOutput/i', $result);
- ob_start();
- Debugger::output('html');
- $wrong .= '';
- $result = ob_get_clean();
- $this->assertRegExp('/<pre class="cake-error">.+<\/pre>/', $result);
- $this->assertRegExp('/<b>Notice<\/b>/', $result);
- $this->assertRegExp('/variable:\s+wrong/', $result);
- ob_start();
- Debugger::output('js');
- $buzz .= '';
- $result = explode('</a>', ob_get_clean());
- $this->assertTags($result[0], array(
- 'pre' => array('class' => 'cake-error'),
- 'a' => array(
- 'href' => "javascript:void(0);",
- 'onclick' => "preg:/document\.getElementById\('cakeErr[a-z0-9]+\-trace'\)\.style\.display = " .
- "\(document\.getElementById\('cakeErr[a-z0-9]+\-trace'\)\.style\.display == 'none'" .
- " \? '' \: 'none'\);/"
- ),
- 'b' => array(), 'Notice', '/b', ' (8)',
- ));
- $this->assertRegExp('/Undefined variable:\s+buzz/', $result[1]);
- $this->assertRegExp('/<a[^>]+>Code/', $result[1]);
- $this->assertRegExp('/<a[^>]+>Context/', $result[2]);
- $this->assertContains('$wrong = ''', $result[3], 'Context should be HTML escaped.');
- }
- /**
- * Tests that changes in output formats using Debugger::output() change the templates used.
- *
- * @return void
- */
- public function testChangeOutputFormats() {
- set_error_handler('Debugger::showError');
- $this->_restoreError = true;
- Debugger::output('js', array(
- 'traceLine' => '{:reference} - <a href="txmt://open?url=file://{:file}' .
- '&line={:line}">{:path}</a>, line {:line}'
- ));
- $result = Debugger::trace();
- $this->assertRegExp('/' . preg_quote('txmt://open?url=file://', '/') . '(\/|[A-Z]:\\\\)' . '/', $result);
- Debugger::output('xml', array(
- 'error' => '<error><code>{:code}</code><file>{:file}</file><line>{:line}</line>' .
- '{:description}</error>',
- 'context' => "<context>{:context}</context>",
- 'trace' => "<stack>{:trace}</stack>",
- ));
- Debugger::output('xml');
- ob_start();
- $foo .= '';
- $result = ob_get_clean();
- $data = array(
- 'error' => array(),
- 'code' => array(), '8', '/code',
- 'file' => array(), 'preg:/[^<]+/', '/file',
- 'line' => array(), '' . ((int)__LINE__ - 7), '/line',
- 'preg:/Undefined variable:\s+foo/',
- '/error'
- );
- $this->assertTags($result, $data, true);
- }
- /**
- * Test that outputAs works.
- *
- * @return void
- */
- public function testOutputAs() {
- Debugger::outputAs('html');
- $this->assertEquals('html', Debugger::outputAs());
- }
- /**
- * Test that choosing a non-existent format causes an exception
- *
- * @expectedException CakeException
- * @return void
- */
- public function testOutputAsException() {
- Debugger::outputAs('Invalid junk');
- }
- /**
- * Tests that changes in output formats using Debugger::output() change the templates used.
- *
- * @return void
- */
- public function testAddFormat() {
- set_error_handler('Debugger::showError');
- $this->_restoreError = true;
- Debugger::addFormat('js', array(
- 'traceLine' => '{:reference} - <a href="txmt://open?url=file://{:file}' .
- '&line={:line}">{:path}</a>, line {:line}'
- ));
- Debugger::outputAs('js');
- $result = Debugger::trace();
- $this->assertRegExp('/' . preg_quote('txmt://open?url=file://', '/') . '(\/|[A-Z]:\\\\)' . '/', $result);
- Debugger::addFormat('xml', array(
- 'error' => '<error><code>{:code}</code><file>{:file}</file><line>{:line}</line>' .
- '{:description}</error>',
- ));
- Debugger::outputAs('xml');
- ob_start();
- $foo .= '';
- $result = ob_get_clean();
- $data = array(
- '<error',
- '<code', '8', '/code',
- '<file', 'preg:/[^<]+/', '/file',
- '<line', '' . ((int)__LINE__ - 7), '/line',
- 'preg:/Undefined variable:\s+foo/',
- '/error'
- );
- $this->assertTags($result, $data, true);
- }
- /**
- * Test adding a format that is handled by a callback.
- *
- * @return void
- */
- public function testAddFormatCallback() {
- set_error_handler('Debugger::showError');
- $this->_restoreError = true;
- Debugger::addFormat('callback', array('callback' => array($this, 'customFormat')));
- Debugger::outputAs('callback');
- ob_start();
- $foo .= '';
- $result = ob_get_clean();
- $this->assertContains('Notice: I eated an error', $result);
- $this->assertContains('DebuggerTest.php', $result);
- }
- /**
- * Test method for testing addFormat with callbacks.
- *
- * @return void
- */
- public function customFormat($error, $strings) {
- return $error['error'] . ': I eated an error ' . $error['file'];
- }
- /**
- * testTrimPath method
- *
- * @return void
- */
- public function testTrimPath() {
- $this->assertEquals('APP' . DS, Debugger::trimPath(APP));
- $this->assertEquals('CORE', Debugger::trimPath(CAKE_CORE_INCLUDE_PATH));
- $this->assertEquals('ROOT', Debugger::trimPath(ROOT));
- $this->assertEquals('CORE' . DS . 'Cake' . DS, Debugger::trimPath(CAKE));
- $this->assertEquals('Some/Other/Path', Debugger::trimPath('Some/Other/Path'));
- }
- /**
- * testExportVar method
- *
- * @return void
- */
- public function testExportVar() {
- App::uses('Controller', 'Controller');
- $Controller = new Controller();
- $Controller->helpers = array('Html', 'Form');
- $View = new View($Controller);
- $View->int = 2;
- $View->float = 1.333;
- $result = Debugger::exportVar($View);
- $expected = <<<TEXT
- object(View) {
- Helpers => object(HelperCollection) {}
- Blocks => object(ViewBlock) {}
- plugin => null
- name => ''
- passedArgs => array()
- helpers => array(
- (int) 0 => 'Html',
- (int) 1 => 'Form'
- )
- viewPath => ''
- viewVars => array()
- view => null
- layout => 'default'
- layoutPath => null
- autoLayout => true
- ext => '.ctp'
- subDir => null
- theme => null
- cacheAction => false
- validationErrors => array()
- hasRendered => false
- uuids => array()
- request => object(CakeRequest) {}
- response => object(CakeResponse) {}
- elementCache => 'default'
- elementCacheSettings => array()
- Html => object(HtmlHelper) {}
- Form => object(FormHelper) {}
- int => (int) 2
- float => (float) 1.333
- TEXT;
- if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
- $expected .= <<<TEXT
- [protected] _passedVars => array(
- (int) 0 => 'viewVars',
- (int) 1 => 'autoLayout',
- (int) 2 => 'ext',
- (int) 3 => 'helpers',
- (int) 4 => 'view',
- (int) 5 => 'layout',
- (int) 6 => 'name',
- (int) 7 => 'theme',
- (int) 8 => 'layoutPath',
- (int) 9 => 'viewPath',
- (int) 10 => 'request',
- (int) 11 => 'plugin',
- (int) 12 => 'passedArgs',
- (int) 13 => 'cacheAction'
- )
- [protected] _scripts => array()
- [protected] _paths => array()
- [protected] _pathsForPlugin => array()
- [protected] _parents => array()
- [protected] _current => null
- [protected] _currentType => ''
- [protected] _stack => array()
- [protected] _eventManager => object(CakeEventManager) {}
- [protected] _eventManagerConfigured => false
- TEXT;
- }
- $expected .= <<<TEXT
- }
- TEXT;
- $this->assertTextEquals($expected, $result);
- $data = array(
- 1 => 'Index one',
- 5 => 'Index five'
- );
- $result = Debugger::exportVar($data);
- $expected = <<<TEXT
- array(
- (int) 1 => 'Index one',
- (int) 5 => 'Index five'
- )
- TEXT;
- $this->assertTextEquals($expected, $result);
- $data = array(
- 'key' => array(
- 'value'
- )
- );
- $result = Debugger::exportVar($data, 1);
- $expected = <<<TEXT
- array(
- 'key' => array(
- [maximum depth reached]
- )
- )
- TEXT;
- $this->assertTextEquals($expected, $result);
- $data = false;
- $result = Debugger::exportVar($data);
- $expected = <<<TEXT
- false
- TEXT;
- $this->assertTextEquals($expected, $result);
- $file = fopen('php://output', 'w');
- fclose($file);
- $result = Debugger::exportVar($file);
- $this->assertTextEquals('unknown', $result);
- }
- /**
- * Test exporting various kinds of false.
- *
- * @return void
- */
- public function testExportVarZero() {
- $data = array(
- 'nothing' => '',
- 'null' => null,
- 'false' => false,
- 'szero' => '0',
- 'zero' => 0
- );
- $result = Debugger::exportVar($data);
- $expected = <<<TEXT
- array(
- 'nothing' => '',
- 'null' => null,
- 'false' => false,
- 'szero' => '0',
- 'zero' => (int) 0
- )
- TEXT;
- $this->assertTextEquals($expected, $result);
- }
- /**
- * testLog method
- *
- * @return void
- */
- public function testLog() {
- if (file_exists(LOGS . 'debug.log')) {
- unlink(LOGS . 'debug.log');
- }
- CakeLog::config('file', array('engine' => 'File', 'path' => TMP . 'logs' . DS));
- Debugger::log('cool');
- $result = file_get_contents(LOGS . 'debug.log');
- $this->assertContains('DebuggerTest::testLog', $result);
- $this->assertContains("'cool'", $result);
- unlink(LOGS . 'debug.log');
- Debugger::log(array('whatever', 'here'));
- $result = file_get_contents(LOGS . 'debug.log');
- $this->assertContains('DebuggerTest::testLog', $result);
- $this->assertContains('[main]', $result);
- $this->assertContains('array', $result);
- $this->assertContains("'whatever',", $result);
- $this->assertContains("'here'", $result);
- }
- /**
- * test log() depth
- *
- * @return void
- */
- public function testLogDepth() {
- if (file_exists(LOGS . 'debug.log')) {
- unlink(LOGS . 'debug.log');
- }
- CakeLog::config('file', array('engine' => 'File', 'path' => TMP . 'logs' . DS));
- $val = array(
- 'test' => array('key' => 'val')
- );
- Debugger::log($val, LOG_DEBUG, 0);
- $result = file_get_contents(LOGS . 'debug.log');
- $this->assertContains('DebuggerTest::testLog', $result);
- $this->assertNotContains("/'val'/", $result);
- unlink(LOGS . 'debug.log');
- }
- /**
- * testDump method
- *
- * @return void
- */
- public function testDump() {
- $var = array('People' => array(
- array(
- 'name' => 'joeseph',
- 'coat' => 'technicolor',
- 'hair_color' => 'brown'
- ),
- array(
- 'name' => 'Shaft',
- 'coat' => 'black',
- 'hair' => 'black'
- )
- ));
- ob_start();
- Debugger::dump($var);
- $result = ob_get_clean();
- $open = php_sapi_name() === 'cli' ? "\n" : '<pre>';
- $close = php_sapi_name() === 'cli' ? "\n" : '</pre>';
- $expected = <<<TEXT
- {$open}array(
- 'People' => array(
- (int) 0 => array(
- 'name' => 'joeseph',
- 'coat' => 'technicolor',
- 'hair_color' => 'brown'
- ),
- (int) 1 => array(
- 'name' => 'Shaft',
- 'coat' => 'black',
- 'hair' => 'black'
- )
- )
- ){$close}
- TEXT;
- $this->assertTextEquals($expected, $result);
- ob_start();
- Debugger::dump($var, 1);
- $result = ob_get_clean();
- $open = php_sapi_name() === 'cli' ? "\n" : '<pre>';
- $close = php_sapi_name() === 'cli' ? "\n" : '</pre>';
- $expected = <<<TEXT
- {$open}array(
- 'People' => array(
- [maximum depth reached]
- )
- ){$close}
- TEXT;
- $this->assertTextEquals($expected, $result);
- }
- /**
- * test getInstance.
- *
- * @return void
- */
- public function testGetInstance() {
- $result = Debugger::getInstance();
- $this->assertInstanceOf('Debugger', $result);
- $result = Debugger::getInstance('DebuggerTestCaseDebugger');
- $this->assertInstanceOf('DebuggerTestCaseDebugger', $result);
- $result = Debugger::getInstance();
- $this->assertInstanceOf('DebuggerTestCaseDebugger', $result);
- $result = Debugger::getInstance('Debugger');
- $this->assertInstanceOf('Debugger', $result);
- }
- /**
- * testNoDbCredentials
- *
- * If a connection error occurs, the config variable is passed through exportVar
- * *** our database login credentials such that they are never visible
- *
- * @return void
- */
- public function testNoDbCredentials() {
- $config = array(
- 'datasource' => 'mysql',
- 'persistent' => false,
- 'host' => 'void.cakephp.org',
- 'login' => 'cakephp-user',
- 'password' => 'cakephp-password',
- 'database' => 'cakephp-database',
- 'prefix' => ''
- );
- $output = Debugger::exportVar($config);
- $expectedArray = array(
- 'datasource' => 'mysql',
- 'persistent' => false,
- 'host' => '*****',
- 'login' => '*****',
- 'password' => '*****',
- 'database' => '*****',
- 'prefix' => ''
- );
- $expected = Debugger::exportVar($expectedArray);
- $this->assertEquals($expected, $output);
- }
- /**
- * Test that exportVar() doesn't loop through recursive structures.
- *
- * @return void
- */
- public function testExportVarRecursion() {
- $output = Debugger::exportVar($GLOBALS);
- $this->assertContains("'GLOBALS' => [recursion]", $output);
- }
- /**
- * test trace exclude
- *
- * @return void
- */
- public function testTraceExclude() {
- $result = Debugger::trace();
- $this->assertRegExp('/^DebuggerTest::testTraceExclude/', $result);
- $result = Debugger::trace(array(
- 'exclude' => array('DebuggerTest::testTraceExclude')
- ));
- $this->assertNotRegExp('/^DebuggerTest::testTraceExclude/', $result);
- }
- }