diff --git a/ClockMock.php b/ClockMock.php index 4c5432f2..bfc7566a 100644 --- a/ClockMock.php +++ b/ClockMock.php @@ -25,6 +25,8 @@ public static function withClockMock($enable = null) } self::$now = is_numeric($enable) ? (float) $enable : ($enable ? microtime(true) : null); + + return null; } public static function time() @@ -50,10 +52,10 @@ public static function sleep($s) public static function usleep($us) { if (null === self::$now) { - return \usleep($us); + \usleep($us); + } else { + self::$now += $us / 1000000; } - - self::$now += $us / 1000000; } public static function microtime($asFloat = false) @@ -104,7 +106,7 @@ function sleep(\$s) function usleep(\$us) { - return \\$self::usleep(\$us); + \\$self::usleep(\$us); } EOPHP diff --git a/DeprecationErrorHandler.php b/DeprecationErrorHandler.php index b81eff52..7cccd8eb 100644 --- a/DeprecationErrorHandler.php +++ b/DeprecationErrorHandler.php @@ -11,6 +11,9 @@ namespace Symfony\Bridge\PhpUnit; +use PHPUnit\Framework\TestResult; +use PHPUnit\Util\ErrorHandler; + /** * Catch deprecation notices and print a summary report at the end of the test suite. * @@ -23,6 +26,7 @@ class DeprecationErrorHandler const MODE_DISABLED = 'disabled'; private static $isRegistered = false; + private static $isAtLeastPhpUnit83; /** * Registers and configures the deprecation handler. @@ -105,11 +109,8 @@ public static function register($mode = 0) 'remaining vendor' => array(), ); $deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix, $inVendors) { - $mode = $getMode(); - if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) || DeprecationErrorHandler::MODE_DISABLED === $mode) { - $ErrorHandler = $UtilPrefix.'ErrorHandler'; - - return $ErrorHandler::handleError($type, $msg, $file, $line, $context); + if ((E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type && (E_WARNING !== $type || false === strpos($msg, '" targeting switch is equivalent to "break'))) || DeprecationErrorHandler::MODE_DISABLED === $mode = $getMode()) { + return \call_user_func(DeprecationErrorHandler::getPhpUnitErrorHandler(), $type, $msg, $file, $line, $context); } $trace = debug_backtrace(); @@ -179,12 +180,14 @@ public static function register($mode = 0) ++$ref; } ++$deprecations[$group.'Count']; + + return null; }; $oldErrorHandler = set_error_handler($deprecationHandler); if (null !== $oldErrorHandler) { restore_error_handler(); - if (array($UtilPrefix.'ErrorHandler', 'handleError') === $oldErrorHandler) { + if ($oldErrorHandler instanceof ErrorHandler || array($UtilPrefix.'ErrorHandler', 'handleError') === $oldErrorHandler) { restore_error_handler(); self::register($mode); } @@ -282,18 +285,16 @@ public static function collectDeprecations($outputFile) { $deprecations = array(); $previousErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, &$previousErrorHandler) { - if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) { + if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type && (E_WARNING !== $type || false === strpos($msg, '" targeting switch is equivalent to "break'))) { if ($previousErrorHandler) { return $previousErrorHandler($type, $msg, $file, $line, $context); } - static $autoload = true; - - $ErrorHandler = class_exists('PHPUnit_Util_ErrorHandler', $autoload) ? 'PHPUnit_Util_ErrorHandler' : 'PHPUnit\Util\ErrorHandler'; - $autoload = false; - return $ErrorHandler::handleError($type, $msg, $file, $line, $context); + return \call_user_func(DeprecationErrorHandler::getPhpUnitErrorHandler(), $type, $msg, $file, $line, $context); } $deprecations[] = array(error_reporting(), $msg, $file); + + return null; }); register_shutdown_function(function () use ($outputFile, &$deprecations) { @@ -301,6 +302,32 @@ public static function collectDeprecations($outputFile) }); } + /** + * @internal + */ + public static function getPhpUnitErrorHandler() + { + if (!isset(self::$isAtLeastPhpUnit83)) { + self::$isAtLeastPhpUnit83 = class_exists('PHPUnit\Util\ErrorHandler') && method_exists('PHPUnit\Util\ErrorHandler', '__invoke'); + } + if (!self::$isAtLeastPhpUnit83) { + return (class_exists('PHPUnit_Util_ErrorHandler', false) ? 'PHPUnit_Util_' : 'PHPUnit\Util\\').'ErrorHandler::handleError'; + } + + foreach (debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) { + if (isset($frame['object']) && $frame['object'] instanceof TestResult) { + return new ErrorHandler( + $frame['object']->getConvertDeprecationsToExceptions(), + $frame['object']->getConvertErrorsToExceptions(), + $frame['object']->getConvertNoticesToExceptions(), + $frame['object']->getConvertWarningsToExceptions() + ); + } + } + + return function () { return false; }; + } + /** * Returns true if STDOUT is defined and supports colorization. * diff --git a/LICENSE b/LICENSE index 15fc1c88..684fbf94 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2018 Fabien Potencier +Copyright (c) 2014-2020 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Legacy/CommandForV5.php b/Legacy/CommandForV5.php index d4b5ea26..ed412848 100644 --- a/Legacy/CommandForV5.php +++ b/Legacy/CommandForV5.php @@ -23,6 +23,35 @@ class CommandForV5 extends \PHPUnit_TextUI_Command */ protected function createRunner() { - return new TestRunnerForV5($this->arguments['loader']); + $this->arguments['listeners'] = isset($this->arguments['listeners']) ? $this->arguments['listeners'] : array(); + + $registeredLocally = false; + + foreach ($this->arguments['listeners'] as $registeredListener) { + if ($registeredListener instanceof SymfonyTestsListenerForV5) { + $registeredListener->globalListenerDisabled(); + $registeredLocally = true; + break; + } + } + + if (isset($this->arguments['configuration'])) { + $configuration = $this->arguments['configuration']; + if (!$configuration instanceof \PHPUnit_Util_Configuration) { + $configuration = \PHPUnit_Util_Configuration::getInstance($this->arguments['configuration']); + } + foreach ($configuration->getListenerConfiguration() as $registeredListener) { + if ('Symfony\Bridge\PhpUnit\SymfonyTestsListener' === ltrim($registeredListener['class'], '\\')) { + $registeredLocally = true; + break; + } + } + } + + if (!$registeredLocally) { + $this->arguments['listeners'][] = new SymfonyTestsListenerForV5(); + } + + return parent::createRunner(); } } diff --git a/Legacy/CommandForV6.php b/Legacy/CommandForV6.php index fc717ef4..93e1ad97 100644 --- a/Legacy/CommandForV6.php +++ b/Legacy/CommandForV6.php @@ -13,7 +13,8 @@ use PHPUnit\TextUI\Command as BaseCommand; use PHPUnit\TextUI\TestRunner as BaseRunner; -use Symfony\Bridge\PhpUnit\TextUI\TestRunner; +use PHPUnit\Util\Configuration; +use Symfony\Bridge\PhpUnit\SymfonyTestsListener; /** * {@inheritdoc} @@ -27,6 +28,35 @@ class CommandForV6 extends BaseCommand */ protected function createRunner(): BaseRunner { - return new TestRunner($this->arguments['loader']); + $this->arguments['listeners'] = isset($this->arguments['listeners']) ? $this->arguments['listeners'] : []; + + $registeredLocally = false; + + foreach ($this->arguments['listeners'] as $registeredListener) { + if ($registeredListener instanceof SymfonyTestsListener) { + $registeredListener->globalListenerDisabled(); + $registeredLocally = true; + break; + } + } + + if (isset($this->arguments['configuration'])) { + $configuration = $this->arguments['configuration']; + if (!$configuration instanceof Configuration) { + $configuration = Configuration::getInstance($this->arguments['configuration']); + } + foreach ($configuration->getListenerConfiguration() as $registeredListener) { + if ('Symfony\Bridge\PhpUnit\SymfonyTestsListener' === ltrim($registeredListener['class'], '\\')) { + $registeredLocally = true; + break; + } + } + } + + if (!$registeredLocally) { + $this->arguments['listeners'][] = new SymfonyTestsListener(); + } + + return parent::createRunner(); } } diff --git a/Legacy/CoverageListenerTrait.php b/Legacy/CoverageListenerTrait.php index 8e9bdbe9..47486dfb 100644 --- a/Legacy/CoverageListenerTrait.php +++ b/Legacy/CoverageListenerTrait.php @@ -76,7 +76,7 @@ public function startTest($test) $cache = $r->getValue(); $cache = array_replace_recursive($cache, array( \get_class($test) => array( - 'covers' => array($sutFqcn), + 'covers' => \is_array($sutFqcn) ? $sutFqcn : array($sutFqcn), ), )); $r->setValue($testClass, $cache); @@ -95,11 +95,7 @@ private function findSutFqcn($test) $sutFqcn = str_replace('\\Tests\\', '\\', $class); $sutFqcn = preg_replace('{Test$}', '', $sutFqcn); - if (!class_exists($sutFqcn)) { - return; - } - - return $sutFqcn; + return class_exists($sutFqcn) ? $sutFqcn : null; } public function __destruct() diff --git a/Legacy/SymfonyTestsListenerTrait.php b/Legacy/SymfonyTestsListenerTrait.php index 6333c4fd..54c15b67 100644 --- a/Legacy/SymfonyTestsListenerTrait.php +++ b/Legacy/SymfonyTestsListenerTrait.php @@ -37,7 +37,6 @@ class SymfonyTestsListenerTrait private $gatheredDeprecations = array(); private $previousErrorHandler; private $testsWithWarnings; - private $reportUselessTests; private $error; private $runsInSeparateProcess = false; @@ -83,6 +82,16 @@ public function __construct(array $mockedNamespaces = array()) } } + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + public function __destruct() { if (0 < $this->state) { @@ -188,10 +197,6 @@ public function addSkippedTest($test, \Exception $e, $time) public function startTest($test) { if (-2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) { - if (null !== $test->getTestResultObject()) { - $this->reportUselessTests = $test->getTestResultObject()->isStrictAboutTestsThatDoNotTestAnything(); - } - // This event is triggered before the test is re-run in isolation if ($this->willBeIsolated($test)) { $this->runsInSeparateProcess = tempnam(sys_get_temp_dir(), 'deprec'); @@ -257,11 +262,6 @@ public function endTest($test, $time) $classGroups = $Test::getGroups($className); $groups = $Test::getGroups($className, $test->getName(false)); - if (null !== $this->reportUselessTests) { - $test->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything($this->reportUselessTests); - $this->reportUselessTests = null; - } - if ($errored = null !== $this->error) { $test->getTestResultObject()->addError($test, $this->error, 0); $this->error = null; @@ -274,7 +274,8 @@ public function endTest($test, $time) foreach ($deprecations ? unserialize($deprecations) : array() as $deprecation) { $error = serialize(array('deprecation' => $deprecation[1], 'class' => $className, 'method' => $test->getName(false), 'triggering_file' => isset($deprecation[2]) ? $deprecation[2] : null)); if ($deprecation[0]) { - @trigger_error($error, E_USER_DEPRECATED); + // unsilenced on purpose + trigger_error($error, E_USER_DEPRECATED); } else { @trigger_error($error, E_USER_DEPRECATED); } @@ -346,6 +347,8 @@ public function handleError($type, $msg, $file, $line, $context = array()) $msg = 'Unsilenced deprecation: '.$msg; } $this->gatheredDeprecations[] = $msg; + + return null; } /** diff --git a/Legacy/TestRunnerForV5.php b/Legacy/TestRunnerForV5.php deleted file mode 100644 index 7897861c..00000000 --- a/Legacy/TestRunnerForV5.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PhpUnit\Legacy; - -/** - * {@inheritdoc} - * - * @internal - */ -class TestRunnerForV5 extends \PHPUnit_TextUI_TestRunner -{ - /** - * {@inheritdoc} - */ - protected function handleConfiguration(array &$arguments) - { - $listener = new SymfonyTestsListenerForV5(); - - $result = parent::handleConfiguration($arguments); - - $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); - - $registeredLocally = false; - - foreach ($arguments['listeners'] as $registeredListener) { - if ($registeredListener instanceof SymfonyTestsListenerForV5) { - $registeredListener->globalListenerDisabled(); - $registeredLocally = true; - break; - } - } - - if (!$registeredLocally) { - $arguments['listeners'][] = $listener; - } - - return $result; - } -} diff --git a/Legacy/TestRunnerForV6.php b/Legacy/TestRunnerForV6.php deleted file mode 100644 index 6da7c654..00000000 --- a/Legacy/TestRunnerForV6.php +++ /dev/null @@ -1,49 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PhpUnit\Legacy; - -use PHPUnit\TextUI\TestRunner as BaseRunner; -use Symfony\Bridge\PhpUnit\SymfonyTestsListener; - -/** - * {@inheritdoc} - * - * @internal - */ -class TestRunnerForV6 extends BaseRunner -{ - /** - * {@inheritdoc} - */ - protected function handleConfiguration(array &$arguments) - { - $listener = new SymfonyTestsListener(); - - parent::handleConfiguration($arguments); - - $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); - - $registeredLocally = false; - - foreach ($arguments['listeners'] as $registeredListener) { - if ($registeredListener instanceof SymfonyTestsListener) { - $registeredListener->globalListenerDisabled(); - $registeredLocally = true; - break; - } - } - - if (!$registeredLocally) { - $arguments['listeners'][] = $listener; - } - } -} diff --git a/Legacy/TestRunnerForV7.php b/Legacy/TestRunnerForV7.php deleted file mode 100644 index a175fb65..00000000 --- a/Legacy/TestRunnerForV7.php +++ /dev/null @@ -1,49 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PhpUnit\Legacy; - -use PHPUnit\TextUI\TestRunner as BaseRunner; -use Symfony\Bridge\PhpUnit\SymfonyTestsListener; - -/** - * {@inheritdoc} - * - * @internal - */ -class TestRunnerForV7 extends BaseRunner -{ - /** - * {@inheritdoc} - */ - protected function handleConfiguration(array &$arguments): void - { - $listener = new SymfonyTestsListener(); - - parent::handleConfiguration($arguments); - - $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); - - $registeredLocally = false; - - foreach ($arguments['listeners'] as $registeredListener) { - if ($registeredListener instanceof SymfonyTestsListener) { - $registeredListener->globalListenerDisabled(); - $registeredLocally = true; - break; - } - } - - if (!$registeredLocally) { - $arguments['listeners'][] = $listener; - } - } -} diff --git a/Tests/CoverageListenerTest.php b/Tests/CoverageListenerTest.php index 6674feb9..d69aee70 100644 --- a/Tests/CoverageListenerTest.php +++ b/Tests/CoverageListenerTest.php @@ -33,14 +33,14 @@ public function test() exec("$php $phpunit -c $dir/phpunit-without-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output); $output = implode("\n", $output); - $this->assertContains('FooCov', $output); + $this->assertStringContainsString('FooCov', $output); exec("$php $phpunit -c $dir/phpunit-with-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output); $output = implode("\n", $output); - $this->assertNotContains('FooCov', $output); - $this->assertContains("SutNotFoundTest::test\nCould not find the tested class.", $output); - $this->assertNotContains("CoversTest::test\nCould not find the tested class.", $output); - $this->assertNotContains("CoversDefaultClassTest::test\nCould not find the tested class.", $output); - $this->assertNotContains("CoversNothingTest::test\nCould not find the tested class.", $output); + $this->assertStringNotContainsString('FooCov', $output); + $this->assertStringContainsString("SutNotFoundTest::test\nCould not find the tested class.", $output); + $this->assertStringNotContainsString("CoversTest::test\nCould not find the tested class.", $output); + $this->assertStringNotContainsString("CoversDefaultClassTest::test\nCould not find the tested class.", $output); + $this->assertStringNotContainsString("CoversNothingTest::test\nCould not find the tested class.", $output); } } diff --git a/Tests/ExpectedDeprecationAnnotationTest.php b/Tests/ExpectedDeprecationAnnotationTest.php new file mode 100644 index 00000000..259c9916 --- /dev/null +++ b/Tests/ExpectedDeprecationAnnotationTest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Tests; + +use PHPUnit\Framework\TestCase; + +final class ExpectedDeprecationAnnotationTest extends TestCase +{ + /** + * Do not remove this test in the next major versions. + * + * @group legacy + * + * @expectedDeprecation foo + */ + public function testOne() + { + @trigger_error('foo', E_USER_DEPRECATED); + } + + /** + * Do not remove this test in the next major versions. + * + * @group legacy + * + * @expectedDeprecation foo + * @expectedDeprecation bar + */ + public function testMany() + { + @trigger_error('foo', E_USER_DEPRECATED); + @trigger_error('bar', E_USER_DEPRECATED); + } +} diff --git a/Tests/ProcessIsolationTest.php b/Tests/ProcessIsolationTest.php index ec8f124a..b8125dc5 100644 --- a/Tests/ProcessIsolationTest.php +++ b/Tests/ProcessIsolationTest.php @@ -25,12 +25,8 @@ public function testIsolation() public function testCallingOtherErrorHandler() { $class = class_exists('PHPUnit\Framework\Exception') ? 'PHPUnit\Framework\Exception' : 'PHPUnit_Framework_Exception'; - if (method_exists($this, 'expectException')) { - $this->expectException($class); - $this->expectExceptionMessage('Test that PHPUnit\'s error handler fires.'); - } else { - $this->setExpectedException($class, 'Test that PHPUnit\'s error handler fires.'); - } + $this->expectException($class); + $this->expectExceptionMessage('Test that PHPUnit\'s error handler fires.'); trigger_error('Test that PHPUnit\'s error handler fires.', E_USER_WARNING); } diff --git a/TextUI/TestRunner.php b/TextUI/TestRunner.php deleted file mode 100644 index cda59209..00000000 --- a/TextUI/TestRunner.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\PhpUnit\TextUI; - -if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { - class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV5', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); -} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) { - class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV6', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); -} else { - class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV7', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); -} - -if (false) { - class TestRunner - { - } -} diff --git a/bin/simple-phpunit b/bin/simple-phpunit index af60eb0f..11a40d55 100755 --- a/bin/simple-phpunit +++ b/bin/simple-phpunit @@ -11,10 +11,18 @@ */ // Please update when phpunit needs to be reinstalled with fresh deps: -// Cache-Id-Version: 2018-11-20 15:30 UTC +// Cache-Id: 2019-09-19 17:00 UTC error_reporting(-1); +$passthruOrFail = function ($command) { + passthru($command, $status); + + if ($status) { + exit($status); + } +}; + if (PHP_VERSION_ID >= 70200) { // PHPUnit 6 is required for PHP 7.2+ $PHPUNIT_VERSION = getenv('SYMFONY_PHPUNIT_VERSION') ?: '6.5'; @@ -26,10 +34,7 @@ if (PHP_VERSION_ID >= 70200) { $PHPUNIT_VERSION = '4.8'; } -if ('composer.json' !== $COMPOSER_JSON = getenv('COMPOSER') ?: 'composer.json') { - putenv('COMPOSER=composer.json'); - $_SERVER['COMPOSER'] = $_ENV['COMPOSER'] = 'composer.json'; -} +$COMPOSER_JSON = getenv('COMPOSER') ?: 'composer.json'; $root = __DIR__; while (!file_exists($root.'/'.$COMPOSER_JSON) || file_exists($root.'/DeprecationErrorHandler.php')) { @@ -47,8 +52,23 @@ if ('phpdbg' === PHP_SAPI) { $PHP .= ' -qrr'; } -$COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar 2> /dev/null`)) - ? $PHP.' '.escapeshellarg($COMPOSER) +$defaultEnvs = array( + 'COMPOSER' => 'composer.json', + 'COMPOSER_VENDOR_DIR' => 'vendor', + 'COMPOSER_BIN_DIR' => 'bin', +); + +foreach ($defaultEnvs as $envName => $envValue) { + if ($envValue !== getenv($envName)) { + putenv("$envName=$envValue"); + $_SERVER[$envName] = $_ENV[$envName] = $envValue; + } +} + +$COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') + || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar 2> /dev/null`)) + || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer`) : `which composer 2> /dev/null`)) + ? (file_get_contents($COMPOSER, false, null, 0, 18) === '#!/usr/bin/env php' ? $PHP : '').' '.escapeshellarg($COMPOSER) // detect shell wrappers by looking at the shebang : 'composer'; if (false === $SYMFONY_PHPUNIT_REMOVE = getenv('SYMFONY_PHPUNIT_REMOVE')) { @@ -61,29 +81,35 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ @mkdir($PHPUNIT_DIR, 0777, true); chdir($PHPUNIT_DIR); if (file_exists("phpunit-$PHPUNIT_VERSION")) { - passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? '(del /S /F /Q %s & rmdir %1$s) >nul': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION")); + passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? 'rmdir /S /Q %s > NUL': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION.old")); + rename("phpunit-$PHPUNIT_VERSION", "phpunit-$PHPUNIT_VERSION.old"); + passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? 'rmdir /S /Q %s': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION.old")); } - passthru("$COMPOSER create-project --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); + $passthruOrFail("$COMPOSER create-project --no-install --prefer-dist --no-scripts --no-plugins --no-progress --ansi phpunit/phpunit phpunit-$PHPUNIT_VERSION \"$PHPUNIT_VERSION.*\""); + @copy("phpunit-$PHPUNIT_VERSION/phpunit.xsd", 'phpunit.xsd'); chdir("phpunit-$PHPUNIT_VERSION"); if ($SYMFONY_PHPUNIT_REMOVE) { - passthru("$COMPOSER remove --no-update ".$SYMFONY_PHPUNIT_REMOVE); + $passthruOrFail("$COMPOSER remove --no-update ".$SYMFONY_PHPUNIT_REMOVE); } if (5.1 <= $PHPUNIT_VERSION && $PHPUNIT_VERSION < 5.4) { - passthru("$COMPOSER require --no-update phpunit/phpunit-mock-objects \"~3.1.0\""); + $passthruOrFail("$COMPOSER require --no-update phpunit/phpunit-mock-objects \"~3.1.0\""); } + + $passthruOrFail("$COMPOSER config --unset platform.php"); if (file_exists($path = $root.'/vendor/symfony/phpunit-bridge')) { - passthru("$COMPOSER require --no-update symfony/phpunit-bridge \"*@dev\""); - passthru("$COMPOSER config repositories.phpunit-bridge path ".escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $path))); + $passthruOrFail("$COMPOSER require --no-update symfony/phpunit-bridge \"*@dev\""); + $passthruOrFail("$COMPOSER config repositories.phpunit-bridge path ".escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $path))); if ('\\' === DIRECTORY_SEPARATOR) { file_put_contents('composer.json', preg_replace('/^( {8})"phpunit-bridge": \{$/m', "$0\n$1 ".'"options": {"symlink": false},', file_get_contents('composer.json'))); } } else { - passthru("$COMPOSER require --no-update symfony/phpunit-bridge \"*\""); + $passthruOrFail("$COMPOSER require --no-update symfony/phpunit-bridge \"*\""); } $prevRoot = getenv('COMPOSER_ROOT_VERSION'); putenv("COMPOSER_ROOT_VERSION=$PHPUNIT_VERSION.99"); + $q = '\\' === DIRECTORY_SEPARATOR ? '"' : ''; // --no-suggest is not in the list to keep compat with composer 1.0, which is shipped with Ubuntu 16.04LTS - $exit = proc_close(proc_open("$COMPOSER install --no-dev --prefer-dist --no-progress --ansi", array(), $p, getcwd(), null, array('bypass_shell' => true))); + $exit = proc_close(proc_open("$q$COMPOSER install --no-dev --prefer-dist --no-progress --ansi$q", array(), $p, getcwd())); putenv('COMPOSER_ROOT_VERSION'.(false !== $prevRoot ? '='.$prevRoot : '')); if ($exit) { exit($exit); @@ -118,6 +144,14 @@ EOPHP global $argv, $argc; $argv = isset($_SERVER['argv']) ? $_SERVER['argv'] : array(); $argc = isset($_SERVER['argc']) ? $_SERVER['argc'] : 0; + +if ($PHPUNIT_VERSION < 8.0) { + $argv = array_filter($argv, function ($v) use (&$argc) { if ('--do-not-cache-result' !== $v) return true; --$argc; return false; }); +} elseif (filter_var(getenv('SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE'), FILTER_VALIDATE_BOOLEAN)) { + $argv[] = '--do-not-cache-result'; + ++$argc; +} + $components = array(); $cmd = array_map('escapeshellarg', $argv); $exit = 0; diff --git a/composer.json b/composer.json index 24a48b60..25dcb0cd 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,7 @@ "php": ">=5.3.3" }, "suggest": { - "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader", - "ext-zip": "Zip support is required when using bin/simple-phpunit" + "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"