Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 18 additions & 26 deletions src/Runner/TestResult/Collector.php
Original file line number Diff line number Diff line change
Expand Up @@ -626,51 +626,43 @@ public function childProcessErrored(ChildProcessErrored $event): void
$this->childProcessErrored = true;
}

public function hasErroredTests(): bool
public function numberOfErroredTests(): int
{
return $this->testErroredEvents !== [];
return count($this->testErroredEvents);
}

public function hasFailedTests(): bool
public function numberOfFailedTests(): int
{
return $this->testFailedEvents !== [];
return count($this->testFailedEvents);
}

public function hasRiskyTests(): bool
public function numberOfRiskyTests(): int
{
return $this->testConsideredRiskyEvents !== [];
return count($this->testConsideredRiskyEvents);
}

public function hasSkippedTests(): bool
public function numberOfSkippedTests(): int
{
return $this->testSkippedEvents !== [];
return count($this->testSkippedEvents);
}

public function hasIncompleteTests(): bool
public function numberOfIncompleteTests(): int
{
return $this->testMarkedIncompleteEvents !== [];
return count($this->testMarkedIncompleteEvents);
}

public function hasDeprecations(): bool
public function numberOfNotices(): int
{
return $this->deprecations !== [] ||
$this->phpDeprecations !== [] ||
$this->testTriggeredPhpunitDeprecationEvents !== [] ||
$this->testRunnerTriggeredDeprecationEvents !== [];
return count($this->notices) +
count($this->phpNotices);
}

public function hasNotices(): bool
public function numberOfWarnings(): int
{
return $this->notices !== [] ||
$this->phpNotices !== [];
}

public function hasWarnings(): bool
{
return $this->warnings !== [] ||
$this->phpWarnings !== [] ||
$this->testTriggeredPhpunitWarningEvents !== [] ||
$this->testRunnerTriggeredWarningEvents !== [];
return count($this->warnings) +
count($this->phpWarnings) +
count($this->testTriggeredPhpunitWarningEvents) +
count($this->testRunnerTriggeredWarningEvents);
}

/**
Expand Down
64 changes: 46 additions & 18 deletions src/Runner/TestResult/Facade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
*/
namespace PHPUnit\TestRunner\TestResult;

use function array_any;
use function array_filter;
use function count;
use function str_contains;
use PHPUnit\Event\Facade as EventFacade;
use PHPUnit\Runner\DeprecationCollector\Facade as DeprecationCollectorFacade;
Expand Down Expand Up @@ -41,35 +42,60 @@ public static function shouldStop(): bool
$configuration = ConfigurationRegistry::get();
$collector = self::collector();

