init without trunk

This commit is contained in:
Kevin Adametz 2020-07-09 12:49:32 +02:00
parent ed24ac4994
commit bb809e7233
14652 changed files with 177862 additions and 94817 deletions

View file

@ -0,0 +1,3 @@
vendor/
composer.lock
phpunit.xml

View file

@ -0,0 +1,23 @@
CHANGELOG
=========
3.4.0
-----
* added a `CoverageListener` to enhance the code coverage report
* all deprecations but those from tests marked with `@group legacy` are always
displayed when not in `weak` mode
3.3.0
-----
* using the `testLegacy` prefix in method names to mark a test as legacy is
deprecated, use the `@group legacy` notation instead
* using the `Legacy` prefix in class names to mark a test as legacy is deprecated,
use the `@group legacy` notation instead
3.1.0
-----
* passing a numerically indexed array to the constructor of the `SymfonyTestsListenerTrait`
is deprecated, pass an array of namespaces indexed by the mocked feature instead

View file

@ -0,0 +1,116 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PhpUnit;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class ClockMock
{
private static $now;
public static function withClockMock($enable = null)
{
if (null === $enable) {
return null !== self::$now;
}
self::$now = is_numeric($enable) ? (float) $enable : ($enable ? microtime(true) : null);
return null;
}
public static function time()
{
if (null === self::$now) {
return \time();
}
return (int) self::$now;
}
public static function sleep($s)
{
if (null === self::$now) {
return \sleep($s);
}
self::$now += (int) $s;
return 0;
}
public static function usleep($us)
{
if (null === self::$now) {
\usleep($us);
} else {
self::$now += $us / 1000000;
}
}
public static function microtime($asFloat = false)
{
if (null === self::$now) {
return \microtime($asFloat);
}
if ($asFloat) {
return self::$now;
}
return sprintf('%0.6f00 %d', self::$now - (int) self::$now, (int) self::$now);
}
public static function register($class)
{
$self = \get_called_class();
$mockedNs = array(substr($class, 0, strrpos($class, '\\')));
if (0 < strpos($class, '\\Tests\\')) {
$ns = str_replace('\\Tests\\', '\\', $class);
$mockedNs[] = substr($ns, 0, strrpos($ns, '\\'));
} elseif (0 === strpos($class, 'Tests\\')) {
$mockedNs[] = substr($class, 6, strrpos($class, '\\') - 6);
}
foreach ($mockedNs as $ns) {
if (\function_exists($ns.'\time')) {
continue;
}
eval(<<<EOPHP
namespace $ns;
function time()
{
return \\$self::time();
}
function microtime(\$asFloat = false)
{
return \\$self::microtime(\$asFloat);
}
function sleep(\$s)
{
return \\$self::sleep(\$s);
}
function usleep(\$us)
{
\\$self::usleep(\$us);
}
EOPHP
);
}
}
}

View file

@ -0,0 +1,26 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PhpUnit;
if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) {
class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListenerForV5', 'Symfony\Bridge\PhpUnit\CoverageListener');
} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) {
class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListenerForV6', 'Symfony\Bridge\PhpUnit\CoverageListener');
} else {
class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListenerForV7', 'Symfony\Bridge\PhpUnit\CoverageListener');
}
if (false) {
class CoverageListener
{
}
}

View file

@ -0,0 +1,369 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
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.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class DeprecationErrorHandler
{
const MODE_WEAK = 'weak';
const MODE_WEAK_VENDORS = 'weak_vendors';
const MODE_DISABLED = 'disabled';
private static $isRegistered = false;
private static $isAtLeastPhpUnit83;
/**
* Registers and configures the deprecation handler.
*
* The following reporting modes are supported:
* - use "weak" to hide the deprecation report but keep a global count;
* - use "weak_vendors" to act as "weak" but only for vendors;
* - use "/some-regexp/" to stop the test suite whenever a deprecation
* message matches the given regular expression;
* - use a number to define the upper bound of allowed deprecations,
* making the test suite fail whenever more notices are triggered.
*
* @param int|string|false $mode The reporting mode, defaults to not allowing any deprecations
*/
public static function register($mode = 0)
{
if (self::$isRegistered) {
return;
}
$UtilPrefix = class_exists('PHPUnit_Util_ErrorHandler') ? 'PHPUnit_Util_' : 'PHPUnit\Util\\';
$getMode = function () use ($mode) {
static $memoizedMode = false;
if (false !== $memoizedMode) {
return $memoizedMode;
}
if (false === $mode) {
$mode = getenv('SYMFONY_DEPRECATIONS_HELPER');
}
if (DeprecationErrorHandler::MODE_DISABLED !== $mode
&& DeprecationErrorHandler::MODE_WEAK !== $mode
&& DeprecationErrorHandler::MODE_WEAK_VENDORS !== $mode
&& (!isset($mode[0]) || '/' !== $mode[0])
) {
$mode = preg_match('/^[1-9][0-9]*$/', $mode) ? (int) $mode : 0;
}
return $memoizedMode = $mode;
};
$inVendors = function ($path) {
/** @var string[] absolute paths to vendor directories */
static $vendors;
if (null === $vendors) {
foreach (get_declared_classes() as $class) {
if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$v = \dirname(\dirname($r->getFileName()));
if (file_exists($v.'/composer/installed.json')) {
$vendors[] = $v;
}
}
}
}
$realPath = realpath($path);
if (false === $realPath && '-' !== $path && 'Standard input code' !== $path) {
return true;
}
foreach ($vendors as $vendor) {
if (0 === strpos($realPath, $vendor) && false !== strpbrk(substr($realPath, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) {
return true;
}
}
return false;
};
$deprecations = array(
'unsilencedCount' => 0,
'remainingCount' => 0,
'legacyCount' => 0,
'otherCount' => 0,
'remaining vendorCount' => 0,
'unsilenced' => array(),
'remaining' => array(),
'legacy' => array(),
'other' => array(),
'remaining vendor' => array(),
);
$deprecationHandler = function ($type, $msg, $file, $line, $context = array()) use (&$deprecations, $getMode, $UtilPrefix, $inVendors) {
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();
$group = 'other';
$isVendor = DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $inVendors($file);
$i = \count($trace);
while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) {
// No-op
}
if (isset($trace[$i]['object']) || isset($trace[$i]['class'])) {
if (isset($trace[$i]['class']) && 0 === strpos($trace[$i]['class'], 'Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerFor')) {
$parsedMsg = unserialize($msg);
$msg = $parsedMsg['deprecation'];
$class = $parsedMsg['class'];
$method = $parsedMsg['method'];
// If the deprecation has been triggered via
// \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
// then we need to use the serialized information to determine
// if the error has been triggered from vendor code.
$isVendor = DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && isset($parsedMsg['triggering_file']) && $inVendors($parsedMsg['triggering_file']);
} else {
$class = isset($trace[$i]['object']) ? \get_class($trace[$i]['object']) : $trace[$i]['class'];
$method = $trace[$i]['function'];
}
$Test = $UtilPrefix.'Test';
if (0 !== error_reporting()) {
$group = 'unsilenced';
} elseif (0 === strpos($method, 'testLegacy')
|| 0 === strpos($method, 'provideLegacy')
|| 0 === strpos($method, 'getLegacy')
|| strpos($class, '\Legacy')
|| \in_array('legacy', $Test::getGroups($class, $method), true)
) {
$group = 'legacy';
} elseif ($isVendor) {
$group = 'remaining vendor';
} else {
$group = 'remaining';
}
if (isset($mode[0]) && '/' === $mode[0] && preg_match($mode, $msg)) {
$e = new \Exception($msg);
$r = new \ReflectionProperty($e, 'trace');
$r->setAccessible(true);
$r->setValue($e, \array_slice($trace, 1, $i));
echo "\n".ucfirst($group).' deprecation triggered by '.$class.'::'.$method.':';
echo "\n".$msg;
echo "\nStack trace:";
echo "\n".str_replace(' '.getcwd().\DIRECTORY_SEPARATOR, ' ', $e->getTraceAsString());
echo "\n";
exit(1);
}
if ('legacy' !== $group && DeprecationErrorHandler::MODE_WEAK !== $mode) {
$ref = &$deprecations[$group][$msg]['count'];
++$ref;
$ref = &$deprecations[$group][$msg][$class.'::'.$method];
++$ref;
}
} elseif (DeprecationErrorHandler::MODE_WEAK !== $mode) {
$ref = &$deprecations[$group][$msg]['count'];
++$ref;
}
++$deprecations[$group.'Count'];
return null;
};
$oldErrorHandler = set_error_handler($deprecationHandler);
if (null !== $oldErrorHandler) {
restore_error_handler();
if ($oldErrorHandler instanceof ErrorHandler || array($UtilPrefix.'ErrorHandler', 'handleError') === $oldErrorHandler) {
restore_error_handler();
self::register($mode);
}
} else {
self::$isRegistered = true;
if (self::hasColorSupport()) {
$colorize = function ($str, $red) {
$color = $red ? '41;37' : '43;30';
return "\x1B[{$color}m{$str}\x1B[0m";
};
} else {
$colorize = function ($str) { return $str; };
}
register_shutdown_function(function () use ($getMode, &$deprecations, $deprecationHandler, $colorize) {
$mode = $getMode();
if (isset($mode[0]) && '/' === $mode[0]) {
return;
}
$currErrorHandler = set_error_handler('var_dump');
restore_error_handler();
if (DeprecationErrorHandler::MODE_WEAK === $mode) {
$colorize = function ($str) { return $str; };
}
if ($currErrorHandler !== $deprecationHandler) {
echo "\n", $colorize('THE ERROR HANDLER HAS CHANGED!', true), "\n";
}
$cmp = function ($a, $b) {
return $b['count'] - $a['count'];
};
$groups = array('unsilenced', 'remaining');
if (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode) {
$groups[] = 'remaining vendor';
}
array_push($groups, 'legacy', 'other');
$displayDeprecations = function ($deprecations) use ($colorize, $cmp, $groups) {
foreach ($groups as $group) {
if ($deprecations[$group.'Count']) {
echo "\n", $colorize(
sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']),
'legacy' !== $group && 'remaining vendor' !== $group
), "\n";
uasort($deprecations[$group], $cmp);
foreach ($deprecations[$group] as $msg => $notices) {
echo "\n ", $notices['count'], 'x: ', $msg, "\n";
arsort($notices);
foreach ($notices as $method => $count) {
if ('count' !== $method) {
echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n";
}
}
}
}
}
if (!empty($notices)) {
echo "\n";
}
};
$displayDeprecations($deprecations);
// store failing status
$isFailing = DeprecationErrorHandler::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount'];
// reset deprecations array
foreach ($deprecations as $group => $arrayOrInt) {
$deprecations[$group] = \is_int($arrayOrInt) ? 0 : array();
}
register_shutdown_function(function () use (&$deprecations, $isFailing, $displayDeprecations, $mode) {
foreach ($deprecations as $group => $arrayOrInt) {
if (0 < (\is_int($arrayOrInt) ? $arrayOrInt : \count($arrayOrInt))) {
echo "Shutdown-time deprecations:\n";
break;
}
}
$displayDeprecations($deprecations);
if ($isFailing || DeprecationErrorHandler::MODE_WEAK !== $mode && $mode < $deprecations['unsilencedCount'] + $deprecations['remainingCount'] + $deprecations['otherCount']) {
exit(1);
}
});
});
}
}
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 && (E_WARNING !== $type || false === strpos($msg, '" targeting switch is equivalent to "break'))) {
if ($previousErrorHandler) {
return $previousErrorHandler($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) {
file_put_contents($outputFile, serialize($deprecations));
});
}
/**
* @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.
*
* Reference: Composer\XdebugHandler\Process::supportsColor
* https://github.com/composer/xdebug-handler
*
* @return bool
*/
private static function hasColorSupport()
{
if (!\defined('STDOUT')) {
return false;
}
if ('Hyper' === getenv('TERM_PROGRAM')) {
return true;
}
if (\DIRECTORY_SEPARATOR === '\\') {
return (\function_exists('sapi_windows_vt100_support')
&& sapi_windows_vt100_support(STDOUT))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
}
if (\function_exists('stream_isatty')) {
return stream_isatty(STDOUT);
}
if (\function_exists('posix_isatty')) {
return posix_isatty(STDOUT);
}
$stat = fstat(STDOUT);
// Check if formatted mode is S_IFCHR
return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
}
}

