Skip to content

Commit 56b13e1

Browse files
committed
test: full unit on Describer & Value - huge speedup feature test
1 parent 09293cb commit 56b13e1

File tree

9 files changed

+168
-119
lines changed

9 files changed

+168
-119
lines changed

tests/Feature/Comment/CollectionTest.php

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,16 @@ class CollectionTest extends FeatureTestCase
1616
{
1717
public function testIndexBasic()
1818
{
19-
$user = $this->dataSeed();
20-
2119
$response = $this->get("comment");
2220

23-
$response->assertExactJson($this->getJsonResult($user));
21+
$response->assertExactJson($this->getJsonResult(Comment::query()->limit(15)->get()));
2422
}
2523

2624
public function testIndexWithInclude()
2725
{
28-
$user = $this->dataSeed();
29-
3026
$response = $this->get("comment?include=post");
3127

32-
$response->assertExactJson($this->getJsonResult($user, null, ['post']));
33-
}
34-
35-
private function dataSeed()
36-
{
37-
$user = User::factory()->create();
38-
$posts = Post::factory()->for($user)->count(3)->create();
39-
$users = User::factory()->count(9)->create();
40-
foreach ($posts as $post) {
41-
foreach ($users->random(5) as $u) {
42-
Comment::factory()->for($post)->for($u)->create();
43-
}
44-
}
45-
46-
return Comment::all();
28+
$response->assertExactJson($this->getJsonResult(Comment::query()->limit(15)->get(), null, ['post']));
4729
}
4830

4931
private function getJsonResult(Collection $comments, ?array $attributes = null, ?array $relationships = null)
@@ -105,14 +87,14 @@ private function getJsonResult(Collection $comments, ?array $attributes = null,
10587
'included' => $include->uniqueStrict()->values()->all(),
10688
"links" => [
10789
"first" => "http://localhost/comment?page=1",
108-
"last" => "http://localhost/comment?page=1",
109-
"next" => null,
90+
"last" => "http://localhost/comment?page=10",
91+
"next" => "http://localhost/comment?page=2",
11092
"prev" => null
11193
],
11294
"meta" => [
11395
'current_page' => 1,
11496
'from' => 1,
115-
'last_page' => 1,
97+
'last_page' => 10,
11698
'links' => [
11799
[
118100
'active' => false,
@@ -124,16 +106,21 @@ private function getJsonResult(Collection $comments, ?array $attributes = null,
124106
'label' => '1',
125107
'url' => "http://localhost/comment?page=1",
126108
],
109+
...(array_map(static fn($value) => [
110+
'active' => false,
111+
'label' => (string)$value,
112+
'url' => "http://localhost/comment?page=$value",
113+
], range(2, 10))),
127114
[
128115
'active' => false,
129116
'label' => "Next »",
130-
'url' => null,
117+
'url' => "http://localhost/comment?page=2",
131118
],
132119
],
133120
'path' => 'http://localhost/comment',
134121
'per_page' => 15,
135122
'to' => 15,
136-
'total' => 15,
123+
'total' => 150,
137124
],
138125
]))
139126
->toArray();

tests/Feature/FeatureTestCase.php

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,60 @@
33
namespace Test\Feature;
44

55
use Illuminate\Foundation\Testing\RefreshDatabase;
6-
use Test\Support\UseLocalApp;
6+
use Illuminate\Support\Facades\DB;
7+
use Test\app\Models\Comment;
8+
use Test\app\Models\Post;
9+
use Test\app\Models\User;
710
use Test\TestCase;
811

