You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2024/01/16 18:34:54 UTC
(causeway) 01/01: CAUSEWAY-3676 : wip
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch CAUSEWAY-3676
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 8cdbede4fe7c4bc7256be92703592f1fdf0de339
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Jan 16 18:32:37 2024 +0000
CAUSEWAY-3676 : wip
---
incubator/viewers/graphql/test/pom.xml | 36 +-
...yViewerGraphqlTestModuleIntegTestAbstract.java} | 22 +-
...=> EndToEnd_IntegTest.changeName.approved.json} | 0
...l => EndToEnd_IntegTest.createE1.approved.json} | 0
... => EndToEnd_IntegTest.findAllE1.approved.json} | 0
.../viewer/test/source/EndToEnd_IntegTest.java | 25 +-
...nd_IntegTest.simple_post_request.approved.json} | 0
.../viewer/test/source/GQLSchema_IntegTest.java | 53 +-
.../source/GQLSchema_IntegTest.schema.approved.gql | 806 +++++++++++++++++++++
.../viewer/test/source/gqltestdomain/E2.java | 3 +-
.../test/source/introspection-query-request.gql | 99 +++
11 files changed, 1029 insertions(+), 15 deletions(-)
diff --git a/incubator/viewers/graphql/test/pom.xml b/incubator/viewers/graphql/test/pom.xml
index edb1462b46..c9a13bf825 100644
--- a/incubator/viewers/graphql/test/pom.xml
+++ b/incubator/viewers/graphql/test/pom.xml
@@ -37,15 +37,28 @@
<git-plugin.propertiesDir>org/apache/causeway/incubator/viewer/graphql/test</git-plugin.propertiesDir>
<maven.install.skip>true</maven.install.skip>
<maven.deploy.skip>true</maven.deploy.skip>
+
+ <java.version>17</java.version>
</properties>
- <build>
+ <build>
<testResources>
<testResource>
<directory>src/test/java</directory>
<filtering>false</filtering>
</testResource>
</testResources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.11.0</version>
+ <configuration>
+ <source>${java.version}</source>
+ <target>${java.version}</target>
+ </configuration>
+ </plugin>
+ </plugins>
</build>
<dependencies>
@@ -76,6 +89,12 @@
<artifactId>causeway-testing-fixtures-applib</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.causeway.testing</groupId>
+ <artifactId>causeway-testing-integtestsupport-applib</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@@ -97,8 +116,21 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-test-autoconfigure</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.graphql</groupId>
+ <artifactId>spring-graphql-test</artifactId>
+ <version>1.2.4</version>
+ <scope>test</scope>
+ </dependency>
- </dependencies>
+ </dependencies>
</project>
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/TestDomainModuleIntegTestAbstract.java b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/CausewayViewerGraphqlTestModuleIntegTestAbstract.java
similarity index 77%
rename from incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/TestDomainModuleIntegTestAbstract.java
rename to incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/CausewayViewerGraphqlTestModuleIntegTestAbstract.java
index 4fa5dbe48b..60c29aa2fb 100644
--- a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/TestDomainModuleIntegTestAbstract.java
+++ b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/CausewayViewerGraphqlTestModuleIntegTestAbstract.java
@@ -18,15 +18,22 @@
*/
package org.apache.causeway.viewer.graphql.viewer.test.source;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.web.reactive.server.WebTestClient;
import org.apache.causeway.core.config.presets.CausewayPresets;
import org.apache.causeway.core.runtimeservices.CausewayModuleCoreRuntimeServices;
@@ -38,12 +45,15 @@ import org.apache.causeway.viewer.graphql.viewer.test.source.gqltestdomain.TestD
@SpringBootTest(
classes = {
- TestDomainModuleIntegTestAbstract.TestApp.class
+ CausewayViewerGraphqlTestModuleIntegTestAbstract.TestApp.class
},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
+@AutoConfigureHttpGraphQlTester
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@ActiveProfiles("test")
-public class TestDomainModuleIntegTestAbstract {
+public class CausewayViewerGraphqlTestModuleIntegTestAbstract {
/**
* Compared to the production app manifest <code>domainapp.webapp.AppManifest</code>,
@@ -75,5 +85,13 @@ public class TestDomainModuleIntegTestAbstract {
@LocalServerPort
protected int port;
+ protected HttpGraphQlTester graphQlTester() {
+ WebTestClient client =
+ WebTestClient.bindToServer()
+ .baseUrl("http://0.0.0.0:" + port + "/graphql")
+ .build();
+ return HttpGraphQlTester.create(client);
+ }
+
}
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.changeName.approved.gql b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.changeName.approved.json
similarity index 100%
rename from incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.changeName.approved.gql
rename to incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.changeName.approved.json
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.createE1.approved.gql b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.createE1.approved.json
similarity index 100%
rename from incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.createE1.approved.gql
rename to incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.createE1.approved.json
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.findAllE1.approved.gql b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.findAllE1.approved.json
similarity index 100%
rename from incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.findAllE1.approved.gql
rename to incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.findAllE1.approved.json
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.java b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.java
index c1f44d58a2..26bef80b25 100644
--- a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.java
+++ b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.java
@@ -34,6 +34,8 @@ import javax.inject.Inject;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.causeway.viewer.graphql.viewer.source.GraphQlServiceForCauseway;
+
import org.approvaltests.Approvals;
import org.approvaltests.core.Options;
import org.approvaltests.core.Scrubber;
@@ -45,6 +47,7 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.annotation.Propagation;
@@ -69,12 +72,13 @@ import lombok.val;
//@Transactional NOT USING @Transactional since we are running server within same transaction otherwise
@ActiveProfiles("test")
-public class EndToEnd_IntegTest extends TestDomainModuleIntegTestAbstract {
+public class EndToEnd_IntegTest extends CausewayViewerGraphqlTestModuleIntegTestAbstract {
@Inject TransactionService transactionService;
@Inject CausewaySystemEnvironment causewaySystemEnvironment;
@Inject SpecificationLoader specificationLoader;
@Inject GraphQlSourceForCauseway graphQlSourceForCauseway;
+ @Inject GraphQlServiceForCauseway graphQlServiceForCauseway;
@Inject TestEntityRepository testEntityRepository;
@Inject GQLTestDomainMenu gqlTestDomainMenu;
@@ -103,12 +107,31 @@ public class EndToEnd_IntegTest extends TestDomainModuleIntegTestAbstract {
HttpClient client = HttpClient.newBuilder().build();
URI uri = URI.create("http://0.0.0.0:" + port + "/graphql/schema");
+
HttpRequest request = HttpRequest.newBuilder().uri(uri).GET().build();
File targetFile1 = new File("src/test/resources/testfiles/schema.gql");
HttpResponse<Path> response = client.send(request, HttpResponse.BodyHandlers.ofFile(targetFile1.toPath()));
}
+ @Test
+ void introspectionQuery() throws Exception {
+
+ HttpClient client = HttpClient.newBuilder().build();
+
+ URI uri = URI.create(String.format("http://0.0.0.0:%d/graphql", port));
+
+ String s = readResource("introspection-query-request.gql");
+// HttpRequest request = HttpRequest.newBuilder().uri(uri).POST(HttpRequest.BodyPublishers.ofString(s)).build();
+//
+// HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
+// String body = response.body();
+
+ //graphQlTester().documentName()
+
+
+ }
+
//TODO started to fail on 2022-04-22, with missing
//"name" : "_gql_input__org_apache_causeway_applib_services_inject_ServiceInjector"
//disabled to rescue CI build
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.simple_post_request.approved.gql b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.simple_post_request.approved.json
similarity index 100%
rename from incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.simple_post_request.approved.gql
rename to incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/EndToEnd_IntegTest.simple_post_request.approved.json
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/GQLSchema_IntegTest.java b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/GQLSchema_IntegTest.java
index c49a74b826..35c63ef439 100644
--- a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/GQLSchema_IntegTest.java
+++ b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/GQLSchema_IntegTest.java
@@ -19,9 +19,17 @@
package org.apache.causeway.viewer.graphql.viewer.test.source;
import java.util.List;
+import java.util.stream.Collectors;
import javax.inject.Inject;
+import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.commons.io.TextUtils;
+
+import org.approvaltests.Approvals;
+import org.approvaltests.core.Options;
+import org.approvaltests.reporters.DiffReporter;
+import org.approvaltests.reporters.UseReporter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -54,18 +62,14 @@ import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLSchemaElement;
import graphql.schema.GraphQLType;
import graphql.schema.GraphQLTypeReference;
+import graphql.schema.idl.SchemaPrinter;
@Transactional
-public class GQLSchema_IntegTest extends TestDomainModuleIntegTestAbstract{
-
- @Inject
- private CausewaySystemEnvironment causewaySystemEnvironment;
-
- @Inject
- private SpecificationLoader specificationLoader;
+public class GQLSchema_IntegTest extends CausewayViewerGraphqlTestModuleIntegTestAbstract {
- @Inject
- private GraphQlSourceForCauseway graphQlSourceForCauseway;
+ @Inject private CausewaySystemEnvironment causewaySystemEnvironment;
+ @Inject private SpecificationLoader specificationLoader;
+ @Inject private GraphQlSourceForCauseway graphQlSourceForCauseway;
@BeforeEach
void beforeEach() {
@@ -74,6 +78,35 @@ public class GQLSchema_IntegTest extends TestDomainModuleIntegTestAbstract{
assertNotNull(graphQlSourceForCauseway);
}
+ @Test
+ @UseReporter(DiffReporter.class)
+ void schema() {
+
+ GraphQLSchema x;
+
+ GraphQL graphQL = graphQlSourceForCauseway.graphQl();
+ GraphQLSchema graphQLSchema = graphQL.getGraphQLSchema();
+
+ SchemaPrinter printer = new SchemaPrinter();
+
+ // Print schema
+ String schemaDefinition = printer.print(graphQLSchema);
+
+ Approvals.verify(schemaDefinition, gqlSchemaOptions());
+ }
+
+ private Options gqlSchemaOptions() {
+ return new Options()
+ .withScrubber(this::unixLineEndings)
+ .forFile().withExtension(".gql");
+ }
+
+ private String unixLineEndings(final String input) {
+ return TextUtils.streamLines(input)
+ .collect(Collectors.joining("\n"));
+ }
+
+
@Test
@Disabled
void assert_stuff_works() {
@@ -98,6 +131,8 @@ public class GQLSchema_IntegTest extends TestDomainModuleIntegTestAbstract{
GraphQL graphQL = graphQlSourceForCauseway.graphQl();
GraphQLSchema graphQLSchema = graphQL.getGraphQLSchema();
+
+
// List<GraphQLNamedType> allTypesAsList = graphQLSchema.getAllTypesAsList();
// allTypesAsList.forEach(t->{
// System.out.println(t.getName());
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/GQLSchema_IntegTest.schema.approved.gql b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/GQLSchema_IntegTest.schema.approved.gql
new file mode 100644
index 0000000000..5b095b0170
--- /dev/null
+++ b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/GQLSchema_IntegTest.schema.approved.gql
@@ -0,0 +1,806 @@
+"Marks the field, argument, input field or enum value as deprecated"
+directive @deprecated(
+ "The reason for the deprecation"
+ reason: String = "No longer supported"
+ ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
+
+"Directs the executor to include this field or fragment only when the `if` argument is true"
+directive @include(
+ "Included when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Directs the executor to skip this field or fragment when the `if` argument is true."
+directive @skip(
+ "Skipped when true."
+ if: Boolean!
+ ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
+
+"Exposes a URL that specifies the behaviour of this scalar."
+directive @specifiedBy(
+ "The URL that specifies the behaviour of this scalar."
+ url: String!
+ ) on SCALAR
+
+type Query {
+ causeway_applib_UserMenu: causeway_applib_UserMenu
+ causeway_conf_ConfigurationMenu: causeway_conf_ConfigurationMenu
+ causeway_security_LogoutMenu: causeway_security_LogoutMenu
+ gqltestdomain_GQLTestDomainMenu: gqltestdomain_GQLTestDomainMenu
+ numServices: Int
+}
+
+type causeway_applib_DomainObjectList {
+ _gql_meta: causeway_applib_DomainObjectList__DomainObject_meta
+ actionArguments: String
+ actionId: String
+ actionOwningFqcn: String
+ elementTypeFqcn: String!
+ title: String!
+}
+
+type causeway_applib_DomainObjectList__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_FacetGroupNode {
+ _gql_meta: causeway_applib_FacetGroupNode__DomainObject_meta
+ facets: String!
+}
+
+type causeway_applib_FacetGroupNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_ParameterNode {
+ _gql_meta: causeway_applib_ParameterNode__DomainObject_meta
+ parameter: String!
+ parentNode: causeway_applib_node_ActionNode!
+}
+
+type causeway_applib_ParameterNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_PropertyNode {
+ _gql_meta: causeway_applib_PropertyNode__DomainObject_meta
+ _gql_mutations: causeway_applib_PropertyNode__DomainObject_mutators
+ mixedIn: String!
+ parentNode: causeway_applib_TypeNode!
+ property: String!
+}
+
+type causeway_applib_PropertyNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_PropertyNode__DomainObject_mutators {
+ streamChildNodes: java_util_stream_Stream
+}
+
+type causeway_applib_RoleMemento {
+ _gql_meta: causeway_applib_RoleMemento__DomainObject_meta
+ description: String!
+ name: String!
+}
+
+type causeway_applib_RoleMemento__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_TypeNode {
+ _gql_meta: causeway_applib_TypeNode__DomainObject_meta
+ domainClassDto: causeway_schema_metamodel_v2_DomainClassDto!
+}
+
+type causeway_applib_TypeNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_UserMemento {
+ _gql_meta: causeway_applib_UserMemento__DomainObject_meta
+ authenticationCode: String!
+ authenticationSource: String!
+ avatarUrl: String
+ impersonating: String!
+ languageLocale: String
+ multiTenancyToken: String
+ name: String!
+ numberFormatLocale: String
+ realName: String
+ roles: [causeway_applib_RoleMemento]
+ timeFormatLocale: String
+}
+
+type causeway_applib_UserMemento__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_UserMenu {
+ me: causeway_applib_UserMemento
+}
+
+type causeway_applib_node_ActionNode {
+ _gql_meta: causeway_applib_node_ActionNode__DomainObject_meta
+ _gql_mutations: causeway_applib_node_ActionNode__DomainObject_mutators
+ action: String!
+ mixedIn: String!
+ parentNode: causeway_applib_TypeNode!
+}
+
+type causeway_applib_node_ActionNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_node_ActionNode__DomainObject_mutators {
+ streamChildNodes: java_util_stream_Stream
+}
+
+type causeway_applib_node_CollectionNode {
+ _gql_meta: causeway_applib_node_CollectionNode__DomainObject_meta
+ _gql_mutations: causeway_applib_node_CollectionNode__DomainObject_mutators
+ collection: String!
+ mixedIn: String!
+ parentNode: causeway_applib_TypeNode!
+}
+
+type causeway_applib_node_CollectionNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_node_CollectionNode__DomainObject_mutators {
+ streamChildNodes: java_util_stream_Stream
+}
+
+type causeway_applib_node_FacetAttrNode {
+ _gql_meta: causeway_applib_node_FacetAttrNode__DomainObject_meta
+ facetAttr: String!
+ parentNode: causeway_applib_node_FacetNode!
+}
+
+type causeway_applib_node_FacetAttrNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_applib_node_FacetNode {
+ _gql_meta: causeway_applib_node_FacetNode__DomainObject_meta
+ facet: String!
+ shadowed: String!
+}
+
+type causeway_applib_node_FacetNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_conf_ConfigurationMenu {
+ configuration: causeway_conf_ConfigurationViewmodel
+}
+
+type causeway_conf_ConfigurationProperty {
+ _gql_meta: causeway_conf_ConfigurationProperty__DomainObject_meta
+ key: String!
+ value: String!
+}
+
+type causeway_conf_ConfigurationProperty__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_conf_ConfigurationViewmodel {
+ _gql_meta: causeway_conf_ConfigurationViewmodel__DomainObject_meta
+ environment: [causeway_conf_ConfigurationProperty]
+ primary: [causeway_conf_ConfigurationProperty]
+ secondary: [causeway_conf_ConfigurationProperty]
+}
+
+type causeway_conf_ConfigurationViewmodel__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_feat_ApplicationFeatureViewModel {
+ _gql_meta: causeway_feat_ApplicationFeatureViewModel__DomainObject_meta
+ memberName: String!
+ namespaceName: String!
+ typeSimpleName: String!
+}
+
+type causeway_feat_ApplicationFeatureViewModel__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_feat_ApplicationNamespace {
+ _gql_meta: causeway_feat_ApplicationNamespace__DomainObject_meta
+ memberName: String!
+ namespaceName: String!
+ typeSimpleName: String!
+}
+
+type causeway_feat_ApplicationNamespace__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_feat_ApplicationType {
+ _gql_meta: causeway_feat_ApplicationType__DomainObject_meta
+ actions: [causeway_feat_ApplicationTypeAction]
+ collections: [causeway_feat_ApplicationTypeCollection]
+ memberName: String!
+ namespaceName: String!
+ properties: [causeway_feat_ApplicationTypeProperty]
+ typeSimpleName: String!
+}
+
+type causeway_feat_ApplicationTypeAction {
+ _gql_meta: causeway_feat_ApplicationTypeAction__DomainObject_meta
+ actionSemantics: String!
+ memberName: String!
+ namespaceName: String!
+ returnType: String!
+ typeSimpleName: String!
+}
+
+type causeway_feat_ApplicationTypeAction__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_feat_ApplicationTypeCollection {
+ _gql_meta: causeway_feat_ApplicationTypeCollection__DomainObject_meta
+ derived: String!
+ elementType: String!
+ memberName: String!
+ namespaceName: String!
+ typeSimpleName: String!
+}
+
+type causeway_feat_ApplicationTypeCollection__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_feat_ApplicationTypeMember {
+ _gql_meta: causeway_feat_ApplicationTypeMember__DomainObject_meta
+ memberName: String!
+ namespaceName: String!
+ typeSimpleName: String!
+}
+
+type causeway_feat_ApplicationTypeMember__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_feat_ApplicationTypeProperty {
+ _gql_meta: causeway_feat_ApplicationTypeProperty__DomainObject_meta
+ derived: String!
+ maxLength: String
+ memberName: String!
+ namespaceName: String!
+ returnType: String!
+ typeSimpleName: String!
+ typicalLength: String
+}
+
+type causeway_feat_ApplicationTypeProperty__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_feat_ApplicationType__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_schema_metamodel_v2_DomainClassDto {
+ _gql_meta: causeway_schema_metamodel_v2_DomainClassDto__DomainObject_meta
+ actions: String!
+ annotations: String!
+ collections: String!
+ facets: String!
+ id: String!
+ majorVersion: String
+ minorVersion: String
+ properties: String!
+ service: String!
+}
+
+type causeway_schema_metamodel_v2_DomainClassDto__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_security_LoginRedirect {
+ _gql_meta: causeway_security_LoginRedirect__DomainObject_meta
+}
+
+type causeway_security_LoginRedirect__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type causeway_security_LogoutMenu {
+ logout: String
+}
+
+type causeway_testing_fixtures_FixtureResult {
+ _gql_meta: causeway_testing_fixtures_FixtureResult__DomainObject_meta
+ className: String!
+ fixtureScriptClassName: String
+ key: String!
+}
+
+type causeway_testing_fixtures_FixtureResult__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type gqltestdomain_E1 {
+ _gql_meta: gqltestdomain_E1__DomainObject_meta
+ e2: gqltestdomain_E2
+ name: String!
+}
+
+type gqltestdomain_E1__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+ version: String
+}
+
+type gqltestdomain_E2 {
+ _gql_meta: gqltestdomain_E2__DomainObject_meta
+ _gql_mutations: gqltestdomain_E2__DomainObject_mutators
+ e1: gqltestdomain_E1
+ name: String
+ otherE2List: [gqltestdomain_E2]
+ otherEntities: [org_apache_causeway_viewer_graphql_viewer_test_source_gqltestdomain_TestEntity]
+ stringList: [String]
+ zintList: [Int]
+}
+
+type gqltestdomain_E2__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+ version: String
+}
+
+type gqltestdomain_E2__DomainObject_mutators {
+ changeE1(e1: _gql_input__gqltestdomain_E1!): gqltestdomain_E2
+ changeName(newName: String!): gqltestdomain_E2
+}
+
+type gqltestdomain_GQLTestDomainMenu {
+ createE1(e2: _gql_input__gqltestdomain_E2, name: String): gqltestdomain_E1
+ findAllE1: [gqltestdomain_E1]
+ findAllE2: [gqltestdomain_E2]
+ findAllTestEntities: [org_apache_causeway_viewer_graphql_viewer_test_source_gqltestdomain_TestEntity]
+ findE2(name: String): gqltestdomain_E2
+}
+
+type java_lang_Runnable {
+ _gql_meta: java_lang_Runnable__DomainObject_meta
+}
+
+type java_lang_Runnable__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type java_util_Map {
+ _gql_meta: java_util_Map__DomainObject_meta
+}
+
+type java_util_Map__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type java_util_SortedMap {
+ _gql_meta: java_util_SortedMap__DomainObject_meta
+}
+
+type java_util_SortedMap__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type java_util_concurrent_Callable {
+ _gql_meta: java_util_concurrent_Callable__DomainObject_meta
+}
+
+type java_util_concurrent_Callable__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type java_util_function_BiFunction {
+ _gql_meta: java_util_function_BiFunction__DomainObject_meta
+}
+
+type java_util_function_BiFunction__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type java_util_function_Consumer {
+ _gql_meta: java_util_function_Consumer__DomainObject_meta
+}
+
+type java_util_function_Consumer__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type java_util_function_Function {
+ _gql_meta: java_util_function_Function__DomainObject_meta
+}
+
+type java_util_function_Function__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type java_util_stream_Stream {
+ _gql_meta: java_util_stream_Stream__DomainObject_meta
+}
+
+type java_util_stream_Stream__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_commons_functional_Either {
+ _gql_meta: org_apache_causeway_commons_functional_Either__DomainObject_meta
+ _gql_mutations: org_apache_causeway_commons_functional_Either__DomainObject_mutators
+ left: String!
+ right: String!
+}
+
+type org_apache_causeway_commons_functional_Either__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_commons_functional_Either__DomainObject_mutators {
+ accept(leftConsumer: _gql_input__java_util_function_Consumer!, rightConsumer: _gql_input__java_util_function_Consumer!): String
+ left: String
+ map(leftMapper: _gql_input__java_util_function_Function!, rightMapper: _gql_input__java_util_function_Function!): org_apache_causeway_commons_functional_Either
+ mapLeft(leftMapper: _gql_input__java_util_function_Function!): org_apache_causeway_commons_functional_Either
+ mapRight(rightMapper: _gql_input__java_util_function_Function!): org_apache_causeway_commons_functional_Either
+ right: String
+}
+
+type org_apache_causeway_commons_functional_Railway {
+ _gql_meta: org_apache_causeway_commons_functional_Railway__DomainObject_meta
+ _gql_mutations: org_apache_causeway_commons_functional_Railway__DomainObject_mutators
+ failure: String!
+ success: String!
+}
+
+type org_apache_causeway_commons_functional_Railway__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_commons_functional_Railway__DomainObject_mutators {
+ chain(chainingFunction: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Railway
+ ifFailure(failureConsumer: _gql_input__org_apache_causeway_commons_functional_ThrowingConsumer!): org_apache_causeway_commons_functional_Railway
+ ifSuccess(successConsumer: _gql_input__org_apache_causeway_commons_functional_ThrowingConsumer!): org_apache_causeway_commons_functional_Railway
+ mapFailure(failureMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Railway
+ mapSuccess(successMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Railway
+}
+
+type org_apache_causeway_commons_functional_ThrowingConsumer {
+ _gql_meta: org_apache_causeway_commons_functional_ThrowingConsumer__DomainObject_meta
+ _gql_mutations: org_apache_causeway_commons_functional_ThrowingConsumer__DomainObject_mutators
+}
+
+type org_apache_causeway_commons_functional_ThrowingConsumer__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_commons_functional_ThrowingConsumer__DomainObject_mutators {
+ andThen(arg0: _gql_input__java_util_function_Consumer!): java_util_function_Consumer
+ throwing(exceptionWrapper: _gql_input__java_util_function_BiFunction!): org_apache_causeway_commons_functional_ThrowingConsumer
+}
+
+type org_apache_causeway_commons_functional_ThrowingFunction {
+ _gql_meta: org_apache_causeway_commons_functional_ThrowingFunction__DomainObject_meta
+ _gql_mutations: org_apache_causeway_commons_functional_ThrowingFunction__DomainObject_mutators
+}
+
+type org_apache_causeway_commons_functional_ThrowingFunction__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_commons_functional_ThrowingFunction__DomainObject_mutators {
+ andThen(arg0: _gql_input__java_util_function_Function!): java_util_function_Function
+ compose(arg0: _gql_input__java_util_function_Function!): java_util_function_Function
+ throwing(exceptionWrapper: _gql_input__java_util_function_BiFunction!): org_apache_causeway_commons_functional_ThrowingFunction
+}
+
+type org_apache_causeway_commons_functional_ThrowingRunnable {
+ _gql_meta: org_apache_causeway_commons_functional_ThrowingRunnable__DomainObject_meta
+ _gql_mutations: org_apache_causeway_commons_functional_ThrowingRunnable__DomainObject_mutators
+}
+
+type org_apache_causeway_commons_functional_ThrowingRunnable__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_commons_functional_ThrowingRunnable__DomainObject_mutators {
+ callUncatched: String
+ run: String
+ runUncatched: String
+ toCallable: java_util_concurrent_Callable
+ toRunnable: java_lang_Runnable
+}
+
+type org_apache_causeway_commons_functional_Try {
+ _gql_meta: org_apache_causeway_commons_functional_Try__DomainObject_meta
+ _gql_mutations: org_apache_causeway_commons_functional_Try__DomainObject_mutators
+ failure: String!
+ success: String!
+}
+
+type org_apache_causeway_commons_functional_Try__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_commons_functional_Try__DomainObject_mutators {
+ accept(failureConsumer: _gql_input__org_apache_causeway_commons_functional_ThrowingConsumer!, successConsumer: _gql_input__org_apache_causeway_commons_functional_ThrowingConsumer!): org_apache_causeway_commons_functional_Try
+ flatMapSuccess(successMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Try
+ flatMapSuccessAsNullable(successMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Try
+ flatMapSuccessWhenPresent(successMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Try
+ ifAbsentFail: org_apache_causeway_commons_functional_Try
+ ifFailure(exceptionConsumer: _gql_input__org_apache_causeway_commons_functional_ThrowingConsumer!): org_apache_causeway_commons_functional_Try
+ ifFailureFail: org_apache_causeway_commons_functional_Try
+ ifSuccess(valueConsumer: _gql_input__org_apache_causeway_commons_functional_ThrowingConsumer!): org_apache_causeway_commons_functional_Try
+ ifSuccessAsNullable(valueConsumer: _gql_input__org_apache_causeway_commons_functional_ThrowingConsumer!): org_apache_causeway_commons_functional_Try
+ mapEmptyToFailure: org_apache_causeway_commons_functional_Try
+ mapFailure(failureMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Try
+ mapFailureToSuccess(recoveryMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Try
+ mapSuccess(successMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Try
+ mapSuccessAsNullable(successMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Try
+ mapSuccessWhenPresent(successMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Try
+ mapToEither(failureMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!, successMapper: _gql_input__org_apache_causeway_commons_functional_ThrowingFunction!): org_apache_causeway_commons_functional_Either
+ orCall(fallback: _gql_input__java_util_concurrent_Callable!): org_apache_causeway_commons_functional_Try
+ then(next: _gql_input__java_util_concurrent_Callable!): org_apache_causeway_commons_functional_Try
+ thenCall(callable: _gql_input__java_util_concurrent_Callable!): org_apache_causeway_commons_functional_Try
+ thenRun(runnable: _gql_input__org_apache_causeway_commons_functional_ThrowingRunnable!): org_apache_causeway_commons_functional_Try
+}
+
+type org_apache_causeway_core_metamodel_inspect_model_MMNode {
+ _gql_meta: org_apache_causeway_core_metamodel_inspect_model_MMNode__DomainObject_meta
+}
+
+type org_apache_causeway_core_metamodel_inspect_model_MMNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_core_metamodel_inspect_model_MemberNode {
+ _gql_meta: org_apache_causeway_core_metamodel_inspect_model_MemberNode__DomainObject_meta
+ _gql_mutations: org_apache_causeway_core_metamodel_inspect_model_MemberNode__DomainObject_mutators
+ mixedIn: String!
+ parentNode: causeway_applib_TypeNode!
+}
+
+type org_apache_causeway_core_metamodel_inspect_model_MemberNode__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_core_metamodel_inspect_model_MemberNode__DomainObject_mutators {
+ streamChildNodes: java_util_stream_Stream
+}
+
+type org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript {
+ _gql_meta: org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__DomainObject_meta
+ friendlyName: String!
+ qualifiedName: String!
+}
+
+type org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+type org_apache_causeway_viewer_graphql_viewer_test_source_gqltestdomain_TestEntity {
+ _gql_meta: org_apache_causeway_viewer_graphql_viewer_test_source_gqltestdomain_TestEntity__DomainObject_meta
+ name: String!
+}
+
+type org_apache_causeway_viewer_graphql_viewer_test_source_gqltestdomain_TestEntity__DomainObject_meta {
+ id: String!
+ logicalTypeName: String!
+}
+
+input _gql_input__causeway_applib_DomainObjectList {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_FacetGroupNode {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_ParameterNode {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_PropertyNode {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_RoleMemento {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_TypeNode {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_UserMemento {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_node_ActionNode {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_node_CollectionNode {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_node_FacetAttrNode {
+ id: ID!
+}
+
+input _gql_input__causeway_applib_node_FacetNode {
+ id: ID!
+}
+
+input _gql_input__causeway_conf_ConfigurationProperty {
+ id: ID!
+}
+
+input _gql_input__causeway_conf_ConfigurationViewmodel {
+ id: ID!
+}
+
+input _gql_input__causeway_feat_ApplicationFeatureViewModel {
+ id: ID!
+}
+
+input _gql_input__causeway_feat_ApplicationNamespace {
+ id: ID!
+}
+
+input _gql_input__causeway_feat_ApplicationType {
+ id: ID!
+}
+
+input _gql_input__causeway_feat_ApplicationTypeAction {
+ id: ID!
+}
+
+input _gql_input__causeway_feat_ApplicationTypeCollection {
+ id: ID!
+}
+
+input _gql_input__causeway_feat_ApplicationTypeMember {
+ id: ID!
+}
+
+input _gql_input__causeway_feat_ApplicationTypeProperty {
+ id: ID!
+}
+
+input _gql_input__causeway_schema_metamodel_v2_DomainClassDto {
+ id: ID!
+}
+
+input _gql_input__causeway_security_LoginRedirect {
+ id: ID!
+}
+
+input _gql_input__causeway_testing_fixtures_FixtureResult {
+ id: ID!
+}
+
+input _gql_input__gqltestdomain_E1 {
+ id: ID!
+}
+
+input _gql_input__gqltestdomain_E2 {
+ id: ID!
+}
+
+input _gql_input__java_lang_Runnable {
+ id: ID!
+}
+
+input _gql_input__java_util_Map {
+ id: ID!
+}
+
+input _gql_input__java_util_SortedMap {
+ id: ID!
+}
+
+input _gql_input__java_util_concurrent_Callable {
+ id: ID!
+}
+
+input _gql_input__java_util_function_BiFunction {
+ id: ID!
+}
+
+input _gql_input__java_util_function_Consumer {
+ id: ID!
+}
+
+input _gql_input__java_util_function_Function {
+ id: ID!
+}
+
+input _gql_input__java_util_stream_Stream {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_commons_functional_Either {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_commons_functional_Railway {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_commons_functional_ThrowingConsumer {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_commons_functional_ThrowingFunction {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_commons_functional_ThrowingRunnable {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_commons_functional_Try {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_core_metamodel_inspect_model_MMNode {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_core_metamodel_inspect_model_MemberNode {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_testing_fixtures_applib_fixturescripts_FixtureScript {
+ id: ID!
+}
+
+input _gql_input__org_apache_causeway_viewer_graphql_viewer_test_source_gqltestdomain_TestEntity {
+ id: ID!
+}
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/gqltestdomain/E2.java b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/gqltestdomain/E2.java
index d2af239bc8..157b8ee882 100644
--- a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/gqltestdomain/E2.java
+++ b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/gqltestdomain/E2.java
@@ -35,6 +35,7 @@ import javax.persistence.Table;
import javax.persistence.Transient;
import org.apache.causeway.applib.annotation.Action;
+import org.apache.causeway.applib.annotation.Bounding;
import org.apache.causeway.applib.annotation.Collection;
import org.apache.causeway.applib.annotation.DomainObject;
import org.apache.causeway.applib.annotation.Nature;
@@ -51,7 +52,7 @@ import lombok.Setter;
name = "E2"
)
@Named("gqltestdomain.E2")
-@DomainObject(nature = Nature.ENTITY)
+@DomainObject(nature = Nature.ENTITY, bounding = Bounding.BOUNDED)
public class E2 implements TestEntity{
@Id
diff --git a/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/introspection-query-request.gql b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/introspection-query-request.gql
new file mode 100644
index 0000000000..d0dc5a1cfc
--- /dev/null
+++ b/incubator/viewers/graphql/test/src/test/java/org/apache/causeway/viewer/graphql/viewer/test/source/introspection-query-request.gql
@@ -0,0 +1,99 @@
+query IntrospectionQuery {
+ __schema {
+ queryType {
+ name
+ }
+ mutationType {
+ name
+ }
+ subscriptionType {
+ name
+ }
+ types {
+ ...FullType
+ }
+ directives {
+ name
+ description
+ locations
+ args {
+ ...InputValue
+ }
+ }
+ }
+}
+
+fragment FullType on __Type {
+ kind
+ name
+ description
+ fields(includeDeprecated: true) {
+ name
+ description
+ args {
+ ...InputValue
+ }
+ type {
+ ...TypeRef
+ }
+ isDeprecated
+ deprecationReason
+ }
+ inputFields {
+ ...InputValue
+ }
+ interfaces {
+ ...TypeRef
+ }
+ enumValues(includeDeprecated: true) {
+ name
+ description
+ isDeprecated
+ deprecationReason
+ }
+ possibleTypes {
+ ...TypeRef
+ }
+}
+
+fragment InputValue on __InputValue {
+ name
+ description
+ type {
+ ...TypeRef
+ }
+ defaultValue
+}
+
+fragment TypeRef on __Type {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file