From bdd4ae0d86a0d6a6edbe613e305db2958260dd18 Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Mon, 2 Feb 2026 19:59:13 +0100 Subject: [PATCH 01/12] Start on removing traits and using union types --- composer.json | 6 +- src/Clauses/CallClause.php | 8 +- src/Clauses/CallProcedureClause.php | 10 +- src/Clauses/CreateClause.php | 3 - src/Clauses/DeleteClause.php | 6 +- src/Clauses/LimitClause.php | 8 +- src/Clauses/RemoveClause.php | 10 +- src/Clauses/ReturnClause.php | 13 +- src/Clauses/SetClause.php | 12 +- src/Clauses/SkipClause.php | 8 +- src/Clauses/WhereClause.php | 10 +- src/Clauses/WithClause.php | 12 +- src/Expressions/Exists.php | 2 - src/Expressions/Literals/Integer.php | 6 +- src/Expressions/Literals/List_.php | 12 +- src/Expressions/Literals/Literal.php | 246 +++++++++--------- src/Expressions/Literals/Map.php | 18 +- src/Expressions/Parameter.php | 3 +- src/Expressions/Procedures/IsEmpty.php | 9 +- src/Expressions/Procedures/Procedure.php | 97 +++---- src/Expressions/Procedures/Raw.php | 12 +- src/Expressions/Property.php | 8 +- src/Expressions/Variable.php | 4 +- src/Patterns/CompletePattern.php | 2 +- src/Patterns/Node.php | 2 - src/Patterns/Path.php | 11 +- src/Patterns/PropertyPattern.php | 12 +- src/Query.php | 12 +- src/Syntax/PropertyReplacement.php | 11 +- src/Traits/ErrorTrait.php | 188 ------------- src/Traits/EscapeTrait.php | 56 ---- src/Traits/NameGenerationTrait.php | 43 --- .../PatternTraits/PropertyPatternTrait.php | 14 +- .../CastTrait.php => Utils/CastUtils.php} | 96 ++----- src/Utils/NameUtils.php | 74 ++++++ tests/unit/Utils/CastUtilsTest.php | 8 + tests/unit/Utils/NameUtilsTest.php | 8 + 37 files changed, 361 insertions(+), 699 deletions(-) delete mode 100644 src/Traits/ErrorTrait.php delete mode 100644 src/Traits/EscapeTrait.php delete mode 100644 src/Traits/NameGenerationTrait.php rename src/{Traits/CastTrait.php => Utils/CastUtils.php} (50%) create mode 100644 src/Utils/NameUtils.php create mode 100644 tests/unit/Utils/CastUtilsTest.php create mode 100644 tests/unit/Utils/NameUtilsTest.php diff --git a/composer.json b/composer.json index 9ccd27b7..25878292 100644 --- a/composer.json +++ b/composer.json @@ -46,11 +46,9 @@ "source": "https://github.com/WikibaseSolutions/php-cypher-dsl" }, "require": { - "php": ">=7.4", + "php": ">=8.1", "ext-ctype": "*", - "ext-openssl": "*", - "symfony/polyfill-php80": "^1.25", - "symfony/polyfill-php81": "^1.25" + "ext-openssl": "*" }, "require-dev": { "phpunit/phpunit": "~9.0", diff --git a/src/Clauses/CallClause.php b/src/Clauses/CallClause.php index cc8b11c8..47df3856 100644 --- a/src/Clauses/CallClause.php +++ b/src/Clauses/CallClause.php @@ -12,8 +12,7 @@ use WikibaseSolutions\CypherDSL\Expressions\Variable; use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\Query; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a CALL {} (subquery) clause. The CALL {} clause evaluates a subquery that returns @@ -26,9 +25,6 @@ */ final class CallClause extends Clause { - use CastTrait; - use ErrorTrait; - /** * @var null|Query The sub-query to call, or NULL if no sub-query has been set yet */ @@ -67,7 +63,7 @@ public function addWithVariable(...$variables): self $res = []; foreach ($variables as $variable) { - $res[] = self::toVariable($variable); + $res[] = CastUtils::toVariable($variable); } $this->withVariables = array_merge($this->withVariables, $res); diff --git a/src/Clauses/CallProcedureClause.php b/src/Clauses/CallProcedureClause.php index 788909b5..8907e51f 100644 --- a/src/Clauses/CallProcedureClause.php +++ b/src/Clauses/CallProcedureClause.php @@ -12,7 +12,7 @@ use WikibaseSolutions\CypherDSL\Expressions\Procedures\Procedure; use WikibaseSolutions\CypherDSL\Expressions\Variable; use WikibaseSolutions\CypherDSL\Syntax\Alias; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a CALL procedure clause. @@ -25,8 +25,6 @@ */ final class CallProcedureClause extends Clause { - use CastTrait; - /** * @var null|Procedure The procedure to call */ @@ -63,7 +61,7 @@ public function addYield(...$yields): self $res = []; foreach ($yields as $yield) { - $res[] = $yield instanceof Alias ? $yield : self::toName($yield); + $res[] = $yield instanceof Alias ? $yield : CastUtils::toName($yield); } $this->yields = array_merge($this->yields, $res); @@ -74,7 +72,7 @@ public function addYield(...$yields): self /** * Returns the procedure to call. * - * @return Procedure + * @return Procedure|null */ public function getProcedure(): ?Procedure { @@ -84,7 +82,7 @@ public function getProcedure(): ?Procedure /** * Returns the variables to yield. * - * @return Alias[]|Variable[]|(Alias|Variable)[] + * @return (Alias|Variable)[] */ public function getYields(): array { diff --git a/src/Clauses/CreateClause.php b/src/Clauses/CreateClause.php index bb4f460f..f305b4b2 100644 --- a/src/Clauses/CreateClause.php +++ b/src/Clauses/CreateClause.php @@ -11,7 +11,6 @@ use WikibaseSolutions\CypherDSL\Patterns\CompletePattern; use WikibaseSolutions\CypherDSL\Query; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; /** * This class represents a CREATE clause. @@ -24,8 +23,6 @@ */ final class CreateClause extends Clause { - use ErrorTrait; - /** * @var CompletePattern[] The patterns to create */ diff --git a/src/Clauses/DeleteClause.php b/src/Clauses/DeleteClause.php index ecf8c759..d5c580fa 100644 --- a/src/Clauses/DeleteClause.php +++ b/src/Clauses/DeleteClause.php @@ -11,8 +11,8 @@ use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\Query; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Types\StructuralTypes\StructuralType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a DELETE clause. @@ -25,8 +25,6 @@ */ final class DeleteClause extends Clause { - use CastTrait; - /** * Whether the DETACH modifier is needed. */ @@ -64,7 +62,7 @@ public function addStructure(...$structures): self $res = []; foreach ($structures as $structure) { - $res[] = self::toStructuralType($structure); + $res[] = CastUtils::toStructuralType($structure); } $this->structures = array_merge($this->structures, $res); diff --git a/src/Clauses/LimitClause.php b/src/Clauses/LimitClause.php index 2819eda2..b252f1fb 100644 --- a/src/Clauses/LimitClause.php +++ b/src/Clauses/LimitClause.php @@ -10,8 +10,8 @@ namespace WikibaseSolutions\CypherDSL\Clauses; use WikibaseSolutions\CypherDSL\Query; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\IntegerType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a LIMIT clause. @@ -24,8 +24,6 @@ */ final class LimitClause extends Clause { - use CastTrait; - /** * The expression of the LIMIT statement. */ @@ -38,9 +36,9 @@ final class LimitClause extends Clause * * @return $this */ - public function setLimit($limit): self + public function setLimit(IntegerType|int $limit): self { - $this->limit = self::toIntegerType($limit); + $this->limit = CastUtils::toIntegerType($limit); return $this; } diff --git a/src/Clauses/RemoveClause.php b/src/Clauses/RemoveClause.php index af9850ab..88384f78 100644 --- a/src/Clauses/RemoveClause.php +++ b/src/Clauses/RemoveClause.php @@ -12,7 +12,6 @@ use WikibaseSolutions\CypherDSL\Expressions\Label; use WikibaseSolutions\CypherDSL\Expressions\Property; use WikibaseSolutions\CypherDSL\QueryConvertible; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; /** * This class represents a REMOVE clause. @@ -23,10 +22,8 @@ */ final class RemoveClause extends Clause { - use ErrorTrait; - /** - * @var Label[]|Property[]|(Label|Property)[] the expressions in this REMOVE clause + * @var (Label|Property)[] the expressions in this REMOVE clause */ private array $expressions = []; @@ -37,9 +34,8 @@ final class RemoveClause extends Clause * * @return RemoveClause */ - public function addExpression(...$expressions): self + public function addExpression(Property|Label ...$expressions): self { - self::assertClassArray('expressions', [Property::class, Label::class], $expressions); $this->expressions = array_merge($this->expressions, $expressions); return $this; @@ -48,7 +44,7 @@ public function addExpression(...$expressions): self /** * Returns the expressions in the REMOVE clause. * - * @return Label[]|Property[]|(Label|Property)[] + * @return (Label|Property)[] */ public function getExpressions(): array { diff --git a/src/Clauses/ReturnClause.php b/src/Clauses/ReturnClause.php index aec1ce24..b27608c3 100644 --- a/src/Clauses/ReturnClause.php +++ b/src/Clauses/ReturnClause.php @@ -13,8 +13,8 @@ use WikibaseSolutions\CypherDSL\QueryConvertible; use WikibaseSolutions\CypherDSL\Syntax\Alias; use WikibaseSolutions\CypherDSL\Traits\CastTrait; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a RETURN clause. @@ -25,9 +25,6 @@ */ final class ReturnClause extends Clause { - use CastTrait; - use ErrorTrait; - /** * @var bool Whether to be a RETURN DISTINCT query */ @@ -41,18 +38,18 @@ final class ReturnClause extends Clause /** * Add a new column to this RETURN clause. * - * @param Alias|AnyType|bool|float|int|mixed[]|Pattern|string ...$columns The values to return + * @param Alias|AnyType|bool|float|int|array|Pattern|string ...$columns The values to return * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/return/#return-column-alias */ - public function addColumn(...$columns): self + public function addColumn(Alias|AnyType|bool|float|int|array|Pattern|string ...$columns): self { $res = []; foreach ($columns as $column) { - $res[] = $column instanceof Alias ? $column : self::toAnyType($column); + $res[] = $column instanceof Alias ? $column : CastUtils::toAnyType($column); } $this->columns = array_merge($this->columns, $res); @@ -77,7 +74,7 @@ public function setDistinct(bool $distinct = true): self /** * Returns the columns to return. Aliased columns have string keys instead of integers. * - * @return Alias[]|AnyType[]|(Alias|AnyType)[] + * @return (Alias|AnyType)[] */ public function getColumns(): array { diff --git a/src/Clauses/SetClause.php b/src/Clauses/SetClause.php index 6c88d014..4249e057 100644 --- a/src/Clauses/SetClause.php +++ b/src/Clauses/SetClause.php @@ -12,7 +12,6 @@ use WikibaseSolutions\CypherDSL\Expressions\Label; use WikibaseSolutions\CypherDSL\QueryConvertible; use WikibaseSolutions\CypherDSL\Syntax\PropertyReplacement; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; /** * This class represents a SET clause. @@ -23,23 +22,20 @@ */ final class SetClause extends Clause { - use ErrorTrait; - /** - * @var Label[]|PropertyReplacement[]|(Label|PropertyReplacement)[] The expressions to set + * @var (Label|PropertyReplacement)[] The expressions to set */ private array $expressions = []; /** * Add one or more expressions to this SET clause. * - * @param Label|PropertyReplacement $expressions The expressions to add to this set clause + * @param Label|PropertyReplacement ...$expressions The expressions to add to this set clause * * @return $this */ - public function add(...$expressions): self + public function add(Label|PropertyReplacement ...$expressions): self { - $this->assertClassArray('expression', [PropertyReplacement::class, Label::class], $expressions); $this->expressions = array_merge($this->expressions, $expressions); return $this; @@ -48,7 +44,7 @@ public function add(...$expressions): self /** * Returns the expressions to SET. * - * @return Label[]|PropertyReplacement[]|(Label|PropertyReplacement)[] + * @return (Label|PropertyReplacement)[] */ public function getExpressions(): array { diff --git a/src/Clauses/SkipClause.php b/src/Clauses/SkipClause.php index 4e544fe7..2a50841c 100644 --- a/src/Clauses/SkipClause.php +++ b/src/Clauses/SkipClause.php @@ -9,8 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Clauses; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\IntegerType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a SKIP clause. @@ -21,8 +21,6 @@ */ final class SkipClause extends Clause { - use CastTrait; - /** * The expression of the SKIP statement. */ @@ -35,9 +33,9 @@ final class SkipClause extends Clause * * @return SkipClause */ - public function setSkip($skip): self + public function setSkip(IntegerType|int $skip): self { - $this->skip = self::toIntegerType($skip); + $this->skip = CastUtils::toIntegerType($skip); return $this; } diff --git a/src/Clauses/WhereClause.php b/src/Clauses/WhereClause.php index 818d7a76..0ab8ae73 100644 --- a/src/Clauses/WhereClause.php +++ b/src/Clauses/WhereClause.php @@ -10,8 +10,8 @@ namespace WikibaseSolutions\CypherDSL\Clauses; use InvalidArgumentException; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a WHERE clause. @@ -24,12 +24,8 @@ */ final class WhereClause extends Clause { - use CastTrait; - public const AND = 'and'; - public const OR = 'or'; - public const XOR = 'xor'; /** @@ -46,9 +42,9 @@ final class WhereClause extends Clause * * @return $this */ - public function addExpression($expression, string $operator = self::AND): self + public function addExpression(BooleanType|bool $expression, string $operator = self::AND): self { - $expression = self::toBooleanType($expression); + $expression = CastUtils::toBooleanType($expression); if ($operator !== self::AND && $operator !== self::OR && $operator !== self::XOR) { throw new InvalidArgumentException('$operator must either be "and", "xor" or "or"'); diff --git a/src/Clauses/WithClause.php b/src/Clauses/WithClause.php index 5783c91d..bb1f3d85 100644 --- a/src/Clauses/WithClause.php +++ b/src/Clauses/WithClause.php @@ -14,7 +14,7 @@ use WikibaseSolutions\CypherDSL\Query; use WikibaseSolutions\CypherDSL\QueryConvertible; use WikibaseSolutions\CypherDSL\Syntax\Alias; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a WITH clause. @@ -28,10 +28,8 @@ */ final class WithClause extends Clause { - use CastTrait; - /** - * @var Alias[]|Variable[]|(Alias|Variable)[] The variables to include in the clause + * @var (Alias|Variable)[] The variables to include in the clause */ private array $entries = []; @@ -42,12 +40,12 @@ final class WithClause extends Clause * * @return $this */ - public function addEntry(...$entries): self + public function addEntry(Alias|Pattern|string|Variable ...$entries): self { $res = []; foreach ($entries as $entry) { - $res[] = $entry instanceof Alias ? $entry : self::toVariable($entry); + $res[] = $entry instanceof Alias ? $entry : CastUtils::toVariable($entry); } $this->entries = array_merge($this->entries, $res); @@ -58,7 +56,7 @@ public function addEntry(...$entries): self /** * Returns the expression to include in the clause. * - * @return Alias[]|Variable[]|(Alias|Variable)[] + * @return (Alias|Variable)[] */ public function getEntries(): array { diff --git a/src/Expressions/Exists.php b/src/Expressions/Exists.php index 72153975..1249d7e7 100644 --- a/src/Expressions/Exists.php +++ b/src/Expressions/Exists.php @@ -11,7 +11,6 @@ use WikibaseSolutions\CypherDSL\Clauses\MatchClause; use WikibaseSolutions\CypherDSL\Clauses\WhereClause; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; @@ -23,7 +22,6 @@ final class Exists implements BooleanType { use BooleanTypeTrait; - use ErrorTrait; /** * @var MatchClause The MATCH part of the EXISTS expression diff --git a/src/Expressions/Literals/Integer.php b/src/Expressions/Literals/Integer.php index f8f8ad37..ad9d8e4b 100644 --- a/src/Expressions/Literals/Integer.php +++ b/src/Expressions/Literals/Integer.php @@ -30,12 +30,8 @@ final class Integer implements IntegerType * * @internal This function is not covered by the backwards compatibility guarantee of php-cypher-dsl */ - public function __construct($value) + public function __construct(int|string $value) { - if (!is_int($value) && !is_string($value)) { - throw new TypeError('An integer should be given as a string or integer, ' . gettype($value) . ' received.'); - } - $parsedValue = filter_var($value, FILTER_SANITIZE_NUMBER_INT); if ($parsedValue === false) { diff --git a/src/Expressions/Literals/List_.php b/src/Expressions/Literals/List_.php index 949bb9dc..c4b9f27a 100644 --- a/src/Expressions/Literals/List_.php +++ b/src/Expressions/Literals/List_.php @@ -14,6 +14,7 @@ use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents a list of expressions. For example, this class can represent the following @@ -25,7 +26,6 @@ */ final class List_ implements ListType { - use CastTrait; use ListTypeTrait; /** @@ -34,25 +34,25 @@ final class List_ implements ListType private array $expressions; /** - * @param mixed[] $expressions The list of expressions + * @param array $expressions The list of expressions * * @internal This method is not covered by the backwards compatibility promise of php-cypher-dsl */ public function __construct(array $expressions = []) { - $this->expressions = array_map([self::class, 'toAnyType'], $expressions); + $this->expressions = array_map(CastUtils::toAnyType(...), $expressions); } /** * Add one or more expressions to the list. * - * @param AnyType|bool|float|int|mixed[]|Pattern|string ...$expressions + * @param AnyType|bool|float|int|array|Pattern|string ...$expressions * * @return $this */ - public function addExpression(...$expressions): self + public function addExpression(AnyType|bool|float|int|array|Pattern|string ...$expressions): self { - $this->expressions = array_merge($this->expressions, array_map([self::class, 'toAnyType'], $expressions)); + $this->expressions = array_merge($this->expressions, array_map(CastUtils::toAnyType(...), $expressions)); return $this; } diff --git a/src/Expressions/Literals/Literal.php b/src/Expressions/Literals/Literal.php index bea5576d..4f7da655 100644 --- a/src/Expressions/Literals/Literal.php +++ b/src/Expressions/Literals/Literal.php @@ -10,6 +10,7 @@ namespace WikibaseSolutions\CypherDSL\Expressions\Literals; use LogicException; +use Stringable; use Traversable; use TypeError; use WikibaseSolutions\CypherDSL\Expressions\Procedures\Date; @@ -19,19 +20,16 @@ use WikibaseSolutions\CypherDSL\Expressions\Procedures\Point; use WikibaseSolutions\CypherDSL\Expressions\Procedures\Procedure; use WikibaseSolutions\CypherDSL\Expressions\Procedures\Time; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\NumeralType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\StringType; /** * Helper class to construct literals. * - * @note This class should only contain static methods + * @note This class should only contain static methods. */ final class Literal { - use ErrorTrait; - /** * Creates a new literal from the given value. This function automatically constructs the appropriate * class based on the type of the value given. @@ -42,7 +40,7 @@ final class Literal * * @return Boolean|Float_|Integer|List_|Map|String_ */ - public static function literal($literal) + public static function literal(string|bool|int|float|array|Stringable $literal): Boolean|Float_|Integer|List_|Map|String_ { if (is_string($literal)) { return self::string($literal); @@ -82,7 +80,7 @@ public static function literal($literal) * @see Literal::number() * @deprecated */ - public static function decimal($value) + public static function decimal(float|int $value): Float_|Integer { return self::number($value); } @@ -94,10 +92,8 @@ public static function decimal($value) * * @return Float_|Integer */ - public static function number($value) + public static function number(float|int $value): Float_|Integer { - self::assertClass('value', ['int', 'float'], $value); - // @phpstan-ignore-next-line PHPStan does not work well with classes named "Integer" return is_int($value) ? self::integer($value) : self::float($value); } @@ -155,7 +151,7 @@ public static function list(iterable $value): List_ /** * Creates a new map literal. * - * @param mixed[] $value + * @param array $value */ public static function map(array $value): Map { @@ -168,9 +164,11 @@ public static function map(array $value): Map * * @param null|string|StringType $timezone * + * @return Date + * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-current Corresponding documentation on Neo4j.com */ - public static function date($timezone = null): Date + public static function date(StringType|string|null $timezone = null): Date { if ($timezone === null) { return Procedure::date(); @@ -182,13 +180,15 @@ public static function date($timezone = null): Date /** * Creates a date from the given year, month and day. * - * @param int|NumeralType $year + * @param int|NumeralType $year * @param null|int|NumeralType $month * @param null|int|NumeralType $day * + * @return Date + * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-calendar Corresponding documentation on Neo4j.com */ - public static function dateYMD($year, $month = null, $day = null): Date + public static function dateYMD(NumeralType|int $year, NumeralType|int|null $month = null, NumeralType|int|null $day = null): Date { return Procedure::date( self::makeTemporalMap( @@ -204,13 +204,15 @@ public static function dateYMD($year, $month = null, $day = null): Date /** * Creates a date from the given year, week and weekday. * - * @param int|NumeralType $year + * @param int|NumeralType $year * @param null|int|NumeralType $week * @param null|int|NumeralType $weekday * + * @return Date + * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-week Corresponding documentation on Neo4j.com */ - public static function dateYWD($year, $week = null, $weekday = null): Date + public static function dateYWD(NumeralType|int $year, NumeralType|int|null $week = null, NumeralType|int|null $weekday = null): Date { return Procedure::date( self::makeTemporalMap( @@ -228,9 +230,11 @@ public static function dateYWD($year, $week = null, $weekday = null): Date * * @param string|StringType $date * + * @return Date + * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-create-string Corresponding documentation on Neo4j.com */ - public static function dateString($date): Date + public static function dateString(StringType|string $date): Date { return Procedure::date($date); } @@ -239,11 +243,13 @@ public static function dateString($date): Date * Retrieves the current DateTime value, optionally for a different time zone. In reality, this * function just returns a call to the "datetime()" function. * - * @param string|StringType $timezone + * @param StringType|string|null $timezone + * + * @return DateTime * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-current Corresponding documentation on Neo4j.com */ - public static function dateTime($timezone = null): DateTime + public static function dateTime(StringType|string|null $timezone = null): DateTime { if ($timezone === null) { return Procedure::datetime(); @@ -269,16 +275,16 @@ public static function dateTime($timezone = null): DateTime * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-calendar Corresponding documentation on Neo4j.com */ public static function dateTimeYMD( - $year, - $month = null, - $day = null, - $hour = null, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null, - $timezone = null + NumeralType|int $year, + NumeralType|int|null $month = null, + NumeralType|int|null $day = null, + NumeralType|int|null $hour = null, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null, + StringType|string|null $timezone = null ): DateTime { return Procedure::datetime( self::makeTemporalMap( @@ -315,16 +321,16 @@ public static function dateTimeYMD( * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-week Corresponding documentation on Neo4j.com */ public static function dateTimeYWD( - $year, - $week = null, - $dayOfWeek = null, - $hour = null, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null, - $timezone = null + NumeralType|int $year, + NumeralType|int|null $week = null, + NumeralType|int|null $dayOfWeek = null, + NumeralType|int|null $hour = null, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null, + StringType|string|null $timezone = null ): DateTime { return Procedure::datetime( self::makeTemporalMap( @@ -361,16 +367,16 @@ public static function dateTimeYWD( * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-quarter Corresponding documentation on Neo4j.com */ public static function dateTimeYQD( - $year, - $quarter = null, - $dayOfQuarter = null, - $hour = null, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null, - $timezone = null + NumeralType|int $year, + NumeralType|int|null $quarter = null, + NumeralType|int|null $dayOfQuarter = null, + NumeralType|int|null $hour = null, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null, + StringType|string|null $timezone = null ): DateTime { return Procedure::datetime( self::makeTemporalMap( @@ -406,15 +412,15 @@ public static function dateTimeYQD( * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-ordinal Corresponding documentation on Neo4j.com */ public static function dateTimeYD( - $year, - $ordinalDay = null, - $hour = null, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null, - $timezone = null + NumeralType|int $year, + NumeralType|int|null $ordinalDay = null, + NumeralType|int|null $hour = null, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null, + StringType|string|null $timezone = null ): DateTime { return Procedure::datetime( self::makeTemporalMap( @@ -438,7 +444,7 @@ public static function dateTimeYD( * * @param string|StringType $dateString */ - public static function dateTimeString($dateString): DateTime + public static function dateTimeString(StringType|string $dateString): DateTime { return Procedure::datetime($dateString); } @@ -450,7 +456,7 @@ public static function dateTimeString($dateString): DateTime * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-current Corresponding documentation on Neo4j.com */ - public static function localDateTime($timezone = null): LocalDateTime + public static function localDateTime(StringType|string|null $timezone = null): LocalDateTime { if ($timezone === null) { return Procedure::localdatetime(); @@ -475,15 +481,15 @@ public static function localDateTime($timezone = null): LocalDateTime * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-calendar Corresponding documentation on Neo4j.com */ public static function localDateTimeYMD( - $year, - $month = null, - $day = null, - $hour = null, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null + NumeralType|int $year, + NumeralType|int|null $month = null, + NumeralType|int|null $day = null, + NumeralType|int|null $hour = null, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null ): LocalDateTime { return Procedure::localdatetime( self::makeTemporalMap( @@ -506,7 +512,7 @@ public static function localDateTimeYMD( * Creates a LocalDateTime value with the specified year, week, dayOfWeek, hour, minute, * second, millisecond, microsecond and nanosecond component value. * - * @param int|NumeralType $year + * @param int|NumeralType $year * @param null|int|NumeralType $week * @param null|int|NumeralType $dayOfWeek * @param null|int|NumeralType $hour @@ -516,18 +522,20 @@ public static function localDateTimeYMD( * @param null|int|NumeralType $microsecond * @param null|int|NumeralType $nanosecond * + * @return LocalDateTime + * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-week Corresponding documentation on Neo4j.com */ public static function localDateTimeYWD( - $year, - $week = null, - $dayOfWeek = null, - $hour = null, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null + NumeralType|int $year, + NumeralType|int|null $week = null, + NumeralType|int|null $dayOfWeek = null, + NumeralType|int|null $hour = null, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null ): LocalDateTime { return Procedure::localdatetime( self::makeTemporalMap( @@ -562,15 +570,15 @@ public static function localDateTimeYWD( * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-quarter Corresponding documentation on Neo4j.com */ public static function localDateTimeYQD( - $year, - $quarter = null, - $dayOfQuarter = null, - $hour = null, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null + NumeralType|int $year, + NumeralType|int|null $quarter = null, + NumeralType|int|null $dayOfQuarter = null, + NumeralType|int|null $hour = null, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null ): LocalDateTime { return Procedure::localdatetime( self::MakeTemporalMap( @@ -604,14 +612,14 @@ public static function localDateTimeYQD( * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-ordinal Corresponding documentation on Neo4j.com */ public static function localDateTimeYD( - $year, - $ordinalDay = null, - $hour = null, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null + NumeralType|int $year, + NumeralType|int|null $ordinalDay = null, + NumeralType|int|null $hour = null, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null ): LocalDateTime { return Procedure::localdatetime( self::makeTemporalMap( @@ -636,7 +644,7 @@ public static function localDateTimeYD( * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-create-string Corresponding documentation on Neo4j.com */ - public static function localDateTimeString($localDateTimeString): LocalDateTime + public static function localDateTimeString(StringType|string $localDateTimeString): LocalDateTime { return Procedure::localdatetime($localDateTimeString); } @@ -648,7 +656,7 @@ public static function localDateTimeString($localDateTimeString): LocalDateTime * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localtime-current Corresponding documentation on Neo4j.com */ - public static function localTimeCurrent($timezone = null): LocalTime + public static function localTimeCurrent(StringType|string|null $timezone = null): LocalTime { if ($timezone === null) { return Procedure::localtime(); @@ -670,12 +678,12 @@ public static function localTimeCurrent($timezone = null): LocalTime * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localtime-create Corresponding documentation on Neo4j.com */ public static function localTime( - $hour, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null + NumeralType|int $hour, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null ): LocalTime { return Procedure::localtime( self::makeTemporalMap( @@ -696,7 +704,7 @@ public static function localTime( * * @param string|StringType $localTimeString */ - public static function localTimeString($localTimeString): LocalTime + public static function localTimeString(StringType|string $localTimeString): LocalTime { return Procedure::localtime($localTimeString); } @@ -708,7 +716,7 @@ public static function localTimeString($localTimeString): LocalTime * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-time-current Corresponding documentation on Neo4j.com */ - public static function time($timezone = null): Time + public static function time(StringType|string|null $timezone = null): Time { if ($timezone === null) { return Procedure::time(); @@ -731,13 +739,13 @@ public static function time($timezone = null): Time * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-time-create Corresponding documentation on Neo4j.com */ public static function timeHMS( - $hour, - $minute = null, - $second = null, - $millisecond = null, - $microsecond = null, - $nanosecond = null, - $timezone = null + NumeralType|int $hour, + NumeralType|int|null $minute = null, + NumeralType|int|null $second = null, + NumeralType|int|null $millisecond = null, + NumeralType|int|null $microsecond = null, + NumeralType|int|null $nanosecond = null, + NumeralType|int|null $timezone = null ): Time { return Procedure::time( self::makeTemporalMap( @@ -761,7 +769,7 @@ public static function timeHMS( * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-time-create-string Corresponding documentation on Neo4j.com */ - public static function timeString($timeString): Time + public static function timeString(StringType|string $timeString): Time { return Procedure::time($timeString); } @@ -774,7 +782,7 @@ public static function timeString($timeString): Time * * @see https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-cartesian-2d Corresponding documentation on Neo4j.com */ - public static function point2d($x, $y): Point + public static function point2d(NumeralType|int|float $x, NumeralType|int|float $y): Point { return Procedure::point([ "x" => $x, @@ -792,7 +800,7 @@ public static function point2d($x, $y): Point * * @see https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-cartesian-3d Corresponding documentation on Neo4j.com */ - public static function point3d($x, $y, $z): Point + public static function point3d(NumeralType|int|float $x, NumeralType|int|float $y, NumeralType|int|float $z): Point { return Procedure::point([ "x" => $x, @@ -810,7 +818,7 @@ public static function point3d($x, $y, $z): Point * * @see https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-wgs84-2d Corresponding documentation on Neo4j.com */ - public static function point2dWGS84($longitude, $latitude): Point + public static function point2dWGS84(NumeralType|int|float $longitude, NumeralType|int|float $latitude): Point { return Procedure::point([ "longitude" => $longitude, @@ -828,7 +836,7 @@ public static function point2dWGS84($longitude, $latitude): Point * * @see https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-wgs84-2d Corresponding documentation on Neo4j.com */ - public static function point3dWGS84($longitude, $latitude, $height): Point + public static function point3dWGS84(NumeralType|int|float $longitude, NumeralType|int|float $latitude, NumeralType|int|float $height): Point { return Procedure::point([ "longitude" => $longitude, @@ -848,9 +856,9 @@ private function __construct() /** * Prepares the variables to be used by temporal (i.e. time-like) CYPHER-functions. * - * @param mixed[] $variables + * @param array $variables * - * @return mixed[] + * @return array */ private static function makeTemporalMap(array $variables): array { diff --git a/src/Expressions/Literals/Map.php b/src/Expressions/Literals/Map.php index 4966ce94..e01710e1 100644 --- a/src/Expressions/Literals/Map.php +++ b/src/Expressions/Literals/Map.php @@ -9,14 +9,14 @@ */ namespace WikibaseSolutions\CypherDSL\Expressions\Literals; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; -use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\MapTypeTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; /** - * This class represents a CYPHER map. For example, this class can represent the following + * This class represents a Cypher map. For example, this class can represent the following * construct:. * * {name: 'Andy', sport: 'Brazilian Ju-Jitsu'} @@ -26,8 +26,6 @@ */ final class Map implements MapType { - use CastTrait; - use EscapeTrait; use MapTypeTrait; /** @@ -36,13 +34,13 @@ final class Map implements MapType private array $elements; /** - * @param mixed[] $elements Associative array of the elements that this map should have + * @param array $elements Associative array of the elements that this map should have * * @internal This method is not covered by the backwards compatibility promise of php-cypher-dsl */ public function __construct(array $elements = []) { - $this->elements = array_map([self::class, 'toAnyType'], $elements); + $this->elements = array_map(CastUtils::toAnyType(...), $elements); } /** @@ -53,9 +51,9 @@ public function __construct(array $elements = []) * * @return $this */ - public function add(string $key, $value): self + public function add(string $key, mixed $value): self { - $this->elements[$key] = self::toAnyType($value); + $this->elements[$key] = CastUtils::toAnyType($value); return $this; } @@ -100,7 +98,7 @@ public function toQuery(): string $pairs = []; foreach ($this->elements as $key => $value) { - $pairs[] = sprintf("%s: %s", self::escape((string) $key), $value->toQuery()); + $pairs[] = sprintf("%s: %s", NameUtils::escape((string) $key), $value->toQuery()); } return sprintf("{%s}", implode(", ", $pairs)); diff --git a/src/Expressions/Parameter.php b/src/Expressions/Parameter.php index cbeb4bf9..d8993dbc 100644 --- a/src/Expressions/Parameter.php +++ b/src/Expressions/Parameter.php @@ -9,7 +9,6 @@ */ namespace WikibaseSolutions\CypherDSL\Expressions; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\NameGenerationTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; @@ -69,9 +68,9 @@ final class Parameter implements StringTypeTrait, TimeTypeTrait; - use ErrorTrait; use EscapeTrait; use NameGenerationTrait; + private string $parameter; /** diff --git a/src/Expressions/Procedures/IsEmpty.php b/src/Expressions/Procedures/IsEmpty.php index 264492a3..7cf7505f 100644 --- a/src/Expressions/Procedures/IsEmpty.php +++ b/src/Expressions/Procedures/IsEmpty.php @@ -9,9 +9,7 @@ */ namespace WikibaseSolutions\CypherDSL\Expressions\Procedures; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; -use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; @@ -26,12 +24,11 @@ final class IsEmpty extends Procedure implements BooleanType { use BooleanTypeTrait; - use ErrorTrait; /** * @var ListType|MapType|StringType An expression that returns a list */ - private AnyType $list; + private ListType|MapType|StringType $list; /** * The signatures of the "isEmpty()" function are: @@ -43,10 +40,8 @@ final class IsEmpty extends Procedure implements BooleanType * * @internal This method is not covered by the backwards compatibility promise of php-cypher-dsl */ - public function __construct(AnyType $list) + public function __construct(ListType|MapType|StringType $list) { - self::assertClass('list', [ListType::class, MapType::class, StringType::class], $list); - $this->list = $list; } diff --git a/src/Expressions/Procedures/Procedure.php b/src/Expressions/Procedures/Procedure.php index c858e20e..2f374ffa 100644 --- a/src/Expressions/Procedures/Procedure.php +++ b/src/Expressions/Procedures/Procedure.php @@ -14,9 +14,7 @@ use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\QueryConvertible; use WikibaseSolutions\CypherDSL\Traits\CastTrait; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; -use WikibaseSolutions\CypherDSL\Types\CompositeTypes\CompositeType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\StringType; @@ -29,38 +27,27 @@ abstract class Procedure implements QueryConvertible { use CastTrait; - use ErrorTrait; /** * Produces a raw function call. This enables the usage of unimplemented functions in your * Cypher queries. The parameters of this function are not type-checked. * * @param string $functionName The name of the function to call - * @param AnyType|AnyType[]|bool|bool[]|float|float[]|int|int[]|mixed[][]|Pattern|Pattern[]|string|string[]|(AnyType|bool|float|int|mixed[]|Pattern|string)[] $parameters The parameters to pass to the function call + * @param mixed ...$parameters The parameters to pass to the function call */ - public static function raw(string $functionName, $parameters = []): Raw + public static function raw(string $functionName, mixed ...$parameters): Raw { - if (!is_array($parameters)) { - $parameters = [$parameters]; - } - - $res = []; - - foreach ($parameters as $parameter) { - $res[] = self::toAnyType($parameter); - } - - return new Raw($functionName, $res); + return new Raw($functionName, ...array_map(self::toAnyType(...), $parameters)); } /** * Calls the "all()" function. The signature of the "all()" function is "all(variable :: VARIABLE IN list :: LIST OF ANY? WHERE predicate :: ANY?) :: (BOOLEAN?)". * - * @param string|Variable $variable A variable that can be used from within the predicate - * @param ListType|mixed[] $list A list - * @param AnyType|bool|float|int|mixed[]|Pattern|string $predicate A predicate that is tested against all items in the list + * @param string|Variable $variable A variable that can be used from within the predicate + * @param ListType|array $list A list + * @param AnyType|bool|float|int|array|Pattern|string $predicate A predicate that is tested against all items in the list */ - public static function all($variable, $list, $predicate): All + public static function all(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): All { return new All(self::toName($variable), self::toListType($list), self::toAnyType($predicate)); } @@ -68,11 +55,11 @@ public static function all($variable, $list, $predicate): All /** * Calls the "any()" function. The signature of the "any()" function is "any(variable :: VARIABLE IN list :: LIST OF ANY? WHERE predicate :: ANY?) :: (BOOLEAN?)". * - * @param string|Variable $variable A variable that can be used from within the predicate - * @param ListType|mixed[] $list A list - * @param AnyType|bool|float|int|mixed[]|Pattern|string $predicate A predicate that is tested against all items in the list + * @param string|Variable $variable A variable that can be used from within the predicate + * @param ListType|array $list A list + * @param AnyType|bool|float|int|array|Pattern|string $predicate A predicate that is tested against all items in the list */ - public static function any($variable, $list, $predicate): Any + public static function any(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): Any { return new Any(self::toName($variable), self::toListType($list), self::toAnyType($predicate)); } @@ -80,9 +67,9 @@ public static function any($variable, $list, $predicate): Any /** * Calls the "exists()" function. The signature of the "exists()" function is "exists(input :: ANY?) :: (BOOLEAN?)". * - * @param AnyType|bool|float|int|mixed[]|Pattern|string $expression A pattern or property + * @param AnyType|bool|float|int|array|Pattern|string $expression A pattern or property */ - public static function exists($expression): Exists + public static function exists(AnyType|bool|float|int|array|Pattern|string $expression): Exists { return new Exists(self::toAnyType($expression)); } @@ -93,12 +80,12 @@ public static function exists($expression): Exists * - isEmpty(input :: MAP?) :: (BOOLEAN?) - to check whether a map is empty * - isEmpty(input :: STRING?) :: (BOOLEAN?) - to check whether a string is empty. * - * @param ListType|MapType|StringType $list An expression that returns a list + * @param ListType|MapType|StringType|string|array $list An expression that returns a list + * + * @return IsEmpty */ - public static function isEmpty($list): IsEmpty + public static function isEmpty(ListType|MapType|StringType|string|array $list): IsEmpty { - self::assertClass('list', [CompositeType::class, StringType::class, 'string', 'array'], $list); - if (!$list instanceof AnyType) { $list = Literal::literal($list); } @@ -110,11 +97,11 @@ public static function isEmpty($list): IsEmpty /** * Calls the "none()" function. The signature of the "none()" function is "none(variable :: VARIABLE IN list :: LIST OF ANY? WHERE predicate :: ANY?) :: (BOOLEAN?)". * - * @param string|Variable $variable A variable that can be used from within the predicate - * @param ListType|mixed[] $list A list - * @param AnyType|bool|float|int|mixed[]|Pattern|string $predicate A predicate that is tested against all items in the list + * @param string|Variable $variable A variable that can be used from within the predicate + * @param ListType|array $list A list + * @param AnyType|bool|float|int|array|Pattern|string $predicate A predicate that is tested against all items in the list */ - public static function none($variable, $list, $predicate): None + public static function none(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): None { return new None(self::toName($variable), self::toListType($list), self::toAnyType($predicate)); } @@ -122,11 +109,11 @@ public static function none($variable, $list, $predicate): None /** * Calls the "single()" function. The signature of the "single()" function is "single(variable :: VARIABLE IN list :: LIST OF ANY? WHERE predicate :: ANY?) :: (BOOLEAN?)". * - * @param string|Variable $variable A variable that can be used from within the predicate - * @param ListType|mixed[] $list A list - * @param AnyType|bool|float|int|mixed[]|Pattern|string $predicate A predicate that is tested against all items in the list + * @param string|Variable $variable A variable that can be used from within the predicate + * @param ListType|array $list A list + * @param AnyType|bool|float|int|array|Pattern|string $predicate A predicate that is tested against all items in the list */ - public static function single($variable, $list, $predicate): Single + public static function single(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): Single { return new Single(self::toName($variable), self::toListType($list), self::toAnyType($predicate)); } @@ -134,14 +121,14 @@ public static function single($variable, $list, $predicate): Single /** * Calls the "point()" function. The signature of the "point()" function is "point(input :: MAP?) :: (POINT?)". * - * @param MapType|mixed[] $map The map to use for constructing the point + * @param MapType|array $map The map to use for constructing the point * * @see Literal::point2d() * @see Literal::point2dWGS84() * @see Literal::point3d() * @see Literal::point3dWGS84() */ - public static function point($map): Point + public static function point(MapType|array $map): Point { return new Point(self::toMapType($map)); } @@ -149,22 +136,22 @@ public static function point($map): Point /** * Calls the "date()" function. The signature of the "date()" function is "date(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (DATE?)". * - * @param null|AnyType|bool|float|int|mixed[]|Pattern|string $value The input to the date function, from which to construct the date + * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the date function, from which to construct the date * * @see Literal::date() * @see Literal::dateString() * @see Literal::dateYWD() * @see Literal::dateYMD() */ - public static function date($value = null): Date + public static function date(AnyType|bool|float|int|array|Pattern|string|null $value = null): Date { - return new Date($value === null ? $value : self::toAnyType($value)); + return new Date($value === null ? null : self::toAnyType($value)); } /** * Calls the "datetime()" function. The signature of the "datetime()" function is "datetime(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (DATETIME?)". * - * @param null|AnyType|bool|float|int|mixed[]|Pattern|string $value The input to the datetime function, from which to construct the datetime + * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the datetime function, from which to construct the datetime * * @see Literal::dateTime() * @see Literal::dateTimeString() @@ -173,15 +160,15 @@ public static function date($value = null): Date * @see Literal::dateTimeYMD() * @see Literal::dateTimeYQD() */ - public static function datetime($value = null): DateTime + public static function datetime(AnyType|bool|float|int|array|Pattern|string|null $value = null): DateTime { - return new DateTime($value === null ? $value : self::toAnyType($value)); + return new DateTime($value === null ? null : self::toAnyType($value)); } /** * Calls the "localdatetime()" function. The signature of the "localdatetime()" function is "datetime(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (LOCALDATETIME?)". * - * @param null|AnyType|bool|float|int|mixed[]|Pattern|string $value The input to the localdatetime function, from which to construct the localdatetime + * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the localdatetime function, from which to construct the localdatetime * * @see Literal::localDateTime() * @see Literal::localDateTimeString() @@ -190,37 +177,37 @@ public static function datetime($value = null): DateTime * @see Literal::localDateTimeYMD() * @see Literal::localDateTimeYQD() */ - public static function localdatetime($value = null): LocalDateTime + public static function localdatetime(AnyType|bool|float|int|array|Pattern|string|null $value = null): LocalDateTime { - return new LocalDateTime($value === null ? $value : self::toAnyType($value)); + return new LocalDateTime($value === null ? null : self::toAnyType($value)); } /** * Calls the "localtime()" function. The signature of the "localtime()" function is "localtime(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (LOCALTIME?)". * - * @param null|AnyType|bool|float|int|mixed[]|Pattern|string $value The input to the localtime function, from which to construct the localtime + * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the localtime function, from which to construct the localtime * * @see Literal::localTime() * @see Literal::localTimeCurrent() * @see Literal::localTimeString() */ - public static function localtime($value = null): LocalTime + public static function localtime(AnyType|bool|float|int|array|Pattern|string|null $value = null): LocalTime { - return new LocalTime($value === null ? $value : self::toAnyType($value)); + return new LocalTime($value === null ? null : self::toAnyType($value)); } /** * Calls the "time()" function. The signature of the "time()" function is "time(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (TIME?)". * - * @param null|AnyType|bool|float|int|mixed[]|Pattern|string $value The input to the localtime function, from which to construct the time + * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the localtime function, from which to construct the time * * @see Literal::time() * @see Literal::timeHMS() * @see Literal::timeString() */ - public static function time($value = null): Time + public static function time(AnyType|bool|float|int|array|Pattern|string|null $value = null): Time { - return new Time($value === null ? $value : self::toAnyType($value)); + return new Time($value === null ? null : self::toAnyType($value)); } /** diff --git a/src/Expressions/Procedures/Raw.php b/src/Expressions/Procedures/Raw.php index a04744c4..b8a8f1cf 100644 --- a/src/Expressions/Procedures/Raw.php +++ b/src/Expressions/Procedures/Raw.php @@ -9,7 +9,6 @@ */ namespace WikibaseSolutions\CypherDSL\Expressions\Procedures; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\MapTypeTrait; @@ -71,7 +70,6 @@ final class Raw extends Procedure implements StringTypeTrait, TimeTypeTrait; - use ErrorTrait; use EscapeTrait; /** @@ -85,15 +83,13 @@ final class Raw extends Procedure implements private array $parameters; /** - * @param string $functionName The name of the function to call - * @param AnyType[] $parameters The parameters to pass to the function call + * @param string $functionName The name of the function to call + * @param AnyType ...$parameters The parameters to pass to the function call * * @internal This method is not covered by the backwards compatibility guarantee of php-cypher-dsl */ - public function __construct(string $functionName, array $parameters) + public function __construct(string $functionName, AnyType ...$parameters) { - self::assertClassArray('parameters', AnyType::class, $parameters); - $this->functionName = self::escape($functionName); $this->parameters = $parameters; } @@ -103,7 +99,7 @@ public function __construct(string $functionName, array $parameters) */ protected function getSignature(): string { - // A string of the form '%s, %s, %s' with count($this->parameters) occurences of '%s' + // A string of the form '%s, %s, %s' with count($this->parameters) occurrences of '%s' $percentSString = count($this->parameters) === 0 ? '' : diff --git a/src/Expressions/Property.php b/src/Expressions/Property.php index 32c50735..68ddefc9 100644 --- a/src/Expressions/Property.php +++ b/src/Expressions/Property.php @@ -92,10 +92,8 @@ final class Property implements * * @internal This function is not covered by the backwards compatibility guarantee of php-cypher-dsl */ - public function __construct($expression, string $property) + public function __construct(MapType|NodeType|RelationshipType $expression, string $property) { - self::assertClass('expression', [MapType::class, NodeType::class, RelationshipType::class], $expression); - $this->expression = $expression; $this->property = $property; } @@ -113,7 +111,7 @@ public function __construct($expression, string $property) * * TODO: Allow this function to take arrays of property types */ - public function replaceWith($value): PropertyReplacement + public function replaceWith(PropertyType|string|bool|float|int $value): PropertyReplacement { return new PropertyReplacement($this, self::toPropertyType($value)); } @@ -131,7 +129,7 @@ public function getProperty(): string * * @return MapType|NodeType|RelationshipType */ - public function getExpression(): AnyType + public function getExpression(): MapType|NodeType|RelationshipType { return $this->expression; } diff --git a/src/Expressions/Variable.php b/src/Expressions/Variable.php index 28bc200f..70dace54 100644 --- a/src/Expressions/Variable.php +++ b/src/Expressions/Variable.php @@ -11,7 +11,6 @@ use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; use WikibaseSolutions\CypherDSL\Syntax\PropertyReplacement; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\NameGenerationTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; @@ -85,7 +84,6 @@ final class Variable implements StringTypeTrait, TimeTypeTrait; - use ErrorTrait; use EscapeTrait; use NameGenerationTrait; @@ -121,7 +119,7 @@ public function labeled(string ...$labels): Label /** * Assign a value to this property. * - * @param Map|mixed[] $value The value to assign + * @param Map|array $value The value to assign */ public function assign($value): PropertyReplacement { diff --git a/src/Patterns/CompletePattern.php b/src/Patterns/CompletePattern.php index 5a968d7b..f8930ea6 100644 --- a/src/Patterns/CompletePattern.php +++ b/src/Patterns/CompletePattern.php @@ -11,7 +11,7 @@ /** * Interface to mark patterns that are complete, i.e. can be matched by a MATCH clause or created by - * a CREATE clause. These are:. + * a CREATE clause. These are: * * - node * - path diff --git a/src/Patterns/Node.php b/src/Patterns/Node.php index 6ab73df5..d11a361c 100644 --- a/src/Patterns/Node.php +++ b/src/Patterns/Node.php @@ -11,7 +11,6 @@ use WikibaseSolutions\CypherDSL\Expressions\Label; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\PatternTraits\PropertyPatternTrait; @@ -22,7 +21,6 @@ */ final class Node implements CompletePattern, PropertyPattern, RelatablePattern { - use ErrorTrait; use EscapeTrait; use PropertyPatternTrait; diff --git a/src/Patterns/Path.php b/src/Patterns/Path.php index ca838e30..935de073 100644 --- a/src/Patterns/Path.php +++ b/src/Patterns/Path.php @@ -10,7 +10,6 @@ namespace WikibaseSolutions\CypherDSL\Patterns; use WikibaseSolutions\CypherDSL\Expressions\Variable; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Traits\PatternTraits\PatternTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; @@ -24,7 +23,6 @@ final class Path implements BooleanType, CompletePattern, RelatablePattern { use BooleanTypeTrait; - use ErrorTrait; use PatternTrait; @@ -44,14 +42,11 @@ final class Path implements BooleanType, CompletePattern, RelatablePattern * * @internal This method is not covered by the backwards compatibility guarantee of php-cypher-dsl */ - public function __construct($nodes = [], $relationships = []) + public function __construct(Node|array $nodes = [], Relationship|array $relationships = []) { $nodes = is_array($nodes) ? $nodes : [$nodes]; $relationships = is_array($relationships) ? $relationships : [$relationships]; - self::assertClassArray('nodes', Node::class, $nodes); - self::assertClassArray('relationships', Relationship::class, $relationships); - $this->nodes = $nodes; $this->relationships = $relationships; } @@ -181,10 +176,10 @@ public function toQuery(): string * * @param string[] $direction The direction of the relationship (should be a Relationship::DIR_* constant) * @param null|string $type The type of the relationship - * @param null|MapType|mixed[] $properties The properties to add to the relationship + * @param null|MapType|array $properties The properties to add to the relationship * @param null|string|Variable $name The name of the variable to which to assign this relationship */ - private static function buildRelationship(array $direction, ?string $type = null, $properties = null, $name = null): Relationship + private static function buildRelationship(array $direction, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Relationship { $relationship = new Relationship($direction); diff --git a/src/Patterns/PropertyPattern.php b/src/Patterns/PropertyPattern.php index 59e1e278..f545867d 100644 --- a/src/Patterns/PropertyPattern.php +++ b/src/Patterns/PropertyPattern.php @@ -32,11 +32,11 @@ public function property(string $property): Property; /** * Set the properties of this pattern. * - * @param MapType|mixed[] $properties + * @param MapType|array $properties * * @return $this */ - public function withProperties($properties): self; + public function withProperties(MapType|array $properties): self; /** * Add a property to the properties in this pattern. This is only possible if the properties in this pattern are @@ -47,18 +47,18 @@ public function withProperties($properties): self; * * @return $this */ - public function addProperty(string $key, $property): self; + public function addProperty(string $key, mixed $property): self; /** * Add the given properties to this pattern. This is only possible if the properties in this pattern are a map. - * An exception will be thrown if they are anything else (such as a variable). If the pattern does not yet contain + * An exception will be thrown if they are anything else (such as a variable). If the pattern does not yet contain * any properties, a new map will be created. * - * @param Map|mixed[] $properties + * @param MapType|array $properties * * @return $this */ - public function addProperties($properties): self; + public function addProperties(MapType|array $properties): self; /** * Returns the properties of this object. diff --git a/src/Query.php b/src/Query.php index 6e43318b..b6014479 100644 --- a/src/Query.php +++ b/src/Query.php @@ -49,7 +49,6 @@ use WikibaseSolutions\CypherDSL\Syntax\Alias; use WikibaseSolutions\CypherDSL\Syntax\PropertyReplacement; use WikibaseSolutions\CypherDSL\Traits\CastTrait; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\IntegerType; @@ -61,7 +60,6 @@ final class Query implements QueryConvertible { use CastTrait; - use ErrorTrait; // A reference to the Literal class public const literal = Literal::class; @@ -363,16 +361,14 @@ public function __toString(): string * @note This feature is not part of the openCypher standard. * * @param callable|Query $query A callable decorating a Query, or an instance of Query - * @param Pattern|Pattern[]|string|string[]|Variable|Variable[]|(Pattern|string|Variable)[] $variables The variables to include in the WITH clause for correlation (optional) + * @param Pattern|string|Variable ...$variables The variables to include in the WITH clause for correlation (optional) * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/call-subquery/ Corresponding documentation on Neo4j.com */ - public function call($query, $variables = []): self + public function call(Query|callable $query, Pattern|Variable|string ...$variables): self { - $this->assertClass('query', [self::class, Closure::class, 'callable'], $query); - if (is_callable($query)) { $subQuery = self::new(); $query($subQuery); @@ -380,10 +376,6 @@ public function call($query, $variables = []): self $subQuery = $query; } - if (!is_array($variables)) { - $variables = [$variables]; - } - $callClause = new CallClause(); $callClause->withSubQuery($subQuery); $callClause->addWithVariable(...$variables); diff --git a/src/Syntax/PropertyReplacement.php b/src/Syntax/PropertyReplacement.php index 7d006a29..cc9014ff 100644 --- a/src/Syntax/PropertyReplacement.php +++ b/src/Syntax/PropertyReplacement.php @@ -12,7 +12,6 @@ use WikibaseSolutions\CypherDSL\Expressions\Property; use WikibaseSolutions\CypherDSL\Expressions\Variable; use WikibaseSolutions\CypherDSL\QueryConvertible; -use WikibaseSolutions\CypherDSL\Traits\ErrorTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; /** @@ -23,12 +22,10 @@ */ final class PropertyReplacement implements QueryConvertible { - use ErrorTrait; - /** * @var Property|Variable The name of the property to which we assign a (new) value */ - private $property; + private Property|Variable $property; /** * @var AnyType The value to assign to the property @@ -48,10 +45,8 @@ final class PropertyReplacement implements QueryConvertible * * @internal This method is not covered by the backwards compatibility guarantee of php-cypher-dsl */ - public function __construct($property, AnyType $value) + public function __construct(Property|Variable $property, AnyType $value) { - self::assertClass('property', [Variable::class, Property::class], $property); - $this->property = $property; $this->value = $value; } @@ -82,7 +77,7 @@ public function mutates(): bool * * @return Property|Variable */ - public function getProperty() + public function getProperty(): Property|Variable { return $this->property; } diff --git a/src/Traits/ErrorTrait.php b/src/Traits/ErrorTrait.php deleted file mode 100644 index d0a94648..00000000 --- a/src/Traits/ErrorTrait.php +++ /dev/null @@ -1,188 +0,0 @@ - 65534) { - // Remark: Some versions of Neo4j support names up to 65535 characters, but we just take the lower bound - throw new InvalidArgumentException("A name cannot be longer than 65534 (2^16 - 2) characters"); - } - - if (\preg_match('/^\p{L}[\p{L}\d_]*$/u', $name)) { - // The name is already valid and does not need to be escaped - return $name; - } - - // Escape backticks that are included in $name by doubling them. - $name = \str_replace('`', '``', $name); - - return \sprintf("`%s`", $name); - } -} diff --git a/src/Traits/NameGenerationTrait.php b/src/Traits/NameGenerationTrait.php deleted file mode 100644 index 5e1ca86f..00000000 --- a/src/Traits/NameGenerationTrait.php +++ /dev/null @@ -1,43 +0,0 @@ -makeMap(); if (is_array($properties)) { - $res = []; - - foreach ($properties as $key => $property) { - $res[$key] = self::toAnyType($property); - } + $res = array_map(function ($property) { + return self::toAnyType($property); + }, $properties); // Cast the array to a Map $properties = new Map($res); diff --git a/src/Traits/CastTrait.php b/src/Utils/CastUtils.php similarity index 50% rename from src/Traits/CastTrait.php rename to src/Utils/CastUtils.php index 6c664444..14299536 100644 --- a/src/Traits/CastTrait.php +++ b/src/Utils/CastUtils.php @@ -1,14 +1,8 @@ -getVariable(); } /** * Casts the given value to a Variable. * - * @param Pattern|string|Variable $variable - * * @see CastTrait::toName() for a function that does not accept Pattern */ - private static function toVariable($variable): Variable + public static function toVariable(Variable|Pattern|string $variable): Variable { - self::assertClass('variable', [Variable::class, Pattern::class, 'string'], $variable); - if ($variable instanceof Variable) { return $variable; } @@ -152,28 +107,20 @@ private static function toVariable($variable): Variable } /** - * Casts the given value to a name (as a variable). - * - * @param string|Variable $name + * Casts the given value to a name. * * @see CastTrait::toVariable() for a function that accepts Pattern */ - private static function toName($name): Variable + public static function toName(Variable|string $name): Variable { - self::assertClass('name', [Variable::class, 'string'], $name); - return $name instanceof Variable ? $name : new Variable($name); } /** * Casts the given value to an AnyType. - * - * @param AnyType|bool|float|int|mixed[]|Pattern|string $value */ - private static function toAnyType($value): AnyType + public static function toAnyType(AnyType|Pattern|Stringable|bool|float|int|array|string $value): AnyType { - self::assertClass('value', [AnyType::class, Pattern::class, 'int', 'float', 'string', 'bool', 'array'], $value); - if ($value instanceof Pattern) { return $value->getVariable(); } @@ -182,7 +129,6 @@ private static function toAnyType($value): AnyType return $value; } - // @phpstan-ignore-next-line return Literal::literal($value); } -} +} \ No newline at end of file diff --git a/src/Utils/NameUtils.php b/src/Utils/NameUtils.php new file mode 100644 index 00000000..792a49cf --- /dev/null +++ b/src/Utils/NameUtils.php @@ -0,0 +1,74 @@ + + */ + private static array $generatedIdentifiers = []; + + /** + * Generates a guaranteed unique random identifier. + * + * @note The returned string is not cryptographically secure. + * + * @param string $prefix The prefix to put before the name. Must start with a letter. + * @param int $length The length of the generated name in bytes. + */ + public static function generateIdentifier(string $prefix = 'var', int $length = 32): string + { + do { + $random = $prefix; + + for ($i = 0; $i < $length; ++$i) { + $random .= dechex(mt_rand(0, 15)); + } + } while (isset(self::$generatedIdentifiers[$random])); + + return $random; + } + + /** + * Escapes a name. + * + * A name in Cypher is any string that should be included directly in a Cypher query, + * such as variable names, labels, property names and relation types. + * + * @see https://neo4j.com/docs/cypher-manual/4.4/syntax/naming Corresponding documentation on Neo4j.com + */ + public static function escape(string $name): string + { + if ($name === "") { + // Although some versions of Neo4j do not crash when the empty string is used as a name, + // but there is no real reason to ever use the empty string as a name, so we disallow it. + throw new InvalidArgumentException("A name cannot be the empty string"); + } + + if (\strlen($name) > 65534) { + // Remark: Some versions of Neo4j support names up to 65535 characters, but we just take + // the lower bound. The user shouldn't be using names this long anyway. + throw new InvalidArgumentException("A name cannot be longer than 65534 (2^16 - 2) characters"); + } + + if (\preg_match('/^\p{L}[\p{L}\d_]*$/u', $name)) { + // The name is already valid and does not need to be escaped. + return $name; + } + + // Escape backticks that are included in the name by doubling them. + $name = \str_replace('`', '``', $name); + + return \sprintf("`%s`", $name); + } +} \ No newline at end of file diff --git a/tests/unit/Utils/CastUtilsTest.php b/tests/unit/Utils/CastUtilsTest.php new file mode 100644 index 00000000..3bed72d1 --- /dev/null +++ b/tests/unit/Utils/CastUtilsTest.php @@ -0,0 +1,8 @@ + Date: Tue, 3 Feb 2026 09:14:31 +0100 Subject: [PATCH 02/12] Actually store the identifier after it has been generated --- src/Utils/NameUtils.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Utils/NameUtils.php b/src/Utils/NameUtils.php index 792a49cf..afb5f540 100644 --- a/src/Utils/NameUtils.php +++ b/src/Utils/NameUtils.php @@ -36,6 +36,8 @@ public static function generateIdentifier(string $prefix = 'var', int $length = } } while (isset(self::$generatedIdentifiers[$random])); + self::$generatedIdentifiers[$random] = ''; + return $random; } From 9d531619ad67b19ad80a8bc1477e1e881b794580 Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Tue, 3 Feb 2026 13:33:05 +0100 Subject: [PATCH 03/12] Refactor more functions to use union types --- src/Expressions/Label.php | 7 ++-- src/Expressions/Parameter.php | 10 ++---- src/Expressions/Property.php | 11 +++--- src/Expressions/Variable.php | 15 ++++---- src/Patterns/Node.php | 6 ++-- src/Patterns/Path.php | 7 ++-- src/Patterns/PropertyPattern.php | 6 ---- src/Patterns/RelatablePattern.php | 12 +++---- src/Patterns/Relationship.php | 6 ++-- src/Traits/PatternTraits/PatternTrait.php | 12 ++----- .../PatternTraits/PropertyPatternTrait.php | 13 ++++--- src/Traits/TypeTraits/AnyTypeTrait.php | 35 ++++++++++--------- .../CompositeTypeTrait.php | 3 ++ .../CompositeTypeTraits/ListTypeTrait.php | 11 +++--- .../CompositeTypeTraits/MapTypeTrait.php | 3 ++ .../MethodTraits/PropertyMethodTrait.php | 3 ++ .../PropertyTypeTraits/BooleanTypeTrait.php | 18 +++++----- .../PropertyTypeTraits/DateTimeTypeTrait.php | 4 +++ .../PropertyTypeTraits/DateTypeTrait.php | 4 +++ .../PropertyTypeTraits/FloatTypeTrait.php | 4 +++ .../PropertyTypeTraits/IntegerTypeTrait.php | 4 +++ .../LocalDateTimeTypeTrait.php | 4 +++ .../PropertyTypeTraits/LocalTimeTypeTrait.php | 4 +++ .../PropertyTypeTraits/NumeralTypeTrait.php | 28 ++++++++------- .../PropertyTypeTraits/PointTypeTrait.php | 4 +++ .../PropertyTypeTraits/PropertyTypeTrait.php | 10 ++++-- .../PropertyTypeTraits/StringTypeTrait.php | 22 ++++++------ .../PropertyTypeTraits/TimeTypeTrait.php | 4 +++ .../StructuralTypeTraits/NodeTypeTrait.php | 3 ++ .../StructuralTypeTraits/PathTypeTrait.php | 4 +++ .../RelationshipTypeTrait.php | 3 ++ .../StructuralTypeTrait.php | 3 ++ src/Types/AnyType.php | 28 +++++---------- src/Types/CompositeTypes/CompositeType.php | 2 +- src/Types/CompositeTypes/ListType.php | 4 +-- src/Types/PropertyTypes/BooleanType.php | 12 ++----- src/Types/PropertyTypes/LocalDateTimeType.php | 4 ++- src/Types/PropertyTypes/NumeralType.php | 26 ++++---------- src/Types/PropertyTypes/PropertyType.php | 6 ++-- src/Types/PropertyTypes/StringType.php | 16 +++------ src/Types/StructuralTypes/StructuralType.php | 2 +- src/functions.php | 10 ++---- 42 files changed, 195 insertions(+), 198 deletions(-) diff --git a/src/Expressions/Label.php b/src/Expressions/Label.php index d3d11d92..66351c7e 100644 --- a/src/Expressions/Label.php +++ b/src/Expressions/Label.php @@ -12,6 +12,7 @@ use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; /** * Represents a label. A label in Cypher would be something like "n:German" or "n:German:Swedish". Label implements @@ -23,8 +24,6 @@ final class Label implements BooleanType { use BooleanTypeTrait; - use EscapeTrait; - /** * @var Variable The variable to which this label belongs */ @@ -44,7 +43,7 @@ final class Label implements BooleanType public function __construct(Variable $variable, string ...$labels) { $this->variable = $variable; - $this->labels = array_map([self::class, 'escape'], $labels); + $this->labels = array_map(NameUtils::escape(...), $labels); } /** @@ -56,7 +55,7 @@ public function __construct(Variable $variable, string ...$labels) */ public function addLabels(string ...$labels): self { - $this->labels = array_merge($this->labels, array_map([self::class, 'escape'], $labels)); + $this->labels = array_merge($this->labels, array_map(NameUtils::escape(...), $labels)); return $this; } diff --git a/src/Expressions/Parameter.php b/src/Expressions/Parameter.php index d8993dbc..54d4d09f 100644 --- a/src/Expressions/Parameter.php +++ b/src/Expressions/Parameter.php @@ -9,8 +9,6 @@ */ namespace WikibaseSolutions\CypherDSL\Expressions; -use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; -use WikibaseSolutions\CypherDSL\Traits\NameGenerationTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\MapTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; @@ -35,6 +33,7 @@ use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PointType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\StringType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\TimeType; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; /** * Represents a parameter. @@ -68,9 +67,6 @@ final class Parameter implements StringTypeTrait, TimeTypeTrait; - use EscapeTrait; - use NameGenerationTrait; - private string $parameter; /** @@ -82,10 +78,10 @@ final class Parameter implements public function __construct(?string $parameter = null) { if (!isset($parameter)) { - $parameter = self::generateIdentifier('param'); + $parameter = NameUtils::generateIdentifier('param'); } - $this->parameter = self::escape($parameter); + $this->parameter = NameUtils::escape($parameter); } /** diff --git a/src/Expressions/Property.php b/src/Expressions/Property.php index 68ddefc9..984438b7 100644 --- a/src/Expressions/Property.php +++ b/src/Expressions/Property.php @@ -40,6 +40,8 @@ use WikibaseSolutions\CypherDSL\Types\PropertyTypes\TimeType; use WikibaseSolutions\CypherDSL\Types\StructuralTypes\NodeType; use WikibaseSolutions\CypherDSL\Types\StructuralTypes\RelationshipType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; /** * Represents a property. A property in Cypher would be something like "n.prop" or "n.a". @@ -61,7 +63,6 @@ final class Property implements use BooleanTypeTrait, DateTimeTypeTrait, DateTypeTrait, - EscapeTrait, FloatTypeTrait, IntegerTypeTrait, ListTypeTrait, @@ -72,12 +73,10 @@ final class Property implements StringTypeTrait, TimeTypeTrait; - use CastTrait; - /** * @var MapType|NodeType|RelationshipType The expression to which this property belongs */ - private AnyType $expression; + private MapType|NodeType|RelationshipType $expression; /** * @var string The name of the property @@ -113,7 +112,7 @@ public function __construct(MapType|NodeType|RelationshipType $expression, strin */ public function replaceWith(PropertyType|string|bool|float|int $value): PropertyReplacement { - return new PropertyReplacement($this, self::toPropertyType($value)); + return new PropertyReplacement($this, CastUtils::toPropertyType($value)); } /** @@ -139,6 +138,6 @@ public function getExpression(): MapType|NodeType|RelationshipType */ public function toQuery(): string { - return sprintf("%s.%s", $this->expression->toQuery(), self::escape($this->property)); + return sprintf("%s.%s", $this->expression->toQuery(), NameUtils::escape($this->property)); } } diff --git a/src/Expressions/Variable.php b/src/Expressions/Variable.php index 70dace54..179330d5 100644 --- a/src/Expressions/Variable.php +++ b/src/Expressions/Variable.php @@ -11,8 +11,6 @@ use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; use WikibaseSolutions\CypherDSL\Syntax\PropertyReplacement; -use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; -use WikibaseSolutions\CypherDSL\Traits\NameGenerationTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\MapTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; @@ -44,6 +42,8 @@ use WikibaseSolutions\CypherDSL\Types\StructuralTypes\NodeType; use WikibaseSolutions\CypherDSL\Types\StructuralTypes\PathType; use WikibaseSolutions\CypherDSL\Types\StructuralTypes\RelationshipType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; /** * Represents a variable. @@ -84,9 +84,6 @@ final class Variable implements StringTypeTrait, TimeTypeTrait; - use EscapeTrait; - use NameGenerationTrait; - /** * @var string The name of this variable */ @@ -100,10 +97,10 @@ final class Variable implements public function __construct(?string $name = null) { if ($name === null) { - $name = self::generateIdentifier(); + $name = NameUtils::generateIdentifier(); } - $this->name = self::escape($name); + $this->name = NameUtils::escape($name); } /** @@ -121,9 +118,9 @@ public function labeled(string ...$labels): Label * * @param Map|array $value The value to assign */ - public function assign($value): PropertyReplacement + public function assign(MapType|array $value): PropertyReplacement { - return new PropertyReplacement($this, self::toMapType($value)); + return new PropertyReplacement($this, CastUtils::toMapType($value)); } /** diff --git a/src/Patterns/Node.php b/src/Patterns/Node.php index d11a361c..8c29e8b0 100644 --- a/src/Patterns/Node.php +++ b/src/Patterns/Node.php @@ -11,8 +11,8 @@ use WikibaseSolutions\CypherDSL\Expressions\Label; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; -use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\PatternTraits\PropertyPatternTrait; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; /** * This class represents a node. @@ -21,8 +21,6 @@ */ final class Node implements CompletePattern, PropertyPattern, RelatablePattern { - use EscapeTrait; - use PropertyPatternTrait; /** @@ -144,7 +142,7 @@ private function nodeInnerToString(): string if ($this->labels !== []) { foreach ($this->labels as $label) { - $nodeInner .= ":" . self::escape($label); + $nodeInner .= ":" . NameUtils::escape($label); } } diff --git a/src/Patterns/Path.php b/src/Patterns/Path.php index 935de073..01f8bd0f 100644 --- a/src/Patterns/Path.php +++ b/src/Patterns/Path.php @@ -23,7 +23,6 @@ final class Path implements BooleanType, CompletePattern, RelatablePattern { use BooleanTypeTrait; - use PatternTrait; /** @@ -95,7 +94,7 @@ public function relationship(Relationship $relationship, Pattern $pattern): self /** * @inheritDoc */ - public function relationshipTo(Pattern $pattern, ?string $type = null, $properties = null, $name = null): self + public function relationshipTo(Pattern $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): self { return $this->relationship( self::buildRelationship(Relationship::DIR_RIGHT, $type, $properties, $name), @@ -106,7 +105,7 @@ public function relationshipTo(Pattern $pattern, ?string $type = null, $properti /** * @inheritDoc */ - public function relationshipFrom(Pattern $pattern, ?string $type = null, $properties = null, $name = null): self + public function relationshipFrom(Pattern $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): self { return $this->relationship( self::buildRelationship(Relationship::DIR_LEFT, $type, $properties, $name), @@ -117,7 +116,7 @@ public function relationshipFrom(Pattern $pattern, ?string $type = null, $proper /** * @inheritDoc */ - public function relationshipUni(Pattern $pattern, ?string $type = null, $properties = null, $name = null): self + public function relationshipUni(Pattern $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): self { return $this->relationship( self::buildRelationship(Relationship::DIR_UNI, $type, $properties, $name), diff --git a/src/Patterns/PropertyPattern.php b/src/Patterns/PropertyPattern.php index f545867d..a01c4833 100644 --- a/src/Patterns/PropertyPattern.php +++ b/src/Patterns/PropertyPattern.php @@ -32,8 +32,6 @@ public function property(string $property): Property; /** * Set the properties of this pattern. * - * @param MapType|array $properties - * * @return $this */ public function withProperties(MapType|array $properties): self; @@ -43,8 +41,6 @@ public function withProperties(MapType|array $properties): self; * a map. An exception will be thrown if they are anything else (such as a variable). If the pattern does not yet * contain any properties, a new map will be created. * - * @param mixed $property - * * @return $this */ public function addProperty(string $key, mixed $property): self; @@ -54,8 +50,6 @@ public function addProperty(string $key, mixed $property): self; * An exception will be thrown if they are anything else (such as a variable). If the pattern does not yet contain * any properties, a new map will be created. * - * @param MapType|array $properties - * * @return $this */ public function addProperties(MapType|array $properties): self; diff --git a/src/Patterns/RelatablePattern.php b/src/Patterns/RelatablePattern.php index 3247319d..df85fc82 100644 --- a/src/Patterns/RelatablePattern.php +++ b/src/Patterns/RelatablePattern.php @@ -35,10 +35,10 @@ public function relationship(Relationship $relationship, self $pattern): Path; * * @param RelatablePattern $pattern The pattern to attach to the end of this pattern * @param null|string $type The type of the relationship - * @param null|MapType|mixed[] $properties The properties to attach to the relationship + * @param null|MapType|array $properties The properties to attach to the relationship * @param null|string|Variable $name The name fo the relationship */ - public function relationshipTo(self $pattern, ?string $type = null, $properties = null, $name = null): Path; + public function relationshipTo(self $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Path; /** * Forms a new path by adding the given relatable pattern to the end of this pattern using a left (<--) @@ -46,10 +46,10 @@ public function relationshipTo(self $pattern, ?string $type = null, $properties * * @param RelatablePattern $pattern The pattern to attach to the end of this pattern * @param null|string $type The type of the relationship - * @param null|MapType|mixed[] $properties The properties to attach to the relationship + * @param null|MapType|array $properties The properties to attach to the relationship * @param null|string|Variable $name The name fo the relationship */ - public function relationshipFrom(self $pattern, ?string $type = null, $properties = null, $name = null): Path; + public function relationshipFrom(self $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Path; /** * Forms a new path by adding the given relatable pattern to the end of this pattern using a unidirectional @@ -57,8 +57,8 @@ public function relationshipFrom(self $pattern, ?string $type = null, $propertie * * @param RelatablePattern $pattern The pattern to attach to the end of this pattern * @param null|string $type The type of the relationship - * @param null|MapType|mixed[] $properties The properties to attach to the relationship + * @param null|MapType|array $properties The properties to attach to the relationship * @param null|string|Variable $name The name fo the relationship */ - public function relationshipUni(self $pattern, ?string $type = null, $properties = null, $name = null): Path; + public function relationshipUni(self $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Path; } diff --git a/src/Patterns/Relationship.php b/src/Patterns/Relationship.php index 2d0ee726..b6f3f658 100644 --- a/src/Patterns/Relationship.php +++ b/src/Patterns/Relationship.php @@ -13,8 +13,8 @@ use InvalidArgumentException; use LogicException; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; -use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\PatternTraits\PropertyPatternTrait; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; /** * This class represents an arbitrary relationship. @@ -23,8 +23,6 @@ */ final class Relationship implements PropertyPattern { - use EscapeTrait; - use PropertyPatternTrait; public const DIR_RIGHT = ["-", "->"]; @@ -266,7 +264,7 @@ private function relationshipDetailToString(): string if (count($types) !== 0) { // If we have at least one condition type, escape them and insert them into the query - $escapedTypes = array_map(static fn (string $type): string => self::escape($type), $types); + $escapedTypes = array_map(static fn (string $type): string => NameUtils::escape($type), $types); $conditionInner .= sprintf(":%s", implode("|", $escapedTypes)); } diff --git a/src/Traits/PatternTraits/PatternTrait.php b/src/Traits/PatternTraits/PatternTrait.php index 6fd8514b..bc40b8b6 100644 --- a/src/Traits/PatternTraits/PatternTrait.php +++ b/src/Traits/PatternTraits/PatternTrait.php @@ -10,15 +10,13 @@ namespace WikibaseSolutions\CypherDSL\Traits\PatternTraits; use WikibaseSolutions\CypherDSL\Expressions\Variable; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "Pattern" interface. */ trait PatternTrait { - use CastTrait; - /** * @var null|Variable The variable that this object is assigned */ @@ -34,14 +32,10 @@ public function hasVariableSet(): bool /** * Explicitly assign a named variable to this object. - * - * @param null|string|Variable $variable - * - * @return $this */ - public function withVariable($variable): self + public function withVariable(Variable|string|null $variable): self { - $this->variable = $variable === null ? null : self::toName($variable); + $this->variable = $variable === null ? null : CastUtils::toName($variable); return $this; } diff --git a/src/Traits/PatternTraits/PropertyPatternTrait.php b/src/Traits/PatternTraits/PropertyPatternTrait.php index 081c69a5..1c51f477 100644 --- a/src/Traits/PatternTraits/PropertyPatternTrait.php +++ b/src/Traits/PatternTraits/PropertyPatternTrait.php @@ -12,15 +12,14 @@ use TypeError; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; use WikibaseSolutions\CypherDSL\Expressions\Property; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "PropertyPattern" interface. */ trait PropertyPatternTrait { - use CastTrait; use PatternTrait; /** @@ -39,9 +38,9 @@ public function property(string $property): Property /** * @inheritDoc */ - public function withProperties($properties): self + public function withProperties(MapType|array $properties): self { - $this->properties = self::toMapType($properties); + $this->properties = CastUtils::toMapType($properties); return $this; } @@ -49,7 +48,7 @@ public function withProperties($properties): self /** * @inheritDoc */ - public function addProperty(string $key, $property): self + public function addProperty(string $key, mixed $property): self { $this->makeMap()->add($key, $property); @@ -59,13 +58,13 @@ public function addProperty(string $key, $property): self /** * @inheritDoc */ - public function addProperties(Map|array $properties): self + public function addProperties(MapType|array $properties): self { $map = $this->makeMap(); if (is_array($properties)) { $res = array_map(function ($property) { - return self::toAnyType($property); + return CastUtils::toAnyType($property); }, $properties); // Cast the array to a Map diff --git a/src/Traits/TypeTraits/AnyTypeTrait.php b/src/Traits/TypeTraits/AnyTypeTrait.php index 94dc7946..62813a3a 100644 --- a/src/Traits/TypeTraits/AnyTypeTrait.php +++ b/src/Traits/TypeTraits/AnyTypeTrait.php @@ -17,70 +17,71 @@ use WikibaseSolutions\CypherDSL\Expressions\Operators\IsNull; use WikibaseSolutions\CypherDSL\Expressions\Operators\LessThan; use WikibaseSolutions\CypherDSL\Expressions\Operators\LessThanOrEqual; +use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\Syntax\Alias; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; +use WikibaseSolutions\CypherDSL\Types\AnyType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "AnyType" interface. */ trait AnyTypeTrait { - use CastTrait; - /** * @inheritDoc */ - public function alias($right): Alias + public function alias(Variable|string $right): Alias { - return new Alias($this, self::toName($right)); + return new Alias($this, CastUtils::toName($right)); } /** * @inheritDoc */ - public function equals($right, bool $insertParentheses = true): Equality + public function equals(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): Equality { - return new Equality($this, self::toAnyType($right), $insertParentheses); + return new Equality($this, CastUtils::toAnyType($right), $insertParentheses); } /** * @inheritDoc */ - public function notEquals($right, bool $insertParentheses = true): Inequality + public function notEquals(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): Inequality { - return new Inequality($this, self::toAnyType($right), $insertParentheses); + return new Inequality($this, CastUtils::toAnyType($right), $insertParentheses); } /** * @inheritDoc */ - public function gt($right, bool $insertParentheses = true): GreaterThan + public function gt(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): GreaterThan { - return new GreaterThan($this, self::toAnyType($right), $insertParentheses); + return new GreaterThan($this, CastUtils::toAnyType($right), $insertParentheses); } /** * @inheritDoc */ - public function gte($right, bool $insertParentheses = true): GreaterThanOrEqual + public function gte(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): GreaterThanOrEqual { - return new GreaterThanOrEqual($this, self::toAnyType($right), $insertParentheses); + return new GreaterThanOrEqual($this, CastUtils::toAnyType($right), $insertParentheses); } /** * @inheritDoc */ - public function lt($right, bool $insertParentheses = true): LessThan + public function lt(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): LessThan { - return new LessThan($this, self::toAnyType($right), $insertParentheses); + return new LessThan($this, CastUtils::toAnyType($right), $insertParentheses); } /** * @inheritDoc */ - public function lte($right, bool $insertParentheses = true): LessThanOrEqual + public function lte(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): LessThanOrEqual { - return new LessThanOrEqual($this, self::toAnyType($right), $insertParentheses); + return new LessThanOrEqual($this, CastUtils::toAnyType($right), $insertParentheses); } /** diff --git a/src/Traits/TypeTraits/CompositeTypeTraits/CompositeTypeTrait.php b/src/Traits/TypeTraits/CompositeTypeTraits/CompositeTypeTrait.php index 70c30255..f1fdc078 100644 --- a/src/Traits/TypeTraits/CompositeTypeTraits/CompositeTypeTrait.php +++ b/src/Traits/TypeTraits/CompositeTypeTraits/CompositeTypeTrait.php @@ -10,6 +10,7 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\AnyTypeTrait; +use WikibaseSolutions\CypherDSL\Types\CompositeTypes\CompositeType; /** * This trait provides a default implementation to satisfy the "CompositeType" interface. @@ -19,6 +20,8 @@ * * - ListTypeTrait * - MapTypeTrait + * + * @implements CompositeType */ trait CompositeTypeTrait { diff --git a/src/Traits/TypeTraits/CompositeTypeTraits/ListTypeTrait.php b/src/Traits/TypeTraits/CompositeTypeTraits/ListTypeTrait.php index 164d738a..9f5f7d9f 100644 --- a/src/Traits/TypeTraits/CompositeTypeTraits/ListTypeTrait.php +++ b/src/Traits/TypeTraits/CompositeTypeTraits/ListTypeTrait.php @@ -10,21 +10,24 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits; use WikibaseSolutions\CypherDSL\Expressions\Operators\In; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; +use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PropertyType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "ListType" interface. + * + * @implements ListType */ trait ListTypeTrait { - use CastTrait; use CompositeTypeTrait; /** * @inheritDoc */ - public function has($left, bool $insertParentheses = true): In + public function has(PropertyType|string|int|float|bool $left, bool $insertParentheses = true): In { - return new In(self::toPropertyType($left), $this, $insertParentheses); + return new In(CastUtils::toPropertyType($left), $this, $insertParentheses); } } diff --git a/src/Traits/TypeTraits/CompositeTypeTraits/MapTypeTrait.php b/src/Traits/TypeTraits/CompositeTypeTraits/MapTypeTrait.php index 3a6f2ddb..015d69b8 100644 --- a/src/Traits/TypeTraits/CompositeTypeTraits/MapTypeTrait.php +++ b/src/Traits/TypeTraits/CompositeTypeTraits/MapTypeTrait.php @@ -10,9 +10,12 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\MethodTraits\PropertyMethodTrait; +use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; /** * This trait provides a default implementation to satisfy the "MapType" interface. + * + * @implements MapType */ trait MapTypeTrait { diff --git a/src/Traits/TypeTraits/MethodTraits/PropertyMethodTrait.php b/src/Traits/TypeTraits/MethodTraits/PropertyMethodTrait.php index 11f2c22d..536277b3 100644 --- a/src/Traits/TypeTraits/MethodTraits/PropertyMethodTrait.php +++ b/src/Traits/TypeTraits/MethodTraits/PropertyMethodTrait.php @@ -10,9 +10,12 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\MethodTraits; use WikibaseSolutions\CypherDSL\Expressions\Property; +use WikibaseSolutions\CypherDSL\Types\Methods\PropertyMethod; /** * This trait provides a default implementation to satisfy the "PropertyFunction" interface. + * + * @implements PropertyMethod */ trait PropertyMethodTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/BooleanTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/BooleanTypeTrait.php index ec1f821c..8705c6aa 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/BooleanTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/BooleanTypeTrait.php @@ -13,38 +13,40 @@ use WikibaseSolutions\CypherDSL\Expressions\Operators\Disjunction; use WikibaseSolutions\CypherDSL\Expressions\Operators\ExclusiveDisjunction; use WikibaseSolutions\CypherDSL\Expressions\Operators\Negation; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "BooleanType" interface. + * + * @implements BooleanType */ trait BooleanTypeTrait { - use CastTrait; use PropertyTypeTrait; /** * @inheritDoc */ - public function and($right, bool $insertParentheses = true): Conjunction + public function and(BooleanType|bool $right, bool $insertParentheses = true): Conjunction { - return new Conjunction($this, self::toBooleanType($right), $insertParentheses); + return new Conjunction($this, CastUtils::toBooleanType($right), $insertParentheses); } /** * @inheritDoc */ - public function or($right, bool $insertParentheses = true): Disjunction + public function or(BooleanType|bool $right, bool $insertParentheses = true): Disjunction { - return new Disjunction($this, self::toBooleanType($right), $insertParentheses); + return new Disjunction($this, CastUtils::toBooleanType($right), $insertParentheses); } /** * @inheritDoc */ - public function xor($right, bool $insertParentheses = true): ExclusiveDisjunction + public function xor(BooleanType|bool $right, bool $insertParentheses = true): ExclusiveDisjunction { - return new ExclusiveDisjunction($this, self::toBooleanType($right), $insertParentheses); + return new ExclusiveDisjunction($this, CastUtils::toBooleanType($right), $insertParentheses); } /** diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/DateTimeTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/DateTimeTypeTrait.php index b47624ea..def424f3 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/DateTimeTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/DateTimeTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\DateTimeType; + /** * This trait provides a default implementation to satisfy the "DateTimeType" interface. + * + * @implements DateTimeType */ trait DateTimeTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/DateTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/DateTypeTrait.php index d25e09db..2614b3df 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/DateTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/DateTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\DateType; + /** * This trait provides a default implementation to satisfy the "DateType" interface. + * + * @implements DateType */ trait DateTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/FloatTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/FloatTypeTrait.php index fbe5ed42..8a6a9595 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/FloatTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/FloatTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\FloatType; + /** * This trait provides a default implementation to satisfy the "FloatType" interface. + * + * @implements FloatType */ trait FloatTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/IntegerTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/IntegerTypeTrait.php index 1b1acdb1..3e591ba3 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/IntegerTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/IntegerTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\IntegerType; + /** * This trait provides a default implementation to satisfy the "IntegerType" interface. + * + * @implements IntegerType */ trait IntegerTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/LocalDateTimeTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/LocalDateTimeTypeTrait.php index 7fb0b913..bfbbe518 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/LocalDateTimeTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/LocalDateTimeTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\LocalDateTimeType; + /** * This trait provides a default implementation to satisfy the "LocalDateTimeType" interface. + * + * @implements LocalDateTimeType */ trait LocalDateTimeTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/LocalTimeTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/LocalTimeTypeTrait.php index 84bafc5a..534d57cd 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/LocalTimeTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/LocalTimeTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\LocalTimeType; + /** * This trait provides a default implementation to satisfy the "LocalTimeType" interface. + * + * @implements LocalTimeType */ trait LocalTimeTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/NumeralTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/NumeralTypeTrait.php index 5b0339ef..874ba63f 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/NumeralTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/NumeralTypeTrait.php @@ -16,9 +16,13 @@ use WikibaseSolutions\CypherDSL\Expressions\Operators\Multiplication; use WikibaseSolutions\CypherDSL\Expressions\Operators\Subtraction; use WikibaseSolutions\CypherDSL\Expressions\Operators\UnaryMinus; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\NumeralType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "NumeralType" interface. + * + * @implements NumeralType */ trait NumeralTypeTrait { @@ -27,49 +31,49 @@ trait NumeralTypeTrait /** * @inheritDoc */ - public function plus($right, bool $insertParentheses = true): Addition + public function plus(NumeralType|float|int $right, bool $insertParentheses = true): Addition { - return new Addition($this, self::toNumeralType($right), $insertParentheses); + return new Addition($this, CastUtils::toNumeralType($right), $insertParentheses); } /** * @inheritDoc */ - public function divide($right, bool $insertParentheses = true): Division + public function divide(NumeralType|float|int $right, bool $insertParentheses = true): Division { - return new Division($this, self::toNumeralType($right), $insertParentheses); + return new Division($this, CastUtils::toNumeralType($right), $insertParentheses); } /** * @inheritDoc */ - public function exponentiate($right, bool $insertParentheses = true): Exponentiation + public function exponentiate(NumeralType|float|int $right, bool $insertParentheses = true): Exponentiation { - return new Exponentiation($this, self::toNumeralType($right), $insertParentheses); + return new Exponentiation($this, CastUtils::toNumeralType($right), $insertParentheses); } /** * @inheritDoc */ - public function mod($right, bool $insertParentheses = true): ModuloDivision + public function mod(NumeralType|float|int $right, bool $insertParentheses = true): ModuloDivision { - return new ModuloDivision($this, self::toNumeralType($right), $insertParentheses); + return new ModuloDivision($this, CastUtils::toNumeralType($right), $insertParentheses); } /** * @inheritDoc */ - public function times($right, bool $insertParentheses = true): Multiplication + public function times(NumeralType|float|int $right, bool $insertParentheses = true): Multiplication { - return new Multiplication($this, self::toNumeralType($right), $insertParentheses); + return new Multiplication($this, CastUtils::toNumeralType($right), $insertParentheses); } /** * @inheritDoc */ - public function minus($right, bool $insertParentheses = true): Subtraction + public function minus(NumeralType|float|int $right, bool $insertParentheses = true): Subtraction { - return new Subtraction($this, self::toNumeralType($right), $insertParentheses); + return new Subtraction($this, CastUtils::toNumeralType($right), $insertParentheses); } /** diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/PointTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/PointTypeTrait.php index c0f49966..bf13c50b 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/PointTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/PointTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PointType; + /** * This trait provides a default implementation to satisfy the "PointType" interface. + * + * @implements PointType */ trait PointTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php index c42aa8f8..c5119869 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php @@ -12,6 +12,9 @@ use WikibaseSolutions\CypherDSL\Expressions\Operators\In; use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\AnyTypeTrait; +use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PropertyType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "PropertyType" interface. @@ -28,17 +31,18 @@ * - PointTypeTrait * - StringTypeTrait * - TimeTypeTrait + * + * @implements PropertyType */ trait PropertyTypeTrait { use AnyTypeTrait; - use CastTrait; /** * @inheritDoc */ - public function in($right, bool $insertParentheses = true): In + public function in(ListType|array $right, bool $insertParentheses = true): In { - return new In($this, self::toListType($right), $insertParentheses); + return new In($this, CastUtils::toListType($right), $insertParentheses); } } diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/StringTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/StringTypeTrait.php index e5221f24..7a705bb2 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/StringTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/StringTypeTrait.php @@ -13,45 +13,47 @@ use WikibaseSolutions\CypherDSL\Expressions\Operators\EndsWith; use WikibaseSolutions\CypherDSL\Expressions\Operators\Regex; use WikibaseSolutions\CypherDSL\Expressions\Operators\StartsWith; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\StringType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "StringType" interface. + * + * @implements StringType */ trait StringTypeTrait { - use CastTrait; use PropertyTypeTrait; /** * @inheritDoc */ - public function contains($right, bool $insertParentheses = true): Contains + public function contains(StringType|string $right, bool $insertParentheses = true): Contains { - return new Contains($this, self::toStringType($right), $insertParentheses); + return new Contains($this, CastUtils::toStringType($right), $insertParentheses); } /** * @inheritDoc */ - public function endsWith($right, bool $insertParentheses = true): EndsWith + public function endsWith(StringType|string $right, bool $insertParentheses = true): EndsWith { - return new EndsWith($this, self::toStringType($right), $insertParentheses); + return new EndsWith($this, CastUtils::toStringType($right), $insertParentheses); } /** * @inheritDoc */ - public function startsWith($right, bool $insertParentheses = true): StartsWith + public function startsWith(StringType|string $right, bool $insertParentheses = true): StartsWith { - return new StartsWith($this, self::toStringType($right), $insertParentheses); + return new StartsWith($this, CastUtils::toStringType($right), $insertParentheses); } /** * @inheritDoc */ - public function regex($right, bool $insertParentheses = true): Regex + public function regex(StringType|string $right, bool $insertParentheses = true): Regex { - return new Regex($this, self::toStringType($right), $insertParentheses); + return new Regex($this, CastUtils::toStringType($right), $insertParentheses); } } diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/TimeTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/TimeTypeTrait.php index 7c281229..49a8cb58 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/TimeTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/TimeTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\TimeType; + /** * This trait provides a default implementation to satisfy the "TimeType" interface. + * + * @implements TimeType */ trait TimeTypeTrait { diff --git a/src/Traits/TypeTraits/StructuralTypeTraits/NodeTypeTrait.php b/src/Traits/TypeTraits/StructuralTypeTraits/NodeTypeTrait.php index d76fde3e..94a4fc29 100644 --- a/src/Traits/TypeTraits/StructuralTypeTraits/NodeTypeTrait.php +++ b/src/Traits/TypeTraits/StructuralTypeTraits/NodeTypeTrait.php @@ -10,9 +10,12 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\StructuralTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\MethodTraits\PropertyMethodTrait; +use WikibaseSolutions\CypherDSL\Types\StructuralTypes\NodeType; /** * This trait provides a default implementation to satisfy the "NodeType" interface. + * + * @implements NodeType */ trait NodeTypeTrait { diff --git a/src/Traits/TypeTraits/StructuralTypeTraits/PathTypeTrait.php b/src/Traits/TypeTraits/StructuralTypeTraits/PathTypeTrait.php index c1473a40..07400c71 100644 --- a/src/Traits/TypeTraits/StructuralTypeTraits/PathTypeTrait.php +++ b/src/Traits/TypeTraits/StructuralTypeTraits/PathTypeTrait.php @@ -9,8 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\StructuralTypeTraits; +use WikibaseSolutions\CypherDSL\Types\StructuralTypes\PathType; + /** * This trait provides a default implementation to satisfy the "PathType" interface. + * + * @implements PathType */ trait PathTypeTrait { diff --git a/src/Traits/TypeTraits/StructuralTypeTraits/RelationshipTypeTrait.php b/src/Traits/TypeTraits/StructuralTypeTraits/RelationshipTypeTrait.php index 222ff499..2de3aa9d 100644 --- a/src/Traits/TypeTraits/StructuralTypeTraits/RelationshipTypeTrait.php +++ b/src/Traits/TypeTraits/StructuralTypeTraits/RelationshipTypeTrait.php @@ -10,9 +10,12 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\StructuralTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\MethodTraits\PropertyMethodTrait; +use WikibaseSolutions\CypherDSL\Types\StructuralTypes\RelationshipType; /** * This trait provides a default implementation to satisfy the "RelationshipType" interface. + * + * @implements RelationshipType */ trait RelationshipTypeTrait { diff --git a/src/Traits/TypeTraits/StructuralTypeTraits/StructuralTypeTrait.php b/src/Traits/TypeTraits/StructuralTypeTraits/StructuralTypeTrait.php index 81a38816..00121ace 100644 --- a/src/Traits/TypeTraits/StructuralTypeTraits/StructuralTypeTrait.php +++ b/src/Traits/TypeTraits/StructuralTypeTraits/StructuralTypeTrait.php @@ -10,6 +10,7 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\StructuralTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\AnyTypeTrait; +use WikibaseSolutions\CypherDSL\Types\StructuralTypes\StructuralType; /** * This trait provides a default implementation to satisfy the "StructuralType" interface. @@ -20,6 +21,8 @@ * - NodeTypeTrait * - PathTypeTrait * - RelationshipTypeTrait + * + * @implements StructuralType */ trait StructuralTypeTrait { diff --git a/src/Types/AnyType.php b/src/Types/AnyType.php index fa679321..ebd9faaa 100644 --- a/src/Types/AnyType.php +++ b/src/Types/AnyType.php @@ -28,7 +28,7 @@ * * @note This interface should not be implemented by any class directly * - * @see AnyTypeTrait for a default implementation + * @see AnyTypeTrait for a default implementation * @see https://neo4j.com/docs/cypher-manual/current/syntax/values/ Corresponding documentation on Neo4j.com */ interface AnyType extends QueryConvertible @@ -38,49 +38,37 @@ interface AnyType extends QueryConvertible * * @param string|Variable $right */ - public function alias($right): Alias; + public function alias(Variable|string $right): Alias; /** * Perform an equality check with the given expression. - * - * @param AnyType|bool|float|int|mixed[]|Pattern|string $right */ - public function equals($right, bool $insertParentheses = true): Equality; + public function equals(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): Equality; /** * Perform an inequality comparison against the given expression. - * - * @param AnyType|bool|float|int|mixed[]|Pattern|string $right */ - public function notEquals($right, bool $insertParentheses = true): Inequality; + public function notEquals(AnyType|Pattern|string|bool|float|int|array$right, bool $insertParentheses = true): Inequality; /** * Perform a greater than comparison against the given expression. - * - * @param AnyType|bool|float|int|mixed[]|Pattern|string $right */ - public function gt($right, bool $insertParentheses = true): GreaterThan; + public function gt(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): GreaterThan; /** * Perform a greater than or equal comparison against the given expression. - * - * @param AnyType|bool|float|int|mixed[]|Pattern|string $right */ - public function gte($right, bool $insertParentheses = true): GreaterThanOrEqual; + public function gte(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): GreaterThanOrEqual; /** * Perform a less than comparison against the given expression. - * - * @param AnyType|bool|float|int|mixed[]|Pattern|string $right */ - public function lt($right, bool $insertParentheses = true): LessThan; + public function lt(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): LessThan; /** * Perform a less than or equal comparison against the given expression. - * - * @param AnyType|bool|float|int|mixed[]|Pattern|string $right */ - public function lte($right, bool $insertParentheses = true): LessThanOrEqual; + public function lte(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): LessThanOrEqual; /** * Checks whether the element is null. diff --git a/src/Types/CompositeTypes/CompositeType.php b/src/Types/CompositeTypes/CompositeType.php index 94c24592..b0753cf8 100644 --- a/src/Types/CompositeTypes/CompositeType.php +++ b/src/Types/CompositeTypes/CompositeType.php @@ -29,7 +29,7 @@ * * @note This interface should not be implemented by any class directly * - * @see CompositeTypeTrait for a default implemenation + * @see CompositeTypeTrait for a default implemenation * @see https://neo4j.com/docs/cypher-manual/current/syntax/values/#composite-types Corresponding documentation on Neo4j.com */ interface CompositeType extends AnyType diff --git a/src/Types/CompositeTypes/ListType.php b/src/Types/CompositeTypes/ListType.php index 7dda806b..f60746c8 100644 --- a/src/Types/CompositeTypes/ListType.php +++ b/src/Types/CompositeTypes/ListType.php @@ -22,8 +22,6 @@ interface ListType extends CompositeType { /** * Checks whether the given element exists in this list. - * - * @param bool|float|int|PropertyType|string $left */ - public function has($left, bool $insertParentheses = true): In; + public function has(PropertyType|string|int|float|bool $left, bool $insertParentheses = true): In; } diff --git a/src/Types/PropertyTypes/BooleanType.php b/src/Types/PropertyTypes/BooleanType.php index e8f72def..ce3a03cd 100644 --- a/src/Types/PropertyTypes/BooleanType.php +++ b/src/Types/PropertyTypes/BooleanType.php @@ -24,24 +24,18 @@ interface BooleanType extends PropertyType { /** * Create a conjunction between this expression and the given expression. - * - * @param bool|BooleanType $right */ - public function and($right, bool $insertParentheses = true): Conjunction; + public function and(BooleanType|bool $right, bool $insertParentheses = true): Conjunction; /** * Create a disjunction between this expression and the given expression. - * - * @param bool|BooleanType $right */ - public function or($right, bool $insertParentheses = true): Disjunction; + public function or(BooleanType|bool $right, bool $insertParentheses = true): Disjunction; /** * Perform an XOR with the given expression. - * - * @param bool|BooleanType $right */ - public function xor($right, bool $insertParentheses = true): ExclusiveDisjunction; + public function xor(BooleanType|bool $right, bool $insertParentheses = true): ExclusiveDisjunction; /** * Negate this expression (using the NOT operator). diff --git a/src/Types/PropertyTypes/LocalDateTimeType.php b/src/Types/PropertyTypes/LocalDateTimeType.php index 8069011c..55b36317 100644 --- a/src/Types/PropertyTypes/LocalDateTimeType.php +++ b/src/Types/PropertyTypes/LocalDateTimeType.php @@ -9,10 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Types\PropertyTypes; +use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\LocalDateTimeTypeTrait; + /** * Represents the leaf type "localdatetime". * - * @see LocalDateTimeType for a default implementation + * @see LocalDateTimeTypeTrait for a default implementation */ interface LocalDateTimeType extends PropertyType { diff --git a/src/Types/PropertyTypes/NumeralType.php b/src/Types/PropertyTypes/NumeralType.php index 74f2493d..1b954e23 100644 --- a/src/Types/PropertyTypes/NumeralType.php +++ b/src/Types/PropertyTypes/NumeralType.php @@ -23,51 +23,39 @@ * * @note This interface should not be implemented by any class directly * - * @see NumeralTypeTrait for a default implementation + * @see NumeralTypeTrait for a default implementation */ interface NumeralType extends PropertyType { /** * Add this expression to the given expression. - * - * @param float|int|NumeralType $right */ - public function plus($right, bool $insertParentheses = true): Addition; + public function plus(NumeralType|float|int $right, bool $insertParentheses = true): Addition; /** * Divide this expression by the given expression. - * - * @param float|int|NumeralType $right */ - public function divide($right, bool $insertParentheses = true): Division; + public function divide(NumeralType|float|int $right, bool $insertParentheses = true): Division; /** * Perform an exponentiation with the given expression. - * - * @param float|int|NumeralType $right */ - public function exponentiate($right, bool $insertParentheses = true): Exponentiation; + public function exponentiate(NumeralType|float|int $right, bool $insertParentheses = true): Exponentiation; /** * Perform the modulo operation with the given expression. - * - * @param float|int|NumeralType $right */ - public function mod($right, bool $insertParentheses = true): ModuloDivision; + public function mod(NumeralType|float|int $right, bool $insertParentheses = true): ModuloDivision; /** * Perform a multiplication with the given expression. - * - * @param float|int|NumeralType $right */ - public function times($right, bool $insertParentheses = true): Multiplication; + public function times(NumeralType|float|int $right, bool $insertParentheses = true): Multiplication; /** * Subtract the given expression from this expression. - * - * @param float|int|NumeralType $right */ - public function minus($right, bool $insertParentheses = true): Subtraction; + public function minus(NumeralType|float|int $right, bool $insertParentheses = true): Subtraction; /** * Negate this expression (negate the numeral using "0"). diff --git a/src/Types/PropertyTypes/PropertyType.php b/src/Types/PropertyTypes/PropertyType.php index cf48d7dd..25ea859a 100644 --- a/src/Types/PropertyTypes/PropertyType.php +++ b/src/Types/PropertyTypes/PropertyType.php @@ -37,15 +37,13 @@ * * @note This interface should not be implemented by any class directly * - * @see PropertyTypeTrait for a default implementation + * @see PropertyTypeTrait for a default implementation * @see https://neo4j.com/docs/cypher-manual/current/syntax/values/#property-types Corresponding documentation on Neo4j.com */ interface PropertyType extends AnyType { /** * Checks whether the element exists in the given list. - * - * @param ListType|mixed[] $right */ - public function in($right): In; + public function in(ListType|array $right): In; } diff --git a/src/Types/PropertyTypes/StringType.php b/src/Types/PropertyTypes/StringType.php index 40818d09..8c9e548a 100644 --- a/src/Types/PropertyTypes/StringType.php +++ b/src/Types/PropertyTypes/StringType.php @@ -24,29 +24,21 @@ interface StringType extends PropertyType { /** * Check whether this expression the given expression. - * - * @param string|StringType $right */ - public function contains($right, bool $insertParentheses = true): Contains; + public function contains(StringType|string $right, bool $insertParentheses = true): Contains; /** * Perform a suffix string search with the given expression. - * - * @param string|StringType $right */ - public function endsWith($right, bool $insertParentheses = true): EndsWith; + public function endsWith(StringType|string $right, bool $insertParentheses = true): EndsWith; /** * Perform a prefix string search with the given expression. - * - * @param string|StringType $right */ - public function startsWith($right, bool $insertParentheses = true): StartsWith; + public function startsWith(StringType|string $right, bool $insertParentheses = true): StartsWith; /** * Perform a regex comparison with the given expression. - * - * @param string|StringType $right */ - public function regex($right, bool $insertParentheses = true): Regex; + public function regex(StringType|string $right, bool $insertParentheses = true): Regex; } diff --git a/src/Types/StructuralTypes/StructuralType.php b/src/Types/StructuralTypes/StructuralType.php index 691f0cd4..4540a6cd 100644 --- a/src/Types/StructuralTypes/StructuralType.php +++ b/src/Types/StructuralTypes/StructuralType.php @@ -30,7 +30,7 @@ * * @note This interface should not be implemented by any class directly * - * @see StructuralTypeTrait for a default implementation + * @see StructuralTypeTrait for a default implementation * @see https://neo4j.com/docs/cypher-manual/current/syntax/values/#structural-types Corresponding documentation on Neo4j.com */ interface StructuralType extends AnyType diff --git a/src/functions.php b/src/functions.php index c067aabf..1e95186d 100644 --- a/src/functions.php +++ b/src/functions.php @@ -160,13 +160,11 @@ function variable(?string $variable = null): Variable * - list_() - For a list * - map() - For a map * - * @param null|bool|float|int|mixed[]|string $literal The literal to construct - * - * @return Boolean|class-string|Float_|Integer|List_|Map|String_ + * @param null|bool|float|int|array|string $literal The literal to construct * * @see Query::literal() */ -function literal($literal = null) +function literal(bool|float|int|array|string|null $literal = null): Boolean|Float_|List_|String_|Integer|string|Map { return Query::literal($literal); } @@ -214,8 +212,6 @@ function float(float $value): Float_ /** * Creates a new list literal. * - * @param mixed[] $value - * * @see Query::list() */ function list_(array $value): List_ @@ -226,8 +222,6 @@ function list_(array $value): List_ /** * Creates a new map literal. * - * @param mixed[] $value - * * @see Query::map() */ function map(array $value): Map From 989521ef56c5765635f5a3375a75ecf204ffdab6 Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Tue, 3 Feb 2026 16:55:03 +0100 Subject: [PATCH 04/12] Refactor more classes to use union types --- src/Clauses/ReturnClause.php | 3 +- src/Expressions/Literals/List_.php | 1 - src/Patterns/Direction.php | 26 ++++++ src/Patterns/Pattern.php | 2 +- src/Patterns/Relationship.php | 34 +++----- src/Query.php | 81 +++++++++---------- .../PropertyTypeTraits/PropertyTypeTrait.php | 1 - 7 files changed, 78 insertions(+), 70 deletions(-) create mode 100644 src/Patterns/Direction.php diff --git a/src/Clauses/ReturnClause.php b/src/Clauses/ReturnClause.php index b27608c3..34e156e3 100644 --- a/src/Clauses/ReturnClause.php +++ b/src/Clauses/ReturnClause.php @@ -12,7 +12,6 @@ use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\QueryConvertible; use WikibaseSolutions\CypherDSL\Syntax\Alias; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Utils\CastUtils; @@ -31,7 +30,7 @@ final class ReturnClause extends Clause private bool $distinct = false; /** - * @var Alias[]|AnyType[]|(Alias|AnyType)[] The expressions to return + * @var (Alias|AnyType)[] The expressions to return */ private array $columns = []; diff --git a/src/Expressions/Literals/List_.php b/src/Expressions/Literals/List_.php index c4b9f27a..679a5c4e 100644 --- a/src/Expressions/Literals/List_.php +++ b/src/Expressions/Literals/List_.php @@ -10,7 +10,6 @@ namespace WikibaseSolutions\CypherDSL\Expressions\Literals; use WikibaseSolutions\CypherDSL\Patterns\Pattern; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; diff --git a/src/Patterns/Direction.php b/src/Patterns/Direction.php new file mode 100644 index 00000000..4132698f --- /dev/null +++ b/src/Patterns/Direction.php @@ -0,0 +1,26 @@ +(b). + */ + case RIGHT; + + /** + * For the relation (a)<--(b). + */ + case LEFT; + + /** + * For the relation (a)--(b). + */ + case UNI; +} diff --git a/src/Patterns/Pattern.php b/src/Patterns/Pattern.php index a3daba2e..ae1ed6b3 100644 --- a/src/Patterns/Pattern.php +++ b/src/Patterns/Pattern.php @@ -47,7 +47,7 @@ public function hasVariableSet(): bool; * * @return $this */ - public function withVariable($variable): self; + public function withVariable(Variable|string|null $variable): self; /** * Returns the variable of this pattern. This function generates a variable if none has been set. It will implicitly set the variable of the pattern as well. diff --git a/src/Patterns/Relationship.php b/src/Patterns/Relationship.php index b6f3f658..e1387b43 100644 --- a/src/Patterns/Relationship.php +++ b/src/Patterns/Relationship.php @@ -10,7 +10,6 @@ namespace WikibaseSolutions\CypherDSL\Patterns; use DomainException; -use InvalidArgumentException; use LogicException; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; use WikibaseSolutions\CypherDSL\Traits\PatternTraits\PropertyPatternTrait; @@ -25,16 +24,10 @@ final class Relationship implements PropertyPattern { use PropertyPatternTrait; - public const DIR_RIGHT = ["-", "->"]; - - public const DIR_LEFT = ["<-", "-"]; - - public const DIR_UNI = ["-", "-"]; - /** - * @var string[] The direction of the relationship (one of the DIR_* constants) + * @var Direction The direction of the relationship */ - private array $direction; + private Direction $direction; /** * @var string[] A list of relationship condition types @@ -62,19 +55,12 @@ final class Relationship implements PropertyPattern private bool $arbitraryHops = false; /** - * @param string[] $direction The direction of the relationship, should be either: - * - Relationship::DIR_RIGHT (for a relation of (a)-->(b)) - * - Relationship::DIR_LEFT (for a relation of (a)<--(b)) - * - Relationship::DIR_UNI (for a relation of (a)--(b)) + * @param Direction $direction The direction of the relationship * * @internal This method is not covered by the backwards compatibility guarantee of php-cypher-dsl */ - public function __construct(array $direction) + public function __construct(Direction $direction) { - if ($direction !== self::DIR_RIGHT && $direction !== self::DIR_LEFT && $direction !== self::DIR_UNI) { - throw new InvalidArgumentException("The direction must be either 'DIR_LEFT', 'DIR_RIGHT' or 'RELATED_TO'"); - } - $this->direction = $direction; } @@ -199,9 +185,9 @@ public function addType(string ...$type): self /** * Returns the direction of this relationship (one of the Relationship::DIR_* constants). * - * @return string[] + * @return Direction */ - public function getDirection(): array + public function getDirection(): Direction { return $this->direction; } @@ -246,7 +232,13 @@ public function getTypes(): array */ public function toQuery(): string { - return $this->direction[0] . $this->relationshipDetailToString() . $this->direction[1]; + $directionParts = match ($this->direction) { + Direction::UNI => ['-', '-'], + Direction::LEFT => ['<-', '-'], + Direction::RIGHT => ['-', '->'], + }; + + return $directionParts[0] . $this->relationshipDetailToString() . $directionParts[1]; } /** diff --git a/src/Query.php b/src/Query.php index b6014479..2e79f642 100644 --- a/src/Query.php +++ b/src/Query.php @@ -43,24 +43,23 @@ use WikibaseSolutions\CypherDSL\Expressions\RawExpression; use WikibaseSolutions\CypherDSL\Expressions\Variable; 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\Syntax\Alias; use WikibaseSolutions\CypherDSL\Syntax\PropertyReplacement; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\IntegerType; use WikibaseSolutions\CypherDSL\Types\StructuralTypes\StructuralType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * Builder class for building complex Cypher queries. */ final class Query implements QueryConvertible { - use CastTrait; - // A reference to the Literal class public const literal = Literal::class; @@ -101,14 +100,11 @@ public static function node(?string $label = null): Node /** * Creates a relationship. * - * @param string[] $direction The direction of the relationship (optional, default: unidirectional), should be either: - * - Relationship::DIR_RIGHT (for a relation of (a)-->(b)) - * - Relationship::DIR_LEFT (for a relation of (a)<--(b)) - * - Relationship::DIR_UNI (for a relation of (a)--(b)) + * @param Direction $direction The direction of the relationship (optional, default: unidirectional) * * @see https://neo4j.com/docs/cypher-manual/current/syntax/patterns/#cypher-pattern-relationship Corresponding documentation on Neo4j.com */ - public static function relationship(array $direction = Relationship::DIR_UNI): Relationship + public static function relationship(Direction $direction = Direction::UNI): Relationship { return new Relationship($direction); } @@ -120,7 +116,7 @@ public static function relationship(array $direction = Relationship::DIR_UNI): R */ public static function relationshipUni(): Relationship { - return new Relationship(Relationship::DIR_UNI); + return new Relationship(Direction::UNI); } /** @@ -130,7 +126,7 @@ public static function relationshipUni(): Relationship */ public static function relationshipTo(): Relationship { - return new Relationship(Relationship::DIR_RIGHT); + return new Relationship(Direction::RIGHT); } /** @@ -140,7 +136,7 @@ public static function relationshipTo(): Relationship */ public static function relationshipFrom(): Relationship { - return new Relationship(Relationship::DIR_LEFT); + return new Relationship(Direction::LEFT); } /** @@ -203,11 +199,11 @@ public static function variable(?string $variable = null): Variable * - Query::list() - For a list * - Query::map() - For a map * - * @param null|bool|float|int|mixed[]|string $literal The literal to construct + * @param bool|float|int|array|string|null $literal The literal to construct * * @return Boolean|class-string|Float_|Integer|List_|Map|String_ */ - public static function literal($literal = null) + public static function literal(null|bool|float|int|array|string $literal = null): Boolean|Float_|Integer|List_|Map|String_|string { if ($literal === null) { return self::literal; @@ -318,11 +314,8 @@ public static function rawExpression(string $expression): RawExpression /** * Creates an EXISTS expression. - * - * @param CompletePattern|CompletePattern[]|MatchClause $match - * @param null|BooleanType|WhereClause $where */ - public static function exists($match, $where = null, bool $insertParentheses = false): Exists + public static function exists(CompletePattern|MatchClause|array $match, WhereClause|BooleanType|bool $where = null, bool $insertParentheses = false): Exists { if (!$match instanceof MatchClause) { $match = is_array($match) ? $match : [$match]; @@ -389,13 +382,13 @@ public function call(Query|callable $query, Pattern|Variable|string ...$variable * Creates the CALL procedure clause. * * @param Procedure|string $procedure The procedure to call - * @param AnyType|AnyType[]|bool|bool[]|float|float[]|int|int[]|mixed[]|mixed[][]|Pattern|Pattern[]|string|string[]|(AnyType|bool|float|int|mixed[]|Pattern|string)[] $yields The result fields that should be returned (optional) + * @param mixed $yields The result fields that should be returned (optional) * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/call/ Corresponding documentation on Neo4j.com */ - public function callProcedure($procedure, $yields = []): self + public function callProcedure(Procedure|string $procedure, mixed $yields = []): self { if (is_string($procedure)) { $procedure = Procedure::raw($procedure); @@ -405,7 +398,7 @@ public function callProcedure($procedure, $yields = []): self $yields = [$yields]; } - $yields = $this->makeAliasArray($yields, fn ($value) => $this->toName($value)); + $yields = $this->makeAliasArray($yields, fn ($value) => CastUtils::toName($value)); $callProcedureClause = new CallProcedureClause(); $callProcedureClause->setProcedure($procedure); @@ -425,7 +418,7 @@ public function callProcedure($procedure, $yields = []): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/match/ Corresponding documentation on Neo4j.com */ - public function match($patterns): self + public function match(CompletePattern|array $patterns): self { if (!is_array($patterns)) { $patterns = [$patterns]; @@ -442,20 +435,20 @@ public function match($patterns): self /** * Creates the RETURN clause. * - * @param Alias|Alias[]|AnyType|AnyType[]|bool|bool[]|float|float[]|int|int[]|Pattern|Pattern[]|string|string[]|(Alias|AnyType|mixed[]|bool|float|int|Pattern|string)[] $expressions A single expression to return, or a non-empty list of expressions to return + * @param mixed $expressions A single expression to return, or a non-empty list of expressions to return * @param bool $distinct Whether to be a RETURN DISTINCT clause (optional, default: false) * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/return/ Corresponding documentation on Neo4j.com */ - public function returning($expressions, bool $distinct = false): self + public function returning(mixed $expressions, bool $distinct = false): self { if (!is_array($expressions)) { $expressions = [$expressions]; } - $expressions = $this->makeAliasArray($expressions, fn ($value) => $this->toAnyType($value)); + $expressions = $this->makeAliasArray($expressions, fn ($value) => CastUtils::toAnyType($value)); $returnClause = new ReturnClause(); $returnClause->addColumn(...$expressions); @@ -475,7 +468,7 @@ public function returning($expressions, bool $distinct = false): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/create/ Corresponding documentation on Neo4j.com */ - public function create($patterns): self + public function create(CompletePattern|array $patterns): self { if (!is_array($patterns)) { $patterns = [$patterns]; @@ -492,14 +485,14 @@ public function create($patterns): self /** * Creates the DELETE clause. * - * @param Pattern|Pattern[]|StructuralType|StructuralType[]|(Pattern|StructuralType)[] $structures A single structure to delete, or a non-empty list of structures to delete + * @param Pattern|StructuralType|(Pattern|StructuralType)[] $structures A single structure to delete, or a non-empty list of structures to delete * @param bool $detach Whether to DETACH DELETE (optional, default: false) * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/delete/ Corresponding documentation on Neo4j.com */ - public function delete($structures, bool $detach = false): self + public function delete(Pattern|StructuralType|array $structures, bool $detach = false): self { if (!is_array($structures)) { $structures = [$structures]; @@ -517,13 +510,13 @@ public function delete($structures, bool $detach = false): self /** * Creates the DETACH DELETE clause. * - * @param Pattern|Pattern[]|StructuralType|StructuralType[]|(Pattern|StructuralType)[] $structures A single structure to delete, or a non-empty list of structures to delete + * @param Pattern|StructuralType|(Pattern|StructuralType)[] $structures A single structure to delete, or a non-empty list of structures to delete * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/delete/ Corresponding documentation on Neo4j.com */ - public function detachDelete($structures): self + public function detachDelete(Pattern|StructuralType|array $structures): self { return $this->delete($structures, true); } @@ -537,7 +530,7 @@ public function detachDelete($structures): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/limit/ Corresponding documentation on Neo4j.com */ - public function limit($limit): self + public function limit(IntegerType|int $limit): self { $limitClause = new LimitClause(); $limitClause->setLimit($limit); @@ -556,7 +549,7 @@ public function limit($limit): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/skip/ Corresponding documentation on Neo4j.com */ - public function skip($amount): self + public function skip(IntegerType|int $amount): self { $skipClause = new SkipClause(); $skipClause->setSkip($amount); @@ -598,7 +591,7 @@ public function merge(CompletePattern $pattern, ?SetClause $createClause = null, * * @see https://neo4j.com/docs/cypher-manual/current/clauses/optional-match/ Corresponding documentation on Neo4j.com */ - public function optionalMatch($patterns): self + public function optionalMatch(CompletePattern|array $patterns): self { if (!is_array($patterns)) { $patterns = [$patterns]; @@ -622,7 +615,7 @@ public function optionalMatch($patterns): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/order-by/ Corresponding documentation on Neo4j.com */ - public function orderBy($properties, bool $descending = false): self + public function orderBy(Property|array $properties, bool $descending = false): self { if (!is_array($properties)) { $properties = [$properties]; @@ -640,13 +633,13 @@ public function orderBy($properties, bool $descending = false): self /** * Creates the REMOVE clause. * - * @param Label|Label[]|Property|Property[]|(Label|Property)[] $expressions A single expression to remove, or a non-empty list of expressions to remove + * @param Label|Property|(Label|Property)[] $expressions A single expression to remove, or a non-empty list of expressions to remove * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/remove/ Corresponding documentation on Neo4j.com */ - public function remove($expressions): self + public function remove(Label|Property|array $expressions): self { if (!is_array($expressions)) { $expressions = [$expressions]; @@ -663,13 +656,13 @@ public function remove($expressions): self /** * Create the SET clause. * - * @param Label|Label[]|PropertyReplacement|PropertyReplacement[]|(Label|PropertyReplacement)[] $expressions A single expression to set, or a non-empty list of expressions to set + * @param Label|PropertyReplacement|(Label|PropertyReplacement)[] $expressions A single expression to set, or a non-empty list of expressions to set * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/set/ Corresponding documentation on Neo4j.com */ - public function set($expressions): self + public function set(Label|PropertyReplacement|array $expressions): self { if (!is_array($expressions)) { $expressions = [$expressions]; @@ -686,7 +679,7 @@ public function set($expressions): self /** * Creates the WHERE clause. * - * @param bool|bool[]|BooleanType|BooleanType[]|(bool|BooleanType)[] $expressions A boolean expression to evaluate, or a non-empty list of boolean expression to evaluate + * @param bool|BooleanType|(bool|BooleanType)[] $expressions A boolean expression to evaluate, or a non-empty list of boolean expression to evaluate * @param string $operator The operator with which to unify the given expressions, should be either WhereClause::OR, * WhereClause::AND or WhereClause::XOR (optional, default: 'and') * @@ -694,7 +687,7 @@ public function set($expressions): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/where/ Corresponding documentation on Neo4j.com */ - public function where($expressions, string $operator = WhereClause::AND): self + public function where(BooleanType|bool|array $expressions, string $operator = WhereClause::AND): self { if (!is_array($expressions)) { $expressions = [$expressions]; @@ -714,13 +707,13 @@ public function where($expressions, string $operator = WhereClause::AND): self /** * Creates the WITH clause. * - * @param Alias|Alias[]|AnyType|AnyType[]|bool|bool[]|float|float[]|int|int[]|mixed[][]|Pattern|Pattern[]|string|string[]|(Alias|AnyType|bool|float|int|mixed[]|Pattern|string)[] $expressions An entry to add, or a non-empty list of entries to add; if the array-key is non-numerical, it is used as the alias + * @param mixed $expressions An entry to add, or a non-empty list of entries to add; if the array-key is non-numerical, it is used as the alias * * @return $this * * @see https://neo4j.com/docs/cypher-manual/current/clauses/with/ Corresponding documentation on Neo4j.com */ - public function with($expressions): self + public function with(mixed $expressions): self { if (!is_array($expressions)) { $expressions = [$expressions]; @@ -763,7 +756,7 @@ public function raw(string $clause, string $subject): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/union/ Corresponding documentation on Neo4j.com */ - public function union($queryOrCallable, bool $all = false): self + public function union(Query|callable $queryOrCallable, bool $all = false): self { if (is_callable($queryOrCallable)) { $query = self::new(); @@ -837,10 +830,10 @@ public function toQuery(): string /** * Changes an associative array into an array of aliases. * - * @param mixed[] $values The array to change into an array of aliases + * @param array $values The array to change into an array of aliases * @param callable $castFunc Function to use to cast the elements of $array * - * @return mixed[] A sequential array, possibly consisting of aliases + * @return array A sequential array, possibly consisting of aliases */ private static function makeAliasArray(array $values, callable $castFunc): array { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php index c5119869..39aed8ce 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php @@ -10,7 +10,6 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; use WikibaseSolutions\CypherDSL\Expressions\Operators\In; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\AnyTypeTrait; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PropertyType; From 366fd4d10f867e765cbbdfcd6c943c9a0dd202f0 Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Tue, 3 Feb 2026 18:37:50 +0100 Subject: [PATCH 05/12] Continue on refactor and make tests pass --- .github/CONTRIBUTING.md | 14 +- CHANGELOG.md | 6 + LIFECYCLE.md | 9 +- composer.json | 3 +- src/Expressions/Label.php | 1 - src/Expressions/Procedures/Procedure.php | 30 ++- src/Expressions/Procedures/Raw.php | 12 +- src/Expressions/Property.php | 3 - src/Patterns/Path.php | 10 +- src/Query.php | 13 +- src/Utils/CastUtils.php | 4 +- src/functions.php | 14 +- tests/unit/Clauses/MatchClauseTest.php | 4 +- tests/unit/Clauses/MergeClauseTest.php | 3 +- tests/unit/Clauses/OptionalMatchTest.php | 3 +- tests/unit/Expressions/ExistsTest.php | 5 +- tests/unit/FunctionsTest.php | 3 +- tests/unit/Patterns/NodeTest.php | 3 +- tests/unit/Patterns/PathTest.php | 25 +-- tests/unit/Patterns/RelationshipTest.php | 187 +++++++++-------- tests/unit/QueryCreateTest.php | 3 +- tests/unit/QueryMatchTest.php | 5 +- tests/unit/QueryOptionalMatchTest.php | 5 +- tests/unit/QueryTest.php | 12 +- tests/unit/Traits/CastTraitTest.php | 193 ------------------ tests/unit/Traits/ErrorTraitTest.php | 139 ------------- tests/unit/Traits/EscapeTraitTest.php | 117 ----------- tests/unit/Traits/NameGenerationTraitTest.php | 46 ----- 28 files changed, 182 insertions(+), 690 deletions(-) delete mode 100644 tests/unit/Traits/CastTraitTest.php delete mode 100644 tests/unit/Traits/ErrorTraitTest.php delete mode 100644 tests/unit/Traits/EscapeTraitTest.php delete mode 100644 tests/unit/Traits/NameGenerationTraitTest.php diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d8d1050e..c487c19b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -37,7 +37,7 @@ Feel free to propose a new feature by [opening an issue for it](https://github.c 1. Fork the repository. 1. Create a new branch. - 1. If you are **implementing new functionality**, create your branch from `development`. + 1. If you are **implementing new functionality**, create your branch from `main`. 1. If you are **fixing a bug**, create your branch from the oldest [supported](https://github.com/neo4j-php/php-cypher-dsl/blob/main/LIFECYCLE.md) branch that is affected by the bug. 1. Implement your change and add tests for it. 1. Make sure the test suite passes. @@ -50,18 +50,6 @@ Some things to keep in mind: * Keep backwards compatibility breaks to a minimum. * You are encouraged to [sign your commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) with GPG. -## Branching model - -The branching model used by this project is [gitflow](https://nvie.com/posts/a-successful-git-branching-model/), with the following changes/additions: - -1. Feature branches must follow the naming convention `feature/*`. -1. The name of a feature branch should reflect the feature added (e.g. `feature/support-indexing-operator` instead of `feature/feature-1`). -1. Release branches must follow the naming convention `release/x.y`, where `x` and `y` are the major and minor version of the release respectively. A release branch should never be made for a patch. -1. Hotfix branches must follow the naming convention `hotfix/x.y.z`, where `x`, `y` and `z` are the major, minor and patch version of the hot respectively. -1. Hotfix branches must branch off from the oldest [supported](https://github.com/neo4j-php/php-cypher-dsl/blob/main/LIFECYCLE.md) branch that is affected by the bug. -1. Right before a new **major** version is released, a *support* branch is created from `main`. -1. Support branches must follow the naming convention `support/x.y`, where `x` and `y` are the major and minor version of the most recent release respectively. - ## Coding guidelines This project comes with a [configuration file](https://github.com/neo4j-php/php-cypher-dsl/blob/main/.php-cs-fixer.dist.php) for `php-cs-fixer` that you can use to format your code: diff --git a/CHANGELOG.md b/CHANGELOG.md index 53d3f7c2..02043e3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ file. A changelog has been kept from version 5.0.0 onwards. The format is based on [Keep a Changelog], and this project adheres to [Semantic Versioning]. +## 7.0.0 - 2026-02-03 + +### Changed + +- T.B.D. + ## 6.0.0 - 2023-09-19 ### Changed diff --git a/LIFECYCLE.md b/LIFECYCLE.md index 041efade..81a1c43e 100644 --- a/LIFECYCLE.md +++ b/LIFECYCLE.md @@ -16,7 +16,8 @@ loss and/or corruption. ## Supported versions -| Major version | PHP version | Initial release | End of bugfix support | -|------------------|-------------|-----------------|-----------------------| -| php-cypher-dsl 5 | >=7.4 | Jan 9th, 2023 | Mar 19th, 2024 | -| php-cypher-dsl 6 | >=7.4 | Sep 19th, 2023 | To be determined | +| Major version | PHP version | Initial release | End of bugfix support | +|------------------|-------------|-------------------|-----------------------| +| php-cypher-dsl 5 | >=7.4 | Jan 9th, 2023 | Mar 19th, 2024 | +| php-cypher-dsl 6 | >=7.4 | Sep 19th, 2023 | To be determined | +| php-cypher-dsl 7 | >=8.1 | To be determined | To be determined | diff --git a/composer.json b/composer.json index 25878292..d3059bca 100644 --- a/composer.json +++ b/composer.json @@ -47,8 +47,7 @@ }, "require": { "php": ">=8.1", - "ext-ctype": "*", - "ext-openssl": "*" + "ext-ctype": "*" }, "require-dev": { "phpunit/phpunit": "~9.0", diff --git a/src/Expressions/Label.php b/src/Expressions/Label.php index 66351c7e..d85bb462 100644 --- a/src/Expressions/Label.php +++ b/src/Expressions/Label.php @@ -9,7 +9,6 @@ */ namespace WikibaseSolutions\CypherDSL\Expressions; -use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; use WikibaseSolutions\CypherDSL\Utils\NameUtils; diff --git a/src/Expressions/Procedures/Procedure.php b/src/Expressions/Procedures/Procedure.php index 2f374ffa..329c6386 100644 --- a/src/Expressions/Procedures/Procedure.php +++ b/src/Expressions/Procedures/Procedure.php @@ -13,11 +13,11 @@ use WikibaseSolutions\CypherDSL\Expressions\Variable; use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\QueryConvertible; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\StringType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This class represents any procedure. @@ -26,8 +26,6 @@ */ abstract class Procedure implements QueryConvertible { - use CastTrait; - /** * Produces a raw function call. This enables the usage of unimplemented functions in your * Cypher queries. The parameters of this function are not type-checked. @@ -35,9 +33,9 @@ abstract class Procedure implements QueryConvertible * @param string $functionName The name of the function to call * @param mixed ...$parameters The parameters to pass to the function call */ - public static function raw(string $functionName, mixed ...$parameters): Raw + public static function raw(string $functionName, mixed $parameters = []): Raw { - return new Raw($functionName, ...array_map(self::toAnyType(...), $parameters)); + return new Raw($functionName, array_map(CastUtils::toAnyType(...), $parameters)); } /** @@ -49,7 +47,7 @@ public static function raw(string $functionName, mixed ...$parameters): Raw */ public static function all(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): All { - return new All(self::toName($variable), self::toListType($list), self::toAnyType($predicate)); + return new All(CastUtils::toName($variable), CastUtils::toListType($list), CastUtils::toAnyType($predicate)); } /** @@ -61,7 +59,7 @@ public static function all(Variable|string $variable, ListType|array $list, AnyT */ public static function any(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): Any { - return new Any(self::toName($variable), self::toListType($list), self::toAnyType($predicate)); + return new Any(CastUtils::toName($variable), CastUtils::toListType($list), CastUtils::toAnyType($predicate)); } /** @@ -71,7 +69,7 @@ public static function any(Variable|string $variable, ListType|array $list, AnyT */ public static function exists(AnyType|bool|float|int|array|Pattern|string $expression): Exists { - return new Exists(self::toAnyType($expression)); + return new Exists(CastUtils::toAnyType($expression)); } /** @@ -103,7 +101,7 @@ public static function isEmpty(ListType|MapType|StringType|string|array $list): */ public static function none(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): None { - return new None(self::toName($variable), self::toListType($list), self::toAnyType($predicate)); + return new None(CastUtils::toName($variable), CastUtils::toListType($list), CastUtils::toAnyType($predicate)); } /** @@ -115,7 +113,7 @@ public static function none(Variable|string $variable, ListType|array $list, Any */ public static function single(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): Single { - return new Single(self::toName($variable), self::toListType($list), self::toAnyType($predicate)); + return new Single(CastUtils::toName($variable), CastUtils::toListType($list), CastUtils::toAnyType($predicate)); } /** @@ -130,7 +128,7 @@ public static function single(Variable|string $variable, ListType|array $list, A */ public static function point(MapType|array $map): Point { - return new Point(self::toMapType($map)); + return new Point(CastUtils::toMapType($map)); } /** @@ -145,7 +143,7 @@ public static function point(MapType|array $map): Point */ public static function date(AnyType|bool|float|int|array|Pattern|string|null $value = null): Date { - return new Date($value === null ? null : self::toAnyType($value)); + return new Date($value === null ? null : CastUtils::toAnyType($value)); } /** @@ -162,7 +160,7 @@ public static function date(AnyType|bool|float|int|array|Pattern|string|null $va */ public static function datetime(AnyType|bool|float|int|array|Pattern|string|null $value = null): DateTime { - return new DateTime($value === null ? null : self::toAnyType($value)); + return new DateTime($value === null ? null : CastUtils::toAnyType($value)); } /** @@ -179,7 +177,7 @@ public static function datetime(AnyType|bool|float|int|array|Pattern|string|null */ public static function localdatetime(AnyType|bool|float|int|array|Pattern|string|null $value = null): LocalDateTime { - return new LocalDateTime($value === null ? null : self::toAnyType($value)); + return new LocalDateTime($value === null ? null : CastUtils::toAnyType($value)); } /** @@ -193,7 +191,7 @@ public static function localdatetime(AnyType|bool|float|int|array|Pattern|string */ public static function localtime(AnyType|bool|float|int|array|Pattern|string|null $value = null): LocalTime { - return new LocalTime($value === null ? null : self::toAnyType($value)); + return new LocalTime($value === null ? null : CastUtils::toAnyType($value)); } /** @@ -207,7 +205,7 @@ public static function localtime(AnyType|bool|float|int|array|Pattern|string|nul */ public static function time(AnyType|bool|float|int|array|Pattern|string|null $value = null): Time { - return new Time($value === null ? null : self::toAnyType($value)); + return new Time($value === null ? null : CastUtils::toAnyType($value)); } /** diff --git a/src/Expressions/Procedures/Raw.php b/src/Expressions/Procedures/Raw.php index b8a8f1cf..962317cc 100644 --- a/src/Expressions/Procedures/Raw.php +++ b/src/Expressions/Procedures/Raw.php @@ -9,7 +9,6 @@ */ namespace WikibaseSolutions\CypherDSL\Expressions\Procedures; -use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\MapTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; @@ -36,6 +35,7 @@ use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PointType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\StringType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\TimeType; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; /** * This class represents any function call. @@ -70,8 +70,6 @@ final class Raw extends Procedure implements StringTypeTrait, TimeTypeTrait; - use EscapeTrait; - /** * @var string The name of the function to call */ @@ -83,14 +81,14 @@ final class Raw extends Procedure implements private array $parameters; /** - * @param string $functionName The name of the function to call - * @param AnyType ...$parameters The parameters to pass to the function call + * @param string $functionName The name of the function to call + * @param AnyType[] $parameters The parameters to pass to the function call * * @internal This method is not covered by the backwards compatibility guarantee of php-cypher-dsl */ - public function __construct(string $functionName, AnyType ...$parameters) + public function __construct(string $functionName, array $parameters) { - $this->functionName = self::escape($functionName); + $this->functionName = NameUtils::escape($functionName); $this->parameters = $parameters; } diff --git a/src/Expressions/Property.php b/src/Expressions/Property.php index 984438b7..895ed311 100644 --- a/src/Expressions/Property.php +++ b/src/Expressions/Property.php @@ -10,8 +10,6 @@ namespace WikibaseSolutions\CypherDSL\Expressions; use WikibaseSolutions\CypherDSL\Syntax\PropertyReplacement; -use WikibaseSolutions\CypherDSL\Traits\CastTrait; -use WikibaseSolutions\CypherDSL\Traits\EscapeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\ListTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\MapTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\BooleanTypeTrait; @@ -24,7 +22,6 @@ use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\PointTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\StringTypeTrait; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits\TimeTypeTrait; -use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; diff --git a/src/Patterns/Path.php b/src/Patterns/Path.php index 01f8bd0f..f3a53fe3 100644 --- a/src/Patterns/Path.php +++ b/src/Patterns/Path.php @@ -97,7 +97,7 @@ public function relationship(Relationship $relationship, Pattern $pattern): self public function relationshipTo(Pattern $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): self { return $this->relationship( - self::buildRelationship(Relationship::DIR_RIGHT, $type, $properties, $name), + self::buildRelationship(Direction::RIGHT, $type, $properties, $name), $pattern ); } @@ -108,7 +108,7 @@ public function relationshipTo(Pattern $pattern, ?string $type = null, MapType|a public function relationshipFrom(Pattern $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): self { return $this->relationship( - self::buildRelationship(Relationship::DIR_LEFT, $type, $properties, $name), + self::buildRelationship(Direction::LEFT, $type, $properties, $name), $pattern ); } @@ -119,7 +119,7 @@ public function relationshipFrom(Pattern $pattern, ?string $type = null, MapType public function relationshipUni(Pattern $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): self { return $this->relationship( - self::buildRelationship(Relationship::DIR_UNI, $type, $properties, $name), + self::buildRelationship(Direction::UNI, $type, $properties, $name), $pattern ); } @@ -173,12 +173,12 @@ public function toQuery(): string /** * Construct a new relationship from the given parameters. * - * @param string[] $direction The direction of the relationship (should be a Relationship::DIR_* constant) + * @param Direction $direction The direction of the relationship * @param null|string $type The type of the relationship * @param null|MapType|array $properties The properties to add to the relationship * @param null|string|Variable $name The name of the variable to which to assign this relationship */ - private static function buildRelationship(array $direction, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Relationship + private static function buildRelationship(Direction $direction, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Relationship { $relationship = new Relationship($direction); diff --git a/src/Query.php b/src/Query.php index 2e79f642..fbe1c202 100644 --- a/src/Query.php +++ b/src/Query.php @@ -10,6 +10,7 @@ namespace WikibaseSolutions\CypherDSL; use Closure; +use Stringable; use WikibaseSolutions\CypherDSL\Clauses\CallClause; use WikibaseSolutions\CypherDSL\Clauses\CallProcedureClause; use WikibaseSolutions\CypherDSL\Clauses\Clause; @@ -199,11 +200,11 @@ public static function variable(?string $variable = null): Variable * - Query::list() - For a list * - Query::map() - For a map * - * @param bool|float|int|array|string|null $literal The literal to construct + * @param bool|float|int|array|string|Stringable|null $literal The literal to construct * * @return Boolean|class-string|Float_|Integer|List_|Map|String_ */ - public static function literal(null|bool|float|int|array|string $literal = null): Boolean|Float_|Integer|List_|Map|String_|string + public static function literal(null|bool|float|int|array|string|Stringable $literal = null): Boolean|Float_|Integer|List_|Map|String_|string { if ($literal === null) { return self::literal; @@ -360,8 +361,12 @@ public function __toString(): string * * @see https://neo4j.com/docs/cypher-manual/current/clauses/call-subquery/ Corresponding documentation on Neo4j.com */ - public function call(Query|callable $query, Pattern|Variable|string ...$variables): self + public function call(Query|callable $query, Pattern|Variable|string|array $variables = []): self { + if (!is_array($variables)) { + $variables = [$variables]; + } + if (is_callable($query)) { $subQuery = self::new(); $query($subQuery); @@ -719,7 +724,7 @@ public function with(mixed $expressions): self $expressions = [$expressions]; } - $expressions = $this->makeAliasArray($expressions, fn ($value) => $this->toAnyType($value)); + $expressions = $this->makeAliasArray($expressions, fn ($value) => CastUtils::toAnyType($value)); $withClause = new WithClause(); $withClause->addEntry(...$expressions); diff --git a/src/Utils/CastUtils.php b/src/Utils/CastUtils.php index 14299536..65cff2b5 100644 --- a/src/Utils/CastUtils.php +++ b/src/Utils/CastUtils.php @@ -91,7 +91,7 @@ public static function toStructuralType(StructuralType|Pattern $structure): Stru /** * Casts the given value to a Variable. * - * @see CastTrait::toName() for a function that does not accept Pattern + * @see CastUtils::toName() for a function that does not accept Pattern */ public static function toVariable(Variable|Pattern|string $variable): Variable { @@ -109,7 +109,7 @@ public static function toVariable(Variable|Pattern|string $variable): Variable /** * Casts the given value to a name. * - * @see CastTrait::toVariable() for a function that accepts Pattern + * @see CastUtils::toVariable() for a function that accepts Pattern */ public static function toName(Variable|string $name): Variable { diff --git a/src/functions.php b/src/functions.php index 1e95186d..7dd49553 100644 --- a/src/functions.php +++ b/src/functions.php @@ -9,17 +9,18 @@ */ namespace WikibaseSolutions\CypherDSL; +use Stringable; use WikibaseSolutions\CypherDSL\Expressions\Literals\Boolean; use WikibaseSolutions\CypherDSL\Expressions\Literals\Float_; use WikibaseSolutions\CypherDSL\Expressions\Literals\Integer; use WikibaseSolutions\CypherDSL\Expressions\Literals\List_; -use WikibaseSolutions\CypherDSL\Expressions\Literals\Literal; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; use WikibaseSolutions\CypherDSL\Expressions\Literals\String_; use WikibaseSolutions\CypherDSL\Expressions\Parameter; use WikibaseSolutions\CypherDSL\Expressions\Procedures\Procedure; use WikibaseSolutions\CypherDSL\Expressions\RawExpression; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Relationship; @@ -58,14 +59,11 @@ function node(?string $label = null): Node /** * Creates a relationship. * - * @param string[] $direction The direction of the relationship (optional, default: unidirectional), should be either: - * - Relationship::DIR_RIGHT (for a relation of (a)-->(b)) - * - Relationship::DIR_LEFT (for a relation of (a)<--(b)) - * - Relationship::DIR_UNI (for a relation of (a)--(b)) + * @param Direction $direction The direction of the relationship (optional, default: unidirectional) * * @see Query::relationship() */ -function relationship(array $direction = Relationship::DIR_UNI): Relationship +function relationship(Direction $direction = Direction::UNI): Relationship { return Query::relationship($direction); } @@ -160,11 +158,11 @@ function variable(?string $variable = null): Variable * - list_() - For a list * - map() - For a map * - * @param null|bool|float|int|array|string $literal The literal to construct + * @param null|bool|float|int|array|Stringable|string $literal The literal to construct * * @see Query::literal() */ -function literal(bool|float|int|array|string|null $literal = null): Boolean|Float_|List_|String_|Integer|string|Map +function literal(bool|float|int|array|string|Stringable|null $literal = null): Boolean|Float_|List_|String_|Integer|string|Map { return Query::literal($literal); } diff --git a/tests/unit/Clauses/MatchClauseTest.php b/tests/unit/Clauses/MatchClauseTest.php index bd0caa0e..0a42bcb0 100644 --- a/tests/unit/Clauses/MatchClauseTest.php +++ b/tests/unit/Clauses/MatchClauseTest.php @@ -12,7 +12,7 @@ use PHPUnit\Framework\TestCase; use TypeError; use WikibaseSolutions\CypherDSL\Clauses\MatchClause; -use WikibaseSolutions\CypherDSL\Patterns\Relationship; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Query; /** @@ -90,7 +90,7 @@ public function testAddPatternAcceptsAnyMatchablePattern(): void public function testAddPatternDoesNotAcceptRelationship(): void { - $rel = Query::relationship(Relationship::DIR_LEFT); + $rel = Query::relationship(Direction::LEFT); $match = new MatchClause(); diff --git a/tests/unit/Clauses/MergeClauseTest.php b/tests/unit/Clauses/MergeClauseTest.php index 3bb6f306..15e076ae 100644 --- a/tests/unit/Clauses/MergeClauseTest.php +++ b/tests/unit/Clauses/MergeClauseTest.php @@ -13,6 +13,7 @@ use TypeError; use WikibaseSolutions\CypherDSL\Clauses\MergeClause; use WikibaseSolutions\CypherDSL\Clauses\SetClause; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Relationship; use WikibaseSolutions\CypherDSL\Query; @@ -108,7 +109,7 @@ public function testSetOnBoth(): void public function testSetPatternDoesNotAcceptRelationship(): void { - $relationship = Query::relationship(Relationship::DIR_RIGHT); + $relationship = Query::relationship(Direction::RIGHT); $merge = new MergeClause(); diff --git a/tests/unit/Clauses/OptionalMatchTest.php b/tests/unit/Clauses/OptionalMatchTest.php index 9656a86c..7d58be84 100644 --- a/tests/unit/Clauses/OptionalMatchTest.php +++ b/tests/unit/Clauses/OptionalMatchTest.php @@ -13,6 +13,7 @@ use TypeError; use WikibaseSolutions\CypherDSL\Clauses\MatchClause; use WikibaseSolutions\CypherDSL\Clauses\OptionalMatchClause; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Relationship; use WikibaseSolutions\CypherDSL\Query; @@ -91,7 +92,7 @@ public function testAddPatternAcceptsAnyMatchablePattern(): void public function testAddPatternDoesNotAcceptRelationship(): void { - $rel = Query::relationship(Relationship::DIR_LEFT); + $rel = Query::relationship(Direction::LEFT); $match = new OptionalMatchClause(); diff --git a/tests/unit/Expressions/ExistsTest.php b/tests/unit/Expressions/ExistsTest.php index 5e70f891..99812c1e 100644 --- a/tests/unit/Expressions/ExistsTest.php +++ b/tests/unit/Expressions/ExistsTest.php @@ -17,6 +17,7 @@ use WikibaseSolutions\CypherDSL\Expressions\Operators\Equality; use WikibaseSolutions\CypherDSL\Expressions\Property; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Path; use WikibaseSolutions\CypherDSL\Patterns\Relationship; @@ -32,7 +33,7 @@ public function testToQuery(): void (new MatchClause)->addPattern( new Path( [(new Node)->withVariable('person'), (new Node('Dog'))->withVariable('dog')], - (new Relationship(Relationship::DIR_RIGHT))->addType('HAS_DOG') + (new Relationship(Direction::RIGHT))->addType('HAS_DOG') ) ) ); @@ -43,7 +44,7 @@ public function testToQuery(): void (new MatchClause)->addPattern( new Path( [(new Node)->withVariable('person'), (new Node('Dog'))->withVariable('dog')], - [(new Relationship(Relationship::DIR_RIGHT))->addType('HAS_DOG')] + [(new Relationship(Direction::RIGHT))->addType('HAS_DOG')] ) ), (new WhereClause)->addExpression( diff --git a/tests/unit/FunctionsTest.php b/tests/unit/FunctionsTest.php index d6c2a7eb..634d517c 100644 --- a/tests/unit/FunctionsTest.php +++ b/tests/unit/FunctionsTest.php @@ -21,6 +21,7 @@ use WikibaseSolutions\CypherDSL\Expressions\Procedures\Procedure; use WikibaseSolutions\CypherDSL\Expressions\RawExpression; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use function WikibaseSolutions\CypherDSL\float; use function WikibaseSolutions\CypherDSL\function_; use function WikibaseSolutions\CypherDSL\integer; @@ -77,7 +78,7 @@ public function testNodeOnlyAcceptsStringLabel(): void public function testRelationshipReturnsRelationship(): void { - $relationship = relationship(Relationship::DIR_RIGHT); + $relationship = relationship(Direction::RIGHT); $this->assertInstanceOf(Relationship::class, $relationship); $this->assertSame('-->', $relationship->toQuery()); diff --git a/tests/unit/Patterns/NodeTest.php b/tests/unit/Patterns/NodeTest.php index 85b71d72..dad8b1ae 100644 --- a/tests/unit/Patterns/NodeTest.php +++ b/tests/unit/Patterns/NodeTest.php @@ -18,6 +18,7 @@ use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; use WikibaseSolutions\CypherDSL\Expressions\Literals\String_; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Relationship; @@ -193,7 +194,7 @@ public function testGetProperties(): void public function testRelationship(): void { $node = new Node("City"); - $relationship = new Relationship(Relationship::DIR_RIGHT); + $relationship = new Relationship(Direction::RIGHT); $relationship->addType("LIVES_IN"); $amsterdam = new Node("City"); diff --git a/tests/unit/Patterns/PathTest.php b/tests/unit/Patterns/PathTest.php index 63989de2..0a5d59a1 100644 --- a/tests/unit/Patterns/PathTest.php +++ b/tests/unit/Patterns/PathTest.php @@ -10,6 +10,7 @@ namespace WikibaseSolutions\CypherDSL\Tests\Unit\Patterns; use PHPUnit\Framework\TestCase; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Path; use WikibaseSolutions\CypherDSL\Patterns\Relationship; @@ -22,7 +23,7 @@ public function testEmpty(): void $this->assertEquals('', (new Path())->toQuery()); $this->assertEquals('', (new Path([], []))->toQuery()); $this->assertEquals('', (new Path([], []))->toQuery()); - $this->assertEquals('', (new Path([], [new Relationship(Relationship::DIR_UNI)]))->toQuery()); + $this->assertEquals('', (new Path([], [new Relationship(Direction::UNI)]))->toQuery()); } public function testSingleNode(): void @@ -42,7 +43,7 @@ public function testSingleNodeNamed(): void public function testSingle(): void { - $path = new Path(new Node(), new Relationship(Relationship::DIR_UNI)); + $path = new Path(new Node(), new Relationship(Direction::UNI)); $this->assertEquals('()', $path->toQuery()); } @@ -56,8 +57,8 @@ public function testSingleNoRel(): void public function testPathMerge(): void { - $pathX = new Path([new Node(), new Node()], [new Relationship(Relationship::DIR_UNI)]); - $pathY = new Path([new Node(), new Node()], [new Relationship(Relationship::DIR_UNI)]); + $pathX = new Path([new Node(), new Node()], [new Relationship(Direction::UNI)]); + $pathY = new Path([new Node(), new Node()], [new Relationship(Direction::UNI)]); $pathX->withVariable('x')->relationshipTo($pathY->withVariable('y')); @@ -68,7 +69,7 @@ public function testPathFewerNodes(): void { $path = new Path( new Node, - [new Relationship(Relationship::DIR_UNI), new Relationship(Relationship::DIR_UNI)] + [new Relationship(Direction::UNI), new Relationship(Direction::UNI)] ); $this->assertSame('()', $path->toQuery()); } @@ -79,7 +80,7 @@ public function testRelationshipLong(): void $path->relationshipUni(new Node('Label')) ->relationshipTo((new Node())->withVariable('b')) ->relationshipFrom(new Node(), 'TYPE', ['x' => Query::literal('y')], 'c') - ->relationship(new Relationship(Relationship::DIR_UNI), (new Node())->withVariable('d')) + ->relationship(new Relationship(Direction::UNI), (new Node())->withVariable('d')) ->withVariable('a'); $this->assertEquals('a = ()--(:Label)-->(b)<-[c:TYPE {x: \'y\'}]-()--(d)', $path->toQuery()); @@ -93,20 +94,20 @@ public function testRelationshipLong(): void ], $path->getNodes()); $this->assertEquals([ - new Relationship(Relationship::DIR_UNI), - new Relationship(Relationship::DIR_RIGHT), - (new Relationship(Relationship::DIR_LEFT)) + new Relationship(Direction::UNI), + new Relationship(Direction::RIGHT), + (new Relationship(Direction::LEFT)) ->addType('TYPE') ->addProperties(['x' => Query::literal('y')]) ->withVariable('c'), - new Relationship(Relationship::DIR_UNI), + new Relationship(Direction::UNI), ], $path->getRelationships()); } public function testPathCanBeTreatedAsBoolean(): void { - $pathA = new Path([new Node(), new Node()], [new Relationship(Relationship::DIR_UNI)]); - $pathB = new Path([new Node(), new Node()], [new Relationship(Relationship::DIR_RIGHT)]); + $pathA = new Path([new Node(), new Node()], [new Relationship(Direction::UNI)]); + $pathB = new Path([new Node(), new Node()], [new Relationship(Direction::RIGHT)]); $this->assertSame("()--() AND ()-->()", $pathA->and($pathB, false)->toQuery()); } diff --git a/tests/unit/Patterns/RelationshipTest.php b/tests/unit/Patterns/RelationshipTest.php index ed80db63..9d16f78a 100644 --- a/tests/unit/Patterns/RelationshipTest.php +++ b/tests/unit/Patterns/RelationshipTest.php @@ -16,6 +16,7 @@ use WikibaseSolutions\CypherDSL\Expressions\Literals\Integer; use WikibaseSolutions\CypherDSL\Expressions\Literals\String_; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Relationship; use WikibaseSolutions\CypherDSL\Query; @@ -24,29 +25,23 @@ */ final class RelationshipTest extends TestCase { - public function testExceptionIsThrownWhenInvalidDirection(): void - { - $this->expectException(InvalidArgumentException::class); - $r = new Relationship(['--', '--']); - } - public function testDirRight(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $this->assertSame("-->", $r->toQuery()); } public function testDirLeft(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $this->assertSame("<--", $r->toQuery()); } public function testDirUni(): void { - $r = new Relationship(Relationship::DIR_UNI); + $r = new Relationship(Direction::UNI); $this->assertSame("--", $r->toQuery()); } @@ -54,7 +49,7 @@ public function testDirUni(): void /** * @dataProvider provideWithNameData */ - public function testWithName(string $name, array $direction, string $expected): void + public function testWithName(string $name, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withVariable($name); @@ -65,7 +60,7 @@ public function testWithName(string $name, array $direction, string $expected): /** * @dataProvider provideAddTypeData */ - public function testAddType(string $type, array $direction, string $expected): void + public function testAddType(string $type, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->addType($type); @@ -75,7 +70,7 @@ public function testAddType(string $type, array $direction, string $expected): v public function testAddTypeMultiple(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $r->addType("a"); $r->addType("b"); $r->addType(":"); @@ -86,7 +81,7 @@ public function testAddTypeMultiple(): void /** * @dataProvider provideWithTypesData */ - public function testWithTypes(array $types, array $direction, string $expected): void + public function testWithTypes(array $types, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withTypes($types); @@ -97,7 +92,7 @@ public function testWithTypes(array $types, array $direction, string $expected): /** * @dataProvider provideWithPropertiesData */ - public function testWithProperties(array $properties, array $direction, string $expected): void + public function testWithProperties(array $properties, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withProperties($properties); @@ -108,7 +103,7 @@ public function testWithProperties(array $properties, array $direction, string $ /** * @dataProvider provideWithNameAndTypeData */ - public function testWithNameAndType(string $name, string $type, array $direction, string $expected): void + public function testWithNameAndType(string $name, string $type, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withVariable($name)->addType($type); @@ -118,7 +113,7 @@ public function testWithNameAndType(string $name, string $type, array $direction public function testWithNameAndMultipleTypes(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $r->withVariable('a')->addType('a')->addType('b'); $this->assertSame('<-[a:a|b]-', $r->toQuery()); @@ -126,7 +121,7 @@ public function testWithNameAndMultipleTypes(): void public function testWithVariableActualVariable(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $r->withVariable(new Variable('a')); $this->assertSame('<-[a]-', $r->toQuery()); @@ -135,7 +130,7 @@ public function testWithVariableActualVariable(): void /** * @dataProvider provideWithNameAndPropertiesData */ - public function testWithNameAndProperties(string $name, array $properties, array $direction, string $expected): void + public function testWithNameAndProperties(string $name, array $properties, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withVariable($name)->withProperties($properties); @@ -146,7 +141,7 @@ public function testWithNameAndProperties(string $name, array $properties, array /** * @dataProvider provideWithNameAndTypeAndPropertiesData */ - public function testWithNameAndTypeAndProperties(string $name, string $type, array $properties, array $direction, string $expected): void + public function testWithNameAndTypeAndProperties(string $name, string $type, array $properties, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withVariable($name)->addType($type)->withProperties($properties); @@ -157,7 +152,7 @@ public function testWithNameAndTypeAndProperties(string $name, string $type, arr /** * @dataProvider provideWithMultipleTypesData */ - public function testWithMultipleTypes(string $name, array $types, array $properties, array $direction, string $expected): void + public function testWithMultipleTypes(string $name, array $types, array $properties, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withVariable($name)->withProperties($properties); @@ -172,7 +167,7 @@ public function testWithMultipleTypes(string $name, array $types, array $propert /** * @dataProvider provideVariableLengthRelationshipsWithNameData */ - public function testVariableLengthRelationshipsWithName(string $name, ?int $minHops, ?int $maxHops, array $direction, string $expected): void + public function testVariableLengthRelationshipsWithName(string $name, ?int $minHops, ?int $maxHops, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withVariable($name); @@ -191,7 +186,7 @@ public function testVariableLengthRelationshipsWithName(string $name, ?int $minH /** * @dataProvider provideVariableLengthRelationshipsWithTypeData */ - public function testVariableLengthRelationshipsWithType(string $type, ?int $minHops, ?int $maxHops, array $direction, string $expected): void + public function testVariableLengthRelationshipsWithType(string $type, ?int $minHops, ?int $maxHops, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->addType($type); @@ -210,7 +205,7 @@ public function testVariableLengthRelationshipsWithType(string $type, ?int $minH /** * @dataProvider provideVariableLengthRelationshipsWithPropertiesData */ - public function testVariableLengthRelationshipsWithProperties(array $properties, ?int $minHops, ?int $maxHops, array $direction, string $expected): void + public function testVariableLengthRelationshipsWithProperties(array $properties, ?int $minHops, ?int $maxHops, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withProperties($properties); @@ -229,7 +224,7 @@ public function testVariableLengthRelationshipsWithProperties(array $properties, /** * @dataProvider provideVariableLengthRelationshipsWithNameAndTypeAndPropertiesData */ - public function testVariableLengthRelationshipsWithNameAndTypeAndProperties(string $name, string $type, array $properties, ?int $minHops, ?int $maxHops, array $direction, string $expected): void + public function testVariableLengthRelationshipsWithNameAndTypeAndProperties(string $name, string $type, array $properties, ?int $minHops, ?int $maxHops, Direction $direction, string $expected): void { $r = new Relationship($direction); $r->withVariable($name)->addType($type)->withProperties($properties); @@ -247,7 +242,7 @@ public function testVariableLengthRelationshipsWithNameAndTypeAndProperties(stri public function testArbitraryHops(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $r->withVariable('hello')->addType('world')->addType('testing')->withProperties(['is' => 'a virtue']); $r->withArbitraryHops(); @@ -256,7 +251,7 @@ public function testArbitraryHops(): void public function testExactLengthRelationships(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withVariable("tom") ->addType("Person") ->withProperties(['name' => 'Tom Hanks']); @@ -268,7 +263,7 @@ public function testExactLengthRelationships(): void public function testMinAndExactHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withMinHops(1); $this->expectException(LogicException::class); @@ -278,7 +273,7 @@ public function testMinAndExactHops(): void public function testMaxAndExactHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withMaxHops(1); $this->expectException(LogicException::class); @@ -288,7 +283,7 @@ public function testMaxAndExactHops(): void public function testMinMaxAndExactHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withMinHops(1); $r->withMaxHops(1); @@ -299,7 +294,7 @@ public function testMinMaxAndExactHops(): void public function testExactAndMinHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withExactHops(1); $this->expectException(LogicException::class); @@ -309,7 +304,7 @@ public function testExactAndMinHops(): void public function testExactAndMaxHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withExactHops(1); $this->expectException(LogicException::class); @@ -319,7 +314,7 @@ public function testExactAndMaxHops(): void public function testMaxHopsLessThanMinHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withMinHops(100); $this->expectException(DomainException::class); @@ -329,7 +324,7 @@ public function testMaxHopsLessThanMinHops(): void public function testMinHopsGreaterThanMaxHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withMaxHops(1); $this->expectException(DomainException::class); @@ -339,7 +334,7 @@ public function testMinHopsGreaterThanMaxHops(): void public function testMinHopsLessThanZero(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $this->expectException(DomainException::class); @@ -348,7 +343,7 @@ public function testMinHopsLessThanZero(): void public function testMaxHopsLessThanOne(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $this->expectException(DomainException::class); @@ -357,7 +352,7 @@ public function testMaxHopsLessThanOne(): void public function testMaxHopsLessThanZero(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $this->expectException(DomainException::class); @@ -366,7 +361,7 @@ public function testMaxHopsLessThanZero(): void public function testExactHopsLessThanOne(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $this->expectException(DomainException::class); @@ -375,7 +370,7 @@ public function testExactHopsLessThanOne(): void public function testExactHopsLessThanZero(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $this->expectException(DomainException::class); @@ -384,7 +379,7 @@ public function testExactHopsLessThanZero(): void public function testExactHopsWithArbitraryHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withArbitraryHops(); $this->expectException(LogicException::class); @@ -394,7 +389,7 @@ public function testExactHopsWithArbitraryHops(): void public function testMinHopsWithArbitraryHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withArbitraryHops(); $this->expectException(LogicException::class); @@ -404,7 +399,7 @@ public function testMinHopsWithArbitraryHops(): void public function testMaxHopsWithArbitraryHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withArbitraryHops(); $this->expectException(LogicException::class); @@ -414,7 +409,7 @@ public function testMaxHopsWithArbitraryHops(): void public function testArbitraryHopsWithExactHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withExactHops(5); $this->expectException(LogicException::class); @@ -424,7 +419,7 @@ public function testArbitraryHopsWithExactHops(): void public function testArbitraryHopsWithMinHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withMinHops(5); $this->expectException(LogicException::class); @@ -434,7 +429,7 @@ public function testArbitraryHopsWithMinHops(): void public function testArbitraryHopsWithMaxHops(): void { - $r = new Relationship(Relationship::DIR_RIGHT); + $r = new Relationship(Direction::RIGHT); $r->withMaxHops(5); $this->expectException(LogicException::class); @@ -444,14 +439,14 @@ public function testArbitraryHopsWithMaxHops(): void public function testGetDirection(): void { - $r = new Relationship(Relationship::DIR_LEFT); - $this->assertSame(Relationship::DIR_LEFT, $r->getDirection()); + $r = new Relationship(Direction::LEFT); + $this->assertSame(Direction::LEFT, $r->getDirection()); } public function testGetProperties(): void { $properties = Query::map(['foo' => 'bar']); - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $this->assertNull($r->getProperties()); $r->withProperties($properties); @@ -461,7 +456,7 @@ public function testGetProperties(): void public function testGetExactHops(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $this->assertNull($r->getExactHops()); $r->withExactHops(12); @@ -471,7 +466,7 @@ public function testGetExactHops(): void public function testGetMaxHops(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $this->assertNull($r->getMaxHops()); $r->withMaxHops(12); @@ -481,7 +476,7 @@ public function testGetMaxHops(): void public function testGetMinHops(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $this->assertNull($r->getMinHops()); $r->withMinHops(12); @@ -491,7 +486,7 @@ public function testGetMinHops(): void public function testGetTypes(): void { - $r = new Relationship(Relationship::DIR_LEFT); + $r = new Relationship(Direction::LEFT); $this->assertEmpty($r->getTypes()); $r->withTypes(['a', 'b']); @@ -502,117 +497,117 @@ public function testGetTypes(): void public function provideVariableLengthRelationshipsWithNameData(): array { return [ - ['b', 0, 100, Relationship::DIR_UNI, '-[b*0..100]-'], - ['b', 5, 5, Relationship::DIR_RIGHT, '-[b*5..5]->'], - ['a', 10, null, Relationship::DIR_UNI, '-[a*10..]-'], - ['a', null, 10, Relationship::DIR_LEFT, '<-[a*..10]-'], + ['b', 0, 100, Direction::UNI, '-[b*0..100]-'], + ['b', 5, 5, Direction::RIGHT, '-[b*5..5]->'], + ['a', 10, null, Direction::UNI, '-[a*10..]-'], + ['a', null, 10, Direction::LEFT, '<-[a*..10]-'], ]; } public function provideVariableLengthRelationshipsWithTypeData(): array { return [ - ['', 1, 100, Relationship::DIR_LEFT, '<-[*1..100]-'], - ['a', 10, null, Relationship::DIR_LEFT, '<-[:a*10..]-'], - [':', null, 10, Relationship::DIR_LEFT, '<-[:`:`*..10]-'], + ['', 1, 100, Direction::LEFT, '<-[*1..100]-'], + ['a', 10, null, Direction::LEFT, '<-[:a*10..]-'], + [':', null, 10, Direction::LEFT, '<-[:`:`*..10]-'], ]; } public function provideVariableLengthRelationshipsWithPropertiesData(): array { return [ - [[], 10, 100, Relationship::DIR_LEFT, "<-[*10..100]-"], - [[new String_('a')], 10, null, Relationship::DIR_LEFT, "<-[*10.. {`0`: 'a'}]-"], - [['a' => new String_('b')], null, 10, Relationship::DIR_LEFT, "<-[*..10 {a: 'b'}]-"], + [[], 10, 100, Direction::LEFT, "<-[*10..100]-"], + [[new String_('a')], 10, null, Direction::LEFT, "<-[*10.. {`0`: 'a'}]-"], + [['a' => new String_('b')], null, 10, Direction::LEFT, "<-[*..10 {a: 'b'}]-"], ]; } public function provideVariableLengthRelationshipsWithNameAndTypeAndPropertiesData(): array { return [ - ['a', 'a', [], 10, 100, Relationship::DIR_LEFT, "<-[a:a*10..100]-"], - ['b', 'a', [new String_('a')], null, 10, Relationship::DIR_LEFT, "<-[b:a*..10 {`0`: 'a'}]-"], - ['a', 'b', [new String_('a')], 10, 100, Relationship::DIR_LEFT, "<-[a:b*10..100 {`0`: 'a'}]-"], - ['a', '', ['a' => new String_('b')], null, 10, Relationship::DIR_LEFT, "<-[a*..10 {a: 'b'}]-"], - ['a', ':', ['a' => new String_('b'), new String_('c')], 10, null, Relationship::DIR_LEFT, "<-[a:`:`*10.. {a: 'b', `0`: 'c'}]-"], + ['a', 'a', [], 10, 100, Direction::LEFT, "<-[a:a*10..100]-"], + ['b', 'a', [new String_('a')], null, 10, Direction::LEFT, "<-[b:a*..10 {`0`: 'a'}]-"], + ['a', 'b', [new String_('a')], 10, 100, Direction::LEFT, "<-[a:b*10..100 {`0`: 'a'}]-"], + ['a', '', ['a' => new String_('b')], null, 10, Direction::LEFT, "<-[a*..10 {a: 'b'}]-"], + ['a', ':', ['a' => new String_('b'), new String_('c')], 10, null, Direction::LEFT, "<-[a:`:`*10.. {a: 'b', `0`: 'c'}]-"], ]; } public function provideWithNameData(): array { return [ - ['a', Relationship::DIR_UNI, '-[a]-'], - ['a', Relationship::DIR_LEFT, '<-[a]-'], - ['a', Relationship::DIR_RIGHT, '-[a]->'], + ['a', Direction::UNI, '-[a]-'], + ['a', Direction::LEFT, '<-[a]-'], + ['a', Direction::RIGHT, '-[a]->'], ]; } public function provideAddTypeData(): array { return [ - ['', Relationship::DIR_LEFT, '<--'], - ['a', Relationship::DIR_LEFT, '<-[:a]-'], - [':', Relationship::DIR_LEFT, '<-[:`:`]-'], + ['', Direction::LEFT, '<--'], + ['a', Direction::LEFT, '<-[:a]-'], + [':', Direction::LEFT, '<-[:`:`]-'], ]; } public function provideWithTypesData(): array { return [ - [['', 'a'], Relationship::DIR_LEFT, '<-[:a]-'], - [['a', 'b'], Relationship::DIR_LEFT, '<-[:a|b]-'], - [['', 'a', 'b'], Relationship::DIR_LEFT, '<-[:a|b]-'], - [['a', '', 'b'], Relationship::DIR_LEFT, '<-[:a|b]-'], - [['a', 'b', ':'], Relationship::DIR_LEFT, '<-[:a|b|`:`]-'], + [['', 'a'], Direction::LEFT, '<-[:a]-'], + [['a', 'b'], Direction::LEFT, '<-[:a|b]-'], + [['', 'a', 'b'], Direction::LEFT, '<-[:a|b]-'], + [['a', '', 'b'], Direction::LEFT, '<-[:a|b]-'], + [['a', 'b', ':'], Direction::LEFT, '<-[:a|b|`:`]-'], ]; } public function provideWithPropertiesData(): array { return [ - [[], Relationship::DIR_LEFT, "<--"], - [[new String_('a')], Relationship::DIR_LEFT, "<-[{`0`: 'a'}]-"], - [['a' => new String_('b')], Relationship::DIR_LEFT, "<-[{a: 'b'}]-"], - [['a' => new String_('b'), new String_('c')], Relationship::DIR_LEFT, "<-[{a: 'b', `0`: 'c'}]-"], - [[':' => new Integer(12)], Relationship::DIR_LEFT, "<-[{`:`: 12}]-"], - [['a' => 'b', 'c' => 12, 'd' => 12.38], Relationship::DIR_LEFT, "<-[{a: 'b', c: 12, d: 12.38}]-"], + [[], Direction::LEFT, "<--"], + [[new String_('a')], Direction::LEFT, "<-[{`0`: 'a'}]-"], + [['a' => new String_('b')], Direction::LEFT, "<-[{a: 'b'}]-"], + [['a' => new String_('b'), new String_('c')], Direction::LEFT, "<-[{a: 'b', `0`: 'c'}]-"], + [[':' => new Integer(12)], Direction::LEFT, "<-[{`:`: 12}]-"], + [['a' => 'b', 'c' => 12, 'd' => 12.38], Direction::LEFT, "<-[{a: 'b', c: 12, d: 12.38}]-"], ]; } public function provideWithNameAndTypeData(): array { return [ - ['a', '', Relationship::DIR_LEFT, '<-[a]-'], - ['a', 'b', Relationship::DIR_LEFT, '<-[a:b]-'], + ['a', '', Direction::LEFT, '<-[a]-'], + ['a', 'b', Direction::LEFT, '<-[a:b]-'], ]; } public function provideWithNameAndPropertiesData(): array { return [ - ['a', [], Relationship::DIR_LEFT, "<-[a]-"], - ['b', [new String_('a')], Relationship::DIR_LEFT, "<-[b {`0`: 'a'}]-"], + ['a', [], Direction::LEFT, "<-[a]-"], + ['b', [new String_('a')], Direction::LEFT, "<-[b {`0`: 'a'}]-"], ]; } public function provideWithNameAndTypeAndPropertiesData(): array { return [ - ['a', 'a', [], Relationship::DIR_LEFT, "<-[a:a]-"], - ['b', 'a', [new String_('a')], Relationship::DIR_LEFT, "<-[b:a {`0`: 'a'}]-"], - ['a', 'b', [new String_('a')], Relationship::DIR_LEFT, "<-[a:b {`0`: 'a'}]-"], - ['a', '', ['a' => new String_('b')], Relationship::DIR_LEFT, "<-[a {a: 'b'}]-"], - ['a', ':', ['a' => new String_('b'), new String_('c')], Relationship::DIR_LEFT, "<-[a:`:` {a: 'b', `0`: 'c'}]-"], + ['a', 'a', [], Direction::LEFT, "<-[a:a]-"], + ['b', 'a', [new String_('a')], Direction::LEFT, "<-[b:a {`0`: 'a'}]-"], + ['a', 'b', [new String_('a')], Direction::LEFT, "<-[a:b {`0`: 'a'}]-"], + ['a', '', ['a' => new String_('b')], Direction::LEFT, "<-[a {a: 'b'}]-"], + ['a', ':', ['a' => new String_('b'), new String_('c')], Direction::LEFT, "<-[a:`:` {a: 'b', `0`: 'c'}]-"], ]; } public function provideWithMultipleTypesData(): array { return [ - ['a', [], [], Relationship::DIR_LEFT, "<-[a]-"], - ['b', ['a'], [new String_('a')], Relationship::DIR_LEFT, "<-[b:a {`0`: 'a'}]-"], - ['a', ['a', 'b', 'c'], [new String_('a')], Relationship::DIR_LEFT, "<-[a:a|b|c {`0`: 'a'}]-"], - ['a', ['a', 'b'], [], Relationship::DIR_LEFT, "<-[a:a|b]-"], + ['a', [], [], Direction::LEFT, "<-[a]-"], + ['b', ['a'], [new String_('a')], Direction::LEFT, "<-[b:a {`0`: 'a'}]-"], + ['a', ['a', 'b', 'c'], [new String_('a')], Direction::LEFT, "<-[a:a|b|c {`0`: 'a'}]-"], + ['a', ['a', 'b'], [], Direction::LEFT, "<-[a:a|b]-"], ]; } } diff --git a/tests/unit/QueryCreateTest.php b/tests/unit/QueryCreateTest.php index c46ecb1c..58e141f4 100644 --- a/tests/unit/QueryCreateTest.php +++ b/tests/unit/QueryCreateTest.php @@ -11,6 +11,7 @@ use PHPUnit\Framework\TestCase; use TypeError; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Relationship; use WikibaseSolutions\CypherDSL\Query; @@ -42,7 +43,7 @@ public function testCreateMultiplePatterns(): void public function testDoesNotAcceptRelationship(): void { - $rel = Query::relationship(Relationship::DIR_RIGHT); + $rel = Query::relationship(Direction::RIGHT); $this->expectException(TypeError::class); diff --git a/tests/unit/QueryMatchTest.php b/tests/unit/QueryMatchTest.php index 14ba6a15..65667d6a 100644 --- a/tests/unit/QueryMatchTest.php +++ b/tests/unit/QueryMatchTest.php @@ -11,6 +11,7 @@ use PHPUnit\Framework\TestCase; use TypeError; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Relationship; use WikibaseSolutions\CypherDSL\Query; @@ -36,7 +37,7 @@ public function testClause(): void public function testDoesNotAcceptRelationship(): void { - $r = Query::relationship(Relationship::DIR_LEFT); + $r = Query::relationship(Direction::LEFT); $this->expectException(TypeError::class); @@ -46,7 +47,7 @@ public function testDoesNotAcceptRelationship(): void public function testDoesNotAcceptRelationshipWithNode(): void { - $r = Query::relationship(Relationship::DIR_LEFT); + $r = Query::relationship(Direction::LEFT); $m = Query::node(); $this->expectException(TypeError::class); diff --git a/tests/unit/QueryOptionalMatchTest.php b/tests/unit/QueryOptionalMatchTest.php index ccfa6a5c..25268b58 100644 --- a/tests/unit/QueryOptionalMatchTest.php +++ b/tests/unit/QueryOptionalMatchTest.php @@ -11,6 +11,7 @@ use PHPUnit\Framework\TestCase; use TypeError; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Relationship; use WikibaseSolutions\CypherDSL\Query; @@ -36,7 +37,7 @@ public function testClause(): void public function testDoesNotAcceptRelationship(): void { - $r = Query::relationship(Relationship::DIR_LEFT); + $r = Query::relationship(Direction::LEFT); $this->expectException(TypeError::class); @@ -46,7 +47,7 @@ public function testDoesNotAcceptRelationship(): void public function testDoesNotAcceptRelationshipWithNode(): void { - $r = Query::relationship(Relationship::DIR_LEFT); + $r = Query::relationship(Direction::UNI); $m = Query::node(); $this->expectException(TypeError::class); diff --git a/tests/unit/QueryTest.php b/tests/unit/QueryTest.php index a3fec160..88ff4513 100644 --- a/tests/unit/QueryTest.php +++ b/tests/unit/QueryTest.php @@ -30,6 +30,7 @@ use WikibaseSolutions\CypherDSL\Expressions\Property; use WikibaseSolutions\CypherDSL\Expressions\RawExpression; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\Direction; use WikibaseSolutions\CypherDSL\Patterns\Node; use WikibaseSolutions\CypherDSL\Patterns\Path; use WikibaseSolutions\CypherDSL\Patterns\Relationship; @@ -80,7 +81,7 @@ public function testNodeWithLabel(): void public function testRelationship(): void { - $directions = [Relationship::DIR_UNI, Relationship::DIR_LEFT, Relationship::DIR_RIGHT]; + $directions = [Direction::UNI, Direction::LEFT, Direction::RIGHT]; foreach ($directions as $direction) { $expected = new Relationship($direction); @@ -90,13 +91,6 @@ public function testRelationship(): void } } - public function testInvalidRelationship(): void - { - $this->expectException(InvalidArgumentException::class); - - Query::relationship(['bad', 'value']); - } - public function testVariable(): void { $variable = Query::variable("foo"); @@ -291,7 +285,7 @@ public function testBuild(): void $variableMock = new Variable("a"); $nodeMock = (new Node)->withVariable($variableMock); - $pathMock = new Path([$nodeMock, (new Node)->withVariable('b')], [new Relationship(Relationship::DIR_RIGHT)]); + $pathMock = new Path([$nodeMock, (new Node)->withVariable('b')], [new Relationship(Direction::RIGHT)]); $numeralMock = new Integer(12); $booleanMock = new GreaterThan($variableMock, new Variable('b'), false); $propertyMock = new Property($variableMock, 'b'); diff --git a/tests/unit/Traits/CastTraitTest.php b/tests/unit/Traits/CastTraitTest.php deleted file mode 100644 index cc7c54d8..00000000 --- a/tests/unit/Traits/CastTraitTest.php +++ /dev/null @@ -1,193 +0,0 @@ -trait = new class - { - use CastTrait { - toListType as public; - toMapType as public; - toStringType as public; - toNumeralType as public; - toIntegerType as public; - toBooleanType as public; - toPropertyType as public; - toStructuralType as public; - toVariable as public; - toName as public; - toAnyType as public; - } - }; - } - - public function testToListType(): void - { - $list = $this->trait->toListType(['a', 'b', 'c']); - - $this->assertInstanceOf(ListType::class, $list); - - $list = Literal::list(['a', 'b', 'c']); - $list = $this->trait->toListType($list); - - $this->assertInstanceOf(ListType::class, $list); - } - - public function testToMapType(): void - { - $map = $this->trait->toMapType(['a' => 'a', 'b' => 'b', 'c' => 'c']); - - $this->assertInstanceOf(MapType::class, $map); - - $map = Literal::map(['a' => 'a', 'b' => 'b', 'c' => 'c']); - $map = $this->trait->toMapType($map); - - $this->assertInstanceOf(MapType::class, $map); - } - - public function testToStringType(): void - { - $string = $this->trait->toStringType('hello'); - - $this->assertInstanceOf(StringType::class, $string); - - $string = Literal::string('a'); - $string = $this->trait->toStringType($string); - - $this->assertInstanceOf(StringType::class, $string); - } - - public function testToNumeralType(): void - { - $numeral = $this->trait->toNumeralType(1); - - $this->assertInstanceOf(IntegerType::class, $numeral); - - $numeral = $this->trait->toNumeralType(1.1); - - $this->assertInstanceOf(FloatType::class, $numeral); - - $numeral = Literal::number(1.1); - $numeral = $this->trait->toNumeralType($numeral); - - $this->assertInstanceOf(FloatType::class, $numeral); - - $numeral = Literal::number(1); - $numeral = $this->trait->toNumeralType($numeral); - - $this->assertInstanceOf(IntegerType::class, $numeral); - } - - public function testToIntegerType(): void - { - $integer = $this->trait->toIntegerType(10); - - $this->assertInstanceOf(IntegerType::class, $integer); - - $integer = Literal::integer(10); - $integer = $this->trait->toIntegerType($integer); - - $this->assertInstanceOf(IntegerType::class, $integer); - } - - public function testToBooleanType(): void - { - $boolean = $this->trait->toBooleanType(true); - - $this->assertInstanceOf(BooleanType::class, $boolean); - - $boolean = Literal::boolean(true); - $boolean = $this->trait->toBooleanType($boolean); - - $this->assertInstanceOf(BooleanType::class, $boolean); - } - - public function testToPropertyType(): void - { - $property = $this->trait->toPropertyType('test'); - - $this->assertInstanceOf(StringType::class, $property); - - $property = $this->trait->toPropertyType(true); - - $this->assertInstanceOf(BooleanType::class, $property); - - $property = Literal::boolean(true); - $property = $this->trait->toBooleanType($property); - - $this->assertInstanceOf(BooleanType::class, $property); - } - - public function testToStructuralType(): void - { - $structural = $this->trait->toStructuralType(Query::node()); - - $this->assertInstanceOf(StructuralType::class, $structural); - - $structural = $this->trait->toStructuralType(Query::node()->getVariable()); - - $this->assertInstanceOf(StructuralType::class, $structural); - } - - public function testToVariable(): void - { - $variable = $this->trait->toVariable('a'); - - $this->assertInstanceOf(Variable::class, $variable); - - $variable = $this->trait->toVariable(Query::node()); - - $this->assertInstanceOf(Variable::class, $variable); - - $variable = $this->trait->toVariable(new Variable('a')); - - $this->assertInstanceOf(Variable::class, $variable); - } - - public function testToName(): void - { - $name = $this->trait->toName('a'); - - $this->assertInstanceOf(Variable::class, $name); - - $name = $this->trait->toName(new Variable('a')); - - $this->assertInstanceOf(Variable::class, $name); - } - - public function testToNameDoesNotAcceptPattern(): void - { - $this->expectException(TypeError::class); - - $this->trait->toName(Query::node()); - } -} diff --git a/tests/unit/Traits/ErrorTraitTest.php b/tests/unit/Traits/ErrorTraitTest.php deleted file mode 100644 index 023ba06f..00000000 --- a/tests/unit/Traits/ErrorTraitTest.php +++ /dev/null @@ -1,139 +0,0 @@ -errorImpl = new ErrorImpl(); - } - - /** - * @doesNotPerformAssertions - * @dataProvider CorrectAssertionsProvider - */ - public function testAssertClass($classNames, $userInput): void - { - $this->errorImpl->call('assertClass', ['foo', $classNames, $userInput]); - } - - /** - * @dataProvider failingAssertionsProvider - */ - public function testAssertClassFailure($classNames, $userInput): void - { - $this->expectException(TypeError::class); - $this->errorImpl->call('assertClass', ['foo', $classNames, $userInput]); - } - - public function correctAssertionsProvider(): array - { - return [ - [ErrorHelperDummyA::class, new ErrorHelperDummyA()], - [ErrorHelperDummyA::class, new ErrorHelperDummyExtendsA()], - [[ErrorHelperDummyA::class, ErrorHelperDummyB::class], new ErrorHelperDummyB()], - [[ErrorHelperDummyA::class, ErrorHelperDummyB::class], new ErrorHelperDummyExtendsB()], - ]; - } - - public function failingAssertionsProvider(): array - { - return [ - [ErrorHelperDummyA::class, new ErrorHelperDummyB()], - [ErrorHelperDummyExtendsA::class, new ErrorHelperDummyA()], - [[ErrorHelperDummyA::class, ErrorHelperDummyExtendsB::class], new ErrorHelperDummyB()], - ]; - } - - public function testGetTypeErrorText(): void - { - $this->assertEquals( - '$foo should be a WikibaseSolutions\CypherDSL\Tests\Unit\Traits\ErrorHelperDummyA, int given.', - $this->errorImpl->call('typeError', ['foo', [ErrorHelperDummyA::class], 5])->getMessage() - ); - $this->assertEquals( - '$foo should be a ' . - 'WikibaseSolutions\CypherDSL\Tests\Unit\Traits\ErrorHelperDummyA or ' . - 'WikibaseSolutions\CypherDSL\Tests\Unit\Traits\ErrorHelperDummyB, int given.', - $this->errorImpl->call('typeError', ['foo', [ErrorHelperDummyA::class, ErrorHelperDummyB::class], 5])->getMessage() - ); - } - - /** - * @dataProvider getUserInputInfoProvider - */ - public function testGetUserInputInfo($expected, $input): void - { - $this->assertEquals( - $expected, - $this->errorImpl->call('getDebugType', [$input]) - ); - } - - public function getUserInputInfoProvider(): array - { - return [ - ['string', 'foo'], - ['int', 5], - ['float', 3.14], - ['bool', true], - ['array', ['foo', 'bar']], - ['class@anonymous', new class() - { - }, ], - [ErrorHelperDummyA::class, new ErrorHelperDummyA()], - ]; - } -} diff --git a/tests/unit/Traits/EscapeTraitTest.php b/tests/unit/Traits/EscapeTraitTest.php deleted file mode 100644 index 15426a4a..00000000 --- a/tests/unit/Traits/EscapeTraitTest.php +++ /dev/null @@ -1,117 +0,0 @@ -trait = new class - { - use EscapeTrait { - escape as public; - } - }; - } - - /** - * @dataProvider provideSafeValueIsNotEscapedData - */ - public function testSafeValueIsNotEscaped(string $expected): void - { - $actual = $this->trait->escape($expected); - - $this->assertSame($expected, $actual); - } - - /** - * @dataProvider provideUnsafeValueIsEscapedData - */ - public function testUnsafeValueIsEscaped(string $value): void - { - $expected = sprintf("`%s`", $value); - $actual = $this->trait->escape($value); - - $this->assertSame($expected, $actual); - } - - /** - * @dataProvider provideValueWithBacktickIsProperlyEscapedData - */ - public function testValueWithBacktickIsProperlyEscaped($input, $expected): void - { - $this->assertSame('`foo``bar`', $this->trait->escape("foo`bar")); - } - - public function testValueWithMoreThan65534CharactersCannotBeEscaped(): void - { - $value = str_repeat('a', 65535); - - $this->expectException(InvalidArgumentException::class); - - $this->trait->escape($value); - } - - public function provideSafeValueIsNotEscapedData(): array - { - return [ - ['foobar'], - ['fooBar'], - ['FOOBAR'], - ['foo_bar'], - ['FOO_BAR'], - ['aaa'], - ['aaa100'], - ['a0'], - ['z10'], - ['z99'], - ['ça'], - ['日'], - ]; - } - - public function provideUnsafeValueIsEscapedData(): array - { - return [ - ['__FooBar__'], - ['_'], - ['__'], - ['\''], - ['"'], - ['0'], - ['10'], - ['100'], - ['1'], - ['2'], - ]; - } - - public function provideValueWithBacktickIsProperlyEscapedData(): array - { - return [ - ['foo`bar', '`foo``bar`'], - ['`foo', '```foo`'], - ['foo`', '`foo```'], - ['foo``bar', '`foo````bar`'], - ['`foo`', '```foo```'], - ]; - } -} diff --git a/tests/unit/Traits/NameGenerationTraitTest.php b/tests/unit/Traits/NameGenerationTraitTest.php deleted file mode 100644 index b76c33b7..00000000 --- a/tests/unit/Traits/NameGenerationTraitTest.php +++ /dev/null @@ -1,46 +0,0 @@ -trait = new class() - { - use NameGenerationTrait { - generateIdentifier as public; - } - }; - } - - public function testGenerateIdentifierWithoutPrefix(): void - { - $this->assertMatchesRegularExpression('/^var\w{32}$/', $this->trait->generateIdentifier()); - } - - public function testGenerateIdentifierWithPrefix(): void - { - $this->assertMatchesRegularExpression('/^x\w{32}$/', $this->trait->generateIdentifier('x')); - } - - public function testGenerateIdentifierWithPrefixAndLength(): void - { - $this->assertMatchesRegularExpression('/^x\w{16}$/', $this->trait->generateIdentifier('x', 16)); - } -} From dba664964dbb68e9e0c6b1f7a4b66419f0e30ed6 Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Tue, 3 Feb 2026 18:53:05 +0100 Subject: [PATCH 06/12] Update CHANGELOG and remove unnecessary doccomments --- CHANGELOG.md | 19 +++++++++++++++++-- src/Clauses/CallClause.php | 4 ---- src/Clauses/CallProcedureClause.php | 6 ------ src/Clauses/DeleteClause.php | 4 ---- src/Clauses/LimitClause.php | 4 ---- src/Clauses/MatchClause.php | 4 ---- src/Clauses/MergeClause.php | 4 ---- src/Clauses/OptionalMatchClause.php | 4 ---- src/Clauses/OrderByClause.php | 4 ---- src/Clauses/RemoveClause.php | 2 -- src/Clauses/ReturnClause.php | 4 ---- src/Clauses/SetClause.php | 2 -- src/Clauses/SkipClause.php | 2 -- src/Clauses/UnionClause.php | 2 -- src/Clauses/WithClause.php | 4 ---- src/Expressions/Procedures/Procedure.php | 4 ++-- src/Query.php | 2 +- 17 files changed, 20 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02043e3f..4788165c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,26 @@ file. A changelog has been kept from version 5.0.0 onwards. The format is based on [Keep a Changelog], and this project adheres to [Semantic Versioning]. -## 7.0.0 - 2026-02-03 +## 7.0.0 - T.B.D. + +### Added + +- Added the `Direction` enum to replace the `Relationship::DIR_*` constants. ### Changed -- T.B.D. +- Changed the minimum required PHP version to 8.1. +- Changed the signature of many functions to use PHP 8 union types. + +### Removed + +- Removed unnecessary dependency for the `openssl` PHP library. +- Removed `ErrorTrait` in favor of PHP 8.0 union types. +- Removed `CastTrait` in favor of the static functions in `CastUtils`. +- Removed `NameGenerationTrait` in favor of the static functions in `NameUtils`. +- Removed `EscapeTrait` in favor of the static functions in `NameUtils`. +- Removed `Relationship::DIR_UNI`, `Relationship::DIR_LEFT` and `Relationship::DIR_RIGHT` constants + in favor of the `Direction` enum. ## 6.0.0 - 2023-09-19 diff --git a/src/Clauses/CallClause.php b/src/Clauses/CallClause.php index 47df3856..50f380d1 100644 --- a/src/Clauses/CallClause.php +++ b/src/Clauses/CallClause.php @@ -52,10 +52,6 @@ public function withSubQuery(Query $subQuery): self /** * Add one or more variables to include in the WITH clause. * - * @param Pattern|string|Variable ...$variables - * - * @return $this - * * @see https://neo4j.com/docs/cypher-manual/current/clauses/call-subquery/#subquery-correlated-importing */ public function addWithVariable(...$variables): self diff --git a/src/Clauses/CallProcedureClause.php b/src/Clauses/CallProcedureClause.php index 8907e51f..9c34832b 100644 --- a/src/Clauses/CallProcedureClause.php +++ b/src/Clauses/CallProcedureClause.php @@ -39,8 +39,6 @@ final class CallProcedureClause extends Clause * Sets the procedure to call. * * @param Procedure $procedure The procedure to call - * - * @return $this */ public function setProcedure(Procedure $procedure): self { @@ -53,8 +51,6 @@ public function setProcedure(Procedure $procedure): self * Adds a variable to yield. * * @param Alias|string|Variable $yields The variable to yield - * - * @return $this */ public function addYield(...$yields): self { @@ -71,8 +67,6 @@ public function addYield(...$yields): self /** * Returns the procedure to call. - * - * @return Procedure|null */ public function getProcedure(): ?Procedure { diff --git a/src/Clauses/DeleteClause.php b/src/Clauses/DeleteClause.php index d5c580fa..b8aeff5b 100644 --- a/src/Clauses/DeleteClause.php +++ b/src/Clauses/DeleteClause.php @@ -40,8 +40,6 @@ final class DeleteClause extends Clause * all relationships connected to the nodes/paths need to be explicitly deleted. * * @param bool $detach Whether to use DETACH DELETE - * - * @return $this */ public function setDetach(bool $detach = true): self { @@ -54,8 +52,6 @@ public function setDetach(bool $detach = true): self * Add one or more structures to delete. * * @param Pattern|StructuralType $structures The structures to delete - * - * @return $this */ public function addStructure(...$structures): self { diff --git a/src/Clauses/LimitClause.php b/src/Clauses/LimitClause.php index b252f1fb..18b900aa 100644 --- a/src/Clauses/LimitClause.php +++ b/src/Clauses/LimitClause.php @@ -31,10 +31,6 @@ final class LimitClause extends Clause /** * Sets the expression that returns the limit. - * - * @param int|IntegerType $limit The limit - * - * @return $this */ public function setLimit(IntegerType|int $limit): self { diff --git a/src/Clauses/MatchClause.php b/src/Clauses/MatchClause.php index 48cfc80d..8615daed 100644 --- a/src/Clauses/MatchClause.php +++ b/src/Clauses/MatchClause.php @@ -29,10 +29,6 @@ final class MatchClause extends Clause /** * Add one or more patterns to the MATCH clause. - * - * @param CompletePattern ...$pattern - * - * @return $this */ public function addPattern(CompletePattern ...$pattern): self { diff --git a/src/Clauses/MergeClause.php b/src/Clauses/MergeClause.php index 6eb4dd07..6f002ef1 100644 --- a/src/Clauses/MergeClause.php +++ b/src/Clauses/MergeClause.php @@ -55,8 +55,6 @@ public function setPattern(CompletePattern $pattern): self * The clause to execute on all nodes that need to be created. * * @see https://neo4j.com/docs/cypher-manual/current/clauses/merge/#merge-merge-with-on-create - * - * @return $this */ public function setOnCreate(?SetClause $createClause): self { @@ -69,8 +67,6 @@ public function setOnCreate(?SetClause $createClause): self * The clause to execute on all found nodes. * * @see https://neo4j.com/docs/cypher-manual/current/clauses/merge/#merge-merge-with-on-match - * - * @return $this */ public function setOnMatch(?SetClause $matchClause): self { diff --git a/src/Clauses/OptionalMatchClause.php b/src/Clauses/OptionalMatchClause.php index fb297ac9..30d473a8 100644 --- a/src/Clauses/OptionalMatchClause.php +++ b/src/Clauses/OptionalMatchClause.php @@ -29,10 +29,6 @@ final class OptionalMatchClause extends Clause /** * Add one or more patterns to the OPTIONAL MATCH clause. - * - * @param CompletePattern ...$pattern - * - * @return $this */ public function addPattern(CompletePattern ...$pattern): self { diff --git a/src/Clauses/OrderByClause.php b/src/Clauses/OrderByClause.php index d36f3c74..91f4e970 100644 --- a/src/Clauses/OrderByClause.php +++ b/src/Clauses/OrderByClause.php @@ -40,8 +40,6 @@ final class OrderByClause extends Clause * Add one or more properties to sort on. * * @param Property ...$property The additional property to sort on - * - * @return OrderByClause */ public function addProperty(Property ...$property): self { @@ -52,8 +50,6 @@ public function addProperty(Property ...$property): self /** * Set to sort in a DESCENDING order. - * - * @return OrderByClause */ public function setDescending(bool $descending = true): self { diff --git a/src/Clauses/RemoveClause.php b/src/Clauses/RemoveClause.php index 88384f78..b28665ff 100644 --- a/src/Clauses/RemoveClause.php +++ b/src/Clauses/RemoveClause.php @@ -31,8 +31,6 @@ final class RemoveClause extends Clause * Add one or more expressions to the REMOVE clause. * * @param Label|Property ...$expressions The expressions to add - * - * @return RemoveClause */ public function addExpression(Property|Label ...$expressions): self { diff --git a/src/Clauses/ReturnClause.php b/src/Clauses/ReturnClause.php index 34e156e3..544febc8 100644 --- a/src/Clauses/ReturnClause.php +++ b/src/Clauses/ReturnClause.php @@ -39,8 +39,6 @@ final class ReturnClause extends Clause * * @param Alias|AnyType|bool|float|int|array|Pattern|string ...$columns The values to return * - * @return $this - * * @see https://neo4j.com/docs/cypher-manual/current/clauses/return/#return-column-alias */ public function addColumn(Alias|AnyType|bool|float|int|array|Pattern|string ...$columns): self @@ -59,8 +57,6 @@ public function addColumn(Alias|AnyType|bool|float|int|array|Pattern|string ...$ /** * Sets this query to only return unique rows. * - * @return $this - * * @see https://neo4j.com/docs/cypher-manual/current/clauses/return/#return-unique-results */ public function setDistinct(bool $distinct = true): self diff --git a/src/Clauses/SetClause.php b/src/Clauses/SetClause.php index 4249e057..19be1ca7 100644 --- a/src/Clauses/SetClause.php +++ b/src/Clauses/SetClause.php @@ -31,8 +31,6 @@ final class SetClause extends Clause * Add one or more expressions to this SET clause. * * @param Label|PropertyReplacement ...$expressions The expressions to add to this set clause - * - * @return $this */ public function add(Label|PropertyReplacement ...$expressions): self { diff --git a/src/Clauses/SkipClause.php b/src/Clauses/SkipClause.php index 2a50841c..3a7ae7b9 100644 --- a/src/Clauses/SkipClause.php +++ b/src/Clauses/SkipClause.php @@ -30,8 +30,6 @@ final class SkipClause extends Clause * Sets the expression that returns the skip. * * @param int|IntegerType $skip The amount to skip - * - * @return SkipClause */ public function setSkip(IntegerType|int $skip): self { diff --git a/src/Clauses/UnionClause.php b/src/Clauses/UnionClause.php index 79b99317..aaed2301 100644 --- a/src/Clauses/UnionClause.php +++ b/src/Clauses/UnionClause.php @@ -31,8 +31,6 @@ final class UnionClause extends Clause * Sets that the union should include all results, instead of removing duplicates. * * @param bool $all Whether the union should include all results or remove the duplicates instead - * - * @return static */ public function setAll(bool $all = true): self { diff --git a/src/Clauses/WithClause.php b/src/Clauses/WithClause.php index bb1f3d85..7332e4a2 100644 --- a/src/Clauses/WithClause.php +++ b/src/Clauses/WithClause.php @@ -35,10 +35,6 @@ final class WithClause extends Clause /** * Add one or more new entries to the WITH clause. - * - * @param Alias|Pattern|string|Variable ...$entries The entries to add - * - * @return $this */ public function addEntry(Alias|Pattern|string|Variable ...$entries): self { diff --git a/src/Expressions/Procedures/Procedure.php b/src/Expressions/Procedures/Procedure.php index 329c6386..11c3e496 100644 --- a/src/Expressions/Procedures/Procedure.php +++ b/src/Expressions/Procedures/Procedure.php @@ -31,9 +31,9 @@ abstract class Procedure implements QueryConvertible * Cypher queries. The parameters of this function are not type-checked. * * @param string $functionName The name of the function to call - * @param mixed ...$parameters The parameters to pass to the function call + * @param array $parameters The parameters to pass to the function call */ - public static function raw(string $functionName, mixed $parameters = []): Raw + public static function raw(string $functionName, array $parameters = []): Raw { return new Raw($functionName, array_map(CastUtils::toAnyType(...), $parameters)); } diff --git a/src/Query.php b/src/Query.php index fbe1c202..77c25a4e 100644 --- a/src/Query.php +++ b/src/Query.php @@ -355,7 +355,7 @@ public function __toString(): string * @note This feature is not part of the openCypher standard. * * @param callable|Query $query A callable decorating a Query, or an instance of Query - * @param Pattern|string|Variable ...$variables The variables to include in the WITH clause for correlation (optional) + * @param Pattern|string|Variable|(Pattern|string|Variable)[] $variables The variables to include in the WITH clause for correlation (optional) * * @return $this * From 3f616aff913e343bf202a9b5291bcad26100b976 Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Tue, 3 Feb 2026 18:54:51 +0100 Subject: [PATCH 07/12] Run php-cs-fixer --- CHANGELOG.md | 5 +- src/Clauses/CallClause.php | 1 - src/Clauses/ReturnClause.php | 2 +- src/Clauses/WhereClause.php | 2 + src/Expressions/Literals/List_.php | 2 +- src/Expressions/Literals/Literal.php | 66 +------------------ src/Expressions/Parameter.php | 1 - src/Expressions/Procedures/Procedure.php | 36 +++++----- src/Expressions/Procedures/Raw.php | 4 +- src/Expressions/Property.php | 2 - src/Expressions/Variable.php | 2 +- src/Patterns/CompletePattern.php | 2 +- src/Patterns/Direction.php | 19 ++++-- src/Patterns/Path.php | 2 +- src/Patterns/Pattern.php | 2 - src/Patterns/RelatablePattern.php | 6 +- src/Patterns/Relationship.php | 2 - src/Query.php | 19 +++--- src/Syntax/PropertyReplacement.php | 2 - .../PatternTraits/PropertyPatternTrait.php | 3 +- src/Types/AnyType.php | 14 ++-- src/Types/PropertyTypes/BooleanType.php | 6 +- src/Types/PropertyTypes/NumeralType.php | 12 ++-- src/Types/PropertyTypes/StringType.php | 8 +-- src/Utils/CastUtils.php | 13 +++- src/Utils/NameUtils.php | 15 +++-- src/functions.php | 2 +- tests/unit/Clauses/MergeClauseTest.php | 1 - tests/unit/Clauses/OptionalMatchTest.php | 1 - tests/unit/FunctionsTest.php | 2 +- tests/unit/Patterns/RelationshipTest.php | 1 - tests/unit/QueryCreateTest.php | 1 - tests/unit/QueryMatchTest.php | 1 - tests/unit/QueryOptionalMatchTest.php | 1 - tests/unit/QueryTest.php | 1 - tests/unit/Utils/CastUtilsTest.php | 14 ++-- tests/unit/Utils/NameUtilsTest.php | 14 ++-- 37 files changed, 117 insertions(+), 170 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4788165c..a2c22c50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,14 +8,11 @@ The format is based on [Keep a Changelog], and this project adheres to ## 7.0.0 - T.B.D. -### Added - -- Added the `Direction` enum to replace the `Relationship::DIR_*` constants. - ### Changed - Changed the minimum required PHP version to 8.1. - Changed the signature of many functions to use PHP 8 union types. +- Changed the `Relationship::DIR_*` to the `Direction` enum. ### Removed diff --git a/src/Clauses/CallClause.php b/src/Clauses/CallClause.php index 50f380d1..a5ad19fd 100644 --- a/src/Clauses/CallClause.php +++ b/src/Clauses/CallClause.php @@ -10,7 +10,6 @@ namespace WikibaseSolutions\CypherDSL\Clauses; use WikibaseSolutions\CypherDSL\Expressions\Variable; -use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\Query; use WikibaseSolutions\CypherDSL\Utils\CastUtils; diff --git a/src/Clauses/ReturnClause.php b/src/Clauses/ReturnClause.php index 544febc8..76986a33 100644 --- a/src/Clauses/ReturnClause.php +++ b/src/Clauses/ReturnClause.php @@ -37,7 +37,7 @@ final class ReturnClause extends Clause /** * Add a new column to this RETURN clause. * - * @param Alias|AnyType|bool|float|int|array|Pattern|string ...$columns The values to return + * @param Alias|AnyType|array|bool|float|int|Pattern|string ...$columns The values to return * * @see https://neo4j.com/docs/cypher-manual/current/clauses/return/#return-column-alias */ diff --git a/src/Clauses/WhereClause.php b/src/Clauses/WhereClause.php index 0ab8ae73..c634e27c 100644 --- a/src/Clauses/WhereClause.php +++ b/src/Clauses/WhereClause.php @@ -25,7 +25,9 @@ final class WhereClause extends Clause { public const AND = 'and'; + public const OR = 'or'; + public const XOR = 'xor'; /** diff --git a/src/Expressions/Literals/List_.php b/src/Expressions/Literals/List_.php index 679a5c4e..12a13bd0 100644 --- a/src/Expressions/Literals/List_.php +++ b/src/Expressions/Literals/List_.php @@ -45,7 +45,7 @@ public function __construct(array $expressions = []) /** * Add one or more expressions to the list. * - * @param AnyType|bool|float|int|array|Pattern|string ...$expressions + * @param AnyType|array|bool|float|int|Pattern|string ...$expressions * * @return $this */ diff --git a/src/Expressions/Literals/Literal.php b/src/Expressions/Literals/Literal.php index 4f7da655..de864f8f 100644 --- a/src/Expressions/Literals/Literal.php +++ b/src/Expressions/Literals/Literal.php @@ -37,8 +37,6 @@ final class Literal * @param mixed $literal The literal to construct * * @throws TypeError when the type could not be deduced - * - * @return Boolean|Float_|Integer|List_|Map|String_ */ public static function literal(string|bool|int|float|array|Stringable $literal): Boolean|Float_|Integer|List_|Map|String_ { @@ -73,10 +71,6 @@ public static function literal(string|bool|int|float|array|Stringable $literal): /** * Creates a new numeral literal. * - * @param float|int $value - * - * @return Float_|Integer - * * @see Literal::number() * @deprecated */ @@ -87,10 +81,6 @@ public static function decimal(float|int $value): Float_|Integer /** * Creates a new numeral literal. - * - * @param float|int $value - * - * @return Float_|Integer */ public static function number(float|int $value): Float_|Integer { @@ -150,8 +140,6 @@ public static function list(iterable $value): List_ /** * Creates a new map literal. - * - * @param array $value */ public static function map(array $value): Map { @@ -164,8 +152,6 @@ public static function map(array $value): Map * * @param null|string|StringType $timezone * - * @return Date - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-current Corresponding documentation on Neo4j.com */ public static function date(StringType|string|null $timezone = null): Date @@ -180,12 +166,9 @@ public static function date(StringType|string|null $timezone = null): Date /** * Creates a date from the given year, month and day. * - * @param int|NumeralType $year * @param null|int|NumeralType $month * @param null|int|NumeralType $day * - * @return Date - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-calendar Corresponding documentation on Neo4j.com */ public static function dateYMD(NumeralType|int $year, NumeralType|int|null $month = null, NumeralType|int|null $day = null): Date @@ -204,12 +187,9 @@ public static function dateYMD(NumeralType|int $year, NumeralType|int|null $mont /** * Creates a date from the given year, week and weekday. * - * @param int|NumeralType $year * @param null|int|NumeralType $week * @param null|int|NumeralType $weekday * - * @return Date - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-week Corresponding documentation on Neo4j.com */ public static function dateYWD(NumeralType|int $year, NumeralType|int|null $week = null, NumeralType|int|null $weekday = null): Date @@ -228,10 +208,6 @@ public static function dateYWD(NumeralType|int $year, NumeralType|int|null $week /** * Creates a date from the given string. * - * @param string|StringType $date - * - * @return Date - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-create-string Corresponding documentation on Neo4j.com */ public static function dateString(StringType|string $date): Date @@ -243,9 +219,7 @@ public static function dateString(StringType|string $date): Date * Retrieves the current DateTime value, optionally for a different time zone. In reality, this * function just returns a call to the "datetime()" function. * - * @param StringType|string|null $timezone - * - * @return DateTime + * @param null|string|StringType $timezone * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-current Corresponding documentation on Neo4j.com */ @@ -261,7 +235,6 @@ public static function dateTime(StringType|string|null $timezone = null): DateTi /** * Creates a date from the given year, month, day and time values. * - * @param int|NumeralType $year * @param null|int|NumeralType $month * @param null|int|NumeralType $day * @param null|int|NumeralType $hour @@ -307,7 +280,6 @@ public static function dateTimeYMD( /** * Creates a datetime with the specified year, week, dayOfWeek, hour, minute, second, millisecond, microsecond, nanosecond and timezone component values. * - * @param int|NumeralType $year * @param null|int|NumeralType $week * @param null|int|NumeralType $dayOfWeek * @param null|int|NumeralType $hour @@ -353,7 +325,6 @@ public static function dateTimeYWD( /** * Creates a datetime with the specified year, quarter, dayOfQuarter, hour, minute, second, millisecond, microsecond, nanosecond and timezone component values. * - * @param int|NumeralType $year * @param null|int|NumeralType $quarter * @param null|int|NumeralType $dayOfQuarter * @param null|int|NumeralType $hour @@ -399,7 +370,6 @@ public static function dateTimeYQD( /** * Creates a datetime with the specified year, ordinalDay, hour, minute, second, millisecond, microsecond, nanosecond and timezone component values. * - * @param int|NumeralType $year * @param null|int|NumeralType $ordinalDay * @param null|int|NumeralType $hour * @param null|int|NumeralType $minute @@ -441,8 +411,6 @@ public static function dateTimeYD( /** * Creates a datetime by parsing a string representation of a temporal value. - * - * @param string|StringType $dateString */ public static function dateTimeString(StringType|string $dateString): DateTime { @@ -468,7 +436,6 @@ public static function localDateTime(StringType|string|null $timezone = null): L /** * Creates a LocalDateTime value with specified year, month, day and time props. * - * @param int|NumeralType $year * @param null|int|NumeralType $month * @param null|int|NumeralType $day * @param null|int|NumeralType $hour @@ -512,7 +479,6 @@ public static function localDateTimeYMD( * Creates a LocalDateTime value with the specified year, week, dayOfWeek, hour, minute, * second, millisecond, microsecond and nanosecond component value. * - * @param int|NumeralType $year * @param null|int|NumeralType $week * @param null|int|NumeralType $dayOfWeek * @param null|int|NumeralType $hour @@ -522,8 +488,6 @@ public static function localDateTimeYMD( * @param null|int|NumeralType $microsecond * @param null|int|NumeralType $nanosecond * - * @return LocalDateTime - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-week Corresponding documentation on Neo4j.com */ public static function localDateTimeYWD( @@ -557,7 +521,6 @@ public static function localDateTimeYWD( /** * Creates a LocalDateTime value with the specified year, quarter, dayOfQuarter, hour, minute, second, millisecond, microsecond and nanosecond component values. * - * @param int|NumeralType $year * @param null|int|NumeralType $quarter * @param null|int|NumeralType $dayOfQuarter * @param null|int|NumeralType $hour @@ -600,7 +563,6 @@ public static function localDateTimeYQD( /** * Creates a LocalDateTime value with the specified year, ordinalDay, hour, minute, second, millisecond, microsecond and nanosecond component values. * - * @param int|NumeralType $year * @param null|int|NumeralType $ordinalDay * @param null|int|NumeralType $hour * @param null|int|NumeralType $minute @@ -640,8 +602,6 @@ public static function localDateTimeYD( /** * Creates the LocalDateTime value obtained by parsing a string representation of a temporal value. * - * @param string|StringType $localDateTimeString - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-create-string Corresponding documentation on Neo4j.com */ public static function localDateTimeString(StringType|string $localDateTimeString): LocalDateTime @@ -668,7 +628,6 @@ public static function localTimeCurrent(StringType|string|null $timezone = null) /** * Creates a LocalTime value with the specified hour, minute, second, millisecond, microsecond and nanosecond component values. * - * @param int|NumeralType $hour * @param null|int|NumeralType $minute * @param null|int|NumeralType $second * @param null|int|NumeralType $millisecond @@ -701,8 +660,6 @@ public static function localTime( /** * Creates the LocalTime value obtained by parsing a string representation of a temporal value. - * - * @param string|StringType $localTimeString */ public static function localTimeString(StringType|string $localTimeString): LocalTime { @@ -728,7 +685,6 @@ public static function time(StringType|string|null $timezone = null): Time /** * Creates a Time value with the specified hour, minute, second, millisecond, microsecond, nanosecond and timezone component values. * - * @param int|NumeralType $hour * @param null|int|NumeralType $minute * @param null|int|NumeralType $second * @param null|int|NumeralType $millisecond @@ -765,8 +721,6 @@ public static function timeHMS( /** * Creates the Time value obtained by parsing a string representation of a temporal value. * - * @param string|StringType $timeString - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-time-create-string Corresponding documentation on Neo4j.com */ public static function timeString(StringType|string $timeString): Time @@ -777,9 +731,6 @@ public static function timeString(StringType|string $timeString): Time /** * Creates a 2d cartesian point. * - * @param float|int|NumeralType $x - * @param float|int|NumeralType $y - * * @see https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-cartesian-2d Corresponding documentation on Neo4j.com */ public static function point2d(NumeralType|int|float $x, NumeralType|int|float $y): Point @@ -794,10 +745,6 @@ public static function point2d(NumeralType|int|float $x, NumeralType|int|float $ /** * Creates a 3d cartesian point. * - * @param float|int|NumeralType $x - * @param float|int|NumeralType $y - * @param float|int|NumeralType $z - * * @see https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-cartesian-3d Corresponding documentation on Neo4j.com */ public static function point3d(NumeralType|int|float $x, NumeralType|int|float $y, NumeralType|int|float $z): Point @@ -813,9 +760,6 @@ public static function point3d(NumeralType|int|float $x, NumeralType|int|float $ /** * Creates a WGS 84 2D point. * - * @param float|int|NumeralType $longitude - * @param float|int|NumeralType $latitude - * * @see https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-wgs84-2d Corresponding documentation on Neo4j.com */ public static function point2dWGS84(NumeralType|int|float $longitude, NumeralType|int|float $latitude): Point @@ -830,10 +774,6 @@ public static function point2dWGS84(NumeralType|int|float $longitude, NumeralTyp /** * Creates a WGS 84 2D point. * - * @param float|int|NumeralType $longitude - * @param float|int|NumeralType $latitude - * @param float|int|NumeralType $height - * * @see https://neo4j.com/docs/cypher-manual/current/functions/spatial/#functions-point-wgs84-2d Corresponding documentation on Neo4j.com */ public static function point3dWGS84(NumeralType|int|float $longitude, NumeralType|int|float $latitude, NumeralType|int|float $height): Point @@ -855,10 +795,6 @@ private function __construct() /** * Prepares the variables to be used by temporal (i.e. time-like) CYPHER-functions. - * - * @param array $variables - * - * @return array */ private static function makeTemporalMap(array $variables): array { diff --git a/src/Expressions/Parameter.php b/src/Expressions/Parameter.php index 54d4d09f..2ab2789b 100644 --- a/src/Expressions/Parameter.php +++ b/src/Expressions/Parameter.php @@ -66,7 +66,6 @@ final class Parameter implements PointTypeTrait, StringTypeTrait, TimeTypeTrait; - private string $parameter; /** diff --git a/src/Expressions/Procedures/Procedure.php b/src/Expressions/Procedures/Procedure.php index 11c3e496..8d12b4da 100644 --- a/src/Expressions/Procedures/Procedure.php +++ b/src/Expressions/Procedures/Procedure.php @@ -31,7 +31,7 @@ abstract class Procedure implements QueryConvertible * Cypher queries. The parameters of this function are not type-checked. * * @param string $functionName The name of the function to call - * @param array $parameters The parameters to pass to the function call + * @param array $parameters The parameters to pass to the function call */ public static function raw(string $functionName, array $parameters = []): Raw { @@ -42,8 +42,8 @@ public static function raw(string $functionName, array $parameters = []): Raw * Calls the "all()" function. The signature of the "all()" function is "all(variable :: VARIABLE IN list :: LIST OF ANY? WHERE predicate :: ANY?) :: (BOOLEAN?)". * * @param string|Variable $variable A variable that can be used from within the predicate - * @param ListType|array $list A list - * @param AnyType|bool|float|int|array|Pattern|string $predicate A predicate that is tested against all items in the list + * @param array|ListType $list A list + * @param AnyType|array|bool|float|int|Pattern|string $predicate A predicate that is tested against all items in the list */ public static function all(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): All { @@ -54,8 +54,8 @@ public static function all(Variable|string $variable, ListType|array $list, AnyT * Calls the "any()" function. The signature of the "any()" function is "any(variable :: VARIABLE IN list :: LIST OF ANY? WHERE predicate :: ANY?) :: (BOOLEAN?)". * * @param string|Variable $variable A variable that can be used from within the predicate - * @param ListType|array $list A list - * @param AnyType|bool|float|int|array|Pattern|string $predicate A predicate that is tested against all items in the list + * @param array|ListType $list A list + * @param AnyType|array|bool|float|int|Pattern|string $predicate A predicate that is tested against all items in the list */ public static function any(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): Any { @@ -65,7 +65,7 @@ public static function any(Variable|string $variable, ListType|array $list, AnyT /** * Calls the "exists()" function. The signature of the "exists()" function is "exists(input :: ANY?) :: (BOOLEAN?)". * - * @param AnyType|bool|float|int|array|Pattern|string $expression A pattern or property + * @param AnyType|array|bool|float|int|Pattern|string $expression A pattern or property */ public static function exists(AnyType|bool|float|int|array|Pattern|string $expression): Exists { @@ -78,9 +78,7 @@ public static function exists(AnyType|bool|float|int|array|Pattern|string $expre * - isEmpty(input :: MAP?) :: (BOOLEAN?) - to check whether a map is empty * - isEmpty(input :: STRING?) :: (BOOLEAN?) - to check whether a string is empty. * - * @param ListType|MapType|StringType|string|array $list An expression that returns a list - * - * @return IsEmpty + * @param array|ListType|MapType|string|StringType $list An expression that returns a list */ public static function isEmpty(ListType|MapType|StringType|string|array $list): IsEmpty { @@ -96,8 +94,8 @@ public static function isEmpty(ListType|MapType|StringType|string|array $list): * Calls the "none()" function. The signature of the "none()" function is "none(variable :: VARIABLE IN list :: LIST OF ANY? WHERE predicate :: ANY?) :: (BOOLEAN?)". * * @param string|Variable $variable A variable that can be used from within the predicate - * @param ListType|array $list A list - * @param AnyType|bool|float|int|array|Pattern|string $predicate A predicate that is tested against all items in the list + * @param array|ListType $list A list + * @param AnyType|array|bool|float|int|Pattern|string $predicate A predicate that is tested against all items in the list */ public static function none(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): None { @@ -108,8 +106,8 @@ public static function none(Variable|string $variable, ListType|array $list, Any * Calls the "single()" function. The signature of the "single()" function is "single(variable :: VARIABLE IN list :: LIST OF ANY? WHERE predicate :: ANY?) :: (BOOLEAN?)". * * @param string|Variable $variable A variable that can be used from within the predicate - * @param ListType|array $list A list - * @param AnyType|bool|float|int|array|Pattern|string $predicate A predicate that is tested against all items in the list + * @param array|ListType $list A list + * @param AnyType|array|bool|float|int|Pattern|string $predicate A predicate that is tested against all items in the list */ public static function single(Variable|string $variable, ListType|array $list, AnyType|bool|float|int|array|Pattern|string $predicate): Single { @@ -119,7 +117,7 @@ public static function single(Variable|string $variable, ListType|array $list, A /** * Calls the "point()" function. The signature of the "point()" function is "point(input :: MAP?) :: (POINT?)". * - * @param MapType|array $map The map to use for constructing the point + * @param array|MapType $map The map to use for constructing the point * * @see Literal::point2d() * @see Literal::point2dWGS84() @@ -134,7 +132,7 @@ public static function point(MapType|array $map): Point /** * Calls the "date()" function. The signature of the "date()" function is "date(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (DATE?)". * - * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the date function, from which to construct the date + * @param null|AnyType|array|bool|float|int|Pattern|string $value The input to the date function, from which to construct the date * * @see Literal::date() * @see Literal::dateString() @@ -149,7 +147,7 @@ public static function date(AnyType|bool|float|int|array|Pattern|string|null $va /** * Calls the "datetime()" function. The signature of the "datetime()" function is "datetime(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (DATETIME?)". * - * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the datetime function, from which to construct the datetime + * @param null|AnyType|array|bool|float|int|Pattern|string $value The input to the datetime function, from which to construct the datetime * * @see Literal::dateTime() * @see Literal::dateTimeString() @@ -166,7 +164,7 @@ public static function datetime(AnyType|bool|float|int|array|Pattern|string|null /** * Calls the "localdatetime()" function. The signature of the "localdatetime()" function is "datetime(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (LOCALDATETIME?)". * - * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the localdatetime function, from which to construct the localdatetime + * @param null|AnyType|array|bool|float|int|Pattern|string $value The input to the localdatetime function, from which to construct the localdatetime * * @see Literal::localDateTime() * @see Literal::localDateTimeString() @@ -183,7 +181,7 @@ public static function localdatetime(AnyType|bool|float|int|array|Pattern|string /** * Calls the "localtime()" function. The signature of the "localtime()" function is "localtime(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (LOCALTIME?)". * - * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the localtime function, from which to construct the localtime + * @param null|AnyType|array|bool|float|int|Pattern|string $value The input to the localtime function, from which to construct the localtime * * @see Literal::localTime() * @see Literal::localTimeCurrent() @@ -197,7 +195,7 @@ public static function localtime(AnyType|bool|float|int|array|Pattern|string|nul /** * Calls the "time()" function. The signature of the "time()" function is "time(input = DEFAULT_TEMPORAL_ARGUMENT :: ANY?) :: (TIME?)". * - * @param null|AnyType|bool|float|int|array|Pattern|string $value The input to the localtime function, from which to construct the time + * @param null|AnyType|array|bool|float|int|Pattern|string $value The input to the localtime function, from which to construct the time * * @see Literal::time() * @see Literal::timeHMS() diff --git a/src/Expressions/Procedures/Raw.php b/src/Expressions/Procedures/Raw.php index 962317cc..f3f9a859 100644 --- a/src/Expressions/Procedures/Raw.php +++ b/src/Expressions/Procedures/Raw.php @@ -81,8 +81,8 @@ final class Raw extends Procedure implements private array $parameters; /** - * @param string $functionName The name of the function to call - * @param AnyType[] $parameters The parameters to pass to the function call + * @param string $functionName The name of the function to call + * @param AnyType[] $parameters The parameters to pass to the function call * * @internal This method is not covered by the backwards compatibility guarantee of php-cypher-dsl */ diff --git a/src/Expressions/Property.php b/src/Expressions/Property.php index 895ed311..b97fdf82 100644 --- a/src/Expressions/Property.php +++ b/src/Expressions/Property.php @@ -122,8 +122,6 @@ public function getProperty(): string /** * Returns the expression to which the property belongs. - * - * @return MapType|NodeType|RelationshipType */ public function getExpression(): MapType|NodeType|RelationshipType { diff --git a/src/Expressions/Variable.php b/src/Expressions/Variable.php index 179330d5..4eaac110 100644 --- a/src/Expressions/Variable.php +++ b/src/Expressions/Variable.php @@ -116,7 +116,7 @@ public function labeled(string ...$labels): Label /** * Assign a value to this property. * - * @param Map|array $value The value to assign + * @param array|Map $value The value to assign */ public function assign(MapType|array $value): PropertyReplacement { diff --git a/src/Patterns/CompletePattern.php b/src/Patterns/CompletePattern.php index f8930ea6..5a968d7b 100644 --- a/src/Patterns/CompletePattern.php +++ b/src/Patterns/CompletePattern.php @@ -11,7 +11,7 @@ /** * Interface to mark patterns that are complete, i.e. can be matched by a MATCH clause or created by - * a CREATE clause. These are: + * a CREATE clause. These are:. * * - node * - path diff --git a/src/Patterns/Direction.php b/src/Patterns/Direction.php index 4132698f..6b7bf958 100644 --- a/src/Patterns/Direction.php +++ b/src/Patterns/Direction.php @@ -1,25 +1,32 @@ -(b). */ case RIGHT; - /** + /* * For the relation (a)<--(b). */ case LEFT; - /** + /* * For the relation (a)--(b). */ case UNI; diff --git a/src/Patterns/Path.php b/src/Patterns/Path.php index f3a53fe3..36c1714a 100644 --- a/src/Patterns/Path.php +++ b/src/Patterns/Path.php @@ -175,7 +175,7 @@ public function toQuery(): string * * @param Direction $direction The direction of the relationship * @param null|string $type The type of the relationship - * @param null|MapType|array $properties The properties to add to the relationship + * @param null|array|MapType $properties The properties to add to the relationship * @param null|string|Variable $name The name of the variable to which to assign this relationship */ private static function buildRelationship(Direction $direction, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Relationship diff --git a/src/Patterns/Pattern.php b/src/Patterns/Pattern.php index ae1ed6b3..0fe27291 100644 --- a/src/Patterns/Pattern.php +++ b/src/Patterns/Pattern.php @@ -43,8 +43,6 @@ public function hasVariableSet(): bool; /** * Explicitly assign a named variable to this pattern. * - * @param null|string|Variable $variable - * * @return $this */ public function withVariable(Variable|string|null $variable): self; diff --git a/src/Patterns/RelatablePattern.php b/src/Patterns/RelatablePattern.php index df85fc82..b61ec3ae 100644 --- a/src/Patterns/RelatablePattern.php +++ b/src/Patterns/RelatablePattern.php @@ -35,7 +35,7 @@ public function relationship(Relationship $relationship, self $pattern): Path; * * @param RelatablePattern $pattern The pattern to attach to the end of this pattern * @param null|string $type The type of the relationship - * @param null|MapType|array $properties The properties to attach to the relationship + * @param null|array|MapType $properties The properties to attach to the relationship * @param null|string|Variable $name The name fo the relationship */ public function relationshipTo(self $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Path; @@ -46,7 +46,7 @@ public function relationshipTo(self $pattern, ?string $type = null, MapType|arra * * @param RelatablePattern $pattern The pattern to attach to the end of this pattern * @param null|string $type The type of the relationship - * @param null|MapType|array $properties The properties to attach to the relationship + * @param null|array|MapType $properties The properties to attach to the relationship * @param null|string|Variable $name The name fo the relationship */ public function relationshipFrom(self $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Path; @@ -57,7 +57,7 @@ public function relationshipFrom(self $pattern, ?string $type = null, MapType|ar * * @param RelatablePattern $pattern The pattern to attach to the end of this pattern * @param null|string $type The type of the relationship - * @param null|MapType|array $properties The properties to attach to the relationship + * @param null|array|MapType $properties The properties to attach to the relationship * @param null|string|Variable $name The name fo the relationship */ public function relationshipUni(self $pattern, ?string $type = null, MapType|array|null $properties = null, Variable|string|null $name = null): Path; diff --git a/src/Patterns/Relationship.php b/src/Patterns/Relationship.php index e1387b43..d229ec68 100644 --- a/src/Patterns/Relationship.php +++ b/src/Patterns/Relationship.php @@ -184,8 +184,6 @@ public function addType(string ...$type): self /** * Returns the direction of this relationship (one of the Relationship::DIR_* constants). - * - * @return Direction */ public function getDirection(): Direction { diff --git a/src/Query.php b/src/Query.php index 77c25a4e..f764a5b5 100644 --- a/src/Query.php +++ b/src/Query.php @@ -9,7 +9,6 @@ */ namespace WikibaseSolutions\CypherDSL; -use Closure; use Stringable; use WikibaseSolutions\CypherDSL\Clauses\CallClause; use WikibaseSolutions\CypherDSL\Clauses\CallProcedureClause; @@ -200,7 +199,7 @@ public static function variable(?string $variable = null): Variable * - Query::list() - For a list * - Query::map() - For a map * - * @param bool|float|int|array|string|Stringable|null $literal The literal to construct + * @param null|array|bool|float|int|string|Stringable $literal The literal to construct * * @return Boolean|class-string|Float_|Integer|List_|Map|String_ */ @@ -361,7 +360,7 @@ public function __toString(): string * * @see https://neo4j.com/docs/cypher-manual/current/clauses/call-subquery/ Corresponding documentation on Neo4j.com */ - public function call(Query|callable $query, Pattern|Variable|string|array $variables = []): self + public function call(self|callable $query, Pattern|Variable|string|array $variables = []): self { if (!is_array($variables)) { $variables = [$variables]; @@ -387,7 +386,7 @@ public function call(Query|callable $query, Pattern|Variable|string|array $varia * Creates the CALL procedure clause. * * @param Procedure|string $procedure The procedure to call - * @param mixed $yields The result fields that should be returned (optional) + * @param mixed $yields The result fields that should be returned (optional) * * @return $this * @@ -403,7 +402,7 @@ public function callProcedure(Procedure|string $procedure, mixed $yields = []): $yields = [$yields]; } - $yields = $this->makeAliasArray($yields, fn ($value) => CastUtils::toName($value)); + $yields = $this->makeAliasArray($yields, static fn ($value) => CastUtils::toName($value)); $callProcedureClause = new CallProcedureClause(); $callProcedureClause->setProcedure($procedure); @@ -441,7 +440,7 @@ public function match(CompletePattern|array $patterns): self * Creates the RETURN clause. * * @param mixed $expressions A single expression to return, or a non-empty list of expressions to return - * @param bool $distinct Whether to be a RETURN DISTINCT clause (optional, default: false) + * @param bool $distinct Whether to be a RETURN DISTINCT clause (optional, default: false) * * @return $this * @@ -453,7 +452,7 @@ public function returning(mixed $expressions, bool $distinct = false): self $expressions = [$expressions]; } - $expressions = $this->makeAliasArray($expressions, fn ($value) => CastUtils::toAnyType($value)); + $expressions = $this->makeAliasArray($expressions, static fn ($value) => CastUtils::toAnyType($value)); $returnClause = new ReturnClause(); $returnClause->addColumn(...$expressions); @@ -724,7 +723,7 @@ public function with(mixed $expressions): self $expressions = [$expressions]; } - $expressions = $this->makeAliasArray($expressions, fn ($value) => CastUtils::toAnyType($value)); + $expressions = $this->makeAliasArray($expressions, static fn ($value) => CastUtils::toAnyType($value)); $withClause = new WithClause(); $withClause->addEntry(...$expressions); @@ -761,7 +760,7 @@ public function raw(string $clause, string $subject): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/union/ Corresponding documentation on Neo4j.com */ - public function union(Query|callable $queryOrCallable, bool $all = false): self + public function union(self|callable $queryOrCallable, bool $all = false): self { if (is_callable($queryOrCallable)) { $query = self::new(); @@ -835,7 +834,7 @@ public function toQuery(): string /** * Changes an associative array into an array of aliases. * - * @param array $values The array to change into an array of aliases + * @param array $values The array to change into an array of aliases * @param callable $castFunc Function to use to cast the elements of $array * * @return array A sequential array, possibly consisting of aliases diff --git a/src/Syntax/PropertyReplacement.php b/src/Syntax/PropertyReplacement.php index cc9014ff..b1085e80 100644 --- a/src/Syntax/PropertyReplacement.php +++ b/src/Syntax/PropertyReplacement.php @@ -74,8 +74,6 @@ public function mutates(): bool /** * Returns the name of the property to which we assign a (new) value. - * - * @return Property|Variable */ public function getProperty(): Property|Variable { diff --git a/src/Traits/PatternTraits/PropertyPatternTrait.php b/src/Traits/PatternTraits/PropertyPatternTrait.php index 1c51f477..4e9197a2 100644 --- a/src/Traits/PatternTraits/PropertyPatternTrait.php +++ b/src/Traits/PatternTraits/PropertyPatternTrait.php @@ -63,7 +63,8 @@ public function addProperties(MapType|array $properties): self $map = $this->makeMap(); if (is_array($properties)) { - $res = array_map(function ($property) { + $res = array_map(static function ($property) + { return CastUtils::toAnyType($property); }, $properties); diff --git a/src/Types/AnyType.php b/src/Types/AnyType.php index ebd9faaa..9d65d69b 100644 --- a/src/Types/AnyType.php +++ b/src/Types/AnyType.php @@ -35,40 +35,38 @@ interface AnyType extends QueryConvertible { /** * Creates an alias of the current expression. - * - * @param string|Variable $right */ public function alias(Variable|string $right): Alias; /** * Perform an equality check with the given expression. */ - public function equals(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): Equality; + public function equals(self|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): Equality; /** * Perform an inequality comparison against the given expression. */ - public function notEquals(AnyType|Pattern|string|bool|float|int|array$right, bool $insertParentheses = true): Inequality; + public function notEquals(self|Pattern|string|bool|float|int|array$right, bool $insertParentheses = true): Inequality; /** * Perform a greater than comparison against the given expression. */ - public function gt(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): GreaterThan; + public function gt(self|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): GreaterThan; /** * Perform a greater than or equal comparison against the given expression. */ - public function gte(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): GreaterThanOrEqual; + public function gte(self|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): GreaterThanOrEqual; /** * Perform a less than comparison against the given expression. */ - public function lt(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): LessThan; + public function lt(self|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): LessThan; /** * Perform a less than or equal comparison against the given expression. */ - public function lte(AnyType|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): LessThanOrEqual; + public function lte(self|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): LessThanOrEqual; /** * Checks whether the element is null. diff --git a/src/Types/PropertyTypes/BooleanType.php b/src/Types/PropertyTypes/BooleanType.php index ce3a03cd..1987a26f 100644 --- a/src/Types/PropertyTypes/BooleanType.php +++ b/src/Types/PropertyTypes/BooleanType.php @@ -25,17 +25,17 @@ interface BooleanType extends PropertyType /** * Create a conjunction between this expression and the given expression. */ - public function and(BooleanType|bool $right, bool $insertParentheses = true): Conjunction; + public function and(self|bool $right, bool $insertParentheses = true): Conjunction; /** * Create a disjunction between this expression and the given expression. */ - public function or(BooleanType|bool $right, bool $insertParentheses = true): Disjunction; + public function or(self|bool $right, bool $insertParentheses = true): Disjunction; /** * Perform an XOR with the given expression. */ - public function xor(BooleanType|bool $right, bool $insertParentheses = true): ExclusiveDisjunction; + public function xor(self|bool $right, bool $insertParentheses = true): ExclusiveDisjunction; /** * Negate this expression (using the NOT operator). diff --git a/src/Types/PropertyTypes/NumeralType.php b/src/Types/PropertyTypes/NumeralType.php index 1b954e23..29490479 100644 --- a/src/Types/PropertyTypes/NumeralType.php +++ b/src/Types/PropertyTypes/NumeralType.php @@ -30,32 +30,32 @@ interface NumeralType extends PropertyType /** * Add this expression to the given expression. */ - public function plus(NumeralType|float|int $right, bool $insertParentheses = true): Addition; + public function plus(self|float|int $right, bool $insertParentheses = true): Addition; /** * Divide this expression by the given expression. */ - public function divide(NumeralType|float|int $right, bool $insertParentheses = true): Division; + public function divide(self|float|int $right, bool $insertParentheses = true): Division; /** * Perform an exponentiation with the given expression. */ - public function exponentiate(NumeralType|float|int $right, bool $insertParentheses = true): Exponentiation; + public function exponentiate(self|float|int $right, bool $insertParentheses = true): Exponentiation; /** * Perform the modulo operation with the given expression. */ - public function mod(NumeralType|float|int $right, bool $insertParentheses = true): ModuloDivision; + public function mod(self|float|int $right, bool $insertParentheses = true): ModuloDivision; /** * Perform a multiplication with the given expression. */ - public function times(NumeralType|float|int $right, bool $insertParentheses = true): Multiplication; + public function times(self|float|int $right, bool $insertParentheses = true): Multiplication; /** * Subtract the given expression from this expression. */ - public function minus(NumeralType|float|int $right, bool $insertParentheses = true): Subtraction; + public function minus(self|float|int $right, bool $insertParentheses = true): Subtraction; /** * Negate this expression (negate the numeral using "0"). diff --git a/src/Types/PropertyTypes/StringType.php b/src/Types/PropertyTypes/StringType.php index 8c9e548a..4b7c415b 100644 --- a/src/Types/PropertyTypes/StringType.php +++ b/src/Types/PropertyTypes/StringType.php @@ -25,20 +25,20 @@ interface StringType extends PropertyType /** * Check whether this expression the given expression. */ - public function contains(StringType|string $right, bool $insertParentheses = true): Contains; + public function contains(self|string $right, bool $insertParentheses = true): Contains; /** * Perform a suffix string search with the given expression. */ - public function endsWith(StringType|string $right, bool $insertParentheses = true): EndsWith; + public function endsWith(self|string $right, bool $insertParentheses = true): EndsWith; /** * Perform a prefix string search with the given expression. */ - public function startsWith(StringType|string $right, bool $insertParentheses = true): StartsWith; + public function startsWith(self|string $right, bool $insertParentheses = true): StartsWith; /** * Perform a regex comparison with the given expression. */ - public function regex(StringType|string $right, bool $insertParentheses = true): Regex; + public function regex(self|string $right, bool $insertParentheses = true): Regex; } diff --git a/src/Utils/CastUtils.php b/src/Utils/CastUtils.php index 65cff2b5..5d19a726 100644 --- a/src/Utils/CastUtils.php +++ b/src/Utils/CastUtils.php @@ -1,5 +1,12 @@ - Date: Tue, 3 Feb 2026 19:28:13 +0100 Subject: [PATCH 08/12] Make PHPStan happy --- composer.json | 6 +- phpstan.neon.dist | 9 +- src/Clauses/CallClause.php | 3 +- src/Clauses/CallProcedureClause.php | 2 +- src/Expressions/Literals/List_.php | 2 - src/Expressions/Literals/Literal.php | 121 +----------------- src/Expressions/Literals/Map.php | 8 +- src/Patterns/Node.php | 2 - src/Patterns/PropertyPattern.php | 6 +- src/Patterns/Relationship.php | 2 - src/Query.php | 23 ++-- .../PatternTraits/PropertyPatternTrait.php | 7 +- .../CompositeTypeTrait.php | 3 - .../CompositeTypeTraits/ListTypeTrait.php | 3 - .../CompositeTypeTraits/MapTypeTrait.php | 3 - .../MethodTraits/PropertyMethodTrait.php | 3 - .../PropertyTypeTraits/BooleanTypeTrait.php | 2 - .../PropertyTypeTraits/DateTimeTypeTrait.php | 4 - .../PropertyTypeTraits/DateTypeTrait.php | 4 - .../PropertyTypeTraits/FloatTypeTrait.php | 4 - .../PropertyTypeTraits/IntegerTypeTrait.php | 4 - .../LocalDateTimeTypeTrait.php | 4 - .../PropertyTypeTraits/LocalTimeTypeTrait.php | 4 - .../PropertyTypeTraits/NumeralTypeTrait.php | 2 - .../PropertyTypeTraits/PointTypeTrait.php | 4 - .../PropertyTypeTraits/PropertyTypeTrait.php | 3 - .../PropertyTypeTraits/StringTypeTrait.php | 2 - .../PropertyTypeTraits/TimeTypeTrait.php | 4 - .../StructuralTypeTraits/NodeTypeTrait.php | 3 - .../StructuralTypeTraits/PathTypeTrait.php | 4 - .../RelationshipTypeTrait.php | 3 - .../StructuralTypeTrait.php | 3 - src/Types/AnyType.php | 2 +- src/Utils/CastUtils.php | 5 + .../unit/Expressions/Literals/IntegerTest.php | 2 - .../unit/Expressions/Literals/LiteralTest.php | 116 ----------------- 36 files changed, 51 insertions(+), 331 deletions(-) diff --git a/composer.json b/composer.json index d3059bca..55de8356 100644 --- a/composer.json +++ b/composer.json @@ -50,11 +50,11 @@ "ext-ctype": "*" }, "require-dev": { - "phpunit/phpunit": "~9.0", - "infection/infection": "^0.25.5", + "phpunit/phpunit": "^10.0", + "infection/infection": "^0.29", "friendsofphp/php-cs-fixer": "^3.0", "rregeer/phpunit-coverage-check": "^0.3.1", - "phpstan/phpstan": "^1.8" + "phpstan/phpstan": "^2.0" }, "autoload": { "files": [ diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 90f61d32..58cd7a2c 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,10 @@ parameters: paths: - src - level: 7 - treatPhpDocTypesAsCertain: false \ No newline at end of file + level: 9 + treatPhpDocTypesAsCertain: false + ignoreErrors: + - "#Method [a-zA-Z0-9\\_\\\\:\\(\\)]+ has parameter \\$[a-zA-Z0-9_]+ with no value type specified in iterable type array#" + - "#Function [a-zA-Z0-9\\_\\\\:\\(\\)]+ has parameter \\$[a-zA-Z0-9_]+ with no value type specified in iterable type array#" + - "#Method [a-zA-Z0-9\\_\\\\:\\(\\)]+ has parameter \\$[a-zA-Z0-9_]+ with no value type specified in iterable type iterable#" + - "#Method [a-zA-Z0-9\\_\\\\:\\(\\)]+ return type has no value type specified in iterable type array#" diff --git a/src/Clauses/CallClause.php b/src/Clauses/CallClause.php index a5ad19fd..3182fc77 100644 --- a/src/Clauses/CallClause.php +++ b/src/Clauses/CallClause.php @@ -10,6 +10,7 @@ namespace WikibaseSolutions\CypherDSL\Clauses; use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\Query; use WikibaseSolutions\CypherDSL\Utils\CastUtils; @@ -53,7 +54,7 @@ public function withSubQuery(Query $subQuery): self * * @see https://neo4j.com/docs/cypher-manual/current/clauses/call-subquery/#subquery-correlated-importing */ - public function addWithVariable(...$variables): self + public function addWithVariable(Pattern|Variable|string ...$variables): self { $res = []; diff --git a/src/Clauses/CallProcedureClause.php b/src/Clauses/CallProcedureClause.php index 9c34832b..be5ccc17 100644 --- a/src/Clauses/CallProcedureClause.php +++ b/src/Clauses/CallProcedureClause.php @@ -31,7 +31,7 @@ final class CallProcedureClause extends Clause private ?Procedure $procedure = null; /** - * @var Alias[]|Variable[]|(Alias|Variable)[] The result fields that are yielded + * @var Alias[]|(Alias|Variable)[]|Variable[] The result fields that are yielded */ private array $yields = []; diff --git a/src/Expressions/Literals/List_.php b/src/Expressions/Literals/List_.php index 12a13bd0..63c91262 100644 --- a/src/Expressions/Literals/List_.php +++ b/src/Expressions/Literals/List_.php @@ -45,8 +45,6 @@ public function __construct(array $expressions = []) /** * Add one or more expressions to the list. * - * @param AnyType|array|bool|float|int|Pattern|string ...$expressions - * * @return $this */ public function addExpression(AnyType|bool|float|int|array|Pattern|string ...$expressions): self diff --git a/src/Expressions/Literals/Literal.php b/src/Expressions/Literals/Literal.php index de864f8f..94f87463 100644 --- a/src/Expressions/Literals/Literal.php +++ b/src/Expressions/Literals/Literal.php @@ -20,6 +20,8 @@ use WikibaseSolutions\CypherDSL\Expressions\Procedures\Point; use WikibaseSolutions\CypherDSL\Expressions\Procedures\Procedure; use WikibaseSolutions\CypherDSL\Expressions\Procedures\Time; +use WikibaseSolutions\CypherDSL\Patterns\Pattern; +use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\NumeralType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\StringType; @@ -34,7 +36,7 @@ final class Literal * Creates a new literal from the given value. This function automatically constructs the appropriate * class based on the type of the value given. * - * @param mixed $literal The literal to construct + * @param array|bool|float|int|string|Stringable $literal The literal to construct * * @throws TypeError when the type could not be deduced */ @@ -49,7 +51,6 @@ public static function literal(string|bool|int|float|array|Stringable $literal): } if (is_int($literal)) { - // @phpstan-ignore-next-line return self::integer($literal); } @@ -61,11 +62,7 @@ public static function literal(string|bool|int|float|array|Stringable $literal): return array_is_list($literal) ? self::list($literal) : self::map($literal); } - if (is_object($literal) && method_exists($literal, '__toString')) { - return self::string($literal->__toString()); - } - - throw new TypeError("The literal type " . get_debug_type($literal) . " is not supported by Cypher"); + return self::string($literal->__toString()); } /** @@ -84,7 +81,6 @@ public static function decimal(float|int $value): Float_|Integer */ public static function number(float|int $value): Float_|Integer { - // @phpstan-ignore-next-line PHPStan does not work well with classes named "Integer" return is_int($value) ? self::integer($value) : self::float($value); } @@ -126,8 +122,6 @@ public static function float(float $value): Float_ /** * Creates a new list literal. - * - * @param mixed[] $value */ public static function list(iterable $value): List_ { @@ -150,8 +144,6 @@ public static function map(array $value): Map * Retrieves the current Date value, optionally for a different time zone. In reality, this function just returns * a call to the "date()" function. * - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-current Corresponding documentation on Neo4j.com */ public static function date(StringType|string|null $timezone = null): Date @@ -166,9 +158,6 @@ public static function date(StringType|string|null $timezone = null): Date /** * Creates a date from the given year, month and day. * - * @param null|int|NumeralType $month - * @param null|int|NumeralType $day - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-calendar Corresponding documentation on Neo4j.com */ public static function dateYMD(NumeralType|int $year, NumeralType|int|null $month = null, NumeralType|int|null $day = null): Date @@ -187,9 +176,6 @@ public static function dateYMD(NumeralType|int $year, NumeralType|int|null $mont /** * Creates a date from the given year, week and weekday. * - * @param null|int|NumeralType $week - * @param null|int|NumeralType $weekday - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-date-week Corresponding documentation on Neo4j.com */ public static function dateYWD(NumeralType|int $year, NumeralType|int|null $week = null, NumeralType|int|null $weekday = null): Date @@ -219,8 +205,6 @@ public static function dateString(StringType|string $date): Date * Retrieves the current DateTime value, optionally for a different time zone. In reality, this * function just returns a call to the "datetime()" function. * - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-current Corresponding documentation on Neo4j.com */ public static function dateTime(StringType|string|null $timezone = null): DateTime @@ -235,16 +219,6 @@ public static function dateTime(StringType|string|null $timezone = null): DateTi /** * Creates a date from the given year, month, day and time values. * - * @param null|int|NumeralType $month - * @param null|int|NumeralType $day - * @param null|int|NumeralType $hour - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-calendar Corresponding documentation on Neo4j.com */ public static function dateTimeYMD( @@ -280,16 +254,6 @@ public static function dateTimeYMD( /** * Creates a datetime with the specified year, week, dayOfWeek, hour, minute, second, millisecond, microsecond, nanosecond and timezone component values. * - * @param null|int|NumeralType $week - * @param null|int|NumeralType $dayOfWeek - * @param null|int|NumeralType $hour - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-week Corresponding documentation on Neo4j.com */ public static function dateTimeYWD( @@ -325,16 +289,6 @@ public static function dateTimeYWD( /** * Creates a datetime with the specified year, quarter, dayOfQuarter, hour, minute, second, millisecond, microsecond, nanosecond and timezone component values. * - * @param null|int|NumeralType $quarter - * @param null|int|NumeralType $dayOfQuarter - * @param null|int|NumeralType $hour - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-quarter Corresponding documentation on Neo4j.com */ public static function dateTimeYQD( @@ -370,15 +324,6 @@ public static function dateTimeYQD( /** * Creates a datetime with the specified year, ordinalDay, hour, minute, second, millisecond, microsecond, nanosecond and timezone component values. * - * @param null|int|NumeralType $ordinalDay - * @param null|int|NumeralType $hour - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-datetime-ordinal Corresponding documentation on Neo4j.com */ public static function dateTimeYD( @@ -420,8 +365,6 @@ public static function dateTimeString(StringType|string $dateString): DateTime /** * Creates the current localDateTime value. * - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-current Corresponding documentation on Neo4j.com */ public static function localDateTime(StringType|string|null $timezone = null): LocalDateTime @@ -436,15 +379,6 @@ public static function localDateTime(StringType|string|null $timezone = null): L /** * Creates a LocalDateTime value with specified year, month, day and time props. * - * @param null|int|NumeralType $month - * @param null|int|NumeralType $day - * @param null|int|NumeralType $hour - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-calendar Corresponding documentation on Neo4j.com */ public static function localDateTimeYMD( @@ -479,15 +413,6 @@ public static function localDateTimeYMD( * Creates a LocalDateTime value with the specified year, week, dayOfWeek, hour, minute, * second, millisecond, microsecond and nanosecond component value. * - * @param null|int|NumeralType $week - * @param null|int|NumeralType $dayOfWeek - * @param null|int|NumeralType $hour - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-week Corresponding documentation on Neo4j.com */ public static function localDateTimeYWD( @@ -521,15 +446,6 @@ public static function localDateTimeYWD( /** * Creates a LocalDateTime value with the specified year, quarter, dayOfQuarter, hour, minute, second, millisecond, microsecond and nanosecond component values. * - * @param null|int|NumeralType $quarter - * @param null|int|NumeralType $dayOfQuarter - * @param null|int|NumeralType $hour - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-quarter Corresponding documentation on Neo4j.com */ public static function localDateTimeYQD( @@ -563,14 +479,6 @@ public static function localDateTimeYQD( /** * Creates a LocalDateTime value with the specified year, ordinalDay, hour, minute, second, millisecond, microsecond and nanosecond component values. * - * @param null|int|NumeralType $ordinalDay - * @param null|int|NumeralType $hour - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localdatetime-ordinal Corresponding documentation on Neo4j.com */ public static function localDateTimeYD( @@ -612,8 +520,6 @@ public static function localDateTimeString(StringType|string $localDateTimeStrin /** * Creates the current LocalTime value. * - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localtime-current Corresponding documentation on Neo4j.com */ public static function localTimeCurrent(StringType|string|null $timezone = null): LocalTime @@ -628,12 +534,6 @@ public static function localTimeCurrent(StringType|string|null $timezone = null) /** * Creates a LocalTime value with the specified hour, minute, second, millisecond, microsecond and nanosecond component values. * - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-localtime-create Corresponding documentation on Neo4j.com */ public static function localTime( @@ -669,8 +569,6 @@ public static function localTimeString(StringType|string $localTimeString): Loca /** * Creates the current Time value. * - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-time-current Corresponding documentation on Neo4j.com */ public static function time(StringType|string|null $timezone = null): Time @@ -685,13 +583,6 @@ public static function time(StringType|string|null $timezone = null): Time /** * Creates a Time value with the specified hour, minute, second, millisecond, microsecond, nanosecond and timezone component values. * - * @param null|int|NumeralType $minute - * @param null|int|NumeralType $second - * @param null|int|NumeralType $millisecond - * @param null|int|NumeralType $microsecond - * @param null|int|NumeralType $nanosecond - * @param null|string|StringType $timezone - * * @see https://neo4j.com/docs/cypher-manual/current/functions/temporal/#functions-time-create Corresponding documentation on Neo4j.com */ public static function timeHMS( @@ -701,7 +592,7 @@ public static function timeHMS( NumeralType|int|null $millisecond = null, NumeralType|int|null $microsecond = null, NumeralType|int|null $nanosecond = null, - NumeralType|int|null $timezone = null + StringType|string|null $timezone = null ): Time { return Procedure::time( self::makeTemporalMap( @@ -795,6 +686,8 @@ private function __construct() /** * Prepares the variables to be used by temporal (i.e. time-like) CYPHER-functions. + * + * @return (AnyType|array|bool|float|int|Pattern|string)[] */ private static function makeTemporalMap(array $variables): array { diff --git a/src/Expressions/Literals/Map.php b/src/Expressions/Literals/Map.php index e01710e1..6b1c0382 100644 --- a/src/Expressions/Literals/Map.php +++ b/src/Expressions/Literals/Map.php @@ -9,6 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Expressions\Literals; +use Stringable; +use WikibaseSolutions\CypherDSL\Patterns\Pattern; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits\MapTypeTrait; use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; @@ -46,12 +48,12 @@ public function __construct(array $elements = []) /** * Adds an element for the given name with the given value. Overrides the element if the $key already exists. * - * @param string $key The name/label for the element - * @param mixed $value The value of the element + * @param string $key The name/label for the element + * @param AnyType|array|bool|float|int|Pattern|string|Stringable $value The value of the element * * @return $this */ - public function add(string $key, mixed $value): self + public function add(string $key, AnyType|Pattern|Stringable|bool|float|int|array|string $value): self { $this->elements[$key] = CastUtils::toAnyType($value); diff --git a/src/Patterns/Node.php b/src/Patterns/Node.php index 8c29e8b0..cb8538d7 100644 --- a/src/Patterns/Node.php +++ b/src/Patterns/Node.php @@ -57,8 +57,6 @@ public function withLabels(array $labels): self /** * Adds one or more labels to this node. * - * @param string ...$label - * * @return $this */ public function addLabel(string ...$label): self diff --git a/src/Patterns/PropertyPattern.php b/src/Patterns/PropertyPattern.php index a01c4833..55fbf6be 100644 --- a/src/Patterns/PropertyPattern.php +++ b/src/Patterns/PropertyPattern.php @@ -9,9 +9,11 @@ */ namespace WikibaseSolutions\CypherDSL\Patterns; +use Stringable; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; use WikibaseSolutions\CypherDSL\Expressions\Property; use WikibaseSolutions\CypherDSL\Traits\PatternTraits\PropertyPatternTrait; +use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; /** @@ -43,7 +45,7 @@ public function withProperties(MapType|array $properties): self; * * @return $this */ - public function addProperty(string $key, mixed $property): self; + public function addProperty(string $key, AnyType|Pattern|Stringable|bool|float|int|array|string $property): self; /** * Add the given properties to this pattern. This is only possible if the properties in this pattern are a map. @@ -52,7 +54,7 @@ public function addProperty(string $key, mixed $property): self; * * @return $this */ - public function addProperties(MapType|array $properties): self; + public function addProperties(Map|array $properties): self; /** * Returns the properties of this object. diff --git a/src/Patterns/Relationship.php b/src/Patterns/Relationship.php index d229ec68..13a49be5 100644 --- a/src/Patterns/Relationship.php +++ b/src/Patterns/Relationship.php @@ -171,8 +171,6 @@ public function withTypes(array $types): self /** * Add one or more types to require for this relationship. * - * @param string ...$type - * * @return $this */ public function addType(string ...$type): self diff --git a/src/Query.php b/src/Query.php index f764a5b5..309bed2e 100644 --- a/src/Query.php +++ b/src/Query.php @@ -77,8 +77,6 @@ final class Query implements QueryConvertible /** * Construct a new Query instance. - * - * @return Query */ public static function new(): self { @@ -203,6 +201,7 @@ public static function variable(?string $variable = null): Variable * * @return Boolean|class-string|Float_|Integer|List_|Map|String_ */ + // @phpstan-ignore-next-line public static function literal(null|bool|float|int|array|string|Stringable $literal = null): Boolean|Float_|Integer|List_|Map|String_|string { if ($literal === null) { @@ -315,7 +314,7 @@ public static function rawExpression(string $expression): RawExpression /** * Creates an EXISTS expression. */ - public static function exists(CompletePattern|MatchClause|array $match, WhereClause|BooleanType|bool $where = null, bool $insertParentheses = false): Exists + public static function exists(CompletePattern|MatchClause|array $match, WhereClause|BooleanType|bool|null $where = null, bool $insertParentheses = false): Exists { if (!$match instanceof MatchClause) { $match = is_array($match) ? $match : [$match]; @@ -353,8 +352,8 @@ public function __toString(): string * * @note This feature is not part of the openCypher standard. * - * @param callable|Query $query A callable decorating a Query, or an instance of Query - * @param Pattern|string|Variable|(Pattern|string|Variable)[] $variables The variables to include in the WITH clause for correlation (optional) + * @param callable|Query $query A callable decorating a Query, or an instance of Query + * @param Pattern|(Pattern|string|Variable)[]|string|Variable $variables The variables to include in the WITH clause for correlation (optional) * * @return $this * @@ -489,8 +488,8 @@ public function create(CompletePattern|array $patterns): self /** * Creates the DELETE clause. * - * @param Pattern|StructuralType|(Pattern|StructuralType)[] $structures A single structure to delete, or a non-empty list of structures to delete - * @param bool $detach Whether to DETACH DELETE (optional, default: false) + * @param Pattern|(Pattern|StructuralType)[]|StructuralType $structures A single structure to delete, or a non-empty list of structures to delete + * @param bool $detach Whether to DETACH DELETE (optional, default: false) * * @return $this * @@ -514,7 +513,7 @@ public function delete(Pattern|StructuralType|array $structures, bool $detach = /** * Creates the DETACH DELETE clause. * - * @param Pattern|StructuralType|(Pattern|StructuralType)[] $structures A single structure to delete, or a non-empty list of structures to delete + * @param Pattern|(Pattern|StructuralType)[]|StructuralType $structures A single structure to delete, or a non-empty list of structures to delete * * @return $this * @@ -637,7 +636,7 @@ public function orderBy(Property|array $properties, bool $descending = false): s /** * Creates the REMOVE clause. * - * @param Label|Property|(Label|Property)[] $expressions A single expression to remove, or a non-empty list of expressions to remove + * @param Label|(Label|Property)[]|Property $expressions A single expression to remove, or a non-empty list of expressions to remove * * @return $this * @@ -660,7 +659,7 @@ public function remove(Label|Property|array $expressions): self /** * Create the SET clause. * - * @param Label|PropertyReplacement|(Label|PropertyReplacement)[] $expressions A single expression to set, or a non-empty list of expressions to set + * @param Label|(Label|PropertyReplacement)[]|PropertyReplacement $expressions A single expression to set, or a non-empty list of expressions to set * * @return $this * @@ -684,8 +683,8 @@ public function set(Label|PropertyReplacement|array $expressions): self * Creates the WHERE clause. * * @param bool|BooleanType|(bool|BooleanType)[] $expressions A boolean expression to evaluate, or a non-empty list of boolean expression to evaluate - * @param string $operator The operator with which to unify the given expressions, should be either WhereClause::OR, - * WhereClause::AND or WhereClause::XOR (optional, default: 'and') + * @param string $operator The operator with which to unify the given expressions, should be either WhereClause::OR, + * WhereClause::AND or WhereClause::XOR (optional, default: 'and') * * @return $this * diff --git a/src/Traits/PatternTraits/PropertyPatternTrait.php b/src/Traits/PatternTraits/PropertyPatternTrait.php index 4e9197a2..80dda049 100644 --- a/src/Traits/PatternTraits/PropertyPatternTrait.php +++ b/src/Traits/PatternTraits/PropertyPatternTrait.php @@ -9,9 +9,12 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\PatternTraits; +use Stringable; use TypeError; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; use WikibaseSolutions\CypherDSL\Expressions\Property; +use WikibaseSolutions\CypherDSL\Patterns\Pattern; +use WikibaseSolutions\CypherDSL\Types\AnyType; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; use WikibaseSolutions\CypherDSL\Utils\CastUtils; @@ -48,7 +51,7 @@ public function withProperties(MapType|array $properties): self /** * @inheritDoc */ - public function addProperty(string $key, mixed $property): self + public function addProperty(string $key, AnyType|Pattern|Stringable|bool|float|int|array|string $property): self { $this->makeMap()->add($key, $property); @@ -58,7 +61,7 @@ public function addProperty(string $key, mixed $property): self /** * @inheritDoc */ - public function addProperties(MapType|array $properties): self + public function addProperties(Map|array $properties): self { $map = $this->makeMap(); diff --git a/src/Traits/TypeTraits/CompositeTypeTraits/CompositeTypeTrait.php b/src/Traits/TypeTraits/CompositeTypeTraits/CompositeTypeTrait.php index f1fdc078..70c30255 100644 --- a/src/Traits/TypeTraits/CompositeTypeTraits/CompositeTypeTrait.php +++ b/src/Traits/TypeTraits/CompositeTypeTraits/CompositeTypeTrait.php @@ -10,7 +10,6 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\AnyTypeTrait; -use WikibaseSolutions\CypherDSL\Types\CompositeTypes\CompositeType; /** * This trait provides a default implementation to satisfy the "CompositeType" interface. @@ -20,8 +19,6 @@ * * - ListTypeTrait * - MapTypeTrait - * - * @implements CompositeType */ trait CompositeTypeTrait { diff --git a/src/Traits/TypeTraits/CompositeTypeTraits/ListTypeTrait.php b/src/Traits/TypeTraits/CompositeTypeTraits/ListTypeTrait.php index 9f5f7d9f..762ac10d 100644 --- a/src/Traits/TypeTraits/CompositeTypeTraits/ListTypeTrait.php +++ b/src/Traits/TypeTraits/CompositeTypeTraits/ListTypeTrait.php @@ -10,14 +10,11 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits; use WikibaseSolutions\CypherDSL\Expressions\Operators\In; -use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PropertyType; use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** * This trait provides a default implementation to satisfy the "ListType" interface. - * - * @implements ListType */ trait ListTypeTrait { diff --git a/src/Traits/TypeTraits/CompositeTypeTraits/MapTypeTrait.php b/src/Traits/TypeTraits/CompositeTypeTraits/MapTypeTrait.php index 015d69b8..3a6f2ddb 100644 --- a/src/Traits/TypeTraits/CompositeTypeTraits/MapTypeTrait.php +++ b/src/Traits/TypeTraits/CompositeTypeTraits/MapTypeTrait.php @@ -10,12 +10,9 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\CompositeTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\MethodTraits\PropertyMethodTrait; -use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; /** * This trait provides a default implementation to satisfy the "MapType" interface. - * - * @implements MapType */ trait MapTypeTrait { diff --git a/src/Traits/TypeTraits/MethodTraits/PropertyMethodTrait.php b/src/Traits/TypeTraits/MethodTraits/PropertyMethodTrait.php index 536277b3..11f2c22d 100644 --- a/src/Traits/TypeTraits/MethodTraits/PropertyMethodTrait.php +++ b/src/Traits/TypeTraits/MethodTraits/PropertyMethodTrait.php @@ -10,12 +10,9 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\MethodTraits; use WikibaseSolutions\CypherDSL\Expressions\Property; -use WikibaseSolutions\CypherDSL\Types\Methods\PropertyMethod; /** * This trait provides a default implementation to satisfy the "PropertyFunction" interface. - * - * @implements PropertyMethod */ trait PropertyMethodTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/BooleanTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/BooleanTypeTrait.php index 8705c6aa..fff4662f 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/BooleanTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/BooleanTypeTrait.php @@ -18,8 +18,6 @@ /** * This trait provides a default implementation to satisfy the "BooleanType" interface. - * - * @implements BooleanType */ trait BooleanTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/DateTimeTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/DateTimeTypeTrait.php index def424f3..b47624ea 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/DateTimeTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/DateTimeTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\DateTimeType; - /** * This trait provides a default implementation to satisfy the "DateTimeType" interface. - * - * @implements DateTimeType */ trait DateTimeTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/DateTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/DateTypeTrait.php index 2614b3df..d25e09db 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/DateTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/DateTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\DateType; - /** * This trait provides a default implementation to satisfy the "DateType" interface. - * - * @implements DateType */ trait DateTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/FloatTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/FloatTypeTrait.php index 8a6a9595..fbe5ed42 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/FloatTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/FloatTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\FloatType; - /** * This trait provides a default implementation to satisfy the "FloatType" interface. - * - * @implements FloatType */ trait FloatTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/IntegerTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/IntegerTypeTrait.php index 3e591ba3..1b1acdb1 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/IntegerTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/IntegerTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\IntegerType; - /** * This trait provides a default implementation to satisfy the "IntegerType" interface. - * - * @implements IntegerType */ trait IntegerTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/LocalDateTimeTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/LocalDateTimeTypeTrait.php index bfbbe518..7fb0b913 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/LocalDateTimeTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/LocalDateTimeTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\LocalDateTimeType; - /** * This trait provides a default implementation to satisfy the "LocalDateTimeType" interface. - * - * @implements LocalDateTimeType */ trait LocalDateTimeTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/LocalTimeTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/LocalTimeTypeTrait.php index 534d57cd..84bafc5a 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/LocalTimeTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/LocalTimeTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\LocalTimeType; - /** * This trait provides a default implementation to satisfy the "LocalTimeType" interface. - * - * @implements LocalTimeType */ trait LocalTimeTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/NumeralTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/NumeralTypeTrait.php index 874ba63f..012ff24f 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/NumeralTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/NumeralTypeTrait.php @@ -21,8 +21,6 @@ /** * This trait provides a default implementation to satisfy the "NumeralType" interface. - * - * @implements NumeralType */ trait NumeralTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/PointTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/PointTypeTrait.php index bf13c50b..c0f49966 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/PointTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/PointTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PointType; - /** * This trait provides a default implementation to satisfy the "PointType" interface. - * - * @implements PointType */ trait PointTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php index 39aed8ce..787bc2a1 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/PropertyTypeTrait.php @@ -12,7 +12,6 @@ use WikibaseSolutions\CypherDSL\Expressions\Operators\In; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\AnyTypeTrait; use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\PropertyType; use WikibaseSolutions\CypherDSL\Utils\CastUtils; /** @@ -30,8 +29,6 @@ * - PointTypeTrait * - StringTypeTrait * - TimeTypeTrait - * - * @implements PropertyType */ trait PropertyTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/StringTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/StringTypeTrait.php index 7a705bb2..80c00e48 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/StringTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/StringTypeTrait.php @@ -18,8 +18,6 @@ /** * This trait provides a default implementation to satisfy the "StringType" interface. - * - * @implements StringType */ trait StringTypeTrait { diff --git a/src/Traits/TypeTraits/PropertyTypeTraits/TimeTypeTrait.php b/src/Traits/TypeTraits/PropertyTypeTraits/TimeTypeTrait.php index 49a8cb58..7c281229 100644 --- a/src/Traits/TypeTraits/PropertyTypeTraits/TimeTypeTrait.php +++ b/src/Traits/TypeTraits/PropertyTypeTraits/TimeTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\PropertyTypeTraits; -use WikibaseSolutions\CypherDSL\Types\PropertyTypes\TimeType; - /** * This trait provides a default implementation to satisfy the "TimeType" interface. - * - * @implements TimeType */ trait TimeTypeTrait { diff --git a/src/Traits/TypeTraits/StructuralTypeTraits/NodeTypeTrait.php b/src/Traits/TypeTraits/StructuralTypeTraits/NodeTypeTrait.php index 94a4fc29..d76fde3e 100644 --- a/src/Traits/TypeTraits/StructuralTypeTraits/NodeTypeTrait.php +++ b/src/Traits/TypeTraits/StructuralTypeTraits/NodeTypeTrait.php @@ -10,12 +10,9 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\StructuralTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\MethodTraits\PropertyMethodTrait; -use WikibaseSolutions\CypherDSL\Types\StructuralTypes\NodeType; /** * This trait provides a default implementation to satisfy the "NodeType" interface. - * - * @implements NodeType */ trait NodeTypeTrait { diff --git a/src/Traits/TypeTraits/StructuralTypeTraits/PathTypeTrait.php b/src/Traits/TypeTraits/StructuralTypeTraits/PathTypeTrait.php index 07400c71..c1473a40 100644 --- a/src/Traits/TypeTraits/StructuralTypeTraits/PathTypeTrait.php +++ b/src/Traits/TypeTraits/StructuralTypeTraits/PathTypeTrait.php @@ -9,12 +9,8 @@ */ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\StructuralTypeTraits; -use WikibaseSolutions\CypherDSL\Types\StructuralTypes\PathType; - /** * This trait provides a default implementation to satisfy the "PathType" interface. - * - * @implements PathType */ trait PathTypeTrait { diff --git a/src/Traits/TypeTraits/StructuralTypeTraits/RelationshipTypeTrait.php b/src/Traits/TypeTraits/StructuralTypeTraits/RelationshipTypeTrait.php index 2de3aa9d..222ff499 100644 --- a/src/Traits/TypeTraits/StructuralTypeTraits/RelationshipTypeTrait.php +++ b/src/Traits/TypeTraits/StructuralTypeTraits/RelationshipTypeTrait.php @@ -10,12 +10,9 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\StructuralTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\MethodTraits\PropertyMethodTrait; -use WikibaseSolutions\CypherDSL\Types\StructuralTypes\RelationshipType; /** * This trait provides a default implementation to satisfy the "RelationshipType" interface. - * - * @implements RelationshipType */ trait RelationshipTypeTrait { diff --git a/src/Traits/TypeTraits/StructuralTypeTraits/StructuralTypeTrait.php b/src/Traits/TypeTraits/StructuralTypeTraits/StructuralTypeTrait.php index 00121ace..81a38816 100644 --- a/src/Traits/TypeTraits/StructuralTypeTraits/StructuralTypeTrait.php +++ b/src/Traits/TypeTraits/StructuralTypeTraits/StructuralTypeTrait.php @@ -10,7 +10,6 @@ namespace WikibaseSolutions\CypherDSL\Traits\TypeTraits\StructuralTypeTraits; use WikibaseSolutions\CypherDSL\Traits\TypeTraits\AnyTypeTrait; -use WikibaseSolutions\CypherDSL\Types\StructuralTypes\StructuralType; /** * This trait provides a default implementation to satisfy the "StructuralType" interface. @@ -21,8 +20,6 @@ * - NodeTypeTrait * - PathTypeTrait * - RelationshipTypeTrait - * - * @implements StructuralType */ trait StructuralTypeTrait { diff --git a/src/Types/AnyType.php b/src/Types/AnyType.php index 9d65d69b..1b1b3fb3 100644 --- a/src/Types/AnyType.php +++ b/src/Types/AnyType.php @@ -46,7 +46,7 @@ public function equals(self|Pattern|string|bool|float|int|array $right, bool $in /** * Perform an inequality comparison against the given expression. */ - public function notEquals(self|Pattern|string|bool|float|int|array$right, bool $insertParentheses = true): Inequality; + public function notEquals(self|Pattern|string|bool|float|int|array $right, bool $insertParentheses = true): Inequality; /** * Perform a greater than comparison against the given expression. diff --git a/src/Utils/CastUtils.php b/src/Utils/CastUtils.php index 5d19a726..8e3d89e5 100644 --- a/src/Utils/CastUtils.php +++ b/src/Utils/CastUtils.php @@ -33,6 +33,8 @@ class CastUtils { /** * Casts the given value to a ListType. + * + * @param ListType|ListType[] $list */ public static function toListType(ListType|array $list): ListType { @@ -41,6 +43,8 @@ public static function toListType(ListType|array $list): ListType /** * Casts the given value to a MapType. + * + * @param MapType|MapType[] $map */ public static function toMapType(MapType|array $map): MapType { @@ -84,6 +88,7 @@ public static function toBooleanType(BooleanType|bool $boolean): BooleanType */ public static function toPropertyType(PropertyType|bool|int|float|string $property): PropertyType { + // @phpstan-ignore-next-line return $property instanceof PropertyType ? $property : Literal::literal($property); } diff --git a/tests/unit/Expressions/Literals/IntegerTest.php b/tests/unit/Expressions/Literals/IntegerTest.php index d2c2e6cc..b7e39f42 100644 --- a/tests/unit/Expressions/Literals/IntegerTest.php +++ b/tests/unit/Expressions/Literals/IntegerTest.php @@ -48,8 +48,6 @@ public function testThrowsTypeErrorOnInvalidString(): void /** * @dataProvider provideToQueryData - * - * @param $number */ public function testToQuery($number, string $expected): void { diff --git a/tests/unit/Expressions/Literals/LiteralTest.php b/tests/unit/Expressions/Literals/LiteralTest.php index 916aa89c..3606ad5d 100644 --- a/tests/unit/Expressions/Literals/LiteralTest.php +++ b/tests/unit/Expressions/Literals/LiteralTest.php @@ -317,11 +317,6 @@ public function testDateTimezone(): void /** * @dataProvider provideDateYMDData - * - * @param $year - * @param $month - * @param $day - * @param $expected */ public function testDateYMD($year, $month, $day, $expected): void { @@ -341,11 +336,6 @@ public function testDateYMDMissingMonth(): void /** * @dataProvider provideDateYWDData - * - * @param $year - * @param $week - * @param $weekday - * @param $expected */ public function testDateYWD($year, $week, $weekday, $expected): void { @@ -386,18 +376,6 @@ public function testDateTimeWithTimeZone(): void /** * @dataProvider provideDatetimeYMDData - * - * @param $year - * @param $month - * @param $day - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $timezone - * @param $expected */ public function testDatetimeYMD($year, $month, $day, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected): void { @@ -417,18 +395,6 @@ public function testDatetimeYMDMissingMonth(): void /** * @dataProvider provideDatetimeYWDData - * - * @param $year - * @param $week - * @param $dayOfWeek - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $timezone - * @param $expected */ public function testDatetimeYWD($year, $week, $dayOfWeek, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected): void { @@ -448,18 +414,6 @@ public function testDatetimeYWDMissingWeek(): void /** * @dataProvider provideDatetimeYQDData - * - * @param $year - * @param $quarter - * @param $dayOfQuarter - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $timezone - * @param $expected */ public function testDatetimeYQD($year, $quarter, $dayOfQuarter, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected): void { @@ -479,17 +433,6 @@ public function testDatetimeYQDMissingQuarter(): void /** * @dataProvider provideDatetimeYQData - * - * @param $year - * @param $ordinalDay - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $timezone - * @param $expected */ public function testDatetimeYD($year, $ordinalDay, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected): void { @@ -530,17 +473,6 @@ public function testLocalDateTimeWithTimezone(): void /** * @dataProvider provideLocalDatetimeYMDData - * - * @param $year - * @param $month - * @param $day - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $expected */ public function testLocalDateTimeYMD($year, $month, $day, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected): void { @@ -560,17 +492,6 @@ public function testLocalDateTimeYMDMissingMonth(): void /** * @dataProvider provideLocalDatetimeYWDData - * - * @param $year - * @param $week - * @param $dayOfWeek - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $expected */ public function testLocalDateTimeYWD($year, $week, $dayOfWeek, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected): void { @@ -590,17 +511,6 @@ public function testLocalDateTimeYWDMissingWeek(): void /** * @dataProvider provideLocalDatetimeYQDData - * - * @param $year - * @param $quarter - * @param $dayOfQuarter - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $expected */ public function testLocalDatetimeYQD($year, $quarter, $dayOfQuarter, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected): void { @@ -620,16 +530,6 @@ public function testLocalDateTimeYQDMissingQuarter(): void /** * @dataProvider provideLocalDatetimeYQData - * - * @param $year - * @param $ordinalDay - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $expected */ public function testLocalDatetimeYD($year, $ordinalDay, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected): void { @@ -668,14 +568,6 @@ public function testLocalTimeCurrentWithTimezone(): void /** * @dataProvider provideLocalTimeData - * - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $expected */ public function testLocalTime($hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected): void { @@ -712,14 +604,6 @@ public function testTimeCurrentWithTimezone(): void /** * @dataProvider provideTimeData - * - * @param $hour - * @param $minute - * @param $second - * @param $millisecond - * @param $microsecond - * @param $nanosecond - * @param $expected */ public function testTime($hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected): void { From f39d8e0a5cc72f86125b51a19c63efc7853152c1 Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Tue, 3 Feb 2026 19:50:18 +0100 Subject: [PATCH 09/12] Ensure all tests pass, and fix deprecation warnings --- .github/CONTRIBUTING.md | 2 +- phpunit.xml.dist | 19 +- tests/unit/Expressions/Literals/FloatTest.php | 20 +- .../unit/Expressions/Literals/IntegerTest.php | 48 +- tests/unit/Expressions/Literals/ListTest.php | 36 +- .../unit/Expressions/Literals/LiteralTest.php | 700 +++++++++--------- tests/unit/Expressions/Literals/MapTest.php | 54 +- .../unit/Expressions/Literals/StringTest.php | 96 +-- tests/unit/Expressions/ParameterTest.php | 36 +- tests/unit/Expressions/PropertyTest.php | 20 +- tests/unit/Expressions/VariableTest.php | 34 +- tests/unit/Patterns/NodeTest.php | 146 ++-- tests/unit/Patterns/RelationshipTest.php | 234 +++--- tests/unit/QueryTest.php | 42 +- tests/unit/Utils/CastUtilsTest.php | 153 +++- tests/unit/Utils/NameUtilsTest.php | 108 ++- 16 files changed, 1003 insertions(+), 745 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index c487c19b..72b8eb99 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -69,7 +69,7 @@ After making your changes and adding your tests, you can check whether the minim ``` $ XDEBUG_MODE=coverage php vendor/bin/phpunit --testsuite unit $ php vendor/bin/coverage-check coverage/clover.xml 90 -$ XDEBUG_MODE=coverage php vendor/bin/infection --min-msi=80 +$ XDEBUG_MODE=coverage php vendor/bin/infection --min-msi=8 ``` ## Running test suites diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d9399d2b..4ad067c1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,12 @@ - @@ -15,16 +20,18 @@ tests/integration - - - - - + src src/functions.php + + + + + + \ No newline at end of file diff --git a/tests/unit/Expressions/Literals/FloatTest.php b/tests/unit/Expressions/Literals/FloatTest.php index 202c650d..d8163ca6 100644 --- a/tests/unit/Expressions/Literals/FloatTest.php +++ b/tests/unit/Expressions/Literals/FloatTest.php @@ -18,6 +18,16 @@ */ final class FloatTest extends TestCase { + public static function provideToQueryData(): array + { + return [ + [1, '1.0'], + [1.0, '1.0'], + [111111111111111, '1.1111111111111E+14'], + [1337.1337, '1337.1337'], + ]; + } + public function testZero(): void { $float = new Float_(0); @@ -48,14 +58,4 @@ public function testInstanceOfFloatType(): void { $this->assertInstanceOf(FloatType::class, new Float_(1.0)); } - - public function provideToQueryData(): array - { - return [ - [1, '1.0'], - [1.0, '1.0'], - [111111111111111, '1.1111111111111E+14'], - [1337.1337, '1337.1337'], - ]; - } } diff --git a/tests/unit/Expressions/Literals/IntegerTest.php b/tests/unit/Expressions/Literals/IntegerTest.php index b7e39f42..c1364cc2 100644 --- a/tests/unit/Expressions/Literals/IntegerTest.php +++ b/tests/unit/Expressions/Literals/IntegerTest.php @@ -19,6 +19,30 @@ */ final class IntegerTest extends TestCase { + public static function provideToQueryData(): array + { + return [ + [1, "1"], + [2, "2"], + ["2147483649", "2147483649"], + ["9223372036854775816", "9223372036854775816"], + [-12, "-12"], + [69, "69"], + ["292922929312312831203129382304823043284234729847294324724982749274294729427429471230918457", "292922929312312831203129382304823043284234729847294324724982749274294729427429471230918457"], + ["-1238109438204130457284308235720483205", "-1238109438204130457284308235720483205"], + ]; + } + + public static function provideInvalidInputData(): array + { + return [ + ['nonumber'], + ['12.3E36'], + ['0x86'], + ['5.5'], + ]; + } + public function testZero(): void { $decimal = new Integer(0); @@ -65,28 +89,4 @@ public function testInvalidInput($input): void $this->expectException(TypeError::class); new Integer($input); } - - public function provideToQueryData(): array - { - return [ - [1, "1"], - [2, "2"], - ["2147483649", "2147483649"], - ["9223372036854775816", "9223372036854775816"], - [-12, "-12"], - [69, "69"], - ["292922929312312831203129382304823043284234729847294324724982749274294729427429471230918457", "292922929312312831203129382304823043284234729847294324724982749274294729427429471230918457"], - ["-1238109438204130457284308235720483205", "-1238109438204130457284308235720483205"], - ]; - } - - public function provideInvalidInputData(): array - { - return [ - ['nonumber'], - ['12.3E36'], - ['0x86'], - ['5.5'], - ]; - } } diff --git a/tests/unit/Expressions/Literals/ListTest.php b/tests/unit/Expressions/Literals/ListTest.php index c3440858..54802dc5 100644 --- a/tests/unit/Expressions/Literals/ListTest.php +++ b/tests/unit/Expressions/Literals/ListTest.php @@ -20,6 +20,24 @@ */ final class ListTest extends TestCase { + public static function provideOneDimensionalData(): array + { + return [ + [[Query::literal(12)], "[12]"], + [[Query::literal('12')], "['12']"], + [[Query::literal('12'), Query::literal('13')], "['12', '13']"], + ]; + } + + public static function provideMultidimensionalData(): array + { + return [ + [[new List_([Query::literal(12)])], "[[12]]"], + [[new List_([Query::literal('12')])], "[['12']]"], + [[new List_([Query::literal('12'), Query::literal('14')]), new List_([Query::literal('13')])], "[['12', '14'], ['13']]"], + ]; + } + public function testEmpty(): void { $list = new List_([]); @@ -145,22 +163,4 @@ public function testMultidimensional(array $expressions, string $expected): void $this->assertSame($expected, $list->toQuery()); } - - public function provideOneDimensionalData(): array - { - return [ - [[Query::literal(12)], "[12]"], - [[Query::literal('12')], "['12']"], - [[Query::literal('12'), Query::literal('13')], "['12', '13']"], - ]; - } - - public function provideMultidimensionalData(): array - { - return [ - [[new List_([Query::literal(12)])], "[[12]]"], - [[new List_([Query::literal('12')])], "[['12']]"], - [[new List_([Query::literal('12'), Query::literal('14')]), new List_([Query::literal('13')])], "[['12', '14'], ['13']]"], - ]; - } } diff --git a/tests/unit/Expressions/Literals/LiteralTest.php b/tests/unit/Expressions/Literals/LiteralTest.php index 3606ad5d..08bfd386 100644 --- a/tests/unit/Expressions/Literals/LiteralTest.php +++ b/tests/unit/Expressions/Literals/LiteralTest.php @@ -33,108 +33,396 @@ */ final class LiteralTest extends TestCase { - public function testLiteralString(): void + public static function provideLiteralDeductionFailure(): array { - $string = Literal::literal('Testing is a virtue!'); - - $this->assertInstanceOf(String_::class, $string); + return [ + [new class() + { + }, ], + [null], + ]; } - public function testLiteralBoolean(): void + public static function provideDateYMDData(): array { - $boolean = Literal::literal(true); + return [ + [2000, null, null, new Date(Literal::map(["year" => 2000]))], + [2000, 12, null, new Date(Literal::map(["year" => 2000, "month" => 12]))], + [2000, 12, 17, new Date(Literal::map(["year" => 2000, "month" => 12, "day" => 17]))], + [new Integer(2000), null, null, new Date(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(12), null, new Date(Literal::map(["year" => 2000, "month" => 12]))], + [new Integer(2000), new Integer(12), new Integer(17), new Date(Literal::map(["year" => 2000, "month" => 12, "day" => 17]))], - $this->assertInstanceOf(Boolean::class, $boolean); + ]; } - public function testLiteralInteger(): void + public static function provideDateYWDData(): array { - $integer = Literal::literal(1); + return [ + [2000, null, null, new Date(Literal::map(["year" => 2000]))], + [2000, 12, null, new Date(Literal::map(["year" => 2000, "week" => 12]))], + [2000, 12, 17, new Date(Literal::map(["year" => 2000, "week" => 12, "dayOfWeek" => 17]))], + [new Integer(2000), null, null, new Date(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(12), null, new Date(Literal::map(["year" => 2000, "week" => 12]))], + [new Integer(2000), new Integer(12), new Integer(17), new Date(Literal::map(["year" => 2000, "week" => 12, "dayOfWeek" => 17]))], - $this->assertInstanceOf(Integer::class, $integer); + ]; } - public function testLiteralFloat(): void + public static function provideDatetimeYMDData(): array { - $float = Literal::literal(1.0); + // [$year, $month, $day, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected] + return [ + [2000, null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], + [2000, 12, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12]))], + [2000, 12, 15, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15]))], + [2000, 12, 15, 8, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8]))], + [2000, 12, 15, 8, 25, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25]))], + [2000, 12, 15, 8, 25, 44, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44]))], + [2000, 12, 15, 8, 25, 44, 18, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [2000, 12, 15, 8, 25, 44, 18, 6, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [2000, 12, 15, 8, 25, 44, 18, 6, 31, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + [2000, 12, 15, 8, 25, 44, 18, 6, 31, "America/Los Angeles", new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - $this->assertInstanceOf(Float_::class, $float); + // types + [new Integer(2000), null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(12), null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12]))], + [new Integer(2000), new Integer(12), new Integer(15), null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new String_("America/Los Angeles"), new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], + ]; } - public function testLiteralList(): void + public static function provideDatetimeYWDData(): array { - $list = Literal::literal(['a', 'b', 'c']); + // [$year, $week, $dayOfWeek, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected] + return [ + [2000, null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], + [2000, 9, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9]))], + [2000, 9, 4, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4]))], + [2000, 9, 4, 8, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8]))], + [2000, 9, 4, 8, 25, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25]))], + [2000, 9, 4, 8, 25, 44, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], + [2000, 9, 4, 8, 25, 44, 18, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [2000, 9, 4, 8, 25, 44, 18, 6, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [2000, 9, 4, 8, 25, 44, 18, 6, 31, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + [2000, 9, 4, 8, 25, 44, 18, 6, 31, "America/Los Angeles", new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - $this->assertInstanceOf(List_::class, $list); + // types + [new Integer(2000), null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(9), null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9]))], + [new Integer(2000), new Integer(9), new Integer(4), null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new String_("America/Los Angeles"), new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], + ]; } - public function testLiteralMap(): void + public static function provideDatetimeYQDData(): array { - $map = Literal::literal(['a' => 'b']); + // [$year, $quarter, $dayOfQuarter, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected] + return [ + [2000, null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], + [2000, 3, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3]))], + [2000, 3, 4, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4]))], + [2000, 3, 4, 8, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8]))], + [2000, 3, 4, 8, 25, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25]))], + [2000, 3, 4, 8, 25, 44, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], + [2000, 3, 4, 8, 25, 44, 18, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [2000, 3, 4, 8, 25, 44, 18, 6, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [2000, 3, 4, 8, 25, 44, 18, 6, 31, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + [2000, 3, 4, 8, 25, 44, 18, 6, 31, "America/Los Angeles", new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - $this->assertInstanceOf(Map::class, $map); + // types + [new Integer(2000), null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(3), null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3]))], + [new Integer(2000), new Integer(3), new Integer(4), null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new String_("America/Los Angeles"), new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], + ]; } - public function testInvalidTypeThrowsException(): void + public static function provideDatetimeYQData(): array { - $this->expectException(TypeError::class); + // [$year, $ordinalDay, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected] + return [ + [2000, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], + [2000, 3, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3]))], + [2000, 3, 8, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8]))], + [2000, 3, 8, 25, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25]))], + [2000, 3, 8, 25, 44, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44]))], + [2000, 3, 8, 25, 44, 18, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [2000, 3, 8, 25, 44, 18, 6, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [2000, 3, 8, 25, 44, 18, 6, 31, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + [2000, 3, 8, 25, 44, 18, 6, 31, "America/Los Angeles", new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - Literal::literal(new stdClass()); + // types + [new Integer(2000), null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(3), null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3]))], + [new Integer(2000), new Integer(3), new Integer(8), null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new String_("America/Los Angeles"), new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], + ]; } - public function testStringable(): void + public static function provideLocalDatetimeYMDData(): array { - $stringable = Literal::literal(new class() - { - public function __toString() - { - return 'Testing is a virtue!'; - } - }); - - $this->assertInstanceOf(String_::class, $stringable); - } + // [$year, $month, $day, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] + return [ + [2000, null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], + [2000, 12, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12]))], + [2000, 12, 15, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15]))], + [2000, 12, 15, 8, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8]))], + [2000, 12, 15, 8, 25, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25]))], + [2000, 12, 15, 8, 25, 44, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44]))], + [2000, 12, 15, 8, 25, 44, 18, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [2000, 12, 15, 8, 25, 44, 18, 6, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [2000, 12, 15, 8, 25, 44, 18, 6, 31, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - /** - * @dataProvider literalDeductionFailureProvider - */ - public function testLiteralDeductionFailure($value): void - { - $this->expectException(TypeError::class); - Literal::literal($value); + // types + [new Integer(2000), null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(12), null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12]))], + [new Integer(2000), new Integer(12), new Integer(15), null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + ]; } - public function literalDeductionFailureProvider(): array + public static function provideLocalDatetimeYWDData(): array { + // [$year, $week, $dayOfWeek, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] return [ - [new class() - { - }, ], - [null], + [2000, null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], + [2000, 9, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9]))], + [2000, 9, 4, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4]))], + [2000, 9, 4, 8, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8]))], + [2000, 9, 4, 8, 25, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25]))], + [2000, 9, 4, 8, 25, 44, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], + [2000, 9, 4, 8, 25, 44, 18, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [2000, 9, 4, 8, 25, 44, 18, 6, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [2000, 9, 4, 8, 25, 44, 18, 6, 31, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + + // types + [new Integer(2000), null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(9), null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9]))], + [new Integer(2000), new Integer(9), new Integer(4), null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], ]; } - public function testNumberInteger(): void + public static function provideLocalDatetimeYQDData(): array { - $integer = Literal::number(1); + // [$year, $quarter, $dayOfQuarter, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] + return [ + [2000, null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], + [2000, 3, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3]))], + [2000, 3, 4, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4]))], + [2000, 3, 4, 8, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8]))], + [2000, 3, 4, 8, 25, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25]))], + [2000, 3, 4, 8, 25, 44, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], + [2000, 3, 4, 8, 25, 44, 18, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [2000, 3, 4, 8, 25, 44, 18, 6, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [2000, 3, 4, 8, 25, 44, 18, 6, 31, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - $this->assertInstanceOf(Integer::class, $integer); + // types + [new Integer(2000), null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(3), null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3]))], + [new Integer(2000), new Integer(3), new Integer(4), null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + ]; } - public function testNumberFloat(): void + public static function provideLocalDatetimeYQData(): array { - $float = Literal::number(1.0); + // [$year, $ordinalDay, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] + return [ + [2000, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], + [2000, 3, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3]))], + [2000, 3, 8, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8]))], + [2000, 3, 8, 25, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25]))], + [2000, 3, 8, 25, 44, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44]))], + [2000, 3, 8, 25, 44, 18, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [2000, 3, 8, 25, 44, 18, 6, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [2000, 3, 8, 25, 44, 18, 6, 31, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - $this->assertInstanceOf(Float_::class, $float); + // types + [new Integer(2000), null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], + [new Integer(2000), new Integer(3), null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3]))], + [new Integer(2000), new Integer(3), new Integer(8), null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], + [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], + ]; } - public function testNumberNoString(): void + public static function provideLocalTimeData(): array { - $this->expectException(TypeError::class); - - Literal::number('55'); - } - + // [$hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] + return [ + [11, null, null, null, null, null, new LocalTime(Literal::map(["hour" => 11]))], + [11, 23, null, null, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23]))], + [11, 23, 2, null, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2]))], + [11, 23, 2, 54, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54]))], + [11, 23, 2, 54, 8, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8]))], + [11, 23, 2, 54, 8, 29, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8, "nanosecond" => 29]))], + + // types + [new Integer(11), null, null, null, null, null, new LocalTime(Literal::map(["hour" => 11]))], + [new Integer(11), new Integer(23), null, null, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23]))], + [new Integer(11), new Integer(23), new Integer(2), null, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2]))], + [new Integer(11), new Integer(23), new Integer(2), new Integer(54), null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54]))], + [new Integer(11), new Integer(23), new Integer(2), new Integer(54), new Integer(8), null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8]))], + [new Integer(11), new Integer(23), new Integer(2), new Integer(54), new Integer(8), new Integer(29), new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8, "nanosecond" => 29]))], + ]; + } + + public static function provideTimeData(): array + { + // [$hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] + return [ + [11, null, null, null, null, null, new Time(Literal::map(["hour" => 11]))], + [11, 23, null, null, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23]))], + [11, 23, 2, null, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2]))], + [11, 23, 2, 54, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54]))], + [11, 23, 2, 54, 8, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8]))], + [11, 23, 2, 54, 8, 29, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8, "nanosecond" => 29]))], + + // types + [new Integer(11), null, null, null, null, null, new Time(Literal::map(["hour" => 11]))], + [new Integer(11), new Integer(23), null, null, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23]))], + [new Integer(11), new Integer(23), new Integer(2), null, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2]))], + [new Integer(11), new Integer(23), new Integer(2), new Integer(54), null, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54]))], + [new Integer(11), new Integer(23), new Integer(2), new Integer(54), new Integer(8), null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8]))], + [new Integer(11), new Integer(23), new Integer(2), new Integer(54), new Integer(8), new Integer(29), new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8, "nanosecond" => 29]))], + ]; + } + + public function testLiteralString(): void + { + $string = Literal::literal('Testing is a virtue!'); + + $this->assertInstanceOf(String_::class, $string); + } + + public function testLiteralBoolean(): void + { + $boolean = Literal::literal(true); + + $this->assertInstanceOf(Boolean::class, $boolean); + } + + public function testLiteralInteger(): void + { + $integer = Literal::literal(1); + + $this->assertInstanceOf(Integer::class, $integer); + } + + public function testLiteralFloat(): void + { + $float = Literal::literal(1.0); + + $this->assertInstanceOf(Float_::class, $float); + } + + public function testLiteralList(): void + { + $list = Literal::literal(['a', 'b', 'c']); + + $this->assertInstanceOf(List_::class, $list); + } + + public function testLiteralMap(): void + { + $map = Literal::literal(['a' => 'b']); + + $this->assertInstanceOf(Map::class, $map); + } + + public function testInvalidTypeThrowsException(): void + { + $this->expectException(TypeError::class); + + Literal::literal(new stdClass()); + } + + public function testStringable(): void + { + $stringable = Literal::literal(new class() + { + public function __toString() + { + return 'Testing is a virtue!'; + } + }); + + $this->assertInstanceOf(String_::class, $stringable); + } + + /** + * @dataProvider provideLiteralDeductionFailure + */ + public function testLiteralDeductionFailure($value): void + { + $this->expectException(TypeError::class); + Literal::literal($value); + } + + public function testNumberInteger(): void + { + $integer = Literal::number(1); + + $this->assertInstanceOf(Integer::class, $integer); + } + + public function testNumberFloat(): void + { + $float = Literal::number(1.0); + + $this->assertInstanceOf(Float_::class, $float); + } + + public function testNumberNoString(): void + { + $this->expectException(TypeError::class); + + Literal::number('55'); + } + public function testBoolean(): void { $boolean = Literal::boolean(true); @@ -189,21 +477,21 @@ public function testListAcceptsIterable(): void { $list = Literal::list(new class implements Iterator { - public function current() + public function current(): int { return 1; } - public function next() + public function next(): void { - return 1; } - public function key(): void + public function key(): string { + return ''; } - public function valid() + public function valid(): bool { static $i = 0; @@ -625,292 +913,4 @@ public function testTimeString(): void $time = Literal::timeString("21:40:32.142+0100"); $this->assertEquals($time, new Time(new String_("21:40:32.142+0100"))); } - - public function provideDateYMDData(): array - { - return [ - [2000, null, null, new Date(Literal::map(["year" => 2000]))], - [2000, 12, null, new Date(Literal::map(["year" => 2000, "month" => 12]))], - [2000, 12, 17, new Date(Literal::map(["year" => 2000, "month" => 12, "day" => 17]))], - [new Integer(2000), null, null, new Date(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(12), null, new Date(Literal::map(["year" => 2000, "month" => 12]))], - [new Integer(2000), new Integer(12), new Integer(17), new Date(Literal::map(["year" => 2000, "month" => 12, "day" => 17]))], - - ]; - } - - public function provideDateYWDData(): array - { - return [ - [2000, null, null, new Date(Literal::map(["year" => 2000]))], - [2000, 12, null, new Date(Literal::map(["year" => 2000, "week" => 12]))], - [2000, 12, 17, new Date(Literal::map(["year" => 2000, "week" => 12, "dayOfWeek" => 17]))], - [new Integer(2000), null, null, new Date(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(12), null, new Date(Literal::map(["year" => 2000, "week" => 12]))], - [new Integer(2000), new Integer(12), new Integer(17), new Date(Literal::map(["year" => 2000, "week" => 12, "dayOfWeek" => 17]))], - - ]; - } - - public function provideDatetimeYMDData(): array - { - // [$year, $month, $day, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected] - return [ - [2000, null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], - [2000, 12, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12]))], - [2000, 12, 15, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15]))], - [2000, 12, 15, 8, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8]))], - [2000, 12, 15, 8, 25, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25]))], - [2000, 12, 15, 8, 25, 44, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44]))], - [2000, 12, 15, 8, 25, 44, 18, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [2000, 12, 15, 8, 25, 44, 18, 6, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [2000, 12, 15, 8, 25, 44, 18, 6, 31, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - [2000, 12, 15, 8, 25, 44, 18, 6, 31, "America/Los Angeles", new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - - // types - [new Integer(2000), null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(12), null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12]))], - [new Integer(2000), new Integer(12), new Integer(15), null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), null, null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), null, new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new String_("America/Los Angeles"), new DateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - ]; - } - - public function provideDatetimeYWDData(): array - { - // [$year, $week, $dayOfWeek, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected] - return [ - [2000, null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], - [2000, 9, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9]))], - [2000, 9, 4, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4]))], - [2000, 9, 4, 8, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8]))], - [2000, 9, 4, 8, 25, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25]))], - [2000, 9, 4, 8, 25, 44, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], - [2000, 9, 4, 8, 25, 44, 18, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [2000, 9, 4, 8, 25, 44, 18, 6, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [2000, 9, 4, 8, 25, 44, 18, 6, 31, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - [2000, 9, 4, 8, 25, 44, 18, 6, 31, "America/Los Angeles", new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - - // types - [new Integer(2000), null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(9), null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9]))], - [new Integer(2000), new Integer(9), new Integer(4), null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), null, null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), null, new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new String_("America/Los Angeles"), new DateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - ]; - } - - public function provideDatetimeYQDData(): array - { - // [$year, $quarter, $dayOfQuarter, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected] - return [ - [2000, null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], - [2000, 3, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3]))], - [2000, 3, 4, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4]))], - [2000, 3, 4, 8, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8]))], - [2000, 3, 4, 8, 25, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25]))], - [2000, 3, 4, 8, 25, 44, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], - [2000, 3, 4, 8, 25, 44, 18, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [2000, 3, 4, 8, 25, 44, 18, 6, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [2000, 3, 4, 8, 25, 44, 18, 6, 31, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - [2000, 3, 4, 8, 25, 44, 18, 6, 31, "America/Los Angeles", new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - - // types - [new Integer(2000), null, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(3), null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3]))], - [new Integer(2000), new Integer(3), new Integer(4), null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), null, null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), null, new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new String_("America/Los Angeles"), new DateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - ]; - } - - public function provideDatetimeYQData(): array - { - // [$year, $ordinalDay, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $timezone, $expected] - return [ - [2000, null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], - [2000, 3, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3]))], - [2000, 3, 8, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8]))], - [2000, 3, 8, 25, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25]))], - [2000, 3, 8, 25, 44, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44]))], - [2000, 3, 8, 25, 44, 18, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [2000, 3, 8, 25, 44, 18, 6, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [2000, 3, 8, 25, 44, 18, 6, 31, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - [2000, 3, 8, 25, 44, 18, 6, 31, "America/Los Angeles", new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - - // types - [new Integer(2000), null, null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(3), null, null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3]))], - [new Integer(2000), new Integer(3), new Integer(8), null, null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), null, null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), null, null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), null, new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new String_("America/Los Angeles"), new DateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31, "timezone" => "America/Los Angeles"]))], - ]; - } - - public function provideLocalDatetimeYMDData(): array - { - // [$year, $month, $day, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] - return [ - [2000, null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], - [2000, 12, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12]))], - [2000, 12, 15, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15]))], - [2000, 12, 15, 8, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8]))], - [2000, 12, 15, 8, 25, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25]))], - [2000, 12, 15, 8, 25, 44, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44]))], - [2000, 12, 15, 8, 25, 44, 18, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [2000, 12, 15, 8, 25, 44, 18, 6, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [2000, 12, 15, 8, 25, 44, 18, 6, 31, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - - // types - [new Integer(2000), null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(12), null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12]))], - [new Integer(2000), new Integer(12), new Integer(15), null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [new Integer(2000), new Integer(12), new Integer(15), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new LocalDateTime(Literal::map(["year" => 2000, "month" => 12, "day" => 15, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - ]; - } - - public function provideLocalDatetimeYWDData(): array - { - // [$year, $week, $dayOfWeek, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] - return [ - [2000, null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], - [2000, 9, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9]))], - [2000, 9, 4, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4]))], - [2000, 9, 4, 8, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8]))], - [2000, 9, 4, 8, 25, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25]))], - [2000, 9, 4, 8, 25, 44, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], - [2000, 9, 4, 8, 25, 44, 18, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [2000, 9, 4, 8, 25, 44, 18, 6, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [2000, 9, 4, 8, 25, 44, 18, 6, 31, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - - // types - [new Integer(2000), null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(9), null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9]))], - [new Integer(2000), new Integer(9), new Integer(4), null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [new Integer(2000), new Integer(9), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new LocalDateTime(Literal::map(["year" => 2000, "week" => 9, "dayOfWeek" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - ]; - } - - public function provideLocalDatetimeYQDData(): array - { - // [$year, $quarter, $dayOfQuarter, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] - return [ - [2000, null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], - [2000, 3, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3]))], - [2000, 3, 4, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4]))], - [2000, 3, 4, 8, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8]))], - [2000, 3, 4, 8, 25, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25]))], - [2000, 3, 4, 8, 25, 44, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], - [2000, 3, 4, 8, 25, 44, 18, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [2000, 3, 4, 8, 25, 44, 18, 6, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [2000, 3, 4, 8, 25, 44, 18, 6, 31, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - - // types - [new Integer(2000), null, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(3), null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3]))], - [new Integer(2000), new Integer(3), new Integer(4), null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [new Integer(2000), new Integer(3), new Integer(4), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new LocalDateTime(Literal::map(["year" => 2000, "quarter" => 3, "dayOfQuarter" => 4, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - ]; - } - - public function provideLocalDatetimeYQData(): array - { - // [$year, $ordinalDay, $hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] - return [ - [2000, null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], - [2000, 3, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3]))], - [2000, 3, 8, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8]))], - [2000, 3, 8, 25, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25]))], - [2000, 3, 8, 25, 44, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44]))], - [2000, 3, 8, 25, 44, 18, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [2000, 3, 8, 25, 44, 18, 6, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [2000, 3, 8, 25, 44, 18, 6, 31, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - - // types - [new Integer(2000), null, null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000]))], - [new Integer(2000), new Integer(3), null, null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3]))], - [new Integer(2000), new Integer(3), new Integer(8), null, null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), null, null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), null, null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), null, null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), null, new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6]))], - [new Integer(2000), new Integer(3), new Integer(8), new Integer(25), new Integer(44), new Integer(18), new Integer(6), new Integer(31), new LocalDateTime(Literal::map(["year" => 2000, "ordinalDay" => 3, "hour" => 8, "minute" => 25, "second" => 44, "millisecond" => 18, "microsecond" => 6, "nanosecond" => 31]))], - ]; - } - - public function provideLocalTimeData(): array - { - // [$hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] - return [ - [11, null, null, null, null, null, new LocalTime(Literal::map(["hour" => 11]))], - [11, 23, null, null, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23]))], - [11, 23, 2, null, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2]))], - [11, 23, 2, 54, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54]))], - [11, 23, 2, 54, 8, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8]))], - [11, 23, 2, 54, 8, 29, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8, "nanosecond" => 29]))], - - // types - [new Integer(11), null, null, null, null, null, new LocalTime(Literal::map(["hour" => 11]))], - [new Integer(11), new Integer(23), null, null, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23]))], - [new Integer(11), new Integer(23), new Integer(2), null, null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2]))], - [new Integer(11), new Integer(23), new Integer(2), new Integer(54), null, null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54]))], - [new Integer(11), new Integer(23), new Integer(2), new Integer(54), new Integer(8), null, new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8]))], - [new Integer(11), new Integer(23), new Integer(2), new Integer(54), new Integer(8), new Integer(29), new LocalTime(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8, "nanosecond" => 29]))], - ]; - } - - public function provideTimeData(): array - { - // [$hour, $minute, $second, $millisecond, $microsecond, $nanosecond, $expected] - return [ - [11, null, null, null, null, null, new Time(Literal::map(["hour" => 11]))], - [11, 23, null, null, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23]))], - [11, 23, 2, null, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2]))], - [11, 23, 2, 54, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54]))], - [11, 23, 2, 54, 8, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8]))], - [11, 23, 2, 54, 8, 29, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8, "nanosecond" => 29]))], - - // types - [new Integer(11), null, null, null, null, null, new Time(Literal::map(["hour" => 11]))], - [new Integer(11), new Integer(23), null, null, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23]))], - [new Integer(11), new Integer(23), new Integer(2), null, null, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2]))], - [new Integer(11), new Integer(23), new Integer(2), new Integer(54), null, null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54]))], - [new Integer(11), new Integer(23), new Integer(2), new Integer(54), new Integer(8), null, new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8]))], - [new Integer(11), new Integer(23), new Integer(2), new Integer(54), new Integer(8), new Integer(29), new Time(Literal::map(["hour" => 11, "minute" => 23, "second" => 2, "millisecond" => 54, "microsecond" => 8, "nanosecond" => 29]))], - ]; - } } diff --git a/tests/unit/Expressions/Literals/MapTest.php b/tests/unit/Expressions/Literals/MapTest.php index 9738f440..bfee9778 100644 --- a/tests/unit/Expressions/Literals/MapTest.php +++ b/tests/unit/Expressions/Literals/MapTest.php @@ -19,6 +19,33 @@ */ final class MapTest extends TestCase { + public static function provideNumericalKeysData(): array + { + return [ + [[0 => new String_('a')], "{`0`: 'a'}"], + [[0 => new String_('a'), 1 => new String_('b')], "{`0`: 'a', `1`: 'b'}"], + ]; + } + + public static function provideStringKeysData(): array + { + return [ + [['a' => new String_('a')], "{a: 'a'}"], + [['a' => new String_('a'), 'b' => new String_('b')], "{a: 'a', b: 'b'}"], + [['a' => new String_('b')], "{a: 'b'}"], + [[':' => new String_('a')], "{`:`: 'a'}"], + ]; + } + + public static function provideNestedMapsData() + { + return [ + [['a' => new Map([])], "{a: {}}"], + [['a' => new Map(['a' => new Map(['a' => new String_('b')])])], "{a: {a: {a: 'b'}}}"], + [['a' => new Map(['b' => new String_('c')]), 'b' => new String_('d')], "{a: {b: 'c'}, b: 'd'}"], + ]; + } + public function testEmpty(): void { $map = new Map([]); @@ -101,31 +128,4 @@ public function testIsInstanceOfMapType(): void $this->assertInstanceOf(MapType::class, $map); } - - public function provideNumericalKeysData(): array - { - return [ - [[0 => new String_('a')], "{`0`: 'a'}"], - [[0 => new String_('a'), 1 => new String_('b')], "{`0`: 'a', `1`: 'b'}"], - ]; - } - - public function provideStringKeysData(): array - { - return [ - [['a' => new String_('a')], "{a: 'a'}"], - [['a' => new String_('a'), 'b' => new String_('b')], "{a: 'a', b: 'b'}"], - [['a' => new String_('b')], "{a: 'b'}"], - [[':' => new String_('a')], "{`:`: 'a'}"], - ]; - } - - public function provideNestedMapsData() - { - return [ - [['a' => new Map([])], "{a: {}}"], - [['a' => new Map(['a' => new Map(['a' => new String_('b')])])], "{a: {a: {a: 'b'}}}"], - [['a' => new Map(['b' => new String_('c')]), 'b' => new String_('d')], "{a: {b: 'c'}, b: 'd'}"], - ]; - } } diff --git a/tests/unit/Expressions/Literals/StringTest.php b/tests/unit/Expressions/Literals/StringTest.php index 1be239ae..35044717 100644 --- a/tests/unit/Expressions/Literals/StringTest.php +++ b/tests/unit/Expressions/Literals/StringTest.php @@ -18,6 +18,54 @@ */ final class StringTest extends TestCase { + public static function provideSingleQuotesData(): array + { + return [ + ["a", "'a'"], + ["b", "'b'"], + ["\t", "'\\t'"], + ["\b", "'\\\\b'"], + ["\n", "'\\n'"], + ["\r", "'\\r'"], + ["\f", "'\\f'"], + ["'", "'\\''"], + ["\"", "'\\\"'"], + ["\\\\", "'\\\\\\\\'"], + ["\u1234", "'\\\\u1234'"], + ["\U12345678", "'\\\\U12345678'"], + ["\u0000", "'\\\\u0000'"], + ["\uffff", "'\\\\uffff'"], + ["\U00000000", "'\\\\U00000000'"], + ["\Uffffffff", "'\\\\Uffffffff'"], + ["\\\\b", "'\\\\\\\\b'"], + ["\t\n\\", "'\\t\\n\\\\'"], + ]; + } + + public static function provideDoubleQuotesData(): array + { + return [ + ["a", "\"a\""], + ["b", "\"b\""], + ["\t", "\"\\t\""], + ["\b", "\"\\\\b\""], + ["\n", "\"\\n\""], + ["\r", "\"\\r\""], + ["\f", "\"\\f\""], + ["'", "\"\\'\""], + ["\"", "\"\\\"\""], + ["\\\\", "\"\\\\\\\\\""], + ["\u1234", "\"\\\\u1234\""], + ["\U12345678", "\"\\\\U12345678\""], + ["\u0000", "\"\\\\u0000\""], + ["\uffff", "\"\\\\uffff\""], + ["\U00000000", "\"\\\\U00000000\""], + ["\Uffffffff", "\"\\\\Uffffffff\""], + ["\\\\b", "\"\\\\\\\\b\""], + ["\t\n\\", "\"\\t\\n\\\\\""], + ]; + } + public function testEmptySingleQuotes(): void { $string = new String_(""); @@ -68,52 +116,4 @@ public function testDoubleQuotes(string $string, string $expected): void $this->assertEquals($string, $literal->getValue()); $this->assertTrue($literal->usesDoubleQuotes()); } - - public function provideSingleQuotesData(): array - { - return [ - ["a", "'a'"], - ["b", "'b'"], - ["\t", "'\\t'"], - ["\b", "'\\\\b'"], - ["\n", "'\\n'"], - ["\r", "'\\r'"], - ["\f", "'\\f'"], - ["'", "'\\''"], - ["\"", "'\\\"'"], - ["\\\\", "'\\\\\\\\'"], - ["\u1234", "'\\\\u1234'"], - ["\U12345678", "'\\\\U12345678'"], - ["\u0000", "'\\\\u0000'"], - ["\uffff", "'\\\\uffff'"], - ["\U00000000", "'\\\\U00000000'"], - ["\Uffffffff", "'\\\\Uffffffff'"], - ["\\\\b", "'\\\\\\\\b'"], - ["\t\n\\", "'\\t\\n\\\\'"], - ]; - } - - public function provideDoubleQuotesData(): array - { - return [ - ["a", "\"a\""], - ["b", "\"b\""], - ["\t", "\"\\t\""], - ["\b", "\"\\\\b\""], - ["\n", "\"\\n\""], - ["\r", "\"\\r\""], - ["\f", "\"\\f\""], - ["'", "\"\\'\""], - ["\"", "\"\\\"\""], - ["\\\\", "\"\\\\\\\\\""], - ["\u1234", "\"\\\\u1234\""], - ["\U12345678", "\"\\\\U12345678\""], - ["\u0000", "\"\\\\u0000\""], - ["\uffff", "\"\\\\uffff\""], - ["\U00000000", "\"\\\\U00000000\""], - ["\Uffffffff", "\"\\\\Uffffffff\""], - ["\\\\b", "\"\\\\\\\\b\""], - ["\t\n\\", "\"\\t\\n\\\\\""], - ]; - } } diff --git a/tests/unit/Expressions/ParameterTest.php b/tests/unit/Expressions/ParameterTest.php index 77f7afab..dbbb341a 100644 --- a/tests/unit/Expressions/ParameterTest.php +++ b/tests/unit/Expressions/ParameterTest.php @@ -18,6 +18,24 @@ */ final class ParameterTest extends TestCase { + public static function provideToQueryData(): array + { + return [ + ["a", '$a'], + ["b", '$b'], + ["foo_bar", '$foo_bar'], + ["A", '$A'], + ]; + } + + public static function provideThrowsExceptionOnInvalidData(): array + { + return [ + [""], + [str_repeat('a', 65535)], + ]; + } + /** * @dataProvider provideToQueryData */ @@ -38,22 +56,4 @@ public function testThrowsExceptionOnInvalid(string $parameter): void new Parameter($parameter); } - - public function provideToQueryData(): array - { - return [ - ["a", '$a'], - ["b", '$b'], - ["foo_bar", '$foo_bar'], - ["A", '$A'], - ]; - } - - public function provideThrowsExceptionOnInvalidData(): array - { - return [ - [""], - [str_repeat('a', 65535)], - ]; - } } diff --git a/tests/unit/Expressions/PropertyTest.php b/tests/unit/Expressions/PropertyTest.php index 5c3c8ce0..bc418a87 100644 --- a/tests/unit/Expressions/PropertyTest.php +++ b/tests/unit/Expressions/PropertyTest.php @@ -25,6 +25,16 @@ */ final class PropertyTest extends TestCase { + public static function provideToQueryData(): array + { + return [ + [new Variable("a"), "a", "a.a"], + [new Map(["b" => new String_("c")]), "b", "{b: 'c'}.b"], + [new Variable("b"), "a", "b.a"], + [new Map([":" => new String_("c")]), ":", "{`:`: 'c'}.`:`"], + ]; + } + /** * @dataProvider provideToQueryData */ @@ -80,14 +90,4 @@ public function testReplaceWithUsesSameProperty(): void $this->assertSame($property, $replaceWith->getProperty()); } - - public function provideToQueryData(): array - { - return [ - [new Variable("a"), "a", "a.a"], - [new Map(["b" => new String_("c")]), "b", "{b: 'c'}.b"], - [new Variable("b"), "a", "b.a"], - [new Map([":" => new String_("c")]), ":", "{`:`: 'c'}.`:`"], - ]; - } } diff --git a/tests/unit/Expressions/VariableTest.php b/tests/unit/Expressions/VariableTest.php index 08c874c2..dea06368 100644 --- a/tests/unit/Expressions/VariableTest.php +++ b/tests/unit/Expressions/VariableTest.php @@ -22,6 +22,23 @@ */ final class VariableTest extends TestCase { + public static function provideToQueryData(): array + { + return [ + ["a", "a"], + ["b", "b"], + ['$foo', '`$foo`'], + ]; + } + + public static function providePropertyData(): array + { + return [ + ["a", "a", new Property(new Variable("a"), "a")], + ["a", "b", new Property(new Variable("a"), "b")], + ]; + } + public function testEmptyConstructor(): void { $variable = new Variable(); @@ -97,21 +114,4 @@ public function testProperty(string $variable, string $property, Property $expec $this->assertEquals($expected, $property); } - - public function provideToQueryData(): array - { - return [ - ["a", "a"], - ["b", "b"], - ['$foo', '`$foo`'], - ]; - } - - public function providePropertyData(): array - { - return [ - ["a", "a", new Property(new Variable("a"), "a")], - ["a", "b", new Property(new Variable("a"), "b")], - ]; - } } diff --git a/tests/unit/Patterns/NodeTest.php b/tests/unit/Patterns/NodeTest.php index dad8b1ae..8f64e3f0 100644 --- a/tests/unit/Patterns/NodeTest.php +++ b/tests/unit/Patterns/NodeTest.php @@ -27,6 +27,79 @@ */ final class NodeTest extends TestCase { + public static function provideOnlyLabelData(): array + { + return [ + ['(:a)', 'a'], + ['(:Foo:Bar)', 'Foo', 'Bar'], + ['(:`:`)', ':'], + ]; + } + + public static function provideOnlyNameData(): array + { + return [ + ['a', '(a)'], + ['A', '(A)'], + ]; + } + + public static function provideWithNameAndLabelData(): array + { + return [ + ['a', 'a', '(a:a)'], + ['A', ':', '(A:`:`)'], + ]; + } + + public static function provideWithNameAndPropertiesData(): array + { + return [ + ['a', ['a' => new String_('b'), 'b' => new String_('c')], "(a {a: 'b', b: 'c'})"], + ['b', ['a' => new Integer(0), 'b' => new Float_(1)], "(b {a: 0, b: 1.0})"], + ['c', [':' => new List_([new Integer(1), new String_('a')])], "(c {`:`: [1, 'a']})"], + ]; + } + + public static function provideWithLabelAndPropertiesData(): array + { + return [ + ['a', ['a' => new String_('b'), 'b' => new String_('c')], "(:a {a: 'b', b: 'c'})"], + ['b', ['a' => new Integer(0), 'b' => new Float_(1)], "(:b {a: 0, b: 1.0})"], + ['c', [':' => new List_([new Integer(1), new String_('a')])], "(:c {`:`: [1, 'a']})"], + ]; + } + + public static function provideOnlyPropertiesData(): array + { + return [ + [['a' => new String_('b'), 'b' => new String_('c')], "({a: 'b', b: 'c'})"], + [['a' => new Integer(0), 'b' => new Float_(-1.0)], "({a: 0, b: -1.0})"], + [[':' => new List_([new Integer(1), new String_('a')])], "({`:`: [1, 'a']})"], + ]; + } + + public static function provideWithNameAndLabelAndPropertiesData(): array + { + return [ + ['a', 'd', ['a' => new String_('b'), 'b' => new String_('c')], "(a:d {a: 'b', b: 'c'})"], + ['b', 'e', ['a' => new Integer(0), 'b' => new Float_(1)], "(b:e {a: 0, b: 1.0})"], + ['c', 'f', [':' => new List_([new Integer(1), new String_('a')])], "(c:f {`:`: [1, 'a']})"], + ]; + } + + public static function provideMultipleLabelsData(): array + { + return [ + [['a'], '(:a)'], + [['A'], '(:A)'], + [[':'], '(:`:`)'], + [['a', 'b'], '(:a:b)'], + [['A', 'B'], '(:A:B)'], + [[':', 'a'], '(:`:`:a)'], + ]; + } + public function testEmptyNode(): void { $node = new Node(); @@ -251,77 +324,4 @@ public function testLabeledMultipleLabels(): void $this->assertEquals(new Label($node->getVariable(), 'German', 'Swedish'), $labeled); } - - public function provideOnlyLabelData(): array - { - return [ - ['(:a)', 'a'], - ['(:Foo:Bar)', 'Foo', 'Bar'], - ['(:`:`)', ':'], - ]; - } - - public function provideOnlyNameData(): array - { - return [ - ['a', '(a)'], - ['A', '(A)'], - ]; - } - - public function provideWithNameAndLabelData(): array - { - return [ - ['a', 'a', '(a:a)'], - ['A', ':', '(A:`:`)'], - ]; - } - - public function provideWithNameAndPropertiesData(): array - { - return [ - ['a', ['a' => new String_('b'), 'b' => new String_('c')], "(a {a: 'b', b: 'c'})"], - ['b', ['a' => new Integer(0), 'b' => new Float_(1)], "(b {a: 0, b: 1.0})"], - ['c', [':' => new List_([new Integer(1), new String_('a')])], "(c {`:`: [1, 'a']})"], - ]; - } - - public function provideWithLabelAndPropertiesData(): array - { - return [ - ['a', ['a' => new String_('b'), 'b' => new String_('c')], "(:a {a: 'b', b: 'c'})"], - ['b', ['a' => new Integer(0), 'b' => new Float_(1)], "(:b {a: 0, b: 1.0})"], - ['c', [':' => new List_([new Integer(1), new String_('a')])], "(:c {`:`: [1, 'a']})"], - ]; - } - - public function provideOnlyPropertiesData(): array - { - return [ - [['a' => new String_('b'), 'b' => new String_('c')], "({a: 'b', b: 'c'})"], - [['a' => new Integer(0), 'b' => new Float_(-1.0)], "({a: 0, b: -1.0})"], - [[':' => new List_([new Integer(1), new String_('a')])], "({`:`: [1, 'a']})"], - ]; - } - - public function provideWithNameAndLabelAndPropertiesData(): array - { - return [ - ['a', 'd', ['a' => new String_('b'), 'b' => new String_('c')], "(a:d {a: 'b', b: 'c'})"], - ['b', 'e', ['a' => new Integer(0), 'b' => new Float_(1)], "(b:e {a: 0, b: 1.0})"], - ['c', 'f', [':' => new List_([new Integer(1), new String_('a')])], "(c:f {`:`: [1, 'a']})"], - ]; - } - - public function provideMultipleLabelsData(): array - { - return [ - [['a'], '(:a)'], - [['A'], '(:A)'], - [[':'], '(:`:`)'], - [['a', 'b'], '(:a:b)'], - [['A', 'B'], '(:A:B)'], - [[':', 'a'], '(:`:`:a)'], - ]; - } } diff --git a/tests/unit/Patterns/RelationshipTest.php b/tests/unit/Patterns/RelationshipTest.php index 1acbccae..75349e61 100644 --- a/tests/unit/Patterns/RelationshipTest.php +++ b/tests/unit/Patterns/RelationshipTest.php @@ -24,6 +24,123 @@ */ final class RelationshipTest extends TestCase { + public static function provideVariableLengthRelationshipsWithNameData(): array + { + return [ + ['b', 0, 100, Direction::UNI, '-[b*0..100]-'], + ['b', 5, 5, Direction::RIGHT, '-[b*5..5]->'], + ['a', 10, null, Direction::UNI, '-[a*10..]-'], + ['a', null, 10, Direction::LEFT, '<-[a*..10]-'], + ]; + } + + public static function provideVariableLengthRelationshipsWithTypeData(): array + { + return [ + ['', 1, 100, Direction::LEFT, '<-[*1..100]-'], + ['a', 10, null, Direction::LEFT, '<-[:a*10..]-'], + [':', null, 10, Direction::LEFT, '<-[:`:`*..10]-'], + ]; + } + + public static function provideVariableLengthRelationshipsWithPropertiesData(): array + { + return [ + [[], 10, 100, Direction::LEFT, "<-[*10..100]-"], + [[new String_('a')], 10, null, Direction::LEFT, "<-[*10.. {`0`: 'a'}]-"], + [['a' => new String_('b')], null, 10, Direction::LEFT, "<-[*..10 {a: 'b'}]-"], + ]; + } + + public static function provideVariableLengthRelationshipsWithNameAndTypeAndPropertiesData(): array + { + return [ + ['a', 'a', [], 10, 100, Direction::LEFT, "<-[a:a*10..100]-"], + ['b', 'a', [new String_('a')], null, 10, Direction::LEFT, "<-[b:a*..10 {`0`: 'a'}]-"], + ['a', 'b', [new String_('a')], 10, 100, Direction::LEFT, "<-[a:b*10..100 {`0`: 'a'}]-"], + ['a', '', ['a' => new String_('b')], null, 10, Direction::LEFT, "<-[a*..10 {a: 'b'}]-"], + ['a', ':', ['a' => new String_('b'), new String_('c')], 10, null, Direction::LEFT, "<-[a:`:`*10.. {a: 'b', `0`: 'c'}]-"], + ]; + } + + public static function provideWithNameData(): array + { + return [ + ['a', Direction::UNI, '-[a]-'], + ['a', Direction::LEFT, '<-[a]-'], + ['a', Direction::RIGHT, '-[a]->'], + ]; + } + + public static function provideAddTypeData(): array + { + return [ + ['', Direction::LEFT, '<--'], + ['a', Direction::LEFT, '<-[:a]-'], + [':', Direction::LEFT, '<-[:`:`]-'], + ]; + } + + public static function provideWithTypesData(): array + { + return [ + [['', 'a'], Direction::LEFT, '<-[:a]-'], + [['a', 'b'], Direction::LEFT, '<-[:a|b]-'], + [['', 'a', 'b'], Direction::LEFT, '<-[:a|b]-'], + [['a', '', 'b'], Direction::LEFT, '<-[:a|b]-'], + [['a', 'b', ':'], Direction::LEFT, '<-[:a|b|`:`]-'], + ]; + } + + public static function provideWithPropertiesData(): array + { + return [ + [[], Direction::LEFT, "<--"], + [[new String_('a')], Direction::LEFT, "<-[{`0`: 'a'}]-"], + [['a' => new String_('b')], Direction::LEFT, "<-[{a: 'b'}]-"], + [['a' => new String_('b'), new String_('c')], Direction::LEFT, "<-[{a: 'b', `0`: 'c'}]-"], + [[':' => new Integer(12)], Direction::LEFT, "<-[{`:`: 12}]-"], + [['a' => 'b', 'c' => 12, 'd' => 12.38], Direction::LEFT, "<-[{a: 'b', c: 12, d: 12.38}]-"], + ]; + } + + public static function provideWithNameAndTypeData(): array + { + return [ + ['a', '', Direction::LEFT, '<-[a]-'], + ['a', 'b', Direction::LEFT, '<-[a:b]-'], + ]; + } + + public static function provideWithNameAndPropertiesData(): array + { + return [ + ['a', [], Direction::LEFT, "<-[a]-"], + ['b', [new String_('a')], Direction::LEFT, "<-[b {`0`: 'a'}]-"], + ]; + } + + public static function provideWithNameAndTypeAndPropertiesData(): array + { + return [ + ['a', 'a', [], Direction::LEFT, "<-[a:a]-"], + ['b', 'a', [new String_('a')], Direction::LEFT, "<-[b:a {`0`: 'a'}]-"], + ['a', 'b', [new String_('a')], Direction::LEFT, "<-[a:b {`0`: 'a'}]-"], + ['a', '', ['a' => new String_('b')], Direction::LEFT, "<-[a {a: 'b'}]-"], + ['a', ':', ['a' => new String_('b'), new String_('c')], Direction::LEFT, "<-[a:`:` {a: 'b', `0`: 'c'}]-"], + ]; + } + + public static function provideWithMultipleTypesData(): array + { + return [ + ['a', [], [], Direction::LEFT, "<-[a]-"], + ['b', ['a'], [new String_('a')], Direction::LEFT, "<-[b:a {`0`: 'a'}]-"], + ['a', ['a', 'b', 'c'], [new String_('a')], Direction::LEFT, "<-[a:a|b|c {`0`: 'a'}]-"], + ['a', ['a', 'b'], [], Direction::LEFT, "<-[a:a|b]-"], + ]; + } + public function testDirRight(): void { $r = new Relationship(Direction::RIGHT); @@ -492,121 +609,4 @@ public function testGetTypes(): void $this->assertSame(['a', 'b'], $r->getTypes()); } - - public function provideVariableLengthRelationshipsWithNameData(): array - { - return [ - ['b', 0, 100, Direction::UNI, '-[b*0..100]-'], - ['b', 5, 5, Direction::RIGHT, '-[b*5..5]->'], - ['a', 10, null, Direction::UNI, '-[a*10..]-'], - ['a', null, 10, Direction::LEFT, '<-[a*..10]-'], - ]; - } - - public function provideVariableLengthRelationshipsWithTypeData(): array - { - return [ - ['', 1, 100, Direction::LEFT, '<-[*1..100]-'], - ['a', 10, null, Direction::LEFT, '<-[:a*10..]-'], - [':', null, 10, Direction::LEFT, '<-[:`:`*..10]-'], - ]; - } - - public function provideVariableLengthRelationshipsWithPropertiesData(): array - { - return [ - [[], 10, 100, Direction::LEFT, "<-[*10..100]-"], - [[new String_('a')], 10, null, Direction::LEFT, "<-[*10.. {`0`: 'a'}]-"], - [['a' => new String_('b')], null, 10, Direction::LEFT, "<-[*..10 {a: 'b'}]-"], - ]; - } - - public function provideVariableLengthRelationshipsWithNameAndTypeAndPropertiesData(): array - { - return [ - ['a', 'a', [], 10, 100, Direction::LEFT, "<-[a:a*10..100]-"], - ['b', 'a', [new String_('a')], null, 10, Direction::LEFT, "<-[b:a*..10 {`0`: 'a'}]-"], - ['a', 'b', [new String_('a')], 10, 100, Direction::LEFT, "<-[a:b*10..100 {`0`: 'a'}]-"], - ['a', '', ['a' => new String_('b')], null, 10, Direction::LEFT, "<-[a*..10 {a: 'b'}]-"], - ['a', ':', ['a' => new String_('b'), new String_('c')], 10, null, Direction::LEFT, "<-[a:`:`*10.. {a: 'b', `0`: 'c'}]-"], - ]; - } - - public function provideWithNameData(): array - { - return [ - ['a', Direction::UNI, '-[a]-'], - ['a', Direction::LEFT, '<-[a]-'], - ['a', Direction::RIGHT, '-[a]->'], - ]; - } - - public function provideAddTypeData(): array - { - return [ - ['', Direction::LEFT, '<--'], - ['a', Direction::LEFT, '<-[:a]-'], - [':', Direction::LEFT, '<-[:`:`]-'], - ]; - } - - public function provideWithTypesData(): array - { - return [ - [['', 'a'], Direction::LEFT, '<-[:a]-'], - [['a', 'b'], Direction::LEFT, '<-[:a|b]-'], - [['', 'a', 'b'], Direction::LEFT, '<-[:a|b]-'], - [['a', '', 'b'], Direction::LEFT, '<-[:a|b]-'], - [['a', 'b', ':'], Direction::LEFT, '<-[:a|b|`:`]-'], - ]; - } - - public function provideWithPropertiesData(): array - { - return [ - [[], Direction::LEFT, "<--"], - [[new String_('a')], Direction::LEFT, "<-[{`0`: 'a'}]-"], - [['a' => new String_('b')], Direction::LEFT, "<-[{a: 'b'}]-"], - [['a' => new String_('b'), new String_('c')], Direction::LEFT, "<-[{a: 'b', `0`: 'c'}]-"], - [[':' => new Integer(12)], Direction::LEFT, "<-[{`:`: 12}]-"], - [['a' => 'b', 'c' => 12, 'd' => 12.38], Direction::LEFT, "<-[{a: 'b', c: 12, d: 12.38}]-"], - ]; - } - - public function provideWithNameAndTypeData(): array - { - return [ - ['a', '', Direction::LEFT, '<-[a]-'], - ['a', 'b', Direction::LEFT, '<-[a:b]-'], - ]; - } - - public function provideWithNameAndPropertiesData(): array - { - return [ - ['a', [], Direction::LEFT, "<-[a]-"], - ['b', [new String_('a')], Direction::LEFT, "<-[b {`0`: 'a'}]-"], - ]; - } - - public function provideWithNameAndTypeAndPropertiesData(): array - { - return [ - ['a', 'a', [], Direction::LEFT, "<-[a:a]-"], - ['b', 'a', [new String_('a')], Direction::LEFT, "<-[b:a {`0`: 'a'}]-"], - ['a', 'b', [new String_('a')], Direction::LEFT, "<-[a:b {`0`: 'a'}]-"], - ['a', '', ['a' => new String_('b')], Direction::LEFT, "<-[a {a: 'b'}]-"], - ['a', ':', ['a' => new String_('b'), new String_('c')], Direction::LEFT, "<-[a:`:` {a: 'b', `0`: 'c'}]-"], - ]; - } - - public function provideWithMultipleTypesData(): array - { - return [ - ['a', [], [], Direction::LEFT, "<-[a]-"], - ['b', ['a'], [new String_('a')], Direction::LEFT, "<-[b:a {`0`: 'a'}]-"], - ['a', ['a', 'b', 'c'], [new String_('a')], Direction::LEFT, "<-[a:a|b|c {`0`: 'a'}]-"], - ['a', ['a', 'b'], [], Direction::LEFT, "<-[a:a|b]-"], - ]; - } } diff --git a/tests/unit/QueryTest.php b/tests/unit/QueryTest.php index e01454f6..215373db 100644 --- a/tests/unit/QueryTest.php +++ b/tests/unit/QueryTest.php @@ -45,6 +45,25 @@ */ final class QueryTest extends TestCase { + /** + * @return mixed[][] + */ + public static function provideLiteralData(): array + { + return [ + ['foobar', new String_('foobar')], + ['0', new String_('0')], + ['100', new String_('100')], + [0, new Integer(0)], + [100, new Integer(100)], + [10.0, new Float_(10.0)], + [69420.0, new Float_(69420)], + [10.0000000000000000000000000000001, new Float_(10.0000000000000000000000000000001)], + [false, new Boolean(false)], + [true, new Boolean(true)], + ]; + } + public function testNew(): void { $new = Query::new(); @@ -218,11 +237,9 @@ public function current(): int return 1; } - public function next(): int + public function next(): void { $this->count++; - - return 1; } public function key(): int @@ -413,23 +430,4 @@ public function testAutomaticIdentifierGeneration(): void $this->assertInstanceOf(Variable::class, $node->getVariable()); } - - /** - * @return mixed[][] - */ - public function provideLiteralData(): array - { - return [ - ['foobar', new String_('foobar')], - ['0', new String_('0')], - ['100', new String_('100')], - [0, new Integer(0)], - [100, new Integer(100)], - [10.0, new Float_(10.0)], - [69420.0, new Float_(69420)], - [10.0000000000000000000000000000001, new Float_(10.0000000000000000000000000000001)], - [false, new Boolean(false)], - [true, new Boolean(true)], - ]; - } } diff --git a/tests/unit/Utils/CastUtilsTest.php b/tests/unit/Utils/CastUtilsTest.php index fa77a547..5b687c2b 100644 --- a/tests/unit/Utils/CastUtilsTest.php +++ b/tests/unit/Utils/CastUtilsTest.php @@ -7,8 +7,157 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace WikibaseSolutions\CypherDSL\Tests\unit\Utils; +namespace WikibaseSolutions\CypherDSL\Tests\Unit\Utils; -class CastUtilsTest +use PHPUnit\Framework\TestCase; +use WikibaseSolutions\CypherDSL\Expressions\Literals\Literal; +use WikibaseSolutions\CypherDSL\Expressions\Variable; +use WikibaseSolutions\CypherDSL\Query; +use WikibaseSolutions\CypherDSL\Types\CompositeTypes\ListType; +use WikibaseSolutions\CypherDSL\Types\CompositeTypes\MapType; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\BooleanType; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\FloatType; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\IntegerType; +use WikibaseSolutions\CypherDSL\Types\PropertyTypes\StringType; +use WikibaseSolutions\CypherDSL\Types\StructuralTypes\StructuralType; +use WikibaseSolutions\CypherDSL\Utils\CastUtils; + +/** + * @covers \WikibaseSolutions\CypherDSL\Utils\CastUtils + */ +class CastUtilsTest extends TestCase { + public function testToListType(): void + { + $list = CastUtils::toListType(['a', 'b', 'c']); + + $this->assertInstanceOf(ListType::class, $list); + + $list = Literal::list(['a', 'b', 'c']); + $list = CastUtils::toListType($list); + + $this->assertInstanceOf(ListType::class, $list); + } + + public function testToMapType(): void + { + $map = CastUtils::toMapType(['a' => 'a', 'b' => 'b', 'c' => 'c']); + + $this->assertInstanceOf(MapType::class, $map); + + $map = Literal::map(['a' => 'a', 'b' => 'b', 'c' => 'c']); + $map = CastUtils::toMapType($map); + + $this->assertInstanceOf(MapType::class, $map); + } + + public function testToStringType(): void + { + $string = CastUtils::toStringType('hello'); + + $this->assertInstanceOf(StringType::class, $string); + + $string = Literal::string('a'); + $string = CastUtils::toStringType($string); + + $this->assertInstanceOf(StringType::class, $string); + } + + public function testToNumeralType(): void + { + $numeral = CastUtils::toNumeralType(1); + + $this->assertInstanceOf(IntegerType::class, $numeral); + + $numeral = CastUtils::toNumeralType(1.1); + + $this->assertInstanceOf(FloatType::class, $numeral); + + $numeral = Literal::number(1.1); + $numeral = CastUtils::toNumeralType($numeral); + + $this->assertInstanceOf(FloatType::class, $numeral); + + $numeral = Literal::number(1); + $numeral = CastUtils::toNumeralType($numeral); + + $this->assertInstanceOf(IntegerType::class, $numeral); + } + + public function testToIntegerType(): void + { + $integer = CastUtils::toIntegerType(10); + + $this->assertInstanceOf(IntegerType::class, $integer); + + $integer = Literal::integer(10); + $integer = CastUtils::toIntegerType($integer); + + $this->assertInstanceOf(IntegerType::class, $integer); + } + + public function testToBooleanType(): void + { + $boolean = CastUtils::toBooleanType(true); + + $this->assertInstanceOf(BooleanType::class, $boolean); + + $boolean = Literal::boolean(true); + $boolean = CastUtils::toBooleanType($boolean); + + $this->assertInstanceOf(BooleanType::class, $boolean); + } + + public function testToPropertyType(): void + { + $property = CastUtils::toPropertyType('test'); + + $this->assertInstanceOf(StringType::class, $property); + + $property = CastUtils::toPropertyType(true); + + $this->assertInstanceOf(BooleanType::class, $property); + + $property = Literal::boolean(true); + $property = CastUtils::toBooleanType($property); + + $this->assertInstanceOf(BooleanType::class, $property); + } + + public function testToStructuralType(): void + { + $structural = CastUtils::toStructuralType(Query::node()); + + $this->assertInstanceOf(StructuralType::class, $structural); + + $structural = CastUtils::toStructuralType(Query::node()->getVariable()); + + $this->assertInstanceOf(StructuralType::class, $structural); + } + + public function testToVariable(): void + { + $variable = CastUtils::toVariable('a'); + + $this->assertInstanceOf(Variable::class, $variable); + + $variable = CastUtils::toVariable(Query::node()); + + $this->assertInstanceOf(Variable::class, $variable); + + $variable = CastUtils::toVariable(new Variable('a')); + + $this->assertInstanceOf(Variable::class, $variable); + } + + public function testToName(): void + { + $name = CastUtils::toName('a'); + + $this->assertInstanceOf(Variable::class, $name); + + $name = CastUtils::toName(new Variable('a')); + + $this->assertInstanceOf(Variable::class, $name); + } } diff --git a/tests/unit/Utils/NameUtilsTest.php b/tests/unit/Utils/NameUtilsTest.php index d35e0a2b..ed770ced 100644 --- a/tests/unit/Utils/NameUtilsTest.php +++ b/tests/unit/Utils/NameUtilsTest.php @@ -7,8 +7,112 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace WikibaseSolutions\CypherDSL\Tests\unit\Utils; +namespace WikibaseSolutions\CypherDSL\Tests\Unit\Utils; -class NameUtilsTest +use InvalidArgumentException; +use PHPUnit\Framework\TestCase; +use WikibaseSolutions\CypherDSL\Utils\NameUtils; + +/** + * @covers \WikibaseSolutions\CypherDSL\Utils\NameUtils + */ +class NameUtilsTest extends TestCase { + public static function provideSafeValueIsNotEscapedData(): array + { + return [ + ['foobar'], + ['fooBar'], + ['FOOBAR'], + ['foo_bar'], + ['FOO_BAR'], + ['aaa'], + ['aaa100'], + ['a0'], + ['z10'], + ['z99'], + ['ça'], + ['日'], + ]; + } + + public static function provideUnsafeValueIsEscapedData(): array + { + return [ + ['__FooBar__'], + ['_'], + ['__'], + ['\''], + ['"'], + ['0'], + ['10'], + ['100'], + ['1'], + ['2'], + ]; + } + + public static function provideValueWithBacktickIsProperlyEscapedData(): array + { + return [ + ['foo`bar', '`foo``bar`'], + ['`foo', '```foo`'], + ['foo`', '`foo```'], + ['foo``bar', '`foo````bar`'], + ['`foo`', '```foo```'], + ]; + } + + /** + * @dataProvider provideSafeValueIsNotEscapedData + */ + public function testSafeValueIsNotEscaped(string $expected): void + { + $actual = NameUtils::escape($expected); + + $this->assertSame($expected, $actual); + } + + /** + * @dataProvider provideUnsafeValueIsEscapedData + */ + public function testUnsafeValueIsEscaped(string $value): void + { + $expected = sprintf("`%s`", $value); + $actual = NameUtils::escape($value); + + $this->assertSame($expected, $actual); + } + + /** + * @dataProvider provideValueWithBacktickIsProperlyEscapedData + */ + public function testValueWithBacktickIsProperlyEscaped($input, $expected): void + { + $this->assertSame($expected, NameUtils::escape($input)); + } + + public function testValueWithMoreThan65534CharactersCannotBeEscaped(): void + { + $value = str_repeat('a', 65535); + + $this->expectException(InvalidArgumentException::class); + + NameUtils::escape($value); + } + + public function testGenerateIdentifierWithoutPrefix(): void + { + $this->assertMatchesRegularExpression('/^var\w{32}$/', NameUtils::generateIdentifier()); + } + + public function testGenerateIdentifierWithPrefix(): void + { + $this->assertMatchesRegularExpression('/^x\w{32}$/', NameUtils::generateIdentifier('x')); + } + + public function testGenerateIdentifierWithPrefixAndLength(): void + { + $this->assertMatchesRegularExpression('/^x\w{16}$/', NameUtils::generateIdentifier('x', 16)); + } } From 08ee9c974efee5738213b82b51175fc23cee90ea Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Tue, 3 Feb 2026 19:55:32 +0100 Subject: [PATCH 10/12] Update README --- README.md | 23 ++++++++++++----------- composer.json | 2 +- tests/end-to-end/ExamplesTest.php | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index f6afc161..1f71a1fd 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,20 @@ # php-cypher-dsl -The `php-cypher-dsl` library provides a way to construct advanced Cypher -queries in an object-oriented and type-safe manner. +The `php-cypher-dsl` library provides a way to construct Cypher queries in a type-safe manner. ## Documentation -[The documentation can be found on the wiki -here.](https://github.com/WikibaseSolutions/php-cypher-dsl/wiki) +[The documentation can be found on the wiki here.](https://github.com/WikibaseSolutions/php-cypher-dsl/wiki) ## Installation ### Requirements -`php-cypher-dsl` requires PHP 7.4 or greater; using the latest version of PHP -is highly recommended. +`php-cypher-dsl` requires PHP 8.1 or greater; using the latest version of PHP is highly recommended. ### Installation through Composer -You can install `php-cypher-dsl` through composer by running the following -command: +You can install `php-cypher-dsl` through Composer by running the following command: ``` composer require "wikibase-solutions/php-cypher-dsl" @@ -30,8 +26,7 @@ Please refer to [CONTRIBUTING.md](https://github.com/neo4j-php/php-cypher-dsl/bl ## Example -To construct a query to find all of Tom Hanks' co-actors, you can use the -following code: +To construct a query to find all of Tom Hanks' co-actors, you can use the following code: ```php use function WikibaseSolutions\CypherDSL\node; @@ -41,7 +36,13 @@ $tom = node("Person")->withProperties(["name" => "Tom Hanks"]); $coActors = node(); $statement = query() - ->match($tom->relationshipTo(Query::node(), "ACTED_IN")->relationshipFrom($coActors, "ACTED_IN")) + ->match($tom->relationshipTo(node(), "ACTED_IN")->relationshipFrom($coActors, "ACTED_IN")) ->returning($coActors->property("name")) ->build(); ``` + +This produces the following Cypher query (where `$1` is a random variable name): + +``` +MATCH (:Person {name: 'Tom Hanks'})-[:ACTED_IN]->()<-[:ACTED_IN]-($1) RETURN $1.name +``` diff --git a/composer.json b/composer.json index 55de8356..b599bdb5 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "wikibase-solutions/php-cypher-dsl", - "description": "A query builder for the Cypher query language written in PHP", + "description": "A query builder for the Cypher query language", "type": "library", "keywords": [ "neo4j", diff --git a/tests/end-to-end/ExamplesTest.php b/tests/end-to-end/ExamplesTest.php index fa75a78d..095ae3e1 100644 --- a/tests/end-to-end/ExamplesTest.php +++ b/tests/end-to-end/ExamplesTest.php @@ -32,7 +32,7 @@ */ final class ExamplesTest extends TestCase { - public function testReadmeExample(): void + public function testOldReadmeExample(): void { $tom = node("Person")->withProperties(["name" => "Tom Hanks"]); $coActors = node(); From 2090f6085eb4aac1b7252bdbc11f0df07b56053c Mon Sep 17 00:00:00 2001 From: Marijn van Wezel Date: Tue, 3 Feb 2026 19:56:20 +0100 Subject: [PATCH 11/12] Update workflow with newer PHP versions --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ebca4dba..c4c126ed 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,13 +14,13 @@ jobs: strategy: matrix: - php-version: [ "7.4", "8.0", "8.1", "8.2" ] + php-version: [ "8.1", "8.2", "8.3", "8.4", "8.5" ] env: COMPOSER_VERSION: 2 COVERAGE_DRIVER: xdebug MINIMUM_COVERAGE_PERCENTAGE: 90 - MINIMUM_MSI_PERCENTAGE: 80 + MINIMUM_MSI_PERCENTAGE: 85 steps: - name: Checkout repository From 69fad51a6910095968248d4cd24d35d1d1514989 Mon Sep 17 00:00:00 2001 From: Marijn van Wezel <96489967+marijnvanwezel@users.noreply.github.com> Date: Tue, 3 Feb 2026 19:59:06 +0100 Subject: [PATCH 12/12] Fix minimum MSI threshold for infection tool Signed-off-by: Marijn van Wezel <96489967+marijnvanwezel@users.noreply.github.com> --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 72b8eb99..9d79d838 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -69,7 +69,7 @@ After making your changes and adding your tests, you can check whether the minim ``` $ XDEBUG_MODE=coverage php vendor/bin/phpunit --testsuite unit $ php vendor/bin/coverage-check coverage/clover.xml 90 -$ XDEBUG_MODE=coverage php vendor/bin/infection --min-msi=8 +$ XDEBUG_MODE=coverage php vendor/bin/infection --min-msi=85 ``` ## Running test suites