Skip to content

Commit 24f9126

Browse files
authored
Merge pull request #9 from mcg-web/custom-scalar
Add custom scalar type config
2 parents fa42d67 + aef2be9 commit 24f9126

File tree

8 files changed

+153
-6
lines changed

8 files changed

+153
-6
lines changed

src/Generator/AbstractTypeGenerator.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@ abstract class AbstractTypeGenerator extends AbstractClassGenerator
1919
{
2020
const DEFAULT_CLASS_NAMESPACE = 'Overblog\\CG\\GraphQLGenerator\\__Schema__';
2121

22+
protected static $closureTemplate = <<<EOF
23+
function (%s) <closureUseStatements>{
24+
<spaces><spaces>return %s;
25+
<spaces>}
26+
EOF;
27+
2228
private static $typeSystems = [
2329
'object' => 'GraphQL\\Type\\Definition\\ObjectType',
2430
'interface' => 'GraphQL\\Type\\Definition\\InterfaceType',
2531
'enum' => 'GraphQL\\Type\\Definition\\EnumType',
2632
'union' => 'GraphQL\\Type\\Definition\\UnionType',
2733
'input-object' => 'GraphQL\\Type\\Definition\\InputObjectType',
34+
'custom-scalar' => 'GraphQL\\Type\\Definition\\CustomScalarType',
2835
];
2936

3037

@@ -161,7 +168,7 @@ protected function callableCallbackFromArrayValue(array $value, $key, $argDefini
161168
return $default;
162169
}
163170

164-
$code = 'function (%s) <closureUseStatements>{ return %s; }';
171+
$code = static::$closureTemplate;
165172

166173
if (is_callable($value[$key])) {
167174
$func = $value[$key];
@@ -244,7 +251,7 @@ protected function resolveTypeCode($alias)
244251
protected function resolveTypesCode(array $values, $key)
245252
{
246253
if (isset($values[$key])) {
247-
$types = sprintf('function () <closureUseStatements>{ return %s; }', $this->types2String($values[$key]));
254+
$types = $this->types2String($values[$key]);
248255
} else {
249256
$types = '[]';
250257
}

src/Generator/TypeGenerator.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ class TypeGenerator extends AbstractTypeGenerator
1515
{
1616
protected function generateOutputFields(array $config)
1717
{
18-
return $this->processFromArray($config['fields'], 'OutputField');
18+
return sprintf(static::$closureTemplate, '', $this->processFromArray($config['fields'], 'OutputField'));
1919
}
2020

2121
protected function generateInputFields(array $config)
2222
{
23-
return $this->processFromArray($config['fields'], 'InputField');
23+
return sprintf(static::$closureTemplate, '', $this->processFromArray($config['fields'], 'InputField'));
2424
}
2525

2626
protected function generateArgs(array $fields)
@@ -63,7 +63,7 @@ protected function generateType(array $value)
6363
$type = 'null';
6464

6565
if (isset($value['type'])) {
66-
$type = sprintf('function () <closureUseStatements>{ return %s; }', $this->typeAlias2String($value['type']));
66+
$type = sprintf('%s', $this->typeAlias2String($value['type']));
6767
}
6868

6969
return $type;
@@ -123,4 +123,31 @@ protected function generateComplexity(array $value)
123123
{
124124
return $this->callableCallbackFromArrayValue($value, 'complexity', '$childrenComplexity, $args = []');
125125
}
126+
127+
/**
128+
* @param array $value
129+
* @return string
130+
*/
131+
protected function generateSerialize(array $value)
132+
{
133+
return $this->callableCallbackFromArrayValue($value, 'serialize', '$value');
134+
}
135+
136+
/**
137+
* @param array $value
138+
* @return string
139+
*/
140+
protected function generateParseValue(array $value)
141+
{
142+
return $this->callableCallbackFromArrayValue($value, 'parseValue', '$value');
143+
}
144+
145+
/**
146+
* @param array $value
147+
* @return string
148+
*/
149+
protected function generateParseLiteral(array $value)
150+
{
151+
return $this->callableCallbackFromArrayValue($value, 'parseLiteral', '$value');
152+
}
126153
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
<spaces>'name' => <name>,
3+
<spaces>'serialize' => <serialize>,
4+
<spaces>'parseValue' => <parseValue>,
5+
<spaces>'parseLiteral' => <parseLiteral>,
6+
]

tests/DateTimeType.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the OverblogGraphQLPhpGenerator package.
5+
*
6+
* (c) Overblog <http://github.com/overblog/>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Overblog\GraphQLGenerator\Tests;
13+
14+
use GraphQL\Language\AST\Node;
15+
16+
class DateTimeType
17+
{
18+
/**
19+
* @param \DateTime $value
20+
*
21+
* @return string
22+
*/
23+
public static function serialize(\DateTime $value)
24+
{
25+
return $value->format('Y-m-d H:i:s');
26+
}
27+
28+
/**
29+
* @param mixed $value
30+
*
31+
* @return mixed
32+
*/
33+
public static function parseValue($value)
34+
{
35+
return new \DateTime($value);
36+
}
37+
38+
/**
39+
* @param Node $valueNode
40+
*
41+
* @return string
42+
*/
43+
public static function parseLiteral($valueNode)
44+
{
45+
return new \DateTime($valueNode->value);
46+
}
47+
}

tests/Resolver.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,9 @@ public static function getDroid($root, $args)
8686
$droids = StarWarsData::droids();
8787
return isset($droids[$args['id']]) ? $droids[$args['id']] : null;
8888
}
89+
90+
public static function getDateTime($root, $args)
91+
{
92+
return isset($args['dateTime']) ? $args['dateTime'] : new \DateTime('2016-11-28 12:00:00');
93+
}
8994
}

tests/StarWarsIntrospectionTest.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public function testAllowsQueryingTheSchemaForTypes()
3636
['name' => 'String'],
3737
['name' => 'Human'],
3838
['name' => 'Droid'],
39+
['name' => 'DateTime'],
3940
['name' => '__Schema'],
4041
['name' => '__Type'],
4142
['name' => '__TypeKind'],
@@ -310,7 +311,7 @@ public function testAllowsQueryingTheSchemaForFieldArgs()
310311
'name' => 'hero',
311312
'args' => [
312313
[
313-
'defaultValue' => null,
314+
'defaultValue' => 'null',
314315
'description' => 'If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode.',
315316
'name' => 'episode',
316317
'type' => [
@@ -358,6 +359,21 @@ public function testAllowsQueryingTheSchemaForFieldArgs()
358359
],
359360
],
360361
],
362+
[
363+
'name' => 'dateTime',
364+
'args' => [
365+
[
366+
'name' => 'dateTime',
367+
'description' => null,
368+
'type' => [
369+
'name' => 'DateTime',
370+
'kind' => 'SCALAR',
371+
'ofType' => null,
372+
],
373+
'defaultValue' => 'null',
374+
]
375+
],
376+
],
361377
],
362378
],
363379
],

