Passed
Push — main ( 8a18ed...1ea679 )
by Peter
02:40
created

SelectTest::testToStringFromTwoTablesWithAliases()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace QB\Generic\Statement;
6
7
use PDO;
8
use PHPUnit\Framework\TestCase;
9
use QB\Generic\Clause\Column;
10
use QB\Generic\Clause\IJoin;
11
use QB\Generic\Clause\Join;
12
use QB\Generic\Clause\Table;
13
use QB\Generic\Expr\Expr;
14
15
/**
16
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
17
 */
18
class SelectTest extends TestCase
19
{
20
    /**
21
     * @suppress PhanNoopCast
22
     */
23 3
    public function testToStringThrowsAnExceptionIfNotInitialized()
24
    {
25 3
        $this->expectException(\RuntimeException::class);
26
27 3
        (string)$this->getSut();
28
    }
29
30 3
    public function testToStringConstant()
31
    {
32 3
        $sql = (string)$this->getSut()->addColumn('1');
33
34 3
        $this->assertSame('SELECT 1', $sql);
35 3
    }
36
37 3
    public function testToStringExpressions()
38
    {
39 3
        $sql = (string)$this->getSut()->addColumn('COUNT(foo)', 'foo_count');
40
41 3
        $this->assertSame('SELECT COUNT(foo) AS foo_count', $sql);
42 3
    }
43
44 3
    public function testToStringFromTwoTables()
45
    {
46 3
        $sql = (string)$this->getSut('foo', 'bar');
47
48 3
        $expectedSql = "SELECT *\nFROM foo, bar";
49
50 3
        $this->assertSame($expectedSql, $sql);
51 3
    }
52
53 3
    public function testToStringFromTwoTablesWithOneAlias()
54
    {
55 3
        $sql = (string)$this->getSut(new Table('foo', 'f'), 'bar');
56
57 3
        $expectedSql = "SELECT *\nFROM foo AS f, bar";
58
59 3
        $this->assertSame($expectedSql, $sql);
60 3
    }
61
62 3
    public function testToStringFromTwoTablesWithAliases()
63
    {
64 3
        $sql = (string)$this->getSut(new Table('foo', 'f'), new Table('bar', 'b'));
65
66 3
        $expectedSql = "SELECT *\nFROM foo AS f, bar AS b";
67
68 3
        $this->assertSame($expectedSql, $sql);
69 3
    }
70
71 3
    public function testWithInnerJoin()
72
    {
73 3
        $sql = (string)$this->getSut('foo')
74 3
            ->addInnerJoin('baz', 'foo.id = baz.foo_id');
75
76 3
        $parts   = [];
77 3
        $parts[] = "SELECT *";
78 3
        $parts[] = "FROM foo";
79 3
        $parts[] = "INNER JOIN baz ON foo.id = baz.foo_id";
80
81 3
        $expectedSql = implode(PHP_EOL, $parts);
82
83 3
        $this->assertSame($expectedSql, $sql);
84 3
    }
85
86 3
    public function testToStringWithLeftJoin()
87
    {
88 3
        $sql = (string)$this->getSut('foo')
89 3
            ->addLeftJoin('baz', new Expr('foo.id = b.foo_id'), 'b');
90
91 3
        $parts   = [];
92 3
        $parts[] = "SELECT *";
93 3
        $parts[] = "FROM foo";
94 3
        $parts[] = "LEFT JOIN baz AS b ON foo.id = b.foo_id";
95
96 3
        $expectedSql = implode(PHP_EOL, $parts);
97
98 3
        $this->assertSame($expectedSql, $sql);
99 3
    }
100
101 3
    public function testToStringWithRightJoin()
102
    {
103 3
        $sql = (string)$this->getSut(new Table('foo', 'f'))
104 3
            ->addRightJoin('baz', new Expr('f.id = b.foo_id'), 'b');
105
106 3
        $parts   = [];
107 3
        $parts[] = "SELECT *";
108 3
        $parts[] = "FROM foo AS f";
109 3
        $parts[] = "RIGHT JOIN baz AS b ON f.id = b.foo_id";
110
111 3
        $expectedSql = implode(PHP_EOL, $parts);
112
113 3
        $this->assertSame($expectedSql, $sql);
114 3
    }
115
116 3
    public function testToStringWithFullJoin()
117
    {
118 3
        $sql = (string)$this->getSut(new Table('foo', 'f'))
119 3
            ->addFullJoin('baz', new Expr('f.id = b.foo_id'), 'b');
120
121 3
        $parts   = [];
122 3
        $parts[] = "SELECT *";
123 3
        $parts[] = "FROM foo AS f";
124 3
        $parts[] = "FULL JOIN baz AS b ON f.id = b.foo_id";
125
126 3
        $expectedSql = implode(PHP_EOL, $parts);
127
128 3
        $this->assertSame($expectedSql, $sql);
129 3
    }
130
131 3
    public function testToStringWithManyJoins()
132
    {
133 3
        $join0 = new Join(IJoin::TYPE_INNER_JOIN, 'bar', 'b0.foo_id = foo.id', 'b0');
134 3
        $join1 = new Join(IJoin::TYPE_LEFT_JOIN, 'bar', 'b1.foo_id = foo.id AND FALSE', 'b1');
135 3
        $join2 = new Join(IJoin::TYPE_LEFT_JOIN, 'bar', 'b2.foo_id = foo.id AND 0', 'b2');
136
137 3
        $sql = (string)$this->getSut('foo')
138 3
            ->addColumn('foo.*')
139 3
            ->addJoin($join0, $join1, $join2);
140
141 3
        $parts   = [];
142 3
        $parts[] = "SELECT foo.*";
143 3
        $parts[] = "FROM foo";
144 3
        $parts[] = "INNER JOIN bar AS b0 ON b0.foo_id = foo.id";
145 3
        $parts[] = "LEFT JOIN bar AS b1 ON b1.foo_id = foo.id AND FALSE";
146 3
        $parts[] = "LEFT JOIN bar AS b2 ON b2.foo_id = foo.id AND 0";
147
148 3
        $expectedSql = implode(PHP_EOL, $parts);
149
150 3
        $this->assertSame($expectedSql, $sql);
151 3
    }
152
153 2
    public function testToStringComplex()
154
    {
155 2
        $sql = (string)$this->getSut()
156 2
            ->addFrom('foo', 'bar')
157 2
            ->addModifier('DISTINCT')
158 2
            ->addColumns('COUNT(DISTINCT baz) AS baz_count', 'q.foo_id')
159 2
            ->addInnerJoin('quix', 'foo.id = q.foo_id', 'q')
160 2
            ->addWhere('foo.bar = "foo-bar"', new Expr('bar.foo = ?', ['bar-foo']))
161 2
            ->addGroupBy('q.foo_id', new Expr('q.bar.id'))
162 2
            ->addHaving('baz_count > 0')
163 2
            ->addOrderBy('baz_count', 'ASC')
164 2
            ->setLimit(10)
165 2
            ->setOffset(20);
166
167 2
        $parts   = [];
168 2
        $parts[] = 'SELECT DISTINCT COUNT(DISTINCT baz) AS baz_count, q.foo_id';
169 2
        $parts[] = 'FROM foo, bar';
170 2
        $parts[] = 'INNER JOIN quix AS q ON foo.id = q.foo_id';
171 2
        $parts[] = 'WHERE foo.bar = "foo-bar" AND bar.foo = ?';
172 2
        $parts[] = 'GROUP BY q.foo_id, q.bar.id';
173 2
        $parts[] = 'HAVING baz_count > 0';
174 2
        $parts[] = 'ORDER BY baz_count ASC';
175 2
        $parts[] = 'OFFSET 20 ROWS';
176 2
        $parts[] = 'FETCH FIRST 10 ROWS ONLY';
177
178 2
        $expectedSql = implode(PHP_EOL, $parts);
179
180 2
        $this->assertSame($expectedSql, $sql);
181 2
    }
182
183 3
    public function testGetParamsComplex()
184
    {
185 3
        $query = $this->getSut()
186 3
            ->addFrom('foo', 'bar')
187 3
            ->addColumns(new Column(new Expr('COUNT(*) + ?', [2]), 'cpp'))
188 3
            ->addLeftJoin('baz', new Expr('b.c < ?', [3]), 'b')
189 3
            ->addWhere(new Expr('foo.a IN (?)', [[4], [5]]))
190 3
            ->addGroupBy(new Expr('foo.c > ?', [6]))
191 3
            ->addHaving(new Expr('foo.maybe = ?', [7]));
192
193 3
        $expectedParams = [
194
            [2, PDO::PARAM_INT],
195
            [3, PDO::PARAM_INT],
196
            [4, PDO::PARAM_INT],
197
            [5, PDO::PARAM_INT],
198
            [6, PDO::PARAM_INT],
199
            [7, PDO::PARAM_INT],
200
        ];
201
202 3
        $this->assertSame($expectedParams, $query->getParams());
203 3
    }
204
205
    /**
206
     * @param string|Table ...$tables
207
     *
208
     * @return ISelect
209
     */
210 13
    protected function getSut(string|Table ...$tables): ISelect
211
    {
212 13
        return (new Select())->addFrom(...$tables);
213
    }
214
}
215