mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-02-11 18:19:23 +03:00
Merge pull request #344 from simPod/fix-cs-test-type
Fix CS in tests/Type
This commit is contained in:
commit
4e43a2cbcd
@ -1,11 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Tests\Type;
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
require_once __DIR__ . '/TestClasses.php';
|
|
||||||
|
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
|
use GraphQL\Tests\Type\TestClasses\MyCustomType;
|
||||||
|
use GraphQL\Tests\Type\TestClasses\OtherCustom;
|
||||||
use GraphQL\Type\Definition\CustomScalarType;
|
use GraphQL\Type\Definition\CustomScalarType;
|
||||||
use GraphQL\Type\Schema;
|
|
||||||
use GraphQL\Type\Definition\EnumType;
|
use GraphQL\Type\Definition\EnumType;
|
||||||
use GraphQL\Type\Definition\InputObjectType;
|
use GraphQL\Type\Definition\InputObjectType;
|
||||||
use GraphQL\Type\Definition\InterfaceType;
|
use GraphQL\Type\Definition\InterfaceType;
|
||||||
@ -14,74 +16,53 @@ use GraphQL\Type\Definition\NonNull;
|
|||||||
use GraphQL\Type\Definition\ObjectType;
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Definition\UnionType;
|
use GraphQL\Type\Definition\UnionType;
|
||||||
|
use GraphQL\Type\Schema;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use function count;
|
||||||
|
use function get_class;
|
||||||
|
use function json_encode;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
class DefinitionTest extends TestCase
|
class DefinitionTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
public $blogImage;
|
public $blogImage;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
public $blogArticle;
|
public $blogArticle;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
public $blogAuthor;
|
public $blogAuthor;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
public $blogMutation;
|
public $blogMutation;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
public $blogQuery;
|
public $blogQuery;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
public $blogSubscription;
|
public $blogSubscription;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
public $objectType;
|
public $objectType;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
public $objectWithIsTypeOf;
|
public $objectWithIsTypeOf;
|
||||||
|
|
||||||
/**
|
/** @var InterfaceType */
|
||||||
* @var InterfaceType
|
|
||||||
*/
|
|
||||||
public $interfaceType;
|
public $interfaceType;
|
||||||
|
|
||||||
/**
|
/** @var UnionType */
|
||||||
* @var UnionType
|
|
||||||
*/
|
|
||||||
public $unionType;
|
public $unionType;
|
||||||
|
|
||||||
/**
|
/** @var EnumType */
|
||||||
* @var EnumType
|
|
||||||
*/
|
|
||||||
public $enumType;
|
public $enumType;
|
||||||
|
|
||||||
/**
|
/** @var InputObjectType */
|
||||||
* @var InputObjectType
|
|
||||||
*/
|
|
||||||
public $inputObjectType;
|
public $inputObjectType;
|
||||||
|
|
||||||
/**
|
/** @var CustomScalarType */
|
||||||
* @var CustomScalarType
|
|
||||||
*/
|
|
||||||
public $scalarType;
|
public $scalarType;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
@ -99,9 +80,12 @@ class DefinitionTest extends TestCase
|
|||||||
|
|
||||||
$this->scalarType = new CustomScalarType([
|
$this->scalarType = new CustomScalarType([
|
||||||
'name' => 'Scalar',
|
'name' => 'Scalar',
|
||||||
'serialize' => function () {},
|
'serialize' => function () {
|
||||||
'parseValue' => function () {},
|
},
|
||||||
'parseLiteral' => function () {},
|
'parseValue' => function () {
|
||||||
|
},
|
||||||
|
'parseLiteral' => function () {
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->blogImage = new ObjectType([
|
$this->blogImage = new ObjectType([
|
||||||
@ -109,20 +93,23 @@ class DefinitionTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'url' => ['type' => Type::string()],
|
'url' => ['type' => Type::string()],
|
||||||
'width' => ['type' => Type::int()],
|
'width' => ['type' => Type::int()],
|
||||||
'height' => ['type' => Type::int()]
|
'height' => ['type' => Type::int()],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->blogAuthor = new ObjectType([
|
$this->blogAuthor = new ObjectType([
|
||||||
'name' => 'Author',
|
'name' => 'Author',
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
return [
|
return [
|
||||||
'id' => ['type' => Type::string()],
|
'id' => ['type' => Type::string()],
|
||||||
'name' => ['type' => Type::string()],
|
'name' => ['type' => Type::string()],
|
||||||
'pic' => [ 'type' => $this->blogImage, 'args' => [
|
'pic' => [
|
||||||
|
'type' => $this->blogImage,
|
||||||
|
'args' => [
|
||||||
'width' => ['type' => Type::int()],
|
'width' => ['type' => Type::int()],
|
||||||
'height' => ['type' => Type::int()]
|
'height' => ['type' => Type::int()],
|
||||||
]],
|
],
|
||||||
|
],
|
||||||
'recentArticle' => $this->blogArticle,
|
'recentArticle' => $this->blogArticle,
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
@ -135,35 +122,38 @@ class DefinitionTest extends TestCase
|
|||||||
'isPublished' => ['type' => Type::boolean()],
|
'isPublished' => ['type' => Type::boolean()],
|
||||||
'author' => ['type' => $this->blogAuthor],
|
'author' => ['type' => $this->blogAuthor],
|
||||||
'title' => ['type' => Type::string()],
|
'title' => ['type' => Type::string()],
|
||||||
'body' => ['type' => Type::string()]
|
'body' => ['type' => Type::string()],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->blogQuery = new ObjectType([
|
$this->blogQuery = new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'article' => ['type' => $this->blogArticle, 'args' => [
|
'article' => [
|
||||||
'id' => ['type' => Type::string()]
|
'type' => $this->blogArticle,
|
||||||
]],
|
'args' => [
|
||||||
'feed' => ['type' => new ListOfType($this->blogArticle)]
|
'id' => ['type' => Type::string()],
|
||||||
]
|
],
|
||||||
|
],
|
||||||
|
'feed' => ['type' => new ListOfType($this->blogArticle)],
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->blogMutation = new ObjectType([
|
$this->blogMutation = new ObjectType([
|
||||||
'name' => 'Mutation',
|
'name' => 'Mutation',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'writeArticle' => ['type' => $this->blogArticle]
|
'writeArticle' => ['type' => $this->blogArticle],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->blogSubscription = new ObjectType([
|
$this->blogSubscription = new ObjectType([
|
||||||
'name' => 'Subscription',
|
'name' => 'Subscription',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'articleSubscribe' => [
|
'articleSubscribe' => [
|
||||||
'args' => [ 'id' => [ 'type' => Type::string() ]],
|
'args' => ['id' => ['type' => Type::string()]],
|
||||||
'type' => $this->blogArticle
|
'type' => $this->blogArticle,
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +165,7 @@ class DefinitionTest extends TestCase
|
|||||||
public function testDefinesAQueryOnlySchema() : void
|
public function testDefinesAQueryOnlySchema() : void
|
||||||
{
|
{
|
||||||
$blogSchema = new Schema([
|
$blogSchema = new Schema([
|
||||||
'query' => $this->blogQuery
|
'query' => $this->blogQuery,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertSame($blogSchema->getQueryType(), $this->blogQuery);
|
$this->assertSame($blogSchema->getQueryType(), $this->blogQuery);
|
||||||
@ -220,7 +210,7 @@ class DefinitionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->blogQuery,
|
'query' => $this->blogQuery,
|
||||||
'mutation' => $this->blogMutation
|
'mutation' => $this->blogMutation,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertSame($this->blogMutation, $schema->getMutationType());
|
$this->assertSame($this->blogMutation, $schema->getMutationType());
|
||||||
@ -239,7 +229,7 @@ class DefinitionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->blogQuery,
|
'query' => $this->blogQuery,
|
||||||
'subscription' => $this->blogSubscription
|
'subscription' => $this->blogSubscription,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertEquals($this->blogSubscription, $schema->getSubscriptionType());
|
$this->assertEquals($this->blogSubscription, $schema->getSubscriptionType());
|
||||||
@ -258,19 +248,22 @@ class DefinitionTest extends TestCase
|
|||||||
$enumTypeWithDeprecatedValue = new EnumType([
|
$enumTypeWithDeprecatedValue = new EnumType([
|
||||||
'name' => 'EnumWithDeprecatedValue',
|
'name' => 'EnumWithDeprecatedValue',
|
||||||
'values' => [
|
'values' => [
|
||||||
'foo' => ['deprecationReason' => 'Just because']
|
'foo' => ['deprecationReason' => 'Just because'],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$value = $enumTypeWithDeprecatedValue->getValues()[0];
|
$value = $enumTypeWithDeprecatedValue->getValues()[0];
|
||||||
|
|
||||||
$this->assertArraySubset([
|
$this->assertArraySubset(
|
||||||
|
[
|
||||||
'name' => 'foo',
|
'name' => 'foo',
|
||||||
'description' => null,
|
'description' => null,
|
||||||
'deprecationReason' => 'Just because',
|
'deprecationReason' => 'Just because',
|
||||||
'value' => 'foo',
|
'value' => 'foo',
|
||||||
'astNode' => null
|
'astNode' => null,
|
||||||
], (array) $value);
|
],
|
||||||
|
(array) $value
|
||||||
|
);
|
||||||
|
|
||||||
$this->assertEquals(true, $value->isDeprecated());
|
$this->assertEquals(true, $value->isDeprecated());
|
||||||
}
|
}
|
||||||
@ -285,7 +278,7 @@ class DefinitionTest extends TestCase
|
|||||||
'values' => [
|
'values' => [
|
||||||
'NULL' => ['value' => null],
|
'NULL' => ['value' => null],
|
||||||
'UNDEFINED' => ['value' => null],
|
'UNDEFINED' => ['value' => null],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$expected = [
|
$expected = [
|
||||||
@ -308,8 +301,8 @@ class DefinitionTest extends TestCase
|
|||||||
$actual = $EnumTypeWithNullishValue->getValues();
|
$actual = $EnumTypeWithNullishValue->getValues();
|
||||||
|
|
||||||
$this->assertEquals(count($expected), count($actual));
|
$this->assertEquals(count($expected), count($actual));
|
||||||
$this->assertArraySubset($expected[0], (array)$actual[0]);
|
$this->assertArraySubset($expected[0], (array) $actual[0]);
|
||||||
$this->assertArraySubset($expected[1], (array)$actual[1]);
|
$this->assertArraySubset($expected[1], (array) $actual[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -322,9 +315,9 @@ class DefinitionTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'bar' => [
|
'bar' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'deprecationReason' => 'A terrible reason'
|
'deprecationReason' => 'A terrible reason',
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$field = $TypeWithDeprecatedField->getField('bar');
|
$field = $TypeWithDeprecatedField->getField('bar');
|
||||||
@ -343,25 +336,25 @@ class DefinitionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$nestedInputObject = new InputObjectType([
|
$nestedInputObject = new InputObjectType([
|
||||||
'name' => 'NestedInputObject',
|
'name' => 'NestedInputObject',
|
||||||
'fields' => ['value' => ['type' => Type::string()]]
|
'fields' => ['value' => ['type' => Type::string()]],
|
||||||
]);
|
]);
|
||||||
$someInputObject = new InputObjectType([
|
$someInputObject = new InputObjectType([
|
||||||
'name' => 'SomeInputObject',
|
'name' => 'SomeInputObject',
|
||||||
'fields' => ['nested' => ['type' => $nestedInputObject]]
|
'fields' => ['nested' => ['type' => $nestedInputObject]],
|
||||||
]);
|
]);
|
||||||
$someMutation = new ObjectType([
|
$someMutation = new ObjectType([
|
||||||
'name' => 'SomeMutation',
|
'name' => 'SomeMutation',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'mutateSomething' => [
|
'mutateSomething' => [
|
||||||
'type' => $this->blogArticle,
|
'type' => $this->blogArticle,
|
||||||
'args' => ['input' => ['type' => $someInputObject]]
|
'args' => ['input' => ['type' => $someInputObject]],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->blogQuery,
|
'query' => $this->blogQuery,
|
||||||
'mutation' => $someMutation
|
'mutation' => $someMutation,
|
||||||
]);
|
]);
|
||||||
$this->assertSame($nestedInputObject, $schema->getType('NestedInputObject'));
|
$this->assertSame($nestedInputObject, $schema->getType('NestedInputObject'));
|
||||||
}
|
}
|
||||||
@ -374,14 +367,14 @@ class DefinitionTest extends TestCase
|
|||||||
$someInterface = new InterfaceType([
|
$someInterface = new InterfaceType([
|
||||||
'name' => 'SomeInterface',
|
'name' => 'SomeInterface',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'f' => ['type' => Type::int()]
|
'f' => ['type' => Type::int()],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$someSubtype = new ObjectType([
|
$someSubtype = new ObjectType([
|
||||||
'name' => 'SomeSubtype',
|
'name' => 'SomeSubtype',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'f' => ['type' => Type::int()]
|
'f' => ['type' => Type::int()],
|
||||||
],
|
],
|
||||||
'interfaces' => [$someInterface],
|
'interfaces' => [$someInterface],
|
||||||
]);
|
]);
|
||||||
@ -390,10 +383,10 @@ class DefinitionTest extends TestCase
|
|||||||
'query' => new ObjectType([
|
'query' => new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'iface' => ['type' => $someInterface]
|
'iface' => ['type' => $someInterface],
|
||||||
]
|
],
|
||||||
]),
|
]),
|
||||||
'types' => [$someSubtype]
|
'types' => [$someSubtype],
|
||||||
]);
|
]);
|
||||||
$this->assertSame($someSubtype, $schema->getType('SomeSubtype'));
|
$this->assertSame($someSubtype, $schema->getType('SomeSubtype'));
|
||||||
}
|
}
|
||||||
@ -408,26 +401,28 @@ class DefinitionTest extends TestCase
|
|||||||
$someSubtype = new ObjectType([
|
$someSubtype = new ObjectType([
|
||||||
'name' => 'SomeSubtype',
|
'name' => 'SomeSubtype',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'f' => ['type' => Type::int()]
|
'f' => ['type' => Type::int()],
|
||||||
],
|
],
|
||||||
'interfaces' => function() use (&$someInterface) { return [$someInterface]; },
|
'interfaces' => function () use (&$someInterface) {
|
||||||
|
return [$someInterface];
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$someInterface = new InterfaceType([
|
$someInterface = new InterfaceType([
|
||||||
'name' => 'SomeInterface',
|
'name' => 'SomeInterface',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'f' => ['type' => Type::int()]
|
'f' => ['type' => Type::int()],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => new ObjectType([
|
'query' => new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'iface' => ['type' => $someInterface]
|
'iface' => ['type' => $someInterface],
|
||||||
]
|
],
|
||||||
]),
|
]),
|
||||||
'types' => [$someSubtype]
|
'types' => [$someSubtype],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertSame($someSubtype, $schema->getType('SomeSubtype'));
|
$this->assertSame($someSubtype, $schema->getType('SomeSubtype'));
|
||||||
@ -483,11 +478,15 @@ class DefinitionTest extends TestCase
|
|||||||
[$this->interfaceType, false],
|
[$this->interfaceType, false],
|
||||||
[$this->unionType, false],
|
[$this->unionType, false],
|
||||||
[$this->enumType, true],
|
[$this->enumType, true],
|
||||||
[$this->inputObjectType, true]
|
[$this->inputObjectType, true],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($expected as $index => $entry) {
|
foreach ($expected as $index => $entry) {
|
||||||
$this->assertSame($entry[1], Type::isInputType($entry[0]), "Type {$entry[0]} was detected incorrectly");
|
$this->assertSame(
|
||||||
|
$entry[1],
|
||||||
|
Type::isInputType($entry[0]),
|
||||||
|
sprintf('Type %s was detected incorrectly', $entry[0])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,11 +501,15 @@ class DefinitionTest extends TestCase
|
|||||||
[$this->interfaceType, true],
|
[$this->interfaceType, true],
|
||||||
[$this->unionType, true],
|
[$this->unionType, true],
|
||||||
[$this->enumType, true],
|
[$this->enumType, true],
|
||||||
[$this->inputObjectType, false]
|
[$this->inputObjectType, false],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($expected as $index => $entry) {
|
foreach ($expected as $index => $entry) {
|
||||||
$this->assertSame($entry[1], Type::isOutputType($entry[0]), "Type {$entry[0]} was detected incorrectly");
|
$this->assertSame(
|
||||||
|
$entry[1],
|
||||||
|
Type::isOutputType($entry[0]),
|
||||||
|
sprintf('Type %s was detected incorrectly', $entry[0])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +532,9 @@ class DefinitionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$union = new UnionType([
|
$union = new UnionType([
|
||||||
'name' => 'ThunkUnion',
|
'name' => 'ThunkUnion',
|
||||||
'types' => function() {return [$this->objectType]; }
|
'types' => function () {
|
||||||
|
return [$this->objectType];
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$types = $union->getTypes();
|
$types = $union->getTypes();
|
||||||
@ -543,8 +548,8 @@ class DefinitionTest extends TestCase
|
|||||||
$node = new InterfaceType([
|
$node = new InterfaceType([
|
||||||
'name' => 'Node',
|
'name' => 'Node',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'id' => ['type' => Type::nonNull(Type::id())]
|
'id' => ['type' => Type::nonNull(Type::id())],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$blog = null;
|
$blog = null;
|
||||||
@ -552,41 +557,41 @@ class DefinitionTest extends TestCase
|
|||||||
|
|
||||||
$user = new ObjectType([
|
$user = new ObjectType([
|
||||||
'name' => 'User',
|
'name' => 'User',
|
||||||
'fields' => function() use (&$blog, &$called) {
|
'fields' => function () use (&$blog, &$called) {
|
||||||
$this->assertNotNull($blog, 'Blog type is expected to be defined at this point, but it is null');
|
$this->assertNotNull($blog, 'Blog type is expected to be defined at this point, but it is null');
|
||||||
$called = true;
|
$called = true;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => ['type' => Type::nonNull(Type::id())],
|
'id' => ['type' => Type::nonNull(Type::id())],
|
||||||
'blogs' => ['type' => Type::nonNull(Type::listOf(Type::nonNull($blog)))]
|
'blogs' => ['type' => Type::nonNull(Type::listOf(Type::nonNull($blog)))],
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
'interfaces' => function() use ($node) {
|
'interfaces' => function () use ($node) {
|
||||||
return [$node];
|
return [$node];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$blog = new ObjectType([
|
$blog = new ObjectType([
|
||||||
'name' => 'Blog',
|
'name' => 'Blog',
|
||||||
'fields' => function() use ($user) {
|
'fields' => function () use ($user) {
|
||||||
return [
|
return [
|
||||||
'id' => ['type' => Type::nonNull(Type::id())],
|
'id' => ['type' => Type::nonNull(Type::id())],
|
||||||
'owner' => ['type' => Type::nonNull($user)]
|
'owner' => ['type' => Type::nonNull($user)],
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
'interfaces' => function() use ($node) {
|
'interfaces' => function () use ($node) {
|
||||||
return [$node];
|
return [$node];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => new ObjectType([
|
'query' => new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'node' => ['type' => $node]
|
'node' => ['type' => $node],
|
||||||
]
|
],
|
||||||
]),
|
]),
|
||||||
'types' => [$user, $blog]
|
'types' => [$user, $blog],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($called);
|
$this->assertTrue($called);
|
||||||
@ -607,27 +612,29 @@ class DefinitionTest extends TestCase
|
|||||||
$called = false;
|
$called = false;
|
||||||
$inputObject = new InputObjectType([
|
$inputObject = new InputObjectType([
|
||||||
'name' => 'InputObject',
|
'name' => 'InputObject',
|
||||||
'fields' => function() use (&$inputObject, &$called) {
|
'fields' => function () use (&$inputObject, &$called) {
|
||||||
$called = true;
|
$called = true;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'value' => ['type' => Type::string()],
|
'value' => ['type' => Type::string()],
|
||||||
'nested' => ['type' => $inputObject ]
|
'nested' => ['type' => $inputObject],
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$someMutation = new ObjectType([
|
$someMutation = new ObjectType([
|
||||||
'name' => 'SomeMutation',
|
'name' => 'SomeMutation',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'mutateSomething' => [
|
'mutateSomething' => [
|
||||||
'type' => $this->blogArticle,
|
'type' => $this->blogArticle,
|
||||||
'args' => ['input' => ['type' => $inputObject]]
|
'args' => ['input' => ['type' => $inputObject]],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->blogQuery,
|
'query' => $this->blogQuery,
|
||||||
'mutation' => $someMutation
|
'mutation' => $someMutation,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertSame($inputObject, $schema->getType('InputObject'));
|
$this->assertSame($inputObject, $schema->getType('InputObject'));
|
||||||
@ -642,25 +649,24 @@ class DefinitionTest extends TestCase
|
|||||||
$called = false;
|
$called = false;
|
||||||
$interface = new InterfaceType([
|
$interface = new InterfaceType([
|
||||||
'name' => 'SomeInterface',
|
'name' => 'SomeInterface',
|
||||||
'fields' => function() use (&$interface, &$called) {
|
'fields' => function () use (&$interface, &$called) {
|
||||||
$called = true;
|
$called = true;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'value' => ['type' => Type::string()],
|
'value' => ['type' => Type::string()],
|
||||||
'nested' => ['type' => $interface ]
|
'nested' => ['type' => $interface],
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$query = new ObjectType([
|
$query = new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'test' => ['type' => $interface]
|
'test' => ['type' => $interface],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema([
|
$schema = new Schema(['query' => $query]);
|
||||||
'query' => $query
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->assertSame($interface, $schema->getType('SomeInterface'));
|
$this->assertSame($interface, $schema->getType('SomeInterface'));
|
||||||
$this->assertTrue($called);
|
$this->assertTrue($called);
|
||||||
@ -673,30 +679,26 @@ class DefinitionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$interface = new InterfaceType([
|
$interface = new InterfaceType([
|
||||||
'name' => 'SomeInterface',
|
'name' => 'SomeInterface',
|
||||||
'fields' => function() use (&$interface) {
|
'fields' => function () use (&$interface) {
|
||||||
return [
|
return [
|
||||||
'value' => Type::string(),
|
'value' => Type::string(),
|
||||||
'nested' => $interface,
|
'nested' => $interface,
|
||||||
'withArg' => [
|
'withArg' => [
|
||||||
'type' => Type::string(),
|
'type' => Type::string(),
|
||||||
'args' => [
|
'args' => [
|
||||||
'arg1' => Type::int()
|
'arg1' => Type::int(),
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$query = new ObjectType([
|
$query = new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => [
|
'fields' => ['test' => $interface],
|
||||||
'test' => $interface
|
|
||||||
]
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema([
|
$schema = new Schema(['query' => $query]);
|
||||||
'query' => $query
|
|
||||||
]);
|
|
||||||
|
|
||||||
$valueField = $schema->getType('SomeInterface')->getField('value');
|
$valueField = $schema->getType('SomeInterface')->getField('value');
|
||||||
$nestedField = $schema->getType('SomeInterface')->getField('nested');
|
$nestedField = $schema->getType('SomeInterface')->getField('nested');
|
||||||
@ -728,14 +730,17 @@ class DefinitionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$idType = new CustomScalarType([
|
$idType = new CustomScalarType([
|
||||||
'name' => 'ID',
|
'name' => 'ID',
|
||||||
'serialize' => function() {},
|
'serialize' => function () {
|
||||||
'parseValue' => function() {},
|
},
|
||||||
'parseLiteral' => function() {}
|
'parseValue' => function () {
|
||||||
|
},
|
||||||
|
'parseLiteral' => function () {
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => new ObjectType(['name' => 'Query', 'fields' => []]),
|
'query' => new ObjectType(['name' => 'Query', 'fields' => []]),
|
||||||
'types' => [$idType]
|
'types' => [$idType],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertSame($idType, $schema->getType('ID'));
|
$this->assertSame($idType, $schema->getType('ID'));
|
||||||
@ -767,9 +772,7 @@ class DefinitionTest extends TestCase
|
|||||||
{
|
{
|
||||||
$objType = new ObjectType([
|
$objType = new ObjectType([
|
||||||
'name' => 'SomeObject',
|
'name' => 'SomeObject',
|
||||||
'fields' => [
|
'fields' => ['f' => null],
|
||||||
'f' => null,
|
|
||||||
],
|
|
||||||
]);
|
]);
|
||||||
$this->expectException(InvariantViolation::class);
|
$this->expectException(InvariantViolation::class);
|
||||||
$this->expectExceptionMessage(
|
$this->expectExceptionMessage(
|
||||||
@ -929,6 +932,17 @@ class DefinitionTest extends TestCase
|
|||||||
|
|
||||||
// Type System: Object fields must have valid resolve values
|
// Type System: Object fields must have valid resolve values
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see it('accepts a lambda as an Object field resolver')
|
||||||
|
*/
|
||||||
|
public function testAcceptsALambdaAsAnObjectFieldResolver() : void
|
||||||
|
{
|
||||||
|
$this->expectNotToPerformAssertions();
|
||||||
|
// should not throw:
|
||||||
|
$this->schemaWithObjectWithFieldResolver(function () {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private function schemaWithObjectWithFieldResolver($resolveValue)
|
private function schemaWithObjectWithFieldResolver($resolveValue)
|
||||||
{
|
{
|
||||||
$BadResolverType = new ObjectType([
|
$BadResolverType = new ObjectType([
|
||||||
@ -950,17 +964,8 @@ class DefinitionTest extends TestCase
|
|||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
$schema->assertValid();
|
$schema->assertValid();
|
||||||
return $schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
return $schema;
|
||||||
* @see it('accepts a lambda as an Object field resolver')
|
|
||||||
*/
|
|
||||||
public function testAcceptsALambdaAsAnObjectFieldResolver() : void
|
|
||||||
{
|
|
||||||
$this->expectNotToPerformAssertions();
|
|
||||||
// should not throw:
|
|
||||||
$this->schemaWithObjectWithFieldResolver(function () {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -987,21 +992,8 @@ class DefinitionTest extends TestCase
|
|||||||
$this->schemaWithObjectWithFieldResolver(0);
|
$this->schemaWithObjectWithFieldResolver(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Type System: Interface types must be resolvable
|
// Type System: Interface types must be resolvable
|
||||||
|
|
||||||
private function schemaWithFieldType($type)
|
|
||||||
{
|
|
||||||
$schema = new Schema([
|
|
||||||
'query' => new ObjectType([
|
|
||||||
'name' => 'Query',
|
|
||||||
'fields' => ['field' => ['type' => $type]],
|
|
||||||
]),
|
|
||||||
'types' => [$type],
|
|
||||||
]);
|
|
||||||
$schema->assertValid();
|
|
||||||
return $schema;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts an Interface type defining resolveType')
|
* @see it('accepts an Interface type defining resolveType')
|
||||||
*/
|
*/
|
||||||
@ -1023,6 +1015,20 @@ class DefinitionTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function schemaWithFieldType($type)
|
||||||
|
{
|
||||||
|
$schema = new Schema([
|
||||||
|
'query' => new ObjectType([
|
||||||
|
'name' => 'Query',
|
||||||
|
'fields' => ['field' => ['type' => $type]],
|
||||||
|
]),
|
||||||
|
'types' => [$type],
|
||||||
|
]);
|
||||||
|
$schema->assertValid();
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts an Interface with implementing type defining isTypeOf')
|
* @see it('accepts an Interface with implementing type defining isTypeOf')
|
||||||
*/
|
*/
|
||||||
@ -1085,14 +1091,6 @@ class DefinitionTest extends TestCase
|
|||||||
|
|
||||||
// Type System: Union types must be resolvable
|
// Type System: Union types must be resolvable
|
||||||
|
|
||||||
private function ObjectWithIsTypeOf()
|
|
||||||
{
|
|
||||||
return new ObjectType([
|
|
||||||
'name' => 'ObjectWithIsTypeOf',
|
|
||||||
'fields' => ['f' => ['type' => Type::string()]],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts a Union type defining resolveType')
|
* @see it('accepts a Union type defining resolveType')
|
||||||
*/
|
*/
|
||||||
@ -1156,8 +1154,6 @@ class DefinitionTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type System: Scalar types must be serializable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts a Scalar type defining serialize')
|
* @see it('accepts a Scalar type defining serialize')
|
||||||
*/
|
*/
|
||||||
@ -1175,6 +1171,8 @@ class DefinitionTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type System: Scalar types must be serializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('rejects a Scalar type not defining serialize')
|
* @see it('rejects a Scalar type not defining serialize')
|
||||||
*/
|
*/
|
||||||
@ -1187,9 +1185,7 @@ class DefinitionTest extends TestCase
|
|||||||
'functions are also provided.'
|
'functions are also provided.'
|
||||||
);
|
);
|
||||||
$this->schemaWithFieldType(
|
$this->schemaWithFieldType(
|
||||||
new CustomScalarType([
|
new CustomScalarType(['name' => 'SomeScalar'])
|
||||||
'name' => 'SomeScalar',
|
|
||||||
])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1292,8 +1288,6 @@ class DefinitionTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type System: Object types must be assertable
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts an Object type with an isTypeOf function')
|
* @see it('accepts an Object type with an isTypeOf function')
|
||||||
*/
|
*/
|
||||||
@ -1309,6 +1303,8 @@ class DefinitionTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type System: Object types must be assertable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('rejects an Object type with an incorrect type for isTypeOf')
|
* @see it('rejects an Object type with an incorrect type for isTypeOf')
|
||||||
*/
|
*/
|
||||||
@ -1327,8 +1323,6 @@ class DefinitionTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type System: Union types must be array
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts a Union type with array types')
|
* @see it('accepts a Union type with array types')
|
||||||
*/
|
*/
|
||||||
@ -1344,6 +1338,8 @@ class DefinitionTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type System: Union types must be array
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts a Union type with function returning an array of types')
|
* @see it('accepts a Union type with function returning an array of types')
|
||||||
*/
|
*/
|
||||||
@ -1370,9 +1366,7 @@ class DefinitionTest extends TestCase
|
|||||||
'Must provide Array of types or a callable which returns such an array for Union SomeUnion'
|
'Must provide Array of types or a callable which returns such an array for Union SomeUnion'
|
||||||
);
|
);
|
||||||
$this->schemaWithFieldType(
|
$this->schemaWithFieldType(
|
||||||
new UnionType([
|
new UnionType(['name' => 'SomeUnion'])
|
||||||
'name' => 'SomeUnion',
|
|
||||||
])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1388,13 +1382,11 @@ class DefinitionTest extends TestCase
|
|||||||
$this->schemaWithFieldType(
|
$this->schemaWithFieldType(
|
||||||
new UnionType([
|
new UnionType([
|
||||||
'name' => 'SomeUnion',
|
'name' => 'SomeUnion',
|
||||||
'types' => (object)[ 'test' => $this->objectType, ],
|
'types' => (object) ['test' => $this->objectType],
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type System: Input Objects must have fields
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts an Input Object type with fields')
|
* @see it('accepts an Input Object type with fields')
|
||||||
*/
|
*/
|
||||||
@ -1410,6 +1402,8 @@ class DefinitionTest extends TestCase
|
|||||||
$this->assertSame(Type::string(), $inputObjType->getField('f')->getType());
|
$this->assertSame(Type::string(), $inputObjType->getField('f')->getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type System: Input Objects must have fields
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts an Input Object type with a field function')
|
* @see it('accepts an Input Object type with a field function')
|
||||||
*/
|
*/
|
||||||
@ -1438,7 +1432,7 @@ class DefinitionTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
$this->expectException(InvariantViolation::class);
|
$this->expectException(InvariantViolation::class);
|
||||||
$this->expectExceptionMessage(
|
$this->expectExceptionMessage(
|
||||||
'SomeInputObject fields must be an associative array with field names as keys or a callable '.
|
'SomeInputObject fields must be an associative array with field names as keys or a callable ' .
|
||||||
'which returns such an array.'
|
'which returns such an array.'
|
||||||
);
|
);
|
||||||
$inputObjType->assertValid();
|
$inputObjType->assertValid();
|
||||||
@ -1463,8 +1457,6 @@ class DefinitionTest extends TestCase
|
|||||||
$inputObjType->assertValid();
|
$inputObjType->assertValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type System: Input Object fields must not have resolvers
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('rejects an Input Object type with resolvers')
|
* @see it('rejects an Input Object type with resolvers')
|
||||||
*/
|
*/
|
||||||
@ -1489,6 +1481,8 @@ class DefinitionTest extends TestCase
|
|||||||
$inputObjType->assertValid();
|
$inputObjType->assertValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type System: Input Object fields must not have resolvers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('rejects an Input Object type with resolver constant')
|
* @see it('rejects an Input Object type with resolver constant')
|
||||||
*/
|
*/
|
||||||
@ -1511,8 +1505,6 @@ class DefinitionTest extends TestCase
|
|||||||
$inputObjType->assertValid();
|
$inputObjType->assertValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type System: Enum types must be well defined
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts a well defined Enum type with empty value definition')
|
* @see it('accepts a well defined Enum type with empty value definition')
|
||||||
*/
|
*/
|
||||||
@ -1529,6 +1521,8 @@ class DefinitionTest extends TestCase
|
|||||||
$this->assertEquals('BAR', $enumType->getValue('BAR')->value);
|
$this->assertEquals('BAR', $enumType->getValue('BAR')->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type System: Enum types must be well defined
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('accepts a well defined Enum type with internal value definition')
|
* @see it('accepts a well defined Enum type with internal value definition')
|
||||||
*/
|
*/
|
||||||
@ -1569,9 +1563,7 @@ class DefinitionTest extends TestCase
|
|||||||
$enumType = new EnumType([
|
$enumType = new EnumType([
|
||||||
'name' => 'SomeEnum',
|
'name' => 'SomeEnum',
|
||||||
'values' => [
|
'values' => [
|
||||||
'FOO' => [
|
'FOO' => ['isDeprecated' => true],
|
||||||
'isDeprecated' => true,
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
$this->expectException(InvariantViolation::class);
|
$this->expectException(InvariantViolation::class);
|
||||||
@ -1582,7 +1574,6 @@ class DefinitionTest extends TestCase
|
|||||||
$enumType->assertValid();
|
$enumType->assertValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type System: List must accept only types
|
* Type System: List must accept only types
|
||||||
*/
|
*/
|
||||||
@ -1606,21 +1597,20 @@ class DefinitionTest extends TestCase
|
|||||||
try {
|
try {
|
||||||
Type::listOf($type);
|
Type::listOf($type);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->fail("List is expected to accept type: " . get_class($type) . ", but got error: ". $e->getMessage());
|
$this->fail('List is expected to accept type: ' . get_class($type) . ', but got error: ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($badTypes as $badType) {
|
foreach ($badTypes as $badType) {
|
||||||
$typeStr = Utils::printSafe($badType);
|
$typeStr = Utils::printSafe($badType);
|
||||||
try {
|
try {
|
||||||
Type::listOf($badType);
|
Type::listOf($badType);
|
||||||
$this->fail("List should not accept $typeStr");
|
$this->fail(sprintf('List should not accept %s', $typeStr));
|
||||||
} catch (InvariantViolation $e) {
|
} catch (InvariantViolation $e) {
|
||||||
$this->assertEquals("Expected $typeStr to be a GraphQL type.", $e->getMessage());
|
$this->assertEquals(sprintf('Expected %s to be a GraphQL type.', $typeStr), $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type System: NonNull must only accept non-nullable types
|
* Type System: NonNull must only accept non-nullable types
|
||||||
*/
|
*/
|
||||||
@ -1648,22 +1638,20 @@ class DefinitionTest extends TestCase
|
|||||||
try {
|
try {
|
||||||
Type::nonNull($type);
|
Type::nonNull($type);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->fail("NonNull is expected to accept type: " . get_class($type) . ", but got error: ". $e->getMessage());
|
$this->fail('NonNull is expected to accept type: ' . get_class($type) . ', but got error: ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($notNullableTypes as $badType) {
|
foreach ($notNullableTypes as $badType) {
|
||||||
$typeStr = Utils::printSafe($badType);
|
$typeStr = Utils::printSafe($badType);
|
||||||
try {
|
try {
|
||||||
Type::nonNull($badType);
|
Type::nonNull($badType);
|
||||||
$this->fail("Nulls should not accept $typeStr");
|
$this->fail(sprintf('Nulls should not accept %s', $typeStr));
|
||||||
} catch (InvariantViolation $e) {
|
} catch (InvariantViolation $e) {
|
||||||
$this->assertEquals("Expected $typeStr to be a GraphQL nullable type.", $e->getMessage());
|
$this->assertEquals(sprintf('Expected %s to be a GraphQL nullable type.', $typeStr), $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type System: A Schema must contain uniquely named types
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('rejects a Schema which redefines a built-in type')
|
* @see it('rejects a Schema which redefines a built-in type')
|
||||||
*/
|
*/
|
||||||
@ -1685,13 +1673,15 @@ class DefinitionTest extends TestCase
|
|||||||
|
|
||||||
$this->expectException(InvariantViolation::class);
|
$this->expectException(InvariantViolation::class);
|
||||||
$this->expectExceptionMessage(
|
$this->expectExceptionMessage(
|
||||||
'Schema must contain unique named types but contains multiple types named "String" '.
|
'Schema must contain unique named types but contains multiple types named "String" ' .
|
||||||
'(see http://webonyx.github.io/graphql-php/type-system/#type-registry).'
|
'(see http://webonyx.github.io/graphql-php/type-system/#type-registry).'
|
||||||
);
|
);
|
||||||
$schema = new Schema(['query' => $QueryType]);
|
$schema = new Schema(['query' => $QueryType]);
|
||||||
$schema->assertValid();
|
$schema->assertValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type System: A Schema must contain uniquely named types
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('rejects a Schema which defines an object type twice')
|
* @see it('rejects a Schema which defines an object type twice')
|
||||||
*/
|
*/
|
||||||
@ -1719,7 +1709,7 @@ class DefinitionTest extends TestCase
|
|||||||
'Schema must contain unique named types but contains multiple types named "SameName" ' .
|
'Schema must contain unique named types but contains multiple types named "SameName" ' .
|
||||||
'(see http://webonyx.github.io/graphql-php/type-system/#type-registry).'
|
'(see http://webonyx.github.io/graphql-php/type-system/#type-registry).'
|
||||||
);
|
);
|
||||||
$schema = new Schema([ 'query' => $QueryType ]);
|
$schema = new Schema(['query' => $QueryType]);
|
||||||
$schema->assertValid();
|
$schema->assertValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1763,4 +1753,12 @@ class DefinitionTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
$schema->assertValid();
|
$schema->assertValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function objectWithIsTypeOf() : ObjectType
|
||||||
|
{
|
||||||
|
return new ObjectType([
|
||||||
|
'name' => 'ObjectWithIsTypeOf',
|
||||||
|
'fields' => ['f' => ['type' => Type::string()]],
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,33 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Tests\Type;
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
use GraphQL\GraphQL;
|
use GraphQL\GraphQL;
|
||||||
use GraphQL\Language\SourceLocation;
|
use GraphQL\Language\SourceLocation;
|
||||||
use GraphQL\Type\Schema;
|
|
||||||
use GraphQL\Type\Definition\EnumType;
|
use GraphQL\Type\Definition\EnumType;
|
||||||
use GraphQL\Type\Definition\ObjectType;
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Introspection;
|
use GraphQL\Type\Introspection;
|
||||||
|
use GraphQL\Type\Schema;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use function count;
|
||||||
|
use function is_array;
|
||||||
|
|
||||||
class EnumTypeTest extends TestCase
|
class EnumTypeTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/** @var Schema */
|
||||||
* @var Schema
|
|
||||||
*/
|
|
||||||
private $schema;
|
private $schema;
|
||||||
|
|
||||||
/**
|
/** @var EnumType */
|
||||||
* @var EnumType
|
|
||||||
*/
|
|
||||||
private $ComplexEnum;
|
private $ComplexEnum;
|
||||||
|
|
||||||
|
/** @var mixed[] */
|
||||||
private $Complex1;
|
private $Complex1;
|
||||||
|
|
||||||
|
/** @var ArrayObject */
|
||||||
private $Complex2;
|
private $Complex2;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
@ -34,25 +38,30 @@ class EnumTypeTest extends TestCase
|
|||||||
'RED' => ['value' => 0],
|
'RED' => ['value' => 0],
|
||||||
'GREEN' => ['value' => 1],
|
'GREEN' => ['value' => 1],
|
||||||
'BLUE' => ['value' => 2],
|
'BLUE' => ['value' => 2],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$simpleEnum = new EnumType([
|
$simpleEnum = new EnumType([
|
||||||
'name' => 'SimpleEnum',
|
'name' => 'SimpleEnum',
|
||||||
'values' => [
|
'values' => [
|
||||||
'ONE', 'TWO', 'THREE'
|
'ONE',
|
||||||
]
|
'TWO',
|
||||||
|
'THREE',
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$Complex1 = ['someRandomFunction' => function() {}];
|
$Complex1 = [
|
||||||
|
'someRandomFunction' => function () {
|
||||||
|
},
|
||||||
|
];
|
||||||
$Complex2 = new \ArrayObject(['someRandomValue' => 123]);
|
$Complex2 = new \ArrayObject(['someRandomValue' => 123]);
|
||||||
|
|
||||||
$ComplexEnum = new EnumType([
|
$ComplexEnum = new EnumType([
|
||||||
'name' => 'Complex',
|
'name' => 'Complex',
|
||||||
'values' => [
|
'values' => [
|
||||||
'ONE' => ['value' => $Complex1],
|
'ONE' => ['value' => $Complex1],
|
||||||
'TWO' => ['value' => $Complex2]
|
'TWO' => ['value' => $Complex2],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$QueryType = new ObjectType([
|
$QueryType = new ObjectType([
|
||||||
@ -75,22 +84,22 @@ class EnumTypeTest extends TestCase
|
|||||||
if (isset($args['fromEnum'])) {
|
if (isset($args['fromEnum'])) {
|
||||||
return $args['fromEnum'];
|
return $args['fromEnum'];
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
'simpleEnum' => [
|
'simpleEnum' => [
|
||||||
'type' => $simpleEnum,
|
'type' => $simpleEnum,
|
||||||
'args' => [
|
'args' => [
|
||||||
'fromName' => ['type' => Type::string()],
|
'fromName' => ['type' => Type::string()],
|
||||||
'fromValue' => ['type' => Type::string()]
|
'fromValue' => ['type' => Type::string()],
|
||||||
],
|
],
|
||||||
'resolve' => function($value, $args) {
|
'resolve' => function ($value, $args) {
|
||||||
if (isset($args['fromName'])) {
|
if (isset($args['fromName'])) {
|
||||||
return $args['fromName'];
|
return $args['fromName'];
|
||||||
}
|
}
|
||||||
if (isset($args['fromValue'])) {
|
if (isset($args['fromValue'])) {
|
||||||
return $args['fromValue'];
|
return $args['fromValue'];
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
'colorInt' => [
|
'colorInt' => [
|
||||||
'type' => Type::int(),
|
'type' => Type::int(),
|
||||||
@ -105,7 +114,7 @@ class EnumTypeTest extends TestCase
|
|||||||
if (isset($args['fromEnum'])) {
|
if (isset($args['fromEnum'])) {
|
||||||
return $args['fromEnum'];
|
return $args['fromEnum'];
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
'complexEnum' => [
|
'complexEnum' => [
|
||||||
'type' => $ComplexEnum,
|
'type' => $ComplexEnum,
|
||||||
@ -114,30 +123,31 @@ class EnumTypeTest extends TestCase
|
|||||||
'type' => $ComplexEnum,
|
'type' => $ComplexEnum,
|
||||||
// Note: defaultValue is provided an *internal* representation for
|
// Note: defaultValue is provided an *internal* representation for
|
||||||
// Enums, rather than the string name.
|
// Enums, rather than the string name.
|
||||||
'defaultValue' => $Complex1
|
'defaultValue' => $Complex1,
|
||||||
],
|
],
|
||||||
'provideGoodValue' => [
|
'provideGoodValue' => [
|
||||||
'type' => Type::boolean(),
|
'type' => Type::boolean(),
|
||||||
],
|
],
|
||||||
'provideBadValue' => [
|
'provideBadValue' => [
|
||||||
'type' => Type::boolean()
|
'type' => Type::boolean(),
|
||||||
]
|
|
||||||
],
|
],
|
||||||
'resolve' => function($value, $args) use ($Complex1, $Complex2) {
|
],
|
||||||
if (!empty($args['provideGoodValue'])) {
|
'resolve' => function ($value, $args) use ($Complex1, $Complex2) {
|
||||||
|
if (! empty($args['provideGoodValue'])) {
|
||||||
// Note: this is one of the references of the internal values which
|
// Note: this is one of the references of the internal values which
|
||||||
// ComplexEnum allows.
|
// ComplexEnum allows.
|
||||||
return $Complex2;
|
return $Complex2;
|
||||||
}
|
}
|
||||||
if (!empty($args['provideBadValue'])) {
|
if (! empty($args['provideBadValue'])) {
|
||||||
// Note: similar shape, but not the same *reference*
|
// Note: similar shape, but not the same *reference*
|
||||||
// as Complex2 above. Enum internal values require === equality.
|
// as Complex2 above. Enum internal values require === equality.
|
||||||
return new \ArrayObject(['someRandomValue' => 123]);
|
return new \ArrayObject(['someRandomValue' => 123]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $args['fromEnum'];
|
return $args['fromEnum'];
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$MutationType = new ObjectType([
|
$MutationType = new ObjectType([
|
||||||
@ -147,10 +157,10 @@ class EnumTypeTest extends TestCase
|
|||||||
'type' => $ColorType,
|
'type' => $ColorType,
|
||||||
'args' => ['color' => ['type' => $ColorType]],
|
'args' => ['color' => ['type' => $ColorType]],
|
||||||
'resolve' => function ($value, $args) {
|
'resolve' => function ($value, $args) {
|
||||||
return isset($args['color']) ? $args['color'] : null;
|
return $args['color'] ?? null;
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$SubscriptionType = new ObjectType([
|
$SubscriptionType = new ObjectType([
|
||||||
@ -160,10 +170,10 @@ class EnumTypeTest extends TestCase
|
|||||||
'type' => $ColorType,
|
'type' => $ColorType,
|
||||||
'args' => ['color' => ['type' => $ColorType]],
|
'args' => ['color' => ['type' => $ColorType]],
|
||||||
'resolve' => function ($value, $args) {
|
'resolve' => function ($value, $args) {
|
||||||
return isset($args['color']) ? $args['color'] : null;
|
return $args['color'] ?? null;
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->Complex1 = $Complex1;
|
$this->Complex1 = $Complex1;
|
||||||
@ -173,7 +183,7 @@ class EnumTypeTest extends TestCase
|
|||||||
$this->schema = new Schema([
|
$this->schema = new Schema([
|
||||||
'query' => $QueryType,
|
'query' => $QueryType,
|
||||||
'mutation' => $MutationType,
|
'mutation' => $MutationType,
|
||||||
'subscription' => $SubscriptionType
|
'subscription' => $SubscriptionType,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,12 +231,34 @@ class EnumTypeTest extends TestCase
|
|||||||
'{ colorEnum(fromEnum: "GREEN") }',
|
'{ colorEnum(fromEnum: "GREEN") }',
|
||||||
null,
|
null,
|
||||||
[
|
[
|
||||||
'message' => "Expected type Color, found \"GREEN\"; Did you mean the enum value GREEN?",
|
'message' => 'Expected type Color, found "GREEN"; Did you mean the enum value GREEN?',
|
||||||
'locations' => [new SourceLocation(1, 23)]
|
'locations' => [new SourceLocation(1, 23)],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function expectFailure($query, $vars, $err)
|
||||||
|
{
|
||||||
|
$result = GraphQL::executeQuery($this->schema, $query, null, null, $vars);
|
||||||
|
$this->assertEquals(1, count($result->errors));
|
||||||
|
|
||||||
|
if (is_array($err)) {
|
||||||
|
$this->assertEquals(
|
||||||
|
$err['message'],
|
||||||
|
$result->errors[0]->getMessage()
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$err['locations'],
|
||||||
|
$result->errors[0]->getLocations()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->assertEquals(
|
||||||
|
$err,
|
||||||
|
$result->errors[0]->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('does not accept valuesNotInTheEnum')
|
* @see it('does not accept valuesNotInTheEnum')
|
||||||
*/
|
*/
|
||||||
@ -236,8 +268,8 @@ class EnumTypeTest extends TestCase
|
|||||||
'{ colorEnum(fromEnum: GREENISH) }',
|
'{ colorEnum(fromEnum: GREENISH) }',
|
||||||
null,
|
null,
|
||||||
[
|
[
|
||||||
'message' => "Expected type Color, found GREENISH; Did you mean the enum value GREEN?",
|
'message' => 'Expected type Color, found GREENISH; Did you mean the enum value GREEN?',
|
||||||
'locations' => [new SourceLocation(1, 23)]
|
'locations' => [new SourceLocation(1, 23)],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -251,8 +283,8 @@ class EnumTypeTest extends TestCase
|
|||||||
'{ colorEnum(fromEnum: green) }',
|
'{ colorEnum(fromEnum: green) }',
|
||||||
null,
|
null,
|
||||||
[
|
[
|
||||||
'message' => "Expected type Color, found green; Did you mean the enum value GREEN?",
|
'message' => 'Expected type Color, found green; Did you mean the enum value GREEN?',
|
||||||
'locations' => [new SourceLocation(1, 23)]
|
'locations' => [new SourceLocation(1, 23)],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -281,7 +313,7 @@ class EnumTypeTest extends TestCase
|
|||||||
$this->expectFailure(
|
$this->expectFailure(
|
||||||
'{ colorEnum(fromEnum: 1) }',
|
'{ colorEnum(fromEnum: 1) }',
|
||||||
null,
|
null,
|
||||||
"Expected type Color, found 1."
|
'Expected type Color, found 1.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +325,7 @@ class EnumTypeTest extends TestCase
|
|||||||
$this->expectFailure(
|
$this->expectFailure(
|
||||||
'{ colorEnum(fromInt: GREEN) }',
|
'{ colorEnum(fromInt: GREEN) }',
|
||||||
null,
|
null,
|
||||||
"Expected type Int, found GREEN."
|
'Expected type Int, found GREEN.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +413,7 @@ class EnumTypeTest extends TestCase
|
|||||||
$this->expectFailure(
|
$this->expectFailure(
|
||||||
'query test($color: Int!) { colorEnum(fromEnum: $color) }',
|
'query test($color: Int!) { colorEnum(fromEnum: $color) }',
|
||||||
['color' => 2],
|
['color' => 2],
|
||||||
'Variable "$color" of type "Int!" used in position ' . 'expecting type "Color".'
|
'Variable "$color" of type "Int!" used in position expecting type "Color".'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,10 +424,13 @@ class EnumTypeTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
['data' => ['colorEnum' => 'RED', 'colorInt' => 0]],
|
['data' => ['colorEnum' => 'RED', 'colorInt' => 0]],
|
||||||
GraphQL::executeQuery($this->schema, "{
|
GraphQL::executeQuery(
|
||||||
|
$this->schema,
|
||||||
|
'{
|
||||||
colorEnum(fromEnum: RED)
|
colorEnum(fromEnum: RED)
|
||||||
colorInt(fromEnum: RED)
|
colorInt(fromEnum: RED)
|
||||||
}")->toArray()
|
}'
|
||||||
|
)->toArray()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,10 +441,13 @@ class EnumTypeTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
['data' => ['colorEnum' => null, 'colorInt' => null]],
|
['data' => ['colorEnum' => null, 'colorInt' => null]],
|
||||||
GraphQL::executeQuery($this->schema, "{
|
GraphQL::executeQuery(
|
||||||
|
$this->schema,
|
||||||
|
'{
|
||||||
colorEnum
|
colorEnum
|
||||||
colorInt
|
colorInt
|
||||||
}")->toArray()
|
}'
|
||||||
|
)->toArray()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,25 +484,29 @@ class EnumTypeTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function testMayBeInternallyRepresentedWithComplexValues() : void
|
public function testMayBeInternallyRepresentedWithComplexValues() : void
|
||||||
{
|
{
|
||||||
$result = GraphQL::executeQuery($this->schema, '{
|
$result = GraphQL::executeQuery(
|
||||||
|
$this->schema,
|
||||||
|
'{
|
||||||
first: complexEnum
|
first: complexEnum
|
||||||
second: complexEnum(fromEnum: TWO)
|
second: complexEnum(fromEnum: TWO)
|
||||||
good: complexEnum(provideGoodValue: true)
|
good: complexEnum(provideGoodValue: true)
|
||||||
bad: complexEnum(provideBadValue: true)
|
bad: complexEnum(provideBadValue: true)
|
||||||
}')->toArray(true);
|
}'
|
||||||
|
)->toArray(true);
|
||||||
|
|
||||||
$expected = [
|
$expected = [
|
||||||
'data' => [
|
'data' => [
|
||||||
'first' => 'ONE',
|
'first' => 'ONE',
|
||||||
'second' => 'TWO',
|
'second' => 'TWO',
|
||||||
'good' => 'TWO',
|
'good' => 'TWO',
|
||||||
'bad' => null
|
'bad' => null,
|
||||||
],
|
],
|
||||||
'errors' => [[
|
'errors' => [[
|
||||||
'debugMessage' =>
|
'debugMessage' =>
|
||||||
'Expected a value of type "Complex" but received: instance of ArrayObject',
|
'Expected a value of type "Complex" but received: instance of ArrayObject',
|
||||||
'locations' => [['line' => 5, 'column' => 9]]
|
'locations' => [['line' => 5, 'column' => 9]],
|
||||||
]]
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->assertArraySubset($expected, $result);
|
$this->assertArraySubset($expected, $result);
|
||||||
@ -492,32 +534,11 @@ class EnumTypeTest extends TestCase
|
|||||||
'data' => ['first' => 'ONE', 'second' => 'TWO', 'third' => null],
|
'data' => ['first' => 'ONE', 'second' => 'TWO', 'third' => null],
|
||||||
'errors' => [[
|
'errors' => [[
|
||||||
'debugMessage' => 'Expected a value of type "SimpleEnum" but received: WRONG',
|
'debugMessage' => 'Expected a value of type "SimpleEnum" but received: WRONG',
|
||||||
'locations' => [['line' => 4, 'column' => 13]]
|
'locations' => [['line' => 4, 'column' => 13]],
|
||||||
]]
|
],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
GraphQL::executeQuery($this->schema, $q)->toArray(true)
|
GraphQL::executeQuery($this->schema, $q)->toArray(true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function expectFailure($query, $vars, $err)
|
|
||||||
{
|
|
||||||
$result = GraphQL::executeQuery($this->schema, $query, null, null, $vars);
|
|
||||||
$this->assertEquals(1, count($result->errors));
|
|
||||||
|
|
||||||
if (is_array($err)) {
|
|
||||||
$this->assertEquals(
|
|
||||||
$err['message'],
|
|
||||||
$result->errors[0]->getMessage()
|
|
||||||
);
|
|
||||||
$this->assertEquals(
|
|
||||||
$err['locations'],
|
|
||||||
$result->errors[0]->getLocations()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->assertEquals(
|
|
||||||
$err,
|
|
||||||
$result->errors[0]->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Tests\Type;
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
class ObjectIdStub
|
class ObjectIdStub
|
||||||
{
|
{
|
||||||
/**
|
/** @var int */
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Tests\Type;
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
@ -10,75 +13,53 @@ use GraphQL\Type\Definition\UnionType;
|
|||||||
use GraphQL\Type\EagerResolution;
|
use GraphQL\Type\EagerResolution;
|
||||||
use GraphQL\Type\LazyResolution;
|
use GraphQL\Type\LazyResolution;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use function lcfirst;
|
||||||
|
|
||||||
class ResolutionTest extends TestCase
|
class ResolutionTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $query;
|
private $query;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $mutation;
|
private $mutation;
|
||||||
|
|
||||||
/**
|
/** @var InterfaceType */
|
||||||
* @var InterfaceType
|
|
||||||
*/
|
|
||||||
private $node;
|
private $node;
|
||||||
|
|
||||||
/**
|
/** @var InterfaceType */
|
||||||
* @var InterfaceType
|
|
||||||
*/
|
|
||||||
private $content;
|
private $content;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $blogStory;
|
private $blogStory;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $link;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $video;
|
private $video;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $videoMetadata;
|
private $videoMetadata;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $comment;
|
private $comment;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $user;
|
private $user;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $category;
|
private $category;
|
||||||
|
|
||||||
/**
|
/** @var UnionType */
|
||||||
* @var UnionType
|
|
||||||
*/
|
|
||||||
private $mention;
|
private $mention;
|
||||||
|
|
||||||
|
/** @var ObjectType */
|
||||||
private $postStoryMutation;
|
private $postStoryMutation;
|
||||||
|
|
||||||
|
/** @var InputObjectType */
|
||||||
private $postStoryMutationInput;
|
private $postStoryMutationInput;
|
||||||
|
|
||||||
|
/** @var ObjectType */
|
||||||
private $postCommentMutation;
|
private $postCommentMutation;
|
||||||
|
|
||||||
|
/** @var InputObjectType */
|
||||||
private $postCommentMutationInput;
|
private $postCommentMutationInput;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
@ -86,48 +67,30 @@ class ResolutionTest extends TestCase
|
|||||||
$this->node = new InterfaceType([
|
$this->node = new InterfaceType([
|
||||||
'name' => 'Node',
|
'name' => 'Node',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'id' => Type::string()
|
'id' => Type::string(),
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->content = new InterfaceType([
|
$this->content = new InterfaceType([
|
||||||
'name' => 'Content',
|
'name' => 'Content',
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
return [
|
return [
|
||||||
'title' => Type::string(),
|
'title' => Type::string(),
|
||||||
'body' => Type::string(),
|
'body' => Type::string(),
|
||||||
'author' => $this->user,
|
'author' => $this->user,
|
||||||
'comments' => Type::listOf($this->comment),
|
'comments' => Type::listOf($this->comment),
|
||||||
'categories' => Type::listOf($this->category)
|
'categories' => Type::listOf($this->category),
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->blogStory = new ObjectType([
|
$this->blogStory = new ObjectType([
|
||||||
'name' => 'BlogStory',
|
'name' => 'BlogStory',
|
||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
$this->node,
|
$this->node,
|
||||||
$this->content
|
$this->content,
|
||||||
],
|
],
|
||||||
'fields' => function() {
|
'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')
|
|
||||||
];
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->link = new ObjectType([
|
|
||||||
'name' => 'Link',
|
|
||||||
'interfaces' => [
|
|
||||||
$this->node,
|
|
||||||
$this->content
|
|
||||||
],
|
|
||||||
'fields' => function() {
|
|
||||||
return [
|
return [
|
||||||
$this->node->getField('id'),
|
$this->node->getField('id'),
|
||||||
$this->content->getField('title'),
|
$this->content->getField('title'),
|
||||||
@ -135,87 +98,108 @@ class ResolutionTest extends TestCase
|
|||||||
$this->content->getField('author'),
|
$this->content->getField('author'),
|
||||||
$this->content->getField('comments'),
|
$this->content->getField('comments'),
|
||||||
$this->content->getField('categories'),
|
$this->content->getField('categories'),
|
||||||
'url' => Type::string()
|
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
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([
|
$this->video = new ObjectType([
|
||||||
'name' => 'Video',
|
'name' => 'Video',
|
||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
$this->node,
|
$this->node,
|
||||||
$this->content
|
$this->content,
|
||||||
],
|
],
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
return [
|
return [
|
||||||
$this->node->getField('id'),
|
'id' => $this->node->getField('id'),
|
||||||
$this->content->getField('title'),
|
'title' => $this->content->getField('title'),
|
||||||
$this->content->getField('body'),
|
'body' => $this->content->getField('body'),
|
||||||
$this->content->getField('author'),
|
'author' => $this->content->getField('author'),
|
||||||
$this->content->getField('comments'),
|
'comments' => $this->content->getField('comments'),
|
||||||
$this->content->getField('categories'),
|
'categories' => $this->content->getField('categories'),
|
||||||
'streamUrl' => Type::string(),
|
'streamUrl' => Type::string(),
|
||||||
'downloadUrl' => Type::string(),
|
'downloadUrl' => Type::string(),
|
||||||
'metadata' => $this->videoMetadata = new ObjectType([
|
'metadata' => $this->videoMetadata,
|
||||||
'name' => 'VideoMetadata',
|
|
||||||
'fields' => [
|
|
||||||
'lat' => Type::float(),
|
|
||||||
'lng' => Type::float()
|
|
||||||
]
|
|
||||||
])
|
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->comment = new ObjectType([
|
$this->comment = new ObjectType([
|
||||||
'name' => 'Comment',
|
'name' => 'Comment',
|
||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
$this->node
|
$this->node,
|
||||||
],
|
],
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
return [
|
return [
|
||||||
$this->node->getField('id'),
|
'id' => $this->node->getField('id'),
|
||||||
'author' => $this->user,
|
'author' => $this->user,
|
||||||
'text' => Type::string(),
|
'text' => Type::string(),
|
||||||
'replies' => Type::listOf($this->comment),
|
'replies' => Type::listOf($this->comment),
|
||||||
'parent' => $this->comment,
|
'parent' => $this->comment,
|
||||||
'content' => $this->content
|
'content' => $this->content,
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->user = new ObjectType([
|
$this->user = new ObjectType([
|
||||||
'name' => 'User',
|
'name' => 'User',
|
||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
$this->node
|
$this->node,
|
||||||
],
|
],
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
return [
|
return [
|
||||||
$this->node->getField('id'),
|
'id' => $this->node->getField('id'),
|
||||||
'name' => Type::string(),
|
'name' => Type::string(),
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->category = new ObjectType([
|
$this->category = new ObjectType([
|
||||||
'name' => 'Category',
|
'name' => 'Category',
|
||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
$this->node
|
$this->node,
|
||||||
],
|
],
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
return [
|
return [
|
||||||
$this->node->getField('id'),
|
'id' => $this->node->getField('id'),
|
||||||
'name' => Type::string()
|
'name' => Type::string(),
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->mention = new UnionType([
|
$this->mention = new UnionType([
|
||||||
'name' => 'Mention',
|
'name' => 'Mention',
|
||||||
'types' => [
|
'types' => [
|
||||||
$this->user,
|
$this->user,
|
||||||
$this->category
|
$this->category,
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->query = new ObjectType([
|
$this->query = new ObjectType([
|
||||||
@ -224,8 +208,18 @@ class ResolutionTest extends TestCase
|
|||||||
'viewer' => $this->user,
|
'viewer' => $this->user,
|
||||||
'latestContent' => $this->content,
|
'latestContent' => $this->content,
|
||||||
'node' => $this->node,
|
'node' => $this->node,
|
||||||
'mentions' => Type::listOf($this->mention)
|
'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([
|
$this->mutation = new ObjectType([
|
||||||
@ -235,28 +229,20 @@ class ResolutionTest extends TestCase
|
|||||||
'type' => $this->postStoryMutation = new ObjectType([
|
'type' => $this->postStoryMutation = new ObjectType([
|
||||||
'name' => 'PostStoryMutation',
|
'name' => 'PostStoryMutation',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'story' => $this->blogStory
|
'story' => $this->blogStory,
|
||||||
]
|
],
|
||||||
]),
|
]),
|
||||||
'args' => [
|
'args' => [
|
||||||
'input' => Type::nonNull($this->postStoryMutationInput = new InputObjectType([
|
'input' => Type::nonNull($this->postStoryMutationInput),
|
||||||
'name' => 'PostStoryMutationInput',
|
'clientRequestId' => Type::string(),
|
||||||
'fields' => [
|
],
|
||||||
'title' => Type::string(),
|
|
||||||
'body' => Type::string(),
|
|
||||||
'author' => Type::id(),
|
|
||||||
'category' => Type::id()
|
|
||||||
]
|
|
||||||
])),
|
|
||||||
'clientRequestId' => Type::string()
|
|
||||||
]
|
|
||||||
],
|
],
|
||||||
'postComment' => [
|
'postComment' => [
|
||||||
'type' => $this->postCommentMutation = new ObjectType([
|
'type' => $this->postCommentMutation = new ObjectType([
|
||||||
'name' => 'PostCommentMutation',
|
'name' => 'PostCommentMutation',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'comment' => $this->comment
|
'comment' => $this->comment,
|
||||||
]
|
],
|
||||||
]),
|
]),
|
||||||
'args' => [
|
'args' => [
|
||||||
'input' => Type::nonNull($this->postCommentMutationInput = new InputObjectType([
|
'input' => Type::nonNull($this->postCommentMutationInput = new InputObjectType([
|
||||||
@ -265,13 +251,13 @@ class ResolutionTest extends TestCase
|
|||||||
'text' => Type::nonNull(Type::string()),
|
'text' => Type::nonNull(Type::string()),
|
||||||
'author' => Type::nonNull(Type::id()),
|
'author' => Type::nonNull(Type::id()),
|
||||||
'content' => Type::id(),
|
'content' => Type::id(),
|
||||||
'parent' => Type::id()
|
'parent' => Type::id(),
|
||||||
]
|
],
|
||||||
])),
|
])),
|
||||||
'clientRequestId' => Type::string()
|
'clientRequestId' => Type::string(),
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +270,7 @@ class ResolutionTest extends TestCase
|
|||||||
'String' => Type::string(),
|
'String' => Type::string(),
|
||||||
'Float' => Type::float(),
|
'Float' => Type::float(),
|
||||||
'Int' => Type::int(),
|
'Int' => Type::int(),
|
||||||
'Boolean' => Type::boolean()
|
'Boolean' => Type::boolean(),
|
||||||
];
|
];
|
||||||
$this->assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
$this->assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
||||||
|
|
||||||
@ -297,7 +283,7 @@ class ResolutionTest extends TestCase
|
|||||||
'Int' => 1,
|
'Int' => 1,
|
||||||
'Boolean' => 1,
|
'Boolean' => 1,
|
||||||
],
|
],
|
||||||
'possibleTypeMap' => []
|
'possibleTypeMap' => [],
|
||||||
];
|
];
|
||||||
$this->assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
$this->assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
||||||
|
|
||||||
@ -321,10 +307,16 @@ class ResolutionTest extends TestCase
|
|||||||
$this->assertSame($this->postStoryMutation, $eagerTypeResolution->resolveType('PostStoryMutation'));
|
$this->assertSame($this->postStoryMutation, $eagerTypeResolution->resolveType('PostStoryMutation'));
|
||||||
$this->assertSame($this->postStoryMutationInput, $eagerTypeResolution->resolveType('PostStoryMutationInput'));
|
$this->assertSame($this->postStoryMutationInput, $eagerTypeResolution->resolveType('PostStoryMutationInput'));
|
||||||
$this->assertSame($this->postCommentMutation, $eagerTypeResolution->resolveType('PostCommentMutation'));
|
$this->assertSame($this->postCommentMutation, $eagerTypeResolution->resolveType('PostCommentMutation'));
|
||||||
$this->assertSame($this->postCommentMutationInput, $eagerTypeResolution->resolveType('PostCommentMutationInput'));
|
$this->assertSame(
|
||||||
|
$this->postCommentMutationInput,
|
||||||
|
$eagerTypeResolution->resolveType('PostCommentMutationInput')
|
||||||
|
);
|
||||||
|
|
||||||
$this->assertEquals([$this->blogStory], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
$this->assertEquals([$this->blogStory], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
||||||
$this->assertEquals([$this->user, $this->comment, $this->category, $this->blogStory], $eagerTypeResolution->resolvePossibleTypes($this->node));
|
$this->assertEquals(
|
||||||
|
[$this->user, $this->comment, $this->category, $this->blogStory],
|
||||||
|
$eagerTypeResolution->resolvePossibleTypes($this->node)
|
||||||
|
);
|
||||||
$this->assertEquals([$this->user, $this->category], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
$this->assertEquals([$this->user, $this->category], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
||||||
|
|
||||||
$expectedTypeMap = [
|
$expectedTypeMap = [
|
||||||
@ -345,7 +337,7 @@ class ResolutionTest extends TestCase
|
|||||||
'PostCommentMutation' => $this->postCommentMutation,
|
'PostCommentMutation' => $this->postCommentMutation,
|
||||||
'Float' => Type::float(),
|
'Float' => Type::float(),
|
||||||
'Int' => Type::int(),
|
'Int' => Type::int(),
|
||||||
'Boolean' => Type::boolean()
|
'Boolean' => Type::boolean(),
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
$this->assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
||||||
@ -370,23 +362,21 @@ class ResolutionTest extends TestCase
|
|||||||
'PostCommentMutation' => 1,
|
'PostCommentMutation' => 1,
|
||||||
'Float' => 1,
|
'Float' => 1,
|
||||||
'Int' => 1,
|
'Int' => 1,
|
||||||
'Boolean' => 1
|
'Boolean' => 1,
|
||||||
],
|
],
|
||||||
'possibleTypeMap' => [
|
'possibleTypeMap' => [
|
||||||
'Node' => [
|
'Node' => [
|
||||||
'User' => 1,
|
'User' => 1,
|
||||||
'Comment' => 1,
|
'Comment' => 1,
|
||||||
'Category' => 1,
|
'Category' => 1,
|
||||||
'BlogStory' => 1
|
'BlogStory' => 1,
|
||||||
],
|
|
||||||
'Content' => [
|
|
||||||
'BlogStory' => 1
|
|
||||||
],
|
],
|
||||||
|
'Content' => ['BlogStory' => 1],
|
||||||
'Mention' => [
|
'Mention' => [
|
||||||
'User' => 1,
|
'User' => 1,
|
||||||
'Category' => 1
|
'Category' => 1,
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
$this->assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
||||||
@ -402,7 +392,10 @@ class ResolutionTest extends TestCase
|
|||||||
$this->assertEquals(null, $eagerTypeResolution->resolveType('VideoMetadata'));
|
$this->assertEquals(null, $eagerTypeResolution->resolveType('VideoMetadata'));
|
||||||
|
|
||||||
$this->assertEquals([$this->blogStory], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
$this->assertEquals([$this->blogStory], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
||||||
$this->assertEquals([$this->user, $this->comment, $this->category, $this->blogStory], $eagerTypeResolution->resolvePossibleTypes($this->node));
|
$this->assertEquals(
|
||||||
|
[$this->user, $this->comment, $this->category, $this->blogStory],
|
||||||
|
$eagerTypeResolution->resolvePossibleTypes($this->node)
|
||||||
|
);
|
||||||
$this->assertEquals([$this->user, $this->category], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
$this->assertEquals([$this->user, $this->category], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
||||||
|
|
||||||
$eagerTypeResolution = new EagerResolution([null, $this->video, null]);
|
$eagerTypeResolution = new EagerResolution([null, $this->video, null]);
|
||||||
@ -410,7 +403,10 @@ class ResolutionTest extends TestCase
|
|||||||
$this->assertEquals($this->video, $eagerTypeResolution->resolveType('Video'));
|
$this->assertEquals($this->video, $eagerTypeResolution->resolveType('Video'));
|
||||||
|
|
||||||
$this->assertEquals([$this->video], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
$this->assertEquals([$this->video], $eagerTypeResolution->resolvePossibleTypes($this->content));
|
||||||
$this->assertEquals([$this->video, $this->user, $this->comment, $this->category], $eagerTypeResolution->resolvePossibleTypes($this->node));
|
$this->assertEquals(
|
||||||
|
[$this->video, $this->user, $this->comment, $this->category],
|
||||||
|
$eagerTypeResolution->resolvePossibleTypes($this->node)
|
||||||
|
);
|
||||||
$this->assertEquals([], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
$this->assertEquals([], $eagerTypeResolution->resolvePossibleTypes($this->mention));
|
||||||
|
|
||||||
$expectedTypeMap = [
|
$expectedTypeMap = [
|
||||||
@ -425,7 +421,7 @@ class ResolutionTest extends TestCase
|
|||||||
'Float' => Type::float(),
|
'Float' => Type::float(),
|
||||||
'ID' => Type::id(),
|
'ID' => Type::id(),
|
||||||
'Int' => Type::int(),
|
'Int' => Type::int(),
|
||||||
'Boolean' => Type::boolean()
|
'Boolean' => Type::boolean(),
|
||||||
];
|
];
|
||||||
$this->assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
$this->assertEquals($expectedTypeMap, $eagerTypeResolution->getTypeMap());
|
||||||
|
|
||||||
@ -443,19 +439,17 @@ class ResolutionTest extends TestCase
|
|||||||
'Float' => 1,
|
'Float' => 1,
|
||||||
'ID' => 1,
|
'ID' => 1,
|
||||||
'Int' => 1,
|
'Int' => 1,
|
||||||
'Boolean' => 1
|
'Boolean' => 1,
|
||||||
],
|
],
|
||||||
'possibleTypeMap' => [
|
'possibleTypeMap' => [
|
||||||
'Node' => [
|
'Node' => [
|
||||||
'Video' => 1,
|
'Video' => 1,
|
||||||
'User' => 1,
|
'User' => 1,
|
||||||
'Comment' => 1,
|
'Comment' => 1,
|
||||||
'Category' => 1
|
'Category' => 1,
|
||||||
|
],
|
||||||
|
'Content' => ['Video' => 1],
|
||||||
],
|
],
|
||||||
'Content' => [
|
|
||||||
'Video' => 1
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
$this->assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
$this->assertEquals($expectedDescriptor, $eagerTypeResolution->getDescriptor());
|
||||||
}
|
}
|
||||||
@ -466,8 +460,8 @@ class ResolutionTest extends TestCase
|
|||||||
$eager = new EagerResolution([]);
|
$eager = new EagerResolution([]);
|
||||||
$emptyDescriptor = $eager->getDescriptor();
|
$emptyDescriptor = $eager->getDescriptor();
|
||||||
|
|
||||||
$typeLoader = function($name) {
|
$typeLoader = function ($name) {
|
||||||
throw new \Exception("This should be never called for empty descriptor");
|
throw new \Exception('This should be never called for empty descriptor');
|
||||||
};
|
};
|
||||||
|
|
||||||
$lazy = new LazyResolution($emptyDescriptor, $typeLoader);
|
$lazy = new LazyResolution($emptyDescriptor, $typeLoader);
|
||||||
@ -480,9 +474,10 @@ class ResolutionTest extends TestCase
|
|||||||
|
|
||||||
$called = 0;
|
$called = 0;
|
||||||
$descriptor = $eager->getDescriptor();
|
$descriptor = $eager->getDescriptor();
|
||||||
$typeLoader = function($name) use (&$called) {
|
$typeLoader = function ($name) use (&$called) {
|
||||||
$called++;
|
$called++;
|
||||||
$prop = lcfirst($name);
|
$prop = lcfirst($name);
|
||||||
|
|
||||||
return $this->{$prop};
|
return $this->{$prop};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -507,7 +502,10 @@ class ResolutionTest extends TestCase
|
|||||||
$this->assertSame($eager->resolveType('PostStoryMutation'), $lazy->resolveType('PostStoryMutation'));
|
$this->assertSame($eager->resolveType('PostStoryMutation'), $lazy->resolveType('PostStoryMutation'));
|
||||||
$this->assertSame($eager->resolveType('PostStoryMutationInput'), $lazy->resolveType('PostStoryMutationInput'));
|
$this->assertSame($eager->resolveType('PostStoryMutationInput'), $lazy->resolveType('PostStoryMutationInput'));
|
||||||
$this->assertSame($eager->resolveType('PostCommentMutation'), $lazy->resolveType('PostCommentMutation'));
|
$this->assertSame($eager->resolveType('PostCommentMutation'), $lazy->resolveType('PostCommentMutation'));
|
||||||
$this->assertSame($eager->resolveType('PostCommentMutationInput'), $lazy->resolveType('PostCommentMutationInput'));
|
$this->assertSame(
|
||||||
|
$eager->resolveType('PostCommentMutationInput'),
|
||||||
|
$lazy->resolveType('PostCommentMutationInput')
|
||||||
|
);
|
||||||
$this->assertSame(13, $called);
|
$this->assertSame(13, $called);
|
||||||
|
|
||||||
$this->assertEquals($eager->resolvePossibleTypes($this->content), $lazy->resolvePossibleTypes($this->content));
|
$this->assertEquals($eager->resolvePossibleTypes($this->content), $lazy->resolvePossibleTypes($this->content));
|
||||||
@ -527,25 +525,29 @@ class ResolutionTest extends TestCase
|
|||||||
$this->assertEquals($eager->resolvePossibleTypes($this->mention), $lazy->resolvePossibleTypes($this->mention));
|
$this->assertEquals($eager->resolvePossibleTypes($this->mention), $lazy->resolvePossibleTypes($this->mention));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createLazy(){
|
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 = [
|
$descriptor = [
|
||||||
'version' => '1.0',
|
'version' => '1.0',
|
||||||
'typeMap' => [
|
'typeMap' => [
|
||||||
'null' => 1,
|
'null' => 1,
|
||||||
'int' => 1
|
'int' => 1,
|
||||||
],
|
],
|
||||||
'possibleTypeMap' => [
|
'possibleTypeMap' => [
|
||||||
'a' => [
|
'a' => ['null' => 1],
|
||||||
'null' => 1,
|
'b' => ['int' => 1],
|
||||||
],
|
],
|
||||||
'b' => [
|
|
||||||
'int' => 1
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$invalidTypeLoader = function($name) {
|
$invalidTypeLoader = function ($name) {
|
||||||
switch ($name) {
|
switch ($name) {
|
||||||
case 'null':
|
case 'null':
|
||||||
return null;
|
return null;
|
||||||
@ -561,14 +563,6 @@ class ResolutionTest extends TestCase
|
|||||||
return $lazy;
|
return $lazy;
|
||||||
}
|
}
|
||||||
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLazyThrowsOnInvalidLoadedPossibleType() : void
|
public function testLazyThrowsOnInvalidLoadedPossibleType() : void
|
||||||
{
|
{
|
||||||
$tmp = new InterfaceType(['name' => 'a', 'fields' => []]);
|
$tmp = new InterfaceType(['name' => 'a', 'fields' => []]);
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Tests\Type;
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
use GraphQL\GraphQL;
|
use GraphQL\GraphQL;
|
||||||
use GraphQL\Type\Schema;
|
|
||||||
use GraphQL\Type\Definition\ObjectType;
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
use GraphQL\Type\Definition\ResolveInfo;
|
use GraphQL\Type\Definition\ResolveInfo;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
|
use GraphQL\Type\Schema;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class ResolveInfoTest extends TestCase
|
class ResolveInfoTest extends TestCase
|
||||||
@ -17,22 +20,25 @@ class ResolveInfoTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'url' => ['type' => Type::string()],
|
'url' => ['type' => Type::string()],
|
||||||
'width' => ['type' => Type::int()],
|
'width' => ['type' => Type::int()],
|
||||||
'height' => ['type' => Type::int()]
|
'height' => ['type' => Type::int()],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$article = null;
|
$article = null;
|
||||||
|
|
||||||
$author = new ObjectType([
|
$author = new ObjectType([
|
||||||
'name' => 'Author',
|
'name' => 'Author',
|
||||||
'fields' => function() use ($image, &$article) {
|
'fields' => function () use ($image, &$article) {
|
||||||
return [
|
return [
|
||||||
'id' => ['type' => Type::string()],
|
'id' => ['type' => Type::string()],
|
||||||
'name' => ['type' => Type::string()],
|
'name' => ['type' => Type::string()],
|
||||||
'pic' => [ 'type' => $image, 'args' => [
|
'pic' => [
|
||||||
|
'type' => $image,
|
||||||
|
'args' => [
|
||||||
'width' => ['type' => Type::int()],
|
'width' => ['type' => Type::int()],
|
||||||
'height' => ['type' => Type::int()]
|
'height' => ['type' => Type::int()],
|
||||||
]],
|
],
|
||||||
|
],
|
||||||
'recentArticle' => ['type' => $article],
|
'recentArticle' => ['type' => $article],
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
@ -42,8 +48,8 @@ class ResolveInfoTest extends TestCase
|
|||||||
'name' => 'Reply',
|
'name' => 'Reply',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'author' => ['type' => $author],
|
'author' => ['type' => $author],
|
||||||
'body' => ['type' => Type::string()]
|
'body' => ['type' => Type::string()],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$article = new ObjectType([
|
$article = new ObjectType([
|
||||||
@ -55,8 +61,8 @@ class ResolveInfoTest extends TestCase
|
|||||||
'title' => ['type' => Type::string()],
|
'title' => ['type' => Type::string()],
|
||||||
'body' => ['type' => Type::string()],
|
'body' => ['type' => Type::string()],
|
||||||
'image' => ['type' => $image],
|
'image' => ['type' => $image],
|
||||||
'replies' => ['type' => Type::listOf($reply)]
|
'replies' => ['type' => Type::listOf($reply)],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$doc = '
|
$doc = '
|
||||||
@ -102,20 +108,20 @@ class ResolveInfoTest extends TestCase
|
|||||||
$expectedDefaultSelection = [
|
$expectedDefaultSelection = [
|
||||||
'author' => true,
|
'author' => true,
|
||||||
'image' => true,
|
'image' => true,
|
||||||
'replies' => true
|
'replies' => true,
|
||||||
];
|
];
|
||||||
$expectedDeepSelection = [
|
$expectedDeepSelection = [
|
||||||
'author' => [
|
'author' => [
|
||||||
'name' => true,
|
'name' => true,
|
||||||
'pic' => [
|
'pic' => [
|
||||||
'url' => true,
|
'url' => true,
|
||||||
'width' => true
|
'width' => true,
|
||||||
]
|
],
|
||||||
],
|
],
|
||||||
'image' => [
|
'image' => [
|
||||||
'width' => true,
|
'width' => true,
|
||||||
'height' => true,
|
'height' => true,
|
||||||
'url' => true
|
'url' => true,
|
||||||
],
|
],
|
||||||
'replies' => [
|
'replies' => [
|
||||||
'body' => true,
|
'body' => true,
|
||||||
@ -125,15 +131,15 @@ class ResolveInfoTest extends TestCase
|
|||||||
'pic' => [
|
'pic' => [
|
||||||
'url' => true,
|
'url' => true,
|
||||||
'width' => true,
|
'width' => true,
|
||||||
'height' => true
|
'height' => true,
|
||||||
],
|
],
|
||||||
'recentArticle' => [
|
'recentArticle' => [
|
||||||
'id' => true,
|
'id' => true,
|
||||||
'title' => true,
|
'title' => true,
|
||||||
'body' => true
|
'body' => true,
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
$hasCalled = false;
|
$hasCalled = false;
|
||||||
@ -145,14 +151,25 @@ class ResolveInfoTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'article' => [
|
'article' => [
|
||||||
'type' => $article,
|
'type' => $article,
|
||||||
'resolve' => function($value, $args, $context, ResolveInfo $info) use (&$hasCalled, &$actualDefaultSelection, &$actualDeepSelection) {
|
'resolve' => function (
|
||||||
|
$value,
|
||||||
|
$args,
|
||||||
|
$context,
|
||||||
|
ResolveInfo $info
|
||||||
|
) use (
|
||||||
|
&$hasCalled,
|
||||||
|
&
|
||||||
|
$actualDefaultSelection,
|
||||||
|
&$actualDeepSelection
|
||||||
|
) {
|
||||||
$hasCalled = true;
|
$hasCalled = true;
|
||||||
$actualDefaultSelection = $info->getFieldSelection();
|
$actualDefaultSelection = $info->getFieldSelection();
|
||||||
$actualDeepSelection = $info->getFieldSelection(5);
|
$actualDeepSelection = $info->getFieldSelection(5);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema(['query' => $blogQuery]);
|
$schema = new Schema(['query' => $blogQuery]);
|
||||||
@ -171,22 +188,25 @@ class ResolveInfoTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'url' => ['type' => Type::string()],
|
'url' => ['type' => Type::string()],
|
||||||
'width' => ['type' => Type::int()],
|
'width' => ['type' => Type::int()],
|
||||||
'height' => ['type' => Type::int()]
|
'height' => ['type' => Type::int()],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$article = null;
|
$article = null;
|
||||||
|
|
||||||
$author = new ObjectType([
|
$author = new ObjectType([
|
||||||
'name' => 'Author',
|
'name' => 'Author',
|
||||||
'fields' => function() use ($image, &$article) {
|
'fields' => function () use ($image, &$article) {
|
||||||
return [
|
return [
|
||||||
'id' => ['type' => Type::string()],
|
'id' => ['type' => Type::string()],
|
||||||
'name' => ['type' => Type::string()],
|
'name' => ['type' => Type::string()],
|
||||||
'pic' => [ 'type' => $image, 'args' => [
|
'pic' => [
|
||||||
|
'type' => $image,
|
||||||
|
'args' => [
|
||||||
'width' => ['type' => Type::int()],
|
'width' => ['type' => Type::int()],
|
||||||
'height' => ['type' => Type::int()]
|
'height' => ['type' => Type::int()],
|
||||||
]],
|
],
|
||||||
|
],
|
||||||
'recentArticle' => ['type' => $article],
|
'recentArticle' => ['type' => $article],
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
@ -196,8 +216,8 @@ class ResolveInfoTest extends TestCase
|
|||||||
'name' => 'Reply',
|
'name' => 'Reply',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'author' => ['type' => $author],
|
'author' => ['type' => $author],
|
||||||
'body' => ['type' => Type::string()]
|
'body' => ['type' => Type::string()],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$article = new ObjectType([
|
$article = new ObjectType([
|
||||||
@ -209,8 +229,8 @@ class ResolveInfoTest extends TestCase
|
|||||||
'title' => ['type' => Type::string()],
|
'title' => ['type' => Type::string()],
|
||||||
'body' => ['type' => Type::string()],
|
'body' => ['type' => Type::string()],
|
||||||
'image' => ['type' => $image],
|
'image' => ['type' => $image],
|
||||||
'replies' => ['type' => Type::listOf($reply)]
|
'replies' => ['type' => Type::listOf($reply)],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$doc = '
|
$doc = '
|
||||||
@ -268,13 +288,13 @@ class ResolveInfoTest extends TestCase
|
|||||||
'name' => true,
|
'name' => true,
|
||||||
'pic' => [
|
'pic' => [
|
||||||
'url' => true,
|
'url' => true,
|
||||||
'width' => true
|
'width' => true,
|
||||||
]
|
],
|
||||||
],
|
],
|
||||||
'image' => [
|
'image' => [
|
||||||
'width' => true,
|
'width' => true,
|
||||||
'height' => true,
|
'height' => true,
|
||||||
'url' => true
|
'url' => true,
|
||||||
],
|
],
|
||||||
'replies' => [
|
'replies' => [
|
||||||
'body' => true, //this would be missing if not for the fix https://github.com/webonyx/graphql-php/pull/98
|
'body' => true, //this would be missing if not for the fix https://github.com/webonyx/graphql-php/pull/98
|
||||||
@ -284,15 +304,15 @@ class ResolveInfoTest extends TestCase
|
|||||||
'pic' => [
|
'pic' => [
|
||||||
'url' => true,
|
'url' => true,
|
||||||
'width' => true,
|
'width' => true,
|
||||||
'height' => true
|
'height' => true,
|
||||||
],
|
],
|
||||||
'recentArticle' => [
|
'recentArticle' => [
|
||||||
'id' => true,
|
'id' => true,
|
||||||
'title' => true,
|
'title' => true,
|
||||||
'body' => true
|
'body' => true,
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
$hasCalled = false;
|
$hasCalled = false;
|
||||||
@ -304,13 +324,23 @@ class ResolveInfoTest extends TestCase
|
|||||||
'fields' => [
|
'fields' => [
|
||||||
'article' => [
|
'article' => [
|
||||||
'type' => $article,
|
'type' => $article,
|
||||||
'resolve' => function($value, $args, $context, ResolveInfo $info) use (&$hasCalled, &$actualDeepSelection) {
|
'resolve' => function (
|
||||||
|
$value,
|
||||||
|
$args,
|
||||||
|
$context,
|
||||||
|
ResolveInfo $info
|
||||||
|
) use (
|
||||||
|
&$hasCalled,
|
||||||
|
&
|
||||||
|
$actualDeepSelection
|
||||||
|
) {
|
||||||
$hasCalled = true;
|
$hasCalled = true;
|
||||||
$actualDeepSelection = $info->getFieldSelection(5);
|
$actualDeepSelection = $info->getFieldSelection(5);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema = new Schema(['query' => $blogQuery]);
|
$schema = new Schema(['query' => $blogQuery]);
|
||||||
@ -320,6 +350,4 @@ class ResolveInfoTest extends TestCase
|
|||||||
$this->assertEquals(['data' => ['article' => null]], $result);
|
$this->assertEquals(['data' => ['article' => null]], $result);
|
||||||
$this->assertEquals($expectedDeepSelection, $actualDeepSelection);
|
$this->assertEquals($expectedDeepSelection, $actualDeepSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Tests\Type;
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
@ -8,7 +11,6 @@ use PHPUnit\Framework\TestCase;
|
|||||||
class ScalarSerializationTest extends TestCase
|
class ScalarSerializationTest extends TestCase
|
||||||
{
|
{
|
||||||
// Type System: Scalar coercion
|
// Type System: Scalar coercion
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see it('serializes output int')
|
* @see it('serializes output int')
|
||||||
*/
|
*/
|
||||||
@ -42,7 +44,6 @@ class ScalarSerializationTest extends TestCase
|
|||||||
$this->expectException(Error::class);
|
$this->expectException(Error::class);
|
||||||
$this->expectExceptionMessage('Int cannot represent non-integer value: 1.1');
|
$this->expectExceptionMessage('Int cannot represent non-integer value: 1.1');
|
||||||
$intType->serialize(1.1);
|
$intType->serialize(1.1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSerializesOutputIntCannotRepresentNegativeFloat() : void
|
public function testSerializesOutputIntCannotRepresentNegativeFloat() : void
|
||||||
@ -51,7 +52,6 @@ class ScalarSerializationTest extends TestCase
|
|||||||
$this->expectException(Error::class);
|
$this->expectException(Error::class);
|
||||||
$this->expectExceptionMessage('Int cannot represent non-integer value: -1.1');
|
$this->expectExceptionMessage('Int cannot represent non-integer value: -1.1');
|
||||||
$intType->serialize(-1.1);
|
$intType->serialize(-1.1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSerializesOutputIntCannotRepresentNumericString() : void
|
public function testSerializesOutputIntCannotRepresentNumericString() : void
|
||||||
@ -60,7 +60,6 @@ class ScalarSerializationTest extends TestCase
|
|||||||
$this->expectException(Error::class);
|
$this->expectException(Error::class);
|
||||||
$this->expectExceptionMessage('Int cannot represent non 32-bit signed integer value: Int cannot represent non-integer value: "-1.1"');
|
$this->expectExceptionMessage('Int cannot represent non 32-bit signed integer value: Int cannot represent non-integer value: "-1.1"');
|
||||||
$intType->serialize('Int cannot represent non-integer value: "-1.1"');
|
$intType->serialize('Int cannot represent non-integer value: "-1.1"');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSerializesOutputIntCannotRepresentBiggerThan32Bits() : void
|
public function testSerializesOutputIntCannotRepresentBiggerThan32Bits() : void
|
||||||
@ -71,7 +70,6 @@ class ScalarSerializationTest extends TestCase
|
|||||||
$this->expectException(Error::class);
|
$this->expectException(Error::class);
|
||||||
$this->expectExceptionMessage('Int cannot represent non 32-bit signed integer value: 9876504321');
|
$this->expectExceptionMessage('Int cannot represent non 32-bit signed integer value: 9876504321');
|
||||||
$intType->serialize(9876504321);
|
$intType->serialize(9876504321);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSerializesOutputIntCannotRepresentLowerThan32Bits() : void
|
public function testSerializesOutputIntCannotRepresentLowerThan32Bits() : void
|
||||||
@ -104,7 +102,6 @@ class ScalarSerializationTest extends TestCase
|
|||||||
$this->expectException(Error::class);
|
$this->expectException(Error::class);
|
||||||
$this->expectExceptionMessage('Int cannot represent non 32-bit signed integer value: one');
|
$this->expectExceptionMessage('Int cannot represent non 32-bit signed integer value: one');
|
||||||
$intType->serialize('one');
|
$intType->serialize('one');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSerializesOutputIntCannotRepresentEmptyString() : void
|
public function testSerializesOutputIntCannotRepresentEmptyString() : void
|
||||||
@ -196,7 +193,6 @@ class ScalarSerializationTest extends TestCase
|
|||||||
$this->assertSame(false, $boolType->serialize(0));
|
$this->assertSame(false, $boolType->serialize(0));
|
||||||
$this->assertSame(true, $boolType->serialize(true));
|
$this->assertSame(true, $boolType->serialize(true));
|
||||||
$this->assertSame(false, $boolType->serialize(false));
|
$this->assertSame(false, $boolType->serialize(false));
|
||||||
|
|
||||||
// TODO: how should it behave on '0'?
|
// TODO: how should it behave on '0'?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Tests\Type;
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
@ -12,14 +15,19 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class SchemaTest extends TestCase
|
class SchemaTest extends TestCase
|
||||||
{
|
{
|
||||||
|
/** @var InterfaceType */
|
||||||
private $interfaceType;
|
private $interfaceType;
|
||||||
|
|
||||||
|
/** @var ObjectType */
|
||||||
private $implementingType;
|
private $implementingType;
|
||||||
|
|
||||||
|
/** @var InputObjectType */
|
||||||
private $directiveInputType;
|
private $directiveInputType;
|
||||||
|
|
||||||
|
/** @var InputObjectType */
|
||||||
private $wrappedDirectiveInputType;
|
private $wrappedDirectiveInputType;
|
||||||
|
|
||||||
|
/** @var Directive */
|
||||||
private $directive;
|
private $directive;
|
||||||
|
|
||||||
/** @var Schema */
|
/** @var Schema */
|
||||||
@ -35,9 +43,14 @@ class SchemaTest extends TestCase
|
|||||||
$this->implementingType = new ObjectType([
|
$this->implementingType = new ObjectType([
|
||||||
'name' => 'Object',
|
'name' => 'Object',
|
||||||
'interfaces' => [$this->interfaceType],
|
'interfaces' => [$this->interfaceType],
|
||||||
'fields' => ['fieldName' => ['type' => Type::string(), 'resolve' => function () {
|
'fields' => [
|
||||||
|
'fieldName' => [
|
||||||
|
'type' => Type::string(),
|
||||||
|
'resolve' => function () {
|
||||||
return '';
|
return '';
|
||||||
}]],
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->directiveInputType = new InputObjectType([
|
$this->directiveInputType = new InputObjectType([
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace GraphQL\Tests\Type;
|
|
||||||
|
|
||||||
use GraphQL\Type\Definition\ObjectType;
|
|
||||||
use GraphQL\Type\Definition\Type;
|
|
||||||
|
|
||||||
class MyCustomType extends ObjectType
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$config = [
|
|
||||||
'fields' => [
|
|
||||||
'a' => Type::string()
|
|
||||||
]
|
|
||||||
];
|
|
||||||
parent::__construct($config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: named OtherCustom vs OtherCustomType intentionally
|
|
||||||
class OtherCustom extends ObjectType
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$config = [
|
|
||||||
'fields' => [
|
|
||||||
'b' => Type::string()
|
|
||||||
]
|
|
||||||
];
|
|
||||||
parent::__construct($config);
|
|
||||||
}
|
|
||||||
}
|
|
21
tests/Type/TestClasses/MyCustomType.php
Normal file
21
tests/Type/TestClasses/MyCustomType.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace GraphQL\Tests\Type\TestClasses;
|
||||||
|
|
||||||
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
|
use GraphQL\Type\Definition\Type;
|
||||||
|
|
||||||
|
class MyCustomType extends ObjectType
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$config = [
|
||||||
|
'fields' => [
|
||||||
|
'a' => Type::string(),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
parent::__construct($config);
|
||||||
|
}
|
||||||
|
}
|
24
tests/Type/TestClasses/OtherCustom.php
Normal file
24
tests/Type/TestClasses/OtherCustom.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace GraphQL\Tests\Type\TestClasses;
|
||||||
|
|
||||||
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
|
use GraphQL\Type\Definition\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: named OtherCustom vs OtherCustomType intentionally
|
||||||
|
*/
|
||||||
|
class OtherCustom extends ObjectType
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$config = [
|
||||||
|
'fields' => [
|
||||||
|
'b' => Type::string(),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
parent::__construct($config);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace GraphQL\Tests\Type;
|
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
use GraphQL\Error\InvariantViolation;
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Type\Definition\InputObjectType;
|
use GraphQL\Type\Definition\InputObjectType;
|
||||||
@ -9,52 +11,35 @@ use GraphQL\Type\Definition\ObjectType;
|
|||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Schema;
|
use GraphQL\Type\Schema;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use function lcfirst;
|
||||||
|
|
||||||
class TypeLoaderTest extends TestCase
|
class TypeLoaderTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $query;
|
private $query;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $mutation;
|
private $mutation;
|
||||||
|
|
||||||
/**
|
/** @var InterfaceType */
|
||||||
* @var InterfaceType
|
|
||||||
*/
|
|
||||||
private $node;
|
private $node;
|
||||||
|
|
||||||
/**
|
/** @var InterfaceType */
|
||||||
* @var InterfaceType
|
|
||||||
*/
|
|
||||||
private $content;
|
private $content;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $blogStory;
|
private $blogStory;
|
||||||
|
|
||||||
/**
|
/** @var ObjectType */
|
||||||
* @var ObjectType
|
|
||||||
*/
|
|
||||||
private $postStoryMutation;
|
private $postStoryMutation;
|
||||||
|
|
||||||
/**
|
/** @var InputObjectType */
|
||||||
* @var InputObjectType
|
|
||||||
*/
|
|
||||||
private $postStoryMutationInput;
|
private $postStoryMutationInput;
|
||||||
|
|
||||||
/**
|
/** @var callable */
|
||||||
* @var callable
|
|
||||||
*/
|
|
||||||
private $typeLoader;
|
private $typeLoader;
|
||||||
|
|
||||||
/**
|
/** @var string[] */
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $calls;
|
private $calls;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
@ -63,35 +48,40 @@ class TypeLoaderTest extends TestCase
|
|||||||
|
|
||||||
$this->node = new InterfaceType([
|
$this->node = new InterfaceType([
|
||||||
'name' => 'Node',
|
'name' => 'Node',
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
$this->calls[] = 'Node.fields';
|
$this->calls[] = 'Node.fields';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => Type::string()
|
'id' => Type::string(),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
'resolveType' => function() {}
|
'resolveType' => function () {
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->content = new InterfaceType([
|
$this->content = new InterfaceType([
|
||||||
'name' => 'Content',
|
'name' => 'Content',
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
$this->calls[] = 'Content.fields';
|
$this->calls[] = 'Content.fields';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'title' => Type::string(),
|
'title' => Type::string(),
|
||||||
'body' => Type::string(),
|
'body' => Type::string(),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
'resolveType' => function() {}
|
'resolveType' => function () {
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->blogStory = new ObjectType([
|
$this->blogStory = new ObjectType([
|
||||||
'name' => 'BlogStory',
|
'name' => 'BlogStory',
|
||||||
'interfaces' => [
|
'interfaces' => [
|
||||||
$this->node,
|
$this->node,
|
||||||
$this->content
|
$this->content,
|
||||||
],
|
],
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
$this->calls[] = 'BlogStory.fields';
|
$this->calls[] = 'BlogStory.fields';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
$this->node->getField('id'),
|
$this->node->getField('id'),
|
||||||
$this->content->getField('title'),
|
$this->content->getField('title'),
|
||||||
@ -102,36 +92,38 @@ class TypeLoaderTest extends TestCase
|
|||||||
|
|
||||||
$this->query = new ObjectType([
|
$this->query = new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
$this->calls[] = 'Query.fields';
|
$this->calls[] = 'Query.fields';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'latestContent' => $this->content,
|
'latestContent' => $this->content,
|
||||||
'node' => $this->node,
|
'node' => $this->node,
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->mutation = new ObjectType([
|
$this->mutation = new ObjectType([
|
||||||
'name' => 'Mutation',
|
'name' => 'Mutation',
|
||||||
'fields' => function() {
|
'fields' => function () {
|
||||||
$this->calls[] = 'Mutation.fields';
|
$this->calls[] = 'Mutation.fields';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'postStory' => [
|
'postStory' => [
|
||||||
'type' => $this->postStoryMutation,
|
'type' => $this->postStoryMutation,
|
||||||
'args' => [
|
'args' => [
|
||||||
'input' => Type::nonNull($this->postStoryMutationInput),
|
'input' => Type::nonNull($this->postStoryMutationInput),
|
||||||
'clientRequestId' => Type::string()
|
'clientRequestId' => Type::string(),
|
||||||
]
|
],
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->postStoryMutation = new ObjectType([
|
$this->postStoryMutation = new ObjectType([
|
||||||
'name' => 'PostStoryMutation',
|
'name' => 'PostStoryMutation',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'story' => $this->blogStory
|
'story' => $this->blogStory,
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->postStoryMutationInput = new InputObjectType([
|
$this->postStoryMutationInput = new InputObjectType([
|
||||||
@ -140,14 +132,15 @@ class TypeLoaderTest extends TestCase
|
|||||||
'title' => Type::string(),
|
'title' => Type::string(),
|
||||||
'body' => Type::string(),
|
'body' => Type::string(),
|
||||||
'author' => Type::id(),
|
'author' => Type::id(),
|
||||||
'category' => Type::id()
|
'category' => Type::id(),
|
||||||
]
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->typeLoader = function($name) {
|
$this->typeLoader = function ($name) {
|
||||||
$this->calls[] = $name;
|
$this->calls[] = $name;
|
||||||
$prop = lcfirst($name);
|
$prop = lcfirst($name);
|
||||||
return isset($this->{$prop}) ? $this->{$prop} : null;
|
|
||||||
|
return $this->{$prop} ?? null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,9 +150,10 @@ class TypeLoaderTest extends TestCase
|
|||||||
new Schema([
|
new Schema([
|
||||||
'query' => new ObjectType([
|
'query' => new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => ['a' => Type::string()]
|
'fields' => ['a' => Type::string()],
|
||||||
]),
|
]),
|
||||||
'typeLoader' => function() {}
|
'typeLoader' => function () {
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,9 +165,9 @@ class TypeLoaderTest extends TestCase
|
|||||||
new Schema([
|
new Schema([
|
||||||
'query' => new ObjectType([
|
'query' => new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => ['a' => Type::string()]
|
'fields' => ['a' => Type::string()],
|
||||||
]),
|
]),
|
||||||
'typeLoader' => []
|
'typeLoader' => [],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +176,7 @@ class TypeLoaderTest extends TestCase
|
|||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'mutation' => $this->mutation,
|
'mutation' => $this->mutation,
|
||||||
'types' => [$this->blogStory]
|
'types' => [$this->blogStory],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$expected = [
|
$expected = [
|
||||||
@ -220,7 +214,7 @@ class TypeLoaderTest extends TestCase
|
|||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'mutation' => $this->mutation,
|
'mutation' => $this->mutation,
|
||||||
'typeLoader' => $this->typeLoader
|
'typeLoader' => $this->typeLoader,
|
||||||
]);
|
]);
|
||||||
$this->assertEquals([], $this->calls);
|
$this->assertEquals([], $this->calls);
|
||||||
|
|
||||||
@ -245,7 +239,7 @@ class TypeLoaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'typeLoader' => $this->typeLoader
|
'typeLoader' => $this->typeLoader,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$schema->getType('Node');
|
$schema->getType('Node');
|
||||||
@ -259,7 +253,8 @@ class TypeLoaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'typeLoader' => function() {}
|
'typeLoader' => function () {
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->expectException(InvariantViolation::class);
|
$this->expectException(InvariantViolation::class);
|
||||||
@ -272,9 +267,9 @@ class TypeLoaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'typeLoader' => function() {
|
'typeLoader' => function () {
|
||||||
return new \stdClass();
|
return new \stdClass();
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->expectException(InvariantViolation::class);
|
$this->expectException(InvariantViolation::class);
|
||||||
@ -287,9 +282,9 @@ class TypeLoaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'typeLoader' => function() {
|
'typeLoader' => function () {
|
||||||
return $this->content;
|
return $this->content;
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->expectException(InvariantViolation::class);
|
$this->expectException(InvariantViolation::class);
|
||||||
@ -302,9 +297,9 @@ class TypeLoaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'typeLoader' => function() {
|
'typeLoader' => function () {
|
||||||
throw new \Exception("This is the exception we are looking for");
|
throw new \Exception('This is the exception we are looking for');
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->expectException(\Throwable::class);
|
$this->expectException(\Throwable::class);
|
||||||
@ -317,13 +312,13 @@ class TypeLoaderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$withoutLoader = new Schema([
|
$withoutLoader = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'mutation' => $this->mutation
|
'mutation' => $this->mutation,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$withLoader = new Schema([
|
$withLoader = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'mutation' => $this->mutation,
|
'mutation' => $this->mutation,
|
||||||
'typeLoader' => $this->typeLoader
|
'typeLoader' => $this->typeLoader,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertSame($withoutLoader->getQueryType(), $withLoader->getQueryType());
|
$this->assertSame($withoutLoader->getQueryType(), $withLoader->getQueryType());
|
||||||
@ -337,7 +332,7 @@ class TypeLoaderTest extends TestCase
|
|||||||
$schema = new Schema([
|
$schema = new Schema([
|
||||||
'query' => $this->query,
|
'query' => $this->query,
|
||||||
'mutation' => $this->mutation,
|
'mutation' => $this->mutation,
|
||||||
'typeLoader' => $this->typeLoader
|
'typeLoader' => $this->typeLoader,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$type = $schema->getType('ID');
|
$type = $schema->getType('ID');
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user