Skip to content

Commit 8b7628d

Browse files
committed
Improving test coverage
1 parent 2d9b835 commit 8b7628d

File tree

5 files changed

+175
-10
lines changed

5 files changed

+175
-10
lines changed

phpstan.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ parameters:
2525
message: '#Parameter \#2 \$subType of method .* expects#'
2626
path: src/Mappers/Root/IteratorTypeMapper.php
2727
-
28-
message: '#Array .* does not accept GraphQL\\Type\\Definition\\InterfaceType\|GraphQL\\Type\\Definition\\ObjectType.*#'
28+
message: '#Method TheCodingMachine\\GraphQLite\\Mappers\\StaticTypeMapper::castOutputTypeToMutable() should return TheCodingMachine\\GraphQLite\\Mappers\\Proxys\\MutableInterfaceTypeAdapter\|TheCodingMachine\\GraphQLite\\Mappers\\Proxys\\MutableObjectTypeAdapter but returns GraphQL\\Type\\Definition\\InterfaceType|GraphQL\\Type\\Definition\\ObjectType.#'
2929
path: src/Mappers/StaticTypeMapper.php
3030
-
3131
message: '#Unreachable statement - code above always terminates.#'

src/Mappers/Proxys/MutableAdapterTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ trait MutableAdapterTrait
3030
private $className;
3131

3232
/** @var string */
33-
private $status;
33+
private $status = MutableInterface::STATUS_PENDING;
3434

3535
/** @var array<callable> */
3636
private $fieldsCallables = [];

