add config loader to read phpunit file and get the tests directory or fallback

This commit is contained in:
danilopolani
2022-03-30 15:39:50 +02:00
parent db5c11d96e
commit 80c411be44
3 changed files with 132 additions and 1 deletions

View File

@ -2,6 +2,7 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
use Pest\Actions\ValidatesEnvironment; use Pest\Actions\ValidatesEnvironment;
use Pest\ConfigLoader;
use Pest\Support\Container; use Pest\Support\Container;
use Pest\Kernel; use Pest\Kernel;
use Pest\TestSuite; use Pest\TestSuite;
@ -28,7 +29,9 @@ use Symfony\Component\Console\Output\OutputInterface;
$rootPath = dirname($autoloadPath, 2); $rootPath = dirname($autoloadPath, 2);
$argv = new ArgvInput(); $argv = new ArgvInput();
$testSuite = TestSuite::getInstance($rootPath, $argv->getParameterOption('--test-directory', 'tests')); $phpunitConfig = new ConfigLoader($rootPath);
$testSuite = TestSuite::getInstance($rootPath, $argv->getParameterOption('--test-directory', $phpunitConfig->getTestsDirectory()));
$isDecorated = $argv->getParameterOption('--colors', 'always') !== 'never'; $isDecorated = $argv->getParameterOption('--colors', 'always') !== 'never';
$output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, $isDecorated); $output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, $isDecorated);

110
src/ConfigLoader.php Normal file
View File

@ -0,0 +1,110 @@
<?php
declare(strict_types=1);
namespace Pest;
use Pest\Support\Str;
use SimpleXMLElement;
use Throwable;
/**
* @internal
*/
final class ConfigLoader
{
private ?SimpleXMLElement $config = null;
/**
* Default path if config loading went wrong.
*
* @var string
*/
private const DEFAULT_TESTS_PATH = 'tests';
/**
* Creates a new instance of the config loader.
*/
public function __construct(private string $rootPath)
{
$this->loadConfiguration();
}
/**
* Get the tests directory or fallback to default path.
*/
public function getTestsDirectory(): string
{
if (is_null($this->config)) {
return self::DEFAULT_TESTS_PATH;
}
$suiteDirectory = $this->config->xpath('/phpunit/testsuites/testsuite/directory');
// @phpstan-ignore-next-line
if (!$suiteDirectory || count($suiteDirectory) === 0) {
return self::DEFAULT_TESTS_PATH;
}
$directory = (string) ($suiteDirectory[0] ?? '');
if ($directory === '') {
return self::DEFAULT_TESTS_PATH;
}
// Return the whole directory if only a separator found (e.g. `./tests`)
if (substr_count($directory, DIRECTORY_SEPARATOR) === 1) {
return is_dir($directory) ? $directory : self::DEFAULT_TESTS_PATH;
}
$basePath = Str::beforeLast($directory, DIRECTORY_SEPARATOR);
return is_dir($basePath) ? $basePath : self::DEFAULT_TESTS_PATH;
}
/**
* Load the configuration file.
*/
private function loadConfiguration(): void
{
$configPath = $this->getConfigurationFilePath();
if ($configPath === false) {
return;
}
$oldReportingLevel = error_reporting(0);
$content = file_get_contents($configPath);
if ($content !== false) {
try {
$this->config = new SimpleXMLElement($content);
} catch (Throwable) { // @phpstan-ignore-line
// @ignoreException
}
}
// Restore the correct error reporting
error_reporting($oldReportingLevel);
}
/**
* Get the configuration file path.
*/
private function getConfigurationFilePath(): string|false
{
$candidates = [
$this->rootPath . '/phpunit.xml',
$this->rootPath . '/phpunit.dist.xml',
$this->rootPath . '/phpunit.xml.dist',
];
foreach ($candidates as $candidate) {
if (is_file($candidate)) {
return realpath($candidate);
}
}
return false;
}
}

View File

@ -58,4 +58,22 @@ final class Str
return (string) preg_replace('/[^A-Z_a-z0-9\\\\]/', '', $code); return (string) preg_replace('/[^A-Z_a-z0-9\\\\]/', '', $code);
} }
/**
* Get the portion of a string before the last occurrence of a given value.
*/
public static function beforeLast(string $subject, string $search): string
{
if ($search === '') {
return $subject;
}
$pos = mb_strrpos($subject, $search);
if ($pos === false) {
return $subject;
}
return substr($subject, 0, $pos);
}
} }