Skip to content

Commit d6ac901

Browse files
committed
test(database): add unit tests for shouldUsePropertyNameAlias detection
Verify the query builder correctly flags duplicate target tables: - single relation: not aliased - duplicate target tables: both aliased - mixed relations: only duplicates aliased - nested relations under non-duplicate: not aliased
1 parent 26dab63 commit d6ac901

3 files changed

Lines changed: 142 additions & 3 deletions

File tree

packages/database/src/QueryStatements/FieldStatement.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function (string $part) use ($dialect) {
4949
return $part;
5050
}
5151

52-
return sprintf('`%s`', $part);
52+
return $dialect->quoteIdentifier($part);
5353
},
5454
)
5555
->implode('.');

packages/database/tests/QueryStatements/FieldStatementTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ public function test_mysql(): void
4747
public function test_postgres(): void
4848
{
4949
$this->assertSame(
50-
'`table`.`field`',
50+
'"table"."field"',
5151
new FieldStatement('`table`.`field`')->compile(DatabaseDialect::POSTGRESQL),
5252
);
5353

5454
$this->assertSame(
55-
'`table`.`field`',
55+
'"table"."field"',
5656
new FieldStatement('table.field')->compile(DatabaseDialect::POSTGRESQL),
5757
);
5858
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Tempest\Integration\Database\Builder;
6+
7+
use PHPUnit\Framework\Attributes\Test;
8+
use Tempest\Database\BelongsTo;
9+
use Tempest\Database\HasMany;
10+
use Tempest\Database\HasOne;
11+
use Tempest\Database\IsDatabaseModel;
12+
use Tempest\Database\Table;
13+
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;
14+
15+
use function Tempest\Database\query;
16+
17+
/**
18+
* @internal
19+
*/
20+
final class ShouldUsePropertyNameAliasTest extends FrameworkIntegrationTestCase
21+
{
22+
#[Test]
23+
public function single_relation_is_not_aliased(): void
24+
{
25+
$relations = query(model: SingleRelationModel::class)
26+
->select()
27+
->with('author')
28+
->getResolvedRelations();
29+
30+
$this->assertFalse($relations['author']->withPropertyNameAlias);
31+
}
32+
33+
#[Test]
34+
public function duplicate_target_tables_are_aliased(): void
35+
{
36+
$relations = query(model: DuplicateRelationModel::class)
37+
->select()
38+
->with('createdBy', 'updatedBy')
39+
->getResolvedRelations();
40+
41+
$this->assertTrue($relations['createdBy']->withPropertyNameAlias);
42+
$this->assertTrue($relations['updatedBy']->withPropertyNameAlias);
43+
}
44+
45+
#[Test]
46+
public function mixed_relations_only_alias_duplicates(): void
47+
{
48+
$relations = query(model: MixedRelationModel::class)
49+
->select()
50+
->with('title', 'createdBy', 'updatedBy')
51+
->getResolvedRelations();
52+
53+
$this->assertFalse($relations['title']->withPropertyNameAlias);
54+
$this->assertTrue($relations['createdBy']->withPropertyNameAlias);
55+
$this->assertTrue($relations['updatedBy']->withPropertyNameAlias);
56+
}
57+
58+
#[Test]
59+
public function nested_relations_under_non_duplicate_are_not_aliased(): void
60+
{
61+
$relations = query(model: SingleRelationModel::class)
62+
->select()
63+
->with('author', 'author.posts')
64+
->getResolvedRelations();
65+
66+
$this->assertFalse($relations['author']->withPropertyNameAlias);
67+
$this->assertFalse($relations['author.posts']->withPropertyNameAlias);
68+
}
69+
}
70+
71+
#[Table('alias_test_books')]
72+
final class SingleRelationModel
73+
{
74+
use IsDatabaseModel;
75+
76+
#[BelongsTo]
77+
public ?AliasTestAuthor $author = null;
78+
79+
public string $title;
80+
}
81+
82+
#[Table('alias_test_authors')]
83+
final class AliasTestAuthor
84+
{
85+
use IsDatabaseModel;
86+
87+
public string $name;
88+
89+
/** @var \Tests\Tempest\Integration\Database\Builder\SingleRelationModel[] */
90+
#[HasMany]
91+
public array $posts = [];
92+
}
93+
94+
#[Table('alias_test_items')]
95+
final class DuplicateRelationModel
96+
{
97+
use IsDatabaseModel;
98+
99+
#[BelongsTo(ownerJoin: 'created_by')]
100+
public ?AliasTestUser $createdBy = null;
101+
102+
#[BelongsTo(ownerJoin: 'updated_by')]
103+
public ?AliasTestUser $updatedBy = null;
104+
105+
public string $name;
106+
}
107+
108+
#[Table('alias_test_mixed')]
109+
final class MixedRelationModel
110+
{
111+
use IsDatabaseModel;
112+
113+
#[HasOne]
114+
public ?AliasTestTitle $title = null;
115+
116+
#[BelongsTo(ownerJoin: 'created_by')]
117+
public ?AliasTestUser $createdBy = null;
118+
119+
#[BelongsTo(ownerJoin: 'updated_by')]
120+
public ?AliasTestUser $updatedBy = null;
121+
122+
public string $name;
123+
}
124+
125+
#[Table('alias_test_users')]
126+
final class AliasTestUser
127+
{
128+
use IsDatabaseModel;
129+
130+
public string $name;
131+
}
132+
133+
#[Table('alias_test_titles')]
134+
final class AliasTestTitle
135+
{
136+
use IsDatabaseModel;
137+
138+
public string $value;
139+
}

0 commit comments

Comments
 (0)