From cf7eed845d4c179d68b3d8aa3a6b5657ffbbb902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Gonz=C3=A1lez?= Date: Sat, 22 Feb 2020 20:47:24 +0100 Subject: [PATCH] Add Union validation (#230) --- .../src/main/scala/caliban/CalibanError.scala | 2 +- .../scala/caliban/validation/Validator.scala | 33 +++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/caliban/CalibanError.scala b/core/src/main/scala/caliban/CalibanError.scala index 06f2064e72..b7740765f7 100644 --- a/core/src/main/scala/caliban/CalibanError.scala +++ b/core/src/main/scala/caliban/CalibanError.scala @@ -28,7 +28,7 @@ object CalibanError { */ case class ValidationError(msg: String, explanatoryText: String, locationInfo: Option[LocationInfo] = None) extends CalibanError { - override def toString: String = s"ValidationError Error: $msg}" + override def toString: String = s"ValidationError Error: $msg" } /** diff --git a/core/src/main/scala/caliban/validation/Validator.scala b/core/src/main/scala/caliban/validation/Validator.scala index 92e1ce85fe..d31e5a13d2 100644 --- a/core/src/main/scala/caliban/validation/Validator.scala +++ b/core/src/main/scala/caliban/validation/Validator.scala @@ -31,8 +31,9 @@ object Validator { def validateSchema(rootType: RootType): IO[ValidationError, Unit] = IO.foreach(rootType.types.values) { t => t.kind match { - case __TypeKind.ENUM => validateEnum(t) - case _ => IO.unit + case __TypeKind.ENUM => validateEnum(t) + case __TypeKind.UNION => validateUnion(t) + case _ => IO.unit } } .unit @@ -573,6 +574,34 @@ object Validator { ) } + private def validateUnion(t: __Type): IO[ValidationError, Unit] = { + + def isObject(t: __Type): Boolean = t.kind match { + case __TypeKind.OBJECT => true + case _ => false + } + + t.possibleTypes match { + case None | Some(Nil) => + IO.fail( + ValidationError( + s"Union ${t.name.getOrElse("")} doesn't contain any type.", + "A Union type must include one or more unique member types." + ) + ) + case Some(types) if !types.forall(isObject) => + IO.fail( + ValidationError( + s"Union ${t.name.getOrElse("")} contains the following non Object types: " + + types.filterNot(isObject).map(_.name.getOrElse("")).filterNot(_.isEmpty).mkString("", ", ", "."), + s"The member types of a Union type must all be Object base types." + ) + ) + case _ => IO.unit + } + + } + case class Context( document: Document, rootType: RootType,