summaryrefslogtreecommitdiff
path: root/test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala
diff options
context:
space:
mode:
Diffstat (limited to 'test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala')
-rw-r--r--test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala122
1 files changed, 122 insertions, 0 deletions
diff --git a/test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala b/test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala
new file mode 100644
index 0000000000..13e231891d
--- /dev/null
+++ b/test/scalacheck/scala/reflect/quasiquotes/QuasiquoteProperties.scala
@@ -0,0 +1,122 @@
+package scala.reflect.quasiquotes
+
+import org.scalacheck._, Prop._, Gen._, Arbitrary._
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.reflect.runtime.currentMirror
+import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport.setSymbol
+
+abstract class QuasiquoteProperties(name: String) extends Properties(name) with ArbitraryTreesAndNames with Helpers
+
+trait Helpers {
+ /** Runs a code block and returns proof confirmation
+ * if no exception has been thrown while executing code
+ * block. This is useful for simple one-off tests.
+ */
+ def test[T](block: => T) =
+ Prop { params =>
+ block
+ Result(Prop.Proof)
+ }
+
+ object simplify extends Transformer {
+ object SimplifiedName {
+ val st = scala.reflect.runtime.universe.asInstanceOf[scala.reflect.internal.SymbolTable]
+ val FreshName = new st.FreshNameExtractor
+ def unapply[T <: Name](name: T): Option[T] = name.asInstanceOf[st.Name] match {
+ case FreshName(prefix) =>
+ Some((if (name.isTermName) TermName(prefix) else TypeName(prefix)).asInstanceOf[T])
+ }
+ }
+
+ override def transform(tree: Tree): Tree = tree match {
+ case Ident(SimplifiedName(name)) => Ident(name)
+ case ValDef(mods, SimplifiedName(name), tpt, rhs) => ValDef(mods, name, transform(tpt), transform(rhs))
+ case Bind(SimplifiedName(name), rhs) => Bind(name, rhs)
+ case _ =>
+ super.transform(tree)
+ }
+
+ def apply(tree: Tree): Tree = transform(tree)
+ }
+
+ implicit class TestSimilarTree(tree1: Tree) {
+ def ≈(tree2: Tree) = simplify(tree1).equalsStructure(simplify(tree2))
+ }
+
+ implicit class TestSimilarListTree(lst: List[Tree]) {
+ def ≈(other: List[Tree]) = (lst.length == other.length) && lst.zip(other).forall { case (t1, t2) => t1 ≈ t2 }
+ }
+
+ implicit class TestSimilarListListTree(lst: List[List[Tree]]) {
+ def ≈(other: List[List[Tree]]) = (lst.length == other.length) && lst.zip(other).forall { case (l1, l2) => l1 ≈ l2 }
+ }
+
+ implicit class TestSimilarName(name: Name) {
+ def ≈(other: Name) = name == other
+ }
+
+ implicit class TestSimilarMods(mods: Modifiers) {
+ def ≈(other: Modifiers) = (mods.flags == other.flags) && (mods.privateWithin ≈ other.privateWithin) && (mods.annotations ≈ other.annotations)
+ }
+
+ def assertThrows[T <: AnyRef](f: => Any)(implicit manifest: Manifest[T]): Unit = {
+ val clazz = manifest.runtimeClass.asInstanceOf[Class[T]]
+ val thrown =
+ try {
+ f
+ false
+ } catch {
+ case u: Throwable =>
+ if (!clazz.isAssignableFrom(u.getClass))
+ assert(false, s"wrong exception: $u")
+ true
+ }
+ if(!thrown)
+ assert(false, "exception wasn't thrown")
+ }
+
+ def assertEqAst(tree: Tree, code: String) = assert(eqAst(tree, code))
+ def eqAst(tree: Tree, code: String) = tree ≈ parse(code)
+
+ val toolbox = currentMirror.mkToolBox()
+ val parse = toolbox.parse(_)
+ val compile = toolbox.compile(_)
+ val eval = toolbox.eval(_)
+
+ def typecheck(tree: Tree) = toolbox.typecheck(tree)
+
+ def typecheckTyp(tree: Tree) = {
+ val q"type $_ = $res" = typecheck(q"type T = $tree")
+ res
+ }
+
+ def typecheckPat(tree: Tree) = {
+ val q"$_ match { case $res => }" = typecheck(q"((): Any) match { case $tree => }")
+ res
+ }
+
+ def fails(msg: String, block: String) = {
+ def result(ok: Boolean, description: String = "") = {
+ val status = if (ok) Prop.Proof else Prop.False
+ val labels = if (description != "") Set(description) else Set.empty[String]
+ Prop { new Prop.Result(status, Nil, Set.empty, labels) }
+ }
+ try {
+ compile(parse(s"""
+ object Wrapper extends Helpers {
+ import scala.reflect.runtime.universe._
+ $block
+ }
+ """))
+ result(false, "given code doesn't fail to typecheck")
+ } catch {
+ case ToolBoxError(emsg, _) =>
+ if (!emsg.contains(msg))
+ result(false, s"error message '${emsg}' is not the same as expected '$msg'")
+ else
+ result(true)
+ }
+ }
+
+ val scalapkg = setSymbol(Ident(TermName("scala")), definitions.ScalaPackage)
+}