Completed
Pull Request — master (#44)
by David
01:59
created

anonymous//tests/AbstractQueryProviderTest.php$0   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 11
dl 0
loc 65
c 0
b 0
f 0
rs 10
1
<?php
2
3
4
namespace TheCodingMachine\GraphQL\Controllers;
5
6
use Doctrine\Common\Annotations\AnnotationReader;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, TheCodingMachine\GraphQL...ollers\AnnotationReader. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
7
use GraphQL\Type\Definition\InputObjectType;
8
use GraphQL\Type\Definition\InputType;
9
use GraphQL\Type\Definition\ObjectType;
10
use GraphQL\Type\Definition\OutputType;
11
use GraphQL\Type\Definition\Type;
12
use PHPUnit\Framework\TestCase;
13
use Psr\Container\ContainerInterface;
14
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject;
15
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject2;
16
use TheCodingMachine\GraphQL\Controllers\Mappers\CannotMapTypeException;
17
use TheCodingMachine\GraphQL\Controllers\Mappers\RecursiveTypeMapper;
18
use TheCodingMachine\GraphQL\Controllers\Mappers\TypeMapperInterface;
19
use TheCodingMachine\GraphQL\Controllers\Registry\EmptyContainer;
20
use TheCodingMachine\GraphQL\Controllers\Registry\Registry;
21
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthenticationService;
22
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthorizationService;
23
24
abstract class AbstractQueryProviderTest extends TestCase
25
{
26
    private $testObjectType;
27
    private $testObjectType2;
28
    private $inputTestObjectType;
29
    private $typeMapper;
30
    private $hydrator;
31
    private $registry;
32
33
    protected function getTestObjectType()
34
    {
35
        if ($this->testObjectType === null) {
36
            $this->testObjectType = new ObjectType([
37
                'name'    => 'TestObject',
38
                'fields'  => [
39
                    'test'   => Type::string(),
40
                ],
41
            ]);
42
        }
43
        return $this->testObjectType;
44
    }
45
46
    protected function getTestObjectType2()
47
    {
48
        if ($this->testObjectType2 === null) {
49
            $this->testObjectType2 = new ObjectType([
50
                'name'    => 'TestObject2',
51
                'fields'  => [
52
                    'test'   => Type::string(),
53
                ],
54
            ]);
55
        }
56
        return $this->testObjectType2;
57
    }
58
59
    protected function getInputTestObjectType()
60
    {
61
        if ($this->inputTestObjectType === null) {
62
            $this->inputTestObjectType = new InputObjectType([
63
                'name'    => 'TestObject',
64
                'fields'  => [
65
                    'test'   => Type::string(),
66
                ],
67
            ]);
68
        }
69
        return $this->inputTestObjectType;
70
    }
71
72
    protected function getTypeMapper()
73
    {
74
        if ($this->typeMapper === null) {
75
            $this->typeMapper = new RecursiveTypeMapper(new class($this->getTestObjectType(), $this->getTestObjectType2(), $this->getInputTestObjectType()) implements TypeMapperInterface {
76
                /**
77
                 * @var ObjectType
78
                 */
79
                private $testObjectType;
80
                /**
81
                 * @var ObjectType
82
                 */
83
                private $testObjectType2;
84
                /**
85
                 * @var InputObjectType
86
                 */
87
                private $inputTestObjectType;
88
89
                public function __construct(ObjectType $testObjectType, ObjectType $testObjectType2, InputObjectType $inputTestObjectType)
90
                {
91
                    $this->testObjectType = $testObjectType;
92
                    $this->testObjectType2 = $testObjectType2;
93
                    $this->inputTestObjectType = $inputTestObjectType;
94
                }
95
96
                public function mapClassToType(string $className): OutputType
97
                {
98
                    if ($className === TestObject::class) {
99
                        return $this->testObjectType;
100
                    } elseif ($className === TestObject2::class) {
101
                        return $this->testObjectType2;
102
                    } else {
103
                        throw CannotMapTypeException::createForType($className);
104
                    }
105
                }
106
107
                public function mapClassToInputType(string $className): InputType
108
                {
109
                    if ($className === TestObject::class) {
110
                        return $this->inputTestObjectType;
111
                    } else {
112
                        throw CannotMapTypeException::createForInputType($className);
113
                    }
114
                }
115
116
                public function canMapClassToType(string $className): bool
117
                {
118
                    return $className === TestObject::class || $className === TestObject2::class;
119
                }
120
121
                /**
122
                 * Returns true if this type mapper can map the $className FQCN to a GraphQL input type.
123
                 *
124
                 * @param string $className
125
                 * @return bool
126
                 */
127
                public function canMapClassToInputType(string $className): bool
128
                {
129
                    return $className === TestObject::class || $className === TestObject2::class;
130
                }
131
132
                /**
133
                 * Returns the list of classes that have matching input GraphQL types.
134
                 *
135
                 * @return string[]
136
                 */
137
                public function getSupportedClasses(): array
138
                {
139
                    return [TestObject::class, TestObject2::class];
140
                }
141
            });
142
        }
143
        return $this->typeMapper;
144
    }
145
146
    protected function getHydrator()
147
    {
148
        if ($this->hydrator === null) {
149
            $this->hydrator = new class implements HydratorInterface {
150
                public function hydrate(array $data, InputType $type)
151
                {
152
                    return new TestObject($data['test']);
153
                }
154
            };
155
        }
156
        return $this->hydrator;
157
    }
158
159
    protected function getRegistry()
160
    {
161
        if ($this->registry === null) {
162
            $this->registry = $this->buildRegistry(new EmptyContainer());
163
        }
164
        return $this->registry;
165
    }
166
167
    protected function buildRegistry(ContainerInterface $container): Registry
168
    {
169
        $reader = new AnnotationReader();
170
        return new Registry($container,
171
                new VoidAuthorizationService(),
172
                new VoidAuthenticationService(),
173
                $reader,
174
                $this->getTypeMapper(),
175
                $this->getHydrator());
176
    }
177
}
178