Skip to content

Commit

Permalink
Support adding SoftDeletes trait
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonmccreary committed Nov 9, 2019
1 parent 7e16204 commit 037f5b9
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 19 deletions.
4 changes: 3 additions & 1 deletion src/Blueprint.php
Expand Up @@ -14,7 +14,9 @@ class Blueprint

public function parse($content)
{
$content = preg_replace('/^(\s+)(id|timestamps)$/m', '$1$2: $2', $content);
$content = preg_replace_callback('/^(\s+)(id|timestamps|soft[dD]eletes)$/m', function ($matches) {
return $matches[1] . strtolower($matches[2]) . ': ' . $matches[2];
}, $content);

return Yaml::parse($content);
}
Expand Down
33 changes: 24 additions & 9 deletions src/Generators/ModelGenerator.php
Expand Up @@ -41,6 +41,7 @@ protected function populateStub(string $stub, Model $model)
$stub = str_replace('DummyNamespace', 'App', $stub);
$stub = str_replace('DummyClass', $model->name(), $stub);
$stub = str_replace('// properties...', $this->buildProperties($model), $stub);
$stub = $this->addTraits($model, $stub);

return $stub;
}
Expand All @@ -49,19 +50,21 @@ private function buildProperties(Model $model)
{
$properties = '';

$property = $this->fillableColumns($model->columns());
if (!empty($property)) {
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($property, false), $this->propertyStub('fillable'));
$columns = $this->fillableColumns($model->columns());
if (!empty($columns)) {
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns, false), $this->propertyStub('fillable'));
} else {
$properties .= $this->propertyStub('fillable');
}

$property = $this->castableColumns($model->columns());
if (!empty($property)) {
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($property), $this->propertyStub('casts'));
$columns = $this->castableColumns($model->columns());
if (!empty($columns)) {
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns), $this->propertyStub('casts'));
}

$property = $this->dateColumns($model->columns());
if (!empty($property)) {
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($property, false), $this->propertyStub('dates'));
$columns = $this->dateColumns($model->columns());
if (!empty($columns)) {
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns, false), $this->propertyStub('dates'));
}

return trim($properties);
Expand Down Expand Up @@ -148,4 +151,16 @@ private function propertyStub(string $stub)

return $stubs[$stub];
}

private function addTraits(Model $model, $stub)
{
if (!$model->usesSoftDeletes()) {
return $stub;
}

$stub = str_replace('use Illuminate\\Database\\Eloquent\\Model;', 'use Illuminate\\Database\\Eloquent\\Model;' . PHP_EOL . 'use Illuminate\\Database\\Eloquent\\SoftDeletes;', $stub);
$stub = str_replace('{', '{' . PHP_EOL . ' use SoftDeletes;' . PHP_EOL, $stub);

return $stub;
}
}
5 changes: 5 additions & 0 deletions src/Lexers/ModelLexer.php
Expand Up @@ -110,6 +110,11 @@ private function buildModel(string $name, array $columns)
unset($columns['timestamps']);
}

if (isset($columns['softdeletes'])) {
$model->enableSoftDeletes();
unset($columns['softdeletes']);
}

