Skip to content

Commit 83c8c41

Browse files
committed
Backfill generator tests
1 parent 4154423 commit 83c8c41

18 files changed

+442
-19
lines changed

sample.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ models:
44
content: bigtext
55
published_at: nullable timestamp
66

7-
87
controllers:
98
Post:
109
index:

src/Generators/FactoryGenerator.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44

55
use Blueprint\Contracts\Generator;
66
use Blueprint\Model;
7+
use Illuminate\Support\Facades\File;
78

89
class FactoryGenerator implements Generator
910
{
11+
const INDENT = ' ';
12+
1013
public function output(array $tree): void
1114
{
1215
// TODO: what if changing an existing model
13-
$stub = file_get_contents('stubs/factory.stub');
16+
$stub = File::get('stubs/factory.stub');
1417

1518
/** @var \Blueprint\Model $model */
1619
foreach ($tree['models'] as $model) {
17-
file_put_contents(
20+
File::put(
1821
$this->getPath($model),
1922
$this->populateStub($stub, $model)
2023
);
@@ -45,7 +48,7 @@ protected function buildDefinition(Model $model)
4548
continue;
4649
}
4750

48-
$definition .= "'{$column->name()}' => ";
51+
$definition .= self::INDENT . "'{$column->name()}' => ";
4952
$faker = $this->fakerData($column->name()) ?? $this->fakerDataType($column->dataType());
5053
$definition .= '$faker->' . $faker;
5154
$definition .= ',' . PHP_EOL;
@@ -59,6 +62,7 @@ protected function fakerData(string $name)
5962
static $fakeableNames = [
6063
'city' => 'city',
6164
'company' => 'company',
65+
'content' => 'paragraphs(3, true)',
6266
'country' => 'country',
6367
'description' => 'text',
6468
'email' => 'safeEmail',
@@ -96,6 +100,7 @@ protected function fakerData(string $name)
96100
protected function fakerDataType(string $type)
97101
{
98102
$fakeableTypes = [
103+
'id' => 'randomDigitNotNull', // TODO: override with closure generator
99104
'string' => 'word',
100105
'text' => 'text',
101106
'date' => 'date()',

src/Generators/MigrationGenerator.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@
44

55
use Blueprint\Contracts\Generator;
66
use Blueprint\Model;
7+
use Illuminate\Support\Facades\File;
78
use Illuminate\Support\Str;
89

910
class MigrationGenerator implements Generator
1011
{
12+
const INDENT = ' ';
13+
1114
public function output(array $tree): void
1215
{
1316
// TODO: what if changing an existing model
14-
$stub = file_get_contents('stubs/migration.stub');
17+
$stub = File::get('stubs/migration.stub');
1518

1619
/** @var \Blueprint\Model $model */
1720
foreach ($tree['models'] as $model) {
18-
file_put_contents(
21+
File::put(
1922
$this->getPath($model),
2023
$this->populateStub($stub, $model)
2124
);
@@ -37,16 +40,27 @@ protected function buildDefinition(Model $model)
3740

3841
/** @var \Blueprint\Column $column */
3942
foreach ($model->columns() as $column) {
40-
$definition .= '$table->' . $column->dataType() . "('{$column->name()}'";
43+
$dataType = $column->dataType();
44+
if ($column->name() === 'id') {
45+
$dataType = 'increments';
46+
} elseif ($column->dataType() === 'id') {
47+
$dataType = 'unsignedBigInteger';
48+
}
49+
50+
$definition .= self::INDENT . '$table->' . $dataType . "('{$column->name()}'";
51+
4152
if (!empty($column->attributes())) {
42-
// TODO: what about set and enum?
43-
$definition .= ', ' . implode(', ', $column->attributes());
53+
$definition .= ', ';
54+
if (in_array($column->dataType(), ['set', 'enum'])) {
55+
$definition .= json_encode($column->attributes());
56+
} else {
57+
$definition .= implode(', ', $column->attributes());
58+
}
4459
}
4560
$definition .= ')';
4661

4762
foreach ($column->modifiers() as $modifier) {
4863
if (is_array($modifier)) {
49-
// TODO: properly handle quoted values
5064
$definition .= "->" . key($modifier) . "(" . current($modifier) . ")";
5165
} else {
5266
$definition .= '->' . $modifier . '()';
@@ -57,7 +71,7 @@ protected function buildDefinition(Model $model)
5771
}
5872

5973
if ($model->usesTimestamps()) {
60-
$definition .= '$table->timestamps();' . PHP_EOL;
74+
$definition .= self::INDENT . '$table->timestamps();' . PHP_EOL;
6175
}
6276

6377
return trim($definition);
@@ -70,6 +84,6 @@ protected function getClassName(Model $model)
7084

7185
protected function getPath(Model $model)
7286
{
73-
return 'build/' . date('Y_m_d_His') . '_create_' . $model->tableName() . '_table.php';
87+
return 'build/' . \Carbon\Carbon::now()->format('Y_m_d_His') . '_create_' . $model->tableName() . '_table.php';
7488
}
7589
}

src/Generators/ModelGenerator.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@
55
use Blueprint\Column;
66
use Blueprint\Contracts\Generator;
77
use Blueprint\Model;
8+
use Illuminate\Support\Facades\File;
89

910
class ModelGenerator implements Generator
1011
{
1112
public function output(array $tree): void
1213
{
1314
// TODO: what if changing an existing model
14-
$stub = file_get_contents('stubs/model/class.stub');
15+
$stub = File::get('stubs/model/class.stub');
1516

1617
/** @var \Blueprint\Model $model */
1718
foreach ($tree['models'] as $model) {
18-
file_put_contents(
19+
File::put(
1920
$this->getPath($model),
2021
$this->populateStub($stub, $model)
2122
);
@@ -113,21 +114,23 @@ private function castForColumn(Column $column)
113114
private function pretty_print_array(array $data, $assoc = true)
114115
{
115116
$output = var_export($data, true);
116-
$output = preg_replace(['/^array\s\(/', "/\)$/"], ['[', ']'], $output);
117+
$output = preg_replace('/^\s+/m', ' ', $output);
118+
$output = preg_replace(['/^array\s\(/', "/\)$/"], ['[', ' ]'], $output);
117119

118120
if (!$assoc) {
119121
$output = preg_replace('/^(\s+)[^=]+=>\s+/m', '$1', $output);
120122
}
121123

122-
return $output;
124+
125+
return trim($output);
123126
}
124127

125128
private function propertyStub(string $stub)
126129
{
127130
static $stubs = [];
128131

129132
if (empty($stubs[$stub])) {
130-
$stubs[$stub] = file_get_contents('stubs/model/'. $stub .'.stub');
133+
$stubs[$stub] = File::get('stubs/model/' . $stub . '.stub');
131134
}
132135

133136
return $stubs[$stub];

stubs/migration.stub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ class DummyClass extends Migration
2727
{
2828
Schema::dropIfExists('DummyTable');
2929
}
30-
}
30+
}

stubs/model/class.stub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ use Illuminate\Database\Eloquent\Model;
77
class DummyClass extends Model
88
{
99
// properties...
10-
}
10+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Tests\Feature\Generators;
4+
5+
use Blueprint\Blueprint;
6+
use Blueprint\Generators\FactoryGenerator;
7+
use Illuminate\Support\Facades\File;
8+
use Tests\TestCase;
9+
10+
class FactoryGeneratorTest extends TestCase
11+
{
12+
private $blueprint;
13+
14+
private $file;
15+
16+
protected function setUp()
17+
{
18+
parent::setUp();
19+
20+
$this->file = \Mockery::mock();
21+
File::swap($this->file);
22+
23+
$this->blueprint = new Blueprint();
24+
$this->blueprint->registerLexer(new \Blueprint\Lexers\ModelLexer());
25+
$this->blueprint->registerGenerator(new FactoryGenerator());
26+
}
27+
28+
/**
29+
* @test
30+
*/
31+
public function output_writes_nothing_for_empty_tree()
32+
{
33+
$this->file->expects('get')
34+
->with('stubs/factory.stub')
35+
->andReturn(file_get_contents('stubs/factory.stub'));
36+
37+
$this->file->shouldNotHaveReceived('put');
38+
39+
$this->blueprint->generate(['models' => []]);
40+
}
41+
42+
/**
43+
* @test
44+
* @dataProvider modelTreeDataProvider
45+
*/
46+
public function output_writes_migration_for_model_tree($definition, $path, $migration)
47+
{
48+
$this->file->expects('get')
49+
->with('stubs/factory.stub')
50+
->andReturn(file_get_contents('stubs/factory.stub'));
51+
52+
$this->file->expects('put')
53+
->with($path, $this->fixture($migration));
54+
55+
$tokens = $this->blueprint->parse($this->fixture($definition));
56+
$tree = $this->blueprint->analyze($tokens);
57+
$this->blueprint->generate($tree);
58+
}
59+
60+
61+
public function modelTreeDataProvider()
62+
{
63+
return [
64+
['definitions/post.bp', 'build/PostFactory.php', 'factories/post.php']
65+
];
66+
}
67+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace Tests\Feature\Generators;
4+
5+
use Blueprint\Blueprint;
6+
use Blueprint\Generators\MigrationGenerator;
7+
use Blueprint\Model;
8+
use Carbon\Carbon;
9+
use Illuminate\Support\Facades\File;
10+
use Tests\TestCase;
11+
12+
class MigrationGeneratorTest extends TestCase
13+
{
14+
private $blueprint;
15+
16+
private $file;
17+
18+
protected function setUp()
19+
{
20+
parent::setUp();
21+
22+
$this->file = \Mockery::mock();
23+
File::swap($this->file);
24+
25+
$this->blueprint = new Blueprint();
26+
$this->blueprint->registerLexer(new \Blueprint\Lexers\ModelLexer());
27+
$this->blueprint->registerGenerator(new MigrationGenerator());
28+
}
29+
30+
/**
31+
* @test
32+
*/
33+
public function output_writes_nothing_for_empty_tree()
34+
{
35+
$this->file->expects('get')
36+
->with('stubs/migration.stub')
37+
->andReturn(file_get_contents('stubs/migration.stub'));
38+
39+
$this->file->shouldNotHaveReceived('put');
40+
41+
$this->blueprint->generate(['models' => []]);
42+
}
43+
44+
/**
45+
* @test
46+
* @dataProvider modelTreeDataProvider
47+
*/
48+
public function output_writes_migration_for_model_tree($definition, $path, $migration)
49+
{
50+
$this->file->expects('get')
51+
->with('stubs/migration.stub')
52+
->andReturn(file_get_contents('stubs/migration.stub'));
53+
54+
$now = Carbon::now();
55+
Carbon::setTestNow($now);
56+
57+
$timestamp_path = str_replace('timestamp', $now->format('Y_m_d_His'), $path);
58+
59+
$this->file->expects('put')
60+
->with($timestamp_path, $this->fixture($migration));
61+
62+
$tokens = $this->blueprint->parse($this->fixture($definition));
63+
$tree = $this->blueprint->analyze($tokens);
64+
$this->blueprint->generate($tree);
65+
}
66+
67+
68+
public function modelTreeDataProvider()
69+
{
70+
return [
71+
['definitions/readme-example.bp', 'build/timestamp_create_posts_table.php', 'migrations/readme-example.php'],
72+
['definitions/model-identities.bp', 'build/timestamp_create_relationships_table.php', 'migrations/identity-columns.php'],
73+
['definitions/model-modifiers.bp', 'build/timestamp_create_modifiers_table.php', 'migrations/modifiers.php'],
74+
// TODO: optimizations like nullableTimestamp, unsignedInteger, etc
75+
];
76+
}
77+
}

0 commit comments

Comments
 (0)