Skip to content

Commit

Permalink
[10.x] Adds make:view Artisan command (laravel#48330)
Browse files Browse the repository at this point in the history
* Adds `make:view` Artisan command

* Style

* Sorts method names

* Renames

* formatting

* formatting

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
2 people authored and coppolafab committed Sep 8, 2023
1 parent 50f2028 commit 3c3ff64
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 0 deletions.
236 changes: 236 additions & 0 deletions src/Illuminate/Foundation/Console/ViewMakeCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
<?php

namespace Illuminate\Foundation\Console;

use Illuminate\Console\Concerns\CreatesMatchingTest;
use Illuminate\Console\GeneratorCommand;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputOption;

#[AsCommand(name: 'make:view')]
class ViewMakeCommand extends GeneratorCommand
{
use CreatesMatchingTest;

/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new view';

/**
* The name and signature of the console command.
*
* @var string
*/
protected $name = 'make:view';

/**
* The type of file being generated.
*
* @var string
*/
protected $type = 'View';

/**
* Build the class with the given name.
*
* @param string $name
* @return string
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
protected function buildClass($name)
{
$contents = parent::buildClass($name);

return str_replace(
'{{ quote }}',
Inspiring::quotes()->random(),
$contents,
);
}

/**
* Get the destination view path.
*
* @param string $name
* @return string
*/
protected function getPath($name)
{
return $this->viewPath(
$this->getNameInput().'.'.$this->option('extension'),
);
}

/**
* Get the desired view name from the input.
*
* @return string
*/
protected function getNameInput()
{
$name = trim($this->argument('name'));

$name = str_replace(['\\', '.'], '/', $this->argument('name'));

return $name;
}

/**
* Get the stub file for the generator.
*
* @return string
*/
protected function getStub()
{
return $this->resolveStubPath(
'/stubs/view.stub',
);
}

/**
* Resolve the fully-qualified path to the stub.
*
* @param string $stub
* @return string
*/
protected function resolveStubPath($stub)
{
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
? $customPath
: __DIR__.$stub;
}

/**
* Get the destination test case path.
*
* @return string
*/
protected function getTestPath()
{
return base_path(
Str::of($this->testClassFullyQualifiedName())
->replace('\\', '/')
->replaceFirst('Tests/Feature', 'tests/Feature')
->append('Test.php')
->value()
);
}

/**
* Create the matching test case if requested.
*
* @param string $path
*/
protected function handleTestCreation($path): bool
{
if (! $this->option('test') && ! $this->option('pest')) {
return false;
}

$contents = preg_replace(
['/\{{ namespace \}}/', '/\{{ class \}}/', '/\{{ name \}}/'],
[$this->testNamespace(), $this->testClassName(), $this->testViewName()],
File::get($this->getTestStub()),
);

File::ensureDirectoryExists(dirname($this->getTestPath()), 0755, true);

return File::put($this->getTestPath(), $contents);
}

/**
* Get the namespace for the test.
*
* @return string
*/
protected function testNamespace()
{
return Str::of($this->testClassFullyQualifiedName())
->beforeLast('\\')
->value();
}

/**
* Get the class name for the test.
*
* @return string
*/
protected function testClassName()
{
return Str::of($this->testClassFullyQualifiedName())
->afterLast('\\')
->append('Test')
->value();
}

/**
* Get the class fully qualified name for the test.
*
* @return string
*/
protected function testClassFullyQualifiedName()
{
$name = Str::of(Str::lower($this->getNameInput()))->replace('.'.$this->option('extension'), '');

$namespacedName = Str::of(
Str::of($name)
->replace('/', ' ')
->explode(' ')
->map(fn ($part) => Str::of($part)->ucfirst())
->implode('\\')
)
->replace(['-', '_'], ' ')
->explode(' ')
->map(fn ($part) => Str::of($part)->ucfirst())
->implode('');

return 'Tests\\Feature\\View\\'.$namespacedName;
}

/**
* Get the test stub file for the generator.
*
* @return string
*/
protected function getTestStub()
{
$stubName = 'view.'.($this->option('pest') ? 'pest' : 'test').'.stub';

return file_exists($customPath = $this->laravel->basePath("stubs/$stubName"))
? $customPath
: __DIR__.'/stubs/'.$stubName;
}

/**
* Get the view name for the test.
*
* @return string
*/
protected function testViewName()
{
return Str::of($this->getNameInput())
->replace('/', '.')
->lower()
->value();
}

/**
* Get the console command arguments.
*
* @return array
*/
protected function getOptions()
{
return [
['extension', null, InputOption::VALUE_OPTIONAL, 'The extension of the generated view', 'blade.php'],
['force', 'f', InputOption::VALUE_NONE, 'Create the view even if the view already exists'],
];
}
}
9 changes: 9 additions & 0 deletions src/Illuminate/Foundation/Console/stubs/view.pest.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

it('can render', function () {
$contents = $this->view('{{ name }}', [
//
]);

$contents->assertSee('');
});
3 changes: 3 additions & 0 deletions src/Illuminate/Foundation/Console/stubs/view.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
<!-- {{ quote }} -->
</div>
20 changes: 20 additions & 0 deletions src/Illuminate/Foundation/Console/stubs/view.test.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace {{ namespace }};

use Tests\TestCase;

class {{ class }} extends TestCase
{
/**
* A basic view test example.
*/
public function test_it_can_render(): void
{
$contents = $this->view('{{ name }}', [
//
]);

$contents->assertSee('');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
use Illuminate\Foundation\Console\VendorPublishCommand;
use Illuminate\Foundation\Console\ViewCacheCommand;
use Illuminate\Foundation\Console\ViewClearCommand;
use Illuminate\Foundation\Console\ViewMakeCommand;
use Illuminate\Notifications\Console\NotificationTableCommand;
use Illuminate\Queue\Console\BatchesTableCommand;
use Illuminate\Queue\Console\ClearCommand as QueueClearCommand;
Expand Down Expand Up @@ -204,6 +205,7 @@ class ArtisanServiceProvider extends ServiceProvider implements DeferrableProvid
'StubPublish' => StubPublishCommand::class,
'TestMake' => TestMakeCommand::class,
'VendorPublish' => VendorPublishCommand::class,
'ViewMake' => ViewMakeCommand::class,
];

/**
Expand Down

0 comments on commit 3c3ff64

Please sign in to comment.