Skip to content

Commit

Permalink
Add missing directive rendering for derrived types (#1275)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fluxx committed Jan 28, 2022
1 parent fbb5e65 commit 49536fc
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 24 deletions.
18 changes: 14 additions & 4 deletions core/src/main/scala-2/caliban/schema/SchemaDerivation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ trait SchemaDerivation[R] extends LowPriorityDerivedSchema {
)
)
.toList,
Some(ctx.typeName.full)
Some(ctx.typeName.full),
Some(getDirectives(ctx))
)
else
makeObject(
Expand Down Expand Up @@ -132,14 +133,16 @@ trait SchemaDerivation[R] extends LowPriorityDerivedSchema {
annotations.collectFirst { case GQLDeprecated(reason) => reason }
)
},
Some(ctx.typeName.full)
Some(ctx.typeName.full),
Some(getDirectives(ctx.annotations))
)
else if (!isInterface)
makeUnion(
Some(getName(ctx)),
getDescription(ctx),
subtypes.map { case (t, _) => fixEmptyUnionObject(t) },
Some(ctx.typeName.full)
Some(ctx.typeName.full),
Some(getDirectives(ctx.annotations))
)
else {
val impl = subtypes.map(_._1.copy(interfaces = () => Some(List(toType(isInput, isSubscription)))))
Expand All @@ -157,7 +160,14 @@ trait SchemaDerivation[R] extends LowPriorityDerivedSchema {
.flatten
.toList

makeInterface(Some(getName(ctx)), getDescription(ctx), commonFields, impl, Some(ctx.typeName.full))
makeInterface(
Some(getName(ctx)),
getDescription(ctx),
commonFields,
impl,
Some(ctx.typeName.full),
Some(getDirectives(ctx.annotations))
)
}
}

Expand Down
12 changes: 8 additions & 4 deletions core/src/main/scala-3/caliban/schema/SchemaDerivation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,16 @@ trait SchemaDerivation[A] {
annotations.collectFirst { case GQLDeprecated(reason) => reason }
)
},
Some(info.full)
Some(info.full),
Some(getDirectives(annotations))
)
} else if (!isInterface)
makeUnion(
Some(getName(annotations, info)),
getDescription(annotations),
subTypes.map { case (_, t, _) => fixEmptyUnionObject(t) },
Some(info.full)
Some(info.full),
Some(getDirectives(annotations))
)
else {
val impl = subTypes.map(_._2.copy(interfaces = () => Some(List(toType(isInput, isSubscription)))))
Expand All @@ -111,7 +113,8 @@ trait SchemaDerivation[A] {
getDescription(annotations),
commonFields,
impl,
Some(info.full)
Some(info.full),
Some(getDirectives(annotations))
)
}

