Skip to content

Commit d3305d4

Browse files
Make sure that types are frozen before creating the schema
1 parent 2b84d38 commit d3305d4

3 files changed

Lines changed: 81 additions & 9 deletions

File tree

src/SchemaFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@ classBoundCache: $classBoundCache,
538538

539539
$aggregateQueryProvider = new AggregateQueryProvider($queryProviders);
540540

541+
$typeRegistry->finalizeTypes();
542+
541543
return new Schema($aggregateQueryProvider, $recursiveTypeMapper, $typeResolver, $topRootTypeMapper, $this->schemaConfig);
542544
}
543545

src/TypeRegistry.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,15 @@ public function getMutableInterface(string $typeName): MutableInterface
9797

9898
return $type;
9999
}
100+
101+
public function finalizeTypes(): void
102+
{
103+
foreach ($this->types as $type) {
104+
if (! ($type instanceof MutableObjectType) && ! ($type instanceof MutableInterfaceType)) {
105+
continue;
106+
}
107+
108+
$type->freeze();
109+
}
110+
}
100111
}

tests/TypeRegistryTest.php

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace TheCodingMachine\GraphQLite;
46

57
use GraphQL\Type\Definition\ObjectType;
8+
use PHPUnit\Framework\Attributes\Test;
69
use PHPUnit\Framework\TestCase;
10+
use TheCodingMachine\GraphQLite\Types\MutableInterfaceType;
711
use TheCodingMachine\GraphQLite\Types\MutableObjectType;
812

913
class TypeRegistryTest extends TestCase
1014
{
11-
1215
public function testRegisterTypeException(): void
1316
{
1417
$type = new ObjectType([
1518
'name' => 'Foo',
16-
'fields' => function() {return [];}
19+
'fields' => static function () {
20+
return [];
21+
},
1722
]);
1823

1924
$registry = new TypeRegistry();
@@ -27,7 +32,9 @@ public function testGetType(): void
2732
{
2833
$type = new ObjectType([
2934
'name' => 'Foo',
30-
'fields' => function() {return [];}
35+
'fields' => static function () {
36+
return [];
37+
},
3138
]);
3239

3340
$registry = new TypeRegistry();
@@ -43,26 +50,31 @@ public function testHasType(): void
4350
{
4451
$type = new ObjectType([
4552
'name' => 'Foo',
46-
'fields' => function() {return [];}
53+
'fields' => static function () {
54+
return [];
55+
},
4756
]);
4857

4958
$registry = new TypeRegistry();
5059
$registry->registerType($type);
5160

5261
$this->assertTrue($registry->hasType('Foo'));
5362
$this->assertFalse($registry->hasType('Bar'));
54-
5563
}
5664

5765
public function testGetMutableObjectType(): void
5866
{
5967
$type = new MutableObjectType([
6068
'name' => 'Foo',
61-
'fields' => function() {return [];}
69+
'fields' => static function () {
70+
return [];
71+
},
6272
]);
6373
$type2 = new ObjectType([
6474
'name' => 'FooBar',
65-
'fields' => function() {return [];}
75+
'fields' => static function () {
76+
return [];
77+
},
6678
]);
6779

6880
$registry = new TypeRegistry();
@@ -79,11 +91,15 @@ public function testGetMutableInterface(): void
7991
{
8092
$type = new MutableObjectType([
8193
'name' => 'Foo',
82-
'fields' => function() {return [];}
94+
'fields' => static function () {
95+
return [];
96+
},
8397
]);
8498
$type2 = new ObjectType([
8599
'name' => 'FooBar',
86-
'fields' => function() {return [];}
100+
'fields' => static function () {
101+
return [];
102+
},
87103
]);
88104

89105
$registry = new TypeRegistry();
@@ -95,4 +111,47 @@ public function testGetMutableInterface(): void
95111
$this->expectException(GraphQLRuntimeException::class);
96112
$this->assertSame($type, $registry->getMutableInterface('FooBar'));
97113
}
114+
115+
public function testFinalizeTypesFreezesMutableTypesOnly(): void
116+
{
117+
$mutableObjectType = $this->getMockBuilder(MutableObjectType::class)
118+
->setConstructorArgs([
119+
[
120+
'name' => 'Foo',
121+
'fields' => static function () {
122+
return [];
123+
},
124+
],
125+
])
126+
->onlyMethods(['freeze'])
127+
->getMock();
128+
129+
$mutableObjectType->expects($this->once())
130+
->method('freeze');
131+
132+
$mutableInterfaceType = $this->getMockBuilder(MutableInterfaceType::class)
133+
->setConstructorArgs([
134+
[
135+
'name' => 'Bar',
136+
'fields' => static fn () => [],
137+
],
138+
])
139+
->onlyMethods(['freeze'])
140+
->getMock();
141+
142+
$mutableInterfaceType->expects($this->once())
143+
->method('freeze');
144+
145+
$regularObjectType = new ObjectType([
146+
'name' => 'Baz',
147+
'fields' => static fn () => [],
148+
]);
149+
150+
$registry = new TypeRegistry();
151+
$registry->registerType($mutableObjectType);
152+
$registry->registerType($mutableInterfaceType);
153+
$registry->registerType($regularObjectType);
154+
155+
$registry->finalizeTypes();
156+
}
98157
}

0 commit comments

Comments
 (0)