Skip to content

Commit

Permalink
GQLGW-666 POC on how we might replace $argument things
Browse files Browse the repository at this point in the history
  • Loading branch information
bbakerman committed Oct 4, 2023
1 parent 31ba727 commit fe7f4a2
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 37 deletions.
23 changes: 4 additions & 19 deletions lib/src/main/java/graphql/nadel/dsl/AstValueReplacer.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package graphql.nadel.dsl

import graphql.language.Argument
import graphql.language.AstTransformer
import graphql.language.Node
import graphql.language.NodeVisitorStub
import graphql.language.ObjectField
import graphql.language.StringValue
import graphql.language.Value
import graphql.util.TraversalControl
Expand All @@ -29,26 +27,13 @@ class AstValueReplacer {
return null;
}

override fun visitArgument(
node: Argument,
override fun visitStringValue(
node: StringValue,
context: TraverserContext<Node<*>>,
): TraversalControl {
val newAstValue = possiblyReplaceValue(node.value)
val newAstValue = possiblyReplaceValue(node)
if (newAstValue != null) {
val transformedNode = node.transform { it.value(newAstValue) }
return changeNode(context, transformedNode)
}
return TraversalControl.CONTINUE
}

override fun visitObjectField(
node: ObjectField,
context: TraverserContext<Node<*>>,
): TraversalControl {
val newAstValue = possiblyReplaceValue(node.value)
if (newAstValue != null) {
val transformedNode = node.transform { it.value(newAstValue) }
return changeNode(context, transformedNode)
return changeNode(context, newAstValue)
}
return TraversalControl.CONTINUE
}
Expand Down
84 changes: 66 additions & 18 deletions lib/src/test/kotlin/graphql/nadel/dsl/AstValueReplacerTest.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,66 @@
package graphql.nadel.dsl

import graphql.GraphQLContext
import graphql.execution.ValuesResolver
import graphql.language.AstPrinter
import graphql.language.ObjectField
import graphql.language.ObjectValue
import graphql.language.StringValue
import graphql.language.Value
import graphql.parser.Parser
import graphql.schema.GraphQLSchema
import graphql.schema.InputValueWithState
import graphql.schema.idl.RuntimeWiring
import graphql.schema.idl.SchemaGenerator
import graphql.schema.idl.SchemaParser
import io.kotest.core.spec.style.DescribeSpec
import java.util.Locale

class AstValueReplacerTest : DescribeSpec({

fun getSchema(schemaText: String): GraphQLSchema {
val typeDefs = SchemaParser().parse(schemaText)
return SchemaGenerator().makeExecutableSchema(typeDefs, RuntimeWiring.MOCKED_WIRING)
}


describe("can change values") {

val schema = getSchema(
"""
type Query {
q(arg : ComplexXyType) : String
}

input ComplexXyType {
x : String
y : String
}
""".trimIndent()
)

val complexXyType = schema.getType("ComplexXyType")!!

val argument = "${'$'}argument"

val xyValueReplacer = object : AstValueReplacer.ValueReplacer {
override fun replaceString(strValue: String): Value<*>? {
if (strValue.contains("$argument.x")) {
// we would find all $argument things
// then look them up to resolve to a JVM value
// then create an AST value of that external value based on some type
// which we get from the target field
val jvmValue = mapOf("x" to "X", "y" to "Y") // from argument object
val inputValueWithState = InputValueWithState.newExternalValue(jvmValue)
// maybe its already a literal ???
return ValuesResolver.valueToLiteral(
inputValueWithState,
complexXyType,
GraphQLContext.getDefault(),
Locale.getDefault()
)
}
return null
}
}

it("can replace object values in AST") {

val startingValue = Parser.parseValue(
Expand All @@ -20,24 +71,21 @@ class AstValueReplacerTest : DescribeSpec({
}
""".trimIndent()
)

val valueReplacer = object : AstValueReplacer.ValueReplacer {
override fun replaceString(strValue: String): Value<*>? {
if (strValue.contains("${'$'}argument.x")) {
return ObjectValue(
listOf(
ObjectField("x", StringValue("X")),
ObjectField("y", StringValue("Y"))
)
)
}
return null
}
}
val newValue = AstValueReplacer().replaceValues(startingValue, valueReplacer)
val newValue = AstValueReplacer().replaceValues(startingValue, xyValueReplacer)

assert(AstPrinter.printAst(newValue) == """{abc : {x : "X", y : "Y"}, note : "not to be changed"}""")

}

it("can replace string values in AST") {

val startingValue = Parser.parseValue(""""${'$'}argument.x"""")

val newValue = AstValueReplacer().replaceValues(startingValue, xyValueReplacer)

assert(AstPrinter.printAst(newValue) == """{x : "X", y : "Y"}""")

}

}
})

0 comments on commit fe7f4a2

Please sign in to comment.