??????????????
PK       ! h*Ks  s    Listener.phpnu &1i        <?php

/**
 * This file is part of Collision.
 *
 * (c) Nuno Maduro <enunomaduro@gmail.com>
 *
 *  For the full copyright and license information, please view the LICENSE
 *  file that was distributed with this source code.
 */

namespace NunoMaduro\Collision\Adapters\Phpunit;

use ReflectionObject;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\Warning;
use Whoops\Exception\Inspector;
use NunoMaduro\Collision\Writer;
use PHPUnit\Framework\TestSuite;
use Symfony\Component\Console\Application;
use PHPUnit\Framework\AssertionFailedError;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use NunoMaduro\Collision\Contracts\Writer as WriterContract;
use NunoMaduro\Collision\Contracts\Adapters\Phpunit\Listener as ListenerContract;

if (class_exists(\PHPUnit\Runner\Version::class) && intval(substr(\PHPUnit\Runner\Version::id(), 0, 1)) >= 7) {

    /**
     * This is an Collision Phpunit Adapter implementation.
     *
     * @author Nuno Maduro <enunomaduro@gmail.com>
     */
    class Listener implements ListenerContract
    {
        /**
         * Holds an instance of the writer.
         *
         * @var \NunoMaduro\Collision\Contracts\Writer
         */
        protected $writer;

        /**
         * Holds the exception found, if any.
         *
         * @var \Throwable|null
         */
        protected $exceptionFound;

        /**
         * Creates a new instance of the class.
         *
         * @param \NunoMaduro\Collision\Contracts\Writer|null $writer
         */
        public function __construct(WriterContract $writer = null)
        {
            $this->writer = $writer ?: $this->buildWriter();
        }

        /**
         * {@inheritdoc}
         */
        public function render(\Throwable $t)
        {
            $inspector = new Inspector($t);

            $this->writer->write($inspector);
        }

        /**
         * {@inheritdoc}
         */
        public function addError(Test $test, \Throwable $t, float $time): void
        {
            if ($this->exceptionFound === null) {
                $this->exceptionFound = $t;
            }
        }

        /**
         * {@inheritdoc}
         */
        public function addWarning(Test $test, Warning $t, float $time): void
        {
        }

        /**
         * {@inheritdoc}
         */
        public function addFailure(Test $test, AssertionFailedError $t, float $time): void
        {
            $this->writer->ignoreFilesIn(['/vendor/'])
            ->showTrace(false);

            if ($this->exceptionFound === null) {
                $this->exceptionFound = $t;
            }
        }

        /**
         * {@inheritdoc}
         */
        public function addIncompleteTest(Test $test, \Throwable $t, float $time): void
        {
        }

        /**
         * {@inheritdoc}
         */
        public function addRiskyTest(Test $test, \Throwable $t, float $time): void
        {
        }

        /**
         * {@inheritdoc}
         */
        public function addSkippedTest(Test $test, \Throwable $t, float $time): void
        {
        }

        /**
         * {@inheritdoc}
         */
        public function startTestSuite(TestSuite $suite): void
        {
        }

        /**
         * {@inheritdoc}
         */
        public function endTestSuite(TestSuite $suite): void
        {
        }

        /**
         * {@inheritdoc}
         */
        public function startTest(Test $test): void
        {
        }

        /**
         * {@inheritdoc}
         */
        public function endTest(Test $test, float $time): void
        {
        }

        /**
         * {@inheritdoc}
         */
        public function __destruct()
        {
            if ($this->exceptionFound !== null) {
                $this->render($this->exceptionFound);
            }
        }

        /**
         * Builds an Writer.
         *
         * @return \NunoMaduro\Collision\Contracts\Writer
         */
        protected function buildWriter(): WriterContract
        {
            $writer = new Writer;

            $application = new Application();
            $reflector = new ReflectionObject($application);
            $method = $reflector->getMethod('configureIO');
            $method->setAccessible(true);
            $method->invoke($application, new ArgvInput, $output = new ConsoleOutput);

            return $writer->setOutput($output);
        }
    }
}
PK       ! y      TestResult.phpnu &1i        <?php

