Skip to content

Commit 874d686

Browse files
chore: test functions against a real PostgreSQL server
1 parent b653dce commit 874d686

14 files changed

+653
-28
lines changed

tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonTestCase.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,18 @@ protected function insertTestDataForJsonFixture(): void
3939
{
4040
$json1 = '{"name": "John", "age": 30, "tags": ["developer", "manager"], "address": {"city": "New York"}}';
4141
$json2 = '{"name": "Jane", "age": 25, "tags": ["designer"], "address": {"city": "Boston"}}';
42+
$json3 = '{"name": "Micky", "age": 30, "tags": [], "address": {"city": "New York"}}';
43+
$json4 = '{}';
44+
$json5 = '{"name": "John", "age": null, "tags": ["developer"], "address": {"city": "New York", "zip": null}}';
4245

4346
$sql = \sprintf('
4447
INSERT INTO %s.containsjsons (object1, object2) VALUES
4548
(\'%s\', \'%s\'),
49+
(\'%s\', \'%s\'),
50+
(\'%s\', \'%s\'),
51+
(\'%s\', \'%s\'),
4652
(\'%s\', \'%s\')
47-
', self::DATABASE_SCHEMA, $json1, $json1, $json2, $json2);
53+
', self::DATABASE_SCHEMA, $json1, $json1, $json2, $json2, $json3, $json3, $json4, $json4, $json5, $json5);
4854
$this->connection->executeStatement($sql);
4955
}
5056
}

tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAggTest.php

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,11 @@ public function test_jsonb_agg_with_single_row(): void
3131
$this->assertEqualsCanonicalizing($expected, $actual);
3232
}
3333

34-
public function test_jsonb_agg_with_all_rows(): void
34+
public function test_jsonb_agg_with_multiple_rows(): void
3535
{
3636
$dql = 'SELECT JSONB_AGG(t.object1) as result
37-
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t';
38-
$result = $this->executeDqlQuery($dql);
39-
$this->assertIsString($result[0]['result']);
40-
$actual = \json_decode($result[0]['result'], true);
41-
$this->assertIsArray($actual);
42-
$expected = [
43-
[
44-
'name' => 'John',
45-
'age' => 30,
46-
'tags' => ['developer', 'manager'],
47-
'address' => ['city' => 'New York'],
48-
],
49-
[
50-
'name' => 'Jane',
51-
'age' => 25,
52-
'tags' => ['designer'],
53-
'address' => ['city' => 'Boston'],
54-
],
55-
];
56-
$this->assertEqualsCanonicalizing($expected, $actual);
57-
}
58-
59-
public function test_jsonb_agg_with_object2_column(): void
60-
{
61-
$dql = 'SELECT JSONB_AGG(t.object2) as result
62-
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t';
37+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
38+
WHERE t.id IN (1, 2)';
6339
$result = $this->executeDqlQuery($dql);
6440
$this->assertIsString($result[0]['result']);
6541
$actual = \json_decode($result[0]['result'], true);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayElements;
8+
9+
class JsonbArrayElementsTest extends JsonTestCase
10+
{
11+
protected function getStringFunctions(): array
12+
{
13+
return [
14+
'JSONB_ARRAY_ELEMENTS' => JsonbArrayElements::class,
15+
];
16+
}
17+
18+
public function test_jsonb_array_elements(): void
19+
{
20+
$dql = 'SELECT JSONB_ARRAY_ELEMENTS(t.object1) as result
21+
FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t
22+
WHERE t.id = 1';
23+
$result = $this->executeDqlQuery($dql);
24+
$this->assertIsArray($result);
25+
$this->assertCount(2, $result);
26+
$this->assertSame('"developer"', $result[0]['result']);
27+
$this->assertSame('"manager"', $result[1]['result']);
28+
}
29+
30+
public function test_jsonb_array_elements_with_empty_array(): void
31+
{
32+
$dql = 'SELECT JSONB_ARRAY_ELEMENTS(t.object1) as result
33+
FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t
34+
WHERE t.id = 3';
35+
$result = $this->executeDqlQuery($dql);
36+
$this->assertIsArray($result);
37+
$this->assertCount(0, $result);
38+
}
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbArrayElementsText;
8+
9+
class JsonbArrayElementsTextTest extends JsonTestCase
10+
{
11+
protected function getStringFunctions(): array
12+
{
13+
return [
14+
'JSONB_ARRAY_ELEMENTS_TEXT' => JsonbArrayElementsText::class,
15+
];
16+
}
17+
18+
public function test_jsonb_array_elements_text(): void
19+
{
20+
$dql = 'SELECT JSONB_ARRAY_ELEMENTS_TEXT(t.object1) as result
21+
FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t
22+
WHERE t.id = 1';
23+
$result = $this->executeDqlQuery($dql);
24+
$this->assertIsArray($result);
25+
$this->assertCount(2, $result);
26+
$this->assertSame('developer', $result[0]['result']);
27+
$this->assertSame('manager', $result[1]['result']);
28+
}
29+
30+
public function test_jsonb_array_elements_text_with_empty_array(): void
31+
{
32+
$dql = 'SELECT JSONB_ARRAY_ELEMENTS_TEXT(t.object1) as result
33+
FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t
34+
WHERE t.id = 3';
35+
$result = $this->executeDqlQuery($dql);
36+
$this->assertIsArray($result);
37+
$this->assertCount(0, $result);
38+
}
39+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use Doctrine\DBAL\Exception;
8+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbInsert;
9+
10+
class JsonbInsertTest extends JsonTestCase
11+
{
12+
protected function getStringFunctions(): array
13+
{
14+
return [
15+
'JSONB_INSERT' => JsonbInsert::class,
16+
];
17+
}
18+
19+
public function test_jsonb_insert_new_value(): void
20+
{
21+
$dql = 'SELECT JSONB_INSERT(t.object1, :path, :value) as result
22+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
23+
WHERE t.id = 1';
24+
$result = $this->executeDqlQuery($dql, [
25+
'path' => '{email}',
26+
'value' => '"john@example.com"',
27+
]);
28+
$this->assertIsString($result[0]['result']);
29+
$decoded = \json_decode($result[0]['result'], true);
30+
$this->assertSame('john@example.com', $decoded['email']);
31+
}
32+
33+
public function test_jsonb_insert_nested_path(): void
34+
{
35+
$dql = 'SELECT JSONB_INSERT(t.object1, :path, :value) as result
36+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
37+
WHERE t.id = 1';
38+
$result = $this->executeDqlQuery($dql, [
39+
'path' => '{address,zip}',
40+
'value' => '"10001"',
41+
]);
42+
$this->assertIsString($result[0]['result']);
43+
$decoded = \json_decode($result[0]['result'], true);
44+
$this->assertSame('10001', $decoded['address']['zip']);
45+
}
46+
47+
public function test_jsonb_insert_existing_path(): void
48+
{
49+
$this->expectException(Exception::class);
50+
$dql = 'SELECT JSONB_INSERT(t.object1, :path, :value) as result
51+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
52+
WHERE t.id = 1';
53+
$this->executeDqlQuery($dql, [
54+
'path' => '{name}',
55+
'value' => '"John Doe"',
56+
]);
57+
}
58+
59+
public function test_jsonb_insert_with_insert_if_missing_true(): void
60+
{
61+
$this->expectException(Exception::class);
62+
$dql = "SELECT JSONB_INSERT(t.object1, :path, :value, 'true') as result
63+
FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t
64+
WHERE t.id = 1";
65+
$this->executeDqlQuery($dql, [
66+
'path' => '{name}',
67+
'value' => '"John Doe"',
68+
]);
69+
}
70+
}
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 Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectAgg;
8+
9+
class JsonbObjectAggTest extends JsonTestCase
10+
{
11+
protected function getStringFunctions(): array
12+
{
13+
return [
14+
'JSONB_OBJECT_AGG' => JsonbObjectAgg::class,
15+
];
16+
}
17+
18+
public function test_jsonb_object_agg(): void
19+
{
20+
$dql = "SELECT JSONB_OBJECT_AGG('key', 'value') as result
21+
FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t
22+
WHERE t.id = 1";
23+
$result = $this->executeDqlQuery($dql);
24+
$this->assertIsString($result[0]['result']);
25+
$decoded = \json_decode($result[0]['result'], true);
26+
$this->assertIsArray($decoded);
27+
$this->assertSame(['key' => 'value'], $decoded);
28+
}
29+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectKeys;
8+
9+
class JsonbObjectKeysTest extends JsonTestCase
10+
{
11+
protected function getStringFunctions(): array
12+
{
13+
return [
14+
'JSONB_OBJECT_KEYS' => JsonbObjectKeys::class,
15+
];
16+
}
17+
18+
public function test_jsonb_object_keys(): void
19+
{
20+
$dql = 'SELECT JSONB_OBJECT_KEYS(t.object1) as result
21+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
22+
WHERE t.id = 1';
23+
$result = $this->executeDqlQuery($dql);
24+
$this->assertIsString($result[0]['result']);
25+
}
26+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbPathQueryArray;
8+
9+
class JsonbPathQueryArrayTest extends JsonTestCase
10+
{
11+
protected function getStringFunctions(): array
12+
{
13+
return [
14+
'JSONB_PATH_QUERY_ARRAY' => JsonbPathQueryArray::class,
15+
];
16+
}
17+
18+
public function test_jsonb_path_query_array_simple(): void
19+
{
20+
$dql = 'SELECT JSONB_PATH_QUERY_ARRAY(:json, :path) as result
21+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
22+
WHERE t.id = 1';
23+
$result = $this->executeDqlQuery($dql, [
24+
'json' => '{"a": 1, "b": 2}',
25+
'path' => '$.b',
26+
]);
27+
$this->assertIsString($result[0]['result']);
28+
$decoded = \json_decode($result[0]['result'], true);
29+
$this->assertIsArray($decoded);
30+
$this->assertCount(1, $decoded);
31+
$this->assertSame(2, $decoded[0]);
32+
}
33+
34+
public function test_jsonb_path_query_array_multiple_values(): void
35+
{
36+
$dql = 'SELECT JSONB_PATH_QUERY_ARRAY(:json, :path) as result
37+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
38+
WHERE t.id = 1';
39+
$result = $this->executeDqlQuery($dql, [
40+
'json' => '{"items": [1, 2, 3]}',
41+
'path' => '$.items[*]',
42+
]);
43+
$this->assertIsString($result[0]['result']);
44+
$decoded = \json_decode($result[0]['result'], true);
45+
$this->assertIsArray($decoded);
46+
$this->assertCount(3, $decoded);
47+
$this->assertSame([1, 2, 3], $decoded);
48+
}
49+
50+
public function test_jsonb_path_query_array_with_filter(): void
51+
{
52+
$dql = 'SELECT JSONB_PATH_QUERY_ARRAY(:json, :path) as result
53+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
54+
WHERE t.id = 1';
55+
$result = $this->executeDqlQuery($dql, [
56+
'json' => '{"items": [{"id": 1}, {"id": 2}, {"id": 3}]}',
57+
'path' => '$.items[*] ? (@.id > 1)',
58+
]);
59+
$this->assertIsString($result[0]['result']);
60+
$decoded = \json_decode($result[0]['result'], true);
61+
$this->assertIsArray($decoded);
62+
$this->assertCount(2, $decoded);
63+
$this->assertSame(['id' => 2], $decoded[0]);
64+
$this->assertSame(['id' => 3], $decoded[1]);
65+
}
66+
67+
public function test_jsonb_path_query_array_with_column_reference(): void
68+
{
69+
$dql = 'SELECT JSONB_PATH_QUERY_ARRAY(t.object1, :path) as result
70+
FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsJsons t
71+
WHERE t.id = 1';
72+
$result = $this->executeDqlQuery($dql, ['path' => '$.tags[*]']);
73+
$this->assertIsString($result[0]['result']);
74+
$decoded = \json_decode($result[0]['result'], true);
75+
$this->assertIsArray($decoded);
76+
$this->assertCount(2, $decoded);
77+
$this->assertSame(['developer', 'manager'], $decoded);
78+
}
79+
}

0 commit comments

Comments
 (0)