diff --git a/core/src/main/scala/caliban/GraphQL.scala b/core/src/main/scala/caliban/GraphQL.scala index e143b82c69..59b3187863 100644 --- a/core/src/main/scala/caliban/GraphQL.scala +++ b/core/src/main/scala/caliban/GraphQL.scala @@ -32,15 +32,23 @@ trait GraphQL[-R] { self => /** * Returns a string that renders the API types into the GraphQL format. */ - final def render: String = - s"""schema { - |${schemaBuilder.query.flatMap(_.opType.name).fold("")(n => s" query: $n\n")}${schemaBuilder.mutation - .flatMap(_.opType.name) - .fold("")(n => s" mutation: $n\n")}${schemaBuilder.subscription - .flatMap(_.opType.name) - .fold("")(n => s" subscription: $n\n")}} + final def render: String = { + val parts = Seq( + schemaBuilder.query.flatMap(_.opType.name).map(n => s" query: $n"), + schemaBuilder.mutation.flatMap(_.opType.name).map(n => s" mutation: $n"), + schemaBuilder.subscription.flatMap(_.opType.name).map(n => s" subscription: $n") + ) + val schema = parts.flatten.mkString("\n") match { + case "" => "" + case something => s"""schema { + |$something + |}""".stripMargin + } + + s"""$schema | |${renderTypes(schemaBuilder.types)}""".stripMargin + } /** * Converts the schema to a Document. diff --git a/core/src/main/scala/caliban/Rendering.scala b/core/src/main/scala/caliban/Rendering.scala index cd338c06d8..61653addbf 100644 --- a/core/src/main/scala/caliban/Rendering.scala +++ b/core/src/main/scala/caliban/Rendering.scala @@ -62,11 +62,19 @@ object Rendering { .enumValues(__DeprecatedArgs(Some(true))) .fold(List.empty[String])(_.map(renderEnumValue)) .mkString("\n ") - Some( - s"""${renderDescription(t.description)}${renderKind(t.kind)} ${renderTypeName(t)}${renderInterfaces(t)}$renderedDirectives { - | $renderedFields$renderedInputFields$renderedEnumValues - |}""".stripMargin - ) + + val typedef = + s"${renderDescription(t.description)}${renderKind(t.kind)} ${renderTypeName(t)}${renderInterfaces(t)}$renderedDirectives" + + s"$renderedFields$renderedInputFields$renderedEnumValues" match { + case "" => Some(typedef) + case interior => + Some( + s"""$typedef { + | $interior + |}""".stripMargin + ) + } } } .mkString("\n\n") diff --git a/core/src/test/scala/caliban/RenderingSpec.scala b/core/src/test/scala/caliban/RenderingSpec.scala index 6ff9bf0195..5683480a3f 100644 --- a/core/src/test/scala/caliban/RenderingSpec.scala +++ b/core/src/test/scala/caliban/RenderingSpec.scala @@ -95,6 +95,24 @@ object RenderingSpec extends DefaultRunnableSpec { | "field-description" | age: Int! |}""".stripMargin.trim)) + }, + test("it should render empty objects without field list") { + assert(graphQL(InvalidSchemas.Object.resolverEmpty).render.trim)( + equalTo("""schema { + | query: TestEmptyObject + |} + | + |type EmptyObject + | + |type TestEmptyObject { + | o: EmptyObject! + |}""".stripMargin.trim) + ) + }, + test("it should not render a schema in no queries, mutations, or subscription") { + assert(graphQL(InvalidSchemas.resolverEmpty).render.trim)( + equalTo("") + ) } ) } diff --git a/core/src/test/scala/caliban/TestUtils.scala b/core/src/test/scala/caliban/TestUtils.scala index df21aceda4..347c09f45e 100644 --- a/core/src/test/scala/caliban/TestUtils.scala +++ b/core/src/test/scala/caliban/TestUtils.scala @@ -518,5 +518,6 @@ object TestUtils { TestWrongFieldArgDirectiveName(_ => UIO.unit) ) + val resolverEmpty = new RootResolver(Option.empty[Unit], Option.empty[Unit], Option.empty[Unit]) } }