4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\ClassLoader\Tests;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\ClassLoader\ClassCollectionLoader;
17 require_once __DIR__.'/Fixtures/ClassesWithParents/GInterface.php';
18 require_once __DIR__.'/Fixtures/ClassesWithParents/CInterface.php';
19 require_once __DIR__.'/Fixtures/ClassesWithParents/B.php';
20 require_once __DIR__.'/Fixtures/ClassesWithParents/A.php';
22 class ClassCollectionLoaderTest extends TestCase
27 public function testTraitDependencies()
29 require_once __DIR__.'/Fixtures/deps/traits.php';
31 $r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
32 $m = $r->getMethod('getOrderedClasses');
33 $m->setAccessible(true);
35 $ordered = $m->invoke(null, array('CTFoo'));
38 array('TD', 'TC', 'TB', 'TA', 'TZ', 'CTFoo'),
39 array_map(function ($class) { return $class->getName(); }, $ordered)
42 $ordered = $m->invoke(null, array('CTBar'));
45 array('TD', 'TZ', 'TC', 'TB', 'TA', 'CTBar'),
46 array_map(function ($class) { return $class->getName(); }, $ordered)
51 * @dataProvider getDifferentOrders
53 public function testClassReordering(array $classes)
56 'ClassesWithParents\\GInterface',
57 'ClassesWithParents\\CInterface',
58 'ClassesWithParents\\B',
59 'ClassesWithParents\\A',
62 $r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
63 $m = $r->getMethod('getOrderedClasses');
64 $m->setAccessible(true);
66 $ordered = $m->invoke(null, $classes);
68 $this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
71 public function getDifferentOrders()
75 'ClassesWithParents\\A',
76 'ClassesWithParents\\CInterface',
77 'ClassesWithParents\\GInterface',
78 'ClassesWithParents\\B',
81 'ClassesWithParents\\B',
82 'ClassesWithParents\\A',
83 'ClassesWithParents\\CInterface',
86 'ClassesWithParents\\CInterface',
87 'ClassesWithParents\\B',
88 'ClassesWithParents\\A',
91 'ClassesWithParents\\A',
97 * @dataProvider getDifferentOrdersForTraits
100 public function testClassWithTraitsReordering(array $classes)
102 require_once __DIR__.'/Fixtures/ClassesWithParents/ATrait.php';
103 require_once __DIR__.'/Fixtures/ClassesWithParents/BTrait.php';
104 require_once __DIR__.'/Fixtures/ClassesWithParents/CTrait.php';
105 require_once __DIR__.'/Fixtures/ClassesWithParents/D.php';
106 require_once __DIR__.'/Fixtures/ClassesWithParents/E.php';
109 'ClassesWithParents\\GInterface',
110 'ClassesWithParents\\CInterface',
111 'ClassesWithParents\\ATrait',
112 'ClassesWithParents\\BTrait',
113 'ClassesWithParents\\CTrait',
114 'ClassesWithParents\\B',
115 'ClassesWithParents\\A',
116 'ClassesWithParents\\D',
117 'ClassesWithParents\\E',
120 $r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
121 $m = $r->getMethod('getOrderedClasses');
122 $m->setAccessible(true);
124 $ordered = $m->invoke(null, $classes);
126 $this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
129 public function getDifferentOrdersForTraits()
133 'ClassesWithParents\\E',
134 'ClassesWithParents\\ATrait',
137 'ClassesWithParents\\E',
145 public function testFixClassWithTraitsOrdering()
147 require_once __DIR__.'/Fixtures/ClassesWithParents/CTrait.php';
148 require_once __DIR__.'/Fixtures/ClassesWithParents/F.php';
149 require_once __DIR__.'/Fixtures/ClassesWithParents/G.php';
152 'ClassesWithParents\\F',
153 'ClassesWithParents\\G',
157 'ClassesWithParents\\CTrait',
158 'ClassesWithParents\\F',
159 'ClassesWithParents\\G',
162 $r = new \ReflectionClass('Symfony\Component\ClassLoader\ClassCollectionLoader');
163 $m = $r->getMethod('getOrderedClasses');
164 $m->setAccessible(true);
166 $ordered = $m->invoke(null, $classes);
168 $this->assertEquals($expected, array_map(function ($class) { return $class->getName(); }, $ordered));
172 * @dataProvider getFixNamespaceDeclarationsData
174 public function testFixNamespaceDeclarations($source, $expected)
176 $this->assertEquals('<?php '.$expected, ClassCollectionLoader::fixNamespaceDeclarations('<?php '.$source));
179 public function getFixNamespaceDeclarationsData()
182 array("namespace;\nclass Foo {}\n", "namespace\n{\nclass Foo {}\n}"),
183 array("namespace Foo;\nclass Foo {}\n", "namespace Foo\n{\nclass Foo {}\n}"),
184 array("namespace Bar ;\nclass Foo {}\n", "namespace Bar\n{\nclass Foo {}\n}"),
185 array("namespace Foo\Bar;\nclass Foo {}\n", "namespace Foo\Bar\n{\nclass Foo {}\n}"),
186 array("namespace Foo\Bar\Bar\n{\nclass Foo {}\n}\n", "namespace Foo\Bar\Bar\n{\nclass Foo {}\n}"),
187 array("namespace\n{\nclass Foo {}\n}\n", "namespace\n{\nclass Foo {}\n}"),
192 * @dataProvider getFixNamespaceDeclarationsDataWithoutTokenizer
194 public function testFixNamespaceDeclarationsWithoutTokenizer($source, $expected)
196 ClassCollectionLoader::enableTokenizer(false);
197 $this->assertEquals('<?php '.$expected, ClassCollectionLoader::fixNamespaceDeclarations('<?php '.$source));
198 ClassCollectionLoader::enableTokenizer(true);
201 public function getFixNamespaceDeclarationsDataWithoutTokenizer()
204 array("namespace;\nclass Foo {}\n", "namespace\n{\nclass Foo {}\n}\n"),
205 array("namespace Foo;\nclass Foo {}\n", "namespace Foo\n{\nclass Foo {}\n}\n"),
206 array("namespace Bar ;\nclass Foo {}\n", "namespace Bar\n{\nclass Foo {}\n}\n"),
207 array("namespace Foo\Bar;\nclass Foo {}\n", "namespace Foo\Bar\n{\nclass Foo {}\n}\n"),
208 array("namespace Foo\Bar\Bar\n{\nclass Foo {}\n}\n", "namespace Foo\Bar\Bar\n{\nclass Foo {}\n}\n"),
209 array("\nnamespace\n{\nclass Foo {}\n\$namespace=123;}\n", "\nnamespace\n{\nclass Foo {}\n\$namespace=123;}\n"),
214 * @expectedException \InvalidArgumentException
216 public function testUnableToLoadClassException()
218 if (is_file($file = sys_get_temp_dir().'/foo.php')) {
222 ClassCollectionLoader::load(array('SomeNotExistingClass'), sys_get_temp_dir(), 'foo', false);
225 public function testCommentStripping()
227 if (is_file($file = __DIR__.'/bar.php')) {
230 spl_autoload_register($r = function ($class) {
231 if (0 === strpos($class, 'Namespaced') || 0 === strpos($class, 'Pearlike_')) {
232 @require_once __DIR__.'/Fixtures/'.str_replace(array('\\', '_'), '/', $class).'.php';
236 $strictTypes = defined('HHVM_VERSION') ? '' : "\nnamespace {require __DIR__.'/Fixtures/Namespaced/WithStrictTypes.php';}";
238 ClassCollectionLoader::load(
239 array('Namespaced\\WithComments', 'Pearlike_WithComments', 'Namespaced\\WithDirMagic', 'Namespaced\\WithFileMagic', 'Namespaced\\WithHaltCompiler', $strictTypes ? 'Namespaced\\WithStrictTypes' : 'Namespaced\\WithComments'),
245 spl_autoload_unregister($r);
247 $this->assertEquals(<<<'EOF'
252 public static $loaded = true;
254 $string ='string should not be modified {$string}';
258 Heredoc should not be modified {$string}
266 Nowdoc should not be modified {$string}
274 class Pearlike_WithComments
276 public static $loaded = true;
279 namespace {require __DIR__.'/Fixtures/Namespaced/WithDirMagic.php';}
280 namespace {require __DIR__.'/Fixtures/Namespaced/WithFileMagic.php';}
281 namespace {require __DIR__.'/Fixtures/Namespaced/WithHaltCompiler.php';}
284 str_replace(array("<?php \n", '\\\\'), array('', '/'), file_get_contents($file))