Skip to content

Commit ad27e81

Browse files
committed
GraphQL::type modifier support rebing#617
1 parent ffe0cb9 commit ad27e81

File tree

3 files changed

+219
-0
lines changed

3 files changed

+219
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
- Support Laravel 7 [\#597 / exodusanto](https://github.com/rebing/graphql-laravel/pull/597)
1111
- Add support for custom authorization message [\#578 / Sh1d0w](https://github.com/rebing/graphql-laravel/pull/578)
1212
- Add support for macros on the GraphQL service/facade [\#592 / stevelacey](https://github.com/rebing/graphql-laravel/pull/592)
13+
- Add support for modifiers to `GraphQL::type` [\#621 / stevelacey](https://github.com/rebing/graphql-laravel/pull/621)
1314
### Fixed
1415
- Fix the infinite loop as well as sending the correct matching input data to the rule-callback [\#579 / crissi](https://github.com/rebing/graphql-laravel/pull/579)
1516
- Fix selecting not the correct columns for interface fields [\#607 / illambo](https://github.com/rebing/graphql-laravel/pull/607)

src/GraphQL.php

+30
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use GraphQL\Type\Schema;
1717
use Illuminate\Contracts\Container\Container;
1818
use Illuminate\Contracts\Debug\ExceptionHandler;
19+
use Illuminate\Support\Str;
1920
use Illuminate\Support\Traits\Macroable;
2021
use Rebing\GraphQL\Error\AuthorizationError;
2122
use Rebing\GraphQL\Error\ValidationError;
@@ -175,6 +176,35 @@ public function addType($class, string $name = null): void
175176

176177
public function type(string $name, bool $fresh = false): Type
177178
{
179+
$modifiers = [];
180+
181+
while (true) {
182+
if (Str::endsWith($name, '!')) {
183+
$name = Str::replaceLast('!', '', $name);
184+
array_unshift($modifiers, 'nonNull');
185+
} elseif (preg_match('/^\[.+\]$/', $name)) {
186+
$name = substr($name, 1, -1);
187+
array_unshift($modifiers, 'listOf');
188+
} else {
189+
break;
190+
}
191+
}
192+
193+
$type = $this->getType($name, $fresh);
194+
195+
foreach ($modifiers as $modifier) {
196+
$type = Type::$modifier($type);
197+
}
198+
199+
return $type;
200+
}
201+
202+
public function getType(string $name, bool $fresh = false): Type
203+
{
204+
if (in_array($name, Type::getStandardTypes())) {
205+
return Type::getStandardTypes()[$name];
206+
}
207+
178208
if (! isset($this->types[$name])) {
179209
$error = "Type $name not found.";
180210

tests/Unit/GraphQLTest.php

+188
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace Rebing\GraphQL\Tests\Unit;
66

77
use GraphQL\Error\Error;
8+
use GraphQL\Type\Definition\ListOfType;
9+
use GraphQL\Type\Definition\NonNull;
810
use GraphQL\Type\Definition\ObjectType;
911
use GraphQL\Type\Definition\Type;
1012
use GraphQL\Type\Schema;
@@ -123,6 +125,192 @@ public function testWrongType(): void
123125
GraphQL::type('ExampleWrong');
124126
}
125127

128+
/**
129+
* Test nonNull type.
130+
*/
131+
public function testNonNullType(): void
132+
{
133+
/** @var NonNull */
134+
$type = GraphQL::type('Example!');
135+
$this->assertInstanceOf(NonNull::class, $type);
136+
137+
/** @var NonNull */
138+
$typeOther = GraphQL::type('Example!');
139+
$this->assertTrue($type->getWrappedType() === $typeOther->getWrappedType());
140+
141+
/** @var NonNull */
142+
$typeOther = GraphQL::type('Example!', true);
143+
$this->assertFalse($type->getWrappedType() === $typeOther->getWrappedType());
144+
}
145+
146+
/**
147+
* Test listOf type.
148+
*/
149+
public function testListOfType(): void
150+
{
151+
/** @var ListOfType */
152+
$type = GraphQL::type('[Example]');
153+
$this->assertInstanceOf(ListOfType::class, $type);
154+
155+
/** @var ListOfType */
156+
$typeOther = GraphQL::type('[Example]');
157+
$this->assertTrue($type->getWrappedType() === $typeOther->getWrappedType());
158+
159+
/** @var ListOfType */
160+
$typeOther = GraphQL::type('[Example]', true);
161+
$this->assertFalse($type->getWrappedType() === $typeOther->getWrappedType());
162+
}
163+
164+
/**
165+
* Test listOf nonNull type.
166+
*/
167+
public function testListOfNonNullType(): void
168+
{
169+
/** @var ListOfType */
170+
$type = GraphQL::type('[Example!]');
171+
$this->assertInstanceOf(ListOfType::class, $type);
172+
$this->assertInstanceOf(NonNull::class, $type->getWrappedType());
173+
174+
/** @var ListOfType */
175+
$typeOther = GraphQL::type('[Example!]');
176+
$this->assertTrue($type->getWrappedType(true) === $typeOther->getWrappedType(true));
177+
178+
/** @var ListOfType */
179+
$typeOther = GraphQL::type('[Example!]', true);
180+
$this->assertFalse($type->getWrappedType(true) === $typeOther->getWrappedType(true));
181+
}
182+
183+
/**
184+
* Test nonNull listOf nonNull type.
185+
*/
186+
public function testNonNullListOfNonNullType(): void
187+
{
188+
/** @var NonNull */
189+
$type = GraphQL::type('[Example!]!');
190+
/** @var ListOfType */
191+
$wrappedType = $type->getWrappedType();
192+
193+
$this->assertInstanceOf(NonNull::class, $type);
194+
$this->assertInstanceOf(ListOfType::class, $wrappedType);
195+
$this->assertInstanceOf(NonNull::class, $wrappedType->getWrappedType());
196+
197+
/** @var NonNull */
198+
$typeOther = GraphQL::type('[Example!]!');
199+
$this->assertTrue($type->getWrappedType(true) === $typeOther->getWrappedType(true));
200+
201+
/** @var NonNull */
202+
$typeOther = GraphQL::type('[Example!]!', true);
203+
$this->assertFalse($type->getWrappedType(true) === $typeOther->getWrappedType(true));
204+
}
205+
206+
/**
207+
* Test malformed listOf with no leading bracket.
208+
*/
209+
public function testMalformedListOfWithNoLeadingBracket(): void
210+
{
211+
$this->expectException(TypeNotFound::class);
212+
$this->expectExceptionMessage('Type Example] not found.');
213+
GraphQL::type('Example]');
214+
}
215+
216+
/**
217+
* Test malformed listOf with no trailing bracket.
218+
*/
219+
public function testMalformedListOfWithNoTrailingBracket(): void
220+
{
221+
$this->expectException(TypeNotFound::class);
222+
$this->expectExceptionMessage('Type [Example not found.');
223+
GraphQL::type('[Example');
224+
}
225+
226+
/**
227+
* Test malformed nonNull listOf with no trailing bracket.
228+
*/
229+
public function testMalformedNonNullListOfWithNoTrailingBracket(): void
230+
{
231+
$this->expectException(TypeNotFound::class);
232+
$this->expectExceptionMessage('Type [Example not found.');
233+
GraphQL::type('[Example!');
234+
}
235+
236+
/**
237+
* Test empty listOf.
238+
*/
239+
public function testEmptyListOf(): void
240+
{
241+
$this->expectException(TypeNotFound::class);
242+
$this->expectExceptionMessage('Type [] not found.');
243+
GraphQL::type('[]');
244+
}
245+
246+
/**
247+
* Test empty.
248+
*/
249+
public function testEmptyNonNull(): void
250+
{
251+
$this->expectException(TypeNotFound::class);
252+
$this->expectExceptionMessage('Type not found.');
253+
GraphQL::type('!');
254+
}
255+
256+
/**
257+
* Test standard types.
258+
*/
259+
public function testStandardTypes(): void
260+
{
261+
$standardTypes = Type::getStandardTypes();
262+
263+
foreach ($standardTypes as $standardType) {
264+
$type = GraphQL::type($standardType->name);
265+
$this->assertTrue($standardType === $type);
266+
267+
$typeOther = GraphQL::type($type->name);
268+
$this->assertTrue($type === $typeOther);
269+
270+
$typeOther = GraphQL::type($type->name, true);
271+
$this->assertTrue($type === $typeOther);
272+
}
273+
}
274+
275+
/**
276+
* Test standard type modifiers.
277+
*/
278+
public function testStandardTypeModifiers(): void
279+
{
280+
$standardTypes = Type::getStandardTypes();
281+
282+
foreach ($standardTypes as $standardType) {
283+
/** @var NonNull */
284+
$type = GraphQL::type("$standardType->name!");
285+
286+
$this->assertInstanceOf(NonNull::class, $type);
287+
$this->assertTrue($type->getWrappedType() === $standardType);
288+
289+
/** @var ListOfType */
290+
$type = GraphQL::type("[$standardType->name]");
291+
292+
$this->assertInstanceOf(ListOfType::class, $type);
293+
$this->assertTrue($type->getWrappedType() === $standardType);
294+
295+
/** @var ListOfType */
296+
$type = GraphQL::type("[$standardType->name!]");
297+
298+
$this->assertInstanceOf(ListOfType::class, $type);
299+
$this->assertInstanceOf(NonNull::class, $type->getWrappedType());
300+
$this->assertTrue($type->getWrappedType(true) === $standardType);
301+
302+
/** @var NonNull */
303+
$type = GraphQL::type("[$standardType->name!]!");
304+
/** @var ListOfType */
305+
$wrappedType = $type->getWrappedType();
306+
307+
$this->assertInstanceOf(NonNull::class, $type);
308+
$this->assertInstanceOf(ListOfType::class, $wrappedType);
309+
$this->assertInstanceOf(NonNull::class, $wrappedType->getWrappedType());
310+
$this->assertTrue($type->getWrappedType(true) === $standardType);
311+
}
312+
}
313+
126314
/**
127315
* Test objectType.
128316
*/

0 commit comments

Comments
 (0)