From eef99d7568e3eae8e5ea371177c78dd72b122248 Mon Sep 17 00:00:00 2001 From: Rob Date: Mon, 24 Dec 2018 14:49:35 -0800 Subject: [PATCH] extend ProjectionNames to include Args addresses https://github.com/sangria-graphql/sangria/issues/427 --- build.sbt | 2 +- .../scala/sangria/execution/Resolver.scala | 2 +- src/main/scala/sangria/schema/Context.scala | 2 +- .../sangria/execution/ProjectorSpec.scala | 55 ++++++++++++------- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/build.sbt b/build.sbt index 75e62ce5..a9a9a1e0 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ name := "sangria" organization := "org.sangria-graphql" -version := "1.4.3-SNAPSHOT" +version := "1.4.4-SNAPSHOT" description := "Scala GraphQL implementation" homepage := Some(url("http://sangria-graphql.org")) diff --git a/src/main/scala/sangria/execution/Resolver.scala b/src/main/scala/sangria/execution/Resolver.scala index 10a6eeb2..229818b7 100644 --- a/src/main/scala/sangria/execution/Resolver.scala +++ b/src/main/scala/sangria/execution/Resolver.scala @@ -1165,7 +1165,7 @@ class Resolver[Ctx]( else Vector(field.name) projectedName.map (name ⇒ - ProjectedName(name, loop(path.add(astField, objTpe), field.fieldType, fields, currLevel + 1))) + ProjectedName(name, loop(path.add(astField, objTpe), field.fieldType, fields, currLevel + 1), Args(field, astField))) } .flatten case Failure(_) ⇒ Vector.empty diff --git a/src/main/scala/sangria/schema/Context.scala b/src/main/scala/sangria/schema/Context.scala index 21d0ea94..f0f20a1d 100644 --- a/src/main/scala/sangria/schema/Context.scala +++ b/src/main/scala/sangria/schema/Context.scala @@ -158,7 +158,7 @@ object Projector { } } -case class ProjectedName(name: String, children: Vector[ProjectedName] = Vector.empty) { +case class ProjectedName(name: String, children: Vector[ProjectedName] = Vector.empty, args: Args = Args.empty) { lazy val asVector = { def loop(name: ProjectedName): Vector[Vector[String]] = Vector(name.name) +: (name.children flatMap loop map (name.name +: _)) diff --git a/src/test/scala/sangria/execution/ProjectorSpec.scala b/src/test/scala/sangria/execution/ProjectorSpec.scala index 5add9bd1..e63faf02 100644 --- a/src/test/scala/sangria/execution/ProjectorSpec.scala +++ b/src/test/scala/sangria/execution/ProjectorSpec.scala @@ -16,6 +16,9 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { case class ProductDefer(productIds: List[String]) extends Deferred[List[Right[String, Product]]] + val IntArgument = Argument("intArg", IntType) + val StringArgument = Argument("stringArg", StringType) + val ProductAttributeType = InterfaceType("ProductAttribute", fields[Unit, (String, Any)]( Field("name", StringType, resolve = _.value._1))) @@ -37,7 +40,7 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { Field("relatedProducts", ListType(ProductType), tags = ProjectionName("rp") :: Nil, resolve = Projector(1, (ctx, projected) ⇒ projected match { - case Vector(ProjectedName("id", _)) ⇒ Value(ctx.value.relatedProductIds map (Left(_))) + case Vector(ProjectedName("id", _, _)) ⇒ Value(ctx.value.relatedProductIds map (Left(_))) case _ ⇒ ProductDefer(ctx.value.relatedProductIds) })) )) @@ -51,8 +54,11 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { Field("typeId", StringType, tags = ProjectionExclude :: Nil, resolve = _ ⇒ "product"), Field("masterVariant", VariantType, tags = ProjectionName("master1") :: ProjectionName("master2") :: Nil, + arguments = IntArgument :: Nil, resolve = _.value.right.get.variants.head), - Field("variants", ListType(VariantType), resolve = _.value.right.get.variants.tail) + Field("variants", ListType(VariantType), + arguments = StringArgument :: Nil, + resolve = _.value.right.get.variants.tail) )) val QueryType = ObjectType("Query", fields[Ctx, Unit]( @@ -103,7 +109,7 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { projectAll { id typeId - variants { + variants(stringArg: "a") { id attributes { name @@ -115,7 +121,7 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { relatedProducts { id typeId - variants { + variants(stringArg: "b") { id } } @@ -124,7 +130,7 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { projectOne { id typeId - variants { + variants(stringArg: "c") { id typeId } @@ -189,12 +195,15 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { ProjectedName("rp", Vector( ProjectedName("id", Vector.empty), ProjectedName("variants", Vector( - ProjectedName("id", Vector.empty))))))))) + ProjectedName("id", Vector.empty)), + Args(StringArgument :: Nil, "stringArg" -> "b"))))), + Args(StringArgument :: Nil, "stringArg" -> "a")))) ctx.oneLevelprojections should be ( Vector( ProjectedName("id", Vector.empty), - ProjectedName("variants", Vector.empty))) + ProjectedName("variants", Vector.empty, + Args(StringArgument :: Nil, "stringArg" -> "c")))) } "handle multiple projected names" in { @@ -204,10 +213,10 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { projectAll { id variantIds - masterVariant { + masterVariant(intArg: 1) { mixed } - variants { + variants(stringArg: "a") { id mixed } @@ -216,10 +225,10 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { projectOne { id variantIds - masterVariant { + masterVariant(intArg: 2) { mixed } - variants { + variants(stringArg: "b") { id mixed } @@ -260,26 +269,34 @@ class ProjectorSpec extends WordSpec with Matchers with FutureResultSupport { ProjectedName("id", Vector.empty), ProjectedName("masterVariant.id", Vector.empty), ProjectedName("variants.id", Vector.empty), - ProjectedName("master1", Vector( + ProjectedName("master1", + Vector( ProjectedName("mixed1", Vector.empty), - ProjectedName("mixed2", Vector.empty))), - ProjectedName("master2", Vector( + ProjectedName("mixed2", Vector.empty)), + Args(IntArgument :: Nil, "intArg" -> 1)), + ProjectedName("master2", + Vector( ProjectedName("mixed1", Vector.empty), - ProjectedName("mixed2", Vector.empty))), + ProjectedName("mixed2", Vector.empty)), + Args(IntArgument :: Nil, "intArg" -> 1)), ProjectedName("variants", Vector( ProjectedName("id", Vector.empty), ProjectedName("mixed1", Vector.empty), - ProjectedName("mixed2", Vector.empty))))) + ProjectedName("mixed2", Vector.empty)), + Args(StringArgument :: Nil, "stringArg" -> "a")))) ctx.oneLevelprojections should be ( Vector( ProjectedName("id", Vector.empty), ProjectedName("masterVariant.id", Vector.empty), ProjectedName("variants.id", Vector.empty), - ProjectedName("master1", Vector.empty), - ProjectedName("master2", Vector.empty), - ProjectedName("variants", Vector.empty))) + ProjectedName("master1", Vector.empty, + Args(IntArgument :: Nil, "intArg" -> 2)), + ProjectedName("master2", Vector.empty, + Args(IntArgument :: Nil, "intArg" -> 2)), + ProjectedName("variants", Vector.empty, + Args(StringArgument :: Nil, "stringArg" -> "b")))) } } } \ No newline at end of file