Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: symfony/phpunit-bridge
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v5.4.25
Choose a base ref
...
head repository: symfony/phpunit-bridge
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v5.4.26
Choose a head ref
  • 3 commits
  • 4 files changed
  • 2 contributors

Commits on Jul 7, 2023

  1. Copy the full SHA
    6ffaf5e View commit details
  2. bug #47252 [PhpUnitBridge] Use triggering class to generate baseline …

    …for deprecation messages from DebugClassLoader (leongersen)
    
    This PR was merged into the 5.4 branch.
    
    Discussion
    ----------
    
    [PhpUnitBridge] Use triggering class to generate baseline for deprecation messages from DebugClassLoader
    
    | Q             | A
    | ------------- | ---
    | Branch?       | 5.4
    | Bug fix?      | yes
    | New feature?  | no
    | Deprecations? | no
    | Tickets       | Fix #45943
    | License       | MIT
    | Doc PR        | N/A
    
    Fixes #45943 by using the triggering class to generate the baseline for messages from `DebugClassLoader`.
    
    This would break currently generated baselines, but as #45943 describes, those are broken already when running tests in another order, or when running a sub-/superset of tests.
    
    I'll finish this PR by adding/updating tests if this approach is acceptable.
    
    Commits
    -------
    
    3987757aad Use triggering class to generate baseline for deprecation messages from DebugClassLoader
    nicolas-grekas committed Jul 7, 2023
    Copy the full SHA
    ffd2885 View commit details

Commits on Jul 12, 2023

  1. Copy the full SHA
    d04639b View commit details
Showing with 95 additions and 7 deletions.
  1. +3 −1 DeprecationErrorHandler/Configuration.php
  2. +25 −0 DeprecationErrorHandler/Deprecation.php
  3. +44 −6 Tests/DeprecationErrorHandler/ConfigurationTest.php
  4. +23 −0 bin/simple-phpunit.php
4 changes: 3 additions & 1 deletion DeprecationErrorHandler/Configuration.php
Original file line number Diff line number Diff line change
@@ -200,7 +200,9 @@ public function isBaselineDeprecation(Deprecation $deprecation)
return false;
}

if ($deprecation->originatesFromAnObject()) {
if ($deprecation->originatesFromDebugClassLoader()) {
$location = $deprecation->triggeringClass();
} elseif ($deprecation->originatesFromAnObject()) {
$location = $deprecation->originatingClass().'::'.$deprecation->originatingMethod();
} else {
$location = 'procedural code';
25 changes: 25 additions & 0 deletions DeprecationErrorHandler/Deprecation.php
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ class Deprecation
private $originClass;
private $originMethod;
private $triggeringFile;
private $triggeringClass;

/** @var string[] Absolute paths to vendor directories */
private static $vendors;
@@ -61,6 +62,10 @@ class Deprecation
*/
public function __construct($message, array $trace, $file, $languageDeprecation = false)
{
if (isset($trace[2]['class']) && \in_array($trace[2]['class'], [DebugClassLoader::class, LegacyDebugClassLoader::class], true)) {
$this->triggeringClass = $trace[2]['args'][0];
}

if (isset($trace[2]['function']) && 'trigger_deprecation' === $trace[2]['function']) {
$file = $trace[2]['file'];
array_splice($trace, 1, 1);
@@ -158,6 +163,26 @@ private function lineShouldBeSkipped(array $line)
return 'ReflectionMethod' === $class || 0 === strpos($class, 'PHPUnit\\');
}

/**
* @return bool
*/
public function originatesFromDebugClassLoader()
{
return isset($this->triggeringClass);
}

/**
* @return string
*/
public function triggeringClass()
{
if (null === $this->triggeringClass) {
throw new \LogicException('Check with originatesFromDebugClassLoader() before calling this method.');
}

return $this->triggeringClass;
}

/**
* @return bool
*/
50 changes: 44 additions & 6 deletions Tests/DeprecationErrorHandler/ConfigurationTest.php
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Configuration;
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Deprecation;
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\DeprecationGroup;
use Symfony\Component\ErrorHandler\DebugClassLoader;

class ConfigurationTest extends TestCase
{
@@ -356,7 +357,7 @@ public function testBaselineGenerationEmptyFile()
$this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, '')));
$configuration->writeBaseline();
$this->assertEquals($filename, $configuration->getBaselineFile());
$expected_baseline = [
$expected = [
[
'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest',
'message' => 'Test message 1',
@@ -368,7 +369,7 @@ public function testBaselineGenerationEmptyFile()
'count' => 1,
],
];
$this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
$this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
}

public function testBaselineGenerationNoFile()
@@ -383,7 +384,7 @@ public function testBaselineGenerationNoFile()
$this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, '')));
$configuration->writeBaseline();
$this->assertEquals($filename, $configuration->getBaselineFile());
$expected_baseline = [
$expected = [
[
'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest',
'message' => 'Test message 1',
@@ -395,7 +396,7 @@ public function testBaselineGenerationNoFile()
'count' => 2,
],
];
$this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
$this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
}

