100, 'nestingLevel' => 10, 'fieldsPerType' => 10, 'listFieldsPerType' => 2 ]; private $typeIndex = 0; private $objectTypes = []; /** * BenchmarkSchemaBuilder constructor. * @param array $config */ public function __construct(array $config) { $this->config = array_merge($this->config, $config); } public function buildSchema() { return new Schema([ 'query' => $this->buildQueryType() ]); } public function buildQueryType() { $this->typeIndex = 0; $this->objectTypes = []; return $this->createType(0); } public function loadType($name) { $tokens = explode('_', $name); $nestingLevel = (int) $tokens[1]; return $this->createType($nestingLevel, $name); } protected function createType($nestingLevel, $typeName = null) { if ($this->typeIndex > $this->config['totalTypes']) { throw new \Exception( "Cannot create new type: there are already {$this->typeIndex} ". "which exceeds allowed number of {$this->config['totalTypes']} types total" ); } $this->typeIndex++; if (!$typeName) { $typeName = 'Level_' . $nestingLevel . '_Type' . $this->typeIndex; } $type = new ObjectType([ 'name' => $typeName, 'fields' => function() use ($typeName, $nestingLevel) { return $this->createTypeFields($typeName, $nestingLevel + 1); } ]); $this->objectTypes[$typeName] = $type; return $type; } protected function getFieldTypeAndName($nestingLevel, $fieldIndex) { if ($nestingLevel >= $this->config['nestingLevel']) { $fieldType = Type::string(); $fieldName = 'leafField' . $fieldIndex; } else if ($this->typeIndex >= $this->config['totalTypes']) { $fieldType = $this->objectTypes[array_rand($this->objectTypes)]; $fieldName = 'randomTypeField' . $fieldIndex; } else { $fieldType = $this->createType($nestingLevel); $fieldName = 'field' . $fieldIndex; } return [$fieldType, $fieldName]; } protected function createTypeFields($typeName, $nestingLevel) { $fields = []; for ($index = 0; $index < $this->config['fieldsPerType']; $index++) { list($type, $name) = $this->getFieldTypeAndName($nestingLevel, $index); $fields[] = [ 'name' => $name, 'type' => $type, 'resolve' => [$this, 'resolveField'] ]; } for ($index = 0; $index < $this->config['listFieldsPerType']; $index++) { list($type, $name) = $this->getFieldTypeAndName($nestingLevel, $index); $name = 'listOf' . ucfirst($name); $fields[] = [ 'name' => $name, 'type' => Type::listOf($type), 'args' => $this->createFieldArgs($name, $typeName), 'resolve' => function() { return [ 'string1', 'string2', 'string3', 'string4', 'string5', ]; } ]; } return $fields; } protected function createFieldArgs($fieldName, $typeName) { return [ 'argString' => [ 'type' => Type::string() ], 'argEnum' => [ 'type' => new EnumType([ 'name' => $typeName . $fieldName . 'Enum', 'values' => [ "ONE", "TWO", "THREE" ] ]) ], 'argInputObject' => [ 'type' => new InputObjectType([ 'name' => $typeName . $fieldName . 'Input', 'fields' => [ 'field1' => Type::string(), 'field2' => Type::int() ] ]) ] ]; } public function resolveField($value, $args, $context, $resolveInfo) { return $resolveInfo->fieldName . '-value'; } }