summaryrefslogtreecommitdiff
path: root/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util')
-rw-r--r--examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/DirectTest.scala70
-rw-r--r--examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/JSASTTest.scala100
-rw-r--r--examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/TestHelpers.scala68
3 files changed, 238 insertions, 0 deletions
diff --git a/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/DirectTest.scala b/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/DirectTest.scala
new file mode 100644
index 0000000..8289129
--- /dev/null
+++ b/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/DirectTest.scala
@@ -0,0 +1,70 @@
+package scala.scalajs.compiler.test.util
+
+import scala.tools.nsc._
+import reporters.{Reporter, ConsoleReporter}
+import scala.reflect.internal.util.{ SourceFile, BatchSourceFile }
+
+import scala.scalajs.compiler.ScalaJSPlugin
+
+import scala.collection.mutable
+
+/** This is heavily inspired by scala's partest suite's DirectTest */
+abstract class DirectTest {
+
+ /** these arguments are always added to the args passed to newSettings */
+ def extraArgs: List[String] = Nil
+
+ /** create settings objects for test from arg string */
+ def newSettings(args: List[String]) = {
+ val s = new Settings
+ s processArguments (args, true)
+ s
+ }
+
+ def newScalaJSCompiler(args: String*): Global = {
+ val settings = newSettings(
+ List(
+ "-d", testOutputPath,
+ "-bootclasspath", scalaLibPath,
+ "-classpath", scalaJSLibPath) ++
+ extraArgs ++ args.toList)
+
+ lazy val global: Global = new Global(settings, newReporter(settings)) {
+ override lazy val plugins = newScalaJSPlugin(global) :: Nil
+ }
+
+ global
+ }
+
+ def newScalaJSPlugin(global: Global): ScalaJSPlugin =
+ new ScalaJSPlugin(global)
+
+ def newReporter(settings: Settings) = new ConsoleReporter(settings)
+
+ def newSources(codes: String*) = codes.toList.zipWithIndex map {
+ case (src, idx) => new BatchSourceFile(s"newSource${idx + 1}.scala", src)
+ }
+
+ def withRun[T](global: Global)(f: global.Run => T): T = {
+ global.reporter.reset()
+ f(new global.Run)
+ }
+
+ def compileSources(global: Global)(sources: SourceFile*): Boolean = {
+ withRun(global)(_ compileSources sources.toList)
+ !global.reporter.hasErrors
+ }
+
+ def compileString(global: Global)(sourceCode: String): Boolean =
+ compileSources(global)(newSources(sourceCode): _*)
+
+ def compileString(sourceCode: String): Boolean =
+ compileString(defaultGlobal)(sourceCode)
+
+ lazy val defaultGlobal = newScalaJSCompiler()
+
+ def testOutputPath = sys.props("scala.scalajs.compiler.test.output")
+ def scalaJSLibPath = sys.props("scala.scalajs.compiler.test.scalajslib")
+ def scalaLibPath = sys.props("scala.scalajs.compiler.test.scalalib")
+
+}
diff --git a/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/JSASTTest.scala b/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/JSASTTest.scala
new file mode 100644
index 0000000..d3dfd75
--- /dev/null
+++ b/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/JSASTTest.scala
@@ -0,0 +1,100 @@
+package scala.scalajs.compiler.test.util
+
+import language.implicitConversions
+
+import scala.tools.nsc._
+import scala.reflect.internal.util.SourceFile
+
+import scala.util.control.ControlThrowable
+
+import org.junit.Assert._
+
+import scala.scalajs.compiler.{ScalaJSPlugin, JSTreeExtractors}
+import JSTreeExtractors.jse
+import scala.scalajs.ir
+import ir.{Trees => js}
+
+abstract class JSASTTest extends DirectTest {
+
+ private var lastAST: JSAST = _
+
+ class JSAST(val clDefs: List[js.Tree]) {
+ type Pat = PartialFunction[js.Tree, Unit]
+
+ class PFTraverser(pf: Pat) extends ir.Traversers.Traverser {
+ private case object Found extends ControlThrowable
+
+ private[this] var finding = false
+
+ def find: Boolean = {
+ finding = true
+ try {
+ clDefs.map(traverse)
+ false
+ } catch {
+ case Found => true
+ }
+ }
+
+ def traverse(): Unit = {
+ finding = false
+ clDefs.map(traverse)
+ }
+
+ override def traverse(tree: js.Tree): Unit = {
+ if (finding && pf.isDefinedAt(tree))
+ throw Found
+
+ if (!finding)
+ pf.lift(tree)
+
+ super.traverse(tree)
+ }
+ }
+
+ def has(trgName: String)(pf: Pat): this.type = {
+ val tr = new PFTraverser(pf)
+ assertTrue(s"AST should have $trgName", tr.find)
+ this
+ }
+
+ def hasNot(trgName: String)(pf: Pat): this.type = {
+ val tr = new PFTraverser(pf)
+ assertFalse(s"AST should not have $trgName", tr.find)
+ this
+ }
+
+ def traverse(pf: Pat): this.type = {
+ val tr = new PFTraverser(pf)
+ tr.traverse()
+ this
+ }
+
+ def show: this.type = {
+ clDefs foreach println _
+ this
+ }
+
+ }
+
+ implicit def string2ast(str: String): JSAST = stringAST(str)
+
+ override def newScalaJSPlugin(global: Global) = new ScalaJSPlugin(global) {
+ override def generatedJSAST(cld: List[js.Tree]): Unit = {
+ lastAST = new JSAST(cld)
+ }
+ }
+
+ def stringAST(code: String): JSAST = stringAST(defaultGlobal)(code)
+ def stringAST(global: Global)(code: String): JSAST = {
+ compileString(global)(code)
+ lastAST
+ }
+
+ def sourceAST(source: SourceFile): JSAST = sourceAST(defaultGlobal)(source)
+ def sourceAST(global: Global)(source: SourceFile): JSAST = {
+ compileSources(global)(source)
+ lastAST
+ }
+
+}
diff --git a/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/TestHelpers.scala b/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/TestHelpers.scala
new file mode 100644
index 0000000..adad89c
--- /dev/null
+++ b/examples/scala-js/compiler/src/test/scala/scala/scalajs/compiler/test/util/TestHelpers.scala
@@ -0,0 +1,68 @@
+package scala.scalajs.compiler.test.util
+
+import java.io._
+import scala.tools.nsc._
+
+import reporters.ConsoleReporter
+
+import org.junit.Assert._
+
+import scala.util.matching.Regex
+
+trait TestHelpers extends DirectTest {
+
+ private[this] val errBuffer = new CharArrayWriter
+
+ override def newReporter(settings: Settings) = {
+ val in = new BufferedReader(new StringReader(""))
+ val out = new PrintWriter(errBuffer)
+ new ConsoleReporter(settings, in, out)
+ }
+
+ /** will be prefixed to every code that is compiled. use for imports */
+ def preamble = ""
+
+ /** pimps a string to compile it and apply the specified test */
+ implicit class CompileTests(val code: String) {
+
+ def hasErrors(expected: String) = {
+ val reps = repResult {
+ assertFalse("snippet shouldn't compile", compileString(preamble + code))
+ }
+ assertEquals("should have right errors",
+ expected.stripMargin.trim, reps.trim)
+ }
+
+ def hasWarns(expected: String) = {
+ val reps = repResult {
+ assertTrue("snippet should compile", compileString(preamble + code))
+ }
+ assertEquals("should have right warnings",
+ expected.stripMargin.trim, reps.trim)
+ }
+
+ def fails() =
+ assertFalse("snippet shouldn't compile", compileString(preamble + code))
+
+ def warns() = {
+ val reps = repResult {
+ assertTrue("snippet should compile", compileString(preamble + code))
+ }
+ assertFalse("should have warnings", reps.isEmpty)
+ }
+
+ def succeeds() =
+ assertTrue("snippet should compile", compileString(preamble + code))
+
+ private def repResult(body: => Unit) = {
+ errBuffer.reset()
+ body
+ errBuffer.toString
+ }
+ }
+
+ implicit class CodeWrappers(sc: StringContext) {
+ def expr() = new CompileTests(s"class A { ${sc.parts.mkString} }")
+ }
+
+}