declare(strict_types=1);

namespace NunoMaduro\Collision\Adapters\Phpunit;

use NunoMaduro\Collision\Contracts\Adapters\Phpunit\HasPrintableTestCaseName;
use PHPUnit\Framework\TestCase;
use Throwable;

/**
 * @internal
 */
final class TestResult
{
    public const FAIL       = 'failed';
    public const SKIPPED    = 'skipped';
    public const INCOMPLETE = 'incompleted';
    public const RISKY      = 'risked';
    public const WARN       = 'warnings';
    public const RUNS       = 'pending';
    public const PASS       = 'passed';

    /**
     * @readonly
     *
     * @var string
     */
    public $testCaseName;

    /**
     * @readonly
     *
     * @var string
     */
    public $description;

    /**
     * @readonly
     *
     * @var string
     */
    public $type;

    /**
     * @readonly
     *
     * @var string
     */
    public $icon;

    /**
     * @readonly
     *
     * @var string
     */
    public $color;

    /**
     * @readonly
     *
     * @var Throwable|null
     */
    public $throwable;

    /**
     * @readonly
     *
     * @var string
     */
    public $warning = '';

    /**
     * Test constructor.
     */
    private function __construct(string $testCaseName, string $description, string $type, string $icon, string $color, Throwable $throwable = null)
    {
        $this->testCaseName = $testCaseName;
        $this->description  = $description;
        $this->type         = $type;
        $this->icon         = $icon;
        $this->color        = $color;
        $this->throwable    = $throwable;

        $asWarning = $this->type === TestResult::WARN
             || $this->type === TestResult::RISKY
             || $this->type === TestResult::SKIPPED
             || $this->type === TestResult::INCOMPLETE;

        if ($throwable instanceof Throwable && $asWarning) {
            $this->warning     = trim((string) preg_replace("/\r|\n/", ' ', $throwable->getMessage()));
        }
    }

    /**
     * Creates a new test from the given test case.
     */
    public static function fromTestCase(TestCase $testCase, string $type, Throwable $throwable = null): self
    {
        $testCaseName = State::getPrintableTestCaseName($testCase);

        $description = self::makeDescription($testCase);

        $icon = self::makeIcon($type);

        $color = self::makeColor($type);

        return new self($testCaseName, $description, $type, $icon, $color, $throwable);
    }

    /**
     * Get the test case description.
     */
    public static function makeDescription(TestCase $testCase): string
    {
        $name = $testCase->getName(false);

        if ($testCase instanceof HasPrintableTestCaseName) {
            return $name;
        }

        // First, lets replace underscore by spaces.
        $name = str_replace('_', ' ', $name);

        // Then, replace upper cases by spaces.
        $name = (string) preg_replace('/([A-Z])/', ' $1', $name);

        // Finally, if it starts with `test`, we remove it.
        $name = (string) preg_replace('/^test/', '', $name);

        // Removes spaces
        $name = trim($name);

        // Lower case everything
        $name = mb_strtolower($name);

        // Add the dataset name if it has one
        if ($dataName = $testCase->dataName()) {
            if (is_int($dataName)) {
                $name .= sprintf(' with data set #%d', $dataName);
            } else {
                $name .= sprintf(' with data set "%s"', $dataName);
            }
        }

        return $name;
    }

    /**
     * Get the test case icon.
     */
    public static function makeIcon(string $type): string
    {
        switch ($type) {
            case self::FAIL:
                return '⨯';
            case self::SKIPPED:
                return '-';
            case self::RISKY:
                return '!';
            case self::INCOMPLETE:
                return '…';
            case self::WARN:
                return '!';
            case self::RUNS:
                return '•';
            default:
                return '✓';
        }
    }