View file

@ -0,0 +1,226 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PhpUnit;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class DnsMock
{
private static $hosts = array();
private static $dnsTypes = array(
'A' => DNS_A,
'MX' => DNS_MX,
'NS' => DNS_NS,
'SOA' => DNS_SOA,
'PTR' => DNS_PTR,
'CNAME' => DNS_CNAME,
'AAAA' => DNS_AAAA,
'A6' => DNS_A6,
'SRV' => DNS_SRV,
'NAPTR' => DNS_NAPTR,
'TXT' => DNS_TXT,
'HINFO' => DNS_HINFO,
);
/**
* Configures the mock values for DNS queries.
*
* @param array $hosts Mocked hosts as keys, arrays of DNS records as returned by dns_get_record() as values
*/
public static function withMockedHosts(array $hosts)
{
self::$hosts = $hosts;
}
public static function checkdnsrr($hostname, $type = 'MX')
{
if (!self::$hosts) {
return \checkdnsrr($hostname, $type);
}
if (isset(self::$hosts[$hostname])) {
$type = strtoupper($type);
foreach (self::$hosts[$hostname] as $record) {
if ($record['type'] === $type) {
return true;
}
if ('ANY' === $type && isset(self::$dnsTypes[$record['type']]) && 'HINFO' !== $record['type']) {
return true;
}
}
}
return false;
}
public static function getmxrr($hostname, &$mxhosts, &$weight = null)
{
if (!self::$hosts) {
return \getmxrr($hostname, $mxhosts, $weight);
}
$mxhosts = $weight = array();
if (isset(self::$hosts[$hostname])) {
foreach (self::$hosts[$hostname] as $record) {
if ('MX' === $record['type']) {
$mxhosts[] = $record['host'];
$weight[] = $record['pri'];
}
}
}
return (bool) $mxhosts;
}
public static function gethostbyaddr($ipAddress)
{
if (!self::$hosts) {
return \gethostbyaddr($ipAddress);
}
foreach (self::$hosts as $hostname => $records) {
foreach ($records as $record) {
if ('A' === $record['type'] && $ipAddress === $record['ip']) {
return $hostname;
}
if ('AAAA' === $record['type'] && $ipAddress === $record['ipv6']) {
return $hostname;
}
}
}
return $ipAddress;
}
public static function gethostbyname($hostname)
{
if (!self::$hosts) {
return \gethostbyname($hostname);
}
if (isset(self::$hosts[$hostname])) {
foreach (self::$hosts[$hostname] as $record) {
if ('A' === $record['type']) {
return $record['ip'];
}
}
}
return $hostname;
}
public static function gethostbynamel($hostname)
{
if (!self::$hosts) {
return \gethostbynamel($hostname);
}
$ips = false;
if (isset(self::$hosts[$hostname])) {
$ips = array();
foreach (self::$hosts[$hostname] as $record) {
if ('A' === $record['type']) {
$ips[] = $record['ip'];
}
}
}
return $ips;
}
public static function dns_get_record($hostname, $type = DNS_ANY, &$authns = null, &$addtl = null, $raw = false)
{
if (!self::$hosts) {
return \dns_get_record($hostname, $type, $authns, $addtl, $raw);
}
$records = false;
if (isset(self::$hosts[$hostname])) {
if (DNS_ANY === $type) {
$type = DNS_ALL;
}
$records = array();
foreach (self::$hosts[$hostname] as $record) {
if (isset(self::$dnsTypes[$record['type']]) && (self::$dnsTypes[$record['type']] & $type)) {
$records[] = array_merge(array('host' => $hostname, 'class' => 'IN', 'ttl' => 1, 'type' => $record['type']), $record);
}
}
}
return $records;
}
public static function register($class)
{
$self = \get_called_class();
$mockedNs = array(substr($class, 0, strrpos($class, '\\')));
if (0 < strpos($class, '\\Tests\\')) {
$ns = str_replace('\\Tests\\', '\\', $class);
$mockedNs[] = substr($ns, 0, strrpos($ns, '\\'));
} elseif (0 === strpos($class, 'Tests\\')) {
$mockedNs[] = substr($class, 6, strrpos($class, '\\') - 6);
}
foreach ($mockedNs as $ns) {
if (\function_exists($ns.'\checkdnsrr')) {
continue;
}
eval(<<<EOPHP
namespace $ns;
function checkdnsrr(\$host, \$type = 'MX')
{
return \\$self::checkdnsrr(\$host, \$type);
}
function dns_check_record(\$host, \$type = 'MX')
{
return \\$self::checkdnsrr(\$host, \$type);
}
function getmxrr(\$hostname, &\$mxhosts, &\$weight = null)
{
return \\$self::getmxrr(\$hostname, \$mxhosts, \$weight);
}
function dns_get_mx(\$hostname, &\$mxhosts, &\$weight = null)
{
return \\$self::getmxrr(\$hostname, \$mxhosts, \$weight);
}
function gethostbyaddr(\$ipAddress)
{
return \\$self::gethostbyaddr(\$ipAddress);
}
function gethostbyname(\$hostname)
{
return \\$self::gethostbyname(\$hostname);
}
function gethostbynamel(\$hostname)
{
return \\$self::gethostbynamel(\$hostname);
}
function dns_get_record(\$hostname, \$type = DNS_ANY, &\$authns = null, &\$addtl = null, \$raw = false)
{
return \\$self::dns_get_record(\$hostname, \$type, \$authns, \$addtl, \$raw);
}
EOPHP
);
}
}
}

