mirror of
https://github.com/pestphp/pest.git
synced 2026-06-08 12:12:17 +02:00
wip
This commit is contained in:
@ -768,6 +768,23 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable
|
|||||||
|
|
||||||
$affected = $changed === [] ? [] : $graph->affected($changed);
|
$affected = $changed === [] ? [] : $graph->affected($changed);
|
||||||
|
|
||||||
|
if ($this->filteredMode) {
|
||||||
|
if ($graph->hasUnlocatedFailuresOrErrors($this->branch)) {
|
||||||
|
$this->output->writeln([
|
||||||
|
'',
|
||||||
|
' <fg=yellow>TIA</> cached failures/errors exist but this baseline cannot map them to files — running full suite.',
|
||||||
|
'',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
$affected = array_values(array_unique([
|
||||||
|
...$affected,
|
||||||
|
...$graph->failedOrErroredTestFiles($this->branch),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
$affectedSet = array_fill_keys($affected, true);
|
$affectedSet = array_fill_keys($affected, true);
|
||||||
$canRefreshReplayEdges = $affected !== [] && $coverageAvailable;
|
$canRefreshReplayEdges = $affected !== [] && $coverageAvailable;
|
||||||
|
|
||||||
@ -1032,6 +1049,10 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable
|
|||||||
'time' => is_float($result['time'] ?? null) || is_int($result['time'] ?? null) ? (float) $result['time'] : 0.0,
|
'time' => is_float($result['time'] ?? null) || is_int($result['time'] ?? null) ? (float) $result['time'] : 0.0,
|
||||||
'assertions' => is_int($result['assertions'] ?? null) ? $result['assertions'] : 0,
|
'assertions' => is_int($result['assertions'] ?? null) ? $result['assertions'] : 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (isset($result['file']) && is_string($result['file'])) {
|
||||||
|
$normalised[$testId]['file'] = $result['file'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($normalised !== []) {
|
if ($normalised !== []) {
|
||||||
@ -1178,6 +1199,7 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable
|
|||||||
$result['message'],
|
$result['message'],
|
||||||
$result['time'],
|
$result['time'],
|
||||||
$result['assertions'],
|
$result['assertions'],
|
||||||
|
$result['file'] ?? null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1211,6 +1233,7 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable
|
|||||||
$result['message'],
|
$result['message'],
|
||||||
$result['time'],
|
$result['time'],
|
||||||
$result['assertions'],
|
$result['assertions'],
|
||||||
|
$result['file'] ?? null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ final class Graph
|
|||||||
* @var array<string, array{
|
* @var array<string, array{
|
||||||
* sha: ?string,
|
* sha: ?string,
|
||||||
* tree: array<string, string>,
|
* tree: array<string, string>,
|
||||||
* results: array<string, array{status: int, message: string, time: float, assertions?: int}>
|
* results: array<string, array{status: int, message: string, time: float, assertions?: int, file?: string}>
|
||||||
* }>
|
* }>
|
||||||
*/
|
*/
|
||||||
private array $baselines = [];
|
private array $baselines = [];
|
||||||
@ -468,7 +468,7 @@ final class Graph
|
|||||||
$this->baselines[$branch]['sha'] = $sha;
|
$this->baselines[$branch]['sha'] = $sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setResult(string $branch, string $testId, int $status, string $message, float $time, int $assertions = 0): void
|
public function setResult(string $branch, string $testId, int $status, string $message, float $time, int $assertions = 0, ?string $file = null): void
|
||||||
{
|
{
|
||||||
$this->ensureBaseline($branch);
|
$this->ensureBaseline($branch);
|
||||||
$this->baselines[$branch]['results'][$testId] = [
|
$this->baselines[$branch]['results'][$testId] = [
|
||||||
@ -477,6 +477,14 @@ final class Graph
|
|||||||
'time' => $time,
|
'time' => $time,
|
||||||
'assertions' => $assertions,
|
'assertions' => $assertions,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($file !== null) {
|
||||||
|
$rel = $this->relative($file);
|
||||||
|
|
||||||
|
if ($rel !== null) {
|
||||||
|
$this->baselines[$branch]['results'][$testId]['file'] = $rel;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAssertions(string $branch, string $testId, string $fallbackBranch = 'main'): ?int
|
public function getAssertions(string $branch, string $testId, string $fallbackBranch = 'main'): ?int
|
||||||
@ -517,6 +525,58 @@ final class Graph
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public function failedOrErroredTestFiles(string $branch, string $fallbackBranch = 'main'): array
|
||||||
|
{
|
||||||
|
$baseline = $this->baselineFor($branch, $fallbackBranch);
|
||||||
|
$files = [];
|
||||||
|
|
||||||
|
foreach ($baseline['results'] as $result) {
|
||||||
|
$status = $result['status'] ?? null;
|
||||||
|
|
||||||
|
if ($status !== 7 && $status !== 8) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $result['file'] ?? null;
|
||||||
|
|
||||||
|
if (! is_string($file) || $file === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rel = $this->relative($file);
|
||||||
|
|
||||||
|
if ($rel !== null) {
|
||||||
|
$files[$rel] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_keys($files);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasUnlocatedFailuresOrErrors(string $branch, string $fallbackBranch = 'main'): bool
|
||||||
|
{
|
||||||
|
$baseline = $this->baselineFor($branch, $fallbackBranch);
|
||||||
|
|
||||||
|
foreach ($baseline['results'] as $result) {
|
||||||
|
$status = $result['status'] ?? null;
|
||||||
|
|
||||||
|
if ($status !== 7 && $status !== 8) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $result['file'] ?? null;
|
||||||
|
|
||||||
|
if (! is_string($file) || $file === '' || $this->relative($file) === null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, string> $tree project-relative path → content hash
|
* @param array<string, string> $tree project-relative path → content hash
|
||||||
*/
|
*/
|
||||||
@ -542,7 +602,7 @@ final class Graph
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array{sha: ?string, tree: array<string, string>, results: array<string, array{status: int, message: string, time: float, assertions?: int}>}
|
* @return array{sha: ?string, tree: array<string, string>, results: array<string, array{status: int, message: string, time: float, assertions?: int, file?: string}>}
|
||||||
*/
|
*/
|
||||||
private function baselineFor(string $branch, string $fallbackBranch): array
|
private function baselineFor(string $branch, string $fallbackBranch): array
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,17 +14,20 @@ namespace Pest\Plugins\Tia;
|
|||||||
final class ResultCollector
|
final class ResultCollector
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var array<string, array{status: int, message: string, time: float, assertions: int}>
|
* @var array<string, array{status: int, message: string, time: float, assertions: int, file?: string}>
|
||||||
*/
|
*/
|
||||||
private array $results = [];
|
private array $results = [];
|
||||||
|
|
||||||
private ?string $currentTestId = null;
|
private ?string $currentTestId = null;
|
||||||
|
|
||||||
|
private ?string $currentTestFile = null;
|
||||||
|
|
||||||
private ?float $startTime = null;
|
private ?float $startTime = null;
|
||||||
|
|
||||||
public function testPrepared(string $testId): void
|
public function testPrepared(string $testId, ?string $testFile = null): void
|
||||||
{
|
{
|
||||||
$this->currentTestId = $testId;
|
$this->currentTestId = $testId;
|
||||||
|
$this->currentTestFile = $testFile;
|
||||||
$this->startTime = microtime(true);
|
$this->startTime = microtime(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +86,7 @@ final class ResultCollector
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string, array{status: int, message: string, time: float, assertions: int}>
|
* @return array<string, array{status: int, message: string, time: float, assertions: int, file?: string}>
|
||||||
*/
|
*/
|
||||||
public function all(): array
|
public function all(): array
|
||||||
{
|
{
|
||||||
@ -102,7 +105,7 @@ final class ResultCollector
|
|||||||
* workers) into this collector so the parent can persist them in the same
|
* workers) into this collector so the parent can persist them in the same
|
||||||
* snapshot pass as non-parallel runs.
|
* snapshot pass as non-parallel runs.
|
||||||
*
|
*
|
||||||
* @param array<string, array{status: int, message: string, time: float, assertions: int}> $results
|
* @param array<string, array{status: int, message: string, time: float, assertions: int, file?: string}> $results
|
||||||
*/
|
*/
|
||||||
public function merge(array $results): void
|
public function merge(array $results): void
|
||||||
{
|
{
|
||||||
@ -115,6 +118,7 @@ final class ResultCollector
|
|||||||
{
|
{
|
||||||
$this->results = [];
|
$this->results = [];
|
||||||
$this->currentTestId = null;
|
$this->currentTestId = null;
|
||||||
|
$this->currentTestFile = null;
|
||||||
$this->startTime = null;
|
$this->startTime = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +130,7 @@ final class ResultCollector
|
|||||||
public function finishTest(): void
|
public function finishTest(): void
|
||||||
{
|
{
|
||||||
$this->currentTestId = null;
|
$this->currentTestId = null;
|
||||||
|
$this->currentTestFile = null;
|
||||||
$this->startTime = null;
|
$this->startTime = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,5 +156,9 @@ final class ResultCollector
|
|||||||
'time' => $time,
|
'time' => $time,
|
||||||
'assertions' => $existing['assertions'] ?? 0,
|
'assertions' => $existing['assertions'] ?? 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($this->currentTestFile !== null) {
|
||||||
|
$this->results[$this->currentTestId]['file'] = $this->currentTestFile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ final readonly class EnsureTiaResultsAreCollected implements PreparedSubscriber
|
|||||||
$test = $event->test();
|
$test = $event->test();
|
||||||
|
|
||||||
if ($test instanceof TestMethod) {
|
if ($test instanceof TestMethod) {
|
||||||
$this->collector->testPrepared($test->className().'::'.$test->methodName());
|
$this->collector->testPrepared($test->className().'::'.$test->methodName(), $test->file());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user