    /**
     * Get the test case color.
     */
    public static function makeColor(string $type): string
    {
        switch ($type) {
            case self::FAIL:
                return 'red';
            case self::SKIPPED:
            case self::INCOMPLETE:
            case self::RISKY:
            case self::WARN:
            case self::RUNS:
                return 'yellow';
            default:
                return 'green';
        }
    }
}
PK       ! gn$    	  State.phpnu &1i        <?php

declare(strict_types=1);

namespace NunoMaduro\Collision\Adapters\Phpunit;

use NunoMaduro\Collision\Contracts\Adapters\Phpunit\HasPrintableTestCaseName;
use PHPUnit\Framework\TestCase;

/**
 * @internal
 */
final class State
{
    /**
     * The complete test suite number of tests.
     *
     * @var int|null
     */
    public $suiteTotalTests;

    /**
     * The complete test suite tests.
     *
     * @var array<int, TestResult>
     */
    public $suiteTests = [];

    /**
     * The current test case class.
     *
     * @var string
     */
    public $testCaseName;

    /**
     * The current test case tests.
     *
     * @var array<int, TestResult>
     */
    public $testCaseTests = [];

    /**
     * The current test case tests.
     *
     * @var array<int, TestResult>
     */
    public $toBePrintedCaseTests = [];

    /**
     * Header printed.
     *
     * @var bool
     */
    public $headerPrinted = false;

    /**
     * The state constructor.
     */
    private function __construct(string $testCaseName)
    {
        $this->testCaseName = $testCaseName;
    }

    /**
     * Creates a new State starting from the given test case.
     */
    public static function from(TestCase $test): self
    {
        return new self(self::getPrintableTestCaseName($test));
    }

    /**
     * Adds the given test to the State.
     */
    public function add(TestResult $test): void
    {
        $this->testCaseTests[]        = $test;
        $this->toBePrintedCaseTests[] = $test;

        $this->suiteTests[] = $test;
    }

    /**
     * Gets the test case title.
     */
    public function getTestCaseTitle(): string
    {
        foreach ($this->testCaseTests as $test) {
            if ($test->type === TestResult::FAIL) {
                return 'FAIL';
            }
        }

        foreach ($this->testCaseTests as $test) {
            if ($test->type !== TestResult::PASS) {
                return 'WARN';
            }
        }

        return 'PASS';
    }

    /**
     * Gets the test case title color.
     */
    public function getTestCaseTitleColor(): string
    {
        foreach ($this->testCaseTests as $test) {
            if ($test->type === TestResult::FAIL) {
                return 'red';
            }
        }

        foreach ($this->testCaseTests as $test) {
            if ($test->type !== TestResult::PASS) {
                return 'yellow';
            }
        }

        return 'green';
    }

    /**
     * Returns the number of tests on the current test case.
     */
    public function testCaseTestsCount(): int
    {
        return count($this->testCaseTests);
    }

    /**
     * Returns the number of tests on the complete test suite.
     */
    public function testSuiteTestsCount(): int
    {
        return count($this->suiteTests);
    }

    /**
     * Checks if the given test case is different from the current one.
     */
    public function testCaseHasChanged(TestCase $testCase): bool
    {
        return self::getPrintableTestCaseName($testCase) !== $this->testCaseName;
    }

    /**
     * Moves the a new test case.
     */
    public function moveTo(TestCase $testCase): void
    {
        $this->testCaseName = self::getPrintableTestCaseName($testCase);

        $this->testCaseTests = [];

        $this->headerPrinted = false;
    }

    /**
     * Foreach test in the test case.
     */
    public function eachTestCaseTests(callable $callback): void
    {
        foreach ($this->toBePrintedCaseTests as $test) {
            $callback($test);
        }

        $this->toBePrintedCaseTests = [];
    }

    public function countTestsInTestSuiteBy(string $type): int
    {
        return count(array_filter($this->suiteTests, function (TestResult $testResult) use ($type) {
            return $testResult->type === $type;
        }));
    }

