PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/tests/Zend/Loader/AutoloaderTest.php

https://github.com/mridgway/zf2
PHP | 454 lines | 348 code | 64 blank | 42 comment | 6 complexity | 71267fb0c1ea8c1be5b3648b08a996b1 MD5 | raw file
  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_Loader
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2010 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. namespace ZendTest\Loader;
  23. use \stdClass,
  24. \Zend\Loader\Autoloader as ZendAutoloader;
  25. /**
  26. * @category Zend
  27. * @package Zend_Loader
  28. * @subpackage UnitTests
  29. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  30. * @license http://framework.zend.com/license/new-bsd New BSD License
  31. * @group Zend_Loader
  32. */
  33. class AutoloaderTest extends \PHPUnit_Framework_TestCase
  34. {
  35. public function setUp()
  36. {
  37. // Store original autoloaders
  38. $this->loaders = spl_autoload_functions();
  39. if (!is_array($this->loaders)) {
  40. // spl_autoload_functions does not return empty array when no
  41. // autoloaders registered...
  42. $this->loaders = array();
  43. }
  44. // Store original include_path
  45. $this->includePath = get_include_path();
  46. ZendAutoloader::resetInstance();
  47. $this->autoloader = ZendAutoloader::getInstance();
  48. // initialize 'error' member for tests that utilize error handling
  49. $this->error = null;
  50. }
  51. public function tearDown()
  52. {
  53. // Restore original autoloaders
  54. $loaders = spl_autoload_functions();
  55. foreach ($loaders as $loader) {
  56. spl_autoload_unregister($loader);
  57. }
  58. foreach ($this->loaders as $loader) {
  59. spl_autoload_register($loader);
  60. }
  61. // Retore original include_path
  62. set_include_path($this->includePath);
  63. // Reset autoloader instance so it doesn't affect other tests
  64. ZendAutoloader::resetInstance();
  65. ZendAutoloader::getInstance();
  66. }
  67. public function testAutoloaderShouldBeSingleton()
  68. {
  69. $autoloader = ZendAutoloader::getInstance();
  70. $this->assertSame($this->autoloader, $autoloader);
  71. }
  72. public function testSingletonInstanceShouldAllowReset()
  73. {
  74. ZendAutoloader::resetInstance();
  75. $autoloader = ZendAutoloader::getInstance();
  76. $this->assertNotSame($this->autoloader, $autoloader);
  77. }
  78. public function testAutoloaderShouldRegisterItselfWithSplAutoloader()
  79. {
  80. $autoloaders = spl_autoload_functions();
  81. $found = false;
  82. foreach ($autoloaders as $loader) {
  83. if (is_array($loader)) {
  84. if (('autoload' == $loader[1]) && ($loader[0] === get_class($this->autoloader))) {
  85. $found = true;
  86. break;
  87. }
  88. }
  89. }
  90. $this->assertTrue($found, 'Autoloader instance not found in spl_autoload stack: ' . var_export($autoloaders, 1));
  91. }
  92. public function testDefaultAutoloaderShouldBeZendLoader()
  93. {
  94. $this->assertSame(array('\\Zend\\Loader', 'loadClass'), $this->autoloader->getDefaultAutoloader());
  95. }
  96. public function testDefaultAutoloaderShouldBeMutable()
  97. {
  98. $this->autoloader->setDefaultAutoloader(array($this, 'autoload'));
  99. $this->assertSame(array($this, 'autoload'), $this->autoloader->getDefaultAutoloader());
  100. }
  101. public function testSpecifyingInvalidDefaultAutoloaderShouldRaiseException()
  102. {
  103. $this->setExpectedException('\\Zend\\Loader\\InvalidCallbackException');
  104. $this->autoloader->setDefaultAutoloader(uniqid());
  105. }
  106. public function testZfNamespacesShouldBeRegisteredByDefault()
  107. {
  108. $namespaces = $this->autoloader->getRegisteredNamespaces();
  109. $this->assertContains('Zend', $namespaces);
  110. $this->assertContains('ZendX', $namespaces);
  111. }
  112. public function testAutoloaderShouldAllowRegisteringArbitraryNamespaces()
  113. {
  114. $this->autoloader->registerNamespace('Phly');
  115. $namespaces = $this->autoloader->getRegisteredNamespaces();
  116. $this->assertContains('Phly', $namespaces);
  117. }
  118. public function testAutoloaderShouldAllowRegisteringMultipleNamespacesAtOnce()
  119. {
  120. $this->autoloader->registerNamespace(array('Phly', 'Solar'));
  121. $namespaces = $this->autoloader->getRegisteredNamespaces();
  122. $this->assertContains('Phly', $namespaces);
  123. $this->assertContains('Solar', $namespaces);
  124. }
  125. public function testRegisteringInvalidNamespaceSpecShouldRaiseException()
  126. {
  127. $this->setExpectedException('\\Zend\\Loader\\InvalidNamespaceException');
  128. $o = new stdClass;
  129. $this->autoloader->registerNamespace($o);
  130. }
  131. public function testAutoloaderShouldAllowUnregisteringNamespaces()
  132. {
  133. $this->autoloader->unregisterNamespace('Zend');
  134. $namespaces = $this->autoloader->getRegisteredNamespaces();
  135. $this->assertNotContains('Zend', $namespaces);
  136. }
  137. public function testAutoloaderShouldAllowUnregisteringMultipleNamespacesAtOnce()
  138. {
  139. $this->autoloader->unregisterNamespace(array('Zend', 'ZendX'));
  140. $namespaces = $this->autoloader->getRegisteredNamespaces();
  141. $this->assertNotContains('Zend', $namespaces);
  142. $this->assertNotContains('ZendX', $namespaces);
  143. }
  144. public function testUnregisteringInvalidNamespaceSpecShouldRaiseException()
  145. {
  146. $this->setExpectedException('\\Zend\\Loader\\InvalidNamespaceException');
  147. $o = new stdClass;
  148. $this->autoloader->unregisterNamespace($o);
  149. }
  150. public function testZfPrefixesShouldBeRegisteredByDefault()
  151. {
  152. $prefixes = $this->autoloader->getRegisteredPrefixes();
  153. $this->assertContains('Zend_', $prefixes);
  154. $this->assertContains('ZendX_', $prefixes);
  155. }
  156. public function testAutoloaderShouldAllowRegisteringArbitraryPrefixes()
  157. {
  158. $this->autoloader->registerPrefix('Phly_');
  159. $prefixes = $this->autoloader->getRegisteredPrefixes();
  160. $this->assertContains('Phly_', $prefixes);
  161. }
  162. public function testAutoloaderShouldAllowRegisteringMultiplePrefixesAtOnce()
  163. {
  164. $this->autoloader->registerPrefix(array('Phly_', 'Solar_'));
  165. $prefixes = $this->autoloader->getRegisteredPrefixes();
  166. $this->assertContains('Phly_', $prefixes);
  167. $this->assertContains('Solar_', $prefixes);
  168. }
  169. public function testRegisteringInvalidPrefixSpecShouldRaiseException()
  170. {
  171. $this->setExpectedException('\\Zend\\Loader\\InvalidPrefixException');
  172. $o = new stdClass;
  173. $this->autoloader->registerPrefix($o);
  174. }
  175. public function testAutoloaderShouldAllowUnregisteringPrefixes()
  176. {
  177. $this->autoloader->unregisterPrefix('Zend');
  178. $prefixes = $this->autoloader->getRegisteredPrefixes();
  179. $this->assertNotContains('Zend', $prefixes);
  180. }
  181. public function testAutoloaderShouldAllowUnregisteringMultiplePrefixesAtOnce()
  182. {
  183. $this->autoloader->unregisterPrefix(array('Zend', 'ZendX'));
  184. $prefixes = $this->autoloader->getRegisteredPrefixes();
  185. $this->assertNotContains('Zend', $prefixes);
  186. $this->assertNotContains('ZendX', $prefixes);
  187. }
  188. public function testUnregisteringInvalidPrefixSpecShouldRaiseException()
  189. {
  190. $this->setExpectedException('\\Zend\\Loader\\InvalidPrefixException');
  191. $o = new stdClass;
  192. $this->autoloader->unregisterPrefix($o);
  193. }
  194. /**
  195. * @group ZF-6536
  196. */
  197. public function testWarningSuppressionShouldBeDisabledByDefault()
  198. {
  199. $this->assertFalse($this->autoloader->suppressNotFoundWarnings());
  200. }
  201. public function testAutoloaderSuppressNotFoundWarningsFlagShouldBeMutable()
  202. {
  203. $this->autoloader->suppressNotFoundWarnings(true);
  204. $this->assertTrue($this->autoloader->suppressNotFoundWarnings());
  205. }
  206. public function testFallbackAutoloaderFlagShouldBeOffByDefault()
  207. {
  208. $this->assertFalse($this->autoloader->isFallbackAutoloader());
  209. }
  210. public function testFallbackAutoloaderFlagShouldBeMutable()
  211. {
  212. $this->autoloader->setFallbackAutoloader(true);
  213. $this->assertTrue($this->autoloader->isFallbackAutoloader());
  214. }
  215. public function testUnshiftAutoloaderShouldAddToTopOfAutoloaderStack()
  216. {
  217. $this->autoloader->unshiftAutoloader('require');
  218. $autoloaders = $this->autoloader->getAutoloaders();
  219. $test = array_shift($autoloaders);
  220. $this->assertEquals('require', $test);
  221. }
  222. public function testUnshiftAutoloaderWithoutNamespaceShouldRegisterAsEmptyNamespace()
  223. {
  224. $this->autoloader->unshiftAutoloader('require');
  225. $autoloaders = $this->autoloader->getNamespaceAutoloaders('');
  226. $test = array_shift($autoloaders);
  227. $this->assertEquals('require', $test);
  228. }
  229. public function testUnshiftAutoloaderShouldAllowSpecifyingSingleNamespace()
  230. {
  231. $this->autoloader->unshiftAutoloader('require', 'Foo');
  232. $autoloaders = $this->autoloader->getNamespaceAutoloaders('Foo');
  233. $test = array_shift($autoloaders);
  234. $this->assertEquals('require', $test);
  235. }
  236. public function testUnshiftAutoloaderShouldAllowSpecifyingMultipleNamespaces()
  237. {
  238. $this->autoloader->unshiftAutoloader('require', array('Foo', 'Bar'));
  239. $autoloaders = $this->autoloader->getNamespaceAutoloaders('Foo');
  240. $test = array_shift($autoloaders);
  241. $this->assertEquals('require', $test);
  242. $autoloaders = $this->autoloader->getNamespaceAutoloaders('Bar');
  243. $test = array_shift($autoloaders);
  244. $this->assertEquals('require', $test);
  245. }
  246. public function testPushAutoloaderShouldAddToEndOfAutoloaderStack()
  247. {
  248. $this->autoloader->pushAutoloader('require');
  249. $autoloaders = $this->autoloader->getAutoloaders();
  250. $test = array_pop($autoloaders);
  251. $this->assertEquals('require', $test);
  252. }
  253. public function testPushAutoloaderWithoutNamespaceShouldRegisterAsEmptyNamespace()
  254. {
  255. $this->autoloader->pushAutoloader('require');
  256. $autoloaders = $this->autoloader->getNamespaceAutoloaders('');
  257. $test = array_pop($autoloaders);
  258. $this->assertEquals('require', $test);
  259. }
  260. public function testPushAutoloaderShouldAllowSpecifyingSingleNamespace()
  261. {
  262. $this->autoloader->pushAutoloader('require', 'Foo');
  263. $autoloaders = $this->autoloader->getNamespaceAutoloaders('Foo');
  264. $test = array_pop($autoloaders);
  265. $this->assertEquals('require', $test);
  266. }
  267. public function testPushAutoloaderShouldAllowSpecifyingMultipleNamespaces()
  268. {
  269. $this->autoloader->pushAutoloader('require', array('Foo', 'Bar'));
  270. $autoloaders = $this->autoloader->getNamespaceAutoloaders('Foo');
  271. $test = array_pop($autoloaders);
  272. $this->assertEquals('require', $test);
  273. $autoloaders = $this->autoloader->getNamespaceAutoloaders('Bar');
  274. $test = array_pop($autoloaders);
  275. $this->assertEquals('require', $test);
  276. }
  277. public function testAutoloaderShouldAllowRemovingConcreteAutoloadersFromStackByCallback()
  278. {
  279. $this->autoloader->pushAutoloader('require');
  280. $this->autoloader->removeAutoloader('require');
  281. $autoloaders = $this->autoloader->getAutoloaders();
  282. $this->assertNotContains('require', $autoloaders);
  283. }
  284. public function testRemovingAutoloaderShouldAlsoRemoveAutoloaderFromNamespacedAutoloaders()
  285. {
  286. $this->autoloader->pushAutoloader('require', array('Foo', 'Bar'))
  287. ->pushAutoloader('include');
  288. $this->autoloader->removeAutoloader('require');
  289. $test = $this->autoloader->getNamespaceAutoloaders('Foo');
  290. $this->assertTrue(empty($test));
  291. $test = $this->autoloader->getNamespaceAutoloaders('Bar');
  292. $this->assertTrue(empty($test));
  293. }
  294. public function testAutoloaderShouldAllowRemovingCallbackFromSpecifiedNamespaces()
  295. {
  296. $this->autoloader->pushAutoloader('require', array('Foo', 'Bar'))
  297. ->pushAutoloader('include');
  298. $this->autoloader->removeAutoloader('require', 'Foo');
  299. $test = $this->autoloader->getNamespaceAutoloaders('Foo');
  300. $this->assertTrue(empty($test));
  301. $test = $this->autoloader->getNamespaceAutoloaders('Bar');
  302. $this->assertFalse(empty($test));
  303. }
  304. public function testAutoloadShouldReturnFalseWhenNamespaceIsNotRegistered()
  305. {
  306. $this->assertFalse(ZendAutoloader::autoload('Foo_Bar'));
  307. }
  308. public function testAutoloadShouldReturnFalseWhenNamespaceIsNotRegisteredButClassfileExists()
  309. {
  310. $this->addTestIncludePath();
  311. $this->assertFalse(ZendAutoloader::autoload('ZendLoaderAutoloader_Foo'));
  312. }
  313. public function testAutoloadShouldLoadClassWhenNamespaceIsRegisteredAndClassfileExists()
  314. {
  315. $this->addTestIncludePath();
  316. $this->autoloader->registerPrefix('ZendLoaderAutoloader');
  317. $result = ZendAutoloader::autoload('ZendLoaderAutoloader_Foo');
  318. $this->assertFalse($result === false);
  319. $this->assertTrue(class_exists('ZendLoaderAutoloader_Foo', false));
  320. }
  321. public function testAutoloadShouldNotSuppressFileNotFoundWarningsWhenFlagIsDisabled()
  322. {
  323. $this->addTestIncludePath();
  324. $this->autoloader->suppressNotFoundWarnings(false);
  325. $this->autoloader->registerPrefix('ZendLoaderAutoloader');
  326. set_error_handler(array($this, 'handleErrors'));
  327. $this->assertFalse(ZendAutoloader::autoload('ZendLoaderAutoloader_Bar'));
  328. restore_error_handler();
  329. $this->assertNotNull($this->error);
  330. }
  331. public function testAutoloadShouldReturnTrueIfFunctionBasedAutoloaderMatchesAndReturnsNonFalseValue()
  332. {
  333. $this->autoloader->pushAutoloader('\\ZendTest\\Loader\\testAutoload');
  334. $this->assertTrue(ZendAutoloader::autoload('ZendLoaderAutoloader_Foo_Bar'));
  335. }
  336. public function testAutoloadShouldReturnTrueIfMethodBasedAutoloaderMatchesAndReturnsNonFalseValue()
  337. {
  338. $this->autoloader->pushAutoloader(array($this, 'autoload'));
  339. $this->assertTrue(ZendAutoloader::autoload('ZendLoaderAutoloader_Foo_Bar'));
  340. }
  341. public function testAutoloadShouldReturnTrueIfAutoloaderImplementationReturnsNonFalseValue()
  342. {
  343. $this->autoloader->pushAutoloader(new TestAutoloader());
  344. $this->assertTrue(ZendAutoloader::autoload('ZendLoaderAutoloader_Foo_Bar'));
  345. }
  346. public function testUsingAlternateDefaultLoaderShouldOverrideUsageOfZendLoader()
  347. {
  348. $this->autoloader->setDefaultAutoloader(array($this, 'autoload'));
  349. $class = $this->autoloader->autoload('Zend_ThisClass_WilNever_Exist');
  350. $this->assertEquals('Zend_ThisClass_WilNever_Exist', $class);
  351. $this->assertFalse(class_exists($class, false));
  352. }
  353. /**
  354. * @group ZF-10024
  355. */
  356. public function testClosuresRegisteredWithAutoloaderShouldBeUtilized()
  357. {
  358. if (version_compare(PHP_VERSION, '5.3.0', '<')) {
  359. $this->markTestSkipped(__METHOD__ . ' requires PHP version 5.3.0 or greater');
  360. }
  361. $this->autoloader->pushAutoloader(function($class) {
  362. require_once __DIR__ . '/_files/AutoloaderClosure.php';
  363. });
  364. $test = new AutoloaderTest_AutoloaderClosure();
  365. $this->assertTrue($test instanceof AutoloaderTest_AutoloaderClosure);
  366. }
  367. public function addTestIncludePath()
  368. {
  369. set_include_path(__DIR__ . '/_files/' . PATH_SEPARATOR . $this->includePath);
  370. }
  371. public function handleErrors($errno, $errstr)
  372. {
  373. $this->error = $errstr;
  374. }
  375. public function autoload($class)
  376. {
  377. return $class;
  378. }
  379. }
  380. function testAutoload($class)
  381. {
  382. return $class;
  383. }
  384. class TestAutoloader implements \Zend\Loader\Autoloadable
  385. {
  386. public function autoload($class)
  387. {
  388. return $class;
  389. }
  390. }