Skip to content

Commit

Permalink
add config loader to read phpunit file and get the tests directory or…
Browse files Browse the repository at this point in the history
… fallback
  • Loading branch information
danilopolani committed Mar 30, 2022
1 parent db5c11d commit 80c411b
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 1 deletion.
5 changes: 4 additions & 1 deletion bin/pest
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<?php declare(strict_types=1);

use Pest\Actions\ValidatesEnvironment;
use Pest\ConfigLoader;
use Pest\Support\Container;
use Pest\Kernel;
use Pest\TestSuite;
Expand All @@ -28,7 +29,9 @@ use Symfony\Component\Console\Output\OutputInterface;
$rootPath = dirname($autoloadPath, 2);
$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';
$output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, $isDecorated);
Expand Down
110 changes: 110 additions & 0 deletions src/ConfigLoader.php
Original file line number Diff line number Diff line change
@@ -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;
}
}
18 changes: 18 additions & 0 deletions src/Support/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,22 @@ public static function evaluable(string $code): string

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);
}
}

0 comments on commit 80c411b

Please sign in to comment.