    /**
     * Checks if the given test already contains a result.
     */
    public function existsInTestCase(TestCase $test): bool
    {
        foreach ($this->testCaseTests as $testResult) {
            if (TestResult::makeDescription($test) === $testResult->description) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the printable test case name from the given `TestCase`.
     */
    public static function getPrintableTestCaseName(TestCase $test): string
    {
        return $test instanceof HasPrintableTestCaseName
            ? $test->getPrintableTestCaseName()
            : get_class($test);
    }
}
PK       ! ]	    	  Style.phpnu &1i        <?php

declare(strict_types=1);

namespace NunoMaduro\Collision\Adapters\Phpunit;

use NunoMaduro\Collision\Exceptions\ShouldNotHappen;
use NunoMaduro\Collision\Writer;
use PHPUnit\Framework\AssertionFailedError;
use PHPUnit\Framework\ExceptionWrapper;
use PHPUnit\Framework\ExpectationFailedException;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Throwable;
use Whoops\Exception\Inspector;

/**
 * @internal
 */
final class Style
{
    /**
     * @var ConsoleOutput
     */
    private $output;

    /**
     * Style constructor.
     */
    public function __construct(ConsoleOutputInterface $output)
    {
        if (!$output instanceof ConsoleOutput) {
            throw new ShouldNotHappen();
        }

        $this->output = $output;
    }

    /**
     * Prints the content.
     */
    public function write(string $content): void
    {
        $this->output->write($content);
    }

    /**
     * Prints the content similar too:.
     *
     * ```
     *    PASS  Unit\ExampleTest
     *    ✓ basic test
     * ```
     */
    public function writeCurrentTestCaseSummary(State $state): void
    {
        if ($state->testCaseTestsCount() === 0) {
            return;
        }

        if (!$state->headerPrinted) {
            $this->output->writeln($this->titleLineFrom(
                $state->getTestCaseTitle() === 'FAIL' ? 'white' : 'black',
                $state->getTestCaseTitleColor(),
                $state->getTestCaseTitle(),
                $state->testCaseName
            ));
            $state->headerPrinted = true;
        }

        $state->eachTestCaseTests(function (TestResult $testResult) {
            $this->output->writeln($this->testLineFrom(
                $testResult->color,
                $testResult->icon,
                $testResult->description,
                $testResult->warning
            ));
        });
    }

    /**
     * Prints the content similar too:.
     *
     * ```
     *    PASS  Unit\ExampleTest
     *    ✓ basic test
     * ```
     */
    public function writeErrorsSummary(State $state, bool $onFailure): void
    {
        $errors = array_filter($state->suiteTests, function (TestResult $testResult) {
            return $testResult->type === TestResult::FAIL;
        });

        if (!$onFailure) {
            $this->output->writeln(['', "  \e[2m---\e[22m", '']);
        }

        array_map(function (TestResult $testResult) use ($onFailure) {
            if (!$onFailure) {
                $this->output->write(sprintf(
                    '  <fg=red;options=bold>• %s </>> <fg=red;options=bold>%s</>',
                    $testResult->testCaseName,
                    $testResult->description
                ));
            }

            if (!$testResult->throwable instanceof Throwable) {
                throw new ShouldNotHappen();
            }

            $this->writeError($testResult->throwable);
        }, $errors);
    }

    /**
     * Writes the final recap.
     */
    public function writeRecap(State $state, Timer $timer = null): void
    {
        $types = [TestResult::FAIL, TestResult::WARN, TestResult::RISKY, TestResult::INCOMPLETE, TestResult::SKIPPED, TestResult::PASS];
        foreach ($types as $type) {
            if (($countTests = $state->countTestsInTestSuiteBy($type)) !== 0) {
                $color   = TestResult::makeColor($type);
                $tests[] = "<fg=$color;options=bold>$countTests $type</>";
            }
        }

        $pending = $state->suiteTotalTests - $state->testSuiteTestsCount();
        if ($pending !== 0) {
            $tests[] = "\e[2m$pending pending\e[22m";
        }

        if (!empty($tests)) {
            $this->output->write([
                "\n",
                sprintf(
                    '  <fg=white;options=bold>Tests:  </><fg=default>%s</>',
                    implode(', ', $tests)
                ),
            ]);
        }

        if ($timer !== null) {
            $timeElapsed = number_format($timer->result(), 2, '.', '');
            $this->output->writeln([
                    '',
                    sprintf(
                        '  <fg=white;options=bold>Time:   </><fg=default>%ss</>',
                        $timeElapsed
                    ),
                ]
            );
        }

        $this->output->writeln('');
    }

