diff --git a/benchmarks/src/main/scala/caliban/ParserBenchmark.scala b/benchmarks/src/main/scala/caliban/ParserBenchmark.scala index a20f5306b0..370286aa8a 100644 --- a/benchmarks/src/main/scala/caliban/ParserBenchmark.scala +++ b/benchmarks/src/main/scala/caliban/ParserBenchmark.scala @@ -25,7 +25,7 @@ class ParserBenchmark { @Benchmark def runCaliban(): Document = - Parser.parseQueryEither(fullIntrospectionQuery).fold(throw _, identity) + Parser.parseQuery(fullIntrospectionQuery).fold(throw _, identity) @Benchmark def runSangria(): sangria.ast.Document = diff --git a/benchmarks/src/main/scala/caliban/validation/ValidationBenchmark.scala b/benchmarks/src/main/scala/caliban/validation/ValidationBenchmark.scala index 3b0cbe52fd..a7f604d9ba 100644 --- a/benchmarks/src/main/scala/caliban/validation/ValidationBenchmark.scala +++ b/benchmarks/src/main/scala/caliban/validation/ValidationBenchmark.scala @@ -4,9 +4,8 @@ import caliban._ import caliban.execution.NestedZQueryBenchmarkSchema import caliban.introspection.Introspector import caliban.parsing.{ Parser, VariablesCoercer } -import caliban.schema.{ RootSchema, RootType } -import org.openjdk.jmh.annotations.{ Scope, _ } -import zio._ +import caliban.schema.RootType +import org.openjdk.jmh.annotations._ import java.util.concurrent.TimeUnit @@ -18,17 +17,16 @@ import java.util.concurrent.TimeUnit @Fork(2) class ValidationBenchmark { - private val runtime = Runtime.default + def run[A](either: Either[Throwable, A]): A = either.fold(throw _, identity) - def run[A](zio: Task[A]): A = Unsafe.unsafe(implicit u => runtime.unsafe.run(zio).getOrThrow()) - def toSchema[R](graphQL: GraphQL[R]): IO[CalibanError, RootType] = - graphQL.validateRootSchema.map { schema => + def toRootType[R](graphQL: GraphQL[R]): RootType = + run(graphQL.validateRootSchema.map { schema => RootType( schema.query.opType, schema.mutation.map(_.opType), schema.subscription.map(_.opType) ) - } + }) import NestedZQueryBenchmarkSchema._ @@ -38,72 +36,54 @@ class ValidationBenchmark { val parsedDeepWithArgsQuery = run(Parser.parseQuery(deepWithArgsQuery)) val parsedIntrospectionQuery = run(Parser.parseQuery(ComplexQueryBenchmark.fullIntrospectionQuery)) - val simpleType = run( - toSchema(graphQL[Any, SimpleRoot, Unit, Unit](RootResolver(NestedZQueryBenchmarkSchema.simple100Elements))) - ) + val simpleType = + toRootType(graphQL[Any, SimpleRoot, Unit, Unit](RootResolver(NestedZQueryBenchmarkSchema.simple100Elements))) val multifieldType = - run( - toSchema( - graphQL[Any, MultifieldRoot, Unit, Unit]( - RootResolver(NestedZQueryBenchmarkSchema.multifield100Elements) - ) + toRootType( + graphQL[Any, MultifieldRoot, Unit, Unit]( + RootResolver(NestedZQueryBenchmarkSchema.multifield100Elements) ) ) val deepType = - run( - toSchema( - graphQL[Any, DeepRoot, Unit, Unit]( - RootResolver[DeepRoot](NestedZQueryBenchmarkSchema.deep100Elements) - ) + toRootType( + graphQL[Any, DeepRoot, Unit, Unit]( + RootResolver[DeepRoot](NestedZQueryBenchmarkSchema.deep100Elements) ) ) val deepWithArgsType = - run( - toSchema( - graphQL[Any, DeepWithArgsRoot, Unit, Unit]( - RootResolver[DeepWithArgsRoot](NestedZQueryBenchmarkSchema.deepWithArgs100Elements) - ) + toRootType( + graphQL[Any, DeepWithArgsRoot, Unit, Unit]( + RootResolver[DeepWithArgsRoot](NestedZQueryBenchmarkSchema.deepWithArgs100Elements) ) ) @Benchmark - def simple(): Any = { - val io = Validator.validate(parsedSimpleQuery, simpleType) - run(io) - } + def simple(): Any = + run(Validator.validateAll(parsedSimpleQuery, simpleType)) @Benchmark - def multifield(): Any = { - val io = Validator.validate(parsedMultifieldQuery, multifieldType) - run(io) - } + def multifield(): Any = + run(Validator.validateAll(parsedMultifieldQuery, multifieldType)) @Benchmark - def deep(): Any = { - val io = Validator.validate(parsedDeepQuery, deepType) - run(io) - } + def deep(): Any = + run(Validator.validateAll(parsedDeepQuery, deepType)) @Benchmark - def variableCoercer(): Any = { - val io = VariablesCoercer.coerceVariables(deepArgs100Elements, parsedDeepWithArgsQuery, deepWithArgsType, false) - run(io) - } + def variableCoercer(): Any = + run(VariablesCoercer.coerceVariables(deepArgs100Elements, parsedDeepWithArgsQuery, deepWithArgsType, false)) @Benchmark - def introspection(): Any = { - val io = - Validator.validate(parsedIntrospectionQuery, Introspector.introspectionRootType) - run(io) - } + def introspection(): Any = + run(Validator.validateAll(parsedIntrospectionQuery, Introspector.introspectionRootType)) @Benchmark def fieldCreationSimple(): Any = - Validator - .prepareEither( + run( + Validator.prepare( parsedSimpleQuery, simpleType, None, @@ -111,12 +91,12 @@ class ValidationBenchmark { skipValidation = true, validations = Nil ) - .fold(throw _, identity) + ) @Benchmark def fieldCreationMultifield(): Any = - Validator - .prepareEither( + run( + Validator.prepare( parsedMultifieldQuery, multifieldType, None, @@ -124,12 +104,12 @@ class ValidationBenchmark { skipValidation = true, validations = Nil ) - .fold(throw _, identity) + ) @Benchmark - def fieldCreationDeep(): Any = - Validator - .prepareEither( + def fieldCreationDeep(): Any = + run( + Validator.prepare( parsedDeepQuery, deepType, None, @@ -137,12 +117,11 @@ class ValidationBenchmark { skipValidation = true, validations = Nil ) - .fold(throw _, identity) - + ) @Benchmark def fieldCreationIntrospection(): Any = - Validator - .prepareEither( + run( + Validator.prepare( parsedIntrospectionQuery, Introspector.introspectionRootType, None, @@ -150,6 +129,6 @@ class ValidationBenchmark { skipValidation = true, validations = Nil ) - .fold(throw _, identity) + ) } diff --git a/benchmarks/src/test/scala/caliban/CalibanSpec.scala b/benchmarks/src/test/scala/caliban/CalibanSpec.scala index 5cd063a7d9..e9ff6d5f9a 100644 --- a/benchmarks/src/test/scala/caliban/CalibanSpec.scala +++ b/benchmarks/src/test/scala/caliban/CalibanSpec.scala @@ -22,8 +22,9 @@ object CalibanSpec extends ZIOSpecDefault { assertTrue(Caliban.run(io).errors.isEmpty) }, test("Parser") { - val io = Parser.parseQuery(fullIntrospectionQuery) - assertTrue(Caliban.run(io).definitions.nonEmpty) + Parser.parseQuery(fullIntrospectionQuery).map { doc => + assertTrue(doc.definitions.nonEmpty) + } } ) } diff --git a/core/src/main/scala/caliban/GraphQL.scala b/core/src/main/scala/caliban/GraphQL.scala index 591acd01fe..97ffbe5fa3 100644 --- a/core/src/main/scala/caliban/GraphQL.scala +++ b/core/src/main/scala/caliban/GraphQL.scala @@ -15,7 +15,7 @@ import caliban.validation.Validator import caliban.wrappers.Wrapper import caliban.wrappers.Wrapper._ import zio.stacktracer.TracingImplicits.disableAutoTrace -import zio.{ IO, Trace, URIO, ZIO } +import zio.{ Exit, IO, Trace, URIO, Unsafe, ZIO } /** * A `GraphQL[-R]` represents a GraphQL API whose execution requires a ZIO environment of type `R`. @@ -31,8 +31,8 @@ trait GraphQL[-R] { self => protected val features: Set[Feature] protected val transformer: Transformer[R] - private[caliban] def validateRootSchema(implicit trace: Trace): IO[ValidationError, RootSchema[R]] = - ZIO.fromEither(Validator.validateSchemaEither(schemaBuilder)) + private[caliban] def validateRootSchema: Either[ValidationError, RootSchema[R]] = + Validator.validateSchema(schemaBuilder) /** * Returns a string that renders the API types into the GraphQL SDL. @@ -63,8 +63,8 @@ trait GraphQL[-R] { self => * * @see [[interpreterEither]] for a variant that returns an Either instead, making it easier to embed in non-ZIO applications */ - final def interpreter(implicit trace: Trace): IO[ValidationError, GraphQLInterpreter[R, CalibanError]] = - ZIO.fromEither(interpreterEither) + final def interpreter: Exit[ValidationError, GraphQLInterpreter[R, CalibanError]] = + Exit.fromEither(interpreterEither) /** * Impure variant of [[interpreterEither]] which throws schema validation errors. Useful for cases that the @@ -72,7 +72,7 @@ trait GraphQL[-R] { self => */ @throws[CalibanError.ValidationError]("if the schema is invalid") final def interpreterUnsafe: GraphQLInterpreter[R, CalibanError] = - interpreterEither.fold(throw _, identity) + Unsafe.unsafe(interpreter.getOrThrowFiberFailure()(_)) /** * Creates an interpreter from your API. A GraphQLInterpreter is a wrapper around your API that allows @@ -83,7 +83,7 @@ trait GraphQL[-R] { self => * @see [[interpreterUnsafe]] of an unsafe variant that will throw validation errors */ final lazy val interpreterEither: Either[ValidationError, GraphQLInterpreter[R, CalibanError]] = - Validator.validateSchemaEither(schemaBuilder).map { schema => + validateRootSchema.map { schema => new GraphQLInterpreter[R, CalibanError] { private val rootType = RootType( @@ -98,9 +98,12 @@ trait GraphQL[-R] { self => private val introWrappers = wrappers.collect { case w: IntrospectionWrapper[R] => w } private lazy val introspectionRootSchema: RootSchema[R] = Introspector.introspect(rootType, introWrappers) + private def parseZIO(query: String)(implicit trace: Trace): IO[CalibanError.ParsingError, Document] = + ZIO.fromEither(Parser.parseQuery(query)) + override def check(query: String)(implicit trace: Trace): IO[CalibanError, Unit] = for { - document <- Parser.parseQuery(query) + document <- parseZIO(query) intro = Introspector.isIntrospection(document) typeToValidate = if (intro) Introspector.introspectionRootType else rootType _ <- Validator.validate(document, typeToValidate) @@ -113,7 +116,7 @@ trait GraphQL[-R] { self => case (overallWrappers, parsingWrappers, validationWrappers, executionWrappers, fieldWrappers, _) => wrap((request: GraphQLRequest) => (for { - doc <- wrap(Parser.parseQuery)(parsingWrappers, request.query.getOrElse("")) + doc <- wrap(parseZIO)(parsingWrappers, request.query.getOrElse("")) coercedVars <- coerceVariables(doc, request.variables.getOrElse(Map.empty)) executionReq <- wrap(validation(request.operationName, coercedVars))(validationWrappers, doc) result <- wrap(execution(schemaToExecute(doc), fieldWrappers))(executionWrappers, executionReq) @@ -128,7 +131,7 @@ trait GraphQL[-R] { self => if (doc.isIntrospection && !config.enableIntrospection) ZIO.fail(CalibanError.ValidationError("Introspection is disabled", "")) else - VariablesCoercer.coerceVariablesEither(variables, doc, typeToValidate(doc), config.skipValidation) match { + VariablesCoercer.coerceVariables(variables, doc, typeToValidate(doc), config.skipValidation) match { case Right(value) => ZIO.succeed(value) case Left(error) => ZIO.fail(error) } @@ -139,7 +142,7 @@ trait GraphQL[-R] { self => coercedVars: Map[String, InputValue] )(doc: Document)(implicit trace: Trace): IO[ValidationError, ExecutionRequest] = Configurator.ref.getWith { config => - Validator.prepareEither( + Validator.prepare( doc, typeToValidate(doc), operationName, diff --git a/core/src/main/scala/caliban/parsing/Parser.scala b/core/src/main/scala/caliban/parsing/Parser.scala index d31270f1aa..b34c4b495f 100644 --- a/core/src/main/scala/caliban/parsing/Parser.scala +++ b/core/src/main/scala/caliban/parsing/Parser.scala @@ -4,8 +4,6 @@ import caliban.CalibanError.ParsingError import caliban.InputValue import caliban.parsing.adt._ import fastparse._ -import zio.stacktracer.TracingImplicits.disableAutoTrace -import zio.{ IO, Trace, ZIO } import scala.util.Try import scala.util.control.NonFatal @@ -13,20 +11,11 @@ import scala.util.control.NonFatal object Parser { import caliban.parsing.parsers.Parsers._ - /** - * Parses the given string into a [[caliban.parsing.adt.Document]] object or fails with a [[caliban.CalibanError.ParsingError]]. - * - * @see [[parseQueryEither]] for a version that returns an `Either` instead of an `IO`. - */ - def parseQuery(query: String)(implicit trace: Trace): IO[ParsingError, Document] = ZIO.fromEither { - parseQueryEither(query) - } - /** * Parses the given string into a [[caliban.parsing.adt.Document]] object or returns a [[caliban.CalibanError.ParsingError]] * if the string is not a valid GraphQL document. */ - def parseQueryEither(query: String): Either[ParsingError, Document] = { + def parseQuery(query: String): Either[ParsingError, Document] = { val sm = SourceMapper(query) try parse(query, document(_)) match { diff --git a/core/src/main/scala/caliban/parsing/VariablesCoercer.scala b/core/src/main/scala/caliban/parsing/VariablesCoercer.scala index 8c948e20e1..7927ab3789 100644 --- a/core/src/main/scala/caliban/parsing/VariablesCoercer.scala +++ b/core/src/main/scala/caliban/parsing/VariablesCoercer.scala @@ -22,7 +22,7 @@ object VariablesCoercer { doc: Document, rootType: RootType, skipValidation: Boolean - )(implicit trace: Trace): IO[ValidationError, GraphQLRequest] = + ): Either[ValidationError, GraphQLRequest] = coerceVariables(req.variables.getOrElse(Map.empty), doc, rootType, skipValidation) .map(m => req.copy(variables = Some(m))) @@ -31,14 +31,6 @@ object VariablesCoercer { doc: Document, rootType: RootType, skipValidation: Boolean - )(implicit trace: Trace): IO[ValidationError, Map[String, InputValue]] = - ZIO.fromEither(coerceVariablesEither(variables, doc, rootType, skipValidation)) - - def coerceVariablesEither( - variables: Map[String, InputValue], - doc: Document, - rootType: RootType, - skipValidation: Boolean ): Either[ValidationError, Map[String, InputValue]] = { // Scala 2's compiler loves inferring `ZPure.succeed` as ZPure[Nothing, Nothing, Any, R, E, A] so we help it out type F[+A] = EReader[Any, ValidationError, A] diff --git a/core/src/main/scala/caliban/validation/Validator.scala b/core/src/main/scala/caliban/validation/Validator.scala index 183313cea1..74d835eabd 100644 --- a/core/src/main/scala/caliban/validation/Validator.scala +++ b/core/src/main/scala/caliban/validation/Validator.scala @@ -49,18 +49,23 @@ object Validator { ) /** - * Verifies that the given document is valid for this type. Fails with a [[caliban.CalibanError.ValidationError]] otherwise. + * Verifies that the given document is valid for this type. + * Fails with a [[caliban.CalibanError.ValidationError]] otherwise. */ def validate(document: Document, rootType: RootType)(implicit trace: Trace): IO[ValidationError, Unit] = Configurator.ref.getWith(v => ZIO.fromEither(check(document, rootType, Map.empty, v.validations).map(_ => ()))) /** - * Verifies that the given schema is valid. Fails with a [[caliban.CalibanError.ValidationError]] otherwise. + * Verifies that the given document is valid for this type for all available validations. + * Fails with a [[caliban.CalibanError.ValidationError]] otherwise. */ - def validateSchema[R](schema: RootSchemaBuilder[R])(implicit trace: Trace): IO[ValidationError, RootSchema[R]] = - ZIO.fromEither(validateSchemaEither(schema)) + def validateAll(document: Document, rootType: RootType): Either[ValidationError, Unit] = + check(document, rootType, Map.empty, AllValidations).map(_ => ()) - def validateSchemaEither[R](schema: RootSchemaBuilder[R]): Either[ValidationError, RootSchema[R]] = { + /** + * Verifies that the given schema is valid. Fails with a [[caliban.CalibanError.ValidationError]] otherwise. + */ + def validateSchema[R](schema: RootSchemaBuilder[R]): Either[ValidationError, RootSchema[R]] = { val types = schema.types ZPure.foreachDiscard(types.sorted)(validateType) *> validateClashingTypes(types) *> @@ -89,8 +94,6 @@ object Validator { /** * Prepare the request for execution. * Fails with a [[caliban.CalibanError.ValidationError]] otherwise. - * - * @see [[prepareEither]] for a variant that returns an Either instead */ def prepare( document: Document, @@ -99,21 +102,6 @@ object Validator { variables: Map[String, InputValue], skipValidation: Boolean, validations: List[QueryValidation] - ): IO[ValidationError, ExecutionRequest] = ZIO.fromEither( - prepareEither(document, rootType, operationName, variables, skipValidation, validations) - )(Trace.empty) - - /** - * Prepare the request for execution. - * Fails with a [[caliban.CalibanError.ValidationError]] otherwise. - */ - def prepareEither( - document: Document, - rootType: RootType, - operationName: Option[String], - variables: Map[String, InputValue], - skipValidation: Boolean, - validations: List[QueryValidation] ): Either[ValidationError, ExecutionRequest] = { val fragments: Either[ValidationError, Map[String, FragmentDefinition]] = if (skipValidation) { Right( diff --git a/core/src/test/scala/caliban/RenderingSpec.scala b/core/src/test/scala/caliban/RenderingSpec.scala index 441ea8ae4c..fdfde45f71 100644 --- a/core/src/test/scala/caliban/RenderingSpec.scala +++ b/core/src/test/scala/caliban/RenderingSpec.scala @@ -57,7 +57,7 @@ object RenderingSpec extends ZIOSpecDefault { case other => other } - def checkApi[R](api: GraphQL[R]): IO[ParsingError, TestResult] = { + def checkApi[R](api: GraphQL[R]): Either[ParsingError, TestResult] = { val definitions = fixDefinitions(api.toDocument.definitions.filter { case d: Definition.TypeSystemDefinition.TypeDefinition.ScalarTypeDefinition => !DocumentRenderer.isBuiltinScalar(d.name) @@ -230,10 +230,10 @@ object RenderingSpec extends ZIOSpecDefault { private def roundTrip(file: String, isCompact: Boolean = false) = ZIO.scoped(for { - input <- ZIO.fromAutoCloseable(ZIO.attempt(Source.fromResource(file))).map(_.mkString) - doc <- Parser.parseQuery(input) - rendered = if (isCompact) DocumentRenderer.renderCompact(doc) else DocumentRenderer.render(doc) - reparsed <- Parser.parseQuery(rendered).either + input <- ZIO.fromAutoCloseable(ZIO.attempt(Source.fromResource(file))).map(_.mkString) + doc <- ZIO.fromEither(Parser.parseQuery(input)) + rendered = if (isCompact) DocumentRenderer.renderCompact(doc) else DocumentRenderer.render(doc) + reparsed = Parser.parseQuery(rendered) } yield assertTrue(input == rendered, reparsed.isRight)) @GQLOneOfInput diff --git a/core/src/test/scala/caliban/execution/FieldSpec.scala b/core/src/test/scala/caliban/execution/FieldSpec.scala index 8ad32032db..fd59be9130 100644 --- a/core/src/test/scala/caliban/execution/FieldSpec.scala +++ b/core/src/test/scala/caliban/execution/FieldSpec.scala @@ -53,20 +53,22 @@ object FieldSpec extends ZIOSpecDefault { fields <- ref.get } yield fields - private def prepare(query: String) = for { - ref <- Ref.make[Chunk[Field]](Chunk.empty) - schema <- api(ref).validateRootSchema - doc <- Parser.parseQuery(query) - rootType = RootType(schema.query.opType, mutationType = None, subscriptionType = None) - req <- Validator.prepare( - doc, - rootType, - operationName = None, - Map.empty, - skipValidation = false, - validations = AllValidations - ) - } yield req + private def prepare(query: String) = Unsafe.unsafe { implicit us => + val ref = Ref.unsafe.make[Chunk[Field]](Chunk.empty) + for { + schema <- api(ref).validateRootSchema + doc <- Parser.parseQuery(query) + rootType = RootType(schema.query.opType, mutationType = None, subscriptionType = None) + req <- Validator.prepare( + doc, + rootType, + operationName = None, + Map.empty, + skipValidation = false, + validations = AllValidations + ) + } yield req + } private val targetsSpec = suite("targets")( test("gets populated with inline fragments") { diff --git a/core/src/test/scala/caliban/parsing/DocumentSpec.scala b/core/src/test/scala/caliban/parsing/DocumentSpec.scala index 9d04ac6fdc..1ed1a7b340 100644 --- a/core/src/test/scala/caliban/parsing/DocumentSpec.scala +++ b/core/src/test/scala/caliban/parsing/DocumentSpec.scala @@ -2,7 +2,6 @@ package caliban.parsing import caliban.TestUtils import org.apache.commons.lang3.SerializationUtils -import zio._ import zio.test._ object DocumentSpec extends ZIOSpecDefault { @@ -10,7 +9,7 @@ object DocumentSpec extends ZIOSpecDefault { test("is serializable") { for { doc1 <- Parser.parseQuery(TestUtils.introspectionQuery) - doc2 <- ZIO.attempt(SerializationUtils.roundtrip(doc1)) + doc2 = SerializationUtils.roundtrip(doc1) } yield assertTrue(doc1 == doc2) } ) diff --git a/core/src/test/scala/caliban/parsing/ParserSpec.scala b/core/src/test/scala/caliban/parsing/ParserSpec.scala index 9bc27d07f3..1a951fcf97 100644 --- a/core/src/test/scala/caliban/parsing/ParserSpec.scala +++ b/core/src/test/scala/caliban/parsing/ParserSpec.scala @@ -465,16 +465,12 @@ object ParserSpec extends ZIOSpecDefault { | name( | } |}""".stripMargin - Parser - .parseQuery(query) - .exit - .map( - assert(_)( - fails( - isSubtype[ParsingError](hasField("locationInfo", _.locationInfo, isSome(equalTo(LocationInfo(3, 4))))) - ) - ) + + assert(Parser.parseQuery(query))( + isLeft( + isSubtype[ParsingError](hasField("locationInfo", _.locationInfo, isSome(equalTo(LocationInfo(3, 4))))) ) + ) }, test("type") { val gqltype = diff --git a/core/src/test/scala/caliban/validation/ValidationSpec.scala b/core/src/test/scala/caliban/validation/ValidationSpec.scala index c23e54b34f..17c535e08b 100644 --- a/core/src/test/scala/caliban/validation/ValidationSpec.scala +++ b/core/src/test/scala/caliban/validation/ValidationSpec.scala @@ -531,7 +531,7 @@ object ValidationSpec extends ZIOSpecDefault { ) }, test("schema is valid") { - api.validateRootSchema.as(assertCompletes) + api.validateRootSchema.map(_ => assertCompletes) } ) } diff --git a/federation/src/test/scala/caliban/federation/v2x/FederationV2Spec.scala b/federation/src/test/scala/caliban/federation/v2x/FederationV2Spec.scala index 1ab0b32cb9..6527e32835 100644 --- a/federation/src/test/scala/caliban/federation/v2x/FederationV2Spec.scala +++ b/federation/src/test/scala/caliban/federation/v2x/FederationV2Spec.scala @@ -226,7 +226,7 @@ object FederationV2Spec extends ZIOSpecDefault { interpreter <- f(api).interpreter data <- interpreter.execute(query).map(resp => decode[Json](resp.data.toString)).absolve sdl <- ZIO.fromEither(data.hcursor.downField("_service").downField("sdl").as[String]) - document <- Parser.parseQuery(sdl) + document <- ZIO.fromEither(Parser.parseQuery(sdl)) } yield document.definitions.flatMap { case Definition.TypeSystemDefinition.SchemaDefinition(d, _, _, _, _) => d.map(_.copy(index = 0)) // Unset the index to make the test deterministic diff --git a/tools/src/main/scala/caliban/tools/SchemaLoader.scala b/tools/src/main/scala/caliban/tools/SchemaLoader.scala index 5d6860921f..d0e9daf2b5 100644 --- a/tools/src/main/scala/caliban/tools/SchemaLoader.scala +++ b/tools/src/main/scala/caliban/tools/SchemaLoader.scala @@ -22,10 +22,10 @@ object SchemaLoader { ZIO .attempt(scala.io.Source.fromFile(path)) .acquireReleaseWithAuto(f => ZIO.attempt(f.mkString)) - }.flatMap(Parser.parseQuery) + }.map(Parser.parseQuery).absolve } case class FromString private[SchemaLoader] (schema: String) extends SchemaLoader { - override def load: Task[Document] = Parser.parseQuery(schema) + override def load: Task[Document] = ZIO.fromEither(Parser.parseQuery(schema)) } case class FromIntrospection private[SchemaLoader] ( url: String, diff --git a/tools/src/test/scala/caliban/tools/ClientWriterSpec.scala b/tools/src/test/scala/caliban/tools/ClientWriterSpec.scala index 958c547107..374bc7fe33 100644 --- a/tools/src/test/scala/caliban/tools/ClientWriterSpec.scala +++ b/tools/src/test/scala/caliban/tools/ClientWriterSpec.scala @@ -1,7 +1,7 @@ package caliban.tools import caliban.parsing.Parser -import zio.Task +import zio.{ Task, ZIO } import zio.test._ object ClientWriterSpec extends SnapshotTest { @@ -13,8 +13,8 @@ object ClientWriterSpec extends SnapshotTest { extensibleEnums: Boolean = false, excludeDeprecated: Boolean = false, genView: Boolean = false - ): Task[String] = Parser - .parseQuery(schema) + ): Task[String] = ZIO + .fromEither(Parser.parseQuery(schema)) .flatMap(doc => Formatter.format( ClientWriter @@ -35,8 +35,8 @@ object ClientWriterSpec extends SnapshotTest { def genSplit( schema: String, scalarMappings: Map[String, String] = Map.empty - ): Task[List[(String, String)]] = Parser - .parseQuery(schema) + ): Task[List[(String, String)]] = ZIO + .fromEither(Parser.parseQuery(schema)) .flatMap(doc => Formatter.format( ClientWriter.write(doc, packageName = Some("test"), splitFiles = true, scalarMappings = Some(scalarMappings)), diff --git a/tools/src/test/scala/caliban/tools/ClientWriterViewSpec.scala b/tools/src/test/scala/caliban/tools/ClientWriterViewSpec.scala index cfc9576658..311cbf6461 100644 --- a/tools/src/test/scala/caliban/tools/ClientWriterViewSpec.scala +++ b/tools/src/test/scala/caliban/tools/ClientWriterViewSpec.scala @@ -1,15 +1,15 @@ package caliban.tools import caliban.parsing.Parser -import zio.Task import zio.test._ +import zio.{ Task, ZIO } object ClientWriterViewSpec extends SnapshotTest { override val testName: String = "ClientWriterViewSpec" val gen: String => Task[String] = (schema: String) => - Parser - .parseQuery(schema) + ZIO + .fromEither(Parser.parseQuery(schema)) .flatMap(doc => Formatter.format(ClientWriter.write(doc, genView = true, scalarMappings = None).head._2, None)) override def spec = diff --git a/tools/src/test/scala/caliban/tools/SchemaComparisonSpec.scala b/tools/src/test/scala/caliban/tools/SchemaComparisonSpec.scala index 09c4196f5b..8326fe158f 100644 --- a/tools/src/test/scala/caliban/tools/SchemaComparisonSpec.scala +++ b/tools/src/test/scala/caliban/tools/SchemaComparisonSpec.scala @@ -16,7 +16,7 @@ object SchemaComparisonSpec extends ZIOSpecDefault { schema1: String, schema2: String, expected: List[String] - ): ZIO[Any, CalibanError.ParsingError, TestResult] = + ): Either[CalibanError.ParsingError, TestResult] = for { s1 <- Parser.parseQuery(schema1) s2 <- Parser.parseQuery(schema2) @@ -27,7 +27,7 @@ object SchemaComparisonSpec extends ZIOSpecDefault { schema1: String, schema2: String, expected: List[SchemaComparisonChange] - ): ZIO[Any, CalibanError.ParsingError, TestResult] = + ): Either[CalibanError.ParsingError, TestResult] = for { s1 <- Parser.parseQuery(schema1) s2 <- Parser.parseQuery(schema2) @@ -253,8 +253,9 @@ object SchemaComparisonSpec extends ZIOSpecDefault { val expected = SchemaComparisonChange.DirectiveDefinitionRepeatableChanged("test", from = false, to = true) - compareChanges(nonRepeatable, repeatable, List(expected)) && - assertTrue(!expected.breaking) + compareChanges(nonRepeatable, repeatable, List(expected)).map( + _ && assertTrue(!expected.breaking) + ) }, test("becomes non-repeatable") { val repeatable = "directive @test repeatable on FIELD_DEFINITION" @@ -262,9 +263,9 @@ object SchemaComparisonSpec extends ZIOSpecDefault { val expected = SchemaComparisonChange.DirectiveDefinitionRepeatableChanged("test", from = true, to = false) - compareChanges(repeatable, nonRepeatable, List(expected)) && - assertTrue(expected.breaking) - + compareChanges(repeatable, nonRepeatable, List(expected)).map { + _ && assertTrue(expected.breaking) + } }, test("changes in base interfaces") { val schema1: String = diff --git a/tools/src/test/scala/caliban/tools/SchemaWriterSpec.scala b/tools/src/test/scala/caliban/tools/SchemaWriterSpec.scala index 16fd556b98..72953a8487 100644 --- a/tools/src/test/scala/caliban/tools/SchemaWriterSpec.scala +++ b/tools/src/test/scala/caliban/tools/SchemaWriterSpec.scala @@ -2,7 +2,7 @@ package caliban.tools import caliban.parsing.Parser import caliban.parsing.adt.Directives.NewtypeDirective -import zio.Task +import zio.{ Task, ZIO } import zio.test._ object SchemaWriterSpec extends SnapshotTest { @@ -17,8 +17,8 @@ object SchemaWriterSpec extends SnapshotTest { isEffectTypeAbstract: Boolean = false, preserveInputNames: Boolean = false, addDerives: Boolean = false - ): Task[String] = Parser - .parseQuery(schema.stripMargin) + ): Task[String] = ZIO + .fromEither(Parser.parseQuery(schema.stripMargin)) .flatMap(doc => Formatter .format(