912
abstract class FeatureTestCase extends TestCase
1013
{
11-
use RefreshDatabase, UseLocalApp;
14+
use RefreshDatabase;
1215

13-
public function setUp(): void
16+
protected function defineRoutes($router)
1417
{
15-
parent::setUp();
16-
$this->useLocalApp();
18+
include __DIR__ . '/../app/routes.php';
19+
}
20+
21+
protected function afterRefreshingDatabase()
22+
{
23+
$this->loadMigrationsFrom(__DIR__ . '/../app/migrations.php');
24+
25+
self::loadSeed();
26+
}
27+
28+
private static function loadSeed(): void
29+
{
30+
static $seed;
31+
32+
DB::beginTransaction();
33+
34+
if (isset($seed)) {
35+
foreach ($seed as $query) {
36+
DB::statement($query['query'], $query['bindings']);
37+
}
38+
} else {
39+
DB::enableQueryLog();
40+
self::dataSeed();
41+
$seed = DB::getQueryLog();
42+
DB::disableQueryLog();
43+
DB::flushQueryLog();
44+
}
45+
46+
DB::commit();
47+
}
48+
49+
private static function dataSeed(): void
50+
{
51+
$users = User::factory()->count(10)->create();
52+
53+
foreach ($users as $udx => $user) {
54+
$posts = Post::factory()->for($user)->count(3)->create();
55+
foreach ($posts as $post) {
56+
foreach ($users->except($udx)->random(5) as $u) {
57+
Comment::factory()->for($post)->for($u)->create();
58+
}
59+
}
60+
}
1761
}
1862
}

tests/Feature/User/CollectionTest.php

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use DateTimeInterface;
66
use Illuminate\Http\Request;
77
use Illuminate\Support\Collection;
8+
use Illuminate\Support\Facades\DB;
9+
use Illuminate\Support\Facades\Schema;
810
use Test\app\Http\Resources\CommentResource;
911
use Test\app\Http\Resources\PostResource;
1012
use Test\app\Models\Comment;
@@ -16,30 +18,14 @@ class CollectionTest extends FeatureTestCase
1618
{
1719
public function testGetIndex()
1820
{
19-
$users = $this->dataSeed();
21+
$users = User::all();
2022

2123
$expected = $this->getJsonResult($users);
2224

2325
$response = $this->get('user');
2426
$response->assertJson($expected);
2527
}
2628

27-
private function dataSeed()
28-
{
29-
$users = User::factory()->count(10)->create();
30-
31-
foreach ($users as $udx => $user) {
32-
$posts = Post::factory()->for($user)->count(3)->create();
33-
foreach ($posts as $post) {
34-
foreach ($users->except($udx)->random(5) as $u) {
35-
Comment::factory()->for($post)->for($u)->create();
36-
}
37-
}
38-
}
39-
40-
return $users;
41-
}
42-
4329
private function getJsonResult(Collection $users, ?array $attributes = null, ?array $relationships = null)
4430
{
4531
$request = new Request(array_merge(

tests/Feature/User/ResourceTest.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,20 +134,9 @@ public function testShowMultipleFailures()
134134
]]);
135135
}
136136

137-
138137
private function dataSeed()
139138
{
140-
/** @var User $user */
141-
$user = User::factory()->create();
142-
$posts = Post::factory()->for($user)->count(3)->create();
143-
$users = User::factory()->count(9)->create();
144-
foreach ($posts as $post) {
145-
foreach ($users->random(5) as $u) {
146-
Comment::factory()->for($post)->for($u)->create();
147-
}
148-
}
149-
150-
return $user;
139+
return User::first();
151140
}
152141

153142
private function getJsonResult(User $user, ?array $attributes = null, ?array $relationships = null)

