Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: initialize data-provided tests late #3210

Closed
wants to merge 13 commits into from
114 changes: 114 additions & 0 deletions src/Framework/DataProvidedTestSuite.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework;

use Generator;
use ReflectionClass;
use Throwable;

abstract class DataProvidedTestSuite extends TestSuite
{
/**
* @var ReflectionClass
*/
protected $theClass;
protected $method;
public function __construct(ReflectionClass $theClass, string $method)
{
parent::__construct($theClass, $theClass->getName().'::'.$method, true);
$this->theClass = $theClass;
$this->method = $method;
}
/**
* @var string[]
*/
private $dependencies = [];

/**
* @param string[] $dependencies
*/
public function setDependencies(array $dependencies): void
{
$this->dependencies = $dependencies;

foreach ($this->tests as $test) {
$test->setDependencies($dependencies);
}
}

public function getDependencies(): array
{
return $this->dependencies;
}

public function hasDependencies(): bool
{
return \count($this->dependencies) > 0;
}

abstract protected function yieldData(): iterable;

/**
* @return Generator|Test[]
*/
protected function yieldTests(): Generator
{
yield from parent::yieldTests();
try {
foreach ($this->yieldData() as $name => $set) {
if(!is_array($set)) {
yield self::incompleteTest(
$this->name,
$this->method,
"{$this->name} set $name is invalid."
);
continue;
}

try {
$test = $this->theClass->newInstanceArgs([
$this->method,
$set,
$name
]);
$test->setDependencies($this->dependencies);
yield $test;
} catch (Throwable $e) {
yield new TestFailureTest(
$this->name,
$this->method,
"Test creation failed for {$this->name} with set $name"
);
}
}
} catch (RiskyTestError $exception) {
return new RiskyTestError($exception->getMessage(), 0, $exception);
} catch(IncompleteTestError $exception) {
return self::incompleteTest(
$this->theClass->getName(),
$this->method,
$exception->getMessage()
);
} catch (SkippedTestError $e) {
return new SkippedTestCase(
$this->name,
$this->method,
"Test for {$this->name} skipped by data provider."
);
} catch (Throwable $e) {
return self::warning("The data provider specified for {$this->name} is invalid.");
}
}

public function count($preferCache = false): int
{
return 1;
}
}
40 changes: 18 additions & 22 deletions src/Framework/DataProviderTestSuite.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,28 @@
*/
namespace PHPUnit\Framework;

class DataProviderTestSuite extends TestSuite
{
/**
* @var string[]
*/
private $dependencies = [];

/**
* @param string[] $dependencies
*/
public function setDependencies(array $dependencies): void
{
$this->dependencies = $dependencies;

foreach ($this->tests as $test) {
$test->setDependencies($dependencies);
}
}
use ReflectionClass;

public function getDependencies(): array
class DataProviderTestSuite extends DataProvidedTestSuite
{
private $provider;
public function __construct($provider, ReflectionClass $theClass, string $method)
{
return $this->dependencies;
parent::__construct($theClass, $method);
$this->provider = $provider;
}

public function hasDependencies(): bool
protected function yieldData(): iterable
{
return \count($this->dependencies) > 0;
if (!$this->theClass->hasMethod($this->provider)) {
throw new Exception();
}
if (!$this->theClass->getMethod($this->provider)->isPublic()) {
throw new Exception();
}
if ($this->theClass->getMethod($this->provider)->isAbstract()) {
throw new Exception();
}
yield from $this->theClass->newInstanceArgs()->{$this->provider}();
}
}
22 changes: 10 additions & 12 deletions src/Framework/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -1098,20 +1098,18 @@ public function registerComparator(Comparator $comparator): void

public function getDataSetAsString(bool $includeData = true): string
{
if (empty($this->data)) {
return '';
}
$buffer = '';
if (\is_int($this->dataName)) {
$buffer .= \sprintf(' with data set #%d', $this->dataName);
} else {
$buffer .= \sprintf(' with data set "%s"', $this->dataName);
}

if (!empty($this->data)) {
if (\is_int($this->dataName)) {
$buffer .= \sprintf(' with data set #%d', $this->dataName);
} else {
$buffer .= \sprintf(' with data set "%s"', $this->dataName);
}

$exporter = new Exporter;

if ($includeData) {
$buffer .= \sprintf(' (%s)', $exporter->shortenedRecursiveExport($this->data));
}
if ($includeData) {
$buffer .= \sprintf(' (%s)', (new Exporter)->shortenedRecursiveExport($this->data));
}

return $buffer;
Expand Down
Loading