1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBoxError
import scala.reflect.macros.TypecheckException
import org.scalacheck._
import Prop._
import Gen._
import Arbitrary._
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)
}
implicit class TestSimilarTree(tree1: Tree) {
def ≈(tree2: Tree) = tree1.equalsStructure(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.erasure.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 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 {
val tb = rootMirror.mkToolBox()
val tree = tb.parse(s"""
object Wrapper extends Helpers {
import scala.reflect.runtime.universe._
$block
}
""")
tb.compile(tree)
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)
}
}
def annot(name: String): Tree = annot(TypeName(name), Nil)
def annot(name: TypeName): Tree = annot(name, Nil)
def annot(name: String, args: List[Tree]): Tree = annot(TypeName(name), args)
def annot(name: TypeName, args: List[Tree]): Tree = q"new $name(..$args)"
}
|