<commit_before><?php

/*
 * This file is part of the Symfony package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * 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 <NAME> <<EMAIL>>
 *
 * @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);<commit_msg>bug #36569 [PhpUnitBridge] Mark parent class also covered in CoverageListener (lyrixx)<commit_after><?php

/*
 * This file is part of the Symfony package.
 *
 * (c) <NAME> <<EMAIL>>
 *
 * 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 <NAME> <<EMAIL>>
 *
 * @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);

        $covers = $sutFqcn;
        if (!\is_array($sutFqcn)) {
            $covers = [$sutFqcn];
            while ($parent = get_parent_class($sutFqcn)) {
                $covers[] = $parent;
                $sutFqcn = $parent;
            }
        }

        $cache = $r->getValue();
        $cache = array_replace_recursive($cache, array(
            \get_class($test) => array(
                'covers' => $covers,
            ),
        ));
        $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);
{'fraction_non_alphanumeric': 0.14268927312405574, 'fraction_numerical': 0.0018465670639583682, 'mean_word_length': 2.2557377049180327, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1562154', 'n_tokens_mistral': 1822, 'n_tokens_neox': 1768, 'n_words': 356}