diff --git a/CHANGELOG.md b/CHANGELOG.md index c6c7add..20ea160 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ The format is based on [Keep a Changelog], and this project adheres to ### Added - Added support for operator chaining (e.g. `a > b > c`). +- Added support for `shortestPath` and `allShortestPaths` pattern constructs. +- Added support for shortest path constructs (`SHORTEST k`, `ALL SHORTEST`, `SHORTEST k GROUPS`, and `ANY`). ### Changed diff --git a/src/Patterns/AllShortest.php b/src/Patterns/AllShortest.php new file mode 100644 index 0000000..3bba2ca --- /dev/null +++ b/src/Patterns/AllShortest.php @@ -0,0 +1,52 @@ +pattern = $pattern; + } + + /** + * @inheritDoc + */ + public function toQuery(): string + { + $cql = ''; + + if (isset($this->variable)) { + $cql = $this->variable->toQuery() . ' = '; + } + + $cql .= sprintf("ALL SHORTEST (%s)", $this->pattern->toQuery()); + + return $cql; + } +} diff --git a/src/Patterns/AllShortestPaths.php b/src/Patterns/AllShortestPaths.php new file mode 100644 index 0000000..36c85fe --- /dev/null +++ b/src/Patterns/AllShortestPaths.php @@ -0,0 +1,52 @@ +pattern = $pattern; + } + + /** + * @inheritDoc + */ + public function toQuery(): string + { + $cql = ''; + + if (isset($this->variable)) { + $cql = $this->variable->toQuery() . ' = '; + } + + $cql .= sprintf("allShortestPaths(%s)", $this->pattern->toQuery()); + + return $cql; + } +} diff --git a/src/Patterns/AnyPath.php b/src/Patterns/AnyPath.php new file mode 100644 index 0000000..6f8b18f --- /dev/null +++ b/src/Patterns/AnyPath.php @@ -0,0 +1,52 @@ +pattern = $pattern; + } + + /** + * @inheritDoc + */ + public function toQuery(): string + { + $cql = ''; + + if (isset($this->variable)) { + $cql = $this->variable->toQuery() . ' = '; + } + + $cql .= sprintf("ANY (%s)", $this->pattern->toQuery()); + + return $cql; + } +} diff --git a/src/Patterns/Shortest.php b/src/Patterns/Shortest.php new file mode 100644 index 0000000..6d0d9ac --- /dev/null +++ b/src/Patterns/Shortest.php @@ -0,0 +1,61 @@ +pattern = $pattern; + $this->k = CastUtils::toIntegerType($k); + } + + /** + * @inheritDoc + */ + public function toQuery(): string + { + $cql = ''; + + if (isset($this->variable)) { + $cql = $this->variable->toQuery() . ' = '; + } + + $cql .= sprintf("SHORTEST %s (%s)", $this->k->toQuery(), $this->pattern->toQuery()); + + return $cql; + } +} diff --git a/src/Patterns/ShortestGroups.php b/src/Patterns/ShortestGroups.php new file mode 100644 index 0000000..8ccbb38 --- /dev/null +++ b/src/Patterns/ShortestGroups.php @@ -0,0 +1,61 @@ +pattern = $pattern; + $this->k = CastUtils::toIntegerType($k); + } + + /** + * @inheritDoc + */ + public function toQuery(): string + { + $cql = ''; + + if (isset($this->variable)) { + $cql = $this->variable->toQuery() . ' = '; + } + + $cql .= sprintf("SHORTEST %s GROUPS (%s)", $this->k->toQuery(), $this->pattern->toQuery()); + + return $cql; + } +} diff --git a/src/Patterns/ShortestPath.php b/src/Patterns/ShortestPath.php new file mode 100644 index 0000000..6aed9c2 --- /dev/null +++ b/src/Patterns/ShortestPath.php @@ -0,0 +1,52 @@ +pattern = $pattern; + } + + /** + * @inheritDoc + */ + public function toQuery(): string + { + $cql = ''; + + if (isset($this->variable)) { + $cql = $this->variable->toQuery() . ' = '; + } + + $cql .= sprintf("shortestPath(%s)", $this->pattern->toQuery()); + + return $cql; + } +} diff --git a/src/Query.php b/src/Query.php index 03f11a3..9a5b493 100644 --- a/src/Query.php +++ b/src/Query.php @@ -43,11 +43,17 @@ use WikibaseSolutions\CypherDSL\Expressions\Property; use WikibaseSolutions\CypherDSL\Expressions\RawExpression; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\AllShortest; +use WikibaseSolutions\CypherDSL\Patterns\AllShortestPaths; +use WikibaseSolutions\CypherDSL\Patterns\AnyPath; use WikibaseSolutions\CypherDSL\Patterns\CompletePattern; use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\Patterns\Relationship; +use WikibaseSolutions\CypherDSL\Patterns\Shortest; +use WikibaseSolutions\CypherDSL\Patterns\ShortestGroups; +use WikibaseSolutions\CypherDSL\Patterns\ShortestPath; use WikibaseSolutions\CypherDSL\Syntax\Alias; use WikibaseSolutions\CypherDSL\Syntax\PropertyReplacement; use WikibaseSolutions\CypherDSL\Types\AnyType; @@ -138,6 +144,80 @@ public static function relationshipFrom(): Relationship return new Relationship(Direction::LEFT); } + /** + * Creates a shortestPath pattern. + * + * @param CompletePattern $pattern The pattern to find the shortest path for + * + * @see https://neo4j.com/docs/cypher-manual/current/clauses/shortestpath/ Corresponding documentation on Neo4j.com + */ + public static function shortestPath(CompletePattern $pattern): ShortestPath + { + return new ShortestPath($pattern); + } + + /** + * Creates an allShortestPaths pattern. + * + * @param CompletePattern $pattern The pattern to find all shortest paths for + * + * @see https://neo4j.com/docs/cypher-manual/current/clauses/allshortestpaths/ Corresponding documentation on Neo4j.com + */ + public static function allShortestPaths(CompletePattern $pattern): AllShortestPaths + { + return new AllShortestPaths($pattern); + } + + /** + * Creates a SHORTEST k construct. + * + * @param CompletePattern $pattern The pattern to find the shortest path for + * @param int|IntegerType $k The number of paths to match + * + * @see https://neo4j.com/docs/cypher-manual/current/patterns/shortest-paths/ Corresponding documentation on Neo4j.com + */ + public static function shortest(CompletePattern $pattern, int|IntegerType $k = 1): Shortest + { + return new Shortest($pattern, $k); + } + + /** + * Creates an ALL SHORTEST construct. + * + * @param CompletePattern $pattern The pattern to find all shortest paths for + * + * @see https://neo4j.com/docs/cypher-manual/current/patterns/shortest-paths/ Corresponding documentation on Neo4j.com + */ + public static function allShortest(CompletePattern $pattern): AllShortest + { + return new AllShortest($pattern); + } + + /** + * Creates a SHORTEST k GROUPS construct. + * + * @param CompletePattern $pattern The pattern to find the shortest groups for + * @param int|IntegerType $k The number of groups to match + * + * @see https://neo4j.com/docs/cypher-manual/current/patterns/shortest-paths/ Corresponding documentation on Neo4j.com + */ + public static function shortestGroups(CompletePattern $pattern, int|IntegerType $k): ShortestGroups + { + return new ShortestGroups($pattern, $k); + } + + /** + * Creates an ANY construct. + * + * @param CompletePattern $pattern The pattern to find any path for + * + * @see https://neo4j.com/docs/cypher-manual/current/patterns/shortest-paths/ Corresponding documentation on Neo4j.com + */ + public static function anyPath(CompletePattern $pattern): AnyPath + { + return new AnyPath($pattern); + } + /** * Creates a new variable with the given name, or generates a new variable with a random unique name. * diff --git a/src/functions.php b/src/functions.php index 2b99586..bd01182 100644 --- a/src/functions.php +++ b/src/functions.php @@ -21,9 +21,17 @@ use WikibaseSolutions\CypherDSL\Expressions\Procedures\Procedure; use WikibaseSolutions\CypherDSL\Expressions\RawExpression; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\AllShortest; +use WikibaseSolutions\CypherDSL\Patterns\AllShortestPaths; +use WikibaseSolutions\CypherDSL\Patterns\AnyPath; +use WikibaseSolutions\CypherDSL\Patterns\CompletePattern; use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Relationship; +use WikibaseSolutions\CypherDSL\Patterns\Shortest; +use WikibaseSolutions\CypherDSL\Patterns\ShortestGroups; +use WikibaseSolutions\CypherDSL\Patterns\ShortestPath; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\IntegerType; /** * Creates a new Cypher query. @@ -99,6 +107,80 @@ function relationshipFrom(): Relationship return Query::relationshipFrom(); } +/** + * Creates a shortestPath pattern. + * + * @param CompletePattern $pattern The pattern to find the shortest path for + * + * @see Query::shortestPath() + */ +function shortestPath(CompletePattern $pattern): ShortestPath +{ + return Query::shortestPath($pattern); +} + +/** + * Creates an allShortestPaths pattern. + * + * @param CompletePattern $pattern The pattern to find all shortest paths for + * + * @see Query::allShortestPaths() + */ +function allShortestPaths(CompletePattern $pattern): AllShortestPaths +{ + return Query::allShortestPaths($pattern); +} + +/** + * Creates the SHORTEST k construct. + * + * @param CompletePattern $pattern The pattern to find the shortest path for + * @param int|IntegerType $k The number of paths to match + * + * @see Query::shortest() + */ +function shortest(CompletePattern $pattern, int|IntegerType $k = 1): Shortest +{ + return Query::shortest($pattern, $k); +} + +/** + * Creates the ALL SHORTEST construct. + * + * @param CompletePattern $pattern The pattern to find all shortest paths for + * + * @see Query::allShortest() + */ +function allShortest(CompletePattern $pattern): AllShortest +{ + return Query::allShortest($pattern); +} + +/** + * Creates the SHORTEST k GROUPS construct. + * + * @param CompletePattern $pattern The pattern to find the shortest groups for + * @param int|IntegerType $k The number of groups to match + * + * @see Query::shortestGroups() + */ +function shortestGroups(CompletePattern $pattern, int|IntegerType $k): ShortestGroups +{ + return Query::shortestGroups($pattern, $k); +} + +/** + * Creates the ANY construct. + * + * @param CompletePattern $pattern The pattern to find any path for + * + * @see Query::anyPath() + */ +function anyPath(CompletePattern $pattern): AnyPath +{ + return Query::anyPath($pattern); +} + /** * Creates a new variable with the given name, or generates a new variable with a random unique name. * diff --git a/tests/unit/FunctionsTest.php b/tests/unit/FunctionsTest.php index d0ea56f..008c040 100644 --- a/tests/unit/FunctionsTest.php +++ b/tests/unit/FunctionsTest.php @@ -12,6 +12,9 @@ use PHPUnit\Framework\TestCase; use TypeError; +use function WikibaseSolutions\CypherDSL\allShortest; +use function WikibaseSolutions\CypherDSL\allShortestPaths; +use function WikibaseSolutions\CypherDSL\anyPath; use WikibaseSolutions\CypherDSL\Expressions\Literals\Boolean; use WikibaseSolutions\CypherDSL\Expressions\Literals\Float_; use WikibaseSolutions\CypherDSL\Expressions\Literals\Integer; @@ -29,13 +32,22 @@ use function WikibaseSolutions\CypherDSL\literal; use function WikibaseSolutions\CypherDSL\map; use function WikibaseSolutions\CypherDSL\node; +use WikibaseSolutions\CypherDSL\Patterns\AllShortest; +use WikibaseSolutions\CypherDSL\Patterns\AllShortestPaths; +use WikibaseSolutions\CypherDSL\Patterns\AnyPath; use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Relationship; +use WikibaseSolutions\CypherDSL\Patterns\Shortest; +use WikibaseSolutions\CypherDSL\Patterns\ShortestGroups; +use WikibaseSolutions\CypherDSL\Patterns\ShortestPath; use WikibaseSolutions\CypherDSL\Query; use function WikibaseSolutions\CypherDSL\query; use function WikibaseSolutions\CypherDSL\raw; use function WikibaseSolutions\CypherDSL\relationship; +use function WikibaseSolutions\CypherDSL\shortest; +use function WikibaseSolutions\CypherDSL\shortestGroups; +use function WikibaseSolutions\CypherDSL\shortestPath; use function WikibaseSolutions\CypherDSL\string; use function WikibaseSolutions\CypherDSL\variable; @@ -247,4 +259,76 @@ public function testRawOnlyAcceptsString(): void // @phpstan-ignore-next-line raw([]); } + + public function testShortestPath(): void + { + $path = node()->relationshipTo(node()); + $shortestPath = shortestPath($path); + + $this->assertInstanceOf(ShortestPath::class, $shortestPath); + $this->assertSame('shortestPath(()-->())', $shortestPath->toQuery()); + } + + public function testAllShortestPaths(): void + { + $path = node()->relationshipTo(node()); + $allShortestPaths = allShortestPaths($path); + + $this->assertInstanceOf(AllShortestPaths::class, $allShortestPaths); + $this->assertSame('allShortestPaths(()-->())', $allShortestPaths->toQuery()); + } + + public function testShortest(): void + { + $path = node()->relationshipTo(node()); + $shortest = shortest($path, 2); + + $this->assertInstanceOf(Shortest::class, $shortest); + $this->assertSame('SHORTEST 2 (()-->())', $shortest->toQuery()); + } + + public function testShortestIntegerType(): void + { + $path = node()->relationshipTo(node()); + $shortest = shortest($path, new Integer(2)); + + $this->assertInstanceOf(Shortest::class, $shortest); + $this->assertSame('SHORTEST 2 (()-->())', $shortest->toQuery()); + } + + public function testAllShortest(): void + { + $path = node()->relationshipTo(node()); + $allShortest = allShortest($path); + + $this->assertInstanceOf(AllShortest::class, $allShortest); + $this->assertSame('ALL SHORTEST (()-->())', $allShortest->toQuery()); + } + + public function testShortestGroups(): void + { + $path = node()->relationshipTo(node()); + $shortestGroups = shortestGroups($path, 3); + + $this->assertInstanceOf(ShortestGroups::class, $shortestGroups); + $this->assertSame('SHORTEST 3 GROUPS (()-->())', $shortestGroups->toQuery()); + } + + public function testShortestGroupsIntegerType(): void + { + $path = node()->relationshipTo(node()); + $shortestGroups = shortestGroups($path, new Integer(3)); + + $this->assertInstanceOf(ShortestGroups::class, $shortestGroups); + $this->assertSame('SHORTEST 3 GROUPS (()-->())', $shortestGroups->toQuery()); + } + + public function testAnyPath(): void + { + $path = node()->relationshipTo(node()); + $anyPath = anyPath($path); + + $this->assertInstanceOf(AnyPath::class, $anyPath); + $this->assertSame('ANY (()-->())', $anyPath->toQuery()); + } } diff --git a/tests/unit/Patterns/AllShortestPathsTest.php b/tests/unit/Patterns/AllShortestPathsTest.php new file mode 100644 index 0000000..8022771 --- /dev/null +++ b/tests/unit/Patterns/AllShortestPathsTest.php @@ -0,0 +1,45 @@ +relationshipTo(Query::node()); + $allShortestPaths = new AllShortestPaths($path); + + $this->assertEquals('allShortestPaths(()-->())', $allShortestPaths->toQuery()); + } + + public function testToQueryWithVariable(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $allShortestPaths = new AllShortestPaths($path); + $allShortestPaths->withVariable('p'); + + $this->assertEquals('p = allShortestPaths(()-->())', $allShortestPaths->toQuery()); + } + + public function testToQueryWithInnerVariable(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $path->withVariable('q'); + $allShortestPaths = new AllShortestPaths($path); + + $this->assertEquals('allShortestPaths(q = ()-->())', $allShortestPaths->toQuery()); + } +} diff --git a/tests/unit/Patterns/AllShortestTest.php b/tests/unit/Patterns/AllShortestTest.php new file mode 100644 index 0000000..733b1df --- /dev/null +++ b/tests/unit/Patterns/AllShortestTest.php @@ -0,0 +1,36 @@ +relationshipTo(Query::node()); + $allShortest = new AllShortest($path); + + $this->assertEquals('ALL SHORTEST (()-->())', $allShortest->toQuery()); + } + + public function testToQueryWithVariable(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $allShortest = new AllShortest($path); + $allShortest->withVariable('p'); + + $this->assertEquals('p = ALL SHORTEST (()-->())', $allShortest->toQuery()); + } +} diff --git a/tests/unit/Patterns/AnyPathTest.php b/tests/unit/Patterns/AnyPathTest.php new file mode 100644 index 0000000..486db39 --- /dev/null +++ b/tests/unit/Patterns/AnyPathTest.php @@ -0,0 +1,36 @@ +relationshipTo(Query::node()); + $anyPath = new AnyPath($path); + + $this->assertEquals('ANY (()-->())', $anyPath->toQuery()); + } + + public function testToQueryWithVariable(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $anyPath = new AnyPath($path); + $anyPath->withVariable('p'); + + $this->assertEquals('p = ANY (()-->())', $anyPath->toQuery()); + } +} diff --git a/tests/unit/Patterns/ShortestGroupsTest.php b/tests/unit/Patterns/ShortestGroupsTest.php new file mode 100644 index 0000000..a668d1c --- /dev/null +++ b/tests/unit/Patterns/ShortestGroupsTest.php @@ -0,0 +1,44 @@ +relationshipTo(Query::node()); + $shortestGroups = new ShortestGroups($path, 2); + + $this->assertEquals('SHORTEST 2 GROUPS (()-->())', $shortestGroups->toQuery()); + } + + public function testToQueryWithIntegerClass(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortestGroups = new ShortestGroups($path, Query::integer(5)); + + $this->assertEquals('SHORTEST 5 GROUPS (()-->())', $shortestGroups->toQuery()); + } + + public function testToQueryWithVariable(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortestGroups = new ShortestGroups($path, 10); + $shortestGroups->withVariable('p'); + + $this->assertEquals('p = SHORTEST 10 GROUPS (()-->())', $shortestGroups->toQuery()); + } +} diff --git a/tests/unit/Patterns/ShortestPathTest.php b/tests/unit/Patterns/ShortestPathTest.php new file mode 100644 index 0000000..4596be1 --- /dev/null +++ b/tests/unit/Patterns/ShortestPathTest.php @@ -0,0 +1,45 @@ +relationshipTo(Query::node()); + $shortestPath = new ShortestPath($path); + + $this->assertEquals('shortestPath(()-->())', $shortestPath->toQuery()); + } + + public function testToQueryWithVariable(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortestPath = new ShortestPath($path); + $shortestPath->withVariable('p'); + + $this->assertEquals('p = shortestPath(()-->())', $shortestPath->toQuery()); + } + + public function testToQueryWithInnerVariable(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $path->withVariable('q'); + $shortestPath = new ShortestPath($path); + + $this->assertEquals('shortestPath(q = ()-->())', $shortestPath->toQuery()); + } +} diff --git a/tests/unit/Patterns/ShortestTest.php b/tests/unit/Patterns/ShortestTest.php new file mode 100644 index 0000000..bd1729e --- /dev/null +++ b/tests/unit/Patterns/ShortestTest.php @@ -0,0 +1,52 @@ +relationshipTo(Query::node()); + $shortest = new Shortest($path, 1); + + $this->assertEquals('SHORTEST 1 (()-->())', $shortest->toQuery()); + } + + public function testToQueryWithVariable(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortest = new Shortest($path, 5); + $shortest->withVariable('p'); + + $this->assertEquals('p = SHORTEST 5 (()-->())', $shortest->toQuery()); + } + + public function testToQueryWithParameter(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortest = new Shortest($path, Query::parameter('k')); + + $this->assertEquals('SHORTEST $k (()-->())', $shortest->toQuery()); + } + + public function testToQueryWithIntegerClass(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortest = new Shortest($path, Query::integer(10)); + + $this->assertEquals('SHORTEST 10 (()-->())', $shortest->toQuery()); + } +} diff --git a/tests/unit/QueryTest.php b/tests/unit/QueryTest.php index 785b9fb..7ae64e8 100644 --- a/tests/unit/QueryTest.php +++ b/tests/unit/QueryTest.php @@ -16,6 +16,7 @@ use WikibaseSolutions\CypherDSL\Clauses\RawClause; use WikibaseSolutions\CypherDSL\Clauses\WhereClause; use WikibaseSolutions\CypherDSL\Clauses\WithClause; +use WikibaseSolutions\CypherDSL\Expressions\Exists; use WikibaseSolutions\CypherDSL\Expressions\Label; use WikibaseSolutions\CypherDSL\Expressions\Literals\Boolean; use WikibaseSolutions\CypherDSL\Expressions\Literals\Float_; @@ -30,16 +31,22 @@ use WikibaseSolutions\CypherDSL\Expressions\Property; use WikibaseSolutions\CypherDSL\Expressions\RawExpression; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\AllShortest; +use WikibaseSolutions\CypherDSL\Patterns\AllShortestPaths; +use WikibaseSolutions\CypherDSL\Patterns\AnyPath; use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Path; use WikibaseSolutions\CypherDSL\Patterns\Relationship; +use WikibaseSolutions\CypherDSL\Patterns\Shortest; +use WikibaseSolutions\CypherDSL\Patterns\ShortestGroups; +use WikibaseSolutions\CypherDSL\Patterns\ShortestPath; use WikibaseSolutions\CypherDSL\Query; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PropertyType; /** - * This class only tests methods of the query class that do not add a neq clause. Use a separate class for testing + * This class only tests methods of the query class that do not add a new clause. Use a separate class for testing * functions that add new clauses to the query. * * @covers \WikibaseSolutions\CypherDSL\Query @@ -196,6 +203,77 @@ public function testToString(): void $this->assertSame('SKIP 10', (string) $query); } + public function testShortestPath(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortestPath = Query::shortestPath($path); + + $this->assertInstanceOf(ShortestPath::class, $shortestPath); + } + + public function testAllShortestPaths(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $allShortestPaths = Query::allShortestPaths($path); + + $this->assertInstanceOf(AllShortestPaths::class, $allShortestPaths); + } + + public function testShortest(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortest = Query::shortest($path, 2); + + $this->assertInstanceOf(Shortest::class, $shortest); + } + + public function testShortestWithIntegerClass(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortest = Query::shortest($path, Query::integer(2)); + + $this->assertInstanceOf(Shortest::class, $shortest); + } + + public function testAllShortest(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $allShortest = Query::allShortest($path); + + $this->assertInstanceOf(AllShortest::class, $allShortest); + } + + public function testShortestGroups(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortestGroups = Query::shortestGroups($path, 3); + + $this->assertInstanceOf(ShortestGroups::class, $shortestGroups); + } + + public function testShortestGroupsWithIntegerClass(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $shortestGroups = Query::shortestGroups($path, Query::integer(3)); + + $this->assertInstanceOf(ShortestGroups::class, $shortestGroups); + } + + public function testAnyPath(): void + { + $path = Query::node()->relationshipTo(Query::node()); + $anyPath = Query::anyPath($path); + + $this->assertInstanceOf(AnyPath::class, $anyPath); + } + + public function testExists(): void + { + $exists = Query::exists(Query::node()); + + $this->assertInstanceOf(Exists::class, $exists); + } + public function testListOfLiterals(): void { $list = Query::list(["hello", "world", 1.0, 1, 2, 3, true]);