dependencies-upgrade
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: nunomaduro
|
||||
patreon: nunomaduro
|
||||
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L
|
||||
29
vendor/nunomaduro/collision/.php_cs
vendored
29
vendor/nunomaduro/collision/.php_cs
vendored
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->in(__DIR__ . DIRECTORY_SEPARATOR . 'tests')
|
||||
->notPath(__DIR__ . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'laravel')
|
||||
->in(__DIR__ . DIRECTORY_SEPARATOR . 'src')
|
||||
->append(['.php_cs']);
|
||||
|
||||
$rules = [
|
||||
'@Symfony' => true,
|
||||
'phpdoc_no_empty_return' => false,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'yoda_style' => false,
|
||||
'binary_operator_spaces' => [
|
||||
'operators' => [
|
||||
'=>' => 'align',
|
||||
'=' => 'align',
|
||||
],
|
||||
],
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
'not_operator_with_space' => false,
|
||||
];
|
||||
|
||||
$rules['increment_style'] = ['style' => 'post'];
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setUsingCache(true)
|
||||
->setRules($rules)
|
||||
->setFinder($finder);
|
||||
22
vendor/nunomaduro/collision/README.md
vendored
22
vendor/nunomaduro/collision/README.md
vendored
@@ -5,7 +5,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/nunomaduro/collision"><img src="https://img.shields.io/travis/nunomaduro/collision/stable.svg" alt="Build Status"></img></a>
|
||||
<a href="https://github.com/nunomaduro/collision/actions"><img src="https://img.shields.io/github/workflow/status/nunomaduro/collision/Tests.svg" alt="Build Status"></img></a>
|
||||
<a href="https://scrutinizer-ci.com/g/nunomaduro/collision"><img src="https://img.shields.io/scrutinizer/g/nunomaduro/collision.svg" alt="Quality Score"></img></a>
|
||||
<a href="https://packagist.org/packages/nunomaduro/collision"><img src="https://poser.pugx.org/nunomaduro/collision/d/total.svg" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/nunomaduro/collision"><img src="https://poser.pugx.org/nunomaduro/collision/v/stable.svg" alt="Latest Stable Version"></a>
|
||||
@@ -22,7 +22,7 @@ Collision was created by, and is maintained by **[Nuno Maduro](https://github.co
|
||||
|
||||
## Installation & Usage
|
||||
|
||||
> **Requires [PHP 7.2.5+](https://php.net/releases/)**
|
||||
> **Requires [PHP 7.3+](https://php.net/releases/)**
|
||||
|
||||
Require Collision using [Composer](https://getcomposer.org):
|
||||
|
||||
@@ -30,17 +30,23 @@ Require Collision using [Composer](https://getcomposer.org):
|
||||
composer require nunomaduro/collision --dev
|
||||
```
|
||||
|
||||
## Lumen adapter
|
||||
## Laravel Version Compatibility
|
||||
|
||||
Configure the Collision service provider:
|
||||
```php
|
||||
// bootstrap/app.php:
|
||||
$app->register(\NunoMaduro\Collision\Adapters\Laravel\CollisionServiceProvider::class);
|
||||
Laravel | Collision
|
||||
:---------|:----------
|
||||
6.x | 3.x
|
||||
7.x | 4.x
|
||||
8.x | 5.x
|
||||
|
||||
As an example, here is how to require Collision on Laravel 6.x:
|
||||
|
||||
```bash
|
||||
composer require nunomaduro/collision:^3.0 --dev
|
||||
```
|
||||
|
||||
## Phpunit adapter
|
||||
|
||||
Phpunit must be 8.5.1 or higher.
|
||||
Phpunit must be 9.0 or higher.
|
||||
|
||||
Add the Collision `printerClass` to your `phpunit.xml` in the `phpunit` section:
|
||||
|
||||
|
||||
30
vendor/nunomaduro/collision/composer.json
vendored
30
vendor/nunomaduro/collision/composer.json
vendored
@@ -14,22 +14,21 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"php": "^7.3 || ^8.0",
|
||||
"facade/ignition-contracts": "^1.0",
|
||||
"filp/whoops": "^2.4",
|
||||
"filp/whoops": "^2.14.3",
|
||||
"symfony/console": "^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"facade/ignition": "^2.0",
|
||||
"fideloper/proxy": "^4.2",
|
||||
"fruitcake/laravel-cors": "^1.0",
|
||||
"laravel/framework": "^7.0",
|
||||
"laravel/tinker": "^2.0",
|
||||
"nunomaduro/larastan": "^0.6",
|
||||
"orchestra/testbench": "^5.0",
|
||||
"phpstan/phpstan": "^0.12.3",
|
||||
"phpunit/phpunit": "^8.5.1 || ^9.0"
|
||||
"brianium/paratest": "^6.1",
|
||||
"fideloper/proxy": "^4.4.1",
|
||||
"fruitcake/laravel-cors": "^2.0.3",
|
||||
"laravel/framework": "8.x-dev",
|
||||
"nunomaduro/larastan": "^0.6.2",
|
||||
"nunomaduro/mock-final-classes": "^1.0",
|
||||
"orchestra/testbench": "^6.0",
|
||||
"phpstan/phpstan": "^0.12.64",
|
||||
"phpunit/phpunit": "^9.5.0"
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
@@ -58,14 +57,11 @@
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "php-cs-fixer fix -v",
|
||||
"test:types": "phpstan analyse --ansi",
|
||||
"test:unit": "phpunit --colors=always",
|
||||
"test:lint": "php-cs-fixer fix -v --dry-run",
|
||||
"test": [
|
||||
"@test:lint",
|
||||
"@test:unit",
|
||||
"@test:types"
|
||||
"@test:types",
|
||||
"@test:unit"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
19
vendor/nunomaduro/collision/phpstan.neon.dist
vendored
19
vendor/nunomaduro/collision/phpstan.neon.dist
vendored
@@ -1,19 +0,0 @@
|
||||
includes:
|
||||
- ./vendor/nunomaduro/larastan/extension.neon
|
||||
parameters:
|
||||
level: max
|
||||
paths:
|
||||
- src
|
||||
checkMissingIterableValueType: false
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
excludes_analyse:
|
||||
- src/Adapters/Phpunit/Printer
|
||||
ignoreErrors:
|
||||
- '#Parameter \#1 \$input of function str_pad expects string, int given.#'
|
||||
- '#Cannot call method addTheme\(\) on array|JakubOnderka\\PhpConsoleColor\\ConsoleColor#'
|
||||
- '#Method NunoMaduro\\Collision\\Adapters\\Laravel\\IgnitionSolutionsRepository::getFromThrowable\(\) should return array<int,#'
|
||||
- '#Result of static method Dotenv\\Repository\\RepositoryBuilder::create\(\) \(void\) is used.#'
|
||||
- message: '#Cannot call method make\(\) on void.#'
|
||||
paths:
|
||||
- src/Adapters/Laravel/Commands/*
|
||||
|
||||
28
vendor/nunomaduro/collision/phpunit.xml.dist
vendored
28
vendor/nunomaduro/collision/phpunit.xml.dist
vendored
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
processIsolation="false"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
verbose="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Collision Test Suite">
|
||||
<directory suffix="Test.php">./tests/Unit</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Laravel;
|
||||
|
||||
@@ -21,11 +14,9 @@ use NunoMaduro\Collision\SolutionsRepositories\NullSolutionsRepository;
|
||||
use NunoMaduro\Collision\Writer;
|
||||
|
||||
/**
|
||||
* This is an Collision Laravel Adapter Service Provider implementation.
|
||||
* @internal
|
||||
*
|
||||
* Registers the Error Handler on Laravel.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @final
|
||||
*/
|
||||
class CollisionServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Laravel\Commands;
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
use Dotenv\Repository\RepositoryBuilder;
|
||||
use Dotenv\Exception\InvalidPathException;
|
||||
use Dotenv\Parser\Parser;
|
||||
use Dotenv\Store\StoreBuilder;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Env;
|
||||
use Illuminate\Support\Str;
|
||||
use NunoMaduro\Collision\Adapters\Laravel\Exceptions\RequirementsException;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Process\Exception\ProcessSignaledException;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class TestCommand extends Command
|
||||
{
|
||||
/**
|
||||
@@ -17,7 +27,11 @@ class TestCommand extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'test {--without-tty : Disable output to TTY}';
|
||||
protected $signature = 'test
|
||||
{--without-tty : Disable output to TTY}
|
||||
{--p|parallel : Indicates if the tests should run in parallel}
|
||||
{--recreate-databases : Indicates if the test databases should be re-created}
|
||||
';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
@@ -26,16 +40,6 @@ class TestCommand extends Command
|
||||
*/
|
||||
protected $description = 'Run the application tests';
|
||||
|
||||
/**
|
||||
* The arguments to be used while calling phpunit.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [
|
||||
'--printer',
|
||||
'NunoMaduro\Collision\Adapters\Phpunit\Printer',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
@@ -55,17 +59,39 @@ class TestCommand extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if ((int) \PHPUnit\Runner\Version::id()[0] < 9) {
|
||||
throw new RequirementsException('Running Collision ^5.0 artisan test command requires at least PHPUnit ^9.0.');
|
||||
}
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
if ((int) \Illuminate\Foundation\Application::VERSION[0] < 8) {
|
||||
throw new RequirementsException('Running Collision ^5.0 artisan test command requires at least Laravel ^8.0.');
|
||||
}
|
||||
|
||||
if ($this->option('parallel') && !$this->isParallelDependenciesInstalled()) {
|
||||
if (!$this->confirm('Running tests in parallel requires "brianium/paratest". Do you wish to install it as a dev dependency?')) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->installParallelDependencies();
|
||||
}
|
||||
|
||||
$options = array_slice($_SERVER['argv'], $this->option('without-tty') ? 3 : 2);
|
||||
|
||||
$this->clearEnv();
|
||||
|
||||
$parallel = $this->option('parallel');
|
||||
|
||||
$process = (new Process(array_merge(
|
||||
$this->binary(),
|
||||
array_merge(
|
||||
$this->arguments,
|
||||
$this->phpunitArguments($options)
|
||||
)
|
||||
)))->setTimeout(null);
|
||||
// Binary ...
|
||||
$this->binary(),
|
||||
// Arguments ...
|
||||
$parallel ? $this->paratestArguments($options) : $this->phpunitArguments($options)
|
||||
),
|
||||
null,
|
||||
// Envs ...
|
||||
$parallel ? $this->paratestEnvironmentVariables() : $this->phpunitEnvironmentVariables(),
|
||||
))->setTimeout(null);
|
||||
|
||||
try {
|
||||
$process->setTty(!$this->option('without-tty'));
|
||||
@@ -91,11 +117,17 @@ class TestCommand extends Command
|
||||
*/
|
||||
protected function binary()
|
||||
{
|
||||
if ('phpdbg' === PHP_SAPI) {
|
||||
return [PHP_BINARY, '-qrr', 'vendor/phpunit/phpunit/phpunit'];
|
||||
if (class_exists(\Pest\Laravel\PestServiceProvider::class)) {
|
||||
$command = $this->option('parallel') ? ['vendor/pestphp/pest/bin/pest', '--parallel'] : ['vendor/pestphp/pest/bin/pest'];
|
||||
} else {
|
||||
$command = $this->option('parallel') ? ['vendor/brianium/paratest/bin/paratest'] : ['vendor/phpunit/phpunit/phpunit'];
|
||||
}
|
||||
|
||||
return [PHP_BINARY, 'vendor/phpunit/phpunit/phpunit'];
|
||||
if ('phpdbg' === PHP_SAPI) {
|
||||
return array_merge([PHP_BINARY, '-qrr'], $command);
|
||||
}
|
||||
|
||||
return array_merge([PHP_BINARY], $command);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,6 +139,8 @@ class TestCommand extends Command
|
||||
*/
|
||||
protected function phpunitArguments($options)
|
||||
{
|
||||
$options = array_merge(['--printer=NunoMaduro\\Collision\\Adapters\\Phpunit\\Printer'], $options);
|
||||
|
||||
$options = array_values(array_filter($options, function ($option) {
|
||||
return !Str::startsWith($option, '--env=');
|
||||
}));
|
||||
@@ -115,7 +149,56 @@ class TestCommand extends Command
|
||||
$file = base_path('phpunit.xml.dist');
|
||||
}
|
||||
|
||||
return array_merge(['-c', $file], $options);
|
||||
return array_merge(["--configuration=$file"], $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array of arguments for running Paratest.
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function paratestArguments($options)
|
||||
{
|
||||
$options = array_values(array_filter($options, function ($option) {
|
||||
return !Str::startsWith($option, '--env=')
|
||||
&& !Str::startsWith($option, '-p')
|
||||
&& !Str::startsWith($option, '--parallel')
|
||||
&& !Str::startsWith($option, '--recreate-databases');
|
||||
}));
|
||||
|
||||
if (!file_exists($file = base_path('phpunit.xml'))) {
|
||||
$file = base_path('phpunit.xml.dist');
|
||||
}
|
||||
|
||||
return array_merge([
|
||||
"--configuration=$file",
|
||||
"--runner=\Illuminate\Testing\ParallelRunner",
|
||||
], $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array of environment variables for running PHPUnit.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function phpunitEnvironmentVariables()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array of environment variables for running Paratest.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function paratestEnvironmentVariables()
|
||||
{
|
||||
return [
|
||||
'LARAVEL_PARALLEL_TESTING' => 1,
|
||||
'LARAVEL_PARALLEL_TESTING_RECREATE_DATABASES' => $this->option('recreate-databases'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,18 +209,101 @@ class TestCommand extends Command
|
||||
protected function clearEnv()
|
||||
{
|
||||
if (!$this->option('env')) {
|
||||
$repositories = RepositoryBuilder::create()
|
||||
->make();
|
||||
|
||||
$envs = Dotenv::create(
|
||||
$repositories,
|
||||
$vars = self::getEnvironmentVariables(
|
||||
// @phpstan-ignore-next-line
|
||||
$this->laravel->environmentPath(),
|
||||
// @phpstan-ignore-next-line
|
||||
$this->laravel->environmentFile()
|
||||
)->safeLoad();
|
||||
);
|
||||
|
||||
foreach ($envs as $name => $value) {
|
||||
$repositories->clear($name);
|
||||
$repository = Env::getRepository();
|
||||
|
||||
foreach ($vars as $name) {
|
||||
$repository->clear($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function getEnvironmentVariables($path, $file)
|
||||
{
|
||||
try {
|
||||
$content = StoreBuilder::createWithNoNames()
|
||||
->addPath($path)
|
||||
->addName($file)
|
||||
->make()
|
||||
->read();
|
||||
} catch (InvalidPathException $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$vars = [];
|
||||
|
||||
foreach ((new Parser())->parse($content) as $entry) {
|
||||
$vars[] = $entry->getName();
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the parallel dependencies are installed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isParallelDependenciesInstalled()
|
||||
{
|
||||
return class_exists(\ParaTest\Console\Commands\ParaTestCommand::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install parallel testing needed dependencies.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function installParallelDependencies()
|
||||
{
|
||||
$command = $this->findComposer() . ' require brianium/paratest --dev';
|
||||
|
||||
$process = Process::fromShellCommandline($command, null, null, null, null);
|
||||
|
||||
if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) {
|
||||
try {
|
||||
$process->setTty(true);
|
||||
} catch (RuntimeException $e) {
|
||||
$this->output->writeln('Warning: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$process->run(function ($type, $line) {
|
||||
$this->output->write($line);
|
||||
});
|
||||
} catch (ProcessSignaledException $e) {
|
||||
if (extension_loaded('pcntl') && $e->getSignal() !== SIGINT) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the composer command for the environment.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function findComposer()
|
||||
{
|
||||
$composerPath = getcwd() . '/composer.phar';
|
||||
|
||||
if (file_exists($composerPath)) {
|
||||
return '"' . PHP_BINARY . '" ' . $composerPath;
|
||||
}
|
||||
|
||||
return 'composer';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Laravel;
|
||||
|
||||
@@ -18,13 +11,9 @@ use Symfony\Component\Console\Exception\ExceptionInterface as SymfonyConsoleExce
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* This is an Collision Laravel Adapter ExceptionHandler implementation.
|
||||
*
|
||||
* Registers the Error Handler on Laravel.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
class ExceptionHandler implements ExceptionHandlerContract
|
||||
final class ExceptionHandler implements ExceptionHandlerContract
|
||||
{
|
||||
/**
|
||||
* Holds an instance of the application exception handler.
|
||||
|
||||
16
vendor/nunomaduro/collision/src/Adapters/Laravel/Exceptions/RequirementsException.php
vendored
Normal file
16
vendor/nunomaduro/collision/src/Adapters/Laravel/Exceptions/RequirementsException.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Laravel\Exceptions;
|
||||
|
||||
use NunoMaduro\Collision\Contracts\RenderlessEditor;
|
||||
use NunoMaduro\Collision\Contracts\RenderlessTrace;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class RequirementsException extends RuntimeException implements RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Laravel;
|
||||
|
||||
@@ -16,13 +9,9 @@ use NunoMaduro\Collision\Contracts\SolutionsRepository;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* This is an Collision Laravel Adapter Solutions Provider implementation.
|
||||
*
|
||||
* Registers the Error Handler on Laravel.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
class IgnitionSolutionsRepository implements SolutionsRepository
|
||||
final class IgnitionSolutionsRepository implements SolutionsRepository
|
||||
{
|
||||
/**
|
||||
* Holds an instance of ignition solutions provider repository.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of Collision.
|
||||
*
|
||||
@@ -14,11 +16,9 @@ namespace NunoMaduro\Collision\Adapters\Laravel;
|
||||
use Whoops\Exception\Inspector as BaseInspector;
|
||||
|
||||
/**
|
||||
* This is an Collision Laravel Adapter Inspector implementation.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
class Inspector extends BaseInspector
|
||||
final class Inspector extends BaseInspector
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of Collision.
|
||||
*
|
||||
|
||||
@@ -1,56 +1,245 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Phpunit;
|
||||
|
||||
/*
|
||||
* This `if` condition exists because phpunit
|
||||
* is not a direct dependency of Collision.
|
||||
*
|
||||
* This code bellow it's for phpunit@8
|
||||
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
|
||||
*/
|
||||
if (class_exists(\PHPUnit\Runner\Version::class) && intval(substr(\PHPUnit\Runner\Version::id(), 0, 1)) === 8) {
|
||||
final class Printer implements \PHPUnit\TextUI\ResultPrinter
|
||||
{
|
||||
/**
|
||||
* This is an Collision Phpunit Adapter implementation.
|
||||
* Holds an instance of the style.
|
||||
*
|
||||
* @internal
|
||||
* Style is a class we use to interact with output.
|
||||
*
|
||||
* @var Style
|
||||
*/
|
||||
final class Printer extends \PHPUnit\Util\Printer implements \PHPUnit\Framework\TestListener
|
||||
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')
|
||||
{
|
||||
use PrinterContents;
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This `if` condition exists because phpunit
|
||||
* is not a direct dependency of Collision.
|
||||
*
|
||||
* This code bellow it's for phpunit@9
|
||||
*/
|
||||
if (class_exists(\PHPUnit\Runner\Version::class) && intval(substr(\PHPUnit\Runner\Version::id(), 0, 1)) === 9) {
|
||||
/**
|
||||
* This is an Collision Phpunit Adapter implementation.
|
||||
*
|
||||
* @internal
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final class Printer implements \PHPUnit\TextUI\ResultPrinter
|
||||
public function addError(Test $testCase, Throwable $throwable, float $time): void
|
||||
{
|
||||
use PrinterContents;
|
||||
$this->failed = true;
|
||||
|
||||
/**
|
||||
* Intentionally left blank as we output things on events of the listener.
|
||||
*/
|
||||
public function printResult(\PHPUnit\Framework\TestResult $result): void
|
||||
{
|
||||
// ..
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
<?php
|
||||
|
||||
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;
|
||||
|
||||
trait PrinterContents
|
||||
{
|
||||
/**
|
||||
* 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 ended before.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $ended = false;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the listener.
|
||||
*
|
||||
* @param ConsoleOutput $output
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function __construct(ConsoleOutput $output = null)
|
||||
{
|
||||
if (intval(substr(\PHPUnit\Runner\Version::id(), 0, 1)) === 8) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
$this->timer = Timer::start();
|
||||
|
||||
$output = $output ?? new ConsoleOutput();
|
||||
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
|
||||
{
|
||||
$testCase = $this->testCaseFromTest($testCase);
|
||||
|
||||
$this->state->add(TestResult::fromTestCase($testCase, TestResult::FAIL));
|
||||
|
||||
$this->style->writeError($this->state, $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->getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addFailure(Test $testCase, AssertionFailedError $error, float $time): void
|
||||
{
|
||||
$testCase = $this->testCaseFromTest($testCase);
|
||||
|
||||
$this->state->add(TestResult::fromTestCase($testCase, TestResult::FAIL));
|
||||
|
||||
$reflector = new ReflectionObject($error);
|
||||
|
||||
if ($reflector->hasProperty('message')) {
|
||||
$message = trim((string) preg_replace("/\r|\n/", ' ', $error->getMessage()));
|
||||
$property = $reflector->getProperty('message');
|
||||
$property->setAccessible(true);
|
||||
$property->setValue($error, $message);
|
||||
}
|
||||
|
||||
$this->style->writeError($this->state, $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addIncompleteTest(Test $testCase, Throwable $t, float $time): void
|
||||
{
|
||||
$testCase = $this->testCaseFromTest($testCase);
|
||||
|
||||
$this->state->add(TestResult::fromTestCase($testCase, TestResult::INCOMPLETE));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addRiskyTest(Test $testCase, Throwable $t, float $time): void
|
||||
{
|
||||
$testCase = $this->testCaseFromTest($testCase);
|
||||
|
||||
$this->state->add(TestResult::fromTestCase($testCase, TestResult::RISKY, $t->getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addSkippedTest(Test $testCase, Throwable $t, float $time): void
|
||||
{
|
||||
$testCase = $this->testCaseFromTest($testCase);
|
||||
|
||||
$this->state->add(TestResult::fromTestCase($testCase, TestResult::SKIPPED, $t->getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function startTestSuite(TestSuite $suite): void
|
||||
{
|
||||
if ($this->state->suiteTotalTests === null) {
|
||||
$this->state->suiteTotalTests = $suite->count();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function endTestSuite(TestSuite $suite): void
|
||||
{
|
||||
if (!$this->ended && $this->state->suiteTotalTests === $this->state->testSuiteTestsCount()) {
|
||||
$this->ended = true;
|
||||
|
||||
$this->style->writeCurrentRecap($this->state);
|
||||
|
||||
$this->style->updateFooter($this->state);
|
||||
$this->style->writeRecap($this->timer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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->writeCurrentRecap($this->state);
|
||||
|
||||
$this->state->moveTo($testCase);
|
||||
}
|
||||
|
||||
$this->style->updateFooter($this->state, $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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Phpunit;
|
||||
|
||||
@@ -47,6 +40,20 @@ final class State
|
||||
*/
|
||||
public $testCaseTests = [];
|
||||
|
||||
/**
|
||||
* The current test case tests.
|
||||
*
|
||||
* @var array<int, TestResult>
|
||||
*/
|
||||
public $toBePrintedCaseTests = [];
|
||||
|
||||
/**
|
||||
* Header printed.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $headerPrinted = false;
|
||||
|
||||
/**
|
||||
* The state constructor.
|
||||
*/
|
||||
@@ -68,7 +75,8 @@ final class State
|
||||
*/
|
||||
public function add(TestResult $test): void
|
||||
{
|
||||
$this->testCaseTests[] = $test;
|
||||
$this->testCaseTests[] = $test;
|
||||
$this->toBePrintedCaseTests[] = $test;
|
||||
|
||||
$this->suiteTests[] = $test;
|
||||
}
|
||||
@@ -145,6 +153,8 @@ final class State
|
||||
$this->testCaseName = self::getPrintableTestCaseName($testCase);
|
||||
|
||||
$this->testCaseTests = [];
|
||||
|
||||
$this->headerPrinted = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,9 +162,11 @@ final class State
|
||||
*/
|
||||
public function eachTestCaseTests(callable $callback): void
|
||||
{
|
||||
foreach ($this->testCaseTests as $test) {
|
||||
foreach ($this->toBePrintedCaseTests as $test) {
|
||||
$callback($test);
|
||||
}
|
||||
|
||||
$this->toBePrintedCaseTests = [];
|
||||
}
|
||||
|
||||
public function countTestsInTestSuiteBy(string $type): int
|
||||
@@ -181,14 +193,10 @@ final class State
|
||||
/**
|
||||
* Returns the printable test case name from the given `TestCase`.
|
||||
*/
|
||||
private static function getPrintableTestCaseName(TestCase $test): string
|
||||
public static function getPrintableTestCaseName(TestCase $test): string
|
||||
{
|
||||
if ($test instanceof HasPrintableTestCaseName) {
|
||||
$name = $test->getPrintableTestCaseName();
|
||||
} else {
|
||||
$name = get_class($test);
|
||||
}
|
||||
|
||||
return $name;
|
||||
return $test instanceof HasPrintableTestCaseName
|
||||
? $test->getPrintableTestCaseName()
|
||||
: get_class($test);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
<?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.
|
||||
*/
|
||||
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 PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
use Symfony\Component\Console\Output\ConsoleSectionOutput;
|
||||
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||
use Throwable;
|
||||
use Whoops\Exception\Inspector;
|
||||
|
||||
@@ -31,19 +24,24 @@ final class Style
|
||||
*/
|
||||
private $output;
|
||||
|
||||
/**
|
||||
* @var ConsoleSectionOutput
|
||||
*/
|
||||
private $footer;
|
||||
|
||||
/**
|
||||
* Style constructor.
|
||||
*/
|
||||
public function __construct(ConsoleOutput $output)
|
||||
public function __construct(ConsoleOutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
if (!$output instanceof ConsoleOutput) {
|
||||
throw new ShouldNotHappen();
|
||||
}
|
||||
|
||||
$this->footer = $output->section();
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the content.
|
||||
*/
|
||||
public function write(string $content): void
|
||||
{
|
||||
$this->output->write($content);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,20 +52,21 @@ final class Style
|
||||
* ✓ basic test
|
||||
* ```
|
||||
*/
|
||||
public function writeCurrentRecap(State $state): void
|
||||
public function writeCurrentTestCaseSummary(State $state): void
|
||||
{
|
||||
if (!$state->testCaseTestsCount()) {
|
||||
if ($state->testCaseTestsCount() === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->footer->clear();
|
||||
|
||||
$this->output->writeln($this->titleLineFrom(
|
||||
$state->getTestCaseTitle() === 'FAIL' ? 'white' : 'black',
|
||||
$state->getTestCaseTitleColor(),
|
||||
$state->getTestCaseTitle(),
|
||||
$state->testCaseName
|
||||
));
|
||||
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(
|
||||
@@ -80,85 +79,97 @@ final class Style
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the content similar too on the footer. Where
|
||||
* we are updating the current test.
|
||||
* Prints the content similar too:.
|
||||
*
|
||||
* ```
|
||||
* Runs Unit\ExampleTest
|
||||
* • basic test
|
||||
* PASS Unit\ExampleTest
|
||||
* ✓ basic test
|
||||
* ```
|
||||
*/
|
||||
public function updateFooter(State $state, TestCase $testCase = null): void
|
||||
public function writeErrorsSummary(State $state, bool $onFailure): void
|
||||
{
|
||||
$runs = [];
|
||||
$errors = array_filter($state->suiteTests, function (TestResult $testResult) {
|
||||
return $testResult->type === TestResult::FAIL;
|
||||
});
|
||||
|
||||
if ($testCase) {
|
||||
$runs[] = $this->titleLineFrom(
|
||||
'black',
|
||||
'yellow',
|
||||
'RUNS',
|
||||
get_class($testCase)
|
||||
);
|
||||
|
||||
$testResult = TestResult::fromTestCase($testCase, TestResult::RUNS);
|
||||
$runs[] = $this->testLineFrom(
|
||||
$testResult->color,
|
||||
$testResult->icon,
|
||||
$testResult->description
|
||||
);
|
||||
if (!$onFailure) {
|
||||
$this->output->writeln(['', " \e[2m---\e[22m", '']);
|
||||
}
|
||||
|
||||
$types = [TestResult::FAIL, TestResult::WARN, TestResult::RISKY, TestResult::INCOMPLETE, TestResult::SKIPPED, TestResult::PASS];
|
||||
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)) {
|
||||
if (($countTests = $state->countTestsInTestSuiteBy($type)) !== 0) {
|
||||
$color = TestResult::makeColor($type);
|
||||
$tests[] = "<fg=$color;options=bold>$countTests $type</>";
|
||||
}
|
||||
}
|
||||
|
||||
$pending = $state->suiteTotalTests - $state->testSuiteTestsCount();
|
||||
if ($pending) {
|
||||
if ($pending !== 0) {
|
||||
$tests[] = "\e[2m$pending pending\e[22m";
|
||||
}
|
||||
|
||||
if (!empty($tests)) {
|
||||
$this->footer->overwrite(array_merge($runs, [
|
||||
'',
|
||||
$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('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the final recap.
|
||||
* Displays a warning message.
|
||||
*/
|
||||
public function writeRecap(Timer $timer): void
|
||||
public function writeWarning(string $message): void
|
||||
{
|
||||
$timeElapsed = number_format($timer->result(), 2, '.', '');
|
||||
$this->footer->writeln(
|
||||
sprintf(
|
||||
' <fg=white;options=bold>Time: </><fg=default>%ss</>',
|
||||
$timeElapsed
|
||||
)
|
||||
);
|
||||
$this->output->writeln($this->testLineFrom('yellow', $message, ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the error using Collision's writer
|
||||
* and terminates with exit code === 1.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function writeError(State $state, Throwable $throwable)
|
||||
public function writeError(Throwable $throwable): void
|
||||
{
|
||||
$this->writeCurrentRecap($state);
|
||||
|
||||
$this->updateFooter($state);
|
||||
|
||||
$writer = (new Writer())->setOutput($this->output);
|
||||
|
||||
if ($throwable instanceof AssertionFailedError) {
|
||||
@@ -167,10 +178,24 @@ final class Style
|
||||
}
|
||||
|
||||
$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\/symfony\/dom-crawler/',
|
||||
'/vendor\/symfony\/browser-kit/',
|
||||
'/vendor\/symfony\/css-selector/',
|
||||
'/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) {
|
||||
@@ -182,10 +207,25 @@ final class Style
|
||||
$writer->write($inspector);
|
||||
|
||||
if ($throwable instanceof ExpectationFailedException && $comparisionFailure = $throwable->getComparisonFailure()) {
|
||||
$this->output->write($comparisionFailure->getDiff());
|
||||
$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");
|
||||
}
|
||||
|
||||
exit(1);
|
||||
$this->output->writeln('');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,20 +233,6 @@ final class Style
|
||||
*/
|
||||
private function titleLineFrom(string $fg, string $bg, string $title, string $testCaseName): string
|
||||
{
|
||||
if (class_exists($testCaseName)) {
|
||||
$nameParts = explode('\\', $testCaseName);
|
||||
$highlightedPart = array_pop($nameParts);
|
||||
$nonHighlightedPart = implode('\\', $nameParts);
|
||||
$testCaseName = sprintf("\e[2m%s\e[22m<fg=white;options=bold>%s</>", "$nonHighlightedPart\\", $highlightedPart);
|
||||
} elseif (file_exists($testCaseName)) {
|
||||
$testCaseName = substr($testCaseName, strlen((string) getcwd()) + 1);
|
||||
$nameParts = explode(DIRECTORY_SEPARATOR, $testCaseName);
|
||||
$highlightedPart = (string) array_pop($nameParts);
|
||||
$highlightedPart = substr($highlightedPart, 0, (int) strrpos($highlightedPart, '.'));
|
||||
$nonHighlightedPart = implode('\\', $nameParts);
|
||||
$testCaseName = sprintf("\e[2m%s\e[22m<fg=white;options=bold>%s</>", "$nonHighlightedPart\\", $highlightedPart);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
"\n <fg=%s;bg=%s;options=bold> %s </><fg=default> %s</>",
|
||||
$fg,
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Phpunit;
|
||||
|
||||
use NunoMaduro\Collision\Contracts\Adapters\Phpunit\HasPrintableTestCaseName;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -26,6 +21,13 @@ final class TestResult
|
||||
public const RUNS = 'pending';
|
||||
public const PASS = 'passed';
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $testCaseName;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
*
|
||||
@@ -57,36 +59,53 @@ final class TestResult
|
||||
/**
|
||||
* @readonly
|
||||
*
|
||||
* @var string|null
|
||||
* @var Throwable|null
|
||||
*/
|
||||
public $warning;
|
||||
public $throwable;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $warning = '';
|
||||
|
||||
/**
|
||||
* Test constructor.
|
||||
*
|
||||
* @param string $warning
|
||||
*/
|
||||
private function __construct(string $description, string $type, string $icon, string $color, string $warning = null)
|
||||
private function __construct(string $testCaseName, string $description, string $type, string $icon, string $color, Throwable $throwable = null)
|
||||
{
|
||||
$this->description = $description;
|
||||
$this->type = $type;
|
||||
$this->icon = $icon;
|
||||
$this->color = $color;
|
||||
$this->warning = trim((string) preg_replace("/\r|\n/", ' ', (string) $warning));
|
||||
$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, string $warning = null): self
|
||||
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($description, $type, $icon, $color, $warning);
|
||||
return new self($testCaseName, $description, $type, $icon, $color, $throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +113,11 @@ final class TestResult
|
||||
*/
|
||||
public static function makeDescription(TestCase $testCase): string
|
||||
{
|
||||
$name = $testCase->getName(true);
|
||||
$name = $testCase->getName(false);
|
||||
|
||||
if ($testCase instanceof HasPrintableTestCaseName) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
// First, lets replace underscore by spaces.
|
||||
$name = str_replace('_', ' ', $name);
|
||||
@@ -106,10 +129,21 @@ final class TestResult
|
||||
$name = (string) preg_replace('/^test/', '', $name);
|
||||
|
||||
// Removes spaces
|
||||
$name = (string) trim($name);
|
||||
$name = trim($name);
|
||||
|
||||
// Finally, lower case everything
|
||||
return (string) mb_strtolower($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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,15 +153,15 @@ final class TestResult
|
||||
{
|
||||
switch ($type) {
|
||||
case self::FAIL:
|
||||
return '✕';
|
||||
return '⨯';
|
||||
case self::SKIPPED:
|
||||
return 's';
|
||||
return '-';
|
||||
case self::RISKY:
|
||||
return 'r';
|
||||
return '!';
|
||||
case self::INCOMPLETE:
|
||||
return 'i';
|
||||
return '…';
|
||||
case self::WARN:
|
||||
return 'w';
|
||||
return '!';
|
||||
case self::RUNS:
|
||||
return '•';
|
||||
default:
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Adapters\Phpunit;
|
||||
|
||||
|
||||
@@ -1,25 +1,20 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision;
|
||||
|
||||
use NunoMaduro\Collision\Contracts\ArgumentFormatter as ArgumentFormatterContract;
|
||||
|
||||
/**
|
||||
* This is an Collision Argument Formatter implementation.
|
||||
* @internal
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @see \Tests\Unit\ArgumentFormatterTest
|
||||
*/
|
||||
class ArgumentFormatter implements ArgumentFormatterContract
|
||||
final class ArgumentFormatter implements ArgumentFormatterContract
|
||||
{
|
||||
private const MAX_STRING_LENGTH = 1000;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -30,7 +25,7 @@ class ArgumentFormatter implements ArgumentFormatterContract
|
||||
foreach ($arguments as $argument) {
|
||||
switch (true) {
|
||||
case is_string($argument):
|
||||
$result[] = '"' . $argument . '"';
|
||||
$result[] = '"' . (mb_strlen($argument) > self::MAX_STRING_LENGTH ? mb_substr($argument, 0, self::MAX_STRING_LENGTH) . '...' : $argument) . '"';
|
||||
break;
|
||||
case is_array($argument):
|
||||
$associative = array_keys($argument) !== range(0, count($argument) - 1);
|
||||
|
||||
61
vendor/nunomaduro/collision/src/ConsoleColor.php
vendored
61
vendor/nunomaduro/collision/src/ConsoleColor.php
vendored
@@ -1,35 +1,23 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision;
|
||||
|
||||
use NunoMaduro\Collision\Exceptions\InvalidStyleException;
|
||||
use NunoMaduro\Collision\Exceptions\ShouldNotHappen;
|
||||
|
||||
/**
|
||||
* This is an Collision Console Color implementation.
|
||||
*
|
||||
* Code originally from { JakubOnderka\\PhpConsoleColor }. But the package got deprecated.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class ConsoleColor
|
||||
final class ConsoleColor
|
||||
{
|
||||
const FOREGROUND = 38;
|
||||
const BACKGROUND = 48;
|
||||
public const FOREGROUND = 38;
|
||||
public const BACKGROUND = 48;
|
||||
|
||||
const COLOR256_REGEXP = '~^(bg_)?color_([0-9]{1,3})$~';
|
||||
public const COLOR256_REGEXP = '~^(bg_)?color_(\d{1,3})$~';
|
||||
|
||||
const RESET_STYLE = 0;
|
||||
public const RESET_STYLE = 0;
|
||||
|
||||
/** @var bool */
|
||||
private $isSupported;
|
||||
@@ -38,7 +26,7 @@ class ConsoleColor
|
||||
private $forceStyle = false;
|
||||
|
||||
/** @var array */
|
||||
private $styles = [
|
||||
private const STYLES = [
|
||||
'none' => null,
|
||||
'bold' => '1',
|
||||
'dark' => '2',
|
||||
@@ -145,7 +133,7 @@ class ConsoleColor
|
||||
*/
|
||||
public function setForceStyle($forceStyle)
|
||||
{
|
||||
$this->forceStyle = (bool) $forceStyle;
|
||||
$this->forceStyle = $forceStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,17 +205,16 @@ class ConsoleColor
|
||||
*/
|
||||
public function isSupported()
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
if (function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT)) {
|
||||
return true;
|
||||
} elseif (getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return function_exists('posix_isatty') && @posix_isatty(STDOUT);
|
||||
// The COLLISION_FORCE_COLORS variable is for internal purposes only
|
||||
if (getenv('COLLISION_FORCE_COLORS') !== false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
return getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON';
|
||||
}
|
||||
|
||||
return function_exists('posix_isatty') && @posix_isatty(STDOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,9 +224,9 @@ class ConsoleColor
|
||||
{
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
return function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT);
|
||||
} else {
|
||||
return strpos(getenv('TERM'), '256color') !== false;
|
||||
}
|
||||
|
||||
return strpos(getenv('TERM'), '256color') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,7 +234,7 @@ class ConsoleColor
|
||||
*/
|
||||
public function getPossibleStyles()
|
||||
{
|
||||
return array_keys($this->styles);
|
||||
return array_keys(self::STYLES);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,8 +259,8 @@ class ConsoleColor
|
||||
*/
|
||||
private function styleSequence($style)
|
||||
{
|
||||
if (array_key_exists($style, $this->styles)) {
|
||||
return $this->styles[$style];
|
||||
if (array_key_exists($style, self::STYLES)) {
|
||||
return self::STYLES[$style];
|
||||
}
|
||||
|
||||
if (!$this->are256ColorsSupported()) {
|
||||
@@ -295,7 +282,7 @@ class ConsoleColor
|
||||
*/
|
||||
private function isValidStyle($style)
|
||||
{
|
||||
return array_key_exists($style, $this->styles) || preg_match(self::COLOR256_REGEXP, $style);
|
||||
return array_key_exists($style, self::STYLES) || preg_match(self::COLOR256_REGEXP, $style);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts\Adapters\Phpunit;
|
||||
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts\Adapters\Phpunit;
|
||||
|
||||
@@ -15,9 +8,7 @@ use PHPUnit\Framework\Test;
|
||||
use PHPUnit\Framework\TestListener;
|
||||
|
||||
/**
|
||||
* This is an Collision Phpunit Adapter contract.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
interface Listener extends TestListener
|
||||
{
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts;
|
||||
|
||||
/**
|
||||
* This is an Collision Argument Formatter contract.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
interface ArgumentFormatter
|
||||
{
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts;
|
||||
|
||||
@@ -15,9 +8,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Whoops\Handler\HandlerInterface;
|
||||
|
||||
/**
|
||||
* This is an Collision Handler contract.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
interface Handler extends HandlerInterface
|
||||
{
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts;
|
||||
|
||||
/**
|
||||
* This is the Collision Highlighter contract.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
interface Highlighter
|
||||
{
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts;
|
||||
|
||||
/**
|
||||
* This is an Collision Provider contract.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
interface Provider
|
||||
{
|
||||
|
||||
12
vendor/nunomaduro/collision/src/Contracts/RenderlessEditor.php
vendored
Normal file
12
vendor/nunomaduro/collision/src/Contracts/RenderlessEditor.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
interface RenderlessEditor
|
||||
{
|
||||
}
|
||||
12
vendor/nunomaduro/collision/src/Contracts/RenderlessTrace.php
vendored
Normal file
12
vendor/nunomaduro/collision/src/Contracts/RenderlessTrace.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
interface RenderlessTrace
|
||||
{
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Contracts;
|
||||
|
||||
@@ -15,9 +8,7 @@ use Facade\IgnitionContracts\Solution;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* This is an Collision Solutions Repository contract.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
interface SolutionsRepository
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of Collision.
|
||||
*
|
||||
@@ -15,9 +17,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Whoops\Exception\Inspector;
|
||||
|
||||
/**
|
||||
* This is the Collision Writer contract.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
interface Writer
|
||||
{
|
||||
|
||||
14
vendor/nunomaduro/collision/src/Exceptions/InvalidStyleException.php
vendored
Normal file
14
vendor/nunomaduro/collision/src/Exceptions/InvalidStyleException.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Exceptions;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class InvalidStyleException extends RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\Exceptions;
|
||||
|
||||
@@ -18,10 +11,13 @@ use RuntimeException;
|
||||
*/
|
||||
final class ShouldNotHappen extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const MESSAGE = 'This should not happen, please open an issue on collision repository: %s';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$message = 'This should not happen, please open an issue on collision repository: %s';
|
||||
|
||||
parent::__construct(sprintf($message, 'https://github.com/nunomaduro/collision/issues/new'));
|
||||
parent::__construct(sprintf(self::MESSAGE, 'https://github.com/nunomaduro/collision/issues/new'));
|
||||
}
|
||||
}
|
||||
|
||||
15
vendor/nunomaduro/collision/src/Handler.php
vendored
15
vendor/nunomaduro/collision/src/Handler.php
vendored
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision;
|
||||
|
||||
@@ -17,11 +10,11 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Whoops\Handler\Handler as AbstractHandler;
|
||||
|
||||
/**
|
||||
* This is an Collision Handler implementation.
|
||||
* @internal
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @see \Tests\Unit\HandlerTest
|
||||
*/
|
||||
class Handler extends AbstractHandler implements HandlerContract
|
||||
final class Handler extends AbstractHandler implements HandlerContract
|
||||
{
|
||||
/**
|
||||
* Holds an instance of the writer.
|
||||
|
||||
158
vendor/nunomaduro/collision/src/Highlighter.php
vendored
158
vendor/nunomaduro/collision/src/Highlighter.php
vendored
@@ -1,84 +1,94 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision;
|
||||
|
||||
use NunoMaduro\Collision\Contracts\Highlighter as HighlighterContract;
|
||||
|
||||
/**
|
||||
* This is an Collision Highlighter implementation.
|
||||
*
|
||||
* Code originally from { JakubOnderka\\PhpConsoleColor }. But the package got deprecated.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class Highlighter implements HighlighterContract
|
||||
final class Highlighter implements HighlighterContract
|
||||
{
|
||||
public const TOKEN_DEFAULT = 'token_default';
|
||||
public const TOKEN_COMMENT = 'token_comment';
|
||||
public const TOKEN_STRING = 'token_string';
|
||||
public const TOKEN_HTML = 'token_html';
|
||||
public const TOKEN_KEYWORD = 'token_keyword';
|
||||
public const ACTUAL_LINE_MARK = 'actual_line_mark';
|
||||
public const LINE_NUMBER = 'line_number';
|
||||
|
||||
private const ARROW_SYMBOL = '>';
|
||||
private const DELIMITER = '|';
|
||||
private const ARROW_SYMBOL_UTF8 = '➜';
|
||||
private const DELIMITER_UTF8 = '▕'; // '▶';
|
||||
private const LINE_NUMBER_DIVIDER = 'line_divider';
|
||||
private const MARKED_LINE_NUMBER = 'marked_line';
|
||||
private const WIDTH = 3;
|
||||
/**
|
||||
* Holds the theme.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $theme = [
|
||||
self::TOKEN_STRING => ['light_gray'],
|
||||
self::TOKEN_COMMENT => ['dark_gray', 'italic'],
|
||||
self::TOKEN_KEYWORD => ['magenta', 'bold'],
|
||||
self::TOKEN_DEFAULT => ['default', 'bold'],
|
||||
self::TOKEN_HTML => ['blue', 'bold'],
|
||||
self::ACTUAL_LINE_MARK => ['red', 'bold'],
|
||||
self::LINE_NUMBER => ['dark_gray'],
|
||||
private const THEME = [
|
||||
self::TOKEN_STRING => ['light_gray'],
|
||||
self::TOKEN_COMMENT => ['dark_gray', 'italic'],
|
||||
self::TOKEN_KEYWORD => ['magenta', 'bold'],
|
||||
self::TOKEN_DEFAULT => ['default', 'bold'],
|
||||
self::TOKEN_HTML => ['blue', 'bold'],
|
||||
|
||||
self::ACTUAL_LINE_MARK => ['red', 'bold'],
|
||||
self::LINE_NUMBER => ['dark_gray'],
|
||||
self::MARKED_LINE_NUMBER => ['italic', 'bold'],
|
||||
self::LINE_NUMBER_DIVIDER => ['dark_gray'],
|
||||
];
|
||||
|
||||
const TOKEN_DEFAULT = 'token_default';
|
||||
const TOKEN_COMMENT = 'token_comment';
|
||||
const TOKEN_STRING = 'token_string';
|
||||
const TOKEN_HTML = 'token_html';
|
||||
const TOKEN_KEYWORD = 'token_keyword';
|
||||
|
||||
const ACTUAL_LINE_MARK = 'actual_line_mark';
|
||||
const LINE_NUMBER = 'line_number';
|
||||
|
||||
/** @var ConsoleColor */
|
||||
private $color;
|
||||
|
||||
/** @var array */
|
||||
private $defaultTheme = [
|
||||
private const DEFAULT_THEME = [
|
||||
self::TOKEN_STRING => 'red',
|
||||
self::TOKEN_COMMENT => 'yellow',
|
||||
self::TOKEN_KEYWORD => 'green',
|
||||
self::TOKEN_DEFAULT => 'default',
|
||||
self::TOKEN_HTML => 'cyan',
|
||||
|
||||
self::ACTUAL_LINE_MARK => 'red',
|
||||
self::LINE_NUMBER => 'dark_gray',
|
||||
self::ACTUAL_LINE_MARK => 'dark_gray',
|
||||
self::LINE_NUMBER => 'dark_gray',
|
||||
self::MARKED_LINE_NUMBER => 'dark_gray',
|
||||
self::LINE_NUMBER_DIVIDER => 'dark_gray',
|
||||
];
|
||||
/** @var string */
|
||||
private $delimiter = self::DELIMITER_UTF8;
|
||||
/** @var string */
|
||||
private $arrow = self::ARROW_SYMBOL_UTF8;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const NO_MARK = ' ';
|
||||
|
||||
/**
|
||||
* Creates an instance of the Highlighter.
|
||||
*/
|
||||
public function __construct(ConsoleColor $color = null)
|
||||
public function __construct(ConsoleColor $color = null, bool $UTF8 = true)
|
||||
{
|
||||
$this->color = $color ?: new ConsoleColor();
|
||||
|
||||
foreach ($this->defaultTheme as $name => $styles) {
|
||||
foreach (self::DEFAULT_THEME as $name => $styles) {
|
||||
if (!$this->color->hasTheme($name)) {
|
||||
$this->color->addTheme($name, $styles);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->theme as $name => $styles) {
|
||||
$this->color->addTheme((string) $name, $styles);
|
||||
foreach (self::THEME as $name => $styles) {
|
||||
$this->color->addTheme($name, $styles);
|
||||
}
|
||||
if (!$UTF8) {
|
||||
$this->delimiter = self::DELIMITER;
|
||||
$this->arrow = self::ARROW_SYMBOL;
|
||||
}
|
||||
$this->delimiter .= ' ';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,10 +104,8 @@ class Highlighter implements HighlighterContract
|
||||
* @param int $lineNumber
|
||||
* @param int $linesBefore
|
||||
* @param int $linesAfter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCodeSnippet($source, $lineNumber, $linesBefore = 2, $linesAfter = 2)
|
||||
public function getCodeSnippet($source, $lineNumber, $linesBefore = 2, $linesAfter = 2): string
|
||||
{
|
||||
$tokenLines = $this->getHighlightedLines($source);
|
||||
|
||||
@@ -113,10 +121,8 @@ class Highlighter implements HighlighterContract
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getHighlightedLines($source)
|
||||
private function getHighlightedLines($source): array
|
||||
{
|
||||
$source = str_replace(["\r\n", "\r"], "\n", $source);
|
||||
$tokens = $this->tokenize($source);
|
||||
@@ -126,10 +132,8 @@ class Highlighter implements HighlighterContract
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function tokenize($source)
|
||||
private function tokenize($source): array
|
||||
{
|
||||
$tokens = token_get_all($source);
|
||||
|
||||
@@ -148,7 +152,6 @@ class Highlighter implements HighlighterContract
|
||||
case T_CLOSE_TAG:
|
||||
case T_STRING:
|
||||
case T_VARIABLE:
|
||||
|
||||
// Constants
|
||||
case T_DIR:
|
||||
case T_FILE:
|
||||
@@ -204,10 +207,7 @@ class Highlighter implements HighlighterContract
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function splitToLines(array $tokens)
|
||||
private function splitToLines(array $tokens): array
|
||||
{
|
||||
$lines = [];
|
||||
|
||||
@@ -232,10 +232,7 @@ class Highlighter implements HighlighterContract
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function colorLines(array $tokenLines)
|
||||
private function colorLines(array $tokenLines): array
|
||||
{
|
||||
$lines = [];
|
||||
foreach ($tokenLines as $lineCount => $tokenLine) {
|
||||
@@ -256,24 +253,47 @@ class Highlighter implements HighlighterContract
|
||||
|
||||
/**
|
||||
* @param int|null $markLine
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function lineNumbers(array $lines, $markLine = null)
|
||||
private function lineNumbers(array $lines, $markLine = null): string
|
||||
{
|
||||
end($lines);
|
||||
$lineStrlen = strlen(key($lines) + 1);
|
||||
|
||||
$snippet = '';
|
||||
$lineStrlen = strlen((string) (array_key_last($lines) + 1));
|
||||
$lineStrlen = $lineStrlen < self::WIDTH ? self::WIDTH : $lineStrlen;
|
||||
$snippet = '';
|
||||
$mark = ' ' . $this->arrow . ' ';
|
||||
foreach ($lines as $i => $line) {
|
||||
if ($markLine !== null) {
|
||||
$snippet .= ($markLine === $i + 1 ? $this->color->apply(self::ACTUAL_LINE_MARK, ' > ') : ' ');
|
||||
}
|
||||
$coloredLineNumber = $this->coloredLineNumber(self::LINE_NUMBER, $i, $lineStrlen);
|
||||
|
||||
if (null !== $markLine) {
|
||||
$snippet .=
|
||||
($markLine === $i + 1
|
||||
? $this->color->apply(self::ACTUAL_LINE_MARK, $mark)
|
||||
: self::NO_MARK
|
||||
);
|
||||
|
||||
$coloredLineNumber =
|
||||
($markLine === $i + 1 ?
|
||||
$this->coloredLineNumber(self::MARKED_LINE_NUMBER, $i, $lineStrlen) :
|
||||
$coloredLineNumber
|
||||
);
|
||||
}
|
||||
$snippet .= $coloredLineNumber;
|
||||
|
||||
$snippet .=
|
||||
$this->color->apply(self::LINE_NUMBER_DIVIDER, $this->delimiter);
|
||||
|
||||
$snippet .= $this->color->apply(self::LINE_NUMBER, str_pad($i + 1, $lineStrlen, ' ', STR_PAD_LEFT) . '| ');
|
||||
$snippet .= $line . PHP_EOL;
|
||||
}
|
||||
|
||||
return $snippet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $style
|
||||
* @param int $i
|
||||
* @param int $lineStrlen
|
||||
*/
|
||||
private function coloredLineNumber($style, $i, $lineStrlen): string
|
||||
{
|
||||
return $this->color->apply($style, str_pad((string) ($i + 1), $lineStrlen, ' ', STR_PAD_LEFT));
|
||||
}
|
||||
}
|
||||
|
||||
15
vendor/nunomaduro/collision/src/Provider.php
vendored
15
vendor/nunomaduro/collision/src/Provider.php
vendored
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision;
|
||||
|
||||
@@ -17,11 +10,11 @@ use Whoops\Run;
|
||||
use Whoops\RunInterface;
|
||||
|
||||
/**
|
||||
* This is an Collision Provider implementation.
|
||||
* @internal
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @see \Tests\Unit\ProviderTest
|
||||
*/
|
||||
class Provider implements ProviderContract
|
||||
final class Provider implements ProviderContract
|
||||
{
|
||||
/**
|
||||
* Holds an instance of the Run.
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision\SolutionsRepositories;
|
||||
|
||||
@@ -15,11 +8,9 @@ use NunoMaduro\Collision\Contracts\SolutionsRepository;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* This is an Collision Null Solutions Provider implementation.
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @internal
|
||||
*/
|
||||
class NullSolutionsRepository implements SolutionsRepository
|
||||
final class NullSolutionsRepository implements SolutionsRepository
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
58
vendor/nunomaduro/collision/src/Writer.php
vendored
58
vendor/nunomaduro/collision/src/Writer.php
vendored
@@ -1,18 +1,13 @@
|
||||
<?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.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace NunoMaduro\Collision;
|
||||
|
||||
use NunoMaduro\Collision\Contracts\ArgumentFormatter as ArgumentFormatterContract;
|
||||
use NunoMaduro\Collision\Contracts\Highlighter as HighlighterContract;
|
||||
use NunoMaduro\Collision\Contracts\RenderlessEditor;
|
||||
use NunoMaduro\Collision\Contracts\RenderlessTrace;
|
||||
use NunoMaduro\Collision\Contracts\SolutionsRepository;
|
||||
use NunoMaduro\Collision\Contracts\Writer as WriterContract;
|
||||
use NunoMaduro\Collision\SolutionsRepositories\NullSolutionsRepository;
|
||||
@@ -22,16 +17,16 @@ use Whoops\Exception\Frame;
|
||||
use Whoops\Exception\Inspector;
|
||||
|
||||
/**
|
||||
* This is an Collision Writer implementation.
|
||||
* @internal
|
||||
*
|
||||
* @author Nuno Maduro <enunomaduro@gmail.com>
|
||||
* @see \Tests\Unit\WriterTest
|
||||
*/
|
||||
class Writer implements WriterContract
|
||||
final class Writer implements WriterContract
|
||||
{
|
||||
/**
|
||||
* The number of frames if no verbosity is specified.
|
||||
*/
|
||||
const VERBOSITY_NORMAL_FRAMES = 1;
|
||||
public const VERBOSITY_NORMAL_FRAMES = 1;
|
||||
|
||||
/**
|
||||
* Holds an instance of the solutions repository.
|
||||
@@ -116,15 +111,20 @@ class Writer implements WriterContract
|
||||
|
||||
$editorFrame = array_shift($frames);
|
||||
|
||||
if ($this->showEditor && $editorFrame !== null) {
|
||||
$exception = $inspector->getException();
|
||||
|
||||
if ($this->showEditor
|
||||
&& $editorFrame !== null
|
||||
&& !$exception instanceof RenderlessEditor
|
||||
) {
|
||||
$this->renderEditor($editorFrame);
|
||||
}
|
||||
|
||||
$this->renderSolution($inspector);
|
||||
|
||||
if ($this->showTrace && !empty($frames)) {
|
||||
if ($this->showTrace && !empty($frames) && !$exception instanceof RenderlessTrace) {
|
||||
$this->renderTrace($frames);
|
||||
} else {
|
||||
} elseif (!$exception instanceof RenderlessEditor) {
|
||||
$this->output->writeln('');
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,10 @@ class Writer implements WriterContract
|
||||
}
|
||||
|
||||
foreach ($this->ignore as $ignore) {
|
||||
if (preg_match($ignore, $frame->getFile())) {
|
||||
// Ensure paths are linux-style (like the ones on $this->ignore)
|
||||
// @phpstan-ignore-next-line
|
||||
$sanitizedPath = (string) str_replace('\\', '/', $frame->getFile());
|
||||
if (preg_match($ignore, $sanitizedPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -267,15 +270,17 @@ class Writer implements WriterContract
|
||||
*/
|
||||
protected function renderEditor(Frame $frame): WriterContract
|
||||
{
|
||||
$file = $this->getFileRelativePath((string) $frame->getFile());
|
||||
if ($frame->getFile() !== 'Unknown') {
|
||||
$file = $this->getFileRelativePath((string) $frame->getFile());
|
||||
|
||||
// getLine() might return null so cast to int to get 0 instead
|
||||
$line = (int) $frame->getLine();
|
||||
$this->render('at <fg=green>' . $file . '</>' . ':<fg=green>' . $line . '</>');
|
||||
// getLine() might return null so cast to int to get 0 instead
|
||||
$line = (int) $frame->getLine();
|
||||
$this->render('at <fg=green>' . $file . '</>' . ':<fg=green>' . $line . '</>');
|
||||
|
||||
$content = $this->highlighter->highlight((string) $frame->getFileContents(), (int) $frame->getLine());
|
||||
$content = $this->highlighter->highlight((string) $frame->getFileContents(), (int) $frame->getLine());
|
||||
|
||||
$this->output->writeln($content);
|
||||
$this->output->writeln($content);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -317,15 +322,6 @@ class Writer implements WriterContract
|
||||
$this->render("<fg=white> $class$function($args)</>", false);
|
||||
}
|
||||
|
||||
/* Let's consider add this later...
|
||||
* if ($vendorFrames > 0) {
|
||||
* $this->output->write(
|
||||
* sprintf("\n \e[2m+%s vendor frames \e[22m\n", $vendorFrames)
|
||||
* );
|
||||
* $vendorFrames = 0;
|
||||
* }.
|
||||
*/
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user