Skip to content

Commit c6eb386

Browse files
committed
Adding support for migrations
1 parent dccfc63 commit c6eb386

File tree

4 files changed

+124
-30
lines changed

4 files changed

+124
-30
lines changed

src/Annotations/Mutation.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
4+
namespace TheCodingMachine\GraphQL\Controllers\Annotations;
5+
6+
/**
7+
* @Annotation
8+
*/
9+
class Mutation
10+
{
11+
12+
}

src/ControllerQueryProvider.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Roave\BetterReflection\Reflection\ReflectionMethod;
1313
use Doctrine\Common\Annotations\Reader;
1414
use phpDocumentor\Reflection\Types\Integer;
15+
use TheCodingMachine\GraphQL\Controllers\Annotations\Mutation;
1516
use TheCodingMachine\GraphQL\Controllers\Annotations\Query;
1617
use Youshido\GraphQL\Field\Field;
1718
use Youshido\GraphQL\Type\ListType\ListType;
@@ -58,6 +59,22 @@ public function __construct($controller, Reader $annotationReader, TypeMapperInt
5859
* @return Field[]
5960
*/
6061
public function getQueries(): array
62+
{
63+
return $this->getFieldsByAnnotations(Query::class);
64+
}
65+
66+
/**
67+
* @return Field[]
68+
*/
69+
public function getMutations(): array
70+
{
71+
return $this->getFieldsByAnnotations(Mutation::class);
72+
}
73+
74+
/**
75+
* @return Field[]
76+
*/
77+
private function getFieldsByAnnotations(string $annotationName): array
6178
{
6279
$refClass = ReflectionClass::createFromInstance($this->controller);
6380

@@ -66,7 +83,7 @@ public function getQueries(): array
6683
foreach ($refClass->getMethods() as $refMethod) {
6784
$standardPhpMethod = new \ReflectionMethod(get_class($this->controller), $refMethod->getName());
6885
// First, let's check the "Query" annotation
69-
$queryAnnotation = $this->annotationReader->getMethodAnnotation($standardPhpMethod, Query::class);
86+
$queryAnnotation = $this->annotationReader->getMethodAnnotation($standardPhpMethod, $annotationName);
7087
if ($queryAnnotation !== null) {
7188
$methodName = $refMethod->getName();
7289

tests/ControllerQueryProviderTest.php

Lines changed: 83 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,72 @@
1616

1717
class ControllerQueryProviderTest extends TestCase
1818
{
19-
public function testQueryProvider()
19+
20+
private $testObjectType;
21+
private $typeMapper;
22+
private $hydrator;
23+
24+
private function getTestObjectType()
2025
{
21-
$controller = new TestController();
22-
$reader = new AnnotationReader();
26+
if ($this->testObjectType === null) {
27+
$this->testObjectType = new ObjectType([
28+
'name' => 'TestObject',
29+
'fields' => [
30+
'test' => new StringType(),
31+
],
32+
]);
33+
}
34+
return $this->testObjectType;
35+
}
2336

24-
$typeMapper = new class implements TypeMapperInterface {
25-
public function mapClassToType(string $className): TypeInterface
26-
{
27-
if ($className === TestObject::class) {
28-
return new ObjectType([
29-
'name' => 'TestObject',
30-
'fields' => [
31-
'test' => new StringType(),
32-
],
33-
]);
34-
} else {
35-
throw new \RuntimeException('Unexpected type');
37+
private function getTypeMapper()
38+
{
39+
if ($this->typeMapper === null) {
40+
$this->typeMapper = new class($this->getTestObjectType()) implements TypeMapperInterface {
41+
/**
42+
* @var ObjectType
43+
*/
44+
private $testObjectType;
45+
46+
public function __construct(ObjectType $testObjectType)
47+
{
48+
49+
$this->testObjectType = $testObjectType;
50+
}
51+
52+
public function mapClassToType(string $className): TypeInterface
53+
{
54+
if ($className === TestObject::class) {
55+
return $this->testObjectType;
56+
} else {
57+
throw new \RuntimeException('Unexpected type');
58+
}
3659
}
37-
}
38-
};
60+
};
61+
}
62+
return $this->typeMapper;
63+
}
3964

40-
$hydrator = new class implements HydratorInterface {
41-
public function hydrate(array $data, TypeInterface $type)
65+
private function getHydrator()
66+
{
67+
if ($this->hydrator === null) {
68+
$this->hydrator = new class implements HydratorInterface
4269
{
43-
return new TestObject($data['test']);
44-
}
45-
};
70+
public function hydrate(array $data, TypeInterface $type)
71+
{
72+
return new TestObject($data['test']);
73+
}
74+
};
75+
}
76+
return $this->hydrator;
77+
}
78+
79+
public function testQueryProvider()
80+
{
81+
$controller = new TestController();
82+
$reader = new AnnotationReader();
4683

47-
$queryProvider = new ControllerQueryProvider($controller, $reader, $typeMapper, $hydrator);
84+
$queryProvider = new ControllerQueryProvider($controller, $reader, $this->getTypeMapper(), $this->getHydrator());
4885

4986
$queries = $queryProvider->getQueries();
5087

@@ -62,12 +99,7 @@ public function hydrate(array $data, TypeInterface $type)
6299
$this->assertInstanceOf(ObjectType::class, $usersQuery->getArgument('list')->getType()->getTypeOf()->getItemType()->getTypeOf());
63100
$this->assertSame('TestObject', $usersQuery->getArgument('list')->getType()->getTypeOf()->getItemType()->getTypeOf()->getName());
64101

65-
$mockResolveInfo = $this->getMockBuilder(ResolveInfo::class)
66-
->disableOriginalConstructor()
67-
->disableOriginalClone()
68-
->disableArgumentCloning()
69-
->disallowMockingUnknownTypes()
70-
->getMock();
102+
$mockResolveInfo = $this->createMock(ResolveInfo::class);
71103

72104
$result = $usersQuery->resolve('foo', ['int'=>42, 'string'=>'foo', 'list'=>[
73105
['test'=>42],
@@ -77,4 +109,26 @@ public function hydrate(array $data, TypeInterface $type)
77109
$this->assertInstanceOf(TestObject::class, $result);
78110
$this->assertSame('foo424212', $result->getTest());
79111
}
112+
113+
public function testMutations()
114+
{
115+
$controller = new TestController();
116+
$reader = new AnnotationReader();
117+
118+
$queryProvider = new ControllerQueryProvider($controller, $reader, $this->getTypeMapper(), $this->getHydrator());
119+
120+
$mutations = $queryProvider->getMutations();
121+
122+
$this->assertCount(1, $mutations);
123+
$mutation = $mutations[0];
124+
$this->assertSame('mutation', $mutation->getName());
125+
126+
$mockResolveInfo = $this->createMock(ResolveInfo::class);
127+
128+
$result = $mutation->resolve('foo', ['testObject'=>['test'=>42]], $mockResolveInfo);
129+
130+
$this->assertInstanceOf(TestObject::class, $result);
131+
$this->assertEquals('42', $result->getTest());
132+
133+
}
80134
}

tests/Fixtures/TestController.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace TheCodingMachine\GraphQL\Controllers\Fixtures;
55

66

7+
use TheCodingMachine\GraphQL\Controllers\Annotations\Mutation;
78
use TheCodingMachine\GraphQL\Controllers\Annotations\Query;
89

910
class TestController
@@ -26,4 +27,14 @@ public function test(int $int, ?string $string, array $list): TestObject
2627
}
2728
return new TestObject($string.$int.$str);
2829
}
30+
31+
/**
32+
* @Mutation()
33+
* @param TestObject $testObject
34+
* @return TestObject
35+
*/
36+
public function mutation(TestObject $testObject): TestObject
37+
{
38+
return $testObject;
39+
}
2940
}

0 commit comments

Comments
 (0)