laravel-dump-server icon indicating copy to clipboard operation
laravel-dump-server copied to clipboard

Using --format=html while debugging unit tests with $this->json(...$args)->dump(); throws exception

Open edvordo opened this issue 6 years ago • 0 comments

Simillar to #9 (I guess?) I'm getting an exception while running unit test and try to debug a request with the ->dump() helper, such as

class CategoryModuleTest extends TestCase
{
    public function testAdminCanAccessCategoriesModule()
    {
        $this->signIn(Admin::first());

        $this->json('GET', route('web.api.lists.categories.index'))
            ->dump()
            ->assertOk()
            ->assertJsonCount(1, 'meta.order');
    }
}
Symfony\Component\Debug\Exception\FatalThrowableError  : Argument 1 passed to Symfony\Component\VarDumper\Dumper\HtmlDumper::dump() must be an instance of Symfony\Component\VarDumper\Cloner\Data, null given, called in C:\path\to\project\vendor\symfony\var-dumper\Command\Descriptor\HtmlDescriptor.php on line 47
--
  |  
  | at C:\path\to\project\vendor\symfony\var-dumper\Dumper\HtmlDumper.php:111
  | 107\|
  | 108\|     /**
  | 109\|      * {@inheritdoc}
  | 110\|      */
  | > 111\|     public function dump(Data $data, $output = null, array $extraDisplayOptions = array())
  | 112\|     {
  | 113\|         $this->extraDisplayOptions = $extraDisplayOptions;
  | 114\|         $result = parent::dump($data, $output);
  | 115\|         $this->dumpId = 'sf-dump-'.mt_rand();
  |  
  | Exception trace:
  |  
  | 1   Symfony\Component\VarDumper\Dumper\HtmlDumper::dump([])
  | C:\path\to\project\vendor\symfony\var-dumper\Command\Descriptor\HtmlDescriptor.php:47
  |  
  | 2   Symfony\Component\VarDumper\Command\Descriptor\HtmlDescriptor::describe(Object(Symfony\Component\Console\Style\SymfonyStyle), Object(Symfony\Component\VarDumper\Cloner\Data), [])
  | C:\path\to\project\vendor\beyondcode\laravel-dump-server\src\DumpServerCommand.php:81
  |  
  | 3   BeyondCode\DumpServer\DumpServerCommand::BeyondCode\DumpServer\{closure}(Object(Symfony\Component\VarDumper\Cloner\Data), [])
  | C:\path\to\project\vendor\symfony\var-dumper\Server\DumpServer.php:76
  |  
  | 4   Symfony\Component\VarDumper\Server\DumpServer::listen(Object(Closure))
  | C:\path\to\project\vendor\beyondcode\laravel-dump-server\src\DumpServerCommand.php:82
  |  
  | 5   BeyondCode\DumpServer\DumpServerCommand::handle()
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:29
  |  
  | 6   call_user_func_array([])
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:29
  |  
  | 7   Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:87
  |  
  | 8   Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Object(Closure))
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:31
  |  
  | 9   Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), [])
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Container\Container.php:572
  |  
  | 10  Illuminate\Container\Container::call()
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Console\Command.php:183
  |  
  | 11  Illuminate\Console\Command::execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
  | C:\path\to\project\vendor\symfony\console\Command\Command.php:255
  |  
  | 12  Symfony\Component\Console\Command\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Console\Command.php:170
  |  
  | 13  Illuminate\Console\Command::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  | C:\path\to\project\vendor\symfony\console\Application.php:886
  |  
  | 14  Symfony\Component\Console\Application::doRunCommand(Object(BeyondCode\DumpServer\DumpServerCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  | C:\path\to\project\vendor\symfony\console\Application.php:262
  |  
  | 15  Symfony\Component\Console\Application::doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  | C:\path\to\project\vendor\symfony\console\Application.php:145
  |  
  | 16  Symfony\Component\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Console\Application.php:89
  |  
  | 17  Illuminate\Console\Application::run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  | C:\path\to\project\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:122
  |  
  | 18  Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  | C:\path\to\project\artisan:37

The problem here is that $this->currentRequest->route() returns null since the $routeResolver is null and so the $controller stays set to null and HtmlDumper just doesn't like it.

I've solved my issue by adding this to the RequestContextProvider



    /**
     * Get the context.
     *
     * @return array|null
     */
    public function getContext(): ?array
    {
        if ($this->currentRequest === null) {
            return null;
        }

        $controller = null;

        if ($route = $this->currentRequest->route()) {
            $controller = $route->controller;

            if (! $controller && ! is_string($route->action['uses'])) {
                $controller = $route->action['uses'];
            }
        }

        if (app()->runningUnitTests()) {
            $controller = $this->guessPHPUnitTestController($this->currentRequest->server->get('argv'));
        }

        return [
            'uri' => $this->currentRequest->getUri(),
            'method' => $this->currentRequest->getMethod(),
            'controller' => $controller ? $this->cloner->cloneVar(class_basename($controller)) : $controller,
            'identifier' => spl_object_hash($this->currentRequest),
        ];
    }

    /**
     * Try to provide as much information to the dump as possible
     *
     * @param array $args
     *
     * @return string
     */
    private function guessPHPUnitTestController(array $args)
    {
        $controller = TestCase::class;

        var_export($args);

        if (false === in_array('--filter', $args)) {
            return $controller;
        }

        if (preg_match('/^[A-Z][a-zA-Z]+Test$/', $args[2])) {
            return $args[2];
        }

        if (preg_match('/^test[A-Z][0-9a-zA-Z]+/', $args[2])) {
            return $controller . '::' . $args[2];
        }

        return $controller;
    }

which produces image

If this way is okay for you, I can create PR with this solution :)

edvordo avatar Nov 02 '18 10:11 edvordo