Skip to content

Commit 6f0e9f3

Browse files
smyrickbrennantaylor
authored andcommitted
fix: add directives on enum values (#181)
1 parent 1de6b80 commit 6f0e9f3

File tree

8 files changed

+80
-2
lines changed

8 files changed

+80
-2
lines changed

example/src/main/kotlin/com/expedia/graphql/sample/model/Animal.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.expedia.graphql.sample.model
22

33
import com.expedia.graphql.annotations.GraphQLDescription
4+
import com.expedia.graphql.sample.directives.SimpleDirective
45

56
@GraphQLDescription("animal interface type")
67
interface Animal {
@@ -12,8 +13,10 @@ interface Animal {
1213
}
1314

1415
@GraphQLDescription("enum holding all supported animal types")
16+
@SimpleDirective
1517
enum class AnimalType {
1618
CAT,
19+
@SimpleDirective
1720
DOG
1821
}
1922

@@ -38,4 +41,4 @@ class Cat: Animal {
3841

3942
@GraphQLDescription("this is specific to cats")
4043
fun ignoreEveryone(): String = "ignore everyone"
41-
}
44+
}

src/main/kotlin/com/expedia/graphql/generator/SchemaGenerator.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.expedia.graphql.generator.types.UnionTypeBuilder
1818
import graphql.schema.GraphQLDirective
1919
import graphql.schema.GraphQLInterfaceType
2020
import graphql.schema.GraphQLSchema
21+
import java.lang.reflect.Field
2122
import kotlin.reflect.KAnnotatedElement
2223
import kotlin.reflect.KClass
2324
import kotlin.reflect.KFunction
@@ -88,4 +89,10 @@ internal class SchemaGenerator(internal val config: SchemaGeneratorConfig) {
8889
state.directives.addAll(directives)
8990
return directives
9091
}
92+
93+
internal fun fieldDirectives(field: Field): List<GraphQLDirective> {
94+
val directives = directiveTypeBuilder.fieldDirectives(field)
95+
state.directives.addAll(directives)
96+
return directives
97+
}
9198
}

src/main/kotlin/com/expedia/graphql/generator/types/DirectiveTypeBuilder.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.expedia.graphql.generator.extensions.safeCast
88
import com.google.common.base.CaseFormat
99
import graphql.schema.GraphQLArgument
1010
import graphql.schema.GraphQLDirective
11+
import java.lang.reflect.Field
1112
import kotlin.reflect.KAnnotatedElement
1213
import com.expedia.graphql.annotations.GraphQLDirective as GraphQLDirectiveAnnotation
1314