public function testExistingBaseline()
@@ -447,7 +448,7 @@ public function testExistingBaselineAndGeneration()
$this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 3', $trace, '')));
$configuration->writeBaseline();
$this->assertEquals($filename, $configuration->getBaselineFile());
$expected_baseline = [
$expected = [
[
'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest',
'message' => 'Test message 2',
@@ -459,7 +460,44 @@ public function testExistingBaselineAndGeneration()
'count' => 1,
],
];
$this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
$this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
}

public function testBaselineGenerationWithDeprecationTriggeredByDebugClassLoader()
{
$filename = $this->createFile();
$configuration = Configuration::fromUrlEncodedString('generateBaseline=true&baselineFile='.urlencode($filename));

$trace = debug_backtrace();
$this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Regular deprecation', $trace, '')));

$trace[2] = [
'class' => DebugClassLoader::class,
'function' => 'testBaselineGenerationWithDeprecationTriggeredByDebugClassLoader',
'args' => [self::class]
];

$deprecation = new Deprecation('Deprecation by debug class loader', $trace, '');

$this->assertTrue($deprecation->originatesFromDebugClassLoader());

$this->assertTrue($configuration->isBaselineDeprecation($deprecation));

$configuration->writeBaseline();
$this->assertEquals($filename, $configuration->getBaselineFile());
$expected = [
[
'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest',
'message' => 'Regular deprecation',
'count' => 1,
],
[
'location' => self::class,
'message' => 'Deprecation by debug class loader',
'count' => 1,
],
];
$this->assertEquals(json_encode($expected, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename));
}

public function testBaselineArgumentException()
23 changes: 23 additions & 0 deletions bin/simple-phpunit.php
Original file line number Diff line number Diff line change
@@ -398,6 +398,9 @@ class_exists(\SymfonyExcludeListSimplePhpunit::class, false) && PHPUnit\Util\Bla
}
}

$lastOutput = null;
$lastOutputTime = null;

while ($runningProcs) {
usleep(300000);
$terminatedProcs = [];
@@ -410,6 +413,26 @@ class_exists(\SymfonyExcludeListSimplePhpunit::class, false) && PHPUnit\Util\Bla
}
}

if (!$terminatedProcs && 1 === count($runningProcs)) {
$component = key($runningProcs);

$output = file_get_contents("$component/phpunit.stdout");
$output .= file_get_contents("$component/phpunit.stderr");

if ($lastOutput !== $output) {
$lastOutput = $output;
$lastOutputTime = microtime(true);
} elseif (microtime(true) - $lastOutputTime > 60) {
echo "\033[41mTimeout\033[0m $component\n\n";

if ('\\' === \DIRECTORY_SEPARATOR) {
exec(sprintf('taskkill /F /T /PID %d 2>&1', $procStatus['pid']), $output, $exitCode);
} else {
proc_terminate(current($runningProcs));
}
}
}

foreach ($terminatedProcs as $component => $procStatus) {
foreach (['out', 'err'] as $file) {
$file = "$component/phpunit.std$file";