19
vendor/symfony/phpunit-bridge/LICENSE vendored Normal file
View file

@ -0,0 +1,19 @@
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
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -0,0 +1,57 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 CommandForV5 extends \PHPUnit_TextUI_Command
{
/**
* {@inheritdoc}
*/
protected function createRunner()
{
$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();
}
}

View file

@ -0,0 +1,62 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Command as BaseCommand;
use PHPUnit\TextUI\TestRunner as BaseRunner;
use PHPUnit\Util\Configuration;
use Symfony\Bridge\PhpUnit\SymfonyTestsListener;
/**
* {@inheritdoc}
*
* @internal
*/
class CommandForV6 extends BaseCommand
{
/**
* {@inheritdoc}
*/
protected function createRunner(): BaseRunner
{
$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();
}
}

View file

@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PhpUnit\Legacy;
/**
* CoverageListener adds `@covers <className>` on each test when possible to
* make the code coverage more accurate.
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*
* @internal
*/
class CoverageListenerForV5 extends \PHPUnit_Framework_BaseTestListener
{
private $trait;
public function __construct(callable $sutFqcnResolver = null, $warningOnSutNotFound = false)
{
$this->trait = new CoverageListenerTrait($sutFqcnResolver, $warningOnSutNotFound);
}
public function startTest(\PHPUnit_Framework_Test $test)
{
$this->trait->startTest($test);
}
}

View file

@ -0,0 +1,38 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Framework\BaseTestListener;
use PHPUnit\Framework\Test;
/**
* CoverageListener adds `@covers <className>` on each test when possible to
* make the code coverage more accurate.
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*
* @internal
*/
class CoverageListenerForV6 extends BaseTestListener
{
private $trait;
public function __construct(callable $sutFqcnResolver = null, $warningOnSutNotFound = false)
{
$this->trait = new CoverageListenerTrait($sutFqcnResolver, $warningOnSutNotFound);
}
public function startTest(Test $test)
{
$this->trait->startTest($test);
}
}

View file

@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Framework\Test;
use PHPUnit\Framework\TestListener;
use PHPUnit\Framework\TestListenerDefaultImplementation;
/**
* CoverageListener adds `@covers <className>` on each test when possible to
* make the code coverage more accurate.
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*
* @internal
*/
class CoverageListenerForV7 implements TestListener
{
use TestListenerDefaultImplementation;
private $trait;
public function __construct(callable $sutFqcnResolver = null, $warningOnSutNotFound = false)
{
$this->trait = new CoverageListenerTrait($sutFqcnResolver, $warningOnSutNotFound);
}
public function startTest(Test $test): void
{
$this->trait->startTest($test);
}
}

View file

@ -0,0 +1,113 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Framework\TestCase;
use PHPUnit\Framework\Warning;
/**
* PHP 5.3 compatible trait-like shared implementation.
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*
* @internal
*/
class CoverageListenerTrait
{
private $sutFqcnResolver;
private $warningOnSutNotFound;
private $warnings;
public function __construct(callable $sutFqcnResolver = null, $warningOnSutNotFound = false)
{
$this->sutFqcnResolver = $sutFqcnResolver;
$this->warningOnSutNotFound = $warningOnSutNotFound;
$this->warnings = array();
}
public function startTest($test)
{
if (!$test instanceof TestCase) {
return;
}
$annotations = $test->getAnnotations();
$ignoredAnnotations = array('covers', 'coversDefaultClass', 'coversNothing');
foreach ($ignoredAnnotations as $annotation) {
if (isset($annotations['class'][$annotation]) || isset($annotations['method'][$annotation])) {
return;
}
}
$sutFqcn = $this->findSutFqcn($test);
if (!$sutFqcn) {
if ($this->warningOnSutNotFound) {
$message = 'Could not find the tested class.';
// addWarning does not exist on old PHPUnit version
if (method_exists($test->getTestResultObject(), 'addWarning') && class_exists(Warning::class)) {
$test->getTestResultObject()->addWarning($test, new Warning($message), 0);
} else {
$this->warnings[] = sprintf("%s::%s\n%s", \get_class($test), $test->getName(), $message);
}
}
return;
}
$testClass = \PHPUnit\Util\Test::class;
if (!class_exists($testClass, false)) {
$testClass = \PHPUnit_Util_Test::class;
}
$r = new \ReflectionProperty($testClass, 'annotationCache');
$r->setAccessible(true);
$cache = $r->getValue();
$cache = array_replace_recursive($cache, array(
\get_class($test) => array(
'covers' => \is_array($sutFqcn) ? $sutFqcn : array($sutFqcn),
),
));
$r->setValue($testClass, $cache);
}
private function findSutFqcn($test)
{
if ($this->sutFqcnResolver) {
$resolver = $this->sutFqcnResolver;
return $resolver($test);
}
$class = \get_class($test);
$sutFqcn = str_replace('\\Tests\\', '\\', $class);
$sutFqcn = preg_replace('{Test$}', '', $sutFqcn);
return class_exists($sutFqcn) ? $sutFqcn : null;
}
public function __destruct()
{
if (!$this->warnings) {
return;
}
echo "\n";
foreach ($this->warnings as $key => $warning) {
echo sprintf("%d) %s\n", ++$key, $warning);
}
}
}

View file