    /**
     * Displays a warning message.
     */
    public function writeWarning(string $message): void
    {
        $this->output->writeln($this->testLineFrom('yellow', $message, ''));
    }

    /**
     * Displays the error using Collision's writer
     * and terminates with exit code === 1.
     */
    public function writeError(Throwable $throwable): void
    {
        $writer = (new Writer())->setOutput($this->output);

        if ($throwable instanceof AssertionFailedError) {
            $writer->showTitle(false);
            $this->output->write('', true);
        }

        $writer->ignoreFilesIn([
            '/vendor\/pestphp\/pest/',
            '/vendor\/phpspec\/prophecy-phpunit/',
            '/vendor\/phpunit\/phpunit\/src/',
            '/vendor\/mockery\/mockery/',
            '/vendor\/laravel\/dusk/',
            '/vendor\/laravel\/framework\/src\/Illuminate\/Testing/',
            '/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Testing/',
            '/vendor\/symfony\/framework-bundle\/Test/',
            '/vendor\/symfony\/phpunit-bridge/',
            '/vendor\/bin\/.phpunit/',
            '/bin\/.phpunit/',
            '/vendor\/bin\/simple-phpunit/',
            '/bin\/phpunit/',
            '/vendor\/coduo\/php-matcher\/src\/PHPUnit/',
            '/vendor\/sulu\/sulu\/src\/Sulu\/Bundle\/TestBundle\/Testing/',
        ]);

        if ($throwable instanceof ExceptionWrapper && $throwable->getOriginalException() !== null) {
            $throwable = $throwable->getOriginalException();
        }

        $inspector = new Inspector($throwable);

        $writer->write($inspector);

        if ($throwable instanceof ExpectationFailedException && $comparisionFailure = $throwable->getComparisonFailure()) {
            $diff  = $comparisionFailure->getDiff();
            $lines = explode(PHP_EOL, $diff);
            $diff  = '';
            foreach ($lines as $line) {
                if (0 === strpos($line, '-')) {
                    $line = '<fg=red>' . $line . '</>';
                } elseif (0 === strpos($line, '+')) {
                    $line = '<fg=green>' . $line . '</>';
                }

                $diff .= $line . PHP_EOL;
            }

            $diff  = trim((string) preg_replace("/\r|\n/", "\n  ", $diff));

            $this->output->write("  $diff");
        }

        $this->output->writeln('');
    }

    /**
     * Returns the title contents.
     */
    private function titleLineFrom(string $fg, string $bg, string $title, string $testCaseName): string
    {
        return sprintf(
            "\n  <fg=%s;bg=%s;options=bold> %s </><fg=default> %s</>",
            $fg,
            $bg,
            $title,
            $testCaseName
        );
    }

