diff --git a/src/Type/Definition/InputObjectType.php b/src/Type/Definition/InputObjectType.php index 8a6d569..dbce453 100644 --- a/src/Type/Definition/InputObjectType.php +++ b/src/Type/Definition/InputObjectType.php @@ -25,6 +25,10 @@ class InputObjectType extends Type implements InputType */ public function __construct(array $config) { + if (!isset($config['name'])) { + $config['name'] = $this->tryInferName(); + } + Config::validate($config, [ 'name' => Config::STRING | Config::REQUIRED, 'fields' => Config::arrayOf([ @@ -32,7 +36,7 @@ class InputObjectType extends Type implements InputType 'type' => Config::INPUT_TYPE | Config::REQUIRED, 'defaultValue' => Config::ANY, 'description' => Config::STRING - ], Config::KEY_AS_NAME | Config::MAYBE_THUNK), + ], Config::KEY_AS_NAME | Config::MAYBE_THUNK | Config::MAYBE_TYPE), 'description' => Config::STRING ]); diff --git a/src/Type/Definition/InterfaceType.php b/src/Type/Definition/InterfaceType.php index 11f110a..126a597 100644 --- a/src/Type/Definition/InterfaceType.php +++ b/src/Type/Definition/InterfaceType.php @@ -35,6 +35,10 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT */ public function __construct(array $config) { + if (!isset($config['name'])) { + $config['name'] = $this->tryInferName(); + } + Config::validate($config, [ 'name' => Config::STRING, 'fields' => Config::arrayOf( diff --git a/src/Type/Definition/ObjectType.php b/src/Type/Definition/ObjectType.php index 2c8c7f0..25c4037 100644 --- a/src/Type/Definition/ObjectType.php +++ b/src/Type/Definition/ObjectType.php @@ -79,6 +79,10 @@ class ObjectType extends Type implements OutputType, CompositeType */ public function __construct(array $config) { + if (!isset($config['name'])) { + $config['name'] = $this->tryInferName(); + } + Utils::invariant(!empty($config['name']), 'Every type is expected to have name'); // Note: this validation is disabled by default, because it is resource-consuming diff --git a/src/Type/Definition/Type.php b/src/Type/Definition/Type.php index cfe96e0..4349b78 100644 --- a/src/Type/Definition/Type.php +++ b/src/Type/Definition/Type.php @@ -242,6 +242,27 @@ abstract class Type */ public $description; + /** + * @return null|string + */ + protected function tryInferName() + { + if ($this->name) { + return $this->name; + } + + // If class is extended - infer name from className + // QueryType -> Type + // SomeOtherType -> SomeOther + $tmp = new \ReflectionClass($this); + $name = $tmp->getShortName(); + + if ($tmp->getNamespaceName() !== __NAMESPACE__) { + return preg_replace('~Type$~', '', $name); + } + return null; + } + /** * @return string */ diff --git a/src/Type/Definition/UnionType.php b/src/Type/Definition/UnionType.php index 90d26c0..74ab9be 100644 --- a/src/Type/Definition/UnionType.php +++ b/src/Type/Definition/UnionType.php @@ -36,6 +36,10 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType */ public function __construct($config) { + if (!isset($config['name'])) { + $config['name'] = $this->tryInferName(); + } + Config::validate($config, [ 'name' => Config::STRING | Config::REQUIRED, 'types' => Config::arrayOf(Config::OBJECT_TYPE, Config::MAYBE_THUNK | Config::REQUIRED), diff --git a/tests/Type/DefinitionTest.php b/tests/Type/DefinitionTest.php index e6af327..7ddb808 100644 --- a/tests/Type/DefinitionTest.php +++ b/tests/Type/DefinitionTest.php @@ -1,6 +1,8 @@ assertEquals($interface, $testField->getType()); $this->assertEquals('test', $testField->name); } + + public function testInfersNameFromClassname() + { + $myObj = new MyCustomType(); + $this->assertEquals('MyCustom', $myObj->name); + + $otherCustom = new OtherCustom(); + $this->assertEquals('OtherCustom', $otherCustom->name); + } } + diff --git a/tests/Type/TestClasses.php b/tests/Type/TestClasses.php new file mode 100644 index 0000000..affe6a4 --- /dev/null +++ b/tests/Type/TestClasses.php @@ -0,0 +1,31 @@ + [ + 'a' => Type::string() + ] + ]; + parent::__construct($config); + } +} + +class OtherCustom extends ObjectType +{ + public function __construct() + { + $config = [ + 'fields' => [ + 'b' => Type::string() + ] + ]; + parent::__construct($config); + } +}