Skip to content

Commit 48e0394

Browse files
committed
test: add ColumnNormalizationTest
Add test to validate chain resolution and alias inference - Covers dot-based and dotless expressions with and without aliases - Verifies field inference for valid and invalid relationship chains - Confirms suffix-based aggregate handling and auto-aliasing behavior - Includes HAVING and ORDER BY clause tests for __count expressions
1 parent 8fa2976 commit 48e0394

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
namespace protich\AutoJoinEloquent\Tests\Unit;
4+
5+
use protich\AutoJoinEloquent\Tests\AutoJoinTestCase;
6+
use protich\AutoJoinEloquent\Tests\Models\User;
7+
8+
class ColumnNormalizationTest extends AutoJoinTestCase
9+
{
10+
public function test_dot_based_column_is_preserved(): void
11+
{
12+
$query = User::query()
13+
->select(['name as Name', 'agent__departments|inner.name as
14+
Department', 'agent__departments__manager__user.name as
15+
mgr_name']);
16+
17+
$sql = $this->debugSql($query);
18+
19+
$this->assertStringContainsStringIgnoringCase('JOIN', $sql);
20+
$this->assertStringContainsStringIgnoringCase('."name"', $sql);
21+
$this->assertStringContainsStringIgnoringCase('as "mgr_name"', $sql);
22+
23+
$this->assertNonEmptyResults($query->get()->toArray());
24+
}
25+
26+
public function test_column_without_dot_infers_primary_key_field(): void
27+
{
28+
$query = User::query()
29+
->select(['name as Name', 'agent__departments|inner.name as
30+
Department', 'agent__departments__manager__user']);
31+
32+
$sql = $this->debugSql($query);
33+
34+
$this->assertStringContainsStringIgnoringCase('JOIN', $sql);
35+
$this->assertStringContainsStringIgnoringCase('."id"', $sql);
36+
$this->assertStringContainsStringIgnoringCase('agent__departments__manager__user', $sql);
37+
38+
$this->assertNonEmptyResults($query->get()->toArray());
39+
}
40+
41+
public function test_plain_field_expression_is_not_joined(): void
42+
{
43+
$query = User::query()
44+
->select(['id', 'status']);
45+
46+
$sql = $this->debugSql($query);
47+
48+
$this->assertStringNotContainsStringIgnoringCase('JOIN', $sql);
49+
$this->assertStringContainsStringIgnoringCase('status', $sql);
50+
}
51+
52+
public function test_invalid_final_relation_becomes_field(): void
53+
{
54+
$query = User::query()
55+
->select(['agent__nonexistent as maybe_field']);
56+
57+
$sql = $this->debugSql($query);
58+
59+
$this->assertStringContainsStringIgnoringCase('agent', $sql);
60+
$this->assertStringNotContainsStringIgnoringCase('nonexistent.', $sql);
61+
$this->assertStringContainsStringIgnoringCase('as "maybe_field"', $sql);
62+
}
63+
64+
public function test_suffix_based_aggregate_counts_related_departments(): void
65+
{
66+
$query = User::query()
67+
->select(['name', 'agent__departments__count as dept_count'])
68+
->groupBy('agent.id');
69+
70+
$sql = $this->debugSql($query);
71+
72+
$this->assertStringContainsStringIgnoringCase('COUNT', $sql);
73+
$this->assertStringContainsStringIgnoringCase('as "dept_count"', $sql);
74+
$this->assertStringContainsStringIgnoringCase('departments', $sql);
75+
76+
$this->assertNonEmptyResults($query->get()->toArray());
77+
}
78+
79+
/**
80+
* Ensure suffix-based aggregate can be used in a HAVING clause.
81+
*/
82+
public function test_suffix_aggregate_in_having_clause(): void
83+
{
84+
$query = User::query()
85+
->select(['name', 'agent__departments__count as dept_count'])
86+
->groupBy('agent.id')
87+
->having('agent__departments__count', '>', 0)
88+
->orderBy('name', 'asc');
89+
90+
$sql = $this->debugSql($query);
91+
92+
$this->assertStringContainsStringIgnoringCase('HAVING', $sql);
93+
$this->assertStringContainsStringIgnoringCase('COUNT', $sql);
94+
95+
$this->assertNonEmptyResults($query->get()->toArray());
96+
}
97+
98+
/**
99+
* Ensure suffix-based aggregate can be used in ORDER BY.
100+
*/
101+
public function test_suffix_aggregate_in_order_by_clause(): void
102+
{
103+
$query = User::query()
104+
->select(['name', 'agent__departments__count as dept_count'])
105+
->groupBy('agent.id')
106+
->orderBy('agent__departments__count', 'desc');
107+
108+
$sql = $this->debugSql($query);
109+
110+
$this->assertStringContainsStringIgnoringCase('ORDER BY', $sql);
111+
$this->assertStringContainsStringIgnoringCase('COUNT', $sql);
112+
113+
$this->assertNonEmptyResults($query->get()->toArray());
114+
}
115+
116+
/**
117+
* Ensure explicit alias suppresses auto-generated alias.
118+
*/
119+
public function test_explicit_alias_overrides_auto_aliasing(): void
120+
{
121+
$query = User::query()
122+
->select(['agent__departments__manager__user as manager_id']);
123+
124+
$sql = $this->debugSql($query);
125+
126+
$this->assertStringContainsStringIgnoringCase('JOIN', $sql);
127+
$this->assertStringContainsStringIgnoringCase('as "manager_id"', $sql);
128+
$this->assertStringNotContainsStringIgnoringCase('agent__departments__manager__user', $sql);
129+
}
130+
}

0 commit comments

Comments
 (0)