From 398fa982f9d006db6198e02e6e61e99def96a48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Wed, 10 Aug 2022 16:25:58 +0200 Subject: [PATCH] Add encoding for timestamp, some tests --- .../scala/playground/NodeEncoderVisitor.scala | 10 ++-- .../main/scala/playground/QueryCompiler.scala | 2 +- .../main/scala/playground/smithyql/AST.scala | 6 ++ .../scala/playground/NodeEncoderTests.scala | 55 +++++++++++++++++++ .../smithyql/CompilationTests.scala | 24 ++++++++ 5 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 core/src/test/scala/playground/NodeEncoderTests.scala diff --git a/core/src/main/scala/playground/NodeEncoderVisitor.scala b/core/src/main/scala/playground/NodeEncoderVisitor.scala index 13f27c6e..9400f067 100644 --- a/core/src/main/scala/playground/NodeEncoderVisitor.scala +++ b/core/src/main/scala/playground/NodeEncoderVisitor.scala @@ -97,12 +97,10 @@ object NodeEncoderVisitor extends SchemaVisitor[NodeEncoder] { self => case PDouble => int.contramap(_.toInt) // todo: wraps case PDocument => document case PFloat => unsupported("float") - case PUnit => - // todo: inconsistent with decoder (takes everything) - _ => obj(Nil) - case PUUID => string.contramap(_.toString()) - case PByte => unsupported("byte") - case PTimestamp => string.contramap(_.toString) + case PUnit => struct(shapeId, hints, Vector.empty, _ => ()) + case PUUID => string.contramap(_.toString()) + case PByte => unsupported("byte") + case PTimestamp => string.contramap(_.toString) } def collection[C[_], A]( diff --git a/core/src/main/scala/playground/QueryCompiler.scala b/core/src/main/scala/playground/QueryCompiler.scala index 56d499db..9771d2a2 100644 --- a/core/src/main/scala/playground/QueryCompiler.scala +++ b/core/src/main/scala/playground/QueryCompiler.scala @@ -295,7 +295,7 @@ object QueryCompiler extends SchemaVisitor[PartialCompiler] { PartialCompiler .typeCheck(NodeKind.Bool) { case b @ BooleanLiteral(_) => b } .map(_.value.value) - case PUnit => _ => ().rightIor + case PUnit => struct(shapeId, hints, Vector.empty, _ => ()) case PInt => PartialCompiler .typeCheck(NodeKind.IntLiteral) { case i @ IntLiteral(_) => i } diff --git a/core/src/main/scala/playground/smithyql/AST.scala b/core/src/main/scala/playground/smithyql/AST.scala index cba3d092..ca937ec8 100644 --- a/core/src/main/scala/playground/smithyql/AST.scala +++ b/core/src/main/scala/playground/smithyql/AST.scala @@ -7,12 +7,18 @@ import cats.Applicative import cats.data.NonEmptyList import smithy4s.ShapeId import cats.Show +import cats.kernel.Eq +import cats.Id sealed trait AST[F[_]] extends Product with Serializable { def mapK[G[_]: Functor](fk: F ~> G): AST[G] def kind: NodeKind } +object AST { + implicit val astIdEq: Eq[AST[Id]] = Eq.fromUniversalEquals +} + sealed trait InputNode[F[_]] extends AST[F] { def fold[A]( diff --git a/core/src/test/scala/playground/NodeEncoderTests.scala b/core/src/test/scala/playground/NodeEncoderTests.scala new file mode 100644 index 00000000..a914b51a --- /dev/null +++ b/core/src/test/scala/playground/NodeEncoderTests.scala @@ -0,0 +1,55 @@ +package playground + +import cats.Id +import demo.smithy.Good +import playground.NodeEncoder +import playground.smithyql.AST +import playground.smithyql.DSL._ +import smithy4s.schema.Schema +import weaver._ +import demo.smithy.Hero +import smithy4s.Timestamp +import smithy.api.TimestampFormat + +object NodeEncoderTests extends FunSuite { + + def assertEncodes[A]( + schema: Schema[A], + value: A, + expected: AST[Id], + )( + implicit loc: SourceLocation + ) = { + val enc = NodeEncoder.derive(schema) + + assert.eql(enc.toNode(value), expected) + } + + test("unit") { + assertEncodes(Schema.unit, (), struct()) + } + + test("String") { + assertEncodes(Schema.string, "test", "test") + } + + test("int") { + assertEncodes(Schema.int, 42, 42) + } + + test("simple struct") { + assertEncodes(Good.schema, Good(42), struct("howGood" -> 42)) + } + + test("union") { + assertEncodes(Hero.schema, Hero.GoodCase(Good(42)), struct("good" -> struct("howGood" -> 42))) + } + + test("timestamp") { + assertEncodes( + Schema.timestamp, + Timestamp.parse("2022-07-11T17:42:28Z", TimestampFormat.DATE_TIME).get, + "2022-07-11T17:42:28Z", + ) + } +} diff --git a/core/src/test/scala/playground/smithyql/CompilationTests.scala b/core/src/test/scala/playground/smithyql/CompilationTests.scala index 9286a58a..fd092418 100644 --- a/core/src/test/scala/playground/smithyql/CompilationTests.scala +++ b/core/src/test/scala/playground/smithyql/CompilationTests.scala @@ -100,6 +100,30 @@ object CompilationTests extends SimpleIOSuite with Checkers { assert(result == Ior.leftNec(e)) } + pureTest("unit") { + assert( + compile { + WithSource.liftId(struct().mapK(WithSource.liftId)) + }(Schema.unit).isRight + ) + } + + pureTest("unit - doesn't accept string") { + assert( + compile { + WithSource.liftId("test".mapK(WithSource.liftId)) + }(Schema.unit).isLeft + ) + } + + pureTest("unit - doesn't accept struct with a field present") { + assert( + compile { + WithSource.liftId(struct("test" -> 42).mapK(WithSource.liftId)) + }(Schema.unit).isBoth + ) + } + pureTest("string") { assert( compile {