Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse fake dates into Carbon objects #676

Merged
merged 3 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions src/Generators/PestTestGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Blueprint\Contracts\Model as BlueprintModel;
use Blueprint\Models\Column;
use Blueprint\Models\Controller;
use Blueprint\Models\Model;
use Blueprint\Models\Statements\DispatchStatement;
use Blueprint\Models\Statements\EloquentStatement;
use Blueprint\Models\Statements\FireStatement;
Expand Down Expand Up @@ -99,6 +98,7 @@ protected function buildTestCases(Controller $controller): string
'mock' => [],
];
$request_data = [];
$model_columns = [];
$tested_bits = 0;

$model = $controller->prefix();
Expand Down Expand Up @@ -227,11 +227,17 @@ protected function buildTestCases(Controller $controller): string
} else {
$this->addImport($controller, 'function Pest\\Faker\\fake');

$faker = sprintf('$%s = fake()->%s;', $data, FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_model->column($column)->dataType()));
if ($local_column->isDate()) {
$this->addImport($controller, 'Illuminate\\Support\\Carbon');
$faker = sprintf('$%s = Carbon::parse(fake()->%s);', $data, FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_model->column($column)->dataType()));
} else {
$faker = sprintf('$%s = fake()->%s;', $data, FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_model->column($column)->dataType()));
}
}

$setup['data'][] = $faker;
$request_data[$data] = '$' . $variable_name;
$model_columns[$data] = '$' . $variable_name;
} elseif (!is_null($local_model)) {
foreach ($local_model->columns() as $local_column) {
if (in_array($local_column->name(), ['id', 'softdeletes', 'softdeletestz'])) {
Expand All @@ -248,12 +254,28 @@ protected function buildTestCases(Controller $controller): string
} else {
$this->addImport($controller, 'function Pest\\Faker\\fake');

$faker = sprintf('$%s = fake()->%s;', $local_column->name(), FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_column->dataType()));
if ($local_column->isDate()) {
$this->addImport($controller, 'Illuminate\\Support\\Carbon');
$faker = sprintf('$%s = Carbon::parse(fake()->%s);', $local_column->name(), FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_column->dataType()));
} else {
$faker = sprintf('$%s = fake()->%s;', $local_column->name(), FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_column->dataType()));
}

$variable_name = $local_column->name();
}

$setup['data'][] = $faker;
$request_data[$local_column->name()] = '$' . $variable_name;
if ($local_column->isDate()) {
if ($local_column->dataType() === 'date') {
$request_data[$local_column->name()] = '$' . $variable_name . '->toDateString()';
} else {
$request_data[$local_column->name()] = '$' . $variable_name . '->toDateTimeString()';
}
} else {
$request_data[$local_column->name()] = '$' . $variable_name;
}

