Skip to content

Commit 1d9a5ea

Browse files
authored
Testing (#3)
* moved prepare body method to HttpCypherFormatter * ran php-cs-fixer * added complex query tests
1 parent 86c2885 commit 1d9a5ea

File tree

3 files changed

+162
-17
lines changed

3 files changed

+162
-17
lines changed

composer.lock

Lines changed: 14 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Formatter/BoltCypherFormatter.php

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,11 @@ public function formatResult(array $meta, array $results): Vector
3737
/** @var mixed $value */
3838
$value = $result[$i];
3939
if (is_object($value)) {
40-
if (method_exists($value, 'properties')) {
41-
/** @var array $properties */
42-
$properties = $value->properties();
43-
$map->put($column, $properties);
44-
} else {
45-
throw new UnexpectedValueException('Cannot handle objects without a properties method. Class given: '.get_class($value));
46-
}
47-
} elseif ($value === null || is_scalar($value) || is_array($value)) {
40+
$map->put($column, $this->objectToProperty($value));
41+
} elseif ($value === null || is_scalar($value)) {
42+
$map->put($column, $value);
43+
} elseif (is_array($value)) {
44+
$value = $this->remapObjectsInArray($value);
4845
$map->put($column, $value);
4946
} else {
5047
throw new UnexpectedValueException('Did not expect to receive value of type: '.gettype($value));
@@ -55,4 +52,30 @@ public function formatResult(array $meta, array $results): Vector
5552

5653
return $tbr;
5754
}
55+
56+
private function objectToProperty(object $object): array
57+
{
58+
if (!method_exists($object, 'properties')) {
59+
throw new UnexpectedValueException('Cannot handle objects without a properties method. Class given: '.get_class($object));
60+
}
61+
62+
/** @var array $properties */
63+
$properties = $object->properties();
64+
65+
return $properties;
66+
}
67+
68+
private function remapObjectsInArray(array $value): array
69+
{
70+
/**
71+
* @psalm-var mixed $variable
72+
*/
73+
foreach ($value as $key => $variable) {
74+
if (is_object($variable)) {
75+
$value[$key] = $this->objectToProperty($variable);
76+
}
77+
}
78+
79+
return $value;
80+
}
5881
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Laudis Neo4j package.
7+
*
8+
* (c) Laudis technologies <http://laudis.tech>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Laudis\Neo4j\Tests\Integration;
15+
16+
use Laudis\Neo4j\ClientBuilder;
17+
use Laudis\Neo4j\Contracts\ClientInterface;
18+
use PHPUnit\Framework\TestCase;
19+
20+
final class ComplexQueryTests extends TestCase
21+
{
22+
private ClientInterface $client;
23+
24+
protected function setUp(): void
25+
{
26+
parent::setUp();
27+
$this->client = ClientBuilder::create()
28+
->addBoltConnection('bolt', 'bolt://neo4j:test@neo4j')
29+
->addHttpConnection('http', 'http://neo4j:test@neo4j')
30+
->build();
31+
}
32+
33+
/**
34+
* @dataProvider transactionProvider
35+
*/
36+
public function testCreationAndResult(string $alias): void
37+
{
38+
$result = $this->client->run(<<<'CYPHER'
39+
MERGE (x:Node {x:$x})
40+
RETURN x
41+
CYPHER
42+
, ['x' => 'x'], $alias)->first();
43+
44+
self::assertEquals(['x' => 'x'], $result->get('x'));
45+
}
46+
47+
/**
48+
* @dataProvider transactionProvider
49+
*/
50+
public function testPath(string $alias): void
51+
{
52+
$results = $this->client->run(<<<'CYPHER'
53+
MERGE (b:Node {x:$x}) - [:HasNode {attribute: $xy}] -> (:Node {y:$y}) - [:HasNode {attribute: $yz}] -> (:Node {z:$z})
54+
WITH b
55+
MATCH (x:Node) - [y:HasNode*2] -> (z:Node)
56+
RETURN x, y, z
57+
CYPHER
58+
, ['x' => 'x', 'xy' => 'xy', 'y' => 'y', 'yz' => 'yz', 'z' => 'z'], $alias);
59+
60+
self::assertEquals(1, $results->count());
61+
$result = $results->first();
62+
self::assertEquals(3, $result->count());
63+
self::assertEquals(['x' => 'x'], $result->get('x'));
64+
self::assertEquals([['attribute' => 'xy'], ['attribute' => 'yz']], $result->get('y'));
65+
self::assertEquals(['z' => 'z'], $result->get('z'));
66+
}
67+
68+
/**
69+
* @dataProvider transactionProvider
70+
*/
71+
public function testNullListAndMap(string $alias): void
72+
{
73+
$results = $this->client->run(<<<'CYPHER'
74+
RETURN null as x, [1, 2, 3] as y, {x: 'x', y: 'y', z: 'z'} as z
75+
CYPHER
76+
, ['x' => 'x', 'xy' => 'xy', 'y' => 'y', 'yz' => 'yz', 'z' => 'z'], $alias);
77+
78+
self::assertEquals(1, $results->count());
79+
$result = $results->first();
80+
self::assertEquals(3, $result->count());
81+
self::assertNull($result->get('x'));
82+
self::assertEquals([1, 2, 3], $result->get('y'));
83+
self::assertEquals(['x' => 'x', 'y' => 'y', 'z' => 'z'], $result->get('z'));
84+
}
85+
86+
/**
87+
* @dataProvider transactionProvider
88+
*/
89+
public function testListAndMapInput(string $alias): void
90+
{
91+
$results = $this->client->run(<<<'CYPHER'
92+
MERGE (x:Node {x: $x.x})
93+
WITH x
94+
MERGE (y:Node {list: $y})
95+
RETURN x, y
96+
LIMIT 1
97+
CYPHER
98+
, ['x' => ['x' => 'x'], 'y' => [1, 2, 3]], $alias);
99+
100+
self::assertEquals(1, $results->count());
101+
$result = $results->first();
102+
self::assertEquals(2, $result->count());
103+
self::assertEquals(['x' => 'x'], $result->get('x'));
104+
self::assertEquals(['list' => [1, 2, 3]], $result->get('y'));
105+
}
106+
107+
/**
108+
* @return array<int, array<int, string>>
109+
*/
110+
public function transactionProvider(): array
111+
{
112+
return [
113+
['http'],
114+
['bolt'],
115+
];
116+
}
117+
}

0 commit comments

Comments
 (0)