@ -0,0 +1,59 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PhpUnit\Legacy;
/**
* Collects and replays skipped tests.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class SymfonyTestsListenerForV5 extends \PHPUnit_Framework_BaseTestListener
{
private $trait;
public function __construct(array $mockedNamespaces = array())
{
$this->trait = new SymfonyTestsListenerTrait($mockedNamespaces);
}
public function globalListenerDisabled()
{
$this->trait->globalListenerDisabled();
}
public function startTestSuite(\PHPUnit_Framework_TestSuite $suite)
{
$this->trait->startTestSuite($suite);
}
public function addSkippedTest(\PHPUnit_Framework_Test $test, \Exception $e, $time)
{
$this->trait->addSkippedTest($test, $e, $time);
}
public function startTest(\PHPUnit_Framework_Test $test)
{
$this->trait->startTest($test);
}
public function addWarning(\PHPUnit_Framework_Test $test, \PHPUnit_Framework_Warning $e, $time)
{
$this->trait->addWarning($test, $e, $time);
}
public function endTest(\PHPUnit_Framework_Test $test, $time)
{
$this->trait->endTest($test, $time);
}
}

View file

@ -0,0 +1,64 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Framework\BaseTestListener;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Framework\Warning;
/**
* Collects and replays skipped tests.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class SymfonyTestsListenerForV6 extends BaseTestListener
{
private $trait;
public function __construct(array $mockedNamespaces = array())
{
$this->trait = new SymfonyTestsListenerTrait($mockedNamespaces);
}
public function globalListenerDisabled()
{
$this->trait->globalListenerDisabled();
}
public function startTestSuite(TestSuite $suite)
{
$this->trait->startTestSuite($suite);
}
public function addSkippedTest(Test $test, \Exception $e, $time)
{
$this->trait->addSkippedTest($test, $e, $time);
}
public function startTest(Test $test)
{
$this->trait->startTest($test);
}
public function addWarning(Test $test, Warning $e, $time)
{
$this->trait->addWarning($test, $e, $time);
}
public function endTest(Test $test, $time)
{
$this->trait->endTest($test, $time);
}
}

View file

@ -0,0 +1,67 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\Framework\Test;
use PHPUnit\Framework\TestListener;
use PHPUnit\Framework\TestListenerDefaultImplementation;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Framework\Warning;
/**
* Collects and replays skipped tests.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class SymfonyTestsListenerForV7 implements TestListener
{
use TestListenerDefaultImplementation;
private $trait;
public function __construct(array $mockedNamespaces = array())
{
$this->trait = new SymfonyTestsListenerTrait($mockedNamespaces);
}
public function globalListenerDisabled()
{
$this->trait->globalListenerDisabled();
}
public function startTestSuite(TestSuite $suite): void
{
$this->trait->startTestSuite($suite);
}
public function addSkippedTest(Test $test, \Throwable $t, float $time): void
{
$this->trait->addSkippedTest($test, $t, $time);
}
public function startTest(Test $test): void
{
$this->trait->startTest($test);
}
public function addWarning(Test $test, Warning $e, float $time): void
{
$this->trait->addWarning($test, $e, $time);
}
public function endTest(Test $test, float $time): void
{
$this->trait->endTest($test, $time);
}
}

View file

@ -0,0 +1,370 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 Doctrine\Common\Annotations\AnnotationRegistry;
use PHPUnit\Framework\AssertionFailedError;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Util\Blacklist;
use Symfony\Bridge\PhpUnit\ClockMock;
use Symfony\Bridge\PhpUnit\DnsMock;
/**
* PHP 5.3 compatible trait-like shared implementation.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class SymfonyTestsListenerTrait
{
private static $globallyEnabled = false;
private $state = -1;
private $skippedFile = false;
private $wasSkipped = array();
private $isSkipped = array();
private $expectedDeprecations = array();
private $gatheredDeprecations = array();
private $previousErrorHandler;
private $testsWithWarnings;
private $error;
private $runsInSeparateProcess = false;
/**
* @param array $mockedNamespaces List of namespaces, indexed by mocked features (time-sensitive or dns-sensitive)
*/
public function __construct(array $mockedNamespaces = array())
{
if (class_exists('PHPUnit_Util_Blacklist')) {
\PHPUnit_Util_Blacklist::$blacklistedClassNames['\Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait'] = 2;
} else {
Blacklist::$blacklistedClassNames['\Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait'] = 2;
}
$warn = false;
foreach ($mockedNamespaces as $type => $namespaces) {
if (!\is_array($namespaces)) {
$namespaces = array($namespaces);
}
if (\is_int($type)) {
// @deprecated BC with v2.8 to v3.0
$type = 'time-sensitive';
$warn = true;
}
if ('time-sensitive' === $type) {
foreach ($namespaces as $ns) {
ClockMock::register($ns.'\DummyClass');
}
}
if ('dns-sensitive' === $type) {
foreach ($namespaces as $ns) {
DnsMock::register($ns.'\DummyClass');
}
}
}
if (self::$globallyEnabled) {
$this->state = -2;
} else {
self::$globallyEnabled = true;
if ($warn) {
echo "Clock-mocked namespaces for SymfonyTestsListener need to be nested in a \"time-sensitive\" key. This will be enforced in Symfony 4.0.\n";
}
}
}
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) {
file_put_contents($this->skippedFile, '<?php return '.var_export($this->isSkipped, true).';');
}
}
public function globalListenerDisabled()
{
self::$globallyEnabled = false;
$this->state = -1;
}
public function startTestSuite($suite)
{
if (class_exists('PHPUnit_Util_Blacklist', false)) {
$Test = 'PHPUnit_Util_Test';
} else {
$Test = 'PHPUnit\Util\Test';
}
$suiteName = $suite->getName();
$this->testsWithWarnings = array();
foreach ($suite->tests() as $test) {
if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
continue;
}
if (null === $Test::getPreserveGlobalStateSettings(\get_class($test), $test->getName(false))) {
$test->setPreserveGlobalState(false);
}
}
if (-1 === $this->state) {
echo "Testing $suiteName\n";
$this->state = 0;
if (!class_exists('Doctrine\Common\Annotations\AnnotationRegistry', false) && class_exists('Doctrine\Common\Annotations\AnnotationRegistry')) {
if (method_exists('Doctrine\Common\Annotations\AnnotationRegistry', 'registerUniqueLoader')) {
AnnotationRegistry::registerUniqueLoader('class_exists');
} else {
AnnotationRegistry::registerLoader('class_exists');
}
}
if ($this->skippedFile = getenv('SYMFONY_PHPUNIT_SKIPPED_TESTS')) {
$this->state = 1;
if (file_exists($this->skippedFile)) {
$this->state = 2;
if (!$this->wasSkipped = require $this->skippedFile) {
echo "All tests already ran successfully.\n";
$suite->setTests(array());
}
}
}
$testSuites = array($suite);
for ($i = 0; isset($testSuites[$i]); ++$i) {
foreach ($testSuites[$i]->tests() as $test) {
if ($test instanceof \PHPUnit_Framework_TestSuite || $test instanceof TestSuite) {
if (!class_exists($test->getName(), false)) {
$testSuites[] = $test;
continue;
}
$groups = $Test::getGroups($test->getName());
if (\in_array('time-sensitive', $groups, true)) {
ClockMock::register($test->getName());
}
if (\in_array('dns-sensitive', $groups, true)) {
DnsMock::register($test->getName());
}
}
}
}
} elseif (2 === $this->state) {
$skipped = array();
foreach ($suite->tests() as $test) {
if (!($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)
|| isset($this->wasSkipped[$suiteName]['*'])
|| isset($this->wasSkipped[$suiteName][$test->getName()])) {
$skipped[] = $test;
}
}
$suite->setTests($skipped);
}
}
public function addSkippedTest($test, \Exception $e, $time)
{
if (0 < $this->state) {
if ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase) {
$class = \get_class($test);
$method = $test->getName();
} else {
$class = $test->getName();
$method = '*';
}
$this->isSkipped[$class][$method] = 1;
}
}
public function startTest($test)
{
if (-2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
// This event is triggered before the test is re-run in isolation
if ($this->willBeIsolated($test)) {
$this->runsInSeparateProcess = tempnam(sys_get_temp_dir(), 'deprec');
putenv('SYMFONY_DEPRECATIONS_SERIALIZE='.$this->runsInSeparateProcess);
}
if (class_exists('PHPUnit_Util_Blacklist', false)) {
$Test = 'PHPUnit_Util_Test';
$AssertionFailedError = 'PHPUnit_Framework_AssertionFailedError';
} else {
$Test = 'PHPUnit\Util\Test';
$AssertionFailedError = 'PHPUnit\Framework\AssertionFailedError';
}
$groups = $Test::getGroups(\get_class($test), $test->getName(false));
if (!$this->runsInSeparateProcess) {
if (\in_array('time-sensitive', $groups, true)) {
ClockMock::register(\get_class($test));
ClockMock::withClockMock(true);
}
if (\in_array('dns-sensitive', $groups, true)) {
DnsMock::register(\get_class($test));
}
}
$annotations = $Test::parseTestMethodAnnotations(\get_class($test), $test->getName(false));
if (isset($annotations['class']['expectedDeprecation'])) {
$test->getTestResultObject()->addError($test, new $AssertionFailedError('`@expectedDeprecation` annotations are not allowed at the class level.'), 0);
}
if (isset($annotations['method']['expectedDeprecation'])) {
if (!\in_array('legacy', $groups, true)) {
$this->error = new $AssertionFailedError('Only tests with the `@group legacy` annotation can have `@expectedDeprecation`.');
}
$test->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything(false);
$this->expectedDeprecations = $annotations['method']['expectedDeprecation'];
$this->previousErrorHandler = set_error_handler(array($this, 'handleError'));
}
}
}
public function addWarning($test, $e, $time)
{
if ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase) {
$this->testsWithWarnings[$test->getName()] = true;
}
}
public function endTest($test, $time)
{
if (class_exists('PHPUnit_Util_Blacklist', false)) {
$Test = 'PHPUnit_Util_Test';
$BaseTestRunner = 'PHPUnit_Runner_BaseTestRunner';
$Warning = 'PHPUnit_Framework_Warning';
} else {
$Test = 'PHPUnit\Util\Test';
$BaseTestRunner = 'PHPUnit\Runner\BaseTestRunner';
$Warning = 'PHPUnit\Framework\Warning';
}
$className = \get_class($test);
$classGroups = $Test::getGroups($className);
$groups = $Test::getGroups($className, $test->getName(false));
if ($errored = null !== $this->error) {
$test->getTestResultObject()->addError($test, $this->error, 0);
$this->error = null;
}
if ($this->runsInSeparateProcess) {
$deprecations = file_get_contents($this->runsInSeparateProcess);
unlink($this->runsInSeparateProcess);
putenv('SYMFONY_DEPRECATIONS_SERIALIZE');
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]) {
// unsilenced on purpose
trigger_error($error, E_USER_DEPRECATED);
} else {
@trigger_error($error, E_USER_DEPRECATED);
}
}
$this->runsInSeparateProcess = false;
}
if ($this->expectedDeprecations) {
if (!\in_array($test->getStatus(), array($BaseTestRunner::STATUS_SKIPPED, $BaseTestRunner::STATUS_INCOMPLETE), true)) {
$test->addToAssertionCount(\count($this->expectedDeprecations));
}
restore_error_handler();
if (!$errored && !\in_array($test->getStatus(), array($BaseTestRunner::STATUS_SKIPPED, $BaseTestRunner::STATUS_INCOMPLETE, $BaseTestRunner::STATUS_FAILURE, $BaseTestRunner::STATUS_ERROR), true)) {
try {
$prefix = "@expectedDeprecation:\n";
$test->assertStringMatchesFormat($prefix.'%A '.implode("\n%A ", $this->expectedDeprecations)."\n%A", $prefix.' '.implode("\n ", $this->gatheredDeprecations)."\n");
} catch (AssertionFailedError $e) {
$test->getTestResultObject()->addFailure($test, $e, $time);
} catch (\PHPUnit_Framework_AssertionFailedError $e) {
$test->getTestResultObject()->addFailure($test, $e, $time);
}
}
$this->expectedDeprecations = $this->gatheredDeprecations = array();
$this->previousErrorHandler = null;
}
if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase)) {
if (\in_array('time-sensitive', $groups, true)) {
ClockMock::withClockMock(false);
}
if (\in_array('dns-sensitive', $groups, true)) {
DnsMock::withMockedHosts(array());
}
}
if (($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase) && 0 === strpos($test->getName(), 'testLegacy') && !isset($this->testsWithWarnings[$test->getName()]) && !\in_array('legacy', $groups, true)) {
$result = $test->getTestResultObject();
if (method_exists($result, 'addWarning')) {
$result->addWarning($test, new $Warning('Using the "testLegacy" prefix to mark tests as legacy is deprecated since version 3.3 and will be removed in 4.0. Use the "@group legacy" notation instead to add the test to the legacy group.'), $time);
}
}
if (($test instanceof \PHPUnit\Framework\TestCase || $test instanceof TestCase) && strpos($className, '\Legacy') && !isset($this->testsWithWarnings[$test->getName()]) && !\in_array('legacy', $classGroups, true)) {
$result = $test->getTestResultObject();
if (method_exists($result, 'addWarning')) {
$result->addWarning($test, new $Warning('Using the "Legacy" prefix to mark all tests of a class as legacy is deprecated since version 3.3 and will be removed in 4.0. Use the "@group legacy" notation instead to add the test to the legacy group.'), $time);
}
}
}
public function handleError($type, $msg, $file, $line, $context = array())
{
if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) {
$h = $this->previousErrorHandler;
return $h ? $h($type, $msg, $file, $line, $context) : false;
}
// If the message is serialized we need to extract the message. This occurs when the error is triggered by
// by the isolated test path in \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest().
$parsedMsg = @unserialize($msg);
if (\is_array($parsedMsg)) {
$msg = $parsedMsg['deprecation'];
}
if (error_reporting()) {
$msg = 'Unsilenced deprecation: '.$msg;
}
$this->gatheredDeprecations[] = $msg;
return null;
}
/**
* @param TestCase $test
*
* @return bool
*/
private function willBeIsolated($test)
{
if ($test->isInIsolation()) {
return false;
}
$r = new \ReflectionProperty($test, 'runTestInSeparateProcess');
$r->setAccessible(true);
return $r->getValue($test);
}
}

