From dbb5ca459dc0a191c488aab234c7bd74a3723cd5 Mon Sep 17 00:00:00 2001 From: Dustin Whittle Date: Tue, 19 Apr 2011 00:29:29 -0700 Subject: [PATCH 1/4] [Classloader] Fixed APC class loader + added unit tests --- .../ClassLoader/ApcUniversalClassLoader.php | 2 - .../ApcUniversalClassLoaderTest.php | 194 ++++++++++++++++++ 2 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php diff --git a/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php b/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php index dceb8a2294..ba7bbd4612 100644 --- a/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php +++ b/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php @@ -11,8 +11,6 @@ namespace Symfony\Component\ClassLoader; -require_once __DIR__.'/UniversalClassLoader.php'; - /** * Class loader utilizing APC to remember where files are. * diff --git a/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php b/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php new file mode 100644 index 0000000000..59ab7417ad --- /dev/null +++ b/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php @@ -0,0 +1,194 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\ClassLoader; + +use Symfony\Component\ClassLoader\ApcUniversalClassLoader; + +class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase +{ + + protected function skipIfAPCExtensionIsNotLoadedOrEnabled() + { + if (!extension_loaded('apc')) { + $this->markTestSkipped('The apc extension is available.'); + } + + if (!(ini_get('apc.enabled') && ini_get('apc.enable_cli'))) { + $this->markTestSkipped('The apc extension is available, but not enabled.'); + } + } + + public function testConstructor() + { + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + + $loader = new ApcUniversalClassLoader('test.prefix.'); + $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + + $this->assertEquals($loader->findFile('\Namespaced\Bar'), apc_fetch('test.prefix.\Namespaced\Bar'), '__construct() takes a prefix as its first argument'); + } + + /** + * @dataProvider getLoadClassTests + */ + public function testLoadClass($className, $testClassName, $message) + { + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + + $loader = new ApcUniversalClassLoader('test.prefix.'); + $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassTests() + { + return array( + array('\\Namespaced\\Foo', 'Namespaced\\Foo', '->loadClass() loads Namespaced\Foo class'), + array('\\Pearlike_Foo', 'Pearlike_Foo', '->loadClass() loads Pearlike_Foo class'), + array('\\Namespaced\\Bar', '\\Namespaced\\Bar', '->loadClass() loads Namespaced\Bar class with a leading slash'), + array('\\Pearlike_Bar', '\\Pearlike_Bar', '->loadClass() loads Pearlike_Bar class with a leading slash'), + ); + } + + /** + * @dataProvider getLoadClassFromFallbackTests + */ + public function testLoadClassFromFallback($className, $testClassName, $message) + { + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + + $loader = new ApcUniversalClassLoader('test.prefix.'); + $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerNamespaceFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'); + $loader->registerPrefixFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassFromFallbackTests() + { + return array( + array('\\Namespaced\\Baz', 'Namespaced\\Baz', '->loadClass() loads Namespaced\Baz class'), + array('\\Pearlike_Baz', 'Pearlike_Baz', '->loadClass() loads Pearlike_Baz class'), + array('\\Namespaced\\FooBar', 'Namespaced\\FooBar', '->loadClass() loads Namespaced\Baz class from fallback dir'), + array('\\Pearlike_FooBar', 'Pearlike_FooBar', '->loadClass() loads Pearlike_Baz class from fallback dir'), + ); + } + + /** + * @dataProvider getLoadClassNamespaceCollisionTests + */ + public function testLoadClassNamespaceCollision($namespaces, $className, $message) + { + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + + $loader = new ApcUniversalClassLoader('test.prefix.'); + $loader->registerNamespaces($namespaces); + + $loader->loadClass($className); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassNamespaceCollisionTests() + { + return array( + array( + array( + 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'NamespaceCollision\A\Foo', + '->loadClass() loads NamespaceCollision\A\Foo from alpha.', + ), + array( + array( + 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'NamespaceCollision\A\Bar', + '->loadClass() loads NamespaceCollision\A\Bar from alpha.', + ), + array( + array( + 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'NamespaceCollision\A\B\Foo', + '->loadClass() loads NamespaceCollision\A\B\Foo from beta.', + ), + array( + array( + 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'NamespaceCollision\A\B\Bar', + '->loadClass() loads NamespaceCollision\A\B\Bar from beta.', + ), + ); + } + + /** + * @dataProvider getLoadClassPrefixCollisionTests + */ + public function testLoadClassPrefixCollision($prefixes, $className, $message) + { + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + + $loader = new ApcUniversalClassLoader('test.prefix.'); + $loader->registerPrefixes($prefixes); + + $loader->loadClass($className); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassPrefixCollisionTests() + { + return array( + array( + array( + 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'PrefixCollision_A_Foo', + '->loadClass() loads PrefixCollision_A_Foo from alpha.', + ), + array( + array( + 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'PrefixCollision_A_Bar', + '->loadClass() loads PrefixCollision_A_Bar from alpha.', + ), + array( + array( + 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + ), + 'PrefixCollision_A_B_Foo', + '->loadClass() loads PrefixCollision_A_B_Foo from beta.', + ), + array( + array( + 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', + 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', + ), + 'PrefixCollision_A_B_Bar', + '->loadClass() loads PrefixCollision_A_B_Bar from beta.', + ), + ); + } + +} From 1f3a968ef2b4ba89512a8d7881daf79e0e7b75af Mon Sep 17 00:00:00 2001 From: Dustin Whittle Date: Tue, 19 Apr 2011 00:43:07 -0700 Subject: [PATCH 2/4] [Classloader] Fixed typo + coding standards in ApcUniversalClassLoader test --- .../ClassLoader/ApcUniversalClassLoaderTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php b/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php index 59ab7417ad..9484b8ae6b 100644 --- a/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php +++ b/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php @@ -19,7 +19,7 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase protected function skipIfAPCExtensionIsNotLoadedOrEnabled() { if (!extension_loaded('apc')) { - $this->markTestSkipped('The apc extension is available.'); + $this->markTestSkipped('The apc extension is not available.'); } if (!(ini_get('apc.enabled') && ini_get('apc.enable_cli'))) { @@ -29,7 +29,7 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase public function testConstructor() { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); @@ -42,7 +42,7 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase */ public function testLoadClass($className, $testClassName, $message) { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); @@ -66,7 +66,7 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase */ public function testLoadClassFromFallback($className, $testClassName, $message) { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); @@ -92,7 +92,7 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase */ public function testLoadClassNamespaceCollision($namespaces, $className, $message) { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerNamespaces($namespaces); @@ -144,7 +144,7 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase */ public function testLoadClassPrefixCollision($prefixes, $className, $message) { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); + $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerPrefixes($prefixes); From 29802faef42526b467ee3d618fb706bc2d4646dd Mon Sep 17 00:00:00 2001 From: Dustin Whittle Date: Tue, 19 Apr 2011 01:04:25 -0700 Subject: [PATCH 3/4] [Classloader] Refactored ApcUniversalClassLoader to use setUp() to detect APC --- .../ClassLoader/ApcUniversalClassLoaderTest.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php b/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php index 9484b8ae6b..e74d93fc3c 100644 --- a/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php +++ b/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php @@ -16,7 +16,7 @@ use Symfony\Component\ClassLoader\ApcUniversalClassLoader; class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase { - protected function skipIfAPCExtensionIsNotLoadedOrEnabled() + protected function setUp() { if (!extension_loaded('apc')) { $this->markTestSkipped('The apc extension is not available.'); @@ -29,8 +29,6 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase public function testConstructor() { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); - $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); @@ -42,8 +40,6 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase */ public function testLoadClass($className, $testClassName, $message) { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); - $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); @@ -66,8 +62,6 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase */ public function testLoadClassFromFallback($className, $testClassName, $message) { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); - $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); @@ -92,8 +86,6 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase */ public function testLoadClassNamespaceCollision($namespaces, $className, $message) { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); - $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerNamespaces($namespaces); @@ -144,8 +136,6 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase */ public function testLoadClassPrefixCollision($prefixes, $className, $message) { - $this->skipIfAPCExtensionIsNotLoadedOrEnabled(); - $loader = new ApcUniversalClassLoader('test.prefix.'); $loader->registerPrefixes($prefixes); From e8bb64c17c9ef0a9c6a3d65a5aeb05be2ddf5642 Mon Sep 17 00:00:00 2001 From: Dustin Whittle Date: Sun, 24 Apr 2011 06:59:28 -0700 Subject: [PATCH 4/4] [Classloader] Added phpdoc with example usage + refactored unit tests fixtures --- .../ClassLoader/ApcUniversalClassLoader.php | 51 +++- .../ApcUniversalClassLoaderTest.php | 284 +++++++++--------- .../Fixtures/Apc/Namespaced/Bar.php | 8 + .../Fixtures/Apc/Namespaced/Baz.php | 8 + .../Fixtures/Apc/Namespaced/Foo.php | 8 + .../Fixtures/Apc/Namespaced/FooBar.php | 8 + .../ClassLoader/Fixtures/Apc/Pearlike/Bar.php | 6 + .../ClassLoader/Fixtures/Apc/Pearlike/Baz.php | 6 + .../ClassLoader/Fixtures/Apc/Pearlike/Foo.php | 6 + .../alpha/Apc/ApcPrefixCollision/A/Bar.php | 6 + .../alpha/Apc/ApcPrefixCollision/A/Foo.php | 6 + .../alpha/Apc/NamespaceCollision/A/Bar.php | 8 + .../alpha/Apc/NamespaceCollision/A/Foo.php | 8 + .../beta/Apc/ApcPrefixCollision/A/B/Bar.php | 6 + .../beta/Apc/ApcPrefixCollision/A/B/Foo.php | 6 + .../beta/Apc/NamespaceCollision/A/B/Bar.php | 8 + .../beta/Apc/NamespaceCollision/A/B/Foo.php | 8 + .../Apc/fallback/Apc/Pearlike/FooBar.php | 6 + .../Apc/fallback/Namespaced/FooBar.php | 8 + 19 files changed, 316 insertions(+), 139 deletions(-) create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Namespaced/Bar.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Namespaced/Baz.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Namespaced/Foo.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Namespaced/FooBar.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Pearlike/Bar.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Pearlike/Baz.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Pearlike/Foo.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/alpha/Apc/ApcPrefixCollision/A/Bar.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/alpha/Apc/ApcPrefixCollision/A/Foo.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/alpha/Apc/NamespaceCollision/A/Bar.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/alpha/Apc/NamespaceCollision/A/Foo.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/beta/Apc/ApcPrefixCollision/A/B/Bar.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/beta/Apc/ApcPrefixCollision/A/B/Foo.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/beta/Apc/NamespaceCollision/A/B/Bar.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/beta/Apc/NamespaceCollision/A/B/Foo.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/fallback/Apc/Pearlike/FooBar.php create mode 100644 tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/fallback/Namespaced/FooBar.php diff --git a/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php b/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php index ba7bbd4612..d46f466b8a 100644 --- a/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php +++ b/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php @@ -12,8 +12,50 @@ namespace Symfony\Component\ClassLoader; /** - * Class loader utilizing APC to remember where files are. + * ApcUniversalClassLoader implements a "universal" autoloader cached in APC for PHP 5.3. * + * It is able to load classes that use either: + * + * * The technical interoperability standards for PHP 5.3 namespaces and + * class names (http://groups.google.com/group/php-standards/web/psr-0-final-proposal); + * + * * The PEAR naming convention for classes (http://pear.php.net/). + * + * Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be + * looked for in a list of locations to ease the vendoring of a sub-set of + * classes for large projects. + * + * Example usage: + * + * require 'vendor/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php'; + * require 'vendor/symfony/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php'; + * + * use Symfony\Component\ClassLoader\ApcUniversalClassLoader; + * + * $loader = new ApcUniversalClassLoader('apc.prefix.'); + * + * // register classes with namespaces + * $loader->registerNamespaces(array( + * 'Symfony\Component' => __DIR__.'/component', + * 'Symfony' => __DIR__.'/framework', + * 'Sensio' => array(__DIR__.'/src', __DIR__.'/vendor'), + * )); + * + * // register a library using the PEAR naming convention + * $loader->registerPrefixes(array( + * 'Swift_' => __DIR__.'/Swift', + * )); + * + * // activate the autoloader + * $loader->register(); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * @author Fabien Potencier * @author Kris Wallsmith * * @api @@ -34,6 +76,13 @@ class ApcUniversalClassLoader extends UniversalClassLoader $this->prefix = $prefix; } + /** + * Finds a file by class name while caching lookups to APC. + * + * @param string $class A class name to resolve to file + * + * @api + */ public function findFile($class) { if (false === $file = apc_fetch($this->prefix.$class)) { diff --git a/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php b/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php index e74d93fc3c..cd3e375071 100644 --- a/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php +++ b/tests/Symfony/Tests/Component/ClassLoader/ApcUniversalClassLoaderTest.php @@ -25,160 +25,168 @@ class ApcUniversalClassLoaderTest extends \PHPUnit_Framework_TestCase if (!(ini_get('apc.enabled') && ini_get('apc.enable_cli'))) { $this->markTestSkipped('The apc extension is available, but not enabled.'); } + + apc_clear_cache('user'); } + protected function tearDown() + { + apc_clear_cache('user'); + } + public function testConstructor() { $loader = new ApcUniversalClassLoader('test.prefix.'); - $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerNamespace('Apc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); - $this->assertEquals($loader->findFile('\Namespaced\Bar'), apc_fetch('test.prefix.\Namespaced\Bar'), '__construct() takes a prefix as its first argument'); + $this->assertEquals($loader->findFile('\Apc\Namespaced\FooBar'), apc_fetch('test.prefix.\Apc\Namespaced\FooBar'), '__construct() takes a prefix as its first argument'); } - /** - * @dataProvider getLoadClassTests - */ - public function testLoadClass($className, $testClassName, $message) - { - $loader = new ApcUniversalClassLoader('test.prefix.'); - $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); - $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); - $loader->loadClass($testClassName); - $this->assertTrue(class_exists($className), $message); - } + /** + * @dataProvider getLoadClassTests + */ + public function testLoadClass($className, $testClassName, $message) + { + $loader = new ApcUniversalClassLoader('test.prefix.'); + $loader->registerNamespace('Apc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerPrefix('Apc_Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } - public function getLoadClassTests() - { - return array( - array('\\Namespaced\\Foo', 'Namespaced\\Foo', '->loadClass() loads Namespaced\Foo class'), - array('\\Pearlike_Foo', 'Pearlike_Foo', '->loadClass() loads Pearlike_Foo class'), - array('\\Namespaced\\Bar', '\\Namespaced\\Bar', '->loadClass() loads Namespaced\Bar class with a leading slash'), - array('\\Pearlike_Bar', '\\Pearlike_Bar', '->loadClass() loads Pearlike_Bar class with a leading slash'), - ); - } + public function getLoadClassTests() + { + return array( + array('\\Apc\\Namespaced\\Foo', '\\Apc\\Namespaced\\Foo', '->loadClass() loads Apc\Namespaced\Foo class'), + array('Apc_Pearlike_Foo', 'Apc_Pearlike_Foo', '->loadClass() loads Apc_Pearlike_Foo class'), + array('\\Apc\\Namespaced\\Bar', '\\Apc\\Namespaced\\Bar', '->loadClass() loads Apc\Namespaced\Bar class with a leading slash'), + array('Apc_Pearlike_Bar', '\\Apc_Pearlike_Bar', '->loadClass() loads Apc_Pearlike_Bar class with a leading slash'), + ); + } - /** - * @dataProvider getLoadClassFromFallbackTests - */ - public function testLoadClassFromFallback($className, $testClassName, $message) - { - $loader = new ApcUniversalClassLoader('test.prefix.'); - $loader->registerNamespace('Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); - $loader->registerPrefix('Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); - $loader->registerNamespaceFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'); - $loader->registerPrefixFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/fallback'); - $loader->loadClass($testClassName); - $this->assertTrue(class_exists($className), $message); - } + /** + * @dataProvider getLoadClassFromFallbackTests + */ + public function testLoadClassFromFallback($className, $testClassName, $message) + { + $loader = new ApcUniversalClassLoader('test.prefix.fallback'); + $loader->registerNamespace('Apc\Namespaced', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerPrefix('Apc_Pearlike_', __DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $loader->registerNamespaceFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/fallback'); + $loader->registerPrefixFallback(__DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/fallback'); + $loader->loadClass($testClassName); + $this->assertTrue(class_exists($className), $message); + } - public function getLoadClassFromFallbackTests() - { - return array( - array('\\Namespaced\\Baz', 'Namespaced\\Baz', '->loadClass() loads Namespaced\Baz class'), - array('\\Pearlike_Baz', 'Pearlike_Baz', '->loadClass() loads Pearlike_Baz class'), - array('\\Namespaced\\FooBar', 'Namespaced\\FooBar', '->loadClass() loads Namespaced\Baz class from fallback dir'), - array('\\Pearlike_FooBar', 'Pearlike_FooBar', '->loadClass() loads Pearlike_Baz class from fallback dir'), - ); - } + public function getLoadClassFromFallbackTests() + { + return array( + array('\\Apc\\Namespaced\\Baz', '\\Apc\\Namespaced\\Baz', '->loadClass() loads Apc\Namespaced\Baz class'), + array('Apc_Pearlike_Baz', 'Apc_Pearlike_Baz', '->loadClass() loads Apc_Pearlike_Baz class'), + array('\\Apc\\Namespaced\\FooBar', '\\Apc\\Namespaced\\FooBar', '->loadClass() loads Apc\Namespaced\Baz class from fallback dir'), + array('Apc_Pearlike_FooBar', 'Apc_Pearlike_FooBar', '->loadClass() loads Apc_Pearlike_Baz class from fallback dir'), + ); + } - /** - * @dataProvider getLoadClassNamespaceCollisionTests - */ - public function testLoadClassNamespaceCollision($namespaces, $className, $message) - { - $loader = new ApcUniversalClassLoader('test.prefix.'); - $loader->registerNamespaces($namespaces); + /** + * @dataProvider getLoadClassNamespaceCollisionTests + */ + public function testLoadClassNamespaceCollision($namespaces, $className, $message) + { + $loader = new ApcUniversalClassLoader('test.prefix.collision.'); + $loader->registerNamespaces($namespaces); - $loader->loadClass($className); - $this->assertTrue(class_exists($className), $message); - } + $loader->loadClass($className); - public function getLoadClassNamespaceCollisionTests() - { - return array( - array( - array( - 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', - 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', - ), - 'NamespaceCollision\A\Foo', - '->loadClass() loads NamespaceCollision\A\Foo from alpha.', - ), - array( - array( - 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', - 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', - ), - 'NamespaceCollision\A\Bar', - '->loadClass() loads NamespaceCollision\A\Bar from alpha.', - ), - array( - array( - 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', - 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', - ), - 'NamespaceCollision\A\B\Foo', - '->loadClass() loads NamespaceCollision\A\B\Foo from beta.', - ), - array( - array( - 'NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', - 'NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', - ), - 'NamespaceCollision\A\B\Bar', - '->loadClass() loads NamespaceCollision\A\B\Bar from beta.', - ), - ); - } + $this->assertTrue(class_exists($className), $message); + } - /** - * @dataProvider getLoadClassPrefixCollisionTests - */ - public function testLoadClassPrefixCollision($prefixes, $className, $message) - { - $loader = new ApcUniversalClassLoader('test.prefix.'); - $loader->registerPrefixes($prefixes); + public function getLoadClassNamespaceCollisionTests() + { + return array( + array( + array( + 'Apc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha', + 'Apc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta', + ), + '\Apc\NamespaceCollision\A\Foo', + '->loadClass() loads NamespaceCollision\A\Foo from alpha.', + ), + array( + array( + 'Apc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta', + 'Apc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha', + ), + '\Apc\NamespaceCollision\A\Bar', + '->loadClass() loads NamespaceCollision\A\Bar from alpha.', + ), + array( + array( + 'Apc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha', + 'Apc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta', + ), + '\Apc\NamespaceCollision\A\B\Foo', + '->loadClass() loads NamespaceCollision\A\B\Foo from beta.', + ), + array( + array( + 'Apc\\NamespaceCollision\\A\\B' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta', + 'Apc\\NamespaceCollision\\A' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha', + ), + '\Apc\NamespaceCollision\A\B\Bar', + '->loadClass() loads NamespaceCollision\A\B\Bar from beta.', + ), + ); + } - $loader->loadClass($className); - $this->assertTrue(class_exists($className), $message); - } + /** + * @dataProvider getLoadClassPrefixCollisionTests + */ + public function testLoadClassPrefixCollision($prefixes, $className, $message) + { + $loader = new ApcUniversalClassLoader('test.prefix.collision.'); + $loader->registerPrefixes($prefixes); - public function getLoadClassPrefixCollisionTests() - { - return array( - array( - array( - 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', - 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', - ), - 'PrefixCollision_A_Foo', - '->loadClass() loads PrefixCollision_A_Foo from alpha.', - ), - array( - array( - 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', - 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', - ), - 'PrefixCollision_A_Bar', - '->loadClass() loads PrefixCollision_A_Bar from alpha.', - ), - array( - array( - 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', - 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', - ), - 'PrefixCollision_A_B_Foo', - '->loadClass() loads PrefixCollision_A_B_Foo from beta.', - ), - array( - array( - 'PrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/beta', - 'PrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/alpha', - ), - 'PrefixCollision_A_B_Bar', - '->loadClass() loads PrefixCollision_A_B_Bar from beta.', - ), - ); - } + $loader->loadClass($className); + $this->assertTrue(class_exists($className), $message); + } + + public function getLoadClassPrefixCollisionTests() + { + return array( + array( + array( + 'ApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha/Apc', + 'ApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta/Apc', + ), + 'ApcPrefixCollision_A_Foo', + '->loadClass() loads ApcPrefixCollision_A_Foo from alpha.', + ), + array( + array( + 'ApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta/Apc', + 'ApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha/Apc', + ), + 'ApcPrefixCollision_A_Bar', + '->loadClass() loads ApcPrefixCollision_A_Bar from alpha.', + ), + array( + array( + 'ApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha/Apc', + 'ApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta/Apc', + ), + 'ApcPrefixCollision_A_B_Foo', + '->loadClass() loads ApcPrefixCollision_A_B_Foo from beta.', + ), + array( + array( + 'ApcPrefixCollision_A_B_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/beta/Apc', + 'ApcPrefixCollision_A_' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/Apc/alpha/Apc', + ), + 'ApcPrefixCollision_A_B_Bar', + '->loadClass() loads ApcPrefixCollision_A_B_Bar from beta.', + ), + ); + } } diff --git a/tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Namespaced/Bar.php b/tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Namespaced/Bar.php new file mode 100644 index 0000000000..6db570a90c --- /dev/null +++ b/tests/Symfony/Tests/Component/ClassLoader/Fixtures/Apc/Namespaced/Bar.php @@ -0,0 +1,8 @@ +