tests/Support/UseLocalApp.php

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace Test\Unit\Descriptors;
4+
5+
use Ark4ne\JsonApi\Descriptors\Descriptors;
6+
use Ark4ne\JsonApi\Descriptors\Relations\RelationMany;
7+
use Ark4ne\JsonApi\Descriptors\Relations\RelationOne;
8+
use Ark4ne\JsonApi\Descriptors\Values\ValueArray;
9+
use Ark4ne\JsonApi\Descriptors\Values\ValueBool;
10+
use Ark4ne\JsonApi\Descriptors\Values\ValueDate;
11+
use Ark4ne\JsonApi\Descriptors\Values\ValueFloat;
12+
use Ark4ne\JsonApi\Descriptors\Values\ValueInteger;
13+
use Ark4ne\JsonApi\Descriptors\Values\ValueMixed;
14+
use Ark4ne\JsonApi\Descriptors\Values\ValueString;
15+
use Ark4ne\JsonApi\Resources\JsonApiCollection;
16+
use Ark4ne\JsonApi\Resources\JsonApiResource;
17+
use Closure;
18+
use Test\Support\Reflect;
19+
use Test\TestCase;
20+
21+
class DescriptorsTraitTest extends TestCase
22+
{
23+
public function methods()
24+
{
25+
return [
26+
'bool' => [ValueBool::class, 'bool'],
27+
'integer' => [ValueInteger::class, 'integer'],
28+
'float' => [ValueFloat::class, 'float'],
29+
'string' => [ValueString::class, 'string'],
30+
'date' => [ValueDate::class, 'date'],
31+
'array' => [ValueArray::class, 'array'],
32+
'mixed' => [ValueMixed::class, 'mixed'],
33+
'one' => [RelationOne::class, 'one', JsonApiResource::class],
34+
'many' => [RelationMany::class, 'many', JsonApiCollection::class],
35+
];
36+
}
37+
38+
/**
39+
* @dataProvider methods
40+
*/
41+
public function testDescriptorTrait($expected, $method, ...$args)
42+
{
43+
$mock = new class {
44+
use Descriptors;
45+
};
46+
/** @var \Ark4ne\JsonApi\Descriptors\Describer $descriptor */
47+
$descriptor = Reflect::invoke($mock, $method, ...$args);
48+
$this->assertInstanceOf($expected, $descriptor);
49+
$this->assertNull($descriptor->retriever());
50+
$descriptor = Reflect::invoke($mock, $method, ...[...$args, 'test']);
51+
$this->assertInstanceOf($expected, $descriptor);
52+
$this->assertEquals('test', $descriptor->retriever());
53+
$descriptor = Reflect::invoke($mock, $method, ...[...$args, fn() => 'closure']);
54+
$this->assertInstanceOf($expected, $descriptor);
55+
$this->assertInstanceOf(Closure::class, $descriptor->retriever());
56+
}
57+
}

tests/Unit/Descriptors/ValueTest.php

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,34 @@ public function values()
2727

