211 lines
6.2 KiB
PHP
211 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace Drupal\xautoload\Tests;
|
|
|
|
use Drupal\xautoload\ClassFinder\ClassFinder;
|
|
use Drupal\xautoload\DirectoryBehavior\Psr0DirectoryBehavior;
|
|
use Drupal\xautoload\Tests\Filesystem\StreamWrapper;
|
|
use Drupal\xautoload\Tests\Filesystem\VirtualFilesystem;
|
|
|
|
class ClassLoaderTest extends \PHPUnit_Framework_TestCase {
|
|
|
|
/**
|
|
* @var VirtualFilesystem
|
|
*/
|
|
protected $filesystem;
|
|
|
|
function setUp() {
|
|
parent::setUp();
|
|
$this->filesystem = StreamWrapper::register('test');
|
|
}
|
|
|
|
function tearDown() {
|
|
stream_wrapper_unregister('test');
|
|
parent::tearDown();
|
|
}
|
|
|
|
// Test methods
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Test PSR-4-like namespaces.
|
|
*/
|
|
function testPsr4() {
|
|
|
|
// Prepare the class finder.
|
|
$finder = new ClassFinder();
|
|
|
|
$finder->addPsr4('Drupal\ex_ample\\', 'test://base/lib/');
|
|
|
|
$this->assertCandidateOrder(
|
|
$finder,
|
|
'Drupal\ex_ample\Psr4_%\Foo_Bar',
|
|
array('test://base/lib/Psr4_%/Foo_Bar.php'));
|
|
}
|
|
|
|
/**
|
|
* Test PSR-0-like namespaces.
|
|
*/
|
|
function testNamespaces() {
|
|
|
|
// Prepare the class finder.
|
|
$finder = new ClassFinder();
|
|
$psr0 = new Psr0DirectoryBehavior();
|
|
|
|
$finder->registerNamespaceDeep('Drupal\\ex_ample', 'test://base/lib', $psr0);
|
|
$finder->registerNamespaceRoot('Drupal\\ex_ample', 'test://base/vendor', $psr0);
|
|
|
|
$this->assertCandidateOrder(
|
|
$finder,
|
|
'Drupal\ex_ample\Sub_%\Foo_Bar',
|
|
array(
|
|
'test://base/lib/Sub_%/Foo/Bar.php',
|
|
'test://base/vendor/Drupal/ex_ample/Sub_%/Foo/Bar.php',
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Test PEAR-like prefixes.
|
|
*/
|
|
function testPrefixes() {
|
|
|
|
// Prepare the class finder.
|
|
$finder = new ClassFinder();
|
|
|
|
$finder->registerPrefixDeep('ex_ample', 'test://base/lib');
|
|
$finder->registerPrefixRoot('ex_ample', 'test://base/vendor');
|
|
|
|
$this->assertCandidateOrder(
|
|
$finder,
|
|
'ex_ample_Sub%_Foo',
|
|
array(
|
|
'test://base/lib/Sub%/Foo.php',
|
|
'test://base/vendor/ex/ample/Sub%/Foo.php',
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Tests PEAR-like class names beginning with underscore, or with a double
|
|
* underscore in between.
|
|
*/
|
|
function testSpecialUnderscores() {
|
|
|
|
// Prepare the class finder.
|
|
$finder = new ClassFinder();
|
|
|
|
$finder->registerPrefixDeep('_ex_ample', 'test://lib');
|
|
$finder->registerPrefixRoot('_ex_ample', 'test://vendor');
|
|
|
|
// Verify that underscores are not a problem..
|
|
$this->assertCandidateOrder(
|
|
$finder,
|
|
'_ex_ample_Abc%_Def', array(
|
|
'test://lib/Abc%/Def.php',
|
|
'test://vendor/_ex/ample/Abc%/Def.php',
|
|
));
|
|
$this->assertCandidateOrder($finder, '_abc_Foo%', array());
|
|
$this->assertCandidateOrder($finder, 'abc__Foo%', array());
|
|
}
|
|
|
|
// Assertion helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @param \Drupal\xautoload\ClassLoader\ClassLoaderInterface $loader
|
|
* @param string $class
|
|
* @param string $file
|
|
*/
|
|
protected function assertLoadClass($loader, $class, $file) {
|
|
|
|
// Register the class file in the virtual filesystem.
|
|
$this->filesystem->addClass($file, $class);
|
|
|
|
// Check that the class is not already defined.
|
|
$this->assertFalse(class_exists($class, FALSE));
|
|
|
|
// Trigger the class loader.
|
|
$loader->loadClass($class);
|
|
|
|
// Check that the class is defined after the class loader has done its job.
|
|
$this->assertTrue(class_exists($class, FALSE));
|
|
}
|
|
|
|
/**
|
|
* @param \Drupal\xautoload\ClassLoader\ClassLoaderInterface $loader
|
|
* @param string $classTemplate
|
|
* @param string[] $expectedCandidateTemplates
|
|
*/
|
|
protected function assertCandidateOrder($loader, $classTemplate, array $expectedCandidateTemplates) {
|
|
for ($i = 0; $i < count($expectedCandidateTemplates); ++$i) {
|
|
$class = $this->replaceWildcard($classTemplate, "n$i");
|
|
// If str_replace() is called with an array as 3rd parameter, it will do
|
|
// the replacement on all array elements.
|
|
$expectedCandidates = $this->replaceWildcardMultiple(array_slice($expectedCandidateTemplates, 0, $i + 1), "n$i");
|
|
$this->assertFileInclusions($loader, $class, $expectedCandidates);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assert that inclusions are done in the expected order.
|
|
*
|
|
* @param \Drupal\xautoload\ClassLoader\ClassLoaderInterface $loader
|
|
* @param string $class
|
|
* @param string[] $expectedCandidates
|
|
*/
|
|
protected function assertFileInclusions($loader, $class, array $expectedCandidates) {
|
|
|
|
// Register the class file in the virtual filesystem.
|
|
$this->filesystem->addClass(end($expectedCandidates), $class);
|
|
|
|
$this->filesystem->resetReportedOperations();
|
|
|
|
// Check that the class is not already defined.
|
|
$this->assertFalse(class_exists($class, FALSE), "Class '$class' is not defined before loadClass().");
|
|
|
|
// Trigger the class loader.
|
|
$loader->loadClass($class);
|
|
|
|
$expectedOperations = array();
|
|
foreach ($expectedCandidates as $file) {
|
|
$expectedOperations[] = $file . ' - stat';
|
|
}
|
|
$expectedOperations[] = end($expectedCandidates) . ' - include';
|
|
$this->assertSame($expectedOperations, $this->filesystem->getReportedOperations());
|
|
|
|
// Check that the class is defined after the class loader has done its job.
|
|
$this->assertTrue(class_exists($class, FALSE), "Class is defined after loadClass().");
|
|
}
|
|
|
|
/**
|
|
* @param string[] $strings
|
|
* @param string $replacement
|
|
*
|
|
* @return string[]
|
|
*/
|
|
protected function replaceWildcardMultiple(array $strings, $replacement) {
|
|
foreach ($strings as &$str) {
|
|
$str = $this->replaceWildcard($str, $replacement);
|
|
}
|
|
return $strings;
|
|
}
|
|
|
|
/**
|
|
* @param string $str
|
|
* @param string $replacement
|
|
*
|
|
* @return string
|
|
*
|
|
* @throws \Exception
|
|
*/
|
|
protected function replaceWildcard($str, $replacement) {
|
|
$fragments = explode('%', $str);
|
|
if (count($fragments) < 2) {
|
|
throw new \Exception("String '$str' does not contain a '%' wildcard.");
|
|
}
|
|
if (count($fragments) > 2) {
|
|
throw new \Exception("String '$str' has more than one '%' wildcard.");
|
|
}
|
|
return str_replace('%', $replacement, $str);
|
|
}
|
|
}
|