tests/StarWarsQueryTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public function testCorrectlyIdentifiesR2D2AsTheHeroOfTheStarWarsSaga()
4242
];
4343
$this->assertValidQuery($query, $expected);
4444
}
45+
4546
public function testAllowsUsToQueryForTheIDAndFriendsOfR2D2()
4647
{
4748
$query = '
@@ -74,6 +75,7 @@ public function testAllowsUsToQueryForTheIDAndFriendsOfR2D2()
7475
];
7576
$this->assertValidQuery($query, $expected);
7677
}
78+
7779
// Nested Queries
7880
public function testAllowsUsToQueryForTheFriendsOfFriendsOfR2D2()
7981
{
@@ -130,6 +132,7 @@ public function testAllowsUsToQueryForTheFriendsOfFriendsOfR2D2()
130132
];
131133
$this->assertValidQuery($query, $expected);
132134
}
135+
133136
// Using IDs and query parameters to refetch objects
134137
public function testAllowsUsToQueryForLukeSkywalkerDirectlyUsingHisID()
135138
{
@@ -167,6 +170,7 @@ public function testGenericQueryToGetLukeSkywalkerById()
167170
];
168171
$this->assertValidQuery($query, $expected, $params);
169172
}
173+
170174
public function testGenericQueryToGetHanSoloById()
171175
{
172176
// Allows us to create a generic query, then use it to fetch Han Solo using his ID
@@ -187,6 +191,7 @@ public function testGenericQueryToGetHanSoloById()
187191
];
188192
$this->assertValidQuery($query, $expected, $params);
189193
}
194+
190195
public function testGenericQueryWithInvalidId()
191196
{
192197
// Allows us to create a generic query, then pass an invalid ID to get null back
@@ -205,6 +210,7 @@ public function testGenericQueryWithInvalidId()
205210
];
206211
$this->assertValidQuery($query, $expected, $params);
207212
}
213+
208214
// Using aliases to change the key in the response
209215
public function testLukeKeyAlias()
210216
{
@@ -223,6 +229,7 @@ public function testLukeKeyAlias()
223229
];
224230
$this->assertValidQuery($query, $expected);
225231
}
232+
226233
public function testTwoRootKeysAsAnAlias()
227234
{
228235
// Allows us to query for both Luke and Leia, using two root fields and an alias
@@ -246,6 +253,7 @@ public function testTwoRootKeysAsAnAlias()
246253
];
247254
$this->assertValidQuery($query, $expected);
248255
}
256+
249257
// Uses fragments to express more complex queries
250258
public function testQueryUsingDuplicatedContent()
251259
{
@@ -274,6 +282,7 @@ public function testQueryUsingDuplicatedContent()
274282
];
275283
$this->assertValidQuery($query, $expected);
276284
}
285+
277286
public function testUsingFragment()
278287
{
279288
// Allows us to use a fragment to avoid duplicating content
@@ -303,6 +312,7 @@ public function testUsingFragment()
303312
];
304313
$this->assertValidQuery($query, $expected);
305314
}
315+
306316
// Using __typename to find the type of an object
307317
public function testVerifyThatR2D2IsADroid()
308318
{
@@ -322,6 +332,7 @@ public function testVerifyThatR2D2IsADroid()
322332
];
323333
$this->assertValidQuery($query, $expected);
324334
}
335+
325336
public function testVerifyThatLukeIsHuman()
326337
{
327338
$query = '
@@ -340,4 +351,19 @@ public function testVerifyThatLukeIsHuman()
340351
];
341352
$this->assertValidQuery($query, $expected);
342353
}
354+
355+
public function testDateTime()
356+
{
357+
$query = '{ dateTime }';
358+
$expected = [
359+
'dateTime' => '2016-11-28 12:00:00',
360+
];
361+
$this->assertValidQuery($query, $expected);
362+
363+
$query = '{ dateTime(dateTime: "2016-01-18 23:00:00") }';
364+
$expected = [
365+
'dateTime' => '2016-01-18 23:00:00',
366+
];
367+
$this->assertValidQuery($query, $expected);
368+
}
343369
}

tests/starWarsSchema.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
---
2+
DateTime:
3+
type: custom-scalar
4+
config:
5+
serialize: ["Overblog\\GraphQLGenerator\\Tests\\DateTimeType", "serialize"]
6+
parseValue: ["Overblog\\GraphQLGenerator\\Tests\\DateTimeType", "parseValue"]
7+
parseLiteral: ["Overblog\\GraphQLGenerator\\Tests\\DateTimeType", "parseLiteral"]
8+
29
# Characters in the Star Wars trilogy are either humans or droids.
310
#
411
# This implements the following type system shorthand:
@@ -152,6 +159,12 @@ Query:
152159
description: "id of the droid"
153160
type: "String!"
154161
resolve: ["Overblog\\GraphQLGenerator\\Tests\\Resolver", "getDroid"]
162+
dateTime:
163+
type: "DateTime!"
164+
args:
165+
dateTime:
166+
type: "DateTime"
167+
resolve: ["Overblog\\GraphQLGenerator\\Tests\\Resolver", "getDateTime"]
155168

156169
HumanAndDroid:
157170
type: union

0 commit comments

Comments
 (0)