@@ -18,6 +19,11 @@ internal class DirectiveTypeBuilder(generator: SchemaGenerator) : TypeBuilder(ge
1819
.mapNotNull { it.getDirectiveInfo() }
1920
.map(this::getDirective)
2021

22+
internal fun fieldDirectives(field: Field): List<GraphQLDirective> =
23+
field.annotations
24+
.mapNotNull { it.getDirectiveInfo() }
25+
.map(this::getDirective)
26+
2127
private fun getDirective(directiveInfo: DirectiveInfo): GraphQLDirective {
2228

2329
val existingDirective = state.directives.find { it.name == directiveInfo.effectiveName }

src/main/kotlin/com/expedia/graphql/generator/types/EnumTypeBuilder.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ internal class EnumTypeBuilder(generator: SchemaGenerator) : TypeBuilder(generat
3434
valueBuilder.value(enum.name)
3535

3636
val valueField = kClass.java.getField(enum.name)
37+
38+
generator.fieldDirectives(valueField).forEach {
39+
valueBuilder.withDirective(it)
40+
}
41+
3742
valueBuilder.description(valueField.getGraphQLDescription())
3843
valueBuilder.deprecationReason(valueField.getDeprecationReason())
3944

src/test/kotlin/com/expedia/graphql/generator/types/DirectiveTypeBuilderTest.kt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ internal class DirectiveTypeBuilderTest {
1919
internal annotation class DirectiveWithString(val string: String)
2020

2121
internal enum class Type {
22-
ONE, TWO
22+
@DirectiveWithString("my string")
23+
@DirectiveWithClass(SimpleDirective::class)
24+
ONE,
25+
26+
@GraphQLDescription("my description")
27+
TWO
2328
}
2429

2530
@GraphQLDirective
@@ -86,4 +91,24 @@ internal class DirectiveTypeBuilderTest {
8691
basicGenerator.directives(MyClass::simpleDirective)
8792
assertEquals(1, basicGenerator.state.directives.size)
8893
}
94+
95+
@Test
96+
fun `directives are valid on fields (enum values)`() {
97+
val field = Type::class.java.getField("ONE")
98+
99+
val directives = basicGenerator.fieldDirectives(field)
100+
101+
assertEquals(2, directives.size)
102+
assertEquals("directiveWithString", directives.first().name)
103+
assertEquals("directiveWithClass", directives.last().name)
104+
}
105+
106+
@Test
107+
fun `directives are empty on an enum with no valid annotations`() {
108+
val field = Type::class.java.getField("TWO")
109+
110+
val directives = basicGenerator.fieldDirectives(field)
111+
112+
assertEquals(0, directives.size)
113+
}
89114
}

src/test/kotlin/com/expedia/graphql/generator/types/EnumTypeBuilderTest.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.expedia.graphql.generator.types
22

33
import com.expedia.graphql.annotations.GraphQLDescription
4+
import com.expedia.graphql.utils.CustomDirective
45
import com.expedia.graphql.utils.SimpleDirective
56
import org.junit.jupiter.api.Test
67
import kotlin.test.assertEquals
@@ -23,6 +24,8 @@ internal class EnumTypeBuilderTest : TypeTestHelper() {
2324
@Deprecated("Deprecated enum value")
2425
TWO,
2526

27+
@SimpleDirective
28+
@CustomDirective("foo bar")
2629
@Deprecated("THREE is out", replaceWith = ReplaceWith("TWO"))
2730
THREE
2831
}
@@ -77,4 +80,21 @@ internal class EnumTypeBuilderTest : TypeTestHelper() {
7780
assertEquals(1, gqlEnum.directives.size)
7881
assertEquals("simpleDirective", gqlEnum.directives.first().name)
7982
}
83+
84+
@Test
85+
fun `Enum values can have a single directive`() {
86+
val gqlEnum = assertNotNull(builder.enumType(MyTestEnum::class))
87+
88+
val directives = gqlEnum.values.last().directives
89+
assertEquals(2, directives.size)
90+
assertEquals("simpleDirective", directives.first().name)
91+
assertEquals("customName", directives.last().name)
92+
}
93+
94+
@Test
95+
fun `Enum values can have a multiple directives`() {
96+
val gqlEnum = assertNotNull(builder.enumType(MyTestEnum::class))
97+
assertEquals(1, gqlEnum.values.first().directives.size)
98+
assertEquals("simpleDirective", gqlEnum.values.first().directives.first().name)
99+
}
80100
}

src/test/kotlin/com/expedia/graphql/generator/types/TypeTestHelper.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import graphql.schema.GraphQLInterfaceType
1212
import io.mockk.every
1313
import io.mockk.mockk
1414
import io.mockk.spyk
15+
import java.lang.reflect.Field
1516
import kotlin.reflect.KAnnotatedElement
1617
import kotlin.reflect.KClass
1718
import kotlin.reflect.KFunction
@@ -84,6 +85,11 @@ internal open class TypeTestHelper {
8485
state.directives.addAll(directives)
8586
directives
8687
}
88+
every { generator.fieldDirectives(any()) } answers {
89+
val directives = directiveTypeBuilder!!.fieldDirectives(it.invocation.args[0] as Field)
90+
state.directives.addAll(directives)
91+
directives
92+
}
8793

8894
beforeTest()
8995
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.expedia.graphql.utils
2+
3+
import com.expedia.graphql.annotations.GraphQLDirective
4+
5+
@GraphQLDirective(name = "customName", description = "custom description")
6+
annotation class CustomDirective(val customValue: String)

0 commit comments

Comments
 (0)