Skip to content

Commit

Permalink
Merge pull request #2 from Astrotomic/issue-1
Browse files Browse the repository at this point in the history
add model assertion that two models are related
  • Loading branch information
Gummibeer authored Mar 10, 2021
2 parents 0ce82cd + 52bb5d9 commit ee9a6c2
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 23 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ This will prevent any method name conflicts with core, your custom or other trai
```php
\Astrotomic\PhpunitAssertions\Laravel\ModelAssertions::assertExists($model);
\Astrotomic\PhpunitAssertions\Laravel\ModelAssertions::assertSame($model, \App\Models\User::first());
\Astrotomic\PhpunitAssertions\Laravel\ModelAssertions::assertRelated($post, 'comments', $comment);
\Astrotomic\PhpunitAssertions\Laravel\ModelAssertions::assertRelated(
$post,
'comments',
\App\Models\Comment::class,
\Illuminate\Database\Eloquent\Relations\HasMany::class
);
```

### Blade
Expand Down
39 changes: 39 additions & 0 deletions src/Laravel/ModelAssertions.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
namespace Astrotomic\PhpunitAssertions\Laravel;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Facades\DB;
use Illuminate\Testing\Constraints\HasInDatabase;
use PHPUnit\Framework\Assert as PHPUnit;

trait ModelAssertions
{
/**
* @param string|\Illuminate\Database\Eloquent\Model $table
* @param array $data
* @param string|null $connection
*/
public static function assertExists($table, array $data = [], ?string $connection = null): void
{
if ($table instanceof Model) {
Expand All @@ -27,10 +33,43 @@ public static function assertExists($table, array $data = [], ?string $connectio
);
}

/**
* @param \Illuminate\Database\Eloquent\Model $expected
* @param \Illuminate\Database\Eloquent\Model|mixed $actual
*/
public static function assertSame(Model $expected, $actual): void
{
PHPUnit::assertInstanceOf(get_class($expected), $actual);
PHPUnit::assertSame($expected->exists, $actual->exists);
PHPUnit::assertTrue($expected->is($actual));
}

/**
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $relation
* @param string|\Illuminate\Database\Eloquent\Model|mixed $actual
* @param string|null $type
*/
public static function assertRelated(Model $model, string $relation, $actual, ?string $type = null)
{
PHPUnit::assertTrue(method_exists($model, $relation));
PHPUnit::assertInstanceOf(Relation::class, $model->$relation());

if ($type) {
PHPUnit::assertInstanceOf($type, $model->$relation());
}

$related = $model->$relation()->getRelated();
PHPUnit::assertInstanceOf(Model::class, $related);

if (is_string($actual)) {
PHPUnit::assertInstanceOf($actual, $related);
} else {
PHPUnit::assertInstanceOf(get_class($actual), $related);
self::assertSame(
$actual,
$model->$relation()->whereKey($actual->getKey())->first()
);
}
}
}
64 changes: 41 additions & 23 deletions tests/Laravel/ModelAssertionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@
namespace Astrotomic\PhpunitAssertions\Tests\Laravel;

use Astrotomic\PhpunitAssertions\Laravel\ModelAssertions;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Astrotomic\PhpunitAssertions\Tests\Laravel\Models\Comment;
use Astrotomic\PhpunitAssertions\Tests\Laravel\Models\Post;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

final class ModelAssertionsTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();

Schema::create('posts', static function (Blueprint $table): void {
$table->increments('id');
$table->string('title');
$table->timestamps();
});
Post::migrate();
Comment::migrate();
}

/**
Expand All @@ -26,15 +24,11 @@ protected function setUp(): void
*/
public function it_can_validate_exists(): void
{
$model = new class extends Model {
protected $table = 'posts';
protected $guarded = [];
};
$post = Post::create([
'title' => self::randomString(),
]);

$model->title = self::randomString();
$model->save();

ModelAssertions::assertExists($model);
ModelAssertions::assertExists($post);
}

/**
Expand All @@ -43,14 +37,38 @@ public function it_can_validate_exists(): void
*/
public function it_can_validate_same(): void
{
$model = new class extends Model {
protected $table = 'posts';
protected $guarded = [];
};
$post = Post::create([
'title' => self::randomString(),
]);

ModelAssertions::assertSame($post, Post::first());
}

/**
* @test
* @dataProvider hundredTimes
*/
public function it_can_validate_relationship(): void
{
$post = Post::create([
'title' => self::randomString(),
]);

$comment = Comment::create([
'message' => self::randomString(),
'post_id' => $post->getKey(),
]);

ModelAssertions::assertRelated($post, 'comments', Comment::class);
ModelAssertions::assertRelated($post, 'comments', $comment);

ModelAssertions::assertRelated($post, 'comments', Comment::class, HasMany::class);
ModelAssertions::assertRelated($post, 'comments', $comment, HasMany::class);

$model->title = self::randomString();
$model->save();
ModelAssertions::assertRelated($comment, 'post', Post::class);
ModelAssertions::assertRelated($comment, 'post', $post);

ModelAssertions::assertSame($model, $model->query()->first());
ModelAssertions::assertRelated($comment, 'post', Post::class, BelongsTo::class);
ModelAssertions::assertRelated($comment, 'post', $post, BelongsTo::class);
}
}
29 changes: 29 additions & 0 deletions tests/Laravel/Models/Comment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Astrotomic\PhpunitAssertions\Tests\Laravel\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class Comment extends Model
{
protected $table = 'comments';
protected $guarded = [];

public static function migrate(): void
{
Schema::create((new self)->table, static function (Blueprint $table): void {
$table->increments('id');
$table->text('message');
$table->foreignId('post_id')->constrained('posts');
$table->timestamps();
});
}

public function post(): BelongsTo
{
return $this->belongsTo(Post::class);
}
}
28 changes: 28 additions & 0 deletions tests/Laravel/Models/Post.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Astrotomic\PhpunitAssertions\Tests\Laravel\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class Post extends Model
{
protected $table = 'posts';
protected $guarded = [];

public static function migrate(): void
{
Schema::create((new self)->table, static function (Blueprint $table): void {
$table->increments('id');
$table->string('title');
$table->timestamps();
});
}

public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
}

0 comments on commit ee9a6c2

Please sign in to comment.