diff options
author | phaller <hallerp@gmail.com> | 2012-11-12 15:19:41 +0100 |
---|---|---|
committer | phaller <hallerp@gmail.com> | 2012-11-12 15:19:41 +0100 |
commit | 35e62f929df44ff83ed2296352a9db9df889af17 (patch) | |
tree | 2c85470d5fdb248157b21551bb537e353662712a /src/test | |
parent | 386026d6489bd64cc42ac81b76571bf2312d4c42 (diff) | |
parent | 7a27951f47635f8badcabfee2f315dd6183ac8ce (diff) | |
download | scala-async-35e62f929df44ff83ed2296352a9db9df889af17.tar.gz scala-async-35e62f929df44ff83ed2296352a9db9df889af17.tar.bz2 scala-async-35e62f929df44ff83ed2296352a9db9df889af17.zip |
Fix merge conflicts and tests
Diffstat (limited to 'src/test')
14 files changed, 177 insertions, 16 deletions
diff --git a/src/test/scala/scala/async/TestUtils.scala b/src/test/scala/scala/async/TestUtils.scala index 0920659..bac22a3 100644 --- a/src/test/scala/scala/async/TestUtils.scala +++ b/src/test/scala/scala/async/TestUtils.scala @@ -40,11 +40,14 @@ trait TestUtils { } def eval(code: String, compileOptions: String = ""): Any = { + val tb = mkToolbox(compileOptions) + tb.eval(tb.parse(code)) + } + + def mkToolbox(compileOptions: String = "") = { val m = scala.reflect.runtime.currentMirror import scala.tools.reflect.ToolBox - val tb = m.mkToolBox(options = compileOptions) - val result = tb.eval(tb.parse(code)) - result + m.mkToolBox(options = compileOptions) } def expectError(errorSnippet: String, compileOptions: String = "")(code: String) { diff --git a/src/test/scala/scala/async/TreeInterrogation.scala b/src/test/scala/scala/async/TreeInterrogation.scala new file mode 100644 index 0000000..1293bdf --- /dev/null +++ b/src/test/scala/scala/async/TreeInterrogation.scala @@ -0,0 +1,38 @@ +package scala.async + +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.Test +import AsyncId._ + +@RunWith(classOf[JUnit4]) +class TreeInterrogation { + @Test + def `a minimal set of vals are lifted to vars`() { + val cm = reflect.runtime.currentMirror + val tb = mkToolbox("-cp target/scala-2.10/classes") + val tree = mkToolbox().parse( + """| import _root_.scala.async.AsyncId._ + | async { + | val x = await(1) + | val y = x * 2 + | val z = await(x * 3) + | z + | }""".stripMargin) + val tree1 = tb.typeCheck(tree) + + // println(cm.universe.showRaw(tree1)) + + import tb.mirror.universe._ + val functions = tree1.collect { + case f: Function => f + } + functions.size mustBe 1 + + val varDefs = tree1.collect { + case ValDef(mods, name, _, _) if mods.hasFlag(Flag.MUTABLE) => name + } + // TODO no need to lift `y` as it is only accessed from a single state. + varDefs.map(_.decoded).toSet mustBe(Set("state$async", "onCompleteHandler$async", "x$1", "z$1", "y$1")) + } +} diff --git a/src/test/scala/scala/async/neg/LocalClasses0Spec.scala b/src/test/scala/scala/async/neg/LocalClasses0Spec.scala index 838c988..7932744 100644 --- a/src/test/scala/scala/async/neg/LocalClasses0Spec.scala +++ b/src/test/scala/scala/async/neg/LocalClasses0Spec.scala @@ -16,7 +16,9 @@ class LocalClasses0Spec { def `reject a local class`() { expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") { """ + | import scala.concurrent.ExecutionContext.Implicits.global | import scala.async.Async._ + | | async { | case class Person(name: String) | } @@ -31,6 +33,7 @@ class LocalClasses0Spec { | import scala.concurrent.{Future, ExecutionContext} | import ExecutionContext.Implicits.global | import scala.async.Async._ + | | async { | case class Person(name: String) | val fut = Future { 5 } @@ -48,6 +51,7 @@ class LocalClasses0Spec { | import scala.concurrent.{Future, ExecutionContext} | import ExecutionContext.Implicits.global | import scala.async.Async._ + | | async { | val fut = Future { 5 } | val x = await(fut) @@ -65,6 +69,7 @@ class LocalClasses0Spec { | import scala.concurrent.{Future, ExecutionContext} | import ExecutionContext.Implicits.global | import scala.async.Async._ + | | async { | val fut = Future { 5 } | val x = await(fut) @@ -82,6 +87,7 @@ class LocalClasses0Spec { | import scala.concurrent.{Future, ExecutionContext} | import ExecutionContext.Implicits.global | import scala.async.Async._ + | | async { | val fut = Future { 5 } | val x = 2 + 2 @@ -102,7 +108,9 @@ class LocalClasses0Spec { def `reject a local singleton object`() { expectError("Local object Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") { """ + | import scala.concurrent.ExecutionContext.Implicits.global | import scala.async.Async._ + | | async { | object Person { val name = "Joe" } | } diff --git a/src/test/scala/scala/async/run/await0/Await0Spec.scala b/src/test/scala/scala/async/run/await0/Await0Spec.scala index e7740e0..42d4ef2 100644 --- a/src/test/scala/scala/async/run/await0/Await0Spec.scala +++ b/src/test/scala/scala/async/run/await0/Await0Spec.scala @@ -20,27 +20,22 @@ class Await0Class { import ExecutionContext.Implicits.global def m1(x: Double): Future[Double] = future { - Thread.sleep(200) x + 2.0 } def m2(x: Float): Future[Float] = future { - Thread.sleep(200) x + 2.0f } def m3(x: Char): Future[Char] = future { - Thread.sleep(200) (x.toInt + 2).toChar } def m4(x: Short): Future[Short] = future { - Thread.sleep(200) (x + 2).toShort } def m5(x: Byte): Future[Byte] = future { - Thread.sleep(200) (x + 2).toByte } @@ -75,4 +70,3 @@ class Await0Spec { res mustBe (26.0) } } - diff --git a/src/test/scala/scala/async/run/block0/AsyncSpec.scala b/src/test/scala/scala/async/run/block0/AsyncSpec.scala index f56e394..5a7247c 100644 --- a/src/test/scala/scala/async/run/block0/AsyncSpec.scala +++ b/src/test/scala/scala/async/run/block0/AsyncSpec.scala @@ -20,7 +20,6 @@ class Test1Class { import ExecutionContext.Implicits.global def m1(x: Int): Future[Int] = future { - Thread.sleep(1000) x + 2 } diff --git a/src/test/scala/scala/async/run/block1/block1.scala b/src/test/scala/scala/async/run/block1/block1.scala index 8f21688..a449805 100644 --- a/src/test/scala/scala/async/run/block1/block1.scala +++ b/src/test/scala/scala/async/run/block1/block1.scala @@ -20,7 +20,6 @@ class Test1Class { import ExecutionContext.Implicits.global def m1(x: Int): Future[Int] = future { - Thread.sleep(1000) x + 2 } diff --git a/src/test/scala/scala/async/run/hygiene/Hygiene.scala b/src/test/scala/scala/async/run/hygiene/Hygiene.scala new file mode 100644 index 0000000..0cc68a4 --- /dev/null +++ b/src/test/scala/scala/async/run/hygiene/Hygiene.scala @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com> + */ + +package scala.async +package run +package hygiene + +import language.{reflectiveCalls, postfixOps} +import concurrent._ +import scala.concurrent.{Future, ExecutionContext, future, Await} +import scala.concurrent.duration._ +import scala.async.Async.{async, await} +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + + +class HygieneClass { + + import ExecutionContext.Implicits.global + + def m1(x: Int): Future[Int] = future { + x + 2 + } + + def m2(y: Int) = { + val state = 23 + val result: Any = "result" + def resume(): Any = "resume" + async { + val f1 = m1(state) + val x = await(f1) + val y = await(future(result)) + val z = await(future(resume())) + (x, y, z) + } + } +} + +@RunWith(classOf[JUnit4]) +class HygieneSpec { + + @Test def `is hygenic`() { + val o = new HygieneClass + val fut = o.m2(10) + val res = Await.result(fut, 2 seconds) + 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 eca3acd..0363a75 100644 --- a/src/test/scala/scala/async/run/ifelse0/IfElse0.scala +++ b/src/test/scala/scala/async/run/ifelse0/IfElse0.scala @@ -20,7 +20,6 @@ class TestIfElseClass { import ExecutionContext.Implicits.global def m1(x: Int): Future[Int] = future { - Thread.sleep(1000) x + 2 } diff --git a/src/test/scala/scala/async/run/ifelse1/IfElse1.scala b/src/test/scala/scala/async/run/ifelse1/IfElse1.scala index 128f02a..3ca3a94 100644 --- a/src/test/scala/scala/async/run/ifelse1/IfElse1.scala +++ b/src/test/scala/scala/async/run/ifelse1/IfElse1.scala @@ -20,7 +20,6 @@ class TestIfElse1Class { import ExecutionContext.Implicits.global def base(x: Int): Future[Int] = future { - Thread.sleep(1000) x + 2 } diff --git a/src/test/scala/scala/async/run/ifelse2/ifelse2.scala b/src/test/scala/scala/async/run/ifelse2/ifelse2.scala index f894923..84974b6 100644 --- a/src/test/scala/scala/async/run/ifelse2/ifelse2.scala +++ b/src/test/scala/scala/async/run/ifelse2/ifelse2.scala @@ -20,7 +20,6 @@ class TestIfElse2Class { import ExecutionContext.Implicits.global def base(x: Int): Future[Int] = future { - Thread.sleep(1000) x + 2 } diff --git a/src/test/scala/scala/async/run/ifelse3/IfElse3.scala b/src/test/scala/scala/async/run/ifelse3/IfElse3.scala index 0c0dbfe..d475a0c 100644 --- a/src/test/scala/scala/async/run/ifelse3/IfElse3.scala +++ b/src/test/scala/scala/async/run/ifelse3/IfElse3.scala @@ -20,7 +20,6 @@ class TestIfElse3Class { import ExecutionContext.Implicits.global def base(x: Int): Future[Int] = future { - Thread.sleep(1000) x + 2 } diff --git a/src/test/scala/scala/async/run/match0/Match0.scala b/src/test/scala/scala/async/run/match0/Match0.scala index 3c7e297..6a17e2b 100644 --- a/src/test/scala/scala/async/run/match0/Match0.scala +++ b/src/test/scala/scala/async/run/match0/Match0.scala @@ -20,7 +20,6 @@ class TestMatchClass { import ExecutionContext.Implicits.global def m1(x: Int): Future[Int] = future { - Thread.sleep(1000) x + 2 } diff --git a/src/test/scala/scala/async/run/noawait/NoAwaitSpec.scala b/src/test/scala/scala/async/run/noawait/NoAwaitSpec.scala new file mode 100644 index 0000000..90be946 --- /dev/null +++ b/src/test/scala/scala/async/run/noawait/NoAwaitSpec.scala @@ -0,0 +1,34 @@ +package scala.async +package run +package noawait + +import AsyncId._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(classOf[JUnit4]) +class NoAwaitSpec { + @Test + def `async block without await`() { + def foo = 1 + async { + foo + foo + } mustBe (foo) + } + + @Test + def `async block without await 2`() { + async { + def x = 0 + if (x > 0) 0 else 1 + } mustBe (1) + } + + @Test + def `async expr without await`() { + def foo = 1 + async(foo) mustBe (foo) + } +} diff --git a/src/test/scala/scala/async/run/toughtype/ToughType.scala b/src/test/scala/scala/async/run/toughtype/ToughType.scala new file mode 100644 index 0000000..f576ddc --- /dev/null +++ b/src/test/scala/scala/async/run/toughtype/ToughType.scala @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com> + */ + +package scala.async +package run +package toughtype + +import language.{reflectiveCalls, postfixOps} +import scala.concurrent._ +import scala.concurrent.duration._ +import scala.async.Async._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + + +object ToughTypeObject { + + import ExecutionContext.Implicits.global + + class Inner + + def m2 = async[(List[_], ToughTypeObject.Inner)] { + val y = await(future[List[_]](Nil)) + val z = await(future[Inner](new Inner)) + (y, z) + } +} + +@RunWith(classOf[JUnit4]) +class ToughTypeSpec { + + @Test def `propogates tough types`() { + val fut = ToughTypeObject.m2 + val res: (List[_], scala.async.run.toughtype.ToughTypeObject.Inner) = Await.result(fut, 2 seconds) + res._1 mustBe (Nil) + } +} |