diff options
Diffstat (limited to 'src/test/scala/scala/async')
9 files changed, 160 insertions, 62 deletions
diff --git a/src/test/scala/scala/async/TreeInterrogation.scala b/src/test/scala/scala/async/TreeInterrogation.scala index dd239a3..a46eaf2 100644 --- a/src/test/scala/scala/async/TreeInterrogation.scala +++ b/src/test/scala/scala/async/TreeInterrogation.scala @@ -8,6 +8,7 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.junit.Test import AsyncId._ +import tools.reflect.ToolBox @RunWith(classOf[JUnit4]) class TreeInterrogation { @@ -20,47 +21,68 @@ class TreeInterrogation { | async { | val x = await(1) | val y = x * 2 + | def foo(a: Int) = { def nested = 0; a } // don't lift `nested`. | val z = await(x * 3) + | foo(z) | z | }""".stripMargin) val tree1 = tb.typeCheck(tree) //println(cm.universe.show(tree1)) - import tb.mirror.universe._ + import tb.u._ val functions = tree1.collect { case f: Function => f + case t: Template => t } functions.size mustBe 1 val varDefs = tree1.collect { case ValDef(mods, name, _, _) if mods.hasFlag(Flag.MUTABLE) => name } - varDefs.map(_.decoded).toSet mustBe (Set("state$async", "onCompleteHandler$async", "await$1", "await$2")) + varDefs.map(_.decoded.trim).toSet mustBe (Set("state$async", "await$1", "await$2")) + varDefs.map(_.decoded.trim).toSet mustBe (Set("state$async", "await$1", "await$2")) + + val defDefs = tree1.collect { + case t: Template => + val stats: List[Tree] = t.body + stats.collect { + case dd : DefDef + if !dd.symbol.isImplementationArtifact + && !dd.symbol.asTerm.isAccessor && !dd.symbol.asTerm.isSetter => dd.name + } + }.flatten + defDefs.map(_.decoded.trim).toSet mustBe (Set("foo$1", "apply", "resume$async", "<init>")) } +} - //@Test - def sandbox() { - sys.props("scala.async.debug") = true.toString - sys.props("scala.async.trace") = false.toString +object TreeInterrogation extends App { + def withDebug[T](t: => T) { + AsyncUtils.trace = true + AsyncUtils.verbose = true + try t + finally { + AsyncUtils.trace = false + AsyncUtils.verbose = false + } + } + withDebug { val cm = reflect.runtime.currentMirror - val tb = mkToolbox("-cp target/scala-2.10/classes") + val tb = mkToolbox("-cp target/scala-2.10/classes -Xprint:all") val tree = tb.parse( """ import _root_.scala.async.AsyncId._ - | async { - | var sum = 0 - | var i = 0 - | while (i < 5) { - | var j = 0 - | while (j < 5) { - | sum += await(i) * await(j) - | j += 1 - | } - | i += 1 - | } - | sum + | val state = 23 + | val result: Any = "result" + | def resume(): Any = "resume" + | val res = async { + | val f1 = async { state + 2 } + | val x = await(f1) + | val y = await(async { result }) + | val z = await(async { resume() }) + | (x, y, z) | } + | () | """.stripMargin) println(tree) val tree1 = tb.typeCheck(tree.duplicate) diff --git a/src/test/scala/scala/async/neg/LocalClasses0Spec.scala b/src/test/scala/scala/async/neg/LocalClasses0Spec.scala index 06a0e71..2569303 100644 --- a/src/test/scala/scala/async/neg/LocalClasses0Spec.scala +++ b/src/test/scala/scala/async/neg/LocalClasses0Spec.scala @@ -18,7 +18,7 @@ class LocalClasses0Spec { @Test def `reject a local class`() { - expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") { + expectError("Local case class Person illegal within `async` block") { """ | import scala.concurrent.ExecutionContext.Implicits.global | import scala.async.Async._ @@ -32,7 +32,7 @@ class LocalClasses0Spec { @Test def `reject a local class 2`() { - expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") { + expectError("Local case class Person illegal within `async` block") { """ | import scala.concurrent.{Future, ExecutionContext} | import ExecutionContext.Implicits.global @@ -50,7 +50,7 @@ class LocalClasses0Spec { @Test def `reject a local class 3`() { - expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") { + expectError("Local case class Person illegal within `async` block") { """ | import scala.concurrent.{Future, ExecutionContext} | import ExecutionContext.Implicits.global @@ -68,7 +68,7 @@ class LocalClasses0Spec { @Test def `reject a local class with symbols in its name`() { - expectError("Local class :: illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") { + expectError("Local case class :: illegal within `async` block") { """ | import scala.concurrent.{Future, ExecutionContext} | import ExecutionContext.Implicits.global @@ -86,7 +86,7 @@ class LocalClasses0Spec { @Test def `reject a nested local class`() { - expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") { + expectError("Local case class Person illegal within `async` block") { """ | import scala.concurrent.{Future, ExecutionContext} | import ExecutionContext.Implicits.global @@ -110,7 +110,7 @@ class LocalClasses0Spec { @Test def `reject a local singleton object`() { - expectError("Local object Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") { + expectError("Local object Person illegal within `async` block") { """ | import scala.concurrent.ExecutionContext.Implicits.global | import scala.async.Async._ diff --git a/src/test/scala/scala/async/neg/NakedAwait.scala b/src/test/scala/scala/async/neg/NakedAwait.scala index f4cfca2..ecc84f9 100644 --- a/src/test/scala/scala/async/neg/NakedAwait.scala +++ b/src/test/scala/scala/async/neg/NakedAwait.scala @@ -143,15 +143,4 @@ class NakedAwait { |""".stripMargin } } - - // TODO Anf transform if to have a simple condition. - @Test - def ifCondition() { - expectError("await must not be used under a condition.") { - """ - | import _root_.scala.async.AsyncId._ - | async { if (await(true)) () } - |""".stripMargin - } - } } diff --git a/src/test/scala/scala/async/package.scala b/src/test/scala/scala/async/package.scala index bc4ebac..4a7a958 100644 --- a/src/test/scala/scala/async/package.scala +++ b/src/test/scala/scala/async/package.scala @@ -5,7 +5,7 @@ package scala import reflect._ -import tools.reflect.ToolBoxError +import tools.reflect.{ToolBox, ToolBoxError} package object async { @@ -36,7 +36,7 @@ package object async { tb.eval(tb.parse(code)) } - def mkToolbox(compileOptions: String = "") = { + def mkToolbox(compileOptions: String = ""): ToolBox[_ <: scala.reflect.api.Universe] = { val m = scala.reflect.runtime.currentMirror import scala.tools.reflect.ToolBox m.mkToolBox(options = compileOptions) diff --git a/src/test/scala/scala/async/run/anf/AnfTransformSpec.scala b/src/test/scala/scala/async/run/anf/AnfTransformSpec.scala index 41eeaa5..6dd4db7 100644 --- a/src/test/scala/scala/async/run/anf/AnfTransformSpec.scala +++ b/src/test/scala/scala/async/run/anf/AnfTransformSpec.scala @@ -24,8 +24,8 @@ class AnfTestClass { } def m(y: Int): Future[Int] = async { - val f = base(y) - await(f) + val blerg = base(y) + await(blerg) } def m2(y: Int): Future[Int] = async { diff --git a/src/test/scala/scala/async/run/hygiene/Hygiene.scala b/src/test/scala/scala/async/run/hygiene/Hygiene.scala index 0da2a4d..9d1df21 100644 --- a/src/test/scala/scala/async/run/hygiene/Hygiene.scala +++ b/src/test/scala/scala/async/run/hygiene/Hygiene.scala @@ -30,28 +30,6 @@ class HygieneSpec { res mustBe ((25, "result", "resume")) } -/* TODO: -[error] /Users/phaller/git/async/src/test/scala/scala/async/run/hygiene/Hygiene.scala:52: not found: value tr$1 -[error] val f1 = async { state + 2 } -[error] ^ - @Test - def `is hygenic`() { - val state = 23 - val result: Any = "result" - def resume(): Any = "resume" - val res = async { - val f1 = async { state + 2 } - val x = await(f1) - val y = await(async { result }) - val z = await(async { resume() }) - (x, y, z) - } - res._1 mustBe (25) - res._2 mustBe ("result") - res._3 mustBe ("resume") - } -*/ - @Test def `external var as result of await`() { var ext = 0 @@ -87,4 +65,22 @@ class HygieneSpec { } ext mustBe (14) } + + @Test + def `is hygenic nested`() { + val state = 23 + val result: Any = "result" + def resume(): Any = "resume" + import AsyncId.{await, async} + val res = async { + val f1 = async { state + 2 } + val x = await(f1) + val y = await(async { result }) + val z = await(async(await(async { resume() }))) + (x, y, z) + } + res._1 mustBe (25) + res._2 mustBe ("result") + res._3 mustBe ("resume") + } } diff --git a/src/test/scala/scala/async/run/ifelse0/IfElse0.scala b/src/test/scala/scala/async/run/ifelse0/IfElse0.scala index 0a72f1e..e2b1ca6 100644 --- a/src/test/scala/scala/async/run/ifelse0/IfElse0.scala +++ b/src/test/scala/scala/async/run/ifelse0/IfElse0.scala @@ -47,4 +47,12 @@ class IfElseSpec { val res = Await.result(fut, 2 seconds) res mustBe (14) } + + @Test def `await in condition`() { + import AsyncId.{async, await} + val result = async { + if ({await(true); await(true)}) await(1) else ??? + } + result mustBe (1) + } } diff --git a/src/test/scala/scala/async/run/match0/Match0.scala b/src/test/scala/scala/async/run/match0/Match0.scala index f550a69..8263e72 100644 --- a/src/test/scala/scala/async/run/match0/Match0.scala +++ b/src/test/scala/scala/async/run/match0/Match0.scala @@ -69,4 +69,47 @@ class MatchSpec { val res = Await.result(fut, 2 seconds) res mustBe (5) } + + @Test def `support await in a match expression with binds`() { + val result = AsyncId.async { + val x = 1 + Option(x) match { + case op @ Some(x) => + assert(op == Some(1)) + x + AsyncId.await(x) + case None => AsyncId.await(0) + } + } + result mustBe (2) + } + + @Test def `support await referring to pattern matching vals`() { + import AsyncId.{async, await} + val result = async { + val x = 1 + val opt = Some("") + await(0) + val o @ Some(y) = opt + + { + val o @ Some(y) = Some(".") + } + + await(0) + await((o, y.isEmpty)) + } + result mustBe ((Some(""), true)) + } + + @Test def `await in scrutinee`() { + import AsyncId.{async, await} + val result = async { + await(if ("".isEmpty) await(1) else ???) match { + case x if x < 0 => ??? + case y: Int => y * await(3) + case _ => ??? + } + } + result mustBe (3) + } } diff --git a/src/test/scala/scala/async/run/nesteddef/NestedDef.scala b/src/test/scala/scala/async/run/nesteddef/NestedDef.scala new file mode 100644 index 0000000..2baef0d --- /dev/null +++ b/src/test/scala/scala/async/run/nesteddef/NestedDef.scala @@ -0,0 +1,40 @@ +package scala.async +package run +package nesteddef + +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.Test + +@RunWith(classOf[JUnit4]) +class NestedDef { + + @Test + def nestedDef() { + import AsyncId._ + val result = async { + val a = 0 + val x = await(a) - 1 + val local = 43 + def bar(d: Double) = -d + a + local + def foo(z: Any) = (a.toDouble, bar(x).toDouble, z) + foo(await(2)) + } + result mustBe (0d, 44d, 2) + } + + + @Test + def nestedFunction() { + import AsyncId._ + val result = async { + val a = 0 + val x = await(a) - 1 + val local = 43 + val bar = (d: Double) => -d + a + local + val foo = (z: Any) => (a.toDouble, bar(x).toDouble, z) + foo(await(2)) + } + result mustBe (0d, 44d, 2) + } +} |