CompositeTypeMapperTest   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 19
eloc 61
dl 0
loc 168
rs 10
c 0
b 0
f 0

21 Methods

Rating   Name   Duplication   Size   Complexity  
A hp$0 ➔ canMapClassToInputType() 0 3 1
A hp$0 ➔ mapClassToInputType() 0 11 2
A hp$0 ➔ canMapClassToType() 0 3 1
A hp$0 ➔ mapClassToType() 0 11 2
A hp$0 ➔ canMapNameToType() 0 3 1
A hp$0 ➔ canExtendTypeForClass() 0 3 1
A hp$0 ➔ canExtendTypeForName() 0 3 1
A hp$0 ➔ getSupportedClasses() 0 3 1
A hp$0 ➔ mapNameToType() 0 12 2
A hp$0 ➔ extendTypeForClass() 0 3 1
testException1() 0 4 ?
testException2() 0 4 ?
A hp$0 ➔ testException3() 0 4 1
A hp$0 ➔ testComposite() 0 29 1
A hp$0 ➔ testException2() 0 4 1
A hp$0 ➔ testException1() 0 4 1
testException3() 0 4 ?
testComposite() 0 29 ?
setUp() 0 111 ?
A hp$0 ➔ extendTypeForName() 0 5 1
B hp$0 ➔ setUp() 0 111 1
1
<?php
2
3
namespace TheCodingMachine\GraphQL\Controllers\Mappers;
4
5
use GraphQL\Type\Definition\InputType;
6
use GraphQL\Type\Definition\OutputType;
7
use GraphQL\Type\Definition\Type;
8
use PHPUnit\Framework\TestCase;
9
use TheCodingMachine\GraphQL\Controllers\AbstractQueryProviderTest;
10
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject;
11
use TheCodingMachine\GraphQL\Controllers\TypeMappingException;
12
use GraphQL\Type\Definition\InputObjectType;
13
use GraphQL\Type\Definition\ObjectType;
14
use TheCodingMachine\GraphQL\Controllers\Types\MutableObjectType;
15
16
class CompositeTypeMapperTest extends AbstractQueryProviderTest
17
{
18
    /**
19
     * @var CompositeTypeMapper
20
     */
21
    protected $composite;
22
23
    public function setUp()
24
    {
25
        $typeMapper1 = new class() implements TypeMapperInterface {
26
            public function mapClassToType(string $className, ?OutputType $subType, RecursiveTypeMapperInterface $recursiveTypeMapper): MutableObjectType
27
            {
28
                if ($className === TestObject::class) {
29
                    return new MutableObjectType([
30
                        'name'    => 'TestObject',
31
                        'fields'  => [
32
                            'test'   => Type::string(),
33
                        ],
34
                    ]);
35
                } else {
36
                    throw TypeMappingException::createFromType(TestObject::class);
0 ignored issues
show
Bug introduced by
TheCodingMachine\GraphQL...tures\TestObject::class of type string is incompatible with the type phpDocumentor\Reflection\Type expected by parameter $type of TheCodingMachine\GraphQL...ption::createFromType(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

36
                    throw TypeMappingException::createFromType(/** @scrutinizer ignore-type */ TestObject::class);
Loading history...
37
                }
38
            }
39
40
            public function mapClassToInputType(string $className, RecursiveTypeMapperInterface $recursiveTypeMapper): InputObjectType
41
            {
42
                if ($className === TestObject::class) {
43
                    return new InputObjectType([
44
                        'name'    => 'TestObject',
45
                        'fields'  => [
46
                            'test'   => Type::string(),
47
                        ],
48
                    ]);
49
                } else {
50
                    throw TypeMappingException::createFromType(TestObject::class);
0 ignored issues
show
Bug introduced by
TheCodingMachine\GraphQL...tures\TestObject::class of type string is incompatible with the type phpDocumentor\Reflection\Type expected by parameter $type of TheCodingMachine\GraphQL...ption::createFromType(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

50
                    throw TypeMappingException::createFromType(/** @scrutinizer ignore-type */ TestObject::class);
Loading history...
51
                }
52
            }
53
54
            public function canMapClassToType(string $className): bool
55
            {
56
                return $className === TestObject::class;
57
            }
58
59
            public function canMapClassToInputType(string $className): bool
60
            {
61
                return $className === TestObject::class;
62
            }
63
64
            /**
65
             * Returns the list of classes that have matching input GraphQL types.
66
             *
67
             * @return string[]
68
             */
69
            public function getSupportedClasses(): array
70
            {
71
                return [TestObject::class];
72
            }
73
74
            /**
75
             * Returns a GraphQL type by name (can be either an input or output type)
76
             *
77
             * @param string $typeName The name of the GraphQL type
78
             * @param RecursiveTypeMapperInterface $recursiveTypeMapper
79
             * @return Type&(InputType|OutputType)
80
             */
81
            public function mapNameToType(string $typeName, RecursiveTypeMapperInterface $recursiveTypeMapper): Type
82
            {
83
                switch ($typeName) {
84
                    case 'TestObject':
85
                        return new MutableObjectType([
86
                            'name'    => 'TestObject',
87
                            'fields'  => [
88
                                'test'   => Type::string(),
89
                            ],
90
                        ]);
91
                    default:
92
                        throw CannotMapTypeException::createForName($typeName);
93
                }
94
            }
95
96
            /**
97
             * Returns true if this type mapper can map the $typeName GraphQL name to a GraphQL type.
98
             *
99
             * @param string $typeName The name of the GraphQL type
100
             * @return bool
101
             */
102
            public function canMapNameToType(string $typeName): bool
103
            {
104
                return $typeName === 'TestObject';
105
            }
106
107
            public function canExtendTypeForClass(string $className, MutableObjectType $type, RecursiveTypeMapperInterface $recursiveTypeMapper): bool
108
            {
109
                return false;
110
            }
111
112
            public function extendTypeForClass(string $className, MutableObjectType $type, RecursiveTypeMapperInterface $recursiveTypeMapper): void
113
            {
114
                throw CannotMapTypeException::createForExtendType($className, $type);
115
            }
116
117
            public function canExtendTypeForName(string $typeName, MutableObjectType $type, RecursiveTypeMapperInterface $recursiveTypeMapper): bool
118
            {
119
                return true;
120
            }
121
122
            public function extendTypeForName(string $typeName, MutableObjectType $type, RecursiveTypeMapperInterface $recursiveTypeMapper): void
123
            {
124
                $type->addFields(function() {
125
                    return [
126
                        'test2' => Type::int()
127
                    ];
128
                });
129
                //throw CannotMapTypeException::createForExtendName($typeName, $type);
130
            }
131
        };
132
133
        $this->composite = new CompositeTypeMapper([$typeMapper1]);
134
    }
135
136
137
    public function testComposite(): void
138
    {
139
        $this->assertTrue($this->composite->canMapClassToType(TestObject::class));
140
        $this->assertFalse($this->composite->canMapClassToType(\Exception::class));
141
        $this->assertTrue($this->composite->canMapClassToInputType(TestObject::class));
142
        $this->assertFalse($this->composite->canMapClassToInputType(\Exception::class));
143
        $this->assertInstanceOf(ObjectType::class, $this->composite->mapClassToType(TestObject::class, null, $this->getTypeMapper()));
144
        $this->assertInstanceOf(InputObjectType::class, $this->composite->mapClassToInputType(TestObject::class, $this->getTypeMapper()));
145
        $this->assertSame([TestObject::class], $this->composite->getSupportedClasses());
146
        $this->assertInstanceOf(ObjectType::class, $this->composite->mapNameToType('TestObject', $this->getTypeMapper()));
147
        $this->assertTrue($this->composite->canMapNameToType('TestObject'));
148
        $this->assertFalse($this->composite->canMapNameToType('NotExists'));
149
150
151
        $type = new MutableObjectType([
152
            'name'    => 'TestObject',
153
            'fields'  => [
154
                'test'   => Type::string(),
155
            ],
156
        ]);
157
158
        $this->assertFalse($this->composite->canExtendTypeForClass('foo', $type, $this->getTypeMapper()));
159
        $this->assertTrue($this->composite->canExtendTypeForName('foo', $type, $this->getTypeMapper()));
160
161
162
        $this->composite->extendTypeForName('foo', $type, $this->getTypeMapper());
163
164
        $type->freeze();
165
        $this->assertCount(2, $type->getFields());
166
    }
167
168
    public function testException1(): void
169
    {
170
        $this->expectException(CannotMapTypeException::class);
171
        $this->composite->mapClassToType(\Exception::class, null, $this->getTypeMapper());
172
    }
173
174
    public function testException2(): void
175
    {
176
        $this->expectException(CannotMapTypeException::class);
177
        $this->composite->mapClassToInputType(\Exception::class, $this->getTypeMapper());
178
    }
179
180
    public function testException3(): void
181
    {
182
        $this->expectException(CannotMapTypeException::class);
183
        $this->composite->mapNameToType('NotExists', $this->getTypeMapper());
184
    }
185
}
186