mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-25 06:16:05 +03:00
Removed previously deprecated classes/methods
This commit is contained in:
parent
2580750d4c
commit
1b22f95a86
@ -25,7 +25,6 @@
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"files": ["src/deprecated.php"],
|
||||
"psr-4": {
|
||||
"GraphQL\\": "src/"
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
namespace GraphQL;
|
||||
|
||||
trigger_error(
|
||||
'GraphQL\Error was moved to GraphQL\Error\Error and will be deleted on next release',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Class Error
|
||||
*
|
||||
* @deprecated as of 8.0 in favor of GraphQL\Error\Error
|
||||
* @package GraphQL
|
||||
*/
|
||||
class Error extends \GraphQL\Error\Error
|
||||
{
|
||||
}
|
@ -1421,30 +1421,4 @@ class Executor
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of v0.8.0 should use self::defaultFieldResolver method
|
||||
*
|
||||
* @param $source
|
||||
* @param $args
|
||||
* @param $context
|
||||
* @param ResolveInfo $info
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function defaultResolveFn($source, $args, $context, ResolveInfo $info)
|
||||
{
|
||||
trigger_error(__METHOD__ . ' is renamed to ' . __CLASS__ . '::defaultFieldResolver', E_USER_DEPRECATED);
|
||||
return self::defaultFieldResolver($source, $args, $context, $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of v0.8.0 should use self::setDefaultFieldResolver method
|
||||
*
|
||||
* @param callable $fn
|
||||
*/
|
||||
public static function setDefaultResolveFn($fn)
|
||||
{
|
||||
trigger_error(__METHOD__ . ' is renamed to ' . __CLASS__ . '::setDefaultFieldResolver', E_USER_DEPRECATED);
|
||||
self::setDefaultFieldResolver($fn);
|
||||
}
|
||||
}
|
||||
|
@ -182,6 +182,10 @@ class GraphQL
|
||||
$operationName = null
|
||||
)
|
||||
{
|
||||
trigger_error(
|
||||
__METHOD__ . ' is deprecated, use GraphQL::executeQuery()->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,
|
||||
|
@ -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
|
||||
|
@ -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] = '<SOF>';
|
||||
$description[self::EOF] = '<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).
|
||||
*
|
||||
|
@ -1,6 +1,10 @@
|
||||
<?php
|
||||
namespace GraphQL;
|
||||
|
||||
trigger_error(
|
||||
'GraphQL\Schema is moved to GraphQL\Type\Schema',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
/**
|
||||
* Schema Definition
|
||||
|
604
src/Server.php
604
src/Server.php
@ -1,604 +0,0 @@
|
||||
<?php
|
||||
namespace GraphQL;
|
||||
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Executor\ExecutionResult;
|
||||
use GraphQL\Executor\Executor;
|
||||
use GraphQL\Executor\Promise\PromiseAdapter;
|
||||
use GraphQL\Language\AST\DocumentNode;
|
||||
use GraphQL\Language\Parser;
|
||||
use GraphQL\Type\Definition\Directive;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Resolution;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
trigger_error(
|
||||
'GraphQL\Server is deprecated in favor of new implementation: GraphQL\Server\StandardServer and will be removed in next version',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
class Server
|
||||
{
|
||||
const DEBUG_PHP_ERRORS = 1;
|
||||
const DEBUG_EXCEPTIONS = 2;
|
||||
const DEBUG_ALL = 7;
|
||||
|
||||
private $queryType;
|
||||
|
||||
private $mutationType;
|
||||
|
||||
private $subscriptionType;
|
||||
|
||||
private $directives;
|
||||
|
||||
private $types = [];
|
||||
|
||||
private $schema;
|
||||
|
||||
private $debug = 0;
|
||||
|
||||
private $contextValue;
|
||||
|
||||
private $rootValue;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $phpErrorFormatter = ['GraphQL\Error\FormattedError', 'createFromPHPError'];
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $exceptionFormatter = ['GraphQL\Error\FormattedError', 'createFromException'];
|
||||
|
||||
private $unexpectedErrorMessage = 'Unexpected Error';
|
||||
|
||||
private $unexpectedErrorStatus = 500;
|
||||
|
||||
private $validationRules;
|
||||
|
||||
/**
|
||||
* @var Resolution
|
||||
*/
|
||||
private $typeResolutionStrategy;
|
||||
|
||||
/**
|
||||
* @var PromiseAdapter
|
||||
*/
|
||||
private $promiseAdapter;
|
||||
|
||||
private $phpErrors = [];
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public static function create()
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ObjectType|null
|
||||
*/
|
||||
public function getQueryType()
|
||||
{
|
||||
return $this->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);
|
||||
}
|
||||
}
|
@ -1,307 +0,0 @@
|
||||
<?php
|
||||
namespace GraphQL\Type\Definition;
|
||||
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Error\Warning;
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
/**
|
||||
* Class Config
|
||||
* @package GraphQL\Type\Definition
|
||||
* @deprecated See https://github.com/webonyx/graphql-php/issues/148 for alternatives
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
const BOOLEAN = 1;
|
||||
const STRING = 2;
|
||||
const INT = 4;
|
||||
const FLOAT = 8;
|
||||
const NUMERIC = 16;
|
||||
const SCALAR = 32;
|
||||
const CALLBACK = 64;
|
||||
const ANY = 128;
|
||||
const NAME = 256;
|
||||
|
||||
const OUTPUT_TYPE = 2048;
|
||||
const INPUT_TYPE = 4096;
|
||||
const INTERFACE_TYPE = 8192;
|
||||
const OBJECT_TYPE = 16384;
|
||||
|
||||
const REQUIRED = 65536;
|
||||
const KEY_AS_NAME = 131072;
|
||||
const MAYBE_THUNK = 262144;
|
||||
const MAYBE_TYPE = 524288;
|
||||
const MAYBE_NAME = 1048576;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $enableValidation = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $allowCustomOptions = true;
|
||||
|
||||
/**
|
||||
*
|
||||
* Disables config validation
|
||||
*
|
||||
* @deprecated See https://github.com/webonyx/graphql-php/issues/148 for alternatives
|
||||
*/
|
||||
public static function disableValidation()
|
||||
{
|
||||
self::$enableValidation = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable deep config validation (disabled by default because it creates significant performance overhead).
|
||||
* Useful only at development to catch type definition errors quickly.
|
||||
*
|
||||
* @deprecated See https://github.com/webonyx/graphql-php/issues/148 for alternatives
|
||||
*/
|
||||
public static function enableValidation($allowCustomOptions = true)
|
||||
{
|
||||
Warning::warnOnce(
|
||||
'GraphQL\Type\Defintion\Config is deprecated and will be removed in the next version. ' .
|
||||
'See https://github.com/webonyx/graphql-php/issues/148 for alternatives',
|
||||
Warning::WARNING_CONFIG_DEPRECATION,
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
self::$enableValidation = true;
|
||||
self::$allowCustomOptions = $allowCustomOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidationEnabled()
|
||||
{
|
||||
return self::$enableValidation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
* @param array $definition
|
||||
*/
|
||||
public static function validate(array $config, array $definition)
|
||||
{
|
||||
if (self::$enableValidation) {
|
||||
$name = isset($config['name']) ? $config['name'] : '(Unnamed Type)';
|
||||
self::validateMap($name, $config, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $typeName
|
||||
* @param array $config
|
||||
* @param array $definition
|
||||
*/
|
||||
public static function validateField($typeName, array $config, array $definition)
|
||||
{
|
||||
if (self::$enableValidation) {
|
||||
if (!isset($config['name'])) {
|
||||
$pathStr = isset($config['type'])
|
||||
? '(Unknown Field of type: ' . Utils::printSafe($config['type']) . ')'
|
||||
: '(Unknown Field)';
|
||||
} else {
|
||||
$pathStr = '';
|
||||
}
|
||||
self::validateMap($typeName ?: '(Unnamed Type)', $config, $definition, $pathStr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|int $definition
|
||||
* @param int $flags
|
||||
* @return \stdClass
|
||||
*/
|
||||
public static function arrayOf($definition, $flags = 0)
|
||||
{
|
||||
$tmp = new \stdClass();
|
||||
$tmp->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;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
namespace GraphQL\Type\Definition;
|
||||
|
||||
use GraphQL\Language\DirectiveLocation as NewDirectiveLocation;
|
||||
|
||||
trigger_error(
|
||||
'GraphQL\Type\Definition\DirectiveLocation was moved to GraphQL\Language\DirectiveLocation and will be deleted on next release',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
/**
|
||||
* @deprecated moved to GraphQL\Language\DirectiveLocation
|
||||
*/
|
||||
class DirectiveLocation extends NewDirectiveLocation
|
||||
{
|
||||
|
||||
}
|
@ -42,17 +42,6 @@ class EnumType extends Type implements InputType, OutputType, LeafType, NamedTyp
|
||||
|
||||
Utils::invariant(is_string($config['name']), 'Must provide name.');
|
||||
|
||||
Config::validate($config, [
|
||||
'name' => 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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
namespace GraphQL\Type\Definition;
|
||||
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Language\AST\FieldNode;
|
||||
use GraphQL\Language\AST\FragmentDefinitionNode;
|
||||
use GraphQL\Language\AST\FragmentSpreadNode;
|
||||
@ -25,12 +24,6 @@ class ResolveInfo
|
||||
*/
|
||||
public $fieldName;
|
||||
|
||||
/**
|
||||
* @var FieldNode[]
|
||||
* @deprecated as of 8.0 (Renamed to $fieldNodes)
|
||||
*/
|
||||
public $fieldASTs;
|
||||
|
||||
/**
|
||||
* AST of all nodes referencing this field in the query.
|
||||
*
|
||||
@ -106,7 +99,6 @@ class ResolveInfo
|
||||
public function __construct(array $values)
|
||||
{
|
||||
Utils::assign($this, $values);
|
||||
$this->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__);
|
||||
}
|
||||
}
|
||||
|
@ -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[]
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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']),
|
||||
|
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
namespace GraphQL;
|
||||
|
||||
trigger_error(
|
||||
'GraphQL\Utils was moved to GraphQL\Utils\Utils and will be deleted on next release',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
/**
|
||||
* @deprecated Use GraphQL\Utils\Utils
|
||||
*/
|
||||
class Utils extends \GraphQL\Utils\Utils
|
||||
{
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
if (defined('GRAPHQL_WITH_DEPRECATED') && !GRAPHQL_WITH_DEPRECATED) {
|
||||
return ;
|
||||
}
|
||||
|
||||
// Renamed as of 8.0:
|
||||
class_alias('GraphQL\Error\FormattedError', 'GraphQL\FormattedError');
|
||||
class_alias('GraphQL\Error\SyntaxError', 'GraphQL\SyntaxError');
|
||||
|
||||
class_alias('GraphQL\Language\AST\ArgumentNode', 'GraphQL\Language\AST\Argument');
|
||||
class_alias('GraphQL\Language\AST\BooleanValueNode', 'GraphQL\Language\AST\BooleanValue');
|
||||
class_alias('GraphQL\Language\AST\DefinitionNode', 'GraphQL\Language\AST\Definition');
|
||||
class_alias('GraphQL\Language\AST\DirectiveNode', 'GraphQL\Language\AST\Directive');
|
||||
class_alias('GraphQL\Language\AST\DocumentNode', 'GraphQL\Language\AST\Document');
|
||||
class_alias('GraphQL\Language\AST\EnumValueNode', 'GraphQL\Language\AST\EnumValue');
|
||||
class_alias('GraphQL\Language\AST\FieldNode', 'GraphQL\Language\AST\Field');
|
||||
class_alias('GraphQL\Language\AST\FloatValueNode', 'GraphQL\Language\AST\FloatValue');
|
||||
class_alias('GraphQL\Language\AST\FragmentDefinitionNode', 'GraphQL\Language\AST\FragmentDefinition');
|
||||
class_alias('GraphQL\Language\AST\FragmentSpreadNode', 'GraphQL\Language\AST\FragmentSpread');
|
||||
class_alias('GraphQL\Language\AST\InlineFragmentNode', 'GraphQL\Language\AST\InlineFragment');
|
||||
class_alias('GraphQL\Language\AST\IntValueNode', 'GraphQL\Language\AST\IntValue');
|
||||
class_alias('GraphQL\Language\AST\ListTypeNode', 'GraphQL\Language\AST\ListType');
|
||||
class_alias('GraphQL\Language\AST\ListValueNode', 'GraphQL\Language\AST\ListValue');
|
||||
class_alias('GraphQL\Language\AST\NamedTypeNode', 'GraphQL\Language\AST\NamedType');
|
||||
class_alias('GraphQL\Language\AST\NameNode', 'GraphQL\Language\AST\Name');
|
||||
class_alias('GraphQL\Language\AST\NonNullTypeNode', 'GraphQL\Language\AST\NonNullType');
|
||||
class_alias('GraphQL\Language\AST\ObjectFieldNode', 'GraphQL\Language\AST\ObjectField');
|
||||
class_alias('GraphQL\Language\AST\ObjectValueNode', 'GraphQL\Language\AST\ObjectValue');
|
||||
class_alias('GraphQL\Language\AST\OperationDefinitionNode', 'GraphQL\Language\AST\OperationDefinition');
|
||||
class_alias('GraphQL\Language\AST\SelectionNode', 'GraphQL\Language\AST\Selection');
|
||||
class_alias('GraphQL\Language\AST\SelectionSetNode', 'GraphQL\Language\AST\SelectionSet');
|
||||
class_alias('GraphQL\Language\AST\StringValueNode', 'GraphQL\Language\AST\StringValue');
|
||||
class_alias('GraphQL\Language\AST\TypeNode', 'GraphQL\Language\AST\Type');
|
||||
class_alias('GraphQL\Language\AST\ValueNode', 'GraphQL\Language\AST\Value');
|
||||
class_alias('GraphQL\Language\AST\VariableDefinitionNode', 'GraphQL\Language\AST\VariableDefinition');
|
||||
class_alias('GraphQL\Language\AST\VariableNode', 'GraphQL\Language\AST\Variable');
|
@ -5,7 +5,7 @@ use GraphQL\Deferred;
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Error\Warning;
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Schema;
|
||||
use GraphQL\Type\Schema;
|
||||
use GraphQL\Type\Definition\InterfaceType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
@ -87,7 +87,7 @@ class AbstractPromiseTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
}';
|
||||
|
||||
$result = GraphQL::execute($schema, $query);
|
||||
$result = GraphQL::executeQuery($schema, $query)->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' => [
|
||||
|
@ -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' => [
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1,626 +0,0 @@
|
||||
<?php
|
||||
namespace GraphQL\Tests;
|
||||
|
||||
use GraphQL\Error\Debug;
|
||||
use GraphQL\Error\FormattedError;
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Error\SyntaxError;
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter;
|
||||
use GraphQL\Schema;
|
||||
use GraphQL\Server;
|
||||
use GraphQL\Type\Definition\Directive;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\EagerResolution;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
class ServerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testDefaults()
|
||||
{
|
||||
$server = @new Server();
|
||||
$this->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 <EOF>', $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);
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1,682 +0,0 @@
|
||||
<?php
|
||||
namespace GraphQL\Tests\Type;
|
||||
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Error\Warning;
|
||||
use GraphQL\Type\Definition\Config;
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
use GraphQL\Type\Definition\InputObjectType;
|
||||
use GraphQL\Type\Definition\InterfaceType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
class ConfigTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
Warning::suppress(Warning::WARNING_CONFIG_DEPRECATION);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
Config::disableValidation();
|
||||
Warning::enable(Warning::WARNING_CONFIG_DEPRECATION);
|
||||
}
|
||||
|
||||
public function testToggling()
|
||||
{
|
||||
// Disabled by default
|
||||
$this->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;
|
||||
}
|
||||
}
|
@ -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)) {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user