Skip to content

Commit 8cbd460

Browse files
how about some integration tests, martin :)?
1 parent 9e70791 commit 8cbd460

File tree

4 files changed

+136
-7
lines changed

4 files changed

+136
-7
lines changed

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonGetField.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,18 @@ protected function feedParserWithNodes(Parser $parser): void
3333
{
3434
$shouldUseLexer = DoctrineOrm::isPre219();
3535

36-
// Parse first parameter (always StringPrimary for the JSON column)
37-
$this->nodes[0] = $parser->StringPrimary();
36+
$nodeForJsonDocumentName = $parser->StringPrimary();
3837
$parser->match($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA);
3938

40-
// Parse second parameter - try ArithmeticPrimary first, then StringPrimary
39+
// Second parameter can be either an index or a property name
4140
try {
42-
$this->nodes[1] = $parser->ArithmeticPrimary();
41+
$nodeForJsonIndexOrPropertyName = $parser->ArithmeticPrimary();
4342
} catch (QueryException) {
44-
// If ArithmeticPrimary fails (e.g., when encountering a string), try StringPrimary
45-
$this->nodes[1] = $parser->StringPrimary();
43+
// If ArithmeticPrimary fails (e.g., when encountering a property name rather than an index), try StringPrimary
44+
$nodeForJsonIndexOrPropertyName = $parser->StringPrimary();
4645
}
46+
47+
/* @phpstan-ignore-next-line assign.propertyType */
48+
$this->nodes = [$nodeForJsonDocumentName, $nodeForJsonIndexOrPropertyName];
4749
}
4850
}

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
66

7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetField;
78
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetFieldAsInteger;
89

910
class JsonGetFieldAsIntegerTest extends JsonTestCase
1011
{
1112
protected function getStringFunctions(): array
1213
{
1314
return [
15+
'JSON_GET_FIELD' => JsonGetField::class,
1416
'JSON_GET_FIELD_AS_INTEGER' => JsonGetFieldAsInteger::class,
1517
];
1618
}
@@ -22,6 +24,18 @@ public function test_json_get_field_as_integer(): void
2224
$this->assertSame(30, $result[0]['result']);
2325
}
2426

27+
public function test_json_get_field_as_integer_with_index(): void
28+
{
29+
// First, let's insert test data with numeric arrays
30+
$this->connection->executeStatement(
31+
\sprintf("UPDATE %s.containsjsons SET object1 = '{\"scores\": [85, 92, 78]}' WHERE id = 1", self::DATABASE_SCHEMA)
32+
);
33+
34+
$dql = "SELECT JSON_GET_FIELD_AS_INTEGER(JSON_GET_FIELD(t.object1, 'scores'), 1) as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
35+
$result = $this->executeDqlQuery($dql);
36+
$this->assertSame(92, $result[0]['result']);
37+
}
38+
2539
public function test_json_get_field_as_integer_empty_object(): void
2640
{
2741
$dql = "SELECT JSON_GET_FIELD_AS_INTEGER(t.object1, 'age') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 4";
@@ -36,7 +50,7 @@ public function test_json_get_field_as_integer_null_value(): void
3650
$this->assertNull($result[0]['result']);
3751
}
3852

