Skip to content

Commit 844bdc1

Browse files
Add some convenience functions and create end-to-end tests
1 parent 95df46d commit 844bdc1

File tree

3 files changed

+227
-6
lines changed

3 files changed

+227
-6
lines changed

src/Query.php

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public static function new(): self
9393
*
9494
* @param null|string $label The label to give to the node
9595
*
96-
* @see https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-node Corresponding documentation on Neo4j.com
96+
* @link https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-node Corresponding documentation on Neo4j.com
9797
*/
9898
public static function node(?string $label = null): Node
9999
{
@@ -103,18 +103,48 @@ public static function node(?string $label = null): Node
103103
/**
104104
* Creates a relationship.
105105
*
106-
* @param string[] $direction The direction of the relationship, should be either:
106+
* @param string[] $direction The direction of the relationship (optional, default: unidirectional), should be either:
107107
* - Relationship::DIR_RIGHT (for a relation of (a)-->(b))
108108
* - Relationship::DIR_LEFT (for a relation of (a)<--(b))
109109
* - Relationship::DIR_UNI (for a relation of (a)--(b))
110110
*
111-
* @see https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-relationship Corresponding documentation on Neo4j.com
111+
* @link https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-relationship Corresponding documentation on Neo4j.com
112112
*/
113-
public static function relationship(array $direction): Relationship
113+
public static function relationship(array $direction = Relationship::DIR_UNI): Relationship
114114
{
115115
return new Relationship($direction);
116116
}
117117

118+
/**
119+
* Creates a unidirectional relationship.
120+
*
121+
* @link https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-relationship Corresponding documentation on Neo4j.com
122+
*/
123+
public static function relationshipUni(): Relationship
124+
{
125+
return new Relationship(Relationship::DIR_UNI);
126+
}
127+
128+
/**
129+
* Creates a right relationship.
130+
*
131+
* @link https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-relationship Corresponding documentation on Neo4j.com
132+
*/
133+
public static function relationshipTo(): Relationship
134+
{
135+
return new Relationship(Relationship::DIR_RIGHT);
136+
}
137+
138+
/**
139+
* Creates a left relationship.
140+
*
141+
* @link https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-relationship Corresponding documentation on Neo4j.com
142+
*/
143+
public static function relationshipFrom(): Relationship
144+
{
145+
return new Relationship(Relationship::DIR_LEFT);
146+
}
147+
118148
/**
119149
* Creates a new variable with the given name, or generates a new variable with a random unique name.
120150
*

src/functions.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,48 @@ function node(?string $label = null): Node
5858
/**
5959
* Creates a relationship.
6060
*
61-
* @param string[] $direction The direction of the relationship, should be either:
61+
* @param string[] $direction The direction of the relationship (optional, default: unidirectional), should be either:
6262
* - Relationship::DIR_RIGHT (for a relation of (a)-->(b))
6363
* - Relationship::DIR_LEFT (for a relation of (a)<--(b))
6464
* - Relationship::DIR_UNI (for a relation of (a)--(b))
6565
*
6666
* @see Query::relationship()
6767
*/
68-
function relationship(array $direction): Relationship
68+
function relationship(array $direction = Relationship::DIR_UNI): Relationship
6969
{
7070
return Query::relationship($direction);
7171
}
7272

73+
/**
74+
* Creates a unidirectional relationship.
75+
*
76+
* @see Query::relationshipUni()
77+
*/
78+
function relationshipUni(): Relationship
79+
{
80+
return Query::relationshipUni();
81+
}
82+
83+
/**
84+
* Creates a right relationship.
85+
*
86+
* @see Query::relationshipTo()
87+
*/
88+
function relationshipTo(): Relationship
89+
{
90+
return Query::relationshipTo();
91+
}
92+
93+
/**
94+
* Creates a left relationship.
95+
*
96+
* @see Query::relationshipFrom()
97+
*/
98+
function relationshipFrom(): Relationship
99+
{
100+
return Query::relationshipFrom();
101+
}
102+
73103
/**
74104
* Creates a new variable with the given name, or generates a new variable with a random unique name.
75105
*

tests/Unit/MoviesTest.php

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of php-cypher-dsl.
4+
*
5+
* Copyright (C) Wikibase Solutions
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace WikibaseSolutions\CypherDSL\Tests\Unit;
11+
12+
use PHPUnit\Framework\TestCase;
13+
use TypeError;
14+
use WikibaseSolutions\CypherDSL\Expressions\Literals\Boolean;
15+
use WikibaseSolutions\CypherDSL\Expressions\Literals\Float_;
16+
use WikibaseSolutions\CypherDSL\Expressions\Literals\Integer;
17+
use WikibaseSolutions\CypherDSL\Expressions\Literals\List_;
18+
use WikibaseSolutions\CypherDSL\Expressions\Literals\Literal;
19+
use WikibaseSolutions\CypherDSL\Expressions\Literals\Map;
20+
use WikibaseSolutions\CypherDSL\Expressions\Literals\String_;
21+
use WikibaseSolutions\CypherDSL\Expressions\Procedures\Procedure;
22+
use WikibaseSolutions\CypherDSL\Expressions\RawExpression;
23+
use WikibaseSolutions\CypherDSL\Expressions\Variable;
24+
use function WikibaseSolutions\CypherDSL\float;
25+
use function WikibaseSolutions\CypherDSL\function_;
26+
use function WikibaseSolutions\CypherDSL\integer;
27+
use function WikibaseSolutions\CypherDSL\list_;
28+
use function WikibaseSolutions\CypherDSL\literal;
29+
use function WikibaseSolutions\CypherDSL\map;
30+
use function WikibaseSolutions\CypherDSL\node;
31+
use WikibaseSolutions\CypherDSL\Patterns\Node;
32+
use WikibaseSolutions\CypherDSL\Patterns\Relationship;
33+
use WikibaseSolutions\CypherDSL\Query;
34+
use function WikibaseSolutions\CypherDSL\query;
35+
use function WikibaseSolutions\CypherDSL\raw;
36+
use function WikibaseSolutions\CypherDSL\relationship;
37+
use function WikibaseSolutions\CypherDSL\relationshipUni;
38+
use function WikibaseSolutions\CypherDSL\string;
39+
use function WikibaseSolutions\CypherDSL\variable;
40+
41+
/**
42+
* This class contains some end-to-end tests to test the creation of Cypher queries present in the ":play movies" example.
43+
*
44+
* @coversNothing
45+
*
46+
* @link https://neo4j.com/developer/example-data/
47+
*/
48+
final class MoviesTest extends TestCase
49+
{
50+
public function testFindActorNamedTomHanks(): void
51+
{
52+
$tom = node()->withProperties([
53+
'name' => 'Tom Hanks'
54+
]);
55+
56+
$query = query()
57+
->match($tom)
58+
->returning($tom);
59+
60+
$this->assertStringMatchesFormat('MATCH (%s {name: \'Tom Hanks\'}) RETURN %s', $query->toQuery());
61+
}
62+
63+
public function testFindTheMovieWithTitleCloudAtlas(): void
64+
{
65+
$cloudAtlas = node()->withProperties([
66+
'title' => 'Cloud Atlas'
67+
]);
68+
69+
$query = query()
70+
->match($cloudAtlas)
71+
->returning($cloudAtlas);
72+
73+
$this->assertStringMatchesFormat('MATCH (%s {title: \'Cloud Atlas\'}) RETURN %s', $query->toQuery());
74+
}
75+
76+
public function testFind10People(): void
77+
{
78+
$people = node('Person');
79+
80+
$query = query()
81+
->match($people)
82+
->returning($people->property('name'))
83+
->limit(10);
84+
85+
$this->assertStringMatchesFormat('MATCH (%s:Person) RETURN %s.name LIMIT 10', $query->toQuery());
86+
}
87+
88+
public function testFindMoviesReleasedInThe1990s(): void
89+
{
90+
$nineties = node('Movie');
91+
$query = query()
92+
->match($nineties)
93+
->where([
94+
$nineties->property('released')->gte(1990),
95+
$nineties->property('released')->lt(2000)
96+
])
97+
->returning($nineties->property('title'));
98+
99+
$this->assertStringMatchesFormat('MATCH (%s:Movie) WHERE ((%s.released >= 1990) AND (%s.released < 2000)) RETURN %s.title', $query->toQuery());
100+
}
101+
102+
public function testListAllTomHanksMovies(): void
103+
{
104+
$movies = node();
105+
$tom = node('Person')->withProperties([
106+
'name' => 'Tom Hanks'
107+
]);
108+
109+
$query = query()
110+
->match($tom->relationshipTo($movies, 'ACTED_IN'))
111+
->returning([$tom, $movies]);
112+
113+
$this->assertStringMatchesFormat('MATCH (%s:Person {name: \'Tom Hanks\'})-[:ACTED_IN]->(%s) RETURN %s, %s', $query->toQuery());
114+
}
115+
116+
public function testWhoDirectedCloudAtlas(): void
117+
{
118+
$directors = node();
119+
$cloudAtlas = node()->withProperties([
120+
'title' => 'Cloud Atlas'
121+
]);
122+
123+
$query = query()
124+
->match($cloudAtlas->relationshipFrom($directors, 'DIRECTED'))
125+
->returning($directors->property('name'));
126+
127+
$this->assertStringMatchesFormat('MATCH ({title: \'Cloud Atlas\'})<-[:DIRECTED]-(%s) RETURN %s.name', $query->toQuery());
128+
}
129+
130+
public function testTomHanksCoActors(): void
131+
{
132+
$coActors = node();
133+
$tom = node('Person')->withProperties([
134+
'name' => 'Tom Hanks'
135+
]);
136+
137+
$query = query()
138+
->match($tom->relationshipTo(node(), 'ACTED_IN')->relationshipFrom($coActors, 'ACTED_IN'))
139+
->returning($coActors->property('name'));
140+
141+
$this->assertStringMatchesFormat('MATCH (:Person {name: \'Tom Hanks\'})-[:ACTED_IN]->()<-[:ACTED_IN]-(%s) RETURN %s.name', $query->toQuery());
142+
}
143+
144+
public function testMoviesAndActorsUpTo4HopsAwayFromKevinBacon(): void
145+
{
146+
$hollywood = node();
147+
$bacon = node('Person')->withProperties([
148+
'name' => 'Kevin Bacon'
149+
]);
150+
151+
$relation = relationshipUni()
152+
->withMinHops(1)
153+
->withMaxHops(4);
154+
155+
$query = query()
156+
->match($bacon->relationship($relation, $hollywood))
157+
->returning($hollywood, true);
158+
159+
$this->assertStringMatchesFormat('MATCH (:Person {name: \'Kevin Bacon\'})-[*1..4]-(%s) RETURN DISTINCT %s', $query->toQuery());
160+
}
161+
}

0 commit comments

Comments
 (0)