Merge pull request #347 from simPod/fix-cs-test

Fix CS in tests
This commit is contained in:
Vladimir Razuvaev 2018-09-02 21:30:04 +07:00 committed by GitHub
commit bfff27ef34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 415 additions and 422 deletions

View File

@ -1,62 +1,31 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests; namespace GraphQL\Tests;
use function array_map;
class StarWarsData class StarWarsData
{ {
private static function luke() /**
* Helper function to get a character by ID.
*/
public static function getCharacter($id)
{ {
return [ $humans = self::humans();
'id' => '1000', $droids = self::droids();
'name' => 'Luke Skywalker', if (isset($humans[$id])) {
'friends' => ['1002', '1003', '2000', '2001'], return $humans[$id];
'appearsIn' => [4, 5, 6], }
'homePlanet' => 'Tatooine', if (isset($droids[$id])) {
]; return $droids[$id];
}
return null;
} }
private static function vader() public static function humans()
{
return [
'id' => '1001',
'name' => 'Darth Vader',
'friends' => ['1004'],
'appearsIn' => [4, 5, 6],
'homePlanet' => 'Tatooine',
];
}
private static function han()
{
return [
'id' => '1002',
'name' => 'Han Solo',
'friends' => ['1000', '1003', '2001'],
'appearsIn' => [4, 5, 6],
];
}
private static function leia()
{
return [
'id' => '1003',
'name' => 'Leia Organa',
'friends' => ['1000', '1002', '2000', '2001'],
'appearsIn' => [4, 5, 6],
'homePlanet' => 'Alderaan',
];
}
private static function tarkin()
{
return [
'id' => '1004',
'name' => 'Wilhuff Tarkin',
'friends' => ['1001'],
'appearsIn' => [4],
];
}
static function humans()
{ {
return [ return [
'1000' => self::luke(), '1000' => self::luke(),
@ -67,13 +36,74 @@ class StarWarsData
]; ];
} }
private static function luke()
{
return [
'id' => '1000',
'name' => 'Luke Skywalker',
'friends' => ['1002', '1003', '2000', '2001'],
'appearsIn' => [4, 5, 6],
'homePlanet' => 'Tatooine',
];
}
private static function vader()
{
return [
'id' => '1001',
'name' => 'Darth Vader',
'friends' => ['1004'],
'appearsIn' => [4, 5, 6],
'homePlanet' => 'Tatooine',
];
}
private static function han()
{
return [
'id' => '1002',
'name' => 'Han Solo',
'friends' => ['1000', '1003', '2001'],
'appearsIn' => [4, 5, 6],
];
}
private static function leia()
{
return [
'id' => '1003',
'name' => 'Leia Organa',
'friends' => ['1000', '1002', '2000', '2001'],
'appearsIn' => [4, 5, 6],
'homePlanet' => 'Alderaan',
];
}
private static function tarkin()
{
return [
'id' => '1004',
'name' => 'Wilhuff Tarkin',
'friends' => ['1001'],
'appearsIn' => [4],
];
}
public static function droids()
{
return [
'2000' => self::threepio(),
'2001' => self::artoo(),
];
}
private static function threepio() private static function threepio()
{ {
return [ return [
'id' => '2000', 'id' => '2000',
'name' => 'C-3PO', 'name' => 'C-3PO',
'friends' => ['1000', '1002', '1003', '2001'], 'friends' => ['1000', '1002', '1003', '2001'],
'appearsIn' => [4, 5, 6], 'appearsIn' => [4, 5, 6],
'primaryFunction' => 'Protocol', 'primaryFunction' => 'Protocol',
]; ];
} }
@ -82,60 +112,37 @@ class StarWarsData
* We export artoo directly because the schema returns him * We export artoo directly because the schema returns him
* from a root field, and hence needs to reference him. * from a root field, and hence needs to reference him.
*/ */
static function artoo() private static function artoo()
{ {
return [ return [
'id' => '2001', 'id' => '2001',
'name' => 'R2-D2', 'name' => 'R2-D2',
'friends' => ['1000', '1002', '1003'], 'friends' => ['1000', '1002', '1003'],
'appearsIn' => [4, 5, 6], 'appearsIn' => [4, 5, 6],
'primaryFunction' => 'Astromech', 'primaryFunction' => 'Astromech',
]; ];
} }
static function droids()
{
return [
'2000' => self::threepio(),
'2001' => self::artoo(),
];
}
/**
* Helper function to get a character by ID.
*/
static function getCharacter($id)
{
$humans = self::humans();
$droids = self::droids();
if (isset($humans[$id])) {
return $humans[$id];
}
if (isset($droids[$id])) {
return $droids[$id];
}
return null;
}
/** /**
* Allows us to query for a character's friends. * Allows us to query for a character's friends.
*/ */
static function getFriends($character) public static function getFriends($character)
{ {
return array_map([__CLASS__, 'getCharacter'], $character['friends']); return array_map([__CLASS__, 'getCharacter'], $character['friends']);
} }
/** /**
* @param $episode * @param int $episode
* @return array * @return mixed[]
*/ */
static function getHero($episode) public static function getHero($episode)
{ {
if ($episode === 5) { if ($episode === 5) {
// Luke is the hero of Episode V. // Luke is the hero of Episode V.
return self::luke(); return self::luke();
} }
// Artoo is the hero otherwise. // Artoo is the hero otherwise.
return self::artoo(); return self::artoo();
} }
@ -144,19 +151,21 @@ class StarWarsData
* @param $id * @param $id
* @return mixed|null * @return mixed|null
*/ */
static function getHuman($id) public static function getHuman($id)
{ {
$humans = self::humans(); $humans = self::humans();
return isset($humans[$id]) ? $humans[$id] : null;
return $humans[$id] ?? null;
} }
/** /**
* @param $id * @param $id
* @return mixed|null * @return mixed|null
*/ */
static function getDroid($id) public static function getDroid($id)
{ {
$droids = self::droids(); $droids = self::droids();
return isset($droids[$id]) ? $droids[$id] : null;
return $droids[$id] ?? null;
} }
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests; namespace GraphQL\Tests;
use GraphQL\GraphQL; use GraphQL\GraphQL;
@ -14,7 +17,7 @@ class StarWarsIntrospectionTest extends TestCase
*/ */
public function testAllowsQueryingTheSchemaForTypes() : void public function testAllowsQueryingTheSchemaForTypes() : void
{ {
$query = ' $query = '
query IntrospectionTypeQuery { query IntrospectionTypeQuery {
__schema { __schema {
types { types {
@ -44,18 +47,26 @@ class StarWarsIntrospectionTest extends TestCase
['name' => '__EnumValue'], ['name' => '__EnumValue'],
['name' => '__Directive'], ['name' => '__Directive'],
['name' => '__DirectiveLocation'], ['name' => '__DirectiveLocation'],
] ],
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
/**
* Helper function to test a query and the expected response.
*/
private function assertValidQuery($query, $expected) : void
{
$this->assertEquals(['data' => $expected], GraphQL::executeQuery(StarWarsSchema::build(), $query)->toArray());
}
/** /**
* @see it('Allows querying the schema for query type') * @see it('Allows querying the schema for query type')
*/ */
public function testAllowsQueryingTheSchemaForQueryType() : void public function testAllowsQueryingTheSchemaForQueryType() : void
{ {
$query = ' $query = '
query IntrospectionQueryTypeQuery { query IntrospectionQueryTypeQuery {
__schema { __schema {
queryType { queryType {
@ -66,10 +77,8 @@ class StarWarsIntrospectionTest extends TestCase
'; ';
$expected = [ $expected = [
'__schema' => [ '__schema' => [
'queryType' => [ 'queryType' => ['name' => 'Query'],
'name' => 'Query' ],
],
]
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -79,7 +88,7 @@ class StarWarsIntrospectionTest extends TestCase
*/ */
public function testAllowsQueryingTheSchemaForASpecificType() : void public function testAllowsQueryingTheSchemaForASpecificType() : void
{ {
$query = ' $query = '
query IntrospectionDroidTypeQuery { query IntrospectionDroidTypeQuery {
__type(name: "Droid") { __type(name: "Droid") {
name name
@ -87,9 +96,7 @@ class StarWarsIntrospectionTest extends TestCase
} }
'; ';
$expected = [ $expected = [
'__type' => [ '__type' => ['name' => 'Droid'],
'name' => 'Droid'
]
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -99,7 +106,7 @@ class StarWarsIntrospectionTest extends TestCase
*/ */
public function testAllowsQueryingForAnObjectKind() : void public function testAllowsQueryingForAnObjectKind() : void
{ {
$query = ' $query = '
query IntrospectionDroidKindQuery { query IntrospectionDroidKindQuery {
__type(name: "Droid") { __type(name: "Droid") {
name name
@ -110,8 +117,8 @@ class StarWarsIntrospectionTest extends TestCase
$expected = [ $expected = [
'__type' => [ '__type' => [
'name' => 'Droid', 'name' => 'Droid',
'kind' => 'OBJECT' 'kind' => 'OBJECT',
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -121,7 +128,7 @@ class StarWarsIntrospectionTest extends TestCase
*/ */
public function testAllowsQueryingForInterfaceKind() : void public function testAllowsQueryingForInterfaceKind() : void
{ {
$query = ' $query = '
query IntrospectionCharacterKindQuery { query IntrospectionCharacterKindQuery {
__type(name: "Character") { __type(name: "Character") {
name name
@ -132,8 +139,8 @@ class StarWarsIntrospectionTest extends TestCase
$expected = [ $expected = [
'__type' => [ '__type' => [
'name' => 'Character', 'name' => 'Character',
'kind' => 'INTERFACE' 'kind' => 'INTERFACE',
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -143,7 +150,7 @@ class StarWarsIntrospectionTest extends TestCase
*/ */
public function testAllowsQueryingForObjectFields() : void public function testAllowsQueryingForObjectFields() : void
{ {
$query = ' $query = '
query IntrospectionDroidFieldsQuery { query IntrospectionDroidFieldsQuery {
__type(name: "Droid") { __type(name: "Droid") {
name name
@ -159,52 +166,52 @@ class StarWarsIntrospectionTest extends TestCase
'; ';
$expected = [ $expected = [
'__type' => [ '__type' => [
'name' => 'Droid', 'name' => 'Droid',
'fields' => [ 'fields' => [
[ [
'name' => 'id', 'name' => 'id',
'type' => [ 'type' => [
'name' => null, 'name' => null,
'kind' => 'NON_NULL' 'kind' => 'NON_NULL',
] ],
], ],
[ [
'name' => 'name', 'name' => 'name',
'type' => [ 'type' => [
'name' => 'String', 'name' => 'String',
'kind' => 'SCALAR' 'kind' => 'SCALAR',
] ],
], ],
[ [
'name' => 'friends', 'name' => 'friends',
'type' => [ 'type' => [
'name' => null, 'name' => null,
'kind' => 'LIST' 'kind' => 'LIST',
] ],
], ],
[ [
'name' => 'appearsIn', 'name' => 'appearsIn',
'type' => [ 'type' => [
'name' => null, 'name' => null,
'kind' => 'LIST' 'kind' => 'LIST',
] ],
], ],
[ [
'name' => 'secretBackstory', 'name' => 'secretBackstory',
'type' => [ 'type' => [
'name' => 'String', 'name' => 'String',
'kind' => 'SCALAR' 'kind' => 'SCALAR',
] ],
], ],
[ [
'name' => 'primaryFunction', 'name' => 'primaryFunction',
'type' => [ 'type' => [
'name' => 'String', 'name' => 'String',
'kind' => 'SCALAR' 'kind' => 'SCALAR',
] ],
] ],
] ],
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -214,7 +221,7 @@ class StarWarsIntrospectionTest extends TestCase
*/ */
public function testAllowsQueryingTheSchemaForNestedObjectFields() : void public function testAllowsQueryingTheSchemaForNestedObjectFields() : void
{ {
$query = ' $query = '
query IntrospectionDroidNestedFieldsQuery { query IntrospectionDroidNestedFieldsQuery {
__type(name: "Droid") { __type(name: "Droid") {
name name
@ -234,67 +241,67 @@ class StarWarsIntrospectionTest extends TestCase
'; ';
$expected = [ $expected = [
'__type' => [ '__type' => [
'name' => 'Droid', 'name' => 'Droid',
'fields' => [ 'fields' => [
[ [
'name' => 'id', 'name' => 'id',
'type' => [ 'type' => [
'name' => null, 'name' => null,
'kind' => 'NON_NULL', 'kind' => 'NON_NULL',
'ofType' => [ 'ofType' => [
'name' => 'String', 'name' => 'String',
'kind' => 'SCALAR' 'kind' => 'SCALAR',
] ],
] ],
], ],
[ [
'name' => 'name', 'name' => 'name',
'type' => [ 'type' => [
'name' => 'String', 'name' => 'String',
'kind' => 'SCALAR', 'kind' => 'SCALAR',
'ofType' => null 'ofType' => null,
] ],
], ],
[ [
'name' => 'friends', 'name' => 'friends',
'type' => [ 'type' => [
'name' => null, 'name' => null,
'kind' => 'LIST', 'kind' => 'LIST',
'ofType' => [ 'ofType' => [
'name' => 'Character', 'name' => 'Character',
'kind' => 'INTERFACE' 'kind' => 'INTERFACE',
] ],
] ],
], ],
[ [
'name' => 'appearsIn', 'name' => 'appearsIn',
'type' => [ 'type' => [
'name' => null, 'name' => null,
'kind' => 'LIST', 'kind' => 'LIST',
'ofType' => [ 'ofType' => [
'name' => 'Episode', 'name' => 'Episode',
'kind' => 'ENUM' 'kind' => 'ENUM',
] ],
] ],
], ],
[ [
'name' => 'secretBackstory', 'name' => 'secretBackstory',
'type' => [ 'type' => [
'name' => 'String', 'name' => 'String',
'kind' => 'SCALAR', 'kind' => 'SCALAR',
'ofType' => null 'ofType' => null,
] ],
], ],
[ [
'name' => 'primaryFunction', 'name' => 'primaryFunction',
'type' => [ 'type' => [
'name' => 'String', 'name' => 'String',
'kind' => 'SCALAR', 'kind' => 'SCALAR',
'ofType' => null 'ofType' => null,
] ],
] ],
] ],
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -329,7 +336,7 @@ class StarWarsIntrospectionTest extends TestCase
} }
'; ';
$expected = array( $expected = [
'__schema' => [ '__schema' => [
'queryType' => [ 'queryType' => [
'fields' => [ 'fields' => [
@ -337,13 +344,13 @@ class StarWarsIntrospectionTest extends TestCase
'name' => 'hero', 'name' => 'hero',
'args' => [ 'args' => [
[ [
'defaultValue' => NULL, 'defaultValue' => null,
'description' => 'If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode.', 'description' => 'If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode.',
'name' => 'episode', 'name' => 'episode',
'type' => [ 'type' => [
'kind' => 'ENUM', 'kind' => 'ENUM',
'name' => 'Episode', 'name' => 'Episode',
'ofType' => NULL, 'ofType' => null,
], ],
], ],
], ],
@ -352,17 +359,17 @@ class StarWarsIntrospectionTest extends TestCase
'name' => 'human', 'name' => 'human',
'args' => [ 'args' => [
[ [
'name' => 'id', 'name' => 'id',
'description' => 'id of the human', 'description' => 'id of the human',
'type' => [ 'type' => [
'kind' => 'NON_NULL', 'kind' => 'NON_NULL',
'name' => NULL, 'name' => null,
'ofType' => [ 'ofType' => [
'kind' => 'SCALAR', 'kind' => 'SCALAR',
'name' => 'String', 'name' => 'String',
], ],
], ],
'defaultValue' => NULL, 'defaultValue' => null,
], ],
], ],
], ],
@ -370,25 +377,25 @@ class StarWarsIntrospectionTest extends TestCase
'name' => 'droid', 'name' => 'droid',
'args' => [ 'args' => [
[ [
'name' => 'id', 'name' => 'id',
'description' => 'id of the droid', 'description' => 'id of the droid',
'type' => [ 'type' => [
'kind' => 'NON_NULL', 'kind' => 'NON_NULL',
'name' => NULL, 'name' => null,
'ofType' => 'ofType' =>
[ [
'kind' => 'SCALAR', 'kind' => 'SCALAR',
'name' => 'String', 'name' => 'String',
], ],
], ],
'defaultValue' => NULL, 'defaultValue' => null,
], ],
], ],
], ],
], ],
], ],
], ],
); ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -398,7 +405,7 @@ class StarWarsIntrospectionTest extends TestCase
*/ */
public function testAllowsQueryingTheSchemaForDocumentation() : void public function testAllowsQueryingTheSchemaForDocumentation() : void
{ {
$query = ' $query = '
query IntrospectionDroidDescriptionQuery { query IntrospectionDroidDescriptionQuery {
__type(name: "Droid") { __type(name: "Droid") {
name name
@ -408,18 +415,10 @@ class StarWarsIntrospectionTest extends TestCase
'; ';
$expected = [ $expected = [
'__type' => [ '__type' => [
'name' => 'Droid', 'name' => 'Droid',
'description' => 'A mechanical creature in the Star Wars universe.' 'description' => 'A mechanical creature in the Star Wars universe.',
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
/**
* Helper function to test a query and the expected response.
*/
private function assertValidQuery($query, $expected)
{
$this->assertEquals(['data' => $expected], GraphQL::executeQuery(StarWarsSchema::build(), $query)->toArray());
}
} }

View File

@ -1,21 +1,20 @@
<?php <?php
namespace GraphQL\Tests;
declare(strict_types=1);
namespace GraphQL\Tests;
use GraphQL\GraphQL; use GraphQL\GraphQL;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class StarWarsQueryTest extends TestCase class StarWarsQueryTest extends TestCase
{ {
// Star Wars Query Tests
// Basic Queries
/** /**
* @see it('Correctly identifies R2-D2 as the hero of the Star Wars Saga') * @see it('Correctly identifies R2-D2 as the hero of the Star Wars Saga')
*/ */
public function testCorrectlyIdentifiesR2D2AsTheHeroOfTheStarWarsSaga() : void public function testCorrectlyIdentifiesR2D2AsTheHeroOfTheStarWarsSaga() : void
{ {
$query = ' $query = '
query HeroNameQuery { query HeroNameQuery {
hero { hero {
name name
@ -23,19 +22,30 @@ class StarWarsQueryTest extends TestCase
} }
'; ';
$expected = [ $expected = [
'hero' => [ 'hero' => ['name' => 'R2-D2'],
'name' => 'R2-D2'
]
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
/**
* Helper function to test a query and the expected response.
*/
private function assertValidQuery($query, $expected) : void
{
$this->assertEquals(
['data' => $expected],
GraphQL::executeQuery(StarWarsSchema::build(), $query)->toArray()
);
}
// Describe: Nested Queries
/** /**
* @see it('Allows us to query for the ID and friends of R2-D2') * @see it('Allows us to query for the ID and friends of R2-D2')
*/ */
public function testAllowsUsToQueryForTheIDAndFriendsOfR2D2() : void public function testAllowsUsToQueryForTheIDAndFriendsOfR2D2() : void
{ {
$query = ' $query = '
query HeroNameAndFriendsQuery { query HeroNameAndFriendsQuery {
hero { hero {
id id
@ -48,32 +58,26 @@ class StarWarsQueryTest extends TestCase
'; ';
$expected = [ $expected = [
'hero' => [ 'hero' => [
'id' => '2001', 'id' => '2001',
'name' => 'R2-D2', 'name' => 'R2-D2',
'friends' => [ 'friends' => [
[ ['name' => 'Luke Skywalker'],
'name' => 'Luke Skywalker', ['name' => 'Han Solo'],
], ['name' => 'Leia Organa'],
[ ],
'name' => 'Han Solo', ],
],
[
'name' => 'Leia Organa',
],
]
]
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
// Describe: Nested Queries // Describe: Using IDs and query parameters to refetch objects
/** /**
* @see it('Allows us to query for the friends of friends of R2-D2') * @see it('Allows us to query for the friends of friends of R2-D2')
*/ */
public function testAllowsUsToQueryForTheFriendsOfFriendsOfR2D2() : void public function testAllowsUsToQueryForTheFriendsOfFriendsOfR2D2() : void
{ {
$query = ' $query = '
query NestedQuery { query NestedQuery {
hero { hero {
name name
@ -89,52 +93,50 @@ class StarWarsQueryTest extends TestCase
'; ';
$expected = [ $expected = [
'hero' => [ 'hero' => [
'name' => 'R2-D2', 'name' => 'R2-D2',
'friends' => [ 'friends' => [
[ [
'name' => 'Luke Skywalker', 'name' => 'Luke Skywalker',
'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI',], 'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI'],
'friends' => [ 'friends' => [
['name' => 'Han Solo',], ['name' => 'Han Solo'],
['name' => 'Leia Organa',], ['name' => 'Leia Organa'],
['name' => 'C-3PO',], ['name' => 'C-3PO'],
['name' => 'R2-D2',], ['name' => 'R2-D2'],
], ],
], ],
[ [
'name' => 'Han Solo', 'name' => 'Han Solo',
'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI'], 'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI'],
'friends' => [ 'friends' => [
['name' => 'Luke Skywalker',], ['name' => 'Luke Skywalker'],
['name' => 'Leia Organa'], ['name' => 'Leia Organa'],
['name' => 'R2-D2',], ['name' => 'R2-D2'],
] ],
], ],
[ [
'name' => 'Leia Organa', 'name' => 'Leia Organa',
'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI'], 'appearsIn' => ['NEWHOPE', 'EMPIRE', 'JEDI'],
'friends' => 'friends' =>
[ [
['name' => 'Luke Skywalker',], ['name' => 'Luke Skywalker'],
['name' => 'Han Solo',], ['name' => 'Han Solo'],
['name' => 'C-3PO',], ['name' => 'C-3PO'],
['name' => 'R2-D2',], ['name' => 'R2-D2'],
], ],
], ],
], ],
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
// Describe: Using IDs and query parameters to refetch objects
/** /**
* @see it('Using IDs and query parameters to refetch objects') * @see it('Using IDs and query parameters to refetch objects')
*/ */
public function testAllowsUsToQueryForLukeSkywalkerDirectlyUsingHisID() : void public function testAllowsUsToQueryForLukeSkywalkerDirectlyUsingHisID() : void
{ {
$query = ' $query = '
query FetchLukeQuery { query FetchLukeQuery {
human(id: "1000") { human(id: "1000") {
name name
@ -142,9 +144,7 @@ class StarWarsQueryTest extends TestCase
} }
'; ';
$expected = [ $expected = [
'human' => [ 'human' => ['name' => 'Luke Skywalker'],
'name' => 'Luke Skywalker'
]
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
@ -155,44 +155,49 @@ class StarWarsQueryTest extends TestCase
*/ */
public function testGenericQueryToGetLukeSkywalkerById() : void public function testGenericQueryToGetLukeSkywalkerById() : void
{ {
$query = ' $query = '
query FetchSomeIDQuery($someId: String!) { query FetchSomeIDQuery($someId: String!) {
human(id: $someId) { human(id: $someId) {
name name
} }
} }
'; ';
$params = [ $params = ['someId' => '1000'];
'someId' => '1000'
];
$expected = [ $expected = [
'human' => [ 'human' => ['name' => 'Luke Skywalker'],
'name' => 'Luke Skywalker'
]
]; ];
$this->assertValidQueryWithParams($query, $params, $expected); $this->assertValidQueryWithParams($query, $params, $expected);
} }
/**
* Helper function to test a query with params and the expected response.
*/
private function assertValidQueryWithParams($query, $params, $expected)
{
$this->assertEquals(
['data' => $expected],
GraphQL::executeQuery(StarWarsSchema::build(), $query, null, null, $params)->toArray()
);
}
// Using aliases to change the key in the response
/** /**
* @see it('Allows us to create a generic query, then use it to fetch Han Solo using his ID') * @see it('Allows us to create a generic query, then use it to fetch Han Solo using his ID')
*/ */
public function testGenericQueryToGetHanSoloById() : void public function testGenericQueryToGetHanSoloById() : void
{ {
$query = ' $query = '
query FetchSomeIDQuery($someId: String!) { query FetchSomeIDQuery($someId: String!) {
human(id: $someId) { human(id: $someId) {
name name
} }
} }
'; ';
$params = [ $params = ['someId' => '1002'];
'someId' => '1002'
];
$expected = [ $expected = [
'human' => [ 'human' => ['name' => 'Han Solo'],
'name' => 'Han Solo'
]
]; ];
$this->assertValidQueryWithParams($query, $params, $expected); $this->assertValidQueryWithParams($query, $params, $expected);
} }
@ -202,30 +207,26 @@ class StarWarsQueryTest extends TestCase
*/ */
public function testGenericQueryWithInvalidId() : void public function testGenericQueryWithInvalidId() : void
{ {
$query = ' $query = '
query humanQuery($id: String!) { query humanQuery($id: String!) {
human(id: $id) { human(id: $id) {
name name
} }
} }
'; ';
$params = [ $params = ['id' => 'not a valid id'];
'id' => 'not a valid id' $expected = ['human' => null];
];
$expected = [
'human' => null
];
$this->assertValidQueryWithParams($query, $params, $expected); $this->assertValidQueryWithParams($query, $params, $expected);
} }
// Using aliases to change the key in the response // Uses fragments to express more complex queries
/** /**
* @see it('Allows us to query for Luke, changing his key with an alias') * @see it('Allows us to query for Luke, changing his key with an alias')
*/ */
function testLukeKeyAlias() public function testLukeKeyAlias() : void
{ {
$query = ' $query = '
query FetchLukeAliased { query FetchLukeAliased {
luke: human(id: "1000") { luke: human(id: "1000") {
name name
@ -233,9 +234,7 @@ class StarWarsQueryTest extends TestCase
} }
'; ';
$expected = [ $expected = [
'luke' => [ 'luke' => ['name' => 'Luke Skywalker'],
'name' => 'Luke Skywalker'
],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -243,9 +242,9 @@ class StarWarsQueryTest extends TestCase
/** /**
* @see it('Allows us to query for both Luke and Leia, using two root fields and an alias') * @see it('Allows us to query for both Luke and Leia, using two root fields and an alias')
*/ */
function testTwoRootKeysAsAnAlias() public function testTwoRootKeysAsAnAlias() : void
{ {
$query = ' $query = '
query FetchLukeAndLeiaAliased { query FetchLukeAndLeiaAliased {
luke: human(id: "1000") { luke: human(id: "1000") {
name name
@ -256,24 +255,18 @@ class StarWarsQueryTest extends TestCase
} }
'; ';
$expected = [ $expected = [
'luke' => [ 'luke' => ['name' => 'Luke Skywalker'],
'name' => 'Luke Skywalker' 'leia' => ['name' => 'Leia Organa'],
],
'leia' => [
'name' => 'Leia Organa'
]
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
// Uses fragments to express more complex queries
/** /**
* @see it('Allows us to query using duplicated content') * @see it('Allows us to query using duplicated content')
*/ */
function testQueryUsingDuplicatedContent() public function testQueryUsingDuplicatedContent() : void
{ {
$query = ' $query = '
query DuplicateFields { query DuplicateFields {
luke: human(id: "1000") { luke: human(id: "1000") {
name name
@ -287,13 +280,13 @@ class StarWarsQueryTest extends TestCase
'; ';
$expected = [ $expected = [
'luke' => [ 'luke' => [
'name' => 'Luke Skywalker', 'name' => 'Luke Skywalker',
'homePlanet' => 'Tatooine' 'homePlanet' => 'Tatooine',
], ],
'leia' => [ 'leia' => [
'name' => 'Leia Organa', 'name' => 'Leia Organa',
'homePlanet' => 'Alderaan' 'homePlanet' => 'Alderaan',
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -301,7 +294,7 @@ class StarWarsQueryTest extends TestCase
/** /**
* @see it('Allows us to use a fragment to avoid duplicating content') * @see it('Allows us to use a fragment to avoid duplicating content')
*/ */
function testUsingFragment() public function testUsingFragment() : void
{ {
$query = ' $query = '
query UseFragment { query UseFragment {
@ -321,13 +314,13 @@ class StarWarsQueryTest extends TestCase
$expected = [ $expected = [
'luke' => [ 'luke' => [
'name' => 'Luke Skywalker', 'name' => 'Luke Skywalker',
'homePlanet' => 'Tatooine' 'homePlanet' => 'Tatooine',
], ],
'leia' => [ 'leia' => [
'name' => 'Leia Organa', 'name' => 'Leia Organa',
'homePlanet' => 'Alderaan' 'homePlanet' => 'Alderaan',
] ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
@ -337,7 +330,7 @@ class StarWarsQueryTest extends TestCase
*/ */
public function testVerifyThatR2D2IsADroid() : void public function testVerifyThatR2D2IsADroid() : void
{ {
$query = ' $query = '
query CheckTypeOfR2 { query CheckTypeOfR2 {
hero { hero {
__typename __typename
@ -348,7 +341,7 @@ class StarWarsQueryTest extends TestCase
$expected = [ $expected = [
'hero' => [ 'hero' => [
'__typename' => 'Droid', '__typename' => 'Droid',
'name' => 'R2-D2' 'name' => 'R2-D2',
], ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
@ -371,32 +364,10 @@ class StarWarsQueryTest extends TestCase
$expected = [ $expected = [
'hero' => [ 'hero' => [
'__typename' => 'Human', '__typename' => 'Human',
'name' => 'Luke Skywalker' 'name' => 'Luke Skywalker',
], ],
]; ];
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
/**
* Helper function to test a query and the expected response.
*/
private function assertValidQuery($query, $expected)
{
$this->assertEquals(
['data' => $expected],
GraphQL::executeQuery(StarWarsSchema::build(), $query)->toArray()
);
}
/**
* Helper function to test a query with params and the expected response.
*/
private function assertValidQueryWithParams($query, $params, $expected)
{
$this->assertEquals(
['data' => $expected],
GraphQL::executeQuery(StarWarsSchema::build(), $query, null, null, $params)->toArray()
);
}
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests; namespace GraphQL\Tests;
/** /**
@ -11,13 +14,16 @@ namespace GraphQL\Tests;
* NOTE: This may contain spoilers for the original Star * NOTE: This may contain spoilers for the original Star
* Wars trilogy. * Wars trilogy.
*/ */
use GraphQL\Type\Schema;
use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\InterfaceType;
use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\NonNull;
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 function array_intersect_key;
use function array_map;
/** /**
* Using our shorthand to describe type systems, the type system for our * Using our shorthand to describe type systems, the type system for our
@ -56,10 +62,9 @@ use GraphQL\Type\Definition\Type;
* *
* We begin by setting up our schema. * We begin by setting up our schema.
*/ */
class StarWarsSchema class StarWarsSchema
{ {
public static function build() public static function build() : Schema
{ {
/** /**
* The original trilogy consists of three movies. * The original trilogy consists of three movies.
@ -68,22 +73,22 @@ class StarWarsSchema
* enum Episode { NEWHOPE, EMPIRE, JEDI } * enum Episode { NEWHOPE, EMPIRE, JEDI }
*/ */
$episodeEnum = new EnumType([ $episodeEnum = new EnumType([
'name' => 'Episode', 'name' => 'Episode',
'description' => 'One of the films in the Star Wars Trilogy', 'description' => 'One of the films in the Star Wars Trilogy',
'values' => [ 'values' => [
'NEWHOPE' => [ 'NEWHOPE' => [
'value' => 4, 'value' => 4,
'description' => 'Released in 1977.' 'description' => 'Released in 1977.',
], ],
'EMPIRE' => [ 'EMPIRE' => [
'value' => 5, 'value' => 5,
'description' => 'Released in 1980.' 'description' => 'Released in 1980.',
], ],
'JEDI' => [ 'JEDI' => [
'value' => 6, 'value' => 6,
'description' => 'Released in 1983.' 'description' => 'Released in 1983.',
], ],
] ],
]); ]);
$humanType = null; $humanType = null;
@ -101,28 +106,28 @@ class StarWarsSchema
* } * }
*/ */
$characterInterface = new InterfaceType([ $characterInterface = new InterfaceType([
'name' => 'Character', 'name' => 'Character',
'description' => 'A character in the Star Wars Trilogy', 'description' => 'A character in the Star Wars Trilogy',
'fields' => function() use (&$characterInterface, $episodeEnum) { 'fields' => function () use (&$characterInterface, $episodeEnum) {
return [ return [
'id' => [ 'id' => [
'type' => Type::nonNull(Type::string()), 'type' => Type::nonNull(Type::string()),
'description' => 'The id of the character.', 'description' => 'The id of the character.',
], ],
'name' => [ 'name' => [
'type' => Type::string(), 'type' => Type::string(),
'description' => 'The name of the character.' 'description' => 'The name of the character.',
], ],
'friends' => [ 'friends' => [
'type' => Type::listOf($characterInterface), 'type' => Type::listOf($characterInterface),
'description' => 'The friends of the character, or an empty list if they have none.', 'description' => 'The friends of the character, or an empty list if they have none.',
], ],
'appearsIn' => [ 'appearsIn' => [
'type' => Type::listOf($episodeEnum), 'type' => Type::listOf($episodeEnum),
'description' => 'Which movies they appear in.' 'description' => 'Which movies they appear in.',
], ],
'secretBackstory' => [ 'secretBackstory' => [
'type' => Type::string(), 'type' => Type::string(),
'description' => 'All secrets about their past.', 'description' => 'All secrets about their past.',
], ],
]; ];
@ -145,26 +150,26 @@ class StarWarsSchema
* } * }
*/ */
$humanType = new ObjectType([ $humanType = new ObjectType([
'name' => 'Human', 'name' => 'Human',
'description' => 'A humanoid creature in the Star Wars universe.', 'description' => 'A humanoid creature in the Star Wars universe.',
'fields' => [ 'fields' => [
'id' => [ 'id' => [
'type' => new NonNull(Type::string()), 'type' => new NonNull(Type::string()),
'description' => 'The id of the human.', 'description' => 'The id of the human.',
], ],
'name' => [ 'name' => [
'type' => Type::string(), 'type' => Type::string(),
'description' => 'The name of the human.', 'description' => 'The name of the human.',
], ],
'friends' => [ 'friends' => [
'type' => Type::listOf($characterInterface), 'type' => Type::listOf($characterInterface),
'description' => 'The friends of the human, or an empty list if they have none.', 'description' => 'The friends of the human, or an empty list if they have none.',
'resolve' => function ($human, $args, $context, ResolveInfo $info) { 'resolve' => function ($human, $args, $context, ResolveInfo $info) {
$fieldSelection = $info->getFieldSelection(); $fieldSelection = $info->getFieldSelection();
$fieldSelection['id'] = true; $fieldSelection['id'] = true;
$friends = array_map( $friends = array_map(
function($friend) use ($fieldSelection) { function ($friend) use ($fieldSelection) {
return array_intersect_key($friend, $fieldSelection); return array_intersect_key($friend, $fieldSelection);
}, },
StarWarsData::getFriends($human) StarWarsData::getFriends($human)
@ -173,24 +178,24 @@ class StarWarsSchema
return $friends; return $friends;
}, },
], ],
'appearsIn' => [ 'appearsIn' => [
'type' => Type::listOf($episodeEnum), 'type' => Type::listOf($episodeEnum),
'description' => 'Which movies they appear in.' 'description' => 'Which movies they appear in.',
], ],
'homePlanet' => [ 'homePlanet' => [
'type' => Type::string(), 'type' => Type::string(),
'description' => 'The home planet of the human, or null if unknown.' 'description' => 'The home planet of the human, or null if unknown.',
], ],
'secretBackstory' => [ 'secretBackstory' => [
'type' => Type::string(), 'type' => Type::string(),
'description' => 'Where are they from and how they came to be who they are.', 'description' => 'Where are they from and how they came to be who they are.',
'resolve' => function() { 'resolve' => function () {
// This is to demonstrate error reporting // This is to demonstrate error reporting
throw new \Exception('secretBackstory is secret.'); throw new \Exception('secretBackstory is secret.');
}, },
], ],
], ],
'interfaces' => [$characterInterface] 'interfaces' => [$characterInterface],
]); ]);
/** /**
@ -207,42 +212,42 @@ class StarWarsSchema
* } * }
*/ */
$droidType = new ObjectType([ $droidType = new ObjectType([
'name' => 'Droid', 'name' => 'Droid',
'description' => 'A mechanical creature in the Star Wars universe.', 'description' => 'A mechanical creature in the Star Wars universe.',
'fields' => [ 'fields' => [
'id' => [ 'id' => [
'type' => Type::nonNull(Type::string()), 'type' => Type::nonNull(Type::string()),
'description' => 'The id of the droid.', 'description' => 'The id of the droid.',
], ],
'name' => [ 'name' => [
'type' => Type::string(), 'type' => Type::string(),
'description' => 'The name of the droid.' 'description' => 'The name of the droid.',
], ],
'friends' => [ 'friends' => [
'type' => Type::listOf($characterInterface), 'type' => Type::listOf($characterInterface),
'description' => 'The friends of the droid, or an empty list if they have none.', 'description' => 'The friends of the droid, or an empty list if they have none.',
'resolve' => function ($droid) { 'resolve' => function ($droid) {
return StarWarsData::getFriends($droid); return StarWarsData::getFriends($droid);
}, },
], ],
'appearsIn' => [ 'appearsIn' => [
'type' => Type::listOf($episodeEnum), 'type' => Type::listOf($episodeEnum),
'description' => 'Which movies they appear in.' 'description' => 'Which movies they appear in.',
], ],
'secretBackstory' => [ 'secretBackstory' => [
'type' => Type::string(), 'type' => Type::string(),
'description' => 'Construction date and the name of the designer.', 'description' => 'Construction date and the name of the designer.',
'resolve' => function() { 'resolve' => function () {
// This is to demonstrate error reporting // This is to demonstrate error reporting
throw new \Exception('secretBackstory is secret.'); throw new \Exception('secretBackstory is secret.');
}, },
], ],
'primaryFunction' => [ 'primaryFunction' => [
'type' => Type::string(), 'type' => Type::string(),
'description' => 'The primary function of the droid.' 'description' => 'The primary function of the droid.',
] ],
], ],
'interfaces' => [$characterInterface] 'interfaces' => [$characterInterface],
]); ]);
/** /**
@ -260,49 +265,51 @@ class StarWarsSchema
* *
*/ */
$queryType = new ObjectType([ $queryType = new ObjectType([
'name' => 'Query', 'name' => 'Query',
'fields' => [ 'fields' => [
'hero' => [ 'hero' => [
'type' => $characterInterface, 'type' => $characterInterface,
'args' => [ 'args' => [
'episode' => [ 'episode' => [
'description' => 'If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode.', 'description' => 'If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode.',
'type' => $episodeEnum 'type' => $episodeEnum,
] ],
], ],
'resolve' => function ($root, $args) { 'resolve' => function ($root, $args) {
return StarWarsData::getHero(isset($args['episode']) ? $args['episode'] : null); return StarWarsData::getHero($args['episode'] ?? null);
}, },
], ],
'human' => [ 'human' => [
'type' => $humanType, 'type' => $humanType,
'args' => [ 'args' => [
'id' => [ 'id' => [
'name' => 'id', 'name' => 'id',
'description' => 'id of the human', 'description' => 'id of the human',
'type' => Type::nonNull(Type::string()) 'type' => Type::nonNull(Type::string()),
] ],
], ],
'resolve' => function ($root, $args) { 'resolve' => function ($root, $args) {
$humans = StarWarsData::humans(); $humans = StarWarsData::humans();
return isset($humans[$args['id']]) ? $humans[$args['id']] : null;
} return $humans[$args['id']] ?? null;
},
], ],
'droid' => [ 'droid' => [
'type' => $droidType, 'type' => $droidType,
'args' => [ 'args' => [
'id' => [ 'id' => [
'name' => 'id', 'name' => 'id',
'description' => 'id of the droid', 'description' => 'id of the droid',
'type' => Type::nonNull(Type::string()) 'type' => Type::nonNull(Type::string()),
] ],
], ],
'resolve' => function ($root, $args) { 'resolve' => function ($root, $args) {
$droids = StarWarsData::droids(); $droids = StarWarsData::droids();
return isset($droids[$args['id']]) ? $droids[$args['id']] : null;
} return $droids[$args['id']] ?? null;
] },
] ],
],
]); ]);
return new Schema(['query' => $queryType]); return new Schema(['query' => $queryType]);

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests; namespace GraphQL\Tests;
use GraphQL\Language\Parser; use GraphQL\Language\Parser;
@ -15,7 +18,7 @@ class StarWarsValidationTest extends TestCase
*/ */
public function testValidatesAComplexButValidQuery() : void public function testValidatesAComplexButValidQuery() : void
{ {
$query = ' $query = '
query NestedQueryWithFragment { query NestedQueryWithFragment {
hero { hero {
...NameAndAppearances ...NameAndAppearances
@ -37,12 +40,22 @@ class StarWarsValidationTest extends TestCase
$this->assertEquals(true, empty($errors)); $this->assertEquals(true, empty($errors));
} }
/**
* Helper function to test a query and the expected response.
*/
private function validationErrors($query)
{
$ast = Parser::parse($query);
return DocumentValidator::validate(StarWarsSchema::build(), $ast);
}
/** /**
* @see it('Notes that non-existent fields are invalid') * @see it('Notes that non-existent fields are invalid')
*/ */
public function testThatNonExistentFieldsAreInvalid() : void public function testThatNonExistentFieldsAreInvalid() : void
{ {
$query = ' $query = '
query HeroSpaceshipQuery { query HeroSpaceshipQuery {
hero { hero {
favoriteSpaceship favoriteSpaceship
@ -73,7 +86,7 @@ class StarWarsValidationTest extends TestCase
*/ */
public function testDisallowsFieldsOnScalars() : void public function testDisallowsFieldsOnScalars() : void
{ {
$query = ' $query = '
query HeroFieldsOnScalarQuery { query HeroFieldsOnScalarQuery {
hero { hero {
name { name {
@ -91,7 +104,7 @@ class StarWarsValidationTest extends TestCase
*/ */
public function testDisallowsObjectFieldsOnInterfaces() : void public function testDisallowsObjectFieldsOnInterfaces() : void
{ {
$query = ' $query = '
query DroidFieldOnCharacter { query DroidFieldOnCharacter {
hero { hero {
name name
@ -108,7 +121,7 @@ class StarWarsValidationTest extends TestCase
*/ */
public function testAllowsObjectFieldsInFragments() : void public function testAllowsObjectFieldsInFragments() : void
{ {
$query = ' $query = '
query DroidFieldInFragment { query DroidFieldInFragment {
hero { hero {
name name
@ -129,7 +142,7 @@ class StarWarsValidationTest extends TestCase
*/ */
public function testAllowsObjectFieldsInInlineFragments() : void public function testAllowsObjectFieldsInInlineFragments() : void
{ {
$query = ' $query = '
query DroidFieldInFragment { query DroidFieldInFragment {
hero { hero {
name name
@ -142,13 +155,4 @@ class StarWarsValidationTest extends TestCase
$errors = $this->validationErrors($query); $errors = $this->validationErrors($query);
$this->assertEquals(true, empty($errors)); $this->assertEquals(true, empty($errors));
} }
/**
* Helper function to test a query and the expected response.
*/
private function validationErrors($query)
{
$ast = Parser::parse($query);
return DocumentValidator::validate(StarWarsSchema::build(), $ast);
}
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests; namespace GraphQL\Tests;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
@ -8,7 +11,7 @@ class UtilsTest extends TestCase
{ {
public function testAssignThrowsExceptionOnMissingRequiredKey() : void public function testAssignThrowsExceptionOnMissingRequiredKey() : void
{ {
$object = new \stdClass(); $object = new \stdClass();
$object->requiredKey = 'value'; $object->requiredKey = 'value';
$this->expectException(\InvalidArgumentException::class); $this->expectException(\InvalidArgumentException::class);