Skip to content

Commit 5151f18

Browse files
committed
tests: add full test coverage
1 parent 27da53d commit 5151f18

File tree

11 files changed

+337
-1
lines changed

11 files changed

+337
-1
lines changed

src/ServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ServiceProvider extends IlluminateServiceProvider implements DeferrablePro
1919
#[Override]
2020
public function provides(): array
2121
{
22-
return [EntityManager::class];
22+
return [EntityManager::class]; // @codeCoverageIgnore
2323
}
2424

2525
#[Override]

testbench.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
---
22
providers:
33
- CalebDW\SqlEntities\ServiceProvider
4+
laravel: ./workbench
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use CalebDW\SqlEntities\Entities\Entity;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Illuminate\Database\Query\Builder;
8+
9+
beforeEach(function () {
10+
test()->entity = new FooEntity();
11+
});
12+
13+
it('converts entity to string', function () {
14+
$expected = 'select "id", "name" from "foo"';
15+
16+
expect((string) test()->entity)
17+
->toBe($expected);
18+
19+
expect(test()->entity->toString())
20+
->toBe($expected);
21+
});
22+
23+
class Foo extends Model
24+
{
25+
protected $table = 'foo';
26+
}
27+
28+
class FooEntity extends Entity
29+
{
30+
public function name(): string
31+
{
32+
return 'foo_entity';
33+
}
34+
35+
public function definition(): Builder|string
36+
{
37+
return Foo::query()
38+
->select('id', 'name')
39+
->toBase();
40+
}
41+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use CalebDW\SqlEntities\Entities\Entity;
6+
use CalebDW\SqlEntities\Entities\View;
7+
use CalebDW\SqlEntities\EntityManager;
8+
use Illuminate\Database\Connection;
9+
use Illuminate\Database\DatabaseManager;
10+
use Workbench\Database\Entities\views\FooConnectionUserView;
11+
use Workbench\Database\Entities\views\UserView;
12+
13+
beforeEach(function () {
14+
test()->connection = test()->mock(Connection::class);
15+
16+
$db = test()->mock(DatabaseManager::class)
17+
->shouldReceive('connection')
18+
->andReturn(test()->connection)
19+
->getMock();
20+
app()->instance('db', $db);
21+
22+
test()->manager = resolve(EntityManager::class);
23+
});
24+
25+
afterEach(function () {
26+
Mockery::close();
27+
});
28+
29+
it('loads the entities')
30+
->expect(test()->manager->entities)
31+
->not->toBeEmpty();
32+
33+
describe('get', function () {
34+
it('returns the entity by name', function () {
35+
$entity = test()->manager->get('users_view');
36+
37+
expect($entity)->toBeInstanceOf(UserView::class);
38+
});
39+
40+
it('returns the entity by name and connection', function () {
41+
$entity = test()->manager->get('users_view', 'foo');
42+
43+
expect($entity)->toBeInstanceOf(FooConnectionUserView::class);
44+
});
45+
46+
it('throws an exception for unknown entity', function () {
47+
$entity = test()->manager->get('unknown');
48+
})->throws(InvalidArgumentException::class, 'Entity [unknown] not found.');
49+
});
50+
51+
it('creates an entity', function (string|Entity $entity) {
52+
test()->connection
53+
->shouldReceive('getDriverName')->once()->andReturn('sqlite')
54+
->shouldReceive('statement')
55+
->once()
56+
->withArgs(fn ($sql) => str_contains($sql, 'CREATE VIEW'));
57+
58+
test()->manager->create($entity);
59+
})->with([
60+
'name' => 'users_view',
61+
'entity' => new UserView(),
62+
]);
63+
64+
it('drops an entity', function (string|Entity $entity) {
65+
test()->connection
66+
->shouldReceive('getDriverName')->once()->andReturn('pgsql')
67+
->shouldReceive('statement')
68+
->once()
69+
->withArgs(fn ($sql) => str_contains($sql, 'DROP VIEW'));
70+
71+
test()->manager->drop($entity);
72+
})->with([
73+
'name' => 'users_view',
74+
'entity' => new UserView(),
75+
]);
76+
77+
it('creates entities by type and connection', function () {
78+
test()->connection
79+
->shouldReceive('getDriverName')->once()->andReturn('sqlite')
80+
->shouldReceive('statement')
81+
->once()
82+
->withArgs(fn ($sql) => str_contains($sql, 'CREATE VIEW'));
83+
84+
test()->manager->createAll(View::class, 'foo');
85+
});
86+
87+
it('drops entities by type and connection', function () {
88+
test()->connection
89+
->shouldReceive('getDriverName')->once()->andReturn('pgsql')
90+
->shouldReceive('statement')
91+
->once()
92+
->withArgs(fn ($sql) => str_contains($sql, 'DROP VIEW'));
93+
94+
test()->manager->dropAll(View::class, 'foo');
95+
});
96+
97+
it('throws exception for unsupported driver', function () {
98+
test()->connection
99+
->shouldReceive('getDriverName')
100+
->andReturn('unknown');
101+
102+
resolve(EntityManager::class)->create(new UserView());
103+
})->throws(InvalidArgumentException::class, 'Unsupported driver [unknown].');
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use CalebDW\SqlEntities\Entities\Entity;
6+
use CalebDW\SqlEntities\Entities\View;
7+
use CalebDW\SqlEntities\Grammars\Grammar;
8+
use Illuminate\Database\Connection;
9+
use Illuminate\Database\Query\Builder;
10+
11+
beforeEach(function () {
12+
$connection = Mockery::mock(Connection::class);
13+
14+
test()->grammar = new TestGrammar($connection);
15+
});
16+
17+
it('throws exception when creating unknown entity', function () {
18+
$entity = new UnknownEntity();
19+
20+
test()->grammar->compileCreate($entity);
21+
})->throws(InvalidArgumentException::class, 'Unsupported entity [UnknownEntity].');
22+
23+
it('throws exception when dropping unknown entity', function () {
24+
$entity = new UnknownEntity();
25+
26+
test()->grammar->compileDrop($entity);
27+
})->throws(InvalidArgumentException::class, 'Unsupported entity [UnknownEntity].');
28+
29+
class TestGrammar extends Grammar
30+
{
31+
public function compileViewCreate(View $view): string
32+
{
33+
return '';
34+
}
35+
36+
public function compileViewDrop(View $view): string
37+
{
38+
return '';
39+
}
40+
}
41+
42+
class UnknownEntity extends Entity
43+
{
44+
public function name(): string
45+
{
46+
return 'unknown_entity';
47+
}
48+
49+
public function definition(): Builder|string
50+
{
51+
return '';
52+
}
53+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use CalebDW\SqlEntities\Grammars\PostgresGrammar;
6+
use Illuminate\Database\Connection;
7+
use Workbench\Database\Entities\views\UserView;
8+
9+
beforeEach(function () {
10+
$connection = Mockery::mock(Connection::class);
11+
12+
test()->grammar = new PostgresGrammar($connection);
13+
});
14+
15+
it('compiles view create', function () {
16+
$sql = test()->grammar->compileCreate(new UserView());
17+
18+
expect($sql)->toBe(<<<'SQL'
19+
CREATE OR REPLACE VIEW users_view AS
20+
SELECT id, name FROM users
21+
SQL);
22+
});
23+
24+
it('compiles view drop', function () {
25+
$sql = test()->grammar->compileDrop(new UserView());
26+
27+
expect($sql)->toBe(<<<'SQL'
28+
DROP VIEW IF EXISTS users_view CASCADE
29+
SQL);
30+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use CalebDW\SqlEntities\Grammars\SQLiteGrammar;
6+
use Illuminate\Database\Connection;
7+
use Workbench\Database\Entities\views\UserView;
8+
9+
beforeEach(function () {
10+
$connection = Mockery::mock(Connection::class);
11+
12+
test()->grammar = new SQLiteGrammar($connection);
13+
});
14+
15+
it('compiles view drop', function () {
16+
$sql = test()->grammar->compileCreate(new UserView());
17+
18+
expect($sql)->toBe(<<<'SQL'
19+
CREATE VIEW users_view AS
20+
SELECT id, name FROM users
21+
SQL);
22+
});
23+
24+
it('compiles view create', function () {
25+
$sql = test()->grammar->compileDrop(new UserView());
26+
27+
expect($sql)->toBe(<<<'SQL'
28+
DROP VIEW IF EXISTS users_view
29+
SQL);
30+
});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore

workbench/composer.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "laravel/laravel",
3+
"description": "The Laravel Framework.",
4+
"keywords": [
5+
"framework",
6+
"laravel"
7+
],
8+
"license": "MIT",
9+
"type": "project",
10+
"autoload": {
11+
"psr-4": {
12+
"App\\": "app/",
13+
"Workbench\\Database\\Entities\\": "database/entities/",
14+
"Database\\Factories\\": "database/factories/",
15+
"Database\\Seeders\\": "database/seeders/"
16+
}
17+
},
18+
"autoload-dev": {
19+
"psr-4": {
20+
"Tests\\": "tests/"
21+
}
22+
},
23+
"minimum-stability": "dev"
24+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Workbench\Database\Entities\views;
6+
7+
use CalebDW\SqlEntities\Entities\View;
8+
use Override;
9+
10+
class FooConnectionUserView extends View
11+
{
12+
#[Override]
13+
public function name(): string
14+
{
15+
return 'users_view';
16+
}
17+
18+
#[Override]
19+
public function definition(): string
20+
{
21+
return 'SELECT id, name FROM users';
22+
}
23+
24+
#[Override]
25+
public function connectionName(): string
26+
{
27+
return 'foo';
28+
}
29+
}

0 commit comments

Comments
 (0)