diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 38e44ca2a..59addd0b4 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -115,12 +115,14 @@ EOF; $namespacesFile .= ");\n"; if (isset($autoloads['classmap'])) { - $it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['classmap'])); - ClassMapGenerator::dump(iterator_to_array($it), $targetDir.'/autoload_classmap.php'); + // flatten array + $autoloads['classmap'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['classmap'])); } else { - file_put_contents($targetDir.'/autoload_classmap.php', 'vendorDir.'/.composer', 0777, true); $this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer'); $this->assertAutoloadFiles('vendors', $this->vendorDir.'/.composer'); + $this->assertTrue(file_exists($this->vendorDir.'/.composer/autoload_classmap.php'), "ClassMap file needs to be generated, even if empty."); + } + + public function testVendorsClassMapAutoloading() + { + $package = new MemoryPackage('a', '1.0', '1.0'); + + $packages = array(); + $packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0'); + $packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0'); + $a->setAutoload(array('classmap' => array('src/'))); + $b->setAutoload(array('classmap' => array('src/', 'lib/'))); + + $this->repository->expects($this->once()) + ->method('getPackages') + ->will($this->returnValue($packages)); + + @mkdir($this->vendorDir.'/.composer', 0777, true); + mkdir($this->vendorDir.'/a/a/src', 0777, true); + mkdir($this->vendorDir.'/b/b/src', 0777, true); + mkdir($this->vendorDir.'/b/b/lib', 0777, true); + file_put_contents($this->vendorDir.'/a/a/src/a.php', 'vendorDir.'/b/b/src/b.php', 'vendorDir.'/b/b/lib/c.php', 'generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer'); + $this->assertTrue(file_exists($this->vendorDir.'/.composer/autoload_classmap.php'), "ClassMap file needs to be generated, even if empty."); + $this->assertEquals(array( + 'ClassMapFoo' => $this->vendorDir.'/a/a/src/a.php', + 'ClassMapBar' => $this->vendorDir.'/b/b/src/b.php', + 'ClassMapBaz' => $this->vendorDir.'/b/b/lib/c.php', + ), + include ($this->vendorDir.'/.composer/autoload_classmap.php') + ); } public function testOverrideVendorsAutoloading() diff --git a/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php new file mode 100644 index 000000000..d40321768 --- /dev/null +++ b/tests/Composer/Test/Autoload/ClassMapGeneratorTest.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Autoload; + +use Composer\Autoload\ClassMapGenerator; + +class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getTestCreateMapTests + */ + public function testCreateMap($directory, $expected) + { + $this->assertEqualsNormalized($expected, ClassMapGenerator::createMap($directory)); + } + + public function getTestCreateMapTests() + { + return array( + array(__DIR__.'/Fixtures/Namespaced', array( + 'Namespaced\\Bar' => realpath(__DIR__).'/Fixtures/Namespaced/Bar.php', + 'Namespaced\\Foo' => realpath(__DIR__).'/Fixtures/Namespaced/Foo.php', + 'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php', + ) + ), + array(__DIR__.'/Fixtures/beta/NamespaceCollision', array( + 'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php', + 'NamespaceCollision\\A\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Foo.php', + )), + array(__DIR__.'/Fixtures/Pearlike', array( + 'Pearlike_Foo' => realpath(__DIR__).'/Fixtures/Pearlike/Foo.php', + 'Pearlike_Bar' => realpath(__DIR__).'/Fixtures/Pearlike/Bar.php', + 'Pearlike_Baz' => realpath(__DIR__).'/Fixtures/Pearlike/Baz.php', + )), + array(__DIR__.'/Fixtures/classmap', array( + 'Foo\\Bar\\A' => realpath(__DIR__).'/Fixtures/classmap/sameNsMultipleClasses.php', + 'Foo\\Bar\\B' => realpath(__DIR__).'/Fixtures/classmap/sameNsMultipleClasses.php', + 'Alpha\\A' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'Alpha\\B' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'Beta\\A' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'Beta\\B' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', + 'ClassMap\\SomeInterface' => realpath(__DIR__).'/Fixtures/classmap/SomeInterface.php', + 'ClassMap\\SomeParent' => realpath(__DIR__).'/Fixtures/classmap/SomeParent.php', + 'ClassMap\\SomeClass' => realpath(__DIR__).'/Fixtures/classmap/SomeClass.php', + )), + ); + } + + public function testCreateMapFinderSupport() + { + if (!class_exists('Symfony\\Component\\Finder\\Finder')) { + $this->markTestSkipped('Finder component is not available'); + } + + $finder = new \Symfony\Component\Finder\Finder(); + $finder->files()->in(__DIR__ . '/Fixtures/beta/NamespaceCollision'); + + $this->assertEqualsNormalized(array( + 'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php', + 'NamespaceCollision\\A\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Foo.php', + ), ClassMapGenerator::createMap($finder)); + } + + protected function assertEqualsNormalized($expected, $actual, $message = null) + { + foreach ($expected as $ns => $path) { + $expected[$ns] = strtr($path, '\\', '/'); + } + foreach ($actual as $ns => $path) { + $actual[$ns] = strtr($path, '\\', '/'); + } + $this->assertEquals($expected, $actual, $message); + } +} diff --git a/tests/Composer/Test/Autoload/Fixtures/Namespaced/Bar.php b/tests/Composer/Test/Autoload/Fixtures/Namespaced/Bar.php new file mode 100644 index 000000000..f9c519a66 --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/Namespaced/Bar.php @@ -0,0 +1,8 @@ +