From 1b22f95a8655cd0ddd6143868ab00a99e81594f0 Mon Sep 17 00:00:00 2001 From: Vladimir Razuvaev Date: Sun, 27 May 2018 19:13:32 +0700 Subject: [PATCH] Removed previously deprecated classes/methods --- composer.json | 1 - src/Error.php | 18 - src/Executor/Executor.php | 26 - src/GraphQL.php | 8 + src/Language/Lexer.php | 9 - src/Language/Token.php | 34 -- src/Schema.php | 4 + src/Server.php | 604 ------------------- src/Type/Definition/Config.php | 307 ---------- src/Type/Definition/DirectiveLocation.php | 17 - src/Type/Definition/EnumType.php | 11 - src/Type/Definition/FieldDefinition.php | 61 -- src/Type/Definition/InputObjectType.php | 11 - src/Type/Definition/InterfaceType.php | 10 - src/Type/Definition/ObjectType.php | 17 - src/Type/Definition/ResolveInfo.php | 17 - src/Type/Definition/UnionType.php | 16 - src/Type/Introspection.php | 6 +- src/Type/Schema.php | 15 - src/Type/SchemaConfig.php | 14 - src/Utils.php | 14 - src/deprecated.php | 36 -- tests/Executor/AbstractPromiseTest.php | 16 +- tests/Executor/AbstractTest.php | 6 +- tests/Executor/DeferredFieldsTest.php | 2 +- tests/Executor/DirectivesTest.php | 2 +- tests/Executor/ExecutorTest.php | 3 +- tests/Executor/LazyInterfaceTest.php | 2 +- tests/Executor/ListsTest.php | 2 +- tests/Executor/MutationsTest.php | 2 +- tests/Executor/NonNullTest.php | 2 +- tests/Executor/ResolveTest.php | 16 +- tests/Executor/UnionInterfaceTest.php | 2 +- tests/ServerTest.php | 626 -------------------- tests/StarWarsIntrospectionTest.php | 2 +- tests/StarWarsQueryTest.php | 10 +- tests/StarWarsSchema.php | 2 +- tests/Type/ConfigTest.php | 682 ---------------------- tests/Type/EnumTypeTest.php | 36 +- tests/Type/IntrospectionTest.php | 22 +- tests/Type/ResolveInfoTest.php | 6 +- 41 files changed, 86 insertions(+), 2611 deletions(-) delete mode 100644 src/Error.php delete mode 100644 src/Server.php delete mode 100644 src/Type/Definition/Config.php delete mode 100644 src/Type/Definition/DirectiveLocation.php delete mode 100644 src/Utils.php delete mode 100644 src/deprecated.php delete mode 100644 tests/ServerTest.php delete mode 100644 tests/Type/ConfigTest.php diff --git a/composer.json b/composer.json index 493767b..d48b76a 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,6 @@ "sort-packages": true }, "autoload": { - "files": ["src/deprecated.php"], "psr-4": { "GraphQL\\": "src/" } diff --git a/src/Error.php b/src/Error.php deleted file mode 100644 index b7ac3c6..0000000 --- a/src/Error.php +++ /dev/null @@ -1,18 +0,0 @@ -toArray() as a quick replacement', + E_USER_DEPRECATED + ); $result = self::promiseToExecute( $promiseAdapter = Executor::getPromiseAdapter(), $schema, @@ -223,6 +227,10 @@ class GraphQL $operationName = null ) { + trigger_error( + __METHOD__ . ' is deprecated, use GraphQL::executeQuery() as a quick replacement', + E_USER_DEPRECATED + ); $result = self::promiseToExecute( $promiseAdapter = Executor::getPromiseAdapter(), $schema, diff --git a/src/Language/Lexer.php b/src/Language/Lexer.php index 5ea7992..924f8e0 100644 --- a/src/Language/Lexer.php +++ b/src/Language/Lexer.php @@ -108,15 +108,6 @@ class Lexer return $token; } - /** - * @return Token - */ - public function nextToken() - { - trigger_error(__METHOD__ . ' is deprecated in favor of advance()', E_USER_DEPRECATED); - return $this->advance(); - } - /** * @param Token $prev * @return Token diff --git a/src/Language/Token.php b/src/Language/Token.php index f98d686..4b433d1 100644 --- a/src/Language/Token.php +++ b/src/Language/Token.php @@ -30,40 +30,6 @@ class Token const BLOCK_STRING = 'BlockString'; const COMMENT = 'Comment'; - /** - * @param $kind - * @return mixed - */ - public static function getKindDescription($kind) - { - trigger_error('Deprecated as of 16.10.2016 ($kind itself contains description string now)', E_USER_DEPRECATED); - - $description = []; - $description[self::SOF] = ''; - $description[self::EOF] = ''; - $description[self::BANG] = '!'; - $description[self::DOLLAR] = '$'; - $description[self::PAREN_L] = '('; - $description[self::PAREN_R] = ')'; - $description[self::SPREAD] = '...'; - $description[self::COLON] = ':'; - $description[self::EQUALS] = '='; - $description[self::AT] = '@'; - $description[self::BRACKET_L] = '['; - $description[self::BRACKET_R] = ']'; - $description[self::BRACE_L] = '{'; - $description[self::PIPE] = '|'; - $description[self::BRACE_R] = '}'; - $description[self::NAME] = 'Name'; - $description[self::INT] = 'Int'; - $description[self::FLOAT] = 'Float'; - $description[self::STRING] = 'String'; - $description[self::BLOCK_STRING] = 'BlockString'; - $description[self::COMMENT] = 'Comment'; - - return $description[$kind]; - } - /** * The kind of Token (see one of constants above). * diff --git a/src/Schema.php b/src/Schema.php index 42cc703..39d500b 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -1,6 +1,10 @@ queryType; - } - - /** - * @param ObjectType $queryType - * @return Server - */ - public function setQueryType(ObjectType $queryType) - { - $this->assertSchemaNotSet('Query Type', __METHOD__); - $this->queryType = $queryType; - return $this; - } - - /** - * @return ObjectType|null - */ - public function getMutationType() - { - return $this->mutationType; - } - - /** - * @param ObjectType $mutationType - * @return Server - */ - public function setMutationType(ObjectType $mutationType) - { - $this->assertSchemaNotSet('Mutation Type', __METHOD__); - $this->mutationType = $mutationType; - return $this; - } - - /** - * @return ObjectType|null - */ - public function getSubscriptionType() - { - return $this->subscriptionType; - } - - /** - * @param ObjectType $subscriptionType - * @return Server - */ - public function setSubscriptionType($subscriptionType) - { - $this->assertSchemaNotSet('Subscription Type', __METHOD__); - $this->subscriptionType = $subscriptionType; - return $this; - } - - /** - * @param Type[] $types - * @return Server - */ - public function addTypes(array $types) - { - if (!empty($types)) { - $this->assertSchemaNotSet('Types', __METHOD__); - $this->types = array_merge($this->types, $types); - } - return $this; - } - - /** - * @return array - */ - public function getTypes() - { - return $this->types; - } - - /** - * @return Directive[] - */ - public function getDirectives() - { - if (null === $this->directives) { - $this->directives = Directive::getInternalDirectives(); - } - - return $this->directives; - } - - /** - * @param Directive[] $directives - * @return Server - */ - public function setDirectives(array $directives) - { - $this->assertSchemaNotSet('Directives', __METHOD__); - $this->directives = $directives; - return $this; - } - - /** - * @return int - */ - public function getDebug() - { - return $this->debug; - } - - /** - * @param int $debug - * @return Server - */ - public function setDebug($debug = self::DEBUG_ALL) - { - $this->debug = (int) $debug; - return $this; - } - - /** - * @return mixed - */ - public function getContext() - { - return $this->contextValue; - } - - /** - * @param mixed $context - * @return Server - */ - public function setContext($context) - { - $this->contextValue = $context; - return $this; - } - - /** - * @param $rootValue - * @return Server - */ - public function setRootValue($rootValue) - { - $this->rootValue = $rootValue; - return $this; - } - - /** - * @return mixed - */ - public function getRootValue() - { - return $this->rootValue; - } - - /** - * Set schema instance manually. Mutually exclusive with `setQueryType`, `setMutationType`, `setSubscriptionType`, `setDirectives`, `addTypes` - * - * @param Schema $schema - * @return $this - */ - public function setSchema(Schema $schema) - { - if ($this->queryType) { - $err = 'Query Type is already set'; - $errMethod = __CLASS__ . '::setQueryType'; - } else if ($this->mutationType) { - $err = 'Mutation Type is already set'; - $errMethod = __CLASS__ . '::setMutationType'; - } else if ($this->subscriptionType) { - $err = 'Subscription Type is already set'; - $errMethod = __CLASS__ . '::setSubscriptionType'; - } else if ($this->directives) { - $err = 'Directives are already set'; - $errMethod = __CLASS__ . '::setDirectives'; - } else if ($this->types) { - $err = 'Additional types are already set'; - $errMethod = __CLASS__ . '::addTypes'; - } else if ($this->typeResolutionStrategy) { - $err = 'Type Resolution Strategy is already set'; - $errMethod = __CLASS__ . '::setTypeResolutionStrategy'; - } else if ($this->schema && $this->schema !== $schema) { - $err = 'Different schema is already set'; - } - - if (isset($err)) { - if (isset($errMethod)) { - $err .= " ($errMethod is mutually exclusive with " . __METHOD__ . ")"; - } - throw new InvariantViolation("Cannot set Schema on Server: $err"); - } - $this->schema = $schema; - return $this; - } - - /** - * @param $entry - * @param $mutuallyExclusiveMethod - */ - private function assertSchemaNotSet($entry, $mutuallyExclusiveMethod) - { - if ($this->schema) { - $schemaMethod = __CLASS__ . '::setSchema'; - throw new InvariantViolation("Cannot set $entry on Server: Schema is already set ($mutuallyExclusiveMethod is mutually exclusive with $schemaMethod)"); - } - } - - /** - * @return Schema - */ - public function getSchema() - { - if (null === $this->schema) { - $this->schema = new Schema([ - 'query' => $this->queryType, - 'mutation' => $this->mutationType, - 'subscription' => $this->subscriptionType, - 'directives' => $this->directives, - 'types' => $this->types, - 'typeResolution' => $this->typeResolutionStrategy - ]); - } - return $this->schema; - } - - /** - * @return callable - */ - public function getPhpErrorFormatter() - { - return $this->phpErrorFormatter; - } - - /** - * Expects function(\ErrorException $e) : array - * - * @param callable $phpErrorFormatter - * @return $this - */ - public function setPhpErrorFormatter(callable $phpErrorFormatter) - { - $this->phpErrorFormatter = $phpErrorFormatter; - return $this; - } - - /** - * @return callable - */ - public function getExceptionFormatter() - { - return $this->exceptionFormatter; - } - - /** - * Expects function(Exception $e) : array - * - * @param callable $exceptionFormatter - * @return $this - */ - public function setExceptionFormatter(callable $exceptionFormatter) - { - $this->exceptionFormatter = $exceptionFormatter; - return $this; - } - - /** - * @return string - */ - public function getUnexpectedErrorMessage() - { - return $this->unexpectedErrorMessage; - } - - /** - * @param string $unexpectedErrorMessage - * @return $this - */ - public function setUnexpectedErrorMessage($unexpectedErrorMessage) - { - $this->unexpectedErrorMessage = $unexpectedErrorMessage; - return $this; - } - - /** - * @return int - */ - public function getUnexpectedErrorStatus() - { - return $this->unexpectedErrorStatus; - } - - /** - * @param int $unexpectedErrorStatus - * @return $this - */ - public function setUnexpectedErrorStatus($unexpectedErrorStatus) - { - $this->unexpectedErrorStatus = $unexpectedErrorStatus; - return $this; - } - - /** - * Parses GraphQL query string and returns Abstract Syntax Tree for this query - * - * @param string $query - * @return Language\AST\DocumentNode - * @throws \GraphQL\Error\SyntaxError - */ - public function parse($query) - { - return Parser::parse($query); - } - - /** - * @return array - */ - public function getValidationRules() - { - if (null === $this->validationRules) { - $this->validationRules = DocumentValidator::allRules(); - } - return $this->validationRules; - } - - /** - * @param array $validationRules - * @return $this - */ - public function setValidationRules(array $validationRules) - { - $this->validationRules = $validationRules; - return $this; - } - - /** - * EXPERIMENTAL! - * This method can be removed or changed in future versions without a prior notice. - * - * @return Resolution - */ - public function getTypeResolutionStrategy() - { - return $this->typeResolutionStrategy; - } - - /** - * EXPERIMENTAL! - * This method can be removed or changed in future versions without a prior notice. - * - * @param Resolution $typeResolutionStrategy - * @return Server - */ - public function setTypeResolutionStrategy(Resolution $typeResolutionStrategy) - { - $this->assertSchemaNotSet('Type Resolution Strategy', __METHOD__); - $this->typeResolutionStrategy = $typeResolutionStrategy; - return $this; - } - - /** - * @return PromiseAdapter|null - */ - public function getPromiseAdapter() - { - return $this->promiseAdapter; - } - - /** - * See /docs/data-fetching.md#async-php - * - * @param PromiseAdapter $promiseAdapter - * @return Server - */ - public function setPromiseAdapter(PromiseAdapter $promiseAdapter) - { - if ($this->promiseAdapter && $promiseAdapter !== $this->promiseAdapter) { - throw new InvariantViolation("Cannot set promise adapter: Different adapter is already set"); - } - $this->promiseAdapter = $promiseAdapter; - return $this; - } - - /** - * Returns array with validation errors (empty when there are no validation errors) - * - * @param DocumentNode $query - * @return array - */ - public function validate(DocumentNode $query) - { - try { - $schema = $this->getSchema(); - $schema->assertValid(); - } catch (InvariantViolation $e) { - throw new InvariantViolation("Cannot validate, schema contains errors: {$e->getMessage()}", null, $e); - } - - return DocumentValidator::validate($schema, $query, $this->validationRules); - } - - /** - * Executes GraphQL query against this server and returns execution result - * - * @param string|DocumentNode $query - * @param array|null $variables - * @param string|null $operationName - * @return ExecutionResult - */ - public function executeQuery($query, array $variables = null, $operationName = null) - { - $this->phpErrors = []; - if ($this->debug & static::DEBUG_PHP_ERRORS) { - // Catch custom errors (to report them in query results) - set_error_handler(function($severity, $message, $file, $line) { - $this->phpErrors[] = new \ErrorException($message, 0, $severity, $file, $line); - }); - } - - if ($this->promiseAdapter) { - // TODO: inline GraphQL::executeAndReturnResult and pass promise adapter to executor constructor directly - $promiseAdapter = Executor::getPromiseAdapter(); - Executor::setPromiseAdapter($this->promiseAdapter); - } - - $result = GraphQL::executeAndReturnResult( - $this->getSchema(), - $query, - $this->getRootValue(), - $this->getContext(), - $variables, - $operationName - ); - - if (isset($promiseAdapter)) { - Executor::setPromiseAdapter($promiseAdapter); - } - - // Add details about original exception in error entry (if any) - if ($this->debug & static::DEBUG_EXCEPTIONS) { - $result->setErrorFormatter([$this, 'formatError']); - } - - // Add reported PHP errors to result (if any) - if (!empty($this->phpErrors) && ($this->debug & static::DEBUG_PHP_ERRORS)) { - $result->extensions['phpErrors'] = array_map($this->phpErrorFormatter, $this->phpErrors); - } - - if ($this->debug & static::DEBUG_PHP_ERRORS) { - restore_error_handler(); - } - return $result; - } - - /** - * GraphQL HTTP endpoint compatible with express-graphql - */ - public function handleRequest() - { - try { - $httpStatus = 200; - if (isset($_SERVER['CONTENT_TYPE']) && strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) { - $raw = $this->readInput(); - $data = json_decode($raw, true); - - Utils::invariant( - is_array($data), - "GraphQL Server expects JSON object with keys 'query' and 'variables', but got " . Utils::getVariableType($data) - ); - } else { - $data = $_REQUEST ?: []; - } - $data += ['query' => null, 'variables' => null]; - $result = $this->executeQuery($data['query'], (array) $data['variables'])->toArray(); - } catch (\Exception $e) { - // This is only possible for schema creation errors and some very unpredictable errors, - // (all errors which occur during query execution are caught and included in final response) - $httpStatus = $this->unexpectedErrorStatus; - $error = new Error($this->unexpectedErrorMessage, null, null, null, null, $e); - $result = ['errors' => [$this->formatError($error)]]; - } catch (\Throwable $e) { - $httpStatus = $this->unexpectedErrorStatus; - $error = new Error($this->unexpectedErrorMessage, null, null, null, null, $e); - $result = ['errors' => [$this->formatError($error)]]; - } - - $this->produceOutput($result, $httpStatus); - } - - /** - * @param \Throwable $e - */ - private function formatException($e) - { - $formatter = $this->exceptionFormatter; - return $formatter($e); - } - - /** - * @param Error $e - * @return array - */ - public function formatError(\GraphQL\Error\Error $e) - { - $result = $e->toSerializableArray(); - - if (($this->debug & static::DEBUG_EXCEPTIONS) && $e->getPrevious()) { - $result['exception'] = $this->formatException($e->getPrevious()); - } - return $result; - } - - protected function readInput() - { - return file_get_contents('php://input') ?: ''; - } - - protected function produceOutput(array $result, $httpStatus) - { - header('Content-Type: application/json', true, $httpStatus); - echo json_encode($result); - } -} diff --git a/src/Type/Definition/Config.php b/src/Type/Definition/Config.php deleted file mode 100644 index ba4cb27..0000000 --- a/src/Type/Definition/Config.php +++ /dev/null @@ -1,307 +0,0 @@ -isArray = true; - $tmp->definition = $definition; - $tmp->flags = (int) $flags; - return $tmp; - } - - /** - * @param $typeName - * @param array $map - * @param array $definitions - * @param null $pathStr - */ - private static function validateMap($typeName, array $map, array $definitions, $pathStr = null) - { - $suffix = $pathStr ? " at $pathStr" : ''; - - // Make sure there are no unexpected keys in map - $unexpectedKeys = array_keys(array_diff_key($map, $definitions)); - - if (!empty($unexpectedKeys)) { - if (!self::$allowCustomOptions) { - Warning::warnOnce( - sprintf('Error in "%s" type definition: Non-standard keys "%s" ' . $suffix, $typeName, implode(', ', $unexpectedKeys)), - Warning::WARNING_CONFIG - ); - } - $map = array_intersect_key($map, $definitions); - } - - // Make sure that all required keys are present in map - $requiredKeys = array_filter($definitions, function($def) {return (self::getFlags($def) & self::REQUIRED) > 0;}); - $missingKeys = array_keys(array_diff_key($requiredKeys, $map)); - Utils::invariant( - empty($missingKeys), - 'Error in "' . $typeName . '" type definition: Required keys missing: "%s" %s', implode(', ', $missingKeys), $suffix - ); - - // Make sure that every map value is valid given the definition - foreach ($map as $key => $value) { - self::validateEntry($typeName, $key, $value, $definitions[$key], $pathStr ? "$pathStr:$key" : $key); - } - } - - /** - * @param $typeName - * @param $key - * @param $value - * @param $def - * @param $pathStr - * @throws \Exception - */ - private static function validateEntry($typeName, $key, $value, $def, $pathStr) - { - $type = Utils::getVariableType($value); - $err = 'Error in "'.$typeName.'" type definition: expecting "%s" at "' . $pathStr . '", but got "' . $type . '"'; - - if ($def instanceof \stdClass) { - if (($def->flags & self::REQUIRED) === 0 && $value === null) { - return ; - } - if (($def->flags & self::MAYBE_THUNK) > 0) { - // TODO: consider wrapping thunk with other function to force validation of value returned by thunk - Utils::invariant(is_array($value) || is_callable($value), $err, 'array or callable'); - } else { - Utils::invariant(is_array($value), $err, 'array'); - } - - if (!empty($def->isArray)) { - - if ($def->flags & self::REQUIRED) { - Utils::invariant(!empty($value), 'Error in "'.$typeName.'" type definition: ' . "Value at '$pathStr' cannot be empty array"); - } - - $err = 'Error in "'.$typeName.'" type definition: ' . "Each entry at '$pathStr' must be an array, but entry at '%s' is '%s'"; - - foreach ($value as $arrKey => $arrValue) { - if (is_array($def->definition)) { - if ($def->flags & self::MAYBE_TYPE && $arrValue instanceof Type) { - $arrValue = ['type' => $arrValue]; - } - if ($def->flags & self::MAYBE_NAME && is_string($arrValue)) { - $arrValue = ['name' => $arrValue]; - } - - if (!$arrValue instanceof FieldDefinition) { - Utils::invariant(is_array($arrValue), $err, $arrKey, Utils::getVariableType($arrValue)); - - if ($def->flags & self::KEY_AS_NAME && is_string($arrKey)) { - $arrValue += ['name' => $arrKey]; - } - self::validateMap($typeName, $arrValue, $def->definition, "$pathStr:$arrKey"); - } - } else { - self::validateEntry($typeName, $arrKey, $arrValue, $def->definition, "$pathStr:$arrKey"); - } - } - } else { - throw new InvariantViolation('Error in "'.$typeName.'" type definition: ' . "unexpected definition: " . print_r($def, true)); - } - } else { - Utils::invariant(is_int($def), 'Error in "'.$typeName.'" type definition: ' . "Definition for '$pathStr' is expected to be single integer value"); - - if ($def & self::REQUIRED) { - Utils::invariant($value !== null, 'Error in "'.$typeName.'" type definition: ' . 'Value at "%s" can not be null', $pathStr); - } - - if (null === $value) { - return ; // Allow nulls for non-required fields - } - - switch (true) { - case $def & self::ANY: - break; - case $def & self::BOOLEAN: - Utils::invariant(is_bool($value), $err, 'boolean'); - break; - case $def & self::STRING: - Utils::invariant(is_string($value), $err, 'string'); - break; - case $def & self::NUMERIC: - Utils::invariant(is_numeric($value), $err, 'numeric'); - break; - case $def & self::FLOAT: - Utils::invariant(is_float($value) || is_int($value), $err, 'float'); - break; - case $def & self::INT: - Utils::invariant(is_int($value), $err, 'int'); - break; - case $def & self::CALLBACK: - Utils::invariant(is_callable($value), $err, 'callable'); - break; - case $def & self::SCALAR: - Utils::invariant(is_scalar($value), $err, 'scalar'); - break; - case $def & self::NAME: - Utils::invariant(is_string($value), $err, 'name'); - Utils::invariant( - preg_match('~^[_a-zA-Z][_a-zA-Z0-9]*$~', $value), - 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "%s" does not.', - $value - ); - break; - case $def & self::INPUT_TYPE: - Utils::invariant( - is_callable($value) || $value instanceof InputType, - $err, - 'InputType definition' - ); - break; - case $def & self::OUTPUT_TYPE: - Utils::invariant( - is_callable($value) || $value instanceof OutputType, - $err, - 'OutputType definition' - ); - break; - case $def & self::INTERFACE_TYPE: - Utils::invariant( - is_callable($value) || $value instanceof InterfaceType, - $err, - 'InterfaceType definition' - ); - break; - case $def & self::OBJECT_TYPE: - Utils::invariant( - is_callable($value) || $value instanceof ObjectType, - $err, - 'ObjectType definition' - ); - break; - default: - throw new InvariantViolation("Unexpected validation rule: " . $def); - } - } - } - - /** - * @param $def - * @return mixed - */ - private static function getFlags($def) - { - return is_object($def) ? $def->flags : $def; - } -} \ No newline at end of file diff --git a/src/Type/Definition/DirectiveLocation.php b/src/Type/Definition/DirectiveLocation.php deleted file mode 100644 index a4bc719..0000000 --- a/src/Type/Definition/DirectiveLocation.php +++ /dev/null @@ -1,17 +0,0 @@ - Config::NAME | Config::REQUIRED, - 'values' => Config::arrayOf([ - 'name' => Config::NAME | Config::REQUIRED, - 'value' => Config::ANY, - 'deprecationReason' => Config::STRING, - 'description' => Config::STRING - ], Config::KEY_AS_NAME | Config::MAYBE_NAME), - 'description' => Config::STRING - ]); - $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->astNode = isset($config['astNode']) ? $config['astNode'] : null; diff --git a/src/Type/Definition/FieldDefinition.php b/src/Type/Definition/FieldDefinition.php index 8da5b05..19199c3 100644 --- a/src/Type/Definition/FieldDefinition.php +++ b/src/Type/Definition/FieldDefinition.php @@ -69,28 +69,6 @@ class FieldDefinition private static $def; - /** - * @return array - */ - public static function getDefinition() - { - return self::$def ?: (self::$def = [ - 'name' => Config::NAME | Config::REQUIRED, - 'type' => Config::OUTPUT_TYPE | Config::REQUIRED, - 'args' => Config::arrayOf([ - 'name' => Config::NAME | Config::REQUIRED, - 'type' => Config::INPUT_TYPE | Config::REQUIRED, - 'description' => Config::STRING, - 'defaultValue' => Config::ANY - ], Config::KEY_AS_NAME | Config::MAYBE_TYPE), - 'resolve' => Config::CALLBACK, - 'map' => Config::CALLBACK, - 'description' => Config::STRING, - 'deprecationReason' => Config::STRING, - 'complexity' => Config::CALLBACK, - ]); - } - public static function defineFieldMap(Type $type, $fields) { if (is_callable($fields)) { @@ -129,42 +107,6 @@ class FieldDefinition return $map; } - /** - * @param array $fields - * @param string $parentTypeName - * @deprecated use defineFieldMap instead - * @return array - */ - public static function createMap(array $fields, $parentTypeName = null) - { - trigger_error( - __METHOD__ . ' is deprecated, use ' . __CLASS__ . '::defineFieldMap() instead', - E_USER_DEPRECATED - ); - - $map = []; - foreach ($fields as $name => $field) { - if (is_array($field)) { - if (!isset($field['name']) && is_string($name)) { - $field['name'] = $name; - } - $fieldDef = self::create($field); - } else if ($field instanceof FieldDefinition) { - $fieldDef = $field; - } else { - if (is_string($name)) { - $fieldDef = self::create(['name' => $name, 'type' => $field]); - } else { - throw new InvariantViolation( - "Unexpected field definition for type $parentTypeName at field $name: " . Utils::printSafe($field) - ); - } - } - $map[$fieldDef->name] = $fieldDef; - } - return $map; - } - /** * @param array|Config $field * @param string $typeName @@ -172,9 +114,6 @@ class FieldDefinition */ public static function create($field, $typeName = null) { - if ($typeName) { - Config::validateField($typeName, $field, self::getDefinition()); - } return new self($field); } diff --git a/src/Type/Definition/InputObjectType.php b/src/Type/Definition/InputObjectType.php index a3661e6..0eef3b2 100644 --- a/src/Type/Definition/InputObjectType.php +++ b/src/Type/Definition/InputObjectType.php @@ -33,17 +33,6 @@ class InputObjectType extends Type implements InputType, NamedType Utils::invariant(is_string($config['name']), 'Must provide name.'); - Config::validate($config, [ - 'name' => Config::NAME | Config::REQUIRED, - 'fields' => Config::arrayOf([ - 'name' => Config::NAME | Config::REQUIRED, - 'type' => Config::INPUT_TYPE | Config::REQUIRED, - 'defaultValue' => Config::ANY, - 'description' => Config::STRING - ], Config::KEY_AS_NAME | Config::MAYBE_THUNK | Config::MAYBE_TYPE), - 'description' => Config::STRING - ]); - $this->config = $config; $this->name = $config['name']; $this->astNode = isset($config['astNode']) ? $config['astNode'] : null; diff --git a/src/Type/Definition/InterfaceType.php b/src/Type/Definition/InterfaceType.php index 3d57f88..711df55 100644 --- a/src/Type/Definition/InterfaceType.php +++ b/src/Type/Definition/InterfaceType.php @@ -53,16 +53,6 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT Utils::invariant(is_string($config['name']), 'Must provide name.'); - Config::validate($config, [ - 'name' => Config::NAME, - 'fields' => Config::arrayOf( - FieldDefinition::getDefinition(), - Config::KEY_AS_NAME | Config::MAYBE_THUNK | Config::MAYBE_TYPE - ), - 'resolveType' => Config::CALLBACK, // function($value, $context, ResolveInfo $info) => ObjectType - 'description' => Config::STRING - ]); - $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->astNode = isset($config['astNode']) ? $config['astNode'] : null; diff --git a/src/Type/Definition/ObjectType.php b/src/Type/Definition/ObjectType.php index 9f01483..b566947 100644 --- a/src/Type/Definition/ObjectType.php +++ b/src/Type/Definition/ObjectType.php @@ -105,23 +105,6 @@ class ObjectType extends Type implements OutputType, CompositeType, NamedType Utils::invariant(is_string($config['name']), 'Must provide name.'); - // Note: this validation is disabled by default, because it is resource-consuming - // TODO: add bin/validate script to check if schema is valid during development - Config::validate($config, [ - 'name' => Config::NAME | Config::REQUIRED, - 'fields' => Config::arrayOf( - FieldDefinition::getDefinition(), - Config::KEY_AS_NAME | Config::MAYBE_THUNK | Config::MAYBE_TYPE - ), - 'description' => Config::STRING, - 'interfaces' => Config::arrayOf( - Config::INTERFACE_TYPE, - Config::MAYBE_THUNK - ), - 'isTypeOf' => Config::CALLBACK, // ($value, $context, ResolveInfo $info) => boolean - 'resolveField' => Config::CALLBACK // ($value, $args, $context, ResolveInfo $info) => $fieldValue - ]); - $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->resolveFieldFn = isset($config['resolveField']) ? $config['resolveField'] : null; diff --git a/src/Type/Definition/ResolveInfo.php b/src/Type/Definition/ResolveInfo.php index 16a9acc..8c061df 100644 --- a/src/Type/Definition/ResolveInfo.php +++ b/src/Type/Definition/ResolveInfo.php @@ -1,7 +1,6 @@ fieldASTs = $this->fieldNodes; } /** @@ -179,13 +171,4 @@ class ResolveInfo return $fields; } - - public function __get($name) - { - if ('fieldASTs' === $name) { - trigger_error('Property ' . __CLASS__ . '->fieldASTs was renamed to ' . __CLASS__ . '->fieldNodes', E_USER_DEPRECATED); - return $this->fieldNodes; - } - throw new InvariantViolation("Undefined property '$name' in class " . __CLASS__); - } } diff --git a/src/Type/Definition/UnionType.php b/src/Type/Definition/UnionType.php index f9f4863..ec9a30b 100644 --- a/src/Type/Definition/UnionType.php +++ b/src/Type/Definition/UnionType.php @@ -38,13 +38,6 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType, Utils::invariant(is_string($config['name']), 'Must provide name.'); - Config::validate($config, [ - 'name' => Config::NAME | Config::REQUIRED, - 'types' => Config::arrayOf(Config::OBJECT_TYPE, Config::MAYBE_THUNK | Config::REQUIRED), - 'resolveType' => Config::CALLBACK, // function($value, ResolveInfo $info) => ObjectType - 'description' => Config::STRING - ]); - /** * Optionally provide a custom type resolver function. If one is not provided, * the default implemenation will call `isTypeOf` on each implementing @@ -56,15 +49,6 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType, $this->config = $config; } - /** - * @return ObjectType[] - */ - public function getPossibleTypes() - { - trigger_error(__METHOD__ . ' is deprecated in favor of ' . __CLASS__ . '::getTypes()', E_USER_DEPRECATED); - return $this->getTypes(); - } - /** * @return ObjectType[] */ diff --git a/src/Type/Introspection.php b/src/Type/Introspection.php index 4fd41ca..911b171 100644 --- a/src/Type/Introspection.php +++ b/src/Type/Introspection.php @@ -48,7 +48,11 @@ class Introspection public static function getIntrospectionQuery($options = []) { if (is_bool($options)) { - trigger_error('Calling Introspection::getIntrospectionQuery(boolean) is deprecated. Please use Introspection::getIntrospectionQuery(["descriptions" => boolean]).', E_USER_DEPRECATED); + trigger_error( + 'Calling Introspection::getIntrospectionQuery(boolean) is deprecated. '. + 'Please use Introspection::getIntrospectionQuery(["descriptions" => boolean]).', + E_USER_DEPRECATED + ); $descriptions = $options; } else { $descriptions = !array_key_exists('descriptions', $options) || $options['descriptions'] === true; diff --git a/src/Type/Schema.php b/src/Type/Schema.php index bffe726..095f5cd 100644 --- a/src/Type/Schema.php +++ b/src/Type/Schema.php @@ -75,21 +75,6 @@ class Schema */ public function __construct($config) { - if (func_num_args() > 1 || $config instanceof Type) { - trigger_error( - 'GraphQL\Schema constructor expects config object now instead of types passed as arguments. '. - 'See https://github.com/webonyx/graphql-php/issues/36', - E_USER_DEPRECATED - ); - list($queryType, $mutationType, $subscriptionType) = func_get_args() + [null, null, null]; - - $config = [ - 'query' => $queryType, - 'mutation' => $mutationType, - 'subscription' => $subscriptionType - ]; - } - if (is_array($config)) { $config = SchemaConfig::create($config); } diff --git a/src/Type/SchemaConfig.php b/src/Type/SchemaConfig.php index 5905a94..ca8bc7f 100644 --- a/src/Type/SchemaConfig.php +++ b/src/Type/SchemaConfig.php @@ -96,20 +96,6 @@ class SchemaConfig $config->setDirectives($options['directives']); } - if (isset($options['typeResolution'])) { - trigger_error( - 'Type resolution strategies are deprecated. Just pass single option `typeLoader` '. - 'to schema constructor instead.', - E_USER_DEPRECATED - ); - if ($options['typeResolution'] instanceof Resolution && !isset($options['typeLoader'])) { - $strategy = $options['typeResolution']; - $options['typeLoader'] = function($name) use ($strategy) { - return $strategy->resolveType($name); - }; - } - } - if (isset($options['typeLoader'])) { Utils::invariant( is_callable($options['typeLoader']), diff --git a/src/Utils.php b/src/Utils.php deleted file mode 100644 index feabcf0..0000000 --- a/src/Utils.php +++ /dev/null @@ -1,14 +0,0 @@ -toArray(); $expected = [ 'data' => [ @@ -172,7 +172,7 @@ class AbstractPromiseTest extends \PHPUnit_Framework_TestCase } }'; - $result = GraphQL::execute($schema, $query); + $result = GraphQL::executeQuery($schema, $query)->toArray(); $expected = [ 'data' => [ @@ -259,7 +259,7 @@ class AbstractPromiseTest extends \PHPUnit_Framework_TestCase } }'; - $result = GraphQL::execute($schema, $query); + $result = GraphQL::executeQuery($schema, $query)->toArray(); $expected = [ 'data' => [ @@ -357,7 +357,7 @@ class AbstractPromiseTest extends \PHPUnit_Framework_TestCase } }'; - $result = GraphQL::executeAndReturnResult($schema, $query)->toArray(true); + $result = GraphQL::executeQuery($schema, $query)->toArray(true); $expected = [ 'data' => [ @@ -458,7 +458,7 @@ class AbstractPromiseTest extends \PHPUnit_Framework_TestCase } }'; - $result = GraphQL::executeAndReturnResult($schema, $query)->toArray(true); + $result = GraphQL::executeQuery($schema, $query)->toArray(true); $expected = [ 'data' => [ @@ -552,7 +552,7 @@ class AbstractPromiseTest extends \PHPUnit_Framework_TestCase } }'; - $result = GraphQL::execute($schema, $query); + $result = GraphQL::executeQuery($schema, $query)->toArray(); $expected = [ 'data' => [ @@ -631,7 +631,7 @@ class AbstractPromiseTest extends \PHPUnit_Framework_TestCase } }'; - $result = GraphQL::execute($schema, $query); + $result = GraphQL::executeQuery($schema, $query)->toArray(); $expected = [ 'data' => [ diff --git a/tests/Executor/AbstractTest.php b/tests/Executor/AbstractTest.php index bca67d3..4d89c8c 100644 --- a/tests/Executor/AbstractTest.php +++ b/tests/Executor/AbstractTest.php @@ -256,7 +256,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase 'path' => ['pets', 2] ]] ]; - $actual = GraphQL::executeAndReturnResult($schema, $query)->toArray(true); + $actual = GraphQL::executeQuery($schema, $query)->toArray(true); $this->assertArraySubset($expected, $actual); } @@ -336,7 +336,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase } }'; - $result = GraphQL::executeAndReturnResult($schema, $query)->toArray(true); + $result = GraphQL::executeQuery($schema, $query)->toArray(true); $expected = [ 'data' => [ 'pets' => [ @@ -421,7 +421,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase } }'; - $result = GraphQL::execute($schema, $query); + $result = GraphQL::executeQuery($schema, $query)->toArray(); $this->assertEquals([ 'data' => [ diff --git a/tests/Executor/DeferredFieldsTest.php b/tests/Executor/DeferredFieldsTest.php index 1c9cc06..45219d1 100644 --- a/tests/Executor/DeferredFieldsTest.php +++ b/tests/Executor/DeferredFieldsTest.php @@ -5,7 +5,7 @@ namespace GraphQL\Tests\Executor; use GraphQL\Deferred; use GraphQL\Executor\Executor; use GraphQL\Language\Parser; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; diff --git a/tests/Executor/DirectivesTest.php b/tests/Executor/DirectivesTest.php index b7c8c63..ed8fbd0 100644 --- a/tests/Executor/DirectivesTest.php +++ b/tests/Executor/DirectivesTest.php @@ -3,7 +3,7 @@ namespace GraphQL\Tests\Executor; use GraphQL\Executor\Executor; use GraphQL\Language\Parser; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; diff --git a/tests/Executor/ExecutorTest.php b/tests/Executor/ExecutorTest.php index bd6a16d..bbc0813 100644 --- a/tests/Executor/ExecutorTest.php +++ b/tests/Executor/ExecutorTest.php @@ -8,7 +8,7 @@ use GraphQL\Error\Error; use GraphQL\Error\UserError; use GraphQL\Executor\Executor; use GraphQL\Language\Parser; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\ObjectType; @@ -252,7 +252,6 @@ class ExecutorTest extends \PHPUnit_Framework_TestCase $this->assertEquals([ 'fieldName', - 'fieldASTs', 'fieldNodes', 'returnType', 'parentType', diff --git a/tests/Executor/LazyInterfaceTest.php b/tests/Executor/LazyInterfaceTest.php index 8dc05d8..5085c57 100644 --- a/tests/Executor/LazyInterfaceTest.php +++ b/tests/Executor/LazyInterfaceTest.php @@ -8,7 +8,7 @@ namespace GraphQL\Tests\Executor; use GraphQL\Executor\Executor; use GraphQL\Language\Parser; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; diff --git a/tests/Executor/ListsTest.php b/tests/Executor/ListsTest.php index ba6b4ed..15a8dd2 100644 --- a/tests/Executor/ListsTest.php +++ b/tests/Executor/ListsTest.php @@ -8,7 +8,7 @@ use GraphQL\Executor\Executor; use GraphQL\Error\FormattedError; use GraphQL\Language\Parser; use GraphQL\Language\SourceLocation; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; diff --git a/tests/Executor/MutationsTest.php b/tests/Executor/MutationsTest.php index 7c63ccd..a1c790a 100644 --- a/tests/Executor/MutationsTest.php +++ b/tests/Executor/MutationsTest.php @@ -7,7 +7,7 @@ use GraphQL\Executor\Executor; use GraphQL\Error\FormattedError; use GraphQL\Language\Parser; use GraphQL\Language\SourceLocation; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; diff --git a/tests/Executor/NonNullTest.php b/tests/Executor/NonNullTest.php index 1519f78..9c5fbfe 100644 --- a/tests/Executor/NonNullTest.php +++ b/tests/Executor/NonNullTest.php @@ -8,7 +8,7 @@ use GraphQL\Executor\Executor; use GraphQL\Error\FormattedError; use GraphQL\Language\Parser; use GraphQL\Language\SourceLocation; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; diff --git a/tests/Executor/ResolveTest.php b/tests/Executor/ResolveTest.php index 7929e4a..37c6196 100644 --- a/tests/Executor/ResolveTest.php +++ b/tests/Executor/ResolveTest.php @@ -2,7 +2,7 @@ namespace GraphQL\Tests\Executor; use GraphQL\GraphQL; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; @@ -37,7 +37,7 @@ class ResolveTest extends \PHPUnit_Framework_TestCase $this->assertEquals( ['data' => ['test' => 'testValue']], - GraphQL::execute($schema, '{ test }', $source) + GraphQL::executeQuery($schema, '{ test }', $source)->toArray() ); } @@ -56,7 +56,7 @@ class ResolveTest extends \PHPUnit_Framework_TestCase ]; $this->assertEquals( ['data' => ['test' => $_secret]], - GraphQL::execute($schema, '{ test }', $source) + GraphQL::executeQuery($schema, '{ test }', $source)->toArray() ); } @@ -74,7 +74,7 @@ class ResolveTest extends \PHPUnit_Framework_TestCase $source = new Adder(700); - $result = GraphQL::execute($schema, '{ test(addend1: 80) }', $source, ['addend2' => 9]); + $result = GraphQL::executeQuery($schema, '{ test(addend1: 80) }', $source, ['addend2' => 9])->toArray(); $this->assertEquals(['data' => ['test' => 789]], $result); } @@ -96,22 +96,22 @@ class ResolveTest extends \PHPUnit_Framework_TestCase $this->assertEquals( ['data' => ['test' => '[null,[]]']], - GraphQL::execute($schema, '{ test }') + GraphQL::executeQuery($schema, '{ test }')->toArray() ); $this->assertEquals( ['data' => ['test' => '["Source!",[]]']], - GraphQL::execute($schema, '{ test }', 'Source!') + GraphQL::executeQuery($schema, '{ test }', 'Source!')->toArray() ); $this->assertEquals( ['data' => ['test' => '["Source!",{"aStr":"String!"}]']], - GraphQL::execute($schema, '{ test(aStr: "String!") }', 'Source!') + GraphQL::executeQuery($schema, '{ test(aStr: "String!") }', 'Source!')->toArray() ); $this->assertEquals( ['data' => ['test' => '["Source!",{"aStr":"String!","aInt":-123}]']], - GraphQL::execute($schema, '{ test(aInt: -123, aStr: "String!") }', 'Source!') + GraphQL::executeQuery($schema, '{ test(aInt: -123, aStr: "String!") }', 'Source!')->toArray() ); } } diff --git a/tests/Executor/UnionInterfaceTest.php b/tests/Executor/UnionInterfaceTest.php index d2b0f14..4c2b366 100644 --- a/tests/Executor/UnionInterfaceTest.php +++ b/tests/Executor/UnionInterfaceTest.php @@ -394,7 +394,7 @@ class UnionInterfaceTest extends \PHPUnit_Framework_TestCase $this->assertEquals( ['data' => ['name' => 'John', 'friends' => [['name' => 'Liz']]]], - GraphQL::execute($schema2, $ast, $john2, $context) + GraphQL::executeQuery($schema2, $ast, $john2, $context)->toArray() ); $this->assertSame($context, $encounteredContext); $this->assertSame($schema2, $encounteredSchema); diff --git a/tests/ServerTest.php b/tests/ServerTest.php deleted file mode 100644 index db7df22..0000000 --- a/tests/ServerTest.php +++ /dev/null @@ -1,626 +0,0 @@ -assertEquals(null, $server->getQueryType()); - $this->assertEquals(null, $server->getMutationType()); - $this->assertEquals(null, $server->getSubscriptionType()); - $this->assertEquals(Directive::getInternalDirectives(), $server->getDirectives()); - $this->assertEquals([], $server->getTypes()); - $this->assertEquals(null, $server->getTypeResolutionStrategy()); - - $this->assertEquals(null, $server->getContext()); - $this->assertEquals(null, $server->getRootValue()); - $this->assertEquals(0, $server->getDebug()); - - $this->assertEquals(['GraphQL\Error\FormattedError', 'createFromException'], $server->getExceptionFormatter()); - $this->assertEquals(['GraphQL\Error\FormattedError', 'createFromPHPError'], $server->getPhpErrorFormatter()); - $this->assertEquals(null, $server->getPromiseAdapter()); - $this->assertEquals('Unexpected Error', $server->getUnexpectedErrorMessage()); - $this->assertEquals(500, $server->getUnexpectedErrorStatus()); - $this->assertEquals(DocumentValidator::allRules(), $server->getValidationRules()); - - $schema = $server->getSchema(); - $this->setExpectedException(InvariantViolation::class, 'Query root type must be provided.'); - $schema->assertValid(); - } - - public function testCannotUseSetQueryTypeAndSetSchema() - { - $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Schema on Server: Query Type is already set ' . - '(GraphQL\Server::setQueryType is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setQueryType($queryType) - ->setSchema($schema); - } - - public function testCannotUseSetMutationTypeAndSetSchema() - { - $mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Schema on Server: Mutation Type is already set ' . - '(GraphQL\Server::setMutationType is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setMutationType($mutationType) - ->setSchema($schema); - } - - public function testCannotUseSetSubscriptionTypeAndSetSchema() - { - $subscriptionType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Schema on Server: Subscription Type is already set ' . - '(GraphQL\Server::setSubscriptionType is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setSubscriptionType($subscriptionType) - ->setSchema($schema); - } - - public function testCannotUseSetDirectivesAndSetSchema() - { - $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Schema on Server: Directives are already set ' . - '(GraphQL\Server::setDirectives is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setDirectives(Directive::getInternalDirectives()) - ->setSchema($schema); - } - - public function testCannotUseAddTypesAndSetSchema() - { - $mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Schema on Server: Additional types are already set ' . - '(GraphQL\Server::addTypes is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->addTypes([$queryType, $mutationType]) - ->setSchema($schema); - } - - public function testCannotUseSetTypeResolutionStrategyAndSetSchema() - { - $mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Schema on Server: Type Resolution Strategy is already set ' . - '(GraphQL\Server::setTypeResolutionStrategy is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setTypeResolutionStrategy(new EagerResolution([$queryType, $mutationType])) - ->setSchema($schema); - } - - public function testCannotUseSetSchemaAndSetQueryType() - { - $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Query Type on Server: Schema is already set ' . - '(GraphQL\Server::setQueryType is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setSchema($schema) - ->setQueryType($queryType); - } - - public function testCannotUseSetSchemaAndSetMutationType() - { - $mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Mutation Type on Server: Schema is already set ' . - '(GraphQL\Server::setMutationType is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setSchema($schema) - ->setMutationType($mutationType); - } - - public function testCannotUseSetSchemaAndSetSubscriptionType() - { - $subscriptionType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Subscription Type on Server: Schema is already set ' . - '(GraphQL\Server::setSubscriptionType is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setSchema($schema) - ->setSubscriptionType($subscriptionType); - } - - public function testCannotUseSetSchemaAndSetDirectives() - { - $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Directives on Server: Schema is already set ' . - '(GraphQL\Server::setDirectives is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setSchema($schema) - ->setDirectives([]); - - } - - public function testCannotUseSetSchemaAndAddTypes() - { - $mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Types on Server: Schema is already set ' . - '(GraphQL\Server::addTypes is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setSchema($schema) - ->addTypes([$queryType, $mutationType]); - } - - public function testCanUseSetSchemaAndAddEmptyTypes() - { - $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - // But empty types should work (as they don't change anything): - Server::create() - ->setSchema($schema) - ->addTypes([]); - } - - public function testCannotUseSetSchemaAndSetTypeResolutionStrategy() - { - $mutationType = $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Type Resolution Strategy on Server: Schema is already set ' . - '(GraphQL\Server::setTypeResolutionStrategy is mutually exclusive with GraphQL\Server::setSchema)'); - Server::create() - ->setSchema($schema) - ->setTypeResolutionStrategy(new EagerResolution([$queryType, $mutationType])); - - } - - public function testCannotUseSetSchemaAndSetSchema() - { - $queryType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $this->setExpectedException(InvariantViolation::class, - 'Cannot set Schema on Server: Different schema is already set'); - Server::create() - ->setSchema($schema) - ->setSchema(new Schema(['query' => $queryType])); - $this->fail('Expected exception not thrown'); - } - - public function testSchemaDefinition() - { - $mutationType = $queryType = $subscriptionType = new ObjectType(['name' => 'A', 'fields' => ['a' => Type::string()]]); - $schema = new Schema([ - 'query' => $queryType, - ]); - - $server = Server::create() - ->setSchema($schema); - - $this->assertSame($schema, $server->getSchema()); - - $server = Server::create() - ->setQueryType($queryType); - $this->assertSame($queryType, $server->getQueryType()); - $this->assertSame($queryType, $server->getSchema()->getQueryType()); - - $server = Server::create() - ->setQueryType($queryType) - ->setMutationType($mutationType); - - $this->assertSame($mutationType, $server->getMutationType()); - $this->assertSame($mutationType, $server->getSchema()->getMutationType()); - - $server = Server::create() - ->setQueryType($queryType) - ->setSubscriptionType($subscriptionType); - - $this->assertSame($subscriptionType, $server->getSubscriptionType()); - $this->assertSame($subscriptionType, $server->getSchema()->getSubscriptionType()); - - $server = Server::create() - ->setQueryType($queryType) - ->addTypes($types = [$queryType, $subscriptionType]); - - $this->assertSame($types, $server->getTypes()); - $server->addTypes([$mutationType]); - $this->assertSame(array_merge($types, [$mutationType]), $server->getTypes()); - - $server = Server::create() - ->setDirectives($directives = []); - - $this->assertSame($directives, $server->getDirectives()); - } - - public function testParse() - { - $server = Server::create(); - $ast = $server->parse('{q}'); - $this->assertInstanceOf('GraphQL\Language\AST\DocumentNode', $ast); - } - - public function testParseFailure() - { - $server = Server::create(); - try { - $server->parse('{q'); - $this->fail('Expected exception not thrown'); - } catch (SyntaxError $error) { - $this->assertContains('{q', (string) $error); - $this->assertEquals('Syntax Error: Expected Name, found ', $error->getMessage()); - } - } - - public function testValidate() - { - $server = Server::create() - ->setQueryType(new ObjectType(['name' => 'Q', 'fields' => ['a' => Type::string()]])); - - $ast = $server->parse('{q}'); - $errors = $server->validate($ast); - - $this->assertInternalType('array', $errors); - $this->assertNotEmpty($errors); - - $server = Server::create(); - $this->setExpectedException(InvariantViolation::class, 'Cannot validate, schema contains errors: Query root type must be provided.'); - $server->validate($ast); - } - - public function testPromiseAdapter() - { - $adapter1 = new SyncPromiseAdapter(); - $adapter2 = new SyncPromiseAdapter(); - - $server = Server::create() - ->setPromiseAdapter($adapter1); - - $this->assertSame($adapter1, $server->getPromiseAdapter()); - $server->setPromiseAdapter($adapter1); - - $this->setExpectedException(InvariantViolation::class, 'Cannot set promise adapter: Different adapter is already set'); - $server->setPromiseAdapter($adapter2); - } - - public function testValidationRules() - { - $rules = []; - $server = Server::create() - ->setValidationRules($rules); - - $this->assertSame($rules, $server->getValidationRules()); - } - - public function testExecuteQuery() - { - $called = false; - $queryType = new ObjectType([ - 'name' => 'Q', - 'fields' => [ - 'field' => [ - 'type' => Type::string(), - 'resolve' => function($value, $args, $context, ResolveInfo $info) use (&$called) { - $called = true; - $this->assertEquals(null, $context); - $this->assertEquals(null, $value); - $this->assertEquals(null, $info->rootValue); - return 'ok'; - } - ] - ] - ]); - - $server = Server::create() - ->setQueryType($queryType); - - $result = $server->executeQuery('{field}'); - $this->assertEquals(true, $called); - $this->assertInstanceOf('GraphQL\Executor\ExecutionResult', $result); - $this->assertEquals(['data' => ['field' => 'ok']], $result->toArray()); - - $called = false; - $contextValue = new \stdClass(); - $rootValue = new \stdClass(); - - $queryType = new ObjectType([ - 'name' => 'QueryType', - 'fields' => [ - 'field' => [ - 'type' => Type::string(), - 'resolve' => function($value, $args, $context, ResolveInfo $info) use (&$called, $contextValue, $rootValue) { - $called = true; - $this->assertSame($rootValue, $value); - $this->assertSame($contextValue, $context); - $this->assertEquals($rootValue, $info->rootValue); - return 'ok'; - } - ] - ] - ]); - - $server = Server::create() - ->setQueryType($queryType) - ->setRootValue($rootValue) - ->setContext($contextValue); - - $result = $server->executeQuery('{field}'); - $this->assertEquals(true, $called); - $this->assertInstanceOf('GraphQL\Executor\ExecutionResult', $result); - $this->assertEquals(['data' => ['field' => 'ok']], $result->toArray()); - } - - public function testDebugPhpErrors() - { - $queryType = new ObjectType([ - 'name' => 'Query', - 'fields' => [ - 'err' => [ - 'type' => Type::string(), - 'resolve' => function() { - trigger_error('notice', E_USER_NOTICE); - return 'err'; - } - ] - ] - ]); - - $server = Server::create() - ->setDebug(0) - ->setQueryType($queryType); - - $prevEnabled = \PHPUnit_Framework_Error_Notice::$enabled; - \PHPUnit_Framework_Error_Notice::$enabled = false; - $result = @$server->executeQuery('{err}'); - - $expected = [ - 'data' => ['err' => 'err'] - ]; - $this->assertEquals($expected, $result->toArray()); - - $server->setDebug(Server::DEBUG_PHP_ERRORS); - $result = @$server->executeQuery('{err}'); - - $expected = [ - 'data' => ['err' => 'err'], - 'extensions' => [ - 'phpErrors' => [ - [ - 'message' => 'notice', - 'severity' => 1024, - // 'trace' => [...] - ] - ] - ] - ]; - - $this->assertArraySubset($expected, $result->toArray()); - - $server->setPhpErrorFormatter(function(\ErrorException $e) { - return ['test' => $e->getMessage()]; - }); - - $result = $server->executeQuery('{err}'); - $expected = [ - 'data' => ['err' => 'err'], - 'extensions' => [ - 'phpErrors' => [ - [ - 'test' => 'notice' - ] - ] - ] - ]; - $this->assertEquals($expected, $result->toArray()); - - \PHPUnit_Framework_Error_Notice::$enabled = $prevEnabled; - } - - public function testDebugExceptions() - { - $queryType = new ObjectType([ - 'name' => 'Query', - 'fields' => [ - 'withException' => [ - 'type' => Type::string(), - 'resolve' => function() { - throw new UserError("Error"); - } - ] - ] - ]); - - $server = Server::create() - ->setDebug(0) - ->setQueryType($queryType); - - $result = $server->executeQuery('{withException}'); - $expected = [ - 'data' => [ - 'withException' => null - ], - 'errors' => [[ - 'message' => 'Error', - 'path' => ['withException'], - 'locations' => [[ - 'line' => 1, - 'column' => 2 - ]], - ]] - ]; - $this->assertArraySubset($expected, $result->toArray()); - - $server->setDebug(Server::DEBUG_EXCEPTIONS); - $server->setExceptionFormatter(function($e) { - $debug = Debug::INCLUDE_TRACE; - return FormattedError::createFromException($e, $debug); - }); - $result = $server->executeQuery('{withException}'); - - $expected['errors'][0]['exception'] = ['message' => 'Error', 'trace' => []]; - $this->assertArraySubset($expected, $result->toArray()); - - $server->setExceptionFormatter(function(\Exception $e) { - return ['test' => $e->getMessage()]; - }); - - $result = $server->executeQuery('{withException}'); - $expected['errors'][0]['exception'] = ['test' => 'Error']; - $this->assertArraySubset($expected, $result->toArray()); - } - - public function testHandleRequest() - { - $mock = $this->getMockBuilder('GraphQL\Server') - ->setMethods(['readInput', 'produceOutput']) - ->getMock(); - - $mock->method('readInput') - ->will($this->returnValue(json_encode(['query' => '{err}']))); - - $output = null; - $mock->method('produceOutput') - ->will($this->returnCallback(function ($a1, $a2) use (&$output) { - $output = func_get_args(); - })); - - /** @var $mock Server */ - $mock->handleRequest(); - - $this->assertInternalType('array', $output); - $this->assertArraySubset(['errors' => [['message' => 'Schema does not define the required query root type.']]], $output[0]); - $this->assertEquals(200, $output[1]); - - $output = null; - $mock->setUnexpectedErrorMessage($newErr = 'Hey! Something went wrong!'); - $mock->setUnexpectedErrorStatus(501); - $mock->method('readInput') - ->will($this->throwException(new \Exception('test'))); - $mock->handleRequest(); - - $this->assertInternalType('array', $output); - $this->assertEquals(['errors' => [['message' => $newErr]]], $output[0]); - $this->assertEquals(501, $output[1]); - } - - public function testHandleRequest2() - { - $mock = $this->getMockBuilder('GraphQL\Server') - ->setMethods(['readInput', 'produceOutput']) - ->getMock(); - - $mock->method('readInput') - ->will($this->returnValue(json_encode(['query' => '{err}']))); - - $output = null; - $mock->method('produceOutput') - ->will($this->returnCallback(function ($a1, $a2) use (&$output) { - $output = func_get_args(); - })); - - $mock->setQueryType(new ObjectType([ - 'name' => 'Query', - 'fields' => [ - 'test' => [ - 'type' => Type::string(), - 'resolve' => function() { - return 'ok'; - } - ] - ] - ])); - - $_REQUEST = ['query' => '{err}']; - $output = null; - $mock->handleRequest(); - $this->assertInternalType('array', $output); - - $expectedOutput = [ - ['errors' => [[ - 'message' => 'Cannot query field "err" on type "Query".', - 'locations' => [[ - 'line' => 1, - 'column' => 2 - ]], - 'category' => 'graphql', - ]]], - 200 - ]; - - $this->assertEquals($expectedOutput, $output); - - $output = null; - $_SERVER['CONTENT_TYPE'] = 'application/json'; - $_REQUEST = []; - $mock->handleRequest(); - - $this->assertInternalType('array', $output); - $this->assertEquals($expectedOutput, $output); - } -} diff --git a/tests/StarWarsIntrospectionTest.php b/tests/StarWarsIntrospectionTest.php index 2569027..78527eb 100644 --- a/tests/StarWarsIntrospectionTest.php +++ b/tests/StarWarsIntrospectionTest.php @@ -420,6 +420,6 @@ class StarWarsIntrospectionTest extends \PHPUnit_Framework_TestCase */ private function assertValidQuery($query, $expected) { - $this->assertEquals(['data' => $expected], GraphQL::execute(StarWarsSchema::build(), $query)); + $this->assertEquals(['data' => $expected], GraphQL::executeQuery(StarWarsSchema::build(), $query)->toArray()); } } diff --git a/tests/StarWarsQueryTest.php b/tests/StarWarsQueryTest.php index 206ef5d..80624f3 100644 --- a/tests/StarWarsQueryTest.php +++ b/tests/StarWarsQueryTest.php @@ -382,7 +382,10 @@ class StarWarsQueryTest extends \PHPUnit_Framework_TestCase */ private function assertValidQuery($query, $expected) { - $this->assertEquals(['data' => $expected], GraphQL::execute(StarWarsSchema::build(), $query)); + $this->assertEquals( + ['data' => $expected], + GraphQL::executeQuery(StarWarsSchema::build(), $query)->toArray() + ); } /** @@ -390,6 +393,9 @@ class StarWarsQueryTest extends \PHPUnit_Framework_TestCase */ private function assertValidQueryWithParams($query, $params, $expected) { - $this->assertEquals(['data' => $expected], GraphQL::execute(StarWarsSchema::build(), $query, null, null, $params)); + $this->assertEquals( + ['data' => $expected], + GraphQL::executeQuery(StarWarsSchema::build(), $query, null, null, $params)->toArray() + ); } } diff --git a/tests/StarWarsSchema.php b/tests/StarWarsSchema.php index a6b661d..91c3378 100644 --- a/tests/StarWarsSchema.php +++ b/tests/StarWarsSchema.php @@ -11,7 +11,7 @@ namespace GraphQL\Tests; * NOTE: This may contain spoilers for the original Star * Wars trilogy. */ -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\NonNull; diff --git a/tests/Type/ConfigTest.php b/tests/Type/ConfigTest.php deleted file mode 100644 index 1a15134..0000000 --- a/tests/Type/ConfigTest.php +++ /dev/null @@ -1,682 +0,0 @@ -assertEquals(false, Config::isValidationEnabled()); - Config::validate(['test' => []], ['test' => Config::STRING]); // must not throw - - Config::enableValidation(); - $this->assertEquals(true, Config::isValidationEnabled()); - - try { - Config::validate(['test' => []], ['test' => Config::STRING]); - $this->fail('Expected exception not thrown'); - } catch (\Exception $e) { - } - - Config::disableValidation(); - $this->assertEquals(false, Config::isValidationEnabled()); - Config::validate(['test' => []], ['test' => Config::STRING]); - } - - public function testValidateString() - { - $this->expectValidationPasses( - [ - 'test' => 'string', - 'empty' => '' - ], - [ - 'test' => Config::STRING, - 'empty' => Config::STRING - ] - ); - - $this->expectValidationThrows( - ['test' => 1], - ['test' => Config::STRING], - $this->typeError('expecting "string" at "test", but got "integer"') - ); - } - - public function testArray() - { - $this->expectValidationPasses( - ['test' => [ - [], - ['nested' => 'A'], - ['nested' => null] - ]], - ['test' => Config::arrayOf( - ['nested' => Config::STRING] - )] - ); - - $this->expectValidationThrows( - ['test' => [ - null - ]], - ['test' => Config::arrayOf( - ['nested' => Config::STRING] - )], - $this->typeError("Each entry at 'test' must be an array, but entry at '0' is 'NULL'") - ); - - $this->expectValidationPasses( - ['test' => null], - ['test' => Config::arrayOf( - ['nested' => Config::STRING] - )] - ); - - $this->expectValidationThrows( - ['test' => null], - ['test' => Config::arrayOf( - ['nested' => Config::STRING], - Config::REQUIRED - )], - $this->typeError('expecting "array" at "test", but got "NULL"') - ); - - // Check validation nesting: - $this->expectValidationPasses( - ['nest' => [ - ['nest' => [ - ['test' => 'value'] - ]] - ]], - ['nest' => Config::arrayOf([ - 'nest' => Config::arrayOf([ - 'test' => Config::STRING - ]) - ])] - ); - - $this->expectValidationThrows( - ['nest' => [ - ['nest' => [ - ['test' => 'notInt'] - ]] - ]], - ['nest' => Config::arrayOf([ - 'nest' => Config::arrayOf([ - 'test' => Config::INT - ]) - ])], - $this->typeError('expecting "int" at "nest:0:nest:0:test", but got "string"') - ); - - // Check arrays of types: - $this->expectValidationPasses( - ['nest' => [ - Type::string(), - Type::int() - ]], - ['nest' => Config::arrayOf( - Config::OUTPUT_TYPE, Config::REQUIRED - )] - ); - - // Check arrays of types: - $this->expectValidationThrows( - ['nest' => [ - Type::string(), - new InputObjectType(['name' => 'test', 'fields' => []]) - ]], - ['nest' => Config::arrayOf( - Config::OUTPUT_TYPE, Config::REQUIRED - )], - $this->typeError('expecting "OutputType definition" at "nest:1", but got "test"') - ); - } - - public function testRequired() - { - $this->expectValidationPasses( - ['required' => ''], - ['required' => Config::STRING | Config::REQUIRED] - ); - - $this->expectValidationThrows( - [], - ['required' => Config::STRING | Config::REQUIRED], - $this->typeError('Required keys missing: "required" ') - ); - - $this->expectValidationThrows( - ['required' => null], - ['required' => Config::STRING | Config::REQUIRED], - $this->typeError('Value at "required" can not be null') - ); - - $this->expectValidationPasses( - ['test' => [ - ['nested' => ''] - ]], - ['test' => Config::arrayOf([ - 'nested' => Config::STRING | Config::REQUIRED - ])] - ); - - $this->expectValidationThrows( - ['test' => [ - [] - ]], - ['test' => Config::arrayOf([ - 'nested' => Config::STRING | Config::REQUIRED - ])], - $this->typeError('Required keys missing: "nested" at test:0') - ); - - $this->expectValidationThrows( - ['test' => [ - ['nested' => null] - ]], - ['test' => Config::arrayOf([ - 'nested' => Config::STRING | Config::REQUIRED - ])], - $this->typeError('Value at "test:0:nested" can not be null') - ); - - $this->expectValidationPasses( - ['test' => [ - ['nested' => null] - ]], - ['test' => Config::arrayOf( - ['nested' => Config::STRING], - Config::REQUIRED - )] - ); - - $this->expectValidationThrows( - ['test' => [ - - ]], - ['test' => Config::arrayOf( - ['nested' => Config::STRING], - Config::REQUIRED - )], - $this->typeError("Value at 'test' cannot be empty array") - ); - } - - public function testKeyAsName() - { - $this->expectValidationPasses( - ['test' => [ - 'name1' => ['key1' => null], - ['name' => 'name1'], - ]], - ['test' => Config::arrayOf( - ['name' => Config::STRING | Config::REQUIRED, 'key1' => Config::STRING], - Config::KEY_AS_NAME - )] - ); - - $this->expectValidationThrows( - ['test' => [ - 'name1' => ['key1' => null] - ]], - ['test' => Config::arrayOf( - ['name' => Config::STRING | Config::REQUIRED, 'key1' => Config::STRING] - )], - $this->typeError('Required keys missing: "name" at test:name1') - ); - - $this->expectValidationThrows( - ['test' => [ - ['key1' => null] - ]], - ['test' => Config::arrayOf( - ['name' => Config::STRING | Config::REQUIRED, 'key1' => Config::STRING], - Config::KEY_AS_NAME - )], - $this->typeError('Required keys missing: "name" at test:0') - ); - } - - public function testMaybeThunk() - { - $this->expectValidationPasses( - [ - 'test' => [ - ['nested' => ''], - ['nested' => '1'], - ], - 'testThunk' => function() { - // Currently config won't validate thunk return value - } - ], - [ - 'test' => Config::arrayOf( - ['nested' => Config::STRING | Config::REQUIRED], - Config::MAYBE_THUNK - ), - 'testThunk' => Config::arrayOf( - ['nested' => Config::STRING | Config::REQUIRED], - Config::MAYBE_THUNK - ) - ] - ); - - $this->expectValidationThrows( - [ - 'testThunk' => $closure = function() {} - ], - [ - 'testThunk' => Config::arrayOf( - ['nested' => Config::STRING | Config::REQUIRED] - ) - ], - $this->typeError('expecting "array" at "testThunk", but got "' . Utils::getVariableType($closure) . '"') - ); - - $this->expectValidationThrows( - [ - 'testThunk' => 1 - ], - [ - 'testThunk' => Config::arrayOf( - ['nested' => Config::STRING | Config::REQUIRED], - Config::MAYBE_THUNK - ) - ], - $this->typeError('expecting "array or callable" at "testThunk", but got "integer"') - ); - } - - public function testMaybeType() - { - $type = new ObjectType([ - 'name' => 'Test', - 'fields' => [] - ]); - - $this->expectValidationPasses( - ['test' => [ - $type, - ['type' => $type], - ]], - ['test' => Config::arrayOf( - ['type' => Config::OBJECT_TYPE | Config::REQUIRED], - Config::MAYBE_TYPE - )] - ); - - $this->expectValidationThrows( - ['test' => [ - ['type' => 'str'] - ]], - ['test' => Config::arrayOf( - ['type' => Config::OBJECT_TYPE | Config::REQUIRED], - Config::MAYBE_TYPE - )], - $this->typeError('expecting "ObjectType definition" at "test:0:type", but got "string"') - ); - - $this->expectValidationThrows( - ['test' => [ - $type - ]], - ['test' => Config::arrayOf( - ['name' => Config::OBJECT_TYPE | Config::REQUIRED] - )], - $this->typeError("Each entry at 'test' must be an array, but entry at '0' is 'Test'") - ); - } - - public function testMaybeName() - { - $this->expectValidationPasses( - ['test' => [ - 'some-name', - ['name' => 'other-name'], - ]], - ['test' => Config::arrayOf( - ['name' => Config::STRING | Config::REQUIRED], - Config::MAYBE_NAME - )] - ); - - $this->expectValidationThrows( - ['test' => [ - 'some-name' - ]], - ['test' => Config::arrayOf( - ['name' => Config::OBJECT_TYPE | Config::REQUIRED] - )], - $this->typeError("Each entry at 'test' must be an array, but entry at '0' is 'string'") - ); - - $this->expectValidationPasses( - ['test' => [ - 'some-key' => 'some-name', - 'some-name' - ]], - ['test' => Config::arrayOf( - ['name' => Config::STRING | Config::REQUIRED], - Config::MAYBE_NAME | Config::KEY_AS_NAME - )] - ); - } - - public function getValidValues() - { - return [ - // $type, $validValue - [Config::ANY, null], - [Config::ANY, 0], - [Config::ANY, ''], - [Config::ANY, '0'], - [Config::ANY, 1], - [Config::ANY, function() {}], - [Config::ANY, []], - [Config::ANY, new \stdClass()], - [Config::STRING, null], - [Config::STRING, ''], - [Config::STRING, '0'], - [Config::STRING, 'anything'], - [Config::BOOLEAN, null], - [Config::BOOLEAN, false], - [Config::BOOLEAN, true], - [Config::INT, null], - [Config::INT, 0], - [Config::INT, 1], - [Config::INT, -1], - [Config::INT, 5000000], - [Config::INT, -5000000], - [Config::FLOAT, null], - [Config::FLOAT, 0], - [Config::FLOAT, 0.0], - [Config::FLOAT, 0.1], - [Config::FLOAT, -12.5], - [Config::NUMERIC, null], - [Config::NUMERIC, '0'], - [Config::NUMERIC, 0], - [Config::NUMERIC, 1], - [Config::NUMERIC, 0.0], - [Config::NUMERIC, 1.0], - [Config::NUMERIC, -1.0], - [Config::NUMERIC, -1], - [Config::NUMERIC, 1], - [Config::CALLBACK, null], - [Config::CALLBACK, function() {}], - [Config::CALLBACK, [$this, 'getValidValues']], - [Config::SCALAR, null], - [Config::SCALAR, 0], - [Config::SCALAR, 1], - [Config::SCALAR, 0.0], - [Config::SCALAR, 1.0], - [Config::SCALAR, true], - [Config::SCALAR, false], - [Config::SCALAR, ''], - [Config::SCALAR, '0'], - [Config::SCALAR, 'anything'], - [Config::NAME, null], - [Config::NAME, 'CamelCaseIsOk'], - [Config::NAME, 'underscore_is_ok'], - [Config::NAME, 'numbersAreOk0123456789'], - [Config::INPUT_TYPE, null], - [Config::INPUT_TYPE, new InputObjectType(['name' => 'test', 'fields' => []])], - [Config::INPUT_TYPE, new EnumType(['name' => 'test2', 'values' => ['A', 'B', 'C']])], - [Config::INPUT_TYPE, Type::string()], - [Config::INPUT_TYPE, Type::int()], - [Config::INPUT_TYPE, Type::float()], - [Config::INPUT_TYPE, Type::boolean()], - [Config::INPUT_TYPE, Type::id()], - [Config::INPUT_TYPE, Type::listOf(Type::string())], - [Config::INPUT_TYPE, Type::nonNull(Type::string())], - [Config::OUTPUT_TYPE, null], - [Config::OUTPUT_TYPE, new ObjectType(['name' => 'test3', 'fields' => []])], - [Config::OUTPUT_TYPE, new EnumType(['name' => 'test4', 'values' => ['A', 'B', 'C']])], - [Config::OUTPUT_TYPE, Type::string()], - [Config::OUTPUT_TYPE, Type::int()], - [Config::OUTPUT_TYPE, Type::float()], - [Config::OUTPUT_TYPE, Type::boolean()], - [Config::OUTPUT_TYPE, Type::id()], - [Config::OBJECT_TYPE, null], - [Config::OBJECT_TYPE, new ObjectType(['name' => 'test6', 'fields' => []])], - [Config::INTERFACE_TYPE, null], - [Config::INTERFACE_TYPE, new InterfaceType(['name' => 'test7', 'fields' => []])], - ]; - } - - /** - * @dataProvider getValidValues - */ - public function testValidValues($type, $validValue) - { - $this->expectValidationPasses( - ['test' => $validValue], - ['test' => $type] - ); - } - - public function getInvalidValues() - { - return [ - // $type, $typeLabel, $invalidValue, $actualTypeLabel - [Config::STRING, 'string', 1, 'integer'], - [Config::STRING, 'string', 0, 'integer'], - [Config::STRING, 'string', false, 'boolean'], - [Config::STRING, 'string', $tmp = function() {}, Utils::getVariableType($tmp)], // Note: can't use "Closure" as HHVM returns different string - [Config::STRING, 'string', [], 'array'], - [Config::STRING, 'string', new \stdClass(), 'stdClass'], - [Config::BOOLEAN, 'boolean', '', 'string'], - [Config::BOOLEAN, 'boolean', 1, 'integer'], - [Config::BOOLEAN, 'boolean', $tmp = function() {}, Utils::getVariableType($tmp)], - [Config::BOOLEAN, 'boolean', [], 'array'], - [Config::BOOLEAN, 'boolean', new \stdClass(), 'stdClass'], - [Config::INT, 'int', false, 'boolean'], - [Config::INT, 'int', '', 'string'], - [Config::INT, 'int', '0', 'string'], - [Config::INT, 'int', '1', 'string'], - [Config::INT, 'int', $tmp = function() {}, Utils::getVariableType($tmp)], - [Config::INT, 'int', [], 'array'], - [Config::INT, 'int', new \stdClass(), 'stdClass'], - [Config::FLOAT, 'float', '', 'string'], - [Config::FLOAT, 'float', '0', 'string'], - [Config::FLOAT, 'float', $tmp = function() {}, Utils::getVariableType($tmp)], - [Config::FLOAT, 'float', [], 'array'], - [Config::FLOAT, 'float', new \stdClass(), 'stdClass'], - [Config::NUMERIC, 'numeric', '', 'string'], - [Config::NUMERIC, 'numeric', 'tmp', 'string'], - [Config::NUMERIC, 'numeric', [], 'array'], - [Config::NUMERIC, 'numeric', new \stdClass(), 'stdClass'], - [Config::NUMERIC, 'numeric', $tmp = function() {}, Utils::getVariableType($tmp)], - [Config::CALLBACK, 'callable', 1, 'integer'], - [Config::CALLBACK, 'callable', '', 'string'], - [Config::CALLBACK, 'callable', [], 'array'], - [Config::CALLBACK, 'callable', new \stdClass(), 'stdClass'], - [Config::SCALAR, 'scalar', [], 'array'], - [Config::SCALAR, 'scalar', new \stdClass(), 'stdClass'], - [Config::SCALAR, 'scalar', $tmp = function() {}, Utils::getVariableType($tmp)], - [Config::NAME, 'name', 5, 'integer'], - [Config::NAME, 'name', $tmp = function() {}, Utils::getVariableType($tmp)], - [Config::NAME, 'name', [], 'array'], - [Config::NAME, 'name', new \stdClass(), 'stdClass'], - [Config::NAME, 'name', '', null, 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "" does not.'], - [Config::NAME, 'name', '0', null, 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "0" does not.'], - [Config::NAME, 'name', '4abc', null, 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "4abc" does not.'], - [Config::NAME, 'name', 'specialCharsAreBad!', null, 'Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but "specialCharsAreBad!" does not.'], - [Config::INPUT_TYPE, 'InputType definition', new ObjectType(['name' => 'test3', 'fields' => []]), 'test3'], - [Config::INPUT_TYPE, 'InputType definition', '', 'string'], - [Config::INPUT_TYPE, 'InputType definition', 'test', 'string'], - [Config::INPUT_TYPE, 'InputType definition', 1, 'integer'], - [Config::INPUT_TYPE, 'InputType definition', 0.5, 'double'], - [Config::INPUT_TYPE, 'InputType definition', false, 'boolean'], - [Config::INPUT_TYPE, 'InputType definition', [], 'array'], - [Config::INPUT_TYPE, 'InputType definition', new \stdClass(), 'stdClass'], - [Config::OUTPUT_TYPE, 'OutputType definition', new InputObjectType(['name' => 'InputTypeTest']), 'InputTypeTest'], - [Config::OBJECT_TYPE, 'ObjectType definition', '', 'string'], - [Config::OBJECT_TYPE, 'ObjectType definition', new InputObjectType(['name' => 'InputTypeTest2']), 'InputTypeTest2'], - [Config::INTERFACE_TYPE, 'InterfaceType definition', new ObjectType(['name' => 'ObjectTypeTest']), 'ObjectTypeTest'], - [Config::INTERFACE_TYPE, 'InterfaceType definition', 'InputTypeTest2', 'string'], - ]; - } - - /** - * @dataProvider getInvalidValues - */ - public function testInvalidValues($type, $typeLabel, $invalidValue, $actualTypeLabel = null, $expectedFullError = null) - { - if (!$expectedFullError) { - $expectedFullError = $this->typeError( - $invalidValue === null ? - 'Value at "test" can not be null' : - 'expecting "' . $typeLabel . '" at "test", but got "' . $actualTypeLabel . '"' - ); - } - - $this->expectValidationThrows( - ['test' => $invalidValue], - ['test' => $type], - $expectedFullError - ); - } - - public function testErrorMessageContainsTypeName() - { - $this->expectValidationThrows( - [ - 'name' => 'TypeName', - 'test' => 'notInt' - ], - [ - 'name' => Config::STRING | Config::REQUIRED, - 'test' => Config::INT - ], - $this->typeError('expecting "int" at "test", but got "string"', 'TypeName') - ); - } - - public function testValidateField() - { - Config::enableValidation(); - - // Should just validate: - Config::validateField( - 'TypeName', - ['test' => 'value'], - ['test' => Config::STRING] - ); - - // Should include type name in error - try { - Config::validateField( - 'TypeName', - ['test' => 'notInt'], - ['test' => Config::INT] - ); - $this->fail('Expected exception not thrown'); - } catch (InvariantViolation $e) { - $this->assertEquals( - $this->typeError('expecting "int" at "(Unknown Field):test", but got "string"', 'TypeName'), - $e->getMessage() - ); - } - - // Should include field type in error when field name is unknown: - try { - Config::validateField( - 'TypeName', - ['type' => Type::string()], - ['name' => Config::STRING | Config::REQUIRED, 'type' => Config::OUTPUT_TYPE] - ); - $this->fail('Expected exception not thrown'); - } catch (InvariantViolation $e) { - $this->assertEquals( - $this->typeError('Required keys missing: "name" at (Unknown Field of type: String)', 'TypeName'), - $e->getMessage() - ); - } - - // Should include field name in error when field name is set: - try { - Config::validateField( - 'TypeName', - ['name' => 'fieldName', 'test' => 'notInt'], - ['name' => Config::STRING, 'test' => Config::INT] - ); - $this->fail('Expected exception not thrown'); - } catch (InvariantViolation $e) { - $this->assertEquals( - $this->typeError('expecting "int" at "test", but got "string"', 'TypeName'), - $e->getMessage() - ); - } - } - - public function testAllowCustomOptions() - { - // Disabled by default when validation is enabled - Config::enableValidation(true); - - Config::validate( - ['test' => 'value', 'test2' => 'value'], - ['test' => Config::STRING] - ); - - Config::enableValidation(false); - - try { - Config::validate( - ['test' => 'value', 'test2' => 'value'], - ['test' => Config::STRING] - ); - $this->fail('Expected exception not thrown'); - } catch (\PHPUnit_Framework_Error_Warning $e) { - $this->assertEquals( - $this->typeError('Non-standard keys "test2" '), - $e->getMessage() - ); - } - } - - private function expectValidationPasses($config, $definition) - { - Config::enableValidation(false); - Config::validate($config, $definition); - } - - private function expectValidationThrows($config, $definition, $expectedError) - { - Config::enableValidation(false); - try { - Config::validate($config, $definition); - $this->fail('Expected exception not thrown: ' . $expectedError); - } catch (InvariantViolation $e) { - $this->assertEquals($expectedError, $e->getMessage()); - } - } - - private function typeError($err, $typeName = null) - { - return 'Error in "'. ($typeName ?: '(Unnamed Type)') . '" type definition: ' . $err; - } -} diff --git a/tests/Type/EnumTypeTest.php b/tests/Type/EnumTypeTest.php index 79741d3..3dbc0d9 100644 --- a/tests/Type/EnumTypeTest.php +++ b/tests/Type/EnumTypeTest.php @@ -3,7 +3,7 @@ namespace GraphQL\Tests\Type; use GraphQL\GraphQL; use GraphQL\Language\SourceLocation; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; @@ -185,7 +185,7 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase { $this->assertEquals( ['data' => ['colorInt' => 1]], - GraphQL::execute($this->schema, '{ colorInt(fromEnum: GREEN) }') + GraphQL::executeQuery($this->schema, '{ colorInt(fromEnum: GREEN) }')->toArray() ); } @@ -196,7 +196,7 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase { $this->assertEquals( ['data' => ['colorEnum' => 'GREEN']], - GraphQL::execute($this->schema, '{ colorEnum(fromInt: 1) }') + GraphQL::executeQuery($this->schema, '{ colorEnum(fromInt: 1) }')->toArray() ); } @@ -207,7 +207,7 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase { $this->assertEquals( ['data' => ['colorEnum' => 'GREEN']], - GraphQL::execute($this->schema, '{ colorEnum(fromEnum: GREEN) }') + GraphQL::executeQuery($this->schema, '{ colorEnum(fromEnum: GREEN) }')->toArray() ); } @@ -303,13 +303,13 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase { $this->assertEquals( ['data' => ['colorEnum' => 'BLUE']], - GraphQL::execute( + GraphQL::executeQuery( $this->schema, 'query test($color: Color!) { colorEnum(fromEnum: $color) }', null, null, ['color' => 'BLUE'] - ) + )->toArray() ); } @@ -320,13 +320,13 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase { $this->assertEquals( ['data' => ['favoriteEnum' => 'GREEN']], - GraphQL::execute( + GraphQL::executeQuery( $this->schema, 'mutation x($color: Color!) { favoriteEnum(color: $color) }', null, null, ['color' => 'GREEN'] - ) + )->toArray() ); } @@ -338,13 +338,13 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase { $this->assertEquals( ['data' => ['subscribeToEnum' => 'GREEN']], - GraphQL::execute( + GraphQL::executeQuery( $this->schema, 'subscription x($color: Color!) { subscribeToEnum(color: $color) }', null, null, ['color' => 'GREEN'] - ) + )->toArray() ); } @@ -391,10 +391,10 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase { $this->assertEquals( ['data' => ['colorEnum' => 'RED', 'colorInt' => 0]], - GraphQL::execute($this->schema, "{ + GraphQL::executeQuery($this->schema, "{ colorEnum(fromEnum: RED) colorInt(fromEnum: RED) - }") + }")->toArray() ); } @@ -405,10 +405,10 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase { $this->assertEquals( ['data' => ['colorEnum' => null, 'colorInt' => null]], - GraphQL::execute($this->schema, "{ + GraphQL::executeQuery($this->schema, "{ colorEnum colorInt - }") + }")->toArray() ); } @@ -445,7 +445,7 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase */ public function testMayBeInternallyRepresentedWithComplexValues() { - $result = GraphQL::executeAndReturnResult($this->schema, '{ + $result = GraphQL::executeQuery($this->schema, '{ first: complexEnum second: complexEnum(fromEnum: TWO) good: complexEnum(provideGoodValue: true) @@ -474,7 +474,7 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase */ public function testCanBeIntrospectedWithoutError() { - $result = GraphQL::execute($this->schema, Introspection::getIntrospectionQuery()); + $result = GraphQL::executeQuery($this->schema, Introspection::getIntrospectionQuery())->toArray(); $this->assertArrayNotHasKey('errors', $result); } @@ -494,13 +494,13 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase 'locations' => [['line' => 4, 'column' => 13]] ]] ], - GraphQL::executeAndReturnResult($this->schema, $q)->toArray(true) + GraphQL::executeQuery($this->schema, $q)->toArray(true) ); } private function expectFailure($query, $vars, $err) { - $result = GraphQL::executeAndReturnResult($this->schema, $query, null, null, $vars); + $result = GraphQL::executeQuery($this->schema, $query, null, null, $vars); $this->assertEquals(1, count($result->errors)); if (is_array($err)) { diff --git a/tests/Type/IntrospectionTest.php b/tests/Type/IntrospectionTest.php index e1d92de..e9bd621 100644 --- a/tests/Type/IntrospectionTest.php +++ b/tests/Type/IntrospectionTest.php @@ -3,7 +3,7 @@ namespace GraphQL\Tests\Type; use GraphQL\Error\FormattedError; use GraphQL\Language\SourceLocation; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\GraphQL; use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\InputObjectType; @@ -1062,7 +1062,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ) ); - $actual = GraphQL::execute($emptySchema, $request); + $actual = GraphQL::executeQuery($emptySchema, $request)->toArray(); // $this->assertEquals($expected, $actual); $this->assertArraySubset($expected, $actual); @@ -1164,7 +1164,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ] ]; - $result = GraphQL::execute($schema, $request); + $result = GraphQL::executeQuery($schema, $request)->toArray(); $result = $result['data']['__schema']['types']; // $this->assertEquals($expectedFragment, $result[1]); $this->assertContains($expectedFragment, $result); @@ -1200,7 +1200,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ] ]]; - $this->assertEquals($expected, GraphQL::execute($schema, $request)); + $this->assertEquals($expected, GraphQL::executeQuery($schema, $request)->toArray()); } /** @@ -1255,7 +1255,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ] ] ]; - $this->assertEquals($expected, GraphQL::execute($schema, $request)); + $this->assertEquals($expected, GraphQL::executeQuery($schema, $request)->toArray()); } /** @@ -1320,7 +1320,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ] ]; - $this->assertEquals($expected, GraphQL::execute($schema, $request)); + $this->assertEquals($expected, GraphQL::executeQuery($schema, $request)->toArray()); } /** @@ -1384,7 +1384,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ] ] ]; - $this->assertEquals($expected, GraphQL::execute($schema, $request)); + $this->assertEquals($expected, GraphQL::executeQuery($schema, $request)->toArray()); } /** @@ -1447,7 +1447,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ] ] ]; - $this->assertEquals($expected, GraphQL::execute($schema, $request)); + $this->assertEquals($expected, GraphQL::executeQuery($schema, $request)->toArray()); } /** @@ -1479,7 +1479,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ) ] ]; - $this->assertArraySubset($expected, GraphQL::execute($schema, $request)); + $this->assertArraySubset($expected, GraphQL::executeQuery($schema, $request)->toArray()); } /** @@ -1539,7 +1539,7 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ] ] ]; - $this->assertEquals($expected, GraphQL::execute($schema, $request)); + $this->assertEquals($expected, GraphQL::executeQuery($schema, $request)->toArray()); } /** @@ -1615,6 +1615,6 @@ class IntrospectionTest extends \PHPUnit_Framework_TestCase ] ]; - $this->assertEquals($expected, GraphQL::execute($schema, $request)); + $this->assertEquals($expected, GraphQL::executeQuery($schema, $request)->toArray()); } } diff --git a/tests/Type/ResolveInfoTest.php b/tests/Type/ResolveInfoTest.php index 571efc4..4aea85f 100644 --- a/tests/Type/ResolveInfoTest.php +++ b/tests/Type/ResolveInfoTest.php @@ -2,7 +2,7 @@ namespace GraphQL\Tests\Type; use GraphQL\GraphQL; -use GraphQL\Schema; +use GraphQL\Type\Schema; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; @@ -155,7 +155,7 @@ class ResolveInfoTest extends \PHPUnit_Framework_TestCase ]); $schema = new Schema(['query' => $blogQuery]); - $result = GraphQL::execute($schema, $doc); + $result = GraphQL::executeQuery($schema, $doc)->toArray(); $this->assertTrue($hasCalled); $this->assertEquals(['data' => ['article' => null]], $result); @@ -313,7 +313,7 @@ class ResolveInfoTest extends \PHPUnit_Framework_TestCase ]); $schema = new Schema(['query' => $blogQuery]); - $result = GraphQL::execute($schema, $doc); + $result = GraphQL::executeQuery($schema, $doc)->toArray(); $this->assertTrue($hasCalled); $this->assertEquals(['data' => ['article' => null]], $result);