mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-25 14:26:08 +03:00
More definition tests (for type validation)
This commit is contained in:
parent
392b567f23
commit
39df711eac
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
namespace GraphQL\Type\Definition;
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Language\AST\FieldDefinitionNode;
|
||||
use GraphQL\Language\AST\TypeDefinitionNode;
|
||||
@ -82,8 +83,15 @@ class FieldDefinition
|
||||
$map = [];
|
||||
foreach ($fields as $name => $field) {
|
||||
if (is_array($field)) {
|
||||
if (!isset($field['name']) && is_string($name)) {
|
||||
$field['name'] = $name;
|
||||
if (!isset($field['name'])) {
|
||||
if (is_string($name)) {
|
||||
$field['name'] = $name;
|
||||
} else {
|
||||
throw new InvariantViolation(
|
||||
"{$type->name} fields must be an associative array with field names as keys or a " .
|
||||
"function which returns such an array."
|
||||
);
|
||||
}
|
||||
}
|
||||
if (isset($field['args']) && !is_array($field['args'])) {
|
||||
throw new InvariantViolation(
|
||||
@ -185,7 +193,7 @@ class FieldDefinition
|
||||
{
|
||||
try {
|
||||
Utils::assertValidName($this->name);
|
||||
} catch (InvariantViolation $e) {
|
||||
} catch (Error $e) {
|
||||
throw new InvariantViolation("{$parentType->name}.{$this->name}: {$e->getMessage()}");
|
||||
}
|
||||
Utils::invariant(
|
||||
|
@ -1,6 +1,9 @@
|
||||
<?php
|
||||
namespace GraphQL\Type\Definition;
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Language\AST\InputValueDefinitionNode;
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
/**
|
||||
* Class InputObjectField
|
||||
@ -81,4 +84,30 @@ class InputObjectField
|
||||
{
|
||||
return $this->defaultValueExists;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Type $parentType
|
||||
* @throws InvariantViolation
|
||||
*/
|
||||
public function assertValid(Type $parentType)
|
||||
{
|
||||
try {
|
||||
Utils::assertValidName($this->name);
|
||||
} catch (Error $e) {
|
||||
throw new InvariantViolation("{$parentType->name}.{$this->name}: {$e->getMessage()}");
|
||||
}
|
||||
$type = $this->type;
|
||||
if ($type instanceof WrappingType) {
|
||||
$type = $type->getWrappedType(true);
|
||||
}
|
||||
Utils::invariant(
|
||||
$type instanceof InputType,
|
||||
"{$parentType->name}.{$this->name} field type must be Input Type but got: " . Utils::printSafe($this->type)
|
||||
);
|
||||
Utils::invariant(
|
||||
empty($this->config['resolve']),
|
||||
"{$parentType->name}.{$this->name} field type has a resolve property, " .
|
||||
'but Input Types cannot define resolvers.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -80,4 +80,25 @@ class InputObjectType extends Type implements InputType, NamedType
|
||||
Utils::invariant(isset($this->fields[$name]), "Field '%s' is not defined for type '%s'", $name, $this->name);
|
||||
return $this->fields[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates type config and throws if one of type options is invalid.
|
||||
* Note: this method is shallow, it won't validate object fields and their arguments.
|
||||
*
|
||||
* @throws InvariantViolation
|
||||
*/
|
||||
public function assertValid()
|
||||
{
|
||||
parent::assertValid();
|
||||
|
||||
Utils::invariant(
|
||||
!empty($this->getFields()),
|
||||
"{$this->name} fields must be an associative array with field names as keys or a " .
|
||||
"callable which returns such an array."
|
||||
);
|
||||
|
||||
foreach ($this->getFields() as $field) {
|
||||
$field->assertValid($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,9 +110,11 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
||||
{
|
||||
parent::assertValid();
|
||||
|
||||
$resolveType = $this->config['resolveType'] ?? null;
|
||||
|
||||
Utils::invariant(
|
||||
!isset($this->config['resolveType']) || is_callable($this->config['resolveType']),
|
||||
"{$this->name} must provide \"resolveType\" as a function."
|
||||
!isset($resolveType) || is_callable($resolveType),
|
||||
"{$this->name} must provide \"resolveType\" as a function, but got: " . Utils::printSafe($resolveType)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -207,9 +207,15 @@ class ObjectType extends Type implements OutputType, CompositeType, NamedType
|
||||
"{$this->name} description must be string if set, but it is: " . Utils::printSafe($this->description)
|
||||
);
|
||||
|
||||
$isTypeOf = $this->config['isTypeOf'] ?? null;
|
||||
|
||||
Utils::invariant(
|
||||
!isset($this->config['isTypeOf']) || is_callable($this->config['isTypeOf']),
|
||||
"{$this->name} must provide 'isTypeOf' as a function"
|
||||
!isset($isTypeOf) || is_callable($isTypeOf),
|
||||
"{$this->name} must provide \"isTypeOf\" as a function, but got: " . Utils::printSafe($isTypeOf)
|
||||
);
|
||||
|
||||
foreach ($this->getFields() as $field) {
|
||||
$field->assertValid($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,16 +216,7 @@ abstract class Type implements \JsonSerializable
|
||||
*/
|
||||
public static function isType($type)
|
||||
{
|
||||
return (
|
||||
$type instanceof ScalarType ||
|
||||
$type instanceof ObjectType ||
|
||||
$type instanceof InterfaceType ||
|
||||
$type instanceof UnionType ||
|
||||
$type instanceof EnumType ||
|
||||
$type instanceof InputObjectType ||
|
||||
$type instanceof ListOfType ||
|
||||
$type instanceof NonNull
|
||||
);
|
||||
return $type instanceof Type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,7 +121,7 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType,
|
||||
if (isset($this->config['resolveType'])) {
|
||||
Utils::invariant(
|
||||
is_callable($this->config['resolveType']),
|
||||
"{$this->name} must provide \"resolveType\" as a function."
|
||||
"{$this->name} must provide \"resolveType\" as a function, but got: " . Utils::printSafe($this->config['resolveType'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +406,8 @@ class Schema
|
||||
* @api
|
||||
* @return InvariantViolation[]|Error[]
|
||||
*/
|
||||
public function validate() {
|
||||
public function validate()
|
||||
{
|
||||
// If this Schema has already been validated, return the previous results.
|
||||
if ($this->validationErrors !== null) {
|
||||
return $this->validationErrors;
|
||||
|
@ -49,11 +49,13 @@ class SchemaValidationContext
|
||||
/**
|
||||
* @return Error[]
|
||||
*/
|
||||
public function getErrors() {
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function validateRootTypes() {
|
||||
public function validateRootTypes()
|
||||
{
|
||||
$queryType = $this->schema->getQueryType();
|
||||
if (!$queryType) {
|
||||
$this->reportError(
|
||||
@ -208,7 +210,8 @@ class SchemaValidationContext
|
||||
/**
|
||||
* @param ObjectType|InterfaceType $type
|
||||
*/
|
||||
private function validateFields($type) {
|
||||
private function validateFields($type)
|
||||
{
|
||||
$fieldMap = $type->getFields();
|
||||
|
||||
// Objects and Interfaces both must define one or more fields.
|
||||
@ -271,7 +274,8 @@ class SchemaValidationContext
|
||||
}
|
||||
}
|
||||
|
||||
private function validateObjectInterfaces(ObjectType $object) {
|
||||
private function validateObjectInterfaces(ObjectType $object)
|
||||
{
|
||||
$implementedTypeNames = [];
|
||||
foreach($object->getInterfaces() as $iface) {
|
||||
if (isset($implementedTypeNames[$iface->name])) {
|
||||
@ -714,7 +718,8 @@ class SchemaValidationContext
|
||||
* @param string $message
|
||||
* @param array|Node|TypeNode|TypeDefinitionNode $nodes
|
||||
*/
|
||||
private function reportError($message, $nodes = null) {
|
||||
private function reportError($message, $nodes = null)
|
||||
{
|
||||
$nodes = array_filter($nodes && is_array($nodes) ? $nodes : [$nodes]);
|
||||
$this->addError(new Error($message, $nodes));
|
||||
}
|
||||
@ -722,7 +727,8 @@ class SchemaValidationContext
|
||||
/**
|
||||
* @param Error $error
|
||||
*/
|
||||
private function addError($error) {
|
||||
private function addError($error)
|
||||
{
|
||||
$this->errors[] = $error;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user