Skip to content
This repository was archived by the owner on Nov 29, 2023. It is now read-only.

Commit

Permalink
Merge pull request pgutkowski#46 from jeggy/master
Browse files Browse the repository at this point in the history
Add scalar deserializers to the objectMapper
  • Loading branch information
pgutkowski authored Jan 8, 2019
2 parents 15262db + 6f10193 commit 0436b70
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ abstract class ScalarDSL<T : Any, Raw : Any>(kClass: KClass<T>, block: ScalarDSL

var coercion: ScalarCoercion<T, Raw>? = null

internal fun createCoercion() : ScalarCoercion<T, Raw> {
fun createCoercion() : ScalarCoercion<T, Raw> {
return coercion ?: createCoercionFromFunctions()
}

abstract protected fun createCoercionFromFunctions() : ScalarCoercion<T, Raw>
protected abstract fun createCoercionFromFunctions() : ScalarCoercion<T, Raw>
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.github.pgutkowski.kgraphql.schema.dsl

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
import com.fasterxml.jackson.databind.module.SimpleModule
import com.github.pgutkowski.kgraphql.schema.Schema
import com.github.pgutkowski.kgraphql.schema.SchemaException
import com.github.pgutkowski.kgraphql.schema.model.EnumValueDef
Expand Down Expand Up @@ -44,6 +48,7 @@ class SchemaBuilder<Context : Any>(private val init: SchemaBuilder<Context>.() -

fun <T : Any>stringScalar(kClass: KClass<T>, block: ScalarDSL<T, String>.() -> Unit){
val scalar = StringScalarDSL(kClass, block)
configuration.appendMapper(scalar, kClass)
model.addScalar(TypeDef.Scalar(scalar.name, kClass, scalar.createCoercion(), scalar.description))
}

Expand All @@ -53,6 +58,7 @@ class SchemaBuilder<Context : Any>(private val init: SchemaBuilder<Context>.() -

fun <T : Any>intScalar(kClass: KClass<T>, block: ScalarDSL<T, Int>.() -> Unit){
val scalar = IntScalarDSL(kClass, block)
configuration.appendMapper(scalar, kClass)
model.addScalar(TypeDef.Scalar(scalar.name, kClass, scalar.createCoercion(), scalar.description))
}

Expand All @@ -62,6 +68,7 @@ class SchemaBuilder<Context : Any>(private val init: SchemaBuilder<Context>.() -

fun <T : Any>floatScalar(kClass: KClass<T>, block: ScalarDSL<T, Double>.() -> Unit){
val scalar = DoubleScalarDSL(kClass, block)
configuration.appendMapper(scalar, kClass)
model.addScalar(TypeDef.Scalar(scalar.name, kClass, scalar.createCoercion(), scalar.description))
}

Expand All @@ -71,6 +78,7 @@ class SchemaBuilder<Context : Any>(private val init: SchemaBuilder<Context>.() -

fun <T : Any>longScalar(kClass: KClass<T>, block: ScalarDSL<T, Long>.() -> Unit){
val scalar = LongScalarDSL(kClass, block)
configuration.appendMapper(scalar, kClass)
model.addScalar(TypeDef.Scalar(scalar.name, kClass, scalar.createCoercion(), scalar.description))
}

Expand All @@ -80,6 +88,7 @@ class SchemaBuilder<Context : Any>(private val init: SchemaBuilder<Context>.() -

fun <T : Any>booleanScalar(kClass: KClass<T>, block: ScalarDSL<T, Boolean>.() -> Unit){
val scalar = BooleanScalarDSL(kClass, block)
configuration.appendMapper(scalar, kClass)
model.addScalar(TypeDef.Scalar(scalar.name, kClass, scalar.createCoercion(), scalar.description))
}

Expand Down Expand Up @@ -160,4 +169,18 @@ class SchemaBuilder<Context : Any>(private val init: SchemaBuilder<Context>.() -
inline fun <reified T : Any> inputType() {
inputType(T::class, {})
}
}

inline fun <T: Any, reified Raw: Any> SchemaConfigurationDSL.appendMapper(scalar: ScalarDSL<T, Raw>, kClass: KClass<T>) {
objectMapper.registerModule(SimpleModule().addDeserializer(kClass.java, object : UsesDeserializer<T>() {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext?): T? {
return scalar
.createCoercion()
.deserialize(p.readValueAs(Raw::class.java))
}
}))
}

open class UsesDeserializer<T>(vc: Class<*>? = null) : StdDeserializer<T>(vc) {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext?): T? = TODO("Implement")
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ class ScalarsSpecificationTest {
assertThat(response.extract<Boolean>("data/boolean"), equalTo(value))
}

data class Dob(val double : Double)
data class Boo(val boolean: Boolean)
data class Lon(val long: Long)
data class Dob(val double: Double)
data class Num(val int: Int)
data class Str(val string: String)
data class Multi(val boo: Boo, val str: String, val num: Num)

@Test
fun `Schema may declare custom double scalar type`(){
Expand All @@ -167,4 +172,76 @@ class ScalarsSpecificationTest {
val response = deserialize(schema.execute("{double(double: $value)}"))
assertThat(response.extract<Double>("data/double"), equalTo(value))
}

@Test
fun `Scalars within input variables`(){
val schema = KGraphQL.schema {
booleanScalar<Boo> {
deserialize = ::Boo
serialize = { (boolean) -> boolean }
}
longScalar<Lon> {
deserialize = ::Lon
serialize = { (long) -> long }
}
floatScalar<Dob> {
deserialize = ::Dob
serialize = { (double) -> double }
}
intScalar<Num> {
deserialize = ::Num
serialize = { (num) -> num }
}
stringScalar<Str> {
deserialize = ::Str
serialize = { (str) -> str }
}

query("boo") { resolver { boo : Boo -> boo } }
query("lon") { resolver { lon : Lon -> lon } }
query("dob") { resolver { dob : Dob -> dob } }
query("num") { resolver { num : Num -> num } }
query("str") { resolver { str : Str -> str } }
query("multi") { resolver { -> Multi(Boo(false), "String", Num(25)) } }
}

val booValue = true
val lonValue = 124L
val dobValue = 2.5
val numValue = 155
val strValue = "Test"
val d = '$'

val req = """
query Query(${d}boo: Boo!, ${d}lon: Lon!, ${d}dob: Dob!, ${d}num: Num!, ${d}str: Str!){
boo(boo: ${d}boo)
lon(lon: ${d}lon)
dob(dob: ${d}dob)
num(num: ${d}num)
str(str: ${d}str)
multi { boo, str, num }
}
""".trimIndent()

val values = """
{
"boo": $booValue,
"lon": $lonValue,
"dob": $dobValue,
"num": $numValue,
"str": "$strValue"
}
""".trimIndent()

val response = deserialize(schema.execute(req, values))
assertThat(response.extract<Boolean>("data/boo"), equalTo(booValue))
assertThat(response.extract<Int>("data/lon"), equalTo(lonValue.toInt()))
assertThat(response.extract<Double>("data/dob"), equalTo(dobValue))
assertThat(response.extract<Int>("data/num"), equalTo(numValue))
assertThat(response.extract<String>("data/str"), equalTo(strValue))

assertThat(response.extract<Boolean>("data/multi/boo"), equalTo(false))
assertThat(response.extract<String>("data/multi/str"), equalTo("String"))
assertThat(response.extract<Int>("data/multi/num"), equalTo(25))
}
}

0 comments on commit 0436b70

Please sign in to comment.