Skip to content

Commit

Permalink
Merge pull request #210 from buildo/munit
Browse files Browse the repository at this point in the history
Migrate tests to MUnit + other improvements
  • Loading branch information
gabro authored Mar 31, 2020
2 parents 359d0cb + aea31ff commit e6d2325
Show file tree
Hide file tree
Showing 49 changed files with 1,052 additions and 1,261 deletions.
16 changes: 4 additions & 12 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import Dependencies._
import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}
import org.scalajs.sbtplugin.ScalaJSCrossVersion

val scala212 = "2.12.8"
val scala213 = "2.13.0-RC2"
val scala212 = "2.12.11"
val scala213 = "2.13.1"

inThisBuild(
List(
scalaVersion := "2.12.8",
scalaVersion := scala212,
// crossScalaVersions := List(scala212, scala213),
licenses += ("MIT", url("http://opensource.org/licenses/MIT")),
homepage := Some(url("https://github.com/buildo/retro")),
Expand All @@ -19,6 +19,7 @@ inThisBuild(
url("https://github.com/gabro"),
),
),
testFrameworks += new TestFramework("munit.Framework"),
),
)

Expand Down Expand Up @@ -118,24 +119,15 @@ lazy val metarpheusCore = crossProject(JSPlatform, JVMPlatform)
.settings(
name := "metarpheus-core",
dynverTagPrefix := "metarpheus-",
)
.jvmSettings(
libraryDependencies ++= metarpheusCoreDependencies,
)
.jsSettings(
libraryDependencies ++= metarpheusCoreDependencies.map { dep =>
if (dep.configurations == Some(Test.name)) dep
else dep.cross(ScalaJSCrossVersion.binary)
},
)

lazy val metarpheusJsFacade = project
.in(file("metarpheus/jsFacade"))
.enablePlugins(ScalaJSPlugin, ScalaJSBundlerPlugin)
.settings(
name := "metarpheus-js-facade",
scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.CommonJSModule) },
scalacOptions += "-P:scalajs:sjsDefinedByDefault",
libraryDependencies ++= metarpheusJsFacadeDependencies.map(_.cross(ScalaJSCrossVersion.binary)),
dynverTagPrefix := "metarpheus-",
)
Expand Down
2 changes: 1 addition & 1 deletion ci/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ resources:
icon: docker
source:
repository: buildo/scala-sbt-alpine
tag: 8u201_2.12.8_1.2.8
tag: 8u201_2.12.11_1.3.8

jobs:

Expand Down
2 changes: 1 addition & 1 deletion ci/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ image_resource:
type: docker-image
source:
repository: hseeberger/scala-sbt
tag: 8u181_2.12.8_1.2.8
tag: 8u242_1.3.8_2.12.10

inputs:
- name: retro
Expand Down
2 changes: 1 addition & 1 deletion enumero/ci/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ image_resource:
type: docker-image
source:
repository: buildo/scala-sbt-alpine
tag: 8u201_2.12.8_1.2.8
tag: 8u201_2.12.11_1.3.8

inputs:
- name: retro
Expand Down
31 changes: 14 additions & 17 deletions enumero/circe/src/test/scala/CirceSupportSpec.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import io.buildo.enumero._
import io.buildo.enumero.circe._
import io.circe.{DecodingFailure, Json}
import io.circe.syntax._
import io.circe.parser._
import io.circe.parser.parse

