HelperRegistryTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 2.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\View;
  16. use Cake\Core\Configure;
  17. use Cake\Core\Plugin;
  18. use Cake\TestSuite\TestCase;
  19. use Cake\View\Helper;
  20. use Cake\View\HelperRegistry;
  21. use Cake\View\View;
  22. /**
  23. * Extended HtmlHelper
  24. */
  25. class HtmlAliasHelper extends Helper
  26. {
  27. public function afterRender($viewFile)
  28. {
  29. }
  30. }
  31. /**
  32. * HelperRegistryTest
  33. */
  34. class HelperRegistryTest extends TestCase
  35. {
  36. /**
  37. * @var \Cake\View\HelperRegistry
  38. */
  39. public $Helpers;
  40. /**
  41. * @var \Cake\Event\EventManager
  42. */
  43. public $Events;
  44. /**
  45. * setUp
  46. *
  47. * @return void
  48. */
  49. public function setUp()
  50. {
  51. parent::setUp();
  52. $this->View = new View();
  53. $this->Events = $this->View->eventManager();
  54. $this->Helpers = new HelperRegistry($this->View);
  55. }
  56. /**
  57. * tearDown
  58. *
  59. * @return void
  60. */
  61. public function tearDown()
  62. {
  63. Plugin::unload();
  64. unset($this->Helpers, $this->View);
  65. parent::tearDown();
  66. }
  67. /**
  68. * test loading helpers.
  69. *
  70. * @return void
  71. */
  72. public function testLoad()
  73. {
  74. $result = $this->Helpers->load('Html');
  75. $this->assertInstanceOf('Cake\View\Helper\HtmlHelper', $result);
  76. $this->assertInstanceOf('Cake\View\Helper\HtmlHelper', $this->Helpers->Html);
  77. $result = $this->Helpers->loaded();
  78. $this->assertEquals(['Html'], $result, 'loaded() results are wrong.');
  79. }
  80. /**
  81. * test lazy loading of helpers
  82. *
  83. * @return void
  84. */
  85. public function testLazyLoad()
  86. {
  87. $result = $this->Helpers->Html;
  88. $this->assertInstanceOf('Cake\View\Helper\HtmlHelper', $result);
  89. $result = $this->Helpers->Form;
  90. $this->assertInstanceOf('Cake\View\Helper\FormHelper', $result);
  91. $this->View->plugin = 'TestPlugin';
  92. Plugin::load(['TestPlugin']);
  93. $result = $this->Helpers->OtherHelper;
  94. $this->assertInstanceOf('TestPlugin\View\Helper\OtherHelperHelper', $result);
  95. }
  96. /**
  97. * test lazy loading of helpers
  98. *
  99. * @expectedException \Cake\View\Exception\MissingHelperException
  100. * @return void
  101. */
  102. public function testLazyLoadException()
  103. {
  104. $this->Helpers->NotAHelper;
  105. }
  106. /**
  107. * Test that loading helpers subscribes to events.
  108. *
  109. * @return void
  110. */
  111. public function testLoadSubscribeEvents()
  112. {
  113. $this->Helpers->load('Html', ['className' => __NAMESPACE__ . '\HtmlAliasHelper']);
  114. $result = $this->Events->listeners('View.afterRender');
  115. $this->assertCount(1, $result);
  116. }
  117. /**
  118. * Tests loading as an alias
  119. *
  120. * @return void
  121. */
  122. public function testLoadWithAlias()
  123. {
  124. $result = $this->Helpers->load('Html', ['className' => __NAMESPACE__ . '\HtmlAliasHelper']);
  125. $this->assertInstanceOf(__NAMESPACE__ . '\HtmlAliasHelper', $result);
  126. $this->assertInstanceOf(__NAMESPACE__ . '\HtmlAliasHelper', $this->Helpers->Html);
  127. $result = $this->Helpers->loaded();
  128. $this->assertEquals(['Html'], $result, 'loaded() results are wrong.');
  129. $result = $this->Helpers->load('Html');
  130. $this->assertInstanceOf(__NAMESPACE__ . '\HtmlAliasHelper', $result);
  131. }
  132. /**
  133. * Test loading helpers with aliases and plugins.
  134. *
  135. * @return void
  136. */
  137. public function testLoadWithAliasAndPlugin()
  138. {
  139. Plugin::load('TestPlugin');
  140. $result = $this->Helpers->load('SomeOther', ['className' => 'TestPlugin.OtherHelper']);
  141. $this->assertInstanceOf('TestPlugin\View\Helper\OtherHelperHelper', $result);
  142. $this->assertInstanceOf('TestPlugin\View\Helper\OtherHelperHelper', $this->Helpers->SomeOther);
  143. $result = $this->Helpers->loaded();
  144. $this->assertEquals(['SomeOther'], $result, 'loaded() results are wrong.');
  145. }
  146. /**
  147. * test that the enabled setting disables the helper.
  148. *
  149. * @return void
  150. */
  151. public function testLoadWithEnabledFalse()
  152. {
  153. $result = $this->Helpers->load('Html', ['enabled' => false]);
  154. $this->assertInstanceOf('Cake\View\Helper\HtmlHelper', $result);
  155. $this->assertInstanceOf('Cake\View\Helper\HtmlHelper', $this->Helpers->Html);
  156. $this->assertEmpty($this->Events->listeners('View.beforeRender'));
  157. }
  158. /**
  159. * test missinghelper exception
  160. *
  161. * @expectedException \Cake\View\Exception\MissingHelperException
  162. * @return void
  163. */
  164. public function testLoadMissingHelper()
  165. {
  166. $this->Helpers->load('ThisHelperShouldAlwaysBeMissing');
  167. }
  168. /**
  169. * test loading a plugin helper.
  170. *
  171. * @return void
  172. */
  173. public function testLoadPluginHelper()
  174. {
  175. Plugin::load(['TestPlugin']);
  176. $result = $this->Helpers->load('TestPlugin.OtherHelper');
  177. $this->assertInstanceOf('TestPlugin\View\Helper\OtherHelperHelper', $result, 'Helper class is wrong.');
  178. $this->assertInstanceOf('TestPlugin\View\Helper\OtherHelperHelper', $this->Helpers->OtherHelper, 'Class is wrong');
  179. }
  180. /**
  181. * test loading helpers with dotted aliases
  182. *
  183. * @return void
  184. */
  185. public function testLoadPluginHelperDottedAlias()
  186. {
  187. Plugin::load(['TestPlugin']);
  188. $result = $this->Helpers->load('thing.helper', [
  189. 'className' => 'TestPlugin.OtherHelper',
  190. ]);
  191. $this->assertInstanceOf('TestPlugin\View\Helper\OtherHelperHelper', $result, 'Helper class is wrong.');
  192. $this->assertInstanceOf(
  193. 'TestPlugin\View\Helper\OtherHelperHelper',
  194. $this->Helpers->get('thing.helper'),
  195. 'Class is wrong'
  196. );
  197. $this->assertTrue($this->Helpers->has('thing.helper'));
  198. $this->assertFalse($this->Helpers->has('thing'));
  199. $this->assertFalse($this->Helpers->has('helper'));
  200. $this->Helpers->unload('thing.helper');
  201. $this->assertFalse($this->Helpers->has('thing.helper'), 'Should be gone now.');
  202. }
  203. /**
  204. * Test reset.
  205. *
  206. * @return void
  207. */
  208. public function testReset()
  209. {
  210. Configure::write('App.namespace', 'TestApp');
  211. $instance = $this->Helpers->load('EventListenerTest');
  212. $this->assertSame(
  213. $instance,
  214. $this->Helpers->EventListenerTest,
  215. 'Instance in registry should be the same as previously loaded'
  216. );
  217. $this->assertCount(1, $this->Events->listeners('View.beforeRender'));
  218. $this->Helpers->reset();
  219. $this->assertCount(0, $this->Events->listeners('View.beforeRender'));
  220. $this->assertNotSame($instance, $this->Helpers->load('EventListenerTest'));
  221. }
  222. /**
  223. * Test unloading.
  224. *
  225. * @return void
  226. */
  227. public function testUnload()
  228. {
  229. Configure::write('App.namespace', 'TestApp');
  230. $instance = $this->Helpers->load('EventListenerTest');
  231. $this->assertSame(
  232. $instance,
  233. $this->Helpers->EventListenerTest,
  234. 'Instance in registry should be the same as previously loaded'
  235. );
  236. $this->assertCount(1, $this->Events->listeners('View.beforeRender'));
  237. $this->assertNull($this->Helpers->unload('EventListenerTest'), 'No return expected');
  238. $this->assertCount(0, $this->Events->listeners('View.beforeRender'));
  239. }
  240. /**
  241. * Test that unloading a none existing helper triggers an error.
  242. *
  243. * This should produce an "Object "Foo" was not loaded before." error
  244. * which gets thrown as a \PHPUnit\Framework\Error\Error Exception by PHPUnit.
  245. *
  246. * @expectedException \PHPUnit\Framework\Error\Error
  247. * @expectedExceptionMessage Object "Foo" was not loaded before.
  248. * @return void
  249. */
  250. public function testUnloadUnknown()
  251. {
  252. $this->Helpers->unload('Foo');
  253. }
  254. /**
  255. * Test that unloading a none existing plugin helper triggers an error.
  256. *
  257. * This should produce an "Object "Plugin.Foo" was not loaded before. Remember to omit plugin prefixes." error
  258. * which gets thrown as a \PHPUnit\Framework\Error\Error Exception by PHPUnit.
  259. *
  260. * @expectedException \PHPUnit\Framework\Error\Error
  261. * @expectedExceptionMessage Object "Plugin.Foo" was not loaded before. Remember to omit plugin prefixes.
  262. * @return void
  263. */
  264. public function testUnloadUnknownPluginHelper()
  265. {
  266. $this->Helpers->unload('Plugin.Foo');
  267. }
  268. /**
  269. * Loading a helper with no config should "just work"
  270. *
  271. * The addToAssertionCount call is to record that no exception was thrown
  272. *
  273. * @return void
  274. */
  275. public function testLoadMultipleTimesNoConfig()
  276. {
  277. $this->Helpers->load('Html');
  278. $this->Helpers->load('Html');
  279. $this->addToAssertionCount(1);
  280. }
  281. /**
  282. * Loading a helper with bespoke config, where the subsequent load specifies no
  283. * config should "just work"
  284. *
  285. * The addToAssertionCount call is to record that no exception was thrown
  286. *
  287. * @return void
  288. */
  289. public function testLoadMultipleTimesAlreadyConfigured()
  290. {
  291. $this->Helpers->load('Html', ['same' => 'stuff']);
  292. $this->Helpers->load('Html');
  293. $this->addToAssertionCount(1);
  294. }
  295. /**
  296. * Loading a helper overriding defaults to default value
  297. * should "just work"
  298. *
  299. * @return void
  300. */
  301. public function testLoadMultipleTimesDefaultConfigValuesWorks()
  302. {
  303. $this->Helpers->load('Number', ['engine' => 'Cake\I18n\Number']);
  304. $this->Helpers->load('Number');
  305. $this->addToAssertionCount(1);
  306. }
  307. /**
  308. * Loading a helper with different config, should throw an exception
  309. *
  310. * @expectedException \RuntimeException
  311. * @expectedExceptionMessage The "Html" alias has already been loaded with the following
  312. * @return void
  313. */
  314. public function testLoadMultipleTimesDifferentConfigured()
  315. {
  316. $this->Helpers->load('Html');
  317. $this->Helpers->load('Html', ['same' => 'stuff']);
  318. }
  319. /**
  320. * Loading a helper with different config, should throw an exception
  321. *
  322. * @expectedException \RuntimeException
  323. * @expectedExceptionMessage The "Html" alias has already been loaded with the following
  324. * @return void
  325. */
  326. public function testLoadMultipleTimesDifferentConfigValues()
  327. {
  328. $this->Helpers->load('Html', ['key' => 'value']);
  329. $this->Helpers->load('Html', ['key' => 'new value']);
  330. }
  331. }