Merge pull request #443 from pestphp/tweaks

Small Tweaks for Pest v2
This commit is contained in:
Nuno Maduro
2021-11-27 11:30:52 +00:00
committed by GitHub
2 changed files with 78 additions and 59 deletions

View File

@ -7,7 +7,6 @@ namespace Pest\Factories;
use ParseError; use ParseError;
use Pest\Concerns; use Pest\Concerns;
use Pest\Contracts\HasPrintableTestCaseName; use Pest\Contracts\HasPrintableTestCaseName;
use Pest\Datasets;
use Pest\Exceptions\DatasetMissing; use Pest\Exceptions\DatasetMissing;
use Pest\Exceptions\ShouldNotHappen; use Pest\Exceptions\ShouldNotHappen;
use Pest\Exceptions\TestAlreadyExist; use Pest\Exceptions\TestAlreadyExist;
@ -73,9 +72,10 @@ final class TestCaseFactory
{ {
$methodsUsingOnly = $this->methodsUsingOnly(); $methodsUsingOnly = $this->methodsUsingOnly();
$methods = array_values(array_filter($this->methods, function ($method) use ($methodsUsingOnly) { $methods = array_values(array_filter(
return count($methodsUsingOnly) === 0 || in_array($method, $methodsUsingOnly, true); $this->methods,
})); fn ($method) => count($methodsUsingOnly) === 0 || in_array($method, $methodsUsingOnly, true)
));
if (count($methods) > 0) { if (count($methods) > 0) {
$this->evaluate($this->filename, $methods); $this->evaluate($this->filename, $methods);
@ -141,56 +141,10 @@ final class TestCaseFactory
$classFQN .= $className; $classFQN .= $className;
} }
$methodsCode = implode('', array_map(static function (TestCaseMethodFactory $method): string { $methodsCode = implode('', array_map(
if ($method->description === null) { fn (TestCaseMethodFactory $methodFactory) => $methodFactory->buildForEvaluation(self::$annotations),
throw ShouldNotHappen::fromMessage('The test description may not be empty.'); $methods
} ));
$methodName = Str::evaluable($method->description);
$datasetsCode = '';
$annotations = ['@test'];
foreach (self::$annotations as $annotation) {
/** @phpstan-ignore-next-line */
$annotations = (new $annotation())->__invoke($method, $annotations);
}
if (count($method->datasets) > 0) {
$dataProviderName = $methodName . '_dataset';
$annotations[] = "@dataProvider $dataProviderName";
Datasets::with($method->filename, $methodName, $method->datasets);
$datasetsCode = <<<EOF
public function $dataProviderName()
{
return __PestDatasets::get(self::\$__filename, "$methodName");
}
EOF;
}
$annotations = implode('', array_map(
static fn ($annotation) => sprintf("\n * %s", $annotation), $annotations,
));
return <<<EOF
/**$annotations
*/
public function $methodName()
{
return \$this->__runTest(
\$this->__test,
...func_get_args(),
);
}
$datasetsCode
EOF;
}, $methods));
try { try {
eval(" eval("

View File

@ -5,8 +5,10 @@ declare(strict_types=1);
namespace Pest\Factories; namespace Pest\Factories;
use Closure; use Closure;
use Pest\Datasets;
use Pest\Exceptions\ShouldNotHappen; use Pest\Exceptions\ShouldNotHappen;
use Pest\Factories\Concerns\HigherOrderable; use Pest\Factories\Concerns\HigherOrderable;
use Pest\Support\Str;
use Pest\TestSuite; use Pest\TestSuite;
use PHPUnit\Framework\Assert; use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@ -17,6 +19,7 @@ use PHPUnit\Framework\TestCase;
final class TestCaseMethodFactory final class TestCaseMethodFactory
{ {
use HigherOrderable; use HigherOrderable;
/** /**
* Determines if the Test Case will be the "only" being run. * Determines if the Test Case will be the "only" being run.
*/ */
@ -51,11 +54,9 @@ final class TestCaseMethodFactory
public ?string $description, public ?string $description,
public ?Closure $closure, public ?Closure $closure,
) { ) {
if ($this->closure === null) { $this->closure ??= function () {
$this->closure = function () { Assert::getCount() > 0 ?: self::markTestIncomplete(); // @phpstan-ignore-line
Assert::getCount() > 0 ?: self::markTestIncomplete(); // @phpstan-ignore-line };
};
}
$this->bootHigherOrderable(); $this->bootHigherOrderable();
} }
@ -100,4 +101,68 @@ final class TestCaseMethodFactory
{ {
return count($this->datasets) > 0 || count($this->depends) > 0; return count($this->datasets) > 0 || count($this->depends) > 0;
} }
/**
* Creates a PHPUnit method as a string ready for evaluation.
*
* @param array<int, class-string> $annotationsToUse
*/
public function buildForEvaluation(array $annotationsToUse): string
{
if ($this->description === null) {
throw ShouldNotHappen::fromMessage('The test description may not be empty.');
}
$methodName = Str::evaluable($this->description);
$datasetsCode = '';
$annotations = ['@test'];
foreach ($annotationsToUse as $annotation) {
/** @phpstan-ignore-next-line */
$annotations = (new $annotation())->__invoke($this, $annotations);
}
if (count($this->datasets) > 0) {
$dataProviderName = $methodName . '_dataset';
$annotations[] = "@dataProvider $dataProviderName";
$datasetsCode = $this->buildDatasetForEvaluation($methodName, $dataProviderName);
}
$annotations = implode('', array_map(
static fn ($annotation) => sprintf("\n * %s", $annotation), $annotations,
));
return <<<EOF
/**$annotations
*/
public function $methodName()
{
return \$this->__runTest(
\$this->__test,
...func_get_args(),
);
}
$datasetsCode
EOF;
}
/**
* Creates a PHPUnit Data Provider as a string ready for evaluation.
*/
private function buildDatasetForEvaluation(string $methodName, string $dataProviderName): string
{
Datasets::with($this->filename, $methodName, $this->datasets);
return <<<EOF
public function $dataProviderName()
{
return __PestDatasets::get(self::\$__filename, "$methodName");
}
EOF;
}
} }