    /**
     * Returns the test contents.
     */
    private function testLineFrom(string $fg, string $icon, string $description, string $warning = null): string
    {
        if (!empty($warning)) {
            $warning = sprintf(
                ' → %s',
                $warning
            );
        }

        return sprintf(
            "  <fg=%s;options=bold>%s</><fg=default> \e[2m%s\e[22m</><fg=yellow>%s</>",
            $fg,
            $icon,
            $description,
            $warning
        );
    }
}
PK       ! J-      ConfigureIO.phpnu &1i        <?php

declare(strict_types=1);

/**
 * This file is part of Collision.
 *
 * (c) Nuno Maduro <enunomaduro@gmail.com>
 *
 *  For the full copyright and license information, please view the LICENSE
 *  file that was distributed with this source code.
 */

namespace NunoMaduro\Collision\Adapters\Phpunit;

use ReflectionObject;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\Output;

/**
 * @internal
 */
final class ConfigureIO
{
    /**
     * Configures both given input and output with
     * options from the enviroment.
     *
     * @throws \ReflectionException
     */
    public static function of(InputInterface $input, Output $output): void
    {
        $application = new Application();
        $reflector   = new ReflectionObject($application);
        $method      = $reflector->getMethod('configureIO');
        $method->setAccessible(true);
        $method->invoke($application, $input, $output);
    }
}
PK       ! 
d  d  	  Timer.phpnu &1i        <?php

declare(strict_types=1);

namespace NunoMaduro\Collision\Adapters\Phpunit;

/**
 * @internal
 */
final class Timer
{
    /**
     * @var float
     */
    private $start;

    /**
     * Timer constructor.
     */
    private function __construct(float $start)
    {
        $this->start = $start;
    }

    /**
     * Starts the timer.
     */
    public static function start(): Timer
    {
        return new self(microtime(true));
    }

    /**
     * Returns the elapsed time in microseconds.
     */
    public function result(): float
    {
        return microtime(true) - $this->start;
    }
}
PK       ! k@?      Printer.phpnu &1i        <?php

declare(strict_types=1);

namespace NunoMaduro\Collision\Adapters\Phpunit;

use NunoMaduro\Collision\Exceptions\ShouldNotHappen;
use PHPUnit\Framework\AssertionFailedError;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Framework\Warning;
use ReflectionObject;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Throwable;

/**
 * @internal
 */
final class Printer implements \PHPUnit\TextUI\ResultPrinter
{
    /**
     * Holds an instance of the style.
     *
     * Style is a class we use to interact with output.
     *
     * @var Style
     */
    private $style;

    /**
     * Holds the duration time of the test suite.
     *
     * @var Timer
     */
    private $timer;

    /**
     * Holds the state of the test
     * suite. The number of tests, etc.
     *
     * @var State
     */
    private $state;

    /**
     * If the test suite has failed.
     *
     * @var bool
     */
    private $failed = false;

    /**
     * Creates a new instance of the listener.
     *
     * @param ConsoleOutput $output
     *
     * @throws \ReflectionException
     */
    public function __construct(\Symfony\Component\Console\Output\ConsoleOutputInterface $output = null, bool $verbose = false, string $colors = 'always')
    {
        $this->timer = Timer::start();

        $decorated = $colors === 'always' || $colors === 'auto';

        $output = $output ?? new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, $decorated);

        ConfigureIO::of(new ArgvInput(), $output);

        $this->style = new Style($output);
        $dummyTest   = new class() extends TestCase {
        };

        $this->state = State::from($dummyTest);
    }

    /**
     * {@inheritdoc}
     */
    public function addError(Test $testCase, Throwable $throwable, float $time): void
    {
        $this->failed = true;

        $testCase = $this->testCaseFromTest($testCase);

        $this->state->add(TestResult::fromTestCase($testCase, TestResult::FAIL, $throwable));
    }

    /**
     * {@inheritdoc}
     */
    public function addWarning(Test $testCase, Warning $warning, float $time): void
    {
        $testCase = $this->testCaseFromTest($testCase);

        $this->state->add(TestResult::fromTestCase($testCase, TestResult::WARN, $warning));
    }

    /**
     * {@inheritdoc}
     */
    public function addFailure(Test $testCase, AssertionFailedError $error, float $time): void
    {
        $this->failed = true;

        $testCase = $this->testCaseFromTest($testCase);

        $reflector = new ReflectionObject($error);

        if ($reflector->hasProperty('message')) {
            $message  = trim((string) preg_replace("/\r|\n/", "\n  ", $error->getMessage()));
            $property = $reflector->getProperty('message');
            $property->setAccessible(true);
            $property->setValue($error, $message);
        }

        $this->state->add(TestResult::fromTestCase($testCase, TestResult::FAIL, $error));
    }