13
vendor/symfony/phpunit-bridge/README.md vendored Normal file
View file

@ -0,0 +1,13 @@
PHPUnit Bridge
==============
Provides utilities for PHPUnit, especially user deprecation notices management.
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/phpunit_bridge.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
in the [main Symfony repository](https://github.com/symfony/symfony)

View file

@ -0,0 +1,26 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PhpUnit;
if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) {
class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV5', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener');
} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) {
class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV6', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener');
} else {
class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV7', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener');
}
if (false) {
class SymfonyTestsListener
{
}
}

View file

@ -0,0 +1,60 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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;
use Symfony\Bridge\PhpUnit\ClockMock;
/**
* @author Dominic Tubach <dominic.tubach@to.com>
*
* @covers \Symfony\Bridge\PhpUnit\ClockMock
*/
class ClockMockTest extends TestCase
{
public static function setUpBeforeClass()
{
ClockMock::register(__CLASS__);
}
protected function setUp()
{
ClockMock::withClockMock(1234567890.125);
}
public function testTime()
{
$this->assertSame(1234567890, time());
}
public function testSleep()
{
sleep(2);
$this->assertSame(1234567892, time());
}
public function testMicrotime()
{
$this->assertSame('0.12500000 1234567890', microtime());
}
public function testMicrotimeAsFloat()
{
$this->assertSame(1234567890.125, microtime(true));
}
public function testUsleep()
{
usleep(2);
$this->assertSame(1234567890.125002, microtime(true));
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace Symfony\Bridge\PhpUnit\Tests;
use PHPUnit\Framework\TestCase;
class CoverageListenerTest extends TestCase
{
public function test()
{
if ('\\' === \DIRECTORY_SEPARATOR) {
$this->markTestSkipped('This test cannot be run on Windows.');
}
if (\defined('HHVM_VERSION')) {
$this->markTestSkipped('This test cannot be run on HHVM.');
}
exec('type phpdbg 2> /dev/null', $output, $returnCode);
if (\PHP_VERSION_ID >= 70000 && 0 === $returnCode) {
$php = 'phpdbg -qrr';
} else {
exec('php --ri xdebug -d zend_extension=xdebug.so 2> /dev/null', $output, $returnCode);
if (0 !== $returnCode) {
$this->markTestSkipped('Xdebug is required to run this test.');
}
$php = 'php -d zend_extension=xdebug.so';
}
$dir = __DIR__.'/../Tests/Fixtures/coverage';
$phpunit = $_SERVER['argv'][0];
exec("$php $phpunit -c $dir/phpunit-without-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output);
$output = implode("\n", $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->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);
}
}

View file

@ -0,0 +1,87 @@
--TEST--
Test DeprecationErrorHandler in default mode
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
@trigger_error('root deprecation', E_USER_DEPRECATED);
eval(<<<'EOPHP'
namespace PHPUnit\Util;
class Test
{
public static function getGroups()
{
return array();
}
}
EOPHP
);
class PHPUnit_Util_Test
{
public static function getGroups()
{
return array();
}
}
class FooTestCase
{
public function testLegacyFoo()
{
@trigger_error('silenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
}
public function testNonLegacyBar()
{
@trigger_error('silenced bar deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced bar deprecation', E_USER_DEPRECATED);
}
}
$foo = new FooTestCase();
$foo->testLegacyFoo();
$foo->testNonLegacyBar();
register_shutdown_function(function () {
exit('I get precedence over any exit statements inside the deprecation error handler.');
});
?>
--EXPECTF--
Unsilenced deprecation notices (3)
2x: unsilenced foo deprecation
2x in FooTestCase::testLegacyFoo
1x: unsilenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Remaining deprecation notices (1)
1x: silenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Legacy deprecation notices (1)
Other deprecation notices (1)
1x: root deprecation
I get precedence over any exit statements inside the deprecation error handler.

View file

@ -0,0 +1,3 @@
<?php
@trigger_error('I come from… afar! :D', E_USER_DEPRECATED);

View file

@ -0,0 +1,24 @@
--TEST--
Test DeprecationErrorHandler in weak mode
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=disabled');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
echo (int) set_error_handler('var_dump');
echo (int) class_exists('Symfony\Bridge\PhpUnit\DeprecationErrorHandler', false);
?>
--EXPECTF--
00

View file

@ -0,0 +1,37 @@
<?php
eval(<<<'EOPHP'
namespace PHPUnit\Util;
class Test
{
public static function getGroups()
{
return array();
}
}
EOPHP
);
@trigger_error('root deprecation', E_USER_DEPRECATED);
class FooTestCase
{
public function testLegacyFoo()
{
@trigger_error('silenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
@trigger_error('silenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
}
public function testNonLegacyBar()
{
@trigger_error('silenced bar deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced bar deprecation', E_USER_DEPRECATED);
}
}
$foo = new FooTestCase();
$foo->testLegacyFoo();
$foo->testNonLegacyBar();

View file

@ -0,0 +1,3 @@
<?php
require_once __DIR__.'/composer/autoload_real.php';

View file

@ -0,0 +1,5 @@
<?php
class ComposerAutoloaderInitFake
{
}

View file

@ -0,0 +1 @@
{"just here": "for the detection"}

View file

@ -0,0 +1,4 @@
<?php
$phar = new Phar(__DIR__.DIRECTORY_SEPARATOR.'deprecation.phar', 0, 'deprecation.phar');
$phar->buildFromDirectory(__DIR__.DIRECTORY_SEPARATOR.'deprecation');

View file

@ -0,0 +1,40 @@
--TEST--
Test DeprecationErrorHandler in weak mode
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=/foo/');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
@trigger_error('root deprecation', E_USER_DEPRECATED);
class FooTestCase
{
public function testLegacyFoo()
{
@trigger_error('silenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
}
}
$foo = new FooTestCase();
$foo->testLegacyFoo();
?>
--EXPECTF--
Legacy deprecation triggered by FooTestCase::testLegacyFoo:
silenced foo deprecation
Stack trace:
#%A(%d): FooTestCase->testLegacyFoo()
#%d {main}

View file

@ -0,0 +1,91 @@
--TEST--
Test DeprecationErrorHandler in default mode
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
@trigger_error('root deprecation', E_USER_DEPRECATED);
eval(<<<'EOPHP'
namespace PHPUnit\Util;
class Test
{
public static function getGroups()
{
return array();
}
}
EOPHP
);
class PHPUnit_Util_Test
{
public static function getGroups()
{
return array();
}
}
class FooTestCase
{
public function testLegacyFoo()
{
@trigger_error('silenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
}
public function testNonLegacyBar()
{
@trigger_error('silenced bar deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced bar deprecation', E_USER_DEPRECATED);
}
}
$foo = new FooTestCase();
$foo->testLegacyFoo();
$foo->testNonLegacyBar();
register_shutdown_function(function () {
@trigger_error('root deprecation during shutdown', E_USER_DEPRECATED);
});
?>
--EXPECTF--
Unsilenced deprecation notices (3)
2x: unsilenced foo deprecation
2x in FooTestCase::testLegacyFoo
1x: unsilenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Remaining deprecation notices (1)
1x: silenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Legacy deprecation notices (1)
Other deprecation notices (1)
1x: root deprecation
Shutdown-time deprecations:
Other deprecation notices (1)
1x: root deprecation during shutdown

View file

@ -0,0 +1,39 @@
--TEST--
Test DeprecationErrorHandler in weak mode
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=weak');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
@trigger_error('root deprecation', E_USER_DEPRECATED);
class FooTestCase
{
public function testLegacyFoo()
{
@trigger_error('silenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
}
}
$foo = new FooTestCase();
$foo->testLegacyFoo();
?>
--EXPECTF--
Unsilenced deprecation notices (1)
Legacy deprecation notices (1)
Other deprecation notices (1)

View file

@ -0,0 +1,25 @@
--TEST--
Test DeprecationErrorHandler in weak vendors mode on eval()'d deprecation
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=weak_vendors');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
eval("@trigger_error('who knows where I come from?', E_USER_DEPRECATED);");
?>
--EXPECTF--
Other deprecation notices (1)
1x: who knows where I come from?

View file

@ -0,0 +1,74 @@
--TEST--
Test DeprecationErrorHandler in weak vendors mode on a non vendor file
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=weak_vendors');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
@trigger_error('root deprecation', E_USER_DEPRECATED);
eval(<<<'EOPHP'
namespace PHPUnit\Util;
class Test
{
public static function getGroups()
{
return array();
}
}
EOPHP
);
class FooTestCase
{
public function testLegacyFoo()
{
@trigger_error('silenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED);
}
public function testNonLegacyBar()
{
@trigger_error('silenced bar deprecation', E_USER_DEPRECATED);
trigger_error('unsilenced bar deprecation', E_USER_DEPRECATED);
}
}
$foo = new FooTestCase();
$foo->testLegacyFoo();
$foo->testNonLegacyBar();
?>
--EXPECTF--
Unsilenced deprecation notices (3)
2x: unsilenced foo deprecation
2x in FooTestCase::testLegacyFoo
1x: unsilenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Remaining deprecation notices (1)
1x: silenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Legacy deprecation notices (1)
Other deprecation notices (1)
1x: root deprecation

View file

@ -0,0 +1,27 @@
--TEST--
Test DeprecationErrorHandler in weak vendors mode on eval()'d deprecation
The phar can be regenerated by running php src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/generate_phar.php
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=weak_vendors');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
\Phar::loadPhar(__DIR__.'/deprecation.phar', 'deprecation.phar');
include 'phar://deprecation.phar/deprecation.php';
?>
--EXPECTF--
Other deprecation notices (1)
1x: I come from… afar! :D

View file

@ -0,0 +1,40 @@
--TEST--
Test DeprecationErrorHandler in weak vendors mode on vendor file
--FILE--
<?php
putenv('SYMFONY_DEPRECATIONS_HELPER=weak_vendors');
putenv('ANSICON');
putenv('ConEmuANSI');
putenv('TERM');
$vendor = __DIR__;
while (!file_exists($vendor.'/vendor')) {
$vendor = dirname($vendor);
}
define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
require_once __DIR__.'/../../bootstrap.php';
require __DIR__.'/fake_vendor/autoload.php';
require __DIR__.'/fake_vendor/acme/lib/deprecation_riddled.php';
?>
--EXPECTF--
Unsilenced deprecation notices (3)
2x: unsilenced foo deprecation
2x in FooTestCase::testLegacyFoo
1x: unsilenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Remaining vendor deprecation notices (1)
1x: silenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Legacy deprecation notices (2)
Other deprecation notices (1)
1x: root deprecation

View file

@ -0,0 +1,148 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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;
use Symfony\Bridge\PhpUnit\DnsMock;
class DnsMockTest extends TestCase
{
protected function tearDown()
{
DnsMock::withMockedHosts(array());
}
public function testCheckdnsrr()
{
DnsMock::withMockedHosts(array('example.com' => array(array('type' => 'MX'))));
$this->assertTrue(DnsMock::checkdnsrr('example.com'));
DnsMock::withMockedHosts(array('example.com' => array(array('type' => 'A'))));
$this->assertFalse(DnsMock::checkdnsrr('example.com'));
$this->assertTrue(DnsMock::checkdnsrr('example.com', 'a'));
$this->assertTrue(DnsMock::checkdnsrr('example.com', 'any'));
$this->assertFalse(DnsMock::checkdnsrr('foobar.com', 'ANY'));
}
public function testGetmxrr()
{
DnsMock::withMockedHosts(array(
'example.com' => array(array(
'type' => 'MX',
'host' => 'mx.example.com',
'pri' => 10,
)),
));
$this->assertFalse(DnsMock::getmxrr('foobar.com', $mxhosts, $weight));
$this->assertTrue(DnsMock::getmxrr('example.com', $mxhosts, $weight));
$this->assertSame(array('mx.example.com'), $mxhosts);
$this->assertSame(array(10), $weight);
}
public function testGethostbyaddr()
{
DnsMock::withMockedHosts(array(
'example.com' => array(
array(
'type' => 'A',
'ip' => '1.2.3.4',
),
array(
'type' => 'AAAA',
'ipv6' => '::12',
),
),
));
$this->assertSame('::21', DnsMock::gethostbyaddr('::21'));
$this->assertSame('example.com', DnsMock::gethostbyaddr('::12'));
$this->assertSame('example.com', DnsMock::gethostbyaddr('1.2.3.4'));
}
public function testGethostbyname()
{
DnsMock::withMockedHosts(array(
'example.com' => array(
array(
'type' => 'AAAA',
'ipv6' => '::12',
),
array(
'type' => 'A',
'ip' => '1.2.3.4',
),
),
));
$this->assertSame('foobar.com', DnsMock::gethostbyname('foobar.com'));
$this->assertSame('1.2.3.4', DnsMock::gethostbyname('example.com'));
}
public function testGethostbynamel()
{
DnsMock::withMockedHosts(array(
'example.com' => array(
array(
'type' => 'A',
'ip' => '1.2.3.4',
),
array(
'type' => 'A',
'ip' => '2.3.4.5',
),
),
));
$this->assertFalse(DnsMock::gethostbynamel('foobar.com'));
$this->assertSame(array('1.2.3.4', '2.3.4.5'), DnsMock::gethostbynamel('example.com'));
}
public function testDnsGetRecord()
{
DnsMock::withMockedHosts(array(
'example.com' => array(
array(
'type' => 'A',
'ip' => '1.2.3.4',
),
array(
'type' => 'PTR',
'ip' => '2.3.4.5',
),
),
));
$records = array(
array(
'host' => 'example.com',
'class' => 'IN',
'ttl' => 1,
'type' => 'A',
'ip' => '1.2.3.4',
),
$ptr = array(
'host' => 'example.com',
'class' => 'IN',
'ttl' => 1,
'type' => 'PTR',
'ip' => '2.3.4.5',
),
);
$this->assertFalse(DnsMock::dns_get_record('foobar.com'));
$this->assertSame($records, DnsMock::dns_get_record('example.com'));
$this->assertSame($records, DnsMock::dns_get_record('example.com', DNS_ALL));
$this->assertSame($records, DnsMock::dns_get_record('example.com', DNS_A | DNS_PTR));
$this->assertSame(array($ptr), DnsMock::dns_get_record('example.com', DNS_PTR));
}
}

View file

@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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);
}
}

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="tests/bootstrap.php"
failOnRisky="true"
failOnWarning="true"
>
<testsuites>
<testsuite name="Fixtures/coverage Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
</whitelist>
</filter>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\CoverageListener">
<arguments>
<null/>
<boolean>true</boolean>
</arguments>
</listener>
</listeners>
</phpunit>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="tests/bootstrap.php"
failOnRisky="true"
failOnWarning="true"
>
<testsuites>
<testsuite name="Fixtures/coverage Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
</whitelist>
</filter>
</phpunit>

View file

@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpUnitCoverageTest;
class BarCov
{
private $foo;
public function __construct(FooCov $foo)
{
$this->foo = $foo;
}
public function barZ()
{
$this->foo->fooZ();
return 'bar';
}
}

View file

@ -0,0 +1,20 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpUnitCoverageTest;
class FooCov
{
public function fooZ()
{
return 'foo';
}
}

View file

@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PhpUnitCoverageTest\Tests;
use PHPUnit\Framework\TestCase;
class BarCovTest extends TestCase
{
public function testBarCov()
{
if (!class_exists('PhpUnitCoverageTest\FooCov')) {
$this->markTestSkipped('This test is not part of the main Symfony test suite. It\'s here to test the CoverageListener.');
}
$foo = new \PhpUnitCoverageTest\FooCov();
$bar = new \PhpUnitCoverageTest\BarCov($foo);
$this->assertSame('bar', $bar->barZ());
}
}

View file

@ -0,0 +1,23 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass \DateTime
*/
class CoversDefaultClassTest extends TestCase
{
public function test()
{
$this->assertTrue(true);
}
}

View file

@ -0,0 +1,23 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use PHPUnit\Framework\TestCase;
/**
* @coversNothing
*/
class CoversNothingTest extends TestCase
{
public function test()
{
$this->assertTrue(true);
}
}

View file

@ -0,0 +1,23 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use PHPUnit\Framework\TestCase;
class CoversTest extends TestCase
{
/**
* @covers \DateTime
*/
public function test()
{
$this->assertTrue(true);
}
}

View file

@ -0,0 +1,20 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use PHPUnit\Framework\TestCase;
class SutNotFoundTest extends TestCase
{
public function test()
{
$this->assertTrue(true);
}
}

View file

@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require __DIR__.'/../src/BarCov.php';
require __DIR__.'/../src/FooCov.php';
require __DIR__.'/../../../../Legacy/CoverageListenerTrait.php';
if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) {
require_once __DIR__.'/../../../../Legacy/CoverageListenerForV5.php';
} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) {
require_once __DIR__.'/../../../../Legacy/CoverageListenerForV6.php';
} else {
require_once __DIR__.'/../../../../Legacy/CoverageListenerForV7.php';
}
require __DIR__.'/../../../../CoverageListener.php';

View file

@ -0,0 +1,33 @@
<?php
namespace Symfony\Bridge\PhpUnit\Tests;
use PHPUnit\Framework\TestCase;
/**
* Don't remove this test case, it tests the legacy group.
*
* @group legacy
*
* @runTestsInSeparateProcesses
*/
class ProcessIsolationTest extends TestCase
{
/**
* @expectedDeprecation Test abc
*/
public function testIsolation()
{
@trigger_error('Test abc', E_USER_DEPRECATED);
$this->addToAssertionCount(1);
}
public function testCallingOtherErrorHandler()
{
$class = class_exists('PHPUnit\Framework\Exception') ? 'PHPUnit\Framework\Exception' : 'PHPUnit_Framework_Exception';
$this->expectException($class);
$this->expectExceptionMessage('Test that PHPUnit\'s error handler fires.');
trigger_error('Test that PHPUnit\'s error handler fires.', E_USER_WARNING);
}
}

View file

@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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\CommandForV5', 'Symfony\Bridge\PhpUnit\TextUI\Command');
} else {
class_alias('Symfony\Bridge\PhpUnit\Legacy\CommandForV6', 'Symfony\Bridge\PhpUnit\TextUI\Command');
}
if (false) {
class Command
{
}
}

View file

@ -0,0 +1,250 @@
#!/usr/bin/env php
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
// Please update when phpunit needs to be reinstalled with fresh deps:
// 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';
} elseif (PHP_VERSION_ID >= 50600) {
// PHPUnit 4 does not support PHP 7
$PHPUNIT_VERSION = getenv('SYMFONY_PHPUNIT_VERSION') ?: '5.7';
} else {
// PHPUnit 5.1 requires PHP 5.6+
$PHPUNIT_VERSION = '4.8';
}
$COMPOSER_JSON = getenv('COMPOSER') ?: 'composer.json';
$root = __DIR__;
while (!file_exists($root.'/'.$COMPOSER_JSON) || file_exists($root.'/DeprecationErrorHandler.php')) {
if ($root === dirname($root)) {
break;
}
$root = dirname($root);
}
$oldPwd = getcwd();
$PHPUNIT_DIR = getenv('SYMFONY_PHPUNIT_DIR') ?: ($root.'/vendor/bin/.phpunit');
$PHP = defined('PHP_BINARY') ? PHP_BINARY : 'php';
$PHP = escapeshellarg($PHP);
if ('phpdbg' === PHP_SAPI) {
$PHP .= ' -qrr';
}
$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')) {
$SYMFONY_PHPUNIT_REMOVE = 'phpspec/prophecy symfony/yaml';
}
if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__FILE__)."\n".$SYMFONY_PHPUNIT_REMOVE !== @file_get_contents("$PHPUNIT_DIR/.$PHPUNIT_VERSION.md5")) {
// Build a standalone phpunit without symfony/yaml nor prophecy by default
@mkdir($PHPUNIT_DIR, 0777, true);
chdir($PHPUNIT_DIR);
if (file_exists("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"));
}
$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) {
$passthruOrFail("$COMPOSER remove --no-update ".$SYMFONY_PHPUNIT_REMOVE);
}
if (5.1 <= $PHPUNIT_VERSION && $PHPUNIT_VERSION < 5.4) {
$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')) {
$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 {
$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("$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);
}
file_put_contents('phpunit', <<<'EOPHP'
<?php
define('PHPUNIT_COMPOSER_INSTALL', __DIR__.'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
if (!class_exists('SymfonyBlacklistPhpunit', false)) {
class SymfonyBlacklistPhpunit {}
}
if (class_exists('PHPUnit_Util_Blacklist')) {
PHPUnit_Util_Blacklist::$blacklistedClassNames['SymfonyBlacklistPhpunit'] = 1;
PHPUnit_Util_Blacklist::$blacklistedClassNames['SymfonyBlacklistSimplePhpunit'] = 1;
} else {
PHPUnit\Util\Blacklist::$blacklistedClassNames['SymfonyBlacklistPhpunit'] = 1;
PHPUnit\Util\Blacklist::$blacklistedClassNames['SymfonyBlacklistSimplePhpunit'] = 1;
}
Symfony\Bridge\PhpUnit\TextUI\Command::main();
EOPHP
);
chdir('..');
file_put_contents(".$PHPUNIT_VERSION.md5", md5_file(__FILE__)."\n".$SYMFONY_PHPUNIT_REMOVE);
chdir($oldPwd);
}
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;
if (isset($argv[1]) && 'symfony' === $argv[1] && !file_exists('symfony') && file_exists('src/Symfony')) {
$argv[1] = 'src/Symfony';
}
if (isset($argv[1]) && is_dir($argv[1]) && !file_exists($argv[1].'/phpunit.xml.dist')) {
// Find Symfony components in plain php for Windows portability
$finder = new RecursiveDirectoryIterator($argv[1], FilesystemIterator::KEY_AS_FILENAME | FilesystemIterator::UNIX_PATHS);
$finder = new RecursiveIteratorIterator($finder);
$finder->setMaxDepth(getenv('SYMFONY_PHPUNIT_MAX_DEPTH') ?: 3);
foreach ($finder as $file => $fileInfo) {
if ('phpunit.xml.dist' === $file) {
$components[] = dirname($fileInfo->getPathname());
}
}
if ($components) {
array_shift($cmd);
}
}
$cmd[0] = sprintf('%s %s --colors=always', $PHP, escapeshellarg("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit"));
$cmd = str_replace('%', '%%', implode(' ', $cmd)).' %1$s';
if ('\\' === DIRECTORY_SEPARATOR) {
$cmd = 'cmd /v:on /d /c "('.$cmd.')%2$s"';
} else {
$cmd .= '%2$s';
}
if ($components) {
$skippedTests = isset($_SERVER['SYMFONY_PHPUNIT_SKIPPED_TESTS']) ? $_SERVER['SYMFONY_PHPUNIT_SKIPPED_TESTS'] : false;
$runningProcs = array();
foreach ($components as $component) {
// Run phpunit tests in parallel
if ($skippedTests) {
putenv("SYMFONY_PHPUNIT_SKIPPED_TESTS=$component/$skippedTests");
}
$c = escapeshellarg($component);
if ($proc = proc_open(sprintf($cmd, $c, " > $c/phpunit.stdout 2> $c/phpunit.stderr"), array(), $pipes)) {
$runningProcs[$component] = $proc;
} else {
$exit = 1;
echo "\033[41mKO\033[0m $component\n\n";
}
}
while ($runningProcs) {
usleep(300000);
$terminatedProcs = array();
foreach ($runningProcs as $component => $proc) {
$procStatus = proc_get_status($proc);
if (!$procStatus['running']) {
$terminatedProcs[$component] = $procStatus['exitcode'];
unset($runningProcs[$component]);
proc_close($proc);
}
}
foreach ($terminatedProcs as $component => $procStatus) {
foreach (array('out', 'err') as $file) {
$file = "$component/phpunit.std$file";
readfile($file);
unlink($file);
}
// Fail on any individual component failures but ignore some error codes on Windows when APCu is enabled:
// STATUS_STACK_BUFFER_OVERRUN (-1073740791/0xC0000409)
// STATUS_ACCESS_VIOLATION (-1073741819/0xC0000005)
// STATUS_HEAP_CORRUPTION (-1073740940/0xC0000374)
if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN) || !in_array($procStatus, array(-1073740791, -1073741819, -1073740940)))) {
$exit = $procStatus;
echo "\033[41mKO\033[0m $component\n\n";
} else {
echo "\033[32mOK\033[0m $component\n\n";
}
}
}
} elseif (!isset($argv[1]) || 'install' !== $argv[1] || file_exists('install')) {
if (!class_exists('SymfonyBlacklistSimplePhpunit', false)) {
class SymfonyBlacklistSimplePhpunit {}
}
array_splice($argv, 1, 0, array('--colors=always'));
$_SERVER['argv'] = $argv;
$_SERVER['argc'] = ++$argc;
include "$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit";
}
exit($exit);