$model_columns[$local_column->name()] = '$' . $variable_name;
}
}
}
Expand Down Expand Up @@ -404,11 +426,11 @@ protected function buildTestCases(Controller $controller): string
if ($statement->operation() === 'save') {
$tested_bits |= self::TESTS_SAVE;

if ($request_data) {
if ($model_columns) {
$indent = str_pad(' ', 8);
$plural = Str::plural($variable);
$assertion = sprintf('$%s = %s::query()', $plural, $model);
foreach ($request_data as $key => $datum) {
foreach ($model_columns as $key => $datum) {
$assertion .= PHP_EOL . sprintf('%s->where(\'%s\', %s)', $indent, $key, $datum);
}
$assertion .= PHP_EOL . $indent . '->get();';
Expand Down Expand Up @@ -441,13 +463,12 @@ protected function buildTestCases(Controller $controller): string
} elseif ($statement->operation() === 'update') {
$assertions['sanity'][] = sprintf('$%s->refresh();', $variable);

if ($request_data) {
if ($model_columns) {
/** @var \Blueprint\Models\Model $local_model */
$local_model = $this->tree->modelForContext($model);
foreach ($request_data as $key => $datum) {
if (!is_null($local_model) && $local_model->hasColumn($key) && $local_model->column($key)->dataType() === 'date') {
$this->addImport($controller, 'Carbon\\Carbon');
$assertions['generic'][] = sprintf('expect(Carbon::parse(%s))->toEqual($%s->%s);', $datum, $variable, $key);
foreach ($model_columns as $key => $datum) {
if (!is_null($local_model) && $local_model->hasColumn($key) && $local_model->column($key)->dataType() === 'timestamp') {
$assertions['generic'][] = sprintf('expect(%s->timestamp)->toEqual($%s->%s);', $datum, $variable, $key);
} else {
$assertions['generic'][] = sprintf('expect(%s)->toEqual($%s->%s);', $datum, $variable, $key);
}
Expand Down
41 changes: 31 additions & 10 deletions src/Generators/PhpUnitTestGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ protected function buildTestCases(Controller $controller): string
'mock' => [],
];
$request_data = [];
$model_columns = [];
$tested_bits = 0;

$model = $controller->prefix();
Expand Down Expand Up @@ -227,11 +228,17 @@ protected function buildTestCases(Controller $controller): string
if ($factory) {
[$faker, $variable_name] = $factory;
} else {
$faker = sprintf('$%s = $this->faker->%s;', $data, FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_model->column($column)->dataType()));
if ($local_column->isDate()) {
$this->addImport($controller, 'Illuminate\\Support\\Carbon');
$faker = sprintf('$%s = Carbon::parse($this->faker->%s);', $data, FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_model->column($column)->dataType()));
} else {
$faker = sprintf('$%s = $this->faker->%s;', $data, FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_model->column($column)->dataType()));
}
}

$setup['data'][] = $faker;
$request_data[$data] = '$' . $variable_name;
$model_columns[$data] = '$' . $variable_name;
} elseif (!is_null($local_model)) {
foreach ($local_model->columns() as $local_column) {
if (in_array($local_column->name(), ['id', 'softdeletes', 'softdeletestz'])) {
Expand All @@ -246,12 +253,27 @@ protected function buildTestCases(Controller $controller): string
if ($factory) {
[$faker, $variable_name] = $factory;
} else {
$faker = sprintf('$%s = $this->faker->%s;', $local_column->name(), FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_column->dataType()));
if ($local_column->isDate()) {
$this->addImport($controller, 'Illuminate\\Support\\Carbon');
$faker = sprintf('$%s = Carbon::parse($this->faker->%s);', $local_column->name(), FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_column->dataType()));
} else {
$faker = sprintf('$%s = $this->faker->%s;', $local_column->name(), FakerRegistry::fakerData($local_column->name()) ?? FakerRegistry::fakerDataType($local_column->dataType()));
}
$variable_name = $local_column->name();
}

$setup['data'][] = $faker;
$request_data[$local_column->name()] = '$' . $variable_name;
if ($local_column->isDate()) {
if ($local_column->dataType() === 'date') {
$request_data[$local_column->name()] = '$' . $variable_name . '->toDateString()';
} else {
$request_data[$local_column->name()] = '$' . $variable_name . '->toDateTimeString()';
}
} else {
$request_data[$local_column->name()] = '$' . $variable_name;
}

$model_columns[$local_column->name()] = '$' . $variable_name;
}
}
}
Expand Down Expand Up @@ -404,11 +426,11 @@ protected function buildTestCases(Controller $controller): string
if ($statement->operation() === 'save') {
$tested_bits |= self::TESTS_SAVE;

if ($request_data) {
if ($model_columns) {
$indent = str_pad(' ', 12);
$plural = Str::plural($variable);
$assertion = sprintf('$%s = %s::query()', $plural, $model);
foreach ($request_data as $key => $datum) {
foreach ($model_columns as $key => $datum) {
$assertion .= PHP_EOL . sprintf('%s->where(\'%s\', %s)', $indent, $key, $datum);
}
$assertion .= PHP_EOL . $indent . '->get();';
Expand All @@ -435,13 +457,12 @@ protected function buildTestCases(Controller $controller): string
} elseif ($statement->operation() === 'update') {
$assertions['sanity'][] = sprintf('$%s->refresh();', $variable);

if ($request_data) {
if ($model_columns) {
/** @var \Blueprint\Models\Model $local_model */
$local_model = $this->tree->modelForContext($model);
foreach ($request_data as $key => $datum) {
if (!is_null($local_model) && $local_model->hasColumn($key) && $local_model->column($key)->dataType() === 'date') {
$this->addImport($controller, 'Carbon\\Carbon');
$assertions['generic'][] = sprintf('$this->assertEquals(Carbon::parse(%s), $%s->%s);', $datum, $variable, $key);
foreach ($model_columns as $key => $datum) {
if (!is_null($local_model) && $local_model->hasColumn($key) && $local_model->column($key)->dataType() === 'timestamp') {
$assertions['generic'][] = sprintf('$this->assertEquals(%s->timestamp, $%s->%s);', $datum, $variable, $key);
} else {
$assertions['generic'][] = sprintf('$this->assertEquals(%s, $%s->%s);', $datum, $variable, $key);
}
Expand Down
9 changes: 9 additions & 0 deletions src/Models/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ public function modifiers(): array
return $this->modifiers;
}

public function isDate()
{
return in_array(strtolower($this->dataType()), [
'date',
'datetime',
'timestamp',
]);
}

public function isForeignKey()
{
return collect($this->modifiers())->filter(fn ($modifier) => (is_array($modifier) && key($modifier) === 'foreign') || $modifier === 'foreign')->flatten()->first();
Expand Down
5 changes: 4 additions & 1 deletion src/Models/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ public function addColumn(Column $column): void
$this->columns[$column->name()] = $column;
}

/**
* @return Column[]
*/
public function columns(): array
{
return $this->columns;
Expand Down Expand Up @@ -176,7 +179,7 @@ public function hasColumn(string $name): bool
return isset($this->columns[$name]);
}

public function column(string $name)
public function column(string $name): Column
{
return $this->columns[$name];
}
Expand Down
9 changes: 5 additions & 4 deletions tests/Feature/Generators/PestTestGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function output_writes_nothing_for_empty_tree(): void

#[Test]
#[DataProvider('controllerTreeDataProvider')]
public function output_generates_test_for_controller_tree_l8($definition, $path, $test): void
public function output_generates_test_for_controller_tree($definition, $path, $test): void
{
$this->filesystem->expects('stub')
->with('pest.test.class.stub')
Expand Down Expand Up @@ -78,7 +78,7 @@ public function output_generates_test_for_controller_tree_l8($definition, $path,
}

#[Test]
public function output_works_for_pascal_case_definition_l8(): void
public function output_works_for_pascal_case_definition(): void
{
$this->filesystem->expects('stub')
->with('pest.test.class.stub')
Expand Down Expand Up @@ -112,7 +112,7 @@ public function output_works_for_pascal_case_definition_l8(): void
}

#[Test]
public function output_generates_test_for_controller_tree_using_cached_model_l8(): void
public function output_generates_test_for_controller_tree_using_cached_model(): void
{
$this->filesystem->expects('stub')
->with('pest.test.class.stub')
Expand Down Expand Up @@ -145,7 +145,7 @@ public function output_generates_test_for_controller_tree_using_cached_model_l8(
}

#[Test]
public function output_generates_tests_with_models_with_custom_namespace_correctly_l8(): void
public function output_generates_tests_with_models_with_custom_namespace_correctly(): void
{
$definition = 'drafts/models-with-custom-namespace.yaml';
$path = 'tests/Feature/Http/Controllers/CategoryControllerTest.php';
Expand Down Expand Up @@ -224,6 +224,7 @@ public static function controllerTreeDataProvider(): array
['drafts/crud-show-only.yaml', 'tests/Feature/Http/Controllers/PostControllerTest.php', 'tests/pest/crud-show-only.php'],
['drafts/model-reference-validate.yaml', 'tests/Feature/Http/Controllers/CertificateControllerTest.php', 'tests/pest/api-shorthand-validation.php'],
['drafts/controllers-only-no-context.yaml', 'tests/Feature/Http/Controllers/ReportControllerTest.php', 'tests/pest/controllers-only-no-context.php'],
['drafts/date-formats.yaml', 'tests/Feature/Http/Controllers/DateControllerTest.php', 'tests/pest/date-formats.php'],
['drafts/call-to-a-member-function-columns-on-null.yaml', [
'tests/Feature/Http/Controllers/SubscriptionControllerTest.php',
'tests/Feature/Http/Controllers/TelegramControllerTest.php',
Expand Down
9 changes: 5 additions & 4 deletions tests/Feature/Generators/PhpUnitTestGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function output_writes_nothing_for_empty_tree(): void

#[Test]
#[DataProvider('controllerTreeDataProvider')]
public function output_generates_test_for_controller_tree_l8($definition, $path, $test): void
public function output_generates_test_for_controller_tree($definition, $path, $test): void
{
$this->filesystem->expects('stub')
->with('phpunit.test.class.stub')
Expand Down Expand Up @@ -78,7 +78,7 @@ public function output_generates_test_for_controller_tree_l8($definition, $path,
}

#[Test]
public function output_works_for_pascal_case_definition_l8(): void
public function output_works_for_pascal_case_definition(): void
{
$this->filesystem->expects('stub')
->with('phpunit.test.class.stub')
Expand Down Expand Up @@ -112,7 +112,7 @@ public function output_works_for_pascal_case_definition_l8(): void
}

#[Test]
public function output_generates_test_for_controller_tree_using_cached_model_l8(): void
public function output_generates_test_for_controller_tree_using_cached_model(): void
{
$this->filesystem->expects('stub')
->with('phpunit.test.class.stub')
Expand Down Expand Up @@ -145,7 +145,7 @@ public function output_generates_test_for_controller_tree_using_cached_model_l8(
}

#[Test]
public function output_generates_tests_with_models_with_custom_namespace_correctly_l8(): void
public function output_generates_tests_with_models_with_custom_namespace_correctly(): void
{
$definition = 'drafts/models-with-custom-namespace.yaml';
$path = 'tests/Feature/Http/Controllers/CategoryControllerTest.php';
Expand Down Expand Up @@ -224,6 +224,7 @@ public static function controllerTreeDataProvider(): array
['drafts/crud-show-only.yaml', 'tests/Feature/Http/Controllers/PostControllerTest.php', 'tests/phpunit/crud-show-only.php'],
['drafts/model-reference-validate.yaml', 'tests/Feature/Http/Controllers/CertificateControllerTest.php', 'tests/phpunit/api-shorthand-validation.php'],
['drafts/controllers-only-no-context.yaml', 'tests/Feature/Http/Controllers/ReportControllerTest.php', 'tests/phpunit/controllers-only-no-context.php'],
['drafts/date-formats.yaml', 'tests/Feature/Http/Controllers/DateControllerTest.php', 'tests/phpunit/date-formats.php'],
['drafts/call-to-a-member-function-columns-on-null.yaml', [
'tests/Feature/Http/Controllers/SubscriptionControllerTest.php',
'tests/Feature/Http/Controllers/TelegramControllerTest.php',
Expand Down
9 changes: 9 additions & 0 deletions tests/fixtures/drafts/date-formats.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
models:
Date:
born_at: date
expires_at: datetime
published_at: timestamp

controllers:
Date:
resource: web
Loading
Loading