diff --git a/.gitignore b/.gitignore index fcd7e48..4537dbe 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ vendor/ composer.lock .php_cs.cache -.phpunit.result.cache \ No newline at end of file +.phpunit.result.cache +app/ +database/ +routes/ \ No newline at end of file diff --git a/composer.json b/composer.json index 9566d25..20010a0 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "require": { "php": "^7.3|^8.0", "laravel/framework": "^8.0", - "doctrine/dbal": "^2.9" + "doctrine/dbal": "^2.9", + "illuminate/support": "^8.61" }, "require-dev": { "phpunit/phpunit": "^7|^8", diff --git a/phpunit.xml b/phpunit.xml index 5db2d54..fe60832 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -4,6 +4,12 @@ ./tests + + ./tests/Unit + + + ./tests/Feature + @@ -16,4 +22,4 @@ - + \ No newline at end of file diff --git a/src/Commands/ApiCrudGenerator.php b/src/Commands/ApiCrudGenerator.php index 62461c6..cb4df52 100644 --- a/src/Commands/ApiCrudGenerator.php +++ b/src/Commands/ApiCrudGenerator.php @@ -3,6 +3,13 @@ namespace AndreaCivita\ApiCrudGenerator\Commands; use AndreaCivita\ApiCrudGenerator\Core\Generator; +use AndreaCivita\ApiCrudGenerator\Core\Generators\ControllerGenerator; +use AndreaCivita\ApiCrudGenerator\Core\Generators\FactoryGenerator; +use AndreaCivita\ApiCrudGenerator\Core\Generators\ModelGenerator; +use AndreaCivita\ApiCrudGenerator\Core\Generators\RequestGenerator; +use AndreaCivita\ApiCrudGenerator\Core\Generators\ResourceGenerator; +use AndreaCivita\ApiCrudGenerator\Core\Generators\RouteGenerator; +use AndreaCivita\ApiCrudGenerator\Core\Generators\TestGenerator; use Doctrine\DBAL\Driver\PDOException; use Illuminate\Console\Command; use Illuminate\Contracts\Filesystem\FileNotFoundException; @@ -42,6 +49,42 @@ class ApiCrudGenerator extends Command */ protected $generator; + /** + * @var ControllerGenerator $controller + */ + protected $controller; + + /** + * @var FactoryGenerator $factory + */ + protected $factory; + + /** + * @var ModelGenerator $model + */ + protected $model; + + /** + * @var RequestGenerator $request + */ + protected $request; + + /** + * @var ResourceGenerator $resource + */ + protected $resource; + + /** + * @var RouteGenerator $route + */ + protected $route; + + + /** + * @var TestGenerator $test + */ + protected $test; + /** * The String support instance @@ -66,14 +109,35 @@ class ApiCrudGenerator extends Command /** * Create a new command instance. * - * @param Generator $generator + * @param ControllerGenerator $controllerGenerator + * @param FactoryGenerator $factoryGenerator + * @param ModelGenerator $modelGenerator + * @param RequestGenerator $requestGenerator + * @param ResourceGenerator $resourceGenerator + * @param RouteGenerator $routeGenerator + * @param TestGenerator $testGenerator * @param Str $str * @param Schema $schema */ - public function __construct(Generator $generator, Str $str, Schema $schema) - { + public function __construct( + ControllerGenerator $controllerGenerator, + FactoryGenerator $factoryGenerator, + ModelGenerator $modelGenerator, + RequestGenerator $requestGenerator, + ResourceGenerator $resourceGenerator, + RouteGenerator $routeGenerator, + TestGenerator $testGenerator, + Str $str, + Schema $schema + ) { parent::__construct(); - $this->generator = $generator; + $this->controller = $controllerGenerator; + $this->factory = $factoryGenerator; + $this->model = $modelGenerator; + $this->request = $requestGenerator; + $this->resource = $resourceGenerator; + $this->route = $routeGenerator; + $this->test = $testGenerator; $this->str = $str; $this->schema = $schema; } @@ -83,7 +147,7 @@ public function __construct(Generator $generator, Str $str, Schema $schema) * * @return int */ - public function handle() : int + public function handle(): int { // Checking interactive mode if ($this->option('interactive') == "") { @@ -117,7 +181,7 @@ public function handle() : int protected function all() { try { - $tables = DB::connection()->getDoctrineSchemaManager()->listTableNames(); + $tables = DB::connection()->getDoctrineSchemaManager()->listTableNames(); foreach ($tables as $table) { $this->comment("Generating " . $table . " CRUD"); $columns = Schema::getColumnListing($table); @@ -134,7 +198,7 @@ protected function all() /** * Generate CRUD in interactive mode */ - protected function interactive() : void + protected function interactive(): void { $this->info("Welcome in Interactive mode"); @@ -170,25 +234,25 @@ protected function interactive() : void */ protected function generate(string $name, string $table, bool $timestamps) { - $this->generator->controller($name, $table); + $this->controller->setData($name, $table)->generate(); $this->info("Generated Controller!"); - $this->generator->model($name, $table, $timestamps); + $this->model->setData($name, $table, $timestamps)->generate(); $this->info("Generated Model!"); - $this->generator->request($name); + $this->request->setData($name)->generate(); $this->info("Generated Request!"); - $this->generator->resource($name); + $this->resource->setData($name)->generate(); $this->info("Generated Resource!"); - $this->passport ? $this->generator->secureRoutes($name) : $this->generator->routes($name); + $this->route->setData($name, $this->passport)->generate(); $this->info("Generated routes!"); - $this->generator->factory($name); + $this->factory->setData($name)->generate(); $this->info("Generated Factory!"); - $this->generator->test($name); + $this->test->setData($name)->generate(); $this->info("Generated Test!"); } } diff --git a/src/Core/Generator.php b/src/Core/Generator.php index 0f62c5d..e073efd 100644 --- a/src/Core/Generator.php +++ b/src/Core/Generator.php @@ -2,10 +2,12 @@ namespace AndreaCivita\ApiCrudGenerator\Core; -use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Str; +/** + * @deprecated + */ class Generator { diff --git a/src/Core/Generators/ControllerGenerator.php b/src/Core/Generators/ControllerGenerator.php new file mode 100644 index 0000000..92d03d7 --- /dev/null +++ b/src/Core/Generators/ControllerGenerator.php @@ -0,0 +1,65 @@ +stub = $stub; + $this->fileSystem = $this->stub->getFilesystemInstance(); + } + + /** + * @param string $name + * @param string $table + * @return ControllerGenerator + */ + public function setData(string $name, string $table): ControllerGenerator + { + $this->name = $name; + $this->table = $table; + return $this; + } + + /** + * @inheritDoc + */ + public function generate() + { + $content = $this->stub->parseStub('Controller', $this->name, ['table' => $this->table]); + + if (!$this->fileSystem->exists("app/Http/Controllers/")) { + $this->fileSystem->makeDirectory("app/Http/Controllers/", 0755, true); + } + + return $this->fileSystem->put("app/Http/Controllers/{$this->name}Controller.php", $content); + } +} diff --git a/src/Core/Generators/FactoryGenerator.php b/src/Core/Generators/FactoryGenerator.php new file mode 100644 index 0000000..cbbab1c --- /dev/null +++ b/src/Core/Generators/FactoryGenerator.php @@ -0,0 +1,58 @@ +stub = $stub; + $this->fileSystem = $this->stub->getFilesystemInstance(); + } + + /** + * @param string $name + * @return $this + */ + public function setData(string $name): FactoryGenerator + { + $this->name = $name; + return $this; + } + + /** + * @inheritDoc + */ + public function generate() + { + $content = $this->stub->parseStub('Factory', $this->name); + + if (!$this->fileSystem->exists("database/factories/")) { + $this->fileSystem->makeDirectory("database/factories/", 0755, true); + } + return $this->fileSystem->put("database/factories/{$this->name}Factory.php", $content); + } +} diff --git a/src/Core/Generators/ModelGenerator.php b/src/Core/Generators/ModelGenerator.php new file mode 100644 index 0000000..c1bc5a5 --- /dev/null +++ b/src/Core/Generators/ModelGenerator.php @@ -0,0 +1,82 @@ +stub = $stub; + $this->fileSystem = $stub->getFilesystemInstance(); + $this->str = $stub->getStrInstance(); + } + + /** + * @param string $name + * @param string $table + * @param bool $timestamps + * @return $this + */ + public function setData(string $name, string $table, bool $timestamps): ModelGenerator + { + $this->name = $name; + $this->table = $table; + $this->timestamps = $timestamps; + return $this; + } + + + /** + * @inheritDoc + */ + public function generate() + { + $content = $this->stub->parseStub('Model', $this->name, [ + 'tableDeclaration' => $this->table === "default" ? $this->str->lower($this->str->plural($this->name)) : null, + 'timestamps' => $this->timestamps ? 'public $timestamps = false;' : '' + ]); + + if (!$this->fileSystem->exists("app/Models/")) { + $this->fileSystem->makeDirectory("app/Models/", 0755, true); + } + return $this->fileSystem->put("app/Models/{$this->name}.php", $content); + } +} diff --git a/src/Core/Generators/RequestGenerator.php b/src/Core/Generators/RequestGenerator.php new file mode 100644 index 0000000..c30a0e3 --- /dev/null +++ b/src/Core/Generators/RequestGenerator.php @@ -0,0 +1,57 @@ +stub = $stub; + $this->fileSystem = $stub->getFilesystemInstance(); + } + + /** + * @param string $name + * @return RequestGenerator $this + */ + public function setData(string $name): RequestGenerator + { + $this->name = $name; + return $this; + } + /** + * @inheritDoc + */ + public function generate() + { + $content = $this->stub->parseStub('Request', $this->name); + + if (!$this->fileSystem->exists("app/Http/Requests/")) { + $this->fileSystem->makeDirectory("app/Http/Requests/", 0755, true); + } + + return $this->fileSystem->put("app/Http/Requests/{$this->name}Request.php", $content); + } +} diff --git a/src/Core/Generators/ResourceGenerator.php b/src/Core/Generators/ResourceGenerator.php new file mode 100644 index 0000000..49872de --- /dev/null +++ b/src/Core/Generators/ResourceGenerator.php @@ -0,0 +1,54 @@ +stub = $stub; + $this->fileSystem = $this->stub->getFilesystemInstance(); + } + + public function setData(string $name): ResourceGenerator + { + $this->name = $name; + return $this; + } + + /** + * @inheritDoc + */ + public function generate() + { + $content = $this->stub->parseStub('Resource', $this->name); + + if (!$this->fileSystem->exists("app/Http/Resources/")) { + $this->fileSystem->makeDirectory("app/Http/Resources/", 0755, true); + } + return $this->fileSystem->put("app/Http/Resources/{$this->name}Resource.php", $content); + } +} diff --git a/src/Core/Generators/RouteGenerator.php b/src/Core/Generators/RouteGenerator.php new file mode 100644 index 0000000..c667b99 --- /dev/null +++ b/src/Core/Generators/RouteGenerator.php @@ -0,0 +1,68 @@ +stub = $stub; + $this->fileSystem = $this->stub->getFilesystemInstance(); + } + + /** + * @param string $modelName + * @param bool $secure + * @return $this + */ + public function setData(string $modelName, bool $secure): RouteGenerator + { + $this->modelName = $modelName; + $this->secure = $secure; + return $this; + } + + /** + * @inheritDoc + */ + public function generate() + { + $fileName = $this->secure ? 'Passport-Routes' : 'Routes'; + $content = $this->stub->parseStub($fileName, $this->modelName); + + if (!$this->fileSystem->exists("routes/")) { + $this->fileSystem->makeDirectory("routes/", 0755, true); + $this->fileSystem->put('routes/api.php', ""); + } + + return $this->fileSystem->append("routes/api.php", $content); + } +} diff --git a/src/Core/Generators/TestGenerator.php b/src/Core/Generators/TestGenerator.php new file mode 100644 index 0000000..437fc91 --- /dev/null +++ b/src/Core/Generators/TestGenerator.php @@ -0,0 +1,57 @@ +stub = $stub; + $this->fileSystem = $this->stub->getFilesystemInstance(); + } + + /** + * @param string $modelName + * @return $this + */ + public function setData(string $modelName): TestGenerator + { + $this->modelName = $modelName; + return $this; + } + + /** + * @inheritDoc + */ + public function generate() + { + $content = $this->stub->parseStub('Test', $this->modelName); + + if (!$this->fileSystem->exists("tests/Feature/")) { + $this->fileSystem->makeDirectory("tests/Feature/", 0775, true); + } + return $this->fileSystem->append("tests/Feature/{$this->modelName}Test.php", $content); + } +} diff --git a/src/Core/Stub.php b/src/Core/Stub.php index e5fa009..0b7cef0 100644 --- a/src/Core/Stub.php +++ b/src/Core/Stub.php @@ -19,14 +19,14 @@ class Stub /** * The filesystem instance. * - * @var \Illuminate\Filesystem\Filesystem + * @var Filesystem */ - protected $files; + protected $filesystem; /** * The String support instance * - * @var \Illuminate\Support\Str + * @var Str */ protected $str; @@ -37,48 +37,45 @@ class Stub */ public function __construct(Filesystem $filesystem, Str $str) { - $this->files = $filesystem; + $this->filesystem = $filesystem; $this->str = $str; } - /** * Get the file from the stub * - * @param $type - * @return bool|string - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + * @param string $name + * @return string + * @throws FileNotFoundException */ - protected function getStub($type) + public function getStub($name) : string { - if ($this->files->exists("/resources/stubs/$type.stub")) { - return $this->files->get("/resources/stubs/$type.stub"); + if ($this->filesystem->exists("/resources/stubs/$name.stub")) { + return $this->filesystem->get("/resources/stubs/$name.stub"); } - return $this->files->get(__DIR__ . "/../stubs/{$type}.stub"); + return $this->filesystem->get(__DIR__ . "/../stubs/$name.stub"); } - - /** * Fill stub with data * * @param $stub string name of stub * @param $name string name of resource * @param $args array additional placeholders to replace - * @return mixed + * @return string */ - public function parseStub(string $stub, string $name, array $args = []) + public function parseStub(string $stub, string $name, array $args = []) : string { $toParse = array_merge([ 'modelName' => $name, - 'modelNamePluralLowerCase' => $args['table'] ?? strtolower($this->str->plural($name)), - 'modelNameSingularLowerCase' => strtolower($name) + 'modelNamePluralLowerCase' => $args['table'] ?? $this->str->lower($this->str->plural($name)), + 'modelNameSingularLowerCase' => $this->str->lower($name) ], $args); try { - return str_replace( + return $this->str->replace( array_map(function ($key) { return "{{{$key}}}"; }, array_keys($toParse)), @@ -89,4 +86,21 @@ public function parseStub(string $stub, string $name, array $args = []) return "Stub not found"; } } + + + /** + * @return Filesystem + */ + public function getFilesystemInstance() : Filesystem + { + return $this->filesystem; + } + + /** + * @return Str + */ + public function getStrInstance() : Str + { + return $this->str; + } } diff --git a/src/Interfaces/Generator.php b/src/Interfaces/Generator.php new file mode 100644 index 0000000..484c150 --- /dev/null +++ b/src/Interfaces/Generator.php @@ -0,0 +1,12 @@ +{{modelNameSingularLowerCase}} = \App\Models\{{modelName}}::factory()->make(); + $this->{{modelNameSingularLowerCase}} = {{modelName}}::factory()->make(); } /** @@ -77,7 +77,7 @@ class {{modelName}}Test extends TestCase */ public function testDestroy() : void { - $id = \App\Models\{{modelName}}::all()->last()->id; + $id = {{modelName}}::all()->last()->id; $this->deleteJson('/api/{{modelNameSingularLowerCase}}/'.$id) ->assertSuccessful(); diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index de50eff..f6a5834 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -6,6 +6,7 @@ class GeneratorTest extends TestCase { protected $name; + protected $table; protected $generator; protected $files; @@ -23,6 +24,7 @@ public function setUp(): void { parent::setUp(); $this->name = "Car"; + $this->table = "cars"; $this->generator = new Generator( new Illuminate\Filesystem\Filesystem(), new \Illuminate\Support\Str(), @@ -36,14 +38,14 @@ public function setUp(): void public function testModel() : void { $this->files->makeDirectory('app/Models', 0777, true); - $this->assertIsInt($this->generator->model($this->name, "cars", true)); - $this->assertIsInt($this->generator->model($this->name, "cars", false)); + $this->assertIsInt($this->generator->model($this->name, $this->table, true)); + $this->assertIsInt($this->generator->model($this->name, $this->table, false)); } public function testController() : void { $this->files->makeDirectory('app/Http/Controllers', 0777, true); - $this->assertIsInt($this->generator->controller($this->name)); + $this->assertIsInt($this->generator->controller($this->name, $this->table)); } public function testRequest() : void diff --git a/tests/StubTest.php b/tests/StubTest.php deleted file mode 100644 index 3e66a5f..0000000 --- a/tests/StubTest.php +++ /dev/null @@ -1,35 +0,0 @@ -parseStub("Controller", "Car"); - $this->assertIsString($content); - } - - /** - * - */ - public function testFailParseStub() - { - $stub = new Stub(new \Illuminate\Filesystem\Filesystem(), new \Illuminate\Support\Str()); - $stub->parseStub("StubThatDoesNotExist", "Car"); - try { - $stub->parseStub("StubThatDoesNotExist", "Car"); - $this->fail("Stub not found."); - } catch (Exception $ex) { - $this->assertEquals($ex->getMessage(), "Stub not found."); - } - } -} diff --git a/tests/Unit/ControllerGeneratorTest.php b/tests/Unit/ControllerGeneratorTest.php new file mode 100644 index 0000000..f5fb1b9 --- /dev/null +++ b/tests/Unit/ControllerGeneratorTest.php @@ -0,0 +1,50 @@ +modelName = 'Car'; + $this->tableName = 'cars'; + $this->controllerGenerator = new ControllerGenerator(new Stub(new Filesystem(), new Str())); + } + + public function testSetData() + { + $this->assertInstanceOf( + ControllerGenerator::class, + $this->controllerGenerator->setData($this->modelName, $this->tableName) + ); + } + + + public function testGenerate() + { + $this->controllerGenerator->setData($this->modelName, $this->tableName); + $this->assertIsInt($this->controllerGenerator->generate()); + } +} diff --git a/tests/Unit/FactoryGeneratorTest.php b/tests/Unit/FactoryGeneratorTest.php new file mode 100644 index 0000000..980518f --- /dev/null +++ b/tests/Unit/FactoryGeneratorTest.php @@ -0,0 +1,43 @@ +modelName = 'Car'; + $this->factoryGenerator = new FactoryGenerator(new Stub(new Filesystem(), new Str())); + } + + public function testSetData() + { + $this->assertInstanceOf( + FactoryGenerator::class, + $this->factoryGenerator->setData($this->modelName) + ); + } + + + public function testGenerate() + { + $this->factoryGenerator->setData($this->modelName); + $this->assertIsInt($this->factoryGenerator->generate()); + } +} diff --git a/tests/Unit/ModelGeneratorTest.php b/tests/Unit/ModelGeneratorTest.php new file mode 100644 index 0000000..69d4617 --- /dev/null +++ b/tests/Unit/ModelGeneratorTest.php @@ -0,0 +1,51 @@ +modelName = 'Car'; + $this->tableName = 'cars'; + $this->modelGenerator = new ModelGenerator(new Stub(new Filesystem(), new Str())); + } + + public function testSetData() + { + $this->assertInstanceOf( + ModelGenerator::class, + $this->modelGenerator->setData($this->modelName, $this->tableName, false) + ); + } + + + public function testGenerate() + { + $this->modelGenerator->setData($this->modelName, $this->tableName, true); + $this->assertIsInt($this->modelGenerator->generate()); + } +} diff --git a/tests/Unit/RequestGeneratorTest.php b/tests/Unit/RequestGeneratorTest.php new file mode 100644 index 0000000..52ee097 --- /dev/null +++ b/tests/Unit/RequestGeneratorTest.php @@ -0,0 +1,43 @@ +modelName = 'Car'; + $this->requestGenerator = new RequestGenerator(new Stub(new Filesystem(), new Str())); + } + + public function testSetData() + { + $this->assertInstanceOf( + RequestGenerator::class, + $this->requestGenerator->setData($this->modelName) + ); + } + + + public function testGenerate() + { + $this->requestGenerator->setData($this->modelName); + $this->assertIsInt($this->requestGenerator->generate()); + } +} diff --git a/tests/Unit/ResourceGeneratorTest.php b/tests/Unit/ResourceGeneratorTest.php new file mode 100644 index 0000000..28e6cc4 --- /dev/null +++ b/tests/Unit/ResourceGeneratorTest.php @@ -0,0 +1,43 @@ +modelName = 'Car'; + $this->resourceGenerator = new ResourceGenerator(new Stub(new Filesystem(), new Str())); + } + + public function testSetData() + { + $this->assertInstanceOf( + ResourceGenerator::class, + $this->resourceGenerator->setData($this->modelName) + ); + } + + + public function testGenerate() + { + $this->resourceGenerator->setData($this->modelName); + $this->assertIsInt($this->resourceGenerator->generate()); + } +} diff --git a/tests/Unit/RouteGeneratorTest.php b/tests/Unit/RouteGeneratorTest.php new file mode 100644 index 0000000..acf4f79 --- /dev/null +++ b/tests/Unit/RouteGeneratorTest.php @@ -0,0 +1,43 @@ +modelName = 'Car'; + $this->routeGenerator = new RouteGenerator(new Stub(new Filesystem(), new Str())); + } + + public function testSetData() + { + $this->assertInstanceOf( + RouteGenerator::class, + $this->routeGenerator->setData($this->modelName, false) + ); + } + + + public function testGenerate() + { + $this->routeGenerator->setData($this->modelName, false); + $this->assertIsInt($this->routeGenerator->generate()); + } +} diff --git a/tests/Unit/StubTest.php b/tests/Unit/StubTest.php new file mode 100644 index 0000000..c393787 --- /dev/null +++ b/tests/Unit/StubTest.php @@ -0,0 +1,56 @@ +stub = new Stub(new Filesystem(), new Str()); + $this->names = [ + 'Controller', + 'Factory', + 'Model', + 'Passport-Routes', + 'Request', + 'Resource', + 'Routes', + 'Test', + ]; + } + + public function testGetStub() + { + foreach ($this->names as $name) { + echo "Fetching $name stub... \n"; + $this->assertIsString($this->stub->getStub($name)); + echo $name . " ✅ \n"; + } + + $this->expectException(FileNotFoundException::class); + $this->stub->getStub('StubThatDoesNotExist'); + } + + /** + * Test StubClass + */ + public function testParseStub(): void + { + foreach ($this->names as $name) { + $this->assertIsString($this->stub->parseStub($name, 'Car', ['table' => 'cars'])); + } + } +} diff --git a/tests/Unit/TestGeneratorTest.php b/tests/Unit/TestGeneratorTest.php new file mode 100644 index 0000000..8acdbe1 --- /dev/null +++ b/tests/Unit/TestGeneratorTest.php @@ -0,0 +1,43 @@ +modelName = 'Car'; + $this->testGenerator = new TestGenerator(new Stub(new Filesystem(), new Str())); + } + + public function testSetData() + { + $this->assertInstanceOf( + TestGenerator::class, + $this->testGenerator->setData($this->modelName) + ); + } + + + public function testGenerate() + { + $this->testGenerator->setData($this->modelName); + $this->assertIsInt($this->testGenerator->generate()); + } +}