if (($configuration->stopOnDefect() || $configuration->stopOnError()) && $collector->hasErroredTests()) {
$numberOfErrors = $collector->numberOfErroredTests();
$numberOfFailures = $collector->numberOfFailedTests();
$numberOfWarnings = $collector->numberOfWarnings();
$numberOfRisky = $collector->numberOfRiskyTests();

$stopOnDefect = $configuration->stopOnDefectThreshold();

if ($stopOnDefect > 0 && ($numberOfErrors + $numberOfFailures + $numberOfWarnings + $numberOfRisky) >= $stopOnDefect) {
return true;
}

if (($configuration->stopOnDefect() || $configuration->stopOnFailure()) && $collector->hasFailedTests()) {
$stopOnError = $configuration->stopOnErrorThreshold();

if ($stopOnError > 0 && $numberOfErrors >= $stopOnError) {
return true;
}

$stopOnFailure = $configuration->stopOnFailureThreshold();

if ($stopOnFailure > 0 && $numberOfFailures >= $stopOnFailure) {
return true;
}

if (($configuration->stopOnDefect() || $configuration->stopOnWarning()) && $collector->hasWarnings()) {
$stopOnWarning = $configuration->stopOnWarningThreshold();

if ($stopOnWarning > 0 && $numberOfWarnings >= $stopOnWarning) {
return true;
}

if (($configuration->stopOnDefect() || $configuration->stopOnRisky()) && $collector->hasRiskyTests()) {
$stopOnRisky = $configuration->stopOnRiskyThreshold();

if ($stopOnRisky > 0 && $numberOfRisky >= $stopOnRisky) {
return true;
}

if (self::stopOnDeprecation($configuration)) {
return true;
}

if ($configuration->stopOnNotice() && $collector->hasNotices()) {
$stopOnNotice = $configuration->stopOnNoticeThreshold();

if ($stopOnNotice > 0 && $collector->numberOfNotices() >= $stopOnNotice) {
return true;
}

if ($configuration->stopOnIncomplete() && $collector->hasIncompleteTests()) {
$stopOnIncomplete = $configuration->stopOnIncompleteThreshold();

if ($stopOnIncomplete > 0 && $collector->numberOfIncompleteTests() >= $stopOnIncomplete) {
return true;
}

if ($configuration->stopOnSkipped() && $collector->hasSkippedTests()) {
$stopOnSkipped = $configuration->stopOnSkippedThreshold();

if ($stopOnSkipped > 0 && $collector->numberOfSkippedTests() >= $stopOnSkipped) {
return true;
}

Expand All @@ -92,22 +118,24 @@ private static function collector(): Collector

private static function stopOnDeprecation(Configuration $configuration): bool
{
if (!$configuration->stopOnDeprecation()) {
$threshold = $configuration->stopOnDeprecationThreshold();

if ($threshold === 0) {
return false;
}

$deprecations = DeprecationCollectorFacade::filteredDeprecations();

if (!$configuration->hasSpecificDeprecationToStopOn()) {
return $deprecations !== [];
if ($configuration->hasSpecificDeprecationToStopOn()) {
$deprecations = array_filter(
$deprecations,
static fn (string $deprecation) => str_contains(
$deprecation,
$configuration->specificDeprecationToStopOn(),
),
);
}

return array_any(
$deprecations,
static fn (string $deprecation) => str_contains(
$deprecation,
$configuration->specificDeprecationToStopOn(),
),
);
return count($deprecations) >= $threshold;
}
}
49 changes: 31 additions & 18 deletions src/TextUI/Configuration/Cli/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use function getcwd;
use function is_file;
use function is_numeric;
use function max;
use function sprintf;
use function strtolower;
use PHPUnit\Event\Facade as EventFacade;
Expand Down Expand Up @@ -135,15 +136,15 @@ final class Builder
'do-not-fail-on-risky',
'do-not-fail-on-skipped',
'do-not-fail-on-warning',
'stop-on-defect',
'stop-on-defect==',
'stop-on-deprecation==',
'stop-on-error',
'stop-on-failure',
'stop-on-incomplete',
'stop-on-notice',
'stop-on-risky',
'stop-on-skipped',
'stop-on-warning',
'stop-on-error==',
'stop-on-failure==',
'stop-on-incomplete==',
'stop-on-notice==',
'stop-on-risky==',
'stop-on-skipped==',
'stop-on-warning==',
'strict-coverage',
'disable-coverage-ignore',
'strict-global-state',
Expand Down Expand Up @@ -933,51 +934,51 @@ public function fromParameters(array $parameters): Configuration
break;

case '--stop-on-defect':
$stopOnDefect = true;
$stopOnDefect = $this->parseStopOnValue($option[1]);

break;

case '--stop-on-deprecation':
$stopOnDeprecation = true;
$stopOnDeprecation = $this->parseStopOnValue($option[1]);

if ($option[1] !== null) {
if ($option[1] !== null && !is_numeric($option[1])) {
$specificDeprecationToStopOn = $option[1];
}

break;

case '--stop-on-error':
$stopOnError = true;
$stopOnError = $this->parseStopOnValue($option[1]);

break;

case '--stop-on-failure':
$stopOnFailure = true;
$stopOnFailure = $this->parseStopOnValue($option[1]);

break;

case '--stop-on-incomplete':
$stopOnIncomplete = true;
$stopOnIncomplete = $this->parseStopOnValue($option[1]);

break;

case '--stop-on-notice':
$stopOnNotice = true;
$stopOnNotice = $this->parseStopOnValue($option[1]);

break;

case '--stop-on-risky':
$stopOnRisky = true;
$stopOnRisky = $this->parseStopOnValue($option[1]);

break;

case '--stop-on-skipped':
$stopOnSkipped = true;
$stopOnSkipped = $this->parseStopOnValue($option[1]);

break;

case '--stop-on-warning':
$stopOnWarning = true;
$stopOnWarning = $this->parseStopOnValue($option[1]);

break;

Expand Down Expand Up @@ -1422,4 +1423,16 @@ private function warnWhenOptionsConflict(?bool $current, string $option, string
),
);
}

/**
* @return positive-int
*/
private function parseStopOnValue(?string $value): int
{
if ($value !== null && is_numeric($value)) {
return max(1, (int) $value);
}

return 1;
}
}
Loading