feat: support for deprecated, notices, and warnings

This commit is contained in:
Nuno Maduro
2023-03-02 20:37:18 +00:00
parent 3f6b2e856e
commit 1e61034e86
11 changed files with 124 additions and 38 deletions

View File

@ -12,6 +12,7 @@ use function fread;
use function fseek;
use function ftell;
use function fwrite;
use NunoMaduro\Collision\Adapters\Phpunit\State;
use ParaTest\Options;
use Pest\Plugins\Parallel\Support\CompactPrinter;
use Pest\Support\StateGenerator;
@ -27,11 +28,21 @@ use Symfony\Component\Console\Output\OutputInterface;
/** @internal */
final class ResultPrinter
{
/**
* If the test should be marked as todo.
*/
public bool $lastWasTodo = false;
/**
* The "native" printer.
*/
public readonly Printer $printer;
/**
* The state.
*/
public int $passedTests = 0;
/**
* The "compact" printer.
*/
@ -140,7 +151,7 @@ final class ResultPrinter
return;
}
$state = (new StateGenerator())->fromPhpUnitTestResult($testResult);
$state = (new StateGenerator())->fromPhpUnitTestResult($this->passedTests, $testResult);
$this->compactPrinter->errors($state);
$this->compactPrinter->recap($state, $testResult, $duration, $this->options);
@ -148,6 +159,20 @@ final class ResultPrinter
private function printFeedbackItem(string $item): void
{
if ($this->lastWasTodo) {
$this->lastWasTodo = false;
return;
}
if ($item === 'T') {
$this->lastWasTodo = true;
}
if ($item === '.') {
$this->passedTests++;
}
$this->compactPrinter->descriptionItem($item);
}

View File

@ -36,8 +36,8 @@ final class CompactPrinter
'.' => ['gray', '.'],
'S' => ['yellow', 's'],
'T' => ['cyan', 't'],
'I' => ['yellow', 'i'],
'N' => ['yellow', 'i'],
'I' => ['yellow', '!'],
'N' => ['yellow', '!'],
'D' => ['yellow', '!'],
'R' => ['yellow', '!'],
'W' => ['yellow', '!'],
@ -106,7 +106,9 @@ final class CompactPrinter
*/
public function errors(State $state): void
{
$this->style->writeErrorsSummary($state, false);
$this->output->writeln('');
$this->style->writeErrorsSummary($state);
}
/**

View File

@ -6,15 +6,12 @@ namespace Pest\Support;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use Throwable;
/**
* @internal
*/
final class HigherOrderTapProxy
{
private const UNDEFINED_PROPERTY = 'Undefined property: P\\'; // @phpstan-ignore-line
/**
* Create a new tap proxy instance.
*/
@ -40,16 +37,18 @@ final class HigherOrderTapProxy
public function __get(string $property)
{
if (property_exists($this->target, $property)) {
return $this->target->{$property};
return $this->target->{$property}; // @phpstan-ignore-line
}
$className = (new ReflectionClass($this->target))->getName();
if (str_starts_with($className, "P\\")) {
if (str_starts_with($className, 'P\\')) {
$className = substr($className, 2);
}
trigger_error(sprintf('Undefined property %s::$%s', $className, $property), E_USER_WARNING);
return null;
}
/**

View File

@ -11,6 +11,7 @@ use PHPUnit\Event\Code\TestMethod;
use PHPUnit\Event\Code\Throwable;
use PHPUnit\Event\Test\Errored;
use PHPUnit\Event\TestData\TestDataCollection;
use PHPUnit\Framework\Exception;
use PHPUnit\Framework\IncompleteTestError;
use PHPUnit\Framework\SkippedWithMessageException;
use PHPUnit\Metadata\MetadataCollection;
@ -18,7 +19,7 @@ use PHPUnit\TestRunner\TestResult\TestResult as PHPUnitTestResult;
final class StateGenerator
{
public function fromPhpUnitTestResult(PHPUnitTestResult $testResult): State
public function fromPhpUnitTestResult(int $passedTests, PHPUnitTestResult $testResult): State
{
$state = new State();
@ -74,16 +75,69 @@ final class StateGenerator
));
}
$numberOfPassedTests = $testResult->numberOfTestsRun()
- $testResult->numberOfTestErroredEvents()
- $testResult->numberOfTestFailedEvents()
- $testResult->numberOfTestSkippedEvents()
- $testResult->numberOfTestsWithTestConsideredRiskyEvents()
- $testResult->numberOfTestMarkedIncompleteEvents();
foreach ($testResult->testTriggeredDeprecationEvents() as $testResultEvent) {
$testResultEvent = $testResultEvent[0];
for ($i = 0; $i < $numberOfPassedTests; $i++) {
$state->add(TestResult::fromTestCase(
$testResultEvent->test(),
TestResult::DEPRECATED,
Throwable::from(new Exception($testResultEvent->message()))
));
}
foreach ($testResult->testTriggeredPhpDeprecationEvents() as $testResultEvent) {
$testResultEvent = $testResultEvent[0];
$state->add(TestResult::fromTestCase(
$testResultEvent->test(),
TestResult::DEPRECATED,
Throwable::from(new Exception($testResultEvent->message()))
));
}
foreach ($testResult->testTriggeredNoticeEvents() as $testResultEvent) {
$testResultEvent = $testResultEvent[0];
$state->add(TestResult::fromTestCase(
$testResultEvent->test(),
TestResult::NOTICE,
Throwable::from(new Exception($testResultEvent->message()))
));
}
foreach ($testResult->testTriggeredPhpNoticeEvents() as $testResultEvent) {
$testResultEvent = $testResultEvent[0];
$state->add(TestResult::fromTestCase(
$testResultEvent->test(),
TestResult::NOTICE,
Throwable::from(new Exception($testResultEvent->message()))
));
}
foreach ($testResult->testTriggeredWarningEvents() as $testResultEvent) {
$testResultEvent = $testResultEvent[0];
$state->add(TestResult::fromTestCase(
$testResultEvent->test(),
TestResult::WARN,
Throwable::from(new Exception($testResultEvent->message()))
));
}
foreach ($testResult->testTriggeredPhpWarningEvents() as $testResultEvent) {
$testResultEvent = $testResultEvent[0];
$state->add(TestResult::fromTestCase(
$testResultEvent->test(),
TestResult::WARN,
Throwable::from(new Exception($testResultEvent->message()))
));
}
// for each test that passed, we need to add it to the state
for ($i = 0; $i < $passedTests; $i++) {
$state->add(TestResult::fromTestCase(
new TestMethod(
/** @phpstan-ignore-next-line */
"$i",