diff --git a/composer.json b/composer.json index d4ac7f674f0e..ce24f8536bd3 100644 --- a/composer.json +++ b/composer.json @@ -104,7 +104,7 @@ "league/flysystem-read-only": "^3.3", "league/flysystem-sftp-v3": "^3.0", "mockery/mockery": "^1.5.1", - "orchestra/testbench-core": "^8.4", + "orchestra/testbench-core": "^8.10", "pda/pheanstalk": "^4.0", "phpstan/phpstan": "^1.4.7", "phpunit/phpunit": "^10.0.7", diff --git a/tests/Integration/Generators/CastMakeCommandTest.php b/tests/Integration/Generators/CastMakeCommandTest.php new file mode 100644 index 000000000000..dbbc5ad98dd1 --- /dev/null +++ b/tests/Integration/Generators/CastMakeCommandTest.php @@ -0,0 +1,37 @@ +artisan('make:cast', ['name' => 'Foo']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Casts;', + 'use Illuminate\Contracts\Database\Eloquent\CastsAttributes;', + 'class Foo implements CastsAttributes', + 'public function get(Model $model, string $key, mixed $value, array $attributes): mixed', + 'public function set(Model $model, string $key, mixed $value, array $attributes): mixed', + ], 'app/Casts/Foo.php'); + } + + public function testItCanGenerateInboundCastFile() + { + $this->artisan('make:cast', ['name' => 'Foo', '--inbound' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Casts;', + 'use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;', + 'class Foo implements CastsInboundAttributes', + 'public function set(Model $model, string $key, mixed $value, array $attributes): mixed', + ], 'app/Casts/Foo.php'); + } +} diff --git a/tests/Integration/Generators/ChannelMakeCommandTest.php b/tests/Integration/Generators/ChannelMakeCommandTest.php new file mode 100644 index 000000000000..1c75ffda28c8 --- /dev/null +++ b/tests/Integration/Generators/ChannelMakeCommandTest.php @@ -0,0 +1,22 @@ +artisan('make:channel', ['name' => 'FooChannel']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Broadcasting;', + 'use Illuminate\Foundation\Auth\User;', + 'class FooChannel', + ], 'app/Broadcasting/FooChannel.php'); + } +} diff --git a/tests/Integration/Generators/ComponentMakeCommandTest.php b/tests/Integration/Generators/ComponentMakeCommandTest.php new file mode 100644 index 000000000000..fc1651ec7d95 --- /dev/null +++ b/tests/Integration/Generators/ComponentMakeCommandTest.php @@ -0,0 +1,53 @@ +artisan('make:component', ['name' => 'Foo']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\View\Components;', + 'use Illuminate\View\Component;', + 'class Foo extends Component', + "return view('components.foo');", + ], 'app/View/Components/Foo.php'); + + $this->assertFilenameExists('resources/views/components/foo.blade.php'); + $this->assertFilenameNotExists('tests/Feature/View/Components/FooTest.php'); + } + + public function testItCanGenerateInlineComponentFile() + { + $this->artisan('make:component', ['name' => 'Foo', '--inline' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\View\Components;', + 'use Illuminate\View\Component;', + 'class Foo extends Component', + "return <<<'blade'", + ], 'app/View/Components/Foo.php'); + + $this->assertFilenameNotExists('resources/views/components/foo.blade.php'); + } + + public function testItCanGenerateComponentFileWithTest() + { + $this->artisan('make:component', ['name' => 'Foo', '--test' => true]) + ->assertExitCode(0); + + $this->assertFilenameExists('app/View/Components/Foo.php'); + $this->assertFilenameExists('resources/views/components/foo.blade.php'); + $this->assertFilenameExists('tests/Feature/View/Components/FooTest.php'); + } +} diff --git a/tests/Integration/Generators/ControllerMakeCommandTest.php b/tests/Integration/Generators/ControllerMakeCommandTest.php new file mode 100644 index 000000000000..c0c27c3b4e24 --- /dev/null +++ b/tests/Integration/Generators/ControllerMakeCommandTest.php @@ -0,0 +1,169 @@ +artisan('make:controller', ['name' => 'FooController']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use Illuminate\Http\Request;', + 'class FooController extends Controller', + ], 'app/Http/Controllers/FooController.php'); + + $this->assertFileNotContains([ + 'public function __invoke(Request $request)', + ], 'app/Http/Controllers/FooController.php'); + + $this->assertFilenameNotExists('tests/Feature/Http/Controllers/FooControllerTest.php'); + } + + public function testItCanGenerateControllerFileWithInvokableTypeOption() + { + $this->artisan('make:controller', ['name' => 'FooController', '--type' => 'invokable']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use Illuminate\Http\Request;', + 'class FooController extends Controller', + 'public function __invoke(Request $request)', + ], 'app/Http/Controllers/FooController.php'); + } + + public function testItCanGenerateControllerFileWithInvokableOption() + { + $this->artisan('make:controller', ['name' => 'FooController', '--invokable' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use Illuminate\Http\Request;', + 'class FooController extends Controller', + 'public function __invoke(Request $request)', + ], 'app/Http/Controllers/FooController.php'); + } + + public function testItCanGenerateControllerFileWithModelOption() + { + $this->artisan('make:controller', ['name' => 'FooController', '--model' => 'Foo']) + ->expectsQuestion('A App\Models\Foo model does not exist. Do you want to generate it?', false) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use App\Models\Foo;', + 'public function index()', + 'public function create()', + 'public function store(Request $request)', + 'public function show(Foo $foo)', + 'public function edit(Foo $foo)', + 'public function update(Request $request, Foo $foo)', + 'public function destroy(Foo $foo)', + ], 'app/Http/Controllers/FooController.php'); + } + + public function testItCanGenerateControllerFileWithModelAndParentOption() + { + $this->artisan('make:controller', ['name' => 'FooController', '--model' => 'Bar', '--parent' => 'Foo']) + ->expectsQuestion('A App\Models\Foo model does not exist. Do you want to generate it?', false) + ->expectsQuestion('A App\Models\Bar model does not exist. Do you want to generate it?', false) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use App\Models\Bar;', + 'use App\Models\Foo;', + 'public function index(Foo $foo)', + 'public function create(Foo $foo)', + 'public function store(Request $request, Foo $foo)', + 'public function show(Foo $foo, Bar $bar)', + 'public function edit(Foo $foo, Bar $bar)', + 'public function update(Request $request, Foo $foo, Bar $bar)', + 'public function destroy(Foo $foo, Bar $bar)', + ], 'app/Http/Controllers/FooController.php'); + } + + public function testItCanGenerateControllerFileWithApiOption() + { + $this->artisan('make:controller', ['name' => 'FooController', '--api' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use Illuminate\Http\Request;', + 'class FooController extends Controller', + 'public function index()', + 'public function store(Request $request)', + 'public function update(Request $request, string $id)', + 'public function destroy(string $id)', + ], 'app/Http/Controllers/FooController.php'); + + $this->assertFileNotContains([ + 'public function create()', + 'public function edit($id)', + ], 'app/Http/Controllers/FooController.php'); + } + + public function testItCanGenerateControllerFileWithInvokableIgnoresApiOption() + { + $this->artisan('make:controller', ['name' => 'FooController', '--api' => true, '--invokable' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use Illuminate\Http\Request;', + 'class FooController extends Controller', + 'public function __invoke(Request $request)', + ], 'app/Http/Controllers/FooController.php'); + + $this->assertFileNotContains([ + 'public function index()', + 'public function store(Request $request)', + 'public function update(Request $request, $id)', + 'public function destroy($id)', + ], 'app/Http/Controllers/FooController.php'); + } + + public function testItCanGenerateControllerFileWithApiAndModelOption() + { + $this->artisan('make:controller', ['name' => 'FooController', '--model' => 'Foo', '--api' => true]) + ->expectsQuestion('A App\Models\Foo model does not exist. Do you want to generate it?', false) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use App\Models\Foo;', + 'public function index()', + 'public function store(Request $request)', + 'public function show(Foo $foo)', + 'public function update(Request $request, Foo $foo)', + 'public function destroy(Foo $foo)', + ], 'app/Http/Controllers/FooController.php'); + + $this->assertFileNotContains([ + 'public function create()', + 'public function edit(Foo $foo)', + ], 'app/Http/Controllers/FooController.php'); + } + + public function testItCanGenerateControllerFileWithTest() + { + $this->artisan('make:controller', ['name' => 'FooController', '--test' => true]) + ->assertExitCode(0); + + $this->assertFilenameExists('app/Http/Controllers/FooController.php'); + $this->assertFilenameExists('tests/Feature/Http/Controllers/FooControllerTest.php'); + } +} diff --git a/tests/Integration/Generators/EventMakeCommandTest.php b/tests/Integration/Generators/EventMakeCommandTest.php new file mode 100644 index 000000000000..eb3f05fa06c6 --- /dev/null +++ b/tests/Integration/Generators/EventMakeCommandTest.php @@ -0,0 +1,21 @@ +artisan('make:event', ['name' => 'FooCreated']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Events;', + 'class FooCreated', + ], 'app/Events/FooCreated.php'); + } +} diff --git a/tests/Integration/Generators/ExceptionMakeCommandTest.php b/tests/Integration/Generators/ExceptionMakeCommandTest.php new file mode 100644 index 000000000000..9876630c7452 --- /dev/null +++ b/tests/Integration/Generators/ExceptionMakeCommandTest.php @@ -0,0 +1,75 @@ +artisan('make:exception', ['name' => 'FooException']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Exceptions;', + 'use Exception;', + 'class FooException extends Exception', + ], 'app/Exceptions/FooException.php'); + + $this->assertFileNotContains([ + 'public function report()', + 'public function render($request)', + ], 'app/Exceptions/FooException.php'); + } + + public function testItCanGenerateExceptionFileWithReportOption() + { + $this->artisan('make:exception', ['name' => 'FooException', '--report' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Exceptions;', + 'use Exception;', + 'class FooException extends Exception', + 'public function report()', + ], 'app/Exceptions/FooException.php'); + + $this->assertFileNotContains([ + 'public function render($request)', + ], 'app/Exceptions/FooException.php'); + } + + public function testItCanGenerateExceptionFileWithRenderOption() + { + $this->artisan('make:exception', ['name' => 'FooException', '--render' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Exceptions;', + 'use Exception;', + 'class FooException extends Exception', + 'public function render(Request $request): Response', + ], 'app/Exceptions/FooException.php'); + + $this->assertFileNotContains([ + 'public function report()', + ], 'app/Exceptions/FooException.php'); + } + + public function testItCanGenerateExceptionFileWithReportAndRenderOption() + { + $this->artisan('make:exception', ['name' => 'FooException', '--report' => true, '--render' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Exceptions;', + 'use Exception;', + 'class FooException extends Exception', + 'public function render(Request $request): Response', + 'public function report()', + ], 'app/Exceptions/FooException.php'); + } +} diff --git a/tests/Integration/Generators/FactoryMakeCommandTest.php b/tests/Integration/Generators/FactoryMakeCommandTest.php new file mode 100644 index 000000000000..02ec76943c99 --- /dev/null +++ b/tests/Integration/Generators/FactoryMakeCommandTest.php @@ -0,0 +1,24 @@ +artisan('make:factory', ['name' => 'FooFactory']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace Database\Factories;', + 'use Illuminate\Database\Eloquent\Factories\Factory;', + 'class FooFactory extends Factory', + 'public function definition()', + ], 'database/factories/FooFactory.php'); + } +} diff --git a/tests/Integration/Generators/JobMakeCommandTest.php b/tests/Integration/Generators/JobMakeCommandTest.php new file mode 100644 index 000000000000..0d1d1479128a --- /dev/null +++ b/tests/Integration/Generators/JobMakeCommandTest.php @@ -0,0 +1,56 @@ +artisan('make:job', ['name' => 'FooCreated']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Jobs;', + 'use Illuminate\Bus\Queueable;', + 'use Illuminate\Contracts\Queue\ShouldQueue;', + 'use Illuminate\Foundation\Bus\Dispatchable;', + 'use Illuminate\Queue\InteractsWithQueue;', + 'use Illuminate\Queue\SerializesModels;', + 'class FooCreated implements ShouldQueue', + ], 'app/Jobs/FooCreated.php'); + + $this->assertFilenameNotExists('tests/Feature/Jobs/FooCreatedTest.php'); + } + + public function testItCanGenerateSyncJobFile() + { + $this->artisan('make:job', ['name' => 'FooCreated', '--sync' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Jobs;', + 'use Illuminate\Foundation\Bus\Dispatchable;', + 'class FooCreated', + ], 'app/Jobs/FooCreated.php'); + + $this->assertFileNotContains([ + 'use Illuminate\Contracts\Queue\ShouldQueue;', + 'use Illuminate\Queue\InteractsWithQueue;', + 'use Illuminate\Queue\SerializesModels;', + ], 'app/Jobs/FooCreated.php'); + } + + public function testItCanGenerateJobFileWithTest() + { + $this->artisan('make:job', ['name' => 'FooCreated', '--test' => true]) + ->assertExitCode(0); + + $this->assertFilenameExists('app/Jobs/FooCreated.php'); + $this->assertFilenameExists('tests/Feature/Jobs/FooCreatedTest.php'); + } +} diff --git a/tests/Integration/Generators/MailMakeCommandTest.php b/tests/Integration/Generators/MailMakeCommandTest.php new file mode 100644 index 000000000000..8da9c0785ccc --- /dev/null +++ b/tests/Integration/Generators/MailMakeCommandTest.php @@ -0,0 +1,58 @@ +artisan('make:mail', ['name' => 'FooMail']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Mail;', + 'use Illuminate\Mail\Mailable;', + 'class FooMail extends Mailable', + ], 'app/Mail/FooMail.php'); + + $this->assertFilenameNotExists('resources/views/foo-mail.blade.php'); + $this->assertFilenameNotExists('tests/Feature/Mail/FooMailTest.php'); + } + + public function testItCanGenerateMailFileWithMarkdownOption() + { + $this->artisan('make:mail', ['name' => 'FooMail', '--markdown' => 'foo-mail']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Mail;', + 'use Illuminate\Mail\Mailable;', + 'class FooMail extends Mailable', + 'return new Content(', + "markdown: 'foo-mail',", + ], 'app/Mail/FooMail.php'); + + $this->assertFileContains([ + '', + '', + '', + '', + ], 'resources/views/foo-mail.blade.php'); + } + + public function testItCanGenerateMailFileWithTest() + { + $this->artisan('make:mail', ['name' => 'FooMail', '--test' => true]) + ->assertExitCode(0); + + $this->assertFilenameExists('app/Mail/FooMail.php'); + $this->assertFilenameNotExists('resources/views/foo-mail.blade.php'); + $this->assertFilenameExists('tests/Feature/Mail/FooMailTest.php'); + } +} diff --git a/tests/Integration/Generators/MiddlewareMakeCommandTest.php b/tests/Integration/Generators/MiddlewareMakeCommandTest.php new file mode 100644 index 000000000000..604dd8c0e921 --- /dev/null +++ b/tests/Integration/Generators/MiddlewareMakeCommandTest.php @@ -0,0 +1,37 @@ +artisan('make:middleware', ['name' => 'Foo']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Middleware;', + 'use Closure;', + 'use Illuminate\Http\Request;', + 'class Foo', + 'public function handle(Request $request, Closure $next)', + 'return $next($request);', + ], 'app/Http/Middleware/Foo.php'); + + $this->assertFilenameNotExists('tests/Feature/Http/Middleware/FooTest.php'); + } + + public function testItCanGenerateMiddlewareFile_with_tests() + { + $this->artisan('make:middleware', ['name' => 'Foo', '--test' => true]) + ->assertExitCode(0); + + $this->assertFilenameExists('app/Http/Middleware/Foo.php'); + $this->assertFilenameExists('tests/Feature/Http/Middleware/FooTest.php'); + } +} diff --git a/tests/Integration/Generators/MigrateMakeCommandTest.php b/tests/Integration/Generators/MigrateMakeCommandTest.php new file mode 100644 index 000000000000..fd2ef65adc8f --- /dev/null +++ b/tests/Integration/Generators/MigrateMakeCommandTest.php @@ -0,0 +1,56 @@ +artisan('make:migration', ['name' => 'AddBarToFoosTable']) + ->assertExitCode(0); + + $this->assertMigrationFileContains([ + 'use Illuminate\Database\Migrations\Migration;', + 'return new class extends Migration', + 'Schema::table(\'foos\', function (Blueprint $table) {', + ], 'add_bar_to_foos_table.php'); + } + + public function testItCanGenerateMigrationFileWIthTableOption() + { + $this->artisan('make:migration', ['name' => 'AddBarToFoosTable', '--table' => 'foobar']) + ->assertExitCode(0); + + $this->assertMigrationFileContains([ + 'use Illuminate\Database\Migrations\Migration;', + 'return new class extends Migration', + 'Schema::table(\'foobar\', function (Blueprint $table) {', + ], 'add_bar_to_foos_table.php'); + } + + public function testItCanGenerateMigrationFileUsingCreateKeyword() + { + $this->artisan('make:migration', ['name' => 'CreateFoosTable']) + ->assertExitCode(0); + + $this->assertMigrationFileContains([ + 'use Illuminate\Database\Migrations\Migration;', + 'return new class extends Migration', + 'Schema::create(\'foos\', function (Blueprint $table) {', + 'Schema::dropIfExists(\'foos\');', + ], 'create_foos_table.php'); + } + + public function testItCanGenerateMigrationFileUsingCreateOption() + { + $this->artisan('make:migration', ['name' => 'FoosTable', '--create' => 'foobar']) + ->assertExitCode(0); + + $this->assertMigrationFileContains([ + 'use Illuminate\Database\Migrations\Migration;', + 'return new class extends Migration', + 'Schema::create(\'foobar\', function (Blueprint $table) {', + 'Schema::dropIfExists(\'foobar\');', + ], 'foos_table.php'); + } +} diff --git a/tests/Integration/Generators/ModelMakeCommandTest.php b/tests/Integration/Generators/ModelMakeCommandTest.php new file mode 100644 index 000000000000..3ab287ccbc6f --- /dev/null +++ b/tests/Integration/Generators/ModelMakeCommandTest.php @@ -0,0 +1,182 @@ +artisan('make:model', ['name' => 'Foo']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models;', + 'use Illuminate\Database\Eloquent\Model;', + 'class Foo extends Model', + ], 'app/Models/Foo.php'); + + $this->assertFilenameNotExists('app/Http/Controllers/FooController.php'); + $this->assertFilenameNotExists('database/factories/FooFactory.php'); + $this->assertFilenameNotExists('database/seeders/FooSeeder.php'); + $this->assertFilenameNotExists('tests/Feature/Models/FooTest.php'); + } + + public function testItCanGenerateModelFileWithPivotOption() + { + $this->artisan('make:model', ['name' => 'Foo', '--pivot' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models;', + 'use Illuminate\Database\Eloquent\Relations\Pivot;', + 'class Foo extends Pivot', + ], 'app/Models/Foo.php'); + } + + public function testItCanGenerateModelFileWithMorphPivotOption() + { + $this->artisan('make:model', ['name' => 'Foo', '--morph-pivot' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models;', + 'use Illuminate\Database\Eloquent\Relations\MorphPivot;', + 'class Foo extends MorphPivot', + ], 'app/Models/Foo.php'); + } + + public function testItCanGenerateModelFileWithControllerOption() + { + $this->artisan('make:model', ['name' => 'Foo', '--controller' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models;', + 'use Illuminate\Database\Eloquent\Model;', + 'class Foo extends Model', + ], 'app/Models/Foo.php'); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use Illuminate\Http\Request;', + 'class FooController extends Controller', + ], 'app/Http/Controllers/FooController.php'); + + $this->assertFileNotContains([ + 'use App\Models\Foo;', + 'public function index()', + 'public function create()', + 'public function store(Request $request)', + 'public function show(Foo $foo)', + 'public function edit(Foo $foo)', + 'public function update(Request $request, Foo $foo)', + 'public function destroy(Foo $foo)', + ], 'app/Http/Controllers/FooController.php'); + + $this->assertFilenameNotExists('database/factories/FooFactory.php'); + $this->assertFilenameNotExists('database/seeders/FooSeeder.php'); + } + + public function testItCanGenerateModelFileWithFactoryOption() + { + $this->artisan('make:model', ['name' => 'Foo', '--factory' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models;', + 'use Illuminate\Database\Eloquent\Model;', + 'class Foo extends Model', + ], 'app/Models/Foo.php'); + + $this->assertFilenameNotExists('app/Http/Controllers/FooController.php'); + $this->assertFilenameExists('database/factories/FooFactory.php'); + $this->assertFilenameNotExists('database/seeders/FooSeeder.php'); + } + + public function testItCanGenerateModelFileWithMigrationOption() + { + $this->artisan('make:model', ['name' => 'Foo', '--migration' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models;', + 'use Illuminate\Database\Eloquent\Model;', + 'class Foo extends Model', + ], 'app/Models/Foo.php'); + + $this->assertMigrationFileContains([ + 'use Illuminate\Database\Migrations\Migration;', + 'return new class extends Migration', + 'Schema::create(\'foos\', function (Blueprint $table) {', + 'Schema::dropIfExists(\'foos\');', + ], 'create_foos_table.php'); + + $this->assertFilenameNotExists('app/Http/Controllers/FooController.php'); + $this->assertFilenameNotExists('database/factories/FooFactory.php'); + $this->assertFilenameNotExists('database/seeders/FooSeeder.php'); + } + + public function testItCanGenerateModelFileWithSeederption() + { + $this->artisan('make:model', ['name' => 'Foo', '--seed' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models;', + 'use Illuminate\Database\Eloquent\Model;', + 'class Foo extends Model', + ], 'app/Models/Foo.php'); + + $this->assertFilenameNotExists('app/Http/Controllers/FooController.php'); + $this->assertFilenameNotExists('database/factories/FooFactory.php'); + $this->assertFilenameExists('database/seeders/FooSeeder.php'); + } + + public function testItCanGenerateNestedModelFileWithControllerOption() + { + $this->artisan('make:model', ['name' => 'Foo/Bar', '--controller' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models\Foo;', + 'use Illuminate\Database\Eloquent\Model;', + 'class Bar extends Model', + ], 'app/Models/Foo/Bar.php'); + + $this->assertFileContains([ + 'namespace App\Http\Controllers;', + 'use Illuminate\Http\Request;', + 'class BarController extends Controller', + ], 'app/Http/Controllers/BarController.php'); + + $this->assertFilenameNotExists('database/factories/FooFactory.php'); + $this->assertFilenameNotExists('database/seeders/FooSeeder.php'); + } + + public function testItCanGenerateModelFileWithTest() + { + $this->artisan('make:model', ['name' => 'Foo', '--test' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Models;', + 'use Illuminate\Database\Eloquent\Model;', + 'class Foo extends Model', + ], 'app/Models/Foo.php'); + + $this->assertFilenameNotExists('app/Http/Controllers/FooController.php'); + $this->assertFilenameNotExists('database/factories/FooFactory.php'); + $this->assertFilenameNotExists('database/seeders/FooSeeder.php'); + $this->assertFilenameExists('tests/Feature/Models/FooTest.php'); + } +} diff --git a/tests/Integration/Generators/NotificationMakeCommandTest.php b/tests/Integration/Generators/NotificationMakeCommandTest.php new file mode 100644 index 000000000000..b2381c6811ba --- /dev/null +++ b/tests/Integration/Generators/NotificationMakeCommandTest.php @@ -0,0 +1,54 @@ +artisan('make:notification', ['name' => 'FooNotification']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Notifications;', + 'use Illuminate\Notifications\Notification;', + 'class FooNotification extends Notification', + 'return (new MailMessage)', + ], 'app/Notifications/FooNotification.php'); + + $this->assertFilenameNotExists('resources/views/foo-notification.blade.php'); + $this->assertFilenameNotExists('tests/Feature/Notifications/FooNotificationTest.php'); + } + + public function testItCanGenerateNotificationFileWithMarkdownOption() + { + $this->artisan('make:notification', ['name' => 'FooNotification', '--markdown' => 'foo-notification']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Notifications;', + 'class FooNotification extends Notification', + "return (new MailMessage)->markdown('foo-notification')", + ], 'app/Notifications/FooNotification.php'); + + $this->assertFileContains([ + '', + ], 'resources/views/foo-notification.blade.php'); + } + + public function testItCanGenerateNotificationFileWithTest() + { + $this->artisan('make:notification', ['name' => 'FooNotification', '--test' => true]) + ->assertExitCode(0); + + $this->assertFilenameExists('app/Notifications/FooNotification.php'); + $this->assertFilenameNotExists('resources/views/foo-notification.blade.php'); + $this->assertFilenameExists('tests/Feature/Notifications/FooNotificationTest.php'); + } +} diff --git a/tests/Integration/Generators/ObserverMakeCommandTest.php b/tests/Integration/Generators/ObserverMakeCommandTest.php new file mode 100644 index 000000000000..5ba618acca0f --- /dev/null +++ b/tests/Integration/Generators/ObserverMakeCommandTest.php @@ -0,0 +1,38 @@ +artisan('make:observer', ['name' => 'FooObserver']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Observers;', + 'class FooObserver', + ], 'app/Observers/FooObserver.php'); + } + + public function testItCanGenerateObserverFileWithModel() + { + $this->artisan('make:observer', ['name' => 'FooObserver', '--model' => 'Foo']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Observers;', + 'use App\Models\Foo;', + 'class FooObserver', + 'public function created(Foo $foo)', + 'public function updated(Foo $foo)', + 'public function deleted(Foo $foo)', + 'public function restored(Foo $foo)', + 'public function forceDeleted(Foo $foo)', + ], 'app/Observers/FooObserver.php'); + } +} diff --git a/tests/Integration/Generators/PolicyMakeCommandTest.php b/tests/Integration/Generators/PolicyMakeCommandTest.php new file mode 100644 index 000000000000..77f0cbbed049 --- /dev/null +++ b/tests/Integration/Generators/PolicyMakeCommandTest.php @@ -0,0 +1,42 @@ +artisan('make:policy', ['name' => 'FooPolicy']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Policies;', + 'use Illuminate\Foundation\Auth\User;', + 'class FooPolicy', + ], 'app/Policies/FooPolicy.php'); + } + + public function testItCanGeneratePolicyFileWithModelOption() + { + $this->artisan('make:policy', ['name' => 'FooPolicy', '--model' => 'Post']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Policies;', + 'use App\Models\Post;', + 'use Illuminate\Foundation\Auth\User;', + 'class FooPolicy', + 'public function viewAny(User $user)', + 'public function view(User $user, Post $post)', + 'public function create(User $user)', + 'public function update(User $user, Post $post)', + 'public function delete(User $user, Post $post)', + 'public function restore(User $user, Post $post)', + 'public function forceDelete(User $user, Post $post)', + ], 'app/Policies/FooPolicy.php'); + } +} diff --git a/tests/Integration/Generators/ProviderMakeCommandTest.php b/tests/Integration/Generators/ProviderMakeCommandTest.php new file mode 100644 index 000000000000..9f0416c6d312 --- /dev/null +++ b/tests/Integration/Generators/ProviderMakeCommandTest.php @@ -0,0 +1,24 @@ +artisan('make:provider', ['name' => 'FooServiceProvider']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Providers;', + 'use Illuminate\Support\ServiceProvider;', + 'class FooServiceProvider extends ServiceProvider', + 'public function register()', + 'public function boot()', + ], 'app/Providers/FooServiceProvider.php'); + } +} diff --git a/tests/Integration/Generators/RequestMakeCommandTest.php b/tests/Integration/Generators/RequestMakeCommandTest.php new file mode 100644 index 000000000000..584be86b58a3 --- /dev/null +++ b/tests/Integration/Generators/RequestMakeCommandTest.php @@ -0,0 +1,22 @@ +artisan('make:request', ['name' => 'FooRequest']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Requests;', + 'use Illuminate\Foundation\Http\FormRequest;', + 'class FooRequest extends FormRequest', + ], 'app/Http/Requests/FooRequest.php'); + } +} diff --git a/tests/Integration/Generators/ResourceMakeCommandTest.php b/tests/Integration/Generators/ResourceMakeCommandTest.php new file mode 100644 index 000000000000..b50b40872a85 --- /dev/null +++ b/tests/Integration/Generators/ResourceMakeCommandTest.php @@ -0,0 +1,37 @@ +artisan('make:resource', ['name' => 'FooResource']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Resources;', + 'use Illuminate\Http\Resources\Json\JsonResource;', + 'class FooResource extends JsonResource', + ], 'app/Http/Resources/FooResource.php'); + } + + /** @test */ + public function it_can_generate_resource_collection_file() + { + $this->artisan('make:resource', ['name' => 'FooResourceCollection', '--collection' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Http\Resources;', + 'use Illuminate\Http\Resources\Json\ResourceCollection;', + 'class FooResourceCollection extends ResourceCollection', + ], 'app/Http/Resources/FooResourceCollection.php'); + } +} diff --git a/tests/Integration/Generators/RuleMakeCommandTest.php b/tests/Integration/Generators/RuleMakeCommandTest.php new file mode 100644 index 000000000000..770672a71937 --- /dev/null +++ b/tests/Integration/Generators/RuleMakeCommandTest.php @@ -0,0 +1,49 @@ +artisan('make:rule', ['name' => 'Foo']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Rules;', + 'use Illuminate\Contracts\Validation\ValidationRule;', + 'class Foo implements ValidationRule', + ], 'app/Rules/Foo.php'); + } + + public function testItCanGenerateInvokableRuleFile() + { + $this->artisan('make:rule', ['name' => 'Foo']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Rules;', + 'use Illuminate\Contracts\Validation\ValidationRule;', + 'class Foo implements ValidationRule', + 'public function validate(string $attribute, mixed $value, Closure $fail): void', + ], 'app/Rules/Foo.php'); + } + + public function testItCanGenerateImplicitRuleFile() + { + $this->artisan('make:rule', ['name' => 'Foo', '--implicit' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace App\Rules;', + 'use Illuminate\Contracts\Validation\ValidationRule;', + 'class Foo implements ValidationRule', + 'public $implicit = true;', + 'public function validate(string $attribute, mixed $value, Closure $fail): void', + ], 'app/Rules/Foo.php'); + } +} diff --git a/tests/Integration/Generators/SeederMakeCommandTest.php b/tests/Integration/Generators/SeederMakeCommandTest.php new file mode 100644 index 000000000000..72702000ecb3 --- /dev/null +++ b/tests/Integration/Generators/SeederMakeCommandTest.php @@ -0,0 +1,23 @@ +artisan('make:seeder', ['name' => 'FooSeeder']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace Database\Seeders;', + 'use Illuminate\Database\Seeder;', + 'class FooSeeder extends Seeder', + 'public function run()', + ], 'database/seeders/FooSeeder.php'); + } +} diff --git a/tests/Integration/Generators/TestCase.php b/tests/Integration/Generators/TestCase.php new file mode 100644 index 000000000000..19bce44b7ddb --- /dev/null +++ b/tests/Integration/Generators/TestCase.php @@ -0,0 +1,10 @@ +artisan('make:test', ['name' => 'FooTest']) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace Tests\Feature;', + 'use Illuminate\Foundation\Testing\RefreshDatabase;', + 'use Illuminate\Foundation\Testing\WithFaker;', + 'use Tests\TestCase;', + 'class FooTest extends TestCase', + ], 'tests/Feature/FooTest.php'); + } + + public function testItCanGenerateUnitTest() + { + $this->artisan('make:test', ['name' => 'FooTest', '--unit' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'namespace Tests\Unit;', + 'use PHPUnit\Framework\TestCase;', + 'class FooTest extends TestCase', + ], 'tests/Unit/FooTest.php'); + } + + public function testItCanGenerateFeatureTestUsingPest() + { + $this->artisan('make:test', ['name' => 'FooTest', '--pest' => true]) + ->assertExitCode(0); + + $this->assertFileContains([ + 'test(\'example\', function () {', + '$response = $this->get(\'/\');', + '$response->assertStatus(200);', + ], 'tests/Feature/FooTest.php'); + } + + public function testItCanGenerateUnitTestUsingPest() + { + $this->artisan('make:test', ['name' => 'FooTest', '--unit' => true, '--pest' => true]) + ->assertExitCode(0); + $this->assertFileContains([ + 'test(\'example\', function () {', + 'expect(true)->toBeTrue();', + ], 'tests/Unit/FooTest.php'); + } +} diff --git a/tests/Integration/Generators/ViewMakeCommandTest.php b/tests/Integration/Generators/ViewMakeCommandTest.php new file mode 100644 index 000000000000..202bc15656ab --- /dev/null +++ b/tests/Integration/Generators/ViewMakeCommandTest.php @@ -0,0 +1,29 @@ +artisan('make:view', ['name' => 'foo']) + ->assertExitCode(0); + + $this->assertFilenameExists('resources/views/foo.blade.php'); + $this->assertFilenameNotExists('tests/Feature/View/FooTest.php'); + } + + public function testItCanGenerateViewFileWithTest() + { + $this->artisan('make:view', ['name' => 'foo', '--test' => true]) + ->assertExitCode(0); + + $this->assertFilenameExists('resources/views/foo.blade.php'); + $this->assertFilenameExists('tests/Feature/View/FooTest.php'); + } +}