2011-01-27 01:49:54 +01:00
|
|
|
package sbt
|
2011-03-02 12:46:28 +01:00
|
|
|
package compiler
|
2011-01-27 01:49:54 +01:00
|
|
|
|
|
|
|
|
import org.scalacheck._
|
|
|
|
|
import Prop._
|
|
|
|
|
import scala.tools.nsc.reporters.StoreReporter
|
|
|
|
|
|
|
|
|
|
object EvalTest extends Properties("eval")
|
|
|
|
|
{
|
|
|
|
|
private[this] val reporter = new StoreReporter
|
|
|
|
|
import reporter.{ERROR,Info,Severity}
|
2011-02-23 04:36:48 +01:00
|
|
|
private[this] val eval = new Eval(_ => reporter, None)
|
2011-01-27 01:49:54 +01:00
|
|
|
|
|
|
|
|
property("inferred integer") = forAll{ (i: Int) =>
|
|
|
|
|
val result = eval.eval(i.toString)
|
2011-07-10 02:18:42 +02:00
|
|
|
(label("Value", value(result)) |: (value(result) == i)) &&
|
|
|
|
|
(label("Type", value(result)) |: (result.tpe == IntType)) &&
|
2011-01-27 01:49:54 +01:00
|
|
|
(label("Files", result.generated) |: (result.generated.isEmpty))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
property("explicit integer") = forAll{ (i: Int) =>
|
|
|
|
|
val result = eval.eval(i.toString, tpeName = Some(IntType))
|
2011-07-10 02:18:42 +02:00
|
|
|
(label("Value", value(result)) |: (value(result) == i)) &&
|
2011-01-27 01:49:54 +01:00
|
|
|
(label("Type", result.tpe) |: (result.tpe == IntType)) &&
|
|
|
|
|
(label("Files", result.generated) |: (result.generated.isEmpty))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
property("type mismatch") = forAll{ (i: Int, l: Int) =>
|
|
|
|
|
val line = math.abs(l)
|
|
|
|
|
val src = "mismatch"
|
|
|
|
|
throws(eval.eval(i.toString, tpeName =Some(BooleanType), line = line, srcName = src), classOf[RuntimeException]) &&
|
|
|
|
|
hasErrors(line+1, src)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
property("backed local class") = forAll{ (i: Int) =>
|
2011-02-23 04:36:48 +01:00
|
|
|
IO.withTemporaryDirectory { dir =>
|
|
|
|
|
val eval = new Eval(_ => reporter, backing = Some(dir))
|
|
|
|
|
val result = eval.eval(local(i))
|
2011-07-10 02:18:42 +02:00
|
|
|
val v = value(result).asInstanceOf[{def i: Int}].i
|
|
|
|
|
(label("Value", v) |: (v == i)) &&
|
2011-01-27 01:49:54 +01:00
|
|
|
(label("Type", result.tpe) |: (result.tpe == LocalType)) &&
|
|
|
|
|
(label("Files", result.generated) |: (!result.generated.isEmpty))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-10 02:40:41 +01:00
|
|
|
val ValTestNames = Set("x", "a")
|
|
|
|
|
val ValTestContent = """
|
|
|
|
|
val x: Int = {
|
|
|
|
|
val y: Int = 4
|
|
|
|
|
y
|
|
|
|
|
}
|
|
|
|
|
val z: Double = 3.0
|
|
|
|
|
val a = 9
|
|
|
|
|
val p = {
|
|
|
|
|
object B { val i = 3 }
|
|
|
|
|
class C { val j = 4 }
|
|
|
|
|
"asdf"
|
|
|
|
|
}
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
property("val test") = secure {
|
|
|
|
|
val defs = (ValTestContent, 1 to 7) :: Nil
|
|
|
|
|
val res = eval.evalDefinitions(defs, new EvalImports(Nil, ""), "<defs>", "scala.Int" :: Nil)
|
|
|
|
|
label("Val names", res.valNames) |: (res.valNames.toSet == ValTestNames)
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-27 01:49:54 +01:00
|
|
|
|
|
|
|
|
property("explicit import") = forAll(testImport("import math.abs" :: Nil))
|
|
|
|
|
property("wildcard import") = forAll(testImport("import math._" :: Nil))
|
|
|
|
|
property("comma-separated imports") = forAll(testImport("import util._, math._, xml._" :: Nil))
|
|
|
|
|
property("multiple imports") = forAll(testImport("import util._" :: "import math._" :: "import xml._" :: Nil))
|
|
|
|
|
|
|
|
|
|
private[this] def testImport(imports: Seq[String]): Int => Prop = i =>
|
2011-07-10 02:18:42 +02:00
|
|
|
value(eval.eval("abs("+i+")", new EvalImports(imports.zipWithIndex, "imp"))) == math.abs(i)
|
2011-01-27 01:49:54 +01:00
|
|
|
|
|
|
|
|
private[this] def local(i: Int) = "{ class ETest(val i: Int); new ETest(" + i + ") }"
|
2012-12-10 02:40:41 +01:00
|
|
|
val LocalType = "Object{val i: Int}"
|
2011-01-27 01:49:54 +01:00
|
|
|
|
2011-07-10 02:18:42 +02:00
|
|
|
private[this] def value(r: EvalResult) = r.getValue(getClass.getClassLoader)
|
2011-01-27 01:49:54 +01:00
|
|
|
private[this] def hasErrors(line: Int, src: String) =
|
|
|
|
|
{
|
|
|
|
|
val is = reporter.infos
|
|
|
|
|
("Has errors" |: (!is.isEmpty)) &&
|
|
|
|
|
all(is.toSeq.map(validPosition(line,src)) :_*)
|
|
|
|
|
}
|
|
|
|
|
private[this] def validPosition(line: Int, src: String)(i: Info) =
|
|
|
|
|
{
|
|
|
|
|
val nme = i.pos.source.file.name
|
|
|
|
|
(label("Severity", i.severity) |: (i.severity == ERROR)) &&
|
|
|
|
|
(label("Line", i.pos.line) |: (i.pos.line == line)) &&
|
|
|
|
|
(label("Name", nme) |: (nme == src))
|
|
|
|
|
}
|
|
|
|
|
val IntType = "Int"
|
|
|
|
|
val BooleanType = "Boolean"
|
|
|
|
|
|
|
|
|
|
def label(s: String, value: Any) = s + " (" + value + ")"
|
|
|
|
|
}
|