Skip to content

Commit

Permalink
No more quasiquotes, add test for ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
lloydmeta committed Apr 22, 2015
1 parent 48db104 commit 51bd60b
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 18 deletions.
4 changes: 2 additions & 2 deletions enumeratum-core/src/main/scala/enumeratum/Enum.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ trait Enum[A <: EnumEntry] {
def values: Seq[A]

/**
* Method that returns an IndexedSeq of [[A]] objects that the macro was able to find.
* Method that returns a Seq of [[A]] objects that the macro was able to find.
*
* You will want to use this in some way to implement your [[values]] method. In fact,
* if you aren't using this method...why are you even bothering with this lib?
*/
protected def findValues: IndexedSeq[A] = macro EnumMacros.findValuesImpl[A]
protected def findValues: Seq[A] = macro EnumMacros.findValuesImpl[A]

/**
* Map of [[A]] object names to [[A]]s
Expand Down
27 changes: 27 additions & 0 deletions enumeratum-core/src/test/scala/enumeratum/EnumSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,33 @@ class EnumSpec extends FunSpec with Matchers {

}

describe("findValues Vector") {

// This is a fairly intense test.
it("should be in the same order that the objects were declared in") {
import scala.util._
(1 to 50).foreach { i =>
val members = Random.shuffle((1 to Random.nextInt(20)).map { m => s"member$m" })
val membersDefs = members.map { m => s"case object $m extends Enum$i" }.mkString("\n\n")
val objDefinition =
s"""
import enumeratum._
sealed trait Enum$i extends EnumEntry

case object Enum$i extends Enum[Enum$i] {
$membersDefs
val values = findValues
}

Enum$i
"""
val obj = Eval[Enum[_ <: EnumEntry]](objDefinition)
obj.values.map(_.toString) shouldBe members
}
}

}

describe("trying to use with improper types") {

it("should fail to compile for unsealed traits") {
Expand Down
41 changes: 41 additions & 0 deletions enumeratum-core/src/test/scala/enumeratum/Eval.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package enumeratum

import scala.tools.reflect.ToolBox
import java.io.File

/**
* Eval with bits and pieces stolen from here and there...
*/
object Eval {

def apply[A](string: String,
compileOptions: String = s"-cp ${macroToolboxClassPath.mkString(";")}"): A = {
import scala.reflect.runtime.currentMirror
val toolbox = currentMirror.mkToolBox(options = compileOptions)
val tree = toolbox.parse(string)
toolbox.eval(tree).asInstanceOf[A]
}

def macroToolboxClassPath = {
val paths = Seq(
new java.io.File(s"macros/target/scala-${scalaBinaryVersion}/classes")
)
paths.foreach { p =>
if (!p.exists) sys.error(s"output directory ${p.getAbsolutePath} does not exist.")
}
paths.map(_.getAbsolutePath)
}

def scalaBinaryVersion: String = {
val PreReleasePattern = """.*-(M|RC).*""".r
val Pattern = """(\d+\.\d+)\..*""".r
val SnapshotPattern = """(\d+\.\d+\.\d+)-\d+-\d+-.*""".r
scala.util.Properties.versionNumberString match {
case s @ PreReleasePattern(_) => s
case SnapshotPattern(v) => v + "-SNAPSHOT"
case Pattern(v) => v
case _ => ""
}
}

}
6 changes: 5 additions & 1 deletion macros/src/main/scala/enumeratum/EnumMacros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ object EnumMacros {
val typeSymbol = weakTypeOf[A].typeSymbol
validateType(c)(typeSymbol)
val subclassSymbols = enclosedSubClasses(c)(typeSymbol)
c.Expr[IndexedSeq[A]](q"IndexedSeq[${tq"$resultType"}](..${subclassSymbols.map(s => Ident(s))})")
c.Expr[IndexedSeq[A]](
Apply(
Select(reify(IndexedSeq).tree, newTermName("apply")),
subclassSymbols.map(Ident(_)).toList
))
}

private[this] def validateType(c: Context)(typeSymbol: c.universe.Symbol): Unit = {
Expand Down
20 changes: 5 additions & 15 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ object Enumeratum extends Build {
crossScalaVersions := scalaVersions,
crossVersion := CrossVersion.binary,
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "2.2.1" % "test"
"org.scalatest" %% "scalatest" % "2.2.1" % Test,
"org.scala-lang" % "scala-compiler" % scalaVersion.value % Test
)
).dependsOn(macros)

Expand All @@ -55,18 +56,7 @@ object Enumeratum extends Build {
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.scalatest" %% "scalatest" % "2.2.1" % "test"
) ++ {
val additionalMacroDeps = CrossVersion.partialVersion(scalaVersion.value) match {
// if scala 2.11+ is used, quasiquotes are merged into scala-reflect
case Some((2, scalaMajor)) if scalaMajor >= 11 =>
Nil
// in Scala 2.10, quasiquotes are provided by macro paradise
case Some((2, 10)) =>
Seq(
compilerPlugin("org.scalamacros" % "paradise" % "2.0.1" cross CrossVersion.full),
"org.scalamacros" %% "quasiquotes" % "2.0.1" cross CrossVersion.binary)
}
additionalMacroDeps }
)
)

lazy val enumeratumPlayJson = Project(id = "enumeratum-play-json", base = file("enumeratum-play-json"), settings = commonWithPublishSettings)
Expand All @@ -84,8 +74,8 @@ object Enumeratum extends Build {
crossScalaVersions := scalaVersions,
crossVersion := CrossVersion.binary,
libraryDependencies ++= Seq(
"com.typesafe.play" %% "play" % "2.3.8" % "provided",
"org.scalatest" %% "scalatest" % "2.2.1" % "test"
"com.typesafe.play" %% "play" % "2.3.8" % Provided,
"org.scalatest" %% "scalatest" % "2.2.1" % Test
)
).dependsOn(core, enumeratumPlayJson)

Expand Down

0 comments on commit 51bd60b

Please sign in to comment.