2828
return [
2929
// class, value, expected, expected for null
30-
[ValueBool::class, 0, false, false],
31-
[ValueBool::class, 1, true, false],
32-
[ValueInteger::class, 123, 123, 0],
33-
[ValueInteger::class, 123.12, 123, 0],
34-
[ValueInteger::class, '123', 123, 0],
35-
[ValueFloat::class, '123', 123, 0],
36-
[ValueFloat::class, '123.12', 123.12, 0],
37-
[ValueFloat::class, 123.12, 123.12, 0],
38-
[ValueString::class, 'abc', 'abc', ''],
39-
[ValueString::class, true, '1', ''],
40-
[ValueString::class, 123.12, '123.12', ''],
41-
[ValueString::class, collect([]), (string)collect([]), ''],
42-
[ValueArray::class, [], [], []],
43-
[ValueArray::class, collect([]), [], []],
44-
[ValueArray::class, [123], [123], []],
45-
[ValueArray::class, collect([123]), [123], []],
46-
[ValueMixed::class, 0, 0, null],
47-
[ValueMixed::class, 1, 1, null],
48-
[ValueMixed::class, false, false, null],
49-
[ValueMixed::class, true, true, null],
50-
[ValueMixed::class, 'abc', 'abc', null],
51-
[ValueMixed::class, [], [], null],
52-
[ValueMixed::class, collect(), collect(), null],
53-
[ValueDate::class, '2022-01-01', '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
54-
[ValueDate::class, '2022-01-01 00:00:00', '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
55-
[ValueDate::class, 1640995200, '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
56-
[ValueDate::class, new DateTime("@1640995200"), '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
57-
[ValueDate::class, new Carbon("@1640995200"), '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
30+
'bool.0' => [ValueBool::class, 0, false, false],
31+
'bool.1' => [ValueBool::class, 1, true, false],
32+
'integer.0' => [ValueInteger::class, 123, 123, 0],
33+
'integer.1' => [ValueInteger::class, 123.12, 123, 0],
34+
'integer.2' => [ValueInteger::class, '123', 123, 0],
35+
'float.0' => [ValueFloat::class, '123', 123, 0],
36+
'float.1' => [ValueFloat::class, '123.12', 123.12, 0],
37+
'float.2' => [ValueFloat::class, 123.12, 123.12, 0],
38+
'string.0' => [ValueString::class, 'abc', 'abc', ''],
39+
'string.1' => [ValueString::class, true, '1', ''],
40+
'string.2' => [ValueString::class, 123.12, '123.12', ''],
41+
'string.3' => [ValueString::class, collect([]), (string)collect([]), ''],
42+
'array.0' => [ValueArray::class, [], [], []],
43+
'array.1' => [ValueArray::class, collect([]), [], []],
44+
'array.2' => [ValueArray::class, [123], [123], []],
45+
'array.3' => [ValueArray::class, collect([123]), [123], []],
46+
'mixed.0' => [ValueMixed::class, 0, 0, null],
47+
'mixed.1' => [ValueMixed::class, 1, 1, null],
48+
'mixed.2' => [ValueMixed::class, false, false, null],
49+
'mixed.3' => [ValueMixed::class, true, true, null],
50+
'mixed.4' => [ValueMixed::class, 'abc', 'abc', null],
51+
'mixed.5' => [ValueMixed::class, [], [], null],
52+
'mixed.6' => [ValueMixed::class, collect(), collect(), null],
53+
'date.0' => [ValueDate::class, '2022-01-01', '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
54+
'date.1' => [ValueDate::class, '2022-01-01 00:00:00', '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
55+
'date.2' => [ValueDate::class, 1640995200, '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
56+
'date.3' => [ValueDate::class, new DateTime("@1640995200"), '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
57+
'date.4' => [ValueDate::class, new Carbon("@1640995200"), '2022-01-01T00:00:00+00:00', '1970-01-01T00:00:00+00:00'],
5858
];
5959
}
6060

tests/app/Http/Resources/PostResource.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ protected function toType(Request $request): string
1616
return 'post';
1717
}
1818

19-
protected function toAttributes(Request $request): iterable
20-
{
21-
return [
22-
'title' => $this->string(),
23-
'content' => $this->string()->whenInFields(),
24-
];
25-
}
19+
protected function toAttributes(Request $request): iterable
20+
{
21+
return [
22+
'title' => $this->string(),
23+
'content' => $this->string()->whenInFields(),
24+
];
25+
}
2626

2727
protected function toResourceMeta(Request $request): ?iterable
2828
{
@@ -35,10 +35,10 @@ protected function toResourceMeta(Request $request): ?iterable
3535
protected function toRelationships(Request $request): iterable
3636
{
3737
return [
38-
$this->one(UserResource::class, 'user')->links(fn() => [
38+
'user' => $this->one(UserResource::class)->links(fn() => [
3939
'self' => "https://api.example.com/posts/{$this->resource->id}/relationships/user",
4040
]),
41-
$this->many(CommentResource::class, 'comments')->links(fn() => [
41+
'comments' => $this->many(CommentResource::class)->links(fn() => [
4242
'self' => "https://api.example.com/posts/{$this->resource->id}/relationships/comments",
4343
'related' => "https://api.example.com/posts/{$this->resource->id}/comments",
4444
]),

0 commit comments

Comments
 (0)