11package graphql.kickstart.tools
22
33import graphql.GraphQL
4+ import org.junit.Assert.assertThrows
45import org.junit.Test
56
67class GenericObjectTypesTest {
@@ -12,8 +13,11 @@ class GenericObjectTypesTest {
1213 """
1314 type Query {
1415 test: TestClass!
16+ anyMatch: Match!
1517 }
1618
19+ union Match = StringListEntityMatch | StringEntityMatch
20+
1721 type TestClass {
1822 match: StringListEntityMatch!
1923 single: StringEntityMatch!
@@ -32,7 +36,7 @@ class GenericObjectTypesTest {
3236 .resolvers(EntityMatchQueryResolver ())
3337 .build()
3438 .makeExecutableSchema()
35- .assertEveryFieldResolves()
39+ .assertEveryFieldResolves(except = setOf ( " Query.anyMatch " ) )
3640 val gql = GraphQL .newGraphQL(schema).build()
3741
3842 val data = assertNoGraphQlErrors(gql) {
@@ -50,6 +54,9 @@ class GenericObjectTypesTest {
5054 " match" to mapOf (" text" to " x y" , " value" to listOf (" x" , " y" )),
5155 " single" to mapOf (" text" to " z" , " value" to " z" )
5256 ))
57+
58+ val error = assertThrows(TypeResolverError ::class .java) { gql.execute(" query { anyMatch { __typename } }" ) }
59+ assertEquals(error.message, " Expected object type with name 'EntityMatch' to exist for union 'Match', but it doesn't!" )
5360 }
5461
5562 @Test
@@ -60,14 +67,22 @@ class GenericObjectTypesTest {
6067 type Query {
6168 characterHit: CharacterHit!
6269 characterHitPage: CharacterHitPage!
70+ lastPage: Result!
71+ topHit: Scored!
72+ }
73+
74+ union Result = CharacterHitPage | Human
75+
76+ interface Scored {
77+ score: Float!
6378 }
6479
6580 type CharacterHitPage {
6681 content: [CharacterHit!]!
6782 totalElements: Int!
6883 }
6984
70- type CharacterHit {
85+ type CharacterHit implements Scored {
7186 score: Float!
7287 source: Character!
7388 }
@@ -110,6 +125,13 @@ class GenericObjectTypesTest {
110125 }
111126 }
112127 }
128+ lastPage {
129+ ... on CharacterHitPage { totalElements }
130+ }
131+ topHit {
132+ score
133+ ... on CharacterHit { source { name } }
134+ }
113135 }
114136 """
115137 }
@@ -122,13 +144,56 @@ class GenericObjectTypesTest {
122144 mapOf (" source" to mapOf (" name" to " R2-D2" , " primaryFunction" to " Astromech" ))
123145 )
124146 ))
147+ assertEquals(data[" lastPage" ], mapOf (" totalElements" to 1 ))
148+ assertEquals(data[" topHit" ], mapOf (" score" to 0.5 , " source" to mapOf (" name" to " Luke" )))
149+ }
150+
151+ @Test
152+ fun `a raw class keeps its own type when a parameterized entry shares it` () {
153+ val schema = SchemaParser .newParser()
154+ .schemaString(
155+ """
156+ type Query {
157+ single: StringEntityMatch!
158+ anyMatch: Match!
159+ }
160+
161+ union Match = StringEntityMatch | AnyEntityMatch
162+
163+ type StringEntityMatch {
164+ text: String!
165+ value: String
166+ }
167+
168+ type AnyEntityMatch {
169+ text: String!
170+ }
171+ """ )
172+ .resolvers(RawEntityMatchQueryResolver ())
173+ .dictionary(" AnyEntityMatch" , EntityMatch ::class .java)
174+ .build()
175+ .makeExecutableSchema()
176+ .assertEveryFieldResolves()
177+ val gql = GraphQL .newGraphQL(schema).build()
178+
179+ val data = assertNoGraphQlErrors(gql) { " query { anyMatch { __typename } }" }
180+
181+ assertEquals(data[" anyMatch" ], mapOf (" __typename" to " AnyEntityMatch" ))
125182 }
126183
127184 class EntityMatchQueryResolver : GraphQLQueryResolver {
128185 fun test (): TestClass = TestClass (
129186 match = EntityMatch (" x y" , listOf (" x" , " y" )),
130187 single = EntityMatch (" z" , " z" )
131188 )
189+
190+ fun anyMatch (): Any = EntityMatch (" z" , " z" )
191+ }
192+
193+ class RawEntityMatchQueryResolver : GraphQLQueryResolver {
194+ fun single (): EntityMatch <String > = EntityMatch (" z" , " z" )
195+
196+ fun anyMatch (): Any = EntityMatch (" z" , " z" )
132197 }
133198
134199 data class TestClass (val match : EntityMatch <List <String >>, val single : EntityMatch <String >)
@@ -141,11 +206,19 @@ class GenericObjectTypesTest {
141206 listOf (Hit (Human (" Luke" , " Tatooine" ), 1.0 ), Hit (Droid (" R2-D2" , " Astromech" ), 1.0 )),
142207 2
143208 )
209+
210+ fun lastPage (): Any = Page (listOf (Hit (Droid (" R2-D2" , " Astromech" ), 1.0 )), 1 )
211+
212+ fun topHit (): Scored = Hit (Human (" Luke" , " Tatooine" ), 0.5 )
144213 }
145214
146215 class Page <T >(val content : List <T >, val totalElements : Int )
147216
148- class Hit <T >(val source : T , val score : Double )
217+ interface Scored {
218+ val score: Double
219+ }
220+
221+ class Hit <T >(val source : T , override val score : Double ) : Scored
149222
150223 interface Character {
151224 val name: String
0 commit comments