if (!isset($columns['id'])) {
$column = $this->buildColumn('id', 'id');
$model->addColumn($column);
Expand Down
11 changes: 11 additions & 0 deletions src/Model.php
Expand Up @@ -8,6 +8,7 @@ class Model
{
private $name;
private $timestamps = true;
private $softDeletes = false;
private $columns = [];

/**
Expand Down Expand Up @@ -52,4 +53,14 @@ public function tableName()
{
return Str::snake(Str::pluralStudly($this->name));
}

public function usesSoftDeletes(): bool
{
return $this->softDeletes;
}

public function enableSoftDeletes()
{
$this->softDeletes = true;
}
}
1 change: 1 addition & 0 deletions tests/Feature/BlueprintTest.php
Expand Up @@ -79,6 +79,7 @@ public function it_parses_shorthands()
$this->assertEquals([
'models' => [
'Name' => [
'softdeletes' => 'softDeletes',
'id' => 'id',
'timestamps' => 'timestamps',
],
Expand Down
24 changes: 15 additions & 9 deletions tests/Feature/Generator/ModelGeneratorTest.php
Expand Up @@ -47,21 +47,25 @@ public function output_writes_nothing_for_empty_tree()
*/
public function output_writes_migration_for_model_tree($definition, $path, $model)
{
static $iteration = 0;

$this->files->expects('get')
->with('stubs/model/class.stub')
->andReturn(file_get_contents('stubs/model/class.stub'));

$this->files->expects('get')
->with('stubs/model/fillable.stub')
->andReturn(file_get_contents('stubs/model/fillable.stub'));
if ($iteration === 0) {
$this->files->expects('get')
->with('stubs/model/fillable.stub')
->andReturn(file_get_contents('stubs/model/fillable.stub'));

$this->files->expects('get')
->with('stubs/model/casts.stub')
->andReturn(file_get_contents('stubs/model/casts.stub'));
$this->files->expects('get')
->with('stubs/model/casts.stub')
->andReturn(file_get_contents('stubs/model/casts.stub'));

$this->files->expects('get')
->with('stubs/model/dates.stub')
->andReturn(file_get_contents('stubs/model/dates.stub'));
$this->files->expects('get')
->with('stubs/model/dates.stub')
->andReturn(file_get_contents('stubs/model/dates.stub'));
}

$this->files->expects('put')
->with($path, $this->fixture($model));
Expand All @@ -70,13 +74,15 @@ public function output_writes_migration_for_model_tree($definition, $path, $mode
$tree = $this->blueprint->analyze($tokens);

$this->assertEquals(['created' => [$path]], $this->subject->output($tree));
++$iteration;
}


public function modelTreeDataProvider()
{
return [
['definitions/readme-example.bp', 'app/Post.php', 'models/readme-example.php'],
['definitions/soft-deletes.bp', 'app/Comment.php', 'models/soft-deletes.php'],
];
}
}
38 changes: 38 additions & 0 deletions tests/Feature/Lexers/ModelLexerTest.php
Expand Up @@ -53,6 +53,7 @@ public function it_returns_models()
$model = $actual['models']['ModelOne'];
$this->assertEquals('ModelOne', $model->name());
$this->assertTrue($model->usesTimestamps());
$this->assertFalse($model->usesSoftDeletes());

$columns = $model->columns();
$this->assertCount(2, $columns);
Expand All @@ -66,6 +67,7 @@ public function it_returns_models()
$model = $actual['models']['ModelTwo'];
$this->assertEquals('ModelTwo', $model->name());
$this->assertTrue($model->usesTimestamps());
$this->assertFalse($model->usesSoftDeletes());

$columns = $model->columns();
$this->assertCount(2, $columns);
Expand Down Expand Up @@ -98,6 +100,7 @@ public function it_defaults_the_id_column()
$model = $actual['models']['Model'];
$this->assertEquals('Model', $model->name());
$this->assertTrue($model->usesTimestamps());
$this->assertFalse($model->usesSoftDeletes());

$columns = $model->columns();
$this->assertCount(2, $columns);
Expand Down Expand Up @@ -132,6 +135,7 @@ public function it_disables_timestamps()
$model = $actual['models']['Model'];
$this->assertEquals('Model', $model->name());
$this->assertFalse($model->usesTimestamps());
$this->assertFalse($model->usesSoftDeletes());
}

/**
Expand All @@ -155,6 +159,7 @@ public function it_defaults_to_string_datatype()
$model = $actual['models']['Model'];
$this->assertEquals('Model', $model->name());
$this->assertTrue($model->usesTimestamps());
$this->assertFalse($model->usesSoftDeletes());

$columns = $model->columns();
$this->assertCount(2, $columns);
Expand Down Expand Up @@ -191,6 +196,7 @@ public function it_accepts_lowercase_keywords()
$model = $actual['models']['Model'];
$this->assertEquals('Model', $model->name());
$this->assertTrue($model->usesTimestamps());
$this->assertFalse($model->usesSoftDeletes());

$columns = $model->columns();
$this->assertCount(4, $columns);
Expand Down Expand Up @@ -235,6 +241,7 @@ public function it_handles_data_type_attributes($definition, $data_type, $attrib
$model = $actual['models']['Model'];
$this->assertEquals('Model', $model->name());
$this->assertTrue($model->usesTimestamps());
$this->assertFalse($model->usesSoftDeletes());

$columns = $model->columns();
$this->assertCount(2, $columns);
Expand Down Expand Up @@ -269,6 +276,7 @@ public function it_handles_modifier_attributes($definition, $modifier, $attribut
$model = $actual['models']['Model'];
$this->assertEquals('Model', $model->name());
$this->assertTrue($model->usesTimestamps());
$this->assertFalse($model->usesSoftDeletes());

$columns = $model->columns();
$this->assertCount(2, $columns);
Expand All @@ -281,6 +289,36 @@ public function it_handles_modifier_attributes($definition, $modifier, $attribut
$this->assertEquals([[$modifier => $attributes], 'nullable'], $columns['column']->modifiers());
}

/**
* @test
*/
public function it_enables_soft_deletes()
{
$tokens = [
'models' => [
'Model' => [
'softdeletes' => 'softdeletes'
]
],
];

$actual = $this->subject->analyze($tokens);

$this->assertIsArray($actual['models']);
$this->assertCount(1, $actual['models']);

$model = $actual['models']['Model'];
$this->assertEquals('Model', $model->name());
$this->assertTrue($model->usesTimestamps());
$this->assertTrue($model->usesSoftDeletes());

$columns = $model->columns();
$this->assertCount(1, $columns);
$this->assertEquals('id', $columns['id']->name());
$this->assertEquals('id', $columns['id']->dataType());
$this->assertEquals([], $columns['id']->modifiers());
}

public function dataTypeAttributesDataProvider()
{
return [
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/definitions/shorthands.bp
@@ -1,4 +1,5 @@
models:
Name:
softDeletes
id
timestamps
3 changes: 3 additions & 0 deletions tests/fixtures/definitions/soft-deletes.bp
@@ -0,0 +1,3 @@
models:
Comment:
softdeletes
27 changes: 27 additions & 0 deletions tests/fixtures/models/soft-deletes.php
@@ -0,0 +1,27 @@
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Comment extends Model
{
use SoftDeletes;

/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [];

/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'id' => 'integer',
];
}

0 comments on commit 037f5b9

Please sign in to comment.