39-
public function test_json_get_field_as_integer_nonexistent_field(): void
53+
public function test_json_get_field_as_integer_nonexistent_property_name(): void
4054
{
4155
$dql = "SELECT JSON_GET_FIELD_AS_INTEGER(t.object1, 'nonexistent') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
4256
$result = $this->executeDqlQuery($dql);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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\JsonGetField;
8+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonGetFieldAsText;
9+
10+
class JsonGetFieldAsTextTest extends JsonTestCase
11+
{
12+
protected function getStringFunctions(): array
13+
{
14+
return [
15+
'JSON_GET_FIELD' => JsonGetField::class,
16+
'JSON_GET_FIELD_AS_TEXT' => JsonGetFieldAsText::class,
17+
];
18+
}
19+
20+
public function test_json_get_field_as_text_with_property_name(): void
21+
{
22+
$dql = "SELECT JSON_GET_FIELD_AS_TEXT(t.object1, 'name') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
23+
$result = $this->executeDqlQuery($dql);
24+
$this->assertSame('John', $result[0]['result']);
25+
}
26+
27+
public function test_json_get_field_as_text_with_index(): void
28+
{
29+
$dql = "SELECT JSON_GET_FIELD_AS_TEXT(JSON_GET_FIELD(t.object1, 'tags'), 0) as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
30+
$result = $this->executeDqlQuery($dql);
31+
$this->assertSame('developer', $result[0]['result']);
32+
}
33+
34+
public function test_json_get_field_as_text_nested_access(): void
35+
{
36+
$dql = "SELECT JSON_GET_FIELD_AS_TEXT(JSON_GET_FIELD(t.object1, 'address'), 'city') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
37+
$result = $this->executeDqlQuery($dql);
38+
$this->assertSame('New York', $result[0]['result']);
39+
}
40+
41+
public function test_json_get_field_as_text_with_null_value(): void
42+
{
43+
$dql = "SELECT JSON_GET_FIELD_AS_TEXT(t.object1, 'age') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 5";
44+
$result = $this->executeDqlQuery($dql);
45+
$this->assertNull($result[0]['result']);
46+
}
47+
48+
public function test_json_get_field_as_text_with_nonexistent_index(): void
49+
{
50+
$dql = "SELECT JSON_GET_FIELD_AS_TEXT(JSON_GET_FIELD(t.object1, 'tags'), 10) as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
51+
$result = $this->executeDqlQuery($dql);
52+
$this->assertNull($result[0]['result']);
53+
}
54+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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\JsonGetField;
8+
9+
class JsonGetFieldTest extends JsonTestCase
10+
{
11+
protected function getStringFunctions(): array
12+
{
13+
return [
14+
'JSON_GET_FIELD' => JsonGetField::class,
15+
];
16+
}
17+
18+
public function test_json_get_field_with_property_name(): void
19+
{
20+
$dql = "SELECT JSON_GET_FIELD(t.object1, 'name') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
21+
$result = $this->executeDqlQuery($dql);
22+
$this->assertSame('"John"', $result[0]['result']);
23+
}
24+
25+
public function test_json_get_field_with_index(): void
26+
{
27+
$dql = "SELECT JSON_GET_FIELD(JSON_GET_FIELD(t.object1, 'tags'), 0) as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
28+
$result = $this->executeDqlQuery($dql);
29+
$this->assertSame('"developer"', $result[0]['result']);
30+
}
31+
32+
public function test_json_get_field_nested_object_access(): void
33+
{
34+
$dql = "SELECT JSON_GET_FIELD(JSON_GET_FIELD(t.object1, 'address'), 'city') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
35+
$result = $this->executeDqlQuery($dql);
36+
$this->assertSame('"New York"', $result[0]['result']);
37+
}
38+
39+
public function test_json_get_field_with_empty_array(): void
40+
{
41+
$dql = "SELECT JSON_GET_FIELD(JSON_GET_FIELD(t.object1, 'tags'), 0) as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 3";
42+
$result = $this->executeDqlQuery($dql);
43+
$this->assertNull($result[0]['result']);
44+
}
45+
46+
public function test_json_get_field_with_nonexistent_index(): void
47+
{
48+
$dql = "SELECT JSON_GET_FIELD(JSON_GET_FIELD(t.object1, 'tags'), 10) as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
49+
$result = $this->executeDqlQuery($dql);
50+
$this->assertNull($result[0]['result']);
51+
}
52+
53+
public function test_json_get_field_with_nonexistent_property_name(): void
54+
{
55+
$dql = "SELECT JSON_GET_FIELD(t.object1, 'nonexistent') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsJsons t WHERE t.id = 1";
56+
$result = $this->executeDqlQuery($dql);
57+
$this->assertNull($result[0]['result']);
58+
}
59+
}

0 commit comments

Comments
 (0)