Expand Down Expand Up @@ -147,7 +150,8 @@ trait SchemaDerivation[A] {
Some(fieldAnnotations.collect { case GQLDirective(dir) => dir }).filter(_.nonEmpty)
)
},
Some(info.full)
Some(info.full),
Some(getDirectives(annotations))
)
else
makeObject(
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/scala/caliban/Rendering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ object Rendering {
.fold(List.empty[String])(_.flatMap(_.name))
.mkString(" | ")
Some(
s"""${renderDescription(t.description)}${renderKind(t.kind)} ${renderTypeName(t)} = $renderedTypes"""
s"""${renderDescription(t.description)}${renderKind(t.kind)} ${renderTypeName(t)}${renderDirectives(
t.directives
)} = $renderedTypes"""
)
case _ =>
val renderedDirectives: String = renderDirectives(t.directives)
Expand Down
36 changes: 28 additions & 8 deletions core/src/main/scala/caliban/schema/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,17 @@ object Types {
name: Option[String],
description: Option[String],
values: List[__EnumValue],
origin: Option[String]
origin: Option[String],
directives: Option[List[Directive]] = None
): __Type =
__Type(
__TypeKind.ENUM,
name,
description,
enumValues =
args => if (args.includeDeprecated.getOrElse(false)) Some(values) else Some(values.filter(!_.isDeprecated)),
origin = origin
origin = origin,
directives = directives
)

def makeObject(
Expand All @@ -57,24 +59,41 @@ object Types {
name: Option[String],
description: Option[String],
fields: List[__InputValue],
origin: Option[String] = None
origin: Option[String] = None,
directives: Option[List[Directive]] = None
): __Type =
__Type(__TypeKind.INPUT_OBJECT, name, description, inputFields = Some(fields), origin = origin)
__Type(
__TypeKind.INPUT_OBJECT,
name,
description,
inputFields = Some(fields),
origin = origin,
directives = directives
)

def makeUnion(
name: Option[String],
description: Option[String],
subTypes: List[__Type],
origin: Option[String] = None
origin: Option[String] = None,
directives: Option[List[Directive]] = None
): __Type =
__Type(__TypeKind.UNION, name, description, possibleTypes = Some(subTypes), origin = origin)
__Type(
__TypeKind.UNION,
name,
description,
possibleTypes = Some(subTypes),
origin = origin,
directives = directives
)

def makeInterface(
name: Option[String],
description: Option[String],
fields: () => List[__Field],
subTypes: List[__Type],
origin: Option[String] = None
origin: Option[String] = None,
directives: Option[List[Directive]] = None
): __Type =
__Type(
__TypeKind.INTERFACE,
Expand All @@ -83,7 +102,8 @@ object Types {
fields =
args => if (args.includeDeprecated.getOrElse(false)) Some(fields()) else Some(fields().filter(!_.isDeprecated)),
possibleTypes = Some(subTypes),
origin = origin
origin = origin,
directives = directives
)

/**
Expand Down
17 changes: 13 additions & 4 deletions core/src/test/scala/caliban/RenderingSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,30 @@ object RenderingSpec extends DefaultRunnableSpec {
|"Description of custom scalar emphasizing proper captain ship names"
|scalar CaptainShipName @specifiedBy(url: "http://someUrl")
|
|union Role = Captain | Engineer | Mechanic | Pilot
|union Role @uniondirective = Captain | Engineer | Mechanic | Pilot
|
|enum Origin {
|enum Origin @enumdirective {
| BELT
| EARTH
| MARS
| MOON @deprecated(reason: "Use: EARTH | MARS | BELT")
|}
|
|input CharacterInput {
|input CharacterInput @inputobjdirective {
| name: String! @external
| nicknames: [String!]! @required
| origin: Origin!
|}
|
|interface Human {
| name: String! @external
|}
|
|type Captain {
| shipName: CaptainShipName!
|}
|
|type Character @key(name: "name") {
|type Character implements Human @key(name: "name") {
| name: String! @external
| nicknames: [String!]! @required
| origin: Origin!
Expand All @@ -56,6 +60,10 @@ object RenderingSpec extends DefaultRunnableSpec {
| shipName: String!
|}
|
|type Narrator implements Human {
| name: String!
|}
|
|type Pilot {
| shipName: String!
|}
Expand All @@ -67,6 +75,7 @@ object RenderingSpec extends DefaultRunnableSpec {
| character(name: String!): Character @deprecated(reason: "Use `characters`")
| charactersIn(names: [String!]!): [Character!]!
| exists(character: CharacterInput!): Boolean!
| human: Human!
|}""".stripMargin.trim)
)
},
Expand Down
18 changes: 15 additions & 3 deletions core/src/test/scala/caliban/TestUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ object TestUtils {
case class C(id: String, blah: Boolean) extends Interface
}

@GQLDirective(Directive("enumdirective"))
sealed trait Origin

object Origin {
Expand All @@ -34,6 +35,7 @@ object TestUtils {
case object MOON extends Origin
}

@GQLDirective(Directive("uniondirective"))
sealed trait Role

case class CaptainShipName(value: String)
Expand All @@ -53,13 +55,20 @@ object TestUtils {
case class Mechanic(shipName: String) extends Role
}

@GQLInterface
sealed trait Human

@GQLDirective(Directive("key", Map("name" -> StringValue("name"))))
case class Character(
@GQLDirective(Directive("external")) name: String,
@GQLDirective(Directive("required")) nicknames: List[String],
origin: Origin,
role: Option[Role]
)
) extends Human

case class Narrator(
name: String
) extends Human

case class OrganizationId(self: Long) extends AnyVal
case class Event(organizationId: OrganizationId, title: String)
Expand All @@ -68,6 +77,7 @@ object TestUtils {
case class WrappedPainter(self: Painter) extends AnyVal

@GQLInputName("CharacterInput")
@GQLDirective(Directive("inputobjdirective"))
case class CharacterInput(
@GQLDirective(Directive("external")) name: String,
@GQLDirective(Directive("required")) nicknames: List[String],
Expand Down Expand Up @@ -98,7 +108,8 @@ object TestUtils {
@GQLDescription("Return all characters from a given origin") characters: CharactersArgs => List[Character],
@GQLDeprecated("Use `characters`") character: CharacterArgs => Option[Character],
charactersIn: CharacterInArgs => List[Character],
exists: CharacterObjectArgs => Boolean
exists: CharacterObjectArgs => Boolean,
human: Human
)

@GQLDescription("Queries")
Expand All @@ -122,7 +133,8 @@ object TestUtils {
args => characters.filter(c => args.origin.forall(c.origin == _)),
args => characters.find(c => c.name == args.name),
args => characters.filter(c => args.names.contains(c.name)),
args => characters.exists(_.name == args.character.name)
args => characters.exists(_.name == args.character.name),
Narrator("narrator")
)
)
val resolverIO = RootResolver(
Expand Down

0 comments on commit 49536fc

Please sign in to comment.