import org.scalatest.{Matchers, WordSpec}
class CirceSupportSuite extends munit.FunSuite {

class CirceSupportSpec extends WordSpec with Matchers {
sealed trait Planet extends CaseEnum
object Planet {
case object Mercury extends Planet
Expand All @@ -17,36 +15,35 @@ class CirceSupportSpec extends WordSpec with Matchers {
val planetMap = Map[Planet, Int](
Planet.Mercury -> 12,
Planet.Venus -> 812763,
Planet.Earth -> 0
Planet.Earth -> 0,
)

val planetMapJson: Json = parse("""
val planetMapJson = parse("""
{
"Mercury": 12,
"Venus": 812763,
"Earth": 0
}
""").getOrElse(Json.Null)
""").right.get

"CirceSupport handles encoding of a map with CaseEnum keys" in {
test("CirceSupport handles encoding a map with CaseEnum keys") {
val encodedJson = planetMap.asJson

encodedJson shouldBe planetMapJson
assertEquals(encodedJson, planetMapJson)
}

"CirceSupport handles dencoding of a json with CaseEnum keys" in {
planetMapJson.as[Map[Planet, Int]].getOrElse(Json.Null) shouldBe planetMap
test("CirceSupport handles decoding a json with CaseEnum keys") {
assertEquals(planetMapJson.as[Map[Planet, Int]].right.get, planetMap)
}

"CirceSupport handles dencoding of a json with wrong CaseEnum keys" in {
parse("""
test("CirceSupport handles decoding a json with wrong CaseEnum keys") {
val decodeResult = parse("""
{
"Mercury": 12,
"Venus": 812763,
"wrongKey": 0
}
""")
.getOrElse(Json.Null)
.as[Map[Planet, Int]] shouldBe a[Left[_, DecodingFailure]]
""").right.get
.as[Map[Planet, Int]]
assert(decodeResult.isLeft)
}
}
75 changes: 35 additions & 40 deletions enumero/core/src/test/scala/CaseEnumIndex.scala
Original file line number Diff line number Diff line change
@@ -1,66 +1,61 @@
import io.buildo.enumero._
import scala.language.reflectiveCalls

import org.scalatest.{Matchers, WordSpec}

class CaseEnumIndexSpec extends WordSpec with Matchers {
class CaseEnumIndexSuite extends munit.FunSuite {
sealed trait Planet extends IndexedCaseEnum { type Index = Int }
object Planet {
case object Mercury extends Planet { val index = 1 }
case object Venus extends Planet { val index = 2 }
case object Earth extends Planet { val index = 3 }
}

"CaseEnumIndexMacro" should {
"construct a sensible CaseEnumIndex" in {
val converter = CaseEnumIndex.caseEnumIndex[Planet]
test("CaseEnumIndexMacro should construct a sensible CaseEnumIndex") {
val converter = CaseEnumIndex.caseEnumIndex[Planet]

val pairs = List(Planet.Mercury -> 1, Planet.Venus -> 2, Planet.Earth -> 3)
val pairs = List(Planet.Mercury -> 1, Planet.Venus -> 2, Planet.Earth -> 3)

for ((co, index) <- pairs) {
converter.caseToIndex(co).shouldBe(index)
converter.caseFromIndex(index).shouldBe(Some(co))
}
for ((co, index) <- pairs) {
assertEquals(converter.caseToIndex(co), index)
assertEquals(converter.caseFromIndex(index), Some(co))
}
}

"CaseEnumIndex" should {
"provide the typeclass instance" in {
trait FakeBinaryPickler[T] {
def pickle(c: T)(picklerState: { def writeInt(int: Int) }): Unit
def unpickle(unpicklerState: { def getInt(): Int }): Option[T]
}
test("CaseEnumIndex should provide the typeclass instance") {
trait FakeBinaryPickler[T] {
def pickle(c: T)(picklerState: { def writeInt(int: Int): Unit }): Unit
def unpickle(unpicklerState: { def getInt(): Int }): Option[T]
}

implicit def fakeBinaryPickler[T <: IndexedCaseEnum { type Index = Int }](
implicit instance: CaseEnumIndex[T]
) = new FakeBinaryPickler[T] {
implicit def fakeBinaryPickler[T <: IndexedCaseEnum { type Index = Int }](
implicit instance: CaseEnumIndex[T],
) = new FakeBinaryPickler[T] {

def pickle(c: T)(picklerState: { def writeInt(int: Int) }): Unit = {
picklerState.writeInt(instance.caseToIndex(c))
}
def unpickle(unpicklerState: { def getInt(): Int }): Option[T] = {
instance.caseFromIndex(unpicklerState.getInt())
}
def pickle(c: T)(picklerState: { def writeInt(int: Int): Unit }): Unit = {
picklerState.writeInt(instance.caseToIndex(c))
}

object picklerState {
var value: Int = 0
def writeInt(int: Int): Unit = {
value = int
}
def unpickle(unpicklerState: { def getInt(): Int }): Option[T] = {
instance.caseFromIndex(unpicklerState.getInt())
}
val binaryPickler = implicitly[FakeBinaryPickler[Planet]]
binaryPickler.pickle(Planet.Venus)(picklerState)
picklerState.value.shouldBe(2)
}

object unpicklerState {
def getInt(): Int = 3
object picklerState {
var value: Int = 0
def writeInt(int: Int): Unit = {
value = int
}
binaryPickler.unpickle(unpicklerState).shouldBe(Some(Planet.Earth))
}
val binaryPickler = implicitly[FakeBinaryPickler[Planet]]
binaryPickler.pickle(Planet.Venus)(picklerState)
assertEquals(picklerState.value, 2)

"retrieve a typeclass instance using apply" in {
CaseEnumIndex[Planet].caseFromIndex(1) shouldBe Some(Planet.Mercury)
object unpicklerState {
def getInt(): Int = 3
}
assertEquals(binaryPickler.unpickle(unpicklerState), Some(Planet.Earth))
}

test("CaseEnumIndex should retrieve a typeclass instance using apply") {
assertEquals(CaseEnumIndex[Planet].caseFromIndex(1), Some(Planet.Mercury))
}

}
94 changes: 43 additions & 51 deletions enumero/core/src/test/scala/CaseEnumMacroSpec.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import io.buildo.enumero.annotations.{enum, indexedEnum}

import org.scalatest.{Matchers, WordSpec}

class CaseEnumMacroSpec extends WordSpec with Matchers {
class CaseEnumMacroSuite extends munit.FunSuite {
@enum trait Planet {
Mercury
Venus
Expand All @@ -14,43 +12,39 @@ class CaseEnumMacroSpec extends WordSpec with Matchers {
object Ale
}

"@enum annotation" should {
"produce a valid CaseEnum-style ADT" in {
Planet.Earth shouldBe a[Product]
Planet.Earth shouldBe a[Serializable]
Planet.Earth shouldBe a[Planet]
Planet.Mercury should not be a[Planet.Earth.type]
Planet.Earth shouldBe Planet.Earth
}
test("@enum annotation should produce a valid CaseEnum-style ADT") {
assert(Planet.Earth.isInstanceOf[Product])
assert(Planet.Earth.isInstanceOf[Serializable])
assert(Planet.Earth.isInstanceOf[Planet])
assertEquals(Planet.Earth, Planet.Earth)
}

"produce a valid CaseEnum-style ADT (alternative syntax)" in {
Beer.Lager shouldBe a[Product]
Beer.Lager shouldBe a[Serializable]
Beer.Lager shouldBe a[Beer]
Beer.Ale should not be a[Beer.Lager.type]
Beer.Lager shouldBe Beer.Lager
}
test("@enum annotation should produce a valid CaseEnum-style ADT (alternative syntax)") {
assert(Beer.Lager.isInstanceOf[Product])
assert(Beer.Lager.isInstanceOf[Serializable])
assert(Beer.Lager.isInstanceOf[Beer])
assertEquals(Beer.Lager, Beer.Lager)
}

"allow accessing the values of the enumeration" in {
val typecheck: Set[Planet] = Planet.values
Planet.values shouldBe Set(Planet.Mercury, Planet.Venus, Planet.Earth)
}
test("@enum annotation should allow accessing the values of the enumeration") {
(Planet.values: Set[Planet]) // typecheck
assertEquals(Planet.values, Set(Planet.Mercury, Planet.Venus, Planet.Earth))
}

"allow printing / parsing the values of the enumeration" in {
Planet.caseFromString("Earth") shouldBe Some(Planet.Earth)
Planet.caseFromString("Nope") shouldBe None
Planet.caseToString(Planet.Earth) shouldBe "Earth"
"Planet.caseToString(Beer.Lager)" shouldNot typeCheck
}
test("@enum annotation should allow printing / parsing the values of the enumeration") {
assertEquals(Planet.caseFromString("Earth"), Some(Planet.Earth))
assertEquals(Planet.caseFromString("Nope"), None)
assertEquals(Planet.caseToString(Planet.Earth), "Earth")
compileErrors("Planet.caseToString(Beer.Lager)")
}

"allow accessing the enumeration name" in {
Planet.name shouldBe "Planet"
}
test("@enum annotation should allow accessing the enumeration name") {
assertEquals(Planet.name, "Planet")
}

}

class IndexedCaseEnumMacroSpec extends WordSpec with Matchers {
class IndexedCaseEnumMacroSpec extends munit.FunSuite {
@indexedEnum trait Planet {
type Index = Int
Mercury { 1 }
Expand All @@ -64,26 +58,24 @@ class IndexedCaseEnumMacroSpec extends WordSpec with Matchers {
Ale { 2 }
}

"@indexedEnum annotation" should {
"produce a valid IndexedCaseEnum-style ADT" in {
val typecheck: Int = 3: Planet#Index
Planet.Earth shouldBe a[Product]
Planet.Earth shouldBe a[Serializable]
Planet.Earth shouldBe a[Planet]
Planet.Mercury should not be a[Planet.Earth.type]
Planet.Earth shouldBe Planet.Earth
Planet.Earth.index shouldBe 3
}
test("@indexedEnum annotation should produce a valid IndexedCaseEnum-style ADT") {
val _: Int = 3: Planet#Index // typecheck
assert(Planet.Earth.isInstanceOf[Product])
assert(Planet.Earth.isInstanceOf[Serializable])
assert(Planet.Earth.isInstanceOf[Planet])
assertEquals(Planet.Earth, Planet.Earth)
assertEquals(Planet.Earth.index, 3)
}

"produce a valid IndexedCaseEnum-style ADT (alternative syntax)" in {
val typecheck: Int = 2: Planet#Index
Beer.Lager shouldBe a[Product]
Beer.Lager shouldBe a[Serializable]
Beer.Lager shouldBe a[Beer]
Beer.Ale should not be a[Beer.Lager.type]
Beer.Lager shouldBe Beer.Lager
Beer.Ale.index shouldBe 2
}
test(
"@indexedEnum annotation should produce a valid IndexedCaseEnum-style ADT (alternative syntax)",
) {
val _: Int = 2: Planet#Index // typecheck
assert(Beer.Lager.isInstanceOf[Product])
assert(Beer.Lager.isInstanceOf[Serializable])
assert(Beer.Lager.isInstanceOf[Beer])
assertEquals(Beer.Lager, Beer.Lager)
assertEquals(Beer.Ale.index, 2)
}

}
Loading

0 comments on commit e6d2325

Please sign in to comment.