DebuggerTest.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP Project
  13. * @since 1.2.0
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Test\TestCase\Error;
  17. use Cake\Controller\Controller;
  18. use Cake\Core\Configure;
  19. use Cake\Error\Debugger;
  20. use Cake\Log\Log;
  21. use Cake\TestSuite\TestCase;
  22. use TestApp\Error\TestDebugger;
  23. class DebuggableThing
  24. {
  25. public function __debugInfo()
  26. {
  27. return ['foo' => 'bar', 'inner' => new self()];
  28. }
  29. }
  30. class SecurityThing
  31. {
  32. public $password = 'pass1234';
  33. }
  34. /**
  35. * DebuggerTest class
  36. *
  37. * !!! Be careful with changing code below as it may
  38. * !!! change line numbers which are used in the tests
  39. */
  40. class DebuggerTest extends TestCase
  41. {
  42. protected $_restoreError = false;
  43. /**
  44. * setUp method
  45. *
  46. * @return void
  47. */
  48. public function setUp()
  49. {
  50. parent::setUp();
  51. Configure::write('debug', true);
  52. Log::drop('stderr');
  53. Log::drop('stdout');
  54. }
  55. /**
  56. * tearDown method
  57. *
  58. * @return void
  59. */
  60. public function tearDown()
  61. {
  62. parent::tearDown();
  63. if ($this->_restoreError) {
  64. restore_error_handler();
  65. }
  66. }
  67. /**
  68. * testDocRef method
  69. *
  70. * @return void
  71. */
  72. public function testDocRef()
  73. {
  74. $this->skipIf(
  75. defined('HHVM_VERSION'),
  76. 'HHVM does not output doc references'
  77. );
  78. ini_set('docref_root', '');
  79. $this->assertEquals(ini_get('docref_root'), '');
  80. new Debugger();
  81. $this->assertEquals(ini_get('docref_root'), 'https://secure.php.net/');
  82. }
  83. /**
  84. * test Excerpt writing
  85. *
  86. * @return void
  87. */
  88. public function testExcerpt()
  89. {
  90. $result = Debugger::excerpt(__FILE__, __LINE__ - 1, 2);
  91. $this->assertInternalType('array', $result);
  92. $this->assertCount(5, $result);
  93. $this->assertRegExp('/function(.+)testExcerpt/', $result[1]);
  94. $result = Debugger::excerpt(__FILE__, 2, 2);
  95. $this->assertInternalType('array', $result);
  96. $this->assertCount(4, $result);
  97. $this->skipIf(defined('HHVM_VERSION'), 'HHVM does not highlight php code');
  98. $pattern = '/<code>.*?<span style\="color\: \#\d+">.*?&lt;\?php/';
  99. $this->assertRegExp($pattern, $result[0]);
  100. $result = Debugger::excerpt(__FILE__, 11, 2);
  101. $this->assertCount(5, $result);
  102. $pattern = '/<span style\="color\: \#\d{6}">.*?<\/span>/';
  103. $this->assertRegExp($pattern, $result[0]);
  104. $return = Debugger::excerpt('[internal]', 2, 2);
  105. $this->assertEmpty($return);
  106. $result = Debugger::excerpt(__FILE__, __LINE__, 5);
  107. $this->assertCount(11, $result);
  108. $this->assertContains('Debugger', $result[5]);
  109. $this->assertContains('excerpt', $result[5]);
  110. $this->assertContains('__FILE__', $result[5]);
  111. $result = Debugger::excerpt(__FILE__, 1, 2);
  112. $this->assertCount(3, $result);
  113. $lastLine = count(explode("\n", file_get_contents(__FILE__)));
  114. $result = Debugger::excerpt(__FILE__, $lastLine, 2);
  115. $this->assertCount(3, $result);
  116. }
  117. /**
  118. * Test that setOutputFormat works.
  119. *
  120. * @return void
  121. */
  122. public function testSetOutputFormat()
  123. {
  124. Debugger::setOutputFormat('html');
  125. $this->assertEquals('html', Debugger::getOutputFormat());
  126. }
  127. /**
  128. * Test that getOutputFormat/setOutputFormat works.
  129. *
  130. * @return void
  131. */
  132. public function testGetSetOutputFormat()
  133. {
  134. Debugger::setOutputFormat('html');
  135. $this->assertEquals('html', Debugger::getOutputFormat());
  136. }
  137. /**
  138. * Test that choosing a non-existent format causes an exception
  139. *
  140. * @return void
  141. */
  142. public function testSetOutputAsException()
  143. {
  144. $this->expectException(\InvalidArgumentException::class);
  145. Debugger::setOutputFormat('Invalid junk');
  146. }
  147. /**
  148. * Test outputError with description encoding
  149. *
  150. * @return void
  151. */
  152. public function testOutputErrorDescriptionEncoding()
  153. {
  154. Debugger::setOutputFormat('html');
  155. ob_start();
  156. $debugger = Debugger::getInstance();
  157. $debugger->outputError([
  158. 'error' => 'Notice',
  159. 'code' => E_NOTICE,
  160. 'level' => E_NOTICE,
  161. 'description' => 'Undefined index <script>alert(1)</script>',
  162. 'file' => __FILE__,
  163. 'line' => __LINE__,
  164. ]);
  165. $result = ob_get_clean();
  166. $this->assertContains('&lt;script&gt;', $result);
  167. $this->assertNotContains('<script>', $result);
  168. }
  169. /**
  170. * Tests that the correct line is being highlighted.
  171. *
  172. * @return void
  173. */
  174. public function testOutputErrorLineHighlight()
  175. {
  176. Debugger::setOutputFormat('js');
  177. ob_start();
  178. $debugger = Debugger::getInstance();
  179. $data = [
  180. 'level' => E_NOTICE,
  181. 'code' => E_NOTICE,
  182. 'file' => __FILE__,
  183. 'line' => __LINE__,
  184. 'description' => 'Error description',
  185. 'start' => 1,
  186. ];
  187. $debugger->outputError($data);
  188. $result = ob_get_clean();
  189. $this->assertRegExp('#^\<span class\="code\-highlight"\>.*outputError.*\</span\>$#m', $result);
  190. }
  191. /**
  192. * Tests that changes in output formats using Debugger::output() change the templates used.
  193. *
  194. * @return void
  195. */
  196. public function testAddFormat()
  197. {
  198. Debugger::addFormat('js', [
  199. 'traceLine' => '{:reference} - <a href="txmt://open?url=file://{:file}' .
  200. '&line={:line}">{:path}</a>, line {:line}',
  201. ]);
  202. Debugger::setOutputFormat('js');
  203. $result = Debugger::trace();
  204. $this->assertRegExp('/' . preg_quote('txmt://open?url=file://', '/') . '(\/|[A-Z]:\\\\)' . '/', $result);
  205. Debugger::addFormat('xml', [
  206. 'error' => '<error><code>{:code}</code><file>{:file}</file><line>{:line}</line>' .
  207. '{:description}</error>',
  208. ]);
  209. Debugger::setOutputFormat('xml');
  210. ob_start();
  211. $debugger = Debugger::getInstance();
  212. $debugger->outputError([
  213. 'level' => E_NOTICE,
  214. 'code' => E_NOTICE,
  215. 'file' => __FILE__,
  216. 'line' => __LINE__,
  217. 'description' => 'Undefined variable: foo',
  218. ]);
  219. $result = ob_get_clean();
  220. $expected = [
  221. '<error',
  222. '<code', '8', '/code',
  223. '<file', 'preg:/[^<]+/', '/file',
  224. '<line', '' . ((int)__LINE__ - 9), '/line',
  225. 'preg:/Undefined variable:\s+foo/',
  226. '/error',
  227. ];
  228. $this->assertHtml($expected, $result, true);
  229. }
  230. /**
  231. * Test adding a format that is handled by a callback.
  232. *
  233. * @return void
  234. */
  235. public function testAddFormatCallback()
  236. {
  237. Debugger::addFormat('callback', ['callback' => [$this, 'customFormat']]);
  238. Debugger::setOutputFormat('callback');
  239. ob_start();
  240. $debugger = Debugger::getInstance();
  241. $debugger->outputError([
  242. 'error' => 'Notice',
  243. 'code' => E_NOTICE,
  244. 'level' => E_NOTICE,
  245. 'description' => 'Undefined variable $foo',
  246. 'file' => __FILE__,
  247. 'line' => __LINE__,
  248. ]);
  249. $result = ob_get_clean();
  250. $this->assertContains('Notice: I eated an error', $result);
  251. $this->assertContains('DebuggerTest.php', $result);
  252. }
  253. /**
  254. * Test method for testing addFormat with callbacks.
  255. *
  256. * @return void
  257. */
  258. public function customFormat($error, $strings)
  259. {
  260. echo $error['error'] . ': I eated an error ' . $error['file'];
  261. }
  262. /**
  263. * testTrimPath method
  264. *
  265. * @return void
  266. */
  267. public function testTrimPath()
  268. {
  269. $this->assertEquals('APP/', Debugger::trimPath(APP));
  270. $this->assertEquals('CORE' . DS . 'src' . DS, Debugger::trimPath(CAKE));
  271. $this->assertEquals('Some/Other/Path', Debugger::trimPath('Some/Other/Path'));
  272. }
  273. /**
  274. * testExportVar method
  275. *
  276. * @return void
  277. */
  278. public function testExportVar()
  279. {
  280. $Controller = new Controller();
  281. $Controller->viewBuilder()->setHelpers(['Html', 'Form']);
  282. $View = $Controller->createView();
  283. $View->int = 2;
  284. $View->float = 1.333;
  285. $View->string = ' ';
  286. $result = Debugger::exportVar($View);
  287. $expected = <<<TEXT
  288. object(Cake\View\View) {
  289. Html => object(Cake\View\Helper\HtmlHelper) {}
  290. Form => object(Cake\View\Helper\FormHelper) {}
  291. int => (int) 2
  292. float => (float) 1.333
  293. string => ' '
  294. [protected] _helpers => object(Cake\View\HelperRegistry) {}
  295. [protected] Blocks => object(Cake\View\ViewBlock) {}
  296. [protected] plugin => null
  297. [protected] name => ''
  298. [protected] helpers => [
  299. (int) 0 => 'Html',
  300. (int) 1 => 'Form'
  301. ]
  302. [protected] templatePath => null
  303. [protected] template => null
  304. [protected] layout => 'default'
  305. [protected] layoutPath => ''
  306. [protected] autoLayout => true
  307. [protected] viewVars => []
  308. [protected] _ext => '.php'
  309. [protected] subDir => ''
  310. [protected] theme => null
  311. [protected] request => object(Cake\Http\ServerRequest) {}
  312. [protected] response => object(Cake\Http\Response) {}
  313. [protected] elementCache => 'default'
  314. [protected] _passedVars => [
  315. (int) 0 => 'viewVars',
  316. (int) 1 => 'autoLayout',
  317. (int) 2 => 'helpers',
  318. (int) 3 => 'template',
  319. (int) 4 => 'layout',
  320. (int) 5 => 'name',
  321. (int) 6 => 'theme',
  322. (int) 7 => 'layoutPath',
  323. (int) 8 => 'templatePath',
  324. (int) 9 => 'plugin'
  325. ]
  326. [protected] _paths => []
  327. [protected] _pathsForPlugin => []
  328. [protected] _parents => []
  329. [protected] _current => null
  330. [protected] _currentType => ''
  331. [protected] _stack => []
  332. [protected] _viewBlockClass => 'Cake\View\ViewBlock'
  333. [protected] _eventManager => object(Cake\Event\EventManager) {}
  334. [protected] _eventClass => 'Cake\Event\Event'
  335. [protected] _viewBuilder => null
  336. }
  337. TEXT;
  338. $this->assertTextEquals($expected, $result);
  339. $data = [
  340. 1 => 'Index one',
  341. 5 => 'Index five',
  342. ];
  343. $result = Debugger::exportVar($data);
  344. $expected = <<<TEXT
  345. [
  346. (int) 1 => 'Index one',
  347. (int) 5 => 'Index five'
  348. ]
  349. TEXT;
  350. $this->assertTextEquals($expected, $result);
  351. $data = [
  352. 'key' => [
  353. 'value',
  354. ],
  355. ];
  356. $result = Debugger::exportVar($data, 1);
  357. $expected = <<<TEXT
  358. [
  359. 'key' => [
  360. [maximum depth reached]
  361. ]
  362. ]
  363. TEXT;
  364. $this->assertTextEquals($expected, $result);
  365. $data = false;
  366. $result = Debugger::exportVar($data);
  367. $expected = <<<TEXT
  368. false
  369. TEXT;
  370. $this->assertTextEquals($expected, $result);
  371. $file = fopen('php://output', 'w');
  372. fclose($file);
  373. $result = Debugger::exportVar($file);
  374. $this->assertTextEquals('unknown', $result);
  375. }
  376. /**
  377. * Test exporting various kinds of false.
  378. *
  379. * @return void
  380. */
  381. public function testExportVarZero()
  382. {
  383. $data = [
  384. 'nothing' => '',
  385. 'null' => null,
  386. 'false' => false,
  387. 'szero' => '0',
  388. 'zero' => 0,
  389. ];
  390. $result = Debugger::exportVar($data);
  391. $expected = <<<TEXT
  392. [
  393. 'nothing' => '',
  394. 'null' => null,
  395. 'false' => false,
  396. 'szero' => '0',
  397. 'zero' => (int) 0
  398. ]
  399. TEXT;
  400. $this->assertTextEquals($expected, $result);
  401. }
  402. /**
  403. * testLog method
  404. *
  405. * @return void
  406. */
  407. public function testLog()
  408. {
  409. $mock = $this->getMockBuilder('Cake\Log\Engine\BaseLog')
  410. ->setMethods(['log'])
  411. ->getMock();
  412. Log::setConfig('test', ['engine' => $mock]);
  413. $mock->expects($this->at(0))
  414. ->method('log')
  415. ->with('debug', $this->logicalAnd(
  416. $this->stringContains('DebuggerTest::testLog'),
  417. $this->stringContains('cool')
  418. ));
  419. $mock->expects($this->at(1))
  420. ->method('log')
  421. ->with('debug', $this->logicalAnd(
  422. $this->stringContains('DebuggerTest::testLog'),
  423. $this->stringContains('[main]'),
  424. $this->stringContains("'whatever',"),
  425. $this->stringContains("'here'")
  426. ));
  427. Debugger::log('cool');
  428. Debugger::log(['whatever', 'here']);
  429. Log::drop('test');
  430. }
  431. /**
  432. * test log() depth
  433. *
  434. * @return void
  435. */
  436. public function testLogDepth()
  437. {
  438. $mock = $this->getMockBuilder('Cake\Log\Engine\BaseLog')
  439. ->setMethods(['log'])
  440. ->getMock();
  441. Log::setConfig('test', ['engine' => $mock]);
  442. $mock->expects($this->at(0))
  443. ->method('log')
  444. ->with('debug', $this->logicalAnd(
  445. $this->stringContains('DebuggerTest::testLog'),
  446. $this->stringContains('test'),
  447. $this->logicalNot($this->stringContains('val'))
  448. ));
  449. $val = [
  450. 'test' => ['key' => 'val'],
  451. ];
  452. Debugger::log($val, 'debug', 0);
  453. }
  454. /**
  455. * testDump method
  456. *
  457. * @return void
  458. */
  459. public function testDump()
  460. {
  461. $var = ['People' => [
  462. [
  463. 'name' => 'joeseph',
  464. 'coat' => 'technicolor',
  465. 'hair_color' => 'brown',
  466. ],
  467. [
  468. 'name' => 'Shaft',
  469. 'coat' => 'black',
  470. 'hair' => 'black',
  471. ],
  472. ]];
  473. ob_start();
  474. Debugger::dump($var);
  475. $result = ob_get_clean();
  476. $open = "\n";
  477. $close = "\n\n";
  478. $expected = <<<TEXT
  479. {$open}[
  480. 'People' => [
  481. (int) 0 => [
  482. 'name' => 'joeseph',
  483. 'coat' => 'technicolor',
  484. 'hair_color' => 'brown'
  485. ],
  486. (int) 1 => [
  487. 'name' => 'Shaft',
  488. 'coat' => 'black',
  489. 'hair' => 'black'
  490. ]
  491. ]
  492. ]{$close}
  493. TEXT;
  494. $this->assertTextEquals($expected, $result);
  495. ob_start();
  496. Debugger::dump($var, 1);
  497. $result = ob_get_clean();
  498. $expected = <<<TEXT
  499. {$open}[
  500. 'People' => [
  501. [maximum depth reached]
  502. ]
  503. ]{$close}
  504. TEXT;
  505. $this->assertTextEquals($expected, $result);
  506. }
  507. /**
  508. * test getInstance.
  509. *
  510. * @return void
  511. */
  512. public function testGetInstance()
  513. {
  514. $result = Debugger::getInstance();
  515. $this->assertInstanceOf(Debugger::class, $result);
  516. $result = Debugger::getInstance(TestDebugger::class);
  517. $this->assertInstanceOf(TestDebugger::class, $result);
  518. $result = Debugger::getInstance();
  519. $this->assertInstanceOf(TestDebugger::class, $result);
  520. $result = Debugger::getInstance(Debugger::class);
  521. $this->assertInstanceOf(Debugger::class, $result);
  522. }
  523. /**
  524. * Test that exportVar() doesn't loop through recursive structures.
  525. *
  526. * @return void
  527. */
  528. public function testExportVarRecursion()
  529. {
  530. $output = Debugger::exportVar($GLOBALS);
  531. $this->assertContains("'GLOBALS' => [recursion]", $output);
  532. }
  533. /**
  534. * test trace exclude
  535. *
  536. * @return void
  537. */
  538. public function testTraceExclude()
  539. {
  540. $result = Debugger::trace();
  541. $this->assertRegExp('/^Cake\\\Test\\\TestCase\\\Error\\\DebuggerTest::testTraceExclude/', $result);
  542. $result = Debugger::trace([
  543. 'exclude' => ['Cake\Test\TestCase\Error\DebuggerTest::testTraceExclude'],
  544. ]);
  545. $this->assertNotRegExp('/^Cake\\\Test\\\TestCase\\\Error\\\DebuggerTest::testTraceExclude/', $result);
  546. }
  547. /**
  548. * Tests that __debugInfo is used when available
  549. *
  550. * @return void
  551. */
  552. public function testDebugInfo()
  553. {
  554. $object = new DebuggableThing();
  555. $result = Debugger::exportVar($object, 2);
  556. $expected = <<<eos
  557. object(Cake\Test\TestCase\Error\DebuggableThing) {
  558. 'foo' => 'bar',
  559. 'inner' => object(Cake\Test\TestCase\Error\DebuggableThing) {}
  560. }
  561. eos;
  562. $this->assertEquals($expected, $result);
  563. }
  564. /**
  565. * Tests reading the output mask settings.
  566. *
  567. * @return void
  568. */
  569. public function testSetOutputMask()
  570. {
  571. Debugger::setOutputMask(['password' => '[**********]']);
  572. $this->assertEquals(['password' => '[**********]'], Debugger::outputMask());
  573. Debugger::setOutputMask(['serial' => 'XXXXXX']);
  574. $this->assertEquals(['password' => '[**********]', 'serial' => 'XXXXXX'], Debugger::outputMask());
  575. Debugger::setOutputMask([], false);
  576. $this->assertEquals([], Debugger::outputMask());
  577. }
  578. /**
  579. * Tests the masking of an array key.
  580. *
  581. * @return void
  582. */
  583. public function testMaskArray()
  584. {
  585. Debugger::setOutputMask(['password' => '[**********]']);
  586. $result = Debugger::exportVar(['password' => 'pass1234']);
  587. $expected = "['password'=>[**********]]";
  588. $this->assertEquals($expected, preg_replace('/\s+/', '', $result));
  589. }
  590. /**
  591. * Tests the masking of an array key.
  592. *
  593. * @return void
  594. */
  595. public function testMaskObject()
  596. {
  597. Debugger::setOutputMask(['password' => '[**********]']);
  598. $object = new SecurityThing();
  599. $result = Debugger::exportVar($object);
  600. $expected = 'object(Cake\\Test\\TestCase\\Error\\SecurityThing){password=>[**********]}';
  601. $this->assertEquals($expected, preg_replace('/\s+/', '', $result));
  602. }
  603. /**
  604. * test testPrintVar()
  605. *
  606. * @return void
  607. */
  608. public function testPrintVar()
  609. {
  610. ob_start();
  611. Debugger::printVar('this-is-a-test', ['file' => __FILE__, 'line' => __LINE__], false);
  612. $result = ob_get_clean();
  613. $expectedText = <<<EXPECTED
  614. %s (line %d)
  615. ########## DEBUG ##########
  616. 'this-is-a-test'
  617. ###########################
  618. EXPECTED;
  619. $expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
  620. $this->assertEquals($expected, $result);
  621. ob_start();
  622. $value = '<div>this-is-a-test</div>';
  623. Debugger::printVar($value, ['file' => __FILE__, 'line' => __LINE__], true);
  624. $result = ob_get_clean();
  625. $expectedHtml = <<<EXPECTED
  626. <div class="cake-debug-output" style="direction:ltr">
  627. <span><strong>%s</strong> (line <strong>%d</strong>)</span>
  628. <pre class="cake-debug">
  629. &#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
  630. </pre>
  631. </div>
  632. EXPECTED;
  633. $expected = sprintf($expectedHtml, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 10);
  634. $this->assertEquals($expected, $result);
  635. ob_start();
  636. Debugger::printVar('<div>this-is-a-test</div>', ['file' => __FILE__, 'line' => __LINE__], true);
  637. $result = ob_get_clean();
  638. $expected = <<<EXPECTED
  639. <div class="cake-debug-output" style="direction:ltr">
  640. <span><strong>%s</strong> (line <strong>%d</strong>)</span>
  641. <pre class="cake-debug">
  642. &#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
  643. </pre>
  644. </div>
  645. EXPECTED;
  646. $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 10);
  647. $this->assertEquals($expected, $result);
  648. ob_start();
  649. Debugger::printVar('<div>this-is-a-test</div>', [], true);
  650. $result = ob_get_clean();
  651. $expected = <<<EXPECTED
  652. <div class="cake-debug-output" style="direction:ltr">
  653. <pre class="cake-debug">
  654. &#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
  655. </pre>
  656. </div>
  657. EXPECTED;
  658. $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 10);
  659. $this->assertEquals($expected, $result);
  660. ob_start();
  661. Debugger::printVar('<div>this-is-a-test</div>', ['file' => __FILE__, 'line' => __LINE__]);
  662. $result = ob_get_clean();
  663. $expectedHtml = <<<EXPECTED
  664. <div class="cake-debug-output" style="direction:ltr">
  665. <span><strong>%s</strong> (line <strong>%d</strong>)</span>
  666. <pre class="cake-debug">
  667. &#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
  668. </pre>
  669. </div>
  670. EXPECTED;
  671. $expectedText = <<<EXPECTED
  672. %s (line %d)
  673. ########## DEBUG ##########
  674. '<div>this-is-a-test</div>'
  675. ###########################
  676. EXPECTED;
  677. if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg')) {
  678. $expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 18);
  679. } else {
  680. $expected = sprintf($expectedHtml, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 19);
  681. }
  682. $this->assertEquals($expected, $result);
  683. ob_start();
  684. Debugger::printVar('<div>this-is-a-test</div>');
  685. $result = ob_get_clean();
  686. $expectedHtml = <<<EXPECTED
  687. <div class="cake-debug-output" style="direction:ltr">
  688. <pre class="cake-debug">
  689. &#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
  690. </pre>
  691. </div>
  692. EXPECTED;
  693. $expectedText = <<<EXPECTED
  694. ########## DEBUG ##########
  695. '<div>this-is-a-test</div>'
  696. ###########################
  697. EXPECTED;
  698. if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg')) {
  699. $expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 18);
  700. } else {
  701. $expected = sprintf($expectedHtml, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 19);
  702. }
  703. $this->assertEquals($expected, $result);
  704. ob_start();
  705. Debugger::printVar('<div>this-is-a-test</div>', ['file' => __FILE__, 'line' => __LINE__], false);
  706. $result = ob_get_clean();
  707. $expected = <<<EXPECTED
  708. %s (line %d)
  709. ########## DEBUG ##########
  710. '<div>this-is-a-test</div>'
  711. ###########################
  712. EXPECTED;
  713. $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
  714. $this->assertEquals($expected, $result);
  715. ob_start();
  716. Debugger::printVar('<div>this-is-a-test</div>', ['file' => __FILE__, 'line' => __LINE__], false);
  717. $result = ob_get_clean();
  718. $expected = <<<EXPECTED
  719. %s (line %d)
  720. ########## DEBUG ##########
  721. '<div>this-is-a-test</div>'
  722. ###########################
  723. EXPECTED;
  724. $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
  725. $this->assertEquals($expected, $result);
  726. ob_start();
  727. Debugger::printVar('<div>this-is-a-test</div>', [], false);
  728. $result = ob_get_clean();
  729. $expected = <<<EXPECTED
  730. ########## DEBUG ##########
  731. '<div>this-is-a-test</div>'
  732. ###########################
  733. EXPECTED;
  734. $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
  735. $this->assertEquals($expected, $result);
  736. ob_start();
  737. Debugger::printVar(false, [], false);
  738. $result = ob_get_clean();
  739. $expected = <<<EXPECTED
  740. ########## DEBUG ##########
  741. false
  742. ###########################
  743. EXPECTED;
  744. $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
  745. $this->assertEquals($expected, $result);
  746. }
  747. }