src/Mappers/StaticTypeMapper.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,7 @@ final class StaticTypeMapper implements TypeMapperInterface
3737
public function setTypes(array $types): void
3838
{
3939
foreach ($types as $className => $type) {
40-
if ($type instanceof ObjectType && ! $type instanceof MutableObjectType) {
41-
$type = new MutableObjectTypeAdapter($type);
42-
} elseif ($type instanceof InterfaceType && ! $type instanceof MutableInterfaceType) {
43-
$type = new MutableInterfaceTypeAdapter($type);
44-
}
40+
$type = $this->castOutputTypeToMutable($type);
4541
$this->types[$className] = $type;
4642
}
4743
}
@@ -66,17 +62,37 @@ public function setInputTypes(array $inputTypes): void
6662
* An array containing ObjectType or ResolvableMutableInputInterface instances that are not mapped by default to any class.
6763
* ObjectType not linked to any type by default will have to be accessed using the outputType attribute of the annotations.
6864
*
69-
* @param array<int,Type> $types
65+
* @param array<int,Type&((ResolvableMutableInputInterface&InputObjectType)|MutableObjectType|MutableInterfaceType)> $types
7066
*/
7167
public function setNotMappedTypes(array $types): void
7268
{
73-
$this->notMappedTypes = array_reduce($types, static function ($result, Type $type) {
69+
$this->notMappedTypes = array_reduce($types, function ($result, Type $type) {
70+
if ($type instanceof ObjectType || $type instanceof InterfaceType) {
71+
$type = $this->castOutputTypeToMutable($type);
72+
}
73+
7474
$result[$type->name] = $type;
7575

7676
return $result;
7777
}, []);
7878
}
7979

80+
/**
81+
* @param ObjectType|InterfaceType $type
82+
*
83+
* @return MutableInterfaceTypeAdapter|MutableObjectTypeAdapter
84+
*/
85+
private function castOutputTypeToMutable($type)
86+
{
87+
if ($type instanceof ObjectType && ! $type instanceof MutableObjectType) {
88+
return new MutableObjectTypeAdapter($type);
89+
}
90+
if ($type instanceof InterfaceType && ! $type instanceof MutableInterfaceType) {
91+
return new MutableInterfaceTypeAdapter($type);
92+
}
93+
return $type;
94+
}
95+
8096
/**
8197
* Returns true if this type mapper can map the $className FQCN to a GraphQL type.
8298
*/
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
3+
namespace TheCodingMachine\GraphQLite\Mappers\Proxys;
4+
5+
use GraphQL\Type\Definition\InterfaceType;
6+
use GraphQL\Type\Definition\ObjectType;
7+
use GraphQL\Type\Definition\Type;
8+
use PHPUnit\Framework\TestCase;
9+
use RuntimeException;
10+
use TheCodingMachine\GraphQLite\Fixtures\StaticTypeMapper\Types\TestLegacyObject;
11+
use TheCodingMachine\GraphQLite\Types\MutableObjectType;
12+
use TheCodingMachine\GraphQLite\Types\NoFieldsException;
13+
14+
class MutableObjectTypeAdapterTest extends TestCase
15+
{
16+
17+
private function getAdapter(): MutableObjectTypeAdapter
18+
{
19+
$type = new ObjectType([
20+
'name' => 'TestLegacyObject',
21+
'fields' => [
22+
'foo' => [
23+
'type' =>Type::int(),
24+
'resolve' => function(TestLegacyObject $source) {
25+
return $source->getFoo();
26+
}
27+
]
28+
]
29+
]);
30+
31+
$adapter = new MutableObjectTypeAdapter($type);
32+
33+
return $adapter;
34+
}
35+
public function testAdapter()
36+
{
37+
$type = new ObjectType([
38+
'name' => 'TestLegacyObject',
39+
'fields' => [
40+
'foo' => [
41+
'type' =>Type::int(),
42+
'resolve' => function(TestLegacyObject $source) {
43+
return $source->getFoo();
44+
}
45+
]
46+
]
47+
]);
48+
49+
$adapter = new MutableObjectTypeAdapter($type);
50+
51+
$adapter->assertValid();
52+
53+
$adapter->freeze();
54+
$this->assertSame($type->getInterfaces(), $adapter->getInterfaces());
55+
$this->assertSame($type->jsonSerialize(), $adapter->jsonSerialize());
56+
$this->assertSame($type->getField('foo'), $adapter->getField('foo'));
57+
$this->assertSame($type->hasField('foo'), $adapter->hasField('foo'));
58+
$interfaceType = new InterfaceType(['name' => 'Foo']);
59+
$this->assertSame($type->implementsInterface($interfaceType), $adapter->implementsInterface($interfaceType));
60+
61+
}
62+
63+
public function testGetStatus(): void
64+
{
65+
$type = $this->getAdapter();
66+
67+
$this->assertSame(MutableObjectType::STATUS_PENDING, $type->getStatus());
68+
$type->freeze();
69+
$this->assertSame(MutableObjectType::STATUS_FROZEN, $type->getStatus());
70+
}
71+
72+
public function testAddFields(): void
73+
{
74+
$type = $this->getAdapter();
75+
76+
$type->addFields(function() {
77+
return [
78+
'test' => Type::int(),
79+
'test2' => Type::string(),
80+
];
81+
});
82+
$type->addFields(function() {
83+
return [
84+
'test3' => Type::int(),
85+
];
86+
});
87+
$type->freeze();
88+
$fields = $type->getFields();
89+
$this->assertCount(4, $fields);
90+
$this->assertArrayHasKey('test', $fields);
91+
$this->assertSame(Type::int(), $fields['test']->getType());
92+
}
93+
94+
public function testHasFieldError(): void
95+
{
96+
$type = $this->getAdapter();
97+
98+
$this->expectException(RuntimeException::class);
99+
$type->hasField('test');
100+
}
101+
102+
public function testGetFieldError(): void
103+
{
104+
$type = $this->getAdapter();
105+
106+
$this->expectException(RuntimeException::class);
107+
$type->getField('test');
108+
}
109+
110+
public function testGetFieldsError(): void
111+
{
112+
$type = $this->getAdapter();
113+
114+
$this->expectException(RuntimeException::class);
115+
$type->getFields();
116+
}
117+
118+
public function testAddFieldsError(): void
119+
{
120+
$type = $this->getAdapter();
121+
122+
$type->freeze();
123+
$this->expectException(RuntimeException::class);
124+
$type->addFields(function() {});
125+
}
126+
127+
public function testNoFieldsType(): void
128+
{
129+
$type = new ObjectType([
130+
'name' => 'TestLegacyObject',
131+
'fields' => [
132+
133+
]
134+
]);
135+
136+
$adapter = new MutableObjectTypeAdapter($type);
137+
138+
$adapter->freeze();
139+
$this->expectException(NoFieldsException::class);
140+
$this->expectExceptionMessage('The GraphQL object type "TestLegacyObject" has no fields defined. Please check that some fields are defined (using the @Field annotation). If some fields are defined, please check that at least one is visible to the current user.');
141+
$adapter->getFields();
142+
}
143+
144+
}

tests/Mappers/StaticTypeMapperTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use GraphQL\Error\Debug;
66
use GraphQL\GraphQL;
7+
use GraphQL\Type\Definition\InterfaceType;
78
use GraphQL\Type\Definition\StringType;
89
use GraphQL\Type\Definition\Type;
910
use Symfony\Component\Cache\Adapter\ArrayAdapter;
@@ -150,7 +151,11 @@ public function testEndToEnd(): void
150151
}
151152
]
152153
]
153-
])
154+
]),
155+
]);
156+
157+
$staticTypeMapper->setNotMappedTypes([
158+
new InterfaceType(['name' => 'FooInterface'])
154159
]);
155160

156161
// Register the static type mapper in your application using the SchemaFactory instance

0 commit comments

Comments
 (0)