-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[10.x] Adds
make:view
Artisan command (#48330)
* Adds `make:view` Artisan command * Style * Sorts method names * Renames * formatting * formatting --------- Co-authored-by: Taylor Otwell <[email protected]>
- Loading branch information
1 parent
1591fed
commit 3caca4c
Showing
5 changed files
with
270 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(''); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div> | ||
<!-- {{ quote }} --> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(''); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters