Skip to content

Commit 34a8070

Browse files
Initial work on detecting where an issue was triggered (in test code, first-party code, or third-party code) and from where the triggering code was called (from test code, first-party code, or third-party code)
1 parent c4f0c78 commit 34a8070

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

src/Runner/ErrorHandler.php

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@
2424
use const E_USER_NOTICE;
2525
use const E_USER_WARNING;
2626
use const E_WARNING;
27+
use function debug_backtrace;
2728
use function error_reporting;
2829
use function restore_error_handler;
2930
use function set_error_handler;
3031
use PHPUnit\Event;
3132
use PHPUnit\Event\Code\NoTestCaseObjectOnCallStackException;
3233
use PHPUnit\Runner\Baseline\Baseline;
3334
use PHPUnit\Runner\Baseline\Issue;
35+
use PHPUnit\TextUI\Configuration\Registry;
36+
use PHPUnit\TextUI\Configuration\Source;
37+
use PHPUnit\TextUI\Configuration\SourceFilter;
3438
use PHPUnit\Util\ExcludeList;
3539

3640
/**
@@ -44,10 +48,18 @@ final class ErrorHandler
4448
private ?Baseline $baseline = null;
4549
private bool $enabled = false;
4650
private ?int $originalErrorReportingLevel = null;
51+
private readonly Source $source;
52+
private readonly SourceFilter $sourceFilter;
4753

4854
public static function instance(): self
4955
{
50-
return self::$instance ?? self::$instance = new self;
56+
return self::$instance ?? self::$instance = new self(Registry::get()->source());
57+
}
58+
59+
private function __construct(Source $source)
60+
{
61+
$this->source = $source;
62+
$this->sourceFilter = new SourceFilter;
5163
}
5264

5365
/**
@@ -61,11 +73,35 @@ public function __invoke(int $errorNumber, string $errorString, string $errorFil
6173
return false;
6274
}
6375

64-
$test = Event\Code\TestMethodBuilder::fromCallStack();
76+
$trace = debug_backtrace(0);
77+
$test = Event\Code\TestMethodBuilder::fromCallStack();
6578

6679
$ignoredByBaseline = $this->ignoredByBaseline($errorFile, $errorLine, $errorString);
6780
$ignoredByTest = $test->metadata()->isIgnoreDeprecations()->isNotEmpty();
6881

82+
$triggeredInTestCode = false;
83+
$triggeredInFirstPartyCode = false;
84+
$triggeredInThirdPartyCode = false;
85+
$triggerCalledFromTestCode = false;
86+
$triggerCalledFromFirstPartyCode = false;
87+
$triggerCalledFromThirdPartyCode = false;
88+
89+
if ($trace[1]['file'] === $test->file()) {
90+
$triggeredInTestCode = true;
91+
} elseif ($this->sourceFilter->includes($this->source, $trace[1]['file'])) {
92+
$triggeredInFirstPartyCode = true;
93+
} else {
94+
$triggeredInThirdPartyCode = true;
95+
}
96+
97+
if ($trace[2]['file'] === $test->file()) {
98+
$triggerCalledFromTestCode = true;
99+
} elseif ($this->sourceFilter->includes($this->source, $trace[2]['file'])) {
100+
$triggerCalledFromFirstPartyCode = true;
101+
} else {
102+
$triggerCalledFromThirdPartyCode = true;
103+
}
104+
69105
switch ($errorNumber) {
70106
case E_NOTICE:
71107
case E_STRICT:

0 commit comments

Comments
 (0)