    /**
     * {@inheritdoc}
     */
    public function addIncompleteTest(Test $testCase, Throwable $throwable, float $time): void
    {
        $testCase = $this->testCaseFromTest($testCase);

        $this->state->add(TestResult::fromTestCase($testCase, TestResult::INCOMPLETE, $throwable));
    }

    /**
     * {@inheritdoc}
     */
    public function addRiskyTest(Test $testCase, Throwable $throwable, float $time): void
    {
        $testCase = $this->testCaseFromTest($testCase);

        $this->state->add(TestResult::fromTestCase($testCase, TestResult::RISKY, $throwable));
    }

    /**
     * {@inheritdoc}
     */
    public function addSkippedTest(Test $testCase, Throwable $throwable, float $time): void
    {
        $testCase = $this->testCaseFromTest($testCase);

        $this->state->add(TestResult::fromTestCase($testCase, TestResult::SKIPPED, $throwable));
    }

    /**
     * {@inheritdoc}
     */
    public function startTestSuite(TestSuite $suite): void
    {
        if ($this->state->suiteTotalTests === null) {
            $this->state->suiteTotalTests = $suite->count();
        }
    }

    /**
     * {@inheritdoc}
     */
    public function endTestSuite(TestSuite $suite): void
    {
        // ..
    }

    /**
     * {@inheritdoc}
     */
    public function startTest(Test $testCase): void
    {
        $testCase = $this->testCaseFromTest($testCase);

        // Let's check first if the testCase is over.
        if ($this->state->testCaseHasChanged($testCase)) {
            $this->style->writeCurrentTestCaseSummary($this->state);

            $this->state->moveTo($testCase);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function endTest(Test $testCase, float $time): void
    {
        $testCase = $this->testCaseFromTest($testCase);

        if (!$this->state->existsInTestCase($testCase)) {
            $this->state->add(TestResult::fromTestCase($testCase, TestResult::PASS));
        }

        if ($testCase instanceof TestCase
            && $testCase->getTestResultObject() instanceof \PHPUnit\Framework\TestResult
            && !$testCase->getTestResultObject()->isStrictAboutOutputDuringTests()
            && !$testCase->hasExpectationOnOutput()) {
            $this->style->write($testCase->getActualOutput());
        }
    }

    /**
     * Intentionally left blank as we output things on events of the listener.
     */
    public function write(string $content): void
    {
        // ..
    }

    /**
     * Returns a test case from the given test.
     *
     * Note: This printer is do not work with normal Test classes - only
     * with Test Case classes. Please report an issue if you think
     * this should work any other way.
     */
    private function testCaseFromTest(Test $test): TestCase
    {
        if (!$test instanceof TestCase) {
            throw new ShouldNotHappen();
        }

        return $test;
    }

    /**
     * Intentionally left blank as we output things on events of the listener.
     */
    public function printResult(\PHPUnit\Framework\TestResult $result): void
    {
        if ($result->count() === 0) {
            $this->style->writeWarning('No tests executed!');
        }

        $this->style->writeCurrentTestCaseSummary($this->state);

        if ($this->failed) {
            $onFailure = $this->state->suiteTotalTests !== $this->state->testSuiteTestsCount();
            $this->style->writeErrorsSummary($this->state, $onFailure);
        }

        $this->style->writeRecap($this->state, $this->timer);
    }
}
PK         ! h*Ks  s                  Listener.phpnu &1i        PK         ! y                  TestResult.phpnu &1i        PK         ! gn$    	            #  State.phpnu &1i        PK         ! ]	    	            5  Style.phpnu &1i        PK         ! J-                S  ConfigureIO.phpnu &1i        PK         ! 
d  d  	            	X  Timer.phpnu &1i        PK         ! k@?                Z  Printer.phpnu &1i        PK  