From ece29b6b0d6da432642be943e72bb7f59b02c572 Mon Sep 17 00:00:00 2001 From: Rohan Sircar Date: Mon, 19 Apr 2021 19:51:58 +0530 Subject: [PATCH] many changes --- build.sbt | 54 ++++---- src/main/scala/wow/doge/mygame/Main.scala | 2 +- src/main/scala/wow/doge/mygame/MainApp.scala | 7 +- .../moddingsystem/ModdingSystem.scala | 129 ++++-------------- .../scriptsystem/MonixScriptCompiler.scala | 49 +++++-- .../scriptsystem/ScriptSystemModule.scala | 6 +- .../scala/wow/doge/mygame/utils/IOUtils.scala | 11 ++ .../scala/wow/doge/mygame/AmmoniteTest.scala | 32 +++++ .../wow/doge/mygame/AssetManagerTest.scala | 80 ++++++----- .../mygame/CollisionShapeFactoryTest.scala | 28 ++-- .../wow/doge/mygame/FileWatcherTest.scala | 26 ++-- ...ctor3fTest.scala => ImVector3fSuite.scala} | 54 +++++--- .../wow/doge/mygame/ModdingSystemTest.scala | 16 ++- .../scala/wow/doge/mygame/MonixBioSuite.scala | 13 ++ .../doge/mygame/MonixScriptCompilerTest.scala | 17 ++- 15 files changed, 282 insertions(+), 242 deletions(-) create mode 100644 src/test/scala/wow/doge/mygame/AmmoniteTest.scala rename src/test/scala/wow/doge/mygame/{ImVector3fTest.scala => ImVector3fSuite.scala} (50%) create mode 100644 src/test/scala/wow/doge/mygame/MonixBioSuite.scala diff --git a/build.sbt b/build.sbt index 9ac3e53..e5c4cc6 100755 --- a/build.sbt +++ b/build.sbt @@ -18,6 +18,7 @@ lazy val osName = System.getProperty("os.name") match { lazy val javaFXModules = Seq("base", "controls", "fxml", "graphics", "media", "swing", "web") +testFrameworks += new TestFramework("munit.Framework") lazy val root = (project in file(".")).settings( name := "mygame", organization := "wow.doge", @@ -33,6 +34,7 @@ lazy val root = (project in file(".")).settings( "com.simsilica" % "zay-es" % "1.2.1", "org.typelevel" %% "cats-core" % "2.3.0", "com.lihaoyi" % "ammonite" % "2.2.0" cross CrossVersion.full, + // "com.lihaoyi" % "ammonite" % "2.3.8" % "test" cross CrossVersion.full, "org.jetbrains.kotlin" % "kotlin-main-kts" % "1.4.10", "org.jetbrains.kotlin" % "kotlin-scripting-jsr223" % "1.4.10", "org.codehaus.groovy" % "groovy-all" % "3.0.6" pomOnly (), @@ -75,7 +77,11 @@ lazy val root = (project in file(".")).settings( "org.kordamp.ikonli" % "ikonli-javafx" % "12.0.0", "org.kordamp.ikonli" % "ikonli-fontawesome5-pack" % "12.0.0", "org.kordamp.ikonli" % "ikonli-material-pack" % "12.0.0", - "org.kordamp.bootstrapfx" % "bootstrapfx-core" % "0.4.0" + "org.kordamp.bootstrapfx" % "bootstrapfx-core" % "0.4.0", + "org.scalameta" %% "munit" % "0.7.23" % Test, + "de.lolhens" %% "munit-tagless-final" % "0.0.1" % Test, + "org.scalameta" %% "munit-scalacheck" % "0.7.23" % Test, + "org.scalacheck" %% "scalacheck" % "1.15.3" % Test ), // Determine OS version of JavaFX binaries @@ -150,31 +156,23 @@ inThisBuild( ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.4.3" scalafixDependencies in ThisBuild += "org.scalalint" %% "rules" % "0.1.4" -// wartremoverErrors in (Compile, compile) ++= Warts.allBut( -// Wart.Any, -// Wart.Nothing, -// Wart.Serializable -// ) - -// wartremoverWarnings in (Compile, compile) ++= Seq(Wart.Any, Wart.Serializable) - -// wartremoverErrors in (Compile, compile) ++= -// Warts.allBut( -// Wart.Any, -// Wart.NonUnitStatements, -// // Wart.StringPlusAny, -// Wart.Overloading, -// Wart.PublicInference, -// Wart.Nothing, -// Wart.Var, -// Wart.DefaultArguments, -// // Wart.MutableDataStructures, -// Wart.ImplicitConversion, -// Wart.ImplicitParameter, -// Wart.ToString, -// Wart.Recursion, -// Wart.While, -// Wart.ExplicitImplicitTypes, -// Wart.ListUnapply -// ) +wartremoverErrors in (Compile, compile) ++= + Warts.allBut( + Wart.Any, + Wart.NonUnitStatements, + // Wart.StringPlusAny, + Wart.Overloading, + Wart.PublicInference, + Wart.Nothing, + Wart.Var, + Wart.DefaultArguments, + // Wart.MutableDataStructures, + Wart.ImplicitConversion, + Wart.ImplicitParameter, + Wart.ToString, + Wart.Recursion, + Wart.While, + Wart.ExplicitImplicitTypes, + Wart.ListUnapply + ) // Seq(Wart.FinalCaseClass) diff --git a/src/main/scala/wow/doge/mygame/Main.scala b/src/main/scala/wow/doge/mygame/Main.scala index f90234b..bca1c23 100644 --- a/src/main/scala/wow/doge/mygame/Main.scala +++ b/src/main/scala/wow/doge/mygame/Main.scala @@ -37,7 +37,7 @@ object Main extends BIOApp with ExecutorsModule { fileLogger( "application-log-1.log", Formatter.json - ).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(2000)) + ).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(100)) jmeScheduler <- jmeSchedulerResource // backend <- Resource.make(toIO(HttpClientMonixBackend()))(backend => // toIO(backend.close()) diff --git a/src/main/scala/wow/doge/mygame/MainApp.scala b/src/main/scala/wow/doge/mygame/MainApp.scala index c982b2c..ca29e8c 100644 --- a/src/main/scala/wow/doge/mygame/MainApp.scala +++ b/src/main/scala/wow/doge/mygame/MainApp.scala @@ -99,7 +99,12 @@ class MainApp( implicit val as = scheduler.value val scriptSystemResource: Resource[UIO, ScriptCompiler] = - new ScriptSystemResource(os.pwd, logger, ScriptInitMode.Eager).init2 + new ScriptSystemResource( + os.pwd, + logger, + ScriptInitMode.Eager, + schedulers.io + ).init2 val eventsModule = new EventsModule(scheduler, spawnProtocol) diff --git a/src/main/scala/wow/doge/mygame/subsystems/moddingsystem/ModdingSystem.scala b/src/main/scala/wow/doge/mygame/subsystems/moddingsystem/ModdingSystem.scala index dbf6278..fff29dc 100755 --- a/src/main/scala/wow/doge/mygame/subsystems/moddingsystem/ModdingSystem.scala +++ b/src/main/scala/wow/doge/mygame/subsystems/moddingsystem/ModdingSystem.scala @@ -18,6 +18,7 @@ import monix.reactive.Consumer import monix.reactive.Observable import wow.doge.mygame.implicits._ import wow.doge.mygame.utils.readAsyncL +import wow.doge.mygame.utils.IOUtils @JsonCodec final case class Test1(hello1: String, hello2: String) @@ -42,13 +43,15 @@ object ModdingSystem { implicit val eq = Eq.fromUniversalEquals[Error] } - def readPluginsList2(dir: os.Path) = - for { - contents <- readAsyncL(dir) - } yield () + val x: IO[Error, String] = + IOUtils.liftErrors(readAsyncL(os.pwd / "plugins.json")) { + case _: FileNotFoundException => + IO.raiseError(FileNotFound(os.pwd / "plugins.json")) + case _: NoSuchFileException => + IO.raiseError(FileNotFound(os.pwd / "plugins.json")) + } def readPluginsList(dir: os.Path): IO[Error, ArraySeq[Plugin]] = - // IO(os.read(dir / "plugins.json")) readAsyncL(dir / "plugins.json") .onErrorHandleWith { case _: FileNotFoundException => @@ -64,110 +67,28 @@ object ModdingSystem { ) .flatMap(result => IO.fromEither(result).mapError(DecodingFailure)) - // def findPluginFiles(dir: os.Path): View[os.Path] = - // os.list(dir) - // .view - // .filter(f => f.ext === "json" && f.baseName.endsWith("plugin")) - def findAndReadPluginFiles( dir: os.Path, plugins: ArraySeq[Plugin] - ): UIO[(View[(Plugin, Error)], View[(Plugin, String)])] = - UIO( - plugins - .sortBy(_.priority) - .view - .map { p => - val path = dir / os.RelPath(p.name + ".plugin.json") - p -> - Either - .catchNonFatal(os.read(path)) - .leftMap { - case _: FileNotFoundException => FileNotFound(path) - case _: NoSuchFileException => FileNotFound(path) - } - - } - .partitionMap { - case (p, either) => - either match { - case Left(value) => Left(p -> value) - case Right(value) => Right(p -> value) - } - } - ) - // : (View[(Plugin, Error)], View[(Plugin, String)]) - def findAndReadPluginFiles2( - dir: os.Path, - plugins: ArraySeq[Plugin] ) = - // IO.parTraverse(plugins.sortBy(_.priority))(p => - // IO { - // val path = dir / os.RelPath(p.name + ".plugin.json") - // os.read(path) - // } - // .onErrorHandleWith { - // case _: FileNotFoundException => - // IO.raiseError(FileNotFound(dir.toString)) - // case _: NoSuchFileException => - // IO.raiseError(FileNotFound(dir.toString)) - // } - // .flatMap(r => UIO(p -> r)) - // ).map { - // _.partitionMap { - // case (p, either) => - // either match { - // case Left(value) => Left(p -> value) - // case Right(value) => Right(p -> value) - // } - // } - // } - plugins - .sortBy(_.priority) - .view - .map { p => - val path = dir / os.RelPath(p.name + ".plugin.json") - p -> IO(os.read(path)) + IO + .parTraverse(plugins.sortBy(_.priority))(p => + readAsyncL(dir / os.RelPath(p.name + ".plugin.json")) .onErrorHandleWith { - case _: FileNotFoundException => IO.raiseError(FileNotFound(path)) - case _: NoSuchFileException => IO.raiseError(FileNotFound(path)) + case _: FileNotFoundException => + IO.raiseError(FileNotFound(dir)) + case _: NoSuchFileException => + IO.raiseError(FileNotFound(dir)) + case other => IO.terminate(other) } - // .map(r => p -> r) + .attempt + .map(r => p -> r) + ) + .map(_.partitionMap { + case p -> Left(value) => Left(p -> value) + case p -> Right(value) => Right(p -> value) + }) - } - .map { - case (p, io) => - io.attempt.map { - case Left(value) => Left(p -> value) - case Right(value) => Right(p -> value) - } - } - .to(List) - .parSequence - - // .partitionMap { - // _.map { - // case l @ Left(value) => l - // case r @ Right(value) => r - // } - // } - // .sequence - - // def readPluginFiles(filePaths: View[os.Path]) = - // filePaths.map(path => os.read(path)) - - // def readPluginFiles2(filePaths: View[os.Path]) = - // filePaths - // .map(path => - // IO(os.read(path)).onErrorHandleWith { - // case _: FileNotFoundException => - // IO.raiseError(FileNotFound(path)) - // case _: NoSuchFileException => - // IO.raiseError(FileNotFound(path)) - // } - // ) - // .to(List) - // .parSequence def parsePluginFiles(files: View[(Plugin, String)]) = files .map { @@ -197,10 +118,10 @@ object ModdingSystem { for { plugins <- readPluginsList(wd) (readFailures, readSuccesses) <- findAndReadPluginFiles(wd, plugins) - (parseFailures, parseSuccesses) <- UIO(parsePluginFiles(readSuccesses)) + (parseFailures, parseSuccesses) = parsePluginFiles(readSuccesses.view) res <- UIO.parMap5( UIO(readFailures.to(List)), - UIO(readSuccesses.to(List)), + UIO.pure(readSuccesses), UIO(parseFailures.to(List)), UIO(parseSuccesses.to(List)), Observable diff --git a/src/main/scala/wow/doge/mygame/subsystems/scriptsystem/MonixScriptCompiler.scala b/src/main/scala/wow/doge/mygame/subsystems/scriptsystem/MonixScriptCompiler.scala index 5a966d3..61f5e30 100644 --- a/src/main/scala/wow/doge/mygame/subsystems/scriptsystem/MonixScriptCompiler.scala +++ b/src/main/scala/wow/doge/mygame/subsystems/scriptsystem/MonixScriptCompiler.scala @@ -29,6 +29,8 @@ import monix.catnap.MVar import monix.reactive.Observable import monix.{eval => me} import wow.doge.mygame.implicits._ +import wow.doge.mygame.utils.readAsyncL +import wow.doge.mygame.executors.Schedulers trait Requestable[A] { @@ -84,7 +86,7 @@ object ScriptCompiler { sealed trait KotlinEngineTag type KotlinScriptEngine = ScriptEngine @@ KotlinEngineTag - sealed trait Error + sealed trait Error extends Product with Serializable final case class AmmoniteFailure(error: Res.Failure) extends Error final case class AmmoniteException(error: Res.Exception) extends Error final case class ScriptExceptionError(error: ScriptException) extends Error @@ -221,6 +223,24 @@ object ScriptCompiler { case _ => Left(SomeError("Failed to run script")) } + def runScala2(path: os.Path): IO[Error, Any] = + for { + scriptContent <- readAsyncL(path).hideErrors + res <- IO.fromEither( + scalaRunner + .runCode(scriptContent) + ._1 match { + case e @ Res.Exception(t, msg) => Left(AmmoniteException(e)) + + case f @ Failure(msg) => Left(AmmoniteFailure(f)) + + case Res.Success(obj) => Right(obj) + + case _ => Left(SomeError("Failed to run script")) + } + ) + } yield res + def runKotlin(path: os.Path): Either[Error, Any] = Either .catchNonFatal(kotlinRunner.eval(os.read(path))) @@ -228,6 +248,8 @@ object ScriptCompiler { case ex: ScriptException => ScriptExceptionError(ex) } + // def runKotlin2(path: os.path): IO[Error,] + def runGroovy(path: os.Path): Either[Error, Any] = Either .catchNonFatal(groovyRunner.run(path.relativeTo(os.pwd).toString, "")) @@ -243,9 +265,9 @@ object ScriptCompiler { class ScriptCompileSource( fns: ScriptCompileFns, logger: Logger[Task], - queue: ConcurrentQueue[Task, ScriptCompilerWorker.CompileRequest] + queue: ConcurrentQueue[Task, ScriptCompilerWorker.CompileRequest], + ioScheduler: Schedulers.IoScheduler ) { - import fns._ val source = Task.deferAction(implicit s => @@ -256,11 +278,12 @@ object ScriptCompiler { .mapParallelUnorderedF(4) { case ScriptCompilerWorker.CompileAny(path, result) => for { - mbRes <- Task( - runScala(path) - .flatMap(ensureReturnedObjectNotNull) - // .map(_.taggedWith[ScriptTag]) - ) + mbRes <- (logger.debugU("Test") >> Task( + fns + .runScala(path) + .flatMap(fns.ensureReturnedObjectNotNull) + // .map(_.taggedWith[ScriptTag]) + )).executeOn(ioScheduler.value) _ <- result.complete(mbRes) } yield mbRes } @@ -292,7 +315,8 @@ object ScriptCompiler { logger: Logger[Task], scalaRunner: ammonite.Main = defaultScalaRunner, kotlinRunner: KotlinScriptEngine = defaultKotlinRunner, - groovyRunner: GroovyScriptEngine = defaultGroovyRunner + groovyRunner: GroovyScriptEngine = defaultGroovyRunner, + ioScheduler: Schedulers.IoScheduler ) = { val acquire = for { queue <- ConcurrentQueue[Task].bounded[CompileRequest](10) @@ -310,14 +334,17 @@ object ScriptCompiler { } - def apply(logger: Logger[Task]): Resource[UIO, ScriptCompiler] = { + def apply( + logger: Logger[Task], + ioScheduler: Schedulers.IoScheduler + ): Resource[UIO, ScriptCompiler] = { def acquire(worker: ScriptCompilerWorker) = for { queue <- ConcurrentQueue.bounded[Task, Command](10) fib <- wire[SourceMaker].get.flatMap(_.completedL.toIO.start) } yield new ScriptCompiler(queue) -> fib - ScriptCompilerWorker(logger) + ScriptCompilerWorker(logger, ioScheduler = ioScheduler) .flatMap(worker => Resource.make(acquire(worker).hideErrors) { case (_, fib) => fib.cancel diff --git a/src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptSystemModule.scala b/src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptSystemModule.scala index fed3c58..ea73605 100644 --- a/src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptSystemModule.scala +++ b/src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptSystemModule.scala @@ -11,6 +11,7 @@ import monix.bio.Task import monix.bio.UIO import wow.doge.mygame.scriptsystem.ScriptCachingActor import wow.doge.mygame.utils.AkkaUtils +import wow.doge.mygame.executors.Schedulers /** * Scripts can either be searched and compiled at startup (Eager mode) @@ -24,7 +25,8 @@ object ScriptInitMode { class ScriptSystemResource( path: os.Path, logger: Logger[Task], - mode: ScriptInitMode = ScriptInitMode.Lazy + mode: ScriptInitMode = ScriptInitMode.Lazy, + ioScheduler: Schedulers.IoScheduler )(implicit spawnProtocol: ActorRef[SpawnProtocol.Command], timeout: Timeout, @@ -42,7 +44,7 @@ class ScriptSystemResource( } yield scriptCacheActor val init2: Resource[UIO, ScriptCompiler] = for { - sc <- ScriptCompiler(logger) + sc <- ScriptCompiler(logger, ioScheduler) } yield sc def findScriptFiles(wd: os.Path) = diff --git a/src/main/scala/wow/doge/mygame/utils/IOUtils.scala b/src/main/scala/wow/doge/mygame/utils/IOUtils.scala index f5f3ff6..a828117 100644 --- a/src/main/scala/wow/doge/mygame/utils/IOUtils.scala +++ b/src/main/scala/wow/doge/mygame/utils/IOUtils.scala @@ -14,4 +14,15 @@ object IOUtils { def fromCoevalEither[L, R](coeval: Coeval[Either[L, R]]) = coeval.to[Task].hideErrors.rethrow + def liftErrors[E, T]( + task: Task[T] + )(pf: PartialFunction[Throwable, IO[E, T]]): IO[E, T] = { + val _ = 1 + // val x = task.onErrorRecoverWith() + task.onErrorHandleWith(ex => pf.applyOrElse(ex, IO.terminate)) + } + + // final def mapErrorPartial[E1, B >: A](pf: PartialFunction[E, IO[E1, B]])(implicit ev: E <:< Throwable): IO[E1, B] = + // onErrorHandleWith(ex => pf.applyOrElse(ex, IO.terminate)) + } diff --git a/src/test/scala/wow/doge/mygame/AmmoniteTest.scala b/src/test/scala/wow/doge/mygame/AmmoniteTest.scala new file mode 100644 index 0000000..f847a7f --- /dev/null +++ b/src/test/scala/wow/doge/mygame/AmmoniteTest.scala @@ -0,0 +1,32 @@ +package wow.doge.mygame + +import monix.bio.Task +import wow.doge.mygame.subsystems.scriptsystem.ScriptCompiler +import monix.bio.UIO +import scala.concurrent.Future +import monix.execution.Scheduler + +class AmmoniteTest extends munit.TaglessFinalSuite[Task] { + + override protected def toFuture[A](f: Task[A]): Future[A] = { + implicit val s = Scheduler.global + f.runToFuture + } + + val scriptCompileFns = new ScriptCompiler.ScriptCompileFns( + ScriptCompiler.defaultScalaRunner, + ScriptCompiler.defaultKotlinRunner, + ScriptCompiler.defaultGroovyRunner + ) + + override def afterAll(): Unit = () + + test("Basic test") { + UIO( + scriptCompileFns + .runScala( + os.pwd / "assets" / "scripts" / "scala" / "basicTestScript.sc" + ) + ).assertEquals(Right("hello")) + } +} diff --git a/src/test/scala/wow/doge/mygame/AssetManagerTest.scala b/src/test/scala/wow/doge/mygame/AssetManagerTest.scala index 0fe7d4d..5a71552 100644 --- a/src/test/scala/wow/doge/mygame/AssetManagerTest.scala +++ b/src/test/scala/wow/doge/mygame/AssetManagerTest.scala @@ -1,67 +1,75 @@ package wow.doge.mygame -import scala.annotation.nowarn - -import cats.syntax.eq._ import com.jme3.asset.DesktopAssetManager import com.jme3.material.Material import com.jme3.material.MaterialDef import com.jme3.scene.Geometry import com.jme3.scene.Node -import com.jme3.{asset => jmea} -import monix.execution.Scheduler.Implicits.global -import org.scalatest.funsuite.AnyFunSuite import wow.doge.mygame.utils.wrappers.jme.AssetManager import wow.doge.mygame.utils.wrappers.jme.AssetManager.AssetNotFound import wow.doge.mygame.utils.wrappers.jme.AssetManager.CouldNotCastError -@nowarn("msg=method get in class LeftProjection is deprecated") -@nowarn("msg=method right in class Either is deprecated") -@nowarn("msg=method get in class RightProjection is deprecated") -class AssetManagerTest extends AnyFunSuite { +class AssetManagerTest extends MonixBioSuite { - val _assetManager: jmea.AssetManager = new DesktopAssetManager(true) - val assetManager = new AssetManager(_assetManager) + val fixture = FunFixture[AssetManager]( + setup = _ => new AssetManager(new DesktopAssetManager(true)), + teardown = _ => () + ) - test("Test for AssetNotFound error") { - val res = - assetManager.loadModel(os.rel / "doesnotexist").attempt.runSyncUnsafe() - assert(res.isLeft) - assert(res.left.get eqv AssetNotFound("doesnotexist")) + override def beforeAll(): Unit = { + import java.util.logging.{Logger => JLogger, Level} + JLogger.getLogger("").setLevel(Level.SEVERE) } - test("Test for Model CouldNotCastError") { + fixture.test( + "AssetManager#loadModel should fail with AssetNotFoundError when asset does not exist" + ) { assetManager => + assetManager + .loadModel(os.rel / "doesnotexist") + .attempt + .assertEquals(Left(AssetNotFound("doesnotexist"))) + } + + fixture.test( + "AssetManager#loadModelAs should fail with CouldNotCastError when model is not of target type" + ) { assetManager => val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o" - val res1 = assetManager + assetManager .loadModelAs[Geometry](modelPath) .attempt - .runSyncUnsafe() - assert(res1.isLeft) - assert(res1.left.get eqv CouldNotCastError) + .assertEquals(Left(CouldNotCastError)) - val res2 = assetManager + } + + fixture.test( + "AssetManager#loadModelAs should load com.jme3.Node successfully" + ) { assetManager => + val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o" + assetManager .loadModelAs[Node](modelPath) .attempt - .runSyncUnsafe() - assert(res2.isRight) - assert(res2.map(_.getName).right.get eqv "JaimeGeom-ogremesh") + .map(_.map(_.getName)) + .assertEquals(Right("JaimeGeom-ogremesh")) } - test("Test for Asset CouldNotCastError") { + fixture.test( + "AssetManager#loadAssetAs should fail with CouldNotCastError when asset is not of target type" + ) { assetManager => val assetPath = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md" - - val res1 = assetManager + assetManager .loadAssetAs[Material](assetPath) .attempt - .runSyncUnsafe() - assert(res1.isLeft) - assert(res1.left.get eqv CouldNotCastError) + .assertEquals(Left(CouldNotCastError)) + } - val res2 = assetManager + fixture.test( + "AssetManager#loadAssetAs should should load asset succesfully" + ) { assetManager => + val assetPath = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md" + assetManager .loadAssetAs[MaterialDef](assetPath) .attempt - .runSyncUnsafe() - assert(res2.isRight) - assert(res2.map(_.getName).right.get eqv "Unshaded") + .map(_.map(_.getName)) + .assertEquals(Right("Unshaded")) } } diff --git a/src/test/scala/wow/doge/mygame/CollisionShapeFactoryTest.scala b/src/test/scala/wow/doge/mygame/CollisionShapeFactoryTest.scala index af81a94..49a80de 100644 --- a/src/test/scala/wow/doge/mygame/CollisionShapeFactoryTest.scala +++ b/src/test/scala/wow/doge/mygame/CollisionShapeFactoryTest.scala @@ -1,35 +1,27 @@ package wow.doge.mygame -import java.util.Queue - -import cats.syntax.eq._ import com.jme3.bounding.BoundingVolume import com.jme3.collision.Collidable import com.jme3.collision.CollisionResults import com.jme3.scene.SceneGraphVisitor import com.jme3.scene.Spatial import com.jme3.scene.Spatial.DFSMode -import monix.execution.Scheduler.Implicits.global -import org.scalatest.funsuite.AnyFunSuite import wow.doge.mygame.utils.wrappers.jme.CollisionShapeFactory -import scala.annotation.nowarn -@nowarn("msg=method get in class LeftProjection is deprecated") -class CollisionShapeFactoryTest extends AnyFunSuite { +import java.util.Queue + +class CollisionShapeFactoryTest extends MonixBioSuite { test("Test for WrongArgumentError") { - val res = CollisionShapeFactory + CollisionShapeFactory .createMeshShape(new TestSpatial) .attempt - .runSyncUnsafe() - - assert(res.isLeft) - - assert( - res.left.get eqv - CollisionShapeFactory.WrongArgumentError( - "The spatial must either be a Node or a Geometry!" + .assertEquals( + Left( + CollisionShapeFactory.WrongArgumentError( + "The spatial must either be a Node or a Geometry!" + ) ) - ) + ) } } diff --git a/src/test/scala/wow/doge/mygame/FileWatcherTest.scala b/src/test/scala/wow/doge/mygame/FileWatcherTest.scala index 016de09..7f4b63f 100644 --- a/src/test/scala/wow/doge/mygame/FileWatcherTest.scala +++ b/src/test/scala/wow/doge/mygame/FileWatcherTest.scala @@ -4,13 +4,21 @@ import scala.concurrent.duration._ import cats.syntax.show._ import monix.bio.IO -import monix.eval.Task import monix.reactive.Observable -import org.scalatest.funsuite.AnyFunSuite import wow.doge.mygame.implicits._ import wow.doge.mygame.utils.MonixDirectoryWatcher +import scala.concurrent.Future +import monix.execution.Scheduler +import monix.bio.Task +import monix.{eval => me} + +class FileWatcherTest extends munit.TaglessFinalSuite[Task] { + + override protected def toFuture[A](f: Task[A]): Future[A] = { + implicit val s = Scheduler.global + f.runToFuture + } -class FileWatcherTest extends AnyFunSuite { // test("1") { // import better.files._ // import io.methvin.better.files._ @@ -36,27 +44,27 @@ class FileWatcherTest extends AnyFunSuite { val obsT = MonixDirectoryWatcher(os.pwd / "assets" / "scripts") - import monix.execution.Scheduler.Implicits.global obsT .flatMap( _.takeUntil(Observable.unit.delayExecution(2.seconds)) .doOnNext { case MonixDirectoryWatcher.CreateEvent(file, count) => - Task(println(show"${file.toString} got created")) + me.Task(println(show"${file.toString} got created")) case MonixDirectoryWatcher.DeleteEvent(file, count) => - Task(println(show"${file.toString} got deleted")) + me.Task(println(show"${file.toString} got deleted")) case MonixDirectoryWatcher.ModifyEvent(file, count) => - Task(pprint.log(show"${file.toString} got modified $count times")) + me.Task( + pprint.log(show"${file.toString} got modified $count times") + ) } .completedL - .flatMap(_ => Task.sleep(3.seconds)) + .flatMap(_ => me.Task.sleep(3.seconds)) .toIO ) .onErrorHandleWith { case ex: java.nio.file.ClosedWatchServiceException => IO.unit case ex: java.lang.UnsupportedOperationException => IO.unit } - .runSyncUnsafe(16.seconds) } } diff --git a/src/test/scala/wow/doge/mygame/ImVector3fTest.scala b/src/test/scala/wow/doge/mygame/ImVector3fSuite.scala similarity index 50% rename from src/test/scala/wow/doge/mygame/ImVector3fTest.scala rename to src/test/scala/wow/doge/mygame/ImVector3fSuite.scala index a43bc2a..b28a5e3 100644 --- a/src/test/scala/wow/doge/mygame/ImVector3fTest.scala +++ b/src/test/scala/wow/doge/mygame/ImVector3fSuite.scala @@ -1,12 +1,41 @@ package wow.doge.mygame -import cats.syntax.eq._ -import cats.syntax.show._ -import com.typesafe.scalalogging.LazyLogging -import org.scalatest.funsuite.AnyFunSuite +import munit.ScalaCheckSuite +import org.scalacheck.Prop._ +import munit.FunSuite import wow.doge.mygame.math.ImVector3f +import com.typesafe.scalalogging.LazyLogging +import cats.syntax.show._ +import cats.syntax.eq._ +import org.scalacheck.Gen +import org.scalacheck.Arbitrary.arbitrary + +class ImVector3fSuite extends FunSuite with ScalaCheckSuite with LazyLogging { + + val floatGen = for { + a <- arbitrary[Float] + b <- arbitrary[Float] + c <- arbitrary[Float] + } yield ImVector3f(a, b, c) + + val intGen = for { + a <- arbitrary[Int] + b <- arbitrary[Int] + c <- arbitrary[Int] + } yield ImVector3f(a.toFloat, b.toFloat, c.toFloat) + + property("imvector3f dst float") { + forAll(floatGen, floatGen) { (v1: ImVector3f, v2: ImVector3f) => + assertEquals(ImVector3f.dst(v1, v2), ImVector3f.dst(v2, v1)) + } + } + + property("imvector3f dst int") { + forAll(intGen, intGen) { (v1: ImVector3f, v2: ImVector3f) => + assertEquals(ImVector3f.dst(v1, v2), ImVector3f.dst(v2, v1)) + } + } -class ImVector3fTest extends AnyFunSuite with LazyLogging { test("maxvalue") { val v1 = ImVector3f.Max val v2 = ImVector3f.Max @@ -33,19 +62,4 @@ class ImVector3fTest extends AnyFunSuite with LazyLogging { assert(ImVector3f.dst(v1, v2) eqv ImVector3f.dst(v2, v1)) } - test("another") { - { - val v1 = ImVector3f(1, 0, 0) - val v2 = ImVector3f(1, 1, 1) - logger.info(ImVector3f.dst(v1, v2).show) - assert(ImVector3f.dst(v1, v2) eqv ImVector3f.dst(v2, v1)) - } - { - val v1 = ImVector3f(1, 1, 0) - val v2 = ImVector3f(1, 1, 1) - logger.info(ImVector3f.dst(v1, v2).show) - assert(ImVector3f.dst(v1, v2) eqv ImVector3f.dst(v2, v1)) - } - - } } diff --git a/src/test/scala/wow/doge/mygame/ModdingSystemTest.scala b/src/test/scala/wow/doge/mygame/ModdingSystemTest.scala index 2f882e1..0b1a4c6 100644 --- a/src/test/scala/wow/doge/mygame/ModdingSystemTest.scala +++ b/src/test/scala/wow/doge/mygame/ModdingSystemTest.scala @@ -3,11 +3,18 @@ package wow.doge.mygame import cats.syntax.eq._ import io.circe.Printer import monix.bio.UIO -import monix.execution.Scheduler.Implicits.global import org.scalatest.funsuite.AnyFunSuite import wow.doge.mygame.subsystems.moddingsystem.ModdingSystem +import monix.bio.Task +import scala.concurrent.Future +import monix.execution.Scheduler -class ModdingSystemTest extends AnyFunSuite { +class ModdingSystemTest extends munit.TaglessFinalSuite[Task] { + + override protected def toFuture[A](f: Task[A]): Future[A] = { + implicit val s = Scheduler.global + f.runToFuture + } val printer = Printer.spaces2 test("main") { val io = for { @@ -19,9 +26,6 @@ class ModdingSystemTest extends AnyFunSuite { ) _ <- ModdingSystem.log(res) } yield res - io.attempt.runSyncUnsafe() match { - case Left(value) => pprint.log(value); () - case Right(value) => () - } + io.attempt } } diff --git a/src/test/scala/wow/doge/mygame/MonixBioSuite.scala b/src/test/scala/wow/doge/mygame/MonixBioSuite.scala new file mode 100644 index 0000000..2ac767d --- /dev/null +++ b/src/test/scala/wow/doge/mygame/MonixBioSuite.scala @@ -0,0 +1,13 @@ +package wow.doge.mygame + +import scala.concurrent.Future + +import monix.bio.Task +import monix.execution.Scheduler + +trait MonixBioSuite extends munit.TaglessFinalSuite[Task] { + override protected def toFuture[A](f: Task[A]): Future[A] = { + implicit val s = Scheduler.global + f.runToFuture + } +} diff --git a/src/test/scala/wow/doge/mygame/MonixScriptCompilerTest.scala b/src/test/scala/wow/doge/mygame/MonixScriptCompilerTest.scala index d5f982b..eb956b0 100644 --- a/src/test/scala/wow/doge/mygame/MonixScriptCompilerTest.scala +++ b/src/test/scala/wow/doge/mygame/MonixScriptCompilerTest.scala @@ -4,14 +4,20 @@ import scala.concurrent.duration._ import io.odin.consoleLogger import monix.bio.Task -import monix.execution.Scheduler.Implicits.global -import org.scalatest.funsuite.AnyFunSuite import wow.doge.mygame.subsystems.scriptsystem.ScriptCompiler +import wow.doge.mygame.executors.Schedulers +import scala.concurrent.Future +import monix.execution.Scheduler -class MonixScriptCompilerTest extends AnyFunSuite { +class MonixScriptCompilerTest extends munit.TaglessFinalSuite[Task] { + + override protected def toFuture[A](f: Task[A]): Future[A] = { + implicit val s = Scheduler.global + f.runToFuture + } test("some-test") { - ScriptCompiler(consoleLogger[Task]()) + ScriptCompiler(consoleLogger[Task](), Schedulers.default.io) .use(scriptCompiler => for { // _ <- @@ -23,7 +29,7 @@ class MonixScriptCompilerTest extends AnyFunSuite { // .startAndForget response <- scriptCompiler.request( ScriptCompiler.GetScript( - os.pwd / "assets" / "scripts" / "scala" / "hello2.sc", + os.pwd / "assets" / "scripts" / "scala" / "hello.sc", _, false ) @@ -39,6 +45,5 @@ class MonixScriptCompilerTest extends AnyFunSuite { // _ <- Task.sleep(8.seconds) } yield () ) - .runSyncUnsafe(20.seconds) } }