diff --git a/src/BlueprintServiceProvider.php b/src/BlueprintServiceProvider.php index c4ac71c9..4df0b059 100644 --- a/src/BlueprintServiceProvider.php +++ b/src/BlueprintServiceProvider.php @@ -43,7 +43,7 @@ public function register() $this->app->bind('command.blueprint.build', function ($app) { - return new BuildCommand($app['files']); + return new BuildCommand($app['files'],app(Builder::class)); } ); $this->app->bind('command.blueprint.erase', diff --git a/src/Builder.php b/src/Builder.php index 8c77f806..fa71a3b5 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -6,7 +6,7 @@ class Builder { - public static function execute(Blueprint $blueprint, Filesystem $files, string $draft, string $only = '', string $skip = '') + public function execute(Blueprint $blueprint, Filesystem $files, string $draft, string $only = '', string $skip = '') { $cache = []; if ($files->exists('.blueprint')) { diff --git a/src/Commands/BuildCommand.php b/src/Commands/BuildCommand.php index ca06d11f..a00fad43 100644 --- a/src/Commands/BuildCommand.php +++ b/src/Commands/BuildCommand.php @@ -5,6 +5,7 @@ use Blueprint\Blueprint; use Blueprint\Builder; use Illuminate\Console\Command; +use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Str; use Symfony\Component\Console\Input\InputArgument; @@ -32,35 +33,35 @@ class BuildCommand extends Command /** @var Filesystem */ protected $files; + /** @var Builder */ + private $builder; + /** * @param Filesystem $files + * @param Builder $builder */ - public function __construct(Filesystem $files) + public function __construct(Filesystem $files, Builder $builder) { parent::__construct(); $this->files = $files; + $this->builder = $builder; } - /** - * Execute the console command. - * - * @return void - */ public function handle() { $file = $this->argument('draft') ?? $this->defaultDraftFile(); - if (! file_exists($file)) { + if (!$this->files->exists($file)) { $this->error('Draft file could not be found: '.($file ?: 'draft.yaml')); - exit(1); + return 1; } $only = $this->option('only') ?: ''; $skip = $this->option('skip') ?: ''; $blueprint = resolve(Blueprint::class); - $generated = Builder::execute($blueprint, $this->files, $file, $only, $skip); + $generated = $this->builder->execute($blueprint, $this->files, $file, $only, $skip); collect($generated)->each(function ($files, $action) { $this->line(Str::studly($action).':', $this->outputStyle($action)); @@ -97,12 +98,6 @@ private function outputStyle($action) private function defaultDraftFile() { - if (file_exists('draft.yaml')) { - return 'draft.yaml'; - } - - if (file_exists('draft.yml')) { - return 'draft.yml'; - } + return file_exists('draft.yml') ? 'draft.yml' : 'draft.yaml'; } } diff --git a/tests/Feature/Commands/BuildCommandTest.php b/tests/Feature/Commands/BuildCommandTest.php new file mode 100644 index 00000000..aa5516e3 --- /dev/null +++ b/tests/Feature/Commands/BuildCommandTest.php @@ -0,0 +1,99 @@ +makePartial(); + $this->swap('files', $filesystem); + + $filesystem->shouldReceive('exists') + ->with('draft.yaml') + ->andReturnTrue(); + + $builder = $this->mock(Builder::class); + + $builder->shouldReceive('execute') + ->with(resolve(Blueprint::class), $filesystem, 'draft.yaml', '', '') + ->andReturn(collect([])); + + $this->artisan('blueprint:build') + ->assertExitCode(0); + } + + /** @test */ + public function it_passes_the_command_args_to_the_builder_in_right_order() + { + $filesystem = \Mockery::mock(\Illuminate\Filesystem\Filesystem::class)->makePartial(); + $this->swap('files', $filesystem); + + $filesystem->shouldReceive('exists') + ->with('test.yml') + ->andReturnTrue(); + + $builder = $this->mock(Builder::class); + + $builder->shouldReceive('execute') + ->with(resolve(Blueprint::class), $filesystem, 'test.yml', 'a,b,c', 'x,y,z') + ->andReturn(collect([])); + + $this->artisan('blueprint:build test.yml --only=a,b,c --skip=x,y,z') + ->assertExitCode(0); + } + + /** @test */ + public function it_fails_if_the_draft_file_not_exists() + { + $filesystem = \Mockery::mock(\Illuminate\Filesystem\Filesystem::class)->makePartial(); + $this->swap('files', $filesystem); + + $filesystem->shouldReceive('exists') + ->with('test.yml') + ->andReturnFalse(); + + $builder = $this->mock(Builder::class); + + $builder->shouldNotReceive('execute'); + + $this->artisan('blueprint:build test.yml --only=a,b,c --skip=x,y,z') + ->assertExitCode(1); + } + + /** @test */ + public function it_shows_the_generated_files_groupbed_by_actions() + { + $filesystem = \Mockery::mock(\Illuminate\Filesystem\Filesystem::class)->makePartial(); + $this->swap('files', $filesystem); + + $filesystem->shouldReceive('exists') + ->with('draft.yaml') + ->andReturnTrue(); + + $builder = $this->mock(Builder::class); + + $builder->shouldReceive('execute') + ->with(resolve(Blueprint::class), $filesystem, 'draft.yaml', '', '') + ->andReturn(collect([ + "created" => [ + "file1", + "file2", + ] + ])); + + $this->artisan('blueprint:build') + ->assertExitCode(0) + ->expectsOutput('Created:') + ->expectsOutput('- file1') + ->expectsOutput('- file2'); + } +} diff --git a/tests/Unit/BuilderTest.php b/tests/Unit/BuilderTest.php index 59ec91b9..0950782e 100644 --- a/tests/Unit/BuilderTest.php +++ b/tests/Unit/BuilderTest.php @@ -46,7 +46,7 @@ public function execute_builds_draft_content() $file->expects('put') ->with('.blueprint', 'cacheable blueprint content'); - $actual = Builder::execute($blueprint, $file, 'draft.yaml'); + $actual = (new Builder)->execute($blueprint, $file, 'draft.yaml'); $this->assertSame($generated, $actual); } @@ -104,7 +104,7 @@ public function execute_uses_cache_and_remembers_models() $file->expects('put') ->with('.blueprint', 'cacheable blueprint content'); - $actual = Builder::execute($blueprint, $file, 'draft.yaml'); + $actual = (new Builder)->execute($blueprint, $file, 'draft.yaml'); $this->assertSame($generated, $actual); }