From 2a540ff8a8bb53561cca81b1a7d947db2cce6490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=BCrth?= Date: Sat, 27 Jul 2013 06:51:30 +0200 Subject: [PATCH] Fix for #3515, functional extension & tests https://cakephp.lighthouseapp.com/projects/42648-cakephp/tickets/3515 I used (string) because it is faster than strval() and there are no real benefits in this case. Also enabled assign(), append() and prepend() to take any values convertible to string. Removed try/catch as discussed with ADmad. Changed the three exception expecting tests to check for PHPUnit_Framework_Error now. --- lib/Cake/Test/Case/View/ViewTest.php | 268 +++++++++++++++++++++------ lib/Cake/View/View.php | 13 +- lib/Cake/View/ViewBlock.php | 15 +- 3 files changed, 221 insertions(+), 75 deletions(-) diff --git a/lib/Cake/Test/Case/View/ViewTest.php b/lib/Cake/Test/Case/View/ViewTest.php index fb20bc1b948..0c599ebd817 100644 --- a/lib/Cake/Test/Case/View/ViewTest.php +++ b/lib/Cake/Test/Case/View/ViewTest.php @@ -219,6 +219,26 @@ public function afterLayout($layoutFile) { } +/** + * Class TestObjectWithToString + * + * An object with the magic method __toString() for testing with view blocks. + */ +class TestObjectWithToString { + + public function __toString() { + return "I'm ObjectWithToString"; + } + +} + +/** + * Class TestObjectWithoutToString + * + * An object without the magic method __toString() for testing with view blocks. + */ +class TestObjectWithoutToString { +} /** * ViewTest class @@ -283,7 +303,7 @@ public function tearDown() { } /** - * testGetTemplate method + * Test getViewFileName method * * @return void */ @@ -321,7 +341,7 @@ public function testGetTemplate() { } /** - * testPluginGetTemplate method + * Test getLayoutFileName method on plugin * * @return void */ @@ -343,7 +363,7 @@ public function testPluginGetTemplate() { } /** - * testPluginGetTemplate method + * Test getViewFileName method on plugin * * @return void */ @@ -369,7 +389,7 @@ public function testPluginThemedGetTemplate() { } /** - * test that plugin/$plugin_name is only appended to the paths it should be. + * Test that plugin/$plugin_name is only appended to the paths it should be. * * @return void */ @@ -397,7 +417,7 @@ public function testPluginPathGeneration() { } /** - * test that CamelCase plugins still find their view files. + * Test that CamelCase'd plugins still find their view files. * * @return void */ @@ -424,7 +444,7 @@ public function testCamelCasePluginGetTemplate() { } /** - * testGetTemplate method + * Test getViewFileName method * * @return void */ @@ -517,7 +537,7 @@ public function testGetLayoutFileNamePlugin() { } /** - * testMissingView method + * Test for missing views * * @expectedException MissingViewException * @return void @@ -546,7 +566,7 @@ public function testMissingView() { } /** - * testMissingLayout method + * Test for missing layouts * * @expectedException MissingLayoutException * @return void @@ -573,7 +593,7 @@ public function testMissingLayout() { } /** - * testViewVars method + * Test viewVars method * * @return void */ @@ -582,7 +602,7 @@ public function testViewVars() { } /** - * testUUIDGeneration method + * Test generation of UUIDs method * * @return void */ @@ -596,7 +616,7 @@ public function testUUIDGeneration() { } /** - * testAddInlineScripts method + * Test addInlineScripts method * * @return void */ @@ -611,7 +631,7 @@ public function testAddInlineScripts() { } /** - * testElementExists method + * Test elementExists method * * @return void */ @@ -634,7 +654,7 @@ public function testElementExists() { } /** - * testElement method + * Test element method * * @return void */ @@ -657,7 +677,7 @@ public function testElement() { } /** - * testElementInexistent method + * Test elementInexistent method * * @expectedException PHPUnit_Framework_Error_Notice * @return void @@ -667,7 +687,7 @@ public function testElementInexistent() { } /** - * testElementInexistent2 method + * Test elementInexistent2 method * * @expectedException PHPUnit_Framework_Error_Notice * @return void @@ -677,7 +697,7 @@ public function testElementInexistent2() { } /** - * testElementInexistent3 method + * Test elementInexistent3 method * * @expectedException PHPUnit_Framework_Error_Notice * @return void @@ -687,8 +707,7 @@ public function testElementInexistent3() { } /** - * test that elements can have callbacks - * + * Test that elements can have callbacks */ public function testElementCallbacks() { $this->getMock('Helper', array(), array($this->View), 'ElementCallbackMockHtmlHelper'); @@ -703,7 +722,7 @@ public function testElementCallbacks() { } /** - * test that additional element viewVars don't get overwritten with helpers. + * Test that additional element viewVars don't get overwritten with helpers. * * @return void */ @@ -721,7 +740,7 @@ public function testElementParamsDontOverwriteHelpers() { } /** - * testElementCacheHelperNoCache method + * Test elementCacheHelperNoCache method * * @return void */ @@ -734,7 +753,7 @@ public function testElementCacheHelperNoCache() { } /** - * testElementCache method + * Test elementCache method * * @return void */ @@ -788,7 +807,7 @@ public function testElementCache() { } /** - * test __get allowing access to helpers. + * Test __get allowing access to helpers. * * @return void */ @@ -799,7 +818,7 @@ public function testMagicGet() { } /** - * test that ctp is used as a fallback file extension for elements + * Test that ctp is used as a fallback file extension for elements * * @return void */ @@ -814,7 +833,7 @@ public function testElementCtpFallback() { } /** - * testLoadHelpers method + * Test loadHelpers method * * @return void */ @@ -829,7 +848,7 @@ public function testLoadHelpers() { } /** - * test lazy loading helpers + * Test lazy loading helpers * * @return void */ @@ -842,7 +861,7 @@ public function testLazyLoadHelpers() { } /** - * test the correct triggering of helper callbacks + * Test the correct triggering of helper callbacks * * @return void */ @@ -925,7 +944,7 @@ public function testHelperCallbackTriggering() { } /** - * testBeforeLayout method + * Test beforeLayout method * * @return void */ @@ -937,7 +956,7 @@ public function testBeforeLayout() { } /** - * testAfterLayout method + * Test afterLayout method * * @return void */ @@ -955,7 +974,7 @@ public function testAfterLayout() { } /** - * testRenderLoadHelper method + * Test renderLoadHelper method * * @return void */ @@ -981,7 +1000,7 @@ public function testRenderLoadHelper() { } /** - * testRender method + * Test render method * * @return void */ @@ -1024,7 +1043,7 @@ public function testRender() { } /** - * test that View::$view works + * Test that View::$view works * * @return void */ @@ -1055,7 +1074,7 @@ public function testGetViewFileNameSubdirWithPluginAndViewPath() { } /** - * test that view vars can replace the local helper variables + * Test that view vars can replace the local helper variables * and not overwrite the $this->Helper references * * @return void @@ -1072,7 +1091,7 @@ public function testViewVarOverwritingLocalHelperVar() { } /** - * testGetViewFileName method + * Test getViewFileName method * * @return void */ @@ -1100,7 +1119,7 @@ public function testViewFileName() { } /** - * testRenderCache method + * Test renderCache method * * @return void */ @@ -1323,6 +1342,55 @@ public function testBlockReset() { $this->assertSame('', $result); } +/** + * Test setting a block's content to null + * + * @return void + * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/3938-this-redirectthis-auth-redirecturl-broken + */ + public function testBlockSetNull() { + $this->View->assign('testWithNull', null); + $result = $this->View->fetch('testWithNull'); + $this->assertSame('', $result); + } + +/** + * Test setting a block's content to an object with __toString magic method + * + * @return void + */ + public function testBlockSetObjectWithToString() { + $objectWithToString = new TestObjectWithToString(); + $this->View->assign('testWithObjectWithToString', $objectWithToString); + $result = $this->View->fetch('testWithObjectWithToString'); + $this->assertSame("I'm ObjectWithToString", $result); + } + +/** + * Test setting a block's content to an object without __toString magic method + * + * This should produce a "Object of class TestObjectWithoutToString could not be converted to string" error + * which gets thrown as a PHPUnit_Framework_Error Exception by PHPUnit. + * + * @expectedException PHPUnit_Framework_Error + * @return void + */ + public function testBlockSetObjectWithoutToString() { + $objectWithToString = new TestObjectWithoutToString(); + $this->View->assign('testWithObjectWithoutToString', $objectWithToString); + } + +/** + * Test setting a block's content to a decimal + * + * @return void + */ + public function testBlockSetDecimal() { + $this->View->assign('testWithDecimal', 1.23456789); + $result = $this->View->fetch('testWithDecimal'); + $this->assertEqual('1.23456789', $result); + } + /** * Test appending to a block with append. * @@ -1337,7 +1405,62 @@ public function testBlockAppend() { } /** - * Test prepending to a block with append. + * Test appending null to a block with append. + * + * @return void + * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/3938-this-redirectthis-auth-redirecturl-broken + */ + public function testBlockAppendNull() { + $this->View->assign('testWithNull', 'Block'); + $this->View->append('testWithNull', null); + + $result = $this->View->fetch('testWithNull'); + $this->assertSame('Block', $result); + } + +/** + * Test appending an object with __toString magic method to a block with append. + * + * @return void + */ + public function testBlockAppendObjectWithToString() { + $objectWithToString = new TestObjectWithToString(); + $this->View->assign('testWithObjectWithToString', 'Block '); + $this->View->append('testWithObjectWithToString', $objectWithToString); + $result = $this->View->fetch('testWithObjectWithToString'); + $this->assertSame("Block I'm ObjectWithToString", $result); + } + +/** + * Test appending an object without __toString magic method to a block with append. + * + * This should produce a "Object of class TestObjectWithoutToString could not be converted to string" error + * which gets thrown as a PHPUnit_Framework_Error Exception by PHPUnit. + * + * @expectedException PHPUnit_Framework_Error + * @return void + */ + public function testBlockAppendObjectWithoutToString() { + $objectWithToString = new TestObjectWithoutToString(); + $this->View->assign('testWithObjectWithoutToString', 'Block '); + $this->View->append('testWithObjectWithoutToString', $objectWithToString); + } + +/** + * Test appending a decimal to a block with append. + * + * @return void + */ + public function testBlockAppendDecimal() { + $this->View->assign('testWithDecimal', 'Block '); + $this->View->append('testWithDecimal', 1.23456789); + + $result = $this->View->fetch('testWithDecimal'); + $this->assertSame('Block 1.23456789', $result); + } + +/** + * Test prepending to a block with prepend. * * @return void */ @@ -1350,45 +1473,80 @@ public function testBlockPrepend() { } /** - * You should be able to append to undefined blocks. + * Test prepending null to a block with prepend. * * @return void + * @link https://cakephp.lighthouseapp.com/projects/42648/tickets/3938-this-redirectthis-auth-redirecturl-broken */ - public function testBlockAppendUndefined() { - $this->View->append('test', 'Unknown'); - $result = $this->View->fetch('test'); - $this->assertEquals('Unknown', $result); + public function testBlockPrependNull() { + $this->View->assign('testWithNull', 'Block'); + $this->View->prepend('testWithNull', null); + + $result = $this->View->fetch('testWithNull'); + $this->assertSame('Block', $result); } /** - * You should be able to prepend to undefined blocks. + * Test prepending an object with __toString magic method to a block with prepend. * * @return void */ - public function testBlockPrependUndefined() { - $this->View->prepend('test', 'Unknown'); - $result = $this->View->fetch('test'); - $this->assertEquals('Unknown', $result); + public function testBlockPrependObjectWithToString() { + $objectWithToString = new TestObjectWithToString(); + $this->View->assign('testWithObjectWithToString', ' Block'); + $this->View->prepend('testWithObjectWithToString', $objectWithToString); + $result = $this->View->fetch('testWithObjectWithToString'); + $this->assertSame("I'm ObjectWithToString Block", $result); } /** - * setting an array should cause an exception. + * Test prepending an object without __toString magic method to a block with prepend. * - * @expectedException CakeException + * This should produce a "Object of class TestObjectWithoutToString could not be converted to string" error + * which gets thrown as a PHPUnit_Framework_Error Exception by PHPUnit. + * + * @expectedException PHPUnit_Framework_Error * @return void */ - public function testBlockSetArrayException() { - $this->View->assign('test', array(1, 2, 3)); + public function testBlockPrependObjectWithoutToString() { + $objectWithToString = new TestObjectWithoutToString(); + $this->View->assign('testWithObjectWithoutToString', 'Block '); + $this->View->prepend('testWithObjectWithoutToString', $objectWithToString); } /** - * Appending an array should cause an exception. + * Test prepending a decimal to a block with prepend. * - * @expectedException CakeException * @return void */ - public function testBlockAppendArrayException() { - $this->View->append('test', array(1, 2, 3)); + public function testBlockPrependDecimal() { + $this->View->assign('testWithDecimal', ' Block'); + $this->View->prepend('testWithDecimal', 1.23456789); + + $result = $this->View->fetch('testWithDecimal'); + $this->assertSame('1.23456789 Block', $result); + } + +/** + * You should be able to append to undefined blocks. + * + * @return void + */ + public function testBlockAppendUndefined() { + $this->View->append('test', 'Unknown'); + $result = $this->View->fetch('test'); + $this->assertEquals('Unknown', $result); + } + +/** + * You should be able to prepend to undefined blocks. + * + * @return void + */ + public function testBlockPrependUndefined() { + $this->View->prepend('test', 'Unknown'); + $result = $this->View->fetch('test'); + $this->assertEquals('Unknown', $result); } /** @@ -1543,7 +1701,7 @@ public function testPropertySettingMagicGet() { } /** - * test memory leaks that existed in _paths at one point. + * Test memory leaks that existed in _paths at one point. * * @return void */ @@ -1566,7 +1724,7 @@ public function testMemoryLeakInPaths() { } /** - * tests that a vew block uses default value when not assigned and uses assigned value when it is + * Tests that a vew block uses default value when not assigned and uses assigned value when it is * * @return void */ diff --git a/lib/Cake/View/View.php b/lib/Cake/View/View.php index 7e98108a7c8..d6f01606220 100644 --- a/lib/Cake/View/View.php +++ b/lib/Cake/View/View.php @@ -454,7 +454,7 @@ public function elementExists($name) { * @param string $view Name of view file to use * @param string $layout Layout to use. * @return string Rendered Element - * @throws CakeException if there is an error in the view. + * @throws CakeException If there is an error in the view. */ public function render($view = null, $layout = null) { if ($this->hasRendered) { @@ -640,9 +640,8 @@ public function startIfEmpty($name) { * block will create the block. * * @param string $name Name of the block - * @param string $value The content for the block. + * @param mixed $value The content for the block. * @return void - * @throws CakeException when you use non-string values. * @see ViewBlock::concat() */ public function append($name, $value = null) { @@ -654,9 +653,8 @@ public function append($name, $value = null) { * block will create the block. * * @param string $name Name of the block - * @param string $value The content for the block. + * @param mixed $value The content for the block. * @return void - * @throws CakeException when you use non-string values. * @see ViewBlock::concat() */ public function prepend($name, $value = null) { @@ -668,9 +666,8 @@ public function prepend($name, $value = null) { * existing content. * * @param string $name Name of the block - * @param string $value The content for the block. + * @param mixed $value The content for the block. * @return void - * @throws CakeException when you use non-string values. * @see ViewBlock::set() */ public function assign($name, $value) { @@ -841,7 +838,7 @@ public function __get($name) { * Magic accessor for deprecated attributes. * * @param string $name Name of the attribute to set. - * @param string $value Value of the attribute to set. + * @param mixed $value Value of the attribute to set. * @return mixed */ public function __set($name, $value) { diff --git a/lib/Cake/View/ViewBlock.php b/lib/Cake/View/ViewBlock.php index 1a2fa32bfa5..ecde67d4e7b 100644 --- a/lib/Cake/View/ViewBlock.php +++ b/lib/Cake/View/ViewBlock.php @@ -131,17 +131,13 @@ public function end() { * of the new capturing context will be added to the existing block context. * * @param string $name Name of the block - * @param string $value The content for the block + * @param mixed $value The content for the block * @param string $mode If ViewBlock::APPEND content will be appended to existing content. * If ViewBlock::PREPEND it will be prepended. * @return void - * @throws CakeException when you use non-string values. */ public function concat($name, $value = null, $mode = ViewBlock::APPEND) { if (isset($value)) { - if (!is_string($value)) { - throw new CakeException(__d('cake_dev', '%s must be a string.', '$value')); - } if (!isset($this->_blocks[$name])) { $this->_blocks[$name] = ''; } @@ -166,7 +162,6 @@ public function concat($name, $value = null, $mode = ViewBlock::APPEND) { * @param string $name Name of the block * @param string $value The content for the block. * @return void - * @throws CakeException when you use non-string values. * @deprecated As of 2.3 use ViewBlock::concat() instead. */ public function append($name, $value = null) { @@ -178,15 +173,11 @@ public function append($name, $value = null) { * existing content. * * @param string $name Name of the block - * @param string $value The content for the block. + * @param mixed $value The content for the block. * @return void - * @throws CakeException when you use non-string values. */ public function set($name, $value) { - if (!is_string($value)) { - throw new CakeException(__d('cake_dev', 'Blocks can only contain strings.')); - } - $this->_blocks[$name] = $value; + $this->_blocks[$name] = (string)$value; } /**