View file

@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Doctrine\Common\Annotations\AnnotationRegistry;
use Symfony\Bridge\PhpUnit\DeprecationErrorHandler;
// Detect if we need to serialize deprecations to a file.
if ($file = getenv('SYMFONY_DEPRECATIONS_SERIALIZE')) {
DeprecationErrorHandler::collectDeprecations($file);
return;
}
// Detect if we're loaded by an actual run of phpunit
if (!defined('PHPUNIT_COMPOSER_INSTALL') && !class_exists('PHPUnit_TextUI_Command', false) && !class_exists('PHPUnit\TextUI\Command', false)) {
return;
}
// Enforce a consistent locale
setlocale(LC_ALL, 'C');
if (!class_exists('Doctrine\Common\Annotations\AnnotationRegistry', false) && class_exists('Doctrine\Common\Annotations\AnnotationRegistry')) {
if (method_exists('Doctrine\Common\Annotations\AnnotationRegistry', 'registerUniqueLoader')) {
AnnotationRegistry::registerUniqueLoader('class_exists');
} else {
AnnotationRegistry::registerLoader('class_exists');
}
}
if ('disabled' !== getenv('SYMFONY_DEPRECATIONS_HELPER')) {
DeprecationErrorHandler::register(getenv('SYMFONY_DEPRECATIONS_HELPER'));
}

