HeadScriptTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_View
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. // Call Zend_View_Helper_HeadScriptTest::main() if this source file is executed directly.
  23. if (!defined("PHPUnit_MAIN_METHOD")) {
  24. define("PHPUnit_MAIN_METHOD", "Zend_View_Helper_HeadScriptTest::main");
  25. }
  26. require_once dirname(__FILE__) . '/../../../TestHelper.php';
  27. /** Zend_View_Helper_HeadScript */
  28. require_once 'Zend/View/Helper/HeadScript.php';
  29. /** Zend_View_Helper_Placeholder_Registry */
  30. require_once 'Zend/View/Helper/Placeholder/Registry.php';
  31. /** Zend_Registry */
  32. require_once 'Zend/Registry.php';
  33. /**
  34. * Test class for Zend_View_Helper_HeadScript.
  35. *
  36. * @category Zend
  37. * @package Zend_View
  38. * @subpackage UnitTests
  39. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  40. * @license http://framework.zend.com/license/new-bsd New BSD License
  41. * @group Zend_View
  42. * @group Zend_View_Helper
  43. */
  44. class Zend_View_Helper_HeadScriptTest extends PHPUnit_Framework_TestCase
  45. {
  46. /**
  47. * @var Zend_View_Helper_HeadScript
  48. */
  49. public $helper;
  50. /**
  51. * @var string
  52. */
  53. public $basePath;
  54. /**
  55. * Runs the test methods of this class.
  56. *
  57. * @return void
  58. */
  59. public static function main()
  60. {
  61. $suite = new PHPUnit_Framework_TestSuite("Zend_View_Helper_HeadScriptTest");
  62. $result = PHPUnit_TextUI_TestRunner::run($suite);
  63. }
  64. /**
  65. * Sets up the fixture, for example, open a network connection.
  66. * This method is called before a test is executed.
  67. *
  68. * @return void
  69. */
  70. public function setUp()
  71. {
  72. $regKey = Zend_View_Helper_Placeholder_Registry::REGISTRY_KEY;
  73. if (Zend_Registry::isRegistered($regKey)) {
  74. $registry = Zend_Registry::getInstance();
  75. unset($registry[$regKey]);
  76. }
  77. $this->basePath = dirname(__FILE__) . '/_files/modules';
  78. $this->helper = new Zend_View_Helper_HeadScript();
  79. }
  80. /**
  81. * Tears down the fixture, for example, close a network connection.
  82. * This method is called after a test is executed.
  83. *
  84. * @return void
  85. */
  86. public function tearDown()
  87. {
  88. unset($this->helper);
  89. }
  90. public function testNamespaceRegisteredInPlaceholderRegistryAfterInstantiation()
  91. {
  92. $registry = Zend_View_Helper_Placeholder_Registry::getRegistry();
  93. if ($registry->containerExists('Zend_View_Helper_HeadScript')) {
  94. $registry->deleteContainer('Zend_View_Helper_HeadScript');
  95. }
  96. $this->assertFalse($registry->containerExists('Zend_View_Helper_HeadScript'));
  97. $helper = new Zend_View_Helper_HeadScript();
  98. $this->assertTrue($registry->containerExists('Zend_View_Helper_HeadScript'));
  99. }
  100. public function testHeadScriptReturnsObjectInstance()
  101. {
  102. $placeholder = $this->helper->headScript();
  103. $this->assertTrue($placeholder instanceof Zend_View_Helper_HeadScript);
  104. }
  105. public function testSetPrependAppendAndOffsetSetThrowExceptionsOnInvalidItems()
  106. {
  107. try {
  108. $this->helper->append('foo');
  109. $this->fail('Append should throw exception with invalid item');
  110. } catch (Zend_View_Exception $e) { }
  111. try {
  112. $this->helper->offsetSet(1, 'foo');
  113. $this->fail('OffsetSet should throw exception with invalid item');
  114. } catch (Zend_View_Exception $e) { }
  115. try {
  116. $this->helper->prepend('foo');
  117. $this->fail('Prepend should throw exception with invalid item');
  118. } catch (Zend_View_Exception $e) { }
  119. try {
  120. $this->helper->set('foo');
  121. $this->fail('Set should throw exception with invalid item');
  122. } catch (Zend_View_Exception $e) { }
  123. }
  124. protected function _inflectAction($type)
  125. {
  126. return ucfirst(strtolower($type));
  127. }
  128. protected function _testOverloadAppend($type)
  129. {
  130. $action = 'append' . $this->_inflectAction($type);
  131. $string = 'foo';
  132. for ($i = 0; $i < 3; ++$i) {
  133. $string .= ' foo';
  134. $this->helper->$action($string);
  135. $values = $this->helper->getArrayCopy();
  136. $this->assertEquals($i + 1, count($values));
  137. if ('file' == $type) {
  138. $this->assertEquals($string, $values[$i]->attributes['src']);
  139. } elseif ('script' == $type) {
  140. $this->assertEquals($string, $values[$i]->source);
  141. }
  142. $this->assertEquals('text/javascript', $values[$i]->type);
  143. }
  144. }
  145. protected function _testOverloadPrepend($type)
  146. {
  147. $action = 'prepend' . $this->_inflectAction($type);
  148. $string = 'foo';
  149. for ($i = 0; $i < 3; ++$i) {
  150. $string .= ' foo';
  151. $this->helper->$action($string);
  152. $values = $this->helper->getArrayCopy();
  153. $this->assertEquals($i + 1, count($values));
  154. $first = array_shift($values);
  155. if ('file' == $type) {
  156. $this->assertEquals($string, $first->attributes['src']);
  157. } elseif ('script' == $type) {
  158. $this->assertEquals($string, $first->source);
  159. }
  160. $this->assertEquals('text/javascript', $first->type);
  161. }
  162. }
  163. protected function _testOverloadSet($type)
  164. {
  165. $action = 'set' . $this->_inflectAction($type);
  166. $string = 'foo';
  167. for ($i = 0; $i < 3; ++$i) {
  168. $this->helper->appendScript($string);
  169. $string .= ' foo';
  170. }
  171. $this->helper->$action($string);
  172. $values = $this->helper->getArrayCopy();
  173. $this->assertEquals(1, count($values));
  174. if ('file' == $type) {
  175. $this->assertEquals($string, $values[0]->attributes['src']);
  176. } elseif ('script' == $type) {
  177. $this->assertEquals($string, $values[0]->source);
  178. }
  179. $this->assertEquals('text/javascript', $values[0]->type);
  180. }
  181. protected function _testOverloadOffsetSet($type)
  182. {
  183. $action = 'offsetSet' . $this->_inflectAction($type);
  184. $string = 'foo';
  185. $this->helper->$action(5, $string);
  186. $values = $this->helper->getArrayCopy();
  187. $this->assertEquals(1, count($values));
  188. if ('file' == $type) {
  189. $this->assertEquals($string, $values[5]->attributes['src']);
  190. } elseif ('script' == $type) {
  191. $this->assertEquals($string, $values[5]->source);
  192. }
  193. $this->assertEquals('text/javascript', $values[5]->type);
  194. }
  195. public function testOverloadAppendFileAppendsScriptsToStack()
  196. {
  197. $this->_testOverloadAppend('file');
  198. }
  199. public function testOverloadAppendScriptAppendsScriptsToStack()
  200. {
  201. $this->_testOverloadAppend('script');
  202. }
  203. public function testOverloadPrependFileAppendsScriptsToStack()
  204. {
  205. $this->_testOverloadPrepend('file');
  206. }
  207. public function testOverloadPrependScriptAppendsScriptsToStack()
  208. {
  209. $this->_testOverloadPrepend('script');
  210. }
  211. public function testOverloadSetFileOverwritesStack()
  212. {
  213. $this->_testOverloadSet('file');
  214. }
  215. public function testOverloadSetScriptOverwritesStack()
  216. {
  217. $this->_testOverloadSet('script');
  218. }
  219. public function testOverloadOffsetSetFileWritesToSpecifiedIndex()
  220. {
  221. $this->_testOverloadOffsetSet('file');
  222. }
  223. public function testOverloadOffsetSetScriptWritesToSpecifiedIndex()
  224. {
  225. $this->_testOverloadOffsetSet('script');
  226. }
  227. public function testOverloadingThrowsExceptionWithInvalidMethod()
  228. {
  229. try {
  230. $this->helper->fooBar('foo');
  231. $this->fail('Invalid method should raise exception');
  232. } catch (Zend_View_Exception $e) {
  233. }
  234. }
  235. public function testOverloadingWithTooFewArgumentsRaisesException()
  236. {
  237. try {
  238. $this->helper->setScript();
  239. $this->fail('Too few arguments should raise exception');
  240. } catch (Zend_View_Exception $e) {
  241. }
  242. try {
  243. $this->helper->offsetSetScript(5);
  244. $this->fail('Too few arguments should raise exception');
  245. } catch (Zend_View_Exception $e) {
  246. }
  247. }
  248. public function testHeadScriptAppropriatelySetsScriptItems()
  249. {
  250. $this->helper->headScript('FILE', 'foo', 'set')
  251. ->headScript('SCRIPT', 'bar', 'prepend')
  252. ->headScript('SCRIPT', 'baz', 'append');
  253. $items = $this->helper->getArrayCopy();
  254. for ($i = 0; $i < 3; ++$i) {
  255. $item = $items[$i];
  256. switch ($i) {
  257. case 0:
  258. $this->assertObjectHasAttribute('source', $item);
  259. $this->assertEquals('bar', $item->source);
  260. break;
  261. case 1:
  262. $this->assertObjectHasAttribute('attributes', $item);
  263. $this->assertTrue(isset($item->attributes['src']));
  264. $this->assertEquals('foo', $item->attributes['src']);
  265. break;
  266. case 2:
  267. $this->assertObjectHasAttribute('source', $item);
  268. $this->assertEquals('baz', $item->source);
  269. break;
  270. }
  271. }
  272. }
  273. public function testToStringRendersValidHtml()
  274. {
  275. $this->helper->headScript('FILE', 'foo', 'set')
  276. ->headScript('SCRIPT', 'bar', 'prepend')
  277. ->headScript('SCRIPT', 'baz', 'append');
  278. $string = $this->helper->toString();
  279. $scripts = substr_count($string, '<script ');
  280. $this->assertEquals(3, $scripts);
  281. $scripts = substr_count($string, '</script>');
  282. $this->assertEquals(3, $scripts);
  283. $scripts = substr_count($string, 'src="');
  284. $this->assertEquals(1, $scripts);
  285. $scripts = substr_count($string, '><');
  286. $this->assertEquals(1, $scripts);
  287. $this->assertContains('src="foo"', $string);
  288. $this->assertContains('bar', $string);
  289. $this->assertContains('baz', $string);
  290. $doc = new DOMDocument;
  291. $dom = $doc->loadHtml($string);
  292. $this->assertTrue($dom !== false);
  293. }
  294. public function testCapturingCapturesToObject()
  295. {
  296. $this->helper->captureStart();
  297. echo 'foobar';
  298. $this->helper->captureEnd();
  299. $values = $this->helper->getArrayCopy();
  300. $this->assertEquals(1, count($values), var_export($values, 1));
  301. $item = array_shift($values);
  302. $this->assertContains('foobar', $item->source);
  303. }
  304. public function testIndentationIsHonored()
  305. {
  306. $this->helper->setIndent(4);
  307. $this->helper->appendScript('
  308. var foo = "bar";
  309. document.write(foo.strlen());');
  310. $this->helper->appendScript('
  311. var bar = "baz";
  312. document.write(bar.strlen());');
  313. $string = $this->helper->toString();
  314. $scripts = substr_count($string, ' <script');
  315. $this->assertEquals(2, $scripts);
  316. $this->assertContains(' //', $string);
  317. $this->assertContains('var', $string);
  318. $this->assertContains('document', $string);
  319. $this->assertContains(' document', $string);
  320. }
  321. public function testDoesNotAllowDuplicateFiles()
  322. {
  323. $this->helper->headScript('FILE', '/js/prototype.js');
  324. $this->helper->headScript('FILE', '/js/prototype.js');
  325. $this->assertEquals(1, count($this->helper));
  326. }
  327. public function testRenderingDoesNotRenderArbitraryAttributesByDefault()
  328. {
  329. $this->helper->headScript()->appendFile('/js/foo.js', 'text/javascript', array('bogus' => 'deferred'));
  330. $test = $this->helper->headScript()->toString();
  331. $this->assertNotContains('bogus="deferred"', $test);
  332. }
  333. public function testCanRenderArbitraryAttributesOnRequest()
  334. {
  335. $this->helper->headScript()->appendFile('/js/foo.js', 'text/javascript', array('bogus' => 'deferred'))
  336. ->setAllowArbitraryAttributes(true);
  337. $test = $this->helper->headScript()->toString();
  338. $this->assertContains('bogus="deferred"', $test);
  339. }
  340. public function testCanPerformMultipleSerialCaptures()
  341. {
  342. $this->helper->headScript()->captureStart();
  343. echo "this is something captured";
  344. $this->helper->headScript()->captureEnd();
  345. try {
  346. $this->helper->headScript()->captureStart();
  347. } catch (Zend_View_Exception $e) {
  348. $this->fail('Serial captures should be allowed');
  349. }
  350. echo "this is something else captured";
  351. $this->helper->headScript()->captureEnd();
  352. }
  353. public function testCannotNestCaptures()
  354. {
  355. $this->helper->headScript()->captureStart();
  356. echo "this is something captured";
  357. try {
  358. $this->helper->headScript()->captureStart();
  359. $this->helper->headScript()->captureEnd();
  360. $this->fail('Should not be able to nest captures');
  361. } catch (Zend_View_Exception $e) {
  362. $this->helper->headScript()->captureEnd();
  363. $this->assertContains('Cannot nest', $e->getMessage());
  364. }
  365. $this->helper->headScript()->captureEnd();
  366. }
  367. /**
  368. * @issue ZF-3928
  369. * @link http://framework.zend.com/issues/browse/ZF-3928
  370. */
  371. public function testTurnOffAutoEscapeDoesNotEncodeAmpersand()
  372. {
  373. $this->helper->setAutoEscape(false)->appendFile('test.js?id=123&foo=bar');
  374. $this->assertEquals('<script type="text/javascript" src="test.js?id=123&foo=bar"></script>', $this->helper->toString());
  375. }
  376. public function testConditionalScript()
  377. {
  378. $this->helper->headScript()->appendFile('/js/foo.js', 'text/javascript', array('conditional' => 'lt IE 7'));
  379. $test = $this->helper->headScript()->toString();
  380. $this->assertContains('<!--[if lt IE 7]>', $test);
  381. }
  382. /**
  383. * @issue ZF-5435
  384. */
  385. public function testContainerMaintainsCorrectOrderOfItems()
  386. {
  387. $this->helper->offsetSetFile(1, 'test1.js');
  388. $this->helper->offsetSetFile(20, 'test2.js');
  389. $this->helper->offsetSetFile(10, 'test3.js');
  390. $this->helper->offsetSetFile(5, 'test4.js');
  391. $test = $this->helper->toString();
  392. $expected = '<script type="text/javascript" src="test1.js"></script>
  393. <script type="text/javascript" src="test4.js"></script>
  394. <script type="text/javascript" src="test3.js"></script>
  395. <script type="text/javascript" src="test2.js"></script>';
  396. $this->assertEquals($expected, $test);
  397. }
  398. }
  399. // Call Zend_View_Helper_HeadScriptTest::main() if this source file is executed directly.
  400. if (PHPUnit_MAIN_METHOD == "Zend_View_Helper_HeadScriptTest::main") {
  401. Zend_View_Helper_HeadScriptTest::main();
  402. }