Skip to content

Commit

Permalink
OPTIONAL: Add default implementation for getModuleInfoFilePath(), so …
Browse files Browse the repository at this point in the history
…that subclasses don't need to implement it.
  • Loading branch information
donquixote committed May 23, 2014
1 parent df501b4 commit f005a68
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 8 deletions.
7 changes: 0 additions & 7 deletions core/modules/path/tests/src/Field/PathFieldDefinitionTest.php
Expand Up @@ -38,13 +38,6 @@ protected function getPluginId() {
return 'path';
}

/**
* {@inheritdoc}
*/
protected function getModuleInfoFilePath() {
return dirname(dirname(dirname(__DIR__))) . '/path.info.yml';
}

/**
* Tests FieldDefinition::getColumns().
*
Expand Down
91 changes: 90 additions & 1 deletion core/tests/Drupal/Tests/Core/Field/FieldDefinitionTestBase.php
Expand Up @@ -85,10 +85,99 @@ abstract protected function getPluginId();
* This will be used to determine both the module name and the module
* directory.
*
* This defaults to the module that contains the test, but can be overridden.
*
* @return string
* The path to the MODULE.info.yml file, e.g.
* DRUPAL_ROOT . "/core/modules/path/path.info.yml".
*
* @throws \Exception
*/
protected function getModuleInfoFilePath() {

$class = get_class($this);
$module_info_file = $this->classExtractModuleInfoFilePath($class);
if ($module_info_file === FALSE) {
throw new \Exception("No module info file found for class '$class'.");
}
return $module_info_file;
}

/**
* Determines if a given class is part of a Drupal module, and determines the
* path to the *.info.yml file, if possible.
*
* @todo Put this in a globally accessible place.
*
* @param string $class
* The fully-qualified class name, e.g.
* "Drupal\\path\\Tests\\PathFieldDefinitionTest".
*
* @return string|false
* The path to the module info file, or FALSE if it could not be determined.
*/
private function classExtractModuleInfoFilePath($class) {

if (!preg_match("/Drupal\\\\(.+)\\\\Tests\\\\(.+)$/", $class, $m)) {
return FALSE;
}

list(, $module_name, $relative_class_name) = $m;

$relative_path = str_replace('\\', '/', $relative_class_name) . '.php';

$suffixes = array(
// PSR-4 location for PHPUnit tests.
'/tests/src/' . $relative_path,
// PSR-0 location for PHPUnit tests.
// @todo Remove when PSR-0 support has ended.
"/tests/Drupal/$module_name/Tests/" . $relative_path,
);

$class_file = (new \ReflectionClass($class))->getFileName();
if ($class_file === FALSE) {
return FALSE;
}

// Normalize the directory separator to '/'.
$class_file = str_replace(DIRECTORY_SEPARATOR, '/', $class_file);

foreach ($suffixes as $suffix) {
$dir = $this->stringRemoveSuffix($class_file, $suffix);
if (FALSE !== $dir) {
$module_info_file = $dir . '/' . $module_name . '.info.yml';
if (is_file($module_info_file)) {
return $module_info_file;
}
}
}

return FALSE;
}

/**
* Removes a suffix from a string, if possible.
*
* @todo Put this in a globally accessible place.
*
* @param string $string
* A string to test.
* @param string $suffix
* A string that could be a suffix of $string.
*
* @return bool|string
* The $prefix, so that $prefix . $suffix === $string, or
* FALSE, if $string does not end with $suffix.
*/
abstract protected function getModuleInfoFilePath();
private function stringRemoveSuffix($string, $suffix) {
if (FALSE !== $pos = strrpos($string, $suffix)) {
if ($pos + strlen($suffix) === strlen($string)) {
// $string ends with $suffix, so return the beginning of $string.
return substr($string, 0, $pos);
}
}
// $string does not end with $suffix.
return FALSE;
}

}

0 comments on commit f005a68

Please sign in to comment.