mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 04:46:04 +03:00
Removed old experimental code
This commit is contained in:
parent
6f8aed800e
commit
23169603fc
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Type;
|
||||
|
||||
use GraphQL\Type\Definition\AbstractType;
|
||||
use GraphQL\Type\Definition\InterfaceType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\UnionType;
|
||||
use GraphQL\Utils\TypeInfo;
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL!
|
||||
* This class can be removed or changed in future versions without a prior notice.
|
||||
*/
|
||||
class EagerResolution implements Resolution
|
||||
{
|
||||
/** @var Type[] */
|
||||
private $typeMap = [];
|
||||
|
||||
/** @var array<string, ObjectType[]> */
|
||||
private $implementations = [];
|
||||
|
||||
/**
|
||||
* @param Type[] $initialTypes
|
||||
*/
|
||||
public function __construct(array $initialTypes)
|
||||
{
|
||||
$typeMap = [];
|
||||
foreach ($initialTypes as $type) {
|
||||
$typeMap = TypeInfo::extractTypes($type, $typeMap);
|
||||
}
|
||||
$this->typeMap = $typeMap + Type::getInternalTypes();
|
||||
|
||||
// Keep track of all possible types for abstract types
|
||||
foreach ($this->typeMap as $typeName => $type) {
|
||||
if (! ($type instanceof ObjectType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($type->getInterfaces() as $iface) {
|
||||
$this->implementations[$iface->name][] = $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function resolveType($name)
|
||||
{
|
||||
return $this->typeMap[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function resolvePossibleTypes(AbstractType $abstractType)
|
||||
{
|
||||
if (! isset($this->typeMap[$abstractType->name])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($abstractType instanceof UnionType) {
|
||||
return $abstractType->getTypes();
|
||||
}
|
||||
|
||||
/** @var InterfaceType $abstractType */
|
||||
Utils::invariant($abstractType instanceof InterfaceType);
|
||||
|
||||
return $this->implementations[$abstractType->name] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns serializable schema representation suitable for GraphQL\Type\LazyResolution
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getDescriptor()
|
||||
{
|
||||
$typeMap = [];
|
||||
$possibleTypesMap = [];
|
||||
foreach ($this->getTypeMap() as $type) {
|
||||
if ($type instanceof UnionType) {
|
||||
foreach ($type->getTypes() as $innerType) {
|
||||
$possibleTypesMap[$type->name][$innerType->name] = 1;
|
||||
}
|
||||
} elseif ($type instanceof InterfaceType) {
|
||||
foreach ($this->implementations[$type->name] as $obj) {
|
||||
$possibleTypesMap[$type->name][$obj->name] = 1;
|
||||
}
|
||||
}
|
||||
$typeMap[$type->name] = 1;
|
||||
}
|
||||
|
||||
return [
|
||||
'version' => '1.0',
|
||||
'typeMap' => $typeMap,
|
||||
'possibleTypeMap' => $possibleTypesMap,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Type[]
|
||||
*/
|
||||
public function getTypeMap()
|
||||
{
|
||||
return $this->typeMap;
|
||||
}
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Type;
|
||||
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Type\Definition\AbstractType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Utils\Utils;
|
||||
use function call_user_func;
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL!
|
||||
* This class can be removed or changed in future versions without a prior notice.
|
||||
*/
|
||||
class LazyResolution implements Resolution
|
||||
{
|
||||
/** @var int[] */
|
||||
private $typeMap;
|
||||
|
||||
/** @var int[][] */
|
||||
private $possibleTypeMap;
|
||||
|
||||
/** @var callable */
|
||||
private $typeLoader;
|
||||
|
||||
/**
|
||||
* List of currently loaded types
|
||||
*
|
||||
* @var Type[]
|
||||
*/
|
||||
private $loadedTypes;
|
||||
|
||||
/**
|
||||
* Map of $interfaceTypeName => $objectType[]
|
||||
*
|
||||
* @var Type[][]
|
||||
*/
|
||||
private $loadedPossibleTypes;
|
||||
|
||||
/**
|
||||
* @param mixed[] $descriptor
|
||||
*/
|
||||
public function __construct(array $descriptor, callable $typeLoader)
|
||||
{
|
||||
Utils::invariant(
|
||||
isset($descriptor['typeMap'], $descriptor['possibleTypeMap'], $descriptor['version'])
|
||||
);
|
||||
Utils::invariant(
|
||||
$descriptor['version'] === '1.0'
|
||||
);
|
||||
|
||||
$this->typeLoader = $typeLoader;
|
||||
$this->typeMap = $descriptor['typeMap'] + Type::getInternalTypes();
|
||||
$this->possibleTypeMap = $descriptor['possibleTypeMap'];
|
||||
$this->loadedTypes = Type::getInternalTypes();
|
||||
$this->loadedPossibleTypes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function resolvePossibleTypes(AbstractType $type)
|
||||
{
|
||||
if (! isset($this->possibleTypeMap[$type->name])) {
|
||||
return [];
|
||||
}
|
||||
if (! isset($this->loadedPossibleTypes[$type->name])) {
|
||||
$tmp = [];
|
||||
foreach ($this->possibleTypeMap[$type->name] as $typeName => $true) {
|
||||
$obj = $this->resolveType($typeName);
|
||||
if (! $obj instanceof ObjectType) {
|
||||
throw new InvariantViolation(
|
||||
sprintf(
|
||||
'Lazy Type Resolution Error: Implementation %s of interface %s is expected to be instance of ObjectType, but got %s',
|
||||
$typeName,
|
||||
$type->name,
|
||||
Utils::getVariableType($obj)
|
||||
)
|
||||
);
|
||||
}
|
||||
$tmp[] = $obj;
|
||||
}
|
||||
$this->loadedPossibleTypes[$type->name] = $tmp;
|
||||
}
|
||||
|
||||
return $this->loadedPossibleTypes[$type->name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function resolveType($name)
|
||||
{
|
||||
if (! isset($this->typeMap[$name])) {
|
||||
return null;
|
||||
}
|
||||
if (! isset($this->loadedTypes[$name])) {
|
||||
$type = call_user_func($this->typeLoader, $name);
|
||||
if (! $type instanceof Type && $type !== null) {
|
||||
throw new InvariantViolation(
|
||||
'Lazy Type Resolution Error: Expecting GraphQL Type instance, but got ' .
|
||||
Utils::getVariableType($type)
|
||||
);
|
||||
}
|
||||
|
||||
$this->loadedTypes[$name] = $type;
|
||||
}
|
||||
|
||||
return $this->loadedTypes[$name];
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Type;
|
||||
|
||||
use GraphQL\Type\Definition\AbstractType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL!
|
||||
* This interface can be removed or changed in future versions without a prior notice.
|
||||
*
|
||||
* Interface Resolution
|
||||
*/
|
||||
interface Resolution
|
||||
{
|
||||
/**
|
||||
* Returns instance of type with given $name for GraphQL Schema
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Type
|
||||
*/
|
||||
public function resolveType($name);
|
||||
|
||||
/**
|
||||
* Returns instances of possible ObjectTypes for given InterfaceType or UnionType
|
||||
*
|
||||
* @return ObjectType[]
|
||||
*/
|
||||
public function resolvePossibleTypes(AbstractType $type);
|
||||
}
|
@ -1,584 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Type;
|
||||
|
||||
use Exception;
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Type\Definition\InputObjectType;
|
||||
use GraphQL\Type\Definition\InterfaceType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\UnionType;
|
||||
use GraphQL\Type\EagerResolution;
|
||||
use GraphQL\Type\LazyResolution;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function lcfirst;
|
||||
|
||||
class ResolutionTest extends TestCase
|
||||
{
|
||||
/** @var ObjectType */
|
||||
private $query;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $mutation;
|
||||
|
||||
/** @var InterfaceType */
|
||||
private $node;
|
||||
|
||||
/** @var InterfaceType */
|
||||
private $content;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $blogStory;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $video;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $videoMetadata;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $comment;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $user;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $category;
|
||||
|
||||
/** @var UnionType */
|
||||
private $mention;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $postStoryMutation;
|
||||
|
||||
/** @var InputObjectType */
|
||||
private $postStoryMutationInput;
|
||||
|
||||
/** @var ObjectType */
|
||||
private $postCommentMutation;
|
||||
|
||||
/** @var InputObjectType */
|
||||
private $postCommentMutationInput;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->node = new InterfaceType([
|
||||
'name' => 'Node',
|
||||
'fields' => [
|
||||
'id' => Type::string(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->content = new InterfaceType([
|
||||
'name' => 'Content',
|
||||
'fields' => function () {
|
||||
return [
|
||||
'title' => Type::string(),
|
||||
'body' => Type::string(),
|
||||
'author' => $this->user,
|
||||
'comments' => Type::listOf($this->comment),
|
||||
'categories' => Type::listOf($this->category),
|
||||
];
|
||||
},
|
||||
]);
|
||||
|
||||
$this->blogStory = new ObjectType([
|
||||
'name' => 'BlogStory',
|
||||
'interfaces' => [
|
||||
$this->node,
|
||||
$this->content,
|
||||
],
|
||||
'fields' => function () {
|
||||
return [
|
||||
$this->node->getField('id'),
|
||||
$this->content->getField('title'),
|
||||
$this->content->getField('body'),
|
||||
$this->content->getField('author'),
|
||||
$this->content->getField('comments'),
|
||||
$this->content->getField('categories'),
|
||||
];
|
||||
},
|
||||
]);
|
||||
|
||||
new ObjectType([
|
||||
'name' => 'Link',
|
||||
'interfaces' => [
|
||||
$this->node,
|
||||
$this->content,
|
||||
],
|
||||
'fields' => function () {
|
||||
return [
|
||||
'id' => $this->node->getField('id'),
|
||||
'title' => $this->content->getField('title'),
|
||||
'body' => $this->content->getField('body'),
|
||||
'author' => $this->content->getField('author'),
|
||||
'comments' => $this->content->getField('comments'),
|
||||
'categories' => $this->content->getField('categories'),
|
||||
'url' => Type::string(),
|
||||
];
|
||||
},
|
||||
|
||||
]);
|
||||
|
||||
$this->videoMetadata = new ObjectType([
|
||||
'name' => 'VideoMetadata',
|
||||
'fields' => [
|
||||
'lat' => Type::float(),
|
||||
'lng' => Type::float(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->video = new ObjectType([
|
||||
'name' => 'Video',
|
||||
'interfaces' => [
|
||||
$this->node,
|
||||
$this->content,
|
||||
],
|
||||
'fields' => function () {
|
||||
return [
|
||||
'id' => $this->node->getField('id'),
|
||||
'title' => $this->content->getField('title'),
|
||||
'body' => $this->content->getField('body'),
|
||||
'author' => $this->content->getField('author'),
|
||||
'comments' => $this->content->getField('comments'),
|
||||
'categories' => $this->content->getField('categories'),
|
||||
'streamUrl' => Type::string(),
|
||||
'downloadUrl' => Type::string(),
|
||||
'metadata' => $this->videoMetadata,
|
||||
];
|
||||
},
|
||||
]);
|
||||
|
||||
$this->comment = new ObjectType([
|
||||
'name' => 'Comment',
|
||||
'interfaces' => [
|
||||
$this->node,
|
||||
],
|
||||
'fields' => function () {
|
||||
return [
|
||||
'id' => $this->node->getField('id'),
|
||||
'author' => $this->user,
|
||||
'text' => Type::string(),
|
||||
'replies' => Type::listOf($this->comment),
|
||||
'parent' => $this->comment,
|
||||
'content' => $this->content,
|
||||
];
|
||||
},
|
||||
]);
|
||||
|
||||
$this->user = new ObjectType([
|
||||
'name' => 'User',
|
||||
'interfaces' => [
|
||||
$this->node,
|
||||
],
|
||||
'fields' => function () {
|
||||
return [
|
||||
'id' => $this->node->getField('id'),
|
||||
'name' => Type::string(),
|
||||
];
|
||||
},
|
||||
]);
|
||||
|
||||
$this->category = new ObjectType([
|
||||
'name' => 'Category',
|
||||
'interfaces' => [
|
||||
$this->node,
|
||||
],
|
||||
'fields' => function () {
|
||||
return [
|
||||
'id' => $this->node->getField('id'),
|
||||
'name' => Type::string(),
|
||||
];
|
||||
},
|
||||
]);
|
||||
|
||||
$this->mention = new UnionType([
|
||||
'name' => 'Mention',
|
||||
'types' => [
|
||||
$this->user,
|
||||
$this->category,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->query = new ObjectType([
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
'viewer' => $this->user,
|
||||
'latestContent' => $this->content,
|
||||
'node' => $this->node,
|
||||
'mentions' => Type::listOf($this->mention),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->postStoryMutationInput = new InputObjectType([
|
||||
'name' => 'PostStoryMutationInput',
|
||||
'fields' => [
|
||||
'title' => Type::string(),
|
||||
'body' => Type::string(),
|
||||
'author' => Type::id(),
|
||||
'category' => Type::id(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->mutation = new ObjectType([
|
||||
'name' => 'Mutation',
|
||||
'fields' => [
|
||||
'postStory' => [
|
||||
'type' => $this->postStoryMutation = new ObjectType([
|
||||
'name' => 'PostStoryMutation',
|
||||
'fields' => [
|
||||
'story' => $this->blogStory,
|
||||
],
|
||||
]),
|
||||
'args' => [
|
||||
'input' => Type::nonNull($this->postStoryMutationInput),
|
||||
'clientRequestId' => Type::string(),
|
||||
],
|
||||
],
|
||||
'postComment' => [
|
||||
'type' => $this->postCommentMutation = new ObjectType([
|
||||
'name' => 'PostCommentMutation',
|
||||
'fields' => [
|
||||
'comment' => $this->comment,
|
||||
],
|
||||
]),
|
||||
'args' => [
|
||||
'input' => Type::nonNull($this->postCommentMutationInput = new InputObjectType([
|
||||
'name' => 'PostCommentMutationInput',
|
||||
'fields' => [
|
||||
'text' => Type::nonNull(Type::string()),
|
||||
'author' => Type::nonNull(Type::id()),
|
||||
'content' => Type::id(),
|
||||
'parent' => Type::id(),
|
||||
],
|
||||
])),
|
||||
'clientRequestId' => Type::string(),
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testEagerTypeResolution() : void
|
||||
{
|
||||
// Has internal types by default:
|
||||
$eagerTypeResolution = new EagerResolution([]);
|
||||
$expectedTypeMap = [
|
||||
'ID' => Type::id(),
|
||||
'String' => Type::string(),
|
||||
'Float' => Type::float(),
|
||||
'Int' => Type::int(),
|
||||
'Boolean' => Type::boolean(),
|
||||
];
|
||||
self::assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
||||
|
||||
$expectedDescriptor = [
|
||||
'version' => '1.0',
|
||||
'typeMap' => [
|
||||
'ID' => 1,
|
||||
'String' => 1,
|
||||
'Float' => 1,
|
||||
'Int' => 1,
|
||||
'Boolean' => 1,
|
||||
],
|
||||
'possibleTypeMap' => [],
|
||||
];
|
||||
self::assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
||||
|
||||
self::assertNull($eagerTypeResolution->resolveType('User'));
|
||||
self::assertSame([], $eagerTypeResolution->resolvePossibleTypes($this->node));
|
||||
self::assertSame([], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
||||
self::assertSame([], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
||||
|
||||
$eagerTypeResolution = new EagerResolution([$this->query, $this->mutation]);
|
||||
|
||||
self::assertSame($this->query, $eagerTypeResolution->resolveType('Query'));
|
||||
self::assertSame($this->mutation, $eagerTypeResolution->resolveType('Mutation'));
|
||||
self::assertSame($this->user, $eagerTypeResolution->resolveType('User'));
|
||||
self::assertSame($this->node, $eagerTypeResolution->resolveType('Node'));
|
||||
self::assertSame($this->node, $eagerTypeResolution->resolveType('Node'));
|
||||
self::assertSame($this->content, $eagerTypeResolution->resolveType('Content'));
|
||||
self::assertSame($this->comment, $eagerTypeResolution->resolveType('Comment'));
|
||||
self::assertSame($this->mention, $eagerTypeResolution->resolveType('Mention'));
|
||||
self::assertSame($this->blogStory, $eagerTypeResolution->resolveType('BlogStory'));
|
||||
self::assertSame($this->category, $eagerTypeResolution->resolveType('Category'));
|
||||
self::assertSame($this->postStoryMutation, $eagerTypeResolution->resolveType('PostStoryMutation'));
|
||||
self::assertSame($this->postStoryMutationInput, $eagerTypeResolution->resolveType('PostStoryMutationInput'));
|
||||
self::assertSame($this->postCommentMutation, $eagerTypeResolution->resolveType('PostCommentMutation'));
|
||||
self::assertSame(
|
||||
$this->postCommentMutationInput,
|
||||
$eagerTypeResolution->resolveType('PostCommentMutationInput')
|
||||
);
|
||||
|
||||
self::assertEquals([$this->blogStory], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
||||
self::assertEquals(
|
||||
[$this->user, $this->comment, $this->category, $this->blogStory],
|
||||
$eagerTypeResolution->resolvePossibleTypes($this->node)
|
||||
);
|
||||
self::assertEquals([$this->user, $this->category], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
||||
|
||||
$expectedTypeMap = [
|
||||
'Query' => $this->query,
|
||||
'Mutation' => $this->mutation,
|
||||
'User' => $this->user,
|
||||
'Node' => $this->node,
|
||||
'String' => Type::string(),
|
||||
'Content' => $this->content,
|
||||
'Comment' => $this->comment,
|
||||
'Mention' => $this->mention,
|
||||
'BlogStory' => $this->blogStory,
|
||||
'Category' => $this->category,
|
||||
'PostStoryMutationInput' => $this->postStoryMutationInput,
|
||||
'ID' => Type::id(),
|
||||
'PostStoryMutation' => $this->postStoryMutation,
|
||||
'PostCommentMutationInput' => $this->postCommentMutationInput,
|
||||
'PostCommentMutation' => $this->postCommentMutation,
|
||||
'Float' => Type::float(),
|
||||
'Int' => Type::int(),
|
||||
'Boolean' => Type::boolean(),
|
||||
];
|
||||
|
||||
self::assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
||||
|
||||
$expectedDescriptor = [
|
||||
'version' => '1.0',
|
||||
'typeMap' => [
|
||||
'Query' => 1,
|
||||
'Mutation' => 1,
|
||||
'User' => 1,
|
||||
'Node' => 1,
|
||||
'String' => 1,
|
||||
'Content' => 1,
|
||||
'Comment' => 1,
|
||||
'Mention' => 1,
|
||||
'BlogStory' => 1,
|
||||
'Category' => 1,
|
||||
'PostStoryMutationInput' => 1,
|
||||
'ID' => 1,
|
||||
'PostStoryMutation' => 1,
|
||||
'PostCommentMutationInput' => 1,
|
||||
'PostCommentMutation' => 1,
|
||||
'Float' => 1,
|
||||
'Int' => 1,
|
||||
'Boolean' => 1,
|
||||
],
|
||||
'possibleTypeMap' => [
|
||||
'Node' => [
|
||||
'User' => 1,
|
||||
'Comment' => 1,
|
||||
'Category' => 1,
|
||||
'BlogStory' => 1,
|
||||
],
|
||||
'Content' => ['BlogStory' => 1],
|
||||
'Mention' => [
|
||||
'User' => 1,
|
||||
'Category' => 1,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
self::assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
||||
|
||||
// Ignores duplicates and nulls in initialTypes:
|
||||
$eagerTypeResolution = new EagerResolution([null, $this->query, null, $this->query, $this->mutation, null]);
|
||||
self::assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
||||
self::assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
||||
|
||||
// Those types are only part of interface
|
||||
self::assertEquals(null, $eagerTypeResolution->resolveType('Link'));
|
||||
self::assertEquals(null, $eagerTypeResolution->resolveType('Video'));
|
||||
self::assertEquals(null, $eagerTypeResolution->resolveType('VideoMetadata'));
|
||||
|
||||
self::assertEquals([$this->blogStory], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
||||
self::assertEquals(
|
||||
[$this->user, $this->comment, $this->category, $this->blogStory],
|
||||
$eagerTypeResolution->resolvePossibleTypes($this->node)
|
||||
);
|
||||
self::assertEquals([$this->user, $this->category], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
||||
|
||||
$eagerTypeResolution = new EagerResolution([null, $this->video, null]);
|
||||
self::assertEquals($this->videoMetadata, $eagerTypeResolution->resolveType('VideoMetadata'));
|
||||
self::assertEquals($this->video, $eagerTypeResolution->resolveType('Video'));
|
||||
|
||||
self::assertEquals([$this->video], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
||||
self::assertEquals(
|
||||
[$this->video, $this->user, $this->comment, $this->category],
|
||||
$eagerTypeResolution->resolvePossibleTypes($this->node)
|
||||
);
|
||||
self::assertEquals([], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
||||
|
||||
$expectedTypeMap = [
|
||||
'Video' => $this->video,
|
||||
'Node' => $this->node,
|
||||
'String' => Type::string(),
|
||||
'Content' => $this->content,
|
||||
'User' => $this->user,
|
||||
'Comment' => $this->comment,
|
||||
'Category' => $this->category,
|
||||
'VideoMetadata' => $this->videoMetadata,
|
||||
'Float' => Type::float(),
|
||||
'ID' => Type::id(),
|
||||
'Int' => Type::int(),
|
||||
'Boolean' => Type::boolean(),
|
||||
];
|
||||
self::assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
||||
|
||||
$expectedDescriptor = [
|
||||
'version' => '1.0',
|
||||
'typeMap' => [
|
||||
'Video' => 1,
|
||||
'Node' => 1,
|
||||
'String' => 1,
|
||||
'Content' => 1,
|
||||
'User' => 1,
|
||||
'Comment' => 1,
|
||||
'Category' => 1,
|
||||
'VideoMetadata' => 1,
|
||||
'Float' => 1,
|
||||
'ID' => 1,
|
||||
'Int' => 1,
|
||||
'Boolean' => 1,
|
||||
],
|
||||
'possibleTypeMap' => [
|
||||
'Node' => [
|
||||
'Video' => 1,
|
||||
'User' => 1,
|
||||
'Comment' => 1,
|
||||
'Category' => 1,
|
||||
],
|
||||
'Content' => ['Video' => 1],
|
||||
],
|
||||
];
|
||||
self::assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
||||
}
|
||||
|
||||
public function testLazyResolutionFollowsEagerResolution() : void
|
||||
{
|
||||
// Lazy resolution should work the same way as eager resolution works, except that it should load types on demand
|
||||
$eager = new EagerResolution([]);
|
||||
$emptyDescriptor = $eager->getDescriptor();
|
||||
|
||||
$typeLoader = static function () {
|
||||
throw new Exception('This should be never called for empty descriptor');
|
||||
};
|
||||
|
||||
$lazy = new LazyResolution($emptyDescriptor, $typeLoader);
|
||||
self::assertSame($eager->resolveType('User'), $lazy->resolveType('User'));
|
||||
self::assertSame($eager->resolvePossibleTypes($this->node), $lazy->resolvePossibleTypes($this->node));
|
||||
self::assertSame($eager->resolvePossibleTypes($this->content), $lazy->resolvePossibleTypes($this->content));
|
||||
self::assertSame($eager->resolvePossibleTypes($this->mention), $lazy->resolvePossibleTypes($this->mention));
|
||||
|
||||
$eager = new EagerResolution([$this->query, $this->mutation]);
|
||||
|
||||
$called = 0;
|
||||
$descriptor = $eager->getDescriptor();
|
||||
$typeLoader = function ($name) use (&$called) {
|
||||
$called++;
|
||||
$prop = lcfirst($name);
|
||||
|
||||
return $this->{$prop};
|
||||
};
|
||||
|
||||
$lazy = new LazyResolution($descriptor, $typeLoader);
|
||||
|
||||
self::assertSame($eager->resolveType('Query'), $lazy->resolveType('Query'));
|
||||
self::assertSame(1, $called);
|
||||
self::assertSame($eager->resolveType('Mutation'), $lazy->resolveType('Mutation'));
|
||||
self::assertSame(2, $called);
|
||||
self::assertSame($eager->resolveType('User'), $lazy->resolveType('User'));
|
||||
self::assertSame(3, $called);
|
||||
self::assertSame($eager->resolveType('User'), $lazy->resolveType('User'));
|
||||
self::assertSame(3, $called);
|
||||
self::assertSame($eager->resolveType('Node'), $lazy->resolveType('Node'));
|
||||
self::assertSame($eager->resolveType('Node'), $lazy->resolveType('Node'));
|
||||
self::assertSame(4, $called);
|
||||
self::assertSame($eager->resolveType('Content'), $lazy->resolveType('Content'));
|
||||
self::assertSame($eager->resolveType('Comment'), $lazy->resolveType('Comment'));
|
||||
self::assertSame($eager->resolveType('Mention'), $lazy->resolveType('Mention'));
|
||||
self::assertSame($eager->resolveType('BlogStory'), $lazy->resolveType('BlogStory'));
|
||||
self::assertSame($eager->resolveType('Category'), $lazy->resolveType('Category'));
|
||||
self::assertSame($eager->resolveType('PostStoryMutation'), $lazy->resolveType('PostStoryMutation'));
|
||||
self::assertSame($eager->resolveType('PostStoryMutationInput'), $lazy->resolveType('PostStoryMutationInput'));
|
||||
self::assertSame($eager->resolveType('PostCommentMutation'), $lazy->resolveType('PostCommentMutation'));
|
||||
self::assertSame(
|
||||
$eager->resolveType('PostCommentMutationInput'),
|
||||
$lazy->resolveType('PostCommentMutationInput')
|
||||
);
|
||||
self::assertSame(13, $called);
|
||||
|
||||
self::assertEquals($eager->resolvePossibleTypes($this->content), $lazy->resolvePossibleTypes($this->content));
|
||||
self::assertEquals($eager->resolvePossibleTypes($this->node), $lazy->resolvePossibleTypes($this->node));
|
||||
self::assertEquals($eager->resolvePossibleTypes($this->mention), $lazy->resolvePossibleTypes($this->mention));
|
||||
|
||||
$called = 0;
|
||||
$eager = new EagerResolution([$this->video]);
|
||||
$lazy = new LazyResolution($eager->getDescriptor(), $typeLoader);
|
||||
|
||||
self::assertEquals($eager->resolveType('VideoMetadata'), $lazy->resolveType('VideoMetadata'));
|
||||
self::assertEquals($eager->resolveType('Video'), $lazy->resolveType('Video'));
|
||||
self::assertEquals(2, $called);
|
||||
|
||||
self::assertEquals($eager->resolvePossibleTypes($this->content), $lazy->resolvePossibleTypes($this->content));
|
||||
self::assertEquals($eager->resolvePossibleTypes($this->node), $lazy->resolvePossibleTypes($this->node));
|
||||
self::assertEquals($eager->resolvePossibleTypes($this->mention), $lazy->resolvePossibleTypes($this->mention));
|
||||
}
|
||||
|
||||
public function testLazyThrowsOnInvalidLoadedType() : void
|
||||
{
|
||||
$lazy = $this->createLazy();
|
||||
$this->expectException(InvariantViolation::class);
|
||||
$this->expectExceptionMessage('Lazy Type Resolution Error: Expecting GraphQL Type instance, but got integer');
|
||||
$lazy->resolveType('int');
|
||||
}
|
||||
|
||||
private function createLazy()
|
||||
{
|
||||
$descriptor = [
|
||||
'version' => '1.0',
|
||||
'typeMap' => [
|
||||
'null' => 1,
|
||||
'int' => 1,
|
||||
],
|
||||
'possibleTypeMap' => [
|
||||
'a' => ['null' => 1],
|
||||
'b' => ['int' => 1],
|
||||
],
|
||||
];
|
||||
|
||||
$invalidTypeLoader = static function ($name) {
|
||||
switch ($name) {
|
||||
case 'null':
|
||||
return null;
|
||||
case 'int':
|
||||
return 7;
|
||||
}
|
||||
};
|
||||
|
||||
$lazy = new LazyResolution($descriptor, $invalidTypeLoader);
|
||||
$value = $lazy->resolveType('null');
|
||||
self::assertEquals(null, $value);
|
||||
|
||||
return $lazy;
|
||||
}
|
||||
|
||||
public function testLazyThrowsOnInvalidLoadedPossibleType() : void
|
||||
{
|
||||
$tmp = new InterfaceType(['name' => 'a', 'fields' => []]);
|
||||
$lazy = $this->createLazy();
|
||||
$this->expectException(InvariantViolation::class);
|
||||
$this->expectExceptionMessage('Lazy Type Resolution Error: Implementation null of interface a is expected to be instance of ObjectType, but got NULL');
|
||||
$lazy->resolvePossibleTypes($tmp);
|
||||
}
|
||||
|
||||
public function testLazyThrowsOnInvalidLoadedPossibleTypeWithInteger() : void
|
||||
{
|
||||
$tmp = new InterfaceType(['name' => 'b', 'fields' => []]);
|
||||
$lazy = $this->createLazy();
|
||||
$this->expectException(InvariantViolation::class);
|
||||
$this->expectExceptionMessage('Lazy Type Resolution Error: Expecting GraphQL Type instance, but got integer');
|
||||
$lazy->resolvePossibleTypes($tmp);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user