From 016e4c29ade696dbea12b5800d9ecba3c23c33cb Mon Sep 17 00:00:00 2001 From: Yuriy Mazepin Date: Thu, 30 May 2024 12:56:42 +0300 Subject: [PATCH] purs tests for scala 3 --- ops/src/main/scala-3/Common.scala | 2 +- ops/src/main/scala-3/ops.scala | 2 +- purs/src/test/scala-3/default.test.scala | 26 +++++ purs/src/test/scala-3/enum.test.scala | 25 +++++ purs/src/test/scala-3/eq.test.scala | 28 +++++ purs/src/test/scala-3/purs.test.scala | 135 +++++++++++++++++++++++ purs/src/test/scala-3/setmap.test.scala | 26 +++++ 7 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 purs/src/test/scala-3/default.test.scala create mode 100644 purs/src/test/scala-3/enum.test.scala create mode 100644 purs/src/test/scala-3/eq.test.scala create mode 100644 purs/src/test/scala-3/purs.test.scala create mode 100644 purs/src/test/scala-3/setmap.test.scala diff --git a/ops/src/main/scala-3/Common.scala b/ops/src/main/scala-3/Common.scala index b8a37d1..0b4af8a 100644 --- a/ops/src/main/scala-3/Common.scala +++ b/ops/src/main/scala-3/Common.scala @@ -5,7 +5,7 @@ import scala.collection.immutable.ArraySeq import compiletime.asMatchable import scala.annotation.* -trait Common: +trait CommonOps: implicit val qctx: Quotes import qctx.reflect.{*, given} import qctx.reflect.defn.* diff --git a/ops/src/main/scala-3/ops.scala b/ops/src/main/scala-3/ops.scala index abd95bf..1237446 100644 --- a/ops/src/main/scala-3/ops.scala +++ b/ops/src/main/scala-3/ops.scala @@ -3,7 +3,7 @@ package proto import scala.quoted.* import scala.annotation.* -trait Ops extends Common: +trait Ops extends CommonOps: implicit val qctx: Quotes import qctx.reflect.{*, given} import report.* diff --git a/purs/src/test/scala-3/default.test.scala b/purs/src/test/scala-3/default.test.scala new file mode 100644 index 0000000..a5f93c7 --- /dev/null +++ b/purs/src/test/scala-3/default.test.scala @@ -0,0 +1,26 @@ +package proto +package purs +package default + +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers + +class DefaultSpec extends AnyFreeSpec with Matchers { + "generate" - { + "src" in { + val res = proto.purs.generate[Push, Pull](moduleEncode="DefaultSpec.Pull", moduleDecode="DefaultSpec.Push", moduleCommon="DefaultSpec.Common") + res.purs.foreach{ case (filename, content) => + io.writeToFile(s"purs/test/src/$filename.purs", content) + } + } + } +} + +sealed trait Push +sealed trait Pull +@N(1) final case class SimpleT1(@N(1) m1: Option[Boolean], @N(2) b1: Boolean=false, @N(3) b2: String="") extends Push with Pull +@N(2) final case class SimpleT2(@N(1) b0: Boolean, @N(2) b1: Boolean=false, @N(3) b2: String="") extends Push with Pull +@N(3) final case class RecursiveT1(@N(1) b1: Boolean=false, @N(2) b2: String="", @N(3) x: RecursiveT1) extends Push with Pull +@N(4) final case class RecursiveT2(@N(1) b1: Boolean=false, @N(2) b2: String="", @N(3) x: Option[RecursiveT2]) extends Push with Pull +@N(5) final case class OneMaybe(@N(1) m1: Option[String]) extends Push with Pull +@N(6) final case class OneSeq(@N(1) xs: Seq[String]) extends Push with Pull diff --git a/purs/src/test/scala-3/enum.test.scala b/purs/src/test/scala-3/enum.test.scala new file mode 100644 index 0000000..42aa456 --- /dev/null +++ b/purs/src/test/scala-3/enum.test.scala @@ -0,0 +1,25 @@ +package proto +package purs +package `enum` + +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers + +class EnumSpec extends AnyFreeSpec with Matchers { + val res = proto.purs.generate[Push, Pull](moduleEncode="Enum.Pull", moduleDecode="Enum.Push", moduleCommon="Enum.Common") + "enum" - { + "print" in { + res.purs.foreach{ case (filename, content) => + io.writeToFile(s"purs/test/src/$filename.purs", content) + } + } + } +} + +sealed trait Push +@N(1) case object Pong extends Push +@N(2) case class Saved(@N(1) x: String) extends Push + +sealed trait Pull +@N(1) case object Ping extends Pull +@N(2) case class Save(@N(1) x: String) extends Pull diff --git a/purs/src/test/scala-3/eq.test.scala b/purs/src/test/scala-3/eq.test.scala new file mode 100644 index 0000000..0fd4455 --- /dev/null +++ b/purs/src/test/scala-3/eq.test.scala @@ -0,0 +1,28 @@ +package proto +package purs +package eq + +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers + +class EqSpec extends AnyFreeSpec with Matchers { + val res = proto.purs.generate[Push, Pull](moduleEncode="EqSpec.Pull", moduleDecode="EqSpec.Push", moduleCommon="EqSpec.Common") + "eq" - { + "out" in { + res.purs.foreach{ case (filename, content) => + io.writeToFile(s"purs/test/src/$filename.purs", content) + } + } + } +} + +sealed trait Push +sealed trait Pull +@N(1) case class Flow(@N(1) steps: Seq[FlowStep]) extends Push with Pull +sealed trait FlowStep +@N(1) case object Start extends FlowStep +@N(2) case class Ext(@N(1) tree: Node) extends FlowStep +case class Node(@N(1) root: String, @N(2) forest: Seq[Node]) +@N(2) case class B(@N(1) a: A) extends Pull +sealed trait A +@N(1) case class C(@N(1) bytes: Array[Byte]) extends A diff --git a/purs/src/test/scala-3/purs.test.scala b/purs/src/test/scala-3/purs.test.scala new file mode 100644 index 0000000..6876a3c --- /dev/null +++ b/purs/src/test/scala-3/purs.test.scala @@ -0,0 +1,135 @@ +package proto +package purs + +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers +import proto.{encode} +import proto.{caseCodecIdx, caseCodecAuto, sealedTraitCodecAuto} + +class PurescriptSpec extends AnyFreeSpec with Matchers { + "generate" - { + "src" in { + val res = proto.purs.generate[Push, Pull](moduleEncode="Pull", moduleDecode="Push", moduleCommon="Common") + res.purs.foreach{ case (filename, content) => + io.writeToFile(s"purs/test/src/$filename.purs", content) + } + } + "test" in { + val res = proto.purs.generate[TestSchema, TestSchema](moduleEncode="SchemaPull", moduleDecode="SchemaPush", moduleCommon="SchemaCommon") + res.purs.foreach{ case (filename, content) => + io.writeToFile(s"purs/test/test/$filename.purs", content) + } + + implicit val tc = caseCodecIdx[(String,String)] + implicit val ac = caseCodecAuto[ClassWithMap] + implicit val ac2 = caseCodecAuto[ClassWithLong] + implicit val ac3 = caseCodecAuto[ClassWithInt] + implicit val cwmc = sealedTraitCodecAuto[TestSchema] + val hellomap = encode[TestSchema](new ClassWithMap(Map("en_GB"->"Hello", "it_IT"->"Ciao"))) + val Number_MAX_SAFE_INTEGER = 9007199254740991L + val Number_MIN_SAFE_INTEGER = -9007199254740991L + val maxlong = encode[TestSchema](new ClassWithLong(Number_MAX_SAFE_INTEGER)) + val minlong = encode[TestSchema](new ClassWithLong(Number_MIN_SAFE_INTEGER)) + val maxbigint = encode[TestSchema](new ClassWithLong(Long.MaxValue)) + val minbigint = encode[TestSchema](new ClassWithLong(Long.MinValue)) + val maxint = encode[TestSchema](new ClassWithInt(Int.MaxValue)) + val minint = encode[TestSchema](new ClassWithInt(Int.MinValue)) + def bytes_to_str(xs: Array[Byte]): String = xs.map(x => if (x >= 0) x.toString else (x+256).toString).mkString(" ") + val exp = + s"""|module Cases where + | + |import Prelude (negate) + |import SchemaCommon + |import Data.Tuple (Tuple(Tuple)) + |import Proto.BigInt as BigInt + | + |map_schema :: TestSchema + |map_schema = ClassWithMap { m: [ Tuple "en_GB" "Hello", Tuple "it_IT" "Ciao" ] } + | + |map_bytestr :: String + |map_bytestr = "${bytes_to_str(hellomap)}" + | + |maxlong_schema :: TestSchema + |maxlong_schema = ClassWithLong { x: BigInt.fromNumber ($Number_MAX_SAFE_INTEGER.0) } + | + |maxlong_bytestr :: String + |maxlong_bytestr = "${bytes_to_str(maxlong)}" + | + |minlong_schema :: TestSchema + |minlong_schema = ClassWithLong { x: BigInt.fromNumber ($Number_MIN_SAFE_INTEGER.0) } + | + |minlong_bytestr :: String + |minlong_bytestr = "${bytes_to_str(minlong)}" + | + |max_bigint_schema :: TestSchema + |max_bigint_schema = ClassWithLong { x: BigInt.fromString "${Long.MaxValue}" } + | + |max_bigint_bytestr :: String + |max_bigint_bytestr = "${bytes_to_str(maxbigint)}" + | + |min_bigint_schema :: TestSchema + |min_bigint_schema = ClassWithLong { x: BigInt.fromString "${Long.MinValue}" } + | + |min_bigint_bytestr :: String + |min_bigint_bytestr = "${bytes_to_str(minbigint)}" + | + |maxint_schema :: TestSchema + |maxint_schema = ClassWithInt { x: ${Int.MaxValue} } + | + |maxint_bytestr :: String + |maxint_bytestr = "${bytes_to_str(maxint)}" + | + |minint_schema :: TestSchema + |minint_schema = ClassWithInt { x: ${Int.MinValue} } + | + |minint_bytestr :: String + |minint_bytestr = "${bytes_to_str(minint)}" + |""".stripMargin + io.writeToFile("purs/test/test/Cases.purs", exp) + } + } +} + +final case class FieldNode(@N(1) root: String, @N(2) forest: List[FieldNode]) +final case class FieldNode1(@N(1) root: Option[String], @N(2) forest: List[FieldNode1]) +sealed trait TestSchema +@N(1) final case class ClassWithMap(@N(1) m: Map[String,String]) extends TestSchema +@N(2) final case class ClassWithLong(@N(1) x: Long) extends TestSchema +@N(3) final case class ClassWithInt(@N(1) x: Int) extends TestSchema + +sealed trait Push +@N(1) final case class SiteOpts(@N(1) xs: LazyList[SiteOpt]) extends Push +@N(2) final case class Permissions(@N(1) xs: List[String]) extends Push +@N(3) final case class Page(@N(1) tpe: PageType, @N(2) guest: Boolean, @N(3) seo: PageSeo, @N(4) mobileSeo: Option[PageSeo], @N(5) name: Map[String,String]) extends Push +final case class PageSeo(@N(1) descr: String, @N(2) order: Double) +@N(4) final case class PageTreeItem(@N(1) priority: Int) extends Push +@N(5) case object Ping extends Push + +@N(1300) final case class ComponentTemplateOk + ( @N(1) fieldNode: FieldNode + , @N(2) fieldNode1: FieldNode1 + ) extends Push + +final case class SiteOpt(@N(1) id: String, @N(2) label: Option[String]) +sealed trait PageType +@N(1) case object PageWidgets extends PageType +@N(2) final case class PageUrl(@N(1) addr: String) extends PageType + +sealed trait Pull +@N(1000) final case class GetSites() extends Pull +@N(1001) final case class UploadChunk + ( @N(1) path: List[String] + , @N(2) id: String + , @N(3) chunk: Array[Byte] + ) extends Pull +@N(1002) final case class SavePage(@N(1) tpe: PageType, @N(2) guest: Boolean, @N(3) seo: PageSeo, @N(4) mobileSeo: Option[PageSeo], @N(5) name: Map[String,String]) extends Pull +@N(1400) final case class SaveComponentTemplate + ( @N(1) fieldNode: FieldNode + ) extends Pull +@N(1920) final case class ComponentsSavePrefs + ( @N(1) id: String + , @N(2) pageid: String + , @N(3) siteid: String + , @N(4) tree: FieldNode + , @N(5) extTree: Option[FieldNode] + ) extends Pull diff --git a/purs/src/test/scala-3/setmap.test.scala b/purs/src/test/scala-3/setmap.test.scala new file mode 100644 index 0000000..09d731f --- /dev/null +++ b/purs/src/test/scala-3/setmap.test.scala @@ -0,0 +1,26 @@ +package proto +package purs +package setmap + +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers +import scala.collection.immutable.ListSet + +class SetMapSpec extends AnyFreeSpec with Matchers { + val res = proto.purs.generate[Push, Pull](moduleEncode="SetMap.Pull", moduleDecode="SetMap.Push", moduleCommon="SetMap.Common") + "set/map" - { + "print" in { + res.purs.foreach{ case (filename, content) => + io.writeToFile(s"purs/test/src/$filename.purs", content) + } + } + } +} + +sealed trait Push +sealed trait Pull +@N(1) final case class Flow1(@N(1) graph: String Map ListSet[String]) extends Push with Pull +@N(2) final case class Flow2(@N(1) graph: StepId Map ListSet[StepId]) extends Push with Pull +sealed trait StepId +@N(1) case object Prod extends StepId +@N(2) case object Dev extends StepId