View file

@ -0,0 +1,49 @@
{
"name": "symfony/phpunit-bridge",
"type": "symfony-bridge",
"description": "Symfony PHPUnit Bridge",
"keywords": [],
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3 EVEN ON LATEST SYMFONY VERSIONS TO ALLOW USING",
"php": "THIS BRIDGE WHEN TESTING LOWEST SYMFONY VERSIONS.",
"php": ">=5.3.3"
},
"suggest": {
"symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
},
"conflict": {
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
},
"autoload": {
"files": [ "bootstrap.php" ],
"psr-4": { "Symfony\\Bridge\\PhpUnit\\": "" },
"exclude-from-classmap": [
"/Tests/"
]
},
"bin": [
"bin/simple-phpunit"
],
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
},
"thanks": {
"name": "phpunit/phpunit",
"url": "https://github.com/sebastianbergmann/phpunit"
}
}
}

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
failOnRisky="true"
failOnWarning="true"
>
<php>
<ini name="error_reporting" value="-1" />
</php>
<testsuites>
<testsuite name="Symfony PHPUnit Bridge Test Suite">
<directory>./Tests/</directory>
<directory suffix=".phpt">./Tests/DeprecationErrorHandler/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./</directory>
<exclude>
<directory>./Tests</directory>
<directory>./vendor</directory>
</exclude>
</whitelist>
</filter>
</phpunit>